From ywc-agent-toolkit
Executes tasks from the tasks/ directory in strict order through the full development lifecycle (branch, implement, commit, PR, CI, merge, cleanup). Use when you have a sequence of numbered tasks to run one at a time.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ywc-agent-toolkit:ywc-sequential-executorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Announce at start:** "I'm using the ywc-sequential-executor skill to run tasks through their full lifecycle in strict order."
README.en.mdREADME.es.mdREADME.ja.mdREADME.ko.mdREADME.mdREADME.zh.mdevals/evals.jsonreferences/advisor-escalation.mdreferences/aggregate-pr.mdreferences/branch-lifecycle.mdreferences/checkpoint-resume.mdreferences/external-url-policy.mdreferences/plan-critical-review.mdreferences/worktree-run.mdscripts/inspect-state.pyscripts/resume-state.pyscripts/verify-transition.shAnnounce at start: "I'm using the ywc-sequential-executor skill to run tasks through their full lifecycle in strict order."
Execute tasks generated by the ywc-task-generator skill through the full development lifecycle: branch creation, implementation, commit, PR, CI verification, merge, and local sync.
When tempted to skip a step, check this table first:
| Excuse | Reality |
|---|---|
| "Task A and Task B are independent, run them in parallel" | This is the sequential executor. For parallel runs, the user must explicitly switch to ywc-parallel-executor. |
| "CI is taking long, --skip-ci-wait gets the next task started" | Skipping CI hides regressions in subsequent tasks. Skip only if user explicitly approved. |
| "Previous task partially succeeded, I'll continue and clean up later" | Each task must leave the codebase buildable. Stop and report on partial success. |
| "Merge conflict is small, I'll resolve and continue" | Conflicts during sequential execution mean a base branch shifted. Stop, sync, get user direction. |
| "PR is created, mark task complete" | Task is complete only when merged + cleaned up + branch deleted. PR alone is not done. |
| "Task spec is unclear, I'll infer from neighbors" | Stop. Inferring from neighbors compounds error across the sequence. Ask user. |
"Local merge with --local-merge is faster, default to it" | Default is PR-based. --local-merge only when user explicitly opts in (e.g., personal repo). |
| "Lint/format failed in Step 4 with --draft, I'll stop and report" | Lint/format failures are auto-fixable. Run the project's fix command (e.g., eslint --fix, prettier --write, ruff --fix), commit the result, re-run verification, then continue to Step 5. Only stop if auto-fix fails to resolve residual errors after 2 attempts. |
| "--draft creates the PR and stops — bot review is for later" | Bot review bots (CodeRabbit, Codex Review, Claude Review) post on draft PRs immediately. After finish-branch creates the draft PR, poll for reviews and invoke ywc-handle-pr-reviews. The PR stays draft — responding now avoids a round-trip after un-drafting. |
| "normal-pr range: CI passed and no bot comments yet — proceed to merge" | Bot reviewers post 1–5 minutes after CI completes, not immediately. ywc-finish-branch runs a mandatory 60-second initial wait plus a 300-second polling window before concluding no bots are active. BOT_COUNT == 0 right after CI is not evidence that no bots are active — it means they have not posted yet. The polling window is a required wait gate in range mode, not a pause to skip. |
"Last task in --local-merge range: no following task needs this merge, skip finish-branch" | Step 5 (Delivery) is unconditional — every task, including the last, must have its feature branch merged into base, the completion-marker committed, and the push executed via ywc-finish-branch. Without it, the implementation code is stranded on an orphaned feature branch, tasks/completed/ is wrong, and the remote base branch is missing the work. The absence of a next task is not a reason to skip delivery. |
"Last task in normal-pr range: it's the last one, no need to omit --defer-push" | --defer-push must be omitted on the last task in normal-pr range — that omission IS the flush. If --defer-push is set on the last task, all accumulated completion-marker commits stay local and are never pushed. The last task's ywc-finish-branch invocation performs the single batch push; no separate git push runs after the loop. |
"--aggregate-pr: all tasks local-merged onto the work branch, the run is done" | The work branch is not the base branch. The group is delivered only when the single work → base PR is created, marked ready, CI-verified, bot-reviewed, merged, and local base synced (Section C of references/aggregate-pr.md). A work branch full of merged tasks with no merged PR is an incomplete group. |
"--aggregate-pr: per task, deliver to the real base like local-merge" | Per-task delivery targets the work branch (--base-branch work/<name> in finish-branch local-merge), never the real base. Merging tasks straight onto the real base would defeat the single-PR goal and mutate base before review. Each task branches from and merges into the work branch only. |
"--worktree: the cycle runs in the worktree, so the skill just cds there once and proceeds" | This skill is an LLM prompt with no persistent shell — a cd does not survive between Bash calls. Every git command must be git -C "$WT" …, every Edit/Write must target an absolute path under $WT, and every test/lint must be cd "$WT" && <cmd> inside a single Bash call. See references/worktree-run.md §A1. |
"--worktree non-aggregate DONE: prune the worktree and its integration branch together" | Non-aggregate prune must pass --keep-branch so the integration branch survives — it is what the user opens the final integration→trunk PR from. Omitting --keep-branch deletes that branch and strands the whole run's work with no path to trunk. Only --aggregate-pr (whose work/<name> is already merged) prunes the branch. See references/worktree-run.md §A3. |
| "I'll add tests after the implementation is working" | For behavior changes, the failing test comes first — a bugfix needs a regression test that fails on the old code, a feature needs a failing unit/integration test before implementation. Without test feedback gating each step you outrun your headlights and the code crashes at runtime. Docs/config/mechanical tasks are the only exception (record it). See ../references/tdd-deep-module-gray-box.md §2. |
| "This task only changes internals, no contract to write down" | If the change alters a public contract (exported function, endpoint, event, DTO, schema, props, CLI flag), design and write the interface before the body, and report it. Shallow single-use wrappers around cohesive behavior are the maze AI gets lost in later. See ../references/tdd-deep-module-gray-box.md §3. |
| "I reviewed the whole implementation line by line" | Default review is gray-box — verify the contract, delegate internals. The exception is critical paths (auth, payment, crypto, PII, external input): those get internal review and /ywc-security-audit, forced even without --review. Uniform-depth review wastes effort on safe code and under-scrutinizes dangerous code. See ../references/tdd-deep-module-gray-box.md §4. |
Violating the letter of these rules is violating the spirit. Sequential execution exists because each task's correctness depends on the previous task's stable state.
Parse $ARGUMENTS for the following parameters:
| Parameter | Format | Example | Description |
|---|---|---|---|
| Task specifier | <task-name> or <start>..<end> | 000001-010-db-create-users or 000001-010..000002-030 | Single task or range (phase+sequence prefix match). Both 001010 (legacy) and 000001-010 (new 6-digit PHASE) formats are accepted; prefix matching works with either. |
--pr-lang | --pr-lang <lang> | --pr-lang ja | PR title/description language. Default: auto-detect from CLAUDE.md or AGENTS.md, fallback to project's dominant language |
--tasks-dir | --tasks-dir <path> | --tasks-dir ./docs/tasks | Tasks directory path. Default: tasks/ |
--skip-ci-wait | flag | Skip CI wait and auto-merge (create PR only) | |
--draft | flag | Create PR as draft, skip merge | |
--local-merge | flag | Skip PR creation entirely — merge the feature branch into the base branch locally and push. Mutually exclusive with --draft and --skip-ci-wait | |
--base-branch | --base-branch <branch> | --base-branch develop | Base branch override. Default: auto-detect (develop > main > master) |
--dry-run | flag | Show the execution plan (task order, dependencies, modes) without executing anything | |
--terse | flag | Compact Completion Report: task table + Completion Status only — no prose reminders, no mode explanations, no advisor notes | |
--review | flag | Auto-run /ywc-impl-review after each task, before PR creation or merge | |
--run-tests-locally | flag | Before merging in --local-merge mode, detect and run the project's test command. On failure: mark task FAIL and do not merge. Ignored in PR-based modes. | |
--aggregate-pr | flag | Deliver the whole range as one work branch + one PR: each task is local-merged onto a work/<name> branch sequentially, then a single PR delivers the group to the base branch (ready → CI → bot → merge). The real base is never mutated until the final merge. See references/aggregate-pr.md | |
--group-name | --group-name <name> | --group-name project-health | Names the work branch (work/<name>). --aggregate-pr only; defaults to work/<base-branch>-<timestamp> when omitted |
--worktree | flag | Run the whole range inside one isolated git worktree so the main checkout stays free. Run-level isolation — tasks still run strictly sequentially. Independent flag, not part of the mutual-exclusion group: combines with all four delivery modes and --review. Full lifecycle in references/worktree-run.md. |
Flag conflicts: --local-merge, --draft, --skip-ci-wait, and --aggregate-pr are mutually exclusive. If the user passes more than one, stop before any branch or implementation work and ask which mode they actually want. The reason is that --local-merge skips PRs entirely while the others assume a PR exists — silently picking one would surprise the user. --group-name is valid only with --aggregate-pr. --worktree is orthogonal to this group — it is not a fifth member and may combine with any one delivery mode (§A8 S4); see references/worktree-run.md.
Example:
/ywc-sequential-executor 000001-010 --local-merge --draft
# → Stop. Report: "--local-merge and --draft are mutually exclusive
# (local-merge produces no PR; draft requires one). Which mode did you want?"
--review can be combined with any delivery mode flag.
--run-tests-locally has no effect without --local-merge (PR CI handles tests in PR-based modes).
If no task specifier is given, detect the next executable task from the dependency graph.
When --dry-run is set, perform Pre-flight and Task Resolution as usual, then display:
--draft, --skip-ci-wait, --local-merge, --aggregate-pr, or normal)--aggregate-pr, the work/<name> branch that would be created)Do not create branches, modify files, or run any git commands beyond read-only operations (git branch --show-current, git status). Exit after displaying the plan.
git branch --show-currentgit status --shortls tasks/ 2>/dev/null || echo "No tasks/ directory found"Resume check first: Before running the checks below, look for
.ywc-run-state.jsonin the project root. If it exists, follow the Resume Detection procedure in Checkpoint and Resume. If the user confirms resume, skip Pre-flight and jump to the saved task and step. If the user declines or there is no state file, proceed with the checks below. Intent-match guard (do not skip): if this invocation specifies an explicit range/task that does not match the saved run'srange, never silently resume — surface the divergence and require an explicit choice (resume the saved run vs discard it and start the new range), per the guard in references/checkpoint-resume.md. A new range hijacked by a stale interrupted run is the failure this guard prevents.
Before starting execution, verify these conditions:
git status --porcelain must be empty. If dirty, warn the user and stop.gh auth status must succeed.dependency-graph.md.Spec Reference section. See External URL Policy below. This check runs once per project, not once per task.State Init (non-resume runs only): Initialize .ywc-run-state.json now using the Write tool (see format in Checkpoint and Resume). Do not modify .gitignore during execution; the ignore entry must already be committed or present in repo-local exclude before the run:
grep -qxF '.ywc-run-state.json' .gitignore 2>/dev/null \
|| grep -qxF '.ywc-run-state.json' .git/info/exclude 2>/dev/null \
|| { echo "Missing .ywc-run-state.json ignore entry; add it to tracked .gitignore before the run or to .git/info/exclude for local-only state."; exit 1; }
Tasks generated by ywc-task-generator may list external URLs in Spec Reference > Primary Sources. Fetching external content mid-task is unpredictable (network, rate limits, SSO walls) and is also a privacy decision the user must make once per project.
Procedure: at Pre-flight, check .claude/settings.local.json for taskExecutor.externalSpecUrls. If present, use it silently. If missing, ask the user once to choose deny (default), allow, or allowlist, then persist the decision under the taskExecutor key (preserving every other key in the file). During Step 1b enforcement, apply the chosen policy: deny skips all http(s):// URLs, allow fetches everything, allowlist fetches only matching host+path prefixes.
For full procedure, jsonc schema, exact prompt wording, and rationale, see references/external-url-policy.md.
A task is done only when all of the following have happened, in this order. A task that has been "merged but not moved to completed/" is not done — Step 6's auto-detect logic and other tasks' dependency validation read <tasks-dir>/completed/ as the source of truth, so a missing move silently breaks dependency resolution for the next task in any range and for any future invocation of this skill.
ywc-finish-branch returned DONE for the task in Step 5. That status enforces conditions 3–5 inline: the merge succeeded with post-merge verification, the task directory was moved to <tasks-dir>/completed/<task-name> with a chore: mark <task-name> as completed commit, and the local feature branch was deleted.--local-merge (every task) and for normal-pr range execution (only the last task), the completion-marker commit has been pushed to the remote base branch — ywc-finish-branch pushes immediately when --defer-push is not set; the executor itself pushes once after the final task in a deferred-push range.A merged-but-not-moved task is not done. Mark Task Complete is part of the task definition, not optional bookkeeping; ywc-finish-branch enforces it and refuses to return DONE if the move did not verify. If finish-branch returns anything other than DONE, the task is incomplete — go back and resolve before transitioning.
--draft and --skip-ci-wait are the only documented exceptions: in those modes finish-branch ends at PR creation, the task stays in <tasks-dir>/<task-name>, and the user is expected to re-run the executor (or merge the PRs manually) to finalize them.
--aggregate-pr adds a group-level gate on top of the per-task definition. Each task is "done" against the work branch (local-merged, marked complete on the work branch, pushed). The group is done only when the single work → base PR has been created, marked ready, passed CI, cleared bot review, passed the merge-readiness gate, and been merged with local base synced — see Section C/E of references/aggregate-pr.md. A run whose work PR is created but unmerged is DONE_WITH_CONCERNS, never DONE.
The Non-Stop Execution Principle below governs LLM-level pausing, but it cannot override Claude Code's tool permission layer — every unprompted git/gh/mv command can independently block on user confirmation. In range mode this is the single most common reason execution stops mid-range: each git checkout, git push, git mv, and gh pr in every task triggers an individual prompt.
Required for range execution: Without pre-authorization, every
git/gh/mvcommand in every task will pause for user approval — directly breaking the Non-Stop Execution Principle. Complete this setup before starting any range; it is not optional.
The fix is a one-time .claude/settings.local.json setup that pre-authorizes a small set of read-only and task-scoped Bash patterns. The same permissions are used by both ywc-sequential-executor and ywc-parallel-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.
When a range of 3+ tasks is about to start and the plan was either generated in a prior session or modified since, run a one-shot upfront Opus advisor (Pattern C from ../references/advisor-pattern.md) over the dependency graph + first/last task summaries. The verdict is proceed or reconsider with refinements; on the latter, surface the refinements to the user and stop — do not auto-apply. The full invocation conditions, payload shape, output format, and budget accounting (consumes 1 of the 3 advisor calls) live in references/plan-critical-review.md. Skip the review for single-task, ≤2 task ranges, auto-detect mode, or when ywc-task-generator ran in the same session.
The executor writes .ywc-run-state.json in the project root after each major step. If a range run is interrupted, you can resume from the last checkpoint — completed tasks are skipped and the in-progress task restarts at its last saved step.
Resume detection runs before Pre-flight. For the resume procedure (executor/age/git validation, resume offer prompt), the on-disk state schema, the per-step Checkpoint event table, and manual inspection commands, see references/checkpoint-resume.md. The per-step **Checkpoint** markers below in Steps 2/4/5 reference the event table in that document — update last_checkpoint to the current UTC time on every write. The legacy current_step: 8 value is preserved for resume compatibility with state files written by older skill versions; new runs reach the same logical state via Step 5 (Delivery).
Match the specifier against task directory names in the tasks directory. Accept both exact match and prefix match (e.g., 000001-010 matches 000001-010-db-create-users-table; legacy 001010 format is still accepted during the transition period).
For <start>..<end> format, collect all tasks whose phase+sequence falls within the range (inclusive). Sort by phase then sequence. Execute sequentially, repeating the full cycle for each task.
If no specifier is given:
dependency-graph.mdtasks/completed/Depends On tasks are in completed/)For each task, execute these steps in order. If executing a range, repeat the entire cycle (Step 1 → Step 5) for each task before moving to the next. Each task gets its own feature branch — range mode does not reuse a single branch across multiple tasks.
Each task in a range gets its own feature branch — never reuse a branch across tasks. Starting point depends on mode: normal / --local-merge branch from a fresh base branch; --draft / --skip-ci-wait chain-branch from the previous feature branch (prior tasks are not merged, so their code would be missing otherwise). For per-mode diagrams, the decision table, and the "non-stop transitions ≠ non-stop coding on one branch" rationale (the single most common range-mode failure), see references/branch-lifecycle.md.
--worktree)When --worktree is set, the entire Execution Cycle below runs inside one isolated run worktree (captured as $WT) instead of the main checkout: every git command becomes git -C "$WT" …, every Edit/Write targets an absolute path under $WT, the state file moves to $WT/.ywc-run-state.json, each task branches from the run's integration branch, Step 5 passes ywc-finish-branch --worktree-path "$WT", and the worktree is pruned only on a DONE run (non-aggregate prune keeps the integration branch via --keep-branch). The full lifecycle — audit, create + $WT capture, naming/trunk-detection, 2-stage resume, prune branching, dry-run, and the Completion Report addendum — is in references/worktree-run.md. When --worktree is unset, everything below runs unchanged in the main checkout (AC6).
Action required before any range task begins: Read
../references/non-stop-execution.mdnow. It defines the exhaustive allowed-stop list, the force-continue rule, tool permission prompt handling, and the Tool Error Recovery policy (how to recover fromEdit/Bashfailures without entering extended thinking). Do not defer this read to mid-execution.
When executing a range, do not pause, ask for confirmation, or report intermediate results between tasks. The shared rule, full stop list, force-continue rule, zero-output rule, and the "non-stop transitions ≠ non-stop coding on one branch" reasoning live in ../references/non-stop-execution.md.
The unit for this skill is task. Sequential-specific Allowed Stop Reasons: dependency unsatisfied (Step 1), task.md stop condition triggered (Step 3), verification fails after 2 fix attempts (Step 4), ywc-finish-branch returned BLOCKED and the four-step triage (context → reasoning → scope → plan) is exhausted (Step 5) — covers CI failures, merge conflicts, and push rejections that previously stopped this skill directly, flag conflict detected (Pre-flight). The "Zero output between transitions" rule applies to the gap between Step 5 of one task and Step 1 of the next. Everything else — Force Continue Rule, what not to stop for, tool-permission-prompts-are-not-stop-conditions, the --local-merge rationale, and the branch-lifecycle warning — is in the reference and applies verbatim.
This skill follows Pattern A from ../references/advisor-pattern.md: a single inherited-model executor with bounded Opus escalation. Budget: up to 3 Opus calls per invocation (single-task or range alike); exceeding requires explicit justification in the Completion Report. Context payload rule: forward only the decision point (≤100 lines), never the full task README, spec, repo state, or prior Execution Cycle turns; advisor returns a ≤200-word verdict.
The escalation conditions remaining in this skill's scope — Spec Reference conflict (Step 1b), verification first failure with unclear cause (Step 4), Stop Condition borderline (Step 3) — are defined in references/advisor-escalation.md. Merge conflict and CI first-failure escalations (originally conditions 3 and 4 in that reference) move to ywc-finish-branch's scope at Step 5; finish-branch consumes its own advisor_budget: 1 for those escalations independently of this skill's budget of 3.
Read the task's README.md in full. This step has two purposes: verify dependencies are met, and load the Spec Reference into context so implementation in Step 3 is grounded in the actual specification rather than guesswork.
1a. Dependency Validation
Depends On exist in tasks/completed/--local-merge actually merges into the base branch, earlier dependencies in a range will be genuinely completed by the time later tasks are checked.1b. Spec Reference Loading
Locate the ## Spec Reference section in README.md. Three sub-fields drive Step 3 implementation:
find or Glob. If exactly one candidate is found, use it and log a warning noting the path mismatch. If zero or multiple candidates are found, stop and report — the spec is the contract, and silently proceeding would guarantee divergence.http:// / https://), apply the External URL Policy determined in Pre-flight. Urls skipped by policy are logged, not errors.N/A — no external spec, skip loading and proceed. This is a legitimate state for housekeeping / refactor / config tasks.If the Spec Reference section is entirely absent from README.md (i.e. the task was generated before this section existed), do not stop — instead, warn once in the execution log and fall back to implementing from task.md alone. This preserves backward compatibility with older task sets.
Every task gets its own feature branch. This applies to both single-task and range execution. Never run multiple tasks on the same branch — each task's changes must be isolated so they can be reviewed, merged, and rolled back independently.
Normal / local-merge mode (including range execution):
git checkout <base-branch>
git pull origin <base-branch>
git checkout -b feature/<task-name>
This applies to every task in a range, not just the first one. After each task completes its cycle (verify → finish-branch delivery), the next task starts fresh from the updated base branch. ywc-finish-branch (Step 5) leaves the working tree on <base-branch> for normal-pr and local-merge modes, so this command sequence runs cleanly without manual setup.
Range + draft/skip-ci-wait mode (chain branching):
When executing a range with --draft or --skip-ci-wait, earlier tasks are not merged into the base branch, so their code changes are absent from it. To ensure dependent tasks can build on prior work, create each subsequent branch from the previous task's feature branch instead of the base branch:
# First task in range — branch from base as usual
git checkout <base-branch>
git pull origin <base-branch>
git checkout -b feature/<task-name>
# Subsequent tasks — branch from the previous feature branch
git checkout feature/<previous-task-name>
git checkout -b feature/<task-name>
This solves the code-availability problem that Step 1's dependency-validation exception alone cannot address: the exception lets the dependency check pass, but without chain branching the implementation code from the previous task would be missing.
--aggregate-pr mode: create the work/<name> branch once before the loop (Section A of references/aggregate-pr.md), then branch every task from the work branch (git checkout work/<name> && git checkout -b feature/<task-name>). Each task's Step 5 local-merges back into the work branch, so the next task sees all prior work — the same guarantee normal/local-merge mode gets from the base branch, but isolated on the work branch.
Branch name format: feature/<task-name> (e.g., feature/000001-010-db-create-users-table)
Checkpoint: Update .ywc-run-state.json — set current_task to <task-name>, current_step to 2, branch to feature/<task-name>, and last_checkpoint to current UTC time.
Read the task's task.md and implement according to the checklist. The Spec Reference section loaded in Step 1b is the authoritative source of intent — when task.md and the spec disagree, the spec wins and the discrepancy should be noted in the PR description. If docs/ubiquitous-language.md exists in the project root, read it now and apply canonical term names throughout implementation — identifiers matching a "Synonyms to Avoid" entry are a naming violation.
Question-First gate (run before any code change): After reading task.md and the Spec Reference, 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, stop and return NEEDS_CONTEXT with the questions enumerated — do not infer from neighboring tasks. Inferring silently compounds error across the sequence and is the most expensive failure mode. For the canonical procedure, what counts as genuine ambiguity, and the question format, see ../references/question-first-gate.md.
Simplicity + Surgical Changes (enforce throughout implementation): Implement the minimum code that satisfies the task spec — no speculative features, no unsolicited abstractions, no "flexibility" that wasn't asked for. When editing existing code: touch only files within the 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.
Interface-first (deep module): When the task adds or changes a public contract — an exported function, endpoint, event payload, DTO, schema contract, component props, or CLI flag — write the interface (signature + contract) before the body, and note it in the PR description. Hide the implementation behind that interface; do not split cohesive behavior into shallow single-use wrappers to satisfy a "small function" reflex (that is the maze the next reader, human or AI, gets lost in). Add an interface only for a real boundary — no speculative generality. See ../references/tdd-deep-module-gray-box.md §3.
Schema-aware implementation (when the task touches DB): If the task adds, modifies, or removes tables, columns, indexes, or relations, read the shared ../references/schema/core.md and the one stack file matching the project (prisma.md / sql-ddl.md / drizzle.md / typeorm.md) before writing the migration. The eight mechanical invariants there (bilateral relations, cascade ↔ API status, NOT NULL backfill, FK index, composite uniqueness, multi-tenant scope, enum domain, timestamptz) fail deterministically at generate time or first write when omitted, and a migration task is the single point where they must all be right.
README.mdOut of Scope (from spec) list in mind at every step — if an implementation step tempts you toward an Out of Scope item, stop and re-read the step; the item likely belongs to a different task.task.md lists specific test requirements, follow them. Otherwise, author tests appropriate to the change:
ls/find before creating new structures)DONE_WITH_CONCERNS. The default ywc-code-gen minimal gate and the opt-in --tdd ritual are two strengths of the same discipline — see ../references/tdd-deep-module-gray-box.md §2.Commit guidelines:
Co-Authored-By trailer when Claude generated the changes. Use the format specified in the project's CLAUDE.md or commit convention; if none is specified, default to Co-Authored-By: Claude <[email protected]>git add -A or git add .)Completeness Gate (required before first commit): Before creating the first commit for this task, run a stub-pattern check on all modified files:
files="$(git ls-files -co --exclude-standard | grep -vE '(^|/)(test|tests|spec|__tests__)/|\.test\.' || true)"
if [ -n "$files" ]; then
printf '%s\n' "$files" | xargs grep -lnE \
"TODO|FIXME|XXX|HACK|raise NotImplementedError|throw new Error\(.*[Nn]ot [Ii]mplemented" \
2>/dev/null || echo "OK: no stub patterns found"
else
echo "OK: no files to scan"
fi
If any stub patterns appear in implementation files, complete the implementation before committing. Stubs committed here become Step 4 verification failures; catching them before the first commit saves the entire retry cycle.
Exception: TODO comments in test files (e.g., // TODO: add edge case for overflow) are permitted. TODO in implementation files are not.
Ownership-scope Gate (required before first commit): mechanize the prose Surgical-changes rule. Run git diff --name-only HEAD and confirm every changed path falls within the task's declared Ownership from README.md. Any file outside Ownership is a scope-creep signal — either it is a genuine dependency the task missed (stop and report BLOCKED) or a drive-by edit (revert it). Do not commit out-of-Ownership files with an unexplained justification.
git diff --name-only HEAD # every path must match the README Ownership globs
Run verification in three layers, from narrowest to broadest. Each layer must pass before moving on.
Task Verify commands — Run each command listed in the task.md Task Verify section. These are the task-author's definition of "this specific change works."
Task-local test run — Explicitly run the tests you authored or touched in Step 3, even if they overlap with (1). This catches the case where a task's Verify section is stale or missing the new tests.
Full project test suite (required, every task) — After (1) and (2) pass, run the entire project test suite, not just the files the task touched. The purpose is to catch regressions in code outside the task's declared Ownership — a task can technically stay within its edit scope and still break something downstream via shared state, shared types, schema changes, or runtime wiring. Discover the command from (in order): package.json scripts, Makefile, pyproject.toml/tox.ini, Cargo.toml, go test ./..., CI workflow files, or CLAUDE.md. Typical examples: npm test, pnpm test, pytest, go test ./..., cargo test, bundle exec rspec. Long test suites may be run in the background.
General verification — Run the remaining checks specified by the task or project: lint, typecheck, build. These are cheap regression catchers and should always run. For lint/format failures, run the project's auto-fix command first (e.g., eslint --fix, prettier --write, ruff --fix, gofmt -w) before counting it as a fix attempt. Commit the auto-fixed changes and re-run the layer. If auto-fix resolves the issue, continue to Step 5 normally.
If any layer fails: fix the code, never the test — no skip/xit/.only, no commented-out or relaxed assertions. Re-run the failing layer plus any earlier layer the fix could invalidate. For a failure in a test unrelated to the current task, investigate whether the task actually caused it (shared state, fixtures, ordering) before dismissing as flaky. Layer 4 lint/format exception: running the project's auto-fix command is step zero and does not count toward the 2-attempt limit — the limit starts only if auto-fix leaves residual errors. After 2 fix attempts (post-auto-fix for Layer 4, or 2 direct attempts for other layers), stop and report layer + failing test name(s) + error output + attempts made. Never proceed to Step 5 with a failing full suite — local catch saves a CI round trip and keeps main healthy.
Checkpoint: Update .ywc-run-state.json — set current_step to 4, last_checkpoint to current UTC time.
--run-tests-locally gate (applies only when --run-tests-locally is set AND --local-merge is active): After all four verification layers pass, detect the project's test command from CLAUDE.md or package.json (scripts field). Run it before proceeding to Step 5 (merge). On failure: mark the task FAIL and do not merge — surface the test output to the user and stop. If no test command can be detected: emit a warning and proceed to Step 5 without blocking.
If --review is set, invoke /ywc-impl-review on the current feature branch after all verification layers in Step 4 pass. The review runs before PR creation (Step 5) or local merge (Step 6a), so any issues it surfaces can be fixed while still on the feature branch.
This is optional — it adds time and tokens but catches design issues, naming problems, and patterns that automated tests miss. It pairs especially well with --local-merge, where no remote CI runs and this review becomes the last quality gate before code reaches the base branch.
Critical-path auto-escalation (forced, even without --review). Gray-box review is the default, but it is insufficient for critical modules. When the task's declared Ownership matches a critical path (auth / authz / session / token / password / secret / crypto / payment / billing / finance / PII / external-input boundaries — full list and CLAUDE.md critical_paths override in ../references/tdd-deep-module-gray-box.md §4), invoke /ywc-impl-review and /ywc-security-audit on the feature branch before Step 5 delivery, regardless of whether --review was passed. Detection is on the task's Ownership (known before implementation). Non-critical tasks keep the default gray-box verification.
The review applies the recurring real-world defects catalog — the classes (data-layer access-boundary / ownership isolation, data-integrity / NULL handling, error-swallow, external-call resilience, validation / fail-fast, HTTP status, test fidelity) that PR-review bots such as CodeRabbit flag most. In PR-based modes (normal-pr, --draft, --skip-ci-wait), catching these before the PR opens directly reduces the bot-review round-trips handled later by ywc-handle-pr-reviews — the issue is fixed on the feature branch instead of in a follow-up review cycle.
Handling the review's status return: /ywc-impl-review emits one of DONE, DONE_WITH_CONCERNS, BLOCKED, NEEDS_CONTEXT. The orchestrator's response is defined by ../references/subagent-status-actions.md — in particular, BLOCKED triggers the four-step triage (context → reasoning → scope → plan) before surfacing to the user, and DONE_WITH_CONCERNS requires reading the concerns to decide whether they are correctness-level (fix and re-review) or observation-level (carry forward to the Completion Report).
ywc-finish-branch)After Step 4 verification (and optional Step 4.5 review) passes, the rest of the task — PR creation, CI wait, bot polling, merge (PR or local), post-merge verification, Mark Task Complete, and local branch cleanup — is delivered by ywc-finish-branch. This skill does not duplicate that logic.
Mode mapping (this skill's flag → finish-branch --mode):
| This skill's flag | finish-branch --mode |
|---|---|
--local-merge | local-merge |
--draft | draft |
--skip-ci-wait | skip-ci-wait |
--aggregate-pr | local-merge with --base-branch work/<name> (per task) — accumulates onto the work branch, not the real base |
| (none — default) | normal-pr |
--aggregate-pr final delivery (after the last task): the per-task loop above merges every task onto the work/<name> branch. Once the last task's local-merge completes, deliver the whole group as a single work → base PR (create via ywc-create-pr --skip-post-ci-check, then mark ready → CI → bot → merge-readiness gate → gh pr merge → sync). The completion markers committed during the loop ride into base through that one merge — do not re-Mark-Complete. The exact command sequence is Section C of references/aggregate-pr.md.
⚠️ DO NOT SKIP THIS STEP FOR THE LAST TASK. The single most common failure in --local-merge range mode is jumping from Step 4 directly to the Completion Report for the last task. There is no exception. Even when there are no remaining tasks in the range, ywc-finish-branch must be invoked — it performs the git merge, push, completion-marker commit, and branch deletion. Skipping it leaves the implementation code on an orphaned feature branch with nothing pushed to the remote base branch.
Invocation (unconditional — every task in a range, including the last task, runs through this exact delegation; the optional --defer-push flag controls only whether the Mark-Complete commit is pushed at the end of finish-branch Step 7, and never affects PR creation, CI wait, bot polling, merge, post-merge verification, or Mark Complete itself):
/ywc-finish-branch \
--mode <mapped-mode> \
--branch feature/<task-name> \
--base-branch <base-branch> \
--task-name <task-name> \
--tasks-dir <tasks-dir> \
--pr-lang <pr-lang> \
--bot-action sequential \
[--defer-push only when mapped-mode is `normal-pr` AND this is not the last task in a multi-task range]
--bot-action sequential is required: this skill executes one task at a time, so bot review fixes must trigger a CI re-gate before merging (finish-branch's parallel mode skips the re-gate).
Range push deferral (push behavior only — does not affect PR creation, CI wait, bot polling, merge, or Mark Complete): in normal-pr range mode, Mark-Complete commits accumulate locally as --defer-push is set on every task except the last; finish-branch's own Step 7 push on the last task (which deliberately omits --defer-push) flushes all accumulated commits in a single push. No separate post-loop git push command is required — the last task's finish-branch invocation IS the flush. For --local-merge and single-task invocations, omit --defer-push — push happens immediately every time.
Handling finish-branch's status return: ywc-finish-branch ends with one of DONE, DONE_WITH_CONCERNS, BLOCKED, NEEDS_CONTEXT. The orchestrator's response is defined by ../references/subagent-status-actions.md. In particular, BLOCKED triggers the four-step triage (context → reasoning → scope → plan) before surfacing to the user, and DONE_WITH_CONCERNS requires reading the concerns to decide whether they are correctness-level (fix and re-dispatch) or observation-level (carry forward to the Completion Report).
Both ywc-finish-branch (Step 5) and the optional /ywc-impl-review invocation (Step 4.5) return payloads per ../references/subagent-status-actions.md §3.5. Apply the following routing table:
| Returned status | Caller action |
|---|---|
DONE | Proceed to Step 6 (transition to next task in range, or to the Completion Report if this was the last task) |
DONE_WITH_CONCERNS | Observation-level concerns → carry forward to the Completion Report; correctness-level concerns → fix and re-dispatch finish-branch (or impl-review) before proceeding |
BLOCKED | Run the four-step triage (context → reasoning → scope → plan); if exhausted, halt the range and surface to the user with the failing task name and finish-branch's blocker excerpt — see Sequential-specific amplification below |
NEEDS_CONTEXT | Provide the missing context and re-dispatch finish-branch (or impl-review) — do not silently infer from prior tasks in the range |
| Status absent or unparseable | Treat as implicit BLOCKED; halt the range, surface the raw payload to the user |
BLOCKED returns from ywc-finish-branch in sequential mode preserve the task branch and any in-progress merge state (finish-branch never auto-aborts). The task directory stays in <tasks-dir>/<task-name> (not moved to completed/). When the user resolves the blocker and re-invokes this skill, Resume Detection (see Checkpoint and Resume) picks up at the failed task's Step 5. CI-failure and merge-conflict cases inside finish-branch are handled by its own internal retry loop (up to 2 fix attempts); only fundamentally unresolvable blockers reach this Status Routing table.
Mode-skip semantics: for --mode draft and --mode skip-ci-wait, finish-branch's responsibility ends at PR creation (not at merge or Mark Complete). The task remains in <tasks-dir>/<task-name> (not moved to completed/) and no completion marker is committed; the user is expected to re-run the executor (or merge the PRs manually) to finalize.
--draft bot review: After finish-branch returns with the draft PR URL, run the bot review polling loop from ../references/pr-bot-polling.md. If BOT_COUNT > 0, invoke ywc-handle-pr-reviews for this PR. The PR stays as draft after review response — do not un-draft or merge.
Checkpoint: Update .ywc-run-state.json after finish-branch returns — set current_step to 8 (final pre-completion checkpoint, preserved for resume compatibility with older state files); set branch to null for normal-pr and local-merge (finish-branch deleted it) or keep feature/<task-name> for draft / skip-ci-wait (branch stays alive). Append <task-name> to completed only when finish-branch returned DONE and --mode is normal-pr or local-merge. For draft / skip-ci-wait, do not append; the task is intentionally incomplete.
Precondition (enforced, not optional): You may only enter Step 6 if ywc-finish-branch (Step 5) has already returned DONE for the current task. If you have not yet invoked ywc-finish-branch for the current task, go back to Step 5 now — do not proceed here. Step 6 is a transition step, not a shortcut past Step 5.
If executing a range:
DONE for the current task, proceed to the Completion Report.normal-pr, local-merge, and --aggregate-pr modes): Run the bundled verification script, passing the branch the next task will branch from — <base-branch> in normal-pr/local-merge, or work/<name> in --aggregate-pr. The script is mode-agnostic and checks the same 4 conditions against whichever integration branch it receives. Skip for --draft/--skip-ci-wait, which chain-branch from the still-alive previous feature branch:
# normal-pr / local-merge (integration branch is the base branch):
bash claude-code/skills/ywc-sequential-executor/scripts/verify-transition.sh \
<base-branch> <completed-task-name> [<tasks-dir>]
# --aggregate-pr (integration branch is the work branch):
bash claude-code/skills/ywc-sequential-executor/scripts/verify-transition.sh \
work/<name> <completed-task-name> [<tasks-dir>]
Exit 0 = PASS — all 4 conditions satisfied, safe to proceed. Exit 1 = FAIL — details printed to stdout with fix hints. Remediations per condition: wrong branch → git checkout <base-branch>; feature branch still alive → re-invoke ywc-finish-branch (it returned non-DONE); dirty tracked files → stop and report, do not auto-stash (only ?? untracked files are safe to git clean -fd); missing completed/<task> directory → finish-branch's Step 7 post-move verification did not run — treat as a Step 5 failure and re-invoke or surface to the user. Never transition forward without PASS. This gate exists because the most common range-mode failure is carrying state from one task into the next, and a missed Mark-Complete silently corrupts the dependency contract for every subsequent task.README.md) of Step 1 of the next task — not any text. Suppress any transition-message impulse and issue the tool call instead.The working tree state at this point differs by mode (normal-pr / local-merge are on <base-branch> with merged changes pulled; draft / skip-ci-wait stay positioned for chain branching from the previous feature branch). For per-mode transition details, see references/branch-lifecycle.md. The key point: Step 2 is not skipped for subsequent tasks — every task in a range goes through the complete Step 1 → Step 5 cycle, including branch creation.
After all tasks are executed, display:
local-merge with the merge commit SHA when --local-merge is used/ywc-security-auditWhen --terse is set, omit all prose reminders and mode-specific explanations. Emit only:
Completion Status lineThis is the preferred format for CI scripts or automation that parse the report output.
Reporting Symbols: Use the shared vocabulary in symbols.md for the per-task status column and inline step traces. The symbol is a scan aid, not a replacement for the status text — keep both. For multi-step traces inside a single task report, use the flow operator » (e.g. branch ✅ » impl ✅ » verify ✅ » PR ✅ » merge ✅). Do not use symbols inside commit messages, PR titles, or generated source code — they belong to the report layer only.
Example task table row:
000003-010-add-auth-middleware | ✅ merged | https://github.com/.../pull/142
000003-020-add-rate-limiting | 🚫 blocked | depends on 000003-010 (failed)
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 PRs merged (or merged locally), no open issues |
DONE_WITH_CONCERNS | Run completed but with caveats — failed tasks, skipped steps, advisor budget exceeded, or non-critical warnings |
BLOCKED | Run stopped and cannot continue — merge conflict, authentication failure, 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-sequential-executor","project":"<basename>","learning":"<one sentence>"}). Add the file to .gitignore if absent. Record only project-specific facts (package manager quirks, CI timing, build-step ordering, branch-protection rules) — 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 (mandatory, unconditional, every mode): After displaying the report, delete the checkpoint file. This step runs for every successful run regardless of mode (normal-pr / local-merge / draft / skip-ci-wait), regardless of how many tasks ran (single-task or range), and regardless of whether mid-flight checkpoint updates were actually written. Skipping it leaves a stale .ywc-run-state.json whose current_task / current_step / completed fields no longer reflect reality, and the next invocation's Resume Detection will pick it up and offer to resume — silently re-executing or short-circuiting tasks that already finished. The most common failure mode is single-task normal-pr runs where intermediate checkpoint writes did not fire (because the path is short) and the LLM perceives the cleanup as superfluous; treat it as part of the run, not an optional post-script.
rm -f .ywc-run-state.json
test ! -f .ywc-run-state.json && echo "OK: state cleaned" || echo "WARNING: state file still present"
If the verification line prints WARNING, the run is DONE_WITH_CONCERNS, not DONE — surface the leftover file path in the Completion Report.
When --pr-lang is not specified, detect the language in this priority:
gh pr list --limit 5 --json title,body to detect dominant languageMerge conflict during pull → stop and ask the user to resolve manually. PR-vs-base conflict at delivery → ywc-finish-branch's Merge-Readiness Gate (Step 4 final, per ../references/pr-conflict-resolution.md) handles it: a merely-behind branch is auto-updated and CI re-verified; a real textual conflict returns BLOCKED for human resolution. CI timeout (>30 min) → report status and ask whether to continue waiting. CI failure → ywc-finish-branch Step 4 diagnoses the failing checks, categorizes the failure (lint/format, type, test, build), and applies up to 2 fix attempts automatically; returns BLOCKED only when fixes are exhausted — do not stop at the first CI failure. gh CLI not authenticated → provide setup instructions and stop. Task not found → list available tasks and ask the user to specify. Dirty working tree → show changed files and ask the user to commit or stash.
This skill works with tasks generated by ywc-task-generator. PR creation is delegated to the create-pr skill (security check + CI pre-push validation handled there). Parallel execution (multiple independent tasks at once) belongs to ywc-parallel-executor — this skill is sequential by default for safety. Never force-push or amend published commits without explicit user approval. On any step failure, explain what went wrong and suggest a fix rather than silently retrying.
npx claudepluginhub yongwoon/ywc-agent-toolkitGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.