@pilotspace/add 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,6 +47,8 @@ A spec delta feeds the *next feature*. But a loop also teaches the **method itse
47
47
 
48
48
  Each delta is one tagged entry — `- [COMPETENCY · status] the learning (evidence: a pointer)` — and the evidence is **required**: a failing scenario, a production signal, a review note. No evidence means it is an opinion, not a delta. The AI **emits** deltas as `open`; it never consolidates its own. Consolidation is judgment, and judgment is the human's — the same verify/observe decision point that keeps the AI from grading its own work.
49
49
 
50
+ **The ship review.** Before the consolidation, once a milestone's goal is met, the AI fills the milestone's `## Close — ship review` — the whole-milestone, cross-task evidence a person reads *before* checking the exit-criteria boxes (it is evidence, **not a new gate**). It has three parts: **ship by domain** — what changed in each bounded context (`tooling` · `skill` · `book`); **cross-task evidence** — one row per task (its gate, its tests, any residue); and a **goal-met map** — each exit criterion tied to the evidence that satisfies it. The AI then defines the milestone's **release steps**: the ordered, tool-agnostic hints to ship the milestone, of which `merge` is one small step (a pull request, an exported hand-off document, a tag or a publish are others). Those steps **feed** the release scope, not a second flow. The ritual itself lives in the `add` skill's `loop.md`; this chapter only names it.
51
+
50
52
  **The consolidation.** At milestone close (or on demand, when open deltas pile up), a person runs the retrospective consolidation: **gather** every `open` delta across the milestone's tasks, **group** them by competency, **propose** the exact foundation edit for each, **confirm** with the human one by one, then **write** — append-only, newest-first (the newest record prepended at the top) — flipping each delta to `folded` (merged) or `rejected` (considered and deliberately not merged, left in place so the trail survives), and bumping the `foundation-version:` marker. `DDD`/`SDD`/`UDD` deltas consolidate into the matching section of `PROJECT.md`; `TDD`/`ADD` consolidate into `CONVENTIONS.md` (they sharpen the engine, not the product); and **every** consolidation also prepends one row at the top of `PROJECT.md` §Key Decisions — the universal, auditable record of what the foundation learned.
51
53
 
52
54
  **Tooling.** `add.py deltas` lists every open delta across the project (so nothing waiting to be consolidated is invisible); `add.py check` lints each delta's well-formedness — known competency tag, valid status, non-empty evidence. There is deliberately **no `add.py fold`**: the engine stays judgment-free, and the ritual lives with the human who owns it.
@@ -42,6 +42,10 @@
42
42
 
43
43
  **The decision arc** — the three engine-sourced lines a gate report opens with at every **decision point**: `goal:` the milestone goal the work serves · `done:` the achievement, the proven progress toward it (the gate reports render this line as `done`) · `plan:` what comes next. What `done` reports adapts per gate (verify: tests + evidence · milestone close: exit-criteria met · intake: the request sized) while the three-part shape stays constant. Rendered first, above the report's summary, so the human confirms with sight of the whole trajectory, not a local snapshot. Engine-sourced like all evidence — goal · done · plan are pulled from `add.py` output, never re-typed. Presentation only: it never adds a gate or changes a `PASS` / `RISK-ACCEPTED` / `HARD-STOP` / freeze outcome. The report it opens is the chat report a person reads at a decision point — distinct from the three Test/Quality/Risk reports a verify gate produces ([11 Governance](./11-governance.md)). See the `add` skill's `report-template.md`.
44
44
 
45
+ **Guided decision** — a **decision point** presented not as a bare next-step line but as one highlighted **recommended pick** plus its real, described alternatives (each with its one-line consequence), so the human chooses with the recommendation and what each option costs already in view. It refines the report's DECISION block — composing with **the decision arc**, never adding a gate — and fires at human gates only (never at an autonomous `[you drive]` step). The sibling of the decision arc: both are what the human sees when it is their turn. See the `add` skill's `report-template.md` for the convention itself.
46
+
47
+ **Recommended pick** — the one option a **guided decision** highlights with the `▶ … (recommended)` marker: exactly one, never zero and never two. The AI's confidence self-score informs the pick; the human overrides it freely. See **Guided decision**.
48
+
45
49
  **Specification bundle** (formerly "the one-approval front") — §1–§4 of a task (spec · scenarios · contract · failing tests) drafted by the AI as one piece and approved by a person **once**, at the contract freeze. Rejecting any part returns the whole bundle to draft. The single approval it carries is the bundle approval.
46
50
 
47
51
  **Retrospective consolidation** (formerly "the fold / fold ritual") — the milestone-close (or on-demand) step where a person gathers `open` lessons learned, confirms each, and the AI writes them append-only into the versioned foundation, bumping `foundation-version:`. The AI never self-approves a consolidation. The machine names keep their names: `fold.md`, the `folded` delta status, and `add.py deltas`.
@@ -80,6 +84,10 @@
80
84
 
81
85
  **Release scope level** — the fifth scope level: releasing as its own granularity, orthogonal to the stage. A release bundles ≥1 closed milestone (never forced one-per-milestone) and may be cut at any stage — prototype preview, mvp beta, production GA. Distinct from milestone-close (feature-complete + consolidated) and from stage graduation (which changes rigor, not version). See **Scope level** and [16 · Releasing](./16-releasing.md).
82
86
 
87
+ **Ship review** — the whole-milestone, cross-task evidence the AI fills at milestone close in the `## Close — ship review` section: ship-by-domain (what changed per bounded context), cross-task evidence (one row per task: gate · tests · residue), and a goal-met map (each exit criterion tied to its evidence). A person reads it *before* checking the exit-criteria boxes — evidence, not a new gate. The ritual lives in the `add` skill's `loop.md`. See [09 · The Loop](./09-the-loop.md).
88
+
89
+ **Release steps** — the AI-defined, per-milestone ordered hints to ship a closed milestone, of which `merge` is one small step (a pull request, an exported hand-off document, a tag or a publish are others). Defined at close and **fed** into the release scope (see **Release**), never a second flow.
90
+
83
91
  **Readiness floor** — the engine-enforced pre-cut gate `add.py release` applies before it records anything: a green suite, zero open security `HARD-STOP`, a closed-and-unreleased milestone to bundle, and every riding `RISK-ACCEPTED` waiver disclosed in the notes. Its four rejects are `release_security_open` (un-forceable) · `release_tests_red` · `release_no_closed_milestone` · `release_undisclosed_waiver`; `--force` may override every reject except the security stop.
84
92
 
85
93
  **RELEASES.md ledger** — the append-only, newest-first trail of release rows at the project root (date · version · milestones · waivers shipped · evidence). Like the §Key Decisions log it is never rewritten; a superseded or yanked version is recorded as a new row. The ledger is the attribution source — a milestone is "released" because a row says so — which is why the `→ releasable` cue never has to read a milestone file.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pilotspace/add",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "ADD (AI-Driven Development) — a minimal, state-tracked Claude Code skill that drives every feature through Specify → Scenarios → Contract → Tests → Build → Verify → Observe. Ships the AIDD book as its trust layer.",
5
5
  "bin": {
6
6
  "add": "bin/cli.js"
@@ -8,6 +8,9 @@
8
8
  "publishConfig": {
9
9
  "access": "public"
10
10
  },
11
+ "dependencies": {
12
+ "@clack/prompts": "^1.5.1"
13
+ },
11
14
  "scripts": {
12
15
  "test": "python3 -m unittest discover -s tooling -p 'test_*.py'",
13
16
  "prepublishOnly": "python3 -m unittest discover -s tooling -p 'test_packaging.py'"
@@ -11,6 +11,15 @@ description: >-
11
11
  new feature and you want spec/tests-first discipline instead of vague-prompt
12
12
  coding. Also use it to resume work across sessions (it reads `.add/state.json`
13
13
  so you never re-read the whole repo).
14
+ user-invocable: true
15
+ when_to_use: "Invoke in any repo with a `.add/` directory, or when the user wants spec/tests-first feature work, resumes ADD work, or asks to start/advance a task."
16
+ category: workflows
17
+ keywords: [add, aidd, ai-driven-development, spec-first, tdd, contract, scenarios, verify, milestone, task-orchestration]
18
+ argument-hint: "[describe your goals] OR [describe what is your expectation] (e.g., implement authentication flows for both server api and client side to handle email + Google OAuth login, session refresh, RBAC guards, and a profile page that survives page reloads)"
19
+ license: MIT
20
+ metadata:
21
+ author: add
22
+ version: "1.0.0"
14
23
  ---
15
24
 
16
25
  # ADD — the orchestration engine
@@ -25,6 +34,23 @@ you are so context never rots across sessions.
25
34
 
26
35
  ## Always start here (orient — do not skip)
27
36
 
37
+ The engine lives at `.add/tooling/add.py` and the book at `.add/docs/`. Make sure the
38
+ engine is in this project before anything else:
39
+
40
+ - If `.add/tooling/add.py` exists, go straight to `status` below.
41
+ - If it does NOT exist, ADD was installed as a Claude Code plugin — the engine and the
42
+ book ride in the plugin, not the project. Materialize them into the project once, before
43
+ any other step:
44
+
45
+ ```bash
46
+ node "${CLAUDE_PLUGIN_ROOT}/bin/cli.js" init --no-skill
47
+ ```
48
+
49
+ That drops `.add/tooling/` (the engine) and `.add/docs/` (the book) here, so the engine,
50
+ the book, and the agent-agnostic guideline block in `CLAUDE.md` all work for every agent
51
+ and for a human at the shell — exactly like an npm or pip install. The skill itself stays
52
+ in the plugin, so nothing is duplicated.
53
+
28
54
  Run the tool to find the resume point instead of re-reading the repo:
29
55
 
30
56
  ```bash
package/skill/add/fold.md CHANGED
@@ -1,60 +1,77 @@
1
- # Consolidating deltas — how the foundation self-improves
1
+ # Consolidating lessons — how the foundation self-improves
2
2
 
3
- This **closes the loop**. `deltas.md` lets a task EMIT learnings (`open` lessons learned in its
4
- OBSERVE phase); the retrospective consolidation gathers the confirmed ones and writes them into a **versioned foundation**,
5
- so `DDD · SDD · UDD · TDD · ADD` sharpen across milestones instead of drifting.
3
+ This **closes the loop**. `deltas.md` lets a task EMIT lessons (`open` lessons learned in its
4
+ OBSERVE phase); the retrospective consolidation gathers the confirmed ones and writes them into a
5
+ **versioned foundation**, so `DDD · SDD · UDD · TDD · ADD` sharpen across milestones instead of drifting.
6
6
 
7
- You (the AI) **gather and propose**; the **human confirms**; you then write the **append-only** consolidation.
8
- You never self-approve a consolidation consolidating is judgment (see the verify/observe decision point).
7
+ Since v3 this is mechanized by a command `add.py fold` but the command stays **judgment-free**:
8
+ it only ever TRANSCRIBES each lesson's OWN captured text into its routed home and bumps the version.
9
+ It NEVER composes or merges prose, and it never **self-approves** a consolidation — running the
10
+ command records the human's confirmation, it does not replace their judgment. Deciding WHICH lessons
11
+ to keep, and later polishing the raw transcribed bullets into lean one-screen prose, remain the
12
+ human's work — the latter via the **compaction door** (`compact-foundation.md`).
9
13
 
10
14
  ## When to consolidate
11
15
 
12
16
  At **milestone close** (the natural "version bump to the foundation"), or **on demand** when open
13
- deltas have piled up. This is a convention, not a command — there is no `add.py fold`; the consolidation
14
- lives here so the engine stays judgment-free.
17
+ lessons have piled up. One run of `add.py fold` is ONE consolidation session: it bumps
18
+ `foundation-version` exactly once and stamps every lesson it resolves with that one new version.
15
19
 
16
20
  ## The ritual
17
21
 
18
- 1. **Gather** — scan every task's §7 OBSERVE block for lesson-learned lines still `open` (`add.py deltas` reads them by the machine heading).
19
- 2. **Group** — bucket them by competency (`DDD · SDD · UDD · TDD · ADD`).
20
- 3. **Propose** for each, draft the exact foundation edit (see routing) and show the human.
21
- 4. **Confirm** — the human accepts or declines each delta. No write happens without this.
22
- 5. **Write** prepend the accepted edits at the top (newest-first), flip each delta's status, and bump the version.
22
+ 1. **Gather** — `add.py deltas` reads every task's OBSERVE block for lessons still `open` (by the machine heading).
23
+ 2. **Confirm** — decide which to keep; a lesson you do NOT want is marked `rejected` and left in place
24
+ (see below). Running `add.py fold` over the rest IS your confirmation the command needs no separate flag.
25
+ 3. **Write** — `add.py fold [--task <slug>] [--comp <TAG>]` performs the mechanical write atomically:
26
+ - flips each selected `open` lesson to `folded` and stamps it `[folded foundation-version N]`;
27
+ - transcribes each lesson VERBATIM as one bullet at the TOP (newest-first) of its routed section (below);
28
+ - prepends one row to §Key Decisions (date · what · why · outcome);
29
+ - bumps `foundation-version` by one.
30
+ Validate-all-then-write: if any precondition fails the command writes NOTHING (the tree stays byte-identical).
31
+ 4. **Propose & polish** — the transcribed bullets are RAW; afterward you consolidate/merge them into
32
+ lean prose (append-only, newest-first) via the compaction door. The engine never does this editorial step.
23
33
 
24
34
  ## Consolidation routing (every competency has a home)
25
35
 
26
36
  | competency | consolidates into | how |
27
37
  |------------|-----------|-----|
28
- | `DDD` | `PROJECT.md` §Domain (DDD) | refine/append a model bullet |
29
- | `SDD` | `PROJECT.md` §Spec / Living Document (SDD) | refine/append a settled-vs-open line |
30
- | `UDD` | `PROJECT.md` §Users (UDD) | refine/append a UX line |
31
- | `TDD` | `CONVENTIONS.md` | append a testing convention (no PROJECT.md section — it is the engine) |
32
- | `ADD` | `CONVENTIONS.md` | append a build/harness convention (likewise the engine) |
38
+ | `DDD` | `PROJECT.md` §Domain | a transcribed bullet at the top |
39
+ | `SDD` | `PROJECT.md` §Spec | a transcribed bullet at the top |
40
+ | `UDD` | `PROJECT.md` §Users | a transcribed bullet at the top |
41
+ | `TDD` | `CONVENTIONS.md` §Method learnings | a transcribed bullet (no PROJECT.md section — it is the engine) |
42
+ | `ADD` | `CONVENTIONS.md` §Method learnings | a transcribed bullet (likewise the engine) |
33
43
 
34
- **Every** consolidation — whatever the competency — ALSO prepends one row at the TOP of `PROJECT.md` **§Key Decisions** (newest-first)
35
- (date · decision · why · outcome): the universal, auditable trail of what the foundation learned.
44
+ **Every** consolidation — whatever the competency — ALSO prepends one row at the TOP of `PROJECT.md`
45
+ **§Key Decisions** (newest-first) (date · decision · why · outcome): the universal, auditable trail of
46
+ what the foundation learned.
36
47
 
37
48
  ## Status transitions & version
38
49
 
39
- - on **confirm**: the delta moves `open` → `folded` (and its edit is prepended at the top of the routed target, newest-first).
40
- - on **decline**: the delta moves `open` → `rejected` and is **left in place** — never deleted —
50
+ - on **confirm**: the lesson moves `open` → `folded` (its text transcribed at the top of the routed target, newest-first).
51
+ - on **decline**: the lesson moves `open` → `rejected` and is **left in place** — never deleted —
41
52
  so "we considered this and chose not to act" stays auditable.
42
- - a consolidation is **append-only (newest-first)**: it PREPENDS new bullets/rows at the top and never silently rewrites existing foundation text — EXCEPT via the recorded **compaction door** (`compact-foundation.md`): eligible (shipped + zero open residues) stable entries collapse upward into a rolled-up settled line at the tail. Reject: `open-residue-version` · `trail-loss` · `wrong-order`.
43
- - each consolidation session **bumps** the `foundation-version:` marker in `PROJECT.md` by one (monotonic int).
53
+ - a consolidation is **append-only (newest-first)**: it PREPENDS new bullets/rows at the top and never
54
+ silently rewrites existing foundation text — EXCEPT via the recorded **compaction door** (`compact-foundation.md`):
55
+ eligible (shipped + zero open residues) stable entries collapse upward into a rolled-up settled line at the tail.
56
+ - each `add.py fold` run **bumps** the `foundation-version:` marker in `PROJECT.md` by one (monotonic int).
44
57
 
45
- ## Reject codes (the AI is first check, the human the backstop)
58
+ ## Reject codes (the command is fail-closed; validate-all-then-write)
46
59
 
47
60
  <reject_codes>
48
- - `no_open_deltas` — nothing is `open` anywhere. The ritual is a no-op; do **not** bump the version.
49
- - `unconfirmed_fold` — a write was attempted without recorded human confirmation. The AI proposes;
50
- it never self-approves one. Stop and get confirmation.
51
- - `unroutable_delta` — a delta's competency is not one of the five, so it has no consolidation target. Fix the
52
- delta (it is malformed per `deltas.md`) before consolidating.
61
+ - `no_open_deltas` — nothing is `open` in the selected scope. The session is a no-op; the version is NOT bumped.
62
+ - `missing_route_section` — a lesson routes to a foundation section that does not exist (e.g. a `UDD`
63
+ lesson with no `## Users` section). Fail-closed: add the section header, then re-run. Nothing is written.
64
+ - `no_foundation_version` — `PROJECT.md` carries no parseable `foundation-version:` marker to bump.
53
65
  </reject_codes>
54
66
 
67
+ The convention-era codes `unconfirmed_fold` and `unroutable_delta` are **retired** (bridged here, not
68
+ silently dropped): invoking `add.py fold` IS the confirmation, so `unconfirmed_fold` no longer applies;
69
+ and routing is total over the five competencies, so a missing destination surfaces as the more precise
70
+ `missing_route_section` rather than `unroutable_delta`.
71
+
55
72
  ## Worked example (from this repo's own history)
56
73
 
57
- The `competency-deltas` task closed its OBSERVE with two deltas — the homeless ones, `TDD`/`ADD`,
74
+ The `competency-deltas` task closed its OBSERVE with two lessons — the homeless ones, `TDD`/`ADD`,
58
75
  which have no PROJECT.md section:
59
76
 
60
77
  ```
@@ -62,7 +79,8 @@ which have no PROJECT.md section:
62
79
  - [TDD · open] structural tests guard canonical artifacts but not their dogfood twins (evidence: scope-loop note + this build)
63
80
  ```
64
81
 
65
- At the next consolidation the human confirms both. Routing sends each to `CONVENTIONS.md` (a "sync the dogfood
66
- tree + assert md5 parity" convention), appends a §Key Decisions row for each, flips them to `folded`,
67
- and bumps `foundation-version` 1 → 2. The two competencies the foundation never tracked before now
68
- have a home — which is exactly why v5 routes TDD/ADD to `CONVENTIONS.md`.
82
+ At the next consolidation the human keeps both and runs `add.py fold`. Routing transcribes each into
83
+ `CONVENTIONS.md` §Method learnings, prepends a §Key Decisions row, flips them to `folded` with a
84
+ `[folded foundation-version N]` stamp, and bumps `foundation-version` 1 → 2 all in one atomic write.
85
+ The two competencies the foundation never tracked before now have a home — which is exactly why v5
86
+ routes `TDD`/`ADD` to `CONVENTIONS.md`.
@@ -40,7 +40,8 @@ That line is the trigger. Before both tallies complete, status is silent and not
40
40
  is what these milestones *contain*; this guide proposes them, it does not do them.
41
41
  4. **Human confirms** — present the roadmap via `report-template.md`, opening with the ARC
42
42
  (goal · done · plan): the stage-graduation goal, the MVP coverage that earns the move, and the
43
- plan the production milestones lay out. The human accepts, edits, or declines each drafted
43
+ plan the production milestones lay out. Render the roadmap as a guided choice — the recommended path
44
+ + its described alternatives (per `report-template.md`). The human accepts, edits, or declines each drafted
44
45
  milestone. No milestone is created without this; nothing advances on a draft the human has not confirmed.
45
46
  5. **Flip — the final step** — only now run `add.py stage production`. Because ≥1 production milestone
46
47
  now exists, the guard passes and the transition is recorded. This is the orchestration's last act.
@@ -35,6 +35,7 @@ First ask "does this change already-frozen scope?" → if yes, it is a `change-r
35
35
 
36
36
  Present the proposal to the human via `report-template.md` — open with the ARC (goal · done ·
37
37
  plan): the goal this request serves, what is already covered, and the plan the chosen bucket sets up.
38
+ Render the proposal as a guided choice — the recommended bucket + its described alternatives (per `report-template.md`).
38
39
 
39
40
  For every request, emit ONE of:
40
41
 
package/skill/add/loop.md CHANGED
@@ -37,10 +37,24 @@ When every task is done but the goal is not, `add.py status` shows
37
37
  4. **Create** each accepted task — `add.py new-task <slug> --title "..."` — and run it through
38
38
  the normal flow (specify → … → verify).
39
39
  5. **Repeat** until the work the goal needs is done.
40
- 6. **Close** — when the goal is genuinely met, check the exit-criteria boxes in `MILESTONE.md`,
41
- then `add.py milestone-done <slug>` succeeds (then consolidate the open deltas and archive).
42
- Present the close via `report-template.md` open with the ARC (goal · done · plan): the
43
- milestone goal, the exit-criteria met that prove it, and the plan beyond the close.
40
+ 6. **Close** — when the goal is genuinely met, run the **ship review** before you close:
41
+ - **Fill the ship review first** write the milestone's `## Close — ship review` section (the
42
+ scaffold ships in `MILESTONE.md`): **Ship by domain** what changed per bounded context
43
+ (`tooling` · `skill` · `book`, or "untouched"); **Cross-task evidence** one row per task
44
+ (`gate` · `tests` · `residue`); and the **Goal met?** map — each exit criterion tied to the
45
+ evidence that satisfies it. This is the whole-milestone, cross-task evidence the human READS;
46
+ it is evidence, **not a new gate**.
47
+ - **Check the boxes** — read that evidence, then check the exit-criteria boxes in `MILESTONE.md`
48
+ (the single affirmation — the same gate as ever), and `add.py milestone-done <slug>` succeeds
49
+ (then consolidate the open deltas and archive — the `milestone-done → fold → compact → archive`
50
+ lifecycle, per `fold.md` · `compact-foundation.md`).
51
+ - **Define the release steps** — write the milestone's `## Release steps` (merge is one small step
52
+ among them; PR, asset export, tag/publish are others — tool-agnostic hints the human runs).
53
+ These **feed** the release scope — read `release.md` for the cut; loop.md never re-specifies it.
54
+ Present the close via `report-template.md` — open with the ARC (goal · done · plan): the milestone
55
+ goal, the exit-criteria met (with the ship-review evidence) that prove it, and the plan beyond the
56
+ close. Render the close as a guided choice — the recommended next move + its described alternatives
57
+ (per `report-template.md`).
44
58
 
45
59
  ## Reopen is the verb; this loop is the trigger
46
60
 
@@ -118,7 +118,7 @@ high-risk task still refuses `auto` and forces a lowered rung (run.md guard).
118
118
 
119
119
  ## 4 · The one human gate — the baseline approval
120
120
 
121
- Open the report with the ARC (goal · done · plan) per `report-template.md`, then present
121
+ Open the report with the ARC (goal · done · plan) per `report-template.md`, render the baseline-lock DECISION as a guided choice (the recommended pick + described alternatives), then present
122
122
  `SETUP-REVIEW.md` lowest-confidence-first (the `guessed` rows are what the human must actually check). They
123
123
  confirm **once** — an explicit yes to the baseline approval itself, in conversation; ambient agreement mid-stream is
124
124
  not a confirmation. On that recorded confirmation, you run the lock with their name:
@@ -28,6 +28,7 @@ Objective: one scenario per Must and per Reject rule, each result specific and o
28
28
  Steps:
29
29
  1. Write one scenario per Must rule and one per Reject rule.
30
30
  2. For every rejection add an And-clause asserting what must NOT change.
31
+ 3. Sweep for the edge cases the spec omits — boundary, duplicate, partial failure, concurrency, malformed input — add one per case that applies, or rule it out on purpose.
31
32
  Never: settle for a vague result ("then it works") — results must be specific and observable.
32
33
  </prompt>
33
34
 
@@ -36,6 +37,7 @@ Never: settle for a vague result ("then it works") — results must be specific
36
37
  <exit_gate>
37
38
  - [ ] One scenario per Must rule.
38
39
  - [ ] One scenario per Reject rule.
40
+ - [ ] Edge cases the spec omits are covered (boundary · duplicate · partial failure · …) or ruled out on purpose.
39
41
  - [ ] Each result is a specific, observable fact.
40
42
  - [ ] Every rejection asserts what stays unchanged.
41
43
  </exit_gate>
@@ -20,7 +20,7 @@ work can start before the real code exists.
20
20
  **The freeze is the one approval.** This decision point is where the single human approval lands, over the
21
21
  whole bundle (§1–§4). Before asking for it, present the bundle **lowest-confidence first**: the 1–2 points
22
22
  most likely wrong (`⚠ [spec|scenario|contract|test] … — because …; if wrong: …`) — aim the human's
23
- eye before they freeze. Open that report with the ARC (goal · done · plan) per `report-template.md` so the
23
+ eye before they freeze. Open that report with the ARC (goal · done · plan) per `report-template.md`, rendering the freeze DECISION as a guided choice (the recommended pick + described alternatives), so the
24
24
  human sees the goal this freeze serves and the plan beyond it, not just the bundle. See `run.md`.
25
25
  The approval also freezes the §5 Scope (may touch) + Strategy declarations — the bundle covers them.
26
26
 
@@ -66,7 +66,7 @@ redo, and only after the loop's cap does it HARD-STOP to the human (the loop liv
66
66
  ## Record exactly one outcome (no silent pass)
67
67
 
68
68
  When you present this gate to the human, open with the ARC (goal · done · plan) per
69
- `report-template.md`, and reconcile its FLAGS with `add.py report --decide`'s open-item count
69
+ `report-template.md`, render the gate DECISION as a guided choice (the recommended pick + described alternatives), and reconcile its FLAGS with `add.py report --decide`'s open-item count
70
70
  before the ask — per that file's reconcile rule (verify is where a flag-vs-digest mismatch bites).
71
71
 
72
72
  | Outcome | When |
@@ -47,7 +47,8 @@ One arc, seven steps: **cue → gather → draft notes → readiness floor → h
47
47
  never auto-passed, never shipped silent.
48
48
  4. **Human confirms the cut** — present via `report-template.md`, opening with the ARC (goal · done · plan):
49
49
  the version you are shipping, the milestones + evidence that earn it, and the rollout + watch plan that
50
- follows. Show the drafted notes, the version, and the waivers being shipped. The human approves once
50
+ follows. Render the cut as a guided choice the recommended version + its described alternatives
51
+ (per `report-template.md`). Show the drafted notes, the version, and the waivers being shipped. The human approves once
51
52
  (the decision point) — never pre-stamped; you surface a summary to decide on, not the artifact itself.
52
53
  5. **Cut — record the marker** — only now run `add.py release <version> --notes <file>`. The engine
53
54
  **records**: it prepends the CHANGELOG entry, stamps one append-only row (newest-first) in
@@ -61,9 +61,12 @@ NEXT the single next action + what it unlocks
61
61
  1. **SUMMARY** — one line carrying intent + target + position, e.g.
62
62
  "v13 task 2/3 — tests-declared-fallback is green, gate PASS." The reader
63
63
  knows where they are before they read anything else.
64
- 2. **DECISION** — the question the human must answer, stated plainly; exactly
65
- one decision per report, or an explicit "none FYI". If a decision exists,
66
- ask it AFTER everything below has been shown (show-before-ask).
64
+ 2. **DECISION** — the question the human must answer, presented as a **guided
65
+ decision**: lead with the one **recommended pick** marked `▶ (recommended)`,
66
+ then its **1–3** described alternatives, every option carrying a one-line
67
+ description (see "guided choice" below). Exactly one decision per report, or an
68
+ explicit "none — FYI". If a decision exists, ask it after everything below has
69
+ been shown (show-before-ask).
67
70
  3. **⚠ FLAGS** — lowest-confidence first, each with *why* confidence is lowest and the
68
71
  *cost if wrong*. Where TASK.md markers exist (`⚠` / `- [~]` / `- [ ]`),
69
72
  quote them verbatim and keep their document order — extraction ≠ judgment.
@@ -74,9 +77,38 @@ NEXT the single next action + what it unlocks
74
77
  line when it is right; overrule it only with a stated reason (e.g. planned
75
78
  tasks the state file cannot see yet).
76
79
 
77
- **The ask itself** — when block 2's decision becomes a literal question component
78
- (option picker, numbered menu), compose it as a summary: the detail stays in the
79
- report above, the question carries intent + what "yes" means + the flag count.
80
+ ### The DECISION block as a guided choice
81
+
82
+ When the human must choose, render block 2 as a **guided decision** never a bare next step:
83
+
84
+ ```
85
+ DECISION <the question>
86
+
87
+ ▶ <recommended option> (recommended)
88
+ <one-line description — what it means · what it unlocks or costs>
89
+ <alternative option>
90
+ <one-line description>
91
+ <alternative option>
92
+ <one-line description>
93
+ ```
94
+
95
+ - **Recommended pick** — exactly one option carries the `▶ … (recommended)` marker; never zero,
96
+ never two. Your `confidence.md` self-score informs which to recommend; the human overrides freely
97
+ (a recommendation, not a default that auto-proceeds).
98
+ - **1–3 described alternatives** — only real, takeable options (no strawmen). If there is genuinely
99
+ one path, show the single recommended step + its description — never invent filler to reach three.
100
+ - **Every option is described** — the pick and each alternative carry a one-line description (what
101
+ it means + what it unlocks or costs); ≤1 line, no bare labels.
102
+ - **Human gates only** — render the guided choice at `[human gate]` decision points; at a
103
+ `[you drive]` autonomous step there is no human to choose, so render none. Show-before-ask still
104
+ holds — the described choice is the ASK, rendered after EVIDENCE.
105
+
106
+ **The ask itself** — when block 2's decision becomes a literal question component (an
107
+ `AskUserQuestion` picker or a numbered menu), compose it as the guided choice above: the
108
+ **recommended option goes first, with a `(Recommended)` suffix**, and each option's `description`
109
+ carries its one-line description. On a tool without `AskUserQuestion`, render the same shape as a
110
+ numbered/`▶` menu in chat — the convention is tool-agnostic. The question text stays a summary —
111
+ intent + what "yes" means + the flag count — pointing at the report above.
80
112
 
81
113
  ## Hard rules
82
114
 
@@ -84,6 +116,10 @@ report above, the question carries intent + what "yes" means + the flag count.
84
116
  - **Summary-first.** Never bury the decision under a task list or a diff.
85
117
  - **Show before ask.** Render the artifact (digest · diff · report) before any
86
118
  approval question; the human decides on what they can see.
119
+ - **Guided decision.** At a `[human gate]`, present block 2 as a guided choice — one highlighted
120
+ **recommended pick** (`▶ … (recommended)`, exactly one) + its 1–3 described alternatives, every
121
+ option carrying a one-line description; never a bare next step. `confidence.md` informs the pick;
122
+ the human overrides freely. Not at `[you drive]` autonomous steps.
87
123
  - **Reconcile the count.** Before the ask, your ⚠ FLAGS must reconcile with
88
124
  `add.py report --decide`'s open-item count. If your prose calls an item
89
125
  resolved while the digest still counts it open, the engine wins — fix the data
@@ -39,6 +39,7 @@ Rank assumptions lowest-confidence first; the top 1–2 get the flag the human r
39
39
  `⚠ <assumption> — lowest confidence because <why>; if wrong: <cost>`. Present the draft via
40
40
  `report-template.md` — open with the ARC (goal · done · plan): the goal this milestone serves,
41
41
  what is already covered, and the plan its task list lays out.
42
+ Render the draft as a guided choice — the recommended scope + its described alternatives (per `report-template.md`).
42
43
 
43
44
  ## Drafting a good MILESTONE.md (section by section)
44
45