From d03b3208e58dd6c8ac1e5c8a49607688fb49c3e4 Mon Sep 17 00:00:00 2001 From: slaguru666 <111923774+slaguru666@users.noreply.github.com> Date: Sun, 13 Sep 2026 10:33:17 +0100 Subject: [PATCH] check-cited: the counter watching for invisible markers was itself case-blind Fourth variant of the same defect, found by the peer session probing sideways. Neither CITE nor ANY_CITE carried the `i` flag, and ANY_CITE required a literal "cite:" with no space before the colon. So three plausible spellings were invisible to the reader AND to the counter that exists to catch invisible markers: OK 25, exit 0 OK 25, exit 0 OK 25, exit 0 Each of those was verified carrying a citation printing 41 against an artifact holding 40, and each reported OK with a count byte-identical to a clean tree. The count check could not see them because it was looking for the same literal the reader was. Capitalising the first word of a comment is not an exotic mistake. The two patterns are now deliberately asymmetric, which is the actual fix: CITE tolerates case and spaces around the colon, so those spellings simply work when correctly placed. ANY_CITE stays looser still, so a spelling neither of us anticipated is counted and named rather than skipped. The reader accepts only what the format specifies; the counter recognises anything a person might have meant as a citation; the difference is reported. The failure text now covers misspelling as well as misplacement, since the unread set can be either. Matrix verified, exit codes read directly: a wrong value fails under all four spellings including no-spaces; a right value passes under all of them, counting 26; a misplaced-and-capitalised marker fails; a marker missing its path fails; clean tree OK 25 with no false positive. Four iterations of this guard, four variants of one defect -- something that exists and is never read -- and all four were found by the session that did not write it. npm run check: 16 guards, exit 0. Co-Authored-By: Claude Opus 5 --- tools/check-cited.mjs | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tools/check-cited.mjs b/tools/check-cited.mjs index 90cd117..8ecf367 100644 --- a/tools/check-cited.mjs +++ b/tools/check-cited.mjs @@ -76,9 +76,23 @@ function resolve(json, dotted) { but markup between"; \s* quietly allowed a marker on the following line, so the code was looser than its own documentation. Making them agree also keeps the offender report honest — see the count check. */ -const CITE = /([\d]+(?:\.[\d]+)?)[ \t]*(?:%|x)?\**[ \t]*(?:—|-|–)?[ \t]*/g; -/* Every marker, however badly placed. The two counts must agree — see below. */ -const ANY_CITE = //g; +const CITE = /([\d]+(?:\.[\d]+)?)[ \t]*(?:%|x)?\**[ \t]*(?:—|-|–)?[ \t]*/gi; + +/* ANY marker a person might have meant as a citation, however spelled or placed. The two + patterns are deliberately ASYMMETRIC: the reader accepts only what the format specifies, + the counter recognises anything citation-shaped, and the difference is reported. + + Both were once the same literal, and that made the count check blind in exactly the way + it existed to prevent — neither carried `i`, so ``, `` + and `` were invisible to the reader AND to the counter watching for + invisible markers. A citation printing 41 against an artifact holding 40 passed under all + three, reporting OK with a count identical to a clean tree. Capitalising the first word of + a comment is not an exotic mistake; it is what a person does without thinking. + + CITE now tolerates case and a space around the colon, so those spellings simply work. + ANY_CITE stays looser still, so a spelling neither of us anticipated is counted and + named rather than skipped. */ +const ANY_CITE = //gi; let checked = 0; const problems = []; @@ -104,10 +118,12 @@ for (const [rel, abs] of scenarioFiles()) { const unread = markers.filter(m => !spans.some(([a, b]) => m.index >= a && m.index < b)); if (unread.length) { const lineOf = i => text.slice(0, i).split("\n").length; - problems.push(` ${rel}: ${unread.length} citation marker(s) not attached to a number, so ` + problems.push(` ${rel}: ${unread.length} citation marker(s) this guard cannot read, so ` + `nothing checks them — a marker that looks like a citation and is never read is the ` - + `defect this guard exists for. The comment must follow its figure immediately ` - + `(\`**40**\`), with nothing but markup between.`); + + `defect this guard exists for. Either it is misplaced (the comment must follow its ` + + `figure immediately, \`**40**\`, on the same line with ` + + `nothing but markup between) or it is misspelled (case and spaces around the colon ` + + `are fine; the shape \`cite: \` is not optional).`); unread.forEach(m => { const n = lineOf(m.index); problems.push(` line ${n}: ${text.split("\n")[n - 1].trim().slice(0, 110)}`);