Phase 3 · complete · the milestone that mattered
Your Chapter 5, rebuilt from raw logs, in one command
Every table and figure in Chapter 5 was produced by a script that read your log files. Phase 3 writes a second, independent program that reads the same logs — and checks whether the two agree, character for character.
Two commands
$ bun run replay
replay — 51 cells from archive/legacy_runs
test-verified (report.json) 42
apply-verified (no report) 9 of which APPLY_FAIL: 9
baseline resolved 12/20
failure pool 8 evaluable: 7
recovered 3/7
logic-class 0/4
format-class 3/3
failure pool matches declared yes
failure class matches hardcoded yes
$ bun run report
byte-identical to the committed master_table.md
That last line is the whole point of the phase.
A program written from scratch, months later, in a different language, reading the same evidence, produced your submitted table with not one character different. Your Chapter 5 is now reproducible rather than merely written down.
The 22 cells nobody could see
The first thing the new reader noticed was an arithmetic problem. The archive holds 95 evaluated task folders and 95 patch files — but only 73 result files.
The reason is a detail of how the evaluation harness works. When
git apply refuses a patch, the harness throws an error
before it writes its report. Your table-building script looks for
report files. So those 22 attempts — every one of them a patch that failed to
apply — were invisible to every table you produced.
Those cells can never be mistaken for successes. Each is marked as verified by patch-application only, its “resolved” field is forced to empty, and the function that computes a success rate will not accept them — the safeguard built in phase 1, doing its job on real data.
The classification you made by hand, checked
Your script begins with a promise: “Nothing in this script invents a number. Every cell is read from a report.json.” It keeps that promise for 38 of its 42 records. The four format-class rows are written from a list typed by hand, because — as we now know — no result file exists for them to read.
So phase 3 derives the logic/format split from the outcomes themselves and compares it with your list:
failure_pool.json, which is a third independent copy of the same
list.
Your judgement was right. What changes is its status: a constant that nothing could contradict is now a result with a test attached.
Proving the check can actually fail
A test that always passes proves nothing. So after everything was green, we deliberately broke the analysis in two ways and confirmed the suite noticed.
| Sabotage introduced | Result |
|---|---|
| Score the baseline out of 16 (the tasks with results) instead of 20 — the survivorship error | 3 tests failed |
| Go back to collecting result files, dropping the 22 — the original blind spot | 9 tests failed |
Both were then reverted, and all 191 tests pass again. The check has teeth.
What was deliberately not done
The .drawio figure sources and their exported images are
not regenerated. Those images are already embedded inside
Self.docx, which is final and cannot be re-exported — so rewriting
them could only create a difference between the repository and the document you
submitted.
Instead, the data behind figures 5.1 to 5.4 is now computed and committed as a file, and tested against the numbers typed into the figures. The pictures stay exactly as submitted; the numbers in them are now checkable. One quantity resisted: the 1× / 2× / 3× input-cost comparison in figure 5.4. The archive contains no token records at all — the original never wrote any — so that figure's data is carried as a labelled input from your configuration notes, marked in the file as not measured by this pipeline. Phase 4 is what fixes that going forward.
Where this leaves the project
Four of nine phases were done at this point, and the repository can now do something the original never could: reproduce the entire results chapter, offline, on any machine, in about three seconds — with no API key, no network and no Docker.
Next was phase 4: the first live model call, with a token budget that is enforced rather than merely written down, and usage recorded per attempt. It found four things wrong with the endpoints we thought we understood.