@pilotspace/add 1.10.0 → 1.11.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 +40 -0
- package/bin/cli.js +55 -0
- package/docs/09-the-loop.md +1 -1
- package/docs/11-governance.md +1 -1
- package/docs/14-foundation.md +1 -1
- package/docs/16-releasing.md +2 -2
- package/docs/appendix-c-glossary.md +3 -3
- package/package.json +4 -1
- package/skill/add/SKILL.md +7 -1
- package/skill/add/phases/0-ground.md +9 -3
- package/skill/add/phases/0-setup.md +2 -2
- package/skill/add/scope.md +1 -1
- package/tooling/add.py +361 -1571
- package/tooling/add_engine/__init__.py +5 -0
- package/tooling/add_engine/accessors.py +61 -0
- package/tooling/add_engine/autonomy.py +58 -0
- package/tooling/add_engine/components.py +117 -0
- package/tooling/add_engine/constants.py +221 -0
- package/tooling/add_engine/guidelines.py +252 -0
- package/tooling/add_engine/identity.py +107 -0
- package/tooling/add_engine/io_state.py +201 -0
- package/tooling/add_engine/milestones.py +108 -0
- package/tooling/add_engine/predicates.py +75 -0
- package/tooling/add_engine/release.py +86 -0
- package/tooling/add_engine/render.py +90 -0
- package/tooling/add_engine/taskdoc.py +217 -0
- package/tooling/add_engine/version.py +45 -0
- package/tooling/templates/TASK.fast.md.tmpl +2 -0
- package/tooling/templates/gitignore.tmpl +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,46 @@ All notable changes to the ADD method (`@pilotspace/add` on npm,
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.11.0] — 2026-06-26
|
|
10
|
+
|
|
11
|
+
Engine-modularization + audit-hardening release — the 7k-line monolith becomes a
|
|
12
|
+
navigable package, the verify/atomicity/coverage gates get five fixes, and the
|
|
13
|
+
standalone (milestone-free) lane becomes first-class. **No behavior change** to the
|
|
14
|
+
CLI, the flow, or any output: this is an internal architecture + hardening release.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **The engine is now a focused package.** `add-method/tooling/add.py` (7049 → 5640
|
|
18
|
+
lines, −20%) split into **13 `add_engine/*.py` modules** — `constants`, `io_state`,
|
|
19
|
+
`accessors`, `predicates`, `identity`, `guidelines`, `render`, `milestones`,
|
|
20
|
+
`components`, `version`, `release`, `taskdoc`, `autonomy` — behind a stable
|
|
21
|
+
re-export surface (`import add; add.<name>` still resolves, public AND `_`-prefixed,
|
|
22
|
+
so every existing test is untouched). `add.py` stays the runnable **orchestrator
|
|
23
|
+
entry** (the `load_state`/`save_state`/`report_data`/`cmd_*`/`main` spine). Each of
|
|
24
|
+
the 16 extractions was its own CI-green PR, proven verbatim by an AST source-segment
|
|
25
|
+
diff and gated by the full suite (1815 → 1959 green throughout, no test weakened).
|
|
26
|
+
- **Two-pin integrity model.** Alongside `ENGINE_MD5` (md5 of `add.py`),
|
|
27
|
+
`ENGINE_PKG_MD5` is a manifest digest over every `add_engine/*.py`; both are literal
|
|
28
|
+
pins (never self-hashed) and are checked byte-identical across the 3-tree mirror
|
|
29
|
+
(canonical · `.add` · `_bundled`). `prepare_bundle` + both installers + the `.add`
|
|
30
|
+
mirror now ship the whole `add_engine/` package.
|
|
31
|
+
|
|
32
|
+
### Fixed (audit-hardening)
|
|
33
|
+
- Five gate/atomicity/coverage fixes: a phase-build guard, hardened save-state
|
|
34
|
+
atomicity, force-preserve self-healing, setup-tests-before-build ordering, and a
|
|
35
|
+
consumer-stale gate. A security finding remains an un-forceable HARD-STOP.
|
|
36
|
+
|
|
37
|
+
### Added (the standalone / lightweight lane)
|
|
38
|
+
- **`add.py todo`** — capture a milestone-free backlog item without scaffolding a task.
|
|
39
|
+
- **`loose tasks:` release attribution** — a release now attributes *any* done,
|
|
40
|
+
milestone-free task on its `RELEASES.md` row (not only milestone membership), with a
|
|
41
|
+
separate status cue for releasable loose work.
|
|
42
|
+
- **`fast` (task) + `auto` (mode) flag modes** — the standalone lane is first-class:
|
|
43
|
+
a minimal `TASK.fast.md`, freeze-gated under any milestone, with a flag-mode quick
|
|
44
|
+
reference.
|
|
45
|
+
|
|
46
|
+
This release bundles **2 closed milestones** (`audit-hardening`,
|
|
47
|
+
`engine-modularization`) and **27 loose tasks** since 1.10.0.
|
|
48
|
+
|
|
9
49
|
## [1.10.0] — 2026-06-25
|
|
10
50
|
|
|
11
51
|
Component-aware major — ADD now models every codebase as a **graph of components**,
|
package/bin/cli.js
CHANGED
|
@@ -562,6 +562,57 @@ function writeGeminiSettings(target) {
|
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
+
// Seed .add/SOUL.md from the bundled template if it does not yet exist. Mirror of
|
|
566
|
+
// _installer.py:_seed_soul_md (npm <-> pip parity): skip-if-exists (SOUL.md is
|
|
567
|
+
// user-owned — never clobber); fail-soft (warn + return, never abort install/update).
|
|
568
|
+
function seedSoulMd(target) {
|
|
569
|
+
const dest = path.join(target, ".add", "SOUL.md");
|
|
570
|
+
if (fs.existsSync(dest)) return; // skip-if-exists (never clobber)
|
|
571
|
+
const source = path.join(PKG_ROOT, "tooling", "templates", "SOUL.md.tmpl");
|
|
572
|
+
if (!fs.existsSync(source)) {
|
|
573
|
+
warn("soul_seed_skipped: SOUL.md.tmpl not found in bundled tooling/templates/");
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
try {
|
|
577
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
578
|
+
fs.writeFileSync(dest, fs.readFileSync(source, "utf8"));
|
|
579
|
+
} catch (e) {
|
|
580
|
+
warn("soul_seed_skipped: could not write .add/SOUL.md — " + (e && e.message ? e.message : e));
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Ensure .add/.gitignore lists the engine's transient artifacts. Seed it from the bundled
|
|
585
|
+
// tooling/templates/gitignore.tmpl if absent; else APPEND-IF-ABSENT each pattern line the
|
|
586
|
+
// template carries that the file lacks — additive only, never reorders/removes user lines,
|
|
587
|
+
// idempotent; comment/blank lines are not appended to an existing file. Fail-soft. Twin of
|
|
588
|
+
// _installer.py:_seed_gitignore.
|
|
589
|
+
function seedGitignore(target) {
|
|
590
|
+
const source = path.join(PKG_ROOT, "tooling", "templates", "gitignore.tmpl");
|
|
591
|
+
if (!fs.existsSync(source)) {
|
|
592
|
+
warn("gitignore_seed_skipped: gitignore.tmpl not found in bundled tooling/templates/");
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
const dest = path.join(target, ".add", ".gitignore");
|
|
596
|
+
try {
|
|
597
|
+
const body = fs.readFileSync(source, "utf8");
|
|
598
|
+
if (!fs.existsSync(dest)) {
|
|
599
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
600
|
+
fs.writeFileSync(dest, body); // seed-if-missing
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
const current = fs.readFileSync(dest, "utf8");
|
|
604
|
+
const have = new Set(current.split("\n").map((l) => l.trim()));
|
|
605
|
+
const missing = body.split("\n").filter(
|
|
606
|
+
(l) => l.trim() && !l.trim().startsWith("#") && !have.has(l.trim())
|
|
607
|
+
);
|
|
608
|
+
if (missing.length === 0) return; // idempotent — nothing to add
|
|
609
|
+
const suffix = current === "" || current.endsWith("\n") ? "" : "\n";
|
|
610
|
+
fs.writeFileSync(dest, current + suffix + missing.join("\n") + "\n");
|
|
611
|
+
} catch (e) {
|
|
612
|
+
warn("gitignore_seed_skipped: could not update .add/.gitignore — " + (e && e.message ? e.message : e));
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
565
616
|
// The drop — now a RECONCILE: restore missing managed trees + refresh present ones
|
|
566
617
|
// (sweep orphans) + report per-tree status. Byte-compatible handoff with the prior
|
|
567
618
|
// installer. The interactive path resolves a target then calls straight into this.
|
|
@@ -569,6 +620,8 @@ function dropFiles(args, target, profile, intent) {
|
|
|
569
620
|
profile = profile || detectAgent(process.env);
|
|
570
621
|
log("Installing ADD into " + target);
|
|
571
622
|
reconcile(args, target);
|
|
623
|
+
seedSoulMd(target); // pip parity: re-seed a missing user-owned SOUL.md (never clobber)
|
|
624
|
+
seedGitignore(target); // pip parity: seed/append-if-absent the engine-transient ignore lines
|
|
572
625
|
|
|
573
626
|
// Agent detection: write THE detected agent's integration file (a marker-delimited
|
|
574
627
|
// pointer init's sync-guidelines later supersedes) + tailor the closing next-step.
|
|
@@ -932,6 +985,8 @@ function cmdUpdate(args) {
|
|
|
932
985
|
fs.copyFileSync(stateFile, path.join(addDir, "pre-update-state.bak.json"));
|
|
933
986
|
}
|
|
934
987
|
reconcile(args, target);
|
|
988
|
+
seedSoulMd(target); // pip parity: re-seed a missing user-owned SOUL.md (never clobber)
|
|
989
|
+
seedGitignore(target); // pip parity: seed/append-if-absent the engine-transient ignore lines
|
|
935
990
|
writeStamp(addDir, version);
|
|
936
991
|
log("ADD updated " + (cur || "(unstamped)") + " -> " + version +
|
|
937
992
|
" · managed layer reconciled · your project state untouched.");
|
package/docs/09-the-loop.md
CHANGED
|
@@ -51,7 +51,7 @@ Each delta is one tagged entry — `- [COMPETENCY · status] the learning (evide
|
|
|
51
51
|
|
|
52
52
|
**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.
|
|
53
53
|
|
|
54
|
-
**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.
|
|
54
|
+
**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. `add.py fold [--task <slug>] [--comp <TAG>]` mechanizes the consolidation — flip + transcribe + route + bump, validate-all-then-write so a reject leaves the tree byte-unchanged; running it **is** the human's confirmation, and the engine never self-approves *which* lessons to keep.
|
|
55
55
|
|
|
56
56
|
**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.
|
|
57
57
|
|
package/docs/11-governance.md
CHANGED
|
@@ -31,7 +31,7 @@ Every checkpoint produces three short reports — **Test** (does it pass?), **Qu
|
|
|
31
31
|
|
|
32
32
|
- **`PASS`** — criteria met; proceed.
|
|
33
33
|
- **`RISK-ACCEPTED`** — proceed with a signed waiver carrying a named owner, a linked ticket, and an expiry. Allowed for non-security gaps only.
|
|
34
|
-
- **`HARD-STOP`** — cannot proceed. Triggered by any failing test or any security finding
|
|
34
|
+
- **`HARD-STOP`** — cannot proceed. Triggered by any failing test or any security finding. A non-security limitation may proceed only with a signed `RISK-ACCEPTED` record carrying an owner and an expiry; security is never waved through.
|
|
35
35
|
|
|
36
36
|
The rule behind the protocol is *no silent skips.* A report nobody is accountable for approving is just a document; an outcome with an owner is governance.
|
|
37
37
|
|
package/docs/14-foundation.md
CHANGED
|
@@ -56,7 +56,7 @@ then render a real screen and **capture** it. That capture is the **design-confi
|
|
|
56
56
|
evidence — a real image the person approves *before* implementation, so the build
|
|
57
57
|
matches the layout instead of discovering it. The book keeps the *why*; the
|
|
58
58
|
operational recipe (the wireframe format, the token-bound mock, the capture engines)
|
|
59
|
-
lives in the `add` skill's `design.md` and `udd-wireframe.md
|
|
59
|
+
lives in the `add` skill's `design.md` and the `udd-wireframe.md` template (`tooling/templates/`).
|
|
60
60
|
|
|
61
61
|
These three foundation competencies, together with the **TDD ⇄ ADD** engine of
|
|
62
62
|
[Part II](./02-the-flow.md), are ADD's five. The first four feed context to the
|
package/docs/16-releasing.md
CHANGED
|
@@ -11,8 +11,8 @@ them *ship*. This chapter names the act every project eventually performs and th
|
|
|
11
11
|
now, never formalized: bundling closed milestones into a versioned, user-facing release whose notes
|
|
12
12
|
are evidence-backed, whose risk is disclosed, and whose behaviour is then watched.
|
|
13
13
|
|
|
14
|
-
Releasing is the **fifth scope level** — after
|
|
15
|
-
|
|
14
|
+
Releasing is the **fifth scope level** — after setup, intake, the milestone loop, and stage graduation.
|
|
15
|
+
Like every scope level it runs the same shape: **gather → propose → the human
|
|
16
16
|
confirms → the engine records and enforces a floor.** And like graduation, it ends with an outward
|
|
17
17
|
act the human owns. The operational recipe lives in the `release.md` skill guide; this chapter is the
|
|
18
18
|
*why* behind it.
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
|
|
85
85
|
**Baseline approval** (formerly "the lock-down") — the single human gate ending autonomous setup: an explicit yes that freezes the foundation, first scope, and first contract together; runs as `add.py lock --by <name>`.
|
|
86
86
|
|
|
87
|
-
**Scope level** (formerly "altitude") — the granularity a decision lives at: intake
|
|
87
|
+
**Scope level** (formerly "altitude") — the granularity a decision lives at, as one ordered ladder of five: **setup/foundation** · **intake** (request → versioned scope) · **the milestone loop** (the task is its inner unit) · **stage graduation** (changes rigor, not version; see **Stage graduation**) · **release** (≥1 closed milestone → a versioned, watched cut; see **Release scope level**). One ⚠-assumption notation is shared across every scope level.
|
|
88
88
|
|
|
89
89
|
**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`).
|
|
90
90
|
|
|
@@ -134,9 +134,9 @@
|
|
|
134
134
|
|
|
135
135
|
**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.
|
|
136
136
|
|
|
137
|
-
**Wireframe** — the Stage-A low-fidelity, *structural* map of one screen: its regions and the component **slots** inside them, derived from `prototypes/<name>.json` *before* any color, type, or spacing — it answers "what goes where", not "what it looks like". Beat 3 of the UDD **design-definition loop**; the low-fi half of the two-stage fidelity that ends in a confirmed capture. See the `
|
|
137
|
+
**Wireframe** — the Stage-A low-fidelity, *structural* map of one screen: its regions and the component **slots** inside them, derived from `prototypes/<name>.json` *before* any color, type, or spacing — it answers "what goes where", not "what it looks like". Beat 3 of the UDD **design-definition loop**; the low-fi half of the two-stage fidelity that ends in a confirmed capture. See the `udd-wireframe.md` template (`tooling/templates/`, Stage A).
|
|
138
138
|
|
|
139
|
-
**Design mock** — the Stage-B high-fidelity, **self-contained** HTML render of a screen: the `catalog.json` components as a reusable token-bound kit, bound to `tokens.json` and populated with mock data, openable offline and screenshot-able. The human-facing *visible* evidence the human confirms (the frozen `prototypes/<name>.json` tree is its machine-checkable twin). Beat 4's hi-fi artifact; the recipe lives in the `
|
|
139
|
+
**Design mock** — the Stage-B high-fidelity, **self-contained** HTML render of a screen: the `catalog.json` components as a reusable token-bound kit, bound to `tokens.json` and populated with mock data, openable offline and screenshot-able. The human-facing *visible* evidence the human confirms (the frozen `prototypes/<name>.json` tree is its machine-checkable twin). Beat 4's hi-fi artifact; the recipe lives in the `udd-wireframe.md` template (`tooling/templates/`, Stage B).
|
|
140
140
|
|
|
141
141
|
**Capture** — the real rendered image (PNG/SVG) of a design mock: the **design-confirm evidence** artifact. Captures live at `.add/design/captures/<name>.<ext>` (one per prototype) and are attached or mentioned in the feature's `TASK.md`; `@json-render/image` (Satori → PNG/SVG, no browser) is the named default capture engine, otherwise the self-contained mock is screenshot headless. The engine never renders — it only MEASURES presence: `add.py check` raises a never-red `missing_capture` WARN for a prototype with no capture.
|
|
142
142
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pilotspace/add",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.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"
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
"bin/",
|
|
20
20
|
"skill/",
|
|
21
21
|
"tooling/add.py",
|
|
22
|
+
"tooling/add_engine/",
|
|
23
|
+
"!tooling/add_engine/__pycache__",
|
|
24
|
+
"!**/*.pyc",
|
|
22
25
|
"tooling/templates/",
|
|
23
26
|
"docs/",
|
|
24
27
|
"README.md",
|
package/skill/add/SKILL.md
CHANGED
|
@@ -62,7 +62,13 @@ self-improving via the `soul-self-improve` path). Then branch on state:
|
|
|
62
62
|
- **No active task** → first SIZE the request (Intake below), then `add.py new-task <slug> --title "..."`.
|
|
63
63
|
|
|
64
64
|
**Quick ref** — `status` resume · `init` bootstrap · `advance` continue · `gate PASS` at verify.
|
|
65
|
-
**
|
|
65
|
+
**Flag mode** — two human-owned settings (never auto-picked): **fast** (task) · **auto** (mode).
|
|
66
|
+
- **fast** — `new-task --fast`: minimal template, freeze-gated; a milestone-free `--fast` task is a
|
|
67
|
+
blessed standalone low-ceremony lane. Jot ideas first with `add.py todo "<text>"` (then `todo` to
|
|
68
|
+
list · `todo --done <id>`).
|
|
69
|
+
- **auto** — `autonomy: auto` (default) auto-gates verify on evidence; lower the autonomy level with
|
|
70
|
+
`add.py autonomy set conservative|manual` for a human gate · `new-milestone --await-confirm`
|
|
71
|
+
confirm-gates a milestone's tasks.
|
|
66
72
|
|
|
67
73
|
## Intake — size a request before creating scope
|
|
68
74
|
|
|
@@ -47,11 +47,17 @@ Never: invent a file, symbol, or signature you have not opened.
|
|
|
47
47
|
## Exit gate
|
|
48
48
|
|
|
49
49
|
<exit_gate>
|
|
50
|
-
- [ ]
|
|
51
|
-
- [ ]
|
|
52
|
-
- [ ]
|
|
50
|
+
- [ ] **Touches** — the real files/symbols the task touches are named (from the code, not assumed).
|
|
51
|
+
- [ ] **Context** (working folder) — the non-code artifacts the task touches (docs · todos · config · data) are named, task-delta only.
|
|
52
|
+
- [ ] **Honors** — the patterns/conventions to honor are cited (task-delta only; no architecture re-scan).
|
|
53
|
+
- [ ] **Anchors** — the anchors §3 will cite are listed — §3 names only anchors that exist here.
|
|
53
54
|
</exit_gate>
|
|
54
55
|
|
|
56
|
+
**Grounding is complete when** all four fields are filled from real assets: a STRONG grounding cites
|
|
57
|
+
actual files/symbols/docs/conventions you opened; a WEAK one leaves a `<…>` placeholder or names what you
|
|
58
|
+
assume. All four are non-optional — skipping **Context** (the working folder beyond code) is the usual
|
|
59
|
+
silent gap. §3 may cite only anchors that appear here.
|
|
60
|
+
|
|
55
61
|
> **Advisor · Confidence** — a broad sweep is the canonical spawn case (advisor.md); self-score your grounding before you specify against it (confidence.md).
|
|
56
62
|
|
|
57
63
|
## Next
|
|
@@ -57,7 +57,7 @@ Capture each surfaced decision as an **ADR** into `PROJECT.md` **Key Decisions**
|
|
|
57
57
|
```bash
|
|
58
58
|
python3 .add/tooling/add.py new-task <slug> --title "<first feature>"
|
|
59
59
|
```
|
|
60
|
-
Draft
|
|
60
|
+
Draft the full bundle **§1–§4** — incl. the **§4 red suite** (`phases/4-tests.md`); the lock approves it whole. **Leave §3 `Status: DRAFT`** — the lock is its approval. You MAY `advance` pre-lock, but the engine **refuses crossing into build** until you `lock` (`setup_unlocked`). Sequence: **bundle (§1–§4, tests RED) → lock → build** — the red suite must FAIL **before build** (never start Build until §1–§4 exist and tests are red).
|
|
61
61
|
4. **Write `.add/SETUP-REVIEW.md`** per `setup-review.md`: every drafted decision, **lowest-confidence-first**, tagged `guessed` | `evidence-grounded`.
|
|
62
62
|
|
|
63
63
|
## Run mode — how the build will be driven (propose parallel + auto; confirm to keep)
|
|
@@ -93,7 +93,7 @@ Typing it themselves stays the **escape hatch** — the decision is always the h
|
|
|
93
93
|
<exit_gate>
|
|
94
94
|
- [ ] `.add/state.json` exists; setup was seeded unlocked (`--await-lock`) then locked.
|
|
95
95
|
- [ ] Living docs filled (brownfield: from code, tagged evidence-grounded; greenfield: from the interview).
|
|
96
|
-
- [ ] First task created;
|
|
96
|
+
- [ ] First task created; **§1–§4 drafted — the red suite (per `phases/4-tests.md`) runs RED before build opens**; `.add/SETUP-REVIEW.md` written lowest-confidence-first.
|
|
97
97
|
- [ ] Human confirmed the baseline approval and `add.py lock --by` ran with their name; first task §3 `FROZEN @ v1`; build open.
|
|
98
98
|
</exit_gate>
|
|
99
99
|
|
package/skill/add/scope.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
Before drafting the goal sentence, position the request in what already exists — distinct from intake's classification, not redundant with it.
|
|
21
21
|
|
|
22
|
-
1. **Ground in current assets.** Read the goal against `
|
|
22
|
+
1. **Ground in current assets.** Read the goal against what exists — the goal must reflect what the project already is. Ground as rigorously as a task's §0 (`phases/0-ground.md`), using the **same four fields** at milestone scope: **Touches** (the subsystems/files the milestone spans) · **Context** (the docs · todos · config · data it works against) · **Honors** (the `PROJECT.md` / `CONVENTIONS.md` invariants it must respect) · **Anchors** (the existing contracts/symbols its tasks will cite). Grounding is complete when each is named from real assets, not assumed.
|
|
23
23
|
2. **Relate to the milestone map.** Read every existing goal — `.add/milestones/*/MILESTONE.md` and `.add/archive/*` — and name THIS request's relationship: *extends* X · *depends-on* Y · *overlaps* Z. Record in the `rationale` line.
|
|
24
24
|
3. **If the goal is already delivered** by an existing milestone, reject `duplicate_goal` and route as `task` or `change-request`.
|
|
25
25
|
|