@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
@@ -0,0 +1,388 @@
1
+ import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { parseDocument } from "yaml";
4
+ import { resolveSafeCwd } from "../../core/safe-exec.js";
5
+ import { byteLength } from "../../tools/truncate-utf8.js";
6
+ import { compareCodepoints } from "../evidence/ordering.js";
7
+
8
+ /**
9
+ * The one strict loader for the version-1 scientific validation contract.
10
+ * Rigor resolution, verifier authoring, doctor, and the startup hint all read
11
+ * the contract through this module, so a file either parses under one schema
12
+ * or is diagnosed under one vocabulary. Nothing here executes anything: a
13
+ * parsed contract is a requirement statement, and its `validators` stay prose
14
+ * until the project declares matching `.clio-coder/verifiers.yaml` entries.
15
+ */
16
+
17
+ export const VALIDATION_CONTRACT_VERSION = 1;
18
+
19
+ /** YAML contract paths in resolution order; the first that exists is the contract. */
20
+ export const VALIDATION_CONTRACT_YAML_PATHS: ReadonlyArray<string> = [
21
+ ".clio-coder/validation.yaml",
22
+ ".clio-coder/validation.yml",
23
+ "validation.yaml",
24
+ "validation.yml",
25
+ ];
26
+
27
+ /** Markdown is recognized as present but never parsed and never raises rigor. */
28
+ export const VALIDATION_CONTRACT_MARKDOWN_PATH = "VALIDATION.md";
29
+
30
+ /** Public schema limits. Diagnostics cite these values instead of hiding policy. */
31
+ export const VALIDATION_CONTRACT_CAPS = Object.freeze({
32
+ fileBytes: 256 * 1024,
33
+ textBytes: 4096,
34
+ notesBytes: 16 * 1024,
35
+ artifacts: 256,
36
+ validators: 128,
37
+ modules: 64,
38
+ mapEntries: 256,
39
+ mapKeyBytes: 256,
40
+ });
41
+
42
+ export type ValidationRuntimeKind = "local" | "slurm" | "mpi" | "other";
43
+
44
+ const RUNTIME_KINDS: ReadonlyArray<ValidationRuntimeKind> = ["local", "slurm", "mpi", "other"];
45
+
46
+ export interface ValidationContractRuntime {
47
+ kind: ValidationRuntimeKind;
48
+ nodes?: number;
49
+ ranks?: number;
50
+ walltime?: string;
51
+ modules?: string[];
52
+ }
53
+
54
+ export interface ValidationNumericalTolerances {
55
+ relative?: number;
56
+ absolute?: number;
57
+ ulp?: number;
58
+ }
59
+
60
+ export interface ValidationContractArtifact {
61
+ path: string;
62
+ format?: string;
63
+ expected_dimensions?: Record<string, number>;
64
+ expected_attributes?: Record<string, string>;
65
+ numerical_tolerances?: ValidationNumericalTolerances;
66
+ preserve?: boolean;
67
+ }
68
+
69
+ export interface ValidationContract {
70
+ version: typeof VALIDATION_CONTRACT_VERSION;
71
+ task?: string;
72
+ runtime?: ValidationContractRuntime;
73
+ artifacts?: ValidationContractArtifact[];
74
+ /** Advisory command prose. Never executed from here. */
75
+ validators?: string[];
76
+ notes?: string;
77
+ }
78
+
79
+ export type ValidationContractLoadResult =
80
+ /** A YAML contract parsed under the version-1 schema. */
81
+ | { ok: true; contract: ValidationContract; path: string }
82
+ /** No contract file at the workspace root. */
83
+ | { ok: true; contract: null }
84
+ /** Only `VALIDATION.md` exists: present, unparsed, advisory. */
85
+ | { ok: true; contract: null; path: string; advisory: true }
86
+ /** A YAML contract exists but does not parse; `reason` names the fault and cites the cap it crossed. */
87
+ | { ok: false; path: string; reason: string };
88
+
89
+ const ROOT_FIELDS = new Set(["version", "task", "runtime", "artifacts", "validators", "notes"]);
90
+ const RUNTIME_FIELDS = new Set(["kind", "nodes", "ranks", "walltime", "modules"]);
91
+ const ARTIFACT_FIELDS = new Set([
92
+ "path",
93
+ "format",
94
+ "expected_dimensions",
95
+ "expected_attributes",
96
+ "numerical_tolerances",
97
+ "preserve",
98
+ ]);
99
+ const TOLERANCE_FIELDS = new Set(["relative", "absolute", "ulp"]);
100
+
101
+ function isRecord(value: unknown): value is Record<string, unknown> {
102
+ return value !== null && typeof value === "object" && !Array.isArray(value);
103
+ }
104
+
105
+ function unknownFields(record: Record<string, unknown>, allowed: ReadonlySet<string>): string[] {
106
+ return Object.keys(record)
107
+ .filter((key) => !allowed.has(key))
108
+ .sort(compareCodepoints);
109
+ }
110
+
111
+ function boundedText(value: unknown, location: string, cap: number): string | Error {
112
+ if (typeof value !== "string" || value.length === 0) return new Error(`${location} must be a non-empty string`);
113
+ if (value.includes("\0")) return new Error(`${location} must not contain a NUL byte`);
114
+ if (byteLength(value) > cap) return new Error(`${location} exceeds the ${cap}-byte cap`);
115
+ return value;
116
+ }
117
+
118
+ function positiveInteger(value: unknown, location: string): number | Error {
119
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
120
+ return new Error(`${location} must be a positive integer`);
121
+ }
122
+ return value;
123
+ }
124
+
125
+ function nonNegativeNumber(value: unknown, location: string): number | Error {
126
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
127
+ return new Error(`${location} must be a finite non-negative number`);
128
+ }
129
+ return value;
130
+ }
131
+
132
+ function boundedStringList(value: unknown, location: string, cap: number): string[] | Error {
133
+ if (!Array.isArray(value)) return new Error(`${location} must be an array of strings`);
134
+ if (value.length > cap) return new Error(`${location} exceeds the ${cap}-entry cap`);
135
+ const items: string[] = [];
136
+ for (const [index, entry] of value.entries()) {
137
+ const text = boundedText(entry, `${location}[${index}]`, VALIDATION_CONTRACT_CAPS.textBytes);
138
+ if (text instanceof Error) return text;
139
+ items.push(text);
140
+ }
141
+ return items;
142
+ }
143
+
144
+ function boundedMap<T>(
145
+ value: unknown,
146
+ location: string,
147
+ validateEntry: (entry: unknown, entryLocation: string) => T | Error,
148
+ ): Record<string, T> | Error {
149
+ if (!isRecord(value)) return new Error(`${location} must be a map`);
150
+ const keys = Object.keys(value);
151
+ if (keys.length > VALIDATION_CONTRACT_CAPS.mapEntries) {
152
+ return new Error(`${location} exceeds the ${VALIDATION_CONTRACT_CAPS.mapEntries}-entry cap`);
153
+ }
154
+ const out: Record<string, T> = {};
155
+ for (const key of keys.sort(compareCodepoints)) {
156
+ const entryLocation = `${location}.${key}`;
157
+ if (key.length === 0) return new Error(`${location} has an empty key`);
158
+ if (byteLength(key) > VALIDATION_CONTRACT_CAPS.mapKeyBytes) {
159
+ return new Error(`${entryLocation} key exceeds the ${VALIDATION_CONTRACT_CAPS.mapKeyBytes}-byte cap`);
160
+ }
161
+ const entry = validateEntry(value[key], entryLocation);
162
+ if (entry instanceof Error) return entry;
163
+ out[key] = entry;
164
+ }
165
+ return out;
166
+ }
167
+
168
+ function validateRuntime(value: unknown, location: string): ValidationContractRuntime | Error {
169
+ if (!isRecord(value)) return new Error(`${location} must be an object with a kind field`);
170
+ const unknown = unknownFields(value, RUNTIME_FIELDS);
171
+ if (unknown.length > 0) return new Error(`${location} has unknown field(s): ${unknown.join(", ")}`);
172
+ if (!Object.hasOwn(value, "kind")) return new Error(`${location}.kind is required`);
173
+ const kind = value.kind;
174
+ if (typeof kind !== "string" || !(RUNTIME_KINDS as ReadonlyArray<string>).includes(kind)) {
175
+ return new Error(`${location}.kind must be one of ${RUNTIME_KINDS.join(", ")}`);
176
+ }
177
+ const runtime: ValidationContractRuntime = { kind: kind as ValidationRuntimeKind };
178
+ if (Object.hasOwn(value, "nodes")) {
179
+ const nodes = positiveInteger(value.nodes, `${location}.nodes`);
180
+ if (nodes instanceof Error) return nodes;
181
+ runtime.nodes = nodes;
182
+ }
183
+ if (Object.hasOwn(value, "ranks")) {
184
+ const ranks = positiveInteger(value.ranks, `${location}.ranks`);
185
+ if (ranks instanceof Error) return ranks;
186
+ runtime.ranks = ranks;
187
+ }
188
+ if (Object.hasOwn(value, "walltime")) {
189
+ const walltime = boundedText(value.walltime, `${location}.walltime`, VALIDATION_CONTRACT_CAPS.textBytes);
190
+ if (walltime instanceof Error) return walltime;
191
+ runtime.walltime = walltime;
192
+ }
193
+ if (Object.hasOwn(value, "modules")) {
194
+ const modules = boundedStringList(value.modules, `${location}.modules`, VALIDATION_CONTRACT_CAPS.modules);
195
+ if (modules instanceof Error) return modules;
196
+ runtime.modules = modules;
197
+ }
198
+ return runtime;
199
+ }
200
+
201
+ function validateTolerances(value: unknown, location: string): ValidationNumericalTolerances | Error {
202
+ if (!isRecord(value)) return new Error(`${location} must be an object`);
203
+ const unknown = unknownFields(value, TOLERANCE_FIELDS);
204
+ if (unknown.length > 0) return new Error(`${location} has unknown field(s): ${unknown.join(", ")}`);
205
+ const tolerances: ValidationNumericalTolerances = {};
206
+ if (Object.hasOwn(value, "relative")) {
207
+ const relative = nonNegativeNumber(value.relative, `${location}.relative`);
208
+ if (relative instanceof Error) return relative;
209
+ tolerances.relative = relative;
210
+ }
211
+ if (Object.hasOwn(value, "absolute")) {
212
+ const absolute = nonNegativeNumber(value.absolute, `${location}.absolute`);
213
+ if (absolute instanceof Error) return absolute;
214
+ tolerances.absolute = absolute;
215
+ }
216
+ if (Object.hasOwn(value, "ulp")) {
217
+ const ulp = value.ulp;
218
+ if (typeof ulp !== "number" || !Number.isInteger(ulp) || ulp < 0) {
219
+ return new Error(`${location}.ulp must be a non-negative integer`);
220
+ }
221
+ tolerances.ulp = ulp;
222
+ }
223
+ return tolerances;
224
+ }
225
+
226
+ function validateArtifact(value: unknown, location: string): ValidationContractArtifact | Error {
227
+ if (!isRecord(value)) return new Error(`${location} must be an object with a path field`);
228
+ const unknown = unknownFields(value, ARTIFACT_FIELDS);
229
+ if (unknown.length > 0) return new Error(`${location} has unknown field(s): ${unknown.join(", ")}`);
230
+ if (!Object.hasOwn(value, "path")) return new Error(`${location}.path is required`);
231
+ const artifactPath = boundedText(value.path, `${location}.path`, VALIDATION_CONTRACT_CAPS.textBytes);
232
+ if (artifactPath instanceof Error) return artifactPath;
233
+ const artifact: ValidationContractArtifact = { path: artifactPath };
234
+ if (Object.hasOwn(value, "format")) {
235
+ const format = boundedText(value.format, `${location}.format`, VALIDATION_CONTRACT_CAPS.textBytes);
236
+ if (format instanceof Error) return format;
237
+ artifact.format = format;
238
+ }
239
+ if (Object.hasOwn(value, "expected_dimensions")) {
240
+ const dimensions = boundedMap(value.expected_dimensions, `${location}.expected_dimensions`, (entry, entryLocation) =>
241
+ typeof entry === "number" && Number.isInteger(entry) && entry >= 0
242
+ ? entry
243
+ : new Error(`${entryLocation} must be a non-negative integer`),
244
+ );
245
+ if (dimensions instanceof Error) return dimensions;
246
+ artifact.expected_dimensions = dimensions;
247
+ }
248
+ if (Object.hasOwn(value, "expected_attributes")) {
249
+ const attributes = boundedMap(value.expected_attributes, `${location}.expected_attributes`, (entry, entryLocation) =>
250
+ typeof entry === "string"
251
+ ? boundedText(entry, entryLocation, VALIDATION_CONTRACT_CAPS.textBytes)
252
+ : new Error(`${entryLocation} must be a string`),
253
+ );
254
+ if (attributes instanceof Error) return attributes;
255
+ artifact.expected_attributes = attributes;
256
+ }
257
+ if (Object.hasOwn(value, "numerical_tolerances")) {
258
+ const tolerances = validateTolerances(value.numerical_tolerances, `${location}.numerical_tolerances`);
259
+ if (tolerances instanceof Error) return tolerances;
260
+ artifact.numerical_tolerances = tolerances;
261
+ }
262
+ if (Object.hasOwn(value, "preserve")) {
263
+ if (typeof value.preserve !== "boolean") return new Error(`${location}.preserve must be a boolean`);
264
+ artifact.preserve = value.preserve;
265
+ }
266
+ return artifact;
267
+ }
268
+
269
+ /** Parse contract text under the version-1 schema; `contractPath` only labels the result. */
270
+ export function parseValidationContractText(text: string, contractPath: string): ValidationContractLoadResult {
271
+ const invalid = (reason: string): ValidationContractLoadResult => ({ ok: false, path: contractPath, reason });
272
+ const document = parseDocument(text, { prettyErrors: false, strict: true, uniqueKeys: true });
273
+ if (document.errors.length > 0) {
274
+ return invalid(`invalid YAML: ${document.errors.map((error) => error.message).join("; ")}`);
275
+ }
276
+ let parsed: unknown;
277
+ try {
278
+ parsed = document.toJS({ maxAliasCount: 0 }) as unknown;
279
+ } catch (error) {
280
+ return invalid(`invalid YAML: ${error instanceof Error ? error.message : String(error)}`);
281
+ }
282
+ if (!isRecord(parsed)) return invalid("root must be an object with a version field");
283
+ const rootUnknown = unknownFields(parsed, ROOT_FIELDS);
284
+ if (rootUnknown.length > 0) return invalid(`root has unknown field(s): ${rootUnknown.join(", ")}`);
285
+ if (!Object.hasOwn(parsed, "version")) return invalid("root.version is required");
286
+ if (parsed.version !== VALIDATION_CONTRACT_VERSION) {
287
+ return invalid(
288
+ `unsupported version ${JSON.stringify(parsed.version)}; supported version is ${VALIDATION_CONTRACT_VERSION}`,
289
+ );
290
+ }
291
+ const contract: ValidationContract = { version: VALIDATION_CONTRACT_VERSION };
292
+ if (Object.hasOwn(parsed, "task")) {
293
+ const task = boundedText(parsed.task, "root.task", VALIDATION_CONTRACT_CAPS.textBytes);
294
+ if (task instanceof Error) return invalid(task.message);
295
+ contract.task = task;
296
+ }
297
+ if (Object.hasOwn(parsed, "runtime")) {
298
+ const runtime = validateRuntime(parsed.runtime, "root.runtime");
299
+ if (runtime instanceof Error) return invalid(runtime.message);
300
+ contract.runtime = runtime;
301
+ }
302
+ if (Object.hasOwn(parsed, "artifacts")) {
303
+ if (!Array.isArray(parsed.artifacts)) return invalid("root.artifacts must be an array");
304
+ if (parsed.artifacts.length > VALIDATION_CONTRACT_CAPS.artifacts) {
305
+ return invalid(`root.artifacts exceeds the ${VALIDATION_CONTRACT_CAPS.artifacts}-entry cap`);
306
+ }
307
+ const artifacts: ValidationContractArtifact[] = [];
308
+ for (const [index, value] of parsed.artifacts.entries()) {
309
+ const artifact = validateArtifact(value, `artifacts[${index}]`);
310
+ if (artifact instanceof Error) return invalid(artifact.message);
311
+ artifacts.push(artifact);
312
+ }
313
+ contract.artifacts = artifacts;
314
+ }
315
+ if (Object.hasOwn(parsed, "validators")) {
316
+ const validators = boundedStringList(parsed.validators, "root.validators", VALIDATION_CONTRACT_CAPS.validators);
317
+ if (validators instanceof Error) return invalid(validators.message);
318
+ contract.validators = validators;
319
+ }
320
+ if (Object.hasOwn(parsed, "notes")) {
321
+ const notes = boundedText(parsed.notes, "root.notes", VALIDATION_CONTRACT_CAPS.notesBytes);
322
+ if (notes instanceof Error) return invalid(notes.message);
323
+ contract.notes = notes;
324
+ }
325
+ return { ok: true, contract, path: contractPath };
326
+ }
327
+
328
+ function readContractText(absolutePath: string, workspaceRoot: string): string | Error {
329
+ let realPath: string;
330
+ try {
331
+ const realRoot = realpathSync(workspaceRoot);
332
+ realPath = realpathSync(absolutePath);
333
+ resolveSafeCwd(realPath, realRoot);
334
+ } catch (error) {
335
+ const message = error instanceof Error ? error.message : String(error);
336
+ return new Error(`contract file must resolve inside the workspace root (${message})`);
337
+ }
338
+ try {
339
+ const stats = statSync(realPath);
340
+ if (!stats.isFile()) return new Error("contract path must be a regular file");
341
+ if (stats.size > VALIDATION_CONTRACT_CAPS.fileBytes) {
342
+ return new Error(`file exceeds the ${VALIDATION_CONTRACT_CAPS.fileBytes}-byte cap`);
343
+ }
344
+ return readFileSync(realPath, "utf8");
345
+ } catch (error) {
346
+ return new Error(`cannot read contract (${error instanceof Error ? error.message : String(error)})`);
347
+ }
348
+ }
349
+
350
+ /**
351
+ * Load the workspace's validation contract. The first YAML path in
352
+ * {@link VALIDATION_CONTRACT_YAML_PATHS} that exists is the contract; a
353
+ * `VALIDATION.md` without any YAML is reported present and advisory. Every
354
+ * failure is a value, never a throw, so rigor resolution stays total.
355
+ */
356
+ export function loadValidationContract(workspaceRoot: string): ValidationContractLoadResult {
357
+ let contractPath: string | null = null;
358
+ try {
359
+ contractPath =
360
+ VALIDATION_CONTRACT_YAML_PATHS.find((relative) => existsSync(path.join(workspaceRoot, relative))) ?? null;
361
+ if (contractPath === null) {
362
+ if (existsSync(path.join(workspaceRoot, VALIDATION_CONTRACT_MARKDOWN_PATH))) {
363
+ return { ok: true, contract: null, path: VALIDATION_CONTRACT_MARKDOWN_PATH, advisory: true };
364
+ }
365
+ return { ok: true, contract: null };
366
+ }
367
+ } catch (error) {
368
+ return {
369
+ ok: false,
370
+ path: contractPath ?? VALIDATION_CONTRACT_YAML_PATHS[0] ?? "validation.yaml",
371
+ reason: `cannot inspect workspace root (${error instanceof Error ? error.message : String(error)})`,
372
+ };
373
+ }
374
+ const text = readContractText(path.join(workspaceRoot, contractPath), workspaceRoot);
375
+ if (text instanceof Error) return { ok: false, path: contractPath, reason: text.message };
376
+ return parseValidationContractText(text, contractPath);
377
+ }
378
+
379
+ /** One line a diagnostic surface can print for a load result, or null when there is nothing to say. */
380
+ export function describeValidationContract(result: ValidationContractLoadResult): string | null {
381
+ if (!result.ok) return `${result.path}: ${result.reason}`;
382
+ if (result.contract === null) {
383
+ return "advisory" in result
384
+ ? `${result.path} is advisory prose and does not raise rigor; add a version-1 validation.yaml to raise the default to high`
385
+ : null;
386
+ }
387
+ return null;
388
+ }
@@ -30,6 +30,8 @@ export interface AuditReadResult {
30
30
  }
31
31
 
32
32
  export interface SessionReadResult {
33
+ /** Persisted /tree selection, when the session has not appended past it. */
34
+ leafTurnId?: string;
33
35
  entries: SessionEntry[];
34
36
  missing: boolean;
35
37
  errors: string[];
@@ -142,7 +144,14 @@ export async function readSessionEntriesForId(stateDir: string, sessionId: strin
142
144
  return { entries: [], missing: false, errors: [`${currentPath}: ${err.message ?? String(err)}`] };
143
145
  }
144
146
  }
145
- return parseSessionEntries(raw, source);
147
+ const result = parseSessionEntries(raw, source);
148
+ try {
149
+ const meta: unknown = JSON.parse(await readFile(join(root, cwdHash, sessionId, "meta.json"), "utf8"));
150
+ if (isRecord(meta) && typeof meta.pinnedLeafTurnId === "string") result.leafTurnId = meta.pinnedLeafTurnId;
151
+ } catch {
152
+ // Legacy archives without metadata fall back to the newest message branch.
153
+ }
154
+ return result;
146
155
  }
147
156
  return { entries: [], missing: true, errors: [] };
148
157
  }
@@ -10,10 +10,11 @@
10
10
  * boundary; this module does not import pi-ai directly.
11
11
  */
12
12
 
13
- import { stream } from "../../../engine/ai.js";
13
+ import { streamSimple } from "../../../engine/ai.js";
14
14
  import type { EngineModel, Usage } from "../../../engine/types.js";
15
15
  import { foldWorkingSet } from "../../context/working-set/fold.js";
16
16
  import { recallableRefListing } from "../../context/working-set/recall.js";
17
+ import { extractReasoningTokens } from "../context-accounting.js";
17
18
  import type { CompactionUsage, SessionEntry } from "../entries.js";
18
19
  import { serializeConversation } from "./branch-summary.js";
19
20
  import { findCutPoint } from "./cut-point.js";
@@ -86,6 +87,14 @@ In addition to that carried-forward context, summarize ONLY the active-turn deta
86
87
 
87
88
  Do NOT answer the user. Do NOT summarize unrelated older history.`;
88
89
 
90
+ /** One invoked summary stream, including failed calls that produce no checkpoint. */
91
+ export interface CompactionCallObservation {
92
+ outcome: "success" | "error" | "aborted";
93
+ usage: unknown;
94
+ timestamp: string;
95
+ durationMs: number;
96
+ }
97
+
89
98
  export interface CompactInput {
90
99
  /** Ordered session entries to compact. The caller reads these from the session domain. */
91
100
  entries: ReadonlyArray<SessionEntry>;
@@ -105,6 +114,8 @@ export interface CompactInput {
105
114
  reserveTokens?: number;
106
115
  /** Override the built-in keep-recent default (DEFAULT_KEEP_RECENT_TOKENS). */
107
116
  keepRecentTokens?: number;
117
+ /** Accounting observer; called once per invoked stream, including failures. */
118
+ onCall?: (call: CompactionCallObservation) => void;
108
119
  }
109
120
 
110
121
  export interface CompactResult {
@@ -367,6 +378,24 @@ function addCompactionUsage(total: CompactionUsage | undefined, raw: unknown): C
367
378
  };
368
379
  }
369
380
 
381
+ /** Keep attributable partial facts if a failed terminal object resets missing fields to zero. */
382
+ function retainReportedUsage(previous: Record<string, unknown>, raw: unknown): Record<string, unknown> {
383
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return previous;
384
+ const usage = raw as Record<string, unknown>;
385
+ const known = { ...previous };
386
+ for (const field of ["input", "output", "cacheRead", "cacheWrite", "totalTokens"]) {
387
+ const value = numberOrZero(usage[field]);
388
+ if (value > 0) known[field] = value;
389
+ }
390
+ const reasoning = extractReasoningTokens({ ...usage, reasoningTokens: undefined });
391
+ if (reasoning !== null && reasoning > 0) known.reasoning = reasoning;
392
+ if (usage.cost && typeof usage.cost === "object" && "total" in usage.cost) {
393
+ const cost = numberOrZero(usage.cost.total);
394
+ if (cost > 0) known.cost = { total: cost };
395
+ }
396
+ return known;
397
+ }
398
+
370
399
  async function runSummaryStream(
371
400
  input: CompactInput,
372
401
  userText: string,
@@ -383,26 +412,47 @@ async function runSummaryStream(
383
412
  messages: [buildUserMessage(userText)],
384
413
  };
385
414
 
386
- const events = stream(
387
- input.model,
388
- context as unknown as Parameters<typeof stream>[1],
389
- options as unknown as Parameters<typeof stream>[2],
390
- );
391
-
392
- let summary = "";
415
+ const timestamp = new Date().toISOString();
416
+ const started = performance.now();
393
417
  let usage: unknown;
394
- for await (const event of events) {
395
- if (event.type === "done") {
396
- summary = textFromAssistant(event.message);
397
- usage = (event.message as { usage?: unknown }).usage;
398
- break;
399
- }
400
- if (event.type === "error") {
401
- const reason = event.error.errorMessage ?? "unknown error";
402
- throw new Error(`compaction stream failed: ${reason}`);
418
+ let reported: Record<string, unknown> = {};
419
+ let outcome: CompactionCallObservation["outcome"] = "error";
420
+ try {
421
+ // Summarization requests thinking off, as its resolver does. Bare stream
422
+ // infers an active level from model.reasoning and would undo that choice.
423
+ const events = streamSimple(
424
+ input.model,
425
+ context as unknown as Parameters<typeof streamSimple>[1],
426
+ options as unknown as Parameters<typeof streamSimple>[2],
427
+ );
428
+ for await (const event of events) {
429
+ // Some transports throw after yielding a partial response. Retain the
430
+ // last reported usage even without a terminal error message.
431
+ if ("partial" in event) {
432
+ usage = event.partial.usage ?? usage;
433
+ reported = retainReportedUsage(reported, usage);
434
+ }
435
+ if (event.type === "done") {
436
+ usage = event.message.usage ?? usage;
437
+ outcome = "success";
438
+ return { text: textFromAssistant(event.message).trim(), usage };
439
+ }
440
+ if (event.type === "error") {
441
+ usage = event.error.usage ?? usage;
442
+ reported = retainReportedUsage(reported, usage);
443
+ outcome = event.error.stopReason === "aborted" ? "aborted" : "error";
444
+ throw new Error(`compaction stream failed: ${event.error.errorMessage ?? "unknown error"}`);
445
+ }
403
446
  }
447
+ throw new Error("compaction stream ended without a terminal response");
448
+ } finally {
449
+ input.onCall?.({
450
+ outcome: outcome === "error" && input.signal?.aborted ? "aborted" : outcome,
451
+ usage: outcome === "success" ? usage : reported,
452
+ timestamp,
453
+ durationMs: Math.max(0, performance.now() - started),
454
+ });
404
455
  }
405
- return { text: summary.trim(), usage };
406
456
  }
407
457
 
408
458
  /**
@@ -464,16 +514,16 @@ export async function compact(input: CompactInput): Promise<CompactResult> {
464
514
  const userText = buildUserText(conversationText, input.instructions, previousContextText);
465
515
  const historySummary = await runSummaryStream(input, userText, systemPrompt, maxTokens);
466
516
  usage = addCompactionUsage(usage, historySummary.usage);
467
- if (historySummary.text.length > 0) summaryParts.push(historySummary.text);
517
+ if (historySummary.text.length === 0) throw new Error("compaction returned an empty history summary");
518
+ summaryParts.push(historySummary.text);
468
519
  }
469
520
  if (turnPrefix.length > 0) {
470
521
  const conversationText = serializeConversation(turnPrefix);
471
522
  const userText = buildTurnPrefixUserText(conversationText, input.instructions, previousContextText);
472
523
  const prefixSummary = await runSummaryStream(input, userText, systemPrompt, maxTokens);
473
524
  usage = addCompactionUsage(usage, prefixSummary.usage);
474
- if (prefixSummary.text.length > 0) {
475
- summaryParts.push(`**Turn Context (split turn):**\n\n${prefixSummary.text}`);
476
- }
525
+ if (prefixSummary.text.length === 0) throw new Error("compaction returned an empty split-turn summary");
526
+ summaryParts.push(`**Turn Context (split turn):**\n\n${prefixSummary.text}`);
477
527
  }
478
528
 
479
529
  const summary = `${summaryParts.join("\n\n---\n\n").trim()}${formatFileOperations(fileOps)}${formatRecallableRefs(