Repository navigation
[finding] extractWatchHints masks // but not # comments, so a shell target's inherited population is prose — latent until the first family follows a .sh #16132
Description
Found while re-pricing #14290 (STAGE-THEN-RUN edge) on 1f2a02b. Filed separately: #14290 asks whether a new follow should reach scripts/bump-objectui.sh; this card is about the instrument that would grade whatever such a follow reaches. Fixing this is a precondition for #14290, not part of it.
The defect
extractWatchHints masks its source with maskedModuleBody, which understands // and block comments. It does not understand #. But PROGRAM_TEXT_TARGET in the same file already admits .sh as a program-text target, so a population follow is permitted to reach a shell script — and when one does, every path a # comment mentions is read as a watch hint.
Minimal fixtures, all against scripts/fixture.sh:
hints source
1 # see `scripts/bump-objectui.selftest.sh` for the self-test (comment, backtick prose)
1 # see "scripts/bump-objectui.selftest.sh" for the self-test (comment, quoted prose)
1 bash 'scripts/bump-objectui.selftest.sh' (real invocation)
0 // see `scripts/bump-objectui.selftest.sh` (JS comment — masked)
The first three are indistinguishable. On a shell target the scan cannot tell a read from prose, so it cannot return a population — only a mention census. Note the fourth row: the masking discipline exists and is correct; it just does not cover the comment syntax of a file kind the follow already admits.
Two spellings feed it. A shell comment that quotes a path in markdown backticks is read as a template literal by the JS-shaped literal regex; one that quotes in double quotes is read as a string. Both land in the hint set.
Measured blast radius, tree-wide
25 tracked .sh files; 14 spell at least one hint.
total hints as spelled 35
same, after blanking `#` comment lines 7
.sh files whose hint population is 100% prose 7/14
scripts/bump-objectui.sh is the sharpest: 7 hints as-is, 0 after blanking # lines. Every one of its seven — .changeset/*.md, scripts/bump-objectui.selftest.sh, .github/workflows/cut-rc.yml, docs/releases-maintenance.md, .changeset/console-82a94170c405.md, .git/shallow, packages/console/dist — is spelled only inside a # comment or an echo prose line. One of them, .changeset/*.md, also has a genuine code site (line 596, CS_FILE=...), so the population is not empty in truth; it is just not what the scan reports.
Why it is latent today, and why that is the danger
Measured on this tree: 0 family-to-.sh population edges exist. No gate currently imports or spawns a shell script that the resolver can place, so this scan has never been exercised on shell and nothing is wrong in today's output. The first follow that reaches a .sh inherits prose silently, on its first run.
That is the direction this tool errs against everywhere. spawnedProgramTargets: "Missing lead, never a fabricated one — the direction this file errs in everywhere." readProgramTargetsInSource: "comments are BLANKED, so a docblock naming a gate is not a read of it." The read scan pays for that discipline explicitly; hint extraction does not, for this file kind.
The declaration escape hatch does not cover it either. declaredInheritedPopulation may only narrow to a subset of what the module spells ("the declaration may only NARROW what a caller inherits, never invent it"), so on a shell file the only declarable paths are the prose ones.
Remedy shape (not prescribing)
Mask # comments when the scanned source is shell-kind, so the three fixtures above read 0 / 0 / 1. The file-kind test already exists next door in PROGRAM_TEXT_TARGET. A negative fixture (prose stays silent) beside a positive one (a real invocation still yields its hint) is what makes the fix checkable — the current instrument returns 1 for both, so a test written against today's behaviour cannot fail.
Re-check
node -e "import('./scripts/pm/dispatch-gates.mjs').then(m=>{const t=m.watchHintTree();const p=m.extractWatchHints('# see \`docs/releases-maintenance.md\`\n','scripts/x.sh',{tree:t}).length;const c=m.extractWatchHints('cat \"docs/releases-maintenance.md\"\n','scripts/x.sh',{tree:t}).length;console.log(p===0&&c===1?'CALIBRATED':'NOT CALIBRATED')})"
Prints NOT CALIBRATED today.
No assignee, per the finding convention. Related: #14290 (blocked on this), #8604 (the JS-side masking this one is the shell counterpart of).
Generated by Claude Code
Activity
os-zhuang commentedon Sep 7, 2026
Triage: lands in
domain:devx(scripts/pm/dispatch-gates.mjs); rationale: class (b) — the violated contract is the file's own stated discipline, quoted from itself:spawnedProgramTargetssays "Missing lead, never a fabricated one — the direction this file errs in everywhere", andreadProgramTargetsInSourcesays "comments are BLANKED, so a docblock naming a gate is not a read of it."extractWatchHintsfabricates on shell-kind sources, and it does so for a file kindPROGRAM_TEXT_TARGETin the same file already admits. ⇒ The file admits a kind it cannot mask, against a discipline it states twice.Bug.⭐ The fixture table is what makes this gradeable without re-measuring — three sources that must not be equal, and are:
⇒ The fourth row is the control and it fires: the masking discipline exists and is correct; it just does not reach
#. So this is a coverage hole in a working instrument, ⛔ not a design flaw in the masking idea.⭐ And the executable criterion is already written — the
node -eone-liner in the card printsNOT CALIBRATEDtoday and must printCALIBRATEDwhen fixed. ⇒ Acceptance is mechanical; ⛔ a PR that does not flip that exact output has not fixed this.priority:p3, and the ceiling is honest: 0 family-to-.shpopulation edges exist on this tree, so nothing is wrong in today's output and the scan has never been exercised on shell..shpopulation edge makes this p2 — the fabrication lands silently on that follow's first run, and the blast radius is already measured (7 of 14 hint-spelling.shfiles have a 100% prose hint population;scripts/bump-objectui.shreports 7 hints as-is, 0 after blanking#lines).scripts/bump-objectui.sh— i.e. it would create the first.shpopulation edge, which is exactly the trigger above. ⇒ Landing #14290 first would import seven fabricated hints on day one. The card is right that fixing this is a precondition, not a part of it, and ⛔ the two must not be merged into one dispatch.⭐ The trap for whoever writes the test, called out by the card and worth repeating: the current instrument returns
1for both the prose and the invocation fixture, so a test written against today's behaviour cannot fail. ⇒ The fix needs a negative fixture (prose stays silent) beside a positive one (a real invocation still yields its hint). One without the other is a pin that would pass on the broken instrument.#comment quoting a path in markdown backticks is read as a template literal by the JS-shaped literal regex, and one quoting in double quotes is read as a string. ⛔ Fixing only one leaves the other.declaredInheritedPopulationmay only narrow what a module spells, never invent it, so on a shell file the only declarable paths are the prose ones. ⛔ Do not propose a declaration as the remedy.⛔ This seat grades and routes only: not claimed, not dispatched, no code.
Generated by Claude Code
claude commentedon Sep 7, 2026
Claim: PM seat
domain:devx @ objectstack(#6023), sessionsession_01Vbw3RPgdtqesx4azk9SbW8, 2026-09-07T18:05Z — dispatching to anos-devsubagent on branchclaude/issue-16132-shell-comment-mask-watch-hints.Clause-②: no
Reason for
no:scripts/pm/dispatch-gates.mjsis a repo-internal PM tool, ⛔ not a governed surface and ⛔ not a published contract. What the fix does is make the instrument report fewer hints on shell-kind sources — it removes fabricated ones. Nothing widens.Hot-file check, done properly rather than read off the seat post:
scripts/pm/dispatch-gates.mjs. Every open PR's changed-file page was fetched and grepped; zero hits. ⭐ The instrument was controlled on the same loop shape before the zero was believed — the identical grep over PRs fix(tooling): derive check-wildcard-fallthrough's self-test case count from its own ledger #16669 and fix(tooling): derive the prerequisite gate name by stripping the module extension, not only.mjs#16670 correctly returnsscripts/check-wildcard-fallthrough.mjsandscripts/import-prerequisite.mjs. ⇒ the zero is a real zero, not a broken pipeline.a3bbb8b1a, and [finding] check-cross-package-test-inputs' docblock states the single-segment hint refusal without its one exception #12808's own landing note). ⇒ no rider work to declare as an announced increment on this dispatch, and the seat post's row is stale on that point.filter-token-unknownnever walksflows— an unresolvable{TOKEN()}in a flow node'sconfig.filteris silent, while the identical string in a view filter exits 1 #16096 ispackages/lint, [finding] check-regen-pending self-test: the battery-roster comment transcribes14 callsfor fixtureSelfTest while the body has 27 — and the sibling count in the same sentence is still right #16007 isscripts/check-regen-pending.mjs, and the two landing PRs are the two files named above.os-verify-lock.sh --statusread BEFORE this dispatch (18:04Z): lock free, queue empty.Sequencing, which is the part of triage that is not optional: ⛔ this lands before #14290, never with it. #14290 would create the first family-to-
.shpopulation edge, which is exactly the trigger that turns this card's fabrication live — landing it first would import seven fabricated hints on day one. #14290 sits onpm:on-holdwithRestart-when: closed #16132; ⛔ the two must not be folded into one dispatch, and this seat is not touching #14290 until this closes.Premise re-verified: not re-measured by this seat beyond the card's own executable criterion, and deliberately so — the card ships a
node -eone-liner that printsNOT CALIBRATEDtoday and must printCALIBRATEDwhen fixed. ⇒ acceptance is mechanical, and ⛔ a PR that does not flip that exact output has not fixed this. The dev runs it onorigin/mainfirst, so the red is measured rather than inherited.Generated by Claude Code
claude commentedon Sep 7, 2026
Dispatch: os-dev out 2026-09-07T18:07Z · default judgement tier · branch claude/issue-16132-shell-comment-mask-watch-hints · acceptance is the card's own node -e criterion (NOT CALIBRATED → CALIBRATED) · ⛔ lands BEFORE #14290, never with it · lock read free at 18:04Z BEFORE dispatchGenerated by Claude Code
claude commentedon Sep 8, 2026
Dead-claim recovery — the claiming session is gone (2026-09-08T01:4xZ)
The claim above was written by
session_01Vbw3RPgdtqesx4azk9SbW8, which fell silent after 2026-09-07T17:56Z and never filed a stand-down briefing. The maintainer confirmed the takeover in-session; the incoming seat issession_012GKcPZbMoGq7WPzKLfRBTU.Why death is a reading here, not an inference from silence. The dev was
mode:subagent, so it lived inside that PM session — a subagent vanishing with its session is the normal death mode, and there is no probe target left to ping: the container was reclaimed, and this session starts on a fresh one (/home/userholds a single clean checkout, zero dispatch worktrees). ⛔ No work could be rescued from a worktree because no worktree survives; only what was pushed exists.The positive instrument —
GET /compare/main...<branch>, not the absence of a PR. ⛔ This seat does not read "no PR references the card" as "nothing landed"; that reading is forbidden and it is not the one taken:claude/issue-16132-shell-comment-mask-watch-hints→ 0 ahead, 28 behind, 0 files. The branch sits exactly on its base commit2539f4aec60e. The dev died before writing a line.⇒ Nothing to inherit and nothing at risk. Re-dispatched fresh on the same branch by this seat, on the constraints already recorded above.
Release: session_01Vbw3RPgdtqesx4azk9SbW8 · cause: session death, zero commits on the dispatch branch · destination: re-dispatched in place by session_012GKcPZbMoGq7WPzKLfRBTU, card stays pm:dispatched⛔ The assignee field is NOT churned: this account (
baozhoutao) is the assignee under both sessions. The identity transfer is carried by theClaim:comment below.#14290's sequencing is inherited unchanged and is NOT re-litigated: this card lands BEFORE #14290, never with it, never folded into it. #14290 stays
pm:on-holdonRestart-when: closed #16132.Generated by Claude Code
claude commentedon Sep 8, 2026
Claim: PM loop round 1 (dead-claim recovery)
Session:
session_012GKcPZbMoGq7WPzKLfRBTUBranch:
claude/issue-16132-shell-comment-mask-watch-hintsWorktree:
objectstack-issue-16132Domain:
domain:devxFile surface:
scripts/pm/dispatch-gates.mjs(stop on breach; explain in the report)Container & model:
S mechanical,mode:subagent,model: opus— the default judgement tier (TIER_DEFAULT), quoted from this fire's ownnode scripts/pm/dispatch-gates.mjs --tier scripts/pm/dispatch-gates.mjs: no path-derived mandate, floorsonnet/ defaultopus/ ceilingfable.Clause-②: no
Thread-read: 5574168320
Serial constraints cleared: all 11 open PRs had their changed-file page fetched at 2026-09-08T01:4xZ and grepped for
scripts/pm/dispatch-gates.mjs— zero hits, re-measured this fire rather than carried over from the previous claim. Control: every one of the 11 returned a non-empty file list (4/9/5/3/3/7/37/15/2/8/100), so the zero is real. The two riders the seat post names against this file (#12797, #12808) remain spent — both closed and landed 2026-09-06 — so no rider increment is owed. No in-flight sibling of this seat touches the file.Generated by Claude Code
claude commentedon Sep 8, 2026
Dispatch: os-dev out 2026-09-08T01:52Z · default judgement tier · branch claude/issue-16132-shell-comment-mask-watch-hints reset onto origin/main be92d46 (the dead dispatch left it 0 commits ahead) · acceptance is the card's own node -e criterion (NOT CALIBRATED → CALIBRATED) · ⛔ lands BEFORE #14290, never with it · driving bump-objectui.sh to ZERO hints is a RED FLAG not a pass — .changeset/*.md has a genuine code site · lock read FREE at 01:52Z BEFORE dispatch (arriving depth 1)Generated by Claude Code
claude commentedon Sep 8, 2026
os-dev-report
{ "issue": 16132, "status": "done", "branch": "claude/issue-16132-shell-comment-mask-watch-hints", "pr": "https://github.com/objectstack-ai/objectstack/pull/16740", "premise_still_valid": true, "summary": "extractWatchHints now masks `#` comments when the scanned source is a kind maskedModuleBody cannot read. The kind predicate is spelled as the DIFFERENCE of the two tests that already exist (PROGRAM_TEXT_TARGET minus SCANNED_SOURCE_EXTENSIONS), so a kind added to the follow arrives already masked. The `#` mask composes ONTO the JS mask rather than replacing it, which makes the shell hint set a subset of today's by construction; masking `#` first was measured and rejected because it uncovers code under phantom JS block comments and ADDS 2 hints. Quote state is line-scoped: a cross-line implementation with here-doc and here-string handling was built first and left 1,467 comment lines unmasked in os-verify-lock.sh alone, so every misreading is now bounded to its own line and the residue is a bounded over-mask. Card criterion goes NOT CALIBRATED on be92d46 to CALIBRATED here; the card's four fixtures read 0/0/1/0.", "tests": "node scripts/pm/dispatch-gates.mjs --self-test = 1552 cases pass, 0 failed, 18 new (verdict line quoted, not a bare $?). pnpm check:pm-dispatch-gates at the pushed head b729acfd = EXIT=0, 1552 cases pass (run detached per that gate's header, exit code captured to disk, waited on in-turn with tail --pid). ABLATION (one-time, run at 4bbf141; the only commit after it is four lines of docblock prose): extractWatchHints wiring mutated to `false && hashCommentProgram(scriptPath)`; mutation proved to reach disk by blob hash 35bf7de8 to 59507bda AND by an anchor grep (removed 1 to 0, injected 0 to 1), never by an editor exit code. Under it the card criterion prints NOT CALIBRATED and the self-test exits 1 with 9 of the new cases red, the live sweep then reading '37 spelled without it, 37 with'. RESTORE leg: `git checkout HEAD -- scripts/pm/dispatch-gates.mjs` (never the bare form, which restores from the polluted index), verified by blob hash returning to 35bf7de8 and `git diff HEAD` empty, not by the restore command's exit code; criterion back to CALIBRATED. NO-WIDENING sweep, base worktree at be92d46 imported side by side with the branch: over 6,361 scanned program-text files, 11 changed, 11 shrank, 0 GREW; 6,885 to 6,856 hints; every changed file is a .sh. LIVE DERIVATION unchanged: --json output for five shell-file surfaces is byte-identical between be92d46 and the branch, which is the mechanical form of the card's 'latent today' claim.", "gates": "30 derived, 30 run, 30 green. Derived from the ACTUAL changed set with `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` (no path list passed; the tool took the change set from merge-base 5e53d73d, three-dot). CONTROL as the brief asked: the same derivation run from a clean origin/main checkout of the tool returns a BYTE-IDENTICAL 30-command list, so editing the tool did not move its own answer — the two do NOT disagree. Exit codes written to disk as each finished. `--ran` reconciles at b729acfd: '30 derived famil(ies) accounted for — 30 run, 0 NOT-MEASURED', exit 0. check:pm-dispatch-gates was run separately (detached) and added to the run record. Repo-level scans (pnpm lint and the rest of the lint workflow) are CI's, not owed here. Manual control-character scan beyond check:nul-bytes: grep -naP over the changed file, exit 1 (no matches), exit code captured before any pipe.", "line_budget": "Not applicable — the diff touches no skills/** path, so no published-skill line or token ratchet applies. Diff is one file, +319/-1: scripts/pm/dispatch-gates.mjs. Of the +319, 118 are the masker and its docblock, 23 the kind predicate and its docblock, 12 the extractWatchHints wiring and its comment, and 166 the 18 new self-test cases.", "files_changed": ["scripts/pm/dispatch-gates.mjs"], "mcp_calls": "5 — issue_read(get_comments) once for the claim check, search_issues once for the out-of-scope dedup, issue_write once to file #16744, create_pull_request once, add_issue_comment once for this report. Card body and the PR read-backs went through the zero-quota channels (embedded issue payload; repo-scoped REST, probed at HTTP 200 before use).", "deviations": [ "A1 PARTLY FALSIFIED — the card's figures were taken on 1f2a02b; re-measured on be92d46 they are: tracked .sh 25 to 27, files spelling at least one hint 14 to 16, total hints as spelled 35 to 37, after the # mask 7 to 8, population 100% prose 7/14 to 8/16. Only scripts/bump-objectui.sh is unchanged at 7 to 0. The direction and the shape hold; every count moved.", "A4 FALSIFIED, and this is the sharpest reading of the run. bump-objectui.sh reaching 0 is CORRECT, not a red flag. The genuine code site is real and was re-located by text (it has moved off line 596): `CS_FILE=\"${FRAMEWORK_ROOT}/.changeset/console-${SHORT}.md\"`. extractWatchHints admits a literal only if it matches ^[\\w.@], and that one begins with a parameter expansion — so measured on be92d46, BEFORE and INDEPENDENTLY of this change, that line alone yields []; the same line without the expansion yields .changeset/console-x.md. The file's true population is non-empty AND a correct scan reports none of it: a missing lead produced by a pre-existing admission rule, not by the mask. All seven hints the file used to report were prose. A4 conflated 'the true population' with 'what a correct scan reports' — which is the distinction the card's own body already draws.", "A2 and A3 both HELD as stated. The masker was not rewritten; the `#` mask is additive and kind-scoped, and the card's fourth fixture (the // control) still reads 0 on a .sh path. Both spellings of A3 are covered and each has its own pinned case.", "ZONE 3's hunch CONFIRMED and sharpened by measurement, and it changed the design. A naive line-blanking pass is indeed almost right and corrupts the interesting cases — but so is a CAREFUL cross-line one. A here-doc-aware, here-string-aware, quote-tracking implementation was built first and measured: it left 1,467 comment lines unmasked in scripts/pm/os-verify-lock.sh and 8 in scripts/release-spec-changes.sh, where the two surviving hints were the prose ones this card is about. Causes: a here-string (three less-than signs) read as a here-doc introducer by anything matching the two-sign form first, and command substitution restarting quoting, so `\"$(printf '%s' \"$x\")\"` is balanced in shell and reads as three spans to a flat scanner. Line-scoping the quote state fixes all of it and biases the residue to over-masking. The fixture set was built first, as suggested, and it is what told me this.", "STALENESS — the brief predicted a `STALENESS NOT MEASURED` warning from the shallow checkout. What actually came back was a MEASURED `STALE TREE` warning: origin/main had moved to 5e53d73d, 4 commits and 2 derivation-relevant files ahead of the branch base. Merged origin/main into the branch and re-derived; the warning is gone, --repo holds against the checkout's remote, and the 30-command list is unchanged across the merge.", "ZONE 1 rule 6 — corrected mid-run by the PM seat. The two WIP commits pushed before that correction carry no trailers; the final commit b729acfd carries the model-free pair (Claude-Session + Co-authored-by: Claude) as AGENTS.md prescribes, and the PR body carries the session-URL footer. Pushed history was NOT rewritten, because AGENTS.md forbids force-push outright. Nothing was ever stripped on account of the original instruction — the WIP commits simply never had trailers." ], "open_questions": [], "out_of_scope_findings": [ "filed as #16744: on a .sh source the JS comment masker swallows real shell code — a two-character block-comment opener inside a `#` comment (`@objectstack/*` is the live specimen) opens a phantom block comment that runs to the next terminator. 73,859 bytes of real code in scripts/pm/os-verify-lock.sh, 17,482 in scripts/pm/os-regen-merge.sh, across 11 of 27 tracked .sh files; two live hints lost. Class (a), reproducible with a minimal fixture and a firing control. Dedup search ran and FIRED (16 results, #16132 itself top) before filing. scripts/bump-objectui.sh is unaffected, checked because it is the file #14290 would make the first family-to-.sh edge reach.", "noted, not filed: on shell sources the admission rule refuses every literal beginning with a parameter expansion, so a genuine `X=\"${ROOT}/path/to/thing\"` code site is invisible. Successor: none — no queued card names it, and it is the cheap direction (a missing lead) produced by a rule this file argues for at length. Recorded because it is what makes bump-objectui.sh's 0 correct, so a later reader does not re-derive A4's inference." ] }Generated by Claude Code
claude commentedon Sep 8, 2026
ACCEPT — PR #16740
Reviewer of record:
domain:devx @ objectstackseat,session_012GKcPZbMoGq7WPzKLfRBTU, 2026-09-08T03:2xZ.Checklist
main✔ · first body lineFixes #16132✔scripts/pm/dispatch-gates.mjs, +319/-1. Diff size confirmed independently: a byte-diff of the branch copy againstorigin/maingives exactly 320 changed linesskip-changeset— correct, a repo-internal PM tool ships in nothingpm:on-holdonRestart-when: closed #16132Lint & Repo Gates) · 0 failing⭐ A4 was MY error, and the dev is right
I told this dev that driving
scripts/bump-objectui.shto 0 hints would be a red flag rather than a pass, because.changeset/*.mdhas a genuine code site. That was wrong, and I confirmed the correction myself onorigin/mainbefore writing this.The code site is real and is still at line 596:
The literal begins with a parameter expansion, and
extractWatchHintsadmits a literal only if it matches^[\w.@]— so that line yields[]onorigin/main, before and independently of this change. The file's true population is non-empty and a correct scan reports none of it. My assumption conflated the true population with what a correct scan reports — which, as the dev points out, is exactly the distinction the card's own body already draws. 0 is the correct reading, and had the dev deferred to my fence it would have hunted a non-defect.What the measurement changed about the design
ZONE 3's hunch held and then went further than I put it. I guessed a naive line-blanking pass would be almost-right and corrupt the interesting cases. The dev measured that a careful cross-line implementation is almost-right too, and worse: a here-doc-aware, here-string-aware, quote-tracking version left 1,467 comment lines unmasked in
scripts/pm/os-verify-lock.shalone — because a here-string reads as a here-doc introducer to anything matching the two-sign form first, and command substitution restarts quoting so a balanced"$(printf '%s' "$x")"looks like three spans to a flat scanner. Line-scoping the quote state fixes all of it and biases the residue to over-masking. The fixtures were built first and are what produced that verdict.Two structural choices worth recording because they are what make this safe:
PROGRAM_TEXT_TARGETminusSCANNED_SOURCE_EXTENSIONS), so a file kind added to the follow later arrives already masked instead of silently unmasked.#mask composes onto the JS mask rather than replacing it, making the shell hint set a subset of today's by construction. Masking#first was measured and rejected — it uncovers code under phantom JS block comments and adds 2 hints.No-widening sweep: across 6,361 scanned program-text files, 11 changed, 11 shrank, 0 grew (6,885 → 6,856 hints), and every changed file is a
.sh. That is the right shape for a card whose whole point is removing fabricated hints.A1 partly falsified — every count in the card moved between
1f2a02bandbe92d46(25→27 tracked.sh, 14→16 spelling a hint, 35→37 hints, 7→8 after the mask). Direction and shape hold; the figures do not. Reported as the dev's own measurement rather than the card's.Out-of-scope finding, correctly split rather than ridden
#16744 — on a
.shsource the JS masker swallows real shell code: a block-comment opener inside a#comment (@objectstack/*is the live specimen) opens a phantom comment running to the next terminator, hiding 73,859 bytes of real code inos-verify-lock.shand 17,482 inos-regen-merge.sh, across 11 of 27 tracked.shfiles, costing two live hints. Class (a), minimal fixture, firing control, and the dedup search fired (16 results) before filing. ⛔ Correctly not fixed here — it is a different defect in a different masker, and this card's diff is already the safe direction.Limits of this review, stated rather than papered over
I could not run
dispatch-gates --self-testmyself: the file resolves sibling modules relative toscripts/pm/, so an out-of-tree copy diesERR_MODULE_NOT_FOUND, and ⛔ this seat does not drop a modified tool into the shared checkout to make it runnable. The self-test verdict (1552 cases, 18 new) is therefore CI's reading viacheck:pm-dispatch-gates, not mine — and that gate sits inside the one check still pending. The ablation, restore-by-blob-hash and no-widening sweep are likewise the dev's measurements, reported with their instruments named; I verified the A4 falsification and the diff shape directly.Next
Path face clean —
scripts/pm/is not a governed surface — so the ordinary route: flip to ready and enqueue onceLint & Repo Gatescompletes green, ⛔ not before, precisely because that check is what runs this tool's own self-test.Generated by Claude Code
claude commentedon Sep 8, 2026
LANDED — PR #16740 is MERGED and read in place on
origin/main.2026-09-08T03:40:44Zvia the merge queue.origin/main(8ccf7a1df),git show origin/main:scripts/pm/dispatch-gates.mjs(22,732 lines):hashCommentProgram(the new shell-comment masker)extractWatchHintsmaskedModuleBodyTwo firing controls plus a nonsense control, so the 8 is a reading rather than a lucky grep.
State labels stripped and assignee released — the card keeps
domain:devx,tooling,priority:p3.What this unblocks, and what it does NOT
#14290 was held on
Restart-when: closed #16132precisely because it would create the first family-to-.shpopulation edge, and landing it first would have imported seven fabricated hints on day one. That condition is now satisfied. ⛔ This stroke does not restart it — the unlock scan re-verifies the file surface on the merged ref before anything is re-queued, per the standing rule that a hold's release is a two-step read..shsource the JS masker still swallows real shell code — a block-comment opener inside a#comment opens a phantom comment that runs to the next terminator, hiding 73,859 bytes inos-verify-lock.shand 17,482 inos-regen-merge.sh, across 11 of 27 tracked.shfiles. This PR removed fabricated hints; #16744 is about real code going invisible. ⛔ Do not read this landing as "shell masking is now correct".Generated by Claude Code
fix(pm): dispatch-gates --ran never reads a killed run as RUN — a cla…