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.
Files changed (349) hide show
  1. package/CONTEXT.md +41 -0
  2. package/MANIFEST.SHA256 +348 -83
  3. package/R34-BASELINE.json +9 -0
  4. package/README.txt +135 -9
  5. package/bench/fixtures/corpus.json +17 -0
  6. package/bin/WORKER-REGISTRY.txt +3 -3
  7. package/bin/appcontainer-stage.exe +0 -0
  8. package/bin/appcontainer-stage.obj +0 -0
  9. package/bin/bootstrap-advapi32.exe +0 -0
  10. package/bin/bootstrap-advapi32.obj +0 -0
  11. package/bin/bootstrap-exitcode.exe +0 -0
  12. package/bin/bootstrap-exitcode.obj +0 -0
  13. package/bin/bootstrap-kernel32.exe +0 -0
  14. package/bin/bootstrap-kernel32.obj +0 -0
  15. package/bin/child-control-probe.exe +0 -0
  16. package/bin/child-control-probe.obj +0 -0
  17. package/bin/child-control-stage.exe +0 -0
  18. package/bin/child-control-stage.obj +0 -0
  19. package/bin/contained-reverse-worker.exe +0 -0
  20. package/bin/contained-reverse-worker.obj +0 -0
  21. package/bin/contained-transform-worker.exe +0 -0
  22. package/bin/contained-transform-worker.obj +0 -0
  23. package/bin/containment-probe.exe +0 -0
  24. package/bin/containment-probe.obj +0 -0
  25. package/bin/deadbyte-contain.exe +0 -0
  26. package/bin/deadbyte-contain.obj +0 -0
  27. package/bin/deadbyte-exec.exe +0 -0
  28. package/bin/deadbyte-exec.obj +0 -0
  29. package/bin/deadbyte-process-host.exe +0 -0
  30. package/bin/deadbyte-process-host.obj +0 -0
  31. package/bin/deadbyte-tunnel-host.exe +0 -0
  32. package/bin/deadbyte-tunnel-host.obj +0 -0
  33. package/controller/README.TXT +10 -4
  34. package/controller/deadbyte-controller.config.psd1.example +14 -0
  35. package/controller/deadbyte-controller.ps1 +144 -19
  36. package/controller/deadbyte-process-policy.json +5 -5
  37. package/controller/deadbyte-semantic-lsp-config.json +95 -0
  38. package/deadbyte-mcp-0.8.9.tgz +0 -0
  39. package/docs/ADR-0001-PRODUCTION-BASELINE-SEAMS.md +29 -0
  40. package/docs/ARCHITECTURE.md +6 -5
  41. package/docs/superpowers/plans/2026-09-16-deadbyte-loop-engine.md +846 -0
  42. package/docs/superpowers/plans/2026-09-17-r35-production-successor.md +408 -0
  43. package/docs/superpowers/specs/2026-09-16-deadbyte-loop-engine-design.md +435 -0
  44. package/docs/superpowers/specs/2026-09-17-r35-production-successor-design.md +220 -0
  45. package/node_modules/typescript/LICENSE.txt +55 -0
  46. package/node_modules/typescript/README.md +50 -0
  47. package/node_modules/typescript/SECURITY.md +41 -0
  48. package/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
  49. package/node_modules/typescript/bin/tsc +2 -0
  50. package/node_modules/typescript/bin/tsserver +2 -0
  51. package/node_modules/typescript/lib/_tsc.js +133818 -0
  52. package/node_modules/typescript/lib/_tsserver.js +659 -0
  53. package/node_modules/typescript/lib/_typingsInstaller.js +222 -0
  54. package/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
  55. package/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
  56. package/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
  57. package/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
  58. package/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
  59. package/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
  60. package/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
  61. package/node_modules/typescript/lib/lib.d.ts +22 -0
  62. package/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
  63. package/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
  64. package/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
  65. package/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
  66. package/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
  67. package/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
  68. package/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
  69. package/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
  70. package/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
  71. package/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
  72. package/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
  73. package/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
  74. package/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
  75. package/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
  76. package/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
  77. package/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
  78. package/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
  79. package/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
  80. package/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
  81. package/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
  82. package/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
  83. package/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
  84. package/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
  85. package/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
  86. package/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
  87. package/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
  88. package/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
  89. package/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
  90. package/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
  91. package/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
  92. package/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
  93. package/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
  94. package/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
  95. package/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
  96. package/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
  97. package/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
  98. package/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
  99. package/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
  100. package/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
  101. package/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
  102. package/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
  103. package/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
  104. package/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
  105. package/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
  106. package/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
  107. package/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
  108. package/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
  109. package/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
  110. package/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
  111. package/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
  112. package/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
  113. package/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
  114. package/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
  115. package/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
  116. package/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
  117. package/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
  118. package/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
  119. package/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
  120. package/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
  121. package/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
  122. package/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
  123. package/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
  124. package/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
  125. package/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
  126. package/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
  127. package/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
  128. package/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
  129. package/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
  130. package/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
  131. package/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
  132. package/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
  133. package/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
  134. package/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
  135. package/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
  136. package/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
  137. package/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
  138. package/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
  139. package/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
  140. package/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
  141. package/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
  142. package/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
  143. package/node_modules/typescript/lib/lib.es6.d.ts +23 -0
  144. package/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
  145. package/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
  146. package/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
  147. package/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
  148. package/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
  149. package/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
  150. package/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
  151. package/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
  152. package/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
  153. package/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
  154. package/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
  155. package/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
  156. package/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
  157. package/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
  158. package/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
  159. package/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
  160. package/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
  161. package/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
  162. package/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
  163. package/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
  164. package/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
  165. package/node_modules/typescript/lib/tsc.js +8 -0
  166. package/node_modules/typescript/lib/tsserver.js +8 -0
  167. package/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
  168. package/node_modules/typescript/lib/tsserverlibrary.js +21 -0
  169. package/node_modules/typescript/lib/typesMap.json +497 -0
  170. package/node_modules/typescript/lib/typescript.d.ts +11437 -0
  171. package/node_modules/typescript/lib/typescript.js +200276 -0
  172. package/node_modules/typescript/lib/typingsInstaller.js +8 -0
  173. package/node_modules/typescript/lib/watchGuard.js +53 -0
  174. package/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
  175. package/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
  176. package/node_modules/typescript/package.json +120 -0
  177. package/package.json +5 -3
  178. package/proof/CONTAINMENT-BUILD.txt +6 -6
  179. package/proof/R34-TASK8-SUPERVISOR-CHECKPOINT.json +29 -0
  180. package/proof/R34-TASK9-MCP-SURFACE-CHECKPOINT.json +28 -0
  181. package/scripts/capability-benchmark.mjs +27 -0
  182. package/scripts/deferred-slot-operation.mjs +4 -2
  183. package/scripts/final-closure-verify.mjs +10 -10
  184. package/scripts/final-closure.mjs +11 -11
  185. package/scripts/gate-windows.ps1 +3 -3
  186. package/scripts/release-parity.mjs +14 -14
  187. package/scripts/semantic-preflight.ps1 +73 -0
  188. package/scripts/tool-surface-snapshot.mjs +73 -0
  189. package/scripts/windows-gate-evidence.mjs +5 -5
  190. package/src/audit-verify.mjs +6 -2
  191. package/src/autonomous-action-reconcile.mjs +142 -0
  192. package/src/autonomous-context-engine.mjs +255 -0
  193. package/src/autonomous-live-state.mjs +17 -0
  194. package/src/autonomous-local-supervisor.mjs +249 -0
  195. package/src/autonomous-loop-state.mjs +304 -0
  196. package/src/autonomous-output-contracts.mjs +22 -3
  197. package/src/autonomous-plan.mjs +181 -0
  198. package/src/autonomous-planner-contracts.mjs +44 -0
  199. package/src/autonomous-planner.mjs +91 -6
  200. package/src/autonomous-policy.mjs +15 -2
  201. package/src/autonomous-progress.mjs +127 -0
  202. package/src/autonomous-runtime.mjs +601 -48
  203. package/src/autonomous-supervisor-host.mjs +70 -0
  204. package/src/autonomous-supervisor.mjs +31 -8
  205. package/src/capability-benchmark-runner.mjs +108 -0
  206. package/src/capability-benchmark.mjs +50 -0
  207. package/src/coding-mcp-tools.mjs +46 -3
  208. package/src/coding-output-contracts.mjs +45 -0
  209. package/src/context-provenance.mjs +86 -0
  210. package/src/deadbyte-cli.mjs +136 -30
  211. package/src/document-adapter.mjs +43 -0
  212. package/src/lsp-stdio-client.mjs +112 -0
  213. package/src/machine-fs-smoke-client.mjs +2 -1
  214. package/src/mcp-server.mjs +17 -3
  215. package/src/observation-smoke-client.mjs +3 -2
  216. package/src/operator-surface.mjs +37 -0
  217. package/src/provider-circuit.mjs +125 -0
  218. package/src/release-generation.mjs +44 -5
  219. package/src/remote-mcp-autonomous-smoke-client.mjs +53 -14
  220. package/src/remote-mcp-coding-smoke-client.mjs +5 -4
  221. package/src/remote-mcp-r24-disarmed-smoke-client.mjs +4 -2
  222. package/src/remote-mcp-r33-parity-client.mjs +1 -1
  223. package/src/remote-mcp-r34-parity-client.mjs +177 -0
  224. package/src/remote-mcp-smoke-client.mjs +2 -1
  225. package/src/remote-result-journal.mjs +114 -0
  226. package/src/runtime-update.mjs +58 -8
  227. package/src/semantic-backend-registry.mjs +39 -0
  228. package/src/semantic-code.mjs +179 -0
  229. package/src/semantic-lsp-backend.mjs +183 -0
  230. package/src/semantic-lsp-config.mjs +112 -0
  231. package/src/tool-surface-ledger.mjs +92 -0
  232. package/src/version.mjs +1 -1
  233. package/test/audit-verify.test.mjs +1 -1
  234. package/test/autonomous-action-reconcile.test.mjs +106 -0
  235. package/test/autonomous-adversarial.test.mjs +149 -6
  236. package/test/autonomous-context-engine.test.mjs +181 -0
  237. package/test/autonomous-live-state.test.mjs +27 -0
  238. package/test/autonomous-local-supervisor.test.mjs +403 -0
  239. package/test/autonomous-loop-state.test.mjs +126 -0
  240. package/test/autonomous-loop-v2.test.mjs +105 -0
  241. package/test/autonomous-loop.test.mjs +79 -1
  242. package/test/autonomous-output-contract.test.mjs +54 -0
  243. package/test/autonomous-plan.test.mjs +101 -0
  244. package/test/autonomous-progress.test.mjs +106 -0
  245. package/test/autonomous-r34-e2e.test.mjs +338 -0
  246. package/test/autonomous-runtime.test.mjs +3 -3
  247. package/test/autonomous-supervisor-integration.test.mjs +48 -3
  248. package/test/capability-benchmark-runner.test.mjs +49 -0
  249. package/test/capability-benchmark.test.mjs +47 -0
  250. package/test/cli-entrypoint.test.mjs +12 -0
  251. package/test/coding-catalog-consistency.test.mjs +24 -0
  252. package/test/coding-plane.test.mjs +3 -3
  253. package/test/context-provenance.test.mjs +61 -0
  254. package/test/controller-r27.test.mjs +4 -3
  255. package/test/controller.test.mjs +52 -0
  256. package/test/core.test.mjs +1 -1
  257. package/test/deferred-slot-operation-behavior.test.mjs +5 -1
  258. package/test/deferred-slot-operation.test.mjs +2 -1
  259. package/test/document-adapter.test.mjs +23 -0
  260. package/test/fixtures/lsp-framed-server.mjs +33 -0
  261. package/test/fixtures/semantic/cpp/compile_commands.json +4 -0
  262. package/test/fixtures/semantic/cpp/lib.cpp +2 -0
  263. package/test/fixtures/semantic/cpp/lib.hpp +2 -0
  264. package/test/fixtures/semantic/cpp/main.cpp +2 -0
  265. package/test/fixtures/semantic/python/lib.py +2 -0
  266. package/test/fixtures/semantic/python/main.py +2 -0
  267. package/test/fixtures/semantic/rust/Cargo.lock +7 -0
  268. package/test/fixtures/semantic/rust/Cargo.toml +8 -0
  269. package/test/fixtures/semantic/rust/src/lib.rs +3 -0
  270. package/test/fixtures/semantic/rust/src/main.rs +5 -0
  271. package/test/fixtures/semantic/rust/src/math.rs +3 -0
  272. package/test/fixtures/semantic/rust/target/.rustc_info.json +1 -0
  273. package/test/fixtures/semantic/rust/target/CACHEDIR.TAG +3 -0
  274. package/test/fixtures/semantic/rust/target/debug/.cargo-lock +0 -0
  275. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/dep-test-lib-semantic_rust +0 -0
  276. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/invoked.timestamp +1 -0
  277. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/test-lib-semantic_rust +1 -0
  278. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-4c168fa33c79d09c/test-lib-semantic_rust.json +1 -0
  279. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/dep-test-bin-semantic_rust_bin +0 -0
  280. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/invoked.timestamp +1 -0
  281. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/test-bin-semantic_rust_bin +1 -0
  282. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-5dcd474439c54a26/test-bin-semantic_rust_bin.json +1 -0
  283. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/dep-lib-semantic_rust +0 -0
  284. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/invoked.timestamp +1 -0
  285. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/lib-semantic_rust +1 -0
  286. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-6212ccd976aa3808/lib-semantic_rust.json +1 -0
  287. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/bin-semantic_rust_bin +1 -0
  288. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/bin-semantic_rust_bin.json +1 -0
  289. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/dep-bin-semantic_rust_bin +0 -0
  290. package/test/fixtures/semantic/rust/target/debug/.fingerprint/semantic_rust-d741378dccdef61c/invoked.timestamp +1 -0
  291. package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust-4c168fa33c79d09c.rmeta +0 -0
  292. package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust-6212ccd976aa3808.rmeta +0 -0
  293. package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust_bin-5dcd474439c54a26.rmeta +0 -0
  294. package/test/fixtures/semantic/rust/target/debug/deps/libsemantic_rust_bin-d741378dccdef61c.rmeta +0 -0
  295. package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust-4c168fa33c79d09c.d +5 -0
  296. package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust-6212ccd976aa3808.d +5 -0
  297. package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust_bin-5dcd474439c54a26.d +6 -0
  298. package/test/fixtures/semantic/rust/target/debug/deps/semantic_rust_bin-d741378dccdef61c.d +6 -0
  299. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/dep-graph.bin +0 -0
  300. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/query-cache.bin +0 -0
  301. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc-1qb77z00k06rqw4jdkj92spax/work-products.bin +0 -0
  302. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-1nzlugxi6lq16/s-hmdgo8b6hg-1n6glhc.lock +0 -0
  303. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/dep-graph.bin +0 -0
  304. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/metadata.rmeta +0 -0
  305. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/query-cache.bin +0 -0
  306. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq-9twkpivsqnjon278x20bddozq/work-products.bin +0 -0
  307. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust-3s436v7g6f5xm/s-hmdgo8b58k-1ekj4lq.lock +0 -0
  308. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/dep-graph.bin +0 -0
  309. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/query-cache.bin +0 -0
  310. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3-cmu3jai030no72y8u9eurrnjj/work-products.bin +0 -0
  311. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-1jxcbdeehal7q/s-hmdgo8bxlf-1qr24o3.lock +0 -0
  312. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/dep-graph.bin +0 -0
  313. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/query-cache.bin +0 -0
  314. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt-diy9mqvc2eoiblmhjs3stcgi3/work-products.bin +0 -0
  315. package/test/fixtures/semantic/rust/target/debug/incremental/semantic_rust_bin-2ocx55p60ni6b/s-hmdgo8bxj8-0ir41qt.lock +0 -0
  316. package/test/fixtures/semantic/rust/target/flycheck0/stderr +1 -0
  317. package/test/fixtures/semantic/rust/target/flycheck0/stdout +5 -0
  318. package/test/fixtures/semantic/typescript/lib.ts +3 -0
  319. package/test/fixtures/semantic/typescript/main.ts +2 -0
  320. package/test/fixtures/tool-surface-stdio-server.mjs +14 -0
  321. package/test/helpers/autonomous-r34-fixture.mjs +120 -0
  322. package/test/lsp-stdio-client.test.mjs +72 -0
  323. package/test/multi-file-read.test.mjs +41 -0
  324. package/test/observation-integration.test.mjs +3 -3
  325. package/test/production-docs.test.mjs +48 -0
  326. package/test/prompts-resources.test.mjs +35 -0
  327. package/test/provider-circuit.test.mjs +93 -0
  328. package/test/public-autonomous-ingress-budget.test.mjs +28 -0
  329. package/test/r33-closeout-regression.test.mjs +3 -3
  330. package/test/r33-finalization.test.mjs +19 -16
  331. package/test/release-generation.test.mjs +23 -2
  332. package/test/release-version.test.mjs +24 -17
  333. package/test/remote-r24-catalog.test.mjs +5 -4
  334. package/test/remote-result-journal.test.mjs +58 -0
  335. package/test/remote-session-cli.test.mjs +150 -15
  336. package/test/runtime-self-update.test.mjs +63 -0
  337. package/test/semantic-backend-registry.test.mjs +29 -0
  338. package/test/semantic-code.test.mjs +66 -0
  339. package/test/semantic-lsp-backend.test.mjs +99 -0
  340. package/test/semantic-lsp-config.test.mjs +81 -0
  341. package/test/semantic-lsp-readiness.test.mjs +34 -0
  342. package/test/semantic-lsp-transient-empty.test.mjs +32 -0
  343. package/test/semantic-lsp-transient-null.test.mjs +31 -0
  344. package/test/semantic-multilang.test.mjs +72 -0
  345. package/test/semantic-runtime-routing.test.mjs +32 -0
  346. package/test/semantic-server-config-integration.test.mjs +66 -0
  347. package/test/tool-surface-ledger.test.mjs +59 -0
  348. package/test/tool-surface-snapshot.test.mjs +17 -0
  349. package/test/tracer-bullet.test.mjs +77 -0
@@ -0,0 +1,183 @@
1
+ import { createHash } from 'node:crypto';
2
+ import path from 'node:path';
3
+ import { fileURLToPath, pathToFileURL } from 'node:url';
4
+ import { createLspStdioClient } from './lsp-stdio-client.mjs';
5
+
6
+ const SYMBOL_KIND={1:'file',2:'module',3:'namespace',4:'package',5:'class',6:'method',7:'property',8:'field',9:'constructor',10:'enum',11:'interface',12:'function',13:'variable',14:'constant',15:'string',16:'number',17:'boolean',18:'array',19:'object',20:'key',21:'null',22:'enum_member',23:'struct',24:'event',25:'operator',26:'type_parameter'};
7
+ const SEVERITY={1:'error',2:'warning',3:'information',4:'hint'};
8
+ const MAX_WORKSPACE_ENTRIES=512;
9
+ const MAX_WORKSPACE_DOCUMENTS=128;
10
+ const relNormalized=value=>value.replaceAll('\\','/').replace(/^\.\//,'');
11
+ const digest=value=>createHash('sha256').update(JSON.stringify(value)).digest('hex');
12
+ function inside(root,target){const rel=path.relative(root,target);return rel===''||(!rel.startsWith(`..${path.sep}`)&&rel!=='..'&&!path.isAbsolute(rel));}
13
+ function denied(root,absolute){
14
+ if(!inside(root.real_path,absolute)) return true;
15
+ const rel=relNormalized(path.relative(root.real_path,absolute)).toLowerCase();
16
+ return (root.deny_paths??[]).some(item=>rel===String(item).toLowerCase()||rel.startsWith(`${String(item).toLowerCase()}/`));
17
+ }
18
+ function kindName(kind){return SYMBOL_KIND[Number(kind)]??String(kind??'unknown');}
19
+ function validPosition(value){return value&&Number.isInteger(value.line)&&value.line>=0&&Number.isInteger(value.character)&&value.character>=0;}
20
+ function validRange(value){return value&&validPosition(value.start)&&validPosition(value.end);}
21
+ function positionToOffset(text,position){
22
+ if(!validPosition(position)) throw new Error('LSP position invalid');
23
+ let line=0,start=0;
24
+ while(line<position.line){const next=text.indexOf('\n',start);if(next<0)throw new Error('LSP position line outside file');start=next+1;line+=1;}
25
+ const lineEnd=text.indexOf('\n',start);const end=lineEnd<0?text.length:lineEnd;
26
+ const offset=start+position.character;
27
+ if(offset>end) throw new Error('LSP position character outside line');
28
+ return offset;
29
+ }
30
+ function rangeLocation(root,uri,range,{name='',kind='unknown'}={}){
31
+ if(typeof uri!=='string'||!uri.startsWith('file:')||!validRange(range)) return null;
32
+ let absolute;
33
+ try { absolute=path.resolve(fileURLToPath(uri)); } catch { return null; }
34
+ if(!inside(root.real_path,absolute)||denied(root,absolute)) return null;
35
+ return {path:relNormalized(path.relative(root.real_path,absolute)),name:String(name),kind:String(kind),start_line:range.start.line,start_column:range.start.character,end_line:range.end.line,end_column:range.end.character};
36
+ }
37
+ async function rootContext(codingRuntime,rootId,relativePath){
38
+ const status=await codingRuntime.sessionStatus();
39
+ if(!status.armed) throw new Error(`coding plane is disarmed: ${status.reason}`);
40
+ if(!status.root_ids.includes(rootId)) throw new Error(`coding root '${rootId}' is outside active lease`);
41
+ const root=codingRuntime.policy.roots[rootId];
42
+ if(!root||root.read!==true) throw new Error(`coding root '${rootId}' does not allow read`);
43
+ const normalized=relNormalized(relativePath);
44
+ const absolute=path.resolve(root.real_path,...normalized.split('/'));
45
+ if(!inside(root.real_path,absolute)) throw new Error('semantic target escapes coding root');
46
+ if(denied(root,absolute)) throw new Error(`semantic target denied by coding policy: ${normalized}`);
47
+ const file=await codingRuntime.fileRead({rootId,relativePath:normalized,encoding:'utf8'});
48
+ if(typeof file.content!=='string'||typeof file.sha256!=='string') throw new Error('semantic target read missing content identity');
49
+ return {root,rootId,relativePath:normalized,absolute,file,uri:pathToFileURL(absolute).href,rootUri:pathToFileURL(root.real_path+path.sep).href};
50
+ }
51
+ function flattenDocumentSymbols(result,ctx,backendId,maxSymbols){
52
+ if(!Array.isArray(result)) return {symbols:[],truncated:false};
53
+ const out=[];
54
+ const visit=(item,container='')=>{
55
+ if(out.length>=maxSymbols||!item||typeof item!=='object') return;
56
+ if(item.location?.uri&&validRange(item.location.range)){
57
+ const kind=kindName(item.kind);const loc=rangeLocation(ctx.root,item.location.uri,item.location.range,{name:item.name??'',kind});
58
+ if(loc){const selection=item.location.range;const symbolId=digest({schema:'deadbyte.semantic-symbol.v1',backend:backendId,path:loc.path,file_sha256:ctx.file.sha256,name:loc.name,kind,range:item.location.range});out.push({...loc,symbol_id:symbolId,container_name:String(item.containerName??container),name_start_line:selection.start.line,name_start_column:selection.start.character,_range:item.location.range});}
59
+ return;
60
+ }
61
+ if(typeof item.name==='string'&&validRange(item.range)){
62
+ const kind=kindName(item.kind);const loc={path:ctx.relativePath,name:item.name,kind,start_line:item.range.start.line,start_column:item.range.start.character,end_line:item.range.end.line,end_column:item.range.end.character};
63
+ const selection=validRange(item.selectionRange)?item.selectionRange:item.range;
64
+ const symbolId=digest({schema:'deadbyte.semantic-symbol.v1',backend:backendId,path:loc.path,file_sha256:ctx.file.sha256,name:item.name,kind,range:item.range});
65
+ out.push({...loc,symbol_id:symbolId,container_name:container,name_start_line:selection.start.line,name_start_column:selection.start.character,_range:item.range});
66
+ for(const child of item.children??[]) visit(child,item.name);
67
+ }
68
+ };
69
+ for(const item of result) visit(item,'');
70
+ return {symbols:out.slice(0,maxSymbols),truncated:out.length>=maxSymbols};
71
+ }
72
+ function normalizeLocations(result,ctx,maxResults){
73
+ const raw=result==null?[]:(Array.isArray(result)?result:[result]);
74
+ const locations=[];
75
+ for(const item of raw){
76
+ let uri=null,range=null;
77
+ if(item?.uri&&validRange(item.range)){uri=item.uri;range=item.range;}
78
+ else if(item?.targetUri&&validRange(item.targetSelectionRange??item.targetRange)){uri=item.targetUri;range=item.targetSelectionRange??item.targetRange;}
79
+ const loc=rangeLocation(ctx.root,uri,range,{name:'',kind:'reference'});if(loc)locations.push(loc);
80
+ }
81
+ return {locations:locations.slice(0,maxResults),truncated:locations.length>maxResults};
82
+ }
83
+
84
+ export function createSemanticLspBackend({id,extensions,codingRuntime,server}){
85
+ if(typeof id!=='string'||id.length<1) throw new Error('semantic LSP backend id missing');
86
+ if(!Array.isArray(extensions)||extensions.length<1) throw new Error(`semantic LSP backend ${id} extensions missing`);
87
+ if(!codingRuntime) throw new Error(`semantic LSP backend ${id} requires coding runtime`);
88
+ if(!server||typeof server!=='object') throw new Error(`semantic LSP backend ${id} server config missing`);
89
+ const extensionSet=new Set(extensions.map(ext=>String(ext).toLowerCase()));
90
+ const languageId=String(server.language_id??id);
91
+ const startupSettleMs=server.startup_settle_ms===undefined?0:Number(server.startup_settle_ms);
92
+ if(!Number.isInteger(startupSettleMs)||startupSettleMs<0||startupSettleMs>5000) throw new Error(`semantic LSP backend ${id} startup_settle_ms invalid`);
93
+ const nullResultRetryMs=server.null_result_retry_ms===undefined?0:Number(server.null_result_retry_ms);
94
+ const nullResultMaxAttempts=server.null_result_max_attempts===undefined?1:Number(server.null_result_max_attempts);
95
+ const retryEmptyResults=server.retry_empty_results===undefined?false:server.retry_empty_results;
96
+ if(!Number.isInteger(nullResultRetryMs)||nullResultRetryMs<0||nullResultRetryMs>1000) throw new Error(`semantic LSP backend ${id} null_result_retry_ms invalid`);
97
+ if(!Number.isInteger(nullResultMaxAttempts)||nullResultMaxAttempts<1||nullResultMaxAttempts>20) throw new Error(`semantic LSP backend ${id} null_result_max_attempts invalid`);
98
+ if(typeof retryEmptyResults!=='boolean') throw new Error(`semantic LSP backend ${id} retry_empty_results invalid`);
99
+ if(nullResultMaxAttempts>1&&nullResultRetryMs<1) throw new Error(`semantic LSP backend ${id} null_result_retry_ms required when retrying null results`);
100
+ const workspaceDocuments=async ctx=>{
101
+ const target={relativePath:ctx.relativePath,uri:ctx.uri,text:ctx.file.content};
102
+ if(typeof codingRuntime.tree!=='function') return [target];
103
+ const tree=await codingRuntime.tree({rootId:ctx.rootId,path:'.',maxDepth:12,maxEntries:MAX_WORKSPACE_ENTRIES});
104
+ if(tree.truncated) throw new Error(`semantic LSP workspace exceeds ${MAX_WORKSPACE_ENTRIES} entry bound`);
105
+ const relativeFiles=tree.entries.filter(item=>item.type==='file'&&extensionSet.has(path.extname(item.path).toLowerCase())).map(item=>relNormalized(item.path));
106
+ if(relativeFiles.length>MAX_WORKSPACE_DOCUMENTS) throw new Error(`semantic LSP workspace exceeds ${MAX_WORKSPACE_DOCUMENTS} source document bound`);
107
+ const documents=[];
108
+ for(const relativePath of relativeFiles){
109
+ if(relativePath===ctx.relativePath){documents.push(target);continue;}
110
+ const absolute=path.resolve(ctx.root.real_path,...relativePath.split('/'));
111
+ if(!inside(ctx.root.real_path,absolute)||denied(ctx.root,absolute)) continue;
112
+ const file=await codingRuntime.fileRead({rootId:ctx.rootId,relativePath,encoding:'utf8'});
113
+ if(typeof file.content!=='string') throw new Error(`semantic LSP preload missing UTF-8 content: ${relativePath}`);
114
+ documents.push({relativePath,uri:pathToFileURL(absolute).href,text:file.content});
115
+ }
116
+ if(!documents.some(item=>item.relativePath===ctx.relativePath)) documents.unshift(target);
117
+ return documents;
118
+ };
119
+ const open=async ctx=>{
120
+ const client=createLspStdioClient({executablePath:server.executable_path,expectedSha256:server.executable_sha256,args:server.args??[],cwd:ctx.root.real_path,env:server.env??{},dependencies:server.dependencies??[],requestTimeoutMs:server.request_timeout_ms??10000,maxMessageBytes:server.max_message_bytes??4*1024*1024});
121
+ try{
122
+ await client.initialize({processId:null,rootPath:ctx.root.real_path,rootUri:ctx.rootUri,workspaceFolders:[{uri:ctx.rootUri,name:path.basename(ctx.root.real_path)}],capabilities:{workspace:{workspaceFolders:true},textDocument:{documentSymbol:{hierarchicalDocumentSymbolSupport:true},definition:{},references:{},diagnostic:{}}},initializationOptions:server.initialization_options??{}});
123
+ for(const document of await workspaceDocuments(ctx)) client.notify('textDocument/didOpen',{textDocument:{uri:document.uri,languageId,version:1,text:document.text}});
124
+ if(startupSettleMs>0) await new Promise(resolve=>setTimeout(resolve,startupSettleMs));
125
+ return client;
126
+ } catch(error){await client.shutdown().catch(()=>{});throw error;}
127
+ };
128
+ const withClient=async(ctx,fn)=>{const client=await open(ctx);try{return await fn(client);}finally{await client.shutdown().catch(()=>{});}};
129
+ const requestRead=async(client,method,params)=>{
130
+ let result=null;
131
+ for(let attempt=1;attempt<=nullResultMaxAttempts;attempt+=1){
132
+ result=await client.request(method,params);
133
+ const transientEmpty=retryEmptyResults&&Array.isArray(result)&&result.length===0;
134
+ if((result!==null&&!transientEmpty)||attempt===nullResultMaxAttempts) return result;
135
+ await new Promise(resolve=>setTimeout(resolve,nullResultRetryMs));
136
+ }
137
+ return result;
138
+ };
139
+ async function outline({rootId,relativePath,maxSymbols=200}){
140
+ if(!Number.isInteger(maxSymbols)||maxSymbols<1||maxSymbols>500) throw new Error('max_symbols must be in [1, 500]');
141
+ const ctx=await rootContext(codingRuntime,rootId,relativePath);
142
+ const raw=await withClient(ctx,client=>requestRead(client,'textDocument/documentSymbol',{textDocument:{uri:ctx.uri}}));
143
+ const flat=flattenDocumentSymbols(raw,ctx,id,maxSymbols);
144
+ return {status:'ok',root_id:rootId,path:ctx.relativePath,file_sha256:ctx.file.sha256,engine:id,symbols:flat.symbols.map(({_range,...item})=>item),truncated:flat.truncated};
145
+ }
146
+ async function definition({rootId,relativePath,line,column,maxResults=50}){
147
+ if(!Number.isInteger(maxResults)||maxResults<1||maxResults>200) throw new Error('max_results must be in [1, 200]');
148
+ const ctx=await rootContext(codingRuntime,rootId,relativePath);
149
+ const raw=await withClient(ctx,client=>requestRead(client,'textDocument/definition',{textDocument:{uri:ctx.uri},position:{line,character:column}}));
150
+ const normalized=normalizeLocations(raw,ctx,maxResults);
151
+ return {status:'ok',root_id:rootId,path:ctx.relativePath,line,column,engine:id,...normalized};
152
+ }
153
+ async function references({rootId,relativePath,line,column,maxResults=200}){
154
+ if(!Number.isInteger(maxResults)||maxResults<1||maxResults>500) throw new Error('max_results must be in [1, 500]');
155
+ const ctx=await rootContext(codingRuntime,rootId,relativePath);
156
+ const raw=await withClient(ctx,client=>requestRead(client,'textDocument/references',{textDocument:{uri:ctx.uri},position:{line,character:column},context:{includeDeclaration:true}}));
157
+ const normalized=normalizeLocations(raw,ctx,maxResults);
158
+ return {status:'ok',root_id:rootId,path:ctx.relativePath,line,column,engine:id,...normalized};
159
+ }
160
+ async function diagnostics({rootId,relativePath,maxResults=200}){
161
+ if(!Number.isInteger(maxResults)||maxResults<1||maxResults>500) throw new Error('max_results must be in [1, 500]');
162
+ const ctx=await rootContext(codingRuntime,rootId,relativePath);
163
+ const raw=await withClient(ctx,client=>requestRead(client,'textDocument/diagnostic',{textDocument:{uri:ctx.uri}}));
164
+ const items=Array.isArray(raw?.items)?raw.items:[];
165
+ const diagnosticsOut=items.slice(0,maxResults).filter(item=>validRange(item?.range)).map(item=>({message:String(item.message??''),code:String(item.code??''),severity:SEVERITY[Number(item.severity)]??'unknown',location:{path:ctx.relativePath,name:'',kind:'diagnostic',start_line:item.range.start.line,start_column:item.range.start.character,end_line:item.range.end.line,end_column:item.range.end.character}}));
166
+ return {status:'ok',root_id:rootId,path:ctx.relativePath,engine:id,diagnostics:diagnosticsOut,truncated:items.length>maxResults};
167
+ }
168
+ async function replaceSymbol({rootId,relativePath,symbolId,newBody,expectedSha256}){
169
+ if(typeof newBody!=='string'||newBody.length>524288) throw new Error('new_body exceeds 524288 characters');
170
+ const ctx=await rootContext(codingRuntime,rootId,relativePath);
171
+ if(ctx.file.sha256!==expectedSha256) throw new Error(`semantic replace precondition mismatch: expected ${expectedSha256}, found ${ctx.file.sha256}`);
172
+ const raw=await withClient(ctx,client=>requestRead(client,'textDocument/documentSymbol',{textDocument:{uri:ctx.uri}}));
173
+ const flat=flattenDocumentSymbols(raw,ctx,id,500);
174
+ const symbol=flat.symbols.find(item=>item.symbol_id===symbolId);
175
+ if(!symbol) throw new Error('semantic symbol_id is stale or unknown for current file');
176
+ const start=positionToOffset(ctx.file.content,symbol._range.start);const end=positionToOffset(ctx.file.content,symbol._range.end);
177
+ if(end<start) throw new Error('semantic symbol range invalid');
178
+ const oldBody=ctx.file.content.slice(start,end);
179
+ const result=await codingRuntime.textReplace({rootId,relativePath:ctx.relativePath,oldString:oldBody,newString:newBody,expectedSha256,expectedReplacements:1});
180
+ return {...result,symbol_id:symbolId,symbol_name:symbol.name,engine:id};
181
+ }
182
+ return Object.freeze({id,extensions:extensionSet,outline,definition,references,replaceSymbol,diagnostics});
183
+ }
@@ -0,0 +1,112 @@
1
+ import path from 'node:path';
2
+ import { createHash } from 'node:crypto';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { createSemanticLspBackend } from './semantic-lsp-backend.mjs';
5
+
6
+ const HEX64=/^[0-9a-f]{64}$/;
7
+ const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
8
+ const ID=/^[A-Za-z0-9._-]{1,64}$/;
9
+
10
+ function plainObject(value){return value&&typeof value==='object'&&!Array.isArray(value);}
11
+
12
+ export function parseSemanticLspConfig(value){
13
+ if(!plainObject(value)||value.schema!=='deadbyte.semantic-lsp-config.v1') throw new Error('semantic LSP config schema mismatch');
14
+ if(!Array.isArray(value.servers)) throw new Error('semantic LSP config servers must be an array');
15
+ if(value.servers.length>16) throw new Error('semantic LSP config server count exceeds 16');
16
+ const ids=new Set();
17
+ const extensions=new Map();
18
+ const servers=value.servers.map((raw,index)=>{
19
+ if(!plainObject(raw)) throw new Error(`semantic LSP server ${index} must be an object`);
20
+ const id=String(raw.id??'');
21
+ if(!ID.test(id)) throw new Error(`semantic LSP server ${index} id invalid`);
22
+ const languageId=String(raw.language_id??id);
23
+ if(!ID.test(languageId)) throw new Error(`semantic LSP server ${id} language_id invalid`);
24
+ if(ids.has(id)) throw new Error(`duplicate semantic LSP server id: ${id}`);
25
+ ids.add(id);
26
+ if(!Array.isArray(raw.extensions)||raw.extensions.length<1||raw.extensions.length>32) throw new Error(`semantic LSP server ${id} extensions missing`);
27
+ const normalizedExtensions=[];
28
+ for(const item of raw.extensions){
29
+ const ext=String(item??'').toLowerCase();
30
+ if(!/^\.[a-z0-9+_-]{1,16}$/.test(ext)) throw new Error(`semantic LSP server ${id} extension invalid: ${ext||'<empty>'}`);
31
+ const owner=extensions.get(ext);
32
+ if(owner&&owner!==id) throw new Error(`semantic extension ${ext} already owned by ${owner}`);
33
+ extensions.set(ext,id);
34
+ if(!normalizedExtensions.includes(ext)) normalizedExtensions.push(ext);
35
+ }
36
+ const executablePath=String(raw.executable_path??'');
37
+ if(!path.isAbsolute(executablePath)) throw new Error(`semantic LSP server ${id} executable_path must be absolute`);
38
+ const executableSha=String(raw.executable_sha256??'').toLowerCase();
39
+ if(!HEX64.test(executableSha)) throw new Error(`semantic LSP server ${id} executable SHA-256 invalid`);
40
+ const args=raw.args===undefined?[]:raw.args;
41
+ if(!Array.isArray(args)||args.length>64||args.some(item=>typeof item!=='string'||item.length>2048)) throw new Error(`semantic LSP server ${id} args invalid`);
42
+ const env=raw.env===undefined?{}:raw.env;
43
+ if(!plainObject(env)||Object.entries(env).some(([key,item])=>!ID.test(key)||typeof item!=='string'||item.length>4096)) throw new Error(`semantic LSP server ${id} env invalid`);
44
+ const dependencies=raw.dependencies===undefined?[]:raw.dependencies;
45
+ if(!Array.isArray(dependencies)||dependencies.length>32) throw new Error(`semantic LSP server ${id} dependencies invalid`);
46
+ const normalizedDependencies=dependencies.map((dependency,depIndex)=>{
47
+ if(!plainObject(dependency)) throw new Error(`semantic LSP server ${id} dependency ${depIndex} invalid`);
48
+ const dependencyPath=String(dependency.path??'');
49
+ if(!path.isAbsolute(dependencyPath)) throw new Error(`semantic LSP server ${id} dependency path must be absolute`);
50
+ const expectedSha256=String(dependency.expected_sha256??dependency.expectedSha256??'').toLowerCase();
51
+ if(!HEX64.test(expectedSha256)) throw new Error(`semantic LSP server ${id} dependency SHA-256 invalid`);
52
+ return {path:dependencyPath,expectedSha256};
53
+ });
54
+ const initializationOptions=raw.initialization_options===undefined?{}:raw.initialization_options;
55
+ if(!plainObject(initializationOptions)) throw new Error(`semantic LSP server ${id} initialization_options invalid`);
56
+ const requestTimeoutMs=raw.request_timeout_ms===undefined?10000:Number(raw.request_timeout_ms);
57
+ if(!Number.isInteger(requestTimeoutMs)||requestTimeoutMs<100||requestTimeoutMs>120000) throw new Error(`semantic LSP server ${id} request_timeout_ms invalid`);
58
+ const maxMessageBytes=raw.max_message_bytes===undefined?4*1024*1024:Number(raw.max_message_bytes);
59
+ if(!Number.isInteger(maxMessageBytes)||maxMessageBytes<256||maxMessageBytes>16*1024*1024) throw new Error(`semantic LSP server ${id} max_message_bytes invalid`);
60
+ const startupSettleMs=raw.startup_settle_ms===undefined?0:Number(raw.startup_settle_ms);
61
+ if(!Number.isInteger(startupSettleMs)||startupSettleMs<0||startupSettleMs>5000) throw new Error(`semantic LSP server ${id} startup_settle_ms invalid`);
62
+ const nullResultRetryMs=raw.null_result_retry_ms===undefined?0:Number(raw.null_result_retry_ms);
63
+ const nullResultMaxAttempts=raw.null_result_max_attempts===undefined?1:Number(raw.null_result_max_attempts);
64
+ const retryEmptyResults=raw.retry_empty_results===undefined?false:raw.retry_empty_results;
65
+ if(!Number.isInteger(nullResultRetryMs)||nullResultRetryMs<0||nullResultRetryMs>1000) throw new Error(`semantic LSP server ${id} null_result_retry_ms invalid`);
66
+ if(!Number.isInteger(nullResultMaxAttempts)||nullResultMaxAttempts<1||nullResultMaxAttempts>20) throw new Error(`semantic LSP server ${id} null_result_max_attempts invalid`);
67
+ if(typeof retryEmptyResults!=='boolean') throw new Error(`semantic LSP server ${id} retry_empty_results invalid`);
68
+ if(nullResultMaxAttempts>1&&nullResultRetryMs<1) throw new Error(`semantic LSP server ${id} null_result_retry_ms required when retrying null results`);
69
+ const required=raw.required===undefined?false:raw.required;
70
+ if(typeof required!=='boolean') throw new Error(`semantic LSP server ${id} required must be boolean`);
71
+ return {id,language_id:languageId,extensions:normalizedExtensions,executable_path:executablePath,executable_sha256:executableSha,args:[...args],env:{...env},dependencies:normalizedDependencies,initialization_options:initializationOptions,request_timeout_ms:requestTimeoutMs,max_message_bytes:maxMessageBytes,startup_settle_ms:startupSettleMs,null_result_retry_ms:nullResultRetryMs,null_result_max_attempts:nullResultMaxAttempts,retry_empty_results:retryEmptyResults,required};
72
+ });
73
+ return Object.freeze({schema:'deadbyte.semantic-lsp-config.v1',servers});
74
+ }
75
+
76
+ export function semanticConfigBindingFromEnv(env=process.env){
77
+ const configPath=String(env.DEADBYTE_SEMANTIC_LSP_CONFIG??'').trim();
78
+ const expectedConfigSha256=String(env.DEADBYTE_SEMANTIC_LSP_CONFIG_SHA256??'').trim().toLowerCase();
79
+ if(!configPath&&!expectedConfigSha256) return null;
80
+ if(configPath&&!expectedConfigSha256) throw new Error('DEADBYTE_SEMANTIC_LSP_CONFIG requires semantic LSP config SHA-256');
81
+ if(!configPath&&expectedConfigSha256) throw new Error('DEADBYTE_SEMANTIC_LSP_CONFIG_SHA256 requires semantic LSP config path');
82
+ if(!path.isAbsolute(configPath)) throw new Error('semantic LSP config path must be absolute');
83
+ if(!HEX64.test(expectedConfigSha256)) throw new Error('semantic LSP config SHA-256 invalid');
84
+ return Object.freeze({configPath,expectedConfigSha256});
85
+ }
86
+
87
+ export async function loadSemanticLspBackends({configPath,expectedConfigSha256,codingRuntime}){
88
+ if(typeof configPath!=='string'||!path.isAbsolute(configPath)) throw new Error('semantic LSP config path must be absolute');
89
+ if(!HEX64.test(expectedConfigSha256??'')) throw new Error('semantic LSP config SHA-256 invalid');
90
+ if(!codingRuntime) throw new Error('semantic LSP config requires coding runtime');
91
+ let configBytes,parsedJson;
92
+ try { configBytes=await readFile(configPath); parsedJson=JSON.parse(configBytes.toString('utf8')); }
93
+ catch(error){ throw new Error(`semantic LSP config read failed: ${error.message}`); }
94
+ const observedConfigSha256=sha256(configBytes);
95
+ if(observedConfigSha256!==expectedConfigSha256) throw new Error(`semantic LSP config SHA-256 mismatch: expected ${expectedConfigSha256}, found ${observedConfigSha256}`);
96
+ const config=parseSemanticLspConfig(parsedJson);
97
+ const backends=[];
98
+ const requiredIds=[];
99
+ for(const server of config.servers){
100
+ const executableBytes=await readFile(server.executable_path);
101
+ const executableSha=sha256(executableBytes);
102
+ if(executableSha!==server.executable_sha256) throw new Error(`semantic LSP executable SHA-256 mismatch for ${server.id}: expected ${server.executable_sha256}, found ${executableSha}`);
103
+ for(const dependency of server.dependencies){
104
+ const dependencyBytes=await readFile(dependency.path);
105
+ const dependencySha=sha256(dependencyBytes);
106
+ if(dependencySha!==dependency.expectedSha256) throw new Error(`semantic LSP dependency SHA-256 mismatch for ${server.id}: expected ${dependency.expectedSha256}, found ${dependencySha}`);
107
+ }
108
+ backends.push(createSemanticLspBackend({id:server.id,extensions:server.extensions,codingRuntime,server}));
109
+ if(server.required) requiredIds.push(server.id);
110
+ }
111
+ return Object.freeze({backends:Object.freeze(backends),required_ids:Object.freeze(requiredIds)});
112
+ }
@@ -0,0 +1,92 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ const SURFACE_SCHEMA='deadbyte.tool-surface.v1';
4
+
5
+ function canonicalValue(value,seen=new Set()){
6
+ if(value===null||typeof value==='string'||typeof value==='boolean') return value;
7
+ if(typeof value==='number'){
8
+ if(!Number.isFinite(value)) throw new Error('schema contains unsupported non-finite JSON number');
9
+ return Object.is(value,-0)?0:value;
10
+ }
11
+ if(typeof value==='undefined') throw new Error('schema contains unsupported undefined JSON value');
12
+ if(typeof value==='function') throw new Error('schema contains unsupported function JSON value');
13
+ if(typeof value==='symbol') throw new Error('schema contains unsupported symbol JSON value');
14
+ if(typeof value==='bigint') throw new Error('schema contains unsupported bigint JSON value');
15
+ if(typeof value!=='object') throw new Error(`schema contains unsupported JSON value type: ${typeof value}`);
16
+ if(seen.has(value)) throw new Error('schema contains circular JSON value');
17
+ seen.add(value);
18
+ try{
19
+ if(Array.isArray(value)){
20
+ const out=[];
21
+ for(let index=0;index<value.length;index+=1){
22
+ if(!Object.prototype.hasOwnProperty.call(value,index)) throw new Error('schema contains sparse JSON array');
23
+ out.push(canonicalValue(value[index],seen));
24
+ }
25
+ return out;
26
+ }
27
+ const proto=Object.getPrototypeOf(value);
28
+ if(proto!==Object.prototype&&proto!==null) throw new Error('schema contains unsupported non-plain JSON object');
29
+ const out={};
30
+ for(const key of Object.keys(value).sort((a,b)=>a.localeCompare(b,'en'))){
31
+ out[key]=canonicalValue(value[key],seen);
32
+ }
33
+ return out;
34
+ } finally {
35
+ seen.delete(value);
36
+ }
37
+ }
38
+
39
+ function canonicalJson(value){return JSON.stringify(canonicalValue(value));}
40
+ function sha256(value){return createHash('sha256').update(value,'utf8').digest('hex');}
41
+
42
+ export function canonicalSchemaHash(schema){return sha256(canonicalJson(schema));}
43
+
44
+ export function snapshotToolSurface(toolDescriptors){
45
+ if(!Array.isArray(toolDescriptors)) throw new Error('tool descriptors must be an array');
46
+ const names=new Set();
47
+ const tools=toolDescriptors.map(descriptor=>{
48
+ if(!descriptor||typeof descriptor!=='object'||Array.isArray(descriptor)) throw new Error('tool descriptor must be an object');
49
+ const name=descriptor.name;
50
+ if(typeof name!=='string'||name.length<1) throw new Error('tool descriptor name must be non-empty');
51
+ if(names.has(name)) throw new Error(`duplicate tool: ${name}`);
52
+ names.add(name);
53
+ return {
54
+ name,
55
+ input_sha256:canonicalSchemaHash(descriptor.inputSchema),
56
+ output_sha256:canonicalSchemaHash(descriptor.outputSchema)
57
+ };
58
+ }).sort((a,b)=>a.name.localeCompare(b.name,'en'));
59
+ const body={schema:SURFACE_SCHEMA,tools};
60
+ return {...body,surface_sha256:sha256(canonicalJson(body))};
61
+ }
62
+
63
+ export function snapshotToolsListResult(result){
64
+ if(!result||typeof result!=='object'||!Array.isArray(result.tools)) throw new Error('MCP tools/list result tools must be an array');
65
+ return snapshotToolSurface(result.tools.map(tool=>{
66
+ if(!tool||typeof tool!=='object'||Array.isArray(tool)) throw new Error('MCP tools/list tool must be an object');
67
+ if(!tool.inputSchema||typeof tool.inputSchema!=='object'||Array.isArray(tool.inputSchema)) throw new Error(`tool ${tool.name??'<unknown>'} missing inputSchema`);
68
+ if(!tool.outputSchema||typeof tool.outputSchema!=='object'||Array.isArray(tool.outputSchema)) throw new Error(`tool ${tool.name??'<unknown>'} missing outputSchema`);
69
+ return {name:tool.name,inputSchema:tool.inputSchema,outputSchema:tool.outputSchema};
70
+ }));
71
+ }
72
+
73
+ function assertSnapshot(snapshot,label){
74
+ if(!snapshot||snapshot.schema!==SURFACE_SCHEMA||!Array.isArray(snapshot.tools)) throw new Error(`${label} tool surface snapshot invalid`);
75
+ }
76
+
77
+ export function diffToolSurface(baseline,current){
78
+ assertSnapshot(baseline,'baseline'); assertSnapshot(current,'current');
79
+ const before=new Map(baseline.tools.map(tool=>[tool.name,tool]));
80
+ const after=new Map(current.tools.map(tool=>[tool.name,tool]));
81
+ const unchanged=[]; const added=[]; const removed=[]; const schemaChanged=[];
82
+ for(const name of [...new Set([...before.keys(),...after.keys()])].sort((a,b)=>a.localeCompare(b,'en'))){
83
+ const left=before.get(name); const right=after.get(name);
84
+ if(!left){added.push(name);continue;}
85
+ if(!right){removed.push(name);continue;}
86
+ if(left.input_sha256===right.input_sha256&&left.output_sha256===right.output_sha256) unchanged.push(name);
87
+ else schemaChanged.push(name);
88
+ }
89
+ return {unchanged,added,removed,schema_changed:schemaChanged};
90
+ }
91
+
92
+ export const TOOL_SURFACE_SCHEMA=SURFACE_SCHEMA;
package/src/version.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export const DEADBYTE_VERSION = '0.8.9';
1
+ export const DEADBYTE_VERSION = '0.9.0';
2
2
  export const MCP_PROTOCOL_VERSION = '2026-07-28';
3
3
  export const RECEIPT_SCHEMA_V1 = 'deadbyte.receipt.v1';
4
4
  export const RECEIPT_SCHEMA_V2 = 'deadbyte.receipt.v2';
@@ -19,7 +19,7 @@ async function fixture(){
19
19
  }
20
20
  async function lines(file){return (await readFile(file,'utf8')).trim().split(/\r?\n/);}
21
21
 
22
- test('independent verifier accepts a clean signed multi-segment audit chain',async()=>{const f=await fixture();try{const result=await verifyAuditChain({stateRoot:f.root,verifyKeyPath:f.key.publicKeyPath});assert.equal(result.ok,true);assert.equal(result.event_count,4);assert.equal(result.request_count,2);assert.equal(result.result_count,2);assert.equal(result.segment_count,2);assert.equal(result.checkpoint_count,2);assert.equal(result.last_seq,4);assert.match(result.head_sha256,/^[0-9a-f]{64}$/);}finally{await rm(f.root,{recursive:true,force:true});}});
22
+ test('independent verifier accepts a clean signed multi-segment audit chain',async()=>{const f=await fixture();try{const result=await verifyAuditChain({stateRoot:f.root,verifyKeyPath:f.key.publicKeyPath});assert.equal(result.ok,true);assert.equal(result.event_count,4);assert.equal(result.request_count,2);assert.equal(result.result_count,2);assert.equal(result.segment_count,2);assert.equal(result.checkpoint_count,2);assert.equal(result.last_seq,4);assert.match(result.head_sha256,/^[0-9a-f]{64}$/);assert.deepEqual(result.tool_usage,[{tool:'one',requests:1,results:1,errors:0},{tool:'two',requests:1,results:1,errors:0}]);}finally{await rm(f.root,{recursive:true,force:true});}});
23
23
 
24
24
  test('verifier detects an edited event line',async()=>{const f=await fixture();try{const file=path.join(f.root,'audit','segment-00000001.jsonl');const row=await lines(file);const first=JSON.parse(row[0]);first.tool='tampered';row[0]=JSON.stringify(first);await writeFile(file,row.join('\n')+'\n');const result=await verifyAuditChain({stateRoot:f.root,verifyKeyPath:f.key.publicKeyPath});assert.equal(result.ok,false);assert.match(result.reason,/event hash mismatch/i);}finally{await rm(f.root,{recursive:true,force:true});}});
25
25
 
@@ -0,0 +1,106 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { actionIdentity, reconcileStartedAction } from '../src/autonomous-action-reconcile.mjs';
4
+
5
+ const H = c => c.repeat(64);
6
+
7
+ const identityInput = {
8
+ goalId:H('1'),
9
+ planId:H('2'),
10
+ planVersion:3,
11
+ stepId:'fix',
12
+ mutationEpoch:4,
13
+ decisionEventSha:H('5'),
14
+ action:{kind:'patch',operations:[{kind:'replace',path:'x.txt',expected_sha256:H('6'),old_string:'x',new_string:'y',expected_replacements:1}]}
15
+ };
16
+
17
+ test('action identity is deterministic and changes when plan version changes', () => {
18
+ const a = actionIdentity(identityInput);
19
+ const b = actionIdentity(structuredClone(identityInput));
20
+ assert.deepEqual(a,b);
21
+ assert.match(a.action_id,/^[0-9a-f]{64}$/);
22
+ assert.match(a.request_sha256,/^[0-9a-f]{64}$/);
23
+ const changed = actionIdentity({...identityInput,planVersion:4});
24
+ assert.notEqual(changed.action_id,a.action_id);
25
+ assert.notEqual(changed.request_sha256,a.request_sha256);
26
+ });
27
+
28
+ function patchStarted() {
29
+ return {
30
+ type:'action_started',event_sha256:H('7'),payload:{
31
+ action_id:H('8'),request_sha256:H('9'),
32
+ action:{kind:'patch',diff_id:H('a')}
33
+ }
34
+ };
35
+ }
36
+
37
+ test('verified mutation receipt classifies as executed without replay', async () => {
38
+ const result = await reconcileStartedAction({
39
+ startedEvent:patchStarted(),journal:[],
40
+ runtimes:{nativeDiffRuntime:{async verify({diffId}){
41
+ assert.equal(diffId,H('a'));
42
+ return {ok:true,current_state_matches:true,receipt_sha256:H('b'),journal_head_sha256:H('c')};
43
+ }}}
44
+ });
45
+ assert.equal(result.classification,'executed_verified');
46
+ assert.equal(result.replay_allowed,false);
47
+ assert.equal(result.evidence.receipt_sha256,H('b'));
48
+ });
49
+
50
+ test('missing mutation evidence is not executed and may retry with the same identity', async () => {
51
+ const result = await reconcileStartedAction({
52
+ startedEvent:patchStarted(),journal:[],
53
+ runtimes:{nativeDiffRuntime:{async verify(){return {ok:false,reason:'native diff receipt missing'};}}}
54
+ });
55
+ assert.equal(result.classification,'not_executed');
56
+ assert.equal(result.replay_allowed,true);
57
+ });
58
+
59
+ test('conflicting or unverifiable mutation evidence is ambiguous and never replayed', async () => {
60
+ const badSignature = await reconcileStartedAction({
61
+ startedEvent:patchStarted(),journal:[],
62
+ runtimes:{nativeDiffRuntime:{async verify(){return {ok:false,reason:'receipt signature mismatch'};}}}
63
+ });
64
+ assert.equal(badSignature.classification,'ambiguous');
65
+ assert.equal(badSignature.replay_allowed,false);
66
+
67
+ const staleState = await reconcileStartedAction({
68
+ startedEvent:patchStarted(),journal:[],
69
+ runtimes:{nativeDiffRuntime:{async verify(){return {ok:true,current_state_matches:false,receipt_sha256:H('b')};}}}
70
+ });
71
+ assert.equal(staleState.classification,'ambiguous');
72
+ assert.equal(staleState.replay_allowed,false);
73
+ });
74
+
75
+ test('verified profile failure is recovered as executed_failed_verified', async () => {
76
+ const started = {type:'action_started',event_sha256:H('1'),payload:{
77
+ action_id:H('2'),request_sha256:H('3'),
78
+ action:{kind:'profile',receipt_id:'a'.repeat(24),expect_exit_code:0}
79
+ }};
80
+ const result = await reconcileStartedAction({
81
+ startedEvent:started,journal:[],
82
+ runtimes:{codingRuntime:{async verifyReceiptDetailed(receiptId){
83
+ assert.equal(receiptId,'a'.repeat(24));
84
+ return {ok:true,request_sha256:H('3'),receipt_sha256:H('4'),receipt:{receipt_id:receiptId,operation:'coding_command_run',exit_code:1,timed_out:false}};
85
+ }}}
86
+ });
87
+ assert.equal(result.classification,'executed_failed_verified');
88
+ assert.equal(result.replay_allowed,false);
89
+ assert.equal(result.evidence.receipt_sha256,H('4'));
90
+ });
91
+
92
+ test('receipt substitution or stale request identity is ambiguous', async () => {
93
+ const started = {type:'action_started',event_sha256:H('1'),payload:{
94
+ action_id:H('2'),request_sha256:H('3'),
95
+ action:{kind:'profile',receipt_id:'a'.repeat(24),expect_exit_code:0}
96
+ }};
97
+ const result = await reconcileStartedAction({
98
+ startedEvent:started,journal:[],
99
+ runtimes:{codingRuntime:{async verifyReceiptDetailed(){
100
+ return {ok:true,request_sha256:H('f'),receipt_sha256:H('4'),receipt:{receipt_id:'a'.repeat(24),operation:'coding_command_run',exit_code:0,timed_out:false}};
101
+ }}}
102
+ });
103
+ assert.equal(result.classification,'ambiguous');
104
+ assert.match(result.reason,/request/i);
105
+ assert.equal(result.replay_allowed,false);
106
+ });