feat(orchestrator): allow read-only codebase exploration
- commit
- 70aca248489fe3308081d8d2489503ef7a557350
- author
- brice · · 2026-08-13 07:27 UTC
- committer
- brice · · 2026-08-19 04:49 UTC
- parent
- 0b52359
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +14 -2
M packages/agent/build.go +9 -0
| @@ -1254,6 +1254,9 @@ func buildToolRegistry(args Args, cwd string, sandbox *tools.Sandbox, lspEnabled | |||
| 1254 | 1254 | reg[name] = t | |
| 1255 | 1255 | } | |
| 1256 | 1256 | } | |
| 1257 | + | if orchestratorReadToolAllowed(args) { | |
| 1258 | + | reg["read"] = all["read"] | |
| 1259 | + | } | |
| 1257 | 1260 | return reg | |
| 1258 | 1261 | } | |
| 1259 | 1262 | ||
| @@ -1282,6 +1285,12 @@ func autoSubagentsToolAllowed(args Args) bool { | |||
| 1282 | 1285 | return autoSubagentsToolAllowedFor(args, "subagent_spawn") | |
| 1283 | 1286 | } | |
| 1284 | 1287 | ||
| 1288 | + | // orchestratorReadToolAllowed keeps read-only codebase exploration available | |
| 1289 | + | // to the primary orchestrator without widening its launch-time tool policy. | |
| 1290 | + | func orchestratorReadToolAllowed(args Args) bool { | |
| 1291 | + | return args.Orchestrate && !args.NoTools | |
| 1292 | + | } | |
| 1293 | + | ||
| 1285 | 1294 | func autoSubagentsStatusToolAllowed(args Args) bool { | |
| 1286 | 1295 | return autoSubagentsToolAllowedFor(args, "subagent_status") | |
| 1287 | 1296 | } | |
| @@ -1254,6 +1254,9 @@ func buildToolRegistry(args Args, cwd string, sandbox *tools.Sandbox, lspEnabled | |||||
| 1254 | reg[name] = t | 1254 | reg[name] = t | ||
| 1255 | } | 1255 | } | ||
| 1256 | } | 1256 | } | ||
| 1257 | + | if orchestratorReadToolAllowed(args) { | |||
| 1258 | + | reg["read"] = all["read"] | |||
| 1259 | + | } | |||
| 1257 | return reg | 1260 | return reg | ||
| 1258 | } | 1261 | } | ||
| 1259 | 1262 | ||||
| @@ -1282,6 +1285,12 @@ func autoSubagentsToolAllowed(args Args) bool { | |||||
| 1282 | return autoSubagentsToolAllowedFor(args, "subagent_spawn") | 1285 | return autoSubagentsToolAllowedFor(args, "subagent_spawn") | ||
| 1283 | } | 1286 | } | ||
| 1284 | 1287 | ||||
| 1288 | + | // orchestratorReadToolAllowed keeps read-only codebase exploration available | |||
| 1289 | + | // to the primary orchestrator without widening its launch-time tool policy. | |||
| 1290 | + | func orchestratorReadToolAllowed(args Args) bool { | |||
| 1291 | + | return args.Orchestrate && !args.NoTools | |||
| 1292 | + | } | |||
| 1293 | + | ||||
| 1285 | func autoSubagentsStatusToolAllowed(args Args) bool { | 1294 | func autoSubagentsStatusToolAllowed(args Args) bool { | ||
| 1286 | return autoSubagentsToolAllowedFor(args, "subagent_status") | 1295 | return autoSubagentsToolAllowedFor(args, "subagent_status") | ||
| 1287 | } | 1296 | } | ||
M packages/agent/settings_store.go +5 -2
| @@ -254,9 +254,12 @@ func AutoSubagentsEnabled() bool { | |||
| 254 | 254 | // orchestrator. | |
| 255 | 255 | const AutoSubagentsSystemAddendum = `Auto-subagents are enabled. You are the primary-agent orchestrator, not an implementer. | |
| 256 | 256 | ||
| 257 | - | Delegate all implementation, debugging/testing, and code-review work to an appropriately named subagent profile, or to a clearly described general worker when no profile fits. Do not write or edit code yourself, make direct implementation tool calls, inspect or review code, or apply worker patches. You may decompose the request, select and spawn workers, check their status, coordinate follow-ups, and synthesize their results. | |
| 257 | + | - Use the read tool only for read-only codebase exploration before dispatching work. | |
| 258 | + | - Delegate all implementation, debugging/testing, and code-review work to an appropriately named subagent profile or a clearly described general worker. | |
| 259 | + | - Do not write or edit code yourself, make direct implementation tool calls, inspect or review code, or apply worker patches. You may review worker reports, but use the read tool only for read-only codebase exploration before dispatching work. | |
| 260 | + | - Give every worker a self-contained task and synthesize the results. | |
| 258 | 261 | ||
| 259 | - | Give every worker a self-contained task because workers start without this conversation's context. Shared-worktree workers edit the same working directory, so coordinate dependent work and avoid conflicting edits. Use isolation:"worktree" for parallel coding when workers need separate trees; its changes are returned as a patch for a worker to integrate, not for you to apply. Do not invent feature scope beyond the user's request. Child workers cannot recursively spawn more sub-agents in v1. | |
| 262 | + | Workers start without this conversation's context. Shared-worktree workers edit the same working directory, so coordinate dependent work and avoid conflicting edits. Use isolation:"worktree" for parallel coding when workers need separate trees; its changes are returned as a patch for a worker to integrate, not for you to apply. Do not invent feature scope beyond the user's request. Child workers cannot recursively spawn more sub-agents in v1. | |
| 260 | 263 | ||
| 261 | 264 | Use required:true whenever your answer or a declared workflow depends on that worker, especially for required validation or finalization. Required workers remain asynchronous unless you explicitly set subagent_spawn's wait field: without it, manager calls return immediately, the parent stays free to coordinate or perform independent work, and the host delivers terminal outcomes through completion updates. Failed, canceled, or interrupted required work remains unmet: use an enabled manager follow-up action to retry it and do not claim completion. An indeterminate outcome after host restart must not be retried automatically; the user must inspect durable results and side effects, then explicitly resume, restart, or remove the worker. Only the user can waive required work by explicitly removing the terminal worker with /subagents rm. Keep required:false only for independent work that may safely finish later. | |
| 262 | 265 | ||
| @@ -254,9 +254,12 @@ func AutoSubagentsEnabled() bool { | |||||
| 254 | // orchestrator. | 254 | // orchestrator. | ||
| 255 | const AutoSubagentsSystemAddendum = `Auto-subagents are enabled. You are the primary-agent orchestrator, not an implementer. | 255 | const AutoSubagentsSystemAddendum = `Auto-subagents are enabled. You are the primary-agent orchestrator, not an implementer. | ||
| 256 | 256 | ||||
| 257 | - | Delegate all implementation, debugging/testing, and code-review work to an appropriately named subagent profile, or to a clearly described general worker when no profile fits. Do not write or edit code yourself, make direct implementation tool calls, inspect or review code, or apply worker patches. You may decompose the request, select and spawn workers, check their status, coordinate follow-ups, and synthesize their results. | 257 | + | - Use the read tool only for read-only codebase exploration before dispatching work. |
| 258 | + | - Delegate all implementation, debugging/testing, and code-review work to an appropriately named subagent profile or a clearly described general worker. | |||
| 259 | + | - Do not write or edit code yourself, make direct implementation tool calls, inspect or review code, or apply worker patches. You may review worker reports, but use the read tool only for read-only codebase exploration before dispatching work. | |||
| 260 | + | - Give every worker a self-contained task and synthesize the results. | |||
| 258 | 261 | ||||
| 259 | - | Give every worker a self-contained task because workers start without this conversation's context. Shared-worktree workers edit the same working directory, so coordinate dependent work and avoid conflicting edits. Use isolation:"worktree" for parallel coding when workers need separate trees; its changes are returned as a patch for a worker to integrate, not for you to apply. Do not invent feature scope beyond the user's request. Child workers cannot recursively spawn more sub-agents in v1. | 262 | + | Workers start without this conversation's context. Shared-worktree workers edit the same working directory, so coordinate dependent work and avoid conflicting edits. Use isolation:"worktree" for parallel coding when workers need separate trees; its changes are returned as a patch for a worker to integrate, not for you to apply. Do not invent feature scope beyond the user's request. Child workers cannot recursively spawn more sub-agents in v1. |
| 260 | 263 | ||||
| 261 | Use required:true whenever your answer or a declared workflow depends on that worker, especially for required validation or finalization. Required workers remain asynchronous unless you explicitly set subagent_spawn's wait field: without it, manager calls return immediately, the parent stays free to coordinate or perform independent work, and the host delivers terminal outcomes through completion updates. Failed, canceled, or interrupted required work remains unmet: use an enabled manager follow-up action to retry it and do not claim completion. An indeterminate outcome after host restart must not be retried automatically; the user must inspect durable results and side effects, then explicitly resume, restart, or remove the worker. Only the user can waive required work by explicitly removing the terminal worker with /subagents rm. Keep required:false only for independent work that may safely finish later. | 264 | Use required:true whenever your answer or a declared workflow depends on that worker, especially for required validation or finalization. Required workers remain asynchronous unless you explicitly set subagent_spawn's wait field: without it, manager calls return immediately, the parent stays free to coordinate or perform independent work, and the host delivers terminal outcomes through completion updates. Failed, canceled, or interrupted required work remains unmet: use an enabled manager follow-up action to retry it and do not claim completion. An indeterminate outcome after host restart must not be retried automatically; the user must inspect durable results and side effects, then explicitly resume, restart, or remove the worker. Only the user can waive required work by explicitly removing the terminal worker with /subagents rm. Keep required:false only for independent work that may safely finish later. | ||
| 262 | 265 | ||||