@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,164 @@
1
+ import { createHash } from "node:crypto";
2
+ import { pathBoundaryCovers } from "../../core/path-boundary.js";
3
+ import { normalizeWriteBoundary } from "../agents/write-boundary.js";
4
+
5
+ export type DelegationTaskMode = "sequential" | "parallel";
6
+
7
+ export interface DelegationPlanTask {
8
+ id: string;
9
+ agent: string;
10
+ description: string;
11
+ depends_on: ReadonlyArray<string>;
12
+ writes: ReadonlyArray<string>;
13
+ mode?: DelegationTaskMode;
14
+ }
15
+
16
+ export interface DelegationPlan {
17
+ tasks: ReadonlyArray<DelegationPlanTask>;
18
+ }
19
+
20
+ export type DelegationPlanReason =
21
+ | "delegation_plan_malformed"
22
+ | "delegation_plan_over_max_tasks"
23
+ | "delegation_plan_duplicate_id"
24
+ | "delegation_plan_roster_violation"
25
+ | "delegation_plan_dependency_unknown"
26
+ | "delegation_plan_dependency_cycle"
27
+ | "delegation_plan_writes_outside_boundary";
28
+
29
+ export type DelegationPlanValidation =
30
+ | { ok: true; plan: DelegationPlan; hash: string }
31
+ | { ok: false; reason: DelegationPlanReason; detail: string };
32
+
33
+ export interface ValidateDelegationPlanInput {
34
+ value: unknown;
35
+ roster: ReadonlyArray<string>;
36
+ maxTasks: number;
37
+ writes: ReadonlyArray<string>;
38
+ }
39
+
40
+ export const DELEGATION_PROPOSAL_BRIEFING_MAX_BYTES = 12_000;
41
+
42
+ export function buildDelegationProposalBriefing(proposals: ReadonlyArray<{ agent: string; output: string }>): string {
43
+ const value = proposals.map((proposal) => `PROPOSAL ${proposal.agent}\n${proposal.output}`).join("\n\n");
44
+ if (Buffer.byteLength(value, "utf8") <= DELEGATION_PROPOSAL_BRIEFING_MAX_BYTES) return value;
45
+ const suffix = "\n[truncated]";
46
+ const source = Buffer.from(value, "utf8");
47
+ let end = DELEGATION_PROPOSAL_BRIEFING_MAX_BYTES - Buffer.byteLength(suffix, "utf8");
48
+ while (end > 0) {
49
+ const byte = source[end];
50
+ if (byte === undefined || (byte & 0xc0) !== 0x80) break;
51
+ end -= 1;
52
+ }
53
+ return `${source.subarray(0, end).toString("utf8")}${suffix}`;
54
+ }
55
+
56
+ const ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
57
+
58
+ function malformed(detail: string): DelegationPlanValidation {
59
+ return { ok: false, reason: "delegation_plan_malformed", detail };
60
+ }
61
+
62
+ export function validateDelegationPlan(input: ValidateDelegationPlanInput): DelegationPlanValidation {
63
+ if (input.value === null || typeof input.value !== "object" || Array.isArray(input.value)) {
64
+ return malformed("delegation plan must be an object");
65
+ }
66
+ const record = input.value as Record<string, unknown>;
67
+ if (Object.keys(record).some((key) => key !== "tasks") || !Array.isArray(record.tasks)) {
68
+ return malformed("delegation plan must carry only tasks[]");
69
+ }
70
+ if (record.tasks.length === 0) return malformed("delegation plan must carry at least one task");
71
+ if (record.tasks.length > input.maxTasks) {
72
+ return {
73
+ ok: false,
74
+ reason: "delegation_plan_over_max_tasks",
75
+ detail: `delegation plan returned ${record.tasks.length} tasks, above maxTasks ${input.maxTasks}`,
76
+ };
77
+ }
78
+ const roster = new Set(input.roster);
79
+ const ids = new Set<string>();
80
+ const tasks: DelegationPlanTask[] = [];
81
+ for (const raw of record.tasks) {
82
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return malformed("every task must be an object");
83
+ const task = raw as Record<string, unknown>;
84
+ if (
85
+ Object.keys(task).some((key) => !["id", "agent", "description", "depends_on", "writes", "mode"].includes(key)) ||
86
+ typeof task.id !== "string" ||
87
+ !ID_RE.test(task.id) ||
88
+ typeof task.agent !== "string" ||
89
+ task.agent.length === 0 ||
90
+ typeof task.description !== "string" ||
91
+ task.description.trim().length === 0 ||
92
+ !Array.isArray(task.depends_on) ||
93
+ task.depends_on.some((value) => typeof value !== "string" || value.length === 0) ||
94
+ !Array.isArray(task.writes) ||
95
+ task.writes.some((value) => typeof value !== "string" || value.length === 0) ||
96
+ (task.mode !== undefined && task.mode !== "sequential" && task.mode !== "parallel")
97
+ ) {
98
+ return malformed("each task requires id, agent, description, depends_on[], writes[], and an optional valid mode");
99
+ }
100
+ if (ids.has(task.id)) {
101
+ return { ok: false, reason: "delegation_plan_duplicate_id", detail: `duplicate task id '${task.id}'` };
102
+ }
103
+ if (!roster.has(task.agent)) {
104
+ return {
105
+ ok: false,
106
+ reason: "delegation_plan_roster_violation",
107
+ detail: `task '${task.id}' names agent '${task.agent}' outside the roster`,
108
+ };
109
+ }
110
+ let writes: ReadonlyArray<string>;
111
+ try {
112
+ writes = normalizeWriteBoundary(task.writes as string[]);
113
+ } catch (error) {
114
+ return malformed(`task '${task.id}' has invalid writes: ${error instanceof Error ? error.message : String(error)}`);
115
+ }
116
+ const outside = writes.find((path) => !pathBoundaryCovers(input.writes, path));
117
+ if (outside !== undefined) {
118
+ return {
119
+ ok: false,
120
+ reason: "delegation_plan_writes_outside_boundary",
121
+ detail: `task '${task.id}' writes '${outside}' outside the plan step boundary`,
122
+ };
123
+ }
124
+ ids.add(task.id);
125
+ tasks.push({
126
+ id: task.id,
127
+ agent: task.agent,
128
+ description: task.description,
129
+ depends_on: [...(task.depends_on as string[])],
130
+ writes,
131
+ ...(task.mode !== undefined ? { mode: task.mode as DelegationTaskMode } : {}),
132
+ });
133
+ }
134
+ for (const task of tasks) {
135
+ const unknown = task.depends_on.find((dependency) => !ids.has(dependency));
136
+ if (unknown !== undefined) {
137
+ return {
138
+ ok: false,
139
+ reason: "delegation_plan_dependency_unknown",
140
+ detail: `task '${task.id}' depends on unknown task '${unknown}'`,
141
+ };
142
+ }
143
+ }
144
+ const remaining = new Set(ids);
145
+ const completed = new Set<string>();
146
+ while (remaining.size > 0) {
147
+ const ready = tasks.filter(
148
+ (task) => remaining.has(task.id) && task.depends_on.every((dependency) => completed.has(dependency)),
149
+ );
150
+ if (ready.length === 0) {
151
+ return {
152
+ ok: false,
153
+ reason: "delegation_plan_dependency_cycle",
154
+ detail: `delegation plan dependency cycle includes ${[...remaining].sort().join(", ")}`,
155
+ };
156
+ }
157
+ for (const task of ready) {
158
+ remaining.delete(task.id);
159
+ completed.add(task.id);
160
+ }
161
+ }
162
+ const plan = { tasks } satisfies DelegationPlan;
163
+ return { ok: true, plan, hash: createHash("sha256").update(JSON.stringify(plan)).digest("hex") };
164
+ }
@@ -3,7 +3,7 @@ import type { ResultContract } from "../agents/result-contract.js";
3
3
  import type { AgentAutomationAuthority } from "../agents/spec.js";
4
4
  import type { ExecutionRole } from "./execution-role.js";
5
5
 
6
- export type ExecutionPlanTopology = "parallel" | "sequential" | "pipeline" | "review" | "compete" | "fleet";
6
+ export type ExecutionPlanTopology = "parallel" | "sequential" | "pipeline" | "review" | "compete" | "council" | "fleet";
7
7
  export type ExecutionPlanScope = "readonly" | "workspace";
8
8
  export type ExecutionPlanFailurePolicy = "stop" | "continue";
9
9
 
@@ -56,6 +56,19 @@ export interface ExecutionPlanAgentStep {
56
56
  * contract declares no boundary at all and is therefore not enforced.
57
57
  */
58
58
  writes?: ReadonlyArray<string>;
59
+ /** Exact per-step route defaults from a version 5 fleet contract. */
60
+ target?: string;
61
+ profile?: string;
62
+ /** Version 5 gate authoring and baseline execution facts. */
63
+ gate?: { path: string; commandId: string };
64
+ /** Version 5 dynamic planning facts. */
65
+ plan?: {
66
+ roster: ReadonlyArray<string>;
67
+ maxTasks: number;
68
+ proposals: boolean;
69
+ };
70
+ /** The plan step that admitted this dynamically authored task. */
71
+ planParentId?: string;
59
72
  }
60
73
 
61
74
  /**
@@ -85,6 +98,8 @@ export interface ExecutionPlanCodeStep {
85
98
  commitFrom?: ReadonlyArray<string>;
86
99
  /** Declared write boundary; see `ExecutionPlanAgentStep.writes`. */
87
100
  writes?: ReadonlyArray<string>;
101
+ /** A gate check executes a declared gate file through this command. */
102
+ gate?: { gateId: string; path: string };
88
103
  }
89
104
 
90
105
  export type ExecutionPlanStep = ExecutionPlanAgentStep | ExecutionPlanCodeStep;
@@ -106,6 +121,8 @@ export interface ExecutionPlan {
106
121
  topology: ExecutionPlanTopology;
107
122
  rootTask: string;
108
123
  maxWorkers: number;
124
+ /** Serialize writer admission when set. The only supported value in this cut is one. */
125
+ writers?: 1;
109
126
  onFailure: ExecutionPlanFailurePolicy;
110
127
  steps: ReadonlyArray<ExecutionPlanStep>;
111
128
  loops: ReadonlyArray<ExecutionPlanLoop>;
@@ -240,6 +257,7 @@ function checkLoops(steps: ReadonlyArray<ExecutionPlanStep>, loops: ReadonlyArra
240
257
  function checkWriteBoundaryWaves(
241
258
  steps: ReadonlyArray<ExecutionPlanStep>,
242
259
  waves: ReadonlyArray<ReadonlyArray<string>>,
260
+ writerLimit?: 1,
243
261
  ): void {
244
262
  const byId = new Map(steps.map((step) => [step.id, step]));
245
263
  for (const [index, wave] of waves.entries()) {
@@ -250,7 +268,7 @@ function checkWriteBoundaryWaves(
250
268
  const declared = members.filter((step) => step.writes !== undefined);
251
269
  if (declared.length === 0) continue;
252
270
  const undeclared = members.filter((step) => step.writes === undefined);
253
- if (undeclared.length > 0) {
271
+ if (undeclared.length > 0 && writerLimit !== 1) {
254
272
  throw new Error(
255
273
  `execution plan: wave ${index} mixes boundary-enforced steps (${declared
256
274
  .map((step) => step.id)
@@ -260,7 +278,7 @@ function checkWriteBoundaryWaves(
260
278
  );
261
279
  }
262
280
  const writers = declared.filter((step) => (step.writes?.length ?? 0) > 0);
263
- if (writers.length > 1) {
281
+ if (writers.length > 1 && writerLimit !== 1) {
264
282
  throw new Error(
265
283
  `execution plan: wave ${index} schedules ${writers.length} steps that may write (${writers
266
284
  .map((step) => step.id)
@@ -273,6 +291,9 @@ function checkWriteBoundaryWaves(
273
291
  }
274
292
 
275
293
  export function compileExecutionPlan(input: ExecutionPlanInput): ExecutionPlan {
294
+ if (input.writers !== undefined && input.writers !== 1) {
295
+ throw new Error("execution plan: writers must be 1 when present");
296
+ }
276
297
  const steps = canonicalSteps(input.steps);
277
298
  const loops = (input.loops ?? []).map((loop) => ({
278
299
  ...loop,
@@ -281,12 +302,13 @@ export function compileExecutionPlan(input: ExecutionPlanInput): ExecutionPlan {
281
302
  }));
282
303
  checkLoops(steps, loops);
283
304
  const waves = executionPlanWaves(steps, input.maxWorkers);
284
- checkWriteBoundaryWaves(steps, waves);
305
+ checkWriteBoundaryWaves(steps, waves, input.writers);
285
306
  const canonical = {
286
307
  version: 4 as const,
287
308
  topology: input.topology,
288
309
  rootTask: input.rootTask,
289
310
  maxWorkers: input.maxWorkers,
311
+ ...(input.writers === 1 ? { writers: 1 as const } : {}),
290
312
  onFailure: input.onFailure,
291
313
  steps,
292
314
  loops,
@@ -309,6 +331,55 @@ export function executionPlanAncestors(plan: ExecutionPlan, stepId: string): Rea
309
331
  return ancestors;
310
332
  }
311
333
 
334
+ /** Recompile a plan with coordinator-validated dynamic agent tasks. */
335
+ export function spliceExecutionPlan(
336
+ plan: ExecutionPlan,
337
+ parentId: string,
338
+ tasks: ReadonlyArray<{
339
+ id: string;
340
+ agentId: string;
341
+ task: string;
342
+ dependencies: ReadonlyArray<string>;
343
+ writes: ReadonlyArray<string>;
344
+ target?: string;
345
+ profile?: string;
346
+ requestedAuthority: AgentAutomationAuthority;
347
+ approvedAuthority: AgentAutomationAuthority | null;
348
+ expectedResultContract: ResultContract["kind"];
349
+ executionRole: ExecutionRole;
350
+ }>,
351
+ ): ExecutionPlan {
352
+ const parent = plan.steps.find((step) => step.id === parentId);
353
+ if (parent?.kind !== "agent" || parent.plan === undefined) {
354
+ throw new Error(`execution plan: '${parentId}' is not a plan step`);
355
+ }
356
+ const inserted: ExecutionPlanStepInput[] = tasks.map((task) => ({
357
+ kind: "agent",
358
+ id: task.id,
359
+ agentId: task.agentId,
360
+ executionRole: task.executionRole,
361
+ scope: task.writes.length > 0 ? "workspace" : "readonly",
362
+ expectedResultContract: task.expectedResultContract,
363
+ requestedAuthority: task.requestedAuthority,
364
+ approvedAuthority: task.approvedAuthority,
365
+ dependencies: [parentId, ...task.dependencies],
366
+ task: task.task,
367
+ writes: [...task.writes],
368
+ ...(task.target !== undefined ? { target: task.target } : {}),
369
+ ...(task.profile !== undefined ? { profile: task.profile } : {}),
370
+ planParentId: parentId,
371
+ }));
372
+ return compileExecutionPlan({
373
+ topology: plan.topology,
374
+ rootTask: plan.rootTask,
375
+ maxWorkers: plan.maxWorkers,
376
+ ...(plan.writers === 1 ? { writers: 1 as const } : {}),
377
+ onFailure: plan.onFailure,
378
+ steps: [...plan.steps, ...inserted],
379
+ loops: plan.loops,
380
+ });
381
+ }
382
+
312
383
  /** A linear step declares no dependencies; the compiler chains them by position. */
313
384
  export type ExecutionPlanLinearStepInput =
314
385
  | (Omit<ExecutionPlanAgentStep, "kind" | "dependencies"> & { kind?: "agent" })
@@ -317,7 +388,7 @@ export type ExecutionPlanLinearStepInput =
317
388
  export function compileLinearExecutionPlan(
318
389
  input: Omit<ExecutionPlanInput, "steps"> & { steps: ReadonlyArray<ExecutionPlanLinearStepInput> },
319
390
  ): ExecutionPlan {
320
- const parallel = input.topology === "parallel" || input.topology === "compete";
391
+ const parallel = input.topology === "parallel" || input.topology === "compete" || input.topology === "council";
321
392
  return compileExecutionPlan({
322
393
  ...input,
323
394
  steps: input.steps.map((step, index): ExecutionPlanStepInput => {
@@ -47,7 +47,7 @@ export function isExecutionRole(value: unknown): value is ExecutionRole {
47
47
  * statistics belong to: every compete candidate occupies a distinct `candidate`
48
48
  * position but they are all ordinary `builder` routes.
49
49
  */
50
- export type GateTopologyRole = "builder" | "reviewer" | "candidate" | "judge";
50
+ export type GateTopologyRole = "builder" | "reviewer" | "candidate" | "judge" | "member" | "synthesis";
51
51
 
52
52
  /**
53
53
  * Facts the role is derived from. `capabilityClass` and `resultContractKind`
@@ -86,6 +86,8 @@ export function deriveExecutionRole(input: ExecutionRoleInput): ExecutionRole {
86
86
  if (input.attempt > 0) return "recovery";
87
87
  if (input.gateRole === "reviewer") return "reviewer";
88
88
  if (input.gateRole === "judge") return "judge";
89
+ if (input.gateRole === "synthesis") return "judge";
90
+ if (input.gateRole === "member") return "researcher";
89
91
  if (input.gateRole === "builder" || input.gateRole === "candidate") return "builder";
90
92
  if (input.resultContractKind === "verifier-report") return "verifier";
91
93
  if (input.capabilityClass === "read-only") return "researcher";
@@ -170,9 +172,17 @@ export function gateDeciderAgentId(requested: string | undefined): string {
170
172
  * the slot. The gate validates that answer and fails closed on a malformed one,
171
173
  * so also enforcing an inapplicable recipe postcondition would fail the run
172
174
  * before its verdict could be read.
175
+ *
176
+ * `synthesis` is the third decider and belongs here for the same reason.
177
+ * {@link deriveExecutionRole} already resolves it to the `judge` role, and
178
+ * `isBoundedGateRolePrompt` admits it only under the council judge prompt,
179
+ * which asks for `{"verdict","text"}`. A council seats the read-only
180
+ * `researcher` by default, whose recipe declares `research-report`, so leaving
181
+ * the recipe postcondition on the slot sealed a contract failure on every
182
+ * correct synthesis and burned the configured retries reproducing it.
173
183
  */
174
184
  export function appliesRecipeResultContract(gateRole: GateTopologyRole | undefined): boolean {
175
- return gateRole !== "reviewer" && gateRole !== "judge";
185
+ return gateRole !== "reviewer" && gateRole !== "judge" && gateRole !== "synthesis";
176
186
  }
177
187
 
178
188
  /** The route dimensions a gate correlation is measured across. */