@@ -2806,4 +2806,35 @@ describe("sub-agent identity on permission requests", () => {
28062806 expect ( withA ?. agentLabel ) . toBe ( "Worker A" ) ;
28072807 expect ( withoutLabel ?. agentLabel ) . toBeUndefined ( ) ;
28082808 } ) ;
2809+
2810+ test ( "two concurrent ALS scopes keep their agent labels isolated" , async ( ) => {
2811+ const { runWithSubAgentIdentity } = await import ( "../subagent/identity-context.js" ) ;
2812+ const seen : PermissionRequest [ ] = [ ] ;
2813+ const gate = createPermissionGate ( {
2814+ approvals : [ ] ,
2815+ requestApproval : async ( request ) => {
2816+ seen . push ( request ) ;
2817+ // Hold both approvals open so the two scopes truly overlap.
2818+ await new Promise ( ( r ) => setTimeout ( r , 5 ) ) ;
2819+ return { allow : true } ;
2820+ } ,
2821+ interactive : true ,
2822+ skipPermissions : false ,
2823+ cwd : "/repo" ,
2824+ } ) ;
2825+ await Promise . all ( [
2826+ runWithSubAgentIdentity ( { description : "Worker A" , cwd : "/repo-a" } , ( ) =>
2827+ gate . evaluate ( shellCall ( "npm run a" ) ) ,
2828+ ) ,
2829+ runWithSubAgentIdentity ( { description : "Worker B" , cwd : "/repo-b" } , ( ) =>
2830+ gate . evaluate ( shellCall ( "npm run b" ) ) ,
2831+ ) ,
2832+ ] ) ;
2833+ const withA = seen . find ( ( r ) => r . subject === "npm run a" ) ;
2834+ const withB = seen . find ( ( r ) => r . subject === "npm run b" ) ;
2835+ expect ( withA ?. agentLabel ) . toBe ( "Worker A" ) ;
2836+ expect ( withA ?. cwd ) . toBe ( "/repo-a" ) ;
2837+ expect ( withB ?. agentLabel ) . toBe ( "Worker B" ) ;
2838+ expect ( withB ?. cwd ) . toBe ( "/repo-b" ) ;
2839+ } ) ;
28092840} ) ;
0 commit comments