deadbyte-mcp 0.15.46 → 0.15.48

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 (98) hide show
  1. package/MANIFEST.SHA256 +97 -45
  2. package/PROVENANCE.json +22 -11
  3. package/README.txt +18 -18
  4. package/RELEASE.json +378 -369
  5. package/SBOM.cdx.json +2 -2
  6. package/TEST-MATRIX.json +2 -2
  7. package/bin/deadbyte-epoch-lock-r85.node +0 -0
  8. package/bin/deadbyte-kernel-lock-r74.exe +0 -0
  9. package/bridge/package.json +1 -1
  10. package/controller/deadbyte-process-policy.json +7 -7
  11. package/docs/R73-CAPABILITY-GAP-MATRIX.json +17 -0
  12. package/docs/R73-EXECUTION-CONTRACT.md +11 -0
  13. package/docs/R73-IMPLEMENTATION-CHANGELOG.md +12 -0
  14. package/docs/R73-REMAINING-DEFECTS.md +9 -0
  15. package/docs/R74-KERNEL-LOCK-BINARY.json +11 -0
  16. package/docs/R75-RECOVERY-HANDOFF.md +16 -0
  17. package/docs/R85-EPOCH-LOCK-BINARY.json +13 -0
  18. package/native/deadbyte-epoch-lock-r85.cpp +241 -0
  19. package/native/deadbyte-kernel-lock-r74.cpp +65 -0
  20. package/package.json +1 -1
  21. package/scripts/build-epoch-lock-r85.ps1 +34 -0
  22. package/scripts/build-kernel-lock-r74.ps1 +28 -0
  23. package/scripts/deploy-r48.mjs +3 -1
  24. package/scripts/gate-windows-r72.ps1 +2 -2
  25. package/scripts/npm-prepublish-contract-r74.mjs +113 -0
  26. package/scripts/npm-release-r48.mjs +24 -4
  27. package/scripts/npm-release-readiness-r108.mjs +134 -0
  28. package/scripts/npm-release-readiness-r74.mjs +46 -0
  29. package/scripts/r73-atomic-benchmark.mjs +39 -0
  30. package/scripts/r75-npm-bin-integrity-gate.mjs +33 -0
  31. package/scripts/release-manifest.mjs +1 -1
  32. package/scripts/verify-r70-full-regression.ps1 +12 -2
  33. package/src/activation-authority-proof-r75.mjs +67 -0
  34. package/src/activation-continuity-engine-r65.mjs +17 -4
  35. package/src/activation-preflight-r65.mjs +13 -0
  36. package/src/atomic-mutation.mjs +99 -9
  37. package/src/authority-continuity-r65.mjs +265 -21
  38. package/src/deadbyte-cli.mjs +55 -18
  39. package/src/epoch-lock-r85.mjs +48 -0
  40. package/src/foreground-marker-cas-win32.mjs +284 -0
  41. package/src/foreground-process-identity.mjs +3 -3
  42. package/src/kernel-lock-r74.mjs +125 -0
  43. package/src/privileged-install-trust-r89.mjs +196 -0
  44. package/src/remote-session-guardian.mjs +9 -7
  45. package/src/runtime-update.mjs +5 -22
  46. package/src/version.mjs +1 -1
  47. package/src/windows-powershell-environment.mjs +24 -0
  48. package/test/atomic-mutation.test.mjs +68 -2
  49. package/test/cli-entrypoint.test.mjs +1 -1
  50. package/test/commander-schema-differential-r48.test.mjs +1 -1
  51. package/test/helpers/r75-authority-proof.mjs +9 -0
  52. package/test/r100-posix-owned-lock-race.test.mjs +72 -0
  53. package/test/r101-acl-probe-environment.test.mjs +51 -0
  54. package/test/r106-trusted-powershell-spawn.test.mjs +53 -0
  55. package/test/r107-updater-powershell-path.test.mjs +77 -0
  56. package/test/r33-closeout-regression.test.mjs +2 -1
  57. package/test/r54-offline-predecessor-self-exclusion.test.mjs +2 -2
  58. package/test/r55-offline-predecessor-guardian-family.test.mjs +2 -2
  59. package/test/r56-rollback-launcher-restore.test.mjs +2 -2
  60. package/test/r57-core-startup-race.test.mjs +2 -2
  61. package/test/r58-concurrent-recovery.test.mjs +10 -7
  62. package/test/r58-stale-owner.test.mjs +5 -6
  63. package/test/r59-tool-surface-compat.test.mjs +1 -1
  64. package/test/r65-activation-orchestration.test.mjs +2 -1
  65. package/test/r65-activation-preflight.test.mjs +7 -6
  66. package/test/r65-authority-epoch-recovery.test.mjs +3 -1
  67. package/test/r65-authority-restored-safe.test.mjs +2 -1
  68. package/test/r65-deploy-preflight.test.mjs +13 -14
  69. package/test/r65-epoch-native-activation-integration.test.mjs +5 -4
  70. package/test/r65-legacy-authority-migration.test.mjs +2 -1
  71. package/test/r67-npm-cross-volume.test.mjs +9 -2
  72. package/test/r71-full-verifier-artifact.test.mjs +21 -15
  73. package/test/r71-isolated-slot-rollback-restore.test.mjs +3 -1
  74. package/test/r71-release-identity.test.mjs +3 -1
  75. package/test/r73-package-boundary.test.mjs +22 -0
  76. package/test/r74-kernel-lock.test.mjs +156 -0
  77. package/test/r74-prepublish-contract.test.mjs +89 -0
  78. package/test/r75-activation-authority-proof.test.mjs +46 -0
  79. package/test/r75-authority-evidence.test.mjs +77 -0
  80. package/test/r76-pinned-marker-cas.test.mjs +78 -0
  81. package/test/r77-epoch-grant-cas.test.mjs +51 -0
  82. package/test/r78-parent-junction-cas.test.mjs +62 -0
  83. package/test/r79-orphan-revocation-reconcile.test.mjs +88 -0
  84. package/test/r79-windows-fsync-regression.test.mjs +45 -0
  85. package/test/r80-durable-epoch-commit.test.mjs +76 -0
  86. package/test/r82-epoch-lock-owned-cas.test.mjs +93 -0
  87. package/test/r83-epoch-lock-fileid-cas.test.mjs +92 -0
  88. package/test/r84-epoch-lock-created-fileid.test.mjs +112 -0
  89. package/test/r85-epoch-lock-release-lifetime.test.mjs +25 -0
  90. package/test/r85-epoch-repeat-append.test.mjs +30 -0
  91. package/test/r86-epoch-cleanup-and-loader.test.mjs +126 -0
  92. package/test/r87-crashed-orphan-revoke-reconcile.test.mjs +110 -0
  93. package/test/r88-native-disposition-failure.test.mjs +35 -0
  94. package/test/r89-privileged-install-boundary.test.mjs +123 -0
  95. package/test/r92-acl-ace-applicability.test.mjs +45 -0
  96. package/test/r94-win32-propagation-enum.test.mjs +51 -0
  97. package/test/r99-privileged-import-closure.test.mjs +45 -0
  98. package/test/remote-session-cli.test.mjs +69 -9
package/SBOM.cdx.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "bomFormat": "CycloneDX",
3
3
  "specVersion": "1.6",
4
- "serialNumber": "urn:cdx:deadbyte-mcp:r72:0.15.46",
4
+ "serialNumber": "urn:cdx:deadbyte-mcp:r74:0.15.47",
5
5
  "version": 1,
6
6
  "metadata": {
7
7
  "component": {
8
8
  "type": "application",
9
9
  "name": "deadbyte-mcp",
10
- "version": "0.15.46"
10
+ "version": "0.15.47"
11
11
  }
12
12
  },
13
13
  "components": [
package/TEST-MATRIX.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": "deadbyte.test-matrix.v1",
3
- "version": "0.15.46",
4
- "train": "R72",
3
+ "version": "0.15.48",
4
+ "train": "R74",
5
5
  "primary_platform": "win32-x64",
6
6
  "reference": {
7
7
  "package": "@wonderwhy-er/desktop-commander",
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deadbyte-chatgpt-bridge",
3
- "version": "0.15.46",
3
+ "version": "0.15.47",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "engines": {
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "schema": "deadbyte.process-policy.v1",
3
3
  "enabled": true,
4
- "grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.46-r72\\controller\\runtime\\process-grant.json",
5
- "state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.46-r72\\controller\\runtime\\process-state",
4
+ "grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.48-r108-release-dev\\controller\\runtime\\process-grant.json",
5
+ "state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.48-r108-release-dev\\controller\\runtime\\process-state",
6
6
  "native_host": {
7
- "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.46-r72\\bin\\deadbyte-process-host.exe",
7
+ "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.48-r108-release-dev\\bin\\deadbyte-process-host.exe",
8
8
  "sha256": "daf9cfb371bee88cafbf5597eaa507fec504dbe0b0ddd40d0c3c2e02817f49e4"
9
9
  },
10
10
  "roots": {
11
11
  "core": {
12
- "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.46-r72",
12
+ "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.48-r108-release-dev",
13
13
  "deny_paths": [
14
14
  "node_modules",
15
15
  "controller/runtime",
@@ -20,7 +20,7 @@
20
20
  "profiles": {
21
21
  "ping_hold": {
22
22
  "executable": "C:\\WINDOWS\\System32\\cmd.exe",
23
- "executable_sha256": "97ac98b1a92c286054cce55239cfccdfc23a5517bd07fe693072c9ca96c7dabb",
23
+ "executable_sha256": "15cd209c995b7d3009c91ca40892d5b8f1fb162f3e5f10716642ea278e8e0d7b",
24
24
  "root_ids": [
25
25
  "core"
26
26
  ],
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "powershell": {
47
47
  "executable": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
48
- "executable_sha256": "8bb6fa8c283b4d92120b1ef249a9b311b0f804d4cabbe9981159976c8be76a5e",
48
+ "executable_sha256": "60c9b29843624dd8af6b6a7b26147753be6aeef65098b9a503cc50850afe410f",
49
49
  "root_ids": [
50
50
  "core"
51
51
  ],
@@ -76,7 +76,7 @@
76
76
  },
77
77
  "powershell_repl": {
78
78
  "executable": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
79
- "executable_sha256": "8bb6fa8c283b4d92120b1ef249a9b311b0f804d4cabbe9981159976c8be76a5e",
79
+ "executable_sha256": "60c9b29843624dd8af6b6a7b26147753be6aeef65098b9a503cc50850afe410f",
80
80
  "root_ids": [
81
81
  "core"
82
82
  ],
@@ -0,0 +1,17 @@
1
+ {
2
+ "schema": "deadbyte.r73-reference-differential.v1",
3
+ "scope": "read-only static comparison; no donor runtime or benchmark was executed",
4
+ "references": [
5
+ {"version":"0.2.52","root":"D:/Projects/deadbyte-mcp/references/desktop-commander v0.2.52","license":"MIT per package.json"},
6
+ {"version":"0.3.0","root":"D:/Projects/deadbyte-mcp/references/desktop-commander v0.3.0","license":"MIT per package.json and LICENSE"},
7
+ {"version":"0.3.1-alpha.2","root":"D:/Projects/deadbyte-mcp/references/desktop-commander-0.3.1-alpha.2/static","license":"MIT per package.json and LICENSE"}
8
+ ],
9
+ "findings": [
10
+ {"mechanism":"process-tree cleanup","donor_evidence":"desktop-commander v0.3.0/dist/utils/process-tree.js","deadbyte_evidence":"native/deadbyte-process-host.cpp; src/process-runtime.mjs","decision":"KEEP","reason":"DEADBYTE Job Object ownership and creation-time identity are stronger than PID-only taskkill; test PID reuse instead of porting code."},
11
+ {"mechanism":"atomic file replacement","donor_evidence":"desktop-commander v0.3.0/dist/utils/atomic-write.js; dist/utils/rename.js","deadbyte_evidence":"src/atomic-mutation.mjs; test/atomic-mutation.test.mjs","decision":"ADAPT","reason":"The existing mutation lock could reclaim a live writer solely from aged mtime. R73 adds owner liveness and lock identity checks, retaining exact preconditions and unknown-effect semantics."},
12
+ {"mechanism":"corrupt config recovery","donor_evidence":"desktop-commander v0.3.0/dist/config-recovery.js","deadbyte_evidence":"src/runtime-update.mjs; src/activation-preflight-r65.mjs","decision":"DEFER","reason":"No reproduced DEADBYTE config recovery defect yet; avoid a second unsanctioned recovery path."},
13
+ {"mechanism":"bounded remote reconnect and telemetry","donor_evidence":"desktop-commander v0.3.0/dist/remote-device/remote-channel.js; dist/remote-device/transport-telemetry.js","deadbyte_evidence":"src/remote-device-r44.mjs; bridge/src/remote-call-claims-r60.mjs","decision":"KEEP","reason":"DEADBYTE has durable pre-dispatch claims and no-replay; focused recovery tests are required before any runtime change."},
14
+ {"mechanism":"alpha presentation and transport changes","donor_evidence":"desktop-commander-0.3.1-alpha.2/static/dist/utils/toolHistory.js; static/dist/remote-device/remote-channel.js","deadbyte_evidence":"src/remote-live-log.mjs; bridge/src/remote-dispatch-r60.mjs","decision":"DEFER","reason":"Static alpha snapshot is not behavioral or performance evidence; no compatible regression has been demonstrated."}
15
+ ],
16
+ "code_copied": false
17
+ }
@@ -0,0 +1,11 @@
1
+ # R73 controlled successor contract
2
+
3
+ - Objective: improve post-0.15.46 correctness and recovery from reproducible defects; do not claim competitor superiority without equivalent runtime measurements.
4
+ - Source master: published `deadbyte-mcp@0.15.46` tarball at `C:\Users\DEADBYTE\.deadbyte-mcp\evidence\npm-publication\0.15.46\deadbyte-mcp-0.15.46.tgz`, SHA-256 `b1a7c215e66fba14b1f1c19675dd3c9e75340d41fd5bd2a3d778175624bfc03e`. The extracted 2,288-file manifest verifies as `55c42123634a7fc3550c0cc24f09dc769ce777a9566032faab9247bb8d85067a`.
5
+ - Runtime predecessor: active `v0.15.45-34aa8d1241cfb8bf` (manifest `34aa8d1241cfb8bf0b5ba303bf3c06e0e9e1bf01f64457bca659d6dd4d634fdc`); observed OFFLINE with all five authority planes DISARMED on 2026-10-15. Published source and active runtime are intentionally distinct.
6
+ - Target: this non-Git `deadbyte-mcp-0.15.47-r73` successor only. The published tarball, R72 tree, active slots, grants, evidence, and reference corpus are protected.
7
+ - Method: inspect actual current primitives and three Desktop Commander reference snapshots; capture RED for any behavioral change; implement the smallest native fix; focused GREEN, adversarial tests, full regression, Windows gate, independent review, manifest and verify-only package proof. No donor code reuse, generic shell, public tool or authority expansion.
8
+ - Decision authority: owner has approved bounded source/tests in isolated successor (Class 2/3). License choice, new public interface/authority, deployment, npm publication, active runtime operations and production grant changes remain Class 1 and are prohibited in this task.
9
+ - Assurance: HIGH_RISK for authority, filesystem, process, remote replay and release evidence. Acceptance oracles are fixture-controlled runtime state, independent file/process identity, exact hash/receipt verification, protocol responses and actual exit codes. Static comparison is not runtime acceptance.
10
+ - Stop conditions: source/tarball identity drift; unavoidable production effect; missing independent owner authority; unresolved ambiguous mutation; or a mandatory gate that cannot pass without scope expansion. Preserve failed evidence. Do not seal a final release.
11
+ - Rollback: discard only R73 successor changes through an explicitly reviewed file-level recovery from the verified 0.15.46 tarball; never reset or clean another tree.
@@ -0,0 +1,12 @@
1
+ # R73 candidate change log
2
+
3
+ - Bootstrapped this non-Git successor from the verified published 0.15.46 tarball, not the mutable R72 tree. Active runtime 0.15.45 was not operated on.
4
+ - RED: the identical six-case test file against the SHA-verified 0.15.46 predecessor `src/atomic-mutation.mjs` returned 3 pass / 3 fail. An aged lock was deleted while its writer was alive, a dead-owner lock was stolen without atomic ownership proof, and post-commit lock ownership loss was not classified. Against R73, the same six cases returned 6 pass / 0 fail.
5
+ - GREEN: retain owner identity in the lock, do not reclaim an aged live lock, and never auto-delete an aged dead-owner lock without an atomic compare-and-delete primitive. Dead-owner locks fail closed with explicit reconciliation required; this trades automatic availability for serialization safety. New-lock I/O failure attempts to clean its own marker, timeout uses monotonic elapsed time, and post-commit lock ownership loss is classified as unknown effect. No public schema or authority change.
6
+ - R67 v2 receipt reconciliation was already implemented. The npm tarball omitted `package-lock.json`; R73 regenerated it offline from 0.15.46 package metadata (matching the R72 source lock SHA-256 `bdddc9cba7a985feea78d3ec6c7100bb650587dcfee852eaa420f08fc6fdbb12`). The real CLI reconciler now returns `STALE_SOURCE`, 32 stale shards and zero integrity faults against historical R67 evidence, never a fabricated PASS.
7
+ - Package boundary RED: npm dry-run inventory included two generated `testing/r70-verifier` artifacts. Added `.npmignore` for generated test evidence/reference/private environment paths; the identical behavioral test is GREEN. Existing evidence files were not deleted.
8
+ - Full regression exposed four setup failures unrelated to the new lock behavior: the R48 pinned donor path no longer existed, and process policy retained four R72-root paths after tarball extraction. The donor file at `desktop-commander v0.2.52` has the exact pinned SHA-256 `f342345e34e48769dabaefe1b932f09d41e2e207b422f7794a15ee50ffa8f140`; the test now points there without changing expectations. The process policy was rebound only to this isolated successor and refreshed with the canonical native/system hash tool. Targeted 8/8 tests pass.
9
+ - The R72 `RELEASE.json.r72_hotfix` hashes describe an earlier candidate seal, not the final published tarball: embedded `883d73…`/`1aa877…` differ from final manifest `55c421…`/tarball `b1a7c2…`. The current R72 publication fence reads the external manifest and evidence index, not these embedded hashes. R73 must not promote this historical snapshot to a final claim.
10
+ - npm package metadata declares no license, while inspected Desktop Commander snapshots say MIT. No license was chosen for DEADBYTE.
11
+
12
+ No npm publish, production activation, rollback, grant change, donor code copy, or final-release seal is authorized in R73.
@@ -0,0 +1,9 @@
1
+ # R73 remaining boundaries
2
+
3
+ 1. A dead owner may leave an aged `.deadbyte-mutation.lock`. R73 refuses automatic deletion because a pathname check followed by unlink can remove a new writer's lock. Recovery requires independent target/receipt reconciliation and an ownership-safe OS primitive or reviewed operator action; no mutation is retried while the lock remains.
4
+ 2. Lock-file serialization assumes cooperative writers within an authorized root. A hostile process with write access to the same directory can replace the marker between read and unlink. Directory access control and exact SHA preconditions remain necessary; this file lock is not a hostile-local-process security boundary.
5
+ 3. Published 0.15.46 package omits `package-lock.json`; R73 regenerated the 0.15.46 lock offline in the isolated successor, matching the R72 source lock hash. The real R67 CLI now runs here and reports `STALE_SOURCE` for all 32 historical shards, not PASS. This does not change the published tarball or backfill historical receipts.
6
+ 4. `RELEASE.json.r72_hotfix` contains prepublication candidate hashes, not the final published 0.15.46 tarball/manifest hashes. The actual R72 publish fence uses external evidence and current manifest bytes. R73 documentation labels this historical snapshot; future release contracts should use explicit snapshot/final fields without self-referential embedded hashes.
7
+ 5. DEADBYTE npm package has no `license` field or root license file. Owner must decide licensing; donor MIT terms do not license DEADBYTE by implication.
8
+ 6. No donor runtime benchmark or ChatGPT remote end-to-end comparison has been performed. Static reference inspection cannot establish performance or capability superiority.
9
+ 7. R73 package version/metadata remain 0.15.46/R72 pending behavioral and release gates. This directory is a development successor, not a sealed or publishable 0.15.47 artifact.
@@ -0,0 +1,11 @@
1
+ {
2
+ "schema": "deadbyte.r74-kernel-lock-binary.v1",
3
+ "status": "candidate",
4
+ "exe": "bin/deadbyte-kernel-lock-r74.exe",
5
+ "sha256": "a1dbb8963ab89f7c99f06c78612bfa15c3fb8ed7fbc48c1b17d160d4e4f02b4c",
6
+ "source": "native/deadbyte-kernel-lock-r74.cpp",
7
+ "source_sha256": "9cb7f1f8d5e267d7f7359307ab1136b91214b021b01831075514a69f7fe0368a",
8
+ "allow_network_egress": false,
9
+ "max_output_bytes": 65536,
10
+ "exit_fail_closed": true
11
+ }
@@ -0,0 +1,16 @@
1
+ # R75 isolated authority recovery hardening
2
+
3
+ - Source predecessor: `D:\Projects\deadbyte-mcp\development\deadbyte-mcp-0.15.48-r75`, non-Git, verified 2,304-file manifest SHA-256 `e70561e261610d451d33731a5f19b8439548d7062bed4bf109c4e90f1cd8cf38` before copy.
4
+ - Published source identity remains `0.15.47`; active runtime predecessor observed read-only as `v0.15.45-34aa8d1241cfb8bf`, OFFLINE, with no plane armed. The Autonomous status reason was a broad Coding root, not verified clean-disarmed evidence.
5
+ - This successor keeps `0.15.47/R74` package metadata during behavior verification. It is neither sealed nor release-ready. Production slots, grants, pointer, and historical evidence were not mutated.
6
+ - RED: an `armed=false` Autonomous observation with an unverified reason was activation-safe; an object or Boolean observation without direct grant proof was activation-safe; a startup primary failure was hidden by cleanup failure; malformed ownership marker exited successfully. Each now has a matching focused GREEN test.
7
+ - Authority proof reads each policy by digest, resolves its policy-bound grant location within the isolated runtime, checks grant presence, and requires stable regular-file identity across reads. Host policy v1/v2 remain accepted. The broad-root issuance validator is not used for revocation observation.
8
+ - The existing R75 Autonomous revocation split and startup AggregateError were retained. The new CLI change addresses failure masking in the post-synchronization lifecycle and makes unverified marker cleanup terminal rather than success.
9
+ - R72 isolated controller fixtures verify broad-root absent-grant revocation, signed epoch revocation attempt for a present grant, external-path denial and failed epoch handling. These tests do not operate the production predecessor.
10
+ - Recovery boundary added after independent review: absent owner PID and PID reuse are not ownership evidence. A marker with no verified guardian/owner now remains in place and startup fails closed without touching authority. Identical behavioral RED 0/2 (stale marker proceeded, PID reuse passed), then GREEN 2/2; full remote-session CLI suite 30/30. The verified guardian cleanup path remains intact. This leaves manual reconciliation necessary for an orphan marker without a verified guardian; it does not authorize marker deletion.
11
+ - Remaining proof before `R75_RECOVERY_VERIFIED`: rerun final-byte full regression, Windows gate, manifest, native/bin identity, package inspection, isolated install/doctor, and final independent review.
12
+ - First full verifier run on an intermediate manifest produced 1,574 tests: 1,525 pass, 5 fail, 44 historical skips. The failures were isolated preflight fixture lacking the newly required runtime/policy proof; copied Process policy still pointed to R74; a CLI source-grep harness assumed LF only; and two frozen R72 identity tests asserted version 0.15.46 against current development 0.15.47. The first three fixtures/paths were corrected, and R72-only tests now carry explicit historical-version skip reasons. This first run is not final-byte PASS evidence.
13
+ - A later full verifier on intermediate bytes produced 1,575 tests: 1,527 pass, 2 fail, 46 historical skips. Both failures were R58 tests expecting automatic stale-marker removal from an absent/reused PID. Their isolated fixtures now assert the safer R75 contract instead: no authority command, no marker removal, no foreground READY. Focused rerun 4/4 passed. This intermediate full run is not final-byte PASS evidence.
14
+ - Final production-source gates: durable full verifier `1,575 tests / 1,529 pass / 0 fail / 46 historical/version-scoped skip`, stdout SHA-256 `740f30b8078ecc88142645b4197fcce65abfdc952f086457734769b77dd12a35`; Windows gate focused `56 / 54 pass / 0 fail / 2 historical skip`, repeated full `1,575 / 1,529 pass / 0 fail / 46 skip`, stdout SHA-256 `3b1878039f6b3f123dc2fd4d0bf58b97c51a54309dfa380c50508a35e026e9ba`. Isolated doctor PASS.
15
+ - Exact development package before this handoff update: 2,310 tar members, 12,088,356 bytes, tarball SHA-256 `ee550022b468b998e9d34d2a01e61fb85af9fe89c7812fcffa70d08fca1dda28`, isolated npm install/doctor PASS and canonical npm release `--verify-only` PASS. Publication and activation were not run. Regenerate the development manifest/package after this documentation update before using an exact package claim.
16
+ - Independent review: the owner-PID stale-marker deletion path is closed. Armed epoch validity is verified by the controller and composed with independent pinned grant-file observation, not reverified from signed epoch bytes by this module. `releaseRemoteSession` still has a read-identity then pathname-remove TOCTOU boundary; no production-only runtime or crash proof was performed. These limitations must not be described as proven away.
@@ -0,0 +1,13 @@
1
+ {
2
+ "schema": "deadbyte.r85-epoch-lock-binary.v1",
3
+ "status": "development-candidate",
4
+ "platform": "win32-x64",
5
+ "node_api_version": 8,
6
+ "source": "native/deadbyte-epoch-lock-r85.cpp",
7
+ "source_sha256": "c451c257467b6a141918400b61855bac0e466015c1f3901e8be56ce6d9c32c7f",
8
+ "addon": "bin/deadbyte-epoch-lock-r85.node",
9
+ "addon_sha256": "fb73007ca2303d66120940f192461aac2fa4c45dc4603d920f0878d77e65cfed",
10
+ "build_node_header_version": "25.9.0",
11
+ "build_node_api_header_sha256": "2d4560831e525b47b060ec8a0864ab73993df9e20215ce9f0fe7b24cd31af32a",
12
+ "build_node_import_lib_sha256": "e3577a5a4a772b21646fe05a24d53ce3727395bbbc412f326889ddf7129bc7a9"
13
+ }
@@ -0,0 +1,241 @@
1
+ #define WIN32_LEAN_AND_MEAN
2
+ #define NOMINMAX
3
+ #define NAPI_VERSION 8
4
+ #include <windows.h>
5
+ #include <node_api.h>
6
+ #include <algorithm>
7
+ #include <cstddef>
8
+ #include <cstring>
9
+ #include <memory>
10
+ #include <string>
11
+ #include <vector>
12
+
13
+ namespace {
14
+ struct Lease {
15
+ HANDLE leaf = INVALID_HANDLE_VALUE;
16
+ std::vector<HANDLE> ancestors;
17
+ bool renamed = false;
18
+ ~Lease() {
19
+ if (leaf != INVALID_HANDLE_VALUE) CloseHandle(leaf);
20
+ for (auto it = ancestors.rbegin(); it != ancestors.rend(); ++it) CloseHandle(*it);
21
+ }
22
+ };
23
+
24
+ void Throw(napi_env env, const char* message) { napi_throw_error(env, nullptr, message); }
25
+ void ThrowWin32(napi_env env, const char* message, DWORD code) {
26
+ std::string detail = std::string(message) + " (win32=" + std::to_string(code) + ")";
27
+ Throw(env, detail.c_str());
28
+ }
29
+ bool Text(napi_env env, napi_value value, std::string& out) {
30
+ size_t size = 0;
31
+ if (napi_get_value_string_utf8(env, value, nullptr, 0, &size) != napi_ok || size > 32760) return false;
32
+ out.resize(size);
33
+ size_t actual = 0;
34
+ return napi_get_value_string_utf8(env, value, out.data(), size + 1, &actual) == napi_ok && actual == size &&
35
+ out.find('\0') == std::string::npos;
36
+ }
37
+ bool Wide(const std::string& input, std::wstring& output) {
38
+ if (input.empty()) return false;
39
+ int needed = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, input.data(), static_cast<int>(input.size()), nullptr, 0);
40
+ if (needed < 1) return false;
41
+ output.resize(needed);
42
+ return MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, input.data(), static_cast<int>(input.size()),
43
+ output.data(), needed) == needed;
44
+ }
45
+ bool LocalFullPath(const std::wstring& input, std::wstring& output) {
46
+ DWORD needed = GetFullPathNameW(input.c_str(), 0, nullptr, nullptr);
47
+ if (needed < 4 || needed > 32760) return false;
48
+ std::vector<wchar_t> chars(needed);
49
+ if (GetFullPathNameW(input.c_str(), needed, chars.data(), nullptr) != needed - 1) return false;
50
+ output.assign(chars.data());
51
+ if (output.size() < 4 || !((output[0] >= L'A' && output[0] <= L'Z') ||
52
+ (output[0] >= L'a' && output[0] <= L'z')) || output[1] != L':' || output[2] != L'\\' ||
53
+ output.find(L':', 2) != std::wstring::npos || output.back() == L'\\') return false;
54
+ return true;
55
+ }
56
+ bool PinDirectory(const std::wstring& directory, Lease& lease) {
57
+ HANDLE h = CreateFileW(directory.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
58
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
59
+ if (h == INVALID_HANDLE_VALUE) return false;
60
+ FILE_ATTRIBUTE_TAG_INFO info{};
61
+ if (!GetFileInformationByHandleEx(h, FileAttributeTagInfo, &info, sizeof(info)) ||
62
+ !(info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
63
+ CloseHandle(h); SetLastError(ERROR_REPARSE_TAG_INVALID); return false;
64
+ }
65
+ lease.ancestors.push_back(h);
66
+ return true;
67
+ }
68
+ bool PinAncestors(const std::wstring& full, Lease& lease) {
69
+ const size_t end = full.find_last_of(L'\\');
70
+ if (end == std::wstring::npos || end < 2) return false;
71
+ std::wstring current = full.substr(0, 3);
72
+ if (!PinDirectory(current, lease)) return false;
73
+ size_t at = 3;
74
+ while (at < end) {
75
+ size_t next = full.find(L'\\', at);
76
+ if (next == std::wstring::npos || next > end) next = end;
77
+ if (next == at) return false;
78
+ current += full.substr(at, next - at);
79
+ if (!PinDirectory(current, lease)) return false;
80
+ current += L'\\';
81
+ at = next + 1;
82
+ }
83
+ return true;
84
+ }
85
+ DWORD ClosePinnedAncestors(Lease& lease) {
86
+ DWORD firstError = ERROR_SUCCESS;
87
+ for (auto it = lease.ancestors.rbegin(); it != lease.ancestors.rend(); ++it) {
88
+ if (!CloseHandle(*it) && firstError == ERROR_SUCCESS) firstError = GetLastError();
89
+ }
90
+ lease.ancestors.clear();
91
+ return firstError;
92
+ }
93
+ DWORD DisposeHeldLeaf(Lease& lease) {
94
+ if (lease.leaf == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
95
+ FILE_DISPOSITION_INFO disposition{};
96
+ disposition.DeleteFile = TRUE;
97
+ if (!SetFileInformationByHandle(lease.leaf, FileDispositionInfo, &disposition, sizeof(disposition)))
98
+ return GetLastError();
99
+ return ERROR_SUCCESS;
100
+ }
101
+ void ThrowWin32WithCleanup(napi_env env, const char* message, DWORD primary, DWORD cleanup) {
102
+ std::string detail = std::string(message) + " (win32=" + std::to_string(primary);
103
+ if (cleanup != ERROR_SUCCESS) detail += ", cleanup_win32=" + std::to_string(cleanup);
104
+ detail += ")";
105
+ Throw(env, detail.c_str());
106
+ }
107
+ void Finalize(napi_env, void* data, void*) { delete static_cast<Lease*>(data); }
108
+
109
+ napi_value Acquire(napi_env env, napi_callback_info info) {
110
+ size_t argc = 3;
111
+ napi_value argv[3];
112
+ if (napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok || argc != 3) {
113
+ Throw(env, "epoch native acquire arguments invalid"); return nullptr;
114
+ }
115
+ std::string pathUtf8, nonce;
116
+ void* content = nullptr;
117
+ size_t contentLength = 0;
118
+ bool buffer = false;
119
+ if (!Text(env, argv[0], pathUtf8) || napi_is_buffer(env, argv[1], &buffer) != napi_ok || !buffer ||
120
+ napi_get_buffer_info(env, argv[1], &content, &contentLength) != napi_ok ||
121
+ contentLength < 2 || contentLength > 16384 || !Text(env, argv[2], nonce) || nonce.size() != 32 ||
122
+ !std::all_of(nonce.begin(), nonce.end(), [](unsigned char c) {
123
+ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
124
+ })) {
125
+ Throw(env, "epoch native acquire arguments invalid"); return nullptr;
126
+ }
127
+ std::wstring widePath, full;
128
+ if (!Wide(pathUtf8, widePath) || !LocalFullPath(widePath, full)) {
129
+ Throw(env, "epoch native lock requires ordinary local-drive path"); return nullptr;
130
+ }
131
+ auto lease = std::make_unique<Lease>();
132
+ if (!PinAncestors(full, *lease)) {
133
+ ThrowWin32(env, "epoch native ancestor pin failed closed", GetLastError()); return nullptr;
134
+ }
135
+ DWORD existing = GetFileAttributesW(full.c_str());
136
+ if (existing != INVALID_FILE_ATTRIBUTES) {
137
+ napi_value result;
138
+ napi_get_null(env, &result);
139
+ return result;
140
+ }
141
+ DWORD existenceError = GetLastError();
142
+ if (existenceError != ERROR_FILE_NOT_FOUND && existenceError != ERROR_PATH_NOT_FOUND) {
143
+ ThrowWin32(env, "epoch native target existence uncertain", existenceError); return nullptr;
144
+ }
145
+ std::wstring nonceWide(nonce.begin(), nonce.end());
146
+ std::wstring temporary = full + L".r85-" + nonceWide + L".tmp";
147
+ lease->leaf = CreateFileW(temporary.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE | FILE_READ_ATTRIBUTES,
148
+ 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
149
+ if (lease->leaf == INVALID_HANDLE_VALUE) {
150
+ ThrowWin32(env, "epoch native temp create failed closed", GetLastError()); return nullptr;
151
+ }
152
+ FILE_ATTRIBUTE_TAG_INFO tag{};
153
+ if (!GetFileInformationByHandleEx(lease->leaf, FileAttributeTagInfo, &tag, sizeof(tag)) ||
154
+ (tag.FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))) {
155
+ DWORD error = GetLastError(); DWORD cleanup = DisposeHeldLeaf(*lease);
156
+ ThrowWin32WithCleanup(env, "epoch native leaf identity failed closed", error, cleanup); return nullptr;
157
+ }
158
+ const auto* bytes = static_cast<const unsigned char*>(content);
159
+ size_t written = 0;
160
+ while (written < contentLength) {
161
+ DWORD part = 0;
162
+ if (!WriteFile(lease->leaf, bytes + written, static_cast<DWORD>(contentLength - written), &part, nullptr) || !part) {
163
+ DWORD error = GetLastError(); DWORD cleanup = DisposeHeldLeaf(*lease);
164
+ ThrowWin32WithCleanup(env, "epoch native lock write failed closed", error, cleanup); return nullptr;
165
+ }
166
+ written += part;
167
+ }
168
+ if (!FlushFileBuffers(lease->leaf)) {
169
+ DWORD error = GetLastError(); DWORD cleanup = DisposeHeldLeaf(*lease);
170
+ ThrowWin32WithCleanup(env, "epoch native lock flush failed closed", error, cleanup); return nullptr;
171
+ }
172
+ const size_t renameSize = offsetof(FILE_RENAME_INFO, FileName) + (full.size() + 1) * sizeof(wchar_t);
173
+ std::vector<unsigned char> renameBuffer(renameSize, 0);
174
+ auto* renameInfo = reinterpret_cast<FILE_RENAME_INFO*>(renameBuffer.data());
175
+ renameInfo->ReplaceIfExists = FALSE;
176
+ renameInfo->RootDirectory = nullptr;
177
+ renameInfo->FileNameLength = static_cast<DWORD>(full.size() * sizeof(wchar_t));
178
+ std::memcpy(renameInfo->FileName, full.data(), renameInfo->FileNameLength);
179
+ if (!SetFileInformationByHandle(lease->leaf, FileRenameInfo, renameInfo, static_cast<DWORD>(renameSize))) {
180
+ DWORD error = GetLastError(); DWORD cleanup = DisposeHeldLeaf(*lease);
181
+ if (cleanup == ERROR_SUCCESS && (error == ERROR_FILE_EXISTS || error == ERROR_ALREADY_EXISTS)) {
182
+ napi_value result;
183
+ napi_get_null(env, &result);
184
+ return result;
185
+ }
186
+ ThrowWin32WithCleanup(env, "epoch native lock rename failed closed", error, cleanup); return nullptr;
187
+ }
188
+ lease->renamed = true;
189
+ napi_value result;
190
+ if (napi_create_external(env, lease.get(), Finalize, nullptr, &result) != napi_ok) {
191
+ DWORD cleanup = DisposeHeldLeaf(*lease);
192
+ ThrowWin32WithCleanup(env, "epoch native handle publication failed closed", ERROR_NOT_ENOUGH_MEMORY, cleanup);
193
+ return nullptr;
194
+ }
195
+ lease.release();
196
+ return result;
197
+ }
198
+
199
+ napi_value Release(napi_env env, napi_callback_info info) {
200
+ size_t argc = 1;
201
+ napi_value argv[1];
202
+ void* raw = nullptr;
203
+ if (napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok || argc != 1 ||
204
+ napi_get_value_external(env, argv[0], &raw) != napi_ok || !raw) {
205
+ Throw(env, "epoch native release handle invalid"); return nullptr;
206
+ }
207
+ auto* lease = static_cast<Lease*>(raw);
208
+ if (lease->leaf == INVALID_HANDLE_VALUE || !lease->renamed) {
209
+ Throw(env, "epoch native lock already released"); return nullptr;
210
+ }
211
+ FILE_DISPOSITION_INFO disposition{};
212
+ disposition.DeleteFile = TRUE;
213
+ if (!SetFileInformationByHandle(lease->leaf, FileDispositionInfo, &disposition, sizeof(disposition))) {
214
+ ThrowWin32(env, "epoch native lock disposition failed closed", GetLastError()); return nullptr;
215
+ }
216
+ if (!CloseHandle(lease->leaf)) {
217
+ ThrowWin32(env, "epoch native lock close failed closed", GetLastError()); return nullptr;
218
+ }
219
+ lease->leaf = INVALID_HANDLE_VALUE;
220
+ lease->renamed = false;
221
+ DWORD ancestorCloseError = ClosePinnedAncestors(*lease);
222
+ if (ancestorCloseError != ERROR_SUCCESS) {
223
+ ThrowWin32(env, "epoch native ancestor close failed after lock release", ancestorCloseError);
224
+ return nullptr;
225
+ }
226
+ napi_value result;
227
+ napi_get_undefined(env, &result);
228
+ return result;
229
+ }
230
+
231
+ napi_value Init(napi_env env, napi_value exports) {
232
+ napi_value acquire, release;
233
+ if (napi_create_function(env, "acquire", NAPI_AUTO_LENGTH, Acquire, nullptr, &acquire) != napi_ok ||
234
+ napi_create_function(env, "release", NAPI_AUTO_LENGTH, Release, nullptr, &release) != napi_ok ||
235
+ napi_set_named_property(env, exports, "acquire", acquire) != napi_ok ||
236
+ napi_set_named_property(env, exports, "release", release) != napi_ok) return nullptr;
237
+ return exports;
238
+ }
239
+ } // namespace
240
+
241
+ NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
@@ -0,0 +1,65 @@
1
+ #define WIN32_LEAN_AND_MEAN
2
+ #define NOMINMAX
3
+ #include <windows.h>
4
+ #include <iostream>
5
+ #include <string>
6
+
7
+ int wmain(int argc, wchar_t** argv) {
8
+ if (argc < 3) {
9
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"failed\",\"error\":\"usage: acquire <file> | probe <file>\"}\n";
10
+ return 2;
11
+ }
12
+ const std::wstring op = argv[1];
13
+ const std::wstring path = argv[2];
14
+
15
+ if (op == L"probe") {
16
+ HANDLE h = CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
17
+ if (h == INVALID_HANDLE_VALUE) {
18
+ DWORD err = GetLastError();
19
+ if (err == ERROR_SHARING_VIOLATION || err == ERROR_LOCK_VIOLATION || err == ERROR_ACCESS_DENIED) {
20
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"locked\",\"error_code\":\"SHARING_VIOLATION\",\"win32_error\":" << err << "}\n";
21
+ return 1;
22
+ }
23
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"failed\",\"error_code\":\"WIN32_ERROR\",\"win32_error\":" << err << "}\n";
24
+ return 2;
25
+ }
26
+ CloseHandle(h);
27
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"unlocked\"}\n";
28
+ return 0;
29
+ }
30
+
31
+ if (op == L"acquire") {
32
+ HANDLE h = CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
33
+ if (h == INVALID_HANDLE_VALUE) {
34
+ DWORD err = GetLastError();
35
+ if (err == ERROR_SHARING_VIOLATION || err == ERROR_LOCK_VIOLATION || err == ERROR_ACCESS_DENIED) {
36
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"locked\",\"error_code\":\"SHARING_VIOLATION\",\"win32_error\":" << err << "}\n";
37
+ return 1;
38
+ }
39
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"failed\",\"error_code\":\"WIN32_ERROR\",\"win32_error\":" << err << "}\n";
40
+ return 2;
41
+ }
42
+
43
+ std::string record = "deadbyte.kernel-lock.r74:pid=" + std::to_string(GetCurrentProcessId()) + "\n";
44
+ DWORD written = 0;
45
+ SetFilePointer(h, 0, NULL, FILE_BEGIN);
46
+ SetEndOfFile(h);
47
+ WriteFile(h, record.data(), static_cast<DWORD>(record.size()), &written, NULL);
48
+ FlushFileBuffers(h);
49
+
50
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"acquired\",\"pid\":" << GetCurrentProcessId() << "}\n";
51
+ std::cout.flush();
52
+
53
+ char buf[1];
54
+ DWORD bytesRead = 0;
55
+ ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, 1, &bytesRead, NULL);
56
+
57
+ CloseHandle(h);
58
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"released\"}\n";
59
+ std::cout.flush();
60
+ return 0;
61
+ }
62
+
63
+ std::cout << "{\"schema\":\"deadbyte.kernel-lock.r74.v1\",\"status\":\"failed\",\"error\":\"unknown operation\"}\n";
64
+ return 2;
65
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deadbyte-mcp",
3
- "version": "0.15.46",
3
+ "version": "0.15.48",
4
4
  "private": false,
5
5
  "type": "module",
6
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.",
@@ -0,0 +1,34 @@
1
+ param(
2
+ [Parameter(Mandatory=$true)][ValidatePattern('^[0-9a-f]{64}$')][string]$SourceSha256,
3
+ [string]$NodeHeaderRoot = (Join-Path $env:LOCALAPPDATA 'node-gyp\Cache\25.9.0')
4
+ )
5
+ $ErrorActionPreference='Stop'
6
+ Set-StrictMode -Version Latest
7
+ $root=Split-Path -Parent $PSScriptRoot
8
+ $source=Join-Path $root 'native\deadbyte-epoch-lock-r85.cpp'
9
+ $observed=(Get-FileHash -LiteralPath $source -Algorithm SHA256).Hash.ToLowerInvariant()
10
+ if($observed -ne $SourceSha256){throw 'R85 native source SHA mismatch; refusing build'}
11
+ $header=Join-Path $NodeHeaderRoot 'include\node\node_api.h'
12
+ $lib=Join-Path $NodeHeaderRoot 'x64\node.lib'
13
+ if(!(Test-Path -LiteralPath $header -PathType Leaf) -or !(Test-Path -LiteralPath $lib -PathType Leaf)){
14
+ throw 'R85 pinned Node-API headers/import library unavailable; no download fallback'
15
+ }
16
+ $vswhere='C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe'
17
+ if(!(Test-Path -LiteralPath $vswhere)){throw 'vswhere missing'}
18
+ $install=(& $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath | Select-Object -First 1)
19
+ if(!$install){throw 'MSVC x64 C++ toolchain missing'}
20
+ $dev=Join-Path $install 'Common7\Tools\VsDevCmd.bat'
21
+ $bin=Join-Path $root 'bin'
22
+ New-Item -ItemType Directory -Path $bin -Force | Out-Null
23
+ $output=Join-Path $bin 'deadbyte-epoch-lock-r85.node'
24
+ $object=Join-Path $bin 'deadbyte-epoch-lock-r85.obj'
25
+ $include=Join-Path $NodeHeaderRoot 'include\node'
26
+ $common='/nologo /std:c++17 /permissive- /W4 /WX /O2 /MT /EHsc /guard:cf /diagnostics:caret /utf-8 /Brepro /DUNICODE /D_UNICODE /D_WIN32_WINNT=0x0A00 /DNODE_GYP_MODULE_NAME=deadbyte_epoch_lock_r85'
27
+ $compile='cl {0} /LD /I"{1}" "{2}" /Fo:"{3}" /Fe:"{4}" /link /Brepro /INCREMENTAL:NO "{5}"' -f $common,$include,$source,$object,$output,$lib
28
+ $command='call "{0}" -no_logo -arch=x64 -host_arch=x64 && {1}' -f $dev,$compile
29
+ $cmd=if($env:ComSpec){$env:ComSpec}else{Join-Path $env:SystemRoot 'System32\cmd.exe'}
30
+ & $cmd /d /s /c $command
31
+ if($LASTEXITCODE -ne 0){throw "R85 native build failed exit=$LASTEXITCODE"}
32
+ if(!(Test-Path -LiteralPath $output -PathType Leaf)){throw 'R85 native addon missing'}
33
+ $hash=(Get-FileHash -LiteralPath $output -Algorithm SHA256).Hash.ToLowerInvariant()
34
+ Write-Output "R85_NATIVE_BUILD_PASS source_sha256=$observed addon_sha256=$hash path=$output"
@@ -0,0 +1,28 @@
1
+ param([Parameter(Mandatory=$true)][ValidatePattern('^[0-9a-f]{64}$')][string]$SourceSha256)
2
+ $ErrorActionPreference='Stop'
3
+ Set-StrictMode -Version Latest
4
+ $root=Split-Path -Parent $PSScriptRoot
5
+ $src=Join-Path $root 'native\deadbyte-kernel-lock-r74.cpp'
6
+ $observed=(Get-FileHash -LiteralPath $src -Algorithm SHA256).Hash.ToLowerInvariant()
7
+ if($observed -ne $SourceSha256){throw "R74 kernel lock source SHA mismatch; refusing build"}
8
+ Write-Output "R74_SOURCE_SHA256=$observed"
9
+ $bin=Join-Path $root 'bin'
10
+ $exe=Join-Path $bin 'deadbyte-kernel-lock-r74.exe'
11
+ $obj=Join-Path $bin 'deadbyte-kernel-lock-r74.obj'
12
+ $vswhere='C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe'
13
+ if(!(Test-Path -LiteralPath $vswhere)){throw 'vswhere missing'}
14
+ $install=(& $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath | Select-Object -First 1)
15
+ if(!$install){throw 'MSVC x64 C++ toolchain missing'}
16
+ $dev=Join-Path $install 'Common7\Tools\VsDevCmd.bat'
17
+ $cmd=if($env:ComSpec){$env:ComSpec}else{Join-Path $env:SystemRoot 'System32\cmd.exe'}
18
+ New-Item -ItemType Directory -Path $bin -Force | Out-Null
19
+ $common='/nologo /std:c++17 /permissive- /W4 /WX /O2 /MT /EHsc /guard:cf /diagnostics:caret /utf-8 /Brepro /DUNICODE /D_UNICODE /D_WIN32_WINNT=0x0A00'
20
+ $compile='cl {0} "{1}" /Fo:"{2}" /Fe:"{3}" /link /Brepro /INCREMENTAL:NO' -f $common,$src,$obj,$exe
21
+ $line='call "{0}" -no_logo -arch=x64 -host_arch=x64 && {1}' -f $dev,$compile
22
+ $output=& $cmd /d /s /c $line 2>&1
23
+ $rc=$LASTEXITCODE
24
+ $output | ForEach-Object { Write-Output ([string]$_) }
25
+ if($rc -ne 0){throw "R74 kernel lock build failed exit=$rc"}
26
+ if(!(Test-Path -LiteralPath $exe -PathType Leaf)){throw 'R74 kernel lock exe missing'}
27
+ $sha=(Get-FileHash -LiteralPath $exe -Algorithm SHA256).Hash.ToLowerInvariant()
28
+ Write-Output "R74_NATIVE_BUILD_PASS sha256=$sha path=$exe"
@@ -10,6 +10,7 @@ import {parseAuthorityObservation} from '../src/remote-authority.mjs';
10
10
  import {classifyActivationPreflight,classifyAuthorityContinuity,orchestrateActivation} from '../src/activation-preflight-r65.mjs';
11
11
  import {createEpochNativeContinuityEngine} from '../src/activation-continuity-engine-r65.mjs';
12
12
  import {createActivationClaimManager} from '../src/activation-lock-r65.mjs';
13
+ import {observeAuthorityEvidence} from '../src/activation-authority-proof-r75.mjs';
13
14
 
14
15
  const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
15
16
  const state=path.resolve(process.env.DEADBYTE_STATE_ROOT||path.join(os.homedir(),'.deadbyte-mcp'));
@@ -57,7 +58,8 @@ async function observeController(){
57
58
  if(!info.isFile()||info.isSymbolicLink())throw new Error(`activation ${plane} policy must be a regular file`);
58
59
  policySha256[plane]=await sha(file);
59
60
  }
60
- return {...observed,policy_sha256:policySha256,policy_paths:policyPaths,active_release_id:active.release_id,active_manifest_sha256:active.manifest_sha256,
61
+ const authorityProof=await observeAuthorityEvidence({stateRoot:state,policyPaths,policySha256,authority:observed.authority});
62
+ return {...observed,authority_proof:authorityProof,policy_sha256:policySha256,policy_paths:policyPaths,active_release_id:active.release_id,active_manifest_sha256:active.manifest_sha256,
61
63
  active_generation_manifest_sha256:active.generation_manifest_sha256};
62
64
  }
63
65
 
@@ -26,8 +26,8 @@ Push-Location $repo
26
26
  try {
27
27
  $pkg=Get-Content -LiteralPath 'package.json' -Raw | ConvertFrom-Json
28
28
  $release=Get-Content -LiteralPath 'RELEASE.json' -Raw | ConvertFrom-Json
29
- if($pkg.version -ne '0.15.46' -or $release.version -ne '0.15.46' -or $release.train -ne 'R72'){
30
- throw 'R72_CANDIDATE_VERSION_DRIFT'
29
+ if($pkg.version -ne '0.15.47' -or $release.version -ne '0.15.47' -or $release.train -ne 'R74'){
30
+ throw 'R74_CANDIDATE_VERSION_DRIFT'
31
31
  }
32
32
  if($release.parent.release_id -ne $parentId -or $release.parent.manifest_sha256 -ne $parentSha -or
33
33
  $release.parent.generation_manifest_sha256 -ne $parentGen){throw 'R72_PARENT_IDENTITY_DRIFT'}