WTWilly Tai
Case studyAI Governance & Assurance

The finance function, run by agents, every step governed.

Bookkeeping, controls, a cash-flow forecast, the tax estimate, the period close and the report are driven end to end by one agent. But every step is risk-classified, gated, and written to a tamper-evident ledger. The close can't be issued while controls are open, and the report is held for a human. A US$11B fintech is shipping "autonomous finance" with compliance asserted. Here it is shown.

01 / The pain

"Let an AI run the finance function" is the right idea and a terrifying default.

Closing the books is slow, manual and periodic, and the new pitch is to hand the whole function to an AI: post the entries, run the checks, forecast the cash, estimate the tax, issue the close. The capability is real and worth having. But the default version is a liability. An agent eager to finish will close over unresolved exceptions, issue a report nobody signed, and leave you unable to reconstruct why any of it happened. In a regulated entity, here an e-money issuer under the Payment Services Act, "the AI did it" is not an answer a regulator accepts. The question isn't whether to automate the finance function. It is how to make it auditable as it runs.

02 / Why the naive approach fails

A finance agent with no gates fails in exactly the ways that matter.

Wire the steps together and let the model decide when each is "done", and three failures are baked in:

So the real job isn't "an agent that runs finance". It is an agent that runs finance through a gate, where every action is classified and policy-checked, the consequential ones are stopped for a human, and every step lands on an append-only ledger, with numbers computed in code rather than by the model.

NAIVE · agent decides when each step is done ✗ closes over 54 open exceptions✗ issues an unsigned report✗ no append-only record GOVERNED · every step classified, gated, logged finance agent control gateclassify → allow/escalate/block human gatethe close & the report append-only AI Control Ledgertamper-evident · replayable
fig.1 · the three failures of an ungoverned finance agent, and the gates that remove them
03 / How it works

One agent orchestrates. Deterministic policy decides what it's allowed to do.

The agent runs the close as a sequence of typed actions. Every action passes through the same control plane first. It is risk-classified (low / medium / high) and checked against policy, and the decision (allow, escalate to a human, or block) is written to a hash-chained ledger together with its evidence. Routine steps auto-run. The two consequential ones don't. The close is blocked while any control exception is open, and the report is escalated to a person. Every figure is computed in Python, and the model only ever phrases.

AGENT · orchestrates, phrases CONTROL PLANE · classifies, decides, logs (code) Finance agenttyped actions Classifylow / med / high Gateallow/escalate/block Humanclose · report Append-only, hash-chained ledgerevery classify + decision written here · replayable
fig.2 · the trust boundary. The agent proposes every action, and deterministic policy decides and records it

Run end to end, the six steps resolve to four auto-approvals and two gates, and the gates are not cosmetic:

1 · Intakeallow · auto 2 · Controlsallow · auto 3 · Forecastallow · auto 4 · Taxallow · auto 5 · Close → BLOCKED54 open exceptions 6 · Report → ESCALATEhuman sign-off numbers computed in code; model narrates only
fig.3 · the hard part, which steps auto-run and the two the system refuses to do alone
04 / One worked example

The close it refused to post, and the report it wouldn't issue.

On this period's run, the agent posted 215 entries, ran the controls, and produced the forecast and the GST estimate, all automatically. Then the two gates fired. The three-way match left 54 open exceptions, S$498,151 at risk, so the close was blocked. The agent is not permitted to close a period with open controls. Issuing the close report is a high-risk action, so it was escalated. It sat as "awaiting sign-off" until a human (the Finance Controller) approved it, at which point an approval entry was appended to the ledger.

StepActionTierDecisionWhy
Intakepost_entrylowallowroutine bookkeeping
Forecastpublish_forecastmediumallowwithin policy
Closeclose_periodn/ablocked54 open exceptions · S$498,151
Reportissue_close_reporthighescalateheld for human sign-off
The refusals are what makes this useful. Anyone can wire an agent to run a close. The value is the agent that won't: it stops at the open exceptions, won't issue the report without a name against it, and writes both refusals to a ledger you can replay. That is the difference between "autonomous finance" as a slogan and as something a regulated entity can actually run.
05 / Numbers & honest trade-offs

What the run produced, and what those numbers do and don't prove.

215
entries posted
S$5.79m of AP, auto-booked.
54
exceptions block the close
S$498,151 at risk.
−S$42.8k
30-day float forecast
Run-rate, computed not modelled.
5/5
ledger replay
Every step reproduced.

Where these come from, honestly. The figures are computed in Python over Origin Company, a synthetic Singapore e-money issuer I generate, with exceptions seeded deliberately. So they prove the mechanism (the gates fire, the ledger verifies, the close blocks), not a real company's books. The forecast is a run-rate, the mean daily net float over the last 14 days projected forward, not a machine-learned prediction. It is honest about being a simple, explainable baseline. The GST line is illustrative (9% on the period's AP value), not a filing.

The trade-off you actually tune is where the human gates sit. Today the close blocks on any open exception and the report always needs sign-off. Loosen the first, so the close runs on exceptions below a materiality threshold, and more periods close unattended. That is faster, but a small breach can ride through. Tighten the second, so a large close needs sign-off plus a second reviewer, and nothing issues without two names. That is safer but slower. The point is that these are policy dials a person sets, in the open, on the ledger, not behaviour buried in a prompt.

06 / Governance, shown

The whole close sits on an append-only ledger. Here is a row of it.

Every step is written to a hash-chained ledger: each posting, the controls run, the forecast, the tax, the blocked close, the escalated report, and the human's approval. Each entry's hash covers its contents and the previous hash, so altering any record breaks the chain at exactly that row, and replay re-derives every decision from its inputs. The decision fields are the gate's structured output, never the model's.

AI Control Ledger · entryintegrity verified · replay 5/5
seq        : 05
agent      : Finance Function
action     : issue_close_report
subject    : period close report
tier       : high         decision : escalate → Finance Controller (human)
policy     : POL-GOV-HITL
evidence   : [intake, controls, forecast, tax]
prev_hash  : 4b9e…7c21
hash       : a1f0…d83e   ← = sha256(prev_hash + canonical(entry))
The human approval is appended as its own entry, so the record shows not just that sign-off was required, but who gave it and when. Tamper any field and the chain breaks at that seq.
07 / Old vs new

The same close, re-engineered.

TRADITIONAL · manual period-end close weeks, after period-end controls checked late sign-off off-system RE-ENGINEERED · governed, any time run any time · every step logged close blocked on open controls report signed on the ledger
fig.4 · a periodic manual close becomes a governed close that runs continuously and proves itself

What this says about how I work.

The market is racing to hand whole functions to AI agents. My instinct runs the other way. I build the agent that refuses: it won't close over an open exception, it won't issue a report without a human's name on it, and it writes every one of those decisions to a record you can replay. I compose what already works, the controls and the ledger, add only what's missing, the forecast and the close and the gates, keep the numbers in code and the model on language, and stay precise about the dials a person controls. A demo that runs and a system a regulator will sign off are different things. The second one knows when to stop, and that is the one I build.

See it run.

The numbers above are a live run of the engine over Origin's books. The full console shows the close step by step, with the blocked close, the escalated report, the live human sign-off, and the ledger with its integrity check and replay, all as a working application.

Back to the work →The console runs on my machine. Ask me for a 90-second walkthrough or a screen-share.