@nhtio/adk 0.1.0-master-2a4e1bd2 → 0.1.0-master-cd595e6f

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 (413) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/artifact_methods-CJDQ5Lv-.mjs +1 -0
  3. package/artifact_methods-D6k_82r3.js +1 -0
  4. package/batteries/artifacts/ecmascript.cjs +1 -1
  5. package/batteries/artifacts/ecmascript.mjs +1 -1
  6. package/batteries/artifacts/toon.cjs +1 -1
  7. package/batteries/artifacts/toon.mjs +1 -1
  8. package/batteries/artifacts/xml.cjs +1 -1
  9. package/batteries/artifacts/xml.mjs +1 -1
  10. package/batteries/artifacts/yaml.cjs +1 -1
  11. package/batteries/artifacts/yaml.mjs +1 -1
  12. package/batteries/artifacts.cjs +4 -4
  13. package/batteries/artifacts.mjs +4 -4
  14. package/batteries/dev-tools/forge.cjs +3 -3
  15. package/batteries/dev-tools/forge.mjs +3 -3
  16. package/batteries/dev-tools.cjs +2 -2
  17. package/batteries/dev-tools.mjs +2 -2
  18. package/batteries/encoding.cjs +7 -7
  19. package/batteries/encoding.mjs +7 -7
  20. package/batteries/generation/gemini/adapter.cjs +1 -1
  21. package/batteries/generation/gemini/adapter.mjs +1 -1
  22. package/batteries/generation/local_diffusion/adapter.cjs +1 -1
  23. package/batteries/generation/local_diffusion/adapter.mjs +1 -1
  24. package/batteries/generation/openai/adapter.cjs +1 -1
  25. package/batteries/generation/openai/adapter.mjs +1 -1
  26. package/batteries/isolation/browser.d.ts +1 -1
  27. package/batteries/isolation/child_process/transport.d.ts +2 -2
  28. package/batteries/isolation/child_process.cjs +4 -4
  29. package/batteries/isolation/child_process.cjs.map +1 -1
  30. package/batteries/isolation/child_process.mjs +4 -4
  31. package/batteries/isolation/child_process.mjs.map +1 -1
  32. package/batteries/isolation/codec.d.ts +2 -2
  33. package/batteries/isolation/crash_policy.d.ts +1 -1
  34. package/batteries/isolation/isolate_function.d.ts +2 -2
  35. package/batteries/isolation/protocol.d.ts +4 -4
  36. package/batteries/isolation/serve.d.ts +2 -2
  37. package/batteries/isolation/types.d.ts +4 -4
  38. package/batteries/isolation.cjs +1 -1
  39. package/batteries/isolation.mjs +1 -1
  40. package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
  41. package/batteries/llm/anthropic_messages/adapter.cjs.map +1 -1
  42. package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
  43. package/batteries/llm/anthropic_messages/adapter.mjs.map +1 -1
  44. package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
  45. package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
  46. package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
  47. package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
  48. package/batteries/llm/anthropic_messages/types.d.ts +2 -2
  49. package/batteries/llm/anthropic_messages/validation.cjs +3 -3
  50. package/batteries/llm/anthropic_messages/validation.cjs.map +1 -1
  51. package/batteries/llm/anthropic_messages/validation.mjs +3 -3
  52. package/batteries/llm/anthropic_messages/validation.mjs.map +1 -1
  53. package/batteries/llm/anthropic_messages.cjs +2 -2
  54. package/batteries/llm/anthropic_messages.mjs +2 -2
  55. package/batteries/llm/bedrock_converse/adapter.cjs +29 -7
  56. package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
  57. package/batteries/llm/bedrock_converse/adapter.mjs +30 -8
  58. package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
  59. package/batteries/llm/bedrock_converse/exceptions.cjs +3 -0
  60. package/batteries/llm/bedrock_converse/exceptions.cjs.map +1 -1
  61. package/batteries/llm/bedrock_converse/exceptions.d.ts +6 -0
  62. package/batteries/llm/bedrock_converse/exceptions.mjs +3 -1
  63. package/batteries/llm/bedrock_converse/exceptions.mjs.map +1 -1
  64. package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
  65. package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
  66. package/batteries/llm/bedrock_converse/types.d.ts +6 -2
  67. package/batteries/llm/bedrock_converse/validation.cjs +7 -1
  68. package/batteries/llm/bedrock_converse/validation.cjs.map +1 -1
  69. package/batteries/llm/bedrock_converse/validation.mjs +7 -1
  70. package/batteries/llm/bedrock_converse/validation.mjs.map +1 -1
  71. package/batteries/llm/bedrock_converse.cjs +2 -2
  72. package/batteries/llm/bedrock_converse.mjs +2 -2
  73. package/batteries/llm/claude_code_cli/adapter.cjs +6 -6
  74. package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
  75. package/batteries/llm/claude_code_cli/adapter.mjs +6 -6
  76. package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
  77. package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
  78. package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
  79. package/batteries/llm/claude_code_cli/types.d.ts +3 -2
  80. package/batteries/llm/claude_code_cli/validation.cjs +3 -3
  81. package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
  82. package/batteries/llm/claude_code_cli/validation.mjs +3 -3
  83. package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
  84. package/batteries/llm/claude_code_cli.cjs +1 -1
  85. package/batteries/llm/claude_code_cli.mjs +1 -1
  86. package/batteries/llm/gemini_generate_content/adapter.cjs +29 -7
  87. package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
  88. package/batteries/llm/gemini_generate_content/adapter.mjs +30 -8
  89. package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
  90. package/batteries/llm/gemini_generate_content/exceptions.cjs +3 -0
  91. package/batteries/llm/gemini_generate_content/exceptions.cjs.map +1 -1
  92. package/batteries/llm/gemini_generate_content/exceptions.d.ts +6 -0
  93. package/batteries/llm/gemini_generate_content/exceptions.mjs +3 -1
  94. package/batteries/llm/gemini_generate_content/exceptions.mjs.map +1 -1
  95. package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
  96. package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
  97. package/batteries/llm/gemini_generate_content/types.d.ts +7 -3
  98. package/batteries/llm/gemini_generate_content/validation.cjs +11 -2
  99. package/batteries/llm/gemini_generate_content/validation.cjs.map +1 -1
  100. package/batteries/llm/gemini_generate_content/validation.mjs +11 -2
  101. package/batteries/llm/gemini_generate_content/validation.mjs.map +1 -1
  102. package/batteries/llm/gemini_generate_content.cjs +1 -1
  103. package/batteries/llm/gemini_generate_content.mjs +1 -1
  104. package/batteries/llm/litert_lm/adapter.cjs +6 -6
  105. package/batteries/llm/litert_lm/adapter.cjs.map +1 -1
  106. package/batteries/llm/litert_lm/adapter.mjs +6 -6
  107. package/batteries/llm/litert_lm/adapter.mjs.map +1 -1
  108. package/batteries/llm/litert_lm/helpers.cjs +3 -3
  109. package/batteries/llm/litert_lm/helpers.mjs +3 -3
  110. package/batteries/llm/litert_lm/types.d.ts +2 -2
  111. package/batteries/llm/litert_lm/validation.cjs +3 -3
  112. package/batteries/llm/litert_lm/validation.cjs.map +1 -1
  113. package/batteries/llm/litert_lm/validation.mjs +3 -3
  114. package/batteries/llm/litert_lm/validation.mjs.map +1 -1
  115. package/batteries/llm/litert_lm.cjs +1 -1
  116. package/batteries/llm/litert_lm.mjs +1 -1
  117. package/batteries/llm/ollama/adapter.cjs +6 -6
  118. package/batteries/llm/ollama/adapter.cjs.map +1 -1
  119. package/batteries/llm/ollama/adapter.mjs +6 -6
  120. package/batteries/llm/ollama/adapter.mjs.map +1 -1
  121. package/batteries/llm/ollama/helpers.cjs +4 -4
  122. package/batteries/llm/ollama/helpers.mjs +4 -4
  123. package/batteries/llm/ollama/types.d.ts +2 -2
  124. package/batteries/llm/ollama/validation.cjs +3 -3
  125. package/batteries/llm/ollama/validation.cjs.map +1 -1
  126. package/batteries/llm/ollama/validation.mjs +3 -3
  127. package/batteries/llm/ollama/validation.mjs.map +1 -1
  128. package/batteries/llm/ollama.cjs +2 -2
  129. package/batteries/llm/ollama.mjs +2 -2
  130. package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
  131. package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
  132. package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
  133. package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
  134. package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
  135. package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
  136. package/batteries/llm/openai_chat_completions/types.d.ts +2 -2
  137. package/batteries/llm/openai_chat_completions/validation.cjs +3 -3
  138. package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
  139. package/batteries/llm/openai_chat_completions/validation.mjs +3 -3
  140. package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
  141. package/batteries/llm/openai_chat_completions.cjs +2 -2
  142. package/batteries/llm/openai_chat_completions.mjs +2 -2
  143. package/batteries/llm/openai_responses/adapter.cjs +6 -6
  144. package/batteries/llm/openai_responses/adapter.cjs.map +1 -1
  145. package/batteries/llm/openai_responses/adapter.mjs +6 -6
  146. package/batteries/llm/openai_responses/adapter.mjs.map +1 -1
  147. package/batteries/llm/openai_responses/helpers.cjs +3 -3
  148. package/batteries/llm/openai_responses/helpers.mjs +3 -3
  149. package/batteries/llm/openai_responses/types.d.ts +2 -2
  150. package/batteries/llm/openai_responses/validation.cjs +3 -3
  151. package/batteries/llm/openai_responses/validation.cjs.map +1 -1
  152. package/batteries/llm/openai_responses/validation.mjs +3 -3
  153. package/batteries/llm/openai_responses/validation.mjs.map +1 -1
  154. package/batteries/llm/openai_responses.cjs +2 -2
  155. package/batteries/llm/openai_responses.mjs +2 -2
  156. package/batteries/llm/transformers_js/adapter.cjs +6 -6
  157. package/batteries/llm/transformers_js/adapter.cjs.map +1 -1
  158. package/batteries/llm/transformers_js/adapter.mjs +6 -6
  159. package/batteries/llm/transformers_js/adapter.mjs.map +1 -1
  160. package/batteries/llm/transformers_js/helpers.cjs +3 -3
  161. package/batteries/llm/transformers_js/helpers.mjs +3 -3
  162. package/batteries/llm/transformers_js/types.d.ts +2 -2
  163. package/batteries/llm/transformers_js/validation.cjs +3 -3
  164. package/batteries/llm/transformers_js/validation.cjs.map +1 -1
  165. package/batteries/llm/transformers_js/validation.mjs +3 -3
  166. package/batteries/llm/transformers_js/validation.mjs.map +1 -1
  167. package/batteries/llm/transformers_js.cjs +1 -1
  168. package/batteries/llm/transformers_js.mjs +1 -1
  169. package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
  170. package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
  171. package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
  172. package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
  173. package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
  174. package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
  175. package/batteries/llm/webllm_chat_completions/validation.cjs +3 -3
  176. package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
  177. package/batteries/llm/webllm_chat_completions/validation.mjs +3 -3
  178. package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
  179. package/batteries/llm/webllm_chat_completions.cjs +2 -2
  180. package/batteries/llm/webllm_chat_completions.mjs +2 -2
  181. package/batteries/llm.cjs +2 -2
  182. package/batteries/llm.mjs +2 -2
  183. package/batteries/media/builder.d.ts +3 -0
  184. package/batteries/media/contracts.cjs.map +1 -1
  185. package/batteries/media/contracts.d.ts +40 -1
  186. package/batteries/media/contracts.mjs.map +1 -1
  187. package/batteries/media/engines/sharp.cjs +36 -2
  188. package/batteries/media/engines/sharp.cjs.map +1 -1
  189. package/batteries/media/engines/sharp.mjs +36 -2
  190. package/batteries/media/engines/sharp.mjs.map +1 -1
  191. package/batteries/media/forge.cjs +5 -5
  192. package/batteries/media/forge.mjs +5 -5
  193. package/batteries/media/index.d.ts +1 -1
  194. package/batteries/media/lint.cjs +3 -2
  195. package/batteries/media/lint.cjs.map +1 -1
  196. package/batteries/media/lint.mjs +3 -2
  197. package/batteries/media/lint.mjs.map +1 -1
  198. package/batteries/media.cjs +66 -2
  199. package/batteries/media.cjs.map +1 -1
  200. package/batteries/media.mjs +66 -2
  201. package/batteries/media.mjs.map +1 -1
  202. package/batteries/orchestration/conformance.cjs +123 -74
  203. package/batteries/orchestration/conformance.cjs.map +1 -1
  204. package/batteries/orchestration/conformance.d.ts +10 -8
  205. package/batteries/orchestration/conformance.mjs +54 -5
  206. package/batteries/orchestration/conformance.mjs.map +1 -1
  207. package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
  208. package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
  209. package/batteries/orchestration/executor.cjs +2 -2
  210. package/batteries/orchestration/executor.mjs +2 -2
  211. package/batteries/orchestration/forge.cjs +4 -4
  212. package/batteries/orchestration/forge.mjs +4 -4
  213. package/batteries/orchestration/validation.cjs +2 -2
  214. package/batteries/orchestration/validation.mjs +2 -2
  215. package/batteries/orchestration.cjs +4 -4
  216. package/batteries/orchestration.mjs +4 -4
  217. package/batteries/sandbox/contracts/policy_enforcer.d.ts +13 -1
  218. package/batteries/sandbox/js/compartment.d.ts +7 -2
  219. package/batteries/sandbox/js/exceptions.d.ts +4 -0
  220. package/batteries/sandbox/js/runner.d.ts +1 -1
  221. package/batteries/sandbox/js/service.d.ts +1 -1
  222. package/batteries/sandbox/js/ses_contracts.d.ts +4 -3
  223. package/batteries/sandbox/js.cjs +17 -8
  224. package/batteries/sandbox/js.cjs.map +1 -1
  225. package/batteries/sandbox/js.mjs +17 -9
  226. package/batteries/sandbox/js.mjs.map +1 -1
  227. package/batteries/sandbox/manager.d.ts +4 -3
  228. package/batteries/sandbox/node/srt_enforcer.d.ts +1 -1
  229. package/batteries/sandbox/node.cjs +36 -12
  230. package/batteries/sandbox/node.cjs.map +1 -1
  231. package/batteries/sandbox/node.mjs +36 -12
  232. package/batteries/sandbox/node.mjs.map +1 -1
  233. package/batteries/sandbox/tools.cjs +1 -1
  234. package/batteries/sandbox/tools.mjs +1 -1
  235. package/batteries/sandbox/types.d.ts +10 -1
  236. package/batteries/sandbox.cjs +27 -9
  237. package/batteries/sandbox.cjs.map +1 -1
  238. package/batteries/sandbox.mjs +28 -11
  239. package/batteries/sandbox.mjs.map +1 -1
  240. package/batteries/skills.cjs +9 -9
  241. package/batteries/skills.mjs +9 -9
  242. package/batteries/tools/_shared.cjs +1 -1
  243. package/batteries/tools/_shared.mjs +1 -1
  244. package/batteries/tools/color.cjs +2 -2
  245. package/batteries/tools/color.mjs +2 -2
  246. package/batteries/tools/comparison.cjs +2 -2
  247. package/batteries/tools/comparison.mjs +2 -2
  248. package/batteries/tools/data_structure.cjs +2 -2
  249. package/batteries/tools/data_structure.mjs +2 -2
  250. package/batteries/tools/datetime_extended.cjs +3 -3
  251. package/batteries/tools/datetime_extended.mjs +3 -3
  252. package/batteries/tools/datetime_math.cjs +3 -3
  253. package/batteries/tools/datetime_math.mjs +3 -3
  254. package/batteries/tools/encoding.cjs +2 -2
  255. package/batteries/tools/encoding.mjs +2 -2
  256. package/batteries/tools/formatting.cjs +2 -2
  257. package/batteries/tools/formatting.mjs +2 -2
  258. package/batteries/tools/geo_basics.cjs +2 -2
  259. package/batteries/tools/geo_basics.mjs +2 -2
  260. package/batteries/tools/math.cjs +2 -2
  261. package/batteries/tools/math.mjs +2 -2
  262. package/batteries/tools/memory.cjs +5 -5
  263. package/batteries/tools/memory.mjs +5 -5
  264. package/batteries/tools/parsing.cjs +3 -3
  265. package/batteries/tools/parsing.mjs +3 -3
  266. package/batteries/tools/retrievables.cjs +5 -5
  267. package/batteries/tools/retrievables.mjs +5 -5
  268. package/batteries/tools/scrapper.cjs +1 -1
  269. package/batteries/tools/scrapper.mjs +1 -1
  270. package/batteries/tools/searxng.cjs +1 -1
  271. package/batteries/tools/searxng.mjs +1 -1
  272. package/batteries/tools/standing_instructions.cjs +3 -3
  273. package/batteries/tools/standing_instructions.mjs +3 -3
  274. package/batteries/tools/statistics.cjs +3 -3
  275. package/batteries/tools/statistics.mjs +3 -3
  276. package/batteries/tools/string_processing.cjs +2 -2
  277. package/batteries/tools/string_processing.mjs +2 -2
  278. package/batteries/tools/structured_data.cjs +2 -2
  279. package/batteries/tools/structured_data.mjs +2 -2
  280. package/batteries/tools/text_analysis.cjs +3 -3
  281. package/batteries/tools/text_analysis.mjs +3 -3
  282. package/batteries/tools/text_comparison.cjs +2 -2
  283. package/batteries/tools/text_comparison.mjs +2 -2
  284. package/batteries/tools/time.cjs +3 -3
  285. package/batteries/tools/time.mjs +3 -3
  286. package/batteries/tools/unit_conversion.cjs +2 -2
  287. package/batteries/tools/unit_conversion.mjs +2 -2
  288. package/batteries/tools.cjs +2 -2
  289. package/batteries/tools.mjs +2 -2
  290. package/batteries/validation.cjs +5 -5
  291. package/batteries/validation.mjs +5 -5
  292. package/batteries/vector/conformance/index.d.ts +11 -16
  293. package/batteries/vector/conformance.cjs +107 -36
  294. package/batteries/vector/conformance.cjs.map +1 -1
  295. package/batteries/vector/conformance.mjs +84 -13
  296. package/batteries/vector/conformance.mjs.map +1 -1
  297. package/batteries/vector/retrievable.cjs +1 -1
  298. package/batteries/vector/retrievable.mjs +1 -1
  299. package/batteries.cjs +5 -5
  300. package/batteries.mjs +5 -5
  301. package/{chat_common-DbbIESdo.mjs → chat_common-CmKV5Dz4.mjs} +2 -2
  302. package/{chat_common-DbbIESdo.mjs.map → chat_common-CmKV5Dz4.mjs.map} +1 -1
  303. package/{chat_common-B3O3zz-i.js → chat_common-Dpan9moo.js} +2 -2
  304. package/{chat_common-B3O3zz-i.js.map → chat_common-Dpan9moo.js.map} +1 -1
  305. package/{common-v9Jo9M5k.mjs → common-BpdHIpQE.mjs} +7 -7
  306. package/{common-v9Jo9M5k.mjs.map → common-BpdHIpQE.mjs.map} +1 -1
  307. package/{common-BV3HGeLj.js → common-H44Ik9ou.js} +7 -7
  308. package/{common-BV3HGeLj.js.map → common-H44Ik9ou.js.map} +1 -1
  309. package/common.cjs +7 -7
  310. package/common.mjs +7 -7
  311. package/{dispatch_runner-CbNyqSMy.mjs → dispatch_runner-BZDXUe0G.mjs} +5 -5
  312. package/{dispatch_runner-CbNyqSMy.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
  313. package/{dispatch_runner-Bl3Xwebu.js → dispatch_runner-CKhm-scw.js} +5 -5
  314. package/{dispatch_runner-Bl3Xwebu.js.map → dispatch_runner-CKhm-scw.js.map} +1 -1
  315. package/dispatch_runner.cjs +1 -1
  316. package/dispatch_runner.mjs +1 -1
  317. package/{ecmascript-BSnvyY8T.js → ecmascript-CCtgamDh.js} +3 -3
  318. package/{ecmascript-BSnvyY8T.js.map → ecmascript-CCtgamDh.js.map} +1 -1
  319. package/{ecmascript-CZ7_YKfZ.mjs → ecmascript-DcmUQ9Jx.mjs} +3 -3
  320. package/{ecmascript-CZ7_YKfZ.mjs.map → ecmascript-DcmUQ9Jx.mjs.map} +1 -1
  321. package/eslint.cjs +1 -1
  322. package/eslint.mjs +1 -1
  323. package/exceptions.cjs +1 -1
  324. package/exceptions.mjs +1 -1
  325. package/forge.cjs +2 -2
  326. package/forge.mjs +2 -2
  327. package/guards.cjs +7 -7
  328. package/guards.mjs +7 -7
  329. package/{helpers-CDmLDBq5.mjs → helpers-BH7HTtkD.mjs} +3 -3
  330. package/{helpers-CDmLDBq5.mjs.map → helpers-BH7HTtkD.mjs.map} +1 -1
  331. package/{helpers-Tvvwpx1M.js → helpers-CEjjkXso.js} +3 -3
  332. package/{helpers-Tvvwpx1M.js.map → helpers-CEjjkXso.js.map} +1 -1
  333. package/index.cjs +10 -10
  334. package/index.mjs +10 -10
  335. package/{isolation-BQCTQYZ_.js → isolation-7Jrcucgc.js} +11 -11
  336. package/isolation-7Jrcucgc.js.map +1 -0
  337. package/{isolation-7xbkc12r.mjs → isolation-CO0NiK8R.mjs} +11 -11
  338. package/isolation-CO0NiK8R.mjs.map +1 -0
  339. package/lib/classes/tokenizable.d.ts +2 -3
  340. package/mcp/adk-docs-corpus.json +2 -2
  341. package/package.json +469 -469
  342. package/{retrievable-C5dXuDhD.js → retrievable-BTwjmPnl.js} +3 -3
  343. package/{retrievable-C5dXuDhD.js.map → retrievable-BTwjmPnl.js.map} +1 -1
  344. package/{retrievable-gl_TIHnX.mjs → retrievable-CXTAUuuv.mjs} +3 -3
  345. package/{retrievable-gl_TIHnX.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
  346. package/{scrapper-DD6-_2u-.js → scrapper-CJexXXK-.js} +4 -4
  347. package/{scrapper-DD6-_2u-.js.map → scrapper-CJexXXK-.js.map} +1 -1
  348. package/{scrapper-u_orpxIB.mjs → scrapper-DiQ5FfDL.mjs} +4 -4
  349. package/{scrapper-u_orpxIB.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
  350. package/{searxng-fVdJUCK2.mjs → searxng-BFTJ6rTE.mjs} +4 -4
  351. package/{searxng-fVdJUCK2.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
  352. package/{searxng-C7GK0Nrz.js → searxng-DzlGZG4V.js} +4 -4
  353. package/{searxng-C7GK0Nrz.js.map → searxng-DzlGZG4V.js.map} +1 -1
  354. package/server.json +2 -2
  355. package/skills/adk-assembly/SKILL.md +2 -2
  356. package/{spooled_artifact-DriNQRj7.js → spooled_artifact-BpcesRBv.js} +384 -384
  357. package/spooled_artifact-BpcesRBv.js.map +1 -0
  358. package/{spooled_artifact-BkueYJhR.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
  359. package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
  360. package/spooled_artifact.cjs +2 -2
  361. package/spooled_artifact.mjs +2 -2
  362. package/{spooled_markdown_artifact-CfHRZUkl.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
  363. package/{spooled_markdown_artifact-CfHRZUkl.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
  364. package/{spooled_markdown_artifact-C_VkCDhF.js → spooled_markdown_artifact-wJPnE8Ij.js} +3 -3
  365. package/{spooled_markdown_artifact-C_VkCDhF.js.map → spooled_markdown_artifact-wJPnE8Ij.js.map} +1 -1
  366. package/{thought-B8JAi3-W.mjs → thought-BE1KGEhV.mjs} +3 -3
  367. package/{thought-B8JAi3-W.mjs.map → thought-BE1KGEhV.mjs.map} +1 -1
  368. package/{thought--fRgOwTP.js → thought-bS7O9O5H.js} +3 -3
  369. package/{thought--fRgOwTP.js.map → thought-bS7O9O5H.js.map} +1 -1
  370. package/{tokenizable-CWW7iSrD.js → tokenizable-BMZuGWRd.js} +35 -29
  371. package/tokenizable-BMZuGWRd.js.map +1 -0
  372. package/{tokenizable-DLMP68ZV.mjs → tokenizable-VB4Av8GF.mjs} +36 -30
  373. package/tokenizable-VB4Av8GF.mjs.map +1 -0
  374. package/{tool_call-CPjyvkm4.mjs → tool_call-Cfaj-6zK.mjs} +4 -4
  375. package/{tool_call-CPjyvkm4.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
  376. package/{tool_call-DgqVwL5n.js → tool_call-Fs_Uh5wQ.js} +4 -4
  377. package/{tool_call-DgqVwL5n.js.map → tool_call-Fs_Uh5wQ.js.map} +1 -1
  378. package/{tools-BmLzkvNr.mjs → tools-B3_8C78Q.mjs} +6 -6
  379. package/{tools-BmLzkvNr.mjs.map → tools-B3_8C78Q.mjs.map} +1 -1
  380. package/{tools-DmcIe2Cb.js → tools-CqOcmHR8.js} +6 -6
  381. package/{tools-DmcIe2Cb.js.map → tools-CqOcmHR8.js.map} +1 -1
  382. package/{toon-BvTQsKdN.mjs → toon-BSlr88px.mjs} +5 -5
  383. package/{toon-BvTQsKdN.mjs.map → toon-BSlr88px.mjs.map} +1 -1
  384. package/{toon-B05eKx-q.js → toon-D71tkyI3.js} +5 -5
  385. package/{toon-B05eKx-q.js.map → toon-D71tkyI3.js.map} +1 -1
  386. package/{turn_runner-DEGCvfVZ.mjs → turn_runner-BHHD6h77.mjs} +5 -5
  387. package/{turn_runner-DEGCvfVZ.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
  388. package/{turn_runner-DT8TseR4.js → turn_runner-DhLI7OTH.js} +5 -5
  389. package/{turn_runner-DT8TseR4.js.map → turn_runner-DhLI7OTH.js.map} +1 -1
  390. package/turn_runner.cjs +1 -1
  391. package/turn_runner.mjs +1 -1
  392. package/types-D6X_aUIb.mjs.map +1 -1
  393. package/types-DrSosVaM.js.map +1 -1
  394. package/{validate-lzy9nG_E.mjs → validate-Bi7FGjoq.mjs} +13 -1
  395. package/{validate-lzy9nG_E.mjs.map → validate-Bi7FGjoq.mjs.map} +1 -1
  396. package/{validate-CdOS7S2u.js → validate-CkQI-48O.js} +13 -1
  397. package/{validate-CdOS7S2u.js.map → validate-CkQI-48O.js.map} +1 -1
  398. package/{xml-DDTIMpY3.js → xml-BeNvlifb.js} +5 -5
  399. package/{xml-DDTIMpY3.js.map → xml-BeNvlifb.js.map} +1 -1
  400. package/{xml-VhJ4NrMB.mjs → xml-vyCZZiF_.mjs} +5 -5
  401. package/{xml-VhJ4NrMB.mjs.map → xml-vyCZZiF_.mjs.map} +1 -1
  402. package/{yaml-Cx16IYJq.js → yaml-DhLLa2cj.js} +5 -5
  403. package/{yaml-Cx16IYJq.js.map → yaml-DhLLa2cj.js.map} +1 -1
  404. package/{yaml-Du4wFGzL.mjs → yaml-Dtz0Bd7J.mjs} +5 -5
  405. package/{yaml-Du4wFGzL.mjs.map → yaml-Dtz0Bd7J.mjs.map} +1 -1
  406. package/artifact_methods-BMCahBLn.mjs +0 -1
  407. package/artifact_methods-f_bSy4kX.js +0 -1
  408. package/isolation-7xbkc12r.mjs.map +0 -1
  409. package/isolation-BQCTQYZ_.js.map +0 -1
  410. package/spooled_artifact-BkueYJhR.mjs.map +0 -1
  411. package/spooled_artifact-DriNQRj7.js.map +0 -1
  412. package/tokenizable-CWW7iSrD.js.map +0 -1
  413. package/tokenizable-DLMP68ZV.mjs.map +0 -1
@@ -6,18 +6,20 @@
6
6
  * against the {@link PlanStore} interface only — never against in-memory internals — so a passing
7
7
  * suite proves the backend honours the same contract the shipped reference implementation does.
8
8
  *
9
- * Public, deep-import-only (`@nhtio/adk/batteries/orchestration/conformance`). It imports
10
- * `vitest`, an optional peer you install to run the suite; it is never pulled in by the battery
11
- * barrel.
9
+ * Public, deep-import-only (`@nhtio/adk/batteries/orchestration/conformance`). The suite has no
10
+ * test-runner dependency: callers invoke and await it from any test framework.
12
11
  *
13
12
  * @module @nhtio/adk/batteries/orchestration/conformance
14
13
  */
15
14
  import type { PlanStore } from "./store";
16
15
  /**
17
- * Drive a plan store through the shared contract suite.
16
+ * Run the framework-free PlanStore conformance suite against a consumer implementation.
18
17
  *
19
- * @param label - A human label for the store under test, used in the suite title.
20
- * @param makeStore - A factory returning a FRESH store for each case, so no case shares state with
21
- * another. May be async.
18
+ * Each check creates a fresh store through `makeStore`, and the returned promise rejects when any
19
+ * contract assertion fails. Consumers can await this function from Vitest, node:test, Jest, Mocha,
20
+ * or another runner without importing a test framework from the conformance module.
21
+ *
22
+ * @param label - Human-readable name used to identify the implementation under test.
23
+ * @param makeStore - Factory returning a fresh PlanStore for each conformance check; it may be async.
22
24
  */
23
- export declare const runPlanStoreConformance: (label: string, makeStore: () => PlanStore | Promise<PlanStore>) => void;
25
+ export declare const runPlanStoreConformance: (label: string, makeStore: () => PlanStore | Promise<PlanStore>) => Promise<void>;
@@ -1,7 +1,6 @@
1
1
  import { r as isObject } from "../../guards-BEpY7lBI.mjs";
2
2
  import "../../guards.mjs";
3
3
  import { foldOps } from "./ops.mjs";
4
- import { describe, expect, it } from "vitest";
5
4
  //#region src/batteries/orchestration/conformance.ts
6
5
  /**
7
6
  * The shared conformance suite for {@link PlanStore} backends.
@@ -11,9 +10,8 @@ import { describe, expect, it } from "vitest";
11
10
  * against the {@link PlanStore} interface only — never against in-memory internals — so a passing
12
11
  * suite proves the backend honours the same contract the shipped reference implementation does.
13
12
  *
14
- * Public, deep-import-only (`@nhtio/adk/batteries/orchestration/conformance`). It imports
15
- * `vitest`, an optional peer you install to run the suite; it is never pulled in by the battery
16
- * barrel.
13
+ * Public, deep-import-only (`@nhtio/adk/batteries/orchestration/conformance`). The suite has no
14
+ * test-runner dependency: callers invoke and await it from any test framework.
17
15
  *
18
16
  * @module @nhtio/adk/batteries/orchestration/conformance
19
17
  */
@@ -24,7 +22,57 @@ import { describe, expect, it } from "vitest";
24
22
  * @param makeStore - A factory returning a FRESH store for each case, so no case shares state with
25
23
  * another. May be async.
26
24
  */
27
- var runPlanStoreConformance = (label, makeStore) => {
25
+ var equal = (actual, expected) => {
26
+ if (actual === expected) return true;
27
+ if (actual === null || expected === null || typeof actual !== "object" || typeof expected !== "object") return false;
28
+ if (Array.isArray(actual) !== Array.isArray(expected)) return false;
29
+ const keysA = Object.keys(actual);
30
+ const keysB = Object.keys(expected);
31
+ if (keysA.length !== keysB.length) return false;
32
+ return keysA.every((k) => keysB.includes(k) && equal(actual[k], expected[k]));
33
+ };
34
+ var match = (actual, expected) => {
35
+ if (expected === null || typeof expected !== "object") return equal(actual, expected);
36
+ if (actual === null || typeof actual !== "object") return false;
37
+ return Object.entries(expected).every(([key, value]) => match(actual[key], value));
38
+ };
39
+ var expectValue = (actual) => ({
40
+ toBe: (expected) => assert(equal(actual, expected), "values were not equal"),
41
+ toEqual: (expected) => assert(equal(actual, expected), "values were not equal"),
42
+ toMatchObject: (expected) => assert(match(actual, expected), "value did not match expected object"),
43
+ toBeDefined: () => assert(actual !== void 0, "value was undefined"),
44
+ toBeUndefined: () => assert(actual === void 0, "value was defined"),
45
+ toHaveLength: (length) => assert(actual.length === length, "unexpected length"),
46
+ toBeGreaterThan: (value) => assert(actual > value, "value was not greater than expected"),
47
+ rejects: { toThrow: async () => {
48
+ try {
49
+ await actual;
50
+ } catch {
51
+ return;
52
+ }
53
+ throw new Error("expected promise to reject");
54
+ } }
55
+ });
56
+ var assert = (condition, message) => {
57
+ if (!condition) throw new Error(message);
58
+ };
59
+ /**
60
+ * Run the framework-free PlanStore conformance suite against a consumer implementation.
61
+ *
62
+ * Each check creates a fresh store through `makeStore`, and the returned promise rejects when any
63
+ * contract assertion fails. Consumers can await this function from Vitest, node:test, Jest, Mocha,
64
+ * or another runner without importing a test framework from the conformance module.
65
+ *
66
+ * @param label - Human-readable name used to identify the implementation under test.
67
+ * @param makeStore - Factory returning a fresh PlanStore for each conformance check; it may be async.
68
+ */
69
+ var runPlanStoreConformance = async (label, makeStore) => {
70
+ const pending = [];
71
+ const it = (_name, test) => {
72
+ pending.push(test);
73
+ };
74
+ const describe = (_name, suite) => suite();
75
+ const expect = expectValue;
28
76
  describe(`PlanStore conformance: ${label}`, () => {
29
77
  /** A minimal, well-shaped `entry` node for authoring ops. */
30
78
  const entryNode = (id) => ({
@@ -419,6 +467,7 @@ var runPlanStoreConformance = (label, makeStore) => {
419
467
  expect(isObject(entry)).toBe(true);
420
468
  });
421
469
  });
470
+ for (const fn of pending) await fn();
422
471
  };
423
472
  //#endregion
424
473
  export { runPlanStoreConformance };
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.mjs","names":[],"sources":["../../../src/batteries/orchestration/conformance.ts"],"sourcesContent":["/**\n * The shared conformance suite for {@link PlanStore} backends.\n *\n * A consumer who owns their own plan store imports {@link runPlanStoreConformance} and drives it\n * with a factory that mints a fresh store per case. Each case is a contract assertion written\n * against the {@link PlanStore} interface only — never against in-memory internals — so a passing\n * suite proves the backend honours the same contract the shipped reference implementation does.\n *\n * Public, deep-import-only (`@nhtio/adk/batteries/orchestration/conformance`). It imports\n * `vitest`, an optional peer you install to run the suite; it is never pulled in by the battery\n * barrel.\n *\n * @module @nhtio/adk/batteries/orchestration/conformance\n */\n\nimport { foldOps } from './ops'\nimport { isObject } from '@nhtio/adk/guards'\nimport { describe, expect, it } from 'vitest'\nimport type { PlanStore, TransitionRequest } from './store'\nimport type {\n ApprovalRecord,\n ArtifactTable,\n PlanOp,\n PlanNode,\n PendingFrame,\n RunEvent,\n SpooledArtifactLike,\n} from './types'\n\n/**\n * Drive a plan store through the shared contract suite.\n *\n * @param label - A human label for the store under test, used in the suite title.\n * @param makeStore - A factory returning a FRESH store for each case, so no case shares state with\n * another. May be async.\n */\nexport const runPlanStoreConformance = (\n label: string,\n makeStore: () => PlanStore | Promise<PlanStore>\n): void => {\n describe(`PlanStore conformance: ${label}`, () => {\n // ── helpers ────────────────────────────────────────────────────────────────\n /** A minimal, well-shaped `entry` node for authoring ops. */\n const entryNode = (id: string): PlanNode => ({\n id,\n kind: 'entry',\n definition: { input: [] },\n })\n\n /** An `add_node` op for the given node, with a unique identity. */\n const addNodeOp = (node: PlanNode, lamport: number): PlanOp => ({\n op: 'add_node',\n node,\n opId: `op-${lamport}`,\n actorId: 'conformance',\n lamport,\n at: '2024-01-01T00:00:00.000Z',\n })\n\n /** A valid approval record bound to a digest. */\n const approvalFor = (planId: string, digest: string): ApprovalRecord => ({\n planId,\n digest,\n authoritySet: [],\n decidedBy: 'conformance',\n decidedAt: '2024-01-01T00:00:00.000Z',\n disposition: 'approved',\n })\n\n /** Append a single node and return the resulting digest, asserting the append succeeded. */\n const appendNode = async (\n store: PlanStore,\n planId: string,\n node: PlanNode,\n lamport: number\n ) => {\n const result = await store.appendOps(planId, [addNodeOp(node, lamport)])\n expect(result).toMatchObject({ ok: true })\n return (result as { digest: string }).digest\n }\n\n /** Drive a plan to `executable` at the digest of a single authored node, and return that digest. */\n const makeExecutable = async (store: PlanStore, planId: string) => {\n const digest = await appendNode(store, planId, entryNode('entry'), 1)\n await store.transition(planId, { from: 'editable', to: 'reviewable', expectedDigest: digest })\n await store.transition(planId, {\n from: 'reviewable',\n to: 'executable',\n expectedDigest: digest,\n approval: approvalFor(planId, digest),\n })\n return digest\n }\n\n // ── 1. genesis ─────────────────────────────────────────────────────────────\n it('createPlan mints editable at revision 0 with an empty op log and a non-empty digest', async () => {\n const store = await makeStore()\n const created = await store.createPlan('p1')\n expect(created).toMatchObject({ ok: true, revision: 0 })\n const state = await store.readState('p1')\n expect(state.state).toBe('editable')\n expect(state.revision).toBe(0)\n expect(state.digest.length).toBeGreaterThan(0)\n expect(await store.readOps('p1')).toEqual([])\n\n const appended = await store.appendOps('p1', [addNodeOp(entryNode('entry'), 1)])\n expect(appended).toMatchObject({ ok: true, revision: 1 })\n })\n\n // ── 2. duplicate id ────────────────────────────────────────────────────────\n it('createPlan refuses a duplicate id with reason duplicate_id', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const dup = await store.createPlan('p1')\n expect(dup).toMatchObject({ ok: false, reason: 'duplicate_id' })\n })\n\n // ── 3. appendOps refused in reviewable ────────────────────────────────────\n it('appendOps is refused in reviewable with reason not_editable and the real state', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: d1 })\n\n const result = await store.appendOps('p1', [addNodeOp(entryNode('entry2'), 2)])\n expect(result).toMatchObject({\n ok: false,\n reason: 'not_editable',\n actual: { state: 'reviewable' },\n })\n })\n\n // ── 4. appendOps refused in executable, digest unchanged ─────────────────\n it('appendOps is refused in executable with not_editable and leaves the digest unchanged', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n\n const result = await store.appendOps('p1', [addNodeOp(entryNode('entry2'), 2)])\n expect(result).toMatchObject({\n ok: false,\n reason: 'not_editable',\n actual: { state: 'executable' },\n })\n const state = await store.readState('p1')\n expect(state.digest).toBe(d1)\n })\n\n // ── 5. stale expectedRevision ─────────────────────────────────────────────\n it('appendOps with a stale expectedRevision returns revision_moved', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n await appendNode(store, 'p1', entryNode('entry'), 1)\n const result = await store.appendOps('p1', [addNodeOp(entryNode('entry2'), 2)], 0)\n expect(result).toMatchObject({ ok: false, reason: 'revision_moved' })\n })\n\n // ── 6. stale-approval interleaving ────────────────────────────────────────\n it('a transition gated on a stale digest is refused with digest_mismatch and leaves the plan reviewable', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: d1 })\n\n // Unfreeze, append, refreeze — the plan now sits at a NEW digest D2.\n await store.transition('p1', { from: 'reviewable', to: 'editable', expectedDigest: d1 })\n const d2 = await appendNode(store, 'p1', entryNode('entry2'), 2)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: d2 })\n\n // Gate with the STALE digest D1 — must be refused, not silently approved.\n const gate = await store.transition('p1', {\n from: 'reviewable',\n to: 'executable',\n expectedDigest: d1,\n approval: approvalFor('p1', d1),\n })\n expect(gate).toMatchObject({ ok: false, reason: 'digest_mismatch' })\n\n const state = await store.readState('p1')\n expect(state.state).toBe('reviewable')\n expect(await store.readApproval('p1')).toBeUndefined()\n })\n\n // ── 7. approval persists in the same commit ───────────────────────────────\n it('a successful gate persists the approval bound to the gated digest', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: d1 })\n const gate = await store.transition('p1', {\n from: 'reviewable',\n to: 'executable',\n expectedDigest: d1,\n approval: approvalFor('p1', d1),\n })\n expect(gate).toMatchObject({ ok: true })\n const approval = await store.readApproval('p1')\n expect(approval?.digest).toBe(d1)\n })\n\n // ── 8. illegal transition pair ────────────────────────────────────────────\n it('an illegal transition pair is answered with ok:false and reason illegal_transition, not thrown', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n await makeExecutable(store, 'p1')\n\n // Pass the plan's REAL current digest so state and digest can never be the reason —\n // only the illegal pair (executable -> editable) can be. This isolates the legality\n // check from the store's state/digest-first ordering.\n const { digest } = await store.readState('p1')\n\n // A BYO store may receive a request the type system did not police (e.g. over a wire).\n const request = {\n from: 'executable',\n to: 'editable',\n expectedDigest: digest,\n } as unknown as TransitionRequest\n const result = await store.transition('p1', request)\n expect(result).toMatchObject({ ok: false, reason: 'illegal_transition' })\n })\n\n // ── 8b. stale digest on a legal pair ───────────────────────────────────────\n it('a well-formed pair with a stale digest is refused with digest_mismatch', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n // Drive the plan to `reviewable`, so that `reviewable -> executable` below is a LEGAL pair\n // and the digest is the only thing wrong with the request.\n const digest = await appendNode(store, 'p1', entryNode('entry'), 1)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: digest })\n\n // A legal pair gated on a bogus digest must be refused with digest_mismatch — the check the\n // store performs before it considers applying the pair.\n const result = await store.transition('p1', {\n from: 'reviewable',\n to: 'executable',\n expectedDigest: 'stale',\n approval: approvalFor('p1', 'stale'),\n })\n expect(result).toMatchObject({ ok: false, reason: 'digest_mismatch' })\n\n // The refusal left the plan untouched: still reviewable, still at its real digest.\n const state = await store.readState('p1')\n expect(state.state).toBe('reviewable')\n expect(state.digest).toBe(digest)\n })\n\n // ── 9. claimRun exactly once ──────────────────────────────────────────────\n it('claimRun succeeds exactly once under concurrent claimants', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n\n const [a, b] = await Promise.all([store.claimRun('p1', d1), store.claimRun('p1', d1)])\n const winners = [a, b].filter((r) => r.ok === true)\n const losers = [a, b].filter((r) => r.ok === false)\n expect(winners).toHaveLength(1)\n expect(losers).toHaveLength(1)\n expect(losers[0]).toMatchObject({ ok: false, reason: 'run_already_claimed' })\n expect((losers[0] as { existingRunId?: string }).existingRunId).toBe(\n (winners[0] as { runId: string }).runId\n )\n })\n\n // ── 10. claimRun re-entry ─────────────────────────────────────────────────\n it('claimRun re-enters a run with resumeRunId, and refuses unknown or settled runs', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n\n const first = await store.claimRun('p1', d1)\n expect(first).toMatchObject({ ok: true, resumed: false })\n const runId = (first as { runId: string }).runId\n\n const resumed = await store.claimRun('p1', d1, runId)\n expect(resumed).toMatchObject({ ok: true, resumed: true })\n\n const unknown = await store.claimRun('p1', d1, 'no-such-run')\n expect(unknown).toMatchObject({ ok: false, reason: 'run_not_found' })\n\n await store.appendRunEvents('p1', runId, [\n { kind: 'run_settled', outcome: 'completed', at: '2024-01-01T00:00:00.000Z' },\n ])\n const settled = await store.claimRun('p1', d1, runId)\n expect(settled).toMatchObject({ ok: false, reason: 'run_already_settled' })\n })\n\n it('claimRun re-enters after an ABORTED or HALTED run, but not after a completed one', async () => {\n // `aborted` and `halted` are STOPPING POINTS, not endings. The interruption taxonomy\n // classifies a turn abort as resumable with the frontier intact at the same digest, so a\n // store that treats every `run_settled` as terminal makes `resumeRunId` unusable for\n // exactly the cases it exists to serve — which is what the reference store did, and what\n // this case would have caught.\n for (const outcome of ['aborted', 'halted'] as const) {\n const store = await makeStore()\n await store.createPlan(`resumable-${outcome}`)\n const digest = await makeExecutable(store, `resumable-${outcome}`)\n\n const started = await store.claimRun(`resumable-${outcome}`, digest)\n const runId = (started as { runId: string }).runId\n await store.appendRunEvents(`resumable-${outcome}`, runId, [\n {\n kind: 'run_interrupted',\n cause: { kind: 'turn_abort' },\n at: '2024-01-01T00:00:00.000Z',\n },\n { kind: 'run_settled', outcome, at: '2024-01-01T00:00:00.000Z' },\n ])\n\n const again = await store.claimRun(`resumable-${outcome}`, digest, runId)\n expect(again).toMatchObject({ ok: true, resumed: true })\n }\n })\n\n it('a CLONED plan can be frozen — every state fold carries provenance', async () => {\n // A clone carries `PlanProvenance`, and provenance is DIGESTED. So a store whose\n // `transition`/`readState` folds omit it computes a different digest than `freezePlan`\n // does, the `expectedDigest` check fails, and the clone can never leave `editable`.\n //\n // That breaks the documented recovery path outright: `clonePlan` is what you do after a\n // halting failure, and a clone that cannot be frozen cannot be re-approved or re-run. The\n // reference store had exactly this bug — five folds omitted `record.provenance` while\n // `readProvenance` supplied it everywhere else.\n const store = await makeStore()\n await store.createPlan('conf-clone-src')\n await store.appendOps('conf-clone-src', [addNodeOp(entryNode('entry'), 1)])\n\n const cloned = await store.clonePlan('conf-clone-src', 'conf-clone-dst')\n expect(cloned).toMatchObject({ ok: true })\n\n const provenance = await store.readProvenance('conf-clone-dst')\n expect(provenance).toBeDefined()\n\n // The digest the store reports must be the one a provenance-aware fold produces — that is\n // what `freezePlan` computes and passes as `expectedDigest`.\n const ops = await store.readOps('conf-clone-dst')\n const expected = foldOps('conf-clone-dst', ops, provenance).view.digest\n const state = await store.readState('conf-clone-dst')\n expect(state.digest).toBe(expected)\n\n // And the transition must actually commit at that digest.\n const moved = await store.transition('conf-clone-dst', {\n from: 'editable',\n to: 'reviewable',\n expectedDigest: expected,\n })\n expect(moved).toMatchObject({ ok: true })\n })\n\n // ── 11. claimRun preconditions ────────────────────────────────────────────\n it('claimRun is refused with not_executable when not executable and digest_mismatch when the digest moved', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n\n const notExecutable = await store.claimRun('p1', d1)\n expect(notExecutable).toMatchObject({ ok: false, reason: 'not_executable' })\n\n await makeExecutable(store, 'p1')\n const moved = await store.claimRun('p1', 'stale-digest')\n expect(moved).toMatchObject({ ok: false, reason: 'digest_mismatch' })\n })\n\n // ── 12. appendRunEvents is one batch ─────────────────────────────────────\n it('appendRunEvents commits its array as one batch so all three events are read back', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n const claimed = await store.claimRun('p1', d1)\n const runId = (claimed as { runId: string }).runId\n\n // The commit protocol depends on node_settled + every edge_taken + the new\n // frontier_snapshot landing in a SINGLE commit — a store that commits them one at a time\n // and could interleave is non-conforming.\n const batch: RunEvent[] = [\n { kind: 'run_started', runId, digest: d1, at: '2024-01-01T00:00:00.000Z' },\n {\n kind: 'node_entered',\n frame: {\n nodeId: 'entry',\n kind: 'entry',\n branchId: { segments: [] },\n viaEdgeId: undefined,\n },\n at: '2024-01-01T00:00:00.000Z',\n },\n {\n kind: 'node_settled',\n frame: {\n nodeId: 'entry',\n kind: 'entry',\n branchId: { segments: [] },\n viaEdgeId: undefined,\n },\n outcome: {\n status: 'ok',\n output: { items: [{ json: { ok: true } }], branchId: { segments: [] } },\n },\n at: '2024-01-01T00:00:00.000Z',\n },\n ]\n await store.appendRunEvents('p1', runId, batch)\n const events = await store.readRunEvents('p1', runId)\n expect(events).toHaveLength(3)\n expect(events.map((e) => e.kind)).toEqual(['run_started', 'node_entered', 'node_settled'])\n })\n\n // ── 13. readOps revision prefix ───────────────────────────────────────────\n it('readOps throughRevision serves a revision prefix and rejects a revision the log never reached', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n await appendNode(store, 'p1', entryNode('entry'), 1)\n await appendNode(store, 'p1', entryNode('entry2'), 2)\n\n const prefix = await store.readOps('p1', { throughRevision: 1 })\n expect(prefix).toHaveLength(1)\n expect(prefix[0].opId).toBe('op-1')\n\n await expect(store.readOps('p1', { throughRevision: 99 })).rejects.toThrow()\n })\n\n // ── 14. clonePlan ─────────────────────────────────────────────────────────\n it('clonePlan yields an editable, unapproved, run-less clone with parent provenance', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n\n const cloned = await store.clonePlan('p1', 'p2')\n expect(cloned).toMatchObject({ ok: true })\n\n const state = await store.readState('p2')\n expect(state.state).toBe('editable')\n expect(await store.readApproval('p2')).toBeUndefined()\n await expect(store.readRunEvents('p2')).rejects.toThrow()\n\n const provenance = await store.readProvenance('p2')\n expect(provenance).toMatchObject({\n kind: 'clone',\n parent: 'p1',\n parentDigest: d1,\n parentRevision: 1,\n })\n\n const missing = await store.clonePlan('no-such', 'p3')\n expect(missing).toMatchObject({ ok: false, reason: 'source_missing' })\n })\n\n // ── 15. frontier_snapshot artifact handles round-trip ────────────────────\n it('a round-tripped frontier_snapshot preserves artifact handles', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n const claimed = await store.claimRun('p1', d1)\n const runId = (claimed as { runId: string }).runId\n\n // A handle is a pointer, never bytes — the encoding is the store's business, so we assert\n // the PROPERTY (the entry survives the round-trip) rather than any representation.\n const artifact: SpooledArtifactLike = {\n constructor: { toolMethods: [] },\n marker: 'handle',\n }\n const artifacts: ArtifactTable = new Map([['entry:root', artifact]])\n const frame: PendingFrame = {\n frame: {\n nodeId: 'entry',\n kind: 'entry',\n branchId: { segments: [] },\n viaEdgeId: undefined,\n },\n outputs: new Map(),\n artifacts,\n }\n const snapshot: RunEvent = {\n kind: 'frontier_snapshot',\n frames: [frame],\n joins: [],\n at: '2024-01-01T00:00:00.000Z',\n }\n await store.appendRunEvents('p1', runId, [snapshot])\n\n const events = await store.readRunEvents('p1', runId)\n const readBack = events.find((e) => e.kind === 'frontier_snapshot')\n expect(readBack).toBeDefined()\n const readFrame = (readBack as { frames: PendingFrame[] }).frames[0]\n const entry = readFrame.artifacts.get('entry:root')\n expect(entry).toBeDefined()\n expect(isObject(entry)).toBe(true)\n })\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"conformance.mjs","names":[],"sources":["../../../src/batteries/orchestration/conformance.ts"],"sourcesContent":["/**\n * The shared conformance suite for {@link PlanStore} backends.\n *\n * A consumer who owns their own plan store imports {@link runPlanStoreConformance} and drives it\n * with a factory that mints a fresh store per case. Each case is a contract assertion written\n * against the {@link PlanStore} interface only — never against in-memory internals — so a passing\n * suite proves the backend honours the same contract the shipped reference implementation does.\n *\n * Public, deep-import-only (`@nhtio/adk/batteries/orchestration/conformance`). The suite has no\n * test-runner dependency: callers invoke and await it from any test framework.\n *\n * @module @nhtio/adk/batteries/orchestration/conformance\n */\n\nimport { foldOps } from './ops'\nimport { isObject } from '@nhtio/adk/guards'\nimport type { PlanStore, TransitionRequest } from './store'\nimport type {\n ApprovalRecord,\n ArtifactTable,\n PlanOp,\n PlanNode,\n PendingFrame,\n RunEvent,\n SpooledArtifactLike,\n} from './types'\n\n/**\n * Drive a plan store through the shared contract suite.\n *\n * @param label - A human label for the store under test, used in the suite title.\n * @param makeStore - A factory returning a FRESH store for each case, so no case shares state with\n * another. May be async.\n */\nconst equal = (actual: unknown, expected: unknown): boolean => {\n if (actual === expected) return true\n if (\n actual === null ||\n expected === null ||\n typeof actual !== 'object' ||\n typeof expected !== 'object'\n )\n return false\n if (Array.isArray(actual) !== Array.isArray(expected)) return false\n const keysA = Object.keys(actual)\n const keysB = Object.keys(expected)\n if (keysA.length !== keysB.length) return false\n return keysA.every((k) => keysB.includes(k) && equal((actual as any)[k], (expected as any)[k]))\n}\nconst match = (actual: unknown, expected: unknown): boolean => {\n if (expected === null || typeof expected !== 'object') return equal(actual, expected)\n if (actual === null || typeof actual !== 'object') return false\n return Object.entries(expected).every(([key, value]) =>\n match((actual as Record<string, unknown>)[key], value)\n )\n}\nconst expectValue = (actual: unknown) => ({\n toBe: (expected: unknown) => assert(equal(actual, expected), 'values were not equal'),\n toEqual: (expected: unknown) => assert(equal(actual, expected), 'values were not equal'),\n toMatchObject: (expected: unknown) =>\n assert(match(actual, expected), 'value did not match expected object'),\n toBeDefined: () => assert(actual !== undefined, 'value was undefined'),\n toBeUndefined: () => assert(actual === undefined, 'value was defined'),\n toHaveLength: (length: number) =>\n assert((actual as { length: number }).length === length, 'unexpected length'),\n toBeGreaterThan: (value: number) =>\n assert((actual as number) > value, 'value was not greater than expected'),\n rejects: {\n toThrow: async () => {\n try {\n await (actual as Promise<unknown>)\n } catch {\n return\n }\n throw new Error('expected promise to reject')\n },\n },\n})\nconst assert: (condition: boolean, message: string) => asserts condition = (condition, message) => {\n if (!condition) throw new Error(message)\n}\n\n/**\n * Run the framework-free PlanStore conformance suite against a consumer implementation.\n *\n * Each check creates a fresh store through `makeStore`, and the returned promise rejects when any\n * contract assertion fails. Consumers can await this function from Vitest, node:test, Jest, Mocha,\n * or another runner without importing a test framework from the conformance module.\n *\n * @param label - Human-readable name used to identify the implementation under test.\n * @param makeStore - Factory returning a fresh PlanStore for each conformance check; it may be async.\n */\nexport const runPlanStoreConformance = async (\n label: string,\n makeStore: () => PlanStore | Promise<PlanStore>\n): Promise<void> => {\n const pending: Array<() => Promise<void>> = []\n const it = (_name: string, test: () => Promise<void>) => {\n pending.push(test)\n }\n const describe = (_name: string, suite: () => void) => suite()\n const expect = expectValue\n describe(`PlanStore conformance: ${label}`, () => {\n // ── helpers ────────────────────────────────────────────────────────────────\n /** A minimal, well-shaped `entry` node for authoring ops. */\n const entryNode = (id: string): PlanNode => ({\n id,\n kind: 'entry',\n definition: { input: [] },\n })\n\n /** An `add_node` op for the given node, with a unique identity. */\n const addNodeOp = (node: PlanNode, lamport: number): PlanOp => ({\n op: 'add_node',\n node,\n opId: `op-${lamport}`,\n actorId: 'conformance',\n lamport,\n at: '2024-01-01T00:00:00.000Z',\n })\n\n /** A valid approval record bound to a digest. */\n const approvalFor = (planId: string, digest: string): ApprovalRecord => ({\n planId,\n digest,\n authoritySet: [],\n decidedBy: 'conformance',\n decidedAt: '2024-01-01T00:00:00.000Z',\n disposition: 'approved',\n })\n\n /** Append a single node and return the resulting digest, asserting the append succeeded. */\n const appendNode = async (\n store: PlanStore,\n planId: string,\n node: PlanNode,\n lamport: number\n ) => {\n const result = await store.appendOps(planId, [addNodeOp(node, lamport)])\n expect(result).toMatchObject({ ok: true })\n return (result as { digest: string }).digest\n }\n\n /** Drive a plan to `executable` at the digest of a single authored node, and return that digest. */\n const makeExecutable = async (store: PlanStore, planId: string) => {\n const digest = await appendNode(store, planId, entryNode('entry'), 1)\n await store.transition(planId, { from: 'editable', to: 'reviewable', expectedDigest: digest })\n await store.transition(planId, {\n from: 'reviewable',\n to: 'executable',\n expectedDigest: digest,\n approval: approvalFor(planId, digest),\n })\n return digest\n }\n\n // ── 1. genesis ─────────────────────────────────────────────────────────────\n it('createPlan mints editable at revision 0 with an empty op log and a non-empty digest', async () => {\n const store = await makeStore()\n const created = await store.createPlan('p1')\n expect(created).toMatchObject({ ok: true, revision: 0 })\n const state = await store.readState('p1')\n expect(state.state).toBe('editable')\n expect(state.revision).toBe(0)\n expect(state.digest.length).toBeGreaterThan(0)\n expect(await store.readOps('p1')).toEqual([])\n\n const appended = await store.appendOps('p1', [addNodeOp(entryNode('entry'), 1)])\n expect(appended).toMatchObject({ ok: true, revision: 1 })\n })\n\n // ── 2. duplicate id ────────────────────────────────────────────────────────\n it('createPlan refuses a duplicate id with reason duplicate_id', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const dup = await store.createPlan('p1')\n expect(dup).toMatchObject({ ok: false, reason: 'duplicate_id' })\n })\n\n // ── 3. appendOps refused in reviewable ────────────────────────────────────\n it('appendOps is refused in reviewable with reason not_editable and the real state', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: d1 })\n\n const result = await store.appendOps('p1', [addNodeOp(entryNode('entry2'), 2)])\n expect(result).toMatchObject({\n ok: false,\n reason: 'not_editable',\n actual: { state: 'reviewable' },\n })\n })\n\n // ── 4. appendOps refused in executable, digest unchanged ─────────────────\n it('appendOps is refused in executable with not_editable and leaves the digest unchanged', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n\n const result = await store.appendOps('p1', [addNodeOp(entryNode('entry2'), 2)])\n expect(result).toMatchObject({\n ok: false,\n reason: 'not_editable',\n actual: { state: 'executable' },\n })\n const state = await store.readState('p1')\n expect(state.digest).toBe(d1)\n })\n\n // ── 5. stale expectedRevision ─────────────────────────────────────────────\n it('appendOps with a stale expectedRevision returns revision_moved', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n await appendNode(store, 'p1', entryNode('entry'), 1)\n const result = await store.appendOps('p1', [addNodeOp(entryNode('entry2'), 2)], 0)\n expect(result).toMatchObject({ ok: false, reason: 'revision_moved' })\n })\n\n // ── 6. stale-approval interleaving ────────────────────────────────────────\n it('a transition gated on a stale digest is refused with digest_mismatch and leaves the plan reviewable', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: d1 })\n\n // Unfreeze, append, refreeze — the plan now sits at a NEW digest D2.\n await store.transition('p1', { from: 'reviewable', to: 'editable', expectedDigest: d1 })\n const d2 = await appendNode(store, 'p1', entryNode('entry2'), 2)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: d2 })\n\n // Gate with the STALE digest D1 — must be refused, not silently approved.\n const gate = await store.transition('p1', {\n from: 'reviewable',\n to: 'executable',\n expectedDigest: d1,\n approval: approvalFor('p1', d1),\n })\n expect(gate).toMatchObject({ ok: false, reason: 'digest_mismatch' })\n\n const state = await store.readState('p1')\n expect(state.state).toBe('reviewable')\n expect(await store.readApproval('p1')).toBeUndefined()\n })\n\n // ── 7. approval persists in the same commit ───────────────────────────────\n it('a successful gate persists the approval bound to the gated digest', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: d1 })\n const gate = await store.transition('p1', {\n from: 'reviewable',\n to: 'executable',\n expectedDigest: d1,\n approval: approvalFor('p1', d1),\n })\n expect(gate).toMatchObject({ ok: true })\n const approval = await store.readApproval('p1')\n expect(approval?.digest).toBe(d1)\n })\n\n // ── 8. illegal transition pair ────────────────────────────────────────────\n it('an illegal transition pair is answered with ok:false and reason illegal_transition, not thrown', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n await makeExecutable(store, 'p1')\n\n // Pass the plan's REAL current digest so state and digest can never be the reason —\n // only the illegal pair (executable -> editable) can be. This isolates the legality\n // check from the store's state/digest-first ordering.\n const { digest } = await store.readState('p1')\n\n // A BYO store may receive a request the type system did not police (e.g. over a wire).\n const request = {\n from: 'executable',\n to: 'editable',\n expectedDigest: digest,\n } as unknown as TransitionRequest\n const result = await store.transition('p1', request)\n expect(result).toMatchObject({ ok: false, reason: 'illegal_transition' })\n })\n\n // ── 8b. stale digest on a legal pair ───────────────────────────────────────\n it('a well-formed pair with a stale digest is refused with digest_mismatch', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n // Drive the plan to `reviewable`, so that `reviewable -> executable` below is a LEGAL pair\n // and the digest is the only thing wrong with the request.\n const digest = await appendNode(store, 'p1', entryNode('entry'), 1)\n await store.transition('p1', { from: 'editable', to: 'reviewable', expectedDigest: digest })\n\n // A legal pair gated on a bogus digest must be refused with digest_mismatch — the check the\n // store performs before it considers applying the pair.\n const result = await store.transition('p1', {\n from: 'reviewable',\n to: 'executable',\n expectedDigest: 'stale',\n approval: approvalFor('p1', 'stale'),\n })\n expect(result).toMatchObject({ ok: false, reason: 'digest_mismatch' })\n\n // The refusal left the plan untouched: still reviewable, still at its real digest.\n const state = await store.readState('p1')\n expect(state.state).toBe('reviewable')\n expect(state.digest).toBe(digest)\n })\n\n // ── 9. claimRun exactly once ──────────────────────────────────────────────\n it('claimRun succeeds exactly once under concurrent claimants', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n\n const [a, b] = await Promise.all([store.claimRun('p1', d1), store.claimRun('p1', d1)])\n const winners = [a, b].filter((r) => r.ok === true)\n const losers = [a, b].filter((r) => r.ok === false)\n expect(winners).toHaveLength(1)\n expect(losers).toHaveLength(1)\n expect(losers[0]).toMatchObject({ ok: false, reason: 'run_already_claimed' })\n expect((losers[0] as { existingRunId?: string }).existingRunId).toBe(\n (winners[0] as { runId: string }).runId\n )\n })\n\n // ── 10. claimRun re-entry ─────────────────────────────────────────────────\n it('claimRun re-enters a run with resumeRunId, and refuses unknown or settled runs', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n\n const first = await store.claimRun('p1', d1)\n expect(first).toMatchObject({ ok: true, resumed: false })\n const runId = (first as { runId: string }).runId\n\n const resumed = await store.claimRun('p1', d1, runId)\n expect(resumed).toMatchObject({ ok: true, resumed: true })\n\n const unknown = await store.claimRun('p1', d1, 'no-such-run')\n expect(unknown).toMatchObject({ ok: false, reason: 'run_not_found' })\n\n await store.appendRunEvents('p1', runId, [\n { kind: 'run_settled', outcome: 'completed', at: '2024-01-01T00:00:00.000Z' },\n ])\n const settled = await store.claimRun('p1', d1, runId)\n expect(settled).toMatchObject({ ok: false, reason: 'run_already_settled' })\n })\n\n it('claimRun re-enters after an ABORTED or HALTED run, but not after a completed one', async () => {\n // `aborted` and `halted` are STOPPING POINTS, not endings. The interruption taxonomy\n // classifies a turn abort as resumable with the frontier intact at the same digest, so a\n // store that treats every `run_settled` as terminal makes `resumeRunId` unusable for\n // exactly the cases it exists to serve — which is what the reference store did, and what\n // this case would have caught.\n for (const outcome of ['aborted', 'halted'] as const) {\n const store = await makeStore()\n await store.createPlan(`resumable-${outcome}`)\n const digest = await makeExecutable(store, `resumable-${outcome}`)\n\n const started = await store.claimRun(`resumable-${outcome}`, digest)\n const runId = (started as { runId: string }).runId\n await store.appendRunEvents(`resumable-${outcome}`, runId, [\n {\n kind: 'run_interrupted',\n cause: { kind: 'turn_abort' },\n at: '2024-01-01T00:00:00.000Z',\n },\n { kind: 'run_settled', outcome, at: '2024-01-01T00:00:00.000Z' },\n ])\n\n const again = await store.claimRun(`resumable-${outcome}`, digest, runId)\n expect(again).toMatchObject({ ok: true, resumed: true })\n }\n })\n\n it('a CLONED plan can be frozen — every state fold carries provenance', async () => {\n // A clone carries `PlanProvenance`, and provenance is DIGESTED. So a store whose\n // `transition`/`readState` folds omit it computes a different digest than `freezePlan`\n // does, the `expectedDigest` check fails, and the clone can never leave `editable`.\n //\n // That breaks the documented recovery path outright: `clonePlan` is what you do after a\n // halting failure, and a clone that cannot be frozen cannot be re-approved or re-run. The\n // reference store had exactly this bug — five folds omitted `record.provenance` while\n // `readProvenance` supplied it everywhere else.\n const store = await makeStore()\n await store.createPlan('conf-clone-src')\n await store.appendOps('conf-clone-src', [addNodeOp(entryNode('entry'), 1)])\n\n const cloned = await store.clonePlan('conf-clone-src', 'conf-clone-dst')\n expect(cloned).toMatchObject({ ok: true })\n\n const provenance = await store.readProvenance('conf-clone-dst')\n expect(provenance).toBeDefined()\n\n // The digest the store reports must be the one a provenance-aware fold produces — that is\n // what `freezePlan` computes and passes as `expectedDigest`.\n const ops = await store.readOps('conf-clone-dst')\n const expected = foldOps('conf-clone-dst', ops, provenance).view.digest\n const state = await store.readState('conf-clone-dst')\n expect(state.digest).toBe(expected)\n\n // And the transition must actually commit at that digest.\n const moved = await store.transition('conf-clone-dst', {\n from: 'editable',\n to: 'reviewable',\n expectedDigest: expected,\n })\n expect(moved).toMatchObject({ ok: true })\n })\n\n // ── 11. claimRun preconditions ────────────────────────────────────────────\n it('claimRun is refused with not_executable when not executable and digest_mismatch when the digest moved', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n\n const notExecutable = await store.claimRun('p1', d1)\n expect(notExecutable).toMatchObject({ ok: false, reason: 'not_executable' })\n\n await makeExecutable(store, 'p1')\n const moved = await store.claimRun('p1', 'stale-digest')\n expect(moved).toMatchObject({ ok: false, reason: 'digest_mismatch' })\n })\n\n // ── 12. appendRunEvents is one batch ─────────────────────────────────────\n it('appendRunEvents commits its array as one batch so all three events are read back', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n const claimed = await store.claimRun('p1', d1)\n const runId = (claimed as { runId: string }).runId\n\n // The commit protocol depends on node_settled + every edge_taken + the new\n // frontier_snapshot landing in a SINGLE commit — a store that commits them one at a time\n // and could interleave is non-conforming.\n const batch: RunEvent[] = [\n { kind: 'run_started', runId, digest: d1, at: '2024-01-01T00:00:00.000Z' },\n {\n kind: 'node_entered',\n frame: {\n nodeId: 'entry',\n kind: 'entry',\n branchId: { segments: [] },\n viaEdgeId: undefined,\n },\n at: '2024-01-01T00:00:00.000Z',\n },\n {\n kind: 'node_settled',\n frame: {\n nodeId: 'entry',\n kind: 'entry',\n branchId: { segments: [] },\n viaEdgeId: undefined,\n },\n outcome: {\n status: 'ok',\n output: { items: [{ json: { ok: true } }], branchId: { segments: [] } },\n },\n at: '2024-01-01T00:00:00.000Z',\n },\n ]\n await store.appendRunEvents('p1', runId, batch)\n const events = await store.readRunEvents('p1', runId)\n expect(events).toHaveLength(3)\n expect(events.map((e) => e.kind)).toEqual(['run_started', 'node_entered', 'node_settled'])\n })\n\n // ── 13. readOps revision prefix ───────────────────────────────────────────\n it('readOps throughRevision serves a revision prefix and rejects a revision the log never reached', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n await appendNode(store, 'p1', entryNode('entry'), 1)\n await appendNode(store, 'p1', entryNode('entry2'), 2)\n\n const prefix = await store.readOps('p1', { throughRevision: 1 })\n expect(prefix).toHaveLength(1)\n expect(prefix[0].opId).toBe('op-1')\n\n await expect(store.readOps('p1', { throughRevision: 99 })).rejects.toThrow()\n })\n\n // ── 14. clonePlan ─────────────────────────────────────────────────────────\n it('clonePlan yields an editable, unapproved, run-less clone with parent provenance', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await appendNode(store, 'p1', entryNode('entry'), 1)\n\n const cloned = await store.clonePlan('p1', 'p2')\n expect(cloned).toMatchObject({ ok: true })\n\n const state = await store.readState('p2')\n expect(state.state).toBe('editable')\n expect(await store.readApproval('p2')).toBeUndefined()\n await expect(store.readRunEvents('p2')).rejects.toThrow()\n\n const provenance = await store.readProvenance('p2')\n expect(provenance).toMatchObject({\n kind: 'clone',\n parent: 'p1',\n parentDigest: d1,\n parentRevision: 1,\n })\n\n const missing = await store.clonePlan('no-such', 'p3')\n expect(missing).toMatchObject({ ok: false, reason: 'source_missing' })\n })\n\n // ── 15. frontier_snapshot artifact handles round-trip ────────────────────\n it('a round-tripped frontier_snapshot preserves artifact handles', async () => {\n const store = await makeStore()\n await store.createPlan('p1')\n const d1 = await makeExecutable(store, 'p1')\n const claimed = await store.claimRun('p1', d1)\n const runId = (claimed as { runId: string }).runId\n\n // A handle is a pointer, never bytes — the encoding is the store's business, so we assert\n // the PROPERTY (the entry survives the round-trip) rather than any representation.\n const artifact: SpooledArtifactLike = {\n constructor: { toolMethods: [] },\n marker: 'handle',\n }\n const artifacts: ArtifactTable = new Map([['entry:root', artifact]])\n const frame: PendingFrame = {\n frame: {\n nodeId: 'entry',\n kind: 'entry',\n branchId: { segments: [] },\n viaEdgeId: undefined,\n },\n outputs: new Map(),\n artifacts,\n }\n const snapshot: RunEvent = {\n kind: 'frontier_snapshot',\n frames: [frame],\n joins: [],\n at: '2024-01-01T00:00:00.000Z',\n }\n await store.appendRunEvents('p1', runId, [snapshot])\n\n const events = await store.readRunEvents('p1', runId)\n const readBack = events.find((e) => e.kind === 'frontier_snapshot')\n expect(readBack).toBeDefined()\n const readFrame = (readBack as { frames: PendingFrame[] }).frames[0]\n const entry = readFrame.artifacts.get('entry:root')\n expect(entry).toBeDefined()\n expect(isObject(entry)).toBe(true)\n })\n })\n for (const fn of pending) {\n await fn()\n }\n}\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../chunk-Cek0wNdY.js");
3
3
  const require_guards = require("../../guards-05Uq3J4M.js");
4
- const require_spooled_artifact = require("../../spooled_artifact-DriNQRj7.js");
5
- const require_dispatch_runner = require("../../dispatch_runner-Bl3Xwebu.js");
4
+ const require_spooled_artifact = require("../../spooled_artifact-BpcesRBv.js");
5
+ const require_thought = require("../../thought-bS7O9O5H.js");
6
+ const require_common = require("../../common-H44Ik9ou.js");
7
+ const require_dispatch_runner = require("../../dispatch_runner-CKhm-scw.js");
6
8
  require("../../dispatch_runner.cjs");
7
- const require_thought = require("../../thought--fRgOwTP.js");
8
- const require_common = require("../../common-BV3HGeLj.js");
9
9
  const require_batteries_storage_in_memory = require("../storage/in_memory.cjs");
10
10
  const require_batteries_orchestration_reason = require("./reason.cjs");
11
11
  //#region src/batteries/orchestration/dispatch_reasoner.ts
@@ -1,9 +1,9 @@
1
1
  import { n as isInstanceOf, r as isObject } from "../../guards-BEpY7lBI.mjs";
2
- import { f as Tool } from "../../spooled_artifact-BkueYJhR.mjs";
3
- import { t as DispatchRunner } from "../../dispatch_runner-CbNyqSMy.mjs";
2
+ import { p as Tool } from "../../spooled_artifact-Bw_7swIp.mjs";
3
+ import { n as Message } from "../../thought-BE1KGEhV.mjs";
4
+ import { a as inMemoryMediaReader } from "../../common-BpdHIpQE.mjs";
5
+ import { t as DispatchRunner } from "../../dispatch_runner-BZDXUe0G.mjs";
4
6
  import "../../dispatch_runner.mjs";
5
- import { n as Message } from "../../thought-B8JAi3-W.mjs";
6
- import { a as inMemoryMediaReader } from "../../common-v9Jo9M5k.mjs";
7
7
  import { InMemorySpoolStore } from "../storage/in_memory.mjs";
8
8
  import { stripInstructionTags, validateReasonerOutput, wrapInstruction } from "./reason.mjs";
9
9
  //#region src/batteries/orchestration/dispatch_reasoner.ts
@@ -1,13 +1,13 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../chunk-Cek0wNdY.js");
3
3
  const require_guards = require("../../guards-05Uq3J4M.js");
4
- const require_spooled_artifact = require("../../spooled_artifact-DriNQRj7.js");
4
+ const require_spooled_artifact = require("../../spooled_artifact-BpcesRBv.js");
5
5
  const require_batteries_orchestration_encoding = require("./encoding.cjs");
6
6
  const require_batteries_orchestration_ops = require("./ops.cjs");
7
7
  const require_batteries_orchestration_plan = require("./plan.cjs");
8
8
  const require_batteries_orchestration_reason = require("./reason.cjs");
9
9
  const require_batteries_orchestration_runs = require("./runs.cjs");
10
- require("../../artifact_methods-f_bSy4kX.js");
10
+ require("../../artifact_methods-D6k_82r3.js");
11
11
  //#region src/batteries/orchestration/executor.ts
12
12
  /**
13
13
  * @module @nhtio/adk/batteries/orchestration/executor
@@ -1,11 +1,11 @@
1
1
  import { n as isInstanceOf, r as isObject, t as isError } from "../../guards-BEpY7lBI.mjs";
2
- import { i as effectiveToolMethods } from "../../spooled_artifact-BkueYJhR.mjs";
2
+ import { i as effectiveToolMethods } from "../../spooled_artifact-Bw_7swIp.mjs";
3
3
  import { NodeRef } from "./encoding.mjs";
4
4
  import { branchKey, foldOps } from "./ops.mjs";
5
5
  import { entryNodes, handleAppliesTo, immediateDominator, incoming, nodeById, outgoing, readPath } from "./plan.mjs";
6
6
  import { decodeOutputSchema, joinPromptParts } from "./reason.mjs";
7
7
  import { foldRun } from "./runs.mjs";
8
- import "../../artifact_methods-BMCahBLn.mjs";
8
+ import "../../artifact_methods-CJDQ5Lv-.mjs";
9
9
  //#region src/batteries/orchestration/executor.ts
10
10
  /**
11
11
  * @module @nhtio/adk/batteries/orchestration/executor
@@ -1,16 +1,16 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../chunk-Cek0wNdY.js");
3
3
  const require_guards = require("../../guards-05Uq3J4M.js");
4
- const require_spooled_artifact = require("../../spooled_artifact-DriNQRj7.js");
5
- require("../../common-BV3HGeLj.js");
6
- const require_spooled_markdown_artifact = require("../../spooled_markdown_artifact-C_VkCDhF.js");
4
+ const require_spooled_artifact = require("../../spooled_artifact-BpcesRBv.js");
5
+ require("../../common-H44Ik9ou.js");
6
+ const require_spooled_markdown_artifact = require("../../spooled_markdown_artifact-wJPnE8Ij.js");
7
7
  const require_batteries_tools__shared = require("../tools/_shared.cjs");
8
8
  const require_batteries_orchestration_encoding = require("./encoding.cjs");
9
9
  const require_batteries_orchestration_approval = require("./approval.cjs");
10
10
  const require_batteries_orchestration_render = require("./render.cjs");
11
- const require_batteries_orchestration_raw = require("./raw.cjs");
12
11
  const require_batteries_orchestration_outline = require("./outline.cjs");
13
12
  const require_batteries_orchestration_validation = require("./validation.cjs");
13
+ const require_batteries_orchestration_raw = require("./raw.cjs");
14
14
  const require_batteries_orchestration_templates = require("./templates.cjs");
15
15
  let _nhtio_validation = require("@nhtio/validation");
16
16
  //#region src/batteries/orchestration/forge.ts
@@ -1,14 +1,14 @@
1
1
  import { n as isInstanceOf, r as isObject } from "../../guards-BEpY7lBI.mjs";
2
- import { f as Tool } from "../../spooled_artifact-BkueYJhR.mjs";
3
- import "../../common-v9Jo9M5k.mjs";
4
- import { n as SpooledJsonArtifact } from "../../spooled_markdown_artifact-CfHRZUkl.mjs";
2
+ import { p as Tool } from "../../spooled_artifact-Bw_7swIp.mjs";
3
+ import "../../common-BpdHIpQE.mjs";
4
+ import { n as SpooledJsonArtifact } from "../../spooled_markdown_artifact-vd6eNtIP.mjs";
5
5
  import { runToolGate } from "../tools/_shared.mjs";
6
6
  import { NodeRef, ParamRef } from "./encoding.mjs";
7
7
  import { approvePlan, computeAuthoritySet } from "./approval.mjs";
8
8
  import { renderPlan } from "./render.mjs";
9
- import { rawDiff, rawOps, rawPlan } from "./raw.mjs";
10
9
  import { planOutline, planRead } from "./outline.mjs";
11
10
  import { collectIssues, freezePlan } from "./validation.mjs";
11
+ import { rawDiff, rawOps, rawPlan } from "./raw.mjs";
12
12
  import { instantiateTemplate, validateTemplate } from "./templates.mjs";
13
13
  import { validator } from "@nhtio/validation";
14
14
  //#region src/batteries/orchestration/forge.ts
@@ -2,11 +2,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../chunk-Cek0wNdY.js");
3
3
  const require_exceptions = require("../../exceptions-DrHnAGQz.js");
4
4
  const require_guards = require("../../guards-05Uq3J4M.js");
5
- const require_spooled_artifact = require("../../spooled_artifact-DriNQRj7.js");
5
+ const require_spooled_artifact = require("../../spooled_artifact-BpcesRBv.js");
6
6
  const require_batteries_orchestration_encoding = require("./encoding.cjs");
7
7
  const require_batteries_orchestration_ops = require("./ops.cjs");
8
8
  const require_batteries_orchestration_plan = require("./plan.cjs");
9
- require("../../artifact_methods-f_bSy4kX.js");
9
+ require("../../artifact_methods-D6k_82r3.js");
10
10
  //#region src/batteries/orchestration/validation.ts
11
11
  /**
12
12
  * Submit-time validation and the lifecycle machine.
@@ -1,10 +1,10 @@
1
1
  import { a as passesSchema } from "../../exceptions-DRYLe-J4.mjs";
2
2
  import { n as isInstanceOf, r as isObject, t as isError } from "../../guards-BEpY7lBI.mjs";
3
- import { i as effectiveToolMethods } from "../../spooled_artifact-BkueYJhR.mjs";
3
+ import { i as effectiveToolMethods } from "../../spooled_artifact-Bw_7swIp.mjs";
4
4
  import { NodeRef } from "./encoding.mjs";
5
5
  import { foldOps } from "./ops.mjs";
6
6
  import { entryNodes, findCycle, handleAppliesTo, immediateDominator, incoming, isValidEdgeId, isValidNodeId, nodeById, outgoing, reachableFrom, routesBetween } from "./plan.mjs";
7
- import "../../artifact_methods-BMCahBLn.mjs";
7
+ import "../../artifact_methods-CJDQ5Lv-.mjs";
8
8
  //#region src/batteries/orchestration/validation.ts
9
9
  /**
10
10
  * Submit-time validation and the lifecycle machine.
@@ -1,23 +1,23 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../chunk-Cek0wNdY.js");
3
3
  const require_guards = require("../guards-05Uq3J4M.js");
4
- const require_spooled_artifact = require("../spooled_artifact-DriNQRj7.js");
4
+ const require_spooled_artifact = require("../spooled_artifact-BpcesRBv.js");
5
5
  const require_batteries_orchestration_encoding = require("./orchestration/encoding.cjs");
6
6
  const require_batteries_orchestration_ops = require("./orchestration/ops.cjs");
7
7
  const require_batteries_orchestration_plan = require("./orchestration/plan.cjs");
8
8
  const require_batteries_orchestration_approval = require("./orchestration/approval.cjs");
9
9
  const require_batteries_orchestration_reason = require("./orchestration/reason.cjs");
10
10
  const require_batteries_orchestration_dispatch_reasoner = require("./orchestration/dispatch_reasoner.cjs");
11
+ const require_batteries_orchestration_in_memory = require("./orchestration/in_memory.cjs");
11
12
  const require_batteries_orchestration_runs = require("./orchestration/runs.cjs");
12
- require("../artifact_methods-f_bSy4kX.js");
13
+ require("../artifact_methods-D6k_82r3.js");
13
14
  const require_batteries_orchestration_executor = require("./orchestration/executor.cjs");
14
15
  const require_batteries_orchestration_render = require("./orchestration/render.cjs");
15
- const require_batteries_orchestration_raw = require("./orchestration/raw.cjs");
16
16
  const require_batteries_orchestration_outline = require("./orchestration/outline.cjs");
17
17
  const require_batteries_orchestration_validation = require("./orchestration/validation.cjs");
18
+ const require_batteries_orchestration_raw = require("./orchestration/raw.cjs");
18
19
  const require_batteries_orchestration_templates = require("./orchestration/templates.cjs");
19
20
  const require_batteries_orchestration_forge = require("./orchestration/forge.cjs");
20
- const require_batteries_orchestration_in_memory = require("./orchestration/in_memory.cjs");
21
21
  const require_predicates = require("../predicates-f3wvKYT8.js");
22
22
  const require_batteries_orchestration_cells_structured = require("./orchestration/cells/structured.cjs");
23
23
  const require_batteries_orchestration_cells_jexl = require("./orchestration/cells/jexl.cjs");
@@ -1,21 +1,21 @@
1
1
  import { n as isInstanceOf, r as isObject, t as isError } from "../guards-BEpY7lBI.mjs";
2
- import { i as effectiveToolMethods } from "../spooled_artifact-BkueYJhR.mjs";
2
+ import { i as effectiveToolMethods } from "../spooled_artifact-Bw_7swIp.mjs";
3
3
  import { NodeRef, ParamRef, planDigest, registerOrchestrationEncodables } from "./orchestration/encoding.mjs";
4
4
  import { branchKey, foldOps } from "./orchestration/ops.mjs";
5
5
  import { entryNodes, findCycle, handleAppliesTo, immediateDominator, incoming, isPlanEdge, isPlanNode, isValidEdgeId, isValidNodeId, nodeById, outgoing, reachableFrom, readPath, routesBetween } from "./orchestration/plan.mjs";
6
6
  import { approvePlan, computeAuthoritySet } from "./orchestration/approval.mjs";
7
7
  import { decodeOutputSchema, joinPromptParts, stripInstructionTags, validateReasonerOutput, wrapInstruction } from "./orchestration/reason.mjs";
8
8
  import { createDispatchReasoner } from "./orchestration/dispatch_reasoner.mjs";
9
+ import { InMemoryPlanStore } from "./orchestration/in_memory.mjs";
9
10
  import { foldRun } from "./orchestration/runs.mjs";
10
- import "../artifact_methods-BMCahBLn.mjs";
11
+ import "../artifact_methods-CJDQ5Lv-.mjs";
11
12
  import { executePlan } from "./orchestration/executor.mjs";
12
13
  import { renderPlan } from "./orchestration/render.mjs";
13
- import { rawDiff, rawOps, rawPlan } from "./orchestration/raw.mjs";
14
14
  import { planOutline, planRead } from "./orchestration/outline.mjs";
15
15
  import { freezePlan } from "./orchestration/validation.mjs";
16
+ import { rawDiff, rawOps, rawPlan } from "./orchestration/raw.mjs";
16
17
  import { instantiateTemplate, validateTemplate } from "./orchestration/templates.mjs";
17
18
  import { forgeOrchestrationTools } from "./orchestration/forge.mjs";
18
- import { InMemoryPlanStore } from "./orchestration/in_memory.mjs";
19
19
  import { a as isStructuredPredicate, c as E_ORCH_CELL_UNAVAILABLE, i as isPredicateLeaf, l as E_ORCH_ENCODER_REQUIRED, n as isAnyPredicate, o as loadOnce, r as isNotPredicate, s as parseStructuredPredicate, t as isAllPredicate } from "../predicates-CM27Z3TF.mjs";
20
20
  import { createStructuredCell } from "./orchestration/cells/structured.mjs";
21
21
  import { createJexlCell } from "./orchestration/cells/jexl.mjs";
@@ -10,7 +10,15 @@ export interface SandboxPolicyEnforcer {
10
10
  errors: string[];
11
11
  warnings: string[];
12
12
  }>;
13
- /** Spawn under a narrowing policy; a non-zero exit is data, not a rejected promise. */
13
+ /**
14
+ * Spawn under a narrowing policy; a non-zero exit is data, not a rejected promise.
15
+ *
16
+ * @remarks
17
+ * When `op.signal` aborts, an implementation MUST terminate the spawned child (including a
18
+ * child hidden behind a sandbox wrapper) and settle `completed`; it MUST NOT leave the child
19
+ * running after the lifecycle owner has cancelled the invocation. The returned streams may end
20
+ * as a consequence of termination, but `completed` remains the authoritative settlement signal.
21
+ */
14
22
  run(op: {
15
23
  argv: string[];
16
24
  policy: SandboxPolicy;
@@ -27,6 +35,10 @@ export interface SandboxPolicyEnforcer {
27
35
  * `process.env` into every child while this field sat unused.
28
36
  */
29
37
  env?: Record<string, string>;
38
+ /**
39
+ * Lifecycle cancellation for this child. Implementations must kill the spawned child and
40
+ * settle `completed` when this signal aborts.
41
+ */
30
42
  signal?: AbortSignal;
31
43
  }): Promise<{
32
44
  stdout: ReadableStream<Uint8Array>;
@@ -1,6 +1,11 @@
1
1
  import type { GuestOutcome, GuestLimits } from "../types";
2
- /** Construct a minimal SES-backed in-process guest. The runtime boundary is intentionally explicit. */
3
- export declare const createCompartmentRuntime: (globals: Record<string, (...args: unknown[]) => unknown>, limits: GuestLimits, modules?: Record<string, unknown>) => Promise<{
2
+ /**
3
+ * Construct a minimal SES-backed in-process guest.
4
+ *
5
+ * @remarks In Node, SES lockdown is process-global: this hardens the whole host realm, not
6
+ * only the guest. Guest-scoped isolation requires a worker or child runtime.
7
+ */
8
+ export declare const createCompartmentRuntime: (globals: Record<string, (...args: unknown[]) => unknown>, limits: GuestLimits, modules?: Record<string, unknown>, hostLockdown?: boolean) => Promise<{
4
9
  evaluate(source: string, o: {
5
10
  timeoutMs: number;
6
11
  }): Promise<GuestOutcome>;
@@ -2,6 +2,10 @@
2
2
  export declare const E_SES_LOCKDOWN_REQUIRED: import("../../../factories").CreatedException<[
3
3
  string
4
4
  ]>;
5
+ /** In-process SES evaluation requires hardening the complete host realm. */
6
+ export declare const E_SES_HOST_LOCKDOWN_REQUIRED: import("../../../factories").CreatedException<[
7
+ string
8
+ ]>;
5
9
  /** A guest evaluation exceeded its tool-selected deadline. */
6
10
  export declare const E_SES_EVALUATION_TIMEOUT: import("../../../factories").CreatedException<[
7
11
  string
@@ -1,6 +1,6 @@
1
1
  import type { GuestOutcome } from "../types";
2
2
  import type { GuestGlobal, GuestRuntimeLike } from "./ses_contracts";
3
3
  /** Host runner that retains capability implementations and exposes only enumerated names. */
4
- export declare const createGuestRunner: (globals: Record<string, GuestGlobal>, limits?: import("../index").GuestLimits, modules?: Record<string, unknown>) => Promise<GuestRuntimeLike>;
4
+ export declare const createGuestRunner: (globals: Record<string, GuestGlobal>, limits?: import("../index").GuestLimits, modules?: Record<string, unknown>, hostLockdown?: boolean) => Promise<GuestRuntimeLike>;
5
5
  /** Type-only terminal outcome helper. */
6
6
  export declare const isGuestOutcome: (value: unknown) => value is GuestOutcome;
@@ -1,4 +1,4 @@
1
1
  import type { GuestLimits } from "../types";
2
2
  import type { GuestRuntimeLike } from "./ses_contracts";
3
3
  /** In-process runtime factory for environments where SES is available. */
4
- export declare const createGuestRuntime: (globals: Record<string, (...args: unknown[]) => unknown>, limits: GuestLimits, modules?: Record<string, unknown>) => Promise<GuestRuntimeLike>;
4
+ export declare const createGuestRuntime: (globals: Record<string, (...args: unknown[]) => unknown>, limits: GuestLimits, modules?: Record<string, unknown>, hostLockdown?: boolean) => Promise<GuestRuntimeLike>;
@@ -69,11 +69,12 @@ export interface EvaluateJavascriptConfig {
69
69
  */
70
70
  readonly hostcallQuotas?: Partial<HostcallQuotas>;
71
71
  /**
72
- * Whether to apply lockdown to the host realm.
72
+ * Whether to apply lockdown to the host realm for the default in-process SES runtime.
73
73
  *
74
74
  * @remarks
75
- * This governs only the host realm and is process-global and irreversible. The guest's own
76
- * `lockdown()` always runs; that guest lockdown is the security guarantee.
75
+ * In Node, `lockdown()` is process-global and irreversible: it hardens the whole host realm,
76
+ * not only this guest. `false` is an explicit opt-out that refuses in-process evaluation;
77
+ * supply a worker or child runtime for guest-only isolation.
77
78
  */
78
79
  readonly hostLockdown?: boolean;
79
80
  /** Runtime seam used instead of the default SES runtime, typically by an adapter. */