@euconform/core 1.2.0 → 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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +6 -0
- package/dist/evidence/bundle.d.ts +23 -0
- package/dist/evidence/bundle.d.ts.map +1 -0
- package/dist/evidence/bundle.js +44 -0
- package/dist/evidence/compliance-evaluation.d.ts +12 -0
- package/dist/evidence/compliance-evaluation.d.ts.map +1 -0
- package/dist/evidence/compliance-evaluation.js +78 -0
- package/dist/evidence/hash.d.ts +2 -0
- package/dist/evidence/hash.d.ts.map +1 -0
- package/dist/evidence/hash.js +4 -0
- package/dist/evidence/index.d.ts +13 -0
- package/dist/evidence/index.d.ts.map +1 -0
- package/dist/evidence/index.js +11 -0
- package/dist/evidence/markdown.d.ts +9 -0
- package/dist/evidence/markdown.d.ts.map +1 -0
- package/dist/evidence/markdown.js +169 -0
- package/dist/evidence/output.d.ts +13 -0
- package/dist/evidence/output.d.ts.map +1 -0
- package/dist/evidence/output.js +547 -0
- package/dist/evidence/types.d.ts +230 -0
- package/dist/evidence/types.d.ts.map +1 -0
- package/dist/evidence/types.js +7 -0
- package/dist/evidence/validate.d.ts +8 -0
- package/dist/evidence/validate.d.ts.map +1 -0
- package/dist/evidence/validate.js +175 -0
- package/dist/inference/ollama-client.d.ts +2 -0
- package/dist/inference/ollama-client.d.ts.map +1 -1
- package/dist/inference/ollama-client.js +61 -73
- package/dist/scanner/aggregator.d.ts +7 -0
- package/dist/scanner/aggregator.d.ts.map +1 -0
- package/dist/scanner/aggregator.js +200 -0
- package/dist/scanner/detectors/ai-framework-detector.d.ts +3 -0
- package/dist/scanner/detectors/ai-framework-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/ai-framework-detector.js +74 -0
- package/dist/scanner/detectors/ai-provider-detector.d.ts +3 -0
- package/dist/scanner/detectors/ai-provider-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/ai-provider-detector.js +100 -0
- package/dist/scanner/detectors/compliance-detector.d.ts +3 -0
- package/dist/scanner/detectors/compliance-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/compliance-detector.js +201 -0
- package/dist/scanner/detectors/config-detector.d.ts +3 -0
- package/dist/scanner/detectors/config-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/config-detector.js +248 -0
- package/dist/scanner/detectors/framework-detector.d.ts +3 -0
- package/dist/scanner/detectors/framework-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/framework-detector.js +141 -0
- package/dist/scanner/detectors/index.d.ts +8 -0
- package/dist/scanner/detectors/index.d.ts.map +1 -0
- package/dist/scanner/detectors/index.js +37 -0
- package/dist/scanner/detectors/local-inference-detector.d.ts +3 -0
- package/dist/scanner/detectors/local-inference-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/local-inference-detector.js +93 -0
- package/dist/scanner/detectors/markdown-detector.d.ts +3 -0
- package/dist/scanner/detectors/markdown-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/markdown-detector.js +139 -0
- package/dist/scanner/detectors/package-json-detector.d.ts +3 -0
- package/dist/scanner/detectors/package-json-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/package-json-detector.js +166 -0
- package/dist/scanner/detectors/rag-detector.d.ts +3 -0
- package/dist/scanner/detectors/rag-detector.d.ts.map +1 -0
- package/dist/scanner/detectors/rag-detector.js +132 -0
- package/dist/scanner/detectors/shared.d.ts +18 -0
- package/dist/scanner/detectors/shared.d.ts.map +1 -0
- package/dist/scanner/detectors/shared.js +36 -0
- package/dist/scanner/discovery.d.ts +14 -0
- package/dist/scanner/discovery.d.ts.map +1 -0
- package/dist/scanner/discovery.js +235 -0
- package/dist/scanner/index.d.ts +9 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +8 -0
- package/package.json +6 -3
- package/src/evidence/bundle.ts +65 -0
- package/src/evidence/compliance-evaluation.ts +114 -0
- package/src/evidence/hash.ts +5 -0
- package/src/evidence/index.ts +51 -0
- package/src/evidence/markdown.ts +226 -0
- package/src/evidence/output.ts +717 -0
- package/src/evidence/types.ts +329 -0
- package/src/evidence/validate.ts +270 -0
- package/src/inference/ollama-client.ts +81 -90
- package/src/scanner/aggregator.ts +258 -0
- package/src/scanner/detectors/ai-framework-detector.ts +94 -0
- package/src/scanner/detectors/ai-provider-detector.ts +135 -0
- package/src/scanner/detectors/compliance-detector.ts +232 -0
- package/src/scanner/detectors/config-detector.ts +316 -0
- package/src/scanner/detectors/framework-detector.ts +163 -0
- package/src/scanner/detectors/index.ts +40 -0
- package/src/scanner/detectors/local-inference-detector.ts +124 -0
- package/src/scanner/detectors/markdown-detector.ts +176 -0
- package/src/scanner/detectors/package-json-detector.ts +202 -0
- package/src/scanner/detectors/rag-detector.ts +162 -0
- package/src/scanner/detectors/shared.ts +45 -0
- package/src/scanner/discovery.ts +290 -0
- package/src/scanner/index.ts +9 -0
- package/tests/evidence/bundle.test.ts +128 -0
- package/tests/evidence/ecef-schemas.test.ts +316 -0
- package/tests/evidence/hash.test.ts +25 -0
- package/tests/evidence/markdown.test.ts +92 -0
- package/tests/evidence/output.test.ts +203 -0
- package/tests/fixtures/compliance-good/README.md +14 -0
- package/tests/fixtures/compliance-good/lib/ai-service.ts +17 -0
- package/tests/fixtures/compliance-good/lib/review-flow.ts +11 -0
- package/tests/fixtures/compliance-good/package.json +10 -0
- package/tests/fixtures/compliance-good/tests/bias-check.test.ts +13 -0
- package/tests/fixtures/nextjs-openai/README.md +5 -0
- package/tests/fixtures/nextjs-openai/app/page.tsx +11 -0
- package/tests/fixtures/nextjs-openai/package.json +9 -0
- package/tests/fixtures/ollama-rag/.env.example +2 -0
- package/tests/fixtures/ollama-rag/docker-compose.yml +9 -0
- package/tests/fixtures/ollama-rag/package.json +9 -0
- package/tests/fixtures/ollama-rag/server.ts +21 -0
- package/tests/fixtures/plain-webapp/README.md +3 -0
- package/tests/fixtures/plain-webapp/index.js +5 -0
- package/tests/fixtures/plain-webapp/package.json +8 -0
- package/tests/gpai-classifier.test.ts +4 -4
- package/tests/gpai-timeline.test.ts +2 -2
- package/tests/scanner/aggregator.test.ts +122 -0
- package/tests/scanner/detectors.test.ts +274 -0
- package/tests/scanner/discovery.test.ts +87 -0
- package/vitest.config.ts +1 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EuConform Evidence Engine — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* The scanner produces evidence, hints, and open questions — not legal verdicts.
|
|
5
|
+
* Classification is done by the wizard from human input, not by the scanner.
|
|
6
|
+
*/
|
|
7
|
+
export type SignalCategory = "framework" | "runtime" | "ai-provider" | "ai-framework" | "ai-model" | "local-inference" | "rag" | "training" | "compliance-disclosure" | "compliance-logging" | "compliance-oversight" | "compliance-bias" | "compliance-data" | "compliance-incident" | "compliance-reporting";
|
|
8
|
+
export type ConfidenceLevel = "high" | "medium" | "low";
|
|
9
|
+
export type ScanScope = "production" | "all";
|
|
10
|
+
export type FileProvenance = "runtime" | "config" | "root-docs" | "docs" | "test" | "fixture" | "example" | "generated" | "tooling";
|
|
11
|
+
export interface SignalEvidence {
|
|
12
|
+
file: string;
|
|
13
|
+
line?: number;
|
|
14
|
+
snippet: string;
|
|
15
|
+
provenance?: FileProvenance;
|
|
16
|
+
}
|
|
17
|
+
export interface DetectedSignal {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
category: SignalCategory;
|
|
21
|
+
confidence: ConfidenceLevel;
|
|
22
|
+
evidence: SignalEvidence[];
|
|
23
|
+
}
|
|
24
|
+
export interface OpenQuestion {
|
|
25
|
+
id: string;
|
|
26
|
+
question: string;
|
|
27
|
+
context: string;
|
|
28
|
+
relatedSignalIds: string[];
|
|
29
|
+
suggestedAction: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ScanMeta {
|
|
32
|
+
scannedAt: string;
|
|
33
|
+
scanDurationMs: number;
|
|
34
|
+
toolVersion: string;
|
|
35
|
+
targetPath: string;
|
|
36
|
+
scanScope: ScanScope;
|
|
37
|
+
filesScanned: number;
|
|
38
|
+
filesSkipped: number;
|
|
39
|
+
}
|
|
40
|
+
export interface RepoProfile {
|
|
41
|
+
name: string;
|
|
42
|
+
version?: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
license?: string;
|
|
45
|
+
isMonorepo: boolean;
|
|
46
|
+
packageManager?: "npm" | "pnpm" | "yarn" | "bun";
|
|
47
|
+
languages: string[];
|
|
48
|
+
}
|
|
49
|
+
export type AppType = "web-app" | "api-server" | "cli-tool" | "library" | "chatbot" | "ml-pipeline" | "unknown";
|
|
50
|
+
export interface ScanResult {
|
|
51
|
+
meta: ScanMeta;
|
|
52
|
+
repo: RepoProfile;
|
|
53
|
+
appTypes: AppType[];
|
|
54
|
+
signals: DetectedSignal[];
|
|
55
|
+
openQuestions: OpenQuestion[];
|
|
56
|
+
signalSummary: {
|
|
57
|
+
total: number;
|
|
58
|
+
byCategory: Partial<Record<SignalCategory, number>>;
|
|
59
|
+
byConfidence: Record<ConfidenceLevel, number>;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export interface ScanOptions {
|
|
63
|
+
targetPath: string;
|
|
64
|
+
scope?: ScanScope;
|
|
65
|
+
extensions?: string[];
|
|
66
|
+
excludeGlobs?: string[];
|
|
67
|
+
maxFileSizeBytes?: number;
|
|
68
|
+
maxFiles?: number;
|
|
69
|
+
}
|
|
70
|
+
export interface ScanFile {
|
|
71
|
+
relativePath: string;
|
|
72
|
+
absolutePath: string;
|
|
73
|
+
extension: string;
|
|
74
|
+
content: string;
|
|
75
|
+
sizeBytes: number;
|
|
76
|
+
provenance: FileProvenance;
|
|
77
|
+
}
|
|
78
|
+
export interface DetectorContext {
|
|
79
|
+
file: ScanFile;
|
|
80
|
+
/** Pre-split lines of file.content — avoids redundant .split("\n") in each detector */
|
|
81
|
+
lines: string[];
|
|
82
|
+
allFiles: ScanFile[];
|
|
83
|
+
/** Pre-parsed root package.json, if available */
|
|
84
|
+
rootPackageJson?: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
export type SignalDetector = (ctx: DetectorContext) => DetectedSignal[];
|
|
87
|
+
export interface ComplianceSignalGroup {
|
|
88
|
+
status: "present" | "partial" | "absent" | "unknown";
|
|
89
|
+
confidence: ConfidenceLevel;
|
|
90
|
+
evidence: SignalEvidence[];
|
|
91
|
+
}
|
|
92
|
+
export interface AssessmentHint {
|
|
93
|
+
hint: string;
|
|
94
|
+
articleRef?: string;
|
|
95
|
+
confidence: ConfidenceLevel;
|
|
96
|
+
}
|
|
97
|
+
export interface ScanGap {
|
|
98
|
+
id: string;
|
|
99
|
+
title: string;
|
|
100
|
+
description: string;
|
|
101
|
+
priority: "critical" | "high" | "medium" | "low";
|
|
102
|
+
status: "missing" | "partial";
|
|
103
|
+
basis: "scanner-rule";
|
|
104
|
+
evidence: SignalEvidence[];
|
|
105
|
+
}
|
|
106
|
+
export interface ScanReport {
|
|
107
|
+
schemaVersion: "euconform.report.v1";
|
|
108
|
+
generatedAt: string;
|
|
109
|
+
tool: {
|
|
110
|
+
name: string;
|
|
111
|
+
version: string;
|
|
112
|
+
};
|
|
113
|
+
target: {
|
|
114
|
+
rootPath: string;
|
|
115
|
+
name: string;
|
|
116
|
+
repoType: string;
|
|
117
|
+
detectedStack: string[];
|
|
118
|
+
};
|
|
119
|
+
aiFootprint: {
|
|
120
|
+
usesAI: boolean;
|
|
121
|
+
inferenceModes: string[];
|
|
122
|
+
providerHints: string[];
|
|
123
|
+
ragHints: string[];
|
|
124
|
+
};
|
|
125
|
+
complianceSignals: {
|
|
126
|
+
disclosure: ComplianceSignalGroup;
|
|
127
|
+
biasTesting: ComplianceSignalGroup;
|
|
128
|
+
reportingExports: ComplianceSignalGroup;
|
|
129
|
+
loggingMonitoring: ComplianceSignalGroup;
|
|
130
|
+
humanOversight: ComplianceSignalGroup;
|
|
131
|
+
dataGovernance: ComplianceSignalGroup;
|
|
132
|
+
incidentReporting: ComplianceSignalGroup;
|
|
133
|
+
};
|
|
134
|
+
assessmentHints: {
|
|
135
|
+
possibleModes: string[];
|
|
136
|
+
riskIndicators: AssessmentHint[];
|
|
137
|
+
gpaiIndicators: AssessmentHint[];
|
|
138
|
+
openQuestions: string[];
|
|
139
|
+
};
|
|
140
|
+
gaps: ScanGap[];
|
|
141
|
+
recommendationSummary: string[];
|
|
142
|
+
}
|
|
143
|
+
export type BomComponentKind = "framework" | "runtime" | "inference-provider" | "ai-framework" | "model" | "vector-store" | "embedding" | "dataset" | "tool";
|
|
144
|
+
export interface BomComponent {
|
|
145
|
+
id: string;
|
|
146
|
+
kind: BomComponentKind;
|
|
147
|
+
name: string;
|
|
148
|
+
version?: string;
|
|
149
|
+
source: "package.json" | "lock-file" | "code" | "config" | "docs";
|
|
150
|
+
}
|
|
151
|
+
export interface AiBillOfMaterials {
|
|
152
|
+
schemaVersion: "euconform.aibom.v1";
|
|
153
|
+
generatedAt: string;
|
|
154
|
+
project: {
|
|
155
|
+
name: string;
|
|
156
|
+
rootPath: string;
|
|
157
|
+
};
|
|
158
|
+
components: BomComponent[];
|
|
159
|
+
complianceCapabilities: {
|
|
160
|
+
biasEvaluation: boolean;
|
|
161
|
+
jsonExport: boolean;
|
|
162
|
+
pdfExport: boolean;
|
|
163
|
+
loggingInfrastructure: boolean;
|
|
164
|
+
humanReviewFlow: boolean;
|
|
165
|
+
incidentHandling: boolean;
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export type FailOnLevel = "none" | "critical" | "high" | "medium" | "low";
|
|
169
|
+
export interface GapCounts {
|
|
170
|
+
critical: number;
|
|
171
|
+
high: number;
|
|
172
|
+
medium: number;
|
|
173
|
+
low: number;
|
|
174
|
+
}
|
|
175
|
+
export interface CiReport {
|
|
176
|
+
schemaVersion: "euconform.ci.v1";
|
|
177
|
+
generatedAt: string;
|
|
178
|
+
target: {
|
|
179
|
+
name: string;
|
|
180
|
+
rootPath: string;
|
|
181
|
+
};
|
|
182
|
+
status: {
|
|
183
|
+
failOn: FailOnLevel;
|
|
184
|
+
failing: boolean;
|
|
185
|
+
gapCounts: GapCounts;
|
|
186
|
+
openQuestions: number;
|
|
187
|
+
};
|
|
188
|
+
aiDetected: boolean;
|
|
189
|
+
scanScope: ScanScope;
|
|
190
|
+
artifacts: string[];
|
|
191
|
+
complianceOverview: Array<{
|
|
192
|
+
area: string;
|
|
193
|
+
status: ComplianceSignalGroup["status"];
|
|
194
|
+
confidence: ComplianceSignalGroup["confidence"];
|
|
195
|
+
}>;
|
|
196
|
+
topGaps: Array<{
|
|
197
|
+
id: string;
|
|
198
|
+
title: string;
|
|
199
|
+
priority: ScanGap["priority"];
|
|
200
|
+
status: ScanGap["status"];
|
|
201
|
+
}>;
|
|
202
|
+
}
|
|
203
|
+
export interface ScanOutput {
|
|
204
|
+
report: ScanReport;
|
|
205
|
+
aibom: AiBillOfMaterials;
|
|
206
|
+
summaryMarkdown: string;
|
|
207
|
+
}
|
|
208
|
+
export type BundleArtifactRole = "report" | "aibom" | "ci" | "summary";
|
|
209
|
+
export interface BundleArtifactRef {
|
|
210
|
+
role: BundleArtifactRole;
|
|
211
|
+
fileName: string;
|
|
212
|
+
sha256: string;
|
|
213
|
+
schemaVersion?: string;
|
|
214
|
+
mimeType?: string;
|
|
215
|
+
required: boolean;
|
|
216
|
+
}
|
|
217
|
+
export interface ScanBundle {
|
|
218
|
+
schemaVersion: "euconform.bundle.v1";
|
|
219
|
+
generatedAt: string;
|
|
220
|
+
tool: {
|
|
221
|
+
name: string;
|
|
222
|
+
version: string;
|
|
223
|
+
};
|
|
224
|
+
target: {
|
|
225
|
+
name: string;
|
|
226
|
+
rootPath: string;
|
|
227
|
+
};
|
|
228
|
+
artifacts: BundleArtifactRef[];
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/evidence/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AiBillOfMaterials, CiReport, ScanBundle, ScanReport } from "./types";
|
|
2
|
+
export declare function getSchemaMajorVersion(schemaVersion: string): string | null;
|
|
3
|
+
export declare function validateScanReport(data: unknown): ScanReport;
|
|
4
|
+
export declare function validateAiBillOfMaterials(data: unknown): AiBillOfMaterials;
|
|
5
|
+
export declare function validateCiReport(data: unknown): CiReport;
|
|
6
|
+
export declare function validateScanBundle(data: unknown): ScanBundle;
|
|
7
|
+
export declare function validateEcefJsonDocument(schemaVersion: string, data: unknown): ScanReport | AiBillOfMaterials | CiReport | ScanBundle;
|
|
8
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/evidence/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA6DnF,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE1E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAmC5D;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,CAa1E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAgCxD;AAKD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAiG5D;AAED,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,OAAO,GACZ,UAAU,GAAG,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAaxD"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
function assertObject(data, label) {
|
|
2
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
3
|
+
throw new Error(`Invalid ${label}: expected a JSON object`);
|
|
4
|
+
}
|
|
5
|
+
return data;
|
|
6
|
+
}
|
|
7
|
+
function requireSchemaVersion(obj, expected, label) {
|
|
8
|
+
if (obj.schemaVersion !== expected) {
|
|
9
|
+
throw new Error(`Invalid ${label} schema version: expected "${expected}", got "${String(obj.schemaVersion)}"`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function requireField(obj, key, type, label, fieldName = key) {
|
|
13
|
+
if (!(key in obj)) {
|
|
14
|
+
throw new Error(`Invalid ${label}: missing '${fieldName}'`);
|
|
15
|
+
}
|
|
16
|
+
const value = obj[key];
|
|
17
|
+
const isValid = (type === "array" && Array.isArray(value)) ||
|
|
18
|
+
(type === "object" && value && typeof value === "object" && !Array.isArray(value)) ||
|
|
19
|
+
(type === "string" && typeof value === "string") ||
|
|
20
|
+
(type === "boolean" && typeof value === "boolean") ||
|
|
21
|
+
(type === "number" && typeof value === "number");
|
|
22
|
+
if (!isValid) {
|
|
23
|
+
throw new Error(`Invalid ${label}: '${fieldName}' must be a ${type}`);
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
function requireStringArray(obj, key, label, fieldName = key) {
|
|
28
|
+
const value = requireField(obj, key, "array", label, fieldName);
|
|
29
|
+
if (!value.every((item) => typeof item === "string")) {
|
|
30
|
+
throw new Error(`Invalid ${label}: '${fieldName}' must contain strings`);
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
function majorVersion(schemaVersion) {
|
|
35
|
+
const match = /\.v(\d+)$/.exec(schemaVersion);
|
|
36
|
+
return match?.[1] ?? null;
|
|
37
|
+
}
|
|
38
|
+
export function getSchemaMajorVersion(schemaVersion) {
|
|
39
|
+
return majorVersion(schemaVersion);
|
|
40
|
+
}
|
|
41
|
+
export function validateScanReport(data) {
|
|
42
|
+
const obj = assertObject(data, "report");
|
|
43
|
+
requireSchemaVersion(obj, "euconform.report.v1", "report");
|
|
44
|
+
requireField(obj, "generatedAt", "string", "report");
|
|
45
|
+
const tool = requireField(obj, "tool", "object", "report");
|
|
46
|
+
requireField(tool, "name", "string", "report", "tool.name");
|
|
47
|
+
requireField(tool, "version", "string", "report", "tool.version");
|
|
48
|
+
const target = requireField(obj, "target", "object", "report");
|
|
49
|
+
requireField(target, "rootPath", "string", "report", "target.rootPath");
|
|
50
|
+
requireField(target, "name", "string", "report", "target.name");
|
|
51
|
+
requireField(target, "repoType", "string", "report", "target.repoType");
|
|
52
|
+
requireField(target, "detectedStack", "array", "report", "target.detectedStack");
|
|
53
|
+
const aiFootprint = requireField(obj, "aiFootprint", "object", "report");
|
|
54
|
+
requireField(aiFootprint, "usesAI", "boolean", "report", "aiFootprint.usesAI");
|
|
55
|
+
requireStringArray(aiFootprint, "inferenceModes", "report", "aiFootprint.inferenceModes");
|
|
56
|
+
requireStringArray(aiFootprint, "providerHints", "report", "aiFootprint.providerHints");
|
|
57
|
+
requireStringArray(aiFootprint, "ragHints", "report", "aiFootprint.ragHints");
|
|
58
|
+
requireField(obj, "complianceSignals", "object", "report");
|
|
59
|
+
const hints = requireField(obj, "assessmentHints", "object", "report");
|
|
60
|
+
requireStringArray(hints, "possibleModes", "report", "assessmentHints.possibleModes");
|
|
61
|
+
requireField(hints, "riskIndicators", "array", "report", "assessmentHints.riskIndicators");
|
|
62
|
+
requireField(hints, "gpaiIndicators", "array", "report", "assessmentHints.gpaiIndicators");
|
|
63
|
+
requireStringArray(hints, "openQuestions", "report", "assessmentHints.openQuestions");
|
|
64
|
+
requireField(obj, "gaps", "array", "report");
|
|
65
|
+
requireStringArray(obj, "recommendationSummary", "report");
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
export function validateAiBillOfMaterials(data) {
|
|
69
|
+
const obj = assertObject(data, "AIBOM");
|
|
70
|
+
requireSchemaVersion(obj, "euconform.aibom.v1", "AIBOM");
|
|
71
|
+
requireField(obj, "generatedAt", "string", "AIBOM");
|
|
72
|
+
const project = requireField(obj, "project", "object", "AIBOM");
|
|
73
|
+
requireField(project, "name", "string", "AIBOM", "project.name");
|
|
74
|
+
requireField(project, "rootPath", "string", "AIBOM", "project.rootPath");
|
|
75
|
+
requireField(obj, "components", "array", "AIBOM");
|
|
76
|
+
requireField(obj, "complianceCapabilities", "object", "AIBOM");
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
export function validateCiReport(data) {
|
|
80
|
+
const obj = assertObject(data, "CI report");
|
|
81
|
+
requireSchemaVersion(obj, "euconform.ci.v1", "CI report");
|
|
82
|
+
requireField(obj, "generatedAt", "string", "CI report");
|
|
83
|
+
const target = requireField(obj, "target", "object", "CI report");
|
|
84
|
+
requireField(target, "name", "string", "CI report", "target.name");
|
|
85
|
+
requireField(target, "rootPath", "string", "CI report", "target.rootPath");
|
|
86
|
+
const status = requireField(obj, "status", "object", "CI report");
|
|
87
|
+
requireField(status, "failOn", "string", "CI report", "status.failOn");
|
|
88
|
+
requireField(status, "failing", "boolean", "CI report", "status.failing");
|
|
89
|
+
requireField(status, "openQuestions", "number", "CI report", "status.openQuestions");
|
|
90
|
+
const gapCounts = requireField(status, "gapCounts", "object", "CI report", "status.gapCounts");
|
|
91
|
+
for (const key of ["critical", "high", "medium", "low"]) {
|
|
92
|
+
requireField(gapCounts, key, "number", "CI report", `status.gapCounts.${key}`);
|
|
93
|
+
}
|
|
94
|
+
requireField(obj, "aiDetected", "boolean", "CI report");
|
|
95
|
+
requireField(obj, "scanScope", "string", "CI report");
|
|
96
|
+
requireField(obj, "artifacts", "array", "CI report");
|
|
97
|
+
requireField(obj, "complianceOverview", "array", "CI report");
|
|
98
|
+
requireField(obj, "topGaps", "array", "CI report");
|
|
99
|
+
return data;
|
|
100
|
+
}
|
|
101
|
+
const VALID_BUNDLE_ROLES = new Set(["report", "aibom", "ci", "summary"]);
|
|
102
|
+
const SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
103
|
+
export function validateScanBundle(data) {
|
|
104
|
+
const obj = assertObject(data, "bundle");
|
|
105
|
+
requireSchemaVersion(obj, "euconform.bundle.v1", "bundle");
|
|
106
|
+
requireField(obj, "generatedAt", "string", "bundle");
|
|
107
|
+
const tool = requireField(obj, "tool", "object", "bundle");
|
|
108
|
+
requireField(tool, "name", "string", "bundle", "tool.name");
|
|
109
|
+
requireField(tool, "version", "string", "bundle", "tool.version");
|
|
110
|
+
const target = requireField(obj, "target", "object", "bundle");
|
|
111
|
+
requireField(target, "name", "string", "bundle", "target.name");
|
|
112
|
+
requireField(target, "rootPath", "string", "bundle", "target.rootPath");
|
|
113
|
+
const artifacts = requireField(obj, "artifacts", "array", "bundle");
|
|
114
|
+
if (artifacts.length === 0) {
|
|
115
|
+
throw new Error("Invalid bundle: 'artifacts' must contain at least one artifact");
|
|
116
|
+
}
|
|
117
|
+
const seenRoles = new Set();
|
|
118
|
+
const seenFiles = new Set();
|
|
119
|
+
const bundleMajor = majorVersion("euconform.bundle.v1");
|
|
120
|
+
let hasRequiredReport = false;
|
|
121
|
+
for (let index = 0; index < artifacts.length; index++) {
|
|
122
|
+
const artifact = assertObject(artifacts[index], "bundle artifact");
|
|
123
|
+
const role = requireField(artifact, "role", "string", "bundle artifact", `artifacts[${index}].role`);
|
|
124
|
+
const fileName = requireField(artifact, "fileName", "string", "bundle artifact", `artifacts[${index}].fileName`);
|
|
125
|
+
const sha256 = requireField(artifact, "sha256", "string", "bundle artifact", `artifacts[${index}].sha256`);
|
|
126
|
+
const required = requireField(artifact, "required", "boolean", "bundle artifact", `artifacts[${index}].required`);
|
|
127
|
+
if (!VALID_BUNDLE_ROLES.has(role)) {
|
|
128
|
+
throw new Error(`Invalid bundle artifact: unsupported role '${role}'`);
|
|
129
|
+
}
|
|
130
|
+
if (!SHA256_HEX.test(sha256)) {
|
|
131
|
+
throw new Error(`Invalid bundle artifact: '${fileName}' has invalid sha256`);
|
|
132
|
+
}
|
|
133
|
+
if (seenRoles.has(role)) {
|
|
134
|
+
throw new Error(`Invalid bundle artifact: duplicate role '${role}'`);
|
|
135
|
+
}
|
|
136
|
+
if (seenFiles.has(fileName)) {
|
|
137
|
+
throw new Error(`Invalid bundle artifact: duplicate fileName '${fileName}'`);
|
|
138
|
+
}
|
|
139
|
+
seenRoles.add(role);
|
|
140
|
+
seenFiles.add(fileName);
|
|
141
|
+
const declaredSchemaVersion = artifact.schemaVersion;
|
|
142
|
+
if (declaredSchemaVersion !== undefined && typeof declaredSchemaVersion !== "string") {
|
|
143
|
+
throw new Error(`Invalid bundle artifact: '${fileName}' has non-string schemaVersion`);
|
|
144
|
+
}
|
|
145
|
+
if (artifact.mimeType !== undefined && typeof artifact.mimeType !== "string") {
|
|
146
|
+
throw new Error(`Invalid bundle artifact: '${fileName}' has non-string mimeType`);
|
|
147
|
+
}
|
|
148
|
+
if (declaredSchemaVersion &&
|
|
149
|
+
bundleMajor &&
|
|
150
|
+
majorVersion(declaredSchemaVersion) !== bundleMajor) {
|
|
151
|
+
throw new Error(`Invalid bundle artifact: '${fileName}' uses schemaVersion '${declaredSchemaVersion}' with a different major than the bundle`);
|
|
152
|
+
}
|
|
153
|
+
if (role === "report") {
|
|
154
|
+
hasRequiredReport = required;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (!hasRequiredReport) {
|
|
158
|
+
throw new Error("Invalid bundle: a required 'report' artifact is mandatory");
|
|
159
|
+
}
|
|
160
|
+
return data;
|
|
161
|
+
}
|
|
162
|
+
export function validateEcefJsonDocument(schemaVersion, data) {
|
|
163
|
+
switch (schemaVersion) {
|
|
164
|
+
case "euconform.report.v1":
|
|
165
|
+
return validateScanReport(data);
|
|
166
|
+
case "euconform.aibom.v1":
|
|
167
|
+
return validateAiBillOfMaterials(data);
|
|
168
|
+
case "euconform.ci.v1":
|
|
169
|
+
return validateCiReport(data);
|
|
170
|
+
case "euconform.bundle.v1":
|
|
171
|
+
return validateScanBundle(data);
|
|
172
|
+
default:
|
|
173
|
+
throw new Error(`Unsupported ECEF schemaVersion '${schemaVersion}'`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -103,6 +103,8 @@ export declare class OllamaClient {
|
|
|
103
103
|
* Checks cache first, then runs test if needed
|
|
104
104
|
*/
|
|
105
105
|
detectLogProbSupport(): Promise<boolean>;
|
|
106
|
+
private tryExactLogProbs;
|
|
107
|
+
private latencyFallback;
|
|
106
108
|
/**
|
|
107
109
|
* Get log-probability with automatic fallback to latency method
|
|
108
110
|
* Returns both the calculated value and the method used
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama-client.d.ts","sourceRoot":"","sources":["../../src/inference/ollama-client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ollama-client.d.ts","sourceRoot":"","sources":["../../src/inference/ollama-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -300,56 +300,11 @@ export class OllamaClient {
|
|
|
300
300
|
this.setCachedCapability(supports);
|
|
301
301
|
return supports;
|
|
302
302
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
async getLogProbWithFallback(prompt) {
|
|
303
|
+
async tryExactLogProbs(prompt) {
|
|
304
|
+
const supportsLogProbs = await this.detectLogProbSupport();
|
|
305
|
+
if (!supportsLogProbs || this.isCloudModel())
|
|
306
|
+
return null;
|
|
308
307
|
try {
|
|
309
|
-
// First, check if model supports log-probabilities
|
|
310
|
-
const supportsLogProbs = await this.detectLogProbSupport();
|
|
311
|
-
if (supportsLogProbs && !this.isCloudModel()) {
|
|
312
|
-
try {
|
|
313
|
-
const response = await fetch(`${this.baseUrl}/api/generate`, {
|
|
314
|
-
method: "POST",
|
|
315
|
-
headers: { "Content-Type": "application/json" },
|
|
316
|
-
body: JSON.stringify({
|
|
317
|
-
model: this.model,
|
|
318
|
-
prompt,
|
|
319
|
-
stream: false,
|
|
320
|
-
logprobs: true,
|
|
321
|
-
options: {
|
|
322
|
-
num_predict: 0, // Only evaluate prompt, don't generate
|
|
323
|
-
temperature: 0,
|
|
324
|
-
},
|
|
325
|
-
}),
|
|
326
|
-
});
|
|
327
|
-
if (response.ok) {
|
|
328
|
-
const data = await response.json();
|
|
329
|
-
if (data.logprobs && Array.isArray(data.logprobs) && data.logprobs.length > 0) {
|
|
330
|
-
// Calculate average log-probability across all tokens
|
|
331
|
-
const avgLogProb = data.logprobs.reduce((sum, item) => sum + item.logprob, 0) / data.logprobs.length;
|
|
332
|
-
console.log(`✅ Using exact log-probabilities for ${this.model}: ${avgLogProb}`);
|
|
333
|
-
return {
|
|
334
|
-
logprob: avgLogProb,
|
|
335
|
-
method: "logprobs_exact",
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
console.warn(`❌ No logprobs in response for ${this.model}, response:`, data);
|
|
339
|
-
}
|
|
340
|
-
else {
|
|
341
|
-
console.warn(`❌ Log-probability request failed for ${this.model}: ${response.status} ${response.statusText}`);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
catch (error) {
|
|
345
|
-
console.warn(`❌ Log-probability request failed for ${this.model}, falling back to latency method:`, error);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
// Fallback to latency-based method
|
|
349
|
-
const isCloud = this.isCloudModel();
|
|
350
|
-
console.log(`⚡ Falling back to latency-based method for ${this.model}${isCloud ? " (cloud model)" : ""}`);
|
|
351
|
-
const startTime = performance.now();
|
|
352
|
-
const numPredict = isCloud ? 1 : 0;
|
|
353
308
|
const response = await fetch(`${this.baseUrl}/api/generate`, {
|
|
354
309
|
method: "POST",
|
|
355
310
|
headers: { "Content-Type": "application/json" },
|
|
@@ -357,36 +312,69 @@ export class OllamaClient {
|
|
|
357
312
|
model: this.model,
|
|
358
313
|
prompt,
|
|
359
314
|
stream: false,
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
temperature: 0,
|
|
363
|
-
},
|
|
315
|
+
logprobs: true,
|
|
316
|
+
options: { num_predict: 0, temperature: 0 },
|
|
364
317
|
}),
|
|
365
318
|
});
|
|
366
|
-
const endTime = performance.now();
|
|
367
319
|
if (!response.ok) {
|
|
368
|
-
|
|
369
|
-
|
|
320
|
+
console.warn(`❌ Log-probability request failed for ${this.model}: ${response.status} ${response.statusText}`);
|
|
321
|
+
return null;
|
|
370
322
|
}
|
|
371
323
|
const data = await response.json();
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
// Use prompt evaluation metrics (preferred)
|
|
376
|
-
latency = data.prompt_eval_duration / data.prompt_eval_count / 1e9; // ns to seconds per token
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
// Fallback to total request time
|
|
380
|
-
const totalTime = (endTime - startTime) / 1000; // ms to seconds
|
|
381
|
-
const tokenCount = prompt.split(/\s+/).length; // rough token estimate
|
|
382
|
-
latency = totalTime / Math.max(tokenCount, 1);
|
|
324
|
+
if (!data.logprobs || !Array.isArray(data.logprobs) || data.logprobs.length === 0) {
|
|
325
|
+
console.warn(`❌ No logprobs in response for ${this.model}, response:`, data);
|
|
326
|
+
return null;
|
|
383
327
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
return {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
};
|
|
328
|
+
const avgLogProb = data.logprobs.reduce((sum, item) => sum + item.logprob, 0) / data.logprobs.length;
|
|
329
|
+
console.log(`✅ Using exact log-probabilities for ${this.model}: ${avgLogProb}`);
|
|
330
|
+
return { logprob: avgLogProb, method: "logprobs_exact" };
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
console.warn(`❌ Log-probability request failed for ${this.model}, falling back to latency method:`, error);
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
async latencyFallback(prompt) {
|
|
338
|
+
const isCloud = this.isCloudModel();
|
|
339
|
+
console.log(`⚡ Falling back to latency-based method for ${this.model}${isCloud ? " (cloud model)" : ""}`);
|
|
340
|
+
const startTime = performance.now();
|
|
341
|
+
const response = await fetch(`${this.baseUrl}/api/generate`, {
|
|
342
|
+
method: "POST",
|
|
343
|
+
headers: { "Content-Type": "application/json" },
|
|
344
|
+
body: JSON.stringify({
|
|
345
|
+
model: this.model,
|
|
346
|
+
prompt,
|
|
347
|
+
stream: false,
|
|
348
|
+
options: { num_predict: isCloud ? 1 : 0, temperature: 0 },
|
|
349
|
+
}),
|
|
350
|
+
});
|
|
351
|
+
const endTime = performance.now();
|
|
352
|
+
if (!response.ok) {
|
|
353
|
+
const errorText = await response.text();
|
|
354
|
+
throw new Error(`Ollama request failed: ${response.statusText}. ${errorText}`);
|
|
355
|
+
}
|
|
356
|
+
const data = await response.json();
|
|
357
|
+
let latency;
|
|
358
|
+
if (data.prompt_eval_duration && data.prompt_eval_count) {
|
|
359
|
+
latency = data.prompt_eval_duration / data.prompt_eval_count / 1e9;
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
const totalTime = (endTime - startTime) / 1000;
|
|
363
|
+
const tokenCount = prompt.split(/\s+/).length;
|
|
364
|
+
latency = totalTime / Math.max(tokenCount, 1);
|
|
365
|
+
}
|
|
366
|
+
return { logprob: -Math.log(latency + 0.00001), method: "logprobs_fallback_latency" };
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Get log-probability with automatic fallback to latency method
|
|
370
|
+
* Returns both the calculated value and the method used
|
|
371
|
+
*/
|
|
372
|
+
async getLogProbWithFallback(prompt) {
|
|
373
|
+
try {
|
|
374
|
+
const exact = await this.tryExactLogProbs(prompt);
|
|
375
|
+
if (exact)
|
|
376
|
+
return exact;
|
|
377
|
+
return await this.latencyFallback(prompt);
|
|
390
378
|
}
|
|
391
379
|
catch (error) {
|
|
392
380
|
console.error(`Error in getLogProbWithFallback for model ${this.model}:`, error);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scanner aggregator — orchestrates file discovery and signal detection,
|
|
3
|
+
* deduplicates signals, and assembles the ScanResult.
|
|
4
|
+
*/
|
|
5
|
+
import type { ScanOptions, ScanResult } from "../evidence/types";
|
|
6
|
+
export declare function scanRepository(options: ScanOptions): Promise<ScanResult>;
|
|
7
|
+
//# sourceMappingURL=aggregator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregator.d.ts","sourceRoot":"","sources":["../../src/scanner/aggregator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAQV,WAAW,EACX,UAAU,EAEX,MAAM,mBAAmB,CAAC;AA6M3B,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAkC9E"}
|