@iowarp/clio-coder 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/CONTRIBUTING.md +86 -19
  3. package/README.md +35 -6
  4. package/dist/{acp-TMDQZDIG.js → acp-WNAYYF4F.js} +12 -13
  5. package/dist/{agents-5N5NG3XG.js → agents-3OKXHLOI.js} +60 -57
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-Z5CCBXKQ.js → auth-VKNNMGPU.js} +21 -19
  8. package/dist/{builtins-K6TNDT24.js → builtins-WGALA46I.js} +9 -4
  9. package/dist/{chunk-XE3PCIXH.js → chunk-23L32XTI.js} +12 -9
  10. package/dist/{chunk-I64IFBLB.js → chunk-25QBEXRS.js} +18 -11
  11. package/dist/{chunk-CDNVLKUX.js → chunk-26QSH3EJ.js} +13 -7
  12. package/dist/{chunk-QQLGQY2A.js → chunk-2ASED4PZ.js} +22 -22
  13. package/dist/{chunk-MCEPRMZW.js → chunk-2CU2H6KE.js} +2 -2
  14. package/dist/chunk-2DSOYNFC.js +108 -0
  15. package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
  16. package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
  17. package/dist/{chunk-O3YUNJZ2.js → chunk-2ZSONWVL.js} +82 -25
  18. package/dist/{chunk-2NHR3NAY.js → chunk-36CT5VVL.js} +331 -42
  19. package/dist/{chunk-2X4RYJTJ.js → chunk-3GY4F45V.js} +3 -3
  20. package/dist/{chunk-ZW55JB7N.js → chunk-3ODX73FK.js} +4 -6
  21. package/dist/{chunk-PBP4B7XR.js → chunk-3UNOLWNZ.js} +3 -3
  22. package/dist/{chunk-4JDLP6ZS.js → chunk-3UUXNFEX.js} +14 -10
  23. package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
  24. package/dist/{chunk-ZW4HH5JJ.js → chunk-4M6Z5QVF.js} +6 -6
  25. package/dist/{chunk-K6BSR66V.js → chunk-4NSRCOYP.js} +4 -1
  26. package/dist/{chunk-M2DAX4F6.js → chunk-4WR7VSYB.js} +2 -2
  27. package/dist/{chunk-FSP7CMNU.js → chunk-54X7T7DK.js} +61 -6
  28. package/dist/{chunk-54ODD65L.js → chunk-5636DCO5.js} +4 -4
  29. package/dist/chunk-57XXR6DR.js +3763 -0
  30. package/dist/{chunk-3KIPBMUA.js → chunk-5ICU3EUH.js} +2 -2
  31. package/dist/{chunk-77QIVUZB.js → chunk-5MEZN6CB.js} +4 -4
  32. package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
  33. package/dist/{chunk-YJISEZKC.js → chunk-5TUB6SLS.js} +6 -6
  34. package/dist/{chunk-IMXMHHMQ.js → chunk-6OSVSQL5.js} +341 -57
  35. package/dist/{chunk-Q4XWMHX6.js → chunk-6PAZTBPA.js} +14 -2
  36. package/dist/{chunk-FVDGR2ZL.js → chunk-6Q3CYFD3.js} +112 -39
  37. package/dist/{chunk-IDNA72AH.js → chunk-6QOTUPRG.js} +155 -36
  38. package/dist/{chunk-X7IARSHT.js → chunk-6UINWWS6.js} +16 -10
  39. package/dist/{chunk-CYZW7JHJ.js → chunk-72YIHOZQ.js} +9 -9
  40. package/dist/{chunk-IKSLQ4XV.js → chunk-75W7L2E2.js} +752 -861
  41. package/dist/{chunk-CRFOIAX3.js → chunk-7UGL4MB5.js} +6 -6
  42. package/dist/{chunk-HIICAHCJ.js → chunk-AUPNRN7C.js} +2 -2
  43. package/dist/{chunk-7BHIY2MW.js → chunk-BJVFZO5U.js} +8 -50
  44. package/dist/{chunk-B74PXLU7.js → chunk-CUSRQKPU.js} +65 -3
  45. package/dist/chunk-DQOVN6KV.js +386 -0
  46. package/dist/{chunk-E7GT7O5N.js → chunk-DT3LWJOB.js} +7 -4
  47. package/dist/chunk-DXKJURES.js +671 -0
  48. package/dist/{chunk-JBCS7CRR.js → chunk-EL24TAU4.js} +10 -10
  49. package/dist/{chunk-TPEQIQIE.js → chunk-ELWDPP3Y.js} +8 -8
  50. package/dist/{chunk-NDINPTJ4.js → chunk-ELZVTCGV.js} +5 -4
  51. package/dist/chunk-EXLD33WO.js +381 -0
  52. package/dist/chunk-FEAXX7B6.js +101 -0
  53. package/dist/{chunk-RLYRBIYQ.js → chunk-FFUPXJC4.js} +90 -331
  54. package/dist/{chunk-5PFYMY2V.js → chunk-FTMGRKEF.js} +2 -2
  55. package/dist/{chunk-34BHNEE3.js → chunk-GHS5EBTQ.js} +58 -7
  56. package/dist/{chunk-DYHAXKHD.js → chunk-GWZNEVM2.js} +12 -8
  57. package/dist/chunk-GX5WYQO4.js +59 -0
  58. package/dist/chunk-GYV6VZOC.js +26 -0
  59. package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
  60. package/dist/chunk-I2DWJ4GM.js +390 -0
  61. package/dist/{chunk-TXOTCRLG.js → chunk-I5FWO7L5.js} +5 -5
  62. package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
  63. package/dist/{chunk-XQRY4DTA.js → chunk-IGLP3ODT.js} +10 -10
  64. package/dist/chunk-IRXAATOX.js +539 -0
  65. package/dist/chunk-IXIY2H4R.js +44 -0
  66. package/dist/{chunk-SSEYRH53.js → chunk-IZXGRF7P.js} +92 -147
  67. package/dist/{chunk-5TSRNF4G.js → chunk-JCI2ROMZ.js} +164 -6
  68. package/dist/{chunk-JWJGP5DQ.js → chunk-JEIYHLOR.js} +7 -7
  69. package/dist/{chunk-F2I26BDK.js → chunk-JQLNNIKT.js} +4 -4
  70. package/dist/{chunk-BYMNWQ7O.js → chunk-JSD46VO2.js} +315 -63
  71. package/dist/{chunk-AK5XEFVZ.js → chunk-JT2RFCC5.js} +64 -14
  72. package/dist/{chunk-MCMZMDAC.js → chunk-K6T2ZAMZ.js} +168 -6
  73. package/dist/{chunk-PGF63K6I.js → chunk-KFV5L5SK.js} +73 -4
  74. package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
  75. package/dist/{chunk-PJX3WQUQ.js → chunk-LLXSDWXS.js} +3 -3
  76. package/dist/{chunk-DZAW46HP.js → chunk-LTIKRKFL.js} +3 -3
  77. package/dist/{chunk-DZEK6CJN.js → chunk-N56KALIC.js} +21 -21
  78. package/dist/{chunk-B7HM5Z7T.js → chunk-NAI6ZFCY.js} +9 -5
  79. package/dist/{chunk-I66ZTYNP.js → chunk-NRO2BJRH.js} +2656 -2213
  80. package/dist/{chunk-ZGNYYXQ6.js → chunk-NXIMQY5W.js} +3 -3
  81. package/dist/{chunk-IKOZFYBN.js → chunk-NXYCB2VD.js} +149 -106
  82. package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
  83. package/dist/{chunk-462T4EGZ.js → chunk-O5CVSAG5.js} +2 -2
  84. package/dist/chunk-ODGTEFFI.js +50 -0
  85. package/dist/{chunk-3F7VUY77.js → chunk-OEJSLEPW.js} +2 -2
  86. package/dist/{chunk-KKOJXO6R.js → chunk-OMQNJVKW.js} +4 -2
  87. package/dist/{chunk-5KW52TEP.js → chunk-Q4WO54TA.js} +132 -77
  88. package/dist/{chunk-W6NIE6OW.js → chunk-QUFRYSWI.js} +13 -7
  89. package/dist/{chunk-42FMPA75.js → chunk-QZWQA4DE.js} +2 -2
  90. package/dist/chunk-R6Q67RJH.js +134 -0
  91. package/dist/{chunk-W4YEMFBX.js → chunk-RAY4OVGZ.js} +3 -3
  92. package/dist/{chunk-ZNT2M6TG.js → chunk-RQCKCSRL.js} +17 -17
  93. package/dist/{chunk-LJID3DYZ.js → chunk-RXTN6AKH.js} +3 -3
  94. package/dist/{chunk-P75RZCJW.js → chunk-RZDWV63N.js} +3 -3
  95. package/dist/{chunk-UH632ZYL.js → chunk-S6PYF2XF.js} +2 -2
  96. package/dist/{chunk-HJWWJ6IL.js → chunk-TOIVGRUX.js} +17 -5
  97. package/dist/{chunk-HLAFFSEK.js → chunk-TQAHXW6Y.js} +2 -2
  98. package/dist/{chunk-JIEGK6UF.js → chunk-U6TMQNSI.js} +48 -4
  99. package/dist/{chunk-2HFQNRV3.js → chunk-UEPWCCTY.js} +12 -12
  100. package/dist/chunk-UOIZ7DA4.js +41 -0
  101. package/dist/{chunk-UH347SHR.js → chunk-USR47QNF.js} +11 -11
  102. package/dist/{chunk-AZ4WMN4W.js → chunk-V6HJFQZE.js} +2 -2
  103. package/dist/chunk-V76WTFTW.js +318 -0
  104. package/dist/{chunk-NMJXSHBJ.js → chunk-W54I7H25.js} +2 -2
  105. package/dist/{chunk-KPXDY6QF.js → chunk-XRZT5WY5.js} +2 -2
  106. package/dist/{chunk-UBRFI4HS.js → chunk-XULDXHTN.js} +142 -50
  107. package/dist/chunk-XXYSBZIQ.js +283 -0
  108. package/dist/{chunk-HKMD33FO.js → chunk-Y55JBDO5.js} +405 -122
  109. package/dist/{chunk-XOXV5GKE.js → chunk-YD5GIKET.js} +17 -8
  110. package/dist/{chunk-XGDPUNND.js → chunk-YECAMM3D.js} +2 -2
  111. package/dist/{chunk-BO7Y52RY.js → chunk-YNFKXPEC.js} +7 -7
  112. package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
  113. package/dist/{chunk-M2WXEHER.js → chunk-ZA4VCIGV.js} +2 -2
  114. package/dist/cli/index.js +42 -40
  115. package/dist/{clio-7VB377CC.js → clio-QLICPCF5.js} +7 -7
  116. package/dist/{code-nav-YVLCYA7V.js → code-nav-IJR2DBPR.js} +9 -9
  117. package/dist/{components-UBWCQSRW.js → components-2TGAI2RC.js} +5 -6
  118. package/dist/{config-4HVOS65E.js → config-IUA6OYNS.js} +88 -81
  119. package/dist/{configure-PIWO7B24.js → configure-VEPX4NMX.js} +26 -25
  120. package/dist/{context-KQYIWPWT.js → context-2DKHWH2T.js} +60 -45
  121. package/dist/{context-IYEHL3WQ.js → context-4MPR7WKB.js} +78 -69
  122. package/dist/{context-N6ZE3LGJ.js → context-BOYF5EJM.js} +15 -11
  123. package/dist/{context-clear-G4OGZJDS.js → context-clear-S4ZJCQUX.js} +73 -65
  124. package/dist/context-map-COB37XXN.js +505 -0
  125. package/dist/{context-working-set-BWLF6LJP.js → context-working-set-3I3FYX6Y.js} +18 -17
  126. package/dist/detail-A7JAVSIG.js +98 -0
  127. package/dist/{dispatch-runner-2QQAITS3.js → dispatch-runner-RJ5I2F2O.js} +99 -75
  128. package/dist/{docs-PD3EXDKU.js → docs-SPOV3BAN.js} +3 -5
  129. package/dist/{doctor-LHBD36VU.js → doctor-DKICC2SN.js} +71 -48
  130. package/dist/{eval-C45FYRJ6.js → eval-OQOQUDHK.js} +308 -146
  131. package/dist/{eval-inventory-6DEJPLBF.js → eval-inventory-Y6QRFOH5.js} +4 -4
  132. package/dist/{evidence-6SHONYAF.js → evidence-4DQ25GUQ.js} +79 -175
  133. package/dist/evidence-4F5USFKH.js +208 -0
  134. package/dist/{evolve-KRKMV72X.js → evolve-GSS52E5J.js} +71 -67
  135. package/dist/{extensions-KPZ2UHBB.js → extensions-G7MFLYHT.js} +8 -9
  136. package/dist/{fleet-IVTCKDHT.js → fleet-Q37YHHAQ.js} +126 -118
  137. package/dist/{fleet-commands-EDWL3IT7.js → fleet-commands-G7E4N7SM.js} +16 -13
  138. package/dist/{fleet-decisions-YP3YEFGK.js → fleet-decisions-O7M6QBA2.js} +9 -8
  139. package/dist/{fleet-graph-ZFWKHY2M.js → fleet-graph-TOUBW6OW.js} +21 -20
  140. package/dist/{fleet-inspect-FVUNCBML.js → fleet-inspect-SW33JJNI.js} +65 -60
  141. package/dist/{fleet-preflight-UN5XED4R.js → fleet-preflight-CV2655TW.js} +4 -5
  142. package/dist/{fleet-validate-XOWC4HSX.js → fleet-validate-KESZX2YH.js} +25 -24
  143. package/dist/{fleet-verify-UN3SODEL.js → fleet-verify-UQPMTVE3.js} +66 -61
  144. package/dist/{fleet-view-TWHJKCN6.js → fleet-view-MN2VG4MR.js} +65 -60
  145. package/dist/{init-T2QORQ3Y.js → init-PXEXQSBF.js} +90 -82
  146. package/dist/{interop-IN5I2A66.js → interop-ZG5T62U3.js} +12 -13
  147. package/dist/inventory-C26CFDRR.js +101 -0
  148. package/dist/{library-LSCATDLZ.js → library-B2W4N74O.js} +29 -29
  149. package/dist/{memory-HYOKAGGJ.js → memory-YCANYS5A.js} +73 -69
  150. package/dist/{models-2GPMFYCM.js → models-GERTU3YI.js} +51 -47
  151. package/dist/{monitor-E4ASVUJH.js → monitor-CPNIUULB.js} +74 -67
  152. package/dist/{orchestrator-DDMPR3PY.js → orchestrator-J4BSH4WQ.js} +1288 -1606
  153. package/dist/{panes-E3RUXOW5.js → panes-BOHAEGYC.js} +4 -4
  154. package/dist/{panes-IXKLOKA2.js → panes-NXSLDQZ2.js} +10 -11
  155. package/dist/{paths-L7LGY6RN.js → paths-VSUWNC22.js} +6 -7
  156. package/dist/reset-TNWTB5LU.js +343 -0
  157. package/dist/{resources-OTRSN34L.js → resources-4PXNMD5G.js} +29 -22
  158. package/dist/{run-5DEYH5QK.js → run-D6XJ34CN.js} +132 -132
  159. package/dist/{share-IHWTLO3M.js → share-2NWMJJEE.js} +27 -27
  160. package/dist/{skills-IYMXMKW4.js → skills-KR7WON5G.js} +40 -33
  161. package/dist/{skills-eval-DROHSJAR.js → skills-eval-O2ZNOLDS.js} +81 -77
  162. package/dist/{skills-inventory-D7X4L4ZX.js → skills-inventory-ZZOUBK7O.js} +23 -22
  163. package/dist/{slash-commands-QBM7UZ3B.js → slash-commands-ZXPJD64J.js} +47 -37
  164. package/dist/{steer-Z5DO23FJ.js → steer-XA25PSCS.js} +4 -4
  165. package/dist/{support-U7QOWY26.js → support-7EMVWYG2.js} +6 -6
  166. package/dist/{targets-P2FUC4IL.js → targets-OMH2XCSN.js} +50 -49
  167. package/dist/tasks-IPAGMEIX.js +36 -0
  168. package/dist/{terminal-lease-YREJ3JX2.js → terminal-lease-C2J3JYRE.js} +4 -4
  169. package/dist/{tools-5B7RO6MV.js → tools-EFFEAIDP.js} +8 -9
  170. package/dist/{trace-YMGMUM6A.js → trace-FXMXUZUF.js} +7 -7
  171. package/dist/uninstall-HALS6BLF.js +407 -0
  172. package/dist/upgrade-MS72RJEP.js +306 -0
  173. package/dist/{usage-ME5MPXGX.js → usage-NHG6MCJM.js} +162 -108
  174. package/dist/{verifiers-BVZ7IWOO.js → verifiers-7AUNVXDY.js} +155 -22
  175. package/dist/{verify-5K7ZKQFC.js → verify-FWYGPKMR.js} +14 -12
  176. package/dist/{web-fetch-MPARV2K7.js → web-fetch-V4FKSDAV.js} +4 -4
  177. package/dist/{wiki-generate-F5W5QTYY.js → wiki-generate-743CIGJW.js} +99 -90
  178. package/dist/{with-panes-BYOJCLAM.js → with-panes-BDQEWBRT.js} +10 -10
  179. package/dist/worker/entry.js +72 -68
  180. package/docs/README.md +3 -2
  181. package/docs/architecture/acp.md +17 -0
  182. package/docs/architecture/artifact-placement.md +1 -0
  183. package/docs/architecture/artifact-versions.md +2 -2
  184. package/docs/architecture/context-engine.md +4 -0
  185. package/docs/architecture/dispatch-typed-intent.md +1 -1
  186. package/docs/architecture/evidence-and-memory.md +1 -1
  187. package/docs/architecture/middleware-and-components.md +1 -1
  188. package/docs/architecture/model-catalog.md +21 -10
  189. package/docs/architecture/observability.md +19 -2
  190. package/docs/architecture/prompt-envelope-and-tools.md +17 -5
  191. package/docs/architecture/provider-adapter-cookbook.md +63 -0
  192. package/docs/architecture/safety-model.md +25 -22
  193. package/docs/architecture/tui-design.md +1 -1
  194. package/docs/guide/built-in-agents.md +25 -11
  195. package/docs/guide/commands-and-modes.md +18 -3
  196. package/docs/guide/configuration-and-targets.md +100 -10
  197. package/docs/guide/configuration-reference.md +17 -7
  198. package/docs/guide/environment-variables.md +4 -2
  199. package/docs/guide/installation-and-lifecycle.md +37 -4
  200. package/docs/guide/proactive-memory.md +66 -55
  201. package/docs/guide/skills-marketplace.md +18 -0
  202. package/docs/guide/tool-usage.md +78 -3
  203. package/docs/history/config-knobs-audit.md +2 -2
  204. package/docs/process/development-pipeline.md +40 -2
  205. package/docs/process/eval-runner.md +67 -3
  206. package/docs/process/git-commit-provenance.md +15 -0
  207. package/docs/process/release-cut-checklist.md +207 -0
  208. package/docs/process/scientific-validation.md +18 -17
  209. package/evals/behavioral-machinery-support.ts +1 -0
  210. package/evals/behavioral-machinery.yaml +1 -1
  211. package/evals/behavioral-model.yaml +3 -2
  212. package/package.json +2 -2
  213. package/skills/README.md +7 -5
  214. package/skills/coding/ast-grep/SKILL.md +101 -30
  215. package/skills/coding/ast-grep/evals.md +26 -0
  216. package/skills/coding/coding-standards/SKILL.md +47 -2
  217. package/skills/coding/coding-standards/evals.md +23 -0
  218. package/skills/coding/prototype/SKILL.md +87 -28
  219. package/skills/coding/prototype/evals.md +19 -0
  220. package/skills/coding/tdd/SKILL.md +80 -53
  221. package/skills/coding/tdd/evals.md +20 -0
  222. package/skills/context/context-handoff/SKILL.md +43 -2
  223. package/skills/context/context-handoff/evals.md +44 -0
  224. package/skills/context/context-prime/SKILL.md +45 -15
  225. package/skills/context/context-prime/evals.md +45 -0
  226. package/skills/git/branch-closeout/SKILL.md +132 -0
  227. package/skills/git/branch-closeout/evals.md +133 -0
  228. package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
  229. package/skills/git/file-ticket/SKILL.md +77 -63
  230. package/skills/git/file-ticket/assets/issue-template.md +22 -0
  231. package/skills/git/file-ticket/evals.md +31 -26
  232. package/skills/git/file-ticket/references/issue-discovery.md +49 -0
  233. package/skills/git/fix-issue/SKILL.md +87 -64
  234. package/skills/git/fix-issue/evals.md +35 -31
  235. package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
  236. package/skills/git/resolve-merge-conflicts/SKILL.md +100 -51
  237. package/skills/git/resolve-merge-conflicts/evals.md +52 -25
  238. package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
  239. package/skills/git/ship/SKILL.md +103 -67
  240. package/skills/git/ship/assets/pr-template.md +21 -0
  241. package/skills/git/ship/evals.md +44 -28
  242. package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
  243. package/skills/git/worktree-create/SKILL.md +80 -50
  244. package/skills/git/worktree-create/evals.md +40 -33
  245. package/skills/git/worktree-create/references/worktree-setup.md +62 -66
  246. package/skills/git/worktree-merge/SKILL.md +112 -65
  247. package/skills/git/worktree-merge/evals.md +42 -34
  248. package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
  249. package/skills/planning/archify/SKILL.md +196 -0
  250. package/skills/planning/archify/evals.md +65 -0
  251. package/skills/planning/architecture/SKILL.md +61 -12
  252. package/skills/planning/architecture/evals.md +65 -0
  253. package/skills/planning/backlog/SKILL.md +130 -14
  254. package/skills/planning/backlog/evals.md +142 -0
  255. package/skills/planning/prd/SKILL.md +47 -6
  256. package/skills/planning/prd/evals.md +54 -0
  257. package/skills/planning/product-intent/SKILL.md +57 -2
  258. package/skills/planning/product-intent/evals.md +70 -0
  259. package/skills/planning/tech-spec/SKILL.md +53 -2
  260. package/skills/planning/tech-spec/evals.md +73 -0
  261. package/skills/registry.yaml +58 -50
  262. package/skills/remote.yaml +13 -0
  263. package/skills/research/arxiv-literature/SKILL.md +76 -18
  264. package/skills/research/arxiv-literature/evals.md +50 -0
  265. package/skills/research/experiment-protocol/SKILL.md +20 -1
  266. package/skills/research/experiment-protocol/evals.md +23 -0
  267. package/skills/research/scientific-debugging/SKILL.md +24 -1
  268. package/skills/research/scientific-debugging/evals.md +18 -0
  269. package/skills/research/scientific-modernization/SKILL.md +26 -1
  270. package/skills/research/scientific-modernization/evals.md +27 -0
  271. package/skills/skill-marketplace.json +63 -28
  272. package/skills/workflow/cut-it/SKILL.md +64 -5
  273. package/skills/workflow/cut-it/evals.md +101 -0
  274. package/skills/workflow/design-council/SKILL.md +112 -27
  275. package/skills/workflow/design-council/evals.md +161 -0
  276. package/skills/workflow/grill-me/SKILL.md +85 -10
  277. package/skills/workflow/grill-me/evals.md +153 -0
  278. package/skills/workflow/workflow-distiller/SKILL.md +76 -17
  279. package/skills/workflow/workflow-distiller/evals.md +118 -0
  280. package/src/cli/args.ts +0 -8
  281. package/src/cli/configure-interop.ts +105 -13
  282. package/src/cli/configure-oauth.ts +57 -0
  283. package/src/cli/configure-onboarding.ts +980 -0
  284. package/src/cli/configure-target.ts +594 -0
  285. package/src/cli/configure.ts +1084 -529
  286. package/src/cli/context-map.ts +114 -0
  287. package/src/cli/context.ts +4 -0
  288. package/src/cli/doctor-state-size.ts +1 -12
  289. package/src/cli/doctor-validation-contract.ts +28 -0
  290. package/src/cli/doctor.ts +5 -0
  291. package/src/cli/evidence-detail.ts +1 -75
  292. package/src/cli/evidence-inventory.ts +1 -167
  293. package/src/cli/index.ts +3 -0
  294. package/src/cli/lifecycle-presenter.ts +436 -0
  295. package/src/cli/models.ts +10 -2
  296. package/src/cli/modes/print.ts +5 -1
  297. package/src/cli/reset.ts +228 -106
  298. package/src/cli/run.ts +7 -4
  299. package/src/cli/select.ts +664 -0
  300. package/src/cli/skills.ts +9 -2
  301. package/src/cli/targets.ts +3 -0
  302. package/src/cli/tasks.ts +84 -0
  303. package/src/cli/uninstall.ts +233 -165
  304. package/src/cli/upgrade.ts +210 -150
  305. package/src/cli/usage.ts +92 -27
  306. package/src/cli/validate-model.ts +3 -3
  307. package/src/cli/verifiers.ts +147 -1
  308. package/src/cli/wiki-generate.ts +1 -0
  309. package/src/core/commit-attribution.ts +41 -1
  310. package/src/core/config.ts +56 -0
  311. package/src/core/external-diagnostic.ts +44 -0
  312. package/src/core/gateway-routing.ts +157 -0
  313. package/src/core/git-commit-attribution.ts +46 -3
  314. package/src/core/run-overrides.ts +0 -5
  315. package/src/core/safe-exec.ts +17 -2
  316. package/src/core/skill-activation.ts +92 -2
  317. package/src/core/tool-names.ts +5 -2
  318. package/src/domains/agents/builtins/architect.md +1 -1
  319. package/src/domains/agents/builtins/coder.md +1 -1
  320. package/src/domains/agents/builtins/documenter.md +1 -1
  321. package/src/domains/agents/builtins/git-master.md +1 -1
  322. package/src/domains/agents/builtins/provenance.md +7 -7
  323. package/src/domains/agents/builtins/tester.md +1 -1
  324. package/src/domains/agents/builtins/verifier.md +2 -2
  325. package/src/domains/agents/builtins/wiki-writer.md +4 -3
  326. package/src/domains/agents/builtins/world-knowledge.md +31 -0
  327. package/src/domains/agents/catalog.ts +1 -1
  328. package/src/domains/agents/result-contract.ts +70 -0
  329. package/src/domains/context/extension.ts +31 -7
  330. package/src/domains/context/refresh.ts +3 -0
  331. package/src/domains/context/wiki/frontmatter.ts +5 -2
  332. package/src/domains/context/wiki/generate.ts +6 -0
  333. package/src/domains/context/wiki/map-seed.ts +589 -0
  334. package/src/domains/context/wiki/plan.ts +2 -2
  335. package/src/domains/context/wiki/prompts.ts +43 -0
  336. package/src/domains/dispatch/active-route-planner.ts +4 -0
  337. package/src/domains/dispatch/admission.ts +29 -0
  338. package/src/domains/dispatch/agent-candidates.ts +10 -0
  339. package/src/domains/dispatch/budget-envelope.ts +86 -1
  340. package/src/domains/dispatch/capability-match.ts +1 -0
  341. package/src/domains/dispatch/capacity-lease.ts +17 -0
  342. package/src/domains/dispatch/code-step.ts +11 -4
  343. package/src/domains/dispatch/contract.ts +42 -8
  344. package/src/domains/dispatch/execution-scheduler.ts +2 -0
  345. package/src/domains/dispatch/extension.ts +184 -56
  346. package/src/domains/dispatch/fleet-commit-attribution.ts +5 -0
  347. package/src/domains/dispatch/fleet-run.ts +1 -0
  348. package/src/domains/dispatch/host-verification.ts +114 -13
  349. package/src/domains/dispatch/intent.ts +28 -18
  350. package/src/domains/dispatch/orphan-recovery.ts +2 -0
  351. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  352. package/src/domains/dispatch/reservation-store.ts +5 -3
  353. package/src/domains/dispatch/state.ts +15 -2
  354. package/src/domains/dispatch/types.ts +20 -2
  355. package/src/domains/dispatch/worker-model-metadata.ts +38 -0
  356. package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
  357. package/src/domains/eval/metrics/token-stream.ts +201 -31
  358. package/src/domains/eval/metrics/tracked.ts +40 -4
  359. package/src/domains/eval/runners/clio-run.ts +17 -11
  360. package/src/domains/eval/runners/context-index.ts +2 -7
  361. package/src/domains/eval/runners/context-init.ts +3 -6
  362. package/src/domains/eval/runners/external-command.ts +29 -11
  363. package/src/domains/eval/schema/suite.ts +28 -0
  364. package/src/domains/eval/schema/verdict.ts +2 -2
  365. package/src/domains/eval/suites/resolve.ts +13 -1
  366. package/src/domains/eval/suites/run.ts +24 -3
  367. package/src/domains/evidence/build.ts +102 -15
  368. package/src/domains/evidence/detail.ts +69 -0
  369. package/src/domains/evidence/eval.ts +13 -1
  370. package/src/domains/evidence/finish-contract-map.ts +5 -1
  371. package/src/domains/evidence/inventory.ts +167 -0
  372. package/src/domains/evidence/store.ts +16 -0
  373. package/src/domains/evidence/types.ts +12 -0
  374. package/src/domains/extensions/resources.ts +7 -0
  375. package/src/domains/interop/registry.ts +6 -2
  376. package/src/domains/interop/types.ts +4 -0
  377. package/src/domains/lifecycle/migrations/index.ts +4 -0
  378. package/src/domains/memory/task-memory-policy.ts +70 -26
  379. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  380. package/src/domains/middleware/index.ts +0 -1
  381. package/src/domains/middleware/marketplace-offer.ts +22 -35
  382. package/src/domains/middleware/memory-intervention.ts +127 -32
  383. package/src/domains/middleware/memory-step-endpoint.ts +3 -2
  384. package/src/domains/middleware/runtime.ts +7 -3
  385. package/src/domains/middleware/skills-reminder.ts +31 -2
  386. package/src/domains/mux/detect.ts +3 -6
  387. package/src/domains/observability/accountability.ts +15 -1
  388. package/src/domains/observability/compaction-usage.ts +118 -0
  389. package/src/domains/observability/contract.ts +52 -7
  390. package/src/domains/observability/cost.ts +1 -1
  391. package/src/domains/observability/evidence-index.ts +10 -0
  392. package/src/domains/observability/extension.ts +15 -6
  393. package/src/domains/observability/out-of-turn-usage.ts +52 -21
  394. package/src/domains/observability/projection.ts +394 -45
  395. package/src/{interactive → domains/observability}/worker-progress.ts +3 -3
  396. package/src/domains/prompts/fragments/operating/contract.md +2 -0
  397. package/src/domains/prompts/fragments/wiki/page.md +8 -0
  398. package/src/domains/providers/contract.ts +4 -1
  399. package/src/domains/providers/extension.ts +40 -9
  400. package/src/domains/providers/model-capabilities.ts +9 -0
  401. package/src/domains/providers/model-discovery.ts +3 -4
  402. package/src/domains/providers/model-runtime-capabilities.ts +15 -5
  403. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +48 -26
  404. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
  405. package/src/domains/providers/runtimes/claude/claude-code.ts +9 -0
  406. package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
  407. package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
  408. package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
  409. package/src/domains/providers/support.ts +11 -5
  410. package/src/domains/providers/target-model-cache.ts +25 -2
  411. package/src/domains/providers/types/capability-flags.ts +2 -0
  412. package/src/domains/providers/types/runtime-descriptor.ts +20 -1
  413. package/src/domains/providers/types/target-descriptor.ts +19 -0
  414. package/src/domains/resources/index.ts +3 -0
  415. package/src/domains/resources/skills/install.ts +72 -7
  416. package/src/domains/resources/skills/loader.ts +7 -0
  417. package/src/domains/resources/skills/marketplace.ts +63 -11
  418. package/src/domains/safety/action-classifier.ts +7 -0
  419. package/src/domains/safety/autonomy.ts +15 -0
  420. package/src/domains/safety/default-path-policy.ts +2 -0
  421. package/src/domains/safety/finish-contract-registration.ts +29 -14
  422. package/src/domains/safety/finish-contract.ts +252 -40
  423. package/src/domains/safety/index.ts +21 -1
  424. package/src/domains/safety/path-policy.ts +1 -1
  425. package/src/domains/safety/policy-engine.ts +60 -17
  426. package/src/domains/safety/protected-artifacts.ts +191 -88
  427. package/src/domains/safety/rigor.ts +53 -39
  428. package/src/domains/safety/run-effects.ts +2 -22
  429. package/src/domains/safety/skill-authority.ts +55 -0
  430. package/src/domains/safety/validation-contract.ts +388 -0
  431. package/src/domains/session/archive-readers.ts +10 -1
  432. package/src/domains/session/compaction/compact.ts +72 -22
  433. package/src/domains/session/decision-board.ts +101 -2
  434. package/src/domains/session/entries.ts +50 -7
  435. package/src/domains/session/extension.ts +4 -4
  436. package/src/domains/session/handoff.ts +2 -1
  437. package/src/domains/session/manager.ts +2 -3
  438. package/src/domains/session/task-board.ts +14 -1
  439. package/src/domains/session/tree/fork.ts +1 -2
  440. package/src/domains/session/tree/navigator.ts +1 -1
  441. package/src/domains/session/usage.ts +3 -3
  442. package/src/domains/user-tasks/acceptance.ts +56 -0
  443. package/src/domains/user-tasks/active-acceptance.ts +40 -0
  444. package/src/domains/user-tasks/store.ts +34 -3
  445. package/src/engine/acp/adapter.ts +24 -6
  446. package/src/engine/acp/server.ts +21 -4
  447. package/src/engine/acp/transport.ts +53 -8
  448. package/src/engine/acp/types.ts +4 -0
  449. package/src/engine/agent.ts +13 -3
  450. package/src/engine/ai.ts +26 -8
  451. package/src/engine/antigravity/subprocess-runtime.ts +386 -120
  452. package/src/engine/api-registry.ts +3 -0
  453. package/src/engine/apis/ollama-native.ts +15 -0
  454. package/src/engine/apis/openai-completions.ts +117 -14
  455. package/src/engine/claude/subprocess-runtime.ts +107 -60
  456. package/src/engine/external-subprocess.ts +122 -6
  457. package/src/entry/background-model-metadata.ts +18 -0
  458. package/src/entry/compaction-prompt.ts +57 -0
  459. package/src/entry/orchestrator.ts +416 -218
  460. package/src/entry/task-memory-lifecycle.ts +35 -0
  461. package/src/interactive/chat-loop-messages.ts +13 -4
  462. package/src/interactive/chat-loop.ts +65 -2
  463. package/src/interactive/chat-renderer.ts +1 -0
  464. package/src/interactive/cost-overlay.ts +26 -2
  465. package/src/interactive/dispatch-board.ts +46 -717
  466. package/src/interactive/fleet-run-preview.ts +2 -1
  467. package/src/interactive/interactive-application.ts +3 -2
  468. package/src/interactive/interactive-presentation.ts +55 -12
  469. package/src/interactive/interactive-slash-runtime.ts +4 -2
  470. package/src/interactive/oracle.ts +5 -2
  471. package/src/interactive/overlays/fleet-run-approval.ts +3 -2
  472. package/src/interactive/overlays/message-picker.ts +2 -2
  473. package/src/interactive/overlays/settings.ts +2 -2
  474. package/src/interactive/overlays/tree-selector.ts +2 -2
  475. package/src/interactive/renderers/branch-summary.ts +1 -1
  476. package/src/interactive/renderers/worker-entry.ts +32 -0
  477. package/src/interactive/slash-autocomplete.ts +4 -6
  478. package/src/interactive/slash-commands.ts +49 -45
  479. package/src/interactive/slash-spec.ts +28 -0
  480. package/src/interactive/theme/labels.ts +19 -13
  481. package/src/interactive/turn-context.ts +9 -5
  482. package/src/interactive/turn-recovery.ts +8 -0
  483. package/src/interactive/turn-runtime.ts +27 -11
  484. package/src/interactive/turn-state.ts +7 -0
  485. package/src/interactive/view/artifacts.ts +2 -0
  486. package/src/interactive/worker-receipts.ts +1 -0
  487. package/src/interactive/worker-stream.ts +13 -4
  488. package/src/tools/bootstrap.ts +4 -0
  489. package/src/tools/builtin-tool-catalog.ts +31 -0
  490. package/src/tools/compete-worktrees.ts +7 -1
  491. package/src/tools/context/index.ts +30 -9
  492. package/src/tools/core-bootstrap.ts +16 -0
  493. package/src/tools/decide.ts +136 -0
  494. package/src/tools/dispatch-admission.ts +21 -0
  495. package/src/tools/dispatch-arguments.ts +1 -0
  496. package/src/tools/dispatch-event-text.ts +10 -0
  497. package/src/tools/dispatch-plan.ts +6 -2
  498. package/src/tools/dispatch-runner.ts +27 -1
  499. package/src/tools/dispatch-types.ts +6 -0
  500. package/src/tools/evidence.ts +96 -0
  501. package/src/tools/limitation.ts +76 -0
  502. package/src/tools/policy.ts +9 -0
  503. package/src/tools/presentation.ts +3 -0
  504. package/src/tools/registry.ts +11 -5
  505. package/src/tools/result-shaping.ts +17 -5
  506. package/src/tools/task-worktree.ts +13 -3
  507. package/src/tools/tasks.ts +10 -1
  508. package/src/tools/verify/authoring.ts +170 -83
  509. package/src/tools/verify/catalog.ts +122 -5
  510. package/src/tools/verify/index.ts +2 -1
  511. package/src/tools/verify/numeric.ts +298 -0
  512. package/src/tools/verify/perf.ts +143 -0
  513. package/src/tools/verify/scripts.ts +229 -2
  514. package/src/tools/worker-evidence.ts +3 -1
  515. package/src/worker/spec-contract.ts +4 -0
  516. package/dist/chunk-2Z2IKEXI.js +0 -1554
  517. package/dist/chunk-RVG5JXAL.js +0 -41
  518. package/dist/chunk-T56WDKA5.js +0 -183
  519. package/dist/chunk-VN3SHNBN.js +0 -313
  520. package/dist/chunk-VPKWYKEY.js +0 -169
  521. package/dist/reset-OAQP3W4O.js +0 -230
  522. package/dist/uninstall-N34PCTGJ.js +0 -331
  523. package/dist/upgrade-PXK3S2YM.js +0 -325
@@ -641,8 +641,8 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
641
641
  if (!usage || !deps.observability) return;
642
642
  if (usage.totalTokens <= 0 && usage.cost.total <= 0) return;
643
643
  deps.observability.recordTokens(
644
- agentRuntime.targetId,
645
- agentRuntime.wireModelId,
644
+ usage.targetId ?? agentRuntime.targetId,
645
+ usage.modelId ?? agentRuntime.wireModelId,
646
646
  usage.totalTokens,
647
647
  usage.cost.total,
648
648
  {
@@ -654,7 +654,11 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
654
654
  totalTokens: usage.totalTokens,
655
655
  apiCalls: Math.max(1, Math.round(usage.apiCalls)),
656
656
  },
657
- agentRuntime.runtimeResolution.costProvenance,
657
+ usage.targetId === undefined && usage.modelId === undefined
658
+ ? agentRuntime.runtimeResolution.costProvenance
659
+ : usage.cost.total > 0
660
+ ? "estimated"
661
+ : "unknown",
658
662
  );
659
663
  };
660
664
 
@@ -915,8 +919,8 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
915
919
  if (!summaryLifecycleStarted) startSummaryLifecycle();
916
920
  deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
917
921
 
918
- // The summarization call spends tokens on the same target the turn would
919
- // have. The ledger entry carries its usage for a later reseed; this is the
922
+ // The checkpoint identifies the selected summary route; older results
923
+ // fall back to the active chat route. The ledger carries usage for reseed; this is the
920
924
  // live sink, so `/cost` and the footer move the moment /context compact
921
925
  // returns instead of staying byte-identical to before it ran.
922
926
  recordCompactionUsage(agentRuntime, result);
@@ -217,6 +217,14 @@ export function createTurnRecovery(deps: TurnRecoveryDeps): TurnRecovery {
217
217
  text: string,
218
218
  initialFailure: TerminalAssistantFailure,
219
219
  ): Promise<boolean> => {
220
+ // A LiteLLM model id can be a deliberate physical route. Retrying it in
221
+ // Clio obscures the failure, delays operator recovery, and can multiply
222
+ // attempts beneath a gateway. Preserve and emit the one terminal failure;
223
+ // the operator can choose another advertised route with /model.
224
+ if (agentRuntime.runtimeId === "litellm") {
225
+ ensureFailureVisibleAndPersisted(initialFailure);
226
+ return true;
227
+ }
220
228
  const settings = deps.retrySettings();
221
229
  if (!settings.enabled || settings.maxRetries <= 0) return false;
222
230
  if (initialFailure.stopReason === "aborted" || !isRetryableErrorMessage(initialFailure.errorMessage)) return false;
@@ -8,6 +8,7 @@
8
8
  import { performance } from "node:perf_hooks";
9
9
  import type { BackendCompletionTimings } from "../core/cache-telemetry.js";
10
10
  import type { ClioSettings } from "../core/config.js";
11
+ import { gatewayRoutingObservationFromRecord, gatewayRoutingObservationLabel } from "../core/gateway-routing.js";
11
12
  import { attributedModelId } from "../core/response-model-id.js";
12
13
  import type { MiddlewareToolChoiceControl } from "../domains/middleware/index.js";
13
14
  import type { ObservabilityContract } from "../domains/observability/contract.js";
@@ -130,6 +131,8 @@ export interface TurnRuntimeDeps {
130
131
  context: TurnContext;
131
132
  middleware: TurnMiddleware;
132
133
  retrySettings: () => RetrySettings;
134
+ /** Stable Clio session id forwarded only to gateway runtimes that understand it. */
135
+ sessionId?: () => string | undefined;
133
136
  emit: (event: AgentEvent | AssistantDeltaEvent) => void;
134
137
  emitNotice: (text: string) => void;
135
138
  /** Tool-call id to its `performance.now()` start mark; spans only, never an instant. */
@@ -447,6 +450,11 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
447
450
  cleanupSessionResources(state.runtime.agent.sessionId);
448
451
  }
449
452
  let getCurrentAgentSignal: () => AbortSignal | undefined = () => undefined;
453
+ const gatewaySessionId = target.runtime.id === "litellm" ? deps.sessionId?.() : undefined;
454
+ // message_start can follow response headers. Keep each invocation's
455
+ // monotonic anchor before that wait, including custom stream delegates.
456
+ let apiCallStartedAt: number | null = null;
457
+ let apiCallFirstDeltaAt: number | null = null;
450
458
  const handle = deps.createAgent({
451
459
  initialState: {
452
460
  systemPrompt: fallbackIdentityPrompt(),
@@ -456,6 +464,11 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
456
464
  messages: priorMessages,
457
465
  },
458
466
  maxRetryDelayMs: deps.retrySettings().maxDelayMs,
467
+ ...(gatewaySessionId ? { sessionId: gatewaySessionId } : {}),
468
+ onStreamInvocation: () => {
469
+ apiCallStartedAt = performance.now();
470
+ apiCallFirstDeltaAt = null;
471
+ },
459
472
  onPayload: async (payload, currentModel) => {
460
473
  const thinkingPatched = patchProviderThinkingPayload(payload, currentModel, state.currentThinkingLevel);
461
474
  const basePayload = thinkingPatched ?? payload;
@@ -575,10 +588,6 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
575
588
 
576
589
  let streamStartedAt: number | null = null;
577
590
  let firstAssistantDeltaAt: number | null = null;
578
- // Per-API-call timing (T3.2): one assistant message per provider call,
579
- // bounded by message_start/message_end; the first delta marks TTFT.
580
- let apiCallStartedAt: number | null = null;
581
- let apiCallFirstDeltaAt: number | null = null;
582
591
  // First call of the run is the one whose verdict says whether the
583
592
  // backend reused the session prefix; later calls in a tool loop are
584
593
  // trivially warm.
@@ -669,6 +678,15 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
669
678
  }
670
679
  let publicEvent = enrichedEvent;
671
680
  if (enrichedEvent.type === "message_end" && enrichedEvent.message?.role === "assistant") {
681
+ const gatewayRouting = gatewayRoutingObservationFromRecord(
682
+ enrichedEvent.message as unknown as Record<string, unknown>,
683
+ );
684
+ if (
685
+ gatewayRouting !== null &&
686
+ ((gatewayRouting.attemptedFallbacks ?? 0) > 0 || (gatewayRouting.attemptedRetries ?? 0) > 0)
687
+ ) {
688
+ deps.emitNotice(`[Clio Coder] ${gatewayRoutingObservationLabel(gatewayRouting)}`);
689
+ }
672
690
  const interruptedUsage = estimatedUsageForInterruptedTurn(enrichedEvent.message, context.promptSideTokens());
673
691
  if (interruptedUsage !== null) {
674
692
  // Persistence records the same estimate, but it does so after the
@@ -718,17 +736,15 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
718
736
  // mediator, a dropped frame) therefore stops suspending the watchdog
719
737
  // at the turn that issued it instead of for the rest of the run.
720
738
  if (publicEvent?.type === "turn_end") toolsInFlight = 0;
721
- if (publicEvent?.type === "message_start" && publicEvent.message?.role === "assistant") {
722
- apiCallStartedAt = eventClock;
723
- apiCallFirstDeltaAt = null;
724
- }
725
739
  if (publicEvent?.type === "message_update") {
726
740
  const assistantEvent = publicEvent.assistantMessageEvent as { type?: string; delta?: unknown };
727
741
  const hasDelta =
728
- assistantEvent.type === "text_delta" ||
729
- assistantEvent.type === "thinking_delta" ||
730
742
  assistantEvent.type === "toolcall_start" ||
731
- assistantEvent.type === "toolcall_delta";
743
+ ((assistantEvent.type === "text_delta" ||
744
+ assistantEvent.type === "thinking_delta" ||
745
+ assistantEvent.type === "toolcall_delta") &&
746
+ typeof assistantEvent.delta === "string" &&
747
+ assistantEvent.delta.length > 0);
732
748
  if (hasDelta && firstAssistantDeltaAt === null) firstAssistantDeltaAt = eventClock;
733
749
  if (hasDelta && apiCallFirstDeltaAt === null) apiCallFirstDeltaAt = eventClock;
734
750
  }
@@ -127,6 +127,12 @@ export interface ChatTurnState {
127
127
  /** A middleware request_continuation is waiting to resubmit after settle. */
128
128
  pendingRequestContinuation: boolean;
129
129
  currentPendingSkillPolicy: PendingSkillToolPolicy | undefined;
130
+ /**
131
+ * Tool surface an activated skill narrowed, held across the operator's
132
+ * later turns. Replaced when the operator activates a different skill,
133
+ * cleared by `/skill off`, gone with the session.
134
+ */
135
+ activeSkillSurface: PendingSkillToolPolicy | undefined;
130
136
  currentAskUserPolicy: AskUserToolPolicy | undefined;
131
137
  lastRunSnapshot: ChatLoopRunSnapshot | null;
132
138
  }
@@ -153,6 +159,7 @@ export function createTurnState(initialThinkingLevel: ThinkingLevel): ChatTurnSt
153
159
  stalledTurnNudgeSpent: false,
154
160
  pendingRequestContinuation: false,
155
161
  currentPendingSkillPolicy: undefined,
162
+ activeSkillSurface: undefined,
156
163
  currentAskUserPolicy: undefined,
157
164
  lastRunSnapshot: null,
158
165
  };
@@ -1382,6 +1382,8 @@ function renderAccountabilitySummary(summary: AccountabilitySummary): string[] {
1382
1382
  "# Accountability",
1383
1383
  "",
1384
1384
  `first-pass success: ${summary.firstPassRuns}/${summary.totalRuns} (${pct}%)`,
1385
+ `unverified successes: ${summary.unverifiedSuccesses}`,
1386
+ `ungrounded claims: ${summary.ungroundedClaims}`,
1385
1387
  "",
1386
1388
  "## Top failure causes",
1387
1389
  "",
@@ -59,6 +59,7 @@ const PRESENTED_RESULT_CONTRACTS: ReadonlyArray<WorkerPresentedResultContract> =
59
59
  "debugger-report",
60
60
  "verifier-report",
61
61
  "research-report",
62
+ "world-knowledge-report",
62
63
  "scout-report",
63
64
  ];
64
65
 
@@ -9,7 +9,7 @@
9
9
  * I/O, so every sequence below is testable as a pure fold.
10
10
  *
11
11
  * What a worker is saying and doing is not decided here. That is the canonical
12
- * {@link WorkerProgressSnapshot} projection in `worker-progress.ts`, which the
12
+ * {@link WorkerProgressSnapshot} projection in `src/domains/observability/worker-progress.ts`, which the
13
13
  * Fleet Runs board reads from the same events, so the two surfaces cannot drift
14
14
  * on the answer tail, the tool names, or what a call is touching. This module
15
15
  * owns the half the board has no use for: which assignment an event belongs to,
@@ -43,14 +43,18 @@ import type {
43
43
  } from "../core/bus-events.js";
44
44
  import type { RunKind } from "../domains/dispatch/types.js";
45
45
  import type { CanonicalTrustStatus } from "../domains/evidence/trust-status.js";
46
+ import {
47
+ createWorkerProgressFold,
48
+ type WorkerProgressFold,
49
+ type WorkerProgressSnapshot,
50
+ } from "../domains/observability/worker-progress.js";
46
51
  import type { WorkerRunOrigin, WorkerRunRuntime, WorkerRunRuntimeKind } from "../domains/session/index.js";
47
- import { createWorkerProgressFold, type WorkerProgressFold, type WorkerProgressSnapshot } from "./worker-progress.js";
48
52
 
49
53
  export {
50
54
  boundSettledText,
51
55
  WORKER_LIVE_TAIL_LINES,
52
56
  WORKER_TOOL_NAME_LIMIT,
53
- } from "./worker-progress.js";
57
+ } from "../domains/observability/worker-progress.js";
54
58
  export type { WorkerProgressSnapshot };
55
59
 
56
60
  export interface WorkerAttempt {
@@ -62,7 +66,12 @@ export interface WorkerAttempt {
62
66
  export type WorkerResultContract = "pass" | "fail" | "not-reached" | "unmeasured";
63
67
 
64
68
  /** Result kinds whose parsed envelopes have a dedicated transcript presentation. */
65
- export type WorkerPresentedResultContract = "debugger-report" | "verifier-report" | "research-report" | "scout-report";
69
+ export type WorkerPresentedResultContract =
70
+ | "debugger-report"
71
+ | "verifier-report"
72
+ | "research-report"
73
+ | "world-knowledge-report"
74
+ | "scout-report";
66
75
 
67
76
  /**
68
77
  * Terminal facts a worker block reports. Sealed by the receipt when it can be
@@ -5,6 +5,7 @@ import type { DispatchContract } from "../domains/dispatch/contract.js";
5
5
  import type { AgentRoleFactsResolver } from "../domains/dispatch/execution-role.js";
6
6
  import type { PanesOperations } from "../domains/mux/operations.js";
7
7
  import type { AutonomyLevel } from "../domains/safety/autonomy.js";
8
+ import type { DecisionLedgerEntry } from "../domains/session/entries.js";
8
9
  import { builtin, toolPromptHintsForNames } from "./builtin-tool-catalog.js";
9
10
  import type { CompeteMuxWorktrees } from "./compete-worktrees.js";
10
11
  import { assertRegisteredBuiltinTools, type CoreToolBootstrapDeps, registerCoreTools } from "./core-bootstrap.js";
@@ -31,6 +32,8 @@ export interface ToolBootstrapDeps extends CoreToolBootstrapDeps {
31
32
  /** Which optional `dispatch` schema blocks this session advertises; absent means every block. */
32
33
  getDispatchSchemaComposition?: () => DispatchSchemaComposition;
33
34
  dispatchBackground?: DispatchBackgroundRegistry;
35
+ /** Live decision board snapshot; dispatch seals its active refs onto every request. */
36
+ getDecisionBoard?: () => ReadonlyArray<DecisionLedgerEntry>;
34
37
  /** Optional herdr worktree lifecycle for compete candidates. */
35
38
  competeMuxWorktrees?: CompeteMuxWorktrees;
36
39
  /**
@@ -66,6 +69,7 @@ export function registerAllTools(registry: ToolRegistry, deps: ToolBootstrapDeps
66
69
  ...(deps.getWorkerRosters ? { getWorkerRosters: deps.getWorkerRosters } : {}),
67
70
  ...(deps.getDispatchSchemaComposition ? { getSchemaComposition: deps.getDispatchSchemaComposition } : {}),
68
71
  ...(deps.dispatchBackground ? { background: deps.dispatchBackground } : {}),
72
+ ...(deps.getDecisionBoard ? { getDecisionBoard: deps.getDecisionBoard } : {}),
69
73
  ...(deps.competeMuxWorktrees ? { competeWorktrees: { mux: deps.competeMuxWorktrees } } : {}),
70
74
  };
71
75
  registry.register({
@@ -45,6 +45,13 @@ const exactMutationPolicy = {
45
45
  // declares its posture explicitly.
46
46
  const TOOL_METADATA: Readonly<Record<string, ToolMetadata>> = {
47
47
  // OBSERVE: read-class, parallel, envelope + shared turn budget.
48
+ [ToolNames.Evidence]: {
49
+ objective: "Inspect canonical evidence, trust status, gate decisions, and findings.",
50
+ uiLabel: "Evidence",
51
+ retrySafety: "idempotent",
52
+ resultSizePolicy: summaryPolicy("Inspect one run with evidence(mode=run, runId=<id>) to narrow the output."),
53
+ costLatency: "local_medium",
54
+ },
48
55
  [ToolNames.Read]: {
49
56
  objective: "Read exact UTF-8 file content with line and byte bounds.",
50
57
  uiLabel: "Read",
@@ -240,6 +247,30 @@ const TOOL_METADATA: Readonly<Record<string, ToolMetadata>> = {
240
247
  promptHint:
241
248
  'When the operator asks to see a dispatched agent ("show me the tester"), call panes(action="show", target=<agent id>).',
242
249
  },
250
+ [ToolNames.Limitation]: {
251
+ objective: "Record what the turn could not verify and why as a ledger receipt.",
252
+ uiLabel: "Limitation",
253
+ retrySafety: "idempotent",
254
+ resultSizePolicy: {
255
+ kind: "exact",
256
+ maxBytes: 4_096,
257
+ followUpHint: "Call limitation again with a narrower scope if the first call was rejected.",
258
+ },
259
+ costLatency: "local_fast",
260
+ },
261
+ [ToolNames.Decide]: {
262
+ objective: "Record a design decision with its rejected alternatives and rationale on the session decision board.",
263
+ uiLabel: "Decide",
264
+ // A repeated call with the same key supersedes the earlier record, so
265
+ // the surface as a whole is not retry safe.
266
+ retrySafety: "not_retry_safe",
267
+ resultSizePolicy: {
268
+ kind: "exact",
269
+ maxBytes: 4_096,
270
+ followUpHint: "The decision ref in the result is what receipts and commits cite.",
271
+ },
272
+ costLatency: "local_fast",
273
+ },
243
274
  // RETRIEVE: network-class.
244
275
  [ToolNames.WebFetch]: {
245
276
  objective: "Fetch HTTP(S) text for explicit external research.",
@@ -616,7 +616,13 @@ export async function createCandidateWorktreeMapped(
616
616
  * builder changed nothing (an empty candidate is a legitimate ranking fact).
617
617
  */
618
618
  export function commitCandidateWork(worktree: CandidateWorktree, message: string): boolean {
619
- return commitWorktreePath(worktree.path, COMPETE_COMMIT_IDENTITY, message);
619
+ // Context reads refresh these runtime files even in a read-only worker.
620
+ // The caller's pending .gitignore update is not part of the candidate base;
621
+ // exclude the exact files, while keeping operator-owned project assets.
622
+ return commitWorktreePath(worktree.path, COMPETE_COMMIT_IDENTITY, message, [
623
+ ".clio-coder/codewiki.json",
624
+ ".clio-coder/state.json",
625
+ ]);
620
626
  }
621
627
 
622
628
  /** One-line stat summary of what a candidate branch changed relative to HEAD. */
@@ -181,20 +181,33 @@ function pendingSkillPolicyError(name: string, options: ToolInvokeOptions | unde
181
181
  if (!policy) {
182
182
  return NO_PENDING_SKILL_DENIAL;
183
183
  }
184
+ const recipeBound = policyIsRecipeBound(policy);
185
+ // auto-edit / full-auto: the operator already chose to let the model act
186
+ // without being asked, and a skill only ever narrows the tool surface, so
187
+ // the model activates an installed skill itself under the same per-run
188
+ // policy `/skill` produces. A skill that is not installed still fails the
189
+ // lookup below with the operator-gated marketplace message.
190
+ if (policy.modelActivation === true && !recipeBound) {
191
+ if (!policy.loadedSkillNames.has(name)) return null;
192
+ const window = policy.carriedSurface === true ? "in this session" : "this turn";
193
+ return `context: skill ${name} already loaded ${window}; continue with the loaded workflow and call ask_user if an interview/choice is needed.`;
194
+ }
184
195
  const allowed = [...new Set(policy.allowedSkillNames.map((entry) => entry.trim()).filter(Boolean))];
185
196
  if (allowed.length === 0) {
186
197
  return NO_PENDING_SKILL_DENIAL;
187
198
  }
188
- const recipeBound = policyIsRecipeBound(policy);
189
199
  if (!allowed.includes(name)) {
190
- return recipeBound
191
- ? `context: this agent run may load only its declared skill(s): ${allowed.join(", ")}.`
192
- : `context: this turn has pending skill request(s): ${allowed.join(", ")}. Load only those before doing anything else.`;
200
+ if (recipeBound) return `context: this agent run may load only its declared skill(s): ${allowed.join(", ")}.`;
201
+ // A carried surface is a skill the operator activated on an earlier
202
+ // turn, not a request waiting to be loaded now. Claiming a pending
203
+ // request here would invite a retry of a load nothing asked for.
204
+ if (policy.carriedSurface === true) return NO_PENDING_SKILL_DENIAL;
205
+ return `context: this turn has pending skill request(s): ${allowed.join(", ")}. Load only those before doing anything else.`;
193
206
  }
194
207
  if (policy.loadedSkillNames.has(name)) {
195
- return recipeBound
196
- ? `context: skill ${name} is already loaded in this run; continue with its workflow.`
197
- : `context: pending skill ${name} already loaded this turn; continue with the loaded workflow and call ask_user if an interview/choice is needed.`;
208
+ if (recipeBound) return `context: skill ${name} is already loaded in this run; continue with its workflow.`;
209
+ const window = policy.carriedSurface === true ? "in this session" : "this turn";
210
+ return `context: pending skill ${name} already loaded ${window}; continue with the loaded workflow and call ask_user if an interview/choice is needed.`;
198
211
  }
199
212
  return null;
200
213
  }
@@ -274,6 +287,7 @@ function renderSkillsList(
274
287
  skills: ReadonlyArray<Skill>,
275
288
  marketplace: ReadonlyArray<MarketplaceSkill>,
276
289
  marketplaceOffered: boolean,
290
+ modelActivation: boolean,
277
291
  ): string {
278
292
  if (skills.length === 0 && marketplace.length === 0) {
279
293
  // A registry that never offers the marketplace (a worker) must not
@@ -308,7 +322,9 @@ function renderSkillsList(
308
322
  // template where they skip conditional prose in the header.
309
323
  lines.push(
310
324
  "",
311
- `If one skill above matches the current task, begin your reply with the line \`${SKILL_SUGGESTION_ANCHOR}\` (a comma-separated sequence, in order, when several compose), then continue the task in the same turn without it; only the operator can run it. If none match, do not mention skills.`,
325
+ modelActivation
326
+ ? `If one skill above matches the current task, load it now with context(scope="skills", name="<name>") and continue in the same turn; at this autonomy level you activate installed skills yourself and do not wait for the operator. Marketplace rows below are not installed and still need the operator. If none match, do not mention skills.`
327
+ : `If one skill above matches the current task, begin your reply with the line \`${SKILL_SUGGESTION_ANCHOR}\` (a comma-separated sequence, in order, when several compose), then continue the task in the same turn without it; only the operator can run it. If none match, do not mention skills.`,
312
328
  );
313
329
  if (marketplace.length > 0) {
314
330
  // The offer protocol mirrors the marketplace-offer middleware: fixed
@@ -423,7 +439,12 @@ function runSkillsScope(
423
439
  const list = loadSkills({ cwd: cwdFromDeps(deps), ...(deps.getSkillLoaderOptions?.() ?? {}) });
424
440
  const visible = modelVisibleSkills(list.items);
425
441
  const marketplace = marketplaceRowsFor(deps, list.items, options);
426
- const rendered = renderSkillsList(visible, marketplace, deps.skillMarketplace !== false);
442
+ const rendered = renderSkillsList(
443
+ visible,
444
+ marketplace,
445
+ deps.skillMarketplace !== false,
446
+ options?.pendingSkillPolicy?.modelActivation === true,
447
+ );
427
448
  // The catalog is bounded but not small: the whole listing must fit the
428
449
  // per-call cap like any observation, and a cut list says so instead of
429
450
  // silently dropping the marketplace tail.
@@ -1,6 +1,7 @@
1
1
  import type { ContextRecalledPayload } from "../core/bus-events.js";
2
2
  import type { LoadSkillsInput } from "../domains/resources/index.js";
3
3
  import type { SessionContract } from "../domains/session/contract.js";
4
+ import type { DecisionBoardStore } from "../domains/session/decision-board.js";
4
5
  import type { SessionEntry } from "../domains/session/entries.js";
5
6
  import { createTaskBoardStore, type TaskBoardStore } from "../domains/session/task-board.js";
6
7
  import type { UserTasksStore } from "../domains/user-tasks/store.js";
@@ -12,11 +13,14 @@ import { builtin } from "./builtin-tool-catalog.js";
12
13
  import { codeNavToolSurface } from "./codewiki/code-nav-surface.js";
13
14
  import { contextToolSurface } from "./context/surface.js";
14
15
  import { credentialPresentTool } from "./credential-present.js";
16
+ import { createDecideTool } from "./decide.js";
15
17
  import { editTool } from "./edit.js";
18
+ import { evidenceTool } from "./evidence.js";
16
19
  import { findTool } from "./find.js";
17
20
  import { grepTool } from "./grep.js";
18
21
  import { lazyTool } from "./lazy-tool.js";
19
22
  import { createLedgerTool } from "./ledger.js";
23
+ import { limitationTool } from "./limitation.js";
20
24
  import { lsTool } from "./ls.js";
21
25
  import { networkToolsDisabled } from "./network-policy.js";
22
26
  import { assertBuiltinToolPolicy } from "./policy.js";
@@ -36,6 +40,8 @@ export interface CoreToolBootstrapDeps {
36
40
  onContextRecalled?: (payload: ContextRecalledPayload) => void;
37
41
  askUser?: AskUserHandler;
38
42
  taskBoard?: TaskBoardStore;
43
+ /** The session decision board the `decide` tool appends to; absent in worker registries, where the tool refuses. */
44
+ decisionBoard?: DecisionBoardStore;
39
45
  userTasks?: UserTasksStore;
40
46
  agentLedger?: AgentLedgerPort;
41
47
  /**
@@ -65,6 +71,7 @@ export interface CoreToolRegistration {
65
71
 
66
72
  export function registerCoreTools(registry: ToolRegistry, deps: CoreToolBootstrapDeps = {}): CoreToolRegistration {
67
73
  const includeNetworkTools = !networkToolsDisabled();
74
+ registry.register(builtin(evidenceTool, { path: "src/tools/evidence.ts", scope: "core" }));
68
75
  registry.register({
69
76
  ...builtin(readTool, { path: "src/tools/read.ts", scope: "core" }),
70
77
  });
@@ -125,6 +132,15 @@ export function registerCoreTools(registry: ToolRegistry, deps: CoreToolBootstra
125
132
  registry.register({
126
133
  ...builtin(credentialPresentTool, { path: "src/tools/credential-present.ts", scope: "core" }),
127
134
  });
135
+ registry.register({
136
+ ...builtin(limitationTool, { path: "src/tools/limitation.ts", scope: "core" }),
137
+ });
138
+ registry.register({
139
+ ...builtin(createDecideTool(deps.decisionBoard ? { decisionBoard: deps.decisionBoard } : {}), {
140
+ path: "src/tools/decide.ts",
141
+ scope: "core",
142
+ }),
143
+ });
128
144
  const session = deps.session;
129
145
  const readSessionEntries = deps.readSessionEntries;
130
146
  registry.register({
@@ -0,0 +1,136 @@
1
+ import { Type } from "typebox";
2
+ import { ToolNames } from "../core/tool-names.js";
3
+ import type { DecisionBoardStore } from "../domains/session/decision-board.js";
4
+ import { decisionRef } from "../domains/session/entries.js";
5
+ import type { ToolResult, ToolSpec } from "./registry.js";
6
+ import { byteLength } from "./truncate-utf8.js";
7
+
8
+ /**
9
+ * The model's own design decisions, recorded on the session decision board
10
+ * beside the operator's `ask_user` answers. A `decide` call appends one
11
+ * `decisionLedger` entry with `origin: "agent"` and one `DecisionRecord` with
12
+ * `source: "agent"`, the alternatives the model rejected, and why. Dispatch
13
+ * seals every active decision's ref onto the run envelope and receipt, and
14
+ * the commit seams turn the same refs into `Clio-Decision:` trailers, so a
15
+ * receipt or a commit names the choices it was made under.
16
+ */
17
+
18
+ export const DECIDE_CAPS = Object.freeze({
19
+ keyBytes: 64,
20
+ valueBytes: 512,
21
+ alternatives: 6,
22
+ alternativeBytes: 256,
23
+ rationaleBytes: 1024,
24
+ labelBytes: 128,
25
+ });
26
+
27
+ const KEBAB_KEY = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
28
+
29
+ export interface DecideToolDeps {
30
+ decisionBoard?: DecisionBoardStore;
31
+ }
32
+
33
+ function boundedText(value: unknown, field: string, cap: number): string | Error {
34
+ if (typeof value !== "string") return new Error(`decide: ${field} must be a string`);
35
+ const trimmed = value.trim();
36
+ if (trimmed.length === 0) return new Error(`decide: ${field} is required`);
37
+ if (byteLength(trimmed) > cap) return new Error(`decide: ${field} exceeds the ${cap}-byte cap`);
38
+ return trimmed;
39
+ }
40
+
41
+ function boundedAlternatives(value: unknown): string[] | Error {
42
+ if (!Array.isArray(value) || value.length === 0) {
43
+ return new Error("decide: alternatives must list at least one option you rejected");
44
+ }
45
+ if (value.length > DECIDE_CAPS.alternatives) {
46
+ return new Error(`decide: alternatives exceeds the ${DECIDE_CAPS.alternatives}-entry cap`);
47
+ }
48
+ const alternatives: string[] = [];
49
+ for (const [index, entry] of value.entries()) {
50
+ const text = boundedText(entry, `alternatives[${index}]`, DECIDE_CAPS.alternativeBytes);
51
+ if (text instanceof Error) return text;
52
+ alternatives.push(text);
53
+ }
54
+ return alternatives;
55
+ }
56
+
57
+ export function createDecideTool(deps: DecideToolDeps = {}): ToolSpec {
58
+ return {
59
+ name: ToolNames.Decide,
60
+ description:
61
+ "Record a design decision you made between two or more viable options, with the alternatives you rejected and why. Call it before implementing the choice; a later call with the same key supersedes the earlier record.",
62
+ parameters: Type.Object({
63
+ key: Type.String({
64
+ description: `Stable kebab-case name for the decision, e.g. "cache-key-shape" (at most ${DECIDE_CAPS.keyBytes} bytes).`,
65
+ }),
66
+ value: Type.String({ description: `The option you chose (at most ${DECIDE_CAPS.valueBytes} bytes).` }),
67
+ alternatives: Type.Array(Type.String(), {
68
+ description: `Options you considered and rejected, 1 to ${DECIDE_CAPS.alternatives} entries.`,
69
+ }),
70
+ rationale: Type.String({
71
+ description: `Why the chosen option won over the alternatives (at most ${DECIDE_CAPS.rationaleBytes} bytes).`,
72
+ }),
73
+ label: Type.Optional(Type.String({ description: "Short human-readable title for the decision." })),
74
+ }),
75
+ // Read class on purpose: the only effect is one session-ledger append,
76
+ // so it must stay available at every autonomy level without a prompt.
77
+ baseActionClass: "read",
78
+ executionMode: "sequential",
79
+ async run(args): Promise<ToolResult> {
80
+ const key = boundedText(args.key, "key", DECIDE_CAPS.keyBytes);
81
+ if (key instanceof Error) return { kind: "error", message: key.message };
82
+ if (!KEBAB_KEY.test(key)) {
83
+ return { kind: "error", message: "decide: key must be kebab-case (lowercase letters, digits, single hyphens)" };
84
+ }
85
+ const value = boundedText(args.value, "value", DECIDE_CAPS.valueBytes);
86
+ if (value instanceof Error) return { kind: "error", message: value.message };
87
+ const alternatives = boundedAlternatives(args.alternatives);
88
+ if (alternatives instanceof Error) return { kind: "error", message: alternatives.message };
89
+ const rationale = boundedText(args.rationale, "rationale", DECIDE_CAPS.rationaleBytes);
90
+ if (rationale instanceof Error) return { kind: "error", message: rationale.message };
91
+ let label: string | undefined;
92
+ if (args.label !== undefined && args.label !== null) {
93
+ const bounded = boundedText(args.label, "label", DECIDE_CAPS.labelBytes);
94
+ if (bounded instanceof Error) return { kind: "error", message: bounded.message };
95
+ label = bounded;
96
+ }
97
+ if (deps.decisionBoard === undefined) {
98
+ return { kind: "error", message: "decide: no session decision board is available in this context" };
99
+ }
100
+ let outcome: ReturnType<DecisionBoardStore["recordAgentDecision"]>;
101
+ try {
102
+ outcome = deps.decisionBoard.recordAgentDecision({
103
+ key,
104
+ value,
105
+ alternatives,
106
+ rationale,
107
+ ...(label !== undefined ? { label } : {}),
108
+ });
109
+ } catch (error) {
110
+ return { kind: "error", message: error instanceof Error ? error.message : String(error) };
111
+ }
112
+ const ref = decisionRef(outcome.entry.interviewId, key);
113
+ const supersededNote =
114
+ outcome.superseded === null
115
+ ? ""
116
+ : ` (supersedes ${decisionRef(outcome.superseded.interviewId, outcome.superseded.key)})`;
117
+ return {
118
+ kind: "ok",
119
+ output: `decision recorded: ${key} = ${value} [${ref}]${supersededNote}\n`,
120
+ details: {
121
+ decision: {
122
+ ref,
123
+ key,
124
+ value,
125
+ alternatives,
126
+ rationale,
127
+ ...(label !== undefined ? { label } : {}),
128
+ ...(outcome.superseded !== null
129
+ ? { superseded: decisionRef(outcome.superseded.interviewId, outcome.superseded.key) }
130
+ : {}),
131
+ },
132
+ },
133
+ };
134
+ },
135
+ };
136
+ }
@@ -246,6 +246,27 @@ export function createDispatchAdmissionController(deps: DispatchToolDeps): Dispa
246
246
  argv: [...check.command],
247
247
  cwd: resolve(process.cwd(), check.cwd),
248
248
  timeoutMs: entry.timeoutMs,
249
+ // A judged check seals its kind and absolute file paths here, so
250
+ // host verification judges against what the catalog declared at
251
+ // admission rather than whatever the file says at run time.
252
+ ...(check.kind !== "command" ? { kind: check.kind } : {}),
253
+ ...(check.numeric !== undefined
254
+ ? {
255
+ numeric: {
256
+ reference: resolve(process.cwd(), check.numeric.reference),
257
+ tolerance: { ...check.numeric.tolerance },
258
+ },
259
+ }
260
+ : {}),
261
+ ...(check.perf !== undefined
262
+ ? {
263
+ perf: {
264
+ ...(check.perf.budget !== undefined ? { budget: structuredClone(check.perf.budget) } : {}),
265
+ ...(check.perf.baseline !== undefined ? { baseline: resolve(process.cwd(), check.perf.baseline) } : {}),
266
+ ...(check.perf.tolerance !== undefined ? { tolerance: { ...check.perf.tolerance } } : {}),
267
+ },
268
+ }
269
+ : {}),
249
270
  };
250
271
  }),
251
272
  };
@@ -50,6 +50,7 @@ const AUTO_BASELINE_BY_TASK_TYPE: Readonly<Record<AgentTaskType, string>> = {
50
50
  // Read-only shapes.
51
51
  code_review: "verifier",
52
52
  research: "researcher",
53
+ world_knowledge: "world-knowledge",
53
54
  code_read: "scout",
54
55
  unknown: "scout",
55
56
  };
@@ -1,3 +1,4 @@
1
+ import { gatewayRoutingObservationFromRecord, gatewayRoutingObservationLabel } from "../core/gateway-routing.js";
1
2
  import { responseModelIdObservationFromRecord } from "../core/response-model-id.js";
2
3
  import { durableAssistantTextFromEvent } from "../domains/dispatch/event-pump.js";
3
4
  import type { RunReceipt } from "../domains/dispatch/types.js";
@@ -23,3 +24,12 @@ export function receiptResponseModelIdObservationLabel(receipt: Pick<RunReceipt,
23
24
  });
24
25
  return `response_model_id_observation=${labels.join(",")}`;
25
26
  }
27
+
28
+ /** Human projection of gateway routes carried by a receipt. */
29
+ export function receiptGatewayRoutingLabel(receipt: Pick<RunReceipt, "upstreamResponses">): string | null {
30
+ const observations = (receipt.upstreamResponses ?? [])
31
+ .map((response) => gatewayRoutingObservationFromRecord(response as unknown as Record<string, unknown>))
32
+ .filter((observation) => observation !== null);
33
+ if (observations.length === 0) return null;
34
+ return observations.map(gatewayRoutingObservationLabel).join(" | ");
35
+ }