@stigmer/runner 3.15.3-dev.20260914121148 → 3.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (592) hide show
  1. package/README.md +2 -1
  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 +2 -2
  12. package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +61 -0
  13. package/dist/activities/execute-cursor/__test-utils__/fold.js +94 -0
  14. package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -0
  15. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +1 -1
  16. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
  17. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +47 -12
  18. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +41 -10
  19. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
  20. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +15 -6
  21. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +17 -4
  22. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
  23. package/dist/activities/execute-cursor/adapter.d.ts +4 -4
  24. package/dist/activities/execute-cursor/adapter.js +4 -4
  25. package/dist/activities/execute-cursor/approval-policy.d.ts +10 -10
  26. package/dist/activities/execute-cursor/approval-policy.js +12 -23
  27. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  28. package/dist/activities/execute-cursor/approval-state.d.ts +35 -1
  29. package/dist/activities/execute-cursor/approval-state.js +65 -0
  30. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  31. package/dist/activities/execute-cursor/{message-translator.d.ts → boundary-rows.d.ts} +45 -341
  32. package/dist/activities/execute-cursor/boundary-rows.js +1018 -0
  33. package/dist/activities/execute-cursor/boundary-rows.js.map +1 -0
  34. package/dist/activities/execute-cursor/cursor-capabilities.d.ts +1 -1
  35. package/dist/activities/execute-cursor/cursor-capabilities.js +1 -1
  36. package/dist/activities/execute-cursor/cursor-event-recorder.d.ts +33 -14
  37. package/dist/activities/execute-cursor/cursor-event-recorder.js +43 -21
  38. package/dist/activities/execute-cursor/cursor-event-recorder.js.map +1 -1
  39. package/dist/activities/execute-cursor/prompt-builder.d.ts +3 -3
  40. package/dist/activities/execute-cursor/prompt-builder.js +4 -4
  41. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  42. package/dist/activities/execute-cursor/service-tier.js +1 -2
  43. package/dist/activities/execute-cursor/service-tier.js.map +1 -1
  44. package/dist/activities/execute-cursor/sub-agent-steps.d.ts +79 -0
  45. package/dist/activities/execute-cursor/sub-agent-steps.js +180 -0
  46. package/dist/activities/execute-cursor/sub-agent-steps.js.map +1 -0
  47. package/dist/activities/execute-cursor/tool-result.d.ts +49 -0
  48. package/dist/activities/execute-cursor/tool-result.js +130 -0
  49. package/dist/activities/execute-cursor/tool-result.js.map +1 -0
  50. package/dist/activities/execute-cursor/translator.d.ts +178 -0
  51. package/dist/activities/execute-cursor/translator.js +485 -0
  52. package/dist/activities/execute-cursor/translator.js.map +1 -0
  53. package/dist/activities/execute-cursor/turn-boundary.d.ts +15 -5
  54. package/dist/activities/execute-cursor/turn-boundary.js +10 -14
  55. package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
  56. package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
  57. package/dist/activities/execute-cursor/turn-settle.js +47 -34
  58. package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
  59. package/dist/activities/execute-cursor/turn-setup.d.ts +2 -2
  60. package/dist/activities/execute-cursor/turn-setup.js +5 -5
  61. package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
  62. package/dist/activities/execute-cursor/turn-stream.d.ts +23 -14
  63. package/dist/activities/execute-cursor/turn-stream.js +41 -28
  64. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  65. package/dist/activities/execute-cursor/turn.d.ts +4 -4
  66. package/dist/activities/execute-cursor/turn.js +5 -5
  67. package/dist/activities/execute-cursor/usage-pricing.d.ts +2 -2
  68. package/dist/activities/execute-cursor/usage-pricing.js +2 -2
  69. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +2 -2
  70. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +2 -2
  71. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +16 -11
  72. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -10
  73. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
  74. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +1 -1
  75. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -1
  76. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +2 -3
  77. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +2 -3
  78. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -1
  79. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +12 -3
  80. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +18 -4
  81. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
  82. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.d.ts +10 -1
  83. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js +24 -11
  84. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js.map +1 -1
  85. package/dist/activities/execute-deep-agent/adapter.d.ts +1 -1
  86. package/dist/activities/execute-deep-agent/adapter.js +1 -1
  87. package/dist/activities/execute-deep-agent/approval-file-change.d.ts +19 -19
  88. package/dist/activities/execute-deep-agent/approval-file-change.js +16 -15
  89. package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -1
  90. package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +2 -2
  91. package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +2 -2
  92. package/dist/activities/execute-deep-agent/hitl.d.ts +2 -2
  93. package/dist/activities/execute-deep-agent/hitl.js +2 -2
  94. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +13 -3
  95. package/dist/activities/execute-deep-agent/inline-publisher.js +3 -3
  96. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
  97. package/dist/activities/execute-deep-agent/prompt-builder.d.ts +3 -3
  98. package/dist/activities/execute-deep-agent/prompt-builder.js +6 -7
  99. package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
  100. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +16 -8
  101. package/dist/activities/execute-deep-agent/streaming-side-effects.js +20 -33
  102. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  103. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +3 -3
  104. package/dist/activities/execute-deep-agent/subagent-transformer.js +1 -1
  105. package/dist/activities/execute-deep-agent/translator.d.ts +134 -0
  106. package/dist/activities/execute-deep-agent/translator.js +418 -0
  107. package/dist/activities/execute-deep-agent/translator.js.map +1 -0
  108. package/dist/activities/execute-deep-agent/turn-settle.d.ts +13 -7
  109. package/dist/activities/execute-deep-agent/turn-settle.js +34 -45
  110. package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
  111. package/dist/activities/execute-deep-agent/turn-setup.d.ts +8 -8
  112. package/dist/activities/execute-deep-agent/turn-setup.js +7 -7
  113. package/dist/activities/execute-deep-agent/turn-stream.d.ts +13 -10
  114. package/dist/activities/execute-deep-agent/turn-stream.js +44 -41
  115. package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
  116. package/dist/activities/execute-deep-agent/turn.d.ts +3 -3
  117. package/dist/activities/execute-deep-agent/turn.js +3 -3
  118. package/dist/activities/generate-session-subject.d.ts +25 -4
  119. package/dist/activities/generate-session-subject.js +17 -7
  120. package/dist/activities/generate-session-subject.js.map +1 -1
  121. package/dist/client/stigmer-client.d.ts +17 -6
  122. package/dist/client/stigmer-client.js +47 -14
  123. package/dist/client/stigmer-client.js.map +1 -1
  124. package/dist/config.d.ts +6 -3
  125. package/dist/config.js +4 -1
  126. package/dist/config.js.map +1 -1
  127. package/dist/harness/approval-decisions.d.ts +1 -1
  128. package/dist/harness/approval-decisions.js +1 -1
  129. package/dist/harness/capabilities.d.ts +21 -11
  130. package/dist/harness/capabilities.js +2 -2
  131. package/dist/harness/capture.d.ts +4 -4
  132. package/dist/harness/capture.js +4 -4
  133. package/dist/harness/persist-chokepoint.d.ts +3 -3
  134. package/dist/harness/persist-chokepoint.js +3 -3
  135. package/dist/harness/registry.d.ts +2 -2
  136. package/dist/harness/registry.js +2 -2
  137. package/dist/harness/run-turn.d.ts +6 -4
  138. package/dist/harness/run-turn.js +31 -9
  139. package/dist/harness/run-turn.js.map +1 -1
  140. package/dist/harness/stop-controller.d.ts +1 -1
  141. package/dist/harness/stop-controller.js +1 -1
  142. package/dist/harness/terminal-table.d.ts +7 -7
  143. package/dist/harness/terminal-table.js +7 -7
  144. package/dist/harness/transcript/builder.d.ts +182 -0
  145. package/dist/harness/transcript/builder.js +693 -0
  146. package/dist/harness/transcript/builder.js.map +1 -0
  147. package/dist/harness/transcript/events.d.ts +218 -0
  148. package/dist/harness/transcript/events.js +50 -0
  149. package/dist/harness/transcript/events.js.map +1 -0
  150. package/dist/harness/transcript/state.d.ts +110 -0
  151. package/dist/harness/transcript/state.js +148 -0
  152. package/dist/harness/transcript/state.js.map +1 -0
  153. package/dist/harness/turn-context.d.ts +54 -38
  154. package/dist/harness/turn-context.js +42 -43
  155. package/dist/harness/turn-context.js.map +1 -1
  156. package/dist/harness/types.d.ts +63 -22
  157. package/dist/harness/types.js +12 -11
  158. package/dist/harness/types.js.map +1 -1
  159. package/dist/harness/usage-accumulator.d.ts +2 -2
  160. package/dist/harness/usage-accumulator.js +2 -2
  161. package/dist/harness-adapters.d.ts +5 -4
  162. package/dist/harness-adapters.js +5 -4
  163. package/dist/harness-adapters.js.map +1 -1
  164. package/dist/interceptors/run-credential-activity.d.ts +28 -0
  165. package/dist/interceptors/run-credential-activity.js +56 -0
  166. package/dist/interceptors/run-credential-activity.js.map +1 -0
  167. package/dist/middleware/approval-gate.d.ts +6 -0
  168. package/dist/middleware/approval-gate.js +7 -57
  169. package/dist/middleware/approval-gate.js.map +1 -1
  170. package/dist/middleware/cost-advisory.d.ts +3 -3
  171. package/dist/middleware/cost-advisory.js +3 -3
  172. package/dist/middleware/index.d.ts +1 -1
  173. package/dist/middleware/index.js +1 -1
  174. package/dist/runner-manager.js +10 -4
  175. package/dist/runner-manager.js.map +1 -1
  176. package/dist/shared/activity-input.d.ts +9 -0
  177. package/dist/shared/activity-input.js +17 -0
  178. package/dist/shared/activity-input.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-zip.d.ts +2 -2
  188. package/dist/shared/attachment-zip.js +2 -2
  189. package/dist/shared/channel-attachment.d.ts +8 -5
  190. package/dist/shared/channel-attachment.js +10 -6
  191. package/dist/shared/channel-attachment.js.map +1 -1
  192. package/dist/shared/cost-guard.d.ts +2 -2
  193. package/dist/shared/cost-guard.js +2 -2
  194. package/dist/shared/exact-apply.d.ts +1 -1
  195. package/dist/shared/exact-apply.js +1 -1
  196. package/dist/shared/execution-context.d.ts +2 -2
  197. package/dist/shared/execution-context.js +2 -2
  198. package/dist/shared/extract-structured-output.d.ts +2 -2
  199. package/dist/shared/extract-structured-output.js +2 -2
  200. package/dist/shared/filereview/cas-touched.d.ts +2 -2
  201. package/dist/shared/filereview/cas-touched.js +2 -2
  202. package/dist/shared/filereview/progress.d.ts +13 -0
  203. package/dist/shared/filereview/progress.js +13 -0
  204. package/dist/shared/filereview/progress.js.map +1 -1
  205. package/dist/shared/heartbeat.d.ts +1 -1
  206. package/dist/shared/heartbeat.js +1 -1
  207. package/dist/shared/llm-backend.d.ts +0 -4
  208. package/dist/shared/llm-backend.js +0 -4
  209. package/dist/shared/llm-backend.js.map +1 -1
  210. package/dist/shared/memory-attachment.d.ts +16 -9
  211. package/dist/shared/memory-attachment.js +18 -10
  212. package/dist/shared/memory-attachment.js.map +1 -1
  213. package/dist/shared/model-error.d.ts +1 -2
  214. package/dist/shared/model-error.js +1 -2
  215. package/dist/shared/model-error.js.map +1 -1
  216. package/dist/shared/persist-decision.d.ts +18 -24
  217. package/dist/shared/persist-decision.js +19 -11
  218. package/dist/shared/persist-decision.js.map +1 -1
  219. package/dist/shared/prompt-sections.d.ts +4 -4
  220. package/dist/shared/prompt-sections.js +4 -4
  221. package/dist/shared/run-credential-store.d.ts +32 -0
  222. package/dist/shared/run-credential-store.js +39 -0
  223. package/dist/shared/run-credential-store.js.map +1 -0
  224. package/dist/shared/run-credential.d.ts +61 -0
  225. package/dist/shared/run-credential.js +68 -0
  226. package/dist/shared/run-credential.js.map +1 -0
  227. package/dist/shared/skill-resolver.d.ts +3 -3
  228. package/dist/shared/skill-resolver.js +3 -3
  229. package/dist/shared/status-offload.d.ts +1 -1
  230. package/dist/shared/status-offload.js +2 -2
  231. package/dist/shared/status-offload.js.map +1 -1
  232. package/dist/shared/streaming-scheduler.d.ts +2 -7
  233. package/dist/shared/streaming-scheduler.js +6 -14
  234. package/dist/shared/streaming-scheduler.js.map +1 -1
  235. package/dist/shared/subagent-rows.d.ts +2 -2
  236. package/dist/shared/subagent-rows.js +2 -2
  237. package/dist/shared/synthesized-attachment.d.ts +30 -3
  238. package/dist/shared/synthesized-attachment.js +26 -0
  239. package/dist/shared/synthesized-attachment.js.map +1 -1
  240. package/dist/shared/todos.d.ts +3 -3
  241. package/dist/shared/todos.js +3 -3
  242. package/dist/shared/tool-row.d.ts +19 -1
  243. package/dist/shared/tool-row.js +36 -2
  244. package/dist/shared/tool-row.js.map +1 -1
  245. package/dist/shared/worker-shutdown.d.ts +1 -1
  246. package/dist/shared/worker-shutdown.js +1 -1
  247. package/dist/shared/workspace/session-provision.d.ts +1 -1
  248. package/dist/shared/workspace/session-provision.js +1 -1
  249. package/dist/shared/workspace/sources/empty.d.ts +1 -1
  250. package/dist/shared/workspace/sources/empty.js +1 -2
  251. package/dist/shared/workspace/sources/empty.js.map +1 -1
  252. package/dist/shared/workspace/sources/git.js +4 -4
  253. package/dist/shared/workspace/sources/git.js.map +1 -1
  254. package/dist/shared/workspace/sources/local-path.js +6 -6
  255. package/dist/shared/workspace/sources/local-path.js.map +1 -1
  256. package/dist/shared/workspace/stigmer-link.d.ts +1 -1
  257. package/dist/shared/workspace/stigmer-link.js +1 -1
  258. package/dist/shared/workspace/types.d.ts +2 -5
  259. package/dist/shared/workspace/types.js +0 -6
  260. package/dist/shared/workspace/types.js.map +1 -1
  261. package/dist/shared/workspace/writeback-coordinator.d.ts +17 -4
  262. package/dist/shared/workspace/writeback-coordinator.js +7 -9
  263. package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
  264. package/dist/worker.js +10 -3
  265. package/dist/worker.js.map +1 -1
  266. package/dist/workflow-source.d.ts +10 -0
  267. package/dist/workflow-source.js +12 -0
  268. package/dist/workflow-source.js.map +1 -1
  269. package/dist/workflows/execute-from-execution.d.ts +15 -0
  270. package/dist/workflows/execute-from-execution.js +11 -0
  271. package/dist/workflows/execute-from-execution.js.map +1 -1
  272. package/dist/workflows/index.d.ts +5 -3
  273. package/dist/workflows/index.js +5 -3
  274. package/dist/workflows/index.js.map +1 -1
  275. package/dist/workflows/interceptors/run-credential.d.ts +34 -0
  276. package/dist/workflows/interceptors/run-credential.js +71 -0
  277. package/dist/workflows/interceptors/run-credential.js.map +1 -0
  278. package/package.json +4 -4
  279. package/src/__test-utils__/__tests__/execution-record-barrier.test.ts +70 -0
  280. package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +35 -1
  281. package/src/__test-utils__/approval-contract/contract.ts +1 -1
  282. package/src/__test-utils__/approval-contract/types.ts +1 -1
  283. package/src/__test-utils__/harness-boot-order-child.ts +1 -1
  284. package/src/__test-utils__/harness-contract/contract.ts +8 -8
  285. package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
  286. package/src/__test-utils__/harness-contract/runtime-contract.ts +52 -16
  287. package/src/__test-utils__/harness-contract/scripted-adapter.ts +47 -43
  288. package/src/__test-utils__/hermetic-activity.ts +113 -9
  289. package/src/__test-utils__/model-registry-fixture.ts +31 -7
  290. package/src/__test-utils__/module-specifiers.ts +32 -3
  291. package/src/__tests__/harness-boot-order.test.ts +1 -1
  292. package/src/__tests__/harness-contract.test.ts +1 -1
  293. package/src/__tests__/run-credential-e2e.test.ts +233 -0
  294. package/src/__tests__/run-credential-registration.test.ts +80 -0
  295. package/src/__tests__/runner-manager.test.ts +1 -1
  296. package/src/activities/__tests__/generate-session-subject-wire.test.ts +119 -0
  297. package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +1 -1
  298. package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +2 -2
  299. package/src/activities/execute-cursor/__test-utils__/fold.ts +116 -0
  300. package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +1 -1
  301. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +67 -17
  302. package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +19 -5
  303. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +2 -1
  304. package/src/activities/execute-cursor/__tests__/approval-state.test.ts +14 -21
  305. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +3 -3
  306. package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +2 -1
  307. package/src/activities/execute-cursor/__tests__/cursor-event-recorder.test.ts +142 -0
  308. package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +19 -8
  309. package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +10 -8
  310. package/src/activities/execute-cursor/__tests__/cursor-transcript-live.test.ts +298 -0
  311. package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +4 -2
  312. package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +1 -1
  313. package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +1 -1
  314. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -1
  315. package/src/activities/execute-cursor/__tests__/hermetic/goldens/mcp-tool-call.status.json +71 -0
  316. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-task-note.status.json +73 -0
  317. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +78 -0
  318. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +72 -0
  319. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +72 -0
  320. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sub-agent-delegation.status.json +109 -0
  321. package/src/activities/execute-cursor/__tests__/hermetic/goldens/thinking-turn.status.json +78 -0
  322. package/src/activities/execute-cursor/__tests__/hermetic/goldens/todo-write.status.json +119 -0
  323. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-error.status.json +68 -0
  324. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-only-step.status.json +67 -0
  325. package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +1 -1
  326. package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +7 -7
  327. package/src/activities/execute-cursor/__tests__/hermetic/mcp-tool-call.test.ts +146 -0
  328. package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +5 -5
  329. package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +2 -1
  330. package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +2 -1
  331. package/src/activities/execute-cursor/__tests__/hermetic/sdk-task-note.test.ts +122 -0
  332. package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +276 -0
  333. package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +8 -8
  334. package/src/activities/execute-cursor/__tests__/hermetic/sub-agent-delegation.test.ts +196 -0
  335. package/src/activities/execute-cursor/__tests__/hermetic/thinking-turn.test.ts +145 -0
  336. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +1 -1
  337. package/src/activities/execute-cursor/__tests__/hermetic/todo-write.test.ts +165 -0
  338. package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +3 -3
  339. package/src/activities/execute-cursor/__tests__/hermetic/tool-error.test.ts +138 -0
  340. package/src/activities/execute-cursor/__tests__/hermetic/tool-only-step.test.ts +130 -0
  341. package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +13 -1
  342. package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +2 -2
  343. package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +43 -60
  344. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +23 -28
  345. package/src/activities/execute-cursor/__tests__/hook-script.test.ts +2 -1
  346. package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +1 -1
  347. package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +5 -5
  348. package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +11 -13
  349. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +8 -11
  350. package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +8 -22
  351. package/src/activities/execute-cursor/__tests__/translator.test.ts +594 -0
  352. package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +8 -5
  353. package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +87 -63
  354. package/src/activities/execute-cursor/adapter.ts +4 -4
  355. package/src/activities/execute-cursor/approval-policy.ts +12 -24
  356. package/src/activities/execute-cursor/approval-state.ts +66 -1
  357. package/src/activities/execute-cursor/boundary-rows.ts +1132 -0
  358. package/src/activities/execute-cursor/cursor-capabilities.ts +1 -1
  359. package/src/activities/execute-cursor/cursor-event-recorder.ts +57 -28
  360. package/src/activities/execute-cursor/fetch-interceptor.ts +1 -1
  361. package/src/activities/execute-cursor/http2-interceptor.ts +1 -1
  362. package/src/activities/execute-cursor/prompt-builder.ts +6 -6
  363. package/src/activities/execute-cursor/service-tier.ts +1 -2
  364. package/src/activities/execute-cursor/sub-agent-steps.ts +188 -0
  365. package/src/activities/execute-cursor/tool-result.ts +128 -0
  366. package/src/activities/execute-cursor/translator.ts +541 -0
  367. package/src/activities/execute-cursor/turn-boundary.ts +21 -14
  368. package/src/activities/execute-cursor/turn-settle.ts +46 -34
  369. package/src/activities/execute-cursor/turn-setup.ts +5 -5
  370. package/src/activities/execute-cursor/turn-stream.ts +49 -46
  371. package/src/activities/execute-cursor/turn.ts +5 -5
  372. package/src/activities/execute-cursor/usage-pricing.ts +2 -2
  373. package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +2 -2
  374. package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +23 -11
  375. package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +1 -1
  376. package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +2 -3
  377. package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +25 -4
  378. package/src/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.ts +25 -11
  379. package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +1 -1
  380. package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +1 -1
  381. package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +6 -17
  382. package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +25 -8
  383. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +2 -7
  384. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +4 -14
  385. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +1 -5
  386. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +4 -7
  387. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +1 -5
  388. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +2 -9
  389. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +2 -9
  390. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +1 -4
  391. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +1 -4
  392. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +1 -4
  393. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +109 -76
  394. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +1 -5
  395. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +2 -10
  396. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +2 -10
  397. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +1 -5
  398. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +3 -6
  399. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +1 -4
  400. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +1 -4
  401. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/write-todos.status.json +92 -0
  402. package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +3 -3
  403. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +9 -5
  404. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +3 -3
  405. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +3 -3
  406. package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +7 -6
  407. package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +10 -11
  408. package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +4 -4
  409. package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +9 -8
  410. package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +21 -13
  411. package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +2 -2
  412. package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +7 -7
  413. package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +28 -12
  414. package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +21 -21
  415. package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -5
  416. package/src/activities/execute-deep-agent/__tests__/hermetic/write-todos.test.ts +160 -0
  417. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +35 -30
  418. package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +3 -4
  419. package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +12 -10
  420. package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +13 -3
  421. package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +26 -18
  422. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +1 -1
  423. package/src/activities/execute-deep-agent/__tests__/{subagent-tracker.test.ts → translator-subagents.test.ts} +76 -57
  424. package/src/activities/execute-deep-agent/__tests__/{v3-status-builder.test.ts → translator-through-builder.test.ts} +213 -299
  425. package/src/activities/execute-deep-agent/__tests__/translator.test.ts +505 -0
  426. package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +11 -29
  427. package/src/activities/execute-deep-agent/adapter.ts +1 -1
  428. package/src/activities/execute-deep-agent/approval-file-change.ts +20 -22
  429. package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +2 -2
  430. package/src/activities/execute-deep-agent/hitl.ts +2 -2
  431. package/src/activities/execute-deep-agent/inline-publisher.ts +16 -5
  432. package/src/activities/execute-deep-agent/prompt-builder.ts +6 -7
  433. package/src/activities/execute-deep-agent/streaming-side-effects.ts +22 -31
  434. package/src/activities/execute-deep-agent/subagent-transformer.ts +3 -3
  435. package/src/activities/execute-deep-agent/translator.ts +463 -0
  436. package/src/activities/execute-deep-agent/turn-settle.ts +35 -43
  437. package/src/activities/execute-deep-agent/turn-setup.ts +8 -8
  438. package/src/activities/execute-deep-agent/turn-stream.ts +53 -51
  439. package/src/activities/execute-deep-agent/turn.ts +3 -3
  440. package/src/activities/generate-session-subject.ts +29 -4
  441. package/src/client/__tests__/stigmer-client.test.ts +92 -0
  442. package/src/client/stigmer-client.ts +48 -14
  443. package/src/config.ts +6 -3
  444. package/src/harness/README.md +335 -0
  445. package/src/harness/__tests__/approval-decisions.test.ts +2 -2
  446. package/src/harness/__tests__/capture.test.ts +3 -3
  447. package/src/harness/__tests__/import-direction.test.ts +3 -2
  448. package/src/harness/__tests__/mount-skills.test.ts +4 -1
  449. package/src/harness/__tests__/readme-index.test.ts +339 -0
  450. package/src/harness/__tests__/run-turn.test.ts +131 -6
  451. package/src/harness/__tests__/transcript-is-engine-free.test.ts +83 -0
  452. package/src/harness/__tests__/transcript-writers.test.ts +191 -0
  453. package/src/harness/__tests__/turn-attachments-vision.test.ts +5 -2
  454. package/src/harness/__tests__/turn-context.test.ts +5 -5
  455. package/src/harness/approval-decisions.ts +1 -1
  456. package/src/harness/capabilities.ts +21 -11
  457. package/src/harness/capture.ts +4 -4
  458. package/src/harness/persist-chokepoint.ts +3 -3
  459. package/src/harness/registry.ts +2 -2
  460. package/src/harness/run-turn.ts +33 -9
  461. package/src/harness/stop-controller.ts +1 -1
  462. package/src/harness/terminal-table.ts +7 -7
  463. package/src/harness/transcript/__tests__/builder.test.ts +975 -0
  464. package/src/harness/transcript/__tests__/state.test.ts +143 -0
  465. package/src/harness/transcript/builder.ts +755 -0
  466. package/src/harness/transcript/events.ts +262 -0
  467. package/src/harness/transcript/state.ts +167 -0
  468. package/src/harness/turn-context.ts +61 -46
  469. package/src/harness/types.ts +64 -22
  470. package/src/harness/usage-accumulator.ts +2 -2
  471. package/src/harness-adapters.ts +5 -4
  472. package/src/interceptors/__tests__/run-credential-activity.test.ts +133 -0
  473. package/src/interceptors/run-credential-activity.ts +67 -0
  474. package/src/middleware/__tests__/cost-advisory.test.ts +2 -2
  475. package/src/middleware/approval-gate.ts +7 -74
  476. package/src/middleware/cost-advisory.ts +3 -3
  477. package/src/middleware/index.ts +1 -1
  478. package/src/runner-manager.ts +14 -4
  479. package/src/shared/__tests__/approval-policy.test.ts +45 -0
  480. package/src/shared/__tests__/args-preview.test.ts +40 -20
  481. package/src/shared/__tests__/attachment-naming.test.ts +1 -1
  482. package/src/shared/__tests__/attachment-resolver.test.ts +5 -5
  483. package/src/shared/__tests__/attachment-zip.test.ts +1 -1
  484. package/src/shared/__tests__/blueprint-resolver.test.ts +1 -1
  485. package/src/shared/__tests__/channel-attachment.test.ts +12 -0
  486. package/src/shared/__tests__/cost-guard.test.ts +1 -1
  487. package/src/shared/__tests__/exact-apply.test.ts +2 -1
  488. package/src/shared/__tests__/memory-attachment.test.ts +17 -0
  489. package/src/shared/__tests__/persist-decision.test.ts +19 -33
  490. package/src/shared/__tests__/prompt-sections.test.ts +1 -1
  491. package/src/shared/__tests__/run-credential.test.ts +111 -0
  492. package/src/shared/__tests__/stamp-flowed-rows.test.ts +1 -1
  493. package/src/shared/__tests__/status-offload.test.ts +1 -1
  494. package/src/shared/__tests__/streaming-scheduler.test.ts +8 -9
  495. package/src/shared/__tests__/todos.test.ts +1 -1
  496. package/src/shared/__tests__/tool-row.test.ts +1 -1
  497. package/src/shared/activity-input.ts +21 -0
  498. package/src/shared/approval-policy.ts +95 -0
  499. package/src/shared/args-preview.ts +51 -42
  500. package/src/shared/attachment-resolver.ts +4 -4
  501. package/src/shared/attachment-zip.ts +2 -2
  502. package/src/shared/channel-attachment.ts +14 -6
  503. package/src/shared/cost-guard.ts +2 -2
  504. package/src/shared/exact-apply.ts +1 -1
  505. package/src/shared/execution-context.ts +2 -2
  506. package/src/shared/extract-structured-output.ts +2 -2
  507. package/src/shared/filereview/__tests__/capture.test.ts +9 -5
  508. package/src/shared/filereview/__tests__/git-substrate.test.ts +4 -1
  509. package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +3 -3
  510. package/src/shared/filereview/cas-touched.ts +2 -2
  511. package/src/shared/filereview/progress.ts +13 -0
  512. package/src/shared/heartbeat.ts +1 -1
  513. package/src/shared/llm-backend.ts +0 -4
  514. package/src/shared/memory-attachment.ts +22 -10
  515. package/src/shared/model-error.ts +1 -2
  516. package/src/shared/persist-decision.ts +19 -28
  517. package/src/shared/prompt-sections.ts +4 -4
  518. package/src/shared/run-credential-store.ts +45 -0
  519. package/src/shared/run-credential.ts +70 -0
  520. package/src/shared/skill-resolver.ts +3 -3
  521. package/src/shared/status-offload.ts +2 -2
  522. package/src/shared/streaming-scheduler.ts +8 -13
  523. package/src/shared/subagent-rows.ts +2 -2
  524. package/src/shared/synthesized-attachment.ts +38 -3
  525. package/src/shared/todos.ts +3 -3
  526. package/src/shared/tool-row.ts +38 -2
  527. package/src/shared/worker-shutdown.ts +1 -1
  528. package/src/shared/workspace/__tests__/git-source.test.ts +3 -3
  529. package/src/shared/workspace/__tests__/provisioner.test.ts +5 -5
  530. package/src/shared/workspace/__tests__/session-provision.test.ts +2 -2
  531. package/src/shared/workspace/__tests__/writeback-coordinator.integration.test.ts +8 -9
  532. package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +25 -25
  533. package/src/shared/workspace/provisioner.ts +1 -1
  534. package/src/shared/workspace/session-provision.ts +1 -1
  535. package/src/shared/workspace/sources/empty.ts +2 -2
  536. package/src/shared/workspace/sources/git.ts +3 -4
  537. package/src/shared/workspace/sources/local-path.ts +5 -6
  538. package/src/shared/workspace/stigmer-link.ts +1 -1
  539. package/src/shared/workspace/types.ts +2 -5
  540. package/src/shared/workspace/writeback-coordinator.ts +23 -12
  541. package/src/worker.ts +15 -3
  542. package/src/workflow-source.ts +15 -0
  543. package/src/workflows/__tests__/run-credential-interceptor.test.ts +178 -0
  544. package/src/workflows/execute-from-execution.ts +17 -0
  545. package/src/workflows/index.ts +5 -3
  546. package/src/workflows/interceptors/run-credential.ts +101 -0
  547. package/dist/activities/execute-cursor/delta-enricher.d.ts +0 -87
  548. package/dist/activities/execute-cursor/delta-enricher.js +0 -265
  549. package/dist/activities/execute-cursor/delta-enricher.js.map +0 -1
  550. package/dist/activities/execute-cursor/message-translator.js +0 -2040
  551. package/dist/activities/execute-cursor/message-translator.js.map +0 -1
  552. package/dist/activities/execute-cursor/todo-tracker.d.ts +0 -40
  553. package/dist/activities/execute-cursor/todo-tracker.js +0 -80
  554. package/dist/activities/execute-cursor/todo-tracker.js.map +0 -1
  555. package/dist/activities/execute-deep-agent/execution-state.d.ts +0 -54
  556. package/dist/activities/execute-deep-agent/execution-state.js +0 -68
  557. package/dist/activities/execute-deep-agent/execution-state.js.map +0 -1
  558. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +0 -65
  559. package/dist/activities/execute-deep-agent/status-builder-shared.js +0 -90
  560. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +0 -1
  561. package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +0 -113
  562. package/dist/activities/execute-deep-agent/subagent-tracker.js +0 -400
  563. package/dist/activities/execute-deep-agent/subagent-tracker.js.map +0 -1
  564. package/dist/activities/execute-deep-agent/v3-events.d.ts +0 -102
  565. package/dist/activities/execute-deep-agent/v3-events.js +0 -35
  566. package/dist/activities/execute-deep-agent/v3-events.js.map +0 -1
  567. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.d.ts +0 -15
  568. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js +0 -235
  569. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js.map +0 -1
  570. package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +0 -111
  571. package/dist/activities/execute-deep-agent/v3-status-builder.js +0 -457
  572. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +0 -1
  573. package/dist/shared/execution-status-writer.d.ts +0 -31
  574. package/dist/shared/execution-status-writer.js +0 -43
  575. package/dist/shared/execution-status-writer.js.map +0 -1
  576. package/src/activities/execute-cursor/__tests__/delta-enricher.test.ts +0 -310
  577. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -1033
  578. package/src/activities/execute-cursor/__tests__/todo-tracker.test.ts +0 -498
  579. package/src/activities/execute-cursor/delta-enricher.ts +0 -307
  580. package/src/activities/execute-cursor/message-translator.ts +0 -2319
  581. package/src/activities/execute-cursor/todo-tracker.ts +0 -91
  582. package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -148
  583. package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -154
  584. package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +0 -47
  585. package/src/activities/execute-deep-agent/__tests__/v3-protocol-normalizer.test.ts +0 -324
  586. package/src/activities/execute-deep-agent/execution-state.ts +0 -78
  587. package/src/activities/execute-deep-agent/status-builder-shared.ts +0 -142
  588. package/src/activities/execute-deep-agent/subagent-tracker.ts +0 -479
  589. package/src/activities/execute-deep-agent/v3-events.ts +0 -153
  590. package/src/activities/execute-deep-agent/v3-protocol-normalizer.ts +0 -264
  591. package/src/activities/execute-deep-agent/v3-status-builder.ts +0 -565
  592. package/src/shared/execution-status-writer.ts +0 -56
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Hermetic goldens: an INLINE-PUBLISHED ARTIFACT survives a HITL gate — the
3
- * arbiter for Q-S3-16 (the seed's breadth), two invocations on the durable
3
+ * arbiter for the seed's breadth (what a reinvocation carries forward), two
4
+ * invocations on the durable
4
5
  * (sqlite) checkpointer.
5
6
  *
6
7
  * Turn 1: the model writes a report (`write_file`; under capture mode in a
@@ -18,19 +19,19 @@
18
19
  * list is non-empty (`update-status.ts`), so a runtime that seeded messages
19
20
  * only and then published nothing new would carry an empty list — and the
20
21
  * server would keep the old one, but a runtime that published one NEW
21
- * artifact from an empty list would ERASE the prior one. Q-S3-16's
22
+ * artifact from an empty list would ERASE the prior one.
22
23
  * `seedFromPersistedStatus` carries `artifacts` for exactly this reason;
23
24
  * this pair of goldens (`inline-artifact.turn1`, `inline-artifact.turn2`) is
24
25
  * what proves it did.
25
26
  *
26
- * Also recorded, F-M0-8 (a shape fact for the owner): the write's tool row
27
+ * Also recorded (a shape fact, as found): the write's tool row
27
28
  * shows `requiresApproval: true` with `approvalPolicySource` BUILTIN_CATEGORY
28
29
  * — the category policy's verdict — while the row is COMPLETED because
29
30
  * capture mode let it flow; the artifact carries no URL (the local store's
30
31
  * serve URL never enters the record).
31
32
  *
32
- * What every reinvocation golden here shows since S3 M2a (the runtime over
33
- * the native adapter; Q-S3-16 and Q-M2a-2): `startedAt` is THIS turn's own,
33
+ * What every reinvocation golden here shows since #1096 (the runtime over
34
+ * the native adapter): `startedAt` is THIS turn's own,
34
35
  * not turn 1's carried by the orchestrator's whole-status clone; the
35
36
  * `fileReviewEventStream` carries only the events THIS turn authored (the
36
37
  * runtime seeds messages, sub-agents, artifacts, write-backs, todos, usage,
@@ -41,7 +42,7 @@
41
42
  * runtime accountant's fields (`model`, `estimatedCostUsd`, the requested
42
43
  * tier and thinking mode).
43
44
  *
44
- * Golden hunk since S3 M4 (Q-M4-7, ruled Q-M4-12 A): turn 1's
45
+ * Golden hunk since #1096: turn 1's
45
46
  * `fileChangeProgress` is the TRUE snapshot at the WAITING write
46
47
  * (`filesChanged: 1`, `report.md` ADD +3, `capturedAt` t=2) where it was a
47
48
  * stale t=0 snapshot taken by the stream loop before the engine wrote the
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Hermetic goldens: the two ways a turn is INTERRUPTED from outside, and how
3
3
  * the activity tells them apart — the throw-vs-return table the control
4
- * plane's workflow keys on. Since S3 M2a the activity is the turn runtime
4
+ * plane's workflow keys on. Since #1096 the activity is the turn runtime
5
5
  * over the native adapter, and the shapes below are the runtime's terminal
6
- * table (`harness/terminal-table.ts`), ruled at Q-S3-7 (P-1: the pause copy
7
- * is Cursor's) and stigmer#1071 ("persist a thrown terminal once").
6
+ * table (`harness/terminal-table.ts`; the pause copy is Cursor's) and
7
+ * stigmer#1071 ("persist a thrown terminal once").
8
8
  *
9
9
  * 1. USER PAUSE: the activity's `cancellationSignal` aborts. Whether the
10
10
  * abort lands inside a model call (staged from the scripted model's
@@ -13,11 +13,11 @@
13
13
  * stop controller aborts the adapter's signal, the adapter cancels the
14
14
  * graph run and settles `interrupted`, and the runtime persists PAUSED
15
15
  * ONCE — WITH the transcript and the row "Execution paused by user. Use
16
- * resume to continue." (P-1: the runtime's pause copy is Cursor's; the
16
+ * resume to continue." (the runtime's pause copy is Cursor's; the
17
17
  * orchestrator's said "… from this checkpoint.") — then throws
18
- * `CancelledFailure("Activity paused by orchestrator")`. Until M2a the
18
+ * `CancelledFailure("Activity paused by orchestrator")`. Until #1096 the
19
19
  * orchestrator persisted PAUSED TWICE, the second write bare and erasing
20
- * the transcript (S3 M0 finding F-M0-6, stigmer#1054's double persist);
20
+ * the transcript (stigmer#1054's double persist);
21
21
  * `pause.bare.status.json` recorded that write and is gone with it. The
22
22
  * one write differs by where the cancel landed — after the tool finished
23
23
  * (`pause.loop.after-tool`) or while it was still RUNNING
@@ -28,7 +28,7 @@
28
28
  * copy and one row, thrown as
29
29
  * `CancelledFailure("Activity cancelled (worker shutdown, not user pause)")`
30
30
  * (#776) — the workflow re-invokes instead of waiting for a resume. The
31
- * copy is unchanged; what changed at M2a (Q-S3-7, the runtime's arm
31
+ * copy is unchanged; what changed in #1096 (the runtime's arm
32
32
  * wins) is that the runtime's arm KEEPS the transcript the turn produced
33
33
  * and appends the row, where the orchestrator's `buildWorkerShutdownStatus`
34
34
  * replaced the whole status with the row alone.
@@ -145,7 +145,7 @@ describe("ExecuteDeepAgent hermetic — pause vs worker shutdown", () => {
145
145
  expect(record.persistedPhases).toEqual([ExecutionPhase.EXECUTION_IN_PROGRESS, ExecutionPhase.EXECUTION_PAUSED]);
146
146
 
147
147
  const pausedWrites = record.persisted.filter((s) => s.phase === ExecutionPhase.EXECUTION_PAUSED);
148
- expect(pausedWrites, "PAUSED is persisted exactly once (stigmer#1071; F-M0-6 closed at M2a)").toHaveLength(1);
148
+ expect(pausedWrites, "PAUSED is persisted exactly once (stigmer#1071)").toHaveLength(1);
149
149
  const [paused] = pausedWrites;
150
150
  expect(paused.messages.filter((m) => m.type === MessageType.MESSAGE_SYSTEM).map((m) => m.content)).toEqual([
151
151
  "Execution paused by user. Use resume to continue.",
@@ -188,11 +188,10 @@ describe("ExecuteDeepAgent hermetic — pause vs worker shutdown", () => {
188
188
  const final = record.lastFullStatus!;
189
189
  expect(final.error).toBe("Execution interrupted: runner worker was shut down. Retry or resume.");
190
190
  // The transcript the turn produced is kept and the row appended (the
191
- // runtime's arm, Q-S3-7); the tool row rides its own empty AI message
192
- // (F-M0-1, S4's).
191
+ // runtime's arm); the tool row sits on the message whose text
192
+ // proposed it (since #1097 — until then on its own empty message).
193
193
  expect(final.messages.map((m) => [m.type, m.content])).toEqual([
194
194
  [MessageType.MESSAGE_AI, "Let me look."],
195
- [MessageType.MESSAGE_AI, ""],
196
195
  [
197
196
  MessageType.MESSAGE_SYSTEM,
198
197
  "Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",
@@ -5,12 +5,12 @@
5
5
  *
6
6
  * Invariant pinned: the activity resolves the four-resource chain, builds the
7
7
  * REAL deepagents graph, streams it through the v3 protocol into
8
- * `V3StatusBuilder`, persists IN_PROGRESS then COMPLETED, and returns the slim
8
+ * `TranscriptBuilder`, persists IN_PROGRESS then COMPLETED, and returns the slim
9
9
  * status. The golden (`goldens/plain-turn.status.json`) is the smallest
10
10
  * status the native harness produces: one AI message with the scripted text
11
11
  * and the scripted usage, `startedAt` / `completedAt` on the scripted clock.
12
12
  *
13
- * This file is also the PROBE the M0 plan named: no earlier test drove the
13
+ * This file is also the PROBE the native net opened with (#1096): no earlier test drove the
14
14
  * real graph through `streamEvents(..., { version: "v3" })`. The scripted
15
15
  * model streams, so the events under this golden are the ones a provider
16
16
  * produces (`scripted-model.ts` header).
@@ -22,10 +22,10 @@
22
22
  * `thread_id` (carried from `index.test.ts`: "handles empty threadId
23
23
  * gracefully").
24
24
  *
25
- * Since S3 M2a the activity is the turn runtime over the native adapter, and
25
+ * Since #1096 the activity is the turn runtime over the native adapter, and
26
26
  * `streamingUsage` carries the runtime accountant's fields — `model`,
27
27
  * `estimatedCostUsd` priced at the registry's rates, the requested tier and
28
- * thinking mode (Q-M2a-2: one writer of the summary, the runtime). Nothing
28
+ * thinking mode (one writer of the summary, the runtime). Nothing
29
29
  * else in this golden moved with the flip.
30
30
  *
31
31
  * Regenerate ONLY after a deliberate behavior change:
@@ -4,21 +4,21 @@
4
4
  *
5
5
  * What the arm does: the record's `controlSignal` answers STOP on the first
6
6
  * full write that carries a tool row (the tool-call boundary forces that
7
- * persist, `persist-decision.ts` `contentDirty`); the runtime's chokepoint
7
+ * persist, `persist-decision.ts` over the builder's `dirty` flag); the runtime's chokepoint
8
8
  * reads the signal off the write and aborts the adapter's `stopSignal`; the
9
9
  * adapter's loop, which AWAITED that persist, sees the abort before it pulls
10
10
  * the next event, cancels the graph run and settles `interrupted`; the
11
11
  * runtime's table maps the stop to COMPLETED with `platformStopArm`'s one
12
12
  * row, "Execution stopped by the platform.", no `status.error`, and RETURNS.
13
13
  *
14
- * Ruled at Q-S3-3 (a platform STOP is the platform saying "stop spending
15
- * now"; the runtime's abort is the one stop) and landed at S3 M2a. Until
14
+ * The rule (a platform STOP is the platform saying "stop spending
15
+ * now"; the runtime's abort is the one stop) landed in #1096. Until
16
16
  * then the orchestrator answered STOP by activating `graceful-stop.ts`,
17
17
  * which handed the model one more tool-free round: the transcript carried
18
18
  * the model's wrap-up ("Stopping here as asked.") AND the middleware's own
19
- * notice rendered as the agent's words (F-M0-7), and the run ended
20
- * COMPLETED with no row. The graceful-stop middleware was deleted at S3 M2b
21
- * (Q-M2a-4 sequenced it after the legacy loop that activated it); nothing in
19
+ * notice rendered as the agent's words, and the run ended
20
+ * COMPLETED with no row. The graceful-stop middleware was deleted in #1096
21
+ * (after the legacy loop that activated it); nothing in
22
22
  * the graph answers a STOP any more, so the second scripted turn is never
23
23
  * reached — this golden was byte-identical across the deletion.
24
24
  *
@@ -74,7 +74,7 @@ describe("ExecuteDeepAgent hermetic — platform STOP", () => {
74
74
  env.dispose();
75
75
  });
76
76
 
77
- it("stops the run at the STOP and completes with the platform-stop row (Q-S3-3)", async () => {
77
+ it("stops the run at the STOP and completes with the platform-stop row", async () => {
78
78
  // ── Arrange ──────────────────────────────────────────────────────────────
79
79
  let stopsAnswered = 0;
80
80
  const record = deepAgentExecutionRecord({
@@ -113,7 +113,8 @@ describe("ExecuteDeepAgent hermetic — platform STOP", () => {
113
113
  "Execution stopped by the platform.",
114
114
  ]);
115
115
  const ai = final.messages.filter((m) => m.type === MessageType.MESSAGE_AI).map((m) => m.content);
116
- expect(ai, "no wrap-up round and no injected notice: the run stopped at the STOP").toEqual(["Let me look.", ""]);
116
+ expect(ai, "no wrap-up round and no injected notice: the run stopped at the STOP").toEqual(["Let me look."]);
117
+ expect(final.messages[0].toolCalls.map((tc) => tc.name), "the row sits on the text that proposed it").toEqual(["read_file"]);
117
118
  expect(ai).not.toContain(WRAP_UP);
118
119
 
119
120
  // ── Assert: hermeticity ──────────────────────────────────────────────────
@@ -14,8 +14,8 @@
14
14
  * (matched with `startsWith` by stigmer-cloud's `reply-extractor.ts`) and
15
15
  * its row, PERSISTS it, and returns the slim.
16
16
  *
17
- * Ruled at Q-S3-6 and landed at S3 M2a. Until then the orchestrator RETURNED
18
- * the TERMINATED status but never PERSISTED it (S3 M0 finding F-M0-4, a
17
+ * The rule landed in #1096. Until then the orchestrator RETURNED
18
+ * the TERMINATED status but never PERSISTED it (a
19
19
  * production defect): the last status the control plane held was the
20
20
  * stream's mid-run IN_PROGRESS with no error, and only the activity's return
21
21
  * value carried the truth. The golden
@@ -23,18 +23,20 @@
23
23
  * TERMINATED status the control plane holds, which is what that fix changed
24
24
  * on purpose.
25
25
  *
26
- * Also visible here, F-M0-1 at scale: every tool row of the run sits on ONE
27
- * empty AI message, because `ensureAiMessageForToolCall("")` creates it once
28
- * and `currentAiMessage[""]` then catches every later row.
26
+ * Also visible here, the message boundary at scale (since #1097): every tool
27
+ * row sits on the "Reading file N." message whose text proposed it. Until
28
+ * then all of them sat on ONE empty AI message: the namespace miss created the
29
+ * empty message once and its `currentAiMessage[""]` then caught every later
30
+ * row.
29
31
  *
30
32
  * How many rounds fit is the middleware stack's shape, not the knob's
31
- * (S3 M2b, owner ruling 2026-09-13 on F-M2b-26): LangChain makes every
33
+ * (ruled 2026-09-13, #1096): LangChain makes every
32
34
  * middleware hook its own graph node, and `max_tool_rounds` becomes a
33
35
  * super-step budget at the ×6 floor estimate, so a node fewer per round
34
36
  * means more rounds within the same 60 steps. When `graceful-stop.ts` (an
35
- * `afterModel` node) was deleted with Q-S3-3, this golden went from 11 tool
37
+ * `afterModel` node) was deleted in #1096, this golden went from 11 tool
36
38
  * calls to 13 before TERMINATED — the only hunk, the copy unchanged. That the
37
- * knob counts super-steps and not rounds is recorded as an S5 design item
39
+ * knob counts super-steps and not rounds is recorded as #1113
38
40
  * (a round counter in the budget middleware would make it mean what it
39
41
  * says); this file pins what the stack delivers today.
40
42
  *
@@ -88,7 +90,7 @@ describe("ExecuteDeepAgent hermetic — tool-call budget exhausted", () => {
88
90
  env.dispose();
89
91
  });
90
92
 
91
- it("returns TERMINATED with the cross-repo prefix, and persists nothing past IN_PROGRESS (F-M0-4)", async () => {
93
+ it("returns TERMINATED with the cross-repo prefix, and persists that terminal", async () => {
92
94
  // ── Arrange ──────────────────────────────────────────────────────────────
93
95
  const record = deepAgentExecutionRecord({ message: "Keep reading files.", maxToolRounds: MIN_TOOL_ROUNDS });
94
96
  const scenario = beginDeepAgentScenario({
@@ -113,21 +115,27 @@ describe("ExecuteDeepAgent hermetic — tool-call budget exhausted", () => {
113
115
  expect(slim.phase).toBe("EXECUTION_TERMINATED");
114
116
  expect(String(slim.error).startsWith(TOOL_CALL_LIMIT_ERROR_PREFIX), "the cross-repo prefix").toBe(true);
115
117
 
116
- // ── Assert: what the control plane holds (F-M0-4 closed) ─────────────────
118
+ // ── Assert: what the control plane holds ─────────────────────────────────
117
119
  expect(record.persistedPhases, "the TERMINATED terminal is persisted").toEqual([
118
120
  ExecutionPhase.EXECUTION_IN_PROGRESS,
119
121
  ExecutionPhase.EXECUTION_TERMINATED,
120
122
  ]);
121
123
  const persisted = record.lastFullStatus!;
122
124
  expect(String(persisted.error).startsWith(TOOL_CALL_LIMIT_ERROR_PREFIX), "the persisted error carries the prefix").toBe(true);
123
- expect(persisted.error, "the event count left the copy (Q-S3-6)").not.toMatch(/\d+ events?/);
125
+ expect(persisted.error, "the event count left the copy").not.toMatch(/\d+ events?/);
124
126
  expect(persisted.completedAt).not.toBe("");
125
127
  const rows = record.toolCalls();
126
128
  expect(rows.length, "fewer rounds ran than were scripted: the budget stopped the graph").toBeLessThan(SCRIPTED_ROUNDS);
127
129
  expect(rows.length).toBeGreaterThanOrEqual(MIN_TOOL_ROUNDS);
130
+ // The message boundary: every row sits on the message whose text proposed it
131
+ // — one "Reading file N." message per row, no empty host (before #1097 all
132
+ // thirteen rows sat on ONE empty message).
128
133
  const rowHosts = persisted.messages.filter((m) => m.type === MessageType.MESSAGE_AI && m.toolCalls.length > 0);
129
- expect(rowHosts, "F-M0-1: every row on one empty AI message").toHaveLength(1);
130
- expect(rowHosts[0].content).toBe("");
134
+ expect(rowHosts).toHaveLength(rows.length);
135
+ for (const host of rowHosts) {
136
+ expect(host.content).toMatch(/^Reading file \d+\.$/);
137
+ expect(host.toolCalls).toHaveLength(1);
138
+ }
131
139
 
132
140
  // ── Assert: hermeticity ──────────────────────────────────────────────────
133
141
  expect(registry.urls.every((u) => u.includes("/model-registry"))).toBe(true);
@@ -12,11 +12,11 @@
12
12
  * Temporal retry a deterministic failure). Nothing streamed, no lock taken
13
13
  * (the fault precedes the lock phase), no artifacts.
14
14
  *
15
- * The row shape is one of Q-S3-7's ruled alignments, landed at S3 M2a: the
15
+ * The row shape is one of the alignments #1096 made on purpose: the
16
16
  * orchestrator wrote one row `"Error: [Error] <message>"`; the runtime's arm
17
17
  * writes the boilerplate plus the details row. `status.error` itself did
18
18
  * not move (the conformance suite pins it). The setup labels are the
19
- * runtime's resolution phases' (a stated default of the M2a plan).
19
+ * runtime's resolution phases'.
20
20
  *
21
21
  * Carried from `index.test.ts` ("returns EXECUTION_FAILED status when setup
22
22
  * fails", "includes error message in failed status", "always returns a
@@ -13,13 +13,13 @@
13
13
  * 2. The text fallback (the runtime's tier 1): the model answers in prose
14
14
  * with a fenced JSON block and `shared/extract-json.ts` recovers the
15
15
  * object from the final text (`run-turn.ts` `extractStructuredOutputFromText`).
16
- * 3. The LLM fallback (the runtime's tier 2, Q-S3-7): the final text carries
16
+ * 3. The LLM fallback (the runtime's tier 2): the final text carries
17
17
  * no JSON at all, so the runtime asks a second model — the registry's
18
18
  * economy tier for the primary's provider — to extract it through
19
19
  * `withStructuredOutput` (`shared/extract-structured-output.ts`). Native
20
- * gained this arm at S3 M2a, when the turn runtime took the epilogue
21
- * over; it is pinned here since M2b (F-M2b-14), where every other ruled
22
- * alignment is. Two facts the golden records: the extraction call is a
20
+ * gained this arm in #1096, when the turn runtime took the epilogue
21
+ * over; it is pinned here, where every other alignment of that move
22
+ * is. Two facts the golden records: the extraction call is a
23
23
  * SECOND model build (`maxTokens: 4096`, on the primary — the fixture
24
24
  * registry declares no economy row, `getEconomyModel`'s last resort),
25
25
  * and its tool call never reaches the transcript (it is not a graph
@@ -38,10 +38,10 @@
38
38
  * `extract` (`withStructuredOutput` with no name), bound on the extraction
39
39
  * model alone, which is how the script tells the two calls apart.
40
40
  *
41
- * Since S3 M2a the activity is the turn runtime over the native adapter, and
41
+ * Since #1096 the activity is the turn runtime over the native adapter, and
42
42
  * `streamingUsage` carries the runtime accountant's fields — `model`,
43
43
  * `estimatedCostUsd` priced at the registry's rates, the requested tier and
44
- * thinking mode (Q-M2a-2: one writer of the summary, the runtime). Nothing
44
+ * thinking mode (one writer of the summary, the runtime). Nothing
45
45
  * else in this golden moved with the flip.
46
46
  *
47
47
  * Regenerate ONLY after a deliberate behavior change:
@@ -176,7 +176,7 @@ describe("ExecuteDeepAgent hermetic — structured output", () => {
176
176
  await expect(json).toMatchFileSnapshot("./goldens/structured-output.text-fallback.status.json");
177
177
  });
178
178
 
179
- it("LLM fallback (tier 2): prose with no JSON is extracted by a second model call the transcript never sees (Q-S3-7)", async () => {
179
+ it("LLM fallback (tier 2): prose with no JSON is extracted by a second model call the transcript never sees", async () => {
180
180
  // ── Arrange ──────────────────────────────────────────────────────────────
181
181
  clock.reset();
182
182
  // The OSS direct-credential posture, for this arm only: with no proxy the
@@ -8,35 +8,51 @@
8
8
  * runner's `shell`) on the SAME model double through `modelFactory`; the root
9
9
  * proposes `task({ subagent_type, description })`; the tools node runs the
10
10
  * sub-agent graph under a nested namespace (`tools:<uuid>|...`); the
11
- * `SubAgentTracker` opens a `SubAgentExecution` keyed by the `task` call id
12
- * (not by the namespace uuid, which never reaches the status), routes the
13
- * nested model events into its own transcript, and closes it COMPLETED when
14
- * the `task` tool finishes; the root's transcript carries the `task` row and
15
- * its closing text. The golden (`goldens/sub-agent-delegation.status.json`)
16
- * pins the nested transcript shape S4 must reproduce.
11
+ * translator's `sub_agent_started` opens a `SubAgentExecution` keyed by the
12
+ * `task` call id (not by the namespace uuid, which never reaches the status),
13
+ * the builder folds the nested model events into that row's own transcript
14
+ * scope, and `sub_agent_finished` closes it COMPLETED when the `task` tool
15
+ * finishes; the root's transcript carries the `task` row and its closing
16
+ * text. The golden (`goldens/sub-agent-delegation.status.json`) pins the
17
+ * nested transcript shape; its three moves in #1097 are quoted below with
18
+ * their reasons, and every other line is byte-identical through that PR.
17
19
  *
18
20
  * Role selection: `createDeepAgent` gives the sub-agent the same tool set as
19
21
  * its parent (`task` included), so the script tells the roles apart by the
20
22
  * system prompt (`ScriptRoleContext.systemPrompt`), which carries the
21
23
  * sub-agent's own instructions — the one thing that differs.
22
24
  *
23
- * Since S3 M2a the activity is the turn runtime over the native adapter, and
25
+ * Since #1096 the activity is the turn runtime over the native adapter, and
24
26
  * `streamingUsage` carries the runtime accountant's fields — `model`,
25
27
  * `estimatedCostUsd` priced at the registry's rates, the requested tier and
26
- * thinking mode (Q-M2a-2: one writer of the summary, the runtime). Nothing
28
+ * thinking mode (one writer of the summary, the runtime). Nothing
27
29
  * else in this golden moved with the flip.
28
30
  *
29
- * Since S3 M2b (Q-M2b-1, owner ruling 2026-09-13) the sub-agent's spend is
31
+ * Since #1096 (ruled 2026-09-13) the sub-agent's spend is
30
32
  * the execution's spend: the helper's one turn (600 in, 12 out) is reported
31
33
  * through the same hook as the root's, so `streamingUsage` reads 3,900 in /
32
34
  * 102 out / 3 turns where it read 3,300 / 90 / 2, and `estimatedCostUsd`
33
35
  * 0.00441 where it read 0.00375 — the helper's 660 micro-dollars at the
34
- * PARENT's rate (per-sub-agent pricing is an S5 item; the in-graph cost cap
36
+ * PARENT's rate (per-sub-agent pricing is #1121; the in-graph cost cap
35
37
  * this replaces priced sub-agents the same way). The five lines of
36
38
  * `streamingUsage` are the whole diff; the transcript and the sub-agent row
37
39
  * are byte-identical. `max_cost_usd` is now enforced over this total by the
38
40
  * runtime, the one enforcement since the cost middleware became advisory
39
- * (Q-S3-3).
41
+ * (#1096).
42
+ *
43
+ * Since #1097: deepagents' `task` tool
44
+ * returns a LangGraph `Command` like `write_todos` does, so the `task` row's
45
+ * `result` and the sub-agent row's `output` are the nested ToolMessage's
46
+ * content — `[{"type":"text","text":"The fixture value is forty-two."}]`,
47
+ * the blocks array the image offload reads — where they were the whole
48
+ * serialized Command. Those two lines are the whole of that hunk.
49
+ *
50
+ * Also since #1097: the `task` row sits on the AI message whose text
51
+ * delegated ("Delegating to the helper."), not on an empty AI message of its
52
+ * own after it — two root AI messages (the delegating text with the row, the
53
+ * closing text) where there were three; the same scoping fix
54
+ * `tool-call.test.ts` records. And the row carries
55
+ * `argsPreview`, the one preview rule for every row on every harness.
40
56
  *
41
57
  * Regenerate ONLY after a deliberate behavior change:
42
58
  * npx vitest run src/activities/execute-deep-agent/__tests__/hermetic -u
@@ -137,9 +153,9 @@ describe("ExecuteDeepAgent hermetic — sub-agent delegation", () => {
137
153
  expect(rows.map((tc) => [tc.id, tc.name, tc.status])).toEqual([[TASK_CALL_ID, "task", ToolCallStatus.TOOL_CALL_COMPLETED]]);
138
154
  expect(final.messages.filter((m) => m.type === MessageType.MESSAGE_AI).map((m) => m.content)).toEqual([
139
155
  "Delegating to the helper.",
140
- "",
141
156
  ROOT_CLOSING,
142
157
  ]);
158
+ expect(final.messages[0].toolCalls.map((tc) => tc.id), "the task row sits on the text that delegated").toEqual([TASK_CALL_ID]);
143
159
 
144
160
  // ── Assert: the sub-agent execution ──────────────────────────────────────
145
161
  expect(final.subAgentExecutions).toHaveLength(1);
@@ -10,27 +10,27 @@
10
10
  * into ONE tool row, and the turn ends COMPLETED. A read-only built-in is never
11
11
  * gated (`shared/tool-kind.ts` FILE_READ), so no approval fields are set. The
12
12
  * mid-stream persist the tool-call boundary forces (`persist-decision.ts`
13
- * `contentDirty`) is what the platform-stop arm relies on.
13
+ * over the builder's `dirty` flag) is what the platform-stop arm relies on.
14
14
  *
15
- * What the golden shows about TODAY's transcript shape, recorded as found
16
- * (S3 M0 finding F-M0-1; a transcript-shape fact for S4): the row does NOT sit on
17
- * the AI message that carries the text of the same LLM turn. LangGraph 1.3.2
18
- * stamps the model's events with namespace `["model_request:<uuid>"]` and the
19
- * tools node's with `["tools:<uuid>"]`; `V3StatusBuilder.ensureAiMessage`
20
- * files the text under the raw namespace while `handleToolStarted` looks the
21
- * parent up under `resolveAgentNamespace(...)`, which strips only `tools:`
22
- * segments and so resolves to `""` — a miss, and `ensureAiMessageForToolCall`
23
- * appends an EMPTY AI message for the row. So the transcript is THREE AI
24
- * messages: the text, an empty one carrying the row, the closing text. The
25
- * hand-authored fixtures in `v3-event-fixtures.ts` use `namespace: []` and
26
- * never reached this arm; this golden, on the real graph, does. The golden
27
- * (`goldens/tool-call.status.json`) is the shape S4's canonical transcript
28
- * builder is measured against, and the shape any fix must change on purpose.
15
+ * The transcript shape (since #1097): the row sits on the AI
16
+ * message whose text proposed it — TWO AI messages, the text carrying the
17
+ * row and the closing text. Until then it did not (found in #1096):
18
+ * LangGraph 1.3.2 stamps the model's events with namespace
19
+ * `["model_request:<uuid>"]` and the tools node's with `["tools:<uuid>"]`, the
20
+ * builder filed the text under the raw namespace and looked the tool's
21
+ * parent up under a namespace stripped of `tools:` only — a miss, so the row
22
+ * rode an EMPTY AI message between the two texts. The fix is not a patch on
23
+ * the lookup: scope became `subAgentId?` (the root, or one sub-agent) and the
24
+ * translator resolves it from the namespace, so the builder has one
25
+ * "current AI message" per scope and that class of miss cannot exist. The
26
+ * hand-authored fixtures now default to the real namespaces too.
27
+ * The golden (`goldens/tool-call.status.json`) is the shape any later change
28
+ * must move on purpose.
29
29
  *
30
- * Since S3 M2a the activity is the turn runtime over the native adapter, and
30
+ * Since #1096 the activity is the turn runtime over the native adapter, and
31
31
  * `streamingUsage` carries the runtime accountant's fields — `model`,
32
32
  * `estimatedCostUsd` priced at the registry's rates, the requested tier and
33
- * thinking mode (Q-M2a-2: one writer of the summary, the runtime). Nothing
33
+ * thinking mode (one writer of the summary, the runtime). Nothing
34
34
  * else in this golden moved with the flip.
35
35
  *
36
36
  * Regenerate ONLY after a deliberate behavior change:
@@ -134,17 +134,17 @@ describe("ExecuteDeepAgent hermetic — ungated tool call", () => {
134
134
  expect(row.result, "the built-in's numbered listing of the seeded file").toContain("A fixture readme.");
135
135
  expect(row.requiresApproval, "a read-only built-in is not gated").toBe(false);
136
136
 
137
- // ── Assert: the transcript, as it is today (F-M0-1 in the header) ────────
137
+ // ── Assert: the transcript — the row beside the text that proposed it ──
138
138
  const final = record.lastFullStatus!;
139
139
  const ai = final.messages.filter((m) => m.type === MessageType.MESSAGE_AI);
140
- expect(ai.map((m) => m.content), "text, an EMPTY message carrying the row, closing text").toEqual([
140
+ expect(ai.map((m) => m.content), "the proposing text, then the closing text").toEqual([
141
141
  "Let me read it.",
142
- "",
143
142
  ASSISTANT_TEXT,
144
143
  ]);
145
- expect(ai[1].toolCalls.map((tc) => tc.id), "the row sits on the empty message, not beside its text").toEqual([
144
+ expect(ai[0].toolCalls.map((tc) => tc.id), "the row sits on the message whose text proposed it").toEqual([
146
145
  CALL_ID,
147
146
  ]);
147
+ expect(ai[1].toolCalls).toHaveLength(0);
148
148
  expect(final.streamingUsage?.turnCount).toBe(2);
149
149
 
150
150
  // ── Assert: hermeticity ──────────────────────────────────────────────────
@@ -11,7 +11,7 @@
11
11
  * and one system row, persists ONCE, and returns — a Temporal retry would only
12
12
  * queue behind the same holder.
13
13
  *
14
- * The order, ruled at Q-S3-8 and landed at S3 M2a: the runtime takes the
14
+ * The order, since #1096: the runtime takes the
15
15
  * lock right after provisioning the workspace, BEFORE the tool surface, the
16
16
  * skills, the attachments and the graph — so a turn that cannot have the
17
17
  * tree builds no model and compiles no sub-agent. Until then the
@@ -21,8 +21,8 @@
21
21
  * appear, because the turn ends before the adapter runs.
22
22
  *
23
23
  * Why this is the one terminal arm WITHOUT a file golden (owner ruling,
24
- * 2026-09-11, entry 20260911.03 M0; carried for native): the wire copy embeds
25
- * the absolute workspace path, a per-run temp directory. The S0 rule is to
24
+ * 2026-09-11, #1070; carried for native): the wire copy embeds
25
+ * the absolute workspace path, a per-run temp directory. The hermetic rule (#1048) is to
26
26
  * control a volatile source at its origin or escalate — never redact — so
27
27
  * this scenario pins every byte the path does not touch with explicit
28
28
  * assertions and builds the expected message with the SAME error class over
@@ -136,11 +136,11 @@ describe("ExecuteDeepAgent hermetic — workspace lock timeout", () => {
136
136
  "Provisioning workspace",
137
137
  "Waiting for workspace — in use by another session",
138
138
  ]);
139
- expect(recordedModelBuilds(), "no model is built for a turn that cannot have the tree (Q-S3-8)").toHaveLength(0);
139
+ expect(recordedModelBuilds(), "no model is built for a turn that cannot have the tree").toHaveLength(0);
140
140
 
141
141
  // ── Assert: hermeticity ────────────────────────────────────────────────
142
142
  expect(registry.urls.every((u) => u.includes("/model-registry"))).toBe(true);
143
- // The runtime's heartbeat posture (Q-S3-8, parent Q8): every resolution
143
+ // The runtime's heartbeat posture: every resolution
144
144
  // phase pulses on entry and the terminal write pulses once, so a turn
145
145
  // that ends at the lock has heartbeated before any stream existed.
146
146
  expect(invocation.heartbeats.length, "the runtime heartbeats through resolution").toBeGreaterThan(0);