@@ -90,6 +90,27 @@ describe("drift-aware refresh", () => {
9090
9191 expect ( state . getResource ( { type : "agent" , name : "assistant" , provider : "qoder" } ) ) . toBeDefined ( ) ;
9292 } ) ;
93+
94+ test ( "passes the declared resource to comparable reads" , async ( ) => {
95+ const state = StateManager . initialize ( tmpPath ( ) ) ;
96+ state . setResource ( {
97+ address : { type : "agent" , name : "assistant" , provider : "qoder" } ,
98+ remote_id : "agent_1" ,
99+ content_hash : "h" ,
100+ desired_hash : "h" ,
101+ } ) ;
102+ const provider = fakeProvider ( config . agents ! . assistant ! ) ;
103+ const readComparableResource = provider . readComparableResource ! ;
104+ let receivedDeclaration : unknown ;
105+ provider . readComparableResource = async ( type , id , name , declaration ) => {
106+ receivedDeclaration = declaration ;
107+ return readComparableResource ( type , id , name , declaration ) ;
108+ } ;
109+
110+ await refreshState ( state , new Map ( [ [ "qoder" , provider ] ] ) , { config } ) ;
111+
112+ expect ( receivedDeclaration ) . toEqual ( config . agents ! . assistant ! ) ;
113+ } ) ;
93114} ) ;
94115
95116describe ( "Qoder comparable fixtures" , ( ) => {
@@ -144,6 +165,24 @@ describe("Qoder comparable fixtures", () => {
144165 expect ( changed ) . not . toEqual ( desired ) ;
145166 expect ( removed ) . not . toEqual ( matching ) ;
146167 } ) ;
168+
169+ test ( "treats an empty Agent description as omitted while preserving non-empty description drift" , ( ) => {
170+ const adapter = new QoderAdapter ( "pt-test" , undefined , "tmp" ) as any ;
171+ const desired = adapter . normalizeDesiredResource ( "agent" , "assistant" , {
172+ model : "auto" ,
173+ instructions : "Reply only with the marker." ,
174+ } ) ;
175+ const remote = {
176+ name : "assistant" ,
177+ model : "auto" ,
178+ system : "Reply only with the marker." ,
179+ tools : [ { type : "agent_toolset_20260401" } ] ,
180+ metadata : { "agents.project" : "tmp" , "agents.resource" : "assistant" } ,
181+ } ;
182+
183+ expect ( adapter . normalizeRemote ( "agent" , { ...remote , description : "" } ) ) . toEqual ( desired ) ;
184+ expect ( adapter . normalizeRemote ( "agent" , { ...remote , description : "remote description" } ) ) . not . toEqual ( desired ) ;
185+ } ) ;
147186} ) ;
148187
149188describe ( "planner drift classification" , ( ) => {
@@ -300,3 +339,79 @@ describe("Qoder archived resources are treated as gone", () => {
300339 expect ( ( await adapter . findResource ( "agent" , "a" ) ) ?. id ) . toBe ( "agent_active" ) ;
301340 } ) ;
302341} ) ;
342+
343+ describe ( "Qoder managed comparable identity" , ( ) => {
344+ const declaration = { name : "display-name" , model : "auto" , instructions : "test" } ;
345+ const identity = {
346+ id : "agent_1" ,
347+ type : "agent" ,
348+ name : "display-name" ,
349+ metadata : { "agents.project" : "tmp" , "agents.resource" : "display-name" } ,
350+ model : "auto" ,
351+ system : "test" ,
352+ } ;
353+
354+ test ( "accepts a matching detail resource when the logical key differs from its display name" , async ( ) => {
355+ const adapter = new QoderAdapter ( "pt-test" , undefined , "tmp" ) as any ;
356+ adapter . client = {
357+ get : async ( path : string ) => {
358+ expect ( path ) . toBe ( "/agents/agent_1" ) ;
359+ return identity ;
360+ } ,
361+ } ;
362+
363+ const remote = await adapter . readComparableResource ( "agent" , "agent_1" , "logical-key" , declaration ) ;
364+
365+ expect ( remote ?. id ) . toBe ( "agent_1" ) ;
366+ } ) ;
367+
368+ test ( "rejects an ID detail response whose type or managed metadata is not the declared identity" , async ( ) => {
369+ const adapter = new QoderAdapter ( "pt-test" , undefined , "tmp" ) as any ;
370+ adapter . client = {
371+ get : async ( ) => ( {
372+ ...identity ,
373+ type : "environment" ,
374+ metadata : { "agents.project" : "tmp" , "agents.resource" : "other" } ,
375+ } ) ,
376+ } ;
377+
378+ expect ( await adapter . readComparableResource ( "agent" , "agent_1" , "logical-key" , declaration ) ) . toBeNull ( ) ;
379+ } ) ;
380+
381+ test ( "claims only one full-identity match from paginated discovery and verifies its detail" , async ( ) => {
382+ const calls : string [ ] = [ ] ;
383+ const adapter = new QoderAdapter ( "pt-test" , undefined , "tmp" ) as any ;
384+ adapter . client = {
385+ getAllPaged : async ( path : string ) => {
386+ calls . push ( path ) ;
387+ return [ { ...identity , id : "agent_1" } ] ;
388+ } ,
389+ get : async ( path : string ) => {
390+ calls . push ( path ) ;
391+ return identity ;
392+ } ,
393+ } ;
394+
395+ const remote = await adapter . readComparableResource ( "agent" , null , "logical-key" , declaration ) ;
396+
397+ expect ( remote ?. id ) . toBe ( "agent_1" ) ;
398+ expect ( calls ) . toEqual ( [ "/agents" , "/agents/agent_1" ] ) ;
399+ } ) ;
400+
401+ test ( "fails closed for zero or multiple full-identity matches" , async ( ) => {
402+ for ( const candidates of [ [ ] , [ { ...identity } , { ...identity , id : "agent_2" } ] ] ) {
403+ const adapter = new QoderAdapter ( "pt-test" , undefined , "tmp" ) as any ;
404+ let detailRead = false ;
405+ adapter . client = {
406+ getAllPaged : async ( ) => candidates ,
407+ get : async ( ) => {
408+ detailRead = true ;
409+ return identity ;
410+ } ,
411+ } ;
412+
413+ expect ( await adapter . readComparableResource ( "agent" , null , "logical-key" , declaration ) ) . toBeNull ( ) ;
414+ expect ( detailRead ) . toBe ( false ) ;
415+ }
416+ } ) ;
417+ } ) ;
0 commit comments