WAVES — Workers · Aggregate · Verify · Extend (Codex)

SkillAI & models

WAVES - Workers, Aggregate, Verify, Extend - wave-based orchestration for Codex. Decompose a big goal into independent slices, verify coverage, spawn Codex subagents in parallel as a bounded wave, collect evidence-backed handoffs, verify important claims, synthesize one deliverable, and extend into another wave only when warranted. Bounded by design to avoid runaway token loops; invoke deliberately. Formerly parallel-orchestrate-codex; also fan out, parallelize, spin up multiple agents, orchestrate workers, multi-stream research, audit a repo, split disjoint implementation work.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the WAVES — Workers · Aggregate · Verify · Extend (Codex) skill

What this skill tells your AI

The instructions your AI receives, as published by rayfernando1337/rayfernando-skills in plugins/waves-codex/skills/waves-codex/SKILL.md and read by ahel’s review.

Run wave-based orchestration with Codex subagents. A wave is a bounded round of isolated workers in parallel, then a round that verifies what came back, then a deliberate decision to build on it — not an open-ended loop. Use this skill when a task is too broad for one clean linear pass but can be split into independent slices. You are the manager: discover the problem shape, stage and verify coverage, decompose it, spawn bounded Codex workers, collect one structured handoff from each worker, verify important claims, and synthesize the final deliverable.

The shape of every wave — WAVE: Workers fan out across disjoint slices -> Aggregate their handoffs -> Verify the evidence (the moat) -> Extend into another wave only when warranted. A loop doesn't know when to stop; a wave does, because verification is the stop function. (Invoke deliberately - a run spawns more agents than usual.)

Current Codex docs checked on 2026-07-19: Codex subagents are enabled by default in current releases, built-in roles include default, worker, and explorer, custom agents live in ~/.codex/agents/ or .codex/agents/ (TOML; project agents load in trusted projects only), and subagent limits live under [agents] in config.toml. Official docs no longer enumerate the collaboration tool names; the current (multi-agent V2) surface exposes spawn_agent, send_message, followup_task, wait_agent, interrupt_agent, and list_agents, while threads created before the V2 runtime resume on the legacy V1 set (spawn_agent, send_input, resume_agent, wait_agent, close_agent) — read the live tool registry rather than assuming one set. Spawning an unknown agent_type fails with an error rather than silently falling back (fallback in Step 2). V2 delegation payloads are encrypted between model calls, so don't build workflows that inspect spawn prompts from rollout history. spawn_agents_on_csv is documented as experimental; use it when it is exposed in the active Codex surface, and fall back to normal subagent waves when it is not. No current Codex doc confirms a general-purpose claim-verifier or critic hook; use a verifier subagent, CSV verification pass, tests, validators, or codex exec --output-schema instead.

Native delegation on GPT-5.6 (how this skill plugs in): Sol and Terra run the V2 multi-agent runtime, and the delegation mode is derived from reasoning effort per turn -- ultra means proactive (the model spawns on its own judgment), every other effort means explicit-request-only, where the documented triggers are direct user asks and "applicable AGENTS.md or skill instructions" -- this skill's spawn instructions are that sanctioned channel, at any effort, no ultra required. Avoid ultra for wave runs: proactive spawning happens outside your manifest, and its children inherit the parent's model and effort (an ultra parent breeds ultra children -- the runaway-cost failure mode). Native V2 spawns also fork the parent's history by default (fork_turns defaults to all; filtered, but the child sees your conversation), and full-history forks inherit the parent's agent type / model / effort and reject overrides -- so for disjoint wave slices, request fresh-context workers (no history fork), which is also the only spawn shape that can be routed to a different model or effort. V2 ignores agents.max_depth; its binding limit is concurrent agent slots (4 including the manager by default; agents.max_threads + 1 when set) -- batch wider waves accordingly.

Read these references when using the skill:

  • references/handoff-format.md for the exact worker handoff contract.
  • references/verification.md for verification gates and verifier-worker playbooks.
  • references/examples.md for decomposition recipes.
  • references/recommended-config.md for Codex config and custom agent snippets.
  • references/adaptation-notes.md for Cursor-to-Codex translation notes.

When to Use

  • The user explicitly asks to use multiple agents, subagents, parallel workers, fan-out, or orchestration.
  • The task splits into independent slices: data ranges, research streams, repo modules, audit dimensions, verification rows, or disjoint code ownership.
  • The main value is speed, context hygiene, and verification discipline: keep noisy exploration out of the manager thread, then check the claims that matter.
  • A second or third wave may be useful after first-wave handoffs expose gaps, conflicts, narrowed scope, or high-stakes claims needing verification.

When to Skip

  • The task is small, linear, or easy to do locally.
  • The slices require constant cross-talk or shared mutable decisions.
  • The next action is blocked on one immediate investigation; do that locally.
  • Parallel code edits would overlap heavily and no worktree/isolation strategy is available.

Core Principles

  1. The manager plans, verifies, and synthesizes. Workers do heavy reading, research, tests, audits, bounded edits, or focused claim checks.
  2. Worker prompts are self-contained. Do not assume workers can infer the user's original request, your scratch reasoning, or sibling work unless you intentionally pass or fork that context. (On GPT-5.6's V2 runtime, native spawns fork parent history by default -- request fresh-context workers for disjoint slices, and keep prompts self-contained either way: a forked child sees a filtered history, not your reasoning, and fork behavior is version-sensitive.)
  3. One worker owns one slice and returns one handoff.
  4. Verify before you trust. A worker's Status: success is a claim, not evidence.
  5. Parallel reads are the default safe case.
  6. Parallel writes require disjoint ownership or isolated worktrees. Codex is safer than a shared local-only model when workers run in separate sandboxes or worktrees, but write conflicts are still a coordination problem.
  7. Continuous motion (within the stated budget). Handoffs reveal new work; treat each open question or suggested follow-up as a candidate second-wave task and spawn it. Keep going until every slice is terminal and the synthesis is complete -- stopping early while genuine follow-ups remain is the failure mode this skill guards against. (The manifest plus the stated budget is the stop function; see "Bounded Waves.")
  8. Decomposition is entropy reduction. A vague goal is high-entropy: many plausible plans still fit. Shrink that space -- dig locally, then pull from attached resources, then ask the user only if it pays -- before you slice it. See "Entropy-First Decomposition."

Bounded Waves - Size, Budget, and the Stop Function

A wave is bounded on purpose - but bounded by completion and budget, not by a wave count. Unbounded "loop-until-done" burns tokens for little gain: candidate generation is cheap, selection plateaus, and extra rounds are non-monotonic (more iterations can lower quality, not just cost). Equally real is the opposite failure: stopping while the manifest still has open slices. Keep the exploration, drop the runaway, never abandon un-terminal work.

  • Width: 3-8 workers per wave (and within the concurrency limit: V2 allows 4 concurrent agent slots including the manager by default, or agents.max_threads + 1 when set -- with max_threads = 6, that is 7 slots; batch wider waves). Size the wave so you can fully verify all of it. Go wider only with a cheap automatic check (tests, codex exec --output-schema, schema/exec) gating results. (Grounding: homogeneous-agent teams plateau around N~4-8 - added workers contribute redundant evidence, and diversity, not head count, escapes the ceiling - arXiv 2606.02646, 2602.03794.)
  • Depth: the manifest is the stop function. Keep extending while any manifest slice is non-terminal AND the last wave added verified progress. Stop only on one of three conditions: completion (every slice terminal, synthesis done), stagnation (nothing new + outputs near-duplicate the last wave, or a quality drop), or budget exhaustion. State the budget up front in the run-shape line
    • a worker or token budget, not a wave count (e.g. budget: ~20 workers). A realistic run is often 12 + 3 + 1 workers across three waves, and a decomposition cascade on a vague goal legitimately runs more. (Grounding: verification-driven replan loops stop on completeness thresholds, diminishing returns, and token budgets, not fixed iteration caps - VMAO, arXiv 2603.11445; convergence-based stopping beats fixed max_iterations at parity quality - arXiv 2606.27009.)
  • Scouting is cheap - don't let it eat the budget. Entropy-reduction waves (scouting, decomposition) run on cheap models/low effort and count separately from the execution budget. Never end a run "out of waves" when the budget was consumed by discovery before execution started.
  • Budget ~60% generation / 40% verification; selection is the scarce resource.
  • Match width to difficulty: easy -> 1 + light refine; medium -> 3-5; hard/open-ended -> 5-8 for diversity; hardest/novel -> escalate reasoning/model, don't loop.
  • Anti-poisoning: carry only a distilled, verified handoff (winner + short critique) into the next wave, never raw transcripts or losing candidates. Exception: constraints are pinned, never summarized - the manifest, stop conditions/budget, and safety/scope rules travel verbatim through every synthesis and compaction (compaction measurably drops in-context constraints; arXiv 2606.22528).

Loop-until-done is justified only when ALL hold: a cheap reliable ~ground-truth verifier exists; the signal is crisp/actionable (a failing test, not "try harder"); each iteration shows measurable progress; easy-medium difficulty; still hard-capped. Fits code-with-tests/exec-feedback; misfits open-ended research/writing/design.

Entropy-First Decomposition

Before you fan out, treat the goal as an entropy-reduction problem: shrink how many plausible interpretations and plans still fit what you know. A vague, high-entropy request ("build a Flappy Bird game", "make my app faster") does not slice cleanly yet -- reduce the uncertainty first, then decompose the low-entropy version. Name what is uncertain, because the two kinds resolve differently:

  • Specification uncertainty -- what the user wants (ambiguous goal, missing acceptance criteria, unstated constraints). Resolve by stating an explicit assumption and proceeding, or -- only when a wrong guess is expensive -- by asking.
  • Environment / knowledge uncertainty -- facts you do not have yet but can get (repo shape, schema, API behavior, current docs, data size). Resolve by gathering, not by asking.

Spend the cheapest action that buys the most certainty first -- an information-gain ladder -- and aim each probe at the unknown whose answer eliminates the most plans (the highest-information question splits the surviving interpretations roughly in half):

  1. Dig locally first (cheap): inspect local state in the manager thread (list, read schema/README, grep, sample data). This is Step 0; it often collapses most of the uncertainty for free.
  2. Then pull from attached resources: if local state lacks the answer, spawn a small scouting wave of explorer/research workers to fetch it (docs, MCP, web) on a fast low-cost configuration (gpt-5.6-terra or short-context gpt-5.6-luna at low/medium; see Step 2).
  3. Ask the user last, and only when it pays: when residual specification uncertainty is high and a question's expected information gain beats its cost. Most requests carry enough to proceed on a stated assumption.

Then cascade: one request becomes a decomposition wave (understand -> locate unknowns -> draft the plan) -> verify -> an execution wave that builds the subtasks least-to-most (each verified result lowering uncertainty for the next), with more scouting sub-waves wherever entropy stays high. Track the living plan with update_plan; stop reducing when entropy is low enough to act -- the verification gate doubles as "is the uncertainty low enough to commit?" (Worked example: references/examples.md.)

The Loop

Track the run with Codex's plan mechanism (update_plan) whenever the workflow has more than a couple of moving parts.

Step 0 - Discover Serially

Do not fan out blind. First inspect enough local state to learn the natural shape of the work:

  • List directories or data sources.
  • Read schemas, manifests, READMEs, package boundaries, or route maps.
  • Sample representative records/files.
  • Count rows, files, modules, routes, messages, or scope size.
  • Identify likely independent slices and risky overlap.

This manager-side discovery prevents duplicate worker scopes, blind spots, and mis-sized chunks.

Step 0.5 - Stage and Verify Coverage

Codex subagents inherit the current sandbox, approvals, MCP, and tool access, so remote or messy data does not always need to be staged locally first. Still stage data when it reduces risk or repeated work:

  • Export remote/database data once if credentials, rate limits, or query cost would make every worker redo the same setup.
  • Normalize noisy inputs once: strip wrappers, binary blobs, boilerplate, and irrelevant logs.
  • Pre-chunk huge corpora into exact per-worker files or ranges.
  • Keep one scratch dir per run (e.g. .waves/<run>/ with staging/, handoffs/, synthesis-wave-N.md) so prompts cite paths instead of pasting content and later waves re-read files, not chat history.

Then run a pre-fan-out gate:

  • Total rows, files, messages, modules, routes, or records.
  • One line per slice with ID/range/path/date bounds and item count.
  • Partition-sum check: slice counts add back to the total.
  • Duplicate/gap check: no overlapping ranges, missing IDs, bad sort, or empty chunks.
  • Central fix-and-recheck if any anomaly appears.

This serial prep is often the largest phase. The parallel fan-out is fast once inputs are clean and coverage is proven.

Step 1 - Decompose into Independent Slices

Size the run itself first, out loud: weigh breadth (how many independent slices), depth (reasoning per slice), ambiguity (see "Entropy-First Decomposition"), and stakes (this sets verification tiers), then state the chosen shape in one line before spawning -- e.g. Run shape: one wave, 4 workers; second wave only if handoffs expose gaps. On the fence between two shapes, pick the smaller and say so. If no wave is needed, do the task in the manager thread and say that -- never present inline work as wave coverage.

Choose the split axis that gives each worker clear ownership:

  • Data chunks: disjoint ID ranges, date ranges, files, or CSV rows.
  • Workstreams: separate technologies, product areas, research questions.
  • Repo modules: non-overlapping path sets or package boundaries.
  • Audit dimensions: security, performance, correctness, tests, maintainability.
  • Verification rows: one claim, citation group, or metric per verifier task.
  • Code edits: disjoint file/module ownership, preferably in worktrees for heavier changes.

For a large wave, usually 5 or more workers, state the decomposition plan and the pre-fan-out coverage gate to the user before spawning so they can redirect cheaply.

Respect agents.max_threads. Current Codex docs say it defaults to 6 when unset. If you need more slices than available threads, batch them into waves.

Then triage each slice on three axes (classify-and-act): the Codex role (table in Step 2), its dependencies (which slices it needs verified output from -- most have none; a real dependency edge is what separates waves), and a verification tier - auto-accept (low-stakes, corroborated) -> single verifier -> multi-model/multi-pass panel (high-stakes) -> debate (contested, no ground truth). Spend verification where a wrong claim is expensive, not uniformly.

Record the triage as a wave manifest - one row per slice (slice | scope | role | effort | depends_on | verification tier), written to the plan or .waves/<run>/manifest.md before spawning. depends_on defines the wave boundaries: a wave is every not-yet-run slice whose dependencies are all met, and a dependency is met only when its handoff has been verified (Step 3), not merely returned. Launch wave 1 (no dependencies) in parallel; launch each dependent slice with the distilled, verified findings (or their .waves/<run>/ path) folded into its self-contained prompt, and keep unrelated slices parallel. The manifest doubles as the completion gate: N rows spawned means N handoffs collected and checked off before synthesis (Step 3). It is also the spawn-plan audit: V2 delegation payloads are encrypted after dispatch, so the manifest review before spawning is the only point where a human (or the manager) can inspect what each worker was asked to do.

Step 2 - Fan Out with Codex Subagents

Spawn all workers whose dependencies are met (handoffs verified, not just returned) in the same manager turn when possible. In Codex, the stable interaction is explicit: "spawn one agent per slice, wait for all of them, then summarize/synthesize." When the active tool surface exposes direct subagent tools, use those. On the current (V2) surface the names are spawn_agent, send_message, followup_task, wait_agent, interrupt_agent, and list_agents; threads resumed from before the V2 runtime instead expose the legacy V1 set (spawn_agent, send_input, resume_agent, wait_agent, close_agent). Read the live registry and use whichever set is present.

Pick the smallest capable role:

SliceCodex roleNotes
Read-heavy code/data explorationexplorerBest for targeted codebase questions and evidence gathering. Use gpt-5.6-terra (or short-context gpt-5.6-luna) with low reasoning for fast file reads and scans.
General research, docs, MCP/web workdefault or custom docs researcherCodex workers inherit available MCP/tooling. Use a custom agent when the research shape repeats.
Implementation or fixesworkerGive explicit ownership of files/modules and warn that other workers may be active.
Review/security/test-risk auditcustom reviewerUse read-only sandbox and higher reasoning for correctness/security work.
Browser/UI investigationcustom browser debuggerGive browser tooling and ask for evidence, not broad edits.
Verification of important claimscustom verifierGive claim + cited sources, not the generator's reasoning.
Many row-shaped tasksspawn_agents_on_csvExperimental; use one CSV row per work item and require report_agent_job_result.

A missing role is not permission to skip it. Spawning an unknown agent_type fails with an error rather than falling back, and .codex/agents/ roles load only in trusted projects -- so when a custom role you want is unavailable in the active surface, spawn default (or worker/explorer) with that role's instructions inlined in the worker prompt instead of dropping the role.

On GPT-5.6's V2 runtime, inlined role instructions are the primary pattern, not the fallback: custom TOML role routing has been unreliable on Sol/Terra (roles resolving to null, model/sandbox pins ignored -- openai/codex #31814, #32587, #32782; per-spawn model/reasoning_effort overrides return in 0.145+, honored only when the user, AGENTS.md, or skill instructions explicitly request them -- which this skill's routing instructions do). V2 also exposes agent_type only when custom agents are registered. So: put the role in the prompt, state the intended model/effort explicitly per spawn, and treat TOML as optional tuning to re-verify per release rather than required setup.

Route both the model tier and the reasoning effort per slice. The GPT-5.6 family (GA 2026-07-09) is the current default: gpt-5.6 (alias for gpt-5.6-sol, the flagship) for the manager, verifiers, synthesis, and hard slices; gpt-5.6-terra for lighter/faster subagent work (the official Codex guidance) and balanced long-context reads; gpt-5.6-luna as the cheapest option for lightweight, short-context slices -- classification, row-shaped work, small-chunk reads -- but never long-context reads (Luna's recall collapses on 256K+ contexts per OpenAI's MRCR tables; note Codex clients currently treat GPT-5.6 context as 272K anyway, so keep chunks well under that). Spawn caveat: Luna is still on the V1 runtime, so Sol/Terra V2 parents currently cannot spawn Luna children -- Terra is the cheap tier for spawned workers; use Luna from the main thread, codex exec fleets, or CSV fan-out surfaces instead. Terra-vs-Luna is contested among independent evals; the poles are not: lightweight -> Luna, hard/agentic -> Sol. gpt-5.3-codex-spark (research preview) remains the near-instant text-only option, and gpt-5.5 / gpt-5.4-mini remain available as older fallbacks.

Effort ladder (model-dependent at both ends): none, minimal, low, medium, high, xhigh, max, plus ultra as a Codex product setting (not an API effort) that runs max with proactive multi-agent (~4 parallel agents, roughly 3-4x single-agent cost; Plus+ plans; Codex warns about its concurrency). Use low/medium for scouting and all-around research, high for coding and verifying, xhigh/max for orchestration, deep problem solving, and pre-fan-out synthesis; escalate a stuck high-stakes slice to Sol at max before considering ultra (which also flips delegation to proactive -- see the native-delegation note above). The live per-spawn field is reasoning_effort; the config / custom-agent TOML key is model_reasoning_effort -- set effort on each worker, not only in config. On 0.144.x the V2 per-spawn model/reasoning_effort overrides were hidden (children silently inherited the parent's model and effort); 0.145+ exposes them by default, honored when the user, AGENTS.md, or skill instructions explicitly request routing. Overrides work only on fresh-context spawns -- full-history forks always inherit. Verify what actually ran: children inheriting the wrong model/effort was the top July-2026 failure mode, so check each worker's reported model/effort (or judge by output quality) instead of trusting the requested settings. Speed tier is a user preference: honor /fast / service_tier if the user enabled it and don't force it; honor any model/effort the user named, and if a requested model is unavailable, say so rather than substituting.

Step 3 - Collect and Verify Handoffs

Codex handles spawning, routing follow-ups, waiting, and closing in the manager workflow. Current docs say when many agents are running, Codex waits until all requested results are available and returns a consolidated response.

Completion gate first: check every handoff off against the wave manifest - N spawned means N accounted for. A worker that never returns, errors out, or comes back partial/blocked is a hole in the wave. Worker failure ladder: (1) re-task once, narrower -- steer or continue the same worker (V2: send_message to pass info without triggering a turn, followup_task to assign a new turn; legacy V1 threads: send_input, resume_agent) when the slice just needs continuation, or re-spawn fresh with a narrower scope and a note about what came back. Re-task the same worker only for continuation of its own slice -- it keeps its prior context, which contaminates an unrelated assignment; (2) if it fails again, do that slice in the manager thread; (3) if it stays blocked, carry the slice into the synthesis explicitly as not-covered - never average over a missing slice as if coverage were complete.

Avoid manual polling loops. Continue non-overlapping local work while workers run; wait only when synthesis is blocked on their results. For each handoff:

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
129
Forks
19
Last commit
Jul 2026
Advanced
Catalog kind
skill
Gateway key
waves-codex
Source
github.com/rayfernando1337/rayfernando-skills