by DevOtts
Turn a fuzzy idea into a buildable delivery package — discovery → spec → agile split, with a frozen CONTRACT and a binding Test Contract per epic. The planning front-end to /fable-it.
# Add to your Claude Code skills
git clone https://github.com/DevOtts/plan-itplan-it is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by DevOtts. Turn a fuzzy idea into a buildable delivery package — discovery → spec → agile split, with a frozen CONTRACT and a binding Test Contract per epic. The planning front-end to /fable-it. It has 1 GitHub star.
plan-it's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/DevOtts/plan-it" and add it to your Claude Code skills directory (see the Installation section above). plan-it ships a SKILL.md manifest, so compatible agents can discover and load it automatically.
plan-it is primarily written in JavaScript. It is open-source under DevOtts on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh plan-it against similar tools.
No comments yet. Be the first to share your thoughts!
Unlocks once the catalog security scan passes (runs nightly).
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
Take a fuzzy demand → ship a buildable delivery package. This is the planning
conductor: the disciplined front-half of the lifecycle that ends exactly where
/fable-it begins. It does discovery (research the ground truth), spec
(author the design docs), and agile split (PRDs, epics, tests, the shared
contract) — then hands off.
/plan-it ─────────────► docs/ + delivery/ ─────────────► /fable-it
(discovery → spec → plan) (the buildable package) (builds it)
Usable by a human directly, and by any orchestrating conductor agent that receives a new demand and must turn it into a delivery package before dispatching workers.
These are the load-bearing rules reverse-engineered from every successful run. If you violate one, the build downstream drifts or silently fails.
Freeze a shared CONTRACT before any parallel planning. The CONTRACT is the law: canonical entities, schema, API/interface, enums, repo/branch map, and the definition of "shipped." Squads write to it; any cross-cutting discovery folds back into it as a dated amendment (v1.0 → v1.1 …). No frozen contract → no parallel squads.
Batch every human-only decision into ONE gate. Do not pre-decide anything irreversible (repo topology, hosting, product name, architectural mode, build-vs-buy). Surface them together, each with a recommendation attached, and let the human answer numbered. This gate is where the human injects vision, not just picks options — leave room for them to add a concept you didn't propose. Lock each answer with owner + date.
Verify every agent's output on disk — "idle ≠ delivered." A team going idle
does NOT mean it wrote files. After any fan-out, check the actual paths exist and
are non-empty before proceeding. If a team held its output as a message, direct
it to Write to the exact absolute path. Never trust a "done."
Ground the plan against the LIVE system, not the repo — before you freeze. For any plan touching a running system, the repo is a hypothesis; the deployed reality is the truth, and they drift. Before freezing the CONTRACT, verify against the actual system and write the observations in (not repo-derived guesses). Battle-tested: in one program EVERY mid-flight correction traced to a repo-inferred assumption reality contradicted — wrong canonical identifiers (manifests had drifted from the deployed catalog), a config value that was present-but-pointing-at-a-dead-host, "to-be-built" components that were already deployed, and a found credential that was the wrong one. See Phase 3's live-grounding gate for the concrete checks.
Run the machine, not the prose. The pipeline's control flow lives in
machine.json (the explicit statechart), not in this document — this prose
explains the machine. On invocation, read or initialize .plan-it/state.json
(in the target project) and resume from its state; write it on every
transition. At every guarded transition, run the guard's mapped subcommand
(node scripts/gate-check.mjs <check> …) and never advance on a non-zero
exit — fix, re-run, then transition. If Node is unavailable, perform the same
checks manually and record them in the state file (degrade, never break). Full
protocol: references/machine.md.
Control flow written as prose ("do step 1, never skip the gate") is what the determinism literature calls prose control flow: it relies on the model's discipline across a long, summarization-prone context, and sometimes the model won't follow it. v2 inverts that at the right altitude — non-determinism at the edges, determinism at the core:
machine.json — XState v5-compatible statechart of the pipeline: 15 states,
the three human gates (meta.gate + meta.human), guarded transitions, and an
AMENDMENT self-loop on parallelPlanning. Paste into stately.ai/viz to see it..plan-it/state.json — the persisted run: current state, gate approvals
(owner + date), contract version, verified-artifact registry, history. This is
what makes a run survive a crash or a fresh session.scripts/gate-check.mjs — the guards as exit codes: verify (Rule 3,
idle ≠ delivered), freeze (Rule 1, no contract → no squads), handoff (the
mechanizable half of playbooks §F), state (Rule 2, gates recorded),
adversary (Rule 6 / D4 — failure-mode depth: a modelled machine must cover-or-
waive the five cascade classes; N/A for linear workflows). The LINT_CLEAN and
ADVERSARY_CLEAN transitions (verify → adversaryGate → handoff) gate on the
last two.The fuzzy phases — discovery, synthesis, spec authoring, judgment — stay
LLM-at-the-node (tagged llmAtTheNode in the machine). Do not formalize them;
modeling is not ceremony only when it replaces confusion. Details, state-file
schema, and the resume protocol: references/machine.md.
Hard enforcement (v2.1, plugin installs on Claude Code only): a PreToolUse
hook (scripts/hooks/planit-guard.mjs) denies Write/Edit calls on PRD/epic
deliverables while the run's contract is unfrozen — Rule 1 stops being an
instruction and becomes something the harness refuses. Fail-open: it never
touches non-plan-it work. Skill-only installs rely on Rule 5 discipline instead.
The single thing that most raises delivered code quality: every PRD/epic ends by
generating its own test contract — up to ~20 concrete use-cases/scenarios that
stress the implementation — and the feature is NOT "done" until 100% of them pass.
The build agent cannot just deliver the feature; it must satisfy the contract, and
/iterate until green.
This is a named, proven discipline: Specification by Example (Gojko Adzic) + ATDD/BDD for code (concrete examples become executable acceptance tests and living documentation), and Eval-Driven Development for skills/LLM features (register goldens with expected outputs, iterate until they pass). Authoring the cases at planning time is the whole point — they become a binding contract, not an afterthought.
Rules of the Test Contract:
/iterate. No
partial ship; no VERIFIED-on-a-mock (a [REAL] case whose target is unreachable
→ IMPLEMENTED-NOT-VERIFIED, never a fake green).| Implementation | Test types | How |
|---|---|---|
| CRUD / REST API | use-cases (happy+edge) + e2e | run every scenario via API and via UI with Chrome CDP (chrome-cdp-control); unit-test the logic |
| Skill / prompt / LLM function | use-cases w/ expected output | run it, compare real vs expected — exact match for closed outputs, rubric / LLM-as-judge for open ones (make-eval, promptfoo, DeepEval G-Eval) |
| Agent / stateful / multi-step | stress scenarios + use-cases | six axes: async, fan-out, escalation, human-gate, recursion, cycle-guard (Setup/Expected/Pass) |
| Pure logic / library | unit + property-based | enumerated cases + invariants |
| Data pipeline / migration | golden-value + e2e | hand-computed expected values; idempotency/rollback |
| Anything with load/abuse surface | stress / adversarial | concurrency, rate, malformed input, red-team |
/full-qa runs the contract, /iterate loops it to 100%,
chrome-cdp-control drives UI scenarios. The contract is the bridge from
plan-it → fable-it: /fable-it's Definition of Done = this contract.Grammars and the contract header format: references/formats.md (the Test Contract
block + §4–5).
Run research and authoring autonomously at high effort, but stop at three gates:
| Gate | When | What you ask |
|---|---|---|
| G1 — Scope | after intake (Phase 2) | confirm the sizing (feature vs program) + the numbered DoD before burning effort |
| G2 — Decisions | after specs drafted (Phase 7) | the batched "decisions only you can make," each with a recommendation |
| G3 — Delivery | before the agile split (Phase 8) | "specs look aligned — proceed to PRDs/epics?" |
Everything between gates runs unattended. Recommend /effort xhigh at the start
(you cannot set it yourself — tell the user to run /effort xhigh if they haven't).
Machine first (Rule 5): if .plan-it/state.json exists in the target project,
run node scripts/gate-check.mjs state .plan-it/state.json and resume from the
printed state — do not restart phases already in history. If it doesn't exist,
create it now in state intake (schema in references/machine.md) and keep it
updated on every transition for the rest of the run.
Accept the demand in whatever form it arrives: a brain-dump, a pasted
transcription, a list of wants, or a one-liner. Expect pointers, not content —
session names (/read-chat "<name>"), repo paths, doc folders. Your job is to go
fetch the ground truth, not to be handed it.
Capture up front:
02 §1).If the demand is genuinely one fuzzy paragraph with no pointers and an existing repo, that's fine — pre-grounding (Phase 3) will find the targets.
Restructure the fuzzy prose into a numbered, individually-verifiable Definition of Done + a short list of stated assumptions. This is your contract with the user for the planning job itself. Example shape:
DoD for this planning run:
1. Ground-truth findings doc (every claim → path:line or table)
2. Vision + architecture doc that solves each finding/contradiction
3. Data/interface contract
4. … (auto-sized — see Phase 2)
N. Handoff: contract frozen, PRDs+epics with ≥10 tests each, kickoff prompt
Assumptions: <list>
Pick size (how much) and shape (what form) before spending effort. Confirm both with the user.
Size scales the artifact count:
| Signal | Size |
|---|---|
| Single feature, 1 subsystem | S |
| Multi-feature / new subsystem, 1–2 repos | M |
| From-scratch program / many subsystems | L |
Shape is chosen by use-case (full definitions + the use-case→shape table in
references/templates.md PART D):
delivery/ (baseline) — from-scratch program, parallel squads.implementation/<name>/ with numbered PRD-NN — multi-app platform, many PRDs.Same phases regardless — only the artifact count and form change. Don't give a
feature a 4-squad org; don't give a brownfield refactor a greenfield vision doc.
Present the chosen size + shape + the numbered DoD and get a yes before proceeding.
On yes, record G1 = {approved, owner, date} plus the chosen size/shape in
.plan-it/state.json — the G1_APPROVED transition is guarded by gateRecorded.
Before any fan-out, locate exact targets so agents get precise paths, not vague instructions:
/read-chat or similar)
if one is installed; otherwise ask for the relevant transcript or summary.ls/grep the named repos; find the docs/, schema files, entry points.CLAUDE.md).Output: a list of {subsystem → exact paths to read} that seeds the research teams.
The repo tells you what should be true; the live system tells you what is. Do this before Phase 8 freeze, and write the findings into the CONTRACT as observed facts:
code-grep ∪ every component's declared requirements, intersected
with the live registry — then list the gaps as explicit work. A list derived from a
subset or from repo manifests will miss things the running system actually needs.Two build-time corollaries worth encoding in the CONTRACT/epics so the builder inherits them: map a caller/consumer surface before planning any auth-guard or interface change (a guard that breaks N callers is worse than no guard); and any repo import must be a full-tree secret-scan + runtime-only subset, never a history mirror.
Pick a discovery mode by use-case (full playbook in references/playbooks.md §A):
research/stream-<X>.md.Shared mechanics for any fan-out:
research/SHARED-CONTEXT.md, the one file
every agent reads before working (Guardrail 1 for research)._research/NN-<slice>.md) so nothing is
lost to summarization.node scripts/gate-check.mjs verify <every expected output path> — the
FANOUT_COMPLETE transition is guarded by it. On failure, SendMessage any
silent agent to deliver; re-dispatch any team that did 0 work (this happens —
caught and recovered live during the skill's own build-out). Record each passing
artifact in .plan-it/state.json → artifacts.Use the Agent tool (Explore/general-purpose), or /fable-it's team machinery
for larger runs. Keep all synthesis single-threaded in the main thread.
Merge the team reports into docs/01-current-state-and-findings.md (every claim
traceable to path:line or a table). Capture a project memory file so the thread
survives context loss (per the memory rules in your environment).
Author the design docs in dependency order (skeletons in
references/templates.md). For size L the canonical arc:
01 Current state & findings — diagnosis (contradictions/tensions, evidence)02 Vision & architecture — principles that solve each contradiction + the shape03 Data model & contract — canonical entities, schema, interface, migration04 [domain] organization — the durable/human layer (if there is one) (optional)05 [components] — deep-dive each major component: verdict, keep/discard/build, cost07 [organizing pattern] — the composability metaphor + "add a node" playbook (optional)06 Roadmap & open questions — phased plan, first vertical slice, risks, the decision listMethodology to honor while authoring:
gate-check adversary (D4) enforces this at the adversaryGate state — the five
cascade classes (partial-failure, rollback/compensation, failed-recovery→
escalation, recovery/resume, adversarial-verify) must each be covered-or-waived.
A genuinely linear workflow declares no machine and the gate is N/A (no over-reach).Route per the repo's CLAUDE.md: code-adjacent docs → repo docs/; project
decisions/sessions → the vault.
Collect every genuine judgment call into a single "Decisions only you can make"
section (lives in the roadmap doc 06 §4). For each: state it, attach a
recommendation, but do not pre-decide the irreversible ones. Present them
numbered. The user answers numbered.
Then:
G2 = {approved, owner, date} in .plan-it/state.json
(G2_ANSWERED is guarded by gateRecorded).07) and run a coherence pass
(grep for now-stale terms the new decision invalidated; fix them).Ask "specs are aligned — proceed to the delivery package?" On yes, write the backbone first, because squads build their PRDs against it:
delivery/CONTRACT.md (frozen v1.0) — vocabulary, schema, verbs/interface,
primitive interface, enums/literals, repo ownership + branch rules, definition
of "shipped," changelog.delivery/00-program-plan.md — squads, epic backlog, waves, test standard,
branching, the fable-it runbook, the board pointer.delivery/STATUS.md — the live board, all epics in backlog.(For size S/M, fold these into fewer files — a contract section + a single plan.)
Record G3 = {approved, owner, date} on the user's yes. Then, before any squad
fan-out, run node scripts/gate-check.mjs freeze delivery/CONTRACT.md (or the
file carrying the inlined contract section) — the CONTRACT_FROZEN transition is
guarded by it, and Rule 1 is now an exit code, not a plea. Record the contract
version + path in .plan-it/state.json → contract.
Fan out one squad team per repo lane (disjoint files — no co-editing). Each
writes its prds/prd-N-*.md + epics/epics-N-*.md against the frozen CONTRACT.
file:line), epics table, acceptance criteria,
risks, repo/branch plan.epic/<EID>-<slug>), deps, scope, task
checklist (file:line scoped), then — as the LAST and load-bearing step — the
Test Contract: up to ~20 type-selected use-cases/scenarios with expected
outputs registered (see "The Test Contract" above and formats.md). DoD = 100%
of the contract passes. This is the heart of the epic, not a footnote.Amendment loop: squads grounding in real code will surface cross-cutting
integration issues before any code is written — fold each back into CONTRACT.md
centrally (v1.0 → v1.1 …) so squads can't drift. This is the contract doing its job.
Scaling the fan-out (when there are many PRDs, not 4 fixed squads): use the
parallel-batch generator (playbooks §C) — a features.json work-breakdown
(one row per PRD), subagents spawned in review-gated batches, the same
template+glossary injected into every subagent for coherence, and a
cross-PRD consistency lint after the fan-out. PRD numbering PRD-NN where NN =
dependency order.
Optional executable split (playbooks §D): instead of (or beside) epics/*.md,
emit the breakdown onto a live GitHub Projects board via a ghp.sh helper
(epic = parent issue, tasks = native sub-issues, status single-select; GitHub is
source of truth, tracker.md a cache). Offer this when the user wants a live board.
Apply Rule 3 after the fan-out — node scripts/gate-check.mjs verify prds/ epics/
(the SQUADS_COMPLETE transition is guarded by it). Each AMENDMENT bumps the
contract version in .plan-it/state.json (v1.0 → v1.1 …) and stays in
parallelPlanning — the machine's self-loop.
[REAL]
cases (those needing a live target). DoD = 100% pass via /full-qa + /iterate.
No [REAL] case may be marked VERIFIED on a mock — unreachable target →
IMPLEMENTED-NOT-VERIFIED, never a fake green.node scripts/gate-check.mjs handoff delivery/
— the LINT_CLEAN transition is guarded by it. It checks ID grammar, declared-vs-
counted case totals, [REAL] tallies, per-epic Test Contract presence, and token
lint. The judgment half below still needs you.node scripts/gate-check.mjs adversary delivery/
— the ADVERSARY_CLEAN transition (verify → adversaryGate → handoff) is guarded by
it (D4). When the CONTRACT declares a state machine, it enforces failure-mode depth:
the machine models failures + recovery, every declared failure state is an asserted
case, and the five cascade classes are covered-or-waived. Linear workflows: N/A, passes.references/playbooks.md §F) — the lint
that makes a package build unattended: counts add up (count tags, don't hand-type);
every goal & governance rule has a test; the CONTRACT verb/API surface reconciles
with what's "kept" and what's tested; if the tool parses its own artifacts, round-trip
the grammar over the generated sample; every diff/sync verb declares live-vs-cached
reads; every "never X" invariant has an inverse-op test; IDs/dep-graph coherent across
files; token lint. Fix and re-lint until clean. (These are the exact defect classes a
dry-run shipped — don't hand off without it.)delivery/README.md (index) + delivery/KICKOFF.md (orientation:
one-liner, first slice, repo map, locked decisions, gotchas, handoff state).
KICKOFF is generated, never copied stale: it MUST open with the "0. Pinning"
block (absolute repo path @ full git SHA, .plan-it/state.json path, CONTRACT
SHA-256) and make "re-derive tally + reconcile from disk, stop-and-report on
mismatch" the builder's first numbered step (references/templates.md
KICKOFF block, PRD §D4–D5).STATUS.md rows reflect Wave-0 in-progress, rest backlog./sync-obsidian or equivalent), if your
environment has one./session-debrief or equivalent) — session note,
reusable patterns, memory./next-session-prompt, or author it directly) —
the KICKOFF doc and the exact copy-paste launch
prompt (this is the sample-prompt-prd.txt-style artifact that /fable-it
consumes). Done.README.md consolidation hub
(reading-order table + decisions-in-one-screen + GATING items); a KICKOFFS.md
archiving the launch prompt per PRD/phase; a DELIVERY-LOG.md truth board; and
for large PRDs, an initial slice + a later -CONCLUDE run to close deferred
IMPLEMENTED-NOT-VERIFIED items.Final report to the user: per-doc + per-epic status, total test count, the locked decisions, and the launch prompt.
/fable-it — the build engine plan-it feeds. The handoff prompt targets it./read-chat (optional) — resolve pointer sessions in pre-grounding./sync-obsidian, /session-debrief, /next-session-prompt (optional) — the
handoff trio; degrade to inline equivalents when absent.references/machine.md — the deterministic core: machine.json explained,
the .plan-it/state.json schema + resume protocol, gate-check usage, the
degrade-gracefully rule, and the "model the confusing parts" output discipline.
Read at Phase 0 (resume) and before every guarded transition.references/templates.md — doc + delivery skeletons (PARTS A–C) and the 5
packaging shapes + use-case→shape map (PART D). Read PART D at Gate G1 to pick
the shape; read A–C before authoring.references/formats.md — the composable atomic formats (lego bricks): decision
log, blocking-questions table, governance/invariant block, the 4 test-case
grammars, test-tier matrix + coverage-map self-audit, typed task grammar + dep-graph
DAG, the DoD ladder, the honest run-report / DELIVERY-LOG.references/playbooks.md — advanced moves: discovery modes (incl.
verify-then-extend), brownfield/refactor templates (verdict tables, blast-radius,
naming-first, schema-vs-data-migration), scale-out batch PRD generation, the
executable GitHub-board split, and handoff enrichments.Authored by DevOtts.
[!NOTE] Built for agentic delivery — the disciplined front-half of the lifecycle that ends exactly where an autonomous build agent begins.
Everyone has learned that agents can build. What still fails, quietly and expensively, is the step before: turning "here's roughly what I want" into something an agent can build unattended. Paste a fuzzy idea straight into a build agent and it invents the missing decisions, greenfields code that already exists, builds one component against a schema another component doesn't share, and reports "done" on work nobody defined a test for.
plan-it is that missing step, packaged as one command. It runs a ~10-phase discovery → spec → agile-split pipeline: it pre-grounds itself in your actual codebase (and the live system, not just the repo), fans out parallel research teams that must cite path:line for every claim, authors the design docs in dependency order, pauses at one batched human-decision gate, freezes a shared CONTRACT, then fans out squad teams to write PRDs + epics against it — each epic ending in a binding Test Contract the build must pass 100% before "done."
You describe a feature in three paragraphs and dispatch an agent overnight. In the morning: it picked a database schema in one file and a different one in another, "rebuilt" a service that was already deployed, made four irreversible architecture calls you never saw, and its report says everything works — verified against mocks it wrote itself.
None of that is a capability problem. It's a planning problem: no frozen contract for parallel work to agree on, no single gate where the human injects the decisions only a human can make, and no pre-registered definition of what "working" even means. plan-it fixes all three structurally — with a frozen CONTRACT.md that squads write to, one numbered decision round with a recommendation attached to every item, and a Test Contract authored at planning time, so the build agent inherits its Definition of Done instead of improvising one.
plan-it ships as both a Claude Code plugin and a portable SKILL.md (the workflow, on any agent). Pick your tool.
[!TIP] Universal installers understand the
SKILL.mdstandard and drop the skill into the right place for 70+ tools — use these if your agent isn't listed below:npx skills add DevOtts/plan-it -a <agent> # e.g. -a cursor, -a codex ; add -g for global gh skill install DevOtts/plan-it # GitHub CLIPeek first with
npx skills add DevOtts/plan-it --list.
# 1. Register the marketplace
/plugin marketplace add DevOtts/plan-it
# 2. Install the plugin (plugin-name@marketplace-name)
/plugin install plan-it@plan-it
Then invoke it with /plan-it <your idea, brain-dump, or transcription>. On
Claude Code the skill can also drive the Agent tool for its research and
squad fan-outs — the full parallel experience. (Skills-CLI alternative:
npx skills add DevOtts/plan-it -a claude-code.)
npx skills add DevOtts/plan-it -a cursor # add -g for a global install
npx skills add DevOtts/plan-it -a codex
# or: gh skill install DevOtts/plan-it
npx skills add DevOtts/plan-it -a github-copilot
npx skills add DevOtts/plan-it -a <agent>
Run npx skills add DevOtts/plan-it --list, then target your agent.
[!NOTE] On agents without a subagent/team mechanism, the fan-out phases degrade gracefully to sequential research — same pipeline, same gates, same artifacts, just slower. See docs/installation.md.
Three autonomous bursts, three human gates, one frozen contract.
/plan-it ─────────────► docs/ + delivery/ ─────────────► /fable-it
(discovery → spec → plan) (the buildable package) (builds it)
path:line, findings staged to disk immediately. For plans touching a running
system, ground against the live system, not the repo: hit configs, dump live
registries, verify credentials actually work. Contradictions get adjudicated,
not averaged.delivery/CONTRACT.md v1.0 —
canonical entities, schema, interface, enums, repo map, the definition of
"shipped." Then one squad team per repo lane writes PRDs + epics against it.
Cross-cutting discoveries fold back as dated amendments (v1.0 → v1.1), so squads
can't drift.KICKOFF.md plus the
exact copy-paste launch prompt for the build agent.Five rules are enforced, not suggested: freeze the CONTRACT before parallel work · batch human decisions into ONE gate · idle ≠ delivered — verify every agent's output on disk · ground on the live system before the freeze · run the machine, not the prose. Full methodology in docs/methodology.md.
v1's control flow lived entirely in prose — the exact "prose control flow" failure mode David Khourshid names in Beyond the Prompt: Goodbye Slop, Welcome Determinism: step-by-step instructions in markdown that you hope the agent follows, and sometimes it won't. v2 applies his "deterministic core, agentic shell" pattern to the pipeline itself:
| Piece | What it is |
|---|---|
machine.json |
The pipeline as an explicit XState v5-compatible statechart — 15 states, 3 human gates, guarded transitions, an amendment self-loop. Paste it into stately.ai/viz to see it. |
.plan-it/state.json |
Every run persists its position: current state, gate approvals (owner + date), contract version, verified-artifact registry. Crash, compaction, or a fresh session → resume from the machine, not the transcript. |
scripts/gate-check.mjs |
The guards as exit codes (zero-dep Node): verify (idle ≠ delivered), freeze (no contract → no squads), handoff (consistency lint), state (gates recorded). A non-zero exit blocks the transition. |
The fuzzy phases — discovery, synthesis, authoring, judgment — stay LLM-at-the-node. Non-determinism at the edges, determinism at the core. And the same discipline flows into what plan-it plans: every confusing workflow found in discovery