Plan Doctor
A standards reviewer for engineering plans. When the user is planning work, this skill makes sure the plan meets a set of baseline requirements before execution begins.
When this skill does not apply
Single-file edits, bug fixes, code review, questions that want an answer rather than a plan, and work already under way under a plan the user agreed to. Say so in one line and get on with the work — don't impose ceremony on simple work.
If the task is complex (3+ files, new service, new feature, cross-module refactor) but the user never asked for a plan, produce one anyway and run it through the checklist below before writing any code.
What to do
Run through the checklist below before presenting the plan, and keep it in force for the rest of the task. Skills are read once and not re-read on later turns, so treat every check as a standing instruction rather than a one-time step — the completion gate in §3 is satisfied when the formatter and linter actually pass at the end of execution, not when you write the words into the plan.
Each check carries its own applicability test. A check that doesn't fire produces no output at all — not a step, not a mention. If a check needs information you don't have, look it up; don't guess.
1. Dependency and runtime currency
Every dependency, runtime, language version, or framework the plan introduces or upgrades must be pinned to a specific version, and that version must be the current LTS (where the ecosystem ships LTS releases) or the current stable major — verified this session, not recalled. This file deliberately contains no version numbers of its own: any it listed would be stale by the time you read them.
This applies to new choices. Dependencies the project already pins are out of scope — don't turn a feature plan into an upgrade plan. If an existing pin is a genuine blocker or a live CVE, raise it as a separate line item, not a silent bump.
How to verify, in this order:
- The project.
.nvmrc,.python-version,go.mod,package.jsonengines, Dockerfile base images, the CI matrix. An existing pin beats any external "latest" — deviating from it is a decision to surface, not a default. - The registry, from the shell. No network tool needed and it's the source of truth:
npm view <pkg> version,python3 -m pip index versions <pkg>(experimental, andpipis often not onPATH),go list -m -versions <mod>,cargo search <crate>. - Web search, if this host has one — Claude Code calls it
WebSearch; other hosts differ, so use whatever is actually in your tool list. For release-cadence questions like "which Node major is Active LTS",endoflife.date/<product>is machine-readable and dated. - A documentation MCP server such as Context7, only if one is connected, and only when you need version-specific API guidance rather than a version number. Read the tool names off the connected server — they differ between builds.
If none of these are available, say so in the plan. Write "unverified — could not check current versions from this environment" next to the version. A guess presented as verified is worse than an admitted gap.
If the user proposes an outdated version, call it out with the current recommended version and a one-line reason. Don't silently override — surface the swap so they can confirm. If they have a hard constraint (legacy system, vendor lock), respect it but note the risk.
2. Parallel execution
Only when the plan has 3 or more genuinely independent tracks — work that proceeds without waiting on the other tracks and without editing the same files (e.g. scaffold a service + draft the API spec + wire two separate client modules) — name them explicitly:
Run these in parallel: [track A], [track B], [track C].
Then pick the mechanism this host actually has; don't assume one. In Claude Code the choice turns on whether the workers need to talk to each other:
- Subagents — independent tracks that just report a result back. This is the common case and the right default.
- Agent teams — only when workers must share findings and challenge each other mid-flight. Agent teams are experimental and off unless
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1is set, so verify before putting them in a plan. Teammates cannot spawn teammates, so this doesn't apply if you are already one. - On a host with no parallel-agent facility, drop the line — sequential is a valid plan.
Never write a plan step that depends on a capability you haven't confirmed exists.
Don't force it when there are fewer than 3 independent tracks, when the "parallel" tasks actually depend on each other, when they'd edit the same files, or when the work is small and sequential (a 4-step CRUD endpoint). Then say nothing at all — silence is fine, and "I considered parallelising and skipped it" is noise.
3. Formatter and linter as completion gate
Every plan that writes or modifies code must include this as an explicit final step:
Completion gate: run the project's formatter and linter. Both must pass with zero errors before the task is considered done.
For existing projects: auto-detect what's already there. Inspect the repo for config files and package.json / pyproject.toml / Cargo.toml / go.mod / Makefile / justfile entries pointing to a formatter, linter, or type checker. Use whatever the project already uses — even if it isn't the current community favorite. Consistency with the project beats picking the "best" tool.
For new projects: verify, don't recall. Use the same verification ladder as check 1. Prefer whatever the language's own toolchain ships — gofmt, cargo fmt, dotnet format — because official tooling doesn't go stale. Otherwise confirm the tool you're about to name is still maintained (recent releases, live repo) before it goes in the plan.
Never name a formatter or linter because this skill or your training data mentioned one. That is the failure mode this check exists to prevent.
What goes in the gate:
- A formatter, run in whatever check/diff mode that tool provides (
--check,-l,--verify-no-changes) — zero diffs. - A linter (zero errors; warnings are project-policy).
- A type checker, if the language has one and the project uses one (zero errors).
4. API contract for multi-module APIs
This applies only when the project has HTTP/REST endpoints and more than one module provides or consumes them (backend + frontend + mobile, or service A + service B).
When it applies, the plan should specify:
- Maintaining an OpenAPI spec as the source of truth.
- Generating or syncing client/server code from the spec (e.g.
openapi-typescript,openapi-generator,oapi-codegen,orval— verify the one you name is current). - Where the spec lives and which module owns it.
Framework auto-generated specs count. If the API is built with something that emits OpenAPI for free (FastAPI's /openapi.json, NestJS Swagger, Spring Boot springdoc, drf-spectacular), that satisfies "the spec exists". Just make sure the generated spec is the one consumers pull from, and wire codegen for the consumers.
For single-module projects or projects with no APIs, skip this check entirely.
5. Task list for long plans
If the plan has more than 5 steps, it needs a durable checklist rather than prose in the chat. Step count is the whole test — a 3-step plan that touches ten files, or runs over two days, still doesn't need a tracking file.
Sequence matters here:
- While planning, the checklist goes in the plan itself. Plan mode is read-only on most hosts — Claude Code blocks edits until the plan is approved — so do not try to create a file yet, and do not promise one you can't write.
- On approval, before step 1, write it out.
TASKS.md,PLAN.md, or underdocs/; name the path in the plan ("I'll track progress inTASKS.md"). If the host has a native task or todo tool, use that instead of a file — never maintain both. - Keep it current. Flip
- [ ]to- [x]as each step lands and save. Commit it only if the user is already having you commit this work; never commit on your own initiative.
Reference the path in the chat response — don't duplicate the contents inline.
6. Design tokens for UI/UX work
If the plan involves UI/UX work beyond a one-off tweak — new screens, components, theming, redesigns, design system work — it must include generating or using design tokens for consistency.
What this means in practice:
- Define tokens for color, typography, spacing, radii, shadows, motion (durations/easings), and z-index layers.
- Store them as the single source of truth — a
tokens.json/tokens.ts, CSS custom properties in a:rootblock, a Tailwind theme config, or a Style Dictionary setup. Pick whatever fits the stack; just have one place tokens live. - Reference tokens everywhere — components consume
var(--color-primary)ortheme.colors.primary, never a hardcoded hex. - If tokens already exist, extend them rather than introducing parallel values. Audit first.
When it doesn't apply: backend-only or CLI work, and tiny isolated style tweaks where introducing tokens would be over-engineering — but still prefer existing tokens if any exist.
For multi-module projects (web + mobile), share tokens across modules where feasible — export them in a format both can consume.
How to present the reviewed plan
- The plan itself — numbered steps with the standards baked in: versions pinned and verified, parallel tracks named if there are 3+, the completion gate as the final step, an API-contract step if applicable, the task-list path if applicable.
- A short "Standards applied" note at the bottom — 2-4 bullets listing the checks that actually changed the plan, plus any deviation you're flagging for confirmation. Checks that didn't apply produce nothing. Example:
Standards applied: pinned the runtime to the current Active LTS (checked this session, not recalled); three independent tracks run in parallel; the project's existing formatter, linter and type checker as the completion gate; tokens extended from the existing set.
Keep it short — it's a receipt, not a lecture.
When you edit a rule here, go find its examples. Rules and the examples that illustrate them drift apart, and the drift is almost always in remote examples — the ones far from the rule they demonstrate, like this receipt sitting ~90 lines from the parallelism rule it quotes. Adjacent examples stay correct because an editor sees them; remote ones don't.
What not to do
- Don't lecture the user about standards mid-plan. The Standards applied receipt is the only place standards get discussed, it lists what you verified and what you flagged, and it never lists checks that didn't apply.
- Don't impose an API contract, task files, or parallel agents on small work where they add overhead.
- Don't override a convention the project has already committed to. If
CLAUDE.md/AGENTS.md/ existing config contradicts a check here, the project wins — note the divergence in one line and move on. - Don't block the user if they have a legitimate reason to deviate (legacy constraints, explicit choice). Note the deviation and proceed.