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, so a reader had to work out which
one it was looking at before finding the status column.
Repositories with a docs/plans/ directory must satisfy all of:
- An index exists.
docs/plans/index.mdis present wheneverdocs/plans/holds any plan. - Plans are listed in tables, not as prose or a bullet list.
- Every table leads with
DatethenPlan. Later columns are the repository's own business;Intent,StatusandPhasesare the common ones. AStatuscolumn 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. - Every master plan is listed. A plan file 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, below.
Repositories with no docs/plans/ directory are N/A. Whether every
project should plan this way is a separate decision, not smuggled in
here.
Fenced code blocks are not read. An index that shows what a row looks like is documenting its own conventions rather than listing a plan, so the example's columns are not judged as a table and its links do not register the plans they name.
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 "nothing else" is strict because that is the part that decayed:
status cells had grown into whole paragraphs carrying dates, phase
arithmetic and summaries of what happened. That is useful writing in
the wrong column. A status is read to decide whether a plan still wants
attention, and neither a person scanning the table nor a script can get
that out of a paragraph. The detail belongs in the plan file, and a
one-line summary in the index's own Intent column.
The vocabulary is a versioned shared block, plan-status-vocabulary,
which every PLAN-TEMPLATE.md must carry (see the plan-template
audit) so 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/tests/test_plans.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. 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¶
Per-project compliance for this criterion is regenerated every morning by the consistency audit: see the compliance page.