Skip to content

Pipeline Plan inline

ezigus edited this page Mar 31, 2026 · 4 revisions

Plan written to .claude/pipeline-artifacts/plan.md. Here's the summary:

Root cause: resume_state() in pipeline-state.sh:607-620 only clears pipeline-tasks.md when the issue number differs or the file is malformed. When resuming a failed build for the same issue, stale tasks (with checked-off items from the failed attempt) survive and get re-injected into the build loop.

Fix: Replace the conditional validation block with an unconditional rm -f "$TASKS_FILE". The tasks file is a derivative of plan.md and should not persist across resume boundaries.

Changes needed:

  1. scripts/lib/pipeline-state.sh — 1 line replacing 13 lines of conditional logic
  2. scripts/sw-lib-pipeline-stages-test.sh — Update 2 tests that assert the buggy "keep" behavior

Why this approach: Simplest fix with smallest blast radius. plan.md provides equivalent context, so losing the task checklist on resume is harmless. Eliminates the entire class of stale-task bugs including goal-based pipelines with no issue number. SUE` is empty, the issue-mismatch check at line 615 short-circuits, keeping any tasks file regardless of staleness.

Evidence Gathered

Location Finding
pipeline-state.sh:452-465 initialize_state() correctly clears TASKS_FILE via rm -f
pipeline-state.sh:607-620 resume_state() only clears on issue mismatch or malformed file; keeps matching-issue tasks
pipeline-stages-build.sh:172-183 Build stage injects tasks file contents verbatim into enriched_goal
pipeline-stages-intake.sh:440-464 Tasks file is generated during intake stage from plan checklist
sw-pipeline.sh:2534-2544 Resume path calls resume_state() (not initialize_state()) for failed/interrupted pipelines
Test line 474 Existing test asserts the buggy behavior: "resume_state keeps tasks when issue matches"

Fix Strategy

Always clear pipeline-tasks.md in resume_state(), replacing the conditional validation block with an unconditional rm -f. Rationale:

  • If resuming before intake: intake will regenerate the tasks file from the plan
  • If resuming at/after build: stale tasks (with checked-off items from a failed attempt) should not be re-injected; plan.md still provides full context
  • If resuming after build (test, review, etc.): build won't re-run, so the cleared file is irrelevant

This is simpler and more correct than trying to "reset checkboxes" — the tasks file is a derivative artifact of plan.md and should not persist across resume boundaries.

Alternatives Considered

Approach Complexity Trade-off
A: Unconditional clear in resume_state() (chosen) Minimal — 1 line change + test update Loses task checklist on build resume, but plan.md provides equivalent context. Eliminates entire class of stale-task bugs.
B: Reset checkboxes to unchecked on resume Medium — sed/awk to convert [x] to [ ] Preserves task tracking but adds complexity. Still risks other forms of staleness (tasks added/removed between attempts).
C: Regenerate tasks from plan.md on resume Higher — extract + rebuild logic duplicated from intake Most "correct" but duplicates intake logic, adding maintenance burden.

Approach A wins on simplicity and blast radius.

Files to Modify

  1. scripts/lib/pipeline-state.sh — Replace conditional task validation in resume_state() with unconditional clear
  2. scripts/sw-lib-pipeline-stages-test.sh — Update tests that assert tasks are kept on matching issue; assert unconditional clear on resume

Implementation Steps

  1. In pipeline-state.sh, replace lines 607-620 (the conditional validation block in resume_state()) with an unconditional clear:

    # Clear pipeline-tasks.md on resume — stale tasks from previous attempts must not
    # leak into the build loop. Intake will regenerate if the pipeline resumes before build.
    [[ -n "${TASKS_FILE:-}" ]] && rm -f "$TASKS_FILE"
  2. In sw-lib-pipeline-stages-test.sh, update the test at ~line 457 ("resume_state keeps tasks when issue matches") to assert that tasks are removed on resume, even when the issue matches.

  3. Update the "Issue: line has no leading dash" test (~line 637) to assert tasks are cleared on resume.

  4. Run the test suite to confirm no regressions.

Task Checklist

  • Task 1: Replace conditional validation block in resume_state() with unconditional rm -f "$TASKS_FILE" (pipeline-state.sh:607-620)
  • Task 2: Update test "resume_state keeps tasks when issue matches" to assert deletion instead (sw-lib-pipeline-stages-test.sh:~457-478)
  • Task 3: Update test for "Issue: line has no leading dash" format variant to assert deletion (sw-lib-pipeline-stages-test.sh:~637-655)
  • Task 4: Run ./scripts/sw-lib-pipeline-stages-test.sh to verify all tests pass
  • Task 5: Run npm test for full regression check

Testing Approach

  1. Unit tests (sw-lib-pipeline-stages-test.sh):

    • Existing test "resume_state clears stale tasks when issue differs" — should still pass (tasks cleared)
    • Updated test "resume_state keeps tasks when issue matches" → now asserts tasks are cleared
    • Existing test "resume_state removes malformed pipeline-tasks.md" — should still pass
    • Updated "Issue: no leading dash" test → now asserts tasks are cleared
  2. Integration: sw-pipeline-test.sh for end-to-end pipeline resume scenarios

  3. Manual verification: Create a pipeline, let build fail, resume, confirm tasks file is absent when build stage starts

Definition of Done

  • resume_state() unconditionally removes pipeline-tasks.md on every resume
  • No test expects pipeline-tasks.md to survive a resume_state() call
  • ./scripts/sw-lib-pipeline-stages-test.sh passes all assertions
  • npm test passes with no regressions
  • Goal-based pipelines (no issue number) also clear tasks on resume

Risk Analysis

Risk Impact Mitigation
Build stage loses task checklist context Low — plan.md provides equivalent task breakdown Plan is always available and is the source of truth for tasks
Tests that assert "keep" behavior fail Expected — these tests encode the buggy behavior Update tests to assert the corrected behavior
Intake stage not re-run on resume means no task regeneration None — tasks are a convenience, not a requirement for build Build stage works without tasks file; plan.md suffices

Clone this wiki locally