From eeec6b512e8d02adf338eb64347b11d20596bf75 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Wed, 8 Jul 2026 15:26:19 -0400 Subject: [PATCH] fix(#2086): AC2 source-guard must ignore comments/backtick prose, not just code The #338 fail-safe commit added a comment containing the literal `runtime === 'claude'` (explaining what the data lookup is NOT), which the AC2 source-grep test matched as a false positive (the test read the whole file, prose included). Strip block/line comments + backtick spans before matching so the guard flags only LIVE code, and reword the comment. CRLF-safe line-comment strip. Co-Authored-By: Claude Opus 4.8 --- bin/install.js | 2 +- tests/claude-imperative-reference.test.cjs | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/bin/install.js b/bin/install.js index a214124cf..0a9f2dd10 100755 --- a/bin/install.js +++ b/bin/install.js @@ -321,7 +321,7 @@ try { // {} and silently route a claude LOCAL install to the repo-shared, committed // `settings.json` instead of the gitignored `settings.local.json` (#338) — leaking // engineer-specific absolute paths. Keyed by runtime id (a DATA lookup, not a -// `runtime === 'claude'` branch) so behavior degrades CLOSED (safe), never open. +// hardcoded string-equality branch) so behavior degrades CLOSED (safe), never open. // The live descriptor (capabilities/claude/capability.json) remains the source of // truth; this mirrors only the privacy-load-bearing subset. (ADR-1239 / #2086) const FALLBACK_HOST_BEHAVIORS = Object.freeze({ diff --git a/tests/claude-imperative-reference.test.cjs b/tests/claude-imperative-reference.test.cjs index 8b67c3dfd..3cb3245ef 100644 --- a/tests/claude-imperative-reference.test.cjs +++ b/tests/claude-imperative-reference.test.cjs @@ -134,7 +134,14 @@ test('claude descriptor declares runtime.hostBehaviors (the folded-in host behav test('bin/install.js contains no `runtime === "claude"` / `runtime !== "claude"` string-equality branches (AC2)', () => { const src = fs.readFileSync(path.join(__dirname, '..', 'bin', 'install.js'), 'utf8'); - const offenders = src.match(/runtime\s*[!=]==\s*'claude'/g) || []; + // Strip comments + backtick/inline-code spans so PROSE mentions of the old + // pattern (a comment explaining "not a string-equality branch") do not + // false-positive — only LIVE code counts. + const codeOnly = src + .replace(/\/\*[\s\S]*?\*\//g, '') // block comments + .replace(/\/\/[^\r\n]*/g, '') // line comments (CRLF-safe) + .replace(/`[^`]*`/g, ''); // backtick / inline-code spans + const offenders = codeOnly.match(/runtime\s*[!=]==\s*'claude'/g) || []; assert.deepEqual( offenders, [],