Skip to content

fix(i18n): the object catalog loses to an explicitly-set scalar (#8284) - #8454

Merged
qq9340100 merged 5 commits into
mainfrom
claude/issue-8284-i18n-catalog-explicit-override
Aug 13, 2026
Merged

fix(i18n): the object catalog loses to an explicitly-set scalar (#8284)#8454
qq9340100 merged 5 commits into
mainfrom
claude/issue-8284-i18n-catalog-explicit-override

Conversation

@qq9340100

Copy link
Copy Markdown
Collaborator

Part of #8284

⚠️Deliberately Part of, not Fixes — the dispatch asked for Fixes #8284, and this PR does not close it: one of the card's two acceptance pins does not invert, for a reason measured during implementation (below). Merging this and closing #8284 would drop the severe half on the floor.

What the ruling asked for, and what this does

Maintainer ruling (2026-08-13, comment 5278888678): the i18n catalog loses to an explicit override, decided by comparison-based provenance — the catalog value applies only while the document's scalar still equals the packaged base value; a scalar that differs was explicitly set and the catalog yields. No provenance flags through the fold, all three scalars, one mechanism, ?layers=true untouched.

translateObject resolved label / pluralLabel / description as a flat catalog ?? document. The catalog is keyed by object name and is the packaged translation of the packaged declaration, so consulting it first discarded whatever had been authored on top of that declaration.

Per scalar, the catalog now applies only while document[key] === packagedBase[key].

Why the diff is four packages, not one

Reported before implementing, in this comment. Short version: the comparison needs the packaged base at translate time, and translate time is the REST boundary, where the document is already base + extension fold + tenant overlay + materialization. packages/spec has no runtime access (Prime Directive #2), so the value must be handed in.

PackageChange
specTranslateDocumentOptions.packagedBase; the per-scalar comparison in translateObject. Absent base ⇒ pre-#8284 behaviour, exactly.
metadata-protocolgetPackagedObjectBase(name) — the registry's packaged OWNER contributor.
resthands it to the translator at the three sites that localize an object document, feature-detected (so RestProtocol is not widened and spec/src/contracts/** is untouched).
qa/dogfoodpin dispositions (below).

The accessor choice is the trap of this card. The protocol's existing artifact lookup (SchemaRegistry.getArtifactItem) answers resolveOwnerLayer — owner with its extenders folded on. Comparing against that body would report the extension's label as "unchanged" and hand the catalog back the exact case #8037 filed. getPackagedObjectOwner (ADR-0029 D9.8) is the owner alone. Both are pinned side by side in packages/objectql/src/protocol-packaged-object-base.test.ts so the difference cannot be re-discovered by accident.

The half that does NOT invert, and why

The card's second it.fails — "a tenant's own rename reaches the reads its forms derive from" — stays it.fails. The catalog is no longer what discards the rename; the fold is:

mergeObjectDefinitions applies an extender's scalars last onto whatever base it receives, and ADR-0029 D9.2 makes the tenant's overlay that base (overlay ?? own, extenders folded on). So the showcase extension's label: 'Account (Success Overlay)' overwrites the tenant's 'Customer' inside the fold, and the value is not in the document any read serves. No change at the localization layer can put it there.

The card measured this without naming it — its own table records layers.effective = "Account (Success Overlay)"after the rename, i.e. the extension had already beaten the overlay before i18n ran. Whether a package extension's label should outrank a tenant's Studio rename is a fold-precedence decision the ruling did not make, and it is not arm B (nothing here proposes dropping scalars from the fold). Filed as a sub-issue.

So this PR converges the three reads on one label — which is the first pin, now plain green — and a new green case pins what holds in the renamed state, so the file is not silent about it.

Verification

Changeset: patch on the three shipped packages.


Generated by Claude Code

`translateObject` resolved `label` / `pluralLabel` / `description` as a flat
`catalog ?? document`. The i18n catalog is keyed by object name and is the
packaged translation of the PACKAGED declaration, so it overwrote every value
authored on top of that declaration: a code-shipped `objectExtensions` scalar,
and — the severe half — a tenant's own Studio rename, which answered 200 and
then appeared on neither `GET /meta/object` nor `GET /meta/object/:name`.
Maintainer ruling, 2026-08-13: the catalog loses to an explicit override,
decided by COMPARISON against the packaged base value, with no provenance flag
carried through the fold. Implemented per scalar:
- spec: `TranslateDocumentOptions.packagedBase`; the catalog applies only while
the document's scalar still equals the base's. Absent base restores the
pre-#8284 behaviour exactly, so nothing loses a translation it has today.
- metadata-protocol: `getPackagedObjectBase`, over the registry's packaged
OWNER contributor (never `getArtifactItem`, whose object branch answers the
extender-folded body and would call the extension's label unchanged).
- rest: hands the base to the translator at the three sites that localize an
object document, feature-detected so `RestProtocol` is not widened.
`?layers=true` stays untranslated and diagnostic. Arm B (fold drops scalars)
is not implemented and stays rejected.
Part of #8284 — the second `it.fails` pin does not invert: a package
extension's scalar still overwrites a tenant's rename inside
`mergeObjectDefinitions`, one layer below the catalog. Filed separately.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 13, 2026 6:06pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/metadata-protocol, @objectstack/rest, @objectstack/spec.

108 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/connect-mcp.mdx(via @objectstack/rest)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/automation/approvals.mdx(via @objectstack/spec)
  • content/docs/automation/connectors.mdx(via @objectstack/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via @objectstack/metadata-protocol, packages/spec)
  • content/docs/concepts/north-star.mdx(via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/cli.mdx(via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx(via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via @objectstack/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via @objectstack/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/metadata-protocol, @objectstack/spec)
  • content/docs/kernel/services.mdx(via @objectstack/spec)
  • content/docs/permissions/authentication.mdx(via @objectstack/rest)
  • content/docs/permissions/authorization.mdx(via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/rls.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/permissions/system-context.mdx(via packages/rest, packages/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/development.mdx(via @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx(via @objectstack/metadata-protocol, @objectstack/rest, @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via packages/rest, @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/apps.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)
  • content/docs/ui/translations.mdx(via @objectstack/spec)
  • content/docs/ui/views.mdx(via @objectstack/spec)

7 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v16.mdx(via @objectstack/spec)
  • content/docs/releases/v17.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/metadata-protocol, @objectstack/spec)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

`check:generated` proved exactly two artifacts stale, and only those two are
regenerated: the one added public export, `TranslateDocumentOptions` in
`./system`. Delta vs main: 1 added, 0 breaking (removed/narrowed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
Discharges the os-regen deferral recorded by the merge commit. The merge took
main's side of both shards (ADR/AGENTS: never text-merge a generated file), so
this restores the branch's one added export on top of main's current content.
Delta vs the merged main: 1 added (`TranslateDocumentOptions`), 0 breaking.
`check:generated` on the merged tree: all 13 artifacts up to date.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
@qq9340100
qq9340100 marked this pull request as ready for review August 13, 2026 18:32
@qq9340100
qq9340100 added this pull request to the merge queueAug 13, 2026
Merged via the queue into main with commit 427344cAug 13, 2026
27 checks passed
@qq9340100
qq9340100 deleted the claude/issue-8284-i18n-catalog-explicit-override branch August 13, 2026 18:50
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:systemsize/xlteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@qq9340100@claude