Filed unassigned from the #9863 dev seat (session session_01DdCnBGcHeufjrq7drTD3wt, PR #10450). Found by walking into it: a new scan in that PR copied the local idiom and lost the code it was measuring.
The residue
#9367 (closed by PR #9445) converted six scripts/check-*.mjs gates from a private naive stripComments to the shared string-aware maskComments. Two files carrying the identical spelling were outside that scope because they are tests, not gates:
packages/cli/src/commands/serve-verify-security-parity.contract.test.tspackages/cli/src/commands/serve-email-config-parity.contract.test.ts
Both define:
functionstripComments(source: string): string{returnsource.replace(/\/\*[\s\S]*?\*\//g,' ').replace(/(^|[^:])\/\/[^\n]*/g,'$1');}and both run it over packages/cli/src/commands/serve.ts.
Measured on today's serve.ts (e502a6a8e)
serve.ts's 5d. header comment contains the route wildcard /api/v1/auth/* — the very literal #9367 used as its example. Its /* opens a phantom block comment that closes against import(/* webpackIgnore: true */ authPkg)ten lines below, deleting the region in between, which contains the hasAuthPlugin computation and the if (!hasAuthPlugin && tierEnabled('auth')) gate.
Code-bearing lines of serve.ts surviving each order:
| strip | lines kept |
|---|
| block pass first (what these two files do) | 1895 |
| line pass first | 2098 |
shared maskComments | 2098, and the line count is preserved (4638 → 4638) because it blanks rather than deletes |
The 203-line difference is code.
Is it live today? No — and that is the whole reason to fix it now
Both scans currently measure new SecurityPlugin(…) constructions, and every one of them sits outside the swallowed region, so their verdicts are unaffected and both are green for the right reason. This is a latent hazard with a proven mechanism, exactly as #9367 classified its own six.
What makes it worth closing anyway is that it is contagious, which is not a hypothetical: writing #9863's new serve-audit-registration.contract.test.ts meant reading these two files as the local pattern and copying their stripComments verbatim. The copy's first run failed — loudly, because the new scan asserts its anchors exist — with the auth-gate anchor ... is gone from serve.ts. The anchor had not moved; the stripper had eaten it. A scan whose anchors happened to sit elsewhere would simply have passed.
The blast radius also grows on its own: any future assertion in either file about a construction inside lines ~2132–2142 of serve.ts, or any edit that moves a measured construction into a swallowed span, converts this from latent to live silently.
Fix
Swap both private copies for maskComments from scripts/js-comment-mask.mjs, as #9445 did for the gates. Two notes for whoever takes it:
Filed unassigned from the #9863 dev seat (session
session_01DdCnBGcHeufjrq7drTD3wt, PR #10450). Found by walking into it: a new scan in that PR copied the local idiom and lost the code it was measuring.The residue
#9367 (closed by PR #9445) converted six
scripts/check-*.mjsgates from a private naivestripCommentsto the shared string-awaremaskComments. Two files carrying the identical spelling were outside that scope because they are tests, not gates:packages/cli/src/commands/serve-verify-security-parity.contract.test.tspackages/cli/src/commands/serve-email-config-parity.contract.test.tsBoth define:
and both run it over
packages/cli/src/commands/serve.ts.Measured on today's
serve.ts(e502a6a8e)serve.ts's5d.header comment contains the route wildcard/api/v1/auth/*— the very literal #9367 used as its example. Its/*opens a phantom block comment that closes againstimport(/* webpackIgnore: true */ authPkg)ten lines below, deleting the region in between, which contains thehasAuthPlugincomputation and theif (!hasAuthPlugin && tierEnabled('auth'))gate.Code-bearing lines of
serve.tssurviving each order:maskCommentsThe 203-line difference is code.
Is it live today? No — and that is the whole reason to fix it now
Both scans currently measure
new SecurityPlugin(…)constructions, and every one of them sits outside the swallowed region, so their verdicts are unaffected and both are green for the right reason. This is a latent hazard with a proven mechanism, exactly as #9367 classified its own six.What makes it worth closing anyway is that it is contagious, which is not a hypothetical: writing #9863's new
serve-audit-registration.contract.test.tsmeant reading these two files as the local pattern and copying theirstripCommentsverbatim. The copy's first run failed — loudly, because the new scan asserts its anchors exist — withthe auth-gate anchor ... is gone from serve.ts. The anchor had not moved; the stripper had eaten it. A scan whose anchors happened to sit elsewhere would simply have passed.The blast radius also grows on its own: any future assertion in either file about a construction inside lines ~2132–2142 of
serve.ts, or any edit that moves a measured construction into a swallowed span, converts this from latent to live silently.Fix
Swap both private copies for
maskCommentsfromscripts/js-comment-mask.mjs, as #9445 did for the gates. Two notes for whoever takes it:CROSS_PACKAGE_TEST_INPUTSentry for@objectstack/cliplus the matching$TURBO_ROOT$input on@objectstack/cli#test. PR docs(plugin-audit): document theos serveopt-in, and rule out a config-derived audit options helper #10450 already added exactly that forscripts/js-comment-mask.mjs, so after it lands there is nothing to add.check-cross-package-test-inputswill not tell you this is needed — see check-cross-package-test-inputs' literal collector cannot see an escaping relative IMPORT specifier, so a test that imports a module outside its package goes undeclared silently #10452.maskCommentsblanks rather than deletes, so byte offsets and line numbers survive.serve-verify-security-parity.contract.test.ts's paren-walkingsecurityPluginConstructionsis offset-based and benefits; check the email scan for the same property before swapping.maskCommentsdesyncing on nested template literals in 16 files. Cross-check that neither subject is among them, the way docs(plugin-audit): document theos serveopt-in, and rule out a config-derived audit options helper #10450 did for its pair (masker and naive strip agreeing on every anchor count is what rules it out).