@pilotspace/add 1.17.0 → 2.1.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 +193 -0
- package/GETTING-STARTED.md +20 -64
- package/README.md +138 -158
- package/agents/add-advisor.md +66 -21
- package/agents/add-worker.md +102 -0
- package/bin/cli.js +88 -21
- package/package.json +2 -3
- package/personas-teacher/VENDOR.md +6 -0
- package/skill/add/SKILL.md +100 -144
- package/skill/add/adopt.md +28 -0
- package/skill/add/beyond.md +37 -0
- package/skill/add/deltas.md +25 -2
- package/skill/add/design.md +56 -74
- package/skill/add/{report-template.md → gate-udd.md} +28 -38
- package/skill/add/intake.md +56 -25
- package/skill/add/loop.md +32 -19
- package/skill/add/persona-author/SKILL.md +116 -0
- package/skill/add/persona-author/assets/example-design-persona.md +55 -0
- package/skill/add/persona-author/assets/example-persona.md +57 -0
- package/skill/add/persona-author/references/contract.md +69 -0
- package/skill/add/persona-author/references/patterns.md +122 -0
- package/skill/add/persona-author/references/seeding.md +79 -0
- package/skill/add/phases/build.md +79 -0
- package/skill/add/phases/direction.md +287 -0
- package/skill/add/phases/verify.md +161 -0
- package/skill/add/run.md +16 -18
- package/skill/add/terms.md +18 -0
- package/tooling/add.py +2421 -3258
- package/tooling/add_engine/autonomy.py +2 -37
- package/tooling/add_engine/components.py +4 -87
- package/tooling/add_engine/constants.py +148 -93
- package/tooling/add_engine/guidelines.py +10 -11
- package/tooling/add_engine/io_state.py +72 -5
- package/tooling/add_engine/predicates.py +90 -2
- package/tooling/add_engine/search.py +6 -6
- package/tooling/add_engine/taskdoc.py +15 -10
- package/tooling/templates/CONVENTIONS.md.tmpl +1 -1
- package/tooling/templates/GLOSSARY.md.tmpl +10 -4
- package/tooling/templates/MILESTONE.md.tmpl +20 -16
- package/tooling/templates/PLAN.md.tmpl +129 -0
- package/tooling/templates/PROJECT.md.tmpl +6 -1
- package/tooling/templates/PROMPT.persona.md.tmpl +17 -21
- package/tooling/templates/personas/build-engineer.md.tmpl +45 -0
- package/tooling/templates/personas/data-steward.md.tmpl +45 -0
- package/tooling/templates/personas/evidence-verifier.md.tmpl +45 -0
- package/tooling/templates/personas/platform-engineer.md.tmpl +45 -0
- package/tooling/templates/personas/product-lead.md.tmpl +51 -0
- package/tooling/templates/personas/quality-auditor.md.tmpl +47 -0
- package/tooling/templates/personas/release-manager.md.tmpl +52 -0
- package/tooling/templates/personas/security-gatekeeper.md.tmpl +45 -0
- package/tooling/templates/personas/software-architect.md.tmpl +45 -0
- package/tooling/templates/personas/stream-orchestrator.md.tmpl +44 -0
- package/tooling/templates/personas/technical-writer.md.tmpl +49 -0
- package/tooling/templates/personas/ux-experience-lead.md.tmpl +48 -0
- package/tooling/templates/specs/SPEC.md.tmpl +18 -0
- package/tooling/templates/udd-wireframe.md +1 -1
- package/agents/add-build.md +0 -29
- package/agents/add-design.md +0 -32
- package/agents/add-persona.md +0 -33
- package/agents/add-verify.md +0 -36
- package/docs/00-introduction.md +0 -46
- package/docs/01-principles.md +0 -71
- package/docs/02-the-flow.md +0 -113
- package/docs/03-step-1-specify.md +0 -123
- package/docs/04-step-2-scenarios.md +0 -90
- package/docs/05-step-3-contract.md +0 -80
- package/docs/06-step-4-tests.md +0 -85
- package/docs/07-step-5-build.md +0 -82
- package/docs/08-step-6-verify.md +0 -105
- package/docs/09-the-loop.md +0 -75
- package/docs/10-setup-and-stages.md +0 -118
- package/docs/11-governance.md +0 -91
- package/docs/12-roles.md +0 -99
- package/docs/13-adoption.md +0 -67
- package/docs/14-foundation.md +0 -142
- package/docs/15-foundations-and-lineage.md +0 -106
- package/docs/16-releasing.md +0 -182
- package/docs/17-components.md +0 -143
- package/docs/18-personas.md +0 -80
- package/docs/README.md +0 -77
- package/docs/add-competencies.png +0 -0
- package/docs/add-flow.png +0 -0
- package/docs/add-foundation.png +0 -0
- package/docs/add-hierarchy.png +0 -0
- package/docs/add-milestone-task-lifecycle.png +0 -0
- package/docs/add-task-growth-wheel.png +0 -0
- package/docs/appendix-a-templates.md +0 -88
- package/docs/appendix-b-prompts.md +0 -154
- package/docs/appendix-c-glossary.md +0 -176
- package/docs/appendix-d-worked-example.md +0 -231
- package/docs/appendix-e-checklists.md +0 -92
- package/docs/appendix-f-requirements-matrix.md +0 -171
- package/docs/appendix-g-references.md +0 -106
- package/skill/add/advisor.md +0 -81
- package/skill/add/compact-foundation.md +0 -40
- package/skill/add/components.md +0 -52
- package/skill/add/confidence.md +0 -32
- package/skill/add/fold.md +0 -63
- package/skill/add/graduate.md +0 -39
- package/skill/add/phases/0-ground.md +0 -64
- package/skill/add/phases/0-setup.md +0 -103
- package/skill/add/phases/1-specify.md +0 -61
- package/skill/add/phases/2-scenarios.md +0 -48
- package/skill/add/phases/3-contract.md +0 -60
- package/skill/add/phases/4-tests.md +0 -61
- package/skill/add/phases/5-build.md +0 -62
- package/skill/add/phases/6-verify.md +0 -69
- package/skill/add/phases/7-observe.md +0 -45
- package/skill/add/phases/fast-lane.md +0 -34
- package/skill/add/release.md +0 -61
- package/skill/add/scope.md +0 -72
- package/skill/add/self-improve.md +0 -20
- package/skill/add/sensitivity.md +0 -51
- package/skill/add/setup-review.md +0 -48
- package/skill/add/soul.md +0 -58
- package/skill/add/streams.md +0 -269
- package/tooling/add_engine/release.py +0 -86
- package/tooling/templates/TASK.fast.md.tmpl +0 -78
- package/tooling/templates/TASK.md.tmpl +0 -181
- package/tooling/templates/personas/_template.md.tmpl +0 -82
package/bin/cli.js
CHANGED
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* npx @pilotspace/add init [targetDir] [--force] [--stage <stage>] [--name <name>] [--yes|--non-interactive]
|
|
8
8
|
*
|
|
9
|
-
* Installs the ADD skill + tooling
|
|
9
|
+
* Installs the ADD skill + tooling into a target project:
|
|
10
10
|
* <target>/.claude/skills/add/ (the skill Claude loads)
|
|
11
11
|
* <target>/.add/tooling/ (add.py scaffolder + state tracker)
|
|
12
|
-
* <target>/.add/docs/ (the AIDD book — the trust layer)
|
|
13
12
|
* It DROPS FILES ONLY — it does NOT run `add.py init`. Initialisation is deferred to
|
|
14
13
|
* the AI (via `/add`, which runs `init --await-lock` to arm the v12 lock-down gate) or
|
|
15
14
|
* to a CLI user. A pre-run plain init would grandfather-lock the gate before `/add` runs
|
|
@@ -58,9 +57,9 @@ function parseArgs(argv) {
|
|
|
58
57
|
// non-interactive selector the interactive() gate honors (CI/pipes do this too).
|
|
59
58
|
else if (a === "--yes" || a === "-y") args.yes = true;
|
|
60
59
|
else if (a === "--non-interactive") args.nonInteractive = true;
|
|
61
|
-
// --no-skill: drop the engine
|
|
60
|
+
// --no-skill: drop the engine ONLY, not the skill. The Claude Code plugin
|
|
62
61
|
// already provides the `add` skill, so a plugin bootstrap uses this to materialize
|
|
63
|
-
// .add/tooling/
|
|
62
|
+
// .add/tooling/ into the project without a duplicate .claude/skills/add.
|
|
64
63
|
else if (a === "--no-skill") args.noSkill = true;
|
|
65
64
|
// --rule-file: write the ADD block to .claude/rules/add-workflows.md + reference it from
|
|
66
65
|
// CLAUDE.md instead of inlining (auto-on for ccsk projects with a .ccsk/ dir).
|
|
@@ -217,7 +216,7 @@ function agentPointerBlock(profile) {
|
|
|
217
216
|
GUIDE_BEGIN + "\n" +
|
|
218
217
|
"## ADD — how to work in this repo\n" +
|
|
219
218
|
"\n" +
|
|
220
|
-
"This project uses **ADD (AI-Driven Development)**. The engine
|
|
219
|
+
"This project uses **ADD (AI-Driven Development)**. The engine is installed.\n" +
|
|
221
220
|
"To begin: run `python3 .add/tooling/add.py status` (the resume point), read\n" +
|
|
222
221
|
"`.add/PROJECT.md`, then `python3 .add/tooling/add.py guide` for the current phase.\n" +
|
|
223
222
|
"\n" +
|
|
@@ -410,10 +409,11 @@ async function loadClack() {
|
|
|
410
409
|
// --- brand + feature showcase (interactive path only; fail-soft) -------------
|
|
411
410
|
// Wordmark + value line + the 7-step Specify->Observe loop, rendered BEFORE the first
|
|
412
411
|
// prompt on the interactive path only — so the non-interactive byte stream is unchanged.
|
|
413
|
-
// The 7 labels are the real ADD phases (grounded in the method, never invented
|
|
414
|
-
//
|
|
415
|
-
//
|
|
416
|
-
|
|
412
|
+
// The 7 labels are the real ADD phases (grounded in the method, never invented; grounding
|
|
413
|
+
// itself is folded into step 3, Plan, not a separate phase). Fail-soft: any draw error is
|
|
414
|
+
// swallowed so a banner can never abort the install. No color is emitted (default accent:
|
|
415
|
+
// none); the glyphs / tagline / accent are a SWAPPABLE content slot.
|
|
416
|
+
const BRAND_LOOP = ["Specify", "Plan", "Tests", "Build", "Verify"];
|
|
417
417
|
|
|
418
418
|
function terminalCaps(env, stream) {
|
|
419
419
|
const width = Number(env.COLUMNS) || (stream && stream.columns) || 80;
|
|
@@ -481,7 +481,7 @@ async function runClackPreamble(clack, target, detected, askScope) {
|
|
|
481
481
|
initialValue: target, defaultValue: target,
|
|
482
482
|
});
|
|
483
483
|
if (clack.isCancel(chosen)) return { cancelled: true, target: target };
|
|
484
|
-
const ok = await clack.confirm({ message: "Write the ADD skill + tooling
|
|
484
|
+
const ok = await clack.confirm({ message: "Write the ADD skill + tooling here?" });
|
|
485
485
|
if (clack.isCancel(ok) || !ok) return { cancelled: true, target: target };
|
|
486
486
|
// global-first SCOPE step (after the target confirm, before agent-detect) — recommended
|
|
487
487
|
// global home, explicit pick; skipped when --global already chose. global stays ADDITIVE.
|
|
@@ -671,7 +671,7 @@ function dropFiles(args, target, profile, intent) {
|
|
|
671
671
|
// NO step 4: the installer DROPS FILES ONLY. Initialisation is deferred to the AI
|
|
672
672
|
// (via `/add`) or a CLI user — a pre-run plain `add.py init` would grandfather-lock
|
|
673
673
|
// the v12 lock-down gate before `/add` runs (see file header). So no Python is run here.
|
|
674
|
-
log("\nDone. " + (args.noSkill ? "The engine
|
|
674
|
+
log("\nDone. " + (args.noSkill ? "The engine is" : "The `add` skill + tooling are") +
|
|
675
675
|
" installed (no project state yet — that's intentional).");
|
|
676
676
|
if (profile.id === "generic") {
|
|
677
677
|
// the generic onramp line — kept literal so the conversational-only handoff is stable
|
|
@@ -753,7 +753,6 @@ const MANAGED = [
|
|
|
753
753
|
["skill/add", [".claude", "skills", "add"], false],
|
|
754
754
|
["agents", [".claude", "agents"], false],
|
|
755
755
|
["tooling", [".add", "tooling"], true],
|
|
756
|
-
["docs", [".add", "docs"], false],
|
|
757
756
|
["personas-teacher", [".add", "personas-teacher"], false],
|
|
758
757
|
];
|
|
759
758
|
// Optional managed trees: an ENHANCEMENT the persona phase reads, not core runtime. The real
|
|
@@ -762,6 +761,20 @@ const MANAGED = [
|
|
|
762
761
|
// _installer.py:OPTIONAL. Design-for-failure. `agents` joins here (roster-install-drift): the
|
|
763
762
|
// phase-agent roster is a spawn-acceleration enhancement, not core runtime.
|
|
764
763
|
const OPTIONAL = new Set(["personas-teacher", "agents"]);
|
|
764
|
+
// SHARED-namespace managed trees (installer-shared-namespace-guard): destinations OTHER
|
|
765
|
+
// TOOLS also write — `.claude/agents` holds the user's own Claude Code subagents. A
|
|
766
|
+
// whole-dir clean-replace there sweeps the user's files as "orphans" (the reported
|
|
767
|
+
// data-loss bug), so these trees route to sharedFileReplace: per-file atomic landings of
|
|
768
|
+
// the shipped files + removal of ONLY the explicit tombstones below. Twin of
|
|
769
|
+
// _installer.py:_SHARED / _RETIRED_AGENTS.
|
|
770
|
+
const SHARED = new Set(["agents"]);
|
|
771
|
+
// Roster names retired upstream — the ONLY names the shared lander may remove (never a
|
|
772
|
+
// pattern/prefix heuristic: a USER file named add-anything.md must survive).
|
|
773
|
+
// roster-distill (ADD 2.0 M1): the 5-agent roster collapsed into the ONE `add` agent.
|
|
774
|
+
// advisor-split: that ONE `add` agent split into `add-worker` + `add-advisor`, so `add.md`
|
|
775
|
+
// retires here and `add-advisor.md` leaves the list (it ships again; landing precedes removal).
|
|
776
|
+
const RETIRED_AGENTS = ["add-design.md", "add-build.md", "add-verify.md",
|
|
777
|
+
"add-persona.md", "add.md"];
|
|
765
778
|
const STAMP_FILE = ".add-version";
|
|
766
779
|
const LOCK_FILE = ".update.lock"; // the `update --global` home lock (never user-data)
|
|
767
780
|
const LOCK_STALE_DEFAULT = 600; // seconds (10 min); ADD_LOCK_STALE_SECONDS env-overridable
|
|
@@ -948,7 +961,7 @@ function cleanReplaceTree(src, dest, stripTests) {
|
|
|
948
961
|
return { restored: restored, refreshed: refreshed };
|
|
949
962
|
}
|
|
950
963
|
|
|
951
|
-
const TREE_LABEL = { "skill/add": "skill", "agents": "agents", "tooling": "tooling", "
|
|
964
|
+
const TREE_LABEL = { "skill/add": "skill", "agents": "agents", "tooling": "tooling", "personas-teacher": "personas" };
|
|
952
965
|
|
|
953
966
|
// Per managed tree: "missing" (dest absent OR empty) or "present".
|
|
954
967
|
function managedStatus(target) {
|
|
@@ -961,6 +974,36 @@ function managedStatus(target) {
|
|
|
961
974
|
return status;
|
|
962
975
|
}
|
|
963
976
|
|
|
977
|
+
// installer-shared-namespace-guard: land a SHARED-namespace managed tree per FILE.
|
|
978
|
+
// `.claude/agents` belongs to the user as much as to ADD — only the shipped files are
|
|
979
|
+
// written (temp-sibling + atomic rename each, so a crash never leaves a torn file) and
|
|
980
|
+
// only the explicit RETIRED_AGENTS tombstones are removed; every other destination file
|
|
981
|
+
// is never opened. Returns the same { restored, refreshed } roll-up shape as
|
|
982
|
+
// cleanReplaceTree so the reconcile reporting is agnostic. Mirror of
|
|
983
|
+
// _installer.py:_shared_file_replace.
|
|
984
|
+
function sharedFileReplace(src, dest) {
|
|
985
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
986
|
+
let restored = 0, refreshed = 0;
|
|
987
|
+
const entries = fs.readdirSync(src).filter((n) => fs.statSync(path.join(src, n)).isFile()).sort();
|
|
988
|
+
for (const name of entries) {
|
|
989
|
+
const target = path.join(dest, name);
|
|
990
|
+
const existed = fs.existsSync(target);
|
|
991
|
+
const tmp = path.join(dest, name + ".add-tmp-" + Math.random().toString(36).slice(2, 10));
|
|
992
|
+
try {
|
|
993
|
+
fs.copyFileSync(path.join(src, name), tmp);
|
|
994
|
+
fs.renameSync(tmp, target); // atomic overwrite (same directory)
|
|
995
|
+
} catch (e) {
|
|
996
|
+
fs.rmSync(tmp, { force: true }); // dest entry untouched or already whole
|
|
997
|
+
throw e;
|
|
998
|
+
}
|
|
999
|
+
if (existed) refreshed++; else restored++;
|
|
1000
|
+
}
|
|
1001
|
+
for (const name of RETIRED_AGENTS) {
|
|
1002
|
+
fs.rmSync(path.join(dest, name), { force: true }); // absent tombstone — never fatal
|
|
1003
|
+
}
|
|
1004
|
+
return { restored: restored, refreshed: refreshed };
|
|
1005
|
+
}
|
|
1006
|
+
|
|
964
1007
|
// reconcile: restore-missing + refresh-present (sweep orphans) across the managed trees,
|
|
965
1008
|
// reporting per-tree status. Honors --no-skill (the plugin provides the skill). Touches
|
|
966
1009
|
// ONLY managed trees — never user data. Prechecks ALL sources first (design-for-failure:
|
|
@@ -978,7 +1021,9 @@ function reconcile(args, target, srcRoot) {
|
|
|
978
1021
|
const status = managedStatus(target);
|
|
979
1022
|
let restored = 0, refreshed = 0;
|
|
980
1023
|
for (const [sub, destParts, stripTests] of trees) {
|
|
981
|
-
const roll =
|
|
1024
|
+
const roll = SHARED.has(sub)
|
|
1025
|
+
? sharedFileReplace(path.join(srcRoot, sub), path.join(target, ...destParts))
|
|
1026
|
+
: cleanReplaceTree(path.join(srcRoot, sub), path.join(target, ...destParts), stripTests);
|
|
982
1027
|
restored += roll.restored;
|
|
983
1028
|
refreshed += roll.refreshed;
|
|
984
1029
|
const dest = destParts.join("/");
|
|
@@ -992,7 +1037,7 @@ function reconcile(args, target, srcRoot) {
|
|
|
992
1037
|
return { restored: restored, refreshed: refreshed, trees: status };
|
|
993
1038
|
}
|
|
994
1039
|
|
|
995
|
-
// --- global home: an OPT-IN shared install (engine+
|
|
1040
|
+
// --- global home: an OPT-IN shared install (engine+skill) updated for all projects ----
|
|
996
1041
|
// Resolution is PURE + total (never throws); the home MIRRORS the bundled managed layer so
|
|
997
1042
|
// `update --global` propagation reuses reconcile() unchanged. Mirror of _installer.py.
|
|
998
1043
|
function resolveGlobalHome(env) {
|
|
@@ -1034,12 +1079,14 @@ function writeRegistry(home, paths) {
|
|
|
1034
1079
|
fs.renameSync(tmp, target); // atomic on the same filesystem (POSIX + Windows)
|
|
1035
1080
|
}
|
|
1036
1081
|
|
|
1037
|
-
// The home mirrors the bundled layout (skill/add + tooling
|
|
1082
|
+
// The home mirrors the bundled layout (skill/add + tooling at the SAME relative paths
|
|
1038
1083
|
// the package ships) so reconcile(args, project, home) reuses MANAGED unchanged.
|
|
1039
1084
|
const GLOBAL_TREES = [
|
|
1040
1085
|
["skill/add", ["skill", "add"], false],
|
|
1086
|
+
// roster-drift fix: absent here, `update --global` propagation (sourced FROM the home)
|
|
1087
|
+
// soft-skipped the roster forever — no refresh, no retired-agent tombstones.
|
|
1088
|
+
["agents", ["agents"], false],
|
|
1041
1089
|
["tooling", ["tooling"], true],
|
|
1042
|
-
["docs", ["docs"], false],
|
|
1043
1090
|
["personas-teacher", ["personas-teacher"], false],
|
|
1044
1091
|
];
|
|
1045
1092
|
|
|
@@ -1062,7 +1109,7 @@ function reconcileGlobal(home, claudeDir, noSkill) {
|
|
|
1062
1109
|
// --- global DATA: an OPT-IN per-project user-data snapshot under <home>/data/<key> ----------
|
|
1063
1110
|
// Strictly additive; copies ONLY user-data (managed trees + transient excluded), clean-replaced,
|
|
1064
1111
|
// one-way (project->home). Mirror of _installer.py (identical key + include/exclude rule).
|
|
1065
|
-
const DATA_EXCLUDE = ["tooling", "docs", ".update-cache", STAMP_FILE, LOCK_FILE, PROJECT_LOCK_FILE]; // managed trees + meta + both locks
|
|
1112
|
+
const DATA_EXCLUDE = ["tooling", "docs", ".update-cache", STAMP_FILE, LOCK_FILE, PROJECT_LOCK_FILE]; // managed trees + meta + both locks ("docs" = legacy 1.x tree: still never user-data)
|
|
1066
1113
|
|
|
1067
1114
|
// data_key twin: <sanitized-basename>-<sha1(abspath_utf8)[:12]>. Pure · total · separator-free.
|
|
1068
1115
|
function dataKey(projectAbspath) {
|
|
@@ -1840,6 +1887,26 @@ function cmdUpdate(args) {
|
|
|
1840
1887
|
log("ADD updated " + (cur || "(unstamped)") + " -> " + version +
|
|
1841
1888
|
" · managed layer reconciled (" + roll.restored + " restored · " + roll.refreshed +
|
|
1842
1889
|
" refreshed) · your project state untouched.");
|
|
1890
|
+
// crossing nudges — engine-owned follow-ups the updater must NAME, never run (python3
|
|
1891
|
+
// may be absent on this PATH; both commands are idempotent). Twin of _installer.py.
|
|
1892
|
+
if (cur !== version) {
|
|
1893
|
+
log("next: python3 .add/tooling/add.py sync-guidelines # refresh the CLAUDE.md guidance block to this version");
|
|
1894
|
+
}
|
|
1895
|
+
const tasksDir = path.join(addDir, "tasks");
|
|
1896
|
+
let legacyBoard = false;
|
|
1897
|
+
if (fs.existsSync(tasksDir)) {
|
|
1898
|
+
for (const entry of fs.readdirSync(tasksDir, { withFileTypes: true })) {
|
|
1899
|
+
if (entry.isDirectory()
|
|
1900
|
+
&& fs.existsSync(path.join(tasksDir, entry.name, "TASK.md"))
|
|
1901
|
+
&& !fs.existsSync(path.join(tasksDir, entry.name, "PLAN.md"))) {
|
|
1902
|
+
legacyBoard = true;
|
|
1903
|
+
break;
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
if (legacyBoard) {
|
|
1908
|
+
log("next: python3 .add/tooling/add.py migrate # 1.x board detected: TASK.md -> PLAN.md, live + archived");
|
|
1909
|
+
}
|
|
1843
1910
|
}
|
|
1844
1911
|
|
|
1845
1912
|
// js-reclaim-lock-heartbeat: a test-only entrypoint so the Python subprocess suite can drive
|
|
@@ -1888,13 +1955,13 @@ async function main() {
|
|
|
1888
1955
|
case "help":
|
|
1889
1956
|
case "--help":
|
|
1890
1957
|
log("usage: npx @pilotspace/add <init|update|prune-data> [targetDir] [--force] [--check] [--no-skill] [--global] [--yes|--non-interactive]");
|
|
1891
|
-
log(" init install the ADD skill + tooling
|
|
1892
|
-
log(" (--no-skill drops the engine
|
|
1958
|
+
log(" init install the ADD skill + tooling into a project");
|
|
1959
|
+
log(" (--no-skill drops the engine only — used by the Claude Code plugin)");
|
|
1893
1960
|
log(" (--global ALSO installs to a shared home [ADD_HOME|XDG_DATA_HOME/add|~/.add] + registers the project)");
|
|
1894
1961
|
log(" (--global-data implies --global + persists this project's user-data under <home>/data/<key>)");
|
|
1895
1962
|
log(" (--from-global-data rehydrates this project's user-data FROM the shared home on a fresh clone)");
|
|
1896
1963
|
log(" (interactive in a real terminal; --yes / --non-interactive force the plain path)");
|
|
1897
|
-
log(" update re-materialize skill/tooling
|
|
1964
|
+
log(" update re-materialize skill/tooling to this package version (preserves your state)");
|
|
1898
1965
|
log(" (--global refreshes the shared home + propagates to every registered project)");
|
|
1899
1966
|
log(" prune-data remove orphaned per-project snapshots from the shared home (dry-run; --force deletes)");
|
|
1900
1967
|
break;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pilotspace/add",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "ADD (AI-Driven Development).
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "ADD (AI-Driven Development) 2.0. The agent is the hands; ADD is the memory, judgment, and conscience — a minimal, state-tracked skill: one freeze per feature, trust from passing tests, state on disk so context rot never survives a new session.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"add": "bin/cli.js"
|
|
7
7
|
},
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"!tooling/add_engine/__pycache__",
|
|
25
25
|
"!**/*.pyc",
|
|
26
26
|
"tooling/templates/",
|
|
27
|
-
"docs/",
|
|
28
27
|
"personas-teacher/",
|
|
29
28
|
"THIRD_PARTY_NOTICES.md",
|
|
30
29
|
"README.md",
|
|
@@ -11,3 +11,9 @@ KEEP: the agent-definition domain folders (engineering, security, design, produc
|
|
|
11
11
|
DROP: the upstream `.github/` CI, `scripts/`, other-tool `integrations/`, `CONTRIBUTING*`, `SECURITY.md`, and dotfiles.
|
|
12
12
|
|
|
13
13
|
Content is RAW + verbatim — regenerate with `python3 add-method/scripts/update_teacher.py`. Attribution: see the repo-root `THIRD_PARTY_NOTICES.md` and the retained `LICENSE` in this folder (MIT).
|
|
14
|
+
|
|
15
|
+
## Refresh-drift check (run on every refresh PR)
|
|
16
|
+
|
|
17
|
+
Distilled personas keep `source:` provenance pointing into this snapshot. In the refresh PR
|
|
18
|
+
description, list every `.add/personas/*.md` whose `source:` file(s) changed or moved in the
|
|
19
|
+
diff — those personas are candidates for re-distillation, otherwise their provenance rots silently.
|
package/skill/add/SKILL.md
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: add
|
|
3
3
|
description: >-
|
|
4
|
-
ADD (AI-Driven Development) — a minimal, state-tracked workflow
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
new feature and you want spec/tests-first discipline instead of vague-prompt
|
|
12
|
-
coding. Also use it to resume work across sessions (it reads `.add/state.json`
|
|
13
|
-
so you never re-read the whole repo).
|
|
4
|
+
ADD (AI-Driven Development) — a minimal, state-tracked workflow: the AI writes
|
|
5
|
+
the code, the human owns direction and verification. Drives every feature through
|
|
6
|
+
one lean PLAN.md: Specify → Scenarios → Plan → Tests → Build → Verify → Observe,
|
|
7
|
+
red/green TDD built in. Use whenever a repo has `.add/`, or the user says "add",
|
|
8
|
+
"start a task", "next phase", "specify this feature", "ADD method", "AI-driven
|
|
9
|
+
development", or wants spec/tests-first discipline over vague-prompt coding. Also
|
|
10
|
+
resumes work across sessions via `.add/state.json` (never re-read the whole repo).
|
|
14
11
|
user-invocable: true
|
|
15
12
|
category: workflows
|
|
16
13
|
keywords: [add, aidd, ai-driven-development, spec-first, tdd, contract, scenarios, verify, milestone, task-orchestration]
|
|
@@ -18,138 +15,93 @@ argument-hint: "status | init | continue | --todo <text> | [describe new short g
|
|
|
18
15
|
license: MIT
|
|
19
16
|
metadata:
|
|
20
17
|
author: add
|
|
21
|
-
version: "
|
|
18
|
+
version: "2.0.0"
|
|
22
19
|
---
|
|
23
20
|
|
|
24
|
-
# ADD — the
|
|
21
|
+
# ADD — memory · judgment · conscience (the agent is the hands)
|
|
25
22
|
|
|
26
|
-
You
|
|
23
|
+
You turn intent into the right task, then drive it. ADD keeps the AI fast *and* safe by fixing direction
|
|
27
24
|
(spec, scenarios, contract, failing tests) **before** the build, and trusting the
|
|
28
|
-
result through passing evidence
|
|
25
|
+
result through passing evidence, not a plausible diff.
|
|
29
26
|
|
|
30
|
-
**One
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
**One task = one atomic node.** Each feature is one `.add/tasks/<slug>/PLAN.md`; its frozen §3
|
|
28
|
+
(contract · scope · Target) is the interface neighbor nodes depend on — edges compile from the
|
|
29
|
+
milestone, `graph` renders the DAG, `locate` walks a failure to its node. Shard context beside it.
|
|
33
30
|
|
|
34
|
-
**The `--todo` fast-path.**
|
|
35
|
-
|
|
36
|
-
`--todo --done <id>` closes (engine errors surfaced verbatim) — then STOP.
|
|
31
|
+
**The `--todo` fast-path.** ARGUMENTS begin with `--todo`? Skip orienting: run `add.py todo`, print
|
|
32
|
+
it — `--todo <text>` captures · `--todo` lists · `--todo --done <id>` closes — then STOP.
|
|
37
33
|
|
|
38
34
|
## Always start here (orient — do not skip)
|
|
39
35
|
|
|
40
|
-
Engine: `.add/tooling/add.py
|
|
36
|
+
Engine: `.add/tooling/add.py`. Missing (a plugin install)? Materialize it once —
|
|
37
|
+
`node "${CLAUDE_PLUGIN_ROOT}/bin/cli.js" init --no-skill` drops `.add/tooling/` + the agent-agnostic
|
|
38
|
+
`CLAUDE.md` block; the skill stays in the plugin.
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
`.add/tooling/` (engine) + `.add/docs/` (book) + the agent-agnostic `CLAUDE.md` block — like an
|
|
46
|
-
npm/pip install; the skill stays in the plugin, nothing duplicated.
|
|
40
|
+
Resume from the tool, never re-read the repo — run `add.py status --brief` (cookbook), then
|
|
41
|
+
the foundation map `status --foundation` (`--all` full) + `.add/SOUL.md` (**voice**); mid-flow, trust
|
|
42
|
+
each verb's `next:` footer. Then branch on state:
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
- **No `.add/state.json` yet** (`status` says `no .add/ project found`) → **autonomous setup**: read
|
|
45
|
+
`.add/.intent` if present (the installer's first-build intent — a NOTE, never an init trigger), then
|
|
46
|
+
YOU run `add.py init --name "<inferred>" --stage <picked> --await-lock` and drive setup via
|
|
47
|
+
`phases/direction.md` (brownfield repo → map it silently, `adopt.md`) — to the human baseline `lock`.
|
|
48
|
+
- **A task is active** → open its `.add/tasks/<active>/PLAN.md`, read the `phase:` marker, work that
|
|
49
|
+
beat per the loop below.
|
|
50
|
+
- **No active task** → first SIZE the request (Intake below), then `add.py new-task`.
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
`
|
|
55
|
-
(your **voice** — tone, style, what keeps the human's trust; read it each session — human-owned and
|
|
56
|
-
self-improving via the `soul-self-improve` path). Then branch on state:
|
|
57
|
-
|
|
58
|
-
- **No `.add/state.json` yet** (`status` says `no .add/ project found`) → **autonomous setup**: if
|
|
59
|
-
`.add/.intent` exists, read it — the installer's one-line first-build intent (a NOTE, never an init
|
|
60
|
-
trigger) — to seed your kickoff; then YOU run init — `add.py init --name "<inferred>" --stage <picked>
|
|
61
|
-
--await-lock` — and read `phases/0-setup.md` to draft the foundation + §1–§3 through to the human
|
|
62
|
-
baseline approval.
|
|
63
|
-
- **A task is active** → open its `.add/tasks/<active>/TASK.md`, read the `phase:` marker, load the
|
|
64
|
-
matching `phases/<n>-<phase>.md`. Work *only* that phase.
|
|
65
|
-
- **No active task** → first SIZE the request (Intake below), then `add.py new-task <slug> --title "..."`.
|
|
66
|
-
|
|
67
|
-
**Quick ref** — `status` resume · `init` bootstrap · `advance` continue · `gate PASS` at verify.
|
|
68
|
-
**Flag mode** — two human-owned settings (never auto-picked): **fast** (task) · **auto** (mode).
|
|
69
|
-
- **fast** — `new-task --fast`: minimal template, freeze-gated; a milestone-free `--fast` task is a
|
|
70
|
-
blessed standalone low-ceremony lane. Jot ideas first with `add.py todo "<text>"` (then `todo` to
|
|
71
|
-
list · `todo --done <id>`).
|
|
72
|
-
- **auto** — `autonomy: auto` (default) auto-gates verify on evidence; lower the autonomy level with
|
|
73
|
-
`add.py autonomy set conservative|manual` for a human gate · `new-milestone --await-confirm`
|
|
74
|
-
confirm-gates a milestone's tasks.
|
|
52
|
+
**Flag mode** — ONE atomic template serves every task (no lanes); flags are header declarations.
|
|
53
|
+
- **gate_mode** — headless/agent-crossed freeze: declare `gate_mode: ai-plan-verify` in the PLAN.md
|
|
54
|
+
header + fill the §3 AI-verify record; security|data|architecture stay human-frozen (unstrikeable).
|
|
55
|
+
- **auto** — `autonomy: auto` (default) auto-gates verify on evidence; `add.py autonomy set
|
|
56
|
+
conservative|manual` restores a human gate.
|
|
75
57
|
|
|
76
58
|
## Intake — size a request before creating scope
|
|
77
59
|
|
|
78
|
-
Classify a raw request BEFORE any
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
## The
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
`
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
contracts — `streams.md`. Delegate one piece of your plan to a subagent — prefer the named roster
|
|
124
|
-
(`add-design`/`add-build`/`add-verify`/`add-persona`/`add-advisor`) over an ad-hoc spawn; when to
|
|
125
|
-
spawn, the prompt template, the tier — `advisor.md`. Self-score a draft (0–1 across six dimensions, refine if any < 0.9)
|
|
126
|
-
— `confidence.md`. Both advisory; the engine never spawns.
|
|
127
|
-
- **Small, low-risk task**, less ceremony → the **fast lane**: `new-task --fast` scaffolds the minimal
|
|
128
|
-
`TASK.fast.md`, bundle approved in one freeze — `phases/fast-lane.md`. Floor held (frozen contract ·
|
|
129
|
-
red test · verify gate; freeze-gated under any milestone). Collapse, never skip; opt-in.
|
|
130
|
-
- **UI feature** at specify → the **design-definition loop** (UDD): intake the design axes → review the
|
|
131
|
-
domain → research and reuse components → wireframe → a captured screen the human confirms **before** build — `design.md`.
|
|
132
|
-
Tool-agnostic; the engine never renders.
|
|
133
|
-
- Tasks all done but the milestone **goal** unmet → `milestone-done` holds it open; the loop turns open
|
|
134
|
-
deltas + extras into the next tasks until the goal is met — `loop.md`.
|
|
135
|
-
- `status` prints **`MVP covered → propose graduation`** (every milestone done AND stage criteria all
|
|
136
|
-
`[x]`) → `graduate.md`: `graduation-report` → co-specify interview → draft ≥1 production milestone →
|
|
137
|
-
human confirm → then `stage production`. Guarded (`stage_no_roadmap`); the FINAL step, never a bare flip.
|
|
138
|
-
- `status` prints **`→ releasable: N milestone(s) closed since last release`** → `release.md` (the 5th
|
|
139
|
-
scope level): `release-report` → draft notes from the consolidated deltas → meet the readiness floor
|
|
140
|
-
(security HARD-STOP is un-forceable) → human confirms → `add.py release <version>` records the cut
|
|
141
|
-
(CHANGELOG + `RELEASES.md` ledger + milestone attribution). The engine records; the human runs the
|
|
142
|
-
tag/publish/deploy. A release bundles ≥1 milestone, orthogonal to stage.
|
|
143
|
-
- **Monorepo / multi-repo** — a milestone spans more than one green bar (a BE + its FE) → the
|
|
144
|
-
**component pillar**: declare components in `.add/components.toml`, gate each task on its component's
|
|
145
|
-
green-bar, freeze cross-component contracts (`produces:`/`consumes:`), hold the FE until the BE
|
|
146
|
-
freezes, `federate pull` across repos — `components.md`. Opt-in; no components = today.
|
|
147
|
-
- **Project-fit personas** — the **persona loop** seeds `.add/personas/<slug>.md`, grows them via
|
|
148
|
-
observe→delta→consolidate, applies them in design/streams/advisor/build (advisory; never lowers a gate) — `docs/18-personas.md`.
|
|
149
|
-
- **Risk-class of a task** — declare `sensitivity:` in the TASK header (base `security|data|architecture|
|
|
150
|
-
mechanical`, always valid). EXTEND it with your project's domain classes in `GLOSSARY.md`'s `## Sensitivity
|
|
151
|
-
classes` section; freeze/status/check read base ∪ project. The AI keeps the domain vocabulary current —
|
|
152
|
-
`sensitivity.md`. Security is a human floor in every tier; only `mechanical` is advisor-gatable — see `advisor-gate-relax` in `run.md`.
|
|
60
|
+
Classify a raw request BEFORE any scope: read `intake.md`. Too small for scope → the **inline lane**
|
|
61
|
+
(diff + `delta-append` receipt; security·data·architecture escalates). Else one bucket — `new-major` ·
|
|
62
|
+
`sub-milestone` · `task` · `change-request` — propose `{ bucket, rationale, command }`; the human
|
|
63
|
+
confirms. Unsharp intent? **Interview before you size** (`intake.md`). A milestone bucket: draft
|
|
64
|
+
`MILESTONE.md` (goal · scope · exit criteria · breadth-first tasks — `phases/direction.md`), then the
|
|
65
|
+
`new-milestone`/`milestone-confirm` pair below (new-task inherits each node's depends-on). A
|
|
66
|
+
`task`/`change-request`: `add.py new-task`, then beat 1 above.
|
|
67
|
+
|
|
68
|
+
## The 3-beat loop (this file IS the loop; references load on demand)
|
|
69
|
+
|
|
70
|
+
Every task is three beats (seven steps, folded), three engine calls, ONE human decision:
|
|
71
|
+
|
|
72
|
+
1. **DIRECTION** — load the domain-fit persona (seed via add-worker persona-mode if none), then draft
|
|
73
|
+
the whole bundle top-to-bottom in PLAN.md: §1 rules + ranked ⚠ flag (co-specify) ·
|
|
74
|
+
§2 scenarios · §3 PLAN (grounding → frozen contract shape → build-strategy + Scope + Target) · §4 red suite
|
|
75
|
+
(run it — red for the RIGHT reason; fill each bullet's `covers:` clause key). Then the ONE approval,
|
|
76
|
+
presented lowest-confidence-first: `add.py freeze` (a setup session's baseline `lock` IS this approval).
|
|
77
|
+
2. **BUILD** — code in `src/` until every red is green; change no test, no frozen contract; stay
|
|
78
|
+
inside the §3 Scope. A test OUTSIDE your suite failing? `add.py locate` names the owning node, the
|
|
79
|
+
failure class, the frozen §3 clause it proves, and who re-verifies if a settled contract must move.
|
|
80
|
+
3. **VERIFY** — confirm evidence · 3 lenses (**security always HARD-STOP**) · earned-green
|
|
81
|
+
refute-read · then `add.py gate PASS` (from build it compound-crosses; under `autonomy: auto` a
|
|
82
|
+
run auto-PASSes on complete no-residue evidence — *auto-resolved*, an explicit PASS, never a skip; residue or
|
|
83
|
+
lowered autonomy → human — `run.md`).
|
|
84
|
+
|
|
85
|
+
Stuck or deep? On demand: `phases/direction.md` · `phases/build.md` · `phases/verify.md` · opaque
|
|
86
|
+
term? `terms.md`. Delegating? Spawn the roster agent — it loads its own refs (you read ONLY this file).
|
|
87
|
+
|
|
88
|
+
At each decision point (intake · bundle · gate · close) the fitting persona OWNS the gate report —
|
|
89
|
+
`gate-udd.md` (read once per session) holds the principles: CONVEY decision + ARC (engine-sourced) ·
|
|
90
|
+
shape · flags (lowest-first) · evidence · a guided APPROVE. The persona owns the form, never the four
|
|
91
|
+
floors (security stays HARD-STOP) — the question is a summary, never the artifact.
|
|
92
|
+
|
|
93
|
+
Emit **lessons learned** tagged by which of the five (`DDD · SDD · UDD · TDD · ADD`) they improve —
|
|
94
|
+
in-flight, via `delta-append` → its living spec in `.add/specs/`. The living specs
|
|
95
|
+
ARE the foundation; the close counts what §7 still holds open. Observe also tunes your voice: a
|
|
96
|
+
confirmable delta the human confirms rewrites `SOUL.md` (the human is the only writer) — `deltas.md`.
|
|
97
|
+
|
|
98
|
+
## Beyond the bundle — one trigger = one guide (full prose: `beyond.md`); load only on a trigger
|
|
99
|
+
|
|
100
|
+
- §3 FROZEN → auto-gated run `run.md` · subagent roster + pipelines (agent-call-preferred, the
|
|
101
|
+
default execution mode) → `phases/verify.md` · self-score → `phases/direction.md`
|
|
102
|
+
- UI/experience surface → UDD loop `design.md` · milestone goal unmet at `milestone-done` → `loop.md`
|
|
103
|
+
- graduation · release · monorepo green-bars → persona-owned playbooks, `beyond.md` ·
|
|
104
|
+
the persona loop (`.add/personas/`) → `docs/18-personas.md` · `sensitivity:`/`advisor-gate-relax` → `phases/verify.md`
|
|
153
105
|
|
|
154
106
|
## Non-negotiable rules (from the method)
|
|
155
107
|
|
|
@@ -158,35 +110,39 @@ once the human confirms, rewrites `SOUL.md` (the human is the only writer) — `
|
|
|
158
110
|
2. **Trust evidence, not inspection.** A feature is trusted because its tests pass and the
|
|
159
111
|
non-functional risks (concurrency, security, architecture) were checked — not because the code
|
|
160
112
|
reads plausibly.
|
|
161
|
-
3. **Never weaken a test or edit a frozen contract to make the build pass.** That inverts the
|
|
162
|
-
A real change is a *change request* back to Specify.
|
|
113
|
+
3. **Never weaken a test or edit a frozen contract to make the build pass.** That inverts the
|
|
114
|
+
method. A real change is a *change request* back to Specify.
|
|
163
115
|
4. **No silent skips.** Every Verify ends in exactly one recorded outcome: `PASS`, `RISK-ACCEPTED`
|
|
164
116
|
(signed, non-security only), or `HARD-STOP`. A security finding is always `HARD-STOP`.
|
|
165
|
-
5. **Ask, don't guess.** If a requirement is unclear, stop and ask the user.
|
|
166
117
|
</constraints>
|
|
167
118
|
|
|
168
|
-
##
|
|
119
|
+
## Command cookbook — copy a line; `-h` only off-menu
|
|
169
120
|
|
|
170
|
-
|
|
121
|
+
`add.py` = `python3 .add/tooling/add.py`; lines 2–4 = the 3-call walk (`advance --fill <draft>` = step-wise).
|
|
171
122
|
|
|
172
123
|
```bash
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
124
|
+
add.py status --brief # resume · status --section <n|phase> = §body · --foundation · --json
|
|
125
|
+
add.py new-task <slug> --title "..." # --milestone m · --depends-on a,b · --sensitivity security
|
|
126
|
+
add.py freeze --by "<name>" --cross # the ONE approval -> build (--ai-plan-verify = headless)
|
|
127
|
+
add.py gate PASS --target-hit yes # partial|no · RISK-ACCEPTED --owner --ticket --expires
|
|
128
|
+
add.py locate tests/x.py::test_y # failure -> owning node + its frozen §3 clause
|
|
129
|
+
add.py graph --milestone <slug> # mermaid DAG · relate <slug> --depends-on|--extends
|
|
130
|
+
add.py delta-append tdd "<lesson>" # lens: ddd|sdd|udd|tdd|add
|
|
131
|
+
add.py new-milestone <slug> --title "..." --goal "..." --await-confirm # confirm-gates its tasks
|
|
132
|
+
add.py milestone-confirm <slug> --by "<name>" # compiles Tasks -> DAG; unlocks new-task
|
|
133
|
+
add.py report [<milestone>|<task>] --decide # rollup/drill-in · check · search · use
|
|
176
134
|
```
|
|
177
135
|
|
|
178
136
|
## Depth by stage
|
|
179
137
|
|
|
180
|
-
|
|
138
|
+
Steps never change; depth does (`add.py status`):
|
|
181
139
|
|
|
182
|
-
- **prototype** —
|
|
183
|
-
- **poc** —
|
|
140
|
+
- **prototype** — light; throwaway code; design/experience is the point.
|
|
141
|
+
- **poc** — contract/tests/build deep on the single riskiest slice only.
|
|
184
142
|
- **mvp** — full flow, narrow scope, light observation.
|
|
185
|
-
- **production** —
|
|
186
|
-
|
|
143
|
+
- **production** — full rigor + the observe loop; reached via the graduation playbook
|
|
144
|
+
(`beyond.md`), never a bare `stage production` flip.
|
|
187
145
|
|
|
188
|
-
|
|
146
|
+
The **method rationale** (the *why*) lives in the AIDD book — https://pilotspace.github.io/ADD/ (the `docs/…` chapters the
|
|
147
|
+
guides cite). Read it when a decision is genuinely unclear; never duplicate it here.
|
|
189
148
|
|
|
190
|
-
The full method (the *why* behind every rule) is the AIDD book in `.add/docs/`. When a phase decision is
|
|
191
|
-
genuinely unclear, read the linked chapter — each phase guide points to its chapter. Do not duplicate
|
|
192
|
-
the book here; load it on demand.
|
package/skill/add/adopt.md
CHANGED
|
@@ -35,6 +35,34 @@ Fill each living-doc file in `.add/` from what the code shows — **ask nothing*
|
|
|
35
35
|
2. **Tag every drafted decision `evidence-grounded` vs `guessed`.** A line you read from the code is *evidence-grounded* (cite the file). A line you inferred because the code was silent is *guessed*. The human's single baseline approval is only honest if they can see which is which — the guesses are what they actually need to check. (The tags feed `SETUP-REVIEW.md`.)
|
|
36
36
|
</constraints>
|
|
37
37
|
|
|
38
|
+
## Setup review — the one page the human signs
|
|
39
|
+
|
|
40
|
+
Both setup paths (this brownfield map AND the greenfield draft, `phases/direction.md`) end at
|
|
41
|
+
the same single human gate, and `SETUP-REVIEW.md` is that page: every decision you made while
|
|
42
|
+
drafting the foundation, first-scope, and first contract, ordered **lowest-confidence-first** so
|
|
43
|
+
the riskiest guesses meet the human's eye first. The engine never reads it — `add.py lock` is
|
|
44
|
+
judgment-free; the human *reading* this page is the review. Write ONE artifact at
|
|
45
|
+
`.add/SETUP-REVIEW.md`, beside `PROJECT.md` (never clobber a human-edited one — append/update):
|
|
46
|
+
|
|
47
|
+
```markdown
|
|
48
|
+
# SETUP REVIEW — <project>
|
|
49
|
+
|
|
50
|
+
<stage> · <brownfield | greenfield> · drafted by <model> @ <date>
|
|
51
|
+
|
|
52
|
+
| # | Decision | Lands in | Tag | Why / Evidence |
|
|
53
|
+
|---|----------|----------|-----|----------------|
|
|
54
|
+
| 1 | <the drafted decision> | PROJECT.md \| scope \| first-contract | `guessed` | <the inference + why you had to guess> |
|
|
55
|
+
| 2 | <…> | <…> | `evidence-grounded` | <cite the source file/line you read it from> |
|
|
56
|
+
|
|
57
|
+
Sign: confirm in chat → the agent runs `add.py lock --by "<name>"` (typing it yourself works too)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The two rules that make it honest: rows sort by confidence **ascending** — a `guessed` row
|
|
61
|
+
always floats above an `evidence-grounded` one (the top of the table is what the human must
|
|
62
|
+
actually challenge); and EVERY row is tagged with the shared vocabulary above (`guessed` = the
|
|
63
|
+
repo was silent, state the inference; `evidence-grounded` = cite the file). Rows are numbered
|
|
64
|
+
for reference at the gate. Present it lowest-confidence-first, not field-by-field.
|
|
65
|
+
|
|
38
66
|
## Where it ends — the baseline approval
|
|
39
67
|
|
|
40
68
|
Brownfield onboarding draws no per-step approvals: map the foundation, draft the first milestone's scope and first task's candidate specification bundle, then present it all at **one** human gate. The human reviews decisions (`guessed` first) and confirms; you run the lock:
|