Repository navigation
Per-task runtime policy and workspace options for delegated children (provider-agnostic) #20425
forge-zephyr
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
We run one orchestrator thread that delegates 10–20 concurrent child agents into separate git worktrees: building, testing, committing, pushing and opening PRs. Today we do this outside T3 with our own launcher, because
delegate_taskcan't give a child what it needs to finish real repository work. We'd much rather usedelegate_taskand keep T3's task tracking, notifications, cancellation and PR linking.Reading the source (543af77) shows most of the building blocks already exist; they just aren't exposed per task. This request is framed around T3's own provider-neutral concepts so it works for every harness, not just Codex.
What exists today
delegate_taskper task: target/model/options,runtimeMode(narrow only),interactionMode,isolation: shared|worktree. Worktrees always start at the parent's HEAD with a generated branch, in the parent's project.t3_thread_launchalready hasworkspaceStrategy(worktree{baseRef, branch, startFromOrigin},existing_worktree,root) andprojectId, and uses the sameThreadLaunchService.prepareRun.RuntimePolicyalready carriessandboxPolicy/approvalPolicyoverrides honoured by the Codex and Claude adapters (RuntimePolicy.ts:33-38), but onlylayerWithOverride, used in tests, can set them.runOnWorktreeCreateandrunOnSettlerun on the host, outside any agent sandbox.environment[]andbinaryPath.Observed behaviour (probe child via
delegate_task, codex gpt-6.1-sol, runtimeModeauto, isolationshared)workspace-write, writable root = project root.gitand linked-worktree gitdirsgit commitworks)TMPDIR,/tmpRead-only file system~/.cargo)Read-only file systemCODEX_SANDBOX_NETWORK_DISABLEDset;Could not resolve host: github.com;git pushandghfailCARGO_TARGET_DIR; no per-task overrideSo a delegated child can edit, build and commit, but cannot push or open a PR, and cannot use an out-of-tree build cache.
Requests
1.
delegate_taskworkspace parity witht3_thread_launchAccept the same
workspaceStrategy(base ref, branch name, existing worktree for follow-up rounds) and aprojectId, so a child can target a sibling repository or continue its own earlier work. The machinery is already shared, so this is mostly exposing it.2. Expose the provider-neutral runtime policy per task, and extend it
Make
RuntimePolicysettable per task (within the parent's ceiling, likeruntimeModetoday), and add two provider-neutral fields every adapter maps to its own mechanism:writableRoots: string[]: extra directories the child may write outside its worktree. Real cases: out-of-tree build caches and the package cache (both read-only today, observed above), and the git metadata of a repository outside the project root when the child targets a sibling repo (request 1). Codex maps tosandbox_workspace_write.writable_roots; Claude toadditionalDirectories(currently hard-coded to cwd plus attachments,ClaudeAdapterV2.ts:1165-1170); other adapters to their own permission rules.network: boolean: needed forgit pushandgh. Codex maps toworkspaceWrite.networkAccess; others to their equivalent, or a documented no-op where the harness has no network sandbox.An admin-level allowlist for
writableRoots(per project or instance) would keep this safe.3. Per-task environment for the commands the child runs
setandunsetmaps, with{taskId}/{worktreePath}templating, e.g. a per-taskCARGO_TARGET_DIRand compiler-cache port. Unset matters: a shell rc exportingCARGO_TARGET_DIRsilently overrode per-worktree config for every child. Codex threads share one app-server process, so this can't be process env; for Codex it would go through the thread's shell-environment policy, and other adapters would use their own per-session mechanism.4. Lifecycle hooks with task context
Let project scripts receive the task's id, worktree path and resolved policy (env), and add a post-exit hook (or extend
runOnSettle). Our cases: a dependency prefetch, because agent sandboxes often mount the package cache read-only; creating the per-task cache directory; and starting a per-task compiler-cache server on the host, because a server spawned inside a sandboxed command dies with that command. Post-exit stops and cleans these up.5. Launch pacing for batches
An optional concurrency limit or start stagger for delegated children. We've seen several Codex children started together fail together on auth token refresh.
Two probable bugs, found while reading
providerInstances.codex.config.launchArgs = "-c sandbox_workspace_write.network_access=true", then restarted the codex app-server. It respawned ascodex -c features.code_mode_host=true app-server --listen unix://, without the configured args, and a fresh delegated child still hadCODEX_SANDBOX_NETWORK_DISABLED=1and no DNS. Separately, the per-turn sandbox is sent as{type:"workspaceWrite"}withoutnetworkAccess(CodexAdapterV2.ts:674-713), which would override such a flag even if it arrived.delegate_taskdocuments it, but setup scripts default toasync(ProjectSetupScriptRunner.ts:442), and the run is released before they finish (ThreadLaunchService.ts:625-664).Happy to test a build against a 20-child Rust workload.
All reactions