planning-skills
Nine agent skills covering the planning loop, the contracts they share, and the budgets that keep the set from growing into something nobody can route through. Each skill owns one phase and produces one artifact.
No planning skill writes code or modifies application files. Output is
documents under plans/<slug>/ in the host project.
| Skill | Owns | Produces |
|---|---|---|
planning-router |
Classifying the request and picking the chain | Nothing of its own |
planning-frame |
The problem, stated | 00-brief.md |
planning-discover |
What is actually true | 10-context.md |
planning-options |
The approaches, and which one | 20-options.md |
planning-decompose |
The work, sliced and sequenced | 30-plan.md |
planning-estimate |
How long, as a range | 35-estimate.md |
planning-risk |
What could go wrong | 40-risks.md |
planning-review |
Whether it is ready to act on | 50-review.md |
planning-replan |
What it becomes once reality diverges | changelog.md |
The three ideas the set is built on
A plan cannot be run, so every claim carries where it came from.
[verified: <pointer>] — read, run, or cited, with the pointer.
[assumed] — needs a matching A-n and a cost of being wrong.
[unknown] — needs a matching Q-n. An untagged claim in a decision-bearing
section is a defect, and a pointer-less [verified] is [assumed] wearing a
better tag. UNVERIFIED is the residual class that matters here: every
other one is visible in the plan, while an unverified assumption reads exactly
like a fact.
Over-planning is a failure of the same weight as under-planning. The tier
(S / M / L) is read off the work and declared at the top, and the planning
gate stops a run before it starts — a goal that needs "and", no measurable
criterion, a cheap unverified assumption, or a person who has already decided
and is asking for execution.
A range nobody ever scores is not a forecast. Estimating in ranges already
sounds rigorous, so the practice survives without being checked: ranges are
produced, work takes what it takes, and the next range comes out of the same
method with the same confidence. So every range is scored once its work closes
— within, under, over, open, abandoned — with the ratio of actual to
midpoint beside it, on the original range and never the revision.
A record of ten within in ten is a defect, not a result: ranges that would
have contained almost any outcome carry no information. The record attaches to
the method and the kind of work, never to a person — a record used to grade
someone stops being honest within one cycle
(_planning/CALIBRATION.md).
How it is put together
A skill is loaded in three stages. The listing carries name and
description only, on every turn. SKILL.md is read in full once a skill
is chosen. Anything it points at is read only when the situation calls for it.
Selection happens on the description alone, so every word that selects a
skill appears literally in its description, and
planning-registry/capabilities.yaml
lists those words per skill. A rule checks the two agree.
Boundaries live in one file — that same registry's not:. Descriptions
never name a neighbour. If they did, adding a tenth skill would mean editing the
other nine.
Contracts are delivered, not referenced. The operative part of each contract
is copied verbatim into every SKILL.md between <!-- deliver:… --> markers;
make render writes it back and a rule fails on drift.
Knowledge splits by whether it rots. playbooks/ holds judgement and is
budgeted. reference/ holds what goes stale — the artifact templates, whose
sections change when the artifact set does — carries no line budget, and states
its purpose and a checked-on date instead.
Where the set does arithmetic, the arithmetic is measured.
sizing.md defined σ per task and the estimate template asked for a critical
path total; nothing joined them, and the obvious route — add the optimistic
values, add the pessimistic ones — puts both endpoints outside the achievable
range. Twelve tasks of [2/3/8] sum to 24 … 96, where the simulated p10–p90
is 39.6 … 48.6 and no run in 200,000 landed at either end.
aggregation has the
method that does work (means add, σ adds in quadrature), the parallel-merge cost
that grows with the number of tracks, and the point where the independence
assumption fails. make figures holds every figure in it against a generated fixture — in
make check and the pre-commit hook, in hundredths of a second — and
make figures-full re-derives that fixture from the seed in about a minute. The
fast tier catches the realistic failure, a number edited in the page; the slow
tier is the only thing that catches a stale fixture, so it runs when the model
changes rather than never.
Budgets are enforced, not intended.
planning-registry/harness.yaml holds every
threshold; planning-tools/validate.py decides them and CI fails on a violation.
Names, and why none of them are generic
A skills directory is flat and shared with every other set on the machine, so a
generic name placed there is a silent collision — _common in that directory
already belongs to an unrelated set.
One declaration. set: planning in the harness file is the only place the
name is written; the prefix, the shared directory (_planning/), and the label
every document carries all derive from it.
Every directory this set owns carries the set name. The exceptions are named
by the platform, not by the set: .claude-plugin/ and skills/ are where the
plugin format expects them. Carrying the prefix is not what makes something
installable — a skill is a directory holding a SKILL.md, and only those are
linked.
Everything a skill reads lives inside the skill, reached through symlinks
named _planning and registry. Relative paths are normalised lexically, so
../_planning/X.md written inside a SKILL.md does not travel back through the
install symlink — a shell follows the link and finds the file, which is what
makes this fail quietly. Seventeen such references were what this set carried
before.
Files
| File | What it fixes |
|---|---|
skills/_planning/CONTRACT.md |
Evidence tags, confidence, status, residuals, the sweep |
skills/_planning/SIZING.md |
The tier, the planning gate, and the brief |
skills/_planning/ARTIFACTS.md |
Where output lives, the ID scheme, the decision record, language |
skills/_planning/HANDOFF.md |
What passes between phases, and the seven checks the receiver runs |
skills/_planning/VALUES.md |
The order when two goods conflict, and the escape hatch |
skills/_planning/ROUTING.md |
Guidance. Which phase owns the call when two could take it |
skills/_planning/REPORT.md |
What a person reads: the order, the ceiling per tier, and why the artifacts are the record |
Layout
planning-skills/
├── README.md
├── Makefile
├── .claude-plugin/plugin.json # named by the plugin format
├── planning-registry/ # budgets, boundaries, routes, delivered blocks
├── planning-tools/ # validate · test_validate · render · pre-commit
└── skills/ # named by the plugin format: skills live here
├── _planning/ # contracts in force on every run
└── planning-<phase>/
├── SKILL.md # Owns / Before starting / Decide first /
│ # Always·Never / Verify with / Done when
├── _planning -> ../_planning
├── registry -> ../../planning-registry
├── playbooks/ # judgement. Budgeted, and must not rot
└── reference/ # the artifact template. No line budget, dated
Working on it
make check # what CI runs: the rules, then proof the rules still fire
make render # after editing anything in planning-registry/delivered/
make hooks # run the rules on every commit
Installing
As a plugin. Add this repo; skills/ ships whole, so _planning/ travels
with the phases.
As individual skills.
make link # into ~/.claude/skills
make link CLAUDE_DIR=.claude/skills
Each planning-* skill is linked individually and reaches its contracts through
the symlinks inside it. Nothing un-prefixed is copied anywhere.
What this does not guarantee
allowed-toolsis one CLI's mechanism. Where a tool grant is not enforced, theNeverlines are discipline and nothing more- Nine skills is the closest this family comes to the point where selection degrades. The threshold for splitting the set is in the harness file
- The fixtures do not model how a model chooses. They catch a missing or duplicated signal, not a misroute
Verified:dates are not checked against anything. A stale reference file with a fresh date passes- Nothing here checks that a plan's tags are honest. The contract says every
claim carries one; whether
[verified]was earned is read by a person - The path checker assumes symlink delivery. Under a plugin the tree ships whole and the same paths resolve, but a distribution that copies skills individually would need the checks designed again
The published overview
docs/index.html is a generated page — every figure on it is
read off this repository, the way make figures recomputes what the reference
layer states. Do not edit it by hand: tools/pages.py in the agent-toolkit
repository writes it, tools/pages.py --check fails when it is behind, and
.github/workflows/pages.yml here only publishes what is committed.
No comments yet
Be the first to share your take.