@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,368 @@
|
|
|
1
|
+
/** Расширение EU AI Act assessment для LLM-моделей (pending SaaS adoption) */
|
|
2
|
+
export interface EuAiActModelAssessment {
|
|
3
|
+
readonly risk_level?: string;
|
|
4
|
+
readonly risk_reasoning?: string;
|
|
5
|
+
readonly applicable_obligation_ids?: readonly string[];
|
|
6
|
+
readonly confidence?: string;
|
|
7
|
+
// Расширения для LLM-моделей (нет в SaaS пока):
|
|
8
|
+
readonly training_cutoff?: string;
|
|
9
|
+
readonly license?: string;
|
|
10
|
+
readonly gpai_compliant?: boolean | null;
|
|
11
|
+
readonly eu_representative?: string | null;
|
|
12
|
+
readonly limitations?: readonly string[];
|
|
13
|
+
readonly known_risks?: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* CLI-представление карточки AI-системы из реестра.
|
|
18
|
+
* Структурно совместим с SaaS RegistryTool (PROJECT/frontend/lib/registry.ts).
|
|
19
|
+
* Опущены DB-поля: registryToolId, seo, active, createdAt, updatedAt.
|
|
20
|
+
*/
|
|
21
|
+
export interface RegistryToolCard {
|
|
22
|
+
readonly slug: string;
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly provider: { readonly name: string; readonly website?: string };
|
|
25
|
+
readonly description: string | null;
|
|
26
|
+
readonly category: string | null;
|
|
27
|
+
readonly riskLevel: string | null;
|
|
28
|
+
readonly aiActRole: string | null;
|
|
29
|
+
readonly level: 'classified' | 'scanned' | 'verified';
|
|
30
|
+
readonly assessments: {
|
|
31
|
+
readonly 'eu-ai-act'?: EuAiActModelAssessment;
|
|
32
|
+
} | null;
|
|
33
|
+
readonly detectionPatterns: {
|
|
34
|
+
readonly code?: Readonly<Record<string, string | readonly string[]>>;
|
|
35
|
+
} | null;
|
|
36
|
+
readonly evidence: readonly {
|
|
37
|
+
readonly date: string;
|
|
38
|
+
readonly title: string;
|
|
39
|
+
readonly type?: string;
|
|
40
|
+
}[] | null;
|
|
41
|
+
readonly capabilities: readonly string[] | null;
|
|
42
|
+
readonly jurisdictions: readonly string[] | null;
|
|
43
|
+
readonly vendorCountry: string | null;
|
|
44
|
+
readonly dataResidency: string | null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const REGISTRY_CARDS: readonly RegistryToolCard[] = Object.freeze([
|
|
48
|
+
{
|
|
49
|
+
slug: 'gpt-4o',
|
|
50
|
+
name: 'GPT-4o',
|
|
51
|
+
provider: { name: 'OpenAI', website: 'https://openai.com/policies' },
|
|
52
|
+
description: 'Multimodal GPT model with vision, text, and code capabilities',
|
|
53
|
+
category: 'api_platform',
|
|
54
|
+
riskLevel: 'gpai_systemic',
|
|
55
|
+
aiActRole: 'provider',
|
|
56
|
+
level: 'classified',
|
|
57
|
+
assessments: {
|
|
58
|
+
'eu-ai-act': {
|
|
59
|
+
risk_level: 'gpai_systemic',
|
|
60
|
+
risk_reasoning: 'GPAI model per Art.51. Systemic risk classification likely. No EU representative disclosed',
|
|
61
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
62
|
+
confidence: 'medium',
|
|
63
|
+
training_cutoff: '2024-10',
|
|
64
|
+
license: 'proprietary',
|
|
65
|
+
gpai_compliant: null,
|
|
66
|
+
eu_representative: null,
|
|
67
|
+
limitations: ['hallucination risk', 'no real-time data', 'context window limit'],
|
|
68
|
+
known_risks: ['bias in training data', 'prompt injection susceptibility', 'overconfident outputs'],
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
detectionPatterns: { code: { npm: ['openai'], pip: ['openai'] } },
|
|
72
|
+
evidence: null,
|
|
73
|
+
capabilities: ['text generation', 'code generation', 'multimodal (vision)', 'function calling', 'reasoning'],
|
|
74
|
+
jurisdictions: ['US'],
|
|
75
|
+
vendorCountry: 'US',
|
|
76
|
+
dataResidency: 'US',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
slug: 'gpt-4o-mini',
|
|
80
|
+
name: 'GPT-4o Mini',
|
|
81
|
+
provider: { name: 'OpenAI', website: 'https://openai.com/policies' },
|
|
82
|
+
description: 'Lightweight GPT model for cost-efficient text and code tasks',
|
|
83
|
+
category: 'api_platform',
|
|
84
|
+
riskLevel: 'gpai',
|
|
85
|
+
aiActRole: 'provider',
|
|
86
|
+
level: 'classified',
|
|
87
|
+
assessments: {
|
|
88
|
+
'eu-ai-act': {
|
|
89
|
+
risk_level: 'gpai',
|
|
90
|
+
risk_reasoning: 'GPAI model per Art.51. Below systemic risk threshold',
|
|
91
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
92
|
+
confidence: 'medium',
|
|
93
|
+
training_cutoff: '2024-10',
|
|
94
|
+
license: 'proprietary',
|
|
95
|
+
gpai_compliant: null,
|
|
96
|
+
eu_representative: null,
|
|
97
|
+
limitations: ['reduced reasoning vs GPT-4o', 'hallucination risk'],
|
|
98
|
+
known_risks: ['bias in training data', 'prompt injection susceptibility'],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
detectionPatterns: { code: { npm: ['openai'], pip: ['openai'] } },
|
|
102
|
+
evidence: null,
|
|
103
|
+
capabilities: ['text generation', 'code generation', 'function calling'],
|
|
104
|
+
jurisdictions: ['US'],
|
|
105
|
+
vendorCountry: 'US',
|
|
106
|
+
dataResidency: 'US',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
slug: 'o1',
|
|
110
|
+
name: 'OpenAI o1',
|
|
111
|
+
provider: { name: 'OpenAI', website: 'https://openai.com/policies' },
|
|
112
|
+
description: 'Advanced reasoning model with multi-step problem solving',
|
|
113
|
+
category: 'api_platform',
|
|
114
|
+
riskLevel: 'gpai_systemic',
|
|
115
|
+
aiActRole: 'provider',
|
|
116
|
+
level: 'classified',
|
|
117
|
+
assessments: {
|
|
118
|
+
'eu-ai-act': {
|
|
119
|
+
risk_level: 'gpai_systemic',
|
|
120
|
+
risk_reasoning: 'GPAI model per Art.51. Systemic risk due to advanced reasoning capabilities',
|
|
121
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
122
|
+
confidence: 'medium',
|
|
123
|
+
training_cutoff: '2024-10',
|
|
124
|
+
license: 'proprietary',
|
|
125
|
+
gpai_compliant: null,
|
|
126
|
+
eu_representative: null,
|
|
127
|
+
limitations: ['high latency', 'higher cost', 'no streaming in reasoning phase'],
|
|
128
|
+
known_risks: ['chain-of-thought manipulation', 'overconfident reasoning', 'training data bias'],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
detectionPatterns: { code: { npm: ['openai'], pip: ['openai'] } },
|
|
132
|
+
evidence: null,
|
|
133
|
+
capabilities: ['advanced reasoning', 'multi-step problem solving', 'code generation', 'math'],
|
|
134
|
+
jurisdictions: ['US'],
|
|
135
|
+
vendorCountry: 'US',
|
|
136
|
+
dataResidency: 'US',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
slug: 'claude-opus-4',
|
|
140
|
+
name: 'Claude Opus 4',
|
|
141
|
+
provider: { name: 'Anthropic', website: 'https://www.anthropic.com/policies' },
|
|
142
|
+
description: 'Frontier model with extended thinking and Constitutional AI alignment',
|
|
143
|
+
category: 'api_platform',
|
|
144
|
+
riskLevel: 'gpai_systemic',
|
|
145
|
+
aiActRole: 'provider',
|
|
146
|
+
level: 'classified',
|
|
147
|
+
assessments: {
|
|
148
|
+
'eu-ai-act': {
|
|
149
|
+
risk_level: 'gpai_systemic',
|
|
150
|
+
risk_reasoning: 'GPAI model per Art.51. Constitutional AI alignment approach. Systemic risk classification likely',
|
|
151
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
152
|
+
confidence: 'medium',
|
|
153
|
+
training_cutoff: '2025-03',
|
|
154
|
+
license: 'proprietary',
|
|
155
|
+
gpai_compliant: null,
|
|
156
|
+
eu_representative: null,
|
|
157
|
+
limitations: ['no real-time data', 'context window limit', 'no internet access'],
|
|
158
|
+
known_risks: ['hallucination risk', 'training data bias', 'sycophancy tendency'],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
detectionPatterns: { code: { npm: ['@anthropic-ai/sdk'], pip: ['anthropic'] } },
|
|
162
|
+
evidence: null,
|
|
163
|
+
capabilities: ['text generation', 'code generation', 'analysis', 'multimodal (vision)', 'extended thinking'],
|
|
164
|
+
jurisdictions: ['US'],
|
|
165
|
+
vendorCountry: 'US',
|
|
166
|
+
dataResidency: 'US',
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
slug: 'claude-sonnet-4',
|
|
170
|
+
name: 'Claude Sonnet 4',
|
|
171
|
+
provider: { name: 'Anthropic', website: 'https://www.anthropic.com/policies' },
|
|
172
|
+
description: 'Balanced model for text, code, and multimodal analysis',
|
|
173
|
+
category: 'api_platform',
|
|
174
|
+
riskLevel: 'gpai',
|
|
175
|
+
aiActRole: 'provider',
|
|
176
|
+
level: 'classified',
|
|
177
|
+
assessments: {
|
|
178
|
+
'eu-ai-act': {
|
|
179
|
+
risk_level: 'gpai',
|
|
180
|
+
risk_reasoning: 'GPAI model per Art.51. Below systemic risk threshold',
|
|
181
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
182
|
+
confidence: 'medium',
|
|
183
|
+
training_cutoff: '2025-03',
|
|
184
|
+
license: 'proprietary',
|
|
185
|
+
gpai_compliant: null,
|
|
186
|
+
eu_representative: null,
|
|
187
|
+
limitations: ['reduced capability vs Opus', 'no real-time data'],
|
|
188
|
+
known_risks: ['hallucination risk', 'training data bias'],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
detectionPatterns: { code: { npm: ['@anthropic-ai/sdk'], pip: ['anthropic'] } },
|
|
192
|
+
evidence: null,
|
|
193
|
+
capabilities: ['text generation', 'code generation', 'analysis', 'multimodal (vision)'],
|
|
194
|
+
jurisdictions: ['US'],
|
|
195
|
+
vendorCountry: 'US',
|
|
196
|
+
dataResidency: 'US',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
slug: 'gemini-2.0-flash',
|
|
200
|
+
name: 'Gemini 2.0 Flash',
|
|
201
|
+
provider: { name: 'Google', website: 'https://ai.google/responsibility/principles/' },
|
|
202
|
+
description: 'Fast multimodal model optimized for low-latency tasks',
|
|
203
|
+
category: 'api_platform',
|
|
204
|
+
riskLevel: 'gpai',
|
|
205
|
+
aiActRole: 'provider',
|
|
206
|
+
level: 'classified',
|
|
207
|
+
assessments: {
|
|
208
|
+
'eu-ai-act': {
|
|
209
|
+
risk_level: 'gpai',
|
|
210
|
+
risk_reasoning: 'GPAI model per Art.51. EU data residency option available',
|
|
211
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
212
|
+
confidence: 'medium',
|
|
213
|
+
training_cutoff: '2024-08',
|
|
214
|
+
license: 'proprietary',
|
|
215
|
+
gpai_compliant: null,
|
|
216
|
+
eu_representative: 'Google Ireland Limited',
|
|
217
|
+
limitations: ['lower accuracy on complex tasks', 'hallucination risk'],
|
|
218
|
+
known_risks: ['training data bias', 'geographic bias in knowledge'],
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
detectionPatterns: { code: { npm: ['@google/generative-ai'], pip: ['google-generativeai'] } },
|
|
222
|
+
evidence: null,
|
|
223
|
+
capabilities: ['text generation', 'multimodal', 'code generation', 'function calling'],
|
|
224
|
+
jurisdictions: ['US', 'EU'],
|
|
225
|
+
vendorCountry: 'US',
|
|
226
|
+
dataResidency: 'US',
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
slug: 'gemini-2.0-pro',
|
|
230
|
+
name: 'Gemini 2.0 Pro',
|
|
231
|
+
provider: { name: 'Google', website: 'https://ai.google/responsibility/principles/' },
|
|
232
|
+
description: 'High-capability multimodal model with reasoning and code generation',
|
|
233
|
+
category: 'api_platform',
|
|
234
|
+
riskLevel: 'gpai_systemic',
|
|
235
|
+
aiActRole: 'provider',
|
|
236
|
+
level: 'classified',
|
|
237
|
+
assessments: {
|
|
238
|
+
'eu-ai-act': {
|
|
239
|
+
risk_level: 'gpai_systemic',
|
|
240
|
+
risk_reasoning: 'GPAI model per Art.51. Systemic risk classification likely. EU data residency option available',
|
|
241
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
242
|
+
confidence: 'medium',
|
|
243
|
+
training_cutoff: '2024-08',
|
|
244
|
+
license: 'proprietary',
|
|
245
|
+
gpai_compliant: null,
|
|
246
|
+
eu_representative: 'Google Ireland Limited',
|
|
247
|
+
limitations: ['hallucination risk', 'high cost'],
|
|
248
|
+
known_risks: ['training data bias', 'geographic bias', 'overconfident outputs'],
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
detectionPatterns: { code: { npm: ['@google/generative-ai'], pip: ['google-generativeai'] } },
|
|
252
|
+
evidence: null,
|
|
253
|
+
capabilities: ['text generation', 'multimodal', 'code generation', 'reasoning', 'function calling'],
|
|
254
|
+
jurisdictions: ['US', 'EU'],
|
|
255
|
+
vendorCountry: 'US',
|
|
256
|
+
dataResidency: 'US',
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
slug: 'mistral-large',
|
|
260
|
+
name: 'Mistral Large',
|
|
261
|
+
provider: { name: 'Mistral AI', website: 'https://mistral.ai/terms/' },
|
|
262
|
+
description: 'Large multilingual model from EU-headquartered provider',
|
|
263
|
+
category: 'api_platform',
|
|
264
|
+
riskLevel: 'gpai',
|
|
265
|
+
aiActRole: 'provider',
|
|
266
|
+
level: 'classified',
|
|
267
|
+
assessments: {
|
|
268
|
+
'eu-ai-act': {
|
|
269
|
+
risk_level: 'gpai',
|
|
270
|
+
risk_reasoning: 'EU-headquartered provider. GPAI model per Art.51. EU data residency by default',
|
|
271
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
272
|
+
confidence: 'medium',
|
|
273
|
+
training_cutoff: '2024-11',
|
|
274
|
+
license: 'proprietary',
|
|
275
|
+
gpai_compliant: null,
|
|
276
|
+
eu_representative: 'Mistral AI (Paris, France)',
|
|
277
|
+
limitations: ['smaller knowledge base', 'less tested than GPT-4/Claude'],
|
|
278
|
+
known_risks: ['training data bias', 'limited safety testing disclosure'],
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
detectionPatterns: { code: { npm: ['@mistralai/mistralai'], pip: ['mistralai'] } },
|
|
282
|
+
evidence: null,
|
|
283
|
+
capabilities: ['text generation', 'code generation', 'multilingual', 'function calling'],
|
|
284
|
+
jurisdictions: ['EU', 'US'],
|
|
285
|
+
vendorCountry: 'FR',
|
|
286
|
+
dataResidency: 'EU',
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
slug: 'mistral-small',
|
|
290
|
+
name: 'Mistral Small',
|
|
291
|
+
provider: { name: 'Mistral AI', website: 'https://mistral.ai/terms/' },
|
|
292
|
+
description: 'Compact multilingual model for efficient text and code tasks',
|
|
293
|
+
category: 'api_platform',
|
|
294
|
+
riskLevel: 'gpai',
|
|
295
|
+
aiActRole: 'provider',
|
|
296
|
+
level: 'classified',
|
|
297
|
+
assessments: {
|
|
298
|
+
'eu-ai-act': {
|
|
299
|
+
risk_level: 'gpai',
|
|
300
|
+
risk_reasoning: 'EU-headquartered provider. Below systemic risk threshold',
|
|
301
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
302
|
+
confidence: 'medium',
|
|
303
|
+
training_cutoff: '2024-11',
|
|
304
|
+
license: 'proprietary',
|
|
305
|
+
gpai_compliant: null,
|
|
306
|
+
eu_representative: 'Mistral AI (Paris, France)',
|
|
307
|
+
limitations: ['reduced capability vs Large', 'limited reasoning'],
|
|
308
|
+
known_risks: ['training data bias'],
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
detectionPatterns: { code: { npm: ['@mistralai/mistralai'], pip: ['mistralai'] } },
|
|
312
|
+
evidence: null,
|
|
313
|
+
capabilities: ['text generation', 'code generation', 'multilingual'],
|
|
314
|
+
jurisdictions: ['EU', 'US'],
|
|
315
|
+
vendorCountry: 'FR',
|
|
316
|
+
dataResidency: 'EU',
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
slug: 'llama-3',
|
|
320
|
+
name: 'Llama 3',
|
|
321
|
+
provider: { name: 'Meta', website: 'https://llama.meta.com/' },
|
|
322
|
+
description: 'Open-weight model for self-hosted text and code generation',
|
|
323
|
+
category: 'api_platform',
|
|
324
|
+
riskLevel: 'gpai',
|
|
325
|
+
aiActRole: 'provider',
|
|
326
|
+
level: 'classified',
|
|
327
|
+
assessments: {
|
|
328
|
+
'eu-ai-act': {
|
|
329
|
+
risk_level: 'gpai',
|
|
330
|
+
risk_reasoning: 'Open-weight model. Deployer assumes GPAI obligations if modified. Art.53(2) open-source exemption may apply',
|
|
331
|
+
applicable_obligation_ids: ['OBL-026'],
|
|
332
|
+
confidence: 'low',
|
|
333
|
+
training_cutoff: '2024-03',
|
|
334
|
+
license: 'llama-community',
|
|
335
|
+
gpai_compliant: null,
|
|
336
|
+
eu_representative: null,
|
|
337
|
+
limitations: ['no multimodal', 'requires self-hosting or third-party provider', 'limited function calling'],
|
|
338
|
+
known_risks: ['training data bias', 'deployer responsible for safety guardrails', 'no built-in content filtering'],
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
detectionPatterns: { code: { pip: ['llama-cpp-python', 'transformers'] } },
|
|
342
|
+
evidence: null,
|
|
343
|
+
capabilities: ['text generation', 'code generation', 'multilingual', 'on-premise deployment'],
|
|
344
|
+
jurisdictions: ['self-hosted'],
|
|
345
|
+
vendorCountry: 'US',
|
|
346
|
+
dataResidency: null,
|
|
347
|
+
},
|
|
348
|
+
] as const);
|
|
349
|
+
|
|
350
|
+
export const findRegistryCard = (slug: string): RegistryToolCard | undefined =>
|
|
351
|
+
REGISTRY_CARDS.find((c) => c.slug === slug);
|
|
352
|
+
|
|
353
|
+
export const findRegistryCardsByProvider = (providerName: string): readonly RegistryToolCard[] =>
|
|
354
|
+
REGISTRY_CARDS.filter((c) => c.provider.name.toLowerCase() === providerName.toLowerCase());
|
|
355
|
+
|
|
356
|
+
/** Regex matching all known model slugs. Longest-first to avoid partial matches (e.g. gpt-4o vs gpt-4o-mini). */
|
|
357
|
+
export const REGISTRY_SLUG_PATTERN = new RegExp(
|
|
358
|
+
`\\b(?:${[...REGISTRY_CARDS].sort((a, b) => b.slug.length - a.slug.length || a.slug.localeCompare(b.slug)).map((c) => c.slug.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')})\\b`,
|
|
359
|
+
'g',
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
/** Check if a card is classified as GPAI with systemic risk. */
|
|
363
|
+
export const isGpaiSystemic = (card: RegistryToolCard): boolean =>
|
|
364
|
+
card.riskLevel === 'gpai_systemic';
|
|
365
|
+
|
|
366
|
+
/** Get the provider name from a card. */
|
|
367
|
+
export const getProviderName = (card: RegistryToolCard): string =>
|
|
368
|
+
card.provider.name;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { REGULATION_RAW } from './regulation-data.js';
|
|
2
|
+
export { loadRegulationData, clearRegulationCache } from './regulation-loader.js';
|
|
3
|
+
export type { RegulationData } from './regulation-loader.js';
|
|
4
|
+
export { listJurisdictions, getJurisdiction, JurisdictionSchema } from './jurisdiction-data.js';
|
|
5
|
+
export type { Jurisdiction } from './jurisdiction-data.js';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { listJurisdictions, getJurisdiction, JurisdictionSchema } from './jurisdiction-data.js';
|
|
3
|
+
|
|
4
|
+
describe('jurisdiction-data', () => {
|
|
5
|
+
it('lists all 30 jurisdictions', () => {
|
|
6
|
+
const jurisdictions = listJurisdictions();
|
|
7
|
+
expect(jurisdictions.length).toBe(30);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('all jurisdictions validate against schema', () => {
|
|
11
|
+
for (const j of listJurisdictions()) {
|
|
12
|
+
const result = JurisdictionSchema.safeParse(j);
|
|
13
|
+
expect(result.success, `Failed for ${j.country_code}: ${JSON.stringify(result.error?.issues)}`).toBe(true);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('getJurisdiction returns correct country', () => {
|
|
18
|
+
const de = getJurisdiction('de');
|
|
19
|
+
expect(de).toBeDefined();
|
|
20
|
+
expect(de!.country_name).toBe('Germany');
|
|
21
|
+
expect(de!.msa_name).toContain('Bundesnetzagentur');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('getJurisdiction is case-insensitive', () => {
|
|
25
|
+
expect(getJurisdiction('DE')).toBeDefined();
|
|
26
|
+
expect(getJurisdiction('de')).toBeDefined();
|
|
27
|
+
expect(getJurisdiction('De')).toBeDefined();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('getJurisdiction returns undefined for invalid code', () => {
|
|
31
|
+
expect(getJurisdiction('xx')).toBeUndefined();
|
|
32
|
+
expect(getJurisdiction('us')).toBeUndefined();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('all country codes are unique', () => {
|
|
36
|
+
const codes = listJurisdictions().map(j => j.country_code);
|
|
37
|
+
expect(new Set(codes).size).toBe(30);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('all countries have non-empty local_requirements', () => {
|
|
41
|
+
for (const j of listJurisdictions()) {
|
|
42
|
+
expect(j.local_requirements.length, `${j.country_code} has no local_requirements`).toBeGreaterThan(0);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('all countries have valid enforcement_date format', () => {
|
|
47
|
+
for (const j of listJurisdictions()) {
|
|
48
|
+
expect(j.enforcement_date).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('EEA countries (IS, LI, NO) are included', () => {
|
|
53
|
+
expect(getJurisdiction('is')).toBeDefined();
|
|
54
|
+
expect(getJurisdiction('li')).toBeDefined();
|
|
55
|
+
expect(getJurisdiction('no')).toBeDefined();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('France has CNIL as MSA', () => {
|
|
59
|
+
const fr = getJurisdiction('fr')!;
|
|
60
|
+
expect(fr.msa_name).toContain('CNIL');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('Spain has AESIA as MSA', () => {
|
|
64
|
+
const es = getJurisdiction('es')!;
|
|
65
|
+
expect(es.msa_name).toContain('AESIA');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('each jurisdiction has an msa_url starting with https', () => {
|
|
69
|
+
for (const j of listJurisdictions()) {
|
|
70
|
+
expect(j.msa_url, `${j.country_code} msa_url`).toMatch(/^https:\/\//);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
export const JurisdictionSchema = z.object({
|
|
4
|
+
country_code: z.string().length(2),
|
|
5
|
+
country_name: z.string(),
|
|
6
|
+
msa_name: z.string(),
|
|
7
|
+
msa_url: z.string().url(),
|
|
8
|
+
msa_contact: z.string(),
|
|
9
|
+
local_requirements: z.array(z.string()),
|
|
10
|
+
enforcement_date: z.string(),
|
|
11
|
+
language: z.string(),
|
|
12
|
+
notes: z.string().optional(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type Jurisdiction = z.infer<typeof JurisdictionSchema>;
|
|
16
|
+
|
|
17
|
+
// Import all 30 jurisdiction JSON files at compile time
|
|
18
|
+
import atData from '../../../data/regulations/jurisdictions/at.json' with { type: 'json' };
|
|
19
|
+
import beData from '../../../data/regulations/jurisdictions/be.json' with { type: 'json' };
|
|
20
|
+
import bgData from '../../../data/regulations/jurisdictions/bg.json' with { type: 'json' };
|
|
21
|
+
import hrData from '../../../data/regulations/jurisdictions/hr.json' with { type: 'json' };
|
|
22
|
+
import cyData from '../../../data/regulations/jurisdictions/cy.json' with { type: 'json' };
|
|
23
|
+
import czData from '../../../data/regulations/jurisdictions/cz.json' with { type: 'json' };
|
|
24
|
+
import dkData from '../../../data/regulations/jurisdictions/dk.json' with { type: 'json' };
|
|
25
|
+
import eeData from '../../../data/regulations/jurisdictions/ee.json' with { type: 'json' };
|
|
26
|
+
import fiData from '../../../data/regulations/jurisdictions/fi.json' with { type: 'json' };
|
|
27
|
+
import frData from '../../../data/regulations/jurisdictions/fr.json' with { type: 'json' };
|
|
28
|
+
import deData from '../../../data/regulations/jurisdictions/de.json' with { type: 'json' };
|
|
29
|
+
import grData from '../../../data/regulations/jurisdictions/gr.json' with { type: 'json' };
|
|
30
|
+
import huData from '../../../data/regulations/jurisdictions/hu.json' with { type: 'json' };
|
|
31
|
+
import ieData from '../../../data/regulations/jurisdictions/ie.json' with { type: 'json' };
|
|
32
|
+
import itData from '../../../data/regulations/jurisdictions/it.json' with { type: 'json' };
|
|
33
|
+
import lvData from '../../../data/regulations/jurisdictions/lv.json' with { type: 'json' };
|
|
34
|
+
import ltData from '../../../data/regulations/jurisdictions/lt.json' with { type: 'json' };
|
|
35
|
+
import luData from '../../../data/regulations/jurisdictions/lu.json' with { type: 'json' };
|
|
36
|
+
import mtData from '../../../data/regulations/jurisdictions/mt.json' with { type: 'json' };
|
|
37
|
+
import nlData from '../../../data/regulations/jurisdictions/nl.json' with { type: 'json' };
|
|
38
|
+
import plData from '../../../data/regulations/jurisdictions/pl.json' with { type: 'json' };
|
|
39
|
+
import ptData from '../../../data/regulations/jurisdictions/pt.json' with { type: 'json' };
|
|
40
|
+
import roData from '../../../data/regulations/jurisdictions/ro.json' with { type: 'json' };
|
|
41
|
+
import skData from '../../../data/regulations/jurisdictions/sk.json' with { type: 'json' };
|
|
42
|
+
import siData from '../../../data/regulations/jurisdictions/si.json' with { type: 'json' };
|
|
43
|
+
import esData from '../../../data/regulations/jurisdictions/es.json' with { type: 'json' };
|
|
44
|
+
import seData from '../../../data/regulations/jurisdictions/se.json' with { type: 'json' };
|
|
45
|
+
import isData from '../../../data/regulations/jurisdictions/is.json' with { type: 'json' };
|
|
46
|
+
import liData from '../../../data/regulations/jurisdictions/li.json' with { type: 'json' };
|
|
47
|
+
import noData from '../../../data/regulations/jurisdictions/no.json' with { type: 'json' };
|
|
48
|
+
|
|
49
|
+
const RAW_DATA = [
|
|
50
|
+
atData, beData, bgData, hrData, cyData, czData, dkData, eeData, fiData, frData,
|
|
51
|
+
deData, grData, huData, ieData, itData, lvData, ltData, luData, mtData, nlData,
|
|
52
|
+
plData, ptData, roData, skData, siData, esData, seData, isData, liData, noData,
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
const ALL_JURISDICTIONS: readonly Jurisdiction[] = RAW_DATA.map(d => JurisdictionSchema.parse(d));
|
|
56
|
+
|
|
57
|
+
const jurisdictionMap = new Map<string, Jurisdiction>(
|
|
58
|
+
ALL_JURISDICTIONS.map(j => [j.country_code.toLowerCase(), j])
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
export const getJurisdiction = (code: string): Jurisdiction | undefined =>
|
|
62
|
+
jurisdictionMap.get(code.toLowerCase());
|
|
63
|
+
|
|
64
|
+
export const listJurisdictions = (): readonly Jurisdiction[] =>
|
|
65
|
+
ALL_JURISDICTIONS;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import obligations from '../../../data/regulations/eu-ai-act/obligations.json' with { type: 'json' };
|
|
2
|
+
import technicalRequirements from '../../../data/regulations/eu-ai-act/technical-requirements.json' with { type: 'json' };
|
|
3
|
+
import scoring from '../../../data/regulations/eu-ai-act/scoring.json' with { type: 'json' };
|
|
4
|
+
import regulationMeta from '../../../data/regulations/eu-ai-act/regulation-meta.json' with { type: 'json' };
|
|
5
|
+
import applicabilityTree from '../../../data/regulations/eu-ai-act/applicability-tree.json' with { type: 'json' };
|
|
6
|
+
import crossMapping from '../../../data/regulations/eu-ai-act/cross-mapping.json' with { type: 'json' };
|
|
7
|
+
import localization from '../../../data/regulations/eu-ai-act/localization.json' with { type: 'json' };
|
|
8
|
+
import timeline from '../../../data/regulations/eu-ai-act/timeline.json' with { type: 'json' };
|
|
9
|
+
|
|
10
|
+
export const REGULATION_RAW = {
|
|
11
|
+
obligations,
|
|
12
|
+
technicalRequirements,
|
|
13
|
+
scoring,
|
|
14
|
+
regulationMeta,
|
|
15
|
+
applicabilityTree,
|
|
16
|
+
crossMapping,
|
|
17
|
+
localization,
|
|
18
|
+
timeline,
|
|
19
|
+
} as const;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { loadRegulationData, clearRegulationCache } from './regulation-loader.js';
|
|
3
|
+
|
|
4
|
+
describe('RegulationLoader', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
clearRegulationCache();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('should load all 8 regulation files successfully', async () => {
|
|
10
|
+
const data = await loadRegulationData();
|
|
11
|
+
|
|
12
|
+
expect(data.obligations).toBeDefined();
|
|
13
|
+
expect(data.technicalRequirements).toBeDefined();
|
|
14
|
+
expect(data.scoring).toBeDefined();
|
|
15
|
+
expect(data.regulationMeta).toBeDefined();
|
|
16
|
+
expect(data.applicabilityTree).toBeDefined();
|
|
17
|
+
expect(data.crossMapping).toBeDefined();
|
|
18
|
+
expect(data.localization).toBeDefined();
|
|
19
|
+
expect(data.timeline).toBeDefined();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should validate obligations schema', async () => {
|
|
23
|
+
const data = await loadRegulationData();
|
|
24
|
+
|
|
25
|
+
expect(data.obligations._version).toBe('2.0');
|
|
26
|
+
expect(data.obligations.obligations.length).toBeGreaterThan(0);
|
|
27
|
+
|
|
28
|
+
const firstObligation = data.obligations.obligations[0];
|
|
29
|
+
expect(firstObligation?.obligation_id).toMatch(/^eu-ai-act-OBL-/);
|
|
30
|
+
expect(firstObligation?.article_reference).toBeDefined();
|
|
31
|
+
expect(firstObligation?.title).toBeDefined();
|
|
32
|
+
expect(firstObligation?.severity).toBeDefined();
|
|
33
|
+
expect(firstObligation?.applies_to_risk_level).toBeInstanceOf(Array);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should validate scoring schema', async () => {
|
|
37
|
+
const data = await loadRegulationData();
|
|
38
|
+
const scoring = data.scoring.scoring;
|
|
39
|
+
|
|
40
|
+
expect(scoring.regulation_id).toBe('eu-ai-act');
|
|
41
|
+
expect(scoring.total_obligations).toBeGreaterThan(0);
|
|
42
|
+
expect(scoring.critical_obligation_ids.length).toBeGreaterThan(0);
|
|
43
|
+
expect(scoring.weighted_categories.length).toBeGreaterThan(0);
|
|
44
|
+
expect(scoring.thresholds.red).toBeDefined();
|
|
45
|
+
expect(scoring.thresholds.yellow).toBeDefined();
|
|
46
|
+
expect(scoring.thresholds.green).toBeDefined();
|
|
47
|
+
|
|
48
|
+
const totalWeight = scoring.weighted_categories.reduce((sum, c) => sum + c.weight, 0);
|
|
49
|
+
expect(totalWeight).toBe(100);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should validate technical-requirements schema', async () => {
|
|
53
|
+
const data = await loadRegulationData();
|
|
54
|
+
|
|
55
|
+
expect(data.technicalRequirements._version).toBe('2.0');
|
|
56
|
+
expect(data.technicalRequirements.technical_requirements.length).toBeGreaterThan(0);
|
|
57
|
+
|
|
58
|
+
const first = data.technicalRequirements.technical_requirements[0];
|
|
59
|
+
expect(first?.obligation_id).toMatch(/^eu-ai-act-OBL-/);
|
|
60
|
+
expect(first?.feature_type).toBeDefined();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should validate regulation-meta schema', async () => {
|
|
64
|
+
const data = await loadRegulationData();
|
|
65
|
+
const meta = data.regulationMeta.stage_1_metadata;
|
|
66
|
+
|
|
67
|
+
expect(meta.regulation_id).toBe('eu-ai-act');
|
|
68
|
+
expect(meta.status).toBe('in-force');
|
|
69
|
+
expect(meta.extraterritorial).toBe(true);
|
|
70
|
+
expect(meta.risk_levels.length).toBeGreaterThan(0);
|
|
71
|
+
expect(data.regulationMeta.stage_2_role_mapping.roles.length).toBeGreaterThan(0);
|
|
72
|
+
expect(data.regulationMeta.stage_3_risk_classification.levels.length).toBeGreaterThan(0);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should validate applicability-tree schema', async () => {
|
|
76
|
+
const data = await loadRegulationData();
|
|
77
|
+
const tree = data.applicabilityTree.applicability_tree;
|
|
78
|
+
|
|
79
|
+
expect(tree.regulation_id).toBe('eu-ai-act');
|
|
80
|
+
expect(tree.root_question).toBe('Q1');
|
|
81
|
+
expect(tree.questions.length).toBeGreaterThan(0);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should validate timeline schema', async () => {
|
|
85
|
+
const data = await loadRegulationData();
|
|
86
|
+
const timeline = data.timeline.timeline;
|
|
87
|
+
|
|
88
|
+
expect(timeline.regulation_id).toBe('eu-ai-act');
|
|
89
|
+
expect(timeline.key_dates.length).toBeGreaterThan(0);
|
|
90
|
+
expect(timeline.expected_amendments.length).toBeGreaterThan(0);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should return cached data on second call', async () => {
|
|
94
|
+
const data1 = await loadRegulationData();
|
|
95
|
+
const data2 = await loadRegulationData();
|
|
96
|
+
|
|
97
|
+
expect(data1).toBe(data2);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should load within 500ms', async () => {
|
|
101
|
+
const start = performance.now();
|
|
102
|
+
await loadRegulationData();
|
|
103
|
+
const duration = performance.now() - start;
|
|
104
|
+
|
|
105
|
+
expect(duration).toBeLessThan(500);
|
|
106
|
+
});
|
|
107
|
+
});
|