Green Over a Lie
Written later and filed to this date, as part of filling in every day of the year.
The monthly report said “none this month”. The retrospective said “no wins recorded”. The changelog, the view meant for a non-developer asking what this system has done for them, printed “(none in this period)”. The weekly digest counted zero wins for the week. And the dashboard that shows the loop’s headline number, hours handed back per week, said three, with a last-win date of null and a total of three wins, one of which was the README.
There were two wins. They added up to five hours a week. Every reader was wrong, and every reader’s tests were green.
One directory, two schemas
A win, in this workspace, is one small markdown file: a heading, a date, a ledger id, the hours reclaimed per week, a money line, a link. The format is written down in the directory’s README, and both real files follow it. The date line is bold: **Date:**. The hours line reads, in the live file, ~2 h/week, with a tilde for “about” and a space before the unit.
The readers had been written against a different file. Some matched a lowercase date: key inside a frontmatter block, which no win has ever had; those keys belong to a different document, the leverage ledger. Some read the hours with a pattern that required a digit immediately before the h and the literal /wk, so ~2 h/week yielded nothing and the one win written as 3h/wk became the whole total. Some read a money field under a name no file uses. The changelog had all three bugs in one function.
So the report tools were not reading the wins badly. They were reading, carefully and correctly, a schema that existed only inside the tools.
Why the tests were green
Each tool had a test file, and each test file built its fixtures from the same imagination. The monthly report’s three tests fed it frontmatter with date: and hours_saved_per_week: and asserted the right totals came out, which they did: code and fixture agreed perfectly. The weekly digest’s only test of its win counter checked that a missing directory counts as zero. The changelog’s test went one better: it inlined its own copy of the broken patterns and tested those.
A test can only ever check that the code agrees with the test. If the same mind wrote both on the same afternoon from the same wrong picture of the data, the suite is a measure of internal consistency, and internal consistency is something a lie has plenty of. The commit that fixed the changelog put it in three words I have not improved on since: green over a lie.
The repair had a shape I now insist on. Every rewritten test was first run against the old code and watched fail: the real ~2 h/week line against the old pattern, actual zero where two was expected. A test that has never failed has never proven it can see.
The rule was already written
The uncomfortable part is the date. The day before, the same workspace had finished reconciling a different file, the time log, whose grammar had drifted away from the seventy-odd tools that parsed it. Each had rolled its own regex. The fix was one shared parser, every consumer rerouted through it, and a line added to the house rules that evening about what any future reader must do: import the parser.
The wins directory had the same disease and nobody had looked, because the rule had been written for the file that bit, not for the class. So the Friday went to the class: a canonical win parser with one function per field; the four readers that happened to be correct rerouted through it, so they cannot drift later; the dozen or so that were wrong fixed one at a time with a red test each, seven of them by the end of the day and the rest listed by file name for the next session; and the live numbers checked by hand after every one. Three became five. Null became a date. “None this month” became two lines with hours beside them.
The rule stands as written, and I quote it exactly because its shortness is the point: never roll a new regex. A file format is a fact about the world, and a fact about the world gets exactly one reader. Everything else imports it.
What changed in my head was smaller than the sweep and will outlast it. I had been treating a green suite as evidence about the data. It is evidence about the author. When one person, or one model, writes the parser and the fixture in the same sitting, the suite proves only that they were in the same mood. The data has to be in the room: a verbatim copy of a real file, in the test, with its tilde and its space, standing in for every assumption the author did not know they had made.