@euconform/core 1.0.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/dist/evidence/bundle.d.ts +23 -0
  4. package/dist/evidence/bundle.d.ts.map +1 -0
  5. package/dist/evidence/bundle.js +44 -0
  6. package/dist/evidence/compliance-evaluation.d.ts +12 -0
  7. package/dist/evidence/compliance-evaluation.d.ts.map +1 -0
  8. package/dist/evidence/compliance-evaluation.js +78 -0
  9. package/dist/evidence/hash.d.ts +2 -0
  10. package/dist/evidence/hash.d.ts.map +1 -0
  11. package/dist/evidence/hash.js +4 -0
  12. package/dist/evidence/index.d.ts +13 -0
  13. package/dist/evidence/index.d.ts.map +1 -0
  14. package/dist/evidence/index.js +11 -0
  15. package/dist/evidence/markdown.d.ts +9 -0
  16. package/dist/evidence/markdown.d.ts.map +1 -0
  17. package/dist/evidence/markdown.js +169 -0
  18. package/dist/evidence/output.d.ts +13 -0
  19. package/dist/evidence/output.d.ts.map +1 -0
  20. package/dist/evidence/output.js +547 -0
  21. package/dist/evidence/types.d.ts +230 -0
  22. package/dist/evidence/types.d.ts.map +1 -0
  23. package/dist/evidence/types.js +7 -0
  24. package/dist/evidence/validate.d.ts +8 -0
  25. package/dist/evidence/validate.d.ts.map +1 -0
  26. package/dist/evidence/validate.js +175 -0
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +1 -1
  30. package/dist/inference/ollama-client.d.ts +3 -0
  31. package/dist/inference/ollama-client.d.ts.map +1 -1
  32. package/dist/inference/ollama-client.js +69 -71
  33. package/dist/legal-checks/annex-iv-report.d.ts +3 -0
  34. package/dist/legal-checks/annex-iv-report.d.ts.map +1 -1
  35. package/dist/legal-checks/annex-iv-report.js +1 -0
  36. package/dist/legal-checks/deadline-timeline.d.ts +57 -0
  37. package/dist/legal-checks/deadline-timeline.d.ts.map +1 -0
  38. package/dist/legal-checks/deadline-timeline.js +265 -0
  39. package/dist/legal-checks/gap-analysis.d.ts +48 -0
  40. package/dist/legal-checks/gap-analysis.d.ts.map +1 -0
  41. package/dist/legal-checks/gap-analysis.js +397 -0
  42. package/dist/legal-checks/gpai-classifier.d.ts +49 -0
  43. package/dist/legal-checks/gpai-classifier.d.ts.map +1 -0
  44. package/dist/legal-checks/gpai-classifier.js +197 -0
  45. package/dist/legal-checks/index.d.ts +6 -0
  46. package/dist/legal-checks/index.d.ts.map +1 -1
  47. package/dist/legal-checks/index.js +3 -0
  48. package/dist/scanner/aggregator.d.ts +7 -0
  49. package/dist/scanner/aggregator.d.ts.map +1 -0
  50. package/dist/scanner/aggregator.js +200 -0
  51. package/dist/scanner/detectors/ai-framework-detector.d.ts +3 -0
  52. package/dist/scanner/detectors/ai-framework-detector.d.ts.map +1 -0
  53. package/dist/scanner/detectors/ai-framework-detector.js +74 -0
  54. package/dist/scanner/detectors/ai-provider-detector.d.ts +3 -0
  55. package/dist/scanner/detectors/ai-provider-detector.d.ts.map +1 -0
  56. package/dist/scanner/detectors/ai-provider-detector.js +100 -0
  57. package/dist/scanner/detectors/compliance-detector.d.ts +3 -0
  58. package/dist/scanner/detectors/compliance-detector.d.ts.map +1 -0
  59. package/dist/scanner/detectors/compliance-detector.js +201 -0
  60. package/dist/scanner/detectors/config-detector.d.ts +3 -0
  61. package/dist/scanner/detectors/config-detector.d.ts.map +1 -0
  62. package/dist/scanner/detectors/config-detector.js +248 -0
  63. package/dist/scanner/detectors/framework-detector.d.ts +3 -0
  64. package/dist/scanner/detectors/framework-detector.d.ts.map +1 -0
  65. package/dist/scanner/detectors/framework-detector.js +141 -0
  66. package/dist/scanner/detectors/index.d.ts +8 -0
  67. package/dist/scanner/detectors/index.d.ts.map +1 -0
  68. package/dist/scanner/detectors/index.js +37 -0
  69. package/dist/scanner/detectors/local-inference-detector.d.ts +3 -0
  70. package/dist/scanner/detectors/local-inference-detector.d.ts.map +1 -0
  71. package/dist/scanner/detectors/local-inference-detector.js +93 -0
  72. package/dist/scanner/detectors/markdown-detector.d.ts +3 -0
  73. package/dist/scanner/detectors/markdown-detector.d.ts.map +1 -0
  74. package/dist/scanner/detectors/markdown-detector.js +139 -0
  75. package/dist/scanner/detectors/package-json-detector.d.ts +3 -0
  76. package/dist/scanner/detectors/package-json-detector.d.ts.map +1 -0
  77. package/dist/scanner/detectors/package-json-detector.js +166 -0
  78. package/dist/scanner/detectors/rag-detector.d.ts +3 -0
  79. package/dist/scanner/detectors/rag-detector.d.ts.map +1 -0
  80. package/dist/scanner/detectors/rag-detector.js +132 -0
  81. package/dist/scanner/detectors/shared.d.ts +18 -0
  82. package/dist/scanner/detectors/shared.d.ts.map +1 -0
  83. package/dist/scanner/detectors/shared.js +36 -0
  84. package/dist/scanner/discovery.d.ts +14 -0
  85. package/dist/scanner/discovery.d.ts.map +1 -0
  86. package/dist/scanner/discovery.js +235 -0
  87. package/dist/scanner/index.d.ts +9 -0
  88. package/dist/scanner/index.d.ts.map +1 -0
  89. package/dist/scanner/index.js +8 -0
  90. package/package.json +6 -3
  91. package/src/evidence/bundle.ts +65 -0
  92. package/src/evidence/compliance-evaluation.ts +114 -0
  93. package/src/evidence/hash.ts +5 -0
  94. package/src/evidence/index.ts +51 -0
  95. package/src/evidence/markdown.ts +226 -0
  96. package/src/evidence/output.ts +717 -0
  97. package/src/evidence/types.ts +329 -0
  98. package/src/evidence/validate.ts +270 -0
  99. package/src/index.ts +25 -0
  100. package/src/inference/ollama-client.ts +93 -86
  101. package/src/legal-checks/annex-iv-report.ts +4 -0
  102. package/src/legal-checks/deadline-timeline.ts +313 -0
  103. package/src/legal-checks/gap-analysis.ts +454 -0
  104. package/src/legal-checks/gpai-classifier.ts +281 -0
  105. package/src/legal-checks/index.ts +33 -0
  106. package/src/scanner/aggregator.ts +258 -0
  107. package/src/scanner/detectors/ai-framework-detector.ts +94 -0
  108. package/src/scanner/detectors/ai-provider-detector.ts +135 -0
  109. package/src/scanner/detectors/compliance-detector.ts +232 -0
  110. package/src/scanner/detectors/config-detector.ts +316 -0
  111. package/src/scanner/detectors/framework-detector.ts +163 -0
  112. package/src/scanner/detectors/index.ts +40 -0
  113. package/src/scanner/detectors/local-inference-detector.ts +124 -0
  114. package/src/scanner/detectors/markdown-detector.ts +176 -0
  115. package/src/scanner/detectors/package-json-detector.ts +202 -0
  116. package/src/scanner/detectors/rag-detector.ts +162 -0
  117. package/src/scanner/detectors/shared.ts +45 -0
  118. package/src/scanner/discovery.ts +290 -0
  119. package/src/scanner/index.ts +9 -0
  120. package/tests/evidence/bundle.test.ts +128 -0
  121. package/tests/evidence/ecef-schemas.test.ts +316 -0
  122. package/tests/evidence/hash.test.ts +25 -0
  123. package/tests/evidence/markdown.test.ts +92 -0
  124. package/tests/evidence/output.test.ts +203 -0
  125. package/tests/fixtures/compliance-good/README.md +14 -0
  126. package/tests/fixtures/compliance-good/lib/ai-service.ts +17 -0
  127. package/tests/fixtures/compliance-good/lib/review-flow.ts +11 -0
  128. package/tests/fixtures/compliance-good/package.json +10 -0
  129. package/tests/fixtures/compliance-good/tests/bias-check.test.ts +13 -0
  130. package/tests/fixtures/nextjs-openai/README.md +5 -0
  131. package/tests/fixtures/nextjs-openai/app/page.tsx +11 -0
  132. package/tests/fixtures/nextjs-openai/package.json +9 -0
  133. package/tests/fixtures/ollama-rag/.env.example +2 -0
  134. package/tests/fixtures/ollama-rag/docker-compose.yml +9 -0
  135. package/tests/fixtures/ollama-rag/package.json +9 -0
  136. package/tests/fixtures/ollama-rag/server.ts +21 -0
  137. package/tests/fixtures/plain-webapp/README.md +3 -0
  138. package/tests/fixtures/plain-webapp/index.js +5 -0
  139. package/tests/fixtures/plain-webapp/package.json +8 -0
  140. package/tests/gpai-classifier.test.ts +125 -0
  141. package/tests/gpai-timeline.test.ts +55 -0
  142. package/tests/scanner/aggregator.test.ts +122 -0
  143. package/tests/scanner/detectors.test.ts +274 -0
  144. package/tests/scanner/discovery.test.ts +87 -0
  145. package/vitest.config.ts +1 -0
  146. package/.turbo/turbo-check-types.log +0 -4
  147. package/.turbo/turbo-test.log +0 -364
  148. package/coverage/base.css +0 -224
  149. package/coverage/block-navigation.js +0 -87
  150. package/coverage/clover.xml +0 -3282
  151. package/coverage/coverage-final.json +0 -20
  152. package/coverage/favicon.png +0 -0
  153. package/coverage/index.html +0 -161
  154. package/coverage/prettify.css +0 -1
  155. package/coverage/prettify.js +0 -2
  156. package/coverage/sort-arrow-sprite.png +0 -0
  157. package/coverage/sorter.js +0 -210
  158. package/coverage/src/fairness-metrics.ts.html +0 -1579
  159. package/coverage/src/index.html +0 -161
  160. package/coverage/src/index.ts.html +0 -535
  161. package/coverage/src/inference/browser-inference.ts.html +0 -859
  162. package/coverage/src/inference/capability-detection.ts.html +0 -2227
  163. package/coverage/src/inference/index.html +0 -176
  164. package/coverage/src/inference/index.ts.html +0 -553
  165. package/coverage/src/inference/inference-factory.ts.html +0 -751
  166. package/coverage/src/inference/ollama-client.ts.html +0 -1627
  167. package/coverage/src/legal-checks/annex-iv-report.ts.html +0 -556
  168. package/coverage/src/legal-checks/bias-metrics.ts.html +0 -1855
  169. package/coverage/src/legal-checks/data-governance.ts.html +0 -529
  170. package/coverage/src/legal-checks/human-oversight-logging.ts.html +0 -490
  171. package/coverage/src/legal-checks/index.html +0 -206
  172. package/coverage/src/legal-checks/index.ts.html +0 -250
  173. package/coverage/src/legal-checks/risk-classifier.ts.html +0 -940
  174. package/coverage/src/legal-checks/robustness-transparency.ts.html +0 -571
  175. package/coverage/src/metrics/crows-pairs-bias.ts.html +0 -820
  176. package/coverage/src/metrics/index.html +0 -146
  177. package/coverage/src/metrics/index.ts.html +0 -151
  178. package/coverage/src/metrics/stereotype-bias.ts.html +0 -886
  179. package/coverage/src/risk-engine.ts.html +0 -1660
  180. package/coverage/src/types.ts.html +0 -547
  181. package/dist/legal-checks/disclaimer.d.ts +0 -2
  182. package/dist/legal-checks/disclaimer.d.ts.map +0 -1
  183. package/dist/legal-checks/disclaimer.js +0 -1
@@ -0,0 +1,454 @@
1
+ /**
2
+ * Compliance Gap Analysis Generator
3
+ * Produces prioritized action plans from EU AI Act assessment results.
4
+ *
5
+ * Supports:
6
+ * - Annex III high-risk assessment → mandatory Art. 9–15 + Art. 43 + Art. 71 obligations
7
+ * - GPAI compliance assessment → gaps directly from GPAIComplianceResult flags
8
+ *
9
+ * IMPORTANT: This module provides technical orientation, not legal advice.
10
+ */
11
+
12
+ import type { RiskAssessment } from "../types";
13
+ import type { GPAIComplianceResult, GPAIObligationType } from "./gpai-classifier";
14
+
15
+ /** Priority level for a compliance gap action */
16
+ export type GapPriority = "critical" | "high" | "medium";
17
+
18
+ /** A single compliance gap with actionable remediation steps */
19
+ export interface GapAction {
20
+ id: string;
21
+ title: string;
22
+ description: string;
23
+ articleRef: string;
24
+ priority: GapPriority;
25
+ status: "missing" | "partial";
26
+ steps: string[];
27
+ penaltyRef?: string;
28
+ }
29
+
30
+ /** Aggregated gap analysis result */
31
+ export interface GapAnalysisResult {
32
+ totalGaps: number;
33
+ criticalCount: number;
34
+ highCount: number;
35
+ mediumCount: number;
36
+ actions: GapAction[];
37
+ }
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // Annex III: Mandatory obligations for ALL high-risk systems (Art. 9–15 + Art. 43 + Art. 71 + Art. 72)
41
+ // ---------------------------------------------------------------------------
42
+
43
+ const HIGH_RISK_OBLIGATIONS: GapAction[] = [
44
+ {
45
+ id: "risk-management-system",
46
+ title: "Risk Management System",
47
+ description:
48
+ "Establish and maintain a continuous risk management system covering the full AI system lifecycle.",
49
+ articleRef: "Art. 9",
50
+ priority: "critical",
51
+ status: "missing",
52
+ steps: [
53
+ "Identify and analyze foreseeable risks to health, safety, and fundamental rights",
54
+ "Implement risk mitigation measures proportionate to identified risks",
55
+ "Test residual risks against acceptance criteria before deployment",
56
+ "Document and update risk assessment throughout lifecycle",
57
+ ],
58
+ penaltyRef: "Art. 99(3)",
59
+ },
60
+ {
61
+ id: "data-governance",
62
+ title: "Data Governance & Training Data",
63
+ description:
64
+ "Implement data governance practices covering training, validation, and testing datasets.",
65
+ articleRef: "Art. 10",
66
+ priority: "critical",
67
+ status: "missing",
68
+ steps: [
69
+ "Document data sources, collection methods, and data preparation processes",
70
+ "Assess training data for biases that could lead to discriminatory outcomes",
71
+ "Implement data quality and relevance criteria appropriate to the intended purpose",
72
+ "Establish and document data governance policies",
73
+ ],
74
+ penaltyRef: "Art. 99(3)",
75
+ },
76
+ {
77
+ id: "technical-documentation",
78
+ title: "Technical Documentation (Annex IV)",
79
+ description: "Prepare and maintain comprehensive technical documentation per Annex IV.",
80
+ articleRef: "Art. 11 + Annex IV",
81
+ priority: "critical",
82
+ status: "missing",
83
+ steps: [
84
+ "Document general system description including intended purpose and high-risk category",
85
+ "Describe design specifications, architecture, and development methods",
86
+ "Document training methods, datasets, and accuracy/robustness metrics",
87
+ "Keep documentation up-to-date throughout the system lifecycle",
88
+ ],
89
+ penaltyRef: "Art. 99(3)",
90
+ },
91
+ {
92
+ id: "record-keeping",
93
+ title: "Logging & Record-Keeping",
94
+ description: "Implement automatic logging capabilities throughout system operation.",
95
+ articleRef: "Art. 12",
96
+ priority: "high",
97
+ status: "missing",
98
+ steps: [
99
+ "Enable automatic logging of system events during operation",
100
+ "Ensure logs identify operating periods and referenced databases used",
101
+ "Retain logs for minimum 6 months (or as required by sector regulations)",
102
+ "Implement secure log storage with appropriate access controls",
103
+ ],
104
+ penaltyRef: "Art. 99(3)",
105
+ },
106
+ {
107
+ id: "transparency-information",
108
+ title: "Transparency & User Information",
109
+ description:
110
+ "Provide clear instructions for use and ensure deployers and users understand the system.",
111
+ articleRef: "Art. 13",
112
+ priority: "high",
113
+ status: "missing",
114
+ steps: [
115
+ "Prepare instructions for use covering capabilities, limitations, and intended purpose",
116
+ "Disclose the AI nature of the system clearly",
117
+ "Inform users about accuracy levels and known limitations",
118
+ "Document contact information for user questions and complaints",
119
+ ],
120
+ penaltyRef: "Art. 99(3)",
121
+ },
122
+ {
123
+ id: "human-oversight",
124
+ title: "Human Oversight Measures",
125
+ description: "Enable meaningful human oversight of the AI system throughout its operation.",
126
+ articleRef: "Art. 14",
127
+ priority: "high",
128
+ status: "missing",
129
+ steps: [
130
+ "Implement interfaces enabling human monitoring of AI outputs",
131
+ "Ensure humans can override, correct, or disregard AI decisions",
132
+ "Train persons responsible for oversight on capabilities and limitations",
133
+ "Document human oversight procedures",
134
+ ],
135
+ penaltyRef: "Art. 99(3)",
136
+ },
137
+ {
138
+ id: "accuracy-robustness",
139
+ title: "Accuracy, Robustness & Cybersecurity",
140
+ description:
141
+ "Ensure the system meets required accuracy levels and is resilient against errors and attacks.",
142
+ articleRef: "Art. 15",
143
+ priority: "high",
144
+ status: "missing",
145
+ steps: [
146
+ "Define and test accuracy metrics appropriate to the intended purpose",
147
+ "Test for robustness against errors, faults, and inconsistencies",
148
+ "Implement cybersecurity measures against adversarial manipulation",
149
+ "Document all performance metrics in technical documentation",
150
+ ],
151
+ penaltyRef: "Art. 99(3)",
152
+ },
153
+ {
154
+ id: "conformity-assessment",
155
+ title: "Conformity Assessment",
156
+ description: "Conduct conformity assessment before placing the system on the EU market.",
157
+ articleRef: "Art. 43",
158
+ priority: "critical",
159
+ status: "missing",
160
+ steps: [
161
+ "Determine the applicable conformity assessment procedure for your category",
162
+ "Conduct internal assessment OR involve a notified body (depending on category)",
163
+ "Draw up EU declaration of conformity per Annex V",
164
+ "Affix CE marking to the system or accompanying documentation",
165
+ ],
166
+ penaltyRef: "Art. 99(4)",
167
+ },
168
+ {
169
+ id: "eu-database-registration",
170
+ title: "EU AI Database Registration",
171
+ description: "Register the high-risk AI system in the EU AI Database before market placement.",
172
+ articleRef: "Art. 71",
173
+ priority: "critical",
174
+ status: "missing",
175
+ steps: [
176
+ "Create an account on the EU AI Database (managed by the AI Office)",
177
+ "Provide all required information per Art. 71(3)",
178
+ "Register before placing the system on the EU market",
179
+ "Update the registration when significant modifications occur",
180
+ ],
181
+ penaltyRef: "Art. 99(4)",
182
+ },
183
+ {
184
+ id: "post-market-monitoring",
185
+ title: "Post-Market Monitoring",
186
+ description:
187
+ "Set up a post-market monitoring system to track performance and report incidents.",
188
+ articleRef: "Art. 72",
189
+ priority: "medium",
190
+ status: "missing",
191
+ steps: [
192
+ "Establish a post-market monitoring plan before deployment",
193
+ "Collect and analyze data on system performance over time",
194
+ "Report serious incidents to national market surveillance authorities",
195
+ "Report near misses and systemic issues to the AI Office",
196
+ ],
197
+ penaltyRef: "Art. 99(3)",
198
+ },
199
+ ];
200
+
201
+ // ---------------------------------------------------------------------------
202
+ // GPAI: Detailed gap definitions for each obligation type
203
+ // ---------------------------------------------------------------------------
204
+
205
+ const GPAI_OBLIGATION_GAPS: Record<GPAIObligationType, Omit<GapAction, "id" | "status">> = {
206
+ "technical-docs": {
207
+ title: "Technical Documentation (Annex XI/XII)",
208
+ description:
209
+ "Prepare and maintain technical documentation covering the GPAI model per Annex XI (standard) or Annex XII (systemic risk extension).",
210
+ articleRef: "Art. 53(1)(a)",
211
+ priority: "critical",
212
+ steps: [
213
+ "Document general model description, training approach, and architecture",
214
+ "List training data sources, data governance policies, and total compute (FLOP)",
215
+ "Document capabilities, limitations, and foreseeable misuse risks",
216
+ "Keep documentation updated with each significant model change",
217
+ ],
218
+ penaltyRef: "Art. 101",
219
+ },
220
+ "downstream-info": {
221
+ title: "Downstream Provider Information Package",
222
+ description:
223
+ "Provide downstream providers with all information they need for their own EU AI Act obligations.",
224
+ articleRef: "Art. 53(1)(b)",
225
+ priority: "critical",
226
+ steps: [
227
+ "Document model capabilities, limitations, and intended use cases",
228
+ "Specify restrictions on use and integration requirements",
229
+ "Provide API documentation and integration guidance",
230
+ "Update the information package when the model is updated",
231
+ ],
232
+ penaltyRef: "Art. 101",
233
+ },
234
+ "copyright-policy": {
235
+ title: "Copyright Policy + Training Data Summary",
236
+ description: "Establish a copyright compliance policy and publish a training data summary.",
237
+ articleRef: "Art. 53(1)(c–d)",
238
+ priority: "high",
239
+ steps: [
240
+ "Implement a text and data mining (TDM) opt-out compliance policy (Art. 53(1)(c))",
241
+ "Publish a sufficiently detailed training data summary (Art. 53(1)(d))",
242
+ "Document copyright clearances obtained for training data",
243
+ "Establish an ongoing compliance process for future training data updates",
244
+ ],
245
+ penaltyRef: "Art. 101",
246
+ },
247
+ "eu-database": {
248
+ title: "EU AI Database Registration",
249
+ description:
250
+ "Register the GPAI model in the EU AI Database before placing it on the EU market.",
251
+ articleRef: "Art. 71",
252
+ priority: "critical",
253
+ steps: [
254
+ "Access the EU AI Database portal managed by the AI Office",
255
+ "Provide required model information including name, type, and capabilities",
256
+ "Register before placing the model on the EU market",
257
+ "Update the registration when the model is significantly updated",
258
+ ],
259
+ penaltyRef: "Art. 101",
260
+ },
261
+ "open-source": {
262
+ title: "Open-Source Release Compliance",
263
+ description:
264
+ "Verify compliance with remaining obligations that apply despite the open-source exemption.",
265
+ articleRef: "Art. 53(2)",
266
+ priority: "medium",
267
+ steps: [
268
+ "Confirm that weights, parameters, and architecture are publicly available",
269
+ "Ensure Art. 53(1)(d) training data summary obligation is still fulfilled",
270
+ "If systemic risk threshold is met, Art. 55 obligations remain applicable",
271
+ ],
272
+ },
273
+ "systemic-risk": {
274
+ title: "Systemic Risk Threshold Verification",
275
+ description: "Formally determine if the model meets the ≥10²⁵ FLOP systemic risk threshold.",
276
+ articleRef: "Art. 51 + Annex XIII",
277
+ priority: "high",
278
+ steps: [
279
+ "Document total training compute (FLOP) with engineering sign-off",
280
+ "Consult with technical experts if compute is near the threshold",
281
+ "If threshold is met, implement all Art. 55 obligations",
282
+ "Notify the AI Office if the systemic risk threshold is reached",
283
+ ],
284
+ },
285
+ "red-teaming": {
286
+ title: "Adversarial Testing / Red-Teaming",
287
+ description:
288
+ "Conduct model evaluations and adversarial testing to identify and mitigate systemic risks.",
289
+ articleRef: "Art. 55(1)(a)",
290
+ priority: "critical",
291
+ steps: [
292
+ "Define red-teaming scope covering systemic risks (CBRN, cyberattacks, disinformation, etc.)",
293
+ "Conduct standardized evaluations per AI Office guidelines and emerging standards",
294
+ "Engage external domain experts for adversarial testing",
295
+ "Document findings and implement mitigation measures",
296
+ "Repeat evaluations before each significant model release",
297
+ ],
298
+ penaltyRef: "Art. 101",
299
+ },
300
+ "incident-reporting": {
301
+ title: "Serious Incident Reporting Mechanisms",
302
+ description:
303
+ "Establish systems to track and report serious incidents caused by the GPAI model.",
304
+ articleRef: "Art. 55(1)(b)",
305
+ priority: "critical",
306
+ steps: [
307
+ "Define criteria for what constitutes a serious incident for your GPAI model",
308
+ "Implement an incident tracking and documentation system",
309
+ "Establish a direct reporting channel to the AI Office",
310
+ "Set up notification procedures for affected national authorities and users",
311
+ "Document incident response and remediation procedures",
312
+ ],
313
+ penaltyRef: "Art. 101",
314
+ },
315
+ cybersecurity: {
316
+ title: "Cybersecurity Measures",
317
+ description:
318
+ "Implement adequate cybersecurity protections for the GPAI model and its infrastructure.",
319
+ articleRef: "Art. 55(1)(c)",
320
+ priority: "high",
321
+ steps: [
322
+ "Assess cybersecurity risks specific to the GPAI model and API surface",
323
+ "Implement adversarial robustness measures against prompt injection and model extraction",
324
+ "Secure training infrastructure, model weights, and API endpoints",
325
+ "Document cybersecurity measures in Annex XII technical documentation",
326
+ ],
327
+ penaltyRef: "Art. 101",
328
+ },
329
+ };
330
+
331
+ // ---------------------------------------------------------------------------
332
+ // Public API
333
+ // ---------------------------------------------------------------------------
334
+
335
+ const PRIORITY_ORDER: Record<GapPriority, number> = { critical: 0, high: 1, medium: 2 };
336
+
337
+ const SORTED_HIGH_RISK_OBLIGATIONS: GapAction[] = [...HIGH_RISK_OBLIGATIONS].sort(
338
+ (a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]
339
+ );
340
+
341
+ function countByPriority(
342
+ actions: GapAction[]
343
+ ): Pick<GapAnalysisResult, "criticalCount" | "highCount" | "mediumCount"> {
344
+ let criticalCount = 0;
345
+ let highCount = 0;
346
+ let mediumCount = 0;
347
+ for (const a of actions) {
348
+ if (a.priority === "critical") criticalCount++;
349
+ else if (a.priority === "high") highCount++;
350
+ else mediumCount++;
351
+ }
352
+ return { criticalCount, highCount, mediumCount };
353
+ }
354
+
355
+ /**
356
+ * Generate a gap analysis action plan from an Annex III risk assessment.
357
+ *
358
+ * - unacceptable → Art. 5 prohibition action (critical)
359
+ * - high → all mandatory Art. 9–15 + Art. 43 + Art. 71 + Art. 72 obligations
360
+ * - limited → Art. 50 transparency obligations
361
+ * - minimal → no gaps
362
+ */
363
+ export function generateAnnexIIIGapAnalysis(assessment: RiskAssessment): GapAnalysisResult {
364
+ if (assessment.level === "minimal") {
365
+ return { totalGaps: 0, criticalCount: 0, highCount: 0, mediumCount: 0, actions: [] };
366
+ }
367
+
368
+ if (assessment.level === "unacceptable") {
369
+ const actions: GapAction[] = [
370
+ {
371
+ id: "prohibited-ai",
372
+ title: "Prohibited AI System (Art. 5)",
373
+ description:
374
+ "This system shows characteristics potentially prohibited under Art. 5. Do not deploy in the EU without comprehensive legal review.",
375
+ articleRef: "Art. 5",
376
+ priority: "critical",
377
+ status: "missing",
378
+ steps: [
379
+ "Immediately halt deployment plans for the EU market",
380
+ "Seek qualified legal counsel to assess whether the Art. 5 prohibition applies",
381
+ "Consider fundamental system redesign to eliminate prohibited characteristics",
382
+ ],
383
+ penaltyRef: "Art. 99(4)",
384
+ },
385
+ ];
386
+ return { totalGaps: 1, criticalCount: 1, highCount: 0, mediumCount: 0, actions };
387
+ }
388
+
389
+ if (assessment.level === "limited") {
390
+ const actions: GapAction[] = [
391
+ {
392
+ id: "ai-interaction-disclosure",
393
+ title: "AI Interaction Disclosure",
394
+ description: "Inform users that they are interacting with an AI system (Art. 50(1)).",
395
+ articleRef: "Art. 50(1)",
396
+ priority: "high",
397
+ status: "missing",
398
+ steps: [
399
+ "Add a clear disclosure at the start of each AI interaction",
400
+ "Exception: disclosure not required if obvious from context to a reasonable person",
401
+ "Document the disclosure mechanism in your compliance records",
402
+ ],
403
+ penaltyRef: "Art. 99(3)",
404
+ },
405
+ {
406
+ id: "ai-content-labeling",
407
+ title: "AI-Generated Content Labeling",
408
+ description:
409
+ "Label AI-generated audio, image, video, or text content that could mislead users (Art. 50(2–4)).",
410
+ articleRef: "Art. 50(2–4)",
411
+ priority: "high",
412
+ status: "partial",
413
+ steps: [
414
+ "Implement machine-readable marking of AI-generated content",
415
+ "Add visible disclosure for synthetic media (deepfakes, AI-generated images/video)",
416
+ "Apply Art. 50(4) disclosure for emotion recognition or biometric categorization",
417
+ ],
418
+ penaltyRef: "Art. 99(3)",
419
+ },
420
+ ];
421
+ return {
422
+ totalGaps: actions.length,
423
+ ...countByPriority(actions),
424
+ actions,
425
+ };
426
+ }
427
+
428
+ // high: all mandatory obligations, pre-sorted at module init
429
+ return {
430
+ totalGaps: SORTED_HIGH_RISK_OBLIGATIONS.length,
431
+ ...countByPriority(SORTED_HIGH_RISK_OBLIGATIONS),
432
+ actions: SORTED_HIGH_RISK_OBLIGATIONS,
433
+ };
434
+ }
435
+
436
+ /**
437
+ * Generate a gap analysis action plan from a GPAI compliance result.
438
+ * Only generates actions for obligations flagged as missing or partial.
439
+ */
440
+ export function generateGPAIGapAnalysis(result: GPAIComplianceResult): GapAnalysisResult {
441
+ if (result.flags.length === 0) {
442
+ return { totalGaps: 0, criticalCount: 0, highCount: 0, mediumCount: 0, actions: [] };
443
+ }
444
+
445
+ const actions: GapAction[] = result.flags
446
+ .map((flag) => ({
447
+ id: flag.obligation,
448
+ status: flag.status,
449
+ ...GPAI_OBLIGATION_GAPS[flag.obligation],
450
+ }))
451
+ .sort((a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]);
452
+
453
+ return { totalGaps: actions.length, ...countByPriority(actions), actions };
454
+ }