@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 +50 -0
- package/docs/03-step-1-specify.md +1 -1
- package/docs/04-step-2-scenarios.md +1 -1
- package/docs/08-step-6-verify.md +4 -2
- package/docs/09-the-loop.md +4 -0
- package/docs/11-governance.md +1 -1
- package/docs/16-releasing.md +1 -1
- package/docs/appendix-c-glossary.md +3 -1
- package/package.json +1 -1
- package/skill/add/SKILL.md +5 -1
- package/skill/add/advisor.md +8 -1
- package/skill/add/phases/5-build.md +1 -1
- package/skill/add/phases/6-verify.md +13 -14
- package/skill/add/phases/7-observe.md +11 -10
- package/skill/add/release.md +1 -1
- package/skill/add/run.md +20 -20
- package/skill/add/scope.md +1 -1
- package/skill/add/streams.md +7 -0
- package/tooling/add.py +435 -80
- package/tooling/add_engine/constants.py +1 -1
- package/tooling/add_engine/release.py +3 -3
- package/tooling/templates/TASK.fast.md.tmpl +2 -0
- package/tooling/templates/TASK.md.tmpl +15 -1
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:** `
|
|
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).
|
package/docs/08-step-6-verify.md
CHANGED
|
@@ -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
|
|
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:
|
package/docs/09-the-loop.md
CHANGED
|
@@ -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.
|
package/docs/11-governance.md
CHANGED
|
@@ -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
|
|
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
|
|
package/docs/16-releasing.md
CHANGED
|
@@ -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
|
-
- `
|
|
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) · `
|
|
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.
|
|
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"
|
package/skill/add/SKILL.md
CHANGED
|
@@ -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:
|
package/skill/add/advisor.md
CHANGED
|
@@ -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
|
-
|
|
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
|
|
7
|
-
>
|
|
8
|
-
>
|
|
9
|
-
>
|
|
10
|
-
>
|
|
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
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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** —
|
|
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
|
|
10
|
-
|
|
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
|
-
|
|
13
|
-
4. **Propose a voice delta** —
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
only
|
|
17
|
-
|
|
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
|
|
package/skill/add/release.md
CHANGED
|
@@ -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
|
-
- `
|
|
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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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: …`)
|
|
26
|
-
assumption
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
142
|
-
|
|
143
|
-
|
|
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>
|
package/skill/add/scope.md
CHANGED
|
@@ -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
|
|
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
|
|
package/skill/add/streams.md
CHANGED
|
@@ -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 ·
|