@pilotspace/add 1.1.0 → 1.2.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/GETTING-STARTED.md +165 -139
  3. package/README.md +13 -7
  4. package/bin/cli.js +13 -4
  5. package/docs/01-principles.md +3 -3
  6. package/docs/02-the-flow.md +15 -11
  7. package/docs/03-step-1-specify.md +13 -13
  8. package/docs/04-step-2-scenarios.md +2 -2
  9. package/docs/05-step-3-contract.md +3 -3
  10. package/docs/06-step-4-tests.md +2 -2
  11. package/docs/07-step-5-build.md +1 -1
  12. package/docs/08-step-6-verify.md +14 -5
  13. package/docs/09-the-loop.md +12 -6
  14. package/docs/10-setup-and-stages.md +27 -13
  15. package/docs/11-governance.md +2 -2
  16. package/docs/12-roles.md +3 -3
  17. package/docs/13-adoption.md +1 -1
  18. package/docs/14-foundation.md +15 -15
  19. package/docs/15-foundations-and-lineage.md +106 -0
  20. package/docs/README.md +4 -0
  21. package/docs/appendix-a-templates.md +3 -3
  22. package/docs/appendix-b-prompts.md +40 -5
  23. package/docs/appendix-c-glossary.md +42 -12
  24. package/docs/appendix-d-worked-example.md +2 -2
  25. package/docs/appendix-e-checklists.md +2 -2
  26. package/docs/appendix-f-requirements-matrix.md +8 -8
  27. package/docs/appendix-g-references.md +106 -0
  28. package/package.json +1 -1
  29. package/skill/add/SKILL.md +39 -37
  30. package/skill/add/adopt.md +13 -11
  31. package/skill/add/deltas.md +8 -6
  32. package/skill/add/fold.md +19 -17
  33. package/skill/add/graduate.md +74 -0
  34. package/skill/add/intake.md +22 -7
  35. package/skill/add/loop.md +59 -0
  36. package/skill/add/phases/0-setup.md +29 -24
  37. package/skill/add/phases/1-specify.md +23 -13
  38. package/skill/add/phases/2-scenarios.md +14 -4
  39. package/skill/add/phases/3-contract.md +24 -11
  40. package/skill/add/phases/4-tests.md +15 -5
  41. package/skill/add/phases/5-build.md +11 -4
  42. package/skill/add/phases/6-verify.md +24 -2
  43. package/skill/add/phases/7-observe.md +13 -5
  44. package/skill/add/report-template.md +65 -7
  45. package/skill/add/run.md +45 -34
  46. package/skill/add/scope.md +10 -6
  47. package/skill/add/setup-review.md +13 -10
  48. package/skill/add/streams.md +69 -19
  49. package/tooling/add.py +476 -34
  50. package/tooling/templates/CONVENTIONS.md.tmpl +1 -1
  51. package/tooling/templates/GLOSSARY.md.tmpl +23 -0
  52. package/tooling/templates/MILESTONE.md.tmpl +1 -0
  53. package/tooling/templates/PROJECT.md.tmpl +4 -3
  54. package/tooling/templates/TASK.md.tmpl +33 -12
@@ -34,7 +34,7 @@ python3 .add/tooling/add.py status
34
34
  - **No `.add/state.json` yet** (a fresh install drops tooling + docs but does *not* init — so `status` says
35
35
  `no .add/ project found`) → enter **autonomous setup**: YOU run init yourself —
36
36
  `add.py init --name "<inferred>" --stage <picked> --await-lock` (don't tell the human to) — then read
37
- `phases/0-setup.md` and draft the foundation + first scope + first contract through to the human lock-down.
37
+ `phases/0-setup.md` and draft the foundation + first scope + first contract through to the human baseline approval.
38
38
  - **A task is active** → open `.add/tasks/<active>/TASK.md`, look at its `phase:`
39
39
  marker, and read the matching `phases/<n>-<phase>.md`. Work *only* that phase.
40
40
  - **No active task** → first SIZE the request (see Intake below), then create the
@@ -45,8 +45,9 @@ python3 .add/tooling/add.py status
45
45
  When the user brings a raw request, classify it BEFORE making a milestone or task:
46
46
  read `intake.md` and place it in exactly one bucket — `new-major` · `sub-milestone`
47
47
  · `task` · `change-request` — then propose `{ bucket, rationale, command }` and let
48
- the human confirm. This is the intake altitude (request → versioned scope); see
49
- `intake.md` for the rubric, the tie-break order, and worked examples.
48
+ the human confirm. This is the intake level (request → versioned scope); see
49
+ `intake.md` for the rubric, the tie-break order, and worked examples. A question or
50
+ unsharp intent? **Interview before you size** — explore and suggest first (`intake.md`).
50
51
 
51
52
  Once a request is classified `new-major`/`sub-milestone`, drafting the actual
52
53
  `MILESTONE.md` (goal · scope · exit criteria · breadth-first tasks) is the second
@@ -59,57 +60,55 @@ Load the phase guide **only for the phase you are in** (progressive disclosure):
59
60
 
60
61
  | Phase | Guide | Produces (TASK.md section) | Who leads |
61
62
  |-------|-------|----------------------------|-----------|
62
- | setup | `phases/0-setup.md` | `.add/` + survivors + first §1–§3 + `SETUP-REVIEW.md` | AI drafts → **human locks** (the lock-down) |
63
- | specify | `phases/1-specify.md` | §1 rules + ranked least-sure flag | AI drafts (co-specify)† |
63
+ | setup | `phases/0-setup.md` | `.add/` + living docs + first §1–§3 + `SETUP-REVIEW.md` | AI drafts → **human locks** (the baseline approval) |
64
+ | specify | `phases/1-specify.md` | §1 rules + ranked lowest-confidence flag | AI drafts (co-specify)† |
64
65
  | scenarios | `phases/2-scenarios.md` | §2 Given/When/Then | AI drafts† |
65
- | contract | `phases/3-contract.md` | §3 frozen shape | AI drafts → **human approves once** (the seam)† |
66
+ | contract | `phases/3-contract.md` | §3 frozen shape | AI drafts → **human approves once** (the decision point)† |
66
67
  | tests | `phases/4-tests.md` | §4 + red suite in `tests/` | AI drafts† |
67
68
  | build | `phases/5-build.md` | code in `src/`, tests green | **AI** |
68
69
  | verify | `phases/6-verify.md` | §6 checks + gate record | **AI auto-gates on evidence**; human on residue/security‡ |
69
70
  | observe | `phases/7-observe.md` | §7 spec delta | human + AI |
70
71
 
71
- † **One-approval front (v7).** §1–§4 are drafted by the AI as a single bundle and frozen
72
- together; the human gives **one approval, at the contract freeze** (the autonomy seam) not
73
- three separate sign-offs. The AI presents the bundle least-sure-first. See `run.md`.
74
- **Verify auto-gate (v6–v7).** Under `autonomy: auto` (the default) a run may auto-PASS once
75
- the evidence is complete (all tests green · loops dry · no residue) recorded as *auto-resolved*,
76
- an explicit PASS, not a skip. **Security always escalates** (HARD-STOP), as do concurrency /
77
- architecture residue and `conservative` autonomy. See `run.md`.
72
+ † **The specification bundle (v7).** §1–§4 are one bundle; the human gives **one approval at the
73
+ contract freeze** (the decision point), presented lowest-confidence-first. See `run.md`.
74
+ **Verify auto-gate (v6–v7).** Under `autonomy: auto` (the default) a run may auto-PASS on
75
+ complete evidence — recorded as *auto-resolved*, an explicit PASS, not a skip. **Security always
76
+ escalates** (HARD-STOP); so do concurrency / architecture residue and `conservative` autonomy.
77
+ See `run.md`.
78
78
 
79
- Whenever you present a seam to the human in chat (intake · front approval · gate ·
80
- milestone close), follow `report-template.md` — SUMMARY DECISION FLAGS
81
- EVIDENCE → NEXT, engine-sourced facts, show-before-ask, never pre-stamp a seam.
79
+ Whenever you present a decision point to the human in chat (intake · bundle approval · gate ·
80
+ milestone close), follow `report-template.md` — open with the ARC (goal · done · plan,
81
+ engine-sourced), then SUMMARY → DECISION → ⚠ FLAGS → EVIDENCE → NEXT, show-before-ask, never
82
+ pre-stamp a decision point — and the question is a summary, never the artifact.
82
83
 
83
- In **observe**, also emit **competency deltas** — learnings tagged by which of the five
84
+ In **observe**, also emit **lessons learned** — learnings tagged by which of the five
84
85
  (`DDD · SDD · UDD · TDD · ADD`) they improve — so the foundation self-improves across loops.
85
- You write them as `open`; the human folds them into `PROJECT.md`. Read `deltas.md` for the
86
- grammar and the status lifecycle. At milestone close (or on demand), run the fold ritual that
86
+ You write them as `open`; the human consolidates them into `PROJECT.md`. Read `deltas.md` for the
87
+ grammar and the status lifecycle. At milestone close (or on demand), run the retrospective consolidation that
87
88
  gathers confirmed deltas into a versioned foundation — read `fold.md`.
88
89
 
89
- ## The dynamic run (v6–v7)
90
+ ## Beyond the bundle — load on demand
90
91
 
91
- Once **§3 CONTRACT is FROZEN**, the build→verify half runs as a dynamic, auto-gated run
92
- fan-out + in-run convergence instead of a manual build (`autonomy: auto` is the default; lower
93
- to `conservative` to keep a human at the gate). Read `run.md` for the trigger, the touch-boundary,
94
- the evidence auto-gate, and the autonomy dial. The human-led front still owns *direction*, but v7
95
- compresses it to a **single approval at the contract seam**; the run never edits a frozen contract
96
- and never auto-passes a security finding.
92
+ Once **§3 CONTRACT is FROZEN**, the build→verify half is a dynamic, auto-gated run
93
+ (`autonomy: auto` default, lowered to `conservative` for a human gate) read `run.md`. To
94
+ pipeline several ready tasks behind their own frozen contracts, read `streams.md`.
97
95
 
98
- ## Parallel streams pipelining independent tasks (opt-in)
96
+ When a milestone's tasks are all done but its **goal** (the `MILESTONE.md` exit criteria) is not
97
+ yet met, `milestone-done` holds the milestone open — read `loop.md` for the dynamic loop that turns
98
+ open deltas + extras into the next tasks, proposed by you and confirmed by the human, until the goal is met.
99
99
 
100
- The default is one task at a time. When a milestone has several tasks whose `deps=` are
101
- already `PASS` and a human is ready to review, you MAY run them concurrently: read
102
- `streams.md`. It changes no `add.py` code you compute a READY-QUEUE from `status`,
103
- spawn one worker per ready task (each in a worktree, building behind its own frozen
104
- contract), and keep the human seams (front approval · escalated Verify) on one serial
105
- REVIEW-QUEUE. The honest gain is pipelining (the reviewer never waits on a build), not
106
- N× speed; the autonomy dial sets how much actually overlaps.
100
+ When `add.py status` prints **`MVP covered propose graduation`** (every milestone done AND the
101
+ stage-goal-criteria all `[x]`), the project is ready to graduate its stage read `graduate.md` for the
102
+ orchestration: gather `graduation-report` analytics co-specify interview draft ≥1 production
103
+ milestone human confirm then (and only then) `stage production`. The flip is guarded
104
+ (`stage_no_roadmap`) and is the FINAL step never a bare label change.
107
105
 
108
106
  ## Non-negotiable rules (from the method)
109
107
 
108
+ <constraints>
110
109
  1. **Direction before speed.** Never start Build until §1–§4 exist and tests are red.
111
110
  2. **Trust evidence, not inspection.** A feature is trusted because its tests pass
112
- and the blind-spots (concurrency, security, architecture) were checked — not
111
+ and the non-functional risks (concurrency, security, architecture) were checked — not
113
112
  because the code reads plausibly.
114
113
  3. **Never weaken a test or edit a frozen contract to make the build pass.** That
115
114
  inverts the method. A real change is a *change request* back to Specify.
@@ -117,6 +116,7 @@ N× speed; the autonomy dial sets how much actually overlaps.
117
116
  `PASS`, `RISK-ACCEPTED` (signed, non-security only), or `HARD-STOP`. A security
118
117
  finding is always `HARD-STOP`.
119
118
  5. **Ask, don't guess.** If a requirement is unclear, stop and ask the user.
119
+ </constraints>
120
120
 
121
121
  ## Advancing
122
122
 
@@ -136,9 +136,11 @@ The steps never change; their depth does. Read the stage from `add.py status`:
136
136
  - **prototype** — run light; code is throwaway; design/experience is the point.
137
137
  - **poc** — run contract/tests/build deeply on the single riskiest slice only.
138
138
  - **mvp** — full flow, narrow scope, light observation.
139
- - **production** — every step at full rigor + the observe loop.
139
+ - **production** — every step at full rigor + the observe loop. Reach it via the graduation
140
+ orchestration (`graduate.md`) when status shows `MVP covered → propose graduation`, never a bare
141
+ `stage production` flip — the transition is guarded behind a human-confirmed roadmap.
140
142
 
141
- ## The trust layer
143
+ ## The method rationale
142
144
 
143
145
  The full method (the *why* behind every rule) is the AIDD book in `.add/docs/`.
144
146
  When a phase decision is genuinely unclear, read the linked chapter — each phase
@@ -3,8 +3,8 @@
3
3
  When ADD is pointed at a repo that already has code, onboarding is **silent**: the code
4
4
  answers the questions a greenfield interview would ask, so you read it rather than ask.
5
5
  This is the **brownfield path** of setup (the greenfield path keeps the 4-lens interview —
6
- see `phases/0-setup.md`). You fill the survivor files from evidence, then stop at the one
7
- human gate: the **lock-down** (`add.py lock`).
6
+ see `phases/0-setup.md`). You fill the living-documentation files from evidence, then stop at the one
7
+ human gate: the **baseline approval** (`add.py lock`).
8
8
 
9
9
  ## The signal — and arming the gate
10
10
 
@@ -14,7 +14,7 @@ Enter a brownfield repo with `--await-lock`:
14
14
  python3 .add/tooling/add.py init --await-lock
15
15
  ```
16
16
 
17
- `--await-lock` does two things. It seeds an **unlocked** setup, which *arms the lock-down gate*
17
+ `--await-lock` does two things. It seeds an **unlocked** setup, which *arms the baseline-approval gate*
18
18
  — the engine then refuses a second task, crossing into build, and recording a gate until you
19
19
  `lock`. And init, being brownfield-aware, prints a line that begins:
20
20
 
@@ -29,9 +29,9 @@ code (a mechanical fact); it never reads or fills it — interpreting it is your
29
29
 
30
30
  ## The silent mapping
31
31
 
32
- Fill each survivor file in `.add/` from what the code actually shows — **ask nothing**:
32
+ Fill each living-doc file in `.add/` from what the code actually shows — **ask nothing**:
33
33
 
34
- | Survivor | Read it from |
34
+ | Living doc | Read it from |
35
35
  |----------|--------------|
36
36
  | `PROJECT.md` (foundation) | the domain nouns, entry points, the README, the first milestone the code implies |
37
37
  | `CONVENTIONS.md` | the languages, folder layout, naming, lint config, error style already in the tree |
@@ -41,19 +41,21 @@ Fill each survivor file in `.add/` from what the code actually shows — **ask n
41
41
 
42
42
  Two rules that never bend:
43
43
 
44
- 1. **Never clobber a survivor.** `init` already skips any survivor that exists; if a human
44
+ <constraints>
45
+ 1. **Never clobber a living doc.** `init` already skips any living-doc file that exists; if a human
45
46
  already wrote `PROJECT.md`, you READ it, you do not overwrite it. Add, never replace.
46
47
  2. **Tag every drafted decision `evidence-grounded` vs `guessed`.** A line you read from the
47
48
  code is *evidence-grounded* (cite the file). A line you inferred because the code was silent
48
- is *guessed*. The human's single lock-down is only honest if they can see which is which —
49
+ is *guessed*. The human's single baseline approval is only honest if they can see which is which —
49
50
  the guesses are what they actually need to check. (The tags feed `SETUP-REVIEW.md`.)
51
+ </constraints>
50
52
 
51
- ## Where it ends — the lock-down
53
+ ## Where it ends — the baseline approval
52
54
 
53
55
  Brownfield onboarding draws no per-step approvals. You map the foundation, then draft the
54
- first milestone's scope and the first task's candidate front exactly as greenfield does, and
55
- present it all at **one** human gate. The human reviews the decisions (least-sure / `guessed`
56
- first) and signs:
56
+ first milestone's scope and the first task's candidate specification bundle exactly as greenfield does, and
57
+ present it all at **one** human gate. The human reviews the decisions (lowest-confidence / `guessed`
58
+ first) and confirms in conversation; you run the lock with their name:
57
59
 
58
60
  ```bash
59
61
  python3 .add/tooling/add.py lock --by "<name>"
@@ -1,12 +1,12 @@
1
- # Competency deltas — how each loop sharpens the foundation
1
+ # Lessons learned — how each loop sharpens the foundation
2
2
 
3
- A **competency delta** is a single learning a task produces, tagged by which of ADD's five
3
+ A **lesson learned** is a single learning a task produces, tagged by which of ADD's five
4
4
  competencies it improves. You write deltas in a task's **OBSERVE** phase; later, the
5
- `foundation-update-loop` gathers the confirmed ones and folds them into a versioned `PROJECT.md`.
5
+ `foundation-update-loop` gathers the confirmed ones and consolidates them into a versioned `PROJECT.md`.
6
6
  This is how `DDD · SDD · UDD · TDD · ADD` stop being write-once and start converging.
7
7
 
8
8
  You (the AI) **emit** deltas as `open`. Only the **human** moves a delta to `folded` or `rejected`
9
- (folding into the foundation is judgment — see the verify/observe seam). You never self-fold.
9
+ (consolidating into the foundation is judgment — see the verify/observe decision point). You never self-approve a consolidation.
10
10
 
11
11
  ## The grammar (frozen)
12
12
 
@@ -50,7 +50,7 @@ That is its home. Split genuinely separate learnings into separate deltas; never
50
50
  ```
51
51
  emit (OBSERVE) human review (foundation-update-loop)
52
52
  open ───────────▶ folded (the learning is merged into PROJECT.md; version bumps)
53
- └──────────▶ rejected (considered and deliberately NOT folded — the trail is kept)
53
+ └──────────▶ rejected (considered and deliberately NOT consolidated — the trail is kept)
54
54
  ```
55
55
 
56
56
  An `open` delta is a pending signal. `folded` and `rejected` are both human decisions; a `rejected`
@@ -60,9 +60,11 @@ delta is left in place (not deleted) so "we saw this and chose not to act" stays
60
60
 
61
61
  There is no engine validator yet, so before you record a delta, self-check it:
62
62
 
63
+ <reject_codes>
63
64
  - `unknown_competency` — the tag is missing or not one of `DDD · SDD · UDD · TDD · ADD`. Fix the tag.
64
65
  - `no_evidence` — the `(evidence: …)` pointer is missing or empty. Add the proof, or drop the line.
65
66
  - `unknown_status` — the status is not `open | folded | rejected`. A fresh delta is `open`.
67
+ </reject_codes>
66
68
 
67
69
  ## Worked example
68
70
 
@@ -75,5 +77,5 @@ A task that built a tenancy feature finished its OBSERVE phase with:
75
77
  ```
76
78
 
77
79
  Three learnings, three competencies, each with a pointer. At the next foundation update the human
78
- folded the DDD and TDD deltas into `PROJECT.md` (→ `folded`) and rejected the ADD one as a one-off
80
+ consolidated the DDD and TDD deltas into `PROJECT.md` (→ `folded`) and rejected the ADD one as a one-off
79
81
  (→ `rejected`). The foundation got sharper; nothing was silently lost.
package/skill/add/fold.md CHANGED
@@ -1,29 +1,29 @@
1
- # Folding deltas — how the foundation self-improves
1
+ # Consolidating deltas — how the foundation self-improves
2
2
 
3
- This **closes the loop**. `deltas.md` lets a task EMIT learnings (`open` competency deltas in its
4
- OBSERVE phase); folding gathers the confirmed ones and writes them into a **versioned foundation**,
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
5
  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** fold.
8
- You never self-foldfolding is judgment (see the verify/observe seam).
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).
9
9
 
10
- ## When to fold
10
+ ## When to consolidate
11
11
 
12
12
  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 ritual
13
+ deltas have piled up. This is a convention, not a command — there is no `add.py fold`; the consolidation
14
14
  lives here so the engine stays judgment-free.
15
15
 
16
16
  ## The ritual
17
17
 
18
- 1. **Gather** — scan every task's OBSERVE `### Competency deltas` block for lines still `open`.
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
19
  2. **Group** — bucket them by competency (`DDD · SDD · UDD · TDD · ADD`).
20
20
  3. **Propose** — for each, draft the exact foundation edit (see routing) and show the human.
21
21
  4. **Confirm** — the human accepts or declines each delta. No write happens without this.
22
22
  5. **Write** — append the accepted edits, flip each delta's status, and bump the version.
23
23
 
24
- ## Fold routing (every competency has a home)
24
+ ## Consolidation routing (every competency has a home)
25
25
 
26
- | competency | folds into | how |
26
+ | competency | consolidates into | how |
27
27
  |------------|-----------|-----|
28
28
  | `DDD` | `PROJECT.md` §Domain (DDD) | refine/append a model bullet |
29
29
  | `SDD` | `PROJECT.md` §Spec / Living Document (SDD) | refine/append a settled-vs-open line |
@@ -31,7 +31,7 @@ lives here so the engine stays judgment-free.
31
31
  | `TDD` | `CONVENTIONS.md` | append a testing convention (no PROJECT.md section — it is the engine) |
32
32
  | `ADD` | `CONVENTIONS.md` | append a build/harness convention (likewise the engine) |
33
33
 
34
- **Every** fold — whatever the competency — ALSO appends one row to `PROJECT.md` **§Key Decisions**
34
+ **Every** consolidation — whatever the competency — ALSO appends one row to `PROJECT.md` **§Key Decisions**
35
35
  (date · decision · why · outcome): the universal, auditable trail of what the foundation learned.
36
36
 
37
37
  ## Status transitions & version
@@ -39,16 +39,18 @@ lives here so the engine stays judgment-free.
39
39
  - on **confirm**: the delta moves `open` → `folded` (and its edit is appended to the routed target).
40
40
  - on **decline**: the delta moves `open` → `rejected` and is **left in place** — never deleted —
41
41
  so "we considered this and chose not to act" stays auditable.
42
- - a fold is **append-only**: it adds bullets/rows; it never silently rewrites existing foundation text.
43
- - each fold session **bumps** the `foundation-version:` marker in `PROJECT.md` by one (monotonic int).
42
+ - a consolidation is **append-only**: it adds bullets/rows; it never silently rewrites existing foundation text.
43
+ - each consolidation session **bumps** the `foundation-version:` marker in `PROJECT.md` by one (monotonic int).
44
44
 
45
45
  ## Reject codes (the AI is first check, the human the backstop)
46
46
 
47
+ <reject_codes>
47
48
  - `no_open_deltas` — nothing is `open` anywhere. The ritual is a no-op; do **not** bump the version.
48
49
  - `unconfirmed_fold` — a write was attempted without recorded human confirmation. The AI proposes;
49
- it never self-folds. Stop and get confirmation.
50
- - `unroutable_delta` — a delta's competency is not one of the five, so it has no fold target. Fix the
51
- delta (it is malformed per `deltas.md`) before folding.
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.
53
+ </reject_codes>
52
54
 
53
55
  ## Worked example (from this repo's own history)
54
56
 
@@ -60,7 +62,7 @@ which have no PROJECT.md section:
60
62
  - [TDD · open] structural tests guard canonical artifacts but not their dogfood twins (evidence: scope-loop note + this build)
61
63
  ```
62
64
 
63
- At the next fold the human confirms both. Routing sends each to `CONVENTIONS.md` (a "sync the dogfood
65
+ At the next consolidation the human confirms both. Routing sends each to `CONVENTIONS.md` (a "sync the dogfood
64
66
  tree + assert md5 parity" convention), appends a §Key Decisions row for each, flips them to `folded`,
65
67
  and bumps `foundation-version` 1 → 2. The two competencies the foundation never tracked before now
66
68
  have a home — which is exactly why v5 routes TDD/ADD to `CONVENTIONS.md`.
@@ -0,0 +1,74 @@
1
+ # Stage graduation — propose the move to production as a roadmap, never a flip
2
+
3
+ A project does not become "production" because someone typed a new label. It graduates when
4
+ the MVP is genuinely covered AND a human-confirmed roadmap of production work exists. This guide
5
+ is the **4th scope level** — after setup (`phases/0-setup.md`), intake (`intake.md` / `scope.md`),
6
+ and the milestone loop (`loop.md`). It turns the bare `add.py stage` flip into the **final step** of
7
+ an analytics-driven, interview-led orchestration.
8
+
9
+ You (the AI) **gather and propose**; the **human confirms and judges**; the engine only counts
10
+ tallies and enforces the floor. The engine never decides that the project is "ready" — that is
11
+ judgment, and it belongs to the interview.
12
+
13
+ ## The cue (what starts this)
14
+
15
+ When every milestone is `done` AND the human's stage-goal-criteria in `PROJECT.md` are all `[x]`,
16
+ `add.py status` prints:
17
+
18
+ ```
19
+ → MVP covered → propose graduation
20
+ ```
21
+
22
+ That line is the trigger. Before both tallies complete, status is silent and nothing here applies
23
+ (a project with no stage-goal-criteria block behaves exactly as today — grandfathered, zero change).
24
+
25
+ ## The flow
26
+
27
+ 1. **Gather the analytics** — run `add.py graduation-report` (add `--json` to branch on it). It
28
+ clusters the whole MVP loop's evidence into five labeled record-sets: open deltas by competency ·
29
+ open RISK-ACCEPTED waivers by expiry · RETRO records · verify residue · observe-loop coverage gaps.
30
+ It **gathers, never judges** — there is no readiness verdict to read; the records are what you
31
+ reason from.
32
+ 2. **Co-specify interview** — synthesize *"what production means HERE"* WITH the human, using the
33
+ gathered records as the agenda (the residue to harden, the coverage gaps to monitor, the open
34
+ deltas to consolidate). This synthesis is the judgment the engine refuses to make. Interview to real confidence —
35
+ do not guess what "production-ready" means for this project.
36
+ 3. **Draft the roadmap** — for each production outcome the interview surfaces, draft a production
37
+ milestone with the EXISTING command and goal-gate criteria:
38
+ `add.py new-milestone <slug> --stage production --goal "…"`, then write its exit criteria. The
39
+ roadmap is **≥1** milestone — the hardening work itself (SLOs, rollback tests, incident runbooks)
40
+ is what these milestones *contain*; this guide proposes them, it does not do them.
41
+ 4. **Human confirms** — present the roadmap via `report-template.md`, opening with the ARC
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
44
+ milestone. No milestone is created without this; nothing advances on a draft the human has not confirmed.
45
+ 5. **Flip — the final step** — only now run `add.py stage production`. Because ≥1 production milestone
46
+ now exists, the guard passes and the transition is recorded. This is the orchestration's last act.
47
+
48
+ ## The floor (what the engine enforces)
49
+
50
+ `add.py stage production` is **guarded**: it refuses with `stage_no_roadmap` (non-zero exit, state
51
+ byte-unchanged) when zero milestones have `stage: production`. The check is a **tally** — "does a
52
+ production-roadmap record exist?" — never a readiness judgment (gather-not-judge at stage level;
53
+ it mirrors the milestone goal-gate's `milestone_goal_unmet`). `--force` overrides it, preserving human
54
+ authority for grandfathered/edge cases; use it deliberately, not as the normal path.
55
+
56
+ Scope: the guard is on the `→production` **transition** only. Flips to prototype/poc/mvp are the
57
+ existing bare flip, unchanged. `add.py init --stage production` is an explicit at-creation declaration
58
+ (the same authority as `--force`), not a transition — it is out of scope of the guard by design.
59
+
60
+ ## Invariants (never break these)
61
+
62
+ - **The flip is the final step**, never called outside this confirmed-roadmap path. A bare flip with
63
+ no roadmap is the symptom this scope level removes.
64
+ - **The engine never auto-flips.** Every step here is human-confirmed; the engine gathers, counts, and
65
+ enforces the floor — it does not advance the stage on its own.
66
+ - **The flow is continuous, not cue-reentrant.** The moment you draft the first production milestone,
67
+ `status` stops printing the cue (the "every milestone done" tally breaks). That is expected — do NOT
68
+ re-await the cue after drafting; carry the flow straight through to confirm and flip.
69
+
70
+ ## Depth and reuse
71
+
72
+ The same orchestration serves prototype→poc and poc→mvp; **mvp→production** is the rigorous proof
73
+ case (every step at full depth + the observe loop). At lower stages, run it light — the shape is the
74
+ same, the depth is less.
@@ -1,10 +1,19 @@
1
1
  # Intake — size a request into versioned scope
2
2
 
3
3
  Before a task exists, ADD turns a raw request into correctly-sized, versioned scope.
4
- This is the **intake altitude**: the per-task flow is phases 0–7; intake is the step
4
+ This is the **intake level**: the per-task flow is phases 0–7; intake is the step
5
5
  *before* a task — request → milestone or task. You (the AI) **propose**; the human
6
6
  **confirms**. Never create scope without a confirmed proposal.
7
7
 
8
+ ## Interview before you size
9
+
10
+ When the request arrives as a question, or its intent is not yet sharp enough to
11
+ place in one bucket: explore it WITH the user before classifying. Reflect the
12
+ intent you heard, name what seems in and out of scope, and offer 2–3 sized options
13
+ with your own recommendation. Only then emit `{ bucket, rationale, command }`.
14
+ `ask_human` stays the floor: when interviewing cannot sharpen the request,
15
+ reject — never guess a bucket.
16
+
8
17
  ## The four buckets
9
18
 
10
19
  Classify every request into exactly ONE bucket:
@@ -24,17 +33,23 @@ First ask "does this change already-frozen scope?" → if yes, it is a `change-r
24
33
 
25
34
  ## What you emit (the proposal)
26
35
 
36
+ Present the proposal to the human via `report-template.md` — open with the ARC (goal · done ·
37
+ plan): the goal this request serves, what is already covered, and the plan the chosen bucket sets up.
38
+
27
39
  For every request, emit ONE of:
28
40
 
29
41
  - **a classification** — `{ bucket, rationale, command }` — where `rationale` names WHY
30
42
  (the theme, the slice, the fit, or the frozen scope touched) and `command` is the exact
31
43
  `add.py …` from the table. The human confirms or overrides before you run it.
32
- - **a rejection** — `{ reject, rationale }` — and you create nothing:
33
- - `ask_human` — too ambiguous/underspecified to size. Ask the human; never guess a bucket.
34
- - `frozen_scope` — it changes frozen scope; route it as a `change-request` back to
35
- SPECIFY/CONTRACT of the affected task never spawn a parallel milestone that forks the truth.
36
- - `split_required` — it spans more than one bucket; propose the SMALLEST set of correctly-sized
37
- items, each with its own rationale; never force it into one milestone.
44
+ - **a rejection** — `{ reject, rationale }` — and you create nothing, emitting one of the closed set:
45
+
46
+ <reject_codes>
47
+ - `ask_human` too ambiguous/underspecified to size. Ask the human; never guess a bucket.
48
+ - `frozen_scope` — it changes frozen scope; route it as a `change-request` back to
49
+ SPECIFY/CONTRACT of the affected task never spawn a parallel milestone that forks the truth.
50
+ - `split_required` — it spans more than one bucket; propose the SMALLEST set of correctly-sized
51
+ items, each with its own rationale; never force it into one milestone.
52
+ </reject_codes>
38
53
 
39
54
  When confirmed, record the `rationale` in the artifact you create or affect — the new
40
55
  MILESTONE.md goal/body, the new TASK.md, or a note in the affected TASK.md — never in state.json.
@@ -0,0 +1,59 @@
1
+ # The dynamic loop — open deltas and extras become the next tasks
2
+
3
+ A milestone is not done when its tasks are done — it is done when its **GOAL** is met.
4
+ This guide is the loop that drives a milestone toward that goal: turn what each task
5
+ leaves behind (open lessons, and work discovered but out of scope) into the next tasks,
6
+ and keep going until the exit criteria are all met.
7
+
8
+ You (the AI) **gather and propose**; the **human confirms**; the existing `add.py new-task`
9
+ creates each one. The engine never decides what the next task is — that is judgment.
10
+
11
+ ## The goal-gate (what holds the loop open)
12
+
13
+ `add.py milestone-done <slug>` REFUSES to close a milestone while its exit criteria are not
14
+ all met — it stops with `milestone_goal_unmet` and the milestone stays active. The exit-criteria
15
+ checkboxes in `MILESTONE.md` ARE the human's goal-met affirmation: the engine reads the
16
+ `- [x]`/`- [ ]` tally, it never judges whether the goal is met (the same trust model as reading a
17
+ recorded `PASS`). Checking the last box is the deliberate act that releases the gate.
18
+
19
+ The gate fires only when criteria exist. A milestone with no exit-criteria checkboxes closes as
20
+ before — write criteria into `MILESTONE.md` if you want the goal-gate to hold the milestone open.
21
+
22
+ `milestone-done` is the only way a milestone reaches `done`; `archive-milestone` and `compact`
23
+ both refuse a milestone that is not done. So the one gate is enough — there is no quiet way around it.
24
+
25
+ ## The loop
26
+
27
+ When every task is done but the goal is not, `add.py status` shows
28
+ `goal not met (m/n exit criteria)` where it would otherwise prompt to archive. That is the cue:
29
+
30
+ 1. **Gather** the carried inventory:
31
+ - open lessons — `add.py deltas` (the §7 OBSERVE deltas still `open`);
32
+ - the planned-but-unscaffolded tasks — the plan-vs-state line in `add.py status`;
33
+ - any reopened task — one a deepened verify returned to the flow (see below).
34
+ 2. **Propose** the next tasks: for each carried item worth doing now, draft a one-line task
35
+ (slug + title + why) and show the human. Group the trivial ones; do not propose noise.
36
+ 3. **Confirm** — the human accepts, edits, or declines each. No task is created without this.
37
+ 4. **Create** each accepted task — `add.py new-task <slug> --title "..."` — and run it through
38
+ the normal flow (specify → … → verify).
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.
44
+
45
+ ## Reopen is the verb; this loop is the trigger
46
+
47
+ When a deepened verify (the no-skim wiring / dead-code / semantic check) finds a criterion unmet
48
+ on a task already marked done, `add.py reopen <task> --to <phase> --reason "..."` returns it to the
49
+ flow with a recorded reason and a reset gate. `reopen` is the recorded action; deciding WHEN to
50
+ fire it — because a goal criterion is unmet — is this loop's job.
51
+
52
+ ## The reactivation residual (deferred)
53
+
54
+ A reopen fired inside the loop happens while the milestone is still **active** — the goal-gate held
55
+ it open, so it never reached done, and no reactivation is needed. The one residual — reopening a
56
+ task inside a milestone that was already closed — is surfaced by `add.py check` (a done milestone
57
+ with a live task reads as incoherent). Re-activating a closed milestone is **deferred**: resolve it
58
+ by hand for now (the loop's own design keeps in-flight milestones open), until a later task makes
59
+ milestone reactivation first-class.
@@ -1,14 +1,14 @@
1
- # Phase 0 — Setup (autonomous draft → one human lock-down)
1
+ # Phase 0 — Setup (autonomous draft → one human baseline approval)
2
2
 
3
3
  Goal: point ADD at a repo and **you** draft the whole foundation — domain, first-milestone scope,
4
- and the first task's contract — then hand the human exactly one decision: the **lock-down**. Brownfield
4
+ and the first task's contract — then hand the human exactly one decision: the **baseline approval**. Brownfield
5
5
  is silent (the code answers the questions); greenfield keeps a short interview. Either way, the human's
6
- only gate is `add.py lock`. This is the setup-altitude analog of a task's one-approval contract freeze.
6
+ only gate is `add.py lock`. This is the setup-level analog of a task's one-approval contract freeze.
7
7
 
8
8
  ## 1 · Zero-touch entry — you run init yourself
9
9
 
10
10
  When there is no `.add/state.json`, do **not** tell the human to initialise — run it yourself. Infer the
11
- project name and stage from the repo, and **arm the lock-down gate** with `--await-lock`:
11
+ project name and stage from the repo, and **arm the baseline-approval gate** with `--await-lock`:
12
12
 
13
13
  ```bash
14
14
  python3 .add/tooling/add.py init --name "<inferred from repo/dir>" --stage <prototype|poc|mvp|production> --await-lock
@@ -27,16 +27,16 @@ python3 .add/tooling/add.py init --name "<inferred from repo/dir>" --stage <prot
27
27
 
28
28
  ## 2a · Brownfield — map it silently
29
29
 
30
- The code answers the questions a greenfield interview would ask, so **read it, don't ask**. Open
31
- `adopt.md` and follow it: fill each survivor file from the code, never clobber an existing one, and tag
30
+ The code answers the questions a greenfield interview would ask, so **read it instead of asking**. Open
31
+ `adopt.md` and follow it: fill each living-doc file from the code, never clobber an existing one, and tag
32
32
  every decision `evidence-grounded` (cite the file) or `guessed`. Ask the human **nothing** at this step.
33
33
 
34
- ## 2b · Greenfield — the 4-lens interview (kept): co-specify at foundation altitude
34
+ ## 2b · Greenfield — the 4-lens interview (kept): co-specify at foundation level
35
35
 
36
36
  An empty repo has no code to read, so run the short interview. This is the **co-specify at foundation
37
- altitude** move — the same diverge → converge → validate brainstorm a task's §1 uses (`phases/1-specify.md`),
37
+ level** move — the same diverge → converge → validate brainstorm a task's §1 uses (`phases/1-specify.md`),
38
38
  lifted to the foundation. Ask the one load-bearing question per lens (diverge), draft the foundation
39
- (converge), then rank what you're least sure of and show the top flag first (validate):
39
+ (converge), then rank where your confidence is lowest and show the top flag first (validate):
40
40
 
41
41
  | Lens | The one question that unblocks the section |
42
42
  |------|--------------------------------------------|
@@ -45,52 +45,57 @@ lifted to the foundation. Ask the one load-bearing question per lens (diverge),
45
45
  | Users (UDD) | The primary user and the one job they hire this for? (or "no UI — surface is X") |
46
46
  | Decisions | What's already decided that you'd regret re-litigating? (first Key Decision row) |
47
47
 
48
- Ask only the live ones; skip what the request already answers. Rank your drafts least-sure-first using the
49
- one notation every altitude shares — `⚠ <assumption> — least sure because <why>; if wrong: <cost>` — and
48
+ Ask only the live ones; skip what the request already answers. Rank your drafts lowest-confidence-first using the
49
+ one notation every scope level shares — `⚠ <assumption> — lowest confidence because <why>; if wrong: <cost>` — and
50
50
  tag thin or inferred answers `guessed`.
51
51
 
52
52
  ## 3 · Draft to the lock (both paths)
53
53
 
54
- 1. **Fill the survivors** (they outlive all code): `.add/PROJECT.md` (the foundation — Domain · Spec/active
54
+ 1. **Fill the living documentation** (it outlives all code): `.add/PROJECT.md` (the foundation — Domain · Spec/active
55
55
  milestone · UI/UX · Key Decisions, one screen), `CONVENTIONS.md`, `GLOSSARY.md`, `MODEL_REGISTRY.md`,
56
56
  `dependencies.allowlist`. Brownfield: from the code. Greenfield: from the interview, gaps flagged `guessed`.
57
57
  2. **Size the first milestone** (read `scope.md`) and draft its `MILESTONE.md` — goal · scope · exit criteria
58
58
  · breadth-first tasks.
59
- 3. **Create the first task and draft its candidate front.** `new-task` is allowed pre-lock:
59
+ 3. **Create the first task and draft its candidate specification bundle.** `new-task` is allowed pre-lock:
60
60
  ```bash
61
61
  python3 .add/tooling/add.py new-task <slug> --title "<first feature>"
62
62
  ```
63
63
  Draft §1 (specify) · §2 (scenarios) · §3 (contract). **Leave §3 `Status: DRAFT`** — the lock is its
64
64
  approval (see §5). You MAY `advance` through specify → scenarios → contract → tests pre-lock, but the
65
- engine **refuses crossing into build** until you `lock` (`setup_unlocked`). Sequence: front → lock → build.
65
+ engine **refuses crossing into build** until you `lock` (`setup_unlocked`). Sequence: bundle → lock → build.
66
66
  4. **Write `.add/SETUP-REVIEW.md`** per `setup-review.md`: every decision you drafted (foundation, scope,
67
- first contract), **least-sure-first**, each tagged `guessed` | `evidence-grounded`.
67
+ first contract), **lowest-confidence-first**, each tagged `guessed` | `evidence-grounded`.
68
68
 
69
- ## 4 · The one human gate — the lock-down
69
+ ## 4 · The one human gate — the baseline approval
70
70
 
71
- Present `SETUP-REVIEW.md` least-sure-first (the `guessed` rows are what the human must actually check). They
72
- sign **once**:
71
+ Open the report with the ARC (goal · done · plan) per `report-template.md`, then present
72
+ `SETUP-REVIEW.md` lowest-confidence-first (the `guessed` rows are what the human must actually check). They
73
+ confirm **once** — an explicit yes to the baseline approval itself, in conversation; ambient agreement mid-stream is
74
+ not a confirmation. On that recorded confirmation, you run the lock with their name:
73
75
 
74
76
  ```bash
75
77
  python3 .add/tooling/add.py lock --by "<name>"
76
78
  ```
77
79
 
78
- `lock` records the lock layers (foundation · scope · contract) in one atomic write and opens the build. It is
79
- judgment-free it does **not** parse `SETUP-REVIEW.md`; the human *reading* it is the review.
80
+ Typing the command themselves stays the **escape hatch** the decision is always the human's; you just
81
+ execute it. `lock` records the lock layers (foundation · scope · contract) in one atomic write and opens the
82
+ build. It is judgment-free — it does **not** parse `SETUP-REVIEW.md`; the human *reading* it is the review.
80
83
 
81
84
  ## 5 · After the lock
82
85
 
83
- - The lock **is** the first task's contract approval — the v7 one-approval-front and the lock-down collapse
86
+ - The lock **is** the first task's contract approval — the v7 specification-bundle approval and the baseline approval collapse
84
87
  into this single signature. Do **not** ask for a separate contract-freeze sign-off (that double-gates).
85
88
  - Stamp the first task's §3 `Status: FROZEN @ v1` (lock-authorized), then read `phases/5-build.md` — build is
86
89
  now open. Everything before this signature, you drafted.
87
90
 
88
91
  ## Exit gate
89
92
 
93
+ <exit_gate>
90
94
  - [ ] `.add/state.json` exists; setup was seeded unlocked (`--await-lock`) then locked.
91
- - [ ] Survivors filled (brownfield: from code, tagged evidence-grounded; greenfield: from the interview).
92
- - [ ] First task created; §1–§3 drafted; `.add/SETUP-REVIEW.md` written least-sure-first.
93
- - [ ] Human signed `add.py lock`; first task §3 `FROZEN @ v1`; build open.
95
+ - [ ] Living docs filled (brownfield: from code, tagged evidence-grounded; greenfield: from the interview).
96
+ - [ ] First task created; §1–§3 drafted; `.add/SETUP-REVIEW.md` written lowest-confidence-first.
97
+ - [ ] Human confirmed the baseline approval and `add.py lock --by` ran with their name; first task §3 `FROZEN @ v1`; build open.
98
+ </exit_gate>
94
99
 
95
100
  ## Next
96
101