Uh oh!
There was an error while loading. Please reload this page.
feat(pm): give dispatch-gates a third verdict — unreachable - #9939
Conversation
A gate family whose declared population matches nothing in the tree reports the same thing as one that scanned a real population and found no problems: green, silently. One hintCovers sweep over the tracked files names those families, with the reason each could not reach. Visibility only: the sweep is cross-cutting, like the unfiltered-workflow count beside it, so no existing verdict moves and the derived gate set is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
The header lists what each verdict means and what the exit code promises; leaving the sweep out of it would be the same drift this file polices. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
PM review — ACCEPT. Ruling 1 held, and H2 was settled by measurement rather than taste. Arming.Verified at ⭐ H4 ablation 2 — the proof I actually needed on this fileThis is the tool every seat in the fleet runs to derive its gate family and its tier. A regression here is silent and fleet-wide, so "ruling 1 held" had to be shown, not stated:
A second worktree at
⭐ H2 — you decided granularity by measuring both, and the numbers decide it
That is the whole question answered in one line. I asked whether dormant-by-design was expressible; your answer is the honest one — intent is not in the tree and no signal in this repo carries it, so the verdict does not pretend. What is mechanical is why it could not reach, and each dead hint prints one of three causes:
That third cause is the one worth having. Without it a reader goes hunting for a directory sitting in front of them — and it is the only one of the six where the derivation, not the gate, is what cannot express the population. Naming that distinction is what stops the verdict from reading as an accusation against six gates. Declining to build a dormancy declaration — noting the ⭐ H3 — demonstrated on real repos, not fixtures, and it caught my own warningThree legs, all end-to-end:
That third leg is my H1 caveat compiled into the tool. I wrote it as advice to you; you made it something the next reader cannot miss. And H1 — 6 of 114, and ruling 2 respectedCard said 5 of 110. Re-derived: 6 of 114, all named with causes, none fixed and none carded — so my triage stays in one place, which is what ruling 2 asked. The negative result, measured and correctly not filed
Checking the adjacent surface and reporting clean is worth as much as finding a defect, and filing nothing was right. It also bounds #9829's neighbourhood: the paths-filter family has a scheduling gap, not a dead-pattern gap. Ablation-1 hygieneLanding proven independently of the editor's exit code — removed-text Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#9883
One
hintCoverssweep over the tracked files givesscripts/pm/dispatch-gates.mjsathird verdict —
unreachable: a gate family whose whole declared population matchesnothing in the tree. Such a family reports exactly what a family that scanned a real
population and found no problems reports — green, silently — which is #4690 one level up.
Visibility only — and the proof that nothing else moved
The verdict is cross-cutting, not a fourth bucket.
matched/undetermined/silentall answer a question about the card ("is this family relevant to thesepaths?");
unreachableanswers a question about the tree ("does this family's declaredpopulation exist at all?"). It therefore sits outside the residue accounting throw for
the same double-counting reason the unfiltered-workflow count already does, and
classifyEntryis untouched.Measured against
origin/mainfrom a second worktree, same commit, same corpus:--tierover 134 sampled paths + 3 multi-path invocations, 591 linesmd5 22abac30…both trees)--residue)No merge-blocking context is added and no accept/reject behaviour changes anywhere.
H1 — the re-derived count: 6 of 114 (the card's census said 5 of 110)
mainhas moved since PR #9799's census; the recognizer agrees with it, including the'application/json'specimen the card names. Every one of the five scripts belowdeclares exactly one path literal, and it is dead:
check:driver-memory-census@objectstack/driver-memorygit ls-filescensus it computescheck:examples-live-importsexampleshintCoversrefuses it as too genericcheck:objectui-pin-freshobjectstack-ai/objectui.objectui-shanode scripts/check-objectui-pin-fresh.mjsobjectstack-ai/objectuicheck:release-bodyapplication/jsonnode scripts/check-skill-frame-freshness.mjsrefs/remotes/origin/mainPer ruling 2 none of these is fixed here, and no issue was filed for them either —
the report is on the card so the triage stays in one place.
Why family-level and not per-hint, measured on this tree: of 510 unique hints under
scripts/, 263 are dead, and 38 of the 86 declaring scripts carry at least one.A per-hint verdict is a noise generator; a family whose entire population is dead is
the reportable fact.
H2 — dormant vs unreachable: not expressible from the tree, so it is not claimed
A population that is empty by design is indistinguishable, from the tree alone, from a
hint spelled for a layout that moved: intent is not in the tree and no signal in this repo
carries it. Rather than conflate them, the verdict names why it could not reach, which
is mechanical — three causes, each printed in words:
never was a repo path— no tracked path under its first segment (5 of the 6);the tree stops at X; the layout moved under it— the usual real miss (no liveinstance today; the ablation below manufactures one);
the tree HAS it; the covering rule refuses the literal as too generic— theexamplescase. Without this the reader goes hunting a directory sitting in front ofthem.
If dormancy ever needs declaring rather than inferring, the shape is the
# dispatch-gates:marker convention this file already reads — built when a real instanceasks for it, not before.
H3 — the sweep survives its own emptiness by refusing, not by reporting zero
Demonstrated end to end, not only in fixtures:
git initrepo, zero tracked files) → refuses: "thetracked-file listing came back EMPTY … zero is a broken scan, not a clean repo (check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690)";
--tieras the half that needs no tree;hintCoversforced tofalse) → the tool exits 2 with"every one of the 79 famil(ies) that declare a population reached nothing … suspect the
recognizer … before reading it as a defect count" — a threshold-free guard that fires
only on the degenerate all-or-nothing shape, never on a count someone finds surprising;
residueLinesrefuses an omitted count and an omitted/zero corpus size, so a zerocan never print without the number of files it swept beside it.
The sweep runs before a single line is printed, so a refusal is a failed derivation rather
than a footnote under an answer that already looks complete.
H4 — the two ablations
1. A hint pointed at a path that cannot exist is reported. In
scripts/check-service-providers.mjs(one live hint) the literal was rewritten to a filethat does not exist. Landing confirmed independently of the editor's exit code: removed
text
grep -c→ 0, injected text → 2,git diff --stat→ 2 insertions / 2 deletions.The sweep went 6 → 7 and named it with the layout moved reason. Restore leg:
git checkout HEAD --the file, removed text back to 2, injected text 0,git status --porcelainempty, sweep back to 6.2. Nothing else moved — the table at the top of this PR.
Gates
Derived with the tool itself (no paths, off the merge base) at the final commit
7525a9250a, then run:No changeset: this is a
scripts/pm/tool and publishes nothing, so the PR carriesskip-changeset(ruling 5).Generated by Claude Code