deadbyte-mcp 0.8.9 → 0.9.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 +348 -83
- package/R34-BASELINE.json +9 -0
- package/README.txt +135 -9
- package/bench/fixtures/corpus.json +17 -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 +10 -4
- package/controller/deadbyte-controller.config.psd1.example +14 -0
- package/controller/deadbyte-controller.ps1 +144 -19
- package/controller/deadbyte-process-policy.json +5 -5
- package/controller/deadbyte-semantic-lsp-config.json +95 -0
- package/deadbyte-mcp-0.8.9.tgz +0 -0
- package/docs/ADR-0001-PRODUCTION-BASELINE-SEAMS.md +29 -0
- package/docs/ARCHITECTURE.md +6 -5
- 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/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/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 +4 -2
- package/scripts/final-closure-verify.mjs +10 -10
- package/scripts/final-closure.mjs +11 -11
- package/scripts/gate-windows.ps1 +3 -3
- package/scripts/release-parity.mjs +14 -14
- 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 +255 -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-output-contracts.mjs +22 -3
- package/src/autonomous-plan.mjs +181 -0
- package/src/autonomous-planner-contracts.mjs +44 -0
- package/src/autonomous-planner.mjs +91 -6
- package/src/autonomous-policy.mjs +15 -2
- package/src/autonomous-progress.mjs +127 -0
- package/src/autonomous-runtime.mjs +601 -48
- package/src/autonomous-supervisor-host.mjs +70 -0
- package/src/autonomous-supervisor.mjs +31 -8
- package/src/capability-benchmark-runner.mjs +108 -0
- package/src/capability-benchmark.mjs +50 -0
- package/src/coding-mcp-tools.mjs +46 -3
- package/src/coding-output-contracts.mjs +45 -0
- package/src/context-provenance.mjs +86 -0
- package/src/deadbyte-cli.mjs +136 -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/mcp-server.mjs +17 -3
- package/src/observation-smoke-client.mjs +3 -2
- package/src/operator-surface.mjs +37 -0
- package/src/provider-circuit.mjs +125 -0
- package/src/release-generation.mjs +44 -5
- package/src/remote-mcp-autonomous-smoke-client.mjs +53 -14
- 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-r33-parity-client.mjs +1 -1
- package/src/remote-mcp-r34-parity-client.mjs +177 -0
- package/src/remote-mcp-smoke-client.mjs +2 -1
- package/src/remote-result-journal.mjs +114 -0
- package/src/runtime-update.mjs +58 -8
- package/src/semantic-backend-registry.mjs +39 -0
- package/src/semantic-code.mjs +179 -0
- package/src/semantic-lsp-backend.mjs +183 -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-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-runner.test.mjs +49 -0
- package/test/capability-benchmark.test.mjs +47 -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/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 +2 -1
- package/test/document-adapter.test.mjs +23 -0
- package/test/fixtures/lsp-framed-server.mjs +33 -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 +120 -0
- package/test/lsp-stdio-client.test.mjs +72 -0
- package/test/multi-file-read.test.mjs +41 -0
- package/test/observation-integration.test.mjs +3 -3
- package/test/production-docs.test.mjs +48 -0
- package/test/prompts-resources.test.mjs +35 -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 +3 -3
- package/test/r33-finalization.test.mjs +19 -16
- package/test/release-generation.test.mjs +23 -2
- package/test/release-version.test.mjs +24 -17
- package/test/remote-r24-catalog.test.mjs +5 -4
- package/test/remote-result-journal.test.mjs +58 -0
- package/test/remote-session-cli.test.mjs +150 -15
- package/test/runtime-self-update.test.mjs +63 -0
- package/test/semantic-backend-registry.test.mjs +29 -0
- package/test/semantic-code.test.mjs +66 -0
- package/test/semantic-lsp-backend.test.mjs +99 -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-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
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { access, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { startAutonomousSupervisor } from './autonomous-supervisor.mjs';
|
|
7
|
+
|
|
8
|
+
const execFileAsync=promisify(execFile);
|
|
9
|
+
export const AUTONOMOUS_SUPERVISOR_OWNER_SCHEMA='deadbyte.autonomous-supervisor-owner.v1';
|
|
10
|
+
const HEX64=/^[0-9a-f]{64}$/;
|
|
11
|
+
const RECOVERY_OPERATIONS=Object.freeze(['status','resume','park','disarmautonomous','disarmcoding','disarmprocess','disarmhost']);
|
|
12
|
+
const RECOVERY_SET=new Set(RECOVERY_OPERATIONS);
|
|
13
|
+
|
|
14
|
+
function sha256Bytes(bytes){ return createHash('sha256').update(bytes).digest('hex'); }
|
|
15
|
+
function isIso(value){ return typeof value==='string' && Number.isFinite(Date.parse(value)); }
|
|
16
|
+
function samePath(a,b){
|
|
17
|
+
if(typeof a!=='string'||typeof b!=='string') return false;
|
|
18
|
+
return path.resolve(a).toLowerCase()===path.resolve(b).toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
function assertOptions(options){
|
|
21
|
+
if(!options||typeof options!=='object'||Array.isArray(options)) throw new Error('supervisor options invalid');
|
|
22
|
+
if(typeof options.markerPath!=='string'||options.markerPath.length<3) throw new Error('supervisor markerPath invalid');
|
|
23
|
+
return path.resolve(options.markerPath);
|
|
24
|
+
}
|
|
25
|
+
function validateMarker(marker){
|
|
26
|
+
if(!marker||typeof marker!=='object'||Array.isArray(marker)) return false;
|
|
27
|
+
const keys=Object.keys(marker).sort();
|
|
28
|
+
const expected=['creation_time_utc','image_path','image_sha256','instance_nonce','pid','schema','started_at_utc'].sort();
|
|
29
|
+
if(JSON.stringify(keys)!==JSON.stringify(expected)) return false;
|
|
30
|
+
return marker.schema===AUTONOMOUS_SUPERVISOR_OWNER_SCHEMA && Number.isInteger(marker.pid) && marker.pid>0 &&
|
|
31
|
+
isIso(marker.creation_time_utc) && typeof marker.image_path==='string' && marker.image_path.length>3 &&
|
|
32
|
+
HEX64.test(marker.image_sha256??'') && HEX64.test(marker.instance_nonce??'') && isIso(marker.started_at_utc);
|
|
33
|
+
}
|
|
34
|
+
async function powershellPath(){
|
|
35
|
+
if(process.platform!=='win32') return null;
|
|
36
|
+
const systemRoot=process.env.SystemRoot || process.env.WINDIR;
|
|
37
|
+
if(systemRoot){
|
|
38
|
+
const candidate=path.join(systemRoot,'System32','WindowsPowerShell','v1.0','powershell.exe');
|
|
39
|
+
try { await access(candidate); return candidate; } catch {}
|
|
40
|
+
}
|
|
41
|
+
return 'powershell.exe';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function observeCurrentProcessIdentity(pid=process.pid){
|
|
45
|
+
if(!Number.isInteger(pid)||pid<=0) throw new Error('process pid invalid');
|
|
46
|
+
const shell=await powershellPath();
|
|
47
|
+
if(!shell) return null;
|
|
48
|
+
const script=`$ErrorActionPreference='Stop'; $p=Get-Process -Id ${pid} -ErrorAction Stop; $image=''; try { $image=[string]$p.Path } catch {}; if([string]::IsNullOrWhiteSpace($image)){ try { $c=Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}' -ErrorAction Stop; $image=[string]$c.ExecutablePath } catch {} }; if([string]::IsNullOrWhiteSpace($image)){ exit 3 }; [pscustomobject]@{pid=[int]$p.Id;creation_time_utc=$p.StartTime.ToUniversalTime().ToString('o');image_path=[System.IO.Path]::GetFullPath($image)} | ConvertTo-Json -Compress`;
|
|
49
|
+
let stdout;
|
|
50
|
+
try {
|
|
51
|
+
({stdout}=await execFileAsync(shell,['-NoProfile','-NonInteractive','-ExecutionPolicy','Bypass','-Command',script],{
|
|
52
|
+
windowsHide:true,timeout:10_000,maxBuffer:1024*1024,encoding:'utf8'
|
|
53
|
+
}));
|
|
54
|
+
} catch { return null; }
|
|
55
|
+
let parsed;
|
|
56
|
+
try { parsed=JSON.parse(String(stdout).trim()); } catch { return null; }
|
|
57
|
+
if(parsed?.pid!==pid||!isIso(parsed?.creation_time_utc)||typeof parsed?.image_path!=='string') return null;
|
|
58
|
+
const imagePath=path.resolve(parsed.image_path);
|
|
59
|
+
let imageBytes;
|
|
60
|
+
try { imageBytes=await readFile(imagePath); } catch { return null; }
|
|
61
|
+
return Object.freeze({
|
|
62
|
+
pid,creation_time_utc:new Date(parsed.creation_time_utc).toISOString(),
|
|
63
|
+
image_path:imagePath,image_sha256:sha256Bytes(imageBytes)
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function readMarker(markerPath){
|
|
68
|
+
let raw;
|
|
69
|
+
try { raw=await readFile(markerPath); }
|
|
70
|
+
catch(error){ if(error?.code==='ENOENT') return {exists:false}; throw error; }
|
|
71
|
+
let marker;
|
|
72
|
+
try { marker=JSON.parse(raw.toString('utf8')); }
|
|
73
|
+
catch { return {exists:true,raw,raw_sha256:sha256Bytes(raw),valid:false,marker:null}; }
|
|
74
|
+
return {exists:true,raw,raw_sha256:sha256Bytes(raw),valid:validateMarker(marker),marker};
|
|
75
|
+
}
|
|
76
|
+
function markerFor(identity){
|
|
77
|
+
return {
|
|
78
|
+
schema:AUTONOMOUS_SUPERVISOR_OWNER_SCHEMA,
|
|
79
|
+
pid:identity.pid,creation_time_utc:identity.creation_time_utc,image_path:identity.image_path,
|
|
80
|
+
image_sha256:identity.image_sha256,instance_nonce:randomBytes(32).toString('hex'),
|
|
81
|
+
started_at_utc:new Date().toISOString()
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function currentMarker(){
|
|
85
|
+
const identity=await observeCurrentProcessIdentity();
|
|
86
|
+
if(!identity) throw new Error('supervisor current Windows process identity unavailable');
|
|
87
|
+
return markerFor(identity);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function observeSupervisor(options={}){
|
|
91
|
+
const markerPath=assertOptions(options);
|
|
92
|
+
const stored=await readMarker(markerPath);
|
|
93
|
+
if(!stored.exists) return {status:'absent',live:false,reason:'no_owner',marker:null,marker_sha256:null};
|
|
94
|
+
if(!stored.valid) return {status:'unverified',live:false,reason:'marker_invalid',marker:stored.marker,marker_sha256:stored.raw_sha256};
|
|
95
|
+
const observed=await observeCurrentProcessIdentity(stored.marker.pid);
|
|
96
|
+
if(!observed) return {status:'stale',live:false,reason:'process_unobservable',marker:stored.marker,marker_sha256:stored.raw_sha256};
|
|
97
|
+
if(observed.creation_time_utc!==new Date(stored.marker.creation_time_utc).toISOString()) {
|
|
98
|
+
return {status:'stale',live:false,reason:'pid_reused',marker:stored.marker,observation:observed,marker_sha256:stored.raw_sha256};
|
|
99
|
+
}
|
|
100
|
+
if(!samePath(observed.image_path,stored.marker.image_path)||observed.image_sha256!==stored.marker.image_sha256) {
|
|
101
|
+
return {status:'stale',live:false,reason:'identity_mismatch',marker:stored.marker,observation:observed,marker_sha256:stored.raw_sha256};
|
|
102
|
+
}
|
|
103
|
+
return {status:'owned',live:true,reason:'live_verified_owner',marker:stored.marker,observation:observed,marker_sha256:stored.raw_sha256};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function claimSupervisor(options={}){
|
|
107
|
+
const markerPath=assertOptions(options);
|
|
108
|
+
const marker=await currentMarker();
|
|
109
|
+
await mkdir(path.dirname(markerPath),{recursive:true});
|
|
110
|
+
try {
|
|
111
|
+
await writeFile(markerPath,`${JSON.stringify(marker)}\n`,{flag:'wx',mode:0o600});
|
|
112
|
+
} catch(error){
|
|
113
|
+
if(error?.code==='EEXIST') throw new Error('supervisor owner marker already exists; takeover required');
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
return {status:'claimed',instance_nonce:marker.instance_nonce,marker};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function takeoverSupervisor(options={}){
|
|
120
|
+
const markerPath=assertOptions(options);
|
|
121
|
+
const prior=await observeSupervisor({markerPath});
|
|
122
|
+
if(prior.live&&prior.reason==='live_verified_owner') throw new Error('supervisor takeover refused: live verified owner');
|
|
123
|
+
if(prior.reason==='no_owner') return claimSupervisor({markerPath});
|
|
124
|
+
const marker=await currentMarker();
|
|
125
|
+
const before=await readMarker(markerPath);
|
|
126
|
+
if(!before.exists||before.raw_sha256!==prior.marker_sha256) throw new Error('supervisor ownership changed during takeover');
|
|
127
|
+
const temp=path.join(path.dirname(markerPath),`.${path.basename(markerPath)}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`);
|
|
128
|
+
try {
|
|
129
|
+
await writeFile(temp,`${JSON.stringify(marker)}\n`,{flag:'wx',mode:0o600});
|
|
130
|
+
const check=await readMarker(markerPath);
|
|
131
|
+
if(!check.exists||check.raw_sha256!==prior.marker_sha256) throw new Error('supervisor ownership changed during takeover');
|
|
132
|
+
await rename(temp,markerPath);
|
|
133
|
+
} finally { await rm(temp,{force:true}).catch(()=>{}); }
|
|
134
|
+
return {status:'claimed',instance_nonce:marker.instance_nonce,marker,taken_over_reason:prior.reason};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export async function releaseSupervisor(options={}){
|
|
138
|
+
const markerPath=assertOptions(options);
|
|
139
|
+
if(typeof options.instanceNonce!=='string'||!HEX64.test(options.instanceNonce)) throw new Error('supervisor ownership nonce invalid');
|
|
140
|
+
const observed=await observeSupervisor({markerPath});
|
|
141
|
+
if(observed.reason==='no_owner') return {status:'absent'};
|
|
142
|
+
if(!observed.live||observed.reason!=='live_verified_owner') throw new Error(`supervisor ownership is not a live verified owner: ${observed.reason}`);
|
|
143
|
+
if(observed.marker.instance_nonce!==options.instanceNonce) throw new Error('supervisor ownership nonce mismatch');
|
|
144
|
+
if(observed.marker.pid!==process.pid) throw new Error('supervisor ownership belongs to another process');
|
|
145
|
+
const current=await observeCurrentProcessIdentity();
|
|
146
|
+
if(!current||current.creation_time_utc!==observed.observation.creation_time_utc||
|
|
147
|
+
!samePath(current.image_path,observed.observation.image_path)||current.image_sha256!==observed.observation.image_sha256) {
|
|
148
|
+
throw new Error('supervisor ownership current process identity mismatch');
|
|
149
|
+
}
|
|
150
|
+
const check=await readMarker(markerPath);
|
|
151
|
+
if(!check.exists||check.raw_sha256!==observed.marker_sha256) throw new Error('supervisor ownership changed before release');
|
|
152
|
+
await rm(markerPath,{force:false});
|
|
153
|
+
return {status:'released'};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function validateSupervisorRecoveryRequest(request){
|
|
157
|
+
if(!request||typeof request!=='object'||Array.isArray(request)) throw new Error('supervisor recovery request invalid');
|
|
158
|
+
const keys=Object.keys(request);
|
|
159
|
+
if(keys.length!==1||keys[0]!=='operation') throw new Error('supervisor recovery request fields invalid');
|
|
160
|
+
if(typeof request.operation!=='string'||!RECOVERY_SET.has(request.operation)) throw new Error('supervisor recovery operation is not in allowlist');
|
|
161
|
+
return {operation:request.operation};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export async function runPinnedControllerOperation(options={}){
|
|
165
|
+
if(!options||typeof options!=='object'||Array.isArray(options)) throw new Error('supervisor controller options invalid');
|
|
166
|
+
const keys=Object.keys(options).sort();
|
|
167
|
+
if(JSON.stringify(keys)!==JSON.stringify(['controllerPath','controllerSha256','operation'])) {
|
|
168
|
+
throw new Error('supervisor controller options fields invalid');
|
|
169
|
+
}
|
|
170
|
+
if(typeof options.controllerPath!=='string'||options.controllerPath.length<3) throw new Error('supervisor controller path invalid');
|
|
171
|
+
if(typeof options.controllerSha256!=='string'||!HEX64.test(options.controllerSha256)) throw new Error('supervisor controller hash invalid');
|
|
172
|
+
const {operation}=validateSupervisorRecoveryRequest({operation:options.operation});
|
|
173
|
+
const controllerPath=path.resolve(options.controllerPath);
|
|
174
|
+
let bytes;
|
|
175
|
+
try { bytes=await readFile(controllerPath); }
|
|
176
|
+
catch(error){ throw new Error(`supervisor controller unavailable: ${error?.code??String(error)}`); }
|
|
177
|
+
const actual=sha256Bytes(bytes);
|
|
178
|
+
if(actual!==options.controllerSha256) throw new Error(`supervisor controller hash mismatch: expected ${options.controllerSha256}, found ${actual}`);
|
|
179
|
+
const shell=await powershellPath();
|
|
180
|
+
if(!shell) throw new Error('supervisor controller requires Windows PowerShell');
|
|
181
|
+
try {
|
|
182
|
+
const {stdout,stderr}=await execFileAsync(shell,['-NoProfile','-NonInteractive','-ExecutionPolicy','Bypass','-File',controllerPath,operation],{
|
|
183
|
+
windowsHide:true,timeout:120_000,maxBuffer:4*1024*1024,encoding:'utf8'
|
|
184
|
+
});
|
|
185
|
+
return {exit_code:0,stdout:String(stdout??''),stderr:String(stderr??'')};
|
|
186
|
+
} catch(error) {
|
|
187
|
+
return {exit_code:Number.isInteger(error?.code)?error.code:1,stdout:String(error?.stdout??''),stderr:String(error?.stderr??error?.message??'')};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function parseRecoveryStatus(stdout){
|
|
192
|
+
const text=String(stdout??'');
|
|
193
|
+
const state=text.match(/^DEADBYTE MCP\s*=\s*(ONLINE|PARKED|OFFLINE|DEGRADED)\s*$/mi)?.[1]??null;
|
|
194
|
+
const authority={
|
|
195
|
+
process:text.match(/^Process plane\s*:\s*(ARMED|DISARMED|UNCONFIGURED)\b/mi)?.[1]??null,
|
|
196
|
+
coding:text.match(/^Coding plane\s*:\s*(ARMED|DISARMED|UNCONFIGURED)\b/mi)?.[1]??null,
|
|
197
|
+
autonomous:text.match(/^Autonomous\s*:\s*(ARMED|DISARMED|UNCONFIGURED)\b/mi)?.[1]??null,
|
|
198
|
+
host:text.match(/^Host plane\s*:\s*(ARMED|DISARMED|UNCONFIGURED)\b/mi)?.[1]??null
|
|
199
|
+
};
|
|
200
|
+
return {runtime_state:state,authority};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export async function recoverManagedRuntime({runControllerOperation}={}){
|
|
204
|
+
if(typeof runControllerOperation!=='function') throw new Error('supervisor recovery requires controller runner');
|
|
205
|
+
const operations=['resume','disarmautonomous','disarmcoding','disarmprocess','disarmhost','status'];
|
|
206
|
+
const results=[];
|
|
207
|
+
for(const operation of operations){
|
|
208
|
+
const request=validateSupervisorRecoveryRequest({operation});
|
|
209
|
+
const result=await runControllerOperation(request);
|
|
210
|
+
if(!result||result.exit_code!==0) throw new Error(`supervisor recovery operation '${operation}' failed`);
|
|
211
|
+
results.push({operation,...result});
|
|
212
|
+
}
|
|
213
|
+
const observed=parseRecoveryStatus(results.at(-1)?.stdout);
|
|
214
|
+
if(observed.runtime_state!=='ONLINE') throw new Error(`supervisor recovery expected ONLINE, observed ${observed.runtime_state??'unknown'}`);
|
|
215
|
+
for(const [plane,value] of Object.entries(observed.authority)) {
|
|
216
|
+
if(value!=='DISARMED') throw new Error(`supervisor recovery requires ${plane} DISARMED, observed ${value??'unknown'}`);
|
|
217
|
+
}
|
|
218
|
+
return {status:'recovered',...observed,operations:results.map(item=>item.operation)};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export async function startLocalSupervisorHost({runtime,policy=runtime?.policy,markerPath,idleDelayMs=750,maxCycles=32,logger=console,continuous=true}={}){
|
|
222
|
+
if(!runtime||!policy) throw new Error('local supervisor host requires runtime + policy');
|
|
223
|
+
const observed=await observeSupervisor({markerPath});
|
|
224
|
+
const claim=observed.reason==='no_owner'
|
|
225
|
+
? await claimSupervisor({markerPath})
|
|
226
|
+
: await takeoverSupervisor({markerPath});
|
|
227
|
+
let supervisor;
|
|
228
|
+
try {
|
|
229
|
+
supervisor=startAutonomousSupervisor({runtime,policy,idleDelayMs,maxCycles,logger,continuous});
|
|
230
|
+
} catch(error) {
|
|
231
|
+
await releaseSupervisor({markerPath,instanceNonce:claim.instance_nonce}).catch(()=>{});
|
|
232
|
+
throw error;
|
|
233
|
+
}
|
|
234
|
+
let stopped=false;
|
|
235
|
+
return Object.freeze({
|
|
236
|
+
marker_path:path.resolve(markerPath),instance_nonce:claim.instance_nonce,supervisor,
|
|
237
|
+
get running(){ return !stopped&&supervisor.running; },
|
|
238
|
+
async scanNow(){ if(stopped) throw new Error('local supervisor host stopped'); return supervisor.scanNow(); },
|
|
239
|
+
async stop(){
|
|
240
|
+
if(stopped) return {status:'stopped'};
|
|
241
|
+
stopped=true;
|
|
242
|
+
await supervisor.stop();
|
|
243
|
+
await releaseSupervisor({markerPath,instanceNonce:claim.instance_nonce});
|
|
244
|
+
return {status:'stopped'};
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export const AUTONOMOUS_SUPERVISOR_RECOVERY_OPERATIONS=RECOVERY_OPERATIONS;
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { canonicalJson } from './canonical-json.mjs';
|
|
3
|
+
import { activePlanStep } from './autonomous-plan.mjs';
|
|
4
|
+
|
|
5
|
+
export const AUTONOMOUS_LOOP_STATE_SCHEMA = 'deadbyte.autonomous-loop-state.v2';
|
|
6
|
+
export const AUTONOMOUS_LOOP_PHASES = Object.freeze([
|
|
7
|
+
'PLAN','INSPECT','ACT','VERIFY','CRITIC','REPAIR','RELEASE','WAITING','SUCCEEDED','FAILED'
|
|
8
|
+
]);
|
|
9
|
+
|
|
10
|
+
const PHASES = new Set(AUTONOMOUS_LOOP_PHASES);
|
|
11
|
+
const LEGACY_PHASES = new Map([
|
|
12
|
+
['PLANNING','PLAN'],['INSPECTING','INSPECT'],['ACTING','ACT'],['VERIFYING','VERIFY'],
|
|
13
|
+
['REPLANNING','REPAIR'],['WAITING','WAITING'],['COMPLETE','SUCCEEDED']
|
|
14
|
+
]);
|
|
15
|
+
const HEX64 = /^[0-9a-f]{64}$/;
|
|
16
|
+
const ZERO_HASH = '0'.repeat(64);
|
|
17
|
+
const FAILURE_CLASSES = new Set([
|
|
18
|
+
'verification_failure','stale_precondition','no_progress','insufficient_proof','provider_failure','other'
|
|
19
|
+
]);
|
|
20
|
+
const MUTABLE_TERMINAL_EVENTS = new Set([
|
|
21
|
+
'plan_created','plan_replanned','action_started','action_completed','inspection_completed','inspect_completed',
|
|
22
|
+
'progress_judged','critic_classified','repair_started','repair_completed','waiting_entered','waiting_resumed',
|
|
23
|
+
'native_diff_committed','step_completed','phase_changed'
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
function sha256Object(value) {
|
|
27
|
+
return createHash('sha256').update(Buffer.from(canonicalJson(value),'utf8')).digest('hex');
|
|
28
|
+
}
|
|
29
|
+
function hash(value,label) {
|
|
30
|
+
if (typeof value !== 'string' || !HEX64.test(value)) throw new Error(`${label} invalid`);
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
function requireObject(value,label) {
|
|
34
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} invalid`);
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
function requireText(value,label,max=1024) {
|
|
38
|
+
if (typeof value !== 'string' || value.length < 1 || value.length > max) throw new Error(`${label} invalid`);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function normalizePhase(value,label) {
|
|
42
|
+
const normalized = LEGACY_PHASES.get(value) ?? value;
|
|
43
|
+
if (!PHASES.has(normalized)) throw new Error(`${label} invalid`);
|
|
44
|
+
return normalized;
|
|
45
|
+
}
|
|
46
|
+
function isLegacyPhase(value) { return LEGACY_PHASES.has(value) && !PHASES.has(value); }
|
|
47
|
+
function terminal(phase) { return phase === 'SUCCEEDED' || phase === 'FAILED'; }
|
|
48
|
+
|
|
49
|
+
function normalizedPlanForRepair(plan) {
|
|
50
|
+
if (!plan) return null;
|
|
51
|
+
return {
|
|
52
|
+
schema:plan.schema ?? null,
|
|
53
|
+
title:plan.title ?? null,
|
|
54
|
+
steps:Array.isArray(plan.steps) ? plan.steps.map(step => ({
|
|
55
|
+
step_id:step.step_id,
|
|
56
|
+
intent:step.intent,
|
|
57
|
+
status:step.status,
|
|
58
|
+
...(Array.isArray(step.evidence) ? {evidence:step.evidence} : {})
|
|
59
|
+
})) : []
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function repairFingerprint({plan,hypothesis}) {
|
|
64
|
+
requireText(hypothesis,'repair hypothesis',2048);
|
|
65
|
+
return sha256Object({
|
|
66
|
+
schema:'deadbyte.autonomous-repair-fingerprint.v1',
|
|
67
|
+
hypothesis,
|
|
68
|
+
plan:normalizedPlanForRepair(plan)
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function setPlan(state,plan,{replanned=false}={}) {
|
|
73
|
+
requireObject(plan,'loop plan');
|
|
74
|
+
const current = activePlanStep(plan);
|
|
75
|
+
state.plan = structuredClone(plan);
|
|
76
|
+
state.plan_id = hash(plan.plan_id,'loop plan_id');
|
|
77
|
+
if (!Number.isInteger(plan.plan_version) || plan.plan_version < 1) throw new Error('loop plan_version invalid');
|
|
78
|
+
state.plan_version = plan.plan_version;
|
|
79
|
+
state.current_step = current ? structuredClone(current) : null;
|
|
80
|
+
if (replanned) state.replan_count += 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function setPhase(state,rawFrom,rawTo) {
|
|
84
|
+
const from=normalizePhase(rawFrom,'loop phase from');
|
|
85
|
+
const to=normalizePhase(rawTo,'loop phase to');
|
|
86
|
+
if (state.phase !== from) throw new Error(`loop phase mismatch: journal says ${from} but derived phase is ${state.phase}`);
|
|
87
|
+
if (terminal(state.phase) && to !== state.phase) throw new Error(`loop ${state.phase} phase is terminal`);
|
|
88
|
+
const legacyTransition=isLegacyPhase(rawFrom)||isLegacyPhase(rawTo);
|
|
89
|
+
if (!legacyTransition && from === 'REPAIR' && ['ACT','INSPECT'].includes(to)) {
|
|
90
|
+
if (!state.repair?.completed || state.repair.previous_fingerprint === state.repair.repair_fingerprint) {
|
|
91
|
+
throw new Error('loop REPAIR requires repair fingerprint change before another ACT/INSPECT');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
state.phase=to;
|
|
95
|
+
if (to !== 'WAITING') {
|
|
96
|
+
state.wait_reason=null;
|
|
97
|
+
state.pending_approval=false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function classifyCritic(payload) {
|
|
102
|
+
const failureClass=requireText(payload.failure_class,'loop critic failure_class',64);
|
|
103
|
+
if (!FAILURE_CLASSES.has(failureClass)) throw new Error('loop critic failure_class invalid');
|
|
104
|
+
return {
|
|
105
|
+
failure_class:failureClass,
|
|
106
|
+
evidence_fingerprint:hash(payload.evidence_fingerprint,'loop critic evidence_fingerprint'),
|
|
107
|
+
detail:requireText(payload.detail,'loop critic detail',1024)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function repairStart(state,payload) {
|
|
112
|
+
if (state.phase !== 'REPAIR') throw new Error(`loop repair_started requires REPAIR phase, got ${state.phase}`);
|
|
113
|
+
const hypothesis=requireText(payload.hypothesis,'loop repair hypothesis',2048);
|
|
114
|
+
const previous=hash(payload.previous_fingerprint,'loop repair previous_fingerprint');
|
|
115
|
+
const expected=repairFingerprint({plan:state.plan,hypothesis});
|
|
116
|
+
if (previous !== expected) throw new Error('loop repair previous fingerprint mismatch');
|
|
117
|
+
state.repair={previous_fingerprint:previous,repair_fingerprint:null,hypothesis,completed:false};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function repairComplete(state,payload) {
|
|
121
|
+
if (state.phase !== 'REPAIR') throw new Error(`loop repair_completed requires REPAIR phase, got ${state.phase}`);
|
|
122
|
+
if (!state.repair) throw new Error('loop repair_completed requires repair_started');
|
|
123
|
+
const previous=hash(payload.previous_fingerprint,'loop repair completed previous_fingerprint');
|
|
124
|
+
const next=hash(payload.repair_fingerprint,'loop repair completed repair_fingerprint');
|
|
125
|
+
const hypothesis=requireText(payload.hypothesis,'loop repair completed hypothesis',2048);
|
|
126
|
+
if (previous !== state.repair.previous_fingerprint) throw new Error('loop repair previous fingerprint changed');
|
|
127
|
+
const expected=repairFingerprint({plan:state.plan,hypothesis});
|
|
128
|
+
if (next !== expected) throw new Error('loop repair fingerprint does not bind current plan/hypothesis');
|
|
129
|
+
if (next === previous) throw new Error('loop repair fingerprint must change before another ACT');
|
|
130
|
+
state.repair={previous_fingerprint:previous,repair_fingerprint:next,hypothesis,completed:true};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function deriveLoopState(goal,events) {
|
|
134
|
+
requireObject(goal,'loop goal');
|
|
135
|
+
const goalId=hash(goal.goal_id,'loop goal_id');
|
|
136
|
+
if (!Array.isArray(events)) throw new Error('loop events must be an array');
|
|
137
|
+
const state={
|
|
138
|
+
schema:AUTONOMOUS_LOOP_STATE_SCHEMA,
|
|
139
|
+
phase:'PLAN',
|
|
140
|
+
plan:null,
|
|
141
|
+
plan_id:null,
|
|
142
|
+
plan_version:null,
|
|
143
|
+
current_step:null,
|
|
144
|
+
mutation_epoch:0,
|
|
145
|
+
planner_round:0,
|
|
146
|
+
replan_count:0,
|
|
147
|
+
pending_action:null,
|
|
148
|
+
pending_approval:false,
|
|
149
|
+
progress:null,
|
|
150
|
+
critic:null,
|
|
151
|
+
repair:null,
|
|
152
|
+
wait_reason:null,
|
|
153
|
+
evidence_head_sha256:null,
|
|
154
|
+
journal_head_sha256:ZERO_HASH
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
for (let index=0; index<events.length; index+=1) {
|
|
158
|
+
const event=requireObject(events[index],`loop event ${index+1}`);
|
|
159
|
+
if (event.goal_id !== goalId) throw new Error(`loop event ${index+1} goal mismatch`);
|
|
160
|
+
if (event.seq !== index+1) throw new Error(`loop event sequence mismatch at ${index+1}`);
|
|
161
|
+
hash(event.event_sha256,`loop event ${index+1} hash`);
|
|
162
|
+
const payload=event.payload===undefined?{}:requireObject(event.payload,`loop event ${index+1} payload`);
|
|
163
|
+
|
|
164
|
+
if (terminal(state.phase) && event.type !== 'release_completed' && event.type !== 'goal_cancelled') {
|
|
165
|
+
if (event.type === 'phase_changed') {
|
|
166
|
+
const to=normalizePhase(payload.to,'loop terminal phase to');
|
|
167
|
+
if (to !== state.phase) throw new Error(`loop ${state.phase} phase is terminal`);
|
|
168
|
+
} else if (MUTABLE_TERMINAL_EVENTS.has(event.type)) {
|
|
169
|
+
throw new Error(`loop ${state.phase} phase is terminal; event '${event.type}' is mutable`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
switch (event.type) {
|
|
174
|
+
case 'plan_created':
|
|
175
|
+
setPlan(state,payload.plan);
|
|
176
|
+
break;
|
|
177
|
+
case 'plan_replanned':
|
|
178
|
+
setPlan(state,payload.plan,{replanned:true});
|
|
179
|
+
break;
|
|
180
|
+
case 'step_completed':
|
|
181
|
+
if (payload.plan) setPlan(state,payload.plan);
|
|
182
|
+
break;
|
|
183
|
+
case 'phase_changed':
|
|
184
|
+
setPhase(state,payload.from,payload.to);
|
|
185
|
+
break;
|
|
186
|
+
case 'inspection_completed':
|
|
187
|
+
case 'inspect_completed':
|
|
188
|
+
if (payload.evidence_head_sha256 !== undefined) {
|
|
189
|
+
state.evidence_head_sha256=hash(payload.evidence_head_sha256,'loop evidence head');
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
case 'action_started': {
|
|
193
|
+
const actionId=hash(payload.action_id,'loop action_id');
|
|
194
|
+
const requestSha=hash(payload.request_sha256,'loop action request_sha256');
|
|
195
|
+
if (state.pending_action) throw new Error('loop action_started while another action is pending');
|
|
196
|
+
state.pending_action={...structuredClone(payload),action_id:actionId,request_sha256:requestSha};
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case 'action_completed':
|
|
200
|
+
if (state.pending_action && payload.action_id !== state.pending_action.action_id) {
|
|
201
|
+
throw new Error('loop action completion identity mismatch');
|
|
202
|
+
}
|
|
203
|
+
if (payload.action_id !== undefined) hash(payload.action_id,'loop completed action_id');
|
|
204
|
+
state.pending_action=null;
|
|
205
|
+
break;
|
|
206
|
+
case 'action_reconciled':
|
|
207
|
+
if (payload.action_id !== undefined) hash(payload.action_id,'loop reconciled action_id');
|
|
208
|
+
break;
|
|
209
|
+
case 'progress_judged':
|
|
210
|
+
if (!['progress','stalled','regressed'].includes(payload.verdict)) throw new Error('loop progress verdict invalid');
|
|
211
|
+
state.progress=structuredClone(payload);
|
|
212
|
+
break;
|
|
213
|
+
case 'critic_classified':
|
|
214
|
+
state.critic=classifyCritic(payload);
|
|
215
|
+
break;
|
|
216
|
+
case 'repair_started':
|
|
217
|
+
repairStart(state,payload);
|
|
218
|
+
break;
|
|
219
|
+
case 'repair_completed':
|
|
220
|
+
repairComplete(state,payload);
|
|
221
|
+
break;
|
|
222
|
+
case 'waiting_entered':
|
|
223
|
+
state.phase='WAITING';
|
|
224
|
+
state.wait_reason=requireText(payload.reason,'loop wait reason');
|
|
225
|
+
state.pending_approval=payload.requires_approval===true;
|
|
226
|
+
break;
|
|
227
|
+
case 'waiting_resumed': {
|
|
228
|
+
if (state.phase !== 'WAITING') throw new Error('loop waiting_resumed outside WAITING phase');
|
|
229
|
+
const resumed=payload.to===undefined?'PLAN':normalizePhase(payload.to,'loop resume phase');
|
|
230
|
+
if (resumed === 'WAITING' || terminal(resumed)) throw new Error('loop waiting resume target invalid');
|
|
231
|
+
state.phase=resumed;
|
|
232
|
+
state.wait_reason=null;
|
|
233
|
+
state.pending_approval=false;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
case 'planner_requested':
|
|
237
|
+
case 'planner_decision':
|
|
238
|
+
if (Number.isInteger(payload.planner_round) && payload.planner_round >= 0) {
|
|
239
|
+
state.planner_round=Math.max(state.planner_round,payload.planner_round);
|
|
240
|
+
}
|
|
241
|
+
break;
|
|
242
|
+
case 'native_diff_committed':
|
|
243
|
+
if (!Number.isInteger(payload.mutation_epoch) || payload.mutation_epoch < state.mutation_epoch) {
|
|
244
|
+
throw new Error('loop mutation_epoch invalid');
|
|
245
|
+
}
|
|
246
|
+
state.mutation_epoch=payload.mutation_epoch;
|
|
247
|
+
break;
|
|
248
|
+
case 'goal_paused':
|
|
249
|
+
state.phase='WAITING';
|
|
250
|
+
state.wait_reason=typeof payload.reason==='string'&&payload.reason.length>0?payload.reason:'paused';
|
|
251
|
+
state.pending_approval=true;
|
|
252
|
+
break;
|
|
253
|
+
case 'goal_resumed':
|
|
254
|
+
if (state.phase === 'WAITING') {
|
|
255
|
+
state.phase='PLAN';
|
|
256
|
+
state.wait_reason=null;
|
|
257
|
+
state.pending_approval=false;
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
case 'goal_cancelled':
|
|
261
|
+
state.phase='FAILED';
|
|
262
|
+
state.wait_reason=typeof payload.reason==='string'&&payload.reason.length>0?payload.reason:'cancelled';
|
|
263
|
+
state.pending_approval=false;
|
|
264
|
+
state.pending_action=null;
|
|
265
|
+
break;
|
|
266
|
+
case 'goal_failed':
|
|
267
|
+
state.phase='FAILED';
|
|
268
|
+
state.wait_reason=typeof payload.reason==='string'&&payload.reason.length>0?payload.reason:'failed';
|
|
269
|
+
state.pending_approval=false;
|
|
270
|
+
state.pending_action=null;
|
|
271
|
+
break;
|
|
272
|
+
case 'release_completed':
|
|
273
|
+
state.phase='SUCCEEDED';
|
|
274
|
+
state.wait_reason=null;
|
|
275
|
+
state.pending_approval=false;
|
|
276
|
+
state.pending_action=null;
|
|
277
|
+
break;
|
|
278
|
+
default:
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
state.journal_head_sha256=event.event_sha256;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (state.plan) state.current_step=activePlanStep(state.plan);
|
|
285
|
+
return state;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function deriveTodoProjection(goal,events) {
|
|
289
|
+
const state=deriveLoopState(goal,events);
|
|
290
|
+
return Object.freeze({
|
|
291
|
+
schema:'deadbyte.autonomous-todo-projection.v1',
|
|
292
|
+
goal_id:goal.goal_id,
|
|
293
|
+
phase:state.phase,
|
|
294
|
+
plan_id:state.plan_id,
|
|
295
|
+
plan_version:state.plan_version,
|
|
296
|
+
journal_head_sha256:state.journal_head_sha256,
|
|
297
|
+
items:Object.freeze((state.plan?.steps ?? []).map(step => Object.freeze({
|
|
298
|
+
step_id:step.step_id,
|
|
299
|
+
intent:step.intent,
|
|
300
|
+
status:step.status,
|
|
301
|
+
...(Array.isArray(step.evidence) ? {evidence:structuredClone(step.evidence)} : {})
|
|
302
|
+
})))
|
|
303
|
+
});
|
|
304
|
+
}
|
|
@@ -4,6 +4,24 @@ const hex64 = z.string().regex(/^[0-9a-f]{64}$/);
|
|
|
4
4
|
const goalId = hex64;
|
|
5
5
|
const jsonObject = z.record(z.string(),z.json());
|
|
6
6
|
const goalState = z.enum(['pending','running','paused','cancelled','succeeded']);
|
|
7
|
+
const loopPhase = z.enum(['PLANNING','INSPECTING','ACTING','VERIFYING','REPLANNING','WAITING','COMPLETE']);
|
|
8
|
+
const loopStep = z.strictObject({
|
|
9
|
+
step_id:z.string().regex(/^[A-Za-z0-9._-]{1,64}$/), intent:z.string().min(1).max(512), status:z.literal('active')
|
|
10
|
+
});
|
|
11
|
+
const loopProgress = z.strictObject({
|
|
12
|
+
verdict:z.enum(['progress','stalled','regressed']), score:z.number(),
|
|
13
|
+
reason_codes:z.array(z.string().regex(/^[A-Za-z0-9._-]{1,64}$/)).max(32), fingerprint:hex64
|
|
14
|
+
});
|
|
15
|
+
const loopPendingAction = z.strictObject({
|
|
16
|
+
action_id:hex64, request_sha256:hex64, kind:z.string().regex(/^[A-Za-z0-9._-]{1,64}$/)
|
|
17
|
+
});
|
|
18
|
+
const publicLoopSchema = z.strictObject({
|
|
19
|
+
schema:z.literal('deadbyte.autonomous-loop-state.v1'), phase:loopPhase,
|
|
20
|
+
plan_id:hex64.nullable(), plan_version:z.number().int().min(1).nullable(),
|
|
21
|
+
current_step:loopStep.nullable(), replan_count:z.number().int().min(0),
|
|
22
|
+
progress:loopProgress.nullable(), pending_action:loopPendingAction.nullable(),
|
|
23
|
+
pending_approval:z.boolean(), wait_reason:z.string().min(1).max(1024).nullable()
|
|
24
|
+
});
|
|
7
25
|
function requireFields(value,ctx,fields) {
|
|
8
26
|
for (const field of fields) if (value[field] === undefined) ctx.addIssue({ code:'custom', path:[field], message:`${field} is required` });
|
|
9
27
|
}
|
|
@@ -72,7 +90,8 @@ export const autonomousGoalSubmitOutputSchema = statusContract({
|
|
|
72
90
|
const runShape = Object.fromEntries(Object.entries(derivedShape).map(([key,schema]) => [key,schema.optional()]));
|
|
73
91
|
export const autonomousGoalRunOutputSchema = z.strictObject({
|
|
74
92
|
status:z.enum(['terminal','paused','cancelled','completed','yielded','running','input_required','failed']), error:z.string().optional(),
|
|
75
|
-
goal_id:goalId.optional(), release:jsonObject.optional(), planner_request:jsonObject.optional(),
|
|
93
|
+
goal_id:goalId.optional(), release:jsonObject.optional(), planner_request:jsonObject.optional(), loop:publicLoopSchema.optional(),
|
|
94
|
+
cycles:z.number().int().min(1).max(32).optional(), ...runShape
|
|
76
95
|
}).superRefine((value,ctx) => {
|
|
77
96
|
if (value.error !== undefined) { if (value.status !== 'failed') ctx.addIssue({code:'custom',path:['error'],message:'error wrapper requires failed'}); return; }
|
|
78
97
|
requireFields(value,ctx,['goal_id',...Object.keys(derivedShape)]);
|
|
@@ -81,7 +100,7 @@ export const autonomousGoalRunOutputSchema = z.strictObject({
|
|
|
81
100
|
export const autonomousGoalStatusOutputSchema = statusContract({
|
|
82
101
|
statuses:['ok','failed'], success:['ok'], required:['goal_id','goal_sha256','title','root_id','journal_verified',...Object.keys(derivedShape)],
|
|
83
102
|
shape:{ goal_id:goalId.optional(), goal_sha256:hex64.optional(), title:z.string().optional(), root_id:z.string().optional(),
|
|
84
|
-
journal_verified:z.literal(true).optional(), ...runShape }
|
|
103
|
+
journal_verified:z.literal(true).optional(), loop:publicLoopSchema.optional(), ...runShape }
|
|
85
104
|
});
|
|
86
105
|
export const autonomousGoalEventsOutputSchema = statusContract({
|
|
87
106
|
statuses:['ok','failed'], success:['ok'], required:['goal_id','journal_verified','journal_head_sha256','events'],
|
|
@@ -94,7 +113,7 @@ export const autonomousGoalCancelOutputSchema = statusContract({
|
|
|
94
113
|
});
|
|
95
114
|
export const autonomousGoalApproveOutputSchema = statusContract({
|
|
96
115
|
statuses:['terminal','approved','rejected','failed'], success:['terminal','approved','rejected'], required:['goal_id','state'],
|
|
97
|
-
shape:{ goal_id:goalId.optional(), state:goalState.optional() }
|
|
116
|
+
shape:{ goal_id:goalId.optional(), state:goalState.optional(), loop:publicLoopSchema.optional() }
|
|
98
117
|
});
|
|
99
118
|
export const autonomousReleaseGateOutputSchema = statusContract({
|
|
100
119
|
statuses:['blocked','paused','failed','passed','existing','error'], success:['blocked','paused','failed','passed','existing'],
|