diff options
| -rw-r--r-- | .ai/workflows/spec-create.org | 14 | ||||
| -rw-r--r-- | .ai/workflows/spec-response.org | 6 | ||||
| -rw-r--r-- | .ai/workflows/spec-review.org | 7 | ||||
| -rw-r--r-- | .ai/workflows/task-audit.org | 2 | ||||
| -rw-r--r-- | claude-rules/docs-lifecycle.md | 75 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/spec-create.org | 14 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/spec-response.org | 6 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/spec-review.org | 7 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/task-audit.org | 2 | ||||
| -rw-r--r-- | todo.org | 4 |
10 files changed, 125 insertions, 12 deletions
diff --git a/.ai/workflows/spec-create.org b/.ai/workflows/spec-create.org index 508b969..1249181 100644 --- a/.ai/workflows/spec-create.org +++ b/.ai/workflows/spec-create.org @@ -82,8 +82,9 @@ This is where the spec earns a "Ready" from review: an engineer must be able to ** Phase 5 — Wire it up (conventions) -- *Filename + location:* =docs/<problem-slug>-spec.org=. Org-mode. The slug names the *problem/feature*, not a date. Must end in =-spec.org=. -- *Metadata header:* a small table at the top — Status, Owner, Reviewer(s), Date, Related (link to the task/ticket). +- *Filename + location:* =docs/specs/YYYY-MM-DD-<problem-slug>-spec.org= — formal specs live in =docs/specs/=, never =docs/design/= (that's for notes, brainstorms, inventories; see =claude-rules/docs-lifecycle.md=). Org-mode. The slug names the *problem/feature*; no status suffixes ever — status lives in the file. Must end in =-spec.org=. +- *Status heading (first element after the file header):* a top-level heading carrying the lifecycle keyword, stamped =DRAFT= at authoring — spec-create owns this flip. It holds an =:ID:= UUID (generate with =uuidgen=) and dated history lines, newest first. The keyword is authoritative; the Metadata =Status= field mirrors it in lowercase. Transitions are three lines in one file (keyword + history line + mirror): spec-review flips =READY=, spec-response flips =DOING= at decomposition, the final build task flips =IMPLEMENTED=. Terminal states always record a reason. +- *Metadata header:* a small table at the top — Status (the lowercase mirror), Owner, Reviewer(s), Date, Related (link to the task/ticket). - *Review-and-iteration-history stub:* add a =Review and iteration history= section at the bottom and seed it with the author's first entry. =spec-review= and =spec-response= append provenance entries here, so the heading shape is a contract: =YYYY-MM-DD Day @ HH:MM:SS -ZZZZ — Contributor — Role=, body fields What / Why / Artifacts. - *Cross-link both ways:* the spec links its task; the task links the spec (replace the task's inline plan with a terse description + a =file:= link to the spec). @@ -103,7 +104,14 @@ Then it's ready for =spec-review.org=. Snapshot-vs-living rule: keep the spec li ,#+TITLE: <Feature> — Spec ,#+AUTHOR: <author> ,#+DATE: <YYYY-MM-DD> -,#+TODO: TODO | DONE SUPERSEDED CANCELLED +,#+TODO: TODO | DONE +,#+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED + +,* DRAFT <spec short name> +:PROPERTIES: +:ID: <uuid — generate with uuidgen> +:END: +- <YYYY-MM-DD Day @ HH:MM:SS -ZZZZ> — drafted. ,* Metadata | Status | draft | diff --git a/.ai/workflows/spec-response.org b/.ai/workflows/spec-response.org index de5b1c8..7628e49 100644 --- a/.ai/workflows/spec-response.org +++ b/.ai/workflows/spec-response.org @@ -130,9 +130,11 @@ When related specs were reviewed together, two reviews can recommend opposite th This is the *last* step of the workflow, and it runs *only after the author confirms the spec is Ready* — never during review iterations. A Ready spec nobody can act on is unfinished; this phase turns it into tracked work. It applies to every project type (library, application, service, docs set). -1. *Decide where the tasks live.* If the work is spinning off into its own project/repo, move the parent task into that project's =todo.org= (and relocate the spec with it); otherwise use the current project's =todo.org=. One parent task owns the effort; the phase tasks hang under it. +*This phase owns the =READY= → =DOING= lifecycle flip* (docs-lifecycle convention): when the decomposition below lands, update the spec's top-level status heading keyword to =DOING=, add a dated history line, and set the Metadata =Status= mirror to =doing= — three lines, one file. -2. *Create one task per implementation phase* from the spec's =Implementation phases=, in dependency order, so the task set as a whole describes the *full* milestone (e.g. v1) with no gaps. Each task body names the deliverable, its tests, and how it is verified. Carry over deferred/vNext work and any publish/release steps as their own tasks. +1. *Decide where the tasks live.* If the work is spinning off into its own project/repo, move the parent task into that project's =todo.org= (and relocate the spec with it); otherwise use the current project's =todo.org=. One parent task owns the effort; the phase tasks hang under it. *Stamp the binding:* the parent task's =:PROPERTIES:= drawer gets a =:SPEC_ID:= line holding the spec's status-heading UUID. That property is the durable join task-audit uses to police =DOING= specs (a =DOING= spec whose bound parent is closed, archived, or missing gets flagged). + +2. *Create one task per implementation phase* from the spec's =Implementation phases=, in dependency order, so the task set as a whole describes the *full* milestone (e.g. v1) with no gaps. Each task body names the deliverable, its tests, and how it is verified. Carry over deferred/vNext work and any publish/release steps as their own tasks. *Always end the set with the flip task:* a final "flip the spec to IMPLEMENTED (+ dated history line + mirror)" task under the same parent — the tracked obligation that closes the lifecycle loop when the build finishes. Never skip it; "a human remembers" is the failure mode this exists to prevent. 3. *Turn a critical eye on completeness.* Re-read the spec — every phase, every acceptance criterion, every named deliverable, every data-safety/principle rule — and confirm each has a home in a task. The work is not done when the tasks merely exist; it is done when nothing in the spec is left untracked. This completeness pass is mandatory regardless of project type. diff --git a/.ai/workflows/spec-review.org b/.ai/workflows/spec-review.org index 001238e..d4998eb 100644 --- a/.ai/workflows/spec-review.org +++ b/.ai/workflows/spec-review.org @@ -50,6 +50,11 @@ Run it *early* — design review exists to catch viability problems and costly m Before Phase 1, verify the file under review ends with =-spec.org=. Every design, decision, or planning document under a project's =docs/= directory carries that suffix as its identifier. The =.org= extension alone is not enough because =docs/= holds non-spec org files too (tutorials, frozen inventories, reference material). +*Location expectation (docs-lifecycle convention).* Formal specs live in =docs/specs/=. Whether that's enforced depends on whether the project has run its one-time =spec-sort= retrofit: + +- =:LAST_SPEC_SORT:= present in =.ai/notes.org= Workflow State → the project has sorted; a =-spec.org= file outside =docs/specs/= fails this precondition. Surface it: "this spec sits outside docs/specs/ — move it (and update inbound links) before review." +- Marker absent → legacy locations (=docs/= root, =docs/design/=) stay reviewable; add one nudge line to the review output ("this project's docs pile has never been spec-sorted — say 'run spec-sort' to sort it") and proceed. No legacy spec is ever unreviewable during the transition. + If the file does not end with =-spec.org=, stop immediately and surface the mismatch: #+begin_example @@ -167,6 +172,8 @@ Assign one label consistently: The most useful reviews move a spec from =Not ready= to =Ready with caveats= or =Ready= once decisions are captured. +*The =Ready= verdict flips the spec's lifecycle status.* spec-review owns the =DRAFT= → =READY= transition (docs-lifecycle convention): on assigning =Ready= (or =Ready with caveats= the author accepts), update the spec's top-level status heading keyword to =READY=, add a dated history line under it naming the review that passed, and set the Metadata =Status= mirror to =ready= — three lines, one file. Any other rubric label leaves the keyword where it stands (a re-review that finds new blockers on a =READY= spec demotes it back to =DRAFT= the same three-line way, with the reason in the history line). + Finding severity maps to blocking power: *high-priority findings block =Ready=* — they hold the rubric at =Not ready= (or =Ready with caveats= if the author accepts and tracks them) until dispositioned; *medium-priority findings are the author's discretion* and don't block. State the blocking status on each finding so the author running spec-response knows which ones gate the rubric. Then update the spec's review history. Specs should carry a bottom section named =Review and iteration history= (or the nearest existing equivalent) that tracks each material author/reviewer pass. Add a concise entry for this review even when the spec is ready and no findings are recorded. diff --git a/.ai/workflows/task-audit.org b/.ai/workflows/task-audit.org index 8dd2fb2..7d2b758 100644 --- a/.ai/workflows/task-audit.org +++ b/.ai/workflows/task-audit.org @@ -61,6 +61,8 @@ For each open task, read its body and cross-check its claims against the actual - *Calendar* — did a scheduled event happen; is a SCHEDULED/DEADLINE date now past. - *Meeting recordings* — if a task hinges on "did this conversation happen / what was said," check the recording queue (e.g. =~/sync/recordings/=) and transcribe via =process-meeting-transcript.org= if the answer lives in an un-transcribed recording. (This is exactly how a "did the interview happen?" task gets resolved instead of guessed.) +*Spec lifecycle reconcile (docs-lifecycle convention).* If the project has a =docs/specs/=, run the =:SPEC_ID:= query as part of this phase: for each spec whose top-level status heading reads =DOING=, find the =todo.org= task whose =:SPEC_ID:= property matches the spec's =:ID:=. Flag the spec NEEDS-USER when that bound parent is =DONE=/=CANCELLED=, archived, or missing — the build finished (or evaporated) without the =IMPLEMENTED= flip, exactly the drift this check exists to catch. Check the parent's own keyword, not its children (completed children become dated entries and the final flip task is a child, so child-counting misleads). + Assign each task a bucket (CURRENT / STALE / NEEDS-USER) and, for STALE, the specific factual update. *Scale tactic.* For a large open-task set, dispatch read-only investigation sub-agents over batches of tasks (parallel-safe per =subagents.md= — independent read-only domains). Each returns a per-task bucket + suggested update. *Never* let sub-agents write to =todo.org= concurrently — apply all edits serially in the main thread (concurrent writes to one file race and lose work). diff --git a/claude-rules/docs-lifecycle.md b/claude-rules/docs-lifecycle.md new file mode 100644 index 0000000..3906d86 --- /dev/null +++ b/claude-rules/docs-lifecycle.md @@ -0,0 +1,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. diff --git a/claude-templates/.ai/workflows/spec-create.org b/claude-templates/.ai/workflows/spec-create.org index 508b969..1249181 100644 --- a/claude-templates/.ai/workflows/spec-create.org +++ b/claude-templates/.ai/workflows/spec-create.org @@ -82,8 +82,9 @@ This is where the spec earns a "Ready" from review: an engineer must be able to ** Phase 5 — Wire it up (conventions) -- *Filename + location:* =docs/<problem-slug>-spec.org=. Org-mode. The slug names the *problem/feature*, not a date. Must end in =-spec.org=. -- *Metadata header:* a small table at the top — Status, Owner, Reviewer(s), Date, Related (link to the task/ticket). +- *Filename + location:* =docs/specs/YYYY-MM-DD-<problem-slug>-spec.org= — formal specs live in =docs/specs/=, never =docs/design/= (that's for notes, brainstorms, inventories; see =claude-rules/docs-lifecycle.md=). Org-mode. The slug names the *problem/feature*; no status suffixes ever — status lives in the file. Must end in =-spec.org=. +- *Status heading (first element after the file header):* a top-level heading carrying the lifecycle keyword, stamped =DRAFT= at authoring — spec-create owns this flip. It holds an =:ID:= UUID (generate with =uuidgen=) and dated history lines, newest first. The keyword is authoritative; the Metadata =Status= field mirrors it in lowercase. Transitions are three lines in one file (keyword + history line + mirror): spec-review flips =READY=, spec-response flips =DOING= at decomposition, the final build task flips =IMPLEMENTED=. Terminal states always record a reason. +- *Metadata header:* a small table at the top — Status (the lowercase mirror), Owner, Reviewer(s), Date, Related (link to the task/ticket). - *Review-and-iteration-history stub:* add a =Review and iteration history= section at the bottom and seed it with the author's first entry. =spec-review= and =spec-response= append provenance entries here, so the heading shape is a contract: =YYYY-MM-DD Day @ HH:MM:SS -ZZZZ — Contributor — Role=, body fields What / Why / Artifacts. - *Cross-link both ways:* the spec links its task; the task links the spec (replace the task's inline plan with a terse description + a =file:= link to the spec). @@ -103,7 +104,14 @@ Then it's ready for =spec-review.org=. Snapshot-vs-living rule: keep the spec li ,#+TITLE: <Feature> — Spec ,#+AUTHOR: <author> ,#+DATE: <YYYY-MM-DD> -,#+TODO: TODO | DONE SUPERSEDED CANCELLED +,#+TODO: TODO | DONE +,#+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED + +,* DRAFT <spec short name> +:PROPERTIES: +:ID: <uuid — generate with uuidgen> +:END: +- <YYYY-MM-DD Day @ HH:MM:SS -ZZZZ> — drafted. ,* Metadata | Status | draft | diff --git a/claude-templates/.ai/workflows/spec-response.org b/claude-templates/.ai/workflows/spec-response.org index de5b1c8..7628e49 100644 --- a/claude-templates/.ai/workflows/spec-response.org +++ b/claude-templates/.ai/workflows/spec-response.org @@ -130,9 +130,11 @@ When related specs were reviewed together, two reviews can recommend opposite th This is the *last* step of the workflow, and it runs *only after the author confirms the spec is Ready* — never during review iterations. A Ready spec nobody can act on is unfinished; this phase turns it into tracked work. It applies to every project type (library, application, service, docs set). -1. *Decide where the tasks live.* If the work is spinning off into its own project/repo, move the parent task into that project's =todo.org= (and relocate the spec with it); otherwise use the current project's =todo.org=. One parent task owns the effort; the phase tasks hang under it. +*This phase owns the =READY= → =DOING= lifecycle flip* (docs-lifecycle convention): when the decomposition below lands, update the spec's top-level status heading keyword to =DOING=, add a dated history line, and set the Metadata =Status= mirror to =doing= — three lines, one file. -2. *Create one task per implementation phase* from the spec's =Implementation phases=, in dependency order, so the task set as a whole describes the *full* milestone (e.g. v1) with no gaps. Each task body names the deliverable, its tests, and how it is verified. Carry over deferred/vNext work and any publish/release steps as their own tasks. +1. *Decide where the tasks live.* If the work is spinning off into its own project/repo, move the parent task into that project's =todo.org= (and relocate the spec with it); otherwise use the current project's =todo.org=. One parent task owns the effort; the phase tasks hang under it. *Stamp the binding:* the parent task's =:PROPERTIES:= drawer gets a =:SPEC_ID:= line holding the spec's status-heading UUID. That property is the durable join task-audit uses to police =DOING= specs (a =DOING= spec whose bound parent is closed, archived, or missing gets flagged). + +2. *Create one task per implementation phase* from the spec's =Implementation phases=, in dependency order, so the task set as a whole describes the *full* milestone (e.g. v1) with no gaps. Each task body names the deliverable, its tests, and how it is verified. Carry over deferred/vNext work and any publish/release steps as their own tasks. *Always end the set with the flip task:* a final "flip the spec to IMPLEMENTED (+ dated history line + mirror)" task under the same parent — the tracked obligation that closes the lifecycle loop when the build finishes. Never skip it; "a human remembers" is the failure mode this exists to prevent. 3. *Turn a critical eye on completeness.* Re-read the spec — every phase, every acceptance criterion, every named deliverable, every data-safety/principle rule — and confirm each has a home in a task. The work is not done when the tasks merely exist; it is done when nothing in the spec is left untracked. This completeness pass is mandatory regardless of project type. diff --git a/claude-templates/.ai/workflows/spec-review.org b/claude-templates/.ai/workflows/spec-review.org index 001238e..d4998eb 100644 --- a/claude-templates/.ai/workflows/spec-review.org +++ b/claude-templates/.ai/workflows/spec-review.org @@ -50,6 +50,11 @@ Run it *early* — design review exists to catch viability problems and costly m Before Phase 1, verify the file under review ends with =-spec.org=. Every design, decision, or planning document under a project's =docs/= directory carries that suffix as its identifier. The =.org= extension alone is not enough because =docs/= holds non-spec org files too (tutorials, frozen inventories, reference material). +*Location expectation (docs-lifecycle convention).* Formal specs live in =docs/specs/=. Whether that's enforced depends on whether the project has run its one-time =spec-sort= retrofit: + +- =:LAST_SPEC_SORT:= present in =.ai/notes.org= Workflow State → the project has sorted; a =-spec.org= file outside =docs/specs/= fails this precondition. Surface it: "this spec sits outside docs/specs/ — move it (and update inbound links) before review." +- Marker absent → legacy locations (=docs/= root, =docs/design/=) stay reviewable; add one nudge line to the review output ("this project's docs pile has never been spec-sorted — say 'run spec-sort' to sort it") and proceed. No legacy spec is ever unreviewable during the transition. + If the file does not end with =-spec.org=, stop immediately and surface the mismatch: #+begin_example @@ -167,6 +172,8 @@ Assign one label consistently: The most useful reviews move a spec from =Not ready= to =Ready with caveats= or =Ready= once decisions are captured. +*The =Ready= verdict flips the spec's lifecycle status.* spec-review owns the =DRAFT= → =READY= transition (docs-lifecycle convention): on assigning =Ready= (or =Ready with caveats= the author accepts), update the spec's top-level status heading keyword to =READY=, add a dated history line under it naming the review that passed, and set the Metadata =Status= mirror to =ready= — three lines, one file. Any other rubric label leaves the keyword where it stands (a re-review that finds new blockers on a =READY= spec demotes it back to =DRAFT= the same three-line way, with the reason in the history line). + Finding severity maps to blocking power: *high-priority findings block =Ready=* — they hold the rubric at =Not ready= (or =Ready with caveats= if the author accepts and tracks them) until dispositioned; *medium-priority findings are the author's discretion* and don't block. State the blocking status on each finding so the author running spec-response knows which ones gate the rubric. Then update the spec's review history. Specs should carry a bottom section named =Review and iteration history= (or the nearest existing equivalent) that tracks each material author/reviewer pass. Add a concise entry for this review even when the spec is ready and no findings are recorded. diff --git a/claude-templates/.ai/workflows/task-audit.org b/claude-templates/.ai/workflows/task-audit.org index 8dd2fb2..7d2b758 100644 --- a/claude-templates/.ai/workflows/task-audit.org +++ b/claude-templates/.ai/workflows/task-audit.org @@ -61,6 +61,8 @@ For each open task, read its body and cross-check its claims against the actual - *Calendar* — did a scheduled event happen; is a SCHEDULED/DEADLINE date now past. - *Meeting recordings* — if a task hinges on "did this conversation happen / what was said," check the recording queue (e.g. =~/sync/recordings/=) and transcribe via =process-meeting-transcript.org= if the answer lives in an un-transcribed recording. (This is exactly how a "did the interview happen?" task gets resolved instead of guessed.) +*Spec lifecycle reconcile (docs-lifecycle convention).* If the project has a =docs/specs/=, run the =:SPEC_ID:= query as part of this phase: for each spec whose top-level status heading reads =DOING=, find the =todo.org= task whose =:SPEC_ID:= property matches the spec's =:ID:=. Flag the spec NEEDS-USER when that bound parent is =DONE=/=CANCELLED=, archived, or missing — the build finished (or evaporated) without the =IMPLEMENTED= flip, exactly the drift this check exists to catch. Check the parent's own keyword, not its children (completed children become dated entries and the final flip task is a child, so child-counting misleads). + Assign each task a bucket (CURRENT / STALE / NEEDS-USER) and, for STALE, the specific factual update. *Scale tactic.* For a large open-task set, dispatch read-only investigation sub-agents over batches of tasks (parallel-safe per =subagents.md= — independent read-only domains). Each returns a per-task bucket + suggested update. *Never* let sub-agents write to =todo.org= concurrently — apply all edits serially in the main thread (concurrent writes to one file race and lose work). @@ -402,8 +402,8 @@ Codex re-read the revised [[file:docs/specs/2026-07-01-docs-lifecycle-spec.org][ *** 2026-07-01 Wed @ 23:34:15 -0400 Decomposed into build tasks; spec flipped READY → DOING spec-response Phase 6 run: this parent now carries the =:SPEC_ID:= binding (the spec's status-heading UUID), the phase tasks below track the build, and the spec's status heading is DOING. Completeness pass done: all ten acceptance criteria have homes across the phase tasks; vNext (org-agenda view) was already filed as the [#D] task below. -*** TODO Phase 1 — docs-lifecycle rule + spec-workflow updates :solo: -Write claude-rules/docs-lifecycle.md (the generalized shape). Update, canonical-side: spec-create (emit into docs/specs/, two-sequence keyword header + status heading + :ID: in the template, DRAFT stamped at authoring), spec-review (compatibility rule — legacy locations accepted until :LAST_SPEC_SORT: stamped, then docs/specs/ hardens; DRAFT→READY flip = keyword + history + mirror), spec-response (owns READY→DOING at Phase 6; stamps :SPEC_ID: on the build parent; always emits the final flip-to-IMPLEMENTED task), task-audit (reconcile bullet: :SPEC_ID: query flags a DOING spec whose bound parent is closed/archived/missing). Verify: workflow-integrity bats + sync-check clean + make test. +*** 2026-07-01 Wed @ 23:39:10 -0400 Phase 1 landed — docs-lifecycle rule + four spec-workflow updates +claude-rules/docs-lifecycle.md written and linked machine-wide (make install). Canonical-side updates: spec-create Phase 5 + template (docs/specs/ location, two-sequence keyword header, DRAFT status heading with :ID:, transition mechanics), spec-review (location expectation with the legacy compatibility rule keyed on :LAST_SPEC_SORT:, plus the DRAFT→READY flip — and the demote-back-to-DRAFT path a failed re-review takes), spec-response Phase 6 (owns READY→DOING, stamps :SPEC_ID: on the build parent, always emits the flip-to-IMPLEMENTED task), task-audit Phase B (the :SPEC_ID: reconcile query, checking the parent's keyword rather than counting children). Mirror synced; make test green end to end. *** TODO Phase 2 — spec-sort helper + bats suite :solo: Build claude-templates/.ai/scripts/spec-sort per the spec's retrofit contract: classify (Decisions AND Implementation phases), evidence-based confirm gate, plan + validate before first write, move + rename to -spec.org + status heading + :ID:, relink file: links per the rewritten-roots/report-only contract, clean-worktree preflight (--allow-dirty override), named recovery on mid-apply failure (incl. deleting created untracked copies), residue-grep exit gate, :LAST_SPEC_SORT: stamp. Bats in claude-templates/.ai/scripts/tests/ covering classification, confirm gate, plan validation, move+rename, relink, preflight, forced-failure recovery output, idempotence, marker stamp. Verify: make test green, sync-check clean. |
