Filed out of #16828's mandatory sweep (same class: a whole/subtree-walk gate whose workflow-visible names: covers only current members, so a card that trips the gate is invisible to it). Category (a), a reproducible tooling defect.
What happened, independently re-verified (not just trusted from the reports below)
check:migration-registry (packages/spec/package.json: tsx scripts/build-migration-registry.ts --self-test --check) is never its own CI workflow step — it is invoked internally, as one entry of the GATED array inside packages/spec/scripts/check-generated.ts, whose single workflow step is pnpm --filter @objectstack/spec check:generated --reconcile-only (.github/workflows/lint.yml).
Measured on 881ce2bf3 via discoverFamilies():
check: check:generated | hints (10): [
'scripts/check-regen-pending.mjs', 'docs/protocol-upgrade-guide.md',
'packages/spec/src/meta-spelling/meta-url-data.generated.ts',
'packages/spec/api-surface', 'packages/spec/export-origins', 'packages/spec/declaration-map',
'content/docs/references/**', 'docs/audits/2026-07-unknown-key-strictness-ledger.counts.md',
'packages/spec/liveness/state-counts.md', 'scripts/gen-sdui-manifest.sh'
]
placement for editing packages/spec/src/migrations/registry.ts directly: silent
placement for adding a new packages/spec/src/migrations/entries/*.ts file: silent
Neither the generated artifact nor its source directory is a hint. check:migration-registry isn't even its own dispatch-gates family — none of discoverFamilies()'s keys match /migrat/i at all.
Root cause
check-generated.ts's GATED array entry:
{
check: 'check:migration-registry',
gen: 'gen:migration-registry',
artifact: 'src/migrations/registry.ts — its generated regions, from src/migrations/entries/',
}
artifact is prose for a human reading --list output, not a path literal — the em dash and spaces fail extractWatchHints's path-shaped admission regex (/^[\w.@][\w.@/*-]*$/) outright, so the whole string is silently discarded rather than partially admitted. This is a formatting gap, not a width one: unlike check:route-envelope, the real population here (one generated file + the directory that drives it) is precisely spellable.
Reported independently by PR #16778 and PR #17029's dev seats (per #16828's claim comment) as "absent from dispatch-gates --commands on a diff that regenerates the very file it guards" — this issue is the re-derived, re-verified root cause and fix direction for that report.
Suggested fix (not implemented here — different file, different package's gate pipeline, out of #16828's bounded in-place-fix bar)
Give the GATED array a real path alongside the prose, e.g. a second field (hint: 'packages/spec/src/migrations/registry.ts', or a hints: [...] array covering both the generated file and packages/spec/src/migrations/entries/**) that extractWatchHints can admit, leaving artifact free to stay human-readable. No wide-population/whole-tree-population marker needed — this population is small and precisely nameable, unlike check:route-envelope's.
Positive control run against this issue
placeFamily(check:generated entry, ['packages/spec/src/migrations/registry.ts']) → silent (measured above). Fixing the hint should flip this to matched — not verified here since the fix isn't implemented in this issue.
Filed out of #16828's mandatory sweep (same class: a whole/subtree-walk gate whose workflow-visible
names:covers only current members, so a card that trips the gate is invisible to it). Category (a), a reproducible tooling defect.What happened, independently re-verified (not just trusted from the reports below)
check:migration-registry(packages/spec/package.json:tsx scripts/build-migration-registry.ts --self-test --check) is never its own CI workflow step — it is invoked internally, as one entry of theGATEDarray insidepackages/spec/scripts/check-generated.ts, whose single workflow step ispnpm --filter @objectstack/spec check:generated --reconcile-only(.github/workflows/lint.yml).Measured on
881ce2bf3viadiscoverFamilies():Neither the generated artifact nor its source directory is a hint.
check:migration-registryisn't even its own dispatch-gates family — none ofdiscoverFamilies()'s keys match/migrat/iat all.Root cause
check-generated.ts'sGATEDarray entry:artifactis prose for a human reading--listoutput, not a path literal — the em dash and spaces failextractWatchHints's path-shaped admission regex (/^[\w.@][\w.@/*-]*$/) outright, so the whole string is silently discarded rather than partially admitted. This is a formatting gap, not a width one: unlikecheck:route-envelope, the real population here (one generated file + the directory that drives it) is precisely spellable.Reported independently by PR #16778 and PR #17029's dev seats (per #16828's claim comment) as "absent from
dispatch-gates --commandson a diff that regenerates the very file it guards" — this issue is the re-derived, re-verified root cause and fix direction for that report.Suggested fix (not implemented here — different file, different package's gate pipeline, out of #16828's bounded in-place-fix bar)
Give the
GATEDarray a real path alongside the prose, e.g. a second field (hint: 'packages/spec/src/migrations/registry.ts', or ahints: [...]array covering both the generated file andpackages/spec/src/migrations/entries/**) thatextractWatchHintscan admit, leavingartifactfree to stay human-readable. Nowide-population/whole-tree-populationmarker needed — this population is small and precisely nameable, unlikecheck:route-envelope's.Positive control run against this issue
placeFamily(check:generated entry, ['packages/spec/src/migrations/registry.ts'])→silent(measured above). Fixing the hint should flip this tomatched— not verified here since the fix isn't implemented in this issue.