Skip to content

T-O4I9-refactor-task-work-step-2-via-skill-refine

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

/sdlc:task-work Step 2 (“verify task is workable”) carries ~40 lines of prose for a bundle of deterministic checks: status enum gate, worktree-exists, branch-exists, PR-exists, plus a 5-condition resume-detection. The PR-exists check uses a freetext gh pr list --search "<basename>" that incorrectly matches spec PRs on docs/ branches whose file lists contain the task spec (concrete repro: PR #134). The original framing of this task was a surgical fix to that one query, but the entire Step 2 block is script-shaped — the deterministic parts belong in a precheck_task.py (or the unified sdlc task precheck CLI), and the SKILL.md should reduce to “run the precheck; act on the marker.”

This is the second user of T-ELV7-prototype-skill-refine-skill, following the Step 4 refactor in T-33C0-refactor-task-work-step-4-via-skill-refine. Same extraction pattern; same depends_on gate.

Drop the feat/ legacy prefix entirely from the new code path. The branch-naming convention has finished its transition; in-flight feat/<basename> branches are rare and should be renamed by their owners, not accommodated indefinitely by every reader.

LocationRole today
plugin/skills/task-work/SKILL.md (Step 2)~40 lines of prose for status enum gate, worktree-exists check (git worktree list), branch-exists check (git branch --list 'task/<basename>' 'feat/<basename>'), PR-exists check (gh pr list --search "<basename>"), planning/* prompt branch, and 5-condition resume-detection sub-block. All deterministic except the planning/* AskUserQuestion prompt.
plugin/skills/task-work/SKILL.md (resume-detection sub-section of Step 2)A second gh pr list --search "<basename>" call. Same freetext-search problem.
plugin/conventions/branch-naming.mdDocuments task/<basename> as the implementation prefix; docs/<basename> for spec PRs. feat/<basename> is named as the legacy prefix during transition.
plugin/skills/task-work/invariants.yamlPins phrases from Step 2 (the gh pr list line). Will need updating once Step 2 prose is replaced.
plugin/scripts/Has no precheck_task.py. The current closest analogue is start_task.ts (used by Step 5b), which is also a small deterministic helper called from a SKILL.md Step.

Step 2 of task-work/SKILL.md reduces to roughly:

## 2. Verify the task is workable
Run the precheck:
${CLAUDE_PLUGIN_ROOT}scripts/precheck_task.py <basename>
Act on the stdout marker:
- `OK` — proceed to Step 2a (lease acquire).
- `BLOCKED-CLOSED status=<closed/...>` — surface and stop.
- `BLOCKED-IN-PROGRESS status=<in-progress[/blocked]>` — surface and stop.
- `BLOCKED-WORKTREE path=<...>` — surface and stop.
- `BLOCKED-BRANCH name=<task/<basename>>` — surface and stop.
- `BLOCKED-PR pr=#<N>` — surface and stop.
- `RESUME-AT-5B` — ask the user (resume vs start-over) via
AskUserQuestion; on resume, skip Steps 3, 4, 5a and jump to 5b.
- `PROMPT-PLANNING status=<planning/...>` — ask the user
(proceed-anyway vs stop) via AskUserQuestion; default stop.
Relevance check still happens in prose (it requires LLM judgment).

The new script (plugin/scripts/precheck_task.py, or sdlc task precheck under the unified CLI) owns:

  • The status enum gate (closed/, in-progress/, planning/, open/ — emits the right marker per status family).
  • The worktree-exists check (parse git worktree list).
  • The branch-exists check — only task/<basename>, not feat/.
  • The PR-exists check — scoped to head:task/<basename>, not freetext. A spec PR on docs/... stops matching by construction; no file-list inspection needed.
  • The 5-condition resume-detection (status on main = open/ready AND worktree exists AND branch exists AND HEAD commit subject = “docs(tasks): verify implementation-ready” AND no PR open) — emits RESUME-AT-5B when all five hold.

Output is one line per call: <MARKER> [key=value].... The SKILL.md branches on the marker; AskUserQuestion is the SKILL’s job, not the script’s (judgment lives in prose).

The extraction is performed by /skill-refine from T-ELV7-prototype-skill-refine-skill, same as the Step 4 refactor.

  1. Wait for T-ELV7-prototype-skill-refine-skill to ship. Same gate as the Step 4 refactor task.
  2. Invoke /skill-refine plugin/skills/task-work/SKILL.md "## 2". Review the extraction proposal.
  3. Confirm the proposal includes the feat/ deletion. This is the spec’s explicit request; the script does NOT search feat/<basename> branches.
  4. Confirm the PR-search uses head:task/<basename> scoping. The freetext-search bug from the original framing is fixed by construction.
  5. Let skill-refine generate the script and rewrite Step 2. Verify the resulting SKILL.md passes check_skill_prose.py and the pipe-tail check.
  6. Migrate plugin/skills/task-work/invariants.yaml — drop pinned phrases from old Step 2 prose; pin the new shape (presence of the script call line, AskUserQuestion branches for planning/* and resume).
  7. Add regression tests for the new script. Cover at least: each of the 7 markers, the head:task/ scoping (a spec PR on docs/<basename> does NOT block), the 5-condition resume detection (all four “any-but-not-all” cases of the conditions surface as OK, not RESUME-AT-5B).
  8. Update docs/skills/task-work.md flowchart if Step 2 nodes change shape.
LocationKindChange
plugin/scripts/precheck_task.pynewThe extracted script. Owns status enum gate, worktree/branch/PR existence checks, resume detection. No feat/ legacy.
plugin/skills/task-work/SKILL.mdmodifyReplace ~40 lines under ## 2 with the script call + marker-branching prose. Drop the prose resume-detection sub-section (its logic moves to the script; the AskUserQuestion gate stays in prose).
plugin/scripts/tests/test_precheck_task.pynewRegression tests for every marker and the resume-detection truth table.
plugin/skills/task-work/invariants.yamlmodifyDrop pinned phrases from old Step 2 prose; pin the new shape.
docs/skills/task-work.mdmodifyUpdate Step 2 nodes in the flowchart if needed.
  • AC-1: ${CLAUDE_PLUGIN_ROOT}scripts/precheck_task.py <basename> exits 0 and emits exactly one stdout line whose first whitespace-delimited token is one of: OK, BLOCKED-CLOSED, BLOCKED-IN-PROGRESS, BLOCKED-WORKTREE, BLOCKED-BRANCH, BLOCKED-PR, RESUME-AT-5B, PROMPT-PLANNING.
  • AC-2: Against a task with an open spec-only PR on docs/<basename> (whose file list contains the task spec), the script emits OK — it does not block. The original freetext-search bug is fixed by construction.
  • AC-3: Against a task with an open PR on task/<basename>, the script emits BLOCKED-PR pr=#<N>.
  • AC-4: The script does NOT search for branches or PRs on the legacy feat/<basename> prefix. In-flight feat/ branches are accepted as a no-op; the operator is expected to rename them.
  • AC-5: When all five resume-detection conditions hold (open/ready status on main, worktree exists, task/<basename> branch exists, branch HEAD subject is docs(tasks): verify <basename> implementation-ready, no PR open), the script emits RESUME-AT-5B. Any one condition false yields a different marker.
  • AC-6: plugin/skills/task-work/SKILL.md Step 2 body is ≤25 lines (a shell-out + marker-handling prose + AskUserQuestion branches), and the file still passes check_skill_prose.py and the pipe-tail check.
  • AC-7: A live /sdlc:task-work <some-basename> run end-to-end against a real task succeeds — Step 2 fires the new script, the right marker is emitted, and downstream Steps 2a–7 still work.
  • Cross-repo task PRs. Branch-naming applies to this repo; cross-repo handling is a separate concern.
  • Re-scoping merged/closed PRs. The script filters to --state open.
  • File-list classification of PRs. The earlier draft of this task proposed a classify_pr.py helper that inspected PR file lists; the branch-prefix approach is strictly simpler and uses an existing convention.
  • A --dry-run flag on the precheck. The script is itself read-only; rehearsal is unnecessary.

Original framing (a surgical fix to Step 2’s PR-search) spawned 2026-05-27 from PR #134’s repro (a spec PR’s file list matched freetext-search and blocked Task A pickup). Rewritten 2026-05-28 during an open/ready audit: the bug is real but it’s a symptom of the larger pattern — Step 2’s prose is mostly script-shaped, same as Step 4. Better to extract the whole Step than to patch the one query.

T-ELV7-prototype-skill-refine-skill


← Back to Tasks