@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/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,128 @@ All notable changes to the ADD method (`@pilotspace/add` on npm,
|
|
|
4
4
|
`pilotspace-add` on PyPI) are documented here. The format follows
|
|
5
5
|
[Keep a Changelog](https://keepachangelog.com/); versions follow semver.
|
|
6
6
|
|
|
7
|
+
## [1.4.0] — 2026-06-15
|
|
8
|
+
|
|
9
|
+
The guided-onboarding release: starting and running an ADD project is now guided
|
|
10
|
+
and self-tuning. Setup interviews you into a run mode and a first milestone and
|
|
11
|
+
deepens each drive, the engine schedules parallel work into dependency waves,
|
|
12
|
+
stale installs nudge any agent to update, and the AI carries a human-owned voice
|
|
13
|
+
that improves itself. All additive; no breaking changes (SemVer MINOR).
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Guided, self-tuning setup** — `0-setup` now interviews instead of assuming:
|
|
17
|
+
it proposes a **run mode** (a parallel+auto vs. sequential comparison table,
|
|
18
|
+
confirm-to-keep the recommended default), sketches a **first milestone** as a
|
|
19
|
+
kickoff suggestion (goal + flow + scenarios, shown before it asks), and runs a
|
|
20
|
+
per-drive **domain deep-dive** (DDD · SDD · UDD · TDD) that captures the
|
|
21
|
+
decisions as ADRs. Onboarding stops being a blank page.
|
|
22
|
+
- **`add.py waves` DAG scheduler** — a new read-only command that groups the
|
|
23
|
+
active milestone's open tasks into topological **waves** (a wave is the tasks
|
|
24
|
+
whose in-milestone dependencies have all landed), names the **critical path**,
|
|
25
|
+
emits an advisory **tier hint** (a scope-of-impact proxy for model selection,
|
|
26
|
+
never a gate), and surfaces a transitively-**blocked** set with what each task
|
|
27
|
+
is waiting on. It never mutates state and `streams.md` gains a "DAG strategy"
|
|
28
|
+
section that points at it.
|
|
29
|
+
- **`SOUL.md` — a human-owned, self-improving voice** — `init` now scaffolds a
|
|
30
|
+
`.add/SOUL.md` voice doc (schema: Name · Tone · Communication style · Trust ·
|
|
31
|
+
Learns-from · Voice deltas) with a *proposed* "Trusting" starter voice that is
|
|
32
|
+
explicitly yours to rewrite — the tests assert the schema, never the tone words.
|
|
33
|
+
`status` points at it to read each session, and a new `soul.md` guide drives an
|
|
34
|
+
observe→confirm→rewrite **voice-delta loop** (the human is the only writer),
|
|
35
|
+
the voice-side sibling of the competency-delta→foundation loop.
|
|
36
|
+
- **Agent-agnostic update nudge** — because every agent is told to run
|
|
37
|
+
`add.py status`/`guide` first each session, the engine uses that one universal
|
|
38
|
+
chokepoint to flag a stale install: on those orientation reads only, when a
|
|
39
|
+
launcher `.add-version` stamp is present and the registry's latest is newer, it
|
|
40
|
+
writes one `ACTION REQUIRED` line to **stderr** naming the channel-correct
|
|
41
|
+
command (`npx @pilotspace/add@latest update` / `pipx run pilotspace-add
|
|
42
|
+
update`). It is the engine's one deliberate, tightly-bounded network touch:
|
|
43
|
+
fail-open (offline/timeout → silent no-op), throttled once per 24 h via a
|
|
44
|
+
git-ignored `.update-cache.json`, inert without a launcher stamp, and silenced
|
|
45
|
+
by `ADD_NO_UPDATE_CHECK=1`. stdout and exit codes are never touched, so `--json`
|
|
46
|
+
stays clean. (Originated as community PR #17.)
|
|
47
|
+
- **First-class `add.py autonomy show|set`** — autonomy was the only mutable
|
|
48
|
+
first-class state with no CLI verb, so an agent driving under `autonomy: auto`
|
|
49
|
+
could hallucinate the missing `add.py autonomy` command, hit `invalid choice`,
|
|
50
|
+
and derail an autonomous run. `autonomy show` prints declared · effective
|
|
51
|
+
(fallback-resolved) · project default · the verify-gate owner; `autonomy set
|
|
52
|
+
<level> [slug] [--project] [--yes]` is the first writer of the `autonomy:`
|
|
53
|
+
header token — an idempotent, atomic single-line rewrite (trailing comment
|
|
54
|
+
preserved, never appended) with three fail-closed guards run before any write:
|
|
55
|
+
an invalid level, raising the rung without `--yes` (raising is a human-owned
|
|
56
|
+
trust escalation), and raising a `risk: high` task to `auto`. The command-shaped
|
|
57
|
+
header-edit wording is de-shaped to cite the verb, and an `[enforced]`
|
|
58
|
+
`WORDING_RUBRIC` fence keeps the phantom phrasing from regressing.
|
|
59
|
+
- **Foundation compaction across all four specs** — the living foundation now
|
|
60
|
+
stays relevant-first and short as a project grows. Every append-only sequence
|
|
61
|
+
(`PROJECT.md` §Spec · §Key-Decisions · `CONVENTIONS.md` learnings) reads
|
|
62
|
+
**newest-first**, and at milestone close the AI proposes collapsing each spec's
|
|
63
|
+
shipped, zero-open-residue tail into one per-spec **rolled-up settled line** —
|
|
64
|
+
the human confirms one line at a time; it summarizes and points to git, never
|
|
65
|
+
deletes, and every open residue stays expanded. A new `compact-foundation.md`
|
|
66
|
+
skill guide drives the ritual — convention-guided, with no new engine command,
|
|
67
|
+
and distinct from `add.py compact` (which archives finished-milestone files).
|
|
68
|
+
The loop chapter and glossary document it.
|
|
69
|
+
- **Per-step Advisor + Confidence context** — every ADD step now carries a thin
|
|
70
|
+
pointer to two new shared skill guides: `advisor.md` (when and how to delegate
|
|
71
|
+
one plan-following subagent — vendor-neutral; the engine never spawns) and
|
|
72
|
+
`confidence.md` (an advisory 0–1 self-score across six dimensions, refine if any
|
|
73
|
+
dimension scores below 0.9). Both are advisory by construction — the self-score
|
|
74
|
+
is never a gate — making delegate-and-self-assess first-class guidance for any
|
|
75
|
+
agent driving the loop.
|
|
76
|
+
- **`.add/.gitignore` scaffolded at init** — `init` now writes a co-located
|
|
77
|
+
`.add/.gitignore` so the engine's transient local artifacts (scope snapshots,
|
|
78
|
+
pre-archive backups, the update-nudge cache) never reach git. It is additive and
|
|
79
|
+
never clobbers an existing copy; edit it freely.
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
- **Conversational-only install hand-off** — after `init`, the closing hint points
|
|
83
|
+
only at the conversational entry point: open your AI agent CLI, run `/add`, and
|
|
84
|
+
say what you want to build. The hand-off is tool-agnostic (Claude Code, Codex,
|
|
85
|
+
…) and no longer advertises a manual `add.py new-task` / `--await-lock` escape
|
|
86
|
+
as the primary path (the flag still exists; `/add` runs it internally).
|
|
87
|
+
|
|
88
|
+
## [1.3.0] — 2026-06-13
|
|
89
|
+
|
|
90
|
+
The render-ready-foundation release: a UI project now gets a lintable design
|
|
91
|
+
foundation the AI drafts from, a build's declared scope is enforced as a gate,
|
|
92
|
+
every command names who drives the next step, and the new update command
|
|
93
|
+
refreshes an installed project in place. All additive; no breaking changes
|
|
94
|
+
(SemVer MINOR).
|
|
95
|
+
|
|
96
|
+
### Added
|
|
97
|
+
- **Render-ready UDD foundation** — a `DESIGN.md` prose front-door plus a JSON
|
|
98
|
+
foundation (3-layer design tokens · a component catalog · flat prototype
|
|
99
|
+
content trees) the AI drafts UI from, wired into 0-setup. `add.py check` now
|
|
100
|
+
lints the named set under `.add/design/`, going red with a named code on any
|
|
101
|
+
layer, catalog, tree, or cross-file token-resolution violation — and staying
|
|
102
|
+
silent when a project has no design set, so non-UI projects are unaffected.
|
|
103
|
+
A `udd-tokens.md` + `udd-catalog.md` pair documents the compact-DTCG dialect
|
|
104
|
+
and the json-render render recipe.
|
|
105
|
+
- **The scope gate** — a task's `§5 Scope (may touch)` declaration is frozen
|
|
106
|
+
into a snapshot at tests→build and enforced at the gate: an out-of-scope touch
|
|
107
|
+
heals the task back to BUILD for an honest redo (counting against a per-task
|
|
108
|
+
cap), while erased gate evidence fails closed. Scope creep can no longer ride a
|
|
109
|
+
green suite into a merge.
|
|
110
|
+
- **Engine next-step footer + the driver marker** — every completing command now
|
|
111
|
+
prints exactly one engine-sourced `next:` line, and names who owns it:
|
|
112
|
+
`[you drive]` when the AI proceeds, `[human gate]` at a decision point. The
|
|
113
|
+
driver marker resolves from one place (autonomy × phase), so the next step and
|
|
114
|
+
its owner are never ambiguous across a session.
|
|
115
|
+
- **The `update` command** — `npx @pilotspace/add update` (and the
|
|
116
|
+
`pilotspace-add update` command on PyPI) re-materializes the managed layer
|
|
117
|
+
(skill · tooling · docs) to the installed package version without a re-install.
|
|
118
|
+
It never touches your work — `state.json`, `PROJECT.md`, milestones, tasks, and
|
|
119
|
+
archive are preserved (state is backed up first regardless) — is idempotent via
|
|
120
|
+
a `.add-version` stamp, and offers `--check` to report version drift without
|
|
121
|
+
writing.
|
|
122
|
+
|
|
123
|
+
### Changed
|
|
124
|
+
- The foundation self-improved across these milestones: closing
|
|
125
|
+
`udd-design-foundation` folded its OBSERVE backlog into the versioned
|
|
126
|
+
CONVENTIONS/PROJECT foundation (foundation-version 29), sharpening the
|
|
127
|
+
contract-completeness, adversarial-refute, and engine-pin conventions.
|
|
128
|
+
|
|
7
129
|
## [1.2.0] — 2026-06-10
|
|
8
130
|
|
|
9
131
|
The decision-arc release: the method now narrates the build as one continuous
|
package/GETTING-STARTED.md
CHANGED
|
@@ -63,6 +63,28 @@ handoff — from here on it's conversation, not terminal commands.
|
|
|
63
63
|
> Why stages exist: the steps never change, only how *deeply* you run them.
|
|
64
64
|
> See `.add/docs/10-setup-and-stages.md`.
|
|
65
65
|
|
|
66
|
+
### Updating to a newer ADD — no re-install
|
|
67
|
+
|
|
68
|
+
When a new ADD version ships, refresh a project in two steps: bump the package
|
|
69
|
+
(your package manager), then re-materialize it into the project with `update`:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# npm — one shot (npx fetches latest, then re-materializes into this project):
|
|
73
|
+
npx @pilotspace/add@latest update
|
|
74
|
+
|
|
75
|
+
# pip — one shot via pipx (the npx analog: fetch latest + run):
|
|
76
|
+
pipx run pilotspace-add update
|
|
77
|
+
|
|
78
|
+
# …or plain pip, in two steps:
|
|
79
|
+
pip install -U pilotspace-add && pilotspace-add update
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`update` clean-replaces the managed layer (`skill` · `.add/tooling` · `.add/docs`)
|
|
83
|
+
and **never touches your work** — `state.json`, `PROJECT.md`, milestones, tasks and
|
|
84
|
+
archive are left exactly as they were (it backs `state.json` up first regardless). It
|
|
85
|
+
is idempotent (same version twice is a no-op) and writes a `.add/.add-version` stamp.
|
|
86
|
+
Run `… update --check` to see whether a project is behind the installed package.
|
|
87
|
+
|
|
66
88
|
---
|
|
67
89
|
|
|
68
90
|
## 2 · Your first feature — talk to the agent
|
|
@@ -321,6 +343,10 @@ You just ran the method; now read *why* it's shaped this way:
|
|
|
321
343
|
- Each step in depth — `.add/docs/03-step-1-specify.md` through `.add/docs/09-the-loop.md`
|
|
322
344
|
- Operating it on a team — `.add/docs/11-governance.md`, `.add/docs/12-roles.md`
|
|
323
345
|
- A fully worked example — `.add/docs/appendix-d-worked-example.md`
|
|
346
|
+
- Building UI? The render-ready UDD foundation — `.add/DESIGN.md` is the prose
|
|
347
|
+
front-door to a lintable design system (`.add/design/` tokens · catalog ·
|
|
348
|
+
prototypes) the AI drafts from; `add.py check` lints it (delete `DESIGN.md` if
|
|
349
|
+
your project has no UI)
|
|
324
350
|
|
|
325
351
|
The rule to remember: **build the right thing (direction), prove it's right
|
|
326
352
|
(verification), and let the AI do the building in between.**
|
package/README.md
CHANGED
|
@@ -46,6 +46,12 @@ pilotspace-add init
|
|
|
46
46
|
No flags needed — the project name is inferred from your folder and the stage
|
|
47
47
|
defaults to `prototype` (pass `--name "My App" --stage mvp` to choose up front).
|
|
48
48
|
|
|
49
|
+
**Already installed?** Refresh to the latest without a re-install —
|
|
50
|
+
`npx @pilotspace/add@latest update` (or `pipx run pilotspace-add update`)
|
|
51
|
+
re-materializes the skill, tooling, and book while leaving your project work
|
|
52
|
+
(`.add/state.json`, `PROJECT.md`, milestones, tasks) untouched; add `--check` to
|
|
53
|
+
see whether a project is behind the installed package.
|
|
54
|
+
|
|
49
55
|
**New here?** Follow the [10-minute Quickstart](./GETTING-STARTED.md) — it walks
|
|
50
56
|
your first feature end to end.
|
|
51
57
|
|
|
@@ -56,11 +62,18 @@ This installs:
|
|
|
56
62
|
| `.claude/skills/add/` | the `add` skill Claude loads (thin router + per-phase guides) |
|
|
57
63
|
| `.add/tooling/add.py` | scaffolder + state tracker (Python, stdlib only) |
|
|
58
64
|
| `.add/docs/` | the AIDD book — the method rationale |
|
|
65
|
+
| `.add/DESIGN.md` | (UI projects) the prose front-door to the **render-ready UDD foundation** — delete it if your project has no UI |
|
|
66
|
+
|
|
67
|
+
On a UI project, UDD gives the AI a frozen design ground to draft from: `DESIGN.md`
|
|
68
|
+
plus a lintable JSON foundation under `.add/design/` (design tokens · component
|
|
69
|
+
catalog · prototype trees). `add.py check` lints that foundation, going red with a
|
|
70
|
+
named code on any layer, catalog, tree, or cross-file violation — and staying
|
|
71
|
+
silent when a project has no design set.
|
|
59
72
|
|
|
60
73
|
Project state (`.add/state.json`) and the living-documentation files (`CONVENTIONS.md`,
|
|
61
|
-
`GLOSSARY.md`, `MODEL_REGISTRY.md`, `dependencies.allowlist`
|
|
62
|
-
here — the installer drops files only;
|
|
63
|
-
when you run `/add`.
|
|
74
|
+
`GLOSSARY.md`, `MODEL_REGISTRY.md`, `dependencies.allowlist`, `SOUL.md` — the AI's
|
|
75
|
+
human-owned voice) are *not* created here — the installer drops files only;
|
|
76
|
+
initialisation is the agent's first move when you run `/add`.
|
|
64
77
|
|
|
65
78
|
## Use it
|
|
66
79
|
|
package/bin/cli.js
CHANGED
|
@@ -32,10 +32,11 @@ function parseArgs(argv) {
|
|
|
32
32
|
// stage/name stay null unless EXPLICITLY passed — the engine's own `init`
|
|
33
33
|
// defaults the stage and infers the name from the folder, so the manual-init
|
|
34
34
|
// hint only echoes flags the user actually chose (shortest true command).
|
|
35
|
-
const args = { _: [], force: false, stage: null, name: null };
|
|
35
|
+
const args = { _: [], force: false, check: false, stage: null, name: null };
|
|
36
36
|
for (let i = 0; i < argv.length; i++) {
|
|
37
37
|
const a = argv[i];
|
|
38
38
|
if (a === "--force") args.force = true;
|
|
39
|
+
else if (a === "--check") args.check = true;
|
|
39
40
|
else if (a === "--stage" || a === "--name") {
|
|
40
41
|
const v = argv[++i];
|
|
41
42
|
// fail loudly on a trailing/abutting flag — never silently drop a value
|
|
@@ -101,15 +102,86 @@ function cmdInit(args) {
|
|
|
101
102
|
// (via `/add`) or a CLI user — a pre-run plain `add.py init` would grandfather-lock
|
|
102
103
|
// the v12 lock-down gate before `/add` runs (see file header). So no Python is run here.
|
|
103
104
|
log("\nDone. The `add` skill + tooling are installed (no project state yet — that's intentional).");
|
|
104
|
-
log("Next: open Claude Code, run `/add`, and say what you want to build — the agent");
|
|
105
|
+
log("Next: open your AI Agent CLI (like Claude Code, Codex, etc.), then run `/add`, and say what you want to build — the agent");
|
|
105
106
|
log(" sets up the foundation, sizes it into a milestone, and drives the build with you;");
|
|
106
107
|
log(" you sign off once, at the lock-down.");
|
|
107
108
|
log("");
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// --- update: re-materialize the managed layer without a re-install -----------
|
|
112
|
+
// The managed trees (ship-controlled). `update` clean-replaces each, so a file removed
|
|
113
|
+
// upstream leaves no orphan — and never touches .add/state.json, PROJECT.md, milestones,
|
|
114
|
+
// tasks, or archive (user data). Pure file-copy (npm <-> pip parity with _installer.py).
|
|
115
|
+
const MANAGED = [
|
|
116
|
+
["skill/add", [".claude", "skills", "add"], false],
|
|
117
|
+
["tooling", [".add", "tooling"], true],
|
|
118
|
+
["docs", [".add", "docs"], false],
|
|
119
|
+
];
|
|
120
|
+
const STAMP_FILE = ".add-version";
|
|
121
|
+
|
|
122
|
+
function pkgVersion() {
|
|
123
|
+
try { return require(path.join(PKG_ROOT, "package.json")).version; }
|
|
124
|
+
catch (_e) { return "0.0.0"; }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function readStamp(addDir) {
|
|
128
|
+
const p = path.join(addDir, STAMP_FILE);
|
|
129
|
+
if (!fs.existsSync(p)) return null;
|
|
130
|
+
try { return JSON.parse(fs.readFileSync(p, "utf8")); } catch (_e) { return null; }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function writeStamp(addDir, version) {
|
|
134
|
+
fs.mkdirSync(addDir, { recursive: true });
|
|
135
|
+
fs.writeFileSync(
|
|
136
|
+
path.join(addDir, STAMP_FILE),
|
|
137
|
+
JSON.stringify({ version: version, channel: "npm", installed_at: new Date().toISOString() }, null, 2) + "\n"
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function cleanReplaceTree(src, dest, stripTests) {
|
|
142
|
+
if (!fs.existsSync(src)) fail("missing packaged source: " + src);
|
|
143
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
144
|
+
if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true, force: true });
|
|
145
|
+
fs.cpSync(src, dest, { recursive: true });
|
|
146
|
+
if (stripTests) {
|
|
147
|
+
fs.rmSync(path.join(dest, "__pycache__"), { recursive: true, force: true });
|
|
148
|
+
for (const entry of fs.readdirSync(dest)) {
|
|
149
|
+
if (/^test_.*\.py$/.test(entry)) fs.rmSync(path.join(dest, entry), { force: true });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function cmdUpdate(args) {
|
|
155
|
+
const target = path.resolve(args._[0] || ".");
|
|
156
|
+
const addDir = path.join(target, ".add");
|
|
157
|
+
if (!fs.existsSync(path.join(addDir, "tooling")) && !fs.existsSync(path.join(addDir, "state.json"))) {
|
|
158
|
+
fail("no ADD project at " + target + " (.add/ not found) — run `init` first");
|
|
159
|
+
}
|
|
160
|
+
const version = pkgVersion();
|
|
161
|
+
const stamp = readStamp(addDir);
|
|
162
|
+
const cur = stamp && stamp.version ? stamp.version : null;
|
|
163
|
+
|
|
164
|
+
if (args.check) {
|
|
165
|
+
if (cur === version) log("ADD is current: project and package both at " + version + ".");
|
|
166
|
+
else if (cur === null) log("ADD project is unstamped; installed package is " + version + ". Run `update`.");
|
|
167
|
+
else log("ADD update available: project on " + cur + ", package is " + version + ". Run `update`.");
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (cur === version && !args.force) {
|
|
171
|
+
log("ADD already at " + version + " — nothing to update (use --force to re-materialize).");
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
// design-for-failure: back up state BEFORE touching anything.
|
|
175
|
+
const stateFile = path.join(addDir, "state.json");
|
|
176
|
+
if (fs.existsSync(stateFile)) {
|
|
177
|
+
fs.copyFileSync(stateFile, path.join(addDir, "pre-update-state.bak.json"));
|
|
178
|
+
}
|
|
179
|
+
for (const [sub, destParts, stripTests] of MANAGED) {
|
|
180
|
+
cleanReplaceTree(path.join(PKG_ROOT, sub), path.join(target, ...destParts), stripTests);
|
|
181
|
+
}
|
|
182
|
+
writeStamp(addDir, version);
|
|
183
|
+
log("ADD updated " + (cur || "(unstamped)") + " -> " + version +
|
|
184
|
+
" · skill · tooling · docs refreshed · your project state untouched.");
|
|
113
185
|
}
|
|
114
186
|
|
|
115
187
|
function main() {
|
|
@@ -120,9 +192,14 @@ function main() {
|
|
|
120
192
|
case "init":
|
|
121
193
|
cmdInit(args);
|
|
122
194
|
break;
|
|
195
|
+
case "update":
|
|
196
|
+
cmdUpdate(args);
|
|
197
|
+
break;
|
|
123
198
|
case "help":
|
|
124
199
|
case "--help":
|
|
125
|
-
log("usage: npx @pilotspace/add init [targetDir] [--force] [--
|
|
200
|
+
log("usage: npx @pilotspace/add <init|update> [targetDir] [--force] [--check]");
|
|
201
|
+
log(" init install the ADD skill + tooling + book into a project");
|
|
202
|
+
log(" update re-materialize skill/tooling/docs to this package version (preserves your state)");
|
|
126
203
|
break;
|
|
127
204
|
default:
|
|
128
205
|
fail("unknown command '" + cmd + "'. Try: npx @pilotspace/add init");
|
package/docs/02-the-flow.md
CHANGED
|
@@ -8,10 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
AIDD is one repeatable flow of **seven steps**: six build the feature — Specify → Scenarios → Contract → Tests → Build → Verify — and the seventh, **Observe**, feeds what production teaches back into the next Specify. In the default flow the AI drafts the specification bundle (steps 1–4) and a person approves it **once**, at the contract freeze; the AI performs the Build; and Verify is resolved on evidence under `autonomy: auto`, with a person owning any residue. (See [11 Governance](./11-governance.md) for the autonomy level and the one-approval decision point.)
|
|
10
10
|
|
|
11
|
+
**Before those seven steps comes a phase-0 preamble: `ground`.** Before it specifies anything, the AI gathers the real current codebase the task touches — the actual files, symbols, signatures, patterns, and conventions — into a lean §0 *grounding map*, surfacing the **anchors** the frozen contract will later cite. Ground is AI-owned and adds no new approval (the one approval stays at the contract freeze); it aims the specification bundle at reality instead of assumption, so the contract, tests, and build are grounded in the code as it actually is. The seven steps keep their numbering and brand — ground precedes them as step 0 (it is drawn as node 0 in the diagram below).
|
|
12
|
+
|
|
11
13
|

|
|
12
14
|
|
|
13
15
|
```mermaid
|
|
14
16
|
flowchart LR
|
|
17
|
+
S0["0 Ground<br/>the real codebase"] --> S1["1 Specify<br/>the rules"]
|
|
15
18
|
S1["1 Specify<br/>the rules"] --> S2["2 Scenarios<br/>pass/fail cases"]
|
|
16
19
|
S2 --> S3["3 Contract<br/>freeze the shape"]
|
|
17
20
|
S3 --> S4["4 Tests<br/>failing-first (red)"]
|
|
@@ -27,7 +30,7 @@ flowchart LR
|
|
|
27
30
|
classDef machine fill:#E6F1FB,stroke:#185FA5,color:#042C53;
|
|
28
31
|
class S1,S2 human;
|
|
29
32
|
class S3,S4 decision;
|
|
30
|
-
class S5,S6 machine;
|
|
33
|
+
class S0,S5,S6 machine;
|
|
31
34
|
```
|
|
32
35
|
|
|
33
36
|
> **Solid arrows are the primary flow** — you never start a phase before its input exists (forward-skip forbidden). **Dashed arrows are backward correction** — any phase may return to an earlier one to repair its artifact (the long loop, Observe → Specify, is the same rule at milestone scale). The tight Tests ⇄ Build cycle is the per-feature red/green engine.
|
|
@@ -88,6 +88,8 @@ The defining instruction: *if a requirement is unclear, ask — do not resolve i
|
|
|
88
88
|
- **Free-text errors.** Errors must be named codes, not sentences, so they can become scenarios and contract responses.
|
|
89
89
|
- **Hidden assumptions.** If an assumption is not written down, it is not confirmed — it is a future bug with a delay timer.
|
|
90
90
|
- **A flat list of "confirmed" assumptions.** Eight equal-looking ticks invite a reflex approval. Rank them; flag the one or two that are load-bearing. An unranked list hides the risk inside the noise.
|
|
91
|
+
- **"Existing behavior" claims without a citation.** An assumption row that asserts "this is how X works today" is describing intent, not code. Any wiring claim or assumption that depends on the current state of an existing path must carry a grep/line citation (e.g. `file.rs:203`) — otherwise it is a future bug in disguise.
|
|
92
|
+
- **Wiring claims that name a symbol, not a caller chain.** Verifying that a function exists is not the same as verifying it is reachable. A wiring claim is only valid when it names the production caller chain from an actual entry point — not just the symbol's location in a file. A function that nothing calls is dead, not wired.
|
|
91
93
|
|
|
92
94
|
## Exit check
|
|
93
95
|
|
package/docs/06-step-4-tests.md
CHANGED
|
@@ -60,6 +60,11 @@ The AI generates the test suite from the scenarios and contract. Your job is to
|
|
|
60
60
|
- **A green suite before the build.** Means the tests are not actually exercising the missing feature — fix them now.
|
|
61
61
|
- **Skipping the side-effect assertions.** Without `assert a.balance == 20` on the rejection path, a corrupting partial failure passes silently.
|
|
62
62
|
- **No coverage target.** Without a recorded target, coverage can quietly erode during the build.
|
|
63
|
+
- **`should_panic` as a red test.** Marking a test `#[should_panic(expected = "implement in green wave")]` (or the equivalent in any language) passes immediately and stays green while red — it is a lying red. Declare unimplemented paths with `todo!()` (or `unimplemented!()`) so the test actually fails. If a test is intentionally designed to flip from red to green during the build, say so with a comment: `// flip authorized at green wave`.
|
|
64
|
+
- **Collateral tests named by category, not by exact name.** When a spec adds a slash command, a new CLI subcommand, or any other globally-enumerated thing, there is a fixed collateral set of tests that count or enumerate it (e.g. a command-registry count test, a help-text snapshot, an autocomplete positional assert). Pre-list these tests by their **exact test names** in §4 — not categories — so the build agent's edits to those "pre-existing" tests are expected and the count is right. Naming only the category means the agent finds the wrong test or misses one.
|
|
65
|
+
- **Arithmetic not checked against frozen constants.** Before freezing, check that the red suite can reach green: a fixture with N bytes fails a hard-coded M-byte budget if N > M — the suite can never pass. Run the numbers before freeze, and add an additive override (e.g. `set_budget`) when the scenario implies a limit the production constant cannot satisfy in test.
|
|
66
|
+
- **Non-hermetic tests that read real user state.** Tests that call a loader with `None` (defaulting to `~/.helios/settings.json` or the real home dir) become torn-read flakes under a parallel suite and assert nothing useful. Red tests that create or read production paths must redirect them to a temp dir; grep new tests for `home_dir`, `~/.config`, real-path defaults before freeze.
|
|
67
|
+
- **Tests that share a per-machine singleton without isolation.** Background services (embedded servers, filesystem watchers) bind to fixed ports or paths. Tests that start such a service must tear it down, or they collide with a parallel run or an already-running dev instance. If the singleton cannot be isolated, gate those tests as serial (one thread, no parallel execution) and document it.
|
|
63
68
|
|
|
64
69
|
## Exit check
|
|
65
70
|
|
|
@@ -67,6 +72,9 @@ The AI generates the test suite from the scenarios and contract. Your job is to
|
|
|
67
72
|
- [ ] The suite runs in the pipeline and is **red for the right reason**.
|
|
68
73
|
- [ ] Tests assert observable behavior, not internals.
|
|
69
74
|
- [ ] A coverage target is recorded.
|
|
75
|
+
- [ ] No `should_panic` lying reds — unimplemented paths use `todo!()` or equivalent so they actually fail.
|
|
76
|
+
- [ ] Collateral tests for globally-enumerated things (command counts, help snapshots) are listed by exact name.
|
|
77
|
+
- [ ] Arithmetic checked: the red fixtures can reach green against the frozen constants.
|
|
70
78
|
|
|
71
79
|
## If the check fails
|
|
72
80
|
|
package/docs/07-step-5-build.md
CHANGED
|
@@ -78,3 +78,5 @@ The autonomy granted in this step should match the evidence and your review capa
|
|
|
78
78
|
## If the check fails
|
|
79
79
|
|
|
80
80
|
If the AI weakened a test, reject and re-prompt. If it added an out-of-allow-list package, the pipeline blocks it; have the AI find an approved alternative or raise the package for human approval. If the batch is too large to review, ask the AI to split the work and resubmit. Only once the exit check passes does the change proceed to verification.
|
|
81
|
+
|
|
82
|
+
And in the other direction: if the *verify* gate later finds a confirmed cheat — a tamper, or a build that gamed the green (overfit to the fixtures, vacuous asserts, stubbed-away logic) — the task returns *here* for an honest redo. That return is the **bounded self-heal loop** (see the run chapter): revert the tampered file or de-overfit the code, then advance again. It is capped — after the cap a confirmed cheat HARD-STOPs to the human rather than looping forever, and a gamed green is never auto-passed.
|
package/docs/08-step-6-verify.md
CHANGED
|
@@ -48,6 +48,14 @@ Two failures slip straight past green tests. The first is code that is never *wi
|
|
|
48
48
|
|
|
49
49
|
This is *evidence*, not impression: a reference search showing where each new symbol is called, a scan confirming nothing new is orphaned, or — for prose — a note of exactly what was read and what it confirmed. An unfilled deep check is a **shallow verify**, not a pass. The engine cannot judge wiring, dead code, or whether prose was truly read; the resolver records the evidence, and a person (under `conservative`) or the recorded run (under `auto`) signs it.
|
|
50
50
|
|
|
51
|
+
**The wiring trace is a named step, not a free-form note.** For every new hook, closure, or middleware registered in this task: trace from the process entry point to the call site and record it explicitly — symbol, file, line. A symbol that is only reachable via a test helper or `make_config` but not via the production entry point (e.g. `build_harness_with_dispatcher`, `interactive_mode`) is not wired. This is the third repeated class in production: "runtime-activation-order/silent-noop" — the code exists and the unit tests pass, but the feature is absent in the running program. The wiring trace is how you catch it before a user does.
|
|
52
|
+
|
|
53
|
+
## Part four — was the green earned?
|
|
54
|
+
|
|
55
|
+
Passing tests say the code satisfies the cases you wrote down. They do not say it earned that pass honestly — and the mechanical tamper tripwire (Step 6's floor) only catches an *edited* test or contract, not a build that gamed the *unchanged* suite. The same rubric the phase guide carries names what the tripwire cannot see:
|
|
56
|
+
|
|
57
|
+
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).
|
|
58
|
+
|
|
51
59
|
## Recording the outcome
|
|
52
60
|
|
|
53
61
|
Every verification ends with exactly one recorded outcome, with an accountable owner — never a silent pass:
|
|
@@ -75,6 +83,9 @@ A security finding is always a `HARD-STOP`; it is never waved through with a wai
|
|
|
75
83
|
- **Shipping on plausibility.** Reading the diff, finding it reasonable, and approving — without the evidence and the non-functional review — is the precise failure the method exists to prevent.
|
|
76
84
|
- **Treating a security gap as acceptable risk.** It is a `HARD-STOP`, not a waiver.
|
|
77
85
|
- **Skipping the concurrency check** because the tests are green. Tests rarely exercise simultaneity; this is a manual check by design.
|
|
86
|
+
- **Trusting the green agent's self-reported test count.** A build agent running a filtered suite (e.g. `-E 'test(theme)'`) only sees tests inside the filter. Collateral failures outside the filter — a stale count in `all_commands_in_registry`, an e2e snapshot the agent did not touch — are invisible. The orchestrator's **full-suite rerun is load-bearing**; never skip it on the grounds that the scoped run was green.
|
|
87
|
+
- **User-observable-only failures escalate to the human before exhausting discriminating probes.** When a symptom is only observable by a person (a TCC dialog, a visual flicker, an OS-level prompt), do not respond by running the suite again. Instead, design two or three targeted probes that let the user distinguish cause A from cause B in one interaction each. Three AskUser probes resolve what three blind reruns cannot.
|
|
88
|
+
- **Background-process hangs misdiagnosed as test failures.** A test that never exits is not a failure in the test logic — it is a hang. The diagnosis recipe: background the test process, run `pgrep` to find it, use the platform profiler (`sample <pid>` on macOS, `perf` on Linux) to sample the stack, then `lsof -p <pid>` to see open files. Run an isolation experiment (suspect line on/off, 3×3) before reading any code. Entry-count caps do not bound wall time — a single huge directory or a blocking syscall inside a `spawn_blocking` call can hang indefinitely even when the entry cap is satisfied.
|
|
78
89
|
|
|
79
90
|
## If the check fails
|
|
80
91
|
|
package/docs/09-the-loop.md
CHANGED
|
@@ -47,10 +47,12 @@ A spec delta feeds the *next feature*. But a loop also teaches the **method itse
|
|
|
47
47
|
|
|
48
48
|
Each delta is one tagged entry — `- [COMPETENCY · status] the learning (evidence: a pointer)` — and the evidence is **required**: a failing scenario, a production signal, a review note. No evidence means it is an opinion, not a delta. The AI **emits** deltas as `open`; it never consolidates its own. Consolidation is judgment, and judgment is the human's — the same verify/observe decision point that keeps the AI from grading its own work.
|
|
49
49
|
|
|
50
|
-
**The consolidation.** At milestone close (or on demand, when open deltas pile up), a person runs the retrospective consolidation: **gather** every `open` delta across the milestone's tasks, **group** them by competency, **propose** the exact foundation edit for each, **confirm** with the human one by one, then **write** — append-only — flipping each delta to `folded` (merged) or `rejected` (considered and deliberately not merged, left in place so the trail survives), and bumping the `foundation-version:` marker. `DDD`/`SDD`/`UDD` deltas consolidate into the matching section of `PROJECT.md`; `TDD`/`ADD` consolidate into `CONVENTIONS.md` (they sharpen the engine, not the product); and **every** consolidation also
|
|
50
|
+
**The consolidation.** At milestone close (or on demand, when open deltas pile up), a person runs the retrospective consolidation: **gather** every `open` delta across the milestone's tasks, **group** them by competency, **propose** the exact foundation edit for each, **confirm** with the human one by one, then **write** — append-only, newest-first (the newest record prepended at the top) — flipping each delta to `folded` (merged) or `rejected` (considered and deliberately not merged, left in place so the trail survives), and bumping the `foundation-version:` marker. `DDD`/`SDD`/`UDD` deltas consolidate into the matching section of `PROJECT.md`; `TDD`/`ADD` consolidate into `CONVENTIONS.md` (they sharpen the engine, not the product); and **every** consolidation also prepends one row at the top of `PROJECT.md` §Key Decisions — the universal, auditable record of what the foundation learned.
|
|
51
51
|
|
|
52
52
|
**Tooling.** `add.py deltas` lists every open delta across the project (so nothing waiting to be consolidated is invisible); `add.py check` lints each delta's well-formedness — known competency tag, valid status, non-empty evidence. There is deliberately **no `add.py fold`**: the engine stays judgment-free, and the ritual lives with the human who owns it.
|
|
53
53
|
|
|
54
|
+
**Foundation compaction.** The consolidation *prepends* new learnings; **foundation compaction** is the separate, later step that *shrinks* the result. At milestone close (or on demand, once a foundation spec grows past one screen), the AI proposes collapsing the stable, shipped, zero-residue tail of each foundation spec into ONE per-spec **rolled-up settled line** at the bottom — and the human confirms, one line at a time, exactly as with the consolidation. It never deletes: a settled line summarizes the prose and keeps a `see git` pointer, so the record is lossy on wording but lossless on traceability, and any OPEN residue always stays live. Each spec collapses in its own **per-spec shape** — `PROJECT.md` §Spec version bullets, §Key-Decisions rows, `CONVENTIONS.md` learnings, the `GLOSSARY.md` definition, the `MODEL_REGISTRY.md` rows — under one shared eligibility rule. Because every append-only sequence is **newest-first** (newest record on top), compaction collapses *upward from the bottom*: the settled line anchors at the tail (the oldest end). Like the consolidation it is convention-guided — there is deliberately no `add.py` command for it (read `compact-foundation.md`) — and it is distinct from the engine's `add.py compact <slug>`, which archives a finished milestone's files rather than shrinking a living spec.
|
|
55
|
+
|
|
54
56
|
## Re-entrancy: the loop is the whole point
|
|
55
57
|
|
|
56
58
|
Two principles converge here. *The flow is re-entrant* — any step can send you back to an earlier one — and *the flow is a loop* — production feeds the next specification. Together they mean the artifacts you built are never "finished"; they are living documents that the next cycle refines.
|
|
@@ -109,7 +109,7 @@ The default is one task at a time. But when a milestone holds several tasks whos
|
|
|
109
109
|
- **READY-QUEUE** — tasks in the active milestone where the phase is not `done` and every dependency already reads `gate=PASS`. These are the only tasks a worker may pick up; a task finishing `PASS` unblocks its dependents on the next `status`.
|
|
110
110
|
- **REVIEW-QUEUE** — the irreducibly serial part: the **bundle approval** (contract freeze) and any **Verify escalation**. One human, one queue, presented one at a time — never a batch that invites approval without reading.
|
|
111
111
|
|
|
112
|
-
**The autonomy level is the throttle
|
|
112
|
+
**The autonomy level is the throttle** — an explicit, overridable per-task token on an ordered ladder `manual < conservative < auto`. At `manual`, the human owns every gate and nothing auto-resolves (the strict floor). At `conservative`, both gates queue on the human (pure pipelining — builds overlap, nothing auto-resolves). At `auto` (the seeded default), only the bundle-approval decision point and residue escalations queue; Verify auto-PASSes on evidence, so real concurrency follows. The floor never drops below **one human approval per task, at the contract decision point**.
|
|
113
113
|
|
|
114
114
|
**Design for failure (required).** Lease each task to its worker with a timeout — if a worker dies, release the claim back to READY rather than trusting partial work. A worker that hits a stop-and-escalate blocks only its own task; siblings keep running. And if several workers fail in one wave, trip a circuit-breaker and fall back to sequential — repeated failure means the scope was wrong, not the parallelism.
|
|
115
115
|
|
package/docs/11-governance.md
CHANGED
|
@@ -21,6 +21,10 @@ The governing rule, restated from the principles: **operate only at the level yo
|
|
|
21
21
|
|
|
22
22
|
The **per-scope default is auto-with-evidence behind a one-approval decision point**: the AI drafts the specification bundle, a human approves the frozen contract once, and the build auto-gates on evidence. You *lower* a scope toward draft-and-review or suggest wherever risk is high or evidence is thin — and a high-risk or method-defining scope is *always* lowered (it is never auto-run). The default sets where you start; review capacity and risk set where you stay.
|
|
23
23
|
|
|
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
|
+
|
|
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.
|
|
27
|
+
|
|
24
28
|
## The gate-fail protocol and the three reports
|
|
25
29
|
|
|
26
30
|
Every checkpoint produces three short reports — **Test** (does it pass?), **Quality** (is it well-made and conformant?), and **Risk** (what could go wrong, and who owns it?) — and resolves to exactly one outcome:
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
|
|
25
25
|
**Gate** — a checkpoint with an explicit pass/fail exit. Its outcome is `PASS`, `RISK-ACCEPTED`, or `HARD-STOP`.
|
|
26
26
|
|
|
27
|
+
**Ground (phase-0 preamble)** — the per-task phase *before* Specify in which the AI gathers the real current codebase the task touches — files, symbols, signatures, patterns, conventions — into a lean **grounding map**, surfacing the **anchors** the frozen contract will cite. It is AI-owned and adds no approval (the one approval stays at the contract freeze); it precedes the seven steps as step 0 so the contract, tests, and build are grounded in the code as it actually is, not in assumption. Lives in the `add` skill's `phases/0-ground.md`.
|
|
28
|
+
|
|
29
|
+
**Grounding map / anchors** — the §0 GROUND artifact: the real files, symbols, and conventions a task touches, plus the **anchors** — the symbols the frozen contract names. Task-specific delta only: it defers to `PROJECT.md` / `CONVENTIONS.md` for architecture and never re-runs the setup brownfield scan. `add.py status` / `check` surface whether the active task's contract is grounded (measure, never block — the contract-freeze checklist asks the human to confirm it).
|
|
30
|
+
|
|
27
31
|
**`HARD-STOP`** — a gate outcome meaning work cannot proceed; triggered by any failing test or security finding.
|
|
28
32
|
|
|
29
33
|
**Intake** — the step *before* a task: sizing a raw request into versioned scope by classifying it into one **request bucket**. The AI proposes `{bucket, rationale, command}`; the human confirms. Lives in the `add` skill's `intake.md` (the intake level, above the per-task flow).
|
|
@@ -70,7 +74,9 @@
|
|
|
70
74
|
|
|
71
75
|
**Scope level** (formerly "altitude") — the granularity a decision lives at: intake level (request → versioned scope) · milestone level · setup/foundation level · task level. (A cross-stage decision lives one level out, at the **stage-graduation** loop — which `graduate.md` also numbers as a scope level; see **Stage graduation**.) One ⚠-assumption notation is shared across every scope level.
|
|
72
76
|
|
|
73
|
-
**Autonomy level** (formerly "autonomy dial") — the per-task setting (`autonomy:
|
|
77
|
+
**Autonomy level** (formerly "autonomy dial") — the explicit per-task setting (`autonomy: manual | conservative | auto`, an ordered ladder manual < conservative < auto) choosing who resolves Verify: `auto` auto-PASSes on complete evidence, `conservative` keeps a human at the gate, `manual` is the strict floor (the human owns the gate; nothing auto-resolves). A high-risk scope refuses an unguarded `auto` — it must be lowered to `manual` or `conservative`. New tasks seed a visible, overridable `autonomy: auto`; a live task with no level warns (`implicit_autonomy`), a token outside the set is rejected (`unknown_autonomy_level`).
|
|
78
|
+
|
|
79
|
+
**Auto-ready goal** — a milestone goal whose every exit criterion **cites a verifier** (`(verify: <test|command|metric>)`), so the engine can self-verify the result against the goal without human judgment. It is the prerequisite by which **autonomy is earned by goal-clarity**: the **autonomy level** governs *who* resolves Verify, but a clarified, machine-checkable goal is what makes a self-verifying run meaningful. `add.py check` raises a `goal_not_auto_ready` **WARN** (never red) for the active milestone until it has an auto-ready goal (≥1 exit criterion and every one cited), and `status` surfaces it (`goal-ready: auto-ready ✓` / cited-of-total); a zero-criteria goal reads not-auto-ready and is milestone-shaping's nudge, not this warning's. The lint forces a citation *slot* per criterion — it raises the floor but **cannot prove the citation is real** (a human can write `(verify: it works)`): citation-theater is the accepted irreducible floor, and the freeze gate and autonomy behavior are unchanged by it.
|
|
74
80
|
|
|
75
81
|
**Automated quality gate** (formerly "evidence auto-gate") — the Verify resolver under `autonomy: auto`: a run may auto-PASS on complete evidence, recorded as *auto-resolved*; a security finding always escalates (`HARD-STOP`).
|
|
76
82
|
|
|
@@ -94,6 +100,14 @@
|
|
|
94
100
|
|
|
95
101
|
**Verification capacity / review throughput** — the rate at which a team can confirm AI output is correct; the real ceiling on safe speed.
|
|
96
102
|
|
|
103
|
+
**Foundation compaction** — the retrospective shrink: collapse a foundation spec's stable, shipped, zero-residue tail into one rolled-up settled line; the AI proposes and the human confirms; summarize and point, never delete; a SEPARATE step from the retrospective consolidation; distinct from the engine `add.py compact` (which archives finished-milestone files). See **Rolled-up settled line**, **Per-spec shape**.
|
|
104
|
+
|
|
105
|
+
**Rolled-up settled line** — the single line a compaction leaves in place of a collapsed run of records: lossy on prose, lossless on traceability (it carries a `see git` pointer).
|
|
106
|
+
|
|
107
|
+
**Per-spec shape** — each foundation spec's own tailored rolled-line format (PROJECT §Spec bullets · §Key-Decisions rows · CONVENTIONS learnings · GLOSSARY definition · MODEL_REGISTRY rows), all sharing one eligibility rule: shipped + zero open residues.
|
|
108
|
+
|
|
109
|
+
**Newest-first append-only** — every append-only foundation sequence prepends the newest record at the top; the rolled-up settled line anchors at the bottom (the oldest end), so compaction collapses upward.
|
|
110
|
+
|
|
97
111
|
---
|
|
98
112
|
|
|
99
113
|
## Optional mapping to formal phase names
|
|
@@ -103,6 +117,7 @@ This book uses plain step names. Teams connecting it to a larger formal standard
|
|
|
103
117
|
| Plain step (this book) | Formal phase name |
|
|
104
118
|
|------------------------|-------------------|
|
|
105
119
|
| Project setup | Foundation |
|
|
120
|
+
| Ground (preamble) | Codebase Discovery (the §0 grounding map) |
|
|
106
121
|
| Specify | Domain Discovery + Spec Definition |
|
|
107
122
|
| (design portion) | UX-Driven Design |
|
|
108
123
|
| Scenarios | Behavior specification (Given/When/Then) |
|
|
@@ -19,6 +19,7 @@ Every exit check in the book, collected for quick use. Print this page.
|
|
|
19
19
|
- [ ] Every rejection has a named error code.
|
|
20
20
|
- [ ] Success state-change described.
|
|
21
21
|
- [ ] Assumptions ranked lowest-confidence first; the 1–2 most-likely-wrong ⚠-flagged with why + cost (or an honest "none material" that still names the single biggest risk).
|
|
22
|
+
- [ ] "Existing behavior" assumptions carry grep/line citations; wiring claims name the production caller chain.
|
|
22
23
|
|
|
23
24
|
## Step 2 — Scenarios
|
|
24
25
|
|
|
@@ -40,6 +41,9 @@ Every exit check in the book, collected for quick use. Print this page.
|
|
|
40
41
|
- [ ] Suite runs in the pipeline and is red for the right reason.
|
|
41
42
|
- [ ] Tests assert behavior, not internals.
|
|
42
43
|
- [ ] Coverage target recorded.
|
|
44
|
+
- [ ] No `should_panic` lying reds — unimplemented paths use `todo!()` so they fail.
|
|
45
|
+
- [ ] Collateral tests for globally-enumerated things listed by exact name.
|
|
46
|
+
- [ ] Arithmetic checked: fixtures can reach green against frozen constants.
|
|
43
47
|
|
|
44
48
|
## Step 5 — Build
|
|
45
49
|
|
|
@@ -55,7 +59,10 @@ Every exit check in the book, collected for quick use. Print this page.
|
|
|
55
59
|
- [ ] Concurrency/timing of the risky operation is safe.
|
|
56
60
|
- [ ] No exposed secrets, injection, or unexpected dependencies.
|
|
57
61
|
- [ ] Layering and dependencies follow `CONVENTIONS.md`.
|
|
58
|
-
- [ ]
|
|
62
|
+
- [ ] Deep check: wiring trace recorded (every new symbol reachable from production entry point) and no dead code introduced.
|
|
63
|
+
- [ ] Was the green earned? Adversarial refute-read on the unchanged suite (no overfit, no vacuous asserts, no stubbed logic).
|
|
64
|
+
- [ ] Full-suite rerun by orchestrator (not only the agent's scoped run).
|
|
65
|
+
- [ ] A person reviewed and approved, **or** auto-resolved by the run (under `autonomy: auto`, no residue).
|
|
59
66
|
- [ ] Outcome recorded (`PASS` / `RISK-ACCEPTED` / `HARD-STOP`).
|
|
60
67
|
|
|
61
68
|
## The loop
|
|
@@ -71,10 +78,15 @@ Every exit check in the book, collected for quick use. Print this page.
|
|
|
71
78
|
A feature is shippable only when all are true:
|
|
72
79
|
|
|
73
80
|
- [ ] Spec complete: behavior stated, rejections named, assumptions ranked lowest-confidence first with the biggest risk flagged.
|
|
81
|
+
- [ ] Wiring and "existing behavior" assumptions carry grep/line citations; wiring claims name the production caller chain.
|
|
74
82
|
- [ ] Every rule has a scenario.
|
|
75
83
|
- [ ] Contract frozen; contract tests green.
|
|
76
|
-
- [ ] A test per scenario; suite was red before the build.
|
|
84
|
+
- [ ] A test per scenario; suite was red before the build (no `should_panic` lying reds).
|
|
85
|
+
- [ ] Collateral tests listed by exact name; arithmetic checked against frozen constants.
|
|
77
86
|
- [ ] All tests green; coverage held; tests and contract untouched by the AI.
|
|
87
|
+
- [ ] Wiring trace recorded: every new symbol reachable from production entry point.
|
|
88
|
+
- [ ] Adversarial refute-read confirms the green was earned (no overfit, no vacuous asserts, no stubbed logic).
|
|
89
|
+
- [ ] Full-suite rerun by orchestrator; not just the agent's scoped run.
|
|
78
90
|
- [ ] Concurrency, security, and architecture checked by a person.
|
|
79
91
|
- [ ] Gate outcome recorded with an accountable owner.
|
|
80
92
|
- [ ] Released behind a flag, with monitors in place.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pilotspace/add",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "ADD (AI-Driven Development) — a minimal, state-tracked Claude Code skill that drives every feature through Specify → Scenarios → Contract → Tests → Build → Verify → Observe. Ships the AIDD book as its trust layer.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"add": "bin/cli.js"
|