@iowarp/clio-coder 0.3.6 → 0.3.8

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 (323) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +22 -6
  3. package/dist/{acp-2BEHC4DL.js → acp-U67UHUK2.js} +14 -14
  4. package/dist/{agents-LNNFTM53.js → agents-YU6SGALZ.js} +42 -35
  5. package/dist/assets/codewiki.json +1 -1
  6. package/dist/{auth-KXXFI2VS.js → auth-5ZPJOIVG.js} +32 -24
  7. package/dist/builtins-C6JMZVV6.js +17 -0
  8. package/dist/{chunk-E25LMLRW.js → chunk-26LEYJZH.js} +2 -2
  9. package/dist/{chunk-TSHXZTOQ.js → chunk-2HEJ2F35.js} +5 -5
  10. package/dist/{chunk-PBTHKCPN.js → chunk-2HFZQUHL.js} +7 -7
  11. package/dist/{chunk-FO5ZOVUY.js → chunk-3BINW3FP.js} +5 -5
  12. package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
  13. package/dist/{chunk-CKXWIANG.js → chunk-4SPRNWDE.js} +18 -16
  14. package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
  15. package/dist/{chunk-XF5N4U5A.js → chunk-5DHKRSMQ.js} +9 -8
  16. package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
  17. package/dist/{chunk-EKY57CSP.js → chunk-5H3GB5BO.js} +68 -772
  18. package/dist/{chunk-6XXKFVSN.js → chunk-5Q2VVUKB.js} +4 -4
  19. package/dist/{chunk-DJVECN66.js → chunk-7RFXX52T.js} +295 -3705
  20. package/dist/{chunk-ZXF4XRKW.js → chunk-7RGZWPB6.js} +158 -8
  21. package/dist/{chunk-FYYLNIL5.js → chunk-A2NJGIB3.js} +2 -2
  22. package/dist/{chunk-XXQNGV4M.js → chunk-A3WNZD3P.js} +548 -72
  23. package/dist/{chunk-VEZEGCGW.js → chunk-B5CSFE7B.js} +23 -21
  24. package/dist/{chunk-2SFS6XQE.js → chunk-DGSYXYMX.js} +3 -2
  25. package/dist/chunk-DR52UMZW.js +21 -0
  26. package/dist/{chunk-ZWLZP4ZT.js → chunk-DYIM5TJT.js} +98 -12
  27. package/dist/{chunk-QKMUKYO7.js → chunk-E77JEWSD.js} +270 -125
  28. package/dist/{chunk-LYF7OHWH.js → chunk-EMYUUSFG.js} +12 -467
  29. package/dist/{chunk-4VP4KH3K.js → chunk-EQ63NRB7.js} +8 -8
  30. package/dist/chunk-FBVTI2TJ.js +518 -0
  31. package/dist/{chunk-R46L2BIR.js → chunk-FHJEP5SW.js} +19 -25
  32. package/dist/{chunk-WR67VIZY.js → chunk-GN57SG4G.js} +66 -8
  33. package/dist/{chunk-RD5U66HV.js → chunk-GPIEI3LY.js} +9 -9
  34. package/dist/{chunk-PCZJO5TI.js → chunk-GU2UIAFZ.js} +13 -178
  35. package/dist/chunk-GWS3VEIW.js +195 -0
  36. package/dist/chunk-H7IXIC72.js +103 -0
  37. package/dist/{chunk-3BPUFZDL.js → chunk-HLE42MG7.js} +3 -3
  38. package/dist/{chunk-24I7BN55.js → chunk-IFBNV6H6.js} +3 -3
  39. package/dist/{chunk-QNQHSOLF.js → chunk-IGWKHNIQ.js} +114 -55
  40. package/dist/chunk-IIZWH4XA.js +172 -0
  41. package/dist/{chunk-AD2SYQYC.js → chunk-IJ7RPIYJ.js} +124 -6
  42. package/dist/chunk-J3YUBZWY.js +382 -0
  43. package/dist/{chunk-5JGRAMKL.js → chunk-JOZYP4GM.js} +8 -6
  44. package/dist/{chunk-OH3TOQTB.js → chunk-K4XHGFR5.js} +751 -15
  45. package/dist/{chunk-EYPA3EGJ.js → chunk-KTYTFRMB.js} +178 -14
  46. package/dist/chunk-LU7P4LHA.js +33 -0
  47. package/dist/chunk-ME6CCNFO.js +108 -0
  48. package/dist/chunk-MXKJU4JB.js +1100 -0
  49. package/dist/{chunk-RY3LY4J5.js → chunk-N22QMJKY.js} +21 -18
  50. package/dist/chunk-NMPKI6XL.js +3006 -0
  51. package/dist/chunk-NUGM5KR6.js +165 -0
  52. package/dist/{chunk-22NAGB7X.js → chunk-P43ETTHK.js} +5 -94
  53. package/dist/{chunk-NILBFAPG.js → chunk-PMDBGQSJ.js} +2 -2
  54. package/dist/chunk-PT7HYKEM.js +165 -0
  55. package/dist/chunk-RVG5JXAL.js +41 -0
  56. package/dist/{chunk-GEYXPTRF.js → chunk-RWSI4YD7.js} +2 -2
  57. package/dist/{chunk-4BPJXDWC.js → chunk-TANS5ZJS.js} +35 -19
  58. package/dist/{verifiers-NCBTHHN2.js → chunk-TB5666IT.js} +67 -324
  59. package/dist/{chunk-QM3F2GKX.js → chunk-TLQJPP24.js} +7927 -8088
  60. package/dist/{chunk-G7MUEIGA.js → chunk-TT36MB5S.js} +2 -1
  61. package/dist/chunk-TTHACPOM.js +961 -0
  62. package/dist/{chunk-6US73PDB.js → chunk-TYPGUK6W.js} +7 -7
  63. package/dist/{chunk-MFFY33HR.js → chunk-U6MBIEMB.js} +554 -209
  64. package/dist/chunk-VAWNZU7Z.js +242 -0
  65. package/dist/{chunk-IR4CFBFN.js → chunk-VCBR6CU7.js} +12 -12
  66. package/dist/{chunk-WHJYKASB.js → chunk-VHN4MY6O.js} +2 -2
  67. package/dist/{chunk-XYDYPRZI.js → chunk-VWZOAB7K.js} +10 -10
  68. package/dist/{chunk-ZRGEBJ4T.js → chunk-WLFILSD5.js} +48 -48
  69. package/dist/{chunk-K7T3E2SR.js → chunk-WNIJTQQK.js} +12 -11
  70. package/dist/{chunk-CYQKWTG3.js → chunk-WSB3FPX7.js} +68 -20
  71. package/dist/{chunk-KHSFENX2.js → chunk-WWCZ5F23.js} +116 -14
  72. package/dist/{chunk-XE2VEJHX.js → chunk-WXY7KU3G.js} +2 -2
  73. package/dist/{chunk-PPAMZ32Z.js → chunk-XK56QHLX.js} +6 -1
  74. package/dist/{chunk-KOHPCX4K.js → chunk-XWSF374K.js} +5 -5
  75. package/dist/{chunk-CJUB2JJ2.js → chunk-YS5VLNH5.js} +10 -10
  76. package/dist/{chunk-ZZMN5OM4.js → chunk-ZNLWCMVZ.js} +2 -2
  77. package/dist/{chunk-WHGPSPT5.js → chunk-ZVJ5BLO2.js} +2 -2
  78. package/dist/cli/index.js +33 -31
  79. package/dist/{clio-M2KGYUFZ.js → clio-QVTYJ57A.js} +10 -10
  80. package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +5 -5
  81. package/dist/codewiki/build-worker.js +4 -4
  82. package/dist/{components-5TTYYX6G.js → components-ZFA3SAER.js} +9 -9
  83. package/dist/{config-XUUYQIWO.js → config-LW5IJFQN.js} +65 -55
  84. package/dist/{configure-IHJ7YOMV.js → configure-7XIZCOU4.js} +29 -24
  85. package/dist/{context-75MIWW3U.js → context-L3WL3X7K.js} +54 -43
  86. package/dist/{context-ZQ7SIFJV.js → context-N52ZA626.js} +30 -14
  87. package/dist/{context-74JLXAWD.js → context-Y6Y7QPR6.js} +12 -12
  88. package/dist/{context-clear-GYKWNUML.js → context-clear-MBQRLSDQ.js} +54 -43
  89. package/dist/{context-index-SSR5ECNE.js → context-index-HVMFQHK3.js} +5 -5
  90. package/dist/{context-working-set-UX5KEP4J.js → context-working-set-GS6DSO7F.js} +18 -18
  91. package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-22ZCNOM3.js} +367 -79
  92. package/dist/{docs-6FZSCG5B.js → docs-7LQ23DLM.js} +9 -9
  93. package/dist/{doctor-SVJ5BZCW.js → doctor-M7YEDGAE.js} +27 -23
  94. package/dist/{eval-CG6LLBLD.js → eval-BEC2WHDA.js} +73 -20
  95. package/dist/{evidence-ZYFIEN42.js → evidence-REJUMSKM.js} +70 -59
  96. package/dist/{evolve-QGEXEMDW.js → evolve-PY5ZBA5K.js} +50 -39
  97. package/dist/{extensions-ADGNCJJD.js → extensions-HVKU65YU.js} +7 -7
  98. package/dist/{fleet-S5R4ZOQY.js → fleet-7WZEWRFA.js} +236 -377
  99. package/dist/fleet-commands-UVHWM76J.js +70 -0
  100. package/dist/fleet-graph-6ULH7PES.js +125 -0
  101. package/dist/fleet-new-RDVJLHHH.js +48 -0
  102. package/dist/{fleet-preflight-BHSNPBMH.js → fleet-preflight-J53T6CCE.js} +5 -5
  103. package/dist/fleet-validate-72PC4SLA.js +79 -0
  104. package/dist/{init-5DRU55YR.js → init-OG3TPGQG.js} +69 -57
  105. package/dist/library-CNTMPLRF.js +217 -0
  106. package/dist/{memory-7YKKR6UC.js → memory-6IS7F275.js} +52 -41
  107. package/dist/{models-ZPOLRU2C.js → models-ENRJDA5W.js} +37 -31
  108. package/dist/{monitor-US5F5YGZ.js → monitor-XLDVO7TN.js} +79 -42
  109. package/dist/{orchestrator-E2AL4T5N.js → orchestrator-6KSPYRHA.js} +4126 -762
  110. package/dist/{paths-E7KYAQWE.js → paths-DBXMZMDU.js} +6 -6
  111. package/dist/registry-LG64LTF4.js +11 -0
  112. package/dist/{reset-KZ652EK6.js → reset-RZ4ER727.js} +12 -12
  113. package/dist/{run-SRNBKDWD.js → run-Y2CNK5RU.js} +89 -76
  114. package/dist/{share-CGZE33UP.js → share-A55GYP6Z.js} +37 -13
  115. package/dist/{skills-S2X4DLY5.js → skills-ALC5J6AT.js} +29 -13
  116. package/dist/{skills-eval-W2GGIC4R.js → skills-eval-JPBEBYQU.js} +60 -48
  117. package/dist/support-MIETYA5E.js +38 -0
  118. package/dist/{targets-54SWINWB.js → targets-VGNXIR3S.js} +46 -36
  119. package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WOBR64YA.js} +4 -4
  120. package/dist/{uninstall-BVLWXKBT.js → uninstall-ZJF5H5ZN.js} +9 -9
  121. package/dist/{upgrade-JKAR27XC.js → upgrade-FUSUAGHR.js} +31 -28
  122. package/dist/{usage-MSAWCLX4.js → usage-N4MKVHKD.js} +140 -68
  123. package/dist/verifiers-YAWOJ3H2.js +336 -0
  124. package/dist/{verify-X5HDROLA.js → verify-LTDHYBGY.js} +10 -9
  125. package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-6M7GHTBJ.js} +75 -62
  126. package/dist/worker/entry.js +67 -57
  127. package/docs/README.md +3 -2
  128. package/docs/acp.md +1 -1
  129. package/docs/alcf-provider.md +1 -1
  130. package/docs/architecture.md +2 -2
  131. package/docs/artifact-versions.md +11 -6
  132. package/docs/built-in-agents.md +26 -2
  133. package/docs/capacity-and-scheduling.md +1 -1
  134. package/docs/commands-and-modes.md +83 -3
  135. package/docs/configuration-and-targets.md +86 -4
  136. package/docs/context-engine.md +1 -1
  137. package/docs/development-pipeline.md +1 -1
  138. package/docs/dispatch-architecture-rationale.md +1 -1
  139. package/docs/documentation-coverage.md +3 -3
  140. package/docs/documentation-guide.md +3 -3
  141. package/docs/eval-runner.md +1 -1
  142. package/docs/evals-internal.md +1 -1
  143. package/docs/evidence-and-memory.md +74 -10
  144. package/docs/evolution.md +1 -1
  145. package/docs/exit-codes-and-output.md +4 -1
  146. package/docs/extensions-and-sharing.md +6 -2
  147. package/docs/fleet-demo-runbook.md +2 -2
  148. package/docs/fleet-dispatch.md +228 -16
  149. package/docs/git-commit-provenance.md +2 -2
  150. package/docs/glossary.md +22 -2
  151. package/docs/installation-and-lifecycle.md +2 -2
  152. package/docs/middleware-and-components.md +2 -1
  153. package/docs/model-catalog.md +1 -1
  154. package/docs/observability.md +56 -9
  155. package/docs/proactive-memory.md +1 -1
  156. package/docs/prompt-envelope-and-tools.md +4 -2
  157. package/docs/provider-adapter-cookbook.md +1 -1
  158. package/docs/release-cut-checklist.md +83 -65
  159. package/docs/resource-library.md +59 -0
  160. package/docs/safety-model.md +2 -2
  161. package/docs/scientific-validation.md +3 -3
  162. package/docs/session-lifecycle.md +37 -1
  163. package/docs/skills-marketplace.md +16 -3
  164. package/docs/tool-usage.md +14 -7
  165. package/docs/trace-store.md +1 -1
  166. package/docs/troubleshooting.md +1 -1
  167. package/docs/tui-design.md +1 -1
  168. package/docs/worker-dispatch-mechanics.md +3 -3
  169. package/package.json +1 -2
  170. package/src/cli/argv.ts +5 -0
  171. package/src/cli/configure.ts +107 -23
  172. package/src/cli/doctor.ts +5 -1
  173. package/src/cli/evidence.ts +30 -25
  174. package/src/cli/fleet-commands.ts +37 -0
  175. package/src/cli/fleet-graph.ts +102 -0
  176. package/src/cli/fleet-new.ts +36 -0
  177. package/src/cli/fleet-preflight.ts +111 -0
  178. package/src/cli/fleet-validate.ts +30 -0
  179. package/src/cli/fleet.ts +173 -335
  180. package/src/cli/index.ts +3 -1
  181. package/src/cli/library.ts +190 -0
  182. package/src/cli/share.ts +13 -1
  183. package/src/cli/shared.ts +1 -0
  184. package/src/cli/targets.ts +4 -1
  185. package/src/cli/usage.ts +111 -19
  186. package/src/cli/validate-model.ts +60 -5
  187. package/src/core/bus-events.ts +29 -0
  188. package/src/core/commit-attribution.ts +4 -4
  189. package/src/core/config.ts +130 -0
  190. package/src/core/defaults.ts +81 -0
  191. package/src/core/path-boundary.ts +100 -0
  192. package/src/domains/agents/builtins/architect.md +1 -0
  193. package/src/domains/agents/builtins/oracle.md +33 -0
  194. package/src/domains/agents/catalog.ts +13 -1
  195. package/src/domains/agents/extension.ts +2 -11
  196. package/src/domains/agents/fleet-contract.ts +304 -24
  197. package/src/domains/agents/index.ts +14 -0
  198. package/src/domains/agents/recipe.ts +7 -1
  199. package/src/domains/agents/registry.ts +73 -5
  200. package/src/domains/agents/result-contract.ts +360 -15
  201. package/src/domains/agents/write-boundary.ts +15 -50
  202. package/src/domains/config/classify.ts +4 -0
  203. package/src/domains/context/project-rules.ts +51 -1
  204. package/src/domains/dispatch/active-route-planner.ts +14 -0
  205. package/src/domains/dispatch/assignment-reconcile.ts +22 -5
  206. package/src/domains/dispatch/assignment-store.ts +151 -14
  207. package/src/domains/dispatch/backoff.ts +2 -1
  208. package/src/domains/dispatch/capability-match.ts +1 -0
  209. package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
  210. package/src/domains/dispatch/contract.ts +48 -0
  211. package/src/domains/dispatch/delegation-plan.ts +164 -0
  212. package/src/domains/dispatch/execution-plan.ts +76 -5
  213. package/src/domains/dispatch/execution-role.ts +12 -2
  214. package/src/domains/dispatch/execution-scheduler.ts +183 -67
  215. package/src/domains/dispatch/extension.ts +412 -74
  216. package/src/domains/dispatch/fleet-gate.ts +14 -0
  217. package/src/domains/dispatch/fleet-plan.ts +63 -3
  218. package/src/domains/dispatch/fleet-run.ts +791 -0
  219. package/src/domains/dispatch/gate-role-prompts.ts +47 -0
  220. package/src/domains/dispatch/host-verification.ts +178 -0
  221. package/src/domains/dispatch/index.ts +41 -1
  222. package/src/domains/dispatch/intent-requirements.ts +40 -0
  223. package/src/domains/dispatch/intent.ts +235 -0
  224. package/src/domains/dispatch/path-scope.ts +370 -0
  225. package/src/domains/dispatch/receipt-integrity.ts +9 -4
  226. package/src/domains/dispatch/state.ts +36 -3
  227. package/src/domains/dispatch/types.ts +64 -12
  228. package/src/domains/dispatch/validation.ts +69 -6
  229. package/src/domains/dispatch/write-boundary-enforcer.ts +45 -0
  230. package/src/domains/dispatch/write-boundary.ts +201 -22
  231. package/src/domains/eval/metrics/evidence.ts +79 -2
  232. package/src/domains/eval/runners/clio-run.ts +12 -2
  233. package/src/domains/evidence/build.ts +69 -11
  234. package/src/domains/evidence/index.ts +21 -0
  235. package/src/domains/evidence/provenance.ts +46 -11
  236. package/src/domains/evidence/trust-projection.ts +274 -0
  237. package/src/domains/evidence/trust-status.ts +155 -18
  238. package/src/domains/evidence/types.ts +4 -0
  239. package/src/domains/extensions/discovery.ts +88 -1
  240. package/src/domains/extensions/resources.ts +20 -8
  241. package/src/domains/extensions/state.ts +6 -2
  242. package/src/domains/extensions/types.ts +4 -1
  243. package/src/domains/lifecycle/doctor.ts +140 -1
  244. package/src/domains/middleware/index.ts +15 -0
  245. package/src/domains/middleware/watchdog.ts +281 -0
  246. package/src/domains/observability/contract.ts +3 -1
  247. package/src/domains/observability/cost.ts +12 -1
  248. package/src/domains/observability/extension.ts +2 -2
  249. package/src/domains/observability/index.ts +10 -0
  250. package/src/domains/observability/out-of-turn-usage.ts +223 -0
  251. package/src/domains/prompts/contract.ts +3 -5
  252. package/src/domains/providers/extension.ts +30 -2
  253. package/src/domains/resources/common-loader.ts +3 -0
  254. package/src/domains/resources/index.ts +20 -0
  255. package/src/domains/resources/library.ts +326 -0
  256. package/src/domains/resources/prompts/loader.ts +119 -14
  257. package/src/domains/resources/skills/marketplace.ts +37 -12
  258. package/src/domains/safety/policy-engine.ts +5 -5
  259. package/src/domains/safety/run-effects.ts +64 -1
  260. package/src/domains/safety/scope.ts +7 -12
  261. package/src/domains/session/handoff.ts +629 -0
  262. package/src/domains/share/archive.ts +67 -2
  263. package/src/engine/acp/server.ts +4 -1
  264. package/src/engine/prompt-templates.ts +18 -1
  265. package/src/engine/worker-runtime.ts +6 -3
  266. package/src/entry/orchestrator.ts +37 -0
  267. package/src/interactive/bus-notices.ts +26 -0
  268. package/src/interactive/chat-loop.ts +235 -1
  269. package/src/interactive/chat-renderer.ts +22 -0
  270. package/src/interactive/cost-overlay.ts +31 -3
  271. package/src/interactive/council-dispatch.ts +30 -0
  272. package/src/interactive/council-grid.ts +213 -0
  273. package/src/interactive/council.ts +99 -0
  274. package/src/interactive/dispatch-board.ts +311 -17
  275. package/src/interactive/fleet-run-preview.ts +307 -0
  276. package/src/interactive/footer/notifications.ts +219 -0
  277. package/src/interactive/handoff-round.ts +56 -0
  278. package/src/interactive/interactive-application.ts +43 -1
  279. package/src/interactive/interactive-event-projection.ts +23 -1
  280. package/src/interactive/interactive-slash-runtime.ts +52 -2
  281. package/src/interactive/interactive-subscriptions.ts +14 -2
  282. package/src/interactive/oracle.ts +179 -0
  283. package/src/interactive/overlay-ask-user-lifecycle.ts +6 -0
  284. package/src/interactive/overlay-general-openers.ts +190 -1
  285. package/src/interactive/overlay-key-routing.ts +17 -1
  286. package/src/interactive/overlay-lifecycle.ts +41 -1
  287. package/src/interactive/overlay-permission-lifecycle.ts +10 -0
  288. package/src/interactive/overlay-resource-openers.ts +11 -3
  289. package/src/interactive/overlay-session-lifecycle.ts +234 -2
  290. package/src/interactive/overlays/fleet-run-approval.ts +208 -0
  291. package/src/interactive/overlays/handoff-review.ts +185 -0
  292. package/src/interactive/overlays/library-install-confirm.ts +151 -0
  293. package/src/interactive/overlays/list-overlay.ts +168 -2
  294. package/src/interactive/overlays/settings.ts +221 -30
  295. package/src/interactive/overlays/side-question.ts +139 -0
  296. package/src/interactive/overlays/skills-hub.ts +401 -15
  297. package/src/interactive/side-question.ts +171 -0
  298. package/src/interactive/slash-commands.ts +439 -7
  299. package/src/interactive/slash-spec.ts +19 -6
  300. package/src/interactive/theme/tokens.ts +30 -0
  301. package/src/interactive/turn-middleware.ts +15 -1
  302. package/src/interactive/view/artifacts.ts +42 -9
  303. package/src/interactive/view/view-overlay.ts +15 -3
  304. package/src/interactive/watchdog-run.ts +75 -0
  305. package/src/interactive/worker-receipts.ts +14 -2
  306. package/src/interactive/worker-share.ts +56 -1
  307. package/src/interactive/worker-stream.ts +15 -0
  308. package/src/tools/bootstrap.ts +3 -0
  309. package/src/tools/compete-worktrees.ts +13 -79
  310. package/src/tools/dispatch-admission.ts +251 -18
  311. package/src/tools/dispatch-arguments.ts +84 -1
  312. package/src/tools/dispatch-plan.ts +165 -6
  313. package/src/tools/dispatch-runner.ts +364 -23
  314. package/src/tools/dispatch-types.ts +20 -1
  315. package/src/tools/dispatch.ts +72 -2
  316. package/src/tools/monitor.ts +29 -0
  317. package/src/tools/profiles.ts +18 -4
  318. package/src/tools/task-worktree.ts +238 -0
  319. package/src/tools/verify/authoring.ts +61 -1
  320. package/src/tools/verify/scripts.ts +62 -0
  321. package/src/tools/worker-evidence.ts +21 -14
  322. package/src/worker/spec-contract.ts +3 -1
  323. package/dist/chunk-HC4CLZ2Y.js +0 -68
@@ -0,0 +1,370 @@
1
+ import {
2
+ asDirectoryPathBoundary,
3
+ normalizePathBoundaryEntry,
4
+ PathBoundaryError,
5
+ pathBoundaryCovers,
6
+ resolvePathBoundary,
7
+ } from "../../core/path-boundary.js";
8
+ import type { DispatchRequest } from "./contract.js";
9
+
10
+ /** Path-like tokens retained for requests that do not carry typed intent. */
11
+ const DISPATCH_PATH_TOKEN_RE = /(?:[\w.-]+\/)+[\w.-]+|\b[\w-]+\.[A-Za-z0-9]{1,8}\b/g;
12
+ const HTTP_URL_RE = /\bhttps?:\/\/\S+/gu;
13
+ const POSIX_ABSOLUTE_TOKEN_RE = /(?:^|[\s("'])((?:\/[\w.~+-]+)+)/gu;
14
+ const WINDOWS_ABSOLUTE_TOKEN_RE = /(?:^|[\s("'])([A-Za-z]:[\\/][^\s"']+)/gu;
15
+ const BACKSLASH_PATH_RE = /\b[A-Za-z_.-][\w.-]*\\(?:(?:[\w.-]+\\)+[\w.-]+|[\w-]+\.[A-Za-z0-9]{1,8})\b/gu;
16
+ const DOUBLE_SEPARATOR_PATH_RE = /\b[\w.-]+\/\/[\w./-]+/gu;
17
+
18
+ export type DispatchPathProvenanceKind = "declared" | "derived" | "inferred";
19
+ export type DispatchPathConfidence = "certain" | "high" | "medium" | "low";
20
+ export type DispatchPathProvenanceSource =
21
+ | "intent.read_roots"
22
+ | "intent.write_roots"
23
+ | "intent.relevant_paths"
24
+ | "writeRoots"
25
+ | "task"
26
+ | "briefing";
27
+ export type DispatchPathProvenanceReason =
28
+ | "explicit_intent"
29
+ | "legacy_write_roots"
30
+ | "task_path_token"
31
+ | "briefing_path_token";
32
+
33
+ export interface DispatchPathProvenanceEvidence {
34
+ provenance: DispatchPathProvenanceKind;
35
+ source: DispatchPathProvenanceSource;
36
+ confidence: DispatchPathConfidence;
37
+ reason: DispatchPathProvenanceReason;
38
+ }
39
+
40
+ export interface DispatchPathProvenanceEntry {
41
+ path: string;
42
+ evidence: DispatchPathProvenanceEvidence[];
43
+ }
44
+
45
+ export interface DispatchPathScopeProvenance {
46
+ version: 1;
47
+ mode: "declared" | "legacy-inferred";
48
+ workingContextPaths: DispatchPathProvenanceEntry[];
49
+ writeBoundaries: DispatchPathProvenanceEntry[];
50
+ }
51
+
52
+ export interface DispatchPathScope {
53
+ source: "declared" | "inferred";
54
+ workingContextPaths: ReadonlyArray<string>;
55
+ writeBoundaries: ReadonlyArray<string>;
56
+ inferredOnlyPaths: ReadonlyArray<string>;
57
+ provenance: DispatchPathScopeProvenance;
58
+ }
59
+
60
+ export interface DeclaredScopeReplacementNotice {
61
+ code: "typed_scope_replaced_inferred_paths";
62
+ level: "warning";
63
+ omittedPaths: ReadonlyArray<string>;
64
+ message: string;
65
+ }
66
+
67
+ export interface LegacyScopeInferenceNotice {
68
+ code: "legacy_scope_inferred" | "legacy_scope_empty";
69
+ level: "warning";
70
+ paths: ReadonlyArray<{
71
+ path: string;
72
+ policy: "working-context" | "write-boundary";
73
+ provenance: DispatchPathProvenanceKind;
74
+ source: DispatchPathProvenanceSource;
75
+ confidence: DispatchPathConfidence;
76
+ }>;
77
+ message: string;
78
+ }
79
+
80
+ export type DispatchPathScopeInferenceErrorCode = "legacy_scope_path_absolute" | "legacy_scope_path_malformed";
81
+
82
+ export class DispatchPathScopeInferenceError extends Error {
83
+ readonly code: DispatchPathScopeInferenceErrorCode;
84
+ readonly source: "task" | "briefing";
85
+ readonly token: string;
86
+
87
+ constructor(code: DispatchPathScopeInferenceErrorCode, source: "task" | "briefing", token: string, detail: string) {
88
+ super(`${code}: ${source} contains ${detail} '${token}'; declare intent explicitly`);
89
+ this.name = "DispatchPathScopeInferenceError";
90
+ this.code = code;
91
+ this.source = source;
92
+ this.token = token;
93
+ }
94
+ }
95
+
96
+ const DECLARED_EVIDENCE = {
97
+ readRoots: {
98
+ provenance: "declared",
99
+ source: "intent.read_roots",
100
+ confidence: "certain",
101
+ reason: "explicit_intent",
102
+ },
103
+ writeRoots: {
104
+ provenance: "declared",
105
+ source: "intent.write_roots",
106
+ confidence: "certain",
107
+ reason: "explicit_intent",
108
+ },
109
+ relevantPaths: {
110
+ provenance: "declared",
111
+ source: "intent.relevant_paths",
112
+ confidence: "certain",
113
+ reason: "explicit_intent",
114
+ },
115
+ } as const satisfies Record<"readRoots" | "writeRoots" | "relevantPaths", DispatchPathProvenanceEvidence>;
116
+
117
+ function cloneEvidence(evidence: DispatchPathProvenanceEvidence): DispatchPathProvenanceEvidence {
118
+ return { ...evidence };
119
+ }
120
+
121
+ function addProvenance(
122
+ entries: Map<string, DispatchPathProvenanceEntry>,
123
+ path: string,
124
+ evidence: DispatchPathProvenanceEvidence,
125
+ ): void {
126
+ const current = entries.get(path);
127
+ if (current === undefined) {
128
+ entries.set(path, { path, evidence: [cloneEvidence(evidence)] });
129
+ return;
130
+ }
131
+ if (!current.evidence.some((entry) => entry.source === evidence.source)) {
132
+ current.evidence.push(cloneEvidence(evidence));
133
+ }
134
+ }
135
+
136
+ function sortedEntries(entries: Map<string, DispatchPathProvenanceEntry>): DispatchPathProvenanceEntry[] {
137
+ return [...entries.values()]
138
+ .sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0))
139
+ .map((entry) => ({ path: entry.path, evidence: entry.evidence.map(cloneEvidence) }));
140
+ }
141
+
142
+ /** Build the required field-level provenance for normalized declared intent. */
143
+ export function declaredIntentPathProvenance(input: {
144
+ readRoots: ReadonlyArray<string>;
145
+ writeRoots: ReadonlyArray<string>;
146
+ relevantPaths: ReadonlyArray<string>;
147
+ }): DispatchPathProvenanceEntry[] {
148
+ const entries = new Map<string, DispatchPathProvenanceEntry>();
149
+ for (const path of input.readRoots) addProvenance(entries, path, DECLARED_EVIDENCE.readRoots);
150
+ for (const path of input.writeRoots) addProvenance(entries, path, DECLARED_EVIDENCE.writeRoots);
151
+ for (const path of input.relevantPaths) addProvenance(entries, path, DECLARED_EVIDENCE.relevantPaths);
152
+ return sortedEntries(entries);
153
+ }
154
+
155
+ function inferredPaths(req: Pick<DispatchRequest, "task" | "briefing">): string[] {
156
+ const paths = new Set<string>();
157
+ const text = `${req.task}\n${req.briefing ?? ""}`;
158
+ for (const match of text.matchAll(DISPATCH_PATH_TOKEN_RE)) {
159
+ const token = inferredPathToken(match[0]);
160
+ if (token.startsWith("http://") || token.startsWith("https://")) continue;
161
+ paths.add(token);
162
+ }
163
+ return [...paths];
164
+ }
165
+
166
+ function inferredPathToken(token: string): string {
167
+ return token.replace(/\.+$/u, "");
168
+ }
169
+
170
+ function failMalformedText(text: string, source: "task" | "briefing"): void {
171
+ const withoutUrls = text.replace(HTTP_URL_RE, (url) => " ".repeat(url.length));
172
+ const absolute = POSIX_ABSOLUTE_TOKEN_RE.exec(withoutUrls)?.[1];
173
+ POSIX_ABSOLUTE_TOKEN_RE.lastIndex = 0;
174
+ if (absolute !== undefined) {
175
+ throw new DispatchPathScopeInferenceError("legacy_scope_path_absolute", source, absolute, "an absolute path token");
176
+ }
177
+ const windowsAbsolute = WINDOWS_ABSOLUTE_TOKEN_RE.exec(withoutUrls)?.[1];
178
+ WINDOWS_ABSOLUTE_TOKEN_RE.lastIndex = 0;
179
+ if (windowsAbsolute !== undefined) {
180
+ throw new DispatchPathScopeInferenceError(
181
+ "legacy_scope_path_absolute",
182
+ source,
183
+ windowsAbsolute,
184
+ "an absolute path token",
185
+ );
186
+ }
187
+ for (const pattern of [BACKSLASH_PATH_RE, DOUBLE_SEPARATOR_PATH_RE]) {
188
+ const malformed = pattern.exec(withoutUrls)?.[0];
189
+ pattern.lastIndex = 0;
190
+ if (malformed !== undefined) {
191
+ throw new DispatchPathScopeInferenceError(
192
+ "legacy_scope_path_malformed",
193
+ source,
194
+ malformed,
195
+ "a malformed path token",
196
+ );
197
+ }
198
+ }
199
+ }
200
+
201
+ function strictInferredPaths(
202
+ text: string,
203
+ source: "task" | "briefing",
204
+ ): Array<{ path: string; evidence: DispatchPathProvenanceEvidence }> {
205
+ failMalformedText(text, source);
206
+ const withoutUrls = text.replace(HTTP_URL_RE, (url) => " ".repeat(url.length));
207
+ const evidence: DispatchPathProvenanceEvidence =
208
+ source === "task"
209
+ ? { provenance: "inferred", source, confidence: "medium", reason: "task_path_token" }
210
+ : { provenance: "inferred", source, confidence: "low", reason: "briefing_path_token" };
211
+ const result: Array<{ path: string; evidence: DispatchPathProvenanceEvidence }> = [];
212
+ for (const match of withoutUrls.matchAll(DISPATCH_PATH_TOKEN_RE)) {
213
+ const token = inferredPathToken(match[0]);
214
+ try {
215
+ result.push({ path: normalizePathBoundaryEntry(token), evidence });
216
+ } catch (error) {
217
+ const code =
218
+ error instanceof PathBoundaryError && error.code === "absolute"
219
+ ? "legacy_scope_path_absolute"
220
+ : "legacy_scope_path_malformed";
221
+ throw new DispatchPathScopeInferenceError(
222
+ code,
223
+ source,
224
+ token,
225
+ code === "legacy_scope_path_absolute" ? "an absolute path token" : "a malformed path token",
226
+ );
227
+ }
228
+ }
229
+ return result;
230
+ }
231
+
232
+ function legacyPathScope(req: DispatchRequest, cwd: string): DispatchPathScope {
233
+ const workingEntries = new Map<string, DispatchPathProvenanceEntry>();
234
+ const writeEntries = new Map<string, DispatchPathProvenanceEntry>();
235
+ const writeEvidence: DispatchPathProvenanceEvidence = {
236
+ provenance: "derived",
237
+ source: "writeRoots",
238
+ confidence: "high",
239
+ reason: "legacy_write_roots",
240
+ };
241
+ for (const root of req.writeRoots ?? []) {
242
+ addProvenance(workingEntries, root, writeEvidence);
243
+ addProvenance(writeEntries, asDirectoryPathBoundary(resolvePathBoundary(cwd, root)), writeEvidence);
244
+ }
245
+ for (const candidate of strictInferredPaths(req.task, "task")) {
246
+ addProvenance(workingEntries, candidate.path, candidate.evidence);
247
+ }
248
+ if (req.briefing !== undefined) {
249
+ for (const candidate of strictInferredPaths(req.briefing, "briefing")) {
250
+ addProvenance(workingEntries, candidate.path, candidate.evidence);
251
+ }
252
+ }
253
+ const workingContext = [...workingEntries.values()].map((entry) => ({
254
+ path: entry.path,
255
+ evidence: entry.evidence.map(cloneEvidence),
256
+ }));
257
+ const writeBoundaries = [...writeEntries.values()].map((entry) => ({
258
+ path: entry.path,
259
+ evidence: entry.evidence.map(cloneEvidence),
260
+ }));
261
+ return {
262
+ source: "inferred",
263
+ workingContextPaths: workingContext.map((entry) => entry.path),
264
+ writeBoundaries: writeBoundaries.map((entry) => entry.path),
265
+ inferredOnlyPaths: [],
266
+ provenance: {
267
+ version: 1,
268
+ mode: "legacy-inferred",
269
+ workingContextPaths: workingContext,
270
+ writeBoundaries,
271
+ },
272
+ };
273
+ }
274
+
275
+ /** Resolve every policy-bearing path projection for one dispatch request. */
276
+ export function resolveDispatchPathScope(req: DispatchRequest): DispatchPathScope {
277
+ const cwd = req.cwd ?? process.cwd();
278
+ if (req.intent === undefined) return legacyPathScope(req, cwd);
279
+
280
+ const declaredProvenance = declaredIntentPathProvenance(req.intent);
281
+ const declaredPaths = declaredProvenance.map((entry) => entry.path);
282
+ const inferredOnlyPaths = inferredPaths(req).filter((candidate) => !pathBoundaryCovers(declaredPaths, candidate));
283
+ const writeEvidence = DECLARED_EVIDENCE.writeRoots;
284
+ const writeBoundaries = req.intent.writeRoots.map((root) => ({
285
+ path: resolvePathBoundary(cwd, root),
286
+ evidence: [cloneEvidence(writeEvidence)],
287
+ }));
288
+ return {
289
+ source: "declared",
290
+ workingContextPaths: declaredPaths,
291
+ writeBoundaries: writeBoundaries.map((entry) => entry.path),
292
+ inferredOnlyPaths,
293
+ provenance: {
294
+ version: 1,
295
+ mode: "declared",
296
+ workingContextPaths: declaredProvenance,
297
+ writeBoundaries,
298
+ },
299
+ };
300
+ }
301
+
302
+ /** Render the named diagnostic for the declared-scope replacement tradeoff. */
303
+ export function declaredScopeReplacementDiagnostic(scope: DispatchPathScope): string | null {
304
+ if (scope.source !== "declared" || scope.inferredOnlyPaths.length === 0) return null;
305
+ return `typed_scope_replaced_inferred_paths: typed intent omitted prose-inferred paths ${scope.inferredOnlyPaths.join(
306
+ ", ",
307
+ )}; those paths did not select project rules or expand worker authority`;
308
+ }
309
+
310
+ /** Render the interactive warning for the declared-scope replacement tradeoff. */
311
+ export function declaredScopeReplacementNotice(scope: DispatchPathScope): DeclaredScopeReplacementNotice | null {
312
+ if (scope.source !== "declared" || scope.inferredOnlyPaths.length === 0) return null;
313
+ const omittedPaths = [...scope.inferredOnlyPaths];
314
+ return {
315
+ code: "typed_scope_replaced_inferred_paths",
316
+ level: "warning",
317
+ omittedPaths,
318
+ message: `[dispatch scope] typed intent replaced prose path inference; omitted paths: ${omittedPaths.join(
319
+ ", ",
320
+ )}. Those paths did not select project rules or expand worker authority.`,
321
+ };
322
+ }
323
+
324
+ function legacyNoticePaths(scope: DispatchPathScope): LegacyScopeInferenceNotice["paths"] {
325
+ const paths: Array<LegacyScopeInferenceNotice["paths"][number]> = [];
326
+ for (const [policy, entries] of [
327
+ ["working-context", scope.provenance.workingContextPaths],
328
+ ["write-boundary", scope.provenance.writeBoundaries],
329
+ ] as const) {
330
+ for (const entry of entries) {
331
+ for (const evidence of entry.evidence) {
332
+ paths.push({
333
+ path: entry.path,
334
+ policy,
335
+ provenance: evidence.provenance,
336
+ source: evidence.source,
337
+ confidence: evidence.confidence,
338
+ });
339
+ }
340
+ }
341
+ }
342
+ return paths;
343
+ }
344
+
345
+ /** Render the operator-visible warning for a legacy scope resolution. */
346
+ export function legacyScopeInferenceNotice(scope: DispatchPathScope): LegacyScopeInferenceNotice | null {
347
+ if (scope.source !== "inferred") return null;
348
+ const paths = legacyNoticePaths(scope);
349
+ if (paths.length === 0) {
350
+ return {
351
+ code: "legacy_scope_empty",
352
+ level: "warning",
353
+ paths,
354
+ message:
355
+ "[dispatch scope] legacy dispatch has no declared intent and inferred no policy-bearing paths. Path-scoped rules received no inferred match input, and worker authority did not expand.",
356
+ };
357
+ }
358
+ const rendered = paths
359
+ .map(
360
+ (entry) =>
361
+ `${entry.policy} ${entry.path} (provenance=${entry.provenance} source=${entry.source} confidence=${entry.confidence})`,
362
+ )
363
+ .join("; ");
364
+ return {
365
+ code: "legacy_scope_inferred",
366
+ level: "warning",
367
+ paths,
368
+ message: `[dispatch scope] legacy dispatch resolved policy-bearing scope without declared intent: ${rendered}. Review this scope before execution.`,
369
+ };
370
+ }
@@ -10,7 +10,7 @@ import type { RunEnvelope, RunReceipt, RunReceiptDraft, RunReceiptIntegrity, Run
10
10
  * base, so there are no historical receipts to keep verifying: a receipt is
11
11
  * either this version or it is not a receipt.
12
12
  */
13
- export const RUN_RECEIPT_INTEGRITY_VERSION: RunReceiptIntegrity["version"] = 15;
13
+ export const RUN_RECEIPT_INTEGRITY_VERSION: RunReceiptIntegrity["version"] = 20;
14
14
  export type ReceiptIntegrityVersion = RunReceiptIntegrity["version"];
15
15
  export type ReceiptIntegrityField = keyof RunReceiptDraft;
16
16
  export const RUN_RECEIPT_INTEGRITY_ALGORITHM = "sha256";
@@ -76,6 +76,8 @@ export const RECEIPT_INTEGRITY_FIELD_COVERAGE = {
76
76
  agentAudience: true,
77
77
  requestOrigin: true,
78
78
  task: true,
79
+ intent: true,
80
+ pathScope: true,
79
81
  // Historical receipts omit this field, so their receipt and ledger payloads remain unchanged.
80
82
  budget: true,
81
83
  targetId: true,
@@ -93,12 +95,13 @@ export const RECEIPT_INTEGRITY_FIELD_COVERAGE = {
93
95
  reroutes: true,
94
96
  pipeline: true,
95
97
  gate: true,
98
+ council: true,
96
99
  plan: true,
100
+ fleetGate: true,
97
101
  personaOverride: true,
98
102
  projectContext: true,
99
103
  // Always set on receipts written after #104 landed; absent only on older
100
- // receipts, which digest exactly as they did before these fields existed,
101
- // so the integrity version stays where it is.
104
+ // receipts, which omit these fields from canonical serialization.
102
105
  rulesApplied: true,
103
106
  operatorProfileApplied: true,
104
107
  exitCode: true,
@@ -128,6 +131,8 @@ export const RECEIPT_INTEGRITY_FIELD_COVERAGE = {
128
131
  toolStats: true,
129
132
  toolActivity: true,
130
133
  verification: true,
134
+ hostVerification: true,
135
+ worktree: true,
131
136
  routingIntent: true,
132
137
  quality: true,
133
138
  skillActivations: true,
@@ -143,7 +148,7 @@ export const RECEIPT_INTEGRITY_FIELD_COVERAGE = {
143
148
  validationGrounding: true,
144
149
  capabilityMismatch: true,
145
150
  // Same reasoning: absent unless the run had an agent ledger, so a receipt
146
- // without one digests byte-identically to one produced before it existed.
151
+ // without one omits the field from canonical serialization.
147
152
  ledgerContribution: true,
148
153
  sessionId: true,
149
154
  briefing: true,
@@ -25,10 +25,26 @@ import { resolveGuardrail } from "../../core/guardrails.js";
25
25
  import { withStateFileLock } from "../../core/state-file-lock.js";
26
26
  import { clioStateDir, stateRootRemoved } from "../../core/xdg.js";
27
27
  import { atomicWrite } from "../../engine/session.js";
28
+ import type { ExecutionStepResult } from "./execution-scheduler.js";
28
29
  import { computeReceiptFindingsSummary } from "./receipt-findings.js";
29
30
  import { withReceiptIntegrity } from "./receipt-integrity.js";
30
31
  import type { RunEnvelope, RunReceipt, RunReceiptDraft, RunStatus } from "./types.js";
31
32
 
33
+ export interface FleetRunRecord {
34
+ version: 1;
35
+ id: string;
36
+ fleet: string;
37
+ planHash: string;
38
+ stepIds: string[];
39
+ planSteps: unknown[];
40
+ vars: Record<string, string>;
41
+ startedAt: string;
42
+ endedAt: string | null;
43
+ resumedFrom: string | null;
44
+ steps: Array<{ stepId: string; result: ExecutionStepResult }>;
45
+ dynamicPlans?: Array<{ stepId: string; hash: string }>;
46
+ }
47
+
32
48
  export interface LedgerOptions {
33
49
  maxRuns?: number;
34
50
  }
@@ -45,7 +61,7 @@ export type CreateRunInput = Omit<
45
61
  | "receiptPath"
46
62
  | "tokenCount"
47
63
  | "costUsd"
48
- >;
64
+ > & { id?: string };
49
65
 
50
66
  export interface Ledger {
51
67
  create(input: CreateRunInput): RunEnvelope;
@@ -59,7 +75,7 @@ export interface Ledger {
59
75
  reload(): void;
60
76
  }
61
77
 
62
- function newRunId(): string {
78
+ export function newRunId(): string {
63
79
  const n = BigInt(`0x${randomBytes(8).toString("hex")}`);
64
80
  const raw = n.toString(36);
65
81
  if (raw.length >= 12) return raw.slice(0, 12);
@@ -74,6 +90,23 @@ function receiptPathFor(runId: string): string {
74
90
  return join(clioStateDir(), "receipts", `${runId}.json`);
75
91
  }
76
92
 
93
+ function fleetRunPath(runId: string): string {
94
+ return join(clioStateDir(), "fleet-runs", `${runId}.json`);
95
+ }
96
+
97
+ export function readFleetRun(runId: string): FleetRunRecord | null {
98
+ try {
99
+ const parsed = JSON.parse(readFileSync(fleetRunPath(runId), "utf8")) as FleetRunRecord;
100
+ return parsed.version === 1 && parsed.id === runId ? structuredClone(parsed) : null;
101
+ } catch {
102
+ return null;
103
+ }
104
+ }
105
+
106
+ export async function writeFleetRun(record: FleetRunRecord): Promise<void> {
107
+ await atomicWrite(fleetRunPath(record.id), `${JSON.stringify(record, null, 2)}\n`);
108
+ }
109
+
77
110
  function readRuns(): RunEnvelope[] {
78
111
  const path = runsPath();
79
112
  if (!existsSync(path)) return [];
@@ -169,7 +202,7 @@ export function openLedger(opts?: LedgerOptions): Ledger {
169
202
  return {
170
203
  create(input: CreateRunInput): RunEnvelope {
171
204
  const envelope: RunEnvelope = {
172
- id: newRunId(),
205
+ id: input.id ?? newRunId(),
173
206
  agentId: input.agentId,
174
207
  executionRole: input.executionRole,
175
208
  ...(input.agentAudience !== undefined ? { agentAudience: input.agentAudience } : {}),
@@ -14,6 +14,8 @@ import type { EvidenceTag } from "../evidence/index.js";
14
14
  import type { CostProvenance, RuntimeTargetSnapshot } from "../providers/index.js";
15
15
  import type { RunToolBudgetEnvelope } from "./budget-envelope.js";
16
16
  import type { ExecutionRole, GateTopologyRole } from "./execution-role.js";
17
+ import type { DispatchIntent } from "./intent.js";
18
+ import type { DispatchPathScopeProvenance } from "./path-scope.js";
17
19
  import type { RouteDecisionV1 } from "./route-decision.js";
18
20
  import type { RoutingIntent } from "./routing-intent.js";
19
21
 
@@ -41,7 +43,8 @@ export type RunOutcomeCode =
41
43
  | "worker_tool_call_cap_exhausted"
42
44
  | "loop_guard_tools_disabled_exhausted"
43
45
  | "result_contract_exhausted"
44
- | "worker_final_output_missing";
46
+ | "worker_final_output_missing"
47
+ | "host_verification_rejected";
45
48
 
46
49
  export function isRunOutcomeCode(value: unknown): value is RunOutcomeCode {
47
50
  return (
@@ -49,7 +52,8 @@ export function isRunOutcomeCode(value: unknown): value is RunOutcomeCode {
49
52
  value === "worker_tool_call_cap_exhausted" ||
50
53
  value === "loop_guard_tools_disabled_exhausted" ||
51
54
  value === "result_contract_exhausted" ||
52
- value === "worker_final_output_missing"
55
+ value === "worker_final_output_missing" ||
56
+ value === "host_verification_rejected"
53
57
  );
54
58
  }
55
59
 
@@ -122,12 +126,16 @@ export interface RunPersonaOverride {
122
126
 
123
127
  /**
124
128
  * Effective project-context decision for a run, recorded on every receipt so
125
- * evidence can prove what a worker saw without rehashing. `tier: "none"` is
126
- * written explicitly: it distinguishes "policy said none" from a
127
- * pre-provenance receipt where the whole block is absent. `chars` and
128
- * `contentHash` describe the rendered dynamic message body when bounded;
129
- * `sections` lists extra projected sections that actually rendered
130
- * (currently only "verification-expectations", never for ACP delegation).
129
+ * evidence can prove what a worker saw without rehashing. `tier` is the
130
+ * recipe's CLIO-CODER.md handbook policy and is written explicitly: `none`
131
+ * distinguishes "policy said none" from a pre-provenance receipt where the
132
+ * whole block is absent. `chars` and `contentHash` describe every structured
133
+ * message that was actually sent, whatever the tier, and `sections` names
134
+ * them: `workspace-root` (sent under both tiers, so a none-tier run still
135
+ * records characters), `clio-md` (bounded only), and
136
+ * `verification-expectations` (bounded only, never for ACP delegation). A
137
+ * none-tier block naming only `workspace-root` is a consistent record; the
138
+ * trust adapter treats any other none-tier content as contradictory.
131
139
  */
132
140
  export interface RunProjectContextProvenance {
133
141
  tier: "none" | "bounded";
@@ -238,6 +246,13 @@ export interface RunGateProvenance {
238
246
  verdict?: "pass" | "fail" | "revise";
239
247
  }
240
248
 
249
+ export interface RunCouncilProvenance {
250
+ group: string;
251
+ label: string;
252
+ color?: string;
253
+ round: number;
254
+ }
255
+
241
256
  /**
242
257
  * Plan-approval provenance for multi-task, compete, or remote dispatch.
243
258
  * `approval: "operator"` records that a supervised autonomy level parked the
@@ -248,7 +263,7 @@ export interface RunGateProvenance {
248
263
  */
249
264
  export interface RunPlanProvenance {
250
265
  hash: string;
251
- topology: "parallel" | "sequential" | "pipeline" | "review" | "compete" | "detached" | "fleet";
266
+ topology: "parallel" | "sequential" | "pipeline" | "review" | "compete" | "council" | "detached" | "fleet";
252
267
  taskCount: number;
253
268
  approval: "operator" | "full-auto";
254
269
  source: null | {
@@ -311,7 +326,7 @@ export interface RunPhaseDurations {
311
326
  * bumping one without the other is a compile error.
312
327
  */
313
328
  export interface RunReceiptIntegrity {
314
- version: 15;
329
+ version: 20;
315
330
  algorithm: "sha256";
316
331
  digest: string;
317
332
  }
@@ -449,6 +464,7 @@ export interface RunEnvelope {
449
464
  pipeline?: RunPipelineProvenance;
450
465
  /** Review/compete gate provenance; present only on runs of a gated dispatch. */
451
466
  gate?: RunGateProvenance;
467
+ council?: RunCouncilProvenance;
452
468
  /** Plan-approval provenance; present only on runs of an approval-gated plan. */
453
469
  plan?: RunPlanProvenance;
454
470
  /** Ad-hoc specialist provenance; present only when a persona override composed the stable prompt. */
@@ -674,6 +690,25 @@ export interface RunReceiptVerification {
674
690
  | "receipt-unavailable";
675
691
  }
676
692
 
693
+ export interface RunHostVerificationCheck {
694
+ check: string;
695
+ argv: string[];
696
+ cwd: string;
697
+ exitCode: number;
698
+ durationMs: number;
699
+ memo: boolean;
700
+ outputTail: string;
701
+ artifactPath?: string;
702
+ /** Original evidence owner on a memo hit. */
703
+ evidenceRunId?: string;
704
+ }
705
+
706
+ export interface RunHostVerification {
707
+ status: "verified" | "rejected" | "skipped";
708
+ reason?: string;
709
+ checks: RunHostVerificationCheck[];
710
+ }
711
+
677
712
  export interface RunReceipt {
678
713
  runId: string;
679
714
  agentId: string;
@@ -682,6 +717,10 @@ export interface RunReceipt {
682
717
  agentAudience?: AgentAudience;
683
718
  requestOrigin?: DispatchRequestOrigin;
684
719
  task: string;
720
+ /** Normalized dispatch intent admitted before worker execution. */
721
+ intent?: DispatchIntent;
722
+ /** Resolved policy-bearing paths with field source and confidence, without source prose. */
723
+ pathScope?: DispatchPathScopeProvenance;
685
724
  /** Integrity-sealed recipe policy, invocation request, effective phase, and admission reasons. */
686
725
  budget?: RunToolBudgetEnvelope;
687
726
  /** Proof of briefing content without copying its prose into the receipt. */
@@ -714,8 +753,11 @@ export interface RunReceipt {
714
753
  pipeline?: RunPipelineProvenance;
715
754
  /** Review/compete gate provenance; present only on runs of a gated dispatch. */
716
755
  gate?: RunGateProvenance;
756
+ council?: RunCouncilProvenance;
717
757
  /** Plan-approval provenance; present only on runs of an approval-gated plan. */
718
758
  plan?: RunPlanProvenance;
759
+ /** Version 5 fleet gate artifact authored by this run. */
760
+ fleetGate?: { path: string; pathHash: string };
719
761
  /** Ad-hoc specialist provenance; present only when a persona override composed the stable prompt. */
720
762
  personaOverride?: RunPersonaOverride;
721
763
  /** Effective project-context tier for this run; absent on receipts written before this field landed. */
@@ -764,6 +806,17 @@ export interface RunReceipt {
764
806
  toolActivity?: ToolActivitySummary;
765
807
  /** Integrity-sealed evidence confidence. Sealed on every receipt. */
766
808
  verification: RunReceiptVerification;
809
+ /** Orchestrator-executed declared checks. Worker self-report never populates this field. */
810
+ hostVerification?: RunHostVerification;
811
+ /** Isolated writer checkout and its collect-time application result. */
812
+ worktree?: {
813
+ path: string;
814
+ branch: string;
815
+ diffHash: string;
816
+ apply: "merge" | "preserve";
817
+ applied: boolean;
818
+ reason?: string;
819
+ };
767
820
  /** Required normalized routing request, sealed without task or prompt data. */
768
821
  routingIntent: RoutingIntent;
769
822
  /** Required routing-quality facts known at receipt finalization. */
@@ -786,8 +839,7 @@ export interface RunReceipt {
786
839
  * What this run contributed to its dispatch's agent ledger. Optional and
787
840
  * absent unless the run had a ledger, following validationGrounding and
788
841
  * capabilityMismatch: receiptDigestFields skips undefined, so a receipt
789
- * without one digests exactly as it did before this landed and
790
- * RUN_RECEIPT_INTEGRITY_VERSION stays where it is.
842
+ * without one omits the field from canonical serialization.
791
843
  */
792
844
  ledgerContribution?: RunLedgerContribution;
793
845
  /**