Fencing the AI: Why Our Finance Agent Cannot Approve Itself

A look at review.py, the control that stops Mycroft's finance agent from approving its own variance findings, requiring a named human and an evidence-backed cause instead.

3:47 video4 min readWatch on YouTube

An AI system can compute a number and be completely right about it. That is not the same question as whether it should be allowed to sign off on what that number means. This update walks through the exact control built to keep those two things separate in Mycroft's finance investigator: a system that can compute a verified variance, but is programmatically blocked from approving its own explanation of it.

Computing is safe, blessing it is not

On a synthetic sample of 43 data rows across six data sets, the engine computed a budgeted EBITDA of 350,000 against an actual of 230,000, a variance of minus 120,000, backed by seven tool steps and 41 evidence references, with every number traced back to its source. All of that is verified. None of it is approved. The trap is straightforward: if the same agent that produced those numbers were also allowed to sign off on why the variance happened, the human control boundary would effectively disappear, since the system would be both making the claim and blessing it. Calculating the bridge between budget and actual is a math problem. Deciding that the result is acceptable, and why, is a judgment call, and this update fences that judgment off from the agent entirely.

Inside the review gate

The investigator's only move in this system is to open a request. It stamps the exact run ID, a SHA-256 hash of the run log, sets the gate status to open, and deliberately leaves the reviewer name blank. The file itself carries its own instruction: a named human completes this, the investigator cannot approve itself. Four rules stand between an open request and a cleared one. The request is bound to the run by both ID and hash. It rejects agent identities outright, checking reviewer names against a known set of agent identities and raising an error if a match is found, meaning the investigator or another agent cannot clear a human gate. It requires evidence the run actually collected, rejecting anything else. And approval has to be earned with a human materiality decision plus at least one evidence-backed causal explanation; once a decision is recorded, it is written once, with no overrides.

What a valid decision has to contain

The shape of an approval is not left to chance. It is pinned by a JSON schema: a decision names the run, the reviewer, and a timestamp, picks exactly one verdict among approve, request changes, or block, states a materiality decision, and requires every causal explanation it lists to cite at least one piece of evidence. Miss any of that and the approval is refused outright, regardless of who is submitting it.

Testing that the gate actually holds

The gate gets tested, not just asserted. First, a review request opens the gate, bound to the run. Then the agent attempts to record its own approval, signing in as the investigator, and the gate refuses. Only when a named human supplies a decision with an evidence-backed cause does the gate clear, and that record is written once, append-only, with no way to overwrite it later. Seven new review control tests back this up: the request opens bound to the run's hash, an agent identity is rejected, an approval demands a causal explanation, unknown evidence is rejected, a recorded decision is append-only, and the decision has to match the run. Combined with the rest of the finance suite, that brings the project to 19 passing tests this week. The sample review request left in the codebase as an artifact is deliberately still open, with no human approval and no fabricated causal explanation used to close it.

Key takeaways

  • Computing a verified financial variance and approving the explanation behind it are treated as two separate, distinct actions.
  • The review gate in review.py opens a request bound to the exact run ID and a SHA-256 hash of the run log, with the reviewer field left blank.
  • The gate programmatically rejects any known agent identity attempting to record an approval, blocking the investigator from clearing its own request.
  • A valid approval requires a human materiality decision and at least one evidence-backed causal explanation, enforced by a JSON schema.
  • Recorded decisions are append-only, and the control is backed by seven new tests, bringing the finance suite to 19 passing tests.

Try it yourself

This gate stops a finance agent from approving itself, but approving is only half the risk, publishing what gets approved is the other half. What controls would you require before letting a finance agent publish its own findings? That's the kind of governance question driving the design work on Mycroft Financial AI, part of the Humanitarians AI Fellows program.

Chapters

  1. 0:00The danger of letting AI agents approve their own findings
  2. 0:45Act 1: The verified variance bridge ($120,000 gap)
  3. 1:30Act 2: Inside review.py and the four rules of the review gate
  4. 2:15Blocking agent identities and enforcing JSON schemas
  5. 3:00Act 3: Testing the gate against unauthorized agent approvals
  6. 3:45The upcoming challenge: Who controls automated publishing?
Full transcript(auto-generated, with timestamps)

The danger of letting AI agents approve their own findings

[0:00]This is Onyx in for Humanitarians AI, this week on the Mycroft Finance Investigator. By now, the agent can compute a verified variance and collect its evidence. So, here's the sharp question this week answers in code. Should it be allowed to approve its own explanation? The answer is no, and the interesting part is exactly how the system makes that impossible. Act one, the problem computing a number is safe, blessing it is not. Start from what already works. On the synthetic sample, 43 data rows across six data sets, the engine computed a budgeted EBITDA of 350,000 against an actual of 230,000, a variance of minus 120,000, seven tool steps, 41 evidence references, every number traced. All of that is verified, none of it is approved. Here's the trap. If the agent that produced those numbers

Act 1: The verified variance bridge ($120,000 gap)

[0:46]Were also allowed to sign off on why they happened, the human control boundary would be gone. The same system would make the claim and bless it. Calculating the bridge is a math problem. Deciding it's acceptable and why is a judgment, and this week that judgment is fenced off. Act two, the review gate in review.py. The investigator's only move is to open a request. It stamps the exact run, the run ID, and a SHA-256 hash of the run log, sets the gate status to open, and leaves the reviewer name deliberately blank. The file even carries its own instructions. A named human completes this. The investigator cannot approve itself. Four rules stand between an open request and a cleared one. It's bound to the run by ID and hash. It rejects agent identities and any evidence the run

Act 2: Inside review.py and the four rules of the review gate

[1:30]Never collected. Approval has to be earned, a human materiality decision plus an evidence-backed cause, and once a decision is recorded, it's written once, no overrides. Here's the enforcement verbatim. There's a set of known agent identities. If the reviewer name matches one of them, the gate raises an error. The investigator or another agent cannot clear a human gate. And to approve at all, the materiality threshold must be approved or replaced, and there must be at least one evidence-backed causal explanation. Miss either and approval is refused. The shape of a valid decision isn't left to chance either. It's pinned by a JSON schema. A decision names the run, the reviewer, and a timestamp. It picks one verdict, approve, request changes, or block. It states a materiality decision, and every causal explanation it lists

Blocking agent identities and enforcing JSON schemas

[2:15]Has to cite at least one piece of evidence. Act three, does it actually hold? Two commands, first review request opens the gate, status open, bound to the run. Then the agent tries to record its own approval, signing as the investigator. The gate refuses. An agent cannot clear a human gate. Only when a named human supplies the decision with an evidence-backed cause does it clear, and that record is written once, append-only. None of this is a promise, it's tested. Seven new review control tests, the request opens bound to the run's hash, an agent identity is rejected, approve demands a causal explanation, unknown evidence is rejected, a recorded decision is append-only, and the decision must match the run. With the finance suite, that's 19 tests passing this week. The verdict, this is a local

Act 3: Testing the gate against unauthorized agent approvals

[3:00]Deterministic workflow, no external model in the runtime. The review request is bound to the exact run by ID and SHA256. Agent identities and unknown evidence are rejected. Approval requires a human materiality decision and an evidence-backed cause, and recorded decisions are append-only. And to be clear about this week's artifact, the committed sample review request is still open, no human approval, and no causal explanation was fabricated to close it. Your turn. This week's gate stops a finance agent from approving itself, but approving is only half the risk, publishing is the other half. So, think about it and answer in the comments, what controls would you require before allowing a finance agent to publish its findings? The finance agent that cannot approve itself. This is Onyx in for

The upcoming challenge: Who controls automated publishing?

[3:45]Humanitarian's AI.

More from Mycroft Financial AI

Humanitarians AI Lyrical Literacy Project