An AI audit assistant produces and extracts numbers faster than a reviewer can check them, and a number nobody can replay is a number a reviewer must take on faith. The recompute layer sits under any such tool: for each figure, one deterministic kernel call recomputes it from first principles and returns a receipt your reviewer can replay offline. Written for the audit manager who signs the workpaper and the reviewer who has to rely on it.
Start with a single figure rather than the whole draft. The first receipt proves the sequence to yourself; everything after it is repetition.
execution_hash binds the declared inputs to the recomputed output. File it beside the assistant's draft. To go one step further, build_ai_workpaper_record composes the receipt with engagement metadata and a reviewer sign-off statement; the mapping to the documentation elements is in AI Evidence Auditors Can Actually Review.execution_hash, in a browser, offline. For a full set of receipts, compose_workpaper_bundle packages them into a self-contained bundle a reviewer can open with no connection at all.| The number in the draft | Call (mcp_name) | What the call takes |
|---|---|---|
| A schedule figure the assistant drafted: depreciation, interest accrual, EPS, amortization | run_audit_recalc_suite | One item per figure: the schedule category, its inputs, and the client-reported figure to diff against |
| A report extract the assistant pulled from a client system | verify_ipe_integrity | Declared hashes, row counts and a control total for the source extract and for the report built from it |
| The receipt itself, filed as documentation | build_ai_workpaper_record | The receipt's identity fields, a declared determinism class, engagement metadata and a reviewer statement |
| A set of receipts, handed to a reviewer | compose_workpaper_bundle | A procedure id, a population hash, the prior receipts' execution hashes and three sign-off roles |
Call names as registered in the OpenChainGraph registry (chaingraph).
The recompute checks arithmetic against the values declared in the call; it does not read source documents, so a declared value that misstates the document behind it recomputes cleanly and still misses the misstatement. Judging whether the declared values match those documents, and concluding on the balance, stays with the engagement team.
The assistant's draft reports depreciation of 6,400 for asset A-2 in period 2: cost 20,000, salvage value 2,000, a five-year life, double-declining balance. The request passes that stated figure along with the schedule inputs, and declares no tolerance, so the receipt echoes the recorded 0/0 default and flags any nonzero variance.
{
"policy_parameters": {
"depreciation": [
{ "asset_id": "A-2", "method": "ddb", "cost": 20000, "salvage_value": 2000,
"useful_life_years": 5, "period_number": 2, "client_reported_depreciation": 6400 }
]
}
}The kernel returns a receipt: recalculated depreciation 4,800 against the declared 6,400, a variance of −1,600 (−25%), flagged: true, flagged_count: 1, with tolerance_used recording {abs: 0, pct: 0, declared_by_caller: false}. The returned execution_hash:
"execution_hash": "773faaa3f7492188552e9a38bb5bb0f0d1d1d22a801f344d2436cf33fdf6c882"This request and this hash come from a real run of the recalculation kernel: re-running the same declared values reproduces the same hash, which is exactly what the reviewer's replay checks. Source: vector ddb_no_tolerance_declared in the kernel's fixture file, chaingraph/kernels/fixtures/art-463-recalc-suite.fixtures.json, with all values synthetic.
The same recompute reaches you three ways, and they differ in one respect that matters: whether your declared values leave the device.
| Path | Where the compute runs | What leaves your device |
|---|---|---|
| Browser tool page | Inside the page itself, in your tab | Nothing: the values you enter stay in the tab, and the page makes no network calls |
| Local handover bundle | In the bundle's embedded verifier, opened locally | Nothing: the bundle is a self-contained file a reviewer opens offline |
| Hosted MCP call | On the MCP worker, server-side | The declared values in your request are sent to the worker, which computes with them and returns the receipt |
Treat the hosted path as the one to feed with synthetic or redacted values. The receipt attests the recompute of whatever values you declared, so a redacted set gives up none of the verification while keeping real figures off the wire.