Uh oh!
There was an error while loading. Please reload this page.
fix(tooling): declare check:where-matcher's test-file population where dispatch-gates can read it - #13231
Merged
Merged
Conversation
…e dispatch-gates can read it `scripts/pm/dispatch-gates.mjs` derives a card's gate list from the path literals in each gate's own source. `check-where-matcher-conformance.mjs` declared its population twice and the derivation could read neither: once in prose (the extractor masks comment ranges by construction) and once as `const SCAN_ROOT = 'packages'`, a single-segment literal `looksPathy` refuses as no hint at all. Measured before this change, `extractWatchHints` over the gate returned exactly one hint — `scripts/where-matcher-conformance.baseline.json`, the gate's own ledger. So the derivation could name the gate only for a change set that edits the set of files ALREADY KNOWN to be wrong, and never for a NEW silently-wrong matcher anywhere under the root it scans: the exact inverse of what it guards. Declares `packages/**/*.test.ts` beside `SCAN_ROOT` under the `ROOT_DIR_WATCH_HINTS` idiom, matching the identically-populated sibling `check-objectql-double-limit.mjs` (byte-identical `testFilesUnder`, identical `SCAN_ROOT`, identical call site). Measured at 2889 of the 2889 files the gate's own walk admits — set-equal in both directions — against 5509 tracked files under the bare root. Pinned in the gate's own `--self-test`, in the four directions the sibling pins. The PM's bare-root worklist row is re-decided from REFUSE-UNSPELLABLE to DECLARED-NARROWER with the same `package test files` spelling, re-measured on this tree rather than carried from the sibling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
This was referenced Aug 29, 2026
os-elon
marked this pull request as ready for review
August 29, 2026 14:09
Uh oh!
There was an error while loading. Please reload this page.
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#13163
scripts/pm/dispatch-gates.mjsderives a card's gate list from the path literals in each gate's own source.check-where-matcher-conformance.mjsdeclared its population twice and the derivation could read neither: once in prose (the extractor masks comment ranges by construction) and once asconst SCAN_ROOT = 'packages', a single-segment literallooksPathyrefuses as no hint at all.The deliverable is DERIVABILITY, not a green gate
The gate always worked. What follows is therefore the reverse proof over the specimen the card names — the test file PR #13146 adds,
packages/core/src/security/resolve-authz-context.platform-admin-config.test.ts— and not a run of the gate.check:where-matcherin the MATCHED columnmatched via ... gate source 'packages/**/*.test.ts'The whole accounting moves by exactly one, in every bucket at once: the gate leaves the
silentclass, and specifically the "declare ONLY tracked FILES — an artifact roster" sub-class, which is the card's diagnosis stated in the tool's own vocabulary.Both negative directions hold, so this is a narrowing and not the bare root wearing a glob:
packages/core/src/security/resolve-authz-context.ts(a non-test source in the same directory) — still not named, 0 hits.docs/README.md— still not named, 0 hits.What was measured, including one falsification
A2.3 — the card's extractor reading reproduces, exactly.
extractWatchHintsover the gate returned["scripts/where-matcher-conformance.baseline.json"]— one hint, the gate's own baseline. After:["scripts/where-matcher-conformance.baseline.json", "packages/**/*.test.ts"], exactly one hint added.A2.1 — the two populations are genuinely identical, checked before copying.
check-objectql-double-limit.mjsand this gate hold the sameconst SCAN_ROOT = 'packages', and theirtestFilesUnderfunctions are byte-identical (sha256 of both nine-line bodies:beb4ed6b2f863688) — same skip set, same/\.test\.ts$/admission — and both are called astestFilesUnder(join(repoRoot, SCAN_ROOT)). So the copied spelling declares a population this gate really scans.A2.2 — the
"n/a"in the sibling's hint array is NOT a declaration, and is deliberately not copied. It is a byproduct:wrapOrder: 'n/a'is a verdict token in that gate'sjudge()andmeasure()— module-scope code, so not masked — andlooksPathyadmits any literal containing a separator. Measured: it reaches 0 tracked files, i.e. an inert hint, andisNonPathNamespace('n/a')isfalseso nothing filters it. Copying it would have added a dead hint for no reason.Falsified, and worth recording: the tool does NOT stay silent about this gate today. The card's headline is true of the path derivation, but
check:where-matcheris already printed for the specimen in the convention-triggered section ("adds or edits a test file"), the named table #8632 added for exactly this class of ratchet — and that entry is pinned bydispatch-gates' own self-test. So what this PR changes is narrower than "the gate was unreachable": it moves the gate into the high-signal MATCHED column, the one a dev pastes and runs, for the test files it really walks. The two authorities now agree instead of only one speaking. This does not retire the convention entry, and no line ofscripts/pm/dispatch-gates.mjsis touched (that is #13126, queued behind this card).The declaration, and the pins under it
ROOT_DIR_WATCH_HINTS = ['packages/**/*.test.ts'], declared besideSCAN_ROOTunder the sibling's idiom. Measured on this tree at 2889 of the 2889 files this gate's owntestFilesUnder()walk admits — set-equal in both directions (nothing walked left uncovered, nothing covered left unwalked) — against 5509 tracked files under the bare root.Four assertions were added to the gate's own
--self-test, which is the right host:check:pm-dispatch-gatesis the battery for the derivation tool, and a where-matcher declaration failing there would read as "the derivation broke".pnpm check:where-matcherruns the self-test before the corpus scan, so CI holds it on every PR.The pin was ablated in both directions, each mutation proven on disk (removed-text
grep -c0, injected-textgrep -c1, and a changedgit hash-objectblob) with an absolute-pathtraprestore verified back to the exactHEADblob:SCAN_ROOT'packages/**'Restored tree: self-test exit 0,
git diff HEADempty. No build ordist/leg applies — this gate is executed from source by path, not resolved through a packageexportsmap.The second edit: the recorded verdict had to move with it
scripts/pm/bare-root-worklist.mjsrecorded this row asREFUSE-UNSPELLABLE— "the population is a file-KIND filter inside the root, and NO spelling of the idiom describes it". Leaving that standing beside a gate that now declares exactly such a spelling is the lying-record failure that file exists to catch, and its own--self-testcannot see it (it audits keys and verdicts, never what awhysays).The row moves to
DECLARED-NARROWERwith the existingpackage test filesspelling, re-measured on this tree rather than carried from the sibling. This is a re-decision on a shrink-only map, taken under the authorisation sentence the maintainer's 2026-08-26 ruling granted in that file and no wider one: bringing a verdict back to truth after its definitional basis moved (#12300 retired the collapse the refusal rested on) is not loosening the map. The criterion that split that class was measured downstream pull; this row had none on 2026-08-26 and now has one. The header records the re-decision as an eighteenth row. Please sanity-check this half — it is the one judgement call in the PR.Mechanically confirmed: the row stays uncovered (
packages/**/*.test.tsdoes not coverpackages/probe.file), which is whatDECLARED-NARROWERstates, so the self-test's CONTRADICTED direction stays empty.Verification
All of the following at final head
3ce97e4b4d, each exit code captured before any pipe, each verdict quoted from the gate's own output.pnpm check:where-matcher— VERDICT command-exit 0 under the shared verify lock. "where-matcher conformance holds: 315 matcher(s) discovered, 315 answer the combinator battery correctly or refuse it loudly (197 refuse). 0 silently-wrong and 0 unjudged."node scripts/pm/bare-root-worklist.mjs --self-test— exit 0. "50 live row(s), 43 unreachable as spelled, 43 recorded verdict(s) — none stale, none missing, none contradicted. 18 record(s) carry a spelling and every one of 9 distinct spelling(s) is pinned LIVE, PRECISE and COMPLETE."pnpm check:pm-dispatch-gates— exit 0. "dispatch-gates self-test: 879 cases pass."pnpm check:watch-hint-literal— exit 0. "20 ROOT_DIR_WATCH_HINTS declaration(s), every one an array of quoted literals inside its own statement."node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstackderives for this diff, all exit 0:check:agent-test-spelling,check:bash32-floor,check:cli-command-ids,check:cross-package-test-inputs,check:entry-guard,check:parse-guard,check:pnpm-filter-targets,check:nul-bytes,scripts/check-ci-filter-parity.mjs,scripts/check-cross-package-test-inputs.mjs,scripts/check-shard-attestation.mjs.check:i18n-stale-fill,check:pm-label-desc-cap,scripts/check-published-list-mirrors.mjs,check:pm-dispatch-gates— all exit 0.pnpm lint— whole-repoeslint . --no-inline-config, exit 0 in 70s. No narrowing claimed.node scripts/check-test-completeness.mjs— NOT MEASURED, not red: it printed "PREREQUISITE NOT MET — this gate grades a savedturbo run testlog, and no log was named" ([finding]check-test-completeness.mjsanswers a standalone run with exit 1 + a usage line, so the derived gate family reads one false red — three independent devs paid for it in one session #13110).No changeset: this PR touches two tooling scripts, publishes nothing, and releases no package.
skip-changesetapplied.Generated by Claude Code
Generated by Claude Code