diff --git a/packages/metadata-protocol/CHANGELOG.md b/packages/metadata-protocol/CHANGELOG.md index e3e36d4f40..b41c75aae5 100644 --- a/packages/metadata-protocol/CHANGELOG.md +++ b/packages/metadata-protocol/CHANGELOG.md @@ -125,7 +125,13 @@ The platform still translates nothing and merges nothing. The app authors both record sets; this adds only the axis that selects between them. - **What is not wired yet, stated plainly.** The locale axis is evaluated against `config.locale`, and no first-party call site supplies one — the runtime wiring that would resolve it from the stack's configured locale is a separate change in `packages/runtime`. An embedding host that passes `config.locale` itself gets the full behaviour today; on the default boot path the axis is inert. That is the shape `Seed.env` was in before framework#4704, so it is not left silent: a load carrying locale-scoped datasets and no `config.locale` warns naming each dataset it let through and the config key that would make the scope take effect. The liveness ledger records `seed.locale` as `experimental` for exactly this reason, with the consumer side cited and the producer gap spelled out, rather than claiming `live` on a correct-but-insufficient consumer pointer. + **What is not wired yet, stated plainly.** The locale axis is evaluated against `config.locale`. As published, this entry continued "and no first-party call site supplies one — the runtime wiring that would resolve it from the stack's configured locale is a separate change in `packages/runtime`", and said that on the default boot path the axis is inert. Both clauses are false as of PR #17013: `AppPlugin#resolveSeedLocale` resolves the load-time locale from the app's declared `i18n.defaultLocale` and threads it into all three `SeedLoaderRequest`s that plugin builds — the inline boot seed, the per-org replayer registered for tenant provisioning, and the dev hot-reload seeder — so a first-party call site does supply `config.locale`, and the axis takes effect on the default boot path. An embedding host that passes `config.locale` itself gets the full behaviour, as it always did. What is still unwired is narrower, and named: three request builders outside that plugin pass no locale — `applyPublishedSeeds` (package apply), `applySeedBodies` (draft publish) and `runInlineSeed` (marketplace install). + + *Erratum, 2026-09-12 — PR #17013 supplied the producer this paragraph described as missing. The sentence was true when written: the release compiled this entry 15 minutes before that PR landed.* + + That is the shape `Seed.env` was in before framework#4704, so it is not left silent: a load carrying locale-scoped datasets and no `config.locale` warns naming each dataset it let through and the config key that would make the scope take effect. That warning stays after #17013, because the three builders above, any embedding host that builds its own request, and a stack that declares no `i18n` block all still reach the loader without a locale. As published, this entry closed "The liveness ledger records `seed.locale` as `experimental` for exactly this reason, with the consumer side cited and the producer gap spelled out, rather than claiming `live` on a correct-but-insufficient consumer pointer"; the ledger records `seed.locale` as `live`, naming `AppPlugin#resolveSeedLocale` as the producer and writing the remaining bound — three of six request builders — into the row itself. + + *Erratum, 2026-09-12 — PR #17013 flipped `packages/spec/liveness/seed.json` → `seed.locale` from `experimental` to `live` in the same landing. (Corrected after publication, #17026.)* - 615fac3: A publish now refuses an object whose `highlightFields` names a field that does not exist on it — the same gate that refuses a code-authored stack. `list-view-field-unknown` inspects `view.columns`, and Studio's app builder mints no `view` items at all, so the reference-integrity family had nothing to inspect on the only artifacts the click path authors. What it authors is the **object**, and an object-level field-name list was covered by nothing that could refuse: measured on `origin/main`, `runtimeAuthoringRulesFor('object')` dispatched seven rules with no reference-integrity rule among them, while the object-level existence check that did exist (`semantic-role-field-unknown`) is `warning`, advisory-tier and CLI-only. So `os validate` exited 0 on a dangling reference and the runtime publish door — the only door a Studio, REST `/meta` or MCP author has — said nothing at all. diff --git a/packages/spec/CHANGELOG.md b/packages/spec/CHANGELOG.md index d94ff3b4b5..a1b11b77e1 100644 --- a/packages/spec/CHANGELOG.md +++ b/packages/spec/CHANGELOG.md @@ -2448,7 +2448,13 @@ The platform still translates nothing and merges nothing. The app authors both record sets; this adds only the axis that selects between them. - **What is not wired yet, stated plainly.** The locale axis is evaluated against `config.locale`, and no first-party call site supplies one — the runtime wiring that would resolve it from the stack's configured locale is a separate change in `packages/runtime`. An embedding host that passes `config.locale` itself gets the full behaviour today; on the default boot path the axis is inert. That is the shape `Seed.env` was in before framework#4704, so it is not left silent: a load carrying locale-scoped datasets and no `config.locale` warns naming each dataset it let through and the config key that would make the scope take effect. The liveness ledger records `seed.locale` as `experimental` for exactly this reason, with the consumer side cited and the producer gap spelled out, rather than claiming `live` on a correct-but-insufficient consumer pointer. + **What is not wired yet, stated plainly.** The locale axis is evaluated against `config.locale`. As published, this entry continued "and no first-party call site supplies one — the runtime wiring that would resolve it from the stack's configured locale is a separate change in `packages/runtime`", and said that on the default boot path the axis is inert. Both clauses are false as of PR #17013: `AppPlugin#resolveSeedLocale` resolves the load-time locale from the app's declared `i18n.defaultLocale` and threads it into all three `SeedLoaderRequest`s that plugin builds — the inline boot seed, the per-org replayer registered for tenant provisioning, and the dev hot-reload seeder — so a first-party call site does supply `config.locale`, and the axis takes effect on the default boot path. An embedding host that passes `config.locale` itself gets the full behaviour, as it always did. What is still unwired is narrower, and named: three request builders outside that plugin pass no locale — `applyPublishedSeeds` (package apply), `applySeedBodies` (draft publish) and `runInlineSeed` (marketplace install). + + *Erratum, 2026-09-12 — PR #17013 supplied the producer this paragraph described as missing. The sentence was true when written: the release compiled this entry 15 minutes before that PR landed.* + + That is the shape `Seed.env` was in before framework#4704, so it is not left silent: a load carrying locale-scoped datasets and no `config.locale` warns naming each dataset it let through and the config key that would make the scope take effect. That warning stays after #17013, because the three builders above, any embedding host that builds its own request, and a stack that declares no `i18n` block all still reach the loader without a locale. As published, this entry closed "The liveness ledger records `seed.locale` as `experimental` for exactly this reason, with the consumer side cited and the producer gap spelled out, rather than claiming `live` on a correct-but-insufficient consumer pointer"; the ledger records `seed.locale` as `live`, naming `AppPlugin#resolveSeedLocale` as the producer and writing the remaining bound — three of six request builders — into the row itself. + + *Erratum, 2026-09-12 — PR #17013 flipped `packages/spec/liveness/seed.json` → `seed.locale` from `experimental` to `live` in the same landing. (Corrected after publication, #17026.)* - 8e0b297: fix(plugin-auth)!: `positions[]` on the session payload is the SECURITY axis, not the better-auth role scalar (#15136)