deepbom 2.1.0 → 2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepbom",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "mcpName": "io.github.JunHwan-Kwon/deepbom",
5
5
  "description": "Local multi-format deployment-artifact analysis for on-device AI models",
6
6
  "type": "module",
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "schema": "deepbom.npm_release.v1",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "source": {
5
- "git_commit": "b161cd4c383e1133e97200a04c8459935f4c7d97",
5
+ "git_commit": "77f8caeac9381b947cd159beedb96d97ad9e1e96",
6
6
  "git_state": "clean",
7
7
  "distribution": "public_channel"
8
8
  },
9
9
  "runtime": {
10
10
  "node": ">=20",
11
- "tflite_wasm_sha256": "7a562be6d5daa3df1b8f5dd4d15fd2c05eae715eb805f9c99b2287294fc352ee",
11
+ "tflite_wasm_sha256": "dc46e597ad916c9023b6328949de0dfeed1bb4e98f15937a0caeec2f6766bd70",
12
12
  "self_test": {
13
13
  "file": "bin/deepbom-self-test.onnx",
14
14
  "sha256": "82a2feef00eb6ab03d82f2b30cd17f4d826e2d8307cb059eccd6a0f3120059b2"
@@ -18,7 +18,7 @@
18
18
  "spdx": "Apache-2.0",
19
19
  "file": "LICENSE"
20
20
  },
21
- "public_bundle_input_count": 204,
21
+ "public_bundle_input_count": 228,
22
22
  "supported_inputs": [
23
23
  "tflite",
24
24
  "onnx",
Binary file
package/sdk/index.d.mts CHANGED
@@ -11,6 +11,29 @@ export interface AuditOptions extends InspectOptions {
11
11
  output?: "analysis" | "envelope" | "cyclonedx" | "sarif";
12
12
  sections?: string[];
13
13
  }
14
+ export interface NumericalEvidenceOptions extends Limits {
15
+ weights?: boolean;
16
+ weightBaseline?: string;
17
+ weightOptions?: string;
18
+ weightMapping?: string;
19
+ activationCapture?: string;
20
+ activationBaseline?: string;
21
+ expectedSha256?: string;
22
+ }
23
+ /** A selection of native numerical documents; no automatic model execution. */
24
+ export interface NumericalEvidenceResult extends JsonDocument {
25
+ schema: "deepbom.analysis_selection.v1";
26
+ sections: {
27
+ model_ir: JsonDocument;
28
+ numerical_evidence_bundle: JsonDocument;
29
+ numerical_details: JsonDocument & { schema: "deepbom.numerical_details.v1"; numerical_details_sha256: string };
30
+ weight_ir?: JsonDocument;
31
+ weight_analysis?: JsonDocument;
32
+ weight_comparison?: JsonDocument;
33
+ activation_ir?: JsonDocument;
34
+ activation_baseline_ir?: JsonDocument;
35
+ };
36
+ }
14
37
  export interface Finding extends JsonDocument {
15
38
  id: string; title: string; severity: string; evidence_class: string;
16
39
  source_pointers: string[]; recommendation: string | null;
@@ -53,6 +76,7 @@ export class DeepBomIdentityMismatch extends DeepBomError {}
53
76
  export class DeepBomTimeout extends DeepBomError {}
54
77
  export class DeepBomOutputTooLarge extends DeepBomError {}
55
78
  export function capabilities(options?: Limits): Promise<JsonDocument>;
79
+ export function numericalEvidence(artifact: string, options: NumericalEvidenceOptions): Promise<NumericalEvidenceResult>;
56
80
  export function inspect(artifact: string, options?: InspectOptions): Promise<ReviewSummary>;
57
81
  export function audit(artifact: string, options?: InspectOptions & { output?: "envelope"; sections?: never }): Promise<EvidenceEnvelope>;
58
82
  export function audit(artifact: string, options: AuditOptions): Promise<JsonDocument>;
@@ -60,3 +84,18 @@ export function diff(baseline: string, candidate: string, options?: Limits & { t
60
84
  export function captureContract(artifact: string, options?: Limits): Promise<JsonDocument>;
61
85
  export function verifyContract(artifact: string, contract: string, options?: Limits): Promise<JsonDocument>;
62
86
  export function verifyBom(artifact: string, bom: string, options?: Limits & { componentRef?: string }): Promise<JsonDocument>;
87
+
88
+ export interface EvidenceWorkflowRequest extends JsonDocument {
89
+ schema: "deepbom.evidence_workflow_request.v1";
90
+ operation: "snapshot" | "omop" | "protocol" | "evaluation" | "provenance" | "review" | "deployment" | "verify";
91
+ input: JsonDocument;
92
+ documents: JsonDocument[];
93
+ }
94
+ export interface EvidenceWorkflowResult extends JsonDocument {
95
+ schema: "deepbom.evidence_workflow_result.v1";
96
+ result_sha256: string;
97
+ document: JsonDocument;
98
+ request: EvidenceWorkflowRequest;
99
+ execution_status: "completed";
100
+ }
101
+ export function evidenceWorkflow(request: EvidenceWorkflowRequest | EvidenceWorkflowResult, options?: Limits & {files?: {sha256:string;path:string}[]}): Promise<EvidenceWorkflowResult>;
package/sdk/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /** Public Node SDK. All analysis and policy evaluation run in the packaged CLI. */
2
2
  import { spawn } from "node:child_process";
3
- import { mkdtemp, readFile, rm, stat } from "node:fs/promises";
3
+ import { mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
4
4
  import { tmpdir } from "node:os";
5
5
  import path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
@@ -68,6 +68,31 @@ export async function diff(baseline, candidate, options = {}) {
68
68
  return invoke(["diff", localPath(baseline), localPath(candidate), "--compact", ...(options.tensorsOnly ? ["--tensors"] : [])], options);
69
69
  }
70
70
 
71
+ /** Explicit numerical inspection of stored weights and/or imported captures. */
72
+ export async function numericalEvidence(artifact, options = {}) {
73
+ checkOptions(options, [...limitKeys, "weights", "weightBaseline", "weightOptions", "weightMapping", "activationCapture", "activationBaseline", "expectedSha256"]);
74
+ if (options.weights != null && typeof options.weights !== "boolean") throw new TypeError("weights must be boolean");
75
+ const weights = options.weights === true || ["weightBaseline", "weightOptions", "weightMapping"].some(key => options[key] != null);
76
+ if (!weights && options.activationCapture == null) throw new TypeError("Select weights or provide activationCapture");
77
+ if (options.activationBaseline != null && options.activationCapture == null) throw new TypeError("activationBaseline requires activationCapture");
78
+ if (options.weightMapping != null && options.weightBaseline == null) throw new TypeError("weightMapping requires weightBaseline");
79
+ const argv = ["audit", localPath(artifact), "--compact"];
80
+ const sections = ["model_ir", "numerical_evidence_bundle", "numerical_details"];
81
+ if (weights) { argv.push("--weight-analysis"); sections.push("weight_ir", "weight_analysis"); }
82
+ if (options.weightBaseline != null) sections.push("weight_comparison");
83
+ if (options.activationCapture != null) sections.push("activation_ir");
84
+ if (options.activationBaseline != null) sections.push("activation_baseline_ir");
85
+ for (const [key, flag] of Object.entries({ weightBaseline: "--weight-baseline", weightOptions: "--weight-options", weightMapping: "--weight-mapping", activationCapture: "--activation-evidence", activationBaseline: "--activation-baseline" })) {
86
+ if (options[key] != null) argv.push(flag, localPath(options[key]));
87
+ }
88
+ if (options.expectedSha256 != null) {
89
+ if (typeof options.expectedSha256 !== "string" || !/^[0-9a-f]{64}$/i.test(options.expectedSha256)) throw new TypeError("expectedSha256 must contain 64 hexadecimal characters");
90
+ argv.push("--expected-sha256", options.expectedSha256.toLowerCase());
91
+ }
92
+ argv.push("--section", sections.join(","));
93
+ return invoke(argv, options);
94
+ }
95
+
71
96
  export async function captureContract(artifact, options = {}) {
72
97
  checkOptions(options, limitKeys);
73
98
  return invoke(["contract", "capture", localPath(artifact), "--compact"], options);
@@ -170,3 +195,21 @@ async function invoke(argv, options) {
170
195
  }
171
196
  }
172
197
  }
198
+
199
+ /** The request and result contracts are shared with browser workers and MCP. */
200
+ export async function evidenceWorkflow(request, options = {}) {
201
+ checkOptions(options, [...limitKeys, "files"]);
202
+ if (!request || typeof request !== "object" || Array.isArray(request)) throw new TypeError("request must be a document");
203
+ const directory=await mkdtemp(path.join(tmpdir(),"deepbom-evidence-"));
204
+ try {
205
+ const filename=path.join(directory,"request.json");
206
+ const text=JSON.stringify(request);if(Buffer.byteLength(text)>16*1024*1024)throw new TypeError("Request exceeds 16 MiB");
207
+ await writeFile(filename,text,{mode:0o600});
208
+ const argv=["evidence-workflow",filename];
209
+ if(options.files!==undefined){
210
+ if(!Array.isArray(options.files)||options.files.length>256)throw new TypeError("files must be a bounded list");
211
+ for(const f of options.files){if(!f||Object.keys(f).some(k=>!["sha256","path"].includes(k))||!/^[a-f0-9]{64}$/.test(f.sha256))throw new TypeError("File needs sha256 and local path");argv.push("--file",f.sha256+":"+localPath(f.path));}
212
+ }
213
+ return await invoke(argv,options);
214
+ } finally { await rm(directory,{recursive:true,force:true}); }
215
+ }