pi-aia-asf 0.2.2 → 0.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 +74 -0
- package/README.md +3 -0
- package/index.ts +151 -9
- package/package.json +5 -2
- package/skills/aia-asf/SKILL.md +32 -8
- package/skills/aia-asf/references/01-intake.md +18 -0
- package/skills/aia-asf/references/04-adversarial.md +6 -0
- package/skills/aia-asf/references/05-plan.md +8 -0
- package/skills/aia-asf/references/06-implementation.md +23 -0
- package/skills/aia-asf/references/06b-testing-qa.md +50 -0
- package/skills/aia-asf/references/06d-delegation.md +130 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,80 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-08-28
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Delegation reference `references/06d-delegation.md`** — codifies the two
|
|
15
|
+
delegation mechanisms available to ASF work: **intercom** (message another
|
|
16
|
+
live pi session that owns relevant context — `list` first, say what you want
|
|
17
|
+
back, treat peer findings as evidence, not proof) and **subagents** (spawn an
|
|
18
|
+
isolated `pi -p` process when the OUTCOME matters more than the trace — scoped
|
|
19
|
+
codebase research, independent parallel fixes, fresh-perspective review).
|
|
20
|
+
- **Two verified hard limits, backed by experiment** (both documented as
|
|
21
|
+
anti-patterns in SKILL.md):
|
|
22
|
+
- **Never run parallel subagents against the same file.** Tested: 4 concurrent
|
|
23
|
+
whole-file writers left only 1 of 4 edits, silently, all exiting 0 — the
|
|
24
|
+
no-mutual-dependencies rule is enforced by physics, not preference.
|
|
25
|
+
- **Exit code 0 does not mean success.** Tested: a subagent asked to read a
|
|
26
|
+
non-existent file exited 0. Always validate the returned output.
|
|
27
|
+
- **`pi-intercom` as a declared dependency** (`dependencies` in package.json,
|
|
28
|
+
`^0.10.1`) — `npm install` pulls it in. Intentionally **not bundled**: a
|
|
29
|
+
bundled copy conflicts with a top-level `pi install npm:pi-intercom`
|
|
30
|
+
(tool-name collision, verified), so the tool must be installed top-level to
|
|
31
|
+
register. Added to the ASF runtime dependency check (`/asf` summary now lists
|
|
32
|
+
all five: pi-vigilant, pi-smart-web-search, pi-smart-fetch, pi-aia-browser,
|
|
33
|
+
pi-intercom).
|
|
34
|
+
- **SKILL.md wiring** — Phase 6 delegation note, reference index entry, and
|
|
35
|
+
three new anti-patterns (same-file parallel subagents, trusting subagent exit
|
|
36
|
+
codes/self-reports, re-deriving context another live session already has).
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- README dependencies table now lists pi-intercom with the not-bundled rationale.
|
|
41
|
+
|
|
42
|
+
## [0.3.0] - 2026-08-25
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **Mechanical spec-to-code traceability gate in `/asf verify`** (large work
|
|
47
|
+
only) — reads the shared spec-memory task and validates every `met` spec's
|
|
48
|
+
trace (`outcome → codePath → testFile + assertion`); `testFile` must exist
|
|
49
|
+
and `assertion` must appear in it. Outputs a traceability matrix with
|
|
50
|
+
PASS/FAIL rows and refuses delivery on FAIL (`GATE NOT PASSED`). Small work
|
|
51
|
+
keeps the checklist only — no mechanical gate (scale proportionality).
|
|
52
|
+
- **New QA rules (06b-testing-qa.md)**: Rule 12 — test the operator-facing
|
|
53
|
+
outcome, not the machinery (Betamaxx dead-code failure); Rule 13 — nothing
|
|
54
|
+
is delivered until consumed by a surface (UI or API); Rule 14 — every
|
|
55
|
+
feature spec ships an E2E behavioral test through the real entry point.
|
|
56
|
+
Rule 9 extended for silent async paths; Rule 10 DoD extended (traceability,
|
|
57
|
+
consumed-by-surface, E2E).
|
|
58
|
+
- **M4 — challenge approved designs during implementation** (06-implementation.md):
|
|
59
|
+
product tension → resolve with the user before implementing.
|
|
60
|
+
- **M5 — the delivery log is a claim; the code is the evidence**: trace the
|
|
61
|
+
actual code path before marking anything delivered.
|
|
62
|
+
- **M6 — external planning docs are specs, not ground truth** (01-intake.md +
|
|
63
|
+
SKILL.md Phase 1/3): locate IMPROVEMENT-PLAN.md / PLAN.md / requirements
|
|
64
|
+
docs / delivery logs / tickets, ingest every actionable item as a captured
|
|
65
|
+
spec; their ✅ markers are claims, not evidence.
|
|
66
|
+
- **Adversarial traceability lens** (04-adversarial.md): operator-facing
|
|
67
|
+
outcome + code path + where dead wiring hides.
|
|
68
|
+
- **PLAN.md traceability matrix** (05-plan.md): spec → outcome → code path →
|
|
69
|
+
test.
|
|
70
|
+
- DoD checklist extended; anti-patterns added (delivery-log trust, machinery
|
|
71
|
+
without a surface, unit tests as wiring proof, external plan checkmarks,
|
|
72
|
+
literal implementation of tension-creating specs).
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- `/asf verify` output now shows scale and, for large work, the mechanical
|
|
77
|
+
traceability matrix before the DoD checklist.
|
|
78
|
+
|
|
79
|
+
### Requires
|
|
80
|
+
|
|
81
|
+
- pi-vigilant 0.1.3+ (provides the `trace` field on specs).
|
|
82
|
+
|
|
83
|
+
|
|
10
84
|
## [0.2.2] - 2026-08-14
|
|
11
85
|
|
|
12
86
|
### Added
|
package/README.md
CHANGED
|
@@ -41,6 +41,9 @@ You can also force/start a session explicitly:
|
|
|
41
41
|
| **pi-smart-web-search** | `web_search` | `pi install npm:pi-smart-web-search` |
|
|
42
42
|
| **pi-smart-fetch** | `web_fetch`, `batch_web_fetch` | `pi install npm:pi-smart-fetch` |
|
|
43
43
|
| **pi-aia-browser** | `browser_init`, `browser_navigate`, … (Playwright + Chromium, auto-installed) | `pi install npm:pi-aia-browser` |
|
|
44
|
+
| **pi-intercom** | `intercom` — message other live pi sessions directly (delegation, cross-session verification) | `pi install npm:pi-intercom` |
|
|
45
|
+
|
|
46
|
+
`pi-intercom` is also declared in `dependencies` in `package.json`, so `npm install` of this package pulls it in. It is intentionally **not bundled** into the tarball: bundling it would conflict with a top-level `pi install npm:pi-intercom` (tool name collision), so the tool must be installed at top level to register.
|
|
44
47
|
|
|
45
48
|
The extension warns at startup (and on `/asf` with no args) when any dependency is missing.
|
|
46
49
|
|
package/index.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
15
15
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
16
|
-
import { existsSync } from "node:fs";
|
|
16
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
17
17
|
import { join } from "node:path";
|
|
18
18
|
import { homedir } from "node:os";
|
|
19
19
|
|
|
@@ -51,9 +51,29 @@ const QA_CHECKLIST: Array<{ key: string; label: string }> = [
|
|
|
51
51
|
{ key: "observable", label: "Observable end state verified as a user would experience it" },
|
|
52
52
|
{ key: "browser", label: "Web surfaces exercised through a real browser (n/a if none)" },
|
|
53
53
|
{ key: "specs", label: "Every MUST spec 'met' with concrete evidence" },
|
|
54
|
+
{ key: "trace", label: "Spec-to-code traceability: every met spec has outcome → codePath → test" },
|
|
55
|
+
{ key: "surface", label: "Every delivered feature is consumed by a surface (UI or API) — nothing dead" },
|
|
56
|
+
{ key: "e2e", label: "Feature specs have an end-to-end behavioral test through the real entry point" },
|
|
54
57
|
{ key: "honest", label: "Skipped/inconclusive checks reported explicitly" },
|
|
55
58
|
];
|
|
56
59
|
|
|
60
|
+
/** Spec-to-code traceability (M1) — mirrors pi-vigilant's Trace. */
|
|
61
|
+
interface Trace {
|
|
62
|
+
outcome: string;
|
|
63
|
+
codePath: string;
|
|
64
|
+
testFile?: string;
|
|
65
|
+
assertion?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface SpecItem {
|
|
69
|
+
id: string;
|
|
70
|
+
requirement: string;
|
|
71
|
+
area: string;
|
|
72
|
+
priority: string;
|
|
73
|
+
status: string;
|
|
74
|
+
trace?: Trace;
|
|
75
|
+
}
|
|
76
|
+
|
|
57
77
|
interface ProjectStateFile {
|
|
58
78
|
current: AsfState | null;
|
|
59
79
|
history: Array<{ workType: string; phase: AsfPhase; startedAt: string; endedAt: string }>;
|
|
@@ -94,6 +114,61 @@ async function saveState(project: string, data: ProjectStateFile): Promise<void>
|
|
|
94
114
|
await writeFile(file, JSON.stringify(data, null, 2), "utf-8");
|
|
95
115
|
}
|
|
96
116
|
|
|
117
|
+
// ─── Spec-memory read (shared with pi-vigilant) ────────────────────────────
|
|
118
|
+
|
|
119
|
+
const SPEC_DIR = join(SKILLS_DIR, "spec-memory", "projects");
|
|
120
|
+
|
|
121
|
+
function specTaskFileFor(project: string): string {
|
|
122
|
+
return join(SPEC_DIR, project, "current-task.json");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function loadSpecs(project: string): Promise<SpecItem[] | null> {
|
|
126
|
+
const file = specTaskFileFor(project);
|
|
127
|
+
if (!existsSync(file)) return null;
|
|
128
|
+
try {
|
|
129
|
+
const task = JSON.parse(await readFile(file, "utf-8")) as {
|
|
130
|
+
areas?: Record<string, SpecItem[]>;
|
|
131
|
+
};
|
|
132
|
+
return Object.values(task.areas || {}).flat();
|
|
133
|
+
} catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Mechanical M1 validation of a met spec's trace. */
|
|
139
|
+
function validateTrace(spec: SpecItem): { ok: boolean; reason: string } {
|
|
140
|
+
const t = spec.trace;
|
|
141
|
+
if (!t || !t.outcome || !t.codePath) {
|
|
142
|
+
return {
|
|
143
|
+
ok: false,
|
|
144
|
+
reason: "met but trace incomplete — outcome + codePath required (add via update_spec_status trace)",
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (t.testFile) {
|
|
148
|
+
const abs = join(process.cwd(), t.testFile);
|
|
149
|
+
if (!existsSync(abs)) {
|
|
150
|
+
return { ok: false, reason: `testFile not found: ${t.testFile}` };
|
|
151
|
+
}
|
|
152
|
+
if (t.assertion) {
|
|
153
|
+
let content = "";
|
|
154
|
+
try {
|
|
155
|
+
content = readFileSync(abs, "utf-8");
|
|
156
|
+
} catch {
|
|
157
|
+
/* unreadable → treat as missing */
|
|
158
|
+
}
|
|
159
|
+
if (!content.includes(t.assertion)) {
|
|
160
|
+
return { ok: false, reason: `assertion not found in ${t.testFile}: "${t.assertion}"` };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
ok: true,
|
|
166
|
+
reason: !t.testFile
|
|
167
|
+
? "trace complete (no testFile — ensure this is verifiable by inspection, or add an E2E test per 06b Rule 14)"
|
|
168
|
+
: "trace complete",
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
97
172
|
// ─── Dependency check ──────────────────────────────────────────────────────
|
|
98
173
|
|
|
99
174
|
interface DependencyCheck {
|
|
@@ -140,6 +215,12 @@ function checkDependencies(): DependencyCheck[] {
|
|
|
140
215
|
existsSync(join(gitDir, "github.com", "brunoj", "pi-aia-browser")),
|
|
141
216
|
hint: "pi install npm:pi-aia-browser (installs Playwright + Chromium)",
|
|
142
217
|
},
|
|
218
|
+
{
|
|
219
|
+
name: "pi-intercom (intercom: message other pi sessions)",
|
|
220
|
+
package: "pi-intercom",
|
|
221
|
+
present: existsSync(join(npmDir, "pi-intercom")),
|
|
222
|
+
hint: "pi install npm:pi-intercom",
|
|
223
|
+
},
|
|
143
224
|
];
|
|
144
225
|
|
|
145
226
|
return checks;
|
|
@@ -149,7 +230,7 @@ function dependencySummary(): string {
|
|
|
149
230
|
const checks = checkDependencies();
|
|
150
231
|
const missing = checks.filter((c) => !c.present);
|
|
151
232
|
if (missing.length === 0) {
|
|
152
|
-
return "All ASF dependencies present: pi-vigilant, pi-smart-web-search, pi-smart-fetch, pi-aia-browser ✓";
|
|
233
|
+
return "All ASF dependencies present: pi-vigilant, pi-smart-web-search, pi-smart-fetch, pi-aia-browser, pi-intercom ✓";
|
|
153
234
|
}
|
|
154
235
|
return (
|
|
155
236
|
"⚠️ ASF dependencies missing — install before starting a project:\n" +
|
|
@@ -225,18 +306,79 @@ export default function register(pi: ExtensionAPI): void {
|
|
|
225
306
|
}
|
|
226
307
|
case "verify": {
|
|
227
308
|
// Gate 7: force an explicit, itemised QA pass before delivery.
|
|
309
|
+
// Large work: mechanical spec-to-code traceability gate (M1).
|
|
228
310
|
const project = projectName();
|
|
229
311
|
const state = await loadState(project);
|
|
230
312
|
if (!state.current) return "No active ASF session — nothing to verify.";
|
|
231
313
|
await setPhase(ctx, "verification");
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
`
|
|
235
|
-
`
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
314
|
+
const scale = state.current.scale;
|
|
315
|
+
const lines: string[] = [
|
|
316
|
+
`ASF verification gate (${project}) — Definition of Done.`,
|
|
317
|
+
`Scale: ${scale || "unset"}${
|
|
318
|
+
scale === "large"
|
|
319
|
+
? " — mechanical traceability gate ACTIVE"
|
|
320
|
+
: scale === "small"
|
|
321
|
+
? " (automatic — no mechanical gate)"
|
|
322
|
+
: ""
|
|
323
|
+
}`,
|
|
324
|
+
];
|
|
325
|
+
|
|
326
|
+
if (scale === "large") {
|
|
327
|
+
const specs = await loadSpecs(project);
|
|
328
|
+
lines.push("\nSPEC-TO-CODE TRACEABILITY (M1 — large work):");
|
|
329
|
+
if (!specs || specs.length === 0) {
|
|
330
|
+
lines.push(
|
|
331
|
+
" (no spec-memory task found — capture specs with capture_spec, incl. items from external planning docs)",
|
|
332
|
+
);
|
|
333
|
+
} else {
|
|
334
|
+
const metSpecs = specs.filter((s) => s.status === "met");
|
|
335
|
+
if (metSpecs.length === 0) {
|
|
336
|
+
lines.push(
|
|
337
|
+
" (no specs marked met yet — traceability applies when closing specs)",
|
|
338
|
+
);
|
|
339
|
+
} else {
|
|
340
|
+
let allOk = true;
|
|
341
|
+
for (const spec of metSpecs) {
|
|
342
|
+
const check = validateTrace(spec);
|
|
343
|
+
if (!check.ok) allOk = false;
|
|
344
|
+
lines.push(` [${check.ok ? "PASS" : "FAIL"}] ${spec.id}: ${check.reason}`);
|
|
345
|
+
if (check.ok && spec.trace) {
|
|
346
|
+
lines.push(` outcome: ${spec.trace.outcome}`);
|
|
347
|
+
lines.push(` code path: ${spec.trace.codePath}`);
|
|
348
|
+
if (spec.trace.testFile) {
|
|
349
|
+
lines.push(
|
|
350
|
+
` test: ${spec.trace.testFile}${spec.trace.assertion ? ` (asserts "${spec.trace.assertion}")` : ""}`,
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
lines.push(
|
|
356
|
+
allOk
|
|
357
|
+
? "\n ✓ All met specs have complete traces."
|
|
358
|
+
: "\n ✗ GATE NOT PASSED — resolve FAIL rows before delivery (attach trace via update_spec_status).",
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
lines.push(
|
|
365
|
+
"\nDefinition of Done checklist (references/06b-testing-qa.md Rule 10):",
|
|
366
|
+
);
|
|
367
|
+
lines.push(
|
|
368
|
+
"Read references/06b-testing-qa.md. Confirm EACH item with concrete evidence",
|
|
369
|
+
);
|
|
370
|
+
lines.push(
|
|
371
|
+
"(command output, file list, screenshot). Do not tick anything you did not run.",
|
|
372
|
+
);
|
|
373
|
+
lines.push("");
|
|
374
|
+
QA_CHECKLIST.forEach((c, i) => lines.push(` ${i + 1}. [ ] ${c.label}`));
|
|
375
|
+
lines.push(
|
|
376
|
+
"\nThen run get_task_specs and close every spec with update_spec_status.",
|
|
377
|
+
);
|
|
378
|
+
lines.push(
|
|
379
|
+
"Unverifiable → 'partial' + ask the user. Never self-certify.",
|
|
239
380
|
);
|
|
381
|
+
return lines.join("\n");
|
|
240
382
|
}
|
|
241
383
|
case "abort":
|
|
242
384
|
return await setPhase(ctx, "none");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-aia-asf",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Ai Applied Agentic Software Factory — codifies the full software development flow: intake, research, spec capture, adversarial analysis, planning with approval gates, test-first implementation, and release. Requires pi-vigilant, pi-smart-web-search, pi-smart-fetch,
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Ai Applied Agentic Software Factory — codifies the full software development flow: intake, research, spec capture, adversarial analysis, planning with approval gates, test-first implementation, and release. Requires pi-vigilant, pi-smart-web-search, pi-smart-fetch, pi-aia-browser, and pi-intercom.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
7
7
|
"software-factory",
|
|
@@ -48,6 +48,9 @@
|
|
|
48
48
|
"@earendil-works/pi-coding-agent": "*",
|
|
49
49
|
"typebox": "*"
|
|
50
50
|
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"pi-intercom": "^0.10.1"
|
|
53
|
+
},
|
|
51
54
|
"peerDependenciesMeta": {
|
|
52
55
|
"@earendil-works/pi-ai": {
|
|
53
56
|
"optional": false
|
package/skills/aia-asf/SKILL.md
CHANGED
|
@@ -70,6 +70,7 @@ Minimum intake checklist (ask anything not yet known, one question at a time or
|
|
|
70
70
|
- **Constraints** — musts, must-nots, boundaries, budget, timeline
|
|
71
71
|
- **Preferences** — stack, language, platform, style (only if the user has them)
|
|
72
72
|
- **Definition of done** — tests? deploy? release? docs?
|
|
73
|
+
- **External planning docs** — are there IMPROVEMENT-PLAN.md / PLAN.md / requirements docs / delivery logs / ticket lists? Locate them (repo root, `docs/`, referenced by the user); they are inputs to spec capture, not ground truth.
|
|
73
74
|
|
|
74
75
|
For each answer, **capture hard requirements immediately with `capture_spec`** (requirement, area, priority). Specs are the shared contract with pi-vigilant — it will re-verify them at the end.
|
|
75
76
|
|
|
@@ -105,9 +106,10 @@ Turn the intake answers + research into the authoritative spec set.
|
|
|
105
106
|
|
|
106
107
|
1. Run `get_task_specs` to see what's already captured.
|
|
107
108
|
2. Fill gaps: for every requirement the user stated or approved, ensure a spec exists (`capture_spec`).
|
|
108
|
-
3.
|
|
109
|
-
4.
|
|
110
|
-
5.
|
|
109
|
+
3. **Ingest external planning docs (M6):** every actionable item in an external planning doc (IMPROVEMENT-PLAN.md, PLAN.md, requirements docs, delivery logs, ticket lists) becomes a captured spec with `sourceQuote` pointing at the doc + item id. The doc's own ✅/delivered markers are **claims, not evidence** — each item gets traced and verified like any other spec.
|
|
110
|
+
4. Decompose broad specs with `parentId` (e.g. "must be secure" → auth + encryption sub-specs).
|
|
111
|
+
5. Default priority is `must`; use `should` only when the user says "nice to have".
|
|
112
|
+
6. Areas: functionality, ui-ux, performance, security, error-handling, testing, documentation, compatibility, constraints, format, data, deployment, other.
|
|
111
113
|
|
|
112
114
|
**Gate 3** (large only): show the full spec tree (`get_task_specs`) and get user sign-off: "specs correct — proceed to adversarial analysis?" Small work: capture specs silently, no sign-off needed.
|
|
113
115
|
|
|
@@ -180,6 +182,15 @@ Keep the plan **implementation-ready**: any competent engineer (or agent) can ex
|
|
|
180
182
|
> understand; layered with clear boundaries and an architecture writeup; full I/O debug
|
|
181
183
|
> logging with replay; nothing breaks existing functionality.
|
|
182
184
|
|
|
185
|
+
> **Read `references/06d-delegation.md` before delegating.** Work may be delegated two ways:
|
|
186
|
+
> **intercom** (message another live pi session that owns relevant context — always `list`
|
|
187
|
+
> first, say what you want back, and treat their findings as evidence, not proof), and
|
|
188
|
+
> **subagents** (spawn an isolated `pi -p` process when the OUTCOME matters more than the
|
|
189
|
+
> trace — scoped codebase research, independent parallel fixes, fresh-perspective review).
|
|
190
|
+
> Two verified hard limits: **never run parallel subagents against the same file** — tested,
|
|
191
|
+
> 4 concurrent writers left only 1 of 4 edits, silently, all exiting 0 — and **exit code 0
|
|
192
|
+
> does not mean success**, so always validate the returned output against what you asked for.
|
|
193
|
+
|
|
183
194
|
Execute the task list milestone by milestone. Discipline rules:
|
|
184
195
|
|
|
185
196
|
1. **Test-first**: write/update tests before or with implementation; run them; only commit green.
|
|
@@ -188,9 +199,11 @@ Execute the task list milestone by milestone. Discipline rules:
|
|
|
188
199
|
2. **Codebase isolation**: work strictly inside the project's own codebase. Do NOT edit files in other repos, global config, or unrelated directories — **unless the user explicitly instructs otherwise**. If a change would touch another codebase, stop and ask.
|
|
189
200
|
3. **No scope creep**: if something new is discovered that changes specs, capture it, ask the user, and update the plan before implementing.
|
|
190
201
|
4. **Descriptive commits**: `git commit -m "type: specific description of what and why"` (e.g. `fix: verify specs before rotation`). No vague messages, no placeholders.
|
|
191
|
-
5. **Browser testing — MANDATORY for any web interface**: if the deliverable has a UI/website/web app, test it through `pi-aia-browser` (`browser_init`, `browser_navigate`, `browser_click`, `browser_type`, `browser_screenshot`, `browser_dom`, …) to replicate the user's real experience — not just curl/API checks. Verify: loads, key user journeys, responsive behavior, console errors.
|
|
202
|
+
5. **Browser testing — MANDATORY for any web interface**: if the deliverable has a UI/website/web app, test it through `pi-aia-browser` (`browser_init`, `browser_navigate`, `browser_click`, `browser_type`, `browser_screenshot`, `browser_dom`, …) to replicate the user's real experience — not just curl/API checks. Verify: loads, key user journeys, responsive behavior, console errors. **Silent async paths included**: ingest through the real flow and wait for the enrichment to land (06b Rule 9).
|
|
192
203
|
6. **Let pi-vigilant do its job**: it will auto-continue after premature stops and verify specs at settle. When it asks for `update_spec_status` with evidence, do it.
|
|
193
204
|
7. **CHANGELOG discipline**: every user-visible change gets a CHANGELOG entry describing exactly what changed (no placeholder text).
|
|
205
|
+
8. **Challenge approved designs (M4)**: if a spec's literal reading creates product tension (e.g. feedback clusters under "Plan" when "Plan = plans"), stop and resolve it with the user before implementing — never implement blindly and call it delivered.
|
|
206
|
+
9. **Trace before claiming delivered (M5)**: the delivery log is a claim; the code is the evidence. Before marking anything ✅, trace the actual code path, confirm the output is consumed by a surface, and confirm the operator-facing outcome test passes.
|
|
194
207
|
|
|
195
208
|
---
|
|
196
209
|
|
|
@@ -200,6 +213,8 @@ Run the **Definition of Done checklist** in `references/06b-testing-qa.md` (Rule
|
|
|
200
213
|
|
|
201
214
|
Also check the **modularity DoD** from `references/06c-code-quality.md` (Phase 7 section): no duplicated shared logic, no hardcoded config values, every module tested standalone with the same calls it gets in the host, architecture writeup exists, existing functionality still green.
|
|
202
215
|
|
|
216
|
+
**Large work:** run `/asf verify` — it mechanically validates the **spec-to-code traceability matrix** (M1): every `met` spec must carry `trace` (outcome → codePath → testFile + assertion), testFile must exist, assertion must appear in it. FAIL rows block delivery. **Verify ingested specs from external planning docs too** — the doc's ✅ markers are claims, not evidence.
|
|
217
|
+
|
|
203
218
|
1. Run the full test suite (all of it, not a subset); fix failures; re-run until green.
|
|
204
219
|
2. **Verify the artifact a user would actually get**: inspect the packaged file list
|
|
205
220
|
(`npm pack` → `tar tzf`), install/load it clean-room in a fresh dir with caches
|
|
@@ -240,15 +255,24 @@ Also check the **modularity DoD** from `references/06c-code-quality.md` (Phase 7
|
|
|
240
255
|
- ❌ Escalation/fallback logic re-implemented per caller instead of one shared escalation path
|
|
241
256
|
- ❌ Shipping a module that cannot run/test standalone outside the host
|
|
242
257
|
- ❌ Refactoring without the architecture writeup (see `references/06c-code-quality.md`)
|
|
258
|
+
- ❌ Running parallel subagents that touch the same file — edits are silently lost (see `references/06d-delegation.md`)
|
|
259
|
+
- ❌ Trusting a subagent's exit code or self-report instead of verifying the actual code/test result
|
|
260
|
+
- ❌ Re-deriving context another live session already has instead of asking it over intercom
|
|
243
261
|
- ❌ Breaking existing functionality during a refactor — refactoring preserves behavior
|
|
262
|
+
- ❌ Marking a spec delivered from the delivery log instead of tracing the code — the log is a claim
|
|
263
|
+
- ❌ Shipping machinery no surface consumes — delivered = visible in the product (UI or API)
|
|
264
|
+
- ❌ Trusting unit tests as proof of wiring — assert the operator-facing outcome end-to-end
|
|
265
|
+
- ❌ Trusting an external plan's ✅ (IMPROVEMENT-PLAN / delivery log) — ingest its items as specs and verify them
|
|
266
|
+
- ❌ Implementing a spec literally when it creates product tension — challenge it and resolve with the user
|
|
244
267
|
|
|
245
268
|
## References
|
|
246
269
|
|
|
247
|
-
- `references/01-intake.md` — question bank and probing techniques
|
|
270
|
+
- `references/01-intake.md` — question bank and probing techniques (incl. external planning docs, M6)
|
|
248
271
|
- `references/02-research.md` — research playbook with search templates
|
|
249
272
|
- `references/04-adversarial.md` — adversarial checklist per area
|
|
250
|
-
- `references/05-plan.md` — PLAN.md template with examples
|
|
251
|
-
- `references/06-implementation.md` — coding discipline details
|
|
252
|
-
- `references/06b-testing-qa.md` — **mandatory testing & QA standard** (
|
|
273
|
+
- `references/05-plan.md` — PLAN.md template with examples (incl. spec-to-code traceability matrix)
|
|
274
|
+
- `references/06-implementation.md` — coding discipline details (incl. M4 challenge designs, M5 trace before claiming)
|
|
275
|
+
- `references/06b-testing-qa.md` — **mandatory testing & QA standard** (14 rules + definition of done)
|
|
253
276
|
- `references/06c-code-quality.md` — **mandatory modularity & maintainability standard** (8 rules, SSOT, testable-standalone, single escalation path)
|
|
277
|
+
- `references/06d-delegation.md` — **intercom & subagents**: when to message another session, when to spawn isolated workers, the no-mutual-dependencies rule, and why exit codes lie
|
|
254
278
|
- `references/07-release.md` — release workflow (versioning, CHANGELOG, tags, npm, CI/CD)
|
|
@@ -13,6 +13,24 @@ Keep asking until the user confirms. One question at a time is fine; short batch
|
|
|
13
13
|
- "What exists today?" (blank slate / existing repo / replaces something)
|
|
14
14
|
- "How will we know it's done and correct?" (concrete success criteria)
|
|
15
15
|
- "Any hard constraints?" (stack, platform, budget, timeline, must-nots)
|
|
16
|
+
- "**Are there external planning docs?**" (IMPROVEMENT-PLAN.md, PLAN.md, requirements docs, delivery logs, ticket lists — in the repo, `docs/`, or referenced by the user)
|
|
17
|
+
|
|
18
|
+
## External planning docs (M6) — locate and ingest
|
|
19
|
+
|
|
20
|
+
When a task references or contains external planning documents, **realize they
|
|
21
|
+
exist**: look in the repo root, `docs/`, and anything the user points at. Then
|
|
22
|
+
**treat them like own captured specs**:
|
|
23
|
+
|
|
24
|
+
1. Read the doc(s) and list every actionable item (e.g. `IMP-002/006 — service agent titles`).
|
|
25
|
+
2. `capture_spec` each item with `sourceQuote` pointing at the doc + item id.
|
|
26
|
+
3. **The doc's own ✅ / "delivered" markers are claims, not evidence** — each
|
|
27
|
+
item gets traced (outcome → codePath → test) and verified like any other spec.
|
|
28
|
+
4. If the doc is large, ingest by section and decompose with `parentId`.
|
|
29
|
+
|
|
30
|
+
> **Why this matters (betamaxx audit):** the IMPROVEMENT-PLAN's delivery log said
|
|
31
|
+
> "IMP-006+P-A delivered ✅" and that was trusted as ground truth — the code was
|
|
32
|
+
> never traced. `intelligenceBudget.analyze()` shipped as dead code. Ingesting
|
|
33
|
+
> the plan's items as specs forces each one to be traced and verified.
|
|
16
34
|
|
|
17
35
|
## Probing techniques
|
|
18
36
|
|
|
@@ -14,6 +14,12 @@ Challenge every spec and design decision like a hostile reviewer. For each item,
|
|
|
14
14
|
> testable standalone with the same calls? Any hardcoded values that belong in
|
|
15
15
|
> config?
|
|
16
16
|
|
|
17
|
+
> **Traceability lens (always applied):** for every spec, ask — *what is the
|
|
18
|
+
> operator-facing outcome, and what code path delivers it?* Trace the path in
|
|
19
|
+
> your head: where could **dead wiring** hide (a function defined but never
|
|
20
|
+
> called, an async enrichment that never lands, a surface that never renders)?
|
|
21
|
+
> If the outcome has no concrete path, the spec is not yet real.
|
|
22
|
+
|
|
17
23
|
- **Edge cases**: empty input, zero data, max load, missing fields, concurrent access, duplicate input, unicode, huge payloads
|
|
18
24
|
- **Failure modes**: what breaks first? Is failure loud or silent? Can we recover automatically?
|
|
19
25
|
- **Security**: authentication, authorization, injection (SQL/XSS), data exposure, secrets, abuse/rate-limiting, supply chain
|
|
@@ -29,6 +29,14 @@ Decided approach with rationale. Cite the research (package names, URLs).
|
|
|
29
29
|
- **Layering**: one-way dependency rules between layers; what each layer may/may not import
|
|
30
30
|
- **Standalone testability**: how each module is exercised outside the host with the same calls
|
|
31
31
|
|
|
32
|
+
## Spec-to-code traceability matrix
|
|
33
|
+
For every spec, the operator-facing outcome, the code path that delivers it, and the test that asserts it. This is what `/asf verify` checks mechanically at delivery (M1).
|
|
34
|
+
|
|
35
|
+
| Spec | Operator-facing outcome | Code path | Test (asserts outcome) |
|
|
36
|
+
|------|------------------------|-----------|------------------------|
|
|
37
|
+
| spc-… | e.g. "ingested report has an agent_title on the card" | ingest → analyze() → persist → render | tests/e2e-ingest.test.ts (`agent_title`) |
|
|
38
|
+
| … | | | |
|
|
39
|
+
|
|
32
40
|
## Milestones
|
|
33
41
|
| # | Milestone | Exit criteria |
|
|
34
42
|
|---|-----------|---------------|
|
|
@@ -60,3 +60,26 @@ Every user-visible change gets an entry under `## [Unreleased]` or the released
|
|
|
60
60
|
- New hard requirement discovered → `capture_spec` immediately
|
|
61
61
|
- Requirement changed → capture superseding spec (old → obsolete)
|
|
62
62
|
- When pi-vigilant injects its verification checklist → respond with `update_spec_status` + evidence
|
|
63
|
+
|
|
64
|
+
## Challenge approved designs during implementation (M4)
|
|
65
|
+
|
|
66
|
+
A plan was approved, but that does not make it correct. When a spec's literal
|
|
67
|
+
reading creates **product tension** (e.g. feedback clusters rendered under the
|
|
68
|
+
"Plan" tab when "Plan = plans"), **stop and resolve it with the user before
|
|
69
|
+
implementing** — do not implement blindly and call it delivered.
|
|
70
|
+
|
|
71
|
+
- Tension detected → state it plainly, propose the fix, get a decision.
|
|
72
|
+
- Implement the *sensible* version, not the literal-but-wrong one.
|
|
73
|
+
- The user's words "implemented in a SENSIBLE way" are the acceptance bar.
|
|
74
|
+
|
|
75
|
+
## The delivery log is a claim; the code is the evidence (M5)
|
|
76
|
+
|
|
77
|
+
Before marking anything ✅ (a spec, a milestone, a delivery-log item):
|
|
78
|
+
|
|
79
|
+
1. **Trace the actual code path** — the function is called, not just defined.
|
|
80
|
+
2. Confirm the output is **consumed by a surface** (Rule 13).
|
|
81
|
+
3. Confirm the **operator-facing outcome test** passes (Rule 12).
|
|
82
|
+
|
|
83
|
+
A delivery log saying "IMP-006 delivered ✅" proves nothing. The code is the
|
|
84
|
+
evidence. External planning docs (IMPROVEMENT-PLAN.md, PLAN.md, delivery logs)
|
|
85
|
+
are inputs to spec capture — their ✅ markers are claims, never ground truth.
|
|
@@ -125,6 +125,13 @@ API/curl checks do not replicate what a human sees. Via `pi-aia-browser`:
|
|
|
125
125
|
|
|
126
126
|
A 200 response with a blank or broken page is a **failure**.
|
|
127
127
|
|
|
128
|
+
**Silent async paths are the priority.** Fire-and-forget enrichment (an async
|
|
129
|
+
budgeted analysis that fills in a card title after render) fails silently — the
|
|
130
|
+
page renders, nobody notices the enrichment never landed. For any async/silent
|
|
131
|
+
surface: ingest through the real flow, then **wait for the enrichment to appear**
|
|
132
|
+
and assert it (e.g. ingest a report, wait for `agent_title` on the card). If it
|
|
133
|
+
never arrives, the wiring is dead — that is a failed test.
|
|
134
|
+
|
|
128
135
|
## Rule 10 — Definition of done (all must hold)
|
|
129
136
|
|
|
130
137
|
- [ ] Typecheck/build passes
|
|
@@ -135,6 +142,9 @@ A 200 response with a blank or broken page is a **failure**.
|
|
|
135
142
|
- [ ] Observable end state verified as a user would experience it
|
|
136
143
|
- [ ] Web surfaces exercised through a real browser
|
|
137
144
|
- [ ] Every MUST spec `met` with concrete evidence (`update_spec_status`)
|
|
145
|
+
- [ ] **Spec-to-code traceability: every `met` spec carries `trace` (outcome → codePath → testFile + assertion); `/asf verify` mechanically validates it (large work)**
|
|
146
|
+
- [ ] **Consumed by a surface: every delivered feature's output is visible in the product (UI or API) — nothing ships as dead machinery**
|
|
147
|
+
- [ ] **E2E behavioral test: every feature spec has a test through the real entry point asserting the operator-facing outcome**
|
|
138
148
|
- [ ] Unverifiable specs → `partial` + asked the user (never self-certified)
|
|
139
149
|
|
|
140
150
|
## Rule 11 — Report honestly
|
|
@@ -144,3 +154,43 @@ A 200 response with a blank or broken page is a **failure**.
|
|
|
144
154
|
- If a check was skipped or inconclusive, **say so explicitly** and say why.
|
|
145
155
|
- Distinguish "tests pass" from "feature works for the user" — Rule 2.
|
|
146
156
|
- If you discover you shipped something broken, say it plainly and fix it first.
|
|
157
|
+
|
|
158
|
+
## Rule 12 — Test the OPERATOR-FACING OUTCOME, not the machinery
|
|
159
|
+
|
|
160
|
+
> **Real failure (betamaxx audit):** `intelligence-budget.test.ts` and
|
|
161
|
+
> `service-session.test.ts` passed — they proved `analyze()` *works in
|
|
162
|
+
> isolation*. Nobody tested "does ingest actually call `analyze()`?". The tests
|
|
163
|
+
> proved the machinery, not the wiring. `intelligenceBudget.analyze()` shipped
|
|
164
|
+
> as **dead code** while every unit test was green.
|
|
165
|
+
|
|
166
|
+
Unit tests prove a component works in isolation. They do **not** prove the
|
|
167
|
+
feature is wired. For every feature spec, the deciding test is the one that
|
|
168
|
+
asserts the **operator-facing outcome** end-to-end:
|
|
169
|
+
|
|
170
|
+
- ❌ "`analyze()` returns a budget verdict" (machinery)
|
|
171
|
+
- ✅ "an ingested report eventually has an `agent_title` rendered on the card" (outcome)
|
|
172
|
+
|
|
173
|
+
If a unit test is green but the outcome test is missing, the feature is **not**
|
|
174
|
+
done — the wiring may be dead.
|
|
175
|
+
|
|
176
|
+
## Rule 13 — Nothing is delivered until CONSUMED BY A SURFACE
|
|
177
|
+
|
|
178
|
+
> **Real failure (betamaxx audit):** code commented *"Not yet consumed by a
|
|
179
|
+
> surface"* shipped as "delivered". Machinery (budget, runner, verdict
|
|
180
|
+
> contract) was built; the product behavior (cards titled by the agent) never
|
|
181
|
+
> happened.
|
|
182
|
+
|
|
183
|
+
- **Delivered = the output is visible in the product** (UI or API).
|
|
184
|
+
- Code commented "not yet consumed by a surface" is, by definition, **not
|
|
185
|
+
delivered**.
|
|
186
|
+
- Before marking a spec `met`, answer: *where does a user/operator see this?*
|
|
187
|
+
If nowhere — it is not done.
|
|
188
|
+
|
|
189
|
+
## Rule 14 — Every feature spec ships an E2E behavioral test through the REAL entry point
|
|
190
|
+
|
|
191
|
+
- The E2E test drives the **real entry point** (HTTP endpoint, CLI, UI) with a
|
|
192
|
+
mocked boundary (agent, DB), and asserts the operator-facing outcome.
|
|
193
|
+
- This catches dead wiring in one test: ingest → `analyze()` → persist → render.
|
|
194
|
+
- **Scale note:** mandatory for feature specs in **large/gated work**. For small
|
|
195
|
+
work, required only when the change touches a surface/wiring; otherwise the
|
|
196
|
+
standard test-first rules above suffice.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Delegation: Intercom & Subagents
|
|
2
|
+
|
|
3
|
+
ASF work does not have to happen in one session, in one context window, or one task at a time. Two delegation mechanisms are available. They solve different problems and must not be confused.
|
|
4
|
+
|
|
5
|
+
| | **Intercom** | **Subagents** |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| What it is | Messaging between *live pi sessions* | Spawning a *fresh, isolated pi process* |
|
|
8
|
+
| Peer | A human-driven or long-running session with its own context and history | A stateless worker that exits when done |
|
|
9
|
+
| You get back | A conversation (peer can push back, ask, disagree) | One result |
|
|
10
|
+
| Use when | Another session owns the context/decision | You want the OUTCOME, not the trace |
|
|
11
|
+
| Cost | Cheap (a message) | A whole context window + model spend |
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Part 1 — Intercom: passing messages to other sessions
|
|
16
|
+
|
|
17
|
+
Other pi sessions on this machine are often working on directly relevant things: the same monorepo, an adjacent service, the package you depend on. **Use intercom to talk to them directly instead of guessing, duplicating their work, or routing everything through the user.**
|
|
18
|
+
|
|
19
|
+
### When to use intercom
|
|
20
|
+
|
|
21
|
+
- **Another session owns the context.** They have the repo loaded, the failure reproduced, the domain knowledge. Ask them rather than re-deriving it.
|
|
22
|
+
- **Your change affects their work.** You changed a shared interface, published a version, moved a file they depend on. Tell them.
|
|
23
|
+
- **You need independent verification.** A second session reproducing your result is stronger evidence than your own re-run (see 06b Rule 11).
|
|
24
|
+
- **Cross-project coordination.** Your package is their dependency; sequencing matters.
|
|
25
|
+
- **You found something they need to know.** A bug in shared code, a broken assumption, a security issue.
|
|
26
|
+
|
|
27
|
+
### How
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
intercom({ action: "list" }) // who is live
|
|
31
|
+
intercom({ action: "send", to: "<name-or-id>", message: "…" }) // fire-and-forget
|
|
32
|
+
intercom({ action: "ask", to: "<name-or-id>", message: "…" }) // wait for a reply
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Target by session name, full ID, or the short id in parentheses from `list`. Use `cwd` to scope to a directory when two sessions share a name.
|
|
36
|
+
|
|
37
|
+
### Rules
|
|
38
|
+
|
|
39
|
+
1. **`list` before you send.** Don't message a session that isn't live.
|
|
40
|
+
2. **Say what you want back.** "Please verify X and reply with the result" beats "FYI X."
|
|
41
|
+
3. **Give them what they need to act** — file paths, repro commands, exact error text. Assume zero shared context.
|
|
42
|
+
4. **`ask` blocks; `send` doesn't.** Use `ask` only when you genuinely need the answer before continuing.
|
|
43
|
+
5. **Hand over your weak points, not just your conclusions.** If you want a peer to verify, tell them what you did *not* test and what you'd most like broken. A peer who only receives conclusions will rubber-stamp them.
|
|
44
|
+
6. **Their findings are evidence, not proof.** An independent reproduction is strong; an unverified claim from a peer is still a claim (06b Rule 12, and M5: the log is a claim, the code is the evidence).
|
|
45
|
+
7. **Don't leak the user's private context** across projects without reason.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Part 2 — Subagents: delegating for the outcome
|
|
50
|
+
|
|
51
|
+
A subagent is a **fresh `pi` process with its own context window**. It takes a task, works independently, returns a result, and exits. The parent context never sees its intermediate tool calls — only the answer.
|
|
52
|
+
|
|
53
|
+
> **Core principle: subagents are context isolation, not role-play.** The point is to keep 5,000 lines of grep/read output out of the parent context, not to create "personas."
|
|
54
|
+
|
|
55
|
+
### When to spawn a subagent
|
|
56
|
+
|
|
57
|
+
Spawn when **the outcome matters more than the trace**:
|
|
58
|
+
|
|
59
|
+
- **Scoped codebase research.** "Which module owns retry logic, and what's its interface?" The search noise is worthless once the answer exists. *Signal: gathering the answer means reading many files.*
|
|
60
|
+
- **Independent small changes with NO MUTUAL DEPENDENCIES.** Three unrelated files each needing the same mechanical fix — run them in parallel.
|
|
61
|
+
- **Fresh-perspective review.** A reviewer that never saw your reasoning catches what familiarity hides. Especially valuable for challenging an approved design (06-implementation M4).
|
|
62
|
+
- **Bounded, noisy verification.** Running a long test matrix and reporting just the failures.
|
|
63
|
+
|
|
64
|
+
**Rule of thumb:** if the task needs exploring many files, or there are 3+ genuinely independent pieces of work, delegate.
|
|
65
|
+
|
|
66
|
+
### When NOT to spawn a subagent
|
|
67
|
+
|
|
68
|
+
- **Sequential/dependent work.** If step 2 needs step 1's full output, one context is cleaner than a relay.
|
|
69
|
+
- **Anything touching the same file.** See the hard evidence below.
|
|
70
|
+
- **Small tasks.** Delegation overhead exceeds the benefit. Just do it.
|
|
71
|
+
- **Work needing judgment you'd have to fully specify anyway.** If writing the task description costs more than doing the work, do the work.
|
|
72
|
+
- **The core implementation of a gated (LARGE) change.** You own the specs and the traceability. Delegate research and isolated fixes around it, not the spec-carrying work itself.
|
|
73
|
+
- **Nested delegation.** A subagent must not spawn subagents. Keep the tree one level deep.
|
|
74
|
+
|
|
75
|
+
### ⚠️ The no-mutual-dependencies rule is not advisory — it is enforced by physics
|
|
76
|
+
|
|
77
|
+
**Verified experimentally.** Four subagents were told to each change a different key in the *same* file, reading it and writing the complete file back:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
before: { a: 1, b: 2, c: 3, d: 4 } → 4 agents, one key each
|
|
81
|
+
after: { a: 1, b: 2, c: 3, d: 99 } → 1 of 4 edits survived
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Three edits were silently lost.** Every agent reported success. Every process exited 0. There was no error, no conflict marker, no warning — just a file that quietly lost 75% of the intended work.
|
|
85
|
+
|
|
86
|
+
Concurrent agents each read a snapshot and write back a whole file; last writer wins. Therefore:
|
|
87
|
+
|
|
88
|
+
- **Never run parallel subagents against the same file.** Partition by file, and state the partition in each task.
|
|
89
|
+
- If two tasks *might* touch the same file, they are dependent — **run them sequentially or do them yourself**.
|
|
90
|
+
- Independence must be verified before spawning, not assumed. If you cannot name the disjoint file set, you do not have independence.
|
|
91
|
+
|
|
92
|
+
### ⚠️ Exit code 0 does NOT mean the task succeeded
|
|
93
|
+
|
|
94
|
+
**Verified:** a subagent asked to read a non-existent file explained the problem conversationally and **exited 0**.
|
|
95
|
+
|
|
96
|
+
Never treat process exit status as the success signal. **Validate the returned output against what you asked for.** If a subagent was supposed to change code, verify the code changed — read the file, run the test. This is the delegation-shaped instance of M5: *the report is a claim; the code is the evidence.*
|
|
97
|
+
|
|
98
|
+
### How to spawn
|
|
99
|
+
|
|
100
|
+
There is **no built-in subagent tool in pi** — this is deliberate ("no sub-agents" is a stated design choice; you compose it yourself). Two supported routes:
|
|
101
|
+
|
|
102
|
+
**1. Direct subprocess (always available, zero install):**
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pi -p "<task>" --no-extensions --no-skills -t read,grep,find,ls
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Run several in the background and `wait` for them to parallelize.
|
|
109
|
+
|
|
110
|
+
**2. A subagent extension** (e.g. the `subagent/` example shipped with pi, or a package providing agent orchestration) — gives streaming output, parallel/chain modes, and usage tracking. Prefer this when available; fall back to `pi -p`.
|
|
111
|
+
|
|
112
|
+
### Rules for spawning
|
|
113
|
+
|
|
114
|
+
1. **Restrict tools to the job.** Research agents get read-only (`-t read,grep,find,ls`). Never hand write access to a task that only needs to look.
|
|
115
|
+
2. **Use `--no-extensions --no-skills` for research.** Faster, cheaper, and it prevents a subagent from writing to shared state (specs, feedback) that belongs to the parent task.
|
|
116
|
+
3. **Specify the output format.** "Return: file path, function name, and the 3-line interface — nothing else." Unspecified output returns an essay.
|
|
117
|
+
4. **Bounded, stateless, single-responsibility.** A subagent that needs prior conversation is the wrong tool.
|
|
118
|
+
5. **Partition writes by file** and say so explicitly in every parallel task.
|
|
119
|
+
6. **Verify the result yourself** (see exit-code warning). For code changes: read the file or run the test.
|
|
120
|
+
7. **Cap the fan-out.** A handful of parallel agents, not dozens; each costs a full context window.
|
|
121
|
+
8. **One level deep.** No nesting.
|
|
122
|
+
|
|
123
|
+
### Interaction with ASF gates
|
|
124
|
+
|
|
125
|
+
Delegation changes **who does the work**, never **what must be proven**:
|
|
126
|
+
|
|
127
|
+
- Specs, traceability, and the `/asf verify` gate remain the **parent's** responsibility. A subagent cannot discharge a spec.
|
|
128
|
+
- The QA standard (06b) applies to delegated work identically. "A subagent did it" is not evidence.
|
|
129
|
+
- Subagent findings enter the record as **claims** until verified against code or tests.
|
|
130
|
+
- For LARGE work, the approval gate is unaffected: no subagent may start implementation before plan approval.
|