Found while implementing #13912 (artifact/HMR loader reading the container's own top-level object). Filed unassigned; not fixed there — out of that card's scope and it needs its own verification surface.
The reading, at origin/main1dcb995f2
After #13407 / #13913 / #13912 every container-object derivation in the repo reads the container's own object before the list.data.object chain. They still disagree about the row's own name:
| Site | Chain |
|---|
packages/objectql/src/engine.tsresolveMetadataItemName('views', item) (the boot-loop SOURCE registrar) | item.name then item.id then item.object then list.data.object then form.data.object |
packages/metadata/src/view-container-expansion.tsderiveViewContainerObject (used by the artifact/HMR SOURCE registrar and by getViewsByObject) | object then list.data.object then form.data.object then name |
packages/metadata-protocol/src/protocol.tsexpandRuntimeViewContainer (the runtime door) | object then list.data.object then form.data.object then name |
name is FIRST in one and LAST in the other two. For a container where the two values agree — the ordinary case, and what ViewSchema.name documents ("for an object-scoped container it is the object name") — nothing differs. They differ whenever a container carries a name that is not the object it binds to.
Reachable divergence
A container stored or authored as { name: 'lead_views', object: 'crm_lead', list: { ... } }:
- the ObjectQL boot loop calls
expandViewContainer(itemName, container) with itemName = 'lead_views', minting lead_views.default; - the metadata artifact/HMR loader derives
crm_lead and mints crm_lead.default, registering the container under crm_lead.
Same document, two source registrars, two registry keys and two sets of expanded item names. getViewsByObject('crm_lead') and GET /meta/view?object=crm_lead filter on the expanded items' object, so which registrar loaded the document decides whether the views are addressable under the object at all.
Both spellings are individually defensible — name is the row's identity, object is the declared binding — which is exactly why this is a decision rather than an obvious bug. ViewSchema.object's own .describe() names its readers (getViewsByObject() / GET /meta/view?object=), which is the argument for the declaration-bound order; the boot loop's comment argues from item identity.
Not covered by any test
No fixture in the repo sets a container name that differs from its bound object, so the divergence is un-rehearsed in both directions. Nothing shipped moves today whichever way it is settled.
Suggested direction (not a decision)
Per the 2026-08-07 meta-rule — one operation with two inconsistent implementations, the side bound by a declaration wins — the boot loop would adopt deriveViewContainerObject's order for the views branch of resolveMetadataItemName, with a pin on the disagreeing shape at both registrars. That is a cross-package move (packages/metadata is not a dependency of packages/objectql), so it needs its own scoping.
Related: #13912, #13913, #13407, #7736.
Generated by Claude Code
Found while implementing #13912 (artifact/HMR loader reading the container's own top-level
object). Filed unassigned; not fixed there — out of that card's scope and it needs its own verification surface.The reading, at
origin/main1dcb995f2After #13407 / #13913 / #13912 every container-object derivation in the repo reads the container's own
objectbefore thelist.data.objectchain. They still disagree about the row's ownname:packages/objectql/src/engine.tsresolveMetadataItemName('views', item)(the boot-loop SOURCE registrar)item.namethenitem.idthenitem.objectthenlist.data.objectthenform.data.objectpackages/metadata/src/view-container-expansion.tsderiveViewContainerObject(used by the artifact/HMR SOURCE registrar and bygetViewsByObject)objectthenlist.data.objectthenform.data.objectthennamepackages/metadata-protocol/src/protocol.tsexpandRuntimeViewContainer(the runtime door)objectthenlist.data.objectthenform.data.objectthennamenameis FIRST in one and LAST in the other two. For a container where the two values agree — the ordinary case, and whatViewSchema.namedocuments ("for an object-scoped container it is the object name") — nothing differs. They differ whenever a container carries anamethat is not the object it binds to.Reachable divergence
A container stored or authored as
{ name: 'lead_views', object: 'crm_lead', list: { ... } }:expandViewContainer(itemName, container)withitemName = 'lead_views', mintinglead_views.default;crm_leadand mintscrm_lead.default, registering the container undercrm_lead.Same document, two source registrars, two registry keys and two sets of expanded item names.
getViewsByObject('crm_lead')andGET /meta/view?object=crm_leadfilter on the expanded items'object, so which registrar loaded the document decides whether the views are addressable under the object at all.Both spellings are individually defensible —
nameis the row's identity,objectis the declared binding — which is exactly why this is a decision rather than an obvious bug.ViewSchema.object's own.describe()names its readers (getViewsByObject()/GET /meta/view?object=), which is the argument for the declaration-bound order; the boot loop's comment argues from item identity.Not covered by any test
No fixture in the repo sets a container
namethat differs from its bound object, so the divergence is un-rehearsed in both directions. Nothing shipped moves today whichever way it is settled.Suggested direction (not a decision)
Per the 2026-08-07 meta-rule — one operation with two inconsistent implementations, the side bound by a declaration wins — the boot loop would adopt
deriveViewContainerObject's order for theviewsbranch ofresolveMetadataItemName, with a pin on the disagreeing shape at both registrars. That is a cross-package move (packages/metadatais not a dependency ofpackages/objectql), so it needs its own scoping.Related: #13912, #13913, #13407, #7736.
Generated by Claude Code