The shared stripComments strips BLOCK comments first, so a line comment containing `/*` swallows the code below it — every source-scanning guard built on it can go silently blind
The defect
tests/helpers/v1RouteAudit.ts:258 (origin/main 4f3121228):
export function stripComments(source: string): string {
return source.replace(/\/\*[\s\S]*?\*\//g, ' ').replace(/\/\/[^\n]*/g, ' ');
}
Block comments are removed FIRST. So a // line containing the two characters /* opens a block comment for that first regex, which then runs to the next */ anywhere in the file — deleting every line of real code in between. The scan does not error. It simply stops seeing that code, and a guard that cannot see code reports that the code is fine. It fails in the direction that passes.
stripCommentsAndStrings (:268) has the same order, and tests/api/public/contract-coverage.test.ts carries its own local copy of the same expression.
Reproduction — measured, not read
$ node -e "
const bad = s => s.replace(/\/\*[\s\S]*?\*\//g,'').replace(/^\s*\/\/.*$/gm,'');
const good = s => s.replace(/^\s*\/\/.*$/gm,'').replace(/\/\*[\s\S]*?\*\//g,'');
const src = [
'// the routes under \`app/api/public/*\` are the gated surface',
'export async function GET(req) { return new Response(); }',
'/** a doc comment */',
'export async function POST(req) { return new Response(); }',
].join('\n');
const verbs = s => [...s.matchAll(/export\s+(?:async\s+)?function\s+(GET|POST|PUT|PATCH|DELETE)\b/g)].map(m=>m[1]);
..."
block-first : [ 'POST' ]
line-first : [ 'GET', 'POST' ]
The GET disappears. Nothing reports it.
How it was found, which is the part worth keeping
Not by reading. A guard written for MOTIR-4033 reported that app/(authed)/layout.tsx does not call isCloud() — seven lines after the call had been added and verified by hand. The paragraph above the call ended …gated on \app/api/public/*` serves nothing,` and took the next five lines with it.
The input is not contrived: in this repository a line comment naming a route tree contains /* by construction — app/api/public/*, app/(authed)/*, design/<area>/*, lib/permissions/** — and this is a tree whose files explain themselves at length. The guards most likely to go blind are the ones in the best-commented files.
Blast radius
v1RouteAudit is imported by twelve test files (tests/helpers/structuralGuardLane.ts's BOUNDED_SCAN_MODULES entry states the count), including the v1 route audit that raises bypasses-wrapper for a handler not wrapped in withV1Route — a security-shaped check. No claim is made here that any of them is currently blind: that is exactly what the card has to measure, because the only honest answer is a diff of the two orders over the real tree.
Acceptance criteria
- The two orders are run over the whole scanned tree and the DIFF is quoted in the PR body: for each scanner, which files/symbols the current order misses today. A diff of zero is a real and welcome result — it is reported, not assumed.
stripCommentsandstripCommentsAndStringsremove LINE comments first.tests/api/public/contract-coverage.test.ts's local copy is retired in favour of the shared one, or fixed with it.- A test drives both orders over a fixture whose line comment carries an opening block-comment sequence, and asserts the code below survives — the counterfactual, run rather than argued.
- The residual limit is stated where the helper lives: neither order is a parser, and a
/*inside a STRING LITERAL still opens a block. The heavier scanners intests/rls/use the TypeScript compiler API for that reason. - Every one of the twelve importing suites still passes, and any assertion whose count CHANGES is reported as a finding rather than adjusted to match.
Context refs
motir-core/tests/helpers/v1RouteAudit.ts:258·:268— the two shared strippersmotir-core/tests/api/public/contract-coverage.test.ts— the local copymotir-core/tests/helpers/stripSourceComments.ts— the corrected one, written for MOTIR-4035, with the reasoning in its headermotir-core/tests/helpers/structuralGuardLane.ts—BOUNDED_SCAN_MODULES, which names the twelve importers