@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.
- package/CHANGELOG.md +40 -0
- package/artifact_methods-CJDQ5Lv-.mjs +1 -0
- package/artifact_methods-D6k_82r3.js +1 -0
- package/batteries/artifacts/ecmascript.cjs +1 -1
- package/batteries/artifacts/ecmascript.mjs +1 -1
- package/batteries/artifacts/toon.cjs +1 -1
- package/batteries/artifacts/toon.mjs +1 -1
- package/batteries/artifacts/xml.cjs +1 -1
- package/batteries/artifacts/xml.mjs +1 -1
- package/batteries/artifacts/yaml.cjs +1 -1
- package/batteries/artifacts/yaml.mjs +1 -1
- package/batteries/artifacts.cjs +4 -4
- package/batteries/artifacts.mjs +4 -4
- package/batteries/dev-tools/forge.cjs +3 -3
- package/batteries/dev-tools/forge.mjs +3 -3
- package/batteries/dev-tools.cjs +2 -2
- package/batteries/dev-tools.mjs +2 -2
- package/batteries/encoding.cjs +7 -7
- package/batteries/encoding.mjs +7 -7
- package/batteries/generation/gemini/adapter.cjs +1 -1
- package/batteries/generation/gemini/adapter.mjs +1 -1
- package/batteries/generation/local_diffusion/adapter.cjs +1 -1
- package/batteries/generation/local_diffusion/adapter.mjs +1 -1
- package/batteries/generation/openai/adapter.cjs +1 -1
- package/batteries/generation/openai/adapter.mjs +1 -1
- package/batteries/isolation/browser.d.ts +1 -1
- package/batteries/isolation/child_process/transport.d.ts +2 -2
- package/batteries/isolation/child_process.cjs +4 -4
- package/batteries/isolation/child_process.cjs.map +1 -1
- package/batteries/isolation/child_process.mjs +4 -4
- package/batteries/isolation/child_process.mjs.map +1 -1
- package/batteries/isolation/codec.d.ts +2 -2
- package/batteries/isolation/crash_policy.d.ts +1 -1
- package/batteries/isolation/isolate_function.d.ts +2 -2
- package/batteries/isolation/protocol.d.ts +4 -4
- package/batteries/isolation/serve.d.ts +2 -2
- package/batteries/isolation/types.d.ts +4 -4
- package/batteries/isolation.cjs +1 -1
- package/batteries/isolation.mjs +1 -1
- package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
- package/batteries/llm/anthropic_messages/adapter.cjs.map +1 -1
- package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
- package/batteries/llm/anthropic_messages/adapter.mjs.map +1 -1
- package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
- package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
- package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
- package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
- package/batteries/llm/anthropic_messages/types.d.ts +2 -2
- package/batteries/llm/anthropic_messages/validation.cjs +3 -3
- package/batteries/llm/anthropic_messages/validation.cjs.map +1 -1
- package/batteries/llm/anthropic_messages/validation.mjs +3 -3
- package/batteries/llm/anthropic_messages/validation.mjs.map +1 -1
- package/batteries/llm/anthropic_messages.cjs +2 -2
- package/batteries/llm/anthropic_messages.mjs +2 -2
- package/batteries/llm/bedrock_converse/adapter.cjs +29 -7
- package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
- package/batteries/llm/bedrock_converse/adapter.mjs +30 -8
- package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
- package/batteries/llm/bedrock_converse/exceptions.cjs +3 -0
- package/batteries/llm/bedrock_converse/exceptions.cjs.map +1 -1
- package/batteries/llm/bedrock_converse/exceptions.d.ts +6 -0
- package/batteries/llm/bedrock_converse/exceptions.mjs +3 -1
- package/batteries/llm/bedrock_converse/exceptions.mjs.map +1 -1
- package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
- package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
- package/batteries/llm/bedrock_converse/types.d.ts +6 -2
- package/batteries/llm/bedrock_converse/validation.cjs +7 -1
- package/batteries/llm/bedrock_converse/validation.cjs.map +1 -1
- package/batteries/llm/bedrock_converse/validation.mjs +7 -1
- package/batteries/llm/bedrock_converse/validation.mjs.map +1 -1
- package/batteries/llm/bedrock_converse.cjs +2 -2
- package/batteries/llm/bedrock_converse.mjs +2 -2
- package/batteries/llm/claude_code_cli/adapter.cjs +6 -6
- package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
- package/batteries/llm/claude_code_cli/adapter.mjs +6 -6
- package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
- package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
- package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
- package/batteries/llm/claude_code_cli/types.d.ts +3 -2
- package/batteries/llm/claude_code_cli/validation.cjs +3 -3
- package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
- package/batteries/llm/claude_code_cli/validation.mjs +3 -3
- package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
- package/batteries/llm/claude_code_cli.cjs +1 -1
- package/batteries/llm/claude_code_cli.mjs +1 -1
- package/batteries/llm/gemini_generate_content/adapter.cjs +29 -7
- package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
- package/batteries/llm/gemini_generate_content/adapter.mjs +30 -8
- package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
- package/batteries/llm/gemini_generate_content/exceptions.cjs +3 -0
- package/batteries/llm/gemini_generate_content/exceptions.cjs.map +1 -1
- package/batteries/llm/gemini_generate_content/exceptions.d.ts +6 -0
- package/batteries/llm/gemini_generate_content/exceptions.mjs +3 -1
- package/batteries/llm/gemini_generate_content/exceptions.mjs.map +1 -1
- package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
- package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
- package/batteries/llm/gemini_generate_content/types.d.ts +7 -3
- package/batteries/llm/gemini_generate_content/validation.cjs +11 -2
- package/batteries/llm/gemini_generate_content/validation.cjs.map +1 -1
- package/batteries/llm/gemini_generate_content/validation.mjs +11 -2
- package/batteries/llm/gemini_generate_content/validation.mjs.map +1 -1
- package/batteries/llm/gemini_generate_content.cjs +1 -1
- package/batteries/llm/gemini_generate_content.mjs +1 -1
- package/batteries/llm/litert_lm/adapter.cjs +6 -6
- package/batteries/llm/litert_lm/adapter.cjs.map +1 -1
- package/batteries/llm/litert_lm/adapter.mjs +6 -6
- package/batteries/llm/litert_lm/adapter.mjs.map +1 -1
- package/batteries/llm/litert_lm/helpers.cjs +3 -3
- package/batteries/llm/litert_lm/helpers.mjs +3 -3
- package/batteries/llm/litert_lm/types.d.ts +2 -2
- package/batteries/llm/litert_lm/validation.cjs +3 -3
- package/batteries/llm/litert_lm/validation.cjs.map +1 -1
- package/batteries/llm/litert_lm/validation.mjs +3 -3
- package/batteries/llm/litert_lm/validation.mjs.map +1 -1
- package/batteries/llm/litert_lm.cjs +1 -1
- package/batteries/llm/litert_lm.mjs +1 -1
- package/batteries/llm/ollama/adapter.cjs +6 -6
- package/batteries/llm/ollama/adapter.cjs.map +1 -1
- package/batteries/llm/ollama/adapter.mjs +6 -6
- package/batteries/llm/ollama/adapter.mjs.map +1 -1
- package/batteries/llm/ollama/helpers.cjs +4 -4
- package/batteries/llm/ollama/helpers.mjs +4 -4
- package/batteries/llm/ollama/types.d.ts +2 -2
- package/batteries/llm/ollama/validation.cjs +3 -3
- package/batteries/llm/ollama/validation.cjs.map +1 -1
- package/batteries/llm/ollama/validation.mjs +3 -3
- package/batteries/llm/ollama/validation.mjs.map +1 -1
- package/batteries/llm/ollama.cjs +2 -2
- package/batteries/llm/ollama.mjs +2 -2
- package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
- package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
- package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
- package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
- package/batteries/llm/openai_chat_completions/types.d.ts +2 -2
- package/batteries/llm/openai_chat_completions/validation.cjs +3 -3
- package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/validation.mjs +3 -3
- package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions.cjs +2 -2
- package/batteries/llm/openai_chat_completions.mjs +2 -2
- package/batteries/llm/openai_responses/adapter.cjs +6 -6
- package/batteries/llm/openai_responses/adapter.cjs.map +1 -1
- package/batteries/llm/openai_responses/adapter.mjs +6 -6
- package/batteries/llm/openai_responses/adapter.mjs.map +1 -1
- package/batteries/llm/openai_responses/helpers.cjs +3 -3
- package/batteries/llm/openai_responses/helpers.mjs +3 -3
- package/batteries/llm/openai_responses/types.d.ts +2 -2
- package/batteries/llm/openai_responses/validation.cjs +3 -3
- package/batteries/llm/openai_responses/validation.cjs.map +1 -1
- package/batteries/llm/openai_responses/validation.mjs +3 -3
- package/batteries/llm/openai_responses/validation.mjs.map +1 -1
- package/batteries/llm/openai_responses.cjs +2 -2
- package/batteries/llm/openai_responses.mjs +2 -2
- package/batteries/llm/transformers_js/adapter.cjs +6 -6
- package/batteries/llm/transformers_js/adapter.cjs.map +1 -1
- package/batteries/llm/transformers_js/adapter.mjs +6 -6
- package/batteries/llm/transformers_js/adapter.mjs.map +1 -1
- package/batteries/llm/transformers_js/helpers.cjs +3 -3
- package/batteries/llm/transformers_js/helpers.mjs +3 -3
- package/batteries/llm/transformers_js/types.d.ts +2 -2
- package/batteries/llm/transformers_js/validation.cjs +3 -3
- package/batteries/llm/transformers_js/validation.cjs.map +1 -1
- package/batteries/llm/transformers_js/validation.mjs +3 -3
- package/batteries/llm/transformers_js/validation.mjs.map +1 -1
- package/batteries/llm/transformers_js.cjs +1 -1
- package/batteries/llm/transformers_js.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
- package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
- package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
- package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs +3 -3
- package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/validation.mjs +3 -3
- package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions.cjs +2 -2
- package/batteries/llm/webllm_chat_completions.mjs +2 -2
- package/batteries/llm.cjs +2 -2
- package/batteries/llm.mjs +2 -2
- package/batteries/media/builder.d.ts +3 -0
- package/batteries/media/contracts.cjs.map +1 -1
- package/batteries/media/contracts.d.ts +40 -1
- package/batteries/media/contracts.mjs.map +1 -1
- package/batteries/media/engines/sharp.cjs +36 -2
- package/batteries/media/engines/sharp.cjs.map +1 -1
- package/batteries/media/engines/sharp.mjs +36 -2
- package/batteries/media/engines/sharp.mjs.map +1 -1
- package/batteries/media/forge.cjs +5 -5
- package/batteries/media/forge.mjs +5 -5
- package/batteries/media/index.d.ts +1 -1
- package/batteries/media/lint.cjs +3 -2
- package/batteries/media/lint.cjs.map +1 -1
- package/batteries/media/lint.mjs +3 -2
- package/batteries/media/lint.mjs.map +1 -1
- package/batteries/media.cjs +66 -2
- package/batteries/media.cjs.map +1 -1
- package/batteries/media.mjs +66 -2
- package/batteries/media.mjs.map +1 -1
- package/batteries/orchestration/conformance.cjs +123 -74
- package/batteries/orchestration/conformance.cjs.map +1 -1
- package/batteries/orchestration/conformance.d.ts +10 -8
- package/batteries/orchestration/conformance.mjs +54 -5
- package/batteries/orchestration/conformance.mjs.map +1 -1
- package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
- package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
- package/batteries/orchestration/executor.cjs +2 -2
- package/batteries/orchestration/executor.mjs +2 -2
- package/batteries/orchestration/forge.cjs +4 -4
- package/batteries/orchestration/forge.mjs +4 -4
- package/batteries/orchestration/validation.cjs +2 -2
- package/batteries/orchestration/validation.mjs +2 -2
- package/batteries/orchestration.cjs +4 -4
- package/batteries/orchestration.mjs +4 -4
- package/batteries/sandbox/contracts/policy_enforcer.d.ts +13 -1
- package/batteries/sandbox/js/compartment.d.ts +7 -2
- package/batteries/sandbox/js/exceptions.d.ts +4 -0
- package/batteries/sandbox/js/runner.d.ts +1 -1
- package/batteries/sandbox/js/service.d.ts +1 -1
- package/batteries/sandbox/js/ses_contracts.d.ts +4 -3
- package/batteries/sandbox/js.cjs +17 -8
- package/batteries/sandbox/js.cjs.map +1 -1
- package/batteries/sandbox/js.mjs +17 -9
- package/batteries/sandbox/js.mjs.map +1 -1
- package/batteries/sandbox/manager.d.ts +4 -3
- package/batteries/sandbox/node/srt_enforcer.d.ts +1 -1
- package/batteries/sandbox/node.cjs +36 -12
- package/batteries/sandbox/node.cjs.map +1 -1
- package/batteries/sandbox/node.mjs +36 -12
- package/batteries/sandbox/node.mjs.map +1 -1
- package/batteries/sandbox/tools.cjs +1 -1
- package/batteries/sandbox/tools.mjs +1 -1
- package/batteries/sandbox/types.d.ts +10 -1
- package/batteries/sandbox.cjs +27 -9
- package/batteries/sandbox.cjs.map +1 -1
- package/batteries/sandbox.mjs +28 -11
- package/batteries/sandbox.mjs.map +1 -1
- package/batteries/skills.cjs +9 -9
- package/batteries/skills.mjs +9 -9
- package/batteries/tools/_shared.cjs +1 -1
- package/batteries/tools/_shared.mjs +1 -1
- package/batteries/tools/color.cjs +2 -2
- package/batteries/tools/color.mjs +2 -2
- package/batteries/tools/comparison.cjs +2 -2
- package/batteries/tools/comparison.mjs +2 -2
- package/batteries/tools/data_structure.cjs +2 -2
- package/batteries/tools/data_structure.mjs +2 -2
- package/batteries/tools/datetime_extended.cjs +3 -3
- package/batteries/tools/datetime_extended.mjs +3 -3
- package/batteries/tools/datetime_math.cjs +3 -3
- package/batteries/tools/datetime_math.mjs +3 -3
- package/batteries/tools/encoding.cjs +2 -2
- package/batteries/tools/encoding.mjs +2 -2
- package/batteries/tools/formatting.cjs +2 -2
- package/batteries/tools/formatting.mjs +2 -2
- package/batteries/tools/geo_basics.cjs +2 -2
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/math.cjs +2 -2
- package/batteries/tools/math.mjs +2 -2
- package/batteries/tools/memory.cjs +5 -5
- package/batteries/tools/memory.mjs +5 -5
- package/batteries/tools/parsing.cjs +3 -3
- package/batteries/tools/parsing.mjs +3 -3
- package/batteries/tools/retrievables.cjs +5 -5
- package/batteries/tools/retrievables.mjs +5 -5
- package/batteries/tools/scrapper.cjs +1 -1
- package/batteries/tools/scrapper.mjs +1 -1
- package/batteries/tools/searxng.cjs +1 -1
- package/batteries/tools/searxng.mjs +1 -1
- package/batteries/tools/standing_instructions.cjs +3 -3
- package/batteries/tools/standing_instructions.mjs +3 -3
- package/batteries/tools/statistics.cjs +3 -3
- package/batteries/tools/statistics.mjs +3 -3
- package/batteries/tools/string_processing.cjs +2 -2
- package/batteries/tools/string_processing.mjs +2 -2
- package/batteries/tools/structured_data.cjs +2 -2
- package/batteries/tools/structured_data.mjs +2 -2
- package/batteries/tools/text_analysis.cjs +3 -3
- package/batteries/tools/text_analysis.mjs +3 -3
- package/batteries/tools/text_comparison.cjs +2 -2
- package/batteries/tools/text_comparison.mjs +2 -2
- package/batteries/tools/time.cjs +3 -3
- package/batteries/tools/time.mjs +3 -3
- package/batteries/tools/unit_conversion.cjs +2 -2
- package/batteries/tools/unit_conversion.mjs +2 -2
- package/batteries/tools.cjs +2 -2
- package/batteries/tools.mjs +2 -2
- package/batteries/validation.cjs +5 -5
- package/batteries/validation.mjs +5 -5
- package/batteries/vector/conformance/index.d.ts +11 -16
- package/batteries/vector/conformance.cjs +107 -36
- package/batteries/vector/conformance.cjs.map +1 -1
- package/batteries/vector/conformance.mjs +84 -13
- package/batteries/vector/conformance.mjs.map +1 -1
- package/batteries/vector/retrievable.cjs +1 -1
- package/batteries/vector/retrievable.mjs +1 -1
- package/batteries.cjs +5 -5
- package/batteries.mjs +5 -5
- package/{chat_common-DbbIESdo.mjs → chat_common-CmKV5Dz4.mjs} +2 -2
- package/{chat_common-DbbIESdo.mjs.map → chat_common-CmKV5Dz4.mjs.map} +1 -1
- package/{chat_common-B3O3zz-i.js → chat_common-Dpan9moo.js} +2 -2
- package/{chat_common-B3O3zz-i.js.map → chat_common-Dpan9moo.js.map} +1 -1
- package/{common-v9Jo9M5k.mjs → common-BpdHIpQE.mjs} +7 -7
- package/{common-v9Jo9M5k.mjs.map → common-BpdHIpQE.mjs.map} +1 -1
- package/{common-BV3HGeLj.js → common-H44Ik9ou.js} +7 -7
- package/{common-BV3HGeLj.js.map → common-H44Ik9ou.js.map} +1 -1
- package/common.cjs +7 -7
- package/common.mjs +7 -7
- package/{dispatch_runner-CbNyqSMy.mjs → dispatch_runner-BZDXUe0G.mjs} +5 -5
- package/{dispatch_runner-CbNyqSMy.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
- package/{dispatch_runner-Bl3Xwebu.js → dispatch_runner-CKhm-scw.js} +5 -5
- package/{dispatch_runner-Bl3Xwebu.js.map → dispatch_runner-CKhm-scw.js.map} +1 -1
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.mjs +1 -1
- package/{ecmascript-BSnvyY8T.js → ecmascript-CCtgamDh.js} +3 -3
- package/{ecmascript-BSnvyY8T.js.map → ecmascript-CCtgamDh.js.map} +1 -1
- package/{ecmascript-CZ7_YKfZ.mjs → ecmascript-DcmUQ9Jx.mjs} +3 -3
- package/{ecmascript-CZ7_YKfZ.mjs.map → ecmascript-DcmUQ9Jx.mjs.map} +1 -1
- package/eslint.cjs +1 -1
- package/eslint.mjs +1 -1
- package/exceptions.cjs +1 -1
- package/exceptions.mjs +1 -1
- package/forge.cjs +2 -2
- package/forge.mjs +2 -2
- package/guards.cjs +7 -7
- package/guards.mjs +7 -7
- package/{helpers-CDmLDBq5.mjs → helpers-BH7HTtkD.mjs} +3 -3
- package/{helpers-CDmLDBq5.mjs.map → helpers-BH7HTtkD.mjs.map} +1 -1
- package/{helpers-Tvvwpx1M.js → helpers-CEjjkXso.js} +3 -3
- package/{helpers-Tvvwpx1M.js.map → helpers-CEjjkXso.js.map} +1 -1
- package/index.cjs +10 -10
- package/index.mjs +10 -10
- package/{isolation-BQCTQYZ_.js → isolation-7Jrcucgc.js} +11 -11
- package/isolation-7Jrcucgc.js.map +1 -0
- package/{isolation-7xbkc12r.mjs → isolation-CO0NiK8R.mjs} +11 -11
- package/isolation-CO0NiK8R.mjs.map +1 -0
- package/lib/classes/tokenizable.d.ts +2 -3
- package/mcp/adk-docs-corpus.json +2 -2
- package/package.json +469 -469
- package/{retrievable-C5dXuDhD.js → retrievable-BTwjmPnl.js} +3 -3
- package/{retrievable-C5dXuDhD.js.map → retrievable-BTwjmPnl.js.map} +1 -1
- package/{retrievable-gl_TIHnX.mjs → retrievable-CXTAUuuv.mjs} +3 -3
- package/{retrievable-gl_TIHnX.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
- package/{scrapper-DD6-_2u-.js → scrapper-CJexXXK-.js} +4 -4
- package/{scrapper-DD6-_2u-.js.map → scrapper-CJexXXK-.js.map} +1 -1
- package/{scrapper-u_orpxIB.mjs → scrapper-DiQ5FfDL.mjs} +4 -4
- package/{scrapper-u_orpxIB.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
- package/{searxng-fVdJUCK2.mjs → searxng-BFTJ6rTE.mjs} +4 -4
- package/{searxng-fVdJUCK2.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
- package/{searxng-C7GK0Nrz.js → searxng-DzlGZG4V.js} +4 -4
- package/{searxng-C7GK0Nrz.js.map → searxng-DzlGZG4V.js.map} +1 -1
- package/server.json +2 -2
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-DriNQRj7.js → spooled_artifact-BpcesRBv.js} +384 -384
- package/spooled_artifact-BpcesRBv.js.map +1 -0
- package/{spooled_artifact-BkueYJhR.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
- package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-CfHRZUkl.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
- package/{spooled_markdown_artifact-CfHRZUkl.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
- package/{spooled_markdown_artifact-C_VkCDhF.js → spooled_markdown_artifact-wJPnE8Ij.js} +3 -3
- package/{spooled_markdown_artifact-C_VkCDhF.js.map → spooled_markdown_artifact-wJPnE8Ij.js.map} +1 -1
- package/{thought-B8JAi3-W.mjs → thought-BE1KGEhV.mjs} +3 -3
- package/{thought-B8JAi3-W.mjs.map → thought-BE1KGEhV.mjs.map} +1 -1
- package/{thought--fRgOwTP.js → thought-bS7O9O5H.js} +3 -3
- package/{thought--fRgOwTP.js.map → thought-bS7O9O5H.js.map} +1 -1
- package/{tokenizable-CWW7iSrD.js → tokenizable-BMZuGWRd.js} +35 -29
- package/tokenizable-BMZuGWRd.js.map +1 -0
- package/{tokenizable-DLMP68ZV.mjs → tokenizable-VB4Av8GF.mjs} +36 -30
- package/tokenizable-VB4Av8GF.mjs.map +1 -0
- package/{tool_call-CPjyvkm4.mjs → tool_call-Cfaj-6zK.mjs} +4 -4
- package/{tool_call-CPjyvkm4.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
- package/{tool_call-DgqVwL5n.js → tool_call-Fs_Uh5wQ.js} +4 -4
- package/{tool_call-DgqVwL5n.js.map → tool_call-Fs_Uh5wQ.js.map} +1 -1
- package/{tools-BmLzkvNr.mjs → tools-B3_8C78Q.mjs} +6 -6
- package/{tools-BmLzkvNr.mjs.map → tools-B3_8C78Q.mjs.map} +1 -1
- package/{tools-DmcIe2Cb.js → tools-CqOcmHR8.js} +6 -6
- package/{tools-DmcIe2Cb.js.map → tools-CqOcmHR8.js.map} +1 -1
- package/{toon-BvTQsKdN.mjs → toon-BSlr88px.mjs} +5 -5
- package/{toon-BvTQsKdN.mjs.map → toon-BSlr88px.mjs.map} +1 -1
- package/{toon-B05eKx-q.js → toon-D71tkyI3.js} +5 -5
- package/{toon-B05eKx-q.js.map → toon-D71tkyI3.js.map} +1 -1
- package/{turn_runner-DEGCvfVZ.mjs → turn_runner-BHHD6h77.mjs} +5 -5
- package/{turn_runner-DEGCvfVZ.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
- package/{turn_runner-DT8TseR4.js → turn_runner-DhLI7OTH.js} +5 -5
- package/{turn_runner-DT8TseR4.js.map → turn_runner-DhLI7OTH.js.map} +1 -1
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/types-D6X_aUIb.mjs.map +1 -1
- package/types-DrSosVaM.js.map +1 -1
- package/{validate-lzy9nG_E.mjs → validate-Bi7FGjoq.mjs} +13 -1
- package/{validate-lzy9nG_E.mjs.map → validate-Bi7FGjoq.mjs.map} +1 -1
- package/{validate-CdOS7S2u.js → validate-CkQI-48O.js} +13 -1
- package/{validate-CdOS7S2u.js.map → validate-CkQI-48O.js.map} +1 -1
- package/{xml-DDTIMpY3.js → xml-BeNvlifb.js} +5 -5
- package/{xml-DDTIMpY3.js.map → xml-BeNvlifb.js.map} +1 -1
- package/{xml-VhJ4NrMB.mjs → xml-vyCZZiF_.mjs} +5 -5
- package/{xml-VhJ4NrMB.mjs.map → xml-vyCZZiF_.mjs.map} +1 -1
- package/{yaml-Cx16IYJq.js → yaml-DhLLa2cj.js} +5 -5
- package/{yaml-Cx16IYJq.js.map → yaml-DhLLa2cj.js.map} +1 -1
- package/{yaml-Du4wFGzL.mjs → yaml-Dtz0Bd7J.mjs} +5 -5
- package/{yaml-Du4wFGzL.mjs.map → yaml-Dtz0Bd7J.mjs.map} +1 -1
- package/artifact_methods-BMCahBLn.mjs +0 -1
- package/artifact_methods-f_bSy4kX.js +0 -1
- package/isolation-7xbkc12r.mjs.map +0 -1
- package/isolation-BQCTQYZ_.js.map +0 -1
- package/spooled_artifact-BkueYJhR.mjs.map +0 -1
- package/spooled_artifact-DriNQRj7.js.map +0 -1
- package/tokenizable-CWW7iSrD.js.map +0 -1
- package/tokenizable-DLMP68ZV.mjs.map +0 -1
|
@@ -3,7 +3,6 @@ require("../../chunk-Cek0wNdY.js");
|
|
|
3
3
|
const require_guards = require("../../guards-05Uq3J4M.js");
|
|
4
4
|
require("../../guards.cjs");
|
|
5
5
|
const require_batteries_orchestration_ops = require("./ops.cjs");
|
|
6
|
-
let vitest = require("vitest");
|
|
7
6
|
//#region src/batteries/orchestration/conformance.ts
|
|
8
7
|
/**
|
|
9
8
|
* The shared conformance suite for {@link PlanStore} backends.
|
|
@@ -13,9 +12,8 @@ let vitest = require("vitest");
|
|
|
13
12
|
* against the {@link PlanStore} interface only — never against in-memory internals — so a passing
|
|
14
13
|
* suite proves the backend honours the same contract the shipped reference implementation does.
|
|
15
14
|
*
|
|
16
|
-
* Public, deep-import-only (`@nhtio/adk/batteries/orchestration/conformance`).
|
|
17
|
-
*
|
|
18
|
-
* barrel.
|
|
15
|
+
* Public, deep-import-only (`@nhtio/adk/batteries/orchestration/conformance`). The suite has no
|
|
16
|
+
* test-runner dependency: callers invoke and await it from any test framework.
|
|
19
17
|
*
|
|
20
18
|
* @module @nhtio/adk/batteries/orchestration/conformance
|
|
21
19
|
*/
|
|
@@ -26,8 +24,58 @@ let vitest = require("vitest");
|
|
|
26
24
|
* @param makeStore - A factory returning a FRESH store for each case, so no case shares state with
|
|
27
25
|
* another. May be async.
|
|
28
26
|
*/
|
|
29
|
-
var
|
|
30
|
-
|
|
27
|
+
var equal = (actual, expected) => {
|
|
28
|
+
if (actual === expected) return true;
|
|
29
|
+
if (actual === null || expected === null || typeof actual !== "object" || typeof expected !== "object") return false;
|
|
30
|
+
if (Array.isArray(actual) !== Array.isArray(expected)) return false;
|
|
31
|
+
const keysA = Object.keys(actual);
|
|
32
|
+
const keysB = Object.keys(expected);
|
|
33
|
+
if (keysA.length !== keysB.length) return false;
|
|
34
|
+
return keysA.every((k) => keysB.includes(k) && equal(actual[k], expected[k]));
|
|
35
|
+
};
|
|
36
|
+
var match = (actual, expected) => {
|
|
37
|
+
if (expected === null || typeof expected !== "object") return equal(actual, expected);
|
|
38
|
+
if (actual === null || typeof actual !== "object") return false;
|
|
39
|
+
return Object.entries(expected).every(([key, value]) => match(actual[key], value));
|
|
40
|
+
};
|
|
41
|
+
var expectValue = (actual) => ({
|
|
42
|
+
toBe: (expected) => assert(equal(actual, expected), "values were not equal"),
|
|
43
|
+
toEqual: (expected) => assert(equal(actual, expected), "values were not equal"),
|
|
44
|
+
toMatchObject: (expected) => assert(match(actual, expected), "value did not match expected object"),
|
|
45
|
+
toBeDefined: () => assert(actual !== void 0, "value was undefined"),
|
|
46
|
+
toBeUndefined: () => assert(actual === void 0, "value was defined"),
|
|
47
|
+
toHaveLength: (length) => assert(actual.length === length, "unexpected length"),
|
|
48
|
+
toBeGreaterThan: (value) => assert(actual > value, "value was not greater than expected"),
|
|
49
|
+
rejects: { toThrow: async () => {
|
|
50
|
+
try {
|
|
51
|
+
await actual;
|
|
52
|
+
} catch {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
throw new Error("expected promise to reject");
|
|
56
|
+
} }
|
|
57
|
+
});
|
|
58
|
+
var assert = (condition, message) => {
|
|
59
|
+
if (!condition) throw new Error(message);
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Run the framework-free PlanStore conformance suite against a consumer implementation.
|
|
63
|
+
*
|
|
64
|
+
* Each check creates a fresh store through `makeStore`, and the returned promise rejects when any
|
|
65
|
+
* contract assertion fails. Consumers can await this function from Vitest, node:test, Jest, Mocha,
|
|
66
|
+
* or another runner without importing a test framework from the conformance module.
|
|
67
|
+
*
|
|
68
|
+
* @param label - Human-readable name used to identify the implementation under test.
|
|
69
|
+
* @param makeStore - Factory returning a fresh PlanStore for each conformance check; it may be async.
|
|
70
|
+
*/
|
|
71
|
+
var runPlanStoreConformance = async (label, makeStore) => {
|
|
72
|
+
const pending = [];
|
|
73
|
+
const it = (_name, test) => {
|
|
74
|
+
pending.push(test);
|
|
75
|
+
};
|
|
76
|
+
const describe = (_name, suite) => suite();
|
|
77
|
+
const expect = expectValue;
|
|
78
|
+
describe(`PlanStore conformance: ${label}`, () => {
|
|
31
79
|
/** A minimal, well-shaped `entry` node for authoring ops. */
|
|
32
80
|
const entryNode = (id) => ({
|
|
33
81
|
id,
|
|
@@ -55,7 +103,7 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
55
103
|
/** Append a single node and return the resulting digest, asserting the append succeeded. */
|
|
56
104
|
const appendNode = async (store, planId, node, lamport) => {
|
|
57
105
|
const result = await store.appendOps(planId, [addNodeOp(node, lamport)]);
|
|
58
|
-
|
|
106
|
+
expect(result).toMatchObject({ ok: true });
|
|
59
107
|
return result.digest;
|
|
60
108
|
};
|
|
61
109
|
/** Drive a plan to `executable` at the digest of a single authored node, and return that digest. */
|
|
@@ -74,31 +122,31 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
74
122
|
});
|
|
75
123
|
return digest;
|
|
76
124
|
};
|
|
77
|
-
|
|
125
|
+
it("createPlan mints editable at revision 0 with an empty op log and a non-empty digest", async () => {
|
|
78
126
|
const store = await makeStore();
|
|
79
|
-
|
|
127
|
+
expect(await store.createPlan("p1")).toMatchObject({
|
|
80
128
|
ok: true,
|
|
81
129
|
revision: 0
|
|
82
130
|
});
|
|
83
131
|
const state = await store.readState("p1");
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
132
|
+
expect(state.state).toBe("editable");
|
|
133
|
+
expect(state.revision).toBe(0);
|
|
134
|
+
expect(state.digest.length).toBeGreaterThan(0);
|
|
135
|
+
expect(await store.readOps("p1")).toEqual([]);
|
|
136
|
+
expect(await store.appendOps("p1", [addNodeOp(entryNode("entry"), 1)])).toMatchObject({
|
|
89
137
|
ok: true,
|
|
90
138
|
revision: 1
|
|
91
139
|
});
|
|
92
140
|
});
|
|
93
|
-
|
|
141
|
+
it("createPlan refuses a duplicate id with reason duplicate_id", async () => {
|
|
94
142
|
const store = await makeStore();
|
|
95
143
|
await store.createPlan("p1");
|
|
96
|
-
|
|
144
|
+
expect(await store.createPlan("p1")).toMatchObject({
|
|
97
145
|
ok: false,
|
|
98
146
|
reason: "duplicate_id"
|
|
99
147
|
});
|
|
100
148
|
});
|
|
101
|
-
|
|
149
|
+
it("appendOps is refused in reviewable with reason not_editable and the real state", async () => {
|
|
102
150
|
const store = await makeStore();
|
|
103
151
|
await store.createPlan("p1");
|
|
104
152
|
const d1 = await appendNode(store, "p1", entryNode("entry"), 1);
|
|
@@ -107,33 +155,33 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
107
155
|
to: "reviewable",
|
|
108
156
|
expectedDigest: d1
|
|
109
157
|
});
|
|
110
|
-
|
|
158
|
+
expect(await store.appendOps("p1", [addNodeOp(entryNode("entry2"), 2)])).toMatchObject({
|
|
111
159
|
ok: false,
|
|
112
160
|
reason: "not_editable",
|
|
113
161
|
actual: { state: "reviewable" }
|
|
114
162
|
});
|
|
115
163
|
});
|
|
116
|
-
|
|
164
|
+
it("appendOps is refused in executable with not_editable and leaves the digest unchanged", async () => {
|
|
117
165
|
const store = await makeStore();
|
|
118
166
|
await store.createPlan("p1");
|
|
119
167
|
const d1 = await makeExecutable(store, "p1");
|
|
120
|
-
|
|
168
|
+
expect(await store.appendOps("p1", [addNodeOp(entryNode("entry2"), 2)])).toMatchObject({
|
|
121
169
|
ok: false,
|
|
122
170
|
reason: "not_editable",
|
|
123
171
|
actual: { state: "executable" }
|
|
124
172
|
});
|
|
125
|
-
|
|
173
|
+
expect((await store.readState("p1")).digest).toBe(d1);
|
|
126
174
|
});
|
|
127
|
-
|
|
175
|
+
it("appendOps with a stale expectedRevision returns revision_moved", async () => {
|
|
128
176
|
const store = await makeStore();
|
|
129
177
|
await store.createPlan("p1");
|
|
130
178
|
await appendNode(store, "p1", entryNode("entry"), 1);
|
|
131
|
-
|
|
179
|
+
expect(await store.appendOps("p1", [addNodeOp(entryNode("entry2"), 2)], 0)).toMatchObject({
|
|
132
180
|
ok: false,
|
|
133
181
|
reason: "revision_moved"
|
|
134
182
|
});
|
|
135
183
|
});
|
|
136
|
-
|
|
184
|
+
it("a transition gated on a stale digest is refused with digest_mismatch and leaves the plan reviewable", async () => {
|
|
137
185
|
const store = await makeStore();
|
|
138
186
|
await store.createPlan("p1");
|
|
139
187
|
const d1 = await appendNode(store, "p1", entryNode("entry"), 1);
|
|
@@ -153,7 +201,7 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
153
201
|
to: "reviewable",
|
|
154
202
|
expectedDigest: d2
|
|
155
203
|
});
|
|
156
|
-
|
|
204
|
+
expect(await store.transition("p1", {
|
|
157
205
|
from: "reviewable",
|
|
158
206
|
to: "executable",
|
|
159
207
|
expectedDigest: d1,
|
|
@@ -162,10 +210,10 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
162
210
|
ok: false,
|
|
163
211
|
reason: "digest_mismatch"
|
|
164
212
|
});
|
|
165
|
-
|
|
166
|
-
|
|
213
|
+
expect((await store.readState("p1")).state).toBe("reviewable");
|
|
214
|
+
expect(await store.readApproval("p1")).toBeUndefined();
|
|
167
215
|
});
|
|
168
|
-
|
|
216
|
+
it("a successful gate persists the approval bound to the gated digest", async () => {
|
|
169
217
|
const store = await makeStore();
|
|
170
218
|
await store.createPlan("p1");
|
|
171
219
|
const d1 = await appendNode(store, "p1", entryNode("entry"), 1);
|
|
@@ -174,15 +222,15 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
174
222
|
to: "reviewable",
|
|
175
223
|
expectedDigest: d1
|
|
176
224
|
});
|
|
177
|
-
|
|
225
|
+
expect(await store.transition("p1", {
|
|
178
226
|
from: "reviewable",
|
|
179
227
|
to: "executable",
|
|
180
228
|
expectedDigest: d1,
|
|
181
229
|
approval: approvalFor("p1", d1)
|
|
182
230
|
})).toMatchObject({ ok: true });
|
|
183
|
-
|
|
231
|
+
expect((await store.readApproval("p1"))?.digest).toBe(d1);
|
|
184
232
|
});
|
|
185
|
-
|
|
233
|
+
it("an illegal transition pair is answered with ok:false and reason illegal_transition, not thrown", async () => {
|
|
186
234
|
const store = await makeStore();
|
|
187
235
|
await store.createPlan("p1");
|
|
188
236
|
await makeExecutable(store, "p1");
|
|
@@ -192,12 +240,12 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
192
240
|
to: "editable",
|
|
193
241
|
expectedDigest: digest
|
|
194
242
|
};
|
|
195
|
-
|
|
243
|
+
expect(await store.transition("p1", request)).toMatchObject({
|
|
196
244
|
ok: false,
|
|
197
245
|
reason: "illegal_transition"
|
|
198
246
|
});
|
|
199
247
|
});
|
|
200
|
-
|
|
248
|
+
it("a well-formed pair with a stale digest is refused with digest_mismatch", async () => {
|
|
201
249
|
const store = await makeStore();
|
|
202
250
|
await store.createPlan("p1");
|
|
203
251
|
const digest = await appendNode(store, "p1", entryNode("entry"), 1);
|
|
@@ -206,7 +254,7 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
206
254
|
to: "reviewable",
|
|
207
255
|
expectedDigest: digest
|
|
208
256
|
});
|
|
209
|
-
|
|
257
|
+
expect(await store.transition("p1", {
|
|
210
258
|
from: "reviewable",
|
|
211
259
|
to: "executable",
|
|
212
260
|
expectedDigest: "stale",
|
|
@@ -216,39 +264,39 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
216
264
|
reason: "digest_mismatch"
|
|
217
265
|
});
|
|
218
266
|
const state = await store.readState("p1");
|
|
219
|
-
|
|
220
|
-
|
|
267
|
+
expect(state.state).toBe("reviewable");
|
|
268
|
+
expect(state.digest).toBe(digest);
|
|
221
269
|
});
|
|
222
|
-
|
|
270
|
+
it("claimRun succeeds exactly once under concurrent claimants", async () => {
|
|
223
271
|
const store = await makeStore();
|
|
224
272
|
await store.createPlan("p1");
|
|
225
273
|
const d1 = await makeExecutable(store, "p1");
|
|
226
274
|
const [a, b] = await Promise.all([store.claimRun("p1", d1), store.claimRun("p1", d1)]);
|
|
227
275
|
const winners = [a, b].filter((r) => r.ok === true);
|
|
228
276
|
const losers = [a, b].filter((r) => r.ok === false);
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
277
|
+
expect(winners).toHaveLength(1);
|
|
278
|
+
expect(losers).toHaveLength(1);
|
|
279
|
+
expect(losers[0]).toMatchObject({
|
|
232
280
|
ok: false,
|
|
233
281
|
reason: "run_already_claimed"
|
|
234
282
|
});
|
|
235
|
-
|
|
283
|
+
expect(losers[0].existingRunId).toBe(winners[0].runId);
|
|
236
284
|
});
|
|
237
|
-
|
|
285
|
+
it("claimRun re-enters a run with resumeRunId, and refuses unknown or settled runs", async () => {
|
|
238
286
|
const store = await makeStore();
|
|
239
287
|
await store.createPlan("p1");
|
|
240
288
|
const d1 = await makeExecutable(store, "p1");
|
|
241
289
|
const first = await store.claimRun("p1", d1);
|
|
242
|
-
|
|
290
|
+
expect(first).toMatchObject({
|
|
243
291
|
ok: true,
|
|
244
292
|
resumed: false
|
|
245
293
|
});
|
|
246
294
|
const runId = first.runId;
|
|
247
|
-
|
|
295
|
+
expect(await store.claimRun("p1", d1, runId)).toMatchObject({
|
|
248
296
|
ok: true,
|
|
249
297
|
resumed: true
|
|
250
298
|
});
|
|
251
|
-
|
|
299
|
+
expect(await store.claimRun("p1", d1, "no-such-run")).toMatchObject({
|
|
252
300
|
ok: false,
|
|
253
301
|
reason: "run_not_found"
|
|
254
302
|
});
|
|
@@ -257,12 +305,12 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
257
305
|
outcome: "completed",
|
|
258
306
|
at: "2024-01-01T00:00:00.000Z"
|
|
259
307
|
}]);
|
|
260
|
-
|
|
308
|
+
expect(await store.claimRun("p1", d1, runId)).toMatchObject({
|
|
261
309
|
ok: false,
|
|
262
310
|
reason: "run_already_settled"
|
|
263
311
|
});
|
|
264
312
|
});
|
|
265
|
-
|
|
313
|
+
it("claimRun re-enters after an ABORTED or HALTED run, but not after a completed one", async () => {
|
|
266
314
|
for (const outcome of ["aborted", "halted"]) {
|
|
267
315
|
const store = await makeStore();
|
|
268
316
|
await store.createPlan(`resumable-${outcome}`);
|
|
@@ -277,42 +325,42 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
277
325
|
outcome,
|
|
278
326
|
at: "2024-01-01T00:00:00.000Z"
|
|
279
327
|
}]);
|
|
280
|
-
|
|
328
|
+
expect(await store.claimRun(`resumable-${outcome}`, digest, runId)).toMatchObject({
|
|
281
329
|
ok: true,
|
|
282
330
|
resumed: true
|
|
283
331
|
});
|
|
284
332
|
}
|
|
285
333
|
});
|
|
286
|
-
|
|
334
|
+
it("a CLONED plan can be frozen — every state fold carries provenance", async () => {
|
|
287
335
|
const store = await makeStore();
|
|
288
336
|
await store.createPlan("conf-clone-src");
|
|
289
337
|
await store.appendOps("conf-clone-src", [addNodeOp(entryNode("entry"), 1)]);
|
|
290
|
-
|
|
338
|
+
expect(await store.clonePlan("conf-clone-src", "conf-clone-dst")).toMatchObject({ ok: true });
|
|
291
339
|
const provenance = await store.readProvenance("conf-clone-dst");
|
|
292
|
-
|
|
340
|
+
expect(provenance).toBeDefined();
|
|
293
341
|
const expected = require_batteries_orchestration_ops.foldOps("conf-clone-dst", await store.readOps("conf-clone-dst"), provenance).view.digest;
|
|
294
|
-
|
|
295
|
-
|
|
342
|
+
expect((await store.readState("conf-clone-dst")).digest).toBe(expected);
|
|
343
|
+
expect(await store.transition("conf-clone-dst", {
|
|
296
344
|
from: "editable",
|
|
297
345
|
to: "reviewable",
|
|
298
346
|
expectedDigest: expected
|
|
299
347
|
})).toMatchObject({ ok: true });
|
|
300
348
|
});
|
|
301
|
-
|
|
349
|
+
it("claimRun is refused with not_executable when not executable and digest_mismatch when the digest moved", async () => {
|
|
302
350
|
const store = await makeStore();
|
|
303
351
|
await store.createPlan("p1");
|
|
304
352
|
const d1 = await appendNode(store, "p1", entryNode("entry"), 1);
|
|
305
|
-
|
|
353
|
+
expect(await store.claimRun("p1", d1)).toMatchObject({
|
|
306
354
|
ok: false,
|
|
307
355
|
reason: "not_executable"
|
|
308
356
|
});
|
|
309
357
|
await makeExecutable(store, "p1");
|
|
310
|
-
|
|
358
|
+
expect(await store.claimRun("p1", "stale-digest")).toMatchObject({
|
|
311
359
|
ok: false,
|
|
312
360
|
reason: "digest_mismatch"
|
|
313
361
|
});
|
|
314
362
|
});
|
|
315
|
-
|
|
363
|
+
it("appendRunEvents commits its array as one batch so all three events are read back", async () => {
|
|
316
364
|
const store = await makeStore();
|
|
317
365
|
await store.createPlan("p1");
|
|
318
366
|
const d1 = await makeExecutable(store, "p1");
|
|
@@ -354,43 +402,43 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
354
402
|
];
|
|
355
403
|
await store.appendRunEvents("p1", runId, batch);
|
|
356
404
|
const events = await store.readRunEvents("p1", runId);
|
|
357
|
-
|
|
358
|
-
|
|
405
|
+
expect(events).toHaveLength(3);
|
|
406
|
+
expect(events.map((e) => e.kind)).toEqual([
|
|
359
407
|
"run_started",
|
|
360
408
|
"node_entered",
|
|
361
409
|
"node_settled"
|
|
362
410
|
]);
|
|
363
411
|
});
|
|
364
|
-
|
|
412
|
+
it("readOps throughRevision serves a revision prefix and rejects a revision the log never reached", async () => {
|
|
365
413
|
const store = await makeStore();
|
|
366
414
|
await store.createPlan("p1");
|
|
367
415
|
await appendNode(store, "p1", entryNode("entry"), 1);
|
|
368
416
|
await appendNode(store, "p1", entryNode("entry2"), 2);
|
|
369
417
|
const prefix = await store.readOps("p1", { throughRevision: 1 });
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
await
|
|
418
|
+
expect(prefix).toHaveLength(1);
|
|
419
|
+
expect(prefix[0].opId).toBe("op-1");
|
|
420
|
+
await expect(store.readOps("p1", { throughRevision: 99 })).rejects.toThrow();
|
|
373
421
|
});
|
|
374
|
-
|
|
422
|
+
it("clonePlan yields an editable, unapproved, run-less clone with parent provenance", async () => {
|
|
375
423
|
const store = await makeStore();
|
|
376
424
|
await store.createPlan("p1");
|
|
377
425
|
const d1 = await appendNode(store, "p1", entryNode("entry"), 1);
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
await
|
|
382
|
-
|
|
426
|
+
expect(await store.clonePlan("p1", "p2")).toMatchObject({ ok: true });
|
|
427
|
+
expect((await store.readState("p2")).state).toBe("editable");
|
|
428
|
+
expect(await store.readApproval("p2")).toBeUndefined();
|
|
429
|
+
await expect(store.readRunEvents("p2")).rejects.toThrow();
|
|
430
|
+
expect(await store.readProvenance("p2")).toMatchObject({
|
|
383
431
|
kind: "clone",
|
|
384
432
|
parent: "p1",
|
|
385
433
|
parentDigest: d1,
|
|
386
434
|
parentRevision: 1
|
|
387
435
|
});
|
|
388
|
-
|
|
436
|
+
expect(await store.clonePlan("no-such", "p3")).toMatchObject({
|
|
389
437
|
ok: false,
|
|
390
438
|
reason: "source_missing"
|
|
391
439
|
});
|
|
392
440
|
});
|
|
393
|
-
|
|
441
|
+
it("a round-tripped frontier_snapshot preserves artifact handles", async () => {
|
|
394
442
|
const store = await makeStore();
|
|
395
443
|
await store.createPlan("p1");
|
|
396
444
|
const d1 = await makeExecutable(store, "p1");
|
|
@@ -415,12 +463,13 @@ var runPlanStoreConformance = (label, makeStore) => {
|
|
|
415
463
|
};
|
|
416
464
|
await store.appendRunEvents("p1", runId, [snapshot]);
|
|
417
465
|
const readBack = (await store.readRunEvents("p1", runId)).find((e) => e.kind === "frontier_snapshot");
|
|
418
|
-
|
|
466
|
+
expect(readBack).toBeDefined();
|
|
419
467
|
const entry = readBack.frames[0].artifacts.get("entry:root");
|
|
420
|
-
|
|
421
|
-
|
|
468
|
+
expect(entry).toBeDefined();
|
|
469
|
+
expect(require_guards.isObject(entry)).toBe(true);
|
|
422
470
|
});
|
|
423
471
|
});
|
|
472
|
+
for (const fn of pending) await fn();
|
|
424
473
|
};
|
|
425
474
|
//#endregion
|
|
426
475
|
exports.runPlanStoreConformance = runPlanStoreConformance;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance.cjs","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.cjs","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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"}
|