@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
@@ -8,9 +8,29 @@
8
8
  * JSON: the per-tool offload does not touch it, and the aggregate size backstop
9
9
  * would replace an oversized preview with an unparseable marker.
10
10
  *
11
- * This module is the single home for arg sanitization shared by both harnesses
12
- * (native re-exports {@link sanitizeArgsPreview} from its status builders; the
13
- * Cursor gate path uses {@link buildElidedArgsPreview}).
11
+ * ONE preview rule for every row (since #1097): the transcript builder
12
+ * stamps every tool row's preview through {@link buildElidedArgsPreview} over
13
+ * {@link SALIENT_ARG_FIELDS}, as `message.proto` promises — sanitized,
14
+ * redacted, at creation, for inline visibility. Until then there were two
15
+ * rules: native stamped a whole-string-truncating `sanitizeArgsPreview` on
16
+ * gated rows only (a preview that could truncate to invalid JSON, acceptable
17
+ * only because native's resume never re-parsed it), and Cursor's stream path
18
+ * stamped `JSON.stringify(args)` unredacted. Both are
19
+ * gone; this module holds the one builder and the one salient list.
20
+ *
21
+ * THE PREVIEW NEVER CARRIES A VALUE IT CANNOT CARRY WHOLE. A non-salient
22
+ * string over the per-value cap is left out of the preview — not replaced by
23
+ * an in-band marker. The marker this module wrote until #1097 (`"[381
24
+ * chars]"`) was a string no reader could tell from content: the approval gate
25
+ * rendered it as the file the user was asked to approve (stigmer#1107). An
26
+ * absent key is the out-of-band signal every reader already handles — a
27
+ * surface that needs the whole value reads the row's `args`, the way the
28
+ * gate does now; the codebase's precedent for "content not included" is a
29
+ * typed fact on the wire (file review's `FileReviewBlockReason`), never a
30
+ * display string, and the approval projection gaining such a fact is a
31
+ * follow-up of its own. The cost, named: the CLI's and ink's one-line preview
32
+ * loses the value's size, and Cursor's recovery digest reads `tool({})` for
33
+ * an MCP tool whose only argument is oversized.
14
34
  */
15
35
 
16
36
  /**
@@ -22,24 +42,27 @@ export const SENSITIVE_ARG_KEYS: ReadonlySet<string> = new Set([
22
42
  "credentials", "auth", "authorization",
23
43
  ]);
24
44
 
25
- /** Whole-preview length cap for {@link sanitizeArgsPreview} (native). */
26
- export const MAX_ARGS_PREVIEW_LENGTH = 500;
27
-
28
45
  /**
29
- * Sanitize args into a compact preview string (native harness behavior).
30
- *
31
- * Redacts sensitive keys, then truncates the whole JSON to a fixed length. The
32
- * truncation can yield invalid JSON, which is acceptable for the native harness
33
- * (its resume model keys on `tool_call_id`, never on a re-parsed preview). The
34
- * Cursor gate path must instead use {@link buildElidedArgsPreview}, which keeps
35
- * the JSON valid and preserves the salient identity fields.
46
+ * Top-level tool-argument fields, in priority order, that identify the specific
47
+ * resource a built-in tool acts on — the values a preview must carry VERBATIM,
48
+ * however long, because an identity is parsed back out of them. The list
49
+ * deliberately spans BOTH taxonomies' arg shapes: Cursor's hook input names a
50
+ * file `file_path` and its stream names it `path`; deepagents' file tools send
51
+ * `file_path`; both name a shell command `command`. Extracting the same
52
+ * resource VALUE on both sides (the absolute path / the command string) is
53
+ * what lets the Cursor hook-recorded denial token equal the stream-computed
54
+ * token. Authored here once (moved from `execute-cursor/approval-policy.ts`
55
+ * in #1097) and injected into the generated preToolUse hook script
56
+ * so the runner and the hook never disagree on which field to match.
36
57
  */
58
+ export const SALIENT_ARG_FIELDS = ["file_path", "path", "target_notebook", "command"] as const;
59
+
37
60
  /**
38
61
  * Redact secret-keyed values (see {@link SENSITIVE_ARG_KEYS}), preserving every
39
- * other entry verbatim. The shared first step of both preview builders, and the
40
- * shape stamped as `args` on interrupt-placeholder tool calls (issue #754's
41
- * header fix): full enough for the UI's path/primary-arg extraction, never
42
- * carrying a secret value.
62
+ * other entry verbatim. The first step of the preview builder, and the shape
63
+ * stamped as `args` on a proposed row the harness recovered from its engine's
64
+ * state (issue #754's header fix): full enough for the UI's path/primary-arg
65
+ * extraction, never carrying a secret value.
43
66
  */
44
67
  export function redactSensitiveArgs(
45
68
  args: Record<string, unknown>,
@@ -51,18 +74,6 @@ export function redactSensitiveArgs(
51
74
  return redacted;
52
75
  }
53
76
 
54
- export function sanitizeArgsPreview(args: Record<string, unknown>): string {
55
- const sanitized = redactSensitiveArgs(args);
56
- try {
57
- const json = JSON.stringify(sanitized);
58
- return json.length > MAX_ARGS_PREVIEW_LENGTH
59
- ? json.slice(0, MAX_ARGS_PREVIEW_LENGTH) + "…"
60
- : json;
61
- } catch {
62
- return "";
63
- }
64
- }
65
-
66
77
  /** Per-string-value cap for {@link buildElidedArgsPreview}. */
67
78
  const MAX_PREVIEW_VALUE_LENGTH = 200;
68
79
 
@@ -70,18 +81,19 @@ const MAX_PREVIEW_VALUE_LENGTH = 200;
70
81
  * Build a compact, ALWAYS-VALID `args_preview` from a tool call's full,
71
82
  * authoritative arguments.
72
83
  *
73
- * Unlike {@link sanitizeArgsPreview} (which truncates the whole string, possibly
74
- * to invalid JSON), this elides oversized string *values* in place — preserving
75
- * every key and the JSON structure. Two invariants make it safe for the Cursor
76
- * gate path:
84
+ * Leaves oversized string *values* out — every other key and the JSON
85
+ * structure kept — rather than truncating the whole string. Two invariants
86
+ * make it safe for the Cursor gate path:
77
87
  * - It NEVER elides a salient field (the resume grant's identity — the file
78
88
  * path or shell command — is parsed back out of this preview, so it must
79
89
  * survive verbatim).
80
90
  * - It redacts secret keys.
81
91
  *
92
+ * For short, secret-free args the output is exactly `JSON.stringify(args)`.
82
93
  * The heavy content (a whole-file body, a large diff) lives on `file_changes`
83
94
  * (offloaded to a ref when large) and `args` (bounded by the size backstop), so
84
- * the preview itself stays small even for a multi-MB write.
95
+ * the preview itself stays small even for a multi-MB write. Unserializable
96
+ * args (a cycle) yield `""`, never a thrown row.
85
97
  *
86
98
  * @param args the full tool arguments
87
99
  * @param salientFields keys whose values must be preserved verbatim (identity)
@@ -94,15 +106,12 @@ export function buildElidedArgsPreview(
94
106
  for (const [key, value] of Object.entries(args)) {
95
107
  if (SENSITIVE_ARG_KEYS.has(key.toLowerCase())) {
96
108
  out[key] = "[REDACTED]";
97
- } else if (
98
- !salientFields.includes(key) &&
99
- typeof value === "string" &&
100
- value.length > MAX_PREVIEW_VALUE_LENGTH
101
- ) {
102
- out[key] = `[${value.length} chars]`;
103
- } else {
104
- out[key] = value;
109
+ continue;
105
110
  }
111
+ const oversized = typeof value === "string" && value.length > MAX_PREVIEW_VALUE_LENGTH;
112
+ // An oversized non-salient value is left out, never marked (see the header).
113
+ if (oversized && !salientFields.includes(key)) continue;
114
+ out[key] = value;
106
115
  }
107
116
  try {
108
117
  return JSON.stringify(out);
@@ -24,7 +24,7 @@
24
24
  * written into the user's own tree would be committed to the session's
25
25
  * write-back branch on completion (`git add -A`), and every real producer —
26
26
  * the CLI's directory attachments, the approved plan the console mounts —
27
- * already stays inside `inputs/` (S3 M1, Q-M1-2; the proto's `/workspace/…`
27
+ * already stays inside `inputs/` (since #1096; the proto's `/workspace/…`
28
28
  * example is a doc issue). The prompt's `<input_files>` section and every
29
29
  * path-derived directive are built from the RESOLVED paths, so prompt and
30
30
  * filesystem can never disagree.
@@ -52,9 +52,9 @@
52
52
  * {@link AttachmentResolutionError}; an archive that fails its guards
53
53
  * aborts with the guard's own `AttachmentValidationError`.
54
54
  *
55
- * Until S3 M1 this resolver ignored `mountPath` and could not extract; the
56
- * native harness's `attachment-injector.ts` did both and was retired at S3
57
- * M2b for this one pipeline (Q-S3-14).
55
+ * Until #1096 this resolver ignored `mountPath` and could not extract; the
56
+ * native harness's `attachment-injector.ts` did both and was retired in that
57
+ * PR for this one pipeline.
58
58
  */
59
59
 
60
60
  import { mkdir, copyFile, readFile, stat, writeFile } from "node:fs/promises";
@@ -118,7 +118,8 @@ export type VisionOutcome =
118
118
  /**
119
119
  * What a harness can actually display inline. The split exists because the
120
120
  * Cursor local transport re-sniffs magic bytes and recognizes ONLY PNG and
121
- * JPEG (verified against @cursor/sdk 1.0.13 dist — the declared mimeType is
121
+ * JPEG (verified against the @cursor/sdk dist at 1.0.13 and again at 1.0.31:
122
+ * the attachment sniff map is exactly JPEG and PNG; the declared mimeType is
122
123
  * discarded), while the LangChain providers accept all four types.
123
124
  */
124
125
  export interface VisionProfile {
@@ -25,8 +25,8 @@
25
25
  * "the manifest promised a file extraction cannot find" is unrepresentable.
26
26
  * The WRITE of an extracted entry is the caller's: the attachment resolver
27
27
  * writes under the session's platform dir (`attachment-resolver.ts`), the
28
- * one caller since S3 M2b retired the native injector. Moved here from that
29
- * injector at S3 M1 (Q-S3-14) so the guards have one home.
28
+ * one caller since #1096 retired the native injector. Moved here from that
29
+ * injector in the same PR so the guards have one home.
30
30
  */
31
31
 
32
32
  import { createInflateRaw } from "node:zlib";
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * ExecutionConfig.max_cost_usd enforcement as a hard stop on a harness turn.
3
3
  *
4
- * Harness-agnostic: the Cursor activity is today's only caller and the turn
5
- * runtime takes it over in S2 M3. The rationale below is Cursor's, and it is
4
+ * Harness-agnostic: the Cursor activity was its only caller until the turn
5
+ * runtime took it over in #1070. The rationale below is Cursor's, and it is
6
6
  * why the module is shaped as a hard stop rather than a middleware.
7
7
  *
8
8
  * The native harness enforces the cap in middleware (cost-cap.ts): tools are
@@ -28,7 +28,7 @@
28
28
  *
29
29
  * SOURCE OF TRUTH — the approved whole-file bytes and target path are read from
30
30
  * the gated tool call's `args` (the authoritative proposed content the deny-gate
31
- * stamped from the hook input; see execute-cursor/message-translator.ts
31
+ * stamped from the hook input; see execute-cursor/boundary-rows.ts
32
32
  * `applyGateInput`). This is the single copy — there is no separate captured
33
33
  * `file_changes` mirror — so "what was shown == what is applied" holds by
34
34
  * construction. (Phase 5 Slice 4 removed the redundant `ToolCall.file_changes`
@@ -15,8 +15,8 @@
15
15
  * `setInterceptorExecutionId`) is whichever turn set it last; this store is
16
16
  * what makes concurrent turns not overwrite each other's headers.
17
17
  *
18
- * Moved from `activities/execute-cursor/fetch-interceptor.ts` (S2 M3,
19
- * Q-M3-12) so `harness/run-turn.ts` can enter it without importing the
18
+ * Moved from `activities/execute-cursor/fetch-interceptor.ts` (#1070)
19
+ * so `harness/run-turn.ts` can enter it without importing the
20
20
  * adapter; the interceptors import it from here. No harness enters it: the
21
21
  * contract lists it among the things deliberately NOT on `TurnSink`.
22
22
  */
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Harness-agnostic, and called from one place: the turn runtime's epilogue
5
5
  * (`harness/run-turn.ts` `extractStructuredOutputFromText`), so both
6
- * harnesses have it — Cursor since S2 M3, native since S3 M2a (pinned by the
7
- * native hermetic `structured-output` tier-2 arm since M2b, Q-S3-7).
6
+ * harnesses have it — Cursor since #1070, native since #1096 (pinned by the
7
+ * native hermetic `structured-output` tier-2 arm).
8
8
  *
9
9
  * When tier-1 text extraction (shared/extract-json.ts) cannot find JSON in
10
10
  * the agent's free-text response, this tier asks an economy-tier LLM to
@@ -1,8 +1,12 @@
1
1
  /**
2
- * @regression file-hitl-phase0 — pins file-edit HITL fixes #7, #8, #9 (see _projects/2026-06/20260630.01.file-change-hitl-redesign/tasks/T01_3_regression-manifest.md)
2
+ * @regression file-hitl-phase0 — pins three rules of git capture mode: a
3
+ * no-commit tree-ref snapshot and restore with one card per changed file;
4
+ * edits stay applied through the WAITING-to-resume boundary and the resume
5
+ * reconciles to the pinned refs; a reject is a DISCARD that COMPLETES, snaps
6
+ * the tree back byte for byte, and partial decisions land only approved files.
3
7
  *
4
8
  * Tests the harness-agnostic capture orchestration directly, under one
5
- * harness id (since S3 M4 the runtime is the ONE caller for every harness,
9
+ * harness id (since #1096 the runtime is the ONE caller for every harness,
6
10
  * `harness/capture.ts`; until then each adapter called this seam and the
7
11
  * Cursor side had its own test, `execute-cursor/capture-flow.test.ts`, whose
8
12
  * three reconcile arms no other file carried moved here). Confirms that the
@@ -235,8 +239,8 @@ describe("capture orchestration — deep-agent harness", () => {
235
239
  // artifact mode. `ProxyArtifactStorage.exists()` reports true for ANY key
236
240
  // (the presign endpoint mints a URL regardless of object existence), so the
237
241
  // old reconcile "found" a CAS manifest that a git-only turn never wrote,
238
- // downloaded it, and died on the R2 `NoSuchKey` 404 (see the ExecuteCursor
239
- // crash in _cursor/error.md). The reconcile must decide "is this a CAS turn?"
242
+ // downloaded it, and died on the R2 `NoSuchKey` 404 (the ExecuteCursor
243
+ // crash `proxy-reconcile.test.ts` reproduces). The reconcile must decide "is this a CAS turn?"
240
244
  // from the change set's CANDIDATE snapshot — a git-only turn carries no cas
241
245
  // ref — so a lying `exists()` can no longer turn a git reconcile into a
242
246
  // doomed download.
@@ -335,7 +339,7 @@ function candidateCompleteness(status: AgentExecutionStatus): DiffCompleteness |
335
339
  : undefined;
336
340
  }
337
341
 
338
- describe("capture reconcile — the decision rules the resume enforces (moved from execute-cursor/capture-flow.test at S3 M4)", () => {
342
+ describe("capture reconcile — the decision rules the resume enforces (moved from execute-cursor/capture-flow.test in #1096)", () => {
339
343
  async function captureTwoFileTurn(status: AgentExecutionStatus): Promise<void> {
340
344
  const baseline = await captureBaselineToLedger({ status, gitRoot: repo, executionId: EXEC_ID, changeSetId: CHANGE_SET_ID, harnessId: HARNESS });
341
345
  await write("notes.md", "planton notes\n");
@@ -1,5 +1,8 @@
1
1
  /**
2
- * @regression file-hitl-phase0 — pins file-edit HITL fixes #7, #8 (see _projects/2026-06/20260630.01.file-change-hitl-redesign/tasks/T01_3_regression-manifest.md)
2
+ * @regression file-hitl-phase0 — pins git capture mode: a no-commit tree-ref
3
+ * snapshot and restore with one card per changed file; edits stay applied
4
+ * through the WAITING-to-resume boundary and the resume reconciles to the
5
+ * pinned refs.
3
6
  *
4
7
  * Unit tests for the git snapshot/restore capture substrate (the PRIMITIVES:
5
8
  * snapshot / capture / restore / apply / recompute / drop).
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * @regression file-hitl-proxy-reconcile — the file-review reconcile crash in
3
- * cloud/desktop (proxy) artifact mode (see _cursor/error.md: an ExecuteCursor
4
- * turn died on `Artifact download failed (HTTP 404) ... NoSuchKey` for a CAS
5
- * manifest a git-only turn never wrote).
3
+ * cloud/desktop (proxy) artifact mode: an ExecuteCursor turn died on
4
+ * `Artifact download failed (HTTP 404) ... NoSuchKey` for a CAS manifest a
5
+ * git-only turn never wrote.
6
6
  *
7
7
  * This exercises the REAL {@link ProxyArtifactStorage} end to end against a mock
8
8
  * proxy + object store, so the whole stack — presign, the ranged-GET existence
@@ -14,9 +14,9 @@
14
14
  * capture ({@link buildCasTurnCaptures}), which composes it into the
15
15
  * {@link CasPathCapture}s the CAS substrate stores.
16
16
  *
17
- * Until S3 M4 each harness carried its own copy of `buildCasTurnCaptures`
17
+ * Until #1096 each harness carried its own copy of `buildCasTurnCaptures`
18
18
  * beside its observation source; the copies were byte-near-identical
19
- * (F-M4-P6) and now live here once. The AFTER bytes are always re-read from
19
+ * and now live here once. The AFTER bytes are always re-read from
20
20
  * disk at composition time (the authoritative net result of the turn), so
21
21
  * many edits to one path collapse to one before/after.
22
22
  */
@@ -13,7 +13,7 @@
13
13
  * heartbeat subject — `@temporalio/activity/lib/index.js`
14
14
  * `Context.heartbeat`, `@temporalio/worker/lib/worker.js` the heartbeat
15
15
  * callback; the SDK's own doc: "Cancellation is not propagated from this
16
- * function"). Until S2 M3 this handle carried two flags for a throw that
16
+ * function"). Until #1070 this handle carried two flags for a throw that
17
17
  * cannot happen; a turn reads its interruption from the signal's reason
18
18
  * instead (`worker-shutdown.ts` `classifyTurnInterruption`).
19
19
  */
@@ -8,10 +8,6 @@
8
8
  * factories run `preflightLlmBackends` at startup, and `model-client.ts`
9
9
  * resolves the backend and translates model ids at construction time; see
10
10
  * `__tests__/vertex-seam.test.ts` for the pinned seam behavior.
11
- *
12
- * Design decision record: stigmer-cloud
13
- * `_projects/2026-08/20260809.01.multi-cloud-llm-provider-endpoints/`
14
- * `design-decisions/001-provider-backends.md`.
15
11
  */
16
12
 
17
13
  import type { LlmProvider } from "./llm-proxy.js";
@@ -14,8 +14,7 @@
14
14
  * errors from the PLATFORM's provider account told customers to top up
15
15
  * consoles they don't own. The cloud proxy rewrites those to a 503
16
16
  * carrying PLATFORM_CAPACITY_SENTINEL (the contract lives in
17
- * stigmer-cloud's PlatformProviderErrorClassifier and the DD at
18
- * _projects/2026-08/20260801.02.provider-error-attribution/); this module
17
+ * stigmer-cloud's PlatformProviderErrorClassifier); this module
19
18
  * is the runner-side half that recognizes the sentinel and, in direct
20
19
  * (BYO-key) mode, attributes billing errors to the user's own account
21
20
  * with actionable wording.
@@ -3,10 +3,17 @@
3
3
  *
4
4
  * Harness-agnostic, and both adapters' stream loops read it
5
5
  * (`execute-cursor/turn-stream.ts`, `execute-deep-agent/turn-stream.ts`; the
6
- * native orchestrator's own copy of the rule retired with it at S3 M2b):
7
- * `shouldPersist = forceFlush || scheduler.shouldSendUpdate(eventCount)`.
8
- * Both harnesses thus share one cadence model — discrete state changes flush
9
- * immediately, high-frequency token deltas ride a bounded time cadence.
6
+ * native orchestrator's own copy of the rule retired with it in #1096):
7
+ * `shouldPersist = transcriptDirty || scheduler.shouldSendUpdate(eventCount)`.
8
+ * Both harnesses thus share one cadence model — a discrete state change
9
+ * flushes immediately, high-frequency token deltas ride a bounded time
10
+ * cadence.
11
+ *
12
+ * One flag, the transcript builder's `dirty` (since #1097). Until then the
13
+ * decision took three Cursor-named flags — the delta enricher's, the todo
14
+ * tracker's and the accumulator's — of which two were constant `false` on
15
+ * both loops once the one builder folded every discrete change; a shape
16
+ * that named writers which no longer existed.
10
17
  *
11
18
  * Extracted as a single pure function so the stream loop and its unit tests
12
19
  * exercise the same implementation and cannot drift.
@@ -14,43 +21,27 @@
14
21
 
15
22
  import type { StreamingUpdateScheduler } from "./streaming-scheduler.js";
16
23
 
17
- /**
18
- * Force-flush signals — discrete, user-visible state changes that must reach the
19
- * live stream immediately, independent of the scheduler's time cadence.
20
- */
21
- export interface ForceFlushSignals {
22
- /** Shell/tool output text accumulated past the delta-enricher debounce. */
23
- readonly deltaEnricherDirty: boolean;
24
- /** The agent's todo list changed. */
25
- readonly todosDirty: boolean;
26
- /**
27
- * A tool call started or reached a terminal status, or a sub-agent was
28
- * delegated/updated (MessageAccumulator.isDirty).
29
- */
30
- readonly contentDirty: boolean;
31
- }
32
-
33
24
  /**
34
25
  * Decide whether to persist the streaming status after a stream event.
35
26
  *
36
- * - forceFlush: any discrete signal flushes now so the live trace (tool calls,
37
- * sub-agents, todos, shell output) is never starved on short turns.
27
+ * - `transcriptDirty`: a discrete, user-visible change landed on the
28
+ * transcript since the last persist (a row started or settled, a sub-agent
29
+ * delegated, a todo written, an artifact registered) and must reach the
30
+ * live stream now, so short turns are never starved.
38
31
  * - scheduler: the shared StreamingUpdateScheduler carries assistant text and
39
32
  * model thinking on a bounded time cadence (500ms floor / 5s keepalive),
40
33
  * avoiding a per-token persist storm.
41
34
  *
42
- * After a persist, the caller must call scheduler.markUpdateSent(eventCount) so
43
- * the cadence resets — matching the native harness.
35
+ * After a persist, the caller calls `scheduler.markUpdateSent(eventCount)` so
36
+ * the cadence resets, and clears the builder's flag as it requests the write.
44
37
  *
45
38
  * @param nowMs Injectable clock forwarded to the scheduler, for tests.
46
39
  */
47
40
  export function shouldPersistStreamingStatus(
48
- signals: ForceFlushSignals,
41
+ transcriptDirty: boolean,
49
42
  scheduler: StreamingUpdateScheduler,
50
43
  eventCount: number,
51
44
  nowMs?: number,
52
45
  ): boolean {
53
- const forceFlush =
54
- signals.deltaEnricherDirty || signals.todosDirty || signals.contentDirty;
55
- return forceFlush || scheduler.shouldSendUpdate(eventCount, nowMs);
46
+ return transcriptDirty || scheduler.shouldSendUpdate(eventCount, nowMs);
56
47
  }
@@ -7,7 +7,7 @@
7
7
  * (`sender-identity.ts`, `declared-preferences.ts`, `recalled-memories.ts`,
8
8
  * `session-context.ts`, `context-bridge.ts`, `attachment-vision.ts`,
9
9
  * `attachment-download-urls.ts`). What the two prompt builders duplicated
10
- * until S3 M5 (Q-S3-10, Q-M2b-8) was the glue around those bodies: the order
10
+ * until #1096 was the glue around those bodies: the order
11
11
  * the five standing sections read in, with the same doctrine comments written
12
12
  * twice; the input-files bullet and disclosure lines; which skills a prompt
13
13
  * highlights when there are many. This module is that glue, written once.
@@ -169,10 +169,10 @@ export interface InputFileLines {
169
169
  /**
170
170
  * The input-files lines over the runtime's own `ResolvedAttachment` — one
171
171
  * type, one truth (a structural twin once lived in each builder; native's
172
- * silently dropped the size, Cursor's was deleted at S3 M5, Q-M5-5).
172
+ * silently dropped the size, Cursor's was deleted in #1096).
173
173
  *
174
174
  * Each bullet discloses the size (so the agent can weigh a read — the field's
175
- * own stated purpose; Cursor's line gained it at S3 M5, Q-M5-3), the original
175
+ * own stated purpose; Cursor's line gained it in #1096), the original
176
176
  * name of a duplicate-renamed file (`attachment-naming.ts`; so the agent can
177
177
  * connect "the two report.pdfs" in the user's message to distinct files on
178
178
  * disk), and the download URL when one was minted
@@ -224,7 +224,7 @@ export interface SkillSelection {
224
224
  * named, so the agent can still activate one on its own judgement (the Agent
225
225
  * Skills spec's progressive disclosure: metadata up front, instructions on
226
226
  * demand). The native harness calls this on every turn; the Cursor harness
227
- * lists every skill today and its adoption is S4's (Q-M5-4).
227
+ * lists every skill today; adopting the selection there is an open item.
228
228
  */
229
229
  export function selectSkillsForPrompt(userMessage: string, skills: readonly SkillMetadata[]): SkillSelection {
230
230
  const filter = filterSkills(
@@ -12,9 +12,9 @@
12
12
  * the control plane, which only the runtime holds, and writes under the
13
13
  * platform dir the runtime owns; the harness renders the returned metadata
14
14
  * into its prompt in its own placement. Moved from
15
- * `activities/execute-cursor/` at S2 M3b; the native harness's twin
16
- * (`skill-writer.ts` `fetchSkillsByRefs` + `mountSkills`) retired at S3 M2b,
17
- * and the module itself at S3 M5 — the one renderer it kept is
15
+ * `activities/execute-cursor/` in #1070; the native harness's twin
16
+ * (`skill-writer.ts` `fetchSkillsByRefs` + `mountSkills`) retired in #1096,
17
+ * and the module itself with it — the one renderer it kept is
18
18
  * `shared/prompt-sections.ts` `alsoAvailableSkillsNote`. This is the one
19
19
  * skills path for every harness.
20
20
  *
@@ -20,7 +20,7 @@
20
20
  * Images are uploaded as their decoded bytes (so the UI can render an
21
21
  * <img>); other large output is uploaded as text with a preview head.
22
22
  * Idempotent and content-hash-deduped so the throttled, repeated persists
23
- * (and result re-inflation by mergeToolCallEvent) upload each blob once.
23
+ * (and result re-inflation by the builder's `tool_finished` upsert) upload each blob once.
24
24
  *
25
25
  * 2. offloadCandidateChangesToFit — an aggregate, storage-backed step for the
26
26
  * file-review ledger: if the status still exceeds the soft cap after (1),
@@ -344,7 +344,7 @@ async function maybeOffloadToolCall(
344
344
  const hash = sha256(result);
345
345
 
346
346
  // Idempotent: the same content was already offloaded on a prior persist (or
347
- // mergeToolCallEvent re-inflated `result` with identical bytes). Re-collapse
347
+ // the builder's finish upsert re-inflated `result` with identical bytes). Re-collapse
348
348
  // the inline copy without re-uploading.
349
349
  if (tc.outputRef && tc.outputRef.contentHash === hash) {
350
350
  tc.result = collapsedResultFor(tc.outputRef);
@@ -19,13 +19,8 @@
19
19
  * the live stream cadence is identical across harnesses.
20
20
  */
21
21
 
22
- export enum UpdateReason {
23
- TIME_THRESHOLD = "time_threshold",
24
- BURST_PROTECTION = "burst_protection",
25
- KEEPALIVE = "keepalive",
26
- FIRST_UPDATE = "first_update",
27
- NONE = "none",
28
- }
22
+ /** Why the scheduler last said "send": the cadence rule that fired, or `none`. */
23
+ export type UpdateReason = "time_threshold" | "burst_protection" | "keepalive" | "first_update" | "none";
29
24
 
30
25
  export interface StreamingConfig {
31
26
  /** Minimum time between updates (ms). Rate limit: max ~2 updates/second. */
@@ -95,7 +90,7 @@ export class StreamingUpdateScheduler {
95
90
 
96
91
  private lastUpdateTime: number;
97
92
  private lastUpdateEvents = 0;
98
- private lastReason: UpdateReason = UpdateReason.NONE;
93
+ private lastReason: UpdateReason = "none";
99
94
  private firstCheck = true;
100
95
 
101
96
  /**
@@ -119,26 +114,26 @@ export class StreamingUpdateScheduler {
119
114
  const eventsSinceLast = eventsProcessed - this.lastUpdateEvents;
120
115
 
121
116
  if (this.firstCheck && eventsSinceLast >= 1) {
122
- this.lastReason = UpdateReason.FIRST_UPDATE;
117
+ this.lastReason = "first_update";
123
118
  return true;
124
119
  }
125
120
 
126
121
  if (timeSinceLastMs >= this.config.minIntervalMs && eventsSinceLast >= 1) {
127
- this.lastReason = UpdateReason.TIME_THRESHOLD;
122
+ this.lastReason = "time_threshold";
128
123
  return true;
129
124
  }
130
125
 
131
126
  if (eventsSinceLast >= this.config.burstThreshold) {
132
- this.lastReason = UpdateReason.BURST_PROTECTION;
127
+ this.lastReason = "burst_protection";
133
128
  return true;
134
129
  }
135
130
 
136
131
  if (timeSinceLastMs >= this.config.maxIntervalMs) {
137
- this.lastReason = UpdateReason.KEEPALIVE;
132
+ this.lastReason = "keepalive";
138
133
  return true;
139
134
  }
140
135
 
141
- this.lastReason = UpdateReason.NONE;
136
+ this.lastReason = "none";
142
137
  return false;
143
138
  }
144
139
 
@@ -7,9 +7,9 @@
7
7
  * infrastructure cancel), so the final snapshot has no permanent IN_PROGRESS
8
8
  * "zombie" delegation. Harness-agnostic (a `SubAgentExecution` is the
9
9
  * platform's row, not an engine's), read by the turn runtime's terminal
10
- * table and the Cursor accumulator's own finalize alike.
10
+ * table and the Cursor settle alike.
11
11
  *
12
- * Moved from `activities/execute-cursor/message-translator.ts` at S2 M3 so
12
+ * Moved from `activities/execute-cursor/message-translator.ts` in #1070 so
13
13
  * the runtime's catch can reach it; the body is unchanged.
14
14
  */
15
15
 
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Todo-list projection shared by every harness's status writer.
2
+ * Todo-list projection the one transcript builder applies for every harness.
3
3
  *
4
4
  * All harnesses expose an agent to-do tool — the Cursor SDK emits `TodoWrite`
5
5
  * (legacy) / `updateTodos` (current), the native deepagents harness emits
6
6
  * `write_todos` — and each writes the SAME `AgentExecutionStatus.todos` proto
7
7
  * map that the clients (React `TodoCard`, CLI) render. This module is the single
8
- * place that maps a raw tool payload into that map, so the Cursor `TodoTracker`
9
- * and the native v2/v3 status builders cannot drift in how they build todos.
8
+ * place that maps a raw tool payload into that map, so the one transcript builder
9
+ * (`harness/transcript/builder.ts`, both harnesses since #1097) has one mapping.
10
10
  *
11
11
  * The mapping is a superset of what any one harness emits: the Cursor SDK sends
12
12
  * per-item `id`/`created_at` and can send a `merge` flag and camelCase statuses;
@@ -17,7 +17,7 @@
17
17
  * shape of legacy (pre-stamping) sessions whose flowed edit rows were hidden.
18
18
  */
19
19
 
20
- import { ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
20
+ import { ApprovalAction, ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
21
21
  import type { AgentMessage, ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
22
22
  import type { SubAgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/subagent_pb";
23
23
  import { extractFilePath } from "./file-tools.js";
@@ -80,7 +80,7 @@ export function stampFileEditRow(tc: ToolCall, changeSetId: string): void {
80
80
  * (the Cursor deny-gate's ledger tokens; a status rule). Omit to stamp
81
81
  * every write/delete row, the deep-agent posture where every such row flowed.
82
82
  *
83
- * One pass for every harness (S3 M4; until then each adapter carried a copy
83
+ * One pass for every harness (since #1096; until then each adapter carried a copy
84
84
  * differing only in the `flowed` predicate).
85
85
  */
86
86
  export function stampFlowedFileEditRows(
@@ -294,3 +294,39 @@ export function collectSettledToolCallIds(
294
294
  }
295
295
  return ids;
296
296
  }
297
+
298
+ /**
299
+ * Whether the server has already adjudicated this row — the user decided its
300
+ * gate (`approval_action`, the server's field; the runner never writes it).
301
+ *
302
+ * Such a row belongs to a gate that is CLOSED: approved and executed, or
303
+ * declined, in an earlier invocation of this execution. No reconciliation of
304
+ * the CURRENT turn may rewrite it — not the denial overlay (a new denial of the
305
+ * same identity is a NEW act and gets its own row), not the twin collapse (the
306
+ * executed row is the transcript's record). Before this rule the overlay matched
307
+ * a denial to the FIRST same-identity row in the whole transcript, flipped a
308
+ * completed, approved row back to WAITING_APPROVAL with its APPROVE still on
309
+ * it, and the next invocation read that as the decision for the new, undecided
310
+ * proposal — an approval bleeding to a later identical act (found by the
311
+ * harness contract kit's invariant 3 against this adapter, #1070).
312
+ */
313
+ export function isAdjudicatedRow(tc: ToolCall): boolean {
314
+ return tc.approvalAction !== ApprovalAction.UNSPECIFIED;
315
+ }
316
+
317
+ /** Adjudicated with a decision that does NOT execute: the user declined this gate. */
318
+ export function isDeclinedRow(tc: ToolCall): boolean {
319
+ switch (tc.approvalAction) {
320
+ case ApprovalAction.SKIP:
321
+ case ApprovalAction.REJECT:
322
+ return true;
323
+ case ApprovalAction.UNSPECIFIED:
324
+ case ApprovalAction.APPROVE:
325
+ case ApprovalAction.APPROVE_ALL:
326
+ return false;
327
+ default: {
328
+ const exhaustive: never = tc.approvalAction;
329
+ throw new Error(`isDeclinedRow: unknown approval action ${String(exhaustive)}`);
330
+ }
331
+ }
332
+ }
@@ -107,7 +107,7 @@ export type TurnInterruption = "worker-shutdown" | "pause" | "infrastructure" |
107
107
  * already aborted and nothing actually interrupted. Shutdown requires a
108
108
  * delivered cancellation alongside the signal.
109
109
  *
110
- * Until S2 M3 the evidence also carried two flags from the periodic
110
+ * Until #1070 the evidence also carried two flags from the periodic
111
111
  * heartbeat ("it threw `CancelledFailure`"), and a delivered cancellation
112
112
  * without them read as "none". `Context.heartbeat()` never throws in the
113
113
  * Temporal TypeScript SDK (it enqueues to the worker's heartbeat subject;