From 3d6f672c2fecf294ce009442f808add687c2a71a Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Thu, 30 Jul 2026 08:42:33 +0200 Subject: [PATCH 1/2] fix(docs): close doc-metrics gate's blind spot for open bullets in historical sections (F-1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stripHistoricalSections() blanked every line in a dated/historical section, including genuinely still-open `- ⬜` bullets -- exactly how a stale "Tag v1.24.2" bullet escaped the gate in a same-day doc edit (dc14bc0). DONE_BULLET already had the mirror rule for the opposite polarity (a `- ✅` bullet is historical regardless of section); OPEN_BULLET now gets the same treatment for the "always present-tense" direction. scanForDrift() gains a matching check: a surviving open bullet mentioning tag/release/publish of a version <= the latest git tag is now a drift finding, reusing the existing getLatestReleasedVersion()/semverLte() helpers and the PLANNED check's null-latestVersion skip behavior. Verified the repaired gate actually catches the original defect: reverted TODO.md's already-fixed bullet to ⬜, confirmed the OLD logic passed clean (exit 0) and the NEW logic fails with the exact finding (exit 1), then restored TODO.md. Co-Authored-By: Claude Sonnet 5 --- scripts/check-doc-metrics.mjs | 25 ++++++++++++++++- tests/unit/checkDocMetrics.test.ts | 44 ++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/scripts/check-doc-metrics.mjs b/scripts/check-doc-metrics.mjs index 0e817c48..650b4b34 100644 --- a/scripts/check-doc-metrics.mjs +++ b/scripts/check-doc-metrics.mjs @@ -39,6 +39,11 @@ const ANY_HEADING = /^#{1,6}\s+/; const HISTORICAL_MARKER = /(✅|\bRELEASED\b|\bDELIVERED\b|\bCompleted\b|\[\d+\.\d+\.\d+\]|\(\d{4}-\d{2}-\d{2})/i; const DONE_BULLET = /^\s*-\s*✅/; +// QNBS-v3: mirrors DONE_BULLET's "always present-tense regardless of section" rule for the +// opposite polarity — an open `- ⬜` bullet describes something NOT yet done, so it must survive +// stripping even inside a dated/historical section (that's exactly how a stale ⬜ line escaped +// this gate in a same-day doc edit — see the OPEN_BULLET_VERSION check in scanForDrift below). +const OPEN_BULLET = /^\s*-\s*⬜/; // QNBS-v3: how many lines below a heading to look for a "**Status:** ✅ Released …" marker that // applies to the whole section (this repo puts it on its own line, not in the heading text). const STATUS_LOOKAHEAD = 5; @@ -65,7 +70,12 @@ export function stripHistoricalSections(markdown) { } } - return lines.map((line, i) => (historical[i] || DONE_BULLET.test(line) ? '' : line)).join('\n'); + return lines + .map((line, i) => { + if (OPEN_BULLET.test(line)) return line; // never strip — see OPEN_BULLET comment above + return historical[i] || DONE_BULLET.test(line) ? '' : line; + }) + .join('\n'); } /** Actual locale count = directories under locales/ (translation-glossary.json is a file, not a locale). */ @@ -187,6 +197,19 @@ export function scanForDrift(content, filePath, { localeCount, keyCount, latestV ); } } + // QNBS-v3: catches a stale "⬜ Tag/Release/publish vX.Y.Z" bullet that should have flipped to + // ✅ once that version actually shipped — the exact class of drift that escaped the gate when + // stripHistoricalSections() had no OPEN_BULLET exemption (see comment above its definition). + if (OPEN_BULLET.test(line) && /\b(?:tag|release|publish)\b/i.test(line)) { + for (const m of line.matchAll(/v(\d+\.\d+\.\d+)/gi)) { + const mentioned = m[1]; + if (semverLte(mentioned, latestVersion)) { + findings.push( + `${filePath}:${i + 1} — open "⬜" bullet mentions tag/release/publish of v${mentioned}, but v${mentioned} <= latest released v${latestVersion}: "${line.trim()}"`, + ); + } + } + } } }); diff --git a/tests/unit/checkDocMetrics.test.ts b/tests/unit/checkDocMetrics.test.ts index ff0b5c6c..addcfbfe 100644 --- a/tests/unit/checkDocMetrics.test.ts +++ b/tests/unit/checkDocMetrics.test.ts @@ -62,6 +62,27 @@ describe('stripHistoricalSections', () => { expect(stripped).not.toMatch(/Historical/); expect(stripped).toContain('Present: 17 locales.'); }); + + // QNBS-v3 (F-1): regression guard for the dc14bc0-shaped drift — a stale `- ⬜` bullet sitting + // inside a dated/historical section was invisible to the gate because DONE_BULLET had no mirror + // for the open-bullet polarity. + it('preserves an open "⬜" bullet even inside a dated/historical section', () => { + const md = [ + '## v1.24.2 — CSP/crypto/doc-truth hardening (2026-07-29)', + '', + '- ⬜ **Tag `v1.24.2` + publish the GitHub Release** — maintainer action.', + ].join('\n'); + const stripped = stripHistoricalSections(md); + expect(stripped).toContain('⬜ **Tag `v1.24.2`'); + }); + + it('still blanks a "✅" bullet even inside a live, non-historical section', () => { + const md = ['## Current status', '', '- ✅ Already-done item that should not be scanned.'].join( + '\n', + ); + const stripped = stripHistoricalSections(md); + expect(stripped).not.toContain('Already-done item'); + }); }); describe('scanForDrift', () => { @@ -102,6 +123,29 @@ describe('scanForDrift', () => { const findings = scanForDrift(content, 'FAKE.md', actual); expect(findings).toHaveLength(0); }); + + // QNBS-v3 (F-1): the OPEN_BULLET_VERSION check — a stale "⬜ Tag/Release vX.Y.Z" bullet for an + // already-released version must be flagged now that stripHistoricalSections() preserves it. + it('flags an open "⬜" bullet for tagging/releasing a version <= the latest release', () => { + const content = '- ⬜ **Tag `v1.24.1` + publish the GitHub Release** — maintainer action.'; + const findings = scanForDrift(content, 'FAKE.md', actual); + expect(findings.some((f) => f.includes('v1.24.1'))).toBe(true); + }); + + it('does not flag an open "⬜" bullet for tagging a version newer than the latest release', () => { + const content = '- ⬜ **Tag `v1.25.0` + publish the GitHub Release** — maintainer action.'; + const findings = scanForDrift(content, 'FAKE.md', actual); + expect(findings).toHaveLength(0); + }); + + it('does not flag any version-based drift when latestVersion is null (shallow/tagless checkout)', () => { + const content = [ + '- ⬜ **Tag `v1.24.1` + publish the GitHub Release** — maintainer action.', + '## Upcoming — v1.0 (PLANNED)', + ].join('\n'); + const findings = scanForDrift(content, 'FAKE.md', { ...actual, latestVersion: null }); + expect(findings).toHaveLength(0); + }); }); // QNBS-v3 (F-10): regression guard for the dead worldscript-studio-indol.vercel.app URL that had From d2be95ed8c63ff8a25b3c1d08736fdcb0c406c90 Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:24:18 +0200 Subject: [PATCH 2/2] fix(docs): address CodeRabbit review on WS-1 (single-line comments, inflected action forms) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Collapsed 4 multi-line QNBS-v3 comments to the required single-line format (also dropped the ad-hoc "(F-1)" tag to match the plain `// QNBS-v3: ` convention). - The OPEN_BULLET action matcher only matched base verb forms (tag/ release/publish), so a stale bullet phrased "Tagging"/"Releasing"/ "Publishing" would have evaded the new gate — added the inflected forms, with 3 new parameterized test cases. Co-Authored-By: Claude Sonnet 5 --- scripts/check-doc-metrics.mjs | 14 ++++++-------- tests/unit/checkDocMetrics.test.ts | 16 +++++++++++----- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/scripts/check-doc-metrics.mjs b/scripts/check-doc-metrics.mjs index 650b4b34..eec622b6 100644 --- a/scripts/check-doc-metrics.mjs +++ b/scripts/check-doc-metrics.mjs @@ -39,10 +39,7 @@ const ANY_HEADING = /^#{1,6}\s+/; const HISTORICAL_MARKER = /(✅|\bRELEASED\b|\bDELIVERED\b|\bCompleted\b|\[\d+\.\d+\.\d+\]|\(\d{4}-\d{2}-\d{2})/i; const DONE_BULLET = /^\s*-\s*✅/; -// QNBS-v3: mirrors DONE_BULLET's "always present-tense regardless of section" rule for the -// opposite polarity — an open `- ⬜` bullet describes something NOT yet done, so it must survive -// stripping even inside a dated/historical section (that's exactly how a stale ⬜ line escaped -// this gate in a same-day doc edit — see the OPEN_BULLET_VERSION check in scanForDrift below). +// QNBS-v3: mirrors DONE_BULLET's "always present-tense regardless of section" rule for open bullets, so a stale ⬜ can't hide in a historical section const OPEN_BULLET = /^\s*-\s*⬜/; // QNBS-v3: how many lines below a heading to look for a "**Status:** ✅ Released …" marker that // applies to the whole section (this repo puts it on its own line, not in the heading text). @@ -197,10 +194,11 @@ export function scanForDrift(content, filePath, { localeCount, keyCount, latestV ); } } - // QNBS-v3: catches a stale "⬜ Tag/Release/publish vX.Y.Z" bullet that should have flipped to - // ✅ once that version actually shipped — the exact class of drift that escaped the gate when - // stripHistoricalSections() had no OPEN_BULLET exemption (see comment above its definition). - if (OPEN_BULLET.test(line) && /\b(?:tag|release|publish)\b/i.test(line)) { + // QNBS-v3: catches a stale "⬜ Tag/Release/publish vX.Y.Z" bullet that should have flipped to ✅ once that version shipped + if ( + OPEN_BULLET.test(line) && + /\b(?:tag|tagging|release|releasing|publish|publishing)\b/i.test(line) + ) { for (const m of line.matchAll(/v(\d+\.\d+\.\d+)/gi)) { const mentioned = m[1]; if (semverLte(mentioned, latestVersion)) { diff --git a/tests/unit/checkDocMetrics.test.ts b/tests/unit/checkDocMetrics.test.ts index addcfbfe..004612dd 100644 --- a/tests/unit/checkDocMetrics.test.ts +++ b/tests/unit/checkDocMetrics.test.ts @@ -63,9 +63,7 @@ describe('stripHistoricalSections', () => { expect(stripped).toContain('Present: 17 locales.'); }); - // QNBS-v3 (F-1): regression guard for the dc14bc0-shaped drift — a stale `- ⬜` bullet sitting - // inside a dated/historical section was invisible to the gate because DONE_BULLET had no mirror - // for the open-bullet polarity. + // QNBS-v3: regression guard for the dc14bc0-shaped drift — a stale open bullet was invisible to the gate inside a historical section it('preserves an open "⬜" bullet even inside a dated/historical section', () => { const md = [ '## v1.24.2 — CSP/crypto/doc-truth hardening (2026-07-29)', @@ -124,14 +122,22 @@ describe('scanForDrift', () => { expect(findings).toHaveLength(0); }); - // QNBS-v3 (F-1): the OPEN_BULLET_VERSION check — a stale "⬜ Tag/Release vX.Y.Z" bullet for an - // already-released version must be flagged now that stripHistoricalSections() preserves it. + // QNBS-v3: the OPEN_BULLET_VERSION check — a stale open tag/release bullet for an already-released version must be flagged it('flags an open "⬜" bullet for tagging/releasing a version <= the latest release', () => { const content = '- ⬜ **Tag `v1.24.1` + publish the GitHub Release** — maintainer action.'; const findings = scanForDrift(content, 'FAKE.md', actual); expect(findings.some((f) => f.includes('v1.24.1'))).toBe(true); }); + it.each(['Tagging', 'Releasing', 'Publishing'])( + 'flags an open "⬜" bullet using the inflected form "%s"', + (verb) => { + const content = `- ⬜ **${verb} \`v1.24.1\`** — maintainer action.`; + const findings = scanForDrift(content, 'FAKE.md', actual); + expect(findings.some((f) => f.includes('v1.24.1'))).toBe(true); + }, + ); + it('does not flag an open "⬜" bullet for tagging a version newer than the latest release', () => { const content = '- ⬜ **Tag `v1.25.0` + publish the GitHub Release** — maintainer action.'; const findings = scanForDrift(content, 'FAKE.md', actual);