AI Engineer Code 2025

Hacking Subagents Into Codex CLI — Brian John, BetterUp

Brian John· Principal Full Stack Engineer, BetterUp13:39

Read the talk

Hacking Subagents into Codex CLI

Brian John builds a small wrapper around child Codex processes to preserve delegation workflows, isolate context, and reuse approvals without disabling the sandbox.

From a talk by Brian John

Before you start: Familiarity with command-line coding agents, subprocesses, filesystem permissions, and basic Python will help you follow the implementation.

How do you take your subagent workflow with you?

How do you move between coding tools without giving up the delegation workflow that makes them useful? Brian John approaches that problem as a principal full stack engineer responsible for AI enablement in BetterUp’s R&D organization: helping people work faster and produce higher-quality results. At the time of the talk, he had spent more than eight years at BetterUp, which he describes as using AI from its beginning. Its mission—helping people live with purpose, clarity, and passion—also frames his invitation to engineers interested in working with LLMs.

Claude Code is his daily driver, and subagents are a regular part of his work. But those workflows create a dependency: switching tools can mean losing the ability to delegate in the same way. Codex CLI’s models look appealing to him, and he wants to use them without being locked into either one tool or one model family.

The main benefit is context isolation. The parent gives a subagent a problem; the child spends its own tokens investigating it and returns only the answer. The intermediate work does not fill the parent’s context window. John credits Dex Horthy’s context-engineering talk with changing how he works, particularly in large codebases. Delegation is therefore more than assigning a role: it controls how much working material the main agent has to carry forward.

Slide titled “But…why?” lists vendor lock-in to Claude Code, context management, and “You’re absolutely right!” above a thumbnail for “Advanced Context Engineering for Agents.”Open full source frame
Motivations for subagents, with a reference to Dexter Horthy’s context engineering talk.
0:120:25
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

0:12 · section reference included

A subagent is another Codex process

The implementation starts with a small observation: a subagent can be another instance of the main agent. There is no need to build a separate agent runtime. The parent Codex session can invoke a wrapper that starts a child through codex exec.

The complete execution loop has four steps:

  1. The parent calls the wrapper with a delegated task.
  2. The wrapper selects the agent definition, builds its prompt, and launches child Codex.
  3. The child performs the task and writes its final answer into a file.
  4. The wrapper reads that file and prints its contents to stdout, where the parent receives the result.

The answer file is the handoff between child and wrapper; stdout is the handoff between wrapper and parent. The design is small, but John’s first attempts immediately run into sandbox errors.

Design flowchart connects Parent Codex Session, agent-exec CLI, Child Codex CLI, and the wrapper’s return path back to the parent.Open full source frame
The parent session launches a wrapper, which runs child Codex and returns its file output through stdout.
2:362:49
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

2:36 · section reference included

Getting nested permissions right

John does not solve those errors by disabling permission checks. The hard part is finding the minimum permissions that let the nested process work. In his setup, the parent needs at least --sandbox workspace-write to run the Codex command. The child then encounters another boundary: the OpenAI credentials in the user’s home directory sit outside the workspace accessible under the parent’s sandbox.

ComponentRequirement in the demonstrationPurpose
Parent Codex--sandbox workspace-writePermit the demonstrated child-launch workflow
Child Codex--sandbox workspace-writeWrite the answer file
CredentialsAn accessible workspace locationAvoid depending on blocked home-directory access
Rollout recorderDisabledAvoid logging writes outside the workspace

The child’s own settings cannot make the parent’s filesystem restrictions disappear. John therefore also disables the rollout recorder, the logging mechanism whose filesystem access causes trouble inside the enclosing sandbox.

Before proceeding, he evaluates the arrangement using Meta’s Agents Rule of Two. The framework examines three properties: processing untrusted input, accessing sensitive systems or private data, and changing state or communicating externally. Its security boundary depends on restricting at least one of these properties; allowing all three together calls for supervision.

John assumes his particular workflow does not process untrusted input. It does access private data through a proprietary codebase, and it can both change state and communicate externally. He considers the state changes in his environment relatively low risk and says the external communication is limited to OpenAI’s API endpoint. That is a conditional assessment of his system: lower risk does not mean no risk, and a different input source or set of accessible systems changes the assessment.

3:363:47
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

3:36 · section reference included

Teaching the parent how to delegate

A working wrapper is not enough: the parent needs to know it exists. The repository’s invocation instructions in AGENTS.md supply three parts of the contract:

  • How: map a request for a named subagent to the wrapper invocation.
  • When: delegate when the user asks, or when the parent judges delegation useful.
  • What: list the available subagents and their responsibilities.

This turns a natural-language request to use a subagent into a concrete action the parent can perform.

John then opens the small BetterUp Codex CLI Subagent Demo. Its agent definitions contain a name, a reasoning-effort setting, and a prompt, much like Claude Code’s subagent definitions. He describes choosing lighter, medium, or higher reasoning according to the work. The two toy agents make that distinction easy to see: one counts words, while the other writes supplied text to a file, a task that needs little reasoning.

John describes the command wrapper as 72 lines. It accepts the inputs, calls the Python AgentExecutor, and prints the returned answer to stdout. The executor owns the process details: child permissions, reasoning effort, and rollout-recorder settings. Keeping those details together leaves the outer command focused on input and output.

6:146:26
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

6:14 · section reference included

Change the input files, keep the command

The invocation contract has an unusual detail: the parent writes the agent name into agent.txt and the user’s query into query.txt before running the wrapper. Passing both values as command-line arguments would be more obvious, but it would change the command on every request.

In the permission system John demonstrates, an exactly unchanged command can retain approval, while changing its arguments prompts for approval again. Moving variable data into files lets different tasks use the same invocation. The following Python example prepares a word-count request through that file interface:

python

from pathlib import Path
import subprocess

Path("agent.txt").write_text("word-counter\n", encoding="utf-8")
Path("query.txt").write_text(
    "Count the words in this text: Small wrappers preserve useful workflows.\n",
    encoding="utf-8",
)

subprocess.run(
    ["timeout", "600", "bin/agent-exec"],
    check=True,
)

The sentence can change without changing timeout 600 bin/agent-exec. This separates the command being approved from the task data it will read.

The reusable approval is consequently approval to invoke the wrapper with changing file contents, not approval of one immutable query. Bypassing permission checks would remove the repeated prompts too, but that is not the operating mode John chooses.

9:059:22
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

9:05 · section reference included

Preparing a Codex home inside the workspace

A second wrapper prepares the parent session. It copies Codex home files from the user’s home directory into a workspace subdirectory so the nested process can access them. John describes this as syncing the files, pointing CODEX_HOME at the new location, and launching Codex. In the inspected repository, those responsibilities are split: bin/codex copies the files into tmp/codex-home, while AgentExecutor sets CODEX_HOME for the child. The accessible copy resolves the earlier credential-location problem.

The launch shown uses --full-auto. John associates it with workspace-write permissions but does not recall its precise approval policy. These flags and approval behaviors belong to the historical demonstration: the current CLI reference marks --full-auto deprecated, and current Codex supports native parallel subagents. The wrapper walkthrough explains how this setup worked without treating its historical limitations as current requirements.

Terminal editor shows a loop copying files and directories, credential-sync status messages, and the final exec codex command with --full-auto.Open full source frame
Launch script copies Codex home entries into the workspace location and runs Codex with --full-auto.
10:0910:25
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

10:09 · section reference included

From the first approval to a verified file

With the prepared session running, John asks Codex to use the word-counter subagent. The parent recognizes that it needs the agent-execution wrapper, writes the agent name and query into their files, and requests permission to run the command. John chooses the option to approve it without asking again for that command. This first invocation establishes the approval that the next task will reuse.

The demonstrated workflow runs serially: the parent waits while the child does its work. John finds it slower than his Claude Code workflow and interprets Codex as better suited to hands-off, unattended work, while Claude Code feels more iterative to him. He accepts that tradeoff for his usage. The child’s result then appears on stdout, and the parent turns it into the answer shown to the user.

The second request uses the file-writer subagent. Codex writes a new agent name and query into the same input files and invokes the same command. This time there is no permission prompt. The task has changed, but the approved command has not.

The command uses timeout 600, giving the outer invocation ten minutes. John reports that large-codebase tasks can take ten minutes and sometimes as long as twenty minutes. That motivates allowing more time for substantial repository work. There is also an implementation detail to account for: AgentExecutor passes its own 600-second timeout to subprocess.run, so increasing only the outer timeout would leave the internal limit in place.

John reports that the easy file-writing example took about 40 seconds. These durations are observations from his usage and demonstration, rather than controlled comparisons across models or repositories. He finishes by checking that the requested file was written—the concrete output matters beyond the parent’s success message.

The recording closes with pointers to the open-source code and BetterUp, plus email and X direct messages for questions. The proof of concept ends at a useful boundary: two different delegated tasks, one reusable wrapper approval, and a file checked after creation.

10:4510:50
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

10:45 · section reference included

Resources

From the talk

Updates since the talk

Transcript download
Read the transcript and explore slides

Loading transcript and slides…