@voybio/ace-swarm 2.4.3 → 2.4.4

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.
Files changed (29) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/assets/agent-state/INTERFACE_REGISTRY.md +2 -2
  3. package/assets/agent-state/MODULES/gates/gate-autonomy.json +4 -2
  4. package/assets/agent-state/MODULES/gates/gate-completeness.json +4 -2
  5. package/assets/agent-state/MODULES/gates/gate-operability.json +4 -2
  6. package/assets/agent-state/MODULES/gates/gate-security.json +3 -1
  7. package/assets/agent-state/MODULES/registry.json +1 -4
  8. package/assets/agent-state/MODULES/roles/capability-build.json +1 -2
  9. package/assets/agent-state/MODULES/roles/capability-eval.json +1 -1
  10. package/assets/agent-state/MODULES/roles/capability-qa.json +1 -2
  11. package/assets/agent-state/QUALITY_GATES.md +25 -9
  12. package/assets/agent-state/TEAL_CONFIG.md +2 -11
  13. package/dist/astgrep-index.d.ts +7 -1
  14. package/dist/astgrep-index.js +66 -39
  15. package/dist/gate-contract.d.ts +63 -0
  16. package/dist/gate-contract.js +178 -0
  17. package/dist/runtime-executor.js +45 -2
  18. package/dist/runtime-tool-specs.d.ts +8 -1
  19. package/dist/runtime-tool-specs.js +19 -1
  20. package/dist/schemas.js +16 -15
  21. package/dist/store/bootstrap-store.js +30 -6
  22. package/dist/store/gate-contract-migration.d.ts +10 -0
  23. package/dist/store/gate-contract-migration.js +413 -0
  24. package/dist/tools-files.js +68 -5
  25. package/dist/tools-framework.js +115 -37
  26. package/package.json +3 -1
  27. package/assets/agent-state/MODULES/gates/gate-correctness.json +0 -7
  28. package/assets/agent-state/MODULES/gates/gate-evaluation.json +0 -7
  29. package/assets/agent-state/MODULES/gates/gate-typescript-public-surface.json +0 -7
@@ -18,6 +18,7 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
18
18
  import { resolve } from "node:path";
19
19
  import { auditPublicSurface } from "./public-surface.js";
20
20
  import { auditStoreAuthority, writeStoreAuthorityAuditReport, } from "./store/store-authority-audit.js";
21
+ import { parseGateManifest, resolveGateSelection, } from "./gate-contract.js";
21
22
  import { PROVENANCE_CRITICAL_EVENT_TYPES, validateArtifactManifestPayload, validateProvenanceLogContent, validateTealConfigContent, } from "./schemas.js";
22
23
  import { readAceTaskContractAssessment } from "./ace-autonomy.js";
23
24
  import { listStoreKeysSync, readStoreBlobSync } from "./store/store-snapshot.js";
@@ -54,28 +55,6 @@ function getArtifactManifestEntries(payload) {
54
55
  }
55
56
  return [];
56
57
  }
57
- function parseGateManifest(raw, sourceRef) {
58
- try {
59
- const gate = JSON.parse(raw);
60
- const id = typeof gate.id === "string" ? gate.id.trim() : "";
61
- if (!id)
62
- return undefined;
63
- const type = gate.type === "executable" || gate.type === "artifact_scan" || gate.type === "manual_review"
64
- ? gate.type
65
- : "manual_review";
66
- return {
67
- id,
68
- type,
69
- invariant: typeof gate.invariant === "string" ? gate.invariant : "",
70
- command: typeof gate.command === "string" ? gate.command : "",
71
- evidence_requirement: typeof gate.evidence_requirement === "string" ? gate.evidence_requirement : "",
72
- source_ref: sourceRef,
73
- };
74
- }
75
- catch {
76
- return undefined;
77
- }
78
- }
79
58
  function parseJsonForValidation(raw) {
80
59
  return parseJsonLikeText(raw);
81
60
  }
@@ -130,10 +109,14 @@ function hasArtifactEvidence(reference) {
130
109
  const normalized = reference.trim();
131
110
  if (!normalized)
132
111
  return false;
133
- const candidates = [wsPath("agent-state", normalized), wsPath(normalized)];
134
- if (candidates.some((candidate) => existsSync(candidate)))
112
+ const relativeCandidates = [
113
+ normalized,
114
+ normalized.startsWith("agent-state/") ? normalized : `agent-state/${normalized}`,
115
+ ];
116
+ const absoluteCandidates = relativeCandidates.map((candidate) => wsPath(candidate));
117
+ if (absoluteCandidates.some((candidate) => existsSync(candidate)))
135
118
  return true;
136
- return candidates.some((candidate) => {
119
+ return relativeCandidates.some((candidate) => {
137
120
  const content = safeRead(candidate);
138
121
  return !content.startsWith("[FILE NOT FOUND]") && !content.startsWith("[ACCESS DENIED]");
139
122
  });
@@ -1436,7 +1419,7 @@ export function registerFrameworkTools(server) {
1436
1419
  gate_ids: z
1437
1420
  .array(z.string())
1438
1421
  .optional()
1439
- .describe("Specific gate IDs to run (e.g. ['gate-correctness']). Omit to run all registered gates."),
1422
+ .describe("Specific gate IDs to run (e.g. ['gate-correctness']). Omit to run the active stage's stage-activated workspace gates."),
1440
1423
  review_mode: z
1441
1424
  .enum(["skeptic_adversarial"])
1442
1425
  .optional()
@@ -1449,25 +1432,102 @@ export function registerFrameworkTools(server) {
1449
1432
  const gatesDir = wsPath("agent-state", "MODULES", "gates");
1450
1433
  const resolved = resolveGateManifests(gatesDir);
1451
1434
  const allGates = resolved.gates;
1452
- const gateEvidenceRef = resolved.source === "store" ? "knowledge/gates/*" : "agent-state/MODULES/gates/";
1453
- // Filter to requested gates (or run all)
1454
- const targets = gate_ids
1455
- ? allGates.filter((g) => gate_ids.includes(g.id))
1456
- : allGates;
1435
+ const manifestEvidenceRef = resolved.source === "store" ? "knowledge/gates/*" : "agent-state/MODULES/gates/";
1436
+ const selection = resolveGateSelection({
1437
+ gates: allGates,
1438
+ manifestSource: resolved.source,
1439
+ statusRaw: safeRead("agent-state/STATUS.md"),
1440
+ tealRaw: safeRead("agent-state/TEAL_CONFIG.md"),
1441
+ gateIds: gate_ids,
1442
+ });
1443
+ const targets = selection.selected;
1457
1444
  if (targets.length === 0) {
1458
- const noGateMessage = allGates.length === 0
1459
- ? "❌ No gate manifests found in agent-state/MODULES/gates/ or ace-state.ace knowledge/gates/*."
1460
- : `❌ No matching gates found. Available: ${allGates.map((g) => g.id).join(", ")}`;
1445
+ if (allGates.length === 0) {
1446
+ return {
1447
+ content: [
1448
+ {
1449
+ type: "text",
1450
+ text: "❌ No gate manifests found in agent-state/MODULES/gates/ or ace-state.ace knowledge/gates/*.",
1451
+ },
1452
+ ],
1453
+ };
1454
+ }
1455
+ if (selection.selection_mode === "explicit") {
1456
+ const noGateMessage = selection.missing_explicit_gate_ids.length > 0
1457
+ ? `❌ No matching gates found for: ${selection.missing_explicit_gate_ids.join(", ")}. Available: ${allGates.map((g) => g.id).join(", ")}`
1458
+ : `❌ No matching gates found. Available: ${allGates.map((g) => g.id).join(", ")}`;
1459
+ return {
1460
+ content: [
1461
+ {
1462
+ type: "text",
1463
+ text: noGateMessage,
1464
+ },
1465
+ ],
1466
+ };
1467
+ }
1468
+ const message = selection.note ??
1469
+ "No stage-activated workspace gates were selected for the active ACE stage. Use explicit gate_ids when needed.";
1470
+ await appendStatusEventSafe({
1471
+ source_module: "capability-framework",
1472
+ event_type: "GATES_EXECUTED",
1473
+ status: "pass",
1474
+ summary: message,
1475
+ payload: {
1476
+ gates_run: [],
1477
+ gate_results: [],
1478
+ passed: 0,
1479
+ failed: 0,
1480
+ selection_mode: selection.selection_mode,
1481
+ selected_gate_ids: [],
1482
+ skipped_gate_ids: selection.skipped_gate_ids,
1483
+ gate_manifest_source: resolved.source,
1484
+ active_role: selection.active_role ?? null,
1485
+ active_module: selection.active_module ?? null,
1486
+ active_pipeline: selection.active_pipeline ?? null,
1487
+ selection_note: message,
1488
+ evidence_ref: manifestEvidenceRef,
1489
+ },
1490
+ objective_id: "gate-execution",
1491
+ });
1492
+ const ledger = await appendRunLedgerEntrySafe({
1493
+ tool: "execute_gates",
1494
+ category: "info",
1495
+ message,
1496
+ artifacts: [],
1497
+ metadata: {
1498
+ passed: 0,
1499
+ failed: 0,
1500
+ selection_mode: selection.selection_mode,
1501
+ selected_gate_ids: [],
1502
+ skipped_gate_ids: selection.skipped_gate_ids,
1503
+ gate_manifest_source: resolved.source,
1504
+ active_role: selection.active_role ?? null,
1505
+ active_module: selection.active_module ?? null,
1506
+ active_pipeline: selection.active_pipeline ?? null,
1507
+ selection_note: message,
1508
+ },
1509
+ });
1461
1510
  return {
1462
1511
  content: [
1463
1512
  {
1464
1513
  type: "text",
1465
- text: noGateMessage,
1514
+ text: [
1515
+ `ℹ️ ${message}`,
1516
+ `Selection mode: ${selection.selection_mode}`,
1517
+ `Active role/module: ${selection.active_role ?? "(unknown)"} / ${selection.active_module ?? "(unknown)"}`,
1518
+ `Active pipeline: ${selection.active_pipeline ?? "(unknown)"}`,
1519
+ `Selected gates: none`,
1520
+ `Skipped gates: ${selection.skipped_gate_ids.length > 0 ? selection.skipped_gate_ids.join(", ") : "none"}`,
1521
+ `Gate manifest source: ${resolved.source === "store"
1522
+ ? "ace-state.ace (knowledge/gates/*)"
1523
+ : "agent-state/MODULES/gates/"}`,
1524
+ `Run ledger: ${ledger.path} (${ledger.entry.id})`,
1525
+ ].join("\n"),
1466
1526
  },
1467
1527
  ],
1468
1528
  };
1469
1529
  }
1470
- const gateArtifactRefs = targets.map((gate) => gate.source_ref ?? gateEvidenceRef);
1530
+ const gateArtifactRefs = targets.map((gate) => gate.source_ref ?? manifestEvidenceRef);
1471
1531
  const results = evaluateGateTargets(targets);
1472
1532
  const passed = results.filter((r) => r.ok).length;
1473
1533
  const failed = results.filter((r) => !r.ok).length;
@@ -1495,7 +1555,13 @@ export function registerFrameworkTools(server) {
1495
1555
  })),
1496
1556
  passed,
1497
1557
  failed,
1498
- evidence_ref: evidence?.evidenceRef ?? gateEvidenceRef,
1558
+ evidence_ref: evidence?.evidenceRef ?? manifestEvidenceRef,
1559
+ selection_mode: selection.selection_mode,
1560
+ active_role: selection.active_role ?? null,
1561
+ active_module: selection.active_module ?? null,
1562
+ active_pipeline: selection.active_pipeline ?? null,
1563
+ selected_gate_ids: results.map((r) => r.id),
1564
+ skipped_gate_ids: selection.skipped_gate_ids,
1499
1565
  gate_manifest_source: resolved.source,
1500
1566
  ...(review
1501
1567
  ? {
@@ -1530,6 +1596,13 @@ export function registerFrameworkTools(server) {
1530
1596
  passed,
1531
1597
  failed,
1532
1598
  gate_ids: results.map((r) => r.id),
1599
+ selection_mode: selection.selection_mode,
1600
+ active_role: selection.active_role ?? null,
1601
+ active_module: selection.active_module ?? null,
1602
+ active_pipeline: selection.active_pipeline ?? null,
1603
+ selected_gate_ids: results.map((r) => r.id),
1604
+ skipped_gate_ids: selection.skipped_gate_ids,
1605
+ missing_explicit_gate_ids: selection.missing_explicit_gate_ids,
1533
1606
  gate_manifest_source: resolved.source,
1534
1607
  ...(review
1535
1608
  ? {
@@ -1559,6 +1632,11 @@ export function registerFrameworkTools(server) {
1559
1632
  `Gate manifest source: ${resolved.source === "store"
1560
1633
  ? "ace-state.ace (knowledge/gates/*)"
1561
1634
  : "agent-state/MODULES/gates/"}`,
1635
+ `Selection mode: ${selection.selection_mode}`,
1636
+ `Active role/module: ${selection.active_role ?? "(unknown)"} / ${selection.active_module ?? "(unknown)"}`,
1637
+ `Active pipeline: ${selection.active_pipeline ?? "(unknown)"}`,
1638
+ `Selected gates: ${results.map((r) => r.id).join(", ")}`,
1639
+ `Skipped gates: ${selection.skipped_gate_ids.length > 0 ? selection.skipped_gate_ids.join(", ") : "none"}`,
1562
1640
  `Run ledger: ${ledger.path} (${ledger.entry.id})`,
1563
1641
  ...(evidence ? [`Evidence: ${evidence.path} (${evidence.evidenceRef})`] : []),
1564
1642
  "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voybio/ace-swarm",
3
- "version": "2.4.3",
3
+ "version": "2.4.4",
4
4
  "description": "ACE Framework MCP server and CLI — single-file ACEPACK state, local-model serving, agent orchestration, and host compliance enforcement.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,6 +37,7 @@
37
37
  "scripts": {
38
38
  "build": "tsc",
39
39
  "test": "npm run build && node --test 'test/*.test.mjs' 'test/**/*.test.mjs'",
40
+ "test:real-astgrep": "npm run build && ACE_TEST_REAL_ASTGREP=1 node --test test/astgrep-real-cli.test.mjs",
40
41
  "start": "node dist/cli.js mcp",
41
42
  "dev": "tsc && node dist/cli.js mcp",
42
43
  "init": "node dist/cli.js init",
@@ -70,6 +71,7 @@
70
71
  "dependencies": {
71
72
  "@modelcontextprotocol/sdk": "^1.26.0",
72
73
  "typescript": "^5.9.3",
74
+ "yaml": "^2.9.0",
73
75
  "zod": "^4.3.6"
74
76
  },
75
77
  "devDependencies": {
@@ -1,7 +0,0 @@
1
- {
2
- "id": "gate-correctness",
3
- "type": "executable",
4
- "invariant": "All required tests pass",
5
- "command": "if [ -f ace-mcp-server/package.json ]; then cd ace-mcp-server && npm test --silent; elif [ -f package.json ]; then npm test --silent; else echo 'package.json not found for gate-correctness' && exit 1; fi",
6
- "evidence_requirement": "Command output snippet with exit code 0"
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "id": "gate-evaluation",
3
- "type": "executable",
4
- "invariant": "Core autonomy benchmark suites meet defined pass thresholds",
5
- "command": "bash scripts/ace/eval-harness.sh",
6
- "evidence_requirement": "EVAL_REPORT.md + command output"
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "id": "gate-typescript-public-surface",
3
- "type": "executable",
4
- "invariant": "Exported MCP tools, resources, prompts, and public status events stay registered, described, schema-backed where required, and covered by the audit gate",
5
- "command": "node --input-type=module -e \"import('./dist/public-surface.js').then(async (m) => { const result = await m.auditPublicSurface({ write_artifact: false }); if (!result.ok) { console.error(result.failures.join('\\n')); process.exit(1); } console.log(JSON.stringify(result.summary)); })\"",
6
- "evidence_requirement": "PUBLIC_SURFACE_REPORT.md + passing public-surface audit"
7
- }