Every finance function has one: the workbook nobody dares touch, built by someone who left, feeding numbers that get reported. Panko's research says roughly 94% of operational spreadsheets contain errors, and that human inspectors find only about 60% of seeded errors when they go looking. Retirement projects stall on a proof problem: nobody can demonstrate the replacement produces the same numbers, so the replacement quietly loses to the incumbent. This demo makes the proof mechanical. A risk register scored in code on real Enron workbooks decides what to retire first, a deterministic differ recomputes every cell of the governed micro-app against the spreadsheet, and the cutover gate is a boolean that a named owner must satisfy before anything switches over.
Register rows parsed from the Enron Spreadsheets and Emails corpus (Hermans & Murphy-Hill, figshare, CC BY 4.0) · the close workbook is seeded synthetic · deterministic engine, identical numbers every run
The pattern is depressingly stable. Close runs on inherited workbooks whose owner left two years ago. Internal audit lists "end-user computing risk" in the annual report, but nothing ranks the workbooks, so remediation has no queue. Eventually a replacement is commissioned, and testing is defined as "run both in parallel for a month and eyeball the outputs". Mid-parallel-run a residual difference appears, nobody can say which side is wrong, the project loses its nerve, and the spreadsheet lives another cycle. Meanwhile a hardcoded override pasted in three quarters ago flows into the reported numbers, because a reviewer reading values on a screen has no way to see that a SUM is no longer a SUM.
The research says the reviewer never had a chance. Panko's synthesis of spreadsheet experiments puts errors in roughly 94% of operational spreadsheets, and puts human inspectors near a 60% detection rate on seeded errors, meaning two in five planted mistakes survive a careful review. The workbook in this demo is a quarterly GST close: the tax rate hardcoded into every formula, eight legacy tie-out constants, two external links with cached values, a hidden workings column, a hidden stale sheet, and an owner listed as "left 2024, no documented handover". Every one of those pathologies came from real close workbooks I have reviewed; here they are seeded, labelled synthetic, and machine-checkable.
Rebuilding a close calculation as governed code is usually days of work. What stalls retirement is the burden of proof: the spreadsheet is the incumbent system of record, so the replacement must demonstrate it reproduces the incumbent's numbers, warts included, before anyone will sign the cutover. "Eyeball both versions for a month" cannot carry that burden, because eyeballing is exactly the 60%-detection activity the research measured.
The register scores each workbook from parsed structure: formula count and nesting depth, hardcoded constants inside formulas, external links, hidden sheets and columns, volatile functions, and single-owner metadata. The weights are fixed and printed on screen; no model touches the score. The differ recomputes all 28 formula cells of the governed micro-app from the GL inputs and the two cached external rates, and compares them to the spreadsheet's stored values. The gate is one line of code: max absolute difference on the close-pack outputs, against a tolerance declared on screen at S$0.00. The model stub has exactly two jobs: explaining risk flags by quoting the offending cell and formula text (abstaining, visibly, where the static analysis kept no cell to quote), and drafting the retirement memo from register scores and diff results only.
Here is the deterministic core from the shipped engine: the differ walks every formula cell, compares the micro-app's recomputation with the spreadsheet's stored value, keeps the earliest divergence in calculation order (which is how it locates the override that caused the cascade), and the gate reduces to one comparison:
// the retirement differ: every formula cell, spreadsheet vs micro-app cw.order.forEach(function (ref) { var c = cw.byRef[ref]; if (!c.ast) return; var d = mv[ref] - ss[ref]; // micro-app minus stored, integer cents if (d !== 0) { if (!origin) origin = ref; // earliest divergence in calc order if (isOutput[ref]) maxOut = Math.max(maxOut, Math.abs(d)); } }); // the cutover gate: a boolean over the outputs, tolerance shown on screen function gateOpen() { return maxOut <= tolerance_cents; } // tolerance = 0
All money is integer cents, so "equal" means equal, with no floating-point apologies. The micro-app is an independent hand-written implementation of the close logic; it never reads the spreadsheet's formulas, which is what makes agreement between the two implementations evidence rather than tautology.
The demo loads with the register already scored. The synthetic close workbook tops it at 56.9 of 100, driven by 18 hardcoded constants across 31 formulas, two external links, the hidden column and sheet, and the departed owner; the eight real Enron workbooks score between 21.5 and 43.5 under the same fixed weights, and clicking any row shows its flags quoted cell by cell, straight from the corpus. One Enron cell reads =1+2.786+1.33+2.03+0.538+2.656+5.928+0.739+3.502+5.872+9.97, which is the argument for hardcode scoring made better than I ever could.
The register's eight real rows are parsed from the Enron Spreadsheets and Emails corpus (Hermans & Murphy-Hill), 15,000+ actual corporate spreadsheets recovered from the Enron email archive, published on figshare under CC BY 4.0 and fetched file-by-file via the SheetJS mirror. What ships is a 7KB structural extract with per-file MD5s and source URLs; the binaries stay at the source. The 94% and 60% figures are Panko's published research on spreadsheet error rates and inspection performance, cited as the motivation, while the 100% catch rate is computed live by the shipped engine on the synthetic workbook.
The limits, stated flatly. The Enron workbooks are early-2000s vintage and parsed statically after a LibreOffice conversion; VBA and macros are out of scope, and macro-driven EUCs are often the riskiest, so the register understates exactly the workbooks that scare auditors most. The scoring heuristics are a defensible subset of full EUC frameworks, with fixed weights I chose, and they are a ranking device rather than a certified methodology. The retirement pattern shown covers formula-driven calculation workbooks; data-entry and reporting workbooks need different treatment. And the differ proves value equivalence on the cells the workbook stores, which is the cutover question, but it cannot prove the business logic was right in the first place; it will faithfully reproduce a wrong formula, which is why the memo lists every carried-over constant for owner review after cutover.
Flip the red toggle and watch the human view stay innocent while the differ lights up. Refuse to write an acceptance reason and watch the form hold the line. Take the "fix the micro-app" bait and read what the app admits. Then restore the SUM, unlock the gate, approve the cutover as the named owner, and tamper with the ledger to watch the chain locate the exact entry.
I have sat on both sides of this: the auditor listing EUC risk in the annual letter, and the engineer whose replacement lost to a spreadsheet because trust in twenty years of Excel could not be transferred by assertion. The lesson I took is that the spreadsheet is the incumbent system of record, and incumbents are entitled to due process before execution. Due process here means a scored charge sheet, a cell-by-cell trial, a named judge, and a transcript that replays. Give finance teams that, and retirement stops being an act of faith. If your close depends on a workbook whose author has left the building, this is the procedure I would run before touching it.