Skip to content

Audit: Plan index

What we check

docs/plans/index.md is the one page that answers "what has this repository planned, and what still wants attention". It is read by people picking up work and by tooling deciding what to surface, and neither can read it if every repository shapes it differently. Three layouts had grown across the fleet -- a date-first table of plans, a plan-first table of plans, and a plan-first table of phases -- so a reader (or a script) had to work out which one it was looking at before it could find the status column.

Repositories with a docs/plans/ directory must satisfy all of:

  • An index exists. docs/plans/index.md is present whenever docs/plans/ holds any plan at all.
  • Plans are listed in tables, not as prose or a bullet list.
  • Every table leads with Date then Plan. Later columns are the repository's own business; Intent, Status and Phases are the common ones. A Status column is optional -- a standalone plan listing that tracks no status is registered, just not tracked.
  • Dates are YYYY-MM-DD, and rows run oldest first. Ordering is checked within each table, not across them, so a repository may keep separate master, standalone and consolidation tables that each start over.
  • Every master plan is listed. A plan file in docs/plans/ that the index never links is invisible: it was drafted and then forgotten. Phase plans are exempt -- they are named after their master plan and tracked inside it.
  • Status cells come from the shared vocabulary, described below.

Repositories with no docs/plans/ directory are reported as N/A. Whether every project should plan this way is a separate decision, not smuggled in here.

The status vocabulary

A status cell holds exactly one of Proposed, Not started, In progress, Blocked, Complete, Abandoned or Superseded, and nothing else. Matching is case-insensitive, so In Progress passes, but the canonical spelling is the one to write.

The rule is strict about the "nothing else" because that is the part that decayed. Status cells across the fleet had grown into whole paragraphs:

Complete (phases 1-5 and 2b, 2026-08-15): every merge to develop
installs a freshly built .deb/.rpm on...

That is useful writing in the wrong column. A status is read to decide whether a plan still wants attention; when the answer is buried in a paragraph, neither a person scanning the table nor a script can get it out. Dates, phase arithmetic and summaries of what happened belong in the plan file, and a one-line summary belongs in the index's own Intent column.

The vocabulary itself is a versioned shared block, plan-status-vocabulary, which every PLAN-TEMPLATE.md must carry (see the plan-template audit) so that plans are written to it rather than corrected afterwards. It governs the master plan's own Execution phase table as well as the index row. A test in scripts/test_audit_check.py asserts the block and the list the audit enforces name the same terms, so the wording repositories are handed cannot drift from the wording they are measured against.

Overlap with the session hook, which is deliberate

An unregistered plan is also reported by the local SessionStart plan-status hook, which lists incomplete and unregistered plans as candidate work when a session opens in the repository. The two are not redundant: the hook is a per-session nudge that disappears when the session ends, and the audit is what turns a persistent gap into a tracked issue. Format, ordering and vocabulary are the audit's alone -- the hook only reads the index, it does not police it.

Template

No template. templates/shared-blocks/plan-status-vocabulary.md holds the canonical status vocabulary; copy it verbatim, markers included, into the repository's PLAN-TEMPLATE.md.

To convert an index to the canonical layout, move the date to the first column, sort each table oldest first, and move everything that is not a vocabulary term out of the status column -- into Intent if it is a one-line summary, into the plan file if it is longer. Add a row for any plan the index does not list; consult the plan to work out its real status rather than guessing from the file's existence.

Projects

This table is regenerated daily by the consistency audit workflow from scripts/audit-check.py results; do not edit it by hand.

Last regenerated: 2026-08-23T06:45:38.740880+00:00

Project Status Issue
actions N/A -
agent-python N/A -
client-python non-compliant client-python#365
client-python-k3s non-compliant client-python-k3s#32
clingwrap N/A -
cloudgood N/A -
development compliant -
divergulent non-compliant divergulent#69
instar non-compliant instar#506
kerbside compliant -
kerbside-patches N/A -
library-utilities non-compliant library-utilities#42
occystrap non-compliant occystrap#116
private-ci N/A -
ryll compliant -
sfui non-compliant sfui#24
shakenfist compliant -

Details for non-compliant projects:

  • client-python (Status): docs/plans/index.md is missing, so none of the 1 plan(s) in docs/plans/ are registered
  • client-python-k3s (Status): docs/plans/index.md is missing, so none of the 2 plan(s) in docs/plans/ are registered
  • divergulent (Status): 1 table(s) not led by Date then Plan columns: line 10 starts "Plan | Phases"
  • instar (Status): 1 status cell(s) outside the shared vocabulary (Proposed, Not started, In progress, Blocked, Complete, Abandoned, Superseded): instar amend subcommand ("1.1 (qcow2 v2⇔v3 version transition, ...")
  • library-utilities (Status): docs/plans/index.md is missing, so none of the 1 plan(s) in docs/plans/ are registered
  • occystrap (Status): index has no plan table (it must list plans in a table led by Date and Plan columns, not as prose or a bullet list); 4 master plan(s) not listed in the index: PLAN-make-the-speed.md, PLAN-post-write-verification.md, PLAN-registry-proxy.md, PLAN-structured-logging.md
  • sfui (Status): docs/plans/index.md is missing, so none of the 3 plan(s) in docs/plans/ are registered

📝 Report an issue with this page