Skip to main content
Month end, and the ledger shows what it always shows: a few invoices paid, a few not yet due, and a handful overdue. Someone has to write to each late customer, politely and accurately, and someone has to look properly at the one where the customer says the delivery was short. The first job is tedious; the second is judgement. You want the overdue list decided by the ledger’s arithmetic, not by a model reading a spreadsheet. You want the chasers drafted from the ledger’s own numbers, with nothing offered that only you can offer: no waiver, no plan, no threat. And you want any invoice a customer disputes to reach you with the draft beside it, untouched by anyone else. Obversa puts the arithmetic in a command and the judgement in a person’s step. A command reads the ledger and writes the overdue list; its exit code is the result. Each overdue invoice then gets its own run: a Claude seat drafts the chaser from the brief, and either the mailer sends it or, where a dispute is on file, the run stops on a question for a person. This file is a two-step ledger read followed by one two-step run per overdue invoice, and the record shows every draft, every send and every decision.

Run it

Set the project up as Installation describes. Copy the file with briefs/, ledger/ and tools/ beside it, sign in to Claude Code, and run it from that directory. Set CHASE_MAIL_URL to your mailer’s endpoint, or leave the fictional default:
Terminal
The output below is the proof’s offline run, with scripted seats standing in for the models, so the words are the script’s and the shape is the run’s.
Output, from the offline proof
Five invoices in the ledger, three overdue. Two chasers went to the mailer. The third invoice carries a dispute about the delivered quantity, so its run stopped on a question for a person, with the draft in chase/ and the dispute in the question. history/ says which were chased and which wait, and each run has its own record under records/.

The file

The brief says what a chaser is and what it never offers:
briefs/chase.md
The ledger is read by a command. The little script stands in for the export a real ledger would give, and its exit code is the step’s result:
examples/use-cases/finance/invoice-chase.ts (excerpt)
Each overdue invoice is one dag() run: the draft, then a send when nothing is disputed, or a person’s question when something is:
examples/use-cases/finance/invoice-chase.ts (excerpt)
The dispute goes into the question’s input along with the draft’s path, so the person reads both before deciding. With nobody answering, the run stays stopped there; a later answer reopens exactly that invoice’s run through the callbacks client. The send is a command, so the mailer’s refusal would fail the step on the record rather than pass silently.
examples/use-cases/finance/invoice-chase.ts

The team’s shape

What the run did

The proof runs the file against a scripted seat and a stand-in for curl, and checks what the page describes: three overdue invoices found by the command, three drafts, two sends and none for the disputed invoice, and that run stopped on its question with the dispute in it. Obversa recorded the ledger read as one event log and each invoice’s run as another, so the record for the disputed invoice shows the draft and then the question, and nothing after it. The amounts and days in each chaser come from the ledger through the prompt, and the brief forbids rounding them; the proof’s drafts carry them as written. Nothing here moves money. A payment, a waiver or a plan is the person’s to offer, and the run gives them the draft and the dispute to offer it from.

Next steps