@iowarp/clio-coder 0.4.2 → 0.4.4

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 (523) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/CONTRIBUTING.md +86 -19
  3. package/README.md +35 -6
  4. package/dist/{acp-TMDQZDIG.js → acp-WNAYYF4F.js} +12 -13
  5. package/dist/{agents-5N5NG3XG.js → agents-3OKXHLOI.js} +60 -57
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-Z5CCBXKQ.js → auth-VKNNMGPU.js} +21 -19
  8. package/dist/{builtins-K6TNDT24.js → builtins-WGALA46I.js} +9 -4
  9. package/dist/{chunk-XE3PCIXH.js → chunk-23L32XTI.js} +12 -9
  10. package/dist/{chunk-I64IFBLB.js → chunk-25QBEXRS.js} +18 -11
  11. package/dist/{chunk-CDNVLKUX.js → chunk-26QSH3EJ.js} +13 -7
  12. package/dist/{chunk-QQLGQY2A.js → chunk-2ASED4PZ.js} +22 -22
  13. package/dist/{chunk-MCEPRMZW.js → chunk-2CU2H6KE.js} +2 -2
  14. package/dist/chunk-2DSOYNFC.js +108 -0
  15. package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
  16. package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
  17. package/dist/{chunk-O3YUNJZ2.js → chunk-2ZSONWVL.js} +82 -25
  18. package/dist/{chunk-2NHR3NAY.js → chunk-36CT5VVL.js} +331 -42
  19. package/dist/{chunk-2X4RYJTJ.js → chunk-3GY4F45V.js} +3 -3
  20. package/dist/{chunk-ZW55JB7N.js → chunk-3ODX73FK.js} +4 -6
  21. package/dist/{chunk-PBP4B7XR.js → chunk-3UNOLWNZ.js} +3 -3
  22. package/dist/{chunk-4JDLP6ZS.js → chunk-3UUXNFEX.js} +14 -10
  23. package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
  24. package/dist/{chunk-ZW4HH5JJ.js → chunk-4M6Z5QVF.js} +6 -6
  25. package/dist/{chunk-K6BSR66V.js → chunk-4NSRCOYP.js} +4 -1
  26. package/dist/{chunk-M2DAX4F6.js → chunk-4WR7VSYB.js} +2 -2
  27. package/dist/{chunk-FSP7CMNU.js → chunk-54X7T7DK.js} +61 -6
  28. package/dist/{chunk-54ODD65L.js → chunk-5636DCO5.js} +4 -4
  29. package/dist/chunk-57XXR6DR.js +3763 -0
  30. package/dist/{chunk-3KIPBMUA.js → chunk-5ICU3EUH.js} +2 -2
  31. package/dist/{chunk-77QIVUZB.js → chunk-5MEZN6CB.js} +4 -4
  32. package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
  33. package/dist/{chunk-YJISEZKC.js → chunk-5TUB6SLS.js} +6 -6
  34. package/dist/{chunk-IMXMHHMQ.js → chunk-6OSVSQL5.js} +341 -57
  35. package/dist/{chunk-Q4XWMHX6.js → chunk-6PAZTBPA.js} +14 -2
  36. package/dist/{chunk-FVDGR2ZL.js → chunk-6Q3CYFD3.js} +112 -39
  37. package/dist/{chunk-IDNA72AH.js → chunk-6QOTUPRG.js} +155 -36
  38. package/dist/{chunk-X7IARSHT.js → chunk-6UINWWS6.js} +16 -10
  39. package/dist/{chunk-CYZW7JHJ.js → chunk-72YIHOZQ.js} +9 -9
  40. package/dist/{chunk-IKSLQ4XV.js → chunk-75W7L2E2.js} +752 -861
  41. package/dist/{chunk-CRFOIAX3.js → chunk-7UGL4MB5.js} +6 -6
  42. package/dist/{chunk-HIICAHCJ.js → chunk-AUPNRN7C.js} +2 -2
  43. package/dist/{chunk-7BHIY2MW.js → chunk-BJVFZO5U.js} +8 -50
  44. package/dist/{chunk-B74PXLU7.js → chunk-CUSRQKPU.js} +65 -3
  45. package/dist/chunk-DQOVN6KV.js +386 -0
  46. package/dist/{chunk-E7GT7O5N.js → chunk-DT3LWJOB.js} +7 -4
  47. package/dist/chunk-DXKJURES.js +671 -0
  48. package/dist/{chunk-JBCS7CRR.js → chunk-EL24TAU4.js} +10 -10
  49. package/dist/{chunk-TPEQIQIE.js → chunk-ELWDPP3Y.js} +8 -8
  50. package/dist/{chunk-NDINPTJ4.js → chunk-ELZVTCGV.js} +5 -4
  51. package/dist/chunk-EXLD33WO.js +381 -0
  52. package/dist/chunk-FEAXX7B6.js +101 -0
  53. package/dist/{chunk-RLYRBIYQ.js → chunk-FFUPXJC4.js} +90 -331
  54. package/dist/{chunk-5PFYMY2V.js → chunk-FTMGRKEF.js} +2 -2
  55. package/dist/{chunk-34BHNEE3.js → chunk-GHS5EBTQ.js} +58 -7
  56. package/dist/{chunk-DYHAXKHD.js → chunk-GWZNEVM2.js} +12 -8
  57. package/dist/chunk-GX5WYQO4.js +59 -0
  58. package/dist/chunk-GYV6VZOC.js +26 -0
  59. package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
  60. package/dist/chunk-I2DWJ4GM.js +390 -0
  61. package/dist/{chunk-TXOTCRLG.js → chunk-I5FWO7L5.js} +5 -5
  62. package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
  63. package/dist/{chunk-XQRY4DTA.js → chunk-IGLP3ODT.js} +10 -10
  64. package/dist/chunk-IRXAATOX.js +539 -0
  65. package/dist/chunk-IXIY2H4R.js +44 -0
  66. package/dist/{chunk-SSEYRH53.js → chunk-IZXGRF7P.js} +92 -147
  67. package/dist/{chunk-5TSRNF4G.js → chunk-JCI2ROMZ.js} +164 -6
  68. package/dist/{chunk-JWJGP5DQ.js → chunk-JEIYHLOR.js} +7 -7
  69. package/dist/{chunk-F2I26BDK.js → chunk-JQLNNIKT.js} +4 -4
  70. package/dist/{chunk-BYMNWQ7O.js → chunk-JSD46VO2.js} +315 -63
  71. package/dist/{chunk-AK5XEFVZ.js → chunk-JT2RFCC5.js} +64 -14
  72. package/dist/{chunk-MCMZMDAC.js → chunk-K6T2ZAMZ.js} +168 -6
  73. package/dist/{chunk-PGF63K6I.js → chunk-KFV5L5SK.js} +73 -4
  74. package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
  75. package/dist/{chunk-PJX3WQUQ.js → chunk-LLXSDWXS.js} +3 -3
  76. package/dist/{chunk-DZAW46HP.js → chunk-LTIKRKFL.js} +3 -3
  77. package/dist/{chunk-DZEK6CJN.js → chunk-N56KALIC.js} +21 -21
  78. package/dist/{chunk-B7HM5Z7T.js → chunk-NAI6ZFCY.js} +9 -5
  79. package/dist/{chunk-I66ZTYNP.js → chunk-NRO2BJRH.js} +2656 -2213
  80. package/dist/{chunk-ZGNYYXQ6.js → chunk-NXIMQY5W.js} +3 -3
  81. package/dist/{chunk-IKOZFYBN.js → chunk-NXYCB2VD.js} +149 -106
  82. package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
  83. package/dist/{chunk-462T4EGZ.js → chunk-O5CVSAG5.js} +2 -2
  84. package/dist/chunk-ODGTEFFI.js +50 -0
  85. package/dist/{chunk-3F7VUY77.js → chunk-OEJSLEPW.js} +2 -2
  86. package/dist/{chunk-KKOJXO6R.js → chunk-OMQNJVKW.js} +4 -2
  87. package/dist/{chunk-5KW52TEP.js → chunk-Q4WO54TA.js} +132 -77
  88. package/dist/{chunk-W6NIE6OW.js → chunk-QUFRYSWI.js} +13 -7
  89. package/dist/{chunk-42FMPA75.js → chunk-QZWQA4DE.js} +2 -2
  90. package/dist/chunk-R6Q67RJH.js +134 -0
  91. package/dist/{chunk-W4YEMFBX.js → chunk-RAY4OVGZ.js} +3 -3
  92. package/dist/{chunk-ZNT2M6TG.js → chunk-RQCKCSRL.js} +17 -17
  93. package/dist/{chunk-LJID3DYZ.js → chunk-RXTN6AKH.js} +3 -3
  94. package/dist/{chunk-P75RZCJW.js → chunk-RZDWV63N.js} +3 -3
  95. package/dist/{chunk-UH632ZYL.js → chunk-S6PYF2XF.js} +2 -2
  96. package/dist/{chunk-HJWWJ6IL.js → chunk-TOIVGRUX.js} +17 -5
  97. package/dist/{chunk-HLAFFSEK.js → chunk-TQAHXW6Y.js} +2 -2
  98. package/dist/{chunk-JIEGK6UF.js → chunk-U6TMQNSI.js} +48 -4
  99. package/dist/{chunk-2HFQNRV3.js → chunk-UEPWCCTY.js} +12 -12
  100. package/dist/chunk-UOIZ7DA4.js +41 -0
  101. package/dist/{chunk-UH347SHR.js → chunk-USR47QNF.js} +11 -11
  102. package/dist/{chunk-AZ4WMN4W.js → chunk-V6HJFQZE.js} +2 -2
  103. package/dist/chunk-V76WTFTW.js +318 -0
  104. package/dist/{chunk-NMJXSHBJ.js → chunk-W54I7H25.js} +2 -2
  105. package/dist/{chunk-KPXDY6QF.js → chunk-XRZT5WY5.js} +2 -2
  106. package/dist/{chunk-UBRFI4HS.js → chunk-XULDXHTN.js} +142 -50
  107. package/dist/chunk-XXYSBZIQ.js +283 -0
  108. package/dist/{chunk-HKMD33FO.js → chunk-Y55JBDO5.js} +405 -122
  109. package/dist/{chunk-XOXV5GKE.js → chunk-YD5GIKET.js} +17 -8
  110. package/dist/{chunk-XGDPUNND.js → chunk-YECAMM3D.js} +2 -2
  111. package/dist/{chunk-BO7Y52RY.js → chunk-YNFKXPEC.js} +7 -7
  112. package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
  113. package/dist/{chunk-M2WXEHER.js → chunk-ZA4VCIGV.js} +2 -2
  114. package/dist/cli/index.js +42 -40
  115. package/dist/{clio-7VB377CC.js → clio-QLICPCF5.js} +7 -7
  116. package/dist/{code-nav-YVLCYA7V.js → code-nav-IJR2DBPR.js} +9 -9
  117. package/dist/{components-UBWCQSRW.js → components-2TGAI2RC.js} +5 -6
  118. package/dist/{config-4HVOS65E.js → config-IUA6OYNS.js} +88 -81
  119. package/dist/{configure-PIWO7B24.js → configure-VEPX4NMX.js} +26 -25
  120. package/dist/{context-KQYIWPWT.js → context-2DKHWH2T.js} +60 -45
  121. package/dist/{context-IYEHL3WQ.js → context-4MPR7WKB.js} +78 -69
  122. package/dist/{context-N6ZE3LGJ.js → context-BOYF5EJM.js} +15 -11
  123. package/dist/{context-clear-G4OGZJDS.js → context-clear-S4ZJCQUX.js} +73 -65
  124. package/dist/context-map-COB37XXN.js +505 -0
  125. package/dist/{context-working-set-BWLF6LJP.js → context-working-set-3I3FYX6Y.js} +18 -17
  126. package/dist/detail-A7JAVSIG.js +98 -0
  127. package/dist/{dispatch-runner-2QQAITS3.js → dispatch-runner-RJ5I2F2O.js} +99 -75
  128. package/dist/{docs-PD3EXDKU.js → docs-SPOV3BAN.js} +3 -5
  129. package/dist/{doctor-LHBD36VU.js → doctor-DKICC2SN.js} +71 -48
  130. package/dist/{eval-C45FYRJ6.js → eval-OQOQUDHK.js} +308 -146
  131. package/dist/{eval-inventory-6DEJPLBF.js → eval-inventory-Y6QRFOH5.js} +4 -4
  132. package/dist/{evidence-6SHONYAF.js → evidence-4DQ25GUQ.js} +79 -175
  133. package/dist/evidence-4F5USFKH.js +208 -0
  134. package/dist/{evolve-KRKMV72X.js → evolve-GSS52E5J.js} +71 -67
  135. package/dist/{extensions-KPZ2UHBB.js → extensions-G7MFLYHT.js} +8 -9
  136. package/dist/{fleet-IVTCKDHT.js → fleet-Q37YHHAQ.js} +126 -118
  137. package/dist/{fleet-commands-EDWL3IT7.js → fleet-commands-G7E4N7SM.js} +16 -13
  138. package/dist/{fleet-decisions-YP3YEFGK.js → fleet-decisions-O7M6QBA2.js} +9 -8
  139. package/dist/{fleet-graph-ZFWKHY2M.js → fleet-graph-TOUBW6OW.js} +21 -20
  140. package/dist/{fleet-inspect-FVUNCBML.js → fleet-inspect-SW33JJNI.js} +65 -60
  141. package/dist/{fleet-preflight-UN5XED4R.js → fleet-preflight-CV2655TW.js} +4 -5
  142. package/dist/{fleet-validate-XOWC4HSX.js → fleet-validate-KESZX2YH.js} +25 -24
  143. package/dist/{fleet-verify-UN3SODEL.js → fleet-verify-UQPMTVE3.js} +66 -61
  144. package/dist/{fleet-view-TWHJKCN6.js → fleet-view-MN2VG4MR.js} +65 -60
  145. package/dist/{init-T2QORQ3Y.js → init-PXEXQSBF.js} +90 -82
  146. package/dist/{interop-IN5I2A66.js → interop-ZG5T62U3.js} +12 -13
  147. package/dist/inventory-C26CFDRR.js +101 -0
  148. package/dist/{library-LSCATDLZ.js → library-B2W4N74O.js} +29 -29
  149. package/dist/{memory-HYOKAGGJ.js → memory-YCANYS5A.js} +73 -69
  150. package/dist/{models-2GPMFYCM.js → models-GERTU3YI.js} +51 -47
  151. package/dist/{monitor-E4ASVUJH.js → monitor-CPNIUULB.js} +74 -67
  152. package/dist/{orchestrator-DDMPR3PY.js → orchestrator-J4BSH4WQ.js} +1288 -1606
  153. package/dist/{panes-E3RUXOW5.js → panes-BOHAEGYC.js} +4 -4
  154. package/dist/{panes-IXKLOKA2.js → panes-NXSLDQZ2.js} +10 -11
  155. package/dist/{paths-L7LGY6RN.js → paths-VSUWNC22.js} +6 -7
  156. package/dist/reset-TNWTB5LU.js +343 -0
  157. package/dist/{resources-OTRSN34L.js → resources-4PXNMD5G.js} +29 -22
  158. package/dist/{run-5DEYH5QK.js → run-D6XJ34CN.js} +132 -132
  159. package/dist/{share-IHWTLO3M.js → share-2NWMJJEE.js} +27 -27
  160. package/dist/{skills-IYMXMKW4.js → skills-KR7WON5G.js} +40 -33
  161. package/dist/{skills-eval-DROHSJAR.js → skills-eval-O2ZNOLDS.js} +81 -77
  162. package/dist/{skills-inventory-D7X4L4ZX.js → skills-inventory-ZZOUBK7O.js} +23 -22
  163. package/dist/{slash-commands-QBM7UZ3B.js → slash-commands-ZXPJD64J.js} +47 -37
  164. package/dist/{steer-Z5DO23FJ.js → steer-XA25PSCS.js} +4 -4
  165. package/dist/{support-U7QOWY26.js → support-7EMVWYG2.js} +6 -6
  166. package/dist/{targets-P2FUC4IL.js → targets-OMH2XCSN.js} +50 -49
  167. package/dist/tasks-IPAGMEIX.js +36 -0
  168. package/dist/{terminal-lease-YREJ3JX2.js → terminal-lease-C2J3JYRE.js} +4 -4
  169. package/dist/{tools-5B7RO6MV.js → tools-EFFEAIDP.js} +8 -9
  170. package/dist/{trace-YMGMUM6A.js → trace-FXMXUZUF.js} +7 -7
  171. package/dist/uninstall-HALS6BLF.js +407 -0
  172. package/dist/upgrade-MS72RJEP.js +306 -0
  173. package/dist/{usage-ME5MPXGX.js → usage-NHG6MCJM.js} +162 -108
  174. package/dist/{verifiers-BVZ7IWOO.js → verifiers-7AUNVXDY.js} +155 -22
  175. package/dist/{verify-5K7ZKQFC.js → verify-FWYGPKMR.js} +14 -12
  176. package/dist/{web-fetch-MPARV2K7.js → web-fetch-V4FKSDAV.js} +4 -4
  177. package/dist/{wiki-generate-F5W5QTYY.js → wiki-generate-743CIGJW.js} +99 -90
  178. package/dist/{with-panes-BYOJCLAM.js → with-panes-BDQEWBRT.js} +10 -10
  179. package/dist/worker/entry.js +72 -68
  180. package/docs/README.md +3 -2
  181. package/docs/architecture/acp.md +17 -0
  182. package/docs/architecture/artifact-placement.md +1 -0
  183. package/docs/architecture/artifact-versions.md +2 -2
  184. package/docs/architecture/context-engine.md +4 -0
  185. package/docs/architecture/dispatch-typed-intent.md +1 -1
  186. package/docs/architecture/evidence-and-memory.md +1 -1
  187. package/docs/architecture/middleware-and-components.md +1 -1
  188. package/docs/architecture/model-catalog.md +21 -10
  189. package/docs/architecture/observability.md +19 -2
  190. package/docs/architecture/prompt-envelope-and-tools.md +17 -5
  191. package/docs/architecture/provider-adapter-cookbook.md +63 -0
  192. package/docs/architecture/safety-model.md +25 -22
  193. package/docs/architecture/tui-design.md +1 -1
  194. package/docs/guide/built-in-agents.md +25 -11
  195. package/docs/guide/commands-and-modes.md +18 -3
  196. package/docs/guide/configuration-and-targets.md +100 -10
  197. package/docs/guide/configuration-reference.md +17 -7
  198. package/docs/guide/environment-variables.md +4 -2
  199. package/docs/guide/installation-and-lifecycle.md +37 -4
  200. package/docs/guide/proactive-memory.md +66 -55
  201. package/docs/guide/skills-marketplace.md +18 -0
  202. package/docs/guide/tool-usage.md +78 -3
  203. package/docs/history/config-knobs-audit.md +2 -2
  204. package/docs/process/development-pipeline.md +40 -2
  205. package/docs/process/eval-runner.md +67 -3
  206. package/docs/process/git-commit-provenance.md +15 -0
  207. package/docs/process/release-cut-checklist.md +207 -0
  208. package/docs/process/scientific-validation.md +18 -17
  209. package/evals/behavioral-machinery-support.ts +1 -0
  210. package/evals/behavioral-machinery.yaml +1 -1
  211. package/evals/behavioral-model.yaml +3 -2
  212. package/package.json +2 -2
  213. package/skills/README.md +7 -5
  214. package/skills/coding/ast-grep/SKILL.md +101 -30
  215. package/skills/coding/ast-grep/evals.md +26 -0
  216. package/skills/coding/coding-standards/SKILL.md +47 -2
  217. package/skills/coding/coding-standards/evals.md +23 -0
  218. package/skills/coding/prototype/SKILL.md +87 -28
  219. package/skills/coding/prototype/evals.md +19 -0
  220. package/skills/coding/tdd/SKILL.md +80 -53
  221. package/skills/coding/tdd/evals.md +20 -0
  222. package/skills/context/context-handoff/SKILL.md +43 -2
  223. package/skills/context/context-handoff/evals.md +44 -0
  224. package/skills/context/context-prime/SKILL.md +45 -15
  225. package/skills/context/context-prime/evals.md +45 -0
  226. package/skills/git/branch-closeout/SKILL.md +132 -0
  227. package/skills/git/branch-closeout/evals.md +133 -0
  228. package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
  229. package/skills/git/file-ticket/SKILL.md +77 -63
  230. package/skills/git/file-ticket/assets/issue-template.md +22 -0
  231. package/skills/git/file-ticket/evals.md +31 -26
  232. package/skills/git/file-ticket/references/issue-discovery.md +49 -0
  233. package/skills/git/fix-issue/SKILL.md +87 -64
  234. package/skills/git/fix-issue/evals.md +35 -31
  235. package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
  236. package/skills/git/resolve-merge-conflicts/SKILL.md +100 -51
  237. package/skills/git/resolve-merge-conflicts/evals.md +52 -25
  238. package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
  239. package/skills/git/ship/SKILL.md +103 -67
  240. package/skills/git/ship/assets/pr-template.md +21 -0
  241. package/skills/git/ship/evals.md +44 -28
  242. package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
  243. package/skills/git/worktree-create/SKILL.md +80 -50
  244. package/skills/git/worktree-create/evals.md +40 -33
  245. package/skills/git/worktree-create/references/worktree-setup.md +62 -66
  246. package/skills/git/worktree-merge/SKILL.md +112 -65
  247. package/skills/git/worktree-merge/evals.md +42 -34
  248. package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
  249. package/skills/planning/archify/SKILL.md +196 -0
  250. package/skills/planning/archify/evals.md +65 -0
  251. package/skills/planning/architecture/SKILL.md +61 -12
  252. package/skills/planning/architecture/evals.md +65 -0
  253. package/skills/planning/backlog/SKILL.md +130 -14
  254. package/skills/planning/backlog/evals.md +142 -0
  255. package/skills/planning/prd/SKILL.md +47 -6
  256. package/skills/planning/prd/evals.md +54 -0
  257. package/skills/planning/product-intent/SKILL.md +57 -2
  258. package/skills/planning/product-intent/evals.md +70 -0
  259. package/skills/planning/tech-spec/SKILL.md +53 -2
  260. package/skills/planning/tech-spec/evals.md +73 -0
  261. package/skills/registry.yaml +58 -50
  262. package/skills/remote.yaml +13 -0
  263. package/skills/research/arxiv-literature/SKILL.md +76 -18
  264. package/skills/research/arxiv-literature/evals.md +50 -0
  265. package/skills/research/experiment-protocol/SKILL.md +20 -1
  266. package/skills/research/experiment-protocol/evals.md +23 -0
  267. package/skills/research/scientific-debugging/SKILL.md +24 -1
  268. package/skills/research/scientific-debugging/evals.md +18 -0
  269. package/skills/research/scientific-modernization/SKILL.md +26 -1
  270. package/skills/research/scientific-modernization/evals.md +27 -0
  271. package/skills/skill-marketplace.json +63 -28
  272. package/skills/workflow/cut-it/SKILL.md +64 -5
  273. package/skills/workflow/cut-it/evals.md +101 -0
  274. package/skills/workflow/design-council/SKILL.md +112 -27
  275. package/skills/workflow/design-council/evals.md +161 -0
  276. package/skills/workflow/grill-me/SKILL.md +85 -10
  277. package/skills/workflow/grill-me/evals.md +153 -0
  278. package/skills/workflow/workflow-distiller/SKILL.md +76 -17
  279. package/skills/workflow/workflow-distiller/evals.md +118 -0
  280. package/src/cli/args.ts +0 -8
  281. package/src/cli/configure-interop.ts +105 -13
  282. package/src/cli/configure-oauth.ts +57 -0
  283. package/src/cli/configure-onboarding.ts +980 -0
  284. package/src/cli/configure-target.ts +594 -0
  285. package/src/cli/configure.ts +1084 -529
  286. package/src/cli/context-map.ts +114 -0
  287. package/src/cli/context.ts +4 -0
  288. package/src/cli/doctor-state-size.ts +1 -12
  289. package/src/cli/doctor-validation-contract.ts +28 -0
  290. package/src/cli/doctor.ts +5 -0
  291. package/src/cli/evidence-detail.ts +1 -75
  292. package/src/cli/evidence-inventory.ts +1 -167
  293. package/src/cli/index.ts +3 -0
  294. package/src/cli/lifecycle-presenter.ts +436 -0
  295. package/src/cli/models.ts +10 -2
  296. package/src/cli/modes/print.ts +5 -1
  297. package/src/cli/reset.ts +228 -106
  298. package/src/cli/run.ts +7 -4
  299. package/src/cli/select.ts +664 -0
  300. package/src/cli/skills.ts +9 -2
  301. package/src/cli/targets.ts +3 -0
  302. package/src/cli/tasks.ts +84 -0
  303. package/src/cli/uninstall.ts +233 -165
  304. package/src/cli/upgrade.ts +210 -150
  305. package/src/cli/usage.ts +92 -27
  306. package/src/cli/validate-model.ts +3 -3
  307. package/src/cli/verifiers.ts +147 -1
  308. package/src/cli/wiki-generate.ts +1 -0
  309. package/src/core/commit-attribution.ts +41 -1
  310. package/src/core/config.ts +56 -0
  311. package/src/core/external-diagnostic.ts +44 -0
  312. package/src/core/gateway-routing.ts +157 -0
  313. package/src/core/git-commit-attribution.ts +46 -3
  314. package/src/core/run-overrides.ts +0 -5
  315. package/src/core/safe-exec.ts +17 -2
  316. package/src/core/skill-activation.ts +92 -2
  317. package/src/core/tool-names.ts +5 -2
  318. package/src/domains/agents/builtins/architect.md +1 -1
  319. package/src/domains/agents/builtins/coder.md +1 -1
  320. package/src/domains/agents/builtins/documenter.md +1 -1
  321. package/src/domains/agents/builtins/git-master.md +1 -1
  322. package/src/domains/agents/builtins/provenance.md +7 -7
  323. package/src/domains/agents/builtins/tester.md +1 -1
  324. package/src/domains/agents/builtins/verifier.md +2 -2
  325. package/src/domains/agents/builtins/wiki-writer.md +4 -3
  326. package/src/domains/agents/builtins/world-knowledge.md +31 -0
  327. package/src/domains/agents/catalog.ts +1 -1
  328. package/src/domains/agents/result-contract.ts +70 -0
  329. package/src/domains/context/extension.ts +31 -7
  330. package/src/domains/context/refresh.ts +3 -0
  331. package/src/domains/context/wiki/frontmatter.ts +5 -2
  332. package/src/domains/context/wiki/generate.ts +6 -0
  333. package/src/domains/context/wiki/map-seed.ts +589 -0
  334. package/src/domains/context/wiki/plan.ts +2 -2
  335. package/src/domains/context/wiki/prompts.ts +43 -0
  336. package/src/domains/dispatch/active-route-planner.ts +4 -0
  337. package/src/domains/dispatch/admission.ts +29 -0
  338. package/src/domains/dispatch/agent-candidates.ts +10 -0
  339. package/src/domains/dispatch/budget-envelope.ts +86 -1
  340. package/src/domains/dispatch/capability-match.ts +1 -0
  341. package/src/domains/dispatch/capacity-lease.ts +17 -0
  342. package/src/domains/dispatch/code-step.ts +11 -4
  343. package/src/domains/dispatch/contract.ts +42 -8
  344. package/src/domains/dispatch/execution-scheduler.ts +2 -0
  345. package/src/domains/dispatch/extension.ts +184 -56
  346. package/src/domains/dispatch/fleet-commit-attribution.ts +5 -0
  347. package/src/domains/dispatch/fleet-run.ts +1 -0
  348. package/src/domains/dispatch/host-verification.ts +114 -13
  349. package/src/domains/dispatch/intent.ts +28 -18
  350. package/src/domains/dispatch/orphan-recovery.ts +2 -0
  351. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  352. package/src/domains/dispatch/reservation-store.ts +5 -3
  353. package/src/domains/dispatch/state.ts +15 -2
  354. package/src/domains/dispatch/types.ts +20 -2
  355. package/src/domains/dispatch/worker-model-metadata.ts +38 -0
  356. package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
  357. package/src/domains/eval/metrics/token-stream.ts +201 -31
  358. package/src/domains/eval/metrics/tracked.ts +40 -4
  359. package/src/domains/eval/runners/clio-run.ts +17 -11
  360. package/src/domains/eval/runners/context-index.ts +2 -7
  361. package/src/domains/eval/runners/context-init.ts +3 -6
  362. package/src/domains/eval/runners/external-command.ts +29 -11
  363. package/src/domains/eval/schema/suite.ts +28 -0
  364. package/src/domains/eval/schema/verdict.ts +2 -2
  365. package/src/domains/eval/suites/resolve.ts +13 -1
  366. package/src/domains/eval/suites/run.ts +24 -3
  367. package/src/domains/evidence/build.ts +102 -15
  368. package/src/domains/evidence/detail.ts +69 -0
  369. package/src/domains/evidence/eval.ts +13 -1
  370. package/src/domains/evidence/finish-contract-map.ts +5 -1
  371. package/src/domains/evidence/inventory.ts +167 -0
  372. package/src/domains/evidence/store.ts +16 -0
  373. package/src/domains/evidence/types.ts +12 -0
  374. package/src/domains/extensions/resources.ts +7 -0
  375. package/src/domains/interop/registry.ts +6 -2
  376. package/src/domains/interop/types.ts +4 -0
  377. package/src/domains/lifecycle/migrations/index.ts +4 -0
  378. package/src/domains/memory/task-memory-policy.ts +70 -26
  379. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  380. package/src/domains/middleware/index.ts +0 -1
  381. package/src/domains/middleware/marketplace-offer.ts +22 -35
  382. package/src/domains/middleware/memory-intervention.ts +127 -32
  383. package/src/domains/middleware/memory-step-endpoint.ts +3 -2
  384. package/src/domains/middleware/runtime.ts +7 -3
  385. package/src/domains/middleware/skills-reminder.ts +31 -2
  386. package/src/domains/mux/detect.ts +3 -6
  387. package/src/domains/observability/accountability.ts +15 -1
  388. package/src/domains/observability/compaction-usage.ts +118 -0
  389. package/src/domains/observability/contract.ts +52 -7
  390. package/src/domains/observability/cost.ts +1 -1
  391. package/src/domains/observability/evidence-index.ts +10 -0
  392. package/src/domains/observability/extension.ts +15 -6
  393. package/src/domains/observability/out-of-turn-usage.ts +52 -21
  394. package/src/domains/observability/projection.ts +394 -45
  395. package/src/{interactive → domains/observability}/worker-progress.ts +3 -3
  396. package/src/domains/prompts/fragments/operating/contract.md +2 -0
  397. package/src/domains/prompts/fragments/wiki/page.md +8 -0
  398. package/src/domains/providers/contract.ts +4 -1
  399. package/src/domains/providers/extension.ts +40 -9
  400. package/src/domains/providers/model-capabilities.ts +9 -0
  401. package/src/domains/providers/model-discovery.ts +3 -4
  402. package/src/domains/providers/model-runtime-capabilities.ts +15 -5
  403. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +48 -26
  404. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
  405. package/src/domains/providers/runtimes/claude/claude-code.ts +9 -0
  406. package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
  407. package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
  408. package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
  409. package/src/domains/providers/support.ts +11 -5
  410. package/src/domains/providers/target-model-cache.ts +25 -2
  411. package/src/domains/providers/types/capability-flags.ts +2 -0
  412. package/src/domains/providers/types/runtime-descriptor.ts +20 -1
  413. package/src/domains/providers/types/target-descriptor.ts +19 -0
  414. package/src/domains/resources/index.ts +3 -0
  415. package/src/domains/resources/skills/install.ts +72 -7
  416. package/src/domains/resources/skills/loader.ts +7 -0
  417. package/src/domains/resources/skills/marketplace.ts +63 -11
  418. package/src/domains/safety/action-classifier.ts +7 -0
  419. package/src/domains/safety/autonomy.ts +15 -0
  420. package/src/domains/safety/default-path-policy.ts +2 -0
  421. package/src/domains/safety/finish-contract-registration.ts +29 -14
  422. package/src/domains/safety/finish-contract.ts +252 -40
  423. package/src/domains/safety/index.ts +21 -1
  424. package/src/domains/safety/path-policy.ts +1 -1
  425. package/src/domains/safety/policy-engine.ts +60 -17
  426. package/src/domains/safety/protected-artifacts.ts +191 -88
  427. package/src/domains/safety/rigor.ts +53 -39
  428. package/src/domains/safety/run-effects.ts +2 -22
  429. package/src/domains/safety/skill-authority.ts +55 -0
  430. package/src/domains/safety/validation-contract.ts +388 -0
  431. package/src/domains/session/archive-readers.ts +10 -1
  432. package/src/domains/session/compaction/compact.ts +72 -22
  433. package/src/domains/session/decision-board.ts +101 -2
  434. package/src/domains/session/entries.ts +50 -7
  435. package/src/domains/session/extension.ts +4 -4
  436. package/src/domains/session/handoff.ts +2 -1
  437. package/src/domains/session/manager.ts +2 -3
  438. package/src/domains/session/task-board.ts +14 -1
  439. package/src/domains/session/tree/fork.ts +1 -2
  440. package/src/domains/session/tree/navigator.ts +1 -1
  441. package/src/domains/session/usage.ts +3 -3
  442. package/src/domains/user-tasks/acceptance.ts +56 -0
  443. package/src/domains/user-tasks/active-acceptance.ts +40 -0
  444. package/src/domains/user-tasks/store.ts +34 -3
  445. package/src/engine/acp/adapter.ts +24 -6
  446. package/src/engine/acp/server.ts +21 -4
  447. package/src/engine/acp/transport.ts +53 -8
  448. package/src/engine/acp/types.ts +4 -0
  449. package/src/engine/agent.ts +13 -3
  450. package/src/engine/ai.ts +26 -8
  451. package/src/engine/antigravity/subprocess-runtime.ts +386 -120
  452. package/src/engine/api-registry.ts +3 -0
  453. package/src/engine/apis/ollama-native.ts +15 -0
  454. package/src/engine/apis/openai-completions.ts +117 -14
  455. package/src/engine/claude/subprocess-runtime.ts +107 -60
  456. package/src/engine/external-subprocess.ts +122 -6
  457. package/src/entry/background-model-metadata.ts +18 -0
  458. package/src/entry/compaction-prompt.ts +57 -0
  459. package/src/entry/orchestrator.ts +416 -218
  460. package/src/entry/task-memory-lifecycle.ts +35 -0
  461. package/src/interactive/chat-loop-messages.ts +13 -4
  462. package/src/interactive/chat-loop.ts +65 -2
  463. package/src/interactive/chat-renderer.ts +1 -0
  464. package/src/interactive/cost-overlay.ts +26 -2
  465. package/src/interactive/dispatch-board.ts +46 -717
  466. package/src/interactive/fleet-run-preview.ts +2 -1
  467. package/src/interactive/interactive-application.ts +3 -2
  468. package/src/interactive/interactive-presentation.ts +55 -12
  469. package/src/interactive/interactive-slash-runtime.ts +4 -2
  470. package/src/interactive/oracle.ts +5 -2
  471. package/src/interactive/overlays/fleet-run-approval.ts +3 -2
  472. package/src/interactive/overlays/message-picker.ts +2 -2
  473. package/src/interactive/overlays/settings.ts +2 -2
  474. package/src/interactive/overlays/tree-selector.ts +2 -2
  475. package/src/interactive/renderers/branch-summary.ts +1 -1
  476. package/src/interactive/renderers/worker-entry.ts +32 -0
  477. package/src/interactive/slash-autocomplete.ts +4 -6
  478. package/src/interactive/slash-commands.ts +49 -45
  479. package/src/interactive/slash-spec.ts +28 -0
  480. package/src/interactive/theme/labels.ts +19 -13
  481. package/src/interactive/turn-context.ts +9 -5
  482. package/src/interactive/turn-recovery.ts +8 -0
  483. package/src/interactive/turn-runtime.ts +27 -11
  484. package/src/interactive/turn-state.ts +7 -0
  485. package/src/interactive/view/artifacts.ts +2 -0
  486. package/src/interactive/worker-receipts.ts +1 -0
  487. package/src/interactive/worker-stream.ts +13 -4
  488. package/src/tools/bootstrap.ts +4 -0
  489. package/src/tools/builtin-tool-catalog.ts +31 -0
  490. package/src/tools/compete-worktrees.ts +7 -1
  491. package/src/tools/context/index.ts +30 -9
  492. package/src/tools/core-bootstrap.ts +16 -0
  493. package/src/tools/decide.ts +136 -0
  494. package/src/tools/dispatch-admission.ts +21 -0
  495. package/src/tools/dispatch-arguments.ts +1 -0
  496. package/src/tools/dispatch-event-text.ts +10 -0
  497. package/src/tools/dispatch-plan.ts +6 -2
  498. package/src/tools/dispatch-runner.ts +27 -1
  499. package/src/tools/dispatch-types.ts +6 -0
  500. package/src/tools/evidence.ts +96 -0
  501. package/src/tools/limitation.ts +76 -0
  502. package/src/tools/policy.ts +9 -0
  503. package/src/tools/presentation.ts +3 -0
  504. package/src/tools/registry.ts +11 -5
  505. package/src/tools/result-shaping.ts +17 -5
  506. package/src/tools/task-worktree.ts +13 -3
  507. package/src/tools/tasks.ts +10 -1
  508. package/src/tools/verify/authoring.ts +170 -83
  509. package/src/tools/verify/catalog.ts +122 -5
  510. package/src/tools/verify/index.ts +2 -1
  511. package/src/tools/verify/numeric.ts +298 -0
  512. package/src/tools/verify/perf.ts +143 -0
  513. package/src/tools/verify/scripts.ts +229 -2
  514. package/src/tools/worker-evidence.ts +3 -1
  515. package/src/worker/spec-contract.ts +4 -0
  516. package/dist/chunk-2Z2IKEXI.js +0 -1554
  517. package/dist/chunk-RVG5JXAL.js +0 -41
  518. package/dist/chunk-T56WDKA5.js +0 -183
  519. package/dist/chunk-VN3SHNBN.js +0 -313
  520. package/dist/chunk-VPKWYKEY.js +0 -169
  521. package/dist/reset-OAQP3W4O.js +0 -230
  522. package/dist/uninstall-N34PCTGJ.js +0 -331
  523. package/dist/upgrade-PXK3S2YM.js +0 -325
@@ -16,6 +16,7 @@ import { performance } from "node:perf_hooks";
16
16
  import { BusChannels, type DispatchCompletedPayload, type DispatchRunIdentity } from "../../core/bus-events.js";
17
17
  import { DEFAULT_SETTINGS, type DelegationToolGovernance } from "../../core/defaults.js";
18
18
  import type { DomainBundle, DomainContext, DomainExtension } from "../../core/domain-loader.js";
19
+ import { gatewayRoutingObservationFromRecord } from "../../core/gateway-routing.js";
19
20
  import { GUARDRAIL_DEFAULTS } from "../../core/guardrails.js";
20
21
  import { readClioVersion, readPiMonoVersion } from "../../core/package-root.js";
21
22
  import { canonicalizeExistingPath } from "../../core/path-canonical.js";
@@ -158,6 +159,7 @@ import type {
158
159
  DispatchAdmissionObserver,
159
160
  DispatchContract,
160
161
  DispatchPlanTaskResolution,
162
+ DispatchPreparationOptions,
161
163
  DispatchRequest,
162
164
  DispatchSnapshot,
163
165
  } from "./contract.js";
@@ -297,6 +299,7 @@ import {
297
299
  validateJobSpec,
298
300
  } from "./validation.js";
299
301
  import { describeUngroundedValidations, groundClaimedValidations, invalidatesQuality } from "./validation-grounding.js";
302
+ import { prepareWorkerModelMetadata } from "./worker-model-metadata.js";
300
303
  import {
301
304
  type AgentLedgerBody,
302
305
  computeSettingsFingerprint,
@@ -841,14 +844,19 @@ function renderBoundSkillBlock(recipe: AgentRecipe): string {
841
844
  ].join("\n");
842
845
  }
843
846
 
844
- function workerPersonaBody(
845
- req: DispatchRequest,
846
- recipe: AgentRecipe | null,
847
- allowedTools: ReadonlyArray<ToolName>,
848
- ): string {
847
+ /**
848
+ * Whether Clio's canonical `context` tool is attached to this worker. A
849
+ * subprocess runtime runs its own tool loop and never receives Clio's tool
850
+ * surface, so the recipe's `context` entry does not make the tool available
851
+ * there, and bound skills must not be promised through it.
852
+ */
853
+ function canonicalContextAttached(runtime: Pick<RuntimeDescriptor, "kind">, tools: ReadonlyArray<ToolName>): boolean {
854
+ return runtime.kind !== "subprocess" && tools.includes(ToolNames.Context);
855
+ }
856
+
857
+ function workerPersonaBody(req: DispatchRequest, recipe: AgentRecipe | null, contextAttached: boolean): string {
849
858
  const base = req.systemPrompt && req.systemPrompt.length > 0 ? req.systemPrompt : (recipe?.body ?? "");
850
- const skillBlock =
851
- recipe && req.noSkills !== true && allowedTools.includes(ToolNames.Context) ? renderBoundSkillBlock(recipe) : "";
859
+ const skillBlock = recipe && req.noSkills !== true && contextAttached ? renderBoundSkillBlock(recipe) : "";
852
860
  return [base, skillBlock].filter((part) => part.trim().length > 0).join("\n\n");
853
861
  }
854
862
 
@@ -1347,6 +1355,8 @@ interface DispatchLifecycleStage {
1347
1355
  pipeline: RunPipelineProvenance | null;
1348
1356
  briefing: RunBriefingProvenance | null;
1349
1357
  personaOverride: RunPersonaOverride | null;
1358
+ /** Decision refs sealed on the request by the dispatch tool; null when the parent board was empty. */
1359
+ decisionRefs: ReadonlyArray<string> | null;
1350
1360
  projectContext: RunProjectContextProvenance;
1351
1361
  /** Rule ids the worker prompt compiler selected into this run's system prompt; [] when none matched. */
1352
1362
  rulesApplied: string[];
@@ -1379,6 +1389,8 @@ interface AcpDelegationLifecycleStage {
1379
1389
  pipeline: RunPipelineProvenance | null;
1380
1390
  briefing: RunBriefingProvenance | null;
1381
1391
  personaOverride: RunPersonaOverride | null;
1392
+ /** Decision refs sealed on the request by the dispatch tool; null when the parent board was empty. */
1393
+ decisionRefs: ReadonlyArray<string> | null;
1382
1394
  projectContext: RunProjectContextProvenance;
1383
1395
  /** ACP delegation bypasses the worker prompt compiler entirely, so this is always []. */
1384
1396
  rulesApplied: string[];
@@ -1439,6 +1451,13 @@ function runtimeLimitations(runtimeKind: RunKind, runtimeId: string): string[] {
1439
1451
  "Claude CLI subprocess executes Claude Code tools; Clio constrains permission mode and forbids dangerous bypass unless explicitly gated",
1440
1452
  ];
1441
1453
  }
1454
+ if (runtimeKind === "subprocess" && runtimeId === "antigravity-code") {
1455
+ return [
1456
+ "Antigravity CLI owns its internal tools, network activity, prompts, and approvals; Clio observes only structured stream output and does not provide per-tool mediation or complete tool telemetry",
1457
+ "Antigravity conversation ids are recorded only as opaque provider observations; Clio does not resume them",
1458
+ "Antigravity runs are one-shot and never retried automatically",
1459
+ ];
1460
+ }
1442
1461
  // HTTP/native runtimes run through pi-agent-core, which Clio observes and
1443
1462
  // controls directly, so there are no runtime-imposed dispatch limitations.
1444
1463
  return [];
@@ -1479,13 +1498,6 @@ function assertWriteRootsEnforceable(runtime: RuntimeDescriptor, writeRoots: Rea
1479
1498
  );
1480
1499
  }
1481
1500
 
1482
- function assertWorkerBudgetEnforceable(runtime: RuntimeDescriptor, hasDeclaredBudget: boolean): void {
1483
- if (!hasDeclaredBudget || runtime.kind !== "subprocess") return;
1484
- throw new Error(
1485
- `dispatch: runtime '${runtime.id}' cannot enforce an explicit dispatch budget because subprocess workers do not expose per-tool mediation; choose a native or claude-sdk worker`,
1486
- );
1487
- }
1488
-
1489
1501
  /**
1490
1502
  * API families whose wire protocol carries tool calls. Membership is a property
1491
1503
  * of the protocol, not of any one model: every server speaking one of these can
@@ -1614,13 +1626,38 @@ function workerToolCallHardCap(settings: EffectiveSettings): number {
1614
1626
  return settings?.fleet.limits.toolCallsPerRun ?? GUARDRAIL_DEFAULTS.workerToolCallCap;
1615
1627
  }
1616
1628
 
1629
+ /**
1630
+ * Only a runtime that declares its external agent loop may accept a declared
1631
+ * per-tool budget: Clio records that budget as unobserved rather than enforced.
1632
+ * Any other subprocess runtime cannot mediate tool calls, so a declared budget
1633
+ * would be a claim nobody enforces.
1634
+ */
1635
+ export function assertWorkerBudgetEnforceable(
1636
+ runtime: Pick<RuntimeDescriptor, "id" | "kind" | "externalAgentLoop">,
1637
+ hasDeclaredBudget: boolean,
1638
+ ): void {
1639
+ if (!hasDeclaredBudget || runtime.kind !== "subprocess" || runtime.externalAgentLoop !== undefined) return;
1640
+ throw new Error(
1641
+ `dispatch: runtime '${runtime.id}' cannot enforce an explicit dispatch budget because subprocess workers do not expose per-tool mediation; choose a native or claude-sdk worker`,
1642
+ );
1643
+ }
1644
+
1645
+ /** Per-tool budget enforcement is real only where Clio observes each tool call. */
1646
+ export function budgetEnforcementForRuntime(
1647
+ runtime: Pick<RuntimeDescriptor, "kind">,
1648
+ ): "native-per-tool" | "external-one-shot" {
1649
+ return runtime.kind === "subprocess" ? "external-one-shot" : "native-per-tool";
1650
+ }
1651
+
1617
1652
  function resolveEffectiveWorkerBudget(input: {
1618
1653
  req: DispatchRequest;
1619
1654
  recipeId: string;
1620
1655
  declared: ReturnType<typeof normalizeAgentSpec>["budget"];
1621
1656
  allowedTools: ReadonlyArray<ToolName>;
1622
1657
  settings: EffectiveSettings;
1658
+ runtime: RuntimeDescriptor;
1623
1659
  }): RunToolBudgetEnvelope {
1660
+ assertWorkerBudgetEnforceable(input.runtime, input.declared !== null || input.req.budget !== undefined);
1624
1661
  const hardCap = workerToolCallHardCap(input.settings);
1625
1662
  const declared = input.declared ?? {
1626
1663
  toolCalls: hardCap,
@@ -1635,6 +1672,7 @@ function resolveEffectiveWorkerBudget(input: {
1635
1672
  hasReadTool: input.allowedTools.includes(ToolNames.Read),
1636
1673
  retry: (input.req.lineage?.attempt ?? 0) > 0,
1637
1674
  revision: input.req.gate?.role === "builder" && input.req.gate.cycle > 1 && input.req.gate.verdict === "revise",
1675
+ enforcement: budgetEnforcementForRuntime(input.runtime),
1638
1676
  });
1639
1677
  }
1640
1678
 
@@ -1925,7 +1963,7 @@ function buildDispatchWorkerSpec(input: DispatchWorkerSpecInput, config?: Config
1925
1963
  if (
1926
1964
  input.req.noSkills !== true &&
1927
1965
  recipeSkills.length > 0 &&
1928
- input.admission.allowedTools.includes(ToolNames.Context)
1966
+ canonicalContextAttached(input.target.runtime, input.admission.allowedTools)
1929
1967
  ) {
1930
1968
  spec.agentSkills = [...new Set(recipeSkills)];
1931
1969
  }
@@ -1975,6 +2013,15 @@ function clampWorkerAutonomy(session: AutonomyLevel, requested: AutonomyLevel |
1975
2013
  return AUTONOMY_ORDER[requested] < AUTONOMY_ORDER[session] ? requested : session;
1976
2014
  }
1977
2015
 
2016
+ /** Read-only recipes are an authority boundary, including on opaque external loops. */
2017
+ export function effectiveWorkerAutonomy(
2018
+ session: AutonomyLevel,
2019
+ requested: AutonomyLevel | undefined,
2020
+ capabilityClass: AgentCapabilityClass,
2021
+ ): AutonomyLevel {
2022
+ return clampWorkerAutonomy(session, capabilityClass === "read-only" ? "read-only" : requested);
2023
+ }
2024
+
1978
2025
  function requestedAutonomyEvidence(
1979
2026
  sessionAutonomy: AutonomyLevel,
1980
2027
  requestedAutonomy: AutonomyLevel | undefined,
@@ -2662,6 +2709,7 @@ export function createDispatchBundle(
2662
2709
  nodeId: string,
2663
2710
  timing: RunPhaseMarks,
2664
2711
  endpoint?: EndpointCapacity | null,
2712
+ signal?: AbortSignal,
2665
2713
  ) {
2666
2714
  const queuedAt = now();
2667
2715
  timing.queuedAt = new Date(queuedAt).toISOString();
@@ -2677,7 +2725,12 @@ export function createDispatchBundle(
2677
2725
  : planQueueSlot(req.reservation.ownerId, req.reservation.memberId, (error) =>
2678
2726
  reportDispatchDiagnostic("read plan queue identity", error),
2679
2727
  );
2728
+ const cancel = (): void => {
2729
+ capacityAdmission.cancel(assignmentId);
2730
+ };
2731
+ signal?.addEventListener("abort", cancel, { once: true });
2680
2732
  try {
2733
+ signal?.throwIfAborted();
2681
2734
  const admitted = await capacityAdmission.admit({
2682
2735
  assignmentId,
2683
2736
  nodeId,
@@ -2700,17 +2753,19 @@ export function createDispatchBundle(
2700
2753
  else await failQueuedAssignment(assignmentId);
2701
2754
  }
2702
2755
  throw error;
2756
+ } finally {
2757
+ signal?.removeEventListener("abort", cancel);
2703
2758
  }
2704
2759
  }
2705
2760
 
2706
2761
  /** Retries only: the first attempt's member was consumed with the planned bound. */
2707
- function rebindReservationSlot(
2762
+ async function rebindReservationSlot(
2708
2763
  req: DispatchRequest,
2709
2764
  nodeId: string,
2710
2765
  endpoint: EndpointCapacity | null,
2711
2766
  costUsd: number,
2712
2767
  settings: EffectiveSettings,
2713
- ): void {
2768
+ ): Promise<void> {
2714
2769
  if (req.reservation === undefined || req.lineage === undefined) return;
2715
2770
  const capacity = reservationCapacitySnapshot(settings);
2716
2771
  const rebind = {
@@ -2721,7 +2776,7 @@ export function createDispatchBundle(
2721
2776
  capacity,
2722
2777
  nowMs: now(),
2723
2778
  };
2724
- rebindDispatchReservationMember(rebind);
2779
+ await rebindDispatchReservationMember(rebind);
2725
2780
  }
2726
2781
 
2727
2782
  /** Process-local retry queue keyed by finished run; backoff is keyed by assignment root. */
@@ -2849,6 +2904,14 @@ export function createDispatchBundle(
2849
2904
  if (draining) return { scheduled: false };
2850
2905
  const rootRunId = run.lineage.rootRunId;
2851
2906
  if (!retryChainIsLive(run)) return { scheduled: false };
2907
+ if (providers.getRuntime(run.runtimeId)?.externalAgentLoop?.generatingRetry === "forbidden") {
2908
+ retryBackoff.delete(rootRunId);
2909
+ return {
2910
+ scheduled: false,
2911
+ settlementDetail:
2912
+ "automatic retry suppressed because this external agent loop is one-shot and Clio cannot prove replay is side-effect-free",
2913
+ };
2914
+ }
2852
2915
  if (!RETRYABLE_OUTCOMES.has(outcome)) {
2853
2916
  retryBackoff.delete(rootRunId);
2854
2917
  return { scheduled: false };
@@ -3224,6 +3287,9 @@ export function createDispatchBundle(
3224
3287
  const tickMonotonic = monotonicNow();
3225
3288
  for (const run of active.values()) {
3226
3289
  if (run.aborted || run.stallKilled || !run.heartbeatAt) continue;
3290
+ // Finalizers retain active entries while awaiting ledger persistence.
3291
+ // Their terminal status is already sealed into the receipt digest.
3292
+ if (ledger.get(run.runId)?.endedAt !== null) continue;
3227
3293
  const heartbeatMonotonic = heartbeatMonotonicAt(run.heartbeatAt);
3228
3294
  if (!Number.isFinite(heartbeatMonotonic) || !Number.isFinite(run.heartbeatAt.current)) continue;
3229
3295
  if (run.runtimeKind === "acp-delegation") {
@@ -3415,7 +3481,12 @@ export function createDispatchBundle(
3415
3481
  }
3416
3482
  }
3417
3483
 
3418
- async function resolveLifecycle(req: DispatchRequest, settings: EffectiveSettings): Promise<DispatchLifecycleStage> {
3484
+ async function resolveLifecycle(
3485
+ req: DispatchRequest,
3486
+ settings: EffectiveSettings,
3487
+ metadataDeadlineAt: number,
3488
+ signal?: AbortSignal,
3489
+ ): Promise<DispatchLifecycleStage> {
3419
3490
  const recipe = agents.get(req.agentId);
3420
3491
  if (!recipe) {
3421
3492
  throw new Error(`dispatch: unknown agent recipe: ${req.agentId}`);
@@ -3453,22 +3524,35 @@ export function createDispatchBundle(
3453
3524
  publishDispatchPathScope(req, pathScope);
3454
3525
  const admission = resolveDispatchAdmissionStage(req, recipe, safety, pathScope);
3455
3526
  const targets = readWorkerTargets(settings);
3456
- const target = resolveDispatchTarget(
3457
- req,
3458
- recipe,
3459
- targets.workerDefault,
3460
- targets.workerProfiles,
3461
- targets.agentBindings,
3462
- targets.targetOrder,
3463
- providers,
3464
- );
3527
+ const resolveTarget = () =>
3528
+ resolveDispatchTarget(
3529
+ req,
3530
+ recipe,
3531
+ targets.workerDefault,
3532
+ targets.workerProfiles,
3533
+ targets.agentBindings,
3534
+ targets.targetOrder,
3535
+ providers,
3536
+ );
3537
+ let target = resolveTarget();
3538
+ const identity = (resolved: ResolvedTarget): string =>
3539
+ JSON.stringify([
3540
+ resolved.target.id,
3541
+ resolved.runtime.id,
3542
+ resolved.wireModelId,
3543
+ endpointIdentityHash(resolved.target.url),
3544
+ ]);
3545
+ const selectedIdentity = identity(target);
3546
+ await prepareWorkerModelMetadata(providers, target.target.id, metadataDeadlineAt, signal, now);
3547
+ target = resolveTarget();
3548
+ if (identity(target) !== selectedIdentity) {
3549
+ throw new Error("dispatch: worker route changed during model metadata preparation; request a fresh admission");
3550
+ }
3465
3551
  enforceCapabilityGate(target.target.id, target.modelCapabilities, req.requiredCapabilities);
3466
3552
  assertRuntimeCanHonorWorkerPermissionMode(target.runtime, settings?.fleet.permissions.mode ?? "deny");
3467
- assertWorkerBudgetEnforceable(target.runtime, spec.budget !== null || req.budget !== undefined);
3468
-
3469
3553
  const cwd = req.cwd ?? process.cwd();
3470
3554
  const sessionAutonomy = settings?.safety.autonomy ?? "auto-edit";
3471
- const effectiveAutonomy = clampWorkerAutonomy(sessionAutonomy, req.autonomy);
3555
+ const effectiveAutonomy = effectiveWorkerAutonomy(sessionAutonomy, req.autonomy, spec.capabilityClass);
3472
3556
  const effectiveTools = withLedgerToolNarrowing(
3473
3557
  effectiveToolNames(admission.allowedTools, target, pathScope.writeBoundaries.length > 0, deniedToolNames(req)),
3474
3558
  req,
@@ -3478,8 +3562,8 @@ export function createDispatchBundle(
3478
3562
  ...admission,
3479
3563
  allowedTools: effectiveTools,
3480
3564
  };
3481
- const personaBody = workerPersonaBody(req, recipe, effectiveTools);
3482
- const hasCanonicalContext = effectiveTools.includes(ToolNames.Context);
3565
+ const hasCanonicalContext = canonicalContextAttached(target.runtime, effectiveTools);
3566
+ const personaBody = workerPersonaBody(req, recipe, hasCanonicalContext);
3483
3567
  const hasBoundSkills =
3484
3568
  hasCanonicalContext && recipe.skills !== undefined && recipe.skills.length > 0 && req.noSkills !== true;
3485
3569
  const compiledWorkerPrompt = await prompts.compileWorkerPrompt({
@@ -3507,6 +3591,7 @@ export function createDispatchBundle(
3507
3591
  declared: spec.budget,
3508
3592
  allowedTools: effectiveTools,
3509
3593
  settings,
3594
+ runtime: target.runtime,
3510
3595
  });
3511
3596
  // Fetch structured project context only for tiers that receive it, so
3512
3597
  // read-only scouts never pay the CLIO-CODER.md read. The tier is spec policy
@@ -3563,6 +3648,7 @@ export function createDispatchBundle(
3563
3648
  pipeline: pipelineProvenanceFor(req),
3564
3649
  briefing: briefingProvenanceFor(req),
3565
3650
  personaOverride,
3651
+ decisionRefs: req.decisionRefs ?? null,
3566
3652
  projectContext: projectContextProvenance,
3567
3653
  rulesApplied: compiledWorkerPrompt.rulesApplied ?? [],
3568
3654
  operatorProfileApplied: compiledWorkerPrompt.operatorProfileApplied ?? false,
@@ -3610,7 +3696,7 @@ export function createDispatchBundle(
3610
3696
  }
3611
3697
  const cwd = req.cwd ?? process.cwd();
3612
3698
  const pathScope = resolveDispatchPathScope(req);
3613
- const personaBody = workerPersonaBody(req, null, []);
3699
+ const personaBody = workerPersonaBody(req, null, false);
3614
3700
  // ACP owns an unknown external tool inventory, so it receives the raw
3615
3701
  // bounded persona rather than a native Clio schema-harness claim.
3616
3702
  const systemPrompt = personaBody;
@@ -3652,6 +3738,7 @@ export function createDispatchBundle(
3652
3738
  pipeline: pipelineProvenanceFor(req),
3653
3739
  briefing: briefingProvenanceFor(req),
3654
3740
  personaOverride,
3741
+ decisionRefs: req.decisionRefs ?? null,
3655
3742
  projectContext: projectContextProvenance,
3656
3743
  rulesApplied: [],
3657
3744
  operatorProfileApplied: false,
@@ -3827,11 +3914,13 @@ export function createDispatchBundle(
3827
3914
  const responseModelIdObservation = responseModelIdObservationFromRecord(event.message, "not-observed");
3828
3915
  const differingResponseModelId = readStringOrNull(event.message.responseModel);
3829
3916
  const providerResponseId = readStringOrNull(event.message.responseId);
3917
+ const gatewayRouting = gatewayRoutingObservationFromRecord(event.message);
3830
3918
  upstreamResponses.push({
3831
3919
  requestedModelId,
3832
3920
  responseModelIdObservation,
3833
3921
  differingResponseModelId,
3834
3922
  providerResponseId,
3923
+ ...(gatewayRouting !== null ? { gatewayRouting } : {}),
3835
3924
  });
3836
3925
  if (event.message.stopReason === "error") {
3837
3926
  const message = readStringOrNull(event.message.errorMessage);
@@ -3931,6 +4020,7 @@ export function createDispatchBundle(
3931
4020
  ...(req.council !== undefined ? { council: req.council } : {}),
3932
4021
  ...(req.plan !== undefined ? { plan: req.plan } : {}),
3933
4022
  ...(lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {}),
4023
+ ...(lifecycle.decisionRefs ? { decisionRefs: lifecycle.decisionRefs } : {}),
3934
4024
  });
3935
4025
  observer?.onAdmitted({
3936
4026
  runId: envelope.id,
@@ -4003,6 +4093,12 @@ export function createDispatchBundle(
4003
4093
  });
4004
4094
 
4005
4095
  const startedAt = envelope.startedAt;
4096
+ let resolveFinal!: (receipt: RunReceipt) => void;
4097
+ let rejectFinal!: (error: unknown) => void;
4098
+ const finalPromise = new Promise<RunReceipt>((res, rej) => {
4099
+ resolveFinal = res;
4100
+ rejectFinal = rej;
4101
+ });
4006
4102
  const activeRun: ActiveRun = {
4007
4103
  runId: envelope.id,
4008
4104
  req,
@@ -4034,7 +4130,7 @@ export function createDispatchBundle(
4034
4130
  meter: tokenMeter,
4035
4131
  pricing: null,
4036
4132
  costProvenance: "unknown",
4037
- finalPromise: undefined as unknown as Promise<RunReceipt>,
4133
+ finalPromise,
4038
4134
  };
4039
4135
 
4040
4136
  const buildReceiptDraft = (
@@ -4092,6 +4188,7 @@ export function createDispatchBundle(
4092
4188
  ...(req.council !== undefined ? { council: req.council } : {}),
4093
4189
  ...(req.plan !== undefined ? { plan: req.plan } : {}),
4094
4190
  ...(lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {}),
4191
+ ...(lifecycle.decisionRefs ? { decisionRefs: lifecycle.decisionRefs } : {}),
4095
4192
  projectContext: lifecycle.projectContext,
4096
4193
  rulesApplied: lifecycle.rulesApplied,
4097
4194
  operatorProfileApplied: lifecycle.operatorProfileApplied,
@@ -4217,7 +4314,6 @@ export function createDispatchBundle(
4217
4314
  const assessDispatchFinishContract = (): DispatchFinishContractSnapshot | null => {
4218
4315
  if (finishContractAssistantText.trim().length === 0) return null;
4219
4316
  const assessment = assessFinishContract({
4220
- assistantText: finishContractAssistantText,
4221
4317
  sessionEntries: finishContractEntries,
4222
4318
  assistantTurnId: finishContractAssistantTurnId,
4223
4319
  });
@@ -4238,7 +4334,7 @@ export function createDispatchBundle(
4238
4334
  return { assessment, rigor };
4239
4335
  };
4240
4336
 
4241
- const finalPromise = (async (): Promise<RunReceipt> => {
4337
+ (async (): Promise<RunReceipt> => {
4242
4338
  try {
4243
4339
  const result = await acp.promise;
4244
4340
  // The receipt reads meters the domain pump fills. Finalization
@@ -4374,9 +4470,7 @@ export function createDispatchBundle(
4374
4470
  } finally {
4375
4471
  leaseSlot.release();
4376
4472
  }
4377
- })();
4378
-
4379
- activeRun.finalPromise = finalPromise;
4473
+ })().then(resolveFinal, rejectFinal);
4380
4474
  active.set(envelope.id, activeRun);
4381
4475
 
4382
4476
  return {
@@ -4389,6 +4483,7 @@ export function createDispatchBundle(
4389
4483
  async function dispatchAttempt(
4390
4484
  req: DispatchRequest,
4391
4485
  observer?: DispatchAdmissionObserver,
4486
+ preparation?: DispatchPreparationOptions,
4392
4487
  settlement?: BatchVerificationGate,
4393
4488
  ): Promise<{
4394
4489
  runId: string;
@@ -4483,7 +4578,7 @@ export function createDispatchBundle(
4483
4578
  "dispatch: writeRoots cannot be enforced on an ACP delegation target; the external agent runs its own tool surface. Dispatch to a native or claude-sdk worker.",
4484
4579
  );
4485
4580
  }
4486
- rebindReservationSlot(req, "local", null, UNKNOWN_PRICING_ADMISSION_ESTIMATE_USD, settings);
4581
+ await rebindReservationSlot(req, "local", null, UNKNOWN_PRICING_ADMISSION_ESTIMATE_USD, settings);
4487
4582
  routeObservation = observeShadowRoute(req, undefined, settings);
4488
4583
  const delegated = await dispatchAcpDelegation(req, settings, timing, routeObservation.decision, observer);
4489
4584
  // An ACP member never runs host verification, so it can only ever leave
@@ -4494,7 +4589,10 @@ export function createDispatchBundle(
4494
4589
  }
4495
4590
 
4496
4591
  req = routeAroundCoolingTarget(req, settings) ?? req;
4497
- const lifecycle = await resolveLifecycle(req, settings);
4592
+ const metadataDeadlineAt =
4593
+ req.assignmentDeadlineAt ?? Date.parse(requestedAt) + (req.routingIntent?.deadlineMs ?? 60_000);
4594
+ const lifecycle = await resolveLifecycle(req, settings, metadataDeadlineAt, preparation?.signal);
4595
+ preparation?.signal?.throwIfAborted();
4498
4596
  timing.decisionCompletedAt = new Date(now()).toISOString();
4499
4597
  assertResponseSchemaEnforceable(
4500
4598
  lifecycle.target.runtime,
@@ -4521,7 +4619,7 @@ export function createDispatchBundle(
4521
4619
  };
4522
4620
  const endpoint = endpointCapacityForTarget(lifecycle.target.target.id);
4523
4621
  assertRouteWithinApprovedEnvelope(req, effectiveRoute);
4524
- rebindReservationSlot(
4622
+ await rebindReservationSlot(
4525
4623
  req,
4526
4624
  effectiveRoute.node,
4527
4625
  endpoint,
@@ -4571,7 +4669,13 @@ export function createDispatchBundle(
4571
4669
  if (queuedIdentity !== null) publishCapacityQueued(queuedIdentity, timing, placement?.node ?? null);
4572
4670
  let capacityLease: Awaited<ReturnType<typeof admitAssignmentCapacity>>;
4573
4671
  try {
4574
- capacityLease = await admitAssignmentCapacity(req, placement?.node.id ?? "local", timing, endpoint);
4672
+ capacityLease = await admitAssignmentCapacity(
4673
+ req,
4674
+ placement?.node.id ?? "local",
4675
+ timing,
4676
+ endpoint,
4677
+ preparation?.signal,
4678
+ );
4575
4679
  } catch (error) {
4576
4680
  if (queuedIdentity !== null) publishCapacityAdmissionFailure(queuedIdentity, error);
4577
4681
  throw error;
@@ -4582,6 +4686,7 @@ export function createDispatchBundle(
4582
4686
 
4583
4687
  const ledgerRef = (() => {
4584
4688
  try {
4689
+ preparation?.signal?.throwIfAborted();
4585
4690
  return requireLedger();
4586
4691
  } catch (error) {
4587
4692
  leaseSlot.release();
@@ -4644,6 +4749,7 @@ export function createDispatchBundle(
4644
4749
  };
4645
4750
  let worker: SpawnedWorker;
4646
4751
  try {
4752
+ preparation?.signal?.throwIfAborted();
4647
4753
  worker = (placement?.spawn ?? spawnWorker)(spec, {
4648
4754
  cwd: lifecycle.cwd,
4649
4755
  now,
@@ -4865,11 +4971,13 @@ export function createDispatchBundle(
4865
4971
  const responseModelIdObservation = responseModelIdObservationFromRecord(event.message, "not-observed");
4866
4972
  const differingResponseModelId = readStringOrNull(event.message.responseModel);
4867
4973
  const providerResponseId = readStringOrNull(event.message.responseId);
4974
+ const gatewayRouting = gatewayRoutingObservationFromRecord(event.message);
4868
4975
  upstreamResponses.push({
4869
4976
  requestedModelId,
4870
4977
  responseModelIdObservation,
4871
4978
  differingResponseModelId,
4872
4979
  providerResponseId,
4980
+ ...(gatewayRouting !== null ? { gatewayRouting } : {}),
4873
4981
  });
4874
4982
  if (event.message.stopReason === "error") {
4875
4983
  const message = readStringOrNull(event.message.errorMessage);
@@ -5018,6 +5126,7 @@ export function createDispatchBundle(
5018
5126
  ...(req.council !== undefined ? { council: req.council } : {}),
5019
5127
  ...(req.plan !== undefined ? { plan: req.plan } : {}),
5020
5128
  ...(lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {}),
5129
+ ...(lifecycle.decisionRefs ? { decisionRefs: lifecycle.decisionRefs } : {}),
5021
5130
  ...(heartbeatAt ? { heartbeatAt: heartbeatIso(heartbeatAt) } : {}),
5022
5131
  });
5023
5132
  observer?.onAdmitted({
@@ -5121,6 +5230,13 @@ export function createDispatchBundle(
5121
5230
 
5122
5231
  const startedAt = envelope.startedAt;
5123
5232
 
5233
+ let resolveFinal!: (receipt: RunReceipt) => void;
5234
+ let rejectFinal!: (error: unknown) => void;
5235
+ const finalPromise = new Promise<RunReceipt>((res, rej) => {
5236
+ resolveFinal = res;
5237
+ rejectFinal = rej;
5238
+ });
5239
+
5124
5240
  const activeRun: ActiveRun = {
5125
5241
  runId: envelope.id,
5126
5242
  req,
@@ -5156,7 +5272,7 @@ export function createDispatchBundle(
5156
5272
  meter: tokenMeter,
5157
5273
  pricing: lifecycle.target.effectivePricing.rates,
5158
5274
  costProvenance: lifecycle.target.effectivePricing.provenance,
5159
- finalPromise: undefined as unknown as Promise<RunReceipt>,
5275
+ finalPromise,
5160
5276
  };
5161
5277
 
5162
5278
  const buildReceiptDraft = (
@@ -5251,6 +5367,7 @@ export function createDispatchBundle(
5251
5367
  ...(req.plan !== undefined ? { plan: req.plan } : {}),
5252
5368
  ...(fleetGate !== null ? { fleetGate } : {}),
5253
5369
  ...(lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {}),
5370
+ ...(lifecycle.decisionRefs ? { decisionRefs: lifecycle.decisionRefs } : {}),
5254
5371
  projectContext: lifecycle.projectContext,
5255
5372
  rulesApplied: lifecycle.rulesApplied,
5256
5373
  operatorProfileApplied: lifecycle.operatorProfileApplied,
@@ -5394,7 +5511,6 @@ export function createDispatchBundle(
5394
5511
  const assessDispatchFinishContract = (): DispatchFinishContractSnapshot | null => {
5395
5512
  if (finishContractAssistantText.trim().length === 0) return null;
5396
5513
  const assessment = assessFinishContract({
5397
- assistantText: finishContractAssistantText,
5398
5514
  sessionEntries: finishContractEntries,
5399
5515
  assistantTurnId: finishContractAssistantTurnId,
5400
5516
  });
@@ -5423,7 +5539,7 @@ export function createDispatchBundle(
5423
5539
  // finalPromise settles.
5424
5540
  settlement?.live(envelope.id);
5425
5541
 
5426
- const finalPromise = (async (): Promise<RunReceipt> => {
5542
+ (async (): Promise<RunReceipt> => {
5427
5543
  try {
5428
5544
  const result = await workerDone;
5429
5545
  // The receipt reads meters the domain pump fills. Finalization
@@ -5493,7 +5609,9 @@ export function createDispatchBundle(
5493
5609
  reachedTerminalResult: resultContractWasDue(finalOutcome, outcomeCode),
5494
5610
  output: capturedOutput?.state === "final" ? capturedOutput.text : null,
5495
5611
  cwd: lifecycle.cwd,
5496
- networkAllowed: lifecycle.admission.allowedTools.includes(ToolNames.WebFetch),
5612
+ networkAllowed:
5613
+ lifecycle.admission.allowedTools.includes(ToolNames.WebFetch) ||
5614
+ lifecycle.target.runtime.externalAgentLoop?.network === "externally-governed-unobserved",
5497
5615
  observedRunEffects,
5498
5616
  filesystem: nodeResultContractFilesystem(),
5499
5617
  });
@@ -5738,9 +5856,8 @@ export function createDispatchBundle(
5738
5856
  unsubscribeAgentLedger?.();
5739
5857
  leaseSlot.release();
5740
5858
  }
5741
- })();
5859
+ })().then(resolveFinal, rejectFinal);
5742
5860
 
5743
- activeRun.finalPromise = finalPromise;
5744
5861
  active.set(envelope.id, activeRun);
5745
5862
 
5746
5863
  return attachRouteObservation({
@@ -5754,13 +5871,20 @@ export function createDispatchBundle(
5754
5871
  async function dispatch(
5755
5872
  req: DispatchRequest,
5756
5873
  observer?: DispatchAdmissionObserver,
5874
+ preparation?: DispatchPreparationOptions,
5757
5875
  settlement?: BatchVerificationGate,
5758
5876
  ): Promise<{
5759
5877
  runId: string;
5760
5878
  events: AsyncIterableIterator<unknown>;
5761
5879
  finalPromise: Promise<RunReceipt>;
5762
5880
  }> {
5763
- let prepared = req;
5881
+ let prepared =
5882
+ preparation?.deadlineAt === undefined
5883
+ ? req
5884
+ : {
5885
+ ...req,
5886
+ assignmentDeadlineAt: Math.min(req.assignmentDeadlineAt ?? Number.POSITIVE_INFINITY, preparation.deadlineAt),
5887
+ };
5764
5888
  let createdWorktree: DispatchRequest["taskWorktree"];
5765
5889
  let writerLease: CheckoutWriterLease | undefined;
5766
5890
  const writerRecipe = agents.get(req.agentId);
@@ -5792,7 +5916,7 @@ export function createDispatchBundle(
5792
5916
  return rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel) ? entry : resolvePath(taskWorktree.path, rel);
5793
5917
  });
5794
5918
  prepared = {
5795
- ...req,
5919
+ ...prepared,
5796
5920
  runIdHint: runId,
5797
5921
  taskWorktree,
5798
5922
  cwd: workerCwd,
@@ -5802,7 +5926,8 @@ export function createDispatchBundle(
5802
5926
  }
5803
5927
  let handle: Awaited<ReturnType<typeof dispatchAttempt>>;
5804
5928
  try {
5805
- handle = await dispatchAttempt(prepared, observer, settlement);
5929
+ preparation?.signal?.throwIfAborted();
5930
+ handle = await dispatchAttempt(prepared, observer, preparation, settlement);
5806
5931
  } catch (error) {
5807
5932
  writerLease?.release();
5808
5933
  if (createdWorktree !== undefined) {
@@ -5929,7 +6054,6 @@ export function createDispatchBundle(
5929
6054
  );
5930
6055
  assertPostRuntimeToolCompatibility(req.agentId, agentSpec, effectiveTools, target);
5931
6056
  assertRuntimeCanHonorWorkerPermissionMode(target.runtime, settings?.fleet.permissions.mode ?? "deny");
5932
- assertWorkerBudgetEnforceable(target.runtime, agentSpec.budget !== null || req.budget !== undefined);
5933
6057
  assertResponseSchemaEnforceable(target.runtime, target.modelCapabilities, req.responseSchema, effectiveTools.length);
5934
6058
  assertWriteRootsEnforceable(target.runtime, pathScope.writeBoundaries);
5935
6059
  assertProtectedArtifactsEnforceable(
@@ -5943,6 +6067,7 @@ export function createDispatchBundle(
5943
6067
  declared: agentSpec.budget,
5944
6068
  allowedTools: effectiveTools,
5945
6069
  settings,
6070
+ runtime: target.runtime,
5946
6071
  });
5947
6072
  const endpoint = endpointCapacityForTarget(target.target.id);
5948
6073
  return {
@@ -6191,7 +6316,10 @@ export function createDispatchBundle(
6191
6316
  })();
6192
6317
  }
6193
6318
 
6194
- async function dispatchBatch(reqs: ReadonlyArray<DispatchRequest>): Promise<{
6319
+ async function dispatchBatch(
6320
+ reqs: ReadonlyArray<DispatchRequest>,
6321
+ preparation?: DispatchPreparationOptions,
6322
+ ): Promise<{
6195
6323
  batchId: string;
6196
6324
  assignmentIds: ReadonlyArray<string>;
6197
6325
  events: AsyncIterableIterator<unknown>;
@@ -6210,7 +6338,7 @@ export function createDispatchBundle(
6210
6338
  const handles: Array<Awaited<ReturnType<typeof dispatch>> & { agentId: string }> = [];
6211
6339
  try {
6212
6340
  for (const req of reqs) {
6213
- const handle = await dispatch(req, undefined, settlement);
6341
+ const handle = await dispatch(req, undefined, preparation, settlement);
6214
6342
  handles.push({ ...handle, agentId: req.agentId });
6215
6343
  }
6216
6344
  } catch (err) {
@@ -6,6 +6,8 @@ export interface FleetCommitPriorResult {
6
6
  succeeded: boolean;
7
7
  integrityValid: boolean;
8
8
  receiptDigest: string;
9
+ /** Decision refs from the step's sealed receipt; they become `Clio-Decision:` trailers. */
10
+ decisionRefs?: ReadonlyArray<string>;
9
11
  }
10
12
 
11
13
  /**
@@ -23,6 +25,7 @@ export function deriveFleetCommitAttribution(input: {
23
25
  const byId = new Map(input.plan.steps.map((step) => [step.id, step] as const));
24
26
  let materiallyAuthored = false;
25
27
  let receipt: CommitAttributionEvidence["receipt"];
28
+ let decisions: CommitAttributionEvidence["decisions"];
26
29
  for (const candidate of input.step.commitFrom ?? []) {
27
30
  const source = byId.get(candidate);
28
31
  const result = input.priorResults.get(candidate);
@@ -35,6 +38,7 @@ export function deriveFleetCommitAttribution(input: {
35
38
  continue;
36
39
  }
37
40
  materiallyAuthored = true;
41
+ if (result.decisionRefs !== undefined && result.decisionRefs.length > 0) decisions = [...result.decisionRefs];
38
42
  if (/^[0-9a-f]{64}$/u.test(result.receiptDigest)) {
39
43
  receipt = {
40
44
  version: RUN_RECEIPT_INTEGRITY_VERSION,
@@ -52,5 +56,6 @@ export function deriveFleetCommitAttribution(input: {
52
56
  validationSucceeded: input.validationFresh,
53
57
  independentReviewPassed: input.independentReviewFresh,
54
58
  ...(receipt === undefined ? {} : { receipt }),
59
+ ...(decisions === undefined ? {} : { decisions }),
55
60
  };
56
61
  }