--- name: planner description: Use when a milestone spec exists in docs/specs/ and a new iteration is starting. Produces a placeholder-free, bite-sized implementation plan in docs/plans/ that the implement skill can execute task-by-task. Hard-gate before any implementation work. --- # plan — spec → executable plan > **Violating the letter of these rules is violating the spirit.** ## Overview A plan is the contract between design (spec) and execution (`implement`). It commits the file structure, names every file that will be created or modified, and decomposes work into bites small enough that a subagent can execute one in 2-5 minutes without making judgement calls outside its remit. Plans live at `docs/plans/.md` and the header references the parent spec. The plan decomposes work into tasks; each task is the unit of review (spec-compliance and quality gates inside `implement`), not the unit of commit. Commits are a Boss-only decision taken at the end of the iter against the full working-tree diff. ## When to Use / Skipping Triggers: - A spec at `docs/specs/.md` is approved. - A new iteration within an active milestone is starting. May be skipped when: - The work is a bug fix where the RED test from `debug` IS the plan (handoff goes straight to `implement` mini-mode). - The work is a trivial mechanical edit (one file, ≤30 LOC, no design judgement). **Never skipped** for a standard iteration within an active milestone. "I know the milestone, plan from memory" is exactly the failure mode this skill prevents. ## The Iron Law ``` NO PLACEHOLDERS — TBD, TODO, "implement later", "similar to Task N", or "add appropriate error handling" are PLAN FAILURES. EVERY STEP THAT CHANGES CODE INCLUDES THE CODE. EVERY STEP THAT RUNS A COMMAND INCLUDES THE COMMAND AND EXPECTED OUTPUT. ``` Non-negotiable. ## The Process ### Step 1 — Read the parent spec Read `docs/specs/.md` in full. NOT from memory. Even if the spec is recent and you wrote it yourself, re-read it before planning. The spec is the source of truth; the plan is the projection of one iteration's worth of work onto a task list. ### Step 2 — Map file structure Dispatch `ailang-plan-recon` with the spec path and iteration scope. Read the returned file-map. Lift the relevant entries into the plan's "Files this plan creates or modifies" section; the Boss may add or amend entries that recon missed. Dispatch carrier: | Field | Content | |-------|---------| | `spec_path` | path to the parent spec | | `iteration_scope` | which sections of the spec this iteration covers | | `focus_hint` | optional — subsystem or symbol to prioritise | Recon does NOT decide decomposition. Two recon dispatches per planner run is unusual but legitimate (e.g. one for the main spec sections, one with a sharper `focus_hint` for a tricky subsystem). Three or more is a smell — re-read the spec; the iteration scope is probably too broad. The plan's "Files this plan creates or modifies" section keeps the same shape: ```markdown **Files this plan creates or modifies:** - Create: `` — - Modify: `:` - Test: `` — ``` Files that change together stay in the same task. Files that change independently get separate tasks. ### Step 3 — Write tasks, bite-sized Each task is a logical unit of change (one feature, one fix, one extension). Each task contains steps; each step is ONE action that takes 2-5 minutes: ```markdown ### Task N: **Files:** - Create: `` - Modify: `:` - Test: `` - [ ] **Step 1: Write the failing test** ```rust #[test] fn test_() { let result = function(input); assert_eq!(result, expected); } ``` - [ ] **Step 2: Run test to verify it fails** Run: `cargo test --workspace -p test_` Expected: FAIL with "" - [ ] **Step 3: Write minimal implementation** ```rust fn function(input: T) -> U { // exact code } ``` - [ ] **Step 4: Run test to verify it passes** Run: `cargo test --workspace -p test_` Expected: PASS ``` No `git commit` step. Implement tasks leave their work in the working tree; the Boss commits at the end of the iter. ### Step 4 — Plan header Every plan starts with this header: ```markdown # — Implementation Plan > **Parent spec:** `docs/specs/.md` > > **For agentic workers:** REQUIRED SUB-SKILL: use `skills/implement` > to run this plan. Steps use `- [ ]` checkboxes for tracking. **Goal:** **Architecture:** <2-3 sentences> **Tech Stack:** --- ``` ### Step 5 — Self-review Before handing the plan off, run this checklist inline: 1. **Spec coverage:** every spec section has a task that implements it. If a section has no task, add one. 2. **Placeholder scan:** grep for "TBD", "TODO", "implement later", "similar to Task", "add appropriate error handling". Any hit is a plan failure to fix. 3. **Type consistency:** function names, type names, file paths referenced across tasks must match. `clearLayers()` in Task 3 and `clearFullLayers()` in Task 7 is a bug. 4. **Step granularity:** every step is 2-5 minutes. If a step is "implement the parser", split it. 5. **No commit steps:** task templates must not contain `git commit` instructions. Implement tasks leave work in the working tree. 6. **Pin/replacement substring contiguity:** when a task ships a test asserting `contains("")` (or a grep) AND another task's verbatim replacement body is what must contain that substring, the substring must appear *contiguously* in that replacement body — no soft-wrap splitting it across two lines. Two authoritative artefacts (exact pin vs. exact replacement) that cannot both be applied literally is a plan defect, not an implementer judgement call. This is the recurring grep/contains line-wrap family (iter-revert Concern 2; iter effect-doc-honesty Task 2) — scrub it here, every plan that pairs a presence-pin with a verbatim text edit. 7. **Compile-gate vs. deferred-caller ordering:** when a task changes a function signature (or any change that makes the *whole crate* fail to compile until N call sites are updated) AND that task ends with a `cargo build`/`cargo test` "0 errors" gate, every caller the signature change touches MUST be threaded *inside that same task* — not deferred to a later task. A "0-errors" gate is unsatisfiable while any caller is still unthreaded (hard `error[E0061]`), so a plan that defers a caller (e.g. "the `check_fn` call site is handled in Task 4") past an earlier task's compile gate is internally contradictory: the executor is forced to pull the deferred code forward to satisfy the gate, silently resequencing the plan. Either fold all caller-threading into the signature-change task, or make the gate a *partial* build of just the changed module with the crate-wide build deferred to the task that finishes threading. This is the recurring "compile-gate depends on a caller the plan defers past the gate" family (iter loop-recur.2 Concern 1) — scrub it here, every plan with a signature-change task. 8. **Verification-command filter strings must resolve.** Every literal `cargo test … ` / `grep ` / `cargo test --test ` in a Run step is itself a load-bearing artefact: if its filter substring matches **no** test (or its `--test` target file does not exist), the step silently asserts nothing — a green "0 passed; 0 filtered" reads as success while proving the opposite of the gate's intent. For every such command, either (a) the filter substring must be one verified to match ≥1 real named test/line in the current tree (name it, do not guess from the feature word — e.g. tail-app guards are `*_tail_position_*` / `*musttail*`, NOT `tail`), or (b) use the unfiltered suite plus an explicit result-count assertion (`… | awk '{p+=$4} END{print p}'`, expected ≥ a stated baseline) so "nothing ran" cannot masquerade as "nothing regressed". This is the recurring "literal verification filter doesn't resolve to its evident target" family (iter loop-recur.3 Concern) — scrub every Run step whose assertion lives in a filter string. Fix issues inline. ### Step 6 — Hand off The plan sits in the working tree as an unstaged file at `docs/plans/.md`. Hand off to `implement` with: path to the plan file + optional task focus ("only Tasks 1-3 this run"). The Boss commits the plan when handing it forward (suggested commit subject: `plan: `). The planner skill does not perform the commit itself. ## Handoff Contract | Direction | Carrier | |-----------|---------| | `brainstorm` → `planner` | path to `docs/specs/.md` + iteration scope ("this iteration covers spec section X+Y") | | `planner` → `implement` | path to `docs/plans/.md` + optional task-range focus | | `planner` → `brainstorm` (bounce) | spec contains placeholders or contradictions: name the offending section, request revision | ## Common Rationalisations | Excuse | Reality | |--------|---------| | "TBD in step 4 lets me ship the plan tonight, fill in tomorrow" | Half-decided plans get re-litigated mid-iteration, costing more than the night's sleep saved. Make the decision tonight or close the laptop. | | "Bundle Tasks 3 and 4, both small" | Tasks are the unit of review (spec-check + quality-check fire once per task). Bundling collapses two reviews into one and hides the smaller change inside the bigger one. If 3 and 4 are inseparable, they're one task — rewrite the decomposition. | | "Spec is recent, I wrote it, plan from memory" | Memory diverges from disk. 15 minutes of re-reading is the cheapest insurance in the cycle. | | "Step 5 'implement the parser' is fine, I'll detail it at execution time" | Then it's not a step, it's a wish. Steps are bite-sized OR the plan isn't done. | | "Task 7 is similar to Task 4, just say so" | The executor may read tasks out of order. Repeat the code. | | "The spec has a TBD too, I can pass it through" | Bounce back to `brainstorm`. Plans inherit spec gaps; spec gaps are not plan placeholders. | ## Red Flags — STOP - Any of: "TBD", "TODO", "fill in later", "similar to", "add appropriate " — fix or bounce. - Steps that describe what to do without showing how - Function/type/path names that don't match across tasks - Step descriptions longer than the code they describe - Header missing parent spec reference - Self-review skipped because "the plan looks fine" ## Cross-references - **Input source:** `skills/brainstorm/SKILL.md` — produces the spec this skill consumes. - **Output target:** `skills/implement/SKILL.md` — runs the plan task-by-task. - **Agents dispatched:** - `skills/planner/agents/ailang-plan-recon.md` — Step 2, file-structure mapping (read-only). Mandatory; the Boss does NOT do recon in-context.