aboutsummaryrefslogtreecommitdiff
path: root/claude-rules/docs-lifecycle.md
blob: 3906d86119f20e48ea7c230fd35c617e2ad752a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Docs Lifecycle

Applies to: `**/*` (any project carrying a `docs/` tree)

How formal documents are separated from working notes, and how a document's
lifecycle state stays visible without opening the file. Specs are the first
instance of the shape; the pattern is reusable for any growing collection of
processed artifacts. Full design: the docs-lifecycle spec in rulesets
`docs/specs/`.

## The shape (reusable)

1. **Separate formal artifacts from working notes by location.** A formal
   artifact proposes a buildable change and carries the full spine; everything
   else is a note.
2. **Lifecycle state lives in the artifact**, on a scannable, greppable
   carrier — an org TODO keyword on a top-level status heading — with a dated
   history of every transition.
3. **Links use rename-safe identifiers** so a move or rename never orphans
   inbound references.
4. A collection **earns this treatment when "which of these are live?" starts
   requiring a file-by-file read.**

## The spec instance

- `docs/specs/` holds formal specs only — a doc with both a `Decisions`
  section and an `Implementation phases` section (the spec-create spine).
  `docs/design/` holds everything else: brainstorms, proposals, inventories,
  research notes, frozen source material. Spec filenames end `-spec.org`
  (spec-review's precondition keys on it); no status suffixes ever.
- Every spec opens with a top-level status heading directly after the file
  header, carrying the lifecycle keyword, an `:ID:` UUID, and dated history
  lines (newest first). The keyword header is two sequences, and both lines
  are required:

      #+TODO: TODO | DONE
      #+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED

  The first drives `Decisions` / `Review findings` tasks and their `[/]`
  cookies; the second is the lifecycle. They share no keyword — never merge
  them into one line, and never drop the first (that silently breaks the
  cookies that gate readiness).
- **The heading keyword is authoritative.** The Metadata table's `Status`
  field mirrors it in lowercase; on disagreement the heading wins. A
  transition is three lines in one file — keyword, history line, mirror — and
  never a rename or a link edit.
- **Every flip has a named owner:** spec-create stamps `DRAFT`; spec-review
  flips `DRAFT` → `READY` on a passing gate; spec-response flips `READY` →
  `DOING` when it decomposes phases into build tasks (stamping the spec's
  UUID as a `:SPEC_ID:` property on the build parent, and always emitting a
  final "flip the spec to IMPLEMENTED" task); task-audit flags any `DOING`
  spec whose `:SPEC_ID:`-bound parent is closed, archived, or missing.
  Terminal states (`IMPLEMENTED` / `SUPERSEDED` / `CANCELLED`) always carry a
  stated reason in the history line.
- **The status board is one grep:**

      rg -H '^\* (DRAFT|READY|DOING|IMPLEMENTED|SUPERSEDED|CANCELLED) ' docs/specs/

- **Legacy compatibility:** projects that haven't run the one-time `spec-sort`
  retrofit (no `:LAST_SPEC_SORT:` marker in `.ai/notes.org` Workflow State)
  keep their legacy spec locations reviewable; the `docs/specs/` requirement
  hardens only after the sort runs.
- **Cross-doc links to specs are `file:` links for now.** Specs carry `:ID:`
  UUIDs, but conversion to `[[id:...]]` is a gated follow-up (the Emacs id
  index has to know about project docs first) — don't convert links ad hoc.

## Watch for

- Editing the `#+TODO:` header down to one sequence — the `[/]` cookies stop
  computing and readiness gates go vacuous.
- Bare `[N/N]` tokens in prose or list items — org's cookie updater rewrites
  them; spell counts out in words outside real cookie positions.
- A "done" spec whose keyword still says `DOING` — that's the failure this
  convention exists to prevent; flip it with a history line rather than
  leaving it for the audit to catch.