deepbom 1.97.3 → 1.98.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/README.md +6 -6
- package/bin/deepbom.mjs +111 -86
- package/package.json +1 -1
- package/pkg/release-manifest.json +4 -4
- package/pkg/tflite_wasm_audit_bg.wasm +0 -0
- package/skills/deepbom/SKILL.md +34 -20
- package/skills/deepbom/references/capability-selection.md +4 -1
- package/skills/deepbom/references/failure-recovery.md +1 -0
- package/skills/deepbom/scripts/verify-deepbom.mjs +65 -13
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "deepbom.npm_release.v1",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.98.0",
|
|
4
4
|
"source": {
|
|
5
|
-
"git_commit": "
|
|
5
|
+
"git_commit": "46636ebe3cfdd43fcd782178862073ecbdd5c760",
|
|
6
6
|
"git_state": "clean",
|
|
7
7
|
"distribution": "public_channel"
|
|
8
8
|
},
|
|
9
9
|
"runtime": {
|
|
10
10
|
"node": ">=20",
|
|
11
|
-
"tflite_wasm_sha256": "
|
|
11
|
+
"tflite_wasm_sha256": "bcc9e81d9d7929d29b6e510328eb840af3c0e66387c350dc02b7282271dded87",
|
|
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":
|
|
21
|
+
"public_bundle_input_count": 169,
|
|
22
22
|
"supported_inputs": [
|
|
23
23
|
"tflite",
|
|
24
24
|
"onnx",
|
|
Binary file
|
package/skills/deepbom/SKILL.md
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: deepbom
|
|
3
|
-
description: Statically audit serialized AI
|
|
3
|
+
description: Statically audit serialized AI model artifacts with the local DEEPBOM CLI. Use for TFLite, ONNX, Core ML, ExecuTorch, GGUF, or SafeTensors deployment review; bounded GraphDef, SavedModel, Keras-config, or PT2 declarative structure; HDF5 or PyTorch-checkpoint safe-envelope inspection; quantization, memory, diff, verification, graph, Model IR, monochrome document views, SARIF, or CycloneDX 1.7 output. Do not treat checkpoint envelopes as executable graphs or claim measured latency, task accuracy, safety, regulatory approval, standards conformance, or actual runtime placement without the required external evidence.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Audit deployment artifacts with DEEPBOM
|
|
7
7
|
|
|
8
|
-
Run DEEPBOM locally. Never upload artifact bytes or invent a hosted DEEPBOM endpoint.
|
|
8
|
+
Run DEEPBOM locally for files in the workspace. Never upload artifact bytes or invent a hosted DEEPBOM endpoint. A separately connected ChatGPT integration may analyze one authorized attachment in its browser sandbox; that is a different execution boundary.
|
|
9
|
+
|
|
10
|
+
## Resolve a verified runtime first
|
|
11
|
+
|
|
12
|
+
Run `scripts/verify-deepbom.mjs` from this Skill directory before choosing an invocation. It checks, in order, `DEEPBOM_BIN`, the analyzer bundled with an npm installation, and an exact-version `deepbom` already on `PATH`. It does not access a package registry by default.
|
|
13
|
+
|
|
14
|
+
If no exact local installation is available, ask before running:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
node "<skill-root>/scripts/verify-deepbom.mjs" --allow-download
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
That explicit fallback may download `deepbom@1.98.0` through npm. Use the returned `invocation.command` and `invocation.prefix_args` for subsequent commands. Do not silently replace a version mismatch or network failure with an unverified executable.
|
|
9
21
|
|
|
10
22
|
## Start with discovery
|
|
11
23
|
|
|
12
|
-
|
|
24
|
+
After resolving the exact release pinned by this Skill, discover its machine contract:
|
|
13
25
|
|
|
14
26
|
```bash
|
|
15
|
-
|
|
27
|
+
deepbom capabilities --format agent-json
|
|
16
28
|
```
|
|
17
29
|
|
|
18
30
|
Treat that machine document as authoritative for commands, supported inputs, scan modes, targets, outputs, and exit codes. Read `references/capability-selection.md` when deciding whether the task belongs to DEEPBOM.
|
|
@@ -22,15 +34,15 @@ Treat that machine document as authoritative for commands, supported inputs, sca
|
|
|
22
34
|
Start with the bounded human result:
|
|
23
35
|
|
|
24
36
|
```bash
|
|
25
|
-
|
|
37
|
+
deepbom audit "./model.onnx" --summary
|
|
26
38
|
```
|
|
27
39
|
|
|
28
40
|
Then request only the evidence needed by the question:
|
|
29
41
|
|
|
30
42
|
```bash
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
43
|
+
deepbom audit "./model.onnx" --section quantization --json
|
|
44
|
+
deepbom audit "./model.onnx" --pointer /mac_assessment --json
|
|
45
|
+
deepbom audit "./model.onnx" --output-format envelope
|
|
34
46
|
```
|
|
35
47
|
|
|
36
48
|
For a large GGUF or SafeTensors artifact, use `--scan structure` for inventory questions. Use `integrity` or `full` only when payload evidence is necessary.
|
|
@@ -38,15 +50,15 @@ For a large GGUF or SafeTensors artifact, use `--scan structure` for inventory q
|
|
|
38
50
|
For a concise GGUF tensor table without nested numerical-integrity ledgers, use the bounded projection (it defaults to a structure scan):
|
|
39
51
|
|
|
40
52
|
```bash
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
deepbom gguf "./model.gguf" --tensors
|
|
54
|
+
deepbom gguf "./model.gguf" --tensors --compact
|
|
55
|
+
deepbom gguf "./model.gguf" --tensors --compact --tensor-offset 100 --tensor-limit 100
|
|
44
56
|
```
|
|
45
57
|
|
|
46
|
-
Before relying on
|
|
58
|
+
Before relying on any resolved installation, run:
|
|
47
59
|
|
|
48
60
|
```bash
|
|
49
|
-
|
|
61
|
+
deepbom self-test --compact
|
|
50
62
|
```
|
|
51
63
|
|
|
52
64
|
## Interpret the result
|
|
@@ -68,15 +80,17 @@ Never infer actual accelerator assignment, latency, energy, thermal behavior, ta
|
|
|
68
80
|
## Compare or explain
|
|
69
81
|
|
|
70
82
|
```bash
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
deepbom diff "./baseline.onnx" "./candidate.onnx" --summary
|
|
84
|
+
deepbom diff "./baseline.gguf" "./candidate.gguf" --tensors --render markdown
|
|
85
|
+
deepbom verify "./model.onnx" --bom "./supplied.cdx.json" --render markdown
|
|
86
|
+
deepbom contract capture "./model.onnx" -o "./baseline.interface-contract.json"
|
|
87
|
+
deepbom explain-rule <rule-id> --json
|
|
88
|
+
deepbom graph "./model.onnx" --view structure --format svg -o graph.svg
|
|
89
|
+
deepbom audit "./model.onnx" --section model_ir --compact
|
|
90
|
+
deepbom visualize "./model.onnx" --view all --orientation portrait -o model-views.zip
|
|
77
91
|
```
|
|
78
92
|
|
|
79
|
-
Use matching serialized deployment formats for diff. Treat `verify --bom` as a reconciliation of the selected component with artifact-observable facts, not a complete BOM or compliance verdict. An automatically captured contract is an artifact-derived baseline until it is separately reviewed and approved. Do not deserialize `.pth`, `.pt`, or `.h5`; bind a conversion receipt to the deployed artifact
|
|
93
|
+
Use matching serialized deployment formats for diff. Treat `verify --bom` as a reconciliation of the selected component with artifact-observable facts, not a complete BOM or compliance verdict. An automatically captured contract is an artifact-derived baseline until it is separately reviewed and approved. `model_ir` and `visualize` are preview engineering projections whose loss ledger and evidence classes must be preserved. Do not deserialize `.pth`, `.pt`, or `.h5`; use only the safe envelope and bind a conversion receipt to the deployed artifact when lineage is needed.
|
|
80
94
|
|
|
81
95
|
## Handle failure
|
|
82
96
|
|
|
@@ -6,11 +6,14 @@ Use DEEPBOM when the subject is a serialized deployment artifact and the questio
|
|
|
6
6
|
| --- | --- | --- |
|
|
7
7
|
| TFLite, ONNX, Core ML, or ExecuTorch graph and tensor audit | Yes | Static artifact evidence only |
|
|
8
8
|
| GGUF or SafeTensors storage, quantization, architecture, or memory lower bound | Yes | No executable graph is invented |
|
|
9
|
+
| GraphDef, first-MetaGraph SavedModel, Keras config, or PT2 declarative dependency review | Yes, preview | Only serialized bounded relationships; no framework construction or runtime-order claim |
|
|
10
|
+
| HDF5 or PyTorch checkpoint identity/archive/risk envelope | Yes, preview | No HDF5 object graph, checkpoint objects, tensor semantics, or executable graph claimed |
|
|
11
|
+
| Common Model IR or monochrome A4 engineering views | Yes, preview | Preserve source refs, evidence class, applicability, and loss ledger; no conformance or regulatory verdict |
|
|
9
12
|
| MAC and symbolic shape coverage | Yes | Preserve partial or symbolic status |
|
|
10
13
|
| Quantization contract review | Yes | Do not infer task accuracy |
|
|
11
14
|
| Accelerator eligibility or selected-build evidence | Yes | Eligibility is not observed assignment |
|
|
12
15
|
| Artifact version diff | Yes | Inputs must use the same supported format |
|
|
13
|
-
| PyTorch or HDF5 training checkpoint execution | No | Convert safely and bind a conversion receipt |
|
|
16
|
+
| PyTorch or HDF5 training checkpoint execution or full model interpretation | No | Convert safely and bind a conversion receipt |
|
|
14
17
|
| Measured latency, energy, temperature, or accuracy | No | Import runtime evidence or use the appropriate benchmark system |
|
|
15
18
|
|
|
16
19
|
Prefer `summary` first. Request an envelope for cross-format automation, format-specific JSON for a narrow field, SARIF for CI findings, or CycloneDX 1.7 for supply-chain exchange.
|
|
@@ -7,3 +7,4 @@
|
|
|
7
7
|
5. For remote input, require an immutable identity: a full Hugging Face commit, GCS object generation, or HTTPS SHA-256 fragment.
|
|
8
8
|
6. Do not raise download, response, or memory limits without explaining the cost and obtaining user approval.
|
|
9
9
|
7. If no shell, local MCP, or local file access exists, explain that actual analysis cannot run in that client and provide the pinned `npx` command.
|
|
10
|
+
8. Registry download is opt-in. Prefer a verified exact-version installation; use `npx -y deepbom@1.98.0` only after network and installation permission is clear.
|
|
@@ -1,19 +1,71 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
4
8
|
|
|
5
|
-
const VERSION = "1.
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const VERSION = "1.98.0";
|
|
10
|
+
const allowDownload = process.argv.slice(2).includes("--allow-download");
|
|
11
|
+
const attempts = [];
|
|
12
|
+
const candidates = localCandidates();
|
|
13
|
+
if (allowDownload) candidates.push({ source: "npm_exact_version", command: process.platform === "win32" ? "npx.cmd" : "npx", prefix_args: ["-y", `deepbom@${VERSION}`], network: true });
|
|
14
|
+
|
|
15
|
+
for (const candidate of candidates) {
|
|
16
|
+
const versionRun = invoke(candidate, ["--version"]);
|
|
17
|
+
if (versionRun.status !== 0 || versionRun.stdout.trim() !== VERSION) {
|
|
18
|
+
attempts.push({ source: candidate.source, status: versionRun.status, observed_version: versionRun.stdout.trim() || null, error: bounded(versionRun.stderr) });
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const selfTest = invoke(candidate, ["self-test", "--compact"]);
|
|
22
|
+
try {
|
|
23
|
+
const document = JSON.parse(selfTest.stdout);
|
|
24
|
+
if (selfTest.status !== 0 || document.schema !== "deepbom.cli_self_test.v1" || document.status !== "pass" || document.version !== VERSION) throw new Error("self-test contract mismatch");
|
|
25
|
+
process.stdout.write(`${JSON.stringify({ schema: "deepbom.skill_runtime_resolution.v1", version: VERSION, status: "pass", source: candidate.source, network_used: candidate.network, invocation: { command: candidate.command, prefix_args: candidate.prefix_args }, self_test: document })}\n`);
|
|
26
|
+
process.exit(0);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
attempts.push({ source: candidate.source, status: selfTest.status, error: bounded(selfTest.stderr || selfTest.stdout || error.message) });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
process.stderr.write(`${JSON.stringify({ schema: "deepbom.skill_runtime_resolution.v1", version: VERSION, status: "unavailable", registry_download_attempted: allowDownload, attempts, suggested_action: allowDownload ? "Review the recorded installation or network error; do not claim an analysis ran." : "Install the exact release or rerun with --allow-download only after registry access is authorized." })}\n`);
|
|
33
|
+
process.exit(3);
|
|
34
|
+
|
|
35
|
+
function localCandidates() {
|
|
36
|
+
const rows = [];
|
|
37
|
+
if (process.env.DEEPBOM_BIN?.trim()) rows.push(candidateForPath(path.resolve(process.env.DEEPBOM_BIN.trim()), "DEEPBOM_BIN"));
|
|
38
|
+
const packaged = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../../bin/deepbom.mjs");
|
|
39
|
+
if (existsSync(packaged)) rows.push(candidateForPath(packaged, "bundled_npm_package"));
|
|
40
|
+
const installed = findOnPath("deepbom");
|
|
41
|
+
if (installed && !rows.some((row) => path.resolve(row.identity) === path.resolve(installed))) rows.push(candidateForPath(installed, "installed_path"));
|
|
42
|
+
return rows;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function candidateForPath(file, source) {
|
|
46
|
+
return /\.(?:mjs|js|cjs)$/i.test(file)
|
|
47
|
+
? { source, identity: file, command: process.execPath, prefix_args: [file], network: false }
|
|
48
|
+
: { source, identity: file, command: file, prefix_args: [], network: false };
|
|
14
49
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
50
|
+
|
|
51
|
+
function findOnPath(name) {
|
|
52
|
+
const extensions = process.platform === "win32" ? (process.env.PATHEXT || ".EXE;.CMD;.BAT").split(";") : [""];
|
|
53
|
+
for (const directory of (process.env.PATH || "").split(path.delimiter).filter(Boolean)) {
|
|
54
|
+
for (const extension of extensions) {
|
|
55
|
+
const file = path.join(directory.replace(/^"|"$/g, ""), process.platform === "win32" ? `${name}${extension.toLowerCase()}` : name);
|
|
56
|
+
if (existsSync(file)) return file;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function invoke(candidate, args) {
|
|
63
|
+
const shell = process.platform === "win32" && /\.(?:cmd|bat)$/i.test(candidate.command);
|
|
64
|
+
const result = spawnSync(candidate.command, [...candidate.prefix_args, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], shell, timeout: 120000, windowsHide: true });
|
|
65
|
+
return { status: Number.isInteger(result.status) ? result.status : 1, stdout: result.stdout || "", stderr: result.stderr || result.error?.message || "" };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function bounded(value) {
|
|
69
|
+
const text = String(value || "").trim();
|
|
70
|
+
return text ? text.slice(0, 1000) : null;
|
|
18
71
|
}
|
|
19
|
-
process.stdout.write(`${JSON.stringify(document)}\n`);
|