01 · ANATOMY

Two layers. They must agree.

Every plan file has machine-readable YAML frontmatter and a human-readable Status banner. If they conflict, frontmatter wins. The dashboard reads frontmatter; /plans sync watches for drift between the two.

plans/active/DARK_MODE.md YAML · machine-readable
---
status:        active
priority:      P1
owner:         alex
type:          feature
depends_on:    []
blocks:        [THEME_PICKER]
last_updated:  2026-05-06
in_flight:     true
start_date:    2026-04-28
---
9 fields. Eight are required at creation. in_flight flips to true the moment work actively starts.
## Status banner (same file) prose · human-readable
## Status

- Overall: In progress, Phase 2 of 3
- Phase 0 (Color tokens):     Done · 2026-04-29
- Phase 1 (Component pass):   Done · 2026-05-02
- Phase 2 (Settings UI):      In progress · ETA 2026-05-12

Next action: Wire up the theme toggle to
the settings panel.
Phase progress + next action. What an engineer reads when they re-enter cold. The dashboard does not parse this — it is for humans.
The one rule

New ideas live as backlog bullets in STATUS.md. No plan file gets created until work is committed. No idea lives in two places.

02 · FRONTMATTER

Every field. Every valid value.

Nine fields, all flat YAML. Strings, dates, and string lists. No nested objects, no custom types. plans.json is regenerated from these fields — never hand-edited.

Field Type Valid values Required
status string active · shipped · superseded yes
priority enum P0 (drop everything) · P1 · P2 · P3 (someday) yes
owner string a name or handle. you is fine for solo projects. yes
type enum feature · refactor · bug · infra · docs yes
depends_on string[] filenames (without .md) of plans this one waits on yes
blocks string[] filenames of plans waiting on this one yes
last_updated YYYY-MM-DD date of the most recent edit. Bumped whenever a phase changes. yes
in_flight boolean true when work has actively started — drives the Gantt timeline when active
start_date YYYY-MM-DD when work began (or projected start, for queued plans) optional

03 · LIFECYCLE

One idea. One home at every stage.

An idea moves through five stages, exactly. There is one canonical location for it at each stage — never two. This is what stops the stale-file pile-up.

1Idea

Backlog bullet only

Add a one-line bullet to STATUS.md backlog. No plan file yet.

2Committed

Plan file created

Run /plans new. Frontmatter is filled, banner is templated, row added to STATUS.md "Up next".

3Started

in_flight: true

Flip the flag. Row moves to "In flight". The Gantt picks it up automatically on next sync.

4Shipped

mv to shipped/

mv plans/active/X.md plans/shipped/X.md. Row moves to "Recently shipped".

5Replaced

mv to superseded/

Different approach won. status: superseded. Kept for archaeology, not noise.

04 · /plans SKILL

Two slash commands. Drift goes away.

A Claude Code skill (and Antigravity / Cursor port) with two modes. Both run inside your assistant — no separate process, no daemon, no API key.

/plans sync

Weekly drift audit

Reads every plan's frontmatter, runs git log, cross-references the two, and shows you a diff before writing anything.

  • Catches phases marked "not started" that are already merged
  • Flags plans with no commits in 14 days
  • Detects orphaned depends_on / blocks edges
  • Regenerates plans.json and STATUS.md auto-sections
  • Always proposes — never writes silently

/plans new

Guided plan creation

Walks you through the eight required fields. Picks a filename from the title. Inserts the templated ## Status banner. Adds the row to STATUS.md.

  • Validates priority, status, type are in the enum
  • Resolves depends_on to existing files
  • Won't create the file if frontmatter is incomplete
  • Updates STATUS.md backlog if you started from a bullet
  • Runs in the assistant — your IDE stays where it was

That's the whole spec. Two commands and you're running.

Full reference (every edge case, every CLI flag, the JSON schema) lives in the repo.