diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-12 19:33:12 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-12 19:33:12 -0500 |
| commit | 22edacfd03de68eabd96d9aaa98a4dd5693535a6 (patch) | |
| tree | 242b67435ea9965e23728ad5a9ba73180dac0257 | |
| parent | f058b4c15a67ce3b54e306e8b4778aa3cb540c7c (diff) | |
| download | rulesets-22edacfd03de68eabd96d9aaa98a4dd5693535a6.tar.gz rulesets-22edacfd03de68eabd96d9aaa98a4dd5693535a6.zip | |
feat(workflows): SUPERSEDED/CANCELLED decision states + old-model gate
A superseded decision now flips to SUPERSEDED (linking its replacement) and a moot one to CANCELLED. Both are done-class via a #+TODO: header the spec template auto-adds, so the [/] cookie counts them resolved and neither blocks implementation-ready. The TODO/DONE pair alone had lost the old State: field's superseded value.
spec-review's gate and Ready rubric now read "no decision is still TODO", and a spec still on the retired State: field model fails the gate item until converted. The gate as first written would have vacuously passed old specs, which have no decision tasks at all.
| -rw-r--r-- | .ai/workflows/spec-create.org | 5 | ||||
| -rw-r--r-- | .ai/workflows/spec-review.org | 9 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/spec-create.org | 5 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/spec-review.org | 9 |
4 files changed, 20 insertions, 8 deletions
diff --git a/.ai/workflows/spec-create.org b/.ai/workflows/spec-create.org index daf56f7..f90c511 100644 --- a/.ai/workflows/spec-create.org +++ b/.ai/workflows/spec-create.org @@ -53,7 +53,7 @@ Capture, in this order: - =Context:= the forces motivating the choice - =Decision:= the call, stated actively ("We will…") - =Consequences:= what gets easier *and* what gets harder (both halves — a decision with only upsides is under-examined) - An *open* decision is a =TODO= task with an *owner* and a *by-when*; agreeing flips it to =DONE=. If the decision-maker doesn't agree, it stays =TODO= and the back-and-forth continues under a =*** Discussion= child header — never overwrite the decision body to win an argument. Put a =[/]= statistics cookie on the =* Decisions= heading so the resolved tally is visible at a glance. To revisit a =DONE= decision, either reopen it to =TODO= (carrying the new dispute in its =*** Discussion= thread, prior text preserved) or write a fresh decision that supersedes it; don't silently rewrite the old one. Keep decisions inline here; promote to a standalone numbered ADR only when a decision outlives or spans beyond this one spec. (The per-decision =TODO/DONE= is distinct from the spec-wide =Status= in the metadata header — see the implementation-ready gate in Phase 6.) + An *open* decision is a =TODO= task with an *owner* and a *by-when*; agreeing flips it to =DONE=. If the decision-maker doesn't agree, it stays =TODO= and the back-and-forth continues under a =*** Discussion= child header — never overwrite the decision body to win an argument. Put a =[/]= statistics cookie on the =* Decisions= heading so the resolved tally is visible at a glance. To revisit a =DONE= decision: reopen it to =TODO= (new dispute in its =*** Discussion= thread, prior text preserved) when the same decision is being re-argued; flip it to =SUPERSEDED= with a link to the replacing decision when a fresh decision takes its place; flip it to =CANCELLED= with a one-line reason when scope changes make it moot. All three keep the original body intact — never silently rewrite a resolved decision. =SUPERSEDED= and =CANCELLED= are done-class (the =#+TODO:= header in the template defines them), so they count as resolved in the =[/]= cookie and don't block the gate. Keep decisions inline here; promote to a standalone numbered ADR only when a decision outlives or spans beyond this one spec. (The per-decision =TODO/DONE= is distinct from the spec-wide =Status= in the metadata header — see the implementation-ready gate in Phase 6.) ** Phase 3 — Make it buildable @@ -90,7 +90,7 @@ This is where the spec earns a "Ready" from review: an engineer must be able to ** Phase 6 — Hand-off readiness Self-assess against =spec-review='s rubric before handing off, so the review starts from a clean spec instead of catching basics: -- *Decisions:* every decision is =DONE= (the =[/]= cookie reads complete), or the author *consciously accepts* the risk of building with one still =TODO= (recorded). *Implementation-ready gate:* the spec Status cannot move past =draft= to an implementation-ready state while any decision is still =TODO=. +- *Decisions:* no decision is still =TODO= (the =[/]= cookie reads complete), or the author *consciously accepts* the risk of building with one open (recorded). =SUPERSEDED= and =CANCELLED= count as resolved. *Implementation-ready gate:* the spec Status cannot move past =draft= to an implementation-ready state while any decision is still =TODO=. - *APIs:* every external API assumption is verified or listed as a research prerequisite — otherwise the honest verdict is =Needs research=. - *Self-rubric:* Ready / Ready with caveats / Not ready / Needs research. If it isn't at least =Ready with caveats=, keep drafting. - *Defer:* log open decisions and vNext items to =todo.org= (v1 work =[#B]=, vNext/someday =[#D]=) — don't leave them only in the spec. @@ -103,6 +103,7 @@ 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 ,* Metadata | Status | draft | diff --git a/.ai/workflows/spec-review.org b/.ai/workflows/spec-review.org index 61c1239..d956f00 100644 --- a/.ai/workflows/spec-review.org +++ b/.ai/workflows/spec-review.org @@ -74,7 +74,7 @@ Mark the spec implementation-ready only if *all* of these hold: - Scope is explicit: v1, out-of-scope, and vNext are separated. - Project principles are explicit where the feature touches user data, remote systems, destructive actions, long-running operations, or public extension points. - All prior review questions/recommendations are answered or intentionally deferred. -- Every decision in the spec's =* Decisions= section is =DONE= (the =[/]= cookie reads complete), or each still-=TODO= decision carries a consciously-accepted, recorded risk. +- Every decision in the spec's =* Decisions= section is resolved — no =TODO= remains (the =[/]= cookie reads complete; =SUPERSEDED= and =CANCELLED= count as resolved), or each still-open decision carries a consciously-accepted, recorded risk. A spec still on the retired =State: proposed | accepted | superseded= field model fails this item until converted to decision tasks — convert on the next material touch. - The expected UX is concrete enough to implement without guessing. - Existing platform/framework affordances are reused, wrapped, or intentionally replaced; lost opportunities are called out. - The data model, state ownership, persistence, and sync behavior are defined. @@ -186,7 +186,7 @@ Deferred features to capture in task tracking. Assign one label consistently: -- =Ready= — no blocking open questions; implementation can start. Requires every decision in the spec's =* Decisions= section to be =DONE= (the =[/]= cookie reads complete) — a decision still =TODO= holds the rubric at =Not ready=, or =Ready with caveats= if the author consciously accepts and records the risk. +- =Ready= — no blocking open questions; implementation can start. Requires no decision in the spec's =* Decisions= section to still be =TODO= (the =[/]= cookie reads complete; =SUPERSEDED= and =CANCELLED= count as resolved) — a decision still =TODO= holds the rubric at =Not ready=, or =Ready with caveats= if the author consciously accepts and records the risk. - =Ready with caveats= — can start if the caveats are accepted and tracked. - =Not ready= — blocking ambiguity / missing decisions would force implementers to invent product behavior. - =Needs research= — external API/library/platform assumptions must be verified first. @@ -349,3 +349,8 @@ Sources: - *What:* Reconciled this workflow to spec-create's new Decisions convention (each decision is an org =TODO= task that flips to =DONE= on agreement, with a =[/]= cookie on the =* Decisions= heading). The Phase 1/3 readiness gate gains an all-decisions-=DONE= item, and the Phase 6 =Ready= rubric label now requires the =[/]= cookie to read complete (a still-=TODO= decision holds the rubric at =Not ready=, or =Ready with caveats= on a recorded, consciously-accepted risk). - *Why:* The convention change landed in spec-create.org via an .emacs.d handoff (originated in its keymap-consolidation spec); the rubric still gated on the retired =State:= field model. - *Artifacts:* Handoff =inbox/2026-06-12-1906-from-.emacs.d-spec-create-decisions-todo-note.org=. Paired spec-create.org and spec-response.org edits in the same commit. + +** 2026-06-12 Fri @ 19:30:03 -0500 — Claude Code (rulesets) — author +- *What:* Two refinements to the same-day decisions convention after Craig's review: the gate item and =Ready= rubric now read "no decision is still =TODO=" with =SUPERSEDED= and =CANCELLED= counting as resolved (spec-create's template defines them as done-class keywords via a =#+TODO:= header), and a spec still on the retired =State:= field model explicitly fails the gate item until converted — closing the vacuous-pass hole on old specs. +- *Why:* Review of the freshly-landed convention flagged that TODO/DONE alone lost the old model's superseded state and that the gate as written would silently pass a spec with no decision tasks at all. Craig chose the two done-class keywords and the auto-added =#+TODO:= header (the in-file header is what makes custom keywords portable). +- *Artifacts:* Paired spec-create.org edits (keyword scheme + template header) in the same commit. diff --git a/claude-templates/.ai/workflows/spec-create.org b/claude-templates/.ai/workflows/spec-create.org index daf56f7..f90c511 100644 --- a/claude-templates/.ai/workflows/spec-create.org +++ b/claude-templates/.ai/workflows/spec-create.org @@ -53,7 +53,7 @@ Capture, in this order: - =Context:= the forces motivating the choice - =Decision:= the call, stated actively ("We will…") - =Consequences:= what gets easier *and* what gets harder (both halves — a decision with only upsides is under-examined) - An *open* decision is a =TODO= task with an *owner* and a *by-when*; agreeing flips it to =DONE=. If the decision-maker doesn't agree, it stays =TODO= and the back-and-forth continues under a =*** Discussion= child header — never overwrite the decision body to win an argument. Put a =[/]= statistics cookie on the =* Decisions= heading so the resolved tally is visible at a glance. To revisit a =DONE= decision, either reopen it to =TODO= (carrying the new dispute in its =*** Discussion= thread, prior text preserved) or write a fresh decision that supersedes it; don't silently rewrite the old one. Keep decisions inline here; promote to a standalone numbered ADR only when a decision outlives or spans beyond this one spec. (The per-decision =TODO/DONE= is distinct from the spec-wide =Status= in the metadata header — see the implementation-ready gate in Phase 6.) + An *open* decision is a =TODO= task with an *owner* and a *by-when*; agreeing flips it to =DONE=. If the decision-maker doesn't agree, it stays =TODO= and the back-and-forth continues under a =*** Discussion= child header — never overwrite the decision body to win an argument. Put a =[/]= statistics cookie on the =* Decisions= heading so the resolved tally is visible at a glance. To revisit a =DONE= decision: reopen it to =TODO= (new dispute in its =*** Discussion= thread, prior text preserved) when the same decision is being re-argued; flip it to =SUPERSEDED= with a link to the replacing decision when a fresh decision takes its place; flip it to =CANCELLED= with a one-line reason when scope changes make it moot. All three keep the original body intact — never silently rewrite a resolved decision. =SUPERSEDED= and =CANCELLED= are done-class (the =#+TODO:= header in the template defines them), so they count as resolved in the =[/]= cookie and don't block the gate. Keep decisions inline here; promote to a standalone numbered ADR only when a decision outlives or spans beyond this one spec. (The per-decision =TODO/DONE= is distinct from the spec-wide =Status= in the metadata header — see the implementation-ready gate in Phase 6.) ** Phase 3 — Make it buildable @@ -90,7 +90,7 @@ This is where the spec earns a "Ready" from review: an engineer must be able to ** Phase 6 — Hand-off readiness Self-assess against =spec-review='s rubric before handing off, so the review starts from a clean spec instead of catching basics: -- *Decisions:* every decision is =DONE= (the =[/]= cookie reads complete), or the author *consciously accepts* the risk of building with one still =TODO= (recorded). *Implementation-ready gate:* the spec Status cannot move past =draft= to an implementation-ready state while any decision is still =TODO=. +- *Decisions:* no decision is still =TODO= (the =[/]= cookie reads complete), or the author *consciously accepts* the risk of building with one open (recorded). =SUPERSEDED= and =CANCELLED= count as resolved. *Implementation-ready gate:* the spec Status cannot move past =draft= to an implementation-ready state while any decision is still =TODO=. - *APIs:* every external API assumption is verified or listed as a research prerequisite — otherwise the honest verdict is =Needs research=. - *Self-rubric:* Ready / Ready with caveats / Not ready / Needs research. If it isn't at least =Ready with caveats=, keep drafting. - *Defer:* log open decisions and vNext items to =todo.org= (v1 work =[#B]=, vNext/someday =[#D]=) — don't leave them only in the spec. @@ -103,6 +103,7 @@ 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 ,* Metadata | Status | draft | diff --git a/claude-templates/.ai/workflows/spec-review.org b/claude-templates/.ai/workflows/spec-review.org index 61c1239..d956f00 100644 --- a/claude-templates/.ai/workflows/spec-review.org +++ b/claude-templates/.ai/workflows/spec-review.org @@ -74,7 +74,7 @@ Mark the spec implementation-ready only if *all* of these hold: - Scope is explicit: v1, out-of-scope, and vNext are separated. - Project principles are explicit where the feature touches user data, remote systems, destructive actions, long-running operations, or public extension points. - All prior review questions/recommendations are answered or intentionally deferred. -- Every decision in the spec's =* Decisions= section is =DONE= (the =[/]= cookie reads complete), or each still-=TODO= decision carries a consciously-accepted, recorded risk. +- Every decision in the spec's =* Decisions= section is resolved — no =TODO= remains (the =[/]= cookie reads complete; =SUPERSEDED= and =CANCELLED= count as resolved), or each still-open decision carries a consciously-accepted, recorded risk. A spec still on the retired =State: proposed | accepted | superseded= field model fails this item until converted to decision tasks — convert on the next material touch. - The expected UX is concrete enough to implement without guessing. - Existing platform/framework affordances are reused, wrapped, or intentionally replaced; lost opportunities are called out. - The data model, state ownership, persistence, and sync behavior are defined. @@ -186,7 +186,7 @@ Deferred features to capture in task tracking. Assign one label consistently: -- =Ready= — no blocking open questions; implementation can start. Requires every decision in the spec's =* Decisions= section to be =DONE= (the =[/]= cookie reads complete) — a decision still =TODO= holds the rubric at =Not ready=, or =Ready with caveats= if the author consciously accepts and records the risk. +- =Ready= — no blocking open questions; implementation can start. Requires no decision in the spec's =* Decisions= section to still be =TODO= (the =[/]= cookie reads complete; =SUPERSEDED= and =CANCELLED= count as resolved) — a decision still =TODO= holds the rubric at =Not ready=, or =Ready with caveats= if the author consciously accepts and records the risk. - =Ready with caveats= — can start if the caveats are accepted and tracked. - =Not ready= — blocking ambiguity / missing decisions would force implementers to invent product behavior. - =Needs research= — external API/library/platform assumptions must be verified first. @@ -349,3 +349,8 @@ Sources: - *What:* Reconciled this workflow to spec-create's new Decisions convention (each decision is an org =TODO= task that flips to =DONE= on agreement, with a =[/]= cookie on the =* Decisions= heading). The Phase 1/3 readiness gate gains an all-decisions-=DONE= item, and the Phase 6 =Ready= rubric label now requires the =[/]= cookie to read complete (a still-=TODO= decision holds the rubric at =Not ready=, or =Ready with caveats= on a recorded, consciously-accepted risk). - *Why:* The convention change landed in spec-create.org via an .emacs.d handoff (originated in its keymap-consolidation spec); the rubric still gated on the retired =State:= field model. - *Artifacts:* Handoff =inbox/2026-06-12-1906-from-.emacs.d-spec-create-decisions-todo-note.org=. Paired spec-create.org and spec-response.org edits in the same commit. + +** 2026-06-12 Fri @ 19:30:03 -0500 — Claude Code (rulesets) — author +- *What:* Two refinements to the same-day decisions convention after Craig's review: the gate item and =Ready= rubric now read "no decision is still =TODO=" with =SUPERSEDED= and =CANCELLED= counting as resolved (spec-create's template defines them as done-class keywords via a =#+TODO:= header), and a spec still on the retired =State:= field model explicitly fails the gate item until converted — closing the vacuous-pass hole on old specs. +- *Why:* Review of the freshly-landed convention flagged that TODO/DONE alone lost the old model's superseded state and that the gate as written would silently pass a spec with no decision tasks at all. Craig chose the two done-class keywords and the auto-added =#+TODO:= header (the in-file header is what makes custom keywords portable). +- *Artifacts:* Paired spec-create.org edits (keyword scheme + template header) in the same commit. |
