A Claude Code skill state-machine driven iterative planning and execution protocol for complex coding tasks
Overview
Turn an agent loose on something big and a familiar failure shows up. It plans once, starts strong, then hits a wall. It patches the wall. The patch breaks something else, so it patches that. A few turns later it has forgotten which fixes it already tried, the codebase is a thicket of half-reverted experiments, and nobody — human or model — can say what state anything is in. The root cause is not intelligence. It is memory. Push enough tokens through it and the early decisions blur, the failed approaches fade, and the agent starts relitigating settled ground. Iterative Planner gives the agent a disk. Every finding, decision, pivot, and dead end is written to the filesystem the moment it happens — structured, indexed, and re-read on a schedule. The work is driven by a six-state machine: . The context window can forget. The plan directory does not. The context window is RAM. The filesystem is disk. Truth lives on disk. And here is the part that sneaks up on you.
README
Iterative Planner
A Claude Code skill that stops an agent from losing the plot halfway through a hard task.
Turn an agent loose on something big and a familiar failure shows up. It plans once, starts strong, then hits a wall. It patches the wall. The patch breaks something else, so it patches that. A few turns later it has forgotten which fixes it already tried, the codebase is a thicket of half-reverted experiments, and nobody — human or model — can say what state anything is in.
The root cause is not intelligence. It is memory. The context window is RAM: fast, volatile, and it rots mid-task. Push enough tokens through it and the early decisions blur, the failed approaches fade, and the agent starts relitigating settled ground.
Iterative Planner gives the agent a disk. Every finding, decision, pivot, and dead end is written to the filesystem the moment it happens — structured, indexed, and re-read on a schedule. The work is driven by a six-state machine: Explore → Plan → Execute → Reflect → Pivot → Close. The context window can forget. The plan directory does not.
The context window is RAM. The filesystem is disk. Truth lives on disk.
And here is the part that sneaks up on you. Those files are not just scratch space for one task — they are a record the next task inherits. Every plan leaves behind findings, decisions, hard-won lessons, and a living map of the system it worked on. So the agent stops starting cold. It begins each new job already knowing the terrain, and that knowledge compounds: the tenth plan is sharper than the first because it stands on the nine before it. This tool is least impressive on day one and most valuable on day thirty — it quietly gets better at your codebase the more you use it.
Use it for refactors, migrations, debugging, system design, or deep research — anything where “just do it” quietly turns into a mess.
At a Glance
Say “plan this” and here is what actually happens:
- The agent explores first — reading the codebase, not guessing at it — before proposing anything.
- A written plan comes back for your approval before any code changes.
- Work proceeds one step at a time, each one committed, so a bad turn is a
git revert, not a rewrite. - Progress is checked against the plan as it goes, and the plan adjusts if reality disagrees with it.
This is one skill file plus a handful of scripts — no server, no extra service to run. See Get Started to install it, and A Worked Example to see the whole loop on a real task.
Table of Contents
Start here
Reference How It Works · The Plan Directory · Bootstrapping · Sub-Agent Architecture · Presentation Contracts · Validator · Git Integration · FAQ
Project Contributing · Project Structure · Sponsored by · License
When to Use This
Reach for it when the task is big enough that “what did I already try?” is a question you expect to ask. Skip it when the answer is already in front of you.
| Use it | Skip it |
|---|---|
| Multi-step tasks touching 3+ files or 2+ systems | Single-file, single-step changes |
| Migrations, refactors, architectural changes | Well-known, straightforward solutions |
| Tasks that have already failed once | Quick fixes where you already know the answer |
| Complex research or analysis with many moving parts | One-shot questions |
| System design and technical decision-making | |
| Debugging where the root cause is unclear | |
| Anything where you’d benefit from “what did I already try?” |
Trigger phrases: “plan this”, “figure out”, “help me think through”, “I’ve been struggling with”, “debug this complex issue”.
Get Started in 60 Seconds
Requires: Node.js 18+ (for the bootstrap and validator scripts). No npm install, no runtime dependencies — the scripts are plain ESM on Node builtins.
Option 1 — Zip package (recommended)
Download the latest zip from Releases and unzip into your local skills directory:
unzip iterative-planner-v*.zip -d ~/.claude/skills/
The unzipped skill already contains the sub-agent definitions at ~/.claude/skills/iterative-planner/agents/*.md. To enable parallel agent dispatch (explorers in parallel, a dedicated verifier, an adversarial reviewer), copy them into Claude Code’s shared agents directory:
mkdir -p ~/.claude/agents
cp ~/.claude/skills/iterative-planner/agents/*.md ~/.claude/agents/
The skill works without this step too — sub-agents are an optimization layer, not a requirement.
Option 2 — Single-file skill
Download iterative-planner-combined.md from Releases and add it to Claude Code’s Custom Instructions (Settings → Custom Instructions).
The single-file version does not include
bootstrap.mjsor the sub-agent definitions (src/agents/*.md) — no agent files ship with this option at all. The combined file runs in SKILL.md’s single-thread monolithic-fallback mode. Plan directories must be created manually. For full bootstrap and sub-agent support, use the zip package.
Option 3 — Clone and install
git clone https://github.com/NikolasMarkou/iterative-planner.git
cd iterative-planner
make build
cp -r build/iterative-planner ~/.claude/skills/
To enable parallel agent dispatch (explorers in parallel, a dedicated verifier, an adversarial reviewer), copy the sub-agent definitions from source into Claude Code’s shared agents directory:
mkdir -p ~/.claude/agents
cp src/agents/*.md ~/.claude/agents/
The skill works without this step too — sub-agents are an optimization layer, not a requirement.
cp -r above is fine for a first install, but it only ever adds files — it can’t remove one that was deleted upstream, so re-running it after a git pull leaves orphans behind. To update an existing from-source install, git pull then run the sync target instead:
make sync-skill # Unix/Linux/macOS
.\build.ps1 sync-skill # Windows
This prunes before copying and verifies every synced tree with diff -rq, so deleted files actually disappear from the install.
First run
In any project directory, give Claude a complex task or just say “plan this”. Claude runs bootstrap.mjs new "", drops into EXPLORE, and walks the cycle.
A new release does not retroactively update an already-installed skill — re-run the relevant install step to pick up a new version: re-download and unzip for Option 1, re-download for Option 2, or git pull + make sync-skill for Option 3.
A Worked Example
Watch one full cycle, condensed. Nothing here is a mock-up — this is the shape every plan takes.
You: “I want to migrate our auth from session cookies to stateless JWTs. Plan this.”
Claude (EXPLORE) runs bootstrap.mjs new "Migrate auth from session cookies to JWT", creates plans/plan-2026-05-07T091743-a3f1b2c9/, then:
- Reads
plans/FINDINGS.md,plans/DECISIONS.md,plans/LESSONS.md,plans/SYSTEM.mdfor cross-plan context. - Spawns 2-3
ip-explorersub-agents in parallel: one maps the auth surface, one inventories existing JWT usage, one examines the test suite. - Writes results to
findings/auth-system.md,findings/jwt-current.md,findings/test-coverage.md. - Classifies constraints: HARD (existing OAuth providers must keep working), SOFT (team prefers
joseoverjsonwebtoken), GHOST (a 5-year-old comment about Redis cluster topology that no longer applies).
Claude (PLAN) writes plan.md with:
- Problem Statement — expected behavior, invariants, edge cases.
- Steps — each annotated
[RISK: low/medium/high]and[deps: N,M]. Riskiest first. - Success Criteria + Verification Strategy — every criterion has a test command and a pass condition.
- Assumptions — each traced to a finding.
- Failure Modes — what if the JWT library is slow, returns garbage, or is down.
- Pre-Mortem & Falsification Signals — “STOP IF p99 latency increases more than 20ms.”
Claude presents the plan as a PC-PLAN block: the goal, a short summary, every step verbatim, and the path to plan.md for the rest — the sections above are long, and chat is the wrong place to read them. You approve or push back. If you push back, Claude revises and re-presents the same contract.
Claude (EXECUTE) implements step 1. After each file edit, an entry is appended to changelog.md recording timestamp, step, commit, file, op, blast-radius score, decision-ref, and reason. After each successful step:
plan.mdstep marked[x].progress.mdupdated.state.mdchange manifest extended.- Commit:
[plan-2026-05-07-a3f1b2c9/iter-1/step-1] add JWT verifier.
If a step fails: revert uncommitted, two fix attempts max, each constrained by the Revert-First and 10-Line rules. Both fail → STOP, present, ask you.
Claude (REFLECT) runs the verifier. The PASS/FAIL table from verification.md is rendered verbatim in the PC-REFLECT block. If it is iteration 2+ (or earlier by orchestrator choice — e.g. an iteration-1 attack-before-release pass ahead of a release/version bump), an ip-reviewer sub-agent runs an adversarial review and its concerns are folded in verbatim. Claude recommends close, pivot, or explore (or execute for a same-iteration completion-fix loop). You decide.
Claude (CLOSE) spawns ip-archivist to write summary.md, audit # DECISION plan-2026-05-07T091743-a3f1b2c9/D-NNN anchors in source, rewrite plans/LESSONS.md (≤200 lines), and rewrite the plans/SYSTEM.md atlas (≤300 lines). Then bootstrap.mjs close merges per-plan findings and decisions into the consolidated cross-plan files (sliding window of the 25 most recent plans).
The next plan starts with all of this on disk, waiting to be read.
Why This Works
Five ideas separate this from “ask Claude to make a plan.”
1. Memory that outlives the context window
Everything that matters lives on disk, not in the conversation. State, decisions, findings, progress, and verification results survive restarts, compression, and topic drift. Mandatory re-reads keep the agent anchored: state.md is re-read every 10 tool calls; after 50 messages, state.md and plan.md are re-read before every response. The window can rot. The plan directory is the disk that does not.
2. It compounds — the more you use it, the smarter it starts
This is the biggest second-order effect, and the easiest to miss. A single plan is a useful artifact. A history of plans is something else entirely: an understanding of your system that deepens every time you run one.
When a plan closes, its findings and decisions merge into consolidated files at the plans/ root, and the next plan reads them during EXPLORE. Migrations build on earlier debugging sessions; design plans inherit constraints found in prior research; failed approaches stay visible so nobody walks into the same wall twice. A sliding window keeps the consolidated files to the 25 most recent plans — plus every older section whose plan directory has since been deleted, because that section is then the last surviving copy. plans/INDEX.md indexes them all.
At the center of this sits the system atlas (plans/SYSTEM.md): a curated, domain-neutral map of what the system being planned against actually is — Identity, Components, Boundaries, Invariants, Flows, Known Patterns. Capped at 300 lines, rewritten at CLOSE, read at the start of every EXPLORE and PLAN. It is why the agent walks into each task already understanding your codebase instead of rediscovering it from scratch — and because the atlas is rewritten at the close of every plan, that understanding gets sharper with use. The curve bends the right way: the work gets easier as the map gets better.
3. Research that catches itself lying
Every discovery is written to findings.md with file paths, code-path traces, and evidence. The agent cannot advance to PLAN until it holds at least 3 indexed findings covering problem scope, affected areas, and existing patterns. When execution proves a finding wrong, that finding gets a [CORRECTED iter-N] marker — the original stays put for traceability. Being wrong is recorded, not erased.
4. The autonomy leash
When a step fails during EXECUTE, the agent gets 2 fix attempts, each constrained to reverting, deleting, or a minimal change. If neither lands, it stops, reverts uncommitted changes, presents what happened, and asks you. No silent third attempt. No “one more try.” This single rule is what makes unattended agent work safe to leave running.
5. When in doubt, subtract
The default response to failure is to simplify, never to add: can I fix this by reverting? By deleting? With a one-line change? If none of those — stop and enter REFLECT. Hard limits enforce the instinct.
The rigor is not improvised turn by turn — each state ships with domain-agnostic thinking tools baked in.
And three mechanisms keep the workspace honest, all of them auditable on disk.
That’s the pitch. Everything from here is reference: the exact mechanism, every file, every gate.
How It Works
Six states, one loop. Every transition is logged, every decision recorded, and the filesystem — not the conversation — is the source of truth.
stateDiagram-v2
[*] --> EXPLORE
EXPLORE --> PLAN : enough context
PLAN --> EXPLORE : need more context
PLAN --> PLAN : user rejects / revise
PLAN --> EXECUTE : user approves
EXECUTE --> REFLECT : phase ends/failed/surprise/leash
REFLECT --> CLOSE : all criteria met
REFLECT --> PIVOT : failed / better approach
REFLECT --> EXPLORE : need more context
REFLECT --> EXECUTE : same-iteration completion-fix
PIVOT --> PLAN : new approach ready
CLOSE --> [*]
The runaway brake. Iterations increment on each PLAN → EXECUTE transition. At iteration 5 the protocol forces a decomposition analysis — carve the goal into 2-3 independent sub-goals that could each be their own plan. At iteration 6+ it hard-stops. This is the deliberate cure for the “just one more iteration” spiral that quietly destroys plans.
The Plan Directory
Everything the agent knows about a task lives in one directory. Peek inside and you can reconstruct the entire train of thought.
plans/
├── .current_plan # active plan directory name
├── FINDINGS.md # consolidated findings, newest first, sliding window of 4 plans
├── DECISIONS.md # consolidated decisions, newest first, sliding window of 4 plans
├── LESSONS.md # cross-plan institutional memory (max 200 lines, rewritten on close)
├── SYSTEM.md # system atlas, domain-neutral map (max 300 lines, rewritten on close)
├── INDEX.md # topic-to-directory mapping (survives sliding-window trim)
└── plan-2026-05-07T091743-a3f1b2c9/
├── state.md # current state, iteration, step, change manifest, transition log
├── plan.md # the living plan (rewritten each iteration)
├── decisions.md # append-only log of every decision and pivot
├── findings.md # index of discoveries (corrected when wrong)
├── findings/ # detailed research files (one per topic)
├── progress.md # done vs in-progress vs remaining
├── verification.md # verification results per REFLECT cycle
├── changelog.md # per-edit ledger (one line per file edit)
├── checkpoints/ # snapshots before risky changes
├── lessons_snapshot.md # LESSONS.md snapshot at close (auto-created)
└── summary.md # written at close
Directory naming — a plan directory is plan-YYYY-MM-DDTHHMMSS-XXXXXXXX (UTC timestamp, colon-free so it is legal on Windows, plus an 8-char hex tail). Directories created before v2.36.0 use the legacy shape plan_YYYY-MM-DD_XXXXXXXX; that shape is never generated again but is always still read — the pointer, retire, the # DECISION anchor scan, the consolidated-file sections, and the sliding-window trim all accept both grammars, so old plans and the anchors they left in your source keep resolving.
Templates for every file are in src/references/file-formats.md. Each file also has a lifecycle — which states write it, which read it, which never touch it — and the protocol enforces a read-before-write rule on every plan file: the writing agent must read first, even on the first update after bootstrap.
File ownership
One rule keeps parallel sub-agents from colliding: each file has a single owner. Only the owner writes; everyone else reads. Co-ownership is allowed only where writes are disjoint and never concurrent (the orchestrator sequences the writers), and each co-owner’s scope is named explicitly.
Bootstrapping
A single Node script manages every plan directory from your project root. You rarely type these by hand — Claude runs them for you — but they are the whole lifecycle, and worth knowing.
The command you will reach for most is resume: at the start of a new conversation, after compression, or any time the agent seems to have lost track, it reconstructs the current state from disk and prints a structured re-entry summary. The agent never starts over — it picks up from state.md.
Sub-Agent Architecture
The orchestrator coordinates eight specialized agents. Sub-agents cannot spawn other sub-agents — the orchestrator is the sole coordinator. And the whole layer is optional: if the agent definitions are not installed under ~/.claude/agents/, the monolithic skill drives the same state machine in a single thread.
When the skill activates with the definitions present, the conversation assumes the orchestrator role in-thread — it reads agents/ip-orchestrator.md and adopts it, rather than spawning a separate orchestrator. See src/SKILL.md “Orchestrator Role Assumption.”
Presentation Contracts
Sub-agents are invisible to you — only the orchestrator’s chat text reaches you, and disk artifacts are memory, not a user-facing channel. Left to its own devices, an orchestrator will collapse a critical artifact (the verifier’s PASS/FAIL table, the reviewer’s concerns, a leash-failure block) into a terse summary and quietly drop the detail you needed. Presentation Contracts forbid that: every user-facing transition is governed by a named contract that fixes when it fires, the ordered content, the fidelity (verbatim vs digest), and the minimum sections it must include.
Canonical definitions live in src/references/file-formats.md under “Presentation Contracts.” This closes the old gap where the protocol used single verbs (“Present”, “Report”, “Surface”) and the orchestrator defaulted to terse summaries.
Validator
src/scripts/validate-plan.mjs is a read-only protocol-compliance check. It runs automatically during REFLECT and can be run by hand any time. Exit 0 = pass, exit 1 = errors; warnings are non-blocking. A separate --pre-step mode runs before each EXECUTE step and HARD-blocks (exit 2) on a leash-cap, wrong-state, iteration-cap, or no-plan condition — the mechanism that turns the autonomy leash from advice into enforcement.
The validator cannot inspect chat content — it surfaces metadata signals only. Content fidelity is enforced by the agent prompts themselves.
Git Integration
Commits are the agent’s undo history, and the protocol is deliberate about when they happen.
| Phase | Git behavior |
|---|---|
| EXPLORE / PLAN / REFLECT / PIVOT | No commits. |
| EXECUTE (success) | Commit after each step: [plan-YYYY-MM-DD-HASH/iter-N/step-M] description. Tag id = the plan-dir name with the THHMMSS segment dropped (plan-2026-07-14T051317-317362c4 → plan-2026-07-14-317362c4); a legacy dir derives the same way with _ normalized to -. The changelog’s own step field carries no such prefix — it always names a numbered step, iter-N/step-M, or iter-N/step-M.K for a completion fix on step M. |
| EXECUTE (failure) | Revert all uncommitted changes to the last clean commit. |
| PIVOT | Decide: keep successful commits, or git checkout -- . to revert. Choice logged in decisions.md. |
| CLOSE | Finalizes on disk: writes summary.md, audits DECISION anchors, rewrites plans/LESSONS.md + plans/SYSTEM.md, merges the consolidated cross-plan files, then runs bootstrap.mjs close. No git commit or tag is created — a summarizing commit/tag at CLOSE is a documented, deferred spec item, not yet implemented (no agent or script issues any git commit/tag). |
Bootstrap automatically adds plans/ to .gitignore. Remove that entry if your team wants decision logs versioned for post-mortems.
FAQ
What if bootstrap refuses to create a new plan?
An active plan already exists. Use resume to continue it, close to end it, or new --force to close it and start fresh.
Can I have multiple active plans at once?
No. One active plan at a time, tracked by plans/.current_plan. Close the current plan before starting a new one.
Where do plan files go?
Always under plans/ in the project root. Bootstrap creates this directory automatically.
Are plan files committed to git?
No. Bootstrap adds plans/ to .gitignore by default. Remove it if you want decision logs versioned.
What if I want to start completely over?
Run bootstrap.mjs new --force "new goal". This closes the active plan (merging its findings) and creates a fresh one. All previous plan directories are preserved.
What happens at iteration 5? The protocol forces a decomposition analysis: identify 2-3 independent sub-goals that could each be a separate plan. At iteration 6+, execution stops entirely.
Can I run the agents in parallel? Explorers always parallelize. Verifiers can parallelize across independent checks. Executors never parallelize — exactly one runs at a time, because plan steps are sequential. The orchestrator sequences anything that touches the same plan file.
Do I need the sub-agent definitions? No. They are an optimization layer. Without them, the monolithic skill drives the same state machine in a single thread.
What if I lose context mid-plan?
Run bootstrap.mjs resume. It reconstructs the current state from disk and prints a summary. The agent never starts over — it picks up from state.md.
Why plan-qualified DECISION anchors?
The consolidated plans/DECISIONS.md uses a 25-plan sliding window. Bare D-NNN anchors become orphans once their plan is trimmed. Plan-qualified anchors (# DECISION /D-NNN) survive the trim and resolve unambiguously.
Contributing
The test suite covers bootstrap operations, state transitions, consolidated file management, sliding-window behavior, anchor validation, and edge cases — see the tests badge above for the current total, all on node:test with zero external dependencies.
VERSION is the single source of truth for the version number. Both Makefile and build.ps1 read from it. Bump VERSION and CHANGELOG.md; nothing else.
Project Structure
For the complete protocol specification, see src/SKILL.md.
Sponsored by
This project is sponsored by Electi Consulting, a technology consultancy specializing in AI, blockchain, cryptography, and data science. Founded in 2017, headquartered in Limassol, Cyprus, with a London presence. Clients include the European Central Bank, US Navy, and Cyprus Securities and Exchange Commission.
License
Recommended Tools
Try a different keyword or remove a filter.
Install
npx skillfish add nikolasmarkou/iterative-planner