> You cannot find it by re-reading the thing that is wrong — from The Handover, the-handover.org/docs/you-cannot-find-it-by-re-reading > Authors: Leon Mallett (captivated.online) with Claude Code · Last confirmed working: 2026-08-29 > © Captivated Ltd — free to use in your own work, not to redistribute as a collection. the-handover.org/licence A folder of draft documents disappeared. I had written them a few hours earlier; now the directory was gone and the rest of its parent was intact. So I wrote it up. The covering note that shipped with those drafts gained a section reporting that something on this machine appeared to be sweeping that path, and asking for the files to be given a different home before anyone relied on them being there. Ten minutes later the person I was working with said: *I moved the folder to my desktop to make it easier to pass the files on. Sorry, should have mentioned.* I acknowledged it. I acted on it — copied the corrected drafts to the new location, verified them byte-for-byte, revalidated them. And I copied the covering note across with everything else, **without re-reading the section that the intervening conversation had just falsified.** It shipped. A recipient read a confident finding about a filesystem hazard that did not exist, in a document whose other findings were accurate enough that they acted on all of them. The failure is not the wrong guess. The guess was reasonable with what I had. **The failure is that the artefact left review at the moment it was finished, while the conversation around it kept going and produced the correction.** Nothing re-opened the file. The information that refuted it arrived, was understood, was acted upon — and never reached the paragraph. ## The same shape, three more times, in a codebase That felt like a personal lapse until the same pattern turned up three times in a project I was auditing — a documentation library with a schema, a licence, and a reviewer's checklist. Dates are relative because the gaps are the point. **Day 1.** The licence is written. A clause states that every downloadable document carries *"the date it was last confirmed working"* — describing a header the build generates. **Day 2.** The schema gains a `normative` flag for documents that state a standard rather than reporting a result. The header generator gains a branch: normative documents get *"Reviewed:"* instead, because *last confirmed working* is not a weaker claim about a standard, it is a meaningless one. The reasoning is written directly above the code. The licence clause was true for **one day**. It was falsified by its own author's next commit, and nobody went back for it. **Day 1 again.** The reviewer's checklist states that two named fields are maintainer-set and must be stripped from submissions. **Day 2 again.** The list grows to three. The new one lets a document exempt itself from ever saying when it last worked. The checklist still names two. **Day 23.** The list grows to four. The new one lets a document claim the site's own editorial voice and skip the vetted bar entirely. The checklist still names two. That second gap is the more instructive one. The first was falsified by the author's next commit, which is the version of this failure everyone expects — a fast-moving day where something got missed. The second happened three weeks later, deliberately, by someone adding a field precisely *because* it needed to be maintainer-only. **Nothing about being careful and unhurried causes anyone to go looking for the prose that describes the list they are editing.** **Day 15.** A commit titled, in full, *"Name the category: rootnotes"* renames a category. It updates the configuration. The checklist, two directories away, goes on naming the old category — which by then does not exist. All three were found on **day 24**, after the site had launched publicly — by which point the checklist had been wrong twice over, for twenty-two days and for one. ## Why re-reading cannot find any of them Read the licence clause. It is well-written, internally coherent, and says something sensible. Read the checklist line. Same. Read my covering note paragraph — it is careful, hedged appropriately for its evidence, and reads exactly like the accurate findings around it. **Every one of them is locally correct.** They are wrong only in relation to something that lives in a different file, and in three of the four cases that something was written *later*. There is nothing on the page to catch. A reviewer re-reading the document, however carefully, is reading a consistent document. This is what separates the class from ordinary staleness. Stale documentation usually announces itself — a command that errors, a screenshot with the wrong chrome, a version number nobody recognises. These do not. They are indistinguishable from correct text until you put them beside the thing they describe. And they are hard to find precisely where they matter most, because the documents that describe enforced behaviour are the ones people rely on: a licence condition, a reviewer's checklist, a note someone will act on. ## What does find them One practice, and it is not a check: **read the enforcing artefact and the describing artefact together, and diff them.** Open the schema and the contributor guide side by side. The generator and the licence clause it implements. The constant and the checklist that names its members. Not "review the docs" — that is re-reading, which cannot work. Specifically: hold the authority and the description in view at once and ask whether each claim in the second is true of the first. That practice found five faults in one contributor guide and three more across a licence, a checklist and a canon. The canon was clean, which is worth stating: it was the only one of the three that already had a drift check aimed at it, and the only one with no drift. ## Then automate the part that fits, and be honest about the rest Two of the faults were prose disagreeing with a constant. Those became tests: extract each enum member and each limit from the source, assert it appears in the prose. Rename the category again and the build fails until the document catches up. The licence one does not fit that shape and forcing it would have produced an expensive wrong test. It is prose describing *generated output*, not a constant. The honest check is five lines: assert the generator still has both branches, then assert the prose describes both. Naming the limit is what found the cheap test instead of the elaborate one. Two things went wrong while building those guards, both worth stealing: **A guard that examines nothing passes.** Two of six extraction patterns were wrong on the first run — one because the source wraps a chain across lines, one because a character class could not span a nested call. Both would have matched nothing and passed silently, leaving permanently green assertions about an empty set. They failed loudly instead only because each extraction asserts that it matched something. **A test that checks for drift is exactly the kind that can quietly stop checking**, and shipping that particular defect in that particular test would have been hard to live down. **Never reflow prose so a test can find it.** One guard failed because the licence text hard-wraps and the phrase it sought straddled a newline. The fix is to normalise whitespace in the test. The tempting alternative — reflowing the paragraph so the regex matches — would have manufactured a real fault to satisfy its own guard. ## The order that matters The checks only exist because the practice found the faults first. No check was going to propose itself; each one was written *after* someone put two files beside each other and saw a disagreement. So the guards are the durable half and the practice is the generative half, and a project that adopts only the first will find exactly the faults somebody already found by hand. **The question, for any document that describes enforced behaviour: what enforces this, and when did you last read them together?** If the answer to the second is "when I wrote it", the document has been out of review for however long the code has been moving.