@iowarp/clio-coder 0.3.9 → 0.4.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 (416) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/NOTICE +33 -0
  3. package/README.md +7 -2
  4. package/dist/{acp-7LOELQFP.js → acp-G5WJBNCT.js} +13 -12
  5. package/dist/{agents-FIBG2SHA.js → agents-FMV2Q5G4.js} +39 -36
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-OI4LIH2I.js → auth-3IDSJEIK.js} +16 -15
  8. package/dist/{builtins-AD25UL3C.js → builtins-XCZWXSC7.js} +3 -3
  9. package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
  10. package/dist/{chunk-56KB5IJP.js → chunk-2OQE55CK.js} +3 -3
  11. package/dist/{chunk-N3PBVRTZ.js → chunk-32KWKNSF.js} +9 -7
  12. package/dist/{chunk-VKBMFOYV.js → chunk-36EJLSQQ.js} +23 -27
  13. package/dist/{chunk-465CC7FK.js → chunk-3BT2XMV4.js} +16 -13
  14. package/dist/{chunk-NQ6UCCOD.js → chunk-3URVFKWK.js} +7 -7
  15. package/dist/{chunk-WIE7ZOSW.js → chunk-3XML7CDN.js} +2 -2
  16. package/dist/chunk-42FMPA75.js +101 -0
  17. package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
  18. package/dist/{chunk-HAY4ZE2P.js → chunk-5PSMVOLM.js} +2 -2
  19. package/dist/{chunk-JEQQR47K.js → chunk-6DB53AJS.js} +168 -9
  20. package/dist/{chunk-KV2AOLDF.js → chunk-76ONBSIA.js} +5 -25
  21. package/dist/{chunk-FALJGAWU.js → chunk-7MCTRUCE.js} +2 -2
  22. package/dist/{chunk-5T7RBWN2.js → chunk-AB44T6BB.js} +5 -5
  23. package/dist/chunk-B7OBL7PK.js +1405 -0
  24. package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
  25. package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
  26. package/dist/{chunk-O6I4CIEU.js → chunk-BKFJHQCA.js} +6 -6
  27. package/dist/chunk-BKFM6EJV.js +462 -0
  28. package/dist/chunk-BMS5RKQY.js +27 -0
  29. package/dist/{chunk-MV2VUEJC.js → chunk-BPKCPIL7.js} +2 -2
  30. package/dist/{chunk-TEO2TLVN.js → chunk-BUMFYQFY.js} +964 -1120
  31. package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
  32. package/dist/chunk-C2LTL2W6.js +2447 -0
  33. package/dist/{chunk-EBOC7MT3.js → chunk-CODPRO7Q.js} +8 -8
  34. package/dist/{chunk-HPCTNZM2.js → chunk-CTJ4RNAA.js} +4 -4
  35. package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
  36. package/dist/{chunk-MIX5N5AC.js → chunk-DQITNCXG.js} +394 -154
  37. package/dist/{chunk-S4COXYBG.js → chunk-DYJP44XW.js} +129 -106
  38. package/dist/{chunk-N5XKWMDW.js → chunk-F4CKPOEQ.js} +6 -6
  39. package/dist/{chunk-AMKHQW3C.js → chunk-FEFIFZTL.js} +3 -3
  40. package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
  41. package/dist/{chunk-7C6RYZGQ.js → chunk-GKF55TAZ.js} +3 -3
  42. package/dist/{chunk-B5XRQOLB.js → chunk-GR5G2PVF.js} +9 -8
  43. package/dist/{chunk-XDOQXGFO.js → chunk-GXNLGKAB.js} +64 -8
  44. package/dist/chunk-HHV2GANA.js +88 -0
  45. package/dist/{chunk-774ILSRL.js → chunk-HI63TFOG.js} +4 -3
  46. package/dist/{chunk-R7LNVMCS.js → chunk-HJJTYUHX.js} +64 -72
  47. package/dist/{chunk-RKRLDWD3.js → chunk-HLW2MRKE.js} +1 -1
  48. package/dist/{chunk-CA42X6KT.js → chunk-HWHKMHUA.js} +6 -6
  49. package/dist/chunk-HZHHCK24.js +1631 -0
  50. package/dist/{chunk-HJB5IUKP.js → chunk-I5VEOC6I.js} +12 -12
  51. package/dist/chunk-IBEBSCYA.js +564 -0
  52. package/dist/chunk-IQ7KR472.js +362 -0
  53. package/dist/{chunk-4H6ULJ3H.js → chunk-J4W7KFM7.js} +921 -990
  54. package/dist/{chunk-4LJX2PUC.js → chunk-JDG2WCRO.js} +5 -5
  55. package/dist/{chunk-NZU6YDNV.js → chunk-K5C3NCBD.js} +4 -4
  56. package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
  57. package/dist/{chunk-NNNWO6F2.js → chunk-KFZI4NIL.js} +93 -3
  58. package/dist/chunk-KMVISBZR.js +132 -0
  59. package/dist/{chunk-BVDVID7E.js → chunk-LDQ2ZF2M.js} +2 -2
  60. package/dist/{chunk-OEDBCISO.js → chunk-LQ3DZAMX.js} +2 -2
  61. package/dist/{chunk-PZ4I4JE2.js → chunk-LY4S7GJC.js} +124 -116
  62. package/dist/{chunk-3DUR4WUA.js → chunk-MLKNTWH2.js} +19 -19
  63. package/dist/chunk-NEKRRTYW.js +56 -0
  64. package/dist/{chunk-5DQRIYDZ.js → chunk-NHCZP4K7.js} +2 -2
  65. package/dist/chunk-NHLBIGRH.js +1506 -0
  66. package/dist/chunk-NQQH3YT7.js +302 -0
  67. package/dist/chunk-NYS75XW5.js +15 -0
  68. package/dist/{chunk-TD7UE2L5.js → chunk-O4XIVISU.js} +7 -7
  69. package/dist/{chunk-WXCJ7VME.js → chunk-O6TL7WWY.js} +6 -6
  70. package/dist/chunk-OQBA45DZ.js +97 -0
  71. package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
  72. package/dist/chunk-PMZCIOCJ.js +25 -0
  73. package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
  74. package/dist/{chunk-HKO36JWF.js → chunk-QBJA7R7N.js} +31 -3
  75. package/dist/chunk-QDC3K2U3.js +262 -0
  76. package/dist/{chunk-5HFBWUMU.js → chunk-QLFS5GO2.js} +4 -4
  77. package/dist/{chunk-GAYUJ7LE.js → chunk-QLL7ILRG.js} +41 -32
  78. package/dist/{chunk-LXPJXFM5.js → chunk-QREDIESB.js} +7 -7
  79. package/dist/chunk-QSNYB6ZV.js +195 -0
  80. package/dist/chunk-R346GLFC.js +31 -0
  81. package/dist/{chunk-VPTUJU4P.js → chunk-SJ5ZKQ4S.js} +2 -2
  82. package/dist/{chunk-QQ7EKM72.js → chunk-SP2RXXYO.js} +6 -54
  83. package/dist/chunk-SUCTJL45.js +45 -0
  84. package/dist/{chunk-5QKCQQ3E.js → chunk-SUW5DORT.js} +2 -2
  85. package/dist/chunk-T56WDKA5.js +183 -0
  86. package/dist/chunk-TVHHYFHE.js +255 -0
  87. package/dist/{chunk-IHKBWSXF.js → chunk-TZ3SGWZZ.js} +2 -2
  88. package/dist/{chunk-ECUO3KDP.js → chunk-U77AMWDL.js} +47 -7
  89. package/dist/{chunk-3UUY7R3Z.js → chunk-ULC6OTWO.js} +7 -7
  90. package/dist/{chunk-AEYBF3TB.js → chunk-UM7N4G5A.js} +2 -2
  91. package/dist/{chunk-3V5AYSEQ.js → chunk-UXMFQ54G.js} +43 -36
  92. package/dist/{chunk-YW7UVM5V.js → chunk-V5DHCITQ.js} +34 -1
  93. package/dist/{chunk-47CMYGET.js → chunk-VAZSBTKF.js} +2 -2
  94. package/dist/{chunk-3MRC2YSQ.js → chunk-VEO4AP2K.js} +2 -2
  95. package/dist/{chunk-PNY46YEY.js → chunk-VFA6GDY5.js} +47 -3
  96. package/dist/chunk-VO67MWHC.js +75 -0
  97. package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
  98. package/dist/{chunk-AD7Y7STJ.js → chunk-VYMXRQI6.js} +36 -22
  99. package/dist/{chunk-T3Z6VAAF.js → chunk-W5VSYASO.js} +19 -17
  100. package/dist/{chunk-5PVQ4SRS.js → chunk-WZR7K7ZX.js} +7 -123
  101. package/dist/{chunk-DG4M6ZUE.js → chunk-X3YGUTOB.js} +4 -4
  102. package/dist/chunk-X75E3D2N.js +686 -0
  103. package/dist/{chunk-P3JGPQFL.js → chunk-YDFRH54B.js} +4 -4
  104. package/dist/chunk-YJX4SHTD.js +40 -0
  105. package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
  106. package/dist/{chunk-YSEHGPCT.js → chunk-Z2RR6MAK.js} +3 -3
  107. package/dist/{chunk-HCBCAYZU.js → chunk-Z4TXYIEG.js} +5 -5
  108. package/dist/cli/index.js +47 -36
  109. package/dist/{clio-LT5V7SSZ.js → clio-2JXHBBY5.js} +7 -7
  110. package/dist/{code-nav-LMW275PA.js → code-nav-3YYRMYNF.js} +6 -6
  111. package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
  112. package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
  113. package/dist/{config-RXS5T3JT.js → config-QZPCMYSO.js} +58 -50
  114. package/dist/{configure-2WYWSCSD.js → configure-TEGEBYCA.js} +21 -19
  115. package/dist/{context-I3BTOTCS.js → context-AV7OEZ4D.js} +11 -11
  116. package/dist/{context-MVOORGMF.js → context-E6H5RNMC.js} +49 -41
  117. package/dist/{context-PALKKQYL.js → context-GSXUE4CT.js} +25 -23
  118. package/dist/{context-clear-N2WOYZ2K.js → context-clear-SHIBYK6T.js} +48 -40
  119. package/dist/{context-working-set-MIEVECVZ.js → context-working-set-5ZGKPGZQ.js} +11 -10
  120. package/dist/{dispatch-runner-VVA4SRRH.js → dispatch-runner-EFMJT4LD.js} +88 -60
  121. package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
  122. package/dist/doctor-QOA5FNY5.js +313 -0
  123. package/dist/{eval-IJ5VEZDJ.js → eval-TFBYQH4H.js} +66 -64
  124. package/dist/eval-inventory-SXH7PDKX.js +316 -0
  125. package/dist/{evidence-L5APPXNV.js → evidence-ERGESKGN.js} +198 -44
  126. package/dist/{evolve-RGNKFJ52.js → evolve-VDXTSYCJ.js} +46 -38
  127. package/dist/{extensions-7WYWUX5A.js → extensions-7BGBHN57.js} +6 -6
  128. package/dist/{fleet-6CNVBZZP.js → fleet-2RRVDF2V.js} +189 -101
  129. package/dist/{fleet-commands-L2SXSYEI.js → fleet-commands-VJ726XIA.js} +10 -10
  130. package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
  131. package/dist/{fleet-graph-2J3OOIPO.js → fleet-graph-JF5QOATM.js} +16 -15
  132. package/dist/fleet-inspect-VLY4S7QM.js +442 -0
  133. package/dist/{fleet-preflight-CZRJ4JP5.js → fleet-preflight-AIZUEJOY.js} +6 -5
  134. package/dist/{fleet-validate-C5RI6DP7.js → fleet-validate-AJRPDMDV.js} +20 -18
  135. package/dist/fleet-verify-JFEL2L3H.js +175 -0
  136. package/dist/fleet-view-ZCON35AG.js +102 -0
  137. package/dist/{init-VBN2ACVA.js → init-DN2WWLFE.js} +64 -56
  138. package/dist/install-XGLBQY5E.js +13 -0
  139. package/dist/interop-OZBKXAYL.js +114 -0
  140. package/dist/{library-JHGUMLY2.js → library-YWZG7IMW.js} +19 -18
  141. package/dist/{memory-K4OQIYWG.js → memory-I4C4HMLW.js} +48 -40
  142. package/dist/{models-2NCZUWDD.js → models-CEYXJBO6.js} +30 -28
  143. package/dist/{monitor-MMVTJABD.js → monitor-NZ6GCI3P.js} +53 -47
  144. package/dist/{orchestrator-ZKBPCHW6.js → orchestrator-GCGQ4N5I.js} +6311 -7145
  145. package/dist/panes-HMABYVO4.js +58 -0
  146. package/dist/panes-KY6W3V2E.js +103 -0
  147. package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
  148. package/dist/{reset-DD5JGOY3.js → reset-DQ6FGCSH.js} +13 -11
  149. package/dist/resources-BB3MVJMD.js +111 -0
  150. package/dist/{run-QEGNX7FL.js → run-H2GQDUER.js} +113 -82
  151. package/dist/{share-JKD3BQMW.js → share-GTJN6A5O.js} +18 -17
  152. package/dist/{skills-LMQIKDOZ.js → skills-L55TEW6R.js} +31 -24
  153. package/dist/{skills-eval-I7X2774U.js → skills-eval-XVXPH2JI.js} +61 -52
  154. package/dist/skills-inventory-S4MXPJFV.js +126 -0
  155. package/dist/slash-commands-ZSGASKJC.js +77 -0
  156. package/dist/{steer-CF5TDANS.js → steer-RZGSCY4R.js} +3 -3
  157. package/dist/{support-I7LOJLIF.js → support-PKEUNNQL.js} +4 -4
  158. package/dist/{targets-RUSR6B5Z.js → targets-NCPZ644J.js} +31 -29
  159. package/dist/{terminal-lease-QYVORFR4.js → terminal-lease-44SV3YCN.js} +4 -4
  160. package/dist/tools-DAF3DI3C.js +27 -0
  161. package/dist/{trace-ODOQIVIW.js → trace-FYVW2MQA.js} +149 -7
  162. package/dist/tui-primitives-2AKXQNZK.js +13 -0
  163. package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
  164. package/dist/{upgrade-XANW3FXB.js → upgrade-3XPP6OQL.js} +26 -24
  165. package/dist/{usage-4H7ZRXQT.js → usage-3NLHGTU2.js} +57 -49
  166. package/dist/{verifiers-UZXNBZEB.js → verifiers-SSQONKRT.js} +171 -12
  167. package/dist/{verify-BVKWTNDL.js → verify-3U6J7FZI.js} +9 -9
  168. package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
  169. package/dist/{wiki-generate-MY7WV2QI.js → wiki-generate-CEHYGPGQ.js} +67 -59
  170. package/dist/with-panes-MKB46MPQ.js +782 -0
  171. package/dist/worker/entry.js +101 -66
  172. package/docs/README.md +3 -2
  173. package/docs/acp.md +24 -3
  174. package/docs/alcf-provider.md +1 -1
  175. package/docs/architecture.md +2 -2
  176. package/docs/artifact-versions.md +4 -1
  177. package/docs/built-in-agents.md +1 -1
  178. package/docs/capacity-and-scheduling.md +43 -5
  179. package/docs/commands-and-modes.md +31 -2
  180. package/docs/configuration-and-targets.md +40 -10
  181. package/docs/context-engine.md +1 -1
  182. package/docs/development-pipeline.md +19 -0
  183. package/docs/dispatch-typed-intent.md +385 -0
  184. package/docs/documentation-coverage.md +2 -2
  185. package/docs/documentation-guide.md +1 -1
  186. package/docs/environment-variables.md +1 -0
  187. package/docs/eval-runner.md +1 -1
  188. package/docs/evals-internal.md +1 -1
  189. package/docs/evidence-and-memory.md +2 -2
  190. package/docs/evolution.md +1 -1
  191. package/docs/exit-codes-and-output.md +1 -1
  192. package/docs/extensions-and-sharing.md +25 -1
  193. package/docs/fleet-dispatch.md +22 -1
  194. package/docs/installation-and-lifecycle.md +15 -2
  195. package/docs/middleware-and-components.md +1 -1
  196. package/docs/model-catalog.md +10 -1
  197. package/docs/observability.md +3 -3
  198. package/docs/proactive-memory.md +1 -1
  199. package/docs/prompt-envelope-and-tools.md +1 -1
  200. package/docs/provider-adapter-cookbook.md +1 -1
  201. package/docs/safety-model.md +2 -2
  202. package/docs/scientific-validation.md +3 -3
  203. package/docs/session-lifecycle.md +1 -1
  204. package/docs/skills-marketplace.md +1 -1
  205. package/docs/tool-usage.md +18 -8
  206. package/docs/trace-store.md +1 -1
  207. package/docs/troubleshooting.md +1 -1
  208. package/docs/tui-design.md +1 -1
  209. package/docs/worker-dispatch-mechanics.md +1 -1
  210. package/package.json +4 -2
  211. package/src/cli/acp.ts +6 -2
  212. package/src/cli/argv.ts +25 -0
  213. package/src/cli/configure.ts +23 -21
  214. package/src/cli/doctor-panes.ts +124 -0
  215. package/src/cli/doctor-toolchain.ts +57 -0
  216. package/src/cli/doctor.ts +20 -1
  217. package/src/cli/eval-inventory.ts +436 -0
  218. package/src/cli/eval.ts +13 -0
  219. package/src/cli/evidence-detail.ts +88 -0
  220. package/src/cli/evidence-inventory.ts +183 -0
  221. package/src/cli/evidence.ts +30 -5
  222. package/src/cli/fleet-decisions.ts +69 -0
  223. package/src/cli/fleet-inspect.ts +334 -0
  224. package/src/cli/fleet-verify.ts +133 -0
  225. package/src/cli/fleet-view.ts +810 -0
  226. package/src/cli/fleet.ts +148 -37
  227. package/src/cli/index.ts +14 -2
  228. package/src/cli/interop-inspect.ts +128 -0
  229. package/src/cli/interop.ts +34 -0
  230. package/src/cli/panes.ts +35 -0
  231. package/src/cli/reset.ts +5 -2
  232. package/src/cli/run.ts +58 -0
  233. package/src/cli/skills-inventory.ts +185 -0
  234. package/src/cli/skills.ts +16 -13
  235. package/src/cli/tools.ts +321 -0
  236. package/src/cli/trace-inspect.ts +252 -0
  237. package/src/cli/trace.ts +23 -2
  238. package/src/cli/verifiers-inspect.ts +347 -0
  239. package/src/cli/verifiers.ts +9 -0
  240. package/src/core/bus-events.ts +4 -0
  241. package/src/core/config.ts +49 -0
  242. package/src/core/defaults.ts +93 -7
  243. package/src/core/response-schema.ts +44 -4
  244. package/src/core/theme-token-hex.ts +43 -0
  245. package/src/core/tool-names.ts +2 -1
  246. package/src/core/xdg.ts +1 -1
  247. package/src/domains/agents/fleets/build-review.md +0 -3
  248. package/src/domains/agents/fleets/build-test.md +0 -3
  249. package/src/domains/agents/result-contract-filesystem.ts +32 -0
  250. package/src/domains/agents/result-contract.ts +164 -35
  251. package/src/domains/config/classify.ts +3 -0
  252. package/src/domains/dispatch/admission-error.ts +9 -0
  253. package/src/domains/dispatch/admission.ts +22 -21
  254. package/src/domains/dispatch/capacity-lease.ts +21 -1
  255. package/src/domains/dispatch/council-topology.ts +398 -0
  256. package/src/domains/dispatch/extension.ts +222 -50
  257. package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
  258. package/src/domains/dispatch/fleet-plan.ts +7 -2
  259. package/src/domains/dispatch/fleet-run.ts +64 -1
  260. package/src/domains/dispatch/gate-decisions.ts +11 -1
  261. package/src/domains/dispatch/gate-role-prompts.ts +9 -0
  262. package/src/domains/dispatch/gate-topology.ts +289 -0
  263. package/src/domains/dispatch/index.ts +19 -0
  264. package/src/domains/dispatch/intent-compatibility.ts +330 -0
  265. package/src/domains/dispatch/intent.ts +85 -1
  266. package/src/domains/dispatch/reservation-store.ts +24 -4
  267. package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
  268. package/src/domains/dispatch/run-event-journal.ts +598 -0
  269. package/src/domains/dispatch/state.ts +45 -1
  270. package/src/domains/dispatch/types.ts +13 -0
  271. package/src/domains/dispatch/validation.ts +33 -8
  272. package/src/domains/eval/compare/compare.ts +3 -16
  273. package/src/domains/eval/inventory.ts +113 -0
  274. package/src/domains/eval/schema/serving.ts +31 -0
  275. package/src/domains/evidence/store.ts +6 -0
  276. package/src/domains/memory/index.ts +0 -1
  277. package/src/domains/memory/task-memory-policy.ts +6 -10
  278. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  279. package/src/domains/middleware/memory-intervention.ts +33 -21
  280. package/src/domains/mux/contract.ts +434 -0
  281. package/src/domains/mux/detect.ts +158 -0
  282. package/src/domains/mux/extension.ts +47 -0
  283. package/src/domains/mux/index.ts +96 -0
  284. package/src/domains/mux/manifest.ts +6 -0
  285. package/src/domains/mux/operations.ts +164 -0
  286. package/src/domains/mux/pane-registry.ts +90 -0
  287. package/src/domains/mux/protocol.ts +49 -0
  288. package/src/domains/mux/socket-client.ts +816 -0
  289. package/src/domains/mux/types.ts +222 -0
  290. package/src/domains/mux/viewer-command.ts +59 -0
  291. package/src/domains/mux/yazi/assets/init.lua +2 -0
  292. package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
  293. package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
  294. package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
  295. package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
  296. package/src/domains/mux/yazi/assets/yazi.toml +17 -0
  297. package/src/domains/mux/yazi/event-stream.ts +180 -0
  298. package/src/domains/mux/yazi/profile.ts +299 -0
  299. package/src/domains/mux/yazi/session.ts +228 -0
  300. package/src/domains/mux/yazi/theme.ts +30 -0
  301. package/src/domains/observability/cost.ts +21 -0
  302. package/src/domains/observability/index.ts +2 -0
  303. package/src/domains/observability/trace-store.ts +42 -0
  304. package/src/domains/providers/endpoint-capacity.ts +154 -22
  305. package/src/domains/providers/endpoint-slots-store.ts +189 -0
  306. package/src/domains/providers/extension.ts +20 -3
  307. package/src/domains/providers/index.ts +22 -0
  308. package/src/domains/providers/model-runtime-capabilities.ts +32 -0
  309. package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
  310. package/src/domains/providers/runtimes/builtins.ts +2 -0
  311. package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
  312. package/src/domains/providers/support.ts +1 -0
  313. package/src/domains/providers/target-model-cache.ts +124 -0
  314. package/src/domains/resources/index.ts +3 -0
  315. package/src/domains/resources/skills/loader.ts +33 -0
  316. package/src/domains/safety/action-classifier.ts +6 -0
  317. package/src/domains/toolchain/archive.ts +175 -0
  318. package/src/domains/toolchain/contract.ts +28 -0
  319. package/src/domains/toolchain/extension.ts +47 -0
  320. package/src/domains/toolchain/index.ts +39 -0
  321. package/src/domains/toolchain/install.ts +327 -0
  322. package/src/domains/toolchain/manifest.ts +8 -0
  323. package/src/domains/toolchain/paths.ts +34 -0
  324. package/src/domains/toolchain/registry.ts +265 -0
  325. package/src/domains/toolchain/remove.ts +218 -0
  326. package/src/domains/toolchain/resolve.ts +182 -0
  327. package/src/domains/toolchain/types.ts +113 -0
  328. package/src/domains/toolchain/version.ts +88 -0
  329. package/src/engine/acp/server.ts +413 -70
  330. package/src/engine/acp/types.ts +19 -1
  331. package/src/engine/claude/sdk-module.ts +98 -0
  332. package/src/engine/claude/sdk-runtime.ts +19 -11
  333. package/src/engine/tui-primitives.ts +21 -0
  334. package/src/engine/tui.ts +1 -0
  335. package/src/engine/worker-runtime.ts +2 -13
  336. package/src/entry/boot-options.ts +2 -0
  337. package/src/entry/orchestrator.ts +103 -5
  338. package/src/entry/panes-activation.ts +31 -0
  339. package/src/entry/with-panes.ts +20 -0
  340. package/src/interactive/context-overlay.ts +1 -0
  341. package/src/interactive/cost-overlay.ts +2 -0
  342. package/src/interactive/council-grid.ts +1 -3
  343. package/src/interactive/council.ts +11 -0
  344. package/src/interactive/dispatch-board.ts +26 -16
  345. package/src/interactive/interactive-application.ts +153 -6
  346. package/src/interactive/interactive-input-runtime.ts +7 -0
  347. package/src/interactive/interactive-slash-runtime.ts +36 -6
  348. package/src/interactive/memory-overlay.ts +1 -0
  349. package/src/interactive/modal-marker.ts +170 -0
  350. package/src/interactive/mux-bridge.ts +214 -0
  351. package/src/interactive/overlay-frame.ts +58 -2
  352. package/src/interactive/overlay-general-openers.ts +1 -0
  353. package/src/interactive/overlay-key-routing.ts +14 -3
  354. package/src/interactive/overlay-lifecycle.ts +19 -3
  355. package/src/interactive/overlay-model-selectors.ts +40 -3
  356. package/src/interactive/overlay-permission-lifecycle.ts +90 -22
  357. package/src/interactive/overlay-transitions.ts +18 -4
  358. package/src/interactive/overlays/agents.ts +1 -0
  359. package/src/interactive/overlays/ask-user.ts +136 -30
  360. package/src/interactive/overlays/auth-dialog.ts +1 -0
  361. package/src/interactive/overlays/context-reset.ts +1 -0
  362. package/src/interactive/overlays/cwd-fallback.ts +1 -0
  363. package/src/interactive/overlays/decisions.ts +11 -11
  364. package/src/interactive/overlays/extensions.ts +1 -0
  365. package/src/interactive/overlays/fleet-run-approval.ts +1 -0
  366. package/src/interactive/overlays/handoff-review.ts +1 -0
  367. package/src/interactive/overlays/help-reference.ts +2 -0
  368. package/src/interactive/overlays/interop.ts +1 -0
  369. package/src/interactive/overlays/library-install-confirm.ts +1 -0
  370. package/src/interactive/overlays/library-tabs.ts +28 -0
  371. package/src/interactive/overlays/list-overlay.ts +10 -1
  372. package/src/interactive/overlays/message-picker.ts +1 -0
  373. package/src/interactive/overlays/model-scope.ts +86 -0
  374. package/src/interactive/overlays/model-selector.ts +1 -0
  375. package/src/interactive/overlays/prompts.ts +1 -0
  376. package/src/interactive/overlays/session-selector.ts +1 -0
  377. package/src/interactive/overlays/settings-sections.ts +30 -0
  378. package/src/interactive/overlays/settings.ts +579 -44
  379. package/src/interactive/overlays/side-question.ts +1 -0
  380. package/src/interactive/overlays/skills-hub.ts +3 -11
  381. package/src/interactive/overlays/tree-selector.ts +1 -0
  382. package/src/interactive/pane-policy.ts +46 -0
  383. package/src/interactive/panes-runtime.ts +292 -0
  384. package/src/interactive/renderers/compaction-summary.ts +29 -0
  385. package/src/interactive/renderers/worker-entry.ts +122 -14
  386. package/src/interactive/slash-commands.ts +251 -15
  387. package/src/interactive/tasks-overlay.ts +1 -0
  388. package/src/interactive/theme/tokens.ts +3 -14
  389. package/src/interactive/turn-context.ts +47 -2
  390. package/src/interactive/view/artifacts.ts +109 -1
  391. package/src/interactive/view/view-overlay.ts +1 -0
  392. package/src/interactive/watch-pane.ts +152 -0
  393. package/src/interactive/worker-progress.ts +7 -1
  394. package/src/interactive/worker-receipts.ts +19 -1
  395. package/src/interactive/worker-stream.ts +5 -0
  396. package/src/interactive/yazi-bridge.ts +444 -0
  397. package/src/tools/bootstrap.ts +26 -2
  398. package/src/tools/builtin-tool-catalog.ts +15 -0
  399. package/src/tools/compete-worktrees.ts +83 -2
  400. package/src/tools/core-bootstrap.ts +2 -1
  401. package/src/tools/dispatch-admission.ts +14 -3
  402. package/src/tools/dispatch-arguments.ts +20 -20
  403. package/src/tools/dispatch-run-events.ts +134 -19
  404. package/src/tools/dispatch-runner.ts +29 -7
  405. package/src/tools/dispatch-types.ts +15 -3
  406. package/src/tools/dispatch.ts +1 -1
  407. package/src/tools/executables.ts +17 -14
  408. package/src/tools/observation.ts +54 -4
  409. package/src/tools/panes-surface.ts +38 -0
  410. package/src/tools/panes.ts +112 -0
  411. package/src/tools/policy.ts +10 -1
  412. package/src/tools/presentation.ts +1 -0
  413. package/dist/chunk-D73KXYPF.js +0 -37
  414. package/dist/chunk-MLOK6ZOS.js +0 -2888
  415. package/dist/chunk-YKOFT37S.js +0 -279
  416. package/dist/doctor-TWBWFK5V.js +0 -165
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import { createHash, randomBytes } from "node:crypto";
13
- import { type Dirent, existsSync, readdirSync, readFileSync } from "node:fs";
13
+ import { type Dirent, readdirSync, readFileSync } from "node:fs";
14
14
  import { isAbsolute, relative, resolve as resolvePath, sep } from "node:path";
15
15
  import { performance } from "node:perf_hooks";
16
16
  import { BusChannels, type DispatchCompletedPayload, type DispatchRunIdentity } from "../../core/bus-events.js";
@@ -58,6 +58,7 @@ import {
58
58
  import type { AgentsContract } from "../agents/contract.js";
59
59
  import type { AgentRecipe } from "../agents/recipe.js";
60
60
  import { validateRecipeResult } from "../agents/result-contract.js";
61
+ import { nodeResultContractFilesystem } from "../agents/result-contract-filesystem.js";
61
62
  import {
62
63
  type AgentAudience,
63
64
  type AgentCapabilityClass,
@@ -78,7 +79,7 @@ import {
78
79
  type CapabilityFlags,
79
80
  canonicalizeWireModelId,
80
81
  type EndpointCapacity,
81
- endpointCapacitiesForStatuses,
82
+ endpointCapacityFor,
82
83
  endpointCapacityForStatus,
83
84
  firstRuntimeResolutionError,
84
85
  isDispatchEligibleRuntime,
@@ -86,6 +87,7 @@ import {
86
87
  type ResolvedRuntimeTarget,
87
88
  type RuntimeApiFamily,
88
89
  type RuntimeDescriptor,
90
+ resolveEndpointCapacities,
89
91
  resolveModelCapabilities,
90
92
  resolveRuntimeTarget,
91
93
  runtimeResolutionWarnings,
@@ -112,6 +114,7 @@ import {
112
114
  routeValidationProjection,
113
115
  } from "./active-route-planner.js";
114
116
  import { admit, createCapacityAdmissionController, createLeaseSlotGuard } from "./admission.js";
117
+ import { AdmissionCanceledError } from "./admission-error.js";
115
118
  import { agentRouteCandidates } from "./agent-candidates.js";
116
119
  import { AGENT_LEDGER_PROMPT_MAX_CHARS, renderAgentLedger } from "./agent-ledger.js";
117
120
  import { publishAgentLedgerEntry, subscribeAgentLedger } from "./agent-ledger-hub.js";
@@ -236,6 +239,7 @@ import {
236
239
  import { createRouteObserver, type RouteObservationHandle, type RouteObserver } from "./route-observer.js";
237
240
  import { reduceRouteQuality } from "./route-quality.js";
238
241
  import { defaultRoutingIntent } from "./routing-intent.js";
242
+ import { attachRunEventJournalBridge, type RunEventJournalBridge } from "./run-event-journal-bridge.js";
239
243
  import { detectRunIdentity } from "./run-identity.js";
240
244
  import { type Ledger, newRunId, openLedger } from "./state.js";
241
245
  import {
@@ -358,6 +362,12 @@ interface ActiveRun {
358
362
  finalPromise: Promise<RunReceipt>;
359
363
  }
360
364
 
365
+ interface PendingCapacityAdmission {
366
+ identity: DispatchRunIdentity & { requestOrigin: DispatchRequestOrigin };
367
+ timing: RunPhaseMarks;
368
+ node: RunNodeIdentity | null;
369
+ }
370
+
361
371
  interface DispatchFinishContractSnapshot {
362
372
  assessment: FinishContractAssessment;
363
373
  rigor: Rigor;
@@ -398,6 +408,15 @@ export interface DispatchBundleOptions {
398
408
  collectReproducibility?: typeof collectReproducibilityMetadata;
399
409
  /** Observer injection seam. Production constructs the durable observer. */
400
410
  routeObserver?: RouteObserver;
411
+ /**
412
+ * Write the durable run event journal for every run this bundle dispatches.
413
+ * Off by default and turned on by the three composition roots
414
+ * (src/entry/orchestrator.ts, src/cli/run.ts, src/cli/fleet.ts), because the
415
+ * process that owns a bundle also decides who owns the journal file: a
416
+ * composed process routes `registerAllTools`' event registry to
417
+ * `journal: null` so a tool-path run is transcribed once, not twice.
418
+ */
419
+ journalRunEvents?: boolean;
401
420
  }
402
421
 
403
422
  const DEFAULT_HEARTBEAT_INTERVAL_MS = 1000;
@@ -2419,6 +2438,7 @@ export function createDispatchBundle(
2419
2438
  let ledger: Ledger | null = null;
2420
2439
  let heartbeatTimer: ReturnType<typeof setInterval> | null = null;
2421
2440
  const active = new Map<string, ActiveRun>();
2441
+ const pendingCapacity = new Map<string, PendingCapacityAdmission>();
2422
2442
  const targetCooldowns = new Map<string, { until: number; reason: string }>();
2423
2443
  const ownedReservations = new Set<string>();
2424
2444
  /**
@@ -2459,19 +2479,37 @@ export function createDispatchBundle(
2459
2479
  }),
2460
2480
  );
2461
2481
 
2482
+ /**
2483
+ * Every endpoint the configured fleet can reach.
2484
+ *
2485
+ * Deliberately resolved from the configured targets as well as the probed
2486
+ * statuses. A target whose status has not been built yet contributed no key,
2487
+ * an absent key carries no limit, and reservation planning skips a dimension
2488
+ * it has no limit for, so admission against a single-slot server used to fail
2489
+ * open for whoever asked first after boot.
2490
+ */
2491
+ function configuredEndpointCapacities(): Readonly<Record<string, EndpointCapacity>> {
2492
+ return resolveEndpointCapacities({
2493
+ statuses: providers.list(),
2494
+ targets: getEffectiveSettings()?.targets ?? [],
2495
+ runtimeFor: (runtimeId) => providers.getRuntime(runtimeId),
2496
+ });
2497
+ }
2498
+
2462
2499
  function configuredEndpointLimits(): Readonly<Record<string, number>> {
2463
- return Object.fromEntries(
2464
- Object.entries(endpointCapacitiesForStatuses(providers.list())).map(([key, value]) => [key, value.limit]),
2465
- );
2500
+ return Object.fromEntries(Object.entries(configuredEndpointCapacities()).map(([key, value]) => [key, value.limit]));
2466
2501
  }
2467
2502
 
2468
2503
  function endpointCapacityForTarget(targetId: string): EndpointCapacity | null {
2469
2504
  const status = providers.list().find((entry) => entry.target.id === targetId);
2470
- if (status === undefined) return null;
2471
- const endpoint = endpointCapacityForStatus(status);
2505
+ const target = status?.target ?? providers.getTarget(targetId);
2506
+ if (target === null || target === undefined) return null;
2507
+ const endpoint =
2508
+ status === undefined
2509
+ ? endpointCapacityFor({ target, runtime: providers.getRuntime(target.runtime) })
2510
+ : endpointCapacityForStatus(status);
2472
2511
  if (endpoint === null) return null;
2473
- const configured = endpointCapacitiesForStatuses(providers.list())[endpoint.key];
2474
- return configured ?? endpoint;
2512
+ return configuredEndpointCapacities()[endpoint.key] ?? endpoint;
2475
2513
  }
2476
2514
 
2477
2515
  function reservationCapacitySnapshot(settings: EffectiveSettings): ReservationCapacitySnapshot {
@@ -2564,6 +2602,34 @@ export function createDispatchBundle(
2564
2602
  return scheduling.maxWorkers?.() ?? (configured === "auto" || configured === undefined ? 4 : Math.max(1, configured));
2565
2603
  }
2566
2604
 
2605
+ function publishCapacityQueued(
2606
+ identity: DispatchRunIdentity & { requestOrigin: DispatchRequestOrigin },
2607
+ timing: RunPhaseMarks,
2608
+ node: RunNodeIdentity | null,
2609
+ ): void {
2610
+ pendingCapacity.set(identity.runId, { identity, timing, node });
2611
+ context.bus.emit(BusChannels.DispatchEnqueued, identity);
2612
+ }
2613
+
2614
+ function publishCapacityAdmissionFailure(
2615
+ identity: DispatchRunIdentity & { requestOrigin: DispatchRequestOrigin },
2616
+ error: unknown,
2617
+ ): void {
2618
+ const detail = error instanceof Error ? error.message : String(error);
2619
+ const outcome: RunOutcome =
2620
+ error instanceof AdmissionCanceledError
2621
+ ? "canceled"
2622
+ : /admission timed out/u.test(detail)
2623
+ ? "timed_out"
2624
+ : "denied_by_policy";
2625
+ context.bus.emit(BusChannels.DispatchFailed, {
2626
+ ...identity,
2627
+ outcome,
2628
+ outcomeDetail: detail,
2629
+ reason: outcome,
2630
+ });
2631
+ }
2632
+
2567
2633
  async function admitAssignmentCapacity(
2568
2634
  req: DispatchRequest,
2569
2635
  nodeId: string,
@@ -2572,7 +2638,8 @@ export function createDispatchBundle(
2572
2638
  ) {
2573
2639
  const queuedAt = now();
2574
2640
  timing.queuedAt = new Date(queuedAt).toISOString();
2575
- const assignmentId = req.lineage?.rootRunId ?? `pending-${queuedAt.toString(36)}-${randomBytes(6).toString("hex")}`;
2641
+ const assignmentId =
2642
+ req.lineage?.rootRunId ?? req.runIdHint ?? `pending-${queuedAt.toString(36)}-${randomBytes(6).toString("hex")}`;
2576
2643
  const requestedAt = Date.parse(timing.requestedAt ?? timing.queuedAt);
2577
2644
  const deadlineAt = req.assignmentDeadlineAt ?? requestedAt + (req.routingIntent?.deadlineMs ?? 60_000);
2578
2645
  if (req.lineage === undefined) await registerAssignment(assignmentId);
@@ -2919,6 +2986,10 @@ export function createDispatchBundle(
2919
2986
  depth: run.lineage.depth,
2920
2987
  },
2921
2988
  };
2989
+ // A run-id hint names only the first attempt (and, for task worktrees,
2990
+ // the worktree it created). A retry shares the assignment lineage but
2991
+ // must receive its own ledger/run identity.
2992
+ delete retryReq.runIdHint;
2922
2993
  const reasonKey = retryReasonKey(run.lineage.rootRunId, attempt);
2923
2994
  retryReasons.set(reasonKey, reason);
2924
2995
  try {
@@ -3566,7 +3637,29 @@ export function createDispatchBundle(
3566
3637
 
3567
3638
  assertBudgetAdmitsRoute(req, { rates: null, provenance: "unknown" }, settings);
3568
3639
 
3569
- const capacityLease = await admitAssignmentCapacity(req, "local", timing, null);
3640
+ const queuedIdentity =
3641
+ req.lineage === undefined && req.runIdHint !== undefined
3642
+ ? {
3643
+ runId: req.runIdHint,
3644
+ agentId: req.agentId,
3645
+ task: req.task,
3646
+ requestOrigin: lifecycle.requestOrigin,
3647
+ targetId,
3648
+ wireModelId,
3649
+ runtimeId,
3650
+ runtimeKind: "acp-delegation" as const,
3651
+ }
3652
+ : null;
3653
+ if (queuedIdentity !== null) publishCapacityQueued(queuedIdentity, timing, null);
3654
+ let capacityLease: Awaited<ReturnType<typeof admitAssignmentCapacity>>;
3655
+ try {
3656
+ capacityLease = await admitAssignmentCapacity(req, "local", timing, null);
3657
+ } catch (error) {
3658
+ if (queuedIdentity !== null) publishCapacityAdmissionFailure(queuedIdentity, error);
3659
+ throw error;
3660
+ } finally {
3661
+ if (queuedIdentity !== null) pendingCapacity.delete(queuedIdentity.runId);
3662
+ }
3570
3663
  const leaseSlot = createLeaseSlotGuard(capacityAdmission, capacityLease.leaseId, req.lineage !== undefined);
3571
3664
 
3572
3665
  // Resolve the ledger before starting the ACP process: an external agent
@@ -3774,8 +3867,10 @@ export function createDispatchBundle(
3774
3867
  runIdForPermissionAudit = envelope.id;
3775
3868
  lineage = lineageFor(req, envelope.id);
3776
3869
  if (req.lineage === undefined) {
3777
- capacityAdmission.rename(capacityLease.leaseId, lineage.rootRunId);
3778
- await renameStoredAssignment(capacityLease.assignmentId, lineage.rootRunId);
3870
+ if (capacityLease.assignmentId !== lineage.rootRunId) {
3871
+ capacityAdmission.rename(capacityLease.leaseId, lineage.rootRunId);
3872
+ await renameStoredAssignment(capacityLease.assignmentId, lineage.rootRunId);
3873
+ }
3779
3874
  leaseSlot.transferToAssignment();
3780
3875
  }
3781
3876
  identity = detectRunIdentity();
@@ -3801,16 +3896,18 @@ export function createDispatchBundle(
3801
3896
  // One durable write at start so sibling processes (clio-coder fleet status)
3802
3897
  // can observe the running row; finalization persists the terminal state.
3803
3898
  await ledgerRef.persist();
3804
- context.bus.emit(BusChannels.DispatchEnqueued, {
3805
- runId: envelope.id,
3806
- agentId: req.agentId,
3807
- task: req.task,
3808
- requestOrigin: lifecycle.requestOrigin,
3809
- targetId,
3810
- wireModelId,
3811
- runtimeId,
3812
- runtimeKind: "acp-delegation",
3813
- });
3899
+ if (req.lineage !== undefined) {
3900
+ context.bus.emit(BusChannels.DispatchEnqueued, {
3901
+ runId: envelope.id,
3902
+ agentId: req.agentId,
3903
+ task: req.task,
3904
+ requestOrigin: lifecycle.requestOrigin,
3905
+ targetId,
3906
+ wireModelId,
3907
+ runtimeId,
3908
+ runtimeKind: "acp-delegation",
3909
+ });
3910
+ }
3814
3911
  context.bus.emit(BusChannels.DispatchStarted, {
3815
3912
  runId: envelope.id,
3816
3913
  agentId: req.agentId,
@@ -4268,6 +4365,10 @@ export function createDispatchBundle(
4268
4365
  throw new Error(`dispatch: invalid spec: ${validated.errors.join("; ")}`);
4269
4366
  }
4270
4367
  req = validation.restore(validated.spec);
4368
+ // A top-level run needs its stable identity before it can wait for
4369
+ // capacity. The board can then render the assignment as queued and the
4370
+ // same id becomes the ledger row once its slot opens.
4371
+ if (req.lineage === undefined && req.runIdHint === undefined) req = { ...req, runIdHint: newRunId() };
4271
4372
  let activeRouteObservation: RouteObservationHandle | null = null;
4272
4373
  if (req.delegationAgentId === undefined) {
4273
4374
  const recipe = agents.get(req.agentId);
@@ -4395,7 +4496,41 @@ export function createDispatchBundle(
4395
4496
  shadow: () => observeShadowRoute(req, placed, settings),
4396
4497
  });
4397
4498
 
4398
- const capacityLease = await admitAssignmentCapacity(req, placement?.node.id ?? "local", timing, endpoint);
4499
+ const queuedIdentity =
4500
+ req.lineage === undefined && req.runIdHint !== undefined
4501
+ ? {
4502
+ runId: req.runIdHint,
4503
+ agentId: req.agentId,
4504
+ task: req.task,
4505
+ agentAudience: lifecycle.agentAudience,
4506
+ requestOrigin: lifecycle.requestOrigin,
4507
+ targetId: lifecycle.target.target.id,
4508
+ wireModelId: lifecycle.target.wireModelId,
4509
+ runtimeId: lifecycle.target.runtime.id,
4510
+ runtimeKind: lifecycle.runtimeKind,
4511
+ budget: lifecycle.budgetEnvelope,
4512
+ ...(endpoint !== null ? { endpoint: { key: endpoint.key, label: endpoint.label, limit: endpoint.limit } } : {}),
4513
+ ...(placement !== null ? { node: placement.node.id } : {}),
4514
+ ...(req.gate !== undefined ? { gate: { role: req.gate.role, cycle: req.gate.cycle } } : {}),
4515
+ ...(req.council !== undefined ? { council: req.council } : {}),
4516
+ ...(req.reroutes !== undefined && req.reroutes.length > 0 ? { rerouteCount: req.reroutes.length } : {}),
4517
+ ...(lifecycle.target.modelCapabilities !== undefined &&
4518
+ lifecycle.target.modelCapabilities !== null &&
4519
+ lifecycle.target.modelCapabilities.contextWindow > 0
4520
+ ? { contextWindow: lifecycle.target.modelCapabilities.contextWindow }
4521
+ : {}),
4522
+ }
4523
+ : null;
4524
+ if (queuedIdentity !== null) publishCapacityQueued(queuedIdentity, timing, placement?.node ?? null);
4525
+ let capacityLease: Awaited<ReturnType<typeof admitAssignmentCapacity>>;
4526
+ try {
4527
+ capacityLease = await admitAssignmentCapacity(req, placement?.node.id ?? "local", timing, endpoint);
4528
+ } catch (error) {
4529
+ if (queuedIdentity !== null) publishCapacityAdmissionFailure(queuedIdentity, error);
4530
+ throw error;
4531
+ } finally {
4532
+ if (queuedIdentity !== null) pendingCapacity.delete(queuedIdentity.runId);
4533
+ }
4399
4534
  const leaseSlot = createLeaseSlotGuard(capacityAdmission, capacityLease.leaseId, req.lineage !== undefined);
4400
4535
 
4401
4536
  const ledgerRef = (() => {
@@ -4664,6 +4799,7 @@ export function createDispatchBundle(
4664
4799
  ...(ruleId !== null ? { ruleId } : {}),
4665
4800
  ...(policySource !== null ? { policySource } : {}),
4666
4801
  ...(typeof event.payload.timeoutMs === "number" ? { timeoutMs: event.payload.timeoutMs } : {}),
4802
+ fallback: spec.escalation?.fallback ?? "deny",
4667
4803
  escalation: true,
4668
4804
  });
4669
4805
  }
@@ -4738,6 +4874,7 @@ export function createDispatchBundle(
4738
4874
  decidedBy,
4739
4875
  actionClass,
4740
4876
  reason,
4877
+ ...(source === "timeout" ? { fallback: spec.escalation?.fallback ?? "deny" } : {}),
4741
4878
  ...(runIdForPermissionAudit !== null ? { requestedBy: runIdForPermissionAudit } : {}),
4742
4879
  });
4743
4880
  }
@@ -4793,8 +4930,10 @@ export function createDispatchBundle(
4793
4930
  runIdForPermissionAudit = envelope.id;
4794
4931
  lineage = lineageFor(req, envelope.id);
4795
4932
  if (req.lineage === undefined) {
4796
- capacityAdmission.rename(capacityLease.leaseId, lineage.rootRunId);
4797
- await renameStoredAssignment(capacityLease.assignmentId, lineage.rootRunId);
4933
+ if (capacityLease.assignmentId !== lineage.rootRunId) {
4934
+ capacityAdmission.rename(capacityLease.leaseId, lineage.rootRunId);
4935
+ await renameStoredAssignment(capacityLease.assignmentId, lineage.rootRunId);
4936
+ }
4798
4937
  leaseSlot.transferToAssignment();
4799
4938
  }
4800
4939
  if (agentLedgerId !== null) {
@@ -4855,18 +4994,20 @@ export function createDispatchBundle(
4855
4994
  ? { contextWindow: lifecycle.target.modelCapabilities.contextWindow }
4856
4995
  : {}),
4857
4996
  };
4858
- context.bus.emit(BusChannels.DispatchEnqueued, {
4859
- runId: envelope.id,
4860
- agentId: req.agentId,
4861
- task: req.task,
4862
- agentAudience: lifecycle.agentAudience,
4863
- requestOrigin: lifecycle.requestOrigin,
4864
- targetId: lifecycle.target.target.id,
4865
- wireModelId: lifecycle.target.wireModelId,
4866
- runtimeId: lifecycle.target.runtime.id,
4867
- runtimeKind: lifecycle.runtimeKind,
4868
- ...fleetIdentity,
4869
- });
4997
+ if (req.lineage !== undefined) {
4998
+ context.bus.emit(BusChannels.DispatchEnqueued, {
4999
+ runId: envelope.id,
5000
+ agentId: req.agentId,
5001
+ task: req.task,
5002
+ agentAudience: lifecycle.agentAudience,
5003
+ requestOrigin: lifecycle.requestOrigin,
5004
+ targetId: lifecycle.target.target.id,
5005
+ wireModelId: lifecycle.target.wireModelId,
5006
+ runtimeId: lifecycle.target.runtime.id,
5007
+ runtimeKind: lifecycle.runtimeKind,
5008
+ ...fleetIdentity,
5009
+ });
5010
+ }
4870
5011
  context.bus.emit(BusChannels.DispatchStarted, {
4871
5012
  runId: envelope.id,
4872
5013
  agentId: req.agentId,
@@ -5295,18 +5436,7 @@ export function createDispatchBundle(
5295
5436
  cwd: lifecycle.cwd,
5296
5437
  networkAllowed: lifecycle.admission.allowedTools.includes(ToolNames.WebFetch),
5297
5438
  observedRunEffects,
5298
- filesystem: {
5299
- readFile(filePath) {
5300
- try {
5301
- return readFileSync(filePath, "utf8");
5302
- } catch {
5303
- return null;
5304
- }
5305
- },
5306
- pathExists(filePath) {
5307
- return existsSync(filePath);
5308
- },
5309
- },
5439
+ filesystem: nodeResultContractFilesystem(),
5310
5440
  });
5311
5441
  const resultValidation = resultContract?.applicable === true ? resultContract.validation : null;
5312
5442
  if (finalOutcome === "succeeded" && resultValidation?.conformance === "fail") {
@@ -6154,8 +6284,15 @@ export function createDispatchBundle(
6154
6284
  return receipt;
6155
6285
  }
6156
6286
 
6287
+ let journalBridge: RunEventJournalBridge | null = null;
6288
+
6157
6289
  const extension: DomainExtension = {
6158
6290
  async start() {
6291
+ // The journal subscribes before anything can dispatch. It rides the
6292
+ // domain's own progress and terminal channels, so it covers a run
6293
+ // whose caller iterates the handle itself (every operator path) as
6294
+ // well as one drained by the dispatch tool's event registry.
6295
+ if (options?.journalRunEvents === true) journalBridge = attachRunEventJournalBridge(context.bus);
6159
6296
  // No in-memory executor survives a process restart, so every active
6160
6297
  // side-store lease from an earlier bundle is orphaned and must expire.
6161
6298
  cleanupDispatchReservations({ startup: true, nowMs: now() });
@@ -6221,6 +6358,10 @@ export function createDispatchBundle(
6221
6358
  for (const ownerId of ownedReservations) rollbackDispatchReservation(ownerId, now());
6222
6359
  ownedReservations.clear();
6223
6360
  await Promise.allSettled([...assignmentWrites]);
6361
+ // After drain(), so the last run's terminal line is written before the
6362
+ // bridge stops listening.
6363
+ journalBridge?.stop();
6364
+ journalBridge = null;
6224
6365
  },
6225
6366
  };
6226
6367
 
@@ -6248,6 +6389,26 @@ export function createDispatchBundle(
6248
6389
  const running: DispatchSnapshot["running"] = [];
6249
6390
  const totals = { ...finalizedTotals };
6250
6391
  const costAmounts = [...finalizedCosts];
6392
+ for (const pending of pendingCapacity.values()) {
6393
+ const startedAt = pending.timing.queuedAt ?? pending.timing.requestedAt ?? new Date(tickNow).toISOString();
6394
+ running.push({
6395
+ runId: pending.identity.runId,
6396
+ agentId: pending.identity.agentId,
6397
+ ...(pending.identity.task !== undefined ? { task: pending.identity.task } : {}),
6398
+ ...(pending.identity.budget !== undefined ? { budget: pending.identity.budget } : {}),
6399
+ runtimeKind: pending.identity.runtimeKind,
6400
+ outcomePhase: "queued",
6401
+ heartbeat: "n/a",
6402
+ lineage: { parentRunId: null, rootRunId: pending.identity.runId, attempt: 0, depth: 0 },
6403
+ startedAt,
6404
+ elapsedMs: 0,
6405
+ timing: deriveRunPhaseDurations(pending.timing, startedAt, new Date(tickNow).toISOString()),
6406
+ tokens: { input: 0, output: 0, total: 0 },
6407
+ costUsd: 0,
6408
+ costProvenance: "unknown",
6409
+ node: pending.node === null ? null : { ...pending.node },
6410
+ });
6411
+ }
6251
6412
  for (const run of active.values()) {
6252
6413
  let heartbeat: "alive" | "stale" | "dead" | "n/a" = "n/a";
6253
6414
  if (run.heartbeatAt && Number.isFinite(heartbeatMonotonicAt(run.heartbeatAt))) {
@@ -6426,6 +6587,17 @@ export function createDispatchBundle(
6426
6587
  },
6427
6588
  abort(runId, reason) {
6428
6589
  const rootRunId = assignmentRootFor(runId);
6590
+ const queued = pendingCapacity.get(rootRunId);
6591
+ if (queued !== undefined && capacityAdmission.cancel(rootRunId)) {
6592
+ persistAssignment(cancelStoredAssignment(rootRunId), `${rootRunId}:cancel-queued`);
6593
+ context.bus.emit(BusChannels.RunAborted, {
6594
+ source: "dispatch_abort",
6595
+ runId: rootRunId,
6596
+ startedAt: null,
6597
+ elapsedMs: null,
6598
+ reason: reason?.detail ?? "operator abort while waiting for an endpoint slot",
6599
+ });
6600
+ }
6429
6601
  const assignment = assignments.get(rootRunId);
6430
6602
  if (assignment?.status === "running") {
6431
6603
  assignments.cancel(assignment.id);
@@ -0,0 +1,62 @@
1
+ /**
2
+ * What one fleet node is told about its own answer.
3
+ *
4
+ * A fleet contract renders a single prompt body and the plan compiler gives it
5
+ * to every agent node, because the body describes the whole chain and each node
6
+ * does one part of it. That is fine for the work description and wrong for the
7
+ * answer: nodes in the same chain hold different result contracts, so a body
8
+ * that names one contract names the wrong one for every other node. A loop's
9
+ * check node is where the mismatch is fatal rather than merely untidy. It is
10
+ * dispatched with `verifier-report` as its expected contract, and in
11
+ * `build-review` and `build-test` it received a body ending in "Answer with
12
+ * your `mutation-report`". The verifier complied with the instruction it was
13
+ * given, the gate held it to the schema that instruction never mentioned, and
14
+ * both were behaving correctly: every review cycle in those two fleets ended in
15
+ * `review gate produced no structured verdict` and the bounded revise loop was
16
+ * unresolvable by construction.
17
+ *
18
+ * So each node states its own contract, appended to the shared body, and the
19
+ * precedence line settles the conflict explicitly rather than leaving it to the
20
+ * model to guess which of two shapes the run will actually validate. This is
21
+ * the same remedy `COUNCIL_VOTE_MEMBER_DIRECTIVE` applies to a voting council
22
+ * member, for the same reason and with the same shape of failure behind it
23
+ * (#230): a run whose postcondition differs from the shape its prompt names
24
+ * fails on every input, not intermittently.
25
+ *
26
+ * The shape itself is quoted from `resultContractShape`, the one place a
27
+ * contract's wire example is written, so this directive cannot drift from the
28
+ * validator that judges the answer.
29
+ */
30
+
31
+ import { type ResultContract, resultContractShape } from "../agents/result-contract.js";
32
+
33
+ /**
34
+ * The answer directive for a node holding this contract, or null when the kind
35
+ * alone does not fix the shape.
36
+ *
37
+ * `architect-plan` names the path it must write, and a plan compiler resolving
38
+ * agents holds only the contract's kind. Inventing a path to render would state
39
+ * a location the validator does not check, so that kind gets no directive and
40
+ * its recipe keeps sole authority over the shape. Every other kind is fully
41
+ * determined by its kind and can be quoted exactly.
42
+ */
43
+ export function fleetNodeAnswerDirective(kind: ResultContract["kind"]): string | null {
44
+ if (kind === "architect-plan") return null;
45
+ return [
46
+ `Your result contract for this step is \`${kind}\`.`,
47
+ "The task above describes the whole chain. Any result shape it states belongs to the step that produces it, and does not apply to you.",
48
+ `End with exactly this shape and nothing else: ${resultContractShape({ kind })}`,
49
+ // The wire example carries literal names and evidence, and a small model
50
+ // handed one on a first attempt copies them: the first run of this
51
+ // directive came back claiming `npm run typecheck` / `exit 0` in the same
52
+ // breath as admitting it could not run a command. The fields are the
53
+ // contract; the values in the example are not.
54
+ "Its field values are an example. Fill them with what this run actually produced or observed, and never report a name or evidence you did not.",
55
+ ].join("\n");
56
+ }
57
+
58
+ /** The shared body plus the node's own answer directive. */
59
+ export function renderFleetNodeTask(task: string, kind: ResultContract["kind"]): string {
60
+ const directive = fleetNodeAnswerDirective(kind);
61
+ return directive === null ? task : `${task}\n\n${directive}`;
62
+ }
@@ -32,6 +32,7 @@ import {
32
32
  type ExecutionPlanStepInput,
33
33
  } from "./execution-plan.js";
34
34
  import type { ExecutionRole } from "./execution-role.js";
35
+ import { renderFleetNodeTask } from "./fleet-node-prompt.js";
35
36
 
36
37
  /** Where an agent node sits, so the caller can resolve its role and authority. */
37
38
  export interface FleetPlanAgentContext {
@@ -58,7 +59,11 @@ export interface FleetPlanAgentResolution {
58
59
 
59
60
  export interface CompileFleetPlanInput {
60
61
  contract: FleetContract;
61
- /** Rendered prompt body; every agent node carries it as its task. */
62
+ /**
63
+ * Rendered prompt body. It describes the whole chain, so every agent node
64
+ * carries it, followed by that node's own answer directive: the nodes hold
65
+ * different result contracts and the body can only ever name one of them.
66
+ */
62
67
  task: string;
63
68
  resolveAgent(context: FleetPlanAgentContext): FleetPlanAgentResolution;
64
69
  }
@@ -143,7 +148,7 @@ export function compileFleetExecutionPlan(input: CompileFleetPlanInput): Executi
143
148
  agentId: context.agentId,
144
149
  scope: context.scope,
145
150
  dependencies: [...dependencies],
146
- task,
151
+ task: renderFleetNodeTask(task, resolved.expectedResultContract),
147
152
  expectedResultContract: resolved.expectedResultContract,
148
153
  requestedAuthority: resolved.requestedAuthority,
149
154
  approvedAuthority: resolved.approvedAuthority,