@pilotspace/add 1.2.0 → 1.4.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 +122 -0
- package/GETTING-STARTED.md +26 -0
- package/README.md +16 -3
- package/bin/cli.js +85 -8
- package/docs/02-the-flow.md +4 -1
- package/docs/03-step-1-specify.md +2 -0
- package/docs/06-step-4-tests.md +8 -0
- package/docs/07-step-5-build.md +2 -0
- package/docs/08-step-6-verify.md +11 -0
- package/docs/09-the-loop.md +3 -1
- package/docs/10-setup-and-stages.md +1 -1
- package/docs/11-governance.md +4 -0
- package/docs/appendix-c-glossary.md +16 -1
- package/docs/appendix-e-checklists.md +14 -2
- package/package.json +1 -1
- package/skill/add/SKILL.md +18 -5
- package/skill/add/advisor.md +75 -0
- package/skill/add/compact-foundation.md +53 -0
- package/skill/add/confidence.md +48 -0
- package/skill/add/fold.md +4 -4
- package/skill/add/phases/0-ground.md +68 -0
- package/skill/add/phases/0-setup.md +52 -3
- package/skill/add/phases/1-specify.md +7 -0
- package/skill/add/phases/2-scenarios.md +2 -0
- package/skill/add/phases/3-contract.md +5 -1
- package/skill/add/phases/4-tests.md +2 -0
- package/skill/add/phases/5-build.md +24 -0
- package/skill/add/phases/6-verify.md +18 -0
- package/skill/add/phases/7-observe.md +7 -0
- package/skill/add/run.md +48 -5
- package/skill/add/soul.md +77 -0
- package/skill/add/streams.md +65 -9
- package/tooling/add.py +1715 -64
- package/tooling/templates/DESIGN.md.tmpl +66 -0
- package/tooling/templates/GLOSSARY.md.tmpl +11 -1
- package/tooling/templates/PROJECT.md.tmpl +3 -1
- package/tooling/templates/SOUL.md.tmpl +40 -0
- package/tooling/templates/TASK.md.tmpl +23 -4
- package/tooling/templates/catalog.sample.json +38 -0
- package/tooling/templates/prototype.sample.json +48 -0
- package/tooling/templates/tokens.sample.json +55 -0
- package/tooling/templates/udd-catalog.md +122 -0
- package/tooling/templates/udd-tokens.md +79 -0
package/skill/add/run.md
CHANGED
|
@@ -28,7 +28,7 @@ What the human is actually approving in that one gate: that the drafted Spec cap
|
|
|
28
28
|
that the Scenarios cover the cases that matter, and that the Contract shape is the one to freeze. Reject
|
|
29
29
|
any part and the bundle goes back to draft — that is backward-correction (principle 4), not failure.
|
|
30
30
|
Approve, and the run begins. The decision-point guide (`phases/3-contract.md`) carries the
|
|
31
|
-
**freeze review checklist** —
|
|
31
|
+
**freeze review checklist** — seven lines that walk the human through exactly this, ⚠-first.
|
|
32
32
|
|
|
33
33
|
**The lowest-confidence flag — aiming the one approval.** A single approval over a whole bundle is easy to
|
|
34
34
|
grant without reading. So the AI presents the bundle **lowest-confidence first**: of everything it is asking the human
|
|
@@ -117,6 +117,34 @@ The auto-gate NEVER writes a human signature it did not get. An auto-PASS is log
|
|
|
117
117
|
honestly — the line between a pass and a skip is the recorded outcome, not a forged name.
|
|
118
118
|
</constraints>
|
|
119
119
|
|
|
120
|
+
## The bounded self-heal loop — a confirmed cheat returns to build
|
|
121
|
+
|
|
122
|
+
The auto-gate trusts evidence; but evidence can be **gamed**. A build can make the unchanged red suite
|
|
123
|
+
pass without EARNING it — a test or the frozen contract edited after the red run, src **overfit** to the
|
|
124
|
+
fixtures, **vacuous** asserts, or real logic **stubbed away**. That is a **confirmed cheat**, and a cheat
|
|
125
|
+
is **HARD-STOP-class**: never auto-passed, never RISK-ACCEPTED-waived (like a security finding). But a
|
|
126
|
+
first cheat is not yet a stop — it is a chance to redo honestly.
|
|
127
|
+
|
|
128
|
+
So a confirmed cheat enters a **bounded self-heal loop**: the engine returns the task to **build** for an
|
|
129
|
+
honest redo, **counts** the attempt, and **caps** it. After **3** honest re-build attempts a fourth
|
|
130
|
+
confirmed cheat forces a **HARD-STOP that escalates to the human** — never an auto-PASS, never an unbounded
|
|
131
|
+
loop. The engine COUNTS, CAPS, and ESCALATES; the **agent** does the honest re-build (the engine never
|
|
132
|
+
auto-fixes). The counter is **monotonic** — it never auto-resets, so the cap cannot be cleared by
|
|
133
|
+
re-crossing a phase; only an honest build (no cheat) escapes the loop, and an honest build PASSes even at
|
|
134
|
+
the third attempt (the cap bites a *continued* cheat, never a recovery).
|
|
135
|
+
|
|
136
|
+
Two findings enter the loop:
|
|
137
|
+
- **mechanical** (enforced) — the tamper tripwire (`tamper-tripwire`): at the gate the engine re-hashes the
|
|
138
|
+
red test files + the frozen §3 against the `tests→build` snapshot; any divergence is a cheat, routed to
|
|
139
|
+
the loop before any completing outcome is recorded.
|
|
140
|
+
- **semantic** (honor-system, necessary-not-sufficient) — the **adversarial refute-read** (`6-verify.md`):
|
|
141
|
+
an independent reviewer argues "the green was NOT earned" and, on a confirmed overfit/vacuous/stub, the
|
|
142
|
+
agent reports it with `add.py heal <slug> --reason "<finding>"`. The engine cannot SEE a judgment cheat,
|
|
143
|
+
so this entry is the agent's honest report — the human verify gate stays the real backstop.
|
|
144
|
+
|
|
145
|
+
The mechanical entry returns-to-build automatically at the gate; the `heal` verb is how a *reported* cheat
|
|
146
|
+
enters the same bounded loop. Either way: ≤3 honest redos, then escalate. A gamed green never ships.
|
|
147
|
+
|
|
120
148
|
## Emitting deltas — feeding the foundation back
|
|
121
149
|
|
|
122
150
|
The completeness-critic does not discard what it finds. Every gap, surprise, or convention that helped
|
|
@@ -137,14 +165,19 @@ How much a run may auto-gate is a **per-scope setting**, not a global switch (pr
|
|
|
137
165
|
earned per scope). A task declares its level in its `TASK.md` header:
|
|
138
166
|
|
|
139
167
|
```
|
|
140
|
-
autonomy:
|
|
168
|
+
autonomy: manual | conservative | auto
|
|
141
169
|
```
|
|
142
170
|
|
|
143
|
-
|
|
171
|
+
An ordered ladder — `manual < conservative < auto` — declared once in the header and reviewed at the freeze:
|
|
172
|
+
|
|
173
|
+
- **auto (the seeded default)** — the run may auto-PASS when the evidence + residue checks above are
|
|
144
174
|
satisfied. Security still always escalates. This is the default starting point: a frozen contract
|
|
145
175
|
flips the task into a self-driving run that converges and auto-gates on evidence.
|
|
146
176
|
- **conservative** — the deliberate *lowering*: the run does all the work and converges, but STOPS at
|
|
147
177
|
the verify gate for a human. Auto-PASS is disabled. Choose it wherever evidence is thin or risk is high.
|
|
178
|
+
- **manual** — the strict floor: the human owns the verify gate and the engine never auto-resolves
|
|
179
|
+
(behaviourally the conservative floor with the explicit "I drive this decision; the AI proposes only"
|
|
180
|
+
name). Choose it for the highest-stakes scope; like `conservative`, it satisfies the high-risk guard.
|
|
148
181
|
|
|
149
182
|
> **v7 reversal (recorded, not hidden).** Earlier the default was `conservative` and `auto` was the
|
|
150
183
|
> earned exception; v7 flips this — `auto` is the default, `conservative` is the deliberate lowering.
|
|
@@ -154,7 +187,8 @@ autonomy: auto | conservative
|
|
|
154
187
|
**The high-risk guard — `auto` is refused where it matters most.** The autonomy level is not a blank cheque. On a
|
|
155
188
|
**high-risk or method-defining scope** — anything where a wrong-but-plausible result is expensive or
|
|
156
189
|
hard to reverse (auth, money, data-loss paths, the method/trust-layer itself) — `auto` must be lowered
|
|
157
|
-
to `conservative`; leaving it at `auto` there is the reject code
|
|
190
|
+
to a stricter rung — `conservative` or `manual`; leaving it at `auto` there is the reject code
|
|
191
|
+
**`unguarded_high_risk_auto`**. This
|
|
158
192
|
closes the v6 dogfood gap, where the whole milestone ran at `auto` on the riskiest possible
|
|
159
193
|
scope (defining the method) with no friction. The default is `auto` *for ordinary, well-tested scope*;
|
|
160
194
|
high risk still earns a human gate.
|
|
@@ -163,9 +197,18 @@ Judging *what* is high-risk stays human — the scope declares **`risk: high`**
|
|
|
163
197
|
header where the autonomy level lives, reviewed at the freeze like every header line (the engine never
|
|
164
198
|
classifies scope). **Since v14 the guard is mechanical for the declared case:**
|
|
165
199
|
the engine refuses the declared combination — `add.py gate` will not complete (`PASS`/`RISK-ACCEPTED`) a task whose header
|
|
166
|
-
carries `risk: high` without `
|
|
200
|
+
carries `risk: high` without a lowered level — `conservative` or `manual` (error `unguarded_high_risk_auto`; `HARD-STOP`
|
|
167
201
|
always records — stopping is never blocked), and `add.py audit` flags the same code on a finished
|
|
168
202
|
record whose header was tampered or whose GATE RECORD reviewer is the auto-gate — which CI enforces
|
|
169
203
|
(audit-ci). The honest limit mirrors the audit's: an **undeclared** high-risk scope passes; declaring
|
|
170
204
|
is the human decision point, the engine enforces what was declared.
|
|
205
|
+
|
|
206
|
+
**Autonomy is earned by goal-clarity — the auto-ready goal.** The level decides *who* resolves Verify;
|
|
207
|
+
an **auto-ready goal** decides whether a self-verifying run is even *meaningful*. A milestone goal is
|
|
208
|
+
auto-ready when **every exit criterion cites a verifier** — `(verify: <test | command | metric>)` — so the
|
|
209
|
+
run can check its own result against the goal without human judgment. `add.py check` raises a
|
|
210
|
+
`goal_not_auto_ready` WARN (never red, the active milestone only) while criteria are uncited, and `status`
|
|
211
|
+
prints a `goal-ready:` line every session. It **measures, never blocks** — it changes neither the freeze
|
|
212
|
+
gate nor the autonomy level. The lint forces a citation slot per criterion (raising the floor) but cannot
|
|
213
|
+
prove the citation is honest (`(verify: it works)` passes) — that judgment stays the human's.
|
|
171
214
|
</constraints>
|
|
@@ -0,0 +1,77 @@
|
|
|
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**
|
|
4
|
+
and is **human-owned**; this doc is how it stops being write-once and starts converging to *this*
|
|
5
|
+
human. It mirrors `deltas.md` (emit) + `fold.md` (confirm → rewrite), but a confirmed voice delta is
|
|
6
|
+
consolidated into **SOUL.md**, not the foundation — because voice is not one of the five competencies.
|
|
7
|
+
|
|
8
|
+
You (the AI) **emit** voice deltas as `open`. Only the **human** confirms one, and only a confirmed
|
|
9
|
+
delta rewrites SOUL.md. **The human's confirm is the only writer** — you never self-approve a voice
|
|
10
|
+
rewrite (rewriting someone's voice is theirs to approve, like a foundation consolidation).
|
|
11
|
+
|
|
12
|
+
## What a voice delta is drawn from
|
|
13
|
+
|
|
14
|
+
A voice delta is grounded in how the human actually shows up **in session**:
|
|
15
|
+
- their **wordings** — the words they reach for, and the words they correct you on (they cross out a
|
|
16
|
+
bit of jargon and write the plain word over it);
|
|
17
|
+
- their **flow** — what they skip, what they double-check, where they want the summary before the detail.
|
|
18
|
+
|
|
19
|
+
NOT from their private **memory** files or anything outside the working session — SOUL learns from what
|
|
20
|
+
you observed together, never from reading a personal store.
|
|
21
|
+
|
|
22
|
+
## The grammar (mirrors deltas.md)
|
|
23
|
+
|
|
24
|
+
Each voice delta begins on its own tag line; the observation may wrap, and a required `(evidence: …)`
|
|
25
|
+
clause closes it:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
- [VOICE · <status>] <observation about the voice> (evidence: <in-session pointer>)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- `<status>` — `open` | `confirmed` | `declined`. A newly emitted delta is **`open`**.
|
|
32
|
+
- `<observation>` — what the voice should become ("lead with the decision, not the preamble").
|
|
33
|
+
- `(evidence: …)` — **required**, non-empty: a moment in the session (a correction, a re-ask, a
|
|
34
|
+
visible preference). No evidence → it is a guess about the human, not a delta. Drop it.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
- [VOICE · open] the human strips hedging from my drafts — cut "I think / it seems" and state it plainly
|
|
38
|
+
(evidence: they rewrote two replies this session to remove the qualifier)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## The loop — observe → confirm → rewrite
|
|
42
|
+
|
|
43
|
+
1. **Emit** (OBSERVE) — at a task's observe phase (or on demand), propose 0–N voice deltas as `open`
|
|
44
|
+
from the session's wordings + flow. Surface them in the report; show-before-ask.
|
|
45
|
+
2. **Confirm** — the human accepts or declines each. **No SOUL.md write happens without this.**
|
|
46
|
+
3. **Rewrite** — on a confirmed delta, edit the routed SOUL.md section, then record the delta line
|
|
47
|
+
(status `confirmed`) at the **top** of the "Voice deltas" ledger (**newest-first**, append-only — a
|
|
48
|
+
declined delta flips to `declined` and stays in place, so "considered, chose not to" is auditable).
|
|
49
|
+
|
|
50
|
+
## Routing — every voice delta has a SOUL.md home
|
|
51
|
+
|
|
52
|
+
| the delta is about… | rewrite this SOUL.md section |
|
|
53
|
+
|---------------------|------------------------------|
|
|
54
|
+
| how I *sound* (warmth, directness, hedging) | **## Tone** |
|
|
55
|
+
| how I *structure* what I say (summary-first, show-before-ask, length) | **## Communication style** |
|
|
56
|
+
| what keeps the human's *trust* (gates, honesty, what I never do) | **## Trust** |
|
|
57
|
+
|
|
58
|
+
The rewrite is surgical: refine or append the bullet the delta names; never silently rewrite the rest
|
|
59
|
+
of the voice. Every confirmed delta also gets its line in **## Voice deltas** (newest-first).
|
|
60
|
+
|
|
61
|
+
## Reject codes (the AI is first check, the human the backstop)
|
|
62
|
+
|
|
63
|
+
<reject_codes>
|
|
64
|
+
- `unconfirmed_voice_rewrite` — a SOUL.md write was attempted without a recorded human confirm. The AI
|
|
65
|
+
proposes; it never self-approves. Stop and get the confirm. (The identity-owned floor.)
|
|
66
|
+
- `no_open_voice_deltas` — nothing is `open`. The loop is a no-op; do not touch SOUL.md.
|
|
67
|
+
- `unroutable_voice_delta` — the observation maps to no SOUL.md section (not tone/style/trust). Fix the
|
|
68
|
+
delta or widen the routing before writing.
|
|
69
|
+
</reject_codes>
|
|
70
|
+
|
|
71
|
+
## Where it plugs in
|
|
72
|
+
|
|
73
|
+
- **Emit**: `phases/7-observe.md` proposes voice deltas beside its competency/spec deltas.
|
|
74
|
+
- **Target**: `SOUL.md` (scaffolded by setup) — its "## Voice deltas" ledger holds the confirmed history.
|
|
75
|
+
- **Kin**: `deltas.md` (competency learnings → foundation) and `fold.md` (the same propose→confirm→write
|
|
76
|
+
discipline). This is the voice's version of that discipline; the engine stays judgment-free (no
|
|
77
|
+
`add.py` command writes the voice).
|
package/skill/add/streams.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# Parallel streams — pipelining independent tasks
|
|
2
2
|
|
|
3
|
-
Load this
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Load this when a milestone has more than one task and you want to run them concurrently.
|
|
4
|
+
**Default:** when a project confirms `parallel + auto` as its run mode at setup
|
|
5
|
+
(`phases/0-setup.md` "Run mode"), parallel streaming is the project default — an **opt-out**, not
|
|
6
|
+
the opt-in it once was; downgrade in one step (`add.py autonomy set conservative --project`, or just
|
|
7
|
+
run tasks one at a time). A project that kept the conservative run mode still treats this rubric as
|
|
8
|
+
the opt-in escape hatch. Either way it changes nothing below.
|
|
6
9
|
|
|
7
10
|
It changes **no `add.py` code and no phase semantics**. It is a way *you, the
|
|
8
11
|
orchestrator*, drive several tasks at once by reading the dependency DAG that
|
|
@@ -35,6 +38,44 @@ Compute both from one `python3 .add/tooling/add.py status` — no new state:
|
|
|
35
38
|
└──────────────── a task gating PASS unblocks its dependents ──────────────┘
|
|
36
39
|
```
|
|
37
40
|
|
|
41
|
+
## The DAG strategy — let the engine schedule the waves (`add.py waves`)
|
|
42
|
+
|
|
43
|
+
Do **not** eyeball the READY-QUEUE by hand once a milestone has more than a couple of
|
|
44
|
+
tasks — the engine computes the whole schedule from the dependency DAG `status` already
|
|
45
|
+
holds. `add.py waves` (read-only, writes nothing) groups the active milestone's not-done
|
|
46
|
+
tasks into **topological waves**, names the **critical path**, and emits an advisory
|
|
47
|
+
**tier hint** — exactly the inputs you need to fan out effectively:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
$ add.py waves
|
|
51
|
+
milestone: v13-onboarding-polish
|
|
52
|
+
wave 1: dag-scheduler, setup-suggest-milestone, setup-domain-deepdive, soul-artifact
|
|
53
|
+
wave 2: setup-run-mode (deps: dag-scheduler), soul-self-improve (deps: soul-artifact)
|
|
54
|
+
critical path: dag-scheduler → setup-run-mode (2 tasks)
|
|
55
|
+
tier hint: top → dag-scheduler, setup-run-mode; mid → the rest
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Read the schedule as a strategy, not a command:
|
|
59
|
+
|
|
60
|
+
- **Wave = a fan-out batch.** Every task in a wave has all its in-milestone deps already
|
|
61
|
+
PASS, so the whole wave is spawnable at once (one worker per task, `isolation="worktree"`).
|
|
62
|
+
Finish a wave, gate its tasks PASS, then `add.py waves` again — the next wave is unblocked.
|
|
63
|
+
- **Run the widest wave first.** It hides the most build latency under the human's review
|
|
64
|
+
latency (the honest frame above): more concurrent builds while the reviewer reads one bundle.
|
|
65
|
+
- **Spend your strongest model on the critical path.** The critical-path tasks gate the most
|
|
66
|
+
downstream work, so a wrong-but-plausible result there is the costliest — give them the
|
|
67
|
+
**top** tier (`run.md` tiers); off-path tasks take **mid**. The tier hint is exactly this rule,
|
|
68
|
+
applied to the graph. It is **advisory** — graph position is a proxy for scope difficulty, not a
|
|
69
|
+
gate; override it when you know a task is harder than its position suggests.
|
|
70
|
+
- **`--json`** (`{ milestone, waves, critical_path, critical_path_len, tiers, blocked }`) feeds a
|
|
71
|
+
runner that spawns the wave programmatically. `blocked` lists any task whose dep can never be
|
|
72
|
+
satisfied within this milestone (a cross-milestone dep) — surfaced, never silently dropped; a
|
|
73
|
+
`dependency_cycle` is refused with the offending members named (no schedule exists).
|
|
74
|
+
|
|
75
|
+
What `waves` does **not** change: the irreducible floor below still holds — one human approval
|
|
76
|
+
per contract, builds overlap but the review queue stays serial. `waves` decides *order and model*,
|
|
77
|
+
never *whether the human gate fires*.
|
|
78
|
+
|
|
38
79
|
## The autonomy level is the throttle (not a new flag)
|
|
39
80
|
|
|
40
81
|
How much concurrency you actually get is set by each task's `autonomy:` header
|
|
@@ -42,9 +83,9 @@ How much concurrency you actually get is set by each task's `autonomy:` header
|
|
|
42
83
|
|
|
43
84
|
| `autonomy` (TASK.md) | What serializes on the human | Concurrency |
|
|
44
85
|
|----------------------|------------------------------|-------------|
|
|
45
|
-
| `conservative` | bundle approval **+** every Verify | pure pipelining — builds overlap, both gates queue |
|
|
86
|
+
| `conservative` / `manual` | bundle approval **+** every Verify | pure pipelining — builds overlap, both gates queue (`manual` is the strict floor; same streams behaviour) |
|
|
46
87
|
| `auto` (default) | bundle approval **only**; Verify auto-PASSes on evidence | real concurrency — only the decision point + residue escalations queue |
|
|
47
|
-
| `auto` but **high-risk** | refused →
|
|
88
|
+
| `auto` but **high-risk** | refused → must lower to `conservative` / `manual` (`unguarded_high_risk_auto`) | back to pipelining, by design |
|
|
48
89
|
|
|
49
90
|
The irreducible floor is **one human approval per task at the contract decision point** — the decision point
|
|
50
91
|
never drops to zero (`run.md:22`). That floor is correct; do not engineer around it.
|
|
@@ -72,6 +113,16 @@ never drops to zero (`run.md:22`). That floor is correct; do not engineer around
|
|
|
72
113
|
worktree forked from a stale base forces the worker to recreate the frozen artifacts by hand
|
|
73
114
|
(the v10 dogfood hit exactly this). Before the worker starts, confirm `git -C <worktree>
|
|
74
115
|
rev-parse HEAD` equals the orchestrator's `HEAD`; if it drifted, `git merge` the base in first.
|
|
116
|
+
On a runner that creates each worktree **at spawn** from a pool (e.g. Claude Code), that pool can hand
|
|
117
|
+
out a STALE base, so the pre-spawn `rev-parse` evidence cell is unsatisfiable. The `unverified_fork_base`
|
|
118
|
+
check then **shifts** — it never skips: the worker's **step-0** syncs to base (`git merge` the orchestrator's
|
|
119
|
+
`HEAD`) and re-echoes `rev-parse HEAD`, which the orchestrator verifies at **merge-time**, before merge-back.
|
|
120
|
+
The pre-spawn check stays the DEFAULT for fresh-`HEAD`-worktree runners; the merge-time path is the additive
|
|
121
|
+
ALTERNATIVE for spawn-time runners — never a replacement of the pre-spawn rule.
|
|
122
|
+
**The engine executes this gate** (engine-merge-base-enforcement): run
|
|
123
|
+
`python3 .add/tooling/add.py wave-verify` before the first merge-back — it refuses a mismatched or
|
|
124
|
+
pending echo (`unverified_fork_base`) and an off-template ledger (`wave_ledger_malformed`, fail-closed);
|
|
125
|
+
`add.py check` is the standing monitor (red at `status: merging`, `fork_base_pending` WARN at `live`).
|
|
75
126
|
- **Lease + timeout** — record which worker holds which task (in the wave ledger, below);
|
|
76
127
|
if a worker dies, release the claim back to READY (re-spawn, do not assume partial work is sound).
|
|
77
128
|
- **Failure isolates** — a worker that hits a STOP-and-escalate (below) blocks only its
|
|
@@ -114,7 +165,10 @@ base: <orchestrator HEAD at spawn — the sha every fork must equal>
|
|
|
114
165
|
`git -C <worktree> rev-parse HEAD`, and it must equal `base:`. A tick is not evidence; a row
|
|
115
166
|
you can only fill by running the command is the fresh-worktree-base check EXECUTING — the
|
|
116
167
|
v12-1 lesson (words-exist ≠ method-works) closed structurally. Spawning a worker whose roster
|
|
117
|
-
row lacks that evidence is refused (`unverified_fork_base`).
|
|
168
|
+
row lacks that evidence is refused (`unverified_fork_base`). On a spawn-time pool runner this
|
|
169
|
+
PRE-spawn paste is unsatisfiable (the pooled base is stale until the worker syncs), so the cell
|
|
170
|
+
instead holds the worker's **step-0** post-sync echo (still `== base:`) and the `unverified_fork_base`
|
|
171
|
+
refusal **shifts to merge-time**, before merge-back — it shifts, it never lifts.
|
|
118
172
|
|
|
119
173
|
**Lifecycle — open → consume → digest → delete.** Open the ledger when the first worker
|
|
120
174
|
spawns. The serial integration Verify consumes it (the merge order is read from it, one
|
|
@@ -181,7 +235,7 @@ STOP-and-escalate (return your findings; do not decide):
|
|
|
181
235
|
• a discovered scope/contract gap → backward-correction, reopen Specify (principle 4)
|
|
182
236
|
• any SECURITY finding → HARD-STOP, always
|
|
183
237
|
• a concurrency/timing OR architecture/layering risk the tests cannot exercise
|
|
184
|
-
• [include this bullet
|
|
238
|
+
• [include this bullet when autonomy is conservative OR manual — any lowered rung] the verify gate itself — STOP for the human
|
|
185
239
|
Auto-PASS only if autonomy=auto AND: all tests green · coverage not decreased · no test weakened ·
|
|
186
240
|
no contract edited · loops dry · completeness-critic clean · no residue above. Log it as
|
|
187
241
|
auto-resolved, naming this run as owner — never forge a human signature.
|
|
@@ -204,7 +258,9 @@ ripgrep otherwise. Design every IO path for failure — timeouts, retries, rollb
|
|
|
204
258
|
</tools>
|
|
205
259
|
|
|
206
260
|
<return> <!-- the worker PROPOSES; the orchestrator RECORDS. A worker never runs add.py. -->
|
|
207
|
-
End with a structured verdict AND write the same into SUMMARY.md in the task dir
|
|
261
|
+
End with a structured verdict AND write the same into SUMMARY.md in the task dir, then
|
|
262
|
+
**commit SUMMARY.md + deltas.md** in the worktree (uncommitted worktree files survive only by
|
|
263
|
+
harness courtesy — commit them so the serial-integration merge-back carries your report):
|
|
208
264
|
{ task, outcome: PASS|RISK-ACCEPTED|HARD-STOP|ESCALATE, evidence: <tests+coverage>,
|
|
209
265
|
residue: [security|concurrency|architecture findings], deltas: [open lessons learned] }.
|
|
210
266
|
Do NOT touch add.py or any shared file — the orchestrator gates on your verdict.
|
|
@@ -222,7 +278,7 @@ The contract is identical whichever model runs it (the model is disposable, like
|
|
|
222
278
|
| **top** | complex / ambiguous / cross-cutting / broad scope of impact | `opus` | the runner's strongest reasoning model |
|
|
223
279
|
|
|
224
280
|
Two rules sit **above** model choice and never bend:
|
|
225
|
-
- **High-risk ⇒ `conservative`
|
|
281
|
+
- **High-risk ⇒ a lowered rung (`conservative` or `manual`), regardless of model** (`run.md` high-risk guard). A
|
|
226
282
|
stronger model does not buy back the human gate.
|
|
227
283
|
- **Security residue always escalates** — no tier and no model auto-passes it.
|
|
228
284
|
|