Skip to content

Commit 4132981

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/issue-17162-claude-md-pointer
2 parents 898425e + f801e7d commit 4132981

1 file changed

Lines changed: 125 additions & 14 deletions

File tree

scripts/pm/dispatch-gates.mjs

Lines changed: 125 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -555,14 +555,42 @@ const maskedModuleBody = memoiseMask((source) => maskSelfTests(maskedComments(so
555555
* unbounded under-mask measured above.
556556
*
557557
* Same projection as `blank` next door — spans become spaces, newlines and byte
558-
* offsets survive — so this composes onto `maskedModuleBody`'s output rather
559-
* than replacing it. The order is measured too, and it is the one that cannot
560-
* widen: masking `#` FIRST stops a `#` comment containing `@objectstack/*` from
561-
* opening a phantom JS block comment, which UNCOVERS code below it and adds
562-
* hints (2 on this tree — `scripts/downstream-smoke.sh` and
563-
* `.claude/hooks/guard-tree-enum.sh`). Masking `#` LAST can only blank more of
564-
* an already-masked body, so the shell hint set is a subset of today's by
565-
* construction.
558+
* offsets survive — so this composes WITH the JS mask rather than replacing it.
559+
*
560+
* ## The ORDER, and why it is now `#` FIRST (#16744)
561+
*
562+
* Masking `#` LAST can only blank more of an already-masked body, so the shell
563+
* hint set was a subset of the JS-masked one by CONSTRUCTION. That is why the
564+
* card above took it: it could not widen, and widening was out of its scope.
565+
* The price it left unpaid is the OTHER direction of the same "THIRD kind"
566+
* defect. A `#` comment spelling `@objectstack/*`, a glob, or any other
567+
* two-character block-comment opener is not a comment to the JS scanner — it
568+
* opens a BLOCK comment that runs to the next terminator and blanks every line
569+
* of real shell CODE in between, with nothing in the output saying a region was
570+
* skipped. Re-measured per byte on `ce7bae8b`, over the 31 tracked `.sh` files:
571+
* 12 of them hand a caller shell code as prose, 73,859 bytes in
572+
* `scripts/pm/os-verify-lock.sh` alone.
573+
*
574+
* So `#` is masked FIRST now: shell prose never reaches the JS scanner and
575+
* cannot open a phantom comment. This UNCOVERS the code below such a comment
576+
* and therefore ADDS hints — 2 on this tree, `node_modules/@objectstack/spec/dist`
577+
* in `scripts/downstream-smoke.sh` and one site in
578+
* `.claude/hooks/guard-tree-enum.sh`, both of them real code the follow was
579+
* blind to. ⛔ The shell hint set is therefore NOT a subset of the JS-masked one
580+
* any more, and the live sweep in the self-test pins what the additions ARE —
581+
* ⛔ never that there are none, which is the blindness this removed.
582+
*
583+
* The JS mask still RUNS on a shell source, and still runs BEFORE
584+
* `maskSelfTests` as that function's header requires. Keeping it is the whole
585+
* difference between this order and "do not run the JS scanner over a non-JS
586+
* kind at all": the latter also drops the `//` masking pinned below on a `.sh`
587+
* source, which is a reconciliation across both cards rather than this fix.
588+
*
589+
* Composed from the raw maskers rather than through `maskedModuleBody` — the
590+
* intermediate is a DIFFERENT string on this path, so there is no half to
591+
* share, and routing it through the JS memo would only fill that cache with
592+
* shell-derived keys no JS caller can hit. The memo below is keyed on the raw
593+
* source, so the whole chain is still derived once per source.
566594
*/
567595
const SHELL_WORD_START = /[\s;&|()<>]/;
568596

@@ -621,8 +649,10 @@ export function maskShellComments(source) {
621649
return blank(String(source), shellCommentSpans(String(source)));
622650
}
623651

624-
/** `maskShellComments(maskedModuleBody(source))`, memoised — see the block above. */
625-
const maskedHashCommentBody = memoiseMask((source) => maskShellComments(maskedModuleBody(source)));
652+
/** `maskSelfTests(maskComments(maskShellComments(source)))`, memoised — see the block above. */
653+
const maskedHashCommentBody = memoiseMask((source) =>
654+
maskSelfTests(maskComments(maskShellComments(source))),
655+
);
626656

627657
// ── What a gate that IMPORTS this module inherits (#11556) ─────────────────
628658
//
@@ -15541,6 +15571,46 @@ function selfTest() {
1554115571
shHints(shJsComment).length === 0,
1554215572
shHints(shJsComment),
1554315573
);
15574+
// ── The PHANTOM BLOCK COMMENT the order used to open (#16744) ─────────────
15575+
//
15576+
// The other direction of the same "THIRD kind" defect, and the card's whole
15577+
// acceptance criterion: two sources that differ in FOUR CHARACTERS OF PROSE,
15578+
// both of which must read the one hint their code spells. The first carries a
15579+
// block-comment opener inside a `#` comment; while `#` was masked LAST that
15580+
// opener reached the JS scanner and blanked the real `DEST=` line under it.
15581+
//
15582+
// ⛔ The control is not decoration. A change that only makes the first row
15583+
// fire — by disabling the mask, or by dropping the JS scanner on this kind —
15584+
// takes the second row down with it or leaves it as the ONLY row that fires.
15585+
// Both rows read 1, or this is not the fix.
15586+
const shPhantom = '# published @objectstack/* packages\nDEST="node_modules/@objectstack/spec/dist"\n';
15587+
const shPhantomControl = '# published packages\nDEST="node_modules/@objectstack/spec/dist"\n';
15588+
t(
15589+
'⭐ a `/*` inside a `#` comment no longer opens a block comment over the shell code below it',
15590+
shHints(shPhantom, 'scripts/x.sh').join() === 'node_modules/@objectstack/spec/dist',
15591+
shHints(shPhantom, 'scripts/x.sh'),
15592+
);
15593+
t(
15594+
'⭐ CONTROL: the same code under a comment with NO opener still reads its one hint — the mask was fixed, not switched off',
15595+
shHints(shPhantomControl, 'scripts/x.sh').join() === 'node_modules/@objectstack/spec/dist',
15596+
shHints(shPhantomControl, 'scripts/x.sh'),
15597+
);
15598+
// The span, not just the line: an unterminated opener ran to the END OF FILE,
15599+
// so the cost was every hint below it rather than the one line beside it.
15600+
const shPhantomSpan =
15601+
'# everything below this line is /* invisible\n'
15602+
+ 'bash "scripts/one.sh"\n'
15603+
+ 'bash "scripts/two.sh"\n';
15604+
t(
15605+
'…and it ran to END OF FILE, so the recovered span is every hint below the comment, not one line',
15606+
shHints(shPhantomSpan, 'scripts/x.sh').join() === 'scripts/one.sh,scripts/two.sh',
15607+
shHints(shPhantomSpan, 'scripts/x.sh'),
15608+
);
15609+
t(
15610+
'…non-vacuously: the JS-kind control on the same bytes still loses both, which is what this order costs a `.sh` file',
15611+
shHints(shPhantomSpan, 'scripts/x.sh.mjs').length === 0,
15612+
shHints(shPhantomSpan, 'scripts/x.sh.mjs'),
15613+
);
1554415614
// KIND-SCOPED, in both directions. The same bytes on a `.mjs` path must keep
1554515615
// spelling their hint: `#` is not a comment in JavaScript, and a mask that
1554615616
// fired there would be a widening rather than this card's narrowing.
@@ -15628,25 +15698,46 @@ function selfTest() {
1562815698
let shellShrank = 0;
1562915699
let shellBefore = 0;
1563015700
let shellAfter = 0;
15701+
const shellAddedProse = [];
1563115702
for (const f of liveShellFiles) {
1563215703
const src = readFileSync(nodePath.join(ROOT, f), 'utf8');
1563315704
const masked = extractWatchHints(src, f, { tree: hintTree });
1563415705
const unmasked = extractWatchHints(src, `${f}.mjs`, { tree: hintTree });
1563515706
shellBefore += unmasked.length;
1563615707
shellAfter += masked.length;
15637-
if (masked.some((h) => !unmasked.includes(h))) shellGrew++;
15708+
const added = masked.filter((h) => !unmasked.includes(h));
15709+
// An ADDED hint is admissible only if it is spelled in CODE: its literal has
15710+
// to survive the `#` mask. One spelled only inside a `#` comment would be
15711+
// the FABRICATING direction arriving through the very reorder that fixed
15712+
// the under-mask, so it is collected by name rather than counted.
15713+
const code = maskShellComments(src);
15714+
for (const h of added) if (!code.includes(h)) shellAddedProse.push([f, h]);
15715+
if (added.length) shellGrew++;
1563815716
else if (masked.length < unmasked.length) shellShrank++;
1563915717
}
1564015718
t(
15641-
`⭐ LIVE: over ${liveShellFiles.length} tracked .sh file(s) the mask never ADDS a hint — ${shellBefore} spelled without it, ${shellAfter} with`,
15642-
liveShellFiles.length > 0 && shellGrew === 0 && shellAfter < shellBefore,
15643-
JSON.stringify({ files: liveShellFiles.length, shellBefore, shellAfter, shellGrew, shellShrank }),
15719+
`⭐ LIVE: over ${liveShellFiles.length} tracked .sh file(s) every hint the \`#\` mask ADDS is spelled in CODE — ${shellBefore} hints without the mask, ${shellAfter} with`,
15720+
liveShellFiles.length > 0 && shellAddedProse.length === 0 && shellAfter < shellBefore,
15721+
JSON.stringify({ files: liveShellFiles.length, shellBefore, shellAfter, shellGrew, shellShrank, shellAddedProse }),
1564415722
);
1564515723
t(
1564615724
'…non-vacuously: at least one live file really loses a hint, so the sweep is not passing over an instrument that changed nothing',
1564715725
shellShrank >= 1,
1564815726
JSON.stringify({ shellShrank }),
1564915727
);
15728+
// ⛔ This case replaced a `shellGrew === 0` pin (#16132), and the replacement
15729+
// is the point of #16744 rather than a relaxation of it. That spelling was
15730+
// true only because `#` was masked LAST, which left shell prose to reach the
15731+
// JS scanner first: a `#` comment containing `/*` opened a phantom block
15732+
// comment over the real code below it, so the code could not spell a hint in
15733+
// EITHER column and the difference read 0. Masking `#` FIRST uncovers that
15734+
// code, so additions are now expected — and the honest invariant is what they
15735+
// ARE, not that there are none.
15736+
t(
15737+
'…and the additions really happen, so the case above is not a subset test wearing a code test\'s name',
15738+
shellGrew >= 1,
15739+
JSON.stringify({ shellGrew }),
15740+
);
1565015741
// The card's sharpest specimen, both ends. DEPARTURE alone would stay green
1565115742
// on a mask that emptied the file, so the ARRIVAL half names a live shell
1565215743
// script whose hint is spelled in CODE and must survive.
@@ -15663,6 +15754,26 @@ function selfTest() {
1566315754
'docs/releases-maintenance.md',
1566415755
),
1566515756
);
15757+
// ⭐ LIVE RECOVERY (#16744): the site the card named, both ends. The `.mjs`
15758+
// control is what makes it a recovery rather than an ordinary arrival — the
15759+
// JS-only path STILL cannot read this line, because the phantom comment the
15760+
// header's `@objectstack/*` opens is what hid it, and that is precisely what
15761+
// masking `#` first removes.
15762+
const liveDownstream = 'scripts/downstream-smoke.sh';
15763+
const liveDownstreamSrc = readFileSync(nodePath.join(ROOT, liveDownstream), 'utf8');
15764+
t(
15765+
'⭐ LIVE RECOVERY: a path spelled in real shell CODE under a `#` comment carrying a block-comment opener is read again',
15766+
extractWatchHints(liveDownstreamSrc, liveDownstream, { tree: hintTree }).includes(
15767+
'node_modules/@objectstack/spec/dist',
15768+
),
15769+
extractWatchHints(liveDownstreamSrc, liveDownstream, { tree: hintTree }),
15770+
);
15771+
t(
15772+
'…non-vacuously: the JS-kind control on the same bytes still cannot see it, so a phantom comment is what was hiding it',
15773+
!extractWatchHints(liveDownstreamSrc, `${liveDownstream}.mjs`, { tree: hintTree }).includes(
15774+
'node_modules/@objectstack/spec/dist',
15775+
),
15776+
);
1566615777
const liveShardSelfTest = 'scripts/ci/select-shard-packages.selftest.sh';
1566715778
t(
1566815779
'⭐ LIVE ARRIVAL: a shell script whose hint is spelled in CODE still spells it, so the mask removed prose and not the population',

0 commit comments

Comments
 (0)