vaspera 2.14.0 → 2.16.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 (265) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +15 -2
  3. package/dist/__tests__/certification/agent-certificate-e2e.test.d.ts +2 -0
  4. package/dist/__tests__/certification/agent-certificate-e2e.test.d.ts.map +1 -0
  5. package/dist/__tests__/certification/agent-certificate-e2e.test.js +90 -0
  6. package/dist/__tests__/certification/agent-certificate-e2e.test.js.map +1 -0
  7. package/dist/__tests__/certification/agent-certificate-map.test.d.ts +2 -0
  8. package/dist/__tests__/certification/agent-certificate-map.test.d.ts.map +1 -0
  9. package/dist/__tests__/certification/agent-certificate-map.test.js +107 -0
  10. package/dist/__tests__/certification/agent-certificate-map.test.js.map +1 -0
  11. package/dist/__tests__/certification/agent-certificate.test.d.ts +2 -0
  12. package/dist/__tests__/certification/agent-certificate.test.d.ts.map +1 -0
  13. package/dist/__tests__/certification/agent-certificate.test.js +78 -0
  14. package/dist/__tests__/certification/agent-certificate.test.js.map +1 -0
  15. package/dist/__tests__/certification/verify-endpoint.test.d.ts +2 -0
  16. package/dist/__tests__/certification/verify-endpoint.test.d.ts.map +1 -0
  17. package/dist/__tests__/certification/verify-endpoint.test.js +81 -0
  18. package/dist/__tests__/certification/verify-endpoint.test.js.map +1 -0
  19. package/dist/__tests__/compliance/ai-frameworks.test.d.ts +2 -0
  20. package/dist/__tests__/compliance/ai-frameworks.test.d.ts.map +1 -0
  21. package/dist/__tests__/compliance/ai-frameworks.test.js +87 -0
  22. package/dist/__tests__/compliance/ai-frameworks.test.js.map +1 -0
  23. package/dist/__tests__/eval/llm-analyzer.test.d.ts +2 -0
  24. package/dist/__tests__/eval/llm-analyzer.test.d.ts.map +1 -0
  25. package/dist/__tests__/eval/llm-analyzer.test.js +93 -0
  26. package/dist/__tests__/eval/llm-analyzer.test.js.map +1 -0
  27. package/dist/__tests__/eval/redteam-harness.test.d.ts +2 -0
  28. package/dist/__tests__/eval/redteam-harness.test.d.ts.map +1 -0
  29. package/dist/__tests__/eval/redteam-harness.test.js +136 -0
  30. package/dist/__tests__/eval/redteam-harness.test.js.map +1 -0
  31. package/dist/__tests__/evidence/evidence.test.d.ts +2 -0
  32. package/dist/__tests__/evidence/evidence.test.d.ts.map +1 -0
  33. package/dist/__tests__/evidence/evidence.test.js +240 -0
  34. package/dist/__tests__/evidence/evidence.test.js.map +1 -0
  35. package/dist/__tests__/history/decisions.test.d.ts +2 -0
  36. package/dist/__tests__/history/decisions.test.d.ts.map +1 -0
  37. package/dist/__tests__/history/decisions.test.js +54 -0
  38. package/dist/__tests__/history/decisions.test.js.map +1 -0
  39. package/dist/__tests__/http-auth.test.d.ts +2 -0
  40. package/dist/__tests__/http-auth.test.d.ts.map +1 -0
  41. package/dist/__tests__/http-auth.test.js +55 -0
  42. package/dist/__tests__/http-auth.test.js.map +1 -0
  43. package/dist/__tests__/http-policy.test.d.ts +2 -0
  44. package/dist/__tests__/http-policy.test.d.ts.map +1 -0
  45. package/dist/__tests__/http-policy.test.js +69 -0
  46. package/dist/__tests__/http-policy.test.js.map +1 -0
  47. package/dist/__tests__/http-server-transport.test.d.ts +2 -0
  48. package/dist/__tests__/http-server-transport.test.d.ts.map +1 -0
  49. package/dist/__tests__/http-server-transport.test.js +132 -0
  50. package/dist/__tests__/http-server-transport.test.js.map +1 -0
  51. package/dist/__tests__/integration/destructive-guards.test.d.ts +2 -0
  52. package/dist/__tests__/integration/destructive-guards.test.d.ts.map +1 -0
  53. package/dist/__tests__/integration/destructive-guards.test.js +49 -0
  54. package/dist/__tests__/integration/destructive-guards.test.js.map +1 -0
  55. package/dist/__tests__/logger-redaction.test.d.ts +2 -0
  56. package/dist/__tests__/logger-redaction.test.d.ts.map +1 -0
  57. package/dist/__tests__/logger-redaction.test.js +74 -0
  58. package/dist/__tests__/logger-redaction.test.js.map +1 -0
  59. package/dist/__tests__/manifest-schema.test.d.ts +2 -0
  60. package/dist/__tests__/manifest-schema.test.d.ts.map +1 -0
  61. package/dist/__tests__/manifest-schema.test.js +43 -0
  62. package/dist/__tests__/manifest-schema.test.js.map +1 -0
  63. package/dist/__tests__/scanners/builtin-rules.test.d.ts +2 -0
  64. package/dist/__tests__/scanners/builtin-rules.test.d.ts.map +1 -0
  65. package/dist/__tests__/scanners/builtin-rules.test.js +51 -0
  66. package/dist/__tests__/scanners/builtin-rules.test.js.map +1 -0
  67. package/dist/__tests__/scanners/runtime/golden-path-runner.test.js +13 -1
  68. package/dist/__tests__/scanners/runtime/golden-path-runner.test.js.map +1 -1
  69. package/dist/__tests__/tool-guard.test.d.ts +2 -0
  70. package/dist/__tests__/tool-guard.test.d.ts.map +1 -0
  71. package/dist/__tests__/tool-guard.test.js +97 -0
  72. package/dist/__tests__/tool-guard.test.js.map +1 -0
  73. package/dist/__tests__/util/contained-file.test.d.ts +2 -0
  74. package/dist/__tests__/util/contained-file.test.d.ts.map +1 -0
  75. package/dist/__tests__/util/contained-file.test.js +78 -0
  76. package/dist/__tests__/util/contained-file.test.js.map +1 -0
  77. package/dist/__tests__/util/subprocess.test.d.ts +2 -0
  78. package/dist/__tests__/util/subprocess.test.d.ts.map +1 -0
  79. package/dist/__tests__/util/subprocess.test.js +48 -0
  80. package/dist/__tests__/util/subprocess.test.js.map +1 -0
  81. package/dist/action/diff-mode.d.ts.map +1 -1
  82. package/dist/action/diff-mode.js +31 -12
  83. package/dist/action/diff-mode.js.map +1 -1
  84. package/dist/certification/agent-certificate-map.d.ts +51 -0
  85. package/dist/certification/agent-certificate-map.d.ts.map +1 -0
  86. package/dist/certification/agent-certificate-map.js +265 -0
  87. package/dist/certification/agent-certificate-map.js.map +1 -0
  88. package/dist/certification/agent-certificate-sample.d.ts +25 -0
  89. package/dist/certification/agent-certificate-sample.d.ts.map +1 -0
  90. package/dist/certification/agent-certificate-sample.js +207 -0
  91. package/dist/certification/agent-certificate-sample.js.map +1 -0
  92. package/dist/certification/agent-certificate.d.ts +1981 -0
  93. package/dist/certification/agent-certificate.d.ts.map +1 -0
  94. package/dist/certification/agent-certificate.js +309 -0
  95. package/dist/certification/agent-certificate.js.map +1 -0
  96. package/dist/certification/autofix.d.ts.map +1 -1
  97. package/dist/certification/autofix.js +5 -3
  98. package/dist/certification/autofix.js.map +1 -1
  99. package/dist/certification/store.d.ts.map +1 -1
  100. package/dist/certification/store.js +5 -2
  101. package/dist/certification/store.js.map +1 -1
  102. package/dist/certification/verify-endpoint.d.ts +48 -0
  103. package/dist/certification/verify-endpoint.d.ts.map +1 -0
  104. package/dist/certification/verify-endpoint.js +79 -0
  105. package/dist/certification/verify-endpoint.js.map +1 -0
  106. package/dist/compliance/index.d.ts +2 -0
  107. package/dist/compliance/index.d.ts.map +1 -1
  108. package/dist/compliance/index.js +4 -0
  109. package/dist/compliance/index.js.map +1 -1
  110. package/dist/compliance/iso42001.d.ts +21 -0
  111. package/dist/compliance/iso42001.d.ts.map +1 -0
  112. package/dist/compliance/iso42001.js +160 -0
  113. package/dist/compliance/iso42001.js.map +1 -0
  114. package/dist/compliance/mapper.d.ts.map +1 -1
  115. package/dist/compliance/mapper.js +12 -0
  116. package/dist/compliance/mapper.js.map +1 -1
  117. package/dist/compliance/nist-ai-rmf.d.ts +20 -0
  118. package/dist/compliance/nist-ai-rmf.d.ts.map +1 -0
  119. package/dist/compliance/nist-ai-rmf.js +140 -0
  120. package/dist/compliance/nist-ai-rmf.js.map +1 -0
  121. package/dist/config/flags.d.ts +4 -4
  122. package/dist/eval/fixtures.d.ts.map +1 -1
  123. package/dist/eval/fixtures.js +161 -119
  124. package/dist/eval/fixtures.js.map +1 -1
  125. package/dist/eval/fixtures.test.js +4 -2
  126. package/dist/eval/fixtures.test.js.map +1 -1
  127. package/dist/eval/llm-analyzer.d.ts +40 -0
  128. package/dist/eval/llm-analyzer.d.ts.map +1 -0
  129. package/dist/eval/llm-analyzer.js +154 -0
  130. package/dist/eval/llm-analyzer.js.map +1 -0
  131. package/dist/eval/redteam-harness.d.ts +95 -0
  132. package/dist/eval/redteam-harness.d.ts.map +1 -0
  133. package/dist/eval/redteam-harness.js +137 -0
  134. package/dist/eval/redteam-harness.js.map +1 -0
  135. package/dist/evidence/collector.d.ts.map +1 -1
  136. package/dist/evidence/collector.js +21 -1
  137. package/dist/evidence/collector.js.map +1 -1
  138. package/dist/evidence/store.d.ts.map +1 -1
  139. package/dist/evidence/store.js +29 -5
  140. package/dist/evidence/store.js.map +1 -1
  141. package/dist/evidence/types.d.ts +16 -9
  142. package/dist/evidence/types.d.ts.map +1 -1
  143. package/dist/history/decisions.d.ts +63 -0
  144. package/dist/history/decisions.d.ts.map +1 -0
  145. package/dist/history/decisions.js +60 -0
  146. package/dist/history/decisions.js.map +1 -0
  147. package/dist/history/index.d.ts +2 -0
  148. package/dist/history/index.d.ts.map +1 -1
  149. package/dist/history/index.js +2 -0
  150. package/dist/history/index.js.map +1 -1
  151. package/dist/history/types.d.ts +34 -5
  152. package/dist/history/types.d.ts.map +1 -1
  153. package/dist/history/types.js +2 -0
  154. package/dist/history/types.js.map +1 -1
  155. package/dist/http-auth.d.ts +22 -0
  156. package/dist/http-auth.d.ts.map +1 -0
  157. package/dist/http-auth.js +58 -0
  158. package/dist/http-auth.js.map +1 -0
  159. package/dist/http-policy.d.ts +30 -0
  160. package/dist/http-policy.d.ts.map +1 -0
  161. package/dist/http-policy.js +54 -0
  162. package/dist/http-policy.js.map +1 -0
  163. package/dist/http-server.js +195 -12
  164. package/dist/http-server.js.map +1 -1
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +257 -16
  167. package/dist/index.js.map +1 -1
  168. package/dist/logger.d.ts.map +1 -1
  169. package/dist/logger.js +56 -2
  170. package/dist/logger.js.map +1 -1
  171. package/dist/plugins/types.d.ts +2 -2
  172. package/dist/scanners/agent/prompt-injection-fuzzer.d.ts.map +1 -1
  173. package/dist/scanners/agent/prompt-injection-fuzzer.js +26 -0
  174. package/dist/scanners/agent/prompt-injection-fuzzer.js.map +1 -1
  175. package/dist/scanners/agent/types.d.ts +10 -10
  176. package/dist/scanners/bandit.d.ts.map +1 -1
  177. package/dist/scanners/bandit.js +35 -29
  178. package/dist/scanners/bandit.js.map +1 -1
  179. package/dist/scanners/binary-analysis.d.ts.map +1 -1
  180. package/dist/scanners/binary-analysis.js +24 -49
  181. package/dist/scanners/binary-analysis.js.map +1 -1
  182. package/dist/scanners/brakeman.d.ts.map +1 -1
  183. package/dist/scanners/brakeman.js +19 -33
  184. package/dist/scanners/brakeman.js.map +1 -1
  185. package/dist/scanners/builtin-rules.d.ts +24 -0
  186. package/dist/scanners/builtin-rules.d.ts.map +1 -0
  187. package/dist/scanners/builtin-rules.js +175 -0
  188. package/dist/scanners/builtin-rules.js.map +1 -0
  189. package/dist/scanners/dast.d.ts.map +1 -1
  190. package/dist/scanners/dast.js +24 -34
  191. package/dist/scanners/dast.js.map +1 -1
  192. package/dist/scanners/deploy/types.d.ts +6 -6
  193. package/dist/scanners/eslint.d.ts.map +1 -1
  194. package/dist/scanners/eslint.js +15 -24
  195. package/dist/scanners/eslint.js.map +1 -1
  196. package/dist/scanners/gosec.d.ts.map +1 -1
  197. package/dist/scanners/gosec.js +14 -62
  198. package/dist/scanners/gosec.js.map +1 -1
  199. package/dist/scanners/index.d.ts.map +1 -1
  200. package/dist/scanners/index.js +38 -7
  201. package/dist/scanners/index.js.map +1 -1
  202. package/dist/scanners/memory-safety.d.ts.map +1 -1
  203. package/dist/scanners/memory-safety.js +27 -28
  204. package/dist/scanners/memory-safety.js.map +1 -1
  205. package/dist/scanners/openapi.d.ts.map +1 -1
  206. package/dist/scanners/openapi.js +14 -22
  207. package/dist/scanners/openapi.js.map +1 -1
  208. package/dist/scanners/race-condition.d.ts.map +1 -1
  209. package/dist/scanners/race-condition.js +17 -16
  210. package/dist/scanners/race-condition.js.map +1 -1
  211. package/dist/scanners/runtime/types.d.ts +4 -4
  212. package/dist/scanners/rust.d.ts.map +1 -1
  213. package/dist/scanners/rust.js +38 -37
  214. package/dist/scanners/rust.js.map +1 -1
  215. package/dist/scanners/scale/types.d.ts +16 -16
  216. package/dist/scanners/secrets.d.ts.map +1 -1
  217. package/dist/scanners/secrets.js +66 -78
  218. package/dist/scanners/secrets.js.map +1 -1
  219. package/dist/scanners/semgrep.d.ts +2 -0
  220. package/dist/scanners/semgrep.d.ts.map +1 -1
  221. package/dist/scanners/semgrep.js +12 -0
  222. package/dist/scanners/semgrep.js.map +1 -1
  223. package/dist/scanners/terraform.d.ts.map +1 -1
  224. package/dist/scanners/terraform.js +47 -40
  225. package/dist/scanners/terraform.js.map +1 -1
  226. package/dist/scanners/trivy.d.ts.map +1 -1
  227. package/dist/scanners/trivy.js +38 -30
  228. package/dist/scanners/trivy.js.map +1 -1
  229. package/dist/telemetry/install-id.d.ts +25 -0
  230. package/dist/telemetry/install-id.d.ts.map +1 -0
  231. package/dist/telemetry/install-id.js +49 -0
  232. package/dist/telemetry/install-id.js.map +1 -0
  233. package/dist/telemetry/usage.d.ts +19 -2
  234. package/dist/telemetry/usage.d.ts.map +1 -1
  235. package/dist/telemetry/usage.js +44 -8
  236. package/dist/telemetry/usage.js.map +1 -1
  237. package/dist/tool-guard.d.ts +40 -0
  238. package/dist/tool-guard.d.ts.map +1 -0
  239. package/dist/tool-guard.js +55 -0
  240. package/dist/tool-guard.js.map +1 -0
  241. package/dist/util/index.d.ts +2 -1
  242. package/dist/util/index.d.ts.map +1 -1
  243. package/dist/util/index.js +2 -1
  244. package/dist/util/index.js.map +1 -1
  245. package/dist/util/paths.d.ts +20 -3
  246. package/dist/util/paths.d.ts.map +1 -1
  247. package/dist/util/paths.js +84 -4
  248. package/dist/util/paths.js.map +1 -1
  249. package/dist/util/subprocess.d.ts +51 -0
  250. package/dist/util/subprocess.d.ts.map +1 -0
  251. package/dist/util/subprocess.js +77 -0
  252. package/dist/util/subprocess.js.map +1 -0
  253. package/package.json +12 -2
  254. package/dist/eval/fixtures/healthcare/audit-gaps.d.ts +0 -28
  255. package/dist/eval/fixtures/healthcare/audit-gaps.d.ts.map +0 -1
  256. package/dist/eval/fixtures/healthcare/audit-gaps.js +0 -90
  257. package/dist/eval/fixtures/healthcare/audit-gaps.js.map +0 -1
  258. package/dist/eval/fixtures/healthcare/consent-bypass.d.ts +0 -31
  259. package/dist/eval/fixtures/healthcare/consent-bypass.d.ts.map +0 -1
  260. package/dist/eval/fixtures/healthcare/consent-bypass.js +0 -61
  261. package/dist/eval/fixtures/healthcare/consent-bypass.js.map +0 -1
  262. package/dist/eval/fixtures/healthcare/phi-in-logs.d.ts +0 -24
  263. package/dist/eval/fixtures/healthcare/phi-in-logs.d.ts.map +0 -1
  264. package/dist/eval/fixtures/healthcare/phi-in-logs.js +0 -41
  265. package/dist/eval/fixtures/healthcare/phi-in-logs.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,10 +1,60 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#70](https://github.com/RCOLKITT/hardening-mcp/pull/70) [`d79820c`](https://github.com/RCOLKITT/hardening-mcp/commit/d79820cee28743a0dad7457b34ed3aa2a4def33e) Thanks [@RCOLKITT](https://github.com/RCOLKITT)! - Anonymous, opt-out usage telemetry
8
+
9
+ The CLI / MCP server now reports anonymous usage metrics — no source code, no
10
+ secrets, no file contents — so adoption can be measured and the product
11
+ improved. It is **opt-out**: a one-time first-run notice is shown, and it can be
12
+ disabled with `VASPERA_TELEMETRY_DISABLED=1` or the cross-tool standard
13
+ `DO_NOT_TRACK=1`. Events carry only an anonymous install id, a hashed project
14
+ path, version/platform, and aggregate result counts. Full disclosure in
15
+ `TELEMETRY.md`.
16
+
17
+ Also resolves high-severity transitive dependency advisories (undici, vite,
18
+ hono) surfaced by self-certification.
19
+
20
+ ## 2.15.0
21
+
22
+ ### Minor Changes
23
+
24
+ - [#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.
25
+
26
+ **Agent Certification**
27
+
28
+ - Versioned, signable agent certificate schema (six dimensions) with deterministic content digest; `agent_certificate_generate` / `agent_certificate_verify` MCP tools.
29
+ - ISO 42001 + NIST AI RMF compliance mappings and tamper-evident decision provenance (`decision_record`) on the hash chain.
30
+ - EU AI Act control mapping wired into the certification path (31 controls).
31
+
32
+ **Independent verification (don't trust us — verify)**
33
+
34
+ - 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.
35
+
36
+ **Measured accuracy + red-team**
37
+
38
+ - 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%.
39
+ - LLM-layer + Anthropic/OpenAI cross-model consensus benchmark.
40
+ - 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.
41
+
42
+ **Integrity + supply chain**
43
+
44
+ - Evidence bundles can now be Sigstore-signed and their signatures are really verified (was a presence-only stub).
45
+ - Published manifest now exposes real per-tool input schemas (was an empty placeholder for all tools).
46
+ - Resolved a transitive esbuild advisory.
47
+
48
+ **Hardening (potentially breaking for three tools)**
49
+
50
+ - `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`.
51
+
3
52
  ## [2.14.0] - 2026-06-05
4
53
 
5
54
  ### Added
6
55
 
7
56
  #### Antagonist Agent
57
+
8
58
  - New meta-analysis agent that runs after all other agents complete
9
59
  - **Synthesis mode**: Chains findings into attack narratives mapped to MITRE ATT&CK kill chain
10
60
  - **Challenger mode**: Internal critic that flags false positives, coverage gaps, and inconsistencies
@@ -13,22 +63,26 @@
13
63
  - New `antagonist_challenge` tool - manually challenge specific findings
14
64
 
15
65
  #### Attack Narrative Features
66
+
16
67
  - Builds attack graphs from findings and exploit chains
17
68
  - Maps vulnerabilities to 14 MITRE ATT&CK kill chain phases
18
69
  - Identifies bottleneck findings that block multiple attack paths
19
70
  - Generates human-readable attack stories with difficulty/likelihood ratings
20
71
 
21
72
  #### Challenger Features
73
+
22
74
  - Detects potential false positives (test files, low confidence, generic descriptions)
23
75
  - Identifies untested attack vectors (17 categories tracked)
24
76
  - Flags agents with zero findings as potentially incomplete
25
77
  - Calculates coverage score across attack surface
26
78
 
27
79
  ### Fixed
80
+
28
81
  - Empty catch blocks in `store.ts` and `signing.ts` now log errors
29
82
  - Antagonist agent integration test types corrected
30
83
 
31
84
  ### Changed
85
+
32
86
  - MCP tools increased from 108 to 110
33
87
  - New agent type `antagonist` with weight 0.15 (informs but doesn't dominate consensus)
34
88
  - Added to AGENT_VERIFICATION_MAP (verified by security, adversary, redteam)
@@ -38,17 +92,20 @@
38
92
  ### Added
39
93
 
40
94
  #### False Positive Feedback System
95
+
41
96
  - New `feedback_submit` tool to mark findings as true/false positives
42
97
  - New `feedback_report` tool to view FP rates by scanner and rule
43
98
  - New `feedback_suppressions` tool to get rule suppression suggestions based on feedback
44
99
  - Feedback stored in `.vaspera/fp-feedback.json` with full audit trail
45
100
 
46
101
  #### Diff-Aware CI Scanning
102
+
47
103
  - New `certification_scan_diff` tool scans only changed files (git diff)
48
104
  - Estimates scan time savings vs full scan
49
105
  - Auto-detects security-critical files that always get scanned
50
106
 
51
107
  #### Standalone Autofix Preview
108
+
52
109
  - `autofix_preview` now works without certification_id
53
110
  - Provide file + pattern_id to preview fixes directly
54
111
  - Use `autofix_list_patterns` to see available fix patterns
@@ -56,27 +113,32 @@
56
113
  ### Fixed
57
114
 
58
115
  #### Persistence DB Fallback
116
+
59
117
  - Added JSON file fallback when SQLite is unavailable
60
118
  - New `src/persistence/json-fallback.ts` with atomic writes
61
119
  - Graceful degradation: warns but continues operating
62
120
 
63
121
  #### scale_bottlenecks False Positives
122
+
64
123
  - Added semantic analysis for workflow/pipeline patterns
65
124
  - Confidence scoring (60-100) based on context
66
125
  - Sequential workflows no longer flagged as N+1 queries
67
126
 
68
127
  #### ai_code_verify Diagnostics
128
+
69
129
  - Returns detailed diagnostics when 0 files found
70
130
  - Shows which extensions were searched
71
131
  - Reports which exclude patterns matched
72
132
  - Suggests alternative file extensions
73
133
 
74
134
  #### Scanner Error Messages
135
+
75
136
  - Added `ScannerErrorDetails` with actionable suggestions
76
137
  - tsc/eslint now report phase (init/scan/parse) and fix steps
77
138
  - Full error output available for debugging
78
139
 
79
140
  ### Changed
141
+
80
142
  - MCP tools increased from 103 to 108
81
143
 
82
144
  ## 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,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":"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"}
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-certificate-map.test.js","sourceRoot":"","sources":["../../../src/__tests__/certification/agent-certificate-map.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-certificate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-certificate.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/certification/agent-certificate.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { finalizeCertificate, verifyCertificate, canonicalize, computeContentDigest, parseCertificate, CertificateError, AgentCertificateSchema, AGENT_CERTIFICATE_SCHEMA, } from "../../certification/agent-certificate.js";
3
+ import { buildSampleCertificateBody } from "../../certification/agent-certificate-sample.js";
4
+ const sampleOpts = {
5
+ toolVersion: "2.14.0",
6
+ issuedAt: "2026-06-11T00:00:00.000Z",
7
+ expiresAt: "2026-09-09T00:00:00.000Z",
8
+ certificateId: "vac_test_0001",
9
+ };
10
+ function body() {
11
+ return buildSampleCertificateBody(sampleOpts);
12
+ }
13
+ describe("agent certificate", () => {
14
+ it("finalizes a valid body with a content digest", async () => {
15
+ const cert = await finalizeCertificate(body());
16
+ expect(cert.schemaVersion).toBe(AGENT_CERTIFICATE_SCHEMA);
17
+ expect(cert.integrity.algorithm).toBe("sha256");
18
+ expect(cert.integrity.contentDigest).toMatch(/^[a-f0-9]{64}$/);
19
+ // digest is over the body alone (no signature when unsigned)
20
+ expect(cert.signature).toBeUndefined();
21
+ });
22
+ it("produces a deterministic digest regardless of key order", async () => {
23
+ const a = await finalizeCertificate(body());
24
+ // shuffle top-level key order of the body
25
+ const shuffled = Object.fromEntries(Object.entries(body()).reverse());
26
+ const b = await finalizeCertificate(shuffled);
27
+ expect(a.integrity.contentDigest).toBe(b.integrity.contentDigest);
28
+ });
29
+ it("verifies an untampered certificate", async () => {
30
+ const cert = await finalizeCertificate(body());
31
+ const result = await verifyCertificate(cert);
32
+ expect(result.valid).toBe(true);
33
+ expect(result.schemaValid).toBe(true);
34
+ expect(result.contentDigestValid).toBe(true);
35
+ expect(result.signaturePresent).toBe(false);
36
+ });
37
+ it("detects tampering — any field change breaks the digest", async () => {
38
+ const cert = await finalizeCertificate(body());
39
+ const tampered = { ...cert, overallScore: 100 };
40
+ const result = await verifyCertificate(tampered);
41
+ expect(result.contentDigestValid).toBe(false);
42
+ expect(result.valid).toBe(false);
43
+ expect(result.errors.join(" ")).toMatch(/digest mismatch/i);
44
+ });
45
+ it("detects tampering inside a nested dimension", async () => {
46
+ const cert = await finalizeCertificate(body());
47
+ const tampered = JSON.parse(JSON.stringify(cert));
48
+ tampered.dimensions.security.score = 10;
49
+ const result = await verifyCertificate(tampered);
50
+ expect(result.valid).toBe(false);
51
+ });
52
+ it("rejects a structurally invalid certificate", async () => {
53
+ const result = await verifyCertificate({ not: "a certificate" });
54
+ expect(result.valid).toBe(false);
55
+ expect(result.schemaValid).toBe(false);
56
+ });
57
+ it("round-trips through parseCertificate", async () => {
58
+ const cert = await finalizeCertificate(body());
59
+ const json = JSON.parse(JSON.stringify(cert));
60
+ const parsed = parseCertificate(json);
61
+ expect(parsed.certificateId).toBe(cert.certificateId);
62
+ });
63
+ it("throws a typed error for an invalid body", async () => {
64
+ const bad = { ...body(), overallScore: 999 };
65
+ await expect(finalizeCertificate(bad)).rejects.toBeInstanceOf(CertificateError);
66
+ });
67
+ it("the sample body validates against the full schema once finalized", async () => {
68
+ const cert = await finalizeCertificate(body());
69
+ expect(AgentCertificateSchema.safeParse(cert).success).toBe(true);
70
+ });
71
+ it("canonicalize + computeContentDigest agree with finalize", async () => {
72
+ const b = body();
73
+ const cert = await finalizeCertificate(b);
74
+ expect(computeContentDigest(b)).toBe(cert.integrity.contentDigest);
75
+ expect(typeof canonicalize(b)).toBe("string");
76
+ });
77
+ });
78
+ //# sourceMappingURL=agent-certificate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-certificate.test.js","sourceRoot":"","sources":["../../../src/__tests__/certification/agent-certificate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=verify-endpoint.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-endpoint.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/certification/verify-endpoint.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect, beforeAll } from "vitest";
2
+ import { finalizeCertificate, AGENT_CERTIFICATE_SCHEMA, } from "../../certification/agent-certificate.js";
3
+ import { verifyCertificatePayload } from "../../certification/verify-endpoint.js";
4
+ const NOW = new Date("2026-06-15T00:00:00.000Z");
5
+ function bodyFixture(over = {}) {
6
+ const dim = {
7
+ status: "pass",
8
+ score: 95,
9
+ summary: "ok",
10
+ checks: [],
11
+ };
12
+ return {
13
+ schemaVersion: AGENT_CERTIFICATE_SCHEMA,
14
+ certificateId: "vac_test_0001",
15
+ subject: { kind: "mcp-server", name: "test-subject", version: "1.0.0" },
16
+ issuer: { name: "Vaspera", tool: "vaspera-hardening", toolVersion: "2.14.0" },
17
+ issuedAt: "2026-06-10T00:00:00.000Z",
18
+ expiresAt: "2026-09-10T00:00:00.000Z",
19
+ level: "CERTIFIED",
20
+ overallScore: 95,
21
+ dimensions: {
22
+ security: dim,
23
+ scalability: dim,
24
+ quality: dim,
25
+ explainability: dim,
26
+ compliance: { status: "pass", score: 95, summary: "ok", frameworks: [] },
27
+ aiBom: { status: "pass", score: 95, summary: "ok", components: [] },
28
+ },
29
+ provenance: {},
30
+ evidence: [],
31
+ ...over,
32
+ };
33
+ }
34
+ describe("verifyCertificatePayload", () => {
35
+ let validCert;
36
+ beforeAll(async () => {
37
+ validCert = await finalizeCertificate(bodyFixture());
38
+ });
39
+ it("verifies a well-formed, untampered certificate", async () => {
40
+ const r = await verifyCertificatePayload(validCert, NOW);
41
+ expect(r.valid).toBe(true);
42
+ expect(r.schemaValid).toBe(true);
43
+ expect(r.contentDigestValid).toBe(true);
44
+ expect(r.summary).toMatch(/^VALID/);
45
+ });
46
+ it("surfaces the certificate's claims when structurally valid", async () => {
47
+ const r = await verifyCertificatePayload(validCert, NOW);
48
+ expect(r.claims).toBeDefined();
49
+ expect(r.claims.subject.name).toBe("test-subject");
50
+ expect(r.claims.level).toBe("CERTIFIED");
51
+ expect(r.claims.overallScore).toBe(95);
52
+ });
53
+ it("rejects a tampered certificate (digest mismatch)", async () => {
54
+ const tampered = JSON.parse(JSON.stringify(validCert));
55
+ tampered.overallScore = 100; // mutate body without recomputing the digest
56
+ const r = await verifyCertificatePayload(tampered, NOW);
57
+ expect(r.valid).toBe(false);
58
+ expect(r.contentDigestValid).toBe(false);
59
+ expect(r.summary).toMatch(/tampered/i);
60
+ });
61
+ it("rejects a non-certificate document", async () => {
62
+ const r = await verifyCertificatePayload({ hello: "world" }, NOW);
63
+ expect(r.valid).toBe(false);
64
+ expect(r.schemaValid).toBe(false);
65
+ expect(r.summary).toMatch(/not a well-formed/i);
66
+ });
67
+ it("flags an expired certificate as VALID but EXPIRED", async () => {
68
+ const expired = await finalizeCertificate(bodyFixture({ expiresAt: "2026-01-01T00:00:00.000Z" }));
69
+ const r = await verifyCertificatePayload(expired, NOW);
70
+ expect(r.valid).toBe(true); // integrity is independent of expiry
71
+ expect(r.expired).toBe(true);
72
+ expect(r.warnings.some((w) => /expired/i.test(w))).toBe(true);
73
+ expect(r.summary).toMatch(/EXPIRED/);
74
+ });
75
+ it("warns that a digest-only certificate is unsigned", async () => {
76
+ const r = await verifyCertificatePayload(validCert, NOW);
77
+ expect(r.signaturePresent).toBe(false);
78
+ expect(r.warnings.some((w) => /unsigned/i.test(w))).toBe(true);
79
+ });
80
+ });
81
+ //# sourceMappingURL=verify-endpoint.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-endpoint.test.js","sourceRoot":"","sources":["../../../src/__tests__/certification/verify-endpoint.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ai-frameworks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-frameworks.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/compliance/ai-frameworks.test.ts"],"names":[],"mappings":""}