@stigmer/runner 3.15.1 → 3.15.2-dev.20260913223433
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 +2 -4
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/execution-record-fixture.d.ts +14 -0
- package/dist/__test-utils__/execution-record-fixture.js +4 -0
- package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
- package/dist/__test-utils__/file-review-projection.d.ts +40 -0
- package/dist/__test-utils__/file-review-projection.js +136 -0
- package/dist/__test-utils__/file-review-projection.js.map +1 -0
- package/dist/__test-utils__/harness-contract/types.d.ts +23 -1
- package/dist/__test-utils__/harness-contract/types.js +15 -0
- package/dist/__test-utils__/harness-contract/types.js.map +1 -1
- package/dist/__test-utils__/hermetic-activity.d.ts +44 -12
- package/dist/__test-utils__/hermetic-activity.js +52 -14
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/model-registry-fixture.d.ts +32 -7
- package/dist/__test-utils__/model-registry-fixture.js +31 -7
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
- package/dist/__test-utils__/turn-input-fixture.d.ts +1 -1
- package/dist/__test-utils__/turn-input-fixture.js +1 -1
- package/dist/__test-utils__/turn-input-fixture.js.map +1 -1
- package/dist/activities/call-agent.js +2 -2
- package/dist/activities/call-agent.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +45 -3
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +0 -9
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +2 -41
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +7 -5
- package/dist/activities/execute-cursor/adapter.js +7 -5
- package/dist/activities/execute-cursor/adapter.js.map +1 -1
- package/dist/activities/execute-cursor/approval-policy.d.ts +5 -2
- package/dist/activities/execute-cursor/approval-policy.js +5 -2
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +16 -8
- package/dist/activities/execute-cursor/approval-state.js +6 -3
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/cas-observations.d.ts +14 -2
- package/dist/activities/execute-cursor/cas-observations.js +19 -2
- package/dist/activities/execute-cursor/cas-observations.js.map +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +8 -4
- package/dist/activities/execute-cursor/cursor-capabilities.js +21 -4
- package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +12 -20
- package/dist/activities/execute-cursor/message-translator.js +19 -32
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +48 -58
- package/dist/activities/execute-cursor/prompt-builder.js +76 -95
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/turn-boundary.d.ts +27 -55
- package/dist/activities/execute-cursor/turn-boundary.js +30 -90
- package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
- package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
- package/dist/activities/execute-cursor/turn-settle.js +37 -49
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-setup.d.ts +16 -24
- package/dist/activities/execute-cursor/turn-setup.js +29 -59
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.d.ts +3 -8
- package/dist/activities/execute-cursor/turn-stream.js +9 -22
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.js +5 -1
- package/dist/activities/execute-cursor/turn.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +93 -0
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +348 -0
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +170 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +225 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.d.ts +24 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +41 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +54 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +72 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +187 -23
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +238 -27
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
- package/dist/activities/execute-deep-agent/adapter.d.ts +41 -0
- package/dist/activities/execute-deep-agent/adapter.js +78 -0
- package/dist/activities/execute-deep-agent/adapter.js.map +1 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +8 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js +9 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -1
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +31 -0
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +40 -0
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js.map +1 -0
- package/dist/activities/execute-deep-agent/execution-state.d.ts +4 -11
- package/dist/activities/execute-deep-agent/execution-state.js +4 -12
- package/dist/activities/execute-deep-agent/execution-state.js.map +1 -1
- package/dist/activities/execute-deep-agent/hitl.d.ts +49 -47
- package/dist/activities/execute-deep-agent/hitl.js +77 -103
- package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +51 -23
- package/dist/activities/execute-deep-agent/prompt-builder.js +115 -76
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +18 -32
- package/dist/activities/execute-deep-agent/status-builder-shared.js +10 -65
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +10 -8
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +12 -14
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +36 -13
- package/dist/activities/execute-deep-agent/subagent-tracker.js +76 -39
- package/dist/activities/execute-deep-agent/subagent-tracker.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -28
- package/dist/activities/execute-deep-agent/subagent-transformer.js +29 -82
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +3 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js +2 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-settle.d.ts +42 -0
- package/dist/activities/execute-deep-agent/turn-settle.js +146 -0
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +212 -0
- package/dist/activities/execute-deep-agent/turn-setup.js +430 -0
- package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +97 -0
- package/dist/activities/execute-deep-agent/turn-stream.js +242 -0
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn.d.ts +42 -0
- package/dist/activities/execute-deep-agent/turn.js +116 -0
- package/dist/activities/execute-deep-agent/turn.js.map +1 -0
- package/dist/activities/execute-deep-agent/v3-event-recorder.d.ts +6 -5
- package/dist/activities/execute-deep-agent/v3-event-recorder.js +6 -5
- package/dist/activities/execute-deep-agent/v3-event-recorder.js.map +1 -1
- package/dist/activities/execute-deep-agent/v3-events.d.ts +1 -1
- package/dist/activities/execute-deep-agent/v3-events.js +1 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +60 -17
- package/dist/activities/execute-deep-agent/v3-status-builder.js +72 -57
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
- package/dist/harness/approval-decisions.d.ts +61 -0
- package/dist/harness/approval-decisions.js +102 -0
- package/dist/harness/approval-decisions.js.map +1 -0
- package/dist/harness/capabilities.d.ts +16 -5
- package/dist/harness/capabilities.js +9 -0
- package/dist/harness/capabilities.js.map +1 -1
- package/dist/harness/capture.d.ts +144 -0
- package/dist/harness/capture.js +219 -0
- package/dist/harness/capture.js.map +1 -0
- package/dist/harness/persist-chokepoint.d.ts +19 -4
- package/dist/harness/persist-chokepoint.js +17 -4
- package/dist/harness/persist-chokepoint.js.map +1 -1
- package/dist/harness/run-turn.js +115 -29
- package/dist/harness/run-turn.js.map +1 -1
- package/dist/harness/terminal-table.d.ts +40 -11
- package/dist/harness/terminal-table.js +58 -19
- package/dist/harness/terminal-table.js.map +1 -1
- package/dist/harness/turn-context.d.ts +141 -76
- package/dist/harness/turn-context.js +194 -99
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/harness/types.d.ts +65 -12
- package/dist/harness/types.js +8 -2
- package/dist/harness/types.js.map +1 -1
- package/dist/harness-adapters.d.ts +12 -8
- package/dist/harness-adapters.js +17 -9
- package/dist/harness-adapters.js.map +1 -1
- package/dist/middleware/approval-gate.d.ts +1 -1
- package/dist/middleware/approval-gate.js +1 -1
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +39 -0
- package/dist/middleware/{cost-cap.js → cost-advisory.js} +37 -55
- package/dist/middleware/cost-advisory.js.map +1 -0
- package/dist/middleware/index.d.ts +23 -12
- package/dist/middleware/index.js +26 -18
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/types.d.ts +3 -2
- package/dist/runner-manager.js +1 -5
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +1 -5
- package/dist/runner.js.map +1 -1
- package/dist/shared/attachment-resolver.d.ts +41 -18
- package/dist/shared/attachment-resolver.js +178 -46
- package/dist/shared/attachment-resolver.js.map +1 -1
- package/dist/shared/attachment-zip.d.ts +85 -0
- package/dist/shared/attachment-zip.js +185 -0
- package/dist/shared/attachment-zip.js.map +1 -0
- package/dist/shared/connect-backfill.js +5 -4
- package/dist/shared/connect-backfill.js.map +1 -1
- package/dist/shared/cost-guard.d.ts +3 -3
- package/dist/shared/cost-guard.js +3 -3
- package/dist/shared/execution-status-writer.d.ts +5 -5
- package/dist/shared/execution-status-writer.js +5 -5
- package/dist/shared/extract-structured-output.d.ts +8 -7
- package/dist/shared/extract-structured-output.js +8 -7
- package/dist/shared/extract-structured-output.js.map +1 -1
- package/dist/shared/filereview/cas-progress.d.ts +1 -18
- package/dist/shared/filereview/cas-progress.js +4 -0
- package/dist/shared/filereview/cas-progress.js.map +1 -1
- package/dist/shared/filereview/cas-touched.d.ts +56 -0
- package/dist/shared/filereview/cas-touched.js +63 -0
- package/dist/shared/filereview/cas-touched.js.map +1 -0
- package/dist/shared/filereview/index.d.ts +2 -1
- package/dist/shared/filereview/index.js +2 -1
- package/dist/shared/filereview/index.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +4 -5
- package/dist/shared/mcp-resolver.js +4 -5
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/persist-decision.d.ts +3 -4
- package/dist/shared/persist-decision.js +3 -4
- package/dist/shared/persist-decision.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +2 -2
- package/dist/shared/plan-mode-permissions.js +2 -2
- package/dist/shared/plan-mode-prompt.d.ts +1 -1
- package/dist/shared/plan-mode-prompt.js +1 -1
- package/dist/shared/prompt-sections.d.ts +163 -0
- package/dist/shared/prompt-sections.js +164 -0
- package/dist/shared/prompt-sections.js.map +1 -0
- package/dist/shared/skill-resolver.d.ts +4 -2
- package/dist/shared/skill-resolver.js +4 -2
- package/dist/shared/skill-resolver.js.map +1 -1
- package/dist/shared/tool-rounds.d.ts +32 -0
- package/dist/shared/tool-rounds.js +43 -0
- package/dist/shared/tool-rounds.js.map +1 -1
- package/dist/shared/tool-row.d.ts +34 -0
- package/dist/shared/tool-row.js +52 -0
- package/dist/shared/tool-row.js.map +1 -1
- package/dist/shared/workspace/session-provision.d.ts +3 -3
- package/dist/shared/workspace/session-provision.js +3 -3
- package/dist/shared/workspace/stigmer-link.d.ts +3 -3
- package/dist/shared/workspace/stigmer-link.js +3 -3
- package/dist/shared/workspace/writeback-coordinator.d.ts +15 -22
- package/dist/shared/workspace/writeback-coordinator.js +16 -53
- package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/package.json +4 -4
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +1 -0
- package/src/__test-utils__/execution-record-fixture.ts +18 -2
- package/src/__test-utils__/file-review-projection.ts +156 -0
- package/src/__test-utils__/git-workspace-fixture.ts +58 -0
- package/src/__test-utils__/harness-boot-order-child.ts +7 -2
- package/src/__test-utils__/harness-contract/contract.ts +33 -20
- package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +328 -10
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +38 -6
- package/src/__test-utils__/harness-contract/types.ts +27 -3
- package/src/__test-utils__/hermetic-activity.ts +52 -14
- package/src/__test-utils__/model-registry-fixture.ts +32 -7
- package/src/__test-utils__/module-specifiers.ts +24 -0
- package/src/__test-utils__/turn-input-fixture.ts +2 -2
- package/src/__tests__/harness-boot-order.test.ts +9 -2
- package/src/activities/call-agent.ts +2 -2
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +47 -3
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +2 -48
- package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +6 -1
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +52 -27
- package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +25 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.everything.prompt.md +166 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.plan-mode.prompt.md +186 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.recovery.prompt.md +191 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.reinvocation.prompt.md +13 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.prefixed.prompt.md +32 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.raw.prompt.md +1 -0
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +4 -0
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +24 -4
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +6 -5
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +9 -0
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +11 -8
- package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +229 -0
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +2 -2
- package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +78 -234
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +1 -26
- package/src/activities/execute-cursor/adapter.ts +7 -5
- package/src/activities/execute-cursor/approval-policy.ts +5 -2
- package/src/activities/execute-cursor/approval-state.ts +16 -8
- package/src/activities/execute-cursor/cas-observations.ts +20 -2
- package/src/activities/execute-cursor/cursor-capabilities.ts +24 -5
- package/src/activities/execute-cursor/message-translator.ts +29 -41
- package/src/activities/execute-cursor/prompt-builder.ts +99 -157
- package/src/activities/execute-cursor/turn-boundary.ts +34 -140
- package/src/activities/execute-cursor/turn-settle.ts +37 -51
- package/src/activities/execute-cursor/turn-setup.ts +30 -70
- package/src/activities/execute-cursor/turn-stream.ts +8 -31
- package/src/activities/execute-cursor/turn.ts +5 -1
- package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +391 -0
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +313 -0
- package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +48 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +85 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +383 -36
- package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +76 -0
- package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +47 -0
- package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +80 -0
- package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -2
- package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -3
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +172 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +167 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.minimal.prompt.md +36 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +178 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +158 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +210 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +74 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +104 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +78 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +138 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +68 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +154 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +116 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +69 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +67 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/plain-turn.status.json +47 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +68 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +280 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +77 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +99 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +109 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +76 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.text-fallback.status.json +51 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tier2.status.json +51 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tool-strategy.status.json +56 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +90 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +70 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +71 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +144 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +184 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +203 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +170 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +175 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +206 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +142 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +126 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +139 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +122 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +236 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +161 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +157 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +152 -0
- package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +50 -122
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +8 -6
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +35 -35
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +247 -0
- package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +329 -0
- package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +1 -20
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +78 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/subagent-tracker.test.ts +57 -31
- package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +19 -79
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +15 -15
- package/src/activities/execute-deep-agent/__tests__/summarization-verification.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +391 -0
- package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +343 -38
- package/src/activities/execute-deep-agent/__tests__/vision-input.test.ts +5 -5
- package/src/activities/execute-deep-agent/adapter.ts +94 -0
- package/src/activities/execute-deep-agent/cas-capture-observer.ts +11 -0
- package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +43 -0
- package/src/activities/execute-deep-agent/execution-state.ts +4 -13
- package/src/activities/execute-deep-agent/hitl.ts +100 -123
- package/src/activities/execute-deep-agent/prompt-builder.ts +141 -115
- package/src/activities/execute-deep-agent/status-builder-shared.ts +21 -84
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +13 -19
- package/src/activities/execute-deep-agent/subagent-tracker.ts +77 -42
- package/src/activities/execute-deep-agent/subagent-transformer.ts +46 -105
- package/src/activities/execute-deep-agent/subagent-wiring.ts +5 -4
- package/src/activities/execute-deep-agent/turn-settle.ts +164 -0
- package/src/activities/execute-deep-agent/turn-setup.ts +541 -0
- package/src/activities/execute-deep-agent/turn-stream.ts +313 -0
- package/src/activities/execute-deep-agent/turn.ts +131 -0
- package/src/activities/execute-deep-agent/v3-event-recorder.ts +6 -5
- package/src/activities/execute-deep-agent/v3-events.ts +1 -1
- package/src/activities/execute-deep-agent/v3-status-builder.ts +84 -63
- package/src/harness/__tests__/approval-decisions.test.ts +116 -0
- package/src/harness/__tests__/capture.test.ts +268 -0
- package/src/harness/__tests__/mount-skills.test.ts +169 -0
- package/src/harness/__tests__/persist-chokepoint.test.ts +38 -2
- package/src/harness/__tests__/run-turn-deterministic.test.ts +94 -0
- package/src/harness/__tests__/run-turn.test.ts +39 -23
- package/src/harness/__tests__/turn-attachments-vision.test.ts +80 -0
- package/src/harness/__tests__/turn-context.test.ts +73 -26
- package/src/harness/approval-decisions.ts +104 -0
- package/src/harness/capabilities.ts +16 -5
- package/src/harness/capture.ts +301 -0
- package/src/harness/persist-chokepoint.ts +24 -4
- package/src/harness/run-turn.ts +120 -29
- package/src/harness/terminal-table.ts +61 -20
- package/src/harness/turn-context.ts +208 -111
- package/src/harness/types.ts +66 -12
- package/src/harness-adapters.ts +17 -9
- package/src/middleware/__tests__/approval-gate.test.ts +1 -1
- package/src/middleware/__tests__/cost-advisory.test.ts +113 -0
- package/src/middleware/approval-gate.ts +2 -2
- package/src/middleware/{cost-cap.ts → cost-advisory.ts} +40 -70
- package/src/middleware/index.ts +29 -29
- package/src/middleware/types.ts +3 -2
- package/src/runner-manager.ts +0 -8
- package/src/runner.ts +0 -8
- package/src/shared/__tests__/attachment-naming.test.ts +6 -19
- package/src/shared/__tests__/attachment-resolver.test.ts +158 -8
- package/src/shared/__tests__/attachment-zip.test.ts +236 -0
- package/src/shared/__tests__/bedrock-adapter.test.ts +1 -1
- package/src/shared/__tests__/blueprint-resolver.test.ts +43 -0
- package/src/shared/__tests__/cost-guard.test.ts +3 -3
- package/src/shared/__tests__/prompt-sections.test.ts +167 -0
- package/src/shared/__tests__/secret-leak-scan.test.ts +2 -2
- package/src/{activities/execute-deep-agent → shared}/__tests__/stamp-flowed-rows.test.ts +33 -10
- package/src/shared/__tests__/vertex-adapter.test.ts +1 -1
- package/src/shared/attachment-resolver.ts +218 -55
- package/src/shared/attachment-zip.ts +281 -0
- package/src/shared/connect-backfill.ts +9 -11
- package/src/shared/cost-guard.ts +3 -3
- package/src/shared/execution-status-writer.ts +5 -5
- package/src/shared/extract-structured-output.ts +8 -7
- package/src/shared/filereview/__tests__/capture.test.ts +86 -4
- package/src/shared/filereview/__tests__/cas-progress.test.ts +2 -1
- package/src/shared/filereview/cas-progress.ts +5 -19
- package/src/shared/filereview/cas-touched.ts +89 -0
- package/src/shared/filereview/index.ts +4 -2
- package/src/shared/mcp-resolver.ts +4 -5
- package/src/shared/persist-decision.ts +3 -4
- package/src/shared/plan-mode-permissions.ts +2 -2
- package/src/shared/plan-mode-prompt.ts +1 -1
- package/src/shared/prompt-sections.ts +256 -0
- package/src/shared/skill-resolver.ts +4 -2
- package/src/shared/tool-rounds.ts +48 -0
- package/src/shared/tool-row.ts +61 -0
- package/src/shared/workspace/__tests__/stigmer-link.test.ts +7 -22
- package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +20 -61
- package/src/shared/workspace/session-provision.ts +3 -3
- package/src/shared/workspace/stigmer-link.ts +3 -3
- package/src/shared/workspace/writeback-coordinator.ts +16 -64
- package/src/tools/index.ts +1 -1
- package/dist/activities/execute-cursor/capture-flow.d.ts +0 -142
- package/dist/activities/execute-cursor/capture-flow.js +0 -285
- package/dist/activities/execute-cursor/capture-flow.js.map +0 -1
- package/dist/activities/execute-cursor/command-provenance.d.ts +0 -48
- package/dist/activities/execute-cursor/command-provenance.js +0 -38
- package/dist/activities/execute-cursor/command-provenance.js.map +0 -1
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +0 -134
- package/dist/activities/execute-deep-agent/attachment-injector.js +0 -386
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +0 -1
- package/dist/activities/execute-deep-agent/command-provenance.d.ts +0 -61
- package/dist/activities/execute-deep-agent/command-provenance.js +0 -72
- package/dist/activities/execute-deep-agent/command-provenance.js.map +0 -1
- package/dist/activities/execute-deep-agent/environment.d.ts +0 -24
- package/dist/activities/execute-deep-agent/environment.js +0 -58
- package/dist/activities/execute-deep-agent/environment.js.map +0 -1
- package/dist/activities/execute-deep-agent/event-recorder.d.ts +0 -21
- package/dist/activities/execute-deep-agent/event-recorder.js +0 -67
- package/dist/activities/execute-deep-agent/event-recorder.js.map +0 -1
- package/dist/activities/execute-deep-agent/index.d.ts +0 -15
- package/dist/activities/execute-deep-agent/index.js +0 -918
- package/dist/activities/execute-deep-agent/index.js.map +0 -1
- package/dist/activities/execute-deep-agent/mcp-gate.d.ts +0 -28
- package/dist/activities/execute-deep-agent/mcp-gate.js +0 -22
- package/dist/activities/execute-deep-agent/mcp-gate.js.map +0 -1
- package/dist/activities/execute-deep-agent/post-stream.d.ts +0 -23
- package/dist/activities/execute-deep-agent/post-stream.js +0 -71
- package/dist/activities/execute-deep-agent/post-stream.js.map +0 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +0 -136
- package/dist/activities/execute-deep-agent/setup.js +0 -767
- package/dist/activities/execute-deep-agent/setup.js.map +0 -1
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +0 -36
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +0 -56
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +0 -1
- package/dist/activities/execute-deep-agent/status-builder.d.ts +0 -93
- package/dist/activities/execute-deep-agent/status-builder.js +0 -365
- package/dist/activities/execute-deep-agent/status-builder.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming-terminal.d.ts +0 -21
- package/dist/activities/execute-deep-agent/streaming-terminal.js +0 -80
- package/dist/activities/execute-deep-agent/streaming-terminal.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming-v3.d.ts +0 -13
- package/dist/activities/execute-deep-agent/streaming-v3.js +0 -174
- package/dist/activities/execute-deep-agent/streaming-v3.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming.d.ts +0 -81
- package/dist/activities/execute-deep-agent/streaming.js +0 -160
- package/dist/activities/execute-deep-agent/streaming.js.map +0 -1
- package/dist/middleware/cost-cap.d.ts +0 -22
- package/dist/middleware/cost-cap.js.map +0 -1
- package/dist/middleware/graceful-stop.d.ts +0 -17
- package/dist/middleware/graceful-stop.js +0 -63
- package/dist/middleware/graceful-stop.js.map +0 -1
- package/dist/shared/skill-writer.d.ts +0 -75
- package/dist/shared/skill-writer.js +0 -207
- package/dist/shared/skill-writer.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +0 -1032
- package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +0 -240
- package/src/activities/execute-cursor/__tests__/progress-substrate.test.ts +0 -169
- package/src/activities/execute-cursor/capture-flow.ts +0 -379
- package/src/activities/execute-cursor/command-provenance.ts +0 -73
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +0 -1161
- package/src/activities/execute-deep-agent/__tests__/command-provenance.test.ts +0 -252
- package/src/activities/execute-deep-agent/__tests__/environment.test.ts +0 -108
- package/src/activities/execute-deep-agent/__tests__/event-recorder.test.ts +0 -150
- package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +0 -226
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +0 -318
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +0 -351
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +0 -293
- package/src/activities/execute-deep-agent/__tests__/index.test.ts +0 -99
- package/src/activities/execute-deep-agent/__tests__/mcp-gate.test.ts +0 -44
- package/src/activities/execute-deep-agent/__tests__/post-stream.test.ts +0 -112
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +0 -358
- package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +0 -1933
- package/src/activities/execute-deep-agent/__tests__/streaming-terminal.test.ts +0 -40
- package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +0 -597
- package/src/activities/execute-deep-agent/__tests__/streaming.test.ts +0 -508
- package/src/activities/execute-deep-agent/attachment-injector.ts +0 -627
- package/src/activities/execute-deep-agent/command-provenance.ts +0 -102
- package/src/activities/execute-deep-agent/environment.ts +0 -76
- package/src/activities/execute-deep-agent/event-recorder.ts +0 -95
- package/src/activities/execute-deep-agent/index.ts +0 -1072
- package/src/activities/execute-deep-agent/mcp-gate.ts +0 -37
- package/src/activities/execute-deep-agent/post-stream.ts +0 -109
- package/src/activities/execute-deep-agent/setup.ts +0 -1081
- package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +0 -64
- package/src/activities/execute-deep-agent/status-builder.ts +0 -481
- package/src/activities/execute-deep-agent/streaming-terminal.ts +0 -106
- package/src/activities/execute-deep-agent/streaming-v3.ts +0 -277
- package/src/activities/execute-deep-agent/streaming.ts +0 -313
- package/src/middleware/__tests__/cost-cap.test.ts +0 -192
- package/src/middleware/__tests__/graceful-stop.test.ts +0 -105
- package/src/middleware/graceful-stop.ts +0 -86
- package/src/shared/__tests__/skill-writer.test.ts +0 -372
- package/src/shared/skill-writer.ts +0 -266
|
@@ -56,16 +56,25 @@ import type { TurnInputFixtureOverrides } from "../turn-input-fixture.js";
|
|
|
56
56
|
* ends `failed` on the given surface (`engine` unless the scenario says
|
|
57
57
|
* otherwise — the runtime's three failure copies are its own invariant).
|
|
58
58
|
* - `cancelled`: the engine ends its own run cancelled with nothing to
|
|
59
|
-
* wait for (an SDK-side cancel); the turn ends `cancelled`.
|
|
59
|
+
* wait for (an SDK-side cancel); the turn ends `cancelled`. Not every
|
|
60
|
+
* engine can end itself (a LangGraph run is stopped only by the runtime's
|
|
61
|
+
* signal and settles `interrupted`), so a subject that cannot produce it
|
|
62
|
+
* says so and the runtime arm is reported SKIPPED there.
|
|
63
|
+
* - `limit`: the engine exhausts the tool-round budget the execution set and
|
|
64
|
+
* stops at a step boundary with its work checkpointed; the turn ends
|
|
65
|
+
* `tool_call_limit`. Not every engine has such a budget (Cursor's SDK does
|
|
66
|
+
* not), so a subject that cannot produce it says so and the runtime arm
|
|
67
|
+
* is reported SKIPPED there.
|
|
60
68
|
*/
|
|
61
69
|
export type ScenarioStep =
|
|
62
70
|
| { readonly kind: "say"; readonly text: string }
|
|
63
|
-
| { readonly kind: "propose"; readonly toolCallId: string; readonly action: ProposedAction }
|
|
71
|
+
| { readonly kind: "propose"; readonly toolCallId: string; readonly action: ProposedAction; readonly flows?: boolean }
|
|
64
72
|
| { readonly kind: "read"; readonly toolCallId: string; readonly path: string }
|
|
65
73
|
| { readonly kind: "usage"; readonly delta: UsageDelta }
|
|
66
74
|
| { readonly kind: "hang" }
|
|
67
75
|
| { readonly kind: "fail"; readonly message: string; readonly surface: FailureSurface }
|
|
68
|
-
| { readonly kind: "cancelled" }
|
|
76
|
+
| { readonly kind: "cancelled" }
|
|
77
|
+
| { readonly kind: "limit" };
|
|
69
78
|
|
|
70
79
|
/** One turn's worth of engine behaviour. */
|
|
71
80
|
export type TurnScenario = readonly ScenarioStep[];
|
|
@@ -78,6 +87,18 @@ export const scenario = {
|
|
|
78
87
|
propose(toolCallId: string, action: ProposedAction): ScenarioStep {
|
|
79
88
|
return { kind: "propose", toolCallId, action };
|
|
80
89
|
},
|
|
90
|
+
/**
|
|
91
|
+
* A `write` the arm EXPECTS to flow under apply-then-review capture (a git
|
|
92
|
+
* work tree, or artifact storage): the engine performs it at once, the row
|
|
93
|
+
* completes, and the RUNTIME captures it for review after the turn
|
|
94
|
+
* (`harness/capture.ts`). The arm states the posture rather than the
|
|
95
|
+
* subject inferring it, so a subject that gates a flowing write is caught,
|
|
96
|
+
* not accommodated. The bytes written are the engine's own; the arm
|
|
97
|
+
* asserts the captured PATH and the reconcile's effect, never the content.
|
|
98
|
+
*/
|
|
99
|
+
flowingWrite(toolCallId: string, path: string): ScenarioStep {
|
|
100
|
+
return { kind: "propose", toolCallId, action: { kind: "write", resource: path }, flows: true };
|
|
101
|
+
},
|
|
81
102
|
read(toolCallId: string, path: string): ScenarioStep {
|
|
82
103
|
return { kind: "read", toolCallId, path };
|
|
83
104
|
},
|
|
@@ -93,6 +114,9 @@ export const scenario = {
|
|
|
93
114
|
cancelled(): ScenarioStep {
|
|
94
115
|
return { kind: "cancelled" };
|
|
95
116
|
},
|
|
117
|
+
limit(): ScenarioStep {
|
|
118
|
+
return { kind: "limit" };
|
|
119
|
+
},
|
|
96
120
|
} as const;
|
|
97
121
|
|
|
98
122
|
/**
|
|
@@ -7,11 +7,15 @@
|
|
|
7
7
|
* are the wire contract the control plane's workflow keys on — the phases they
|
|
8
8
|
* persist, the copy they write, whether they RETURN a slim status or THROW
|
|
9
9
|
* `CancelledFailure`. Refactoring them safely needs goldens recorded through the
|
|
10
|
-
* activity whole, not through its modules one at a time. The native harness
|
|
11
|
-
* tests
|
|
12
|
-
* boundary
|
|
13
|
-
* this module is that convention made reusable, harness-agnostic,
|
|
14
|
-
* the framework's own activity environment
|
|
10
|
+
* activity whole, not through its modules one at a time. The native harness's
|
|
11
|
+
* earlier activity tests ran their activity hermetically by mocking three
|
|
12
|
+
* modules at the boundary with a hand-written `Context` stand-in and a scripted
|
|
13
|
+
* graph object; this module is that convention made reusable, harness-agnostic,
|
|
14
|
+
* and driven by the framework's own activity environment. Both harnesses now
|
|
15
|
+
* run on it (`execute-cursor/__test-utils__/hermetic-cursor.ts`,
|
|
16
|
+
* `execute-deep-agent/__test-utils__/hermetic-deep-agent.ts`), and the earlier
|
|
17
|
+
* native tests were re-homed onto the native driver (S3 M0), their assertions
|
|
18
|
+
* carried into `execute-deep-agent/__tests__/hermetic/`.
|
|
15
19
|
*
|
|
16
20
|
* What is generic here and what is not: everything an activity touches that is
|
|
17
21
|
* NOT the vendor SDK — the Temporal `Context`, the control-plane client, the
|
|
@@ -92,6 +96,7 @@ import {
|
|
|
92
96
|
signalWorkerShutdown,
|
|
93
97
|
unregisterWorkerShutdownSignal,
|
|
94
98
|
} from "../shared/worker-shutdown.js";
|
|
99
|
+
import { decideCapturedFileChanges, type FileReviewVerdicts } from "./file-review-projection.js";
|
|
95
100
|
import { mockStigmerClient } from "./mock-client.js";
|
|
96
101
|
|
|
97
102
|
// ---------------------------------------------------------------------------
|
|
@@ -221,6 +226,19 @@ export class ExecutionRecord {
|
|
|
221
226
|
return waiting.length;
|
|
222
227
|
}
|
|
223
228
|
|
|
229
|
+
/**
|
|
230
|
+
* What the server's `SubmitFileDecision` and its projection do between
|
|
231
|
+
* invocations: every change of every AWAITING_REVIEW set the runner captured
|
|
232
|
+
* gets a per-file verdict, and `status.file_change_sets` is re-folded from
|
|
233
|
+
* the ledger (`file-review-projection.ts` mirrors the server's fold). The
|
|
234
|
+
* runner authors the ledger; the server owns the sets — so this is the ONE
|
|
235
|
+
* place a test writes them. Returns how many decisions were written.
|
|
236
|
+
*/
|
|
237
|
+
decideCapturedFileChanges(verdicts: FileReviewVerdicts, decidedAt: string): number {
|
|
238
|
+
if (!this.execution.status) throw new Error("ExecutionRecord: no status to decide file changes on (test bug)");
|
|
239
|
+
return decideCapturedFileChanges(this.execution.status, verdicts, decidedAt);
|
|
240
|
+
}
|
|
241
|
+
|
|
224
242
|
/**
|
|
225
243
|
* Apply one `UpdateStatus` write and answer the control signal the server
|
|
226
244
|
* would. A setup-progress report never carries a signal (the runner ignores
|
|
@@ -389,12 +407,30 @@ export function createHermeticEnvironment(): HermeticEnvironment {
|
|
|
389
407
|
// ---------------------------------------------------------------------------
|
|
390
408
|
|
|
391
409
|
/**
|
|
392
|
-
* A deterministic, TICKING `Date
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
* the
|
|
397
|
-
*
|
|
410
|
+
* A deterministic, TICKING clock: `Date` AND `performance` are faked and
|
|
411
|
+
* advance together; timers stay real (the periodic heartbeat, the stall
|
|
412
|
+
* watchdog, `withTimeout` all need them). The harness double calls
|
|
413
|
+
* {@link ScriptedClock.tick} once per script step, so every clock-based
|
|
414
|
+
* decision on the activity path — status timestamps, the enricher's persist
|
|
415
|
+
* debounce, cache TTLs (`Date`); the streaming scheduler's persist cadence
|
|
416
|
+
* (`performance.now()`) — sees the same instants run after run and runs the
|
|
417
|
+
* same branches production runs.
|
|
418
|
+
*
|
|
419
|
+
* Why both (S3 M5, Q-M5-7; F-M2a-20): until M5 only `Date` was faked, so the
|
|
420
|
+
* scheduler paced persists on REAL elapsed time and `fileChangeProgress`,
|
|
421
|
+
* which rides persists, could gain or lose a capture under load — a golden
|
|
422
|
+
* flake seen twice across S3. One clock, two faces: `tick` advances through
|
|
423
|
+
* the fake clock's own `tick` (`vi.advanceTimersByTime`), which moves both
|
|
424
|
+
* `Date` and `performance.now()`; `vi.setSystemTime` would move `Date` alone
|
|
425
|
+
* (fake-timers keeps `performance` monotonic across a system-time jump), so
|
|
426
|
+
* only {@link reset} uses it — rewinding `Date` to the epoch for a second
|
|
427
|
+
* scenario while `performance` stays monotonic, which is harmless because
|
|
428
|
+
* every turn constructs its scheduler fresh and measures from its own start.
|
|
429
|
+
*
|
|
430
|
+
* Faking `performance` replaces the whole global (`now`, a `timeOrigin` at
|
|
431
|
+
* the epoch, every other method a no-op); nothing on the activity path reads
|
|
432
|
+
* more than `now`, and a module importing from `node:perf_hooks` would bypass
|
|
433
|
+
* the fake (none under `src/` does).
|
|
398
434
|
*/
|
|
399
435
|
export class ScriptedClock {
|
|
400
436
|
/** A fixed epoch: 2026-01-01T00:00:00.000Z. Chosen for readability in goldens. */
|
|
@@ -405,15 +441,17 @@ export class ScriptedClock {
|
|
|
405
441
|
private nowMs = ScriptedClock.EPOCH_MS;
|
|
406
442
|
|
|
407
443
|
install(): void {
|
|
408
|
-
vi.useFakeTimers({ toFake: ["Date"], now: this.nowMs });
|
|
444
|
+
vi.useFakeTimers({ toFake: ["Date", "performance"], now: this.nowMs });
|
|
409
445
|
}
|
|
410
446
|
|
|
411
447
|
tick(ms: number = ScriptedClock.STEP_MS): void {
|
|
412
448
|
this.nowMs += ms;
|
|
413
|
-
|
|
449
|
+
// Through the fake clock's own tick, so `performance.now()` advances with
|
|
450
|
+
// `Date`; with no timers faked there is nothing for it to fire.
|
|
451
|
+
vi.advanceTimersByTime(ms);
|
|
414
452
|
}
|
|
415
453
|
|
|
416
|
-
/** Back to the epoch — for a second scenario in the same file. */
|
|
454
|
+
/** Back to the epoch — for a second scenario in the same file. `Date` rewinds; `performance` stays monotonic (see the header). */
|
|
417
455
|
reset(): void {
|
|
418
456
|
this.nowMs = ScriptedClock.EPOCH_MS;
|
|
419
457
|
vi.setSystemTime(this.nowMs);
|
|
@@ -10,19 +10,29 @@
|
|
|
10
10
|
* registry document — and to THROW for any other URL, so a new network
|
|
11
11
|
* dependency on the activity path fails the run instead of leaking.
|
|
12
12
|
*
|
|
13
|
-
* One entry,
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
13
|
+
* One entry per harness, each priced at round numbers so a golden's usage and
|
|
14
|
+
* cost are legible (600 000 input tokens = $0.60). `composer-2.5` is the
|
|
15
|
+
* Cursor harness's pinned model (also in the Cursor double's catalog);
|
|
16
|
+
* `claude-haiku-4.5` is the native harness's, an Anthropic id so the native
|
|
17
|
+
* error arms' provider label (`tryInferProvider`) and the thinking heuristic
|
|
18
|
+
* read as they do in production. The document itself is the control plane's,
|
|
19
|
+
* read by every harness's runtime: `parsePricingTable` keeps every entry with
|
|
20
|
+
* `pricing`; `parseRegistry` wants `id` + `provider` and reads
|
|
21
|
+
* `capabilities.vision`; `getDefaultModel` selects only `harness: "native"`.
|
|
22
|
+
* Every fixture NAMES its model on the execution, so the list's order is
|
|
23
|
+
* never consulted and adding an entry is byte-invisible to the other
|
|
24
|
+
* harness's goldens (verified when the native entry landed: Cursor's
|
|
25
|
+
* seventeen unchanged).
|
|
19
26
|
*/
|
|
20
27
|
|
|
21
28
|
import { vi } from "vitest";
|
|
22
29
|
|
|
23
|
-
/** The pinned model of every hermetic run; in the registry document AND in the Cursor double's catalog. */
|
|
30
|
+
/** The pinned model of every Cursor hermetic run; in the registry document AND in the Cursor double's catalog. */
|
|
24
31
|
export const FIXTURE_MODEL = "composer-2.5";
|
|
25
32
|
|
|
33
|
+
/** The pinned model of every native (deep-agent) hermetic run. */
|
|
34
|
+
export const FIXTURE_NATIVE_MODEL = "claude-haiku-4.5";
|
|
35
|
+
|
|
26
36
|
export const REGISTRY_DOCUMENT = {
|
|
27
37
|
models: [
|
|
28
38
|
{
|
|
@@ -48,6 +58,21 @@ export const REGISTRY_DOCUMENT = {
|
|
|
48
58
|
},
|
|
49
59
|
},
|
|
50
60
|
},
|
|
61
|
+
{
|
|
62
|
+
id: FIXTURE_NATIVE_MODEL,
|
|
63
|
+
displayName: "Claude Haiku 4.5 (hermetic fixture)",
|
|
64
|
+
provider: "anthropic",
|
|
65
|
+
harness: "native",
|
|
66
|
+
costTier: "standard",
|
|
67
|
+
featured: true,
|
|
68
|
+
capabilities: { vision: true },
|
|
69
|
+
pricing: {
|
|
70
|
+
inputPricePerMillion: 1.0,
|
|
71
|
+
outputPricePerMillion: 5.0,
|
|
72
|
+
cacheWritePricePerMillion: 1.25,
|
|
73
|
+
cacheReadPricePerMillion: 0.1,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
51
76
|
],
|
|
52
77
|
} as const;
|
|
53
78
|
|
|
@@ -42,6 +42,30 @@ export function moduleSpecifiers(fileName: string, source: string): string[] {
|
|
|
42
42
|
return specifiers;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The module specifiers a file LOADS when it is itself loaded: static
|
|
47
|
+
* imports and re-exports that are not type-only. A `import type` is erased
|
|
48
|
+
* by the compiler and a dynamic `import()` runs only when its call runs, so
|
|
49
|
+
* neither is on the static graph — which is what the SDK-free fences on the
|
|
50
|
+
* adapters' lifecycle modules ask about (`harness-adapters.ts`'s rule: the
|
|
51
|
+
* roots import the table before they boot it, so an adapter loads its SDK
|
|
52
|
+
* inside `boot`, never at the top of its module).
|
|
53
|
+
*/
|
|
54
|
+
export function staticRuntimeSpecifiers(fileName: string, source: string): string[] {
|
|
55
|
+
const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, /* setParentNodes */ false);
|
|
56
|
+
const specifiers: string[] = [];
|
|
57
|
+
for (const statement of sourceFile.statements) {
|
|
58
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
59
|
+
if (statement.importClause?.isTypeOnly) continue;
|
|
60
|
+
specifiers.push(statement.moduleSpecifier.text);
|
|
61
|
+
} else if (ts.isExportDeclaration(statement) && statement.moduleSpecifier !== undefined && ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
62
|
+
if (statement.isTypeOnly) continue;
|
|
63
|
+
specifiers.push(statement.moduleSpecifier.text);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return specifiers;
|
|
67
|
+
}
|
|
68
|
+
|
|
45
69
|
/**
|
|
46
70
|
* The relative specifiers in `source` that resolve to a path inside
|
|
47
71
|
* `forbiddenRoot`. Package specifiers are ignored: no alias maps a package
|
|
@@ -58,7 +58,7 @@ export interface TurnInputFixtureOverrides extends Partial<Omit<TurnInput, "exec
|
|
|
58
58
|
* The status the default execution carries — what the control plane
|
|
59
59
|
* persisted at the end of the previous invocation, on a reinvocation. The
|
|
60
60
|
* runtime seeds the turn's in-progress status from a clone of it
|
|
61
|
-
* (`
|
|
61
|
+
* (`seedFromPersistedStatus`) and an adapter may read the record's own
|
|
62
62
|
* copy for its facts, so a test standing in for the runtime hands both.
|
|
63
63
|
*/
|
|
64
64
|
readonly persistedStatus?: AgentExecutionStatus;
|
|
@@ -137,7 +137,7 @@ export function turnInputFixture(overrides: TurnInputFixtureOverrides = {}): Tur
|
|
|
137
137
|
leases: { global: false, categories: new Set(), servers: new Set() },
|
|
138
138
|
policies: new Map(),
|
|
139
139
|
},
|
|
140
|
-
skills: overrides.skills ?? [],
|
|
140
|
+
skills: overrides.skills ?? { root: [], bySubAgent: new Map() },
|
|
141
141
|
attachments: overrides.attachments ?? { results: [], visionImages: [], visionNotViewable: [] },
|
|
142
142
|
appliedToolCallIds: overrides.appliedToolCallIds ?? new Set(),
|
|
143
143
|
model: overrides.model ?? { requested: "default", serviceTier: ServiceTier.STANDARD, thinkingMode: ThinkingMode.DISABLED },
|
|
@@ -20,9 +20,16 @@
|
|
|
20
20
|
* `adapter.ts`'s graph, or a static client import on the registry's, fails
|
|
21
21
|
* the first arm; a `boot` that stopped asserting fails the second.
|
|
22
22
|
*
|
|
23
|
+
* The table has two rows since S3 M2b (2026-09-13): the child boots the
|
|
24
|
+
* Cursor adapter and then the native deep-agent adapter, whose `boot`
|
|
25
|
+
* registers the deepagents profiles and loads LangChain — after the patch,
|
|
26
|
+
* because it is the second row. A `boot` that reordered the rows, or a
|
|
27
|
+
* native adapter that imported its engine statically, would move that load
|
|
28
|
+
* before the patch; the first arm below is where that would show.
|
|
29
|
+
*
|
|
23
30
|
* `HOME` points at a temp dir so an SDK import-time side effect cannot touch
|
|
24
31
|
* the developer's home; the proxy endpoint is an inert loopback; nothing is
|
|
25
|
-
* dialled. Two spawns, a few seconds:
|
|
32
|
+
* dialled. Two spawns, a few seconds: both SDKs are imported for real once.
|
|
26
33
|
*/
|
|
27
34
|
|
|
28
35
|
import { describe, it, expect } from "vitest";
|
|
@@ -63,7 +70,7 @@ function lastLine(text: string): string {
|
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
describe("harness boot order (fresh process)", () => {
|
|
66
|
-
it("booting
|
|
73
|
+
it("booting both harnesses on a proxy-mode config, the way the roots do, installs the interceptors, patches the facade, and loads both engines after it", async () => {
|
|
67
74
|
const verdict = await runChild("boot");
|
|
68
75
|
expect(verdict.line, "the child's verdict").toBe("harness-boot-order: ok");
|
|
69
76
|
expect(verdict.exitCode).toBe(0);
|
|
@@ -225,8 +225,8 @@ export async function callAgentAction(
|
|
|
225
225
|
// Honest RunConfig → ExecutionConfig mapping (issue #358): every field
|
|
226
226
|
// the author may set is forwarded to a field the runner enforces.
|
|
227
227
|
// model_name replaces the agent's default outright; max_cost_usd feeds
|
|
228
|
-
// the
|
|
229
|
-
//
|
|
228
|
+
// the turn runtime's cost guard (shared/cost-guard.ts, both harnesses);
|
|
229
|
+
// max_tool_rounds feeds resolveRecursionLimit (native
|
|
230
230
|
// harness only); service_tier and thinking_mode feed the cursor
|
|
231
231
|
// harness's explicit variant selection (issues #357/#772). Zero/unset
|
|
232
232
|
// means "no override" and is omitted.
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
* would show up there AND in `executionCount`, never be papered over.
|
|
80
80
|
*/
|
|
81
81
|
|
|
82
|
-
import { mkdirSync } from "node:fs";
|
|
83
|
-
import { join } from "node:path";
|
|
82
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
83
|
+
import { dirname, join } from "node:path";
|
|
84
84
|
import { ApprovalAction, ServiceTier, ThinkingMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
85
85
|
|
|
86
86
|
import type { Config } from "../../../config.js";
|
|
@@ -237,7 +237,11 @@ class CursorSubject implements CursorContractSubject {
|
|
|
237
237
|
lastSay = s.text;
|
|
238
238
|
break;
|
|
239
239
|
case "propose":
|
|
240
|
-
script.push(
|
|
240
|
+
script.push(
|
|
241
|
+
...(s.flows
|
|
242
|
+
? this.flowingWriteSteps(s.toolCallId, s.action, view, ev)
|
|
243
|
+
: this.proposeSteps(s.toolCallId, s.action, view, ev)),
|
|
244
|
+
);
|
|
241
245
|
break;
|
|
242
246
|
case "read":
|
|
243
247
|
script.push(...this.readSteps(s.toolCallId, s.path, view, ev));
|
|
@@ -281,6 +285,8 @@ class CursorSubject implements CursorContractSubject {
|
|
|
281
285
|
script.push(step.effect("kit: the SDK cancels its own run", ({ run }) => run.cancel()));
|
|
282
286
|
ended = true;
|
|
283
287
|
break;
|
|
288
|
+
case "limit":
|
|
289
|
+
throw new Error(`${this.name}: limit() is not producible by this subject (the Cursor SDK has no tool-round budget; the runtime arm is declared off for it); test bug`);
|
|
284
290
|
default: {
|
|
285
291
|
const exhaustive: never = s;
|
|
286
292
|
throw new Error(`${this.name}: unknown scenario step ${JSON.stringify(exhaustive)}`);
|
|
@@ -352,6 +358,44 @@ class CursorSubject implements CursorContractSubject {
|
|
|
352
358
|
];
|
|
353
359
|
}
|
|
354
360
|
|
|
361
|
+
/**
|
|
362
|
+
* A write the arm expects to FLOW under apply-then-review capture: the
|
|
363
|
+
* stream tool call, the REAL hook (which allows a git-capturable write in
|
|
364
|
+
* capture mode — asserted through the disagreement record like every other
|
|
365
|
+
* hook answer), the write itself as the SDK would perform it once allowed
|
|
366
|
+
* (the bytes are this double's own: the tool-call id, one line, appended),
|
|
367
|
+
* and the completion. The runtime captures the change after the turn; the
|
|
368
|
+
* hook's sidecar is what this adapter binds as its CAS observations, so a
|
|
369
|
+
* gitignored path here would reach the review that way.
|
|
370
|
+
*/
|
|
371
|
+
private flowingWriteSteps(toolCallId: string, action: ProposedAction, view: EngineView, ev: ReturnType<typeof sdkEvents>): ScriptStep[] {
|
|
372
|
+
if (action.kind !== "write") {
|
|
373
|
+
throw new Error(`${this.name}: only a write flows under capture (got ${action.kind}); test bug`);
|
|
374
|
+
}
|
|
375
|
+
const memory = this.proposals.get(toolCallId) ?? { emitted: 0, allowed: 0 };
|
|
376
|
+
this.proposals.set(toolCallId, memory);
|
|
377
|
+
if (memory.allowed > 0) return [];
|
|
378
|
+
memory.emitted += 1;
|
|
379
|
+
const gated: ProposedAction & { kind: GatedActionKind } = { ...action, kind: "write" };
|
|
380
|
+
const args = streamArgsFor(gated);
|
|
381
|
+
const workspaceRoot = this.workspaceRootOf(view.sessionId);
|
|
382
|
+
const file = join(workspaceRoot, action.resource);
|
|
383
|
+
return [
|
|
384
|
+
step.event(ev.toolCall(toolCallId, STREAM_NAME.write, "running", args)),
|
|
385
|
+
step.effect(`kit: the real hook lets ${action.resource} flow under capture`, () => {
|
|
386
|
+
const { permission } = runWorkspaceHook(workspaceRoot, hookInputFor(gated));
|
|
387
|
+
if (permission !== "allow") {
|
|
388
|
+
this.hookDisagreements.push(`${toolCallId}: expected a flowing write to be allowed, hook answered ${permission}`);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
memory.allowed += 1;
|
|
392
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
393
|
+
appendFileSync(file, `${toolCallId}\n`);
|
|
394
|
+
}),
|
|
395
|
+
step.event(ev.toolCall(toolCallId, STREAM_NAME.write, "completed", args, ALLOWED_RESULT)),
|
|
396
|
+
];
|
|
397
|
+
}
|
|
398
|
+
|
|
355
399
|
/**
|
|
356
400
|
* An ungated read: the stream tool call, the REAL hook (which allows every
|
|
357
401
|
* read — the gate's baked-in category set has no arm for it; asserted
|
|
@@ -42,16 +42,9 @@
|
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
44
|
import { execFileSync } from "node:child_process";
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import { create } from "@bufbuild/protobuf";
|
|
45
|
+
import { readFileSync } from "node:fs";
|
|
46
|
+
import { join } from "node:path";
|
|
48
47
|
import type { ModelListItem } from "@cursor/sdk";
|
|
49
|
-
import {
|
|
50
|
-
LocalPathSourceSchema,
|
|
51
|
-
WorkspaceEntrySchema,
|
|
52
|
-
WorkspaceSourceSchema,
|
|
53
|
-
type WorkspaceEntry,
|
|
54
|
-
} from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
|
|
55
48
|
import type { StigmerClient } from "../../../client/stigmer-client.js";
|
|
56
49
|
import type { Config } from "../../../config.js";
|
|
57
50
|
import type { ExecuteActivityInput } from "../../../shared/activity-input.js";
|
|
@@ -203,45 +196,6 @@ export function runWorkspaceHook(
|
|
|
203
196
|
return { permission, raw };
|
|
204
197
|
}
|
|
205
198
|
|
|
206
|
-
/**
|
|
207
|
-
* A git work tree with one committed file, for the file-review capture
|
|
208
|
-
* scenario. Author, committer and both dates are pinned so the commit AND tree
|
|
209
|
-
* object ids are byte-stable — a file-review golden may carry them.
|
|
210
|
-
*/
|
|
211
|
-
export function initGitWorkspace(root: string, files: Record<string, string>): void {
|
|
212
|
-
mkdirSync(root, { recursive: true });
|
|
213
|
-
const gitEnv = {
|
|
214
|
-
...process.env,
|
|
215
|
-
GIT_AUTHOR_NAME: "hermetic",
|
|
216
|
-
GIT_AUTHOR_EMAIL: "hermetic@stigmer.test",
|
|
217
|
-
GIT_COMMITTER_NAME: "hermetic",
|
|
218
|
-
GIT_COMMITTER_EMAIL: "hermetic@stigmer.test",
|
|
219
|
-
GIT_AUTHOR_DATE: "2026-01-01T00:00:00Z",
|
|
220
|
-
GIT_COMMITTER_DATE: "2026-01-01T00:00:00Z",
|
|
221
|
-
};
|
|
222
|
-
const git = (args: string[]): void => {
|
|
223
|
-
execFileSync("git", args, { cwd: root, env: gitEnv, stdio: "ignore" });
|
|
224
|
-
};
|
|
225
|
-
git(["init", "-q", "-b", "main"]);
|
|
226
|
-
for (const [rel, content] of Object.entries(files)) {
|
|
227
|
-
const abs = join(root, rel);
|
|
228
|
-
mkdirSync(dirname(abs), { recursive: true });
|
|
229
|
-
writeFileSync(abs, content, "utf-8");
|
|
230
|
-
}
|
|
231
|
-
git(["add", "-A"]);
|
|
232
|
-
git(["commit", "-q", "-m", "initial"]);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/** A session workspace entry mounting an absolute local path (local mode only). */
|
|
236
|
-
export function localPathEntry(name: string, path: string): WorkspaceEntry {
|
|
237
|
-
return create(WorkspaceEntrySchema, {
|
|
238
|
-
name,
|
|
239
|
-
source: create(WorkspaceSourceSchema, {
|
|
240
|
-
source: { case: "localPath", value: create(LocalPathSourceSchema, { path }) },
|
|
241
|
-
}),
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
199
|
// ---------------------------------------------------------------------------
|
|
246
200
|
// Running a scenario
|
|
247
201
|
// ---------------------------------------------------------------------------
|
|
@@ -20,7 +20,7 @@ import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/a
|
|
|
20
20
|
import { AgentMessageSchema, ToolCallSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
21
21
|
import { ApprovalAction, MessageType, ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
22
22
|
|
|
23
|
-
import { approvalDecisionsOf } from "../../../harness/
|
|
23
|
+
import { approvalDecisionsOf } from "../../../harness/approval-decisions.js";
|
|
24
24
|
import { reconstructAdjudicatedApprovals } from "../approval-state.js";
|
|
25
25
|
|
|
26
26
|
describe("the runtime's approvalDecisionsOf and the adapter's reconstructAdjudicatedApprovals", () => {
|
|
@@ -260,15 +260,17 @@ describe("buildApprovalState", () => {
|
|
|
260
260
|
});
|
|
261
261
|
|
|
262
262
|
describe("buildReinvocationPrompt", () => {
|
|
263
|
-
it("describes approved and
|
|
263
|
+
it("describes approved, skipped and rejected actions in human terms, not opaque ids", () => {
|
|
264
264
|
const prompt = buildReinvocationPrompt(
|
|
265
265
|
[
|
|
266
266
|
pending({ toolCallId: "c1", toolName: "edit", message: "Write file: gated.txt" }),
|
|
267
267
|
pending({ toolCallId: "c2", toolName: "shell", message: "Run command: rm -rf build" }),
|
|
268
|
+
pending({ toolCallId: "c3", toolName: "shell", message: "Run command: git push --force" }),
|
|
268
269
|
],
|
|
269
270
|
new Map([
|
|
270
271
|
["c1", ApprovalAction.APPROVE],
|
|
271
272
|
["c2", ApprovalAction.SKIP],
|
|
273
|
+
["c3", ApprovalAction.REJECT],
|
|
272
274
|
]),
|
|
273
275
|
);
|
|
274
276
|
|
|
@@ -276,8 +278,11 @@ describe("buildReinvocationPrompt", () => {
|
|
|
276
278
|
expect(prompt).toContain("Write file: gated.txt");
|
|
277
279
|
expect(prompt).toContain("SKIPPED");
|
|
278
280
|
expect(prompt).toContain("Run command: rm -rf build");
|
|
281
|
+
expect(prompt).toContain("REJECTED");
|
|
282
|
+
expect(prompt).toContain("Run command: git push --force");
|
|
279
283
|
expect(prompt).not.toContain("c1");
|
|
280
284
|
expect(prompt).not.toContain("c2");
|
|
285
|
+
expect(prompt).not.toContain("c3");
|
|
281
286
|
});
|
|
282
287
|
|
|
283
288
|
it("falls back to tool name + args preview when no message is set", () => {
|