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.
Files changed (388) hide show
  1. package/CONTEXT.md +41 -0
  2. package/MANIFEST.SHA256 +386 -94
  3. package/R34-BASELINE.json +9 -0
  4. package/README.txt +141 -10
  5. package/bench/fixtures/corpus.json +36 -0
  6. package/bench/fixtures/r36/case-map.json +8 -0
  7. package/bin/WORKER-REGISTRY.txt +3 -3
  8. package/bin/appcontainer-stage.exe +0 -0
  9. package/bin/appcontainer-stage.obj +0 -0
  10. package/bin/bootstrap-advapi32.exe +0 -0
  11. package/bin/bootstrap-advapi32.obj +0 -0
  12. package/bin/bootstrap-exitcode.exe +0 -0
  13. package/bin/bootstrap-exitcode.obj +0 -0
  14. package/bin/bootstrap-kernel32.exe +0 -0
  15. package/bin/bootstrap-kernel32.obj +0 -0
  16. package/bin/child-control-probe.exe +0 -0
  17. package/bin/child-control-probe.obj +0 -0
  18. package/bin/child-control-stage.exe +0 -0
  19. package/bin/child-control-stage.obj +0 -0
  20. package/bin/contained-reverse-worker.exe +0 -0
  21. package/bin/contained-reverse-worker.obj +0 -0
  22. package/bin/contained-transform-worker.exe +0 -0
  23. package/bin/contained-transform-worker.obj +0 -0
  24. package/bin/containment-probe.exe +0 -0
  25. package/bin/containment-probe.obj +0 -0
  26. package/bin/deadbyte-contain.exe +0 -0
  27. package/bin/deadbyte-contain.obj +0 -0
  28. package/bin/deadbyte-exec.exe +0 -0
  29. package/bin/deadbyte-exec.obj +0 -0
  30. package/bin/deadbyte-process-host.exe +0 -0
  31. package/bin/deadbyte-process-host.obj +0 -0
  32. package/bin/deadbyte-tunnel-host.exe +0 -0
  33. package/bin/deadbyte-tunnel-host.obj +0 -0
  34. package/controller/README.TXT +12 -4
  35. package/controller/deadbyte-controller.config.psd1.example +14 -0
  36. package/controller/deadbyte-controller.ps1 +191 -20
  37. package/controller/deadbyte-process-policy.json +5 -5
  38. package/controller/deadbyte-semantic-lsp-config.json +95 -0
  39. package/docs/ADR-0001-PRODUCTION-BASELINE-SEAMS.md +29 -0
  40. package/docs/ARCHITECTURE.md +6 -5
  41. package/docs/R36-CAPABILITY-EVIDENCE.md +43 -0
  42. package/docs/superpowers/plans/2026-09-16-deadbyte-loop-engine.md +846 -0
  43. package/docs/superpowers/plans/2026-09-17-r35-production-successor.md +408 -0
  44. package/docs/superpowers/plans/2026-09-18-r36-zero-loss-autonomy.md +739 -0
  45. package/docs/superpowers/specs/2026-09-16-deadbyte-loop-engine-design.md +435 -0
  46. package/docs/superpowers/specs/2026-09-17-r35-production-successor-design.md +220 -0
  47. package/docs/superpowers/specs/2026-09-18-r36-zero-loss-autonomy-design.md +640 -0
  48. package/node_modules/typescript/LICENSE.txt +55 -0
  49. package/node_modules/typescript/README.md +50 -0
  50. package/node_modules/typescript/SECURITY.md +41 -0
  51. package/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
  52. package/node_modules/typescript/bin/tsc +2 -0
  53. package/node_modules/typescript/bin/tsserver +2 -0
  54. package/node_modules/typescript/lib/_tsc.js +133818 -0
  55. package/node_modules/typescript/lib/_tsserver.js +659 -0
  56. package/node_modules/typescript/lib/_typingsInstaller.js +222 -0
  57. package/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
  58. package/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
  59. package/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
  60. package/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
  61. package/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
  62. package/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
  63. package/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
  64. package/node_modules/typescript/lib/lib.d.ts +22 -0
  65. package/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
  66. package/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
  67. package/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
  68. package/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
  69. package/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
  70. package/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
  71. package/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
  72. package/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
  73. package/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
  74. package/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
  75. package/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
  76. package/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
  77. package/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
  78. package/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
  79. package/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
  80. package/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
  81. package/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
  82. package/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
  83. package/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
  84. package/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
  85. package/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
  86. package/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
  87. package/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
  88. package/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
  89. package/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
  90. package/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
  91. package/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
  92. package/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
  93. package/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
  94. package/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
  95. package/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
  96. package/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
  97. package/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
  98. package/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
  99. package/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
  100. package/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
  101. package/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
  102. package/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
  103. package/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
  104. package/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
  105. package/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
  106. package/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
  107. package/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
  108. package/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
  109. package/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
  110. package/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
  111. package/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
  112. package/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
  113. package/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
  114. package/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
  115. package/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
  116. package/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
  117. package/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
  118. package/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
  119. package/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
  120. package/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
  121. package/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
  122. package/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
  123. package/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
  124. package/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
  125. package/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
  126. package/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
  127. package/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
  128. package/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
  129. package/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
  130. package/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
  131. package/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
  132. package/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
  133. package/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
  134. package/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
  135. package/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
  136. package/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
  137. package/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
  138. package/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
  139. package/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
  140. package/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
  141. package/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
  142. package/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
  143. package/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
  144. package/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
  145. package/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
  146. package/node_modules/typescript/lib/lib.es6.d.ts +23 -0
  147. package/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
  148. package/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
  149. package/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
  150. package/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
  151. package/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
  152. package/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
  153. package/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
  154. package/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
  155. package/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
  156. package/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
  157. package/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
  158. package/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
  159. package/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
  160. package/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
  161. package/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
  162. package/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
  163. package/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
  164. package/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
  165. package/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
  166. package/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
  167. package/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
  168. package/node_modules/typescript/lib/tsc.js +8 -0
  169. package/node_modules/typescript/lib/tsserver.js +8 -0
  170. package/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
  171. package/node_modules/typescript/lib/tsserverlibrary.js +21 -0
  172. package/node_modules/typescript/lib/typesMap.json +497 -0
  173. package/node_modules/typescript/lib/typescript.d.ts +11437 -0
  174. package/node_modules/typescript/lib/typescript.js +200276 -0
  175. package/node_modules/typescript/lib/typingsInstaller.js +8 -0
  176. package/node_modules/typescript/lib/watchGuard.js +53 -0
  177. package/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
  178. package/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
  179. package/node_modules/typescript/package.json +120 -0
  180. package/package.json +5 -3
  181. package/proof/CONTAINMENT-BUILD.txt +6 -6
  182. package/proof/R34-TASK8-SUPERVISOR-CHECKPOINT.json +29 -0
  183. package/proof/R34-TASK9-MCP-SURFACE-CHECKPOINT.json +28 -0
  184. package/scripts/capability-benchmark.mjs +27 -0
  185. package/scripts/deferred-slot-operation.mjs +56 -16
  186. package/scripts/final-closure-verify.mjs +88 -39
  187. package/scripts/final-closure.mjs +63 -56
  188. package/scripts/gate-windows.ps1 +3 -3
  189. package/scripts/release-parity-tests.ps1 +9 -0
  190. package/scripts/release-parity.mjs +149 -139
  191. package/scripts/semantic-preflight.ps1 +73 -0
  192. package/scripts/tool-surface-snapshot.mjs +73 -0
  193. package/scripts/windows-gate-evidence.mjs +5 -5
  194. package/src/audit-verify.mjs +6 -2
  195. package/src/autonomous-action-reconcile.mjs +142 -0
  196. package/src/autonomous-context-engine.mjs +256 -0
  197. package/src/autonomous-live-state.mjs +17 -0
  198. package/src/autonomous-local-supervisor.mjs +249 -0
  199. package/src/autonomous-loop-state.mjs +304 -0
  200. package/src/autonomous-mcp-tools.mjs +5 -1
  201. package/src/autonomous-output-contracts.mjs +26 -7
  202. package/src/autonomous-plan.mjs +181 -0
  203. package/src/autonomous-planner-contracts.mjs +79 -0
  204. package/src/autonomous-planner.mjs +113 -6
  205. package/src/autonomous-policy.mjs +15 -2
  206. package/src/autonomous-progress.mjs +127 -0
  207. package/src/autonomous-runtime.mjs +785 -62
  208. package/src/autonomous-supervisor-host.mjs +70 -0
  209. package/src/autonomous-supervisor.mjs +31 -8
  210. package/src/capability-benchmark-runner.mjs +193 -0
  211. package/src/capability-benchmark.mjs +95 -0
  212. package/src/capability-ledger.mjs +158 -0
  213. package/src/coding-mcp-tools.mjs +65 -8
  214. package/src/coding-output-contracts.mjs +91 -8
  215. package/src/coding-plane.mjs +45 -9
  216. package/src/coding-search.mjs +130 -47
  217. package/src/compact-gateway-mcp-tools.mjs +128 -0
  218. package/src/compact-gateway-output-contracts.mjs +16 -0
  219. package/src/context-provenance.mjs +86 -0
  220. package/src/deadbyte-cli.mjs +145 -30
  221. package/src/document-adapter.mjs +43 -0
  222. package/src/lsp-stdio-client.mjs +112 -0
  223. package/src/machine-fs-smoke-client.mjs +2 -1
  224. package/src/machine-fs.mjs +51 -8
  225. package/src/mcp-server.mjs +46 -9
  226. package/src/native-diff-v2.mjs +337 -0
  227. package/src/native-diff.mjs +50 -2
  228. package/src/observation-smoke-client.mjs +3 -2
  229. package/src/operator-surface.mjs +43 -0
  230. package/src/process-runtime.mjs +98 -11
  231. package/src/process-smoke-client.mjs +11 -3
  232. package/src/provider-circuit.mjs +125 -0
  233. package/src/r36-compact-disarmed-probe.mjs +50 -0
  234. package/src/r36-full-surface-probe.mjs +56 -0
  235. package/src/release-generation.mjs +44 -5
  236. package/src/remote-live-log.mjs +76 -0
  237. package/src/remote-mcp-autonomous-smoke-client.mjs +58 -15
  238. package/src/remote-mcp-coding-smoke-client.mjs +5 -4
  239. package/src/remote-mcp-r24-disarmed-smoke-client.mjs +4 -2
  240. package/src/remote-mcp-r34-parity-client.mjs +177 -0
  241. package/src/remote-mcp-r36-parity-client.mjs +175 -0
  242. package/src/remote-mcp-smoke-client.mjs +113 -56
  243. package/src/remote-result-journal.mjs +114 -0
  244. package/src/runtime-update.mjs +109 -9
  245. package/src/search-cursor.mjs +45 -0
  246. package/src/semantic-backend-registry.mjs +39 -0
  247. package/src/semantic-code.mjs +246 -0
  248. package/src/semantic-lsp-backend.mjs +219 -0
  249. package/src/semantic-lsp-config.mjs +112 -0
  250. package/src/tool-surface-ledger.mjs +92 -0
  251. package/src/version.mjs +1 -1
  252. package/test/audit-verify.test.mjs +1 -1
  253. package/test/autonomous-action-reconcile.test.mjs +106 -0
  254. package/test/autonomous-adversarial.test.mjs +149 -6
  255. package/test/autonomous-capability-r36.test.mjs +151 -0
  256. package/test/autonomous-context-engine.test.mjs +181 -0
  257. package/test/autonomous-live-state.test.mjs +27 -0
  258. package/test/autonomous-local-supervisor.test.mjs +403 -0
  259. package/test/autonomous-loop-state.test.mjs +126 -0
  260. package/test/autonomous-loop-v2.test.mjs +105 -0
  261. package/test/autonomous-loop.test.mjs +79 -1
  262. package/test/autonomous-output-contract.test.mjs +54 -0
  263. package/test/autonomous-plan.test.mjs +101 -0
  264. package/test/autonomous-progress.test.mjs +106 -0
  265. package/test/autonomous-r34-e2e.test.mjs +338 -0
  266. package/test/autonomous-runtime.test.mjs +3 -3
  267. package/test/autonomous-supervisor-integration.test.mjs +48 -3
  268. package/test/capability-benchmark-r36.test.mjs +107 -0
  269. package/test/capability-benchmark-runner.test.mjs +49 -0
  270. package/test/capability-benchmark-semantic-r36.test.mjs +52 -0
  271. package/test/capability-benchmark.test.mjs +47 -0
  272. package/test/capability-claims-r36.test.mjs +23 -0
  273. package/test/capability-ledger-r36.test.mjs +102 -0
  274. package/test/cli-entrypoint.test.mjs +12 -0
  275. package/test/coding-catalog-consistency.test.mjs +24 -0
  276. package/test/coding-plane.test.mjs +3 -3
  277. package/test/coding-runtime.test.mjs +16 -0
  278. package/test/coding-search-r36.test.mjs +90 -0
  279. package/test/compact-catalog-r36.test.mjs +37 -0
  280. package/test/compact-gateway-r36.test.mjs +66 -0
  281. package/test/contained.test.mjs +1 -1
  282. package/test/context-provenance.test.mjs +61 -0
  283. package/test/controller-r27.test.mjs +4 -3
  284. package/test/controller.test.mjs +52 -0
  285. package/test/core.test.mjs +1 -1
  286. package/test/deferred-slot-operation-behavior.test.mjs +5 -1
  287. package/test/deferred-slot-operation.test.mjs +11 -1
  288. package/test/document-adapter.test.mjs +23 -0
  289. package/test/fixtures/lsp-framed-server.mjs +35 -0
  290. package/test/fixtures/semantic/cpp/compile_commands.json +4 -0
  291. package/test/fixtures/semantic/cpp/lib.cpp +2 -0
  292. package/test/fixtures/semantic/cpp/lib.hpp +2 -0
  293. package/test/fixtures/semantic/cpp/main.cpp +2 -0
  294. package/test/fixtures/semantic/python/lib.py +2 -0
  295. package/test/fixtures/semantic/python/main.py +2 -0
  296. package/test/fixtures/semantic/rust/Cargo.lock +7 -0
  297. package/test/fixtures/semantic/rust/Cargo.toml +8 -0
  298. package/test/fixtures/semantic/rust/src/lib.rs +3 -0
  299. package/test/fixtures/semantic/rust/src/main.rs +5 -0
  300. package/test/fixtures/semantic/rust/src/math.rs +3 -0
  301. package/test/fixtures/semantic/rust/target/.rustc_info.json +1 -0
  302. package/test/fixtures/semantic/rust/target/CACHEDIR.TAG +3 -0
  303. package/test/fixtures/semantic/rust/target/debug/.cargo-lock +0 -0
  304. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/dep-test-lib-semantic_rust +0 -0
  305. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/invoked.timestamp +1 -0
  306. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/test-lib-semantic_rust +1 -0
  307. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/test-lib-semantic_rust.json +1 -0
  308. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/dep-test-bin-semantic_rust_bin +0 -0
  309. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/invoked.timestamp +1 -0
  310. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/test-bin-semantic_rust_bin +1 -0
  311. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/test-bin-semantic_rust_bin.json +1 -0
  312. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/dep-lib-semantic_rust +0 -0
  313. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/invoked.timestamp +1 -0
  314. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/lib-semantic_rust +1 -0
  315. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/lib-semantic_rust.json +1 -0
  316. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/bin-semantic_rust_bin +1 -0
  317. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/bin-semantic_rust_bin.json +1 -0
  318. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/dep-bin-semantic_rust_bin +0 -0
  319. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/invoked.timestamp +1 -0
  320. package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust-4c168fa33c79d09c.rmeta +0 -0
  321. package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust-6212ccd976aa3808.rmeta +0 -0
  322. package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust_bin-5dcd474439c54a26.rmeta +0 -0
  323. package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust_bin-d741378dccdef61c.rmeta +0 -0
  324. package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust-4c168fa33c79d09c.d +5 -0
  325. package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust-6212ccd976aa3808.d +5 -0
  326. package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust_bin-5dcd474439c54a26.d +6 -0
  327. package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust_bin-d741378dccdef61c.d +6 -0
  328. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/dep-graph.bin +0 -0
  329. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/query-cache.bin +0 -0
  330. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/work-products.bin +0 -0
  331. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc.lock +0 -0
  332. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/dep-graph.bin +0 -0
  333. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/metadata.rmeta +0 -0
  334. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/query-cache.bin +0 -0
  335. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/work-products.bin +0 -0
  336. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq.lock +0 -0
  337. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/dep-graph.bin +0 -0
  338. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/query-cache.bin +0 -0
  339. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/work-products.bin +0 -0
  340. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3.lock +0 -0
  341. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/dep-graph.bin +0 -0
  342. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/query-cache.bin +0 -0
  343. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/work-products.bin +0 -0
  344. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt.lock +0 -0
  345. package/test/fixtures/semantic/rust/target/flycheck0/stderr +1 -0
  346. package/test/fixtures/semantic/rust/target/flycheck0/stdout +5 -0
  347. package/test/fixtures/semantic/typescript/lib.ts +3 -0
  348. package/test/fixtures/semantic/typescript/main.ts +2 -0
  349. package/test/fixtures/tool-surface-stdio-server.mjs +14 -0
  350. package/test/helpers/autonomous-r34-fixture.mjs +122 -0
  351. package/test/lsp-stdio-client.test.mjs +72 -0
  352. package/test/multi-file-read.test.mjs +44 -0
  353. package/test/native-diff-topology-r36.test.mjs +105 -0
  354. package/test/observation-integration.test.mjs +3 -3
  355. package/test/package-boundary.test.mjs +6 -0
  356. package/test/process-longrun-r36.test.mjs +82 -0
  357. package/test/process-release-gate.test.mjs +9 -0
  358. package/test/production-docs.test.mjs +48 -0
  359. package/test/prompts-resources.test.mjs +41 -0
  360. package/test/provider-circuit.test.mjs +93 -0
  361. package/test/public-autonomous-ingress-budget.test.mjs +28 -0
  362. package/test/r33-closeout-regression.test.mjs +4 -3
  363. package/test/r33-finalization.test.mjs +26 -18
  364. package/test/r36-finalization.test.mjs +104 -0
  365. package/test/r36-release-identity.test.mjs +52 -0
  366. package/test/release-generation.test.mjs +23 -2
  367. package/test/release-version.test.mjs +27 -17
  368. package/test/remote-live-log-r36.test.mjs +37 -0
  369. package/test/remote-live-log-recovery-r36.test.mjs +41 -0
  370. package/test/remote-r24-catalog.test.mjs +18 -4
  371. package/test/remote-result-journal.test.mjs +58 -0
  372. package/test/remote-session-cli.test.mjs +135 -30
  373. package/test/runtime-self-update.test.mjs +121 -1
  374. package/test/semantic-backend-registry.test.mjs +29 -0
  375. package/test/semantic-code.test.mjs +66 -0
  376. package/test/semantic-lsp-backend.test.mjs +108 -0
  377. package/test/semantic-lsp-config.test.mjs +81 -0
  378. package/test/semantic-lsp-readiness.test.mjs +34 -0
  379. package/test/semantic-lsp-transient-empty.test.mjs +32 -0
  380. package/test/semantic-lsp-transient-null.test.mjs +31 -0
  381. package/test/semantic-multilang.test.mjs +72 -0
  382. package/test/semantic-r36-rename.test.mjs +82 -0
  383. package/test/semantic-runtime-routing.test.mjs +32 -0
  384. package/test/semantic-server-config-integration.test.mjs +66 -0
  385. package/test/tool-surface-ledger.test.mjs +59 -0
  386. package/test/tool-surface-snapshot.test.mjs +17 -0
  387. package/test/tracer-bullet.test.mjs +77 -0
  388. package/deadbyte-mcp-0.8.9.tgz +0 -0
@@ -0,0 +1,181 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { canonicalJson } from '../src/canonical-json.mjs';
4
+ import {
5
+ compactLoopContext,
6
+ deriveProjectMemory,
7
+ buildLoopContext
8
+ } from '../src/autonomous-context-engine.mjs';
9
+ import { buildPlannerPrompt } from '../src/autonomous-planner.mjs';
10
+
11
+ const H = c => c.repeat(64);
12
+
13
+ function oversizedContext() {
14
+ return {
15
+ goal:{title:'repair',goal:'repair source',acceptance:'tests pass'},
16
+ loop:{phase:'INSPECTING',mutation_epoch:1,planner_round:2},
17
+ working_context:{
18
+ active_plan:null,
19
+ current_step:null,
20
+ recent_contexts:[
21
+ {path:'old.txt',sha256:H('1'),bytes:20000,content:`OLD_SENTINEL:${'X'.repeat(70000)}`},
22
+ {path:'latest.txt',sha256:H('2'),bytes:20000,content:`LATEST_SENTINEL:${'L'.repeat(8000)}`}
23
+ ],
24
+ recent_observations:[],
25
+ active_identities:[],
26
+ recent_decisions:[]
27
+ },
28
+ historical_evidence:{
29
+ compacted_events:[{
30
+ request_sha256:H('a'),receipt_sha256:H('b'),expected_sha256:H('c'),
31
+ failure_cause:'test_failed',raw_payload:`OLD_RAW_PAYLOAD_SENTINEL${'Y'.repeat(160000)}`
32
+ }],
33
+ failures:[{cause:'test_failed',receipt_sha256:H('d')}],
34
+ receipts:[{receipt_id:'receipt-1',receipt_sha256:H('e')}],
35
+ mutation_epochs:[0,1],
36
+ plan_transitions:[]
37
+ },
38
+ project_memory:{
39
+ acceptance_constraints:['tests pass'],
40
+ proven_invariants:[`source_sha=${H('f')}`],
41
+ rejected_approaches:[],
42
+ important_files:[{path:'latest.txt',sha256:H('2')}],
43
+ unresolved_blockers:['test_failed']
44
+ },
45
+ profiles:[]
46
+ };
47
+ }
48
+
49
+ test('compaction preserves proof identity while dropping stale payload bytes', () => {
50
+ const compacted = compactLoopContext(oversizedContext(),65536);
51
+ const json = canonicalJson(compacted);
52
+ assert.ok(Buffer.byteLength(json,'utf8') <= 65536);
53
+ assert.match(json,/receipt_sha256/);
54
+ assert.match(json,/request_sha256/);
55
+ assert.match(json,/expected_sha256/);
56
+ assert.match(json,/test_failed/);
57
+ assert.match(json,/unresolved_blockers/);
58
+ assert.match(json,/LATEST_SENTINEL/);
59
+ assert.doesNotMatch(json,/OLD_RAW_PAYLOAD_SENTINEL/);
60
+ assert.doesNotMatch(json,/OLD_SENTINEL/);
61
+ assert.match(json,/content_elided/);
62
+ });
63
+
64
+ test('same input always produces byte-identical compacted context', () => {
65
+ const a = canonicalJson(compactLoopContext(oversizedContext(),65536));
66
+ const b = canonicalJson(compactLoopContext(oversizedContext(),65536));
67
+ assert.equal(a,b);
68
+ });
69
+
70
+ test('secret-like fields are redacted without exposing raw values or a hash oracle', () => {
71
+ const context = oversizedContext();
72
+ context.project_memory.credentials = {
73
+ api_token:'super-secret-token',
74
+ password:'correct horse battery staple',
75
+ authorization:'Bearer abc123'
76
+ };
77
+ const compacted = compactLoopContext(context,65536);
78
+ const json = canonicalJson(compacted);
79
+ assert.doesNotMatch(json,/super-secret-token/);
80
+ assert.doesNotMatch(json,/correct horse battery staple/);
81
+ assert.doesNotMatch(json,/Bearer abc123/);
82
+ assert.match(json,/"reason":"secret"/);
83
+ const redacted = compacted.project_memory.credentials;
84
+ assert.equal(redacted.redacted,true);
85
+ assert.equal(redacted.reason,'secret');
86
+ assert.equal(Object.hasOwn(redacted,'sha256'),false);
87
+ });
88
+
89
+ test('project memory derives stable acceptance, failures and unresolved blockers from journal events', () => {
90
+ const memory = deriveProjectMemory([
91
+ {type:'goal_created',payload:{acceptance:'build and tests pass'}},
92
+ {type:'profile_completed',payload:{profile_id:'test',passed:false,receipt_sha256:H('1')}},
93
+ {type:'native_diff_committed',payload:{paths:['src/a.mjs'],diff_receipt_sha256:H('2')}},
94
+ {type:'profile_completed',payload:{profile_id:'test',passed:true,receipt_sha256:H('3')}}
95
+ ]);
96
+ assert.deepEqual(memory.acceptance_constraints,['build and tests pass']);
97
+ assert.ok(memory.proven_invariants.some(value => value.includes('test')));
98
+ assert.equal(memory.unresolved_blockers.length,0);
99
+ assert.ok(memory.important_files.some(item => item.path === 'src/a.mjs'));
100
+ });
101
+
102
+ test('buildLoopContext produces the three named layers and respects the policy budget', () => {
103
+ const built = buildLoopContext({
104
+ goal:{title:'repair',goal:'repair source',acceptance:'tests pass'},
105
+ policy:{limits:{max_context_bytes:65536},profiles:{}},
106
+ loopState:{phase:'INSPECTING',mutation_epoch:0,planner_round:1,plan:null,current_step:null},
107
+ tree:[{path:'src/a.mjs',type:'file'}],
108
+ contexts:[{path:'src/a.mjs',sha256:H('1'),bytes:4,content:'code'}],
109
+ observations:[],
110
+ decisions:[],
111
+ projectMemory:null
112
+ });
113
+ assert.ok(built.working_context);
114
+ assert.ok(built.historical_evidence);
115
+ assert.ok(built.project_memory);
116
+ assert.ok(Buffer.byteLength(canonicalJson(built),'utf8') <= 65536);
117
+ });
118
+
119
+ test('R35 buildLoopContext attaches provenance and deduplicates identical retained context by newest observation', () => {
120
+ const built = buildLoopContext({
121
+ goal:{title:'repair',goal:'repair source',acceptance:'tests pass'},
122
+ policy:{limits:{max_context_bytes:65536},profiles:{}},
123
+ loopState:{phase:'INSPECT',mutation_epoch:3,planner_round:2,plan:null,current_step:null},
124
+ contexts:[
125
+ {path:'src/a.mjs',sha256:H('1'),bytes:4,content:'code',observed_at_utc:'2026-09-17T09:00:00.000Z'},
126
+ {path:'src/a.mjs',sha256:H('1'),bytes:4,content:'code',observed_at_utc:'2026-09-17T09:00:05.000Z'}
127
+ ],
128
+ observations:[],decisions:[],tree:[],projectMemory:null
129
+ });
130
+ assert.equal(built.working_context.recent_contexts.length,1);
131
+ const retained=built.working_context.recent_contexts[0];
132
+ assert.equal(retained.observed_at_utc,'2026-09-17T09:00:05.000Z');
133
+ assert.equal(retained.provenance.source_kind,'context');
134
+ assert.equal(retained.provenance.source_id,'src/a.mjs');
135
+ assert.match(retained.provenance.source_sha256,/^[0-9a-f]{64}$/);
136
+ assert.equal(retained.provenance.relevance_epoch,3);
137
+ });
138
+
139
+ test('R35 deterministic compaction elides payload but preserves provenance envelope', () => {
140
+ const built=buildLoopContext({
141
+ goal:{title:'repair',goal:'repair source',acceptance:'tests pass'},
142
+ policy:{limits:{max_context_bytes:32768},profiles:{}},
143
+ loopState:{phase:'INSPECT',mutation_epoch:7,planner_round:2,plan:null,current_step:null},
144
+ contexts:[
145
+ {path:'src/old.mjs',sha256:H('3'),bytes:70000,content:'OLD:'+('X'.repeat(70000)),observed_at_utc:'2026-09-17T09:00:00.000Z'},
146
+ {path:'src/current.mjs',sha256:H('4'),bytes:7,content:'current',observed_at_utc:'2026-09-17T09:01:00.000Z'}
147
+ ],observations:[],decisions:[],tree:[],projectMemory:null
148
+ });
149
+ const old=built.working_context.recent_contexts.find(item=>item.path==='src/old.mjs');
150
+ assert.ok(old);
151
+ assert.equal(old.content,undefined);
152
+ assert.equal(old.content_elided,true);
153
+ assert.equal(old.provenance.source_id,'src/old.mjs');
154
+ assert.match(old.provenance.source_sha256,/^[0-9a-f]{64}$/);
155
+ assert.match(old.provenance.provenance_id,/^[0-9a-f]{64}$/);
156
+ });
157
+
158
+ test('planner prompt serializes the R34 three-layer context instead of the legacy flat state', () => {
159
+ const policy = { limits:{max_context_bytes:65536}, profiles:{} };
160
+ const prompt = buildPlannerPrompt({
161
+ goal:{title:'repair',goal:'repair source',acceptance:'tests pass'},
162
+ policy,
163
+ view:{
164
+ mutation_epoch:0,
165
+ planner_round:1,
166
+ tree:[{path:'src/a.mjs',type:'file'}],
167
+ contexts:[{path:'src/a.mjs',sha256:H('1'),bytes:4,content:'code'}],
168
+ observations:[],
169
+ active_plan:null,
170
+ recent_decisions:[]
171
+ }
172
+ });
173
+ const stateText = prompt.match(/STATE=(.*)\nExample shape:/s)?.[1];
174
+ assert.ok(stateText);
175
+ const state = JSON.parse(stateText);
176
+ assert.ok(state.working_context);
177
+ assert.ok(state.historical_evidence);
178
+ assert.ok(state.project_memory);
179
+ assert.equal(Object.hasOwn(state,'contexts'),false);
180
+ assert.equal(Object.hasOwn(state,'observations'),false);
181
+ });
@@ -0,0 +1,27 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {
4
+ promptContexts,
5
+ promptObservations,
6
+ promptMutationEpoch
7
+ } from '../src/autonomous-live-state.mjs';
8
+
9
+ const context = { path:'workspaces/autonomous-live/fixture.txt', content:'READY\n', sha256:'a'.repeat(64), bytes:6 };
10
+ const observation = { profile_id:'quick-test', passed:false };
11
+
12
+ test('R34 compact planner state projects recent context, observations, and mutation epoch', () => {
13
+ const state = {
14
+ loop:{ mutation_epoch:2 },
15
+ working_context:{ recent_contexts:[context], recent_observations:[observation] }
16
+ };
17
+ assert.deepEqual(promptContexts(state), [context]);
18
+ assert.deepEqual(promptObservations(state), [observation]);
19
+ assert.equal(promptMutationEpoch(state), 2);
20
+ });
21
+
22
+ test('legacy planner state remains compatible', () => {
23
+ const state = { mutation_epoch:1, contexts:[context], observations:[observation] };
24
+ assert.deepEqual(promptContexts(state), [context]);
25
+ assert.deepEqual(promptObservations(state), [observation]);
26
+ assert.equal(promptMutationEpoch(state), 1);
27
+ });
@@ -0,0 +1,403 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { createHash, randomBytes } from 'node:crypto';
4
+ import { spawn } from 'node:child_process';
5
+ import { createServer } from 'node:http';
6
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
7
+ import os from 'node:os';
8
+ import path from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ import { generateTrustKeypair } from '../src/trust.mjs';
11
+ import { createCodingRuntime, loadCodingPolicy } from '../src/coding-plane.mjs';
12
+ import { loadAutonomousPolicy } from '../src/autonomous-policy.mjs';
13
+ import { createNativeDiffRuntime } from '../src/native-diff.mjs';
14
+ import { createAutonomousRuntime } from '../src/autonomous-runtime.mjs';
15
+ import {
16
+ observeCurrentProcessIdentity, observeSupervisor, takeoverSupervisor,
17
+ claimSupervisor, releaseSupervisor, validateSupervisorRecoveryRequest,
18
+ startLocalSupervisorHost, recoverManagedRuntime, runPinnedControllerOperation
19
+ } from '../src/autonomous-local-supervisor.mjs';
20
+ import { localSupervisorFixture } from './helpers/autonomous-r34-fixture.mjs';
21
+
22
+ const here=path.dirname(fileURLToPath(import.meta.url));
23
+ const repoRoot=path.resolve(here,'..');
24
+ const hostPath=path.join(repoRoot,'src','autonomous-supervisor-host.mjs');
25
+ const nonce=()=>randomBytes(32).toString('hex');
26
+ const sha=bytes=>createHash('sha256').update(bytes).digest('hex');
27
+
28
+ async function createProviderHostFixture(){
29
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r34-host-process-'));
30
+ const project=path.join(root,'project'); const trust=path.join(root,'trust');
31
+ await mkdir(project); await mkdir(trust); await writeFile(path.join(project,'source.txt'),'READY\n');
32
+ const keys=await generateTrustKeypair({privateKeyPath:path.join(trust,'private.pem'),publicKeyPath:path.join(trust,'public.pem')});
33
+ const codingPath=path.join(root,'coding.json');
34
+ await writeFile(codingPath,JSON.stringify({schema:'deadbyte.coding-policy.v1',enabled:true,
35
+ lease_file:path.join(root,'coding-grant.json'),evidence_dir:path.join(root,'coding-evidence'),
36
+ roots:{project:{path:project,read:true,write:true,exec:false,deny_paths:[]}},commands:{}}));
37
+ const codingPolicy=await loadCodingPolicy(codingPath);
38
+ await writeFile(codingPolicy.lease_file,JSON.stringify({schema:'deadbyte.coding-grant.v2',policy_sha256:codingPolicy.policy_sha256,
39
+ instance_nonce:nonce(),root_ids:['project'],granted_at_utc:new Date().toISOString()}));
40
+ let round=0;
41
+ const planner=createServer(async(req,res)=>{ let body=''; for await(const chunk of req) body+=chunk; JSON.parse(body); round+=1;
42
+ const decision=round===1
43
+ ? {schema:'deadbyte.autonomous-decision.v1',action:'inspect',summary:'inspect source',reads:[{path:'source.txt',max_bytes:4096}]}
44
+ : {schema:'deadbyte.autonomous-decision.v1',action:'finish',summary:'verified source observed'};
45
+ res.writeHead(200,{'content-type':'application/json'}); res.end(JSON.stringify({model:'r34-host-test',choices:[{message:{content:JSON.stringify(decision)}}]}));
46
+ });
47
+ await new Promise(resolve=>planner.listen(0,'127.0.0.1',resolve));
48
+ const autonomousPath=path.join(root,'autonomous.json');
49
+ await writeFile(autonomousPath,JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,
50
+ lease_file:path.join(root,'autonomous-grant.json'),evidence_dir:path.join(root,'autonomous-evidence'),
51
+ coding_policy_sha256:codingPolicy.policy_sha256,root_ids:['project'],
52
+ planner:{backend:'openai_compatible',endpoint:`http://127.0.0.1:${planner.address().port}/v1/chat/completions`,model:'r34-host-test',max_tokens:2048,timeout_ms:30000,max_response_bytes:262144},
53
+ limits:{max_iterations:8,max_mutations:8,max_wall_ms:null,max_context_bytes:262144,max_diff_bytes:262144,max_files_per_diff:4},profiles:{}}));
54
+ const autonomousPolicy=await loadAutonomousPolicy(autonomousPath,codingPolicy);
55
+ await writeFile(autonomousPolicy.lease_file,JSON.stringify({schema:'deadbyte.autonomous-grant.v2',policy_sha256:autonomousPolicy.policy_sha256,
56
+ instance_nonce:nonce(),root_ids:['project'],granted_at_utc:new Date().toISOString()}));
57
+ const codingRuntime=createCodingRuntime({policy:codingPolicy,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath});
58
+ const nativeDiffRuntime=createNativeDiffRuntime({policy:autonomousPolicy,codingRuntime,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath});
59
+ const runtime=createAutonomousRuntime({policy:autonomousPolicy,codingRuntime,nativeDiffRuntime,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath});
60
+ const markerPath=path.join(root,'supervisor-owner.json');
61
+ return {root,keys,codingPath,autonomousPath,runtime,markerPath,planner,rounds:()=>round,
62
+ cleanup:async()=>{await new Promise(resolve=>planner.close(resolve)); await rm(root,{recursive:true,force:true});}};
63
+ }
64
+
65
+ test('current Windows process identity binds pid creation time image path and image hash', async () => {
66
+ const identity=await observeCurrentProcessIdentity();
67
+ assert.ok(identity);
68
+ assert.equal(identity.pid,process.pid);
69
+ assert.match(identity.creation_time_utc,/Z$/);
70
+ assert.equal(typeof identity.image_path,'string');
71
+ assert.ok(identity.image_path.length>3);
72
+ assert.match(identity.image_sha256,/^[0-9a-f]{64}$/);
73
+ });
74
+
75
+ test('local supervisor refuses takeover of live verified owner', async () => {
76
+ const identity=await observeCurrentProcessIdentity();
77
+ const f=await localSupervisorFixture({ownerPid:process.pid,ownerIdentity:identity});
78
+ try {
79
+ const observed=await observeSupervisor(f.options);
80
+ assert.equal(observed.reason,'live_verified_owner');
81
+ await assert.rejects(takeoverSupervisor(f.options),/live verified owner/i);
82
+ } finally { await f.cleanup(); }
83
+ });
84
+
85
+ test('stale PID reuse does not inherit ownership', async () => {
86
+ const identity=await observeCurrentProcessIdentity();
87
+ const f=await localSupervisorFixture({ownerPid:process.pid,
88
+ ownerIdentity:{...identity,creation_time_utc:'2000-01-01T00:00:00.000Z'}});
89
+ try {
90
+ const state=await observeSupervisor(f.options);
91
+ assert.equal(state.live,false);
92
+ assert.equal(state.reason,'pid_reused');
93
+ const claimed=await takeoverSupervisor(f.options);
94
+ assert.equal(claimed.status,'claimed');
95
+ const marker=JSON.parse(await readFile(f.markerPath,'utf8'));
96
+ assert.equal(marker.pid,process.pid);
97
+ assert.notEqual(marker.creation_time_utc,'2000-01-01T00:00:00.000Z');
98
+ assert.match(marker.instance_nonce,/^[0-9a-f]{64}$/);
99
+ } finally { await f.cleanup(); }
100
+ });
101
+
102
+ test('exclusive claim and verified release cannot delete another live owner marker', async () => {
103
+ const f=await localSupervisorFixture({ownerPid:null,ownerIdentity:null});
104
+ try {
105
+ const claim=await claimSupervisor(f.options);
106
+ assert.equal(claim.status,'claimed');
107
+ const observed=await observeSupervisor(f.options);
108
+ assert.equal(observed.reason,'live_verified_owner');
109
+ await assert.rejects(releaseSupervisor({...f.options,instanceNonce:'f'.repeat(64)}),/ownership|nonce/i);
110
+ const released=await releaseSupervisor({...f.options,instanceNonce:claim.instance_nonce});
111
+ assert.equal(released.status,'released');
112
+ assert.equal((await observeSupervisor(f.options)).reason,'no_owner');
113
+ } finally { await f.cleanup(); }
114
+ });
115
+
116
+ test('recovery request allowlist permits status resume park and disarm only', () => {
117
+ for(const operation of ['status','resume','park','disarmautonomous','disarmcoding','disarmprocess','disarmhost']) {
118
+ assert.deepEqual(validateSupervisorRecoveryRequest({operation}),{operation});
119
+ }
120
+ for(const operation of ['armautonomous','armcoding','armprocess','armhost','restart','exec','powershell']) {
121
+ assert.throws(()=>validateSupervisorRecoveryRequest({operation}),/operation|allowlist/i);
122
+ }
123
+ assert.throws(()=>validateSupervisorRecoveryRequest({operation:'status',command:'whoami'}),/field|request/i);
124
+ assert.throws(()=>validateSupervisorRecoveryRequest({operation:'resume',executable:'cmd.exe'}),/field|request/i);
125
+ assert.throws(()=>validateSupervisorRecoveryRequest({operation:'park',env:{X:'1'}}),/field|request/i);
126
+ });
127
+
128
+ test('local supervisor host owns marker, advances durable provider goal, and releases ownership on stop', async () => {
129
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r34-local-host-'));
130
+ const evidence=path.join(root,'evidence');
131
+ const goalId='1'.repeat(64);
132
+ await mkdir(path.join(evidence,'goals',goalId),{recursive:true});
133
+ const markerPath=path.join(root,'owner.json');
134
+ let state='pending'; let runs=0;
135
+ const policy={evidence_dir:evidence,planner:{backend:'openai_compatible'}};
136
+ const runtime={policy,
137
+ async status({goalId:id}){ assert.equal(id,goalId); return {state}; },
138
+ async run({goalId:id}){ assert.equal(id,goalId); runs+=1; state='succeeded'; return {status:'completed'}; }
139
+ };
140
+ let host;
141
+ try {
142
+ host=await startLocalSupervisorHost({runtime,policy,markerPath,idleDelayMs:25,maxCycles:4,logger:{warn(){},error(){}}});
143
+ const deadline=Date.now()+3000;
144
+ while(runs<1&&Date.now()<deadline) await new Promise(resolve=>setTimeout(resolve,25));
145
+ assert.equal(runs,1);
146
+ assert.equal((await observeSupervisor({markerPath})).reason,'live_verified_owner');
147
+ await host.stop(); host=null;
148
+ assert.equal((await observeSupervisor({markerPath})).reason,'no_owner');
149
+ } finally {
150
+ if(host) await host.stop().catch(()=>{});
151
+ await rm(root,{recursive:true,force:true});
152
+ }
153
+ });
154
+
155
+ test('managed runtime recovery uses only resume, disarm planes, then exact ONLINE/DISARMED status proof', async () => {
156
+ const operations=[];
157
+ const finalText=[
158
+ 'DEADBYTE MCP = ONLINE',
159
+ 'Process plane : DISARMED [disarmed]',
160
+ 'Coding plane : DISARMED [disarmed]',
161
+ 'Autonomous : DISARMED [disarmed]',
162
+ 'Host plane : DISARMED [disarmed]'
163
+ ].join('\n');
164
+ const result=await recoverManagedRuntime({runControllerOperation:async request=>{
165
+ const checked=validateSupervisorRecoveryRequest(request); operations.push(checked.operation);
166
+ return {exit_code:0,stdout:checked.operation==='status'?finalText:'OK',stderr:''};
167
+ }});
168
+ assert.deepEqual(operations,['resume','disarmautonomous','disarmcoding','disarmprocess','disarmhost','status']);
169
+ assert.equal(result.status,'recovered');
170
+ assert.equal(result.runtime_state,'ONLINE');
171
+ assert.deepEqual(result.authority,{process:'DISARMED',coding:'DISARMED',autonomous:'DISARMED',host:'DISARMED'});
172
+ });
173
+
174
+ test('managed runtime recovery fails closed when final status is not all disarmed', async () => {
175
+ const bad=[
176
+ 'DEADBYTE MCP = ONLINE',
177
+ 'Process plane : DISARMED [disarmed]',
178
+ 'Coding plane : ARMED [standing-grant]',
179
+ 'Autonomous : DISARMED [disarmed]',
180
+ 'Host plane : DISARMED [disarmed]'
181
+ ].join('\n');
182
+ await assert.rejects(recoverManagedRuntime({runControllerOperation:async ({operation})=>({
183
+ exit_code:0,stdout:operation==='status'?bad:'OK',stderr:''
184
+ })}),/coding|disarmed|recovery/i);
185
+ });
186
+
187
+ test('pinned controller runner verifies script hash before fixed PowerShell invocation', async () => {
188
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r34-controller-runner-'));
189
+ const controllerPath=path.join(root,'controller.ps1');
190
+ const script="param([string]$Command)\nif($Command -eq 'status'){ Write-Output 'DEADBYTE MCP = ONLINE' } else { Write-Output ('OK '+$Command) }\n";
191
+ try {
192
+ await writeFile(controllerPath,script,'utf8');
193
+ const controllerSha256=createHash('sha256').update(await readFile(controllerPath)).digest('hex');
194
+ const result=await runPinnedControllerOperation({controllerPath,controllerSha256,operation:'status'});
195
+ assert.equal(result.exit_code,0);
196
+ assert.match(result.stdout,/DEADBYTE MCP = ONLINE/);
197
+ await assert.rejects(runPinnedControllerOperation({controllerPath,controllerSha256:'0'.repeat(64),operation:'status'}),/hash/i);
198
+ await assert.rejects(runPinnedControllerOperation({controllerPath,controllerSha256,operation:'armcoding'}),/allowlist|operation/i);
199
+ await assert.rejects(runPinnedControllerOperation({controllerPath,controllerSha256,operation:'status',executable:'cmd.exe'}),/field|options/i);
200
+ await assert.rejects(runPinnedControllerOperation({controllerPath,controllerSha256,operation:'status',env:{X:'1'}}),/field|options/i);
201
+ } finally { await rm(root,{recursive:true,force:true}); }
202
+ });
203
+
204
+ test('R34 bridge loss is recovered by local supervisor to ONLINE and all-DISARMED', async () => {
205
+ const f=await createProviderHostFixture();
206
+ const statePath=path.join(f.root,'managed-runtime.json');
207
+ const controllerPath=path.join(f.root,'recovery-controller.ps1');
208
+ const psLiteral=value=>`'${String(value).replaceAll("'","''")}'`;
209
+ const codingPolicyDoc=JSON.parse(await readFile(f.codingPath,'utf8'));
210
+ const autonomousPolicyDoc=JSON.parse(await readFile(f.autonomousPath,'utf8'));
211
+ await writeFile(statePath,JSON.stringify({runtime_state:'ONLINE',process:'ARMED',coding:'ARMED',autonomous:'ARMED',host:'ARMED'}));
212
+ const controllerScript=[
213
+ 'param([string]$Command)',
214
+ "$ErrorActionPreference='Stop'",
215
+ `$StatePath=${psLiteral(statePath)}`,
216
+ `$CodingLease=${psLiteral(codingPolicyDoc.lease_file)}`,
217
+ `$AutonomousLease=${psLiteral(autonomousPolicyDoc.lease_file)}`,
218
+ '$s=Get-Content -LiteralPath $StatePath -Raw -Encoding UTF8 | ConvertFrom-Json',
219
+ "switch($Command){",
220
+ " 'park' { $s.runtime_state='PARKED' }",
221
+ " 'resume' { $s.runtime_state='ONLINE' }",
222
+ " 'disarmautonomous' { $s.autonomous='DISARMED'; Remove-Item -LiteralPath $AutonomousLease -Force -ErrorAction SilentlyContinue }",
223
+ " 'disarmcoding' { $s.coding='DISARMED'; Remove-Item -LiteralPath $CodingLease -Force -ErrorAction SilentlyContinue }",
224
+ " 'disarmprocess' { $s.process='DISARMED' }",
225
+ " 'disarmhost' { $s.host='DISARMED' }",
226
+ " 'status' {",
227
+ " Write-Output ('DEADBYTE MCP = {0}' -f $s.runtime_state)",
228
+ " Write-Output ('Process plane : {0} [fixture]' -f $s.process)",
229
+ " Write-Output ('Coding plane : {0} [fixture]' -f $s.coding)",
230
+ " Write-Output ('Autonomous : {0} [fixture]' -f $s.autonomous)",
231
+ " Write-Output ('Host plane : {0} [fixture]' -f $s.host)",
232
+ ' exit 0',
233
+ ' }',
234
+ " default { throw ('unsupported recovery operation: '+$Command) }",
235
+ '}',
236
+ '$s | ConvertTo-Json -Compress | Set-Content -LiteralPath $StatePath -Encoding UTF8',
237
+ "Write-Output ('OK '+$Command)"
238
+ ].join('\n')+'\n';
239
+ await writeFile(controllerPath,controllerScript,'utf8');
240
+ const controllerSha256=sha(await readFile(controllerPath));
241
+ const runControllerOperation=({operation})=>runPinnedControllerOperation({controllerPath,controllerSha256,operation});
242
+ let host;
243
+ try {
244
+ host=await startLocalSupervisorHost({runtime:f.runtime,policy:f.runtime.policy,markerPath:f.markerPath,
245
+ idleDelayMs:25,maxCycles:8,logger:{warn(){},error(){}},continuous:true});
246
+ const ownerBefore=await observeSupervisor({markerPath:f.markerPath});
247
+ assert.equal(ownerBefore.reason,'live_verified_owner');
248
+ assert.equal(host.running,true);
249
+
250
+ assert.equal((await runControllerOperation({operation:'park'})).exit_code,0);
251
+ const parked=await runControllerOperation({operation:'status'});
252
+ assert.equal(parked.exit_code,0);
253
+ assert.match(parked.stdout,/DEADBYTE MCP = PARKED/);
254
+ assert.equal(host.running,true,'local supervisor died when managed Bridge was parked');
255
+
256
+ const submitted=await f.runtime.submit({submissionId:'bridge-loss-oob',rootId:'project',title:'bridge loss proof',
257
+ goal:'Inspect source.txt and finish while the managed Bridge is parked.',acceptance:'source stays READY',maxIterations:8});
258
+ const deadline=Date.now()+5000;
259
+ let goalStatus=await f.runtime.status({goalId:submitted.goal_id});
260
+ while(goalStatus.state!=='succeeded'&&Date.now()<deadline){
261
+ await new Promise(resolve=>setTimeout(resolve,25));
262
+ goalStatus=await f.runtime.status({goalId:submitted.goal_id});
263
+ }
264
+ assert.equal(goalStatus.state,'succeeded','local supervisor did not reconstruct and finish durable goal while Bridge was parked');
265
+ assert.equal((await f.runtime.verify({goalId:submitted.goal_id})).ok,true);
266
+ assert.ok(f.rounds()>=2);
267
+
268
+ const recovered=await recoverManagedRuntime({runControllerOperation});
269
+ assert.equal(recovered.status,'recovered');
270
+ assert.equal(recovered.runtime_state,'ONLINE');
271
+ assert.deepEqual(recovered.authority,{process:'DISARMED',coding:'DISARMED',autonomous:'DISARMED',host:'DISARMED'});
272
+ assert.deepEqual(recovered.operations,['resume','disarmautonomous','disarmcoding','disarmprocess','disarmhost','status']);
273
+ assert.equal(host.running,true,'local supervisor process changed during controlled recovery');
274
+ const ownerAfter=await observeSupervisor({markerPath:f.markerPath});
275
+ assert.equal(ownerAfter.reason,'live_verified_owner');
276
+ assert.equal(ownerAfter.marker.pid,ownerBefore.marker.pid);
277
+ assert.equal(ownerAfter.marker.instance_nonce,ownerBefore.marker.instance_nonce);
278
+ await assert.rejects(readFile(codingPolicyDoc.lease_file,'utf8'),error=>error?.code==='ENOENT');
279
+ await assert.rejects(readFile(autonomousPolicyDoc.lease_file,'utf8'),error=>error?.code==='ENOENT');
280
+ } finally {
281
+ if(host) await host.stop().catch(()=>{});
282
+ await f.cleanup();
283
+ }
284
+ });
285
+
286
+ test('client-sampling local supervisor owns recovery without fabricating planner work', async () => {
287
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r34-client-sampling-host-'));
288
+ const evidence=path.join(root,'evidence');
289
+ const goalId='2'.repeat(64);
290
+ await mkdir(path.join(evidence,'goals',goalId),{recursive:true});
291
+ const markerPath=path.join(root,'owner.json');
292
+ let runs=0;
293
+ const policy={evidence_dir:evidence,planner:{backend:'client_sampling'}};
294
+ const runtime={policy,
295
+ async status(){ return {state:'pending'}; },
296
+ async run(){ runs+=1; return {status:'input_required'}; }
297
+ };
298
+ let host;
299
+ try {
300
+ host=await startLocalSupervisorHost({runtime,policy,markerPath,idleDelayMs:25,maxCycles:4,logger:{warn(){},error(){}},continuous:true});
301
+ assert.equal(host.running,true);
302
+ assert.equal((await observeSupervisor({markerPath})).reason,'live_verified_owner');
303
+ assert.equal(await host.scanNow(),0);
304
+ await new Promise(resolve=>setTimeout(resolve,100));
305
+ assert.equal(runs,0,'client-sampling supervisor must never fabricate or request planner work itself');
306
+ await host.stop(); host=null;
307
+ assert.equal((await observeSupervisor({markerPath})).reason,'no_owner');
308
+ } finally {
309
+ if(host) await host.stop().catch(()=>{});
310
+ await rm(root,{recursive:true,force:true});
311
+ }
312
+ });
313
+
314
+ test('standalone supervisor host starts in client-sampling recovery-only mode', async () => {
315
+ const f=await createProviderHostFixture();
316
+ let child;
317
+ try {
318
+ const submitted=await f.runtime.submit({submissionId:'client-sampling-oob',rootId:'project',title:'client sampling recovery host',
319
+ goal:'Remain durable until an authenticated MCP client supplies planner sampling.',acceptance:'no fabricated planner work',maxIterations:8});
320
+ const policyDoc=JSON.parse(await readFile(f.autonomousPath,'utf8'));
321
+ policyDoc.planner={backend:'client_sampling',max_tokens:2048};
322
+ await writeFile(f.autonomousPath,`${JSON.stringify(policyDoc)}\n`,'utf8');
323
+ child=spawn(process.execPath,[hostPath],{cwd:repoRoot,windowsHide:true,stdio:['ignore','pipe','pipe'],env:{...process.env,
324
+ DEADBYTE_SIGNING_KEY:f.keys.privateKeyPath,DEADBYTE_VERIFY_KEY:f.keys.publicKeyPath,
325
+ DEADBYTE_CODING_POLICY:f.codingPath,DEADBYTE_AUTONOMOUS_POLICY:f.autonomousPath,
326
+ DEADBYTE_SUPERVISOR_MARKER:f.markerPath,DEADBYTE_SUPERVISOR_ONCE:'1'}});
327
+ let stdout=''; let stderr=''; child.stdout.on('data',chunk=>stdout+=chunk); child.stderr.on('data',chunk=>stderr+=chunk);
328
+ const exitCode=await new Promise(resolve=>child.once('exit',code=>resolve(code)));
329
+ assert.equal(exitCode,0,stderr);
330
+ const readyLine=stdout.split(/\r?\n/).find(line=>line.includes('deadbyte.autonomous-supervisor-host.v1'));
331
+ assert.ok(readyLine,stdout);
332
+ assert.equal(JSON.parse(readyLine).status,'ready');
333
+ assert.notEqual((await f.runtime.status({goalId:submitted.goal_id})).state,'succeeded');
334
+ assert.equal(f.rounds(),0,'client-sampling host must not call provider planner');
335
+ assert.equal((await observeSupervisor({markerPath:f.markerPath})).reason,'no_owner');
336
+ } finally {
337
+ if(child && child.exitCode===null) child.kill();
338
+ await f.cleanup();
339
+ }
340
+ });
341
+
342
+ test('continuous standalone supervisor remains alive after READY and hard-stop ownership is takeover-safe', async () => {
343
+ const f=await createProviderHostFixture();
344
+ let child;
345
+ try {
346
+ const policyDoc=JSON.parse(await readFile(f.autonomousPath,'utf8'));
347
+ policyDoc.planner={backend:'client_sampling',max_tokens:2048};
348
+ await writeFile(f.autonomousPath,`${JSON.stringify(policyDoc)}\n`,'utf8');
349
+ child=spawn(process.execPath,[hostPath],{cwd:repoRoot,windowsHide:true,stdio:['ignore','pipe','pipe'],env:{...process.env,
350
+ DEADBYTE_SIGNING_KEY:f.keys.privateKeyPath,DEADBYTE_VERIFY_KEY:f.keys.publicKeyPath,
351
+ DEADBYTE_CODING_POLICY:f.codingPath,DEADBYTE_AUTONOMOUS_POLICY:f.autonomousPath,
352
+ DEADBYTE_SUPERVISOR_MARKER:f.markerPath,DEADBYTE_SUPERVISOR_ONCE:'0'}});
353
+ let stdout=''; let stderr=''; child.stdout.on('data',chunk=>stdout+=chunk); child.stderr.on('data',chunk=>stderr+=chunk);
354
+ const readyDeadline=Date.now()+5000;
355
+ while(!stdout.includes('deadbyte.autonomous-supervisor-host.v1')&&child.exitCode===null&&Date.now()<readyDeadline) {
356
+ await new Promise(resolve=>setTimeout(resolve,25));
357
+ }
358
+ assert.match(stdout,/deadbyte\.autonomous-supervisor-host\.v1/,stderr||stdout);
359
+ await new Promise(resolve=>setTimeout(resolve,400));
360
+ assert.equal(child.exitCode,null,`continuous supervisor exited after READY: ${stderr}`);
361
+ assert.equal((await observeSupervisor({markerPath:f.markerPath})).reason,'live_verified_owner');
362
+ child.kill('SIGTERM');
363
+ await new Promise(resolve=>child.once('exit',()=>resolve()));
364
+ const stale=await observeSupervisor({markerPath:f.markerPath});
365
+ assert.equal(stale.live,false);
366
+ assert.match(stale.reason,/process_unobservable|pid_reused|identity_mismatch/);
367
+ const claimed=await takeoverSupervisor({markerPath:f.markerPath});
368
+ assert.equal(claimed.status,'claimed');
369
+ await releaseSupervisor({markerPath:f.markerPath,instanceNonce:claimed.instance_nonce});
370
+ assert.equal((await observeSupervisor({markerPath:f.markerPath})).reason,'no_owner');
371
+ } finally {
372
+ if(child && child.exitCode===null) child.kill();
373
+ await f.cleanup();
374
+ }
375
+ });
376
+
377
+ test('standalone supervisor host advances durable provider goal without MCP bridge process', async () => {
378
+ const f=await createProviderHostFixture();
379
+ let child;
380
+ try {
381
+ const submitted=await f.runtime.submit({submissionId:'host-out-of-band',rootId:'project',title:'host proof',
382
+ goal:'Inspect source.txt and finish from the standalone supervisor host.',acceptance:'source stays READY',maxIterations:8});
383
+ child=spawn(process.execPath,[hostPath],{cwd:repoRoot,windowsHide:true,stdio:['ignore','pipe','pipe'],env:{...process.env,
384
+ DEADBYTE_SIGNING_KEY:f.keys.privateKeyPath,DEADBYTE_VERIFY_KEY:f.keys.publicKeyPath,
385
+ DEADBYTE_CODING_POLICY:f.codingPath,DEADBYTE_AUTONOMOUS_POLICY:f.autonomousPath,
386
+ DEADBYTE_SUPERVISOR_MARKER:f.markerPath,DEADBYTE_SUPERVISOR_ONCE:'1'}});
387
+ let stdout=''; let stderr=''; child.stdout.on('data',chunk=>stdout+=chunk); child.stderr.on('data',chunk=>stderr+=chunk);
388
+ const exitCode=await new Promise(resolve=>child.once('exit',code=>resolve(code)));
389
+ assert.equal(exitCode,0,stderr);
390
+ const readyLine=stdout.split(/\r?\n/).find(line=>line.includes('deadbyte.autonomous-supervisor-host.v1'));
391
+ assert.ok(readyLine,stdout);
392
+ const ready=JSON.parse(readyLine);
393
+ assert.equal(ready.pid,child.pid);
394
+ assert.equal(ready.status,'ready');
395
+ const status=await f.runtime.status({goalId:submitted.goal_id});
396
+ assert.equal(status.state,'succeeded');
397
+ assert.ok(f.rounds()>=2);
398
+ assert.equal((await observeSupervisor({markerPath:f.markerPath})).reason,'no_owner');
399
+ } finally {
400
+ if(child && child.exitCode===null) child.kill();
401
+ await f.cleanup();
402
+ }
403
+ });