Most back-office automation fails in the same quiet way. The script runs, the API returns 200, and six weeks later somebody finds the ledger and the spreadsheet disagree by four invoices.
The system of record is the one thing you do not automate
In a finance or accounting function there is always one system that is authoritative. The general ledger, the practice system, the billing platform. In most finance stacks it is vendor-controlled, its change history is audited, and you cannot alter its internals even where you own the licence.
So the useful automation is never inside it. It goes around it: read from it, do the work somewhere else, write back through the interface the vendor sanctions. That constraint is the whole design, and it is good news. Automation that stays outside the ledger is the automation you can take out again.
The awkward part arrives immediately afterwards. Once the work happens outside the authoritative system, nothing guarantees the two ever agree.
A write that returned no error may not have happened
This is the failure worth designing against, and it is not exotic. A request succeeds, the receiving system applies a rule you did not model, and the record you believe you created is not there. Nothing throws. Your logs say success. The only evidence is a difference between two places, and nobody is looking at both.
We hit exactly this in our own system, which is an automation built around half a dozen platforms we do not control. It drafts and stages everything a human then approves. Early on it trusted its own queue: if an item said staged, it was staged.
It was not always. Now the first thing it does each day is reconcile — go back to each live surface, ask what is actually there, and compare. This morning's run put three items straight: one draft present in the mailbox with nothing sent, and two items whose supposed comments matched nothing live. None of those three had reported an error when it ran.
Reconciliation is code that re-reads both sides
The distinction matters, because the usual answer to this problem is a screen with green ticks on it, and a screen is not a check.
A reconciliation is code that re-reads both sides and states a verdict the system then acts on. It runs whether or not anyone is watching. It produces a small number of facts — this matched, this did not, this could not be read — and something downstream refuses to proceed on the second and third. Our run treats an unreadable answer as its own verdict rather than folding it into the failure count, because "I could not tell" and "it did not happen" are different problems and only one of them is yours.
Three rules we would defend anywhere:
Read the live surface every time. A queue that audits itself always passes.
Reconcile before anything reads the state, not after the work. A verdict that arrives after the decision is a report.
Make the unreadable case a third outcome. Two-state checks quietly file "unknown" under whichever answer is cheaper.
What breaks silently is what nobody priced
The reason this is worth building at the start rather than the end is that the failures have no symptom. A duplicated payment is noticed. A payment that silently never left is noticed at quarter end, by a person, in a spreadsheet. That spreadsheet is the manual control the automation was meant to replace. It still runs, and now nobody funds it.
That is also the test of whether an automation saved anything. If the reconciliation is a human eyeballing two screens on the last Friday of the month, the work moved; it did not go away.
What it costs us to run
Our own engine is four scheduled jobs and a human approval step. The cash is $34.05 a month of subscriptions against $84.60 of model tokens, measured over 39 runs in the first three weeks of September and projected to the month.
The number that surprised us is the ratio underneath it. Those runs loaded 58,945,807 tokens of context against 553,366 tokens of output — about 107 to 1. Almost all of the money buys the system reading things, and reconciliation is reading things. It is the cheap half of the bill and the part that makes the rest trustworthy.
One caveat we will not round away: 88 runs spent tokens the log could not parse, and they are excluded from that total. The real figure is higher.
Where this lands
If you are automating around a ledger you are not allowed to change, the reconciliation is not a phase two. It is the thing that makes phase one safe to switch on, and it is usually a day of work at the start against a quarter of confusion later.
We build this kind of automation, and the reconciliation comes with it rather than after it. If that is the shape of the problem you have, talk to us about it — a conversation first, and we will tell you if it is not worth doing.