writing-plans
SkillFiles & storageThe spec-to-plan bridge. Routed to by /feature once the brainstormed spec is approved, and by /sprint before execution. Decomposes the spec into 2–5 minute tasks, each carrying its exact file path(s) and a concrete verification step that maps to a tdd obligation. Writes the plan to .codearbiter/plans/<slug>.md, ordered with dependencies flagged and an MVP slice identifiable. Nothing executes until every task has a path and a verification and the task set covers every acceptance criterion.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the writing-plans skill
What this skill tells your AI
The instructions your AI receives, as published by arbiterforge/codearbiter in plugins/ca/skills/writing-plans/SKILL.md and read by ahel’s review.
Turn an approved spec into an executable plan. Routed to by /feature (after spec approval) and /sprint.
Pre-flight
Read these, or STOP and surface the gap — never plan against an unapproved or missing spec:
{{PROJECT_DIR}}/.codearbiter/specs/<slug>.md— the approved brainstorming spec. The single source of acceptance criteria. Absent or unapproved → STOP and route back to/feature.{{PROJECT_DIR}}/.codearbiter/CONTEXT.md— thestage:frontmatter (the maturity value) and project context.{{PROJECT_DIR}}/.codearbiter/tech-stack.md— file layout, build/test/lint invocations. A verification step cites a real command from here, never a guess.{{PROJECT_DIR}}/.codearbiter/coding-standards.md— structure and naming, so a task names the right path.
If --farm was requested: check that FARM_API_KEY is set in the environment{{IF:pi}} of the Pi parent process{{ELSE}} (or .env at {{PLUGIN_ROOT}}/tools/.env){{END}}. If absent, BLOCK immediately — cite {{PLUGIN_ROOT}}/includes/farm.md for setup instructions. Do not proceed; the farm dispatcher cannot run without an API key. Model selection happens later (at dispatch time in subagent-driven-development), so no model research is needed here.
Phase 1 — Criterion extraction · gate: BLOCK
Lift every acceptance criterion from the spec verbatim and assign each a stable ID (AC-01,
AC-02, …). This list is the coverage ledger for the whole plan — Phase 4 checks the task set
against it.
A criterion the spec leaves ambiguous is a [CONFIRM-NN] against
{{PROJECT_DIR}}/.codearbiter/open-questions.md — surface it, do not invent the intent.
Backstop the ledger against the spec's own stated intent, mechanically, before trusting it — this
runs even when brainstorming already ran the same check, because a hole that survived Phase 3
survives Phase 4's bijection too, silently (#566): run "$PY" "{{PLUGIN_ROOT}}/hooks/_intentlib.py" uncovered-intent {{PROJECT_DIR}}/.codearbiter/specs/<slug>.md [--issue-body <scratch-file>] —
<scratch-file> holds the linked issue's body when one exists (gh issue view <N> --json body -q .body > <scratch-file>, written outside the working tree), omitted when none does. A non-empty
result names an in-scope bullet or an acceptance checkbox the criteria never cited — BLOCK and route
back to brainstorming ({{PLUGIN_ROOT}}/skills/brainstorming/SKILL.md) to add the missing criterion or record a [CONFIRM-NN]; never paper over a
missing criterion by authoring a task for it here instead. This is the LAST point before a hole gets
laundered through Phase 4's bijection, which only checks the ledger against itself and cannot see
past it.
Then ask the half this tool cannot mechanize: if every AC-NN passed and nothing else changed,
what would still be broken? A real answer names a criterion the ledger is missing even though
every scope bullet and checkbox is technically cited — judgment, not mechanizable, and not satisfied
by a rhetorical "nothing." Finding nothing broken is a reportable result, stated in one line, never a
silent skip.
Gate: every acceptance criterion in the spec captured as a numbered AC-NN; the uncovered_intent
backstop above returns empty or every finding is resolved; and the negative question has been asked
and answered. A partial ledger does not pass.
Phase 2 — Task decomposition · gate: BLOCK
Break the work into the smallest honest units. Each task is ~2–5 minutes of work and carries:
- id —
T-01,T-02, … stable. - path(s) — the exact file(s) the task touches, resolved against
coding-standards.md. "Some files" is not a path. - verification — one concrete command or observable that proves the task done (e.g.,
<test cmd> -k test_token_expiry passes,endpoint returns 401 on missing header). It cites a realtech-stack.mdinvocation or a directly observable behavior — never "looks right". - maps-to — the
tddobligation this verification corresponds to. The verification maps to a tdd obligation; it does NOT replace tdd's own gates.tddPhase 1 still derives and Phase 4 still verifies obligations against passing tests. - covers — the
AC-NN(s) this task advances.
Split anything that won't fit ~5 minutes or touches unrelated paths. Reject the trap of one monolithic "implement the feature" task — that defeats the plan.
Gate: every task has at least one path AND a verification AND a maps-to. A task missing any of the
three blocks the plan.
Phase 3 — Order & MVP slice · gate: BLOCK
Order tasks so each runs only after what it depends on. Flag every dependency explicitly
(T-07 depends on T-03). A cycle is a decomposition error — return to Phase 2 and split.
Group the ordered tasks so the MVP slice is identifiable: the minimal contiguous task set that satisfies the spec's core acceptance criteria and is shippable on its own. Everything past the slice is incremental.
Gate: a complete dependency order with no cycle, and an explicitly marked MVP slice.
Phase 4 — Bijection proof & write · gate: BLOCK
Cross the ledger against the task set, both directions. This proves the plan and the ledger AGREE
with each other — it does not prove the ledger itself is COMPLETE relative to the spec's stated
intent. A criterion missing from the ledger entirely was never a candidate for either check below;
that completeness gap is caught earlier, by Phase 1's uncovered_intent backstop (and by
brainstorming Phase 3 before that) — never re-derived here, and never implied by this phase's name
(#566: a prior version of this gate read "coverage proof", which a bijective check does not earn).
- Every
AC-NNis covered by at least one task'scovers. An uncovered criterion blocks — author the missing task. - Every task advances at least one
AC-NN. A task that covers nothing is scope creep — cut it or surface it.
Then write the plan to {{PROJECT_DIR}}/.codearbiter/plans/<slug>.md — <slug> matching the
spec — with the AC-NN ledger, the ordered task table (id · path(s) · verification · maps-to ·
covers · depends-on · status, initialized PENDING), the marked MVP slice, and any out-of-scope
item tagged inline [NEEDS-TRIAGE].
The status column is the pipeline's resume ledger: subagent-driven-development flips a task to
ACCEPTED the moment it accepts it, so an interrupted run (crash, compaction, closed session) is
re-entered by /feature at the first non-ACCEPTED task instead of restarted from brainstorming.
Gate: bijection proven between the plan and the ledger — no criterion without a task, no task without
a criterion — and the plan written to disk. This proves the two are mutually consistent, nothing more;
completeness of the ledger itself was Phase 1's gate, not this one. This clears the path to execution:
executing-plans (checkpointed, via /feature) or subagent-driven-development (autonomous, via
/sprint) — each routes every task through tdd. The plan never hands off to tdd directly.
Phase 4-farm extension (only when --farm was requested)
When --farm was requested, after the bijective coverage gate passes and the .md plan is written,
produce the farm artifact (plan.json) — one MVP slice at a time — per
{{PLUGIN_ROOT}}/skills/writing-plans/references/farm-plan.md. Load that leaf and follow it;
it owns the per-task failing-test + schema-valid plan.json procedure.
Gate: all failing tests written and confirmed failing; plan.json written and schema-valid. Both
artifacts exist before handing off to subagent-driven-development ({{PLUGIN_ROOT}}/skills/subagent-driven-development/SKILL.md).
Hard rules
- MUST NOT plan against an absent or unapproved spec — STOP and route back to
/feature. - MUST NOT emit a task without an exact path AND a concrete verification step.
- MUST NOT let a task's verification stand in for a
tddgate — it maps to a tdd obligation, it does not replace one. - MUST NOT write the plan while any acceptance criterion is uncovered or any task covers nothing.
- MUST NOT guess a verification command — cite
tech-stack.mdor STOP. - MUST NOT resolve an ambiguous criterion by guessing — raise a
[CONFIRM-NN]. - MUST run the
uncovered_intentbackstop and ask the negative-judgment question in Phase 1, and MUST NOT treat Phase 4's bijection proof as a substitute — bijection proves the plan and the ledger agree with each other, never that the ledger is complete (#566). - MUST NOT emit
plan.jsonin--farmmode without writing and confirming each failing test first. - MUST NOT set
meta.modelormeta.apiBaseUrlinplan.json— these belong to the dispatch step. - MUST NOT proceed with
--farmifFARM_API_KEYis absent — cite{{PLUGIN_ROOT}}/includes/farm.mdand BLOCK. - MUST, at exit, run the follow-up harvest (
{{PLUGIN_ROOT}}/includes/harvest.md) over any[NEEDS-TRIAGE]out-of-scope items — batch-confirm promoting them toopen-tasks.md(work) oropen-questions.md(decisions) so they don't die in the plan file.
Signals
- GitHub stars
- 144
- Forks
- 7
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
writing-plans-arbiterforge- Source
- github.com/arbiterforge/codearbiter