@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
@@ -487,7 +487,7 @@ function renderPlanText(
487
487
  lines.push(...renderLegacyPathScope(task, cwd));
488
488
  for (const check of task.resolvedVerification ?? []) {
489
489
  lines.push(
490
- ` verification check=${safeField(check.check)} argv=${JSON.stringify(check.argv)} cwd=${JSON.stringify(check.cwd)} timeout_ms=${check.timeoutMs}`,
490
+ ` verification check=${safeField(check.check)}${check.kind !== undefined ? ` kind=${check.kind}` : ""} argv=${JSON.stringify(check.argv)} cwd=${JSON.stringify(check.cwd)} timeout_ms=${check.timeoutMs}`,
491
491
  );
492
492
  }
493
493
  }
@@ -616,7 +616,10 @@ function isResolvedTask(value: unknown): value is ResolvedDispatchPlanArtifact["
616
616
  Array.isArray(check.argv) &&
617
617
  check.argv.every((arg) => typeof arg === "string") &&
618
618
  typeof check.cwd === "string" &&
619
- typeof check.timeoutMs === "number",
619
+ typeof check.timeoutMs === "number" &&
620
+ (check.kind === undefined || check.kind === "numeric-compare" || check.kind === "perf-budget") &&
621
+ (check.numeric === undefined || (isRecord(check.numeric) && typeof check.numeric.reference === "string")) &&
622
+ (check.perf === undefined || isRecord(check.perf)),
620
623
  ))
621
624
  )
622
625
  return false;
@@ -637,6 +640,7 @@ const RESULT_CONTRACT_KINDS = new Set<ResultContract["kind"]>([
637
640
  "council-report",
638
641
  "debugger-report",
639
642
  "research-report",
643
+ "world-knowledge-report",
640
644
  "mutation-report",
641
645
  "provenance-report",
642
646
  "oracle-report",
@@ -50,6 +50,7 @@ import { extractRunProvenance, provenanceCompactSuffix } from "../domains/eviden
50
50
  import { summarizeTrustStatus } from "../domains/evidence/trust-projection.js";
51
51
  import { adaptRunReceiptTrustStatus } from "../domains/evidence/trust-status.js";
52
52
  import type { AutonomyLevel } from "../domains/safety/autonomy.js";
53
+ import { activeDecisionRefs } from "../domains/session/decision-board.js";
53
54
  import {
54
55
  type CandidateWorktree,
55
56
  type CompeteGroupOwnership,
@@ -802,6 +803,7 @@ async function runReviewGated(
802
803
  ...(review.target !== undefined ? { target: review.target } : {}),
803
804
  ...(base.plan !== undefined ? { plan: base.plan } : {}),
804
805
  ...(base.parentToolCallId !== undefined ? { parentToolCallId: base.parentToolCallId } : {}),
806
+ ...(base.decisionRefs !== undefined ? { decisionRefs: base.decisionRefs } : {}),
805
807
  ...(base.reservation !== undefined
806
808
  ? { reservation: { ownerId: base.reservation.ownerId, memberId: base.reservation.memberId } }
807
809
  : {}),
@@ -1334,7 +1336,11 @@ async function runCompete(
1334
1336
  const receipt = candidateRuns[index]?.receipt;
1335
1337
  const failed = receipt !== undefined && isPipelineStepFailure(receipt);
1336
1338
  if (failed) return "builder failed";
1337
- commitCandidateWork(worktree, `clio-coder compete ${group} candidate ${worktree.index}`);
1339
+ // The receipt records the candidate's effective authority after recipe
1340
+ // and invocation narrowing, independently of the coordinator's autonomy.
1341
+ if (receipt?.autonomyEnforcement?.autonomy !== "read-only") {
1342
+ commitCandidateWork(worktree, `clio-coder compete ${group} candidate ${worktree.index}`);
1343
+ }
1338
1344
  return candidateDiffStat(root, worktree.branch);
1339
1345
  });
1340
1346
  if (candidateRuns.every((run) => isPipelineStepFailure(run.receipt))) {
@@ -1367,6 +1373,7 @@ async function runCompete(
1367
1373
  ...(compete.judge?.node !== undefined ? { node: compete.judge.node } : {}),
1368
1374
  ...(base.plan !== undefined ? { plan: base.plan } : {}),
1369
1375
  ...(base.parentToolCallId !== undefined ? { parentToolCallId: base.parentToolCallId } : {}),
1376
+ ...(base.decisionRefs !== undefined ? { decisionRefs: base.decisionRefs } : {}),
1370
1377
  ...(base.reservation !== undefined
1371
1378
  ? { reservation: { ownerId: base.reservation.ownerId, memberId: base.reservation.memberId } }
1372
1379
  : {}),
@@ -2010,6 +2017,7 @@ async function runCouncil(
2010
2017
  ...(council.judge?.node ? { node: council.judge.node } : {}),
2011
2018
  ...(base.plan ? { plan: base.plan } : {}),
2012
2019
  ...(base.parentToolCallId ? { parentToolCallId: base.parentToolCallId } : {}),
2020
+ ...(base.decisionRefs !== undefined ? { decisionRefs: base.decisionRefs } : {}),
2013
2021
  };
2014
2022
  const pinned = council.resolvedTasks?.find((task) => task.role === "synthesis");
2015
2023
  const judgeRun = await runMember(
@@ -2153,6 +2161,18 @@ export async function runDispatchTool(
2153
2161
  if (options?.signal?.aborted) return { kind: "error", message: "dispatch: aborted" };
2154
2162
  const maxOutputBytes = snapshot.maxOutputBytes;
2155
2163
  const timeoutMs = snapshot.timeoutMs;
2164
+ // All modes, including derived Scout/review runs, share the invocation's
2165
+ // admission bounds. Keep these off the serializable approved request.
2166
+ const dispatch = deps.dispatch;
2167
+ const preparation = {
2168
+ ...(options?.signal === undefined ? {} : { signal: options.signal }),
2169
+ ...(timeoutMs === undefined ? {} : { deadlineAt: Date.now() + timeoutMs }),
2170
+ };
2171
+ deps.dispatch = {
2172
+ ...dispatch,
2173
+ dispatch: (request, observer) => dispatch.dispatch(request, observer, preparation),
2174
+ dispatchBatch: (requests) => dispatch.dispatchBatch(requests, preparation),
2175
+ };
2156
2176
  let review = snapshot.review === undefined ? undefined : structuredClone(snapshot.review);
2157
2177
  let council = snapshot.council === undefined ? undefined : structuredClone(snapshot.council);
2158
2178
 
@@ -2177,6 +2197,12 @@ export async function runDispatchTool(
2177
2197
  parentToolCallId === undefined || parentToolCallId.length === 0
2178
2198
  ? structuredClone(snapshot.requests)
2179
2199
  : snapshot.requests.map((request) => ({ ...structuredClone(request), parentToolCallId }));
2200
+ // Seal the parent board's active decisions onto every request on the same
2201
+ // terms as the parent id: from the live board here, never from model
2202
+ // arguments (the validation projection strips the field). Derived reviewer,
2203
+ // judge, and synthesis requests copy it from their base explicitly.
2204
+ const decisionRefs = activeDecisionRefs(deps.getDecisionBoard?.() ?? []);
2205
+ if (decisionRefs.length > 0) requests = requests.map((request) => ({ ...request, decisionRefs }));
2180
2206
  if (planView.planScale && deps.dispatch.preview !== undefined && resolvedPlan === null) {
2181
2207
  return { kind: "error", message: "dispatch: resolved plan is missing after admission" };
2182
2208
  }
@@ -3,6 +3,7 @@ import type { AgentSpec } from "../domains/agents/spec.js";
3
3
  import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
4
4
  import type { AgentRoleFactsResolver } from "../domains/dispatch/execution-role.js";
5
5
  import type { AutonomyLevel } from "../domains/safety/autonomy.js";
6
+ import type { DecisionLedgerEntry } from "../domains/session/entries.js";
6
7
  import type {
7
8
  CandidateWorktree,
8
9
  CompeteGroupOwnership,
@@ -108,4 +109,9 @@ export interface DispatchToolDeps {
108
109
  getWorkerRosters?: () => Readonly<Record<string, { members: ReadonlyArray<DispatchCouncilMember> }>>;
109
110
  /** Which optional schema blocks this session advertises; absent means every block. */
110
111
  getSchemaComposition?: () => DispatchSchemaComposition;
112
+ /**
113
+ * Live decision board snapshot. Every request the tool builds carries the
114
+ * active decisions' refs, sealed here and never from model arguments.
115
+ */
116
+ getDecisionBoard?: () => ReadonlyArray<DecisionLedgerEntry>;
111
117
  }
@@ -0,0 +1,96 @@
1
+ import { Type } from "typebox";
2
+ import { assertSafeId } from "../core/safe-id.js";
3
+ import { ToolNames } from "../core/tool-names.js";
4
+ import { clioDataDir, clioStateDir } from "../core/xdg.js";
5
+ import { StringEnum } from "../engine/ai.js";
6
+ import type { ToolResult, ToolSpec } from "./registry.js";
7
+ import { truncateUtf8 } from "./truncate-utf8.js";
8
+
9
+ export const EVIDENCE_TOOL_MAX_BYTES = 16_384;
10
+
11
+ /** Keep truncated results valid JSON and never hide an unbounded copy in details. */
12
+ function boundedResult(value: unknown): ToolResult {
13
+ const serialized = JSON.stringify(value, null, 2);
14
+ if (Buffer.byteLength(serialized, "utf8") <= EVIDENCE_TOOL_MAX_BYTES) {
15
+ return { kind: "ok", output: serialized, details: { truncated: false } };
16
+ }
17
+ const hint = "Inspect one run to narrow the output; this preview is incomplete JSON text.";
18
+ let preview = truncateUtf8(serialized, EVIDENCE_TOOL_MAX_BYTES, "");
19
+ let output = JSON.stringify({ truncated: true, hint, preview });
20
+ while (Buffer.byteLength(output, "utf8") > EVIDENCE_TOOL_MAX_BYTES) {
21
+ const excess = Buffer.byteLength(output, "utf8") - EVIDENCE_TOOL_MAX_BYTES;
22
+ preview = truncateUtf8(preview, Math.max(0, Buffer.byteLength(preview, "utf8") - excess), "");
23
+ output = JSON.stringify({ truncated: true, hint, preview });
24
+ }
25
+ return { kind: "ok", output, details: { truncated: true } };
26
+ }
27
+
28
+ export const evidenceTool: ToolSpec = {
29
+ name: ToolNames.Evidence,
30
+ description:
31
+ "Read canonical evidence as JSON. List recent bundles, inspect a bundle's overview, trust axes and tier, gate decisions, and findings, or build/read evidence for a run.",
32
+ parameters: Type.Object({
33
+ mode: StringEnum(["list", "inspect", "run"]),
34
+ id: Type.Optional(Type.String({ description: "Evidence bundle id for inspect." })),
35
+ runId: Type.Optional(Type.String({ description: "Run id for run." })),
36
+ }),
37
+ baseActionClass: "read",
38
+ // Run mode may materialize a derived bundle in Clio's data directory.
39
+ executionMode: "sequential",
40
+ async run(args): Promise<ToolResult> {
41
+ const mode = args.mode;
42
+ if (mode !== "list" && mode !== "inspect" && mode !== "run") {
43
+ return { kind: "error", message: "evidence: mode must be list, inspect, or run" };
44
+ }
45
+ try {
46
+ const dataDir = clioDataDir();
47
+ if (mode === "list") {
48
+ const { evidenceInventorySnapshot } = await import("../domains/evidence/inventory.js");
49
+ return boundedResult(await evidenceInventorySnapshot(Date.now, dataDir));
50
+ }
51
+ const id = mode === "inspect" ? args.id : args.runId;
52
+ if (typeof id !== "string" || id.length === 0) {
53
+ return { kind: "error", message: `evidence: ${mode} requires ${mode === "inspect" ? "id" : "runId"}` };
54
+ }
55
+ assertSafeId(id, mode === "inspect" ? "evidence" : "run");
56
+ const { buildEvidence, EvidenceNotFoundError, inspectEvidence, loadEvidenceGateDecisions } = await import(
57
+ "../domains/evidence/index.js"
58
+ );
59
+ const { evidenceDetailSnapshot } = await import("../domains/evidence/detail.js");
60
+ let evidenceId = mode === "run" ? `run-${id}` : id;
61
+ let inspected: Awaited<ReturnType<typeof inspectEvidence>>;
62
+ try {
63
+ inspected = await inspectEvidence(dataDir, evidenceId);
64
+ } catch (error) {
65
+ if (mode !== "run" || !(error instanceof EvidenceNotFoundError)) throw error;
66
+ try {
67
+ evidenceId = (await buildEvidence({ dataDir, stateDir: clioStateDir(), runId: id })).evidenceId;
68
+ } catch (buildError) {
69
+ if (
70
+ buildError instanceof Error &&
71
+ (buildError.message === "run ledger not found" || buildError.message === `run not found: ${id}`)
72
+ )
73
+ throw new EvidenceNotFoundError(evidenceId);
74
+ throw buildError;
75
+ }
76
+ inspected = await inspectEvidence(dataDir, evidenceId);
77
+ }
78
+ return boundedResult({
79
+ ...inspected,
80
+ ...(await evidenceDetailSnapshot(evidenceId, Date.now, dataDir)),
81
+ gateDecisions: await loadEvidenceGateDecisions(dataDir, evidenceId),
82
+ });
83
+ } catch (error) {
84
+ const absent = error instanceof Error && error.name === "EvidenceNotFoundError";
85
+ return {
86
+ kind: "error",
87
+ message: truncateUtf8(
88
+ `evidence: ${error instanceof Error ? error.message : String(error)}`,
89
+ EVIDENCE_TOOL_MAX_BYTES - 3,
90
+ "...",
91
+ ),
92
+ details: { code: absent ? "artifact_absent" : "evidence_error", artifactAbsent: absent },
93
+ };
94
+ }
95
+ },
96
+ };
@@ -0,0 +1,76 @@
1
+ import { Type } from "typebox";
2
+ import { ToolNames } from "../core/tool-names.js";
3
+ import { StringEnum } from "../engine/ai.js";
4
+ import type { ToolResult, ToolSpec } from "./registry.js";
5
+
6
+ /**
7
+ * The typed limitation signal the finish contract reads. Calling the tool
8
+ * records a `limitation` tool_call and tool_result pair in the session ledger,
9
+ * and that successful receipt is what `assessFinishContract` accepts in place
10
+ * of validation evidence. The tool is pure: it touches no filesystem and runs
11
+ * no shell, so the receipt itself is its whole effect.
12
+ */
13
+
14
+ export const LIMITATION_REASONS = ["no-runner", "blocked", "out-of-scope", "environment", "other"] as const;
15
+
16
+ export type LimitationReason = (typeof LIMITATION_REASONS)[number];
17
+
18
+ export interface LimitationRecord {
19
+ scope: string;
20
+ reason: LimitationReason;
21
+ paths: string[];
22
+ }
23
+
24
+ function isLimitationReason(value: unknown): value is LimitationReason {
25
+ return typeof value === "string" && (LIMITATION_REASONS as ReadonlyArray<string>).includes(value);
26
+ }
27
+
28
+ function trimString(value: unknown): string | null {
29
+ if (typeof value !== "string") return null;
30
+ const trimmed = value.trim();
31
+ return trimmed.length > 0 ? trimmed : null;
32
+ }
33
+
34
+ function normalizePaths(value: unknown): string[] | null {
35
+ if (value === undefined || value === null) return [];
36
+ if (!Array.isArray(value)) return null;
37
+ const paths: string[] = [];
38
+ for (const item of value) {
39
+ const path = trimString(item);
40
+ if (path === null) return null;
41
+ if (!paths.includes(path)) paths.push(path);
42
+ }
43
+ return paths;
44
+ }
45
+
46
+ export const limitationTool: ToolSpec = {
47
+ name: ToolNames.Limitation,
48
+ description:
49
+ "Record what this turn could not verify and why. Call it once, before your final reply, when you changed files but could not run validation; the receipt stands in for validation evidence at the finish gate.",
50
+ parameters: Type.Object({
51
+ scope: Type.String({ description: "What could not be verified, in one sentence." }),
52
+ reason: StringEnum(LIMITATION_REASONS, {
53
+ description:
54
+ "no-runner: no test or build runner is available; blocked: a safety gate or denial stopped the check; out-of-scope: verification was excluded by the task; environment: the environment cannot run the check; other.",
55
+ }),
56
+ paths: Type.Optional(Type.Array(Type.String(), { description: "Repository-relative paths left unverified." })),
57
+ }),
58
+ baseActionClass: "read",
59
+ executionMode: "parallel",
60
+ async run(args): Promise<ToolResult> {
61
+ const scope = trimString(args.scope);
62
+ if (scope === null) return { kind: "error", message: "limitation: scope is required" };
63
+ if (!isLimitationReason(args.reason)) {
64
+ return { kind: "error", message: `limitation: reason must be one of ${LIMITATION_REASONS.join(", ")}` };
65
+ }
66
+ const paths = normalizePaths(args.paths);
67
+ if (paths === null) return { kind: "error", message: "limitation: paths must be an array of non-empty strings" };
68
+ const limitation: LimitationRecord = { scope, reason: args.reason, paths };
69
+ const pathSuffix = paths.length > 0 ? ` paths=${paths.join(",")}` : "";
70
+ return {
71
+ kind: "ok",
72
+ output: `limitation recorded: ${scope} (reason=${limitation.reason}${pathSuffix})\n`,
73
+ details: { limitation },
74
+ };
75
+ },
76
+ };
@@ -21,6 +21,7 @@ interface PlaneExpectation {
21
21
 
22
22
  /** One row per registered tool: plane, action class, and concurrency rule. */
23
23
  export const TOOL_PLANES: Readonly<Record<BuiltinToolName, PlaneExpectation>> = {
24
+ [ToolNames.Evidence]: { plane: "observe", actionClass: "read", executionMode: "sequential" },
24
25
  [ToolNames.Read]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
25
26
  [ToolNames.Grep]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
26
27
  [ToolNames.Find]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
@@ -53,6 +54,14 @@ export const TOOL_PLANES: Readonly<Record<BuiltinToolName, PlaneExpectation>> =
53
54
  // panes. It mutates no workspace, so it stays read class; sequential because
54
55
  // two pane operations in one batch would race the same pane registry.
55
56
  [ToolNames.Panes]: { plane: "orchestrate", actionClass: "read", executionMode: "sequential" },
57
+ // limitation records a typed receipt in the session ledger and nothing
58
+ // else: no filesystem, no shell. Read class so it never trips a safety
59
+ // gate; parallel because the call is pure and idempotent.
60
+ [ToolNames.Limitation]: { plane: "orchestrate", actionClass: "read", executionMode: "parallel" },
61
+ // decide appends one decision-board entry to the session ledger and
62
+ // nothing else. Read class so it never trips a safety gate; sequential so
63
+ // two decisions in one batch never race the supersede lookup.
64
+ [ToolNames.Decide]: { plane: "orchestrate", actionClass: "read", executionMode: "sequential" },
56
65
  [ToolNames.WebFetch]: { plane: "retrieve", actionClass: "read", executionMode: "parallel" },
57
66
  [ToolNames.AskUser]: { plane: "interact", actionClass: "read", executionMode: "sequential" },
58
67
  [ToolNames.Artifact]: { plane: "artifact", actionClass: "write", executionMode: "sequential" },
@@ -50,6 +50,7 @@ const FOLDED_WITH_DIFF: ToolPresentationPolicy = {
50
50
  * tools, folds the same way.
51
51
  */
52
52
  export const TOOL_PRESENTATION: Readonly<Record<string, ToolPresentationPolicy>> = {
53
+ [ToolNames.Evidence]: FOLDED,
53
54
  [ToolNames.Read]: FOLDED,
54
55
  [ToolNames.Grep]: FOLDED,
55
56
  [ToolNames.Find]: FOLDED,
@@ -68,6 +69,8 @@ export const TOOL_PRESENTATION: Readonly<Record<string, ToolPresentationPolicy>>
68
69
  [ToolNames.Tasks]: FOLDED,
69
70
  [ToolNames.Ledger]: FOLDED,
70
71
  [ToolNames.Panes]: FOLDED,
72
+ [ToolNames.Limitation]: FOLDED,
73
+ [ToolNames.Decide]: FOLDED,
71
74
  [ToolNames.WebFetch]: FOLDED,
72
75
  [ToolNames.AskUser]: FOLDED,
73
76
  [ToolNames.Artifact]: FOLDED,
@@ -527,9 +527,12 @@ export function createRegistry(deps: RegistryDeps): ToolRegistry {
527
527
  }
528
528
  // Stage 1.5, the skill tool surface: a loaded SKILL.md that declares
529
529
  // allowed-tools or disallowed-tools narrows the surface until the
530
- // policy's lifetime ends (turn end for the main agent, run end for
531
- // workers). Narrowing only blocks; it never grants, and an out-of-
532
- // surface call blocks terminally instead of parking for confirmation.
530
+ // policy's lifetime ends. Interactively that is the session: the
531
+ // narrowing stays armed across the operator's later turns until a
532
+ // different skill replaces it, `/skill off` clears it, or the session
533
+ // ends. A worker keeps the run-scoped lifetime. Narrowing only blocks;
534
+ // it never grants, and an out-of-surface call blocks terminally
535
+ // instead of parking for confirmation.
533
536
  const surfaceViolation = evaluateSkillToolSurface(options?.pendingSkillPolicy, call.tool);
534
537
  if (surfaceViolation) {
535
538
  const verdict = skillSurfaceBlockedVerdict(decision, call.tool, surfaceViolation);
@@ -1090,10 +1093,13 @@ function skillSurfaceBlockedVerdict(
1090
1093
  tool: string,
1091
1094
  violation: SkillToolSurfaceViolation,
1092
1095
  ): Extract<RegistryVerdict, { kind: "blocked" }> {
1096
+ const lifetime = violation.carriedSurface
1097
+ ? "The narrowing stays active for the rest of the session, across the operator's later turns, until a different skill replaces it or the operator clears it with /skill off."
1098
+ : "The narrowing ends when the skill policy's turn or worker run ends.";
1093
1099
  const reason =
1094
1100
  violation.disallowedBy.length > 0
1095
- ? `${tool} is disallowed by the active skill(s) ${violation.disallowedBy.join(", ")} (disallowed-tools). The narrowing ends when the skill policy's turn or worker run ends. Work within the skill workflow; if it genuinely needs this step, use ask_user when available or state the blocker in your reply.`
1096
- : `${tool} is outside the tool surface declared by the active skill(s) ${violation.skills.join(", ")}. Tools are narrowed to: ${(violation.mergedAllowedTools ?? []).join(", ")} (plus context and ask_user). The narrowing ends when the skill policy's turn or worker run ends. Work within the skill workflow; if it genuinely needs this step, use ask_user when available or state the blocker in your reply.`;
1101
+ ? `${tool} is disallowed by the active skill(s) ${violation.disallowedBy.join(", ")} (disallowed-tools). ${lifetime} Work within the skill workflow; if it genuinely needs this step, use ask_user when available or state the blocker in your reply.`
1102
+ : `${tool} is outside the tool surface declared by the active skill(s) ${violation.skills.join(", ")}. Tools are narrowed to: ${(violation.mergedAllowedTools ?? []).join(", ")} (plus context and ask_user). The limitation receipt is also available unless explicitly disallowed. ${lifetime} Work within the skill workflow; if it genuinely needs this step, use ask_user when available or state the blocker in your reply.`;
1097
1103
  const blocked: SafetyDecision = {
1098
1104
  kind: "block",
1099
1105
  classification: decision.classification,
@@ -127,11 +127,17 @@ function offloadBody(text: string, bytes: number, maxBytes: number): string {
127
127
  return `${truncateUtf8(text, Math.max(0, prefixBudget), "")}${notice}`;
128
128
  }
129
129
 
130
+ export interface ToolOffloadSweepResult {
131
+ removed: number;
132
+ skipped: number;
133
+ }
134
+
130
135
  /** Remove regular offload files older than the boot retention cap. */
131
- export function sweepExpiredToolOffloads(now = Date.now()): number {
136
+ export function sweepExpiredToolOffloads(now = Date.now()): ToolOffloadSweepResult {
132
137
  const root = join(clioStateDir(), "scratch");
133
138
  const cutoff = now - TOOL_OFFLOAD_MAX_AGE_MS;
134
139
  let removed = 0;
140
+ let skipped = 0;
135
141
  try {
136
142
  for (const session of readdirSync(root, { withFileTypes: true })) {
137
143
  if (!session.isDirectory()) continue;
@@ -143,14 +149,20 @@ export function sweepExpiredToolOffloads(now = Date.now()): number {
143
149
  if (statSync(path).mtimeMs >= cutoff) continue;
144
150
  rmSync(path, { force: true });
145
151
  removed += 1;
146
- } catch {}
152
+ } catch (error) {
153
+ if ((error as NodeJS.ErrnoException)?.code !== "ENOENT") skipped += 1;
154
+ }
147
155
  }
148
156
  try {
149
157
  if (readdirSync(sessionDir).length === 0) rmdirSync(sessionDir);
150
- } catch {}
158
+ } catch (error) {
159
+ if ((error as NodeJS.ErrnoException)?.code !== "ENOENT") skipped += 1;
160
+ }
151
161
  }
152
- } catch {}
153
- return removed;
162
+ } catch (error) {
163
+ if ((error as NodeJS.ErrnoException)?.code !== "ENOENT") skipped += 1;
164
+ }
165
+ return { removed, skipped };
154
166
  }
155
167
 
156
168
  /**
@@ -57,9 +57,19 @@ export function isCanonicalWorktreePathInside(parent: string, candidate: string)
57
57
  return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
58
58
  }
59
59
 
60
- export function commitWorktreePath(path: string, identity: string, message: string): boolean {
61
- git(path, ["add", "-A"]);
62
- if (git(path, ["status", "--porcelain"]).length === 0) return false;
60
+ export function commitWorktreePath(
61
+ path: string,
62
+ identity: string,
63
+ message: string,
64
+ excludedPaths: ReadonlyArray<string> = [],
65
+ ): boolean {
66
+ // Runtime state can already be staged by a worker. Reset only these exact
67
+ // index entries, leaving their working files and every authored path intact.
68
+ if (excludedPaths.length > 0) {
69
+ git(path, ["reset", "-q", "HEAD", "--", ...excludedPaths.map((entry) => `:(top,literal)${entry}`)]);
70
+ }
71
+ git(path, ["add", "-A", "--", ".", ...excludedPaths.map((entry) => `:(top,exclude,literal)${entry}`)]);
72
+ if (git(path, ["diff", "--cached", "--name-only", "-z"]).length === 0) return false;
63
73
  git(path, [
64
74
  "-c",
65
75
  `user.name=${identity}`,
@@ -60,6 +60,10 @@ function renderTaskBoardText(board: TaskBoardSnapshot, userTasks: ReadonlyArray<
60
60
  if (task.status === "blocked" && task.reason) line += ` — blocked: ${task.reason}`;
61
61
  if (task.status === "cancelled" && task.reason) line += ` — dropped: ${task.reason}`;
62
62
  lines.push(line);
63
+ const outputs = userTasks.find((item) => item.id === task.userTaskId)?.acceptance?.expectedOutputs;
64
+ if (outputs?.length) lines.push(` expected outputs: ${outputs.join(", ")}`);
65
+ for (const item of task.requiredValidationEvidence ?? [])
66
+ lines.push(` acceptance: ${item.command} (${item.status}; ${item.notes})`);
63
67
  }
64
68
  if (counts.open > 0 && counts.active === 0) {
65
69
  lines.push(`next: start a task with action="start" before working it`);
@@ -210,7 +214,12 @@ export function createTasksTool(deps: TasksToolDeps): ToolSpec {
210
214
  if (userTask.status !== "open" && userTask.status !== "handed") {
211
215
  return { kind: "error", message: `tasks: operator task ${id} is ${userTask.status}; it cannot be picked` };
212
216
  }
213
- const result = deps.board.apply({ op: "pick", title: userTask.title, userTaskId: userTask.id });
217
+ const result = deps.board.apply({
218
+ op: "pick",
219
+ title: userTask.title,
220
+ userTaskId: userTask.id,
221
+ ...(userTask.acceptance ? { verification: userTask.acceptance.verification } : {}),
222
+ });
214
223
  if (!result.ok) return { kind: "error", message: `tasks: ${result.message}` };
215
224
  const picked = result.board.tasks.find((task) => task.userTaskId === userTask.id && task.status === "pending");
216
225
  if (!picked) return { kind: "error", message: `tasks: durable pickup for ${id} did not produce a board row` };