deadbyte-mcp 0.8.10 → 0.10.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/CONTEXT.md +41 -0
- package/MANIFEST.SHA256 +386 -94
- package/R34-BASELINE.json +9 -0
- package/README.txt +141 -10
- package/bench/fixtures/corpus.json +36 -0
- package/bench/fixtures/r36/case-map.json +8 -0
- package/bin/WORKER-REGISTRY.txt +3 -3
- package/bin/appcontainer-stage.exe +0 -0
- package/bin/appcontainer-stage.obj +0 -0
- package/bin/bootstrap-advapi32.exe +0 -0
- package/bin/bootstrap-advapi32.obj +0 -0
- package/bin/bootstrap-exitcode.exe +0 -0
- package/bin/bootstrap-exitcode.obj +0 -0
- package/bin/bootstrap-kernel32.exe +0 -0
- package/bin/bootstrap-kernel32.obj +0 -0
- package/bin/child-control-probe.exe +0 -0
- package/bin/child-control-probe.obj +0 -0
- package/bin/child-control-stage.exe +0 -0
- package/bin/child-control-stage.obj +0 -0
- package/bin/contained-reverse-worker.exe +0 -0
- package/bin/contained-reverse-worker.obj +0 -0
- package/bin/contained-transform-worker.exe +0 -0
- package/bin/contained-transform-worker.obj +0 -0
- package/bin/containment-probe.exe +0 -0
- package/bin/containment-probe.obj +0 -0
- package/bin/deadbyte-contain.exe +0 -0
- package/bin/deadbyte-contain.obj +0 -0
- package/bin/deadbyte-exec.exe +0 -0
- package/bin/deadbyte-exec.obj +0 -0
- package/bin/deadbyte-process-host.exe +0 -0
- package/bin/deadbyte-process-host.obj +0 -0
- package/bin/deadbyte-tunnel-host.exe +0 -0
- package/bin/deadbyte-tunnel-host.obj +0 -0
- package/controller/README.TXT +12 -4
- package/controller/deadbyte-controller.config.psd1.example +14 -0
- package/controller/deadbyte-controller.ps1 +191 -20
- package/controller/deadbyte-process-policy.json +5 -5
- package/controller/deadbyte-semantic-lsp-config.json +95 -0
- package/docs/ADR-0001-PRODUCTION-BASELINE-SEAMS.md +29 -0
- package/docs/ARCHITECTURE.md +6 -5
- package/docs/R36-CAPABILITY-EVIDENCE.md +43 -0
- package/docs/superpowers/plans/2026-09-16-deadbyte-loop-engine.md +846 -0
- package/docs/superpowers/plans/2026-09-17-r35-production-successor.md +408 -0
- package/docs/superpowers/plans/2026-09-18-r36-zero-loss-autonomy.md +739 -0
- package/docs/superpowers/specs/2026-09-16-deadbyte-loop-engine-design.md +435 -0
- package/docs/superpowers/specs/2026-09-17-r35-production-successor-design.md +220 -0
- package/docs/superpowers/specs/2026-09-18-r36-zero-loss-autonomy-design.md +640 -0
- package/node_modules/typescript/LICENSE.txt +55 -0
- package/node_modules/typescript/README.md +50 -0
- package/node_modules/typescript/SECURITY.md +41 -0
- package/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
- package/node_modules/typescript/bin/tsc +2 -0
- package/node_modules/typescript/bin/tsserver +2 -0
- package/node_modules/typescript/lib/_tsc.js +133818 -0
- package/node_modules/typescript/lib/_tsserver.js +659 -0
- package/node_modules/typescript/lib/_typingsInstaller.js +222 -0
- package/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/lib.d.ts +22 -0
- package/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
- package/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
- package/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
- package/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
- package/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
- package/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
- package/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
- package/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
- package/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
- package/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
- package/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
- package/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
- package/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
- package/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
- package/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
- package/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
- package/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
- package/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
- package/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
- package/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
- package/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
- package/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
- package/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
- package/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
- package/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
- package/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
- package/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
- package/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
- package/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
- package/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
- package/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
- package/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
- package/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
- package/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
- package/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
- package/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
- package/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
- package/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
- package/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
- package/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
- package/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
- package/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
- package/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
- package/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
- package/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
- package/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
- package/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
- package/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
- package/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
- package/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
- package/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
- package/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
- package/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
- package/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
- package/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
- package/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
- package/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
- package/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
- package/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
- package/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
- package/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
- package/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
- package/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
- package/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
- package/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
- package/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
- package/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
- package/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
- package/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
- package/node_modules/typescript/lib/lib.es6.d.ts +23 -0
- package/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
- package/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
- package/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
- package/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
- package/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
- package/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
- package/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
- package/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
- package/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
- package/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
- package/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
- package/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
- package/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
- package/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
- package/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
- package/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
- package/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/tsc.js +8 -0
- package/node_modules/typescript/lib/tsserver.js +8 -0
- package/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
- package/node_modules/typescript/lib/tsserverlibrary.js +21 -0
- package/node_modules/typescript/lib/typesMap.json +497 -0
- package/node_modules/typescript/lib/typescript.d.ts +11437 -0
- package/node_modules/typescript/lib/typescript.js +200276 -0
- package/node_modules/typescript/lib/typingsInstaller.js +8 -0
- package/node_modules/typescript/lib/watchGuard.js +53 -0
- package/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/package.json +120 -0
- package/package.json +5 -3
- package/proof/CONTAINMENT-BUILD.txt +6 -6
- package/proof/R34-TASK8-SUPERVISOR-CHECKPOINT.json +29 -0
- package/proof/R34-TASK9-MCP-SURFACE-CHECKPOINT.json +28 -0
- package/scripts/capability-benchmark.mjs +27 -0
- package/scripts/deferred-slot-operation.mjs +56 -16
- package/scripts/final-closure-verify.mjs +88 -39
- package/scripts/final-closure.mjs +63 -56
- package/scripts/gate-windows.ps1 +3 -3
- package/scripts/release-parity-tests.ps1 +9 -0
- package/scripts/release-parity.mjs +149 -139
- package/scripts/semantic-preflight.ps1 +73 -0
- package/scripts/tool-surface-snapshot.mjs +73 -0
- package/scripts/windows-gate-evidence.mjs +5 -5
- package/src/audit-verify.mjs +6 -2
- package/src/autonomous-action-reconcile.mjs +142 -0
- package/src/autonomous-context-engine.mjs +256 -0
- package/src/autonomous-live-state.mjs +17 -0
- package/src/autonomous-local-supervisor.mjs +249 -0
- package/src/autonomous-loop-state.mjs +304 -0
- package/src/autonomous-mcp-tools.mjs +5 -1
- package/src/autonomous-output-contracts.mjs +26 -7
- package/src/autonomous-plan.mjs +181 -0
- package/src/autonomous-planner-contracts.mjs +79 -0
- package/src/autonomous-planner.mjs +113 -6
- package/src/autonomous-policy.mjs +15 -2
- package/src/autonomous-progress.mjs +127 -0
- package/src/autonomous-runtime.mjs +785 -62
- package/src/autonomous-supervisor-host.mjs +70 -0
- package/src/autonomous-supervisor.mjs +31 -8
- package/src/capability-benchmark-runner.mjs +193 -0
- package/src/capability-benchmark.mjs +95 -0
- package/src/capability-ledger.mjs +158 -0
- package/src/coding-mcp-tools.mjs +65 -8
- package/src/coding-output-contracts.mjs +91 -8
- package/src/coding-plane.mjs +45 -9
- package/src/coding-search.mjs +130 -47
- package/src/compact-gateway-mcp-tools.mjs +128 -0
- package/src/compact-gateway-output-contracts.mjs +16 -0
- package/src/context-provenance.mjs +86 -0
- package/src/deadbyte-cli.mjs +145 -30
- package/src/document-adapter.mjs +43 -0
- package/src/lsp-stdio-client.mjs +112 -0
- package/src/machine-fs-smoke-client.mjs +2 -1
- package/src/machine-fs.mjs +51 -8
- package/src/mcp-server.mjs +46 -9
- package/src/native-diff-v2.mjs +337 -0
- package/src/native-diff.mjs +50 -2
- package/src/observation-smoke-client.mjs +3 -2
- package/src/operator-surface.mjs +43 -0
- package/src/process-runtime.mjs +98 -11
- package/src/process-smoke-client.mjs +11 -3
- package/src/provider-circuit.mjs +125 -0
- package/src/r36-compact-disarmed-probe.mjs +50 -0
- package/src/r36-full-surface-probe.mjs +56 -0
- package/src/release-generation.mjs +44 -5
- package/src/remote-live-log.mjs +76 -0
- package/src/remote-mcp-autonomous-smoke-client.mjs +58 -15
- package/src/remote-mcp-coding-smoke-client.mjs +5 -4
- package/src/remote-mcp-r24-disarmed-smoke-client.mjs +4 -2
- package/src/remote-mcp-r34-parity-client.mjs +177 -0
- package/src/remote-mcp-r36-parity-client.mjs +175 -0
- package/src/remote-mcp-smoke-client.mjs +113 -56
- package/src/remote-result-journal.mjs +114 -0
- package/src/runtime-update.mjs +109 -9
- package/src/search-cursor.mjs +45 -0
- package/src/semantic-backend-registry.mjs +39 -0
- package/src/semantic-code.mjs +246 -0
- package/src/semantic-lsp-backend.mjs +219 -0
- package/src/semantic-lsp-config.mjs +112 -0
- package/src/tool-surface-ledger.mjs +92 -0
- package/src/version.mjs +1 -1
- package/test/audit-verify.test.mjs +1 -1
- package/test/autonomous-action-reconcile.test.mjs +106 -0
- package/test/autonomous-adversarial.test.mjs +149 -6
- package/test/autonomous-capability-r36.test.mjs +151 -0
- package/test/autonomous-context-engine.test.mjs +181 -0
- package/test/autonomous-live-state.test.mjs +27 -0
- package/test/autonomous-local-supervisor.test.mjs +403 -0
- package/test/autonomous-loop-state.test.mjs +126 -0
- package/test/autonomous-loop-v2.test.mjs +105 -0
- package/test/autonomous-loop.test.mjs +79 -1
- package/test/autonomous-output-contract.test.mjs +54 -0
- package/test/autonomous-plan.test.mjs +101 -0
- package/test/autonomous-progress.test.mjs +106 -0
- package/test/autonomous-r34-e2e.test.mjs +338 -0
- package/test/autonomous-runtime.test.mjs +3 -3
- package/test/autonomous-supervisor-integration.test.mjs +48 -3
- package/test/capability-benchmark-r36.test.mjs +107 -0
- package/test/capability-benchmark-runner.test.mjs +49 -0
- package/test/capability-benchmark-semantic-r36.test.mjs +52 -0
- package/test/capability-benchmark.test.mjs +47 -0
- package/test/capability-claims-r36.test.mjs +23 -0
- package/test/capability-ledger-r36.test.mjs +102 -0
- package/test/cli-entrypoint.test.mjs +12 -0
- package/test/coding-catalog-consistency.test.mjs +24 -0
- package/test/coding-plane.test.mjs +3 -3
- package/test/coding-runtime.test.mjs +16 -0
- package/test/coding-search-r36.test.mjs +90 -0
- package/test/compact-catalog-r36.test.mjs +37 -0
- package/test/compact-gateway-r36.test.mjs +66 -0
- package/test/contained.test.mjs +1 -1
- package/test/context-provenance.test.mjs +61 -0
- package/test/controller-r27.test.mjs +4 -3
- package/test/controller.test.mjs +52 -0
- package/test/core.test.mjs +1 -1
- package/test/deferred-slot-operation-behavior.test.mjs +5 -1
- package/test/deferred-slot-operation.test.mjs +11 -1
- package/test/document-adapter.test.mjs +23 -0
- package/test/fixtures/lsp-framed-server.mjs +35 -0
- package/test/fixtures/semantic/cpp/compile_commands.json +4 -0
- package/test/fixtures/semantic/cpp/lib.cpp +2 -0
- package/test/fixtures/semantic/cpp/lib.hpp +2 -0
- package/test/fixtures/semantic/cpp/main.cpp +2 -0
- package/test/fixtures/semantic/python/lib.py +2 -0
- package/test/fixtures/semantic/python/main.py +2 -0
- package/test/fixtures/semantic/rust/Cargo.lock +7 -0
- package/test/fixtures/semantic/rust/Cargo.toml +8 -0
- package/test/fixtures/semantic/rust/src/lib.rs +3 -0
- package/test/fixtures/semantic/rust/src/main.rs +5 -0
- package/test/fixtures/semantic/rust/src/math.rs +3 -0
- package/test/fixtures/semantic/rust/target/.rustc_info.json +1 -0
- package/test/fixtures/semantic/rust/target/CACHEDIR.TAG +3 -0
- package/test/fixtures/semantic/rust/target/debug/.cargo-lock +0 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/dep-test-lib-semantic_rust +0 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/invoked.timestamp +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/test-lib-semantic_rust +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/test-lib-semantic_rust.json +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/dep-test-bin-semantic_rust_bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/invoked.timestamp +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/test-bin-semantic_rust_bin +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/test-bin-semantic_rust_bin.json +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/dep-lib-semantic_rust +0 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/invoked.timestamp +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/lib-semantic_rust +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/lib-semantic_rust.json +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/bin-semantic_rust_bin +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/bin-semantic_rust_bin.json +1 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/dep-bin-semantic_rust_bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/invoked.timestamp +1 -0
- package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust-4c168fa33c79d09c.rmeta +0 -0
- package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust-6212ccd976aa3808.rmeta +0 -0
- package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust_bin-5dcd474439c54a26.rmeta +0 -0
- package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust_bin-d741378dccdef61c.rmeta +0 -0
- package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust-4c168fa33c79d09c.d +5 -0
- package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust-6212ccd976aa3808.d +5 -0
- package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust_bin-5dcd474439c54a26.d +6 -0
- package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust_bin-d741378dccdef61c.d +6 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/dep-graph.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/query-cache.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/work-products.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc.lock +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/dep-graph.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/metadata.rmeta +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/query-cache.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/work-products.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq.lock +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/dep-graph.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/query-cache.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/work-products.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3.lock +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/dep-graph.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/query-cache.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/work-products.bin +0 -0
- package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt.lock +0 -0
- package/test/fixtures/semantic/rust/target/flycheck0/stderr +1 -0
- package/test/fixtures/semantic/rust/target/flycheck0/stdout +5 -0
- package/test/fixtures/semantic/typescript/lib.ts +3 -0
- package/test/fixtures/semantic/typescript/main.ts +2 -0
- package/test/fixtures/tool-surface-stdio-server.mjs +14 -0
- package/test/helpers/autonomous-r34-fixture.mjs +122 -0
- package/test/lsp-stdio-client.test.mjs +72 -0
- package/test/multi-file-read.test.mjs +44 -0
- package/test/native-diff-topology-r36.test.mjs +105 -0
- package/test/observation-integration.test.mjs +3 -3
- package/test/package-boundary.test.mjs +6 -0
- package/test/process-longrun-r36.test.mjs +82 -0
- package/test/process-release-gate.test.mjs +9 -0
- package/test/production-docs.test.mjs +48 -0
- package/test/prompts-resources.test.mjs +41 -0
- package/test/provider-circuit.test.mjs +93 -0
- package/test/public-autonomous-ingress-budget.test.mjs +28 -0
- package/test/r33-closeout-regression.test.mjs +4 -3
- package/test/r33-finalization.test.mjs +26 -18
- package/test/r36-finalization.test.mjs +104 -0
- package/test/r36-release-identity.test.mjs +52 -0
- package/test/release-generation.test.mjs +23 -2
- package/test/release-version.test.mjs +27 -17
- package/test/remote-live-log-r36.test.mjs +37 -0
- package/test/remote-live-log-recovery-r36.test.mjs +41 -0
- package/test/remote-r24-catalog.test.mjs +18 -4
- package/test/remote-result-journal.test.mjs +58 -0
- package/test/remote-session-cli.test.mjs +135 -30
- package/test/runtime-self-update.test.mjs +121 -1
- package/test/semantic-backend-registry.test.mjs +29 -0
- package/test/semantic-code.test.mjs +66 -0
- package/test/semantic-lsp-backend.test.mjs +108 -0
- package/test/semantic-lsp-config.test.mjs +81 -0
- package/test/semantic-lsp-readiness.test.mjs +34 -0
- package/test/semantic-lsp-transient-empty.test.mjs +32 -0
- package/test/semantic-lsp-transient-null.test.mjs +31 -0
- package/test/semantic-multilang.test.mjs +72 -0
- package/test/semantic-r36-rename.test.mjs +82 -0
- package/test/semantic-runtime-routing.test.mjs +32 -0
- package/test/semantic-server-config-integration.test.mjs +66 -0
- package/test/tool-surface-ledger.test.mjs +59 -0
- package/test/tool-surface-snapshot.test.mjs +17 -0
- package/test/tracer-bullet.test.mjs +77 -0
- package/deadbyte-mcp-0.8.9.tgz +0 -0
package/src/process-runtime.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, randomBytes, sign as cryptoSign, verify as cryptoVerify } from 'node:crypto';
|
|
2
|
-
import { appendFile, lstat, mkdir, readFile, realpath } from 'node:fs/promises';
|
|
2
|
+
import { appendFile, lstat, mkdir, readFile, readdir, realpath, writeFile } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
5
|
import { canonicalJson } from './canonical-json.mjs';
|
|
@@ -13,6 +13,7 @@ const ZERO_SHA256 = '0'.repeat(64);
|
|
|
13
13
|
const SHA256_RE = /^[0-9a-f]{64}$/;
|
|
14
14
|
const READY_PREFIX = Buffer.from('DEADBYTE_PROCESS_HOST_READY ', 'utf8');
|
|
15
15
|
const START_TIMEOUT_MS = 8000;
|
|
16
|
+
const TERMINAL_RECOVERY_SCHEMA = 'deadbyte.process-terminal.v1';
|
|
16
17
|
|
|
17
18
|
const sha256Bytes = bytes => createHash('sha256').update(bytes).digest('hex');
|
|
18
19
|
const nowUtc = () => new Date().toISOString();
|
|
@@ -101,15 +102,85 @@ export function createProcessRuntime({ policy, signingKeyPath, verifyKeyPath })
|
|
|
101
102
|
const sessions = new Map();
|
|
102
103
|
let signingPromise = null;
|
|
103
104
|
let verifyPromise = null;
|
|
105
|
+
let hydrationPromise = null;
|
|
104
106
|
const runtime = {
|
|
105
107
|
policy,
|
|
106
108
|
signing: () => (signingPromise ??= loadPrivateSigningKey(signingKeyPath)),
|
|
107
109
|
verifying: () => (verifyPromise ??= loadPublicVerifyKey(verifyKeyPath))
|
|
108
110
|
};
|
|
109
111
|
|
|
110
|
-
function
|
|
112
|
+
async function readVerifiedJournal(sessionId, journalPath) {
|
|
113
|
+
const verifying = await runtime.verifying();
|
|
114
|
+
const text = await readFile(journalPath, 'utf8');
|
|
115
|
+
const records = text.split(/\r?\n/).filter(Boolean).map(line => JSON.parse(line));
|
|
116
|
+
let previous = ZERO_SHA256;
|
|
117
|
+
let sequence = 0;
|
|
118
|
+
for (const record of records) {
|
|
119
|
+
const { event_sha256: eventSha, key_id: keyId, signature, ...unsigned } = record;
|
|
120
|
+
if (unsigned.schema !== EVENT_SCHEMA || unsigned.session_id !== sessionId || unsigned.sequence !== sequence + 1 ||
|
|
121
|
+
unsigned.previous_event_sha256 !== previous || unsigned.policy_sha256 !== policy.policy_sha256) {
|
|
122
|
+
throw new Error('process event journal chain mismatch');
|
|
123
|
+
}
|
|
124
|
+
const canonical = Buffer.from(canonicalJson(unsigned), 'utf8');
|
|
125
|
+
const observedSha = sha256Bytes(canonical);
|
|
126
|
+
if (eventSha !== observedSha || keyId !== verifying.keyId || typeof signature !== 'string' || !cryptoVerify(null,
|
|
127
|
+
Buffer.concat([EVENT_DOMAIN, canonical]), verifying.publicKey, Buffer.from(signature, 'base64'))) {
|
|
128
|
+
throw new Error('process event journal signature mismatch');
|
|
129
|
+
}
|
|
130
|
+
previous = observedSha;
|
|
131
|
+
sequence += 1;
|
|
132
|
+
}
|
|
133
|
+
return { records, event_count: sequence, head_sha256: previous };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function hydrateTerminalSessions() {
|
|
137
|
+
if (hydrationPromise) return hydrationPromise;
|
|
138
|
+
hydrationPromise = (async () => {
|
|
139
|
+
await mkdir(policy.state_dir, { recursive: true });
|
|
140
|
+
const names = (await readdir(policy.state_dir)).filter(name => /^[0-9a-f]{64}\.jsonl$/.test(name)).sort();
|
|
141
|
+
for (const name of names) {
|
|
142
|
+
const sessionId = name.slice(0, 64);
|
|
143
|
+
if (sessions.has(sessionId)) continue;
|
|
144
|
+
let checked;
|
|
145
|
+
try { checked = await readVerifiedJournal(sessionId, path.join(policy.state_dir, name)); }
|
|
146
|
+
catch { continue; }
|
|
147
|
+
const terminal = checked.records.at(-1);
|
|
148
|
+
if (!terminal || !['exited','terminated'].includes(terminal.type) || terminal.detail?.recovery_schema !== TERMINAL_RECOVERY_SCHEMA) continue;
|
|
149
|
+
const started = checked.records.find(record => record.type === 'started');
|
|
150
|
+
if (!started || !Number.isInteger(started.detail?.child_pid) || !/^[0-9]+$/.test(String(started.detail?.creation_filetime ?? ''))) continue;
|
|
151
|
+
const profile = policy.profiles[terminal.profile_id];
|
|
152
|
+
if (!profile || !policy.roots[terminal.root_id]) continue;
|
|
153
|
+
const outputFile = terminal.detail.output_file;
|
|
154
|
+
if (typeof outputFile !== 'string' || outputFile !== `${sessionId}.stream.bin`) continue;
|
|
155
|
+
let output;
|
|
156
|
+
try { output = await readFile(path.join(policy.state_dir, outputFile)); }
|
|
157
|
+
catch { continue; }
|
|
158
|
+
if (!Number.isInteger(terminal.detail.retained_output_bytes) || terminal.detail.retained_output_bytes !== output.length ||
|
|
159
|
+
!SHA256_RE.test(terminal.detail.retained_output_sha256 ?? '') || sha256Bytes(output) !== terminal.detail.retained_output_sha256 ||
|
|
160
|
+
!SHA256_RE.test(terminal.detail.stream_sha256 ?? '') || !Number.isInteger(terminal.detail.stream_head) ||
|
|
161
|
+
!Number.isInteger(terminal.detail.earliest_offset) || terminal.detail.earliest_offset < 0 ||
|
|
162
|
+
terminal.detail.stream_head < terminal.detail.earliest_offset || terminal.detail.stream_head - terminal.detail.earliest_offset !== output.length) continue;
|
|
163
|
+
sessions.set(sessionId, {
|
|
164
|
+
session_id:sessionId, job_id:null, profile_id:terminal.profile_id, root_id:terminal.root_id,
|
|
165
|
+
cwd_relative:typeof started.detail?.cwd === 'string' ? started.detail.cwd : '.',
|
|
166
|
+
child_pid:started.detail.child_pid, creation_filetime:String(started.detail.creation_filetime),
|
|
167
|
+
state:terminal.type, exit_code:Number.isInteger(terminal.detail.exit_code) ? terminal.detail.exit_code : null,
|
|
168
|
+
earliest_offset:terminal.detail.earliest_offset, stream_head:terminal.detail.stream_head,
|
|
169
|
+
stream_sha256:terminal.detail.stream_sha256, output, control_buffer:Buffer.alloc(0),
|
|
170
|
+
journal_head_sha256:checked.head_sha256, journal_path:path.join(policy.state_dir,name), event_count:checked.event_count,
|
|
171
|
+
max_retained_output_bytes:profile.max_retained_output_bytes, stderr:'', terminate_requested:terminal.type==='terminated',
|
|
172
|
+
protocol_error:null, transport:profile.transport, win32_input_mode:false, host:null, close_promise:Promise.resolve(),
|
|
173
|
+
recovered_terminal:true
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
})();
|
|
177
|
+
return hydrationPromise;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function sessionFor(sessionId) {
|
|
111
181
|
if (typeof sessionId !== 'string' || !SHA256_RE.test(sessionId)) throw new Error('invalid process session id');
|
|
112
|
-
|
|
182
|
+
let session = sessions.get(sessionId);
|
|
183
|
+
if (!session) { await hydrateTerminalSessions(); session = sessions.get(sessionId); }
|
|
113
184
|
if (!session) throw new Error(`unknown process session '${sessionId}'`);
|
|
114
185
|
return session;
|
|
115
186
|
}
|
|
@@ -172,6 +243,7 @@ export function createProcessRuntime({ policy, signingKeyPath, verifyKeyPath })
|
|
|
172
243
|
}
|
|
173
244
|
|
|
174
245
|
async function start({ profileId, rootId, cwd = '.', args = [] }) {
|
|
246
|
+
await hydrateTerminalSessions();
|
|
175
247
|
const grant = await assertProcessArmed(policy, profileId, rootId);
|
|
176
248
|
const profile = policy.profiles[profileId];
|
|
177
249
|
if (!profile) throw new Error(`process profile '${profileId}' is not configured`);
|
|
@@ -209,8 +281,23 @@ export function createProcessRuntime({ policy, signingKeyPath, verifyKeyPath })
|
|
|
209
281
|
parseHostOutput(session, null, true);
|
|
210
282
|
if (session.state === 'starting') session.ready_reject?.(new Error(`process host exited before READY: ${session.stderr}`));
|
|
211
283
|
session.exit_code ??= Number.isInteger(code) ? code : null;
|
|
212
|
-
|
|
213
|
-
try {
|
|
284
|
+
const terminalState = session.terminate_requested ? 'terminated' : 'exited';
|
|
285
|
+
try {
|
|
286
|
+
const outputFile = `${session.session_id}.stream.bin`;
|
|
287
|
+
const retainedOutputSha256 = sha256Bytes(session.output);
|
|
288
|
+
await writeFile(path.join(policy.state_dir, outputFile), session.output, { flag:'wx' });
|
|
289
|
+
await appendEvent(runtime, session, terminalState, {
|
|
290
|
+
recovery_schema:TERMINAL_RECOVERY_SCHEMA,
|
|
291
|
+
exit_code:session.exit_code,
|
|
292
|
+
earliest_offset:session.earliest_offset,
|
|
293
|
+
stream_head:session.stream_head,
|
|
294
|
+
stream_sha256:session.stream_sha256,
|
|
295
|
+
retained_output_bytes:session.output.length,
|
|
296
|
+
retained_output_sha256:retainedOutputSha256,
|
|
297
|
+
output_file:outputFile
|
|
298
|
+
});
|
|
299
|
+
session.state = terminalState;
|
|
300
|
+
} catch {}
|
|
214
301
|
resolve();
|
|
215
302
|
});
|
|
216
303
|
});
|
|
@@ -223,7 +310,7 @@ export function createProcessRuntime({ policy, signingKeyPath, verifyKeyPath })
|
|
|
223
310
|
}
|
|
224
311
|
|
|
225
312
|
async function read({ sessionId, offset = 0, maxBytes = 65536 }) {
|
|
226
|
-
const session = sessionFor(sessionId);
|
|
313
|
+
const session = await sessionFor(sessionId);
|
|
227
314
|
if (!Number.isInteger(offset) || offset < 0 || !Number.isInteger(maxBytes) || maxBytes < 1 || maxBytes > 262144) throw new Error('invalid process read bounds');
|
|
228
315
|
if (offset > session.stream_head) throw new Error('process read offset is beyond stream head');
|
|
229
316
|
const truncated = offset < session.earliest_offset;
|
|
@@ -235,10 +322,10 @@ export function createProcessRuntime({ policy, signingKeyPath, verifyKeyPath })
|
|
|
235
322
|
truncated, data_base64: data.toString('base64'), state: session.state, exit_code: session.exit_code };
|
|
236
323
|
}
|
|
237
324
|
|
|
238
|
-
async function status({ sessionId }) { return publicSession(sessionFor(sessionId)); }
|
|
239
|
-
async function list() { return { sessions: [...sessions.values()].map(publicSession).sort((a,b) => a.session_id.localeCompare(b.session_id)) }; }
|
|
325
|
+
async function status({ sessionId }) { return publicSession(await sessionFor(sessionId)); }
|
|
326
|
+
async function list() { await hydrateTerminalSessions(); return { sessions: [...sessions.values()].map(publicSession).sort((a,b) => a.session_id.localeCompare(b.session_id)) }; }
|
|
240
327
|
async function action({ sessionId, actionId }) {
|
|
241
|
-
const session = sessionFor(sessionId);
|
|
328
|
+
const session = await sessionFor(sessionId);
|
|
242
329
|
if (session.state !== 'running') throw new Error('process action requires a running session');
|
|
243
330
|
await assertProcessArmed(policy, session.profile_id, session.root_id);
|
|
244
331
|
const profile = policy.profiles[session.profile_id];
|
|
@@ -259,7 +346,7 @@ export function createProcessRuntime({ policy, signingKeyPath, verifyKeyPath })
|
|
|
259
346
|
return { action_id: actionId, logical_bytes: logicalBytes.length, logical_sha256: logicalSha256, session: publicSession(session) };
|
|
260
347
|
}
|
|
261
348
|
async function terminate({ sessionId }) {
|
|
262
|
-
const session = sessionFor(sessionId);
|
|
349
|
+
const session = await sessionFor(sessionId);
|
|
263
350
|
if (['exited','terminated'].includes(session.state)) return publicSession(session);
|
|
264
351
|
session.terminate_requested = true;
|
|
265
352
|
session.host.kill();
|
|
@@ -268,7 +355,7 @@ export function createProcessRuntime({ policy, signingKeyPath, verifyKeyPath })
|
|
|
268
355
|
}
|
|
269
356
|
|
|
270
357
|
async function verifyEventJournal({ sessionId }) {
|
|
271
|
-
const session = sessionFor(sessionId);
|
|
358
|
+
const session = await sessionFor(sessionId);
|
|
272
359
|
const verifying = await runtime.verifying();
|
|
273
360
|
const text = await readFile(session.journal_path, 'utf8');
|
|
274
361
|
const records = text.split(/\r?\n/).filter(Boolean).map(line => JSON.parse(line));
|
|
@@ -14,10 +14,18 @@ const ZERO_SHA256 = '0'.repeat(64);
|
|
|
14
14
|
const sha256 = bytes => createHash('sha256').update(bytes).digest('hex');
|
|
15
15
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
16
16
|
const repoRoot = path.resolve(here, '..');
|
|
17
|
-
const
|
|
17
|
+
const productionPolicyPath = path.join(repoRoot, 'controller', 'deadbyte-process-policy.json');
|
|
18
18
|
const serverPath = path.join(repoRoot, 'src', 'mcp-server.mjs');
|
|
19
|
-
const policy = await loadProcessPolicy(policyPath);
|
|
20
19
|
const smokeTrust = await import('node:fs/promises').then(({ mkdtemp }) => mkdtemp(path.join(os.tmpdir(), 'deadbyte-process-smoke-')));
|
|
20
|
+
const smokePolicyPath = path.join(smokeTrust, 'smoke-policy.json');
|
|
21
|
+
const productionPolicy = JSON.parse(await readFile(productionPolicyPath, 'utf8'));
|
|
22
|
+
const smokePolicy = {
|
|
23
|
+
...productionPolicy,
|
|
24
|
+
grant_file: path.join(smokeTrust, 'process-grant.json'),
|
|
25
|
+
state_dir: path.join(smokeTrust, 'process-state')
|
|
26
|
+
};
|
|
27
|
+
await writeFile(smokePolicyPath, `${JSON.stringify(smokePolicy, null, 2)}\n`, { flag: 'wx' });
|
|
28
|
+
const policy = await loadProcessPolicy(smokePolicyPath);
|
|
21
29
|
const keys = await generateTrustKeypair({ privateKeyPath: path.join(smokeTrust, 'private.pem'), publicKeyPath: path.join(smokeTrust, 'public.pem') });
|
|
22
30
|
await mkdir(path.dirname(policy.grant_file), { recursive: true });
|
|
23
31
|
const grant = { schema: PROCESS_GRANT_SCHEMA, policy_sha256: policy.policy_sha256,
|
|
@@ -29,7 +37,7 @@ const client = new Client({ name: 'deadbyte-process-smoke', version: '0.8.0' },
|
|
|
29
37
|
{ versionNegotiation: { mode: { pin: '2026-07-28' } } });
|
|
30
38
|
const transport = new StdioClientTransport({
|
|
31
39
|
command: process.execPath, args: [serverPath], cwd: repoRoot,
|
|
32
|
-
env: { ...getDefaultEnvironment(), DEADBYTE_PROCESS_RUNTIME: '1', DEADBYTE_PROCESS_POLICY:
|
|
40
|
+
env: { ...getDefaultEnvironment(), DEADBYTE_PROCESS_RUNTIME: '1', DEADBYTE_PROCESS_POLICY: smokePolicyPath,
|
|
33
41
|
DEADBYTE_SIGNING_KEY: keys.privateKeyPath, DEADBYTE_VERIFY_KEY: keys.publicKeyPath },
|
|
34
42
|
stderr: 'pipe'
|
|
35
43
|
});
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
const HEX64=/^[0-9a-f]{64}$/;
|
|
4
|
+
const PROVIDER_ID=/^[A-Za-z0-9._:/-]{1,160}$/;
|
|
5
|
+
const FAILURE_CLASSES=new Set(['timeout','transport','rate_limit','auth','invalid_response','other']);
|
|
6
|
+
export const PROVIDER_CIRCUIT_STATES=Object.freeze(['CLOSED','OPEN','HALF_OPEN','UNAVAILABLE']);
|
|
7
|
+
|
|
8
|
+
function isoMs(value){
|
|
9
|
+
if(typeof value!=='string') return null;
|
|
10
|
+
const ms=Date.parse(value);
|
|
11
|
+
return Number.isFinite(ms)?ms:null;
|
|
12
|
+
}
|
|
13
|
+
function checkedPolicy(policy){
|
|
14
|
+
const threshold=policy?.failure_threshold;
|
|
15
|
+
const openMs=policy?.open_ms;
|
|
16
|
+
const probeLimit=policy?.half_open_probe_limit;
|
|
17
|
+
if(!Number.isInteger(threshold)||threshold<1||threshold>32) throw new Error('provider circuit failure_threshold invalid');
|
|
18
|
+
if(!Number.isInteger(openMs)||openMs<100||openMs>3_600_000) throw new Error('provider circuit open_ms invalid');
|
|
19
|
+
if(!Number.isInteger(probeLimit)||probeLimit<1||probeLimit>8) throw new Error('provider circuit half_open_probe_limit invalid');
|
|
20
|
+
return {failure_threshold:threshold,open_ms:openMs,half_open_probe_limit:probeLimit};
|
|
21
|
+
}
|
|
22
|
+
function publicState(state){
|
|
23
|
+
return Object.freeze({
|
|
24
|
+
state:state.state,
|
|
25
|
+
failure_count:state.failure_count,
|
|
26
|
+
opened_at_utc:state.opened_at_utc,
|
|
27
|
+
next_probe_at_utc:state.next_probe_at_utc,
|
|
28
|
+
last_success_at_utc:state.last_success_at_utc,
|
|
29
|
+
half_open_probes:state.half_open_probes
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function unavailable(){
|
|
33
|
+
return publicState({state:'UNAVAILABLE',failure_count:0,opened_at_utc:null,next_probe_at_utc:null,last_success_at_utc:null,half_open_probes:0});
|
|
34
|
+
}
|
|
35
|
+
function advanceTime(state,ms){
|
|
36
|
+
if(state.state==='OPEN'&&state.next_probe_ms!==null&&ms>=state.next_probe_ms){
|
|
37
|
+
state.state='HALF_OPEN';
|
|
38
|
+
state.half_open_probes=0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function openAt(state,ms,policy){
|
|
42
|
+
state.state='OPEN';
|
|
43
|
+
state.failure_count=Math.max(policy.failure_threshold,state.failure_count);
|
|
44
|
+
state.opened_at_utc=new Date(ms).toISOString();
|
|
45
|
+
state.next_probe_ms=ms+policy.open_ms;
|
|
46
|
+
state.next_probe_at_utc=new Date(state.next_probe_ms).toISOString();
|
|
47
|
+
state.half_open_probes=0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function providerCircuitId(planner){
|
|
51
|
+
if(planner?.backend!=='openai_compatible'||typeof planner.endpoint!=='string'||typeof planner.model!=='string') {
|
|
52
|
+
throw new Error('provider circuit planner identity invalid');
|
|
53
|
+
}
|
|
54
|
+
const digest=createHash('sha256').update(Buffer.from(`${planner.endpoint}\0${planner.model}`,'utf8')).digest('hex');
|
|
55
|
+
return `openai_compatible:${digest}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function classifyProviderFailure(error){
|
|
59
|
+
const name=String(error?.name??'').toLowerCase();
|
|
60
|
+
const text=String(error?.message??error??'').toLowerCase();
|
|
61
|
+
if(name==='aborterror'||/\b(?:timed?\s*out|timeout|aborted)\b/.test(text)) return 'timeout';
|
|
62
|
+
if(/(?:http\s*429|rate[ _-]?limit|too many requests)/.test(text)) return 'rate_limit';
|
|
63
|
+
if(/(?:http\s*(?:401|403)|unauthori[sz]ed|forbidden|api key|authentication)/.test(text)) return 'auth';
|
|
64
|
+
if(/(?:not json|invalid json|missing choices|invalid response|response.*(?:schema|contract|content))/.test(text)) return 'invalid_response';
|
|
65
|
+
if(/(?:econnreset|econnrefused|enotfound|fetch failed|network|socket|transport|connection)/.test(text)) return 'transport';
|
|
66
|
+
return 'other';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function deriveCircuit(events,providerId,rawPolicy,observedAtUtc){
|
|
70
|
+
if(typeof providerId!=='string'||!PROVIDER_ID.test(providerId)) throw new Error('provider circuit provider_id invalid');
|
|
71
|
+
if(!Array.isArray(events)) throw new Error('provider circuit events invalid');
|
|
72
|
+
const policy=checkedPolicy(rawPolicy);
|
|
73
|
+
const observedMs=isoMs(observedAtUtc);
|
|
74
|
+
if(observedMs===null) throw new Error('provider circuit observed time invalid');
|
|
75
|
+
const state={state:'CLOSED',failure_count:0,opened_at_utc:null,next_probe_at_utc:null,next_probe_ms:null,last_success_at_utc:null,half_open_probes:0};
|
|
76
|
+
for(const event of events){
|
|
77
|
+
const eventProvider=event?.payload?.provider_id;
|
|
78
|
+
if(eventProvider!==providerId) continue;
|
|
79
|
+
if(!HEX64.test(event?.event_sha256??'')) return unavailable();
|
|
80
|
+
const ms=isoMs(event?.created_at_utc);
|
|
81
|
+
if(ms===null||ms>observedMs) return unavailable();
|
|
82
|
+
advanceTime(state,ms);
|
|
83
|
+
if(event.type==='provider_call_failed'){
|
|
84
|
+
if(!FAILURE_CLASSES.has(event.payload?.failure_class)) return unavailable();
|
|
85
|
+
if(state.state==='HALF_OPEN'){
|
|
86
|
+
state.failure_count=policy.failure_threshold;
|
|
87
|
+
openAt(state,ms,policy);
|
|
88
|
+
}else if(state.state==='OPEN'){
|
|
89
|
+
return unavailable();
|
|
90
|
+
}else{
|
|
91
|
+
state.failure_count+=1;
|
|
92
|
+
if(state.failure_count>=policy.failure_threshold) openAt(state,ms,policy);
|
|
93
|
+
}
|
|
94
|
+
}else if(event.type==='provider_call_succeeded'){
|
|
95
|
+
if(state.state==='OPEN') return unavailable();
|
|
96
|
+
state.state='CLOSED';
|
|
97
|
+
state.failure_count=0;
|
|
98
|
+
state.opened_at_utc=null;
|
|
99
|
+
state.next_probe_at_utc=null;
|
|
100
|
+
state.next_probe_ms=null;
|
|
101
|
+
state.last_success_at_utc=new Date(ms).toISOString();
|
|
102
|
+
state.half_open_probes=0;
|
|
103
|
+
}else if(event.type==='provider_probe_started'){
|
|
104
|
+
if(state.state!=='HALF_OPEN'||state.half_open_probes>=policy.half_open_probe_limit) return unavailable();
|
|
105
|
+
state.half_open_probes+=1;
|
|
106
|
+
}else if(String(event.type??'').startsWith('provider_')){
|
|
107
|
+
return unavailable();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
advanceTime(state,observedMs);
|
|
111
|
+
return publicState(state);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function providerCallDisposition(circuit){
|
|
115
|
+
if(!circuit||!PROVIDER_CIRCUIT_STATES.includes(circuit.state)) return {allowed:false,probe:false,reason:'circuit_unavailable'};
|
|
116
|
+
if(circuit.state==='UNAVAILABLE') return {allowed:false,probe:false,reason:'circuit_unavailable'};
|
|
117
|
+
if(circuit.state==='OPEN') return {allowed:false,probe:false,reason:'circuit_open'};
|
|
118
|
+
if(circuit.state==='HALF_OPEN'){
|
|
119
|
+
if(!Number.isInteger(circuit.half_open_probes)||circuit.half_open_probes<0) return {allowed:false,probe:false,reason:'circuit_unavailable'};
|
|
120
|
+
return circuit.half_open_probes===0
|
|
121
|
+
? {allowed:true,probe:true,reason:'half_open_probe'}
|
|
122
|
+
: {allowed:false,probe:false,reason:'half_open_probe_limit'};
|
|
123
|
+
}
|
|
124
|
+
return {allowed:true,probe:false,reason:'circuit_closed'};
|
|
125
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
|
|
5
|
+
import { R36_COMPACT_GATEWAYS, R36_COMPACT_TOOL_LIMIT } from './remote-mcp-r36-parity-client.mjs';
|
|
6
|
+
|
|
7
|
+
const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
8
|
+
function structured(result,label){
|
|
9
|
+
if(result.isError) throw new Error(`${label} returned error: ${JSON.stringify(result.structuredContent??result.content)}`);
|
|
10
|
+
if(!result.structuredContent||typeof result.structuredContent!=='object') throw new Error(`${label} missing structured output`);
|
|
11
|
+
return result.structuredContent;
|
|
12
|
+
}
|
|
13
|
+
function gateway(result,label){
|
|
14
|
+
const value=structured(result,label);
|
|
15
|
+
if(value.status!=='ok'||!value.result||typeof value.result!=='object') throw new Error(`${label} gateway status=${String(value.status)}`);
|
|
16
|
+
return value.result;
|
|
17
|
+
}
|
|
18
|
+
export async function probeR36CompactDisarmed(endpointText){
|
|
19
|
+
const endpoint=new URL(endpointText);
|
|
20
|
+
if(endpoint.protocol!=='https:') throw new Error('R36 compact disarmed probe requires HTTPS');
|
|
21
|
+
const client=new Client({name:'deadbyte-r36-compact-disarmed-probe',version:'0.10.0'},{versionNegotiation:{mode:{pin:'2026-07-28'}}});
|
|
22
|
+
const transport=new StreamableHTTPClientTransport(endpoint);
|
|
23
|
+
try{
|
|
24
|
+
await client.connect(transport);
|
|
25
|
+
const listed=await client.listTools();
|
|
26
|
+
const names=listed.tools.map(tool=>tool.name).sort();
|
|
27
|
+
if(names.length>R36_COMPACT_TOOL_LIMIT) throw new Error(`R36 compact catalog exceeds ${R36_COMPACT_TOOL_LIMIT}: ${names.length}`);
|
|
28
|
+
for(const name of R36_COMPACT_GATEWAYS) if(!names.includes(name)) throw new Error(`R36 compact gateway missing ${name}`);
|
|
29
|
+
for(const tool of listed.tools) if(tool.outputSchema?.type!=='object'||tool.outputSchema?.additionalProperties!==false||!tool.outputSchema?.properties) throw new Error(`tool ${tool.name} missing strict output schema`);
|
|
30
|
+
const manifest=gateway(await client.callTool({name:'capability_manifest',arguments:{}}),'capability_manifest');
|
|
31
|
+
if(manifest.profile!=='compact'||!/^[0-9a-f]{64}$/.test(String(manifest.ledger_sha256??''))) throw new Error('R36 compact manifest malformed');
|
|
32
|
+
const required=manifest.capabilities.filter(item=>item?.production===true&&item?.host_only!==true);
|
|
33
|
+
for(const item of required) if(typeof item.compact_tool!=='string'||!names.includes(item.compact_tool)) throw new Error(`compact route missing ${String(item.id)}`);
|
|
34
|
+
const coding=structured(await client.callTool({name:'coding_session_status',arguments:{}}),'coding_session_status');
|
|
35
|
+
const autonomous=structured(await client.callTool({name:'autonomous_session_status',arguments:{}}),'autonomous_session_status');
|
|
36
|
+
if(coding.armed!==false||autonomous.coding_armed!==false||autonomous.autonomous_armed!==false) throw new Error('R36 compact authority must be DISARMED');
|
|
37
|
+
const machine=gateway(await client.callTool({name:'machine_observe',arguments:{op:'machine_status'}}),'machine_status');
|
|
38
|
+
const nonce=`r36-final-${randomBytes(16).toString('hex')}`;
|
|
39
|
+
const ping=gateway(await client.callTool({name:'machine_observe',arguments:{op:'machine_ping',nonce}}),'machine_ping');
|
|
40
|
+
if(ping.nonce!==nonce||ping.machine_id!==machine.machine_id||ping.release_id!==machine.release_id||ping.release_manifest_sha256!==machine.release_manifest_sha256) throw new Error('R36 compact machine ping binding mismatch');
|
|
41
|
+
return {status:'passed',profile:'compact',tool_count:names.length,tools:names,catalog_sha256:sha256(Buffer.from(JSON.stringify(names),'utf8')),strict_output_schemas:true,ledger_sha256:manifest.ledger_sha256,capability_count:manifest.capabilities.length,production_non_host_capabilities:required.length,capability_closure:true,coding_armed:false,autonomous_armed:false,release_id:machine.release_id,release_manifest_sha256:machine.release_manifest_sha256,machine_status:machine,machine_ping:ping,nonce,protocol_revision:client.getNegotiatedProtocolVersion()};
|
|
42
|
+
} finally {await client.close().catch(()=>{});}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const invoked=process.argv[1]&&path.resolve(process.argv[1])===fileURLToPath(import.meta.url);
|
|
46
|
+
if(invoked){
|
|
47
|
+
const endpoint=process.argv[2];
|
|
48
|
+
if(!endpoint) throw new Error('usage: node src/r36-compact-disarmed-probe.mjs https://host/mcp/path');
|
|
49
|
+
probeR36CompactDisarmed(endpoint).then(v=>console.log(JSON.stringify(v,null,2))).catch(e=>{console.error(e instanceof Error?e.stack:String(e));process.exitCode=1;});
|
|
50
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { Client } from '@modelcontextprotocol/client';
|
|
6
|
+
import { StdioClientTransport, getDefaultEnvironment } from '@modelcontextprotocol/client/stdio';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { R36_EXPECTED_TOOLS } from './remote-mcp-r36-parity-client.mjs';
|
|
9
|
+
|
|
10
|
+
const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
11
|
+
|
|
12
|
+
export async function probeR36FullSurface({packageRoot,generationRoot,stateRoot=path.join(os.homedir(),'.deadbyte-mcp')}={}){
|
|
13
|
+
const pkgRoot=packageRoot?path.resolve(packageRoot):path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
|
|
14
|
+
const gen=path.resolve(generationRoot);
|
|
15
|
+
const semanticPath=path.join(gen,'semantic-lsp-config.json');
|
|
16
|
+
const semanticSha=sha256(await readFile(semanticPath));
|
|
17
|
+
const env={
|
|
18
|
+
...getDefaultEnvironment(),
|
|
19
|
+
DEADBYTE_STATE_ROOT:path.resolve(stateRoot),
|
|
20
|
+
DEADBYTE_CORE_ROOT:pkgRoot,
|
|
21
|
+
DEADBYTE_WORKSPACE_ROOT:path.join(pkgRoot,'workspaces'),
|
|
22
|
+
DEADBYTE_CAPABILITY_PROFILE:'full',
|
|
23
|
+
DEADBYTE_AUDIT_RUNTIME:'0',
|
|
24
|
+
DEADBYTE_MACHINE_RUNTIME:'1',
|
|
25
|
+
DEADBYTE_AGENT_RUNTIME:'1',
|
|
26
|
+
DEADBYTE_PROCESS_RUNTIME:'1',
|
|
27
|
+
DEADBYTE_PROCESS_POLICY:path.join(gen,'process-policy.json'),
|
|
28
|
+
DEADBYTE_CODING_RUNTIME:'1',
|
|
29
|
+
DEADBYTE_MACHINE_FS_RUNTIME:'1',
|
|
30
|
+
DEADBYTE_OBSERVATION_RUNTIME:'1',
|
|
31
|
+
DEADBYTE_CODING_POLICY:path.join(gen,'coding-policy.json'),
|
|
32
|
+
DEADBYTE_SEMANTIC_LSP_CONFIG:semanticPath,
|
|
33
|
+
DEADBYTE_SEMANTIC_LSP_CONFIG_SHA256:semanticSha,
|
|
34
|
+
DEADBYTE_AUTONOMOUS_RUNTIME:'1',
|
|
35
|
+
DEADBYTE_AUTONOMOUS_POLICY:path.join(gen,'autonomous-policy.json'),
|
|
36
|
+
DEADBYTE_PRIVILEGED_POLICY:path.join(gen,'host-policy.json')
|
|
37
|
+
};
|
|
38
|
+
const client=new Client({name:'deadbyte-r36-full-surface-probe',version:'0.10.0'},{versionNegotiation:{mode:{pin:'2026-07-28'}}});
|
|
39
|
+
const transport=new StdioClientTransport({command:process.execPath,args:[path.join(pkgRoot,'src','mcp-server.mjs')],cwd:pkgRoot,env,stderr:'pipe'});
|
|
40
|
+
try{
|
|
41
|
+
await client.connect(transport);
|
|
42
|
+
const listed=await client.listTools();
|
|
43
|
+
const names=listed.tools.map(tool=>tool.name).sort();
|
|
44
|
+
if(JSON.stringify(names)!==JSON.stringify(R36_EXPECTED_TOOLS)) throw new Error(`R36 full catalog mismatch count=${names.length}`);
|
|
45
|
+
for(const tool of listed.tools){
|
|
46
|
+
if(tool.outputSchema?.type!=='object'||tool.outputSchema?.additionalProperties!==false||!tool.outputSchema?.properties) throw new Error(`R36 full tool ${tool.name} missing strict output schema`);
|
|
47
|
+
}
|
|
48
|
+
return {status:'passed',profile:'full',tool_count:names.length,tools:names,catalog_sha256:sha256(Buffer.from(JSON.stringify(names),'utf8')),strict_output_schemas:true,protocol_revision:client.getNegotiatedProtocolVersion()};
|
|
49
|
+
} finally {await client.close().catch(()=>{});}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if(process.argv[1]&&path.resolve(process.argv[1])===fileURLToPath(import.meta.url)){
|
|
53
|
+
const [packageRoot,generationRoot]=process.argv.slice(2);
|
|
54
|
+
if(!packageRoot||!generationRoot) throw new Error('usage: node src/r36-full-surface-probe.mjs <package-root> <generation-root>');
|
|
55
|
+
probeR36FullSurface({packageRoot,generationRoot}).then(v=>console.log(JSON.stringify(v,null,2))).catch(e=>{console.error(e instanceof Error?e.stack:String(e));process.exitCode=1;});
|
|
56
|
+
}
|
|
@@ -101,8 +101,8 @@ async function rebindProcessPolicy(raw,{developmentRoot,stateRoot,releaseRoot}){
|
|
|
101
101
|
return policy;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
function renderControllerConfig({currentConfig,coreRoot,workspaceRoot,processPolicyPath,codingPolicyPath,autonomousPolicyPath,hostPolicyPath}){
|
|
105
|
-
const bridge=currentConfig.Bridge??{},cloud=currentConfig.Cloud??{};
|
|
104
|
+
function renderControllerConfig({currentConfig,coreRoot,workspaceRoot,processPolicyPath,codingPolicyPath,semanticConfigPath,semanticConfigSha256,autonomousPolicyPath,hostPolicyPath}){
|
|
105
|
+
const supervisor=currentConfig.Supervisor??{},bridge=currentConfig.Bridge??{},cloud=currentConfig.Cloud??{};
|
|
106
106
|
return [
|
|
107
107
|
'@{'," Schema = 'deadbyte.controller.v1'",` CoreRoot = ${psQuote(coreRoot)}`,
|
|
108
108
|
` WorkspaceRoot = ${psQuote(workspaceRoot)}`,
|
|
@@ -114,9 +114,22 @@ function renderControllerConfig({currentConfig,coreRoot,workspaceRoot,processPol
|
|
|
114
114
|
` MachineFsRuntimeEnabled = ${psBool(currentConfig.MachineFsRuntimeEnabled)}`,
|
|
115
115
|
` ObservationRuntimeEnabled = ${psBool(currentConfig.ObservationRuntimeEnabled)}`,
|
|
116
116
|
` CodingPolicyFile = ${psQuote(codingPolicyPath)}`,
|
|
117
|
+
` SemanticLspConfigFile = ${psQuote(semanticConfigPath??'')}`,
|
|
118
|
+
` SemanticLspConfigSha256 = ${psQuote(semanticConfigSha256??'')}`,
|
|
117
119
|
` AutonomousRuntimeEnabled = ${psBool(currentConfig.AutonomousRuntimeEnabled)}`,
|
|
118
120
|
` AutonomousPolicyFile = ${psQuote(autonomousPolicyPath)}`,
|
|
121
|
+
` AutonomousSupervisorEnabled = ${psBool(currentConfig.AutonomousSupervisorEnabled===true)}`,
|
|
119
122
|
` HostPolicyFile = ${psQuote(hostPolicyPath??'')}`,
|
|
123
|
+
...(currentConfig.AutonomousSupervisorEnabled===true?[
|
|
124
|
+
' Supervisor = @{',
|
|
125
|
+
` FilePath = ${psQuote(supervisor.FilePath)}`,
|
|
126
|
+
` FileSha256 = ${psQuote(supervisor.FileSha256)}`,
|
|
127
|
+
` Arguments = ${psQuote(supervisor.Arguments)}`,
|
|
128
|
+
` WorkingDirectory = ${psQuote(supervisor.WorkingDirectory)}`,
|
|
129
|
+
` ScriptPath = ${psQuote(supervisor.ScriptPath)}`,
|
|
130
|
+
` ScriptSha256 = ${psQuote(supervisor.ScriptSha256)}`,
|
|
131
|
+
' }'
|
|
132
|
+
]:[]),
|
|
120
133
|
' Bridge = @{',
|
|
121
134
|
` FilePath = ${psQuote(bridge.FilePath)}`,
|
|
122
135
|
` FileSha256 = ${psQuote(bridge.FileSha256)}`,
|
|
@@ -147,6 +160,13 @@ export async function createGenerationBundle({stateRoot,releaseRoot,developmentR
|
|
|
147
160
|
if(typeof releaseId!=='string'||!/^[A-Za-z0-9._-]{1,96}$/.test(releaseId)) throw new Error('generation release id invalid');
|
|
148
161
|
if(typeof currentConfig?.Bridge?.FileSha256!=='string'||!HEX64.test(currentConfig.Bridge.FileSha256)) throw new Error('generation Bridge FileSha256 invalid');
|
|
149
162
|
if(typeof currentConfig?.Cloud?.FileSha256!=='string'||!HEX64.test(currentConfig.Cloud.FileSha256)) throw new Error('generation Cloud FileSha256 invalid');
|
|
163
|
+
if(currentConfig.AutonomousSupervisorEnabled===true){
|
|
164
|
+
if(currentConfig.AutonomousRuntimeEnabled!==true) throw new Error('generation autonomous supervisor requires AutonomousRuntimeEnabled');
|
|
165
|
+
const supervisor=currentConfig.Supervisor;
|
|
166
|
+
if(!supervisor||typeof supervisor!=='object') throw new Error('generation Supervisor launch specification missing');
|
|
167
|
+
for(const key of ['FilePath','Arguments','WorkingDirectory','ScriptPath']) if(typeof supervisor[key]!=='string'||supervisor[key].length<1) throw new Error(`generation Supervisor ${key} invalid`);
|
|
168
|
+
if(!HEX64.test(String(supervisor.FileSha256??''))||!HEX64.test(String(supervisor.ScriptSha256??''))) throw new Error('generation Supervisor hash invalid');
|
|
169
|
+
}
|
|
150
170
|
if(currentConfig.Cloud.Transport!==undefined){
|
|
151
171
|
const transport=String(currentConfig.Cloud.Transport);
|
|
152
172
|
const expectedDependencies=transport==='deadbyte.named-tunnel.v1'?3:transport==='deadbyte.named-tunnel.v2'?2:null;
|
|
@@ -167,6 +187,20 @@ export async function createGenerationBundle({stateRoot,releaseRoot,developmentR
|
|
|
167
187
|
}
|
|
168
188
|
if(typeof currentConfig?.Bridge?.ScriptPath!=='string'||!path.isAbsolute(currentConfig.Bridge.ScriptPath)) throw new Error('generation Bridge ScriptPath must be absolute');
|
|
169
189
|
if(typeof currentConfig?.Bridge?.ScriptSha256!=='string'||!HEX64.test(currentConfig.Bridge.ScriptSha256)) throw new Error('generation Bridge ScriptSha256 invalid');
|
|
190
|
+
const semanticSource=String(currentConfig.SemanticLspConfigFile??'');
|
|
191
|
+
const semanticExpected=String(currentConfig.SemanticLspConfigSha256??'').toLowerCase();
|
|
192
|
+
if(Boolean(semanticSource)!==Boolean(semanticExpected)) throw new Error('generation semantic LSP config path/SHA must be supplied together');
|
|
193
|
+
let semanticBytes=null,semanticConfigSha256=null;
|
|
194
|
+
if(semanticSource){
|
|
195
|
+
if(currentConfig.CodingRuntimeEnabled!==true) throw new Error('generation semantic LSP config requires CodingRuntimeEnabled');
|
|
196
|
+
if(!path.isAbsolute(semanticSource)) throw new Error('generation semantic LSP config path must be absolute');
|
|
197
|
+
if(!HEX64.test(semanticExpected)) throw new Error('generation semantic LSP config SHA-256 invalid');
|
|
198
|
+
const semanticStat=await lstat(semanticSource);
|
|
199
|
+
if(!semanticStat.isFile()||semanticStat.isSymbolicLink()) throw new Error('generation semantic LSP config source must be a regular file');
|
|
200
|
+
semanticBytes=await readFile(semanticSource);
|
|
201
|
+
semanticConfigSha256=sha256(semanticBytes);
|
|
202
|
+
if(semanticConfigSha256!==semanticExpected) throw new Error(`generation semantic LSP config SHA-256 mismatch: expected ${semanticExpected}, found ${semanticConfigSha256}`);
|
|
203
|
+
}
|
|
170
204
|
const parityScratchRoot=path.join(state,'runtime','r33-parity-scratch');
|
|
171
205
|
await mkdir(parityScratchRoot,{recursive:true});
|
|
172
206
|
const parityScratchStat=await lstat(parityScratchRoot);
|
|
@@ -188,10 +222,13 @@ export async function createGenerationBundle({stateRoot,releaseRoot,developmentR
|
|
|
188
222
|
machine_fs_runtime_enabled:currentConfig.MachineFsRuntimeEnabled===true,
|
|
189
223
|
observation_runtime_enabled:currentConfig.ObservationRuntimeEnabled===true,
|
|
190
224
|
autonomous_runtime_enabled:currentConfig.AutonomousRuntimeEnabled===true,
|
|
225
|
+
autonomous_supervisor_enabled:currentConfig.AutonomousSupervisorEnabled===true,
|
|
226
|
+
supervisor:currentConfig.AutonomousSupervisorEnabled===true?(currentConfig.Supervisor??{}):null,
|
|
191
227
|
bridge:currentConfig.Bridge??{},cloud:currentConfig.Cloud??{},
|
|
192
228
|
local_ready_uri:currentConfig.LocalReadyUri??'',url_regex:currentConfig.UrlRegex??'',
|
|
193
229
|
mcp_url_file:currentConfig.McpUrlFile??'',mcp_url_file_sha256:currentConfig.McpUrlFileSha256??'',mcp_path_file:currentConfig.McpPathFile??'',
|
|
194
230
|
start_timeout_seconds:Number(currentConfig.StartTimeoutSeconds??30),probe_timeout_seconds:Number(currentConfig.ProbeTimeoutSeconds??3),
|
|
231
|
+
semantic_lsp_config_sha256:semanticConfigSha256,
|
|
195
232
|
process_policy_sha256:processBytes?sha256(processBytes):null,
|
|
196
233
|
coding_policy_sha256:sha256(codingBytes),autonomous_policy_sha256:sha256(autonomousBytes),host_policy_sha256:hostBytes?sha256(hostBytes):null
|
|
197
234
|
});
|
|
@@ -201,20 +238,22 @@ export async function createGenerationBundle({stateRoot,releaseRoot,developmentR
|
|
|
201
238
|
const generationRoot=path.join(generationsRoot,generationId);
|
|
202
239
|
const processPath=processBytes?path.join(generationRoot,'process-policy.json'):null;
|
|
203
240
|
const codingPath=path.join(generationRoot,'coding-policy.json');
|
|
241
|
+
const semanticPath=semanticBytes?path.join(generationRoot,'semantic-lsp-config.json'):null;
|
|
204
242
|
const autonomousPath=path.join(generationRoot,'autonomous-policy.json');
|
|
205
243
|
const hostPath=host?path.join(generationRoot,'host-policy.json'):null;
|
|
206
244
|
const configPath=path.join(generationRoot,'controller-config.psd1');
|
|
207
245
|
const files=new Map([
|
|
208
246
|
['coding-policy.json',codingBytes],
|
|
209
247
|
['autonomous-policy.json',autonomousBytes],
|
|
210
|
-
['controller-config.psd1',Buffer.from(renderControllerConfig({currentConfig,coreRoot:release,workspaceRoot:workspace,processPolicyPath:processPath,codingPolicyPath:codingPath,autonomousPolicyPath:autonomousPath,hostPolicyPath:hostPath}),'utf8')]
|
|
248
|
+
['controller-config.psd1',Buffer.from(renderControllerConfig({currentConfig,coreRoot:release,workspaceRoot:workspace,processPolicyPath:processPath,codingPolicyPath:codingPath,semanticConfigPath:semanticPath,semanticConfigSha256,autonomousPolicyPath:autonomousPath,hostPolicyPath:hostPath}),'utf8')]
|
|
211
249
|
]);
|
|
250
|
+
if(semanticBytes) files.set('semantic-lsp-config.json',semanticBytes);
|
|
212
251
|
if(processBytes) files.set('process-policy.json',processBytes);
|
|
213
252
|
if(hostBytes) files.set('host-policy.json',hostBytes);
|
|
214
253
|
const manifestBytes=generationManifest(files),manifestSha256=sha256(manifestBytes);
|
|
215
254
|
if(existsSync(generationRoot)){
|
|
216
255
|
const verified=await verifyGenerationBundle(generationRoot,manifestSha256);
|
|
217
|
-
return {generation_id:generationId,generation_seed_sha256:generationSeed,generation_root:generationRoot,generation_manifest_sha256:manifestSha256,config_path:configPath,process_policy_path:processPath,coding_policy_path:codingPath,autonomous_policy_path:autonomousPath,host_policy_path:hostPath,adopted:true,...verified};
|
|
256
|
+
return {generation_id:generationId,generation_seed_sha256:generationSeed,generation_root:generationRoot,generation_manifest_sha256:manifestSha256,config_path:configPath,process_policy_path:processPath,coding_policy_path:codingPath,semantic_config_path:semanticPath,autonomous_policy_path:autonomousPath,host_policy_path:hostPath,adopted:true,...verified};
|
|
218
257
|
}
|
|
219
258
|
await mkdir(generationsRoot,{recursive:true});
|
|
220
259
|
const staging=path.join(generationsRoot,`.staging-${generationId}-${process.pid}-${randomBytes(4).toString('hex')}`);
|
|
@@ -229,5 +268,5 @@ export async function createGenerationBundle({stateRoot,releaseRoot,developmentR
|
|
|
229
268
|
throw error;
|
|
230
269
|
}
|
|
231
270
|
const verified=await verifyGenerationBundle(generationRoot,manifestSha256);
|
|
232
|
-
return {generation_id:generationId,generation_seed_sha256:generationSeed,generation_root:generationRoot,generation_manifest_sha256:manifestSha256,config_path:configPath,process_policy_path:processPath,coding_policy_path:codingPath,autonomous_policy_path:autonomousPath,host_policy_path:hostPath,adopted:false,...verified};
|
|
271
|
+
return {generation_id:generationId,generation_seed_sha256:generationSeed,generation_root:generationRoot,generation_manifest_sha256:manifestSha256,config_path:configPath,process_policy_path:processPath,coding_policy_path:codingPath,semantic_config_path:semanticPath,autonomous_policy_path:autonomousPath,host_policy_path:hostPath,adopted:false,...verified};
|
|
233
272
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const SAFE_ARG_KEYS=Object.freeze(['root_id','path','pattern','command_id','profile_id','session_id','goal_id','task_id','step_id','mode']);
|
|
2
|
+
const LIFECYCLE=Object.freeze({
|
|
3
|
+
device_start:'🚀 [DEVICE] Starting DEADBYTE MCP...',
|
|
4
|
+
bridge_connected:'🔌 [BRIDGE] Local bridge connected',
|
|
5
|
+
cloud_connected:'🔌 [CLOUD] Remote MCP connected',
|
|
6
|
+
session_new:'[SESSION] New foreground session',
|
|
7
|
+
session_restored:'♻️ [SESSION] Previous result stream replayed',
|
|
8
|
+
ready:'✅ [READY] DEADBYTE MCP online',
|
|
9
|
+
cleanup:'🔐 [AUTH] Revoking session authority...'
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
function safeAtom(value){
|
|
13
|
+
if(typeof value==='string'){
|
|
14
|
+
if(value.length<1||value.length>160||/[\r\n\0]/.test(value)) return null;
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
if(typeof value==='number'&&Number.isFinite(value)) return String(value);
|
|
18
|
+
if(typeof value==='boolean') return String(value);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function summarizeArgs(args){
|
|
23
|
+
if(!args||typeof args!=='object'||Array.isArray(args)) return '';
|
|
24
|
+
const parts=[];
|
|
25
|
+
for(const key of SAFE_ARG_KEYS){
|
|
26
|
+
if(!Object.hasOwn(args,key)) continue;
|
|
27
|
+
const value=safeAtom(args[key]);
|
|
28
|
+
if(value!==null) parts.push(`${key.replace(/_id$/,'')}=${value}`);
|
|
29
|
+
}
|
|
30
|
+
return parts.length?` ${parts.join(' ')}`:'';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function formatDuration(ms){
|
|
34
|
+
const value=Number(ms);
|
|
35
|
+
if(!Number.isFinite(value)||value<0) return '';
|
|
36
|
+
if(value<1000) return `${Math.round(value)}ms`;
|
|
37
|
+
return `${(value/1000).toFixed(2)}s`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function formatCompactAuditEvent(event){
|
|
41
|
+
if(!event||typeof event!=='object'||Array.isArray(event)||typeof event.tool!=='string'||!event.tool) return null;
|
|
42
|
+
if(event.event_type==='tool.request') return `▶ RUN ${event.tool}${summarizeArgs(event.args)}`;
|
|
43
|
+
if(event.event_type==='tool.result'){
|
|
44
|
+
const marker=event.outcome?.is_error===true?'❌ ERR':'✅ OK';
|
|
45
|
+
const duration=formatDuration(event.outcome?.duration_ms);
|
|
46
|
+
return `${marker} ${event.tool}${duration?` ${duration}`:''}`;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function formatRemoteLifecycle(kind){
|
|
52
|
+
if(typeof kind!=='string'||!Object.hasOwn(LIFECYCLE,kind)) throw new Error(`unknown remote lifecycle '${String(kind)}'`);
|
|
53
|
+
return LIFECYCLE[kind];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function createLiveActivityTracker(){
|
|
57
|
+
const pending=new Map();
|
|
58
|
+
return Object.freeze({
|
|
59
|
+
observe(event){
|
|
60
|
+
if(!event||typeof event!=='object'||Array.isArray(event)) return null;
|
|
61
|
+
if(event.event_type==='tool.request'&&typeof event.request_id==='string'&&event.request_id&&typeof event.tool==='string'&&event.tool){
|
|
62
|
+
pending.set(event.request_id,{request_id:event.request_id,tool:event.tool});
|
|
63
|
+
}else if(event.event_type==='tool.result'&&typeof event.request_id==='string'&&event.request_id){
|
|
64
|
+
pending.delete(event.request_id);
|
|
65
|
+
}
|
|
66
|
+
return formatCompactAuditEvent(event);
|
|
67
|
+
},
|
|
68
|
+
pending(){return [...pending.values()].map(item=>({...item}));},
|
|
69
|
+
reconcileInterrupted(reason='session_end'){
|
|
70
|
+
const suffix=reason==='session_end'?'session ended before result':reason==='recovery'?'session recovered before result':'result not observed before stream ended';
|
|
71
|
+
const lines=[...pending.values()].map(item=>`⚠️ INTERRUPTED ${item.tool} — ${suffix}`);
|
|
72
|
+
pending.clear();
|
|
73
|
+
return lines;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|