Uh oh!
There was an error while loading. Please reload this page.
fix(devx): stop check:published-files spelling a bare repo root it never opens - #10890
Merged
Merged
Conversation
…ver opens
`check:published-files` reached the literal `scripts` through a
package-relative predicate over would-be tarball contents
(`rel.startsWith('scripts/')`), not through the repo root of the same
name. The dispatch derivation read that literal as a declaration of the
repo's own `scripts/` tree, and `hintCovers` refuses a bare top-level
word as too generic — so the gate was unnameable for every card while
appearing to name a root it never opens. It was the last row of
`ESCAPABLE_LITERAL_LEDGER`.
Respell the predicate as an anchored regex, the idiom the file's three
other FORBIDDEN entries already use. The row then discharges by
CONSTRUCTION rather than by declaration, and the ledger empties.
The ROOT_DIR_WATCH_HINTS escape — declaring `scripts/**` — is the wrong
remedy for this gate: it would be a false declaration, and would name
the gate for all 226 repo-root scripts/ files it does not read. Pinned
against, since the ledger cannot say so once its row is out.
Re-anchor the ledger's #4690 anti-vacuity guard. It was
`ledgerRows.length > 0`, a live-tree count that conflated "the
recognizer works" with "the tree still owes a row"; paying the last row
pulled those apart and left a shrink-only ledger that could not reach
zero. A probe family spelling a bare root is now spliced into the live
corpus and must be recognized, which holds at zero rows and at any
other count.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wtos-zhuang
marked this pull request as ready for review
August 21, 2026 16:11
Uh oh!
There was an error while loading. Please reload this page.
Contributor
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 32501648886 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
os-zhuang pushed a commit
that referenced
this pull request
Aug 21, 2026
…pecies A gate whose population literal carries no separator builds no watch hint at all -- `looksPathy` drops it before `hintCovers` is consulted -- so it is unnameable by any dispatch brief and leaves no residue saying so. That half is invisible to the derivation AND to ESCAPABLE_LITERAL_LEDGER, which #10890's comment says in the source and names #10840 for. Adds scripts/pm/bare-root-worklist.mjs: the sweep, derived at runtime from the derivation's own exported predicates, plus one recorded verdict per row. Its self-test pins the triage to the tree in both directions -- a verdict cannot outlive its row, and a new row cannot land unjudged -- and proves the recogniser both speaks and discriminates. Lands three per-gate declarations, the only rows clearing precision >= 85% and blast radius <= 300 files: check:driver-conformance packages/drivers/** 259/291 (89%) check:skill-frame-sync skills/** 48/50 (96%) check:skill-compatibility skills/** 49/50 (98%) Each pins the coupling in its own self-test, derived from the population constant rather than re-spelled, and pins its REFUSALS by name too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#10875
check:published-filesreached the literalscriptsthrough a package-relative predicate over would-be tarball contents, not through the repo root it appeared to name. Verified in source:The dispatch derivation read that literal as a declaration of the repo's own
scripts/tree, andhintCoversrefuses a bare top-level word as too generic — so the gate was unnameable for every card while appearing to name a root it never opens. It was the last row ofESCAPABLE_LITERAL_LEDGER.The remedy, and the one that was refused
Respell the predicate as an anchored regex — the idiom the file's three other
FORBIDDENentries already use. Behaviour is identical; the row discharges by construction rather than by declaration, and the ledger empties.⛔ The
ROOT_DIR_WATCH_HINTSescape (['scripts/**']) is the wrong remedy here. It is the idiom, it would have made the ledger green, and it would have been a false declaration. Measured on this tree:scriptsliteral ever contributedscripts/**would have added, to this one gateThe bare literal was already inert for matching, so removing it changes zero match results tree-wide (50259 → 50259 pairs over 131 families × 6300 files). It only ever bought the ledger row. The forbidden remedy would have bought 226 fabricated leads — the currency
hintCovers' refusal is priced in.hintCovers:920was not loosened.The verdict is correct, not merely quiet
Both directions are pinned against the live tree (
check:pm-dispatch-gates), because once a ledger row is out the ledger says nothing at all:scripts/file does not name this gate;scripts/check-published-files.mjs, a population it really does have, still resolvesmatched.The second is what separates a correct verdict from a dead one, and it is what the first case's non-vacuity rests on.
The ledger's #4690 guard had to be re-anchored
the live sweep still reaches this species at allwasledgerRows.length > 0— a live-tree count that read the right rule off the wrong quantity. It conflated two separable claims: "the recognizer works" and "the tree still owes a row". While a debt existed they moved together, so the conflation was invisible. Paying the last row is what pulled them apart, leaving a SHRINK-ONLY ledger that could not be allowed to reach zero — the one end state it exists to reach.A probe family spelling a bare root is now spliced into the live corpus and must be recognized. That holds at zero rows and at any other count, and unlike the fixture cases it exercises the live prefix set.
Two further cases were kept from going vacuous as the ledger emptied — the shape #10784's ablation caught one case over, where
silent === silentread as a pass.Ablations — prediction stated before each run
and no ledger row is stale, naming the rowno gate has NEWLY joined the escapable-literal speciesevery ledger row names a root the tree HASscripts/**…a brand-new repo-root scripts/ file does NOT name itOne prediction missed and is reported as a defect in the test, not noise: killing
trackedPrefixesglobally was predicted at 2 and observed 7.trackedPrefixesis a shared helper and 5 reds belonged to the residue/reachability sweep, which I had failed to include in the blast radius. Both target cases did red; the ablation was simply too broad to isolate the new guard, so it was re-run in isolated form (row 3 above).Note the fourth row: FRESH stayed green under the forbidden remedy, because a subtree declaration is not a bare root. That is exactly the failure the ledger alone could never have caught, and why it is pinned separately.
This list only ever saw the half the derivation can see — a literal that reaches the hint set, which needs a separator in the source spelling. #10840 measures the other half at ~33 gates whose population literal carries no separator at all. Those are invisible to the derivation and to this ledger, and emptying this list moves none of them. The ledger's own comment now says so, so nobody reads an empty list as "done".
Verification
Head
825d27a872. Gates derived withnode scripts/pm/dispatch-gates.mjs(no paths — it reads the merge-base changeset itself), all 7 run pluscheck:nul-bytes, every one exit 0:check:published-files' live verdict is unchanged from base (69 publishable packages, same registered-reason count), which is the behaviour-preservation half.check:entry-guard/check:parse-guardwere run by hand as instructed — though both are now derived automatically via #10873'sscripts/**declaration, so that dispatch note is stale.Rebased onto
origin/mainafter four sibling PRs landed mid-task; the diff is exactly two files.skip-changeset:scripts/-only internal CI tooling, releases nothing.Generated by Claude Code