fix(metadata-protocol,objectql): the /meta read exits materialize a served base the way the registry materializes its own (#8268) - #8380
Conversation
…erved base the way the registry does (#8268)
…pins that measure them
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 2 package(s): 16 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also reference the affected code. These are read-only:
|
ACCEPT — PM review,
|
| card | what is left | owner |
|---|---|---|
| #8375 | the multi-tenant indexes stamp has no converger at all; the read exit converges the fields map only |
pm:queue, this lane |
| #8376 | the read exits materialize the folded object while the registry materializes the base | ⛔ needs-user-decision — branch 2 is schema-migration-bearing |
| #8381 | the nameField strip drops an author's redundant pointer at first save |
pm:queue, this lane — read the correction above before starting |
Why close rather than re-queue: none of the three declares Blocked-by: #8268, so closing creates no circular block, and leaving it open would park a card in the pool whose content is fully duplicated across three children. That is the shape #7654 and #8136 were closed to avoid earlier in this shift.
Marking ready and enqueueing.
Generated by Claude Code
Part of #8268.
GET /meta/object/:nameservednameField: undefinedfor an object whose by-name read is answered from themetadataservice, whileGET /meta/objectand the registry's own resolved schema served'name'— same object, same moment, same host, with nothing in the response saying which link answered.This is the third time one seam has been ruled (#6562 injected system columns, then #8038
__search, nownameField), so it is fixed as a class rather than as a third stamp-specific patch.What changed
SchemaRegistry.registerObject's materialization block is now a single method,materializeBaseLayer, andmaterializeServedObjectOntoreplays that same code onto a body that never came throughregisterObject. The/metaread exits ask for the whole seam (materializeFromRegistry) instead of naming one stamp, so a stamp added to the block converges on served documents the day it is added — no fourth method, no fourth card.provisionSearchCompanionOntois reused, not duplicated; it stays public because the write-side strip is its exact inverse and hosts pin the pair.The seam turned out to be a PAIR
The read stamp created a write obligation, and the landed #4326 round-trip pin caught it —
meta-object-search-companion-roundtrip.test.tswent red with+ "nameField": "name"in the stored body, and the row's checksum moved. SostripMaterializedStampsFromis the whole-seam inverse, reached through the helpersaveMetaItemalready calls.saveMetaItem's own body is untouched.The title strip is exactness-bounded and its boundary is load-bearing in a way the
__searchstrip's is not:__searchremoves a value byte-identical to a platform-canonical field definition, where coincidence is implausible, whereasnameFieldis a single string an author writes deliberately to override the derivation. So the pointer comes off only when identical to what the seam would designate for a body carrying no pointer, and a pointer naming any other field is kept. Pinned directly.Stamp inventory
Every stamp that crosses the read-exit seam, what converges it, and whether this PR covers it.
created_at,owner_id,organization_id, …)applySystemFieldsapplyInjectedSystemColumns(#6562)applyAuditFieldGovernance(#4513)__searchcompanion columnprovisionSearchCompanionprovisionSearchCompanionOnto(#8038)nameField(ADR-0079 designation)provisionPrimaryindexesapplySystemFieldsNot part of this seam, listed so the enumeration is complete:
reconcileManagedApiMethodsand the twowarn*diagnostics run inregisterObjectabove the base-layer gate, so converging them is a separate decision, not an omission from this block.What this PR deliberately does NOT fix
All three are outside this card's region, all three are filed, and all three are pinned as EXPECTED divergences in the tests — so the day any of them is closed, the pin fails deliberately instead of drifting.
#8375 — the multi-tenant
indexesstamp. OnmultiTenant: true,applySystemFieldsalso stampsindexes: [{ fields: ['organization_id'] }]; the read exit converges the fields map only, so the by-name read serves noindexes. This is the general lesson worth more than the patch: the stamp that delegates to the registry (__search) has not drifted; the stamp with no converger (nameField) was simply missing; the stamp converged by a second implementation of its producer (applyInjectedSystemColumnsvsapplySystemFields) is the one that silently disagrees. That is exactly the shaped5031f6a1fixed next door by deleting a second implementation and calling the canonical one — still live here.#8376 — the seam's POSITION relative to the extender fold.
registerObjectmaterializes the base;resolveObjectfoldsextendcontributors on afterwards and never re-materializes; the read exits transform the already-folded document. So a title-less base that an extension gives a text field to gets a__searchcolumn from both/metareads and none from the registry — reproducing on the registry-only host, so it is not the artifact seam. Live since #8038 and unchanged here. Now labelledneeds-user-decision: one branch of the fix is schema-migration-bearing (it would makesyncSchemacreate real__searchcolumns on objects that have none today), which is the maintainer's call, not a seat's.This card's fix does not grow that defect: the title convergence withholds a designation the registry itself declined, so it can only move a served copy onto the registry's answer and never manufacture one. Pinned as
never INVENTS a designation the registry itself declined.#8381 — an author's explicit
nameFieldthat coincides with the derivation is not persisted. The strip is exactness-bounded, andnameFieldis a single string, so "the author wrotenameField: 'name'" and "the read derivednameField: 'name'" are the same bytes; the strip cannot tell them apart and drops it. Ruled by the PM as acceptable to ship (option A) with the lossless refinement (option C — make the strip stored-row-aware) filed as its own card, sinceregisterObjectre-derives the designation over every base layer at load: no resolved answer changes, now or at any future boot. What is lost is stability of intent against a later edit that adds a higher-ranked field.MEASURES that an author pointer identical to the derivation is never STORED, which also asserts the resolved answer is unchanged, so the pin records a persistence-fidelity gap rather than a behaviour regression. #8381 also records that the fence which blocked option C here —saveMetaItembeing held by #8184 — is lifted, since #8184 has landed (003feae65).Verification
Reverse-verified with the direction predicted before running: reverting both source files to
origin/mainturns exactly 5 of the 10 read-side cases red — the artifact agreement, the companion convergence, the companions-off case, keeps-designating, and theindexesmeasurement — and leaves the 5 that describe behaviourmainalready had green.The write half was reverse-verified by the landed pin going red on its own before the strip existed.
Suites, after the latest
mainmerge:All 56
check:*gates fromlint.ymlpass. Four initially reportedPREREQUISITE NOT MET — the workspace packages are not builtand explicitly measured nothing; after a full package-closure build,check:app-nav-i18n,check:i18n,check:i18n-coverageandcheck:type-check-debtare green. Path-re-derivation viascripts/pm/dispatch-gates.mjson the actual changed paths surfaced families the dispatch list did not name —check:authz-resolver,check:meta-type-normalized,check:engine-double-contract,check:query-options-erasure,check:type-check-coverage— all run and green.Anti-vacuity: every host asserts the read is non-empty and that its
namematches the registry's before comparing, and the untitled host proves the stamps are discriminated rather than always-applied.Docs checked, none updated: every
nameFieldpage undercontent/docs/is authoring-side and none states whatGET /meta/object/:nameserves.data-modeling/formulas.mdx's "an explicitnameFieldpointer is honored either way" stays true — #8381 concerns whether a redundant pointer is stored, not whether it is honored.content/docs/releases/**is read-only in a code PR and contains nothing this makes stale.Not touched:
translateObjectand i18n precedence (#8284 / #8037 — that fork is the maintainer's),saveMetaItem's refusal branch (#8184),assertFilterFieldsExist(#8296), the audit-write sites, and the error/catch message construction.Generated by Claude Code