AGENT SKILL

write-plan

Write an implementation plan. Use when the behavior is settled and how to build or fix it is open — a pinned cause, settled spec, hunt finding, or review comment. Not for deciding the behavior (write-specs) or multi-session work (frontier).

License 许可
MIT
最近更新
2026-11-15
Stars
★ 0
Forks
0

01 前言 Front Matter

name
write-plan
description
Write an implementation plan. Use when the behavior is settled and how to build or fix it is open — a pinned cause, settled spec, hunt finding, or review comment. Not for deciding the behavior (write-specs) or multi-session work (frontier).

03 SKILL.md 正文

Write Plan

It is read by a cold executor: a session with no memory of yours, possibly a cheaper model.

Three properties make a plan executable by that reader:

  1. Self-contained — every path, excerpt, convention, and command is in the file. "As discussed above" is a broken plan.
  2. Gated — each step ends in a command with an expected result, so the executor never has to judge whether it worked.
  3. Bounded — an explicit out-of-scope list, and STOP conditions that end the run.

Steps

1. Recon

Open every file the plan will name. Fan out research when the change touches more files than you can open in one pass — it maps callers and conventions while you route, and you still open what the plan names. Run every command it will cite — guessed commands are the most common way a plan dies on contact. Record git rev-parse --short HEAD. Note the conventions the change must match, each with one exemplar file to imitate.

Done when every path, symbol, and command destined for the plan has been verified against the repo, every convention the change must match has a linked exemplar file to imitate, and the SHA is recorded.

2. Route

Order the steps so the build stays passing between them — e.g., add the new path, switch the callers, then delete the old one. Where the change spans layers, make the first step a thin vertical slice and widen from there. Tests are steps, not a wish at the end — a step that adds behavior is worked test-first by tdd, so its Verify command is the suite.

Done when each step verifies on its own, and the step list reads in that order — every new path added before the caller switch, every caller switch before the deletion.

3. Write, then read it cold

Fill the template, then reread it as the executor. Wherever you filled a gap from memory, inline the missing fact.

Done when every Current state excerpt has been re-opened at its file:line and matched, every step is Gated, every file and symbol mention is a working relative link, every out-of-scope file is listed with a reason touching it is wrong, each STOP condition names a risk specific to this change, and every Verify and Done command has been run once and resolves (no command-not-found, unknown script, bad flag, or missing path), with its expected output naming the state after the step, not the state today.

Referencing

Every file, line, and symbol the plan names is a link, so the executor opens it instead of searching for it. A plan lives beside its spec as <name>.plan.md, under the referencing convention — paths relative to the plan file.

file [`src/lib/db.ts`](../../../src/lib/db.ts)
line [`db.ts:42`](../../../src/lib/db.ts#L42)
range [`db.ts:40-60`](../../../src/lib/db.ts#L40-L60)
symbol [`Pool.acquire()`](../../../src/lib/db.ts#L40)
requirement [`R2`](<name>.spec.md#requirements)
sibling spec [`<name>.spec.md`](<name>.spec.md)

Commands, flags, patterns, and expected output stay in plain backticks — nothing to open.

Template

# Plan: <imperative title — what is true once this lands>

> **Executor rules**: work the steps in order. Run every Verify command and
> confirm its expected result before moving on. On any STOP condition, stop and
> report the condition, the step, and the evidence.
>
> **Written against** commit `<short SHA>`, <YYYY-MM-DD>.
> **Drift check (run first)**: `git diff --stat <SHA>..HEAD -- <in-scope paths>`
> Its file list is what narrows the excerpt match: compare
> [Current state](#current-state) against the live code for every file it flags.
> A mismatch is a [STOP](#stop) condition.

## Goal

2–5 sentences: the problem, its concrete cost, what improves when this lands.
Requirements covered: [`R2`](<name>.spec.md#requirements), [`R5`](<name>.spec.md#requirements)
— or "none, this is a fix".

## Current state

The facts, inlined — every excerpt readable without opening another document:

- [`<path>`](<rel-path>#L10-L40) — its role here, and the lines that matter
- Short excerpts as the code exists today, each headed by its linked
  `file:line`, enough that the executor can confirm it is looking at the right
  thing
- Each convention to match, with its linked exemplar: "errors follow the
  pattern in [`result.ts:12-30`](<rel-path>#L12-L30)"
- Any decided constraint from a spec or ADR, quoted, with the source linked —
  the executor has not read those documents

## Commands

| Purpose   | Command | Expected on success |
| --------- | ------- | ------------------- |
| Typecheck | `<cmd>` | exit 0, no errors   |
| Tests     | `<cmd>` | all pass            |

## Scope

**In scope** — the only files to modify:

- [`<path>`](rel-path)

**Files out of scope** — leave alone even though they look related:

- [`<path>`](rel-path) — <why touching it is wrong>

## Steps

### 1. <imperative title>

Exactly what to do, with every file and symbol linked. Include the target shape
where it is load-bearing — the pattern to produce, not every line.

**Verify**: `<command>` → `<expected output>`

### 2. …

## Done

Machine-checkable. All must hold:

- [ ] `<typecheck cmd>` exits 0
- [ ] `<test cmd>` exits 0, including the new tests for <case>
- [ ] `git status` shows no files outside the in-scope list

## STOP

Stop and report if:

- The code at a [Current state](#current-state) location does not match its
  excerpt.
- A step's verification fails twice after one fix attempt — a second failure
  means the step's assumption is wrong, not its implementation.
- The fix appears to require an out-of-scope file.
- <the key assumption this plan rests on> turns out to be false.

## Notes

- What a reviewer should scrutinize, and anything deliberately deferred.
- Rollback, as commands — for migrations, deletions, and production data only.

Sizing

The full template is the default. For a change touching at most two files with no ordering constraint, drop Commands and Notes and keep every other section: run-plan's Orient runs the header's Drift check, its Stopping reads STOP, and Done's last box checks Scope. With no Commands table to fall back on, every step carries its own Verify line.

Secrets

Secrets never appear in a plan: reference file:line and the credential type, and recommend rotation.

Handing off

The plan is written, not trusted. Hand it to plan-hunt — a blind refuter kills dead steps cheaper than run-plan discovers them. A plan of at most two steps against files this session already read may go straight to run-plan; say which route you took and why.

A plan comes back from plan-hunt with a <name>.plan-hunt.md report when the hunt confirmed a finding. Revise it rather than rewriting it: fix each step or section a Confirmed finding names, re-run Recon for the files those fixes touch, update Written against if HEAD moved, and hand the plan to plan-hunt again. A Suspected finding is a check, not a fix: run its Settles it check, and change the step only if the check fails.

04 同仓库更多 Skills