Prompt file imported from chrisarm/task-mgr-framework (
.claude/commands/prd-tasks.md). Fill in{{VERIFICATION_SKILLS}},{{PROJECT_NAME}},{{EXTERNAL_GIT_REPO_OR_OMIT}},{{FEATURE_TITLE}},{{FEATURE_NAME}},{{PROBLEM_STATEMENT}},{{REFERENCE_CODE}},{{DATA_FLOW_CONTRACTS}},{{KEY_LEARNINGS}},{{CLAUDE_MD_EXCERPTS}},{{PROHIBITED_OUTCOMES}},{{GLOBAL_ACCEPTANCE_CRITERIA}},{{CROSS_PRD_REQUIRES}},{{FEATURE_SPECIFIC_CHECKS}},{{TASK_PREFIX}},{{X}}before use. Copyright stays with the author.
/prd-tasks - Convert PRD to Claude Loop Task List
Convert a markdown PRD into JSON task list and prompt file for task-mgr loop execution.
Usage
/prd-tasks tasks/prd-{feature}.md
/prd-tasks # Will prompt for PRD path
Instructions
Canonical reference:
~/.claude/docs/task-mgr-best-practices.md— planning flow, CLI, mid-loop JSON sync, spawn-fixup targeting, model routing (task-mgr models route), and gotchas. This skill adds PRD→JSON conversion steps on top of that base.CLI (embed in the generated prompt):
--from-jsonpins an already-registered PRD (never registers). Spawn:task-mgr add --stdin --from-json tasks/<prd>.json --depended-on-by <milestone>. Patch (includinghumanReviewOutcome):task-mgr update --stdin --from-json tasks/<prd>.json. Bulk sync:task-mgr loop init <prd>.json --append --update-existing— never bareinit --from-json. Export default is the active PRD; registered dest needs--force(lossy dump). Never hand-edit JSON.
You are converting a human-readable PRD into machine-executable task artifacts for the Claude Loop autonomous agent system.
CRITICAL — Four principles must be embedded in every task and the prompt file:
- Quality dimensions explicit — every implementation task carries
qualityDimensions(one flat list) from PRD section 2.5. The agent must know what "good" looks like, not just what to build.- Edge cases = test cases — every PRD Known Edge Case becomes an
edgeCasesentry on a TEST-INIT task. 1:1 mapping, no exceptions. Unnamed edge cases get discovered in production.- Full floor every iteration — every iteration's quality gate is: run
bash bin/gate(or the project's declared floor command) - the full suite - before the completion commit and paste itsGATE_OKline as aGate:trailer; a scoped run is a development convenience, never the pre-commit check. Milestones additionally fix every pre-existing failure so the trunk never degrades.- Project verification skills are the proof — if the code repo ships a
.claude/skills/verif*or.grok/skills/verif*skill, the loop agent must Read and follow it for covered user-facing changes. Language-level gates (fmt, type-check, lint, scoped tests) are necessary but not sufficient. Do not invent a second harness.
Step 1: Read and Parse the PRD
Load the specified PRD file and extract:
- Feature title and type (feature/bug/enhancement/refactor)
- User stories with acceptance criteria
- Functional requirements
- Technical considerations (affected files)
- Non-goals (scope boundaries)
- Low-value / high-effort areas (PRD §5.5) — treat as out of scope by default
Step 1.5: Resolve Current Model IDs
Do not hardcode model IDs — they change with each Claude release and must be read fresh each time you generate a task list.
Current model list
Current model IDs (bumped in src/loop_engine/model.rs):
- Fable (frontier) →
FABLE_MODEL=claude-fable-5 - Opus (standard) →
OPUS_MODEL=claude-opus-5 - Sonnet (cost-efficient) →
SONNET_MODEL=claude-sonnet-5 - Haiku (cheapest) →
HAIKU_MODEL=claude-haiku-4-5-20251001 - Grok (standard) →
GROK_MODEL=grok-4.5
Difficulty → --effort mapping:
- Claude / Grok (
EFFORT_FOR_DIFFICULTY):low→medium,medium→high,high→high - Codex (
CODEX_EFFORT_FOR_DIFFICULTY, capped athighby policy):low→low,medium→medium,high→high
Capability tiers + anchor window (default models config):
Provider-neutral tiers (ordered Cheapest < CostEfficient < Standard < Frontier). The anchor (default standard) + difficulty offset produces the starting tier:
- low difficulty → anchor − 1 (clamped at ladder bottom)
- medium → anchor
- high → anchor + 1 (clamped at ladder top)
See
anchored_tier+difficulty_offset(single normalizer). Sparse ladders: only defined rungs participate in clamp / escalate; gaps are skipped.
Default tier matrix (from the _DEFAULT_TIER_MODELS tables; empty = route with no model flag):
| Tier | Claude | Grok | Codex |
|---|---|---|---|
| frontier | claude-fable-5 | (n/a) | (n/a) |
| standard | claude-opus-5 | grok-4.5 | (no -m flag) |
| cost-efficient | claude-sonnet-5 | (n/a) | (n/a) |
| cheapest | claude-haiku-4-5-20251001 | (n/a) | (n/a) |
Codex routes are always explicit (byIdPrefix or taskClasses in routing); Codex is never inferred from a model string.
Model selection is config-driven at runtime (see src/loop_engine/model.rs:resolve_execution_plan). Do not put a model field on any task entry in the generated JSON (FEAT, ANALYSIS, CODE-REVIEW-, MILESTONE-, VERIFY, CONTRACT, REFACTOR-, spawned FIX-/CODE-FIX-* etc.), and do not set a top-level PRD "model" field — it is ignored under the models config and prints a warning on every import and loop start. Do not document routing in task JSON — operators configure prefixes with task-mgr models route (see Model routing in ~/.claude/docs/task-mgr-best-practices.md).
- Task
estimatedEffort(akadifficulty; canonical keyestimatedEffort, aliasdifficultyaccepted) drives the anchor window:models.anchor(defaultstandard) + difficulty offset picks the capability tier (low→ anchor−1,medium→ anchor,high→ anchor+1, clamped to the ladder), then the provider's tier ladder maps tier → model. With the default config,highresolves to the frontier model andmediumto the standard model. - Operator
routingconfig (task-mgr models route <prefix>,routing.taskClasses) provides forced routes at rungs 2–3, ahead of the anchor window. Review-class IDs (CODE-REVIEW-*,MILESTONE-FINAL,REVIEW-*after prefix strip) carry a built-in, non-redefinable force to the frontier tier. - Explicit per-task
modelwins rung 1 and bypasses the above routing for that task — the whole point of config-driven selection is to stop baking model strings into task lists so operators can control routing viatask-mgr models set-*without regenerating JSONs.
Guidance for strong-model tasks: Set "estimatedEffort": "high" on CONTRACT-xxx (when complex), VERIFY-xxx, MILESTONE-*, REFACTOR-REVIEW-FINAL, and any spawned repair tasks that should start with a capable baseline. Review-class IDs are frontier-forced regardless of difficulty.
The old "stamp model snapshots into the task JSON" pattern is retired; the generator no longer reads .task-mgr/config.json for per-task model values.
timeoutSecs assignment (set on tasks that run the full test suite):
| Task type | timeoutSecs |
Rationale |
|---|---|---|
MILESTONE-xxx |
1800 | Deep cross-PRD review + task updates can be extensive |
VERIFY-xxx |
1800 | Same — runs complete test suite |
| All others | (omit) | Uses loop default (12 min) |
The generated task list contains no model keys at all — not on tasks, not
at the PRD top level. Use estimatedEffort: "high" and/or
modifiesBehavior: true to express the desire for a strong tier; the
models + routing config (task-mgr models show) selects the actual
runner/model at runtime via the anchor window and any forced routes.
Do not set model; use estimatedEffort to preserve runtime provider routing.
Explicit per-task model fields (rung 1, highest precedence) bypass all of
that policy; a top-level PRD model is ignored and warns.
Step 1.6: Extract Quality Dimensions and Edge Cases
From the PRD's Section 2.5 (Quality Dimensions), extract:
- All correctness / performance / style requirements → merge into each implementation task's
qualityDimensionsarray (flat — no sub-buckets). One clear line per requirement. - Known edge cases → become
edgeCasesentries on TEST-INIT tasks
Every edge case in the PRD table MUST appear as an edgeCases entry on at least one TEST-INIT task. This ensures the implementing agent is forced to handle it rather than hoping to discover it independently.
Data Flow Contracts
From the PRD's Section 6 (Data Flow Contracts), extract the concrete access patterns and embed them in:
- The prompt file — as a "Data Flow Contracts" section with copy-pasteable code showing correct key paths (see prompt template below)
- Implementation task
notes— remind the agent which key types to use at each level - TEST-INIT task
notes— require tests to use production-shaped data structures (real structs/schemas), not hand-built maps that might accidentally match the wrong key format
Why this is critical: The #1 source of silent bugs in multi-layer systems is data access path errors — using atom keys on string-keyed maps or vice versa. Tests that construct synthetic data matching the wrong key format pass even though the code is wrong. The PRD's Data Flow Contracts section provides verified access patterns; this step ensures those patterns reach the implementing agent.
If the PRD lacks a Data Flow Contracts section but the feature accesses data across module boundaries, generate one now by reading existing code to verify the actual key types at each level.
Step 2: Explore the Codebase
For each user story, use Glob/Grep to populate two fields:
touchesFiles: which files will be modified. Drives CODE-REVIEW scope, test-scoping, and synergy tie-breaking at selection time.dependsOn: implementation order. Schema/types first → backend logic → API/endpoints → UI; base functionality before extensions.
Do NOT populate synergyWith / batchWith / conflictsWith — task-mgr next derives synergy from touchesFiles overlap at runtime, and anything genuinely conflicting should be expressed as dependsOn.
Step 2.5: Recall Relevant Learnings
Even though the PRD may have already queried task-mgr recall during its drafting (Step 4.7 of /prd), run recall again here when converting to tasks. At conversion time you know the exact files and functions being touched — that precision lets you find learnings the PRD-level recall missed.
Run both tag-based AND query-based recall — they hit different indexes and return different results:
# Tag-based: exact-match on curated tags (use PRD tags + discovered domain terms)
task-mgr recall --tags <domain1> --limit 10
task-mgr recall --tags <domain2> --limit 10
# Query-based: full-text / semantic search over title + content
task-mgr recall --query "<specific function names, file paths, or concepts>" --limit 10
task-mgr recall --query "<failure symptoms the PRD mentions>" --limit 10
# Combined: tag AND query for narrow results
task-mgr recall --tags <domain> --query "<concept>" --limit 10
Why run both: tag searches miss learnings that weren't tagged with your exact domain term (taggers are inconsistent). Query searches catch those via content matching. Conversely, query searches can miss high-signal learnings whose content phrases the topic differently. Run at least one of each per task being generated.
Effective query-based searches:
- Function names discovered in Step 2 exploration (e.g.,
evaluate_transition,compute_auto_invoke_requests) - Type names and error messages from the existing code
- Concept phrases: "cache invalidation", "stale state", "init ordering", "wrong key type"
How to use recalled learnings:
- Embed in task
notes— addLearning [ID]: <summary>lines so the loop agent reads them before coding - Adjust acceptance criteria — if a learning reveals a known-bad pattern, add it as a negative criterion or known-bad discriminator
- Add to prompt file — include a "Key learnings from task-mgr" section in the prompt (see Step 11's prompt template)
Skip this step only if task-mgr has no learnings (fresh project) or the feature is purely greenfield with no overlap.
Step 2.6: Discover Project Verification Skills
Project-level verification skills (directories matching verif* under .claude/skills/ or .grok/skills/) are the maintained harness for proving a change on the real user surface. The loop agent will not reliably find them unless the generated prompt names them.
Search roots — the code repo the loop agent will work in (externalGitRepo if set, else this repo):
# From the code-repo root:
ls -d .claude/skills/verif*/SKILL.md .grok/skills/verif*/SKILL.md 2>/dev/null
Example: ../restaurant_agent_ex/.claude/skills/verify-restaurant-agent/SKILL.md (when that repo is externalGitRepo or is the cwd).
For each hit:
- Read the YAML frontmatter (
name,description) — keep the description as one line; do not paraphrase it into a second procedure. - If
features/README.mdexists next toSKILL.md, read it and map this PRD's stories onto feature ids (e.g.cart-editing↔FEAT-002). Unmapped features stay out of this prompt. - Do not paste the SKILL.md body into the prompt (context economy). The loop agent Reads the skill at verification time.
How to use:
- Populate
{{VERIFICATION_SKILLS}}in the prompt (Step 6). Omit the whole section only when the glob is empty. - For each implementation task that maps to a feature id, add an acceptance criterion (
Drive <skill-path> feature <id> per SKILL.md; evidence captured; compile/unit tests alone are not proof) and anotesline pointing at the skill + feature id. - REVIEW-001 / milestone criteria must include driving every mapped feature.
Skip this step only when the glob is empty.
Step 3: Validate Story Sizing
For each user story, check complexity indicators:
Warn if too large (suggest splitting):
- More than 4 acceptance criteria that modify code
- Touches more than 4 files
- Description exceeds 150 words
- Spans multiple architectural layers
Flag for review (recommended split):
- More than 7 acceptance criteria — agents start losing coherence at this size. Split unless there's a strong reason (e.g., atomic migration). If the
md-to-json-prd-reviewerflags it, split unless you can justify keeping together. - Touches more than 7 files — high blast radius for one iteration. Flag for reviewer decision.
MUST split if (hard rule for automation reliability):
- More than 12 acceptance criteria — autonomous agents lose coherence across this many requirements
- Touches more than 10 files — too many files for a single iteration to handle reliably
- Split into subtasks (e.g., FEAT-001a, FEAT-001b) with clear boundaries between them
Effort sizing (set estimatedEffort on each task):
| Effort | Indicators |
|---|---|
low |
1 file, 1-3 acceptance criteria, single function/field |
medium |
2-3 files, new function with tests, integration with existing system |
high |
3+ files, new module/component, cross-cutting — consider splitting |
Step 4: Generate Story IDs
Use context-appropriate prefixes. Set the taskType field on each task to let the agent apply different strategies per type:
| Prefix | taskType |
Notes |
|---|---|---|
ANALYSIS-xxx |
"analysis" |
Consumer and semantic analysis (priority 0, blocks implementation) |
CONTRACT-xxx |
"contract" |
Foundational abstraction/interface with multi-task downstream impact. Design-only task. |
FEAT-xxx |
"implementation" |
New features |
FIX-xxx |
"implementation" |
Bug fixes |
ENV-xxx |
"implementation" |
Environment/configuration |
TEST-INIT-xxx |
"test" |
Initial TDD tests (before implementation) |
TEST-xxx |
"test" |
Comprehensive test implementation |
INT-xxx |
"verification" |
Integration verification |
WIRE-xxx |
"implementation" |
Integration wiring (spawned by CODE-REVIEW) |
WIRE-FIX-xxx |
"implementation" |
Fix wiring issues (exports, registration, call sites) |
CODE-REVIEW-xxx |
"review" |
Code review tasks |
REFACTOR-xxx |
"implementation" |
Refactoring tasks |
REFACTOR-REVIEW-xxx |
"review" |
Refactoring review tasks |
VERIFY-xxx |
"verification" |
Final validation + documentation |
MILESTONE-xxx |
"milestone" |
Gate checkpoints |
POLISH-xxx |
"implementation" |
Formatting/cleanup |
Special taskType values:
"research"— For spike/evaluation tasks (e.g., "evaluate 3 libraries, write ADR"). SetrequiresHuman: trueso the loop agent skips it and flags it for human attention. Setdifficulty: "high"so the loop controller selects a larger model if it does attempt the task."contract"— Design-only task that defines a stable foundational abstraction, interface, data shape or error model used by 2+ downstream FEAT/FIX tasks. The agent produces precise signatures + edge cases + invariants + known-bad discriminators + rationale, records the full contract in the progress log, and emits no production code. Later tasks list it independsOn. Use only when the decision has clear multi-story ramifications (see/spikeand/prd-tasksguidance on when to emit one)."milestone"— Agent behavior: review completed work, update remaining tasks, check sibling PRDs."review"— Agent behavior: read and analyze code, spawn fix tasks, don't implement."verification"— Agent behavior: run full test suite, verify integration, update docs.
Step 4.5: Identify Behavior-Modifying Tasks
For Bug Fixes, Enhancements, and Refactors, check if any task modifies existing behavior:
A task modifies behavior if:
- It changes the return value or side effects of an existing function
- It changes when/how data is cached, stored, or retrieved
- It changes control flow or routing logic
- It changes error handling or exception propagation
For behavior-modifying tasks:
- Check if PRD has Consumer Impact Table: If the PRD already contains analysis from
/analyze, use that data - If no analysis exists: Run
/analyze "{behavior being changed}"now - Set
modifiesBehavior: truein the task JSON - Create an
ANALYSIS-xxxtask with priority 0 that blocks the implementation task - Populate
consumerAnalysisfrom the/analyzeoutput
AUTO-INVOKE: If the PRD lacks a Consumer Impact Table for a behavior-modifying story, run:
/analyze "{function or behavior from the story}"
ANALYSIS Task Requirements:
- Priority: 0 (runs first)
- dependsOn: [] (no dependencies)
- Acceptance criteria: "Consumer Impact Table generated, all consumers identified, impact assessed"
- Description: Reference
/analyzeskill output
If /analyze recommends SPLIT:
- Do NOT create the original task
- Create separate tasks for each semantic context (e.g., FIX-001a, FIX-001b)
- Each split task should have its own
consumerAnalysisscoped to its context
Step 4.7: Enrich Cross-Boundary Tasks with Data Contract Snippets
For tasks where touchesFiles (including dependencies' touchesFiles) spans different top-level directories (e.g., src/commands/ and src/loop_engine/, or src/db/ and src/models/):
- Identify the boundary: Which module produces data and which consumes it?
- Read the actual struct definitions at the boundary (use Grep/Read — never guess from variable names)
- Embed a concrete data shape example in the task's
notesfield showing:- The source struct/type (with relevant fields)
- The target struct/type (with relevant fields)
- A copy-pasteable example of the correct access pattern
- Source from the codebase — the example must come from reading real struct definitions, not invented
Example notes enrichment:
Data contract: PrdUserStory (src/commands/init/parse.rs) → Task (src/models/task.rs)
Source fields: id, title, description, priority, passes, acceptance_criteria
Access: task.acceptance_criteria = serde_json::to_string(&story.acceptanceCriteria)?
When to skip: If all touchesFiles are in the same directory, or the task only adds new code with no cross-module dependencies.
Step 4.8: Auto-Detect Cross-Boundary Integration Gaps
After building the dependency graph (Step 4) and enriching cross-boundary tasks (Step 4.7), scan for integration paths that need INT-xxx coverage:
- For each dependency edge (
dependsOnrelationship), check if the two tasks'touchesFilesare in different top-level directories (e.g.,src/commands/vssrc/loop_engine/, orsrc/db/vssrc/models/) - If cross-boundary paths exist and no INT-xxx task already traces that specific path, generate one:
- Name the specific data/control path being traced
- List the handoff points at each module boundary
- Set
taskType: "verification"and priority 55-65
- Cap: 1 INT-xxx per distinct cross-boundary data/control path, not per task pair. Multiple tasks touching the same cross-boundary path share a single INT-xxx.
When to skip: If all tasks touch files in the same top-level directory, or the PRD is small enough (2-4 tasks) that CODE-REVIEW-1 will catch any wiring issues.
Step 5: Create JSON Task File
Generate tasks/{feature}.json following this schema.
Required: prdFile — set top-level "prdFile": "prd-{feature}.md" (basename of the source PRD markdown you were given). Auto-review, worktree copy of the PRD, and archive discovery all resolve the markdown via this field first. Keep the original tasks/prd-{feature}.md on disk.
Required: taskPrefix — Do NOT generate this yourself. Leave taskPrefix absent from the JSON. The task-mgr init command will auto-generate a deterministic prefix from md5(branchName + ":" + filename)[..8] and write it back to the JSON file. This ensures the prefix is stable across re-imports and matches what the loop engine uses. If you set a taskPrefix manually, it may conflict with the auto-generated one, causing tasks to be imported under the wrong namespace and breaking dependency tracking.
Cross-PRD dependencies: requires — If this PRD depends on another PRD being completed first (e.g., proto changes must land before Home can use them), add a top-level requires array:
"requires": [
{
"prd": "01-proto-redesign.json",
"task": "MILESTONE-FINAL",
"reason": "SigningKey message must exist in enrollment.proto"
}
]
The agent checks these before starting any task. If the required task in the other PRD hasn't passed, the agent outputs <promise>BLOCKED</promise> with the reason.
{
"version": "1.0",
"project": "{{PROJECT_NAME}}",
"branchName": "feat/{feature-name}",
"prdFile": "prd-{feature-name}.md",
"externalGitRepo": "{{EXTERNAL_GIT_REPO_OR_OMIT}}",
"mergeStrategy": "Merge to main after MILESTONE-FINAL passes. Squash commits optional.",
"description": "{Feature description from PRD}",
"requires": [],
"priorityPhilosophy": {
"description": "Hierarchy of what matters most when implementing tasks",
"hierarchy": [
"1. PLAN — Anticipate edge cases before coding",
"2. PHASE 2 FOUNDATION — ~1 day now to save ~2+ weeks later (1:10+ ratio); we are pre-launch, foundations compound",
"3. FUNCTIONING CODE — Pragmatic, reliable, wired in per plan",
"4. CORRECTNESS — Compiles, type-checks, scoped tests pass deterministically",
"5. CODE QUALITY — Clean code, qualityDimensions satisfied, no warnings",
"6. POLISH — Docs, formatting, minor improvements"
],
"principles": [
"Quality dimensions explicit — qualityDimensions on every task tells you what 'good' looks like",
"Phase 2 foundation — prefer solutions that lay strong post-launch foundations (1:10+ savings ratio)",
"Edge cases = test cases — every known edge case must have a corresponding test",
"Full floor every iteration — every iteration's quality gate is: run `bash bin/gate` (or the project's declared floor command) - the full suite - before the completion commit and paste its `GATE_OK` line as a `Gate:` trailer; a scoped run is a development convenience, never the pre-commit check; milestones must leave the trunk green including pre-existing failures",
"Ship working code with tests to prove it; handle Option/Result explicitly; avoid unwrap() in production"
]
},
"prohibitedOutcomes": [
"Tests that only assert 'no crash' or check type without verifying content",
"Tests that mirror implementation internals (break when refactoring)",
"Abstractions with only one concrete use",
"Error messages that don't identify what went wrong",
"Catch-all error handlers that swallow context"
],
"globalAcceptanceCriteria": {
"description": "These criteria apply to ALL implementation tasks",
"criteria": [
"Rust: No warnings in `cargo check` output",
"Rust: No warnings in `cargo clippy` output",
"Rust: All tests pass with `cargo test`",
"Rust: `cargo fmt --check` passes",
"Python: `ruff check` passes",
"Python: `mypy --strict` passes",
"No breaking changes to existing APIs unless explicitly required"
]
},
"reviewGuidelines": {
"priorityGuidelines": {
"critical": "1-10: Blocks further work, fix immediately",
"high": "11-20: Fix before phase completion",
"medium": "21-50: Fix in current phase if time permits",
"low": "51-99: Defer to hardening phase"
}
},
"userStories": [
{
"id": "FEAT-001",
"title": "Story title from PRD",
"taskType": "implementation",
"description": "What this story accomplishes",
"acceptanceCriteria": [
"Specific, testable criterion 1",
"Specific, testable criterion 2",
"CONTRACT: field names match EXACTLY the struct fields in {source module} (grep to verify)",
"CONTRACT: serde_json::from_value::<TargetStruct>(output) succeeds with production data",
"Drive <skill-path> feature <id> per SKILL.md; evidence captured; compile/unit tests alone are not proof (omit this criterion when no verif* skill maps to this task)"
],
"priority": 1,
"estimatedEffort": "low|medium|high",
"passes": false,
"requiresHuman": false,
"environmentRequirements": ["docker", "protoc", "uv"],
"preflightChecks": ["docker --version", "protoc --version"],
"completionCheck": "cargo test -p deskmait-proto",
"notes": "Implementation hints, gotchas. If a project verif* skill covers this story: follow <skill-path> feature <id>; do not invent a second harness.",
"timeoutSecs": 1800,
"touchesFiles": ["path/to/file.rs"],
"dependsOn": [],
"modifiesBehavior": false,
"qualityDimensions": ["What 'good' looks like for this task — from PRD 2.5: correctness invariants, perf/efficiency requirements, idiomatic patterns vs anti-patterns. One flat list, no sub-buckets."],
"consumerAnalysis": {
"consumers": [
{
"file": "path/to/consumer.rs",
"line": 123,
"usage": "Routes on result.success == false",
"impact": "BREAKS|OK|NEEDS_REVIEW",
"mitigation": "Split into separate code paths"
}
],
"semanticDistinctions": [
{
"context": "LLM-invoked (user retry)",
"currentBehavior": "Skip caching failures",
"requiredBehavior": "Keep: skip caching failures"
},
{
"context": "Auto-invoke (workflow routing)",
"currentBehavior": "Cache all results",
"requiredBehavior": "Keep: cache all results for routing"
}
]
},
"edgeCases": ["(TEST-INIT only) Specific edge cases to test"],
"invariants": ["(TEST-INIT only) Properties that must always hold"],
"failureModes": [{ "cause": "...", "expectedBehavior": "..." }]
}
]
}
Step 6: Generate Prompt File
Create tasks/{feature}-prompt.md using the template below, replacing placeholders:
-
{{PROJECT_NAME}}- Determine from (in order of priority):tasks/project-config.jsonfield"project"package.jsonfield"name"Cargo.tomlfieldnamein[package]- Current directory name
-
{{EXTERNAL_GIT_REPO_OR_OMIT}}- REQUIRED if code lives in a different git repo than task-mgr. Set to relative path (e.g."../restaurant_agent_ex"). Without this, the loop cannot detect task completion from commits in the external repo and tasks get stuck asin_progressforever. Omit the field entirely if the code and task-mgr are in the same repo. -
{{FEATURE_TITLE}}- Feature name from PRD -
{{FEATURE_NAME}}- Kebab-case filename (e.g.,date-context) -
{{PROBLEM_STATEMENT}}- Problem description from PRD -
{{REFERENCE_CODE}}- Optional: code patterns identified during exploration -
{{DATA_FLOW_CONTRACTS}}- Optional but strongly recommended: Copy-pasteable access patterns from PRD Section 6 "Data Flow Contracts". If the feature accesses data across module boundaries, this section prevents the #1 class of silent bugs (wrong key types). Read actual code to verify key types at each level — never guess from variable names. -
{{KEY_LEARNINGS}}- REQUIRED for context economy: Distilled excerpts fromtask-mgr recall(Step 2.5). Embed the 5-10 most relevant learnings (IDs + one-line summaries) directly in the prompt so the loop agent does not need to calltask-mgr recallon every iteration or Readtasks/long-term-learnings.md/tasks/learnings.mdat all. Format:- **[ID]** <one-line takeaway>. Omit the section entirely only when recall returned zero relevant hits. -
{{CLAUDE_MD_EXCERPTS}}- REQUIRED if the PRD touches any area documented in CLAUDE.md: Grep CLAUDE.md for the touched subsystems (e.g. "ADP", "workflow", "KB", "sanitization") and paste the 3-10 bullet points that matter for this PRD — nothing more. This way the loop agent never has to Read CLAUDE.md (which can be hundreds of lines) during iterations. Omit the section if the PRD is greenfield and no existing gotchas apply. -
{{VERIFICATION_SKILLS}}- REQUIRED if the code repo (orexternalGitRepo) ships a project-level verification skill. From Step 2.6: glob.claude/skills/verif*/SKILL.mdand.grok/skills/verif*/SKILL.md. Paths are relative to the code repo the loop agent will work in. Omit the whole section only when the glob is empty. Do not paste the SKILL.md body into the prompt. Render each hit as:- **`verify-restaurant-agent`** — `.claude/skills/verify-restaurant-agent/SKILL.md` Prove restaurant_agent_ex ordering behavior after a code change: scoped tests + the feature ratchet, reload Phoenix, drive the MCP twin of the phone call, capture evidence. Feature map: `.claude/skills/verify-restaurant-agent/features/README.md` **This PRD maps to:** `build-a-cart` (FEAT-001), `cart-editing` (FEAT-002)Use the frontmatter
descriptionas the one-line blurb (do not paraphrase into a second procedure). If there is no feature map, write**This PRD maps to:** all user-facing implementation tasks in this list. -
{{PROHIBITED_OUTCOMES}}- REQUIRED, sourced from the JSON you're generating: Render theprohibitedOutcomesarray from the PRD JSON as a bulleted list (one-line per entry). The loop agent is told not to Read the JSON, so these must live in the prompt. -
{{GLOBAL_ACCEPTANCE_CRITERIA}}- REQUIRED, sourced from the JSON: Render theglobalAcceptanceCriteria.criteriaarray from the PRD JSON as a bulleted list. Same reason — the agent can't see the JSON fields directly, so anything that applies to every task must be embedded here. -
{{CROSS_PRD_REQUIRES}}- REQUIRED only when the JSONrequires[]array is non-empty: Render each entry as a bulleted line:- **<other-prd>.json :: <task-id>** — <reason>. Omit the whole conditional section whenrequires[]is empty. The loop agent reads this block every iteration to decide whether to block, so it must be present; do NOT expect the agent tojq '.requires'during iterations. -
{{FEATURE_SPECIFIC_CHECKS}}- Optional: additional quality checks
# Claude Code Agent Instructions
You are an autonomous coding agent implementing **{{FEATURE_TITLE}}** for **{{PROJECT_NAME}}**.
## Problem Statement
{{PROBLEM_STATEMENT}}
---
## Non-Negotiable Process (Read Every Iteration)
Before writing code:
1. **Internalize quality targets** — Read `qualityDimensions`; that's what "done well" means for THIS task.
2. **Plan edge-case handling** — For each `edgeCases` / `invariants` / `failureModes` entry on the task, decide how it'll be handled before coding.
3. **Pick an approach** — State assumptions in your head. Only for `estimatedEffort: "high"` or `modifiesBehavior: true` tasks, name the one alternative you rejected and why.
After writing code, the scoped quality gate is your critic — run it (Quality Checks § Per-iteration). If a **Project Verification Skills** section applies to this task, follow that skill after the language gate. Don't add a separate self-critique step; the linters, type-checker, targeted tests, and (when present) the project verification skill catch more than a re-read does.
---
## Priority Philosophy
In order: **PLAN** (anticipate edge cases) → **PHASE 2 FOUNDATION** (~1 day now to save ~2+ weeks later — take it, we're pre-launch) → **FUNCTIONING CODE** (pragmatic, reliable) → **CORRECTNESS** (compiles, type-checks, scoped tests pass deterministically) → **CODE QUALITY** (clean, no warnings) → **POLISH** (docs, formatting).
Non-negotiables: tests drive implementation; satisfy every `qualityDimensions` entry; handle `Option`/`Result` explicitly (no `unwrap()` in production). For `estimatedEffort: "high"` or `modifiesBehavior: true` tasks, note the one alternative you rejected and why. For everything else, pick and go.
**Prohibited outcomes:**
{{PROHIBITED_OUTCOMES}}
---
## Global Acceptance Criteria
These apply to **every** implementation task in this PRD — the task-level `acceptanceCriteria` embedded in `## Current Task` are layered on top. If any of these fails, the task is not done.
{{GLOBAL_ACCEPTANCE_CRITERIA}}
---
{{#if CROSS_PRD_REQUIRES}}
## Cross-PRD Dependencies (check before every task)
This PRD blocks on work in other PRD files. Before working `## Current Task`, verify each entry below shows `passes: true` in its referenced PRD JSON (use `jq '.userStories[] | select(.id=="<id>") | .passes' tasks/<other-prd>.json`). If any is still `false`, output `<promise>BLOCKED</promise>` with the reason and stop.
{{CROSS_PRD_REQUIRES}}
---
{{/if}}
## Task Files + CLI (IMPORTANT — context economy)
**Never read or edit `tasks/*.json` directly.** PRDs are thousands of lines; loading one wastes a huge amount of context and editing corrupts loop-engine state. Everything the agent needs about this iteration's task is embedded in `## Current Task`; everything PRD-wide that matters for implementation (Priority Philosophy, Prohibited Outcomes, Global Acceptance Criteria, Cross-PRD Requires, Key Learnings, CLAUDE.md Excerpts, Data Flow Contracts, Project Verification Skills, Key Context) is already embedded in **this prompt file** — that is the authoritative copy. If something here looks inconsistent with the JSON, trust this file and surface the discrepancy.
### Getting your PRD's task prefix
The `taskPrefix` is auto-generated by `task-mgr init` and written into the JSON. Fetch it once at the start of an iteration (don't hardcode it):
```bash
PREFIX=$(jq -r '.taskPrefix' tasks/{{FEATURE_NAME}}.json)
```
Use `$PREFIX` in every CLI call below so you stay scoped to this PRD. If a later note says `{{TASK_PREFIX}}`, substitute `$PREFIX`.
### Commands you'll actually run
| Need | Command |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Inspect this iteration's task | `task-mgr show <TASK-ID>` using the task ID from `## Current Task` |
| List remaining tasks (debug only) | `task-mgr list --prefix $PREFIX --status todo` |
| Recall learnings relevant to a task | `task-mgr recall --for-task $PREFIX-TASK-ID` (also: `--query <text>`, `--tag <tag>`) |
| Add a follow-up task (review spawns) | `echo '{...}' \| task-mgr add --stdin --from-json tasks/{{FEATURE_NAME}}.json --depended-on-by MILESTONE-N` — pin + atomic DB+JSON sync |
| Mark status | Emit `<task-status>$PREFIX-TASK-ID:done</task-status>` (statuses: `done`, `failed`, `skipped`, `irrelevant`, `blocked`) — loop engine routes through `task-mgr` and syncs the JSON |
If you genuinely need a top-level PRD field that's not surfaced per-task (rare — e.g., cross-PRD `requires[]`), pull it with `jq`, never a full Read:
```bash
jq '.requires' tasks/{{FEATURE_NAME}}.json
jq '.globalAcceptanceCriteria' tasks/{{FEATURE_NAME}}.json
```
### Files you DO touch
| File | Purpose |
| ------------------------------------ | -------------------------------------------------------------------------- |
| `tasks/{{FEATURE_NAME}}-prompt.md` | This prompt file (read-only) |
| `tasks/progress-{{TASK_PREFIX}}.txt` | Progress log — **tail** for recent context, **append** after each task |
**Reading progress** — sections are separated by `---` lines and each starts with `## <Date> - <TASK-ID>`. Never Read the whole log; it grows every iteration. Two targeted patterns cover every case:
```bash
# Most recent section only (default recency check)
tac tasks/progress-$PREFIX.txt 2>/dev/null | awk '/^---$/{exit} {print}' | tac
# Specific prior task (e.g. a synergy task you're building on, or a dependsOn task)
grep -n -A 40 '## .* - <TASK-ID>' tasks/progress-$PREFIX.txt
```
Skip the read entirely on the first iteration (file won't exist). Before appending, create it with a minimal header if missing; never crash on absent files.
---
## Your Task (every iteration)
Optimize for context economy: pull only what's needed, don't dump whole files.
1. **Work the task in `## Current Task`** — the loop engine already selected and claimed it at iteration start. Use `task-mgr show <TASK-ID>` only if you need to inspect the pinned task details again. If `## Current Task` says there is no eligible task or unmet cross-PRD `requires`, output `<promise>BLOCKED</promise>` with the printed reason and stop.
2. **Pull only the progress context you need** — most iterations want just the most recent section (the `tac | awk | tac` command above). If `## Current Task` lists a `dependsOn` task whose rationale you need, grep that specific task's block instead of reading the whole log (`grep -n -A 40 '## .* - <THAT-TASK-ID>' tasks/progress-$PREFIX.txt`). Skip entirely on the first iteration (file won't exist).
3. **Recall focused learnings** — `task-mgr recall --for-task <TASK-ID>` returns the learnings scored highest for this specific task. That's the ONLY way to reach `tasks/long-term-learnings.md` / `tasks/learnings.md` content — **do not** Read those files directly; they grow unboundedly.
**Never Read `CLAUDE.md` in full.** If the task description references a specific section, or the task touches a file that's likely documented there, `grep` for the relevant term and read only the surrounding lines:
```bash
grep -n -A 10 '<keyword or header>' CLAUDE.md
```
The authoritative per-task rules (Priority Philosophy, Prohibited Outcomes, Data Flow Contracts, Project Verification Skills, Key Context, and the CLAUDE.md excerpts that matter for this PRD) are already embedded in **this prompt file**. Prefer it over re-reading source docs. When a verification skill applies, Read that SKILL.md at verification time — do not paste it into the progress log.
4. **Verify branch** — `git branch --show-current` matches the `branchName` task-mgr printed. Switch if wrong.
5. **Think before coding** (in context, not on disk):
- State assumptions to yourself.
- For each `edgeCases` / `invariants` / `failureModes` entry, note how it'll be handled.
- Cross-module data access → consult the **Data Flow Contracts** section or grep 2-3 existing call sites. Never guess key types from variable names.
- Pick an approach. Only survey alternatives when `estimatedEffort: "high"` OR `modifiesBehavior: true` — and even then, one rejected alternative with a one-line reason is enough. For normal tasks: pick and go.
6. **Implement** — single task, code and tests in one coherent change.
7. **Run the floor gate** (see Quality Checks below): every iteration's quality gate is: run `bash bin/gate` (or the project's declared floor command) - the full suite - before the completion commit and paste its `GATE_OK` line as a `Gate:` trailer; a scoped run is a development convenience, never the pre-commit check. If a **Project Verification Skills** entry covers this task, Read that SKILL.md and follow it after the language gate; do not invent a second harness. A green compile/test run is not proof for covered user-facing changes. If the skill is blocked (can't launch, unmet precondition), emit `<promise>BLOCKED</promise>` rather than marking the task done. Fix failures before committing; never commit broken code.
8. **Commit**: `feat: <TASK-ID>-completed - [Title]` (or `refactor:`/`fix:`/`test:` as appropriate). Multiple tasks per iteration: `feat: ID1-completed, ID2-completed - [Title]`.
9. **Emit status**: `<task-status><TASK-ID>:done</task-status>` — the loop engine flips `passes` and syncs the PRD JSON. Do NOT edit the JSON. (Legacy `<completed>TASK-ID</completed>` still works; prefer `<task-status>`.)
10. **Append progress** — ONE post-implementation block, using the format below, terminated with `---` so the next iteration's tail works.
11. For TEST-xxx tasks: target 80%+ coverage on new methods; use `assert_eq!` on string outputs.
---
## Task Selection (reference)
The loop engine owns selection and claim at iteration start. It injects the claimed task into `## Current Task`; work only that pinned task during this iteration.
To request a different pick on the **next** iteration, emit `<reorder>TASK-ID</reorder>`. The engine will claim that task on the next iteration. Never combine reorder with `next --claim`.
Two runtime checks you DO own:
- If `## Current Task` has `preflightChecks`, run them. If any fails: emit `<task-status><TASK-ID>:skipped</task-status>` with the preflight reason and stop this iteration; the engine will pick the next task on the next iteration.
- If the previous task had a `completionCheck`, run it before starting the new one. If it fails: `task-mgr fail <prev-task> --error "completionCheck failed"` and fix it first.
---
## Behavior Modification Protocol (only when `modifiesBehavior: true`)
1. **ANALYSIS gate**: a corresponding `ANALYSIS-xxx` must exist and have `passes: true`. If missing, `task-mgr add --stdin` one and work on it first.
2. **Consumer Impact Table** (in the progress file from the ANALYSIS task):
- `BREAKS` → split the task into per-context subtasks (e.g. `FIX-002a`, `FIX-002b`) via `task-mgr add`, then `task-mgr skip` the original with reason "split into …".
- `NEEDS_REVIEW` → verify manually before implementing.
- `OK` → proceed.
3. **Semantic distinctions**: if ANALYSIS identified multiple contexts for the same code path (e.g. LLM-invoked vs auto-invoke), each context may need different handling — split rather than shoehorn.
---
## Quality Checks
The full test suite is expensive. Per-iteration tasks run a **scoped** gate; **milestones** run the full gate and must leave the repo fully green (including pre-existing failures).
### Per-iteration scoped gate (implementation / test / fix tasks)
Format → type-check → lint → **scoped tests for touched files** → pre-commit hooks. Fix every failure before committing.
```bash
# Rust — scope tests to the touched crate/module (grep touchesFiles to pick)
cargo fmt --check
cargo check # fast type check
cargo clippy -- -D warnings
cargo test -p <affected-crate> # whole crate
cargo test -p <affected-crate> <module_or_fn_name> # narrower match within the crate
# Python
ruff check --fix && ruff format
mypy --strict <touched/dir>
pytest tests/<touched_module> -x # scope to tests around changed files
```
Scoping heuristic: start from `touchesFiles`. For each Rust file, run `cargo test -p <its crate>`. For Python, run `pytest` against the test file(s) that target the touched module. If you can't determine the scope confidently, widen to the whole package (still cheaper than the full workspace).
**Do NOT** run the entire workspace test suite (`cargo test` with no filter, `pytest` with no path) during regular iterations — that's the milestone's job.
**Project verification skill:** if this prompt has a **Project Verification Skills** section, run it after the language gate for covered tasks (see that section). Compile/unit tests alone are not proof for those changes.
### Final gate at REVIEW-001 (the milestone)
The single `REVIEW-001` task at the end of the lean path runs the **full, unscoped** suite on a clean checkout and must finish green. There are no separate MILESTONE-1 or MILESTONE-2 tasks in the reduced-ceremony skeleton.
```bash
# Rust
cargo fmt --check && cargo check && cargo clippy -- -D warnings && cargo test
# Python
ruff check && ruff format --check && mypy --strict && pytest
```
If ANY test fails — including pre-existing failures that predate this PRD — the milestone fixes them. Default: **attempt every failure**, even ones that look out-of-scope. They become scope the moment the milestone gates the phase on the full suite being green. Trunk-green is the invariant this mechanism exists to protect.
Pragmatic escape hatch: if there are **more than ~12 failures AND they're all clearly unrelated to this PRD** (e.g., a sibling team's integration test against a now-missing service), don't try to do all of them inline. Triage:
1. Fix everything you can attribute to this PRD's changes, inline in the milestone commit.
2. For the remaining unrelated failures: spawn a single `FIX-xxx` or `CLARIFY-xxx` task via `task-mgr add --stdin --depended-on-by <THIS-MILESTONE>` listing the failing test names + error summaries, and `<promise>BLOCKED</promise>` with that task ID so a human can route ownership.
Below the ~12-failure threshold, just fix them. Each failure you punt is a tax on every future milestone, so the bar to punt is deliberately high.
If a **Project Verification Skills** section is present, this gate also includes that skill's mapped-feature drive (see that section).
---
{{#if VERIFICATION_SKILLS}}
## Project Verification Skills
This repo ships a project-level verification skill. Language-level gates (fmt, type-check, lint, scoped tests) are **necessary but not sufficient** for user-facing changes the skill covers. Follow the skill literally — do not invent a second harness, and do not paste the skill body into the progress log.
{{VERIFICATION_SKILLS}}
**Per-iteration:** if this task is listed in **This PRD maps to** (or is a FIX / WIRE-FIX spawned from a mapped task), Read that SKILL.md (and the matching `features/*.md` if listed) and drive that recipe after the scoped language gate. Capture evidence where the skill says. A green compile/test run is not proof.
**REVIEW-001 / milestone:** drive every listed feature this PRD touched. A skipped sub-feature is reported skipped, not verified via a sibling path.
**Blocked skill:** if you cannot launch or a precondition fails, emit `<promise>BLOCKED</promise>` with the unmet precondition. Do not skip the drive and mark the task done.
---
{{/if}}
## Common Wiring Failures (CODE-REVIEW-1 reference)
New code must be reachable from production — CODE-REVIEW-1 verifies. Most common misses:
- Not registered in dispatcher/router → add to registration
- Test mocks bypass real wiring → verify production path separately
- Config field read but not passed through → wire through
- Unused-import warning on new code → call sites missing
- Wrong key type on map access (atom vs string) — struct keys ≠ JSONB keys → check Data Flow Contracts
- New CLI subcommand / DB column / JSON field defined but not threaded into the dispatcher / `TryFrom<Row>` / parse-to-task mapping
---
## Contract Tasks
`CONTRACT-xxx` tasks (`taskType: "contract"`) are **design-only**. Their job is to produce a stable, reviewable foundational contract (interface, data shape, error model, ownership) that 2+ downstream implementation tasks will depend on.
**When you are given a CONTRACT task**:
- Do not write production code or full test suites.
- Produce the precise definition + extreme details (edge cases, invariants, known-bad discriminators, failure modes, alternatives considered + rationale).
- Explicitly list every downstream story / task ID that will depend on this contract.
- Record the **full contract text** in the progress log under a clear `## CONTRACT-001` (or equivalent) header so later agents can read it directly.
- Emit `<task-status>CONTRACT-001:done</task-status>` when the contract is recorded and the acceptance criteria are satisfied.
Downstream FEAT/FIX tasks that list a CONTRACT task in `dependsOn` are expected to implement against the recorded contract. If the contract needs revision, the revision must be done by re-opening the CONTRACT task (or spawning a follow-up CONTRACT-FIX via `task-mgr add`).
---
## Review Tasks
Review-type tasks (`CODE-REVIEW-1`, `REFACTOR-REVIEW-FINAL`) spawn follow-up tasks for each issue found. The loop re-reads state every iteration, so spawned tasks are picked up automatically.
### What each review looks for
| Review | Priority | Spawns (priority) | Before | Focus |
| ----------------------- | -------- | ---------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------- |
| CODE-REVIEW-1 | 13 | `CODE-FIX` / `WIRE-FIX` (14-16) | early FEATs + CONTRACT | Language idioms, security, error handling, `qualityDimensions`, wiring, respect for any CONTRACT |
| REFACTOR-REVIEW-FINAL | 70 | `REFACTOR-xxx` (71-85) | all implementation | All code + tests: DRY, complexity, coupling, clarity, contract fidelity — full-context final pass |
Use the **rust-python-code-reviewer** / equivalent language agent when reviewing code. Document findings in the progress file. If a specific prior iteration produced something ugly and you don't want to wait for REFACTOR-REVIEW-FINAL, invoke `/simplify` on that touchpoint directly — don't file a dedicated review task just for it.
### Spawning follow-up tasks
One shape covers CODE-FIX, WIRE-FIX, and all REFACTOR-N-xxx — vary `id`, `priority`, and include `rootCause`/`exactFix`/`verifyCommand` for fix tasks so the implementing agent lands the fix in one pass:
```sh
echo '{
"id": "CODE-FIX-001",
"title": "Fix: <specific issue>",
"description": "From CODE-REVIEW-1: <details>",
"rootCause": "<file:line + issue>",
"exactFix": "<specific change>",
"verifyCommand": "<shell command that proves the fix>",
"acceptanceCriteria": ["Issue resolved", "No new warnings"],
"priority": 14,
"touchesFiles": ["affected/file.rs"]
}' | task-mgr add --stdin --from-json tasks/{{FEATURE_NAME}}.json --depended-on-by MILESTONE-1
```
`--depended-on-by` wires the new task into the milestone's `dependsOn` AND syncs the PRD JSON atomically — don't edit the JSON yourself. When a **Project Verification Skills** entry covers the issue, set `verifyCommand` to that skill's drive (the helper or recipe the SKILL.md names), not a unit-test invocation. Commit with `chore: <REVIEW-ID> - Add <FIX|REFACTOR> tasks`, then emit `<task-status><REVIEW-ID>:done</task-status>`. If no issues found, emit the status with a one-line "No issues found" in the progress file.
---
## Progress Report Format
APPEND a block to `tasks/progress-{{TASK_PREFIX}}.txt` (create with a one-line header if missing). Keep it **tight** — future iterations tail this; verbosity here bloats every later context.
```
## [YYYY-MM-DD HH:MM] - [TASK-ID]
Approach: [one sentence — what you chose and why]
Files: [comma-separated paths touched]
Learnings: [1-3 bullets, one line each]
---
```
Target: ~10 lines per block. If your entry is longer than ~25 lines, compress it — a future iteration has to read this.
---
## Learnings Guidelines
Learnings live in `tasks/long-term-learnings.md` (curated) and `tasks/learnings.md` (raw, auto-appended). **Do not Read those files directly** during a loop iteration — they grow unboundedly. Instead:
- `task-mgr recall --for-task <TASK-ID>` — indexed retrieval of learnings scored for this task
- `task-mgr recall --query "<keywords>"` / `--tag <tag>` — targeted queries when recall is sparse
Record your own learnings with `task-mgr learn` so they're indexed for future recall. Don't append directly to those files.
**Write concise learnings** (1-2 lines each):
- GOOD: "`temps::chrono::Timezone` accessed via full path, not temps_core"
- BAD: "The temps crate exports Timezone from temps::chrono module, so when using it you need to access it via the full path temps::chrono::Timezone rather than importing from temps_core which doesn't re-export it."
**Group related tasks** when reporting:
- Instead of separate entries for FIX-001, FIX-002, FIX-003
- Write: "FIX-001 through FIX-003: Fixed X by doing Y"
---
## Stop and Blocked Conditions
### Stop Condition
Before outputting `<promise>COMPLETE</promise>`:
1. Verify ALL stories have `passes: true`
2. Verify no new tasks were created in final review
3. Verify all milestones pass
If verified:
```
<promise>COMPLETE</promise>
```
### Blocked Condition
If blocked (missing dependencies, unclear requirements):
1. Document blocker in the progress file
2. Create clarification task (e.g., `CLARIFY-001` with priority 0)
3. Add to JSON and commit: `chore: Add blocker task CLARIFY-001`
4. Output:
```
<promise>BLOCKED</promise>
```
---
## Milestones
Milestones (MILESTONE-xxx) are **full-gate checkpoints**: they prove the trunk is green before the next phase begins. They are NOT a sweep to rewrite remaining tasks — stale tasks self-correct when their agent picks them up.
### Milestone Protocol
1. Check all `dependsOn` tasks have `passes: true`. If any don't, the milestone can't run yet.
2. **Run the full quality gate** (see Quality Checks § Milestone gate — unscoped format, type-check, lint, and the complete test suite). This is the ONE place in the loop where the entire test suite runs. If a **Project Verification Skills** section is present, also drive every mapped feature this PRD touched.
3. **Leave the repo green.** For every failure, including pre-existing ones that predate this PRD:
- Trivial fixes go in the milestone's own commit: `chore: MILESTONE-N - fix stale test <name>`.
- Non-trivial failures → spawn a `FIX-xxx` task via `task-mgr add --stdin --depended-on-by <THIS-MILESTONE>` with the failure's `verifyCommand`. The loop picks it up; the milestone re-runs when the FIX passes.
- If the failure reveals that a remaining task in this PRD is stale or needs splitting, spawn the correction now. This is the ONLY time milestones touch the task graph — and only in response to a concrete test failure, not a speculative sweep.
4. **Batch sibling PRDs** (if the "Sibling PRD Tasks" section is present AND the full suite revealed cross-PRD breakage): update only the affected sibling tasks with `task-mgr add`/`--append --update-existing`. Commit separately: `chore: MILESTONE-N - update sibling tasks in <file>.json`.
5. Mark the milestone `<task-status>MILESTONE-N:done</task-status>` only when the full gate is green.
---
{{#if REFERENCE_CODE}}
## Reference Code
{{REFERENCE_CODE}}
---
{{/if}}
{{#if KEY_LEARNINGS}}
## Key Learnings (from task-mgr recall)
These are pre-distilled learnings relevant to this PRD. Treat them as authoritative — do NOT Read `tasks/long-term-learnings.md` or `tasks/learnings.md` unless a task explicitly needs a learning that isn't here (then use `task-mgr recall --query <text>`, not a full Read).
{{KEY_LEARNINGS}}
---
{{/if}}
{{#if CLAUDE_MD_EXCERPTS}}
## CLAUDE.md Excerpts (only what applies to this PRD)
These bullets were extracted from `CLAUDE.md` for the subsystems this PRD touches. They're the only CLAUDE.md content you need for iteration work — do NOT Read the full file. If a task description cites a section name not shown here, `grep -n -A 10 '<section header>' CLAUDE.md` to pull just that block.
{{CLAUDE_MD_EXCERPTS}}
---
{{/if}}
{{#if DATA_FLOW_CONTRACTS}}
## Data Flow Contracts
These are **verified access patterns** f
*Truncated - read the full file at https://github.com/chrisarm/task-mgr-framework/blob/21d7c3a8c4a0135da8226975e4fcae97b022fa3f/.claude/commands/prd-tasks.md.*