@@ -1698,10 +1698,12 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
16981698 const services = this . getServicesRegistry ?.( ) ;
16991699 const metadataService = services ?. get ( 'metadata' ) ;
17001700 if ( metadataService && typeof metadataService . get === 'function' ) {
1701- let fromService = await metadataService . get ( request . type , request . name ) ;
1701+ // ADR-0048 — package-scope the code layer so a same-name
1702+ // collision resolves to the requested package's artifact.
1703+ let fromService = await metadataService . get ( request . type , request . name , request . packageId ) ;
17021704 if ( fromService === undefined || fromService === null ) {
17031705 const alt = PLURAL_TO_SINGULAR [ request . type ] ?? SINGULAR_TO_PLURAL [ request . type ] ;
1704- if ( alt ) fromService = await metadataService . get ( alt , request . name ) ;
1706+ if ( alt ) fromService = await metadataService . get ( alt , request . name , request . packageId ) ;
17051707 }
17061708 if ( fromService !== undefined && fromService !== null ) code = fromService ;
17071709 }
@@ -1712,11 +1714,11 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
17121714 // Prefer the artifact-only lookup so an overlay row hydrated
17131715 // into the registry's plain key can't masquerade as the "code
17141716 // default" layer; fall back to getItem for runtime-only items.
1715- let regItem = this . lookupArtifactItem ( request . type , request . name )
1716- ?? this . engine . registry . getItem ( request . type , request . name ) ;
1717+ let regItem = this . lookupArtifactItem ( request . type , request . name , request . packageId )
1718+ ?? this . engine . registry . getItem ( request . type , request . name , request . packageId ) ;
17171719 if ( regItem === undefined ) {
17181720 const alt = PLURAL_TO_SINGULAR [ request . type ] ?? SINGULAR_TO_PLURAL [ request . type ] ;
1719- if ( alt ) regItem = this . engine . registry . getItem ( alt , request . name ) ;
1721+ if ( alt ) regItem = this . engine . registry . getItem ( alt , request . name , request . packageId ) ;
17201722 }
17211723 if ( regItem !== undefined ) code = regItem ;
17221724 }
@@ -1726,20 +1728,24 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
17261728 let overlayScope : 'org' | 'env' | null = null ;
17271729 try {
17281730 const findOverlay = async ( oid : string | null ) => {
1729- const where : Record < string , unknown > = {
1730- type : request . type ,
1731- name : request . name ,
1732- state : 'active' ,
1733- organization_id : oid ,
1731+ // ADR-0048 prefer-local: when a package is supplied, the row
1732+ // owned by that package wins over a package-less first match.
1733+ const lookup = async ( t : string ) => {
1734+ const base : Record < string , unknown > = {
1735+ type : t , name : request . name , state : 'active' , organization_id : oid ,
1736+ } ;
1737+ if ( request . packageId ) {
1738+ const scoped = await this . engine . findOne ( 'sys_metadata' , {
1739+ where : { ...base , package_id : request . packageId } ,
1740+ } ) ;
1741+ if ( scoped ) return scoped ;
1742+ }
1743+ return await this . engine . findOne ( 'sys_metadata' , { where : base } ) ;
17341744 } ;
1735- let rec = await this . engine . findOne ( 'sys_metadata' , { where } ) ;
1745+ let rec = await lookup ( request . type ) ;
17361746 if ( ! rec ) {
17371747 const alt = PLURAL_TO_SINGULAR [ request . type ] ?? SINGULAR_TO_PLURAL [ request . type ] ;
1738- if ( alt ) {
1739- rec = await this . engine . findOne ( 'sys_metadata' , {
1740- where : { ...where , type : alt } ,
1741- } ) ;
1742- }
1748+ if ( alt ) rec = await lookup ( alt ) ;
17431749 }
17441750 return rec ;
17451751 } ;
@@ -3143,7 +3149,7 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
31433149 * type and its singular/plural twin. Returns `undefined` when the
31443150 * registry is unavailable or the item is not artifact-backed.
31453151 */
3146- private lookupArtifactItem ( type : string , name : string ) : unknown {
3152+ private lookupArtifactItem ( type : string , name : string , currentPackageId ?: string ) : unknown {
31473153 const registry = ( this . engine as any ) ?. registry ;
31483154 if ( ! registry ) return undefined ;
31493155 const singular = PLURAL_TO_SINGULAR [ type ] ?? type ;
@@ -3152,15 +3158,16 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
31523158 // into the plain key (getMetaItems / loadMetaFromDb) can never
31533159 // shadow the packaged artifact's protection envelope (ADR-0010
31543160 // §3.3 — pre-fix, that shadow made a `_lock: full` app read back
3155- // as unlocked after PUT+GET until restart).
3161+ // as unlocked after PUT+GET until restart). `currentPackageId`
3162+ // (ADR-0048) makes that scan package-scoped (prefer-local).
31563163 if ( typeof registry . getArtifactItem === 'function' ) {
3157- return registry . getArtifactItem ( singular , name )
3158- ?? registry . getArtifactItem ( type , name ) ;
3164+ return registry . getArtifactItem ( singular , name , currentPackageId )
3165+ ?? registry . getArtifactItem ( type , name , currentPackageId ) ;
31593166 }
31603167 // Partial registry mocks in tests — fall back to getItem and apply
31613168 // the same package-provenance filter inline.
31623169 if ( typeof registry . getItem !== 'function' ) return undefined ;
3163- const item = registry . getItem ( singular , name ) ?? registry . getItem ( type , name ) ;
3170+ const item = registry . getItem ( singular , name , currentPackageId ) ?? registry . getItem ( type , name , currentPackageId ) ;
31643171 if ( ! item || ! ( item as any ) . _packageId || ( item as any ) . _packageId === 'sys_metadata' ) {
31653172 return undefined ;
31663173 }
0 commit comments