Best use of the Nessie banking API
Nessie is the credit desk's bank, and it disagrees with the ledger
Nessie plays Fogline Supply Co.'s bank. The whole case is loaded into it: Fogline's operating account, a customer and account for every trade customer with their invoices as bills, every payment the bank could have cleared as a deposit with the payer's memo, and each credit applicant's monthly deposits. Two AI agents read it through one box tool. The collections clerk reconciles the ledger against what actually arrived; the credit analyst checks stated revenue against real deposits.
Proof Nessie shows Golden Gate Bagel's $1,940 deposit with the memo INV-24098, while the ledger applied that payment to another customer's invoice, and it shows no deposit at all for a check dated after the case date that the ledger marked paid. The clerk caught both in the live run, and the merge gate checks them in Nessie on every merge.
What Capital One asked for
From Capital One's track description, as copied into the project's track plan (docs/tracks.md).
Best use of the Nessie banking API.
MetNessie is the bank behind a finance agent's daily work, not a balance display. Both seats read it through
credit-desk.bank, a tool that runs in the box's core with the Nessie key from a root-only vault. The agents never hold the key.Completeness.
Metnessie-seed.tsloads the case: 1 Fogline customer and operating account, 12 trade customers and accounts, 38 bills, 14 payment deposits, and 6 applicants with 31 monthly deposits. It looks everything up before creating it, so running it again creates nothing, and it writes an id map back.Creativity.
MetThe bank is the second source that disagrees with the books, which is where real collections work happens: a payment memo that names a different invoice, a check that never cleared, an applicant whose deposits are a tenth of the revenue they claim.
Complexity.
MetThe ledger maps onto customers, accounts, bills and deposits with each deposit carrying payer, reference, memo and exact amount. Live behavior that differs from the spec, found while loading, is handled and written down: deposits drop cents, a bill without
recurring_datebreaks every bill list on its account, and balances do not move on deposits.
Screenshots


Open it yourself
- How the case maps onto Nessie, and what the live API did
- The seed script
- The Nessie client
- The credit desk write-up (Hyphenate)The seats, the 14 planted errors and the scores.
Evidence
Every merge, live against Nessie
From the Oct 24 merge-gate run on the x86 test VM:
track credit-desk
ok Nessie: Golden Gate's deposit says INV-24098 (the ledger applied it elsewhere), and the post-dated check has not cleared
ok no CRS or Nessie key is anywhere in the log
What the bank shows against the books
| Planted error | The ledger says | Nessie shows | Caught in live run 73c47b |
|---|---|---|---|
| E03 | PMT-8812 paid Greenleaf Juice's INV-24089 | PMT-8812 from Golden Gate Bagel Co | ACH 1009 GGB | memo INV-24098 | exact 1940.00 |
Yes: applied to the wrong customer and invoice |
| E05 | INV-24091 is paid by Dogpatch Deli's check | No deposit: the check is dated 2026-11-06, after the case date | Yes: post-dated check applied before its date |
| E11 | Lakeshore Diner claims $1.85M a year | Deposits of about $17,600 a month | Yes: $1,850,000 stated against $210,000 verified |
| E10 | Pacific Crest asks for $20,000 | One month of deposits, in an account opened in August | Yes: one of the fraud signals behind the hold |
What is loaded
| Credit desk | Nessie | Count |
|---|---|---|
| Fogline Supply Co. | Customer and checking account Fogline Operating |
1 |
| Each trade customer | Customer (last name is the customer id) and checking account | 12 |
| Each invoice | Bill on that customer's account: payee Fogline, nickname the invoice id, due date, completed or pending |
38 |
| Each payment the bank could have cleared | Deposit into Fogline Operating, with payment id, payer, reference, memo and exact amount in the description |
14 |
| Each applicant's bank statements | Customer, checking account, one deposit per month | 6 applicants, 31 deposits |
How it works
- YouLoad the case into Nessie
nessie-seed.ts: customers, accounts, bills, deposits. Safe to run again. - TaskA seat asks for bank data
credit-desk.bank {"what": "deposits"}, or an applicant's statements. - GurtOS coreThe tool calls NessieWith the key from the vault, over HTTPS.
- OutsideCapital One NessieFogline's deposits, a customer's bills, an applicant's monthly deposits.
- GurtOS coreClean rows back, into the logWith a note that deposits are whole dollars and the exact amount is in the description.
- TaskThe seat compares bank and booksFlags the mismatch with the rows and the rule it breaks.
- Task
- its own Linux user, its own copy of the files, no keys
- GurtOS core
- the GurtOS service on the box, root, the only part that reads the vault
- Outside
- a service outside the box
- You
- a person, on the portal, a phone, Jira or a chat
Live behavior, found while loading. Where the live API and the spec disagree, the desk follows the live API:
- Create calls return the new object (
{"code": 201, ..., "objectCreated": {...}}), where the spec says a string. - Deposits drop cents: 2169.72 is stored as 2169. The seed rounds to whole dollars and keeps the exact amount in the description, and the tool tells the agent so.
- A bill created without
recurring_dateis stored, but then every bill list on its account fails with HTTP 400. Updating it does not fix it; only deleting it does. The seed always setsrecurring_date. - Account balances do not move when a completed deposit is added, so the desk reads deposits, not
balance. - Customers cannot be deleted, and transfers have no create route, so payments are deposits.
Try it
On a test VM with NESSIE_API_KEY in the box vault, as root, from a copy of tracks/credit-desk:
sudo node sandbox/nessie-seed.ts cases/fogline-2026-10 /tmp/nessie-ids.json # load (or re-check) the case
curl -s -X POST localhost:7700/t/credit-desk/run -d '{"case": "fogline-2026-10", "seats": ["clerk"]}'
A case gets the bank tool when its case.json says "nessie": true, meaning it was loaded with the seed script.
Live, test and simulated
| Part | State | Details |
|---|---|---|
| Nessie reads | Live | Nessie's sandbox, called live in every ./demo run and every Droid run. |
| The data in Nessie | Simulated | Fogline and its customers are fictional; the seed loads their made-up ledger. |
| Writing back to the bank | Not built | The clerk's corrections are recorded in the box's log, not pushed to Nessie, so undoing a task never leaves the bank out of step. |
Limits
- Read only: the desk does not write corrections or holds back to Nessie.
- Nessie keeps deposits in whole dollars, so exact amounts come from the deposit description.
- One key per sandbox: every test machine sharing the key sees the same Nessie data.
- Our questions for Capital One (is
recurring_datemeant to be required, can a customer be deleted, should a balance move on a deposit) are insandbox/nessie.md.