@stigmer/runner 3.0.9-dev.20260616060535 → 3.1.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 (328) hide show
  1. package/dist/.build-fingerprint +1 -1
  2. package/dist/__test-utils__/approval-contract/types.d.ts +174 -0
  3. package/dist/__test-utils__/approval-contract/types.js +24 -0
  4. package/dist/__test-utils__/approval-contract/types.js.map +1 -0
  5. package/dist/activities/call-agent-status.d.ts +19 -1
  6. package/dist/activities/call-agent-status.js +64 -5
  7. package/dist/activities/call-agent-status.js.map +1 -1
  8. package/dist/activities/call-llm.js +19 -53
  9. package/dist/activities/call-llm.js.map +1 -1
  10. package/dist/activities/classify-tool-approvals.d.ts +24 -0
  11. package/dist/activities/classify-tool-approvals.js +69 -17
  12. package/dist/activities/classify-tool-approvals.js.map +1 -1
  13. package/dist/activities/discover-mcp-server.d.ts +7 -0
  14. package/dist/activities/discover-mcp-server.js +11 -1
  15. package/dist/activities/discover-mcp-server.js.map +1 -1
  16. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +140 -0
  17. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +130 -0
  18. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -0
  19. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.d.ts +18 -0
  20. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +123 -0
  21. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -0
  22. package/dist/activities/execute-cursor/approval-policy.d.ts +17 -61
  23. package/dist/activities/execute-cursor/approval-policy.js +8 -120
  24. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  25. package/dist/activities/execute-cursor/approval-state.d.ts +219 -9
  26. package/dist/activities/execute-cursor/approval-state.js +233 -17
  27. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  28. package/dist/activities/execute-cursor/capture-flow.d.ts +127 -0
  29. package/dist/activities/execute-cursor/capture-flow.js +234 -0
  30. package/dist/activities/execute-cursor/capture-flow.js.map +1 -0
  31. package/dist/activities/execute-cursor/cas-observations.d.ts +96 -0
  32. package/dist/activities/execute-cursor/cas-observations.js +184 -0
  33. package/dist/activities/execute-cursor/cas-observations.js.map +1 -0
  34. package/dist/activities/execute-cursor/command-provenance.d.ts +62 -0
  35. package/dist/activities/execute-cursor/command-provenance.js +128 -0
  36. package/dist/activities/execute-cursor/command-provenance.js.map +1 -0
  37. package/dist/activities/execute-cursor/exact-apply.d.ts +110 -0
  38. package/dist/activities/execute-cursor/exact-apply.js +204 -0
  39. package/dist/activities/execute-cursor/exact-apply.js.map +1 -0
  40. package/dist/activities/execute-cursor/hook-script.d.ts +53 -24
  41. package/dist/activities/execute-cursor/hook-script.js +310 -47
  42. package/dist/activities/execute-cursor/hook-script.js.map +1 -1
  43. package/dist/activities/execute-cursor/index.d.ts +8 -1
  44. package/dist/activities/execute-cursor/index.js +500 -64
  45. package/dist/activities/execute-cursor/index.js.map +1 -1
  46. package/dist/activities/execute-cursor/message-translator.d.ts +258 -11
  47. package/dist/activities/execute-cursor/message-translator.js +836 -90
  48. package/dist/activities/execute-cursor/message-translator.js.map +1 -1
  49. package/dist/activities/execute-cursor/prompt-builder.d.ts +20 -23
  50. package/dist/activities/execute-cursor/prompt-builder.js +74 -15
  51. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  52. package/dist/activities/execute-cursor/workspace-setup.d.ts +17 -0
  53. package/dist/activities/execute-cursor/workspace-setup.js +212 -33
  54. package/dist/activities/execute-cursor/workspace-setup.js.map +1 -1
  55. package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.d.ts +19 -0
  56. package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.js +143 -0
  57. package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.js.map +1 -0
  58. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +88 -0
  59. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +81 -0
  60. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -0
  61. package/dist/activities/execute-deep-agent/approval-file-change.d.ts +47 -0
  62. package/dist/activities/execute-deep-agent/approval-file-change.js +68 -0
  63. package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -0
  64. package/dist/activities/execute-deep-agent/attachment-injector.d.ts +8 -1
  65. package/dist/activities/execute-deep-agent/attachment-injector.js +7 -7
  66. package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -1
  67. package/dist/activities/execute-deep-agent/cas-capture-backend.d.ts +42 -0
  68. package/dist/activities/execute-deep-agent/cas-capture-backend.js +47 -0
  69. package/dist/activities/execute-deep-agent/cas-capture-backend.js.map +1 -0
  70. package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +79 -0
  71. package/dist/activities/execute-deep-agent/cas-capture-observer.js +112 -0
  72. package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -0
  73. package/dist/activities/execute-deep-agent/hitl.d.ts +10 -0
  74. package/dist/activities/execute-deep-agent/hitl.js +5 -1
  75. package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
  76. package/dist/activities/execute-deep-agent/index.d.ts +2 -1
  77. package/dist/activities/execute-deep-agent/index.js +370 -56
  78. package/dist/activities/execute-deep-agent/index.js.map +1 -1
  79. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +7 -1
  80. package/dist/activities/execute-deep-agent/inline-publisher.js +23 -2
  81. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
  82. package/dist/activities/execute-deep-agent/setup.d.ts +53 -2
  83. package/dist/activities/execute-deep-agent/setup.js +149 -92
  84. package/dist/activities/execute-deep-agent/setup.js.map +1 -1
  85. package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +36 -0
  86. package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +56 -0
  87. package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +1 -0
  88. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +34 -1
  89. package/dist/activities/execute-deep-agent/status-builder-shared.js +26 -25
  90. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
  91. package/dist/activities/execute-deep-agent/status-builder.d.ts +11 -5
  92. package/dist/activities/execute-deep-agent/status-builder.js +6 -2
  93. package/dist/activities/execute-deep-agent/status-builder.js.map +1 -1
  94. package/dist/activities/execute-deep-agent/streaming-side-effects.js +2 -19
  95. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  96. package/dist/activities/execute-deep-agent/streaming.js +3 -15
  97. package/dist/activities/execute-deep-agent/streaming.js.map +1 -1
  98. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -7
  99. package/dist/activities/execute-deep-agent/subagent-transformer.js +23 -7
  100. package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
  101. package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +30 -3
  102. package/dist/activities/execute-deep-agent/subagent-wiring.js +29 -3
  103. package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
  104. package/dist/activities/execute-deep-agent/v3-status-builder.js +6 -2
  105. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
  106. package/dist/claimcheck/payload-codec.js +9 -5
  107. package/dist/claimcheck/payload-codec.js.map +1 -1
  108. package/dist/client/stigmer-client.d.ts +2 -0
  109. package/dist/client/stigmer-client.js +2 -0
  110. package/dist/client/stigmer-client.js.map +1 -1
  111. package/dist/middleware/approval-gate.d.ts +85 -4
  112. package/dist/middleware/approval-gate.js +165 -38
  113. package/dist/middleware/approval-gate.js.map +1 -1
  114. package/dist/middleware/types.d.ts +2 -5
  115. package/dist/shared/activity-input.d.ts +43 -0
  116. package/dist/shared/activity-input.js +17 -0
  117. package/dist/shared/activity-input.js.map +1 -0
  118. package/dist/shared/approval-canonicalize.d.ts +19 -0
  119. package/dist/shared/approval-canonicalize.js +119 -0
  120. package/dist/shared/approval-canonicalize.js.map +1 -0
  121. package/dist/shared/approval-fingerprint.d.ts +106 -0
  122. package/dist/shared/approval-fingerprint.js +113 -0
  123. package/dist/shared/approval-fingerprint.js.map +1 -0
  124. package/dist/shared/approval-policy.d.ts +182 -12
  125. package/dist/shared/approval-policy.js +213 -27
  126. package/dist/shared/approval-policy.js.map +1 -1
  127. package/dist/shared/args-preview.d.ts +52 -0
  128. package/dist/shared/args-preview.js +93 -0
  129. package/dist/shared/args-preview.js.map +1 -0
  130. package/dist/shared/artifact-storage.d.ts +19 -1
  131. package/dist/shared/artifact-storage.js +48 -11
  132. package/dist/shared/artifact-storage.js.map +1 -1
  133. package/dist/shared/file-change.d.ts +44 -0
  134. package/dist/shared/file-change.js +57 -0
  135. package/dist/shared/file-change.js.map +1 -0
  136. package/dist/shared/file-tools.d.ts +107 -0
  137. package/dist/shared/file-tools.js +168 -0
  138. package/dist/shared/file-tools.js.map +1 -0
  139. package/dist/shared/filereview/capture.d.ts +202 -0
  140. package/dist/shared/filereview/capture.js +498 -0
  141. package/dist/shared/filereview/capture.js.map +1 -0
  142. package/dist/shared/filereview/cas-substrate.d.ts +190 -0
  143. package/dist/shared/filereview/cas-substrate.js +284 -0
  144. package/dist/shared/filereview/cas-substrate.js.map +1 -0
  145. package/dist/shared/filereview/digest.d.ts +40 -0
  146. package/dist/shared/filereview/digest.js +66 -0
  147. package/dist/shared/filereview/digest.js.map +1 -0
  148. package/dist/shared/filereview/events.d.ts +170 -0
  149. package/dist/shared/filereview/events.js +298 -0
  150. package/dist/shared/filereview/events.js.map +1 -0
  151. package/dist/shared/filereview/git-substrate.d.ts +175 -0
  152. package/dist/shared/filereview/git-substrate.js +439 -0
  153. package/dist/shared/filereview/git-substrate.js.map +1 -0
  154. package/dist/shared/filereview/index.d.ts +11 -0
  155. package/dist/shared/filereview/index.js +12 -0
  156. package/dist/shared/filereview/index.js.map +1 -0
  157. package/dist/shared/filereview/secret-paths.d.ts +63 -0
  158. package/dist/shared/filereview/secret-paths.js +105 -0
  159. package/dist/shared/filereview/secret-paths.js.map +1 -0
  160. package/dist/shared/fingerprint-secret.d.ts +26 -0
  161. package/dist/shared/fingerprint-secret.js +47 -0
  162. package/dist/shared/fingerprint-secret.js.map +1 -0
  163. package/dist/shared/model-client.d.ts +51 -0
  164. package/dist/shared/model-client.js +77 -0
  165. package/dist/shared/model-client.js.map +1 -0
  166. package/dist/shared/plan-artifact.js +0 -2
  167. package/dist/shared/plan-artifact.js.map +1 -1
  168. package/dist/shared/status-offload.d.ts +83 -9
  169. package/dist/shared/status-offload.js +399 -79
  170. package/dist/shared/status-offload.js.map +1 -1
  171. package/dist/shared/status.js +14 -1
  172. package/dist/shared/status.js.map +1 -1
  173. package/dist/shared/tool-kind.d.ts +19 -0
  174. package/dist/shared/tool-kind.js +13 -0
  175. package/dist/shared/tool-kind.js.map +1 -1
  176. package/dist/shared/tool-row.d.ts +88 -0
  177. package/dist/shared/tool-row.js +127 -0
  178. package/dist/shared/tool-row.js.map +1 -0
  179. package/dist/shared/workspace/platform-dir.d.ts +25 -0
  180. package/dist/shared/workspace/platform-dir.js +38 -2
  181. package/dist/shared/workspace/platform-dir.js.map +1 -1
  182. package/dist/workflows/call-agent-orchestrator.js +56 -7
  183. package/dist/workflows/call-agent-orchestrator.js.map +1 -1
  184. package/dist/workflows/connect-mcp-server.d.ts +50 -0
  185. package/dist/workflows/connect-mcp-server.js +136 -15
  186. package/dist/workflows/connect-mcp-server.js.map +1 -1
  187. package/dist/workflows/types.d.ts +8 -0
  188. package/package.json +2 -2
  189. package/src/__test-utils__/approval-contract/contract.ts +224 -0
  190. package/src/__test-utils__/approval-contract/types.ts +179 -0
  191. package/src/__test-utils__/fake-artifact-storage.ts +72 -0
  192. package/src/__tests__/approval-gateway-contract.test.ts +29 -0
  193. package/src/__tests__/claimcheck-codec.test.ts +16 -53
  194. package/src/__tests__/golden-e2e.test.ts +2 -0
  195. package/src/__tests__/runner-token-coordinator.test.ts +3 -3
  196. package/src/activities/__tests__/call-agent-status.test.ts +135 -0
  197. package/src/activities/__tests__/call-llm.test.ts +1 -1
  198. package/src/activities/__tests__/classify-tool-approvals.test.ts +208 -1
  199. package/src/activities/__tests__/discover-mcp-server.test.ts +30 -0
  200. package/src/activities/__tests__/workflow-event-activities.test.ts +2 -1
  201. package/src/activities/call-agent-status.ts +74 -4
  202. package/src/activities/call-llm.ts +18 -63
  203. package/src/activities/classify-tool-approvals.ts +101 -19
  204. package/src/activities/discover-mcp-server.ts +29 -1
  205. package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +216 -0
  206. package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +148 -0
  207. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +41 -9
  208. package/src/activities/execute-cursor/__tests__/approval-state.test.ts +292 -0
  209. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +68 -1
  210. package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +1005 -0
  211. package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +187 -0
  212. package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +97 -0
  213. package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +240 -0
  214. package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +203 -0
  215. package/src/activities/execute-cursor/__tests__/exact-apply.test.ts +375 -0
  216. package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +1294 -24
  217. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +446 -0
  218. package/src/activities/execute-cursor/__tests__/hook-script.test.ts +384 -110
  219. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +171 -25
  220. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +189 -0
  221. package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +44 -23
  222. package/src/activities/execute-cursor/__tests__/workspace-setup.test.ts +190 -10
  223. package/src/activities/execute-cursor/approval-policy.ts +28 -159
  224. package/src/activities/execute-cursor/approval-state.ts +366 -18
  225. package/src/activities/execute-cursor/capture-flow.ts +323 -0
  226. package/src/activities/execute-cursor/cas-observations.ts +204 -0
  227. package/src/activities/execute-cursor/command-provenance.ts +168 -0
  228. package/src/activities/execute-cursor/exact-apply.ts +253 -0
  229. package/src/activities/execute-cursor/hook-script.ts +317 -51
  230. package/src/activities/execute-cursor/index.ts +575 -67
  231. package/src/activities/execute-cursor/message-translator.ts +963 -89
  232. package/src/activities/execute-cursor/prompt-builder.ts +80 -14
  233. package/src/activities/execute-cursor/workspace-setup.ts +257 -42
  234. package/src/activities/execute-deep-agent/__test-utils__/gateway-substrate.ts +180 -0
  235. package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +134 -0
  236. package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +84 -0
  237. package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +11 -24
  238. package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +64 -0
  239. package/src/activities/execute-deep-agent/__tests__/cas-capture-observer.test.ts +163 -0
  240. package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +8 -5
  241. package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +342 -0
  242. package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +2 -5
  243. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +31 -13
  244. package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +349 -0
  245. package/src/activities/execute-deep-agent/__tests__/stamp-flowed-rows.test.ts +119 -0
  246. package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +12 -11
  247. package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +9 -9
  248. package/src/activities/execute-deep-agent/__tests__/subagent-approval-propagation.test.ts +160 -0
  249. package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +213 -0
  250. package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +3 -6
  251. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +84 -1
  252. package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +4 -1
  253. package/src/activities/execute-deep-agent/approval-file-change.ts +80 -0
  254. package/src/activities/execute-deep-agent/attachment-injector.ts +20 -11
  255. package/src/activities/execute-deep-agent/cas-capture-backend.ts +66 -0
  256. package/src/activities/execute-deep-agent/cas-capture-observer.ts +125 -0
  257. package/src/activities/execute-deep-agent/hitl.ts +15 -1
  258. package/src/activities/execute-deep-agent/index.ts +434 -64
  259. package/src/activities/execute-deep-agent/inline-publisher.ts +27 -4
  260. package/src/activities/execute-deep-agent/setup.ts +223 -125
  261. package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +64 -0
  262. package/src/activities/execute-deep-agent/status-builder-shared.ts +62 -23
  263. package/src/activities/execute-deep-agent/status-builder.ts +19 -7
  264. package/src/activities/execute-deep-agent/streaming-side-effects.ts +2 -16
  265. package/src/activities/execute-deep-agent/streaming.ts +3 -13
  266. package/src/activities/execute-deep-agent/subagent-transformer.ts +53 -13
  267. package/src/activities/execute-deep-agent/subagent-wiring.ts +50 -3
  268. package/src/activities/execute-deep-agent/v3-status-builder.ts +8 -2
  269. package/src/claimcheck/payload-codec.ts +8 -8
  270. package/src/client/stigmer-client.ts +9 -1
  271. package/src/middleware/__tests__/approval-gate.test.ts +488 -4
  272. package/src/middleware/approval-gate.ts +247 -38
  273. package/src/middleware/types.ts +5 -5
  274. package/src/shared/__tests__/activity-input.test.ts +78 -0
  275. package/src/shared/__tests__/approval-canonicalize.test.ts +106 -0
  276. package/src/shared/__tests__/approval-fingerprint.test.ts +115 -0
  277. package/src/shared/__tests__/approval-policy.test.ts +274 -40
  278. package/src/shared/__tests__/args-preview.test.ts +78 -0
  279. package/src/shared/__tests__/artifact-storage-extended.test.ts +62 -10
  280. package/src/shared/__tests__/artifact-storage.test.ts +123 -11
  281. package/src/shared/__tests__/file-change.test.ts +85 -0
  282. package/src/shared/__tests__/file-tools.test.ts +90 -0
  283. package/src/shared/__tests__/fingerprint-secret.test.ts +51 -0
  284. package/src/shared/__tests__/lease-scope-corpus.test.ts +56 -0
  285. package/src/shared/__tests__/model-client.test.ts +162 -0
  286. package/src/shared/__tests__/plan-artifact.test.ts +11 -26
  287. package/src/shared/__tests__/policy-source-corpus.test.ts +58 -0
  288. package/src/shared/__tests__/status-offload.test.ts +573 -16
  289. package/src/shared/__tests__/status.test.ts +4 -5
  290. package/src/shared/__tests__/tool-kind.test.ts +24 -1
  291. package/src/shared/__tests__/tool-row.test.ts +221 -0
  292. package/src/shared/activity-input.ts +57 -0
  293. package/src/shared/approval-canonicalize.ts +159 -0
  294. package/src/shared/approval-fingerprint.ts +148 -0
  295. package/src/shared/approval-policy.ts +303 -27
  296. package/src/shared/args-preview.ts +98 -0
  297. package/src/shared/artifact-storage.ts +62 -11
  298. package/src/shared/checkpointer/__tests__/http-saver.test.ts +1 -2
  299. package/src/shared/file-change.ts +64 -0
  300. package/src/shared/file-tools.ts +169 -0
  301. package/src/shared/filereview/__tests__/capture.test.ts +856 -0
  302. package/src/shared/filereview/__tests__/cas-substrate.test.ts +404 -0
  303. package/src/shared/filereview/__tests__/digest.test.ts +100 -0
  304. package/src/shared/filereview/__tests__/events.test.ts +245 -0
  305. package/src/shared/filereview/__tests__/git-substrate.test.ts +362 -0
  306. package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +286 -0
  307. package/src/shared/filereview/__tests__/secret-paths.test.ts +121 -0
  308. package/src/shared/filereview/capture.ts +727 -0
  309. package/src/shared/filereview/cas-substrate.ts +401 -0
  310. package/src/shared/filereview/digest.ts +83 -0
  311. package/src/shared/filereview/events.ts +449 -0
  312. package/src/shared/filereview/git-substrate.ts +555 -0
  313. package/src/shared/filereview/index.ts +60 -0
  314. package/src/shared/filereview/secret-paths.ts +121 -0
  315. package/src/shared/fingerprint-secret.ts +53 -0
  316. package/src/shared/model-client.ts +122 -0
  317. package/src/shared/plan-artifact.ts +0 -2
  318. package/src/shared/status-offload.ts +433 -77
  319. package/src/shared/status.ts +13 -0
  320. package/src/shared/tool-kind.ts +33 -0
  321. package/src/shared/tool-row.ts +135 -0
  322. package/src/shared/workspace/platform-dir.ts +41 -2
  323. package/src/workflow-engine/__tests__/golden-execution.test.ts +35 -18
  324. package/src/workflow-engine/__tests__/tasks/try.test.ts +1 -1
  325. package/src/workflows/__tests__/connect-mcp-server.test.ts +304 -29
  326. package/src/workflows/call-agent-orchestrator.ts +53 -6
  327. package/src/workflows/connect-mcp-server.ts +179 -24
  328. package/src/workflows/types.ts +8 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Content-addressed snapshot/restore substrate for the apply-then-review HITL
3
+ * subsystem — the sibling of {@link ./git-substrate.js} for paths git cannot
4
+ * snapshot (`.gitignored` and non-git files). It closes the "gap" the git
5
+ * substrate documents at its top: shell/MCP and gitignored writes are not
6
+ * reversible by git, so today they stay on the deny-gate; this module makes
7
+ * gitignored / non-git file edits capturable, reviewable, and reversible.
8
+ *
9
+ * THE MODEL (mirrors the git substrate, different storage domain)
10
+ * --------------------------------------------------------------
11
+ * The git substrate snapshots the whole working tree at the turn boundary and
12
+ * diffs two pinned tree objects. CAS cannot do that: git does not see ignored
13
+ * paths, and a plain directory has no history to recover a pre-edit byte from.
14
+ * So the CAS substrate is fed the exact before/after bytes of each touched path
15
+ * (captured by the harness at mutation time — the deep-agent's
16
+ * CasCaptureFilesystemBackend, or the Cursor hook staging the file before it
17
+ * allows the write) and:
18
+ *
19
+ * 1. Stores each distinct before/after body as a CONTENT-ADDRESSED blob under
20
+ * `artifacts/{executionId}/filereview/cas/blobs/{sha256}` (deduped by hash,
21
+ * idempotent), reusing the existing {@link ArtifactStorage} — no new store.
22
+ * 2. Writes a per-change-set MANIFEST (path -> before/after blob refs) under
23
+ * `artifacts/{executionId}/filereview/cas/{changeSetId}.manifest.json`. The
24
+ * manifest is the durable, authoritative source for the resume-time
25
+ * reconcile — the CAS analogue of the git substrate's pinned refs.
26
+ * 3. On resume, reconciles the workspace to the user's per-file decisions
27
+ * sourced ENTIRELY from the manifest: approved files are written to their
28
+ * "after" bytes; rejected/undecided files are snapped back to their "before"
29
+ * bytes (or removed, for a rejected create). Symmetric and idempotent.
30
+ *
31
+ * DURABILITY DOMAIN (design doc 11 D3)
32
+ * -----------------------------------
33
+ * Unlike git refs, which live inside the repo, CAS blobs + manifests live in
34
+ * artifact storage (a fixed host path in OSS, R2 via the proxy in Cloud) — a
35
+ * DIFFERENT durability domain that must outlive the multi-day approval wait and
36
+ * a sandbox recycle. Because reconcile reads only from the manifest + blobs
37
+ * (never the live tree), it converges regardless of the tree's current state,
38
+ * so a Temporal retry or a recycled workspace is harmless.
39
+ *
40
+ * WHAT THIS MODULE IS NOT
41
+ * -----------------------
42
+ * It is harness-agnostic and wiring-agnostic: it takes explicit before/after
43
+ * bytes, never reads gitignore, never talks to a hook. WHICH paths flow here (vs
44
+ * stay on the deny-gate or block as DIFF_UNREVIEWABLE), and the secret-safety
45
+ * gate (design doc 12), are the harness adapter's concern, applied BEFORE bytes
46
+ * reach this module. This module never persists a path it is not given.
47
+ *
48
+ * @since File-Change HITL Redesign (Phase 3 — CAS)
49
+ */
50
+ import { FileCaptureClass, FileChangeKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
51
+ import type { ArtifactStorage } from "../artifact-storage.js";
52
+ /**
53
+ * Reads an artifact's raw bytes back by storage key. Injected so this module
54
+ * stays free of HTTP/transport concerns and is trivially testable; production
55
+ * callers build one with {@link casBlobReader}.
56
+ */
57
+ export type BlobReader = (storageKey: string) => Promise<Buffer>;
58
+ /** A stored, content-addressed blob and where to find it. */
59
+ export interface CasBlobRef {
60
+ /** Lowercase-hex SHA-256 of the bytes (the content address + enforcement digest). */
61
+ readonly sha256: string;
62
+ /** Artifact-storage key the bytes live under. */
63
+ readonly storageKey: string;
64
+ readonly sizeBytes: number;
65
+ /** A NUL byte was present — the diff cannot render as text (blocks COMPLETE). */
66
+ readonly isBinary: boolean;
67
+ }
68
+ /** One captured file within a CAS change set (before/after blob refs). */
69
+ export interface CasCapturedFile {
70
+ /** Path before the change (workspace-relative). Empty for ADD. */
71
+ readonly pathBefore: string;
72
+ /** Path after the change. Empty for DELETE. */
73
+ readonly pathAfter: string;
74
+ readonly kind: FileChangeKind;
75
+ /** Which substrate class captured it (GIT_IGNORED_CAPTURED | NON_GIT_CAS). */
76
+ readonly captureClass: FileCaptureClass;
77
+ /** Pre-edit blob; absent for ADD. */
78
+ readonly before?: CasBlobRef;
79
+ /** Post-edit blob; absent for DELETE. */
80
+ readonly after?: CasBlobRef;
81
+ /** False when a side is binary — the change set cannot be approved as complete. */
82
+ readonly diffComplete: boolean;
83
+ }
84
+ /** The durable manifest for one change set — the reconcile's source of truth. */
85
+ export interface CasManifest {
86
+ readonly changeSetId: string;
87
+ readonly files: readonly CasCapturedFile[];
88
+ }
89
+ /** A pointer to a persisted {@link CasManifest} (mirrors the proto CasManifestRef). */
90
+ export interface CasSnapshotRef {
91
+ /** SHA-256 over the canonical manifest JSON (tamper/integrity check). */
92
+ readonly manifestDigest: string;
93
+ /** Artifact-storage key the manifest JSON lives under. */
94
+ readonly artifactUri: string;
95
+ }
96
+ /** The before/after bytes of one path the harness captured this turn. */
97
+ export interface CasPathCapture {
98
+ /** Workspace-root-relative path. */
99
+ readonly path: string;
100
+ /** Pre-edit bytes; `null` when the file did not exist before (an ADD). */
101
+ readonly before: Uint8Array | null;
102
+ /** Post-edit bytes; `null` when the file was removed (a DELETE). */
103
+ readonly after: Uint8Array | null;
104
+ /** Which substrate class this path belongs to (for the ledger). */
105
+ readonly captureClass: FileCaptureClass;
106
+ }
107
+ /** The CAS blob key for a content hash, under the execution's artifact prefix. */
108
+ export declare function casBlobKey(executionId: string, sha256: string): string;
109
+ /**
110
+ * The manifest key for a change set. The change-set id (`{exec}:{turnSeq}`)
111
+ * carries a colon; it is sanitized to a filesystem/object-store-safe segment so
112
+ * the key is portable across the local FS and R2 backends.
113
+ */
114
+ export declare function casManifestKey(executionId: string, changeSetId: string): string;
115
+ /**
116
+ * Capture a CAS change set: store every distinct before/after body as a
117
+ * content-addressed blob (deduped, idempotent), assemble the per-file manifest,
118
+ * persist it, and return the manifest plus its ref for the ledger's SnapshotRef.
119
+ *
120
+ * Captures whose before and after bytes are byte-identical (a path touched but
121
+ * left unchanged) are dropped — they are not a reviewable change, exactly as the
122
+ * git substrate's diff omits unchanged files.
123
+ */
124
+ export declare function snapshotCasChangeSet(opts: {
125
+ readonly storage: ArtifactStorage;
126
+ readonly executionId: string;
127
+ readonly changeSetId: string;
128
+ readonly captures: readonly CasPathCapture[];
129
+ }): Promise<{
130
+ manifest: CasManifest;
131
+ ref: CasSnapshotRef;
132
+ }>;
133
+ /**
134
+ * Load a change set's CAS manifest for the resume-time reconcile, digest-verified
135
+ * against the ledger's {@link CasSnapshotRef}.
136
+ *
137
+ * Called ONLY when the caller has already determined this turn captured CAS files
138
+ * — from the change set's CANDIDATE snapshot (the ledger's record of the
139
+ * substrate), never by probing storage. The ref is the whole contract: the
140
+ * manifest is fetched from the exact `artifactUri` the CANDIDATE event recorded
141
+ * (not a re-derived key, so a pending change set survives any future key-scheme
142
+ * change), and the downloaded bytes must hash to `manifestDigest` before they are
143
+ * trusted. Per-blob content addresses protect blob BODIES, but only this check
144
+ * protects the path→blob mapping itself — a corrupted or swapped manifest could
145
+ * otherwise direct a valid blob to the wrong path.
146
+ *
147
+ * Fail-closed: a missing manifest (surfaced by the reader) or a digest mismatch
148
+ * is a genuine integrity error, never a "this was a git-only turn" signal.
149
+ * (Deciding the substrate from storage existence was unsafe: a presigned/proxy
150
+ * backend cannot answer "does this key exist?" reliably, and a git-only turn —
151
+ * which writes no manifest — would then attempt a doomed download.)
152
+ */
153
+ export declare function loadCasManifest(opts: {
154
+ readonly readBlob: BlobReader;
155
+ readonly ref: CasSnapshotRef;
156
+ }): Promise<CasManifest>;
157
+ /**
158
+ * Ensure the APPROVED files hold their captured "after" bytes on disk. An
159
+ * approved CREATE/MODIFY writes the after blob (integrity-checked against its
160
+ * content address); an approved DELETE removes the file. Idempotent — re-running
161
+ * converges (the after blob is immutable), so a Temporal retry is safe.
162
+ *
163
+ * Enforcement ("what you approve is what applies"): the downloaded bytes must
164
+ * still hash to the blob's content address; a mismatch (storage corruption)
165
+ * throws rather than writing wrong bytes.
166
+ */
167
+ export declare function applyCasApproved(opts: {
168
+ readonly readBlob: BlobReader;
169
+ readonly workspaceRoot: string;
170
+ readonly files: readonly CasCapturedFile[];
171
+ }): Promise<void>;
172
+ /**
173
+ * Snap the REJECTED/undecided files back to their captured "before" bytes: a
174
+ * rejected CREATE is removed; a rejected MODIFY/DELETE is rewritten with its
175
+ * before blob. Idempotent, and the byte-exact inverse of {@link applyCasApproved}.
176
+ */
177
+ export declare function restoreCasToBaseline(opts: {
178
+ readonly readBlob: BlobReader;
179
+ readonly workspaceRoot: string;
180
+ readonly files: readonly CasCapturedFile[];
181
+ }): Promise<void>;
182
+ /**
183
+ * Adapt the artifact storage port's {@link ArtifactStorage.download} into a
184
+ * {@link BlobReader}. The seam is retained so the reconcile functions
185
+ * ({@link loadCasManifest}, {@link applyCasApproved}, {@link restoreCasToBaseline})
186
+ * depend only on "read one blob by key", not on the whole storage interface.
187
+ * `download` already throws a descriptive, key-scoped error on a missing blob or
188
+ * transport failure, so no extra wrapping is needed here.
189
+ */
190
+ export declare function casBlobReader(storage: ArtifactStorage): BlobReader;
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Content-addressed snapshot/restore substrate for the apply-then-review HITL
3
+ * subsystem — the sibling of {@link ./git-substrate.js} for paths git cannot
4
+ * snapshot (`.gitignored` and non-git files). It closes the "gap" the git
5
+ * substrate documents at its top: shell/MCP and gitignored writes are not
6
+ * reversible by git, so today they stay on the deny-gate; this module makes
7
+ * gitignored / non-git file edits capturable, reviewable, and reversible.
8
+ *
9
+ * THE MODEL (mirrors the git substrate, different storage domain)
10
+ * --------------------------------------------------------------
11
+ * The git substrate snapshots the whole working tree at the turn boundary and
12
+ * diffs two pinned tree objects. CAS cannot do that: git does not see ignored
13
+ * paths, and a plain directory has no history to recover a pre-edit byte from.
14
+ * So the CAS substrate is fed the exact before/after bytes of each touched path
15
+ * (captured by the harness at mutation time — the deep-agent's
16
+ * CasCaptureFilesystemBackend, or the Cursor hook staging the file before it
17
+ * allows the write) and:
18
+ *
19
+ * 1. Stores each distinct before/after body as a CONTENT-ADDRESSED blob under
20
+ * `artifacts/{executionId}/filereview/cas/blobs/{sha256}` (deduped by hash,
21
+ * idempotent), reusing the existing {@link ArtifactStorage} — no new store.
22
+ * 2. Writes a per-change-set MANIFEST (path -> before/after blob refs) under
23
+ * `artifacts/{executionId}/filereview/cas/{changeSetId}.manifest.json`. The
24
+ * manifest is the durable, authoritative source for the resume-time
25
+ * reconcile — the CAS analogue of the git substrate's pinned refs.
26
+ * 3. On resume, reconciles the workspace to the user's per-file decisions
27
+ * sourced ENTIRELY from the manifest: approved files are written to their
28
+ * "after" bytes; rejected/undecided files are snapped back to their "before"
29
+ * bytes (or removed, for a rejected create). Symmetric and idempotent.
30
+ *
31
+ * DURABILITY DOMAIN (design doc 11 D3)
32
+ * -----------------------------------
33
+ * Unlike git refs, which live inside the repo, CAS blobs + manifests live in
34
+ * artifact storage (a fixed host path in OSS, R2 via the proxy in Cloud) — a
35
+ * DIFFERENT durability domain that must outlive the multi-day approval wait and
36
+ * a sandbox recycle. Because reconcile reads only from the manifest + blobs
37
+ * (never the live tree), it converges regardless of the tree's current state,
38
+ * so a Temporal retry or a recycled workspace is harmless.
39
+ *
40
+ * WHAT THIS MODULE IS NOT
41
+ * -----------------------
42
+ * It is harness-agnostic and wiring-agnostic: it takes explicit before/after
43
+ * bytes, never reads gitignore, never talks to a hook. WHICH paths flow here (vs
44
+ * stay on the deny-gate or block as DIFF_UNREVIEWABLE), and the secret-safety
45
+ * gate (design doc 12), are the harness adapter's concern, applied BEFORE bytes
46
+ * reach this module. This module never persists a path it is not given.
47
+ *
48
+ * @since File-Change HITL Redesign (Phase 3 — CAS)
49
+ */
50
+ import { mkdir, rm, writeFile } from "node:fs/promises";
51
+ import { dirname, join } from "node:path";
52
+ import { FileChangeKind, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
53
+ import { bytesLookBinary } from "../file-change.js";
54
+ import { sha256Bytes, sha256Hex } from "./digest.js";
55
+ // ---------------------------------------------------------------------------
56
+ // Key namespace (design doc 08: execution-scoped, reuse existing authz)
57
+ // ---------------------------------------------------------------------------
58
+ /** The CAS blob key for a content hash, under the execution's artifact prefix. */
59
+ export function casBlobKey(executionId, sha256) {
60
+ return `artifacts/${executionId}/filereview/cas/blobs/${sha256}`;
61
+ }
62
+ /**
63
+ * The manifest key for a change set. The change-set id (`{exec}:{turnSeq}`)
64
+ * carries a colon; it is sanitized to a filesystem/object-store-safe segment so
65
+ * the key is portable across the local FS and R2 backends.
66
+ */
67
+ export function casManifestKey(executionId, changeSetId) {
68
+ const safe = changeSetId.replace(/[^A-Za-z0-9._-]/g, "_");
69
+ return `artifacts/${executionId}/filereview/cas/${safe}.manifest.json`;
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Capture
73
+ // ---------------------------------------------------------------------------
74
+ /**
75
+ * Capture a CAS change set: store every distinct before/after body as a
76
+ * content-addressed blob (deduped, idempotent), assemble the per-file manifest,
77
+ * persist it, and return the manifest plus its ref for the ledger's SnapshotRef.
78
+ *
79
+ * Captures whose before and after bytes are byte-identical (a path touched but
80
+ * left unchanged) are dropped — they are not a reviewable change, exactly as the
81
+ * git substrate's diff omits unchanged files.
82
+ */
83
+ export async function snapshotCasChangeSet(opts) {
84
+ const { storage, executionId, changeSetId, captures } = opts;
85
+ const files = [];
86
+ for (const capture of captures) {
87
+ const file = await buildCasCapturedFile(storage, executionId, capture);
88
+ if (file)
89
+ files.push(file);
90
+ }
91
+ // Deterministic order (by after path, then before path) so the manifest digest
92
+ // is stable and, later, composes with the git manifest into one aggregate
93
+ // digest that is byte-identical across editions (design doc 08 D3).
94
+ files.sort(compareByPath);
95
+ const manifest = { changeSetId, files };
96
+ const canonical = canonicalManifestJson(manifest);
97
+ const manifestKey = casManifestKey(executionId, changeSetId);
98
+ await storage.upload(manifestKey, Buffer.from(canonical, "utf8"), "application/json");
99
+ return {
100
+ manifest,
101
+ ref: { manifestDigest: sha256Hex(canonical), artifactUri: manifestKey },
102
+ };
103
+ }
104
+ /**
105
+ * Store one path's before/after blobs and classify the change. Returns
106
+ * `undefined` for a no-op (both sides absent, or an unchanged touch).
107
+ */
108
+ async function buildCasCapturedFile(storage, executionId, capture) {
109
+ const { path, before, after, captureClass } = capture;
110
+ if (before === null && after === null)
111
+ return undefined;
112
+ const beforeBuf = before === null ? null : Buffer.from(before);
113
+ const afterBuf = after === null ? null : Buffer.from(after);
114
+ // A touch that did not change the bytes is not a reviewable change.
115
+ if (beforeBuf && afterBuf && beforeBuf.equals(afterBuf))
116
+ return undefined;
117
+ const beforeRef = beforeBuf ? await storeBlob(storage, executionId, beforeBuf) : undefined;
118
+ const afterRef = afterBuf ? await storeBlob(storage, executionId, afterBuf) : undefined;
119
+ const kind = beforeRef === undefined
120
+ ? FileChangeKind.ADD
121
+ : afterRef === undefined
122
+ ? FileChangeKind.DELETE
123
+ : FileChangeKind.MODIFY;
124
+ const isCreate = kind === FileChangeKind.ADD;
125
+ const isDelete = kind === FileChangeKind.DELETE;
126
+ return {
127
+ pathBefore: isCreate ? "" : path,
128
+ pathAfter: isDelete ? "" : path,
129
+ kind,
130
+ captureClass,
131
+ before: beforeRef,
132
+ after: afterRef,
133
+ // Binary on either side means the diff cannot render as text; the change set
134
+ // then cannot be approved as complete (parity with the git substrate).
135
+ diffComplete: !(beforeRef?.isBinary || afterRef?.isBinary),
136
+ };
137
+ }
138
+ /** Upload bytes under their content-address, skipping the write when present. */
139
+ async function storeBlob(storage, executionId, bytes) {
140
+ const sha256 = sha256Bytes(bytes);
141
+ const storageKey = casBlobKey(executionId, sha256);
142
+ // Content-addressed: identical bytes yield the same key, so an existing blob
143
+ // is never re-uploaded (idempotent under Temporal retries + intra-turn dedup).
144
+ if (!(await storage.exists(storageKey))) {
145
+ await storage.upload(storageKey, bytes, "application/octet-stream");
146
+ }
147
+ return { sha256, storageKey, sizeBytes: bytes.length, isBinary: bytesLookBinary(bytes) };
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Resume: load + reconcile
151
+ // ---------------------------------------------------------------------------
152
+ /**
153
+ * Load a change set's CAS manifest for the resume-time reconcile, digest-verified
154
+ * against the ledger's {@link CasSnapshotRef}.
155
+ *
156
+ * Called ONLY when the caller has already determined this turn captured CAS files
157
+ * — from the change set's CANDIDATE snapshot (the ledger's record of the
158
+ * substrate), never by probing storage. The ref is the whole contract: the
159
+ * manifest is fetched from the exact `artifactUri` the CANDIDATE event recorded
160
+ * (not a re-derived key, so a pending change set survives any future key-scheme
161
+ * change), and the downloaded bytes must hash to `manifestDigest` before they are
162
+ * trusted. Per-blob content addresses protect blob BODIES, but only this check
163
+ * protects the path→blob mapping itself — a corrupted or swapped manifest could
164
+ * otherwise direct a valid blob to the wrong path.
165
+ *
166
+ * Fail-closed: a missing manifest (surfaced by the reader) or a digest mismatch
167
+ * is a genuine integrity error, never a "this was a git-only turn" signal.
168
+ * (Deciding the substrate from storage existence was unsafe: a presigned/proxy
169
+ * backend cannot answer "does this key exist?" reliably, and a git-only turn —
170
+ * which writes no manifest — would then attempt a doomed download.)
171
+ */
172
+ export async function loadCasManifest(opts) {
173
+ const { readBlob, ref } = opts;
174
+ const bytes = await readBlob(ref.artifactUri);
175
+ const actual = sha256Bytes(bytes);
176
+ if (actual !== ref.manifestDigest) {
177
+ throw new Error(`CAS manifest integrity check failed for '${ref.artifactUri}': ` +
178
+ `expected ${ref.manifestDigest}, got ${actual}`);
179
+ }
180
+ return JSON.parse(bytes.toString("utf8"));
181
+ }
182
+ /**
183
+ * Ensure the APPROVED files hold their captured "after" bytes on disk. An
184
+ * approved CREATE/MODIFY writes the after blob (integrity-checked against its
185
+ * content address); an approved DELETE removes the file. Idempotent — re-running
186
+ * converges (the after blob is immutable), so a Temporal retry is safe.
187
+ *
188
+ * Enforcement ("what you approve is what applies"): the downloaded bytes must
189
+ * still hash to the blob's content address; a mismatch (storage corruption)
190
+ * throws rather than writing wrong bytes.
191
+ */
192
+ export async function applyCasApproved(opts) {
193
+ const { readBlob, workspaceRoot, files } = opts;
194
+ for (const file of files) {
195
+ if (file.kind === FileChangeKind.DELETE) {
196
+ await rm(join(workspaceRoot, file.pathBefore), { force: true });
197
+ continue;
198
+ }
199
+ // CREATE or MODIFY: write the approved after bytes.
200
+ if (!file.after)
201
+ continue;
202
+ await writeVerifiedBlob(readBlob, join(workspaceRoot, file.pathAfter), file.after);
203
+ }
204
+ }
205
+ /**
206
+ * Snap the REJECTED/undecided files back to their captured "before" bytes: a
207
+ * rejected CREATE is removed; a rejected MODIFY/DELETE is rewritten with its
208
+ * before blob. Idempotent, and the byte-exact inverse of {@link applyCasApproved}.
209
+ */
210
+ export async function restoreCasToBaseline(opts) {
211
+ const { readBlob, workspaceRoot, files } = opts;
212
+ for (const file of files) {
213
+ if (file.kind === FileChangeKind.ADD) {
214
+ // The file did not exist before this turn — remove the agent's creation.
215
+ await rm(join(workspaceRoot, file.pathAfter), { force: true });
216
+ continue;
217
+ }
218
+ // MODIFY or DELETE: the baseline holds the file — restore its exact bytes.
219
+ if (!file.before)
220
+ continue;
221
+ await writeVerifiedBlob(readBlob, join(workspaceRoot, file.pathBefore), file.before);
222
+ }
223
+ }
224
+ /**
225
+ * Adapt the artifact storage port's {@link ArtifactStorage.download} into a
226
+ * {@link BlobReader}. The seam is retained so the reconcile functions
227
+ * ({@link loadCasManifest}, {@link applyCasApproved}, {@link restoreCasToBaseline})
228
+ * depend only on "read one blob by key", not on the whole storage interface.
229
+ * `download` already throws a descriptive, key-scoped error on a missing blob or
230
+ * transport failure, so no extra wrapping is needed here.
231
+ */
232
+ export function casBlobReader(storage) {
233
+ return (storageKey) => storage.download(storageKey);
234
+ }
235
+ // ---------------------------------------------------------------------------
236
+ // Internals
237
+ // ---------------------------------------------------------------------------
238
+ /** Download a blob, verify its content address, and write it to `abs`. */
239
+ async function writeVerifiedBlob(readBlob, abs, ref) {
240
+ const bytes = await readBlob(ref.storageKey);
241
+ const actual = sha256Bytes(bytes);
242
+ if (actual !== ref.sha256) {
243
+ throw new Error(`CAS blob integrity check failed for '${ref.storageKey}': ` +
244
+ `expected ${ref.sha256}, got ${actual}`);
245
+ }
246
+ await mkdir(dirname(abs), { recursive: true });
247
+ await writeFile(abs, bytes);
248
+ }
249
+ /** Stable order: by after path, then before path (substrate-agnostic, doc 08 D3). */
250
+ function compareByPath(a, b) {
251
+ const ka = a.pathAfter || a.pathBefore;
252
+ const kb = b.pathAfter || b.pathBefore;
253
+ if (ka < kb)
254
+ return -1;
255
+ if (ka > kb)
256
+ return 1;
257
+ return a.pathBefore < b.pathBefore ? -1 : a.pathBefore > b.pathBefore ? 1 : 0;
258
+ }
259
+ /** Serialize a blob ref fully so the persisted manifest round-trips faithfully. */
260
+ function serializeBlob(b) {
261
+ return b
262
+ ? { sha256: b.sha256, storageKey: b.storageKey, sizeBytes: b.sizeBytes, isBinary: b.isBinary }
263
+ : null;
264
+ }
265
+ /**
266
+ * The canonical JSON the manifest is BOTH persisted as and digested over: files
267
+ * in sorted order with a fixed key order, blob refs serialized in full (incl.
268
+ * `storageKey`) so a reloaded manifest is a faithful {@link CasManifest} the
269
+ * resume reconcile can read directly. Every field is deterministic, so the digest
270
+ * is a stable integrity check over the exact stored bytes.
271
+ */
272
+ function canonicalManifestJson(manifest) {
273
+ const files = manifest.files.map((f) => ({
274
+ pathBefore: f.pathBefore,
275
+ pathAfter: f.pathAfter,
276
+ kind: f.kind,
277
+ captureClass: f.captureClass,
278
+ before: serializeBlob(f.before),
279
+ after: serializeBlob(f.after),
280
+ diffComplete: f.diffComplete,
281
+ }));
282
+ return JSON.stringify({ changeSetId: manifest.changeSetId, files });
283
+ }
284
+ //# sourceMappingURL=cas-substrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cas-substrate.js","sourceRoot":"","sources":["../../../src/shared/filereview/cas-substrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Canonical file-review digests — the runner-side mirror of the Go
3
+ * {@code filereview/digest.go} and the Java {@code FileDigest}, locked
4
+ * byte-for-byte by `apis/testdata/hitl/file-digest/vectors.json`.
5
+ *
6
+ * These are ENFORCEMENT digests, never correlation keys: the reconcile refuses
7
+ * to apply content whose digest differs from what the user approved. The runner
8
+ * is the sole producer of `before_sha256`/`after_sha256` (over the exact captured
9
+ * bytes) and of the derived `file_digest`/`aggregate_digest`; the backends only
10
+ * carry them. Keeping the formula identical across all three editions is what
11
+ * lets the cross-edition corpus prove parity.
12
+ */
13
+ import { FileChangeKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
14
+ /** The proto enum value name for a FileChangeKind (for the digest canonical form). */
15
+ export declare function fileChangeKindName(kind: FileChangeKind): string;
16
+ /** Lowercase-hex SHA-256 of a UTF-8 string. */
17
+ export declare function sha256Hex(s: string): string;
18
+ /** Lowercase-hex SHA-256 of raw bytes — used for `before_sha256`/`after_sha256`. */
19
+ export declare function sha256Bytes(bytes: Uint8Array): string;
20
+ /** The identity+content fields a {@link fileDigest} is computed over. */
21
+ export interface FileDigestInput {
22
+ readonly pathBefore: string;
23
+ readonly pathAfter: string;
24
+ readonly kind: FileChangeKind;
25
+ readonly beforeSha256: string;
26
+ readonly afterSha256: string;
27
+ }
28
+ /**
29
+ * The canonical per-file digest:
30
+ * `sha256(join("\n", [path_before, path_after, kind_name, before_sha256, after_sha256]))`.
31
+ * Digesting the content HASHES (not raw bytes) keeps the string pure ASCII, free
32
+ * of any line-ending or encoding ambiguity across editions.
33
+ */
34
+ export declare function fileDigest(input: FileDigestInput): string;
35
+ /**
36
+ * The canonical change-set digest: `sha256(join("\n", sort_ascending(file_digests)))`.
37
+ * Sorting makes it independent of file order (a change set is an unordered set of
38
+ * files for identity). The empty set hashes the empty string.
39
+ */
40
+ export declare function aggregateDigest(inputs: readonly FileDigestInput[]): string;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Canonical file-review digests — the runner-side mirror of the Go
3
+ * {@code filereview/digest.go} and the Java {@code FileDigest}, locked
4
+ * byte-for-byte by `apis/testdata/hitl/file-digest/vectors.json`.
5
+ *
6
+ * These are ENFORCEMENT digests, never correlation keys: the reconcile refuses
7
+ * to apply content whose digest differs from what the user approved. The runner
8
+ * is the sole producer of `before_sha256`/`after_sha256` (over the exact captured
9
+ * bytes) and of the derived `file_digest`/`aggregate_digest`; the backends only
10
+ * carry them. Keeping the formula identical across all three editions is what
11
+ * lets the cross-edition corpus prove parity.
12
+ */
13
+ import { createHash } from "node:crypto";
14
+ import { FileChangeKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
15
+ /**
16
+ * The proto enum value NAME for a {@link FileChangeKind}, e.g.
17
+ * `FILE_CHANGE_KIND_MODIFY`. The digest is computed over this name (matching Go's
18
+ * `kind.String()` and Java's `kind.name()`), NOT the TS member name, so all three
19
+ * editions hash an identical string. The cross-edition digest corpus validates
20
+ * this map; a missing or wrong entry fails the parity test.
21
+ */
22
+ const FILE_CHANGE_KIND_NAME = {
23
+ [FileChangeKind.UNSPECIFIED]: "FILE_CHANGE_KIND_UNSPECIFIED",
24
+ [FileChangeKind.ADD]: "FILE_CHANGE_KIND_ADD",
25
+ [FileChangeKind.MODIFY]: "FILE_CHANGE_KIND_MODIFY",
26
+ [FileChangeKind.DELETE]: "FILE_CHANGE_KIND_DELETE",
27
+ [FileChangeKind.RENAME]: "FILE_CHANGE_KIND_RENAME",
28
+ [FileChangeKind.BINARY_CHANGE]: "FILE_CHANGE_KIND_BINARY_CHANGE",
29
+ };
30
+ /** The proto enum value name for a FileChangeKind (for the digest canonical form). */
31
+ export function fileChangeKindName(kind) {
32
+ return FILE_CHANGE_KIND_NAME[kind] ?? "FILE_CHANGE_KIND_UNSPECIFIED";
33
+ }
34
+ /** Lowercase-hex SHA-256 of a UTF-8 string. */
35
+ export function sha256Hex(s) {
36
+ return createHash("sha256").update(s, "utf8").digest("hex");
37
+ }
38
+ /** Lowercase-hex SHA-256 of raw bytes — used for `before_sha256`/`after_sha256`. */
39
+ export function sha256Bytes(bytes) {
40
+ return createHash("sha256").update(bytes).digest("hex");
41
+ }
42
+ /**
43
+ * The canonical per-file digest:
44
+ * `sha256(join("\n", [path_before, path_after, kind_name, before_sha256, after_sha256]))`.
45
+ * Digesting the content HASHES (not raw bytes) keeps the string pure ASCII, free
46
+ * of any line-ending or encoding ambiguity across editions.
47
+ */
48
+ export function fileDigest(input) {
49
+ return sha256Hex([
50
+ input.pathBefore,
51
+ input.pathAfter,
52
+ fileChangeKindName(input.kind),
53
+ input.beforeSha256,
54
+ input.afterSha256,
55
+ ].join("\n"));
56
+ }
57
+ /**
58
+ * The canonical change-set digest: `sha256(join("\n", sort_ascending(file_digests)))`.
59
+ * Sorting makes it independent of file order (a change set is an unordered set of
60
+ * files for identity). The empty set hashes the empty string.
61
+ */
62
+ export function aggregateDigest(inputs) {
63
+ const digests = inputs.map(fileDigest).sort();
64
+ return sha256Hex(digests.join("\n"));
65
+ }
66
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../../../src/shared/filereview/digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,8DAA8D,CAAC;AAE9F;;;;;;GAMG;AACH,MAAM,qBAAqB,GAA6C;IACtE,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,8BAA8B;IAC5D,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,sBAAsB;IAC5C,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,yBAAyB;IAClD,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,yBAAyB;IAClD,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,yBAAyB;IAClD,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,gCAAgC;CACjE,CAAC;AAEF,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CAAC,IAAoB;IACrD,OAAO,qBAAqB,CAAC,IAAI,CAAC,IAAI,8BAA8B,CAAC;AACvE,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAWD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,OAAO,SAAS,CACd;QACE,KAAK,CAAC,UAAU;QAChB,KAAK,CAAC,SAAS;QACf,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC;QAC9B,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,WAAW;KAClB,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAkC;IAChE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACvC,CAAC"}