Files
Skills/planner/SKILL.md
T
Brummel 305d7973d4 feat: planner parse-the-bytes-you-inline gate (issue #1 Fix 4)
Adds self-review check #9 to planner Step 5, symmetric to Fix 1: when
the profile declares `spec_validation.parsers`, every verbatim code
body the plan inlines into a task step whose fence label has an entry
must parse clean against the live tool before hand-off. Non-zero exit
is a plan failure — the last defensive line before implementer
dispatch. Trace goes into the planner session.

Targets the surface-language snippets the plan lifts verbatim from the
spec (the compound-hallucination bytes); source-language test/impl
bodies are out of scope — the implement compile gate catches those.

Also adds a Common Rationalisation ("came straight from the spec") and
a Red Flag (configured parser, no trace in session).

refs #1

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 14:29:03 +02:00

300 lines
12 KiB
Markdown

---
name: planner
description: Use when a cycle spec exists under paths.spec_dir and a new iteration is starting. Produces a placeholder-free, bite-sized implementation plan under paths.plan_dir that the implement skill can execute task-by-task. Hard-gate before any implementation work.
---
# planner — 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 under the project's `paths.plan_dir` with a name
shape governed by the project's `naming.policy` (see profile
schema). 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 an orchestrator-only decision
taken at the end of the iter against the full working-tree
diff.
## When to Use / Skipping
Triggers:
- A spec under `paths.spec_dir` for the active cycle is
approved.
- A new iteration within an active cycle 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
cycle. "I know the cycle, 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 the spec under `paths.spec_dir` 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 `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
orchestrator 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: `<exact path>` — <one-line responsibility>
- Modify: `<exact path>:<line range if known>`
- Test: `<exact path>` — <one-line case description>
```
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: <Component Name>
**Files:**
- Create: `<exact path>`
- Modify: `<exact path>:<line range if known>`
- Test: `<exact path>`
- [ ] **Step 1: Write the failing test**
(exact test source code here)
- [ ] **Step 2: Run test to verify it fails**
Run: `<the project's test command from commands.test, scoped to this test>`
Expected: FAIL with "<exact expected message>"
- [ ] **Step 3: Write minimal implementation**
(exact implementation source code here)
- [ ] **Step 4: Run test to verify it passes**
Run: `<the same test command>`
Expected: PASS
```
No `git commit` step. Implement tasks leave their work in
the working tree; the orchestrator commits at the end of the
iter.
### Step 4 — Plan header
Every plan starts with this header:
```markdown
# <Iteration Title> — Implementation Plan
> **Parent spec:** `<path under paths.spec_dir>`
>
> **For agentic workers:** REQUIRED SUB-SKILL: use the
> `implement` skill to run this plan. Steps use `- [ ]`
> checkboxes for tracking.
**Goal:** <one sentence>
**Architecture:** <2-3 sentences>
**Tech Stack:** <key components touched>
---
```
### 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("<substring>")` (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 a recurring
defect family — 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 compilation unit fail to compile until N
call sites are updated) AND that task ends with a
"0 errors" build 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 compile error), so a plan that defers a caller
(e.g. "the X 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 workspace-wide build
deferred to the task that finishes threading. This is a
recurring defect family — scrub it here, every plan with
a signature-change task.
8. **Verification-command filter strings must resolve.**
Every literal test-filter / grep pattern / test-target
in a Run step is itself a load-bearing artefact: if its
filter substring matches **no** test (or its target file
does not exist), the step silently asserts nothing — a
green "0 ran" 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), or (b) use the
unfiltered suite plus an explicit result-count assertion
so "nothing ran" cannot masquerade as "nothing
regressed". This is a recurring defect family — scrub
every Run step whose assertion lives in a filter string.
9. **Parse-the-bytes-you-inline gate.** If the project profile
declares `spec_validation.parsers`, every verbatim code body
the plan inlines into a task step whose fence label has a
`parsers` entry must be parsed clean against the live tool
before hand-off. For each such block: write it to a temp file
with the entry's `ext`, run the entry's `cmd` with `{file}`
substituted, require exit 0. A non-zero exit is a plan failure
— the plan would hand the implementer bytes that do not parse,
the last defensive line before dispatch — fix the plan, do not
hand off. The parse-trace goes into the planner's self-review
activity (the session) as the attestation the gate fired. The
target is the surface-language snippets the plan lifts verbatim
(example programs, fixtures); the project's source-language
test / implementation bodies are NOT the target — the
`implement` compile gate catches those. A block whose fence
label has no entry is skipped and the skip noted ("no parser
for fence label X"); never a silent pass. A malformed entry
(`cmd` without `{file}`, or `ext` / `cmd` missing) is a profile
error to surface, not a skip. If the profile declares no
`spec_validation`, this check is a documented no-op.
Fix issues inline.
### Step 6 — Hand off
The plan sits in the working tree as an unstaged file under
`paths.plan_dir`. Hand off to `implement` with: path to the
plan file + optional task focus ("only Tasks 1-3 this run").
The orchestrator commits the plan when handing it forward
(suggested commit subject: `plan: <iteration> <subject>`).
The planner skill does not perform the commit itself.
## Handoff Contract
| Direction | Carrier |
|-----------|---------|
| `brainstorm``planner` | path to the spec under `paths.spec_dir` + iteration scope ("this iteration covers spec section X+Y") |
| `planner``implement` | path to the plan under `paths.plan_dir` + 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. |
| "The example program came straight from the spec, it must be valid" | The spec's code blocks are hypotheses, not verified bytes — brainstorm's parse gate can be skipped and a post-spec edit can break them. Re-parse every surface-language body you inline; this is the last line before the implementer hits it (issue #1 Fix 4). |
## Red Flags — STOP
- Any of: "TBD", "TODO", "fill in later", "similar to",
"add appropriate <X>" — 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"
- A task step inlining a surface-language code body whose fence
label has a configured `spec_validation` parser, handed off
without a parse-trace in the planner session
## Cross-references
- **Input source:** `../brainstorm/SKILL.md` — produces the
spec this skill consumes.
- **Output target:** `../implement/SKILL.md` — runs the plan
task-by-task.
- **Agents dispatched:**
- `agents/plan-recon.md` — Step 2, file-structure mapping
(read-only). Mandatory; the orchestrator does NOT do
recon in-context.