@pilotspace/add 1.17.0 → 2.0.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 (114) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/GETTING-STARTED.md +20 -64
  3. package/README.md +128 -56
  4. package/agents/add.md +68 -0
  5. package/bin/cli.js +86 -21
  6. package/package.json +2 -3
  7. package/personas-teacher/VENDOR.md +6 -0
  8. package/skill/add/SKILL.md +100 -134
  9. package/skill/add/adopt.md +28 -0
  10. package/skill/add/beyond.md +36 -0
  11. package/skill/add/deltas.md +25 -2
  12. package/skill/add/design.md +56 -74
  13. package/skill/add/{report-template.md → gate-udd.md} +28 -38
  14. package/skill/add/intake.md +56 -25
  15. package/skill/add/loop.md +32 -19
  16. package/skill/add/phases/build.md +78 -0
  17. package/skill/add/phases/direction.md +280 -0
  18. package/skill/add/phases/verify.md +160 -0
  19. package/skill/add/run.md +11 -18
  20. package/skill/add/terms.md +18 -0
  21. package/tooling/add.py +2383 -3261
  22. package/tooling/add_engine/autonomy.py +2 -37
  23. package/tooling/add_engine/components.py +4 -87
  24. package/tooling/add_engine/constants.py +145 -91
  25. package/tooling/add_engine/guidelines.py +9 -11
  26. package/tooling/add_engine/io_state.py +69 -2
  27. package/tooling/add_engine/predicates.py +90 -2
  28. package/tooling/add_engine/search.py +6 -6
  29. package/tooling/add_engine/taskdoc.py +15 -10
  30. package/tooling/templates/CONVENTIONS.md.tmpl +1 -1
  31. package/tooling/templates/GLOSSARY.md.tmpl +10 -4
  32. package/tooling/templates/MILESTONE.md.tmpl +20 -16
  33. package/tooling/templates/PLAN.md.tmpl +128 -0
  34. package/tooling/templates/PROJECT.md.tmpl +6 -1
  35. package/tooling/templates/PROMPT.persona.md.tmpl +17 -21
  36. package/tooling/templates/personas/_template.md.tmpl +33 -29
  37. package/tooling/templates/personas/build-engineer.md.tmpl +45 -0
  38. package/tooling/templates/personas/data-steward.md.tmpl +45 -0
  39. package/tooling/templates/personas/evidence-verifier.md.tmpl +45 -0
  40. package/tooling/templates/personas/platform-engineer.md.tmpl +45 -0
  41. package/tooling/templates/personas/product-lead.md.tmpl +51 -0
  42. package/tooling/templates/personas/quality-auditor.md.tmpl +47 -0
  43. package/tooling/templates/personas/release-manager.md.tmpl +52 -0
  44. package/tooling/templates/personas/security-gatekeeper.md.tmpl +45 -0
  45. package/tooling/templates/personas/software-architect.md.tmpl +45 -0
  46. package/tooling/templates/personas/stream-orchestrator.md.tmpl +44 -0
  47. package/tooling/templates/personas/technical-writer.md.tmpl +49 -0
  48. package/tooling/templates/personas/ux-experience-lead.md.tmpl +48 -0
  49. package/tooling/templates/specs/SPEC.md.tmpl +18 -0
  50. package/tooling/templates/udd-wireframe.md +1 -1
  51. package/agents/add-advisor.md +0 -31
  52. package/agents/add-build.md +0 -29
  53. package/agents/add-design.md +0 -32
  54. package/agents/add-persona.md +0 -33
  55. package/agents/add-verify.md +0 -36
  56. package/docs/00-introduction.md +0 -46
  57. package/docs/01-principles.md +0 -71
  58. package/docs/02-the-flow.md +0 -113
  59. package/docs/03-step-1-specify.md +0 -123
  60. package/docs/04-step-2-scenarios.md +0 -90
  61. package/docs/05-step-3-contract.md +0 -80
  62. package/docs/06-step-4-tests.md +0 -85
  63. package/docs/07-step-5-build.md +0 -82
  64. package/docs/08-step-6-verify.md +0 -105
  65. package/docs/09-the-loop.md +0 -75
  66. package/docs/10-setup-and-stages.md +0 -118
  67. package/docs/11-governance.md +0 -91
  68. package/docs/12-roles.md +0 -99
  69. package/docs/13-adoption.md +0 -67
  70. package/docs/14-foundation.md +0 -142
  71. package/docs/15-foundations-and-lineage.md +0 -106
  72. package/docs/16-releasing.md +0 -182
  73. package/docs/17-components.md +0 -143
  74. package/docs/18-personas.md +0 -80
  75. package/docs/README.md +0 -77
  76. package/docs/add-competencies.png +0 -0
  77. package/docs/add-flow.png +0 -0
  78. package/docs/add-foundation.png +0 -0
  79. package/docs/add-hierarchy.png +0 -0
  80. package/docs/add-milestone-task-lifecycle.png +0 -0
  81. package/docs/add-task-growth-wheel.png +0 -0
  82. package/docs/appendix-a-templates.md +0 -88
  83. package/docs/appendix-b-prompts.md +0 -154
  84. package/docs/appendix-c-glossary.md +0 -176
  85. package/docs/appendix-d-worked-example.md +0 -231
  86. package/docs/appendix-e-checklists.md +0 -92
  87. package/docs/appendix-f-requirements-matrix.md +0 -171
  88. package/docs/appendix-g-references.md +0 -106
  89. package/skill/add/advisor.md +0 -81
  90. package/skill/add/compact-foundation.md +0 -40
  91. package/skill/add/components.md +0 -52
  92. package/skill/add/confidence.md +0 -32
  93. package/skill/add/fold.md +0 -63
  94. package/skill/add/graduate.md +0 -39
  95. package/skill/add/phases/0-ground.md +0 -64
  96. package/skill/add/phases/0-setup.md +0 -103
  97. package/skill/add/phases/1-specify.md +0 -61
  98. package/skill/add/phases/2-scenarios.md +0 -48
  99. package/skill/add/phases/3-contract.md +0 -60
  100. package/skill/add/phases/4-tests.md +0 -61
  101. package/skill/add/phases/5-build.md +0 -62
  102. package/skill/add/phases/6-verify.md +0 -69
  103. package/skill/add/phases/7-observe.md +0 -45
  104. package/skill/add/phases/fast-lane.md +0 -34
  105. package/skill/add/release.md +0 -61
  106. package/skill/add/scope.md +0 -72
  107. package/skill/add/self-improve.md +0 -20
  108. package/skill/add/sensitivity.md +0 -51
  109. package/skill/add/setup-review.md +0 -48
  110. package/skill/add/soul.md +0 -58
  111. package/skill/add/streams.md +0 -269
  112. package/tooling/add_engine/release.py +0 -86
  113. package/tooling/templates/TASK.fast.md.tmpl +0 -78
  114. package/tooling/templates/TASK.md.tmpl +0 -181
package/skill/add/soul.md DELETED
@@ -1,58 +0,0 @@
1
- # Self-improving the voice — how SOUL.md converges to the human
2
-
3
- `SOUL.md` is the AI's voice (Tone · Communication style · Trust). It ships as a **proposed starter** and is **human-owned**; this doc is how it starts converging to *this* human. It mirrors `deltas.md` (emit) + `fold.md` (confirm → rewrite), but a confirmed voice delta consolidates into **SOUL.md**, not the foundation — voice is not one of the five competencies.
4
-
5
- You **emit** voice deltas as `open`. Only the **human** confirms one; **the human's confirm is the only writer** — you never self-approve a voice rewrite.
6
-
7
- ## What a voice delta is drawn from
8
-
9
- A voice delta is grounded in how the human shows up **in session**:
10
- - their **wordings** — the words they reach for, and the words they correct you on;
11
- - their **flow** — what they skip, what they double-check, where they want summary before detail.
12
-
13
- NOT from their private **memory** files or anything outside the working session — SOUL learns only from what you observed together.
14
-
15
- ## The grammar (mirrors deltas.md)
16
-
17
- ```
18
- - [VOICE · <status>] <observation about the voice> (evidence: <in-session pointer>)
19
- ```
20
-
21
- - `<observation>` — what the voice should become ("lead with the decision, not the preamble").
22
- - `<status>` — `open` | `confirmed` | `declined`. A newly emitted delta is **`open`**.
23
- - `(evidence: …)` — **required**, non-empty: a moment in the session (a correction, a re-ask, a visible preference). No evidence → drop it.
24
-
25
- ```
26
- - [VOICE · open] the human strips hedging from my drafts — cut "I think / it seems" and state it plainly
27
- (evidence: they rewrote two replies this session to remove the qualifier)
28
- ```
29
-
30
- ## The loop — observe → confirm → rewrite
31
-
32
- 1. **Emit** (OBSERVE) — propose 0–N voice deltas as `open` from wordings + flow. Surface in the report; show-before-ask.
33
- 2. **Confirm** — the human accepts or declines each. **No SOUL.md write happens without this.**
34
- 3. **Rewrite** — on a confirmed delta, edit the routed SOUL.md section, record the delta line (`confirmed`) at the **top** of "Voice deltas" (**newest-first**, append-only — declined stays in place).
35
-
36
- ## Routing — every voice delta has a SOUL.md home
37
-
38
- | the delta is about… | rewrite this SOUL.md section |
39
- |---------------------|------------------------------|
40
- | how I *sound* (warmth, directness, hedging) | **## Tone** |
41
- | how I *structure* what I say (summary-first, show-before-ask, length) | **## Communication style** |
42
- | what keeps the human's *trust* (gates, honesty, what I never do) | **## Trust** |
43
-
44
- The rewrite is surgical: refine or append the bullet the delta names; never silently rewrite the rest of the voice. Every confirmed delta also gets its line in **## Voice deltas** (newest-first).
45
-
46
- ## Reject codes
47
-
48
- <reject_codes>
49
- - `unconfirmed_voice_rewrite` — a SOUL.md write was attempted without a recorded human confirm. The AI proposes; it never self-approves. Stop and get the confirm.
50
- - `no_open_voice_deltas` — nothing is `open`. The loop is a no-op; do not touch SOUL.md.
51
- - `unroutable_voice_delta` — the observation maps to no SOUL.md section (not tone/style/trust). Fix the delta or widen the routing before writing.
52
- </reject_codes>
53
-
54
- ## Where it plugs in
55
-
56
- - **Emit**: `phases/7-observe.md` proposes voice deltas beside competency/spec deltas.
57
- - **Target**: `SOUL.md` — "## Voice deltas" ledger holds confirmed history.
58
- - **Kin**: `deltas.md` + `fold.md` (same propose→confirm→write discipline). No `add.py` command writes the voice.
@@ -1,269 +0,0 @@
1
- # Parallel streams — pipelining independent tasks
2
-
3
- Load this when a milestone has more than one task and you want to run them concurrently.
4
- **Default:** `sequential + auto` is the project default at setup (`phases/0-setup.md` "Run
5
- mode") — one task at a time, but Verify still auto-PASSes on evidence. Parallel streaming is an
6
- **opt-in** for a milestone with genuinely independent tasks: `add.py streams set parallel
7
- --project`, then read on. A project that raised its gate to `conservative`/`manual` still treats
8
- this rubric as the same opt-in escape hatch.
9
-
10
- It changes **no `add.py` code and no phase semantics**. It is a way *you, the orchestrator*,
11
- drive several tasks at once by reading the dependency DAG `add.py status` already prints and
12
- spawning one worker per ready task.
13
-
14
- ## The honest frame — this is pipelining, not N× speed
15
-
16
- With **one human reviewer** you cannot beat `review_time × N_tasks` (decision points are serial).
17
- The win: the reviewer is **never blocked waiting on a build** — builds for B·C·D run behind *their*
18
- frozen contracts while the human reviews A. Build latency hides under human latency.
19
-
20
- ## The two queues
21
-
22
- Both from one `add.py status` — no new state:
23
-
24
- - **READY-QUEUE** — tasks where `phase ≠ done` **and** every `deps=` task shows `gate=PASS`.
25
- Unmet deps stay queued; a PASS unblocks dependents.
26
- - **REVIEW-QUEUE** — the serial part: **bundle approval** (contract freeze) + any **Verify
27
- escalation**. One human, one queue; present one at a time, never batched.
28
-
29
- ```
30
- add.py status ─► READY-QUEUE ──spawn workers──► builds run ──► REVIEW-QUEUE ──► done
31
- (deps=PASS?) (machine span) (concurrent) (decision points, serial)
32
-
33
- └──────── a task gating PASS unblocks its dependents ──────────────────────────┘
34
- ```
35
-
36
- ## The DAG strategy — let the engine schedule the waves (`add.py waves`)
37
-
38
- Do **not** eyeball the READY-QUEUE by hand once a milestone has more than a couple of tasks.
39
- `add.py waves` (read-only) groups not-done tasks into **topological waves**, names the **critical
40
- path**, and emits an advisory **tier hint**:
41
-
42
- ```
43
- $ add.py waves
44
- milestone: v13-onboarding-polish
45
- wave 1: dag-scheduler, setup-suggest-milestone, setup-domain-deepdive, soul-artifact
46
- wave 2: setup-run-mode (deps: dag-scheduler), soul-self-improve (deps: soul-artifact)
47
- critical path: dag-scheduler → setup-run-mode (2 tasks)
48
- tier hint: top → dag-scheduler, setup-run-mode; mid → the rest
49
- ```
50
-
51
- - **Wave = a fan-out batch.** Every task in a wave has all in-milestone deps PASS, so the whole
52
- wave is spawnable at once — worktree isolation is the default for any spawn, not just a wave.
53
- Finish a wave, gate tasks PASS, then `add.py waves` again — the next wave is unblocked.
54
- - **Run the widest wave first** to hide the most build latency under human review latency.
55
- - **Spend your strongest model on the critical path.** Critical-path tasks gate the most
56
- downstream work; off-path tasks take **mid**. The tier hint is advisory — override when you
57
- know a task is harder than its position suggests.
58
- - **Prefer the named roster per worker** — `add-build` for a tests/build-phase worker, `add-design`
59
- for design-phase, `add-verify` for verify-phase (full roster + when-to-spawn in advisor.md) — over
60
- a generic ad-hoc spawn.
61
- - **`--json`** (`{ milestone, waves, critical_path, critical_path_len, tiers, blocked }`) feeds
62
- a runner that spawns programmatically. `blocked` lists tasks whose dep cannot be satisfied
63
- within this milestone; a `dependency_cycle` is refused with the offending members named.
64
-
65
- The irreducible floor holds — `waves` decides *order and model*, never *whether the human gate fires*.
66
-
67
- ## The autonomy level is the throttle (not a new flag)
68
-
69
- | `autonomy` (TASK.md) | What serializes on the human | Concurrency |
70
- |----------------------|------------------------------|-------------|
71
- | `conservative` / `manual` | bundle approval **+** every Verify | pure pipelining — builds overlap, both gates queue |
72
- | `auto` (default) | bundle approval **only**; Verify auto-PASSes on evidence | real concurrency — only the decision point + residue escalations queue |
73
- | `auto` but **high-risk** | refused → must lower (`unguarded_high_risk_auto`) | back to pipelining, by design |
74
-
75
- The irreducible floor is **one human approval per task at the contract decision point** — that
76
- floor never drops to zero (`run.md:22`). Do not engineer around it.
77
-
78
- ## Who writes what — the hard boundary
79
-
80
- <constraints>
81
- - **You (orchestrator)** own all shared writes: `MILESTONE.md`, and every `add.py advance <slug>` /
82
- `add.py gate <outcome> <slug>` call. Always pass the explicit `<slug>` — **name the task every time** —
83
- omitting it falls back to the single `active_task`, which races once more than one stream is live.
84
- Workers never run these.
85
- - **A worker** owns only its own `.add/tasks/<slug>/` — it builds `src/`, drives tests green,
86
- gathers evidence, and writes `SUMMARY.md` + OBSERVE deltas. It touches **no sibling stream and
87
- no shared file** — never write shared state (state.json, MILESTONE.md, a sibling's files).
88
- - **Isolation**: `isolation="worktree"` is the default for any agent-spawned step, not only a
89
- wave — a shared-tree spawn needs a stated reason. The worktree is discarded on failure; the task
90
- resets to its last-good phase.
91
- </constraints>
92
-
93
- ## Design for failure (required)
94
-
95
- - **Fresh worktree base (verify base == HEAD)** — cut each worktree from current `HEAD` **after**
96
- committing the frozen bundle; confirm `git -C <worktree> rev-parse HEAD` equals the orchestrator's
97
- `HEAD` (drifted → `git merge` first). On a pool runner (e.g. Claude Code) the check **shifts** to
98
- the worker's **step-0** (sync + re-echo `rev-parse HEAD`), verified at **merge-time**. The engine
99
- gates this (`engine-merge-base-enforcement`): `add.py wave-verify` before the first merge-back
100
- refuses a mismatched/pending echo (`unverified_fork_base`) or off-template ledger
101
- (`wave_ledger_malformed`); `add.py check` is the standing monitor.
102
- - **Materialize gitignored engine content** — `git worktree add` checks out TRACKED files only;
103
- `.add/tooling` (engine) and `.add/docs` (book) are gitignored and will be ABSENT even when the
104
- worktree's HEAD matches. `add.py worktree-prep <slug>` mechanizes the recipe: cuts the
105
- worktree, copies both trees in, and echoes the fork base for the ledger — one step.
106
- - **Lease + timeout** — record which worker holds which task (wave ledger); a dead worker releases
107
- its claim back to READY.
108
- - **Failure isolates** — a worker's STOP-and-escalate blocks only its own task; siblings run on, the
109
- escalation joins the REVIEW-QUEUE.
110
- - **Circuit-breaker** — if N workers fail in a wave, stop fanning out and fall back to sequential.
111
- Repeated failure means the scope was wrong, not the parallelism.
112
-
113
- ## Wave ledger — the wave's resume point
114
-
115
- **The file** — `.add/milestones/<m>/WAVE.md`, orchestrator-owned. ONE live wave per milestone;
116
- opening a second while one is live is refused (`wave_already_live`). **Workers never read
117
- WAVE.md** — the orchestrator copies relevant decisions into each worker's PROMPT.md at spawn.
118
-
119
- ```markdown
120
- # WAVE.md — transient wave ledger (orchestrator-owned · one live wave per milestone)
121
- wave: <n> · opened: <date> · status: live|merging
122
- base: <orchestrator HEAD at spawn — the sha every fork must equal>
123
-
124
- ### Roster (lease ledger)
125
- | task | lease (worker) | fork-base (pasted) | autonomy | spawned | timeout |
126
- |--------|----------------|---------------------------------------------|----------|---------|---------|
127
- | <slug> | wt-a | <paste `git -C <wt> rev-parse HEAD` output> | auto | <time> | <dur> |
128
-
129
- ### Mid-wave decisions
130
- - <date> <decision a later or respawned worker must honor — copy it into that worker's PROMPT.md>
131
-
132
- ### Merge order (serial; integration Verify per merge)
133
- 1. <slug> → 2. <slug>
134
- ```
135
-
136
- **Evidence cells, not ticks.** The fork-base cell holds the PASTED output of
137
- `git -C <worktree> rev-parse HEAD` and must equal `base:`. Filling the row requires running the
138
- command — words-exist ≠ method-works. Spawning a worker whose roster row lacks that evidence is
139
- refused (`unverified_fork_base`). On a pool runner the cell holds the worker's **step-0**
140
- post-sync echo (still `== base:`) and the refusal **shifts to merge-time**.
141
-
142
- **Lifecycle — open → consume → digest → delete.** Open when the first worker spawns. At wave
143
- close, absorb the evidence digest — base · roster fork-base · merge order · integration-Verify
144
- outcome — into `MILESTONE.md` as an append-only `## Wave log` block, then remove the file.
145
- Removing WAVE.md before the digest is absorbed is refused (`digest_not_absorbed`).
146
-
147
- **Resume rule.** On session start, a live WAVE.md is the wave's resume point: re-orient from the
148
- file — roster, bases, decisions, merge order — never from conversational memory.
149
-
150
- ## Merge is serial — integration Verify
151
-
152
- Parallel build, **serial integration**. After workers return, merge worktrees one at a time and
153
- run the **integration** Verify — the concurrency / architecture / layering checks automation
154
- cannot judge. Two green tasks in isolation can still conflict when merged. Never auto-pass it.
155
-
156
- Each worktree carries a full copy of `.add/`. Merge back **only** `src/`, `tests/`, and the
157
- worker's own `.add/tasks/<slug>/` (TASK.md · SUMMARY.md) — `.add/state.json`, `MILESTONE.md`,
158
- and the live `WAVE.md` stay orchestrator-owned.
159
-
160
- ## The worker contract — portable across coding agents
161
-
162
- A worker **is** the dynamic run (`run.md`) for one task. The contract below is **agent-agnostic**:
163
- no vendor tool, no model, no spawn API — a durable ADD artifact. The adapter (next sections) is
164
- the thin, swappable mapping for one runner. Fill every `{{...}}` per stream.
165
-
166
- ```xml
167
- <!-- PROMPT.md — dropped into the worker's worktree, or passed inline. No runner-specific tokens. -->
168
- <objective>
169
- Execute the LOCKED dynamic run for task '{{TASK_SLUG}}' in milestone {{MILESTONE}}:
170
- drive §4 TESTS red→green against the FROZEN contract {{CONTRACT_VERSION}}, converge, and
171
- resolve verify per autonomy={{AUTONOMY}}. You own ONLY the machine-led span — the two human
172
- decision points (bundle approval · escalated Verify) are NOT yours.
173
- </objective>
174
-
175
- <persona>
176
- Load `.add/personas/{{PERSONA_SLUG}}.md` (Identity→you · Critical Rules→constraints · Success
177
- Metrics→done-bar); no match → the generic default below. Portable body + per-runner spawn stubs:
178
- `templates/PROMPT.persona.md.tmpl` (one canonical body; Claude Code verified, the rest illustrative).
179
- You are a {{DOMAIN}} engineer with 15 years building {{DOMAIN_DETAIL}}.
180
- A wrong-but-plausible result here is expensive; correctness over speed.
181
- Work step by step:
182
- 1. Load the context files. Confirm the start gate: §3 CONTRACT FROZEN @ {{CONTRACT_VERSION}}
183
- AND §4 TESTS RED for the right reason. If not → STOP and escalate (forward-skip forbidden).
184
- 2. Build in small batches in src/ until the red tests pass — never weaken or skip a test.
185
- 3. Converge: loop-until-dry · adversarial-verify every 'done' claim · completeness-critic.
186
- 4. Resolve verify per the boundary. Write SUMMARY.md + OBSERVE deltas (deltas.md grammar).
187
- Score confidence (0-1) on Completeness · Clarity · Practicality · Optimization · EdgeCases ·
188
- Self-Eval; if any < 0.9, refine before returning.
189
- </persona>
190
-
191
- <strategy>
192
- The task's §5 plan — the Strategy (ordered batches) order and the Known-problem fixes — is
193
- your PREFERRED starting path, not a hard rule. Improve on it when a better strategy emerges
194
- as you build; on done, report the strategy you ACTUALLY used so the orchestrator can update
195
- §5 for the audit trail.
196
- </strategy>
197
-
198
- <touch_boundary> <!-- from run.md; the worker's contract, identical on every runner -->
199
- MAY: rewrite code in src/ · drive tests green WITHOUT weakening them · gather verify evidence.
200
- MUST NOT: edit the frozen CONTRACT or locked scope · weaken/delete/skip any test ·
201
- touch §1–§3 bundle artifacts · write MILESTONE.md / state.json / any sibling stream.
202
- STOP-and-escalate (return your findings; do not decide):
203
- • a discovered scope/contract gap → backward-correction, reopen Specify (principle 4)
204
- • any SECURITY finding → HARD-STOP, always
205
- • a concurrency/timing OR architecture/layering risk the tests cannot exercise
206
- • [include this bullet when autonomy is conservative OR manual] the verify gate itself — STOP for the human
207
- Auto-PASS only if autonomy=auto AND: all tests green · coverage not decreased · no test weakened ·
208
- no contract edited · loops dry · completeness-critic clean · no residue above. Log it as
209
- auto-resolved, naming this run as owner — never forge a human signature.
210
- </touch_boundary>
211
-
212
- <context_files> <!-- paths relative to the worktree root -->
213
- .add/PROJECT.md · .add/milestones/{{MILESTONE}}/MILESTONE.md (READ-ONLY) ·
214
- .add/tasks/{{TASK_SLUG}}/TASK.md · .claude/skills/add/run.md · .claude/skills/add/deltas.md
215
- </context_files>
216
-
217
- <expertise>
218
- If your runner supports specialist injection (a Claude Code skill, a system-prompt preamble, an
219
- agent profile), load the one matching {{DOMAIN}}. Otherwise the persona above IS your expertise.
220
- </expertise>
221
-
222
- <tools>
223
- Navigate with your runner's code-intelligence: mcp__serena under Claude Code; LSP / ctags /
224
- ripgrep otherwise. Design every IO path for failure — timeouts, retries, rollback.
225
- </tools>
226
-
227
- <return> <!-- the worker PROPOSES; the orchestrator RECORDS. A worker never runs add.py. -->
228
- End with a structured verdict AND write the same into SUMMARY.md in the task dir, then
229
- **commit SUMMARY.md + deltas.md** in the worktree (uncommitted files survive only by harness
230
- courtesy — commit them so the serial-integration merge-back carries your report):
231
- { task, outcome: PASS|RISK-ACCEPTED|HARD-STOP|ESCALATE, evidence: <tests+coverage>,
232
- residue: [security|concurrency|architecture findings], deltas: [open lessons learned] }.
233
- Do NOT touch add.py or any shared file — the orchestrator gates on your verdict.
234
- </return>
235
- ```
236
-
237
- ## Choosing the model — vendor-neutral tiers
238
-
239
- ADD picks a **tier** from the scope's nature; the adapter maps the tier to the runner's model id.
240
-
241
- | Tier | When | Claude Code | Any other runner |
242
- |------|------|-------------|------------------|
243
- | **mid** | ordinary, well-tested scope; clear contract | `sonnet` | the runner's balanced model |
244
- | **top** | complex / ambiguous / cross-cutting / broad scope of impact | `opus` | the runner's strongest reasoning model |
245
-
246
- Two rules sit **above** model choice: **high-risk ⇒ a lowered rung (`conservative` or `manual`),
247
- regardless of model** — a stronger model does not buy back the human gate. And **security residue
248
- always escalates** — no tier auto-passes it.
249
-
250
- ## The spawn adapter — one thin mapping per runner
251
-
252
- ADD needs six capabilities from any runner. **Isolation ADD owns itself** (a git worktree,
253
- default for any spawn), so streams stay portable even without a native sandbox.
254
-
255
- | ADD needs | Abstract | Claude Code (verified reference) | Any CLI agent — Codex · opencode · pi-mono · … |
256
- |-----------|----------|----------------------------------|-----------------------------------------------|
257
- | spawn a worker | prompt + label | `Task(description=…, prompt=…)` | `cd $WT && <agent> run --prompt-file PROMPT.md` |
258
- | pick the model | tier → id | `model="opus"\|"sonnet"` | a `--model <id>` flag |
259
- | isolate | worktree | `isolation="worktree"` | `git worktree add $WT HEAD` (after committing the bundle; verify base == HEAD), then run inside it |
260
- | load context | files / cwd | `<context_files>` + repo cwd | run inside `$WT`; paths are relative |
261
- | domain expertise | skill / preamble | a Claude skill in `<expertise>` | a system-prompt / profile preamble |
262
- | return a verdict | structured | final message (optionally a schema) | stdout JSON the orchestrator parses |
263
-
264
- > **Honesty:** only the Claude Code column is verified. The CLI forms for Codex/opencode/pi-mono
265
- > are *illustrative shapes* — confirm exact syntax with the `find-docs` skill.
266
-
267
- When workers return, **you** record each outcome with the explicit slug — `add.py advance <slug>`
268
- as evidence lands, `add.py gate PASS|RISK-ACCEPTED|HARD-STOP <slug>` at verify — then re-read
269
- `status` to refill the READY-QUEUE. The worker proposes; the orchestrator records.
@@ -1,86 +0,0 @@
1
- """add_engine.release — the RELEASE-pillar render helpers (engine-modularization 14/N).
2
-
3
- Render the CHANGELOG block and the append-only RELEASES.md attribution row, locate the
4
- ledger, find closed milestones / key decisions for a cut, and summarise the in-flight build.
5
- A closed, unpatched cluster (transitive-closure AST = zero outbound). Deps: constants + stdlib.
6
- """
7
- from __future__ import annotations
8
-
9
- import re
10
- from pathlib import Path
11
-
12
- from add_engine.constants import RELEASES_FILE
13
-
14
-
15
- def _releases_path(root: Path) -> Path:
16
- """The append-only release ledger — at the PROJECT ROOT (root IS the .add dir, so its
17
- parent), a sibling of CHANGELOG.md. NOT inside .add/."""
18
- return root.parent / RELEASES_FILE
19
-
20
- def _closed_milestones(state: dict) -> list[dict]:
21
- """Every CLOSED milestone (its milestone-done gate passed): LIVE done milestones
22
- (status == 'done', still in state) + ARCHIVED milestones (all were PASS-done before
23
- archive — see _archived_task_slugs). Each: {slug, title, tier}."""
24
- out: list[dict] = []
25
- for slug, m in (state.get("milestones") or {}).items():
26
- if m.get("status") == "done":
27
- out.append({"slug": slug, "title": m.get("title", slug), "tier": "live"})
28
- for rec in state.get("archived") or []:
29
- if rec.get("slug"):
30
- out.append({"slug": rec["slug"], "title": rec.get("title", rec["slug"]),
31
- "tier": "archived"})
32
- return out
33
-
34
- def _key_decisions_for(root: Path, slug: str) -> list[str]:
35
- """Best-effort §Key-Decisions rows from PROJECT.md that NAME this milestone slug — the
36
- consolidated decisions the changelog can cite. Fail-open: a missing section / unreadable
37
- foundation / no slug match -> [] (a gather never raises). READ-ONLY."""
38
- try:
39
- text = (root / "PROJECT.md").read_text(encoding="utf-8")
40
- except OSError:
41
- return []
42
- m = re.search(r"^#{1,6}[^\n]*key decision[^\n]*$(.*?)(?=^#{1,6}\s|\Z)", text, re.S | re.M | re.I)
43
- if not m:
44
- return []
45
- return [st.lstrip("-* ").strip() for st in (ln.strip() for ln in m.group(1).splitlines())
46
- if st.startswith(("-", "*")) and slug in st]
47
-
48
- def _build_in_flight(state: dict) -> bool:
49
- """release_build_in_flight proxy (PURE): is any ACTIVE task mid-build without a recorded green
50
- gate — phase ∈ {build, verify} AND gate == 'none'? The tool-agnostic engine never runs the
51
- suite, so an entered-but-ungated build is the recorded-evidence stand-in for 'the suite is red'."""
52
- return any(t.get("phase") in ("build", "verify") and t.get("gate") == "none"
53
- for t in (state.get("tasks") or {}).values())
54
-
55
- def _render_changelog_block(version: str, day: str, bundle: list[dict],
56
- changed_by_slug: dict) -> str:
57
- """A CHANGELOG block: `## <version> — <date>` + one bullet per bundled milestone (title +
58
- carried-delta / key-decision counts from release_data['changed'])."""
59
- lines = [f"## {version} — {day}", ""]
60
- if bundle:
61
- for m in bundle:
62
- c = changed_by_slug.get(m["slug"], {})
63
- lines.append(f"- {m['title']} — {c.get('carried_deltas', 0)} carried · "
64
- f"{len(c.get('key_decisions', []))} key decision(s)")
65
- else:
66
- lines.append("- (no milestone bundled)")
67
- return "\n".join(lines) + "\n\n"
68
-
69
- def _render_releases_row(version: str, day: str, bundle: list[dict],
70
- waiver_slugs: list[str], evidence: str | None,
71
- actor: str | None = None, loose: list[dict] | None = None) -> str:
72
- """One append-only RELEASES.md row — the attribution source (`milestones:` membership +,
73
- additively, `loose tasks:` membership for done milestone-free standalones). The `actor:`
74
- line records WHO cut the release (structured-actor stamping); absent on a legacy row
75
- (back-compat) when no actor is supplied. `loose` defaults to None so existing callers keep
76
- working; the `loose tasks:` line always renders (`none` when empty), the other lines unchanged."""
77
- ms = ", ".join(m["slug"] for m in bundle) if bundle else "none"
78
- lt = ", ".join(t["slug"] for t in loose) if loose else "none"
79
- wv = ", ".join(waiver_slugs) if waiver_slugs else "none"
80
- actor_line = f"actor: {actor}\n" if actor else ""
81
- return (f"## {version} — {day}\n"
82
- f"milestones: {ms}\n"
83
- f"loose tasks: {lt}\n"
84
- f"waivers: {wv}\n"
85
- f"{actor_line}"
86
- f"evidence: {evidence or 'recorded by add.py release'}\n\n")
@@ -1,78 +0,0 @@
1
- # TASK: {{title}}
2
-
3
- slug: {{slug}} · created: {{date}} · stage: {{stage}}
4
- milestone: {{milestone}}
5
- autonomy: {{autonomy}} <!-- Multi-component repo? add a `component: <name>` line (declared in .add/components.toml) to bind this fast task to a component — its root joins §5 Scope and its green-bar/verify surface at the gate. Omit for single-component projects. -->
6
- phase: ground <!-- fast lane: ground -> specify -> contract -> tests -> build -> verify -> observe -> done -->
7
- fast: true <!-- the fast lane: a small task, collapsed flow + minimal template. Omit --fast for full rigor. -->
8
-
9
- > Fast lane — one small task, minimal sections, filled top-to-bottom. The trust floor still
10
- > holds: a FROZEN §3 contract · ≥1 red test before build · a recorded §6 gate (security = HARD-STOP).
11
- > The acceptance scenario collapses into §1 `Accept:`; OBSERVE is one optional line at the gate.
12
-
13
- ---
14
-
15
- ## 0 · GROUND — the real codebase
16
-
17
- Touches (files · symbols): <path:symbol — what it is / how it is keyed>
18
- Context (working folder): <docs · config · data the task touches — task-delta only>
19
- Honors (patterns / conventions): <PROJECT.md / CONVENTIONS.md anchors — task-delta>
20
- Anchors the contract cites: <the symbols §3 will name>
21
- Ground SHA: <`git rev-parse --short HEAD` at ground time — any line ref reads "as of" it>
22
-
23
- ---
24
-
25
- ## 1 · SPECIFY — the rules
26
-
27
- Feature: <name>
28
- Must:
29
- - <required behavior>
30
- Reject:
31
- - <bad input / situation> -> "<error_code>"
32
- Accept: <the one acceptance scenario, Given/When/Then condensed to one line — it drives the §4 test>
33
- Assumptions: ⚠ <the one most likely wrong> — why; if wrong: <cost> (or "none material — biggest risk: X")
34
-
35
- ---
36
-
37
- ## 3 · CONTRACT — freeze the shape
38
-
39
- ```
40
- <the shape that freezes: signature / fields · success + each rejection's response>
41
- ```
42
-
43
- `Least-sure flag surfaced at freeze:` <[spec|contract|test] the point most likely wrong — why; if wrong: cost>
44
- Status: DRAFT
45
- <!-- The freeze IS the one approval. Approved -> Status: FROZEN @ vN — approved by <name>.
46
- Changing a frozen contract = change request back to SPECIFY. -->
47
-
48
- ---
49
-
50
- ## 4 · TESTS — failing-first (red)
51
-
52
- Plan: test_<accept> — assert the §1 Accept line's Then (behavior, not internals).
53
- Tests live in: `./tests/` · MUST run red (missing implementation) before Build.
54
-
55
- ---
56
-
57
- ## 5 · BUILD — AI writes code
58
-
59
- Scope (may touch): `./src/` <every file the build may write — declared before the §3 freeze>
60
- Strategy & known-problem fixes: <ordered build steps · the trap each known problem must dodge · let the active persona's domain stance (or "generic") shape the approach, not just patterns>
61
- Strategy actually used: <fill at verify — what you ACTUALLY did, or "as planned"; harvested into §7 Decisions>
62
- Code lives in: `./src/` · Constraints: change no test, no contract; allow-list packages only.
63
-
64
- ---
65
-
66
- ## 6 · VERIFY — evidence + gate
67
-
68
- - [ ] all tests pass · coverage held · no test or contract altered during build
69
- - [ ] green was EARNED — no overfit / vacuous asserts / stubbed-away logic
70
- - [ ] no exposed secrets, injection openings, or unexpected dependencies (security = HARD-STOP)
71
-
72
- Build expectations (from §1 Accept + §3 CONTRACT): <the observable outcome a correct build must produce — confirmed by <how / where>>
73
-
74
- ### GATE RECORD
75
- Outcome: <PASS | RISK-ACCEPTED | HARD-STOP>
76
- Reviewed by: <name> · date: <date>
77
- <!-- A security finding is ALWAYS HARD-STOP. Record exactly one outcome — no silent pass.
78
- OBSERVE (optional): one `[SPEC · open]` or competency-delta line here if the loop taught the foundation something. -->