(ywc) Use when multiple independent tasks from tasks/ can run simultaneously and the user wants faster execution via Git Worktree isolation. Triggers: "병렬 실행", "parallel execute", "parallel-executor", "agent executor", "동시 실행", "워크트리 실행", "execute tasks in parallel", "run tasks simultaneously", "並列実行", "並列ワークフロー". Do not use for strictly sequential tasks (use ywc-sequential-executor), single-task execution, or when no dependency-graph.md exists.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add yongwoon/ywc-agent-toolkit --skill ywc-parallel-executor --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Ywc Parallel Executor?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/yongwoon-ywc-parallel-executor-ywc-agent-toolkit)More formats (shields.io, HTML) on the badges page.
---
name: ywc-parallel-executor
description: >-
(ywc) Use when multiple independent tasks from tasks/ can run simultaneously and the user wants faster execution via Git Worktree isolation. Triggers: "병렬 실행", "parallel execute", "parallel-executor", "agent executor", "동시 실행", "워크트리 실행", "execute tasks in parallel", "run tasks simultaneously", "並列実行", "並列ワークフロー". Do not use for strictly sequential tasks (use ywc-sequential-executor), single-task execution, or when no dependency-graph.md exists.
---
# ywc-parallel-executor (Parallel Executor)
**Announce at start:** "I'm using the ywc-parallel-executor skill to run independent tasks concurrently in isolated worktrees."
> Worktree lifecycle is owned by the dedicated `ywc-worktrees` skill (priority resolution + `--mode create` / `audit` / `prune` / `resolve`). This skill delegates worktree creation, audit, and cleanup to `ywc-worktrees` instead of inlining the procedures. See `ywc-worktrees` for the four-mode contract and the priority chain (`.worktrees/` > CLAUDE.md `worktree_root` > caller-specified > legacy fallback). The bundled `audit-worktrees.sh` / `cleanup-worktree.sh` scripts have moved to that skill.
Executes tasks generated by task-generator in parallel using agents.
## Rationalization Defense
When tempted to skip a step, check this table first:
| Excuse | Reality |
|---|---|
| "Tasks look independent, run all in parallel" | Run only tasks whose Ownership and Shared Surfaces do not overlap. Shared Surfaces include public contract names, not just file paths. Dependency-graph.md is the source of truth. |
| "Wave 1 had a partial failure, start Wave 2 anyway" | Wave boundary is a hard gate. All Wave N tasks must succeed before Wave N+1 starts. |
| "Worktree cleanup is manual hassle, skip it" | Stale worktrees corrupt subsequent runs. Always cleanup after each task completes via `ywc-worktrees --mode prune` (see `ywc-worktrees`). |
| "Conflicts With is just a hint" | If two tasks declare Conflicts With each other, they cannot run in the same wave even if dependencies allow. |
| "Task category does not match any specialized agent, skip the assignment" | Default to executor agent. Never silently drop the task. |
| "Mid-wave one task is slow, kill it and continue" | A killed task leaves a dirty branch. Stop, report, and let the user decide. |
| "--draft creates PR at the end, bot review can wait until un-draft" | Bot review bots (CodeRabbit, Codex Review, Claude Review) post on draft PRs immediately. After creating the draft PR in Step 5, poll for reviews via `../references/pr-bot-polling.md` and invoke `ywc-handle-pr-reviews` as a PR health sweep regardless of `BOT_COUNT == 0`; the handler also checks CI status and merge-readiness. The PR stays draft — responding now avoids a round-trip after un-drafting. |
| "The aggregate draft PR passed CI before bot reviews — re-checking CI after bot fixes is extra work" | Bot review fixes push new commits that trigger a fresh CI run. The pre-bot CI result is stale and does not cover the updated code. Always re-verify CI after pushing bot review fixes on the aggregate draft PR (Step 5). |
| "Last task in the last wave has no downstream wave, skip delivery for it" | Step 4e is unconditional — **every** task in **every** wave, including the last task in the last wave, must complete (a) and (b). The absence of a downstream wave is not a reason to skip delivery. Without delivery (`ywc-finish-branch` for `--local-merge`/`--draft`, or `gh pr merge` + inline Mark Complete for `--per-task-pr`), the implementation code is stranded on an orphaned feature branch, `tasks/completed/` is wrong, and the base branch is missing the work. |
| "All waves done in `--draft` mode — go straight to Completion Report" | For `--draft`, before the Completion Report the aggregate draft branch must be created and pushed (Step 5 pre-report). The run does not end at the last wave's 4i; the Step 5 pre-report steps are required. |
| "`--per-task-pr`: the PR is created, move to the next task" | `--per-task-pr` is now a full-lifecycle mode. Creating the PR is not delivery — you must wait for CI to pass, handle bot reviews, **merge the PR** (`gh pr merge --delete-branch`), sync local base, and commit + push the completion marker, all within the task's slot in the wave (Step 4e (a)+(b)). A created-but-unmerged PR is an incomplete task. |
| "`--per-task-pr`: CI is green, merge the PR" | A sibling task in the same wave may have merged first, leaving this PR `CONFLICTING` or `BEHIND`. Refresh the branch against the latest base (Step 4e (a) step 4, merge-not-rebase per `../references/pr-conflict-resolution.md`) and re-verify CI before `gh pr merge`. A real textual conflict on refresh marks the task `BLOCKED` — never force-merge. |
| "`--aggregate-pr`: the single PR is created, the group is done" | `--aggregate-pr` is full-lifecycle, not draft. Creating the aggregate PR is not delivery — you must mark it ready, wait for CI, handle bot reviews, pass the merge-readiness gate, **merge it** (`gh pr merge --delete-branch`), and sync local base. A created-but-unmerged aggregate PR is an incomplete group. See [references/aggregate-pr.md](references/aggregate-pr.md) §B. |
| "`--aggregate-pr`: re-Mark-Complete the tasks after the PR merges" | Each task's `chore: mark ... as completed` commit already landed on the aggregate branch during its wave (`--defer-push` local merge, same as `--draft`). The aggregate PR merge carries those marker commits into base. Running Mark Complete again would double-move directories. Do **not** re-mark. |
| "Run several `--aggregate-pr` groups in parallel in this one clone" | They share the local `<base>` branch ref, which the `--draft`-style accumulation mutates (`git reset --hard origin/<base>` + per-task merges) — concurrent groups corrupt each other's base accumulation. Parallel groups need **one clone per group** (or run them back-to-back). See [references/aggregate-pr.md](references/aggregate-pr.md) §C. |
| "Use git worktrees to split the parallel groups inside one clone" | Worktrees separate the working tree and the untracked `.ywc-run-state.json`, but **share `.git` refs** — the local `<base>` branch is shared and can be checked out in only one worktree, so the accumulation still collides at the ref layer. Worktrees are not an isolation boundary for this mode; use separate clones. See [references/aggregate-pr.md](references/aggregate-pr.md) §C. |
| "Each wave has one task, so work directly on the aggregate branch" | A fully linear chain is the wrong input for this skill. Stop at Step 2 and route to `ywc-sequential-executor`; never invent an `aggregate-branch-serial` path. |
| "`--aggregate-pr` means commit tasks on the aggregate branch" | `--aggregate-pr` changes only end-of-run delivery. Per-task execution still requires isolated worktree + feature branch + local merge; the aggregate branch is created in Step 5, never used as a task workspace. |
**Violating the letter of these rules is violating the spirit.** Parallel execution is faster only when wave isolation is honored.
## Arguments
| Parameter | Format | Example | Description |
|-----------|--------|---------|-------------|
| Task specifier | `<name>` or `<start>..<end>` | `yk-000001-010..yk-000002-040` | Single task or range. Initials-prefixed, current unprefixed, and legacy numeric forms are accepted; range matching uses phase+sequence order and preserves full task names. |
| `--all` | flag | | Execute all tasks |
| `--tasks-dir` | `--tasks-dir <path>` | `--tasks-dir tasks/` | Tasks directory (default: tasks/) |
| `--review` | flag | | Auto-run ywc-impl-review after each task |
| `--local-merge` | flag | | No PR, merge and push to base-branch directly |
| `--draft` | flag | | Create draft PR after all tasks complete |
| `--per-task-pr` | flag | | Per task: create the PR, wait for CI, handle bot reviews, then **merge the PR** (`gh pr merge --delete-branch`), sync base, and mark complete — the full lifecycle, mirroring `ywc-sequential-executor`'s default `normal-pr` mode |
| `--aggregate-pr` | flag | | Whole invocation → **one** branch + **one** PR. Tasks still run in parallel and accumulate onto a single aggregate branch, then the end-of-run PR is marked ready, CI-verified, bot-reviewed, and **merged**. The full-lifecycle twin of `--draft`. See [references/aggregate-pr.md](references/aggregate-pr.md) |
| `--group-name` | `--group-name <name>` | `--group-name payments` | Names the aggregate branch (`aggregate/<name>`) and disambiguates concurrent groups. `--aggregate-pr` only; defaults to `aggregate/<base-branch>-<timestamp>` when omitted |
| `--pr-lang` | `--pr-lang <en\|ja\|ko\|zh\|es>` | `--pr-lang es` | Preferred PR title/body language for every PR mode; pass explicit values unchanged to `$ywc-create-pr --lang <pr-lang>`. If omitted or `auto`, resolve through [language-resolution.md](../references/language-resolution.md); if no tier resolves a language, interactive runs may ask, while non-interactive runs return `NEEDS_CONTEXT: --pr-lang`. |
| `--non-interactive` | flag | | Never wait for approval, progress, resume, conflict, CI, or URL-policy input; return a bounded terminal status instead. |
| `--resume-disposition` | `resume\|stop` | `--resume-disposition resume` | Required whenever an authoritative checkpoint exists, including when the invocation scope matches. Missing input returns `NEEDS_CONTEXT`; `stop` leaves checkpoint state unchanged. |
| `--terse` | flag | | Compact Completion Report: task table + Completion Status only — no prose reminders, no worktree audit lines, no mode explanations |
`--review` can be combined with other flags.
**Flag conflicts**: `--local-merge`, `--draft`, `--per-task-pr`, and `--aggregate-pr` are mutually exclusive. Interactive runs may ask for clarification; non-interactive runs return `NEEDS_CONTEXT` naming the conflicting mode flags. `--group-name` is valid only with `--aggregate-pr`.
**Default behavior**: When none of `--local-merge`, `--draft`, `--per-task-pr`, or `--aggregate-pr` is specified, interactive runs may ask which mode to use; non-interactive runs return `NEEDS_CONTEXT: --local-merge|--draft|--per-task-pr|--aggregate-pr`. Do not silently default to any mode. Present: `--local-merge` (direct merge/push), `--draft` (single draft PR left open), `--per-task-pr` (full lifecycle PR per task), or `--aggregate-pr` (one full-lifecycle PR for the whole invocation).
**Non-interactive transition contract**: With `--non-interactive`, no branch/worktree conflict, CI wait, resume, or policy branch may open a prompt. Return only `DONE`, `DONE_WITH_CONCERNS`, `BLOCKED`, or `NEEDS_CONTEXT` plus bounded reason/missing identifiers. Branch/worktree conflict is `BLOCKED`; CI timeout is `DONE_WITH_CONCERNS` with `ci_timeout`; missing checkpoint disposition is `NEEDS_CONTEXT: --resume-disposition`. Do not invent a mode, disposition, URL policy, or progress decision.
## Definition of Done
A task is **done** only when **all** of the following have happened, in this order. A task that is "merged but not marked" is **not** done — downstream waves resolve dependencies by reading `<tasks-dir>/completed/`, so a missing move silently breaks the dependency graph for the next wave.
1. The feature branch passed Task Verify (Step 4c) and any optional review (Step 4d).
2. The task was delivered in Step 4e. For `--local-merge`, `--draft`, and `--aggregate-pr`, `ywc-finish-branch` returned `DONE` — that status enforces the merge with post-merge verification and the move of the task directory to `<tasks-dir>/completed/<task-name>` with a `chore: mark <task-name> as completed` commit. For `--per-task-pr`, the PR passed CI, was merged via `gh pr merge --delete-branch`, local base was synced, and the same completion-marker move-commit was made and pushed.
3. For `--local-merge` and `--per-task-pr`: every merge / PR-merge and completion-marker commit was pushed immediately during the wave. For `--draft` and `--aggregate-pr`: the deferred local merge commits accumulate locally and are pushed once at the end of all waves before the Completion Report.
4. The worktree was removed and the feature branch was deleted (Step 4g) — finish-branch leaves the local branch alive when called with `--keep-branch`, which is mandatory in this skill because the worktree owns the branch checkout. Step 4g is therefore the source of truth for branch deletion in parallel execution.
If any of the four is missing, the task is incomplete regardless of how `git log --oneline base-branch` looks. The Wave Delivery + Mark Complete step (Step 4e — `ywc-finish-branch` for `--local-merge`/`--draft`/`--aggregate-pr`, inline `gh pr merge` + Mark Complete for `--per-task-pr`) writes the code and the contract; Step 4g releases the worktree and the branch.
**`--aggregate-pr` group-level done**: in addition to every task satisfying the four conditions above, the **group** is done only when the single aggregate PR has been marked ready, passed CI, cleared bot review, passed the merge-readiness gate, and been **merged** with local base synced (Step 5 + [references/aggregate-pr.md](references/aggregate-pr.md) §B). A run whose aggregate PR is created but unmerged is `DONE_WITH_CONCERNS` at best, never `DONE`.
## Non-Stop Execution Principle
> **Action required before creating any worktree**: Read [`../references/non-stop-execution.md`](../references/non-stop-execution.md) now. It defines the exhaustive allowed-stop list, the force-continue rule, tool permission prompt handling, and the **Tool Error Recovery** policy (how to recover from `Edit`/`Bash` failures without entering extended thinking). Do not defer this read to mid-execution.
Execute all waves without interruption. Do not ask the user for confirmation between waves. The shared rule, full stop list, force-continue rule, zero-output rule, and `--local-merge` rationale live in [`../references/non-stop-execution.md`](../references/non-stop-execution.md).
The unit for this skill is **wave**. The Allowed Stop Reasons that are parallel-specific are:
- Pre-flight failure
- Circular dependency detected
- All tasks in a wave failed
- `git push` rejected by remote
- Merge conflict
The "Zero output between transitions" rule applies to the gap between Step 4g/4h of one wave and Step 4a of the next. Everything else — Force Continue Rule, what *not* to stop for, tool-permission-prompts-are-not-stop-conditions, and the `--local-merge` rationale — is in the reference and applies verbatim.
## Pre-flight
> **Resume check first**: Before running the checks below, look for `.ywc-run-state.json` in the project root. If it exists, follow the **Resume Detection** procedure in [references/checkpoint-resume.md](references/checkpoint-resume.md), including the intent-match guard before offering resume. If the user confirms resume, skip Pre-flight and jump to the saved wave and pending tasks. If the user declines, chooses discard/new run, or there is no state file, proceed with the checks below.
Verify the following conditions before starting:
1. **Clean working tree** — `git status --porcelain` must be empty
2. **On base branch** — Must be on main/develop/master
3. **Tasks directory exists** — `dependency-graph.md` and task subdirectories must be present
4. **gh CLI authenticated** (PR creation modes only) — `gh auth status` must succeed
5. **No stale worktrees from previous runs** — Delegate to `ywc-worktrees --mode audit` before creating anything. This applies the shared priority chain (`.worktrees/` > CLAUDE.md `worktree_root` > caller-specified root > legacy fallback) and reports stale, leaked, or unexpected worktrees:
```text
$ywc-worktrees --mode audit
# exit 0 = clean; exit 1 = stale/leaked/unexpected worktrees detected — details on stdout
```
If exit 1, resolve per worktree listed in the output:
- The task already merged → `git worktree remove --force <path> && git branch -D feature/<task-name>`
- The task has unmerged work → stop and surface to the user; do **not** silently delete in-progress work
Pre-flight must end with exit 0 before Step 1 begins. Starting a new run on top of stale metadata is the most common reason worktrees "leak" — the new run reuses paths and branches the cleanup logic no longer recognises.
**State Init (non-resume runs only)**: Initialize `.ywc-run-state.json` from the computed wave plan, and add it to `.gitignore` if absent:
```bash
grep -qxF '.ywc-run-state.json' .gitignore 2>/dev/null || echo '.ywc-run-state.json' >> .gitignore
STATE_SCRIPT="${CODEX_HOME:-$HOME/.codex}/skills/scripts/update-state.py"
[ -f "$STATE_SCRIPT" ] || STATE_SCRIPT="codex/skills/scripts/update-state.py"
python3 "$STATE_SCRIPT" init-parallel \
--mode <local-merge|draft|per-task-pr|aggregate-pr> --tasks-dir <tasks-dir> \
--waves '[{"wave":1,"tasks":["t-a","t-b"]},{"wave":2,"tasks":["t-c"]}]'
```
The `--waves` array is the wave plan from Step 3 — one entry per wave, `tasks` listing that wave's task-directory names. See the schema in [references/checkpoint-resume.md](references/checkpoint-resume.md).
## Pre-authorizing Tool Permissions (required for multi-wave execution)
The Non-Stop Execution Principle above governs LLM-level pausing, but it cannot override Codex's tool approval layer — every unprompted `git`/`gh`/`mv` command can independently block on user confirmation. In multi-wave execution this is the **single most common reason waves stop mid-run**: each worktree creation, merge, push, and cleanup across multiple tasks triggers an individual prompt.
> **Required for multi-wave execution**: Each wave runs multiple `git` and `gh` commands across multiple worktrees. Without pre-authorization, each command pauses for approval — multiplied across all tasks and waves, this makes unattended execution impossible. Complete this setup before starting.
The fix is a one-time Codex command-approval setup that pre-authorizes a small set of read-only and task-scoped command prefixes. The same permissions are used by both `ywc-parallel-executor` and `ywc-sequential-executor`.
**For the full pattern list, narrow fallback for strict policies, privacy notes, and diagnosis steps when pre-authorization is not enough**, see [../references/local-merge-permissions.md](../references/local-merge-permissions.md).
## Checkpoint and Resume
The executor writes `.ywc-run-state.json` in the project root after each major wave event. If a multi-wave run is interrupted, resume from the last checkpoint: completed waves are skipped and the in-progress wave restarts with only its remaining pending tasks. For the resume procedure, on-disk state schema, checkpoint event table, and manual inspection commands, read [references/checkpoint-resume.md](references/checkpoint-resume.md).
## Context Handoff
After each wave transition, `scripts/transition_safety.py` writes exactly one non-authoritative `.ywc-context-handoff.json` beside root `.ywc-run-state.json`. It is an aggregate cache only: workers never write handoffs, and worker output, peer conclusions, transcripts, or raw tool output never enter it. Checkpoint/task sources remain authoritative.
Writes use a same-directory temporary sibling, `fsync`, rename, and parent-directory `fsync` where supported. Failed, missing, malformed, stale, mismatched, private, or worker-local handoffs preserve checkpoint state and reconstruct from checkpoint, `README.md`, then `task.md`.
## Execution Steps
### Step 1: Parse Dependency Graph
Read `dependency-graph.md` to extract the TaskInfo list. Parse the following from each task:
- Task ID (optional initials + Phase + Sequence; legacy numeric IDs remain valid)
- Task Name (full directory name)
- Category (`db`, `api`, `ui`, `test`, etc.)
- Depends On (predecessor task list)
- Agent Hint (if specified in README.md)
### Step 2: Plan Waves (Topological Sort)
Separate tasks into waves based on dependency relationships:
- **Wave 0**: Root tasks with no dependencies
- **Wave N**: Tasks that become executable after all Wave N-1 tasks complete
- If a circular dependency is detected, stop immediately and report
**Linear-chain guard**: if every planned wave contains exactly one task, stop before worktree creation and route the user to `ywc-sequential-executor` (with `--aggregate-pr` when they want single-PR delivery). Proceed in parallel only after explicit user confirmation; never work directly on the base or aggregate branch.
#### Planning Advisor (optional, Pattern C)
Wave Planning is the critical upfront decision in this skill — a wrong wave boundary cascades into unnecessary serialization (waste) or unsafe parallelism (merge conflicts and broken dependencies) across every subsequent wave. Because the damage is expensive to undo once worktrees and feature branches exist, this is the right place to apply **Pattern C** from [advisor-pattern.md](../references/advisor-pattern.md): a **single** upfront advisor call before worktree creation begins.
**When to invoke**:
- Task count is 4 or more, AND
- At least one of: any candidate wave contains 3+ concurrent tasks; `Conflicts With` declarations exist across the task set; `Shared Surfaces` / public contract names overlap across candidate waves; or the first-pass topological sort produced a wave with mixed categories (e.g., `db` + `api` + `ui` in the same wave).
- **Skip for ≤3 tasks or purely linear task chains** — the topological order is obvious and frontier reasoning adds no value.
**How to invoke**: Spawn one higher-capability advisor subagent. Payload (≤200 lines total):
- Dependency graph excerpt — tasks + `Depends On` + `Conflicts With` + `Shared Surfaces` only; do not forward full task READMEs.
- First-pass wave assignment from your topological sort.
- Category distribution per wave (Backend N / Frontend M / QA K / etc).
Ask the advisor for three things:
1. **Wave boundary confirmation** — does the first-pass assignment group tasks safely, or should any task move to a different wave?
2. **Agent assignment risk** — any task whose Category-based agent assignment is a poor fit (for example, a `refactor` task that is actually a domain logic rewrite in disguise)?
3. **Conflict detection** — any Shared Surfaces the topological sort missed that would cause merge conflicts during Wave Merge (Step 4e)?
**Budget**: exactly **1** advisor call per invocation. Mid-wave escalation is explicitly disallowed — per-wave task agents run in isolated worktrees and handle their own decisions. If the initial wave plan proves wrong during Step 4, stop execution, report to the user, and re-run the skill with refined input rather than calling another advisor mid-flight.
**Advisor output format** (≤300 words):
- Wave boundary verdict (confirm, or specific relocations)
- Agent assignment verdict (confirm, or specific reassignments)
- Conflict warnings (if any, with the affected Shared Surface named)
- Single "proceed" or "reconsider with refinements" verdict
After the verdict, either continue to Step 3 with the adjusted wave plan, or surface the "reconsider" verdict to the user for plan refinement before proceeding.
### Step 3: Assign Agents by Task Category
| Category | Codex worker role | Description |
|----------|-----------|-------------|
| `db`, `api`, `domain`, `lib`, `worker` | Backend worker | Server-side code generation/modification |
| `ui` | Frontend worker | UI component, page generation/modification |
| `test` | QA worker | Test strategy + test code generation |
| `infra` | DevOps worker | CI/CD, deployment configuration |
| `refactor` | Reviewer worker | Code structure improvement |
If an Agent Hint is specified in the task's README.md, it overrides the mapping above.
**Docker Isolation Audit** — After the final wave plan is known and before any worktree creation, audit Docker stacks for every selected task name:
```text
$ywc-docker-isolate --mode audit --expect <comma-separated selected task names>
# exit 0 always; stdout non-empty = residual Docker stacks detected
```
If stdout is non-empty, abort before Step 4 and surface the printed stacks. Remediation is `$ywc-docker-isolate --mode audit --expect <comma-separated selected task names> --prune` only after confirming those task-scoped stacks are stale; otherwise they reuse the same deterministic port blocks and will collide during setup.
### Step 4: Execute Waves in Parallel
Repeat the following for each wave. **Each task must have its own independent worktree and branch** — never execute multiple tasks on a single branch. The worktree model structurally guarantees this, but ensure agents do not work outside their assigned worktree.
**4a. Create Worktrees** — For each task in the wave, delegate creation to `ywc-worktrees` and capture the resolved path it returns. Do not hardcode `../worktree-*`; projects may use `.worktrees/`, CLAUDE.md `worktree_root`, or another caller-provided root.
```text
$ywc-worktrees --mode create \
--task-name <task-name> \
--branch feature/<task-name> \
--base-branch <base-branch>
```
Record the resolved worktree path for the subagent payload. Record the resolved root (`worktree_root`) and root kind (`standard` or `legacy`) in `.ywc-run-state.json` so resume validation checks the same location used during creation.
**4a-verify (mechanical gate — do not skip)**: before Step 4b, confirm each task's resolved path appears in `git worktree list --porcelain` and is an existing directory. If any path is missing, re-run Step 4a or stop `BLOCKED`; never spawn agents and never fall back to the base or aggregate branch working tree.
After 4a-verify passes for a task, set up Docker isolation using the same resolved worktree path returned by `ywc-worktrees`:
```text
$ywc-docker-isolate --mode setup --task-name <task-name> --worktree-path <resolved-worktree-path>
# exit 0 = PASS or no Docker compose detected; exit 1 = setup failed
```
If setup exits 1, mark that task `BLOCKED`, preserve its branch/worktree for recovery, and continue the wave with any other tasks whose setup passed. Do not replace or retry `ywc-worktrees --mode create`; Docker isolation wraps the created worktree and never owns git lifecycle.
**Checkpoint**: use the same `STATE_SCRIPT` resolver above, then run `python3 "$STATE_SCRIPT" wave-start <N>` — flips wave `<N>` to `in_progress`, populates `pending` from its task list, and stamps `last_checkpoint`. (Hand-editing the JSON risks malformed state and stale timestamps; the script does the mutation deterministically.)
**4b. Spawn Agents** — Use Codex subagent delegation to spawn one worker subagent per task in parallel. Pass each subagent:
- The task's `task.md` (implementation checklist)
- The task's `README.md` (scope, ownership, spec reference)
- The worktree path (working directory)
- The canonical term table from `docs/ubiquitous-language.md` if it exists in the project root (include the "Synonyms to Avoid" column — identifiers matching those entries are naming violations)
- The shared schema guide when the task touches database schema, migrations, ORM models, relations, indexes, tenant scoping, or enum domains: [../references/schema/core.md](../references/schema/core.md) plus the stack file matching the project (`prisma.md` / `sql-ddl.md` / `drizzle.md` / `typeorm.md`)
- **Question-First directive (append verbatim):**
> Before any code change: read `task.md` and the Spec Reference, then enumerate genuinely ambiguous decisions whose wrong answer would force a rewrite (interface shape, data model, naming that conflicts with existing code, library choice when more than one is installed). If the list is non-empty, return `NEEDS_CONTEXT` with the questions enumerated — do not infer from neighboring tasks. Inferring silently compounds error and is the most expensive failure mode. See [../references/question-first-gate.md](../references/question-first-gate.md) for what counts as genuine ambiguity and the question format.
- **Completeness directive (append verbatim to every subagent prompt):**
> This implementation will be merged directly into the base branch — treat it as production code. Before returning output: (1) every function/method must have a complete implementation body — no `// TODO`, no `// rest of code`, no placeholder stubs; (2) all imports must be used and all referenced symbols must be defined; (3) tests must contain real assertions, not empty `it()` blocks; (4) if token budget is approaching and generation is incomplete, stop at a clean function boundary and write `[PAUSED — X of Y files complete. Continue: <file-list>]` — never truncate mid-function. A stub is a compile error; a truncated function is worse.
- **Tool Error Recovery directive (append verbatim to every subagent prompt):**
> When a tool call returns an error, do not enter extended thinking — apply the recovery action immediately. For `Edit`/`Update` → "Error editing file": (1) re-read the full file with `Read`, (2) retry the edit with `old_string` from the fresh content. For `Bash` non-zero exit: inspect the error, fix the root cause (wrong flag, path, binary), re-run. Maximum 2 fix attempts for any tool error before returning `BLOCKED` with the file path, attempted change, and exact error text.
- **Simplicity + Surgical Changes directive (append verbatim to every subagent prompt):**
> Implement the minimum code that satisfies this task — no speculative features, no unsolicited abstractions, no "flexibility" that wasn't asked for. When editing existing code: touch only files listed in your declared Ownership; do not improve adjacent code, comments, or formatting unless they are the direct subject of this task. If you notice unrelated issues, mention them in the PR description — do not fix them. Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify before committing.
- **Contract + TDD directive (append verbatim):** Apply [../references/tdd-deep-module-gray-box.md](../references/tdd-deep-module-gray-box.md). Before behavior-changing work, record Changed Public Contracts, Critical Internals, and Cross-Module Impact; write or identify the failing test/contract assertion first; return tests authored/executed plus any `TDD Exception: <reason>`.
**Handling each subagent's status return**: each subagent ends with `DONE`, `DONE_WITH_CONCERNS`, `BLOCKED`, or `NEEDS_CONTEXT`. The orchestrator's response is defined by [../references/subagent-status-actions.md](../references/subagent-status-actions.md). In particular: `NEEDS_CONTEXT` → provide the missing context and re-dispatch the same subagent at the same model class (context is the cheapest fix); `BLOCKED` → run the four-step triage (context → reasoning → scope → plan) before surfacing to the user; `DONE_WITH_CONCERNS` → read the concerns and decide whether they are correctness-level (fix and re-dispatch) or observation-level (carry forward to the Completion Report). Do not silently retry the same subagent on the same input — change the input or the model class between attempts.
**Status Routing** — Apply to every per-task subagent return inside the wave loop:
| Returned status | Caller action |
|---|---|
| `DONE` | Proceed to Step 4c for this task and continue the wave. |
| `DONE_WITH_CONCERNS` | Observation concerns go to the Completion Report; correctness concerns require fix and re-dispatch before merge. |
| `BLOCKED` | Run the four-step triage, preserve the task branch/worktree if unresolved, and apply Wave Failure Handling. |
| `NEEDS_CONTEXT` | Provide missing context and re-dispatch the same subagent at the same model class. |
| Status absent or unparseable | Treat as `BLOCKED`; preserve the worktree and surface the raw payload. |
**4c. Task Verify** — After each agent completes, run the Task Verify commands from `task.md`. For DB/API write tasks, generated Task Verify entries covering concurrent write behavior, transaction rollback / partial-write prevention, and durable idempotency are mandatory task-specific gates: adapt the command to the project's harness when necessary, but do not replace them with only lint, typecheck, build, CI, or broad test commands. If behavior changed, also run authored/touched contract or behavior tests before broad verification; a worker with no test evidence must be re-dispatched, marked `DONE_WITH_CONCERNS`, or blocked with a TDD exception.
**4d. Review (optional)** — If `--review` is set, auto-invoke `ywc-impl-review` on the task's worktree branch after Task Verify (4c) and before the Wave Delivery (4e). For `--local-merge`, `--draft`, and `--aggregate-pr`, this is the last quality gate before the change reaches base with no remote bot review yet. For `--per-task-pr`, a remote bot review also runs after PR creation (Step 4e (a)), so here `--review` acts as a pre-PR gate that reduces bot round-trips rather than being the only gate.
**4e. Wave Delivery + Mark Complete** — After all tasks in the wave complete their implementation, deliver successful tasks into the base branch sequentially and mark each one complete. Delivery into the base branch is required for **every** mode because downstream waves branch from it. For `--local-merge`, `--draft`, and `--aggregate-pr`, the per-task `git merge --no-ff` + post-merge verification + Mark Task Complete + push (or defer) is delegated to `ywc-finish-branch`. For `--per-task-pr`, this skill runs the full PR lifecycle (create → CI → bot → `gh pr merge` → base sync) and an inline Mark Complete, because the worktree model is incompatible with finish-branch's `normal-pr` mode (which assumes the feature branch is the current checkout and runs a local `git checkout <base>` that cannot execute from a worktree).
**⚠️ DO NOT SKIP DELIVERY FOR THE LAST TASK IN THE LAST WAVE.** There is no exception. Even when there are no remaining waves and no downstream task waiting, Step 4e (a)+(b) must run for every task. For `--local-merge`, `--draft`, and `--aggregate-pr`, `ywc-finish-branch` performs the local merge, completion-marker commit, and (for local-merge) the push. For `--per-task-pr`, (a) merges the PR via `gh pr merge --delete-branch` and (b) commits and pushes the completion marker. Skipping delivery leaves implementation code on an orphaned branch and `tasks/completed/` out of sync.
For each task in the wave **sequentially** (topological order within the wave) — every task in every wave, **including the last task in the last wave**, must complete steps (a) and (b); no task is exempt because there is no downstream task waiting on it:
**(a) Per-task PR lifecycle** — applies only to `--per-task-pr` (runs unconditionally for every task in every wave, **including the last task in the last wave**). Skip entirely for `--local-merge`, `--draft`, and `--aggregate-pr`. Run branch-local commands from the resolved task worktree when a delegated skill depends on the current branch:
1. Push the feature branch and create the PR in the selected language:
```bash
git push origin feature/<task-name>
$ywc-create-pr <base-branch> --lang <pr-lang> --skip-post-ci-check --skip-ubiquitous-update
```
2. **Wait for CI to pass** (up to 2 fix attempts per failing cycle). Poll the PR's checks; on failure, fix on the worktree branch, push, and re-poll:
```bash
gh pr checks <pr-number> --watch
```
Categorize failures as lint/format (run the project's auto-fix command first), type, test, or build — fix on the worktree branch, commit, `git push origin feature/<task-name>`, then re-poll. After 2 failed fix cycles, mark the task `BLOCKED`, preserve its worktree and branch (skip Step 4g for it), and record it for the Completion Report.
3. **Run PR health sweep after automated review polling**: run the polling loop in [`../references/pr-bot-polling.md`](../references/pr-bot-polling.md), then invoke `ywc-handle-pr-reviews` for this task's PR regardless of `BOT_COUNT == 0`. A zero bot-comment count is not terminal success; the handler checks review artifacts, CI status, and merge-readiness. If the handler applies fixes, **re-verify CI (step 2)** — fixes push new commits that trigger a fresh CI run — then re-poll. Repeat until CI is green, merge-readiness is clean, and no new review artifacts arrive within the polling window. PR health sweeps across tasks in the same wave are processed **one task at a time** so each task's review commits land before its merge.
4. **Refresh the PR branch against the latest base if another task already advanced it** — this is the canonical merge-not-rebase procedure in [`../references/pr-conflict-resolution.md`](../references/pr-conflict-resolution.md). This matters when branch protection requires PR branches to be up to date, or when a previous task in the same wave already merged and pushed its completion marker. Run these commands from the resolved worktree path returned in Step 4a:
```bash
git fetch origin <base-branch>
if ! git merge-base --is-ancestor origin/<base-branch> feature/<task-name>; then
git -C <resolved-worktree-path> merge --no-ff origin/<base-branch> -m "Merge origin/<base-branch> into feature/<task-name>"
git -C <resolved-worktree-path> push origin feature/<task-name>
# The branch now has a new commit; return to step 2 and re-verify CI.
fi
```
If the base refresh conflicts, mark the task `BLOCKED`, preserve its worktree and branch, and record the conflict for the Completion Report. Do not force-push and do not merge a PR whose checks correspond to an older head SHA.
5. **Merge the PR** once CI is green, bots are quiet, and the branch is current with the latest base:
```bash
gh pr merge <pr-number> --merge --delete-branch
```
`--delete-branch` removes only the remote branch; the local branch (checked out in the worktree) is deleted in Step 4g.
6. **Sync local base** so the next wave branches from the merged state:
```bash
git pull origin <base-branch>
```
The main checkout is already on `<base-branch>`; this fast-forwards it to include the PR merge.
**(b) Mark Complete** — move the task directory to `completed/` and commit the marker. The mechanism differs by mode because `--per-task-pr` already merged via `gh pr merge` in (a), while `--local-merge`, `--draft`, and `--aggregate-pr` still need the local merge that `ywc-finish-branch` performs.
**For `--local-merge`, `--draft`, and `--aggregate-pr`** — delegate the local merge + Mark Complete to `ywc-finish-branch`. Mode mapping:
| parallel-executor `--mode` | finish-branch invocation |
|---|---|
| `--local-merge` | `--mode local-merge --keep-branch` (push every task immediately) |
| `--draft` | `--mode local-merge --keep-branch --defer-push` (push deferred to end of all waves; a single draft PR is created in Step 5) |
| `--aggregate-pr` | `--mode local-merge --keep-branch --defer-push` (**identical to `--draft` per wave**; Step 5 lifts the accumulated state onto one branch and runs the full merge lifecycle per [references/aggregate-pr.md](references/aggregate-pr.md) §B) |
```bash
$ywc-finish-branch \
--mode local-merge \
--branch feature/<task-name> \
--base-branch <base-branch> \
--task-name <task-name> \
--tasks-dir <tasks-dir> \
--keep-branch \
[--defer-push only when parallel mode is --draft or --aggregate-pr — controls only the Mark-Complete commit push, never the merge or any earlier step]
```
`--keep-branch` is required: the branch is checked out in the resolved per-task worktree, so `git branch -d` would fail until Step 4g releases the worktree.
**For `--per-task-pr`** — the merge already happened in (a) step 5, so do **not** call finish-branch (its `local-merge` would attempt a redundant merge, and its `normal-pr` assumes the feature branch is the current checkout, which it is not under the worktree model). Instead, run the same Mark Complete that finish-branch would, then push immediately:
```bash
MARK_SCRIPT="${CODEX_HOME:-$HOME/.codex}/skills/scripts/mark-complete.sh"
[ -f "$MARK_SCRIPT" ] || MARK_SCRIPT="codex/skills/scripts/mark-complete.sh"
bash "$MARK_SCRIPT" <tasks-dir> <task-name> --push
```
This is the same shared marker script `ywc-finish-branch` Step 7 uses. It moves the task into `completed/`, writes the mandatory `chore: mark <task-name> as completed` commit (handling the gitignored-`<tasks-dir>` case with a plain `mv` + `--allow-empty` commit), pushes the current branch — which under this flow is the synced base — and verifies the move (destination exists, source gone, marker at HEAD). A **non-zero exit** means the move or verification failed: mark the task `BLOCKED`, do not treat it as delivered. A `--per-task-pr` task is delivered only when its PR is merged (a step 5), local base is synced (a step 6), and this marker commit is pushed.
**Status return handling for `--local-merge`, `--draft`, and `--aggregate-pr`** (per task within the wave loop): ywc-finish-branch ends with `DONE`, `DONE_WITH_CONCERNS`, `BLOCKED`, or `NEEDS_CONTEXT`. Apply [../references/subagent-status-actions.md](../references/subagent-status-actions.md):
- `DONE` → proceed to the next task in the wave.
- `DONE_WITH_CONCERNS` → if observation-level, carry into the Completion Report; if correctness-level, fix and re-dispatch before continuing.
- `BLOCKED` → preserve the task's branch and worktree (Step 4g must skip it for recovery), record for the Completion Report, continue with the remaining wave tasks. Common BLOCKED causes here: merge conflict, post-merge verification mismatch, post-move verification mismatch.
- `NEEDS_CONTEXT` → provide the missing context and re-dispatch.
**Status handling for `--per-task-pr`** (no finish-branch delegation): the inline path has three failure gates — a CI failure exhausted after 2 fix cycles (a step 2), a latest-base refresh conflict (a step 4), and a post-move verification mismatch (b). Any one marks the task `BLOCKED`: preserve its worktree and branch (Step 4g must skip it), record it for the Completion Report, and continue with the remaining wave tasks. A merge conflict reported by `gh pr merge` (a step 5) is likewise `BLOCKED` — never force-merge; surface the conflict to the user.
**Checkpoint** (after each successful task delivery in the inner loop): use the `STATE_SCRIPT` resolver from State Init, then run `python3 "$STATE_SCRIPT" task-merged <N> <task-name>` — moves the task from `pending` to `merged` in wave `<N>` and stamps `last_checkpoint`.
**Wave-end push for `--draft` and `--aggregate-pr` modes**: After every task in the wave has been processed, the `--defer-push` completion-marker commits remain local. They are pushed once at the end of **all waves** (not per-wave), as part of the Completion Report transition. For `--local-merge` and `--per-task-pr`, no wave-end push is needed — every task already pushed individually (local-merge via finish-branch, per-task-pr via the (b) inline push after `gh pr merge`).
Failed (BLOCKED) tasks remain in `<tasks-dir>/<task-name>`; finish-branch never moves them. Record those tasks for the Completion Report.
**Checkpoint** (after the entire wave loop finishes): use the `STATE_SCRIPT` resolver from State Init, then run `python3 "$STATE_SCRIPT" wave-complete <N>` — flips wave `<N>` to `completed` (it refuses if any task is still `pending`, a built-in guard against marking an incomplete wave done) and stamps `last_checkpoint`.
**4g. Clean Up Worktrees** — Delete worktrees and branches for merged-and-marked tasks. This step is **mandatory and verified**, not best-effort. A leaked worktree pollutes Pre-flight on the next run, blocks reuse of the task name, and leaves the feature branch alive long after the work is on the base branch.
For each task whose Step 4e delivery completed (DONE):
```text
$ywc-docker-isolate --mode teardown --task-name <task-name> --worktree-path <resolved-worktree-path>
# exit 0 = Docker stack removed or no stack to remove
# exit 1 = report LEAKED_DOCKER_STACK; do not roll back delivered code
$ywc-worktrees --mode prune --task-name <task-name> --branch feature/<task-name>
# exit 0 = PASS (worktree removed, branch deleted, prune done, verified)
# exit 1 = FAIL — fix hints on stdout; read them before taking any action
```
Run Docker teardown immediately before the delegated worktree prune and only inside this Step 4e-DONE loop. Tasks marked `BLOCKED` or intentionally preserved skip teardown together with prune, so their worktree-local Docker state remains available for recovery. A teardown failure after delivery is reported as `LEAKED_DOCKER_STACK` in the Completion Report; it does not undo the merge, completion-marker commit, or worktree prune attempt.
The delegated prune operation encodes all four failure paths (modified files, locked worktree, not-fully-merged branch, directory persists) and runs post-cleanup verification automatically. If exit 1, read the stdout output — it names the step that failed and includes the exact commands to investigate or resolve.
Preserve worktrees and branches of failed tasks for recovery. Do not run this step for any task whose Step 4e delivery did not complete (DONE). Record every task whose cleanup succeeded, was force-cleaned, or was deliberately preserved — Step 5 reports each category.
**4h. Wave Cleanup Audit** — Before transitioning to the next wave, audit the worktree state for the wave as a whole. Per-task verification in 4g catches single-task drift; this step catches wave-level drift (e.g. an agent created a sibling worktree the executor did not track).
```text
# No preserved failures:
$ywc-worktrees --mode audit
# With preserved failures:
$ywc-worktrees --mode audit --expect <comma-separated preserved-failure task names>
# exit 0 = clean (or only expected preserved failures); exit 1 = DRIFT — investigate before next wave
```
If exit 1 (DRIFT), investigate before starting the next wave. Do not auto-delete unknown worktrees — they may belong to a concurrent operator or to a task whose state was not tracked.
**4i. Transition to Next Wave** — Per the Non-Stop Execution Principle, proceed to the next wave immediately and silently. Do not ask the user for confirmation. Do not emit any text between waves — no "Wave N complete", no status summary, no acknowledgment. The next output after Step 4h is the first tool call (creating worktrees) of Step 4a for the next wave. Before transitioning, run the executable terminal-state audit below — every task in the current wave must be in exactly one of two terminal states.
```bash
# Every task whose Step 4e delivery completed (DONE) must have its directory under completed/.
for task in <wave-success-tasks>; do
test -d <tasks-dir>/completed/$task || { echo "LEAKED: $task missing from completed/"; exit 1; }
done
# Every task whose Step 4e returned BLOCKED (preserved failure) must still be in <tasks-dir>/<task-name>.
for task in <wave-blocked-tasks>; do
test -d <tasks-dir>/$task || { echo "DRIFT: $task missing from <tasks-dir>/ (and not in completed/)"; exit 1; }
done
```
- Success → directory in `<tasks-dir>/completed/`, worktree removed, branch deleted
- Preserved failure → directory still in `<tasks-dir>/<task-name>`, worktree and branch retained for recovery
No task should be in an in-between state (e.g. moved to `completed/` but branch still alive, or worktree removed but directory not moved). If the audit reports `LEAKED` or `DRIFT`, **do not transition** — surface the offending task name to the user; transitioning forward with a missing Mark-Complete silently corrupts dependency resolution for every downstream wave.
## Output Format (Step 5 Completion Report)
**`--draft` and `--aggregate-pr` modes: Aggregate PR** (execute before the report below)
Both modes accumulate all task changes locally on base-branch via wave merges with
`--defer-push`, then lift that state onto a single branch and open one PR. The full
command sequences live in [references/aggregate-pr.md](references/aggregate-pr.md):
- **`--draft`** → §A: create `draft/<base>-<timestamp>`, push, reset local base, open a
**draft** PR, poll bots, re-verify CI, and **stop** (left open for a human to merge).
Capture the PR URL for the report.
- **`--aggregate-pr`** → §B: create `aggregate/<group-name>` (or timestamped), push, reset
local base, open the PR, **mark it ready**, CI-verify, bot-review, pass the
merge-readiness gate, **merge** (`gh pr merge --delete-branch`), and sync local base. The
completion-marker commits ride into base through this single merge — do not re-Mark
Complete. Capture the merged PR URL for the report.
> **Action required**: Read [references/aggregate-pr.md](references/aggregate-pr.md) before
> executing either path — it carries the exact branch names, CI/bot/merge-readiness gates,
> and §C multi-group concurrency rules.
**`--per-task-pr` mode: no end-of-run push** — each task's PR was already merged via `gh pr merge --delete-branch` and its completion-marker commit was already pushed during the task's slot in the wave (Step 4e (a) step 5 and (b)). There is nothing deferred to flush here, and the individual PRs are merged and closed on the remote — not left open. Proceed directly to the report below.
Display the following after all waves are complete:
- Total tasks executed, total waves
- Each task: name, status (success/failed/skipped), merge commit SHA in `--local-merge` mode, the aggregate PR URL in `--draft`/`--aggregate-pr` mode, or the merged PR URL in `--per-task-pr` mode
- Failed/skipped tasks with reasons
- In `--local-merge` mode: remind that no PR was created, no remote CI ran, only local verification was performed
- In `--per-task-pr` mode: each task's PR was created, CI-verified, bot-reviewed, and **merged** (`gh pr merge`); list each PR URL with its merged status
- In `--aggregate-pr` mode: the single aggregate PR was created, marked ready, CI-verified, bot-reviewed, merge-readiness checked, and **merged**; list the merged PR URL
- Contract evidence: Changed Public Contracts, tests authored/executed, Critical Internals, Implementation Notes for non-obvious decisions, and TDD Exceptions per task (or `N/A`)
- **Worktree cleanup status** — one line per task, in one of these categories (omitted when `--terse` is set):
- `clean` — worktree removed and branch deleted via Step 4g (the expected outcome for every successful task)
- `force-cleaned` — `git worktree remove --force` was required; note the reason (lock, disposable artifacts, etc.)
- `preserved (failure)` — intentionally retained for recovery; include the worktree path and branch name so the user can resume work
- `LEAKED` — Step 4g did not produce a clean result and the cause is not a recorded failure; this is a bug, surface it explicitly with the path and branch so the user can clean up manually
Run a final audit before printing the report:
```text
# No preserved failures:
$ywc-worktrees --mode audit
# With preserved failures:
$ywc-worktrees --mode audit --expect <comma-separated preserved-failure task names>
git branch --list 'feature/*' | sed 's/^[* ] //' || true
```
Any worktree under the resolved worktree root or `feature/*` branch that does not map to a `preserved (failure)` task in the report is a leak and must be reported as `LEAKED`, not silently omitted.
**When `--terse` is set**, omit all prose reminders, worktree audit lines, and mode-specific explanations. Emit only:
1. The task table (name | status | merge SHA or PR URL)
2. The `Completion Status` line
This is the preferred format for CI scripts or automation that parse the report output.
**Reporting Symbols**: Use the shared vocabulary in [symbols.md](../references/symbols.md) for the per-task status column, the worktree cleanup status column, and the wave-level summary line. **Parallel-specific addition**: `🚨` for `LEAKED` worktree or branch detected by the final audit (Step 5) — surface explicitly, never reduce to `❌`. Leaks are a distinct severity category the user must act on regardless of overall run status. For multi-step worktree lifecycle traces, use the flow operator `»` (e.g. `worktree ✅ » impl ✅ » verify ✅ » merge ✅ » cleanup ✅`).
Example wave summary row:
```
Wave 2 (3 tasks) | ✅ 2 ❌ 1 | force-cleaned: 0 preserved: 1 LEAKED: 0
```
**Completion Status**: End every report with one of these four declarations on its own line. This is the final line of the report — nothing follows it.
| Status | When to use |
|--------|------------|
| `DONE` | All tasks completed, all worktrees clean, no open issues |
| `DONE_WITH_CONCERNS` | Run completed but with caveats — failed tasks, `LEAKED` worktrees, advisor budget exceeded, or non-critical warnings |
| `BLOCKED` | Run stopped and cannot continue — merge conflict, circular dependency, push rejected, or a decision requiring human input |
| `NEEDS_CONTEXT` | Task list or arguments are ambiguous; the run cannot start without clarification |
**Operational Self-Improvement**: Before deleting the checkpoint file, append any genuinely new project-specific operational findings to `.ywc-learnings.jsonl` (one JSON object per line, format `{"ts":"<ISO-8601>","skill":"ywc-parallel-executor","project":"<basename>","learning":"<one sentence>"}`). Add the file to `.gitignore` if absent. Record only project-specific facts (package manager quirks, worktree isolation issues, build-step ordering, wave sizing observations); skip generic programming facts and anything already in `CLAUDE.md`. If nothing new in this run, skip the write entirely; empty entries are noise.
**State cleanup**: After displaying the report, delete the checkpoint file — the run is complete:
```bash
rm -f .ywc-run-state.json
```
## Validation and Wave Failure Handling
- **1 task fails**: Preserve its branch and worktree (do **not** run Step 4g for it), merge remaining successful tasks normally. Skip subsequent wave tasks that depend on the failed task. Record the preserved worktree path and branch name for the Completion Report.
- **Merge conflict**: Report conflicting files and related tasks, ask user to resolve manually. Do not auto-abort or force. The conflicting task's worktree and branch are preserved as in the single-task failure case.
- **Cleanup failure (Step 4g)**: A failure in 4g does **not** roll back the merge — the code is already on the base branch. It does, however, mean the next run's Pre-flight will detect a stale worktree. Report the affected task as `LEAKED` in Step 5 with the exact `git worktree remove` / `git branch -d` commands the user should run, so cleanup is one paste away.
- **Full stop conditions**: Pre-flight failure, circular dependency detected, `git push` rejected
## Integration
- **upstream**: ywc-task-generator
- **downstream**: ywc-impl-review (with --review), ywc-handle-pr-reviews (bot review handling in --per-task-pr), PR creation + merge
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!