@@ -11,6 +11,7 @@ import { tmpdir } from "node:os";
1111import { mkdtemp } from "node:fs/promises" ;
1212import { join } from "node:path" ;
1313
14+ import { withMockedModuleDuring } from "../../tests/helpers/mock-module.js" ;
1415import { createPermissionGate } from "../permission/gate.js" ;
1516import { FleetAuthorityError } from "./authority.js" ;
1617import { runSubAgent } from "./run.js" ;
@@ -81,3 +82,88 @@ describe("runSubAgent fleet-verb mount gate (CL-6941, fails closed)", () => {
8182 }
8283 } ) ;
8384} ) ;
85+
86+ describe ( "runSubAgent search_agents mount gate (CL-7051, Tier-1 only)" , ( ) => {
87+ test ( "nested-orchestrator does not mount search_agents even when profiles exist" , async ( ) => {
88+ const cwd = await tmpCwd ( ) ;
89+ let searchAgentsMounts = 0 ;
90+
91+ await withMockedModuleDuring (
92+ import . meta. resolve ( "../agent/agent-search.js" ) ,
93+ ( real : typeof import ( "../agent/agent-search.js" ) ) => ( {
94+ ...real ,
95+ createSearchAgentsTool : ( getProfiles : ( ) => never ) => {
96+ searchAgentsMounts ++ ;
97+ return real . createSearchAgentsTool ( getProfiles ) ;
98+ } ,
99+ } ) ,
100+ async ( ) => {
101+ // Re-import so the mock is visible to runSubAgent's binding.
102+ const { runSubAgent : run } = await import ( "./run.js" ) ;
103+ try {
104+ await run ( {
105+ ...baseParams ( cwd , join ( cwd , ".ctx" ) ) ,
106+ id : "greybeard-session" ,
107+ orchestrator : true ,
108+ orchestratorTier : "nested-orchestrator" ,
109+ nestedDispatch : {
110+ permissionGate : testPermissionGate ,
111+ getWorkdirBase : ( ) => join ( cwd , ".ctx" ) ,
112+ provider : {
113+ providerName : "test" ,
114+ baseURL : "http://localhost" ,
115+ model : "test-model" ,
116+ } ,
117+ profiles : [ { id : "intern" , systemPromptRole : "You are intern." } ] ,
118+ } ,
119+ } ) ;
120+ } catch {
121+ // Inference/agent construction may fail; mount decisions run first.
122+ }
123+ } ,
124+ ) ;
125+
126+ expect ( searchAgentsMounts ) . toBe ( 0 ) ;
127+ } ) ;
128+
129+ test ( "Tier-1 orchestrator mounts search_agents when profiles exist" , async ( ) => {
130+ const cwd = await tmpCwd ( ) ;
131+ let searchAgentsMounts = 0 ;
132+
133+ await withMockedModuleDuring (
134+ import . meta. resolve ( "../agent/agent-search.js" ) ,
135+ ( real : typeof import ( "../agent/agent-search.js" ) ) => ( {
136+ ...real ,
137+ createSearchAgentsTool : ( getProfiles : ( ) => never ) => {
138+ searchAgentsMounts ++ ;
139+ return real . createSearchAgentsTool ( getProfiles ) ;
140+ } ,
141+ } ) ,
142+ async ( ) => {
143+ const { runSubAgent : run } = await import ( "./run.js" ) ;
144+ try {
145+ await run ( {
146+ ...baseParams ( cwd , join ( cwd , ".ctx" ) ) ,
147+ id : "skywalker-session" ,
148+ orchestrator : true ,
149+ orchestratorTier : "orchestrator" ,
150+ nestedDispatch : {
151+ permissionGate : testPermissionGate ,
152+ getWorkdirBase : ( ) => join ( cwd , ".ctx" ) ,
153+ provider : {
154+ providerName : "test" ,
155+ baseURL : "http://localhost" ,
156+ model : "test-model" ,
157+ } ,
158+ profiles : [ { id : "intern" , systemPromptRole : "You are intern." } ] ,
159+ } ,
160+ } ) ;
161+ } catch {
162+ // Inference/agent construction may fail; mount decisions run first.
163+ }
164+ } ,
165+ ) ;
166+
167+ expect ( searchAgentsMounts ) . toBe ( 1 ) ;
168+ } ) ;
169+ } ) ;
0 commit comments