plugins/coordinator/skills/writing-plans/SKILL.md
This skill should be used when requirements are clear and the task needs decomposition into executable chunks — before touching code. Triggers on: 'write a plan', 'break this down', 'plan the implementation'.
npx skillsauth add oduffy-delphi/coordinator-claude writing-plansInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Write comprehensive implementation plans assuming the engineer has zero context for our codebase and questionable taste. Document everything they need to know: which files to touch for each task, code, testing, docs they might need to check, how to test it. Give them the whole plan as bite-sized tasks. DRY. YAGNI. TDD. Frequent commits.
Assume they are a skilled developer, but know almost nothing about our toolset or problem domain. Assume they don't know good test design very well.
Announce at start: "I'm using the writing-plans skill to create the implementation plan."
Save plans to: docs/plans/YYYY-MM-DD-<feature-name>.md
If the spec covers multiple independent subsystems, it should have been broken into sub-project specs during brainstorming. If it wasn't, suggest breaking into separate plans — one per subsystem. Each plan should produce working, testable software on its own.
Every plan declares one scope mode. The mode shapes review depth, acceptable tradeoffs, and what counts as "done." Don't skip — pick one before drafting tasks.
| Mode | Use when | Rules | Evidence bar | |------|----------|-------|--------------| | prototype | Learning, demo, throwaway | Mark shortcuts; prefer reversible changes; no broad refactors unless forced | Demo path + known-limitations list | | production-patch | Small safe fix, bug | Minimal diff; no opportunistic refactors; preserve existing behavior unless explicitly changed | Targeted tests + reviewer + low blast radius | | feature | User-visible work | Acceptance criteria required; demo path required; product-risk review required | Acceptance criteria satisfied or explicitly waived | | architecture | Structural/cross-cutting change | Alternatives considered; migration + rollback plan; blast-radius analysis; staff-session likely | Tests + architectural review + risk ledger | | spike | Discovery, "is this feasible?" | Throwaway code allowed; answer the learning question; do not polish unless asked | Findings + recommendation + next step |
If you can't pick confidently, the scope is under-specified — push back to the PM (see "Definition of Ready" below) before drafting tasks.
YK reviews shape, not just correctness — "why this many threads?", "why single-threaded when parallel is 30 lines?", "is this YAGNI legitimate or laziness in a costume?", "have you considered a different shape?" They run as a primary reviewer at merge time on user-visible work, perf/concurrency-touching changes, and patches in patch-accumulating areas. See agents/vp-product.md for the full lens.
The plan is where the wrong shape gets baked in. A plan that picks single-threaded execution, naive polling loops, synchronous calls where async would be more natural, or ad-hoc state where a state machine wants to live — that plan will produce code that walks into a YK finding. Fix it at the plan stage, not at merge.
While drafting, walk the YK questions against your own plan before you save it:
## Alternatives Considered section.The point is not to write a YK simulation in every plan. The point is to internalize the questions so the spectre of the review keeps the planner honest — exactly the way the spectre of Patrik's review keeps engineers writing better code in the first pass. If every plan reaches YK and gets APPROVED_WITH_NOTES, the system is working as designed: the actual YK dispatch is a belt-and-suspenders backstop, not a gatekeeper catching laziness that should have been caught earlier.
If a YK question doesn't have a confident answer at plan time, that's a signal — name the open question in the plan rather than ship the unexamined choice.
Before writing tasks, confirm each item or explicitly waive it. If multiple are missing, recommend brainstorming or a spike instead of a plan.
If two or more checkboxes can't be filled honestly, the plan isn't ready. Surface to the PM with a specific ask, not a draft full of TBDs.
Plans default to decisions, not questions. Reviewer-facing questions in the plan body indicate undelegated decisions the author had context to make. Decide; surface only the genuine tradeoffs.
Before dispatching a build-task agent or entering plan mode for a non-trivial feature, walk through these five gates. Any "no" demands more investigation, not bigger agent dispatch. NOT a numeric score — the checklist is the gate.
Negative-Search Before Drafting below for the formal greppable procedure.)Codebase Research (before file mapping) above for the survey discipline.)Codebase Research (before file mapping) above.)Five greens → dispatch. Any red → loop back to investigation tier 1-3 or escalate to PM.
Read CONTEXT.md if present at the project root; if absent, proceed silently — do not flag, suggest, or scaffold. Use canonical terms throughout the plan — and for any term on the _Avoid_: lists, substitute the canonical term silently. If the plan introduces a new domain term that will recur across sessions, append it to CONTEXT.md as part of the plan-writing pass.
Project-rag is project-scoped. It indexes ONE specific codebase, configured at install time. Before reaching for mcp__*project-rag* tools, confirm they index the codebase you're investigating — not a different project on the same machine. If your target codebase doesn't have a project-rag index (no Saved/ProjectRag/ marker at its root, no --project-root argument pointing at it in the MCP config), skip this preamble entirely and use grep/Explore.
If MCP tools matching mcp__*project-rag* are available AND they index the codebase you're investigating, prefer them over grep/Explore for any code-shaped lookup. Symbol-shaped questions ("where is X defined", "find the function that does Y") → project_cpp_symbol / project_semantic_search. Subsystem-shaped questions ("how does X work") → project_subsystem_profile. Impact questions ("what breaks if I change X") → project_referencers with depth=2. Stale RAG still beats grep on structure. Fall through to grep/Explore only if RAG returns nothing AND staleness is plausible.
Before defining the file structure, check what's already been documented about the relevant systems. Read these if they exist (skip silently if they don't):
tasks/architecture-atlas/systems-index.md → relevant system pages in tasks/architecture-atlas/systems/docs/wiki/DIRECTORY_GUIDE.md → relevant wiki guides in docs/wiki/tasks/repomap.md (or task-scoped variant)This gives you the structural context to make informed file-mapping decisions without redundant grep discovery. Use Glob/Grep after this to fill specific gaps — exact line numbers, recent additions not yet in the atlas, etc.
Substrate-verification at plan time. Verify substrate facts (file paths, framework names, helper APIs, line numbers) via ls/grep while authoring — not at completion. Two minutes of disk verification prevents the substrate-fact errors reviewers will catch on R1.
Periodic baselines drift — instruct read-current-and-increment, not match-spec. When a stub names a count, version, or baseline ("bump from 55 to 56"), absolute values rot between enrichment and execution. Phrase as "read current value and increment" so the math survives the gap.
Before committing to a prescribed shape, run a negative search to surface prior decisions that argue against what the plan proposes to introduce or restore.
Identify the central nouns/abstractions the prescription introduces or restores (e.g., a pattern name, an architectural layer, a specific tool or verb).
Search for those nouns paired with prohibition vocabulary. Grep tasks/lessons.md and docs/wiki/ for each noun alongside: do not, never, tear down, deprecated, forbidden, removed, do NOT. bin/query-records is also useful here for frontmatter-indexed records.
If a prohibition exists, the plan must do one of two things:
Reversal-verb hint: If §1 Objective uses any of restore, reintroduce, reconstitute, undo, re-add, or bring back, the plan author should consider suggesting a staff-session to the PM before approval. This is a suggestion only — the PM owns the call. Frame it as: "This plan reverses prior direction; PM may want a staff-session before approving execution."
External-doctrine proposals — independent location-challenge. When a peer audit or external review recommends a fix, never adopt the proposed location uncritically — proposals frame fixes from where they noticed the problem, which is rarely the cheapest place to apply them. Run an independent location-challenge before drafting: would an upstream surface (producer skill, hook, dispatch template) prevent the class of problem more cheaply than the proposed downstream patch?
Before defining tasks, map out which files will be created or modified and what each is responsible for:
This structure informs task decomposition — each task should produce self-contained changes.
Each step is one action (2-5 minutes):
Every plan MUST start with this header:
# [Feature Name] Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use /execute-plan to implement this plan task-by-task.
**Goal:** [One sentence describing what this builds]
**Status:** Pending review
**Scope mode:** [prototype | production-patch | feature | architecture | spike]
**Architecture:** [2-3 sentences about approach]
**Tech Stack:** [Key technologies/libraries]
## Acceptance Criteria
- [ ] [Testable criterion 1]
- [ ] [Testable criterion 2]
- [ ] [Testable criterion 3]
## Non-Goals
- [Explicitly out of scope — heads off mid-stream scope creep]
---
Why these fields are required:
/merge-to-main read it.The Status: field is part of the write-ahead protocol — it gets updated at every phase transition (review, enrichment, execution) so that crashed sessions leave unambiguous state. See ARCHITECTURE.md § "The Write-Ahead Status Protocol" for the full state machine.
### Task N: [Component Name]
**Files:**
- Create: `exact/path/to/file.py`
- Modify: `exact/path/to/existing.py:123-145`
- Test: `tests/exact/path/to/test.py`
**Step 1: Write the failing test**
```python
def test_specific_behavior():
result = function(input)
assert result == expected
```
**Step 2: Run test to verify it fails**
Run: `pytest tests/path/test.py::test_name -v`
Expected: FAIL with "function not defined"
**Step 3: Write minimal implementation**
```python
def function(input):
return expected
```
**Step 4: Run test to verify it passes**
Run: `pytest tests/path/test.py::test_name -v`
Expected: PASS
**Step 5: Commit**
```bash
git add tests/path/test.py src/path/file.py
git commit -m "feat: add specific feature"
```
Before a plan changes the semantics of a shared symbol — a state enum, gameplay tag, public field, or exported function signature — include a reverse-reference scan in the plan: list every consumer found via grep, IDE rename-preview, or equivalent tool. Plans that mutate shared contracts without enumerating consumers are incomplete and risk silent breakage across subsystems with no obvious compile-time signal.
Checklist: For each shared symbol the plan mutates, add a subsection that names every file/component that reads or depends on it. If the scan is non-trivial, make it an explicit plan step, not an assumption.
Before writing a plan or dispatching agents on a debugging or fix task, identify and run the smallest diagnostic that exposes ground truth — a test runner, curl probe, git show, or single inspect call. Target: < 60 seconds. This is the cheapest step in any plan and prevents hours of hypothesis-driven agent rework.
Framing rule: Hypothesis-driven dispatch without diagnostic data is a stuck-detection trigger. If you find yourself writing a plan section that says "the cause is probably X," stop and run the diagnostic first. (geneva T1.2, paired across writing-plans + systematic-debugging)
These apply to any plan that will be handed to an executor agent. Violations here are the most common source of scope bleed and unauthorized work.
"Restructure the cheatsheets" or "fix the auth module" is insufficient — an executor without a scope constraint will modify adjacent files, run scripts, and create unauthorized commits. Every executor-bound stub MUST include a constraint block:
**Scope constraint:** Only edit files matching `<pattern>`. Do NOT modify files outside that scope. Do NOT run scripts beyond `<allowed list>`. Do NOT create commits.
Name the allowed paths explicitly. If the stub says "update the config files," list them by path — don't rely on the executor to infer scope.
The Agent tool is single-level nesting — subagents cannot spawn further subagents. When a plan calls for an agent that decomposes work and "dispatches sub-tasks," that agent MUST be configured as a read-only planner:
Agent tool in its allowed-toolsexecute-* tools either (omni-tool gravity: if the tool is present, the agent will use it)If a plan step says "an orchestrator agent will analyze and dispatch," rewrite it: "orchestrator agent analyzes and returns a briefing; EM dispatches sub-tasks based on briefing."
When plan A depends on plan B — shared paths, asset names, API contracts — a reviewer of A in isolation cannot see contradictions with B. Plans that interlock require an explicit cross-plan reconciliation step:
In the plan document itself: If interlocking plans exist, add a **Depends on:** line in the header and a reconciliation checklist as the final pre-execution step. Do not leave this implicit.
When a plan step dispatches a teammate agent that needs MCP tools, use graduated ToolSearch in the teammate's prompt — never hardcode a single tool name prefix. MCP tool names vary across teammate spawn contexts (e.g., mcp__notebooklm__* vs mcp__plugin_notebooklm_notebooklm__*).
Graduated resolution order: select:exact → +prefix keyword fallback → graceful failure message. Any teammate prompt that names an MCP tool should follow this pattern; hardcoding a single prefix is a silent failure waiting for the next spawn context change.
Python-fallback / "if MCP missing, use Python" / "if X unavailable, fall back to Y" clauses are a structural fault — under firefight pressure executors pick the fallback every time, bypassing the canonical surface precisely when it most needs exercising. Fix is structural, not prose: remove the clause; convert the "missing verb" branch into an explicit Step 0 prerequisite that fails loudly.
Doc-doctrine corollary: Don't advertise the escape hatch in the README or stub preamble. When a primary path and a fallback both exist, the entry-point promotes one path only; the fallback file lives on disk but isn't surfaced.
When a plan proposes shared-file appends across N machines or sessions, prefer per-machine paths over "atomic per-block append" merge logic — the latter is a euphemism for "PM resolves merges at daily wrap." Per-machine files sidestep the conflict class entirely.
Plans that claim "fully independent files" still need EM-side file-overlap analysis before parallel executor dispatch. Trust-but-verify: a 30-second cross-check against the plan's file lists prevents two executors from racing the same file under independence assumptions.
Default to subagent dispatch over a new RPC verb when adding internal operations. When a plan proposes a new tool/verb/handler/CLI-job, ask first: can a subagent compose this from existing primitives via execute_python_code + inspect + extant MCP verbs? If yes, the plan should propose the dispatch path, not the new verb. The new verb earns its place only on (a) C++-only capability, (b) transactional state coupling that primitive composition cannot preserve, or (c) cross-call editor-state invisible in tool signatures. Never default to dispatch over an existing verb without explicit retire-justification — prior surface is the proven path.
Tag: [universal] — applies to any project_type using the coordinator pipeline.
After saving the plan, it MUST go through one review cycle before execution. This catches structural problems while they're cheap to fix — before enrichment and execution invest real work.
/review-dispatch — the plan document is the artifact**Review:** Reviewed by [reviewer name] on [date]. Ready for execution.
PM Override: If the PM explicitly says to skip review (e.g., "ship it", "straight to execution"), skip this gate and note in the header:
**Review:** Skipped per PM direction. Proceed to execution.
After the plan is reviewed (or review is explicitly skipped), offer execution choice:
"Plan reviewed and saved to docs/plans/<filename>.md. Two execution options:
1. Executor-Driven (this session) - I dispatch Executor agents per task following docs/wiki/delegate-execution.md, code review via /review-dispatch between tasks, fast iteration
2. Parallel Session (separate) - Open new session and run /execute-plan, batch execution with checkpoints
Which approach?"
If Executor-Driven chosen:
docs/wiki/delegate-execution.md to dispatch Executor agents/review-dispatchIf Parallel Session chosen:
tools
Orient session — preflight, load context, choose work
documentation
Wrap up finished work — capture lessons, update docs
development
Triangulate plan-claim / code-reality / review oracles to classify each plan into DELIVERED+REVIEWED / DELIVERED-UNREVIEWED / PARTIAL / IN-FLIGHT / ABANDONED. Run after any crash or 'did we actually finish what we think we finished?' moment.
testing
Check for a published coordinator update and advise a preserve-by-default migration path — never a blind overwrite.