@pilotspace/add 1.5.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.
@@ -0,0 +1,182 @@
1
+ # 16 · Releasing
2
+
3
+ [← 15 Foundations & Lineage](./15-foundations-and-lineage.md) · [Contents](./README.md) · Next: [Appendix A Templates →](./appendix-a-templates.md)
4
+
5
+ ---
6
+
7
+ The flow chapters ([03](./03-step-1-specify.md)–[08](./08-step-6-verify.md)) take one feature from
8
+ spec to verified. The loop chapter ([09](./09-the-loop.md)) keeps a milestone going until its goal
9
+ is met. The stages chapter ([10](./10-setup-and-stages.md)) graduates the project's rigor. None of
10
+ them *ship*. This chapter names the act every project eventually performs and that the method, until
11
+ now, never formalized: bundling closed milestones into a versioned, user-facing release whose notes
12
+ are evidence-backed, whose risk is disclosed, and whose behaviour is then watched.
13
+
14
+ Releasing is the **fifth scope level** — after the task, the milestone, the foundation/setup level,
15
+ and stage graduation. Like every scope level it runs the same shape: **gather → propose → the human
16
+ confirms → the engine records and enforces a floor.** And like graduation, it ends with an outward
17
+ act the human owns. The operational recipe lives in the `release.md` skill guide; this chapter is the
18
+ *why* behind it.
19
+
20
+ ## 16.1 · Why release is its own scope level
21
+
22
+ A number bump is not a release. A release is the moment one or more **closed milestones** become a
23
+ versioned cut that real users can run. Three distinctions make it its own scope level:
24
+
25
+ - **Milestone ≠ release.** A milestone is *feature-complete and consolidated* — its goal is met and
26
+ its lessons are gathered into the foundation (see [14 · The foundation](./14-foundation.md) and the
27
+ `fold.md` retrospective consolidation). A release is *shipped and watched*. The first is an internal
28
+ state; the second faces outward.
29
+ - **Graduation ≠ release.** Stage graduation moves the project's *rigor* (mvp → production); a release
30
+ ships a *version*. The two axes are orthogonal: you cut a prototype preview, an mvp beta, and a
31
+ production GA, each at its own stage. You release at every stage, not only at the end.
32
+ - **A release bundles; it does not equal.** One version may attribute several milestones — "we shipped
33
+ after a couple of milestones closed" is the normal case, not the exception. Forcing one release per
34
+ milestone is the anti-pattern; the decoupling is the whole point.
35
+
36
+ So release sits beside the other scope levels rather than inside any of them. The granularity ladder
37
+ is now complete: intake → milestone → task, with stage graduation and release as the two cross-cutting
38
+ levels that change *rigor* and ship *versions* respectively (see the **Scope level** entry in
39
+ [Appendix C](./appendix-c-glossary.md)).
40
+
41
+ ## 16.2 · The cue and the inventory — gather, never judge
42
+
43
+ The trigger is a status line. When at least one milestone is `done`, archived, and not yet attributed
44
+ to any release, `add.py status` prints:
45
+
46
+ ```
47
+ → releasable: N milestone(s) closed since last release
48
+ ```
49
+
50
+ That line is a **tally**, never a verdict. It counts archived-but-unreleased milestones; it is silent
51
+ for a project that has never released or has already shipped everything (grandfathered — zero change).
52
+ It says *there is something to consider*, not *you are ready*.
53
+
54
+ To gather the cut's evidence, run `add.py release-report`. It clusters five labeled record-sets: the
55
+ closed milestones since the last release · their **consolidated deltas** (the "what changed" record) ·
56
+ the open `RISK-ACCEPTED` waivers riding into the release · any open security `HARD-STOP` (a blocker) ·
57
+ the §2 scenarios to take live as monitors. The report **gathers; it does not judge** — there is no
58
+ readiness score to read off, because a tally that pretended to be a verdict would invite reading the
59
+ number instead of the evidence.
60
+
61
+ The reuse claim, stated plainly: **the consolidated deltas are the changelog source.** You do not write
62
+ release notes from memory. The foundation already recorded what changed when each milestone was
63
+ consolidated (`fold.md`); the release surfaces it. This is why release runs *after* consolidation, not
64
+ before. The lifecycle order is one line:
65
+ `milestone-done → fold → compact → archive → (repeat ≥1×) → release → watch`.
66
+
67
+ ## 16.3 · Drafting the notes and the version — the proposal
68
+
69
+ From those record-sets you draft a [Keep a Changelog](https://keepachangelog.com/) entry: group the
70
+ changes under Added / Changed / Fixed and name the headline capabilities concretely, in the user's
71
+ language, not the commit's. Each bundled milestone's goal anchors one or more entries.
72
+
73
+ Then propose the version. Semver is a decision the evidence informs but does not make for you: a
74
+ breaking change is a MAJOR, a new capability a MINOR, a fix-only cut a PATCH. You propose the bump; the
75
+ **human confirms it** — the version is a judgement, not a default the tool fills in.
76
+
77
+ Both the notes and the version are *shown before they are asked about*. Present the drafted entry, the
78
+ proposed version, and the waivers shipping in this cut via the report template — opening with the ARC
79
+ (goal · done · plan) — and let the human approve once. The question is a summary to decide on; the
80
+ artifact itself is rendered first, never pre-stamped.
81
+
82
+ ## 16.4 · The floor — what the engine enforces
83
+
84
+ `add.py release <version>` is **guarded**. Before it records anything it enforces a readiness floor,
85
+ refusing with a non-zero exit and leaving every file byte-unchanged on any of four conditions:
86
+
87
+ - `release_security_open` — an open security `HARD-STOP` exists. This is the non-negotiable one: a
88
+ security finding is never shipped. Resolve it first, as a change request back to Specify.
89
+ - `release_tests_red` — the suite is not green. A release ships on evidence, not on a plausible diff.
90
+ - `release_no_closed_milestone` — nothing new since the last release. The cut would be a no-op; do not
91
+ bump a version to mark time.
92
+ - `release_undisclosed_waiver` — a `RISK-ACCEPTED` waiver rides into the release but is missing from the
93
+ notes. Disclosure *is* the floor: a shipped risk the user cannot read about is a hidden risk.
94
+
95
+ The security stop is **un-forceable.** `--force` exists for grandfathered and brownfield first-cuts —
96
+ the same authority valve as `stage --force` ([10 · Setup and stages](./10-setup-and-stages.md)) — and
97
+ it can override the other three rejects, but it can never override `release_security_open`. This mirrors
98
+ the verify gate exactly ([08 · Verify](./08-step-6-verify.md)) and the governance ceiling that no
99
+ autonomy level may lift ([11 · Governance](./11-governance.md)): a security `HARD-STOP` is the one
100
+ outcome the method refuses to auto-pass, at verify and again at the cut.
101
+
102
+ ## 16.5 · The cut versus the ship — the engine records, the human ships
103
+
104
+ Only after the human confirms do you run the cut. And here is the line that keeps releasing honest:
105
+ **the engine records; the human ships.**
106
+
107
+ `add.py release <version>` **records** the marker. It prepends the entry to `CHANGELOG.md`, stamps one
108
+ append-only row (newest-first, like the §Key Decisions log) into `RELEASES.md` — date · version ·
109
+ milestones · waivers shipped · evidence — and attributes the bundled milestones to this version, so the
110
+ cue stops firing for them. The ledger is the attribution source: a milestone is "released" because a
111
+ `RELEASES.md` row says so, never because a file was edited to claim it.
112
+
113
+ What the engine does **not** do is act outward. It **never tags, publishes, or deploys.** The outward
114
+ act — `git tag`, `npm publish`, the deploy pipeline — is the human's, tool-agnostic, exactly as the
115
+ method tool "never renders" in design and "never spawns" a subagent. Design-for-failure — timeouts,
116
+ retries, rollback, a tested revert path — belongs in the pipeline the human owns, not in a method tool
117
+ that has no business holding deploy credentials. The tag is the human-gated trigger; the record is the
118
+ engine's receipt that the floor was met.
119
+
120
+ > **A caveat worth one paragraph.** `add.py release` writes `CHANGELOG.md` at the **project root**. That
121
+ > is the right default for most repositories. But a repo with a different changelog convention — for
122
+ > instance a **nested-package** layout whose root `CHANGELOG.md` is a deliberate pointer to a package's
123
+ > own changelog — will get release blocks *prepended above* its existing content rather than replacing
124
+ > it (the writer preserves what is there; it does not clobber). Reconcile per repo: either let the root
125
+ > file carry the canonical log, or point the human's publish step at the package changelog the team
126
+ > treats as the source of truth.
127
+
128
+ ## 16.6 · Watch and the hotfix path — re-entering observe
129
+
130
+ A release is not the finish line; it is where the most reliable information finally appears. The §2
131
+ scenarios that were pass/fail cases at build time become **live monitors** for the released version, and
132
+ error-budget burn feeds the next loop. Live-registry and deploy confirmation are post-cut *evidence*,
133
+ gathered after the tag — not unit tests pretending to be one.
134
+
135
+ The unhappy path is first-class. A regression found in the wild re-enters at Specify as a **change
136
+ request**, which narrows to a **hotfix release** — the same seven-step flow, scoped to the fix, cut as a
137
+ PATCH. Releasing does not have a separate emergency mode; it has the ordinary flow at a tighter scope.
138
+
139
+ Depth follows the stage, as everywhere in the method:
140
+
141
+ - **prototype / poc** — a one-line preview note and a tag; no deploy ceremony. The point is feedback.
142
+ - **mvp** — full notes, a tag, a guarded publish; watch the headline scenarios.
143
+ - **production** — every step at full rigor: notes, tag, a deploy behind a rollback-tested pipeline,
144
+ live scenario monitors, and error-budget watch. The hotfix path is a routine capability here, not a
145
+ fire drill.
146
+
147
+ ## 16.7 · The flow, in one arc
148
+
149
+ One arc, seven steps:
150
+
151
+ **cue → gather → draft notes → readiness floor → human confirms → cut → watch**
152
+
153
+ 1. **cue** — `add.py status` prints `→ releasable: N` when an archived milestone is unreleased.
154
+ 2. **gather** — `add.py release-report` clusters the five record-sets (gather, never judge).
155
+ 3. **draft notes** — a Keep-a-Changelog entry drawn from the consolidated deltas; propose the version.
156
+ 4. **readiness floor** — the four guarded rejects; the security stop is un-forceable.
157
+ 5. **human confirms** — the notes, version, and waivers are shown, then approved once.
158
+ 6. **cut** — `add.py release <version>` records the CHANGELOG block + the `RELEASES.md` row + attribution.
159
+ 7. **watch** — the scenarios become monitors; a wild regression becomes a PATCH hotfix release.
160
+
161
+ The recipe for each step — flags, the report's `--json` shape, the exact ledger row — lives in the
162
+ `release.md` skill guide. This chapter is the reasoning; the guide is the procedure.
163
+
164
+ ## 16.8 · Worked example — this method's own 1.5.0
165
+
166
+ The repository already runs this by hand, which is the best evidence the flow is real. The
167
+ `udd-design-loop` milestone closed (4/4) and consolidated into `foundation-version 33`. From those
168
+ deltas the human drafted the `## [1.5.0]` changelog entry, bumped the three version sources in
169
+ lockstep, and a forward-pinned `test_release_1_5_0.py` asserted in-repo readiness: the versions agree,
170
+ the changelog lineage survives, the feature anchors are named, and the engine is untouched by the
171
+ release. The cut itself — the `git tag` that triggers the npm and PyPI publish — stayed human-gated,
172
+ and the live-registry confirmation was gathered *after* the tag as verify evidence, never as a unit
173
+ test.
174
+
175
+ That ritual is what this chapter formalizes. `release-report` gathers the inventory, the floor enforces
176
+ the security stop and the disclosures, `add.py release` records the cut, and the human still owns the
177
+ tag. The method releases itself the way it asks every project to release: gather the evidence, disclose
178
+ the risk, record the marker, and let a person make the outward call.
179
+
180
+ ---
181
+
182
+ [← 15 Foundations & Lineage](./15-foundations-and-lineage.md) · [Contents](./README.md) · Next: [Appendix A Templates →](./appendix-a-templates.md)
package/docs/README.md CHANGED
@@ -54,6 +54,9 @@ For every feature, before AI writes any code, you write four short artifacts in
54
54
  **Lineage**
55
55
  - [15 · Foundations & Lineage](./15-foundations-and-lineage.md)
56
56
 
57
+ **Releasing**
58
+ - [16 · Releasing](./16-releasing.md)
59
+
57
60
  **Part IV — Reference**
58
61
  - [Appendix A · Templates](./appendix-a-templates.md)
59
62
  - [Appendix B · Prompt library](./appendix-b-prompts.md)
@@ -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`.
@@ -72,10 +76,24 @@
72
76
 
73
77
  **Baseline approval** (formerly "the lock-down") — the single human gate ending autonomous setup: an explicit yes that freezes the foundation, first scope, and first contract together; runs as `add.py lock --by <name>`.
74
78
 
75
- **Scope level** (formerly "altitude") — the granularity a decision lives at: intake level (request → versioned scope) · milestone level · setup/foundation level · task level. (A cross-stage decision lives one level out, at the **stage-graduation** loop — which `graduate.md` also numbers as a scope level; see **Stage graduation**.) One ⚠-assumption notation is shared across every scope level.
79
+ **Scope level** (formerly "altitude") — the granularity a decision lives at: intake level (request → versioned scope) · milestone level · setup/foundation level · task level · release level (≥1 closed milestone → a versioned, watched cut; see **Release scope level**). (A cross-stage decision lives one level out, at the **stage-graduation** loop — which `graduate.md` also numbers as a scope level; see **Stage graduation**.) One ⚠-assumption notation is shared across every scope level.
76
80
 
77
81
  **Autonomy level** (formerly "autonomy dial") — the explicit per-task setting (`autonomy: manual | conservative | auto`, an ordered ladder manual < conservative < auto) choosing who resolves Verify: `auto` auto-PASSes on complete evidence, `conservative` keeps a human at the gate, `manual` is the strict floor (the human owns the gate; nothing auto-resolves). A high-risk scope refuses an unguarded `auto` — it must be lowered to `manual` or `conservative`. New tasks seed a visible, overridable `autonomy: auto`; a live task with no level warns (`implicit_autonomy`), a token outside the set is rejected (`unknown_autonomy_level`).
78
82
 
83
+ **Release** — a versioned, user-facing cut that bundles one or more closed milestones into something real users can run; its notes are evidence-backed, its risk is disclosed, and its behaviour is then watched. Recorded with `add.py release <version>`, which writes the changelog block and the ledger row but never tags, publishes, or deploys — the outward act stays human-owned. See [16 · Releasing](./16-releasing.md).
84
+
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).
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
+
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.
92
+
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.
94
+
95
+ **Hotfix release** — a narrowed PATCH cut that re-enters at Specify as a change request when a regression is found in a released version. It runs the same seven-step release flow scoped to the fix; releasing has no separate emergency mode, only the ordinary flow at a tighter scope.
96
+
79
97
  **Auto-ready goal** — a milestone goal whose every exit criterion **cites a verifier** (`(verify: <test|command|metric>)`), so the engine can self-verify the result against the goal without human judgment. It is the prerequisite by which **autonomy is earned by goal-clarity**: the **autonomy level** governs *who* resolves Verify, but a clarified, machine-checkable goal is what makes a self-verifying run meaningful. `add.py check` raises a `goal_not_auto_ready` **WARN** (never red) for the active milestone until it has an auto-ready goal (≥1 exit criterion and every one cited), and `status` surfaces it (`goal-ready: auto-ready ✓` / cited-of-total); a zero-criteria goal reads not-auto-ready and is milestone-shaping's nudge, not this warning's. The lint forces a citation *slot* per criterion — it raises the floor but **cannot prove the citation is real** (a human can write `(verify: it works)`): citation-theater is the accepted irreducible floor, and the freeze gate and autonomy behavior are unchanged by it.
80
98
 
81
99
  **Automated quality gate** (formerly "evidence auto-gate") — the Verify resolver under `autonomy: auto`: a run may auto-PASS on complete evidence, recorded as *auto-resolved*; a security finding always escalates (`HARD-STOP`).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pilotspace/add",
3
- "version": "1.5.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
@@ -121,6 +147,13 @@ orchestration: gather `graduation-report` analytics → co-specify interview →
121
147
  milestone → human confirm → then (and only then) `stage production`. The flip is guarded
122
148
  (`stage_no_roadmap`) and is the FINAL step — never a bare label change.
123
149
 
150
+ When one or more milestones have closed since the last release, `add.py status` prints
151
+ **`→ releasable: N milestone(s) closed since last release`** — read `release.md` for the 5th scope
152
+ level: gather `release-report` → draft notes from the consolidated deltas → meet the readiness floor
153
+ (security HARD-STOP is un-forceable) → human confirms → `add.py release <version>` records the cut
154
+ (CHANGELOG + `RELEASES.md` ledger + milestone attribution) → watch. The engine records; the human runs
155
+ the tag / publish / deploy. A release bundles ≥1 milestone and is orthogonal to stage.
156
+
124
157
  ## Non-negotiable rules (from the method)
125
158
 
126
159
  <constraints>
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 |