fix(pm): make dispatch-gates see the metadata TYPE registry's i18n coupling - #9219
Merged
os-project-manager merged 1 commit intoAug 17, 2026
Merged
Conversation
…upling walkMetadataForms (packages/cli/src/utils/i18n-extract.ts) emits the metadataForms i18n surface from two producers: METADATA_FORM_REGISTRY (the 17 *.form.ts modules, already covered by the form-module convention entry in dispatch-gates.mjs) and DEFAULT_METADATA_TYPE_REGISTRY plus the METADATA_FORM_REGISTRY module itself (packages/spec/src/kernel/ metadata-plugin.zod.ts, packages/spec/src/system/metadata-form-registry.ts). Editing either of the latter two moves the same platform-objects bundles PR #9113 had to regenerate, and derived nothing from dispatch-gates. Both are exactly two known files, not a runtime-enumerated population, so this closes the gap the same way SURFACE_MODULE and check-type-check-coverage.mjs's ROOT_PROGRAM_COUPLED_SCRIPT already do: two bare module-body path-literal constants declared directly in check-i18n-bundles.mjs (the script check:i18n resolves to), read by the ordinary path-literal derivation with no new CHANGE_KIND_GATES entry. Pinned live in dispatch-gates.mjs's own self-test (existsSync + a matched classifyEntry verdict for each), so a renamed or moved registry module reddens that self-test instead of the derivation silently going blind on this edge again. Fixes #9144
os-project-manager
marked this pull request as ready for review
August 17, 2026 02:39
os-project-manager
deleted the
claude/issue-9144-registry-i18n-gate-visibility
branch
August 17, 2026 02:57
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 #9144
What
walkMetadataForms(packages/cli/src/utils/i18n-extract.ts) emits themetadataFormsi18n surface from two producers. Only one —METADATA_FORM_REGISTRY's 17*.form.tsmodules — was discoverable byscripts/pm/dispatch-gates.mjs, via theedits a metadata form moduleCHANGE_KIND_GATESentry #9116 added. The second —DEFAULT_METADATA_TYPE_REGISTRY(packages/spec/src/kernel/metadata-plugin.zod.ts) andMETADATA_FORM_REGISTRYitself (packages/spec/src/system/metadata-form-registry.ts, the map, not its*.form.tsleaves) — derived nothing: neither file carries the.form.tsfilename convention, so editing a type-level label or adding/removing a registry entry moved the sameplatform-objectsbundles PR #9113 had to regenerate, invisibly to the derivation.Route taken, and why
Per the card's own analysis, this edge is not a runtime-enumerated population like the other two
check:i18nCHANGE_KIND_GATESentries — it is exactly two known files. That is the shapeSURFACE_MODULE(check-i18n-bundles.mjs, #9116) andcheck-type-check-coverage.mjs'sROOT_PROGRAM_COUPLED_SCRIPTalready use, so this closes it the same way: two bare module-body path-literal constants (METADATA_TYPE_REGISTRY_MODULE,METADATA_FORM_REGISTRY_MODULE) declared directly incheck-i18n-bundles.mjs— the one scriptcheck:i18n's invocation resolves to — read by the ordinary path-literal derivation. No newCHANGE_KIND_GATESentry, nomatchesfunction, nothing to keep in sync at runtime.Identifier discovery (walking for the
export constdeclarations) was the other live candidate and is genuinely more self-reporting, but the card measured no cheap bound on its ~925-file-per-run cost and this dispatch didn't find one either — a fixed two-file constant is exactly as expensive per run as identifier discovery would be per changed file, with none of the walk cost. Widening topackages/spec/srcstays disqualified per #9116.How the coupling constants are kept from rotting silently
This is the same open question every reader of
SURFACE_MODULE/ROOT_PROGRAM_COUPLED_SCRIPTwould ask, and the precedent's answer is copied exactly:scripts/pm/dispatch-gates.mjs's own self-test now pins, against the real files:check-i18n-bundles.mjs's live-extracted hints cover both declared paths;matchedthrough that exact hint (notsilent);existsSyncon disk.Delete either constant, rename either module, or let the registries merge, and this self-test reddens instead of the derivation silently going blind on this edge again —
check:pm-dispatch-gatesruns it unconditionally in CI.Verified before building
Re-confirmed on
origin/main@88f97d528(post #9188, post #9202):walkMetadataForms(packages/cli/src/utils/i18n-extract.ts:919-947);find packages/spec/src -name '*.form.ts' | wc -l→ 17, andMETADATA_FORM_REGISTRY's object body → 17 keys, matching exactly;DEFAULT_METADATA_TYPE_REGISTRYcarries 27 entries (17 with a form, 10 form-less —datasource,job,translation, etc.), consistent with the "every entry including form-less types" claim.Reverse verification (commit-first, per AGENTS.md): checked out the pre-fix (
origin/main) versions of all three touched files over the committed fix, confirmednode scripts/pm/dispatch-gates.mjs packages/spec/src/kernel/metadata-plugin.zod.tsand the form-registry-module equivalent both scored not matched (reproducing the exact #9144 gap), then restored the committed fix (git checkout HEAD -- <paths>) and re-confirmed both now scorematchedwithhits[0].hintequal to the exact path.Not in scope
scripts/pm/dispatch-gates.mjsdoes not derivecheck:livenessfor apackages/objectql/**path, but CI'sSpec property livenessjob runs on one — every dispatch tells devs to trust that derivation #9171 nor dispatch-gates discovers no family for a workflow verification step whose script is not namedcheck-*—docs-drift-check.ymlruns one onpackages/**and the tool cannot mention it in any bucket #9187 is touched — this is the third, split edge.check-i18n-bundles.mjs's own drift-detection logic; it already re-extracts fresh on every run regardless of which producer moved. Only the derivation's visibility was broken.Tests
At commit
19b18303e(git rev-parse --short HEAD), under the sharedflockverify lock:Gate derivation re-run against the actual changed paths at this head named exactly
check:i18nandcheck:pm-dispatch-gates— both run above.Changeset
scripts/**only, publishes nothing — no.changeset/*.md. Applyingskip-changesetafter this PR opens (reading back the full label set first, per repo convention).Generated by Claude Code
Generated by Claude Code