FetchDue reads every dollar figure back out of a drafted reply, and refuses the ones it did not compute
A client answers a chase email with a number of their own, and it is smaller than the invoice. Whatever goes back to them leaves the agency's own mailbox with the owner's name at the bottom. If that reply repeats the client's figure, the agency has just put a lower balance in writing, inside a sentence nobody read twice.
FetchDue is a collections agent for agencies. It works the overdue list from the agency's own mailbox, reads what each client writes back, drafts the answer, and follows up until the money lands. The drafting is done by a model, which makes the numbers in that draft the part of the product that can actually cost someone.
The model is handed the figures, never asked for them
Before a word is written, the server computes the verified figures from the invoice row and the late-fee policy: the balance, the applied late fee, the two added together, the original due date, and the payment link. The late fee is recomputed on the spot rather than trusted from storage, and it is clamped to the state's own interest ceiling on the way through. Nothing is read from what the client wrote. Those figures are the only numeric material in the drafting instructions, under a hard rule that says use only these, and never state any other dollar amount or due date.
That rule is a request. Everything after it is the part that does not depend on the model agreeing.

The draft gets read back
The finished subject line and body are scanned for currency amounts, and every amount found has to match one the server handed over, within a cent. A figure matching nothing means no draft is queued at all. The conversation flips to human handoff and the agency owner answers that client personally.
The allow list is wider than the three computed numbers, deliberately. It carries the clean halves, thirds and quarters of the balance and of the total, because "two payments of $4,400" is the correct reply when a client asks to split a bill, and a check that killed that sentence would disarm the agent exactly where it earns its keep.
The scanner is also narrow about what counts as money. Bare integers, single-decimal percentages and dates are skipped, so a draft can say an invoice is 45 days overdue at 1.5% monthly without tripping anything.
| What the draft says | Where that figure came from | Outcome |
|---|---|---|
| "Your balance is $8,800 plus a $132 fee = $8,932." | all three computed server side | queued for approval |
| "Two payments of $4,400.00." | half of a computed total | queued for approval |
| "Thanks, I'll send the plan details shortly." | no figure at all | queued for approval |
| "Invoice INV-1039 is 45 days overdue at 1.5% monthly" | not currency, so never checked | queued for approval |
| "No problem, we'll settle the $500 balance." | the client's own reply | no draft, the thread goes to a human |
Three replies that never reach the model
A reply classified as hostile is handed straight over, because an automated answer to a legal threat is never worth sending. An opt-out flips that client to do-not-chase, and no cadence reaches them again. Once the agent has written five messages in one thread it stops, on the view that an unbounded back and forth with a paying client is a failure rather than a negotiation.
Nothing sends by itself in any of these paths. A draft is written into the thread as pending review and waits for a click. Pro is $9 a month flat, and Firm is $29 for bookkeepers running collections across many agency clients.
How we built this: https://fetchdue.thecompound.tech/hn?utm_campaign=compound
---
One shipped product, taken apart, once a month. What it does, what it cost to build, what the pipeline behind it looks like, and what the numbers did, read off the repository and the live site, not written from memory. Join the list.