A lot of this project's specification lives in markdown tables, and several tools read them. Parsing a table row looks like a solved problem: const cells = line.split('|').slice(1, -1).map((s) => s.trim()); That line is in more places than anyone had counted. Two cells broke it One spec table has a cell containing a set definition and another containing the length notation for a sequence. Written out, they carry a vertical bar inside the cell: | E0 | the admitted set | N_t := {x \| E(x,t) = true} | | S0 | length | \|·\| over a byte sequence | Both are correct markdown. The bar is escaped, which is exactly what the format asks for. The naive split does not care that it was escaped, so both rows fractured into the wrong number of cells. The symptom was not "the parser is broken" This is the part I want to keep. What the run reported was: verified_lying: 2 premise_defs: 2 Two definitions in the specification appeared to rest on nothing. That is a genuinely alarming finding, several steps more serious than a lost cell, and it is what everyone reacted to. The first stretch of work went into the two definitions themselves, both of which turned out to be fully reproduced by a proof and a test. A parser failure arrives dressed as a content failure. The cells shifted, so a column that should have held a reproduction pointer held something else, and every check downstream honestly reported what it was given. what the log said what it meant two definitions unverified a column moved by one the specification has a hole the reader has a hole It was the fourth time, and then the fifth The same class had already been found in a proof-declaration printer and in the map generator. Each time, the person who hit it fixed the tool in front of them and carried on, which is a completely reasonable thing to do and is why it kept happening. A fifth instance turned up in a shared cell-splitting helper the same week. Nothing anywhere knew how many table readers existed. There was no wrong decision to point at. There was an absent list. The repair was the inventory The fix that ended it was not a better regex. Every tool that parses a table became a declared row, and a check reads that list: OK_TABLE_READERS readers=7/7 escaped_pipe=1 lookalike=1 A new tool that reads tables has to be added to the list, and each one is exercised against a fixture containing both hazards. Adding the row is not optional in the sense that the check counts the readers it can find in the tree and compares them to the declared ones. The second hazard is the one worth stealing. The mathematical notation does not actually want U+007C. It wants U+2223, the DIVIDES character, which looks nearly identical in a monospace font and is a completely different codepoint. A reader that learned about the escaped pipe and nothing else still gets that row wrong, silently, and the fixture now contains one of each. Two things I keep A bug found more than twice is not a bug. It is a missing inventory. The third occurrence is the signal to stop patching and start asking how many places have this shape, because the patch rate is clearly not keeping up with the discovery rate. Expect a parser failure to present as a content failure. Whatever sits downstream of the parse will report faithfully on the garbage it received, and its report will be about your data rather than about your reader. When a check suddenly claims something alarming about content that was fine yesterday, suspect the thing that fed it before you suspect the content.