@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.
- package/.well-known/ai-compliance.json +16 -0
- package/COMPLIANCE.md +64 -0
- package/data/data-integrity.test.ts +75 -0
- package/data/eval/eval-mappings.json +33 -0
- package/data/llm/model-pricing.json +15 -0
- package/data/llm/model-routing.json +36 -0
- package/data/onboarding/risk-profile.json +17 -0
- package/data/regulations/eu-ai-act/README.md +245 -0
- package/data/regulations/eu-ai-act/applicability-tree.json +160 -0
- package/data/regulations/eu-ai-act/cross-mapping.json +175 -0
- package/data/regulations/eu-ai-act/localization.json +186 -0
- package/data/regulations/eu-ai-act/obligations.json +3981 -0
- package/data/regulations/eu-ai-act/regulation-meta.json +482 -0
- package/data/regulations/eu-ai-act/scoring.json +342 -0
- package/data/regulations/eu-ai-act/technical-requirements.json +2590 -0
- package/data/regulations/eu-ai-act/timeline.json +160 -0
- package/data/regulations/jurisdictions/at.json +15 -0
- package/data/regulations/jurisdictions/be.json +15 -0
- package/data/regulations/jurisdictions/bg.json +15 -0
- package/data/regulations/jurisdictions/cy.json +15 -0
- package/data/regulations/jurisdictions/cz.json +15 -0
- package/data/regulations/jurisdictions/de.json +15 -0
- package/data/regulations/jurisdictions/dk.json +15 -0
- package/data/regulations/jurisdictions/ee.json +15 -0
- package/data/regulations/jurisdictions/es.json +15 -0
- package/data/regulations/jurisdictions/fi.json +15 -0
- package/data/regulations/jurisdictions/fr.json +15 -0
- package/data/regulations/jurisdictions/gr.json +15 -0
- package/data/regulations/jurisdictions/hr.json +15 -0
- package/data/regulations/jurisdictions/hu.json +15 -0
- package/data/regulations/jurisdictions/ie.json +15 -0
- package/data/regulations/jurisdictions/is.json +15 -0
- package/data/regulations/jurisdictions/it.json +15 -0
- package/data/regulations/jurisdictions/li.json +15 -0
- package/data/regulations/jurisdictions/lt.json +15 -0
- package/data/regulations/jurisdictions/lu.json +15 -0
- package/data/regulations/jurisdictions/lv.json +15 -0
- package/data/regulations/jurisdictions/mt.json +15 -0
- package/data/regulations/jurisdictions/nl.json +15 -0
- package/data/regulations/jurisdictions/no.json +15 -0
- package/data/regulations/jurisdictions/pl.json +15 -0
- package/data/regulations/jurisdictions/pt.json +15 -0
- package/data/regulations/jurisdictions/ro.json +15 -0
- package/data/regulations/jurisdictions/se.json +15 -0
- package/data/regulations/jurisdictions/si.json +15 -0
- package/data/regulations/jurisdictions/sk.json +15 -0
- package/data/scanner/check-id-categories.json +81 -0
- package/data/scanner/confidence-params.json +16 -0
- package/data/scanner/limits.json +4 -0
- package/data/schemas/http-contract-sample.json +79 -0
- package/data/schemas/http-contract.json +144 -0
- package/data/semgrep-rules/bare-call.yaml +37 -0
- package/data/semgrep-rules/injection.yaml +73 -0
- package/data/semgrep-rules/missing-error-handling.yaml +58 -0
- package/data/semgrep-rules/unsafe-deser.yaml +65 -0
- package/data/templates/eu-ai-act/ai-literacy.md +184 -0
- package/data/templates/eu-ai-act/art5-screening.md +131 -0
- package/data/templates/eu-ai-act/data-governance.md +145 -0
- package/data/templates/eu-ai-act/declaration-of-conformity.md +161 -0
- package/data/templates/eu-ai-act/fria.md +127 -0
- package/data/templates/eu-ai-act/gpai-systemic-risk.md +150 -0
- package/data/templates/eu-ai-act/gpai-transparency.md +166 -0
- package/data/templates/eu-ai-act/incident-report.md +188 -0
- package/data/templates/eu-ai-act/instructions-for-use.md +202 -0
- package/data/templates/eu-ai-act/monitoring-policy.md +110 -0
- package/data/templates/eu-ai-act/qms.md +180 -0
- package/data/templates/eu-ai-act/risk-management-system.md +123 -0
- package/data/templates/eu-ai-act/technical-documentation.md +287 -0
- package/data/templates/eu-ai-act/worker-notification.md +143 -0
- package/data/templates/policies/biometrics-ai-policy.md +214 -0
- package/data/templates/policies/critical-infra-ai-policy.md +228 -0
- package/data/templates/policies/education-ai-policy.md +184 -0
- package/data/templates/policies/finance-ai-policy.md +191 -0
- package/data/templates/policies/healthcare-ai-policy.md +197 -0
- package/data/templates/policies/hr-ai-policy.md +178 -0
- package/data/templates/policies/legal-ai-policy.md +189 -0
- package/data/templates/policies/migration-ai-policy.md +239 -0
- package/engine.log +7 -0
- package/package.json +74 -0
- package/src/composition-root.ts +791 -0
- package/src/data/eval/conformity-tests.test.ts +122 -0
- package/src/data/eval/ct-1-transparency.ts +106 -0
- package/src/data/eval/ct-10-gpai.ts +25 -0
- package/src/data/eval/ct-11-industry.ts +42 -0
- package/src/data/eval/ct-2-oversight.ts +41 -0
- package/src/data/eval/ct-3-explanation.ts +14 -0
- package/src/data/eval/ct-4-bias.ts +83 -0
- package/src/data/eval/ct-5-accuracy.ts +41 -0
- package/src/data/eval/ct-6-robustness.ts +81 -0
- package/src/data/eval/ct-7-prohibited.ts +52 -0
- package/src/data/eval/ct-8-logging.ts +68 -0
- package/src/data/eval/ct-9-risk-awareness.ts +33 -0
- package/src/data/eval/deterministic-evaluator.ts +120 -0
- package/src/data/eval/index.ts +55 -0
- package/src/data/eval/judge-prompts.ts +146 -0
- package/src/data/eval/llm-judged-tests.ts +279 -0
- package/src/data/eval/llm-tests.test.ts +83 -0
- package/src/data/eval/remediation/ct-1-transparency.ts +91 -0
- package/src/data/eval/remediation/ct-10-gpai.ts +94 -0
- package/src/data/eval/remediation/ct-11-industry.ts +94 -0
- package/src/data/eval/remediation/ct-2-oversight.ts +71 -0
- package/src/data/eval/remediation/ct-3-explanation.ts +70 -0
- package/src/data/eval/remediation/ct-4-bias.ts +70 -0
- package/src/data/eval/remediation/ct-5-accuracy.ts +70 -0
- package/src/data/eval/remediation/ct-6-robustness.ts +70 -0
- package/src/data/eval/remediation/ct-7-prohibited.ts +94 -0
- package/src/data/eval/remediation/ct-8-logging.ts +94 -0
- package/src/data/eval/remediation/ct-9-risk-awareness.ts +94 -0
- package/src/data/eval/remediation/index.ts +89 -0
- package/src/data/eval/remediation/owasp-art5.ts +15 -0
- package/src/data/eval/remediation/owasp-llm01.ts +72 -0
- package/src/data/eval/remediation/owasp-llm02.ts +72 -0
- package/src/data/eval/remediation/owasp-llm03.ts +15 -0
- package/src/data/eval/remediation/owasp-llm04.ts +15 -0
- package/src/data/eval/remediation/owasp-llm05.ts +15 -0
- package/src/data/eval/remediation/owasp-llm06.ts +15 -0
- package/src/data/eval/remediation/owasp-llm07.ts +15 -0
- package/src/data/eval/remediation/owasp-llm08.ts +15 -0
- package/src/data/eval/remediation/owasp-llm09.ts +15 -0
- package/src/data/eval/remediation/owasp-llm10.ts +15 -0
- package/src/data/eval/remediation/remediation.test.ts +229 -0
- package/src/data/eval/remediation/test-mapping.ts +290 -0
- package/src/data/eval/security-rubrics.ts +381 -0
- package/src/data/finding-explanations.json +453 -0
- package/src/data/industry-patterns.ts +161 -0
- package/src/data/registry-cards.ts +368 -0
- package/src/data/regulation/index.ts +5 -0
- package/src/data/regulation/jurisdiction-data.test.ts +73 -0
- package/src/data/regulation/jurisdiction-data.ts +65 -0
- package/src/data/regulation/regulation-data.ts +19 -0
- package/src/data/regulation/regulation-loader.test.ts +107 -0
- package/src/data/regulation/regulation-loader.ts +56 -0
- package/src/data/scanner-constants.ts +46 -0
- package/src/data/schemas/schemas-core.ts +140 -0
- package/src/data/schemas/schemas-supplementary.ts +211 -0
- package/src/data/schemas/schemas.ts +28 -0
- package/src/data/security/attack-probes.test.ts +62 -0
- package/src/data/security/attack-probes.ts +496 -0
- package/src/data/security/eu-ai-act-security.ts +40 -0
- package/src/data/security/index.ts +19 -0
- package/src/data/security/mitre-atlas.test.ts +43 -0
- package/src/data/security/mitre-atlas.ts +93 -0
- package/src/data/security/nist-ai-rmf.ts +43 -0
- package/src/data/security/owasp-llm-top10.test.ts +60 -0
- package/src/data/security/owasp-llm-top10.ts +138 -0
- package/src/data/template-registry.ts +53 -0
- package/src/data/tool-versions.json +22 -0
- package/src/domain/audit/audit-package.test.ts +152 -0
- package/src/domain/audit/audit-package.ts +166 -0
- package/src/domain/audit/audit-trail.test.ts +121 -0
- package/src/domain/audit/audit-trail.ts +174 -0
- package/src/domain/audit/index.ts +8 -0
- package/src/domain/audit/permissions-matrix.test.ts +136 -0
- package/src/domain/audit/permissions-matrix.ts +121 -0
- package/src/domain/certification/adversarial/bias-tests.ts +95 -0
- package/src/domain/certification/adversarial/evaluators.ts +304 -0
- package/src/domain/certification/adversarial/index.ts +11 -0
- package/src/domain/certification/adversarial/prompt-injection.ts +103 -0
- package/src/domain/certification/adversarial/safety-boundary.ts +132 -0
- package/src/domain/certification/aiuc1-readiness.test.ts +236 -0
- package/src/domain/certification/aiuc1-readiness.ts +298 -0
- package/src/domain/certification/aiuc1-requirements.ts +235 -0
- package/src/domain/certification/index.ts +10 -0
- package/src/domain/certification/redteam-runner.test.ts +97 -0
- package/src/domain/certification/redteam-runner.ts +205 -0
- package/src/domain/certification/test-runner.test.ts +232 -0
- package/src/domain/certification/test-runner.ts +289 -0
- package/src/domain/cost/cost-estimator.test.ts +187 -0
- package/src/domain/cost/cost-estimator.ts +133 -0
- package/src/domain/disclaimer.test.ts +52 -0
- package/src/domain/disclaimer.ts +39 -0
- package/src/domain/documents/ai-enricher.test.ts +120 -0
- package/src/domain/documents/ai-enricher.ts +159 -0
- package/src/domain/documents/document-generator.test.ts +318 -0
- package/src/domain/documents/document-generator.ts +239 -0
- package/src/domain/documents/index.ts +9 -0
- package/src/domain/documents/passport-helpers.ts +25 -0
- package/src/domain/documents/policy-generator.test.ts +252 -0
- package/src/domain/documents/policy-generator.ts +94 -0
- package/src/domain/documents/worker-notification-generator.test.ts +162 -0
- package/src/domain/documents/worker-notification-generator.ts +141 -0
- package/src/domain/eval/adapters/adapter-port.ts +94 -0
- package/src/domain/eval/adapters/adapters.test.ts +303 -0
- package/src/domain/eval/adapters/anthropic-adapter.ts +57 -0
- package/src/domain/eval/adapters/auto-detect.ts +104 -0
- package/src/domain/eval/adapters/create-chat-adapter.ts +106 -0
- package/src/domain/eval/adapters/custom-adapter.ts +74 -0
- package/src/domain/eval/adapters/http-adapter.ts +66 -0
- package/src/domain/eval/adapters/index.ts +7 -0
- package/src/domain/eval/adapters/ollama-adapter.ts +48 -0
- package/src/domain/eval/adapters/openai-adapter.ts +58 -0
- package/src/domain/eval/adapters/with-timeout.ts +25 -0
- package/src/domain/eval/conformity-score.test.ts +161 -0
- package/src/domain/eval/conformity-score.ts +135 -0
- package/src/domain/eval/eval-constants.ts +55 -0
- package/src/domain/eval/eval-evidence.test.ts +85 -0
- package/src/domain/eval/eval-evidence.ts +103 -0
- package/src/domain/eval/eval-fix-generator.test.ts +421 -0
- package/src/domain/eval/eval-fix-generator.ts +205 -0
- package/src/domain/eval/eval-passport.test.ts +82 -0
- package/src/domain/eval/eval-passport.ts +89 -0
- package/src/domain/eval/eval-remediation-report.test.ts +682 -0
- package/src/domain/eval/eval-remediation-report.ts +170 -0
- package/src/domain/eval/eval-report.ts +108 -0
- package/src/domain/eval/eval-runner.test.ts +609 -0
- package/src/domain/eval/eval-runner.ts +593 -0
- package/src/domain/eval/eval-to-findings.test.ts +293 -0
- package/src/domain/eval/eval-to-findings.ts +83 -0
- package/src/domain/eval/index.ts +31 -0
- package/src/domain/eval/llm-judge.test.ts +139 -0
- package/src/domain/eval/llm-judge.ts +168 -0
- package/src/domain/eval/remediation-types.ts +90 -0
- package/src/domain/eval/security-integration.test.ts +196 -0
- package/src/domain/eval/security-integration.ts +136 -0
- package/src/domain/eval/types.test.ts +173 -0
- package/src/domain/eval/types.ts +244 -0
- package/src/domain/eval/verdict-utils.ts +45 -0
- package/src/domain/fixer/create-fixer.ts +101 -0
- package/src/domain/fixer/diff.ts +70 -0
- package/src/domain/fixer/fix-history.ts +23 -0
- package/src/domain/fixer/fixer.test.ts +306 -0
- package/src/domain/fixer/index.ts +9 -0
- package/src/domain/fixer/strategies/bandit-fix.ts +61 -0
- package/src/domain/fixer/strategies/bias-testing.ts +49 -0
- package/src/domain/fixer/strategies/ci-compliance.ts +57 -0
- package/src/domain/fixer/strategies/content-marking.ts +45 -0
- package/src/domain/fixer/strategies/cve-upgrade.ts +66 -0
- package/src/domain/fixer/strategies/data-governance.ts +65 -0
- package/src/domain/fixer/strategies/disclosure.ts +69 -0
- package/src/domain/fixer/strategies/doc-code-sync.ts +53 -0
- package/src/domain/fixer/strategies/documentation.ts +59 -0
- package/src/domain/fixer/strategies/error-handler.ts +63 -0
- package/src/domain/fixer/strategies/hitl-gate.ts +67 -0
- package/src/domain/fixer/strategies/index.ts +61 -0
- package/src/domain/fixer/strategies/kill-switch-test.ts +85 -0
- package/src/domain/fixer/strategies/kill-switch.ts +53 -0
- package/src/domain/fixer/strategies/license-fix.ts +57 -0
- package/src/domain/fixer/strategies/log-retention.ts +40 -0
- package/src/domain/fixer/strategies/logging.ts +59 -0
- package/src/domain/fixer/strategies/metadata.ts +45 -0
- package/src/domain/fixer/strategies/permission-guard.ts +84 -0
- package/src/domain/fixer/strategies/record-keeping.ts +69 -0
- package/src/domain/fixer/strategies/secret-rotation.ts +52 -0
- package/src/domain/fixer/strategies.test.ts +341 -0
- package/src/domain/fixer/template-engine.test.ts +64 -0
- package/src/domain/fixer/template-engine.ts +38 -0
- package/src/domain/fixer/types.ts +88 -0
- package/src/domain/frameworks/aiuc1-framework.test.ts +159 -0
- package/src/domain/frameworks/aiuc1-framework.ts +126 -0
- package/src/domain/frameworks/collect-foundation-metrics.test.ts +96 -0
- package/src/domain/frameworks/collect-foundation-metrics.ts +34 -0
- package/src/domain/frameworks/eu-ai-act-framework.test.ts +117 -0
- package/src/domain/frameworks/eu-ai-act-framework.ts +100 -0
- package/src/domain/frameworks/framework-registry.test.ts +91 -0
- package/src/domain/frameworks/framework-registry.ts +38 -0
- package/src/domain/frameworks/index.ts +8 -0
- package/src/domain/frameworks/mitre-atlas-framework.test.ts +53 -0
- package/src/domain/frameworks/mitre-atlas-framework.ts +53 -0
- package/src/domain/frameworks/owasp-llm-framework.test.ts +77 -0
- package/src/domain/frameworks/owasp-llm-framework.ts +54 -0
- package/src/domain/frameworks/score-plugin-framework.ts +117 -0
- package/src/domain/fria/fria-generator.test.ts +273 -0
- package/src/domain/fria/fria-generator.ts +366 -0
- package/src/domain/import/promptfoo-importer.test.ts +103 -0
- package/src/domain/import/promptfoo-importer.ts +151 -0
- package/src/domain/onboarding/guided-onboarding.test.ts +144 -0
- package/src/domain/onboarding/guided-onboarding.ts +135 -0
- package/src/domain/passport/builder/domain-mapper.ts +9 -0
- package/src/domain/passport/builder/manifest-builder.test.ts +546 -0
- package/src/domain/passport/builder/manifest-builder.ts +535 -0
- package/src/domain/passport/builder/manifest-diff.test.ts +105 -0
- package/src/domain/passport/builder/manifest-diff.ts +89 -0
- package/src/domain/passport/builder/manifest-files.ts +17 -0
- package/src/domain/passport/crypto-signer.test.ts +93 -0
- package/src/domain/passport/crypto-signer.ts +157 -0
- package/src/domain/passport/discovery/agent-discovery.test.ts +296 -0
- package/src/domain/passport/discovery/agent-discovery.ts +325 -0
- package/src/domain/passport/discovery/autonomy-analyzer.test.ts +141 -0
- package/src/domain/passport/discovery/autonomy-analyzer.ts +113 -0
- package/src/domain/passport/discovery/permission-scanner.test.ts +191 -0
- package/src/domain/passport/discovery/permission-scanner.ts +414 -0
- package/src/domain/passport/export/a2a-mapper.ts +75 -0
- package/src/domain/passport/export/aiuc1-mapper.ts +126 -0
- package/src/domain/passport/export/export.test.ts +207 -0
- package/src/domain/passport/export/index.ts +41 -0
- package/src/domain/passport/export/nist-mapper.ts +227 -0
- package/src/domain/passport/import/a2a-importer.test.ts +133 -0
- package/src/domain/passport/import/a2a-importer.ts +156 -0
- package/src/domain/passport/import/index.ts +2 -0
- package/src/domain/passport/index.ts +32 -0
- package/src/domain/passport/obligation-field-map.test.ts +113 -0
- package/src/domain/passport/obligation-field-map.ts +117 -0
- package/src/domain/passport/passport-validator.test.ts +156 -0
- package/src/domain/passport/passport-validator.ts +126 -0
- package/src/domain/passport/scan-to-compliance.test.ts +336 -0
- package/src/domain/passport/scan-to-compliance.ts +166 -0
- package/src/domain/passport/test-generator.test.ts +93 -0
- package/src/domain/passport/test-generator.ts +136 -0
- package/src/domain/proxy/index.ts +11 -0
- package/src/domain/proxy/json-rpc.test.ts +72 -0
- package/src/domain/proxy/json-rpc.ts +53 -0
- package/src/domain/proxy/policy-engine.test.ts +259 -0
- package/src/domain/proxy/policy-engine.ts +137 -0
- package/src/domain/proxy/proxy-bridge.ts +125 -0
- package/src/domain/proxy/proxy-interceptor.test.ts +184 -0
- package/src/domain/proxy/proxy-interceptor.ts +120 -0
- package/src/domain/proxy/proxy-types.ts +35 -0
- package/src/domain/registry/compute-agent-score.test.ts +279 -0
- package/src/domain/registry/compute-agent-score.ts +162 -0
- package/src/domain/reporter/audit-report.test.ts +87 -0
- package/src/domain/reporter/audit-report.ts +116 -0
- package/src/domain/reporter/badge-generator.test.ts +54 -0
- package/src/domain/reporter/badge-generator.ts +40 -0
- package/src/domain/reporter/compliance-md.ts +45 -0
- package/src/domain/reporter/index.ts +7 -0
- package/src/domain/reporter/pdf-renderer.ts +282 -0
- package/src/domain/reporter/share.test.ts +92 -0
- package/src/domain/reporter/share.ts +80 -0
- package/src/domain/scanner/ast/swc-analyzer.test.ts +49 -0
- package/src/domain/scanner/ast/swc-analyzer.ts +124 -0
- package/src/domain/scanner/attestations.ts +97 -0
- package/src/domain/scanner/checks/ai-disclosure.test.ts +90 -0
- package/src/domain/scanner/checks/ai-disclosure.ts +54 -0
- package/src/domain/scanner/checks/ai-literacy.ts +163 -0
- package/src/domain/scanner/checks/behavioral-constraints.test.ts +167 -0
- package/src/domain/scanner/checks/behavioral-constraints.ts +86 -0
- package/src/domain/scanner/checks/compliance-metadata.ts +63 -0
- package/src/domain/scanner/checks/content-marking.ts +74 -0
- package/src/domain/scanner/checks/dep-deep-scan.test.ts +318 -0
- package/src/domain/scanner/checks/dep-deep-scan.ts +137 -0
- package/src/domain/scanner/checks/documentation.test.ts +88 -0
- package/src/domain/scanner/checks/documentation.ts +79 -0
- package/src/domain/scanner/checks/git-history.test.ts +120 -0
- package/src/domain/scanner/checks/git-history.ts +163 -0
- package/src/domain/scanner/checks/gpai-systemic-risk.test.ts +84 -0
- package/src/domain/scanner/checks/gpai-systemic-risk.ts +98 -0
- package/src/domain/scanner/checks/gpai-transparency.ts +94 -0
- package/src/domain/scanner/checks/index.ts +28 -0
- package/src/domain/scanner/checks/industry/index.ts +40 -0
- package/src/domain/scanner/checks/industry/industry.test.ts +287 -0
- package/src/domain/scanner/checks/interaction-logging.test.ts +113 -0
- package/src/domain/scanner/checks/interaction-logging.ts +142 -0
- package/src/domain/scanner/checks/nhi-scanner.test.ts +158 -0
- package/src/domain/scanner/checks/nhi-scanner.ts +78 -0
- package/src/domain/scanner/checks/passport-completeness.test.ts +127 -0
- package/src/domain/scanner/checks/passport-completeness.ts +82 -0
- package/src/domain/scanner/checks/passport-presence.test.ts +56 -0
- package/src/domain/scanner/checks/passport-presence.ts +78 -0
- package/src/domain/scanner/checks/pattern-check-factory.ts +70 -0
- package/src/domain/scanner/checks/permission-scanner.test.ts +279 -0
- package/src/domain/scanner/checks/permission-scanner.ts +90 -0
- package/src/domain/scanner/checks/presence-check-factory.test.ts +124 -0
- package/src/domain/scanner/checks/presence-check-factory.ts +275 -0
- package/src/domain/scanner/compliance-diff.test.ts +165 -0
- package/src/domain/scanner/compliance-diff.ts +138 -0
- package/src/domain/scanner/confidence.test.ts +235 -0
- package/src/domain/scanner/confidence.ts +156 -0
- package/src/domain/scanner/constants.ts +13 -0
- package/src/domain/scanner/create-scanner.ts +573 -0
- package/src/domain/scanner/cross-layer.test.ts +372 -0
- package/src/domain/scanner/cross-layer.ts +232 -0
- package/src/domain/scanner/data/ai-packages.ts +82 -0
- package/src/domain/scanner/debt-calculator.test.ts +89 -0
- package/src/domain/scanner/debt-calculator.ts +111 -0
- package/src/domain/scanner/drift.test.ts +191 -0
- package/src/domain/scanner/drift.ts +73 -0
- package/src/domain/scanner/evidence-store.test.ts +207 -0
- package/src/domain/scanner/evidence-store.ts +195 -0
- package/src/domain/scanner/evidence.test.ts +104 -0
- package/src/domain/scanner/evidence.ts +71 -0
- package/src/domain/scanner/external/bandit-runner.test.ts +45 -0
- package/src/domain/scanner/external/bandit-runner.ts +90 -0
- package/src/domain/scanner/external/checks.ts +321 -0
- package/src/domain/scanner/external/dedup.test.ts +79 -0
- package/src/domain/scanner/external/dedup.ts +94 -0
- package/src/domain/scanner/external/detect-secrets-runner.test.ts +58 -0
- package/src/domain/scanner/external/detect-secrets-runner.ts +81 -0
- package/src/domain/scanner/external/external-scanner.test.ts +221 -0
- package/src/domain/scanner/external/external-scanner.ts +36 -0
- package/src/domain/scanner/external/finding-mapper.test.ts +95 -0
- package/src/domain/scanner/external/finding-mapper.ts +138 -0
- package/src/domain/scanner/external/index.ts +15 -0
- package/src/domain/scanner/external/mappings.ts +93 -0
- package/src/domain/scanner/external/modelscan-runner.test.ts +35 -0
- package/src/domain/scanner/external/modelscan-runner.ts +101 -0
- package/src/domain/scanner/external/path-utils.ts +8 -0
- package/src/domain/scanner/external/runner-port.ts +45 -0
- package/src/domain/scanner/external/semgrep-runner.test.ts +52 -0
- package/src/domain/scanner/external/semgrep-runner.ts +94 -0
- package/src/domain/scanner/external/types.ts +32 -0
- package/src/domain/scanner/finding-attribution.test.ts +444 -0
- package/src/domain/scanner/finding-attribution.ts +195 -0
- package/src/domain/scanner/finding-explainer.test.ts +157 -0
- package/src/domain/scanner/finding-explainer.ts +73 -0
- package/src/domain/scanner/fix-diff-builder.test.ts +272 -0
- package/src/domain/scanner/fix-diff-builder.ts +477 -0
- package/src/domain/scanner/import-graph.test.ts +162 -0
- package/src/domain/scanner/import-graph.ts +198 -0
- package/src/domain/scanner/languages/adapter.test.ts +105 -0
- package/src/domain/scanner/languages/adapter.ts +239 -0
- package/src/domain/scanner/layers/index.ts +24 -0
- package/src/domain/scanner/layers/layer1-files.ts +54 -0
- package/src/domain/scanner/layers/layer2-docs.test.ts +1207 -0
- package/src/domain/scanner/layers/layer2-docs.ts +297 -0
- package/src/domain/scanner/layers/layer2-parsing.ts +217 -0
- package/src/domain/scanner/layers/layer3-config.test.ts +187 -0
- package/src/domain/scanner/layers/layer3-config.ts +279 -0
- package/src/domain/scanner/layers/layer3-parsers.ts +73 -0
- package/src/domain/scanner/layers/layer4-patterns.test.ts +397 -0
- package/src/domain/scanner/layers/layer4-patterns.ts +216 -0
- package/src/domain/scanner/layers/layer5-docs.test.ts +99 -0
- package/src/domain/scanner/layers/layer5-docs.ts +250 -0
- package/src/domain/scanner/layers/layer5-llm.test.ts +146 -0
- package/src/domain/scanner/layers/layer5-llm.ts +262 -0
- package/src/domain/scanner/layers/layer5-targeted.test.ts +93 -0
- package/src/domain/scanner/layers/layer5-targeted.ts +233 -0
- package/src/domain/scanner/layers/lockfile-parsers.test.ts +320 -0
- package/src/domain/scanner/layers/lockfile-parsers.ts +184 -0
- package/src/domain/scanner/regulation-version.test.ts +54 -0
- package/src/domain/scanner/regulation-version.ts +23 -0
- package/src/domain/scanner/role-filter.test.ts +116 -0
- package/src/domain/scanner/role-filter.ts +51 -0
- package/src/domain/scanner/rules/banned-packages-data.ts +553 -0
- package/src/domain/scanner/rules/banned-packages-sdk.ts +65 -0
- package/src/domain/scanner/rules/banned-packages.test.ts +249 -0
- package/src/domain/scanner/rules/banned-packages.ts +55 -0
- package/src/domain/scanner/rules/comment-filter.test.ts +115 -0
- package/src/domain/scanner/rules/comment-filter.ts +297 -0
- package/src/domain/scanner/rules/index.ts +9 -0
- package/src/domain/scanner/rules/nhi-patterns.test.ts +128 -0
- package/src/domain/scanner/rules/nhi-patterns.ts +60 -0
- package/src/domain/scanner/rules/pattern-rules.ts +1152 -0
- package/src/domain/scanner/sbom.test.ts +136 -0
- package/src/domain/scanner/sbom.ts +103 -0
- package/src/domain/scanner/scan-cache.test.ts +136 -0
- package/src/domain/scanner/scan-cache.ts +115 -0
- package/src/domain/scanner/scanner.test.ts +125 -0
- package/src/domain/scanner/score-calculator.test.ts +363 -0
- package/src/domain/scanner/score-calculator.ts +189 -0
- package/src/domain/scanner/security-score.test.ts +107 -0
- package/src/domain/scanner/security-score.ts +116 -0
- package/src/domain/scanner/source-filter.ts +24 -0
- package/src/domain/scanner/validators.ts +223 -0
- package/src/domain/shared/compliance-constants.ts +48 -0
- package/src/domain/shared/disclosure-patterns.ts +16 -0
- package/src/domain/shared/index.ts +6 -0
- package/src/domain/shared/parse-dependencies.ts +21 -0
- package/src/domain/supply-chain/dependency-analyzer.ts +138 -0
- package/src/domain/supply-chain/index.ts +3 -0
- package/src/domain/supply-chain/supply-chain.test.ts +211 -0
- package/src/domain/supply-chain/types.ts +32 -0
- package/src/domain/whatif/config-fixer.ts +187 -0
- package/src/domain/whatif/index.ts +6 -0
- package/src/domain/whatif/scenario-engine.ts +121 -0
- package/src/domain/whatif/simulate-actions.test.ts +161 -0
- package/src/domain/whatif/simulate-actions.ts +114 -0
- package/src/domain/whatif/whatif.test.ts +135 -0
- package/src/e2e/gaps-e2e.test.ts +259 -0
- package/src/e2e/smoke.test.ts +101 -0
- package/src/hooks/hooks-export.test.ts +81 -0
- package/src/hooks/installer.ts +113 -0
- package/src/http/cors.test.ts +38 -0
- package/src/http/create-router.ts +259 -0
- package/src/http/routes/agent.route.ts +380 -0
- package/src/http/routes/audit.route.ts +66 -0
- package/src/http/routes/badge.route.ts +23 -0
- package/src/http/routes/cert.route.ts +66 -0
- package/src/http/routes/chat.route.ts +228 -0
- package/src/http/routes/cost.route.ts +33 -0
- package/src/http/routes/debt.route.ts +29 -0
- package/src/http/routes/disclaimer.route.ts +64 -0
- package/src/http/routes/eval.route.ts +161 -0
- package/src/http/routes/events.route.test.ts +108 -0
- package/src/http/routes/events.route.ts +71 -0
- package/src/http/routes/external-scan.route.ts +24 -0
- package/src/http/routes/file.route.ts +54 -0
- package/src/http/routes/fix.route.ts +219 -0
- package/src/http/routes/frameworks.route.test.ts +66 -0
- package/src/http/routes/frameworks.route.ts +36 -0
- package/src/http/routes/git.route.ts +27 -0
- package/src/http/routes/guided-onboarding.route.ts +65 -0
- package/src/http/routes/import.route.ts +64 -0
- package/src/http/routes/jurisdiction.route.ts +22 -0
- package/src/http/routes/obligations.route.test.ts +122 -0
- package/src/http/routes/obligations.route.ts +110 -0
- package/src/http/routes/onboarding.route.ts +53 -0
- package/src/http/routes/provider.route.ts +42 -0
- package/src/http/routes/proxy.route.ts +40 -0
- package/src/http/routes/redteam.route.ts +84 -0
- package/src/http/routes/report.route.ts +29 -0
- package/src/http/routes/scan.route.ts +104 -0
- package/src/http/routes/share.route.ts +44 -0
- package/src/http/routes/shell.route.ts +27 -0
- package/src/http/routes/status.route.ts +66 -0
- package/src/http/routes/supply-chain.route.ts +121 -0
- package/src/http/routes/sync.route.ts +328 -0
- package/src/http/routes/tools.route.ts +29 -0
- package/src/http/routes/whatif.route.ts +96 -0
- package/src/http/utils/validation.ts +31 -0
- package/src/index.ts +1 -0
- package/src/infra/bundle-fetcher.ts +77 -0
- package/src/infra/cache-storage.ts +34 -0
- package/src/infra/event-bus.ts +31 -0
- package/src/infra/file-collector.ts +61 -0
- package/src/infra/file-ops-adapter.ts +95 -0
- package/src/infra/file-watcher.test.ts +90 -0
- package/src/infra/file-watcher.ts +106 -0
- package/src/infra/git-adapter.ts +93 -0
- package/src/infra/git-history-adapter.ts +41 -0
- package/src/infra/headless-browser.ts +178 -0
- package/src/infra/llm-adapter.test.ts +83 -0
- package/src/infra/llm-adapter.ts +86 -0
- package/src/infra/logger.ts +27 -0
- package/src/infra/project-config.test.ts +74 -0
- package/src/infra/project-config.ts +35 -0
- package/src/infra/rate-limiter.test.ts +36 -0
- package/src/infra/rate-limiter.ts +34 -0
- package/src/infra/retry.ts +46 -0
- package/src/infra/saas-client.ts +123 -0
- package/src/infra/search-adapter.ts +113 -0
- package/src/infra/shell-adapter.ts +68 -0
- package/src/infra/tool-manager.test.ts +99 -0
- package/src/infra/tool-manager.ts +197 -0
- package/src/llm/agents/agent-modes.test.ts +44 -0
- package/src/llm/agents/modes.ts +68 -0
- package/src/llm/routing/cost-routing.test.ts +37 -0
- package/src/llm/routing/cost-tracker.ts +74 -0
- package/src/llm/routing/model-routing.test.ts +79 -0
- package/src/llm/routing/model-routing.ts +38 -0
- package/src/llm/routing/pricing.ts +19 -0
- package/src/llm/sse-protocol.ts +77 -0
- package/src/llm/tool-definitions.ts +83 -0
- package/src/llm/tool-executors.ts +80 -0
- package/src/llm/tools/types.ts +13 -0
- package/src/mcp/create-mcp-stack.ts +82 -0
- package/src/mcp/handlers.ts +245 -0
- package/src/mcp/index.ts +28 -0
- package/src/mcp/mcp-server.test.ts +80 -0
- package/src/mcp/server.ts +79 -0
- package/src/mcp/tools.ts +48 -0
- package/src/onboarding/auto-detect.ts +164 -0
- package/src/onboarding/onboarding.test.ts +89 -0
- package/src/onboarding/profile.ts +169 -0
- package/src/onboarding/questions.ts +112 -0
- package/src/onboarding/wizard.ts +66 -0
- package/src/output/github-issue.ts +32 -0
- package/src/output/json-output.ts +67 -0
- package/src/ports/browser.port.ts +23 -0
- package/src/ports/events.port.ts +28 -0
- package/src/ports/llm.port.ts +23 -0
- package/src/ports/logger.port.ts +6 -0
- package/src/ports/process.port.ts +6 -0
- package/src/ports/scanner.port.ts +15 -0
- package/src/server.ts +134 -0
- package/src/services/badge-service.ts +67 -0
- package/src/services/chat-service.test.ts +162 -0
- package/src/services/chat-service.ts +152 -0
- package/src/services/cost-service.ts +52 -0
- package/src/services/debt-service.ts +65 -0
- package/src/services/eval-integration.test.ts +132 -0
- package/src/services/eval-service.test.ts +373 -0
- package/src/services/eval-service.ts +463 -0
- package/src/services/external-scan-service.ts +60 -0
- package/src/services/file-service.ts +37 -0
- package/src/services/fix-service.test.ts +470 -0
- package/src/services/fix-service.ts +648 -0
- package/src/services/framework-service.test.ts +159 -0
- package/src/services/framework-service.ts +67 -0
- package/src/services/onboarding-service.ts +165 -0
- package/src/services/passport-audit.ts +244 -0
- package/src/services/passport-documents.ts +258 -0
- package/src/services/passport-service-utils.ts +72 -0
- package/src/services/passport-service.test.ts +251 -0
- package/src/services/passport-service.ts +339 -0
- package/src/services/proxy-service.ts +81 -0
- package/src/services/report-service.ts +72 -0
- package/src/services/scan-service.test.ts +470 -0
- package/src/services/scan-service.ts +335 -0
- package/src/services/share-service.ts +108 -0
- package/src/services/shared/backup.ts +23 -0
- package/src/services/status-service.ts +38 -0
- package/src/services/undo-service.test.ts +190 -0
- package/src/services/undo-service.ts +144 -0
- package/src/test-helpers/factories.ts +116 -0
- package/src/types/common.schemas.ts +147 -0
- package/src/types/common.types.ts +292 -0
- package/src/types/contract.test.ts +217 -0
- package/src/types/errors.ts +52 -0
- package/src/types/framework.types.ts +87 -0
- package/src/types/passport-schemas.ts +241 -0
- package/src/types/passport.types.ts +296 -0
- package/src/version.ts +1 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
|
|
4
|
+
export const disclosureStrategy: FixStrategy = (finding, context) => {
|
|
5
|
+
if (finding.checkId !== 'ai-disclosure') return null;
|
|
6
|
+
|
|
7
|
+
const fw = context.framework.toLowerCase();
|
|
8
|
+
|
|
9
|
+
if (fw.includes('next') || fw.includes('react')) {
|
|
10
|
+
const componentPath = 'src/components/AIDisclosure.tsx';
|
|
11
|
+
const content = `export const AIDisclosure = () => (
|
|
12
|
+
<div role="status" aria-label="AI Disclosure" className="ai-disclosure">
|
|
13
|
+
<p>This service uses artificial intelligence. Responses are AI-generated and may contain errors.</p>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
`;
|
|
17
|
+
const action: FixAction = {
|
|
18
|
+
type: 'create',
|
|
19
|
+
path: componentPath,
|
|
20
|
+
content,
|
|
21
|
+
description: 'Create AIDisclosure React component',
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-015',
|
|
25
|
+
checkId: finding.checkId,
|
|
26
|
+
article: finding.articleReference ?? 'Art. 50(1)',
|
|
27
|
+
fixType: 'code_injection',
|
|
28
|
+
framework: context.framework,
|
|
29
|
+
actions: [action],
|
|
30
|
+
diff: generateCreateDiff(componentPath, content),
|
|
31
|
+
scoreImpact: 7,
|
|
32
|
+
commitMessage: 'fix: add AI disclosure component (Art. 50.1) -- via Complior',
|
|
33
|
+
description: 'Add visible AI disclosure notice for users interacting with AI system',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Express / Fastify / Hono / generic server
|
|
38
|
+
const middlewarePath = 'src/middleware/ai-disclosure.ts';
|
|
39
|
+
const content = `// AI Disclosure Middleware (EU AI Act, Art. 50.1)
|
|
40
|
+
// Adds transparency headers to all AI-related responses
|
|
41
|
+
|
|
42
|
+
export const aiDisclosureMiddleware = (req: unknown, res: { setHeader: (k: string, v: string) => void }, next: () => void) => {
|
|
43
|
+
res.setHeader('X-AI-Disclosure', 'This service uses artificial intelligence');
|
|
44
|
+
res.setHeader('X-AI-Provider', 'See /api/ai-disclosure for details');
|
|
45
|
+
next();
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const AI_DISCLOSURE_TEXT = 'This service uses artificial intelligence. Responses are AI-generated and may contain errors.';
|
|
49
|
+
`;
|
|
50
|
+
const action: FixAction = {
|
|
51
|
+
type: 'create',
|
|
52
|
+
path: middlewarePath,
|
|
53
|
+
content,
|
|
54
|
+
description: 'Create AI disclosure middleware with transparency headers',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-015',
|
|
59
|
+
checkId: finding.checkId,
|
|
60
|
+
article: finding.articleReference ?? 'Art. 50(1)',
|
|
61
|
+
fixType: 'code_injection',
|
|
62
|
+
framework: context.framework,
|
|
63
|
+
actions: [action],
|
|
64
|
+
diff: generateCreateDiff(middlewarePath, content),
|
|
65
|
+
scoreImpact: 7,
|
|
66
|
+
commitMessage: 'fix: add AI disclosure middleware (Art. 50.1) -- via Complior',
|
|
67
|
+
description: 'Add AI disclosure middleware with transparency headers',
|
|
68
|
+
};
|
|
69
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
import { ENGINE_VERSION } from '../../../version.js';
|
|
4
|
+
|
|
5
|
+
// --- Strategy: Doc-Code Sync (Art. 11) ---
|
|
6
|
+
|
|
7
|
+
export const docCodeSyncStrategy: FixStrategy = (finding, context) => {
|
|
8
|
+
if (finding.checkId !== 'cross-doc-code-mismatch') return null;
|
|
9
|
+
|
|
10
|
+
const filePath = 'complior-doc-sync-report.md';
|
|
11
|
+
const content = `# Documentation-Code Sync Report
|
|
12
|
+
|
|
13
|
+
Generated by Complior v${ENGINE_VERSION}
|
|
14
|
+
|
|
15
|
+
## Mismatch Detected
|
|
16
|
+
|
|
17
|
+
${finding.message || 'Documentation does not match the current codebase implementation.'}
|
|
18
|
+
|
|
19
|
+
## Checklist
|
|
20
|
+
|
|
21
|
+
- [ ] Review flagged documentation sections
|
|
22
|
+
- [ ] Update technical documentation to match current implementation
|
|
23
|
+
- [ ] Verify API documentation reflects actual endpoints and parameters
|
|
24
|
+
- [ ] Check that architecture diagrams are up to date
|
|
25
|
+
- [ ] Run \`complior scan\` to verify documentation coverage
|
|
26
|
+
|
|
27
|
+
## Auto-generate Missing Docs
|
|
28
|
+
|
|
29
|
+
\`\`\`bash
|
|
30
|
+
complior docs generate --missing
|
|
31
|
+
\`\`\`
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
const action: FixAction = {
|
|
35
|
+
type: 'create',
|
|
36
|
+
path: filePath,
|
|
37
|
+
content,
|
|
38
|
+
description: 'Create documentation-code sync report',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-005',
|
|
43
|
+
checkId: finding.checkId,
|
|
44
|
+
article: finding.articleReference ?? 'Art. 11',
|
|
45
|
+
fixType: 'template_generation',
|
|
46
|
+
framework: context.framework,
|
|
47
|
+
actions: [action],
|
|
48
|
+
diff: generateCreateDiff(filePath, content),
|
|
49
|
+
scoreImpact: 5,
|
|
50
|
+
commitMessage: 'fix: add doc-code sync report (Art. 11) -- via Complior',
|
|
51
|
+
description: 'Create report documenting mismatches between code and documentation',
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction, TemplateMapping } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
import { TEMPLATE_REGISTRY } from '../../../data/template-registry.js';
|
|
4
|
+
|
|
5
|
+
// --- Template mapping: derived from TEMPLATE_REGISTRY (single source of truth) ---
|
|
6
|
+
|
|
7
|
+
const TEMPLATE_MAP: readonly TemplateMapping[] = TEMPLATE_REGISTRY.map((e) => ({
|
|
8
|
+
obligationId: e.obligationId,
|
|
9
|
+
article: e.article,
|
|
10
|
+
templateFile: e.templateFile,
|
|
11
|
+
outputFile: e.outputFile,
|
|
12
|
+
description: e.description,
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
/** CheckIds for which the documentation strategy should generate template fixes. */
|
|
16
|
+
const DOCUMENT_CHECK_IDS = new Set(
|
|
17
|
+
TEMPLATE_REGISTRY.map((e) => e.docType)
|
|
18
|
+
.concat(TEMPLATE_REGISTRY.map((e) => `l2-${e.docType}`))
|
|
19
|
+
.concat(['ai-literacy', 'l2-ai-literacy', 'gpai-transparency', 'gpai-systemic-risk']),
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export const documentationStrategy: FixStrategy = (finding, context) => {
|
|
23
|
+
// Only generate documents for document-presence checks, not permission/pattern checks
|
|
24
|
+
if (!DOCUMENT_CHECK_IDS.has(finding.checkId)) return null;
|
|
25
|
+
|
|
26
|
+
const oblId = finding.obligationId;
|
|
27
|
+
if (!oblId) return null;
|
|
28
|
+
|
|
29
|
+
const mapping = TEMPLATE_MAP.find((m) => m.obligationId === oblId);
|
|
30
|
+
if (!mapping) return null;
|
|
31
|
+
|
|
32
|
+
// For L1 (presence) findings: skip if file already exists
|
|
33
|
+
// For L2 (structure/quality) findings: only fix scaffold/none — never overwrite draft/reviewed docs
|
|
34
|
+
const isL2 = finding.checkId.startsWith('l2-');
|
|
35
|
+
if (isL2 && !context.useAi && (finding.docQuality === 'draft' || finding.docQuality === 'reviewed')) return null;
|
|
36
|
+
if (!isL2 && context.existingFiles.some((f) => f.endsWith(mapping.outputFile))) return null;
|
|
37
|
+
|
|
38
|
+
const action: FixAction = {
|
|
39
|
+
type: 'create',
|
|
40
|
+
path: mapping.outputFile,
|
|
41
|
+
content: `[TEMPLATE:${mapping.templateFile}]`,
|
|
42
|
+
description: `Generate ${mapping.description} from template`,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
obligationId: oblId,
|
|
47
|
+
checkId: finding.checkId,
|
|
48
|
+
article: mapping.article,
|
|
49
|
+
fixType: isL2 && context.useAi ? 'ai_enrichment' : 'template_generation',
|
|
50
|
+
framework: context.framework,
|
|
51
|
+
actions: [action],
|
|
52
|
+
diff: generateCreateDiff(mapping.outputFile, `# ${mapping.description}\n\n[Generated from template: ${mapping.templateFile}]`),
|
|
53
|
+
scoreImpact: 8,
|
|
54
|
+
commitMessage: `fix: generate ${mapping.description} (${mapping.article}) -- via Complior`,
|
|
55
|
+
description: `Generate ${mapping.description} from compliance template`,
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const getTemplateMap = (): readonly TemplateMapping[] => TEMPLATE_MAP;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
|
|
4
|
+
export const errorHandlerStrategy: FixStrategy = (finding, context) => {
|
|
5
|
+
if (finding.checkId !== 'l4-security-risk' && finding.checkId !== 'l4-ast-missing-error-handling') return null;
|
|
6
|
+
|
|
7
|
+
const filePath = 'src/middleware/ai-error-handler.ts';
|
|
8
|
+
const content = `// AI Error Handler (EU AI Act, Art. 15.4)
|
|
9
|
+
// Compliance-aware error handling for AI operations
|
|
10
|
+
|
|
11
|
+
export interface AIErrorLog {
|
|
12
|
+
readonly timestamp: string;
|
|
13
|
+
readonly operation: string;
|
|
14
|
+
readonly error: string;
|
|
15
|
+
readonly severity: 'low' | 'medium' | 'high' | 'critical';
|
|
16
|
+
readonly aiSystemId?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const errorLog: AIErrorLog[] = [];
|
|
20
|
+
|
|
21
|
+
export const withAIErrorHandling = async <T>(
|
|
22
|
+
operation: string,
|
|
23
|
+
fn: () => Promise<T>,
|
|
24
|
+
fallback: T,
|
|
25
|
+
): Promise<T> => {
|
|
26
|
+
try {
|
|
27
|
+
return await fn();
|
|
28
|
+
} catch (err) {
|
|
29
|
+
const entry: AIErrorLog = {
|
|
30
|
+
timestamp: new Date().toISOString(),
|
|
31
|
+
operation,
|
|
32
|
+
error: err instanceof Error ? err.message : String(err),
|
|
33
|
+
severity: 'high',
|
|
34
|
+
};
|
|
35
|
+
errorLog.push(entry);
|
|
36
|
+
console.error(\`[AI-ERROR] \${operation}: \${entry.error}\`);
|
|
37
|
+
return fallback;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const getErrorLog = (): readonly AIErrorLog[] => [...errorLog];
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
const action: FixAction = {
|
|
45
|
+
type: 'create',
|
|
46
|
+
path: filePath,
|
|
47
|
+
content,
|
|
48
|
+
description: 'Create AI error handler with compliance logging',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-008',
|
|
53
|
+
checkId: finding.checkId,
|
|
54
|
+
article: finding.articleReference ?? 'Art. 15(4)',
|
|
55
|
+
fixType: 'code_injection',
|
|
56
|
+
framework: context.framework,
|
|
57
|
+
actions: [action],
|
|
58
|
+
diff: generateCreateDiff(filePath, content),
|
|
59
|
+
scoreImpact: 4,
|
|
60
|
+
commitMessage: 'fix: add AI error handler (Art. 15.4) -- via Complior',
|
|
61
|
+
description: 'Add compliance-aware error handling with incident logging',
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
|
|
4
|
+
// --- Strategy: HITL Gate / Conformity Assessment (Art. 19) ---
|
|
5
|
+
|
|
6
|
+
export const hitlGateStrategy: FixStrategy = (finding, context) => {
|
|
7
|
+
if (finding.checkId !== 'l4-conformity-assessment') return null;
|
|
8
|
+
|
|
9
|
+
const filePath = 'src/compliance/conformity-checklist.ts';
|
|
10
|
+
const content = `// Conformity Assessment Checklist (EU AI Act, Art. 19)
|
|
11
|
+
// Pre-deployment verification for high-risk AI systems
|
|
12
|
+
|
|
13
|
+
export type ConformityStatus = 'pending' | 'passed' | 'failed' | 'waived';
|
|
14
|
+
|
|
15
|
+
export interface ChecklistItem {
|
|
16
|
+
readonly id: string;
|
|
17
|
+
readonly category: string;
|
|
18
|
+
readonly requirement: string;
|
|
19
|
+
status: ConformityStatus;
|
|
20
|
+
signedOffBy?: string;
|
|
21
|
+
signedOffAt?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const CONFORMITY_CHECKLIST: ChecklistItem[] = [
|
|
25
|
+
{ id: 'CA-01', category: 'Risk Assessment', requirement: 'Risk management system established (Art. 9)', status: 'pending' },
|
|
26
|
+
{ id: 'CA-02', category: 'Data Governance', requirement: 'Training data quality verified (Art. 10)', status: 'pending' },
|
|
27
|
+
{ id: 'CA-03', category: 'Documentation', requirement: 'Technical documentation complete (Art. 11)', status: 'pending' },
|
|
28
|
+
{ id: 'CA-04', category: 'Logging', requirement: 'Automatic logging enabled (Art. 12)', status: 'pending' },
|
|
29
|
+
{ id: 'CA-05', category: 'Transparency', requirement: 'User instructions provided (Art. 13)', status: 'pending' },
|
|
30
|
+
{ id: 'CA-06', category: 'Human Oversight', requirement: 'Human oversight measures in place (Art. 14)', status: 'pending' },
|
|
31
|
+
{ id: 'CA-07', category: 'Accuracy', requirement: 'Accuracy and robustness tested (Art. 15)', status: 'pending' },
|
|
32
|
+
{ id: 'CA-08', category: 'Sign-off', requirement: 'Authorized representative sign-off', status: 'pending' },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
export const signOff = (id: string, by: string): boolean => {
|
|
36
|
+
const item = CONFORMITY_CHECKLIST.find((c) => c.id === id);
|
|
37
|
+
if (!item) return false;
|
|
38
|
+
item.status = 'passed';
|
|
39
|
+
item.signedOffBy = by;
|
|
40
|
+
item.signedOffAt = new Date().toISOString();
|
|
41
|
+
return true;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const isConformityComplete = (): boolean =>
|
|
45
|
+
CONFORMITY_CHECKLIST.every((c) => c.status === 'passed' || c.status === 'waived');
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
const action: FixAction = {
|
|
49
|
+
type: 'create',
|
|
50
|
+
path: filePath,
|
|
51
|
+
content,
|
|
52
|
+
description: 'Create conformity assessment checklist for pre-deployment verification',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-011',
|
|
57
|
+
checkId: finding.checkId,
|
|
58
|
+
article: finding.articleReference ?? 'Art. 19',
|
|
59
|
+
fixType: 'code_injection',
|
|
60
|
+
framework: context.framework,
|
|
61
|
+
actions: [action],
|
|
62
|
+
diff: generateCreateDiff(filePath, content),
|
|
63
|
+
scoreImpact: 5,
|
|
64
|
+
commitMessage: 'fix: add conformity assessment checklist (Art. 19) -- via Complior',
|
|
65
|
+
description: 'Add pre-deployment conformity assessment checklist for high-risk AI systems',
|
|
66
|
+
};
|
|
67
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strategy registry — chain-of-responsibility pattern.
|
|
3
|
+
* Order matters: specific strategies first, documentationStrategy as catch-all last.
|
|
4
|
+
*/
|
|
5
|
+
import type { Finding } from '../../../types/common.types.js';
|
|
6
|
+
import type { FixContext, FixPlan } from '../types.js';
|
|
7
|
+
|
|
8
|
+
import { permissionGuardStrategy } from './permission-guard.js';
|
|
9
|
+
import { killSwitchStrategy } from './kill-switch.js';
|
|
10
|
+
import { killSwitchTestStrategy } from './kill-switch-test.js';
|
|
11
|
+
import { errorHandlerStrategy } from './error-handler.js';
|
|
12
|
+
import { hitlGateStrategy } from './hitl-gate.js';
|
|
13
|
+
import { dataGovernanceStrategy } from './data-governance.js';
|
|
14
|
+
import { secretRotationStrategy } from './secret-rotation.js';
|
|
15
|
+
import { banditFixStrategy } from './bandit-fix.js';
|
|
16
|
+
import { cveUpgradeStrategy } from './cve-upgrade.js';
|
|
17
|
+
import { licenseFixStrategy } from './license-fix.js';
|
|
18
|
+
import { ciComplianceStrategy } from './ci-compliance.js';
|
|
19
|
+
import { biasTestingStrategy } from './bias-testing.js';
|
|
20
|
+
import { docCodeSyncStrategy } from './doc-code-sync.js';
|
|
21
|
+
import { disclosureStrategy } from './disclosure.js';
|
|
22
|
+
import { contentMarkingStrategy } from './content-marking.js';
|
|
23
|
+
import { loggingStrategy } from './logging.js';
|
|
24
|
+
import { metadataStrategy } from './metadata.js';
|
|
25
|
+
import { recordKeepingStrategy } from './record-keeping.js';
|
|
26
|
+
import { logRetentionStrategy } from './log-retention.js';
|
|
27
|
+
import { documentationStrategy, getTemplateMap } from './documentation.js';
|
|
28
|
+
|
|
29
|
+
// NOTE: friaStrategy removed — documentationStrategy handles OBL-013 via template-registry
|
|
30
|
+
const STRATEGIES = [
|
|
31
|
+
permissionGuardStrategy,
|
|
32
|
+
killSwitchStrategy,
|
|
33
|
+
killSwitchTestStrategy,
|
|
34
|
+
errorHandlerStrategy,
|
|
35
|
+
hitlGateStrategy,
|
|
36
|
+
dataGovernanceStrategy,
|
|
37
|
+
secretRotationStrategy,
|
|
38
|
+
banditFixStrategy,
|
|
39
|
+
cveUpgradeStrategy,
|
|
40
|
+
licenseFixStrategy,
|
|
41
|
+
ciComplianceStrategy,
|
|
42
|
+
biasTestingStrategy,
|
|
43
|
+
docCodeSyncStrategy,
|
|
44
|
+
disclosureStrategy,
|
|
45
|
+
contentMarkingStrategy,
|
|
46
|
+
loggingStrategy,
|
|
47
|
+
recordKeepingStrategy,
|
|
48
|
+
logRetentionStrategy,
|
|
49
|
+
metadataStrategy,
|
|
50
|
+
documentationStrategy, // catch-all for obligation-based template fixes (incl. FRIA)
|
|
51
|
+
] as const;
|
|
52
|
+
|
|
53
|
+
export const findStrategy = (finding: Finding, context: FixContext): FixPlan | null => {
|
|
54
|
+
for (const strategy of STRATEGIES) {
|
|
55
|
+
const plan = strategy(finding, context);
|
|
56
|
+
if (plan !== null) return plan;
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export { getTemplateMap };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
|
|
4
|
+
export const killSwitchTestStrategy: FixStrategy = (finding, context) => {
|
|
5
|
+
if (finding.checkId !== 'cross-kill-switch-no-test') return null;
|
|
6
|
+
|
|
7
|
+
const testPath = 'src/safety/kill-switch.test.ts';
|
|
8
|
+
const content = `// Kill Switch Tests (EU AI Act, Art. 14)
|
|
9
|
+
// Verifies emergency shutdown capability for AI system
|
|
10
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
11
|
+
import { isAiEnabled, emergencyShutdown, restoreService, withKillSwitch } from './kill-switch';
|
|
12
|
+
|
|
13
|
+
const ENV_KEY = 'AI_KILL_SWITCH';
|
|
14
|
+
|
|
15
|
+
describe('Kill Switch (Art. 14)', () => {
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
delete process.env[ENV_KEY];
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('isAiEnabled', () => {
|
|
21
|
+
it('returns true when env var is not set', () => {
|
|
22
|
+
expect(isAiEnabled()).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('returns false when env var is "1"', () => {
|
|
26
|
+
process.env[ENV_KEY] = '1';
|
|
27
|
+
expect(isAiEnabled()).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('returns false when env var is "true"', () => {
|
|
31
|
+
process.env[ENV_KEY] = 'true';
|
|
32
|
+
expect(isAiEnabled()).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('emergencyShutdown', () => {
|
|
37
|
+
it('disables AI system', () => {
|
|
38
|
+
emergencyShutdown('safety concern');
|
|
39
|
+
expect(isAiEnabled()).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('restoreService', () => {
|
|
44
|
+
it('re-enables AI system after shutdown', () => {
|
|
45
|
+
emergencyShutdown('test');
|
|
46
|
+
restoreService();
|
|
47
|
+
expect(isAiEnabled()).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('withKillSwitch', () => {
|
|
52
|
+
it('executes fn when AI is enabled', () => {
|
|
53
|
+
const result = withKillSwitch(() => 42, 0);
|
|
54
|
+
expect(result).toBe(42);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('returns fallback when AI is disabled', () => {
|
|
58
|
+
emergencyShutdown('test');
|
|
59
|
+
const result = withKillSwitch(() => 42, 0);
|
|
60
|
+
expect(result).toBe(0);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
`;
|
|
65
|
+
|
|
66
|
+
const action: FixAction = {
|
|
67
|
+
type: 'create',
|
|
68
|
+
path: testPath,
|
|
69
|
+
content,
|
|
70
|
+
description: 'Create kill-switch test suite for safety verification',
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-010',
|
|
75
|
+
checkId: finding.checkId,
|
|
76
|
+
article: finding.articleReference ?? 'Art. 14',
|
|
77
|
+
fixType: 'code_injection',
|
|
78
|
+
framework: context.framework,
|
|
79
|
+
actions: [action],
|
|
80
|
+
diff: generateCreateDiff(testPath, content),
|
|
81
|
+
scoreImpact: 4,
|
|
82
|
+
commitMessage: 'fix: add kill-switch tests (Art. 14) -- via Complior',
|
|
83
|
+
description: 'Add automated tests for AI kill switch safety mechanism',
|
|
84
|
+
};
|
|
85
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
|
|
4
|
+
export const killSwitchStrategy: FixStrategy = (finding, context) => {
|
|
5
|
+
if (finding.checkId !== 'l4-kill-switch') return null;
|
|
6
|
+
|
|
7
|
+
const filePath = 'src/safety/kill-switch.ts';
|
|
8
|
+
const content = `// AI Kill Switch (EU AI Act, Art. 14.4)
|
|
9
|
+
// Emergency shutdown capability for AI system
|
|
10
|
+
|
|
11
|
+
const AI_KILL_SWITCH_ENV = 'AI_KILL_SWITCH';
|
|
12
|
+
|
|
13
|
+
export const isAiEnabled = (): boolean => {
|
|
14
|
+
const val = process.env[AI_KILL_SWITCH_ENV];
|
|
15
|
+
return val !== '1' && val !== 'true';
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const emergencyShutdown = (reason: string): void => {
|
|
19
|
+
process.env[AI_KILL_SWITCH_ENV] = '1';
|
|
20
|
+
console.error(\`[KILL-SWITCH] AI system disabled: \${reason}\`);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const restoreService = (): void => {
|
|
24
|
+
delete process.env[AI_KILL_SWITCH_ENV];
|
|
25
|
+
console.info('[KILL-SWITCH] AI system re-enabled');
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const withKillSwitch = <T>(fn: () => T, fallback: T): T => {
|
|
29
|
+
if (!isAiEnabled()) return fallback;
|
|
30
|
+
return fn();
|
|
31
|
+
};
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
const action: FixAction = {
|
|
35
|
+
type: 'create',
|
|
36
|
+
path: filePath,
|
|
37
|
+
content,
|
|
38
|
+
description: 'Create AI kill switch for emergency shutdown',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-006',
|
|
43
|
+
checkId: finding.checkId,
|
|
44
|
+
article: finding.articleReference ?? 'Art. 14(4)',
|
|
45
|
+
fixType: 'code_injection',
|
|
46
|
+
framework: context.framework,
|
|
47
|
+
actions: [action],
|
|
48
|
+
diff: generateCreateDiff(filePath, content),
|
|
49
|
+
scoreImpact: 5,
|
|
50
|
+
commitMessage: 'fix: add AI kill switch (Art. 14.4) -- via Complior',
|
|
51
|
+
description: 'Add emergency kill switch to disable AI system immediately',
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
import { ENGINE_VERSION } from '../../../version.js';
|
|
4
|
+
|
|
5
|
+
// --- Strategy: License Fix (Art. 5) ---
|
|
6
|
+
|
|
7
|
+
export const licenseFixStrategy: FixStrategy = (finding, context) => {
|
|
8
|
+
if (finding.checkId !== 'l3-dep-license') return null;
|
|
9
|
+
|
|
10
|
+
const filePath = 'complior-license-review.md';
|
|
11
|
+
const content = `# License Compliance Review
|
|
12
|
+
|
|
13
|
+
Generated by Complior v${ENGINE_VERSION}
|
|
14
|
+
|
|
15
|
+
## Issue
|
|
16
|
+
|
|
17
|
+
${finding.message || 'Dependency with incompatible or problematic license detected.'}
|
|
18
|
+
|
|
19
|
+
## License Compatibility Matrix
|
|
20
|
+
|
|
21
|
+
| License | Commercial Use | Modification | Distribution | Patent Grant |
|
|
22
|
+
|---------|---------------|-------------|-------------|-------------|
|
|
23
|
+
| MIT | Yes | Yes | Yes | No |
|
|
24
|
+
| Apache-2.0 | Yes | Yes | Yes | Yes |
|
|
25
|
+
| GPL-3.0 | Copyleft | Copyleft | Copyleft | Yes |
|
|
26
|
+
| AGPL-3.0 | Copyleft | Copyleft | Copyleft (network) | Yes |
|
|
27
|
+
| SSPL | Restricted | Copyleft | Copyleft | No |
|
|
28
|
+
|
|
29
|
+
## Action Items
|
|
30
|
+
|
|
31
|
+
- [ ] Identify the problematic dependency and its license
|
|
32
|
+
- [ ] Search for an alternative package with a compatible license
|
|
33
|
+
- [ ] Run \`npx license-checker\` or \`pip-licenses\` for a full audit
|
|
34
|
+
- [ ] Update dependency and verify license compatibility
|
|
35
|
+
- [ ] Document license decision in compliance records
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
const action: FixAction = {
|
|
39
|
+
type: 'create',
|
|
40
|
+
path: filePath,
|
|
41
|
+
content,
|
|
42
|
+
description: 'Create license compliance review document',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-002',
|
|
47
|
+
checkId: finding.checkId,
|
|
48
|
+
article: finding.articleReference ?? 'Art. 5',
|
|
49
|
+
fixType: 'dependency_fix',
|
|
50
|
+
framework: context.framework,
|
|
51
|
+
actions: [action],
|
|
52
|
+
diff: generateCreateDiff(filePath, content),
|
|
53
|
+
scoreImpact: 4,
|
|
54
|
+
commitMessage: 'fix: add license compliance review (Art. 5) -- via Complior',
|
|
55
|
+
description: 'Create license review document for dependency with problematic license',
|
|
56
|
+
};
|
|
57
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
|
|
4
|
+
export const logRetentionStrategy: FixStrategy = (finding, context) => {
|
|
5
|
+
if (finding.checkId !== 'cross-logging-no-retention') return null;
|
|
6
|
+
|
|
7
|
+
const composePath = 'docker-compose.override.yml';
|
|
8
|
+
const content = `# Docker Compose Override — Log Retention (EU AI Act, Art. 12)
|
|
9
|
+
# Generated by Complior: ensures container logs are retained >= 180 days.
|
|
10
|
+
# Merge with your main docker-compose.yml via "docker compose up".
|
|
11
|
+
|
|
12
|
+
services:
|
|
13
|
+
app:
|
|
14
|
+
logging:
|
|
15
|
+
driver: json-file
|
|
16
|
+
options:
|
|
17
|
+
max-size: "50m"
|
|
18
|
+
max-file: "60"
|
|
19
|
+
tag: "{{.Name}}/{{.ID}}"
|
|
20
|
+
`;
|
|
21
|
+
const action: FixAction = {
|
|
22
|
+
type: 'create',
|
|
23
|
+
path: composePath,
|
|
24
|
+
content,
|
|
25
|
+
description: 'Create docker-compose.override.yml with log retention config',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-006',
|
|
30
|
+
checkId: finding.checkId,
|
|
31
|
+
article: finding.articleReference ?? 'Art. 12',
|
|
32
|
+
fixType: 'config_fix',
|
|
33
|
+
framework: context.framework,
|
|
34
|
+
actions: [action],
|
|
35
|
+
diff: generateCreateDiff(composePath, content),
|
|
36
|
+
scoreImpact: 4,
|
|
37
|
+
commitMessage: 'fix: add docker-compose log retention override (Art. 12) -- via Complior',
|
|
38
|
+
description: 'Add docker-compose.override.yml with logging retention config for Art. 12 compliance',
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { FixStrategy, FixAction } from '../types.js';
|
|
2
|
+
import { generateCreateDiff } from '../diff.js';
|
|
3
|
+
|
|
4
|
+
export const loggingStrategy: FixStrategy = (finding, context) => {
|
|
5
|
+
if (finding.checkId !== 'interaction-logging' && finding.checkId !== 'l4-logging') return null;
|
|
6
|
+
|
|
7
|
+
const loggerPath = 'src/logging/ai-interaction-logger.ts';
|
|
8
|
+
const content = `// AI Interaction Logger (EU AI Act, Art. 12)
|
|
9
|
+
// Automatic logging of AI system interactions for traceability
|
|
10
|
+
|
|
11
|
+
export interface AIInteractionLog {
|
|
12
|
+
readonly timestamp: string;
|
|
13
|
+
readonly sessionId: string;
|
|
14
|
+
readonly inputHash: string;
|
|
15
|
+
readonly outputHash: string;
|
|
16
|
+
readonly model: string;
|
|
17
|
+
readonly provider: string;
|
|
18
|
+
readonly durationMs: number;
|
|
19
|
+
readonly tokensUsed?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const auditLog: AIInteractionLog[] = [];
|
|
23
|
+
|
|
24
|
+
/** Log an AI interaction for compliance traceability (Art. 12). */
|
|
25
|
+
export const logAiCall = (entry: Omit<AIInteractionLog, 'timestamp'>): void => {
|
|
26
|
+
auditLog.push({ ...entry, timestamp: new Date().toISOString() });
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const aiLogger = {
|
|
30
|
+
log: logAiCall,
|
|
31
|
+
getAll: (): readonly AIInteractionLog[] => [...auditLog],
|
|
32
|
+
clear: (): void => { auditLog.length = 0; },
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Legacy aliases
|
|
36
|
+
export const logInteraction = logAiCall;
|
|
37
|
+
export const getInteractionLogs = aiLogger.getAll;
|
|
38
|
+
export const clearLogs = aiLogger.clear;
|
|
39
|
+
`;
|
|
40
|
+
const action: FixAction = {
|
|
41
|
+
type: 'create',
|
|
42
|
+
path: loggerPath,
|
|
43
|
+
content,
|
|
44
|
+
description: 'Create AI interaction logger for traceability',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
obligationId: finding.obligationId ?? 'eu-ai-act-OBL-007',
|
|
49
|
+
checkId: finding.checkId,
|
|
50
|
+
article: finding.articleReference ?? 'Art. 12',
|
|
51
|
+
fixType: 'code_injection',
|
|
52
|
+
framework: context.framework,
|
|
53
|
+
actions: [action],
|
|
54
|
+
diff: generateCreateDiff(loggerPath, content),
|
|
55
|
+
scoreImpact: 5,
|
|
56
|
+
commitMessage: 'fix: add AI interaction logger (Art. 12) -- via Complior',
|
|
57
|
+
description: 'Add automatic logging of AI system interactions for traceability',
|
|
58
|
+
};
|
|
59
|
+
};
|