Skip to content

Seed locale scope is silently inert on the three publish/install-time seed-load paths — package apply, draft publish and marketplace install pass no config.locale #17011

Description

@claude

Seed.locale's producer is wired on the boot path only (#16595). Three of this repo's six
SeedLoaderRequest builders still pass no config.locale, so a locale-scoped dataset applied
through any of them loads for every locale — the axis is silently inert exactly where an author is
most likely to reach it from Studio.

The three sites

Found by scanning for SeedLoaderRequestSchema (⛔ not for seedLoader.load, which misses two of
them because they name their local loader), at origin/main fd58495:

  • packages/runtime/src/domains/packages.tsapplyPublishedSeeds — package apply
  • packages/metadata-protocol/src/protocol.tsapplySeedBodies — draft publish
  • packages/cloud-connection/src/marketplace-install-local-plugin.tsrunInlineSeed — marketplace install

Each builds config as defaultMode + multiPass + an optional organizationId, and stops there.

Why this is a trap rather than a missing feature

SeedSchema accepts locale, the authoring docs teach it, and the loader honours it. On these three
paths the key is accepted, stored, replayed — and never read. That is the declared-not-enforced shape
Prime Directive #10 names, and it is the same shape Seed.env was in across all six sites before
framework#4704.

⚠️ Note what is NOT wrong here: Seed.env is live and correct on these three sites, because
resolveEnvConfig resolves the environment INSIDE load() off an ambient NODE_ENV. A locale has no
ambient source — the only layer that knows a stack's locale is the app config, which none of these
three is handed — so the env remedy does not transfer and this needs its own decision.

What the implementer must decide first

  1. Should a publish apply only the active locale's seeds at all? A package publish is arguably a
    locale-neutral act; filtering it may be wrong rather than merely unimplemented. Answer this before
    writing code.
  2. Where does each site get a locale? applyPublishedSeeds has DomainHandlerDeps.resolveService
    and could read the kernel's i18n service; applySeedBodies inside MetadataProtocol has engine
    plus metadata and no service resolver at all; runInlineSeed has a full PluginContext. The three
    answers are not the same shape.
  3. Kernel i18n service, or app config? Wire config.locale at the runtime's seed-load call sites — the locale axis added by #16510 is inert on the default boot path until a producer supplies it #16595's producer reads the app's declared
    i18n.defaultLocale at AppPlugin. A publish-time path has no single app, so it would have to read
    the kernel's active default locale instead — a second source for one axis, which needs to be a
    deliberate choice rather than a drift.

Current state, recorded rather than hidden

The seed.locale ledger row (packages/spec/liveness/seed.json) is live as of #16595 and names this
split explicitly in its note: the producer closes the default boot path, and these three are listed as
still unsupplied. SeedLoaderService#warnOnUnresolvedLocaleScope fires on all three, so the state is
loud rather than silent — that is the whole reason #16595 kept the warning instead of deleting it.

Not this card

Reconciling rows already written under a different locale — that is #16596.

Found while delivering #16595; filed unassigned and ungraded.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions