Repository navigation
fix(scripts): dispatch-gates derives the name-fold loader gate for every file under the roots it walks - #24263
Merged
objectstack-fleet[bot] merged 3 commits intoOct 18, 2026
Conversation
…OT_DIR_WATCH_HINTS, and the walk reads them The walk read a private list of bare single-segment words, which the dispatch-gates hint extractor admits as nothing, so a card editing any file under those roots was never told about this gate. The roots are now one literal subtree declaration, and SCAN_ROOTS is derived from it. The dead tools root (no tracked file) is dropped: the scanned count is unchanged. Claude-Session: https://claude.ai/code/session_01QBcLjVCmcWbZEk6qhYMib2 Co-authored-by: Claude <noreply@anthropic.com>
…WIDE rows its gate's declaration made stale check-position-name-fold-loaders now declares its roots and derives SCAN_ROOTS from that literal, so the bare-word literals these verdicts judged no longer exist and the self-test's STALE remedy applies. The declaration battery's floor follows the row count, two cases per row, 134 to 126 on a run. Claude-Session: https://claude.ai/code/session_01QBcLjVCmcWbZEk6qhYMib2 Co-authored-by: Claude <noreply@anthropic.com>
…ame-fold gate walks derives it Live-tree cases for both invocations: one probe per declared subtree root, read off the family's own extracted hints, plus the exact path PR #24028 edited; stripping the subtree hints leaves the measured miss NOT MATCHED. Claude-Session: https://claude.ai/code/session_01QBcLjVCmcWbZEk6qhYMib2 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
席位核对Seat Implemented-by:
Generated by Claude Code |
objectstack-fleet
Bot
deleted the
claude/issue-24037-dispatch-gates-scan-roots
branch
October 18, 2026 06:07
This was referenced Oct 18, 2026
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 free
to 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 #24037
Clause-②: no
The dispatch derivation now names
node scripts/check-position-name-fold-loaders.mjs(and its--self-test) for a change to any file under the roots that gate walks. The fix is in the gate's own source: its roots become theROOT_DIR_WATCH_HINTSliteral the derivation already reads, and the walk is derived from that literal.scripts/pm/dispatch-gates.mjsandscripts/pm/dispatch-gates.data.mjsare unchanged: no new gate, row, ratchet,--tiermandate or constant (ruling 6243472660, term 3).What changed
scripts/check-position-name-fold-loaders.mjs. The walked roots are now one exported literal,ROOT_DIR_WATCH_HINTS = ['packages/**', 'examples/**', 'apps/**', 'scripts/**', '.github/**'].SCAN_ROOTSis derived from it, so the walk and the declaration are one list and cannot drift. The one root not carried over istools: the tree has notools/directory (0 tracked files). The scan count is unchanged at 10263 files before and after. A declared root the tree does not have would print as a dead lead on every card the gate matches.scripts/pm/bare-root-worklist.mjs. The fourREFUSE-WIDEverdicts on this gate'sSCAN_ROOTSrows (packages, examples, apps, scripts; measured 2026-08-31) are withdrawn. OnceSCAN_ROOTSis derived, the bare-word literals they judged no longer exist, so the self-test's STALE remedy applies: "Delete the entry; do not re-point it at another row". A comment in their place names the ruling and the measured consumer. The declaration battery registers two cases per recorded row, so its floor follows the row count: 128 to 126 (134 to 126 on a run). One docblock sentence that cited the withdrawn 99% row is annotated. This file is outside the claim's declared file surface. The edit is forced: with the gate change alone, this self-test exits 1 with 5 failures (the STALE case plus four attribution cases).scripts/pm/dispatch-gates.self-test.mjs. One fast-tier block, against the live tree, for both invocations of the gate. It reads one probe per declared subtree root off the family's own extracted hints, plus the exact path PR fix(service-package,cloud-connection): convert stored package bodies forward at the sys_packages and marketplace doors #24028 edited (scripts/cross-package-test-inputs.mjs), and each must be MATCHED. In-place ablation: with the subtree hints stripped, the PR fix(service-package,cloud-connection): convert stored package bodies forward at the sys_packages and marketplace doors #24028 path and a brand-new package file both readsilent. A floor case requires at least five subtree roots, so the loop cannot run zero times.The mechanism, measured (the card marked it "likely, not confirmed")
extractWatchHints) keys on no constant name and noexport. It reads every quoted, path-shaped literal in the module body. The gate's roots were invisible because they were bare single-segment words, whichlooksPathyrefuses:extractWatchHints("const X = 'packages';")yields[].'.github'is dotted and was already read. SoSCAN_ROOTSbeing private was not the cause; the spelling was.check:watch-hint-literalconstrains the declaration to a literal array of admissible literals, and the new one passes (--listshows it).bare-root-worklist.mjsheld fourREFUSE-WIDEverdicts on exactly these rows: the declaration would be true, and was refused for the precision of the matched column. Three things decide it here:Derivation, before and after
f5ef054a--commands scripts/cross-package-test-inputs.mjs(the PR #24028 miss)--commandson the four card paths (dispatch-gates.mjs,.data.mjs,.self-test.mjs, the gate)--commandswith no paths (this diff, 3 files)Census (acceptance 2)
Population, by reading. Every gate's population constant, read by
node scripts/pm/bare-root-worklist.mjs, the derivation-coupled instrument for this exact species (a population constant holding a bare top-level word the extractor reads nothing for). Its--widesweep is the unrestricted contrast, and its CENSUS map holds the fs-trace census of computed roots. Each root's placement below is the derivation's ownplaceFamilyverdict for a brand-new file under that root, read on this branch.Queries over
scripts/*.mjsandscripts/pm/*.mjson this branch (files hit; controls first):isEntrypoint: 213 · controlreadFileSync: 255readdirSync|readdir\(: 146 ·\bwalk[A-Za-z]*\(: 99 ·'ls-files': 32 ·SCAN_ROOTS?\b: 25 ·\bROOTS\b: 22^(export )?const [A-Z_]*_WATCH_HINTS =(existing declarations underscripts/): 60 atf5ef054a, 61 here.check:watch-hint-literal --listprints 75 declarations repo-wide.f5ef054a; 78 rows, 46 files here. Wide contrast sweep: 140 pairs, 84 files atf5ef054a; 136 pairs, 83 files here. The diff in both sweeps is exactly the four name-fold rows.Answer: yes, other gates keep roots the same undeclared way. One is converted in this PR; every other is already read or is listed below with its reason. No row was added to
dispatch-gates.data.mjs.check-position-name-fold-loaders· packages, examples, apps, scripts (plus.github, already read)check-doc-formula-expressions(packages/lint) · content, docs, skills;check-agent-test-spelling· scripts, skills;check-cli-command-ids· scripts;check-corpus-claim-drift· skills;check-doc-authoring· packages, content, docs, skills;check-doc-route-spelling· skills;check-examples-live-imports· examples;check-org-identifier· apps, examples, packages;check-role-word· skills;check-scripts-symbol-anchors· scripts;check-skill-compatibility-version· skills;check-skill-frame-sync· skills;check-skill-identifier-liveness· skillsbuild-skill-docs,build-skill-references(packages/spec) · skills;check-declaration-mirrors· scripts;check-driver-conformanceDRIVERS_DIR · packages;check-dual-build-cjs-loads· packages;check-i18n-coverage· examples;check-logger-receiver-detach· apps, examples, packages;check-objectql-double-limit· packages;check-ratchet-remedy-authority· scripts;check-where-matcher-conformance· packages;pm/check-skill-id-lint· skillscheck-adr-0087-registration· apps, examples, packages;check-skill-compatibility-versionPACKAGE_ROOTS · apps, examples, packages;check-i18n-bundles,check-i18n-coverage,check-i18n-stale-fill· packages;check-skills-token-ratchet· skillscheck-dispatcher-error-vocabulary,check-error-code-casing,check-error-status-conformance,check-runtime-services-index,check-single-authz-resolver,check-skill-identifier-livenessIMPL_ROOTS,measure-durability-swallow-family· packages;check-engine-double-contract· examples, packagescheck-error-status-conformanceis derived by its content kind insteadwide-populationchannel (maintainer ruling 2026-09-05)check-optional-error-sink-contract· packages;check-resume-authority-declared· examples, packages;check-verify-stand-in-erasure· examples, packagescheck-driver-conformanceCASE_SETS_DIR,check-examples-live-importsPACKAGES_ROOT · packages;check-meta-type-normalized· packages (wide channel);check-runner-env-posture· apps, examples, packages (wide channel)check-doc-security-posture(packages/lint) · skills;check-live-db-isolation· apps, examples, packages (wide channel);check-vendor-version-stamps· apps, examples, packages, scripts;check-whole-set-label-write· scripts (MATCHED through other hints). Measured "not a population":check-console-injection×2,check-doc-frontmatter· docs,check-doc-security-posture· docscheck:route-envelope,check:live-db-isolation,check:startup-registry-verdict,check:wildcard-fallthrough,check:init-service-contract,check:settings-bind-window; always-runs:check:driver-memory-census; brand-new package filesilent:check:parse-guard,check:cli-command-ids,check:type-check-coverage,check:type-check-debt,check:error-code-provenance; MATCHED:check:org-identifierjoin(ROOT, 'packages')or loop literal is not a literal the extractor can read, so these cannot be read that way--widesweep's 34 extra files, each read)check-cross-package-test-inputs(a loop over packages/apps/examples; its population is test files, and a new test file under any of the three derives it through the test-file convention trigger, probed withexamples/app-crm/src/zz-probe.test.ts);check:skill-examples,check:yaml-examples(adir:property,path.resolve(REPO_ROOT, 'skills'));check:empty-state(a resolved packages root; undetermined);check:object-def-param-keys(git ls-files packages);check:service-providers(MANIFEST_PARENTS);check:docs-audit-scope(walkSrc(join(root, 'packages')));check:console-sha(a dist path);check:tenant-chokepoint(join-built file paths);measure-test-shard-timings --self-test(a loop literal);check:durability-log-level(derived by its content kind and its declared scan surface)check-self-test-wiredwalksscriptsand declaresscripts/**/*.mjs,.mtsand.sh(already read); these 11 are listed; the other 14 hold the word as a data key, a baseline path built byjoin, a self-test fixture or path parsing, not a walked rootThe three earlier instances the card names, read today (
--commandson real files):check:error-status-conformance: derived forpackages/metadata/src/loaders/ambiguous-metadata-stem.tsthrough its HTTP-status content kind. ItsSCAN_ROOT packagesrow stays REFUSE-WIDE.check:durability-log-level: derived forpackages/metadata/src/loaders/database-loader.tsthrough its durability content kind and its declared scan surface.check:i18n-coverage: derived forexamples/app-showcase/src/data/analytics/showcase.cube.tsthrough its declared examples hints. Its packages half stays SPELLABLE-UNDECLARED and is reached through the extract-config convention trigger.Verification
All readings below are on this branch's final head,
cf4e110f(git rev-parse --short HEAD), with no commit after them.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackwith no paths (the change set came from git: 3 files vs merge basef5ef054a7) derived 32 commands. Each was run with its exit code captured before any pipe, and all 32 exited 0.pnpm check:declared-population-livewas also run beyond the union, because this diff adds a declaration; it exited 0 (268 of 330 families declare a population, all live).--ranprinted✓ dispatch-gates --ran: 32 derived famil(ies) accounted for — 32 run, 0 NOT-MEASURED (a DERIVED zero — all 32 recorded an exit code and none of them is 3), with exit 0.node scripts/check-position-name-fold-loaders.mjs→10263 file(s) scanned under packages, examples, apps, scripts, .github; 8 reference(s): 6 test, 2 declared instrument, 0 loader(exit 0). The same 10263 atf5ef054awithtoolsstill in the list.… --self-test→39 cases pass(exit 0).node scripts/pm/bare-root-worklist.mjs --self-test→OK self-test: 78 live row(s), 56 unreachable as spelled, 43 recorded verdict(s) — none stale, none missing, none contradicted(exit 0). With the gate change alone it exits 1 with 5 failures.pnpm check:watch-hint-literal→75 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 50 …(exit 0).pnpm check:pm-dispatch-gates(the fast tier, as CI runs it on a PR) →✓ dispatch-gates self-test (fast tier): 1902 cases pass(exit 0, 384 s).main's push and hourly runs execute):node scripts/pm/dispatch-gates.mjs --self-testrun detached →fast 1902 case(s) in 394.0s · slow 260 case(s) in 1170.8s,✓ dispatch-gates self-test: 2162 cases pass., exit 0, 1566 s wall.check-ci-filter-parity,check-closing-keyword-parity(both),check-comment-mask-corpus,check-declaration-mirrors(both),check-scripts-symbol-anchors(both),check-self-test-wired(both),check-self-test-workflow-commands(both),check-whole-set-label-write(both),check:agent-test-spelling,check:bash32-floor,check:cli-command-ids,check:cross-package-test-inputs,check:driver-memory-census,check:entry-guard,check:gitlink-declared,check:nul-bytes(12120 text files, no control bytes),check:parse-guard,check:pnpm-filter-targets,check:pnpm-flag-spellings,check:ratchet-remedy-authority,check:refd-timer-probe.check:*farm inLint & Repo Gatesand the other required contexts. No package is touched, so there is no build closure, packagetestortypecheckto owe.Acceptance notes
toolsroot dropped from the walk is a behaviour delta only for a tree that grows a top-leveltools/. Today it is a no-op: 10263 files are scanned before and after. A futuretools/would need a declared root, as any other new root would.dispatch-gates*edit, and dispatch-gates lists Dogfood Regression Gate as "scheduled BY YOUR PATHS" for a route-ledger.ts change, but its if: skips pull_request and merge_group, so neither PR CI nor the derived commands run the dogfood pins (main red after #24009) #24073's job-condition rendering is untouched.git grepfinds naming an edited script: none read one.packages/spec/src/system/compliance-families-retirement.test.tsandpackages/types/src/driver-error-classification.callers.test.tsmention the dispatch-gates self-test in prose only, so they are not owed a run.scripts/**is in no package'sfiles[], soskip-changeset.Generated by Claude Code