deadbyte-mcp 0.15.21 → 0.15.23

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 (54) hide show
  1. package/MANIFEST.SHA256 +53 -28
  2. package/PROVENANCE.json +10 -10
  3. package/README.txt +18 -7
  4. package/RELEASE.json +51 -16
  5. package/SBOM.cdx.json +33 -7
  6. package/TEST-MATRIX.json +95 -18
  7. package/bin/deadbyte-hardware-observer-r45.exe +0 -0
  8. package/bin/deadbyte-hardware-observer-r45.obj +0 -0
  9. package/docs/R48-FULL-TOOL-CATALOG.json +124 -0
  10. package/native/deadbyte-hardware-observer.cpp +535 -12
  11. package/package.json +95 -93
  12. package/scripts/activate-skill-creator-1.1.1.mjs +46 -0
  13. package/scripts/build-advanced-pcb-skill.mjs +208 -0
  14. package/scripts/build-hardware-r45.ps1 +19 -0
  15. package/scripts/diagnose-skill-tree.mjs +8 -0
  16. package/scripts/full-regression-r48-batch.mjs +27 -0
  17. package/scripts/npm-release-r48.mjs +252 -0
  18. package/scripts/pcb-skill-src-SKILL.md.txt +67 -0
  19. package/scripts/pcb-skill-src-bringup-evidence.md.txt +22 -0
  20. package/scripts/pcb-skill-src-constraint-model.md.txt +17 -0
  21. package/scripts/pcb-skill-src-emc-mechanical-dfm.md.txt +17 -0
  22. package/scripts/pcb-skill-src-high-speed-layout.md.txt +27 -0
  23. package/scripts/pcb-skill-src-kicad-native.md.txt +30 -0
  24. package/scripts/pcb-skill-src-kicad_pcb_probe.py.txt +159 -0
  25. package/scripts/pcb-skill-src-pcb_constraint_gate.py.txt +76 -0
  26. package/scripts/pcb-skill-src-power-integrity.md.txt +15 -0
  27. package/scripts/prepare-skill-creator-1.1.1.mjs +113 -0
  28. package/scripts/promote-local-c-generation.ps1 +217 -0
  29. package/scripts/promote-local-d-generation.ps1 +217 -0
  30. package/scripts/test-r48-post-bump.ps1 +8 -0
  31. package/scripts/test-r48-windows-observation.ps1 +8 -0
  32. package/scripts/test-skill-creator-semver-matrix.mjs +30 -0
  33. package/scripts/test-skill-creator-semver.mjs +22 -0
  34. package/src/capability-ledger.mjs +7 -0
  35. package/src/capability-resolver.mjs +7 -0
  36. package/src/compact-gateway-mcp-tools.mjs +16 -2
  37. package/src/deadbyte-cli.mjs +70 -15
  38. package/src/machine-fs.mjs +16 -3
  39. package/src/observation-mcp-tools.mjs +13 -1
  40. package/src/observation-output-contracts.mjs +8 -0
  41. package/src/observation-runtime.mjs +54 -2
  42. package/src/remote-live-log.mjs +189 -35
  43. package/src/tool-audit.mjs +1 -1
  44. package/src/version.mjs +1 -1
  45. package/test/full-max-catalog-r47.test.mjs +1 -1
  46. package/test/full-max-catalog-r48.test.mjs +78 -0
  47. package/test/machine-fs-runtime.test.mjs +28 -3
  48. package/test/observation-mcp-tools.test.mjs +4 -3
  49. package/test/r48-release-contract.test.mjs +24 -14
  50. package/test/remote-live-log-r37.test.mjs +106 -7
  51. package/test/remote-session-cli.test.mjs +40 -0
  52. package/test/tool-audit.test.mjs +17 -0
  53. package/test/windows-observation-r48.test.mjs +63 -0
  54. package/test/windows-observation-surface-r48.test.mjs +70 -0
package/package.json CHANGED
@@ -1,93 +1,95 @@
1
- {
2
- "name": "deadbyte-mcp",
3
- "version": "0.15.21",
4
- "private": false,
5
- "type": "module",
6
- "description": "Authenticated MCP agentic runtime with signed skills, persistent model backends, identity-bound remote devices, durable job supervision, immutable release slots, and separately revocable machine authority.",
7
- "engines": {
8
- "node": ">=22"
9
- },
10
- "scripts": {
11
- "test": "node --test test/*.test.mjs",
12
- "manifest:write": "node scripts/release-manifest.mjs write",
13
- "manifest:verify": "node scripts/release-manifest.mjs verify",
14
- "r41:parent:verify": "node scripts/verify-r41-parent.mjs",
15
- "r41:memory:verify": "node scripts/verify-memory-r41.mjs",
16
- "r42:parent:verify": "node scripts/verify-r42-parent.mjs",
17
- "r42:eval": "node scripts/agent-eval-r42.mjs",
18
- "self-update:runtime": "node scripts/runtime-self-update.mjs",
19
- "self-update:deferred": "node scripts/deferred-slot-operation-r46.mjs",
20
- "release:parity": "node scripts/release-parity-r46.mjs",
21
- "release:final:write": "node scripts/final-closure-r46.mjs",
22
- "release:final:verify": "node scripts/final-closure-verify-r46.mjs",
23
- "proof": "node src/proof-cli.mjs workspaces/demo input.txt",
24
- "verify": "node src/verifier-cli.mjs workspaces/demo evidence/latest.json",
25
- "trust:init": "node src/trust-init.mjs",
26
- "mcp": "node src/mcp-server.mjs",
27
- "mcp:smoke": "node src/mcp-smoke-client.mjs",
28
- "mcp:agent:smoke": "node --test test/agent-runtime.test.mjs test/agent-runtime-adversarial.test.mjs test/agent-runtime-crash.test.mjs test/agent-task-receipt.test.mjs",
29
- "mcp:coding:smoke": "node --test test/coding-plane.test.mjs test/coding-plane-adversarial.test.mjs test/coding-runtime.test.mjs test/coding-crash.test.mjs",
30
- "mcp:machine-fs:smoke": "node src/machine-fs-smoke-client.mjs",
31
- "mcp:observation:smoke": "node src/observation-smoke-client.mjs",
32
- "mcp:process:smoke": "node src/process-smoke-client.mjs",
33
- "process:policy:refresh": "node scripts/refresh-process-policy.mjs",
34
- "mcp:autonomous:smoke": "node --test test/autonomous-runtime.test.mjs test/autonomous-loop.test.mjs test/autonomous-adversarial.test.mjs test/autonomous-supervisor-integration.test.mjs test/native-diff.test.mjs",
35
- "containment:build": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-containment.ps1",
36
- "containment:smoke": "node src/containment-smoke.mjs appcontainer",
37
- "containment:bootstrap": "node src/containment-bootstrap.mjs",
38
- "containment:smoke:lpac": "node src/containment-smoke.mjs lpac",
39
- "containment:smoke:appcontainer": "node src/containment-smoke.mjs appcontainer",
40
- "containment:construction": "node src/containment-construction.mjs",
41
- "containment:child-control": "node src/containment-child-control.mjs",
42
- "contained:run": "node src/contained-cli.mjs workspaces/demo input.txt",
43
- "contained:smoke": "node src/contained-smoke.mjs",
44
- "mcp:contained:smoke": "node src/mcp-contained-smoke-client.mjs",
45
- "gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r46.ps1",
46
- "authority:smoke": "node src/authority-smoke.mjs",
47
- "mcp:remote:smoke": "node src/remote-mcp-smoke-client.mjs",
48
- "mcp:host:smoke": "node src/mcp-host-smoke-client.mjs",
49
- "host:policy:init": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/init-host-policy.ps1",
50
- "mcp:remote:host:smoke": "node src/remote-mcp-host-smoke-client.mjs",
51
- "mcp:remote:autonomous:smoke": "node src/remote-mcp-autonomous-smoke-client.mjs",
52
- "mcp:tunnel-compat:smoke": "node src/tunnel-stdio-compat-smoke.mjs",
53
- "audit:verify": "node src/deadbyte-cli.mjs audit verify",
54
- "audit:status": "node src/deadbyte-cli.mjs audit status",
55
- "desktop:build": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-desktop-r40.ps1",
56
- "desktop:policy:refresh": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/init-desktop-policy-r40.ps1",
57
- "r43:parent:verify": "node scripts/verify-r43-parent.mjs",
58
- "r43:full:test": "node scripts/full-regression-r43.mjs",
59
- "r44:parent:verify": "node scripts/verify-r44-parent.mjs",
60
- "r44:full:test": "node scripts/full-regression-r44.mjs",
61
- "finalize:r44": "node scripts/finalize-r44.mjs",
62
- "hardware:build": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-hardware-r45.ps1",
63
- "doctor": "node src/deadbyte-cli.mjs doctor",
64
- "r45:parent:verify": "node scripts/verify-r45-parent.mjs",
65
- "r45:full:test": "node scripts/full-regression-r45.mjs",
66
- "finalize:r45": "node scripts/finalize-r45.mjs",
67
- "r46:fileless:test": "node --test --test-concurrency=1 test/process-policy.test.mjs test/process-policy-refresh.test.mjs test/release-generation.test.mjs test/process-runtime.test.mjs test/process-mcp-tools.test.mjs test/compact-gateway-r36.test.mjs test/capability-ledger-r36.test.mjs test/remote-device-r44.test.mjs test/observation-runtime.test.mjs test/observation-mcp-tools.test.mjs",
68
- "r46:full:test": "node scripts/full-regression-r46.mjs",
69
- "r47:full:test": "node scripts/full-regression-r47.mjs",
70
- "r47:catalog:test": "node --test --test-concurrency=1 test/full-max-catalog-r47.test.mjs",
71
- "r47:hardening:test": "node scripts/commander-hardening-gate-r47.mjs",
72
- "r48:full:test": "node scripts/full-regression-r48.mjs",
73
- "r48:release:test": "node --test --test-concurrency=1 test/r48-release-contract.test.mjs test/commander-reference-contract-r48.test.mjs test/commander-extended-wire-r48.test.mjs test/commander-external-process-r48.test.mjs test/commander-office-reader-r48.test.mjs test/commander-pdf-r48.test.mjs test/commander-url-reader-r48.test.mjs test/commander-wire-contract-r47.test.mjs"
74
- },
75
- "bundleDependencies": [
76
- "@modelcontextprotocol/server",
77
- "@modelcontextprotocol/client",
78
- "typescript",
79
- "zod"
80
- ],
81
- "dependencies": {
82
- "@modelcontextprotocol/client": "2.1.0",
83
- "@modelcontextprotocol/server": "2.1.0",
84
- "typescript": "5.9.3",
85
- "zod": "4.4.3"
86
- },
87
- "bin": {
88
- "deadbyte-mcp": "src/deadbyte-cli.mjs"
89
- },
90
- "publishConfig": {
91
- "access": "public"
92
- }
93
- }
1
+ {
2
+ "name": "deadbyte-mcp",
3
+ "version": "0.15.23",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "Authenticated MCP agentic runtime with signed skills, persistent model backends, identity-bound remote devices, durable job supervision, immutable release slots, and separately revocable machine authority.",
7
+ "engines": {
8
+ "node": ">=22"
9
+ },
10
+ "scripts": {
11
+ "test": "node --test test/*.test.mjs",
12
+ "manifest:write": "node scripts/release-manifest.mjs write",
13
+ "manifest:verify": "node scripts/release-manifest.mjs verify",
14
+ "r41:parent:verify": "node scripts/verify-r41-parent.mjs",
15
+ "r41:memory:verify": "node scripts/verify-memory-r41.mjs",
16
+ "r42:parent:verify": "node scripts/verify-r42-parent.mjs",
17
+ "r42:eval": "node scripts/agent-eval-r42.mjs",
18
+ "self-update:runtime": "node scripts/runtime-self-update.mjs",
19
+ "self-update:deferred": "node scripts/deferred-slot-operation-r46.mjs",
20
+ "release:parity": "node scripts/release-parity-r46.mjs",
21
+ "release:final:write": "node scripts/final-closure-r46.mjs",
22
+ "release:final:verify": "node scripts/final-closure-verify-r46.mjs",
23
+ "proof": "node src/proof-cli.mjs workspaces/demo input.txt",
24
+ "verify": "node src/verifier-cli.mjs workspaces/demo evidence/latest.json",
25
+ "trust:init": "node src/trust-init.mjs",
26
+ "mcp": "node src/mcp-server.mjs",
27
+ "mcp:smoke": "node src/mcp-smoke-client.mjs",
28
+ "mcp:agent:smoke": "node --test test/agent-runtime.test.mjs test/agent-runtime-adversarial.test.mjs test/agent-runtime-crash.test.mjs test/agent-task-receipt.test.mjs",
29
+ "mcp:coding:smoke": "node --test test/coding-plane.test.mjs test/coding-plane-adversarial.test.mjs test/coding-runtime.test.mjs test/coding-crash.test.mjs",
30
+ "mcp:machine-fs:smoke": "node src/machine-fs-smoke-client.mjs",
31
+ "mcp:observation:smoke": "node src/observation-smoke-client.mjs",
32
+ "mcp:process:smoke": "node src/process-smoke-client.mjs",
33
+ "process:policy:refresh": "node scripts/refresh-process-policy.mjs",
34
+ "mcp:autonomous:smoke": "node --test test/autonomous-runtime.test.mjs test/autonomous-loop.test.mjs test/autonomous-adversarial.test.mjs test/autonomous-supervisor-integration.test.mjs test/native-diff.test.mjs",
35
+ "containment:build": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-containment.ps1",
36
+ "containment:smoke": "node src/containment-smoke.mjs appcontainer",
37
+ "containment:bootstrap": "node src/containment-bootstrap.mjs",
38
+ "containment:smoke:lpac": "node src/containment-smoke.mjs lpac",
39
+ "containment:smoke:appcontainer": "node src/containment-smoke.mjs appcontainer",
40
+ "containment:construction": "node src/containment-construction.mjs",
41
+ "containment:child-control": "node src/containment-child-control.mjs",
42
+ "contained:run": "node src/contained-cli.mjs workspaces/demo input.txt",
43
+ "contained:smoke": "node src/contained-smoke.mjs",
44
+ "mcp:contained:smoke": "node src/mcp-contained-smoke-client.mjs",
45
+ "gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r46.ps1",
46
+ "authority:smoke": "node src/authority-smoke.mjs",
47
+ "mcp:remote:smoke": "node src/remote-mcp-smoke-client.mjs",
48
+ "mcp:host:smoke": "node src/mcp-host-smoke-client.mjs",
49
+ "host:policy:init": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/init-host-policy.ps1",
50
+ "mcp:remote:host:smoke": "node src/remote-mcp-host-smoke-client.mjs",
51
+ "mcp:remote:autonomous:smoke": "node src/remote-mcp-autonomous-smoke-client.mjs",
52
+ "mcp:tunnel-compat:smoke": "node src/tunnel-stdio-compat-smoke.mjs",
53
+ "audit:verify": "node src/deadbyte-cli.mjs audit verify",
54
+ "audit:status": "node src/deadbyte-cli.mjs audit status",
55
+ "desktop:build": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-desktop-r40.ps1",
56
+ "desktop:policy:refresh": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/init-desktop-policy-r40.ps1",
57
+ "r43:parent:verify": "node scripts/verify-r43-parent.mjs",
58
+ "r43:full:test": "node scripts/full-regression-r43.mjs",
59
+ "r44:parent:verify": "node scripts/verify-r44-parent.mjs",
60
+ "r44:full:test": "node scripts/full-regression-r44.mjs",
61
+ "finalize:r44": "node scripts/finalize-r44.mjs",
62
+ "hardware:build": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-hardware-r45.ps1",
63
+ "doctor": "node src/deadbyte-cli.mjs doctor",
64
+ "r45:parent:verify": "node scripts/verify-r45-parent.mjs",
65
+ "r45:full:test": "node scripts/full-regression-r45.mjs",
66
+ "finalize:r45": "node scripts/finalize-r45.mjs",
67
+ "r46:fileless:test": "node --test --test-concurrency=1 test/process-policy.test.mjs test/process-policy-refresh.test.mjs test/release-generation.test.mjs test/process-runtime.test.mjs test/process-mcp-tools.test.mjs test/compact-gateway-r36.test.mjs test/capability-ledger-r36.test.mjs test/remote-device-r44.test.mjs test/observation-runtime.test.mjs test/observation-mcp-tools.test.mjs",
68
+ "r46:full:test": "node scripts/full-regression-r46.mjs",
69
+ "r47:full:test": "node scripts/full-regression-r47.mjs",
70
+ "r47:catalog:test": "node --test --test-concurrency=1 test/full-max-catalog-r47.test.mjs",
71
+ "r47:hardening:test": "node scripts/commander-hardening-gate-r47.mjs",
72
+ "r48:full:test": "node scripts/full-regression-r48.mjs",
73
+ "r48:release:test": "node --test --test-concurrency=1 test/r48-release-contract.test.mjs test/commander-reference-contract-r48.test.mjs test/commander-extended-wire-r48.test.mjs test/commander-external-process-r48.test.mjs test/commander-office-reader-r48.test.mjs test/commander-pdf-r48.test.mjs test/commander-url-reader-r48.test.mjs test/commander-wire-contract-r47.test.mjs",
74
+ "r48:catalog:test": "node --test --test-concurrency=1 test/full-max-catalog-r48.test.mjs",
75
+ "release:npm": "node scripts/npm-release-r48.mjs"
76
+ },
77
+ "bundleDependencies": [
78
+ "@modelcontextprotocol/server",
79
+ "@modelcontextprotocol/client",
80
+ "typescript",
81
+ "zod"
82
+ ],
83
+ "dependencies": {
84
+ "@modelcontextprotocol/client": "2.1.0",
85
+ "@modelcontextprotocol/server": "2.1.0",
86
+ "typescript": "5.9.3",
87
+ "zod": "4.4.3"
88
+ },
89
+ "bin": {
90
+ "deadbyte-mcp": "src/deadbyte-cli.mjs"
91
+ },
92
+ "publishConfig": {
93
+ "access": "public"
94
+ }
95
+ }
@@ -0,0 +1,46 @@
1
+ import { readFile, rename, rm, mkdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ import { createSkillPlane } from "../src/skill-plane-r44.mjs";
5
+
6
+ const stateDir=path.join(os.homedir(),".deadbyte-mcp");
7
+ const skillsRoot=path.join(stateDir,"skills");
8
+ const active=path.join(skillsRoot,"skill-creator");
9
+ const stageParent=path.join(stateDir,"skill-staging","skill-creator-1.1.1");
10
+ const candidate=path.join(stageParent,"skill-creator");
11
+ const expectedOld="f34b3953db176c8ae9a5e08e7702b39f12b60b013edcd2f4d63a6268af9ba432";
12
+ const expectedNew="e39960cab9eab44512fa38703fc8255b8be8e8b4f6565b4255b94604eded5359";
13
+
14
+ const oldEnv=JSON.parse(await readFile(path.join(active,"skill.json"),"utf8"));
15
+ const newEnv=JSON.parse(await readFile(path.join(candidate,"skill.json"),"utf8"));
16
+ if(oldEnv.manifest_sha256!==expectedOld||oldEnv.body.version!=="1.1.0") throw new Error("active precondition failed");
17
+ if(newEnv.manifest_sha256!==expectedNew||newEnv.body.version!=="1.1.1") throw new Error("candidate precondition failed");
18
+
19
+ const stagePlane=await createSkillPlane({root:stageParent,verifyKeyPath:path.join(stateDir,"trust","ed25519-public.pem")});
20
+ const staged=await stagePlane.load({name:"skill-creator"});
21
+ if(!staged.verified||staged.version!=="1.1.1") throw new Error("candidate signature verification failed");
22
+
23
+ const swapRoot=path.join(stateDir,"skill-staging","swap");
24
+ await mkdir(swapRoot,{recursive:true});
25
+ const oldSwap=path.join(swapRoot,"skill-creator-1.1.0-"+expectedOld);
26
+ await rm(oldSwap,{recursive:true,force:true});
27
+
28
+ let movedOld=false,movedNew=false;
29
+ try{
30
+ await rename(active,oldSwap); movedOld=true;
31
+ await rename(candidate,active); movedNew=true;
32
+ const livePlane=await createSkillPlane({root:skillsRoot,verifyKeyPath:path.join(stateDir,"trust","ed25519-public.pem")});
33
+ const live=await livePlane.load({name:"skill-creator"});
34
+ if(!live.verified||live.version!=="1.1.1"||live.manifest_sha256!==expectedNew) throw new Error("live verification failed after swap");
35
+ await rm(oldSwap,{recursive:true,force:true});
36
+ await rm(stageParent,{recursive:true,force:true});
37
+ console.log(JSON.stringify({status:"ACTIVATED",version:live.version,manifest_sha256:live.manifest_sha256,verified:live.verified},null,2));
38
+ }catch(e){
39
+ try{
40
+ if(movedNew) await rename(active,candidate);
41
+ if(movedOld) await rename(oldSwap,active);
42
+ }catch(rollbackError){
43
+ e.message += "; rollback_failed="+rollbackError.message;
44
+ }
45
+ throw e;
46
+ }
@@ -0,0 +1,208 @@
1
+ import { readFile, writeFile, mkdir, rm, mkdtemp } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ import { fileURLToPath } from "node:url";
5
+ import { promisify } from "node:util";
6
+ import { execFile } from "node:child_process";
7
+ import { createHash, createPrivateKey, createPublicKey, sign } from "node:crypto";
8
+ import { createSkillPlane } from "../src/skill-plane-r44.mjs";
9
+
10
+ const ex = promisify(execFile);
11
+ const here = path.dirname(fileURLToPath(import.meta.url));
12
+ const home = os.homedir();
13
+ const stateDir = path.join(home, ".deadbyte-mcp");
14
+ const skillsRoot = path.join(stateDir, "skills");
15
+ const creatorDir = path.join(skillsRoot, "skill-creator");
16
+ const name = "deadbyte-advanced-pcb-engineering";
17
+ const version = "1.0.0";
18
+ const out = path.join(skillsRoot, name);
19
+ const description = "Evidence-driven advanced PCB engineering workflow for schematic review, constraint capture, stackup-aware placement and routing, power and signal integrity, EMC, DFM/DFT, KiCad verification, manufacturing release, and hardware bring-up.";
20
+ const creatorManifest = "e39960cab9eab44512fa38703fc8255b8be8e8b4f6565b4255b94604eded5359";
21
+
22
+ const sha = b => createHash("sha256").update(b).digest("hex");
23
+ const canonical = v => Array.isArray(v) ? v.map(canonical) : v && typeof v === "object"
24
+ ? Object.fromEntries(Object.keys(v).sort((a,b)=>a.localeCompare(b,"en")).map(k=>[k,canonical(v[k])]))
25
+ : v;
26
+
27
+ const sources = [
28
+ ["SKILL.md", "pcb-skill-src-SKILL.md.txt", "skill"],
29
+ ["references/bringup-evidence.md", "pcb-skill-src-bringup-evidence.md.txt", "reference"],
30
+ ["references/constraint-model.md", "pcb-skill-src-constraint-model.md.txt", "reference"],
31
+ ["references/emc-mechanical-dfm.md", "pcb-skill-src-emc-mechanical-dfm.md.txt", "reference"],
32
+ ["references/high-speed-layout.md", "pcb-skill-src-high-speed-layout.md.txt", "reference"],
33
+ ["references/kicad-native.md", "pcb-skill-src-kicad-native.md.txt", "reference"],
34
+ ["references/power-integrity.md", "pcb-skill-src-power-integrity.md.txt", "reference"],
35
+ ["scripts/kicad_pcb_probe.py", "pcb-skill-src-kicad_pcb_probe.py.txt", "script"],
36
+ ["scripts/pcb_constraint_gate.py", "pcb-skill-src-pcb_constraint_gate.py.txt", "script"]
37
+ ];
38
+
39
+ await rm(out, { recursive: true, force: true });
40
+ const scaffold = await ex(process.execPath, [path.join(creatorDir, "scripts", "create-skill.mjs"), skillsRoot, name, version], { maxBuffer: 1024 * 1024 });
41
+
42
+ for (const [target, src] of sources) {
43
+ const data = await readFile(path.join(here, src));
44
+ const dst = path.join(out, ...target.split("/"));
45
+ await mkdir(path.dirname(dst), { recursive: true });
46
+ await writeFile(dst, data);
47
+ }
48
+
49
+ const resources = [];
50
+ for (const [target,, kind] of sources) {
51
+ if (target === "SKILL.md") continue;
52
+ const bytes = await readFile(path.join(out, ...target.split("/")));
53
+ resources.push({ path: target, sha256: sha(bytes), kind });
54
+ }
55
+ resources.sort((a,b)=>a.path.localeCompare(b.path,"en"));
56
+
57
+ const body = {
58
+ schema: "deadbyte.skill-manifest.v1",
59
+ name,
60
+ version,
61
+ description,
62
+ audience: "agent",
63
+ skill_md_sha256: sha(await readFile(path.join(out, "SKILL.md"))),
64
+ resources,
65
+ required_capabilities: [],
66
+ authority_planes: ["coding"],
67
+ provenance: {
68
+ source: "skill-creator",
69
+ origin_url: null,
70
+ source_revision: "local-draft-2026-09-27-pcb-v1"
71
+ }
72
+ };
73
+
74
+ const bodyBytes = Buffer.from(JSON.stringify(canonical(body)), "utf8");
75
+ const body_sha256 = sha(bodyBytes);
76
+ const priv = createPrivateKey(await readFile(path.join(stateDir, "trust", "ed25519-private.pem")));
77
+ const pub = createPublicKey(priv);
78
+ const keyId = sha(pub.export({ type: "spki", format: "der" }));
79
+ const attestation = {
80
+ algorithm: "ed25519",
81
+ domain: "DEADBYTE-SKILL-MANIFEST-V1",
82
+ key_id: keyId,
83
+ signature_base64: sign(null, Buffer.concat([Buffer.from("DEADBYTE-SKILL-MANIFEST-V1\0", "utf8"), bodyBytes]), priv).toString("base64")
84
+ };
85
+ const unsigned = { body, body_sha256, attestation };
86
+ const envelope = {
87
+ ...unsigned,
88
+ manifest_sha256: sha(Buffer.from(JSON.stringify(canonical(unsigned)), "utf8"))
89
+ };
90
+ await writeFile(path.join(out, "skill.json"), JSON.stringify(envelope, null, 2), "utf8");
91
+
92
+ const validator = await ex(process.execPath, [path.join(creatorDir, "scripts", "validate-skill.mjs"), out], { maxBuffer: 1024 * 1024 });
93
+
94
+ const plane = await createSkillPlane({
95
+ root: skillsRoot,
96
+ verifyKeyPath: path.join(stateDir, "trust", "ed25519-public.pem")
97
+ });
98
+ const loaded = await plane.load({ name });
99
+ if (!loaded.verified) throw new Error("skill plane returned verified=false");
100
+
101
+ let python = null;
102
+ for (const candidate of ["python", "py"]) {
103
+ try {
104
+ await ex(candidate, ["--version"], { timeout: 10000, maxBuffer: 1024 * 1024 });
105
+ python = candidate;
106
+ break;
107
+ } catch {}
108
+ }
109
+
110
+ let selfTest = { status: "SKIPPED", reason: "python_not_found" };
111
+ if (python) {
112
+ const tmp = await mkdtemp(path.join(os.tmpdir(), "deadbyte-pcb-skill-"));
113
+ try {
114
+ const fixture = [
115
+ "(kicad_pcb",
116
+ " (version 20240108)",
117
+ " (generator pcbnew)",
118
+ " (layers",
119
+ " (0 \"F.Cu\" signal)",
120
+ " (31 \"B.Cu\" signal)",
121
+ " )",
122
+ " (net 0 \"\")",
123
+ " (net 1 \"GND\")",
124
+ " (footprint \"TEST\" (layer \"F.Cu\"))",
125
+ " (segment (start 0 0) (end 1 0) (width 0.2) (layer \"F.Cu\") (net 1))",
126
+ " (via (at 1 0) (size 0.6) (drill 0.3) (layers \"F.Cu\" \"B.Cu\") (net 1))",
127
+ " (zone (net 1) (net_name \"GND\") (layer \"B.Cu\"))",
128
+ ")",
129
+ ""
130
+ ].join("\n");
131
+ const fixturePath = path.join(tmp, "fixture.kicad_pcb");
132
+ const probePath = path.join(tmp, "probe.json");
133
+ const contractPath = path.join(tmp, "contract.json");
134
+ await writeFile(fixturePath, fixture, "utf8");
135
+
136
+ const probeScript = path.join(out, "scripts", "kicad_pcb_probe.py");
137
+ const gateScript = path.join(out, "scripts", "pcb_constraint_gate.py");
138
+ const probeRun = await ex(python, [probeScript, fixturePath, "--pretty"], { timeout: 30000, maxBuffer: 1024 * 1024 });
139
+ const probe = JSON.parse(probeRun.stdout);
140
+ if (probe.copper_layer_count !== 2 || probe.counts.footprints !== 1 || probe.counts.segments !== 1 || probe.counts.vias !== 1 || probe.track_width_mm.min !== 0.2 || probe.via_drill_mm.min !== 0.3) {
141
+ throw new Error("probe self-test observation mismatch");
142
+ }
143
+ await writeFile(probePath, probeRun.stdout, "utf8");
144
+
145
+ const passContract = {
146
+ required_layers: ["F.Cu", "B.Cu"],
147
+ min_copper_layers: 2,
148
+ min_track_width_mm: 0.15,
149
+ min_via_diameter_mm: 0.45,
150
+ min_via_drill_mm: 0.20,
151
+ required_nets: ["GND"],
152
+ min_footprints: 1,
153
+ min_segments: 1,
154
+ min_vias: 1,
155
+ min_zones: 1
156
+ };
157
+ await writeFile(contractPath, JSON.stringify(passContract, null, 2), "utf8");
158
+ const passRun = await ex(python, [gateScript, probePath, contractPath], { timeout: 30000, maxBuffer: 1024 * 1024 });
159
+ const passResult = JSON.parse(passRun.stdout);
160
+ if (passResult.status !== "PASS") throw new Error("positive gate self-test did not pass");
161
+
162
+ const failContract = { min_track_width_mm: 0.25 };
163
+ await writeFile(contractPath, JSON.stringify(failContract, null, 2), "utf8");
164
+ let negativeCaught = false;
165
+ try {
166
+ await ex(python, [gateScript, probePath, contractPath], { timeout: 30000, maxBuffer: 1024 * 1024 });
167
+ } catch (e) {
168
+ const parsed = e.stdout ? JSON.parse(e.stdout) : null;
169
+ if (e.code === 2 && parsed && parsed.status === "FAIL") negativeCaught = true;
170
+ }
171
+ if (!negativeCaught) throw new Error("negative gate self-test did not fail closed");
172
+
173
+ selfTest = {
174
+ status: "PASS",
175
+ python,
176
+ fixture_probe: {
177
+ copper_layers: probe.copper_layer_count,
178
+ footprints: probe.counts.footprints,
179
+ segments: probe.counts.segments,
180
+ vias: probe.counts.vias,
181
+ zones: probe.counts.zones,
182
+ min_track_width_mm: probe.track_width_mm.min,
183
+ min_via_diameter_mm: probe.via_diameter_mm.min,
184
+ min_via_drill_mm: probe.via_drill_mm.min
185
+ },
186
+ positive_gate: "PASS",
187
+ negative_gate: "FAIL_EXIT_2"
188
+ };
189
+ } finally {
190
+ await rm(tmp, { recursive: true, force: true });
191
+ }
192
+ }
193
+
194
+ console.log(JSON.stringify({
195
+ status: "built",
196
+ name,
197
+ version,
198
+ out,
199
+ creator_manifest: creatorManifest,
200
+ scaffold_stdout: scaffold.stdout.trim(),
201
+ manifest_sha256: envelope.manifest_sha256,
202
+ body_sha256,
203
+ resource_count: resources.length,
204
+ verify_key_id: keyId,
205
+ validator_stdout: validator.stdout.trim(),
206
+ skill_plane_verified: loaded.verified,
207
+ self_test: selfTest
208
+ }, null, 2));
@@ -53,6 +53,24 @@ foreach($query in @('cpu','gpu','memory','storage','network','pci')){
53
53
  $queries[$query]=Get-Sha256Hex -Path $Exe
54
54
  }
55
55
 
56
+ $windowsQueries=[ordered]@{}
57
+ foreach($query in @('services','drivers','sockets','volumes','usb','wsl')){
58
+ $raw=& $Exe $query 2>&1
59
+ $queryExit=$LASTEXITCODE
60
+ if($queryExit -ne 0){throw "Windows query $query failed exit=$queryExit output=$($raw -join ' ')"}
61
+ $text=($raw -join [Environment]::NewLine)
62
+ $parsed=$text | ConvertFrom-Json
63
+ if($parsed.schema -ne 'deadbyte.windows-query.v1' -or $parsed.query -ne $query){throw "Windows query $query contract mismatch"}
64
+ $windowsQueries[$query]=Get-Sha256Hex -Path $Exe
65
+ }
66
+ $registryRaw=& $Exe registry HKLM 'SOFTWARE\Microsoft\Windows NT\CurrentVersion' ProductName 2>&1
67
+ $registryExit=$LASTEXITCODE
68
+ if($registryExit -ne 0){throw "Windows registry query failed exit=$registryExit output=$($registryRaw -join ' ')"}
69
+ $registryText=($registryRaw -join [Environment]::NewLine)
70
+ $registryParsed=$registryText | ConvertFrom-Json
71
+ if($registryParsed.schema -ne 'deadbyte.windows-query.v1' -or $registryParsed.query -ne 'registry'){throw 'Windows registry query contract mismatch'}
72
+ $windowsQueries['registry']=Get-Sha256Hex -Path $Exe
73
+
56
74
  $depLine='call "{0}" -no_logo -arch=x64 -host_arch=x64 && dumpbin /nologo /dependents "{1}"' -f $dev,$Exe
57
75
  $deps=& $cmd /d /s /c $depLine 2>&1
58
76
  $depExit=$LASTEXITCODE
@@ -67,5 +85,6 @@ if($depExit -ne 0){throw "hardware observer dumpbin failed exit=$depExit"}
67
85
  obj_sha256=Get-Sha256Hex -Path $Obj
68
86
  selftest=@($self | ForEach-Object {[string]$_})
69
87
  queries=@($queries.Keys)
88
+ windows_queries=@($windowsQueries.Keys)
70
89
  dependencies=@($deps | ForEach-Object {[string]$_})
71
90
  }|ConvertTo-Json -Depth 5
@@ -0,0 +1,8 @@
1
+ import { readFile, readdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ const root=process.argv[2];
4
+ async function walk(d,r=""){let out=[];for(const e of (await readdir(d,{withFileTypes:true})).sort((a,b)=>a.name.localeCompare(b.name,"en"))){const p=path.join(d,e.name),q=r?r+"/"+e.name:e.name;if(e.isDirectory())out.push(...await walk(p,q));else if(e.isFile())out.push(q)}return out}
5
+ const env=JSON.parse(await readFile(path.join(root,"skill.json"),"utf8"));
6
+ const actual=(await walk(root)).sort((a,b)=>a.localeCompare(b,"en"));
7
+ const expected=["SKILL.md","skill.json",...env.body.resources.map(x=>x.path)].sort((a,b)=>a.localeCompare(b,"en"));
8
+ console.log(JSON.stringify({actual,expected,extra:actual.filter(x=>!expected.includes(x)),missing:expected.filter(x=>!actual.includes(x))},null,2));
@@ -0,0 +1,27 @@
1
+ import { readdir, stat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { spawnSync } from 'node:child_process';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const here=path.dirname(fileURLToPath(import.meta.url));
7
+ const root=path.resolve(here,'..');
8
+ const testDir=path.join(root,'test');
9
+ const excluded=new Set(['full-max-catalog-r44.test.mjs','full-max-catalog-r45.test.mjs','full-max-catalog-r46.test.mjs']);
10
+ const files=(await readdir(testDir,{withFileTypes:true}))
11
+ .filter(entry=>entry.isFile()&&entry.name.endsWith('.test.mjs')&&!excluded.has(entry.name));
12
+ const weighted=[];
13
+ for(const entry of files) weighted.push({path:path.join('test',entry.name),size:(await stat(path.join(testDir,entry.name))).size});
14
+ weighted.sort((a,b)=>b.size-a.size||a.path.localeCompare(b.path,'en'));
15
+ const batchCount=8;
16
+ const batches=Array.from({length:batchCount},()=>[]);
17
+ weighted.forEach((entry,index)=>batches[index%batchCount].push(entry.path));
18
+ const requested=Number(process.argv[2]);
19
+ if(!Number.isInteger(requested)||requested<1||requested>batchCount) throw new Error('usage: node full-regression-r48-batch.mjs <1..8>');
20
+ const batch=batches[requested-1].sort((a,b)=>a.localeCompare(b,'en'));
21
+ console.log(`R48-BOUNDED-REGRESSION batch=${requested}/${batchCount} files=${batch.length}`);
22
+ console.log(batch.join('\n'));
23
+ const result=spawnSync(process.execPath,['--test','--test-concurrency=1',...batch],{cwd:root,stdio:'inherit',windowsHide:true,shell:false});
24
+ if(result.error) throw result.error;
25
+ if(result.signal) throw new Error(`regression batch ${requested} terminated by ${result.signal}`);
26
+ if(result.status!==0) throw new Error(`regression batch ${requested} failed with exit code ${result.status}`);
27
+ console.log(`R48-BOUNDED-REGRESSION BATCH PASS batch=${requested} files=${batch.length}`);