GurtOSat Cal Hacks 13.0

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).

  1. Best use of the Nessie banking API.
    Met

    Nessie 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.

  2. Completeness.
    Met

    nessie-seed.ts loads 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.

  3. Creativity.
    Met

    The 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.

  4. Complexity.
    Met

    The 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_date breaks every bill list on its account, and balances do not move on deposits.

Screenshots

The collections clerk task's steps: the Nessie deposits list, including PMT-8812 from Golden Gate Bagel Co with memo INV-24098, then a flagged problem: payment applied to the wrong invoice.
The clerk reads Fogline's deposits from Nessie, sees PMT-8812's memo says INV-24098, and flags that the ledger applied it to INV-24089. From a scripted run of the seats calling the real tools, live against Nessie.
The Credit desk window: the collections clerk is done, with the payment applied to the wrong invoice (PMT-8812) among its findings, and APP-1043 waits for the controller.
The Credit desk window after a Quick run: the clerk's Nessie finding, PMT-8812 applied to the wrong invoice, is listed under the collections clerk.

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

How it works, step by step
  1. YouLoad the case into Nessienessie-seed.ts: customers, accounts, bills, deposits. Safe to run again.
  2. TaskA seat asks for bank datacredit-desk.bank {"what": "deposits"}, or an applicant's statements.
  3. GurtOS coreThe tool calls NessieWith the key from the vault, over HTTPS.
  4. OutsideCapital One NessieFogline's deposits, a customer's bills, an applicant's monthly deposits.
  5. GurtOS coreClean rows back, into the logWith a note that deposits are whole dollars and the exact amount is in the description.
  6. 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_date is 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 sets recurring_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

PartStateDetails
Nessie readsLiveNessie's sandbox, called live in every ./demo run and every Droid run.
The data in NessieSimulatedFogline and its customers are fictional; the seed loads their made-up ledger.
Writing back to the bankNot builtThe 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_date meant to be required, can a customer be deleted, should a balance move on a deposit) are in sandbox/nessie.md.
Every track