
Plan
- 1.3k installs
- 416 repo stars
- Updated August 5, 2026
- boshu2/agentops
plan provides documented workflows for Decompose goals into issue plans. Triggers: "plan", "decompose goals into issue plans.", "plan skill".
About
The plan skill decompose goals into issue plans. Triggers: "plan", "decompose goals into issue plans.", "plan skill". # Plan Skill > **Quick Ref:** Decompose goal into trackable issues with waves. Output: `.agents/plans/*.md` + br issues. **YOU MUST EXECUTE THIS WORKFLOW. Do not just describe it.** ## Absorbed trigger surface - planning-workflow (folded in, skill-prune phase 2) This skill also covers the retired `planning-workflow` skill: the comprehensive markdown planning methodology for software projects. Use `plan` when starting a new project, creating implementation plans, or refining architecture before coding - planning tokens are far fewer and cheaper than implementation tokens, so front-load the thinking. The absorbed methodology's bar for a *delivered* plan: self-contained (a fresh agent can implement without asking the human), dependency-aware (decomposes cleanly into a beads graph), justified (every non-obvious choice has a *why*), reviewed to steady-state by a strong reasoning model, and converted to beads with the dependency edges intact. Ground every load-bearing architectural claim (library choices, existing-codebase structure, performance/cost numbers) in a ve.
- complexity is `"full"`
- the bead is older than 7 days
- the bead description was filed by a prior session (e.g., handoff-sourced, deferred, or reopened)
- **Title**: Clear action verb (e.g., "Add authentication middleware")
- **Description**: What needs to be done
Plan by the numbers
- 1,329 all-time installs (skills.sh)
- +26 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #405 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
plan capabilities & compatibility
- Capabilities
- complexity is `"full"` · the bead is older than 7 days · the bead description was filed by a prior sessio · **title**: clear action verb (e.g., "add authent · **description**: what needs to be done
- Use cases
- documentation
What plan says it does
# Plan Skill > **Quick Ref:** Decompose goal into trackable issues with waves.
Output: `.agents/plans/*.md` + br issues.
npx skills add https://github.com/boshu2/agentops --skill planAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.3k |
|---|---|
| repo stars | ★ 416 |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 5, 2026 |
| Repository | boshu2/agentops ↗ |
How do I use plan for the task described in its SKILL.md triggers?
Decompose goals into issue plans. Triggers: "plan", "decompose goals into issue plans.", "plan skill".
Who is it for?
Teams invoking plan when the user request matches documented triggers and prerequisites.
Skip if: Skip when cached docs are missing, the request is a negative trigger, or another sibling skill owns the workflow.
When should I use this skill?
Decompose goals into issue plans. Triggers: "plan", "decompose goals into issue plans.", "plan skill".
What you get
Step-by-step guidance grounded in plan documentation and reference files.
- .agents/plans/*.md
- execution-packet.json
- beads issues
By the numbers
- Depends on 5 AgentOps skills: research, beads, pre-mortem, crank, implement
- Produces 2 artifact types: `.agents/plans/*.md` and `execution-packet.json`
Files
Plan Skill
Quick Ref: Decompose goal into trackable issues with waves. Output: .agents/plans/*.md + br issues.YOU MUST EXECUTE THIS WORKFLOW. Do not just describe it.
Absorbed trigger surface — planning-workflow (folded in, skill-prune phase 2)
This skill also covers the retired planning-workflow skill: the comprehensive markdown planning methodology for software projects. Use plan when starting a new project, creating implementation plans, or refining architecture before coding — planning tokens are far fewer and cheaper than implementation tokens, so front-load the thinking. The absorbed methodology's bar for a delivered plan: self-contained (a fresh agent can implement without asking the human), dependency-aware (decomposes cleanly into a beads graph), justified (every non-obvious choice has a why), reviewed to steady-state by a strong reasoning model, and converted to beads with the dependency edges intact. Ground every load-bearing architectural claim (library choices, existing-codebase structure, performance/cost numbers) in a verifiable source before it survives a review round. For small local changes (< ~200 LOC), plan in chat instead — the planning overhead would exceed the implementation cost.
Loop position
Moves 3 (vertical slice decomposition) and 5 (wave validity check) of the operating loop. Consumes the BDD intent issue; produces a slice validation plan — one slice per Given/When/Then row with a first-failing-test target, write-scope, bounded context, and ownership. Slices group into a wave only when every row of the wave-validity check passes (distinct write scopes, no shared migration/contract/CLI surface, declared integration order, owner per slice, discard path per slice). Default to sequential when in doubt — parallel waves are an optimization, not a default.
CLI dependencies: br (issue creation) and bv (graph triage). If br is unavailable, write the plan to .agents/plans/ as markdown with issue descriptions, and use TaskList for tracking instead. The plan document is always created regardless of br availability.
Discovery Boundary
Use the Skill Ports and Adapters vocabulary and the Intent-to-Loop Hexagon for the boundary from Discovery into Plan:
| Boundary piece | Plan contract |
|---|---|
| Inbound port | plan_slices from BDD intent, bead, research artifact, or execution packet |
| Outbound ports | persist_issue, verify_symbols, retrieve_context, seed_execution_packet |
| Driving adapter | /plan skill invocation |
| Driven adapters | br, bv, rg, .agents/findings, .agents/plans, execution-packet writer |
| Context packet | slice plan, file dependency matrix, acceptance criteria, test levels |
| Guard adapter | stale-scope verification, symbol verification, wave-validity check |
Executable acceptance: references/plan.feature — consumes Discovery output, one slice per Given/When/Then row, wave-validity gate, durable slice-validation artifact.
Flags
| Flag | Default | Description |
|---|---|---|
--auto | off | Skip human approval gate. Used by /rpi --auto for fully autonomous lifecycle. |
--fast-path | off | Force Minimal detail template (see Step 3.2) |
--skip-symbol-check | off | Skip symbol verification in Step 3.6 (for greenfield plans) |
--skip-audit-gate | off | Skip baseline audit gate in Step 6 (for documentation-only plans) |
Execution Steps
Given /plan <goal> [--auto]:
Step 0: Bead-Input Pre-Flight (Stale-Scope Gate)
When the input to /plan is a bead ID (matches pattern [a-z]{2,6}-[0-9a-z.]+) AND any of the following conditions hold, automatically run ao beads verify <bead-id> as the very first action before any other planning step:
- complexity is
"full" - the bead is older than 7 days
- the bead description was filed by a prior session (e.g., handoff-sourced, deferred, or reopened)
# Example guard — run before Step 1
if [[ "$INPUT" =~ ^[a-z]{2,6}-[0-9a-z.]+$ ]]; then
ao beads verify "$INPUT" || true
fiIf ao beads verify reports any STALE citations, present them to the user (or log them to the execution packet in --auto mode) and ask for scope re-validation before proceeding to Step 1. Do not decompose against stale evidence.
This implements the shared stale-scope validation rule — re-validate inherited scope estimates against HEAD before acting on deferred beads, handoff docs, or prior-session plans.
Step 1: Setup
mkdir -p .agents/plansStep 2: Check for Prior Research + Knowledge Flywheel
ls -la .agents/research/ and use Grep to find prior research. If found, read it before planning.
Then run ao search / ao lookup for prior planning patterns and apply (not just retrieve) any relevant learnings as planning constraints. Record citations with ao metrics cite --type applied|retrieved.
Read references/pre-decomposition.md for full flywheel-search commands, the apply-retrieved-knowledge contract, and section-evidence handling.
Step 2.1: Load Compiled Prevention First (Mandatory)
Load compiled planning rules from .agents/planning-rules/*.md (primary) and fall back to .agents/findings/registry.jsonl. Match by finding ID, applicable_when, language, literal goal-text overlap, and changed-file overlap. Cap at top 5.
Record applied finding IDs and how they changed the plan. Fail open on missing/malformed files. Read references/pre-decomposition.md for the full ranked-packet contract.
Active findings from .agents/findings/registry.jsonl are a fallback planning input. Every written plan must include an Applied findings: line, even when the value is none.
Step 2.2: Read and Validate Research Content
If research files exist, read the most recent one and verify it contains substantive sections (Summary, Findings, Architecture, Executive Summary, Recommendations) before proceeding. See references/pre-decomposition.md for the validation grep and warning behavior.
Step 2.3: Optional Strategic Duel Gate
When the plan is likely to span more than one execution session AND it contains at least one contested operator-default decision, recommend the dueling-idea-wizards route (/council --mode=debate --focus=ideas) on the strategic question before decomposition. Treat it as advisory, not a hard prerequisite: skip it for single-session plans or plans with no meaningful contested default. Evidence from the 2026-05-17 Mt Olympus run: a roughly 22 minute duel flipped 3/5 operator defaults and surfaced one already-shipped adapter bug that ordinary review and passing tests had missed.
Step 3: Explore the Codebase (if needed)
Dispatch an Explore sub-agent (Task tool) with a prompt that demands symbol-level detail: file inventory, function/method signatures, struct/type definitions, reuse points with file:line, test file locations and naming conventions, import paths. Read references/pre-decomposition.md for the canonical explore prompt.
Pre-Planning Baseline Audit (Mandatory)
Before decomposing, run grep/wc/ls commands to quantify files to change, sections to add/remove, LOC to modify, coverage gaps. Record commands alongside results. File size limits (800-line SKILL.md lint limit) and test fixture counts are mandatory checks. Ground truth with numbers prevents scope creep.
Read references/pre-decomposition.md for the bad/good examples table and the full audit recipe.
Step 3.2: Scale Detail by Complexity
Auto-select plan detail level based on issue count and goal complexity:
| Level | Criteria | Template | Description |
|---|---|---|---|
| Minimal | 1-2 issues, fast complexity | Bullet points per issue | Title, 2-line description, acceptance criteria, files list |
| Standard | 3-6 issues, standard complexity | Current plan format | Full implementation specs, tests, verification |
| Deep | 7+ issues, full complexity, or --deep | Extended format | Symbol-level specs, data transformation tables, design briefs, cross-wave registry |
Read references/detail-templates.md for the template definitions.
Override: --deep forces Deep regardless of issue count. --fast-path forces Minimal.
Step 3.5: Generate Implementation Detail (Mandatory)
After exploring the codebase, generate symbol-level implementation detail for EVERY file in the plan. A worker reading the plan should know exactly what to write without rediscovering function names, parameters, or code locations.
Read references/implementation-detail.md for the full contract: file inventory table, per-section implementation specs (function signatures, reuse points, inline code blocks, struct fields, CLI flag definitions), named test functions with pyramid levels, verification procedures, data transformation mapping tables, and symbol verification.
Step 3.6: Symbol Verification (Mandatory)
See the Symbol Verification section in references/implementation-detail.md. For each symbol cited in the plan, grep the codebase to verify it exists. If >20% of cited symbols are stale, WARN (do not block) and log them under ## Stale Symbol Warnings. Opt-out: --skip-symbol-check.
Step 4: Decompose into Issues
Analyze the goal and break it into discrete, implementable issues. For each issue define:
- Title: Clear action verb (e.g., "Add authentication middleware")
- Description: What needs to be done
- Dependencies: Which issues must complete first (if any)
- Scenarios: A Gherkin
## Scenariosblock (Given/When/Then) — mandatory by default for every bead (see Scenarios contract below) - Acceptance criteria: How to verify it's done — emitted as a fenced YAML
acceptance_criteriablock (see contract below) - Test levels: Which pyramid levels (L0–L3) this issue's tests cover
Gherkin Scenarios Contract (mandatory, default)
Every bead this skill creates MUST carry an embedded `## Scenarios` block in Gherkin (Given/When/Then) — by default, without being asked. Free-text-only acceptance is invalid (AGENTS.md: "Free-text acceptance is invalid — promote it to scenarios before work begins"). The operator never hand-specifies BDD: planning emits behavior-based acceptance as scenarios automatically.
Each bead body (and the parent epic body) carries a ## Scenarios block of one or more scenarios:
## Scenarios
Scenario: <behavior named as an observable outcome>
Given <precondition / starting state>
When <action / event>
Then <expected observable result>
And <additional assertion> # optionalRules:
- One scenario per distinct Given/When/Then behavior; a bead with N behaviors carries N scenarios.
- Scenarios describe observable behavior, not implementation steps.
- The
## Scenariosblock sits in the bead description ABOVE theacceptance_criteriaYAML; the YAML is the machine-checkable layer, Gherkin is the behavior layer (they are complementary, not substitutes). - This contract is enforced mechanically by the Step 7b.0 admission gate (
scripts/check-bead-scenario-coverage.sh --admission, perreferences/task-creation.md): every created bead is piped through the gate post-creation, and a bead that fails admission must be fixed before the plan is reported DONE.
This is the same ## Scenarios block the bead-embedded acceptance model expects (scenario-hash-stability CI gate) and that /discovery lifts into the execution packet.
Acceptance Criteria Contract (mandatory)
Every issue body MUST contain an acceptance_criteria fenced YAML block. The block lives BELOW the issue's ## Scenarios block and ABOVE any "Reference" or "Notes" trailer. The parent epic body carries its own acceptance_criteria block (epic-level criteria); each child bead carries its own. /discovery STEP 6 lifts both into the execution packet under epic_criteria and bead_criteria. Canonical shape: `schemas/execution-packet.schema.json` (#/$defs/Criterion).
The ## Scenarios Gherkin block above is the behavior layer and is mandatory by default for every bead; the acceptance_criteria YAML is the machine-checkable layer. They are complementary, never substitutes. Every non-trivial plan and bead body SHOULD also include the hexagon: boundary block from docs/architecture/intent-to-loop-hexagon.md so the next agent knows the inbound port, bounded context, adapters, context packet, and done state.
acceptance_criteria:
- id: ac-<scope>.<n>
description: "<one-line measurable statement>"
check_type: test_pass | command_exit_zero | file_exists | grep_match | manual | council_judge | custom_rubric
check_command: "<shell command or script path>"
evidence_path: "<glob>"
evidence_required: true | false
weight: 0.0–1.0
optional: true | false
agent_judge: "<council:name>" # REQUIRED only when check_type == custom_rubricagent_judge is REQUIRED when check_type == "custom_rubric" — custom_rubric accepts free-text check_command, so the judge field names the council/judge that owns the verdict. The schema enforces this with an if/then clause; an issue body that omits it for a custom_rubric criterion is a contract violation, not a soft warning.
Read references/decomposition.md for: anti-pattern pre-flight, design briefs for rewrites, issue granularity rules, operationalization heuristics, conformance checks, and schema strictness pre-flight.
Step 5: Compute Waves
Group issues by dependencies for parallel execution:
- Wave 1: Issues with no dependencies (can run in parallel)
- Wave 2: Issues depending only on Wave 1
- Wave 3: Issues depending on Wave 2
- Continue until all issues assigned
Planning Rules Compliance (Mandatory Gate): After computing waves, fill in the Planning Rules Compliance checklist (PR-001 through PR-007) in the plan document — see the table in references/plan-document-template.md. Read references/planning-rules.md for detection questions and evidence. Every rule MUST have an explicit justification or N/A rationale. If any row has an empty Justification column, mark the plan output as INCOMPLETE and do not proceed to Step 5.5.
Step 5.5: File Dependency Matrix (MANDATORY)
Before writing the plan document, produce an explicit file-level dependency matrix mapping each task to every file it reads or writes (columns: Task, File, Access=read/write, Notes). This matrix is the input to the swarm pre-spawn conflict check — without it, handoff to /swarm is blocked. Every write is an ownership claim: two same-wave tasks claiming write on the same file MUST be serialized (blockedBy) or merged. read conflicts with concurrent write but not with other reads. Include tests, docs, schemas, fixtures, generated artifacts, and Codex companion files — not just primary sources. The swarm skill's local-mode Pre-Spawn Conflict Check consumes this matrix.
Read references/wave-matrices.md for the full file-conflict matrix format, an example table, cross-wave shared file registry, generated-artifact companion scope, and dependency-necessity validation rules.
Step 6: Write Plan Document
Write to: .agents/plans/YYYY-MM-DD-<goal-slug>.md
Read references/plan-document-template.md for the full canonical template (Context, Intent Issue, Files to Modify, Boundaries, Baseline Audit, Implementation, Tests, Slice Validation Plan, Conformance Checks, Verification, Issues, Execution Order, Planning Rules Compliance, Post-Merge Cleanup, Next Steps) and the Baseline Audit Gate (BLOCK if missing, WARN if incomplete, --skip-audit-gate to opt out). The Intent Issue section links the upstream BDD intent issue and carries its acceptance examples; the Slice Validation Plan section embeds the slice-validation surface (one slice per Given/When/Then with a first failing test, write scope, bounded context, owner), the wave-validity gate, and a roll-up acceptance table. Conformance Checks remains the machine-checkable layer — Gherkin is the behavior layer, not a replacement.
Step 7: Create Tasks for In-Session Tracking
Read references/task-creation.md for the full TaskCreate + beads creation workflow, including: persistent beads issues for ratchet tracking, embedding conformance checks as fenced validation blocks in issue bodies, cross-cutting constraint injection on the epic, wave formation via blocks dependencies, and the Step 7b post-creation validation-block verification gate.
Step 8: Request Human Approval (Gate 2)
Skip this step if `--auto` flag is set. In auto mode, proceed directly to Step 9.
USE AskUserQuestion tool:
Tool: AskUserQuestion
Parameters:
questions:
- question: "Plan complete with N tasks in M waves. Approve to proceed?"
header: "Gate 2"
options:
- label: "Approve"
description: "Proceed to /pre-mortem or /crank"
- label: "Revise"
description: "Modify the plan before proceeding"
- label: "Back to Research"
description: "Need more research before planning"
multiSelect: falseWait for approval before reporting completion.
Step 9: Record Ratchet Progress
ao ratchet record plan 2>/dev/null || trueStep 10: Report to User
Tell the user: 1. Plan document location 2. Number of issues identified 3. Wave structure for parallel execution 4. Tasks created (beads issue IDs or file-backed task refs) 5. Next step: /pre-mortem for failure simulation, then /crank for execution
Key Rules
- Read research first if it exists
- Explore codebase to understand current state
- Identify dependencies between issues
- Compute waves for parallel execution
- Always write the plan to
.agents/plans/
Examples
`/plan "add user authentication"` — Reads research, decomposes into 5 issues (middleware, session store, token validation, tests, docs), creates epic with 2 waves, writes plan to .agents/plans/.
`/plan --auto "refactor payment module"` — Skips approval gates, creates 3-wave/8-issue epic autonomously, ready for /crank.
`/plan "remove dead code"` — Runs quantitative audit (3,003 LOC), creates issues with exact file/LOC targets, includes deletion verification checks.
`/plan "add stale run detection to RPI status"` — Symbol-level detail: names exact functions, struct fields, JSON tags, test names. Implementer executes in a single pass.
See references/examples.md for full walkthroughs.
Troubleshooting
| Problem | Solution |
|---|---|
| br create fails | Run br init --prefix <prefix> first |
| Plan too large (>20 issues) | Narrow goal or split into multiple epics |
| Wave structure incorrect | Review dependencies: does blocked issue modify blocker's files? |
| Conformance checks missing | Add files_exist, content_check, tests, or command checks |
See references/examples.md for more troubleshooting scenarios.
Reference Documents
- references/planning-rules.md — seven compiled planning rules (mechanical enforcement, external validation, feedback loops, separation, process gates, cross-layer consistency, phased rollout).
- Shared stale-scope validation rule — re-validate inherited scope estimates against HEAD before acting on deferred beads, handoff docs, or prior-session plans. Invoked by Step 0 via
ao beads verify. - references/implementation-detail.md — symbol-level implementation specs, test pyramid classification, verification procedures, data transformation tables, symbol verification.
- references/decomposition.md — anti-pattern pre-flight, design briefs, issue granularity, conformance checks, schema strictness.
- references/wave-matrices.md — file-conflict matrix, cross-wave shared file registry, dependency-necessity validation.
- references/plan-document-template.md — canonical
.agents/plans/*.mddocument template with baseline audit gate. - references/task-creation.md — TaskCreate/beads creation, validation-block embedding, post-creation verification.
- references/plan-mutations.md
- references/complexity-estimation.md
- references/detail-templates.md
- references/examples.md
- references/plan-to-beads-workflow.md
- references/sdd-patterns.md
- references/templates.md
Complexity Estimation Heuristics
Extract-Method CC Reduction
Rule of thumb: Each extract-method refactoring reduces the source function's CC by 3-5 points.
| Source CC | Extractions Needed | Expected Result |
|---|---|---|
| 15-20 | 1-2 | CC 10-15 |
| 20-25 | 3-4 | CC 10-15 |
| 25-30 | 4-6 | CC 10-15 |
| 30-40 | 6-10 | CC 10-15 |
Do NOT assume 50% reduction per extraction. Each extraction only removes the branching contained within the extracted block. A 35 CC function with 8 if/switch arms needs ~8 extractions, not 4.
Evidence
- ag-atu: Plan estimated CC 35 → ~10 with 4 extractions. Pre-mortem caught the error. Actual: 8 extractions needed to reach CC 12.
- General: CC tracks decision points (if, switch, for, &&, ||). Extract-method moves decision points, not removes them.
When to Flag
- Plan claims CC reduction >50% with <4 extractions → likely overestimate
- Target CC <10 from CC >25 → will need 6+ extractions minimum
- Any plan that doesn't count extractions individually → underspecified
Decomposition Patterns
Extracted from plan/SKILL.md on 2026-04-11.
Anti-pattern pre-flight, issue granularity, conformance checks, schema strictness.
Anti-Pattern Pre-Flight
Before finalizing issue decomposition, verify the plan avoids these confirmed failure modes:
| Anti-Pattern | Detection Question | Gate |
|---|---|---|
| Free-text-only acceptance | Does every bead carry an embedded ## Scenarios Gherkin block by default? | FAIL if any bead ships free-text-only acceptance with no ## Scenarios (Given/When/Then) block — promote it to scenarios before creating the bead |
| Brainstorm masquerading as plan | Does every issue have mechanically verifiable acceptance criteria? | FAIL if any issue lacks files_exist, content_check, tests, or command conformance checks |
| Dead infrastructure | Does the plan provision anything without an activation test? | WARN if infrastructure is created without a corresponding smoke test issue |
| Propagation surface blindness | Has the full propagation surface been enumerated for renames/refactors? | FAIL if structural changes lack a propagation surface table |
| 40% context budget violation | Will implementation sessions need to load >40% context window for knowledge? | WARN if injected knowledge exceeds estimated budget |
| Commit-per-session anti-pattern | Does the wave structure enforce commit-per-wave? | WARN if no explicit commit cadence in execution order |
Design Briefs for Rewrites
For any issue that says "rewrite", "redesign", or "create from scratch": Include a design brief (3+ sentences) covering: 1. Purpose — what does this component do in the new architecture? 2. Key artifacts — what files/interfaces define success? 3. Workflows — what sequences must work?
Without a design brief, workers invent design decisions. In ol-571, a spec rewrite issue without a design brief produced output that diverged from the intended architecture.
Issue Granularity
- 1-2 independent files → 1 issue
- 3+ independent files with no code deps → split into sub-issues (one per file)
- Example: "Rewrite 4 specs" → 4 sub-issues (4.1, 4.2, 4.3, 4.4)
- Enables N parallel workers instead of 1 serial worker
- Shared files between issues → serialize or assign to same worker
Operationalization Heuristics
Each issue must be immediately executable by a swarm worker without further research:
- File ownership (`metadata.files`): List every file the issue touches. Workers use this for conflict detection.
- Validation commands (`metadata.validation`): Include runnable checks (e.g.,
go test ./...,bash -n script.sh). Workers run these before reporting done. - Homogeneous wave grouping: Group issues by work type (all Go, all docs, all shell) within the same wave. Mixed-type waves cause toolchain context-switching and increase conflict risk.
- Same-file serialization: If two issues touch the same file, flag them for serialization (different waves) or merge into one issue. Never assign same-file issues to parallel workers.
Conformance Checks
For each issue's acceptance criteria, derive at least one mechanically verifiable conformance check using validation-contract.md types. These checks bridge the gap between spec intent and implementation verification.
| Acceptance Criteria | Conformance Check |
|---|---|
| "File X exists" | files_exist: ["X"] |
| "Function Y is implemented" | content_check: {file: "src/foo.go", pattern: "func Y"} |
| "Tests pass" | tests: "go test ./..." |
| "Endpoint returns 200" | `command: "curl -s -o /dev/null -w '%{http_code}' localhost:8080/api \ |
| "Config has setting Z" | content_check: {file: "config.yaml", pattern: "setting_z:"} |
Rules:
- Every issue MUST have at least one conformance check
- Checks MUST use validation-contract.md types:
files_exist,content_check,command,tests,lint - Prefer
content_checkandfiles_exist(fast, deterministic) overcommand(slower, environment-dependent) - If acceptance criteria cannot be mechanically verified, flag it as underspecified
- When adding entries to config files enumerated by tests, search for hardcoded count assertions:
grep -rn 'len.*!=\|len.*==\|expected.*count' <test-dir>/
Schema Strictness Pre-Flight (WARN)
When any issue's file list includes JSON schema files (*.schema.json, files in schemas/), check for additionalProperties: false:
for f in <issue-files matching *.schema.json or schemas/*.json>; do
if grep -q '"additionalProperties":\s*false' "$f" 2>/dev/null; then
echo "WARN: $f has additionalProperties:false — new fields require schema update BEFORE consumer changes"
fi
doneIf triggered: Ensure schema-modifying issues are in an earlier wave than issues that reference the new fields. This prevents implementation failures where consumer SKILL.md files reference fields that the schema doesn't yet allow.
This is advisory (WARN, not FAIL). The wave decomposition in Step 5 must respect this ordering.
Plan Detail Templates
Three tiers of plan detail, auto-selected by issue count and goal complexity. See Step 3.2 in the plan SKILL.md for selection criteria.
Minimal Template (1-2 issues, fast path)
Use for small, well-understood changes where full spec overhead is wasteful.
# Plan: <Goal>
## Issues
### Issue 1: <Title>
- **Files:** `path/to/file.go`
- **Change:** <2-3 sentences>
- **Acceptance:** <1-line test command>
- **Wave:** 1
## Verification
`<single test command>`Includes: Title, 2-line description, acceptance criteria, files list. Omits: Boundaries, design briefs, data transformation tables, cross-wave registry, file-conflict matrix.
Standard Template (3-6 issues)
Full plan format as defined in the main SKILL.md Step 6. This is the default tier for most work.
Includes:
- Context section with applied findings
- Files to Modify table
- Boundaries (Always/Ask First/Never)
- Baseline audit with verification commands
- Implementation with per-section specs
- Tests with named functions
- Conformance checks table
- Verification procedures
- Wave structure with file-conflict matrix
Deep Template (7+ issues, complex operations)
Everything in Standard, plus:
- Design briefs for any rewrite/redesign issues (Purpose, Key artifacts, Workflows)
- Data transformation mapping tables for filtering/exclusion logic (source field -> output transformation)
- Cross-wave shared file registry with collision mitigations
- Inline code blocks for all non-obvious constructs (verified compilable)
- Per-issue `metadata.files` for worker file ownership
- Homogeneous wave grouping by work type (all Go, all docs, all shell within same wave)
- Schema strictness pre-flight for JSON schema changes
Plan Skill Examples
Detailed examples of /plan usage scenarios.
---
Example 1: Plan from Research
User says: /plan "add user authentication"
What happens: 1. Agent reads recent research from .agents/research/2026-02-13-authentication-system.md 2. Explores codebase to identify integration points 3. Decomposes into 5 issues: middleware, session store, token validation, tests, docs 4. Creates epic ag-5k2 with 5 child issues in 2 waves 5. Output written to .agents/plans/2026-02-13-add-user-authentication.md
Result: Epic with dependency graph, conformance checks, and wave structure for parallel execution.
Example 2: Plan with Auto Mode
User says: /plan --auto "refactor payment module"
What happens: 1. Agent skips human approval gates 2. Searches knowledge base for refactoring patterns 3. Creates epic and child issues automatically 4. Records ratchet progress
Result: Fully autonomous plan creation with 3 waves, 8 issues, ready for /crank.
Example 3: Plan Cleanup Epic with Audit
User says: /plan "remove dead code"
What happens: 1. Agent runs quantitative audit: 3,003 LOC across 3 packages 2. Creates issues grounded in audit numbers (not vague "cleanup") 3. Each issue specifies exact files and line count reduction 4. Output includes deletion verification checks
Result: Scoped cleanup plan with measurable completion criteria (e.g., "Delete 1,500 LOC from pkg/legacy").
Example 4: Plan with Implementation Detail (Symbol-Level)
User says: /plan "add stale run detection to RPI status" (external operator loop surface)
What happens: 1. Agent explores codebase, finds classifyRunStatus at rpi_status.go:850, phasedState at rpi_phased.go:100 2. Produces file inventory: 4 files to modify, 2 new files 3. Each implementation section names exact functions, parameters, struct fields with JSON tags 4. Tests section lists TestClassifyRunStatus_StaleWorktree, TestDetermineRunLiveness_MissingWorktree with descriptions 5. Verification section provides manual simulation: create fake stale run, check the external RPI status surface output
Result: Implementer can execute the plan in a single pass without rediscovering any symbol names, reducing implementation time by ~50% and eliminating spec-divergence rework.
---
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| br create fails | Beads not initialized in repo | Run br init --prefix <prefix> first |
| Dependencies not created | Issues created without explicit br dep add calls | Verify plan output includes dependency commands. Re-run to regenerate |
| Plan too large | Research scope was too broad, resulting in >20 issues | Narrow the goal or split into multiple epics |
| Wave structure incorrect | False dependencies declared (logical ordering, not file conflicts) | Review dependency necessity: does blocked issue modify blocker's files? |
| Conformance checks missing | Acceptance criteria not mechanically verifiable | Add files_exist, content_check, tests, or command checks per validation-contract.md |
| Epic has no children | Plan created but br commands failed silently | Check br list --type epic output; re-run plan with br CLI available |
Implementation Detail Generation
Extracted from plan/SKILL.md on 2026-04-11.
Symbol-level implementation detail for every file in the plan.
After exploring the codebase, generate symbol-level implementation detail for EVERY file in the plan. This is what separates actionable specs from vague descriptions. A worker reading the plan should know exactly what to write without rediscovering function names, parameters, or code locations.
File Inventory Table
Start with a ## Files to Modify table listing EVERY file the plan touches:
## Files to Modify
| File | Change |
|------|--------|
| `src/auth/middleware.go` | Add rate limit check to `AuthMiddleware` |
| `src/config/config.go` | Add `RateLimit` section to `Config` struct |
| `src/auth/middleware_test.go` | **NEW** — rate limit middleware tests |Mark new files with **NEW**. This table gives the implementer the full blast radius in 30 seconds.
Per-Section Implementation Specs
For each logical change group, provide symbol-level detail:
1. Exact function signatures — name the function, its parameters, and what changes:
- "Add
worktreePath stringparameter toclassifyRunStatus" - "Create new
RPIConfigstruct withWorktreeMode stringfield"
2. Key functions to reuse — with file:line references from the explore step:
- "Reuse
readRunHeartbeat()atrpi_phased.go:1963" - "Call existing
parsePhasedState()atrpi_phased.go:1924"
3. Inline code blocks — for non-obvious constructs (struct definitions, CLI flags, config snippets). Verify all inline snippets compile with go build ./... before including them in issue descriptions — workers copy them verbatim:
type RPIConfig struct {
WorktreeMode string `yaml:"worktree_mode" json:"worktree_mode"`
}4. New struct fields with tags — exact field names and JSON/YAML tags
5. CLI flag definitions — exact flag names, types, defaults, and help text
Named Test Functions
For each test file, list specific test functions with one-line descriptions:
**`src/auth/middleware_test.go`** — add:
- `TestRateLimitMiddleware_UnderLimit`: Request within limit returns 200
- `TestRateLimitMiddleware_OverLimit`: Request exceeding limit returns 429
- `TestRateLimitMiddleware_ResetAfterWindow`: Counter resets after time windowTest Level Classification
For each test in the plan, classify its pyramid level per the test pyramid standard (test-pyramid.md in the standards skill):
| Test | Level | Rationale |
|---|---|---|
TestRateLimitMiddleware_UnderLimit | L1 (Unit) | Single function behavior in isolation |
TestRateLimitMiddleware_Integration | L2 (Integration) | Middleware + config store interaction |
TestRateLimitMiddleware_E2E | L3 (Component) | Full request pipeline with mocked Redis |
Include test_levels metadata in each issue's validation block:
{
"test_levels": {
"required": ["L0", "L1"],
"recommended": ["L2"],
"rationale": "Reason for level selection"
}
}Agents own L0–L3 autonomously. L4+ requires human-defined scenarios — flag these as "human gate" items in the plan.
Verification Procedures
Add a ## Verification section with runnable bash sequences that reproduce the scenario and confirm the fix:
## Verification
1. **Unit tests**: `go test ./src/auth/ -run "TestRateLimit" -v`
2. **Build check**: `go build ./...`
3. **Manual simulation**:Start server
go run ./cmd/server/ &
Hit endpoint 11 times (limit is 10)
for i in $(seq 1 11); do curl -s -o /dev/null -w "%{http_code}\n" localhost:8080/api; done
Last request should return 429
Why this matters: The golden plan pattern (file tables + symbol-level specs + verification procedures) enabled single-pass implementation of an 8-file, 5-area change with zero ambiguity. Category-level specs ("modify classifyRunStatus") force implementers to rediscover symbols, causing divergence and rework.
Data Transformation Mapping Tables (Mandatory for Filtering)
When a plan declares any struct-level filtering, exclusion, or allowlist logic:
- Create an explicit mapping table showing source field → output transformation
- Format: source name → fields affected → transformation (zeroed, renamed, computed)
Example from context orchestration (na-0v2):
| Section Name | Fields Zeroed |
|---|---|
HISTORY | Sessions |
INTEL | Learnings, Patterns |
TASK | BeadID, Predecessor |
Why: Without explicit mapping tables, workers misinterpret data transformations. In na-0v2, section→field mapping ambiguity was caught only in pre-mortem. An explicit table prevents the concern entirely.
Symbol Verification
For each function, struct, or type cited in the plan's implementation specs, grep the codebase to verify it exists:
# For each symbol referenced in the plan
grep -rn "func <symbolName>" --include="*.go" . 2>/dev/null
grep -rn "type <symbolName>" --include="*.go" . 2>/dev/null
grep -rn "class <symbolName>" --include="*.py" . 2>/dev/nullIf >20% of cited symbols are stale (not found in codebase):
- WARN with list of stale references and their plan locations
- Do NOT block — stale refs may indicate renamed symbols that workers can resolve
- Log stale refs to plan document under
## Stale Symbol Warnings
Opt-out: --skip-symbol-check flag (for greenfield plans where symbols don't yet exist).
Plan Document Template
Extracted from plan/SKILL.md on 2026-04-11.
Canonical template written to .agents/plans/YYYY-MM-DD-<goal-slug>.md at Step 6.Baseline Audit Gate (mechanical): Before writing the plan, verify the ## Baseline Audit table has at least 1 row with both a command and a result:
- If
## Baseline Auditis empty or missing: BLOCK with "Plan lacks baseline audit. Run quantitative checks first." - If any row has a command but no result (or vice versa): WARN with "Incomplete audit row — run the command and record the result."
- Opt-out:
--skip-audit-gateflag (for documentation-only plans with no quantitative claims).
---
id: plan-YYYY-MM-DD-<goal-slug>
type: plan
date: YYYY-MM-DD
source: "[[.agents/research/YYYY-MM-DD-<research-slug>]]"
intent_issue: "<path to filled-in docs/templates/intent-issue.md, or br issue id>"
---
# Plan: <Goal>
## Context
<1-2 paragraphs explaining the problem, current state, and why this change is needed. Include `Applied findings: <id, id, ...>` from `.agents/planning-rules/*.md` first, with `.agents/findings/registry.jsonl` as fallback.>
Applied findings:
- `<finding-id>` — `<how it changed the plan>`
## Intent Issue
> The upstream BDD intent issue this plan decomposes. Plan is move 3 of the [operating loop](../../docs/architecture/operating-loop.md): it consumes a [BDD intent issue](../../docs/templates/intent-issue.md) and turns its acceptance examples into vertical slices. If no intent issue exists yet, write one before planning non-trivial work.
- **Intent issue:** `<path to filled-in intent-issue.md, or br issue id>`
- **Bounded context:** `<from intent issue — the BC this work lands in>`
- **Domain terms:** `<key ubiquitous-language terms the slices use>`
Acceptance examples carried from the intent issue (one Gherkin scenario per behavior — these map 1:1 to slices below):
Feature: <feature name from intent issue>
Scenario: <happy path> Given <...> When <...> Then <...>
Scenario: <edge / failure> Given <...> When <...> Then <...>
## Files to Modify
| File | Change |
|------|--------|
| `path/to/file.go` | Description of change |
| `path/to/new_file.go` | **NEW** — description |
> **Codex parity rule:** Whenever this table includes a `skills/<name>/` path, default-include the matching `skills-codex/<name>/` path on the same row (or a paired row) and add `scripts/regen-codex-hashes.sh` to the validation step. Skipping the codex mirror produces silent parity drift caught only by CI.
## Boundaries
**Always:** <non-negotiable requirements — security, backward compat, testing, etc.>
**Ask First:** <decisions needing human input before proceeding — in auto mode, logged only>
**Never:** <explicit out-of-scope items preventing scope creep>
## Baseline Audit
| Metric | Command | Result |
|--------|---------|--------|
| <what was measured> | `<grep/wc/ls command used>` | <result> |
## Implementation
### 1. <Change Group Name>
In `path/to/file.go`:
- **Modify `functionName`**: Add `paramName Type` parameter. If `paramName != ""` and condition, return `"value"`.
- **Add `NewStruct`**:type NewStruct struct { FieldName string json:"field_name,omitempty" }
- **Key functions to reuse:**
- `existingHelper()` at `path/to/file.go:123`
- `anotherFunc()` at `path/to/other.go:456`
### 2. <Next Change Group>
<Same pattern — exact symbols, inline code, reuse references>
## Tests
**`path/to/file_test.go`** — add:
- `TestFunctionName_ScenarioA`: Input X produces output Y
- `TestFunctionName_ScenarioB`: Edge case Z handled correctly
**`path/to/new_test.go`** — **NEW**:
- `TestNewFeature_HappyPath`: Normal flow succeeds
- `TestNewFeature_ErrorCase`: Bad input returns error
## Slice Validation Plan
> Move 3 + 5 of the operating loop. One row per vertical slice — each slice covers a single Given/When/Then behavior from the Intent Issue, names a **first failing test** (TDD: write the test, watch it fail for the right reason, then implement), a disjoint write scope, the bounded context, and an owner. Full template: [`docs/templates/slice-validation.md`](../../docs/templates/slice-validation.md).
| Slice ID | Behavior under test | First failing test | Write scope | Validation lane | Owner | Acceptance example covered |
|----------|--------------------|--------------------|-------------|-----------------|-------|----------------------------|
| S1 | <single Given/When/Then behavior> | `<file:test_name>` — must fail for missing behavior, not syntax | `<files / packages this slice modifies>` | L1 unit / L2 integration / L3 e2e / property / snapshot / council | `<agent or human>` | Scenario: <name from Intent Issue> |
| S2 | … | … | … | … | … | … |
### Wave Validity
> If slices are planned to run in parallel, every row must pass. Any failed row → those slices run **sequential**. Default to sequential when in doubt.
| Check | Status | Notes |
|-------|--------|-------|
| Distinct write scopes (modified-files sets are disjoint) | [ ] | <overlapping files if any> |
| No shared migration / schema / generated file | [ ] | |
| No shared CLI surface (flags / arguments) | [ ] | |
| Integration order declared if it matters | [ ] | <named order or "n/a"> |
| Owner per slice (one agent or one human, no joint) | [ ] | |
| Discard path per slice (rollback or drop-and-re-plan) | [ ] | |
**Wave decision:** [ ] parallel [ ] sequential
### Roll-up Acceptance
> The bead closes only when every acceptance example from the Intent Issue has a passing test linked to it. Activity logs do not close beads. This is the behavior layer; the machine-checkable layer is the Conformance Checks table below — keep both.
| Acceptance example from Intent Issue | Slice(s) that cover it | Passing-test evidence | Status |
|---------------------------------------|------------------------|------------------------|--------|
| Scenario: <happy path name> | S1 | `<file:test_name>` — green at `<git sha>` | [ ] |
| Scenario: <edge name> | S2 | `<file:test_name>` — green at `<git sha>` | [ ] |
## Conformance Checks
> Machine-checkable acceptance layer. Gherkin in the Roll-up Acceptance table is the behavior layer; this table stays the mechanically verified gate — do not replace it with Gherkin prose.
| Issue | Check Type | Check |
|-------|-----------|-------|
| Issue 1 | content_check | `{file: "src/auth.go", pattern: "func Authenticate"}` |
| Issue 1 | tests | `go test ./src/auth/...` |
| Issue 2 | files_exist | `["docs/api-v2.md"]` |
## Verification
1. **Unit tests**: `go test ./path/to/ -run "TestFoo" -v`
2. **Full suite**: `go test ./... -short -timeout 120s`
3. **Manual simulation**:Create test scenario
mkdir -p .test/data echo '{"key": "value"}' > .test/data/input.json
Run the tool
./bin/tool --flag value
Verify expected output
cat .test/data/output.json # Should show "result"
## Issues
### Issue 1: <Title>
**Dependencies:** None
**Acceptance:** <how to verify>
**Description:** <what to do — reference Implementation section for symbol-level detail>
### Issue 2: <Title>
**Dependencies:** Issue 1
**Acceptance:** <how to verify>
**Description:** <what to do>
## Execution Order
**Wave 1** (parallel): Issue 1, Issue 3
**Wave 2** (after Wave 1): Issue 2, Issue 4
**Wave 3** (after Wave 2): Issue 5
## Planning Rules Compliance
| Rule | Status | Justification |
|------|--------|---------------|
| PR-001: Mechanical Enforcement | PASS / N-A | [justification] |
| PR-002: External Validation | PASS / N-A | [justification] |
| PR-003: Feedback Loops | PASS / N-A | [justification] |
| PR-004: Separation Over Layering | PASS / N-A | [justification] |
| PR-005: Process Gates First | PASS / N-A | [justification] |
| PR-006: Cross-Layer Consistency | PASS / N-A | [justification] |
| PR-007: Phased Rollout | PASS / N-A | [justification] |
Unchecked rules: 0
## Post-Merge Cleanup
After bulk-merging wave results, audit for scaffold-era names:
- Rename placeholder function/variable names (e.g., `handleThing`, `processItem`) to domain-specific names
- Search with `grep -rn 'TODO\|FIXME\|HACK\|XXX' <modified-files>` for deferred cleanup markers
- If any `skills/` files were modified, run `scripts/regen-codex-hashes.sh` to sync codex parity and copy reference files.
## Next Steps
- Run `/pre-mortem` to validate plan
- Run `/crank` for autonomous execution
- Or `/implement <issue>` for single issuePlan Mutation Protocol
Structured mid-execution plan changes with audit trail. Plans are living documents, not contracts.
Problem
During /crank execution, plans often need modification:
- A task turns out to be more complex than estimated (needs splitting)
- A dependency is discovered mid-implementation (needs reordering)
- A task becomes unnecessary after another task completes (needs skipping)
- An overlooked concern surfaces during a wave (needs insertion)
Without a mutation protocol, these changes happen ad-hoc with no audit trail.
Mutation Operations
Split
Break one task into two or more sub-tasks.
mutation:
type: split
original_task: "ag-123: Add auth middleware"
new_tasks:
- "ag-123a: Add JWT validation middleware"
- "ag-123b: Add session store integration"
reason: "Task too large for single worker; JWT and session concerns are independent"
wave: 3
timestamp: "2026-03-21T10:15:00Z"Insert
Add a new task that wasn't in the original plan.
mutation:
type: insert
new_task: "ag-124: Add rate limiting to auth endpoints"
after: "ag-123"
reason: "Security review identified missing rate limiting; must be added before auth goes live"
wave: 3
timestamp: "2026-03-21T10:20:00Z"Skip
Mark a task as unnecessary without deleting it.
mutation:
type: skip
task: "ag-125: Migrate legacy auth tokens"
reason: "Legacy token support removed in ag-120; no tokens to migrate"
wave: 4
timestamp: "2026-03-21T11:00:00Z"Reorder
Change task execution order or wave assignment.
mutation:
type: reorder
task: "ag-126: Update API docs"
from_wave: 5
to_wave: 3
reason: "API docs needed by frontend team before wave 5; moving earlier"
wave: 3
timestamp: "2026-03-21T10:30:00Z"Abandon
Stop working on a plan entirely. Requires justification.
mutation:
type: abandon
reason: "Requirements changed; stakeholder redirected to different approach"
wave: 2
timestamp: "2026-03-21T09:45:00Z"Audit Trail
All mutations are logged to .agents/plans/<epic-id>-mutations.jsonl:
{"type":"split","original":"ag-123","new":["ag-123a","ag-123b"],"reason":"...","wave":3,"ts":"2026-03-21T10:15:00Z"}
{"type":"insert","task":"ag-124","after":"ag-123","reason":"...","wave":3,"ts":"2026-03-21T10:20:00Z"}
{"type":"skip","task":"ag-125","reason":"...","wave":4,"ts":"2026-03-21T11:00:00Z"}One line per mutation, append-only (JSONL format for streaming reads).
Integration with /crank
When to Mutate
Crank's orchestrator decides to mutate when:
1. Worker failure classified as DECOMPOSE → trigger split mutation 2. Cross-wave dependency discovered → trigger reorder mutation 3. Task validation reveals new requirement → trigger insert mutation 4. Task made unnecessary by prior wave → trigger skip mutation
Mutation Budget
- Splits: Unlimited (decomposition is healthy)
- Inserts: Max 5 per epic (prevents scope creep)
- Skips: Unlimited (pruning is healthy)
- Reorders: Max 3 per epic (excessive reordering = bad initial plan)
- Abandon: 1 (terminal)
If insert budget exceeded: log warning and suggest /plan re-run instead.
Crank Checkpoint Integration
After any mutation, write to the wave checkpoint:
{
"mutations_this_wave": [
{"type": "split", "task": "ag-123", "reason": "..."}
],
"total_mutations": 3
}Integration with /plan
Adversarial Review Gate
Before finalizing a plan, optionally spawn a reviewer (strongest available model) to check:
1. Completeness: Are all acceptance criteria covered by tasks? 2. Dependencies: Are task dependencies correctly ordered? 3. Anti-patterns: Does the plan contain known failure patterns?
- Circular dependencies
- Tasks too large for single worker (>200 lines estimated)
- Missing test tasks for implementation tasks
- Config/infrastructure tasks in wrong wave position
4. Parallelization: Are independent tasks assigned to the same wave?
The reviewer produces a findings list. Critical findings block plan finalization; WARN findings are logged.
Integration with /post-mortem
Post-mortem should read the mutation log to assess plan quality:
- High mutation count → plan was underspecified
- Many splits → tasks were too coarse
- Many inserts → requirements were unclear
- Mutations clustered in early waves → research was insufficient
Include mutation summary in post-mortem report.
Self-Contained Step Context
Every task in a plan should include enough context for a cold-start worker:
### Task: ag-123 — Add JWT validation middleware
**Context:** This is part of the auth system refactor (epic ag-100).
The API currently accepts any request without auth checks.
After this task, all `/api/*` endpoints require a valid JWT.
**Dependencies:** ag-121 (JWT signing key in config) must be complete.
**Acceptance Criteria:**
1. Middleware validates JWT on all /api/* routes
2. Returns 401 for missing/invalid tokens
3. Passes user context to downstream handlers
4. Tests cover: valid token, expired token, malformed token, missing token
**File Scope:** `internal/middleware/auth.go`, `internal/middleware/auth_test.go`
**Verification:** `go test ./internal/middleware/ -run TestAuth -v`A fresh agent should be able to execute this task without reading the full plan.
Plan To Beads Workflow
Use this reference when a prose plan, design note, or research artifact needs to become executable br work.
Conversion Loop
1. Identify the smallest independently verifiable outcomes. 2. Create one br issue per outcome, not per file and not per vague phase. 3. Add dependency edges for true sequencing only. 4. Put validation commands and expected artifacts in each issue body. 5. Add parent-child links for epics and broad follow-up work. 6. Re-read br ready --json after creation and fix any issue that is not actionable.
Issue Quality Bar
Each created issue must answer:
- What files or surfaces are probably in scope?
- What behavior changes when this closes?
- How will the implementer prove it?
- What can be skipped without invalidating the outcome?
- What existing parent, research, or plan discovered it?
Polish Pass
Run a final pass over the issue graph before handing to /crank:
| Check | Failure |
|---|---|
| Ready issues have acceptance criteria | Worker will rediscover scope. |
| Dependencies are minimal | Parallelism collapses. |
| Broad parents have children | Parent wording becomes implementation scope. |
| Validation blocks name commands | Closeout becomes subjective. |
---
Source: Adapted from an external skill corpus / beads-workflow. Pattern-only, no verbatim text.
# Executable spec for the /plan skill — vertical-slice decomposition (BC3 Loop).
# /plan consumes dense BDD intent (Discovery output, a bead, or research artifact)
# on the `plan_slices` inbound port and produces a slice-validation plan: one slice
# per Given/When/Then row, each with a first-failing-test target, write scope,
# bounded context, and ownership. Slices group into a wave only when the
# wave-validity check passes. Hexagon: domain; consumes: standards;
# produces: .agents/plans/*.md + execution-packet.json. (soc-qk4b.2)
Feature: Plan converts dense intent into executable slices
As the loop's decomposition step
I want dense intent turned into self-contained, validated slices
So that implementation runs from the plan alone, never from raw chat context
Scenario: Plan consumes Discovery output
Given Discovery provides density fields and artifact links
When Plan receives the `plan_slices` port request
Then each slice has acceptance criteria, write scope, test levels, and ownership
And no slice depends on raw Discovery chat context
Scenario: One slice per Given/When/Then row
Given a BDD intent issue with N Given/When/Then rows
When Plan decomposes it
Then it emits N vertical slices, each with a first-failing-test target
Scenario: Wave-validity gate before parallelization
Given a set of candidate slices
When Plan groups them into a wave
Then the wave passes only if every row holds: distinct write scopes, no shared
migration/contract/CLI surface, a declared integration order, an owner per slice,
and a discard path per slice
And slices default to sequential when any row fails
Scenario: Plan produces a durable slice-validation artifact
Then Plan writes a slice plan to .agents/plans/*.md and an execution-packet.json
And a fresh agent can execute the slices from those artifacts alone
# Gherkin acceptance is emitted by default — the operator never hand-specifies BDD (ag-9jle.2).
Scenario: Every emitted bead carries a Gherkin Scenarios block by default
Given Plan decomposing a goal into beads
When a bead is created without the operator asking for BDD
Then the bead body carries an embedded ## Scenarios (Given/When/Then) block
And it never ships free-text-only acceptance
And the ## Scenarios block sits above the acceptance_criteria YAML as the behavior layer
Seven Compiled Planning Rules
Extracted from 14,753 production sessions, 544,906 messages, 946 council verdicts (124 FAILs analyzed).
These rules are the top cross-cutting failure patterns — each prevented by a specific planning discipline.
How to Use
During plan creation (Step 2), evaluate each issue and wave against all 7 rules. For each rule, ask the Detection Question. If the answer is "no" or "unclear," add a mitigation to the plan before proceeding.
---
PR-001: Mechanical Enforcement
Rule: Every silent-failure risk needs a gate (test, lint, or validation) that mechanically prevents it. Plans must not rely on human vigilance for correctness.
Evidence: ArgoCD CMP timeout mismatch caused cache poisoning with no gate to enforce alignment. K8s status subresource omission caused invisible data loss. SSH parameter parity failures in retry paths silently diverged.
Detection Question: Does every integration point, timeout, and configuration boundary have a mechanical validation gate?
Checklist Item: Each external dependency and configuration boundary has an automated conformance check (test, lint rule, or CI gate).
---
PR-002: External Validation
Rule: Success criteria must be external and measurable. Workers must not declare their own work complete — external gates (tests, validators, reviewers) must confirm.
Evidence: Ralph Loop uses test gates, not agent declarations. Zero-context smoke tests find 3–5x more issues than self-review. Unit tests found zero bugs in production; L3+ testing (integration, E2E) found all real bugs.
Detection Question: Does the plan use external validation gates (test commands, CI checks) rather than self-reported completion?
Checklist Item: Every task has a runnable validation command — no "verify manually" acceptance criteria.
---
PR-003: Feedback Loops
Rule: Any system that captures knowledge without a citation/reuse mechanism is a cemetery. Plans must include how outputs will be consumed, not just produced.
Evidence: Knowledge flywheel formula: velocity (σ) × reuse (ρ) must exceed decay (δ). Platform-lab flywheel decaying at σ=0.02 — producing artifacts nobody consumes. Four-surface closure requires capture → index → retrieval → application.
Detection Question: Does the plan close the feedback loop — who consumes the output, how is it cited, and what triggers reuse?
Checklist Item: Each output artifact has a named consumer and a defined consumption mechanism.
---
PR-004: Separation Over Layering
Rule: Organize components around clear contracts and boundaries, not hierarchical layers. Each component should have a single, unambiguous responsibility.
Evidence: OpenClaw succeeds with horizontal separation (SOUL/AGENTS/IDENTITY own contracts completely). ArgoCD sync waves enforce ordering without external tooling. Prior attempts at adding a third layer with fuzzy boundaries produced unclear ownership and bugs at every seam.
Detection Question: Does the plan add layers or separate concerns? Are boundaries between components explicit contracts?
Checklist Item: Each new component has a defined contract (input/output/error) specified before implementation begins.
---
PR-005: Process Gates First
Rule: When execution is failing, fix the process first. Model/tool improvements compound only after process is stable.
Evidence: 6,367 execution failures solved by process gates, not model upgrades. Pre-worktree sync prevents 82.6/1K git conflicts. Standards guides loaded upfront prevent 13+ violations per session.
Detection Question: Is the plan proposing a tool/model change when a process gate would solve the problem?
Checklist Item: Existing process gates are verified as in place and enforced before any new tool or model change is proposed.
---
PR-006: Cross-Layer Consistency
Rule: Distributed systems fail when adjacent layers have different assumptions. Enforce consistency explicitly at every boundary.
Evidence: ArgoCD 3-layer timeout stack (CMP, repo-server, application) that disagrees causes silent cache poisoning. SSH parameter forwarding through retry paths — primary and retry must carry identical parameters. Plan/tracker/artifacts must stay in lockstep.
Detection Question: Does the plan verify configuration consistency across all layers it touches (timeouts, parameters, schemas)?
Checklist Item: A consistency check verifies all layers agree on shared parameters (timeouts, schemas, feature flags, env vars).
---
PR-007: Phased Rollout
Rule: Big changes decompose into low-risk immediate wins + moderate-risk follow-ups. Ship the cheap wins first.
Evidence: ArgoCD fix order: CMP timeout (low-risk) → replicas (moderate) → Redis HA (evaluate). Swarm gates: Week 1 (sync) → Week 2 (ship gate) → Week 3 (role split) → Week 4 (closeout). Bootstrap: infrastructure → core → applications via sync waves.
Detection Question: Is the plan deploying everything at once, or is it phased with risk isolation between waves?
Checklist Item: Changes are ordered into waves by risk level, with Wave 1 being the safest and most reversible.
---
PR-008: Pre-Decomposition Symbol Verify
Rule: Plans that touch code with deletion patches in the last 30 days must symbol-verify every named function, type, file, and import path against current HEAD before decomposition. Stale inventory silently invalidates wave acceptance criteria.
Evidence: agentops-zm8 was the 5th inventory-vs-reality drift strike in 24 hours — the plan named symbols (functions, helpers, type identifiers) that had been deleted in recent commits. Decomposition assumed they existed; Wave 1 workers couldn't find the symbol and the wave failed mid-cycle. Pattern: plan author scanned an older snapshot or stale doc, not HEAD.
Detection Question: Does the plan touch a region with deletions in git log --since='30 days ago' --diff-filter=D --name-only? If yes, has every symbol named in the plan been grep-verified against HEAD?
Checklist Item: For deletion-adjacent plans, run git log --since='30 days ago' --diff-filter=D --name-only to identify the touched region, then grep -rn '<symbol>' <region> for each named symbol before Wave 1. Plans where any named symbol grep returns zero hits are rejected back to research.
---
PR-009: Mechanical Count Verification
Rule: Plans that claim a count ("there are 47 commands", "12 hooks fail", "this affects 3 packages") must back the claim with a runnable command in the plan body. Hand-counts in agent-generated plans drift; mechanical counts catch the drift at plan time.
Evidence: Agent-generated docs have shipped numeric claims that didn't match reality — function counts, job counts, hook counts off by 5–30%. Reviewers couldn't distinguish "fact" from "rounded estimate" because no command was attached. Once the count was verified mechanically, the plan claim was either right or had to be corrected.
Detection Question: Does every numeric claim in the plan have a command + result pair in the Baseline Audit table or inline in the section?
Checklist Item: For each numeric assertion, include the producing command:
- counts of commands →
ao --help | extract_commands | wc -l - counts of files →
git ls-files | grep -c <pattern> - counts of test functions →
grep -rn "^func Test" <pkg>/ | wc -l - counts of br issues →
br list --status=open --json | jq length
Plans where any numeric claim has no producing command are rejected back to research.
---
Quick-Reference Checklist
Use this during plan review:
| # | Rule | Detection Question |
|---|---|---|
| 1 | Mechanical Enforcement | Does every integration point have a mechanical gate? |
| 1b | Mechanical Enforcement | Does the plan include activation tests for any provisioned infrastructure? (Dead infrastructure = provisioned but never tested under real load) |
| 2 | External Validation | Are all validation gates external (not self-reported)? |
| 3 | Feedback Loops | Who consumes each output, and how? |
| 3b | Feedback Loops | Does the plan specify who consumes each output artifact? (Capture without consumption is a knowledge cemetery) |
| 4 | Separation Over Layering | Are component boundaries explicit contracts? |
| 5 | Process Gates First | Could a process gate solve this instead of a tool change? |
| 5b | Process Gates First | Does the plan enforce commit-per-wave and worktree-commit-before-exit? (Branch hygiene prevents merge conflict accumulation) |
| 6 | Cross-Layer Consistency | Do all layers agree on shared parameters? |
| 7 | Phased Rollout | Are changes phased by risk with validation between waves? |
| 7b | Phased Rollout | Is the 40% context budget respected? (Sessions that load >40% context for knowledge leave insufficient room for implementation work) |
| 8 | Pre-Decomposition Symbol Verify | Are all named symbols grep-verified against current HEAD before decomposition? (Required for plans touching deletion-adjacent code in the last 30 days) |
| 9 | Mechanical Count Verification | Does every numeric claim have a producing command in the plan? (Hand-counts in agent-generated plans drift; counts must be reproducible by reviewers) |
Pre-Decomposition Steps
Extracted from plan/SKILL.md on 2026-04-11.
Knowledge flywheel search, compiled prevention loading, research validation, explore-agent dispatch, baseline audit.
Step 2 Expansion: Knowledge Flywheel Search
Look for existing research on this topic:
ls -la .agents/research/ 2>/dev/null | head -10Use Grep to search .agents/ for related content. If research exists, read it with the Read tool to understand the context before planning.
Search knowledge flywheel for prior planning patterns:
if command -v ao &>/dev/null; then
ao search "<topic> plan decomposition patterns" 2>/dev/null | head -10
# Decision-point pull: prefer the curated GOLD wiki with compact pointers
# (no bodies) and a hard top-K cap — bookend-bounded (ADR-0002: never spray
# full corpus bodies into context). Fall back to the raw .agents/ corpus, but
# WARN loudly so a missing gold wiki is never a silent zero-result.
if [ -d .ao/wiki ]; then
ao lookup --query "<goal>" --gold --pointers --limit 3 2>/dev/null | head -20
else
echo "WARN: gold wiki (.ao/wiki) absent — run 'ao wiki gold' to enable gold retrieval; falling back to raw .agents/ corpus" >&2
ao lookup --query "<goal>" --limit 3 2>/dev/null | head -20
fi
fiApply retrieved knowledge (mandatory when results returned):
If ao returns relevant learnings or patterns, do NOT just load them as passive context. For each returned item: 1. Check: does this learning apply to the current planning goal? (answer yes/no) 2. If yes: incorporate as a planning constraint — does it warn about scope? suggest decomposition? flag a known pitfall? 3. Cite applicable learnings by filename when they influence a planning decision
After reviewing, record each citation with the correct type:
# Only use "applied" when the learning actually influenced your output.
# Use "retrieved" for items that were loaded but not referenced in your work.
ao metrics cite "<learning-path>" --type applied 2>/dev/null || true # influenced a decision
ao metrics cite "<learning-path>" --type retrieved 2>/dev/null || true # loaded but not usedSection evidence: When lookup results include section_heading, matched_snippet, or match_confidence fields, prefer the matched section over the whole file. Higher match_confidence (>0.7) is a strong match; <0.4 is weak. Use matched_snippet as primary context rather than reading the full file.
Skip silently if ao is unavailable or returns no results.
Step 2.1 Expansion: Load Compiled Prevention First (Mandatory)
Before decomposition, load compiled planning rules from .agents/planning-rules/*.md when they exist. This is the primary prevention surface for /plan in the compiler-enabled flow.
Use the tracked contracts in docs/contracts/finding-compiler.md and docs/contracts/finding-registry.md:
- prefer compiled planning rules first
- match by finding ID,
applicable_whenoverlap, language overlap, and literal goal-text overlap - when file inventory is known, rank by changed-file overlap before falling back to weaker textual matches
- cap the injected set at top 5 findings / rule files
- if compiled planning rules are missing, incomplete, or fewer than the matched finding set, fall back to
.agents/findings/registry.jsonl - fail open: missing/empty directory → skip silently; malformed line → warn and ignore; unreadable file → warn once and continue
Use the selected planning rules / active findings as hard planning context before issue decomposition. Record the applied finding IDs and how they changed the plan.
Ranked packet contract: Treat compiled planning rules, active findings, and matching high-severity next-work.jsonl items as one ranked packet, not three unrelated lookups. Rank by: (1) literal goal-text overlap, (2) applicable_when / issue-type overlap, (3) language overlap, (4) changed-file overlap, (5) backlog severity / repo affinity for next-work items.
Step 2.2 Expansion: Read and Validate Research Content
If research files exist, read the most recent one and verify it contains substantive findings before proceeding:
LATEST_RESEARCH=$(ls -t .agents/research/*.md 2>/dev/null | head -1)
if [ -n "$LATEST_RESEARCH" ]; then
if grep -qE '^## (Summary|Key Files|Findings|Key Findings|Architecture|Executive Summary|Recommendations|Part [0-9])' "$LATEST_RESEARCH"; then
echo "Research validated: $LATEST_RESEARCH"
else
echo "WARNING: Research file exists but lacks standard sections. Consider /research first."
fi
fiRead the validated research file with the Read tool before proceeding to Step 3. Do not plan based solely on file existence.
Step 3 Expansion: Explore the Codebase (if needed)
USE THE TASK TOOL to dispatch an Explore agent. The explore prompt MUST request symbol-level detail:
Tool: Task
Parameters:
subagent_type: "Explore"
description: "Understand codebase for: <goal>"
prompt: |
Explore the codebase to understand what's needed for: <goal>
1. Find relevant files and modules
2. Understand current architecture
3. Identify what needs to change
For EACH file that needs modification, return:
- Exact function/method signatures that need changes
- Struct/type definitions that need new fields
- Key functions to reuse (with file:line references)
- Existing test file locations and naming conventions (e.g., TestFoo_Bar)
- Import paths and package relationships
Return: file inventory, per-file symbol details, reuse points with line numbers, test patternsPre-Planning Baseline Audit (Mandatory)
Before decomposing into issues, run a quantitative baseline audit to ground the plan in verified numbers. This is mandatory for ALL plans. Any plan that makes quantitative claims (counts, sizes, coverage) must verify them mechanically.
Run grep/wc/ls commands to count the current state of what you're changing:
- Files to change: count with
ls/find/wc -l - Sections to add/remove: count with
grep -l/grep -L - Code to modify: count LOC, packages, import references
- Coverage gaps: count missing items with
grep -Lorfind
Record the verification commands alongside their results. These become pre-mortem evidence and acceptance criteria.
| Bad | Good |
|---|---|
| "14 missing refs/" | "14 missing refs/ (verified: `ls -d skills/*/references/ \ |
| "clean up dead code" | "Delete 3,003 LOC across 3 packages (verified: `find src/old -name '*.go' \ |
| "update stale docs" | "Rewrite 4 specs (verified: `ls docs/specs/*.md \ |
| "add missing sections" | "Add Examples to 27 skills (verified: `grep -L '## Examples' skills/*/SKILL.md \ |
- File size limits: check
wc -lon files near size limits (especially SKILL.md files with the 800-line lint limit). If a planned change will push a file past the limit, split or refactor before implementation. - Test fixtures affected: count test fixtures upstream of any filter/gate/hook being added or modified with
grep -rn 'func Test' <test-dir>/ | wc -l. Changing a gate without updating its test fixtures causes false-green CI.
Ground truth with numbers prevents scope creep and makes completion verifiable. In ol-571, the audit found 5,752 LOC to remove — without it, the plan would have been vague. In ag-dnu, wrong counts (11 vs 14, 0 vs 7) caused a pre-mortem FAIL that a simple grep audit would have prevented.
SDD Patterns — Boundaries and Conformance Checks
Reference doc for /plan. Loaded JIT when agents need examples.
What Are Boundaries?
Boundaries define the scope of a plan using three tiers:
| Tier | Purpose | Example |
|---|---|---|
| Always | Non-negotiable constraints applied to every issue | "All endpoints require auth middleware" |
| Ask First | Decisions requiring human input before proceeding | "Which rate limit values to use?" |
| Never | Explicit out-of-scope items preventing scope creep | "No new database tables" |
Always boundaries become cross-cutting constraints — /crank injects them into every worker task's validation metadata. Ask First boundaries are logged in auto mode and prompted in interactive mode. Never boundaries are guardrails for workers and pre-mortem judges.
What Are Conformance Checks?
Conformance checks are mechanically verifiable assertions derived from acceptance criteria. They bridge the gap between "what success looks like" (prose) and "how to verify it" (automation).
The derivation chain:
Acceptance Criteria (prose) → Conformance Check (validation-contract.md type) → Worker Validation MetadataEach check uses one of the validation-contract.md types:
| Type | Use When | Example |
|---|---|---|
files_exist | Task creates new files | ["src/auth/middleware.go", "tests/auth_test.go"] |
content_check | Task implements specific functions/patterns | {file: "src/auth.go", pattern: "func Authenticate"} |
command | Task produces verifiable runtime behavior | "go build ./..." |
tests | Task has associated tests | "go test ./src/auth/..." |
lint | Task must maintain code quality | "ruff check src/" |
Rules:
- Every acceptance criterion MUST have at least one conformance check
- Prefer
content_checkandfiles_exist(fast, deterministic) overcommand(environment-dependent) - If an acceptance criterion can't be mechanically verified, it's underspecified — rewrite it
Example 1: API Feature — "Add Rate Limiting"
Boundaries
Always:
- Backward compatible — existing endpoints continue to work without rate limit headers
- All rate-limited endpoints require auth middleware
- Tests cover both under-limit and over-limit cases
Ask First:
- Rate limit values (requests per minute) — depends on infrastructure capacity
- Whether to rate-limit internal service-to-service calls
Never:
- Rate limiting on health check endpoints (
/healthz,/readyz) - Custom rate limit configuration per user (that's a separate feature)
Conformance Checks
| Issue | Check Type | Check |
|---|---|---|
| Add rate limit middleware | content_check | {file: "src/middleware/ratelimit.go", pattern: "func RateLimitMiddleware"} |
| Add rate limit middleware | tests | go test ./src/middleware/... |
| Add rate limit middleware | content_check | {file: "src/middleware/ratelimit.go", pattern: "X-RateLimit-Remaining"} |
| Wire middleware to routes | content_check | {file: "src/routes/api.go", pattern: "RateLimitMiddleware"} |
| Wire middleware to routes | command | go build ./... |
| Add rate limit tests | files_exist | ["tests/ratelimit_test.go"] |
| Add rate limit tests | tests | go test ./tests/ratelimit_test.go -v |
Cross-Cutting Constraints (from "Always")
[
{"name": "auth-required", "type": "content_check", "file": "src/routes/api.go", "pattern": "AuthMiddleware"},
{"name": "builds-clean", "type": "command", "command": "go build ./..."},
{"name": "tests-pass", "type": "tests", "command": "go test ./..."}
]Example 2: Refactoring — "Extract Shared Library"
Boundaries
Always:
- No behavior change — all existing tests must pass before and after
- Extracted functions maintain the same signatures
- No new dependencies added
Ask First:
- Package naming conventions (e.g.,
pkg/sharedvsinternal/common) - Whether to add godoc comments during extraction
Never:
- New features or behavior changes during extraction
- Refactoring unrelated code "while we're at it"
Conformance Checks
| Issue | Check Type | Check |
|---|---|---|
| Create shared package | files_exist | ["pkg/shared/helpers.go"] |
| Create shared package | content_check | {file: "pkg/shared/helpers.go", pattern: "package shared"} |
| Move functions to shared | content_check | {file: "pkg/shared/helpers.go", pattern: "func ParseConfig"} |
| Move functions to shared | content_check | {file: "pkg/shared/helpers.go", pattern: "func ValidateInput"} |
| Update imports in callers | command | go build ./... |
| Update imports in callers | tests | go test ./... |
| Remove duplicates from source | command | ! grep -r 'func ParseConfig' src/old/ 2>/dev/null |
Cross-Cutting Constraints
[
{"name": "tests-unchanged", "type": "tests", "command": "go test ./..."},
{"name": "no-new-deps", "type": "command", "command": "go mod tidy && git diff --exit-code go.mod"}
]Example 3: Documentation — "Rewrite API Docs"
Boundaries
Always:
- All public endpoints documented
- Each endpoint has request/response examples
- Links to source code reference valid files
Ask First:
- Whether to include curl examples or SDK examples
- Documentation framework (plain markdown vs generated)
Never:
- Implementation details or internal architecture
- Auto-generated API reference (that's a separate tool)
Conformance Checks
| Issue | Check Type | Check |
|---|---|---|
| Write endpoint docs | files_exist | ["docs/api/endpoints.md"] |
| Write endpoint docs | content_check | {file: "docs/api/endpoints.md", pattern: "## GET /api/users"} |
| Write endpoint docs | content_check | {file: "docs/api/endpoints.md", pattern: "## POST /api/users"} |
| Write auth docs | files_exist | ["docs/api/authentication.md"] |
| Write auth docs | content_check | {file: "docs/api/authentication.md", pattern: "Authorization: Bearer"} |
| Add examples | content_check | {file: "docs/api/endpoints.md", pattern: "### Example"} |
| Validate links | command | ./scripts/check-doc-links.sh docs/api/ |
Cross-Cutting Constraints
[
{"name": "all-endpoints-covered", "type": "content_check", "file": "docs/api/endpoints.md", "pattern": "## (GET|POST|PUT|DELETE)"},
{"name": "examples-present", "type": "content_check", "file": "docs/api/endpoints.md", "pattern": "### Example"}
]Example 4: Implementation Detail — "Add Stale Run Detection"
This example demonstrates symbol-level implementation detail — the key differentiator between vague plans and actionable specs.
Files to Modify
| File | Change |
|---|---|
cli/cmd/ao/rpi_status.go | Add worktree check to classifyRunStatus, add Reason field to rpiRunInfo |
cli/cmd/ao/rpi_cleanup.go | Historical — superseded by ADR-0009; use retained worktree/registry cleanup surfaces instead |
cli/cmd/ao/rpi_phased.go | Add terminal metadata fields to phasedState |
cli/internal/config/config.go | Add RPIConfig with WorktreeMode |
Implementation (Symbol-Level)
1. Stale Run Detection in rpi_status.go
- Modify `classifyRunStatus`: Add check for
state.TerminalStatus != ""— return it directly. Add check forstate.WorktreePath != ""withos.Stat()— if directory gone, return"stale".
- Add `Reason` field to `rpiRunInfo`:
Reason string `json:"reason,omitempty"` // why a run is stale/failed- Modify `determineRunLiveness`: If
state.WorktreePath != ""andos.Stat(state.WorktreePath)fails, short-circuit toreturn false, hbwithout probing tmux.
- Key functions to reuse:
readRunHeartbeat()atrpi_phased.go:1963checkTmuxSessionAlive()atrpi_status.go:896parsePhasedState()atrpi_phased.go:1924
2. Terminal Metadata in rpi_phased.go
- Add fields to `phasedState`:
TerminalStatus string `json:"terminal_status,omitempty"` // interrupted, failed, stale, completed
TerminalReason string `json:"terminal_reason,omitempty"`
TerminatedAt string `json:"terminated_at,omitempty"`Tests (Named Functions)
`cli/cmd/ao/rpi_status_test.go` — add:
TestClassifyRunStatus_StaleWorktree: Run withworktree_pathpointing to nonexistent dir → status "stale"TestClassifyRunStatus_TerminalMetadata: Run withterminal_statusset → uses that status directlyTestDetermineRunLiveness_MissingWorktree: Worktree path gone → not active
`cli/cmd/ao/rpi_cleanup_test.go` — NEW:
TestCleanupStaleRun: Create stale registry entry, run cleanup, verify terminal metadata writtenTestCleanupActiveRunUntouched: Create active (fresh heartbeat) entry, verify unchangedTestCleanupDryRun: Dry-run produces output but doesn't modify state
Verification
1. Unit tests: cd cli && go test ./cmd/ao/ -run "TestClassifyRunStatus|TestCleanup" -v 2. Manual stale simulation:
mkdir -p .agents/rpi/runs/fakestale
echo '{"schema_version":1,"run_id":"fakestale","phase":2,"worktree_path":"/nonexistent"}' \
> .agents/rpi/runs/fakestale/phased-state.json
ao worktree gc --dry-run # Preview stale managed worktrees
ao worktree gc # Clean stale managed worktrees
ao worktree gc --dry-run # Confirm no stale worktrees remainWhy This Format Works
Compared to a category-level spec like "Add stale worktree detection to classifyRunStatus", the implementation detail above tells the worker:
- The exact parameter name (
state.TerminalStatus) - The exact condition (
os.Stat(state.WorktreePath)fails) - The exact return value (
"stale") - Where to find existing code (
readRunHeartbeat()atrpi_phased.go:1963) - What to name tests (
TestClassifyRunStatus_StaleWorktree) - How to verify manually (create fake stale run, check output)
This enabled single-pass implementation of an 8-file change with zero spec-divergence.
Cross-Cutting Constraints: How They Work
"Always" boundaries become cross-cutting constraints that /crank injects into every worker task:
Plan "Always" boundaries
↓
/crank reads plan → extracts Always
↓
Converts to validation-contract.md checks (flat array):
[{"name": "...", "type": "content_check|command|tests|...", ...fields...}]
↓
Injected into every TaskCreate's metadata.validation.cross_cutting
↓
Workers validated against per-task checks + cross-cutting checksSchema: Each cross-cutting check is a flat object with:
name(string): Human-readable labeltype(string): One offiles_exist,content_check,command,tests,lint- Remaining fields: Same as the corresponding validation-contract.md type
This keeps the schema flat and consistent with existing validation types — no nested meta-types.
Task Creation and Validation Blocks
Extracted from plan/SKILL.md on 2026-04-11.
Covers TaskCreate + beads issue creation, validation-block embedding, post-creation verification.
Step 7: Create Tasks for In-Session Tracking
Use TaskCreate tool for each issue:
Tool: TaskCreate
Parameters:
subject: "<issue title>"
description: |
<Full description including:>
- What to do
- Acceptance criteria
- Dependencies: [list task IDs that must complete first]
activeForm: "<-ing verb form of the task>"After creating all tasks, set up dependencies:
Tool: TaskUpdate
Parameters:
taskId: "<task-id>"
addBlockedBy: ["<dependency-task-id>"]Create Persistent Beads Issues for Ratchet Tracking
If br CLI available, create beads issues to enable progress tracking across sessions:
# Create epic first
br create --title "<goal>" --type epic --label "planned"
# Create child issues (note the IDs returned)
br create --title "<wave-1-task>" --body "<description>" --parent <epic-id> --label "planned"
# Returns: na-0001
br create --title "<wave-2-task-depends-on-wave-1>" --body "<description>" --parent <epic-id> --label "planned"
# Returns: na-0002
# Add blocking dependencies to form waves
br dep add na-0001 na-0002
# Now na-0002 is blocked by na-0001 → Wave 2Include Conformance Checks in Issue Bodies
When creating beads issues, embed the conformance checks from the plan as a fenced validation block in the issue description. This flows to worker validation metadata via /crank:
```` br create --title "<task>" --body "Description...
\\\validation {\"files_exist\": [\"src/auth.go\"], \"content_check\": {\"file\": \"src/auth.go\", \"pattern\": \"func Authenticate\"}} \\\ " --parent <epic-id> ````
Include Cross-Cutting Constraints in Epic Description
"Always" boundaries from the plan should be added to the epic's description as a ## Cross-Cutting Constraints section. /crank reads these from the epic (not per-issue) and injects them into every worker task's validation metadata.
Waves Are Formed by blocks Dependencies
- Issues with NO blockers → Wave 1 (appear in
br readyimmediately) - Issues blocked by Wave 1 → Wave 2 (appear when Wave 1 closes)
- Issues blocked by Wave 2 → Wave 3 (appear when Wave 2 closes)
`br ready` returns the current wave — all unblocked issues that can run in parallel.
Beads-backed issues are the preferred path because they give /crank richer dependency data and make ratchet progress easier to inspect. When br is unavailable or degraded, keep the plan file + execution packet path accurate and continue in file-backed mode for /crank and /validate.
Step 7b.0: Scenario Admission Gate (Blocking)
Before the validation-block check, run the mechanical scenario admission gate over every created issue. The gate (scripts/check-bead-scenario-coverage.sh --admission) is the plan-time structural check: it passes only when the bead body carries at least one structurally complete scenario unit — a Scenario: block or a bare Given/When/Then stanza.
if command -v br &>/dev/null; then
INADMISSIBLE=()
for ISSUE_ID in $ALL_CREATED_ISSUES; do
BEADS_DIR="$(ao beads dir)" br show "$ISSUE_ID" | bash scripts/check-bead-scenario-coverage.sh --admission -
RC=$?
if [[ $RC -eq 1 ]]; then
INADMISSIBLE+=("$ISSUE_ID")
elif [[ $RC -eq 2 ]]; then
echo "TRACKER FAILURE: admission gate got no usable input for $ISSUE_ID (br down? empty body fetch?)."
echo " Surface the infra failure and stop. Do NOT treat the bead as inadmissible."
break
fi
done
if [[ ${#INADMISSIBLE[@]} -gt 0 ]]; then
echo "BLOCKING: ${#INADMISSIBLE[@]} issue(s) failed scenario admission: ${INADMISSIBLE[*]}"
echo " Fix each bead body (add or repair its ## Scenarios block) before reporting the plan DONE."
fi
fiThis is a blocking gate, unlike the Step 7b validation-block warning below. Exit 1 means the bead is inadmissible — fix the bead body before reporting the plan DONE. Exit 2 means tracker/infra failure — surface it and stop; do NOT treat the bead as inadmissible.
Step 7b: Verify Validation Blocks (Post-Creation Check)
After creating all beads issues, verify that every issue body contains a fenced validation block. Missing validation blocks break the plan-to-crank pipeline — /crank cannot extract conformance checks from issues that lack them.
if command -v br &>/dev/null && [[ -n "$EPIC_ID" ]]; then
MISSING_VALIDATION=()
for ISSUE_ID in $ALL_CREATED_ISSUES; do
if ! br show "$ISSUE_ID" 2>/dev/null | grep -q '```validation'; then
MISSING_VALIDATION+=("$ISSUE_ID")
fi
done
if [[ ${#MISSING_VALIDATION[@]} -gt 0 ]]; then
echo "WARNING: ${#MISSING_VALIDATION[@]} issue(s) missing validation blocks: ${MISSING_VALIDATION[*]}"
echo " /crank will fall back to default files_exist checks for these issues."
echo " Consider adding ```validation``` blocks with conformance checks."
else
echo "All ${#ALL_CREATED_ISSUES[@]} issues have validation blocks."
fi
fiThis is a warning gate, not a blocker — plans can proceed without validation blocks, but crank execution will use weaker fallback checks.
Formula Templates Reference
Detailed templates for formula files and plan summaries.
---
Formula File Template (.formula.toml)
Location: .agents/formulas/{topic-slug}.formula.toml
Structure Overview
| Section | Purpose |
|---|---|
| Top-level fields | Formula metadata (formula, description, version, type) |
[vars] | Simple key-value pairs for parameterization |
[[steps]] | Array of implementation steps with dependencies |
Full Template
# Formula: {Goal Name}
# Reusable pattern for creating {description}
# Created: YYYY-MM-DD
# REQUIRED: Top-level fields (NOT in a [formula] table!)
formula = "{topic-slug}"
description = "{Detailed description of what this formula produces}"
version = 2
type = "workflow" # MUST be: workflow | expansion | aspect
# OPTIONAL: Variables for parameterization
# Use {{var_name}} syntax in step descriptions
[vars]
service_name = "default-service"
base_path = "services/"
# Steps define the work items - each becomes a child issue when poured
# Order doesn't matter - dependencies define execution order via `needs`
[[steps]]
id = "core"
title = "Add {{service_name}} core implementation"
description = """
Implement the core {{service_name}} functionality:
- Add main module at {{base_path}}{{service_name}}/core.py
- Include error handling and logging
- Follow existing patterns in the codebase
Files affected:
- {{base_path}}{{service_name}}/core.py
- {{base_path}}{{service_name}}/__init__.py
Acceptance criteria:
- Module is importable
- Passes unit tests
- Handles edge cases gracefully
"""
needs = [] # Wave 1 - no dependencies
[[steps]]
id = "config"
title = "Add {{service_name}} configuration"
description = """
Add configuration for {{service_name}}:
- Update charts/ai-platform/values.yaml with new config section
- Add environment variable mappings
- Document configuration options in values.yaml comments
Files affected:
- charts/ai-platform/values.yaml
- charts/ai-platform/templates/configmap.yaml
Acceptance criteria:
- Config values documented
- Defaults are sensible
- Works in dev and prod environments
"""
needs = [] # Wave 1 - can run parallel with core
[[steps]]
id = "tests"
title = "{{service_name}} integration tests"
description = """
Add comprehensive tests for {{service_name}}:
- Unit tests for core functionality
- Integration tests for API endpoints
- Ensure >80% coverage
Files affected:
- tests/unit/test_{{service_name}}.py
- tests/integration/test_{{service_name}}_e2e.py
Acceptance criteria:
- Happy path covered
- Error cases handled
- CI passes
"""
needs = ["core"] # Wave 2 - depends on core implementation
[[steps]]
id = "docs"
title = "{{service_name}} documentation"
description = """
Document {{service_name}}:
- API reference in docs/api/
- Update README with usage examples
- Add architecture decision record if needed
Files affected:
- docs/api/{{service_name}}.md
- README.md
Acceptance criteria:
- Usage examples work
- API fully documented
"""
needs = ["core", "config"] # Wave 2 - depends on both core and configField Reference
| Field | Required | Type | Description |
|---|---|---|---|
formula | Yes | string | Unique identifier (slug) at TOP LEVEL |
description | Yes | string | What the formula creates |
version | Yes | integer | Use 2 |
type | Yes | string | workflow, expansion, or aspect |
[vars] | No | table | Simple key = "value" pairs |
[[steps]] | Yes | array | Step definitions |
steps.id | Yes | string | Unique step identifier |
steps.title | Yes | string | Short step title (can use {{vars}}) |
steps.description | Yes | string | Detailed implementation guidance |
steps.needs | Yes | array | Step IDs this depends on (empty = Wave 1) |
WRONG Format (Do NOT Use)
# WRONG - Do not use this format!
[formula] # WRONG: formula is a top-level string, not a table
name = "topic-slug" # WRONG: use `formula = "..."` at top level
version = "1.0.0" # WRONG: use integer `version = 2`
[variables] # WRONG: use [vars] with simple values
component = { type = "string" } # WRONG: complex type definitions not supported
[[tasks]] # WRONG: use [[steps]]
title = "..."
type = "feature" # WRONG: no type field in steps
priority = "P1" # WRONG: no priority field in steps
wave = 1 # WRONG: no wave field (computed from needs)
depends_on = ["..."] # WRONG: use needs = [...]
files = ["..."] # WRONG: no files field
[waves] # WRONG: waves are computed, not declared
1 = ["step1", "step2"]Wave Computation
Waves are computed from the needs field:
| Wave | Rule | Example |
|---|---|---|
| Wave 1 | needs = [] | core, config |
| Wave 2 | All needs are Wave 1 | tests (needs core), docs (needs core, config) |
| Wave N | All needs are Wave N-1 or earlier | - |
Variable Substitution
Variables defined in [vars] can be used in step descriptions with {{var}} syntax:
[vars]
service_name = "rate-limiter"
requests_per_minute = "100"
[[steps]]
id = "impl"
title = "Implement {{service_name}}"
description = "Configure {{requests_per_minute}} requests per minute"
needs = []Using bd cook
Note: bd cook is a planned feature, not yet implemented.# Preview what would be created
bd cook .agents/formulas/{topic-slug}.formula.toml --dry-run
# Cook and save proto to database
bd cook .agents/formulas/{topic-slug}.formula.toml --persist
# Cook with variable overrides
bd cook .agents/formulas/{topic-slug}.formula.toml --persist \
--var service_name=auth-middleware
# Then pour to create actual issues
# FUTURE: bd mol not yet implemented. Molecule design deferred post beads-br consolidation (ag-ez7y6).
bd mol pour {topic-slug}---
Companion Plan Document Template
Location: .agents/formulas/{topic-slug}.md
Tag Vocabulary (REQUIRED)
Document type tag: formula (required first)
Examples:
[formula, agents, kagent]- KAgent implementation formula[formula, data, neo4j]- GraphRAG implementation formula[formula, auth, security]- OAuth2 implementation formula[formula, ci-cd, tekton]- Tekton pipeline formula
Full Template
---
date: YYYY-MM-DD
type: Formula
goal: "[Goal description]"
tags: [formula, domain-tag, optional-tech-tag]
formula: "{topic-slug}.formula.toml"
epic: "[beads epic ID, if instantiated]"
status: TEMPLATE | INSTANTIATED
---
# Formula: [Goal]
## Overview
[2-3 sentence summary of what this formula creates and when to use it]
## Variables
| Variable | Default | Description |
|----------|---------|-------------|
| service_name | default-service | Name of the service |
| base_path | services/ | Base path for source files |
## Steps (Dependency Order)
| ID | Title | Needs | Wave |
|----|-------|-------|------|
| core | Add core implementation | - | 1 |
| config | Add configuration | - | 1 |
| tests | Integration tests | core | 2 |
| docs | Documentation | core, config | 2 |
## Dependency Graph
Wave 1 (No Dependencies): core: Add core implementation config: Add configuration | v unblocks Wave 2 (Depends on Wave 1): tests: Integration tests (needs: core) docs: Documentation (needs: core, config)
## Wave Execution Order
| Wave | Steps | Can Parallel | Notes |
|------|-------|--------------|-------|
| 1 | core, config | Yes | No dependencies, different files |
| 2 | tests, docs | Yes | Both depend on Wave 1, different files |
**Wave Computation Rules:**
- **Wave 1:** All steps with `needs = []`
- **Wave N:** Steps where all `needs` are in Wave N-1 or earlier
- **Can Parallel:** "Yes" if steps in same wave affect different files
## Files to Modify
| File | Change |
|------|--------|
| `{{base_path}}{{service_name}}/core.py` | Add core module with main logic |
| `{{base_path}}{{service_name}}/config.py` | **NEW** — configuration handling |
| `tests/unit/test_{{service_name}}.py` | **NEW** — unit tests |
> **Skills-codex parity:** when a plan modifies `skills/<name>/SKILL.md`,
> default-include `skills-codex/<name>/SKILL.md` (and any
> `skills-codex-overrides/<name>/`) in this section. The codex mirror is
> manually maintained and silently drifts if a plan touches the canonical
> skill without listing the mirror.
## Implementation
### 1. Core Module
In `{{base_path}}{{service_name}}/core.py`:
- **Create `ServiceHandler` class** with `__init__(self, config: ServiceConfig)` and `process(self, request: Request) -> Response`
- **Key functions to reuse:**
- `validate_request()` at `{{base_path}}common/validation.py:45`
- `format_response()` at `{{base_path}}common/response.py:23`
### 2. Configuration
In `{{base_path}}{{service_name}}/config.py`:
- **Add `ServiceConfig` dataclass:**@dataclass class ServiceConfig: service_name: str = "{{service_name}}" base_path: str = "{{base_path}}"
## Tests
**`tests/unit/test_{{service_name}}.py`** — **NEW**:
- `test_service_handler_happy_path`: Valid request returns expected response
- `test_service_handler_invalid_input`: Bad request raises ValueError
- `test_config_defaults`: ServiceConfig has correct defaults
## Verification
1. **Unit tests**: `pytest tests/unit/test_{{service_name}}.py -v`
2. **Build check**: `python -c "from {{base_path.replace('/', '.')}}{{service_name}} import core"`
3. **Manual test**:python -c " from {{base_path.replace('/', '.')}}{{service_name}}.core import ServiceHandler handler = ServiceHandler() print(handler.process({'data': 'test'})) "
## Implementation Notes
[Key decisions, patterns to follow, risks identified]
## Usage
### Cook and Pour
> **Note:** `bd cook` is a planned feature, not yet implemented.
Preview what would be created
bd cook .agents/formulas/{topic-slug}.formula.toml --dry-run
Cook proto to database
bd cook .agents/formulas/{topic-slug}.formula.toml --persist
Pour to create actual issues
FUTURE: bd mol not yet implemented. Molecule design deferred post beads-br consolidation (ag-ez7y6).
bd mol pour {topic-slug}
With variable overrides
FUTURE: bd mol not yet implemented. Molecule design deferred post beads-br consolidation (ag-ez7y6).
bd mol pour {topic-slug} --var service_name=rate-limiter
## Next Steps
Run `/crank <epic-id>` for hands-free execution, or `/implement-wave <epic-id>` for supervised.---
Formula Summary Template (Crank Handoff)
Output this after cooking/pouring a formula. This is the handoff to crank.
---
# Formula Instantiated: [Goal Description]
**Formula:** `.agents/formulas/{topic-slug}.formula.toml`
**Epic:** `<rig-prefix>-xxx`
**Plan:** `.agents/formulas/{topic-slug}.md`
**Steps:** N steps across M waves
---
## Wave Execution Order
| Wave | Steps | Can Parallel | Ready Now |
|------|-------|--------------|-----------|
| 1 | xxx.core, xxx.config | Yes | Ready |
| 2 | xxx.tests, xxx.docs | Yes | Blocked by Wave 1 |
## Steps Created
| ID | Step | Needs |
|----|------|-------|
| xxx.core | Add core implementation | - |
| xxx.config | Add configuration | - |
| xxx.tests | Integration tests | core |
| xxx.docs | Documentation | core, config |
## Dependency Graph
Wave 1 (needs = []): xxx.core: Add core implementation xxx.config: Add configuration | v unblocks Wave 2 (depends on Wave 1): xxx.tests: Integration tests (needs: core) xxx.docs: Documentation (needs: core, config)
---
## Ready for Execution
### Pre-Flight Checklist
- [x] Formula cooked with `bd cook --persist` <!-- FUTURE: bd cook not yet implemented -->
- [x] Mol poured with `bd mol pour` <!-- FUTURE: bd mol not yet implemented. Molecule design deferred post beads-br consolidation (ag-ez7y6). -->
- [x] Steps have proper dependencies via `needs`
- [ ] External requirements: [list any, e.g., "API key configured"]
### Execute
**Autonomous (overnight, parallel via polecats):**/crank xxx # Full auto until epic closed
**Supervised (sequential, same session):**/implement-wave xxx # One wave at a time
### Alternative: Manual Execution
Implement one at a time
br ready /implement xxx.core
Wave Matrices: File Conflicts and Cross-Wave Registries
Extracted from plan/SKILL.md on 2026-04-11.
File-level dependency matrix, cross-wave shared file registry, dependency necessity validation.
File-Level Dependency Matrix (Mandatory)
Before assigning issues to waves, build a file-conflict matrix. For EACH issue, list every touched file it modifies or regenerates, not just the primary source files. The inventory must include tests, docs, schemas, fixtures, runtime copies, generated references, parity manifests, hash markers, lockfiles, and other generated artifacts. If an exact generated path is not known yet, assign the smallest owning glob to the issue and replace it with concrete paths before worker dispatch.
If any file appears in 2+ same-wave issues, either:
- Serialize them (move one to a later wave), or
- Merge them into a single issue assigned to one worker.
## File-Conflict Matrix
| File | Issues |
|------|--------|
| `src/auth.go` | Issue 1, Issue 3 | ← CONFLICT: serialize or merge
| `src/config.go` | Issue 2 |
| `src/auth_test.go` | Issue 1 |Why: Issue-level dependency graphs miss shared-file conflicts. In context-orchestration-leverage, two tracks both modified rpi_phased_handoff.go and required an unplanned Wave 2a/2b split. A file-conflict matrix would have caught this during planning.
Cross-Wave Shared File Registry (Mandatory)
After computing waves, build a cross-wave file registry listing every file that appears in issues across different waves. These files are collision risks because later-wave worktrees are created from a base SHA that may not include earlier-wave changes.
## Cross-Wave Shared Files
| File | Wave 1 Issues | Wave 2+ Issues | Mitigation |
|------|---------------|----------------|------------|
| `src/auth_test.go` | Issue 1 | Issue 5 | Wave 2 worktree must branch from post-Wave-1 SHA |
| `src/config.go` | Issue 2 | Issue 6 | Serial: Issue 6 blocked by Issue 2 |If any file appears in multiple waves: 1. Ensure the later-wave issue explicitly declares a dependency on the earlier-wave issue that touches the same file (so br dep add / addBlockedBy is set). 2. Flag the file in the plan's ## Cross-Wave Shared Files section so /crank can enforce worktree base refresh between waves. 3. For test files shared across waves, prefer splitting test additions into the same wave as the code they test — avoid a separate "test coverage" issue that touches files already modified in an earlier wave.
Why: In na-vs9, Wave 2 agents started from pre-Wave-1 SHA. A Wave 2 test coverage issue overwrote Wave 1's .md→.json fix in rpi_phased_test.go because the worktree didn't include Wave 1's commit. The cross-wave registry makes these collisions visible during planning.
Generated Artifact Companion Scope
When a planned issue changes skill behavior, phrasing, orchestration, or UX under skills/<name>/, the same issue must explicitly plan the Codex runtime companion scope:
skills-codex/<name>/when the checked-in Codex artifact needs a body/script/reference change.skills-codex-overrides/<name>/orskills-codex-overrides/catalog.jsonwhen the Codex-specific tailoring or treatment changes.skills-codex/.agentops-manifest.jsonandskills-codex/<name>/.agentops-generated.jsonwhen artifact hashes need refresh.
Record these files in the ## File-Conflict Matrix with the source skill issue, not in a later generic cleanup wave. The issue's validation block must include:
bash scripts/refresh-codex-artifacts.sh --scope worktree
bash scripts/validate-codex-generated-artifacts.sh --scope worktree
bash scripts/audit-codex-parity.sh --skill <name>If the skill behavior change definitely has no Codex-facing effect, write that as the matrix mitigation with evidence. Do not leave Codex artifact scope implicit.
Validate Dependency Necessity
For EACH declared dependency, verify: 1. Does the blocked issue modify a file that the blocker also modifies? → Keep 2. Does the blocked issue read output produced by the blocker? → Keep 3. Is the dependency only logical ordering (e.g., "specs before roles")? → Remove
False dependencies reduce parallelism. Pre-mortem judges will also flag these. In ol-571, unnecessary serialization between independent spec rewrites was caught by pre-mortem.
#!/usr/bin/env bash
set -euo pipefail
SKILL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
PASS=0; FAIL=0
check() { if bash -c "$2"; then echo "PASS: $1"; PASS=$((PASS + 1)); else echo "FAIL: $1"; FAIL=$((FAIL + 1)); fi; }
check "SKILL.md exists" "[ -f '$SKILL_DIR/SKILL.md' ]"
check "SKILL.md has YAML frontmatter" "head -1 '$SKILL_DIR/SKILL.md' | grep -q '^---$'"
check "SKILL.md has name: plan" "grep -q '^name: plan' '$SKILL_DIR/SKILL.md'"
check "references/ directory exists" "[ -d '$SKILL_DIR/references' ]"
check "references/ has at least 2 files" "[ \$(ls '$SKILL_DIR/references/' | wc -l) -ge 2 ]"
check "SKILL.md mentions .agents/plans/ output path" "grep -q '\.agents/plans/' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions compiled planning rules" "grep -q '\.agents/planning-rules' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions finding registry fallback" "grep -q 'registry.jsonl' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions active findings" "grep -qi 'active findings' '$SKILL_DIR/SKILL.md'"
check "SKILL.md requires applied finding IDs in plan context" "grep -q 'Applied findings:' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions waves" "grep -qi 'wave' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions dependencies" "grep -qi 'dependencies\|depend' '$SKILL_DIR/SKILL.md'"
check "wave matrices require Codex companion scope" "grep -q 'Generated Artifact Companion Scope' '$SKILL_DIR/references/wave-matrices.md' && grep -q 'refresh-codex-artifacts.sh --scope worktree' '$SKILL_DIR/references/wave-matrices.md'"
check "wave matrices require full touched-file inventory" "grep -q 'list every touched file' '$SKILL_DIR/references/wave-matrices.md' && grep -q 'tests, docs, schemas, fixtures' '$SKILL_DIR/references/wave-matrices.md' && grep -q 'parity manifests, hash markers' '$SKILL_DIR/references/wave-matrices.md'"
check "SKILL.md mentions br for issue tracking" "grep -q 'br ' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions task tracking" "grep -qi 'task\|tracking\|br ' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions conformance checks" "grep -qi 'conformance' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions --auto flag" "grep -q '\-\-auto' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions Explore agent" "grep -qi 'explore' '$SKILL_DIR/SKILL.md'"
echo ""; echo "Results: $PASS passed, $FAIL failed"
[ $FAIL -eq 0 ] && exit 0 || exit 1
Plan Skill Self-Test
Trigger Cases
- User says:
/plan "add user authentication"(or any/plan <goal>). - Expected: load
plan, read prior research if present, decompose into issues/waves, and write.agents/plans/YYYY-MM-DD-<slug>.md.
- User passes a bead ID:
/plan soc-1234. - Expected: run the Step 0 stale-scope pre-flight (
ao beads verify) before decomposition when the bead is full-complexity, older than 7 days, or filed by a prior session.
- User says:
/plan --auto "refactor payment module". - Expected: load
planand run decomposition without the Gate-2 human approval step.
Non-Trigger Cases
- User asks an open investigation question with no goal to decompose ("how does X work?").
- Expected: route to
/research, notplan.
- User asks to validate already-implemented work or run gates.
- Expected: route to
/validate, notplan.
Behavior Checks
These map to the four scenarios in references/plan.feature:
- Plan consumes Discovery output: each slice carries acceptance criteria, write scope, test levels, and ownership, and no slice depends on raw Discovery chat context.
- One slice per Given/When/Then row: a BDD intent issue with N rows yields N vertical slices, each with a first-failing-test target.
- Wave-validity gate before parallelization: a wave passes only when every row holds — distinct write scopes, no shared migration/contract/CLI surface, declared integration order, an owner per slice, and a discard path per slice; otherwise slices default to sequential.
- Durable slice-validation artifact: Plan writes a slice plan to
.agents/plans/*.mdplus anexecution-packet.json, and a fresh agent can execute the slices from those artifacts alone.
Worker latitude: Plan may create small mechanical files (templates, fixtures, generated companions) when they are required to satisfy a slice's acceptance criteria — these belong in the file dependency matrix as write ownership claims.
Validation Commands
Run from the repo root:
bash skills/heal-skill/scripts/heal.sh --strict skills/plan
bash scripts/validate-skill-frontmatter.sh --strictFailure Cases
- Plan written without a baseline audit (file/section/LOC counts): fail the Baseline Audit Gate and quantify ground truth before decomposing (
--skip-audit-gatefor documentation-only plans). - Acceptance criteria missing the fenced YAML
acceptance_criteriablock: contract violation — add the block to every issue body. - Two same-wave slices claiming
writeon the same file: serialize withblockedByor merge the slices; do not ship the wave.
Related skills
How it compares
Pick plan over generic task lists when work must flow into beads issues and AgentOps downstream skills with bounded contexts.
FAQ
What does plan do?
Decompose goals into issue plans. Triggers: "plan", "decompose goals into issue plans.", "plan skill".
When should I use plan?
Decompose goals into issue plans. Triggers: "plan", "decompose goals into issue plans.", "plan skill".
What are common prerequisites?
--- name: plan description: 'Decompose goals into issue plans.
Is Plan safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.