@pilotspace/add 1.17.0 → 2.1.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 +193 -0
- package/GETTING-STARTED.md +20 -64
- package/README.md +138 -158
- package/agents/add-advisor.md +66 -21
- package/agents/add-worker.md +102 -0
- package/bin/cli.js +88 -21
- package/package.json +2 -3
- package/personas-teacher/VENDOR.md +6 -0
- package/skill/add/SKILL.md +100 -144
- package/skill/add/adopt.md +28 -0
- package/skill/add/beyond.md +37 -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/persona-author/SKILL.md +116 -0
- package/skill/add/persona-author/assets/example-design-persona.md +55 -0
- package/skill/add/persona-author/assets/example-persona.md +57 -0
- package/skill/add/persona-author/references/contract.md +69 -0
- package/skill/add/persona-author/references/patterns.md +122 -0
- package/skill/add/persona-author/references/seeding.md +79 -0
- package/skill/add/phases/build.md +79 -0
- package/skill/add/phases/direction.md +287 -0
- package/skill/add/phases/verify.md +161 -0
- package/skill/add/run.md +16 -18
- package/skill/add/terms.md +18 -0
- package/tooling/add.py +2421 -3258
- package/tooling/add_engine/autonomy.py +2 -37
- package/tooling/add_engine/components.py +4 -87
- package/tooling/add_engine/constants.py +148 -93
- package/tooling/add_engine/guidelines.py +10 -11
- package/tooling/add_engine/io_state.py +72 -5
- 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 +129 -0
- package/tooling/templates/PROJECT.md.tmpl +6 -1
- package/tooling/templates/PROMPT.persona.md.tmpl +17 -21
- 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-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/tooling/templates/personas/_template.md.tmpl +0 -82
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. -->
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
# TASK: {{title}}
|
|
2
|
-
|
|
3
|
-
slug: {{slug}} · created: {{date}} · stage: {{stage}}
|
|
4
|
-
milestone: {{milestone}}
|
|
5
|
-
autonomy: {{autonomy}} <!-- level: manual < conservative < auto — lower for a high-risk task (`add.py autonomy set`). Multi-component repo? add a `component: <name>` line (.add/components.toml) to join that root to §5 Scope. -->
|
|
6
|
-
phase: ground <!-- ground -> specify -> scenarios -> contract -> tests -> build -> verify -> observe -> done -->
|
|
7
|
-
<!-- high-risk/method-defining? declare `risk: high` on the slug line + a lowered autonomy — the engine refuses an unguarded completion (`unguarded_high_risk_auto`). A comment is never a declaration. -->
|
|
8
|
-
|
|
9
|
-
> One file = one task — fill top-to-bottom; the phase marker above is the single source of truth (`add.py phase`); unclear phase → its book chapter.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## 0 · GROUND — the real codebase ▸ docs/02-the-flow.md
|
|
14
|
-
|
|
15
|
-
Touches (files · symbols · signatures): <path:symbol — what it is / how it is keyed>
|
|
16
|
-
Context (working folder): <docs · todos · config · data the task touches — task-delta only>
|
|
17
|
-
Honors (patterns / conventions): <PROJECT.md / CONVENTIONS.md anchors — task-delta only, never a re-scan>
|
|
18
|
-
Seams consulted: <SEAMS.md entry cited instead of re-deriving, e.g. .add/SEAMS.md#scope-token-grammar — optional, omit if none apply>
|
|
19
|
-
Anchors the contract cites: <the symbols §3 will name>
|
|
20
|
-
Issues/Risks (→ feed §1): <problems · traps · untestable risks found in the real code — task-delta; §1 builds on these>
|
|
21
|
-
Related intent: <PROJECT.md § · GLOSSARY term(s) · originating request/milestone rationale — the WHY; task-delta>
|
|
22
|
-
Ground SHA: <`git rev-parse --short HEAD` at ground time — cite symbols, not bare line numbers; any line ref is "as of" this commit>
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## 1 · SPECIFY — the rules ▸ docs/03-step-1-specify.md
|
|
27
|
-
|
|
28
|
-
Feature: <name>
|
|
29
|
-
Framings weighed: <chosen> (chosen) · <alternative> · <alternative>
|
|
30
|
-
Must:
|
|
31
|
-
<must>
|
|
32
|
-
- <required behavior>
|
|
33
|
-
</must>
|
|
34
|
-
Reject:
|
|
35
|
-
<reject>
|
|
36
|
-
- <bad input / situation> -> "<error_code>"
|
|
37
|
-
</reject>
|
|
38
|
-
After:
|
|
39
|
-
<after>
|
|
40
|
-
- <state that is true once it succeeds>
|
|
41
|
-
</after>
|
|
42
|
-
Assumptions — lowest-confidence first:
|
|
43
|
-
<assumptions>
|
|
44
|
-
⚠ <the one assumption most likely to be wrong> — lowest confidence because <why>; if wrong: <cost>
|
|
45
|
-
- [ ] <next assumption, ranked> — confirm or deny; never carry an open one forward
|
|
46
|
-
</assumptions>
|
|
47
|
-
|
|
48
|
-
<!-- EXIT: every rule + rejection stated; assumptions ranked lowest-confidence first, top 1–2 ⚠-flagged with why + cost (or an honest "none material" naming the biggest risk). -->
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## 2 · SCENARIOS — pass/fail cases ▸ docs/04-step-2-scenarios.md
|
|
53
|
-
|
|
54
|
-
<scenarios>
|
|
55
|
-
|
|
56
|
-
```gherkin
|
|
57
|
-
Scenario: <short name> # <Must/Reject item this covers, e.g. M1 or R1>
|
|
58
|
-
Given <starting situation>
|
|
59
|
-
When <action>
|
|
60
|
-
Then <expected result>
|
|
61
|
-
And <what must remain unchanged> # required for every rejection
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
</scenarios>
|
|
65
|
-
|
|
66
|
-
<!-- EXIT: one scenario per Must AND per Reject; each result is observable. -->
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## 3 · CONTRACT — freeze the shape ▸ docs/05-step-3-contract.md
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
<METHOD> <path> body: { <fields> }
|
|
74
|
-
200 -> { <success fields> }
|
|
75
|
-
4xx -> { error: "<code>" | "<code>" }
|
|
76
|
-
Schema: <tables/fields touched, and access pattern>
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Glossary deltas: <new domain term(s) this task introduces, `Term: definition` — or "none">
|
|
80
|
-
Status: DRAFT
|
|
81
|
-
Reported: <yes — the freeze report (banner/ARC/SHAPE) rendered before this froze | no>
|
|
82
|
-
<!-- The freeze IS the one approval — lead it with the bundle's lowest-confidence flag (§1 ⚠ feeds it; a flag may point at any part — run.md). Approved -> Status: FROZEN @ vN — approved by <name>; changing a frozen contract = change request back to SPECIFY. EXIT: frozen · every §1 rejection has a contracted response · names match GLOSSARY (new terms = Glossary delta) · flag surfaced. -->
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## 4 · TESTS — failing-first suite (red) ▸ docs/06-step-4-tests.md
|
|
87
|
-
|
|
88
|
-
Coverage target: <e.g. 90%>
|
|
89
|
-
Plan (one test per scenario, asserting behavior not internals):
|
|
90
|
-
<test_plan>
|
|
91
|
-
- test_<scenario>: arrange <Given> / act <When> / assert <Then> + assert <unchanged> · covers: <M#, R:code — optional>
|
|
92
|
-
</test_plan>
|
|
93
|
-
|
|
94
|
-
Tests live in: `./tests/` · MUST run red (missing implementation) before Build.
|
|
95
|
-
<!-- declare paths as backticked tokens on this line: `./…` = this task dir · a token with "/" = the project root · a bare name = a sibling of the previous token's dir · a directory counts its *.py files (non-recursive) · declared counts marked † · outside the project root counts 0 -->
|
|
96
|
-
|
|
97
|
-
<!-- EXIT: one test per scenario; suite red for the RIGHT reason; target recorded. -->
|
|
98
|
-
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
## 5 · BUILD — AI writes code ▸ docs/07-step-5-build.md
|
|
102
|
-
|
|
103
|
-
Scope (may touch): `./src/` <fill before the §3 freeze — every file the build may write>
|
|
104
|
-
Strategy (ordered batches): <1. … 2. … — the planned build order; guidance, not enforced; preferred architecture/pattern strategies; advise solution/method to resolve issues/implement features; let the named Persona's domain stance (below) shape the approach, not just architecture patterns>
|
|
105
|
-
|
|
106
|
-
Persona (required): <name the persona file under `.add/personas/` this build embodies as a domain stance atop SOUL.md — advisory, never lowers a gate; name "generic" if no project persona fits yet>
|
|
107
|
-
Spawn isolation (default): <prefer isolation: "worktree" for any subagent build/verify spawn, not only explicit parallel mode; shared-tree needs a stated reason — see worktree-isolated-spawn-default>
|
|
108
|
-
Known-problem fixes: <trap → planned fix — the failure modes this build must dodge; guidance, not enforced>
|
|
109
|
-
Strategy actually used: <fill at VERIFY — the strategy you ACTUALLY used (or "as planned"); harvested into the §7 Decisions (ADR) block as the [AI] build decision>
|
|
110
|
-
Safety rule (feature-specific): <e.g. debit+credit in one atomic transaction>
|
|
111
|
-
Code lives in: `./src/`
|
|
112
|
-
Constraints: do NOT change any test or the contract; allow-list packages only; ask if unclear.
|
|
113
|
-
|
|
114
|
-
<!-- Scope tokens, backticked, FIRST declaring line: `./…` = this task dir · a token with "/" = project root · a bare name = sibling of the previous token's dir · a DIRECTORY token covers its whole subtree (diverges from §4's non-recursive counting) · outside-root resolutions drop fail-closed · absent line = UNDECLARED (grandfathered, never retro-red) · enforcement live: a completing verify gate refuses an out-of-scope build (scope_violation → self-heal); check surfaces it. EXIT: all green; coverage held; no test/contract touched; no unlisted dependency. -->
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## 6 · VERIFY — evidence + non-functional review ▸ docs/08-step-6-verify.md
|
|
119
|
-
|
|
120
|
-
- [ ] all tests pass
|
|
121
|
-
- [ ] coverage did not decrease
|
|
122
|
-
- [ ] no test or contract was altered during build
|
|
123
|
-
- [ ] the green was EARNED, not gamed — no overfit to fixtures, vacuous asserts, or stubbed-away logic (score with an adversarial refute-read — a subagent recommended under `autonomy: auto`; a confirmed cheat is HARD-STOP)
|
|
124
|
-
- [ ] concurrency / timing of the risky operation is safe
|
|
125
|
-
- [ ] no exposed secrets, injection openings, or unexpected dependencies
|
|
126
|
-
- [ ] layering & dependencies follow CONVENTIONS.md
|
|
127
|
-
- [ ] a person reviewed and approved the change
|
|
128
|
-
|
|
129
|
-
### Build expectations — what "correct" looks like (fill BEFORE build; confirm each at the gate)
|
|
130
|
-
> OBSERVABLE outcomes a correct build must produce, derived from the §2 scenarios + §3 contract — evidence you can SEE, not test names.
|
|
131
|
-
- [ ] <observable outcome a correct build must produce> — confirmed by <how / where>
|
|
132
|
-
- [ ] <another observable outcome> — confirmed by <evidence seen>
|
|
133
|
-
|
|
134
|
-
### Deep checks — do not skim (fill the path that applies; the resolver judges which)
|
|
135
|
-
- [ ] WIRING (code) — every new symbol is referenced; record where / how confirmed
|
|
136
|
-
- [ ] DEAD-CODE (code) — no new unused or orphaned symbol introduced
|
|
137
|
-
- [ ] SEMANTIC (prose / non-code) — read in full, not skimmed: <what read · what confirmed>
|
|
138
|
-
|
|
139
|
-
### Live-verify evidence — confirm the §0 GROUND anchors still resolve (fill at the gate)
|
|
140
|
-
> Re-resolve every symbol §3 cites against the CURRENT tree (code moved since Ground SHA) — catch a stale anchor here, not later.
|
|
141
|
-
- [ ] every symbol §3 CONTRACT cites still resolves in the current tree — confirmed by <how / where>
|
|
142
|
-
- [ ] any anchor that moved/renamed since Ground SHA is named here, not left silent
|
|
143
|
-
|
|
144
|
-
### Refute-read verdict — the earned-green check (record it; required for an auto-PASS)
|
|
145
|
-
> Under auto, record the earned-green refute-read (the engine never spawns it — you do; NOT-EARNED -> `add.py heal`). Audit-measured (`refute_unrecorded`), never blocked; a human spot-audit is the backstop.
|
|
146
|
-
Verdict: <EARNED | NOT-EARNED>
|
|
147
|
-
By: <self | agent-id> · adversarially checked: <what was probed>
|
|
148
|
-
|
|
149
|
-
### Advisor 3-lens verdict — sequential (security → concurrency → architecture)
|
|
150
|
-
> Lenses run in order; a Security HARD-STOP ends the checklist (leave the rest blank). Binding for sensitivity: mechanical (advisor-gate-relax); advisory otherwise. Audit-measured (`advisor_verdict_unrecorded`), never blocked.
|
|
151
|
-
Advisor: <agent-id | self>
|
|
152
|
-
1. Security: <CLEAR | HARD-STOP: finding>
|
|
153
|
-
2. Concurrency: <CLEAR | RESIDUE: finding>
|
|
154
|
-
3. Architecture: <CLEAR | RESIDUE: finding>
|
|
155
|
-
Verdict: <PASS | HARD-STOP>
|
|
156
|
-
Residue: <none | summary>
|
|
157
|
-
Binding: <yes — mechanical | advisory — <sensitivity>>
|
|
158
|
-
|
|
159
|
-
### GATE RECORD
|
|
160
|
-
Reported: <yes — the gate report (banner/ARC) rendered before this outcome recorded | no>
|
|
161
|
-
Outcome: <PASS | RISK-ACCEPTED | HARD-STOP>
|
|
162
|
-
If RISK-ACCEPTED -> owner: <name> · ticket: <link> · expires: <date> (never for a security gap)
|
|
163
|
-
Reviewed by: <name> · date: <date>
|
|
164
|
-
|
|
165
|
-
<!-- Security is ALWAYS HARD-STOP; record exactly one outcome — no silent pass. The Advisor 3-lens and Refute-read verdicts are audit-measured (`advisor_verdict_unrecorded` · `refute_unrecorded`), never engine-blocked; a human spot-audit backstops anything unrecorded. -->
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## 7 · OBSERVE — feed the next loop ▸ docs/09-the-loop.md
|
|
170
|
-
|
|
171
|
-
Watch (reuse scenarios as monitors): <error rate / per-rejection rate / latency>
|
|
172
|
-
|
|
173
|
-
### Decisions (ADR)
|
|
174
|
-
<harvested at done from §1/§3/§5/§6 — do not hand-edit; one actor-tagged line per decision, refilled only while this placeholder stands>
|
|
175
|
-
|
|
176
|
-
### Spec delta
|
|
177
|
-
One line per forward change, tagged `[SPEC · open|seeded|dropped]` + evidence — each re-enters at Specify (`deltas.md`).
|
|
178
|
-
|
|
179
|
-
### Competency deltas
|
|
180
|
-
One lesson per line: `[DDD|SDD|UDD|TDD|ADD · open] the learning (evidence: …)` — see `deltas.md`.
|
|
181
|
-
<!-- e.g. - [DDD · open] the model missed multi-tenancy (evidence: scenario_x failed) -->
|