@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.
- package/CHANGELOG.md +144 -0
- package/GETTING-STARTED.md +20 -64
- package/README.md +128 -56
- package/agents/add.md +68 -0
- package/bin/cli.js +86 -21
- package/package.json +2 -3
- package/personas-teacher/VENDOR.md +6 -0
- package/skill/add/SKILL.md +100 -134
- package/skill/add/adopt.md +28 -0
- package/skill/add/beyond.md +36 -0
- package/skill/add/deltas.md +25 -2
- package/skill/add/design.md +56 -74
- package/skill/add/{report-template.md → gate-udd.md} +28 -38
- package/skill/add/intake.md +56 -25
- package/skill/add/loop.md +32 -19
- package/skill/add/phases/build.md +78 -0
- package/skill/add/phases/direction.md +280 -0
- package/skill/add/phases/verify.md +160 -0
- package/skill/add/run.md +11 -18
- package/skill/add/terms.md +18 -0
- package/tooling/add.py +2383 -3261
- package/tooling/add_engine/autonomy.py +2 -37
- package/tooling/add_engine/components.py +4 -87
- package/tooling/add_engine/constants.py +145 -91
- package/tooling/add_engine/guidelines.py +9 -11
- package/tooling/add_engine/io_state.py +69 -2
- package/tooling/add_engine/predicates.py +90 -2
- package/tooling/add_engine/search.py +6 -6
- package/tooling/add_engine/taskdoc.py +15 -10
- package/tooling/templates/CONVENTIONS.md.tmpl +1 -1
- package/tooling/templates/GLOSSARY.md.tmpl +10 -4
- package/tooling/templates/MILESTONE.md.tmpl +20 -16
- package/tooling/templates/PLAN.md.tmpl +128 -0
- package/tooling/templates/PROJECT.md.tmpl +6 -1
- package/tooling/templates/PROMPT.persona.md.tmpl +17 -21
- package/tooling/templates/personas/_template.md.tmpl +33 -29
- package/tooling/templates/personas/build-engineer.md.tmpl +45 -0
- package/tooling/templates/personas/data-steward.md.tmpl +45 -0
- package/tooling/templates/personas/evidence-verifier.md.tmpl +45 -0
- package/tooling/templates/personas/platform-engineer.md.tmpl +45 -0
- package/tooling/templates/personas/product-lead.md.tmpl +51 -0
- package/tooling/templates/personas/quality-auditor.md.tmpl +47 -0
- package/tooling/templates/personas/release-manager.md.tmpl +52 -0
- package/tooling/templates/personas/security-gatekeeper.md.tmpl +45 -0
- package/tooling/templates/personas/software-architect.md.tmpl +45 -0
- package/tooling/templates/personas/stream-orchestrator.md.tmpl +44 -0
- package/tooling/templates/personas/technical-writer.md.tmpl +49 -0
- package/tooling/templates/personas/ux-experience-lead.md.tmpl +48 -0
- package/tooling/templates/specs/SPEC.md.tmpl +18 -0
- package/tooling/templates/udd-wireframe.md +1 -1
- package/agents/add-advisor.md +0 -31
- package/agents/add-build.md +0 -29
- package/agents/add-design.md +0 -32
- package/agents/add-persona.md +0 -33
- package/agents/add-verify.md +0 -36
- package/docs/00-introduction.md +0 -46
- package/docs/01-principles.md +0 -71
- package/docs/02-the-flow.md +0 -113
- package/docs/03-step-1-specify.md +0 -123
- package/docs/04-step-2-scenarios.md +0 -90
- package/docs/05-step-3-contract.md +0 -80
- package/docs/06-step-4-tests.md +0 -85
- package/docs/07-step-5-build.md +0 -82
- package/docs/08-step-6-verify.md +0 -105
- package/docs/09-the-loop.md +0 -75
- package/docs/10-setup-and-stages.md +0 -118
- package/docs/11-governance.md +0 -91
- package/docs/12-roles.md +0 -99
- package/docs/13-adoption.md +0 -67
- package/docs/14-foundation.md +0 -142
- package/docs/15-foundations-and-lineage.md +0 -106
- package/docs/16-releasing.md +0 -182
- package/docs/17-components.md +0 -143
- package/docs/18-personas.md +0 -80
- package/docs/README.md +0 -77
- package/docs/add-competencies.png +0 -0
- package/docs/add-flow.png +0 -0
- package/docs/add-foundation.png +0 -0
- package/docs/add-hierarchy.png +0 -0
- package/docs/add-milestone-task-lifecycle.png +0 -0
- package/docs/add-task-growth-wheel.png +0 -0
- package/docs/appendix-a-templates.md +0 -88
- package/docs/appendix-b-prompts.md +0 -154
- package/docs/appendix-c-glossary.md +0 -176
- package/docs/appendix-d-worked-example.md +0 -231
- package/docs/appendix-e-checklists.md +0 -92
- package/docs/appendix-f-requirements-matrix.md +0 -171
- package/docs/appendix-g-references.md +0 -106
- package/skill/add/advisor.md +0 -81
- package/skill/add/compact-foundation.md +0 -40
- package/skill/add/components.md +0 -52
- package/skill/add/confidence.md +0 -32
- package/skill/add/fold.md +0 -63
- package/skill/add/graduate.md +0 -39
- package/skill/add/phases/0-ground.md +0 -64
- package/skill/add/phases/0-setup.md +0 -103
- package/skill/add/phases/1-specify.md +0 -61
- package/skill/add/phases/2-scenarios.md +0 -48
- package/skill/add/phases/3-contract.md +0 -60
- package/skill/add/phases/4-tests.md +0 -61
- package/skill/add/phases/5-build.md +0 -62
- package/skill/add/phases/6-verify.md +0 -69
- package/skill/add/phases/7-observe.md +0 -45
- package/skill/add/phases/fast-lane.md +0 -34
- package/skill/add/release.md +0 -61
- package/skill/add/scope.md +0 -72
- package/skill/add/self-improve.md +0 -20
- package/skill/add/sensitivity.md +0 -51
- package/skill/add/setup-review.md +0 -48
- package/skill/add/soul.md +0 -58
- package/skill/add/streams.md +0 -269
- package/tooling/add_engine/release.py +0 -86
- package/tooling/templates/TASK.fast.md.tmpl +0 -78
- 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.
|
package/skill/add/streams.md
DELETED
|
@@ -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. -->
|