Skip to content

A package extension's scalar overwrites a tenant's Studio rename inside the object fold, so the rename still reaches no read #8460

Description

@qq9340100

Filed from the #8284 implementation (PR #8454). #8284's ruling removed the i18n catalog as the thing that discarded a tenant's rename; this is what discards it underneath the catalog, and it is a decision the ruling did not make.

Mechanism

mergeObjectDefinitions (packages/objectql/src/registry.ts) applies an extender's scalars last, onto whatever base it is handed:

// Override scalar props (last writer wins)if(extension.label!==undefined)merged.label=extension.label;if(extension.pluralLabel!==undefined)merged.pluralLabel=extension.pluralLabel;if(extension.description!==undefined)merged.description=extension.description;

and ADR-0029 D9.2 makes the tenant's overlay the base of that fold — resolveObject picks contributors.find(c =%3E c.ownership === 'overlay') ?? ownerContrib and then folds every extend contributor on top. MetadataProtocol does the same on both read exits (foldObjectExtendersFromRegistry, applied to the overlay row in getMetaItem and to effectiveBase in getMetaItemLayered).

So for the showcase account, after a tenant renames the object through the ordinary Studio round-trip:

Layerlabel
packaged owner declarationAccount
tenant overlay row (sys_metadata)Customer ← what the tenant saved, and what ?layers=true shows under overlay
objectExtensions entry (priority: 210)Account (Success Overlay)
resolved / effective / every readAccount (Success Overlay)

The tenant's value is not in the document any read serves — so no change at the localization layer can put it there. #8284's own table already recorded this without naming it: it measured layers.effective = "Account (Success Overlay)"after the rename, i.e. the extension had beaten the overlay before i18n ran at all.

Why this is filed rather than fixed in PR #8454

The 2026-08-13 ruling on #8284 decided catalog vs explicitly-set scalar and was explicit about its mechanism (comparison against the packaged base, no provenance flags through the fold). Extension vs tenant overlay is a different precedence question, it changes ADR-0029 D9.2 behaviour, and Prime Directive #13 puts a recorded decision out of reach of a patch that quietly does the opposite. PR #8454 therefore leaves #8284's second it.fails pin exactly as written, so it flips to green the day this is ruled on, and adds a green case pinning what does hold today (all three reads now agree — on the extension's label, no longer on the packaged catalog string).

⛔ This is not arm B. Nothing here proposes that the fold stop carrying scalars; the question is only which of two authored scalars wins when both exist.

The decision needed

Should a code package's objectExtensions scalar outrank a tenant's own Studio rename of the same object?

Recommendation: A, implemented as the same comparison the #8284 fix uses, so the two layers share one sentence instead of two rules.

Reproduction

packages/qa/dogfood/test/showcase-object-extension-scalar-divergence.dogfood.test.ts — the it.fails case "SHOULD: a tenant's own rename reaches the reads its forms derive from", on PR #8454's branch (where the catalog no longer interferes, so the case now isolates exactly this defect).

Related

#8284 (parent — the catalog half, ruled and implemented) · #8037 · #8027 / #8045 · ADR-0029 D9.2 / D9.6


Generated by Claude Code

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions