---
name: manual-planning
description: |
Create, update, review, and execute manual Markdown implementation plans when harness planning
mode is not being used. Use when the user asks for a plan file, manual plan, implementation plan,
execution plan, roadmap, task checklist, planning document, or agent-maintained plan with
statuses, validations, milestones, approval gates, and cleanup steps. Also use when resuming or
maintaining an existing plan — marking a task complete, checking plan status, recording a
decision, or validating a plan file — even when the user does not say "plan file".
Triggers: plan file, manual plan, implementation plan, execution plan, planning document, plan
template, resume plan, update the plan, continue the plan, plan status, task checklist, roadmap,
milestones, exit criteria, approval gate, decision log, cleanup phase, check-plan, new-plan.
metadata:
version: "2.0.0"
---
# Manual Planning
Produce Markdown plans that another coding agent can execute without reinterpreting the original
conversation. A plan is an execution ledger, not a proposal: it has to stay accurate while it is
being worked through, and it has to be readable cold by a session that was not there when it was
written.
Anything that can be checked mechanically is checked by a script. Do not hand-verify what
`check-plan.py` verifies.
## Scripts
Standard library Python 3 only — no install step. Run with `python3` or `uv run`.
```bash
# Create a plan: correct name, correct directory, version stamped from this SKILL.md
python3 scripts/new-plan.py "
" [--milestoned] [--dir docs/plans]
[--exclude-locally | --tracked] [--force]
# Validate a plan (read-only). exit 0 = clean, 1 = errors, 2 = warnings only
python3 scripts/check-plan.py [--json] [--strict] [--dir docs/plans]
# Change one task's status, or read every status back
python3 scripts/plan-status.py set ""
python3 scripts/plan-status.py show
```
Each answers `--help`, which lists every check ID and exit code. Quote the status argument: three
of the five task statuses contain a space.
## Default Location
`docs/plans/YYYY-MM-DD--plan.md`.
The date in the filename is the date of record, which is why the metadata block carries no
`Created` or `Last Updated` field. `new-plan.py` produces both the directory and the filename, so
neither is a rule you have to remember. Avoid names like `notes.md`, `scratch.md` or `todo.md`.
## Plan Tracking
Default to not committing the plan. Follow the repo instead when it already has a convention: if
the plan directory holds tracked plans, this project commits them. Commit the plan when the user
asks.
If the plan stays untracked and its `??` entry interferes — a plan's own cleanup task validates with
`git status --porcelain` — add the plan directory to `.git/info/exclude` rather than `.gitignore`;
`.gitignore` is itself a tracked file, so editing it creates the commit you were avoiding.
`new-plan.py --exclude-locally` does this and stamps `Tracking: untracked (locally excluded)`.
## Plan Creation Workflow
1. Gather enough repository context to identify scope, dependencies, test surfaces, and likely
risks. Everything you learn here goes in `## Context For A Clean Session` — see
`references/context-and-evidence.md`.
2. Create the file with `new-plan.py`, choosing `--milestoned` for more than 10 tasks.
3. Fill in the template. Every factual claim carries evidence: a `file:line` reference, a section
reference (`SKILL_RULES.md §5`), or a re-runnable command.
4. Set `Plan Status` to `QUESTIONS PENDING` if clarification is required, then surface the
questions to the user. Mirror them in `Open Questions`.
5. Incorporate the answers, run `check-plan.py`, and paste its output into `## Plan Self-Check`.
6. Set `Plan Status` to `READY FOR APPROVAL` only when the checker is clean and the only remaining
gate is user approval.
Do not begin implementation until the user approves the plan, unless the user explicitly asks to
proceed without approval. When approval is given, replace the `## Approval Gate` boilerplate with
`Approved by on .` — the section is a record, not a standing instruction.
## Open Question Handling
Open questions are not plan-only notes. When clarification is needed, actively ask the user before
marking the plan `READY FOR APPROVAL`.
1. **Use the native question-asking tool** (`question`, `ask-user`, `request-input`, or whatever the
current harness exposes). Always prefer a structured tool over plain text.
2. If no such tool is available, send a concise formatted message in the conversation.
3. Record both the question and the user's answer in `Open Questions`.
4. After the user answers, replace the entry with the resolved answer, or the section with `None`.
Ask only questions that affect correctness, scope, risk, validation, sequencing, or approval. Do not
ask what the repository can answer or what can safely become a stated assumption.
**All open questions must be answered before the plan can transition to `READY FOR APPROVAL`.**
Do not combine unresolved clarifying questions and final approval in the same user prompt.
## Plan State Lifecycle
`Plan Status` in the metadata block is the authoritative plan-level state. It is modelled once —
there is no separate `Approval` field, because in the surveyed corpus the two contradicted each
other in 11 of 32 plans.
1. `DRAFT` while creating the first version.
2. `QUESTIONS PENDING` while waiting for required clarification.
3. `READY FOR APPROVAL` after clarification is incorporated and the checker is clean.
4. `APPROVED` after the user approves execution.
5. `IN PROGRESS` while implementation is underway.
6. `COMPLETED` after cleanup, `## Pre-flight Checks` and final verification all pass.
Use `BLOCKED` when planning or implementation cannot continue, and record the blocker.
## Plan Format Rules
Every plan has these top-level sections, which is what `check-plan.py` `E009` enforces:
`Metadata`, `Status Legend`, `Context For A Clean Session`, `Goal`, `Scope`, `Non-Goals`,
`Assumptions`, `Open Questions`, `Milestones` (or `Tasks` in a simple plan), `Project Gates`,
`Pre-flight Checks`, `Decision Log`, `Final Verification`, `Approval Gate`, `Plan Self-Check`,
`Execution Notes`.
The metadata block is exactly four fields:
```markdown
- Plan Status: DRAFT
- Plan Format: manual-planning v2.0.0
- Template: milestoned
- Tracking: untracked
```
Use exactly these task statuses: `TO BE DONE`, `IN PROGRESS`, `COMPLETED`, `BLOCKED`, `SKIPPED`.
Use exactly these plan statuses: `DRAFT`, `QUESTIONS PENDING`, `READY FOR APPROVAL`, `APPROVED`,
`IN PROGRESS`, `COMPLETED`, `BLOCKED`.
A status may carry a trailing annotation (`COMPLETED — 381/381 passing`); the vocabulary applies to
the leading token.
More than 10 tasks requires milestones. With 10 or fewer, omit milestones unless they clarify
independent delivery phases.
`## Project Gates` is where project-specific rules live — per-project lint/build/test commands,
manual-verification requirements, changelog or backlog bookkeeping. Put them there rather than
forking this skill for a project.
`## Pre-flight Checks` is a named checklist of the project's actual commands, run before the plan may
reach `COMPLETED`. It is distinct from per-task validation: per-task validation proves one task
worked, pre-flight checks prove the repository is shippable.
## Task Rules
Each task must include:
- `Status`: one of the task statuses.
- `Depends On`: `none`, or a list of task numbers.
- `Objective`: the observable outcome.
- `Steps`: concrete implementation steps.
- `Validation`: commands, tests, inspections, or self-checks that prove completion.
- `Notes`: constraints, affected files, or `None`.
**Task numbering is not an execution order.** `Depends On` is the order. Task 3.1 may be runnable
before Task 2.2.
Prefer deterministic validation — a test, build, linter, or exact file inspection. Where none is
possible, state the manual check in observable terms. Say explicitly when a validation passes by
producing no output: `grep` finding nothing exits 1, and so does `diff` on files that are meant to
differ. An executing agent that branches on `$?` will read those as failures.
## Milestone Rules
Each milestone must include `Status`, `Purpose`, `Exit Criteria`, and its tasks. Exit criteria must
be broader than any single task validation: they confirm the completed tasks work together and that
the next milestone can safely start.
## Implementation Workflow
1. Set the plan status to `IN PROGRESS` before starting implementation.
2. Before starting a task, set it to `IN PROGRESS` — `plan-status.py set "IN PROGRESS"`.
3. Complete the task.
4. Run the task validation. Before declaring it passed, check the task's `Steps` and `Validation`
for explicitly named tests (e.g. "add a test `test_foo_bar`"). **A green test suite does not mean
those tests were written — verify by name.**
5. Fix issues until validation passes, or mark the task `BLOCKED` with a reason.
6. Set the task to `COMPLETED` immediately after validation passes.
7. Update the milestone status when its tasks satisfy its exit criteria.
8. Start the next task only after the plan file reflects the current state.
If validation was intentionally deferred earlier, reconcile the plan text once the deferred checks
actually run. Leave no stale "validation pending" phrasing describing a state the plan has moved past.
**Discovered issues.** If a bug or unplanned problem is identified while working on a task, choose
one path immediately — do not defer via a mental note:
- Fix it in the current task if it is small and in scope.
- Create a new task in the plan with status `BLOCKED` if it is out of scope for the current task.
A bug that is noticed but neither fixed nor recorded will be forgotten. There is no third option.
## Decision Log
`## Decision Log` is always present, in simple and milestoned plans alike. Deviations, discovered
issues and deferred validations are the same shape of event and all land in this one append-only
section.
Write an entry **before moving to the next task**, never retrospectively. Entries written after the
fact are unreliable.
An entry is required when implementation diverges from what the plan specifies (different path,
signature, or approach), when a validation failure forces the plan to adapt, when an unplanned
problem is found, or when a validation is deliberately deferred. No entry is needed when execution
matches the plan, or for wording differences that change no outcome.
```markdown
### DEC-001 —
- Date: YYYY-MM-DD
- Task:
- Decision:
- Rationale:
```
Read `references/decision-log.md` when the inline log passes ~10 entries (`check-plan.py` warns with
`W005`), when the user asks for a companion decisions file, or when you are unsure whether something
qualifies as an entry.
## Cleanup Phase
Every plan must include a cleanup task near the end, removing intermediate artifacts that should not
ship: temporary documentation, one-off test cases, scratch scripts, temporary fixtures, generated
data, debug logs, local-only outputs, and obsolete plan fragments.
Do not remove artifacts the user asked to keep, artifacts required for future maintainability, or
generated files that are part of the repository contract.
**Changelog steps are conditional.** Add one only when the project actually has a changelog file.
`check-plan.py` `E010` looks for `CHANGELOG*` at the repository root and requires a task step
mentioning it only when one exists — a project without a changelog needs no changelog step.
## Plan Retirement
Untracked plans need no retirement step; deleting the file is enough.
Where plans are committed, the project owns the retirement convention, and `check-plan.py` must pass
before a plan is retired: in a tracked repo a misleading final state is permanent.
## Self-Check Before Approval
Run the checker and paste its output into `## Plan Self-Check` with the date:
```bash
python3 scripts/check-plan.py docs/plans/.md
```
Fix every error before requesting approval. Judge each warning on its merits and say in the plan why
any surviving warning is acceptable.
Do not replace this with a hand-ticked list. The v1 hand-ticked self-check passed in 32 of 32
surveyed plans and failed in none — including on a plan with no `Open Questions` section that still
claimed its open questions were explicit. It was a signature, not a gate.
## Gotchas
- **A deployed skill copy can be older than its repository.** Editing a repo changes nothing about
what runs if the deployed path is a copy rather than a symlink into it. Check what the path
actually resolves to (`readlink`, then read the file that comes back) before assuming an edit took
effect.
- **Task numbering is not an execution order.** That is what `Depends On` is for. Reading the
numbers as a sequence serialises work that was designed to run in any dependency-respecting order.
- **`.gitignore` versus `.git/info/exclude`.** `.gitignore` is tracked, so excluding an untracked
plan there produces the very commit the untracked default avoids. Use `.git/info/exclude`.
- **A plan that reaches `COMPLETED` with tasks still `TO BE DONE` is the single most common way a
plan ends up lying.** Three surveyed plans were closed with every one of their 18–26 tasks still
`TO BE DONE`. `E005` catches it; `plan-status.py` warns as soon as a write creates it.
- **Statuses are scattered.** A 26-task plan has 27+ status lines. Use `plan-status.py set`, which
rewrites exactly one line, rather than editing by hand and missing some.
- **A validation that passes by producing no output exits non-zero.** Read what the validation
asserts rather than branching on `$?`.
- **Greenfield plans cannot cite line numbers in files that do not exist yet.** That is why the
evidence check only hardens (`E011`) when the plan names files that already exist, and otherwise
only warns (`W003`).
## References
- `references/context-and-evidence.md` — read before writing `## Context For A Clean Session`, or
when a plan is being written for a session that will not have the originating conversation.
- `references/decision-log.md` — read when the inline decision log passes ~10 entries, when a
companion decisions file is requested, or when deciding whether an event qualifies as an entry.
## Resources
`new-plan.py` copies the right one; copy by hand only if the script cannot run.
- `assets/simple-plan-template.md` — 10 or fewer tasks.
- `assets/milestoned-plan-template.md` — more than 10 tasks.