@stigmer/runner 3.14.0 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. package/dist/.build-fingerprint +1 -1
  2. package/dist/__test-utils__/execution-record-fixture.d.ts +47 -0
  3. package/dist/__test-utils__/execution-record-fixture.js +68 -0
  4. package/dist/__test-utils__/execution-record-fixture.js.map +1 -0
  5. package/dist/__test-utils__/harness-contract/types.d.ts +166 -0
  6. package/dist/__test-utils__/harness-contract/types.js +49 -0
  7. package/dist/__test-utils__/harness-contract/types.js.map +1 -0
  8. package/dist/__test-utils__/hermetic-activity.d.ts +268 -0
  9. package/dist/__test-utils__/hermetic-activity.js +385 -0
  10. package/dist/__test-utils__/hermetic-activity.js.map +1 -0
  11. package/dist/__test-utils__/mock-client.d.ts +13 -0
  12. package/dist/__test-utils__/mock-client.js +45 -0
  13. package/dist/__test-utils__/mock-client.js.map +1 -0
  14. package/dist/__test-utils__/mock-workspace.d.ts +15 -0
  15. package/dist/__test-utils__/mock-workspace.js +21 -0
  16. package/dist/__test-utils__/mock-workspace.js.map +1 -0
  17. package/dist/__test-utils__/model-registry-fixture.d.ts +56 -0
  18. package/dist/__test-utils__/model-registry-fixture.js +66 -0
  19. package/dist/__test-utils__/model-registry-fixture.js.map +1 -0
  20. package/dist/__test-utils__/turn-input-fixture.d.ts +60 -0
  21. package/dist/__test-utils__/turn-input-fixture.js +118 -0
  22. package/dist/__test-utils__/turn-input-fixture.js.map +1 -0
  23. package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +107 -0
  24. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +344 -0
  25. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -0
  26. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +20 -0
  27. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +58 -0
  28. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -1
  29. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +2 -32
  30. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
  31. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +148 -0
  32. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +257 -0
  33. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -0
  34. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +183 -0
  35. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +262 -0
  36. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -0
  37. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.d.ts +138 -0
  38. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js +191 -0
  39. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js.map +1 -0
  40. package/dist/activities/execute-cursor/adapter.d.ts +55 -0
  41. package/dist/activities/execute-cursor/adapter.js +119 -0
  42. package/dist/activities/execute-cursor/adapter.js.map +1 -0
  43. package/dist/activities/execute-cursor/approval-state.d.ts +2 -2
  44. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  45. package/dist/activities/execute-cursor/capture-flow.d.ts +15 -30
  46. package/dist/activities/execute-cursor/capture-flow.js +17 -26
  47. package/dist/activities/execute-cursor/capture-flow.js.map +1 -1
  48. package/dist/activities/execute-cursor/cursor-capabilities.d.ts +23 -0
  49. package/dist/activities/execute-cursor/cursor-capabilities.js +33 -0
  50. package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -0
  51. package/dist/activities/execute-cursor/cursor-mcp-config.d.ts +2 -2
  52. package/dist/activities/execute-cursor/cursor-mcp-config.js.map +1 -1
  53. package/dist/activities/execute-cursor/fetch-interceptor.d.ts +15 -25
  54. package/dist/activities/execute-cursor/fetch-interceptor.js +39 -33
  55. package/dist/activities/execute-cursor/fetch-interceptor.js.map +1 -1
  56. package/dist/activities/execute-cursor/http2-interceptor.d.ts +21 -17
  57. package/dist/activities/execute-cursor/http2-interceptor.js +38 -31
  58. package/dist/activities/execute-cursor/http2-interceptor.js.map +1 -1
  59. package/dist/activities/execute-cursor/message-translator.d.ts +28 -19
  60. package/dist/activities/execute-cursor/message-translator.js +76 -27
  61. package/dist/activities/execute-cursor/message-translator.js.map +1 -1
  62. package/dist/activities/execute-cursor/prompt-builder.d.ts +180 -11
  63. package/dist/activities/execute-cursor/prompt-builder.js +171 -0
  64. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  65. package/dist/activities/execute-cursor/rejection-capture.d.ts +3 -6
  66. package/dist/activities/execute-cursor/rejection-capture.js +5 -7
  67. package/dist/activities/execute-cursor/rejection-capture.js.map +1 -1
  68. package/dist/activities/execute-cursor/session-lifecycle.d.ts +1 -4
  69. package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -1
  70. package/dist/activities/execute-cursor/turn-boundary.d.ts +1 -1
  71. package/dist/activities/execute-cursor/turn-settle.d.ts +49 -0
  72. package/dist/activities/execute-cursor/turn-settle.js +507 -0
  73. package/dist/activities/execute-cursor/turn-settle.js.map +1 -0
  74. package/dist/activities/execute-cursor/turn-setup.d.ts +173 -0
  75. package/dist/activities/execute-cursor/turn-setup.js +496 -0
  76. package/dist/activities/execute-cursor/turn-setup.js.map +1 -0
  77. package/dist/activities/execute-cursor/turn-stream.d.ts +41 -71
  78. package/dist/activities/execute-cursor/turn-stream.js +70 -135
  79. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  80. package/dist/activities/execute-cursor/turn.d.ts +43 -0
  81. package/dist/activities/execute-cursor/turn.js +222 -0
  82. package/dist/activities/execute-cursor/turn.js.map +1 -0
  83. package/dist/activities/execute-cursor/usage-pricing.d.ts +38 -0
  84. package/dist/activities/execute-cursor/usage-pricing.js +50 -0
  85. package/dist/activities/execute-cursor/usage-pricing.js.map +1 -0
  86. package/dist/activities/execute-deep-agent/approval-file-change.d.ts +1 -1
  87. package/dist/activities/execute-deep-agent/approval-file-change.js +1 -1
  88. package/dist/activities/execute-deep-agent/environment.js +1 -1
  89. package/dist/activities/execute-deep-agent/environment.js.map +1 -1
  90. package/dist/activities/execute-deep-agent/setup.js +3 -2
  91. package/dist/activities/execute-deep-agent/setup.js.map +1 -1
  92. package/dist/activities/hydrate-workflow-execution.js +1 -1
  93. package/dist/activities/hydrate-workflow-execution.js.map +1 -1
  94. package/dist/config.d.ts +15 -0
  95. package/dist/config.js.map +1 -1
  96. package/dist/harness/capabilities.d.ts +87 -0
  97. package/dist/harness/capabilities.js +37 -0
  98. package/dist/harness/capabilities.js.map +1 -0
  99. package/dist/harness/persist-chokepoint.d.ts +74 -0
  100. package/dist/harness/persist-chokepoint.js +88 -0
  101. package/dist/harness/persist-chokepoint.js.map +1 -0
  102. package/dist/harness/registry.d.ts +106 -0
  103. package/dist/harness/registry.js +168 -0
  104. package/dist/harness/registry.js.map +1 -0
  105. package/dist/harness/run-turn.d.ts +53 -0
  106. package/dist/harness/run-turn.js +528 -0
  107. package/dist/harness/run-turn.js.map +1 -0
  108. package/dist/harness/stop-controller.d.ts +50 -0
  109. package/dist/harness/stop-controller.js +62 -0
  110. package/dist/harness/stop-controller.js.map +1 -0
  111. package/dist/harness/terminal-table.d.ts +141 -0
  112. package/dist/harness/terminal-table.js +239 -0
  113. package/dist/harness/terminal-table.js.map +1 -0
  114. package/dist/harness/turn-context.d.ts +523 -0
  115. package/dist/harness/turn-context.js +739 -0
  116. package/dist/harness/turn-context.js.map +1 -0
  117. package/dist/harness/types.d.ts +448 -0
  118. package/dist/harness/types.js +64 -0
  119. package/dist/harness/types.js.map +1 -0
  120. package/dist/harness/usage-accumulator.d.ts +68 -0
  121. package/dist/harness/usage-accumulator.js +101 -0
  122. package/dist/harness/usage-accumulator.js.map +1 -0
  123. package/dist/harness-adapters.d.ts +27 -0
  124. package/dist/harness-adapters.js +28 -0
  125. package/dist/harness-adapters.js.map +1 -0
  126. package/dist/main.js.map +1 -1
  127. package/dist/runner-manager.js +64 -48
  128. package/dist/runner-manager.js.map +1 -1
  129. package/dist/runner.d.ts +5 -4
  130. package/dist/runner.js +65 -64
  131. package/dist/runner.js.map +1 -1
  132. package/dist/shared/approval-policy.d.ts +1 -1
  133. package/dist/shared/approval-policy.js.map +1 -1
  134. package/dist/{activities/execute-cursor → shared}/attachment-resolver.d.ts +2 -2
  135. package/dist/{activities/execute-cursor → shared}/attachment-resolver.js +5 -5
  136. package/dist/shared/attachment-resolver.js.map +1 -0
  137. package/dist/{activities/execute-cursor → shared}/blueprint-resolver.d.ts +7 -5
  138. package/dist/{activities/execute-cursor → shared}/blueprint-resolver.js +3 -63
  139. package/dist/shared/blueprint-resolver.js.map +1 -0
  140. package/dist/shared/channel-attachment.d.ts +1 -1
  141. package/dist/shared/channel-attachment.js.map +1 -1
  142. package/dist/{activities/execute-cursor → shared}/cost-guard.d.ts +5 -1
  143. package/dist/{activities/execute-cursor → shared}/cost-guard.js +5 -1
  144. package/dist/shared/cost-guard.js.map +1 -0
  145. package/dist/{activities/execute-cursor → shared}/env-resolver.d.ts +1 -1
  146. package/dist/shared/env-resolver.js.map +1 -0
  147. package/dist/{activities/execute-cursor → shared}/exact-apply.d.ts +1 -1
  148. package/dist/{activities/execute-cursor → shared}/exact-apply.js +6 -6
  149. package/dist/shared/exact-apply.js.map +1 -0
  150. package/dist/shared/execution-context.d.ts +35 -0
  151. package/dist/shared/execution-context.js +38 -0
  152. package/dist/shared/execution-context.js.map +1 -0
  153. package/dist/{activities/execute-cursor → shared}/extract-structured-output.d.ts +5 -2
  154. package/dist/{activities/execute-cursor → shared}/extract-structured-output.js +9 -6
  155. package/dist/shared/extract-structured-output.js.map +1 -0
  156. package/dist/shared/filereview/capture.d.ts +1 -1
  157. package/dist/shared/filereview/capture.js +1 -1
  158. package/dist/shared/heartbeat.d.ts +13 -11
  159. package/dist/shared/heartbeat.js +14 -29
  160. package/dist/shared/heartbeat.js.map +1 -1
  161. package/dist/{activities/execute-cursor → shared}/persist-decision.d.ts +5 -2
  162. package/dist/{activities/execute-cursor → shared}/persist-decision.js +4 -1
  163. package/dist/shared/persist-decision.js.map +1 -0
  164. package/dist/{activities/execute-cursor → shared}/skill-resolver.d.ts +16 -3
  165. package/dist/{activities/execute-cursor → shared}/skill-resolver.js +12 -4
  166. package/dist/shared/skill-resolver.js.map +1 -0
  167. package/dist/shared/subagent-rows.d.ts +21 -0
  168. package/dist/shared/subagent-rows.js +34 -0
  169. package/dist/shared/subagent-rows.js.map +1 -0
  170. package/dist/shared/worker-shutdown.d.ts +43 -16
  171. package/dist/shared/worker-shutdown.js +28 -13
  172. package/dist/shared/worker-shutdown.js.map +1 -1
  173. package/dist/shared/workspace/platform-dir.d.ts +1 -1
  174. package/dist/shared/workspace/platform-dir.js +1 -1
  175. package/dist/shared/workspace/session-provision.d.ts +54 -0
  176. package/dist/{activities/execute-cursor/workspace-provision.js → shared/workspace/session-provision.js} +15 -12
  177. package/dist/shared/workspace/session-provision.js.map +1 -0
  178. package/package.json +4 -4
  179. package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +325 -0
  180. package/src/__test-utils__/config-fixture.ts +63 -0
  181. package/src/__test-utils__/execution-record-fixture.ts +104 -0
  182. package/src/__test-utils__/harness-boot-order-child.ts +58 -0
  183. package/src/__test-utils__/harness-contract/contract.ts +581 -0
  184. package/src/__test-utils__/harness-contract/recording-sink.ts +107 -0
  185. package/src/__test-utils__/harness-contract/runtime-contract.ts +666 -0
  186. package/src/__test-utils__/harness-contract/scripted-adapter.ts +349 -0
  187. package/src/__test-utils__/harness-contract/types.ts +176 -0
  188. package/src/__test-utils__/hermetic-activity.ts +502 -0
  189. package/src/__test-utils__/model-registry-fixture.ts +72 -0
  190. package/src/__test-utils__/module-specifiers.ts +82 -0
  191. package/src/__test-utils__/proto-helpers.ts +25 -0
  192. package/src/__test-utils__/turn-input-fixture.ts +155 -0
  193. package/src/__tests__/harness-boot-order.test.ts +77 -0
  194. package/src/__tests__/harness-contract.test.ts +27 -0
  195. package/src/__tests__/runner-manager.test.ts +18 -0
  196. package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +102 -0
  197. package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +396 -0
  198. package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +66 -0
  199. package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +2 -43
  200. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +342 -0
  201. package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +368 -0
  202. package/src/activities/execute-cursor/__test-utils__/scripted-sdk.ts +254 -0
  203. package/src/activities/execute-cursor/__tests__/adapter-is-temporal-free.test.ts +45 -0
  204. package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +90 -0
  205. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +7 -8
  206. package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +28 -1
  207. package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +1 -1
  208. package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +64 -6
  209. package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +228 -0
  210. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +180 -0
  211. package/src/activities/execute-cursor/__tests__/hermetic/goldens/cost-cap.status.json +53 -0
  212. package/src/activities/execute-cursor/__tests__/hermetic/goldens/deny-and-retry.turn1.status.json +55 -0
  213. package/src/activities/execute-cursor/__tests__/hermetic/goldens/deny-and-retry.turn2.status.json +77 -0
  214. package/src/activities/execute-cursor/__tests__/hermetic/goldens/file-review-capture.status.json +126 -0
  215. package/src/activities/execute-cursor/__tests__/hermetic/goldens/pause.status.json +40 -0
  216. package/src/activities/execute-cursor/__tests__/hermetic/goldens/plain-turn.status.json +48 -0
  217. package/src/activities/execute-cursor/__tests__/hermetic/goldens/platform-stop.status.json +56 -0
  218. package/src/activities/execute-cursor/__tests__/hermetic/goldens/recovery-fresh-agent.status.json +53 -0
  219. package/src/activities/execute-cursor/__tests__/hermetic/goldens/recovery-transport-timeout.status.json +48 -0
  220. package/src/activities/execute-cursor/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
  221. package/src/activities/execute-cursor/__tests__/hermetic/goldens/run-cancelled.status.json +36 -0
  222. package/src/activities/execute-cursor/__tests__/hermetic/goldens/run-error-non-retryable.status.json +37 -0
  223. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +38 -0
  224. package/src/activities/execute-cursor/__tests__/hermetic/goldens/stall.status.json +59 -0
  225. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-call.status.json +68 -0
  226. package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +79 -0
  227. package/src/activities/execute-cursor/__tests__/hermetic/goldens/worker-shutdown.status.json +42 -0
  228. package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +170 -0
  229. package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +205 -0
  230. package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +171 -0
  231. package/src/activities/execute-cursor/__tests__/hermetic/recovery-fresh-agent.test.ts +156 -0
  232. package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +286 -0
  233. package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +332 -0
  234. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +193 -0
  235. package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +137 -0
  236. package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +185 -0
  237. package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +151 -0
  238. package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +65 -35
  239. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -40
  240. package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +171 -0
  241. package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +118 -243
  242. package/src/activities/execute-cursor/__tests__/usage-pricing.test.ts +84 -0
  243. package/src/activities/execute-cursor/adapter.ts +138 -0
  244. package/src/activities/execute-cursor/approval-state.ts +2 -2
  245. package/src/activities/execute-cursor/capture-flow.ts +18 -41
  246. package/src/activities/execute-cursor/cursor-capabilities.ts +35 -0
  247. package/src/activities/execute-cursor/cursor-mcp-config.ts +2 -2
  248. package/src/activities/execute-cursor/fetch-interceptor.ts +48 -45
  249. package/src/activities/execute-cursor/http2-interceptor.ts +47 -34
  250. package/src/activities/execute-cursor/message-translator.ts +90 -45
  251. package/src/activities/execute-cursor/prompt-builder.ts +327 -12
  252. package/src/activities/execute-cursor/rejection-capture.ts +5 -12
  253. package/src/activities/execute-cursor/session-lifecycle.ts +1 -5
  254. package/src/activities/execute-cursor/turn-boundary.ts +1 -1
  255. package/src/activities/execute-cursor/turn-settle.ts +601 -0
  256. package/src/activities/execute-cursor/turn-setup.ts +645 -0
  257. package/src/activities/execute-cursor/turn-stream.ts +84 -210
  258. package/src/activities/execute-cursor/turn.ts +240 -0
  259. package/src/activities/execute-cursor/usage-pricing.ts +67 -0
  260. package/src/activities/execute-deep-agent/approval-file-change.ts +1 -1
  261. package/src/activities/execute-deep-agent/environment.ts +1 -1
  262. package/src/activities/execute-deep-agent/setup.ts +3 -2
  263. package/src/activities/hydrate-workflow-execution.ts +1 -1
  264. package/src/config.ts +13 -0
  265. package/src/harness/__tests__/import-direction.test.ts +168 -0
  266. package/src/harness/__tests__/persist-chokepoint.test.ts +146 -0
  267. package/src/harness/__tests__/registry.test.ts +168 -0
  268. package/src/harness/__tests__/run-turn.test.ts +165 -0
  269. package/src/harness/__tests__/stop-controller.test.ts +49 -0
  270. package/src/harness/__tests__/turn-context.test.ts +178 -0
  271. package/src/harness/__tests__/usage-accumulator.test.ts +83 -0
  272. package/src/harness/capabilities.ts +92 -0
  273. package/src/harness/persist-chokepoint.ts +112 -0
  274. package/src/harness/registry.ts +197 -0
  275. package/src/harness/run-turn.ts +618 -0
  276. package/src/harness/stop-controller.ts +83 -0
  277. package/src/harness/terminal-table.ts +276 -0
  278. package/src/harness/turn-context.ts +1028 -0
  279. package/src/harness/types.ts +473 -0
  280. package/src/harness/usage-accumulator.ts +122 -0
  281. package/src/harness-adapters.ts +30 -0
  282. package/src/main.ts +1 -1
  283. package/src/runner-manager.ts +68 -61
  284. package/src/runner.ts +67 -78
  285. package/src/shared/__tests__/attachment-naming.test.ts +1 -1
  286. package/src/{activities/execute-cursor → shared}/__tests__/attachment-resolver.test.ts +6 -4
  287. package/src/{activities/execute-cursor → shared}/__tests__/cost-guard.test.ts +2 -1
  288. package/src/{activities/execute-cursor → shared}/__tests__/exact-apply.test.ts +3 -3
  289. package/src/{activities/execute-cursor → shared}/__tests__/extract-structured-output.test.ts +8 -8
  290. package/src/{activities/execute-cursor → shared}/__tests__/persist-decision.test.ts +4 -2
  291. package/src/{activities/execute-cursor → shared}/__tests__/skill-resolver.test.ts +1 -1
  292. package/src/shared/__tests__/subagent-rows.test.ts +34 -0
  293. package/src/shared/__tests__/worker-shutdown.test.ts +44 -39
  294. package/src/shared/approval-policy.ts +1 -1
  295. package/src/{activities/execute-cursor → shared}/attachment-resolver.ts +6 -6
  296. package/src/{activities/execute-cursor → shared}/blueprint-resolver.ts +7 -78
  297. package/src/shared/channel-attachment.ts +1 -1
  298. package/src/{activities/execute-cursor → shared}/cost-guard.ts +5 -1
  299. package/src/{activities/execute-cursor → shared}/env-resolver.ts +1 -1
  300. package/src/{activities/execute-cursor → shared}/exact-apply.ts +7 -7
  301. package/src/shared/execution-context.ts +45 -0
  302. package/src/{activities/execute-cursor → shared}/extract-structured-output.ts +10 -7
  303. package/src/shared/filereview/capture.ts +1 -1
  304. package/src/shared/heartbeat.ts +13 -33
  305. package/src/{activities/execute-cursor → shared}/persist-decision.ts +5 -2
  306. package/src/{activities/execute-cursor → shared}/skill-resolver.ts +20 -6
  307. package/src/shared/subagent-rows.ts +39 -0
  308. package/src/shared/worker-shutdown.ts +55 -25
  309. package/src/{activities/execute-cursor/__tests__/workspace-provision.test.ts → shared/workspace/__tests__/session-provision.test.ts} +25 -28
  310. package/src/shared/workspace/platform-dir.ts +1 -1
  311. package/src/{activities/execute-cursor/workspace-provision.ts → shared/workspace/session-provision.ts} +29 -16
  312. package/dist/activities/execute-cursor/attachment-resolver.js.map +0 -1
  313. package/dist/activities/execute-cursor/blueprint-resolver.js.map +0 -1
  314. package/dist/activities/execute-cursor/cost-guard.js.map +0 -1
  315. package/dist/activities/execute-cursor/env-resolver.js.map +0 -1
  316. package/dist/activities/execute-cursor/exact-apply.js.map +0 -1
  317. package/dist/activities/execute-cursor/extract-structured-output.js.map +0 -1
  318. package/dist/activities/execute-cursor/index.d.ts +0 -209
  319. package/dist/activities/execute-cursor/index.js +0 -2345
  320. package/dist/activities/execute-cursor/index.js.map +0 -1
  321. package/dist/activities/execute-cursor/persist-decision.js.map +0 -1
  322. package/dist/activities/execute-cursor/skill-resolver.js.map +0 -1
  323. package/dist/activities/execute-cursor/usage-accumulator.d.ts +0 -89
  324. package/dist/activities/execute-cursor/usage-accumulator.js +0 -121
  325. package/dist/activities/execute-cursor/usage-accumulator.js.map +0 -1
  326. package/dist/activities/execute-cursor/workspace-provision.d.ts +0 -42
  327. package/dist/activities/execute-cursor/workspace-provision.js.map +0 -1
  328. package/src/activities/execute-cursor/__tests__/usage-accumulator.test.ts +0 -164
  329. package/src/activities/execute-cursor/index.ts +0 -2876
  330. package/src/activities/execute-cursor/usage-accumulator.ts +0 -169
  331. /package/dist/{activities/execute-cursor → shared}/env-resolver.js +0 -0
@@ -0,0 +1,523 @@
1
+ /**
2
+ * The turn context — everything the runtime resolves for one agent turn
3
+ * before any harness runs, as small named phases producing one typed record.
4
+ *
5
+ * A turn begins with a dozen reads and provisions that have nothing to do
6
+ * with the engine that will run it: the execution and its session, the
7
+ * agent blueprint, the environment, the workspace and its lock, what the
8
+ * previous turn left waiting for approval, the MCP servers and their
9
+ * approval policies, the attachments, the standing context. Until S2 M2
10
+ * that sequence lived inline in the Cursor orchestrator
11
+ * (`activities/execute-cursor/index.ts` `executeCursorInner`, phases 1 to
12
+ * 9c); the native orchestrator carried a second copy in its `performSetup`.
13
+ * This module is the one copy. Each phase is a function that reads its
14
+ * inputs, reports its progress label, heartbeats once on entry, and returns
15
+ * a typed slice of the contract's `TurnInput`; {@link resolveTurnContext}
16
+ * sequences them, and the adapter runs its own harness-specific steps after
17
+ * the whole record exists.
18
+ *
19
+ * Shape, chosen against `execute-deep-agent/setup.ts`: a typed record built
20
+ * from small functions (the `SetupResult` mold), never one 775-line
21
+ * `performSetup`. The record is the adapter contract's `TurnInput`
22
+ * (`types.ts`): every phase returns a named slice of it, and
23
+ * {@link resolveTurnContext} composes the whole. There is no wider
24
+ * "runtime-private" record beside it — the lock release and the write-back
25
+ * coordinator a phase produces are the caller's `TurnFrame` resources, set
26
+ * the instant they exist so a `finally` sees them on every path (M2 had a
27
+ * `TurnContext extends TurnInput` for them; once the groups lifted, nothing
28
+ * read the extension after composition, so M3 deleted it).
29
+ *
30
+ * Three rules every phase obeys:
31
+ *
32
+ * - It never persists and never returns a slim status. A phase that can end
33
+ * the turn (the lock, the reinvocation reconcile) returns a
34
+ * {@link TurnSettlement} naming WHAT was decided; the caller writes the
35
+ * status, persists once and returns. The lock golden pins that persist as
36
+ * the turn's one and only, which is why the rule is structural.
37
+ * - It imports nothing from `src/activities/` (pinned by
38
+ * `__tests__/import-direction.test.ts`). A fact only the harness knows
39
+ * (its file-review identity, its vision profile) arrives through
40
+ * `HarnessCapabilities`.
41
+ * - Its heartbeat pulse and its cold-start timing marks are its own: the
42
+ * step name it enters under is the mark name it emits, one vocabulary for
43
+ * "where in setup are we" in Temporal heartbeat details and the
44
+ * `execution_setup` log (Q-S2-10).
45
+ *
46
+ * What is deliberately NOT here, and where it is instead:
47
+ *
48
+ * - Cursor's catalog validation of the requested model (`resolveModelId`),
49
+ * the pricing preload and the MCP env pre-flight warning stay in the
50
+ * Cursor adapter for S2: each reads a module in the adapter column of the
51
+ * entry's disposition table, and the runtime carries the REQUESTED model
52
+ * name so every harness validates against its own catalog (S2 M2 gate,
53
+ * Q-M2-1). The skill mount was in that list until M3b found it reads the
54
+ * control plane, which only the runtime holds; it is {@link mountSkills}.
55
+ * - The approval grants, the HITL gate, the capture baseline pin and the
56
+ * Cursor agent itself (phases 5c, 7, 8a, 9) are the adapter's.
57
+ * - The memory selection is a memoized thunk, not a value: whether a prompt
58
+ * carries standing context depends on how the ENGINE resolved (a resumed
59
+ * agent already holds it), which the runtime learns only after the
60
+ * adapter runs. The runtime prepares the selection once; the adapter
61
+ * pulls it when its prompt needs it.
62
+ *
63
+ * Every `index.ts` line reference below was read from `2c06bc7ea` on
64
+ * 2026-09-11, before the orchestrator moved onto this module.
65
+ */
66
+ import type { AgentExecution, AgentExecutionStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
67
+ import type { AgentExecutionSpec } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
68
+ import { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
69
+ import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
70
+ import type { Config } from "../config.js";
71
+ import type { StigmerClient } from "../client/stigmer-client.js";
72
+ import type { NormalizedActivityInput } from "../shared/activity-input.js";
73
+ import type { ArtifactStorage } from "../shared/artifact-storage.js";
74
+ import type { TimingRecorder } from "../shared/cold-start-timing.js";
75
+ import { type ResolvedBlueprint } from "../shared/blueprint-resolver.js";
76
+ import { WriteBackCoordinator } from "../shared/workspace/writeback-coordinator.js";
77
+ import { WorkspaceLockTimeoutError, type ReleaseWorkspaceLock } from "../shared/workspace/workspace-lock.js";
78
+ import { type SkillMetadata } from "../shared/skill-resolver.js";
79
+ import { type VisionProfile } from "../shared/attachment-vision.js";
80
+ import type { FileReviewIdentity, HarnessCapabilities, StateIdSource } from "./capabilities.js";
81
+ import type { TurnAttachments, TurnEnvironment, TurnInput, TurnMcp, TurnModelPreferences, TurnStandingContext, TurnWorkspace } from "./types.js";
82
+ /**
83
+ * What every phase reads from its caller. The activity's identity and the
84
+ * runtime's own seams; nothing harness-specific. The four function members
85
+ * are the caller's, injected so the phase bodies are the same code under
86
+ * the Cursor orchestrator today and under `run-turn.ts` in M3 (only the
87
+ * binding changes), and so a test can drive a phase without a Temporal
88
+ * activity context.
89
+ */
90
+ export interface ResolutionDeps {
91
+ /** The activity's own identity: execution id, engine state id, HITL cycle index. */
92
+ readonly input: NormalizedActivityInput;
93
+ readonly client: StigmerClient;
94
+ /**
95
+ * The whole runner config. The runtime is its rightful reader; a shared
96
+ * helper that needs two fields is handed a narrowed view of it
97
+ * (`SessionProvisionConfig`), never the other way round.
98
+ */
99
+ readonly config: Config;
100
+ /**
101
+ * The one execution status this turn folds into. Phases that carry state
102
+ * across invocations write here (the seeded transcript, the file-review
103
+ * reconcile's events, the memory-selection report); nothing else does.
104
+ */
105
+ readonly status: AgentExecutionStatus;
106
+ /** Resolved once by the caller before any phase; absent when no substrate works. */
107
+ readonly artifactStorage: ArtifactStorage | undefined;
108
+ /** The cold-start timeline; each phase marks its own segment(s) exactly as before. */
109
+ readonly timing: TimingRecorder;
110
+ /** Cancellation for the one wait a phase can block on (the workspace lock). */
111
+ readonly signal: AbortSignal;
112
+ /** The Temporal heartbeat, handed to helpers that pulse mid-call (the lock wait, the MCP backfill). */
113
+ readonly heartbeat: () => void;
114
+ /**
115
+ * "Resolution is now at this step": labels the caller's periodic heartbeat
116
+ * and pulses once. Every phase calls it first with its own step name.
117
+ */
118
+ readonly enterPhase: (step: string) => void;
119
+ /** The user-visible setup label (`setupProgress`); the six strings are unchanged from the orchestrator. */
120
+ readonly reportProgress: (label: string) => Promise<void>;
121
+ }
122
+ /**
123
+ * What the previous invocation left for this one (phase 3). Not part of
124
+ * `TurnInput`: `isReinvocation` is the adapter's own derivation from
125
+ * `threadId` (the contract carries no flag by design, `types.ts` header) and
126
+ * the runtime reads it only inside {@link resolveTurnContext}; the decisions
127
+ * ARE on the input. The seeded sub-agent rows are the adapter's to clone from
128
+ * `execution.status` (its accumulator owns `status.subAgentExecutions` and
129
+ * overwrites it on every flush), so they ride nothing here.
130
+ */
131
+ export interface TurnReinvocation {
132
+ /** The engine already holds state for this execution (derived per {@link isReinvocation}). */
133
+ readonly isReinvocation: boolean;
134
+ /** The adjudicated WAITING rows, keyed by tool-call id; empty when nothing was decided. */
135
+ readonly approvalDecisions: ReadonlyMap<string, ApprovalAction>;
136
+ }
137
+ /**
138
+ * A turn that ended during resolution, before any harness ran. Each arm
139
+ * names what was decided and carries only the facts the caller's status
140
+ * writes need; the copy, the phase flip, the persist and the slim return are
141
+ * the caller's (the orchestrator today, the runtime's terminal table in M3).
142
+ *
143
+ * - `workspace-lock-timeout`: another turn held the primary tree past
144
+ * `Config.workspaceLockTimeoutMs`. FAILED, returned (a Temporal retry
145
+ * would queue behind the same holder).
146
+ * - `rejected-by-user`: an adjudicated irreversible action (shell / MCP)
147
+ * was REJECTed. FAILED, returned.
148
+ * - `file-review-resolved`: a pure file-review resume; the agent already
149
+ * finished its turn during capture and the reconcile is the whole act.
150
+ * COMPLETED, returned, with the write-back finalized first when the
151
+ * reconcile held.
152
+ */
153
+ export type TurnSettlement = {
154
+ readonly kind: "workspace-lock-timeout";
155
+ readonly error: WorkspaceLockTimeoutError;
156
+ } | {
157
+ readonly kind: "rejected-by-user";
158
+ } | {
159
+ readonly kind: "file-review-resolved";
160
+ readonly failed: boolean;
161
+ readonly failureDetail: string;
162
+ readonly discardedPaths: readonly string[];
163
+ };
164
+ /** The lock phase's answer: the release handle (absent when there is no primary tree), or the one settlement a lock can produce. */
165
+ export type WorkspaceLockOutcome = {
166
+ readonly kind: "acquired";
167
+ readonly release: ReleaseWorkspaceLock | undefined;
168
+ } | {
169
+ readonly kind: "settled";
170
+ readonly settlement: Extract<TurnSettlement, {
171
+ kind: "workspace-lock-timeout";
172
+ }>;
173
+ };
174
+ /** The reinvocation phase's answer: what the previous invocation left, or one of the two settlements a reconcile can produce. */
175
+ export type ReinvocationOutcome = {
176
+ readonly kind: "ready";
177
+ readonly reinvocation: TurnReinvocation;
178
+ } | {
179
+ readonly kind: "settled";
180
+ readonly settlement: Exclude<TurnSettlement, {
181
+ kind: "workspace-lock-timeout";
182
+ }>;
183
+ };
184
+ /**
185
+ * Whether the engine already holds state for this execution, so this
186
+ * invocation resumes rather than begins. One function keyed on how the
187
+ * harness mints its state id (Q-S2-8):
188
+ *
189
+ * - `engine-minted` (Cursor: the agent id): the runtime knows nothing until
190
+ * the adapter binds an id, so a non-empty `threadId` IS the evidence.
191
+ * Correct today because a pure-reconcile turn does not advance `turnSeq`
192
+ * and the legacy positional wire shape yields 0, so `turnSeq` cannot be
193
+ * the signal (`index.ts` L402-407).
194
+ * - `deterministic` (native: the runtime-minted thread id): the id exists
195
+ * on the FIRST turn too, so the evidence is the persisted transcript
196
+ * (pending approvals, DECIDED sets). That arm lands in S3 with the native
197
+ * adapter; until then this function refuses rather than guess.
198
+ */
199
+ export declare function isReinvocation(stateIdSource: StateIdSource, input: NormalizedActivityInput): boolean;
200
+ /**
201
+ * The runtime's one reader of approval decisions: every top-level tool-call
202
+ * row still WAITING_APPROVAL whose `approvalAction` the server has set,
203
+ * keyed by tool-call id. Derived from the status on every invocation, never
204
+ * stored, so it cannot drift from the rows. The same rows, in the same
205
+ * order, that the Cursor adapter's `reconstructAdjudicatedApprovals` reads
206
+ * for its own facts (the pending-approval protos and content digests); a
207
+ * test pins the two readers' agreement.
208
+ */
209
+ export declare function approvalDecisionsOf(status: AgentExecutionStatus): ReadonlyMap<string, ApprovalAction>;
210
+ /** The facts the reinvocation decision reads; produced by {@link reconcileReinvocation}, exposed for the decision's own tests. */
211
+ export interface ReinvocationFacts {
212
+ readonly approvalDecisions: ReadonlyMap<string, ApprovalAction>;
213
+ /** At least one DECIDED change set was reconciled this invocation. */
214
+ readonly reconciledFileReview: boolean;
215
+ /** A reconcile could not honor what-you-approve-is-what-applies (HASH_MISMATCH). */
216
+ readonly fileReviewFailed: boolean;
217
+ readonly fileReviewFailureDetail: string;
218
+ readonly discardedPaths: readonly string[];
219
+ }
220
+ /**
221
+ * How a reinvocation proceeds, decided once from the facts (`index.ts`
222
+ * L547-618): a REJECT of an irreversible action fails the turn; any other
223
+ * adjudicated decision runs the agent (the approved shell/MCP proceeds and
224
+ * may produce further edits); a resume that reconciled file review and
225
+ * decided nothing else is complete, because keeping or discarding a file
226
+ * never re-prompts the agent (Cursor-like). `undefined` means "run the
227
+ * agent".
228
+ */
229
+ export declare function decideReinvocation(facts: ReinvocationFacts): Exclude<TurnSettlement, {
230
+ kind: "workspace-lock-timeout";
231
+ }> | undefined;
232
+ /**
233
+ * Seed an in-progress status from the persisted execution on a durable
234
+ * resume (HITL approval, pause/resume, transient recovery) so the upcoming
235
+ * turn APPENDS onto prior history instead of replacing it.
236
+ *
237
+ * Why it is required: a resumed engine re-issues the previously gated tool
238
+ * calls with brand-new call ids. Without seeding, the harness's accumulator
239
+ * would rebuild the transcript from empty and emit a status that drops the
240
+ * already-committed tool-call ids. The backend's append-only-at-identity
241
+ * guard rejects any non-terminal update that drops a committed tool-call id,
242
+ * so the resumed progress would never persist: the run stalls in
243
+ * WAITING_FOR_APPROVAL with no pending approvals and the workflow watchdog
244
+ * fails it. Seeding makes the resume status a strict superset; the re-runs
245
+ * are then reconciled in place onto these seeded calls by canonical identity
246
+ * inside the accumulator.
247
+ *
248
+ * The persisted protos are cloned so the input execution stays immutable.
249
+ * Messages are pushed into `status.messages` (which the accumulator wraps by
250
+ * reference) BEFORE the accumulator is constructed. Sub-agent executions are
251
+ * NOT seeded here: the Cursor accumulator owns `status.subAgentExecutions`
252
+ * and overwrites it on every flush, so the adapter clones them itself from
253
+ * `input.execution.status` under the same "left a transcript" test.
254
+ *
255
+ * Moved from `execute-cursor/index.ts` `seedCursorTranscriptFromExecution`
256
+ * (L2468-2478); the native twin is `execute-deep-agent/index.ts`
257
+ * `seedStatusFromExecution` (S3 retires it).
258
+ */
259
+ export declare function seedTranscriptFromExecution(status: AgentExecutionStatus, execution: AgentExecution): void;
260
+ /** Phase 1 (`index.ts` L325-330): hydrate the execution from the control plane. */
261
+ export declare function fetchExecution(deps: ResolutionDeps): Promise<{
262
+ readonly execution: AgentExecution;
263
+ /** `execution.spec`, asserted once here: the control plane never dispatches an execution without one. */
264
+ readonly spec: AgentExecutionSpec;
265
+ readonly sessionId: string;
266
+ }>;
267
+ /** Phase 2 (`index.ts` L332-336): load the session and resolve the full agent blueprint through it. */
268
+ export declare function resolveAgentBlueprint(deps: ResolutionDeps, sessionId: string): Promise<{
269
+ readonly session: Session;
270
+ readonly blueprint: ResolvedBlueprint;
271
+ }>;
272
+ /** Phase 2b (`index.ts` L338-343): the execution environment (MCP server credentials). */
273
+ export declare function resolveEnvironment(deps: ResolutionDeps): Promise<TurnEnvironment>;
274
+ /**
275
+ * Phase 2c, first half (`index.ts` L351-408): provision the workspace (clone
276
+ * git repos / mount local paths) so the LOCAL agent operates on the actual
277
+ * repo, wire the git write-back coordinator, and decide the capture posture.
278
+ *
279
+ * Git provisioning is idempotent across multi-turn and HITL reinvocations.
280
+ * The write-back coordinator pushes the session's APPROVED tree to the
281
+ * session branch (stigmer/<session-id>) and keeps one PR open; finalize runs
282
+ * at exactly two seams (the pure file-review resume and terminal
283
+ * completion), never mid-turn, because the working tree is speculative until
284
+ * reviewed. Non-eligible workspaces (local paths, no credentials) make it a
285
+ * no-op coordinator, here `null`.
286
+ *
287
+ * Apply-then-review is the universal file-review model (Slice 2c): a git work
288
+ * tree captures per-file from the git diff at the turn boundary; a NON-git
289
+ * workspace captures every write via the path-scoped CAS substrate, which
290
+ * needs artifact storage to persist blobs, and falls back to the classic
291
+ * deny-gate without it. `gitWorkspace` selects the substrate; `captureMode`
292
+ * says whether file edits flow at all.
293
+ *
294
+ * The change-set id is minted from the workflow-threaded turn index so it is
295
+ * stable across a Temporal retry (idempotent ledger authoring) and unique per
296
+ * turn; a "wasted" id on a pure-reconcile resume (which never authors a
297
+ * baseline) is harmless.
298
+ */
299
+ export declare function provisionWorkspace(deps: ResolutionDeps, args: {
300
+ readonly session: Session;
301
+ readonly sessionId: string;
302
+ readonly envVars: Record<string, string>;
303
+ }): Promise<{
304
+ readonly workspace: TurnWorkspace;
305
+ readonly writeback: WriteBackCoordinator | null;
306
+ }>;
307
+ /**
308
+ * Phase 2c, second half (`index.ts` L410-449): serialize this turn against
309
+ * every other execution sharing the primary working tree. Sessions declaring
310
+ * the same localPath (or the shared runner root) resolve to ONE directory,
311
+ * and an unserialized concurrent write lands inside this turn's
312
+ * baseline→candidate window, misattributing another session's file to this
313
+ * turn's review. Acquired before ANY tree mutation (decision reconcile, gate
314
+ * install, agent writes, capture); while another turn holds the lock this
315
+ * surfaces a visible waiting state and heartbeats; a cancel aborts the wait
316
+ * at once.
317
+ *
318
+ * Its own phase so the release handle reaches the caller the instant the
319
+ * lock exists: nothing runs between acquisition and hand-over, so nothing
320
+ * can throw and leave a held lock the caller's `finally` never sees.
321
+ */
322
+ export declare function acquireWorkspaceTurnLock(deps: ResolutionDeps, primaryDir: string): Promise<WorkspaceLockOutcome>;
323
+ /**
324
+ * `index.ts` L451-461: set OTel baggage so downstream calls carry execution
325
+ * context. Best-effort; tracing not initialized is a silent skip. Runs after
326
+ * the lock, as it always has.
327
+ */
328
+ export declare function bindTelemetryBaggage(deps: ResolutionDeps, args: {
329
+ readonly session: Session;
330
+ readonly sessionId: string;
331
+ }): Promise<void>;
332
+ /**
333
+ * Phase 3 (`index.ts` L475-619): what the previous invocation left, and
334
+ * whether this one runs the agent at all.
335
+ *
336
+ * On a reinvocation, first seed the in-progress status from the persisted
337
+ * execution ({@link seedTranscriptFromExecution}), BEFORE the harness's
338
+ * accumulator wraps `status.messages`. Then the file-review reconcile (the
339
+ * dual-source half): every change set the server projected as DECIDED is
340
+ * reconciled from the ledger decisions and the pinned git refs (approved
341
+ * kept at their "after" bytes, rejected snapped back to baseline, all
342
+ * uncommitted, hash-verified) through the shared reconcile under the
343
+ * harness's {@link FileReviewIdentity}. Independent of tool approvals: a
344
+ * single turn can carry BOTH a DECIDED file change set AND an approved
345
+ * shell/MCP action. Tool approvals (shell / MCP / gitignored writes) still
346
+ * resolve from the message transcript, the deny-gate path, read here as
347
+ * {@link approvalDecisionsOf} after the reconcile, at the same point the
348
+ * orchestrator always read them.
349
+ *
350
+ * The outcome is {@link decideReinvocation}'s: a settlement the caller
351
+ * writes and persists, or the facts the turn proceeds with.
352
+ */
353
+ export declare function reconcileReinvocation(deps: ResolutionDeps, args: {
354
+ readonly stateIdSource: StateIdSource;
355
+ readonly execution: AgentExecution;
356
+ readonly workspace: TurnWorkspace;
357
+ readonly fileReview: FileReviewIdentity;
358
+ }): Promise<ReinvocationOutcome>;
359
+ /**
360
+ * Phases 4 to 4b (`index.ts` L620-770): the tool surface.
361
+ *
362
+ * The MCP-bound env map (and ONLY it, never the agent process env) carries
363
+ * the reserved caller-identity keys, so a server that declares them in
364
+ * spec.env can template the platform-verified caller into its headers;
365
+ * filterEnvToDeclaredKeys keeps every other server blind. The resolved list
366
+ * then mutates through the Connect backfill and three synthesized
367
+ * attachments, deliberately AFTER resolve + backfill so the backfill's
368
+ * destructiveHint tightener can never force-gate an attachment's tools:
369
+ *
370
+ * - channel messaging (DD-006 D7/D8): the discovery read IS the attachment
371
+ * decision, and every failure mode degrades to honest absence;
372
+ * - conversation participation (channel-conversations DD-008 D-c): the
373
+ * channel-id session label IS the decision, a free local read;
374
+ * - memory capture (DD-005 D1): the recall snapshot's enabled bit IS the
375
+ * decision, server-stamped at execution create.
376
+ *
377
+ * Their credential story (DD-006 D4): the exchanged scoped runner token
378
+ * authenticates the discovery reads per call; the exchange is opportunistic
379
+ * (every consumer degrades to an empty answer by contract, and the server
380
+ * refuses the ambient fallback safely), so a failed exchange must not kill
381
+ * the run, unlike the env read, where secrets are load-bearing.
382
+ *
383
+ * Approval policies merge last, from all layers, with two bypasses shared
384
+ * with the native harness (`shared/approval-policy.ts` `ActiveLeases`): the
385
+ * pre-armed spec.auto_approve_all is the one whole-run global bypass; an
386
+ * interactive APPROVE_ALL grants a run-lifetime lease scoped to that
387
+ * action's class. Layer-3 overrides ride each resolved server from its
388
+ * merged usage (issue #349). The harness projects its SDK config from
389
+ * `servers` after this returns, exactly once, so every mutation is visible
390
+ * by construction.
391
+ */
392
+ export declare function resolveMcpServersAndPolicies(deps: ResolutionDeps, args: {
393
+ readonly execution: AgentExecution;
394
+ readonly session: Session;
395
+ readonly sessionId: string;
396
+ readonly blueprint: ResolvedBlueprint;
397
+ readonly environment: TurnEnvironment;
398
+ }): Promise<TurnMcp>;
399
+ /**
400
+ * Phase 5 (`index.ts` L493-501, the orchestrator's position between the
401
+ * tool surface and the attachments): mount the merged skills under the
402
+ * session's platform dir, reachable from the workspace through its
403
+ * `.stigmer` link, and return what a prompt renders (`shared/skill-
404
+ * resolver.ts`). Reads the control plane, which is why it is the runtime's
405
+ * and not a harness's; each harness places the returned metadata in its own
406
+ * prompt shape. The `.stigmer` link this and the attachment phase create is
407
+ * removed in the runtime's finally, after the harness's own teardown.
408
+ */
409
+ export declare function mountSkills(deps: ResolutionDeps, args: {
410
+ readonly blueprint: ResolvedBlueprint;
411
+ readonly sessionId: string;
412
+ readonly primaryDir: string;
413
+ }): Promise<readonly SkillMetadata[]>;
414
+ /**
415
+ * Phase 5b (`index.ts` L803-838): resolve the turn's attachments, fail-hard
416
+ * (they are explicit user inputs; see `shared/attachment-resolver.ts`).
417
+ * Downloads by storage key through the same artifact storage resolved for
418
+ * status offload. The vision budget rides along so image attachments are
419
+ * selected for inline delivery while their bytes are already in hand
420
+ * (`shared/attachment-vision.ts` owns all policy); it carries the requested
421
+ * model's registry vision capability, looked up from the raw
422
+ * executionConfig name, because full model validation isn't needed for
423
+ * this and ""/"default" (the Auto pool) resolves to unknown, which the
424
+ * policy treats as sighted. The vision profile is the harness's (each
425
+ * engine accepts different image shapes), so it arrives as an argument.
426
+ */
427
+ export declare function resolveTurnAttachments(deps: ResolutionDeps, args: {
428
+ readonly spec: AgentExecutionSpec;
429
+ readonly sessionId: string;
430
+ readonly primaryDir: string;
431
+ readonly visionProfile: VisionProfile;
432
+ }): Promise<TurnAttachments>;
433
+ /**
434
+ * Phase 5b3 (`index.ts` L849-867): exact-apply approved whole-file writes
435
+ * (HITL "what you approve is what gets applied"). A deny-only harness
436
+ * reinvokes the model, which regenerates content, so a resource grant alone
437
+ * cannot guarantee the bytes that land match the bytes the user approved.
438
+ * The runner therefore writes the EXACT approved whole-file content itself
439
+ * and marks those tool calls COMPLETED; the harness then issues NO grant for
440
+ * them, so any FURTHER change the model makes to those files is re-gated.
441
+ * Hunk edits / shell / MCP stay on the grant + reinvocation path, and every
442
+ * uncertain case degrades to that path, so this can never corrupt a file
443
+ * (see `shared/exact-apply.ts`).
444
+ *
445
+ * Scoped OUT of capture mode, which does not reinvoke the model for file
446
+ * edits: it applies the exact captured bytes itself in the reconcile.
447
+ *
448
+ * The caller persists when the returned set is non-empty (the applied state
449
+ * must be durable before the continuation runs, and the UI reflects it at
450
+ * once); this phase, like every phase, never persists.
451
+ */
452
+ export declare function applyApprovedWrites(deps: ResolutionDeps, args: {
453
+ readonly workspace: TurnWorkspace;
454
+ readonly reinvocation: TurnReinvocation;
455
+ }): Promise<ReadonlySet<string>>;
456
+ /**
457
+ * Phase 6, the harness-agnostic half (`index.ts` L998, L1005-1006): the
458
+ * requested model name as the execution states it, and the effective service
459
+ * tier and thinking mode. UNSPECIFIED → STANDARD (#357) and UNSPECIFIED →
460
+ * DISABLED (#772) resolve here and nowhere else; every upstream layer
461
+ * preserves the caller's raw enum values. Validating the NAME against a
462
+ * catalog is the harness's (Cursor's `resolveModelId`), so it is not here.
463
+ */
464
+ export declare function resolveModelPreferences(spec: AgentExecutionSpec): TurnModelPreferences;
465
+ /** Phase 9b (`index.ts` L1183-1184): the structured-output schema the execution asks for, if any. */
466
+ export declare function structuredOutputSchemaOf(spec: AgentExecutionSpec): Record<string, unknown> | undefined;
467
+ /**
468
+ * Phase 9c (`index.ts` L1186-1216, and the metadata reads at L1240-1245):
469
+ * the standing context, read once, and the memory selection prepared once.
470
+ *
471
+ * Selection runs against the frozen first message's semantics: above the
472
+ * activation threshold it picks top-k for spec.message, otherwise (and on
473
+ * any failure) it injects the full candidate set. The outcome report is
474
+ * stamped on the turn's status ONCE, picked up by the next persist; a
475
+ * re-invocation replays the report already persisted on the execution
476
+ * rather than re-selecting (the written-once rule). Memoized because a
477
+ * resumed-agent primary send carries no memories, but a mid-send
478
+ * poisoned-handle failure rebuilds on a FRESH agent whose recovery prompt
479
+ * does, so every memory-carrying build site awaits this lazily.
480
+ */
481
+ export declare function resolveStandingContext(deps: ResolutionDeps, args: {
482
+ readonly execution: AgentExecution;
483
+ readonly spec: AgentExecutionSpec;
484
+ readonly blueprint: ResolvedBlueprint;
485
+ }): TurnStandingContext;
486
+ /**
487
+ * The resources a turn holds that outlive the phase that produced them and
488
+ * must be released or finalized by the caller's `finally` and terminal
489
+ * writes — set on this frame the instant they exist, so no throw between
490
+ * acquisition and hand-over can leave a held lock the caller never sees.
491
+ * Not part of `TurnInput`: an adapter never releases the lock or finalizes
492
+ * the write-back.
493
+ */
494
+ export interface TurnFrame {
495
+ /** The primary tree once provisioned: the `.stigmer` link the skill and attachment phases create under it is removed at turn end. */
496
+ primaryDir: string | undefined;
497
+ /** Exclusive turn lock on the primary tree; released LAST, after the adapter's own teardown. */
498
+ releaseWorkspaceLock: ReleaseWorkspaceLock | undefined;
499
+ /** Finalizes at exactly two seams: the pure file-review resume and terminal completion. `null` when nothing is eligible. */
500
+ writeback: WriteBackCoordinator | null;
501
+ }
502
+ /** What the composer answers: the whole record, or a settlement the caller writes and returns. */
503
+ export type TurnResolution = {
504
+ readonly kind: "ready";
505
+ readonly input: TurnInput;
506
+ } | {
507
+ readonly kind: "settled";
508
+ readonly settlement: TurnSettlement;
509
+ };
510
+ /**
511
+ * Run the twelve phases in order and compose the turn's `TurnInput`, or
512
+ * stop at the first settlement.
513
+ *
514
+ * The order is the orchestrator's, with its harness-specific steps gone
515
+ * (they run inside `adapter.runTurn`, after this returns): the tool surface,
516
+ * the skills, the attachments, the exact-apply, then the reads that need no
517
+ * network.
518
+ *
519
+ * The one persist a phase requires — the applied writes must be durable
520
+ * before the continuation runs — goes through the caller's chokepoint
521
+ * (`persist`), so the rule that phases never persist holds here too.
522
+ */
523
+ export declare function resolveTurnContext(deps: ResolutionDeps, capabilities: HarnessCapabilities, frame: TurnFrame, persist: () => Promise<void>): Promise<TurnResolution>;