From wholework
Autonomous execution (`/auto 123`). Runs spec (when needed)→code→review→merge→verify in sequence. XL Issues use sub-issue dependency graph with parallel execution. Size auto-detection with `--patch`/`--pr` and `--review=light`/`--review=full` overrides. Issues without `phase/*` labels start from issue triage. `--batch N` processes N backlog XS/S Issues; `--batch N1 N2 ...` processes the explicitly listed Issues in order (assigns a BATCH_ID for parallel-safe checkpointing). `--resume N` resumes a single Issue (restores verify counter from checkpoint); `--batch --resume` resumes an interrupted batch using `list_active_batches` to identify the target session.
How this skill is triggered — by the user, by Claude, or both
Slash command
/wholework:autoThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Receive an Issue number and run spec (when needed)→code→review→merge→verify in sequence using Size-based routing. code/review/merge phases run via `run-*.sh` using `claude -p --dangerously-skip-permissions` for a fresh context with full permission bypass. verify runs as a Skill invocation in the parent session (enabling AskUserQuestion for manual AC confirmation).
Receive an Issue number and run spec (when needed)→code→review→merge→verify in sequence using Size-based routing. code/review/merge phases run via run-*.sh using claude -p --dangerously-skip-permissions for a fresh context with full permission bypass. verify runs as a Skill invocation in the parent session (enabling AskUserQuestion for manual AC confirmation).
If ARGUMENTS contains --help, Read ${CLAUDE_PLUGIN_ROOT}/modules/skill-help.md and follow the "Processing Steps" section to output help, then stop.
| Route | Target Size | Phase sequence |
|---|---|---|
| patch (XS/S) | XS, S | spec (when needed) → code(--patch) → verify |
| pr (M) | M | spec (when needed) → code → review(--light) → merge → verify |
| pr (L) | L | spec (when needed) → code → review(--full) → merge → verify |
| XL | XL | Sub-issue dependency graph with parallel execution (spec auto-runs per sub-issue) |
Extract the Issue number from ARGUMENTS. Examples: ARGUMENTS = "279" → NUMBER = 279; ARGUMENTS = "279 --patch" → NUMBER = 279, ROUTE_FLAG = --patch
AUTO_SESSION_ID generation (run before all route detection):
Generate a session identifier and record it in a pointer file so sub-processes spawned by run-auto-sub.sh can read it:
SESSION_ID and create the pointer file:
mkdir -p .tmp
SESSION_ID="$$-$(date +%s)"
printf '%s\n' "$SESSION_ID" > .tmp/auto-session-current
.tmp/auto-session-${SESSION_ID}.json using the Write tool with session metadata:
{"session_id": "<SESSION_ID>", "session_start": "<current UTC timestamp in ISO8601>"}
Substitute the actual SESSION_ID value and current timestamp before writing.AUTO_SESSION_ID="$SESSION_ID" in the current Bash context (does not persist across separate Bash tool calls; sub-processes read from the pointer file instead):
export AUTO_SESSION_ID="$SESSION_ID"
--resume detection (single-Issue resume):
If ARGUMENTS contains --resume but NOT --batch: record RESUME_MODE=true and extract the numeric token following --resume as NUMBER. Output a log line: "Resume mode: restoring checkpoint for issue #$NUMBER". Proceed to Step 2 as normal (checkpoint restoration happens in Step 4 before the verify loop).
--batch detection:
If --batch flag is present:
--resume is present AND no numeric tokens follow --batch (i.e., ARGUMENTS = "--batch --resume" or similar with no numbers after --batch): record RESUME_BATCH=true and branch to ### Resume mode (--batch --resume) in the "Batch Mode (--batch)" section (skip Steps 2–6)--batch, stopping at any non-numeric token or ARGUMENTS end.
ARGUMENTS = "--batch 5"): record BATCH_SIZE = 5 (Count mode) and branch to ### Count mode (--batch N) in the "Batch Mode (--batch)" section (skip Steps 2–6)ARGUMENTS = "--batch 123 124 125"): record BATCH_LIST = [123, 124, 125] (List mode) and branch to ### List mode (--batch N1 N2 ...) in the "Batch Mode (--batch)" section (skip Steps 2–6)No Issue number needed for batch mode.
Read ${CLAUDE_PLUGIN_ROOT}/modules/phase-banner.md and display the start banner with ENTITY_TYPE="issue", ENTITY_NUMBER=$NUMBER, SKILL_NAME="auto".
Detect --patch/--pr, --review=full/--review=light, and --base {branch} flags from ARGUMENTS.
If --base {branch} is present, record as BASE_BRANCH. If --base is not specified, default to BASE_BRANCH=main.
| Flag | Route | Phase sequence |
|---|---|---|
--patch | patch | code(--patch) → verify |
--pr | pr | code → review → merge → verify |
--pr --review=full | pr | code → review(--full) → merge → verify |
--pr --review=light | pr | code → review(--light) → merge → verify |
--base {branch} | (no route change) | Specify base branch; propagates to all phases |
| none | auto-detect | Determine route from Size label |
If no flags, fetch Size to auto-detect route:
${CLAUDE_PLUGIN_ROOT}/scripts/get-issue-size.sh "$NUMBER" 2>/dev/null
Set REVIEW_DEPTH from flags or Size (used unchanged in Step 4 unless Step 3a refreshes it):
| Condition | REVIEW_DEPTH |
|---|---|
--review=full flag present | --full |
--review=light flag present | --light |
--patch flag present | (not applicable — patch route) |
Auto-detect or --pr without --review=...: Size M | --light |
Auto-detect or --pr without --review=...: Size L | --full |
Auto-detect or --pr without --review=...: other/unset | --light (safe fallback) |
phase/ready Label CheckFetch labels with gh issue view $NUMBER --json labels -q '.labels[].name' and branch based on label state:
phase/ready label present: proceed to the next stepphase/issue label present (no phase/ready):
L: run ${CLAUDE_PLUGIN_ROOT}/scripts/run-spec.sh $NUMBER --opus (run spec with Opus model)${CLAUDE_PLUGIN_ROOT}/scripts/run-spec.sh $NUMBERphase/* labels (issue triage not done):
${CLAUDE_PLUGIN_ROOT}/scripts/run-issue.sh $NUMBER (issue triage → Size setting/requirement shaping)${CLAUDE_PLUGIN_ROOT}/scripts/get-issue-size.sh $NUMBER). Update route if Size is now set.gh issue view $NUMBER --json labels -q '.labels[].name'phase/ready: proceed to Step 4phase/issue (no phase/ready):
L: run ${CLAUDE_PLUGIN_ROOT}/scripts/run-spec.sh $NUMBER --opus${CLAUDE_PLUGIN_ROOT}/scripts/run-spec.sh $NUMBERphase/* label state is not reached after re-fetch, go to Step 6 (error report)Run only when run-spec.sh was called and succeeded in Step 3 (i.e., spec was executed — not when phase/ready was already set at Step 3 entry, and not when Size was XS which skips spec). Also skip if --patch, --pr, or --review=... flag is present in ARGUMENTS (preserve explicit-flag priority behavior).
Re-fetch Size to detect updates made by the spec phase:
${CLAUDE_PLUGIN_ROOT}/scripts/get-issue-size.sh --no-cache "$NUMBER" 2>/dev/null
Update ROUTE and REVIEW_DEPTH based on the refreshed Size:
| Refreshed Size | Route | Review depth |
|---|---|---|
| XS or S | patch | — |
| M | pr | --light |
| L | pr | --full |
| XL | sub_issue | — |
| unset | pr | (safe fallback) |
If route changed from Step 2, output a log line: "Post-spec Size refresh: Size updated to {NEW_SIZE}, route re-determined as {NEW_ROUTE}."
Route demotion (pr → patch only):
If ROUTE changed from pr to patch (i.e., the prior ROUTE was pr and the refreshed ROUTE is patch):
code --patch then verify (skip review and merge)Proceed to Step 4 using the updated ROUTE and REVIEW_DEPTH.
Select the route section below based on the current ROUTE value (set in Step 2 and potentially overridden by Step 3a's route demotion logic).
Run each phase via run-*.sh. Each script launches an independent process with claude -p --dangerously-skip-permissions for a fresh context and full permission bypass.
Execution pattern:
run-*.sh runs as a blocking call (timeout: 600000) in sequencegh pr list (included in allowed-tools)VERIFY_ITERATION_COUNT initialization (single-Issue routes only — skip for batch modes):
Before running any phase, initialize VERIFY_ITERATION_COUNT:
RESUME_MODE=true: call ${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh read_single $NUMBER and set VERIFY_ITERATION_COUNT to the returned value. Output: "Restored verify_iteration_count=$VERIFY_ITERATION_COUNT from checkpoint."
gh issue view $NUMBER --json labels -q '.labels[].name'. If the issue is already at phase/done (label phase/done present), the checkpoint is stale — call ${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh delete_single $NUMBER, set VERIFY_ITERATION_COUNT=0, and output: "Checkpoint discarded: live labels show phase/done."RESUME_MODE is not set (normal mode): set VERIFY_ITERATION_COUNT=0XL route: sub-issue dependency graph with parallel execution (run-auto-sub.sh checks each sub-issue's phase/ready and auto-runs spec if not set):
Read ${CLAUDE_PLUGIN_ROOT}/modules/detect-config-markers.md and follow the "Processing Steps" section. Retain AUTO_MAX_CONCURRENT (maximum concurrent sub-issue executions; default: 5).
Fetch dependency graph:
${CLAUDE_PLUGIN_ROOT}/scripts/get-sub-issue-graph.sh $NUMBER
Parse the result JSON and extract execution_order (array of sub-issue numbers per level).
Run levels in order, in parallel: Process each level in execution_order sequentially.
Run each level's sub-issues in parallel via Bash background (&) with concurrency capped at AUTO_MAX_CONCURRENT, then wait for all to complete:
# For each level (in execution_order order):
Skip sub-issues that depend on failed issues,
then run non-skipped sub-issues with concurrency cap using AUTO_MAX_CONCURRENT:
RUNNING=0
PIDS=()
for each SUB in non-skipped sub-issues:
${CLAUDE_PLUGIN_ROOT}/scripts/run-auto-sub.sh $SUB_NUMBER &
PIDS+=($!)
RUNNING=$((RUNNING + 1))
if [ $RUNNING -ge $AUTO_MAX_CONCURRENT ]; then
# bash 4.3+: wait -n waits for any one child to finish
# bash 3.2 fallback (macOS): kill -0 polling
if (( BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 3) )); then
wait -n
else
while true; do
for pid in "${PIDS[@]}"; do
if ! kill -0 "$pid" 2>/dev/null; then break 2; fi
done
sleep 1
done
fi
RUNNING=$((RUNNING - 1))
fi
done
Wait for all processes with `wait`, check each process exit code
After wait completes, aggregate-update parent phase (run after each level completes):
gh issue view $SUB_NUMBER --json labelsphase/code or later (code/review/verify/done) → parent becomes phase/codephase/verify or later (verify/done) → parent becomes phase/verifyphase/done → handled by close flow judgment (Step 4c); do not aggregate-update here${CLAUDE_PLUGIN_ROOT}/scripts/gh-label-transition.sh $NUMBER <aggregated phase>After aggregate-update, cross-cutting condition pre-verification (best-effort): When a level completes, proactively check the parent XL Issue's cross-cutting Acceptance Criteria:
gh issue view $NUMBER --json body -q '.body'<!-- verify: ... --> commands from the Acceptance Criteria sections (pre-merge and post-merge)${CLAUDE_PLUGIN_ROOT}/modules/verify-executor.md and execute each verify command in full mode/verify $NUMBER to confirm."/verify $NUMBER)On failure:
blocked_by containing) a number in the failure setblocked_by in get-sub-issue-graph.sh output and mark any sub-issue containing a failed Issue number as skip targetCompletion report: After all levels complete, report results (success/failure/skip) for each sub-issue.
Auto retrospective: See "Step 4a: Auto Retrospective" section.
patch route XS/S (2 phases):
Each phase follows the Observe → Diagnose → Act pattern (same as pr route; see above).
${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh code-patch $NUMBER --check-precondition --warn-only${CLAUDE_PLUGIN_ROOT}/scripts/run-code.sh $NUMBER --patch [--base {branch}] via Bash (timeout: 600000)${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh code-patch $NUMBER --check-completion — runs unconditionally regardless of exit code; if matches_expected: false (including exit 0), go to Step 6; if code exited non-zero but matches_expected: true, override to success${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh verify $NUMBER --check-precondition --warn-onlyVERIFY_ITERATION_COUNT=$((VERIFY_ITERATION_COUNT + 1))${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh write_single $NUMBER $VERIFY_ITERATION_COUNTSkill(skill="wholework:verify", args="$NUMBER") in the parent session (enables AskUserQuestion for manual AC confirmation)MAX_ITERATIONS_REACHED: max iterations has been reached; delete checkpoint (${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh delete_single $NUMBER); stop chained execution and proceed to Step 5 (human judgment required — do not re-run verify automatically)${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh delete_single $NUMBER) and proceed to Step 5pr route (4 phases):
Phase transition output format: output [N/M] phase_name before each phase, and [N/M] phase_name → done (details) after success. Example:
[1/4] code
(run-code.sh output)
[1/4] code → done (PR #125)
[2/4] review
...
Each phase follows the Observe → Diagnose → Act pattern:
${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh <phase> <issue> --check-precondition --warn-only — mismatch outputs a stderr warning but does not block execution (stage-1 gradual rollout)<run-*.sh>${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh <phase> <issue> --check-completion; parse JSON output — if matches_expected: true, continue; if matches_expected: false, treat as mismatch and go to Step 6Full phase sequence:
${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh code-pr $NUMBER --check-precondition --warn-only[1/4] code, then run ${CLAUDE_PLUGIN_ROOT}/scripts/run-code.sh $NUMBER --pr [--base {branch}] via Bash (timeout: 600000)${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh code-pr $NUMBER --check-completion — runs unconditionally regardless of exit code; if matches_expected: false (including exit 0), go to Step 6; if matches_expected: true, output [1/4] code → done (PR #N) and continuegh pr list --json number,headRefName | jq -r ".[] | select(.headRefName == \"worktree-code+issue-$NUMBER\") | .number" | head -1${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh review $NUMBER --pr $PR_NUMBER --check-precondition --warn-only[2/4] review, then run ${CLAUDE_PLUGIN_ROOT}/scripts/run-review.sh $PR_NUMBER $REVIEW_DEPTH via Bash (timeout: 600000) (REVIEW_DEPTH set in Step 2, refreshed by Step 3a if applicable); on success output [2/4] review → done${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh review $NUMBER --pr $PR_NUMBER --check-completion — if matches_expected: true, override to success; otherwise go to Step 6${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh merge $NUMBER --pr $PR_NUMBER --check-precondition --warn-only[3/4] merge, then run ${CLAUDE_PLUGIN_ROOT}/scripts/run-merge.sh $PR_NUMBER via Bash (timeout: 600000); on success output [3/4] merge → done${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh merge $NUMBER --pr $PR_NUMBER --check-completion — if matches_expected: true, override to success; otherwise go to Step 6${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh verify $NUMBER --check-precondition --warn-onlyVERIFY_ITERATION_COUNT=$((VERIFY_ITERATION_COUNT + 1))${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh write_single $NUMBER $VERIFY_ITERATION_COUNT[4/4] verify, then invoke Skill(skill="wholework:verify", args="$NUMBER") in the parent session (enables AskUserQuestion for manual AC confirmation); on success output [4/4] verify → doneMAX_ITERATIONS_REACHED: max iterations has been reached; delete checkpoint (${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh delete_single $NUMBER); stop chained execution and proceed to Step 5 (human judgment required — do not re-run verify automatically)${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh delete_single $NUMBER) and proceed to Step 5Skip this step for all routes other than XS patch.
The XS patch route does not go through the /spec phase, so no Spec file exists. To allow the /verify improvement proposal pipeline to collect the issue retrospective, create a Spec file and transcribe it using the following steps.
Read ${CLAUDE_PLUGIN_ROOT}/modules/detect-config-markers.md and follow the "Processing Steps" section. Retain SPEC_PATH for use in subsequent steps.
Check for issue retrospective in Issue comments:
gh issue view "$NUMBER" --json comments -q '.comments[].body'## Issue Retrospective sectionDetermine Spec file path: $SPEC_PATH/issue-$NUMBER-<short-title>.md
short-title as English kebab-case from Issue title (e.g., xs-patch-retro)Create (or update) Spec file and append issue retrospective:
# Issue #$NUMBER: $TITLE heading at the top## Issue Retrospective section at the end of the Spec file (naturally referenced by /verify's Spec reading)Commit and push:
git add $SPEC_PATH/issue-$NUMBER-*.md
git commit -s -m "Add issue retrospective for issue #$NUMBER
Co-Authored-By: Claude Sonnet 4.6 [email protected]" git push origin main
### Step 4a: Auto Retrospective
**Conditions to run this step:**
- **XL route**: always run — record orchestration results for all sub-issues
- **M/L/patch route**: run only when the parent session detects **any** of the following orchestration anomalies; skip if no anomalies are detected:
- (a) A shell wrapper (`run-code.sh`, `run-auto-sub.sh`, etc.) exited non-zero, but subsequent state was manually recovered
- (b) A phase that should have transitioned automatically was manually invoked by the parent session
- (c) `/auto` completed with behavior that differs from the original spec
If no anomalies are detected (M/L/patch route), skip this step — do not record an empty section.
Read `${CLAUDE_PLUGIN_ROOT}/modules/detect-config-markers.md` and follow the "Processing Steps" section. Retain `SPEC_PATH` for use in subsequent steps.
1. **Determine Spec file path**: `$SPEC_PATH/issue-$NUMBER-<short-title>.md`
- Generate `short-title` as English kebab-case from Issue title (e.g., `xl-orchestration-retrospective`)
- If an existing Spec file is found, use it and append `## Auto Retrospective` section
- **If Spec file does not exist** (e.g., XS patch route without spec phase): create a new Spec file with `# Issue #$NUMBER: $TITLE` header, then append `## Auto Retrospective` section
2. **Create (or update) Spec file**:
**XL route** — record full sub-issue summary:
```markdown
# Issue #$NUMBER: $TITLE
## Auto Retrospective
### Execution Summary
| # | Title | Route | Result | Notes |
|---|-------|--------|--------|-------|
(list result for each sub-issue)
### Parallel Execution Issues
- (conflicts, race conditions, recovery history. "None" if no issues)
### Improvement Proposals
- (structural issues and fixes. "N/A" if no proposals)
SUCCESS, non-zero exit code → FAILED (exit code N), dependency skip → SKIPPED (blocked by #X)/verify's Step 13 reads ### Improvement Proposals and creates Issues from themM/L/patch route — append orchestration anomaly record (append to existing Spec; create new Spec with header if none exists):
## Auto Retrospective
### Execution Summary
| Phase | Route | Result | Notes |
|-------|-------|--------|-------|
| code | pr | SUCCESS (manual PR extract fallback) | run-auto-sub.sh exit 1 but PR #N already created |
| review | pr | SUCCESS | manual invocation after wrapper failure |
| merge | pr | SUCCESS | manual invocation |
| verify | - | SUCCESS | |
### Orchestration Anomalies
- (describe each anomaly: which script, what exit code, what state, how manually recovered)
### Improvement Proposals
- (list structural improvements to prevent recurrence. "N/A" if none)
Fetch issue retrospective from Issue comments and transcribe to Spec (XL route only):
gh issue view "$NUMBER" --json comments -q '.comments[].body'## Issue Retrospective## Issue Retrospective section at end of Spec file (naturally referenced by /verify's Spec reading)/issue may not have this)Append recovery events to orchestration-recoveries.md (before Spec retrospective commit):
Read ${CLAUDE_PLUGIN_ROOT}/modules/detect-config-markers.md to confirm SPEC_PATH (already retained from step 1 of this section).
Determine whether any of the following sources contributed recovery events during this run:
| Source | When to append | Dependency |
|---|---|---|
Source 1: fallback-catalog | A catalog entry in orchestration-fallbacks.md was applied during Tier 2 recovery | Available (#315 shipped) |
Source 2: recovery-sub-agent | The orchestration-recovery sub-agent produced a successful recovery plan during Tier 3 recovery | Available (#617 shipped) |
Source 3: wrapper-anomaly-detector | detect-wrapper-anomaly.sh detected a known failure pattern during Tier 2 recovery | Available (#313 shipped) |
Source 2 detection — single-Issue parent session only: Check if TIER3_RECOVERY_PHASE is set (retained in Step 6 after Tier 3 succeeds). If set, use retained TIER3_RECOVERY_* variables to build the entry and prepend it. For batch/XL routes, spawn-recovery-subagent.sh writes directly to orchestration-recoveries.md, so Source 2 here covers only single-Issue parent sessions (M/L/patch). run-auto-sub.sh commits and pushes docs/reports/orchestration-recoveries.md immediately after Tier 3 success to prevent dirty-file conflicts at /verify invocation (see #677).
For each applicable source, prepend a new entry block to docs/reports/orchestration-recoveries.md (after the header comment line <!-- Log entries appear below, newest first. -->). Use the Write/Edit tool. Entry format:
## YYYY-MM-DD HH:MM UTC: <symptom-short>
### Context
- Issue #N, phase: <phase>
- Source: <fallback-catalog|recovery-sub-agent|wrapper-anomaly-detector>
- Wrapper: <run-*.sh name>, exit code: <N>
- Log tail: "<last relevant log line>"
### Diagnosis
- <observed state and root cause>
### Recovery Applied
- <catalog anchor or sub-agent plan excerpt or manual steps>
### Outcome
- <success|partial|failed>
### Improvement Candidate
- <未起票|起票済み #NNN|N/A (resolved by known catalog)>
If no sources contributed recovery events, skip the append (do not create an empty entry).
Add docs/reports/orchestration-recoveries.md to the same git add in the next step.
Commit and push:
git add $SPEC_PATH/issue-$NUMBER-*.md docs/reports/orchestration-recoveries.md
git commit -s -m "Add auto retrospective for issue #$NUMBER
Co-Authored-By: Claude Sonnet 4.6 [email protected]" git push origin main
If no recovery events were appended, omit `docs/reports/orchestration-recoveries.md` from `git add` (only add it when it was actually modified).
6. **Collect and create Improvement Proposal Issues**: Read `${CLAUDE_PLUGIN_ROOT}/modules/retro-proposals.md` and follow the "Processing Steps" section. Use `SPEC_PATH` and `HAS_SKILL_PROPOSALS` already retained from this step's `detect-config-markers.md` call. If the shared module returns no proposals, skip silently.
### Step 4d: XL Sub-issue Verify (XL route only)
**Skip this step for all routes other than XL.**
Run after all sub-issue levels complete (after Step 4a Auto Retrospective) and before Step 4c close flow.
Collect all sub-issue numbers from `get-sub-issue-graph.sh` output (all sub-issues that reached `phase/done` or `phase/verify`), then append the parent issue number: `[sub_issue_1, sub_issue_2, ..., $NUMBER]`.
For each issue number in this list, **serially** in the parent session:
Skill(skill="wholework:verify", args="$N")
This runs verify in the parent context, enabling AskUserQuestion for manual AC confirmation on each issue.
**Skip any sub-issue that**:
- was skipped due to a dependency failure (in the failure set from Step 4 execution)
- already has `phase/done` label (already verified and closed in a prior run)
Continue to the next issue even if one verify invocation ends in FAIL or MAX_ITERATIONS_REACHED — the close flow in Step 4c will assess the final state.
### Step 4c: XL Parent Issue Close Flow (XL route only)
**Skip this step for all routes other than XL.**
Determine the close flow for the parent Issue based on all sub-issue execution results.
1. **Confirm all sub-issues succeeded (`phase/done`)**:
- If any sub-issue failed or was skipped: skip close flow and leave parent phase as-is (do not close)
2. **If all children are `phase/done`**: check for unchecked (`- [ ]`) conditions in the post-merge section of the parent Issue body:
- Fetch post-merge section with `gh issue view $NUMBER --json body`
- Check if any unchecked `- [ ]` conditions remain
3. **No unchecked cross-cutting conditions**: auto-close the parent:
```bash
${CLAUDE_PLUGIN_ROOT}/scripts/gh-label-transition.sh $NUMBER done
gh issue close $NUMBER
phase/verify and post a notification comment:
${CLAUDE_PLUGIN_ROOT}/scripts/gh-label-transition.sh $NUMBER verify
gh issue comment $NUMBER --body "All sub-issues are complete. The parent Issue has remaining manual acceptance conditions. Run \`/verify $NUMBER\` after reviewing."
Leave the parent Issue open. The user runs /verify $NUMBER for final confirmation before closing.If all phases succeeded:
Check for opportunistic pending state: Run gh issue view $NUMBER --json labels --jq '.labels[].name'
CI FAIL/recovery scan (build Notes before result table):
Scan the run-*.sh output captured in the LLM context during Step 4 for CI check failures and auto-recovery events in each phase:
gh pr checks-style output lines containing fail or FAILED (e.g., Run bats / bats (push) fail)MUST issue resolved / MUST issue auto-resolved, or commit messages beginning with Fix: added as follow-up commits in the review phaseFor each phase where a CI failure or auto-fix is detected, record a concise one-line Notes value for the result table:
1 CI fail → fixed in abc12341 MUST issue auto-resolved2 CI fails → fixed; 1 MUST issue resolved (multiple events in one phase)If nothing is detected for a phase, leave Notes as —.
If output from step 1 contains phase/verify (opportunistic pending): output the partial success — opportunistic pending banner:
/auto #N partial success — opportunistic pending
TITLE
URL
Followed by a result table (one row per phase with status, Notes from step 2).
Then enumerate unchecked post-merge conditions from the Issue body:
gh issue view $NUMBER --json body -q '.body'### Post-merge or ## Post-merge heading, up to the next ## heading or end of file)- [ ] within that section- [ ] prefix and remove any <!-- verify: ... --> HTML comment substrings, then trim whitespace to produce human-readable condition text - - prefix, then output ... and N more (where N is the total count minus 5)After the list (or result table if no conditions), output: "Run `/verify $NUMBER` after confirming them manually."
If output from step 1 does not contain phase/verify: output the completion banner:
/auto #N complete
TITLE
URL
Followed by a result table (one row per phase with status, Notes from step 2).
If an Auto Retrospective was recorded in the Spec (XL routes: always; M/L/patch routes: when orchestration anomalies were detected), also output "Auto retrospective recorded in Spec".
Then read ${CLAUDE_PLUGIN_ROOT}/modules/next-action-guide.md and follow the "Processing Steps" section with:
SKILL_NAME=autoISSUE_NUMBER=$NUMBERRESULT=successEvent-based observation scan (auto-run event, runs after Completion Report regardless of success/failure):
Run ${CLAUDE_PLUGIN_ROOT}/scripts/observation-trigger.sh --event auto-run
Daily rollup (best-effort, runs after observation scan regardless of success/failure):
Run ${CLAUDE_PLUGIN_ROOT}/scripts/auto-events-rollup.sh. If the command fails, output "Warning: auto-events-rollup failed. Session will continue." and proceed without blocking.
If any phase exits with a non-zero exit code, apply the following 3-tier recovery hierarchy before stopping.
Always first: Write the failed phase's output to .tmp/wrapper-out-$NUMBER-$PHASE.log using the Write tool (needed by Tier 2 anomaly detector).
Run the completion check for the failed phase:
${CLAUDE_PLUGIN_ROOT}/scripts/reconcile-phase-state.sh <phase> $NUMBER --check-completion
Parse the JSON output. If matches_expected: true: the phase actually succeeded despite wrapper exit non-zero — override to success and continue to the next phase (skip Tier 2 and Tier 3).
If matches_expected: false: proceed to Tier 2.
Run the anomaly detector:
${CLAUDE_PLUGIN_ROOT}/scripts/detect-wrapper-anomaly.sh --log .tmp/wrapper-out-$NUMBER-$PHASE.log --exit-code $EXIT_CODE --issue $NUMBER --phase $PHASE
If detector output is non-empty (known pattern matched):
${CLAUDE_PLUGIN_ROOT}/modules/detect-config-markers.md to get SPEC_PATH$SPEC_PATH/issue-$NUMBER-*.md) under ## Auto Retrospective, and commit and push${CLAUDE_PLUGIN_ROOT}/modules/orchestration-fallbacks.md and follow the catalog entry matching the detected pattern to apply the recovery stepsmid-run-api-error pattern: run reconcile-phase-state.sh <phase> $NUMBER --check-completion;
if matches_expected: true override to success; if matches_expected: false inspect
hint_* fields in actual JSON to restore the phase label, then retry the failed phase
once via the corresponding run-*.sh scriptIf detector output is empty (unknown pattern): proceed to Tier 3.
Spawn the orchestration-recovery sub-agent via Task to diagnose the unknown failure and produce a recovery plan:
Collect inputs:
phase: the failed phase name (e.g., code-pr, review, merge, verify)exit_code: wrapper exit codelog_tail: last 200 lines of .tmp/wrapper-out-$NUMBER-$PHASE.logreconcile_snapshot: JSON output from the Tier 1 reconcile-phase-state.sh --check-completion callissue_number: $NUMBERissue_labels: output of gh issue view $NUMBER --json labels -q '.labels[].name'pr_number: $PR_NUMBER if available, otherwise empty stringbranch: current worktree branch if availableSpawn the sub-agent:
Task: agents/orchestration-recovery.md
Prompt: (pass all inputs from step 1)
Write the sub-agent's output (the raw JSON) to .tmp/recovery-plan-$NUMBER-$PHASE.json using the Write tool.
Safety guard — validate the recovery plan:
${CLAUDE_PLUGIN_ROOT}/scripts/validate-recovery-plan.sh .tmp/recovery-plan-$NUMBER-$PHASE.json
action, rationale, steps) present, action in {retry, skip, recover, abort}, steps length ≤ 5, no forbidden ops (force_push, reset_hard, close_issue, merge_pr, direct_push_main)Act on recovery plan:
action=retry: re-run the failed phase once (same run-*.sh call with same arguments); if it fails again, fall back to stop-and-reportaction=skip: treat the phase as complete and continue to the next phaseaction=recover: execute steps sequentially; if all steps succeed, continue to the next phase; if any step fails, fall back to stop-and-reportaction=abort: fall back to stop-and-report immediately5b. Retain recovery state (on successful recovery — action is not abort):
Retain the following as in-context variables for use in Step 4a Source 2:
TIER3_RECOVERY_PHASE=$PHASETIER3_RECOVERY_ACTION=$action (the action that succeeded)TIER3_RECOVERY_RATIONALE: rationale field from the recovery plan JSONTIER3_RECOVERY_STEPS_COUNT: number of steps in the plan (0 for retry/skip)TIER3_RECOVERY_EXIT_CODE=$EXIT_CODETIER3_RECOVERY_LOG_TAIL: last line of .tmp/wrapper-out-$NUMBER-$PHASE.logrm -f .tmp/recovery-plan-$NUMBER-$PHASE.json .tmp/wrapper-out-$NUMBER-$PHASE.logIf all tiers are exhausted without recovery, stop processing and output the stopped banner:
/auto #N stopped at PHASE
TITLE
URL
Followed by a result table (one row per phase; use - for unexecuted phases).
Do not invoke subsequent phases.
Manual recovery hand-off: If the parent session manually recovers and continues to subsequent phases instead of stopping here, complete the remaining phases via manual recovery first, then follow Step 4a (after all phases are done) to append anomaly details and improvement proposals to the Spec's ## Auto Retrospective > ### Orchestration Anomalies and ### Improvement Proposals sections, then proceed to Step 5. Note: if the Tier 2 anomaly detector already appended a known pattern, skip the ### Orchestration Anomalies / ### Improvement Proposals append in Step 4a to avoid duplicate entries.
Then read ${CLAUDE_PLUGIN_ROOT}/modules/next-action-guide.md and follow the "Processing Steps" section with:
SKILL_NAME=autoISSUE_NUMBER=$NUMBERRESULT=failWhen --batch is detected in Step 1, process Issues sequentially (skip Steps 2–6).
Two modes:
--batch N): selects the N most recent XS/S Issues from the backlog--batch N1 N2 ...): processes the explicitly listed Issues in the user-specified order (任意の Issue 番号を空白区切りで指定)既存の --batch N の挙動は変更せず後方互換で維持する。
gh issue list --state open --label triaged --json number,title,labels,createdAt --limit 200
For each candidate, call ${CLAUDE_PLUGIN_ROOT}/scripts/get-issue-size.sh $NUMBER;
exclude Issues where Size is M, L, or XL (Projects V2 field first, label fallback).
Sort by createdAt descending (newest first) and select the top N. Targets: Issues with no Size set, XS, or S.
Process the selected N Issues sequentially (serially):
gh issue view $NUMBER --json labels -q '.labels[].name'phase/* labels: run ${CLAUDE_PLUGIN_ROOT}/scripts/run-issue.sh $NUMBER (issue triage → Size setting → phase/ready assignment)
${CLAUDE_PLUGIN_ROOT}/scripts/get-issue-size.sh $NUMBER; if Size is M, L, or XL: output a warning and skip to the next Issue (do not abort the entire batch)${CLAUDE_PLUGIN_ROOT}/scripts/run-auto-sub.sh $NUMBER (all phases spec→code→review→merge→verify, auto-starting from the current phase/* state)
BATCH_LIST に記録された Issue 番号を、ユーザが渡した順序(指定順)で順次処理する(並び替えなし)。
候補取得(Fetch Batch Candidates)および createdAt ソートは List mode では行わない。
許容 Size: XS/S/M/L。ユーザが明示指定した以上、その意思は heuristic より強いシグナルのため Size 制限を緩和する。XL のみ例外で、警告を出して当該 Issue を skip し、残りの Issue は継続処理する(XL はサブ Issue 依存グラフによる並列実行経路を持ち、batch の直列処理と噛み合わないため)。
Batch checkpoint initialization (List mode only):
At the start of List mode, generate a BATCH_ID and write the full batch state:
BATCH_ID="${PPID}-$(date +%s)"
${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh write_batch "$BATCH_ID" "N1 N2 N3" "" ""
(BATCH_ID is used for all subsequent checkpoint calls in this batch session; first list arg: space-separated full list in double quotes — quoting is required when the list contains spaces; remaining args: empty strings for completed and failed)
Process each Issue in BATCH_LIST in order:
gh issue view $NUMBER --json labels -q '.labels[].name'phase/* labels: run ${CLAUDE_PLUGIN_ROOT}/scripts/run-issue.sh $NUMBER (issue triage → Size setting → phase/ready assignment)
${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh update_batch "$BATCH_ID" $NUMBER fail; skip to the next Issue (do not abort the entire batch)${CLAUDE_PLUGIN_ROOT}/scripts/get-issue-size.sh $NUMBER; if Size is XL: output a warning; call ${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh update_batch "$BATCH_ID" $NUMBER fail; skip to the next Issue (do not abort the entire batch)gh issue view $NUMBER --json body -q '.body' | grep -ioE "blocked by #[0-9]+" | grep -oE "[0-9]+"
$BLOCKER:
gh issue view $BLOCKER --json state,labels -q '{state: .state, phases: [.labels[].name | select(startswith("phase/"))]}'
state is "CLOSED" or phases contains "phase/done": gate released — continue to next blocker$BLOCKER_PHASE (first phase/* label of blocker, or "OPEN" if no phase/* label); output warning and skip $NUMBER (do NOT call update_batch — keeps $NUMBER in remaining for /auto --batch --resume):
Warning: #$NUMBER blocked by #$BLOCKER which is $BLOCKER_PHASE (manual post-merge pending). Skipping #$NUMBER. After completing #$BLOCKER manually, resume with /auto --batch --resume.
${CLAUDE_PLUGIN_ROOT}/scripts/run-auto-sub.sh $NUMBER (all phases spec→code→review→merge→verify, auto-starting from the current phase/* state)
${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh update_batch "$BATCH_ID" $NUMBER fail; skip to the next Issue (do not abort the entire batch)gh issue view $NUMBER --json labels -q '.labels[].name'phase/verify is present in labels:
--non-interactive is NOT in ARGUMENTS: invoke Skill(skill="wholework:verify", args="$NUMBER") in the parent session
${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh update_batch "$BATCH_ID" $NUMBER completeMAX_ITERATIONS_REACHED: output a warning; call ${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh update_batch "$BATCH_ID" $NUMBER fail; skip to the next Issue--non-interactive IS in ARGUMENTS: output "Skipping verify for #$NUMBER (non-interactive mode); phase/verify remains"; call ${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh update_batch "$BATCH_ID" $NUMBER completephase/verify is NOT in labels: call ${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh update_batch "$BATCH_ID" $NUMBER completeAfter all Issues are processed, delete the batch checkpoint:
${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh delete_batch "$BATCH_ID"
Entered from Step 1 when --batch --resume is detected with no numeric tokens after --batch.
${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh list_active_batches and capture the output as ACTIVE_BATCH_IDS (newline-separated list).
ACTIVE_BATCH_IDS is non-empty:
BATCH_IDACTIVE_BATCH_IDS is empty: fall back to BATCH_ID="default" (handles pre-BATCH_ID migration case where .tmp/auto-batch-state.json may exist from an older run)${CLAUDE_PLUGIN_ROOT}/scripts/auto-checkpoint.sh read_batch "$BATCH_ID" and capture the output as REMAINING.REMAINING is empty: output "No resume target found. Run /auto --batch N1 N2 ... to start a new batch." and exit.REMAINING as BATCH_LIST and process each Issue following the same steps as ### List mode (--batch N1 N2 ...).
write_batch again at the start (the existing batch state file is the live state); only call update_batch "$BATCH_ID" and delete_batch "$BATCH_ID" as per List mode.After all Issues are processed, report results (success/skip/failure) for each Issue.
Then read ${CLAUDE_PLUGIN_ROOT}/modules/next-action-guide.md and follow the "Processing Steps" section with:
SKILL_NAME=autoRESULT=successISSUE_NUMBER — batch run with multiple issues, guide will be omitted per module logic)/issue is complete (spec is auto-run if not yet complete)auto itself does not post Issue comments (posted individually within each phase)${CLAUDE_PLUGIN_ROOT} at runtime/auto --resume N resumes a single Issue after interruption. The authority for the current phase is GitHub labels + reconcile-phase-state.sh — the checkpoint is a hint only.
| Information | Authority source (SSoT) | Checkpoint role |
|---|---|---|
| Current phase | GitHub labels (phase/*) + reconcile-phase-state.sh | Not consulted (labels take priority) |
| PR number | gh pr list (live query) | Not stored |
| Route (patch/pr/XL) | Derived from Size | Not stored |
| verify iteration_count | None (in-run variable only) | Persisted (cross-run limit management) |
| Batch remaining list | None | Persisted (incomplete Issue list) |
When checkpoint and labels conflict, labels win and the checkpoint is discarded (stale).
// .tmp/auto-state-NUMBER.json (single Issue)
{
"schema_version": "v1",
"issue_number": 317,
"verify_iteration_count": 2,
"last_update": "2026-04-22T16:10:05Z"
}
// .tmp/auto-batch-state-${BATCH_ID}.json (batch, per-session)
// BATCH_ID="default" -> .tmp/auto-batch-state.json (backward compat)
// BATCH_ID="12345-1718336400" -> .tmp/auto-batch-state-12345-1718336400.json
{
"schema_version": "v1",
"mode": "list",
"remaining": [104, 105],
"completed": [101, 102],
"failed": [103],
"last_update": "2026-04-22T16:10:05Z"
}
// .tmp/auto-batch-active.json (active batch index)
{
"schema_version": "v1",
"active_batch_ids": ["12345-1718336400", "67890-1718336500"],
"last_update": "2026-04-22T16:10:05Z"
}
BATCH_ID format: ${PPID}-$(date +%s) (parent PID + Unix timestamp; bash 3.2+ compatible)"default" BATCH_ID maps to .tmp/auto-batch-state.json and is not tracked in the active index/auto --batch sessions each use a distinct BATCH_ID, so their state files do not collideWrites are atomic: write to *.json.tmp then mv to the target path to prevent corrupt reads on interruption.
A checkpoint is considered stale and must be discarded when either of the following holds:
issue_number field in .tmp/auto-state-NUMBER.json does not match NUMBER (handled by auto-checkpoint.sh read_single — returns 0 and exits 0)phase/done for the issue while a checkpoint exists (handled by /auto Step 4 initialization — calls delete_single and resets count to 0)In both cases, the label + reconciler state is the authority and the checkpoint is dropped.
| Event | Cleanup action |
|---|---|
| Verify loop succeeds | delete_single $NUMBER |
MAX_ITERATIONS_REACHED | delete_single $NUMBER |
Issue CLOSED / phase/done detected at resume | delete_single $NUMBER (stale label conflict path) |
| Batch fully processed | delete_batch "$BATCH_ID" (also removes from active index) |
.tmp/ files are gitignored and are not committed.
XL route checkpoint (sub-issue dependency graph + parallel worktree state) is out of scope for this implementation. XL sub-issues can each be individually resumed with /auto --resume N on their sub-issue numbers.
npx claudepluginhub saitoco/wholework --plugin wholeworkCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.