@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,226 @@
1
+ /**
2
+ * EuConform Evidence Engine — Markdown Summary Generation
3
+ *
4
+ * Generates a human-readable markdown summary from ScanReport and AiBillOfMaterials.
5
+ * Pure function — no side effects, no filesystem operations.
6
+ */
7
+
8
+ import type {
9
+ AiBillOfMaterials,
10
+ BomComponent,
11
+ ComplianceSignalGroup,
12
+ ScanReport,
13
+ ScanScope,
14
+ } from "./types";
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Helpers
18
+ // ---------------------------------------------------------------------------
19
+
20
+ type ComplianceArea = keyof ScanReport["complianceSignals"];
21
+
22
+ const COMPLIANCE_LABELS: Record<ComplianceArea, string> = {
23
+ disclosure: "AI Disclosure",
24
+ biasTesting: "Bias Testing",
25
+ reportingExports: "Reporting & Exports",
26
+ loggingMonitoring: "Logging & Monitoring",
27
+ humanOversight: "Human Oversight",
28
+ dataGovernance: "Data Governance",
29
+ incidentReporting: "Incident Reporting",
30
+ };
31
+
32
+ const STATUS_LABELS: Record<ComplianceSignalGroup["status"], string> = {
33
+ present: "Present",
34
+ partial: "Partial",
35
+ absent: "Absent",
36
+ unknown: "Unknown",
37
+ };
38
+
39
+ function bomKindLabel(kind: BomComponent["kind"]): string {
40
+ const labels: Record<BomComponent["kind"], string> = {
41
+ framework: "Framework",
42
+ runtime: "Runtime",
43
+ "inference-provider": "Inference Provider",
44
+ "ai-framework": "AI Framework",
45
+ model: "Model",
46
+ "vector-store": "Vector Store",
47
+ embedding: "Embedding",
48
+ dataset: "Dataset",
49
+ tool: "Tool",
50
+ };
51
+ return labels[kind];
52
+ }
53
+
54
+ function formatDate(iso: string): string {
55
+ try {
56
+ const d = new Date(iso);
57
+ return d.toISOString().split("T")[0] ?? iso;
58
+ } catch {
59
+ return iso;
60
+ }
61
+ }
62
+
63
+ // ---------------------------------------------------------------------------
64
+ // Section builders
65
+ // ---------------------------------------------------------------------------
66
+
67
+ function buildHeader(report: ScanReport, scanScope: ScanScope): string {
68
+ const date = formatDate(report.generatedAt);
69
+ return [
70
+ "# EuConform Scan Report",
71
+ "",
72
+ "> **Disclaimer:** This is technical guidance only. It does not constitute legal advice.",
73
+ `> Generated by EuConform v${report.tool.version} on ${date}.`,
74
+ `> Scan scope: \`${scanScope}\`.`,
75
+ ].join("\n");
76
+ }
77
+
78
+ function buildProjectOverview(report: ScanReport): string {
79
+ const lines = [
80
+ "## Project Overview",
81
+ "",
82
+ `- **Name:** ${report.target.name}`,
83
+ `- **Type:** ${report.target.repoType}`,
84
+ ];
85
+
86
+ if (report.target.detectedStack.length > 0) {
87
+ lines.push(`- **Stack:** ${report.target.detectedStack.join(", ")}`);
88
+ } else {
89
+ lines.push("- **Stack:** Not detected");
90
+ }
91
+
92
+ return lines.join("\n");
93
+ }
94
+
95
+ function buildAiComponents(aibom: AiBillOfMaterials): string {
96
+ const lines = ["## AI Components Detected", ""];
97
+
98
+ if (aibom.components.length === 0) {
99
+ lines.push("No AI components detected.");
100
+ return lines.join("\n");
101
+ }
102
+
103
+ lines.push("| Component | Kind | Source |");
104
+ lines.push("|-----------|------|--------|");
105
+
106
+ for (const comp of aibom.components) {
107
+ lines.push(`| ${comp.name} | ${bomKindLabel(comp.kind)} | ${comp.source} |`);
108
+ }
109
+
110
+ return lines.join("\n");
111
+ }
112
+
113
+ function buildComplianceSignals(report: ScanReport): string {
114
+ const lines = ["## Compliance Signals", ""];
115
+ lines.push("| Area | Status | Confidence |");
116
+ lines.push("|------|--------|------------|");
117
+
118
+ const areas = Object.keys(COMPLIANCE_LABELS) as ComplianceArea[];
119
+
120
+ for (const area of areas) {
121
+ const group = report.complianceSignals[area];
122
+ lines.push(
123
+ `| ${COMPLIANCE_LABELS[area]} | ${STATUS_LABELS[group.status]} | ${group.confidence} |`
124
+ );
125
+ }
126
+
127
+ return lines.join("\n");
128
+ }
129
+
130
+ function buildAssessmentHints(report: ScanReport): string {
131
+ const { riskIndicators, gpaiIndicators, possibleModes } = report.assessmentHints;
132
+
133
+ const lines = ["## Assessment Hints", ""];
134
+
135
+ if (gpaiIndicators.length === 0 && riskIndicators.length === 0 && possibleModes.length === 0) {
136
+ lines.push("No assessment hints generated (no AI detected).");
137
+ return lines.join("\n");
138
+ }
139
+
140
+ if (possibleModes.length > 0) {
141
+ lines.push(`**Possible classification modes:** ${possibleModes.join(", ")}`);
142
+ lines.push("");
143
+ }
144
+
145
+ if (gpaiIndicators.length > 0) {
146
+ lines.push("### GPAI Indicators");
147
+ lines.push("");
148
+ for (const hint of gpaiIndicators) {
149
+ const ref = hint.articleRef ? ` (${hint.articleRef})` : "";
150
+ lines.push(`- ${hint.hint}${ref}`);
151
+ }
152
+ lines.push("");
153
+ }
154
+
155
+ if (riskIndicators.length > 0) {
156
+ lines.push("### Risk Indicators");
157
+ lines.push("");
158
+ for (const hint of riskIndicators) {
159
+ const ref = hint.articleRef ? ` (${hint.articleRef})` : "";
160
+ lines.push(`- ${hint.hint}${ref}`);
161
+ }
162
+ lines.push("");
163
+ }
164
+
165
+ return lines.join("\n");
166
+ }
167
+
168
+ function buildOpenQuestions(report: ScanReport): string {
169
+ const questions = report.assessmentHints.openQuestions;
170
+ const lines = ["## Open Questions", ""];
171
+
172
+ if (questions.length === 0) {
173
+ lines.push("No open questions.");
174
+ return lines.join("\n");
175
+ }
176
+
177
+ questions.forEach((q, i) => {
178
+ lines.push(`${i + 1}. ${q}`);
179
+ });
180
+
181
+ return lines.join("\n");
182
+ }
183
+
184
+ function buildRecommendedActions(report: ScanReport): string {
185
+ const lines = ["## Recommended Actions", ""];
186
+
187
+ if (report.recommendationSummary.length === 0) {
188
+ lines.push("No recommended actions.");
189
+ return lines.join("\n");
190
+ }
191
+
192
+ for (const rec of report.recommendationSummary) {
193
+ lines.push(`- ${rec}`);
194
+ }
195
+
196
+ return lines.join("\n");
197
+ }
198
+
199
+ function buildFooter(): string {
200
+ return ["---", "*Full details: `euconform.report.json` -- AI BOM: `euconform.aibom.json`*"].join(
201
+ "\n"
202
+ );
203
+ }
204
+
205
+ // ---------------------------------------------------------------------------
206
+ // Main export
207
+ // ---------------------------------------------------------------------------
208
+
209
+ export function generateSummaryMarkdown(
210
+ report: ScanReport,
211
+ aibom: AiBillOfMaterials,
212
+ scanScope: ScanScope
213
+ ): string {
214
+ const sections = [
215
+ buildHeader(report, scanScope),
216
+ buildProjectOverview(report),
217
+ buildAiComponents(aibom),
218
+ buildComplianceSignals(report),
219
+ buildAssessmentHints(report),
220
+ buildOpenQuestions(report),
221
+ buildRecommendedActions(report),
222
+ buildFooter(),
223
+ ];
224
+
225
+ return `${sections.join("\n\n")}\n`;
226
+ }