vaspera 2.13.0 → 2.15.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.
Files changed (300) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +15 -2
  3. package/dist/__tests__/antagonist-integration.test.d.ts +6 -0
  4. package/dist/__tests__/antagonist-integration.test.d.ts.map +1 -0
  5. package/dist/__tests__/antagonist-integration.test.js +239 -0
  6. package/dist/__tests__/antagonist-integration.test.js.map +1 -0
  7. package/dist/__tests__/certification/agent-certificate-e2e.test.d.ts +2 -0
  8. package/dist/__tests__/certification/agent-certificate-e2e.test.d.ts.map +1 -0
  9. package/dist/__tests__/certification/agent-certificate-e2e.test.js +90 -0
  10. package/dist/__tests__/certification/agent-certificate-e2e.test.js.map +1 -0
  11. package/dist/__tests__/certification/agent-certificate-map.test.d.ts +2 -0
  12. package/dist/__tests__/certification/agent-certificate-map.test.d.ts.map +1 -0
  13. package/dist/__tests__/certification/agent-certificate-map.test.js +107 -0
  14. package/dist/__tests__/certification/agent-certificate-map.test.js.map +1 -0
  15. package/dist/__tests__/certification/agent-certificate.test.d.ts +2 -0
  16. package/dist/__tests__/certification/agent-certificate.test.d.ts.map +1 -0
  17. package/dist/__tests__/certification/agent-certificate.test.js +78 -0
  18. package/dist/__tests__/certification/agent-certificate.test.js.map +1 -0
  19. package/dist/__tests__/certification/verify-endpoint.test.d.ts +2 -0
  20. package/dist/__tests__/certification/verify-endpoint.test.d.ts.map +1 -0
  21. package/dist/__tests__/certification/verify-endpoint.test.js +81 -0
  22. package/dist/__tests__/certification/verify-endpoint.test.js.map +1 -0
  23. package/dist/__tests__/compliance/ai-frameworks.test.d.ts +2 -0
  24. package/dist/__tests__/compliance/ai-frameworks.test.d.ts.map +1 -0
  25. package/dist/__tests__/compliance/ai-frameworks.test.js +87 -0
  26. package/dist/__tests__/compliance/ai-frameworks.test.js.map +1 -0
  27. package/dist/__tests__/eval/llm-analyzer.test.d.ts +2 -0
  28. package/dist/__tests__/eval/llm-analyzer.test.d.ts.map +1 -0
  29. package/dist/__tests__/eval/llm-analyzer.test.js +93 -0
  30. package/dist/__tests__/eval/llm-analyzer.test.js.map +1 -0
  31. package/dist/__tests__/eval/redteam-harness.test.d.ts +2 -0
  32. package/dist/__tests__/eval/redteam-harness.test.d.ts.map +1 -0
  33. package/dist/__tests__/eval/redteam-harness.test.js +136 -0
  34. package/dist/__tests__/eval/redteam-harness.test.js.map +1 -0
  35. package/dist/__tests__/evidence/evidence.test.d.ts +2 -0
  36. package/dist/__tests__/evidence/evidence.test.d.ts.map +1 -0
  37. package/dist/__tests__/evidence/evidence.test.js +240 -0
  38. package/dist/__tests__/evidence/evidence.test.js.map +1 -0
  39. package/dist/__tests__/history/decisions.test.d.ts +2 -0
  40. package/dist/__tests__/history/decisions.test.d.ts.map +1 -0
  41. package/dist/__tests__/history/decisions.test.js +54 -0
  42. package/dist/__tests__/history/decisions.test.js.map +1 -0
  43. package/dist/__tests__/http-auth.test.d.ts +2 -0
  44. package/dist/__tests__/http-auth.test.d.ts.map +1 -0
  45. package/dist/__tests__/http-auth.test.js +55 -0
  46. package/dist/__tests__/http-auth.test.js.map +1 -0
  47. package/dist/__tests__/http-policy.test.d.ts +2 -0
  48. package/dist/__tests__/http-policy.test.d.ts.map +1 -0
  49. package/dist/__tests__/http-policy.test.js +69 -0
  50. package/dist/__tests__/http-policy.test.js.map +1 -0
  51. package/dist/__tests__/http-server-transport.test.d.ts +2 -0
  52. package/dist/__tests__/http-server-transport.test.d.ts.map +1 -0
  53. package/dist/__tests__/http-server-transport.test.js +132 -0
  54. package/dist/__tests__/http-server-transport.test.js.map +1 -0
  55. package/dist/__tests__/integration/destructive-guards.test.d.ts +2 -0
  56. package/dist/__tests__/integration/destructive-guards.test.d.ts.map +1 -0
  57. package/dist/__tests__/integration/destructive-guards.test.js +49 -0
  58. package/dist/__tests__/integration/destructive-guards.test.js.map +1 -0
  59. package/dist/__tests__/logger-redaction.test.d.ts +2 -0
  60. package/dist/__tests__/logger-redaction.test.d.ts.map +1 -0
  61. package/dist/__tests__/logger-redaction.test.js +74 -0
  62. package/dist/__tests__/logger-redaction.test.js.map +1 -0
  63. package/dist/__tests__/manifest-schema.test.d.ts +2 -0
  64. package/dist/__tests__/manifest-schema.test.d.ts.map +1 -0
  65. package/dist/__tests__/manifest-schema.test.js +43 -0
  66. package/dist/__tests__/manifest-schema.test.js.map +1 -0
  67. package/dist/__tests__/scanners/builtin-rules.test.d.ts +2 -0
  68. package/dist/__tests__/scanners/builtin-rules.test.d.ts.map +1 -0
  69. package/dist/__tests__/scanners/builtin-rules.test.js +51 -0
  70. package/dist/__tests__/scanners/builtin-rules.test.js.map +1 -0
  71. package/dist/__tests__/scanners/runtime/golden-path-runner.test.js +13 -1
  72. package/dist/__tests__/scanners/runtime/golden-path-runner.test.js.map +1 -1
  73. package/dist/__tests__/tool-guard.test.d.ts +2 -0
  74. package/dist/__tests__/tool-guard.test.d.ts.map +1 -0
  75. package/dist/__tests__/tool-guard.test.js +97 -0
  76. package/dist/__tests__/tool-guard.test.js.map +1 -0
  77. package/dist/__tests__/util/contained-file.test.d.ts +2 -0
  78. package/dist/__tests__/util/contained-file.test.d.ts.map +1 -0
  79. package/dist/__tests__/util/contained-file.test.js +78 -0
  80. package/dist/__tests__/util/contained-file.test.js.map +1 -0
  81. package/dist/__tests__/util/subprocess.test.d.ts +2 -0
  82. package/dist/__tests__/util/subprocess.test.d.ts.map +1 -0
  83. package/dist/__tests__/util/subprocess.test.js +48 -0
  84. package/dist/__tests__/util/subprocess.test.js.map +1 -0
  85. package/dist/action/diff-mode.d.ts.map +1 -1
  86. package/dist/action/diff-mode.js +31 -12
  87. package/dist/action/diff-mode.js.map +1 -1
  88. package/dist/agents/antagonist/challenger.d.ts +46 -0
  89. package/dist/agents/antagonist/challenger.d.ts.map +1 -0
  90. package/dist/agents/antagonist/challenger.js +257 -0
  91. package/dist/agents/antagonist/challenger.js.map +1 -0
  92. package/dist/agents/antagonist/index.d.ts +31 -0
  93. package/dist/agents/antagonist/index.d.ts.map +1 -0
  94. package/dist/agents/antagonist/index.js +175 -0
  95. package/dist/agents/antagonist/index.js.map +1 -0
  96. package/dist/agents/antagonist/prioritizer.d.ts +27 -0
  97. package/dist/agents/antagonist/prioritizer.d.ts.map +1 -0
  98. package/dist/agents/antagonist/prioritizer.js +181 -0
  99. package/dist/agents/antagonist/prioritizer.js.map +1 -0
  100. package/dist/agents/antagonist/prompts.d.ts +12 -0
  101. package/dist/agents/antagonist/prompts.d.ts.map +1 -0
  102. package/dist/agents/antagonist/prompts.js +155 -0
  103. package/dist/agents/antagonist/prompts.js.map +1 -0
  104. package/dist/agents/antagonist/synthesizer.d.ts +34 -0
  105. package/dist/agents/antagonist/synthesizer.d.ts.map +1 -0
  106. package/dist/agents/antagonist/synthesizer.js +451 -0
  107. package/dist/agents/antagonist/synthesizer.js.map +1 -0
  108. package/dist/agents/antagonist/types.d.ts +145 -0
  109. package/dist/agents/antagonist/types.d.ts.map +1 -0
  110. package/dist/agents/antagonist/types.js +63 -0
  111. package/dist/agents/antagonist/types.js.map +1 -0
  112. package/dist/agents/index.d.ts +1 -0
  113. package/dist/agents/index.d.ts.map +1 -1
  114. package/dist/agents/index.js +2 -0
  115. package/dist/agents/index.js.map +1 -1
  116. package/dist/certification/agent-certificate-map.d.ts +51 -0
  117. package/dist/certification/agent-certificate-map.d.ts.map +1 -0
  118. package/dist/certification/agent-certificate-map.js +265 -0
  119. package/dist/certification/agent-certificate-map.js.map +1 -0
  120. package/dist/certification/agent-certificate-sample.d.ts +25 -0
  121. package/dist/certification/agent-certificate-sample.d.ts.map +1 -0
  122. package/dist/certification/agent-certificate-sample.js +207 -0
  123. package/dist/certification/agent-certificate-sample.js.map +1 -0
  124. package/dist/certification/agent-certificate.d.ts +1981 -0
  125. package/dist/certification/agent-certificate.d.ts.map +1 -0
  126. package/dist/certification/agent-certificate.js +309 -0
  127. package/dist/certification/agent-certificate.js.map +1 -0
  128. package/dist/certification/autofix.d.ts.map +1 -1
  129. package/dist/certification/autofix.js +5 -3
  130. package/dist/certification/autofix.js.map +1 -1
  131. package/dist/certification/consensus.test.js +2 -0
  132. package/dist/certification/consensus.test.js.map +1 -1
  133. package/dist/certification/store.d.ts.map +1 -1
  134. package/dist/certification/store.js +11 -3
  135. package/dist/certification/store.js.map +1 -1
  136. package/dist/certification/types.d.ts +1 -1
  137. package/dist/certification/types.d.ts.map +1 -1
  138. package/dist/certification/types.js +2 -0
  139. package/dist/certification/types.js.map +1 -1
  140. package/dist/certification/verify-endpoint.d.ts +48 -0
  141. package/dist/certification/verify-endpoint.d.ts.map +1 -0
  142. package/dist/certification/verify-endpoint.js +79 -0
  143. package/dist/certification/verify-endpoint.js.map +1 -0
  144. package/dist/compliance/index.d.ts +2 -0
  145. package/dist/compliance/index.d.ts.map +1 -1
  146. package/dist/compliance/index.js +4 -0
  147. package/dist/compliance/index.js.map +1 -1
  148. package/dist/compliance/iso42001.d.ts +21 -0
  149. package/dist/compliance/iso42001.d.ts.map +1 -0
  150. package/dist/compliance/iso42001.js +160 -0
  151. package/dist/compliance/iso42001.js.map +1 -0
  152. package/dist/compliance/mapper.d.ts.map +1 -1
  153. package/dist/compliance/mapper.js +12 -0
  154. package/dist/compliance/mapper.js.map +1 -1
  155. package/dist/compliance/nist-ai-rmf.d.ts +20 -0
  156. package/dist/compliance/nist-ai-rmf.d.ts.map +1 -0
  157. package/dist/compliance/nist-ai-rmf.js +140 -0
  158. package/dist/compliance/nist-ai-rmf.js.map +1 -0
  159. package/dist/config/flags.d.ts +4 -4
  160. package/dist/eval/fixtures.d.ts.map +1 -1
  161. package/dist/eval/fixtures.js +161 -119
  162. package/dist/eval/fixtures.js.map +1 -1
  163. package/dist/eval/fixtures.test.js +4 -2
  164. package/dist/eval/fixtures.test.js.map +1 -1
  165. package/dist/eval/llm-analyzer.d.ts +40 -0
  166. package/dist/eval/llm-analyzer.d.ts.map +1 -0
  167. package/dist/eval/llm-analyzer.js +154 -0
  168. package/dist/eval/llm-analyzer.js.map +1 -0
  169. package/dist/eval/redteam-harness.d.ts +95 -0
  170. package/dist/eval/redteam-harness.d.ts.map +1 -0
  171. package/dist/eval/redteam-harness.js +137 -0
  172. package/dist/eval/redteam-harness.js.map +1 -0
  173. package/dist/evidence/collector.d.ts.map +1 -1
  174. package/dist/evidence/collector.js +21 -1
  175. package/dist/evidence/collector.js.map +1 -1
  176. package/dist/evidence/store.d.ts.map +1 -1
  177. package/dist/evidence/store.js +29 -5
  178. package/dist/evidence/store.js.map +1 -1
  179. package/dist/evidence/types.d.ts +16 -9
  180. package/dist/evidence/types.d.ts.map +1 -1
  181. package/dist/history/decisions.d.ts +63 -0
  182. package/dist/history/decisions.d.ts.map +1 -0
  183. package/dist/history/decisions.js +60 -0
  184. package/dist/history/decisions.js.map +1 -0
  185. package/dist/history/index.d.ts +2 -0
  186. package/dist/history/index.d.ts.map +1 -1
  187. package/dist/history/index.js +2 -0
  188. package/dist/history/index.js.map +1 -1
  189. package/dist/history/types.d.ts +34 -5
  190. package/dist/history/types.d.ts.map +1 -1
  191. package/dist/history/types.js +2 -0
  192. package/dist/history/types.js.map +1 -1
  193. package/dist/http-auth.d.ts +22 -0
  194. package/dist/http-auth.d.ts.map +1 -0
  195. package/dist/http-auth.js +58 -0
  196. package/dist/http-auth.js.map +1 -0
  197. package/dist/http-policy.d.ts +30 -0
  198. package/dist/http-policy.d.ts.map +1 -0
  199. package/dist/http-policy.js +54 -0
  200. package/dist/http-policy.js.map +1 -0
  201. package/dist/http-server.js +195 -12
  202. package/dist/http-server.js.map +1 -1
  203. package/dist/index.d.ts.map +1 -1
  204. package/dist/index.js +411 -15
  205. package/dist/index.js.map +1 -1
  206. package/dist/logger.d.ts.map +1 -1
  207. package/dist/logger.js +56 -2
  208. package/dist/logger.js.map +1 -1
  209. package/dist/plugins/types.d.ts +2 -2
  210. package/dist/sbom/provenance.test.js +2 -2
  211. package/dist/sbom/provenance.test.js.map +1 -1
  212. package/dist/sbom/signing.d.ts.map +1 -1
  213. package/dist/sbom/signing.js +5 -3
  214. package/dist/sbom/signing.js.map +1 -1
  215. package/dist/scanners/agent/prompt-injection-fuzzer.d.ts.map +1 -1
  216. package/dist/scanners/agent/prompt-injection-fuzzer.js +26 -0
  217. package/dist/scanners/agent/prompt-injection-fuzzer.js.map +1 -1
  218. package/dist/scanners/agent/types.d.ts +10 -10
  219. package/dist/scanners/bandit.d.ts.map +1 -1
  220. package/dist/scanners/bandit.js +35 -29
  221. package/dist/scanners/bandit.js.map +1 -1
  222. package/dist/scanners/binary-analysis.d.ts.map +1 -1
  223. package/dist/scanners/binary-analysis.js +24 -49
  224. package/dist/scanners/binary-analysis.js.map +1 -1
  225. package/dist/scanners/brakeman.d.ts.map +1 -1
  226. package/dist/scanners/brakeman.js +19 -33
  227. package/dist/scanners/brakeman.js.map +1 -1
  228. package/dist/scanners/builtin-rules.d.ts +24 -0
  229. package/dist/scanners/builtin-rules.d.ts.map +1 -0
  230. package/dist/scanners/builtin-rules.js +175 -0
  231. package/dist/scanners/builtin-rules.js.map +1 -0
  232. package/dist/scanners/dast.d.ts.map +1 -1
  233. package/dist/scanners/dast.js +24 -34
  234. package/dist/scanners/dast.js.map +1 -1
  235. package/dist/scanners/deploy/types.d.ts +6 -6
  236. package/dist/scanners/eslint.d.ts.map +1 -1
  237. package/dist/scanners/eslint.js +15 -24
  238. package/dist/scanners/eslint.js.map +1 -1
  239. package/dist/scanners/gosec.d.ts.map +1 -1
  240. package/dist/scanners/gosec.js +14 -62
  241. package/dist/scanners/gosec.js.map +1 -1
  242. package/dist/scanners/index.d.ts.map +1 -1
  243. package/dist/scanners/index.js +38 -7
  244. package/dist/scanners/index.js.map +1 -1
  245. package/dist/scanners/memory-safety.d.ts.map +1 -1
  246. package/dist/scanners/memory-safety.js +27 -28
  247. package/dist/scanners/memory-safety.js.map +1 -1
  248. package/dist/scanners/openapi.d.ts.map +1 -1
  249. package/dist/scanners/openapi.js +14 -22
  250. package/dist/scanners/openapi.js.map +1 -1
  251. package/dist/scanners/race-condition.d.ts.map +1 -1
  252. package/dist/scanners/race-condition.js +17 -16
  253. package/dist/scanners/race-condition.js.map +1 -1
  254. package/dist/scanners/runtime/types.d.ts +4 -4
  255. package/dist/scanners/rust.d.ts.map +1 -1
  256. package/dist/scanners/rust.js +38 -37
  257. package/dist/scanners/rust.js.map +1 -1
  258. package/dist/scanners/scale/types.d.ts +16 -16
  259. package/dist/scanners/secrets.d.ts.map +1 -1
  260. package/dist/scanners/secrets.js +66 -78
  261. package/dist/scanners/secrets.js.map +1 -1
  262. package/dist/scanners/semgrep.d.ts +2 -0
  263. package/dist/scanners/semgrep.d.ts.map +1 -1
  264. package/dist/scanners/semgrep.js +12 -0
  265. package/dist/scanners/semgrep.js.map +1 -1
  266. package/dist/scanners/terraform.d.ts.map +1 -1
  267. package/dist/scanners/terraform.js +47 -40
  268. package/dist/scanners/terraform.js.map +1 -1
  269. package/dist/scanners/trivy.d.ts.map +1 -1
  270. package/dist/scanners/trivy.js +38 -30
  271. package/dist/scanners/trivy.js.map +1 -1
  272. package/dist/tool-guard.d.ts +40 -0
  273. package/dist/tool-guard.d.ts.map +1 -0
  274. package/dist/tool-guard.js +55 -0
  275. package/dist/tool-guard.js.map +1 -0
  276. package/dist/util/index.d.ts +2 -1
  277. package/dist/util/index.d.ts.map +1 -1
  278. package/dist/util/index.js +2 -1
  279. package/dist/util/index.js.map +1 -1
  280. package/dist/util/paths.d.ts +20 -3
  281. package/dist/util/paths.d.ts.map +1 -1
  282. package/dist/util/paths.js +84 -4
  283. package/dist/util/paths.js.map +1 -1
  284. package/dist/util/subprocess.d.ts +51 -0
  285. package/dist/util/subprocess.d.ts.map +1 -0
  286. package/dist/util/subprocess.js +77 -0
  287. package/dist/util/subprocess.js.map +1 -0
  288. package/package.json +12 -2
  289. package/dist/eval/fixtures/healthcare/audit-gaps.d.ts +0 -28
  290. package/dist/eval/fixtures/healthcare/audit-gaps.d.ts.map +0 -1
  291. package/dist/eval/fixtures/healthcare/audit-gaps.js +0 -90
  292. package/dist/eval/fixtures/healthcare/audit-gaps.js.map +0 -1
  293. package/dist/eval/fixtures/healthcare/consent-bypass.d.ts +0 -31
  294. package/dist/eval/fixtures/healthcare/consent-bypass.d.ts.map +0 -1
  295. package/dist/eval/fixtures/healthcare/consent-bypass.js +0 -61
  296. package/dist/eval/fixtures/healthcare/consent-bypass.js.map +0 -1
  297. package/dist/eval/fixtures/healthcare/phi-in-logs.d.ts +0 -24
  298. package/dist/eval/fixtures/healthcare/phi-in-logs.d.ts.map +0 -1
  299. package/dist/eval/fixtures/healthcare/phi-in-logs.js +0 -41
  300. package/dist/eval/fixtures/healthcare/phi-in-logs.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,21 +1,94 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#61](https://github.com/RCOLKITT/hardening-mcp/pull/61) [`1ecf11d`](https://github.com/RCOLKITT/hardening-mcp/commit/1ecf11dbc073af3430e6df17d0792e2b87ad2568) Thanks [@RCOLKITT](https://github.com/RCOLKITT)! - Agent Certification, independent verification, accuracy + red-team benchmarks, and hardening.
8
+
9
+ **Agent Certification**
10
+
11
+ - Versioned, signable agent certificate schema (six dimensions) with deterministic content digest; `agent_certificate_generate` / `agent_certificate_verify` MCP tools.
12
+ - ISO 42001 + NIST AI RMF compliance mappings and tamper-evident decision provenance (`decision_record`) on the hash chain.
13
+ - EU AI Act control mapping wired into the certification path (31 controls).
14
+
15
+ **Independent verification (don't trust us — verify)**
16
+
17
+ - Standalone certificate verifier: `npm run verify:cert` CLI and a public, unauthenticated `POST /verify` HTTP endpoint that re-checks schema, content digest, and signature without trusting the issuer.
18
+
19
+ **Measured accuracy + red-team**
20
+
21
+ - Accuracy benchmark (`npm run benchmark`, `npm run benchmark:llm`) over labeled fixtures with precision/recall/F1; built-in Semgrep taint rules took deterministic recall from ~10% to ~63% (added SQLi/cmd/SSRF, then insecure-deserialization + XXE), precision 100%.
22
+ - LLM-layer + Anthropic/OpenAI cross-model consensus benchmark.
23
+ - Red-team resistance harness (`npm run benchmark:redteam`) — reproducible prompt-injection resistance score + tool-scope/exfil exposure; fixed a false-positive bug that flagged 100% of tools.
24
+
25
+ **Integrity + supply chain**
26
+
27
+ - Evidence bundles can now be Sigstore-signed and their signatures are really verified (was a presence-only stub).
28
+ - Published manifest now exposes real per-tool input schemas (was an empty placeholder for all tools).
29
+ - Resolved a transitive esbuild advisory.
30
+
31
+ **Hardening (potentially breaking for three tools)**
32
+
33
+ - `deploy_vercel_promote`, `deploy_vercel_rollback`, and `consensus_clear` are now fail-closed: they return a no-op preview unless called with `confirm: true`. Callers that previously relied on these executing immediately must now pass `confirm: true`.
34
+
35
+ ## [2.14.0] - 2026-06-05
36
+
37
+ ### Added
38
+
39
+ #### Antagonist Agent
40
+
41
+ - New meta-analysis agent that runs after all other agents complete
42
+ - **Synthesis mode**: Chains findings into attack narratives mapped to MITRE ATT&CK kill chain
43
+ - **Challenger mode**: Internal critic that flags false positives, coverage gaps, and inconsistencies
44
+ - Prioritized remediation recommendations based on attack surface reduction
45
+ - New `antagonist_synthesize` tool - full analysis with narratives, challenges, and prioritization
46
+ - New `antagonist_challenge` tool - manually challenge specific findings
47
+
48
+ #### Attack Narrative Features
49
+
50
+ - Builds attack graphs from findings and exploit chains
51
+ - Maps vulnerabilities to 14 MITRE ATT&CK kill chain phases
52
+ - Identifies bottleneck findings that block multiple attack paths
53
+ - Generates human-readable attack stories with difficulty/likelihood ratings
54
+
55
+ #### Challenger Features
56
+
57
+ - Detects potential false positives (test files, low confidence, generic descriptions)
58
+ - Identifies untested attack vectors (17 categories tracked)
59
+ - Flags agents with zero findings as potentially incomplete
60
+ - Calculates coverage score across attack surface
61
+
62
+ ### Fixed
63
+
64
+ - Empty catch blocks in `store.ts` and `signing.ts` now log errors
65
+ - Antagonist agent integration test types corrected
66
+
67
+ ### Changed
68
+
69
+ - MCP tools increased from 108 to 110
70
+ - New agent type `antagonist` with weight 0.15 (informs but doesn't dominate consensus)
71
+ - Added to AGENT_VERIFICATION_MAP (verified by security, adversary, redteam)
72
+
3
73
  ## [2.13.0] - 2026-06-04
4
74
 
5
75
  ### Added
6
76
 
7
77
  #### False Positive Feedback System
78
+
8
79
  - New `feedback_submit` tool to mark findings as true/false positives
9
80
  - New `feedback_report` tool to view FP rates by scanner and rule
10
81
  - New `feedback_suppressions` tool to get rule suppression suggestions based on feedback
11
82
  - Feedback stored in `.vaspera/fp-feedback.json` with full audit trail
12
83
 
13
84
  #### Diff-Aware CI Scanning
85
+
14
86
  - New `certification_scan_diff` tool scans only changed files (git diff)
15
87
  - Estimates scan time savings vs full scan
16
88
  - Auto-detects security-critical files that always get scanned
17
89
 
18
90
  #### Standalone Autofix Preview
91
+
19
92
  - `autofix_preview` now works without certification_id
20
93
  - Provide file + pattern_id to preview fixes directly
21
94
  - Use `autofix_list_patterns` to see available fix patterns
@@ -23,27 +96,32 @@
23
96
  ### Fixed
24
97
 
25
98
  #### Persistence DB Fallback
99
+
26
100
  - Added JSON file fallback when SQLite is unavailable
27
101
  - New `src/persistence/json-fallback.ts` with atomic writes
28
102
  - Graceful degradation: warns but continues operating
29
103
 
30
104
  #### scale_bottlenecks False Positives
105
+
31
106
  - Added semantic analysis for workflow/pipeline patterns
32
107
  - Confidence scoring (60-100) based on context
33
108
  - Sequential workflows no longer flagged as N+1 queries
34
109
 
35
110
  #### ai_code_verify Diagnostics
111
+
36
112
  - Returns detailed diagnostics when 0 files found
37
113
  - Shows which extensions were searched
38
114
  - Reports which exclude patterns matched
39
115
  - Suggests alternative file extensions
40
116
 
41
117
  #### Scanner Error Messages
118
+
42
119
  - Added `ScannerErrorDetails` with actionable suggestions
43
120
  - tsc/eslint now report phase (init/scan/parse) and fix steps
44
121
  - Full error output available for debugging
45
122
 
46
123
  ### Changed
124
+
47
125
  - MCP tools increased from 103 to 108
48
126
 
49
127
  ## 2.10.0
package/README.md CHANGED
@@ -2,12 +2,25 @@
2
2
 
3
3
  Enterprise-grade security certification for codebases **and AI agent systems** with deterministic scanners, LLM-powered analysis, and signed attestations.
4
4
 
5
+ [![Self-Certification](https://github.com/RCOLKITT/hardening-mcp/actions/workflows/certify.yml/badge.svg)](https://github.com/RCOLKITT/hardening-mcp/actions/workflows/certify.yml)
6
+ [![CI](https://github.com/RCOLKITT/hardening-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/RCOLKITT/hardening-mcp/actions/workflows/ci.yml)
5
7
  ![npm version](https://img.shields.io/npm/v/vaspera)
6
8
  ![License](https://img.shields.io/badge/License-MIT-green)
7
- ![Tools](https://img.shields.io/badge/MCP_Tools-78-purple)
9
+ ![Tools](https://img.shields.io/badge/MCP_Tools-113-purple)
8
10
  ![AI Frameworks](https://img.shields.io/badge/AI_Frameworks-5-blue)
9
11
  ![Scanners](https://img.shields.io/badge/Scanners-12-orange)
10
- ![Tests](https://img.shields.io/badge/Tests-2942-brightgreen)
12
+ ![Tests](https://img.shields.io/badge/Tests-1891-brightgreen)
13
+
14
+ > **We pass our own strictest certification on every commit.** The
15
+ > Self-Certification badge above is the live result of running this
16
+ > product against its own codebase as a blocking CI gate — the one claim
17
+ > a scanner-wrapper can't fake. [How it works »](docs/SELF-CERTIFICATION.md)
18
+ >
19
+ > **Don't trust us — verify.** Any agent certificate can be checked
20
+ > independently (`npm run verify:cert -- cert.json`, or `POST /verify`)
21
+ > with no token and no trust in Vaspera: it recomputes the content digest
22
+ > and checks the signature from the certificate itself.
23
+ > [Verifying a certificate »](docs/VERIFYING-A-CERTIFICATE.md)
11
24
 
12
25
  ---
13
26
 
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Integration test for Antagonist Agent
3
+ * Tests the full pipeline on sample findings
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=antagonist-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antagonist-integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/antagonist-integration.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Integration test for Antagonist Agent
3
+ * Tests the full pipeline on sample findings
4
+ */
5
+ import { describe, it, expect } from "vitest";
6
+ import { synthesizeNarrativesDeterministic } from "../agents/antagonist/synthesizer.js";
7
+ import { runChallengerDeterministic } from "../agents/antagonist/challenger.js";
8
+ import { prioritizeRemediations } from "../agents/antagonist/prioritizer.js";
9
+ import { DEFAULT_ANTAGONIST_CONFIG } from "../agents/antagonist/types.js";
10
+ // Sample findings that represent real security issues
11
+ const sampleFindings = [
12
+ {
13
+ id: "find-001",
14
+ severity: "high",
15
+ category: "command-injection",
16
+ description: "Potential command injection via unsanitized user input",
17
+ evidence: "spawn(cmd, [userInput])",
18
+ confidence: 85,
19
+ verifications: [],
20
+ created_at: new Date().toISOString(),
21
+ file: "src/scanners/custom.ts",
22
+ line: 42,
23
+ },
24
+ {
25
+ id: "find-002",
26
+ severity: "medium",
27
+ category: "hardcoded-secret",
28
+ description: "Hardcoded API key detected",
29
+ evidence: "const API_KEY = 'sk-...'",
30
+ confidence: 90,
31
+ verifications: [],
32
+ created_at: new Date().toISOString(),
33
+ file: "src/config.ts",
34
+ line: 15,
35
+ },
36
+ {
37
+ id: "find-003",
38
+ severity: "high",
39
+ category: "auth-bypass",
40
+ description: "Missing authentication check on admin endpoint",
41
+ evidence: "No auth middleware on /admin route",
42
+ confidence: 75,
43
+ verifications: [],
44
+ created_at: new Date().toISOString(),
45
+ file: "src/routes/admin.ts",
46
+ line: 8,
47
+ },
48
+ {
49
+ id: "find-004",
50
+ severity: "critical",
51
+ category: "sql-injection",
52
+ description: "SQL injection vulnerability in query builder",
53
+ evidence: "db.query(`SELECT * FROM users WHERE id = ${userId}`)",
54
+ confidence: 95,
55
+ verifications: [],
56
+ created_at: new Date().toISOString(),
57
+ file: "src/db/queries.ts",
58
+ line: 22,
59
+ },
60
+ {
61
+ id: "find-005",
62
+ severity: "low",
63
+ category: "xss",
64
+ description: "Potential XSS in user-generated content",
65
+ evidence: "innerHTML = userContent",
66
+ confidence: 60,
67
+ verifications: [],
68
+ created_at: new Date().toISOString(),
69
+ file: "src/components/Comment.tsx",
70
+ line: 55,
71
+ },
72
+ ];
73
+ // Sample exploit chains (matching ExploitChain type)
74
+ const sampleChains = [
75
+ {
76
+ id: "chain-001",
77
+ name: "Auth Bypass to Data Exfil",
78
+ steps: [
79
+ {
80
+ findingId: "find-003",
81
+ finding: sampleFindings[2],
82
+ role: "entry",
83
+ enables: "find-004",
84
+ techniques: ["T1190"],
85
+ },
86
+ {
87
+ findingId: "find-004",
88
+ finding: sampleFindings[3],
89
+ role: "target",
90
+ prerequisite: "find-003",
91
+ techniques: ["T1213"],
92
+ },
93
+ ],
94
+ totalSeverity: "critical",
95
+ originalSeverities: ["high", "critical"],
96
+ confidence: 85,
97
+ attackScenario: "Attacker bypasses auth, then exfiltrates data via SQL injection",
98
+ mitreAttackIds: ["T1190", "T1213"],
99
+ impact: "Data breach - full database access",
100
+ difficulty: "easy",
101
+ },
102
+ ];
103
+ // Agent summaries
104
+ const agentSummaries = {
105
+ security: { completed: true, findingCount: 5 },
106
+ reliability: { completed: true, findingCount: 2 },
107
+ typesafety: { completed: true, findingCount: 1 },
108
+ performance: { completed: true, findingCount: 0 },
109
+ quality: { completed: true, findingCount: 3 },
110
+ redteam: { completed: true, findingCount: 1 },
111
+ "agent-redteam": { completed: false, findingCount: 0 },
112
+ "agent-privacy": { completed: false, findingCount: 0 },
113
+ "agent-integrity": { completed: false, findingCount: 0 },
114
+ adversary: { completed: false, findingCount: 0 },
115
+ antagonist: { completed: false, findingCount: 0 },
116
+ };
117
+ // Test config with all required fields
118
+ const testConfig = {
119
+ ...DEFAULT_ANTAGONIST_CONFIG,
120
+ maxNarratives: 5,
121
+ minConfidence: 50,
122
+ challengeThreshold: 50,
123
+ };
124
+ describe("Antagonist Integration", () => {
125
+ describe("synthesizeNarrativesDeterministic", () => {
126
+ it("generates attack narratives from findings", () => {
127
+ const narratives = synthesizeNarrativesDeterministic(sampleFindings, sampleChains, [], testConfig);
128
+ expect(narratives.length).toBeGreaterThan(0);
129
+ expect(narratives[0]).toHaveProperty("id");
130
+ expect(narratives[0]).toHaveProperty("name");
131
+ expect(narratives[0]).toHaveProperty("phases");
132
+ expect(narratives[0]).toHaveProperty("narrative");
133
+ expect(narratives[0]).toHaveProperty("findingIds");
134
+ expect(narratives[0]).toHaveProperty("recommendations");
135
+ });
136
+ it("includes MITRE ATT&CK techniques", () => {
137
+ const narratives = synthesizeNarrativesDeterministic(sampleFindings, sampleChains, [], testConfig);
138
+ const narrativeWithTechniques = narratives.find((n) => n.mitreTechniques.length > 0);
139
+ expect(narrativeWithTechniques).toBeDefined();
140
+ });
141
+ it("maps findings to kill chain phases", () => {
142
+ const narratives = synthesizeNarrativesDeterministic(sampleFindings, sampleChains, [], testConfig);
143
+ const narrative = narratives[0];
144
+ expect(narrative.phases.length).toBeGreaterThan(0);
145
+ expect(narrative.phases[0]).toHaveProperty("phase");
146
+ expect(narrative.phases[0]).toHaveProperty("description");
147
+ });
148
+ it("prioritizes critical findings in narratives", () => {
149
+ const narratives = synthesizeNarrativesDeterministic(sampleFindings, sampleChains, [], testConfig);
150
+ const hasCritical = narratives.some((n) => n.findingIds.includes("find-004"));
151
+ expect(hasCritical).toBe(true);
152
+ });
153
+ });
154
+ describe("runChallengerDeterministic", () => {
155
+ it("identifies coverage gaps", () => {
156
+ const result = runChallengerDeterministic(sampleFindings, agentSummaries, testConfig);
157
+ expect(result.assessments).toBeDefined();
158
+ expect(result.gapAnalysis).toBeDefined();
159
+ expect(result.gapAnalysis).toHaveProperty("untestedAttackVectors");
160
+ expect(result.gapAnalysis).toHaveProperty("missingControls");
161
+ expect(result.gapAnalysis).toHaveProperty("coverageScore");
162
+ });
163
+ it("flags potential false positives", () => {
164
+ const findingsWithTestFile = [
165
+ ...sampleFindings,
166
+ {
167
+ id: "find-test",
168
+ severity: "medium",
169
+ category: "sql-injection",
170
+ description: "SQL injection in test",
171
+ evidence: "test code",
172
+ confidence: 60,
173
+ verifications: [],
174
+ created_at: new Date().toISOString(),
175
+ file: "src/__tests__/db.test.ts",
176
+ line: 10,
177
+ },
178
+ ];
179
+ const result = runChallengerDeterministic(findingsWithTestFile, agentSummaries, testConfig);
180
+ const testChallenge = result.assessments.find((c) => c.targetFindingId === "find-test" && c.type === "false_positive_likely");
181
+ expect(testChallenge).toBeDefined();
182
+ expect(testChallenge?.challenge).toContain("false positive");
183
+ });
184
+ it("warns about agents with zero findings", () => {
185
+ const summariesWithZero = {
186
+ ...agentSummaries,
187
+ performance: { completed: true, findingCount: 0 },
188
+ };
189
+ const result = runChallengerDeterministic(sampleFindings, summariesWithZero, testConfig);
190
+ const zeroFindingChallenge = result.assessments.find((c) => c.type === "missed_check" && c.targetAgent === "performance");
191
+ expect(zeroFindingChallenge).toBeDefined();
192
+ });
193
+ });
194
+ describe("prioritizeRemediations", () => {
195
+ it("generates prioritized remediation list", () => {
196
+ const narratives = synthesizeNarrativesDeterministic(sampleFindings, sampleChains, [], testConfig);
197
+ const prioritized = prioritizeRemediations(sampleFindings, narratives);
198
+ expect(prioritized.length).toBeGreaterThan(0);
199
+ expect(prioritized[0]).toHaveProperty("order");
200
+ expect(prioritized[0]).toHaveProperty("findingId");
201
+ expect(prioritized[0]).toHaveProperty("reason");
202
+ expect(prioritized[0]).toHaveProperty("effort");
203
+ expect(prioritized[0]).toHaveProperty("impact");
204
+ });
205
+ it("prioritizes critical findings first", () => {
206
+ const narratives = synthesizeNarrativesDeterministic(sampleFindings, sampleChains, [], testConfig);
207
+ const prioritized = prioritizeRemediations(sampleFindings, narratives);
208
+ const criticalPosition = prioritized.findIndex((p) => p.findingId === "find-004");
209
+ expect(criticalPosition).toBeLessThan(3);
210
+ });
211
+ it("considers bottleneck findings (appear in multiple narratives)", () => {
212
+ const narratives = synthesizeNarrativesDeterministic(sampleFindings, sampleChains, [], testConfig);
213
+ const prioritized = prioritizeRemediations(sampleFindings, narratives);
214
+ const hasBlocksNarratives = prioritized.some((p) => p.blocksNarratives && p.blocksNarratives.length > 0);
215
+ expect(hasBlocksNarratives).toBe(true);
216
+ });
217
+ });
218
+ describe("Full pipeline", () => {
219
+ it("runs complete antagonist analysis", () => {
220
+ const narratives = synthesizeNarrativesDeterministic(sampleFindings, sampleChains, [], testConfig);
221
+ const challengerResult = runChallengerDeterministic(sampleFindings, agentSummaries, testConfig);
222
+ const prioritized = prioritizeRemediations(sampleFindings, narratives);
223
+ expect(narratives.length).toBeGreaterThan(0);
224
+ expect(challengerResult.assessments).toBeDefined();
225
+ expect(challengerResult.gapAnalysis).toBeDefined();
226
+ expect(prioritized.length).toBeGreaterThan(0);
227
+ console.log("\n=== Antagonist Analysis Summary ===");
228
+ console.log(`Attack Narratives: ${narratives.length}`);
229
+ console.log(`Challenger Assessments: ${challengerResult.assessments.length}`);
230
+ console.log(`Coverage Score: ${challengerResult.gapAnalysis.coverageScore}%`);
231
+ console.log(`Prioritized Remediations: ${prioritized.length}`);
232
+ console.log("\nTop 3 Remediation Priorities:");
233
+ prioritized.slice(0, 3).forEach((p, i) => {
234
+ console.log(` ${i + 1}. ${p.findingId}: ${p.reason}`);
235
+ });
236
+ });
237
+ });
238
+ });
239
+ //# sourceMappingURL=antagonist-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antagonist-integration.test.js","sourceRoot":"","sources":["../../src/__tests__/antagonist-integration.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAI1E,sDAAsD;AACtD,MAAM,cAAc,GAAc;IAChC;QACE,EAAE,EAAE,UAAU;QACd,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE,mBAAmB;QAC7B,WAAW,EAAE,wDAAwD;QACrE,QAAQ,EAAE,yBAAyB;QACnC,UAAU,EAAE,EAAE;QACd,aAAa,EAAE,EAAE;QACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE,wBAAwB;QAC9B,IAAI,EAAE,EAAE;KACT;IACD;QACE,EAAE,EAAE,UAAU;QACd,QAAQ,EAAE,QAAQ;QAClB,QAAQ,EAAE,kBAAkB;QAC5B,WAAW,EAAE,4BAA4B;QACzC,QAAQ,EAAE,0BAA0B;QACpC,UAAU,EAAE,EAAE;QACd,aAAa,EAAE,EAAE;QACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,EAAE;KACT;IACD;QACE,EAAE,EAAE,UAAU;QACd,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE,aAAa;QACvB,WAAW,EAAE,gDAAgD;QAC7D,QAAQ,EAAE,oCAAoC;QAC9C,UAAU,EAAE,EAAE;QACd,aAAa,EAAE,EAAE;QACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,CAAC;KACR;IACD;QACE,EAAE,EAAE,UAAU;QACd,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,eAAe;QACzB,WAAW,EAAE,8CAA8C;QAC3D,QAAQ,EAAE,sDAAsD;QAChE,UAAU,EAAE,EAAE;QACd,aAAa,EAAE,EAAE;QACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,EAAE;KACT;IACD;QACE,EAAE,EAAE,UAAU;QACd,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,yCAAyC;QACtD,QAAQ,EAAE,yBAAyB;QACnC,UAAU,EAAE,EAAE;QACd,aAAa,EAAE,EAAE;QACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE,4BAA4B;QAClC,IAAI,EAAE,EAAE;KACT;CACF,CAAC;AAEF,qDAAqD;AACrD,MAAM,YAAY,GAAmB;IACnC;QACE,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,2BAA2B;QACjC,KAAK,EAAE;YACL;gBACE,SAAS,EAAE,UAAU;gBACrB,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;gBAC1B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,UAAU;gBACnB,UAAU,EAAE,CAAC,OAAO,CAAC;aACtB;YACD;gBACE,SAAS,EAAE,UAAU;gBACrB,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;gBAC1B,IAAI,EAAE,QAAQ;gBACd,YAAY,EAAE,UAAU;gBACxB,UAAU,EAAE,CAAC,OAAO,CAAC;aACtB;SACF;QACD,aAAa,EAAE,UAAU;QACzB,kBAAkB,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;QACxC,UAAU,EAAE,EAAE;QACd,cAAc,EAAE,iEAAiE;QACjF,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QAClC,MAAM,EAAE,oCAAoC;QAC5C,UAAU,EAAE,MAAM;KACnB;CACF,CAAC;AAEF,kBAAkB;AAClB,MAAM,cAAc,GAAoE;IACtF,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;IAC9C,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;IACjD,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;IAChD,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;IACjD,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;IAC7C,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;IAC7C,eAAe,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;IACtD,eAAe,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;IACtD,iBAAiB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;IACxD,SAAS,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;IAChD,UAAU,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;CAClD,CAAC;AAEF,uCAAuC;AACvC,MAAM,UAAU,GAAG;IACjB,GAAG,yBAAyB;IAC5B,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,EAAE;IACjB,kBAAkB,EAAE,EAAE;CACvB,CAAC;AAEF,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACjD,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,UAAU,GAAG,iCAAiC,CAClD,cAAc,EACd,YAAY,EACZ,EAAE,EACF,UAAU,CACX,CAAC;YAEF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAC7C,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;YAClD,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YACnD,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,UAAU,GAAG,iCAAiC,CAClD,cAAc,EACd,YAAY,EACZ,EAAE,EACF,UAAU,CACX,CAAC;YAEF,MAAM,uBAAuB,GAAG,UAAU,CAAC,IAAI,CAC7C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CACpC,CAAC;YACF,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,UAAU,GAAG,iCAAiC,CAClD,cAAc,EACd,YAAY,EACZ,EAAE,EACF,UAAU,CACX,CAAC;YAEF,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACnD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACpD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,UAAU,GAAG,iCAAiC,CAClD,cAAc,EACd,YAAY,EACZ,EAAE,EACF,UAAU,CACX,CAAC;YAEF,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACxC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,CAClC,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,MAAM,GAAG,0BAA0B,CACvC,cAAc,EACd,cAAc,EACd,UAAU,CACX,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,uBAAuB,CAAC,CAAC;YACnE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,oBAAoB,GAAc;gBACtC,GAAG,cAAc;gBACjB;oBACE,EAAE,EAAE,WAAW;oBACf,QAAQ,EAAE,QAAQ;oBAClB,QAAQ,EAAE,eAAe;oBACzB,WAAW,EAAE,uBAAuB;oBACpC,QAAQ,EAAE,WAAW;oBACrB,UAAU,EAAE,EAAE;oBACd,aAAa,EAAE,EAAE;oBACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACpC,IAAI,EAAE,0BAA0B;oBAChC,IAAI,EAAE,EAAE;iBACT;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,0BAA0B,CACvC,oBAAoB,EACpB,cAAc,EACd,UAAU,CACX,CAAC;YAEF,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,uBAAuB,CAC/E,CAAC;YACF,MAAM,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;YACpC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,iBAAiB,GAAG;gBACxB,GAAG,cAAc;gBACjB,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;aAClD,CAAC;YAEF,MAAM,MAAM,GAAG,0BAA0B,CACvC,cAAc,EACd,iBAAiB,EACjB,UAAU,CACX,CAAC;YAEF,MAAM,oBAAoB,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAClD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,IAAI,CAAC,CAAC,WAAW,KAAK,aAAa,CACpE,CAAC;YACF,MAAM,CAAC,oBAAoB,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,UAAU,GAAG,iCAAiC,CAClD,cAAc,EACd,YAAY,EACZ,EAAE,EACF,UAAU,CACX,CAAC;YAEF,MAAM,WAAW,GAAG,sBAAsB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;YAEvE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAC/C,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;YACnD,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,UAAU,GAAG,iCAAiC,CAClD,cAAc,EACd,YAAY,EACZ,EAAE,EACF,UAAU,CACX,CAAC;YAEF,MAAM,WAAW,GAAG,sBAAsB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;YAEvE,MAAM,gBAAgB,GAAG,WAAW,CAAC,SAAS,CAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,UAAU,CAClC,CAAC;YACF,MAAM,CAAC,gBAAgB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,MAAM,UAAU,GAAG,iCAAiC,CAClD,cAAc,EACd,YAAY,EACZ,EAAE,EACF,UAAU,CACX,CAAC;YAEF,MAAM,WAAW,GAAG,sBAAsB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;YAEvE,MAAM,mBAAmB,GAAG,WAAW,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAC3D,CAAC;YACF,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,UAAU,GAAG,iCAAiC,CAClD,cAAc,EACd,YAAY,EACZ,EAAE,EACF,UAAU,CACX,CAAC;YAEF,MAAM,gBAAgB,GAAG,0BAA0B,CACjD,cAAc,EACd,cAAc,EACd,UAAU,CACX,CAAC;YAEF,MAAM,WAAW,GAAG,sBAAsB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;YAEvE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAC7C,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;YACnD,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;YACnD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAE9C,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,sBAAsB,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,2BAA2B,gBAAgB,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9E,OAAO,CAAC,GAAG,CAAC,mBAAmB,gBAAgB,CAAC,WAAW,CAAC,aAAa,GAAG,CAAC,CAAC;YAC9E,OAAO,CAAC,GAAG,CAAC,6BAA6B,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;YAC/C,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-certificate-e2e.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-certificate-e2e.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/certification/agent-certificate-e2e.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,90 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { mkdtemp, rm } from "fs/promises";
3
+ import { tmpdir } from "os";
4
+ import { join } from "path";
5
+ import { recordDecision, getDecisionProvenance } from "../../history/decisions.js";
6
+ import { certificationToCertificateBody } from "../../certification/agent-certificate-map.js";
7
+ import { finalizeCertificate, verifyCertificate } from "../../certification/agent-certificate.js";
8
+ function certification() {
9
+ return {
10
+ metadata: {
11
+ id: "cert_e2e",
12
+ project_name: "e2e-agent",
13
+ project_path: "/tmp/e2e-agent",
14
+ started_at: "2026-06-12T00:00:00.000Z",
15
+ completed_at: "2026-06-12T00:05:00.000Z",
16
+ status: "completed",
17
+ agents_requested: ["security"],
18
+ agents_completed: ["security"],
19
+ certification_level: "APPROVED",
20
+ final_score: 84,
21
+ project_hash: "deadbeef",
22
+ },
23
+ agents: {
24
+ security: {
25
+ agent: "security",
26
+ started_at: "2026-06-12T00:00:00.000Z",
27
+ completed_at: "2026-06-12T00:03:00.000Z",
28
+ status: "completed",
29
+ findings: [
30
+ {
31
+ id: "f1",
32
+ severity: "high",
33
+ category: "exfil-path",
34
+ description: "Secret can reach the network",
35
+ evidence: "…",
36
+ confidence: 95,
37
+ verifications: [],
38
+ created_at: "2026-06-12T00:01:00.000Z",
39
+ },
40
+ ],
41
+ },
42
+ },
43
+ cross_verifications: [],
44
+ red_team_challenges: [],
45
+ };
46
+ }
47
+ describe("agent certificate — full flow (decisions + frameworks + provenance)", () => {
48
+ let dir;
49
+ beforeEach(async () => {
50
+ dir = await mkdtemp(join(tmpdir(), "cert-e2e-"));
51
+ });
52
+ afterEach(async () => {
53
+ await rm(dir, { recursive: true, force: true });
54
+ });
55
+ it("records decisions, builds a certificate with real frameworks + provenance, verifies", async () => {
56
+ // 1) capture decision provenance on the hash chain
57
+ await recordDecision(dir, { decisionType: "tool_call", model: "m", input: "x", output: "y" });
58
+ await recordDecision(dir, { decisionType: "gen", model: "m", input: "p", output: "q" });
59
+ const provenance = await getDecisionProvenance(dir);
60
+ expect(provenance.decisionRecords).toBe(2);
61
+ // 2) build a certificate from a real certification + AI frameworks + provenance
62
+ const body = certificationToCertificateBody(certification(), {
63
+ toolVersion: "2.14.0",
64
+ issuedAt: "2026-06-12T00:00:00.000Z",
65
+ expiresAt: "2026-09-10T00:00:00.000Z",
66
+ certificateId: "vac_e2e_1",
67
+ complianceFrameworks: ["ISO-42001", "NIST-AI-RMF"],
68
+ provenance,
69
+ });
70
+ // compliance dimension is real (mapped controls, not a label)
71
+ expect(body.dimensions.compliance.frameworks.map((f) => f.framework)).toEqual([
72
+ "ISO-42001",
73
+ "NIST-AI-RMF",
74
+ ]);
75
+ expect(body.dimensions.compliance.frameworks[0].controlsTotal).toBeGreaterThan(0);
76
+ // the exfil-path finding should fail at least one control
77
+ const totalFailed = body.dimensions.compliance.frameworks.reduce((n, f) => n + f.controlsFailed, 0);
78
+ expect(totalFailed).toBeGreaterThan(0);
79
+ // explainability reflects the recorded decisions
80
+ expect(body.dimensions.explainability.checks.some((c) => c.id === "decision-provenance")).toBe(true);
81
+ expect(body.provenance.decisionRecords).toBe(2);
82
+ expect(body.provenance.auditTrailHead).toBe(provenance.auditTrailHead);
83
+ // 3) finalize + verify independently
84
+ const cert = await finalizeCertificate(body);
85
+ const result = await verifyCertificate(cert);
86
+ expect(result.valid).toBe(true);
87
+ expect(result.contentDigestValid).toBe(true);
88
+ });
89
+ });
90
+ //# sourceMappingURL=agent-certificate-e2e.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-certificate-e2e.test.js","sourceRoot":"","sources":["../../../src/__tests__/certification/agent-certificate-e2e.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,8CAA8C,CAAC;AAC9F,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAGlG,SAAS,aAAa;IACpB,OAAO;QACL,QAAQ,EAAE;YACR,EAAE,EAAE,UAAU;YACd,YAAY,EAAE,WAAW;YACzB,YAAY,EAAE,gBAAgB;YAC9B,UAAU,EAAE,0BAA0B;YACtC,YAAY,EAAE,0BAA0B;YACxC,MAAM,EAAE,WAAW;YACnB,gBAAgB,EAAE,CAAC,UAAU,CAAC;YAC9B,gBAAgB,EAAE,CAAC,UAAU,CAAC;YAC9B,mBAAmB,EAAE,UAAU;YAC/B,WAAW,EAAE,EAAE;YACf,YAAY,EAAE,UAAU;SACzB;QACD,MAAM,EAAE;YACN,QAAQ,EAAE;gBACR,KAAK,EAAE,UAAU;gBACjB,UAAU,EAAE,0BAA0B;gBACtC,YAAY,EAAE,0BAA0B;gBACxC,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,IAAI;wBACR,QAAQ,EAAE,MAAM;wBAChB,QAAQ,EAAE,YAAY;wBACtB,WAAW,EAAE,8BAA8B;wBAC3C,QAAQ,EAAE,GAAG;wBACb,UAAU,EAAE,EAAE;wBACd,aAAa,EAAE,EAAE;wBACjB,UAAU,EAAE,0BAA0B;qBACvC;iBACF;aACF;SACF;QACD,mBAAmB,EAAE,EAAE;QACvB,mBAAmB,EAAE,EAAE;KACxB,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,qEAAqE,EAAE,GAAG,EAAE;IACnF,IAAI,GAAW,CAAC;IAChB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qFAAqF,EAAE,KAAK,IAAI,EAAE;QACnG,mDAAmD;QACnD,MAAM,cAAc,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9F,MAAM,cAAc,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACxF,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE3C,gFAAgF;QAChF,MAAM,IAAI,GAAG,8BAA8B,CAAC,aAAa,EAAE,EAAE;YAC3D,WAAW,EAAE,QAAQ;YACrB,QAAQ,EAAE,0BAA0B;YACpC,SAAS,EAAE,0BAA0B;YACrC,aAAa,EAAE,WAAW;YAC1B,oBAAoB,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC;YAClD,UAAU;SACX,CAAC,CAAC;QAEH,8DAA8D;QAC9D,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5E,WAAW;YACX,aAAa;SACd,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAClF,0DAA0D;QAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAC9D,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,cAAc,EAC9B,CAAC,CACF,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEvC,iDAAiD;QACjD,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAC5F,IAAI,CACL,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QAEvE,qCAAqC;QACrC,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-certificate-map.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-certificate-map.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/certification/agent-certificate-map.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,107 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { certificationToCertificateBody, baselineCertificateBody, } from "../../certification/agent-certificate-map.js";
3
+ import { finalizeCertificate, verifyCertificate, } from "../../certification/agent-certificate.js";
4
+ const opts = {
5
+ toolVersion: "2.14.0",
6
+ issuedAt: "2026-06-11T00:00:00.000Z",
7
+ expiresAt: "2026-09-09T00:00:00.000Z",
8
+ certificateId: "vac_map_0001",
9
+ };
10
+ function fakeCertification() {
11
+ return {
12
+ metadata: {
13
+ id: "cert_1",
14
+ project_name: "demo-agent",
15
+ project_path: "/tmp/demo-agent",
16
+ started_at: "2026-06-11T00:00:00.000Z",
17
+ completed_at: "2026-06-11T00:05:00.000Z",
18
+ status: "completed",
19
+ agents_requested: ["security", "quality"],
20
+ agents_completed: ["security", "quality"],
21
+ certification_level: "APPROVED",
22
+ final_score: 82,
23
+ project_hash: "abc123def456",
24
+ },
25
+ agents: {
26
+ security: {
27
+ agent: "security",
28
+ started_at: "2026-06-11T00:00:00.000Z",
29
+ completed_at: "2026-06-11T00:03:00.000Z",
30
+ status: "completed",
31
+ findings: [
32
+ {
33
+ id: "f1",
34
+ severity: "high",
35
+ category: "prompt-injection",
36
+ file: "src/agent.ts",
37
+ line: 42,
38
+ description: "Untrusted input flows into the system prompt",
39
+ evidence: "…",
40
+ confidence: 90,
41
+ verifications: [],
42
+ created_at: "2026-06-11T00:01:00.000Z",
43
+ },
44
+ {
45
+ id: "f2",
46
+ severity: "low",
47
+ category: "logging-failure",
48
+ description: "Missing structured logging",
49
+ evidence: "…",
50
+ confidence: 70,
51
+ verifications: [],
52
+ created_at: "2026-06-11T00:02:00.000Z",
53
+ },
54
+ ],
55
+ },
56
+ quality: {
57
+ agent: "quality",
58
+ started_at: "2026-06-11T00:00:00.000Z",
59
+ completed_at: "2026-06-11T00:04:00.000Z",
60
+ status: "completed",
61
+ findings: [],
62
+ },
63
+ },
64
+ cross_verifications: [],
65
+ red_team_challenges: [],
66
+ };
67
+ }
68
+ describe("certificationToCertificateBody", () => {
69
+ it("maps a real certification into a verifiable certificate", async () => {
70
+ const body = certificationToCertificateBody(fakeCertification(), opts);
71
+ expect(body.subject.name).toBe("demo-agent");
72
+ expect(body.subject.digest).toBe("abc123def456");
73
+ expect(body.level).toBe("APPROVED");
74
+ expect(body.overallScore).toBe(82);
75
+ // security has a high finding -> fail status, surfaced as a check
76
+ expect(body.dimensions.security.status).toBe("fail");
77
+ expect(body.dimensions.security.checks.some((c) => c.category === "prompt-injection")).toBe(true);
78
+ // quality had no findings -> pass
79
+ expect(body.dimensions.quality.status).toBe("pass");
80
+ // compliance not run -> not_assessed (never fabricated)
81
+ expect(body.dimensions.compliance.status).toBe("not_assessed");
82
+ const cert = await finalizeCertificate(body);
83
+ const result = await verifyCertificate(cert);
84
+ expect(result.valid).toBe(true);
85
+ });
86
+ it("surfaces the most severe findings first and caps the list", () => {
87
+ const c = fakeCertification();
88
+ const body = certificationToCertificateBody(c, opts);
89
+ expect(body.dimensions.security.checks[0].severity).toBe("high");
90
+ });
91
+ it("baseline body is honest — all dimensions not_assessed and verifiable", async () => {
92
+ const body = baselineCertificateBody({
93
+ ...opts,
94
+ subjectName: "fresh-agent",
95
+ subjectKind: "agent",
96
+ identifier: "/tmp/fresh-agent",
97
+ });
98
+ expect(body.overallScore).toBe(0);
99
+ expect(body.level).toBe("REVIEW_REQUIRED");
100
+ for (const dim of Object.values(body.dimensions)) {
101
+ expect(dim.status).toBe("not_assessed");
102
+ }
103
+ const cert = await finalizeCertificate(body);
104
+ expect((await verifyCertificate(cert)).valid).toBe(true);
105
+ });
106
+ });
107
+ //# sourceMappingURL=agent-certificate-map.test.js.map