@stigmer/runner 3.15.3-dev.20260914100347 → 3.15.3-dev.20260916211208

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (549) hide show
  1. package/README.md +1 -0
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/__test-utils__/approval-contract/types.d.ts +1 -1
  4. package/dist/__test-utils__/hermetic-activity.d.ts +61 -7
  5. package/dist/__test-utils__/hermetic-activity.js +100 -9
  6. package/dist/__test-utils__/hermetic-activity.js.map +1 -1
  7. package/dist/__test-utils__/model-registry-fixture.d.ts +22 -3
  8. package/dist/__test-utils__/model-registry-fixture.js +22 -7
  9. package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
  10. package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +2 -2
  11. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +14 -11
  12. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
  13. package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +61 -0
  14. package/dist/activities/execute-cursor/__test-utils__/fold.js +94 -0
  15. package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -0
  16. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +1 -1
  17. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
  18. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +52 -14
  19. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +46 -12
  20. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
  21. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +21 -28
  22. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +27 -11
  23. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
  24. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.d.ts +70 -26
  25. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js +82 -32
  26. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js.map +1 -1
  27. package/dist/activities/execute-cursor/adapter.d.ts +8 -7
  28. package/dist/activities/execute-cursor/adapter.js +13 -9
  29. package/dist/activities/execute-cursor/adapter.js.map +1 -1
  30. package/dist/activities/execute-cursor/approval-policy.d.ts +10 -10
  31. package/dist/activities/execute-cursor/approval-policy.js +12 -23
  32. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  33. package/dist/activities/execute-cursor/approval-state.d.ts +35 -1
  34. package/dist/activities/execute-cursor/approval-state.js +65 -0
  35. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  36. package/dist/activities/execute-cursor/{message-translator.d.ts → boundary-rows.d.ts} +45 -341
  37. package/dist/activities/execute-cursor/boundary-rows.js +1018 -0
  38. package/dist/activities/execute-cursor/boundary-rows.js.map +1 -0
  39. package/dist/activities/execute-cursor/cursor-capabilities.d.ts +1 -1
  40. package/dist/activities/execute-cursor/cursor-capabilities.js +1 -1
  41. package/dist/activities/execute-cursor/cursor-event-recorder.d.ts +33 -14
  42. package/dist/activities/execute-cursor/cursor-event-recorder.js +43 -21
  43. package/dist/activities/execute-cursor/cursor-event-recorder.js.map +1 -1
  44. package/dist/activities/execute-cursor/prompt-builder.d.ts +3 -3
  45. package/dist/activities/execute-cursor/prompt-builder.js +4 -4
  46. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  47. package/dist/activities/execute-cursor/sdk-warmup.d.ts +15 -6
  48. package/dist/activities/execute-cursor/sdk-warmup.js +15 -6
  49. package/dist/activities/execute-cursor/sdk-warmup.js.map +1 -1
  50. package/dist/activities/execute-cursor/service-tier.js +1 -2
  51. package/dist/activities/execute-cursor/service-tier.js.map +1 -1
  52. package/dist/activities/execute-cursor/session-lifecycle.d.ts +38 -59
  53. package/dist/activities/execute-cursor/session-lifecycle.js +59 -96
  54. package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -1
  55. package/dist/activities/execute-cursor/session-store.d.ts +100 -0
  56. package/dist/activities/execute-cursor/session-store.js +157 -0
  57. package/dist/activities/execute-cursor/session-store.js.map +1 -0
  58. package/dist/activities/execute-cursor/sub-agent-steps.d.ts +79 -0
  59. package/dist/activities/execute-cursor/sub-agent-steps.js +180 -0
  60. package/dist/activities/execute-cursor/sub-agent-steps.js.map +1 -0
  61. package/dist/activities/execute-cursor/tool-result.d.ts +49 -0
  62. package/dist/activities/execute-cursor/tool-result.js +130 -0
  63. package/dist/activities/execute-cursor/tool-result.js.map +1 -0
  64. package/dist/activities/execute-cursor/translator.d.ts +178 -0
  65. package/dist/activities/execute-cursor/translator.js +485 -0
  66. package/dist/activities/execute-cursor/translator.js.map +1 -0
  67. package/dist/activities/execute-cursor/turn-boundary.d.ts +15 -5
  68. package/dist/activities/execute-cursor/turn-boundary.js +10 -14
  69. package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
  70. package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
  71. package/dist/activities/execute-cursor/turn-settle.js +47 -34
  72. package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
  73. package/dist/activities/execute-cursor/turn-setup.d.ts +2 -2
  74. package/dist/activities/execute-cursor/turn-setup.js +5 -5
  75. package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
  76. package/dist/activities/execute-cursor/turn-stream.d.ts +23 -14
  77. package/dist/activities/execute-cursor/turn-stream.js +41 -28
  78. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  79. package/dist/activities/execute-cursor/turn.d.ts +4 -4
  80. package/dist/activities/execute-cursor/turn.js +5 -5
  81. package/dist/activities/execute-cursor/usage-pricing.d.ts +2 -2
  82. package/dist/activities/execute-cursor/usage-pricing.js +2 -2
  83. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +2 -2
  84. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +2 -2
  85. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +16 -11
  86. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -10
  87. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
  88. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +1 -1
  89. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -1
  90. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +2 -3
  91. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +2 -3
  92. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -1
  93. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +12 -3
  94. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +18 -4
  95. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
  96. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.d.ts +10 -1
  97. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js +24 -11
  98. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js.map +1 -1
  99. package/dist/activities/execute-deep-agent/adapter.d.ts +1 -1
  100. package/dist/activities/execute-deep-agent/adapter.js +1 -1
  101. package/dist/activities/execute-deep-agent/approval-file-change.d.ts +19 -19
  102. package/dist/activities/execute-deep-agent/approval-file-change.js +16 -15
  103. package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -1
  104. package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +2 -2
  105. package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +2 -2
  106. package/dist/activities/execute-deep-agent/hitl.d.ts +2 -2
  107. package/dist/activities/execute-deep-agent/hitl.js +2 -2
  108. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +13 -3
  109. package/dist/activities/execute-deep-agent/inline-publisher.js +3 -3
  110. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
  111. package/dist/activities/execute-deep-agent/prompt-builder.d.ts +3 -3
  112. package/dist/activities/execute-deep-agent/prompt-builder.js +6 -7
  113. package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
  114. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +16 -8
  115. package/dist/activities/execute-deep-agent/streaming-side-effects.js +20 -33
  116. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  117. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +3 -3
  118. package/dist/activities/execute-deep-agent/subagent-transformer.js +1 -1
  119. package/dist/activities/execute-deep-agent/translator.d.ts +134 -0
  120. package/dist/activities/execute-deep-agent/translator.js +418 -0
  121. package/dist/activities/execute-deep-agent/translator.js.map +1 -0
  122. package/dist/activities/execute-deep-agent/turn-settle.d.ts +13 -7
  123. package/dist/activities/execute-deep-agent/turn-settle.js +34 -45
  124. package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
  125. package/dist/activities/execute-deep-agent/turn-setup.d.ts +8 -8
  126. package/dist/activities/execute-deep-agent/turn-setup.js +7 -7
  127. package/dist/activities/execute-deep-agent/turn-stream.d.ts +13 -10
  128. package/dist/activities/execute-deep-agent/turn-stream.js +44 -41
  129. package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
  130. package/dist/activities/execute-deep-agent/turn.d.ts +3 -3
  131. package/dist/activities/execute-deep-agent/turn.js +3 -3
  132. package/dist/config.d.ts +2 -2
  133. package/dist/harness/approval-decisions.d.ts +1 -1
  134. package/dist/harness/approval-decisions.js +1 -1
  135. package/dist/harness/capabilities.d.ts +21 -11
  136. package/dist/harness/capabilities.js +2 -2
  137. package/dist/harness/capture.d.ts +4 -4
  138. package/dist/harness/capture.js +4 -4
  139. package/dist/harness/persist-chokepoint.d.ts +3 -3
  140. package/dist/harness/persist-chokepoint.js +3 -3
  141. package/dist/harness/registry.d.ts +2 -2
  142. package/dist/harness/registry.js +2 -2
  143. package/dist/harness/run-turn.d.ts +6 -4
  144. package/dist/harness/run-turn.js +31 -9
  145. package/dist/harness/run-turn.js.map +1 -1
  146. package/dist/harness/stop-controller.d.ts +1 -1
  147. package/dist/harness/stop-controller.js +1 -1
  148. package/dist/harness/terminal-table.d.ts +7 -7
  149. package/dist/harness/terminal-table.js +7 -7
  150. package/dist/harness/transcript/builder.d.ts +182 -0
  151. package/dist/harness/transcript/builder.js +693 -0
  152. package/dist/harness/transcript/builder.js.map +1 -0
  153. package/dist/harness/transcript/events.d.ts +218 -0
  154. package/dist/harness/transcript/events.js +50 -0
  155. package/dist/harness/transcript/events.js.map +1 -0
  156. package/dist/harness/transcript/state.d.ts +110 -0
  157. package/dist/harness/transcript/state.js +148 -0
  158. package/dist/harness/transcript/state.js.map +1 -0
  159. package/dist/harness/turn-context.d.ts +54 -38
  160. package/dist/harness/turn-context.js +42 -43
  161. package/dist/harness/turn-context.js.map +1 -1
  162. package/dist/harness/types.d.ts +63 -22
  163. package/dist/harness/types.js +12 -11
  164. package/dist/harness/types.js.map +1 -1
  165. package/dist/harness/usage-accumulator.d.ts +2 -2
  166. package/dist/harness/usage-accumulator.js +2 -2
  167. package/dist/harness-adapters.d.ts +5 -4
  168. package/dist/harness-adapters.js +5 -4
  169. package/dist/harness-adapters.js.map +1 -1
  170. package/dist/middleware/approval-gate.d.ts +6 -0
  171. package/dist/middleware/approval-gate.js +7 -57
  172. package/dist/middleware/approval-gate.js.map +1 -1
  173. package/dist/middleware/cost-advisory.d.ts +3 -3
  174. package/dist/middleware/cost-advisory.js +3 -3
  175. package/dist/middleware/index.d.ts +1 -1
  176. package/dist/middleware/index.js +1 -1
  177. package/dist/runner-manager.js +1 -1
  178. package/dist/runner-manager.js.map +1 -1
  179. package/dist/shared/approval-policy.d.ts +53 -0
  180. package/dist/shared/approval-policy.js +76 -0
  181. package/dist/shared/approval-policy.js.map +1 -1
  182. package/dist/shared/args-preview.d.ts +45 -22
  183. package/dist/shared/args-preview.js +51 -41
  184. package/dist/shared/args-preview.js.map +1 -1
  185. package/dist/shared/attachment-resolver.d.ts +4 -4
  186. package/dist/shared/attachment-resolver.js +4 -4
  187. package/dist/shared/attachment-vision.d.ts +2 -1
  188. package/dist/shared/attachment-vision.js.map +1 -1
  189. package/dist/shared/attachment-zip.d.ts +2 -2
  190. package/dist/shared/attachment-zip.js +2 -2
  191. package/dist/shared/cost-guard.d.ts +2 -2
  192. package/dist/shared/cost-guard.js +2 -2
  193. package/dist/shared/exact-apply.d.ts +1 -1
  194. package/dist/shared/exact-apply.js +1 -1
  195. package/dist/shared/execution-context.d.ts +2 -2
  196. package/dist/shared/execution-context.js +2 -2
  197. package/dist/shared/extract-structured-output.d.ts +2 -2
  198. package/dist/shared/extract-structured-output.js +2 -2
  199. package/dist/shared/filereview/cas-touched.d.ts +2 -2
  200. package/dist/shared/filereview/cas-touched.js +2 -2
  201. package/dist/shared/heartbeat.d.ts +1 -1
  202. package/dist/shared/heartbeat.js +1 -1
  203. package/dist/shared/llm-backend.d.ts +0 -4
  204. package/dist/shared/llm-backend.js +0 -4
  205. package/dist/shared/llm-backend.js.map +1 -1
  206. package/dist/shared/model-error.d.ts +1 -2
  207. package/dist/shared/model-error.js +1 -2
  208. package/dist/shared/model-error.js.map +1 -1
  209. package/dist/shared/persist-decision.d.ts +18 -24
  210. package/dist/shared/persist-decision.js +19 -11
  211. package/dist/shared/persist-decision.js.map +1 -1
  212. package/dist/shared/prompt-sections.d.ts +4 -4
  213. package/dist/shared/prompt-sections.js +4 -4
  214. package/dist/shared/skill-resolver.d.ts +3 -3
  215. package/dist/shared/skill-resolver.js +3 -3
  216. package/dist/shared/status-offload.d.ts +1 -1
  217. package/dist/shared/status-offload.js +2 -2
  218. package/dist/shared/status-offload.js.map +1 -1
  219. package/dist/shared/streaming-scheduler.d.ts +2 -7
  220. package/dist/shared/streaming-scheduler.js +6 -14
  221. package/dist/shared/streaming-scheduler.js.map +1 -1
  222. package/dist/shared/subagent-rows.d.ts +2 -2
  223. package/dist/shared/subagent-rows.js +2 -2
  224. package/dist/shared/todos.d.ts +3 -3
  225. package/dist/shared/todos.js +3 -3
  226. package/dist/shared/tool-row.d.ts +19 -1
  227. package/dist/shared/tool-row.js +36 -2
  228. package/dist/shared/tool-row.js.map +1 -1
  229. package/dist/shared/worker-shutdown.d.ts +1 -1
  230. package/dist/shared/worker-shutdown.js +1 -1
  231. package/dist/shared/workspace/session-provision.d.ts +1 -1
  232. package/dist/shared/workspace/session-provision.js +1 -1
  233. package/dist/shared/workspace/sources/empty.d.ts +1 -1
  234. package/dist/shared/workspace/sources/empty.js +1 -2
  235. package/dist/shared/workspace/sources/empty.js.map +1 -1
  236. package/dist/shared/workspace/sources/git.js +4 -4
  237. package/dist/shared/workspace/sources/git.js.map +1 -1
  238. package/dist/shared/workspace/sources/local-path.js +6 -6
  239. package/dist/shared/workspace/sources/local-path.js.map +1 -1
  240. package/dist/shared/workspace/stigmer-link.d.ts +1 -1
  241. package/dist/shared/workspace/stigmer-link.js +1 -1
  242. package/dist/shared/workspace/types.d.ts +2 -5
  243. package/dist/shared/workspace/types.js +0 -6
  244. package/dist/shared/workspace/types.js.map +1 -1
  245. package/dist/shared/workspace/writeback-coordinator.d.ts +17 -4
  246. package/dist/shared/workspace/writeback-coordinator.js +7 -9
  247. package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
  248. package/package.json +5 -5
  249. package/src/__test-utils__/__tests__/execution-record-barrier.test.ts +70 -0
  250. package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +35 -1
  251. package/src/__test-utils__/approval-contract/contract.ts +1 -1
  252. package/src/__test-utils__/approval-contract/types.ts +1 -1
  253. package/src/__test-utils__/harness-boot-order-child.ts +1 -1
  254. package/src/__test-utils__/harness-contract/contract.ts +8 -8
  255. package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
  256. package/src/__test-utils__/harness-contract/runtime-contract.ts +52 -16
  257. package/src/__test-utils__/harness-contract/scripted-adapter.ts +47 -43
  258. package/src/__test-utils__/hermetic-activity.ts +113 -9
  259. package/src/__test-utils__/model-registry-fixture.ts +31 -7
  260. package/src/__test-utils__/module-specifiers.ts +32 -3
  261. package/src/__tests__/harness-boot-order.test.ts +1 -1
  262. package/src/__tests__/harness-contract.test.ts +1 -1
  263. package/src/__tests__/runner-manager.test.ts +1 -1
  264. package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +32 -8
  265. package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +12 -10
  266. package/src/activities/execute-cursor/__test-utils__/fold.ts +116 -0
  267. package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +1 -1
  268. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +72 -19
  269. package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +35 -29
  270. package/src/activities/execute-cursor/__test-utils__/scripted-sdk.ts +94 -38
  271. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +2 -1
  272. package/src/activities/execute-cursor/__tests__/approval-state.test.ts +14 -21
  273. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +3 -3
  274. package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +2 -1
  275. package/src/activities/execute-cursor/__tests__/cursor-baseurl-routing.test.ts +10 -8
  276. package/src/activities/execute-cursor/__tests__/cursor-event-recorder.test.ts +142 -0
  277. package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +24 -12
  278. package/src/activities/execute-cursor/__tests__/cursor-generate-image-live.test.ts +7 -2
  279. package/src/activities/execute-cursor/__tests__/cursor-hook-protocol-live.test.ts +163 -0
  280. package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +23 -20
  281. package/src/activities/execute-cursor/__tests__/cursor-transcript-live.test.ts +298 -0
  282. package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +4 -2
  283. package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +1 -1
  284. package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +5 -2
  285. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +5 -2
  286. package/src/activities/execute-cursor/__tests__/hermetic/goldens/mcp-tool-call.status.json +71 -0
  287. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-task-note.status.json +73 -0
  288. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +78 -0
  289. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +72 -0
  290. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +72 -0
  291. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sub-agent-delegation.status.json +109 -0
  292. package/src/activities/execute-cursor/__tests__/hermetic/goldens/thinking-turn.status.json +78 -0
  293. package/src/activities/execute-cursor/__tests__/hermetic/goldens/todo-write.status.json +119 -0
  294. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-error.status.json +68 -0
  295. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-only-step.status.json +67 -0
  296. package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +1 -1
  297. package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +10 -7
  298. package/src/activities/execute-cursor/__tests__/hermetic/mcp-tool-call.test.ts +146 -0
  299. package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +8 -5
  300. package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +6 -2
  301. package/src/activities/execute-cursor/__tests__/hermetic/recovery-fresh-agent.test.ts +4 -1
  302. package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +6 -2
  303. package/src/activities/execute-cursor/__tests__/hermetic/sdk-task-note.test.ts +122 -0
  304. package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +276 -0
  305. package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +12 -9
  306. package/src/activities/execute-cursor/__tests__/hermetic/sub-agent-delegation.test.ts +196 -0
  307. package/src/activities/execute-cursor/__tests__/hermetic/thinking-turn.test.ts +145 -0
  308. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +4 -1
  309. package/src/activities/execute-cursor/__tests__/hermetic/todo-write.test.ts +165 -0
  310. package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +7 -4
  311. package/src/activities/execute-cursor/__tests__/hermetic/tool-error.test.ts +138 -0
  312. package/src/activities/execute-cursor/__tests__/hermetic/tool-only-step.test.ts +130 -0
  313. package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +17 -2
  314. package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -2
  315. package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +43 -60
  316. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +23 -28
  317. package/src/activities/execute-cursor/__tests__/hook-script.test.ts +2 -1
  318. package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +1 -1
  319. package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +5 -5
  320. package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +11 -13
  321. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +8 -11
  322. package/src/activities/execute-cursor/__tests__/session-lifecycle.test.ts +86 -58
  323. package/src/activities/execute-cursor/__tests__/session-store.test.ts +220 -0
  324. package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +8 -22
  325. package/src/activities/execute-cursor/__tests__/translator.test.ts +594 -0
  326. package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +8 -5
  327. package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +87 -63
  328. package/src/activities/execute-cursor/adapter.ts +13 -9
  329. package/src/activities/execute-cursor/approval-policy.ts +12 -24
  330. package/src/activities/execute-cursor/approval-state.ts +66 -1
  331. package/src/activities/execute-cursor/boundary-rows.ts +1132 -0
  332. package/src/activities/execute-cursor/cursor-capabilities.ts +1 -1
  333. package/src/activities/execute-cursor/cursor-event-recorder.ts +57 -28
  334. package/src/activities/execute-cursor/fetch-interceptor.ts +1 -1
  335. package/src/activities/execute-cursor/http2-interceptor.ts +1 -1
  336. package/src/activities/execute-cursor/prompt-builder.ts +6 -6
  337. package/src/activities/execute-cursor/sdk-warmup.ts +15 -6
  338. package/src/activities/execute-cursor/service-tier.ts +1 -2
  339. package/src/activities/execute-cursor/session-lifecycle.ts +63 -109
  340. package/src/activities/execute-cursor/session-store.ts +187 -0
  341. package/src/activities/execute-cursor/sub-agent-steps.ts +188 -0
  342. package/src/activities/execute-cursor/tool-result.ts +128 -0
  343. package/src/activities/execute-cursor/translator.ts +541 -0
  344. package/src/activities/execute-cursor/turn-boundary.ts +21 -14
  345. package/src/activities/execute-cursor/turn-settle.ts +46 -34
  346. package/src/activities/execute-cursor/turn-setup.ts +5 -5
  347. package/src/activities/execute-cursor/turn-stream.ts +49 -46
  348. package/src/activities/execute-cursor/turn.ts +5 -5
  349. package/src/activities/execute-cursor/usage-pricing.ts +2 -2
  350. package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +2 -2
  351. package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +23 -11
  352. package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +1 -1
  353. package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +2 -3
  354. package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +25 -4
  355. package/src/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.ts +25 -11
  356. package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +1 -1
  357. package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +1 -1
  358. package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +6 -17
  359. package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +25 -8
  360. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +2 -7
  361. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +4 -14
  362. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +1 -5
  363. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +4 -7
  364. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +1 -5
  365. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +2 -9
  366. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +2 -9
  367. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +1 -4
  368. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +1 -4
  369. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +1 -4
  370. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +109 -76
  371. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +1 -5
  372. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +2 -10
  373. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +2 -10
  374. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +1 -5
  375. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +3 -6
  376. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +1 -4
  377. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +1 -4
  378. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/write-todos.status.json +92 -0
  379. package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +3 -3
  380. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +9 -5
  381. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +3 -3
  382. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +3 -3
  383. package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +7 -6
  384. package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +10 -11
  385. package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +4 -4
  386. package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +9 -8
  387. package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +21 -13
  388. package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +2 -2
  389. package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +7 -7
  390. package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +28 -12
  391. package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +21 -21
  392. package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -5
  393. package/src/activities/execute-deep-agent/__tests__/hermetic/write-todos.test.ts +160 -0
  394. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +35 -30
  395. package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +3 -4
  396. package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +12 -10
  397. package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +13 -3
  398. package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +26 -18
  399. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +1 -1
  400. package/src/activities/execute-deep-agent/__tests__/{subagent-tracker.test.ts → translator-subagents.test.ts} +76 -57
  401. package/src/activities/execute-deep-agent/__tests__/{v3-status-builder.test.ts → translator-through-builder.test.ts} +213 -299
  402. package/src/activities/execute-deep-agent/__tests__/translator.test.ts +505 -0
  403. package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +11 -29
  404. package/src/activities/execute-deep-agent/adapter.ts +1 -1
  405. package/src/activities/execute-deep-agent/approval-file-change.ts +20 -22
  406. package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +2 -2
  407. package/src/activities/execute-deep-agent/hitl.ts +2 -2
  408. package/src/activities/execute-deep-agent/inline-publisher.ts +16 -5
  409. package/src/activities/execute-deep-agent/prompt-builder.ts +6 -7
  410. package/src/activities/execute-deep-agent/streaming-side-effects.ts +22 -31
  411. package/src/activities/execute-deep-agent/subagent-transformer.ts +3 -3
  412. package/src/activities/execute-deep-agent/translator.ts +463 -0
  413. package/src/activities/execute-deep-agent/turn-settle.ts +35 -43
  414. package/src/activities/execute-deep-agent/turn-setup.ts +8 -8
  415. package/src/activities/execute-deep-agent/turn-stream.ts +53 -51
  416. package/src/activities/execute-deep-agent/turn.ts +3 -3
  417. package/src/config.ts +2 -2
  418. package/src/harness/README.md +335 -0
  419. package/src/harness/__tests__/approval-decisions.test.ts +2 -2
  420. package/src/harness/__tests__/capture.test.ts +3 -3
  421. package/src/harness/__tests__/import-direction.test.ts +3 -2
  422. package/src/harness/__tests__/mount-skills.test.ts +4 -1
  423. package/src/harness/__tests__/readme-index.test.ts +339 -0
  424. package/src/harness/__tests__/run-turn.test.ts +131 -6
  425. package/src/harness/__tests__/transcript-is-engine-free.test.ts +83 -0
  426. package/src/harness/__tests__/transcript-writers.test.ts +191 -0
  427. package/src/harness/__tests__/turn-attachments-vision.test.ts +5 -2
  428. package/src/harness/__tests__/turn-context.test.ts +5 -5
  429. package/src/harness/approval-decisions.ts +1 -1
  430. package/src/harness/capabilities.ts +21 -11
  431. package/src/harness/capture.ts +4 -4
  432. package/src/harness/persist-chokepoint.ts +3 -3
  433. package/src/harness/registry.ts +2 -2
  434. package/src/harness/run-turn.ts +33 -9
  435. package/src/harness/stop-controller.ts +1 -1
  436. package/src/harness/terminal-table.ts +7 -7
  437. package/src/harness/transcript/__tests__/builder.test.ts +975 -0
  438. package/src/harness/transcript/__tests__/state.test.ts +143 -0
  439. package/src/harness/transcript/builder.ts +755 -0
  440. package/src/harness/transcript/events.ts +262 -0
  441. package/src/harness/transcript/state.ts +167 -0
  442. package/src/harness/turn-context.ts +61 -46
  443. package/src/harness/types.ts +64 -22
  444. package/src/harness/usage-accumulator.ts +2 -2
  445. package/src/harness-adapters.ts +5 -4
  446. package/src/middleware/__tests__/cost-advisory.test.ts +2 -2
  447. package/src/middleware/approval-gate.ts +7 -74
  448. package/src/middleware/cost-advisory.ts +3 -3
  449. package/src/middleware/index.ts +1 -1
  450. package/src/runner-manager.ts +1 -1
  451. package/src/shared/__tests__/approval-policy.test.ts +45 -0
  452. package/src/shared/__tests__/args-preview.test.ts +40 -20
  453. package/src/shared/__tests__/attachment-naming.test.ts +1 -1
  454. package/src/shared/__tests__/attachment-resolver.test.ts +5 -5
  455. package/src/shared/__tests__/attachment-zip.test.ts +1 -1
  456. package/src/shared/__tests__/blueprint-resolver.test.ts +1 -1
  457. package/src/shared/__tests__/cost-guard.test.ts +1 -1
  458. package/src/shared/__tests__/exact-apply.test.ts +2 -1
  459. package/src/shared/__tests__/persist-decision.test.ts +19 -33
  460. package/src/shared/__tests__/prompt-sections.test.ts +1 -1
  461. package/src/shared/__tests__/stamp-flowed-rows.test.ts +1 -1
  462. package/src/shared/__tests__/status-offload.test.ts +1 -1
  463. package/src/shared/__tests__/streaming-scheduler.test.ts +8 -9
  464. package/src/shared/__tests__/todos.test.ts +1 -1
  465. package/src/shared/__tests__/tool-row.test.ts +1 -1
  466. package/src/shared/approval-policy.ts +95 -0
  467. package/src/shared/args-preview.ts +51 -42
  468. package/src/shared/attachment-resolver.ts +4 -4
  469. package/src/shared/attachment-vision.ts +2 -1
  470. package/src/shared/attachment-zip.ts +2 -2
  471. package/src/shared/cost-guard.ts +2 -2
  472. package/src/shared/exact-apply.ts +1 -1
  473. package/src/shared/execution-context.ts +2 -2
  474. package/src/shared/extract-structured-output.ts +2 -2
  475. package/src/shared/filereview/__tests__/capture.test.ts +9 -5
  476. package/src/shared/filereview/__tests__/git-substrate.test.ts +4 -1
  477. package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +3 -3
  478. package/src/shared/filereview/cas-touched.ts +2 -2
  479. package/src/shared/heartbeat.ts +1 -1
  480. package/src/shared/llm-backend.ts +0 -4
  481. package/src/shared/model-error.ts +1 -2
  482. package/src/shared/persist-decision.ts +19 -28
  483. package/src/shared/prompt-sections.ts +4 -4
  484. package/src/shared/skill-resolver.ts +3 -3
  485. package/src/shared/status-offload.ts +2 -2
  486. package/src/shared/streaming-scheduler.ts +8 -13
  487. package/src/shared/subagent-rows.ts +2 -2
  488. package/src/shared/todos.ts +3 -3
  489. package/src/shared/tool-row.ts +38 -2
  490. package/src/shared/worker-shutdown.ts +1 -1
  491. package/src/shared/workspace/__tests__/git-source.test.ts +3 -3
  492. package/src/shared/workspace/__tests__/provisioner.test.ts +5 -5
  493. package/src/shared/workspace/__tests__/session-provision.test.ts +2 -2
  494. package/src/shared/workspace/__tests__/writeback-coordinator.integration.test.ts +8 -9
  495. package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +25 -25
  496. package/src/shared/workspace/provisioner.ts +1 -1
  497. package/src/shared/workspace/session-provision.ts +1 -1
  498. package/src/shared/workspace/sources/empty.ts +2 -2
  499. package/src/shared/workspace/sources/git.ts +3 -4
  500. package/src/shared/workspace/sources/local-path.ts +5 -6
  501. package/src/shared/workspace/stigmer-link.ts +1 -1
  502. package/src/shared/workspace/types.ts +2 -5
  503. package/src/shared/workspace/writeback-coordinator.ts +23 -12
  504. package/dist/activities/execute-cursor/delta-enricher.d.ts +0 -87
  505. package/dist/activities/execute-cursor/delta-enricher.js +0 -265
  506. package/dist/activities/execute-cursor/delta-enricher.js.map +0 -1
  507. package/dist/activities/execute-cursor/message-translator.js +0 -2040
  508. package/dist/activities/execute-cursor/message-translator.js.map +0 -1
  509. package/dist/activities/execute-cursor/todo-tracker.d.ts +0 -40
  510. package/dist/activities/execute-cursor/todo-tracker.js +0 -80
  511. package/dist/activities/execute-cursor/todo-tracker.js.map +0 -1
  512. package/dist/activities/execute-deep-agent/execution-state.d.ts +0 -54
  513. package/dist/activities/execute-deep-agent/execution-state.js +0 -68
  514. package/dist/activities/execute-deep-agent/execution-state.js.map +0 -1
  515. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +0 -65
  516. package/dist/activities/execute-deep-agent/status-builder-shared.js +0 -90
  517. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +0 -1
  518. package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +0 -113
  519. package/dist/activities/execute-deep-agent/subagent-tracker.js +0 -400
  520. package/dist/activities/execute-deep-agent/subagent-tracker.js.map +0 -1
  521. package/dist/activities/execute-deep-agent/v3-events.d.ts +0 -102
  522. package/dist/activities/execute-deep-agent/v3-events.js +0 -35
  523. package/dist/activities/execute-deep-agent/v3-events.js.map +0 -1
  524. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.d.ts +0 -15
  525. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js +0 -235
  526. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js.map +0 -1
  527. package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +0 -111
  528. package/dist/activities/execute-deep-agent/v3-status-builder.js +0 -457
  529. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +0 -1
  530. package/dist/shared/execution-status-writer.d.ts +0 -31
  531. package/dist/shared/execution-status-writer.js +0 -43
  532. package/dist/shared/execution-status-writer.js.map +0 -1
  533. package/src/activities/execute-cursor/__tests__/delta-enricher.test.ts +0 -310
  534. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -1033
  535. package/src/activities/execute-cursor/__tests__/todo-tracker.test.ts +0 -498
  536. package/src/activities/execute-cursor/delta-enricher.ts +0 -307
  537. package/src/activities/execute-cursor/message-translator.ts +0 -2319
  538. package/src/activities/execute-cursor/todo-tracker.ts +0 -91
  539. package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -148
  540. package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -154
  541. package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +0 -47
  542. package/src/activities/execute-deep-agent/__tests__/v3-protocol-normalizer.test.ts +0 -324
  543. package/src/activities/execute-deep-agent/execution-state.ts +0 -78
  544. package/src/activities/execute-deep-agent/status-builder-shared.ts +0 -142
  545. package/src/activities/execute-deep-agent/subagent-tracker.ts +0 -479
  546. package/src/activities/execute-deep-agent/v3-events.ts +0 -153
  547. package/src/activities/execute-deep-agent/v3-protocol-normalizer.ts +0 -264
  548. package/src/activities/execute-deep-agent/v3-status-builder.ts +0 -565
  549. package/src/shared/execution-status-writer.ts +0 -56
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Live ground truth for the transcript the Cursor harness builds — the one
3
+ * check that proves the translator (`translator.ts`) and the one builder
4
+ * (`harness/transcript/builder.ts`) against what the REAL `@cursor/sdk` sends,
5
+ * through the REAL `ExecuteCursor` activity. The standing instrument an
6
+ * `@cursor/sdk` bump runs before it is trusted, beside
7
+ * `cursor-hook-protocol-live.test.ts` (the hook payloads) and
8
+ * `cursor-sdk-auth-smoke.test.ts` (the credential).
9
+ *
10
+ * WHY THIS EXISTS. The hermetic goldens under `hermetic/` prove the folding
11
+ * rules against the SDK shapes CAPTURED in the scripted double
12
+ * (`__test-utils__/scripted-sdk.ts`). They cannot see the SDK move, and they
13
+ * cannot see the two channels the translator reads — the discrete
14
+ * `run.stream()` events and the fine-grained `onDelta` updates — arrive in the
15
+ * order the real SDK interleaves them. Three facts about a real turn decide
16
+ * whether the transcript the console renders is right, and none is a type:
17
+ *
18
+ * 1. Every row SETTLES. A tool call that ends RUNNING, or an AI message that
19
+ * ends `isStreaming`, is a spinner that never stops.
20
+ * 2. Shell output lands EXACTLY as the command printed it. The stream's own
21
+ * completed `tool_call` carries the final output; `shell-output-delta`
22
+ * chunks, when the SDK sends them, stream into the row while the command
23
+ * runs. Lost output or doubled output (a chunk applied to a row the
24
+ * completion already settled) is the rule #1097 fixed. The prompt
25
+ * prints one line a known number of times over several seconds, so any
26
+ * duplicated or dropped chunk breaks the count.
27
+ * 3. `tool-call-completed` on the delta channel may arrive before or after
28
+ * the stream's own completion; the translator defers to the stream's
29
+ * instant either way. Only a recording of both channels under one
30
+ * sequence shows which order the SDK actually uses. (Observed at 1.0.31,
31
+ * first live run: the delta's completion PRECEDES the stream's completed
32
+ * `tool_call`, three of three; and a 1.2 s `cat` produced no
33
+ * `shell-output-delta` at all — whether a longer command does is printed
34
+ * below, not asserted, because it is the SDK's choice.)
35
+ *
36
+ * HOW. The hermetic driver's LIVE posture (`hermetic-cursor.ts`,
37
+ * `beginLiveCursorScenario`): this file mocks ONLY the control-plane client, so
38
+ * the real activity runs under a real `MockActivityEnvironment` `Context`,
39
+ * persists into an in-memory `ExecutionRecord`, and talks to the real SDK
40
+ * with a real member key on the real clock. The runner's own approval hook is
41
+ * installed and runs (the gate is unconditional; `spec.auto_approve_all`
42
+ * makes it allow), under a temp `HOME` the SDK's own `~/.cursor` state also
43
+ * lands in. The registry fixture keeps pricing and tier pinned and lets every
44
+ * other URL reach the network (`stubRegistryFetch({ live: true })`).
45
+ *
46
+ * The turn's ending is the file review's. The environment pins local artifact
47
+ * storage, so the runtime's capture mode is ON as in production, and a turn
48
+ * that wrote a file ends `EXECUTION_WAITING_FOR_APPROVAL` with the write
49
+ * captured as a change set for review (`hermetic/file-review-capture.test.ts`
50
+ * pins the same ending) — `auto_approve_all` bypasses the tool gate, not the
51
+ * review. So the terminal phase asserted here is COMPLETED, or WAITING with a
52
+ * `candidateCaptured` event on the file-review ledger the runner writes
53
+ * (`file_review_event_stream`; `file_change_sets` is the server's projection
54
+ * of it) and no tool row waiting; a WAITING phase with a tool row at
55
+ * WAITING_APPROVAL would be the gate, and wrong under the bypass.
56
+ *
57
+ * WHAT IT ASSERTS, AND WHAT A FAILURE MEANS. Structural facts of the persisted
58
+ * transcript, never prose (a live model's words are not ours). A live model may
59
+ * also retry — the first run issued the write and the `cat` in one step, the
60
+ * `cat` raced the write and failed, and the model ran a second shell — so the
61
+ * shell facts are read from the LAST shell row, the one that carries the
62
+ * command's final output. Every failure text says which of two readings it
63
+ * supports — the MODEL deviated from the prompt (re-run; not a defect), or the
64
+ * TRANSCRIPT is wrong (a STOP for a bump) — and names the recording as the
65
+ * arbiter: with `CURSOR_EVENT_RECORD_DIR` set, the raw events of both channels
66
+ * are written to `<dir>/<executionId>.cursor-events.jsonl` in arrival order,
67
+ * and this file prints their sequence.
68
+ *
69
+ * Skipped without CURSOR_API_KEY (the sibling arms' convention) — it spends
70
+ * real credits for one two-tool turn. Findings are PRINTED as well as
71
+ * asserted, so a bump's PR can quote what the real SDK sent.
72
+ *
73
+ * Run with:
74
+ * CURSOR_API_KEY=<member key> CURSOR_EVENT_RECORD_DIR=/tmp/cursor-live \
75
+ * CI=1 npx vitest run cursor-transcript-live
76
+ */
77
+ import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
78
+ import { existsSync, readFileSync } from "node:fs";
79
+ import { join } from "node:path";
80
+ import { ExecutionPhase, MessageType, ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
81
+ import type { ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
82
+
83
+ vi.mock("../../../client/stigmer-client.js", async () =>
84
+ (await import("../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
85
+ );
86
+
87
+ import { createHermeticEnvironment, type HermeticEnvironment } from "../../../__test-utils__/hermetic-activity.js";
88
+ import { stubRegistryFetch } from "../../../__test-utils__/model-registry-fixture.js";
89
+ import { approvalCategory } from "../approval-policy.js";
90
+ import { beginLiveCursorScenario, cursorExecutionRecord, runCursorTurn } from "../__test-utils__/hermetic-cursor.js";
91
+
92
+ const CURSOR_API_KEY = process.env.CURSOR_API_KEY ?? "";
93
+ const describeWithCursorKey = CURSOR_API_KEY ? describe : describe.skip;
94
+
95
+ /**
96
+ * Read BEFORE the environment is created: the environment owns the variable
97
+ * for the run (it sets it to this value, or clears it), and restores it after.
98
+ */
99
+ const EVENT_RECORDING_DIR = process.env.CURSOR_EVENT_RECORD_DIR || undefined;
100
+
101
+ /** The one line the shell prints; asserted to appear exactly {@link PROBE_REPEATS} times in the last shell row's stdout. */
102
+ const PROBE_LINE = "transcript probe";
103
+ /** How many times the command prints it, one second apart — output over time, so the SDK has a reason to stream it. */
104
+ const PROBE_REPEATS = 3;
105
+ const SHELL_COMMAND = `for i in 1 2 3; do cat probe.txt; sleep 1; done`;
106
+
107
+ /** The hook-protocol arm's prompt shape: one write, one shell, no questions. */
108
+ const PROMPT =
109
+ "Do exactly two things, in order, without asking questions: " +
110
+ `(1) create a file named probe.txt in the workspace containing the single line '${PROBE_LINE}'; ` +
111
+ `(2) after the file exists, run the shell command \`${SHELL_COMMAND}\`. Then reply with the word done.`;
112
+
113
+ /** The shell tool's result as the SDK renders it into the row (`{"status":"success","value":{...}}`). */
114
+ interface ShellResult {
115
+ readonly status?: unknown;
116
+ readonly value?: { readonly exitCode?: unknown; readonly stdout?: unknown; readonly stderr?: unknown };
117
+ }
118
+
119
+ function parseShellResult(result: string): ShellResult | undefined {
120
+ try {
121
+ return JSON.parse(result) as ShellResult;
122
+ } catch {
123
+ return undefined;
124
+ }
125
+ }
126
+
127
+ /** One line of the recording, as the recorder writes it (`cursor-event-recorder.ts`). */
128
+ interface RecordedLine {
129
+ readonly seq: number;
130
+ readonly channel: "stream" | "delta";
131
+ readonly type: string;
132
+ readonly event?: { readonly subtype?: unknown };
133
+ }
134
+
135
+ function readRecording(dir: string, executionId: string): RecordedLine[] {
136
+ const path = join(dir, `${executionId}.cursor-events.jsonl`);
137
+ if (!existsSync(path)) return [];
138
+ return readFileSync(path, "utf-8")
139
+ .split("\n")
140
+ .filter((line) => line.length > 0)
141
+ .map((line) => JSON.parse(line) as RecordedLine);
142
+ }
143
+
144
+ /** `channel:type` plus the stream event's subtype when it has one (`tool_call` started/completed). */
145
+ function describeLine(line: RecordedLine): string {
146
+ const subtype = line.channel === "stream" && typeof line.event?.subtype === "string" ? `:${line.event.subtype}` : "";
147
+ return `${line.channel}:${line.type}${subtype}`;
148
+ }
149
+
150
+ function countOccurrences(haystack: string, needle: string): number {
151
+ return haystack.split(needle).length - 1;
152
+ }
153
+
154
+ const SETTLED: ReadonlySet<ToolCallStatus> = new Set([
155
+ ToolCallStatus.TOOL_CALL_COMPLETED,
156
+ ToolCallStatus.TOOL_CALL_FAILED,
157
+ ToolCallStatus.TOOL_CALL_SKIPPED,
158
+ ToolCallStatus.TOOL_CALL_INTERRUPTED,
159
+ ]);
160
+
161
+ describeWithCursorKey("ExecuteCursor live — the transcript against the real SDK", () => {
162
+ let env: HermeticEnvironment;
163
+ let registry: ReturnType<typeof stubRegistryFetch>;
164
+
165
+ beforeAll(() => {
166
+ env = createHermeticEnvironment({ eventRecordingDir: EVENT_RECORDING_DIR });
167
+ registry = stubRegistryFetch({ live: true });
168
+ });
169
+
170
+ afterAll(() => {
171
+ registry.restore();
172
+ env.dispose();
173
+ });
174
+
175
+ it("settles every row, lands the shell output exactly as printed, and records both channels in arrival order", async () => {
176
+ // ── Arrange ──────────────────────────────────────────────────────────────
177
+ const record = cursorExecutionRecord({ message: PROMPT, autoApproveAll: true });
178
+ const scenario = beginLiveCursorScenario({ env, record, apiKey: CURSOR_API_KEY });
179
+
180
+ // ── Act ──────────────────────────────────────────────────────────────────
181
+ const invocation = await runCursorTurn(scenario);
182
+
183
+ // ── Findings dump (what a bump's PR quotes) ──────────────────────────────
184
+ const final = record.lastFullStatus;
185
+ const rows = record.toolCalls();
186
+ console.log(`[transcript-live] outcome: ${invocation.outcome.kind}; phases persisted: ${record.persistedPhases.map((p) => ExecutionPhase[p]).join(" → ")}`);
187
+ for (const m of final?.messages ?? []) {
188
+ console.log(`[transcript-live] message type=${MessageType[m.type]} isStreaming=${m.isStreaming} rows=${m.toolCalls.length} content=${JSON.stringify(m.content.slice(0, 80))}`);
189
+ }
190
+ for (const row of rows) {
191
+ console.log(
192
+ `[transcript-live] row name=${row.name} category=${approvalCategory(row.name) ?? "-"} status=${ToolCallStatus[row.status]} ` +
193
+ `argsPreview=${JSON.stringify(row.argsPreview.slice(0, 80))} result=${JSON.stringify(row.result.slice(0, 120))}`,
194
+ );
195
+ }
196
+ const hosts = [...new Set(registry.urls.map((u) => new URL(u).host))];
197
+ console.log(`[transcript-live] fetch hosts dialled: ${hosts.join(", ")}`);
198
+
199
+ const recording = EVENT_RECORDING_DIR ? readRecording(EVENT_RECORDING_DIR, record.executionId) : [];
200
+ if (EVENT_RECORDING_DIR) {
201
+ console.log(`[transcript-live] recording: ${recording.length} lines at ${join(EVENT_RECORDING_DIR, `${record.executionId}.cursor-events.jsonl`)}`);
202
+ console.log(`[transcript-live] sequence: ${recording.map((l) => `${l.seq}=${describeLine(l)}`).join(" ")}`);
203
+ const deltaTypes = new Map<string, number>();
204
+ for (const l of recording) if (l.channel === "delta") deltaTypes.set(l.type, (deltaTypes.get(l.type) ?? 0) + 1);
205
+ console.log(`[transcript-live] delta types: ${[...deltaTypes].map(([t, n]) => `${t}×${n}`).join(", ")}`);
206
+ console.log(
207
+ `[transcript-live] shell-output-delta observed: ${deltaTypes.has("shell-output-delta") ? "YES" : "NO"} (the SDK's choice; printed, not asserted)`,
208
+ );
209
+ }
210
+
211
+ // ── Assert: the turn ended where a captured write turn ends ─────────────
212
+ if (invocation.outcome.kind === "threw") {
213
+ const error = invocation.outcome.error;
214
+ throw new Error(
215
+ `the activity threw instead of returning: ${error instanceof Error ? error.message : String(error)} — ` +
216
+ "a credential or quota refusal from Cursor reads as such in this message and is not a transcript defect; anything else is",
217
+ );
218
+ }
219
+ expect(final, "no full status was persisted").toBeDefined();
220
+ const lastPhase = record.persistedPhases.at(-1);
221
+ const waitingRows = rows.filter((r) => r.status === ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
222
+ // The runner writes the file-review EVENT STREAM (the ledger); `file_change_sets`
223
+ // is the server's projection of it and is never written from here.
224
+ const reviewEvents = (final!.fileReviewEventStream?.events ?? []).map((e) => e.payload.case);
225
+ console.log(`[transcript-live] ending: phase=${lastPhase === undefined ? "-" : ExecutionPhase[lastPhase]} reviewEvents=[${reviewEvents.join(", ")}] waitingRows=${waitingRows.length}`);
226
+ if (lastPhase === ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL) {
227
+ expect(
228
+ waitingRows.map((r) => r.name),
229
+ "the turn waits on a TOOL row under auto_approve_all — the gate did not bypass; the transcript (or the gate) is wrong",
230
+ ).toEqual([]);
231
+ expect(
232
+ reviewEvents,
233
+ "the turn waits but no captured change set is on the file-review ledger — a WAITING phase with nothing to review; the transcript is wrong",
234
+ ).toContain("candidateCaptured");
235
+ } else {
236
+ expect(
237
+ lastPhase,
238
+ "the last persisted phase is neither COMPLETED nor the file review's WAITING — read the phases above",
239
+ ).toBe(ExecutionPhase.EXECUTION_COMPLETED);
240
+ }
241
+
242
+ // ── Assert: fact 1 — every row settled ───────────────────────────────────
243
+ const streaming = final!.messages.filter((m) => m.isStreaming);
244
+ expect(
245
+ streaming.map((m) => m.type),
246
+ "a message is still isStreaming in the COMPLETED status — a spinner that never stops; the transcript is wrong (finalize did not close it)",
247
+ ).toEqual([]);
248
+ const unsettled = rows.filter((r) => !SETTLED.has(r.status));
249
+ expect(
250
+ unsettled.map((r) => `${r.name}=${ToolCallStatus[r.status]}`),
251
+ "a tool call is not settled in the COMPLETED status — the transcript is wrong (a completion the SDK sent was not folded; the recording shows whether it arrived)",
252
+ ).toEqual([]);
253
+
254
+ // ── Assert: the prompt's two actions reached the transcript ──────────────
255
+ const byCategory = (category: "write" | "shell"): ToolCall[] => rows.filter((r) => approvalCategory(r.name) === category);
256
+ const writes = byCategory("write");
257
+ const shells = byCategory("shell");
258
+ expect(
259
+ writes.length,
260
+ "no write-category tool call in the transcript — either the model created the file another way (re-run) or the translator dropped a tool_call (the recording shows a stream tool_call the rows lack; a STOP)",
261
+ ).toBeGreaterThan(0);
262
+ expect(
263
+ shells.length,
264
+ "no shell-category tool call in the transcript — either the model ran no shell command (re-run; the recording shows no shell tool_call from the SDK) or the translator dropped one (the recording shows it; a STOP)",
265
+ ).toBeGreaterThan(0);
266
+
267
+ // ── Assert: fact 2 — the LAST shell row carries the command's output exactly
268
+ const shell = shells.at(-1)!;
269
+ expect(shell.status, "the last shell row did not COMPLETE — the transcript is wrong").toBe(ToolCallStatus.TOOL_CALL_COMPLETED);
270
+ const shellResult = parseShellResult(shell.result);
271
+ expect(
272
+ shellResult?.value,
273
+ `the last shell row's result is not the SDK's {status, value} shape: ${shell.result.slice(0, 160)} — the translator rendered the result differently; a STOP`,
274
+ ).toBeDefined();
275
+ expect(
276
+ shellResult!.value!.exitCode,
277
+ `the last shell command exited ${String(shellResult!.value!.exitCode)} (stderr: ${String(shellResult!.value!.stderr ?? "")}) — the model's command failed (re-run); not a transcript fact`,
278
+ ).toBe(0);
279
+ const stdout = String(shellResult!.value!.stdout ?? "");
280
+ expect(
281
+ countOccurrences(stdout, PROBE_LINE),
282
+ `the last shell row's stdout carries the probe line ${countOccurrences(stdout, PROBE_LINE)} times, not ${PROBE_REPEATS} — ` +
283
+ "fewer is lost output (or the model ran a different command: compare its argsPreview), more is doubled output (a shell-output-delta applied after the completion; the recording shows the order) — either is the transcript being wrong",
284
+ ).toBe(PROBE_REPEATS);
285
+ for (const write of writes) {
286
+ expect(write.status, `the write row ${write.name} did not settle COMPLETED — the transcript is wrong`).toBe(ToolCallStatus.TOOL_CALL_COMPLETED);
287
+ }
288
+
289
+ // ── Assert: fact 3 — the recording holds both channels in one sequence ───
290
+ if (EVENT_RECORDING_DIR) {
291
+ expect(recording.length, "CURSOR_EVENT_RECORD_DIR was set but no recording was written — the recorder was not flushed").toBeGreaterThan(0);
292
+ expect(recording.map((l) => l.seq), "the recording's seq is not the arrival order").toEqual(recording.map((_, i) => i));
293
+ const channels = new Set(recording.map((l) => l.channel));
294
+ expect(channels.has("stream"), "the recording holds no stream event").toBe(true);
295
+ expect(channels.has("delta"), "the recording holds no delta — the onDelta channel was not recorded").toBe(true);
296
+ }
297
+ }, 300_000);
298
+ });
@@ -1,6 +1,8 @@
1
1
  /**
2
- * @regression file-hitl-phase0 — pins the no-storage deny-gate exact-apply seam
3
- * (see _projects/2026-06/20260630.01.file-change-hitl-redesign/tasks/T01_3_regression-manifest.md)
2
+ * @regression file-hitl-phase0 — pins the no-storage deny-gate exact-apply
3
+ * composition: the exact approved bytes are applied AND excluded from the
4
+ * resource grants, so a further write to that path is re-gated while a
5
+ * co-approved shell still flows.
4
6
  *
5
7
  * Deterministic integration proof of the Cursor deny-gate "what you approve is
6
8
  * what gets applied" guarantee, driven through the REAL composition and the REAL
@@ -173,7 +173,7 @@ describe("fetch-interceptor", () => {
173
173
  });
174
174
  });
175
175
 
176
- describe("the token ref is read per request (the root rotates it in place; Q-S2-7)", () => {
176
+ describe("the token ref is read per request (the root rotates it in place)", () => {
177
177
  let proxyTokenRef: { current: string | null };
178
178
 
179
179
  beforeEach(() => {
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * Two goldens, one per invocation: `goldens/deny-and-retry.turn1.status.json`
21
21
  * (the paused transcript) and `goldens/deny-and-retry.turn2.status.json` (the
22
- * resumed, completed transcript). S2 must reproduce both byte for byte.
22
+ * resumed, completed transcript). The runtime must reproduce both byte for byte.
23
23
  *
24
24
  * Parent phase rows exercised beyond `tool-call`: reinvocation detection and
25
25
  * transcript seeding (Phase 3); reading approval decisions from the persisted
@@ -50,6 +50,9 @@ import {
50
50
  vi.mock("@cursor/sdk", async () =>
51
51
  (await import("../../__test-utils__/scripted-sdk.js")).scriptedCursorSdkModule(),
52
52
  );
53
+ vi.mock("@cursor/sdk/sqlite", async () =>
54
+ (await import("../../__test-utils__/scripted-sdk.js")).scriptedCursorSqliteModule(),
55
+ );
53
56
  vi.mock("../../../../client/stigmer-client.js", async () =>
54
57
  (await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
55
58
  );
@@ -137,7 +140,7 @@ describe.skipIf(!hasBash)("ExecuteCursor hermetic — deny-and-retry approval ro
137
140
  step.event(ev2.toolCall(CALL_TURN_2, "shell", "running", SHELL_ARGS)),
138
141
  step.event(ev2.toolCall(CALL_TURN_2, "shell", "completed", SHELL_ARGS, BUILD_OUTPUT)),
139
142
  step.event(ev2.assistant(FINAL_TEXT)),
140
- step.turnEnded({ inputTokens: 3_100, outputTokens: 60 }),
143
+ step.turnEnded({ inputTokens: 3_100, outputTokens: 60, cacheReadTokens: 0, cacheWriteTokens: 0 }),
141
144
  step.finished({ result: FINAL_TEXT, model: { id: FIXTURE.model, params: [] } }),
142
145
  ],
143
146
  ],
@@ -11,7 +11,7 @@
11
11
  * row with the change-set id, and the activity persists WAITING_FOR_APPROVAL
12
12
  * and RETURNS without consulting `run.wait()`. The change-set id is the
13
13
  * deterministic `executionId:turnSeq`. The golden
14
- * (`goldens/file-review-capture.status.json`) pins the ledger shape S2 must
14
+ * (`goldens/file-review-capture.status.json`) pins the ledger shape the runtime must
15
15
  * reproduce.
16
16
  *
17
17
  * Parent phase rows exercised beyond `deny-and-retry`: provision a `local_path`
@@ -42,6 +42,9 @@ import { ExecutionPhase, ToolCallStatus } from "@stigmer/protos/ai/stigmer/agent
42
42
  vi.mock("@cursor/sdk", async () =>
43
43
  (await import("../../__test-utils__/scripted-sdk.js")).scriptedCursorSdkModule(),
44
44
  );
45
+ vi.mock("@cursor/sdk/sqlite", async () =>
46
+ (await import("../../__test-utils__/scripted-sdk.js")).scriptedCursorSqliteModule(),
47
+ );
45
48
  vi.mock("../../../../client/stigmer-client.js", async () =>
46
49
  (await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
47
50
  );
@@ -116,7 +119,7 @@ describe.skipIf(!hasBash)("ExecuteCursor hermetic — file-review capture on a g
116
119
  step.event(ev.toolCall(CALL_ID, "edit", "running", { path: FILE, content: AFTER })),
117
120
  step.event(ev.toolCall(CALL_ID, "edit", "completed", { path: FILE, content: AFTER }, "ok")),
118
121
  step.event(ev.assistant("Done — notes.md now records the review.")),
119
- step.turnEnded({ inputTokens: 2_400, outputTokens: 70 }),
122
+ step.turnEnded({ inputTokens: 2_400, outputTokens: 70, cacheReadTokens: 0, cacheWriteTokens: 0 }),
120
123
  step.finished({ result: "Done", model: { id: FIXTURE.model, params: [] } }),
121
124
  ],
122
125
  ],
@@ -0,0 +1,71 @@
1
+ {
2
+ "messages": [
3
+ {
4
+ "type": "MESSAGE_AI",
5
+ "content": "Searching the docs.",
6
+ "timestamp": "2026-01-01T00:00:02.000Z",
7
+ "toolCalls": [
8
+ {
9
+ "id": "call-hermetic-mcp-0001",
10
+ "name": "search_docs",
11
+ "args": {
12
+ "query": "fixture"
13
+ },
14
+ "result": "1 result: README.md — A fixture readme.",
15
+ "status": "TOOL_CALL_COMPLETED",
16
+ "startedAt": "2026-01-01T00:00:03.000Z",
17
+ "completedAt": "2026-01-01T00:00:04.000Z",
18
+ "mcpServerSlug": "hermetic-docs",
19
+ "argsPreview": "{\"query\":\"fixture\"}",
20
+ "toolKind": "TOOL_KIND_MCP",
21
+ "approvalPolicySource": "APPROVAL_POLICY_SOURCE_CLASSIFIER_DEFAULT",
22
+ "policyEngineVersion": "phase-7"
23
+ }
24
+ ]
25
+ },
26
+ {
27
+ "type": "MESSAGE_AI",
28
+ "content": "One document mentions the fixture: README.md.",
29
+ "timestamp": "2026-01-01T00:00:05.000Z"
30
+ }
31
+ ],
32
+ "phase": "EXECUTION_COMPLETED",
33
+ "startedAt": "2026-01-01T00:00:00.000Z",
34
+ "completedAt": "2026-01-01T00:00:07.000Z",
35
+ "streamingUsage": {
36
+ "inputTokens": "2100",
37
+ "outputTokens": "80",
38
+ "totalTokens": "2180",
39
+ "turnCount": 1,
40
+ "estimatedCostUsd": 0.00242,
41
+ "model": "composer-2.5",
42
+ "observedAt": "2026-01-01T00:00:06.000Z",
43
+ "requestedServiceTier": "SERVICE_TIER_STANDARD",
44
+ "requestedModelParams": "[{\"id\":\"fast\",\"value\":\"false\"},{\"id\":\"thinking\",\"value\":\"false\"}]",
45
+ "requestedThinkingMode": "THINKING_MODE_DISABLED"
46
+ },
47
+ "fileReviewEventStream": {
48
+ "executionId": "aex_hermetic_0001",
49
+ "events": [
50
+ {
51
+ "eventId": "aex_hermetic_0001:0:aex_hermetic_0001:0:FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
52
+ "changeSetId": "aex_hermetic_0001:0",
53
+ "eventType": "FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
54
+ "timestamp": "2026-01-01T00:00:00.000Z",
55
+ "actor": "runner",
56
+ "baselineCaptured": {
57
+ "changeSetId": "aex_hermetic_0001:0",
58
+ "turnId": "aex_hermetic_0001:0",
59
+ "harnessId": "cursor",
60
+ "baselineSnapshot": {
61
+ "kind": "SNAPSHOT_KIND_CAS_MANIFEST"
62
+ }
63
+ }
64
+ }
65
+ ]
66
+ },
67
+ "fileChangeProgress": {
68
+ "changeSetId": "aex_hermetic_0001:0",
69
+ "capturedAt": "2026-01-01T00:00:01.000Z"
70
+ }
71
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "messages": [
3
+ {
4
+ "type": "MESSAGE_AI",
5
+ "content": "Reading the file first.",
6
+ "timestamp": "2026-01-01T00:00:02.000Z",
7
+ "toolCalls": [
8
+ {
9
+ "id": "call-hermetic-tasknote-read-0001",
10
+ "name": "read",
11
+ "args": {
12
+ "path": "README.md"
13
+ },
14
+ "result": "# Hermetic\n\nA fixture readme.\n",
15
+ "status": "TOOL_CALL_COMPLETED",
16
+ "startedAt": "2026-01-01T00:00:05.000Z",
17
+ "completedAt": "2026-01-01T00:00:06.000Z",
18
+ "argsPreview": "{\"path\":\"README.md\"}",
19
+ "toolKind": "TOOL_KIND_FILE_READ"
20
+ }
21
+ ]
22
+ },
23
+ {
24
+ "type": "MESSAGE_SYSTEM",
25
+ "content": "Scanning the workspace for the file.",
26
+ "timestamp": "2026-01-01T00:00:03.000Z"
27
+ },
28
+ {
29
+ "type": "MESSAGE_AI",
30
+ "content": "README.md is a one-line fixture description.",
31
+ "timestamp": "2026-01-01T00:00:07.000Z"
32
+ }
33
+ ],
34
+ "phase": "EXECUTION_COMPLETED",
35
+ "startedAt": "2026-01-01T00:00:00.000Z",
36
+ "completedAt": "2026-01-01T00:00:09.000Z",
37
+ "streamingUsage": {
38
+ "inputTokens": "1800",
39
+ "outputTokens": "50",
40
+ "totalTokens": "1850",
41
+ "turnCount": 1,
42
+ "estimatedCostUsd": 0.002,
43
+ "model": "composer-2.5",
44
+ "observedAt": "2026-01-01T00:00:08.000Z",
45
+ "requestedServiceTier": "SERVICE_TIER_STANDARD",
46
+ "requestedModelParams": "[{\"id\":\"fast\",\"value\":\"false\"},{\"id\":\"thinking\",\"value\":\"false\"}]",
47
+ "requestedThinkingMode": "THINKING_MODE_DISABLED"
48
+ },
49
+ "fileReviewEventStream": {
50
+ "executionId": "aex_hermetic_0001",
51
+ "events": [
52
+ {
53
+ "eventId": "aex_hermetic_0001:0:aex_hermetic_0001:0:FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
54
+ "changeSetId": "aex_hermetic_0001:0",
55
+ "eventType": "FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
56
+ "timestamp": "2026-01-01T00:00:00.000Z",
57
+ "actor": "runner",
58
+ "baselineCaptured": {
59
+ "changeSetId": "aex_hermetic_0001:0",
60
+ "turnId": "aex_hermetic_0001:0",
61
+ "harnessId": "cursor",
62
+ "baselineSnapshot": {
63
+ "kind": "SNAPSHOT_KIND_CAS_MANIFEST"
64
+ }
65
+ }
66
+ }
67
+ ]
68
+ },
69
+ "fileChangeProgress": {
70
+ "changeSetId": "aex_hermetic_0001:0",
71
+ "capturedAt": "2026-01-01T00:00:01.000Z"
72
+ }
73
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "messages": [
3
+ {
4
+ "type": "MESSAGE_AI",
5
+ "content": "Running the tests.",
6
+ "timestamp": "2026-01-01T00:00:24.000Z",
7
+ "toolCalls": [
8
+ {
9
+ "id": "call-hermetic-shelldelta-0003",
10
+ "name": "shell",
11
+ "args": {
12
+ "command": "npm test"
13
+ },
14
+ "status": "TOOL_CALL_FAILED",
15
+ "startedAt": "2026-01-01T00:00:25.000Z",
16
+ "completedAt": "2026-01-01T00:00:27.000Z",
17
+ "error": "sh: npm: command not found",
18
+ "requiresApproval": true,
19
+ "approvalMessage": "Run command: npm test",
20
+ "approvalRequestedAt": "2026-01-01T00:00:27.000Z",
21
+ "argsPreview": "{\"command\":\"npm test\"}",
22
+ "toolKind": "TOOL_KIND_SHELL",
23
+ "approvalPolicySource": "APPROVAL_POLICY_SOURCE_BUILTIN_CATEGORY",
24
+ "policyEngineVersion": "phase-7"
25
+ }
26
+ ]
27
+ },
28
+ {
29
+ "type": "MESSAGE_THINKING",
30
+ "content": "The command failed; npm may be missing.",
31
+ "timestamp": "2026-01-01T00:00:28.000Z"
32
+ },
33
+ {
34
+ "type": "MESSAGE_AI",
35
+ "content": "npm is not installed here.",
36
+ "timestamp": "2026-01-01T00:00:30.000Z"
37
+ }
38
+ ],
39
+ "phase": "EXECUTION_COMPLETED",
40
+ "startedAt": "2026-01-01T00:00:22.000Z",
41
+ "completedAt": "2026-01-01T00:00:32.000Z",
42
+ "streamingUsage": {
43
+ "inputTokens": "2000",
44
+ "outputTokens": "80",
45
+ "totalTokens": "2080",
46
+ "turnCount": 1,
47
+ "estimatedCostUsd": 0.00232,
48
+ "model": "composer-2.5",
49
+ "observedAt": "2026-01-01T00:00:31.000Z",
50
+ "requestedServiceTier": "SERVICE_TIER_STANDARD",
51
+ "requestedModelParams": "[{\"id\":\"fast\",\"value\":\"false\"},{\"id\":\"thinking\",\"value\":\"false\"}]",
52
+ "requestedThinkingMode": "THINKING_MODE_DISABLED"
53
+ },
54
+ "fileReviewEventStream": {
55
+ "executionId": "aex_hermetic_0001",
56
+ "events": [
57
+ {
58
+ "eventId": "aex_hermetic_0001:0:aex_hermetic_0001:0:FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
59
+ "changeSetId": "aex_hermetic_0001:0",
60
+ "eventType": "FILE_REVIEW_EVENT_TYPE_BASELINE_CAPTURED",
61
+ "timestamp": "2026-01-01T00:00:22.000Z",
62
+ "actor": "runner",
63
+ "baselineCaptured": {
64
+ "changeSetId": "aex_hermetic_0001:0",
65
+ "turnId": "aex_hermetic_0001:0",
66
+ "harnessId": "cursor",
67
+ "baselineSnapshot": {
68
+ "kind": "SNAPSHOT_KIND_CAS_MANIFEST"
69
+ }
70
+ }
71
+ }
72
+ ]
73
+ },
74
+ "fileChangeProgress": {
75
+ "changeSetId": "aex_hermetic_0001:0",
76
+ "capturedAt": "2026-01-01T00:00:23.000Z"
77
+ }
78
+ }