@@ -263,7 +263,8 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
263263 // entries (the previous fallback-only logic meant project metadata
264264 // was never surfaced whenever system-bridged items populated the
265265 // registry). Deduplicate against whatever the registry returned.
266- try {
266+ // Skip on project kernels — sys_metadata is control-plane only.
267+ if ( this . environmentId === undefined ) try {
267268 const whereClause : Record < string , unknown > = {
268269 type : request . type ,
269270 state : 'active' ,
@@ -367,8 +368,10 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
367368 }
368369 }
369370
370- // Fallback to database if not in registry
371- if ( item === undefined ) {
371+ // Fallback to database if not in registry.
372+ // Skip on project kernels — sys_metadata is control-plane only;
373+ // project kernels source metadata from the artifact via MetadataService below.
374+ if ( item === undefined && this . environmentId === undefined ) {
372375 try {
373376 const scopedWhere : Record < string , unknown > = {
374377 type : request . type ,
@@ -1085,6 +1088,26 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
10851088 throw new Error ( 'Item data is required' ) ;
10861089 }
10871090
1091+ // Project kernels (environmentId set) never persist to sys_metadata
1092+ // locally — runtime metadata is sourced from the artifact and writes
1093+ // belong to the control plane. Update the in-memory registry only.
1094+ if ( this . environmentId !== undefined ) {
1095+ this . engine . registry . registerItem ( request . type , request . item , 'name' ) ;
1096+ if ( request . type === 'object' || request . type === 'objects' ) {
1097+ try {
1098+ this . engine . registry . registerObject ( request . item as any , 'sys_metadata' ) ;
1099+ } catch ( err : any ) {
1100+ console . warn (
1101+ `[Protocol] registerObject failed for ${ request . name } : ${ err ?. message ?? err } ` ,
1102+ ) ;
1103+ }
1104+ }
1105+ return {
1106+ success : true ,
1107+ message : 'Saved to memory registry (project kernel — sys_metadata is control-plane only)' ,
1108+ } ;
1109+ }
1110+
10881111 // 1. Always update the in-memory registry (runtime cache).
10891112 // For `type === 'object'` we additionally register in the
10901113 // dedicated objects map so that downstream calls (e.g.
@@ -1176,6 +1199,12 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
11761199 * Safe to call repeatedly — idempotent (latest DB record wins).
11771200 */
11781201 async loadMetaFromDb ( ) : Promise < { loaded : number ; errors : number } > {
1202+ // Project kernels never read sys_metadata locally — the table only
1203+ // exists on the control plane. Metadata is sourced from the artifact
1204+ // (MetadataPlugin) or routed via ControlPlaneProxyDriver.
1205+ if ( this . environmentId !== undefined ) {
1206+ return { loaded : 0 , errors : 0 } ;
1207+ }
11791208 let loaded = 0 ;
11801209 let errors = 0 ;
11811210 try {
0 commit comments