Skip to content

T-1QO7-task-work-resumes-from-verify-stamp-commit

Status: closed/done · Impact: medium · Complexity: small

Auto-generated from a /sdlc:task-work post-mortem. Review and promote to open/ready before picking up.

When a previous /sdlc:task-work run exits prematurely between Step 5a (ensure-ready ran, docs(tasks): verify <basename> implementation-ready committed on the feat branch) and Step 5b (status flip + start-commit on main), the user is left in a half-finished state with no clean way to resume. Today, restarting /sdlc:task-work from scratch will re-run ensure-ready (a no-op when the stamp is fresh) but the parent has no signal to skip directly to Step 5b. A small auto-detect at start time closes this loop and makes resume-after-crash a one-command operation instead of a hand-crafted orchestrator prompt.

The premature-exit failure mode just bit T-RNW9-task-close-out-verifies-pr-on-main: a sub-agent ran ensure-ready (which emits READY: <basename>), then mistook that marker for the task-work final verdict and exited. The actual implementation never happened. Recovery required the orchestrator to hand-craft a “resume at Step 5b” prompt that named the exact worktree path, branch state, and step to jump to. The skill itself offered no support.

Concretely, Step 2’s pre-flight checks today refuse to proceed if “A worktree already exists at .claude/worktrees/<basename>” or “A branch already exists named feat/<basename>” — so the natural “just rerun task-work” recovery is actively blocked.

Step 2’s pre-flight grows a resume-detection branch: if all of the following hold, skip Step 4 (worktree create) and Step 5a (ensure-ready) and jump directly to Step 5b:

  • Task status on main is open/ready (the start-commit never landed).
  • A worktree exists at .claude/worktrees/<basename>.
  • A branch feat/<basename> exists.
  • The feat branch HEAD commit subject matches docs(tasks): verify <basename> implementation-ready (ensure-ready’s stamp commit).
  • No PR is open referencing this task.

The same logic should surface the resume as a visible decision to the user via AskUserQuestion (“Detected a prior task-work run that stalled after ensure-ready. Resume at Step 5b, or start over?”) rather than silently jumping — the user might prefer to nuke the worktree and rerun the gate.

  1. Add the resume-detection check to plugin/skills/task-work/SKILL.md Step 2, between the existing pre-flight blocks and the relevance-check section.
  2. Document the marker-confusion failure mode in the skill’s Notes (it’s the motivating example for why this check exists).
  3. Optionally: add an invariants entry pinning the literal commit subject docs(tasks): verify <basename> implementation-ready so the detection can’t drift from the ensure-ready stamp shape.
  • plugin/skills/task-work/SKILL.md — Step 2 gains resume-detection branch; Notes gains the failure-mode explainer.
  • plugin/skills/task-work/invariants.yaml — pin the verify-stamp commit subject so the detection logic doesn’t drift from ensure-ready’s stamp shape.
  • AC-1: Given a stale half-finished state (open/ready on main, worktree exists, feat branch HEAD is the verify-stamp commit, no PR), /sdlc:task-work <slug> offers a resume option via AskUserQuestion and on accept jumps straight to Step 5b without re-creating the worktree or re-running ensure-ready.
  • AC-2: The pre-existing “worktree already exists” / “branch already exists” blockers remain in force for every other combination (e.g. branch exists but HEAD is not the verify-stamp; PR is open).
  • Detecting and recovering from premature exits at other steps (mid-Step 6 implementation, mid-Step 8 post-mortem). Each step has its own recovery shape; start with the most common failure mode (5a→5b boundary, which is the marker-confusion case).
  • Auto-cleaning a stale worktree when the user picks “start over”. Manual git worktree remove --force is fine for now.
  • none

Spawned by /sdlc:task-work post-mortem of T-RNW9-task-close-out-verifies-pr-on-main on 2026-05-20. The marker-confusion failure was directly observed when a parallel sub-agent for this task exited after ensure-ready returned READY:, requiring a hand-crafted resume prompt.

Captured by /sdlc:task-work on 2026-05-21. PR: pending.

  • AC-1: agent-manual — read the new Step 2 “Resume detection” prose end-to-end; confirmed it spells out all five conditions, defers to AskUserQuestion, defaults to stop, and on resume jumps to Step 5b while skipping Step 4 and Step 5a. Cannot be auto-verified without simulating a stalled state and dispatching a sub-agent against it.
  • AC-2: agent-manual — read the same prose; confirmed the “Any other combination … falls through to the existing pre-flight blockers above (they remain in force)” sentence preserves the pre-existing worktree/branch/PR blockers for every off-pattern shape. Same simulation caveat as AC-1.
  • The lint_skill_prose.py invariant pin caught the new verify-stamp-subject phrase requirement immediately on the first quality-check run — no manual cross-check needed to confirm the Step 2 prose included the literal commit subject.
  • The Step 5b rebase conflict on frontmatter (start-commit’s fresh last_reviewed vs verify-stamp’s fresh readiness_verified_at) was unambiguous once the conflict markers were visible: keep both fresh values, drop both stale ones. Took one Edit to resolve.
  • start_task.py rebase conflicted on the task frontmatter because the start-commit (on main) updated last_reviewed to today while the verify-stamp commit (on the feat branch) updated readiness_verified_at to the same day’s timestamp — both rewrote adjacent lines in the same hunk. This is the exact gap that T-H0W9-task-work-rebase-frontmatter-conflict exists to close, and it triggered cleanly on this run. No additional gap to spawn — that task is already in the queue and this run is more evidence for its impact. → T-H0W9-task-work-rebase-frontmatter-conflict
  • The orchestrator-dispatched flow had to interactively resolve the rebase conflict inline. If 2026-05-20-task-work-rebase-frontmatter-conflict ships a merge driver or a smarter merge in start_task.py, this whole class of friction goes away. → T-H0W9-task-work-rebase-frontmatter-conflict

← Back to Tasks