@complior/engine 0.9.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 (594) hide show
  1. package/.well-known/ai-compliance.json +16 -0
  2. package/COMPLIANCE.md +64 -0
  3. package/data/data-integrity.test.ts +75 -0
  4. package/data/eval/eval-mappings.json +33 -0
  5. package/data/llm/model-pricing.json +15 -0
  6. package/data/llm/model-routing.json +36 -0
  7. package/data/onboarding/risk-profile.json +17 -0
  8. package/data/regulations/eu-ai-act/README.md +245 -0
  9. package/data/regulations/eu-ai-act/applicability-tree.json +160 -0
  10. package/data/regulations/eu-ai-act/cross-mapping.json +175 -0
  11. package/data/regulations/eu-ai-act/localization.json +186 -0
  12. package/data/regulations/eu-ai-act/obligations.json +3981 -0
  13. package/data/regulations/eu-ai-act/regulation-meta.json +482 -0
  14. package/data/regulations/eu-ai-act/scoring.json +342 -0
  15. package/data/regulations/eu-ai-act/technical-requirements.json +2590 -0
  16. package/data/regulations/eu-ai-act/timeline.json +160 -0
  17. package/data/regulations/jurisdictions/at.json +15 -0
  18. package/data/regulations/jurisdictions/be.json +15 -0
  19. package/data/regulations/jurisdictions/bg.json +15 -0
  20. package/data/regulations/jurisdictions/cy.json +15 -0
  21. package/data/regulations/jurisdictions/cz.json +15 -0
  22. package/data/regulations/jurisdictions/de.json +15 -0
  23. package/data/regulations/jurisdictions/dk.json +15 -0
  24. package/data/regulations/jurisdictions/ee.json +15 -0
  25. package/data/regulations/jurisdictions/es.json +15 -0
  26. package/data/regulations/jurisdictions/fi.json +15 -0
  27. package/data/regulations/jurisdictions/fr.json +15 -0
  28. package/data/regulations/jurisdictions/gr.json +15 -0
  29. package/data/regulations/jurisdictions/hr.json +15 -0
  30. package/data/regulations/jurisdictions/hu.json +15 -0
  31. package/data/regulations/jurisdictions/ie.json +15 -0
  32. package/data/regulations/jurisdictions/is.json +15 -0
  33. package/data/regulations/jurisdictions/it.json +15 -0
  34. package/data/regulations/jurisdictions/li.json +15 -0
  35. package/data/regulations/jurisdictions/lt.json +15 -0
  36. package/data/regulations/jurisdictions/lu.json +15 -0
  37. package/data/regulations/jurisdictions/lv.json +15 -0
  38. package/data/regulations/jurisdictions/mt.json +15 -0
  39. package/data/regulations/jurisdictions/nl.json +15 -0
  40. package/data/regulations/jurisdictions/no.json +15 -0
  41. package/data/regulations/jurisdictions/pl.json +15 -0
  42. package/data/regulations/jurisdictions/pt.json +15 -0
  43. package/data/regulations/jurisdictions/ro.json +15 -0
  44. package/data/regulations/jurisdictions/se.json +15 -0
  45. package/data/regulations/jurisdictions/si.json +15 -0
  46. package/data/regulations/jurisdictions/sk.json +15 -0
  47. package/data/scanner/check-id-categories.json +81 -0
  48. package/data/scanner/confidence-params.json +16 -0
  49. package/data/scanner/limits.json +4 -0
  50. package/data/schemas/http-contract-sample.json +79 -0
  51. package/data/schemas/http-contract.json +144 -0
  52. package/data/semgrep-rules/bare-call.yaml +37 -0
  53. package/data/semgrep-rules/injection.yaml +73 -0
  54. package/data/semgrep-rules/missing-error-handling.yaml +58 -0
  55. package/data/semgrep-rules/unsafe-deser.yaml +65 -0
  56. package/data/templates/eu-ai-act/ai-literacy.md +184 -0
  57. package/data/templates/eu-ai-act/art5-screening.md +131 -0
  58. package/data/templates/eu-ai-act/data-governance.md +145 -0
  59. package/data/templates/eu-ai-act/declaration-of-conformity.md +161 -0
  60. package/data/templates/eu-ai-act/fria.md +127 -0
  61. package/data/templates/eu-ai-act/gpai-systemic-risk.md +150 -0
  62. package/data/templates/eu-ai-act/gpai-transparency.md +166 -0
  63. package/data/templates/eu-ai-act/incident-report.md +188 -0
  64. package/data/templates/eu-ai-act/instructions-for-use.md +202 -0
  65. package/data/templates/eu-ai-act/monitoring-policy.md +110 -0
  66. package/data/templates/eu-ai-act/qms.md +180 -0
  67. package/data/templates/eu-ai-act/risk-management-system.md +123 -0
  68. package/data/templates/eu-ai-act/technical-documentation.md +287 -0
  69. package/data/templates/eu-ai-act/worker-notification.md +143 -0
  70. package/data/templates/policies/biometrics-ai-policy.md +214 -0
  71. package/data/templates/policies/critical-infra-ai-policy.md +228 -0
  72. package/data/templates/policies/education-ai-policy.md +184 -0
  73. package/data/templates/policies/finance-ai-policy.md +191 -0
  74. package/data/templates/policies/healthcare-ai-policy.md +197 -0
  75. package/data/templates/policies/hr-ai-policy.md +178 -0
  76. package/data/templates/policies/legal-ai-policy.md +189 -0
  77. package/data/templates/policies/migration-ai-policy.md +239 -0
  78. package/engine.log +7 -0
  79. package/package.json +74 -0
  80. package/src/composition-root.ts +791 -0
  81. package/src/data/eval/conformity-tests.test.ts +122 -0
  82. package/src/data/eval/ct-1-transparency.ts +106 -0
  83. package/src/data/eval/ct-10-gpai.ts +25 -0
  84. package/src/data/eval/ct-11-industry.ts +42 -0
  85. package/src/data/eval/ct-2-oversight.ts +41 -0
  86. package/src/data/eval/ct-3-explanation.ts +14 -0
  87. package/src/data/eval/ct-4-bias.ts +83 -0
  88. package/src/data/eval/ct-5-accuracy.ts +41 -0
  89. package/src/data/eval/ct-6-robustness.ts +81 -0
  90. package/src/data/eval/ct-7-prohibited.ts +52 -0
  91. package/src/data/eval/ct-8-logging.ts +68 -0
  92. package/src/data/eval/ct-9-risk-awareness.ts +33 -0
  93. package/src/data/eval/deterministic-evaluator.ts +120 -0
  94. package/src/data/eval/index.ts +55 -0
  95. package/src/data/eval/judge-prompts.ts +146 -0
  96. package/src/data/eval/llm-judged-tests.ts +279 -0
  97. package/src/data/eval/llm-tests.test.ts +83 -0
  98. package/src/data/eval/remediation/ct-1-transparency.ts +91 -0
  99. package/src/data/eval/remediation/ct-10-gpai.ts +94 -0
  100. package/src/data/eval/remediation/ct-11-industry.ts +94 -0
  101. package/src/data/eval/remediation/ct-2-oversight.ts +71 -0
  102. package/src/data/eval/remediation/ct-3-explanation.ts +70 -0
  103. package/src/data/eval/remediation/ct-4-bias.ts +70 -0
  104. package/src/data/eval/remediation/ct-5-accuracy.ts +70 -0
  105. package/src/data/eval/remediation/ct-6-robustness.ts +70 -0
  106. package/src/data/eval/remediation/ct-7-prohibited.ts +94 -0
  107. package/src/data/eval/remediation/ct-8-logging.ts +94 -0
  108. package/src/data/eval/remediation/ct-9-risk-awareness.ts +94 -0
  109. package/src/data/eval/remediation/index.ts +89 -0
  110. package/src/data/eval/remediation/owasp-art5.ts +15 -0
  111. package/src/data/eval/remediation/owasp-llm01.ts +72 -0
  112. package/src/data/eval/remediation/owasp-llm02.ts +72 -0
  113. package/src/data/eval/remediation/owasp-llm03.ts +15 -0
  114. package/src/data/eval/remediation/owasp-llm04.ts +15 -0
  115. package/src/data/eval/remediation/owasp-llm05.ts +15 -0
  116. package/src/data/eval/remediation/owasp-llm06.ts +15 -0
  117. package/src/data/eval/remediation/owasp-llm07.ts +15 -0
  118. package/src/data/eval/remediation/owasp-llm08.ts +15 -0
  119. package/src/data/eval/remediation/owasp-llm09.ts +15 -0
  120. package/src/data/eval/remediation/owasp-llm10.ts +15 -0
  121. package/src/data/eval/remediation/remediation.test.ts +229 -0
  122. package/src/data/eval/remediation/test-mapping.ts +290 -0
  123. package/src/data/eval/security-rubrics.ts +381 -0
  124. package/src/data/finding-explanations.json +453 -0
  125. package/src/data/industry-patterns.ts +161 -0
  126. package/src/data/registry-cards.ts +368 -0
  127. package/src/data/regulation/index.ts +5 -0
  128. package/src/data/regulation/jurisdiction-data.test.ts +73 -0
  129. package/src/data/regulation/jurisdiction-data.ts +65 -0
  130. package/src/data/regulation/regulation-data.ts +19 -0
  131. package/src/data/regulation/regulation-loader.test.ts +107 -0
  132. package/src/data/regulation/regulation-loader.ts +56 -0
  133. package/src/data/scanner-constants.ts +46 -0
  134. package/src/data/schemas/schemas-core.ts +140 -0
  135. package/src/data/schemas/schemas-supplementary.ts +211 -0
  136. package/src/data/schemas/schemas.ts +28 -0
  137. package/src/data/security/attack-probes.test.ts +62 -0
  138. package/src/data/security/attack-probes.ts +496 -0
  139. package/src/data/security/eu-ai-act-security.ts +40 -0
  140. package/src/data/security/index.ts +19 -0
  141. package/src/data/security/mitre-atlas.test.ts +43 -0
  142. package/src/data/security/mitre-atlas.ts +93 -0
  143. package/src/data/security/nist-ai-rmf.ts +43 -0
  144. package/src/data/security/owasp-llm-top10.test.ts +60 -0
  145. package/src/data/security/owasp-llm-top10.ts +138 -0
  146. package/src/data/template-registry.ts +53 -0
  147. package/src/data/tool-versions.json +22 -0
  148. package/src/domain/audit/audit-package.test.ts +152 -0
  149. package/src/domain/audit/audit-package.ts +166 -0
  150. package/src/domain/audit/audit-trail.test.ts +121 -0
  151. package/src/domain/audit/audit-trail.ts +174 -0
  152. package/src/domain/audit/index.ts +8 -0
  153. package/src/domain/audit/permissions-matrix.test.ts +136 -0
  154. package/src/domain/audit/permissions-matrix.ts +121 -0
  155. package/src/domain/certification/adversarial/bias-tests.ts +95 -0
  156. package/src/domain/certification/adversarial/evaluators.ts +304 -0
  157. package/src/domain/certification/adversarial/index.ts +11 -0
  158. package/src/domain/certification/adversarial/prompt-injection.ts +103 -0
  159. package/src/domain/certification/adversarial/safety-boundary.ts +132 -0
  160. package/src/domain/certification/aiuc1-readiness.test.ts +236 -0
  161. package/src/domain/certification/aiuc1-readiness.ts +298 -0
  162. package/src/domain/certification/aiuc1-requirements.ts +235 -0
  163. package/src/domain/certification/index.ts +10 -0
  164. package/src/domain/certification/redteam-runner.test.ts +97 -0
  165. package/src/domain/certification/redteam-runner.ts +205 -0
  166. package/src/domain/certification/test-runner.test.ts +232 -0
  167. package/src/domain/certification/test-runner.ts +289 -0
  168. package/src/domain/cost/cost-estimator.test.ts +187 -0
  169. package/src/domain/cost/cost-estimator.ts +133 -0
  170. package/src/domain/disclaimer.test.ts +52 -0
  171. package/src/domain/disclaimer.ts +39 -0
  172. package/src/domain/documents/ai-enricher.test.ts +120 -0
  173. package/src/domain/documents/ai-enricher.ts +159 -0
  174. package/src/domain/documents/document-generator.test.ts +318 -0
  175. package/src/domain/documents/document-generator.ts +239 -0
  176. package/src/domain/documents/index.ts +9 -0
  177. package/src/domain/documents/passport-helpers.ts +25 -0
  178. package/src/domain/documents/policy-generator.test.ts +252 -0
  179. package/src/domain/documents/policy-generator.ts +94 -0
  180. package/src/domain/documents/worker-notification-generator.test.ts +162 -0
  181. package/src/domain/documents/worker-notification-generator.ts +141 -0
  182. package/src/domain/eval/adapters/adapter-port.ts +94 -0
  183. package/src/domain/eval/adapters/adapters.test.ts +303 -0
  184. package/src/domain/eval/adapters/anthropic-adapter.ts +57 -0
  185. package/src/domain/eval/adapters/auto-detect.ts +104 -0
  186. package/src/domain/eval/adapters/create-chat-adapter.ts +106 -0
  187. package/src/domain/eval/adapters/custom-adapter.ts +74 -0
  188. package/src/domain/eval/adapters/http-adapter.ts +66 -0
  189. package/src/domain/eval/adapters/index.ts +7 -0
  190. package/src/domain/eval/adapters/ollama-adapter.ts +48 -0
  191. package/src/domain/eval/adapters/openai-adapter.ts +58 -0
  192. package/src/domain/eval/adapters/with-timeout.ts +25 -0
  193. package/src/domain/eval/conformity-score.test.ts +161 -0
  194. package/src/domain/eval/conformity-score.ts +135 -0
  195. package/src/domain/eval/eval-constants.ts +55 -0
  196. package/src/domain/eval/eval-evidence.test.ts +85 -0
  197. package/src/domain/eval/eval-evidence.ts +103 -0
  198. package/src/domain/eval/eval-fix-generator.test.ts +421 -0
  199. package/src/domain/eval/eval-fix-generator.ts +205 -0
  200. package/src/domain/eval/eval-passport.test.ts +82 -0
  201. package/src/domain/eval/eval-passport.ts +89 -0
  202. package/src/domain/eval/eval-remediation-report.test.ts +682 -0
  203. package/src/domain/eval/eval-remediation-report.ts +170 -0
  204. package/src/domain/eval/eval-report.ts +108 -0
  205. package/src/domain/eval/eval-runner.test.ts +609 -0
  206. package/src/domain/eval/eval-runner.ts +593 -0
  207. package/src/domain/eval/eval-to-findings.test.ts +293 -0
  208. package/src/domain/eval/eval-to-findings.ts +83 -0
  209. package/src/domain/eval/index.ts +31 -0
  210. package/src/domain/eval/llm-judge.test.ts +139 -0
  211. package/src/domain/eval/llm-judge.ts +168 -0
  212. package/src/domain/eval/remediation-types.ts +90 -0
  213. package/src/domain/eval/security-integration.test.ts +196 -0
  214. package/src/domain/eval/security-integration.ts +136 -0
  215. package/src/domain/eval/types.test.ts +173 -0
  216. package/src/domain/eval/types.ts +244 -0
  217. package/src/domain/eval/verdict-utils.ts +45 -0
  218. package/src/domain/fixer/create-fixer.ts +101 -0
  219. package/src/domain/fixer/diff.ts +70 -0
  220. package/src/domain/fixer/fix-history.ts +23 -0
  221. package/src/domain/fixer/fixer.test.ts +306 -0
  222. package/src/domain/fixer/index.ts +9 -0
  223. package/src/domain/fixer/strategies/bandit-fix.ts +61 -0
  224. package/src/domain/fixer/strategies/bias-testing.ts +49 -0
  225. package/src/domain/fixer/strategies/ci-compliance.ts +57 -0
  226. package/src/domain/fixer/strategies/content-marking.ts +45 -0
  227. package/src/domain/fixer/strategies/cve-upgrade.ts +66 -0
  228. package/src/domain/fixer/strategies/data-governance.ts +65 -0
  229. package/src/domain/fixer/strategies/disclosure.ts +69 -0
  230. package/src/domain/fixer/strategies/doc-code-sync.ts +53 -0
  231. package/src/domain/fixer/strategies/documentation.ts +59 -0
  232. package/src/domain/fixer/strategies/error-handler.ts +63 -0
  233. package/src/domain/fixer/strategies/hitl-gate.ts +67 -0
  234. package/src/domain/fixer/strategies/index.ts +61 -0
  235. package/src/domain/fixer/strategies/kill-switch-test.ts +85 -0
  236. package/src/domain/fixer/strategies/kill-switch.ts +53 -0
  237. package/src/domain/fixer/strategies/license-fix.ts +57 -0
  238. package/src/domain/fixer/strategies/log-retention.ts +40 -0
  239. package/src/domain/fixer/strategies/logging.ts +59 -0
  240. package/src/domain/fixer/strategies/metadata.ts +45 -0
  241. package/src/domain/fixer/strategies/permission-guard.ts +84 -0
  242. package/src/domain/fixer/strategies/record-keeping.ts +69 -0
  243. package/src/domain/fixer/strategies/secret-rotation.ts +52 -0
  244. package/src/domain/fixer/strategies.test.ts +341 -0
  245. package/src/domain/fixer/template-engine.test.ts +64 -0
  246. package/src/domain/fixer/template-engine.ts +38 -0
  247. package/src/domain/fixer/types.ts +88 -0
  248. package/src/domain/frameworks/aiuc1-framework.test.ts +159 -0
  249. package/src/domain/frameworks/aiuc1-framework.ts +126 -0
  250. package/src/domain/frameworks/collect-foundation-metrics.test.ts +96 -0
  251. package/src/domain/frameworks/collect-foundation-metrics.ts +34 -0
  252. package/src/domain/frameworks/eu-ai-act-framework.test.ts +117 -0
  253. package/src/domain/frameworks/eu-ai-act-framework.ts +100 -0
  254. package/src/domain/frameworks/framework-registry.test.ts +91 -0
  255. package/src/domain/frameworks/framework-registry.ts +38 -0
  256. package/src/domain/frameworks/index.ts +8 -0
  257. package/src/domain/frameworks/mitre-atlas-framework.test.ts +53 -0
  258. package/src/domain/frameworks/mitre-atlas-framework.ts +53 -0
  259. package/src/domain/frameworks/owasp-llm-framework.test.ts +77 -0
  260. package/src/domain/frameworks/owasp-llm-framework.ts +54 -0
  261. package/src/domain/frameworks/score-plugin-framework.ts +117 -0
  262. package/src/domain/fria/fria-generator.test.ts +273 -0
  263. package/src/domain/fria/fria-generator.ts +366 -0
  264. package/src/domain/import/promptfoo-importer.test.ts +103 -0
  265. package/src/domain/import/promptfoo-importer.ts +151 -0
  266. package/src/domain/onboarding/guided-onboarding.test.ts +144 -0
  267. package/src/domain/onboarding/guided-onboarding.ts +135 -0
  268. package/src/domain/passport/builder/domain-mapper.ts +9 -0
  269. package/src/domain/passport/builder/manifest-builder.test.ts +546 -0
  270. package/src/domain/passport/builder/manifest-builder.ts +535 -0
  271. package/src/domain/passport/builder/manifest-diff.test.ts +105 -0
  272. package/src/domain/passport/builder/manifest-diff.ts +89 -0
  273. package/src/domain/passport/builder/manifest-files.ts +17 -0
  274. package/src/domain/passport/crypto-signer.test.ts +93 -0
  275. package/src/domain/passport/crypto-signer.ts +157 -0
  276. package/src/domain/passport/discovery/agent-discovery.test.ts +296 -0
  277. package/src/domain/passport/discovery/agent-discovery.ts +325 -0
  278. package/src/domain/passport/discovery/autonomy-analyzer.test.ts +141 -0
  279. package/src/domain/passport/discovery/autonomy-analyzer.ts +113 -0
  280. package/src/domain/passport/discovery/permission-scanner.test.ts +191 -0
  281. package/src/domain/passport/discovery/permission-scanner.ts +414 -0
  282. package/src/domain/passport/export/a2a-mapper.ts +75 -0
  283. package/src/domain/passport/export/aiuc1-mapper.ts +126 -0
  284. package/src/domain/passport/export/export.test.ts +207 -0
  285. package/src/domain/passport/export/index.ts +41 -0
  286. package/src/domain/passport/export/nist-mapper.ts +227 -0
  287. package/src/domain/passport/import/a2a-importer.test.ts +133 -0
  288. package/src/domain/passport/import/a2a-importer.ts +156 -0
  289. package/src/domain/passport/import/index.ts +2 -0
  290. package/src/domain/passport/index.ts +32 -0
  291. package/src/domain/passport/obligation-field-map.test.ts +113 -0
  292. package/src/domain/passport/obligation-field-map.ts +117 -0
  293. package/src/domain/passport/passport-validator.test.ts +156 -0
  294. package/src/domain/passport/passport-validator.ts +126 -0
  295. package/src/domain/passport/scan-to-compliance.test.ts +336 -0
  296. package/src/domain/passport/scan-to-compliance.ts +166 -0
  297. package/src/domain/passport/test-generator.test.ts +93 -0
  298. package/src/domain/passport/test-generator.ts +136 -0
  299. package/src/domain/proxy/index.ts +11 -0
  300. package/src/domain/proxy/json-rpc.test.ts +72 -0
  301. package/src/domain/proxy/json-rpc.ts +53 -0
  302. package/src/domain/proxy/policy-engine.test.ts +259 -0
  303. package/src/domain/proxy/policy-engine.ts +137 -0
  304. package/src/domain/proxy/proxy-bridge.ts +125 -0
  305. package/src/domain/proxy/proxy-interceptor.test.ts +184 -0
  306. package/src/domain/proxy/proxy-interceptor.ts +120 -0
  307. package/src/domain/proxy/proxy-types.ts +35 -0
  308. package/src/domain/registry/compute-agent-score.test.ts +279 -0
  309. package/src/domain/registry/compute-agent-score.ts +162 -0
  310. package/src/domain/reporter/audit-report.test.ts +87 -0
  311. package/src/domain/reporter/audit-report.ts +116 -0
  312. package/src/domain/reporter/badge-generator.test.ts +54 -0
  313. package/src/domain/reporter/badge-generator.ts +40 -0
  314. package/src/domain/reporter/compliance-md.ts +45 -0
  315. package/src/domain/reporter/index.ts +7 -0
  316. package/src/domain/reporter/pdf-renderer.ts +282 -0
  317. package/src/domain/reporter/share.test.ts +92 -0
  318. package/src/domain/reporter/share.ts +80 -0
  319. package/src/domain/scanner/ast/swc-analyzer.test.ts +49 -0
  320. package/src/domain/scanner/ast/swc-analyzer.ts +124 -0
  321. package/src/domain/scanner/attestations.ts +97 -0
  322. package/src/domain/scanner/checks/ai-disclosure.test.ts +90 -0
  323. package/src/domain/scanner/checks/ai-disclosure.ts +54 -0
  324. package/src/domain/scanner/checks/ai-literacy.ts +163 -0
  325. package/src/domain/scanner/checks/behavioral-constraints.test.ts +167 -0
  326. package/src/domain/scanner/checks/behavioral-constraints.ts +86 -0
  327. package/src/domain/scanner/checks/compliance-metadata.ts +63 -0
  328. package/src/domain/scanner/checks/content-marking.ts +74 -0
  329. package/src/domain/scanner/checks/dep-deep-scan.test.ts +318 -0
  330. package/src/domain/scanner/checks/dep-deep-scan.ts +137 -0
  331. package/src/domain/scanner/checks/documentation.test.ts +88 -0
  332. package/src/domain/scanner/checks/documentation.ts +79 -0
  333. package/src/domain/scanner/checks/git-history.test.ts +120 -0
  334. package/src/domain/scanner/checks/git-history.ts +163 -0
  335. package/src/domain/scanner/checks/gpai-systemic-risk.test.ts +84 -0
  336. package/src/domain/scanner/checks/gpai-systemic-risk.ts +98 -0
  337. package/src/domain/scanner/checks/gpai-transparency.ts +94 -0
  338. package/src/domain/scanner/checks/index.ts +28 -0
  339. package/src/domain/scanner/checks/industry/index.ts +40 -0
  340. package/src/domain/scanner/checks/industry/industry.test.ts +287 -0
  341. package/src/domain/scanner/checks/interaction-logging.test.ts +113 -0
  342. package/src/domain/scanner/checks/interaction-logging.ts +142 -0
  343. package/src/domain/scanner/checks/nhi-scanner.test.ts +158 -0
  344. package/src/domain/scanner/checks/nhi-scanner.ts +78 -0
  345. package/src/domain/scanner/checks/passport-completeness.test.ts +127 -0
  346. package/src/domain/scanner/checks/passport-completeness.ts +82 -0
  347. package/src/domain/scanner/checks/passport-presence.test.ts +56 -0
  348. package/src/domain/scanner/checks/passport-presence.ts +78 -0
  349. package/src/domain/scanner/checks/pattern-check-factory.ts +70 -0
  350. package/src/domain/scanner/checks/permission-scanner.test.ts +279 -0
  351. package/src/domain/scanner/checks/permission-scanner.ts +90 -0
  352. package/src/domain/scanner/checks/presence-check-factory.test.ts +124 -0
  353. package/src/domain/scanner/checks/presence-check-factory.ts +275 -0
  354. package/src/domain/scanner/compliance-diff.test.ts +165 -0
  355. package/src/domain/scanner/compliance-diff.ts +138 -0
  356. package/src/domain/scanner/confidence.test.ts +235 -0
  357. package/src/domain/scanner/confidence.ts +156 -0
  358. package/src/domain/scanner/constants.ts +13 -0
  359. package/src/domain/scanner/create-scanner.ts +573 -0
  360. package/src/domain/scanner/cross-layer.test.ts +372 -0
  361. package/src/domain/scanner/cross-layer.ts +232 -0
  362. package/src/domain/scanner/data/ai-packages.ts +82 -0
  363. package/src/domain/scanner/debt-calculator.test.ts +89 -0
  364. package/src/domain/scanner/debt-calculator.ts +111 -0
  365. package/src/domain/scanner/drift.test.ts +191 -0
  366. package/src/domain/scanner/drift.ts +73 -0
  367. package/src/domain/scanner/evidence-store.test.ts +207 -0
  368. package/src/domain/scanner/evidence-store.ts +195 -0
  369. package/src/domain/scanner/evidence.test.ts +104 -0
  370. package/src/domain/scanner/evidence.ts +71 -0
  371. package/src/domain/scanner/external/bandit-runner.test.ts +45 -0
  372. package/src/domain/scanner/external/bandit-runner.ts +90 -0
  373. package/src/domain/scanner/external/checks.ts +321 -0
  374. package/src/domain/scanner/external/dedup.test.ts +79 -0
  375. package/src/domain/scanner/external/dedup.ts +94 -0
  376. package/src/domain/scanner/external/detect-secrets-runner.test.ts +58 -0
  377. package/src/domain/scanner/external/detect-secrets-runner.ts +81 -0
  378. package/src/domain/scanner/external/external-scanner.test.ts +221 -0
  379. package/src/domain/scanner/external/external-scanner.ts +36 -0
  380. package/src/domain/scanner/external/finding-mapper.test.ts +95 -0
  381. package/src/domain/scanner/external/finding-mapper.ts +138 -0
  382. package/src/domain/scanner/external/index.ts +15 -0
  383. package/src/domain/scanner/external/mappings.ts +93 -0
  384. package/src/domain/scanner/external/modelscan-runner.test.ts +35 -0
  385. package/src/domain/scanner/external/modelscan-runner.ts +101 -0
  386. package/src/domain/scanner/external/path-utils.ts +8 -0
  387. package/src/domain/scanner/external/runner-port.ts +45 -0
  388. package/src/domain/scanner/external/semgrep-runner.test.ts +52 -0
  389. package/src/domain/scanner/external/semgrep-runner.ts +94 -0
  390. package/src/domain/scanner/external/types.ts +32 -0
  391. package/src/domain/scanner/finding-attribution.test.ts +444 -0
  392. package/src/domain/scanner/finding-attribution.ts +195 -0
  393. package/src/domain/scanner/finding-explainer.test.ts +157 -0
  394. package/src/domain/scanner/finding-explainer.ts +73 -0
  395. package/src/domain/scanner/fix-diff-builder.test.ts +272 -0
  396. package/src/domain/scanner/fix-diff-builder.ts +477 -0
  397. package/src/domain/scanner/import-graph.test.ts +162 -0
  398. package/src/domain/scanner/import-graph.ts +198 -0
  399. package/src/domain/scanner/languages/adapter.test.ts +105 -0
  400. package/src/domain/scanner/languages/adapter.ts +239 -0
  401. package/src/domain/scanner/layers/index.ts +24 -0
  402. package/src/domain/scanner/layers/layer1-files.ts +54 -0
  403. package/src/domain/scanner/layers/layer2-docs.test.ts +1207 -0
  404. package/src/domain/scanner/layers/layer2-docs.ts +297 -0
  405. package/src/domain/scanner/layers/layer2-parsing.ts +217 -0
  406. package/src/domain/scanner/layers/layer3-config.test.ts +187 -0
  407. package/src/domain/scanner/layers/layer3-config.ts +279 -0
  408. package/src/domain/scanner/layers/layer3-parsers.ts +73 -0
  409. package/src/domain/scanner/layers/layer4-patterns.test.ts +397 -0
  410. package/src/domain/scanner/layers/layer4-patterns.ts +216 -0
  411. package/src/domain/scanner/layers/layer5-docs.test.ts +99 -0
  412. package/src/domain/scanner/layers/layer5-docs.ts +250 -0
  413. package/src/domain/scanner/layers/layer5-llm.test.ts +146 -0
  414. package/src/domain/scanner/layers/layer5-llm.ts +262 -0
  415. package/src/domain/scanner/layers/layer5-targeted.test.ts +93 -0
  416. package/src/domain/scanner/layers/layer5-targeted.ts +233 -0
  417. package/src/domain/scanner/layers/lockfile-parsers.test.ts +320 -0
  418. package/src/domain/scanner/layers/lockfile-parsers.ts +184 -0
  419. package/src/domain/scanner/regulation-version.test.ts +54 -0
  420. package/src/domain/scanner/regulation-version.ts +23 -0
  421. package/src/domain/scanner/role-filter.test.ts +116 -0
  422. package/src/domain/scanner/role-filter.ts +51 -0
  423. package/src/domain/scanner/rules/banned-packages-data.ts +553 -0
  424. package/src/domain/scanner/rules/banned-packages-sdk.ts +65 -0
  425. package/src/domain/scanner/rules/banned-packages.test.ts +249 -0
  426. package/src/domain/scanner/rules/banned-packages.ts +55 -0
  427. package/src/domain/scanner/rules/comment-filter.test.ts +115 -0
  428. package/src/domain/scanner/rules/comment-filter.ts +297 -0
  429. package/src/domain/scanner/rules/index.ts +9 -0
  430. package/src/domain/scanner/rules/nhi-patterns.test.ts +128 -0
  431. package/src/domain/scanner/rules/nhi-patterns.ts +60 -0
  432. package/src/domain/scanner/rules/pattern-rules.ts +1152 -0
  433. package/src/domain/scanner/sbom.test.ts +136 -0
  434. package/src/domain/scanner/sbom.ts +103 -0
  435. package/src/domain/scanner/scan-cache.test.ts +136 -0
  436. package/src/domain/scanner/scan-cache.ts +115 -0
  437. package/src/domain/scanner/scanner.test.ts +125 -0
  438. package/src/domain/scanner/score-calculator.test.ts +363 -0
  439. package/src/domain/scanner/score-calculator.ts +189 -0
  440. package/src/domain/scanner/security-score.test.ts +107 -0
  441. package/src/domain/scanner/security-score.ts +116 -0
  442. package/src/domain/scanner/source-filter.ts +24 -0
  443. package/src/domain/scanner/validators.ts +223 -0
  444. package/src/domain/shared/compliance-constants.ts +48 -0
  445. package/src/domain/shared/disclosure-patterns.ts +16 -0
  446. package/src/domain/shared/index.ts +6 -0
  447. package/src/domain/shared/parse-dependencies.ts +21 -0
  448. package/src/domain/supply-chain/dependency-analyzer.ts +138 -0
  449. package/src/domain/supply-chain/index.ts +3 -0
  450. package/src/domain/supply-chain/supply-chain.test.ts +211 -0
  451. package/src/domain/supply-chain/types.ts +32 -0
  452. package/src/domain/whatif/config-fixer.ts +187 -0
  453. package/src/domain/whatif/index.ts +6 -0
  454. package/src/domain/whatif/scenario-engine.ts +121 -0
  455. package/src/domain/whatif/simulate-actions.test.ts +161 -0
  456. package/src/domain/whatif/simulate-actions.ts +114 -0
  457. package/src/domain/whatif/whatif.test.ts +135 -0
  458. package/src/e2e/gaps-e2e.test.ts +259 -0
  459. package/src/e2e/smoke.test.ts +101 -0
  460. package/src/hooks/hooks-export.test.ts +81 -0
  461. package/src/hooks/installer.ts +113 -0
  462. package/src/http/cors.test.ts +38 -0
  463. package/src/http/create-router.ts +259 -0
  464. package/src/http/routes/agent.route.ts +380 -0
  465. package/src/http/routes/audit.route.ts +66 -0
  466. package/src/http/routes/badge.route.ts +23 -0
  467. package/src/http/routes/cert.route.ts +66 -0
  468. package/src/http/routes/chat.route.ts +228 -0
  469. package/src/http/routes/cost.route.ts +33 -0
  470. package/src/http/routes/debt.route.ts +29 -0
  471. package/src/http/routes/disclaimer.route.ts +64 -0
  472. package/src/http/routes/eval.route.ts +161 -0
  473. package/src/http/routes/events.route.test.ts +108 -0
  474. package/src/http/routes/events.route.ts +71 -0
  475. package/src/http/routes/external-scan.route.ts +24 -0
  476. package/src/http/routes/file.route.ts +54 -0
  477. package/src/http/routes/fix.route.ts +219 -0
  478. package/src/http/routes/frameworks.route.test.ts +66 -0
  479. package/src/http/routes/frameworks.route.ts +36 -0
  480. package/src/http/routes/git.route.ts +27 -0
  481. package/src/http/routes/guided-onboarding.route.ts +65 -0
  482. package/src/http/routes/import.route.ts +64 -0
  483. package/src/http/routes/jurisdiction.route.ts +22 -0
  484. package/src/http/routes/obligations.route.test.ts +122 -0
  485. package/src/http/routes/obligations.route.ts +110 -0
  486. package/src/http/routes/onboarding.route.ts +53 -0
  487. package/src/http/routes/provider.route.ts +42 -0
  488. package/src/http/routes/proxy.route.ts +40 -0
  489. package/src/http/routes/redteam.route.ts +84 -0
  490. package/src/http/routes/report.route.ts +29 -0
  491. package/src/http/routes/scan.route.ts +104 -0
  492. package/src/http/routes/share.route.ts +44 -0
  493. package/src/http/routes/shell.route.ts +27 -0
  494. package/src/http/routes/status.route.ts +66 -0
  495. package/src/http/routes/supply-chain.route.ts +121 -0
  496. package/src/http/routes/sync.route.ts +328 -0
  497. package/src/http/routes/tools.route.ts +29 -0
  498. package/src/http/routes/whatif.route.ts +96 -0
  499. package/src/http/utils/validation.ts +31 -0
  500. package/src/index.ts +1 -0
  501. package/src/infra/bundle-fetcher.ts +77 -0
  502. package/src/infra/cache-storage.ts +34 -0
  503. package/src/infra/event-bus.ts +31 -0
  504. package/src/infra/file-collector.ts +61 -0
  505. package/src/infra/file-ops-adapter.ts +95 -0
  506. package/src/infra/file-watcher.test.ts +90 -0
  507. package/src/infra/file-watcher.ts +106 -0
  508. package/src/infra/git-adapter.ts +93 -0
  509. package/src/infra/git-history-adapter.ts +41 -0
  510. package/src/infra/headless-browser.ts +178 -0
  511. package/src/infra/llm-adapter.test.ts +83 -0
  512. package/src/infra/llm-adapter.ts +86 -0
  513. package/src/infra/logger.ts +27 -0
  514. package/src/infra/project-config.test.ts +74 -0
  515. package/src/infra/project-config.ts +35 -0
  516. package/src/infra/rate-limiter.test.ts +36 -0
  517. package/src/infra/rate-limiter.ts +34 -0
  518. package/src/infra/retry.ts +46 -0
  519. package/src/infra/saas-client.ts +123 -0
  520. package/src/infra/search-adapter.ts +113 -0
  521. package/src/infra/shell-adapter.ts +68 -0
  522. package/src/infra/tool-manager.test.ts +99 -0
  523. package/src/infra/tool-manager.ts +197 -0
  524. package/src/llm/agents/agent-modes.test.ts +44 -0
  525. package/src/llm/agents/modes.ts +68 -0
  526. package/src/llm/routing/cost-routing.test.ts +37 -0
  527. package/src/llm/routing/cost-tracker.ts +74 -0
  528. package/src/llm/routing/model-routing.test.ts +79 -0
  529. package/src/llm/routing/model-routing.ts +38 -0
  530. package/src/llm/routing/pricing.ts +19 -0
  531. package/src/llm/sse-protocol.ts +77 -0
  532. package/src/llm/tool-definitions.ts +83 -0
  533. package/src/llm/tool-executors.ts +80 -0
  534. package/src/llm/tools/types.ts +13 -0
  535. package/src/mcp/create-mcp-stack.ts +82 -0
  536. package/src/mcp/handlers.ts +245 -0
  537. package/src/mcp/index.ts +28 -0
  538. package/src/mcp/mcp-server.test.ts +80 -0
  539. package/src/mcp/server.ts +79 -0
  540. package/src/mcp/tools.ts +48 -0
  541. package/src/onboarding/auto-detect.ts +164 -0
  542. package/src/onboarding/onboarding.test.ts +89 -0
  543. package/src/onboarding/profile.ts +169 -0
  544. package/src/onboarding/questions.ts +112 -0
  545. package/src/onboarding/wizard.ts +66 -0
  546. package/src/output/github-issue.ts +32 -0
  547. package/src/output/json-output.ts +67 -0
  548. package/src/ports/browser.port.ts +23 -0
  549. package/src/ports/events.port.ts +28 -0
  550. package/src/ports/llm.port.ts +23 -0
  551. package/src/ports/logger.port.ts +6 -0
  552. package/src/ports/process.port.ts +6 -0
  553. package/src/ports/scanner.port.ts +15 -0
  554. package/src/server.ts +134 -0
  555. package/src/services/badge-service.ts +67 -0
  556. package/src/services/chat-service.test.ts +162 -0
  557. package/src/services/chat-service.ts +152 -0
  558. package/src/services/cost-service.ts +52 -0
  559. package/src/services/debt-service.ts +65 -0
  560. package/src/services/eval-integration.test.ts +132 -0
  561. package/src/services/eval-service.test.ts +373 -0
  562. package/src/services/eval-service.ts +463 -0
  563. package/src/services/external-scan-service.ts +60 -0
  564. package/src/services/file-service.ts +37 -0
  565. package/src/services/fix-service.test.ts +470 -0
  566. package/src/services/fix-service.ts +648 -0
  567. package/src/services/framework-service.test.ts +159 -0
  568. package/src/services/framework-service.ts +67 -0
  569. package/src/services/onboarding-service.ts +165 -0
  570. package/src/services/passport-audit.ts +244 -0
  571. package/src/services/passport-documents.ts +258 -0
  572. package/src/services/passport-service-utils.ts +72 -0
  573. package/src/services/passport-service.test.ts +251 -0
  574. package/src/services/passport-service.ts +339 -0
  575. package/src/services/proxy-service.ts +81 -0
  576. package/src/services/report-service.ts +72 -0
  577. package/src/services/scan-service.test.ts +470 -0
  578. package/src/services/scan-service.ts +335 -0
  579. package/src/services/share-service.ts +108 -0
  580. package/src/services/shared/backup.ts +23 -0
  581. package/src/services/status-service.ts +38 -0
  582. package/src/services/undo-service.test.ts +190 -0
  583. package/src/services/undo-service.ts +144 -0
  584. package/src/test-helpers/factories.ts +116 -0
  585. package/src/types/common.schemas.ts +147 -0
  586. package/src/types/common.types.ts +292 -0
  587. package/src/types/contract.test.ts +217 -0
  588. package/src/types/errors.ts +52 -0
  589. package/src/types/framework.types.ts +87 -0
  590. package/src/types/passport-schemas.ts +241 -0
  591. package/src/types/passport.types.ts +296 -0
  592. package/src/version.ts +1 -0
  593. package/tsconfig.json +20 -0
  594. package/vitest.config.ts +9 -0
@@ -0,0 +1,173 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ EvalCategorySchema,
4
+ EvalTierSchema,
5
+ EvalOptionsSchema,
6
+ AuditOptionsSchema,
7
+ EVAL_CATEGORIES,
8
+ EVAL_TIERS,
9
+ CATEGORY_META,
10
+ TIER_INCLUDES,
11
+ resolveIncludes,
12
+ resolveTierLabel,
13
+ } from './types.js';
14
+
15
+ describe('EvalCategory', () => {
16
+ it('has 11 categories', () => {
17
+ expect(EVAL_CATEGORIES).toHaveLength(11);
18
+ });
19
+
20
+ it('validates known categories', () => {
21
+ for (const cat of EVAL_CATEGORIES) {
22
+ expect(EvalCategorySchema.parse(cat)).toBe(cat);
23
+ }
24
+ });
25
+
26
+ it('rejects unknown category', () => {
27
+ expect(() => EvalCategorySchema.parse('unknown')).toThrow();
28
+ });
29
+ });
30
+
31
+ describe('CATEGORY_META', () => {
32
+ it('has metadata for all 11 categories', () => {
33
+ expect(CATEGORY_META).toHaveLength(11);
34
+ const ids = CATEGORY_META.map((m) => m.id);
35
+ for (const cat of EVAL_CATEGORIES) {
36
+ expect(ids).toContain(cat);
37
+ }
38
+ });
39
+
40
+ it('each entry has CT-N id', () => {
41
+ for (const meta of CATEGORY_META) {
42
+ expect(meta.ctId).toMatch(/^CT-\d+$/);
43
+ }
44
+ });
45
+ });
46
+
47
+ describe('EvalTier', () => {
48
+ it('has 4 tiers', () => {
49
+ expect(EVAL_TIERS).toHaveLength(4);
50
+ });
51
+
52
+ it('validates known tiers', () => {
53
+ for (const tier of EVAL_TIERS) {
54
+ expect(EvalTierSchema.parse(tier)).toBe(tier);
55
+ }
56
+ });
57
+
58
+ it('basic = deterministic only', () => {
59
+ expect(TIER_INCLUDES.basic).toEqual({ deterministic: true, llm: false, security: false });
60
+ });
61
+
62
+ it('full includes everything', () => {
63
+ expect(TIER_INCLUDES.full).toEqual({ deterministic: true, llm: true, security: true });
64
+ });
65
+
66
+ it('security = probes only', () => {
67
+ expect(TIER_INCLUDES.security).toEqual({ deterministic: false, llm: false, security: true });
68
+ });
69
+ });
70
+
71
+ describe('resolveIncludes', () => {
72
+ it('no flags → deterministic only', () => {
73
+ expect(resolveIncludes({})).toEqual({ deterministic: true, llm: false, security: false });
74
+ });
75
+
76
+ it('--llm → llm-judge only', () => {
77
+ expect(resolveIncludes({ llm: true })).toEqual({ deterministic: false, llm: true, security: false });
78
+ });
79
+
80
+ it('--security → security only', () => {
81
+ expect(resolveIncludes({ security: true })).toEqual({ deterministic: false, llm: false, security: true });
82
+ });
83
+
84
+ it('--full → everything', () => {
85
+ expect(resolveIncludes({ full: true })).toEqual({ deterministic: true, llm: true, security: true });
86
+ });
87
+
88
+ it('--det --llm → deterministic + llm', () => {
89
+ expect(resolveIncludes({ det: true, llm: true })).toEqual({ deterministic: true, llm: true, security: false });
90
+ });
91
+
92
+ it('--llm --security → llm + security (no det)', () => {
93
+ expect(resolveIncludes({ llm: true, security: true })).toEqual({ deterministic: false, llm: true, security: true });
94
+ });
95
+
96
+ it('--det --security → deterministic + security', () => {
97
+ expect(resolveIncludes({ det: true, security: true })).toEqual({ deterministic: true, llm: false, security: true });
98
+ });
99
+
100
+ it('--det alone → same as default', () => {
101
+ expect(resolveIncludes({ det: true })).toEqual({ deterministic: true, llm: false, security: false });
102
+ });
103
+ });
104
+
105
+ describe('resolveTierLabel', () => {
106
+ it('maps includes to tier labels', () => {
107
+ expect(resolveTierLabel({ deterministic: true, llm: false, security: false })).toBe('basic');
108
+ expect(resolveTierLabel({ deterministic: false, llm: true, security: false })).toBe('standard');
109
+ expect(resolveTierLabel({ deterministic: true, llm: true, security: false })).toBe('standard');
110
+ expect(resolveTierLabel({ deterministic: true, llm: true, security: true })).toBe('full');
111
+ expect(resolveTierLabel({ deterministic: false, llm: false, security: true })).toBe('security');
112
+ expect(resolveTierLabel({ deterministic: true, llm: false, security: true })).toBe('security');
113
+ });
114
+ });
115
+
116
+ describe('EvalOptionsSchema', () => {
117
+ it('parses valid options', () => {
118
+ const result = EvalOptionsSchema.parse({
119
+ target: 'http://localhost:4000/api/chat',
120
+ });
121
+ expect(result.target).toBe('http://localhost:4000/api/chat');
122
+ });
123
+
124
+ it('parses with flag booleans', () => {
125
+ const result = EvalOptionsSchema.parse({
126
+ target: 'http://localhost:4000',
127
+ llm: true,
128
+ security: true,
129
+ });
130
+ expect(result.llm).toBe(true);
131
+ expect(result.security).toBe(true);
132
+ });
133
+
134
+ it('rejects missing target', () => {
135
+ expect(() => EvalOptionsSchema.parse({})).toThrow();
136
+ });
137
+
138
+ it('rejects invalid URL', () => {
139
+ expect(() => EvalOptionsSchema.parse({ target: 'not-a-url' })).toThrow();
140
+ });
141
+
142
+ it('accepts optional fields', () => {
143
+ const result = EvalOptionsSchema.parse({
144
+ target: 'http://localhost:4000',
145
+ full: true,
146
+ categories: ['bias', 'transparency'],
147
+ agent: 'my-agent',
148
+ model: 'gpt-4o',
149
+ apiKey: 'sk-test',
150
+ threshold: 80,
151
+ json: true,
152
+ ci: true,
153
+ });
154
+ expect(result.full).toBe(true);
155
+ expect(result.categories).toEqual(['bias', 'transparency']);
156
+ expect(result.threshold).toBe(80);
157
+ });
158
+
159
+ it('rejects threshold > 100', () => {
160
+ expect(() => EvalOptionsSchema.parse({ target: 'http://localhost:4000', threshold: 150 })).toThrow();
161
+ });
162
+ });
163
+
164
+ describe('AuditOptionsSchema', () => {
165
+ it('parses valid audit options', () => {
166
+ const result = AuditOptionsSchema.parse({ target: 'http://localhost:4000' });
167
+ expect(result.target).toBe('http://localhost:4000');
168
+ });
169
+
170
+ it('rejects invalid target', () => {
171
+ expect(() => AuditOptionsSchema.parse({ target: '' })).toThrow();
172
+ });
173
+ });
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Core types for the `complior eval` subsystem.
3
+ *
4
+ * Eval sends probes to EXTERNAL AI endpoints (via TargetAdapter) and evaluates
5
+ * responses for EU AI Act compliance. Two probe families:
6
+ * - 380 conformity tests (CT-1..CT-11, 11 categories)
7
+ * - 300 security probes (OWASP LLM Top 10)
8
+ */
9
+
10
+ import { z } from 'zod';
11
+
12
+ // ── Eval Categories (11 conformity areas) ───────────────────────
13
+
14
+ export const EVAL_CATEGORIES = [
15
+ 'transparency',
16
+ 'oversight',
17
+ 'explanation',
18
+ 'bias',
19
+ 'accuracy',
20
+ 'robustness',
21
+ 'prohibited',
22
+ 'logging',
23
+ 'risk-awareness',
24
+ 'gpai',
25
+ 'industry',
26
+ ] as const;
27
+
28
+ export type EvalCategory = (typeof EVAL_CATEGORIES)[number];
29
+
30
+ export const EvalCategorySchema = z.enum(EVAL_CATEGORIES);
31
+
32
+ // ── Category metadata ───────────────────────────────────────────
33
+
34
+ export interface CategoryMeta {
35
+ readonly id: EvalCategory;
36
+ readonly label: string;
37
+ readonly ctId: string; // CT-1..CT-11
38
+ readonly euAiActArticles: readonly string[];
39
+ readonly description: string;
40
+ }
41
+
42
+ export const CATEGORY_META: readonly CategoryMeta[] = Object.freeze([
43
+ { id: 'transparency', label: 'Transparency', ctId: 'CT-1', euAiActArticles: ['Art.13', 'Art.52'], description: 'AI system identifies itself and discloses AI nature' },
44
+ { id: 'oversight', label: 'Human Oversight', ctId: 'CT-2', euAiActArticles: ['Art.14'], description: 'Meaningful human control and escalation paths' },
45
+ { id: 'explanation', label: 'Explanation Quality', ctId: 'CT-3', euAiActArticles: ['Art.13(1)', 'Art.86'], description: 'Clear reasoning and decision explanation' },
46
+ { id: 'bias', label: 'Bias & Fairness', ctId: 'CT-4', euAiActArticles: ['Art.10', 'Art.15'], description: 'Equal treatment regardless of protected characteristics' },
47
+ { id: 'accuracy', label: 'Accuracy', ctId: 'CT-5', euAiActArticles: ['Art.15', 'Art.9'], description: 'Factual correctness and hallucination resistance' },
48
+ { id: 'robustness', label: 'Robustness', ctId: 'CT-6', euAiActArticles: ['Art.15', 'Art.9'], description: 'Graceful handling of adversarial and edge-case input' },
49
+ { id: 'prohibited', label: 'Prohibited Practices', ctId: 'CT-7', euAiActArticles: ['Art.5'], description: 'Refusal of social scoring, manipulation, exploitation' },
50
+ { id: 'logging', label: 'Logging & Audit', ctId: 'CT-8', euAiActArticles: ['Art.12', 'Art.19'], description: 'Structured, timestamped, PII-safe audit logs' },
51
+ { id: 'risk-awareness', label: 'Risk Awareness', ctId: 'CT-9', euAiActArticles: ['Art.9'], description: 'Self-awareness of limitations, scope, and failure modes' },
52
+ { id: 'gpai', label: 'GPAI Transparency', ctId: 'CT-10', euAiActArticles: ['Art.52', 'Art.53'], description: 'General-purpose AI model and provider identification' },
53
+ { id: 'industry', label: 'Industry-Specific', ctId: 'CT-11', euAiActArticles: ['Art.6', 'Annex III'], description: 'Domain-specific compliance (HR, education, finance, healthcare)' },
54
+ ]);
55
+
56
+ // ── Eval Tier ───────────────────────────────────────────────────
57
+
58
+ export const EVAL_TIERS = ['basic', 'standard', 'full', 'security'] as const;
59
+ export type EvalTier = (typeof EVAL_TIERS)[number];
60
+
61
+ export const EvalTierSchema = z.enum(EVAL_TIERS);
62
+
63
+ /** What each tier includes. */
64
+ export const TIER_INCLUDES: Record<EvalTier, { deterministic: boolean; llm: boolean; security: boolean }> = {
65
+ basic: { deterministic: true, llm: false, security: false },
66
+ standard: { deterministic: false, llm: true, security: false },
67
+ full: { deterministic: true, llm: true, security: true },
68
+ security: { deterministic: false, llm: false, security: true },
69
+ };
70
+
71
+ // ── Flag-based resolution (replaces tier) ────────────────────
72
+
73
+ export interface EvalIncludes {
74
+ readonly deterministic: boolean;
75
+ readonly llm: boolean;
76
+ readonly security: boolean;
77
+ }
78
+
79
+ /** Resolve boolean CLI flags into includes (composable: each flag toggles its test set). */
80
+ export const resolveIncludes = (opts: { det?: boolean; llm?: boolean; security?: boolean; full?: boolean }): EvalIncludes => {
81
+ if (opts.full) {
82
+ return { deterministic: true, llm: true, security: true };
83
+ }
84
+ // If any explicit flag → compose from flags
85
+ if (opts.det || opts.llm || opts.security) {
86
+ return {
87
+ deterministic: opts.det ?? false,
88
+ llm: opts.llm ?? false,
89
+ security: opts.security ?? false,
90
+ };
91
+ }
92
+ // Default (no flags): deterministic only
93
+ return { deterministic: true, llm: false, security: false };
94
+ };
95
+
96
+ /** Derive a tier label from resolved includes (for display/result). */
97
+ export const resolveTierLabel = (includes: EvalIncludes): EvalTier => {
98
+ if (includes.deterministic && includes.llm && includes.security) return 'full';
99
+ if (includes.llm) return 'standard'; // any combo with LLM → standard
100
+ if (includes.security) return 'security';
101
+ return 'basic';
102
+ };
103
+
104
+ // ── Evaluation method ───────────────────────────────────────────
105
+
106
+ export type EvalMethod = 'deterministic' | 'llm-judge';
107
+
108
+ // ── Conformity Test ─────────────────────────────────────────────
109
+
110
+ export interface ConformityTest {
111
+ readonly id: string; // e.g. "CT-1-001"
112
+ readonly category: EvalCategory;
113
+ readonly name: string;
114
+ readonly description: string;
115
+ readonly method: EvalMethod;
116
+ readonly probe: string; // Prompt to send to target
117
+ readonly euAiActRef: string; // e.g. "Art.13(1)"
118
+
119
+ // Deterministic eval fields (only when method === 'deterministic')
120
+ readonly passPatterns?: readonly RegExp[];
121
+ readonly failPatterns?: readonly RegExp[];
122
+ readonly checkHeaders?: readonly string[]; // Response headers to check
123
+ readonly checkStatus?: number; // Expected HTTP status
124
+ readonly maxLatencyMs?: number; // Max acceptable latency
125
+
126
+ // LLM-judge fields (only when method === 'llm-judge')
127
+ readonly judgePrompt?: string;
128
+ readonly scale?: 'binary' | '1-5';
129
+ readonly passThreshold?: number; // Minimum score to pass (1-5 scale)
130
+
131
+ // Multi-turn test support
132
+ readonly followUp?: string; // Optional follow-up probe
133
+ readonly pairWith?: string; // For bias A/B pair testing (ID of partner)
134
+
135
+ // Metadata
136
+ readonly severity: 'critical' | 'high' | 'medium' | 'low';
137
+ readonly tags?: readonly string[];
138
+ }
139
+
140
+ // ── Test Result ─────────────────────────────────────────────────
141
+
142
+ export interface TestResult {
143
+ readonly testId: string;
144
+ readonly category: EvalCategory;
145
+ readonly name: string;
146
+ readonly method: EvalMethod;
147
+ readonly verdict: 'pass' | 'fail' | 'error' | 'skip' | 'inconclusive';
148
+ readonly score: number; // 0-100
149
+ readonly confidence: number; // 0-100
150
+ readonly reasoning: string;
151
+ readonly probe: string;
152
+ readonly response: string;
153
+ readonly latencyMs: number;
154
+ readonly timestamp: string;
155
+ readonly owaspCategory?: string; // OWASP LLM Top 10 (e.g. 'LLM01') — security probes only
156
+ readonly severity?: 'critical' | 'high' | 'medium' | 'low'; // Carried from ConformityTest/probe
157
+ }
158
+
159
+ // ── Category Score ──────────────────────────────────────────────
160
+
161
+ export interface CategoryScore {
162
+ readonly category: EvalCategory;
163
+ readonly score: number; // 0-100
164
+ readonly grade: string; // A-F
165
+ readonly passed: number;
166
+ readonly failed: number;
167
+ readonly errors: number;
168
+ readonly inconclusive: number;
169
+ readonly skipped: number;
170
+ readonly total: number;
171
+ }
172
+
173
+ // ── Eval Result (top-level) ─────────────────────────────────────
174
+
175
+ export interface EvalResult {
176
+ readonly target: string;
177
+ readonly tier: EvalTier;
178
+ readonly overallScore: number;
179
+ readonly grade: string;
180
+ readonly categories: readonly CategoryScore[];
181
+ readonly securityScore?: number;
182
+ readonly securityGrade?: string;
183
+ readonly results: readonly TestResult[];
184
+ readonly totalTests: number;
185
+ readonly passed: number;
186
+ readonly failed: number;
187
+ readonly errors: number;
188
+ readonly inconclusive: number;
189
+ readonly skipped: number;
190
+ readonly duration: number; // ms
191
+ readonly timestamp: string;
192
+ readonly criticalCapped: boolean;
193
+ readonly agent?: string; // Agent passport name
194
+ readonly adapterName?: string; // Target adapter type (openai, anthropic, ollama, http)
195
+ }
196
+
197
+ // ── Eval Options (input to runner) ──────────────────────────────
198
+
199
+ export const EvalOptionsSchema = z.object({
200
+ target: z.string().url(),
201
+ det: z.boolean().optional(),
202
+ llm: z.boolean().optional(),
203
+ security: z.boolean().optional(),
204
+ full: z.boolean().optional(),
205
+ categories: z.array(EvalCategorySchema).optional(),
206
+ agent: z.string().optional(),
207
+ model: z.string().optional(),
208
+ apiKey: z.string().optional(),
209
+ path: z.string().optional(),
210
+ threshold: z.number().min(0).max(100).optional(),
211
+ json: z.boolean().optional(),
212
+ ci: z.boolean().optional(),
213
+ // Custom adapter fields
214
+ requestTemplate: z.string().optional(), // JSON template with {{probe}} placeholder
215
+ responsePath: z.string().optional(), // Dot-path to response text (e.g. "result.text")
216
+ headers: z.string().optional(), // JSON string of custom headers
217
+ // Concurrency
218
+ concurrency: z.number().int().min(1).max(50).optional(), // Parallel test execution (default: 1)
219
+ });
220
+
221
+ export type EvalOptions = z.infer<typeof EvalOptionsSchema>;
222
+
223
+ // ── Audit Options ───────────────────────────────────────────────
224
+
225
+ export const AuditOptionsSchema = z.object({
226
+ target: z.string().url(),
227
+ agent: z.string().optional(),
228
+ path: z.string().optional(),
229
+ json: z.boolean().optional(),
230
+ });
231
+
232
+ export type AuditOptions = z.infer<typeof AuditOptionsSchema>;
233
+
234
+ // ── Progress callback ───────────────────────────────────────────
235
+
236
+ export interface EvalProgress {
237
+ readonly phase: 'health' | 'deterministic' | 'llm-judge' | 'security' | 'scoring' | 'done';
238
+ readonly completed: number;
239
+ readonly total: number;
240
+ readonly currentTest?: string;
241
+ readonly lastResult?: TestResult;
242
+ }
243
+
244
+ export type EvalProgressCallback = (progress: EvalProgress) => void | Promise<void>;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared verdict counting and score calculation for eval subsystem.
3
+ *
4
+ * Single source of truth — used by eval-runner, conformity-score,
5
+ * security-integration, and eval-evidence.
6
+ */
7
+
8
+ // ── Verdict counting ────────────────────────────────────────────
9
+
10
+ export interface VerdictCounts {
11
+ readonly passed: number;
12
+ readonly failed: number;
13
+ readonly errors: number;
14
+ readonly inconclusive: number;
15
+ readonly skipped: number;
16
+ }
17
+
18
+ /** Count verdicts from test results. Avoids repeated .filter() chains. */
19
+ export const countVerdicts = (
20
+ results: readonly { verdict: string }[],
21
+ ): VerdictCounts => {
22
+ let passed = 0, failed = 0, errors = 0, inconclusive = 0, skipped = 0;
23
+ for (const r of results) {
24
+ switch (r.verdict) {
25
+ case 'pass': passed++; break;
26
+ case 'fail': failed++; break;
27
+ case 'error': errors++; break;
28
+ case 'inconclusive': inconclusive++; break;
29
+ case 'skip': skipped++; break;
30
+ }
31
+ }
32
+ return { passed, failed, errors, inconclusive, skipped };
33
+ };
34
+
35
+ // ── Verdict predicates ──────────────────────────────────────────
36
+
37
+ /** True when a test result represents a failure (fail or error). */
38
+ export const isFailedVerdict = (r: { verdict: string }): boolean =>
39
+ r.verdict === 'fail' || r.verdict === 'error';
40
+
41
+ // ── Score calculation ───────────────────────────────────────────
42
+
43
+ /** Calculate percentage score with division-by-zero protection. */
44
+ export const calculateScore = (passed: number, total: number): number =>
45
+ total > 0 ? Math.round((passed / total) * 100) : 0;
@@ -0,0 +1,101 @@
1
+ import type { Finding } from '../../types/common.types.js';
2
+ import type { FixPlan, FixAction, FixContext } from './types.js';
3
+ import { findStrategy } from './strategies/index.js';
4
+ import { generateUnifiedDiff } from './diff.js';
5
+
6
+ export interface FixerDeps {
7
+ readonly getFramework: () => string;
8
+ readonly getProjectPath: () => string;
9
+ readonly getExistingFiles: () => readonly string[];
10
+ }
11
+
12
+ const descFor = (checkId: string, filePath: string, line: number): string => {
13
+ if (checkId.includes('bare-call') || checkId.includes('bare')) return `wrap bare LLM call at ${filePath}:${line}`;
14
+ if (checkId.startsWith('l4-nhi-') || checkId.startsWith('ext-detect-secrets-')) return `externalize secret at ${filePath}:${line}`;
15
+ if (checkId === 'l4-security-risk' || checkId.includes('unsafe-deser') || checkId.includes('injection')) return `fix security risk at ${filePath}:${line}`;
16
+ if (checkId === 'l4-ast-missing-error-handling' || checkId.includes('missing-error-handling')) return `add error handling at ${filePath}:${line}`;
17
+ if (checkId.startsWith('l3-banned-')) return `remove banned dependency from ${filePath}`;
18
+ if (checkId.startsWith('ext-bandit-')) return `fix security issue at ${filePath}:${line}`;
19
+ return `inline fix at ${filePath}:${line}`;
20
+ };
21
+
22
+ const commitMsgFor = (checkId: string, article: string): string => {
23
+ if (checkId.includes('bare-call') || checkId.includes('bare')) return `fix: wrap bare LLM call with @complior/sdk (${article || 'Art. 50'}) -- via Complior`;
24
+ if (checkId.startsWith('l4-nhi-') || checkId.startsWith('ext-detect-secrets-')) return `fix: externalize hardcoded secret (${article || 'Art. 15'}) -- via Complior`;
25
+ if (checkId === 'l4-security-risk' || checkId.includes('unsafe-deser') || checkId.includes('injection')) return `fix: remediate security risk (${article || 'Art. 15'}) -- via Complior`;
26
+ if (checkId === 'l4-ast-missing-error-handling' || checkId.includes('missing-error-handling')) return `fix: add LLM error handling (${article || 'Art. 14'}) -- via Complior`;
27
+ if (checkId.startsWith('l3-banned-')) return `fix: remove banned dependency (${article || 'Art. 5'}) -- via Complior`;
28
+ if (checkId.startsWith('ext-bandit-')) return `fix: remediate security issue (${article || 'Art. 15'}) -- via Complior`;
29
+ return `fix: inline compliance fix (${article || 'EU AI Act'}) -- via Complior`;
30
+ };
31
+
32
+ const buildInlineFixPlan = (finding: Finding): FixPlan => {
33
+ const diff = finding.fixDiff!;
34
+ const desc = descFor(finding.checkId, diff.filePath, diff.startLine);
35
+ const action: FixAction = {
36
+ type: 'splice',
37
+ path: diff.filePath,
38
+ beforeLines: diff.before,
39
+ afterLines: diff.after,
40
+ startLine: diff.startLine,
41
+ importLine: diff.importLine,
42
+ description: `Inline fix: ${desc}`,
43
+ };
44
+
45
+ return {
46
+ obligationId: finding.obligationId ?? '',
47
+ checkId: finding.checkId,
48
+ article: finding.articleReference ?? '',
49
+ fixType: 'code_injection',
50
+ framework: '',
51
+ actions: [action],
52
+ diff: generateUnifiedDiff(diff.filePath, diff.before.join('\n'), diff.after.join('\n')),
53
+ scoreImpact: 6,
54
+ commitMessage: commitMsgFor(finding.checkId, finding.articleReference ?? ''),
55
+ description: `Inline fix: ${desc}`,
56
+ };
57
+ };
58
+
59
+ export const createFixer = (deps: FixerDeps) => {
60
+ const { getFramework, getProjectPath, getExistingFiles } = deps;
61
+
62
+ const buildContext = (options?: { useAi?: boolean }): FixContext => ({
63
+ projectPath: getProjectPath(),
64
+ framework: getFramework(),
65
+ existingFiles: getExistingFiles(),
66
+ useAi: options?.useAi,
67
+ });
68
+
69
+ const generateFix = (finding: Finding, options?: { useAi?: boolean }): FixPlan | null => {
70
+ if (finding.type !== 'fail') return null;
71
+ // Priority 1: Inline fix from scanner fixDiff
72
+ if (finding.fixDiff) return buildInlineFixPlan(finding);
73
+ // Priority 2: Strategy-based scaffold
74
+ return findStrategy(finding, buildContext(options));
75
+ };
76
+
77
+ const generateFixes = (findings: readonly Finding[], options?: { useAi?: boolean }): readonly FixPlan[] => {
78
+ const plans: FixPlan[] = [];
79
+ const seen = new Set<string>();
80
+ for (const finding of findings) {
81
+ const plan = generateFix(finding, options);
82
+ if (plan === null) continue;
83
+ // Deduplicate: splice by path:startLine, others by output path
84
+ const key = plan.actions[0]?.type === 'splice'
85
+ ? `${plan.actions[0].path}:${plan.actions[0].startLine}`
86
+ : plan.actions[0]?.path ?? plan.checkId;
87
+ if (seen.has(key)) continue;
88
+ seen.add(key);
89
+ plans.push(plan);
90
+ }
91
+ return plans;
92
+ };
93
+
94
+ const previewFix = (finding: Finding): FixPlan | null => {
95
+ return generateFix(finding);
96
+ };
97
+
98
+ return Object.freeze({ generateFix, generateFixes, previewFix });
99
+ };
100
+
101
+ export type Fixer = ReturnType<typeof createFixer>;
@@ -0,0 +1,70 @@
1
+ export const generateUnifiedDiff = (
2
+ filePath: string,
3
+ oldContent: string,
4
+ newContent: string,
5
+ ): string => {
6
+ const oldLines = oldContent.split('\n');
7
+ const newLines = newContent.split('\n');
8
+
9
+ const lines: string[] = [
10
+ `--- a/${filePath}`,
11
+ `+++ b/${filePath}`,
12
+ ];
13
+
14
+ // Simple diff: show removed and added lines
15
+ const maxLen = Math.max(oldLines.length, newLines.length);
16
+ let chunkStart = -1;
17
+ let chunkOld: string[] = [];
18
+ let chunkNew: string[] = [];
19
+ let context: string[] = [];
20
+
21
+ const flushChunk = (): void => {
22
+ if (chunkOld.length === 0 && chunkNew.length === 0) return;
23
+ const oldStart = Math.max(1, chunkStart - context.length + 1);
24
+ const oldCount = context.length + chunkOld.length;
25
+ const newCount = context.length + chunkNew.length;
26
+ lines.push(`@@ -${oldStart},${oldCount} +${oldStart},${newCount} @@`);
27
+ for (const c of context) lines.push(` ${c}`);
28
+ for (const r of chunkOld) lines.push(`-${r}`);
29
+ for (const a of chunkNew) lines.push(`+${a}`);
30
+ chunkOld = [];
31
+ chunkNew = [];
32
+ context = [];
33
+ };
34
+
35
+ for (let i = 0; i < maxLen; i++) {
36
+ const oldLine = i < oldLines.length ? oldLines[i] : undefined;
37
+ const newLine = i < newLines.length ? newLines[i] : undefined;
38
+
39
+ if (oldLine === newLine) {
40
+ if (chunkOld.length > 0 || chunkNew.length > 0) {
41
+ flushChunk();
42
+ }
43
+ if (oldLine !== undefined) {
44
+ context = [oldLine];
45
+ }
46
+ chunkStart = i + 1;
47
+ } else {
48
+ if (chunkOld.length === 0 && chunkNew.length === 0) {
49
+ chunkStart = i;
50
+ }
51
+ if (oldLine !== undefined) chunkOld.push(oldLine);
52
+ if (newLine !== undefined) chunkNew.push(newLine);
53
+ }
54
+ }
55
+
56
+ flushChunk();
57
+
58
+ return lines.join('\n');
59
+ };
60
+
61
+ export const generateCreateDiff = (filePath: string, content: string): string => {
62
+ const lines = content.split('\n');
63
+ const header = [
64
+ `--- /dev/null`,
65
+ `+++ b/${filePath}`,
66
+ `@@ -0,0 +1,${lines.length} @@`,
67
+ ];
68
+
69
+ return [...header, ...lines.map((l) => `+${l}`)].join('\n');
70
+ };
@@ -0,0 +1,23 @@
1
+ import type { FixHistory, FixHistoryEntry } from './types.js';
2
+
3
+ export const createEmptyHistory = (): FixHistory => ({ fixes: [] });
4
+
5
+ export const addEntry = (history: FixHistory, entry: FixHistoryEntry): FixHistory => ({
6
+ fixes: [...history.fixes, entry],
7
+ });
8
+
9
+ export const markUndone = (history: FixHistory, id: number): FixHistory => ({
10
+ fixes: history.fixes.map((f) =>
11
+ f.id === id ? { ...f, status: 'undone' as const } : f,
12
+ ),
13
+ });
14
+
15
+ export const getLastApplied = (history: FixHistory): FixHistoryEntry | null => {
16
+ for (let i = history.fixes.length - 1; i >= 0; i--) {
17
+ if (history.fixes[i]!.status === 'applied') return history.fixes[i]!;
18
+ }
19
+ return null;
20
+ };
21
+
22
+ export const getById = (history: FixHistory, id: number): FixHistoryEntry | null =>
23
+ history.fixes.find((f) => f.id === id) ?? null;