@ludecker/aaac 1.1.4 → 1.1.6
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/README.md +27 -12
- package/package.json +1 -1
- package/src/cli.mjs +19 -7
- package/src/generators/generate-commands.mjs +25 -1
- package/src/generators/generate-graph.mjs +9 -1
- package/src/lib/install.mjs +13 -1
- package/src/lib/sweep-project-docs.mjs +348 -0
- package/src/run-engine/advance-phase.mjs +25 -5
- package/src/run-engine/debug-run.mjs +6 -0
- package/src/run-engine/gate-write.mjs +13 -0
- package/src/run-engine/lib.mjs +165 -0
- package/src/run-engine/log.mjs +1 -1
- package/src/run-engine/record-task.mjs +25 -4
- package/templates/cursor/aaac/enforcement.json +20 -4
- package/templates/cursor/aaac/graph.project.yaml +16 -5
- package/templates/cursor/aaac/lifecycle/lifecycle.json +12 -0
- package/templates/cursor/aaac/lifecycle/phases.json +2 -0
- package/templates/cursor/aaac/run/schema.json +5 -0
- package/templates/cursor/aaac/scripts/run-engine/advance-phase.mjs +25 -5
- package/templates/cursor/aaac/scripts/run-engine/debug-run.mjs +6 -0
- package/templates/cursor/aaac/scripts/run-engine/gate-write.mjs +13 -0
- package/templates/cursor/aaac/scripts/run-engine/lib.mjs +165 -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/agents/doc-conformance.md +25 -0
- package/templates/cursor/agents/implementation-review.md +21 -0
- package/templates/cursor/agents/test-author.md +27 -0
- package/templates/cursor/rules/aaac-enforcement.mdc +18 -6
- 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/execution/SKILL.md +7 -3
- package/templates/cursor/skills/shared/governance/implementation/SKILL.md +396 -28
- package/templates/cursor/skills/shared/implementation-review/SKILL.md +49 -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/planning/SKILL.md +5 -0
- package/templates/cursor/skills/shared/test-authoring/SKILL.md +58 -0
- package/templates/cursor/skills/shared/testing/SKILL.md +9 -3
- package/templates/cursor/skills/shared/verbs/create/orchestrator/SKILL.md +5 -3
- package/templates/cursor/skills/shared/verbs/fix/orchestrator/SKILL.md +5 -3
- package/templates/cursor/skills/shared/verbs/update/orchestrator/SKILL.md +5 -3
- package/templates/cursor/skills/shared/verification/SKILL.md +5 -3
- package/templates/docs/agentic_architecture.md +168 -97
|
@@ -123,6 +123,28 @@ export function isEditPhase(phase, enforcement) {
|
|
|
123
123
|
return enforcement.edit_phases.includes(phase);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
/** Test/spec file paths — used for writer vs tester phase scoping. */
|
|
127
|
+
export function isTestPath(filePath) {
|
|
128
|
+
if (!filePath) return false;
|
|
129
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
130
|
+
return (
|
|
131
|
+
/\.(test|spec)\.(mjs|cjs|js|ts|tsx)$/.test(normalized) ||
|
|
132
|
+
/(?:^|\/)__tests__(?:\/|$)/.test(normalized) ||
|
|
133
|
+
/(?:^|\/)tests\/(?:unit|integration|e2e|fixtures)\//.test(normalized)
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Phase-scoped edit rules from enforcement.phase_edit_scopes (v3+). */
|
|
138
|
+
export function isPathAllowedForPhase(filePath, phase, enforcement) {
|
|
139
|
+
if (!filePath) return true;
|
|
140
|
+
const scopes = enforcement.phase_edit_scopes?.[phase];
|
|
141
|
+
if (!scopes) return true;
|
|
142
|
+
const isTest = isTestPath(filePath);
|
|
143
|
+
if (scopes.deny_test_paths && isTest) return false;
|
|
144
|
+
if (scopes.test_paths_only && !isTest) return false;
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
|
|
126
148
|
export function isArtifactPath(filePath, enforcement) {
|
|
127
149
|
const normalized = filePath.replace(/\\/g, "/");
|
|
128
150
|
const prefixes = [
|
|
@@ -136,6 +158,34 @@ export function phaseKind(phase, registry) {
|
|
|
136
158
|
return isGatePhase(phase, registry) ? "gate" : "work";
|
|
137
159
|
}
|
|
138
160
|
|
|
161
|
+
/** Swarm minimum for completed phase — check verb uses check_swarm on discover. */
|
|
162
|
+
export function resolveSwarmMinimum(completedPhase, manifest, enforcement) {
|
|
163
|
+
const mutating = enforcement.mutating_verbs ?? ["create", "update", "fix"];
|
|
164
|
+
const isMutating =
|
|
165
|
+
mutating.includes(manifest.verb) ||
|
|
166
|
+
enforcement.fix_commands?.includes(manifest.command);
|
|
167
|
+
|
|
168
|
+
if (completedPhase === "verify" && isMutating) {
|
|
169
|
+
return (
|
|
170
|
+
enforcement.swarm_min_agents?.verify ??
|
|
171
|
+
enforcement.swarm_min_agents?.verify_fix
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
if (completedPhase === "test_execute" && isMutating) {
|
|
175
|
+
return enforcement.swarm_min_agents?.test_execute;
|
|
176
|
+
}
|
|
177
|
+
if (completedPhase === "review_swarm" && isMutating) {
|
|
178
|
+
return enforcement.swarm_min_agents?.review_swarm;
|
|
179
|
+
}
|
|
180
|
+
if (completedPhase === "discover" && manifest.verb === "check") {
|
|
181
|
+
return (
|
|
182
|
+
enforcement.swarm_min_agents?.check_swarm ??
|
|
183
|
+
enforcement.swarm_min_agents?.discover
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
return enforcement.swarm_min_agents?.[completedPhase];
|
|
187
|
+
}
|
|
188
|
+
|
|
139
189
|
export function promptFromHook(hook) {
|
|
140
190
|
return hook?.prompt ?? hook?.text ?? hook?.content ?? "";
|
|
141
191
|
}
|
|
@@ -172,3 +222,118 @@ export function clearActiveRun(conversationId) {
|
|
|
172
222
|
// already cleared
|
|
173
223
|
}
|
|
174
224
|
}
|
|
225
|
+
|
|
226
|
+
export function isMutatingVerb(manifest, enforcement) {
|
|
227
|
+
const mutating = enforcement.mutating_verbs ?? ["create", "update", "fix"];
|
|
228
|
+
return (
|
|
229
|
+
mutating.includes(manifest.verb) ||
|
|
230
|
+
(enforcement.fix_commands ?? []).includes(manifest.command)
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** List items under a YAML field (lines starting with `-` before next top-level key). */
|
|
235
|
+
export function readYamlListField(content, fieldName) {
|
|
236
|
+
if (!content) return [];
|
|
237
|
+
const lines = content.split("\n");
|
|
238
|
+
const start = lines.findIndex((line) => line.startsWith(`${fieldName}:`));
|
|
239
|
+
if (start < 0) return [];
|
|
240
|
+
|
|
241
|
+
const inline = lines[start].slice(`${fieldName}:`.length).trim();
|
|
242
|
+
if (inline === "[]") return [];
|
|
243
|
+
if (inline && !inline.startsWith("-")) return [inline];
|
|
244
|
+
|
|
245
|
+
const items = [];
|
|
246
|
+
for (let i = start + 1; i < lines.length; i += 1) {
|
|
247
|
+
const line = lines[i];
|
|
248
|
+
if (/^\S/.test(line) && line.trim()) break;
|
|
249
|
+
const itemMatch = line.match(/^\s+-\s+(.*)$/);
|
|
250
|
+
if (itemMatch) items.push(itemMatch[1].trim());
|
|
251
|
+
}
|
|
252
|
+
return items;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function readYamlScalarField(content, fieldName) {
|
|
256
|
+
if (!content) return null;
|
|
257
|
+
const match = content.match(new RegExp(`^${fieldName}:\\s*(.+)$`, "m"));
|
|
258
|
+
if (!match) return null;
|
|
259
|
+
return match[1].trim().replace(/^["']|["']$/g, "");
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function hasYamlField(content, fieldName) {
|
|
263
|
+
if (!content) return false;
|
|
264
|
+
return new RegExp(`^${fieldName}:`, "m").test(content);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export function planRequiresTests(planContent) {
|
|
268
|
+
if (!planContent) return false;
|
|
269
|
+
if (hasYamlField(planContent, "tests_to_add")) {
|
|
270
|
+
return readYamlListField(planContent, "tests_to_add").length > 0;
|
|
271
|
+
}
|
|
272
|
+
return /^\s*create:[\s\S]*?^\s+-\s+path:.*\/lib\//m.test(planContent);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export function validatePhaseArtifactContent(runId, completedPhase, manifest, enforcement) {
|
|
276
|
+
if (!isMutatingVerb(manifest, enforcement)) {
|
|
277
|
+
return { ok: true };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const planPath = path.join(runDir(runId), "artifacts/plan.yaml");
|
|
281
|
+
const planContent = fs.existsSync(planPath)
|
|
282
|
+
? fs.readFileSync(planPath, "utf8")
|
|
283
|
+
: "";
|
|
284
|
+
|
|
285
|
+
if (completedPhase === "plan") {
|
|
286
|
+
if (!hasYamlField(planContent, "tests_to_add")) {
|
|
287
|
+
return {
|
|
288
|
+
ok: false,
|
|
289
|
+
reason:
|
|
290
|
+
"plan.yaml must include tests_to_add (behaviors to cover, or tests_to_add: [] when no tests are needed)",
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
return { ok: true };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (completedPhase === "test_execute") {
|
|
297
|
+
const testPlanPath = path.join(runDir(runId), "artifacts/test_plan.yaml");
|
|
298
|
+
const testPlanContent = fs.existsSync(testPlanPath)
|
|
299
|
+
? fs.readFileSync(testPlanPath, "utf8")
|
|
300
|
+
: "";
|
|
301
|
+
|
|
302
|
+
const filesWritten = readYamlListField(testPlanContent, "files_written");
|
|
303
|
+
const skippedReason = readYamlScalarField(testPlanContent, "skipped_reason");
|
|
304
|
+
const testsRequired = planRequiresTests(planContent);
|
|
305
|
+
|
|
306
|
+
if (/status:\s*deferred/i.test(testPlanContent) && filesWritten.length === 0) {
|
|
307
|
+
return {
|
|
308
|
+
ok: false,
|
|
309
|
+
reason:
|
|
310
|
+
"test_plan.yaml cannot defer tests — author test files in test_execute (files_written required)",
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (testsRequired && filesWritten.length === 0) {
|
|
315
|
+
return {
|
|
316
|
+
ok: false,
|
|
317
|
+
reason:
|
|
318
|
+
"plan.yaml tests_to_add requires non-empty test_plan.files_written — launch test-author Task in test_execute",
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (
|
|
323
|
+
hasYamlField(planContent, "tests_to_add") &&
|
|
324
|
+
/tests_to_add:\s*\[\]/m.test(planContent) &&
|
|
325
|
+
filesWritten.length === 0 &&
|
|
326
|
+
!skippedReason
|
|
327
|
+
) {
|
|
328
|
+
return {
|
|
329
|
+
ok: false,
|
|
330
|
+
reason:
|
|
331
|
+
"tests_to_add is empty — test_plan.yaml must include skipped_reason explaining why no tests were authored",
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return { ok: true };
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return { ok: true };
|
|
339
|
+
}
|
|
@@ -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
|
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Agent: doc-conformance
|
|
2
|
+
|
|
3
|
+
**Readonly.**
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Compare implementation diff against supporting docs and policies — not layer boundaries (see boundary-review).
|
|
8
|
+
|
|
9
|
+
## Sources (read before judging)
|
|
10
|
+
|
|
11
|
+
- [docs/master_rules.md](../../docs/master_rules.md)
|
|
12
|
+
- [docs/architecture.md](../../docs/architecture.md) when present
|
|
13
|
+
- Domain inventory under `.cursor/domains/<slug>/update/inventory/` when available
|
|
14
|
+
- [.cursor/policies/](../../.cursor/policies/)
|
|
15
|
+
|
|
16
|
+
## Check
|
|
17
|
+
|
|
18
|
+
- SSOT violations (duplicated constants, mirrored state)
|
|
19
|
+
- Undocumented exceptions to master rules
|
|
20
|
+
- Plan `requirement_map` entries satisfied in code
|
|
21
|
+
- Missing validation at boundaries when plan promised schemas
|
|
22
|
+
|
|
23
|
+
## Return
|
|
24
|
+
|
|
25
|
+
Findings, Evidence (`path:line`), Severity (critical | suggestion), Confidence.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Agent: implementation-review
|
|
2
|
+
|
|
3
|
+
**Readonly.**
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Independent post-execute review of the diff — **not** the agent that wrote the code. Spot-check that the change matches plan and does not introduce obvious defects.
|
|
8
|
+
|
|
9
|
+
## Check
|
|
10
|
+
|
|
11
|
+
- Plan `paths_to_touch` vs actual diff scope
|
|
12
|
+
- No drive-by refactors outside plan
|
|
13
|
+
- Error paths logged, not swallowed
|
|
14
|
+
- Async flows use explicit state machines where plan required
|
|
15
|
+
- Size budgets not violated on touched files (flag if file grew past 80% budget)
|
|
16
|
+
|
|
17
|
+
## Return
|
|
18
|
+
|
|
19
|
+
Findings, Evidence (`path:line`), Severity (critical | suggestion), Confidence.
|
|
20
|
+
|
|
21
|
+
**Blocking:** any **critical** finding must be fixed before `report` on mutating verbs.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Agent: test-author
|
|
2
|
+
|
|
3
|
+
**Phase:** `test_execute` only. Parent orchestrator must **not** write test files — this agent does.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Author behavioral tests for changes made in `execute`. Read plan `tests_to_add[]`, implementation diff, and domain inventory test conventions.
|
|
8
|
+
|
|
9
|
+
## Must
|
|
10
|
+
|
|
11
|
+
- Write only `*.test.*`, `*.spec.*`, or paths under `__tests__/` / `tests/`
|
|
12
|
+
- Cover behaviors from `requirement_map`, not implementation details
|
|
13
|
+
- Match existing test framework (vitest, playwright) in the touched package
|
|
14
|
+
- Include [_task-prompt-policy.md](../skills/shared/_task-prompt-policy.md) policies
|
|
15
|
+
|
|
16
|
+
## Must not
|
|
17
|
+
|
|
18
|
+
- Edit production/source files (non-test paths)
|
|
19
|
+
- Weaken assertions to make tests pass
|
|
20
|
+
- Duplicate tests that already cover the behavior
|
|
21
|
+
|
|
22
|
+
## Return
|
|
23
|
+
|
|
24
|
+
- Files created/modified (paths only)
|
|
25
|
+
- Behaviors covered (one line each)
|
|
26
|
+
- Gaps — behaviors still untested
|
|
27
|
+
- Confidence: high | medium | low
|
|
@@ -11,15 +11,15 @@ 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
|
|
|
19
19
|
| Hook | Effect |
|
|
20
20
|
|------|--------|
|
|
21
21
|
| `beforeSubmitPrompt` | Detects `/command` → creates Run scoped to **`conversation_id`** (this chat only) |
|
|
22
|
-
| `preToolUse` | **Denies**
|
|
22
|
+
| `preToolUse` | **Denies** edits outside allowed phases; **phase-scoped paths** — `execute` = prod only, `test_execute` = tests only |
|
|
23
23
|
| `subagentStart` | Counts Task launches for swarm phase validation |
|
|
24
24
|
| `stop` | Follow-up if Run not `completed` |
|
|
25
25
|
|
|
@@ -31,11 +31,23 @@ 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
|
-
|
|
38
|
-
|
|
37
|
+
- `test_execute`: 1 test-author Task agent (mutating verbs)
|
|
38
|
+
- `verify`: 3 Task agents (all create/update/fix — not fix-only)
|
|
39
|
+
- `review_swarm`: 3 readonly reviewers (mutating verbs)
|
|
40
|
+
4. **Agent separation (mutating verbs):**
|
|
41
|
+
- **Writer** — parent in `execute` only (no test files)
|
|
42
|
+
- **Tester** — test-author subagent in `test_execute` only
|
|
43
|
+
- **Reviewer** — readonly swarm in `review_swarm` (not the execute agent)
|
|
44
|
+
5. **Verify gate (create / update / fix):** before advancing past `verify`, run:
|
|
45
|
+
```bash
|
|
46
|
+
node .cursor/aaac/scripts/run-engine/verify-website-build.mjs --run-id <run_id>
|
|
47
|
+
```
|
|
48
|
+
`advance-phase.mjs verify` runs this automatically and blocks on missing static assets or failed `vite build` (catches favicon/path regressions).
|
|
49
|
+
5. **Edits:** prod code in `execute`; test files in `test_execute` only. Run artifacts under `.cursor/aaac/state/runs/` anytime.
|
|
50
|
+
6. **Complete the Run** — advance through `report`, set status completed.
|
|
39
51
|
|
|
40
52
|
## If edit is denied
|
|
41
53
|
|
|
@@ -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.
|
|
@@ -15,18 +15,22 @@ Orchestrator phase `execute` after approved plan.
|
|
|
15
15
|
## Mandatory
|
|
16
16
|
|
|
17
17
|
1. Read [governance/implementation/SKILL.md](../governance/implementation/SKILL.md)
|
|
18
|
-
2. Read domain inventory
|
|
18
|
+
2. Read domain [inventory](../../../domains/) constraints
|
|
19
19
|
3. Read [policies/](../../../policies/)
|
|
20
20
|
|
|
21
21
|
## Actions
|
|
22
22
|
|
|
23
|
-
- Edit files per plan and implementation skill
|
|
24
|
-
-
|
|
23
|
+
- Edit **production/source** files per plan and implementation skill
|
|
24
|
+
- **Do not** create or edit test files (`*.test.*`, `*.spec.*`, `__tests__/`) — deferred to `test_execute` / [test-authoring](../test-authoring/SKILL.md)
|
|
25
|
+
- `apply_migration` for new/changed `supabase/migrations/` (project `anseivwusnyiwopihnqu` — see [supabase-mcp.mdc](../../../rules/supabase-mcp.mdc))
|
|
26
|
+
- `track()` for user-facing mutations
|
|
25
27
|
- Structured logging on server async paths
|
|
26
28
|
|
|
27
29
|
## Must not
|
|
28
30
|
|
|
29
31
|
- Invent plan during execution
|
|
32
|
+
- Write or edit test files (hooks block in `execute`; use `test_execute`)
|
|
33
|
+
- Self-review implementation (use [implementation-review](../implementation-review/SKILL.md) in `review_swarm`)
|
|
30
34
|
- Race guards or useEffect-driven mutations (implementation ban)
|
|
31
35
|
- Skip schema validation at boundaries
|
|
32
36
|
|