Skip to main content
A campaign splits one objective into subtasks and runs a worker agent on each one at the same time. When the workers finish, o4 combines their results into one answer. Use a campaign for work that divides into independent parts, such as reviewing several modules or checking one change from different angles.

Start a campaign

Run /campaign with the objective:
o4 then:
  1. Asks the current model to split the objective into up to three subtasks, each with a role and a task.
  2. Starts one worker agent for each subtask. The workers run at the same time, each in its own context.
  3. When all workers finish, asks the model to combine their results into one response in the chat.
The chat shows Campaign starting: and the objective while o4 plans the subtasks. Only one /campaign runs at a time: while one runs, /campaign says A campaign is already running.
Campaign workers don’t ask for approval. Each worker can read and edit files, run shell commands, and fetch URLs in your project without prompting you. Your permission rules, hooks, and sandbox settings still apply, and any action that would need your explicit approval is denied. Workers all use the same checkout, so two workers can change the same file. Commit or stash your work before you start a campaign that edits code.

Watch a campaign

A running campaign and its workers appear in the Agent command center. Run /agents to open it, select a worker, and press Enter to see its output. See todos and background tasks for the dashboard keys.

Cancel a campaign

Press Ctrl+C with an empty prompt to cancel a campaign that is starting or running. The chat shows [Campaign] Cancelled by user, or [Campaign] Startup cancelled by user if o4 was still splitting the job into subtasks. If the main agent is also running a turn, the first Ctrl+C stops that turn and the campaign keeps going; press it again to cancel the campaign. An open approval prompt or panel also takes Ctrl+C first. To stop a single worker instead, select it in /agents and press x.

Results and campaign files

When the workers finish, the combined result appears in the chat. If every worker failed, o4 says so instead of combining results. o4 keeps each campaign’s state in .o4/campaign/<id>/ in your project: A /campaign that fails before its workers start writes failure.json to .o4/campaign/startup-<id>/ instead. /campaign also runs as a background task named Campaign: <objective>. Press Alt+B to open the Task Board, select that row, and press Enter: its output is a short summary and the path to the full result or failure file.

Validation with harness sensors

o4 validates each worker’s result after the workers finish. If your project has a .o4/harness.toml file that defines sensors (commands that check the work, such as a test or lint command), o4 also runs the sensors that apply to the campaign’s objective, without asking, and records their results in result.json. With the sequential strategy, it also runs them after each worker. A campaign counts as failed if a worker fails or a blocking sensor fails. o4 reads .o4/harness.toml only in trusted workspaces. See workspace trust, and Harness guides and sensors for the file format.

The campaign tool

The model can start a campaign itself with the campaign tool. It asks for approval every time. With the tool, the model chooses the workers and their roles directly, and it can pick a strategy: Each worker takes a role, a task, and an optional model. Without a model, a worker uses its agent definition’s model, then the session’s current model. The tool also takes timeout_secs, a time limit for each worker in seconds. Without it, workers have no time limit. The tool’s auto_approve option has no effect: campaign workers never ask for approval. A worker’s role can name an agent definition, such as a custom agent from .o4/agents/. If no definition matches, the worker uses the built-in General agent. See subagents.

Campaigns and worktrees

Campaign workers don’t get their own worktrees. When you want parallel changes kept apart, ask the model to use subagents with worktree isolation instead. Each one then works in its own git worktree on its own branch, and o4 keeps any worktree with changes so you can review and merge it. See run a subagent in its own worktree. The model can also move the main session into a worktree with the enter_worktree tool. It creates a worktree under .o4/worktrees/ on a branch named o4-worktree-<name>-<session>, and file tools then work there. exit_worktree returns to the original directory. With merge, it merges the worktree’s branch into your current branch first. It won’t discard a worktree with uncommitted changes unless the model passes force. Both tools ask for approval once per session.