@stigmer/runner 3.10.0 → 3.11.1-dev.20260812192248
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/README.md +14 -1
- package/dist/.build-fingerprint +1 -1
- package/dist/activities/call-llm.js +9 -10
- package/dist/activities/call-llm.js.map +1 -1
- package/dist/activities/classify-tool-approvals.d.ts +2 -1
- package/dist/activities/classify-tool-approvals.js +28 -2
- package/dist/activities/classify-tool-approvals.js.map +1 -1
- package/dist/activities/discover-mcp-server.d.ts +39 -0
- package/dist/activities/discover-mcp-server.js +165 -28
- package/dist/activities/discover-mcp-server.js.map +1 -1
- package/dist/activities/emit-event.d.ts +14 -2
- package/dist/activities/emit-event.js +52 -17
- package/dist/activities/emit-event.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +8 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +1 -1
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +28 -2
- package/dist/activities/execute-cursor/approval-state.js +7 -1
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/attachment-resolver.d.ts +14 -0
- package/dist/activities/execute-cursor/attachment-resolver.js +18 -4
- package/dist/activities/execute-cursor/attachment-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/blueprint-resolver.d.ts +1 -9
- package/dist/activities/execute-cursor/blueprint-resolver.js +6 -22
- package/dist/activities/execute-cursor/blueprint-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/env-resolver.js +3 -1
- package/dist/activities/execute-cursor/env-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/error-classifier.d.ts +59 -3
- package/dist/activities/execute-cursor/error-classifier.js +115 -6
- package/dist/activities/execute-cursor/error-classifier.js.map +1 -1
- package/dist/activities/execute-cursor/extract-structured-output.d.ts +29 -0
- package/dist/activities/execute-cursor/extract-structured-output.js +58 -0
- package/dist/activities/execute-cursor/extract-structured-output.js.map +1 -0
- package/dist/activities/execute-cursor/hook-script.d.ts +14 -3
- package/dist/activities/execute-cursor/hook-script.js +72 -10
- package/dist/activities/execute-cursor/hook-script.js.map +1 -1
- package/dist/activities/execute-cursor/index.d.ts +51 -11
- package/dist/activities/execute-cursor/index.js +177 -93
- package/dist/activities/execute-cursor/index.js.map +1 -1
- package/dist/activities/execute-cursor/mcp-resolver.d.ts +24 -1
- package/dist/activities/execute-cursor/mcp-resolver.js +5 -2
- package/dist/activities/execute-cursor/mcp-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/model-pricing-data.d.ts +2 -0
- package/dist/activities/execute-cursor/model-pricing-data.js +13 -3
- package/dist/activities/execute-cursor/model-pricing-data.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +51 -4
- package/dist/activities/execute-cursor/prompt-builder.js +49 -7
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/turn-recovery.d.ts +52 -0
- package/dist/activities/execute-cursor/turn-recovery.js +193 -0
- package/dist/activities/execute-cursor/turn-recovery.js.map +1 -0
- package/dist/activities/execute-cursor/turn-stream.js +4 -1
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +18 -1
- package/dist/activities/execute-deep-agent/attachment-injector.js +68 -23
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -1
- package/dist/activities/execute-deep-agent/environment.js +3 -1
- package/dist/activities/execute-deep-agent/environment.js.map +1 -1
- package/dist/activities/execute-deep-agent/index.js +15 -0
- package/dist/activities/execute-deep-agent/index.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +7 -7
- package/dist/activities/execute-deep-agent/prompt-builder.js +8 -2
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +10 -0
- package/dist/activities/execute-deep-agent/setup.js +65 -24
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/shell-env.d.ts +5 -1
- package/dist/activities/execute-deep-agent/shell-env.js +7 -9
- package/dist/activities/execute-deep-agent/shell-env.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +18 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.js +15 -2
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +27 -6
- package/dist/activities/execute-deep-agent/subagent-wiring.js +26 -5
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/hydrate-workflow-execution.js +8 -3
- package/dist/activities/hydrate-workflow-execution.js.map +1 -1
- package/dist/activities/run-command.d.ts +5 -2
- package/dist/activities/run-command.js +22 -10
- package/dist/activities/run-command.js.map +1 -1
- package/dist/activities/run-env.d.ts +40 -0
- package/dist/activities/run-env.js +66 -0
- package/dist/activities/run-env.js.map +1 -0
- package/dist/activities/workflow-event-activities.d.ts +28 -10
- package/dist/activities/workflow-event-activities.js +87 -58
- package/dist/activities/workflow-event-activities.js.map +1 -1
- package/dist/bootstrap.js +5 -0
- package/dist/bootstrap.js.map +1 -1
- package/dist/claimcheck/payload-codec.js +21 -1
- package/dist/claimcheck/payload-codec.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +83 -21
- package/dist/client/stigmer-client.js +106 -29
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/encryption/config.d.ts +64 -0
- package/dist/encryption/config.js +108 -0
- package/dist/encryption/config.js.map +1 -0
- package/dist/encryption/index.d.ts +3 -0
- package/dist/encryption/index.js +3 -0
- package/dist/encryption/index.js.map +1 -0
- package/dist/encryption/payload-codec.d.ts +41 -0
- package/dist/encryption/payload-codec.js +130 -0
- package/dist/encryption/payload-codec.js.map +1 -0
- package/dist/middleware/index.d.ts +3 -0
- package/dist/middleware/index.js +7 -0
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/path-normalization.d.ts +57 -0
- package/dist/middleware/path-normalization.js +109 -0
- package/dist/middleware/path-normalization.js.map +1 -0
- package/dist/middleware/types.d.ts +8 -0
- package/dist/payload-codecs.d.ts +17 -0
- package/dist/payload-codecs.js +42 -0
- package/dist/payload-codecs.js.map +1 -0
- package/dist/preflight.d.ts +31 -0
- package/dist/preflight.js +43 -0
- package/dist/preflight.js.map +1 -1
- package/dist/runner-manager.js +21 -17
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +11 -18
- package/dist/runner.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +9 -3
- package/dist/shared/approval-policy.js +15 -6
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/artifact-storage.d.ts +23 -1
- package/dist/shared/artifact-storage.js +51 -10
- package/dist/shared/artifact-storage.js.map +1 -1
- package/dist/shared/attachment-naming.d.ts +53 -0
- package/dist/shared/attachment-naming.js +59 -0
- package/dist/shared/attachment-naming.js.map +1 -0
- package/dist/shared/caller-identity.d.ts +23 -2
- package/dist/shared/caller-identity.js +36 -5
- package/dist/shared/caller-identity.js.map +1 -1
- package/dist/shared/channel-attachment.js +1 -0
- package/dist/shared/channel-attachment.js.map +1 -1
- package/dist/shared/checkpointer/http-saver.d.ts +26 -1
- package/dist/shared/checkpointer/http-saver.js +54 -8
- package/dist/shared/checkpointer/http-saver.js.map +1 -1
- package/dist/shared/conversation-attachment.js +1 -0
- package/dist/shared/conversation-attachment.js.map +1 -1
- package/dist/shared/conversation-catchup.d.ts +9 -2
- package/dist/shared/conversation-catchup.js +39 -6
- package/dist/shared/conversation-catchup.js.map +1 -1
- package/dist/shared/datastore-attachment.d.ts +50 -7
- package/dist/shared/datastore-attachment.js +93 -11
- package/dist/shared/datastore-attachment.js.map +1 -1
- package/dist/shared/grpc-retry.d.ts +5 -1
- package/dist/shared/grpc-retry.js +5 -1
- package/dist/shared/grpc-retry.js.map +1 -1
- package/dist/shared/http-retry.d.ts +85 -0
- package/dist/shared/http-retry.js +101 -0
- package/dist/shared/http-retry.js.map +1 -0
- package/dist/shared/llm-backend.d.ts +275 -0
- package/dist/shared/llm-backend.js +425 -0
- package/dist/shared/llm-backend.js.map +1 -0
- package/dist/shared/llm-proxy.d.ts +8 -0
- package/dist/shared/llm-proxy.js +15 -0
- package/dist/shared/llm-proxy.js.map +1 -1
- package/dist/shared/mcp-enabled-tools.d.ts +57 -0
- package/dist/shared/mcp-enabled-tools.js +86 -0
- package/dist/shared/mcp-enabled-tools.js.map +1 -0
- package/dist/shared/mcp-manager.d.ts +11 -5
- package/dist/shared/mcp-manager.js +47 -8
- package/dist/shared/mcp-manager.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +39 -2
- package/dist/shared/mcp-resolver.js +38 -2
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/mcp-schema-sanitizer.d.ts +70 -0
- package/dist/shared/mcp-schema-sanitizer.js +197 -0
- package/dist/shared/mcp-schema-sanitizer.js.map +1 -0
- package/dist/shared/model-client.d.ts +18 -5
- package/dist/shared/model-client.js +149 -18
- package/dist/shared/model-client.js.map +1 -1
- package/dist/shared/model-error.js +198 -5
- package/dist/shared/model-error.js.map +1 -1
- package/dist/shared/model-pricing-data.d.ts +2 -0
- package/dist/shared/model-pricing-data.js +13 -3
- package/dist/shared/model-pricing-data.js.map +1 -1
- package/dist/shared/model-registry.js +3 -2
- package/dist/shared/model-registry.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +33 -0
- package/dist/shared/plan-mode-permissions.js +35 -0
- package/dist/shared/plan-mode-permissions.js.map +1 -0
- package/dist/shared/registry-endpoint.d.ts +20 -0
- package/dist/shared/registry-endpoint.js +25 -0
- package/dist/shared/registry-endpoint.js.map +1 -1
- package/dist/shared/runner-credential-keys.d.ts +24 -0
- package/dist/shared/runner-credential-keys.js +47 -0
- package/dist/shared/runner-credential-keys.js.map +1 -0
- package/dist/worker.d.ts +2 -1
- package/dist/worker.js +2 -4
- package/dist/worker.js.map +1 -1
- package/dist/workflow-engine/resolve.d.ts +19 -1
- package/dist/workflow-engine/resolve.js +37 -2
- package/dist/workflow-engine/resolve.js.map +1 -1
- package/dist/workflow-engine/types.d.ts +18 -0
- package/dist/workflow-engine/types.js.map +1 -1
- package/dist/workflows/call-agent-orchestrator.d.ts +9 -0
- package/dist/workflows/call-agent-orchestrator.js +1 -0
- package/dist/workflows/call-agent-orchestrator.js.map +1 -1
- package/dist/workflows/connect-mcp-server.js +9 -0
- package/dist/workflows/connect-mcp-server.js.map +1 -1
- package/dist/workflows/engine-core.js +23 -2
- package/dist/workflows/engine-core.js.map +1 -1
- package/dist/workflows/execute-from-execution.d.ts +1 -1
- package/dist/workflows/execute-from-execution.js +11 -1
- package/dist/workflows/execute-from-execution.js.map +1 -1
- package/dist/workflows/types.d.ts +8 -0
- package/package.json +9 -4
- package/src/__test-utils__/__tests__/vitest-global-setup.test.ts +37 -0
- package/src/__test-utils__/vitest-global-setup.ts +50 -0
- package/src/__tests__/bootstrap.test.ts +43 -0
- package/src/__tests__/claimcheck-codec.test.ts +36 -0
- package/src/__tests__/encryption-codec.test.ts +287 -0
- package/src/__tests__/fixtures/encrypted-payload-fixture.json +15 -0
- package/src/__tests__/history-encryption-e2e.test.ts +243 -0
- package/src/__tests__/preflight.test.ts +65 -2
- package/src/activities/__tests__/call-llm.test.ts +75 -0
- package/src/activities/__tests__/classify-tool-approvals.test.ts +117 -1
- package/src/activities/__tests__/discover-mcp-server.hang.test.ts +103 -0
- package/src/activities/__tests__/discover-mcp-server.test.ts +242 -1
- package/src/activities/__tests__/error-classifier.test.ts +94 -2
- package/src/activities/__tests__/run-command.test.ts +221 -0
- package/src/activities/__tests__/workflow-event-activities.test.ts +107 -8
- package/src/activities/call-llm.ts +9 -16
- package/src/activities/classify-tool-approvals.ts +34 -4
- package/src/activities/discover-mcp-server.ts +203 -31
- package/src/activities/emit-event.ts +65 -21
- package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +9 -0
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +14 -0
- package/src/activities/execute-cursor/__tests__/attachment-resolver.test.ts +53 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +151 -16
- package/src/activities/execute-cursor/__tests__/error-classifier-extraction.test.ts +208 -0
- package/src/activities/execute-cursor/__tests__/extract-structured-output.test.ts +120 -0
- package/src/activities/execute-cursor/__tests__/hook-script.test.ts +93 -0
- package/src/activities/execute-cursor/__tests__/mcp-resolver.test.ts +125 -0
- package/src/activities/execute-cursor/__tests__/model-pricing.test.ts +62 -1
- package/src/activities/execute-cursor/__tests__/prompt-builder-delegation.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/turn-recovery.test.ts +160 -0
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +13 -0
- package/src/activities/execute-cursor/approval-state.ts +30 -1
- package/src/activities/execute-cursor/attachment-resolver.ts +31 -3
- package/src/activities/execute-cursor/blueprint-resolver.ts +7 -27
- package/src/activities/execute-cursor/env-resolver.ts +3 -1
- package/src/activities/execute-cursor/error-classifier.ts +131 -7
- package/src/activities/execute-cursor/extract-structured-output.ts +72 -0
- package/src/activities/execute-cursor/hook-script.ts +74 -10
- package/src/activities/execute-cursor/index.ts +209 -109
- package/src/activities/execute-cursor/mcp-resolver.ts +36 -2
- package/src/activities/execute-cursor/model-pricing-data.ts +22 -3
- package/src/activities/execute-cursor/prompt-builder.ts +85 -9
- package/src/activities/execute-cursor/turn-recovery.ts +208 -0
- package/src/activities/execute-cursor/turn-stream.ts +5 -2
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +110 -8
- package/src/activities/execute-deep-agent/__tests__/datastore-degradation.test.ts +104 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +2 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +174 -0
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +34 -5
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/shell-env.test.ts +24 -10
- package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +178 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +12 -7
- package/src/activities/execute-deep-agent/attachment-injector.ts +94 -30
- package/src/activities/execute-deep-agent/environment.ts +3 -1
- package/src/activities/execute-deep-agent/index.ts +20 -0
- package/src/activities/execute-deep-agent/prompt-builder.ts +20 -10
- package/src/activities/execute-deep-agent/setup.ts +85 -29
- package/src/activities/execute-deep-agent/shell-env.ts +8 -9
- package/src/activities/execute-deep-agent/subagent-transformer.ts +30 -2
- package/src/activities/execute-deep-agent/subagent-wiring.ts +39 -6
- package/src/activities/hydrate-workflow-execution.ts +8 -3
- package/src/activities/run-command.ts +25 -12
- package/src/activities/run-env.ts +79 -0
- package/src/activities/workflow-event-activities.ts +96 -69
- package/src/bootstrap.ts +5 -0
- package/src/claimcheck/payload-codec.ts +33 -1
- package/src/client/__tests__/stigmer-client.test.ts +110 -11
- package/src/client/stigmer-client.ts +150 -37
- package/src/encryption/config.ts +155 -0
- package/src/encryption/index.ts +3 -0
- package/src/encryption/payload-codec.ts +152 -0
- package/src/middleware/__tests__/path-normalization.test.ts +140 -0
- package/src/middleware/index.ts +8 -0
- package/src/middleware/path-normalization.ts +125 -0
- package/src/middleware/types.ts +11 -0
- package/src/payload-codecs.ts +62 -0
- package/src/preflight.ts +45 -0
- package/src/runner-manager.ts +26 -26
- package/src/runner.ts +12 -27
- package/src/shared/__tests__/approval-policy.test.ts +82 -39
- package/src/shared/__tests__/artifact-storage.test.ts +145 -2
- package/src/shared/__tests__/attachment-naming.test.ts +159 -0
- package/src/shared/__tests__/bedrock-adapter.test.ts +213 -0
- package/src/shared/__tests__/bedrock-seam.test.ts +390 -0
- package/src/shared/__tests__/caller-identity.test.ts +25 -0
- package/src/shared/__tests__/channel-attachment.test.ts +1 -1
- package/src/shared/__tests__/connect-backfill.test.ts +1 -0
- package/src/shared/__tests__/conversation-attachment.test.ts +1 -1
- package/src/shared/__tests__/conversation-catchup.test.ts +24 -0
- package/src/shared/__tests__/datastore-attachment.test.ts +129 -1
- package/src/shared/__tests__/foundry-adapter.test.ts +276 -0
- package/src/shared/__tests__/foundry-seam.test.ts +482 -0
- package/src/shared/__tests__/http-retry.test.ts +68 -0
- package/src/shared/__tests__/llm-backend.test.ts +616 -0
- package/src/shared/__tests__/mcp-enabled-tools.test.ts +86 -0
- package/src/shared/__tests__/mcp-manager.test.ts +137 -15
- package/src/shared/__tests__/mcp-resolver.test.ts +146 -3
- package/src/shared/__tests__/mcp-schema-sanitizer.test.ts +267 -0
- package/src/shared/__tests__/model-client.test.ts +200 -0
- package/src/shared/__tests__/model-error.test.ts +289 -1
- package/src/shared/__tests__/model-pricing.test.ts +62 -2
- package/src/shared/__tests__/model-registry.test.ts +22 -0
- package/src/shared/__tests__/synthesized-attachment.test.ts +1 -0
- package/src/shared/__tests__/vertex-adapter.test.ts +169 -0
- package/src/shared/__tests__/vertex-seam.test.ts +295 -0
- package/src/shared/approval-policy.ts +14 -7
- package/src/shared/artifact-storage.ts +75 -10
- package/src/shared/attachment-naming.ts +78 -0
- package/src/shared/caller-identity.ts +40 -5
- package/src/shared/channel-attachment.ts +1 -0
- package/src/shared/checkpointer/__tests__/http-saver.test.ts +196 -1
- package/src/shared/checkpointer/http-saver.ts +71 -8
- package/src/shared/conversation-attachment.ts +1 -0
- package/src/shared/conversation-catchup.ts +39 -6
- package/src/shared/datastore-attachment.ts +106 -11
- package/src/shared/grpc-retry.ts +5 -1
- package/src/shared/http-retry.ts +139 -0
- package/src/shared/llm-backend.ts +544 -0
- package/src/shared/llm-proxy.ts +15 -0
- package/src/shared/mcp-enabled-tools.ts +105 -0
- package/src/shared/mcp-manager.ts +56 -8
- package/src/shared/mcp-resolver.ts +73 -2
- package/src/shared/mcp-schema-sanitizer.ts +224 -0
- package/src/shared/model-client.ts +179 -19
- package/src/shared/model-error.ts +222 -4
- package/src/shared/model-pricing-data.ts +22 -3
- package/src/shared/model-registry.ts +7 -2
- package/src/shared/plan-mode-permissions.ts +37 -0
- package/src/shared/registry-endpoint.ts +27 -0
- package/src/shared/runner-credential-keys.ts +46 -0
- package/src/worker.ts +4 -5
- package/src/workflow-engine/__tests__/tasks/emit-event.test.ts +127 -49
- package/src/workflow-engine/resolve.ts +48 -2
- package/src/workflow-engine/types.ts +18 -0
- package/src/workflows/__tests__/connect-mcp-server.test.ts +25 -0
- package/src/workflows/__tests__/execute-serverless-workflow.test.ts +68 -2
- package/src/workflows/call-agent-orchestrator.ts +10 -0
- package/src/workflows/connect-mcp-server.ts +9 -0
- package/src/workflows/engine-core.ts +23 -2
- package/src/workflows/execute-from-execution.ts +12 -2
- package/src/workflows/types.ts +8 -0
- package/dist/activities/execute-cursor/mcp-config.d.ts +0 -30
- package/dist/activities/execute-cursor/mcp-config.js +0 -39
- package/dist/activities/execute-cursor/mcp-config.js.map +0 -1
- package/src/activities/execute-cursor/mcp-config.ts +0 -66
|
@@ -85,7 +85,21 @@ export async function runWorkflowEngine(input, options) {
|
|
|
85
85
|
dsl: model.document.dsl,
|
|
86
86
|
});
|
|
87
87
|
recordExecutionStartMetric(model.document.name);
|
|
88
|
-
|
|
88
|
+
// Event sequence numbers are workflow state: assigned here in the
|
|
89
|
+
// deterministic sandbox (seeded from the persisted high-water mark) so
|
|
90
|
+
// they are stable across activity retries, worker restarts, and
|
|
91
|
+
// concurrent executions — the store can then treat re-sent sequences as
|
|
92
|
+
// idempotent duplicates. Pre-patch histories recorded the activity
|
|
93
|
+
// result as void and assigned sequences inside the emit activity from a
|
|
94
|
+
// process-global counter; they must keep doing so on replay, hence the
|
|
95
|
+
// gate. Remove the gate (and the activity's legacy counter) once
|
|
96
|
+
// pre-patch executions have drained.
|
|
97
|
+
const workflowAssignedSequences = patched("workflow-assigned-event-sequences");
|
|
98
|
+
const eventLogHighWaterMark = await eventProxy.ResetEventSequence(executionId);
|
|
99
|
+
let eventSequence = workflowAssignedSequences ? Number(eventLogHighWaterMark ?? 0) : 0;
|
|
100
|
+
const nextEventSequence = workflowAssignedSequences
|
|
101
|
+
? () => ++eventSequence
|
|
102
|
+
: undefined;
|
|
89
103
|
let recoveryContext;
|
|
90
104
|
if (options?.recoveryMode && executionId) {
|
|
91
105
|
log.info("Recovery mode active — loading context", { executionId });
|
|
@@ -109,10 +123,16 @@ export async function runWorkflowEngine(input, options) {
|
|
|
109
123
|
const emitEvents = async (events) => {
|
|
110
124
|
if (!executionId || events.length === 0)
|
|
111
125
|
return;
|
|
126
|
+
const stamped = nextEventSequence
|
|
127
|
+
? events.map(e => ({ ...e, sequenceNumber: nextEventSequence() }))
|
|
128
|
+
: events;
|
|
112
129
|
try {
|
|
113
|
-
await eventProxy.EmitWorkflowEvents(executionId,
|
|
130
|
+
await eventProxy.EmitWorkflowEvents(executionId, stamped, taskStatusAccumulator.toArray());
|
|
114
131
|
}
|
|
115
132
|
catch (err) {
|
|
133
|
+
// Final guard after the activity's retries are exhausted: a run must
|
|
134
|
+
// not die because its timeline write failed. With workflow-assigned
|
|
135
|
+
// sequences the result is a gap in the log, never a poisoned log.
|
|
116
136
|
log.warn("Failed to emit workflow events (non-fatal)", {
|
|
117
137
|
executionId,
|
|
118
138
|
eventCount: events.length,
|
|
@@ -164,6 +184,7 @@ export async function runWorkflowEngine(input, options) {
|
|
|
164
184
|
parentWorkflowId: agentMeta.parentWorkflowId || workflowInfo().workflowId,
|
|
165
185
|
taskName: agentMeta.taskName,
|
|
166
186
|
workflowExecutionId: agentMeta.workflowExecutionId || executionId,
|
|
187
|
+
nextEventSequence,
|
|
167
188
|
}),
|
|
168
189
|
promoteTaskOutput: (taskOutput, wexId, taskName, displayName) => promoteProxy.PromoteTaskOutput(taskOutput, wexId || executionId, taskName, displayName),
|
|
169
190
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-core.js","sourceRoot":"","sources":["../../src/workflows/engine-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAChH,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AASzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAEtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AA+BtF,MAAM,SAAS,GAAG,oBAAoB,CAAiB;IACrD,mBAAmB,EAAE,KAAK;CAC3B,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,eAAe,CAAuD;IACtF,mBAAmB,EAAE,IAAI;IACzB,gBAAgB,EAAE,KAAK;IACvB,KAAK,EAAE;QACL,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,CAAC;QACrB,eAAe,EAAE,IAAI;KACtB;CACF,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,eAAe,CAAgB;IAC9C,mBAAmB,EAAE,IAAI;IACzB,gBAAgB,EAAE,KAAK;IACvB,KAAK,EAAE;QACL,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,CAAC;QACrB,eAAe,EAAE,KAAK;KACvB;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,oBAAoB,CAAkB;IACvD,mBAAmB,EAAE,KAAK;IAC1B,KAAK,EAAE;QACL,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,OAAO;KACzB;CACF,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,oBAAoB,CAAoB;IAC3D,mBAAmB,EAAE,KAAK;IAC1B,KAAK,EAAE;QACL,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,IAAI;KACtB;CACF,CAAC,CAAC;AAWH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAqC,EACrC,OAAkC;IAElC,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACvD,MAAM,WAAW,GAAG,QAAQ,EAAE,YAAY,IAAI,EAAE,CAAC;IACjD,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEpC,GAAG,CAAC,IAAI,CAAC,wCAAwC,EAAE;QACjD,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI;QACjC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG;KACxB,CAAC,CAAC;IAEH,0BAA0B,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEhD,MAAM,UAAU,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"engine-core.js","sourceRoot":"","sources":["../../src/workflows/engine-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,4 +29,4 @@ export interface ExecuteFromExecutionInput {
|
|
|
29
29
|
invoker_identity_account_id?: string;
|
|
30
30
|
recovery_mode?: boolean;
|
|
31
31
|
}
|
|
32
|
-
export declare function executeFromExecution(input: ExecuteFromExecutionInput): Promise<
|
|
32
|
+
export declare function executeFromExecution(input: ExecuteFromExecutionInput): Promise<void>;
|
|
@@ -54,7 +54,17 @@ export async function executeFromExecution(input) {
|
|
|
54
54
|
envCount: Object.keys(materialized.env).length,
|
|
55
55
|
});
|
|
56
56
|
try {
|
|
57
|
-
|
|
57
|
+
// The engine's output is deliberately NOT returned. Both orchestrator
|
|
58
|
+
// parents discard this workflow's result (Java awaits it as Void, Go
|
|
59
|
+
// passes nil to Get), and the output already reaches users through
|
|
60
|
+
// PromoteTaskOutput and the event log. Returning it would (a) persist
|
|
61
|
+
// the full workflow output — which may embed secrets — as a plaintext
|
|
62
|
+
// payload in the cross-language parent's history, and (b) hand the Java
|
|
63
|
+
// parent a payload it must decode: once the payload-encryption codec is
|
|
64
|
+
// active, an encrypted result would fail Java's converter lookup
|
|
65
|
+
// (fromPayloads has no Void special-case). A void return produces a
|
|
66
|
+
// data-less binary/null payload that every SDK handles natively.
|
|
67
|
+
await runWorkflowEngine(materialized, {
|
|
58
68
|
checkPause,
|
|
59
69
|
recoveryMode: input.recovery_mode ?? false,
|
|
60
70
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-from-execution.js","sourceRoot":"","sources":["../../src/workflows/execute-from-execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAUjE,MAAM,YAAY,GAAG,eAAe,CAAoB;IACtD,mBAAmB,EAAE,IAAI;IACzB,KAAK,EAAE;QACL,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,CAAC;QACrB,eAAe,EAAE,KAAK;KACvB;CACF,CAAC,CAAC;AAgBH,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAgC;IAEhC,MAAM,EAAE,UAAU,EAAE,GAAG,wBAAwB,EAAE,CAAC;IAElD,GAAG,CAAC,IAAI,CAAC,4CAA4C,EAAE;QACrD,WAAW,EAAE,KAAK,CAAC,YAAY;QAC/B,UAAU,EAAE,KAAK,CAAC,WAAW;QAC7B,kBAAkB,EAAE,KAAK,CAAC,oBAAoB;QAC9C,KAAK,EAAE,KAAK,CAAC,MAAM;KACpB,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,wBAAwB,CAAC;QAC/D,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;QAChD,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,qCAAqC,EAAE;QAC9C,YAAY,EAAE,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;QAC9C,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM;KAC/C,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,
|
|
1
|
+
{"version":3,"file":"execute-from-execution.js","sourceRoot":"","sources":["../../src/workflows/execute-from-execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAUjE,MAAM,YAAY,GAAG,eAAe,CAAoB;IACtD,mBAAmB,EAAE,IAAI;IACzB,KAAK,EAAE;QACL,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,CAAC;QACrB,eAAe,EAAE,KAAK;KACvB;CACF,CAAC,CAAC;AAgBH,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAgC;IAEhC,MAAM,EAAE,UAAU,EAAE,GAAG,wBAAwB,EAAE,CAAC;IAElD,GAAG,CAAC,IAAI,CAAC,4CAA4C,EAAE;QACrD,WAAW,EAAE,KAAK,CAAC,YAAY;QAC/B,UAAU,EAAE,KAAK,CAAC,WAAW;QAC7B,kBAAkB,EAAE,KAAK,CAAC,oBAAoB;QAC9C,KAAK,EAAE,KAAK,CAAC,MAAM;KACpB,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,wBAAwB,CAAC;QAC/D,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;QAChD,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,qCAAqC,EAAE;QAC9C,YAAY,EAAE,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;QAC9C,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM;KAC/C,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,sEAAsE;QACtE,qEAAqE;QACrE,mEAAmE;QACnE,sEAAsE;QACtE,sEAAsE;QACtE,wEAAwE;QACxE,wEAAwE;QACxE,iEAAiE;QACjE,oEAAoE;QACpE,iEAAiE;QACjE,MAAM,iBAAiB,CAAC,YAAY,EAAE;YACpC,UAAU;YACV,YAAY,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK;SAC3C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,8CAA8C,EAAE;gBACvD,WAAW,EAAE,KAAK,CAAC,YAAY;aAChC,CAAC,CAAC;QACL,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -14,6 +14,14 @@
|
|
|
14
14
|
export interface ConnectMcpServerWorkflowInput {
|
|
15
15
|
mcp_server_id: string;
|
|
16
16
|
execution_context_id?: string | null;
|
|
17
|
+
/**
|
|
18
|
+
* Execution-scoped token for reading the connect ExecutionContext's
|
|
19
|
+
* decrypted credentials (oss#535). Populated by the OSS Go handler, whose
|
|
20
|
+
* EC read RPCs redact secrets for tokenless callers; absent on cloud,
|
|
21
|
+
* where the discovery activity's ambient connect_sandbox credential
|
|
22
|
+
* decrypts on its own.
|
|
23
|
+
*/
|
|
24
|
+
execution_context_token?: string | null;
|
|
17
25
|
invoker_identity_account_id?: string | null;
|
|
18
26
|
}
|
|
19
27
|
export interface ConnectMcpServerWorkflowOutput {
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/runner",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.1-dev.20260812192248",
|
|
4
4
|
"description": "Embeddable Temporal worker for the Stigmer AI agent platform — handles agent execution, workflow orchestration, and MCP server management",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": "
|
|
8
|
+
"node": "^22.13.0 || >=23.4.0"
|
|
9
9
|
},
|
|
10
10
|
"bin": {
|
|
11
11
|
"stigmer-runner": "./dist/main.js"
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/build-fingerprint.js",
|
|
28
28
|
"build:slim": "npm run build && node scripts/bundle-slim.mjs",
|
|
29
29
|
"verify:slim": "node scripts/verify-slim-artifact.mjs",
|
|
30
|
+
"verify:dist": "node scripts/verify-dist-boot.mjs",
|
|
30
31
|
"gen:ipc-fixtures": "tsx scripts/generate-ipc-fixtures.ts",
|
|
31
32
|
"start": "tsx src/main.ts",
|
|
32
33
|
"typecheck": "tsc --noEmit",
|
|
@@ -68,6 +69,10 @@
|
|
|
68
69
|
"directory": "backend/services/runner"
|
|
69
70
|
},
|
|
70
71
|
"dependencies": {
|
|
72
|
+
"@anthropic-ai/bedrock-sdk": "^0.32.1",
|
|
73
|
+
"@anthropic-ai/foundry-sdk": "^0.4.1",
|
|
74
|
+
"@anthropic-ai/vertex-sdk": "^0.19.1",
|
|
75
|
+
"@azure/identity": "^4.13.1",
|
|
71
76
|
"@bufbuild/protobuf": "2.12.0",
|
|
72
77
|
"@connectrpc/connect": "^2.0.0",
|
|
73
78
|
"@connectrpc/connect-node": "^2.0.0",
|
|
@@ -85,11 +90,11 @@
|
|
|
85
90
|
"@opentelemetry/sdk-metrics": "^2.0.0",
|
|
86
91
|
"@opentelemetry/sdk-trace-base": "^2.0.0",
|
|
87
92
|
"@opentelemetry/sdk-trace-node": "^2.0.0",
|
|
88
|
-
"@stigmer/protos": "3.
|
|
93
|
+
"@stigmer/protos": "3.11.1-dev.20260812192248",
|
|
89
94
|
"@temporalio/activity": "^1.11.0",
|
|
90
|
-
"@temporalio/client": "^1.11.0",
|
|
91
95
|
"@temporalio/common": "^1.11.0",
|
|
92
96
|
"@temporalio/interceptors-opentelemetry": "~1.16.0",
|
|
97
|
+
"@temporalio/proto": "^1.11.0",
|
|
93
98
|
"@temporalio/worker": "^1.11.0",
|
|
94
99
|
"@temporalio/workflow": "^1.16.2",
|
|
95
100
|
"deepagents": "1.10.2",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suite-gate tests (oss#257).
|
|
3
|
+
*
|
|
4
|
+
* The gate is what turns "three sqlite-importing files die at collection
|
|
5
|
+
* with a raw ERR_UNKNOWN_BUILTIN_MODULE" into one immediate, actionable
|
|
6
|
+
* failure. Both arms are pinned around an injected preflight (the
|
|
7
|
+
* preflightNodeRuntime idiom), so the failure arm is testable on a
|
|
8
|
+
* supported Node. The preflight MESSAGE contract itself is pinned in
|
|
9
|
+
* __tests__/preflight.test.ts — here we pin only what the gate adds: the
|
|
10
|
+
* throw/pass behavior and the test-context fix hint.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { describe, expect, it } from "vitest";
|
|
14
|
+
import { assertNodeCanRunSuite } from "../vitest-global-setup.js";
|
|
15
|
+
|
|
16
|
+
describe("assertNodeCanRunSuite", () => {
|
|
17
|
+
it("returns cleanly when the preflight passes", () => {
|
|
18
|
+
expect(() => assertNodeCanRunSuite(() => null)).not.toThrow();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("throws the preflight diagnosis verbatim when it fails", () => {
|
|
22
|
+
// The diagnosis must arrive unwrapped — it is the single source of what
|
|
23
|
+
// is wrong (found version, missing capability, both floors).
|
|
24
|
+
expect(() => assertNodeCanRunSuite(() => "diagnosis from preflight")).toThrow(
|
|
25
|
+
/diagnosis from preflight/,
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("appends the test-context fix hint", () => {
|
|
30
|
+
// Both escape hatches: the repo's pinned Node, and the experimental flag
|
|
31
|
+
// for Nodes where the builtin is flag-gated.
|
|
32
|
+
expect(() => assertNodeCanRunSuite(() => "boom")).toThrow(/\.nvmrc/);
|
|
33
|
+
expect(() => assertNodeCanRunSuite(() => "boom")).toThrow(
|
|
34
|
+
/--experimental-sqlite/,
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest globalSetup: refuse to run the suite on a Node that cannot run the
|
|
3
|
+
* runner.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: the durable checkpointer imports Node's built-in
|
|
6
|
+
* `node:sqlite` at module load time, so on a Node without it (below 22.13,
|
|
7
|
+
* or 23.0–23.3 — the 23.x line only gained it unflagged in 23.4) the
|
|
8
|
+
* sqlite-importing test files die at COLLECTION with a raw
|
|
9
|
+
* `ERR_UNKNOWN_BUILTIN_MODULE` while the rest of the suite grinds on
|
|
10
|
+
* (oss#257). globalSetup runs once in the main process before any file is
|
|
11
|
+
* collected, so the whole run fails immediately with the same actionable
|
|
12
|
+
* message the runner itself prints at boot (src/preflight.ts).
|
|
13
|
+
*
|
|
14
|
+
* Deliberately fails the WHOLE suite rather than skipping the sqlite tests:
|
|
15
|
+
* a Node that cannot load `node:sqlite` cannot run the runner at all, and a
|
|
16
|
+
* green-with-skips suite on such a Node would be a false signal. The gate is
|
|
17
|
+
* a capability probe, not a version check — on Nodes where the builtin is
|
|
18
|
+
* flag-gated (22.5–22.12, 23.0–23.3), `NODE_OPTIONS=--experimental-sqlite`
|
|
19
|
+
* satisfies the probe and the suite runs (vitest workers inherit
|
|
20
|
+
* NODE_OPTIONS, so the flag reaches every fork).
|
|
21
|
+
*
|
|
22
|
+
* Lives in src/__test-utils__/ so `tsc --noEmit` covers it (the dev tsconfig
|
|
23
|
+
* only includes src/) while tsconfig.build.json's exclusion keeps it out of
|
|
24
|
+
* dist/.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { preflightNodeRuntime } from "../preflight.js";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Throw an actionable error when this Node cannot run the runner (and hence
|
|
31
|
+
* its test suite). The preflight message is reused verbatim — single source
|
|
32
|
+
* of the diagnosis, contract pinned by __tests__/preflight.test.ts — with a
|
|
33
|
+
* test-context fix hint appended (the check-runner-node Makefile idiom).
|
|
34
|
+
*/
|
|
35
|
+
export function assertNodeCanRunSuite(
|
|
36
|
+
preflight: () => string | null = preflightNodeRuntime,
|
|
37
|
+
): void {
|
|
38
|
+
const failure = preflight();
|
|
39
|
+
if (failure === null) return;
|
|
40
|
+
throw new Error(
|
|
41
|
+
`${failure}\n` +
|
|
42
|
+
` fix: nvm use (the repo's .nvmrc pins a supported Node), or on a Node\n` +
|
|
43
|
+
` where node:sqlite is flag-gated (22.5-22.12, 23.0-23.3) run the suite\n` +
|
|
44
|
+
` with NODE_OPTIONS=--experimental-sqlite.`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default function globalSetup(): void {
|
|
49
|
+
assertNodeCanRunSuite();
|
|
50
|
+
}
|
|
@@ -161,6 +161,49 @@ describe("resolveRunnerBootstrap", () => {
|
|
|
161
161
|
);
|
|
162
162
|
|
|
163
163
|
expect(result.runnerAccessToken).toBeUndefined();
|
|
164
|
+
expect(result.payloadEncryption).toBeUndefined();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("surfaces server-managed payload-encryption keys from the discovery branch", async () => {
|
|
168
|
+
const factory: BootstrapClientFactory = async () => ({
|
|
169
|
+
getRunnerBootstrapConfig: () =>
|
|
170
|
+
Promise.resolve({
|
|
171
|
+
temporalAddress: "t:7233",
|
|
172
|
+
temporalNamespace: "default",
|
|
173
|
+
payloadEncryption: {
|
|
174
|
+
key: "a".repeat(44),
|
|
175
|
+
keyId: "identity-key-v2",
|
|
176
|
+
secondaryKey: "b".repeat(44),
|
|
177
|
+
secondaryKeyId: "identity-key-v1",
|
|
178
|
+
},
|
|
179
|
+
}),
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const result = await resolveRunnerBootstrap(
|
|
183
|
+
{ token: "tok", stigmerEndpoint: "https://api.stigmer.ai" },
|
|
184
|
+
factory,
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
expect(result.payloadEncryption).toEqual({
|
|
188
|
+
key: "a".repeat(44),
|
|
189
|
+
keyId: "identity-key-v2",
|
|
190
|
+
secondaryKey: "b".repeat(44),
|
|
191
|
+
secondaryKeyId: "identity-key-v1",
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("omits payload-encryption keys when the server does not manage them", async () => {
|
|
196
|
+
const factory: BootstrapClientFactory = async () => ({
|
|
197
|
+
getRunnerBootstrapConfig: () =>
|
|
198
|
+
Promise.resolve({ temporalAddress: "t:7233", temporalNamespace: "default" }),
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const result = await resolveRunnerBootstrap(
|
|
202
|
+
{ token: "tok", stigmerEndpoint: "https://api.stigmer.ai" },
|
|
203
|
+
factory,
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
expect(result.payloadEncryption).toBeUndefined();
|
|
164
207
|
});
|
|
165
208
|
});
|
|
166
209
|
|
|
@@ -152,6 +152,42 @@ describe("ClaimcheckPayloadCodec", () => {
|
|
|
152
152
|
expect(Buffer.from(decoded.data!)).toEqual(original.data);
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
+
it("restores the original payload metadata (round-trip)", async () => {
|
|
156
|
+
// The restored payload must carry its ORIGINAL encoding, not the
|
|
157
|
+
// marker's binary/claimcheck — otherwise no payload converter can
|
|
158
|
+
// interpret it and composition with the encryption codec breaks.
|
|
159
|
+
const original: Payload = {
|
|
160
|
+
metadata: {
|
|
161
|
+
encoding: Buffer.from("json/plain"),
|
|
162
|
+
"custom-key": Buffer.from("custom-value"),
|
|
163
|
+
},
|
|
164
|
+
data: Buffer.alloc(2048, "y"),
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const [encoded] = await codec.encode([original]);
|
|
168
|
+
const [decoded] = await codec.decode([encoded]);
|
|
169
|
+
|
|
170
|
+
expect(Buffer.from(decoded.metadata!["encoding"]!).toString()).toBe("json/plain");
|
|
171
|
+
expect(Buffer.from(decoded.metadata!["custom-key"]!).toString()).toBe("custom-value");
|
|
172
|
+
expect(Buffer.from(decoded.data!)).toEqual(original.data);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("decodes legacy markers written before metadata preservation", async () => {
|
|
176
|
+
const original = makeLargePayload(2048);
|
|
177
|
+
const [encoded] = await codec.encode([original]);
|
|
178
|
+
|
|
179
|
+
// Simulate a pre-fix marker: strip the metadata field.
|
|
180
|
+
const marker = JSON.parse(Buffer.from(encoded.data!).toString());
|
|
181
|
+
delete marker.metadata;
|
|
182
|
+
const legacy: Payload = {
|
|
183
|
+
metadata: encoded.metadata,
|
|
184
|
+
data: Buffer.from(JSON.stringify(marker)),
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const [decoded] = await codec.decode([legacy]);
|
|
188
|
+
expect(Buffer.from(decoded.data!)).toEqual(original.data);
|
|
189
|
+
});
|
|
190
|
+
|
|
155
191
|
it("retrieves uncompressed payloads correctly", async () => {
|
|
156
192
|
codec = new ClaimcheckPayloadCodec(
|
|
157
193
|
storage,
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the payload-encryption codec (stigmer-cloud#227).
|
|
3
|
+
*
|
|
4
|
+
* Covers the codec in isolation, its composition with the claim-check
|
|
5
|
+
* codec (order is load-bearing: encrypt before relocate, so object
|
|
6
|
+
* storage only ever sees ciphertext), the config loader's fail-fast
|
|
7
|
+
* contract, and the committed cross-language conformance fixture that
|
|
8
|
+
* pins the envelope format the Java decode-only codec (stigmer-cloud
|
|
9
|
+
* temporal-starter) must match.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
13
|
+
import { randomBytes } from "node:crypto";
|
|
14
|
+
import { readFileSync } from "node:fs";
|
|
15
|
+
import { join, dirname } from "node:path";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
17
|
+
import type { Payload } from "@temporalio/common";
|
|
18
|
+
import { EncryptionPayloadCodec } from "../encryption/payload-codec.js";
|
|
19
|
+
import { loadPayloadEncryptionConfig } from "../encryption/config.js";
|
|
20
|
+
import type { PayloadEncryptionConfig } from "../encryption/config.js";
|
|
21
|
+
import { ClaimcheckPayloadCodec } from "../claimcheck/payload-codec.js";
|
|
22
|
+
import { makeInMemoryArtifactStorage } from "../__test-utils__/fake-artifact-storage.js";
|
|
23
|
+
|
|
24
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
|
|
26
|
+
function makeKeyConfig(overrides: Partial<PayloadEncryptionConfig> = {}): PayloadEncryptionConfig {
|
|
27
|
+
return {
|
|
28
|
+
primary: { keyId: "test-key-1", key: randomBytes(32) },
|
|
29
|
+
...overrides,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function makeJsonPayload(value: unknown): Payload {
|
|
34
|
+
return {
|
|
35
|
+
metadata: { encoding: Buffer.from("json/plain") },
|
|
36
|
+
data: Buffer.from(JSON.stringify(value)),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function metadataString(payload: Payload, key: string): string | undefined {
|
|
41
|
+
const bytes = payload.metadata?.[key];
|
|
42
|
+
return bytes ? Buffer.from(bytes).toString("utf-8") : undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe("EncryptionPayloadCodec", () => {
|
|
46
|
+
it("round-trips a payload, restoring metadata and data exactly", async () => {
|
|
47
|
+
const codec = new EncryptionPayloadCodec(makeKeyConfig());
|
|
48
|
+
const original = makeJsonPayload({ secret: "s3cret-value" });
|
|
49
|
+
|
|
50
|
+
const [encoded] = await codec.encode([original]);
|
|
51
|
+
expect(metadataString(encoded, "encoding")).toBe("binary/encrypted");
|
|
52
|
+
expect(metadataString(encoded, "encryption-key-id")).toBe("test-key-1");
|
|
53
|
+
expect(Buffer.from(encoded.data!).includes("s3cret-value")).toBe(false);
|
|
54
|
+
|
|
55
|
+
const [decoded] = await codec.decode([encoded]);
|
|
56
|
+
expect(metadataString(decoded, "encoding")).toBe("json/plain");
|
|
57
|
+
expect(Buffer.from(decoded.data!)).toEqual(original.data);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("passes through payloads it did not encode", async () => {
|
|
61
|
+
const codec = new EncryptionPayloadCodec(makeKeyConfig());
|
|
62
|
+
const plaintext = makeJsonPayload({ from: "java-orchestrator" });
|
|
63
|
+
const [decoded] = await codec.decode([plaintext]);
|
|
64
|
+
expect(decoded).toBe(plaintext);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("skips data-less payloads on encode (binary/null void results)", async () => {
|
|
68
|
+
const codec = new EncryptionPayloadCodec(makeKeyConfig());
|
|
69
|
+
const nullPayload: Payload = {
|
|
70
|
+
metadata: { encoding: Buffer.from("binary/null") },
|
|
71
|
+
data: undefined,
|
|
72
|
+
};
|
|
73
|
+
const [encoded] = await codec.encode([nullPayload]);
|
|
74
|
+
expect(encoded).toBe(nullPayload);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("fails closed on tampered ciphertext", async () => {
|
|
78
|
+
const codec = new EncryptionPayloadCodec(makeKeyConfig());
|
|
79
|
+
const [encoded] = await codec.encode([makeJsonPayload({ a: 1 })]);
|
|
80
|
+
|
|
81
|
+
const tampered = Buffer.from(encoded.data!);
|
|
82
|
+
tampered[tampered.length - 1] ^= 0xff;
|
|
83
|
+
|
|
84
|
+
await expect(
|
|
85
|
+
codec.decode([{ metadata: encoded.metadata, data: tampered }]),
|
|
86
|
+
).rejects.toThrow(/corrupt or the configured key does not match/);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("fails closed on an unknown key id", async () => {
|
|
90
|
+
const writer = new EncryptionPayloadCodec(makeKeyConfig());
|
|
91
|
+
const [encoded] = await writer.encode([makeJsonPayload({ a: 1 })]);
|
|
92
|
+
|
|
93
|
+
const reader = new EncryptionPayloadCodec(
|
|
94
|
+
makeKeyConfig({ primary: { keyId: "other-key", key: randomBytes(32) } }),
|
|
95
|
+
);
|
|
96
|
+
await expect(reader.decode([encoded])).rejects.toThrow(
|
|
97
|
+
/unknown key id 'test-key-1'/,
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("fails closed when the key id metadata is missing", async () => {
|
|
102
|
+
const codec = new EncryptionPayloadCodec(makeKeyConfig());
|
|
103
|
+
const [encoded] = await codec.encode([makeJsonPayload({ a: 1 })]);
|
|
104
|
+
|
|
105
|
+
const stripped: Payload = {
|
|
106
|
+
metadata: { encoding: Buffer.from("binary/encrypted") },
|
|
107
|
+
data: encoded.data,
|
|
108
|
+
};
|
|
109
|
+
await expect(codec.decode([stripped])).rejects.toThrow(
|
|
110
|
+
/missing its encryption-key-id/,
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("decodes payloads written under the secondary key (rotation window)", async () => {
|
|
115
|
+
const oldKey = { keyId: "2026-01", key: randomBytes(32) };
|
|
116
|
+
const writer = new EncryptionPayloadCodec({ primary: oldKey });
|
|
117
|
+
const [encoded] = await writer.encode([makeJsonPayload({ rotated: true })]);
|
|
118
|
+
|
|
119
|
+
const rotatedReader = new EncryptionPayloadCodec({
|
|
120
|
+
primary: { keyId: "2026-08", key: randomBytes(32) },
|
|
121
|
+
secondary: oldKey,
|
|
122
|
+
});
|
|
123
|
+
const [decoded] = await rotatedReader.decode([encoded]);
|
|
124
|
+
expect(JSON.parse(Buffer.from(decoded.data!).toString())).toEqual({ rotated: true });
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe("composition with claim-check (encrypt, then relocate)", () => {
|
|
129
|
+
it("stores only ciphertext in object storage and round-trips exactly", async () => {
|
|
130
|
+
const { storage, blobs } = makeInMemoryArtifactStorage();
|
|
131
|
+
const encryption = new EncryptionPayloadCodec(makeKeyConfig());
|
|
132
|
+
const claimcheck = new ClaimcheckPayloadCodec(storage, {
|
|
133
|
+
enabled: true,
|
|
134
|
+
thresholdBytes: 128,
|
|
135
|
+
compressionEnabled: false,
|
|
136
|
+
keyPrefix: "claimcheck/",
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const secret = "very-large-and-very-secret-".repeat(32);
|
|
140
|
+
const original = makeJsonPayload({ secret });
|
|
141
|
+
|
|
142
|
+
// Temporal applies codec arrays in order on encode, reverse on decode.
|
|
143
|
+
const [encrypted] = await encryption.encode([original]);
|
|
144
|
+
const [relocated] = await claimcheck.encode([encrypted]);
|
|
145
|
+
expect(metadataString(relocated, "encoding")).toBe("binary/claimcheck");
|
|
146
|
+
|
|
147
|
+
expect(blobs.size).toBe(1);
|
|
148
|
+
const blob: Buffer = blobs.values().next().value!;
|
|
149
|
+
expect(blob.includes("very-large-and-very-secret-")).toBe(false);
|
|
150
|
+
|
|
151
|
+
const [restored] = await claimcheck.decode([relocated]);
|
|
152
|
+
const [decrypted] = await encryption.decode([restored]);
|
|
153
|
+
expect(metadataString(decrypted, "encoding")).toBe("json/plain");
|
|
154
|
+
expect(Buffer.from(decrypted.data!)).toEqual(original.data);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe("loadPayloadEncryptionConfig", () => {
|
|
159
|
+
const ENV_VARS = [
|
|
160
|
+
"STIGMER_PAYLOAD_ENCRYPTION_KEY",
|
|
161
|
+
"STIGMER_PAYLOAD_ENCRYPTION_KEY_ID",
|
|
162
|
+
"STIGMER_PAYLOAD_ENCRYPTION_SECONDARY_KEY",
|
|
163
|
+
"STIGMER_PAYLOAD_ENCRYPTION_SECONDARY_KEY_ID",
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
afterEach(() => {
|
|
167
|
+
for (const name of ENV_VARS) delete process.env[name];
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("returns undefined when no key is configured", () => {
|
|
171
|
+
expect(loadPayloadEncryptionConfig()).toBeUndefined();
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it("loads primary and secondary keys", () => {
|
|
175
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_KEY = randomBytes(32).toString("base64");
|
|
176
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_KEY_ID = "k2";
|
|
177
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_SECONDARY_KEY = randomBytes(32).toString("base64");
|
|
178
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_SECONDARY_KEY_ID = "k1";
|
|
179
|
+
|
|
180
|
+
const config = loadPayloadEncryptionConfig();
|
|
181
|
+
expect(config?.primary.keyId).toBe("k2");
|
|
182
|
+
expect(config?.primary.key.length).toBe(32);
|
|
183
|
+
expect(config?.secondary?.keyId).toBe("k1");
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it("fails the boot when a key is set without an id", () => {
|
|
187
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_KEY = randomBytes(32).toString("base64");
|
|
188
|
+
expect(() => loadPayloadEncryptionConfig()).toThrow(
|
|
189
|
+
/STIGMER_PAYLOAD_ENCRYPTION_KEY_ID is required/,
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("fails the boot on a key of the wrong length", () => {
|
|
194
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_KEY = randomBytes(16).toString("base64");
|
|
195
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_KEY_ID = "k1";
|
|
196
|
+
expect(() => loadPayloadEncryptionConfig()).toThrow(/must decode to 32 bytes/);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// Server-managed key material from getRunnerBootstrapConfig (stigmer#398):
|
|
200
|
+
// desktop-class runners receive a per-identity key at bootstrap instead of
|
|
201
|
+
// env config. The env key is the operator's explicit choice and must win.
|
|
202
|
+
describe("bootstrap-delivered keys", () => {
|
|
203
|
+
const bootstrapKeys = () => ({
|
|
204
|
+
key: randomBytes(32).toString("base64"),
|
|
205
|
+
keyId: "identity-key-v1",
|
|
206
|
+
secondaryKey: randomBytes(32).toString("base64"),
|
|
207
|
+
secondaryKeyId: "identity-key-v0",
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it("enables encryption from bootstrap material when no env key is set", () => {
|
|
211
|
+
const config = loadPayloadEncryptionConfig(bootstrapKeys());
|
|
212
|
+
expect(config?.primary.keyId).toBe("identity-key-v1");
|
|
213
|
+
expect(config?.primary.key.length).toBe(32);
|
|
214
|
+
expect(config?.secondary?.keyId).toBe("identity-key-v0");
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("env-configured key wins over bootstrap material", () => {
|
|
218
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_KEY = randomBytes(32).toString("base64");
|
|
219
|
+
process.env.STIGMER_PAYLOAD_ENCRYPTION_KEY_ID = "env-key";
|
|
220
|
+
|
|
221
|
+
const config = loadPayloadEncryptionConfig(bootstrapKeys());
|
|
222
|
+
expect(config?.primary.keyId).toBe("env-key");
|
|
223
|
+
expect(config?.secondary).toBeUndefined();
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("fails the boot on a bootstrap key without its id (server contract violation)", () => {
|
|
227
|
+
expect(() =>
|
|
228
|
+
loadPayloadEncryptionConfig({ key: randomBytes(32).toString("base64") }),
|
|
229
|
+
).toThrow(/payload_encryption_key_id/);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it("fails the boot on a malformed bootstrap key rather than running plaintext", () => {
|
|
233
|
+
expect(() =>
|
|
234
|
+
loadPayloadEncryptionConfig({
|
|
235
|
+
key: randomBytes(16).toString("base64"),
|
|
236
|
+
keyId: "identity-key-v1",
|
|
237
|
+
}),
|
|
238
|
+
).toThrow(/must decode to 32 bytes/);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it("fails the boot on a bootstrap secondary key without its id", () => {
|
|
242
|
+
expect(() =>
|
|
243
|
+
loadPayloadEncryptionConfig({
|
|
244
|
+
key: randomBytes(32).toString("base64"),
|
|
245
|
+
keyId: "identity-key-v1",
|
|
246
|
+
secondaryKey: randomBytes(32).toString("base64"),
|
|
247
|
+
}),
|
|
248
|
+
).toThrow(/payload_encryption_secondary_key_id/);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
describe("cross-language conformance fixture", () => {
|
|
254
|
+
// The committed fixture pins the envelope as a wire contract. A copy
|
|
255
|
+
// lives in stigmer-cloud (temporal-starter test resources) where the
|
|
256
|
+
// Java decode-only codec must decrypt it to the same payload. Never
|
|
257
|
+
// regenerate it casually: changing the fixture means changing the
|
|
258
|
+
// cross-SDK envelope, which requires both implementations to move in
|
|
259
|
+
// lockstep.
|
|
260
|
+
it("decrypts the committed fixture to the expected payload", async () => {
|
|
261
|
+
const fixture = JSON.parse(
|
|
262
|
+
readFileSync(join(__dirname, "fixtures", "encrypted-payload-fixture.json"), "utf-8"),
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const codec = new EncryptionPayloadCodec({
|
|
266
|
+
primary: {
|
|
267
|
+
keyId: fixture.keyId,
|
|
268
|
+
key: Buffer.from(fixture.keyBase64, "base64"),
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
const encrypted: Payload = {
|
|
273
|
+
metadata: Object.fromEntries(
|
|
274
|
+
Object.entries(fixture.encrypted.metadataBase64 as Record<string, string>).map(
|
|
275
|
+
([k, v]) => [k, Buffer.from(v, "base64")],
|
|
276
|
+
),
|
|
277
|
+
),
|
|
278
|
+
data: Buffer.from(fixture.encrypted.dataBase64, "base64"),
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const [decoded] = await codec.decode([encrypted]);
|
|
282
|
+
expect(metadataString(decoded, "encoding")).toBe("json/plain");
|
|
283
|
+
expect(Buffer.from(decoded.data!).toString("utf-8")).toBe(
|
|
284
|
+
fixture.original.dataJson,
|
|
285
|
+
);
|
|
286
|
+
});
|
|
287
|
+
});
|