@stigmer/runner 3.14.1 → 3.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/execution-record-fixture.d.ts +47 -0
- package/dist/__test-utils__/execution-record-fixture.js +68 -0
- package/dist/__test-utils__/execution-record-fixture.js.map +1 -0
- package/dist/__test-utils__/harness-contract/types.d.ts +166 -0
- package/dist/__test-utils__/harness-contract/types.js +49 -0
- package/dist/__test-utils__/harness-contract/types.js.map +1 -0
- package/dist/__test-utils__/hermetic-activity.d.ts +28 -5
- package/dist/__test-utils__/hermetic-activity.js +23 -7
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/mock-workspace.d.ts +15 -0
- package/dist/__test-utils__/mock-workspace.js +21 -0
- package/dist/__test-utils__/mock-workspace.js.map +1 -0
- package/dist/__test-utils__/model-registry-fixture.d.ts +56 -0
- package/dist/__test-utils__/model-registry-fixture.js +66 -0
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -0
- package/dist/__test-utils__/turn-input-fixture.d.ts +60 -0
- package/dist/__test-utils__/turn-input-fixture.js +118 -0
- package/dist/__test-utils__/turn-input-fixture.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +107 -0
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +344 -0
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +20 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +58 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +2 -32
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +38 -62
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +47 -121
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +17 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +27 -4
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.d.ts +52 -11
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js +66 -7
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +55 -0
- package/dist/activities/execute-cursor/adapter.js +119 -0
- package/dist/activities/execute-cursor/adapter.js.map +1 -0
- package/dist/activities/execute-cursor/approval-state.d.ts +2 -2
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/capture-flow.d.ts +15 -30
- package/dist/activities/execute-cursor/capture-flow.js +17 -26
- package/dist/activities/execute-cursor/capture-flow.js.map +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +23 -0
- package/dist/activities/execute-cursor/cursor-capabilities.js +33 -0
- package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -0
- package/dist/activities/execute-cursor/cursor-mcp-config.d.ts +2 -2
- package/dist/activities/execute-cursor/cursor-mcp-config.js.map +1 -1
- package/dist/activities/execute-cursor/fetch-interceptor.d.ts +15 -25
- package/dist/activities/execute-cursor/fetch-interceptor.js +39 -33
- package/dist/activities/execute-cursor/fetch-interceptor.js.map +1 -1
- package/dist/activities/execute-cursor/http2-interceptor.d.ts +21 -17
- package/dist/activities/execute-cursor/http2-interceptor.js +38 -31
- package/dist/activities/execute-cursor/http2-interceptor.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +28 -19
- package/dist/activities/execute-cursor/message-translator.js +76 -27
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +180 -11
- package/dist/activities/execute-cursor/prompt-builder.js +171 -0
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/rejection-capture.d.ts +3 -6
- package/dist/activities/execute-cursor/rejection-capture.js +5 -7
- package/dist/activities/execute-cursor/rejection-capture.js.map +1 -1
- package/dist/activities/execute-cursor/session-lifecycle.d.ts +1 -4
- package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-boundary.d.ts +1 -1
- package/dist/activities/execute-cursor/turn-settle.d.ts +49 -0
- package/dist/activities/execute-cursor/turn-settle.js +507 -0
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -0
- package/dist/activities/execute-cursor/turn-setup.d.ts +173 -0
- package/dist/activities/execute-cursor/turn-setup.js +496 -0
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -0
- package/dist/activities/execute-cursor/turn-stream.d.ts +41 -71
- package/dist/activities/execute-cursor/turn-stream.js +70 -135
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.d.ts +43 -0
- package/dist/activities/execute-cursor/turn.js +222 -0
- package/dist/activities/execute-cursor/turn.js.map +1 -0
- package/dist/activities/execute-cursor/usage-pricing.d.ts +38 -0
- package/dist/activities/execute-cursor/usage-pricing.js +50 -0
- package/dist/activities/execute-cursor/usage-pricing.js.map +1 -0
- package/dist/activities/execute-deep-agent/approval-file-change.d.ts +1 -1
- package/dist/activities/execute-deep-agent/approval-file-change.js +1 -1
- package/dist/activities/execute-deep-agent/environment.js +1 -1
- package/dist/activities/execute-deep-agent/environment.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.js +3 -2
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/hydrate-workflow-execution.js +1 -1
- package/dist/activities/hydrate-workflow-execution.js.map +1 -1
- package/dist/config.d.ts +15 -0
- package/dist/config.js.map +1 -1
- package/dist/harness/capabilities.d.ts +16 -0
- package/dist/harness/capabilities.js +1 -0
- package/dist/harness/capabilities.js.map +1 -1
- package/dist/harness/persist-chokepoint.d.ts +74 -0
- package/dist/harness/persist-chokepoint.js +88 -0
- package/dist/harness/persist-chokepoint.js.map +1 -0
- package/dist/harness/registry.d.ts +44 -5
- package/dist/harness/registry.js +61 -5
- package/dist/harness/registry.js.map +1 -1
- package/dist/harness/run-turn.d.ts +53 -0
- package/dist/harness/run-turn.js +528 -0
- package/dist/harness/run-turn.js.map +1 -0
- package/dist/harness/stop-controller.d.ts +50 -0
- package/dist/harness/stop-controller.js +62 -0
- package/dist/harness/stop-controller.js.map +1 -0
- package/dist/harness/terminal-table.d.ts +141 -0
- package/dist/harness/terminal-table.js +239 -0
- package/dist/harness/terminal-table.js.map +1 -0
- package/dist/harness/turn-context.d.ts +523 -0
- package/dist/harness/turn-context.js +739 -0
- package/dist/harness/turn-context.js.map +1 -0
- package/dist/harness/types.d.ts +232 -52
- package/dist/harness/types.js +17 -8
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage-accumulator.d.ts +68 -0
- package/dist/harness/usage-accumulator.js +101 -0
- package/dist/harness/usage-accumulator.js.map +1 -0
- package/dist/harness-adapters.d.ts +27 -0
- package/dist/harness-adapters.js +28 -0
- package/dist/harness-adapters.js.map +1 -0
- package/dist/main.js.map +1 -1
- package/dist/runner-manager.js +64 -48
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.d.ts +5 -4
- package/dist/runner.js +65 -64
- package/dist/runner.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +1 -1
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/{activities/execute-cursor → shared}/attachment-resolver.d.ts +2 -2
- package/dist/{activities/execute-cursor → shared}/attachment-resolver.js +5 -5
- package/dist/shared/attachment-resolver.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/blueprint-resolver.d.ts +7 -5
- package/dist/{activities/execute-cursor → shared}/blueprint-resolver.js +3 -63
- package/dist/shared/blueprint-resolver.js.map +1 -0
- package/dist/shared/channel-attachment.d.ts +1 -1
- package/dist/shared/channel-attachment.js.map +1 -1
- package/dist/{activities/execute-cursor → shared}/cost-guard.d.ts +5 -1
- package/dist/{activities/execute-cursor → shared}/cost-guard.js +5 -1
- package/dist/shared/cost-guard.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/env-resolver.d.ts +1 -1
- package/dist/shared/env-resolver.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/exact-apply.d.ts +1 -1
- package/dist/{activities/execute-cursor → shared}/exact-apply.js +6 -6
- package/dist/shared/exact-apply.js.map +1 -0
- package/dist/shared/execution-context.d.ts +35 -0
- package/dist/shared/execution-context.js +38 -0
- package/dist/shared/execution-context.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/extract-structured-output.d.ts +5 -2
- package/dist/{activities/execute-cursor → shared}/extract-structured-output.js +9 -6
- package/dist/shared/extract-structured-output.js.map +1 -0
- package/dist/shared/filereview/capture.d.ts +1 -1
- package/dist/shared/filereview/capture.js +1 -1
- package/dist/shared/heartbeat.d.ts +13 -11
- package/dist/shared/heartbeat.js +14 -29
- package/dist/shared/heartbeat.js.map +1 -1
- package/dist/{activities/execute-cursor → shared}/persist-decision.d.ts +5 -2
- package/dist/{activities/execute-cursor → shared}/persist-decision.js +4 -1
- package/dist/shared/persist-decision.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/skill-resolver.d.ts +16 -3
- package/dist/{activities/execute-cursor → shared}/skill-resolver.js +12 -4
- package/dist/shared/skill-resolver.js.map +1 -0
- package/dist/shared/subagent-rows.d.ts +21 -0
- package/dist/shared/subagent-rows.js +34 -0
- package/dist/shared/subagent-rows.js.map +1 -0
- package/dist/shared/worker-shutdown.d.ts +43 -16
- package/dist/shared/worker-shutdown.js +28 -13
- package/dist/shared/worker-shutdown.js.map +1 -1
- package/dist/shared/workspace/platform-dir.d.ts +1 -1
- package/dist/shared/workspace/platform-dir.js +1 -1
- package/dist/shared/workspace/session-provision.d.ts +54 -0
- package/dist/{activities/execute-cursor/workspace-provision.js → shared/workspace/session-provision.js} +15 -12
- package/dist/shared/workspace/session-provision.js.map +1 -0
- package/package.json +4 -4
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +110 -14
- package/src/__test-utils__/execution-record-fixture.ts +104 -0
- package/src/__test-utils__/harness-boot-order-child.ts +58 -0
- package/src/__test-utils__/harness-contract/contract.ts +128 -83
- package/src/__test-utils__/harness-contract/recording-sink.ts +15 -4
- package/src/__test-utils__/harness-contract/runtime-contract.ts +666 -0
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +92 -32
- package/src/__test-utils__/harness-contract/types.ts +85 -9
- package/src/__test-utils__/hermetic-activity.ts +33 -8
- package/src/__test-utils__/model-registry-fixture.ts +72 -0
- package/src/__test-utils__/module-specifiers.ts +82 -0
- package/src/__test-utils__/turn-input-fixture.ts +155 -0
- package/src/__tests__/harness-boot-order.test.ts +77 -0
- package/src/__tests__/harness-contract.test.ts +7 -5
- package/src/__tests__/runner-manager.test.ts +18 -0
- package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +102 -0
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +396 -0
- package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +66 -0
- package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +2 -43
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +65 -145
- package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +30 -4
- package/src/activities/execute-cursor/__test-utils__/scripted-sdk.ts +96 -8
- package/src/activities/execute-cursor/__tests__/adapter-is-temporal-free.test.ts +45 -0
- package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +90 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +7 -8
- package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +28 -1
- package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +64 -6
- package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/cost-cap.status.json +53 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/pause.status.json +1 -6
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/platform-stop.status.json +56 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/recovery-transport-timeout.status.json +48 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/run-cancelled.status.json +36 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/run-error-non-retryable.status.json +37 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +38 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/stall.status.json +59 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +79 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/worker-shutdown.status.json +2 -7
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +170 -0
- package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +22 -18
- package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/recovery-fresh-agent.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +286 -0
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +332 -0
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +193 -0
- package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +185 -0
- package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +151 -0
- package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +65 -35
- package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -40
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +171 -0
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +118 -243
- package/src/activities/execute-cursor/__tests__/usage-pricing.test.ts +84 -0
- package/src/activities/execute-cursor/adapter.ts +138 -0
- package/src/activities/execute-cursor/approval-state.ts +2 -2
- package/src/activities/execute-cursor/capture-flow.ts +18 -41
- package/src/activities/execute-cursor/cursor-capabilities.ts +35 -0
- package/src/activities/execute-cursor/cursor-mcp-config.ts +2 -2
- package/src/activities/execute-cursor/fetch-interceptor.ts +48 -45
- package/src/activities/execute-cursor/http2-interceptor.ts +47 -34
- package/src/activities/execute-cursor/message-translator.ts +90 -45
- package/src/activities/execute-cursor/prompt-builder.ts +327 -12
- package/src/activities/execute-cursor/rejection-capture.ts +5 -12
- package/src/activities/execute-cursor/session-lifecycle.ts +1 -5
- package/src/activities/execute-cursor/turn-boundary.ts +1 -1
- package/src/activities/execute-cursor/turn-settle.ts +601 -0
- package/src/activities/execute-cursor/turn-setup.ts +645 -0
- package/src/activities/execute-cursor/turn-stream.ts +84 -210
- package/src/activities/execute-cursor/turn.ts +240 -0
- package/src/activities/execute-cursor/usage-pricing.ts +67 -0
- package/src/activities/execute-deep-agent/approval-file-change.ts +1 -1
- package/src/activities/execute-deep-agent/environment.ts +1 -1
- package/src/activities/execute-deep-agent/setup.ts +3 -2
- package/src/activities/hydrate-workflow-execution.ts +1 -1
- package/src/config.ts +13 -0
- package/src/harness/__tests__/import-direction.test.ts +168 -0
- package/src/harness/__tests__/persist-chokepoint.test.ts +146 -0
- package/src/harness/__tests__/registry.test.ts +1 -0
- package/src/harness/__tests__/run-turn.test.ts +165 -0
- package/src/harness/__tests__/stop-controller.test.ts +49 -0
- package/src/harness/__tests__/turn-context.test.ts +178 -0
- package/src/harness/__tests__/usage-accumulator.test.ts +83 -0
- package/src/harness/capabilities.ts +17 -0
- package/src/harness/persist-chokepoint.ts +112 -0
- package/src/harness/registry.ts +79 -5
- package/src/harness/run-turn.ts +618 -0
- package/src/harness/stop-controller.ts +83 -0
- package/src/harness/terminal-table.ts +276 -0
- package/src/harness/turn-context.ts +1028 -0
- package/src/harness/types.ts +248 -53
- package/src/harness/usage-accumulator.ts +122 -0
- package/src/harness-adapters.ts +30 -0
- package/src/main.ts +1 -1
- package/src/runner-manager.ts +68 -61
- package/src/runner.ts +67 -78
- package/src/shared/__tests__/attachment-naming.test.ts +1 -1
- package/src/{activities/execute-cursor → shared}/__tests__/attachment-resolver.test.ts +6 -4
- package/src/{activities/execute-cursor → shared}/__tests__/cost-guard.test.ts +2 -1
- package/src/{activities/execute-cursor → shared}/__tests__/exact-apply.test.ts +3 -3
- package/src/{activities/execute-cursor → shared}/__tests__/extract-structured-output.test.ts +8 -8
- package/src/{activities/execute-cursor → shared}/__tests__/persist-decision.test.ts +4 -2
- package/src/{activities/execute-cursor → shared}/__tests__/skill-resolver.test.ts +1 -1
- package/src/shared/__tests__/subagent-rows.test.ts +34 -0
- package/src/shared/__tests__/worker-shutdown.test.ts +44 -39
- package/src/shared/approval-policy.ts +1 -1
- package/src/{activities/execute-cursor → shared}/attachment-resolver.ts +6 -6
- package/src/{activities/execute-cursor → shared}/blueprint-resolver.ts +7 -78
- package/src/shared/channel-attachment.ts +1 -1
- package/src/{activities/execute-cursor → shared}/cost-guard.ts +5 -1
- package/src/{activities/execute-cursor → shared}/env-resolver.ts +1 -1
- package/src/{activities/execute-cursor → shared}/exact-apply.ts +7 -7
- package/src/shared/execution-context.ts +45 -0
- package/src/{activities/execute-cursor → shared}/extract-structured-output.ts +10 -7
- package/src/shared/filereview/capture.ts +1 -1
- package/src/shared/heartbeat.ts +13 -33
- package/src/{activities/execute-cursor → shared}/persist-decision.ts +5 -2
- package/src/{activities/execute-cursor → shared}/skill-resolver.ts +20 -6
- package/src/shared/subagent-rows.ts +39 -0
- package/src/shared/worker-shutdown.ts +55 -25
- package/src/{activities/execute-cursor/__tests__/workspace-provision.test.ts → shared/workspace/__tests__/session-provision.test.ts} +25 -28
- package/src/shared/workspace/platform-dir.ts +1 -1
- package/src/{activities/execute-cursor/workspace-provision.ts → shared/workspace/session-provision.ts} +29 -16
- package/dist/activities/execute-cursor/attachment-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/blueprint-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/cost-guard.js.map +0 -1
- package/dist/activities/execute-cursor/env-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/exact-apply.js.map +0 -1
- package/dist/activities/execute-cursor/extract-structured-output.js.map +0 -1
- package/dist/activities/execute-cursor/index.d.ts +0 -209
- package/dist/activities/execute-cursor/index.js +0 -2345
- package/dist/activities/execute-cursor/index.js.map +0 -1
- package/dist/activities/execute-cursor/persist-decision.js.map +0 -1
- package/dist/activities/execute-cursor/skill-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/usage-accumulator.d.ts +0 -89
- package/dist/activities/execute-cursor/usage-accumulator.js +0 -121
- package/dist/activities/execute-cursor/usage-accumulator.js.map +0 -1
- package/dist/activities/execute-cursor/workspace-provision.d.ts +0 -42
- package/dist/activities/execute-cursor/workspace-provision.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/usage-accumulator.test.ts +0 -164
- package/src/activities/execute-cursor/index.ts +0 -2876
- package/src/activities/execute-cursor/usage-accumulator.ts +0 -169
- /package/dist/{activities/execute-cursor → shared}/env-resolver.js +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"messages": [
|
|
3
|
+
{
|
|
4
|
+
"type": "MESSAGE_AI",
|
|
5
|
+
"content": "Running the suite.",
|
|
6
|
+
"timestamp": "2026-01-01T00:00:02.000Z",
|
|
7
|
+
"toolCalls": [
|
|
8
|
+
{
|
|
9
|
+
"id": "call-hermetic-stall-0001",
|
|
10
|
+
"name": "shell",
|
|
11
|
+
"args": {
|
|
12
|
+
"command": "npm test"
|
|
13
|
+
},
|
|
14
|
+
"status": "TOOL_CALL_RUNNING",
|
|
15
|
+
"startedAt": "2026-01-01T00:00:03.000Z",
|
|
16
|
+
"requiresApproval": true,
|
|
17
|
+
"approvalMessage": "Run command: npm test",
|
|
18
|
+
"argsPreview": "{\"command\":\"npm test\"}",
|
|
19
|
+
"toolKind": "TOOL_KIND_SHELL",
|
|
20
|
+
"approvalPolicySource": "APPROVAL_POLICY_SOURCE_BUILTIN_CATEGORY",
|
|
21
|
+
"policyEngineVersion": "phase-7"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "MESSAGE_SYSTEM",
|
|
27
|
+
"content": "Execution failed: the agent made no progress for too long and was stopped (Agent stream stalled: no activity for 3s (last tool: shell)). You can retry or resume.",
|
|
28
|
+
"timestamp": "2026-01-01T00:00:06.000Z"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"phase": "EXECUTION_FAILED",
|
|
32
|
+
"error": "[StallTimeoutError] Agent stream stalled: no activity for 3s (last tool: shell). Retry or resume.",
|
|
33
|
+
"startedAt": "2026-01-01T00:00:00.000Z",
|
|
34
|
+
"completedAt": "2026-01-01T00:00:06.000Z",
|
|
35
|
+
"fileReviewEventStream": {
|
|
36
|
+
"executionId": "aex_hermetic_0001",
|
|
37
|
+
"events": [
|
|
38
|
+
{
|
|
39
|
+
"eventId": "aex_hermetic_0001:0:aex_hermetic_0001:0:FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
|
|
40
|
+
"changeSetId": "aex_hermetic_0001:0",
|
|
41
|
+
"eventType": "FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
|
|
42
|
+
"timestamp": "2026-01-01T00:00:00.000Z",
|
|
43
|
+
"actor": "runner",
|
|
44
|
+
"baselineCaptured": {
|
|
45
|
+
"changeSetId": "aex_hermetic_0001:0",
|
|
46
|
+
"turnId": "aex_hermetic_0001:0",
|
|
47
|
+
"harnessId": "cursor",
|
|
48
|
+
"baselineSnapshot": {
|
|
49
|
+
"kind": "SNAPSHOT_KIND_CAS_MANIFEST"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"fileChangeProgress": {
|
|
56
|
+
"changeSetId": "aex_hermetic_0001:0",
|
|
57
|
+
"capturedAt": "2026-01-01T00:00:01.000Z"
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"messages": [
|
|
3
|
+
{
|
|
4
|
+
"type": "MESSAGE_AI",
|
|
5
|
+
"content": "Removing the build directory.",
|
|
6
|
+
"timestamp": "2026-01-01T00:00:02.000Z",
|
|
7
|
+
"toolCalls": [
|
|
8
|
+
{
|
|
9
|
+
"id": "call-hermetic-hookblock-0001",
|
|
10
|
+
"name": "shell",
|
|
11
|
+
"args": {
|
|
12
|
+
"command": "rm -rf build"
|
|
13
|
+
},
|
|
14
|
+
"result": "blocked by a hook",
|
|
15
|
+
"status": "TOOL_CALL_FAILED",
|
|
16
|
+
"completedAt": "2026-01-01T00:00:03.000Z",
|
|
17
|
+
"error": "blocked by a hook",
|
|
18
|
+
"requiresApproval": true,
|
|
19
|
+
"approvalMessage": "Run command: rm -rf build",
|
|
20
|
+
"approvalRequestedAt": "2026-01-01T00:00:03.000Z",
|
|
21
|
+
"argsPreview": "{\"command\":\"rm -rf build\"}",
|
|
22
|
+
"toolKind": "TOOL_KIND_SHELL",
|
|
23
|
+
"approvalPolicySource": "APPROVAL_POLICY_SOURCE_BUILTIN_CATEGORY",
|
|
24
|
+
"policyEngineVersion": "phase-7"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "MESSAGE_AI",
|
|
30
|
+
"content": "I could not clean the build directory: the shell command was blocked.",
|
|
31
|
+
"timestamp": "2026-01-01T00:00:04.000Z"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"type": "MESSAGE_SYSTEM",
|
|
35
|
+
"content": "Execution failed: A Cursor hook outside Stigmer's approval gate blocked tool(s): shell. The workspace's .cursor/hooks.json registers hook(s) outside Stigmer's control [./scripts/team-policy-hook.sh], which most likely denied it. Stigmer cannot request approval on a foreign hook's behalf — remove or adjust the hook in .cursor/hooks.json and retry.",
|
|
36
|
+
"timestamp": "2026-01-01T00:00:06.000Z"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"phase": "EXECUTION_FAILED",
|
|
40
|
+
"error": "A Cursor hook outside Stigmer's approval gate blocked tool(s): shell. The workspace's .cursor/hooks.json registers hook(s) outside Stigmer's control [./scripts/team-policy-hook.sh], which most likely denied it. Stigmer cannot request approval on a foreign hook's behalf — remove or adjust the hook in .cursor/hooks.json and retry.",
|
|
41
|
+
"startedAt": "2026-01-01T00:00:00.000Z",
|
|
42
|
+
"completedAt": "2026-01-01T00:00:06.000Z",
|
|
43
|
+
"streamingUsage": {
|
|
44
|
+
"inputTokens": "1500",
|
|
45
|
+
"outputTokens": "40",
|
|
46
|
+
"totalTokens": "1540",
|
|
47
|
+
"turnCount": 1,
|
|
48
|
+
"estimatedCostUsd": 0.00166,
|
|
49
|
+
"model": "composer-2.5",
|
|
50
|
+
"observedAt": "2026-01-01T00:00:05.000Z",
|
|
51
|
+
"requestedServiceTier": "SERVICE_TIER_STANDARD",
|
|
52
|
+
"requestedModelParams": "[{\"id\":\"fast\",\"value\":\"false\"},{\"id\":\"thinking\",\"value\":\"false\"}]",
|
|
53
|
+
"requestedThinkingMode": "THINKING_MODE_DISABLED"
|
|
54
|
+
},
|
|
55
|
+
"fileReviewEventStream": {
|
|
56
|
+
"executionId": "aex_hermetic_0001",
|
|
57
|
+
"events": [
|
|
58
|
+
{
|
|
59
|
+
"eventId": "aex_hermetic_0001:0:aex_hermetic_0001:0:FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
|
|
60
|
+
"changeSetId": "aex_hermetic_0001:0",
|
|
61
|
+
"eventType": "FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
|
|
62
|
+
"timestamp": "2026-01-01T00:00:00.000Z",
|
|
63
|
+
"actor": "runner",
|
|
64
|
+
"baselineCaptured": {
|
|
65
|
+
"changeSetId": "aex_hermetic_0001:0",
|
|
66
|
+
"turnId": "aex_hermetic_0001:0",
|
|
67
|
+
"harnessId": "cursor",
|
|
68
|
+
"baselineSnapshot": {
|
|
69
|
+
"kind": "SNAPSHOT_KIND_CAS_MANIFEST"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"fileChangeProgress": {
|
|
76
|
+
"changeSetId": "aex_hermetic_0001:0",
|
|
77
|
+
"capturedAt": "2026-01-01T00:00:01.000Z"
|
|
78
|
+
}
|
|
79
|
+
}
|
package/src/activities/execute-cursor/__tests__/hermetic/goldens/worker-shutdown.status.json
CHANGED
|
@@ -8,18 +8,13 @@
|
|
|
8
8
|
{
|
|
9
9
|
"type": "MESSAGE_SYSTEM",
|
|
10
10
|
"content": "Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",
|
|
11
|
-
"timestamp": "2026-01-01T00:00:
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"type": "MESSAGE_SYSTEM",
|
|
15
|
-
"content": "Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",
|
|
16
|
-
"timestamp": "2026-01-01T00:00:04.000Z"
|
|
11
|
+
"timestamp": "2026-01-01T00:00:03.000Z"
|
|
17
12
|
}
|
|
18
13
|
],
|
|
19
14
|
"phase": "EXECUTION_FAILED",
|
|
20
15
|
"error": "Execution interrupted: runner worker was shut down. Retry or resume.",
|
|
21
16
|
"startedAt": "2026-01-01T00:00:00.000Z",
|
|
22
|
-
"completedAt": "2026-01-01T00:00:
|
|
17
|
+
"completedAt": "2026-01-01T00:00:03.000Z",
|
|
23
18
|
"fileReviewEventStream": {
|
|
24
19
|
"executionId": "aex_hermetic_0001",
|
|
25
20
|
"events": [
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The harness contract kit, BOTH halves, against the REAL Cursor adapter.
|
|
3
|
+
*
|
|
4
|
+
* The adapter-side half (`__test-utils__/harness-contract/contract.ts`) is the
|
|
5
|
+
* single statement of what every `HarnessAdapter` owes the runtime;
|
|
6
|
+
* `src/__tests__/harness-contract.test.ts` runs it against the scripted fake
|
|
7
|
+
* under both pause primitives. The runtime-side half
|
|
8
|
+
* (`__test-utils__/harness-contract/runtime-contract.ts`) is what the turn
|
|
9
|
+
* runtime owes every harness, through the real activity under
|
|
10
|
+
* `MockActivityEnvironment`; `harness/__tests__/run-turn.test.ts` runs it
|
|
11
|
+
* against the fake. This file runs BOTH against `createCursorAdapter()`
|
|
12
|
+
* through the Cursor subject (`__test-utils__/contract-subject.ts`), which
|
|
13
|
+
* translates the kit's scenarios onto S0's scripted `@cursor/sdk` double and
|
|
14
|
+
* runs the REAL bash preToolUse hook the adapter installs for every gated
|
|
15
|
+
* proposal. Nothing of the adapter is mocked; the SDK and the control-plane
|
|
16
|
+
* client are the two doubles every hermetic golden already substitutes.
|
|
17
|
+
*
|
|
18
|
+
* Every runtime arm here has a golden twin under `goldens/`; the goldens pin
|
|
19
|
+
* the transcript byte for byte, the kit asserts the contract facts in words
|
|
20
|
+
* any harness can satisfy. The `actionable` failure arm is registered
|
|
21
|
+
* SKIPPED: only the unattributed-hook-block path produces that surface on
|
|
22
|
+
* this harness (`unattributed-hook-block.test.ts` pins it), and the kit's
|
|
23
|
+
* vocabulary has no word for it.
|
|
24
|
+
*
|
|
25
|
+
* Beside the kit, the Cursor-only observations the kit's vocabulary cannot
|
|
26
|
+
* express: the agent the SDK minted is CLOSED when the session write behind
|
|
27
|
+
* `bindHarnessState` rejects (S2 M4 finding F5, an M3b regression the kit's
|
|
28
|
+
* rejected-bind leg exposed — before the fix the handle leaked its executor
|
|
29
|
+
* lease and MCP subprocesses; Q-M4-8); the SDK is asked to create one agent
|
|
30
|
+
* per session and never to resume (the parked handle serves every later
|
|
31
|
+
* turn, #215); a DISOBEDIENT re-issue after a SKIP is denied by the hook and
|
|
32
|
+
* never executes (what makes the subject's "obedient model" modelling safe);
|
|
33
|
+
* a later proposal of an identity the user already approved and the agent
|
|
34
|
+
* already ran gets its OWN gate and inherits nothing — the approval bleed the
|
|
35
|
+
* kit's invariant 3 found in this adapter (S2 M4 finding F9;
|
|
36
|
+
* `same-identity-reproposal.test.ts` pins the translator's rule); and the
|
|
37
|
+
* hook agreed with the subject's model of it at every proposal.
|
|
38
|
+
*
|
|
39
|
+
* Needs `bash` (the hook) — skipped where it is unavailable, reported as
|
|
40
|
+
* SKIPPED, never a silent pass. The hermetic environment (temp `HOME` for the
|
|
41
|
+
* gate's per-session artifacts, temp workspace root) is created at module
|
|
42
|
+
* level because the subject's `config` is read at collection time; the forks
|
|
43
|
+
* pool keeps it private to this file. No golden: the kit asserts behaviour,
|
|
44
|
+
* the goldens under `goldens/` pin transcripts.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
|
48
|
+
import { ApprovalAction, ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
49
|
+
|
|
50
|
+
vi.mock("@cursor/sdk", async () =>
|
|
51
|
+
(await import("../../__test-utils__/scripted-sdk.js")).scriptedCursorSdkModule(),
|
|
52
|
+
);
|
|
53
|
+
vi.mock("../../../../client/stigmer-client.js", async () =>
|
|
54
|
+
(await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
import { approvalDecisionsOf } from "../../../../harness/turn-context.js";
|
|
58
|
+
import { ExecutionDriver, describeHarnessContract } from "../../../../__test-utils__/harness-contract/contract.js";
|
|
59
|
+
import { RecordingTurnSink } from "../../../../__test-utils__/harness-contract/recording-sink.js";
|
|
60
|
+
import { describeHarnessRuntimeContract } from "../../../../__test-utils__/harness-contract/runtime-contract.js";
|
|
61
|
+
import { scenario } from "../../../../__test-utils__/harness-contract/types.js";
|
|
62
|
+
import { ScriptedClock, createHermeticEnvironment } from "../../../../__test-utils__/hermetic-activity.js";
|
|
63
|
+
import { stubRegistryFetch } from "../../../../__test-utils__/model-registry-fixture.js";
|
|
64
|
+
import { findToolCallRow } from "../../../../__test-utils__/proto-helpers.js";
|
|
65
|
+
import { createCursorContractSubject } from "../../__test-utils__/contract-subject.js";
|
|
66
|
+
import { hasBash } from "../../__test-utils__/cursor-hook-harness.js";
|
|
67
|
+
import { resetCursorModuleState } from "../../__test-utils__/hermetic-cursor.js";
|
|
68
|
+
|
|
69
|
+
const env = createHermeticEnvironment();
|
|
70
|
+
const clock = new ScriptedClock();
|
|
71
|
+
const subject = createCursorContractSubject(env);
|
|
72
|
+
const WRITE_GAMMA = { kind: "write", resource: "/work/gamma.txt" } as const;
|
|
73
|
+
|
|
74
|
+
describe.skipIf(!hasBash)("ExecuteCursor hermetic — the harness contract kit against the real adapter", () => {
|
|
75
|
+
let registry: ReturnType<typeof stubRegistryFetch>;
|
|
76
|
+
|
|
77
|
+
beforeAll(() => {
|
|
78
|
+
// Once, never between turns: a parked agent must survive turn 1 into
|
|
79
|
+
// turn 2 as it does in a live worker.
|
|
80
|
+
resetCursorModuleState();
|
|
81
|
+
registry = stubRegistryFetch();
|
|
82
|
+
clock.install();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
afterAll(() => {
|
|
86
|
+
clock.uninstall();
|
|
87
|
+
registry.restore();
|
|
88
|
+
env.dispose();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describeHarnessContract(subject);
|
|
92
|
+
describeHarnessRuntimeContract({ subject, env, clock }, { failureSurfaces: ["engine", "internal"] });
|
|
93
|
+
|
|
94
|
+
describe("cursor-only observations", () => {
|
|
95
|
+
beforeAll(async () => {
|
|
96
|
+
await subject.adapter.boot(subject.config);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("closes the agent the SDK minted when the session write behind bindHarnessState rejects (F5)", async () => {
|
|
100
|
+
const driver = new ExecutionDriver(subject, "obs-bind-rejects");
|
|
101
|
+
const rejecting = new RecordingTurnSink({ bindRejectsWith: new Error("session write refused") });
|
|
102
|
+
|
|
103
|
+
const { outcome } = await driver.turn([scenario.say("never sent")], { sink: rejecting });
|
|
104
|
+
|
|
105
|
+
expect(outcome.kind).toBe("failed");
|
|
106
|
+
const agent = subject.agentFor(driver.sessionId);
|
|
107
|
+
expect(agent, "the SDK minted an agent for the session").toBeDefined();
|
|
108
|
+
expect(agent!.sends, "nothing was sent to it").toHaveLength(0);
|
|
109
|
+
expect(agent!.closeCalls, "and it was closed, not leaked: its id was never saved, so no later turn can resume it").toBe(1);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("asks the SDK to create one agent per session and never to resume it (#215: the parked handle serves every later turn)", async () => {
|
|
113
|
+
const driver = new ExecutionDriver(subject, "obs-one-create");
|
|
114
|
+
|
|
115
|
+
const first = await driver.turn([scenario.say("first")]);
|
|
116
|
+
const second = await driver.turn([scenario.say("second")]);
|
|
117
|
+
|
|
118
|
+
expect(first.outcome.kind).toBe("completed");
|
|
119
|
+
expect(second.outcome.kind).toBe("completed");
|
|
120
|
+
const agent = subject.agentFor(driver.sessionId)!;
|
|
121
|
+
const resolutions = subject.sdk.resolutions.filter((r) => r.agentId === agent.agentId);
|
|
122
|
+
expect(resolutions.map((r) => r.kind), "one create, no resume").toEqual(["create"]);
|
|
123
|
+
expect(agent.sends, "both turns went to the same parked agent").toHaveLength(2);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("denies a disobedient re-issue after a SKIP: the action never executes and the turn re-gates", async () => {
|
|
127
|
+
const driver = new ExecutionDriver(subject, "obs-disobedient");
|
|
128
|
+
const id = "obs-disobedient-write";
|
|
129
|
+
|
|
130
|
+
const proposed = await driver.turn([scenario.propose(id, WRITE_GAMMA)]);
|
|
131
|
+
expect(proposed.outcome.kind).toBe("awaiting_approval");
|
|
132
|
+
driver.decide(id, ApprovalAction.SKIP);
|
|
133
|
+
|
|
134
|
+
subject.forceReissue(id);
|
|
135
|
+
const reissued = await driver.turn([scenario.propose(id, WRITE_GAMMA), scenario.say("never reached")]);
|
|
136
|
+
|
|
137
|
+
expect(subject.executionCount(id), "the hook denied the re-issue; nothing ran").toBe(0);
|
|
138
|
+
expect(reissued.outcome.kind, "a fresh gated act pauses the turn again").toBe("awaiting_approval");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("gates a later proposal of an already-approved-and-run identity on its own row; the executed row and its decision stand (F9)", async () => {
|
|
142
|
+
const driver = new ExecutionDriver(subject, "obs-reproposal");
|
|
143
|
+
const first = "obs-reproposal-first";
|
|
144
|
+
const later = "obs-reproposal-later";
|
|
145
|
+
|
|
146
|
+
const proposed = await driver.turn([scenario.propose(first, WRITE_GAMMA)]);
|
|
147
|
+
expect(proposed.outcome.kind).toBe("awaiting_approval");
|
|
148
|
+
driver.decide(first, ApprovalAction.APPROVE);
|
|
149
|
+
const ran = await driver.turn([scenario.propose(first, WRITE_GAMMA), scenario.say("written")]);
|
|
150
|
+
expect(ran.outcome.kind).toBe("completed");
|
|
151
|
+
expect(subject.executionCount(first)).toBe(1);
|
|
152
|
+
|
|
153
|
+
const again = await driver.turn([scenario.say("once more"), scenario.propose(later, WRITE_GAMMA)]);
|
|
154
|
+
|
|
155
|
+
expect(again.outcome.kind, "a new act of the same identity is gated afresh").toBe("awaiting_approval");
|
|
156
|
+
expect(subject.executionCount(later), "and did not run under the earlier approval").toBe(0);
|
|
157
|
+
const firstRow = findToolCallRow(again.sink.status, first)!;
|
|
158
|
+
expect(firstRow.status, "the executed row is never rewritten").toBe(ToolCallStatus.TOOL_CALL_COMPLETED);
|
|
159
|
+
expect(firstRow.approvalAction).toBe(ApprovalAction.APPROVE);
|
|
160
|
+
const laterRow = findToolCallRow(again.sink.status, later);
|
|
161
|
+
expect(laterRow?.status, "the new act has its own WAITING row").toBe(ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
|
|
162
|
+
expect(laterRow?.approvalAction, "undecided").toBe(ApprovalAction.UNSPECIFIED);
|
|
163
|
+
expect(approvalDecisionsOf(again.sink.status).size, "the runtime would read no decision for it").toBe(0);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("the hook agreed with the subject's model of it at every proposal", () => {
|
|
167
|
+
expect(subject.hookDisagreements).toEqual([]);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
});
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Hermetic goldens: USER PAUSE versus WORKER SHUTDOWN — the two interruptions
|
|
3
3
|
* that THROW, and the byte-pinned copy that tells them apart.
|
|
4
4
|
*
|
|
5
|
-
* Invariant pinned (the throw-vs-return table the runtime
|
|
6
|
-
* §5c): both interruptions end the activity with a thrown Temporal
|
|
5
|
+
* Invariant pinned (the throw-vs-return table the runtime owns,
|
|
6
|
+
* `harness/terminal-table.ts`; parent §5c): both interruptions end the activity with a thrown Temporal
|
|
7
7
|
* `CancelledFailure` (never a return), but they persist DIFFERENT terminal
|
|
8
8
|
* states the control plane keys on:
|
|
9
9
|
*
|
|
@@ -22,17 +22,25 @@
|
|
|
22
22
|
* stream loop sees `isCancelled()` on its next iteration and never processes
|
|
23
23
|
* the event that follows.
|
|
24
24
|
*
|
|
25
|
-
* What the goldens ALSO pin
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* (
|
|
25
|
+
* What the goldens ALSO pin: each path appends its system message exactly
|
|
26
|
+
* ONCE. The orchestrator this net was recorded on appended it twice — once in
|
|
27
|
+
* `resolvePreBoundaryTerminal` before the throw, once again in the outer
|
|
28
|
+
* `catch (CancelledFailure)`, which re-stamped and re-persisted — and the
|
|
29
|
+
* goldens pinned that double on purpose so S2 could reproduce the wire byte
|
|
30
|
+
* for byte (stigmer#1054, Q-S2-4). The runtime's `settleWith` is now the one
|
|
31
|
+
* writer of a terminal arm, so a second row has no code path to come from.
|
|
31
32
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
33
|
+
* Runtime phases exercised: the adapter's stop-signal cancel; the runtime's
|
|
34
|
+
* `classifyTurnInterruption`; the terminal table's pause and worker-shutdown
|
|
35
|
+
* arms through `settleWith`; the `finally` teardown under a thrown exit.
|
|
36
|
+
*
|
|
37
|
+
* Regeneration history:
|
|
38
|
+
* - S2 M3b (entry 20260911.03): timestamp-only diff — every terminal stamp
|
|
39
|
+
* one scripted second earlier: the adapter cancels the SDK run the instant
|
|
40
|
+
* the runtime's stop signal aborts (Q-M3-4), before the SDK double pulls,
|
|
41
|
+
* and the clock ticks on, one more step. Transcript unchanged.
|
|
42
|
+
* - 2026-09-12 (stigmer#1054, the PR after S2): one removed system row per
|
|
43
|
+
* golden, nothing else. The transcript now carries each terminal row once.
|
|
36
44
|
*
|
|
37
45
|
* Regenerate ONLY after a deliberate behavior change:
|
|
38
46
|
* npx vitest run src/activities/execute-cursor/__tests__/hermetic -u
|
|
@@ -63,8 +71,8 @@ import {
|
|
|
63
71
|
beginCursorScenario,
|
|
64
72
|
cursorExecutionRecord,
|
|
65
73
|
runCursorTurn,
|
|
66
|
-
stubRegistryFetch,
|
|
67
74
|
} from "../../__test-utils__/hermetic-cursor.js";
|
|
75
|
+
import { stubRegistryFetch } from "../../../../__test-utils__/model-registry-fixture.js";
|
|
68
76
|
|
|
69
77
|
const USER_MESSAGE = "Refactor the parser module.";
|
|
70
78
|
const NEVER_SEEN = "This text must never reach the transcript.";
|
|
@@ -144,10 +152,7 @@ describe("ExecuteCursor hermetic — user pause vs worker shutdown", () => {
|
|
|
144
152
|
expect(final.completedAt, "a paused turn is not complete").toBe("");
|
|
145
153
|
expect(
|
|
146
154
|
final.messages.filter((m) => m.type === MessageType.MESSAGE_SYSTEM).map((m) => m.content),
|
|
147
|
-
).toEqual([
|
|
148
|
-
"Execution paused by user. Use resume to continue.",
|
|
149
|
-
"Execution paused by user. Use resume to continue.",
|
|
150
|
-
]);
|
|
155
|
+
).toEqual(["Execution paused by user. Use resume to continue."]);
|
|
151
156
|
expect(final.messages.some((m) => m.content === NEVER_SEEN), "nothing after the cancel is processed").toBe(false);
|
|
152
157
|
|
|
153
158
|
const json = JSON.stringify(toJson(AgentExecutionStatusSchema, final), null, 2) + "\n";
|
|
@@ -191,7 +196,6 @@ describe("ExecuteCursor hermetic — user pause vs worker shutdown", () => {
|
|
|
191
196
|
final.messages.filter((m) => m.type === MessageType.MESSAGE_SYSTEM).map((m) => m.content),
|
|
192
197
|
).toEqual([
|
|
193
198
|
"Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",
|
|
194
|
-
"Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",
|
|
195
199
|
]);
|
|
196
200
|
expect(final.messages.some((m) => m.content === NEVER_SEEN)).toBe(false);
|
|
197
201
|
|
|
@@ -53,8 +53,8 @@ import {
|
|
|
53
53
|
beginCursorScenario,
|
|
54
54
|
cursorExecutionRecord,
|
|
55
55
|
runCursorTurn,
|
|
56
|
-
stubRegistryFetch,
|
|
57
56
|
} from "../../__test-utils__/hermetic-cursor.js";
|
|
57
|
+
import { stubRegistryFetch } from "../../../../__test-utils__/model-registry-fixture.js";
|
|
58
58
|
|
|
59
59
|
const AGENT_ID = "agent-hermetic-plain-0001";
|
|
60
60
|
const RUN_ID = "run-hermetic-plain-0001";
|
|
@@ -49,8 +49,8 @@ import {
|
|
|
49
49
|
beginCursorScenario,
|
|
50
50
|
cursorExecutionRecord,
|
|
51
51
|
runCursorTurn,
|
|
52
|
-
stubRegistryFetch,
|
|
53
52
|
} from "../../__test-utils__/hermetic-cursor.js";
|
|
53
|
+
import { stubRegistryFetch } from "../../../../__test-utils__/model-registry-fixture.js";
|
|
54
54
|
|
|
55
55
|
const STALE_AGENT_ID = "agent-hermetic-stale-0001";
|
|
56
56
|
const FRESH_AGENT_ID = "agent-hermetic-fresh-0002";
|