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:
<!-- Cite: first-blood cut.swing --> OK 25, exit 0
<!-- CITE: first-blood cut.swing --> OK 25, exit 0
<!-- cite : first-blood cut.swing --> 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0de463c470
commit
d03b3208e5
+22
-6
@@ -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]*<!--[ \t]*cite:[ \t]*([\w-]+)[ \t]+([\w.]+)[ \t]*-->/g;
|
||||
/* Every marker, however badly placed. The two counts must agree — see below. */
|
||||
const ANY_CITE = /<!--\s*cite:[^>]*-->/g;
|
||||
const CITE = /([\d]+(?:\.[\d]+)?)[ \t]*(?:%|x)?\**[ \t]*(?:—|-|–)?[ \t]*<!--[ \t]*cite[ \t]*:[ \t]*([\w-]+)[ \t]+([\w.]+)[ \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 `<!-- Cite: ... -->`, `<!-- CITE: ... -->`
|
||||
and `<!-- cite : ... -->` 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 = /<!--[ \t]*cite[ \t]*:[^>]*-->/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**<!-- cite: ... -->\`), with nothing but markup between.`);
|
||||
+ `defect this guard exists for. Either it is misplaced (the comment must follow its `
|
||||
+ `figure immediately, \`**40**<!-- cite: artifact path -->\`, on the same line with `
|
||||
+ `nothing but markup between) or it is misspelled (case and spaces around the colon `
|
||||
+ `are fine; the shape \`cite: <artifact> <dotted.path>\` is not optional).`);
|
||||
unread.forEach(m => {
|
||||
const n = lineOf(m.index);
|
||||
problems.push(` line ${n}: ${text.split("\n")[n - 1].trim().slice(0, 110)}`);
|
||||
|
||||
Reference in New Issue
Block a user