一键导入
feature-plan-loop
// Use when modifying the plan loop, debugging plan stages, changing clarification flow, scope isolation, or understanding how spectre-build --plan works end-to-end
// Use when modifying the plan loop, debugging plan stages, changing clarification flow, scope isolation, or understanding how spectre-build --plan works end-to-end
| name | feature-plan-loop |
| description | Use when modifying the plan loop, debugging plan stages, changing clarification flow, scope isolation, or understanding how spectre-build --plan works end-to-end |
| user-invocable | false |
Trigger: plan loop, --plan, plan pipeline, planning loop, --scope-name, plan stages, clarifications, plan resume, scope to manifest, scope isolation, scope slug, run_plan_pipeline, create_plan_pipeline Confidence: high Created: 2026-02-17 Updated: 2026-02-19 Version: 3
The --plan flag on spectre-build runs a multi-stage autonomous planning loop that transforms scope documents into a build-ready manifest. It decomposes the interactive /spectre:plan workflow into 7 independent stages — each reading and writing files — leveraging the existing pipeline executor with zero changes to the core engine.
Key insight: The plan loop does NOT use --tasks (tasks are generated, not provided). It takes --context scope docs as input and produces a .md manifest with YAML frontmatter as output.
| Problem | How Plan Loop Solves It |
|---|---|
| 20-40 min manual planning orchestration before builds | Runs autonomously from scope docs to build manifest |
Manual multi-step /spectre:* command sequencing | 7 stages execute in sequence, file-mediated |
| Complexity misjudgment (over/under-planning) | Assess stage scores complexity, routes LIGHT/STANDARD/COMPREHENSIVE |
| Plans that are over-engineered | Plan review stage catches unnecessary abstractions |
| Scope gaps discovered late | Req validate cross-references scope vs plan/tasks |
| Clarification needs block the entire pipeline | Pause/resume: saves session, user edits file, resumes |
spectre-build --plan --context scope.md design_notes.md --max-iterations 10
Pipeline runs 6 stages autonomously:
research → assess → [create_plan] → create_tasks → plan_review → req_validate
Output: docs/tasks/{branch}/{scope_slug}/build.md manifest, then run spectre-build build.md.
research → assess(LIGHT) → create_tasks → plan_review → req_validate
Assess determines the task is simple enough to skip create_plan entirely.
# Pipeline pauses:
spectre-build --plan --context scope.md
# → req_validate finds gaps
# → writes scope_clarifications.md
# → saves session, exits with code 0
# → prints: "Edit: .../scope_clarifications.md"
# User edits clarifications file, then:
spectre-build resume
# → detects plan=True in session
# → runs update_docs stage only
# → incorporates answers, writes manifest
parse_args()
├─ --plan → run_plan_pipeline() ← checked FIRST, before --validate
├─ --pipeline → run_pipeline()
├─ --validate (no --pipeline) → run_default_pipeline()
└─ no flags → run_build_validate_cycle()
--plan requires --context (errors without it). Does NOT require --tasks.
Normal flow
══════════
research → assess ─── LIGHT ──────────────────→ create_tasks → plan_review → req_validate
├── STANDARD ───────→ create_plan ─→ create_tasks → plan_review → req_validate
└── COMPREHENSIVE ──→ create_plan ─→ create_tasks → plan_review → req_validate
Resume flow (separate pipeline config)
════════════════════════════════════
update_docs → PLAN_READY (end)
| Stage | Completion | Signals | Max Iter | Transitions |
|---|---|---|---|---|
| research | JSON | RESEARCH_COMPLETE | 1 | → assess |
| assess | JSON | LIGHT, STANDARD, COMPREHENSIVE | 1 | LIGHT→create_tasks, STANDARD/COMPREHENSIVE→create_plan |
| create_plan | JSON | PLAN_COMPLETE | 1 | → create_tasks |
| create_tasks | JSON | TASKS_COMPLETE | 1 | → plan_review |
| plan_review | JSON | REVIEW_COMPLETE | 1 | → req_validate |
| req_validate | JSON | PLAN_VALIDATED, CLARIFICATIONS_NEEDED | 1 | end pipeline |
| update_docs | JSON | PLAN_READY | 1 | end pipeline (resume only) |
All stages use JsonCompletion with signal_field="status". End signals: ["PLAN_VALIDATED", "PLAN_READY"].
def run_plan_pipeline(
context_files: list[str],
max_iterations: int,
agent: str = "claude",
output_dir: str | None = None, # Default: docs/tasks/{branch}/{scope_slug}
scope_name: str | None = None, # Scope slug for directory isolation
resume_stage: str | None = None, # Set to "update_docs" for resume
resume_context: dict | None = None, # Preserved context from session
) -> tuple[int, int, str]:
Key behaviors:
docs/tasks/{branch}/{scope_slug}/, specs/, clarifications/ subdirs. Each scope gets an isolated directory to prevent collisions between planning cycles.resume_stage → create_plan_resume_pipeline(), else → create_plan_pipeline()resume_contextspectre-build commandcontext = {
"context_files": "- `scope.md`\n- `notes.md`", # Input scope docs
"output_dir": "/abs/path/docs/tasks/main/my_scope", # Artifact root (scope-isolated)
"task_context_path": ".../task_context.md", # Written by research
"plan_path": ".../specs/plan.md", # Written by create_plan
"tasks_path": ".../specs/tasks.md", # Written by create_tasks
"clarifications_path": "", # Set by req_validate if gaps
"clarification_answers": "", # Injected by hook for update_docs
"manifest_path": "", # Set by req_validate/update_docs
"depth": "standard", # Set by assess artifacts
"tier": "STANDARD", # Set by assess artifacts
}
plan_before_stage() (hooks.py:118):
create_plan: Defaults depth to "standard" if missingupdate_docs: Reads clarifications file, injects content as clarification_answersplan_after_stage() (hooks.py:147):
assess: Ensures depth and tier from artifacts flow into contextreq_validate + CLARIFICATIONS_NEEDED: Stores clarifications_path in contextplan_loops: int = 0 field on BuildStats (stats.py:64)create_plan_event_handler(stats) (stats.py:220) — factory returning callback that increments plan_loops on every StageCompletedEventPLAN LOOPS: N when plan_loops > 0 (stats.py:205-206)Planning adds 5 fields to session JSON:
save_session(
tasks_file="", # Empty for --plan
plan=True, # Planning mode flag
plan_output_dir=output_dir, # Artifact directory (scope-isolated)
plan_context=context, # Full context dict for resume
plan_clarifications_path=clarif_path, # Path to clarifications file
plan_scope_name=scope_name, # Scope slug for directory isolation
plan_auto_build=auto_build, # Chain to build after plan completes
...
)
format_session_summary() shows "Mode: Planning", output dir, and clarifications path.
spectre-build resume
→ load_session()
→ session.get("plan") == True
→ save_session() (timestamp update)
→ run_plan_pipeline(
resume_stage="update_docs",
resume_context=session.get("plan_context"),
output_dir=session.get("plan_output_dir"),
)
→ create_plan_resume_pipeline() (single update_docs stage)
→ executor.run()
→ notification
PLAN_RESEARCH_DENIED_TOOLS — allows WebSearch/WebFetch (for external API docs)PLAN_DENIED_TOOLS — same as build loop restrictionsDefined in loader.py:395-410.
create_plan_pipeline() (loader.py:413) — 7-stage config, start_stage="research", end_signals=["PLAN_VALIDATED", "PLAN_READY"]create_plan_resume_pipeline() (loader.py:523) — single update_docs stage, start_stage="update_docs", end_signals=["PLAN_READY"]Resume uses a separate pipeline config (not a start-stage offset) to avoid modifying the executor.
| File | Purpose | When to Modify |
|---|---|---|
build-loop/src/build_loop/cli.py | --plan flag, run_plan_pipeline(), session save/load/resume | Adding plan CLI options, changing plan routing |
build-loop/src/build_loop/pipeline/loader.py | create_plan_pipeline(), create_plan_resume_pipeline(), denied tools lists | Adding/removing plan stages, changing transitions |
build-loop/src/build_loop/hooks.py | plan_before_stage(), plan_after_stage() | Changing what context flows between plan stages |
build-loop/src/build_loop/stats.py | plan_loops field, create_plan_event_handler() | Adding plan-specific metrics |
build-loop/src/build_loop/prompts/planning/*.md | 7 prompt templates (research, assess, create_plan, create_tasks, plan_review, req_validate, update_docs) | Changing agent instructions per stage |
prompts/planning/{stage}.mdcomplete_statuses in create_plan_pipeline() (loader.py)transitions dict for that stageprompts/planning/StageConfig to create_plan_pipeline() in loader.pyhooks.py if inter-stage context injection neededTrace: req_validate emits CLARIFICATIONS_NEEDED → plan_after_stage() stores path → pipeline ends → run_plan_pipeline() detects signal at cli.py:756 → save_session() → user edits file → resume → plan_before_stage("update_docs") reads file at hooks.py:136
docs/tasks/{branch}/{scope_slug}/. The scope slug is derived from the first context file (stripping scope_ prefix) or set explicitly via --scope-name. This prevents planning cycles from colliding when running multiple plan/build/ship cycles on the same branch. The update_docs.md prompt has a scope mismatch guard that detects when plan/tasks belong to a different scope.--plan without --context exits immediately: Error at cli.py. No interactive fallback.create_plan_resume_pipeline(), not a start-stage param on the main pipeline. The executor always starts at start_stage.end_signals: The pipeline ends because there's no transition for it (empty transitions dict on req_validate). The CLI detects it by checking state.stage_history[-1][1].PLAN_RESEARCH_DENIED_TOOLS vs PLAN_DENIED_TOOLS.context.update(result.artifacts) happens automatically in executor after each stage. Hooks handle edge cases (defaults, file reading).executor.run() creates dict(self.initial_context) — a copy. Hook mutations to context during pipeline execution don't propagate back to the caller's original dict. For values that must survive session save (like clarifications_path), the caller must sync them from state.global_artifacts after executor.run() returns.plan_auto_build persists across resume: The auto-build preference (from --build flag or interactive "Auto-start build?" prompt) is saved to session as plan_auto_build and checked in run_resume() to chain to run_manifest() after plan completes.Use when modifying build loop code, debugging stats/token tracking, adding CLI features, changing iteration prompts, or understanding how spectre-build works end-to-end
Use when modifying the ship loop, debugging ship stages, changing clean/test/rebase behavior, or understanding how spectre-build --ship works end-to-end
Use when user wants to search for existing knowledge, recall a specific learning, or discover what knowledge is available.
Use when planning product scaling, adding GUI/server layers, multi-model support, adversarial reviews, live steering, telemetry, scheduling/triggers, or node-based pipeline editors to spectre-build
Use when working with pipeline stages, completion strategies, build loop orchestration, or the web GUI for spectre-build
Use this skill when you see @name or /name patterns in user input without file identifiers. This means the user is trying to call a subagent or slash command using Spectre Agent Tools. The @ prefix dispatches to a subagent (e.g., '@tdd-agent write tests', '@code-reviewer check this file'). The / prefix executes a slash command (e.g., '/spectre:scope', '/spectre:plan'). Both require Spectre CLI to run specialized agents and predefined prompts.