| name | dispatch |
| description | Orchestrator-only main thread for coding work: delegate to codex, require separate Claude adversarial review, run a /loop watchdog, handle git/gh plumbing. Use for engineering-manager delegation of coding work. |
/dispatch: engineering-manager orchestration
The main thread is orchestrator only. Codex implements, a separate Claude subagent reviews adversarially, and the main thread runs git/gh plumbing plus the watchdog.
Role
- Never edit project source, tests, plan docs, or seed data directly. All of those go through
codex:codex-rescue via Agent with run_in_background: true.
- Reading for orchestration is fine:
git status, git log, git diff, gh pr view, file probes, occasional Read.
- Git, gh, and npm verification commands run on the main thread.
- Memory writes (under
~/.claude/projects/...) are main-thread work, not project files.
If the user asks to "just edit the file" or "skip codex, this is small", push back briefly and offer to delegate. Only edit project files directly with explicit user approval that overrides this rule.
Before the first delegation, establish the operating envelope:
- Repo/worktree. Exact working directory, branch, base branch, current
HEAD, and whether the user expects a PR or only local commits.
- Cleanliness.
git status --short. If there are user changes, isolate with a worktree or brief codex with exact ownership boundaries. Do not let codex "clean up" unrelated files.
- Existing automation. Check for active agents,
/loop jobs, or previous dispatch sessions touching the same branch/worktree. Reuse or stop the old loop before starting another.
- Definition of done. Acceptance criteria, required verification commands, PR readiness expectations, explicit non-goals.
- Project rules. Project memory,
CLAUDE.md, ticket text, PR template, or implementation guidance that will materially change the brief.
Anti-patterns:
- Starting codex with "fix this" and no working dir, branch, scope, acceptance criteria, or exact verification commands.
- Two codex implementations in the same worktree without disjoint file ownership and an explicit merge plan.
- Treating codex's self-critique as the adversarial review gate.
- Staging with
git add -A, committing unrelated user changes, or hiding interleaved work in one commit.
- Asking codex to push, merge, mark a PR ready, or bypass hooks with
--no-verify.
- Rearming a new watchdog while an old one can still tick on the same branch.
- Letting tick summaries become narrative logs. The loop advances state or reports a blocker, not chat.
Pipeline state machine
For each non-trivial task, drive these stages explicitly:
- codex_running: codex implements in the background.
- review_running: a separate Claude subagent reviews the codex commit adversarially.
- push: main thread commits (if codex EPERMed) and pushes.
- done: CI verified; watchdog stopped.
Do not enter review_running until there is a local commit (or a clearly documented no-code result). If review finds blockers, return to codex_running for a new correction commit; do not amend the previous commit. Track the round number in tick prompts so "round 2" does not accidentally review the old SHA.
Delegating to codex
Agent({
subagent_type: "codex:codex-rescue",
run_in_background: true,
description: "...",
prompt: "..."
})
Brief codex with:
- Self-contained context. Working dir, branch, base branch, latest commit SHA, today's date, issue/PR/ticket links, and the relevant user ask copied verbatim. Codex cannot see prior conversation.
- Goal and acceptance criteria. The user-visible or developer-visible outcome that must be true when done.
- Scope. What is in, what is out. Files codex may touch, files it must not, and any existing user changes it must preserve.
- Local conventions. Project memory,
CLAUDE.md, PR template, package manager, branch naming, schema generation, migration rules, or other repo-specific constraints that affect the implementation.
- Use its own subagents. Tell codex explicitly: "Use your own subagents / parallel-task capabilities to decompose work where useful, and run a self-critique pass before reporting."
- Verification. Prefer exact commands discovered from the repo, e.g.
pnpm lint, pnpm format:check, pnpm test -- <path>, pnpm build. If only generic commands are known, say they are expected checks and codex should map them to the repo's scripts.
- Commit instructions. New commit, don't amend, don't
--no-verify, HEREDOC message. If git EPERM blocks (codex's sandbox sometimes locks .git/index.lock), leave changes in working tree and the orchestrator will commit using codex's proposed message.
- Failure policy. If blocked by missing env, failing pre-existing tests, or unclear product behaviour, stop and report the smallest concrete blocker instead of guessing.
- Handoff report. Require commit SHA (or explicit EPERM/no-commit status), changed files, verification commands/results, known risks, and the proposed commit message if codex could not commit.
- Don't push. Orchestrator pushes after review. Codex's sandbox usually cannot reach GitHub anyway.
Prompt skeleton:
Codex task: <one-line outcome>
Working dir: <absolute path>
Branch/base/current HEAD: <branch> / <base> / <sha>
Today: <yyyy-mm-dd>
Context:
- <ticket/user ask/why this matters>
- <relevant project rules or files>
Scope:
- In: <files/behaviour>
- Out: <non-goals>
- Preserve: <existing dirty files or user-owned changes>
Acceptance criteria:
- <observable result>
- <edge case>
Verification:
- Required: <exact commands>
- Targeted: <exact commands>
Git:
- Create a new commit; do not amend; do not push; do not use --no-verify.
- If EPERM blocks git, leave the tree as-is and report the proposed HEREDOC commit message.
Report:
- Commit SHA or EPERM status
- Changed files
- Verification results
- Risks/follow-ups
EPERM commit fallback
Known failure mode: codex may finish edits and verification, then fail to create or update .git/index.lock with EPERM during git add or git commit.
Pick up from the main thread when either condition is true:
- Codex explicitly reports EPERM or sandbox denial on
.git/index.lock, git add, or git commit.
- The
codex-rescue wrapper has returned, but uncommitted changes remain and two consecutive watchdog ticks show no file mtime changes, no diff-stat changes, and no active codex/test/build process in the target worktree.
Do not use a raw "4 minutes elapsed" rule on its own. Four minutes is just two 2-minute ticks; it is only enough when the diff is stable and no process is still working. If the wrapper returned early while a codex CLI, package manager, test runner, or build command is still running, stay in codex_running.
Fallback steps:
- Run lint, format:check, test, build to verify clean.
- Stage the specific files codex touched (avoid
git add -A). If the touched set overlaps unrelated user changes or another codex session, stop and ask.
- Commit using codex's proposed message verbatim (HEREDOC).
- Continue to review stage.
If .git/index.lock exists, never remove it while any git/codex/test/build process is active. If no related process exists and the lockfile is stale across two ticks, remove it once and retry the exact git command. If the lock returns or ownership is unclear, escalate instead of looping.
Adversarial Claude review
After codex's commit lands locally, before pushing, spawn a separate reviewer:
Agent({
subagent_type: "general-purpose",
run_in_background: true,
description: "Adversarial review of <commit>",
prompt: "..."
})
Brief reviewer with:
- Exact commit SHA:
git show <sha>, git diff <base>..<sha>.
- Claimed scope: what codex says it did, copied from codex's report.
- Adversarial framing: "Hunt bugs, edge cases, regressions, behavioural drift. Don't rubber-stamp."
- Specific risks: edge cases worth probing for this change.
- Out of scope: files intentionally untouched, so review does not invent scope creep.
- Verification: reviewer runs the exact lint/format/test/build commands itself; doesn't trust codex's claim.
- Report format: verdict (
BLOCKERS_FOUND / NITPICKS_ONLY / CLEAN), blockers, nitpicks, verification results, what was actually checked.
The reviewer must be a separate Agent invocation for the dispatch gate. Codex self-review is preflight only: codex is defending its own patch and shares its blind spots. If the user explicitly downgrades the task to an inline/tiny edit, exit dispatch rather than pretending codex self-review satisfied this gate.
External CLI reviews
After the Claude adversarial reviewer returns NITPICKS_ONLY or CLEAN, run two more reviews in parallel before pushing:
# from the worktree root, both backgrounded so they run in parallel
codex review --base main
coderabbit review --plain --type committed --base main
The Claude reviewer is the gate; these two are independent second opinions (CodeRabbit is good at policy/style/security drift, Codex CLI tends to spot regressions in adjacent code paths the brief did not name). Run them only when there is at least one local commit on the branch, and run both at once so the wall-clock cost is one review's latency.
Aggregating:
- Any
[P0] / [P1] from either tool is a blocker. Loop back to codex with the exact wording, like a Claude blocker round.
[P2] and below are nitpicks. Default to push and surface them; fold them in only if they materially affect the user-visible deliverable.
- "No findings" / clean from CodeRabbit is informational, not authoritative. It does not override a Claude blocker.
When folding in an external-review finding, make a NEW commit (still no amend, still HEREDOC message) and re-run the verification commands. A small mechanical fix-up driven by an external CLI finding doesn't need a fresh Claude review, but if the change touches new files or new behaviour, spawn one.
CodeRabbit needs network and an authenticated session; if it errors with auth, surface and skip rather than blocking the dispatch.
Watchdog loop
When work is in flight, arm a 2-minute /loop watchdog:
CronCreate({
cron: "*/2 * * * *",
recurring: true,
prompt: "<tick prompt>"
})
Tick prompt template (adapt the task description per call):
Watchdog tick: <task description>.
State carried forward:
- worktree: <absolute path>
- branch/base: <branch> / <base>
- stage: <codex_running|review_running|push|done>
- round: <n>
- codex agent: <description/id if available>
- reviewer agent: <description/id if available>
- last observed HEAD: <sha>
- last observed diff stat: <stat or none>
- PR: <number/url or none>
Pipeline stages: codex_running → review_running → push → done.
Each tick:
1. Inspect transcript, active processes for this worktree, file mtimes, `.git/index.lock`, `git status --short`, `git rev-parse HEAD`, and diff stat for current stage.
2. Advance:
- codex wrapper returned but codex/test/build process still active OR diff still changing → stay `codex_running`.
- codex produced a new commit → capture SHA, run targeted sanity checks if needed, spawn Claude review.
- explicit EPERM OR two stable ticks with uncommitted codex changes and no active process → run lint/format/test/build, stage only codex-touched files, commit on codex's behalf using codex's proposed message, spawn Claude review.
- uncommitted changes overlap user files or another codex session → stop advancing and surface collision.
- review done with blockers → re-delegate to codex with exact blocker text and current SHA; require a new commit.
- review done CLEAN or NITPICKS_ONLY → kick off `codex review` and `coderabbit review` in parallel (background bash). Stay in review until both return.
- external CLI reviews returned with `[P0]` / `[P1]` findings → treat as blockers, re-delegate to codex.
- external CLI reviews returned with `[P2]` or no findings → push by default, surface all blockers/nitpicks/Pn findings in the summary, unless the user gave a standing rule to fold them in before push.
- push/CI finds a generated lockfile or dependency metadata mismatch → allow one codex fix round and one CI rerun; repeated lockfile churn becomes a blocker for the user.
- push done and CI green or queued → CronDelete this loop, post one-line summary. NO auto-merge.
3. Output ONE line per tick: `[HH:MM] stage=<stage>, action=<action_or_none>`.
4. If a stage is stuck >12 min (≥6 ticks) with no observable progress, surface a short blocker note to the user.
Use CronList to find this loop's job ID when ready to CronDelete.
End the loop (CronDelete) when push completes and CI is green or queued, when the user signals stop, or when a stage has been stuck >20 min after multiple unsuccessful retries (escalate to user, then stop). Do not start tend-pr or another dispatch watchdog for the same PR until this loop is deleted.
Surfacing to the user
- Tick output: one line per tick. Don't narrate polls beyond the one-liner.
- Between substantive moments: brief sentence updates ("codex returned, spawning review", "review found 1 blocker, re-delegating").
- After review: surface verdict with blocker count and nitpick count. Blockers always loop. Nitpicks are pushable by default; ask before folding them in only if the user gave that preference or the nitpick is really a disguised blocker.
- Before merge: always ask explicitly. Default to no-auto-merge.
- Final summary: one or two sentences when the loop ends: what shipped, where the artefacts are, any follow-ups.
- If interrupted: tell the user the current stage, branch, commit/PR if any, and whether a background agent may still be running before switching context.
Rounds and iteration
When review returns blockers:
- Re-delegate to codex (background) with the specific blockers plus the reviewer's exact wording.
- New commit (don't amend).
- New review pass on the new commit.
- Repeat until verdict is
NITPICKS_ONLY or CLEAN.
Before each new round, confirm the previous codex process is no longer writing and the worktree has no unrelated changes. The correction brief should include the blocker text, the current HEAD, what changed in previous rounds, and an explicit "do not rewrite unrelated earlier work" instruction.
When review returns nitpicks only: push, surface nitpicks. If the user wants them addressed, frame the next round explicitly as "consider each: accept and action OR push back with rationale". A nitpick is not automatically a fix-it; codex should weigh each.
Demo recording handoff
Sometimes the user wants a video demo of the user-visible change ("record a video", "make a demo", "capture before/after"). This is opt-in and runs after CI is green, not as a default step.
Two paths, pick the one that matches the demo:
Path A: Programmatic via Playwright. When the demo is deterministic and headless-safe (paste content, wait, screenshot/record), write a self-contained .mjs that imports chromium from the repo's playwright install, opens a recordVideo context, drives the dev server, then renames the resulting webm into ~/Downloads/<feature>-demo.webm. Spin up a separate nex pane for npm run dev:app (the dev-server pane) so the recording pane is free to run node /tmp/<script>.mjs. Wait for curl -fsS http://localhost:5173 to return 200 before recording. Foot-gun: zsh has read-only shell variables ($status, $RANDOM, $SECONDS, $EUID), use http_code, ready, etc. instead.
Path B: Codex desktop handoff. When the demo needs real computer-use (theme toggles, real cursor movement, region selection, OS-level recording tools), the CLI codex agent in a nex pane is too restricted. Stop the pane task, then hand the user a self-contained prompt to paste into the Codex desktop app, which has computer-control tools. Brief codex desktop like a fresh subagent: working dir, branch, dev-server URL (already running in your dev-server pane), exact content to paste, the visual outcome to verify, and the absolute output path under ~/Downloads. State explicitly "do not modify the repo, the dev server, or the branch state".
In both paths:
- Always start the dev server in its OWN nex pane, not in the recording pane. The recording pane needs a free prompt.
- Keep the worktree in place until the recording is verified saved (
ls -la <path> non-empty); don't git worktree remove early.
- Print the absolute path and size of the resulting file in your final summary so the user can click through.
If the recording fails or the user takes over manually, drop the autopolling and let the user signal completion. Don't loop on ~/Downloads waiting.
Companion skills
git-commit: generate a conventional commit message from the diff. Useful when codex EPERMs and its report doesn't include a message.
gh-pr: generate a PR description when opening a new PR.
tend-pr: keep a single PR green until merge. Complementary to dispatch when the work is rebases/CI babysitting rather than fresh implementation.
bk-buildkite: inspect Buildkite builds, jobs, and logs when CI status is too coarse from gh pr checks.
github:gh-fix-ci: diagnose GitHub Actions failures when CI repair becomes the primary task. Use intentionally; do not let watchdog retries become an unbounded fix loop.
reviewing-branch-changes: borrow review heuristics and output shape for the separate Claude reviewer. Do not substitute it for the required separate Agent invocation.
nex: split panes for the dev-server and demo-recording handoff steps; cxd alias delegates a task to a live codex CLI pane.
yadm-sync: sync dotfiles when this skill itself, memory entries, or other ~/.claude/~/.config content is updated. It usually does not belong in product-repo dispatch work.
What lives where
| Where | What |
|---|
| This skill | Universal pattern: roles, pipeline, EPERM fallback, watchdog template, briefing requirements. |
Per-project memory (~/.claude/projects/.../memory/) | Branch naming, CHANGELOG conventions, required PR labels, dev paths, project-specific "do this / don't do that" rules. |
CLAUDE.md | Project-specific guardrails the project author wants every assistant to see. |
Stop conditions
End the dispatch session when:
- Push complete and CI is green (or queued and reasonable to leave).
- User explicitly stops the work. Delete the watchdog first, then report any background agents that may still be running and the current worktree state.
- User asks to switch tasks. Pause or end the current dispatch cleanly:
CronDelete, summarise branch/stage/commit/PR/uncommitted state, and start a fresh dispatch session only after the old loop cannot tick again.
- Stage stuck >20 minutes after multiple unsuccessful retries: escalate to user, then stop.
- Worktree collision: user changes or another agent modifies files in the codex-owned set and ownership is unclear.
- Remote branch drift: someone else pushed to the same branch after dispatch started. Re-read state and ask before force-pushing or overwriting.
- Verification cannot run because the local environment is missing required services/secrets/dependencies and codex cannot provide a deterministic fix.