@ludecker/aaac 1.1.5 → 1.2.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/README.md +27 -12
- package/package.json +9 -9
- 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 +23 -0
- package/src/run-engine/debug-run.mjs +0 -0
- package/src/run-engine/gate-write.mjs +13 -0
- package/src/run-engine/lib.mjs +153 -5
- package/src/run-engine/log-dump.mjs +0 -0
- package/src/run-engine/log-trace.mjs +0 -0
- package/templates/cursor/aaac/enforcement.json +96 -5
- package/templates/cursor/aaac/graph.project.yaml +44 -5
- package/templates/cursor/aaac/lifecycle/lifecycle.json +26 -0
- package/templates/cursor/aaac/lifecycle/phases.json +9 -1
- package/templates/cursor/aaac/ontology.json +1 -0
- package/templates/cursor/aaac/project.config.json +36 -0
- package/templates/cursor/aaac/scripts/remediation/auto-check-swarm-synthesis.mjs +75 -0
- package/templates/cursor/aaac/scripts/remediation/auto-dispatch-queue-from-health.mjs +78 -0
- package/templates/cursor/aaac/scripts/remediation/bootstrap-autonomous.mjs +113 -0
- package/templates/cursor/aaac/scripts/remediation/capture-verify-baseline.mjs +66 -0
- package/templates/cursor/aaac/scripts/remediation/capture-wave-snapshot.mjs +79 -0
- package/templates/cursor/aaac/scripts/remediation/check-swarm-raw.template.json +26 -0
- package/templates/cursor/aaac/scripts/remediation/classify-fallow-issues.mjs +77 -0
- package/templates/cursor/aaac/scripts/remediation/classify-verify-failure.mjs +176 -0
- package/templates/cursor/aaac/scripts/remediation/compute-satisfaction.mjs +344 -0
- package/templates/cursor/aaac/scripts/remediation/debt-sweep-gate.mjs +202 -0
- package/templates/cursor/aaac/scripts/remediation/dispatch-rules.json +44 -0
- package/templates/cursor/aaac/scripts/remediation/fallow-fp-rules.json +87 -0
- package/templates/cursor/aaac/scripts/remediation/fallow-scan.mjs +219 -0
- package/templates/cursor/aaac/scripts/remediation/handle-yield.mjs +240 -0
- package/templates/cursor/aaac/scripts/remediation/init-campaign.mjs +211 -0
- package/templates/cursor/aaac/scripts/remediation/lib/autonomous-mode.mjs +63 -0
- package/templates/cursor/aaac/scripts/remediation/lib/campaign-focus.mjs +87 -0
- package/templates/cursor/aaac/scripts/remediation/lib/fallow-classifier.mjs +190 -0
- package/templates/cursor/aaac/scripts/remediation/lib/fallow-health-targets.mjs +56 -0
- package/templates/cursor/aaac/scripts/remediation/lib/fallow-metrics.mjs +119 -0
- package/templates/cursor/aaac/scripts/remediation/lib/invoke-cursor-agent.mjs +51 -0
- package/templates/cursor/aaac/scripts/remediation/lib/reconcile-run-manifest.mjs +41 -0
- package/templates/cursor/aaac/scripts/remediation/lib/regression-analysis.mjs +55 -0
- package/templates/cursor/aaac/scripts/remediation/lib/remediation-config.mjs +69 -0
- package/templates/cursor/aaac/scripts/remediation/lib/remediation-progress.mjs +58 -0
- package/templates/cursor/aaac/scripts/remediation/lib/remediation-watch-loop.mjs +168 -0
- package/templates/cursor/aaac/scripts/remediation/lib/runner-exec.mjs +156 -0
- package/templates/cursor/aaac/scripts/remediation/lib/runner-state.mjs +145 -0
- package/templates/cursor/aaac/scripts/remediation/lib/verify-metrics.mjs +205 -0
- package/templates/cursor/aaac/scripts/remediation/merge-check-swarm.mjs +257 -0
- package/templates/cursor/aaac/scripts/remediation/plan-waves-from-queue.mjs +85 -0
- package/templates/cursor/aaac/scripts/remediation/prepare-check-context.mjs +148 -0
- package/templates/cursor/aaac/scripts/remediation/record-fallow-fp.mjs +107 -0
- package/templates/cursor/aaac/scripts/remediation/record-iteration-step.mjs +56 -0
- package/templates/cursor/aaac/scripts/remediation/remediation-cli.mjs +157 -0
- package/templates/cursor/aaac/scripts/remediation/remediation-cursor-watch.sh +10 -0
- package/templates/cursor/aaac/scripts/remediation/remediation-runner-daemon.sh +13 -0
- package/templates/cursor/aaac/scripts/remediation/remediation-runner.mjs +748 -0
- package/templates/cursor/aaac/scripts/remediation/remediation-yield-watcher.mjs +40 -0
- package/templates/cursor/aaac/scripts/remediation/remediator-gate.mjs +405 -0
- package/templates/cursor/aaac/scripts/remediation/repair-fallow-start-baseline.mjs +118 -0
- package/templates/cursor/aaac/scripts/remediation/runner-health-check.mjs +164 -0
- package/templates/cursor/aaac/scripts/remediation/satisfaction-loop-gate.mjs +286 -0
- package/templates/cursor/aaac/scripts/remediation/validate-campaign-complete.mjs +191 -0
- package/templates/cursor/aaac/scripts/remediation/verify-remediation-iteration.mjs +112 -0
- package/templates/cursor/aaac/scripts/run-engine/advance-phase.mjs +23 -0
- package/templates/cursor/aaac/scripts/run-engine/debug-run.mjs +0 -0
- package/templates/cursor/aaac/scripts/run-engine/gate-write.mjs +13 -0
- package/templates/cursor/aaac/scripts/run-engine/lib.mjs +153 -5
- package/templates/cursor/aaac/scripts/run-engine/log-dump.mjs +0 -0
- package/templates/cursor/aaac/scripts/run-engine/log-trace.mjs +0 -0
- package/templates/cursor/agents/doc-conformance.md +25 -0
- package/templates/cursor/agents/implementation-review.md +21 -0
- package/templates/cursor/agents/remediation-check-app-inventory.md +32 -0
- package/templates/cursor/agents/remediation-check-app-ssot.md +24 -0
- package/templates/cursor/agents/remediation-check-app-trace.md +29 -0
- package/templates/cursor/agents/remediation-check-architecture-boundaries.md +21 -0
- package/templates/cursor/agents/remediation-check-architecture-decomposition.md +25 -0
- package/templates/cursor/agents/remediation-check-architecture-deps.md +23 -0
- package/templates/cursor/agents/remediation-check-risk.md +37 -0
- package/templates/cursor/agents/remediation-e2e-gate.md +30 -0
- package/templates/cursor/agents/remediation-remediator.md +69 -0
- package/templates/cursor/agents/test-author.md +27 -0
- package/templates/cursor/commands/remediate-app.md +212 -0
- package/templates/cursor/hooks/aaac-before-submit.sh +0 -0
- package/templates/cursor/hooks/aaac-pre-tool.sh +0 -0
- package/templates/cursor/hooks/aaac-stop.sh +0 -0
- package/templates/cursor/hooks/aaac-subagent-start.sh +0 -0
- package/templates/cursor/rules/aaac-enforcement.mdc +10 -3
- 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/planning/SKILL.md +5 -0
- package/templates/cursor/skills/shared/remediation/SKILL.md +51 -0
- package/templates/cursor/skills/shared/remediation/babysit/SKILL.md +223 -0
- package/templates/cursor/skills/shared/remediation/check-swarm/SKILL.md +114 -0
- package/templates/cursor/skills/shared/remediation/orchestrator/SKILL.md +275 -0
- package/templates/cursor/skills/shared/remediation/orchestrator/contract.yaml +116 -0
- package/templates/cursor/skills/shared/test-authoring/SKILL.md +58 -0
- package/templates/cursor/skills/shared/testing/SKILL.md +6 -0
- 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 +169 -97
package/src/run-engine/lib.mjs
CHANGED
|
@@ -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 = [
|
|
@@ -138,11 +160,22 @@ export function phaseKind(phase, registry) {
|
|
|
138
160
|
|
|
139
161
|
/** Swarm minimum for completed phase — check verb uses check_swarm on discover. */
|
|
140
162
|
export function resolveSwarmMinimum(completedPhase, manifest, enforcement) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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;
|
|
146
179
|
}
|
|
147
180
|
if (completedPhase === "discover" && manifest.verb === "check") {
|
|
148
181
|
return (
|
|
@@ -189,3 +222,118 @@ export function clearActiveRun(conversationId) {
|
|
|
189
222
|
// already cleared
|
|
190
223
|
}
|
|
191
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
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 3,
|
|
3
3
|
"description": "AAAC runtime enforcement — SSOT for hooks and run engine",
|
|
4
|
-
"edit_phases": [
|
|
5
|
-
|
|
4
|
+
"edit_phases": [
|
|
5
|
+
"execute",
|
|
6
|
+
"debt_sweep",
|
|
7
|
+
"test_execute",
|
|
8
|
+
"sync_inventory",
|
|
9
|
+
"persist",
|
|
10
|
+
"write"
|
|
11
|
+
],
|
|
12
|
+
"artifact_write_phases": [
|
|
13
|
+
"plan",
|
|
14
|
+
"report",
|
|
15
|
+
"campaign_init",
|
|
16
|
+
"scan",
|
|
17
|
+
"check_swarm",
|
|
18
|
+
"plan_waves",
|
|
19
|
+
"satisfaction_gate"
|
|
20
|
+
],
|
|
21
|
+
"mutating_verbs": ["create", "update", "fix"],
|
|
22
|
+
"phase_edit_scopes": {
|
|
23
|
+
"execute": { "deny_test_paths": true },
|
|
24
|
+
"test_execute": { "test_paths_only": true }
|
|
25
|
+
},
|
|
6
26
|
"verify_verbs": ["create", "update", "fix"],
|
|
7
27
|
"swarm_min_agents": {
|
|
8
28
|
"discover": 4,
|
|
9
29
|
"check_swarm": 3,
|
|
10
30
|
"investigate_swarm": 7,
|
|
11
31
|
"research_swarm": 6,
|
|
12
|
-
"
|
|
32
|
+
"test_execute": 1,
|
|
33
|
+
"verify": 3,
|
|
34
|
+
"verify_fix": 3,
|
|
35
|
+
"review_swarm": 3
|
|
36
|
+
},
|
|
37
|
+
"swarm_min_agents_by_command": {
|
|
38
|
+
"remediate-app": {
|
|
39
|
+
"check_swarm": 7
|
|
40
|
+
}
|
|
13
41
|
},
|
|
14
42
|
"phase_artifacts": {
|
|
15
43
|
"investigate_swarm": ["artifacts/investigation.md"],
|
|
@@ -20,12 +48,75 @@
|
|
|
20
48
|
"dependency_graph": ["artifacts/dependency_graph.yaml"],
|
|
21
49
|
"fitness_functions": ["artifacts/fitness.yaml"],
|
|
22
50
|
"rollback": ["artifacts/rollback.yaml"],
|
|
51
|
+
"test_execute": ["artifacts/test_plan.yaml"],
|
|
23
52
|
"verify": ["artifacts/verify.yaml"],
|
|
53
|
+
"review_swarm": ["artifacts/review.yaml"],
|
|
24
54
|
"report": ["artifacts/report.md"]
|
|
25
55
|
},
|
|
26
56
|
"allowed_path_prefixes": {
|
|
27
57
|
"run_artifacts": [".cursor/aaac/state/runs/", "aaac/state/runs/"],
|
|
28
|
-
"
|
|
58
|
+
"campaign_artifacts": [".cursor/aaac/state/campaigns/", "aaac/state/campaigns/"]
|
|
59
|
+
},
|
|
60
|
+
"remediation_gate": {
|
|
61
|
+
"script": "verify-remediation-iteration.mjs",
|
|
62
|
+
"remediator_gate_script": "remediator-gate.mjs",
|
|
63
|
+
"debt_sweep_script": "debt-sweep-gate.mjs",
|
|
64
|
+
"satisfaction_loop_script": "satisfaction-loop-gate.mjs",
|
|
65
|
+
"repair_fallow_start_script": "repair-fallow-start-baseline.mjs",
|
|
66
|
+
"bootstrap_autonomous_script": "bootstrap-autonomous.mjs",
|
|
67
|
+
"runner_script": "remediation-runner.mjs",
|
|
68
|
+
"runner_daemon_script": "remediation-runner-daemon.sh",
|
|
69
|
+
"runner_health_script": "runner-health-check.mjs",
|
|
70
|
+
"plan_waves_script": "plan-waves-from-queue.mjs",
|
|
71
|
+
"validate_script": "validate-campaign-complete.mjs",
|
|
72
|
+
"baseline_script": "capture-verify-baseline.mjs",
|
|
73
|
+
"wave_snapshot_script": "capture-wave-snapshot.mjs",
|
|
74
|
+
"classify_fallow_script": "classify-fallow-issues.mjs",
|
|
75
|
+
"record_fallow_fp_script": "record-fallow-fp.mjs",
|
|
76
|
+
"fallow_fp_rules": "fallow-fp-rules.json",
|
|
77
|
+
"classify_script": "classify-verify-failure.mjs",
|
|
78
|
+
"dispatch_rules": "dispatch-rules.json",
|
|
79
|
+
"wave_mode": "wave",
|
|
80
|
+
"debt_mode": "debt",
|
|
81
|
+
"wave_gate_mode": "regression",
|
|
82
|
+
"debt_gate_mode": "strict",
|
|
83
|
+
"campaign_artifact": "artifacts/campaign.json",
|
|
84
|
+
"exit_codes": {
|
|
85
|
+
"promote": 0,
|
|
86
|
+
"block": 1,
|
|
87
|
+
"runtime_error": 2,
|
|
88
|
+
"remediate": 3
|
|
89
|
+
},
|
|
90
|
+
"invariants": {
|
|
91
|
+
"exit_3_is_continue": true,
|
|
92
|
+
"never_block_campaign_on_wave_exit_3": true,
|
|
93
|
+
"satisfaction_exit_3_is_continue_loop": true,
|
|
94
|
+
"fallow_start_baseline_immutable": true,
|
|
95
|
+
"validate_before_report": true
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"phase_artifacts_remediate": {
|
|
99
|
+
"campaign_init": ["artifacts/campaign.json", "artifacts/verify_baseline.json"],
|
|
100
|
+
"scan": [
|
|
101
|
+
"artifacts/fallow_scan.json",
|
|
102
|
+
"artifacts/fallow_dupes.json",
|
|
103
|
+
"artifacts/fallow_health.json",
|
|
104
|
+
"artifacts/fallow_scan_bundle.json",
|
|
105
|
+
"artifacts/fallow_classification.json"
|
|
106
|
+
],
|
|
107
|
+
"check_swarm": [
|
|
108
|
+
"artifacts/check_synthesis.md",
|
|
109
|
+
"artifacts/dispatch-queue.yaml",
|
|
110
|
+
"artifacts/check_app_validate.yaml",
|
|
111
|
+
"artifacts/check_architecture_fitness.yaml",
|
|
112
|
+
"artifacts/protected_paths.yaml",
|
|
113
|
+
"artifacts/check_swarm_merge.json"
|
|
114
|
+
],
|
|
115
|
+
"plan_waves": ["artifacts/plan_waves.yaml"],
|
|
116
|
+
"execute": ["artifacts/execute_waves.yaml"],
|
|
117
|
+
"debt_sweep": ["artifacts/debt_sweep.json", "artifacts/verify_debt.json"],
|
|
118
|
+
"satisfaction_gate": ["artifacts/satisfaction.json", "artifacts/satisfaction_loop_gate.json"],
|
|
119
|
+
"report": ["artifacts/report.md"]
|
|
29
120
|
},
|
|
30
121
|
"fix_commands": ["fix-module", "fix-bug", "module-fix", "bug-fix"]
|
|
31
122
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
# Generic AAAC project overlay —
|
|
2
|
-
# Add
|
|
1
|
+
# Generic AAAC project overlay — copied into consumer repos by `aaac init`.
|
|
2
|
+
# Add `resolvers:` and domain orchestrators when you create `.cursor/domains/<slug>/`.
|
|
3
|
+
# Reference implementation (Lüdecker cms/ui/database): ludecker repo `.cursor/aaac/graph.project.yaml`
|
|
3
4
|
|
|
4
5
|
orchestrators:
|
|
5
6
|
update-doc:
|
|
@@ -30,6 +31,12 @@ orchestrators:
|
|
|
30
31
|
path: skills/shared/platform-release/orchestrator
|
|
31
32
|
requires: [testing, verification, execution, reporting]
|
|
32
33
|
|
|
34
|
+
remediate-app:
|
|
35
|
+
path: skills/shared/remediation/orchestrator
|
|
36
|
+
requires: [remediation, discovery, check, execution, testing, verification, reporting]
|
|
37
|
+
check_swarm_skill: skills/shared/remediation/check-swarm
|
|
38
|
+
phases: [campaign_init, scan, check_swarm, plan_waves, execute, debt_sweep, satisfaction_gate, report]
|
|
39
|
+
|
|
33
40
|
verb-create:
|
|
34
41
|
path: skills/shared/verbs/create/orchestrator
|
|
35
42
|
requires: [discovery, investigation-lite, planning, validation, impact-analysis, dependency-graph, fitness-functions, rollback, execution, testing, verification, reporting, module-authoring]
|
|
@@ -41,7 +48,7 @@ orchestrators:
|
|
|
41
48
|
verb-fix:
|
|
42
49
|
path: skills/shared/verbs/fix/orchestrator
|
|
43
50
|
requires: [discovery, investigation, root-cause, planning, validation, impact-analysis, dependency-graph, fitness-functions, rollback, execution, testing, verification, reporting]
|
|
44
|
-
phases: [load_inventory, discover, investigate_swarm, root_cause, plan, validate, impact_analysis, dependency_graph, fitness_functions, rollback, execute, verify, sync_inventory, report]
|
|
51
|
+
phases: [load_inventory, discover, investigate_swarm, root_cause, plan, validate, impact_analysis, dependency_graph, fitness_functions, rollback, execute, test_execute, verify, review_swarm, sync_inventory, report]
|
|
45
52
|
|
|
46
53
|
verb-review:
|
|
47
54
|
path: skills/shared/verbs/review/orchestrator
|
|
@@ -72,11 +79,17 @@ skills:
|
|
|
72
79
|
execution:
|
|
73
80
|
path: skills/shared/execution
|
|
74
81
|
depends: [governance/implementation]
|
|
82
|
+
test-authoring:
|
|
83
|
+
path: skills/shared/test-authoring
|
|
84
|
+
agents: [test-author]
|
|
75
85
|
testing:
|
|
76
86
|
path: skills/shared/testing
|
|
77
87
|
agents: [unit-test-run, fallow-check-changed, fix-repro-verify]
|
|
78
88
|
verification:
|
|
79
89
|
path: skills/shared/verification
|
|
90
|
+
implementation-review:
|
|
91
|
+
path: skills/shared/implementation-review
|
|
92
|
+
agents: [boundary-review, doc-conformance, implementation-review]
|
|
80
93
|
reporting:
|
|
81
94
|
path: skills/shared/reporting
|
|
82
95
|
architecture:
|
|
@@ -136,6 +149,10 @@ skills:
|
|
|
136
149
|
path: skills/shared/module-authoring
|
|
137
150
|
platform-release:
|
|
138
151
|
path: skills/shared/platform-release
|
|
152
|
+
remediation:
|
|
153
|
+
path: skills/shared/remediation
|
|
154
|
+
remediation-check-swarm:
|
|
155
|
+
path: skills/shared/remediation/check-swarm
|
|
139
156
|
governance/implementation:
|
|
140
157
|
path: skills/shared/governance/implementation
|
|
141
158
|
|
|
@@ -182,14 +199,36 @@ agents:
|
|
|
182
199
|
path: agents/fix-repro-verify.md
|
|
183
200
|
fix-hypothesis-validate:
|
|
184
201
|
path: agents/fix-hypothesis-validate.md
|
|
202
|
+
test-author:
|
|
203
|
+
path: agents/test-author.md
|
|
204
|
+
doc-conformance:
|
|
205
|
+
path: agents/doc-conformance.md
|
|
206
|
+
implementation-review:
|
|
207
|
+
path: agents/implementation-review.md
|
|
185
208
|
release-git:
|
|
186
209
|
path: agents/release-git.md
|
|
187
210
|
wave: 1
|
|
188
211
|
blocking: true
|
|
212
|
+
remediation-check-app-inventory:
|
|
213
|
+
path: agents/remediation-check-app-inventory.md
|
|
214
|
+
remediation-check-app-ssot:
|
|
215
|
+
path: agents/remediation-check-app-ssot.md
|
|
216
|
+
remediation-check-app-trace:
|
|
217
|
+
path: agents/remediation-check-app-trace.md
|
|
218
|
+
remediation-check-architecture-boundaries:
|
|
219
|
+
path: agents/remediation-check-architecture-boundaries.md
|
|
220
|
+
remediation-check-architecture-deps:
|
|
221
|
+
path: agents/remediation-check-architecture-deps.md
|
|
222
|
+
remediation-check-architecture-decomposition:
|
|
223
|
+
path: agents/remediation-check-architecture-decomposition.md
|
|
224
|
+
remediation-check-risk:
|
|
225
|
+
path: agents/remediation-check-risk.md
|
|
226
|
+
remediation-remediator:
|
|
227
|
+
path: agents/remediation-remediator.md
|
|
228
|
+
remediation-e2e-gate:
|
|
229
|
+
path: agents/remediation-e2e-gate.md
|
|
189
230
|
|
|
190
231
|
policies:
|
|
191
232
|
- policies/master-rules.md
|
|
192
|
-
- policies/project-context.md
|
|
193
|
-
- policies/ui-design.md
|
|
194
233
|
- policies/implementation.md
|
|
195
234
|
- policies/mcp-and-deploy.md
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
"investigate_lite",
|
|
9
9
|
"plan",
|
|
10
10
|
"execute",
|
|
11
|
+
"test_execute",
|
|
11
12
|
"verify",
|
|
13
|
+
"review_swarm",
|
|
12
14
|
"report"
|
|
13
15
|
],
|
|
14
16
|
"gate_stack": "pre_execute"
|
|
@@ -19,7 +21,9 @@
|
|
|
19
21
|
"investigate_lite",
|
|
20
22
|
"plan",
|
|
21
23
|
"execute",
|
|
24
|
+
"test_execute",
|
|
22
25
|
"verify",
|
|
26
|
+
"review_swarm",
|
|
23
27
|
"report"
|
|
24
28
|
],
|
|
25
29
|
"gate_stack": "pre_execute"
|
|
@@ -31,7 +35,9 @@
|
|
|
31
35
|
"root_cause",
|
|
32
36
|
"plan",
|
|
33
37
|
"execute",
|
|
38
|
+
"test_execute",
|
|
34
39
|
"verify",
|
|
40
|
+
"review_swarm",
|
|
35
41
|
"report"
|
|
36
42
|
],
|
|
37
43
|
"gate_stack": "pre_execute"
|
|
@@ -58,7 +64,9 @@
|
|
|
58
64
|
"investigate_lite",
|
|
59
65
|
"plan",
|
|
60
66
|
"execute",
|
|
67
|
+
"test_execute",
|
|
61
68
|
"verify",
|
|
69
|
+
"review_swarm",
|
|
62
70
|
"report"
|
|
63
71
|
],
|
|
64
72
|
"gate_stack": "pre_execute"
|
|
@@ -96,7 +104,9 @@
|
|
|
96
104
|
"root_cause",
|
|
97
105
|
"plan",
|
|
98
106
|
"execute",
|
|
107
|
+
"test_execute",
|
|
99
108
|
"verify",
|
|
109
|
+
"review_swarm",
|
|
100
110
|
"report"
|
|
101
111
|
],
|
|
102
112
|
"gate_stack": "pre_execute"
|
|
@@ -109,10 +119,26 @@
|
|
|
109
119
|
"root_cause",
|
|
110
120
|
"plan",
|
|
111
121
|
"execute",
|
|
122
|
+
"test_execute",
|
|
112
123
|
"verify",
|
|
124
|
+
"review_swarm",
|
|
113
125
|
"report"
|
|
114
126
|
],
|
|
115
127
|
"gate_stack": "pre_execute"
|
|
128
|
+
},
|
|
129
|
+
"remediate-app": {
|
|
130
|
+
"description": "Long-running remediation campaign — Fallow scan, check swarm, fix waves, debt sweep, satisfaction loop",
|
|
131
|
+
"work_phases": [
|
|
132
|
+
"campaign_init",
|
|
133
|
+
"scan",
|
|
134
|
+
"check_swarm",
|
|
135
|
+
"plan_waves",
|
|
136
|
+
"execute",
|
|
137
|
+
"debt_sweep",
|
|
138
|
+
"satisfaction_gate",
|
|
139
|
+
"report"
|
|
140
|
+
],
|
|
141
|
+
"gate_stack": null
|
|
116
142
|
}
|
|
117
143
|
}
|
|
118
144
|
}
|
|
@@ -14,7 +14,15 @@
|
|
|
14
14
|
"fitness_functions": { "skill": "fitness-functions", "gate": true },
|
|
15
15
|
"rollback": { "skill": "rollback", "gate": true },
|
|
16
16
|
"execute": { "skill": "execution" },
|
|
17
|
+
"test_execute": { "skill": "test-authoring" },
|
|
17
18
|
"verify": { "skills": ["testing", "verification"] },
|
|
18
|
-
"
|
|
19
|
+
"review_swarm": { "skill": "implementation-review", "readonly": true },
|
|
20
|
+
"report": { "skill": "reporting" },
|
|
21
|
+
"campaign_init": { "skill": "remediation", "readonly": true },
|
|
22
|
+
"scan": { "skill": "remediation", "readonly": true },
|
|
23
|
+
"check_swarm": { "skill": "check", "readonly": true },
|
|
24
|
+
"plan_waves": { "skill": "planning", "readonly": true },
|
|
25
|
+
"debt_sweep": { "skill": "remediation" },
|
|
26
|
+
"satisfaction_gate": { "skill": "remediation", "readonly": true }
|
|
19
27
|
}
|
|
20
28
|
}
|
|
@@ -180,6 +180,7 @@
|
|
|
180
180
|
"review-incident": { "orchestrator": "review-incident" },
|
|
181
181
|
"test-function": { "orchestrator": "test-function" },
|
|
182
182
|
"release-app": { "orchestrator": "release-app" },
|
|
183
|
+
"remediate-app": { "orchestrator": "remediate-app", "object": "app" },
|
|
183
184
|
"module-update": { "alias": "update-module" },
|
|
184
185
|
"update-doc": { "alias": "update-architecture" },
|
|
185
186
|
"architecture": { "alias": "update-architecture" },
|
|
@@ -2,5 +2,41 @@
|
|
|
2
2
|
"manual_commands": [],
|
|
3
3
|
"verify": {
|
|
4
4
|
"enabled": false
|
|
5
|
+
},
|
|
6
|
+
"remediation": {
|
|
7
|
+
"fallow_cwd": ".",
|
|
8
|
+
"scan_root": ".",
|
|
9
|
+
"verify": {
|
|
10
|
+
"layers": [
|
|
11
|
+
{
|
|
12
|
+
"id": "typecheck",
|
|
13
|
+
"command": "npm",
|
|
14
|
+
"args": ["run", "typecheck"],
|
|
15
|
+
"cwd": ".",
|
|
16
|
+
"optional": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "vitest",
|
|
20
|
+
"command": "npm",
|
|
21
|
+
"args": ["test"],
|
|
22
|
+
"cwd": ".",
|
|
23
|
+
"optional": true
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "build",
|
|
27
|
+
"command": "npm",
|
|
28
|
+
"args": ["run", "build"],
|
|
29
|
+
"cwd": ".",
|
|
30
|
+
"optional": true
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"playwright": {
|
|
34
|
+
"enabled": false
|
|
35
|
+
},
|
|
36
|
+
"dev_server": {
|
|
37
|
+
"url": "http://localhost:3000",
|
|
38
|
+
"launch_hint": "Start your dev server before debt sweep / Playwright gates."
|
|
39
|
+
}
|
|
40
|
+
}
|
|
5
41
|
}
|
|
6
42
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Synthesize check-swarm-raw.json from Fallow health targets (scriptable check_swarm).
|
|
4
|
+
*/
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import { isoNow } from "../run-engine/lib.mjs";
|
|
8
|
+
import { campaignDir, iterDir } from "./lib/runner-state.mjs";
|
|
9
|
+
import { loadCampaignContext } from "./lib/campaign-focus.mjs";
|
|
10
|
+
import {
|
|
11
|
+
fetchHealthTargets,
|
|
12
|
+
filterTargetsForWaves,
|
|
13
|
+
} from "./lib/fallow-health-targets.mjs";
|
|
14
|
+
|
|
15
|
+
const AGENT_IDS = [
|
|
16
|
+
"remediation-check-app-inventory",
|
|
17
|
+
"remediation-check-app-ssot",
|
|
18
|
+
"remediation-check-app-trace",
|
|
19
|
+
"remediation-check-architecture-boundaries",
|
|
20
|
+
"remediation-check-architecture-deps",
|
|
21
|
+
"remediation-check-architecture-decomposition",
|
|
22
|
+
"remediation-check-risk",
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
function parseArgs(argv) {
|
|
26
|
+
const out = { campaignId: null, iteration: 0 };
|
|
27
|
+
for (let i = 0; i < argv.length; i++) {
|
|
28
|
+
if (argv[i] === "--campaign-id") out.campaignId = argv[++i];
|
|
29
|
+
else if (argv[i] === "--iteration") out.iteration = Number(argv[++i]);
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const args = parseArgs(process.argv.slice(2));
|
|
35
|
+
if (!args.campaignId) {
|
|
36
|
+
console.error("--campaign-id required");
|
|
37
|
+
process.exit(2);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const ctx = loadCampaignContext(args.campaignId);
|
|
41
|
+
const { targets, score } = fetchHealthTargets({ scope: ctx.scope, limit: 15 });
|
|
42
|
+
const filtered = filterTargetsForWaves(targets, {
|
|
43
|
+
protected_paths: ctx.protected_paths,
|
|
44
|
+
defer_high_fan_in: ctx.focus.defer_high_fan_in,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const safeToFix = filtered.slice(0, 8).map((t) => ({
|
|
48
|
+
path: t.path,
|
|
49
|
+
category: "health_decompose",
|
|
50
|
+
evidence: t.recommendation ?? null,
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
const baseFinding = `health ${score ?? "?"}; focus=${ctx.focus.health_functions_above_60_loc ? "functions>60LOC" : "general"}`;
|
|
54
|
+
|
|
55
|
+
const agents = AGENT_IDS.map((agent_id) => ({
|
|
56
|
+
agent_id,
|
|
57
|
+
command_mirror: agent_id.includes("risk") ? "check-risk" : agent_id.includes("architecture") ? "check-architecture" : "check-app",
|
|
58
|
+
answer: "partial",
|
|
59
|
+
confidence: "high",
|
|
60
|
+
false_positives: [],
|
|
61
|
+
protected_paths: ctx.protected_paths,
|
|
62
|
+
do_not_delete: ctx.protected_paths.map((p) => ({ path: p, reason: "protected" })),
|
|
63
|
+
safe_to_fix: safeToFix,
|
|
64
|
+
findings: [baseFinding, `auto-synthesis iter ${args.iteration}`],
|
|
65
|
+
gaps: [],
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
const outPath = path.join(iterDir(args.campaignId, args.iteration), "check-swarm-raw.json");
|
|
69
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
70
|
+
fs.writeFileSync(
|
|
71
|
+
outPath,
|
|
72
|
+
JSON.stringify({ merged_at: isoNow(), iteration: args.iteration, focus: ctx.focus, agents }, null, 2),
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
console.log(JSON.stringify({ ok: true, path: outPath, agents: agents.length, safe_to_fix: safeToFix.length }));
|