@pilotspace/add 1.12.0 → 1.13.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 CHANGED
@@ -6,6 +6,56 @@ All notable changes to the ADD method (`@pilotspace/add` on npm,
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.13.0] — 2026-06-28
10
+
11
+ Two method milestones make ADD's loop more **self-auditing** and more **honest**:
12
+ the observe step now harvests a decision record automatically, and every flow gate
13
+ is either mechanically enforced or plainly disclosed where it is not. Plus the npm
14
+ release pipeline moves to tokenless **Trusted Publishing**. Backward-compatible
15
+ throughout; nothing retro-changes an existing task or milestone record.
16
+
17
+ ### Added (adr-at-observe — a decision record, harvested not hand-written)
18
+ - **`### Decisions (ADR)` harvested at the gate.** On `add.py gate PASS`, the engine
19
+ harvests a §7 Architecture-Decision-Record block from §1/§3/§5/§6 — one
20
+ actor-tagged line per decision (`[AI] specify · [human] freeze · [AI] build ·
21
+ [human] verify`), refilled only while the placeholder stands (never hand-edited).
22
+ - **`add.py audit` checks the ADR at done.** A done task whose §7 ADR block is unfilled
23
+ is surfaced — presence-only, never a semantic judgment of the decisions themselves.
24
+ - **Strategy write-back.** The §6 GATE RECORD is stamped with the git actor + date, and
25
+ the §5 "Strategy actually used" line is harvested into the ADR as the `[AI] build` row.
26
+
27
+ ### Added (flow-honesty — every gate engine-true or honestly disclosed)
28
+ - **Two structural holes became real, forceable gates.** A **universal freeze gate**
29
+ (`contract_not_frozen` fires for every task at tests→build, with a recorded
30
+ `--skip-freeze` escape) and a **delta-drain release floor**
31
+ (`release_build_in_flight`, `--force`-able but loud) — the two places the method
32
+ promised enforcement and now delivers it.
33
+ - **Four honor-system edges became plain disclosures + measure-not-block lints.**
34
+ `add.py audit` now surfaces `shallow_deep_check`, `risk_unset`, and
35
+ `refute_unrecorded` (presence-only, never blocking); the guides + book state plainly
36
+ that a *missed* security finding is invisible to the engine (a human spot-audit is
37
+ the only backstop under `auto`); reject-code names read honestly
38
+ (`release_tests_red`→`release_build_in_flight`).
39
+ - **The earned-green refute-read is now a recorded verdict.** Under `auto`, the §6
40
+ `### Refute-read verdict` block records `EARNED | NOT-EARNED`; the engine measures it
41
+ is filled but never spawns the read — the resolver still does the judging.
42
+ - **Stale guidance synced to the shipped engine.** The 5-build "scope gate deferred"
43
+ note is gone (the scope gate enforces today); the auto-PASS precondition list is now
44
+ identical across `run.md`, `6-verify.md`, and the book.
45
+
46
+ ### Added (loose tasks)
47
+ - **`/add --todo` flag** (`skill-todo-flag`) — capture/list/close backlog todos.
48
+ - **§5 Strategy fed into spawns** (`build-strategy-solutions` · `streams-strategy-pull`)
49
+ — the planned build order + known-problem fixes flow into subagent prompts.
50
+ - **`<strategy>` softened** (`strategy-soft-not-hard`) — §5 is the *preferred* plan; the
51
+ builder may self-improve during build and reports the strategy actually used for audit.
52
+
53
+ ### Changed (release infrastructure)
54
+ - **npm Trusted Publishing (OIDC).** `publish.yml` drops the stored npm token (no more
55
+ ~90-day rotation), publishes via OIDC (`id-token: write`, Node 24 + npm ≥ 11.5.1),
56
+ and generates provenance automatically (`--provenance` no longer needed). A guard test
57
+ locks the tokenless shape. PyPI already used OIDC.
58
+
9
59
  ## [1.12.0] — 2026-06-26
10
60
 
11
61
  Multi-milestone polish release — the intake/roadmap front grows a real **queue**,
@@ -3,7 +3,7 @@
3
3
  [← 02 The flow](./02-the-flow.md) · [Contents](./README.md) · Next: [04 Step 2 Scenarios →](./04-step-2-scenarios.md)
4
4
 
5
5
  > **Purpose:** state, in plain language, what the feature must do and what it must reject, with no ambiguity left for the AI to resolve by guessing.
6
- > **Produces:** `SPEC.md` for the feature.
6
+ > **Produces:** the **§1 SPECIFY** block of the task's `TASK.md` (one file per task — what this chapter is the *why* behind; historically a separate `SPEC.md`).
7
7
  > **How it works — co-specification:** AI and human **brainstorm the shape together**; the AI drafts; the **human validates, with the AI's advice.** The decisive advice is a *lowest-confidence flag* — the AI names the one or two things most likely to be wrong, so the human's attention lands where it matters. The human owns the decision; the AI owns surfacing what it does not yet know.
8
8
 
9
9
  ---
@@ -3,7 +3,7 @@
3
3
  [← 03 Step 1 Specify](./03-step-1-specify.md) · [Contents](./README.md) · Next: [05 Step 3 Contract →](./05-step-3-contract.md)
4
4
 
5
5
  > **Purpose:** rewrite each rule from the spec as a concrete, pass-or-fail scenario.
6
- > **Produces:** `features/<name>.feature`.
6
+ > **Produces:** the **§2 SCENARIOS** block of the task's `TASK.md` (one file per task — what this chapter is the *why* behind; historically a separate `features/<name>.feature`).
7
7
  > **Person's job:** decide what "correct" looks like in concrete situations. **AI's job:** draft the scenarios.
8
8
 
9
9
  > **Part of the specification bundle (v7).** In the default flow these scenarios are drafted by the AI alongside the spec, contract, and failing tests as **one bundle**, approved by a person **once** (the one approval), at the contract freeze — not signed off step by step. This chapter is how to get the scenarios *right*; [05 Contract](./05-step-3-contract.md) is where the bundle is frozen. See [11 Governance](./11-governance.md).
@@ -18,7 +18,7 @@ This needs care, because it is easy to misread. "Not by inspection" does not mea
18
18
 
19
19
  Verify can be resolved two ways, set per task by the `autonomy:` header (see [governance](./11-governance.md) and the autonomy level):
20
20
 
21
- - **Auto (the default).** When `autonomy: auto`, the run resolves the gate on **evidence** rather than waiting for a person — but only when *all* of these hold: every test green, coverage not decreased, no test weakened and no contract edited, the convergence loops dry, and **no residue** (security, concurrency, or architecture). It records `PASS` as *auto-resolved*, naming the run as the accountable owner — an explicit pass, not a skip. This is principle 7: a gate may be resolved by evidence when that evidence is sufficient and the result is logged.
21
+ - **Auto (the default).** When `autonomy: auto`, the run resolves the gate on **evidence** rather than waiting for a person — but only when *all* of these hold — the **same canonical list run.md owns**: every test green, coverage not decreased, no test weakened and no contract edited, the convergence loops dry, the completeness-critic clean, the deep check filled, the earned-green refute-read verdict recorded (the §6 `### Refute-read verdict` field, under auto), and **no residue** (security, concurrency, or architecture). It records `PASS` as *auto-resolved*, naming the run as the accountable owner — an explicit pass, not a skip. This is principle 7: a gate may be resolved by evidence when that evidence is sufficient and the result is logged.
22
22
  - **Human.** When `autonomy: conservative`, or whenever the run finds residue it cannot judge, the gate stops for a person; the two parts below are theirs.
23
23
 
24
24
  **Security is always a `HARD-STOP` and is never auto-passed, at any autonomy level.** The two parts that follow — confirm the evidence, then check the non-functional risks — are what *either* resolver works through; the only question is whether a person or the recorded run signs the outcome.
@@ -40,7 +40,7 @@ Automated tests are excellent at behavior on defined inputs and poor at a few sp
40
40
 
41
41
  - **Concurrency and timing.** Is the operation correct when two of them happen at once? Tests usually run serially and miss races.
42
42
  - ▶ *Example: the balance update must be one atomic transaction. Confirm that two simultaneous transfers from the same account cannot both pass the balance check and overdraw it.* This is the single most important check for this feature, and it is the reason the build prompt named atomicity explicitly.
43
- - **Security.** Are there exposed secrets, injection openings, or unexpected dependencies? AI-generated code is known to hardcode secrets and to pull in packages by plausible-but-wrong names.
43
+ - **Security.** Are there exposed secrets, injection openings, or unexpected dependencies? AI-generated code is known to hardcode secrets and to pull in packages by plausible-but-wrong names. A security finding is always a `HARD-STOP`, never a waiver — and it escalates only if it is *written down*: `add.py audit`'s `unescalated_security_note` check fires on a **marked** note that slipped through as an auto-gate PASS, but a finding you **never marked** is invisible to the engine, escalated to no one. That is the honest limit of the auto-gate: under `auto`, a human **spot-audit** (reading the diff) is the only backstop for a *missed* security finding — the same backstop named for an unrecorded earned-green refute-read.
44
44
  - **Architecture conformance.** Does the change respect the layering and dependency rules in `CONVENTIONS.md`? Speed with no architectural check produces a fast-growing tangle that becomes unmaintainable within months.
45
45
 
46
46
  ## Part three — the deep check (do not skim)
@@ -59,6 +59,8 @@ Passing tests say the code satisfies the cases you wrote down. They do not say i
59
59
 
60
60
  A green suite proves the tests pass — not that the build EARNED them. Three judgment cheats pass the unchanged suite without earning it: src overfit to the test fixtures (special-cased to the literal inputs, not the general behavior §1 asked for), vacuous asserts (tautological — green even against an empty implementation), and real logic stubbed away (the function returns a constant the tests happen to accept). These cheats are invisible to the mechanical tamper tripwire, which only sees edited files. Score them with an adversarial refute-read: an independent reviewer — a subagent under `autonomy: auto` is recommended, the engine never spawns one — prompted to argue the green was NOT earned from outside the build context. This is the verify-gate, whole-suite specialization of run.md's adversarial verify (see run.md), not a new discipline. A confirmed earned-green failure is HARD-STOP-class: never auto-passed, never RISK-ACCEPTED — but a first cheat is a chance to redo: a confirmed cheat (mechanical tamper or a reported earned-green failure) enters the bounded self-heal loop — it returns to build for an honest redo, and only after the loop's cap does it HARD-STOP to the human (the loop lives in run.md).
61
61
 
62
+ Under `autonomy: auto` there is no human at the gate to confirm the refute-read happened, so the verdict is **recorded** — a `### Refute-read verdict` field in §6 (`Verdict: EARNED | NOT-EARNED`, plus who read it and what they adversarially probed). This closes an honesty gap the auto-gate would otherwise leave open: the method *says* an auto-PASS rests on an earned-green check, but nothing made that check visible. Now `add.py audit` surfaces a verify-or-later task whose verdict block is still a placeholder as `refute_unrecorded` — a **measure, not a gate**: it never blocks the run (a hard gate on this universal completion path would break far too much to justify it, and the engine cannot read whether a self-graded `EARNED` is *true* anyway — only whether it was written). The honest backstop is the same one named for a missed security finding: a human **spot-audit** reading the diff. A `NOT-EARNED` verdict is not a dead end — it routes through `add.py heal` for an honest redo, never an auto-PASS. The discipline this records is simple: under auto, you are the accountable owner of the gate, so you leave the trace of the check you owe.
63
+
62
64
  ## Recording the outcome
63
65
 
64
66
  Every verification ends with exactly one recorded outcome, with an accountable owner — never a silent pass:
@@ -33,6 +33,10 @@ Every defect, surprise, or new need is written up as a change to the specificati
33
33
 
34
34
  This is also where the AI returns to a useful role: summarizing telemetry, clustering errors into themes, and drafting the proposed spec delta for a person to review. But the production decisions — what to roll back, what to prioritize — remain human.
35
35
 
36
+ ## The decision record (ADR)
37
+
38
+ Observe is also where the loop's **decisions** become durable. At the gate the engine harvests §7's **Decisions (ADR)** block from the stamps the task already carries — the §1 framing it chose (and the alternatives it rejected), the §3 contract a person froze, the §5 strategy it actually used, and the §6 gate outcome — tagging each line `[human]` or `[AI]`. It is *harvested, not authored*: the engine writes no decision of its own, only what the task already recorded, so the trail can never drift from what actually happened. The result is one consolidated, auditable record of who decided what — and `add.py audit` flags a done task whose block never harvested (`adr_record_missing`), so the record cannot silently go missing.
39
+
36
40
  ## Lessons learned and the retrospective consolidation
37
41
 
38
42
  A spec delta feeds the *next feature*. But a loop also teaches the **method itself** — that the domain model missed a boundary, that a whole class of scenario was never tested, that a build convention helped or hurt. AIDD captures those as **lessons learned**: a single tagged learning, written in the Observe step, marking which of the five competencies it sharpens.
@@ -23,7 +23,7 @@ The **per-scope default is auto-with-evidence behind a one-approval decision poi
23
23
 
24
24
  The engine expresses this per task as an explicit three-rung level — `autonomy: manual | conservative | auto`, an ordered ladder `manual < conservative < auto` declared in the `TASK.md` header and reviewed at the freeze. `auto` is auto-with-evidence behind the one approval (the seeded default); `conservative` is the deliberate lowering that keeps a person at the verify gate; `manual` is the strict floor where the human owns the gate and nothing auto-resolves. A high-risk or method-defining scope refuses an unguarded `auto` (`unguarded_high_risk_auto`) — it must be lowered to `conservative` or `manual`. The prose here and that engine token are one rule: prose ≡ enforcement.
25
25
 
26
- **Autonomy is earned by goal-clarity — the auto-ready goal.** The autonomy level decides *who* resolves Verify; an **auto-ready goal** decides whether a self-verifying run is even *meaningful*. A milestone goal is *auto-ready* when **every exit criterion cites a verifier** — `(verify: <test | command | metric>)` — so the engine can check the result against the goal without human judgment. `add.py check` raises a `goal_not_auto_ready` WARN (never red, the active milestone only) while the goal has criteria not all cited, and `status` surfaces a `goal-ready:` line every session, so the goal-clarity gap stays visible. The WARN *measures*, it never blocks: it changes neither the freeze gate nor the autonomy level — clarifying the goal is the prerequisite that *earns* trust, not a new gate (a zero-criteria goal reads not-auto-ready and is milestone-shaping's nudge, not this one's). The lint raises the floor — a citation slot per criterion — but cannot prove the citation is honest: a human can still write `(verify: it works)`, and closing that is a person's judgment, not the engine's.
26
+ **Autonomy is earned by goal-clarity — the auto-ready goal.** The autonomy level decides *who* resolves Verify; an **auto-ready goal** decides whether a self-verifying run is even *meaningful*. A milestone goal is *auto-ready* when **every exit criterion cites a verifier** — `(verify: <test | command | metric>)` — so the engine can check the result against the goal without human judgment. `add.py check` raises a `goal_not_auto_ready` WARN (never red, the active milestone only) while the goal has criteria not all cited, and `status` surfaces a `goal-ready:` line every session, so the goal-clarity gap stays visible. The WARN *measures citation presence*, it never blocks: it changes neither the freeze gate nor the autonomy level — clarifying the goal is the prerequisite for a meaningful self-verifying run, not a new gate (a zero-criteria goal reads not-auto-ready and is milestone-shaping's nudge, not this one's). The lint raises the floor — a citation slot per criterion — but cannot prove the citation is honest: a human can still write `(verify: it works)`, and closing that is a person's judgment, not the engine's.
27
27
 
28
28
  ## The gate-fail protocol and the three reports
29
29
 
@@ -86,7 +86,7 @@ refusing with a non-zero exit and leaving every file byte-unchanged on any of fo
86
86
 
87
87
  - `release_security_open` — an open security `HARD-STOP` exists. This is the non-negotiable one: a
88
88
  security finding is never shipped. Resolve it first, as a change request back to Specify.
89
- - `release_tests_red` — the suite is not green. A release ships on evidence, not on a plausible diff.
89
+ - `release_build_in_flight` — a build is in flight: a task sits in build/verify with no recorded green gate. A release ships on evidence, not on a plausible diff.
90
90
  - `release_no_closed_milestone` — nothing new since the last release. The cut would be a no-op; do not
91
91
  bump a version to mark time.
92
92
  - `release_undisclosed_waiver` — a `RISK-ACCEPTED` waiver rides into the release but is missing from the
@@ -46,6 +46,8 @@
46
46
 
47
47
  **Onboarding** (formerly "on-ramp") — the path a new user walks from install to their first milestone: install → `/add` → describe the goal → the agent runs intake (sizing the request into a milestone the human confirms) → the specification bundle → the self-driving run. The AI-first entry to the method; the human talks to the agent rather than hand-typing `add.py`.
48
48
 
49
+ **Decisions (ADR)** — the engine-harvested record in a task's §7 OBSERVE: one actor-tagged line per key decision, gathered at the gate from the stamps already in the task — §1 framing `[AI]` (the choice + the rejected alternatives), §3 freeze `[human]`, §5 strategy-actually-used `[AI]`, §6 gate `[human|AI]`. *Harvested, never authored* — the engine invents no decision content, only mirrors what the task recorded — and scoped to the §7 OBSERVE placeholder alone. The durable who-decided-what trail that separates human direction from AI building; `add.py audit` flags a done task whose block never harvested (`adr_record_missing`).
50
+
49
51
  **Decision point** (formerly "seam") — a place where the flow stops for human judgment: the contract-freeze approval (the one approval), an escalated verify gate, intake confirmation, milestone close. The machine layer keeps the legacy name: the `--json` owner enum `seam`, the decide-digest key `seam`, and the `seam-audit` CI job.
50
52
 
51
53
  **The decision arc** — the three engine-sourced lines a gate report opens with at every **decision point**: `goal:` the milestone goal the work serves · `done:` the achievement, the proven progress toward it (the gate reports render this line as `done`) · `plan:` what comes next. What `done` reports adapts per gate (verify: tests + evidence · milestone close: exit-criteria met · intake: the request sized) while the three-part shape stays constant. Rendered first, above the report's summary, so the human confirms with sight of the whole trajectory, not a local snapshot. Engine-sourced like all evidence — goal · done · plan are pulled from `add.py` output, never re-typed. Presentation only: it never adds a gate or changes a `PASS` / `RISK-ACCEPTED` / `HARD-STOP` / freeze outcome. The report it opens is the chat report a person reads at a decision point — distinct from the three Test/Quality/Risk reports a verify gate produces ([11 Governance](./11-governance.md)). See the `add` skill's `report-template.md`.
@@ -100,7 +102,7 @@
100
102
 
101
103
  **Release steps** — the AI-defined, per-milestone ordered hints to ship a closed milestone, of which `merge` is one small step (a pull request, an exported hand-off document, a tag or a publish are others). Defined at close and **fed** into the release scope (see **Release**), never a second flow.
102
104
 
103
- **Readiness floor** — the engine-enforced pre-cut gate `add.py release` applies before it records anything: a green suite, zero open security `HARD-STOP`, a closed-and-unreleased milestone to bundle, and every riding `RISK-ACCEPTED` waiver disclosed in the notes. Its four rejects are `release_security_open` (un-forceable) · `release_tests_red` · `release_no_closed_milestone` · `release_undisclosed_waiver`; `--force` may override every reject except the security stop.
105
+ **Readiness floor** — the engine-enforced pre-cut gate `add.py release` applies before it records anything: a green suite, zero open security `HARD-STOP`, a closed-and-unreleased milestone to bundle, and every riding `RISK-ACCEPTED` waiver disclosed in the notes. Its four rejects are `release_security_open` (un-forceable) · `release_build_in_flight` · `release_no_closed_milestone` · `release_undisclosed_waiver`; `--force` may override every reject except the security stop.
104
106
 
105
107
  **RELEASES.md ledger** — the append-only, newest-first trail of release rows at the project root (date · version · milestones · waivers shipped · evidence). Like the §Key Decisions log it is never rewritten; a superseded or yanked version is recorded as a new row. The ledger is the attribution source — a milestone is "released" because a row says so — which is why the `→ releasable` cue never has to read a milestone file.
106
108
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pilotspace/add",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "ADD (AI-Driven Development). One skill. Eight steps. Five disciplines. Every feature ships through the loop — a minimal, state-tracked Claude Code skill that ships the AIDD book as its trust layer.",
5
5
  "bin": {
6
6
  "add": "bin/cli.js"
@@ -15,7 +15,7 @@ user-invocable: true
15
15
  when_to_use: "Invoke in any repo with a `.add/` directory, or when the user wants spec/tests-first feature work, resumes ADD work, or asks to start/advance a task."
16
16
  category: workflows
17
17
  keywords: [add, aidd, ai-driven-development, spec-first, tdd, contract, scenarios, verify, milestone, task-orchestration]
18
- argument-hint: "status | init | continue | [describe new short goals or expectation]"
18
+ argument-hint: "status | init | continue | --todo <text> | [describe new short goals or expectation]"
19
19
  license: MIT
20
20
  metadata:
21
21
  author: add
@@ -32,6 +32,10 @@ result through passing evidence rather than a plausible-looking diff.
32
32
  preamble plus seven step sections, filled top to bottom. The Python tool tracks where you
33
33
  are so context never rots across sessions.
34
34
 
35
+ **The `--todo` fast-path.** When the skill ARGUMENTS begin with `--todo`, skip orienting: route to
36
+ `add.py todo` and print its output — `--todo <text>` captures · `--todo` lists open todos ·
37
+ `--todo --done <id>` closes (engine errors surfaced verbatim) — then STOP.
38
+
35
39
  ## Always start here (orient — do not skip)
36
40
 
37
41
  Engine: `.add/tooling/add.py` · book: `.add/docs/`. Ensure the engine is in the project first:
@@ -24,7 +24,7 @@ independent enough to earn it. When in doubt, do it in-context.
24
24
 
25
25
  Give the subagent the *piece of your plan it owns* and a fixed return shape. This reuses
26
26
  `streams.md`'s worker-contract tags for a single advisory subagent — the contract is identical
27
- on any runner; only the spawn adapter (see `streams.md`) changes.
27
+ on any runner; only the spawn adapter (see `streams.md`) changes. The `<strategy>` block mirrors the task's §5 (Strategy + Known-problem fixes) as the subagent's PREFERRED path — it self-improves on that plan and reports the strategy it actually used.
28
28
 
29
29
  ```xml
30
30
  <objective>
@@ -40,6 +40,13 @@ Work step by step, following the plan:
40
40
  3. Self-score your result with confidence.md; if any dimension < 0.9, refine before returning.
41
41
  </persona>
42
42
 
43
+ <strategy>
44
+ The task's §5 plan — the Strategy (ordered batches) order and the Known-problem fixes — is
45
+ your PREFERRED starting path, not a hard rule. Improve on it when a better strategy emerges
46
+ as you build; on done, report the strategy you ACTUALLY used so the orchestrator can update
47
+ §5 for the audit trail.
48
+ </strategy>
49
+
43
50
  <context_files>
44
51
  the plan / task files the piece needs (read-only unless the piece says otherwise)
45
52
  </context_files>
@@ -16,7 +16,7 @@ tests, iterate to green. Keep each batch small enough to review in full.
16
16
  - **Scope (may touch)** — the allowlist of every file the build may write (backticked tokens). Needing a file outside the declared Scope is a **STOP → change request** back to Specify, never improvisation.
17
17
  - **Strategy (ordered batches)** — the planned build order. Guidance, not enforced.
18
18
 
19
- Deferral, named: the engine gate (touched declared) lands in the `scope-gate-enforce` task until it ships this section is prose discipline.
19
+ Enforced: a completing verify gate refuses an out-of-scope build (`scope_violation` self-heal); `add.py check` surfaces it.
20
20
 
21
21
  ## The cardinal rule
22
22
 
@@ -3,16 +3,15 @@
3
3
  Goal: establish trust and record an outcome. Passing tests are necessary, not
4
4
  sufficient. Fill **§6** in TASK.md including the GATE RECORD.
5
5
 
6
- > **Who resolves this gate depends on the `autonomy:` header (see `run.md`).**
7
- > Under `autonomy: auto` (the default) a run auto-PASSes once evidence is complete
8
- > every test green, convergence loops dry, and **no residue** (security · concurrency · architecture) —
9
- > recorded as *auto-resolved* with the named run as accountable owner. **Security is
10
- > always a HARD-STOP and is never auto-passed.** Under `autonomy: conservative`, or
11
- > whenever residue is found, this phase is **human-led**.
6
+ > **Who resolves this gate depends on the `autonomy:` header.** Under `autonomy: auto` (the default)
7
+ > a run auto-PASSes on complete evidence with **no residue** (security · concurrency · architecture),
8
+ > recorded *auto-resolved* with the named run as owner;
9
+ > **security is always a HARD-STOP and is never auto-passed**. Under `conservative`, or whenever
10
+ > residue is found, this phase is **human-led** (auto-PASS conditions: `run.md`).
12
11
 
13
12
  ## Before you build — declare the build expectations
14
13
 
15
- Fill the §6 **Build expectations** block BEFORE Build: OBSERVABLE outcomes derived from §2 SCENARIOS + §3 CONTRACT. At this gate, confirm each against real evidence (the `confirmed by` column). An expectation with no evidence is not yet verified.
14
+ Fill the §6 **Build expectations** block BEFORE Build: OBSERVABLE outcomes derived from §2 + §3. At this gate, confirm each against real evidence (the `confirmed by` column) one with no evidence is not yet verified.
16
15
 
17
16
  ## Part one — confirm the evidence
18
17
 
@@ -26,22 +25,22 @@ If any is false, stop and return to Build.
26
25
  ## Part two — check what tests miss
27
26
 
28
27
  - **Concurrency/timing** — correct when two run at once? (Tests run serially and miss races.)
29
- - **Security** — exposed secrets, injection openings, unexpected dependencies. A security finding is always `HARD-STOP`, never a waiver. ANY note here escalates to the human — start it with `NOTE` or `⚠` so `add.py audit` can see it (`unescalated_security_note`).
28
+ - **Security** — exposed secrets, injection openings, unexpected dependencies. A security finding is always `HARD-STOP`, never a waiver. ANY note here escalates to the human — start it with `NOTE` or `⚠` so `add.py audit` can see it (`unescalated_security_note`). **But that check sees only what you wrote down:** it fires on a *marked* note that slipped through as an auto-gate PASS — a finding you never marked is **invisible** to the engine, escalated to no one. Honest disclosure, not false cover: under `auto`, a human **spot-audit** (reading the diff) is the only backstop for a *missed* security finding.
30
29
  - **Architecture** — respects layering/dependency rules in CONVENTIONS.md?
31
30
 
32
31
  ## Part three — the deep check (do not skim)
33
32
 
34
- Deep check — do not skim. If the task produced code, record that every new symbol is referenced (wiring) and that no new dead/unused code was introduced. If it produced prose or non-code, record a semantic read — what you read in full and what it confirmed. Which path applies is the resolver's judgement; the engine never classifies.
33
+ If the task produced code, record that every new symbol is referenced (wiring) and that no new dead/unused code was introduced. If it produced prose or non-code, record a semantic read — what you read in full and what it confirmed. The resolver judges which path; the engine never classifies.
35
34
 
36
- Record it in the §6 **Deep checks** block. An unfilled Deep checks block is a **shallow verify**, not a PASS.
35
+ Record it in the §6 **Deep checks** block an unfilled one is a **shallow verify**, not a PASS.
37
36
 
38
37
  ## Part four — was the green earned?
39
38
 
40
- A green suite proves tests pass — not that the build EARNED them. Three judgment cheats pass the unchanged suite: src overfit to the test fixtures (special-cased to literal inputs), vacuous asserts (tautological — green against an empty implementation), and real logic stubbed away. These are invisible to the mechanical tamper tripwire. Score them with an adversarial refute-read: an independent reviewer — the engine never spawns one — prompted to argue the green was NOT earned. A confirmed earned-green failure is HARD-STOP-class: never auto-passed, never RISK-ACCEPTED — a first cheat enters the bounded self-heal loop (run.md).
39
+ A green suite proves tests pass — not that the build EARNED them. Three judgment cheats pass the unchanged suite: src overfit to the test fixtures (special-cased to literal inputs), vacuous asserts (green against an empty implementation), and real logic stubbed away all invisible to the mechanical tamper tripwire. Score them with an adversarial refute-read: an independent reviewer — the engine never spawns one — prompted to argue the green was NOT earned. A confirmed earned-green failure is HARD-STOP-class: never auto-passed, never RISK-ACCEPTED — a first cheat enters the bounded self-heal loop (run.md). Under `auto`, **record the verdict** in §6's `### Refute-read verdict` block — `add.py audit` flags an unrecorded `refute_unrecorded`, one of three measure-not-block shape lints it surfaces (also `shallow_deep_check` + `risk_unset`).
41
40
 
42
41
  ## Record exactly one outcome (no silent pass)
43
42
 
44
- When you present this gate, open with the ARC per `report-template.md`, render the DECISION as a guided choice, and reconcile FLAGS with `add.py report --decide`'s open-item count before the ask.
43
+ Present this gate via `report-template.md`'s ARC, render DECISION as a guided choice, and reconcile FLAGS with `add.py report --decide`'s open-item count first.
45
44
 
46
45
  | Outcome | When |
47
46
  |---------|------|
@@ -53,10 +52,10 @@ When you present this gate, open with the ARC per `report-template.md`, render t
53
52
 
54
53
  <exit_gate>
55
54
  - [ ] Evidence confirmed, non-functional risks checked, outcome recorded — a person approved, or
56
- (under `autonomy: auto` with no residue) the run auto-resolved as the accountable owner.
55
+ (under `autonomy: auto`, no residue) the run auto-resolved as accountable owner.
57
56
  </exit_gate>
58
57
 
59
- > **Advisor · Confidence** — the earned-green refute-read is the canonical adversarial spawn (advisor.md); score the verdict before you record the gate (confidence.md).
58
+ > **Advisor · Confidence** — the earned-green refute-read is the canonical adversarial spawn (advisor.md); score it before recording the gate (confidence.md).
60
59
 
61
60
  ```bash
62
61
  python3 .add/tooling/add.py gate PASS # marks the task done
@@ -1,20 +1,21 @@
1
1
  # Phase 7 — Observe (feed the next loop)
2
2
 
3
- Goal: release deliberately, watch reality, and turn what you learn into the next spec. Fill **§7** in TASK.md.
3
+ Goal: release deliberately, watch reality, turn what you learn into the next spec. Fill **§7** in TASK.md.
4
4
 
5
5
  ## Do
6
6
 
7
- 1. **Release behind a scope-of-impact limit** — feature flag and/or gradual rollout.
7
+ 1. **Release behind a scope-of-impact limit** — a flag and/or gradual rollout.
8
8
  2. **Reuse scenarios as monitors** — the §2 scenarios that defined "correct" now
9
- define what you alert on: overall error rate, each rejection's rate (a spike in
10
- one is a signal), latency of the risky operation under load.
9
+ define what you alert on: overall error rate, each rejection's rate (a spike is a
10
+ signal), latency of the risky op under load.
11
11
  3. **Draft the next spec delta** — every defect, surprise, or new need becomes a
12
- concrete change that re-enters the flow at Specify (a new task).
13
- 4. **Propose a voice delta** — you just worked a whole task alongside the human, so
14
- notice where your voice diverged from theirs (their wordings + flow) and propose a
15
- confirmable **voice delta** that tunes `SOUL.md`. Emit it `open`; the human confirms;
16
- only then do you rewrite the routed SOUL.md section. Read `soul.md` for the grammar,
17
- the routing, and the human-is-only-writer rule.
12
+ change that re-enters the flow at Specify (a new task).
13
+ 4. **Propose a voice delta** — note where your voice diverged from the human's (wordings +
14
+ flow); propose a confirmable **voice delta** tuning `SOUL.md`, emitted `open`. The human
15
+ confirms, then you rewrite the routed section. Read `soul.md` (grammar, routing,
16
+ human-is-only-writer).
17
+
18
+ > **Decisions (ADR)** — at the gate the engine harvests §7's ADR block (§1/§3/§5/§6); `add.py audit` flags one never harvested.
18
19
 
19
20
  ## AI prompt
20
21
 
@@ -35,7 +35,7 @@ One arc, seven steps: **cue → gather → draft notes → readiness floor → h
35
35
 
36
36
  <reject_codes>
37
37
  - `release_security_open` — open security HARD-STOP exists. Never shipped. `--force` does NOT override this.
38
- - `release_tests_red` — suite not green.
38
+ - `release_build_in_flight` — a build is in flight, ungated.
39
39
  - `release_no_closed_milestone` — nothing new since last release.
40
40
  - `release_undisclosed_waiver` — a RISK-ACCEPTED waiver rides into the release but is absent from the notes.
41
41
  </reject_codes>
package/skill/add/run.md CHANGED
@@ -1,11 +1,9 @@
1
1
  # The dynamic run — executing a locked scope
2
2
 
3
- Once a task's CONTRACT is frozen (phase 3), the scope is *locked*. That lock is ADD's autonomy
4
- decision point — below it code is disposable; above it nothing breaks. This rubric covers the
5
- **build->verify half, executed as a dynamic, self-improving run**. The human-led **specification
6
- bundle** (Specify · Scenarios · Contract) still owns *direction*, but v7 compresses it to a
7
- **single human approval at the decision point** — the AI drafts the whole bundle, a human approves
8
- it once. The engine stays judgment-free: this is a rubric, not `add.py`.
3
+ Once a task's CONTRACT is frozen (phase 3), the scope is *locked* ADD's autonomy decision point:
4
+ below it code is disposable; above it nothing breaks. This rubric covers the **build->verify half,
5
+ executed as a dynamic, self-improving run**. The human-led **specification bundle** (Specify ·
6
+ Scenarios · Contract) still owns *direction*. The engine stays judgment-free: this is a rubric, not `add.py`.
9
7
 
10
8
  ## The specification bundle (v7)
11
9
 
@@ -14,19 +12,18 @@ bundle in one pass** — Spec, Scenarios, Contract, and failing Tests — and pr
14
12
  The human gives **one approval, at the frozen contract** (the decision point).
15
13
 
16
14
  Why one and not zero: the decision point **stays human**. The AI *drafts* the contract but never
17
- *freezes its own* — a person approves the frozen shape before any auto-run touches code. What the
18
- human approves: that the Spec captures real intent, the Scenarios cover the cases that matter, and
19
- the Contract shape is the one to freeze. Reject any part and the bundle goes back to draft
20
- backward-correction (principle 4), not failure. The decision-point guide (`phases/3-contract.md`) carries the **freeze review checklist** —
21
- seven lines that walk the human through exactly this, ⚠-first.
15
+ *freezes its own* — a person approves the frozen shape before any auto-run touches code: that the
16
+ Spec captures real intent, the Scenarios cover the cases that matter, and the Contract shape is the
17
+ one to freeze. Reject any part back to draft (backward-correction, principle 4, not failure). The
18
+ decision-point guide (`phases/3-contract.md`) carries the **freeze review checklist** — seven lines,
19
+ ⚠-first.
22
20
 
23
21
  **The lowest-confidence flag.** The AI presents the bundle **lowest-confidence first**: the
24
22
  **1–2 points most likely to be wrong**, tagged by part
25
- (`⚠ [spec|scenario|contract|test] … — because …; if wrong: …`). The `because` names the §1
26
- assumption that makes it uncertain; the `if wrong` names what it costs if that assumption is off.
27
- If nothing is materially uncertain, the AI still names the single biggest risk — never a blank "none".
28
- Raising this flag is honor-system: the lint cannot force the AI to engage with it — closing that
29
- gap is a CI checker's job, not prose.
23
+ (`⚠ [spec|scenario|contract|test] … — because …; if wrong: …`) `because` names the §1
24
+ assumption behind the doubt, `if wrong` its cost. If nothing is materially uncertain, the AI still
25
+ names the single biggest risk — never a blank "none". This flag is honor-system: the lint cannot
26
+ force engagement closing that gap is a CI checker's job, not prose.
30
27
 
31
28
  ## When the run begins — the scope-lock trigger
32
29
 
@@ -71,6 +68,7 @@ recorded pass is an explicit pass, not a skip).
71
68
  - **Auto-PASS requires ALL of:** every test green; coverage not decreased; no test weakened and no
72
69
  contract edited; loops dry; completeness-critic clean; and the deep check below.
73
70
  - **The deep check (every gate, do not skim).** If the task produced code, record that every new symbol is referenced (wiring) and that no new dead/unused code was introduced. If it produced prose or non-code, record a semantic read. An unfilled deep check is a **shallow verify**, not an auto-PASS.
71
+ - **The recorded refute-read (under `auto`).** The earned-green refute-read (`6-verify.md`) is not just run — its **verdict is recorded** in §6 (`EARNED | NOT-EARNED`); `add.py audit` surfaces an unrecorded one as `refute_unrecorded` — one of three shape lints it lists (with `shallow_deep_check` + `risk_unset`) — and a human spot-audit is the backstop. NOT-EARNED routes to `add.py heal`, never an auto-PASS.
74
72
  - **Always escalates to a human (never auto-passed):** any **security** finding (HARD-STOP, always);
75
73
  a **concurrency**/timing risk the tests cannot exercise; an **architecture**/layering violation;
76
74
  any failing test.
@@ -118,7 +116,9 @@ autonomy: manual | conservative | auto
118
116
  ```
119
117
 
120
118
  - **auto (the default)** — the run may auto-PASS when evidence + residue checks are satisfied.
121
- Security still always escalates.
119
+ Security still always escalates — but only a finding the AI *surfaces*: a security issue the
120
+ reviewer misses is **invisible** to the engine, so under `auto` a human **spot-audit** is the
121
+ only backstop for a missed finding.
122
122
  - **conservative** — the deliberate *lowering*: the run converges but STOPS at the verify gate.
123
123
  - **manual** — the strict floor: the human owns the verify gate; the engine never auto-resolves.
124
124
 
@@ -138,7 +138,7 @@ in its header is not blocked by the v14 mechanical guard.
138
138
 
139
139
  **Autonomy is earned by goal-clarity — the auto-ready goal.** A milestone goal is auto-ready
140
140
  when **every exit criterion cites a verifier** — `(verify: <test | command | metric>)`.
141
- `add.py check` raises a `goal_not_auto_ready` WARN while criteria are uncited, and `status`
142
- prints a `goal-ready:` line every session. It **measures, never blocks**. The lint cannot prove
143
- the citation is honest — `(verify: it works)` passes the check — that judgment stays the human's.
141
+ `add.py check` raises `goal_not_auto_ready` while criteria are uncited; `status` prints a
142
+ `goal-ready:` line. It **measures, never blocks** the lint cannot prove the citation honest
143
+ (`(verify: it works)` passes); that judgment stays the human's.
144
144
  </constraints>
@@ -11,7 +11,7 @@
11
11
  | `change-request` | route to SPECIFY/CONTRACT of the affected task | 0 milestones |
12
12
  | `split_required` | draft ALL N items as a batch in ONE pass | N milestones/tasks |
13
13
 
14
- **Confirm before create is the invariant.** "One pass" means one drafting pass, NOT auto-creation — nothing is written until the human confirms.
14
+ **Confirm before create is the convention.** "One pass" means one drafting pass, NOT auto-creation — nothing is written until the human confirms; enforced only by the opt-in `--await-confirm` (below).
15
15
 
16
16
  **Confirm the milestone before detailing tasks.** `new-milestone <slug> --await-confirm` seeds it *unconfirmed* — `new-task` is HELD (`milestone_unconfirmed`) until you show the filled `MILESTONE.md`, get the human's go, and run `milestone-confirm <slug>`. Keeps you from digging into task §0–§5 before the parent is agreed. (Omit the flag: no gate.)
17
17
 
@@ -179,6 +179,13 @@ Score confidence (0-1) on Completeness · Clarity · Practicality · Optimizatio
179
179
  Self-Eval; if any < 0.9, refine before returning.
180
180
  </persona>
181
181
 
182
+ <strategy>
183
+ The task's §5 plan — the Strategy (ordered batches) order and the Known-problem fixes — is
184
+ your PREFERRED starting path, not a hard rule. Improve on it when a better strategy emerges
185
+ as you build; on done, report the strategy you ACTUALLY used so the orchestrator can update
186
+ §5 for the audit trail.
187
+ </strategy>
188
+
182
189
  <touch_boundary> <!-- from run.md; the worker's contract, identical on every runner -->
183
190
  MAY: rewrite code in src/ · drive tests green WITHOUT weakening them · gather verify evidence.
184
191
  MUST NOT: edit the frozen CONTRACT or locked scope · weaken/delete/skip any test ·