@iowarp/clio-coder 0.4.1 → 0.4.2

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 (437) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/CONTRIBUTING.md +59 -36
  3. package/README.md +404 -472
  4. package/SECURITY.md +2 -1
  5. package/dist/{acp-ZILU3AUO.js → acp-TMDQZDIG.js} +7 -7
  6. package/dist/{agents-HYWGBGQR.js → agents-5N5NG3XG.js} +28 -28
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-N3QT7CBO.js → auth-Z5CCBXKQ.js} +8 -9
  9. package/dist/{builtins-UJLMOVOV.js → builtins-K6TNDT24.js} +4 -4
  10. package/dist/{chunk-GVQJ5CCZ.js → chunk-2HFQNRV3.js} +7 -7
  11. package/dist/{chunk-QMXC4JB7.js → chunk-2NHR3NAY.js} +163 -1401
  12. package/dist/chunk-2X4RYJTJ.js +39 -0
  13. package/dist/{chunk-Y45G3AXC.js → chunk-2Z2IKEXI.js} +6 -10
  14. package/dist/{chunk-EIMVLWB3.js → chunk-34BHNEE3.js} +7 -3
  15. package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
  16. package/dist/chunk-3EBYEESD.js +314 -0
  17. package/dist/{chunk-CTJ4RNAA.js → chunk-3F7VUY77.js} +2 -2
  18. package/dist/{chunk-AP73CFDC.js → chunk-3KIPBMUA.js} +2 -2
  19. package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
  20. package/dist/{chunk-VEGN6WIQ.js → chunk-462T4EGZ.js} +2 -2
  21. package/dist/{chunk-AFKWHWXF.js → chunk-4JDLP6ZS.js} +33 -16
  22. package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
  23. package/dist/{chunk-AKB4GYDL.js → chunk-54ODD65L.js} +5 -5
  24. package/dist/{chunk-BBTJOK6Y.js → chunk-5KW52TEP.js} +3 -3
  25. package/dist/{chunk-6CCS4G3W.js → chunk-5PFYMY2V.js} +2 -2
  26. package/dist/chunk-77QIVUZB.js +1334 -0
  27. package/dist/{chunk-7OBGU7UB.js → chunk-7BHIY2MW.js} +7 -13
  28. package/dist/{chunk-3QSOM6PA.js → chunk-AZ4WMN4W.js} +2 -2
  29. package/dist/{chunk-6NJQITNH.js → chunk-B74PXLU7.js} +6 -3
  30. package/dist/{chunk-R23Z6K6I.js → chunk-B7HM5Z7T.js} +15 -15
  31. package/dist/{chunk-R32CLGZ6.js → chunk-BO7Y52RY.js} +81 -20
  32. package/dist/{chunk-UEDMSP56.js → chunk-BYMNWQ7O.js} +123 -148
  33. package/dist/{chunk-ZJLUDYFY.js → chunk-CRFOIAX3.js} +4 -4
  34. package/dist/{chunk-2NM363SV.js → chunk-CYZW7JHJ.js} +7 -7
  35. package/dist/{chunk-6HMJX2VU.js → chunk-DYHAXKHD.js} +38 -10
  36. package/dist/{chunk-THYWACCR.js → chunk-DZAW46HP.js} +3 -3
  37. package/dist/{chunk-FYUN5KZ3.js → chunk-DZEK6CJN.js} +17 -17
  38. package/dist/{chunk-3I5NY75V.js → chunk-E7GT7O5N.js} +5 -5
  39. package/dist/{chunk-VKFQTNDV.js → chunk-F2I26BDK.js} +4 -4
  40. package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
  41. package/dist/{chunk-IXJT6DCX.js → chunk-FVDGR2ZL.js} +3 -3
  42. package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
  43. package/dist/{chunk-7EPLI7VL.js → chunk-HIICAHCJ.js} +2 -2
  44. package/dist/{chunk-E67WX76H.js → chunk-HKMD33FO.js} +29 -80
  45. package/dist/chunk-HLAFFSEK.js +360 -0
  46. package/dist/{chunk-UAPGZHYC.js → chunk-I64IFBLB.js} +9 -2
  47. package/dist/{chunk-XKA2ICR3.js → chunk-I66ZTYNP.js} +440 -175
  48. package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
  49. package/dist/{chunk-PVAMAVBB.js → chunk-IDNA72AH.js} +102 -2
  50. package/dist/{chunk-GCSMB2KY.js → chunk-IKOZFYBN.js} +1 -1
  51. package/dist/{chunk-2VG7KLYV.js → chunk-IKSLQ4XV.js} +5460 -3241
  52. package/dist/{chunk-QKIFBZKT.js → chunk-IMXMHHMQ.js} +166 -25
  53. package/dist/{chunk-74YWRRU5.js → chunk-JBCS7CRR.js} +2 -2
  54. package/dist/{chunk-BDPT6GTK.js → chunk-JWJGP5DQ.js} +2 -2
  55. package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
  56. package/dist/chunk-KPXDY6QF.js +47 -0
  57. package/dist/{chunk-ABLSQ6JX.js → chunk-LJID3DYZ.js} +7 -1
  58. package/dist/{chunk-VKRH2TCS.js → chunk-M2DAX4F6.js} +2 -2
  59. package/dist/{chunk-6I5ILFOF.js → chunk-M2WXEHER.js} +2 -2
  60. package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
  61. package/dist/{chunk-N5UK64DP.js → chunk-MCMZMDAC.js} +2 -2
  62. package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
  63. package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
  64. package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
  65. package/dist/{chunk-HUAS7ITX.js → chunk-O3YUNJZ2.js} +13 -21
  66. package/dist/{chunk-MA3H6DM5.js → chunk-P75RZCJW.js} +25 -3
  67. package/dist/{chunk-IG7BCQBA.js → chunk-PGF63K6I.js} +2 -2
  68. package/dist/chunk-PJX3WQUQ.js +42 -0
  69. package/dist/{chunk-6DWBAZ5U.js → chunk-Q4XWMHX6.js} +4 -6
  70. package/dist/{chunk-OJTRZGR3.js → chunk-QQLGQY2A.js} +8 -8
  71. package/dist/{chunk-J4HBWF6Y.js → chunk-RLYRBIYQ.js} +115 -20
  72. package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
  73. package/dist/{chunk-C537JADH.js → chunk-SSEYRH53.js} +6 -7
  74. package/dist/chunk-SZAA6XDG.js +30 -0
  75. package/dist/{chunk-MOPSG2X7.js → chunk-TPEQIQIE.js} +6 -6
  76. package/dist/{chunk-JA5QWE4Z.js → chunk-UBRFI4HS.js} +1879 -1650
  77. package/dist/{chunk-BTGG6BG2.js → chunk-UH347SHR.js} +154 -15
  78. package/dist/{chunk-5YHDIDBP.js → chunk-UH632ZYL.js} +2 -2
  79. package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
  80. package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
  81. package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
  82. package/dist/{chunk-UXN6JT4W.js → chunk-W4YEMFBX.js} +2 -2
  83. package/dist/{chunk-TD3PGPQA.js → chunk-W6NIE6OW.js} +2 -2
  84. package/dist/{chunk-TVH4ONAM.js → chunk-X7IARSHT.js} +3 -3
  85. package/dist/{chunk-PJJ6MY27.js → chunk-XE3PCIXH.js} +3 -3
  86. package/dist/{chunk-FEFIFZTL.js → chunk-XGDPUNND.js} +2 -2
  87. package/dist/{chunk-SCYB3HA4.js → chunk-XOXV5GKE.js} +51 -16
  88. package/dist/{chunk-QTFGO774.js → chunk-XQRY4DTA.js} +24 -11
  89. package/dist/{chunk-BJGUKIG4.js → chunk-YJISEZKC.js} +2 -2
  90. package/dist/{chunk-GPPB3JBE.js → chunk-ZGNYYXQ6.js} +2 -2
  91. package/dist/{chunk-SINK3QR6.js → chunk-ZNT2M6TG.js} +7 -7
  92. package/dist/{chunk-7RY5VZPH.js → chunk-ZW4HH5JJ.js} +6 -6
  93. package/dist/cli/index.js +33 -32
  94. package/dist/{clio-IT3G3VQH.js → clio-7VB377CC.js} +7 -7
  95. package/dist/{code-nav-RK6S7F6E.js → code-nav-YVLCYA7V.js} +85 -17
  96. package/dist/{config-3QZRWZJF.js → config-4HVOS65E.js} +88 -43
  97. package/dist/{configure-FL7Y3KJF.js → configure-PIWO7B24.js} +10 -10
  98. package/dist/{context-5HE7ODYK.js → context-IYEHL3WQ.js} +33 -31
  99. package/dist/{context-XNHL75JV.js → context-KQYIWPWT.js} +47 -34
  100. package/dist/{context-KYQFRVDC.js → context-N6ZE3LGJ.js} +11 -11
  101. package/dist/{context-clear-N545L53A.js → context-clear-G4OGZJDS.js} +33 -31
  102. package/dist/{context-working-set-QHKXSV2F.js → context-working-set-BWLF6LJP.js} +7 -7
  103. package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-2QQAITS3.js} +38 -38
  104. package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
  105. package/dist/{doctor-ZGPEGHIP.js → doctor-LHBD36VU.js} +23 -22
  106. package/dist/{eval-GXLL44RD.js → eval-C45FYRJ6.js} +21 -20
  107. package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-6DEJPLBF.js} +2 -2
  108. package/dist/{evidence-HWLBRH3Q.js → evidence-6SHONYAF.js} +30 -28
  109. package/dist/{evolve-FTZBMNVW.js → evolve-KRKMV72X.js} +30 -28
  110. package/dist/{extensions-VHRBEID7.js → extensions-KPZ2UHBB.js} +5 -3
  111. package/dist/{fleet-CKZHJWZJ.js → fleet-IVTCKDHT.js} +62 -61
  112. package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-EDWL3IT7.js} +5 -5
  113. package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-YP3YEFGK.js} +4 -4
  114. package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-ZFWKHY2M.js} +16 -14
  115. package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-FVUNCBML.js} +31 -29
  116. package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-UN5XED4R.js} +2 -2
  117. package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-XOWC4HSX.js} +17 -15
  118. package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-UN3SODEL.js} +30 -28
  119. package/dist/{fleet-view-WAMJYNDT.js → fleet-view-TWHJKCN6.js} +31 -29
  120. package/dist/{init-5XQRBOFV.js → init-T2QORQ3Y.js} +50 -49
  121. package/dist/{interop-34TVO25M.js → interop-IN5I2A66.js} +5 -5
  122. package/dist/{library-3QY6KF57.js → library-LSCATDLZ.js} +15 -13
  123. package/dist/{memory-L4UTIIIW.js → memory-HYOKAGGJ.js} +31 -29
  124. package/dist/{models-ZVX3QOWE.js → models-2GPMFYCM.js} +22 -21
  125. package/dist/{monitor-CEKVSYTS.js → monitor-E4ASVUJH.js} +34 -32
  126. package/dist/{orchestrator-77BAP6BC.js → orchestrator-DDMPR3PY.js} +984 -583
  127. package/dist/{panes-7STHOAUJ.js → panes-E3RUXOW5.js} +4 -4
  128. package/dist/{panes-SHAUIRXY.js → panes-IXKLOKA2.js} +23 -8
  129. package/dist/{reset-EOLM7GVE.js → reset-OAQP3W4O.js} +4 -4
  130. package/dist/{resources-74GKTLSF.js → resources-OTRSN34L.js} +15 -13
  131. package/dist/{run-HBAUJNNZ.js → run-5DEYH5QK.js} +60 -59
  132. package/dist/{share-G3APVLVP.js → share-IHWTLO3M.js} +19 -15
  133. package/dist/{skills-35HHUKCR.js → skills-IYMXMKW4.js} +17 -15
  134. package/dist/{skills-eval-QN4HSHDC.js → skills-eval-DROHSJAR.js} +36 -36
  135. package/dist/{skills-inventory-J357J34F.js → skills-inventory-D7X4L4ZX.js} +15 -13
  136. package/dist/{slash-commands-JZZCQA32.js → slash-commands-QBM7UZ3B.js} +21 -18
  137. package/dist/{steer-XAVHJM22.js → steer-Z5DO23FJ.js} +2 -2
  138. package/dist/{targets-DSM6CY3M.js → targets-P2FUC4IL.js} +25 -28
  139. package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-YREJ3JX2.js} +5 -5
  140. package/dist/{tools-MKNWVPBH.js → tools-5B7RO6MV.js} +4 -4
  141. package/dist/{trace-ECQ7TIYZ.js → trace-YMGMUM6A.js} +55 -7
  142. package/dist/{upgrade-H7TOM7YL.js → upgrade-PXK3S2YM.js} +11 -9
  143. package/dist/{usage-X52N3IDJ.js → usage-ME5MPXGX.js} +36 -34
  144. package/dist/{verifiers-EJTVVSMA.js → verifiers-BVZ7IWOO.js} +5 -5
  145. package/dist/{verify-YJL6XET2.js → verify-5K7ZKQFC.js} +4 -4
  146. package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
  147. package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-F5W5QTYY.js} +48 -47
  148. package/dist/{with-panes-OBOBFIIR.js → with-panes-BYOJCLAM.js} +51 -255
  149. package/dist/worker/entry.js +45 -30
  150. package/docs/README.md +176 -81
  151. package/docs/{acp.md → architecture/acp.md} +36 -20
  152. package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
  153. package/docs/{architecture.md → architecture/architecture.md} +43 -22
  154. package/docs/{artifact-placement.md → architecture/artifact-placement.md} +26 -23
  155. package/docs/architecture/artifact-versions.md +90 -0
  156. package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
  157. package/docs/{context-engine.md → architecture/context-engine.md} +25 -25
  158. package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
  159. package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
  160. package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
  161. package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
  162. package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
  163. package/docs/{model-catalog.md → architecture/model-catalog.md} +40 -17
  164. package/docs/{observability.md → architecture/observability.md} +26 -13
  165. package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
  166. package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +55 -20
  167. package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +35 -24
  168. package/docs/{safety-model.md → architecture/safety-model.md} +20 -15
  169. package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
  170. package/docs/architecture/time-conventions.md +125 -0
  171. package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
  172. package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
  173. package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
  174. package/docs/{built-in-agents.md → guide/built-in-agents.md} +50 -34
  175. package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +65 -60
  176. package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +227 -289
  177. package/docs/guide/configuration-reference.md +1158 -0
  178. package/docs/{environment-variables.md → guide/environment-variables.md} +31 -28
  179. package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
  180. package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
  181. package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
  182. package/docs/{glossary.md → guide/glossary.md} +14 -11
  183. package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +44 -13
  184. package/docs/guide/panes-and-files.md +290 -0
  185. package/docs/{proactive-memory.md → guide/proactive-memory.md} +79 -66
  186. package/docs/{resource-library.md → guide/resource-library.md} +13 -4
  187. package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +7 -3
  188. package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
  189. package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
  190. package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
  191. package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
  192. package/docs/{development-pipeline.md → process/development-pipeline.md} +24 -26
  193. package/docs/process/documentation-coverage.md +100 -0
  194. package/docs/process/documentation-guide.md +187 -0
  195. package/docs/{eval-runner.md → process/eval-runner.md} +41 -50
  196. package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
  197. package/docs/{evolution.md → process/evolution.md} +2 -2
  198. package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
  199. package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
  200. package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
  201. package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
  202. package/evals/README.md +2 -2
  203. package/package.json +9 -7
  204. package/skills/README.md +46 -37
  205. package/skills/coding/ast-grep/SKILL.md +2 -2
  206. package/skills/coding/coding-standards/SKILL.md +2 -2
  207. package/skills/coding/prototype/SKILL.md +2 -2
  208. package/skills/coding/tdd/SKILL.md +2 -2
  209. package/skills/context/context-handoff/SKILL.md +2 -2
  210. package/skills/context/context-prime/SKILL.md +2 -2
  211. package/skills/git/file-ticket/SKILL.md +2 -2
  212. package/skills/git/fix-issue/SKILL.md +3 -3
  213. package/skills/git/resolve-merge-conflicts/SKILL.md +2 -2
  214. package/skills/git/ship/SKILL.md +2 -2
  215. package/skills/git/worktree-create/SKILL.md +2 -2
  216. package/skills/git/worktree-merge/SKILL.md +2 -2
  217. package/skills/meta/clio-coder-dev/SKILL.md +9 -5
  218. package/skills/meta/clio-coder-dev/evals.md +3 -2
  219. package/skills/meta/clio-coder-test/SKILL.md +102 -95
  220. package/skills/meta/clio-coder-test/evals.md +9 -4
  221. package/skills/meta/clio-coder-test/references/harness.md +100 -124
  222. package/skills/meta/clio-coder-test/references/test-map.md +77 -50
  223. package/skills/meta/credentials/SKILL.md +2 -2
  224. package/skills/meta/find-skills/SKILL.md +2 -2
  225. package/skills/meta/herdr/SKILL.md +2 -2
  226. package/skills/meta/skill-craft/SKILL.md +22 -16
  227. package/skills/planning/architecture/SKILL.md +2 -2
  228. package/skills/planning/backlog/SKILL.md +2 -2
  229. package/skills/planning/prd/SKILL.md +2 -2
  230. package/skills/planning/product-intent/SKILL.md +2 -2
  231. package/skills/planning/tech-spec/SKILL.md +2 -2
  232. package/skills/registry.yaml +62 -62
  233. package/skills/research/arxiv-literature/SKILL.md +2 -2
  234. package/skills/research/experiment-protocol/SKILL.md +2 -2
  235. package/skills/research/scientific-debugging/SKILL.md +2 -2
  236. package/skills/research/scientific-modernization/SKILL.md +2 -2
  237. package/skills/skill-marketplace.json +62 -62
  238. package/skills/workflow/cut-it/SKILL.md +2 -2
  239. package/skills/workflow/design-council/SKILL.md +2 -2
  240. package/skills/workflow/grill-me/SKILL.md +2 -2
  241. package/skills/workflow/workflow-distiller/SKILL.md +2 -2
  242. package/src/cli/args.ts +2 -2
  243. package/src/cli/bootstrap-generate.ts +1 -1
  244. package/src/cli/config-inspect.ts +65 -12
  245. package/src/cli/configure.ts +0 -4
  246. package/src/cli/docs.ts +22 -14
  247. package/src/cli/doctor-naming.ts +5 -5
  248. package/src/cli/doctor-toolchain.ts +3 -3
  249. package/src/cli/eval.ts +1 -2
  250. package/src/cli/extensions.ts +2 -1
  251. package/src/cli/fleet.ts +1 -1
  252. package/src/cli/index.ts +2 -1
  253. package/src/cli/internal-dispatch.ts +3 -4
  254. package/src/cli/panes.ts +19 -5
  255. package/src/cli/run.ts +2 -2
  256. package/src/cli/share.ts +5 -1
  257. package/src/cli/skills-eval.ts +3 -3
  258. package/src/cli/targets.ts +2 -6
  259. package/src/cli/trace.ts +55 -4
  260. package/src/cli/wiki-generate.ts +1 -1
  261. package/src/core/artifact-paths.ts +1 -1
  262. package/src/core/bash-exec.ts +131 -86
  263. package/src/core/bus-events.ts +51 -6
  264. package/src/core/config.ts +5 -1
  265. package/src/core/defaults.ts +7 -4
  266. package/src/core/dispatch-outcome.ts +16 -0
  267. package/src/core/guardrails.ts +10 -49
  268. package/src/core/prompt-hint.ts +9 -0
  269. package/src/domains/agents/builtins/architect.md +2 -3
  270. package/src/domains/agents/builtins/coder.md +3 -2
  271. package/src/domains/agents/builtins/debugger.md +2 -2
  272. package/src/domains/agents/builtins/documenter.md +2 -2
  273. package/src/domains/agents/builtins/git-master.md +1 -1
  274. package/src/domains/agents/builtins/oracle.md +1 -1
  275. package/src/domains/agents/builtins/provenance.md +1 -1
  276. package/src/domains/agents/builtins/researcher.md +1 -1
  277. package/src/domains/agents/builtins/scout.md +1 -1
  278. package/src/domains/agents/builtins/tester.md +2 -2
  279. package/src/domains/agents/builtins/verifier.md +2 -2
  280. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  281. package/src/domains/agents/catalog.ts +12 -14
  282. package/src/domains/agents/contract.ts +2 -0
  283. package/src/domains/agents/extension.ts +23 -1
  284. package/src/domains/config/keybindings.ts +8 -0
  285. package/src/domains/context/extension.ts +0 -3
  286. package/src/domains/context/working-set/path-index.ts +1 -0
  287. package/src/domains/dispatch/capability-match.ts +10 -0
  288. package/src/domains/dispatch/extension.ts +105 -22
  289. package/src/domains/dispatch/host-verification.ts +435 -39
  290. package/src/domains/dispatch/intent-requirements.ts +10 -0
  291. package/src/domains/dispatch/intent.ts +18 -1
  292. package/src/domains/dispatch/path-scope.ts +235 -24
  293. package/src/domains/dispatch/run-event-journal.ts +4 -15
  294. package/src/domains/dispatch/state.ts +2 -3
  295. package/src/domains/dispatch/transport.ts +45 -21
  296. package/src/domains/dispatch/types.ts +55 -3
  297. package/src/domains/eval/artifacts/store.ts +5 -0
  298. package/src/domains/eval/store.ts +8 -1
  299. package/src/domains/evidence/trust-status.ts +10 -1
  300. package/src/domains/extensions/contract.ts +15 -1
  301. package/src/domains/extensions/discovery.ts +238 -41
  302. package/src/domains/extensions/extension.ts +105 -6
  303. package/src/domains/extensions/index.ts +24 -0
  304. package/src/domains/extensions/integrity.ts +189 -0
  305. package/src/domains/extensions/manager.ts +17 -1
  306. package/src/domains/extensions/resource-path.ts +27 -0
  307. package/src/domains/extensions/resources.ts +18 -38
  308. package/src/domains/extensions/snapshot-store.ts +39 -0
  309. package/src/domains/extensions/snapshot.ts +180 -0
  310. package/src/domains/extensions/state.ts +385 -57
  311. package/src/domains/extensions/types.ts +118 -1
  312. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
  313. package/src/domains/lifecycle/migrations/index.ts +2 -0
  314. package/src/domains/lifecycle/naming-resources.ts +19 -4
  315. package/src/domains/lifecycle/naming-yazi.ts +10 -5
  316. package/src/domains/middleware/contract.ts +26 -0
  317. package/src/domains/middleware/extension.ts +24 -24
  318. package/src/domains/middleware/hook-receipts.ts +27 -4
  319. package/src/domains/middleware/hooks-io.ts +65 -32
  320. package/src/domains/middleware/hooks.ts +64 -0
  321. package/src/domains/middleware/index.ts +28 -4
  322. package/src/domains/middleware/registrations.ts +326 -0
  323. package/src/domains/middleware/runtime.ts +28 -0
  324. package/src/domains/middleware/snapshot.ts +20 -7
  325. package/src/domains/mux/contract.ts +38 -0
  326. package/src/domains/mux/detect.ts +6 -13
  327. package/src/domains/mux/index.ts +1 -1
  328. package/src/domains/mux/operations.ts +44 -5
  329. package/src/domains/mux/yazi/assets/yazi.toml +2 -2
  330. package/src/domains/mux/yazi/session.ts +53 -4
  331. package/src/domains/mux/yazi/theme.ts +117 -17
  332. package/src/domains/observability/contract.ts +10 -11
  333. package/src/domains/observability/extension.ts +11 -3
  334. package/src/domains/observability/projection.ts +14 -90
  335. package/src/domains/observability/trace-store.ts +43 -7
  336. package/src/domains/prompts/compiler.ts +73 -53
  337. package/src/domains/prompts/contract.ts +15 -3
  338. package/src/domains/prompts/extension.ts +97 -9
  339. package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
  340. package/src/domains/prompts/fragments/identity/clio.md +6 -12
  341. package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
  342. package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
  343. package/src/domains/prompts/fragments/operating/contract.md +7 -15
  344. package/src/domains/prompts/fragments/operating/delegation.md +32 -34
  345. package/src/domains/prompts/fragments/operating/skills.md +10 -24
  346. package/src/domains/prompts/fragments/operating/worker.md +1 -8
  347. package/src/domains/providers/index.ts +1 -1
  348. package/src/domains/providers/model-runtime-capabilities.ts +85 -21
  349. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +669 -104
  350. package/src/domains/providers/runtime-resolution.ts +31 -0
  351. package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
  352. package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
  353. package/src/domains/providers/types/cost-provenance.ts +19 -0
  354. package/src/domains/providers/types/local-model-quirks.ts +85 -37
  355. package/src/domains/resources/skills/loader.ts +16 -19
  356. package/src/domains/safety/call-target.ts +1 -1
  357. package/src/domains/safety/loop-detector.ts +7 -4
  358. package/src/domains/session/task-board.ts +10 -9
  359. package/src/domains/share/archive.ts +164 -7
  360. package/src/engine/acp/server.ts +62 -9
  361. package/src/engine/apis/llamacpp-residency.ts +3 -4
  362. package/src/engine/apis/lmstudio.ts +3 -3
  363. package/src/engine/apis/ollama-native.ts +6 -6
  364. package/src/engine/apis/openai-completions.ts +28 -25
  365. package/src/engine/apis/output-budget.ts +8 -18
  366. package/src/engine/apis/residency.ts +8 -27
  367. package/src/engine/gemma-channel-filter.ts +19 -0
  368. package/src/engine/loop-guard.ts +92 -12
  369. package/src/engine/worker-runtime.ts +40 -11
  370. package/src/engine/worker-tools.ts +3 -1
  371. package/src/entry/extension-hook-sources.ts +28 -0
  372. package/src/entry/extension-reload.ts +309 -0
  373. package/src/entry/orchestrator.ts +59 -35
  374. package/src/interactive/application-controller.ts +2 -1
  375. package/src/interactive/bus-notices.ts +8 -1
  376. package/src/interactive/chat-loop-messages.ts +3 -13
  377. package/src/interactive/chat-loop.ts +10 -1
  378. package/src/interactive/chat-panel.ts +36 -13
  379. package/src/interactive/chat-renderer.ts +71 -7
  380. package/src/interactive/dispatch-board.ts +6 -11
  381. package/src/interactive/footer/widgets.ts +13 -0
  382. package/src/interactive/interactive-application.ts +39 -4
  383. package/src/interactive/interactive-input-runtime.ts +4 -0
  384. package/src/interactive/interactive-presentation.ts +2 -2
  385. package/src/interactive/interactive-slash-runtime.ts +2 -0
  386. package/src/interactive/overlays/extensions.ts +9 -1
  387. package/src/interactive/overlays/help-reference.ts +13 -0
  388. package/src/interactive/overlays/settings.ts +27 -16
  389. package/src/interactive/panes-runtime.ts +111 -35
  390. package/src/interactive/prompt-cache-identity.ts +88 -0
  391. package/src/interactive/slash-commands.ts +129 -14
  392. package/src/interactive/stream-pacing-policy.ts +0 -23
  393. package/src/interactive/turn-context.ts +30 -15
  394. package/src/interactive/yazi-bridge.ts +60 -6
  395. package/src/tools/agent-tools.ts +30 -1
  396. package/src/tools/artifact.ts +2 -2
  397. package/src/tools/ask-user.ts +3 -3
  398. package/src/tools/bash.ts +1 -1
  399. package/src/tools/bootstrap.ts +4 -0
  400. package/src/tools/builtin-tool-catalog.ts +52 -22
  401. package/src/tools/codewiki/code-nav-surface.ts +6 -0
  402. package/src/tools/codewiki/code-nav.ts +99 -13
  403. package/src/tools/context/docs-engine.ts +20 -7
  404. package/src/tools/context/index.ts +29 -12
  405. package/src/tools/core-bootstrap.ts +28 -6
  406. package/src/tools/credential-present.ts +1 -2
  407. package/src/tools/dispatch-arguments.ts +5 -1
  408. package/src/tools/dispatch-plan.ts +48 -4
  409. package/src/tools/dispatch-run-events.ts +1 -1
  410. package/src/tools/dispatch-schema.ts +338 -0
  411. package/src/tools/dispatch-types.ts +3 -0
  412. package/src/tools/dispatch.ts +9 -254
  413. package/src/tools/ledger.ts +3 -5
  414. package/src/tools/monitor-surface.ts +5 -13
  415. package/src/tools/observation.ts +4 -5
  416. package/src/tools/panes-surface.ts +4 -11
  417. package/src/tools/panes.ts +4 -2
  418. package/src/tools/policy.ts +15 -2
  419. package/src/tools/read.ts +5 -6
  420. package/src/tools/registry.ts +30 -7
  421. package/src/tools/result-shaping.ts +18 -14
  422. package/src/tools/steer-surface.ts +1 -1
  423. package/src/tools/tasks.ts +1 -1
  424. package/src/tools/truncate.ts +6 -5
  425. package/src/tools/verify/surface.ts +6 -12
  426. package/src/tools/web-fetch-surface.ts +1 -3
  427. package/dist/chunk-5QIAJV2D.js +0 -48
  428. package/dist/chunk-JZWT5J3Y.js +0 -814
  429. package/dist/chunk-K7VKOLQQ.js +0 -15
  430. package/dist/chunk-PMZCIOCJ.js +0 -25
  431. package/dist/chunk-SUW5DORT.js +0 -819
  432. package/dist/chunk-UOV2BYIW.js +0 -107
  433. package/dist/chunk-WR6U3OVP.js +0 -45
  434. package/docs/artifact-versions.md +0 -67
  435. package/docs/documentation-coverage.md +0 -46
  436. package/docs/documentation-guide.md +0 -167
  437. package/docs/time-conventions.md +0 -101
@@ -1,11 +1,11 @@
1
1
  # Clio Coder Architecture and Boundaries
2
2
 
3
- > [!TIP]
4
- > **Interactive Spec Available:** An interactive dashboard is located at [docs/html/architecture_blueprint.html](html/architecture_blueprint.html) (Version: 0.4.0).
3
+ > **Visual blueprint:** The source checkout includes the complete
4
+ > [Clio Coder Architecture and Boundaries visual reference](https://github.com/iowarp/clio-coder/blob/main/docs/html/architecture_blueprint.html).
5
5
 
6
6
  Clio Coder is an experimental, terminal-first coding harness for the CLIO ecosystem. CLIO stands for Context Layer for Input/Output; the project is named for the Greek muse of history and developed by the Gnosis Research Center at Illinois Tech. Its architecture favors small, auditable subsystems over a single monolithic agent loop: CLI entry points, the interactive TUI, provider/runtime code, worker subprocesses, tools, and feature domains are kept separate so local-model support and scientific-software workflows can evolve without collapsing safety boundaries.
7
7
 
8
- This page is source-code aligned for the current `v0.4.0` development line.
8
+ This page is source-code aligned for the current source tree.
9
9
 
10
10
  ---
11
11
 
@@ -24,7 +24,12 @@ src/
24
24
  └── utils/ # small support utilities
25
25
  ```
26
26
 
27
- Registered domain modules include:
27
+ Feature-domain directories include the following. Not every row is a loaded
28
+ `DomainModule`: the orchestrator currently loads config, extensions, interop,
29
+ resources, share, context, providers, toolchain, safety, prompts, agents,
30
+ middleware, session, observability, scheduling, dispatch, and lifecycle, plus
31
+ mux when the pane tier is active. The other rows are libraries or CLI-owned
32
+ feature areas.
28
33
 
29
34
  | Domain | Primary source | Public surface |
30
35
  | --- | --- | --- |
@@ -49,6 +54,9 @@ Registered domain modules include:
49
54
  | scheduling | `src/domains/scheduling/**` | Budget ceilings, node cluster states, batch capacity checks. |
50
55
  | session | `src/domains/session/**` | Append-only JSONL transcripts, tree navigation, compaction. |
51
56
  | share | `src/domains/share/**` | Portable workspace and resource archive export/import. |
57
+ | toolchain | `src/domains/toolchain/**` | Pinned external-tool discovery, installation, and resolution. |
58
+ | user-tasks | `src/domains/user-tasks/**` | Library and CLI-owned durable user task list plus board handoff state. |
59
+ | mux | `src/domains/mux/**` | Optional interactive pane-host integration. |
52
60
 
53
61
  The `interop` domain owns one question: which other coding agents are on this
54
62
  machine and in this project. `src/domains/interop/registry.ts` is pure data, one
@@ -67,7 +75,7 @@ or `state` directory. Detection resolves binaries with `access(X_OK)` and no
67
75
  shell, checks install directories, and runs a bounded `--version` only when the
68
76
  caller asks and only for a binary that already resolved; a probe that cannot
69
77
  answer reports `unknown` and never `absent`. The one durable configuration write
70
- is an append to `delegation.agents`, and it happens only after an operator
78
+ is an append to `integrations.externalAgents.entries`, and it happens only after an operator
71
79
  decision.
72
80
 
73
81
  ---
@@ -161,16 +169,18 @@ Admission disposal is one registry-owned finally boundary, so a
161
169
  middleware guard block, ordinary return, or thrown body releases a provisional
162
170
  reservation exactly once.
163
171
 
164
- Only the admitted `run` step crosses `src/tools/lazy-tool.ts`. One cached promise
165
- owns the implementation import, including a deterministic failure, so concurrent
166
- first calls cannot initialize competing implementations. The loaded spec must
167
- match the advertised surface before its body can run. Ordinary body exceptions,
168
- result shaping, `after_tool` middleware, abort signals, and telemetry continue
169
- through the registry's existing path. This mechanism is built-in-only; it does
170
- not turn extension manifests or provider plugins into an executable tool loader.
171
- Source-built and installed-package coverage contracts locate implementations by
172
- stable behavior provenance, prove them absent during a real provider capability
173
- request, and prove only the invoked implementation present after first use.
172
+ For ordinary lazy tools, only the admitted `run` step crosses
173
+ `src/tools/lazy-tool.ts`. One cached promise owns the implementation import,
174
+ including a deterministic failure, so concurrent first calls cannot initialize
175
+ competing implementations. The loaded spec must match the advertised surface
176
+ before its body can run. Ordinary body exceptions, result shaping, `after_tool`
177
+ middleware, abort signals, and telemetry continue through the registry's
178
+ existing path. This mechanism is built-in-only; it does not turn extension
179
+ manifests or provider plugins into an executable tool loader. Dispatch is
180
+ different: `registerAllTools` creates its lightweight admission surface eagerly,
181
+ and `src/tools/dispatch.ts` owns a separate cached dynamic import of
182
+ `dispatch-runner.ts` after admission succeeds. It does not pass through
183
+ `lazy-tool.ts`.
174
184
 
175
185
  ## Boundary invariants
176
186
 
@@ -180,11 +190,11 @@ The enforced import rules below are complemented by the maintained
180
190
  [Pi SDK boundary table](pi-boundary.md), which records the semantic owner of
181
191
  each overlapping helper and the Clio deltas that must survive an SDK upgrade.
182
192
 
183
- These five enforced boundary rules constrain dependency **direction**, never import **form** (whether static vs dynamic, default vs named):
193
+ These six enforced boundary rules constrain dependency **direction**, never import **form** (whether static vs dynamic, default vs named):
184
194
 
185
- ### Rule 1: `@earendil-works/*` imports stay in `src/engine/**`
195
+ ### Rule 1: `@earendil-works/pi-*` imports stay in `src/engine/**`
186
196
 
187
- Only files under `src/engine/**` may import `@earendil-works/*` packages. Since the 0.83.0 engine-boundary rework, no file outside `src/engine/**` may import `@earendil-works/*` at all, value or type-only. Domain modules import erased engine shapes (`EngineModel`, `Api`, `Model`) directly from `src/engine/types.ts`.
197
+ Only files under `src/engine/**` may import `@earendil-works/pi-*` packages. Since the 0.83.0 engine-boundary rework, no file outside `src/engine/**` may import those packages at all, value or type-only. Domain modules import erased engine shapes (`EngineModel`, `Api`, `Model`) directly from `src/engine/types.ts`.
188
198
 
189
199
  Why: provider SDKs and pi-ai engine values must remain swappable behind one engine boundary. Domains and presentation layers operate against Clio contracts rather than vendor or runtime implementations. `src/engine/api-registry.ts` composes Pi's public lazy API factories in their canonical order, retains provider-owned authentication/header dispatch, and lets Clio's local-runtime adapters override API families without importing the deprecated compatibility aggregate. The only `pi-ai/compat` edge is dynamic: before a configured out-of-tree runtime evaluates, Clio joins Pi's process-global registry and mirrors its overrides so external provider plugins retain the same registry identity and last-writer-wins order. No configured plugin means no compatibility aggregate. OpenAI-compatible sampler fields and vLLM thinking budgets flow through Pi's `samplingParams` and `supportsThinkingTokenBudget` contracts; Clio's adapter retains only catalog selection and runtime-specific payload deltas. Tool head/tail truncation, byte formatting, and grep-line clipping likewise flow through pi-agent-core's `truncateHead`, `truncateTail`, `formatSize`, and `truncateLine`; Clio retains only its 16 KiB per-observation default and its exported line-count helper. Tool string enums come from pi-ai's `StringEnum` (`src/engine/ai.ts`), the model-facing text for replayed bash executions and branch or compaction summaries comes from pi-agent-core's `bashExecutionToText` and summary prefixes (`src/engine/messages.ts`), and Anthropic thinking payloads are assembled by Pi's narrow lazy stream implementation with no Clio rewrite.
190
200
 
@@ -210,6 +220,16 @@ Files under `src/tools/**` may never import `src/interactive/**` (neither value
210
220
 
211
221
  Turn modules and state machine files in the chat loop (`src/interactive/turn-*.ts`, `chat-loop.ts`) may never import `src/entry/**`. Composition flows in one direction only: the entry point composes the chat loop, never the reverse.
212
222
 
223
+ ### Rule 6: Stage 0 remains behind declared seams
224
+
225
+ Value importers outside the computed instant-shell Stage 0 closure and its
226
+ `src/interactive/**` and `src/engine/**` trees may enter those protected trees
227
+ only through a seam declared in `STAGE0_SEAMS`. A declared seam may not lead back
228
+ into the Stage 0 closure unless the existing composition-root overlap is
229
+ explicitly recorded. CLI type edges retain the declaration requirement. This
230
+ keeps unrelated importers from creating another reacher into the cold-start
231
+ chunk graph.
232
+
213
233
  ---
214
234
 
215
235
  ## Runtime flow
@@ -293,15 +313,16 @@ editor object and buffer. Submissions accepted before attachment are immutable
293
313
  FIFO records shown in the shell and admitted exactly once through the normal
294
314
  slash/bash/chat pipeline after attachment. A generation guard rejects a late
295
315
  hydration after shutdown; every failure path shares one idempotent close and
296
- terminal restoration transaction. The built-graph contract bounds the Stage 0
297
- closure and rejects provider, tool, codewiki, tree-sitter, and orchestrator
298
- implementation markers. ACP, headless, ordinary non-TTY invocation, help, and
316
+ terminal restoration transaction. The source boundary checker protects the
317
+ declared Stage 0 closure and seams. There is no committed built-chunk budget
318
+ contract at this revision; the installed-package smoke test still exercises
319
+ lazy codewiki loading. ACP, headless, ordinary non-TTY invocation, help, and
299
320
  subcommands never construct a lease; the established explicit
300
321
  `CLIO_CODER_INTERACTIVE=1` non-TTY override remains force-interactive.
301
322
 
302
323
  Tracing is opt-in and content-free. Its bounded asynchronous writer never does
303
324
  filesystem append I/O on the render stack, and shutdown awaits a bounded flush.
304
- See [performance-methodology.md](performance-methodology.md) for vocabulary,
325
+ See [performance-methodology.md](../process/performance-methodology.md) for vocabulary,
305
326
  commands, PTY limitations, and baseline evidence.
306
327
 
307
328
  ## Command spec
@@ -1,9 +1,13 @@
1
1
  # Artifact Placement
2
2
 
3
+ > **Visual blueprint:** The source checkout includes the complete
4
+ > [Artifact Placement visual reference](https://github.com/iowarp/clio-coder/blob/main/docs/html/artifact_placement_blueprint.html).
5
+
3
6
  Every file Clio generates has one home, decided by who reads it. The rule that
4
7
  follows from that: **the repo working tree holds files a human asked for.**
5
- Anything Clio produced on its own initiative lands in the gitignored project
6
- directory or under the XDG dirs, never beside your source.
8
+ Anything Clio produced on its own initiative lands in the project-local
9
+ `.clio-coder/` directory or under the XDG directories, never beside your source.
10
+ `context init` can add the recommended blanket ignore for `.clio-coder/`.
7
11
 
8
12
  This page is the contract. `src/core/artifact-paths.ts` is the code that
9
13
  implements the part of it the `artifact` tool owns.
@@ -13,7 +17,7 @@ implements the part of it the `artifact` tool owns.
13
17
  | Audience | What it means | Where it goes |
14
18
  | --- | --- | --- |
15
19
  | Human deliverable | A file the user asked to keep, and will read and commit | Repo working tree, at the path the user named |
16
- | Human transient | Something a human may want to read once; losing it costs nothing | Project-local `.clio-coder/` (gitignored) |
20
+ | Human transient | Something a human may want to read once; losing it costs nothing | Project-local `.clio-coder/` (normally gitignored) |
17
21
  | Agent-to-agent state | Machine-read plumbing between turns, workers, and sessions | `.clio-coder/` for per-project state; XDG data/state/cache for per-machine state |
18
22
 
19
23
  A class is human-facing only if a person is expected to open it. A plan an
@@ -33,7 +37,7 @@ Markdown.
33
37
  | Task-memory handoffs | `.clio-coder/handoffs/` | Agent-to-agent |
34
38
  | Dispatch proposals | `.clio-coder/proposals/` | Agent-to-agent |
35
39
  | Compete worktrees | `.clio-coder/worktrees/` | Agent-to-agent |
36
- | Test scratch | `.clio-coder/test-scratch/` | Agent-to-agent |
40
+ | Tool-result and harness scratch | XDG state `scratch/`, with tool offloads grouped by session | Agent-to-agent |
37
41
  | Evidence bundles | XDG data `evidence/` | Human transient (`clio-coder evidence`) |
38
42
  | Approved memory | XDG data `memory/` | Human transient (`clio-coder memory`) |
39
43
  | Eval artifacts | XDG data `evals/` | Human transient (`clio-coder eval`) |
@@ -41,7 +45,6 @@ Markdown.
41
45
  | Dispatch receipts | XDG state `receipts/` | Human transient (`clio-coder trace`) |
42
46
  | Audit records | XDG state `audit/` | Human transient |
43
47
  | Interview transcripts | XDG state `interviews/` | Agent-to-agent |
44
- | Harness scratch | XDG state `scratch/` | Agent-to-agent |
45
48
  | Caches | XDG cache | Agent-to-agent |
46
49
 
47
50
  `clio-coder paths` prints the resolved XDG directories for your machine.
@@ -63,27 +66,27 @@ first. Keep several by naming explicit paths.
63
66
 
64
67
  ## `.clio-coder/` and git
65
68
 
66
- `.clio-coder/` is gitignored in full. Everything above that lands there is
67
- generated, reproducible, and worthless in a diff, and the whole point of the
68
- contract is that a dogfooding session ends with `git status` clean.
69
+ `clio-coder context init` checks for a blanket `.clio-coder/` ignore. With
70
+ confirmation, or with `--yes`, it appends `.clio-coder/` to `.gitignore`; without
71
+ confirmation it warns and leaves the file unchanged. A project that has never
72
+ accepted or authored that rule can therefore see generated local state in
73
+ `git status`.
69
74
 
70
75
  Some `.clio-coder/` content is authored rather than generated, and a project
71
- that wants it reviewed and shared commits it deliberately by adding negations
72
- next to the ignore:
73
-
74
- ```gitignore
75
- .clio-coder/
76
- !.clio-coder/fleets/ # fleet contracts: repo-owned dispatch policy
77
- !.clio-coder/fleets/**
78
- !.clio-coder/rules/ # path-scoped project rules
79
- !.clio-coder/rules/**
80
- !.clio-coder/safety.yaml # project safety policy
81
- !.clio-coder/agents/ # project agent recipes
82
- !.clio-coder/agents/**
76
+ that wants it reviewed and shared commits exact files deliberately. With the
77
+ blanket parent directory ignored, child negations alone are ineffective because
78
+ Git does not descend into an excluded parent. Force-add an intentional asset,
79
+ for example:
80
+
81
+ ```bash
82
+ git add -f .clio-coder/fleets/build-review.md
83
+ git add -f .clio-coder/rules/backend.md
84
+ git add -f .clio-coder/safety.yaml
83
85
  ```
84
86
 
85
- This repository commits none of those, so its `.clio-coder/` stays fully
86
- ignored. Benchmark workspaces are temporary external repositories.
87
+ Review the forced path before committing it. This repository commits none of
88
+ those project-local assets, and its `.gitignore` contains the blanket rule.
89
+ Benchmark workspaces are temporary external repositories.
87
90
 
88
91
  ## Finding what was hidden
89
92
 
@@ -97,4 +100,4 @@ Hiding transient output from the working tree must not mean losing it.
97
100
 
98
101
  Related: [evidence-and-memory.md](evidence-and-memory.md),
99
102
  [trace-store.md](trace-store.md), [observability.md](observability.md),
100
- [development-pipeline.md](development-pipeline.md) for where RCAs are committed.
103
+ [development-pipeline.md](../process/development-pipeline.md) for where RCAs are committed.
@@ -0,0 +1,90 @@
1
+ # Artifact Versions & Serialization Contracts
2
+
3
+ > **Visual blueprint:** The source checkout includes the complete
4
+ > [Artifact Versions & Serialization Contracts visual reference](https://github.com/iowarp/clio-coder/blob/main/docs/html/artifact_versions_blueprint.html).
5
+
6
+ This document is an operator-facing registry of compatibility-sensitive file
7
+ formats, serialized structures, integrity digests, and migration rules in the
8
+ current source tree. It is not an exhaustive inventory of every internal store
9
+ or wire frame. Source version constants and their readers remain authoritative.
10
+
11
+ ---
12
+
13
+ ## 1. Operator-facing Artifact Registry
14
+
15
+ Clio Coder gives its compatibility-sensitive persistent and network contracts an
16
+ explicit version or schema identity. This table also calls out selected
17
+ unversioned stores whose handling matters to operators. It does not enumerate
18
+ every internal contract, such as the worker wire protocol, `batches.json`
19
+ (detached batch records), code-step, agent-ledger, and route-history stores.
20
+ Depending on the artifact, an incompatible reader fails closed, skips
21
+ an invalid record, or uses an explicitly documented compatibility
22
+ normalization.
23
+
24
+ | Artifact / Subsystem | Current Version | Symbol / Type & Source Location | Persisted Path / Wire Location | Schema Semantics & Version Differences | Mismatch Handling |
25
+ | :--- | :--- | :--- | :--- | :--- | :--- |
26
+ | **Run Receipt** | `20` | `RUN_RECEIPT_INTEGRITY_VERSION = 20`<br>`src/domains/dispatch/receipt-integrity.ts:13` | `<stateDir>/receipts/<runId>.json` | Cryptographically sealed run record. Version 20 adds `pathProvenance` on dispatch intent and the resolved `pathScope`, over the v19 base of provenance fields, routing intent, quality labels, `validationGrounding`, `capabilityMismatch`, council provenance, and fleet gate provenance. | Fail-closed. A receipt below v20 is reported as retired rather than invalid, is never read as evidence, and is never migrated; a malformed or tampered v20 receipt fails verification. |
27
+ | **Dispatch Intent** | `2` | `DISPATCH_INTENT_VERSION = 2`, `DISPATCH_INTENT_SUPPORTED_VERSIONS = [2]`<br>`src/domains/dispatch/intent-compatibility.ts` | Inside the resolved dispatch plan artifact, the `JobSpec`/`DispatchRequest`, and the sealed run receipt | Typed model- and producer-declared scope: `read_roots`, `write_roots`, `relevant_paths`, `expected_outputs`, and declared-id `verification`, plus the `pathProvenance` binding every policy-bearing path to the field that declared it. Version 2 adds `pathProvenance` over the v1 path-and-output shape. | Fail-closed, never migrated. The supported set is a membership list, not a range: any other version is refused with `intent_version_unsupported` and the caller restates the fields on a fresh dispatch call. Omitted intent is accepted through the separately tracked legacy inference path; contradictory intent is a terminal refusal. See [dispatch-typed-intent.md](dispatch-typed-intent.md). |
28
+ | **Dispatch Path Scope Provenance** | `1` | `version: 1` in `interface DispatchPathScopeProvenance`<br>`src/domains/dispatch/path-scope.ts` | `pathScope` on the sealed run receipt | Resolved policy-bearing paths with per-field provenance (`declared`/`derived`/`inferred`), source, and confidence. Never carries the task or briefing prose an inferred path came from. | Sealed inside the receipt integrity digest; shares the receipt's fail-closed policy. |
29
+ | **Resolved Dispatch Plan Artifact** | `3` | `version: 3` in `interface ResolvedDispatchPlanArtifact`<br>`src/tools/dispatch-plan.ts:121` | Trusted admission-time tool argument, rendered and hashed into the plan approval | Pinned agent/target/model/node per task plus the sealed `intent` and admission-resolved `resolvedVerification`. The rendered artifact carries `intent_sha256` for a declared task and the full inferred scope table for a legacy one. | Fail-closed. Any version but 3 parses as `null`, as does any task whose present `intent` is not a normalized v2 intent; omitted intent remains the valid legacy-inference shape. The call falls back to unresolved admission rather than executing a half-understood plan. |
30
+ | **Session Ledger** | `4` | `CURRENT_SESSION_FORMAT_VERSION = 4`<br>`src/engine/session.ts:73` | `<stateDir>/sessions/<cwdHash>/<sessionId>/` (`meta.json`, `current.jsonl`, `tree.json`) | Append-only ledger format with UUIDv7 turn IDs, session header line, and tree graph linkage. Version 4 adds `contextEviction` and `contextRecall` entry kinds. | The reader accepts v3 and v4. Opening v3 restamps metadata as v4 without rewriting ledger entries; versions below 3 and versions from a newer build are refused. |
31
+ | **Worker Spec** | `3` | `WORKER_SPEC_VERSION = 3`<br>`src/worker/spec-contract.ts:23` | Subprocess `stdin` control plane JSON payload | Worker invocation parameters, tool surface profile, and execution bounds. | Fail-closed preflight rejection before worker activation. |
32
+ | **Worker Runtime Descriptor** | `2` | `WORKER_RUNTIME_DESCRIPTOR_VERSION = 2`<br>`src/worker/spec-contract.ts:24` | Nested `runtime` object in the Worker Spec | Serialized runtime id, kind, API family, auth mode, and optional aliases used to rehydrate the worker's provider runtime. Hardware and environment facts belong to the separate worker-protocol attestation. | Worker-spec parsing rejects an unsupported descriptor version or id mismatch. Rehydration rejects id, kind, API-family, or auth drift before the worker model call. |
33
+ | **Worker Protected Artifact State** | `1` | `WORKER_PROTECTED_ARTIFACT_STATE_VERSION = 1`<br>`src/worker/spec-contract.ts:25` | Worker spec initialization snapshot | Snapshot of active protected artifact paths and validation commands passed to worker. | Worker fails closed before executing mutations. |
34
+ | **Fleet Contract** | `1 \| 2 \| 3 \| 4 \| 5` (Current: `5`) | `FleetContractVersion = 1 \| 2 \| 3 \| 4 \| 5`<br>`FLEET_WRITE_BOUNDARY_VERSION = 4`<br>`FLEET_DYNAMIC_STEP_VERSION = 5`<br>`src/domains/agents/fleet-contract.ts` | Markdown recipes with YAML front matter, including `.clio-coder/fleets/<name>.md` plus built-in, enabled-extension, and user tiers | Multi-agent workflow contract. v1 is agent-only; v2 adds deterministic code steps; v3 adds bounded loops and commit steps; v4 adds declared per-step write boundaries; v5 adds plan steps, gate steps, per-step target or profile routing, and the single-writer declaration. | Reader refuses contracts whose version features it does not support. |
35
+ | **Execution Plan** | `4` | `version: 4` in `interface ExecutionPlan`<br>`src/domains/dispatch/execution-plan.ts:114` | Complete compiled DAG in memory; plan hash and provenance in receipts; selected steps and hash in the Fleet Run Record | Statically unrolled, deterministically hashed execution plan. v4 adds bounded loop nodes, verification staleness tracking, and commit nodes. | The compiler stamps version 4. There is no execution-plan deserializer or cross-version mismatch path; fleet resume validates its separate Fleet Run Record and plan hash. |
36
+ | **Eval Artifact** | `4` | `version: 4` in `interface EvalArtifactV4`<br>`src/domains/eval/schema/artifact.ts` | `<dataDir>/evals/<evalId>.json` | Stored eval results with suite provenance, matrix parameters, and itemized metric outcomes. `EVAL_TASK_FILE_VERSION = 1` versions compatibility v1 `--task-file` inputs; Suite v2 is a separate contract. | Incompatible eval artifacts are rejected during `clio-coder eval report` and `compare`. |
37
+ | **Prompt Manifest** | `2` | `PROMPT_MANIFEST_VERSION = 2`<br>`src/domains/session/prompt-manifest.ts:30` | `<stateDir>/sessions/<cwdHash>/<sessionId>/prompt-manifest.jsonl` | Per-session record of the compiled system prompt: fragment ids, relative paths, content hashes, section token estimates, and the composition hash. Version 2 is the stable-prefix-first ordering with one `# Memory` header and records `contextWindowSource` beside the window the prompt states (#249). | Additive. A record without a `version` field predates the field and reads as version 1, so a 0.3.8 manifest still parses; the version explains the single `promptRecompiled` entry a resumed session's first compile writes. |
38
+ | **Eval Verdict Envelope** | `clio-coder.eval.verdict.v1` | `EVAL_VERDICT_SCHEMA_V1`<br>`src/domains/eval/schema/verdict.ts` | Optional result sibling inside the Eval Artifact at `<dataDir>/evals/<evalId>.json` | Strict per-trial verdict identity with outcome and machinery, ledger- and receipt-sourced tracked metrics, and evidence links (#252). One pass decision: the code grader's outcome is part of `result.pass`. Distribution aggregates and serving configuration belong to the enclosing Eval Artifact. | A present malformed envelope is rejected, and behavioral results require one; an absent envelope remains valid for older non-behavioral results and is omitted from verdict comparisons. Separately, `eval compare` refuses artifact-level serving-configuration drift unless explicitly allowed. Released `clio.eval.*` identities are normalized only at the read boundary. |
39
+ | **Behavioral Scenario & Result** | `clio-coder.eval.scenario.v1`, `clio-coder.eval.behavior.v1` | `EVAL_BEHAVIOR_SCENARIO_SCHEMA_V1`, `EVAL_BEHAVIOR_SCHEMA_V1`<br>`src/domains/eval/schema/behavioral.ts` | Suite v2 task declarations; additive sibling inside the Eval Artifact | Versioned behavioral contract: bounded expected and forbidden rules across tool choice, exploration, delegation, safety comprehension, claim grounding, denied-tool recovery, completion behavior, and task correctness, with deterministic judge inputs canonicalized from transcript, tool, receipt, and grader facts (#156). References the canonical `clio-coder.eval.verdict.v1` identity. | Fail-closed. `unknown`, `unmeasured`, `behavioral_failure`, and `infrastructure_failure` stay distinct; a malformed, partial, contradictory, or cross-linked verdict cannot parse as a pass. Existing artifact readers are unaffected because the sibling is additive. Released `clio.eval.*` identities normalize only on read. |
40
+ | **Behavioral Metrics Projection** | `clio-coder.eval.behavior.metrics.v1` | `EVAL_BEHAVIOR_METRICS_SCHEMA_V1`<br>`src/domains/eval/schema/behavioral-metrics.ts` | Additive role- and target/model-bound projection inside the Eval Artifact | Sourced metric families cover correctness, safety, label violations, tool-call efficiency, unnecessary exploration, delegation quality, unsupported claims, tokens, latency, cost, and repeat variability, with coverage, min/max, p90, population variance, and standard deviation per distribution (#161). | Unmeasured observations stay typed `null` and never become zero violations. A baseline hard metric that becomes unmeasured fails the comparison closed, and `--metric` filtering cannot hide a hard failure. Released `clio.eval.*` identities normalize only on read. |
41
+ | **Execution Envelope** | `clio-coder.eval.execution-envelope.v1` | `EVAL_EXECUTION_ENVELOPE_SCHEMA_V1`<br>`src/domains/eval/schema/execution-envelope.ts` | On every new behavioral result inside the Eval Artifact | Strictly parsed binding of prompt fragment ids, versions, and content hashes, composition hash, recipe identity and content hash, target, wire model, runtime, thinking level, tool signature, autonomy, policy hashes, project-context provenance, and corpus id and version (#164). Suites declare which matrix dimensions may vary. | Fail-closed. Comparisons mark rows incomparable on any undeclared envelope drift, refuse one-sided envelopes and within-run variance, and name every prompt- or recipe-affected corpus result. Released `clio.eval.*` identities normalize only on read. |
42
+ | **Trace Database** | `1` | `TRACE_SCHEMA_VERSION = 1`<br>`src/domains/observability/trace-store.ts:26` | `<stateDir>/trace.sqlite` (`meta` table `schema_version`) | Schema version for the 7 SQLite trace mirror tables (`runs`, `phases`, `events`, `envelopes`, `gate_results`, `agent_sessions`, `processes`). | The asynchronous dispatch mirror logs `[clio-coder:trace]` and degrades without failing the parent run. Direct `clio-coder trace` readers reject an unsupported schema and exit 1. |
43
+ | **Capacity State File** | `2` | `version: 2` in `interface CapacityStateFile`<br>`src/domains/dispatch/capacity-lease.ts:56` | `<stateDir>/dispatch-admission.json` | Active capacity leases, drain status, and whole-plan reservations. The cross-process advisory lock lives in a separate `.lock` file. | Corrupted or unparseable state file causes admission to fail closed. |
44
+ | **Protected Artifact Journal** | `1` | `version: 1` in `interface PendingProtectedArtifactRecord`<br>`src/domains/session/protected-artifact-journal.ts:21` | `<stateDir>/protected-artifact-pending/<key>/<id>.json` | Write-ahead durability records for pending protected artifacts. | Leftover records reconciled during session initialization. |
45
+ | **Fleet Run Record** | `1` | `version: 1` in `interface FleetRunRecord`<br>`src/domains/dispatch/state.ts` | `<stateDir>/fleet-runs/<runId>.json` | Durable record of one fleet run: contract name, plan hash, static step ids and steps, `--var` values, replayed and settled step results, and the delegation plan hash a `kind: plan` step produced. Read by `fleet run --resume`. | Resume refuses a changed plan hash with a per-step diff and refuses differing `--var` values. |
46
+ | **Dispatch Run Ledger** | unversioned JSON array | `RunEnvelope`<br>`src/domains/dispatch/state.ts` | `<stateDir>/runs.json` | In-memory mirror of recent dispatch runs (id, agent, target, model, runtime, status, timing, receipt path, budget/briefing/steering provenance), newest-first, persisted as a settings-bounded ring (default 1000 runs). Read by the eval, evidence, CLI (`usage`), and TUI (Dispatch Board) domains, among others. | A missing file reads as empty; a non-array top-level JSON value reads as empty; malformed JSON throws. There is no per-record version field to check or reject on, since `RunEnvelope` carries none. |
47
+ | **Durable Assignment Store** | `1` | `version: 1` in `interface AssignmentStoreFile`<br>`DurableAssignmentRecord`<br>`src/domains/dispatch/assignment-store.ts` | `<stateDir>/assignments.json` | Machine-wide logical-dispatch records: assignment id, attempt ids, terminal run id, status, optional fleet verdict owner, and—while running—`processOwner {pid, processBirthToken, acquiredAt}`. The owner is cleared on a true terminal transition. | A live sibling owner keeps the row running; a genuinely dead or legacy ownerless row is reconciled. An unsupported or unreadable store is treated as empty, and malformed records are ignored. |
48
+ | **Checkout Writer Lease** | `1` | `version: 1` in `interface CheckoutWriterLeaseRecord`<br>`src/domains/dispatch/checkout-writer-lease.ts` | `<stateDir>/checkout-writer-leases/<key>.json` (key derived from the canonical checkout path) | Cross-process single-writer lease: checkout path, pid, process birth token, acquisition time. | A live sibling holder is refused with `checkout_writer_lease_held`; a dead owner is reclaimed; a malformed or unreadable record throws and fails admission closed. |
49
+ | **Out-of-turn Usage Ledger** | unversioned JSONL | `OutOfTurnUsageRow`<br>`src/domains/observability/out-of-turn-usage.ts` | `<stateDir>/usage/out-of-turn.jsonl` | One row per priced side question, handoff, prompt prewarm, or background-memory call. Each row records its `side-question`, `handoff`, `prewarm`, or `background-memory` label plus session id, repository identity, timestamp, target, attributed model, and provider usage. The ledger is a bounded ring of `MAX_OUT_OF_TURN_USAGE_ROWS = 1000`, rewritten atomically under the state-file lock. | Unparseable rows are skipped and counted by `usage report`; the session ledger is never affected. |
50
+ | **User Tasks File** | `1` | `USER_TASKS_FILE_VERSION = 1`<br>`src/domains/user-tasks/store.ts:6` | `<workspace>/.clio-coder/user-tasks.json` | Durable operator task list with monotonic `uN` ids, status, timestamps, optional notes, and optional session and board links. `nextId` must stay above every stored id. | Fails closed with `UserTasksStoreError` on corrupt JSON, an unknown version or field, an invalid task, a duplicate id, or an unsafe `nextId`; missing files initialize as an empty list. |
51
+ | **Library Pins** | unversioned YAML map | `readLibraryPins`<br>`src/domains/resources/library.ts` | `<configDir>/library-pins.yaml` | Typed ref (`skill:x`, `agent:y`, `prompt:p`, `fleet:z`) to `{sha256, sourceUrl}` for every resource `library add` or the Skills Hub installed. | Malformed YAML throws; a successfully parsed non-map reads as empty. Either a kind-qualified pin or the destination file makes an entry report installed, so a surviving pin still counts when its installed file is missing. |
52
+
53
+ ---
54
+
55
+ ## 2. Integrity Verification Contracts
56
+
57
+ ### Receipt Integrity (Version 20)
58
+
59
+ Receipt integrity authenticates that a sealed receipt matches its ledger envelope without modification. The private `computeReceiptIntegrity` helper hashes a canonical payload built from both records:
60
+
61
+ ```typescript
62
+ function computeReceiptIntegrity(
63
+ receipt: RunReceipt | RunReceiptDraft,
64
+ envelope: RunEnvelope,
65
+ legacyNaming = false,
66
+ ): RunReceiptIntegrity {
67
+ return {
68
+ version: 20,
69
+ algorithm: "sha256",
70
+ digest: sha256(canonicalJson(integrityPayload(receipt, envelope, legacyNaming))),
71
+ };
72
+ }
73
+ ```
74
+
75
+ Receipt verification checks:
76
+ 1. The quality block and integrity block have their strict current shapes, including `integrity.version === 20`. A receipt sealed at a lower version is reported as retired rather than invalid: it is intact, but is not read as evidence and is never migrated.
77
+ 2. `executionRole` and `routingIntent` parse, and an optional `routeDecision` is current.
78
+ 3. Receipt identity, route, timing, usage, cost, outcome, node, briefing, budget, and steering fields agree with the run ledger envelope.
79
+ 4. The SHA-256 of the canonical receipt-and-ledger payload matches `integrity.digest`; the reader also recognizes the released legacy contract-name spelling when recomputing an otherwise current v20 digest.
80
+
81
+ ---
82
+
83
+ ## 3. Migration Mechanics
84
+
85
+ Session format handling runs automatically when a session is opened:
86
+
87
+ 1. **Discovery**: `src/domains/session/migrations/index.ts:runMigrations` reads the recorded `sessionFormatVersion`, treating a missing field as version 1.
88
+ 2. **Readable range**: This build reads only versions 3 and 4. A version below 3 is disposable pre-1.0 state and is refused; a version above 4 belongs to a newer build and is refused with upgrade guidance.
89
+ 3. **Additive step**: Version 3 opens as version 4 because v4 only adds the `contextEviction` and `contextRecall` entry kinds. Existing `current.jsonl` and `tree.json` content is not transformed.
90
+ 4. **Metadata update**: The session metadata is restamped with `sessionFormatVersion: 4` through the session writer's normal durable path.
@@ -1,6 +1,11 @@
1
1
  # Capacity Leases & Fleet Scheduling
2
2
 
3
- This document specifies the multi-process capacity leasing protocols, node scheduling models, cross-process transaction locks, and failure recovery mechanics implemented in Clio Coder `v0.4.0`.
3
+ > **Visual blueprint:** The source checkout includes the complete
4
+ > [Capacity Leases & Fleet Scheduling visual reference](https://github.com/iowarp/clio-coder/blob/main/docs/html/capacity_scheduling_blueprint.html).
5
+
6
+ This document specifies the multi-process capacity leasing protocols, node
7
+ scheduling models, cross-process transaction locks, and failure recovery
8
+ mechanics in the current source tree.
4
9
 
5
10
  Source implementations: `src/domains/scheduling/` and `src/domains/dispatch/capacity-lease.ts`.
6
11
 
@@ -23,7 +28,7 @@ graph TD
23
28
 
24
29
  | Dimension | Identity | Limit resolution |
25
30
  | :--- | :--- | :--- |
26
- | Global | All dispatches using the state directory. | `budget.concurrency: auto` remains four. |
31
+ | Global | All dispatches using the state directory. | `fleet.concurrency: auto` remains four. |
27
32
  | Node | The local node or one configured fleet node. | The configured node limit applies. An unset local node cap remains unbounded. |
28
33
  | Inference endpoint | A normalized scheme, host, port, and base path. | A target's `maxConcurrentRequests` override wins, then a probe in this process, then a persisted probe from an earlier process, then one slot for other local-native targets. vLLM and SGLang remain unbounded. |
29
34
 
@@ -74,7 +79,7 @@ export interface CapacityStateFile {
74
79
 
75
80
  ## 2. Capacity Lease Schema & TTLs
76
81
 
77
- Each in-flight worker holds one `CapacityLease` (`src/domains/dispatch/capacity-lease.ts:18-29`):
82
+ Each in-flight worker holds one `CapacityLease` (`src/domains/dispatch/capacity-lease.ts:30-44`):
78
83
 
79
84
  ```typescript
80
85
  export interface CapacityLease {
@@ -82,6 +87,7 @@ export interface CapacityLease {
82
87
  assignmentId: string; // Owning dispatch assignment ID
83
88
  nodeId: string; // Execution node identifier ("local" or remote ID)
84
89
  endpointKey?: string; // Canonical inference endpoint identifier
90
+ host?: string; // Owner host; absent only on older records
85
91
  ownerPid: number; // Process ID of the orchestrator/worker owner
86
92
  processBirthToken: string; // OS-level token preventing PID reuse collisions
87
93
  acquiredAt: string; // ISO-8601 acquisition timestamp
@@ -94,20 +100,26 @@ export interface CapacityLease {
94
100
 
95
101
  The orchestrator's active model stream is registered in memory against the same endpoint key, so its own turn consumes one endpoint slot before a worker is admitted. This foreground count is not written to `dispatch-admission.json`; process exit releases it. Durable leases and held reservation members carry `endpointKey`, and held members count their peak per wave for the endpoint just as they do for a node.
96
102
 
97
- Execution-plan waves also honor the endpoint bound. A plan with four available worker positions targeting one two-slot server packs at most two of them into a wave, or one when the orchestrator already holds the other slot. Endpoint saturation is refused rather than queued, because an endpoint-specific request queue would hold a dispatch open behind a stream whose length nobody knows. The refusal names the endpoint, both slot counts, why one slot is already gone, and the moves that actually free capacity:
103
+ Execution-plan waves also honor the endpoint bound. A plan with four available worker positions targeting one two-slot server packs at most two of them into a wave, or one when the orchestrator already holds the other slot. Reservation preflight refuses a plan whose peak cannot fit because the scheduler must reserve the whole plan atomically. The refusal names the endpoint, both slot counts, why one slot is already gone, and the moves that actually free capacity:
98
104
 
99
105
  ```text
100
- dispatch: admission denied: endpoint '192.168.86.141:8080' capacity reached (1/1 slots): 1 foreground stream holds the slot; reduce the same-wave worker count, set this target's maxConcurrentRequests to the slot count the server was started with, collect in-flight runs, or point workers at a second server
106
+ dispatch: admission denied: endpoint '127.0.0.1:8080' capacity reached (1/1 slots): 1 foreground stream holds the slot; reduce the same-wave worker count, set this target's maxConcurrentRequests to the slot count the server was started with, collect in-flight runs, or point workers at a second server
101
107
  ```
102
108
 
103
- That remedy is shared by all three paths that can refuse for this reason: lease acquisition (`src/domains/dispatch/capacity-lease.ts`), the admission gate (`src/domains/dispatch/admission.ts`), and reservation preflight (`src/domains/dispatch/reservation-store.ts`). The `1/1` above is the common local case rather than an example: a llama.cpp router started with `--parallel 1` discovers one slot, so any dispatch raised while the orchestrator is streaming is refused before a worker process starts.
109
+ Direct lease acquisition in `src/domains/dispatch/capacity-lease.ts` reports saturation as `capacity reached`. The normal admission controller in `src/domains/dispatch/admission.ts` treats that signal as transient and leaves the assignment in its bounded shared queue, retrying until capacity opens or the request's deadline or 60-second queue ceiling wins. Capacity marked `unavailable`, drain mode, corrupt state, and other errors still fail immediately. Reservation preflight in `src/domains/dispatch/reservation-store.ts` refuses an over-capacity plan instead of queuing a partial reservation. The `1/1` example represents a generic llama.cpp server started with `--parallel 1`: a singular dispatch raised while the orchestrator is streaming waits for that slot, and a council reservation is refused before any worker starts.
110
+
111
+ The reference `mini` target is not a one-slot example. It is a llama.cpp router
112
+ at `192.168.86.141:8080` serving `ornith1.5-35b-moe` with four parallel slots
113
+ and 262,144 context tokens per slot. One foreground stream on that endpoint
114
+ leaves three slots for worker admission. The reference chat target, `dynamo`,
115
+ is LM Studio at `192.168.86.143:1234` serving `qwen3.8-27b-dynamo`.
104
116
 
105
117
  ### What `/council` Needs on a Single-GPU Setup
106
118
 
107
119
  A council seats two to five members and runs the whole roster in one wave, so it needs at least two endpoint slots at once, plus a third if the orchestrator's own turn is streaming to the same server. It cannot answer a capacity denial by dispatching fewer members, which is why its denial says so instead of offering that move:
108
120
 
109
121
  ```text
110
- dispatch: admission denied: endpoint 'mini:8080' capacity exceeded (2/1 slots): no active lease, held reservation, or foreground stream currently holds a slot; a council runs its whole roster in one wave and cannot go below 2 members, so set this target's maxConcurrentRequests to the slot count the server was started with, collect in-flight runs, or point workers at a second server
122
+ dispatch: admission denied: endpoint 'one-slot-local:8080' capacity exceeded (2/1 slots): no active lease, held reservation, or foreground stream currently holds a slot; a council runs its whole roster in one wave and cannot go below 2 members, so set this target's maxConcurrentRequests to the slot count the server was started with, collect in-flight runs, or point workers at a second server
111
123
  ```
112
124
 
113
125
  On a single-GPU box there are three ways to make `/council` work, in order of preference:
@@ -122,9 +134,9 @@ A server genuinely started with one slot cannot run a council, and admitting one
122
134
 
123
135
  | Constant | Value | Description | Source Reference |
124
136
  | :--- | :--- | :--- | :--- |
125
- | `MAX_CAPACITY_LEASES` | `1000` | Hard cap on simultaneous active capacity leases across all nodes. | `src/domains/dispatch/capacity-lease.ts:8` |
126
- | `DEFAULT_CAPACITY_LEASE_TTL_MS` | `30000` ms (30s) | Inactivity expiration window for leases without a refreshed heartbeat. | `src/domains/dispatch/capacity-lease.ts:9` |
127
- | `DEFAULT_CAPACITY_DRAIN_TTL_MS` | `3600000` ms (1h) | Automatic expiration window for operator drain mode. | `src/domains/dispatch/capacity-lease.ts:16` |
137
+ | `MAX_CAPACITY_LEASES` | `1000` | Hard cap on simultaneous active capacity leases across all nodes. | `src/domains/dispatch/capacity-lease.ts:13` |
138
+ | `DEFAULT_CAPACITY_LEASE_TTL_MS` | `30000` ms (30s) | Renewal and fallback expiry horizon when exact process identity is unavailable. A matching live process birth token keeps its lease valid beyond this timestamp. | `src/domains/dispatch/capacity-lease.ts:14` |
139
+ | `DEFAULT_CAPACITY_DRAIN_TTL_MS` | `3600000` ms (1h) | Automatic expiration window for operator drain mode. | `src/domains/dispatch/capacity-lease.ts:28` |
128
140
  | `NODE_DEATH_FAILURE_THRESHOLD` | `2` consecutive failures | Channel failure count before a remote node is classified offline. | `src/domains/scheduling/cluster.ts:64` |
129
141
 
130
142
  ---
@@ -133,9 +145,10 @@ A server genuinely started with one slot cannot run a council, and admitting one
133
145
 
134
146
  To prevent leaked leases when workers or orchestrators crash:
135
147
 
136
- 1. **Heartbeat Protocol**: Active workers emit heartbeats over their control channel every 1,000 ms (`src/worker/heartbeat.ts`). The orchestrator updates `heartbeatAt` and extends `expiresAt` by `DEFAULT_CAPACITY_LEASE_TTL_MS`.
137
- 2. **PID Liveness & Birth Tokens**: The lease reconciler inspects `ownerPid` and validates `processBirthToken` against operating system process tables. If the PID has terminated or been recycled by the OS, the lease is immediately reclaimed.
138
- 3. **Lazy Reaping**: Every admission attempt purges expired leases and dead process records inside the cross-process transaction lock before calculating available capacity.
148
+ 1. **Worker Heartbeat Protocol**: Active native workers emit control-channel heartbeats every 1,000 ms (`src/worker/heartbeat.ts`) for run liveness and stall detection.
149
+ 2. **Capacity-Lease Renewal**: Independently of worker control frames, the process-local admission controller renews every held durable lease every 10,000 ms. A renewal updates `heartbeatAt` and extends `expiresAt` by `DEFAULT_CAPACITY_LEASE_TTL_MS`.
150
+ 3. **PID Liveness & Birth Tokens**: The lease reconciler inspects `ownerPid` and validates `processBirthToken` against operating system process tables for records owned by this host. If the PID has terminated or been recycled by the OS, the lease is immediately reclaimed. A record naming another host is not adjudicated with the local process table.
151
+ 4. **Lazy Reaping**: Every admission attempt purges reclaimable leases and dead process records inside the cross-process transaction lock before calculating available capacity.
139
152
 
140
153
  ---
141
154
 
@@ -1,7 +1,7 @@
1
1
  # Context Engine
2
2
 
3
- > [!TIP]
4
- > **Interactive Spec Available:** An interactive dashboard is located at [docs/html/context_blueprint.html](html/context_blueprint.html) (Version: 0.4.0).
3
+ > **Visual blueprint:** The source checkout includes the complete
4
+ > [Context Engine visual reference](https://github.com/iowarp/clio-coder/blob/main/docs/html/context_blueprint.html).
5
5
 
6
6
  Clio Coder tracks context pressure, records per-turn snapshots, and protects the provider context with bounded tool results plus single-threshold compaction.
7
7
 
@@ -11,13 +11,13 @@ The non-destructive eviction layer has its own guide: [context-working-set.md](c
11
11
 
12
12
  ## Context window resolution
13
13
 
14
- Each target has a declared, desired, and effective context window. The effective window is the operating ceiling used by budget checks and compaction. Sources rank most-live first: the window discovery reports the model is loaded at, then a probed window, then a target override, then a model hint, catalog knowledge, a local-native default, and finally a descriptor default.
14
+ Each target has a declared, desired, and effective context window. The effective window is the operating ceiling used by budget checks and compaction. A one-run `--max-context-tokens` override wins when present. Otherwise sources rank most-live first: the window discovery reports the model is loaded at, then a probed window, a target capability override, a model hint, knowledge-base data, the built-in model catalog, a runtime descriptor default, and finally Clio's assumed fallback.
15
15
 
16
16
  The loaded window outranks the declared one because it is the only figure describing what the backend will serve. LM Studio routinely opens a model well below its `max_context_length`, and a run planned against the larger number overruns the server before compaction ever fires. Discovery carries that number per model in `discoveredModelStates[<model>].contextLength`, and the residency notice reads the same entry, so a model Clio is budgeting a loaded window for is never announced as absent.
17
17
 
18
18
  A resumed session carries the loaded window it already recorded. A resume re-resolves its target before discovery has reported what the backend has open, so the first turn used to budget against the probed figure, which on a multi-slot or multi-copy backend can be several times the real headroom, and corrected a turn later. `lastLoadedContextWindow` reads the last `loaded` window the session's own `context-snapshots.jsonl` recorded for the same target and model and hands it to resolution as `knownLoadedContextWindow`. It is used only when live discovery reports nothing, and it is scoped to that target and model, so a different selection re-probes and a model reloaded at a new size corrects as soon as discovery names the live window.
19
19
 
20
- Local-native runtimes use a recommended minimum desired window of 128,000 tokens. If the live model reports a smaller loaded context window, Clio re-resolves the target so accounting uses the actual ceiling.
20
+ Clio uses 131,072 tokens as the minimum desired window and as the fallback when no source reports one, on every runtime tier. A reported effective window below 128,000 tokens triggers the undersized-window warning. If a live model reports a smaller loaded context window, Clio re-resolves the target so accounting uses the actual ceiling.
21
21
 
22
22
  The `/context` overlay states which layer answered, next to the token total: `loaded`, `probed`, `configured`, `declared`, or `assumed`.
23
23
 
@@ -39,13 +39,13 @@ The `/context` overlay and footer meter read the same ledger categories in displ
39
39
 
40
40
  ## Single-threshold compaction
41
41
 
42
- Auto-compaction is controlled by one pressure threshold. Pressure is `budgeted_tokens / context_window`, where the budgeted figure is the reconciled total when the provider has attested one and the chars/4 estimate otherwise. The default threshold is `0.8`.
42
+ Auto-compaction is controlled by `context.compaction.threshold`. Pressure is `budgeted_tokens / context_window`, where the budgeted figure is the reconciled total when the provider has attested one and the chars/4 estimate otherwise. The default threshold is `0.8`.
43
43
 
44
44
  Crossing that threshold engages three mechanisms in a fixed order. The first two are cheap, reversible, and call no model. Only the third rewrites what the session says about itself.
45
45
 
46
46
  ### 1. Working-set eviction
47
47
 
48
- When `compaction.auto` is enabled and pressure crosses the threshold before a request, Clio applies the configured working-set policy first. The policy selects tool-result bodies and closed-turn thinking blocks, `runAutoCompact` appends one `contextEviction` ledger entry, and `refreshAgentMessagesFromSession` projects those units out of model replay behind a one-line marker. Nothing is deleted: the ledger keeps the original bodies, the transcript keeps showing them, and `/resume`, `/tree`, `/fork`, and the HTML export are unaffected.
48
+ When `context.compaction.auto` is enabled and pressure crosses the threshold before a request, Clio applies the configured working-set policy first. The policy selects tool-result bodies and closed-turn thinking blocks, `runAutoCompact` appends one `contextEviction` ledger entry, and `refreshAgentMessagesFromSession` projects those units out of model replay behind a one-line marker. Nothing is deleted: the ledger keeps the original bodies, the transcript keeps showing them, and `/resume`, `/tree`, `/fork`, and the HTML export are unaffected.
49
49
 
50
50
  Already-evicted units are never selected again. Recent turns keep their full observations and thinking, governed by `context.workingSet.protectLastTurns`. Results whose estimated body is below `context.workingSet.minEvictableTokens` (200 tokens by default) are kept whatever their age as a low-yield churn guard. The engine separately refuses any candidate whose marker would save no tokens. The `age-horizon` policy is therefore the selection the old destructive mask made minus those small results, not a byte-identical reproduction of it; the default `structural-v1` policy applies its structural rules before any age rule.
51
51
 
@@ -85,7 +85,7 @@ When the ledger is replayed to the model, compaction summaries, branch summaries
85
85
 
86
86
  Every provider Clio targets caches by exact prefix. Anthropic hashes the cumulative prefix up to a `cache_control` breakpoint and looks back at most 20 blocks for an earlier write; the minimum cacheable prefix is 512 to 4,096 tokens by model, reads cost 0.1x input and writes 1.25x. OpenAI caches automatically from 1,024 tokens in 128-token increments on exact prefix matches at 0.1x. vLLM hashes each KV block from its parent block's hash, so a change in one block invalidates every later block. llama.cpp (and LM Studio on top of it) picks the slot with the longest common prefix and re-evaluates only the suffix, and `--cache-reuse` can shift later KV chunks back into place after a mid-prompt removal. The consequence is the same everywhere except on llama.cpp with cache reuse: whatever bytes change, everything after the earliest changed position is re-prefilled. That is why a marker is byte-stable, why a recall rides the tail instead of restoring the body in place, why `structural-v1` batches evictions down to `target` instead of trimming on every turn, and why the replay tables report cold prefix tokens per event next to tokens evicted: at a 32k budget one event re-prefills most of the window whichever policy chose the items, so the lever that protects a cloud cache is the number of events, not their contents. A local backend with cache reuse pays less for the same removal, which is where finer-grained eviction and recall earn their keep.
87
87
 
88
- The procedural replay target sweep measured 0.4, 0.5, 0.6, and an exhaustive rung-6 stop over 24 traces. Target 0.4 and exhaustive selection converged because un-evictable residue exhausted the candidate pool. Against 0.6, target 0.4 cut cold-prefix tokens by 2.8% at 64k and 7.3% at 128k, with no summary reduction and a 0.00072 reduction in retention covered at 128k. That is below the 10% cache-saving threshold set for changing a cross-tier default, so the default remains 0.6. The complete sweep and reopening rule are in the replay README.
88
+ A historical local replay target sweep measured 0.4, 0.5, 0.6, and an exhaustive rung-6 stop over 24 traces. Target 0.4 and exhaustive selection converged because un-evictable residue exhausted the candidate pool. Against 0.6, target 0.4 cut cold-prefix tokens by 2.8% at 64k and 7.3% at 128k, with no summary reduction and a 0.00072 reduction in retention covered at 128k. That was below the 10% cache-saving threshold used for the experiment, so the default remained 0.6. The generated tables and reopening calculation were local artifacts and are not versioned in this repository; use the replay commands in [Commands and Modes](../guide/commands-and-modes.md#working-set-replay) to measure the current tree.
89
89
 
90
90
  The same arithmetic governs the compiled system prompt, which sits ahead of every message. Its sections are ordered stable prefix first, so a section that can change between two turns never sits ahead of one that cannot; the order and the rule behind it are in [prompt-envelope-and-tools.md](prompt-envelope-and-tools.md#section-order-stable-prefix-first).
91
91
 
@@ -139,9 +139,9 @@ Clio sends it at three moments: after the session prompt compiles at session sta
139
139
 
140
140
  The payload is the request the next turn would send minus the operator's text: the same system prompt, the same tool schemas, the same replayed messages, the same thinking level, and the same `cache_prompt`, with one single-character user message appended so the chat template renders the prefix up to the user turn, and `max_tokens: 1`. It is built through the same `streamSimple` dispatcher `createEngineAgent` hands the engine as its `streamFn`, not a hand-assembled payload, because any byte that differs ahead of the user turn defeats the purpose.
141
141
 
142
- The pre-warm is refused rather than queued whenever it would compete with real work. It runs only on `local-native` targets, whatever `prewarm.enabled` says, because a cloud provider bills the request and caches on its own schedule. It never runs while a turn is in flight, while any dispatch is outstanding, on a worker, or in headless `run`. The dispatch guard is a stand-in: without per-endpoint capacity accounting the pre-warm cannot tell whether a worker already occupies the server it would warm, so it stands down for all worker traffic. The round already claims one endpoint slot for as long as its request is out and releases it in a `finally`, through the `registerEndpointSlot` seam the chat loop wires from the endpoint-capacity registry, so capacity counts a pre-warm the same way it counts the orchestrator's streaming turn.
142
+ The pre-warm is refused rather than queued whenever it would compete with real work. It runs only on `local-native` targets, whatever `chat.prewarm` says, because a cloud provider bills the request and caches on its own schedule. It never runs while a turn is in flight, while any dispatch is outstanding, on a worker, or in headless `run`. The dispatch guard is a stand-in: without per-endpoint capacity accounting the pre-warm cannot tell whether a worker already occupies the server it would warm, so it stands down for all worker traffic. The round already claims one endpoint slot for as long as its request is out and releases it in a `finally`, through the `registerEndpointSlot` seam the chat loop wires from the endpoint-capacity registry, so capacity counts a pre-warm the same way it counts the orchestrator's streaming turn.
143
143
 
144
- Pressing Enter lets go of an in-flight pre-warm at the keystroke, before the admission gate. Whether it also aborts the HTTP request is gated on what the backend does with a cancelled one, and the measured backend does nothing. On the operator's llama.cpp router (build `b226-2115b73d8`, Qwen3.8-27B, `--parallel 1`), aborting 1.5 s into a 47,620-token prefill did not cancel the server's work: the server finished prefilling, so the prefix did survive the abort and the next request read 47,596 of 47,620 tokens from cache with `prompt_ms 927`, but that request also waited 89.5 s of wall clock for the abandoned one to leave the single slot. Letting the pre-warm complete instead cost 89.3 s plus a 1.3 s turn, the same wall clock. The abort therefore frees no slot and saves no time on this backend; all it does is discard the usage and timings of prefill the server performed. So a submit detaches the round instead: Clio stops calling it the current pre-warm, never waits on it, withholds its `/context` line because it no longer describes the prefix the next turn will send, and still records what it cost. `ABORT_ROUND_ON_SUBMIT` in `src/interactive/turn-prewarm.ts` carries the measurement and flips the behavior for a backend that honors cancellation.
144
+ Pressing Enter lets go of an in-flight pre-warm at the keystroke, before the admission gate. Whether it also aborts the HTTP request is gated on what the backend does with a cancelled one, and the backend used for the original experiment did nothing. On an earlier single-slot llama.cpp deployment (build `b226-2115b73d8`, Qwen3.8-27B, `--parallel 1`), aborting 1.5 s into a 47,620-token prefill did not cancel the server's work: the server finished prefilling, so the prefix did survive the abort and the next request read 47,596 of 47,620 tokens from cache with `prompt_ms 927`, but that request also waited 89.5 s of wall clock for the abandoned one to leave the single slot. Letting the pre-warm complete instead cost 89.3 s plus a 1.3 s turn, the same wall clock. The abort therefore freed no slot and saved no time on that backend; all it did was discard the usage and timings of prefill the server performed. The current operator topology is different: `mini` is a llama.cpp router at `192.168.86.141:8080` serving `ornith1.5-35b-moe` with four parallel slots and 262,144 context tokens per slot, while `dynamo` is LM Studio at `192.168.86.143:1234` serving `qwen3.8-27b-dynamo` for chat. The cancellation result must be remeasured before it is generalized to either deployment. A submit currently detaches the round: Clio stops calling it the current pre-warm, never waits on it, withholds its `/context` line because it no longer describes the prefix the next turn will send, and still records what it cost. `ABORT_ROUND_ON_SUBMIT` in `src/interactive/turn-prewarm.ts` carries the historical measurement and flips the behavior for a backend that honors cancellation.
145
145
 
146
146
  Each round appends one `prewarm` custom ledger entry carrying its trigger, the backend prompt tokens, `timing`, and `promptCache`. The entry is never rendered and never becomes a model message, so it contributes zero tokens to the context estimate. `/context` shows `prewarmed: N tokens in X ms` until the next settled run answers the question it asked. `prewarm` is never an expected-cold reason: a pre-warm is the opposite of a disturbance. Its provider usage is real spend and is reported to `/cost` and `clio-coder usage report` under its own row, the way a `/btw` side question is.
147
147
 
@@ -150,12 +150,8 @@ Each round appends one `prewarm` custom ledger entry carrying its trigger, the b
150
150
  The public settings use one compaction threshold plus a non-destructive working-set stage:
151
151
 
152
152
  ```yaml
153
- compaction:
154
- auto: true
155
- threshold: 0.8
156
- excludeLastTurns: 6
157
- # model: provider/summary-model-id
158
- # systemPrompt: ~/.config/clio-coder/prompts/compaction.md
153
+ chat:
154
+ prewarm: true
159
155
 
160
156
  context:
161
157
  workingSet:
@@ -164,12 +160,14 @@ context:
164
160
  target: 0.6
165
161
  protectLastTurns: 6
166
162
  minEvictableTokens: 200
167
-
168
- prewarm:
169
- enabled: true
163
+ compaction:
164
+ auto: true
165
+ threshold: 0.8
166
+ # model: provider/summary-model-id
167
+ # systemPrompt: ~/.config/clio-coder/prompts/compaction.md
170
168
  ```
171
169
 
172
- `compaction.auto` controls the pre-request trigger. Manual `/context compact` still runs when `auto` is false. `compaction.model` optionally selects a dedicated summarization model, and `compaction.systemPrompt` optionally points at a prompt override file. `compaction.excludeLastTurns` only governs the temporary legacy mask path; working-set protection uses `context.workingSet.protectLastTurns`.
170
+ `context.compaction.auto` controls the pre-request trigger. Manual `/context compact` still runs when `auto` is false. `context.compaction.model` optionally selects a dedicated summarization model, and `context.compaction.systemPrompt` optionally points at a prompt override file. The retired `compaction.excludeLastTurns` key is not part of settings v2. The temporary legacy mask uses its compiled six-turn fallback, while working-set protection uses `context.workingSet.protectLastTurns`.
173
171
 
174
172
  | Key | Default | Accepted | Meaning |
175
173
  | --- | --- | --- | --- |
@@ -300,11 +298,13 @@ owns each entry's status and rewrites the file after every page, so a run that
300
298
  ends early records exactly which pages are still owed. Staging survives such a
301
299
  run and the next one resumes from it.
302
300
 
303
- Every page opens with front matter carrying `title`, `summary`, `sources`,
304
- `symbols`, `tests`, `invariants`, and `validate`. That is the retrieval layer:
305
- `quickstart.md`, every directory `index.md`, and the task-routing table are
306
- generated from it after each run, so navigation cannot drift or miss a page and
307
- no writer has to remember to update it.
301
+ Every page opens with repaired front matter. Its metadata model has `title`,
302
+ `summary`, `sources`, `symbols`, `tests`, `invariants`, and `validate`, but the
303
+ serializer always writes only `title`, adds `summary` when non-empty, and omits
304
+ empty list fields. That metadata is the retrieval layer: `quickstart.md`, every
305
+ directory `index.md`, and the task-routing table are generated from the repaired
306
+ values after each run, so navigation cannot drift or miss a page and no writer
307
+ has to remember to update it.
308
308
 
309
309
  Assembly repairs rather than rejects. A missing H1, absent or malformed front
310
310
  matter, a dangling `sources` entry, a link to a page that was never written, and
@@ -372,5 +372,5 @@ version, project language, file/config/symbol/edge counts, language and role
372
372
  counts, top areas, entry points, key symbols, and dependency samples. The
373
373
  welcome dashboard shows module count, wiki page count and freshness, and a
374
374
  small entry-point excerpt from the same digest. Agents query the structural
375
- layer through the read-only `code_nav` tool. See [tool-usage.md](tool-usage.md)
375
+ layer through the read-only `code_nav` tool. See [tool-usage.md](../guide/tool-usage.md)
376
376
  for the full mode reference.