@ludecker/aaac 1.1.4 → 1.1.5
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/package.json +1 -1
- package/src/run-engine/advance-phase.mjs +2 -5
- package/src/run-engine/debug-run.mjs +6 -0
- package/src/run-engine/lib.mjs +17 -0
- package/src/run-engine/log.mjs +1 -1
- package/src/run-engine/record-task.mjs +25 -4
- package/templates/cursor/aaac/enforcement.json +6 -0
- package/templates/cursor/aaac/run/schema.json +5 -0
- package/templates/cursor/aaac/scripts/run-engine/advance-phase.mjs +2 -5
- package/templates/cursor/aaac/scripts/run-engine/debug-run.mjs +6 -0
- package/templates/cursor/aaac/scripts/run-engine/lib.mjs +17 -0
- package/templates/cursor/aaac/scripts/run-engine/log.mjs +1 -1
- package/templates/cursor/aaac/scripts/run-engine/record-task.mjs +25 -4
- package/templates/cursor/rules/aaac-enforcement.mdc +10 -5
- package/templates/cursor/skills/shared/_task-prompt-policy.md +18 -0
- package/templates/cursor/skills/shared/check/SKILL.md +4 -0
- package/templates/cursor/skills/shared/discovery/SKILL.md +4 -0
- package/templates/cursor/skills/shared/investigation/SKILL.md +1 -1
- package/templates/cursor/skills/shared/investigation-lite/SKILL.md +2 -0
- package/templates/cursor/skills/shared/testing/SKILL.md +3 -3
package/package.json
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
phaseKind,
|
|
17
17
|
isEditPhase,
|
|
18
18
|
isGatePhase,
|
|
19
|
+
resolveSwarmMinimum,
|
|
19
20
|
writeJson,
|
|
20
21
|
saveActiveRun,
|
|
21
22
|
} from "./lib.mjs";
|
|
@@ -55,11 +56,7 @@ if (manifest.phase !== completedPhase) {
|
|
|
55
56
|
process.exit(1);
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
const minAgents =
|
|
59
|
-
completedPhase === "verify" &&
|
|
60
|
-
(enforcement.fix_commands?.includes(manifest.command) || manifest.verb === "fix")
|
|
61
|
-
? enforcement.swarm_min_agents?.verify_fix
|
|
62
|
-
: enforcement.swarm_min_agents?.[completedPhase];
|
|
59
|
+
const minAgents = resolveSwarmMinimum(completedPhase, manifest, enforcement);
|
|
63
60
|
const launches = manifest.swarm?.task_launches_this_phase ?? 0;
|
|
64
61
|
if (minAgents && launches < minAgents && !force) {
|
|
65
62
|
recordLog(manifest, {
|
|
@@ -31,6 +31,12 @@ if (summary.blocked_reason) console.log(`Blocked: ${summary.blocked_reason}`);
|
|
|
31
31
|
console.log(`Completed: ${summary.completed.join(" → ") || "(none)"}`);
|
|
32
32
|
console.log(`Pending: ${summary.pending.join(" → ") || "(none)"}`);
|
|
33
33
|
console.log(`Swarm: phase=${summary.swarm.phase} count=${summary.swarm.task_launches_this_phase}`);
|
|
34
|
+
if (summary.swarm.agents?.length) {
|
|
35
|
+
console.log(`Agents: ${summary.swarm.agents.length} recorded this phase`);
|
|
36
|
+
for (const a of summary.swarm.agents.slice(-5)) {
|
|
37
|
+
console.log(` #${a.index} ${a.subagent_type ?? "?"} ${a.description ?? ""} @ ${a.at}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
34
40
|
console.log(`Log: ${summary.log_count} entries Decisions: ${summary.decisions_count}`);
|
|
35
41
|
console.log("--- last 10 log entries ---");
|
|
36
42
|
for (const e of summary.last_log_entries) {
|
package/src/run-engine/lib.mjs
CHANGED
|
@@ -136,6 +136,23 @@ export function phaseKind(phase, registry) {
|
|
|
136
136
|
return isGatePhase(phase, registry) ? "gate" : "work";
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/** Swarm minimum for completed phase — check verb uses check_swarm on discover. */
|
|
140
|
+
export function resolveSwarmMinimum(completedPhase, manifest, enforcement) {
|
|
141
|
+
if (
|
|
142
|
+
completedPhase === "verify" &&
|
|
143
|
+
(enforcement.fix_commands?.includes(manifest.command) || manifest.verb === "fix")
|
|
144
|
+
) {
|
|
145
|
+
return enforcement.swarm_min_agents?.verify_fix;
|
|
146
|
+
}
|
|
147
|
+
if (completedPhase === "discover" && manifest.verb === "check") {
|
|
148
|
+
return (
|
|
149
|
+
enforcement.swarm_min_agents?.check_swarm ??
|
|
150
|
+
enforcement.swarm_min_agents?.discover
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
return enforcement.swarm_min_agents?.[completedPhase];
|
|
154
|
+
}
|
|
155
|
+
|
|
139
156
|
export function promptFromHook(hook) {
|
|
140
157
|
return hook?.prompt ?? hook?.text ?? hook?.content ?? "";
|
|
141
158
|
}
|
package/src/run-engine/log.mjs
CHANGED
|
@@ -334,7 +334,7 @@ export function debugRunSummary(manifest) {
|
|
|
334
334
|
awaiting_approval: manifest.awaiting_approval,
|
|
335
335
|
completed: manifest.completed ?? [],
|
|
336
336
|
pending: manifest.pending ?? [],
|
|
337
|
-
swarm: { phase: swarmPhase, task_launches_this_phase: swarmCount },
|
|
337
|
+
swarm: { phase: swarmPhase, task_launches_this_phase: swarmCount, agents: manifest.swarm?.agents ?? [] },
|
|
338
338
|
edit_allowed: manifest.enforcement?.edit_allowed ?? false,
|
|
339
339
|
last_log_entries: log.slice(-10),
|
|
340
340
|
decisions_count: (manifest.decisions ?? []).length,
|
|
@@ -44,19 +44,40 @@ process.stdin.on("end", () => {
|
|
|
44
44
|
if (manifest.conversation_id && manifest.conversation_id !== conversationId) allow();
|
|
45
45
|
|
|
46
46
|
manifest.swarm = manifest.swarm ?? {};
|
|
47
|
-
|
|
47
|
+
const launchIndex = (manifest.swarm.task_launches_this_phase ?? 0) + 1;
|
|
48
|
+
manifest.swarm.task_launches_this_phase = launchIndex;
|
|
48
49
|
manifest.swarm.phase = manifest.phase;
|
|
49
|
-
|
|
50
|
+
|
|
51
|
+
const agentEntry = {
|
|
52
|
+
at: isoNow(),
|
|
53
|
+
index: launchIndex,
|
|
54
|
+
phase: manifest.phase,
|
|
55
|
+
subagent_type: hook.subagent_type ?? hook.subagentType ?? null,
|
|
56
|
+
description: hook.description ?? hook.subagent_description ?? null,
|
|
57
|
+
model: hook.model ?? null,
|
|
58
|
+
readonly: hook.readonly ?? null,
|
|
59
|
+
};
|
|
60
|
+
manifest.swarm.agents = manifest.swarm.agents ?? [];
|
|
61
|
+
manifest.swarm.agents.push(agentEntry);
|
|
62
|
+
|
|
63
|
+
const telemetryDetail = JSON.stringify({
|
|
64
|
+
count: launchIndex,
|
|
65
|
+
subagent_type: agentEntry.subagent_type,
|
|
66
|
+
index: launchIndex,
|
|
67
|
+
});
|
|
50
68
|
|
|
51
69
|
recordLog(manifest, {
|
|
52
70
|
event: "agent_spawned",
|
|
53
71
|
phase: manifest.phase,
|
|
54
72
|
phase_kind: manifest.phase_kind,
|
|
55
|
-
detail:
|
|
73
|
+
detail: telemetryDetail,
|
|
56
74
|
level: "debug",
|
|
57
75
|
});
|
|
58
76
|
|
|
59
77
|
writeJson(path.join(runDir(active.run_id), "run.json"), manifest);
|
|
60
|
-
saveActiveRun(conversationId, {
|
|
78
|
+
saveActiveRun(conversationId, {
|
|
79
|
+
...active,
|
|
80
|
+
task_launches_this_phase: manifest.swarm.task_launches_this_phase,
|
|
81
|
+
});
|
|
61
82
|
allow();
|
|
62
83
|
});
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"verify_verbs": ["create", "update", "fix"],
|
|
7
7
|
"swarm_min_agents": {
|
|
8
8
|
"discover": 4,
|
|
9
|
+
"check_swarm": 3,
|
|
9
10
|
"investigate_swarm": 7,
|
|
10
11
|
"research_swarm": 6,
|
|
11
12
|
"verify_fix": 3
|
|
@@ -14,6 +15,11 @@
|
|
|
14
15
|
"investigate_swarm": ["artifacts/investigation.md"],
|
|
15
16
|
"root_cause": ["artifacts/root_cause.yaml"],
|
|
16
17
|
"plan": ["artifacts/plan.yaml"],
|
|
18
|
+
"validate": ["artifacts/validate.yaml"],
|
|
19
|
+
"impact_analysis": ["artifacts/impact.yaml"],
|
|
20
|
+
"dependency_graph": ["artifacts/dependency_graph.yaml"],
|
|
21
|
+
"fitness_functions": ["artifacts/fitness.yaml"],
|
|
22
|
+
"rollback": ["artifacts/rollback.yaml"],
|
|
17
23
|
"verify": ["artifacts/verify.yaml"],
|
|
18
24
|
"report": ["artifacts/report.md"]
|
|
19
25
|
},
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
phaseKind,
|
|
17
17
|
isEditPhase,
|
|
18
18
|
isGatePhase,
|
|
19
|
+
resolveSwarmMinimum,
|
|
19
20
|
writeJson,
|
|
20
21
|
saveActiveRun,
|
|
21
22
|
} from "./lib.mjs";
|
|
@@ -55,11 +56,7 @@ if (manifest.phase !== completedPhase) {
|
|
|
55
56
|
process.exit(1);
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
const minAgents =
|
|
59
|
-
completedPhase === "verify" &&
|
|
60
|
-
(enforcement.fix_commands?.includes(manifest.command) || manifest.verb === "fix")
|
|
61
|
-
? enforcement.swarm_min_agents?.verify_fix
|
|
62
|
-
: enforcement.swarm_min_agents?.[completedPhase];
|
|
59
|
+
const minAgents = resolveSwarmMinimum(completedPhase, manifest, enforcement);
|
|
63
60
|
const launches = manifest.swarm?.task_launches_this_phase ?? 0;
|
|
64
61
|
if (minAgents && launches < minAgents && !force) {
|
|
65
62
|
recordLog(manifest, {
|
|
@@ -31,6 +31,12 @@ if (summary.blocked_reason) console.log(`Blocked: ${summary.blocked_reason}`);
|
|
|
31
31
|
console.log(`Completed: ${summary.completed.join(" → ") || "(none)"}`);
|
|
32
32
|
console.log(`Pending: ${summary.pending.join(" → ") || "(none)"}`);
|
|
33
33
|
console.log(`Swarm: phase=${summary.swarm.phase} count=${summary.swarm.task_launches_this_phase}`);
|
|
34
|
+
if (summary.swarm.agents?.length) {
|
|
35
|
+
console.log(`Agents: ${summary.swarm.agents.length} recorded this phase`);
|
|
36
|
+
for (const a of summary.swarm.agents.slice(-5)) {
|
|
37
|
+
console.log(` #${a.index} ${a.subagent_type ?? "?"} ${a.description ?? ""} @ ${a.at}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
34
40
|
console.log(`Log: ${summary.log_count} entries Decisions: ${summary.decisions_count}`);
|
|
35
41
|
console.log("--- last 10 log entries ---");
|
|
36
42
|
for (const e of summary.last_log_entries) {
|
|
@@ -136,6 +136,23 @@ export function phaseKind(phase, registry) {
|
|
|
136
136
|
return isGatePhase(phase, registry) ? "gate" : "work";
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/** Swarm minimum for completed phase — check verb uses check_swarm on discover. */
|
|
140
|
+
export function resolveSwarmMinimum(completedPhase, manifest, enforcement) {
|
|
141
|
+
if (
|
|
142
|
+
completedPhase === "verify" &&
|
|
143
|
+
(enforcement.fix_commands?.includes(manifest.command) || manifest.verb === "fix")
|
|
144
|
+
) {
|
|
145
|
+
return enforcement.swarm_min_agents?.verify_fix;
|
|
146
|
+
}
|
|
147
|
+
if (completedPhase === "discover" && manifest.verb === "check") {
|
|
148
|
+
return (
|
|
149
|
+
enforcement.swarm_min_agents?.check_swarm ??
|
|
150
|
+
enforcement.swarm_min_agents?.discover
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
return enforcement.swarm_min_agents?.[completedPhase];
|
|
154
|
+
}
|
|
155
|
+
|
|
139
156
|
export function promptFromHook(hook) {
|
|
140
157
|
return hook?.prompt ?? hook?.text ?? hook?.content ?? "";
|
|
141
158
|
}
|
|
@@ -334,7 +334,7 @@ export function debugRunSummary(manifest) {
|
|
|
334
334
|
awaiting_approval: manifest.awaiting_approval,
|
|
335
335
|
completed: manifest.completed ?? [],
|
|
336
336
|
pending: manifest.pending ?? [],
|
|
337
|
-
swarm: { phase: swarmPhase, task_launches_this_phase: swarmCount },
|
|
337
|
+
swarm: { phase: swarmPhase, task_launches_this_phase: swarmCount, agents: manifest.swarm?.agents ?? [] },
|
|
338
338
|
edit_allowed: manifest.enforcement?.edit_allowed ?? false,
|
|
339
339
|
last_log_entries: log.slice(-10),
|
|
340
340
|
decisions_count: (manifest.decisions ?? []).length,
|
|
@@ -44,19 +44,40 @@ process.stdin.on("end", () => {
|
|
|
44
44
|
if (manifest.conversation_id && manifest.conversation_id !== conversationId) allow();
|
|
45
45
|
|
|
46
46
|
manifest.swarm = manifest.swarm ?? {};
|
|
47
|
-
|
|
47
|
+
const launchIndex = (manifest.swarm.task_launches_this_phase ?? 0) + 1;
|
|
48
|
+
manifest.swarm.task_launches_this_phase = launchIndex;
|
|
48
49
|
manifest.swarm.phase = manifest.phase;
|
|
49
|
-
|
|
50
|
+
|
|
51
|
+
const agentEntry = {
|
|
52
|
+
at: isoNow(),
|
|
53
|
+
index: launchIndex,
|
|
54
|
+
phase: manifest.phase,
|
|
55
|
+
subagent_type: hook.subagent_type ?? hook.subagentType ?? null,
|
|
56
|
+
description: hook.description ?? hook.subagent_description ?? null,
|
|
57
|
+
model: hook.model ?? null,
|
|
58
|
+
readonly: hook.readonly ?? null,
|
|
59
|
+
};
|
|
60
|
+
manifest.swarm.agents = manifest.swarm.agents ?? [];
|
|
61
|
+
manifest.swarm.agents.push(agentEntry);
|
|
62
|
+
|
|
63
|
+
const telemetryDetail = JSON.stringify({
|
|
64
|
+
count: launchIndex,
|
|
65
|
+
subagent_type: agentEntry.subagent_type,
|
|
66
|
+
index: launchIndex,
|
|
67
|
+
});
|
|
50
68
|
|
|
51
69
|
recordLog(manifest, {
|
|
52
70
|
event: "agent_spawned",
|
|
53
71
|
phase: manifest.phase,
|
|
54
72
|
phase_kind: manifest.phase_kind,
|
|
55
|
-
detail:
|
|
73
|
+
detail: telemetryDetail,
|
|
56
74
|
level: "debug",
|
|
57
75
|
});
|
|
58
76
|
|
|
59
77
|
writeJson(path.join(runDir(active.run_id), "run.json"), manifest);
|
|
60
|
-
saveActiveRun(conversationId, {
|
|
78
|
+
saveActiveRun(conversationId, {
|
|
79
|
+
...active,
|
|
80
|
+
task_launches_this_phase: manifest.swarm.task_launches_this_phase,
|
|
81
|
+
});
|
|
61
82
|
allow();
|
|
62
83
|
});
|
|
@@ -11,8 +11,8 @@ Every AAAC slash command (`/fix-module`, `/update-module`, `/write-article`, …
|
|
|
11
11
|
|
|
12
12
|
## Prerequisites
|
|
13
13
|
|
|
14
|
-
1. **
|
|
15
|
-
2. **Registry current** —
|
|
14
|
+
1. **Cursor Hooks enabled** — Settings → Hooks; restart Cursor after `.cursor/hooks.json` changes
|
|
15
|
+
2. **Registry current** — `node .cursor/aaac/generate-graph.mjs`
|
|
16
16
|
|
|
17
17
|
## Hook behavior (automatic)
|
|
18
18
|
|
|
@@ -31,11 +31,16 @@ Every AAAC slash command (`/fix-module`, `/update-module`, `/write-article`, …
|
|
|
31
31
|
node .cursor/aaac/scripts/run-engine/advance-phase.mjs <run_id> <phase>
|
|
32
32
|
```
|
|
33
33
|
3. **Swarm minimums** (enforced by advance-phase):
|
|
34
|
-
- `discover`: 4 Task agents
|
|
34
|
+
- `discover`: 4 Task agents (check verbs: `check_swarm` 3)
|
|
35
35
|
- `investigate_swarm`: 7 Task agents
|
|
36
36
|
- `research_swarm`: 6 Task agents
|
|
37
|
-
4. **
|
|
38
|
-
|
|
37
|
+
4. **Verify gate (create / update / fix):** before advancing past `verify`, run:
|
|
38
|
+
```bash
|
|
39
|
+
node .cursor/aaac/scripts/run-engine/verify-website-build.mjs --run-id <run_id>
|
|
40
|
+
```
|
|
41
|
+
`advance-phase.mjs verify` runs this automatically and blocks on missing static assets or failed `vite build` (catches favicon/path regressions).
|
|
42
|
+
5. **Code edits only in `execute`** (hook-enforced). Before execute: artifacts only under `.cursor/aaac/state/runs/`.
|
|
43
|
+
6. **Complete the Run** — advance through `report`, set status completed.
|
|
39
44
|
|
|
40
45
|
## If edit is denied
|
|
41
46
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Task prompt policy excerpt (mandatory)
|
|
2
|
+
|
|
3
|
+
Append this block to **every** Task sub-agent prompt the orchestrator sends.
|
|
4
|
+
|
|
5
|
+
## Policies (mandatory)
|
|
6
|
+
|
|
7
|
+
- **Readonly** unless the agent spec explicitly allows test runs or shell commands.
|
|
8
|
+
- **Evidence:** every claim needs `path:line` citations the parent can spot-check.
|
|
9
|
+
- **SSOT:** do not invent constants, routes, or file paths — read the repo.
|
|
10
|
+
- **Prime directive** (master rules): clarity beats cleverness; predictability beats shortcuts; one truth beats convenience.
|
|
11
|
+
- **Layer boundaries:** `packages/ui` must not import `apps/website`; `packages/types` and `packages/utils` stay runtime-free.
|
|
12
|
+
- **Errors:** never silent — state gaps explicitly in the return block.
|
|
13
|
+
|
|
14
|
+
Full policy chain: [.cursor/policies/master-rules.md](../../policies/master-rules.md) → [docs/master_rules.md](../../../docs/master_rules.md)
|
|
15
|
+
|
|
16
|
+
## Return shape
|
|
17
|
+
|
|
18
|
+
Follow the agent spec (`Findings`, `Evidence`, `Gaps`, `Confidence`). Do not edit files unless the spec allows it.
|
|
@@ -34,6 +34,10 @@ Launch **3** parallel `Task` subagents (`explore`, `readonly: true`) in **one me
|
|
|
34
34
|
|
|
35
35
|
Optional **4th** agent (second wave, only if intent names external system): `discovery-boundaries.md` for integration edges.
|
|
36
36
|
|
|
37
|
+
## Task prompt (mandatory)
|
|
38
|
+
|
|
39
|
+
Every Task prompt **must** include the policy excerpt from [_task-prompt-policy.md](../_task-prompt-policy.md) plus: question, scope, agent spec path, and inventory path when available.
|
|
40
|
+
|
|
37
41
|
## Merge
|
|
38
42
|
|
|
39
43
|
Parent synthesizes one brief:
|
|
@@ -24,6 +24,10 @@ Launch **4–6** parallel `Task` subagents (`explore`, `readonly: true`) in **on
|
|
|
24
24
|
|
|
25
25
|
Add domain-specific angles from inventory skill. Max **8** agents total; second wave ≤2 for critical gaps.
|
|
26
26
|
|
|
27
|
+
## Task prompt (mandatory)
|
|
28
|
+
|
|
29
|
+
Every Task prompt **must** include the policy excerpt from [_task-prompt-policy.md](../_task-prompt-policy.md) plus: intent, domain, inventory constraints, and the linked agent spec path.
|
|
30
|
+
|
|
27
31
|
## Output
|
|
28
32
|
|
|
29
33
|
Merged brief for `planning`: findings, evidence, gaps, confidence. Parent spot-checks `path:line` claims.
|
|
@@ -53,7 +53,7 @@ Launch **7 parallel** `Task` subagents in **one message**. `readonly: true` unle
|
|
|
53
53
|
| 6 | [fix-runtime-evidence.md](../../../agents/fix-runtime-evidence.md) | `generalPurpose` | CI/logs/MCP evidence |
|
|
54
54
|
| 7 | [fix-inventory-confirm.md](../../../agents/fix-inventory-confirm.md) | `explore` | Inventory scope + constraints |
|
|
55
55
|
|
|
56
|
-
**Parent prompt must include:** intent, domain, inventory path, discovery brief summary, frame fields.
|
|
56
|
+
**Parent prompt must include:** intent, domain, inventory path, discovery brief summary, frame fields, and the policy excerpt from [_task-prompt-policy.md](../_task-prompt-policy.md).
|
|
57
57
|
|
|
58
58
|
**Anti-patterns (hard fail):**
|
|
59
59
|
|
|
@@ -36,3 +36,5 @@ Pass output to [validation](../validation/SKILL.md). If any confidence below thr
|
|
|
36
36
|
## Agents
|
|
37
37
|
|
|
38
38
|
Reuse readonly specs: [discovery-inventory.md](../../../agents/discovery-inventory.md), [discovery-ssot.md](../../../agents/discovery-ssot.md), [dependency-analysis.md](../../../agents/dependency-analysis.md) — 2–3 parallel max for lite path.
|
|
39
|
+
|
|
40
|
+
Every Task prompt **must** include the policy excerpt from [_task-prompt-policy.md](../_task-prompt-policy.md).
|
|
@@ -18,15 +18,15 @@ Phase `verify` (and `test_only` orchestrators). On **fix** paths, run fix verify
|
|
|
18
18
|
2. Invoke [unit-test-run.md](../../../agents/unit-test-run.md) pattern for targeted vitest
|
|
19
19
|
3. Fallow MCP → `check_changed` on touched files when configured
|
|
20
20
|
4. `ReadLints` on edited paths
|
|
21
|
-
5. **
|
|
21
|
+
5. **Website build gate (mandatory on create / update / fix):** before advancing `verify`, run:
|
|
22
22
|
```bash
|
|
23
23
|
node .cursor/aaac/scripts/run-engine/verify-website-build.mjs --run-id <run_id>
|
|
24
24
|
```
|
|
25
|
-
|
|
25
|
+
This checks `index.html` static asset paths resolve under `apps/website/public/` (or project root for Vite dev) and runs `pnpm --filter @ludecker/website build`. `advance-phase.mjs verify` **blocks** until this passes and writes `artifacts/verify.yaml`.
|
|
26
26
|
|
|
27
27
|
## Fix verify swarm (mandatory on fix verb / fix_mode)
|
|
28
28
|
|
|
29
|
-
After unit tests, launch **3 parallel** `Task` subagents in **one message
|
|
29
|
+
After unit tests, launch **3 parallel** `Task` subagents in **one message**. Each prompt **must** include [_task-prompt-policy.md](../_task-prompt-policy.md) and investigation artifact paths.
|
|
30
30
|
|
|
31
31
|
| # | Agent spec | `subagent_type` | Role |
|
|
32
32
|
|---|------------|-----------------|------|
|