---
name: delegate-coding-agent
description: "Delegate a long-running, multi-file code-modification task to an external coding-agent CLI (OpenCode, Codex, Claude Code, etc.) and verify the result. Covers prompt design, output capture during slow runs, mid-task kill-and-resume, and independent verification of subagent output. Load when handing a substantial coding task to OpenCode / Codex / Claude Code rather than writing code yourself."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
  hermes:
    tags: [coding-agent, delegation, opencode, codex, claude-code, long-running, verification]
    related_skills: [opencode, codex, claude-code, simplify-code, requesting-code-review]
---

# Delegate a Coding Task to an External Agent

Hand off a substantive code-modify task to a long-running external coding-agent CLI (OpenCode, Codex, Claude Code) when the work is bigger than what you'd type inline — multi-file refactors, feature additions spanning existing modules, large test suites. Drive the agent through the terminal with background processes; do not try to write the code yourself.

## When to Use

Use when the user asks to delegate to an external coding agent:
- "use opencode to ..." / "让 opencode 改 ..."
- "ask codex to fix X" / "用 codex 审一下这个 PR"
- "have claude-code refactor Y"
- "delegate a long refactor / feature / test expansion to an agent"

Generally worth delegating when:
- The task spans 3+ files
- It needs planning across an existing codebase (writing the prompt itself takes effort)
- The agent can iterate on tests / type-check feedback without you in the loop
- The task would exceed the context you'd otherwise need for the same change

It is NOT worth delegating when:
- It's a single-file, <50 line edit
- You know the exact change to make and it's faster to write it
- The user wants to learn / understand the code rather than change it
- The repo is not a git repo and you don't want to make one

## What This Skill Adds Beyond the Per-Tool Skills

Read the per-tool skill first — it has CLI-specific details:

| Skill | What it covers |
|-------|----------------|
| `opencode` | OpenCode CLI specifics: `run`, TUI, model flags, format |
| `codex` | OpenAI Codex CLI specifics: `exec`, sandbox flags, git-repo requirement |
| `claude-code` | Anthropic Claude Code: `-p` print mode, `--bare`, hook configuration |

These cover the *mechanics*. This umbrella covers the **work pattern that holds across all three** — the things every delegation shares:

1. **Choosing the model for the task class**
2. **Prompt engineering for coding agents** (so they don't wander off-spec)
3. **Output capture during long runs** — silent stdout is the #1 trap
4. **Mid-task kill + resume across runs** — when you switch models or extend timeout
5. **Independent verification** — subagent output is a self-report, not a fact
6. **Reading the resulting git diff** before declaring the task complete

## Procedure

### 1. Pick the substrate

Match the task to a tool:

| Tool | Strengths | Avoid when |
|------|-----------|------------|
| OpenCode (`opencode run`) | Provider-agnostic; supports many models via `opencode/`, `myrelay/`, etc.; `--format default` shows edits inline | Need OAuth-gated models (Claude / GPT) you can't get through your gateway |
| Codex (`codex exec`) | Strong at editing inside an existing git repo with full repo context; `--full-auto` is convenient | Running outside a git repo (create `mktemp -d && git init` if scratch) |
| Claude Code (`claude -p`) | Strong at reasoning-heavy tasks, can use full flag set incl. `--json-schema`, `--fallback-model` | Sandbox issues; sub-tasks where you want zero permission prompts (use `-p` mode) |

### 2. Pick the model

This is where practice matters more than instinct. As of mid-2026:

- **Reasoning-heavy refactors across a whole codebase** → use a top model (`myrelay/GLM-5.2`, `claude-opus-4-8`, `gpt-5.5`, etc.). 1M-context class models (GLM-5.x, Gemini) are oversized for tiny tasks but pay off when the diff spans 8+ files.
- **Single-file edits, focused bug fixes** → faster small models (`claude-haiku`, codex-mini, deepseek-flash).
- **Long-running codex / opencode jobs in tight budgets** → flash / mini class for cost control.

If you don't know what's available: `opencode models`, `codex --help`, or check your provider's model list.

### 3. Write the prompt — explicitly enumerate what's done, what isn't

A code-agent prompt is **not** a chat message. The agent has no shared context with you; it only sees the prompt and whatever files `Read`/filesystem access yields. A well-shaped prompt contains:

```
# Task (or "Task RESUME — earlier run did 70%")

## What I want
[1-3 sentences stating the goal]

## Constraints
- "no new dependencies"
- "no default API key in the example"  
- "use the existing dataclass pattern from quota.py"

## Files I want changed
- /path/to/a.py — modify per the spec
- /path/to/b.py — modify per the spec
- /root/QuotaHub/config.json.example — additive only

## API / schema details (verbatim, not paraphrased)
[field names, endpoint URLs, status code meanings]

## Naming choice
[explicit case — e.g., "keep `MiniMax` non-standard casing"]

## What NOT to do
- "Don't add a real default key"
- "Don't rewrite files I didn't list"

## Output
[A list of artifacts to print at the end — files modified with line counts, test results, etc.]
```

For resume prompts, additionally:

```
## Context: partial work already done
- ✅ /root/proj/backend/app/foo.py — FULLY IMPLEMENTED. Don't rewrite.
- ✅ /root/proj/backend/app/config.py — partial:
  - Added BarConfig dataclass at L28-33
  - NOT YET DONE: parse_config still does not call _parse_bar_accounts()
  - NOT YET DONE: AppConfig() at L154-161 missing BarConfig field
- ❌ /root/proj/backend/app/main.py — UNTOUCHED. Add the endpoint here.

## What I need from you
1. Wire BarConfig into parse_config + AppConfig constructor
2. Add new endpoint to main.py
3. Add BarConfig to config.json.example (empty array)
```

Listing each file with explicit "done vs not done" prevents the agent from rewriting correct files (regression) and lets it focus on remaining work.

### 4. Launch in background, capture stdout to a log file

**Critical pitfall.** `opencode run "..." | tail -N` swallows intermediate output until exit. The agent may take 30-180s on multi-file rewrites; without `tee` to a log file, you stare at a silent process and conclude it's hung.

```bash
# BAD — silent until exit, looks hung
opencode run '...refactor X...' | tail -100

# GOOD — full transcript + observable progress
terminal(command="cd /path/to/project && opencode run -m myrelay/GLM-5.2 \
  --dir /path/to/project --format default \
  '...' 2>&1 | tee /tmp/agent.log | tail -400",
  background=true, notify_on_complete=true, timeout=1800)
```

Then `tail -50 /tmp/agent.log` shows progress at any time, and `process(action='log', session_id=...)` returns the full log.

**Use `--format default` (not `json`) for human supervision.** Default shows `→ Read foo.py`, `← Edit bar.py`, `$ pytest` inline — exactly the level of detail you want.

### 5. Don't kill on empty 30s stdout

Multi-file code rewrites routinely take 60-180s before any output appears (the agent is reading the project layout, planning, then writing). Before killing:

```bash
ls -la /tmp/agent.log                                # how big is the log
find /path/to/project -type f -newer /tmp/opencode_start_marker | head
ps -p $(pgrep -f "opencode run" | head -1) -o pid,etime,stat,cmd
```

If the log has grown or files have been written, the agent is working. Wait at least 2 minutes before suspecting a hang.

### 6. Inspecting what the agent has done (when stdout is silent)

Five reliable signals, in order of value:

```bash
# 1. mtime — files written since the run started (NEWEST PROJECTS ONLY — repos with active editors will lie)
find /path -type f -newer /tmp/baseline_marker 2>/dev/null | grep -v ".git" | head -30

# 2. git diff — shows what the agent modified vs the last commit
git -C /path diff --stat
git -C /path diff --stat HEAD

# 3. ls by mtime — sorted newest first
ls -lat /path/to/project | grep -v "^total" | head

# 4. Files in temp/staging areas opencode may use
find /path/temp /path/.git -newer /tmp/baseline_marker 2>/dev/null | head

# 5. The agent's own log (if running with tee)
tail -100 /tmp/agent.log
```

### 7. Mid-task kill + resume (the model-switch pattern)

If you need to switch models mid-task (user changed mind, you picked wrong, timeout, rate limit) OR you need to extend a run that was over-budget:

```bash
# 1. Capture state
find /path -type f -newer /tmp/baseline_marker 2>/dev/null > /tmp/files_changed.txt

# 2. Read each touched file to understand current state
# 3. Compose a RESUME prompt (see §3 above) listing what is done
# 4. Kill the running process
process(action='kill', session_id=...)

# 5. Launch the new run
opencode run -m myrelay/GLM-5.2 --dir /path "$(cat /tmp/resume_prompt.md)"
```

Do NOT pretend the new run inherits the previous run's memory. It does not. The new agent will discover partial state, but only if you point it out.

**Reverse:** if you realize mid-run that you want to *continue* the same agent's session rather than restart, every code-agent CLI has a resume mechanism:

- `opencode run --continue` or `--session <id>`
- `codex exec` (no resume for one-shots — must restart)
- `claude -p --resume <id> --fork-session` (fork for safety; resume in-place keeps same session id)

### 8. Independent verification — DO NOT trust the agent's "Done."

The agent's final message ("Done. 4 files modified, +95/-4 lines.") is a **claim**, not a fact. Verify yourself:

```bash
# 1. The diff is what was intended
git -C /path diff --stat
git -C /path diff -- <expected files>

# 2. Each touched file actually compiles/parses
python -m py_compile backend/app/foo.py backend/app/bar.py
go build ./...
npm run type-check
tsc --noEmit

# 3. Smoke-import the new module to catch syntax errors hidden in py_compile (rare)
python -c "from app import foo; print(foo.__name__)"

# 4. Re-run existing tests for the affected area
python -m pytest backend/tests/test_quota.py -q
go test ./pkg/x/...
npm test -- --testPathPattern=fizz

# 5. Function-level checks for the spec's exact requirements
python -c "
from app.config import parse_config, mask_minimax_key
raw = {'MiniMax_accounts': [{'name': 'A', 'api_key': 'sk-1234567890abcdef'}]}
cfg = parse_config(raw)
assert cfg.minimax_accounts[0].name == 'A'
assert mask_minimax_key('sk-1234567890abcdef') == 'sk-1…cdef'
print('OK')
"
```

This last step (`python -c "..."` smoke) is the only way to verify the agent wired something correctly. py_compile catches syntax; smoke catches wiring. Skip it at your peril — the agent will claim completion either way.

### 9. Report to the user

Concretely. Not "the agent finished." State:

- **Files changed:** list with absolute paths, plus `git diff --stat` line counts
- **Verification results:** "py_compile exit 0", "pytest N passed", "mask_minimax_key() smoke returns expected"
- **Deviations from spec:** if the agent's diff doesn't match what you asked for, name them
- **What was NOT changed:** confirm no spurious changes landed elsewhere (`git status`)

## Pitfalls

- **`opencode run | tail -N` without `tee`** — silent until exit. Always pipe through `tee /tmp/agent.log`.
- **Don't kill runs on empty 30s stdout** — long rewrites take 60-180s. Inspect log + mtime first.
- **Subagent output is a self-report** — verify with `py_compile`, `git diff --stat`, and a smoke import.
- **Always set `workdir` / `--dir`** — unconstrained agents wander. Git-rooted repos help.
- **Specify which model and provider prefix** — `myrelay/GLM-5.2` is meaningful; `claude-sonnet` is not, if your provider has multiple aliases.
- **When the user names a wrong/non-existent project (e.g., 'openroute')**, ask before deploying — don't fabricate a target.
- **Resume prompts MUST enumerate state** — "the new model does not know what the old model did." Use `find -newer` to inventory.
- **Mid-task output is the only progress signal** — make sure `/tmp/agent.log` is being written before you trust the run is healthy.
- **Don't ask for too many goals in one prompt** — split if the spec is huge; one focused task beats one sprawling one.
- **Avoid sharing one working directory across parallel agent sessions.** Different worktrees, mktemp dirs, or `--dir` values per process.
- **Don't auto-restart on user mid-run model swap.** Wait for the user's explicit instruction. They may have a different intent (e.g., swap to verify the previous model was actually wrong).
- **Late-arriving SIGTERM notifications are noise, not signals.** When you `process(action="kill")` a backgrounded coding-agent run, the runtime often emits `[IMPORTANT: Background process X terminated by process.kill (exit code -15, SIGTERM)]` minutes or hours later — sometimes after you've already moved on. These are NOT a new problem to investigate and NOT a signal that the work failed. Verify against the actual files on disk (`git diff --stat`, `find -newer`). If the diff matches the spec, the work is done; if it doesn't, dig into the codebase yourself. The late SIGTERM message is the runtime catching up with bookkeeping, not a state change you can act on.

## Reusable Templates

Save these to `~/templates/` after first success — every agent prompt looks roughly the same:

- `prompt-skeleton.md` — task + constraints + files + naming choice + output
- `prompt-resume-skeleton.md` — adds "Context: partial work already done" section
- `python-verify-skeleton.py` — `py_compile` + smoke-import + targeted pytest

See `references/` for the full patterns with worked examples.

## Support Files

- **`references/opencode-worked-example.md`** — measured session (2026-07-05 QuotaHub MiniMax rewrite): how `tail -N` silent-output swallowed a healthy run, how a mid-task model swap caused a partial-state problem, and the resume-prompt pattern that recovered.
- **`templates/prompt-skeletons.md`** — copy-paste templates for fresh prompts, resume prompts, and the post-task Python smoke-verification block.
- **`scripts/verify-agent-output.sh`** — runnable verifier: `git diff --stat` + `python -m py_compile` + smoke-import + default-secret regex against `*.example` / `*.template` files. Use after any agent claims "Done."

## Related

- `opencode` — the per-tool skill for OpenCode CLI specifics
- `codex` — per-tool skill for OpenAI Codex CLI specifics
- `claude-code` — per-tool skill for Anthropic Claude Code CLI specifics
- `simplify-code` — the *review* pattern, complementary to this delegation pattern
- `requesting-code-review` — pre-commit review gate; useful *after* an external agent's diff, before merging
