Found while implementing #4624 (PR #4635). Unassigned — nobody is on this. Recording only, per Prime Directive #10.
Evidence
loadMetaFromDb's object branch (packages/metadata-protocol/src/protocol.ts, ~line 8958 on current main) registers each hydrated object row with:
this.engine.registry.registerObject(
{ ...(data as Record<string, unknown>), _provenance: 'org' } as any,
record.packageId || 'sys_metadata',
);
But engine.find('sys_metadata', ...) returns rows keyed by the object's snake_case field names — package_id, not packageId:
- the
sys_metadata object declares package_id (packages/metadata-core/src/objects/sys-metadata.object.ts);
SysMetadataRepository writes parentRowData.package_id = ... (sys-metadata-repository.ts ~386-388) and maps row.package_id → packageId explicitly when it wants camelCase (~784);
getMetaItems in the same file reads the same query's rows as r.package_id (~2588, ~2606).
So record.packageId is always undefined and the || 'sys_metadata' fallback always wins: every object overlay row — including rows genuinely bound to a package (package_id = 'app.<slug>' etc.) — registers into the SchemaRegistry under the 'sys_metadata' sentinel sourcePackage at boot, silently dropping its package binding.
Why it matters
The cloud#970 fix comment right above this line documents the intent: pass the row's real package id but stamp _provenance: 'org' so the tenant-authored row is not misread as code-shipped. Half of that intent is dead: the provenance stamp works, the package binding never arrives. Consequences of registering under the sentinel instead of the real package id include the sidebar package filter / provenance classification not seeing the boot-hydrated object as belonging to its package (the same concern the read-side hydration explicitly handles by surfacing record.package_id, ~2596-2609), and registry.getObject-side package bookkeeping diverging between "created this session" (write path, real id) and "restarted" (boot path, sentinel).
Suggested fix
Read (record as { package_id?: string | null }).package_id || 'sys_metadata' — matching every other consumer of this query's rows. Needs a pin test (boot-hydrate an object row with package_id set; assert the registry records the real package binding, and that cloud#970's _provenance: 'org' + editability still hold). Check registerObject's package bookkeeping for whether the sentinel-vs-real-id switch has any other observable effects before landing (i.e. confirm this does not resurrect the cloud#970 not_overridable trap — the _provenance: 'org' stamp is what guards it now).
Not fixed in #4635 because it is the object branch (out of that issue's scope) and changes boot-time registry state for object rows — it deserves its own pin test and review.
Found while implementing #4624 (PR #4635). Unassigned — nobody is on this. Recording only, per Prime Directive #10.
Evidence
loadMetaFromDb's object branch (packages/metadata-protocol/src/protocol.ts, ~line 8958 on currentmain) registers each hydrated object row with:But
engine.find('sys_metadata', ...)returns rows keyed by the object's snake_case field names —package_id, notpackageId:sys_metadataobject declarespackage_id(packages/metadata-core/src/objects/sys-metadata.object.ts);SysMetadataRepositorywritesparentRowData.package_id = ...(sys-metadata-repository.ts~386-388) and mapsrow.package_id → packageIdexplicitly when it wants camelCase (~784);getMetaItemsin the same file reads the same query's rows asr.package_id(~2588, ~2606).So
record.packageIdis alwaysundefinedand the|| 'sys_metadata'fallback always wins: every object overlay row — including rows genuinely bound to a package (package_id = 'app.<slug>'etc.) — registers into the SchemaRegistry under the'sys_metadata'sentinelsourcePackageat boot, silently dropping its package binding.Why it matters
The cloud#970 fix comment right above this line documents the intent: pass the row's real package id but stamp
_provenance: 'org'so the tenant-authored row is not misread as code-shipped. Half of that intent is dead: the provenance stamp works, the package binding never arrives. Consequences of registering under the sentinel instead of the real package id include the sidebar package filter / provenance classification not seeing the boot-hydrated object as belonging to its package (the same concern the read-side hydration explicitly handles by surfacingrecord.package_id, ~2596-2609), andregistry.getObject-side package bookkeeping diverging between "created this session" (write path, real id) and "restarted" (boot path, sentinel).Suggested fix
Read
(record as { package_id?: string | null }).package_id || 'sys_metadata'— matching every other consumer of this query's rows. Needs a pin test (boot-hydrate an object row withpackage_idset; assert the registry records the real package binding, and that cloud#970's_provenance: 'org'+ editability still hold). CheckregisterObject's package bookkeeping for whether the sentinel-vs-real-id switch has any other observable effects before landing (i.e. confirm this does not resurrect the cloud#970not_overridabletrap — the_provenance: 'org'stamp is what guards it now).Not fixed in #4635 because it is the object branch (out of that issue's scope) and changes boot-time registry state for object rows — it deserves its own pin test and review.