@pilotspace/add 1.7.3 → 1.9.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.
@@ -1,8 +1,6 @@
1
1
  # Phase 7 — Observe (feed the next loop)
2
2
 
3
- Goal: release deliberately, watch reality, and turn what you learn into the next
4
- spec. Release is not the finish line — it is where the most reliable information
5
- about the feature finally appears. Fill **§7** in TASK.md.
3
+ Goal: release deliberately, watch reality, and turn what you learn into the next spec. Fill **§7** in TASK.md.
6
4
 
7
5
  ## Do
8
6
 
@@ -0,0 +1,31 @@
1
+ # Fast lane — less ceremony, same floor
2
+
3
+ The fast lane is the **collapsed, opt-in task path for small work**. Same flow — ground → specify →
4
+ contract → tests → build → verify — with fewer sections and the bundle approved in one pass. It
5
+ **collapses** the ceremony; it never drops the floor. The human opts in (`--fast`); the engine never
6
+ guesses that a task is small.
7
+
8
+ ## When
9
+
10
+ Pick it for a **small, low-risk, roughly single-file change**. Stay on the full lane when the work
11
+ wants its scenarios enumerated — a milestone or release, an architecture or security change, anything
12
+ cross-cutting, or anything you are not yet sure is small. In doubt, run the full lane.
13
+
14
+ ## How
15
+
16
+ 1. `add.py new-task <slug> --fast` scaffolds the minimal `TASK.fast.md` (sections {0,1,3,4,5,6};
17
+ §2 SCENARIOS and §7 OBSERVE dropped — §1's Accept line carries the behavior a scenario would).
18
+ 2. Ground, draft §1 + §3, and **freeze the contract as one batched approval** — the single decision
19
+ point, led by the lowest-confidence flag.
20
+ 3. Write a **red** test (§4), run it failing for the right reason.
21
+ 4. Build (§5) to green, then record the **verify gate** (§6).
22
+
23
+ ## Floor kept, only collapsed
24
+
25
+ Three things never move, on either lane: a **frozen** §3 before build · a **red** test before build ·
26
+ a recorded **verify gate** at the end (a security finding is always HARD-STOP). A `--fast` task is
27
+ freeze-gated under ANY milestone — `advance` refuses `contract_not_frozen` while §3 is a draft. Speed
28
+ comes from **fewer sections + auto-gating**, not from cutting any of the three.
29
+
30
+ Not a way around the contract, the red test, or the gate; not for milestones or releases; not
31
+ engine-chosen — ceremony is human-owned.
@@ -1,21 +1,13 @@
1
1
  # Release — cut a versioned ship, never an unwatched flip
2
2
 
3
- A project does not "release" because someone bumped a number. It releases when one or more
4
- **closed milestones** are bundled into a versioned, user-facing cut whose notes are evidence-backed,
5
- whose risk is disclosed, and whose behaviour is then watched. This guide is the **5th scope level** —
6
- after setup (`phases/0-setup.md`), intake (`intake.md` / `scope.md`), the milestone loop (`loop.md`),
7
- and stage graduation (`graduate.md`). It is a different verb from each of them:
3
+ A project releases when ≥1 **closed milestones** are bundled into a versioned cut whose notes are evidence-backed, risk is disclosed, and behaviour is then watched. This is the **5th scope level** — distinct from milestone (feature-complete), graduation (rigor shift), and stage (mvp→prod).
8
4
 
9
- - a **milestone** is *feature-complete and consolidated*; a **release** is *shipped + watched*.
10
- - **graduation** changes the project's *rigor* (mvp→production); a **release** ships a *version*.
11
- The axes are orthogonal — you cut releases at every stage (prototype preview · mvp beta · prod GA).
5
+ - **milestone** = feature-complete and consolidated; **release** = shipped + watched.
6
+ - **graduation** changes *rigor*; a **release** ships a *version*. Orthogonal axes.
12
7
 
13
- So a release is its own scope level: it bundles **≥1** closed milestone, and it may bundle several.
14
- You (the AI) **gather and propose**; the **human confirms and judges**; the engine records the cut
15
- and enforces a floor — it **never tags, publishes, or deploys** (the same stance as "the engine never
16
- renders" in `design.md` and "never spawns" in `advisor.md`). The outward act is the human's.
8
+ You **gather and propose**; the **human confirms and ships**; the engine records the cut and enforces a floor — it **never tags, publishes, or deploys**.
17
9
 
18
- ## The cue (what starts this)
10
+ ## The cue
19
11
 
20
12
  When ≥1 milestone is `done` AND archived AND not yet attributed to a release, `add.py status` prints:
21
13
 
@@ -23,93 +15,47 @@ When ≥1 milestone is `done` AND archived AND not yet attributed to a release,
23
15
  → releasable: N milestone(s) closed since last release
24
16
  ```
25
17
 
26
- That line is the trigger. It is a **tally** over unreleased-but-archived milestones — never a
27
- readiness judgment. It is silent until the first such milestone exists (a project that has never
28
- released, or has released everything, sees nothing here — grandfathered, zero change).
18
+ That line is a tally over unreleased-but-archived milestones — never a readiness judgment.
29
19
 
30
20
  ## The flow
31
21
 
32
22
  One arc, seven steps: **cue → gather → draft notes → readiness floor → human confirms → cut → watch.**
33
23
 
34
- 1. **Gather the release inventory** — run `add.py release-report` (add `--json` to branch on it). It
35
- clusters the cut's evidence into labeled record-sets: the closed milestones since the last release ·
36
- their **consolidated deltas** (the "what changed" record) · open RISK-ACCEPTED waivers riding into
37
- the release · any open **security HARD-STOP** (a blocker) · the §2 scenarios to take live as monitors.
38
- It **gathers, never judges** — there is no readiness verdict to read; the records are what you reason from.
39
- 2. **Draft the release notes** write a [Keep a Changelog](https://keepachangelog.com/) entry **from the
40
- consolidated deltas + each milestone's goal** (reuse those consolidated deltas ARE the changelog source;
41
- you are not inventing the story, you are surfacing what the foundation already recorded). Group Added / Changed /
42
- Fixed; name the headline capabilities concretely. Propose the **semver bump** — breaking→MAJOR,
43
- feature→MINOR, fix-only→PATCH — and let the human confirm it (the version is a decision, not a default).
44
- 3. **Meet the readiness floor** — before the cut the engine enforces a floor (see below): the suite is
45
- green, **zero** open security HARD-STOP, and every RISK-ACCEPTED waiver shipping in this release is
46
- signed AND disclosed in the notes. A security finding is a HARD-STOP here exactly as in verify —
47
- never auto-passed, never shipped silent.
48
- 4. **Human confirms the cut** — present via `report-template.md`, opening with the ARC (goal · done · plan):
49
- the version you are shipping, the milestones + evidence that earn it, and the rollout + watch plan that
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
52
- (the decision point) — never pre-stamped; you surface a summary to decide on, not the artifact itself.
53
- 5. **Cut — record the marker** — only now run `add.py release <version> --notes <file>`. The engine
54
- **records**: it prepends the CHANGELOG entry, stamps one append-only row (newest-first) in
55
- `RELEASES.md` (date · version · milestones · waivers shipped · evidence), and attributes the bundled
56
- milestones to this version (so the cue stops firing for them).
57
- 6. **Ship — the human's outward act** — the engine has recorded the cut; the **human runs the tag /
58
- publish / deploy** (`git tag`, `npm publish`, the deploy pipeline — tool-agnostic, whatever this project
59
- ships through). The tag is the human-gated trigger, exactly the dogfooded recipe today. The engine never
60
- performs it: design-for-failure lives in the pipeline the human owns, not in the method tool.
61
- 7. **Watch — re-enter observe at the release scope level** — the §2 scenarios become live monitors for the
62
- *released* version; live-registry / deploy confirmation is post-cut **evidence**, not a unit test. A
63
- regression found in the wild re-enters at Specify as a **change request** → a narrowed **PATCH hotfix
64
- release** (this same flow, scoped to the fix). Release is not the finish line — it is where the most
65
- reliable information appears (`phases/7-observe.md`).
66
-
67
- ## The floor (what the engine enforces)
68
-
69
- `add.py release <version>` is **guarded** — it refuses (non-zero exit, state byte-unchanged) on:
24
+ 1. **Gather** — run `add.py release-report` (`--json` to branch on it). It clusters the cut's evidence: closed milestones since last release · consolidated deltas · open RISK-ACCEPTED waivers · open security HARD-STOP (blocker) · §2 scenarios to take live as monitors. Gathers, never judges.
25
+ 2. **Draft notes** — write a [Keep a Changelog](https://keepachangelog.com/) entry from the consolidated deltas + each milestone's goal. Group Added / Changed / Fixed. Propose the **semver bump** (breaking→MAJOR, feature→MINOR, fix-only→PATCH) for human confirmation.
26
+ 3. **Readiness floor** the engine enforces: suite green, zero open security HARD-STOP, every RISK-ACCEPTED waiver signed and disclosed in the notes.
27
+ 4. **Human confirms** present via `report-template.md`, opening with the ARC (goal · done · plan). Render as a guided choice (per `report-template.md`). Never pre-stamp; show-before-ask.
28
+ 5. **Cut** — only now run `add.py release <version> --notes <file>`. The engine records: CHANGELOG entry, append-only `RELEASES.md` row (newest-first: date · version · milestones · waivers · evidence), milestone attribution.
29
+ 6. **Ship** the **human** runs the tag / publish / deploy (`git tag`, `npm publish`, deploy pipeline). Engine never performs it.
30
+ 7. **Watch** §2 scenarios become live monitors. A regression re-enters at Specify as a **change request** → PATCH hotfix release.
31
+
32
+ ## The floor
33
+
34
+ `add.py release <version>` is **guarded**refuses (non-zero exit, state byte-unchanged) on:
70
35
 
71
36
  <reject_codes>
72
- - `release_security_open` — an open security HARD-STOP exists. The non-negotiable; a security finding is
73
- never shipped. Resolve it (a change request back to Specify) before the cut. `--force` does NOT override this.
74
- - `release_tests_red` — the suite is not green. Evidence, not a plausible diff, is what a release ships on.
75
- - `release_no_closed_milestone` — nothing new since the last release. The cut is a no-op; do **not** bump.
37
+ - `release_security_open` — open security HARD-STOP exists. Never shipped. `--force` does NOT override this.
38
+ - `release_tests_red` suite not green.
39
+ - `release_no_closed_milestone` — nothing new since last release.
76
40
  - `release_undisclosed_waiver` — a RISK-ACCEPTED waiver rides into the release but is absent from the notes.
77
- Disclosure is the floor: a shipped risk the user can't read about is a hidden risk. Add it to the notes.
78
41
  </reject_codes>
79
42
 
80
- `--force` preserves human authority for grandfathered / edge cases (e.g. a first release of a brownfield
81
- adopt), mirroring `stage --force` — but it never overrides `release_security_open`. Use it deliberately,
82
- not as the normal path.
43
+ `--force` preserves human authority for grandfathered / edge cases (e.g. brownfield first cut) never overrides `release_security_open`.
83
44
 
84
- ## Invariants (never break these)
45
+ ## Invariants
85
46
 
86
- - **The engine records; the human ships.** `add.py release` writes the CHANGELOG + ledger + attribution;
87
- it never tags, publishes, or deploys. The outward act stays human-owned and tool-agnostic.
47
+ - **Engine records; human ships.** `add.py release` writes CHANGELOG + ledger + attribution; never tags, publishes, or deploys.
88
48
  - **Security is a HARD-STOP at the cut**, not just at verify. No `--force`, no waiver, no exception.
89
- - **Notes draw from consolidated deltas** — release after `fold.md` has run, so the changelog surfaces
90
- consolidated learnings, not raw open lessons. The lifecycle order is one line:
91
- `milestone-done fold compact archive (repeat ≥1×) release watch`.
92
- - **The ledger is append-only (newest-first)** — like §Key Decisions, a release row is never rewritten;
93
- a superseded or yanked version is recorded with a new row, never edited away.
94
- - **A release bundles, it does not equal.** One version may attribute several milestones; never force a
95
- release per milestone.
96
-
97
- ## Depth and reuse
98
-
99
- The shape is constant; the depth follows the stage (read it from `add.py status`):
100
-
101
- - **prototype / poc** a one-line preview note + a tag; no deploy ceremony. The point is feedback, not GA.
102
- - **mvp** — full notes + tag + a guarded publish; watch the headline scenarios.
103
- - **production** — every step at full rigor: notes + tag + deploy behind a rollback-tested pipeline +
104
- live scenario monitors + error-budget watch. The hotfix path (step 7) is first-class here.
105
-
106
- ## Worked example (this method's own 1.5.0)
107
-
108
- The repo already runs this by hand. The `udd-design-loop` milestone closed (4/4) and consolidated into
109
- `foundation-version 33`; the human then drafted the `## [1.5.0]` CHANGELOG entry from those deltas,
110
- bumped the three version sources in lockstep, and the forward-pinned `test_release_1_5_0.py` asserted
111
- in-repo readiness (versions agree · changelog lineage survives · feature anchors named · engine
112
- untouched). The cut itself — the `git tag` that triggers the npm/PyPI publish — stayed human-gated, and
113
- the live-registry confirmation was gathered *after* the tag as verify evidence, never a unit test. This
114
- guide makes that ritual first-class: `release-report` gathers it, the floor enforces it, `add.py release`
115
- records it, and the human still owns the tag.
49
+ - **Notes draw from consolidated deltas** — release after `fold.md` has run. Lifecycle order: `milestone-done → fold → compact → archive → (repeat ≥1×) → release → watch`.
50
+ - **Ledger is append-only (newest-first)** a release row is never rewritten; a yanked version gets a new row.
51
+ - **A release bundles, it does not equal.** One version may attribute several milestones.
52
+
53
+ ## Depth by stage
54
+
55
+ - **prototype/poc** — one-line preview note + tag; no deploy ceremony.
56
+ - **mvp** — full notes + tag + guarded publish; watch headline scenarios.
57
+ - **production** full rigor: notes + tag + deploy behind rollback-tested pipeline + live monitors + error-budget watch. Hotfix path (step 7) is first-class.
58
+
59
+ ## Worked example
60
+
61
+ The `udd-design-loop` milestone closed (4/4), consolidated into `foundation-version 33`; the human drafted `## [1.5.0]` from those deltas, bumped version sources in lockstep, and `test_release_1_5_0.py` asserted readiness. The `git tag` stayed human-gated; live-registry confirmation gathered *after* the tag as verify evidence, never a unit test.
@@ -1,19 +1,12 @@
1
1
  # Chat reports — the decision-point template (for the AI, not for add.py)
2
2
 
3
- The engine renders artifacts (`report`, `report --decide`, `status`); this file
4
- governs the CHAT MESSAGE you wrap around them. The digest is the artifact BEHIND
5
- your presentation, never a replacement for it — and your prose is never a
6
- replacement for the digest.
3
+ The engine renders artifacts (`report`, `report --decide`, `status`); this file governs the CHAT MESSAGE you wrap around them.
7
4
 
8
- Use it every time you report at or near a decision point: an intake proposal, a
9
- bundle approval, a verify gate, a task completion, a milestone close.
5
+ Use it every time you report at or near a decision point.
10
6
 
11
7
  ## The decision arc — rendered first, above the report blocks
12
8
 
13
- Every report at a human gate opens with the **ARC** — three labelled lines that
14
- place the decision in the work's whole arc, so the human confirms with sight of
15
- where this is going, not just the step in front of them. Render it first, then a
16
- separator, then the report blocks below:
9
+ Every report at a human gate opens with the **ARC** — three labelled lines placing the decision in the work's whole arc. Render it first, then a separator, then the report blocks:
17
10
 
18
11
  ```
19
12
  ARC goal: <the milestone / project goal this decision serves>
@@ -21,38 +14,22 @@ ARC goal: <the milestone / project goal this decision serves>
21
14
  plan: <this gate → the next step → the goal>
22
15
  ```
23
16
 
24
- - **goal** — the milestone or project goal the decision serves, read from the
25
- `m-goal` line in `add.py status`; never re-typed from memory.
26
- - **done** — proven progress only: exit-criteria met/total and tasks done from
27
- the rollup, plus what this gate proves. An honest fact, never a hope.
28
- - **plan**this gate the next step the goal, mirroring the rollup's
29
- `DECIDE NEXT` line.
30
-
31
- The arc is required at every human gate: **baseline-lock · contract-freeze ·
32
- verify · intake · scope · milestone-close · graduation**. The three labels stay
33
- constant; their content adapts to the gate. The arc is presentation only — it
34
- adds no gate and changes no PASS / RISK-ACCEPTED / HARD-STOP / freeze outcome.
35
-
36
- Its facts are engine-sourced, exactly like EVIDENCE below: goal = `m-goal` ·
37
- done = exit-criteria met/total + tasks done · plan = `DECIDE NEXT`. If your arc
38
- and `add.py` output disagree, the engine wins — fix the arc, not the engine.
39
-
40
- ### Per-gate examples — one shape, gate-specific content
41
-
42
- - **verify** — `goal:` ship the decision arc · `done:` report-arc tests 6/6
43
- green, gate ready · `plan:` PASS this gate → wire the arc into every gate → goal.
44
- - **contract-freeze** — `goal:` … · `done:` bundle drafted, lowest-confidence
45
- flag surfaced · `plan:` freeze §3 → build → goal.
46
- - **milestone-close** — `goal:` … · `done:` exit-criteria 3/3 met, all tasks
47
- done · `plan:` close → archive → the next milestone.
48
- - **intake** — `goal:` the sized request · `done:` classified new-major,
49
- rationale stated · `plan:` create the milestone → first contract → goal.
17
+ - **goal** — read from `m-goal` in `add.py status`; never re-typed from memory.
18
+ - **done** proven progress only: exit-criteria met/total, tasks done, what this gate proves. An honest fact, never a hope.
19
+ - **plan** — this gate the next step the goal, mirroring the rollup's `DECIDE NEXT` line.
20
+
21
+ The arc is required at every human gate: **baseline-lock · contract-freeze · verify · intake · scope · milestone-close · graduation**. It is presentation only it adds no gate and changes no PASS / RISK-ACCEPTED / HARD-STOP / freeze decision.
22
+
23
+ Its facts are engine-sourced (goal = `m-goal` · done = exit-criteria + tasks done · plan = `DECIDE NEXT`); if your arc and `add.py` disagree, the engine wins.
24
+
25
+ ### Per-gate examples
26
+
27
+ - **verify** `goal:` ship the decision arc · `done:` report-arc tests 6/6 green · `plan:` PASS → wire the arc into every gate → goal.
28
+ - **contract-freeze** — `goal:` … · `done:` bundle drafted, lowest-confidence flag surfaced · `plan:` freeze §3 → build → goal.
50
29
 
51
30
  ## The report blocks, in order
52
31
 
53
- The blocks below are the CORE set, rendered in order at every decision-point
54
- report. Render every one (write "none" rather than dropping a block); add MORE
55
- blocks when a specific report needs them (see "Beyond the core blocks" below).
32
+ Render every block (write "none" rather than dropping one); add MORE when needed.
56
33
 
57
34
  ```
58
35
  SUMMARY one line: intent + target + where we are + what we done
@@ -63,47 +40,18 @@ EVIDENCE small table: tests · gates · parity · check — engine-sourced
63
40
  NEXT the recommended next actions, ranked (top ▶ highlighted, bolded) + what each unlocks
64
41
  ```
65
42
 
66
- 1. **SUMMARY** — one line carrying intent + target + position, e.g.
67
- "v13 task 2/3 tests-declared-fallback is green, gate PASS." The reader
68
- knows where they are before they read anything else.
69
- 2. **DECISION** — the question the human must answer, presented as a **guided
70
- decision**: lead with the one **recommended pick** marked `▶ … (recommended)`,
71
- then its **1–3** described alternatives, every option carrying a one-line
72
- description (see "guided choice" below). Exactly one decision per report, or an
73
- explicit "none — FYI". If a decision exists, ask it after everything below has
74
- been shown (show-before-ask).
75
- 3. **FLAGS** — lowest-confidence first, each with *why* confidence is lowest and the
76
- *cost if wrong*. Where TASK.md markers exist (`⚠` / `- [~]` / `- [ ]`),
77
- quote them verbatim and keep their document order — extraction ≠ judgment.
78
- 4. **DECIDED** — the counterpart to FLAGS: the high-confidence calls you settled
79
- autonomously WITHOUT a gate, highest-confidence first, each with *why* it was
80
- safe (the change-type or evidence that earned the autonomy). FLAGS surfaces the
81
- lowest-confidence calls so the human can challenge them; DECIDED surfaces the
82
- highest-confidence ones so the human can see what you closed without asking. "none" when you made no
83
- autonomous calls. NEVER list a security / residue / lowered-autonomy call here —
84
- those always escalate in DECISION (see the Hard rules), never auto-decided.
85
- 5. **EVIDENCE** — engine-sourced facts pasted from `add.py` output, never
86
- re-typed from memory. If your prose and the engine disagree, the engine
87
- wins: fix the engine or the data, not the sentence.
88
- 6. **NEXT** — the recommended next actions as a ranked list, the top one marked
89
- `▶` and each with what it unlocks. NEXT is **informational, not a second gate**:
90
- it shows the menu of what's next and never adds a decision — the one decision
91
- stays the DECISION block. Mirror the rollup's DECIDE NEXT line for the top
92
- action when it is right; overrule it only with a stated reason (e.g. planned
93
- tasks the state file cannot see yet).
94
-
95
- ### Beyond the core blocks — add more when the decision needs it
96
-
97
- The six blocks above are the CORE set. When a specific report needs more than they
98
- carry — a `RISK` ledger, a `DIFF`, a `SCOPE` map, a `COST` estimate — add an extra
99
- block in the same shape (SCREAMING-CASE label · one-line intent · engine-sourced
100
- where it can be), placed AFTER EVIDENCE and BEFORE NEXT so NEXT always closes the
101
- report. Add a block only when it carries what the core six don't; never pad to look
102
- thorough — and never drop a core block; render "none" instead.
43
+ 1. **SUMMARY** — one line: intent + target + position.
44
+ 2. **DECISION** — as a **guided decision**: one `▶ … (recommended)` + 1–3 described alternatives. Exactly one per report, or "none FYI". Ask after everything below (show-before-ask).
45
+ 3. **FLAGS** lowest-confidence first, each with *why* and *cost if wrong*. Where TASK.md markers exist (`⚠` / `- [~]` / `- [ ]`), quote verbatim and keep document order.
46
+ 4. **DECIDED** — high-confidence autonomous calls, highest-confidence first, each with *why* it was safe. "none" when none. NEVER list a security / residue / lowered-autonomy call here.
47
+ 5. **EVIDENCE** engine-sourced facts from `add.py` output, never re-typed.
48
+ 6. **NEXT** ranked next actions, top one marked `▶` with what it unlocks. Mirror the rollup's `DECIDE NEXT` for the top action; overrule it only with a stated reason. **Informational, not a second gate**.
103
49
 
104
- ### The DECISION block as a guided choice
50
+ ### Beyond the core blocks
105
51
 
106
- When the human must choose, render block 2 as a **guided decision** — never a bare next step:
52
+ When a report needs more a `RISK` ledger, a `DIFF`, a `SCOPE` map add an extra block (SCREAMING-CASE label · one-line intent · engine-sourced where possible) AFTER EVIDENCE and BEFORE NEXT. Add only when it carries what the core blocks don't; never pad; never drop a core block.
53
+
54
+ ### The DECISION block as a guided choice
107
55
 
108
56
  ```
109
57
  DECISION <the question>
@@ -112,59 +60,26 @@ DECISION <the question>
112
60
  <one-line description — what it means · what it unlocks or costs>
113
61
  <alternative option>
114
62
  <one-line description>
115
- <alternative option>
116
- <one-line description>
117
63
  ```
118
64
 
119
- - **Recommended pick** — exactly one option carries the `▶ … (recommended)` marker; never zero,
120
- never two. Your `confidence.md` self-score informs which to recommend; the human overrides freely
121
- (a recommendation, not a default that auto-proceeds).
122
- - **1–3 described alternatives** — only real, takeable options (no strawmen). If there is genuinely
123
- one path, show the single recommended step + its description — never invent filler to reach three.
124
- - **Every option is described** the pick and each alternative carry a one-line description (what
125
- it means + what it unlocks or costs); ≤1 line, no bare labels.
126
- - **Human gates only** — render the guided choice at `[human gate]` decision points; at a
127
- `[you drive]` autonomous step there is no human to choose, so render none. Show-before-ask still
128
- holds — the described choice is the ASK, rendered after EVIDENCE.
129
-
130
- **The ask itself** — when block 2's decision becomes a literal question component (an
131
- `AskUserQuestion` picker or a numbered menu), compose it as the guided choice above: the
132
- **recommended option goes first, with a `(Recommended)` suffix**, and each option's `description`
133
- carries its one-line description. On a tool without `AskUserQuestion`, render the same shape as a
134
- numbered/`▶` menu in chat — the convention is tool-agnostic. The question text stays a summary —
135
- intent + what "yes" means + the flag count — pointing at the report above.
65
+ - **Exactly one** option carries `▶ … (recommended)`. `confidence.md` self-score informs which; the human overrides freely.
66
+ - **1–3 real alternatives** only no strawmen; if there is genuinely one path, show one — never invent filler to reach three.
67
+ - **Every option is described** pick and each alternative carry a one-line description.
68
+ - **Human gates only** — render at `[human gate]` points; not at `[you drive]` steps.
69
+
70
+ **The ask itself** — when block 2 becomes an `AskUserQuestion` picker: recommended option goes first with `(Recommended)` suffix. On tools without `AskUserQuestion`, render as a numbered/`▶` menu. The question is a summary, never the artifact intent + what "yes" means + the flag count.
136
71
 
137
72
  ## Hard rules
138
73
 
139
74
  <constraints>
140
75
  - **Summary-first.** Never bury the decision under a task list or a diff.
141
- - **Show before ask.** Render the artifact (digest · diff · report) before any
142
- approval question; the human decides on what they can see.
143
- - **Guided decision.** At a `[human gate]`, present block 2 as a guided choiceone highlighted
144
- **recommended pick** (`▶ (recommended)`, exactly one) + its 1–3 described alternatives, every
145
- option carrying a one-line description; never a bare next step. `confidence.md` informs the pick;
146
- the human overrides freely. Not at `[you drive]` autonomous steps.
147
- - **Reconcile the count.** Before the ask, your FLAGS must reconcile with
148
- `add.py report --decide`'s open-item count. If your prose calls an item
149
- resolved while the digest still counts it open, the engine wins fix the data
150
- (the TASK.md markers the digest reads), not the sentence. A report whose flag
151
- count disagrees with the engine is the un-transparent gate the ARC exists to close.
152
- - **Never pre-stamp a human decision point.** Freeze / gate / lock fields stay DRAFT or
153
- blank until the answer returns: show → ask → stamp → advance. An artifact
154
- must never claim an approval that has not happened.
155
- - **One report per decision point.** After an approval, point at the frozen artifact —
156
- do not re-render the whole bundle.
157
- - **Honest scope.** "Done" means the request, not the last task: report
158
- "task 2/3", never "done" while approved scope remains.
159
- - **The question is a summary, never the artifact.** Every approval ask carries
160
- two layers: a compact SUMMARY · DECISION · FLAGS block sits in chat
161
- immediately before the ask (positional), and the question text itself is a
162
- summary of two lines at most — intent + what "yes" means + the flag count —
163
- pointing at the report above (compositional). The full bundle, diff, or
164
- artifact lives only in the chat report; a question that re-carries it buries
165
- the decision.
166
- - **NEXT is not a second gate.** NEXT lists recommended next actions (ranked, top
167
- `▶`); the single decision stays the DECISION block — NEXT never carries an approval ask.
168
- - **DECIDED never holds a gate-class call.** A security / residue / lowered-autonomy
169
- call is escalated in DECISION, never reported as already auto-decided in DECIDED.
76
+ - **Show before ask.** Render the artifact (digest · diff · report) before any approval question.
77
+ - **Guided decision.** At a `[human gate]`, block 2 is a guided choice — one `▶ … (recommended)` + 1–3 described alternatives; never a bare next step.
78
+ - **Reconcile the count.** FLAGS must reconcile with `add.py report --decide`'s open-item count before the ask. Engine wins if prose disagrees fix the data, not the sentence.
79
+ - **Never pre-stamp a human decision point.** Freeze / gate / lock fields stay DRAFT or blank until the answer returns: show → ask → stamp → advance.
80
+ - **One report per decision point.** After an approval, point at the frozen artifact — do not re-render the bundle.
81
+ - **Honest scope.** "Done" means the request, not the last task: report "task 2/3", never "done" while approved scope remains.
82
+ - **The question is a summary, never the artifact.** A compact SUMMARY · DECISION · FLAGS block sits in chat immediately before the ask; the question text itself is two lines at most — intent + what "yes" means + flag count — pointing at the report above.
83
+ - **NEXT is not a second gate.** The single decision stays in DECISION; NEXT is ranked recommendations only.
84
+ - **DECIDED never holds a gate-class call.** Security / residue / lowered-autonomy calls escalate in DECISION.
170
85
  </constraints>