name: wf-resume description: Resumes an interrupted waterfall workflow — preflight, need lookup, Agent Teams team re-creation, OR handoff with resume brief. user-invocable: false allowed-tools: Read, Grep, Glob, Bash, AskUserQuestion, Skill, TeamCreate
wf-resume — Resume an interrupted workflow
This skill is the entry point to resume a paused or interrupted waterfall need. It is invoked by the /waterfall:resume command.
Resume flow
Step 1 — Preflight (fail-fast)
bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-check-bash.sh
If not running under bash (Git Bash on Windows) → the script fails with an explicit message. STOP.
bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-check-teams.sh
If the CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS flag is missing → the script fails with an explicit message. STOP.
jq verification (used by all wf scripts to parse .wf-state.json, ack-registry.json, etc.):
INSTALL_CMD=$(bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-check-jq.sh) || JQ_RC=$?
- Exit 0 → continue.
- Exit 2 →
jqmissing. If$INSTALL_CMDnon-empty,AskUserQuestion: "jq is required. Install it via${INSTALL_CMD}?" (Yes / No). On Yes:bash -c "$INSTALL_CMD"then re-run the check. On No or if command empty: display stderr and stop.
Step 1.a — Resolve WF_SID (new HO window)
Critical for statusline (INV-002): on resume, $CLAUDE_SESSION_ID is a fresh sid (new Claude Code window) that does not match the session_id stored in .wf-state.json. We must force WF_SID to the current HO sid so the --reactivate migration takes place.
export WF_SID="${CLAUDE_SESSION_ID}"
Without this, the statusline (which filters on state.session_id == $CLAUDE_SESSION_ID) will not display the resumed need.
Step 1.bis — Same-sid ambiguity detection (EX-005)
Note: when resuming in a new window,
WF_SIDis a fresh sid that won't match any state. This step is effectively a no-op on resume; it remains useful if/waterfall:resumeis invoked in the same window as a workflow that was just abandoned.
If WF_SID is set and no <name> is provided as argument:
# Count needs whose session_id == $WF_SID
matches=()
for state in C:/projets/waterfall/wf/needs/*/.wf-state.json; do
[[ -f "$state" ]] || continue
state_sid=$(jq -r '.session_id // ""' "$state" 2>/dev/null)
[[ "$state_sid" == "$WF_SID" ]] && matches+=("$(dirname "$state" | xargs basename)")
done
if [[ ${#matches[@]} -ge 2 ]]; then
# AskUserQuestion: pick among the needs (one option per need)
fi
Step 1.quater — Config read
source ${CLAUDE_PLUGIN_ROOT}/scripts/wf-read-config.sh
# No template copy (need directory already exists)
# watchdog and agent_mode apply normally
Conditional watchdog (after OR re-spawn)
if [[ "$WF_WATCHDOG_INTERVAL" != "off" ]]; then
DELAY_MIN="${WF_WATCHDOG_INTERVAL//min/}" # "3min" → "3"
CronCreate(cron: "*/${DELAY_MIN} * * * *", prompt: "watchdog tick wf-<name>", recurring: true)
# Belt-and-suspenders: touch the marker that OR checks
echo "<cron_job_id>" > wf/needs/<name>/.watchdog-cron-active
# HO message: "Watchdog active (${WF_WATCHDOG_INTERVAL})"
fi
Step 2 — Need lookup via wf-orchestrate.sh
bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-orchestrate.sh --list
Returns a JSON array of needs with {name, phase, step, status, last_updated}.
Cases:
- No active need: inform HO, STOP
- Single active need: automatic selection as
<name> - Multiple active needs:
AskUserQuestionto HO to pick (one option per need,label= name,description=<phase>:<step> [status])
Step 3 — Orphan worktree detection (optional MVP)
git worktree list --porcelain
Identify worktree-dv* entries whose directory no longer exists. If orphans detected, propose cleanup to HO via AskUserQuestion. If approved: git worktree prune.
Step 4 — Lookup table phase → agents to re-spawn
Read bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-orchestrate.sh <name> --query to know the current_phase.
| Resume phase | Agents to re-spawn |
|---|---|
| BOOTSTRAP | OR alone (restart bootstrap) |
| REQUIREMENTS / FUNCTIONAL_SPECS | OR + PO |
| TECHNICAL_DESIGN | OR + TL (+ DS if has_ui: true in PRD.md) |
| REVIEW | OR + RV + relevant authors (PO/TL/DS depending on phase) |
| PLANNING | OR + TL |
| IMPLEMENTATION | OR + TL + DV pool (1-3 DV depending on remaining load) |
| VALIDATION | OR + QA |
| CLOTURE | OR (PM handles alone) |
Step 5 — Team re-creation and OR spawn
- Load the
wf-pmskill viaSkill({name: "wf-pm"}). The main conversation thus adopts PM responsibilities — PM is never spawned as a separate agent (aligned withwf-newstep 3). The team-lead created byTeamCreateIS the main. - PM (= main) executes TeamCreate according to
agent_mode:if [[ "$WF_AGENT_MODE" == "team" ]]; then TeamCreate wf-<name> else # Subagent mode: spawn OR via Agent tool, no TeamCreate fi - PM (= main) may clear the traceability registry (optional, DEC-001):
bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-registry.sh clear <name>DEC-001: traceability only — enforcement uses
agent_typefrom the harness payload. Skipping this step does not prevent teammates from completing their steps. - PM (= main) spawns OR first via
Agent(subagent_type=waterfall:wf-or, name=or, team_name=wf-<name>). For traceability (optional):bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-registry.sh add <name> <or_agent_id> or - PM (= main) sends the resume brief to OR via
SendMessage:
<brief>
<task_id>BRIEF-RESUME-<timestamp></task_id>
<phase>RESUME</phase>
<besoin><name></besoin>
<besoin_dir>wf/needs/<name>/</besoin_dir>
<action>resume</action>
<current_phase><phase read from --query></current_phase>
<context>
<note>Session interrupted. Read .sdd-state.json via --query and or.log to reconstruct the state.</note>
</context>
</brief>
- OR executes its resume sequence:
a.
bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-orchestrate.sh <name> --reactivate --session "${CLAUDE_SESSION_ID}"→ migratesstate.session_idto the current HO sid (INV-002), recreates thewf-session-active.<sid>markers, opens a newsession_segmentin.wf-state.json(auto-heal if previous segment left open — ADR-008). Always pass$CLAUDE_SESSION_ID, never raw$WF_SID: when resuming in a new window,WF_SIDmay be inherited from a previous session. b.bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-orchestrate.sh <name> --query→ read.sdd-state.jsonc. Reador.logto understand the last successful action d. Re-validate state ↔ on-disk artifacts consistency e. Re-spawn the teammates per the lookup table (viaspawn_requestto PM). For traceability, PM may register each teammate in the registry (bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-registry.sh add <name> <uuid> <role>) — optional since DEC-001. f. Send<resume_context>resume briefs to each re-spawned agent g. ReturnSTATUS_REPORTto PM describing where the workflow stands
Step 6 — PM reactive loop
Identical to wf-new step 5. PM handles the workflow reactively from the resume point.
State consistency (key difference vs wf-new)
Before resuming, OR MUST verify:
- The on-disk artifacts match what the state file expects (e.g. if state =
FUNCTIONAL_SPECSdone, thenspecs.mdmust exist) - No task in
tasks.mdis in an impossible state (e.g. DONE without TL Review = APPROVED) - The iteration counter in
review.mdmatches the state file
If disagreement detected → OR returns NEED_PM_DECISION with details, PM asks HO what to do (manual fix, rollback, or abort).
Rules
- Never restart from BOOTSTRAP — always resume at the current step
- Mandatory wf-check-teams preflight — fail-fast if Agent Teams flag absent
- Mandatory consistency check — prevents resuming on a corrupted state
- Silent recovery preferred — only disturb HO if the state is genuinely corrupted
- One question at a time to HO (need selection, worktree cleanup)
- Agent Teams model only — no legacy subagent model. Use
TeamCreate+SendMessageexclusively.
IMPORTANT — SendMessage plain text obligatoire : le paramètre
messagedeSendMessagen'accepte questring. Utiliser le format plain textclé: valeur— jamais d'objet{...}, jamaisJSON.stringify().