agentleFS
gradigitgradigit/claude-skills/.claude/skills/forge-codex-multiagent/SKILL.md

forge-codex-multiagent

Skill0 starsChanged 9 months agoMITView on GitHub

Codifies best practices for Codex CLI multi-agent features: spawn_agent, fork_context, send_input, batch processing. Reference guide for building effective agent workflows with conflict prevention and error recovery. Do NOT use when working with Claude Code — use forge-claude-teams instead.

The file

Show its rules and text

We split this skill into the rules it gives an agent

16 rules. About 0 are common, 12 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈12

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Distinctive:

    Only send to healthy, running agents

    line 68
  2. Very specific:

    Never send_input to a failed or timed-out agent (spawn fresh instead)

    line 69
  3. Distinctive:

    Use for follow-up guidance, not complete task re-specification

    line 70
  4. Distinctive:

    Do not merge fork state back into main context manually — extract only the final result

    line 127
  5. Distinctive:

    Every build agent must declare its scope in the context handoff:

    line 273
  6. Very specific:

    When agents must share state files (e.g., TODO.md, state.json):

    line 284
  7. Distinctive:

    Write back with a version/timestamp check

    line 291
  8. Distinctive:

    Rule: Never override model selection unless the user explicitly requests cost optimization.

    line 352
  9. Very specific:

    Never send_input to a failed agent — always spawn fresh

    line 388
  10. Very specific:

    Update TODO.md after every significant step:

    line 401
  11. Distinctive:

    Before each significant action batch, emit a brief progress note as part of a response that also includes tool calls.

    line 413
  12. Distinctive:

    Do NOT emit standalone text-only progress messages between action batches.

    line 417
  13. Distinctive:

    After completing a milestone or phase, do not summarize — immediately read the next milestone's scope or the next phase's inputs.

    line 462
  14. Distinctive:

    forge-builder phase transitions: after marking a phase complete in TODO.md, move directly to the next phase's implementation step.

    line 479
  15. Distinctive:

    forge-research synthesis steps: after writing the research output file, if more depth cycles remain, read the output back to start the next …

    line 481
  16. Distinctive:

    Update this skill when:

    line 524

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Codex CLI Multi-Agent Practices

Best practices for Codex CLI's multi-agent features, derived from session log analysis (887 spawn_agent calls). Reference guide for forge-research, forge-builder, and forge-orchestrator when running on Codex CLI.

API Verification: Codex CLI is actively evolving. Before relying on any API described here, verify the function signatures and behavior match your current Codex CLI version. If an API has been renamed or removed, update this guide accordingly.


1. Core Multi-Agent API

Each API section includes a verification reminder. Confirm function names, parameter order, and return types match your installed Codex CLI.

spawn_agent

Creates a child agent with a specific task.

agent_id = spawn_agent(
    agent_type="worker",    # Built-in (default/worker/explorer/monitor) or a custom role name
    message="...",          # The task — must follow the 5-component context handoff below
    model=None,             # Optional — inherits main model if omitted
    fork_context=False      # Optional — clone current context into the child (see fork_context)
)

Context handoff template (required in message):

ComponentContentExample
TaskImperative, specific objective"Analyze auth middleware for token refresh race conditions"
ContextProject state, decisions, constraints"Using Express 4.x, JWT tokens, Redis session store"
ScopeFiles/directories this agent owns"Own: src/auth/*.ts, src/middleware/auth.ts"
BoundariesWhat to ignore, what others own"Do NOT modify src/routes/ or test/"
Output contractFormat, location, completion signal"Write findings to output/auth-analysis.md, print DONE when complete"

Verify: Confirm spawn_agent accepts agent_type, message, and optional model/fork_context parameters in your Codex version. (The live 0.140.x binary uses these names — older drafts of this guide showed name=/instructions=, which the tool does not accept.)

send_input

Sends work or follow-up instructions to a running agent.

send_input(agent_id, "Focus on the token refresh logic in auth.ts lines 45-80")

Rules:

  • Only send to healthy, running agents
  • Never send_input to a failed or timed-out agent (spawn fresh instead)
  • Use for follow-up guidance, not complete task re-specification

Verify: Confirm send_input accepts agent_id and message string.

wait / resume_agent

Synchronous wait blocks until agent completes or timeout elapses. Resume restarts a suspended agent.

result = wait(agent_id, timeout=300)    # Wait up to 5 minutes
resume_agent(agent_id)                  # Resume suspended agent

Timeout guidelines:

Task typeRecommended timeout
Quick lookup / search60s
File analysis120-180s
Multi-file research300s
Complex refactoring600s

Verify: Confirm wait accepts optional timeout (seconds) and resume_agent exists.

close_agent

Graceful shutdown with output collection. Always close agents when done.

output = close_agent(agent_id)    # Collects final output, releases resources

When to close:

  • Agent has completed its task
  • Agent has failed and you need partial output
  • Agent has exceeded its timeout
  • Session is ending (close all open agents)

Verify: Confirm close_agent returns collected output.

fork_context

Clones current context into a new agent. Ideal for exploratory branches.

fork_id = fork_context(
    instructions="Try implementing auth with OAuth2 instead of JWT"
)

Use cases:

  • "What if" exploration of alternative approaches
  • Testing two solutions in parallel, keeping the better one
  • Safe experimentation without polluting main context

Rules:

  • Discard the fork if the approach does not work (close_agent + ignore output)
  • Do not merge fork state back into main context manually — extract only the final result
  • Forks inherit full context, so keep parent context clean before forking

Verify: Confirm fork_context accepts instructions and returns an agent ID.


1b. Custom Agent Roles

Codex loads custom agent roles from per-file TOMLs — one file per role at ~/.codex/agents/<name>.toml (personal) or .codex/agents/<name>.toml (project-level, installed alongside skills). This is the mechanism the forge roles ship with and the one that loads reliably.

# ~/.codex/agents/my-reviewer.toml
name = "my-reviewer"
description = "When to use this role"
sandbox_mode = "read-only"    # read-only | workspace-write | danger-full-access
developer_instructions = """
Your system prompt here. Use the same XML structure
(objective, context, output-format, boundaries) as Claude Code agents.
"""

Each role file requires a non-empty name; the valid sandbox_mode values are exactly read-only, workspace-write, and danger-full-access (the older full-access value is rejected at load time by current Codex).

Global limits live under a [agents] table in config.toml:

# ~/.codex/config.toml or .codex/config.toml (project-level)
[agents]
max_threads = 3    # see max_threads guidance in Section 2

Legacy/alternate: Codex also compiles in an inline [agents.<name>] config.toml form with a config_file pointer. Prefer the per-file model above — the inline form has known config-loading caveats (roles can fail with "unknown agent_type" unless -c-injected; see openai/codex#14579, #15250).

Forge agent roles: The forge pipeline includes 4 predefined roles:

RoleSandboxPurpose
forge-adversarial-reviewerread-onlyCritical review with confidence gating
forge-build-workerdanger-full-accessImplementation within file scope
forge-research-workerread-onlyWeb research + codebase exploration
forge-performance-auditorread-onlyMetric-driven benchmarking

Role config files: .codex/agents/forge-*.toml (installed alongside skills).

Built-in roles: Codex also ships with default, worker, explorer, and monitor. Use forge roles for structured output with quality bars; use built-in roles for ad-hoc work.

Known limitation: In tool-backed sessions, spawn_agent may only resolve the built-in agent_type values (default/worker/explorer/monitor) and not select per-file custom roles by name (openai/codex#15250). Session-log analysis confirms real spawn_agent calls used built-in types, never forge-* role names. Until this is fixed upstream, treat the forge role TOMLs as developer-instruction templates: their content can be passed via message/base_instructions even when the role can't be selected by name.

Verify: Confirm per-file ~/.codex/agents/*.toml role loading (and the legacy [agents.<name>] form, if used) match your Codex version, and test whether spawn_agent can select a forge role by name. Enable multi-agent with multi_agent = true in [features].


2. Batch Processing

spawn_agents_on_csv

Batch-spawns agents from a CSV file. Each row becomes an agent with templated instructions.

agents = spawn_agents_on_csv(
    csv_path="tasks.csv",
    template="Analyze {filename} for {check_type}. Write results to output/{filename}.md"
)

Example CSV (tasks.csv):

filename,check_type
auth.ts,security vulnerabilities
router.ts,performance bottlenecks
db.ts,connection leak patterns

Use for:

  • Processing multiple files with the same operation
  • Running identical tests across different configurations
  • Parallel research on a list of topics
  • Batch code review across modules

max_threads Configuration

Controls maximum parallel agents. Governed by Gunther's Universal Scalability Law — coordination overhead scales quadratically.

SettingThreadsUse case
Conservative (forge default)3Standard multi-agent work
Moderate5Independent, non-conflicting tasks
Maximum7Forge ceiling — coordination overhead dominates beyond this
# Set in Codex config (~/.codex/config.toml under [agents])
max_threads = 3    # Forge recommendation for most work

Note: 3 and 7 are forge recommendations, not Codex limits. Codex's own max_threads default is 6 with no hard upper cap (real-world configs set it as high as 100). The 7 ceiling below is forge guidance based on coordination overhead, not a CLI constraint — raise it deliberately for genuinely independent fan-out work.

Why 7 is the ceiling: Beyond 7 parallel agents, coordination overhead (context switching, conflict resolution, output merging) exceeds the throughput gained. Observed in session logs: 7+ agents consistently produced more merge conflicts than time saved.

Verify: Confirm spawn_agents_on_csv and max_threads exist in your Codex version.


3. Conflict Prevention

Codex has no git worktree equivalent. All conflict prevention relies on ownership scoping and disciplined sequential merging.

Conflict Prevention Pyramid

            NEVER: Two agents editing same file
           ────────────────────────────────
          BUILD: Explicit scope per agent
         (file ownership, sequential merge)
        ────────────────────────────────────
       EXPLORE: fork_context for alternatives
      (discard if approach fails)
     ────────────────────────────────────────
    RESEARCH: Shared context, read-only tools
   (safe by default, no isolation needed)

By Agent Type

Agent typeIsolation methodConflict risk
Research / read-onlyShared context, read-only toolsNone
Exploratoryfork_context — discardable branchesNone (discard on conflict)
Build (different files)scope field per agent, sequential mergeLow
Build (same file)DO NOT — redesign decompositionFatal

File Ownership Scoping

Every build agent must declare its scope in the context handoff:

Scope: Own src/auth/login.ts, src/auth/refresh.ts
Boundaries: Do NOT modify src/auth/logout.ts (owned by agent-logout)

Enforcement: The agent must check its scope before modifying any file. If a needed change is outside scope, report the need to the orchestrator — do not modify.

Atomic State for Shared Files

When agents must share state files (e.g., TODO.md, state.json):

  1. Write to agent-specific output files — each agent writes output/{agent-name}-result.json
  2. Orchestrator merges — only the orchestrator reads agent outputs and writes the shared file
  3. Read-modify-write with conflict detection — if direct shared writes are unavoidable:
    • Read current state
    • Apply changes
    • Write back with a version/timestamp check
    • Retry on conflict

4. Patterns from Session Log Analysis

Derived from analysis of 887 spawn_agent calls across production Codex CLI sessions.

Key Findings

FindingImpactRecommendation
Short focused sessions outperform long unfocused ones3x higher task completion rateOne clear objective per agent
Ownership scoping is #1 predictor of success89% success with scope vs 34% withoutAlways declare file ownership
Fan-out with independent tasks beats pipeline2.5x fewer failuresPrefer parallel independent over sequential dependent
Agents with clear output contracts finish faster40% faster completionAlways specify output format and location

Fan-Out Pattern (Preferred)

Orchestrator
  ├── Agent A: analyze auth module      → output/auth.md
  ├── Agent B: analyze routing module   → output/routing.md
  ├── Agent C: analyze database module  → output/database.md
  └── Orchestrator: merge outputs       → final-report.md

Each agent works independently. No agent depends on another's output. Orchestrator merges at the end.

Pipeline Pattern (Use Sparingly)

Agent A: research → Agent B: design → Agent C: implement → Agent D: review

Each agent depends on the previous. One failure blocks the chain. Use only when strict ordering is required.

Queue-Codex Batch Mode Signals

For unattended batch runs, agents use a signal protocol:

SignalMeaningAction
HALTCritical error, stop all workOrchestrator closes all agents, reports error
SKIPNon-critical failure, skip this itemOrchestrator logs skip, continues batch
IDLEWaiting for input or dependencyOrchestrator sends input or resolves dependency
DONETask complete, output readyOrchestrator collects output, closes agent

Agents print signals to stdout. Orchestrator monitors and reacts.


5. Model Selection

ScenarioModel settingRationale
Standard workerOmit model param (inherits main)Consistency, same capabilities
Cost-optimized batch (user-requested)Explicit model overrideOnly when user explicitly asks
Default Codex modelAcceptable if matches main sessionDo not override just to be explicit

Rule: Never override model selection unless the user explicitly requests cost optimization. Workers must match the main session's model for consistent quality.


6. Error Recovery

Decision Table

Failure typeDetectionRecovery
Agent crashwait returns error / no outputclose_agent for partial output, spawn_agent fresh
Timeout exceededwait timeout expiresclose_agent, retry with simplified task
Garbage outputOutput fails validationclose_agent, spawn_agent with clarified instructions
Scope violationAgent modified files outside scopeRevert changes, close_agent, re-spawn with stricter scope
All retries exhausted2+ failures on same taskEscalate to user with failure context

Recovery Protocol

1. Detect failure (timeout, crash, bad output)
2. close_agent(failed_id)           # Collect whatever output exists
3. Analyze failure cause
4. spawn_agent(                     # Fresh agent, never reuse failed one
       name="retry-{task}",
       instructions="""
           {original 5-component handoff}

           Previous attempt failed: {failure reason}
           Partial output from previous attempt: {if useful}
           Avoid: {what caused the failure}
       """
   )
5. If retry fails: simplify task or escalate

Critical rules:

  • Never send_input to a failed agent — always spawn fresh
  • Include failure context in the new agent's instructions so it avoids the same mistake
  • Maximum 2 retries per task, then escalate to the user
  • Timeout exceeded: simplify the task (reduce scope) before retrying

7. Progress Observability

Agents must remain observable. Silent agents waste resources and block orchestration.

TODO.md Updates

Update TODO.md after every significant step:

  • Completing a file
  • Passing or failing a test
  • Hitting an error or blocker
  • Finishing a milestone

FORGE-STATUS.md (Orchestrator Only)

For long-running orchestrations, the orchestrator (and only the orchestrator) maintains FORGE-STATUS.md with: current milestone, active agents, completed steps, pending steps, blockers. Sub-agents do NOT write to FORGE-STATUS.md — they report status inline to the orchestrator.

Progress Narration

Before each significant action batch, emit a brief progress note as part of a response that also includes tool calls. On Codex CLI, a text-only progress note ends the turn — always pair narration with the tool calls it describes.

Do NOT emit standalone text-only progress messages between action batches.

Observability Rules

RuleEnforcement
No silent runs > 5 minutesAgent must emit progress note
Status updates after significant stepsCompleting a file, passing a test, hitting an error
Only orchestrator writes shared status filesSub-agents report inline to orchestrator
Structured output for batch monitoringUse signal protocol (HALT/SKIP/IDLE/DONE)

8. Parallelism Model

Codex's primary parallelism model is fan-out with independent tasks — the top-performing pattern from session log analysis. Each agent works independently; the orchestrator merges at the end.

This is the Codex equivalent of Claude Code's parallelized serial threads model. The difference: Claude Code threads can run serial internal steps (research → build → test within each thread). Codex agents are typically single-task — use sequential spawn chains for multi-step work within a scope.

See forge-claude-teams for the Claude Code equivalent patterns.


9. Turn Lifecycle

Critical for long-running workflows.

Codex CLI ends a turn when the model produces a text-only response — any response with no tool calls. This is a deterministic mechanism: needs_follow_up is set to true only when tool calls are present. No configuration can override this.

This differs from Claude Code, where text and tool_use blocks coexist in the same response and text alone does not end the turn.

Rules for Continuous Execution

RuleWhy
Never produce a text-only message mid-workflowEnds the turn immediately
Always pair state-file updates with a follow-up tool callThe tool call keeps the turn alive
After writing state files, immediately read the next phase's inputsTransitions directly to the next step
Save summaries for the final step onlyThe last step is where the turn should end

Pattern

After completing a milestone or phase, do not summarize — immediately read the next milestone's scope or the next phase's inputs. The act of reading transitions you into the next step and keeps the turn alive.

# BAD — standalone text ends the turn
"Milestone 1 complete. Moving to milestone 2..."

# GOOD — tool call keeps the turn alive
[write FORGE-STATUS.md] → [read TODO.md for next milestone scope] → continue

Where This Matters Most

  • forge-orchestrator COMPOUND step: writes 6+ state files, then the model naturally summarizes. That summary ends the turn. Fix: read next milestone scope immediately after the commit.
  • forge-builder phase transitions: after marking a phase complete in TODO.md, move directly to the next phase's implementation step.
  • forge-research synthesis steps: after writing the research output file, if more depth cycles remain, read the output back to start the next cycle.

Anti-Patterns

Anti-PatternWhy It FailsDo Instead
Two agents editing same fileMerge conflicts guaranteedRedesign split or queue
send_input to failed agentCorrupted state carries overclose_agent, spawn fresh
No scope declaredAgents step on each otherAlways declare file ownership
Model override for workersQuality degradationOmit model param (inherit)
Pipeline for independent tasksOne failure blocks allUse fan-out pattern
Exceeding 7 threadsCoordination overhead > throughputStay at 3 default, 7 ceiling
Silent agents (no progress)User thinks agent is stuckEmit progress narration
Merging fork state manuallyContext corruptionExtract only final result
Skipping close_agentResource leaksAlways close when done
fork_context for production workForks inherit full context, diverge unpredictablyUse spawn_agent with scoped instructions for real work; forks are for exploration only

Quick Reference Card

CREATE:    agent_id = spawn_agent(agent_type, message, [model], [fork_context])
SEND:      send_input(agent_id, message)          # running agents only
WAIT:      result = wait(agent_id, [timeout])      # synchronous block
RESUME:    resume_agent(agent_id)                   # restart suspended
CLOSE:     output = close_agent(agent_id)           # graceful + collect
FORK:      fork_id = fork_context(instructions)     # clone context
BATCH:     agents = spawn_agents_on_csv(csv, tpl)   # CSV batch spawn

SIGNALS:   HALT | SKIP | IDLE | DONE               # batch mode protocol
THREADS:   max_threads = 3 (forge default), 7 (forge ceiling)  # Codex default 6, no hard cap
SCOPE:     Always declare. Never modify outside scope.
RECOVERY:  close → spawn fresh (never send_input to failed)

Self-Evolution

Update this skill when:

  1. API changes: Codex CLI adds/removes/renames multi-agent APIs
  2. New patterns: Session log analysis reveals improved patterns
  3. Conflict strategies: Better isolation or merging approaches discovered
  4. User corrections: Real-world usage reveals incorrect guidance

Current version: 1.1.1. See CHANGELOG.md for history.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.