@iowarp/clio-coder 0.3.0 → 0.3.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 (1187) hide show
  1. package/CHANGELOG.md +123 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +295 -627
  4. package/dist/acp-BIYHVZIM.js +128 -0
  5. package/dist/{agents-Q4MYPMUW.js → agents-YT6SSRIT.js} +52 -27
  6. package/dist/assets/codewiki.json +1 -0
  7. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
  8. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
  9. package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
  10. package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
  11. package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
  12. package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
  13. package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
  14. package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
  15. package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
  16. package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
  17. package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
  18. package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
  19. package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
  20. package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
  21. package/dist/assets/grammars/tree-sitter.wasm +0 -0
  22. package/dist/{auth-O6HYIJ6J.js → auth-5TWEIYDN.js} +30 -15
  23. package/dist/chunk-2EHAIA3X.js +481 -0
  24. package/dist/{chunk-ME6DNWIU.js → chunk-2IR2NMPA.js} +12 -4
  25. package/dist/chunk-2SFS6XQE.js +122 -0
  26. package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
  27. package/dist/chunk-2VTFPG5O.js +48 -0
  28. package/dist/chunk-3I7MS7N2.js +40 -0
  29. package/dist/chunk-3R73A4XB.js +69 -0
  30. package/dist/{chunk-JPOWPFCU.js → chunk-3ZXDFGR5.js} +52 -23
  31. package/dist/chunk-4BJ5BYCE.js +61 -0
  32. package/dist/{chunk-26BZQOAD.js → chunk-4BPJXDWC.js} +161 -260
  33. package/dist/chunk-4KLWL3UC.js +18 -0
  34. package/dist/{chunk-5LDRNKX2.js → chunk-4VP4KH3K.js} +161 -262
  35. package/dist/chunk-4ZG3XFUR.js +77 -0
  36. package/dist/chunk-5B2AEOW5.js +5407 -0
  37. package/dist/chunk-5TSRNF4G.js +510 -0
  38. package/dist/{chunk-WD6AJM35.js → chunk-5UUP6MWO.js} +48 -69
  39. package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
  40. package/dist/chunk-65DEGPJ6.js +52 -0
  41. package/dist/chunk-6EJMN2Y3.js +17 -0
  42. package/dist/chunk-6EJV5X2W.js +16405 -0
  43. package/dist/chunk-6N5PTWMY.js +136 -0
  44. package/dist/chunk-6XLNIQDB.js +27 -0
  45. package/dist/{chunk-XNISANGE.js → chunk-77VKQEHF.js} +171 -74
  46. package/dist/chunk-7CR24IG7.js +242 -0
  47. package/dist/{chunk-UWIJNAOB.js → chunk-7EYHLWU7.js} +907 -638
  48. package/dist/chunk-7MNJORFF.js +22 -0
  49. package/dist/{chunk-JWHCJDCI.js → chunk-A3CYT5EX.js} +257 -79
  50. package/dist/chunk-AGYYIBLL.js +1069 -0
  51. package/dist/chunk-AO4RKG4M.js +277 -0
  52. package/dist/chunk-APJ265NV.js +7410 -0
  53. package/dist/chunk-ARBGF5F7.js +174 -0
  54. package/dist/{chunk-TFSSEXL6.js → chunk-BMEMKKIT.js} +14 -4
  55. package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
  56. package/dist/chunk-CBCAPZAA.js +229 -0
  57. package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
  58. package/dist/chunk-CMZWFGD2.js +352 -0
  59. package/dist/chunk-ECH6PKUQ.js +39 -0
  60. package/dist/{chunk-67MTHP2E.js → chunk-ED4KHGC3.js} +13 -5
  61. package/dist/chunk-EKMEHE4H.js +340 -0
  62. package/dist/{chunk-O4EJEDHO.js → chunk-EPVUXGXG.js} +50 -35
  63. package/dist/chunk-FCSXB6T2.js +338 -0
  64. package/dist/chunk-FJ3H4MN5.js +48 -0
  65. package/dist/chunk-FQ4SKYE4.js +29 -0
  66. package/dist/chunk-G2DE3C7R.js +644 -0
  67. package/dist/chunk-G4BMMOKF.js +182 -0
  68. package/dist/{chunk-7BHLZB3A.js → chunk-GGXXDWE4.js} +190 -1218
  69. package/dist/chunk-HC4CLZ2Y.js +68 -0
  70. package/dist/{chunk-E3NYWENM.js → chunk-HFSBBKSQ.js} +55 -61
  71. package/dist/chunk-HKIYEGME.js +30 -0
  72. package/dist/chunk-I4HZDVNP.js +73 -0
  73. package/dist/chunk-IGLFWIYI.js +161 -0
  74. package/dist/chunk-IHXBNWMM.js +137 -0
  75. package/dist/chunk-IKCO5N3L.js +162 -0
  76. package/dist/chunk-IR4CFBFN.js +56 -0
  77. package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
  78. package/dist/{chunk-VOO7NYPP.js → chunk-J5HN4RYU.js} +27 -9
  79. package/dist/{chunk-4UQA7NCT.js → chunk-J5Q24KAG.js} +7 -2
  80. package/dist/{chunk-KBR4MZZR.js → chunk-JVCV3ICN.js} +7 -1
  81. package/dist/chunk-KJ5LWLOE.js +1077 -0
  82. package/dist/chunk-LBMZMYH2.js +285 -0
  83. package/dist/{chunk-3DANZDGR.js → chunk-LBNRH5WM.js} +100 -161
  84. package/dist/{chunk-TKHQ4DGZ.js → chunk-LZSJBIVT.js} +7358 -7414
  85. package/dist/{chunk-UGYAX5YI.js → chunk-M6SHUN7Q.js} +13 -8
  86. package/dist/chunk-MAW544W2.js +1882 -0
  87. package/dist/chunk-MBS4V7ZP.js +217 -0
  88. package/dist/{chunk-2J63S4SF.js → chunk-MFFY33HR.js} +167 -140
  89. package/dist/chunk-MNA4JGU4.js +255 -0
  90. package/dist/chunk-MQSRRFWA.js +3428 -0
  91. package/dist/{chunk-RQDWMVRB.js → chunk-MVVUPGPW.js} +138 -137
  92. package/dist/chunk-OAO4GE4M.js +619 -0
  93. package/dist/chunk-OHHN2SO4.js +5135 -0
  94. package/dist/chunk-OKGUZO2U.js +34 -0
  95. package/dist/{chunk-BBUH4VAA.js → chunk-OOJYHWRB.js} +60 -361
  96. package/dist/{chunk-D5YD55AR.js → chunk-OQ33BKR3.js} +12 -1
  97. package/dist/chunk-OQE5J4C6.js +73 -0
  98. package/dist/{chunk-AMFR5YA3.js → chunk-ORBHGJC5.js} +26 -12
  99. package/dist/chunk-POHLU5DW.js +1186 -0
  100. package/dist/chunk-QKMUKYO7.js +4961 -0
  101. package/dist/{chunk-7RBKDI66.js → chunk-QTYWRVRA.js} +104 -12
  102. package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
  103. package/dist/chunk-SRF2PJNW.js +184 -0
  104. package/dist/chunk-SST6Z5JA.js +80 -0
  105. package/dist/{chunk-XV4ZJ6ZM.js → chunk-STBPMHSX.js} +473 -1194
  106. package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
  107. package/dist/chunk-T6YILFSB.js +80 -0
  108. package/dist/chunk-TXOTCRLG.js +15 -0
  109. package/dist/chunk-TZTZS7QK.js +227 -0
  110. package/dist/chunk-UOV2BYIW.js +107 -0
  111. package/dist/{chunk-527KG6XR.js → chunk-V4RXGQ5Q.js} +72 -185
  112. package/dist/chunk-VAKQQHWR.js +434 -0
  113. package/dist/chunk-VG7TBQIY.js +128 -0
  114. package/dist/chunk-VJWL6YS5.js +244 -0
  115. package/dist/chunk-WEH5XRJQ.js +32 -0
  116. package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
  117. package/dist/chunk-WMSVI4G2.js +2095 -0
  118. package/dist/chunk-WVO7V2QY.js +797 -0
  119. package/dist/chunk-X4RCMKVQ.js +641 -0
  120. package/dist/chunk-X75S7HFS.js +374 -0
  121. package/dist/chunk-XN3L4EYL.js +46 -0
  122. package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
  123. package/dist/{chunk-PIDUD6M2.js → chunk-YCWGATWI.js} +12 -5
  124. package/dist/chunk-YHZX5GEU.js +193 -0
  125. package/dist/chunk-YXLYO42X.js +91 -0
  126. package/dist/{chunk-UHTSULZS.js → chunk-ZDOOVTXZ.js} +38 -73
  127. package/dist/chunk-ZI647VB5.js +37 -0
  128. package/dist/{chunk-CLJ5HLUD.js → chunk-ZWLZP4ZT.js} +25 -6
  129. package/dist/cli/index.js +70 -56
  130. package/dist/clio-4LY5K2AC.js +25 -0
  131. package/dist/code-nav-7AX6FYE6.js +600 -0
  132. package/dist/codewiki/build-worker.js +66 -0
  133. package/dist/compile-cache-CVJMMODC.js +18 -0
  134. package/dist/{components-JVHMUBEB.js → components-KELWS457.js} +31 -9
  135. package/dist/{config-ZFCDBMDC.js → config-GTLUW2PR.js} +104 -56
  136. package/dist/configure-R6A64DHX.js +42 -0
  137. package/dist/context-5VKGUVJJ.js +866 -0
  138. package/dist/{context-CDXTP2MP.js → context-JFZEJ7W5.js} +21 -13
  139. package/dist/{context-E3KIFVXI.js → context-RW5HC47S.js} +77 -36
  140. package/dist/{context-clear-3F4PLXOS.js → context-clear-6ZHBAZZT.js} +64 -30
  141. package/dist/{context-index-Q7YSYTR3.js → context-index-BZ4UYMTC.js} +36 -24
  142. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  143. package/dist/{docs-YIETIWZI.js → docs-2C2LTVT2.js} +32 -13
  144. package/dist/doctor-KI767GSN.js +87 -0
  145. package/dist/{eval-B3KZZESM.js → eval-XSSNATB4.js} +93 -27
  146. package/dist/{evidence-V67CHM35.js → evidence-UA6AWDQQ.js} +55 -27
  147. package/dist/{evolve-YDZSUQYA.js → evolve-QNTFGV6Z.js} +59 -26
  148. package/dist/{extensions-SRG7XCAH.js → extensions-QVDOHDGJ.js} +23 -8
  149. package/dist/{fleet-CA2CRTVG.js → fleet-Q7UOMUSG.js} +173 -56
  150. package/dist/fleet-preflight-DDN536IT.js +26 -0
  151. package/dist/{init-2OZDJE2D.js → init-WBB65ZHQ.js} +79 -34
  152. package/dist/{memory-3PIQQAKX.js → memory-MD3O64RI.js} +57 -28
  153. package/dist/{models-DY35XI7Y.js → models-BZU34YWD.js} +49 -24
  154. package/dist/monitor-MEQA5C3I.js +661 -0
  155. package/dist/{chunk-PS4PFJQP.js → orchestrator-CGFKEP27.js} +22837 -18564
  156. package/dist/{paths-5OMXW7Z4.js → paths-UXLN5YYZ.js} +17 -6
  157. package/dist/preload-P6DGH2PZ.js +13 -0
  158. package/dist/{reset-PIFYNOS3.js → reset-L2FQEE3E.js} +25 -13
  159. package/dist/{run-3VSPP24F.js → run-IV4Q6RLN.js} +115 -63
  160. package/dist/{share-D36RQCXM.js → share-S5BZQC5I.js} +23 -10
  161. package/dist/{skills-F2MRLELY.js → skills-LQEKRDTN.js} +42 -15
  162. package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-3DC4HEWS.js} +90 -45
  163. package/dist/steer-GGWFUJUD.js +77 -0
  164. package/dist/{targets-DZMEZAH4.js → targets-C4SSGQOB.js} +78 -60
  165. package/dist/terminal-lease-IT5JW2NR.js +395 -0
  166. package/dist/{trace-7NYCUI2J.js → trace-PNCASAXC.js} +48 -17
  167. package/dist/tree-sitter-HGKH6LG4.js +4673 -0
  168. package/dist/{uninstall-AD3JWHBB.js → uninstall-FZCQCDKC.js} +19 -8
  169. package/dist/{upgrade-WYYBKGDY.js → upgrade-7TT7SQ3G.js} +66 -24
  170. package/dist/{usage-ULIDAGFF.js → usage-GV4PKT3M.js} +71 -32
  171. package/dist/verify-G6V4D2G7.js +716 -0
  172. package/dist/version-KGEG7EPO.js +21 -0
  173. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  174. package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-DQF6Z66B.js} +98 -48
  175. package/dist/worker/entry.js +297 -54
  176. package/dist/workspace-G4ZWUIPR.js +22 -0
  177. package/docs/README.md +29 -21
  178. package/docs/acp.md +191 -16
  179. package/docs/alcf-provider.md +1 -1
  180. package/docs/architecture.md +157 -7
  181. package/docs/artifact-placement.md +101 -0
  182. package/docs/artifact-versions.md +1 -1
  183. package/docs/built-in-agents.md +4 -2
  184. package/docs/capacity-and-scheduling.md +1 -1
  185. package/docs/commands-and-modes.md +224 -97
  186. package/docs/config-knobs-audit.md +1 -3
  187. package/docs/configuration-and-targets.md +236 -38
  188. package/docs/context-engine.md +34 -7
  189. package/docs/development-pipeline.md +102 -0
  190. package/docs/dispatch-architecture-rationale.md +1 -1
  191. package/docs/documentation-coverage.md +4 -4
  192. package/docs/documentation-guide.md +3 -3
  193. package/docs/environment-variables.md +15 -6
  194. package/docs/eval-runner.md +3 -3
  195. package/docs/evals-internal.md +2 -2
  196. package/docs/evidence-and-memory.md +10 -2
  197. package/docs/evolution.md +2 -2
  198. package/docs/exit-codes-and-output.md +15 -9
  199. package/docs/extensions-and-sharing.md +25 -18
  200. package/docs/fleet-demo-runbook.md +22 -23
  201. package/docs/fleet-dispatch.md +117 -16
  202. package/docs/git-commit-provenance.md +120 -0
  203. package/docs/glossary.md +107 -15
  204. package/docs/installation-and-lifecycle.md +75 -17
  205. package/docs/middleware-and-components.md +1 -1
  206. package/docs/model-catalog.md +46 -15
  207. package/docs/observability.md +8 -5
  208. package/docs/performance-methodology.md +491 -0
  209. package/docs/pi-boundary.md +72 -0
  210. package/docs/proactive-memory.md +14 -14
  211. package/docs/prompt-envelope-and-tools.md +25 -4
  212. package/docs/provider-adapter-cookbook.md +57 -4
  213. package/docs/release-cut-checklist.md +129 -111
  214. package/docs/safety-model.md +28 -8
  215. package/docs/scientific-validation.md +3 -3
  216. package/docs/session-lifecycle.md +55 -12
  217. package/docs/skills-marketplace.md +12 -8
  218. package/docs/time-conventions.md +101 -0
  219. package/docs/tool-usage.md +6 -5
  220. package/docs/trace-store.md +1 -1
  221. package/docs/troubleshooting.md +10 -7
  222. package/docs/tui-design.md +121 -28
  223. package/docs/worker-dispatch-mechanics.md +3 -3
  224. package/package.json +33 -36
  225. package/skills/README.md +5 -6
  226. package/skills/coding/ast-grep/SKILL.md +136 -0
  227. package/skills/coding/ast-grep/evals.md +56 -0
  228. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  229. package/skills/coding/coding-standards/SKILL.md +113 -0
  230. package/skills/coding/coding-standards/evals.md +34 -0
  231. package/skills/coding/prototype/SKILL.md +86 -0
  232. package/skills/coding/prototype/evals.md +42 -0
  233. package/skills/coding/prototype/references/LOGIC.md +67 -0
  234. package/skills/coding/prototype/references/UI.md +112 -0
  235. package/skills/coding/tdd/SKILL.md +101 -0
  236. package/skills/coding/tdd/evals.md +41 -0
  237. package/skills/coding/tdd/references/mocking.md +59 -0
  238. package/skills/coding/tdd/references/tests.md +77 -0
  239. package/skills/context/context-handoff/SKILL.md +126 -0
  240. package/skills/context/context-handoff/evals.md +57 -0
  241. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  242. package/skills/context/context-prime/SKILL.md +95 -0
  243. package/skills/context/context-prime/evals.md +54 -0
  244. package/skills/git/file-ticket/SKILL.md +107 -0
  245. package/skills/git/file-ticket/evals.md +54 -0
  246. package/skills/git/fix-issue/SKILL.md +106 -0
  247. package/skills/git/fix-issue/evals.md +71 -0
  248. package/skills/git/ship/SKILL.md +92 -0
  249. package/skills/git/ship/evals.md +72 -0
  250. package/skills/meta/clio-dev/SKILL.md +91 -0
  251. package/skills/meta/clio-dev/evals.md +45 -0
  252. package/skills/meta/clio-test/SKILL.md +130 -0
  253. package/skills/meta/clio-test/evals.md +43 -0
  254. package/skills/meta/clio-test/references/harness.md +97 -0
  255. package/skills/meta/clio-test/references/test-map.md +59 -0
  256. package/skills/meta/credentials/SKILL.md +125 -0
  257. package/skills/meta/credentials/evals.md +104 -0
  258. package/skills/meta/find-skills/SKILL.md +72 -0
  259. package/skills/meta/find-skills/evals.md +47 -0
  260. package/skills/meta/herdr/SKILL.md +127 -0
  261. package/skills/meta/herdr/evals.md +38 -0
  262. package/skills/meta/skill-craft/SKILL.md +102 -0
  263. package/skills/meta/skill-craft/evals.md +41 -0
  264. package/skills/planning/architecture/SKILL.md +129 -0
  265. package/skills/planning/architecture/evals.md +36 -0
  266. package/skills/planning/backlog/SKILL.md +90 -0
  267. package/skills/planning/backlog/evals.md +43 -0
  268. package/skills/planning/prd/SKILL.md +82 -0
  269. package/skills/planning/prd/evals.md +49 -0
  270. package/skills/planning/product-intent/SKILL.md +112 -0
  271. package/skills/planning/product-intent/evals.md +36 -0
  272. package/skills/planning/tech-spec/SKILL.md +115 -0
  273. package/skills/planning/tech-spec/evals.md +47 -0
  274. package/skills/registry.yaml +136 -0
  275. package/skills/research/arxiv-literature/SKILL.md +104 -0
  276. package/skills/research/arxiv-literature/evals.md +58 -0
  277. package/skills/research/experiment-protocol/SKILL.md +122 -0
  278. package/skills/research/experiment-protocol/evals.md +91 -0
  279. package/skills/research/scientific-debugging/SKILL.md +119 -0
  280. package/skills/research/scientific-debugging/evals.md +138 -0
  281. package/skills/research/scientific-modernization/SKILL.md +138 -0
  282. package/skills/research/scientific-modernization/evals.md +84 -0
  283. package/skills/skill-marketplace.json +12 -20
  284. package/skills/workflow/design-council/SKILL.md +139 -0
  285. package/skills/workflow/design-council/evals.md +97 -0
  286. package/skills/workflow/grill-me/SKILL.md +186 -0
  287. package/skills/workflow/grill-me/evals.md +78 -0
  288. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  289. package/skills/workflow/workflow-distiller/evals.md +107 -0
  290. package/src/cli/acp.ts +115 -0
  291. package/src/cli/agents.ts +60 -0
  292. package/src/cli/args.ts +280 -0
  293. package/src/cli/argv.ts +170 -0
  294. package/src/cli/ask.ts +34 -0
  295. package/src/cli/auth.ts +468 -0
  296. package/src/cli/bootstrap-generate.ts +498 -0
  297. package/src/cli/clio.ts +96 -0
  298. package/src/cli/components.ts +195 -0
  299. package/src/cli/config-inspect.ts +336 -0
  300. package/src/cli/config.ts +72 -0
  301. package/src/cli/configure-interop.ts +67 -0
  302. package/src/cli/configure-layout.ts +172 -0
  303. package/src/cli/configure.ts +1525 -0
  304. package/src/cli/context-clear.ts +76 -0
  305. package/src/cli/context-index.ts +100 -0
  306. package/src/cli/context.ts +321 -0
  307. package/src/cli/default-target.ts +55 -0
  308. package/src/cli/docs.ts +346 -0
  309. package/src/cli/doctor.ts +54 -0
  310. package/src/cli/eval.ts +315 -0
  311. package/src/cli/evidence.ts +225 -0
  312. package/src/cli/evolve.ts +219 -0
  313. package/src/cli/extensions.ts +214 -0
  314. package/src/cli/fleet.ts +868 -0
  315. package/src/cli/index.ts +338 -0
  316. package/src/cli/init.ts +219 -0
  317. package/src/cli/initial-message.ts +47 -0
  318. package/src/cli/internal-dispatch.ts +55 -0
  319. package/src/cli/memory.ts +182 -0
  320. package/src/cli/models.ts +257 -0
  321. package/src/cli/modes/json-stream.ts +121 -0
  322. package/src/cli/modes/jsonl.ts +9 -0
  323. package/src/cli/modes/print.ts +604 -0
  324. package/src/cli/oauth-manual-input.ts +72 -0
  325. package/src/cli/oauth-select.ts +36 -0
  326. package/src/cli/output-guard.ts +48 -0
  327. package/src/cli/paths.ts +44 -0
  328. package/src/cli/provider-target.ts +113 -0
  329. package/src/cli/removal.ts +72 -0
  330. package/src/cli/reset.ts +253 -0
  331. package/src/cli/run.ts +497 -0
  332. package/src/cli/share.ts +243 -0
  333. package/src/cli/shared.ts +60 -0
  334. package/src/cli/skills-eval.ts +1240 -0
  335. package/src/cli/skills.ts +485 -0
  336. package/src/cli/steer-channel.ts +86 -0
  337. package/src/cli/targets.ts +1154 -0
  338. package/src/cli/text-layout.ts +112 -0
  339. package/src/cli/trace.ts +322 -0
  340. package/src/cli/uninstall.ts +405 -0
  341. package/src/cli/upgrade.ts +286 -0
  342. package/src/cli/usage.ts +876 -0
  343. package/src/cli/validate-model.ts +28 -0
  344. package/src/cli/version.ts +7 -0
  345. package/src/cli/wiki-generate.ts +510 -0
  346. package/src/core/agent-environment.ts +7 -0
  347. package/src/core/artifact-paths.ts +43 -0
  348. package/src/core/bash-exec.ts +313 -0
  349. package/src/core/boot-trace.ts +42 -0
  350. package/src/core/bus-events.ts +744 -0
  351. package/src/core/bus-trace.ts +53 -0
  352. package/src/core/c-header-language.ts +265 -0
  353. package/src/core/clio-repo.ts +78 -0
  354. package/src/core/commit-attribution.ts +157 -0
  355. package/src/core/compile-cache.ts +159 -0
  356. package/src/core/config.ts +1722 -0
  357. package/src/core/context-floor.ts +33 -0
  358. package/src/core/defaults.ts +659 -0
  359. package/src/core/domain-loader.ts +177 -0
  360. package/src/core/event-bus.ts +94 -0
  361. package/src/core/file-references.ts +282 -0
  362. package/src/core/git-commit-attribution.ts +362 -0
  363. package/src/core/guardrails.ts +185 -0
  364. package/src/core/headless-permission.ts +21 -0
  365. package/src/core/incomplete-installation.ts +45 -0
  366. package/src/core/init.ts +223 -0
  367. package/src/core/json-payload.ts +58 -0
  368. package/src/core/package-root.ts +54 -0
  369. package/src/core/path-canonical.ts +37 -0
  370. package/src/core/process-identity.ts +41 -0
  371. package/src/core/recent-models.ts +91 -0
  372. package/src/core/residency-protection.ts +56 -0
  373. package/src/core/resolve-config-value.ts +88 -0
  374. package/src/core/response-schema.ts +279 -0
  375. package/src/core/run-overrides.ts +77 -0
  376. package/src/core/safe-exec.ts +205 -0
  377. package/src/core/safe-id.ts +37 -0
  378. package/src/core/safe-resource-write.ts +162 -0
  379. package/src/core/session-routing.ts +339 -0
  380. package/src/core/settings-layers.ts +354 -0
  381. package/src/core/shared-bus.ts +8 -0
  382. package/src/core/shell-quote.ts +26 -0
  383. package/src/core/skill-activation.ts +190 -0
  384. package/src/core/startup-timer.ts +37 -0
  385. package/src/core/state-file-lock.ts +219 -0
  386. package/src/core/termination.ts +275 -0
  387. package/src/core/timers.ts +38 -0
  388. package/src/core/tool-names.ts +65 -0
  389. package/src/core/verification-scripts.ts +13 -0
  390. package/src/core/workspace-files.ts +492 -0
  391. package/src/core/xdg.ts +177 -0
  392. package/src/domains/agents/builtins/architect.md +4 -4
  393. package/src/domains/agents/builtins/coder.md +3 -2
  394. package/src/domains/agents/builtins/debugger.md +1 -1
  395. package/src/domains/agents/builtins/documenter.md +1 -1
  396. package/src/domains/agents/builtins/git-master.md +3 -3
  397. package/src/domains/agents/builtins/provenance.md +1 -1
  398. package/src/domains/agents/builtins/researcher.md +1 -1
  399. package/src/domains/agents/builtins/scout.md +1 -1
  400. package/src/domains/agents/builtins/tester.md +1 -1
  401. package/src/domains/agents/builtins/verifier.md +1 -1
  402. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  403. package/src/domains/agents/catalog.ts +172 -0
  404. package/src/domains/agents/contract.ts +16 -0
  405. package/src/domains/agents/extension.ts +110 -0
  406. package/src/domains/agents/fleet-commands.ts +154 -0
  407. package/src/domains/agents/fleet-contract.ts +797 -0
  408. package/src/domains/agents/frontmatter.ts +40 -0
  409. package/src/domains/agents/index.ts +102 -0
  410. package/src/domains/agents/manifest.ts +6 -0
  411. package/src/domains/agents/recipe-schema.ts +202 -0
  412. package/src/domains/agents/recipe.ts +125 -0
  413. package/src/domains/agents/registry.ts +111 -0
  414. package/src/domains/agents/result-contract.ts +1265 -0
  415. package/src/domains/agents/spec.ts +371 -0
  416. package/src/domains/agents/write-boundary.ts +109 -0
  417. package/src/domains/components/diff.ts +99 -0
  418. package/src/domains/components/hash.ts +21 -0
  419. package/src/domains/components/index.ts +3 -0
  420. package/src/domains/components/scan.ts +304 -0
  421. package/src/domains/components/snapshot.ts +108 -0
  422. package/src/domains/components/types.ts +82 -0
  423. package/src/domains/config/agent-namespace.ts +13 -0
  424. package/src/domains/config/classify.ts +106 -0
  425. package/src/domains/config/contract.ts +22 -0
  426. package/src/domains/config/extension.ts +142 -0
  427. package/src/domains/config/index.ts +23 -0
  428. package/src/domains/config/keybindings.ts +200 -0
  429. package/src/domains/config/manifest.ts +6 -0
  430. package/src/domains/config/watcher.ts +41 -0
  431. package/src/domains/context/adoption.ts +880 -0
  432. package/src/domains/context/bootstrap-prompt.ts +273 -0
  433. package/src/domains/context/bootstrap.ts +1502 -0
  434. package/src/domains/context/clear.ts +91 -0
  435. package/src/domains/context/clio-md.ts +429 -0
  436. package/src/domains/context/codewiki/artifact.ts +400 -0
  437. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  438. package/src/domains/context/codewiki/build-worker.ts +54 -0
  439. package/src/domains/context/codewiki/cmake.ts +356 -0
  440. package/src/domains/context/codewiki/cooperative.ts +46 -0
  441. package/src/domains/context/codewiki/coordinator.ts +182 -0
  442. package/src/domains/context/codewiki/digest.ts +135 -0
  443. package/src/domains/context/codewiki/grammar-assets.ts +33 -0
  444. package/src/domains/context/codewiki/indexer.ts +1529 -0
  445. package/src/domains/context/codewiki/paths.ts +67 -0
  446. package/src/domains/context/codewiki/schema.ts +80 -0
  447. package/src/domains/context/codewiki/tree-sitter.ts +771 -0
  448. package/src/domains/context/contract.ts +68 -0
  449. package/src/domains/context/excluded-dirs.ts +1 -0
  450. package/src/domains/context/extension.ts +358 -0
  451. package/src/domains/context/fingerprint.ts +198 -0
  452. package/src/domains/context/index.ts +154 -0
  453. package/src/domains/context/init-options.ts +69 -0
  454. package/src/domains/context/manifest.ts +6 -0
  455. package/src/domains/context/operator-profile.ts +157 -0
  456. package/src/domains/context/project-metadata.ts +529 -0
  457. package/src/domains/context/project-rules.ts +227 -0
  458. package/src/domains/context/prompt-context.ts +61 -0
  459. package/src/domains/context/refresh.ts +178 -0
  460. package/src/domains/context/runtime.ts +17 -0
  461. package/src/domains/context/sibling-files.ts +10 -0
  462. package/src/domains/context/state.ts +237 -0
  463. package/src/domains/context/wiki/assemble.ts +303 -0
  464. package/src/domains/context/wiki/frontmatter.ts +210 -0
  465. package/src/domains/context/wiki/generate.ts +595 -0
  466. package/src/domains/context/wiki/layout.ts +111 -0
  467. package/src/domains/context/wiki/meta.ts +221 -0
  468. package/src/domains/context/wiki/plan-store.ts +217 -0
  469. package/src/domains/context/wiki/plan.ts +250 -0
  470. package/src/domains/context/wiki/prompts.ts +283 -0
  471. package/src/domains/context/wiki/staleness.ts +198 -0
  472. package/src/domains/dispatch/active-route-planner.ts +168 -0
  473. package/src/domains/dispatch/admission-queue.ts +150 -0
  474. package/src/domains/dispatch/admission.ts +334 -0
  475. package/src/domains/dispatch/agent-candidates.ts +307 -0
  476. package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
  477. package/src/domains/dispatch/agent-ledger-store.ts +257 -0
  478. package/src/domains/dispatch/agent-ledger.ts +212 -0
  479. package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
  480. package/src/domains/dispatch/assignment-events.ts +132 -0
  481. package/src/domains/dispatch/assignment-reconcile.ts +76 -0
  482. package/src/domains/dispatch/assignment-store.ts +162 -0
  483. package/src/domains/dispatch/assignment.ts +278 -0
  484. package/src/domains/dispatch/backoff.ts +59 -0
  485. package/src/domains/dispatch/batch-store.ts +134 -0
  486. package/src/domains/dispatch/batch-tracker.ts +66 -0
  487. package/src/domains/dispatch/capability-match.ts +155 -0
  488. package/src/domains/dispatch/capacity-lease.ts +413 -0
  489. package/src/domains/dispatch/code-step-store.ts +52 -0
  490. package/src/domains/dispatch/code-step.ts +387 -0
  491. package/src/domains/dispatch/contract.ts +278 -0
  492. package/src/domains/dispatch/dedup.ts +133 -0
  493. package/src/domains/dispatch/event-pump.ts +251 -0
  494. package/src/domains/dispatch/execution-handoff.ts +29 -0
  495. package/src/domains/dispatch/execution-plan.ts +328 -0
  496. package/src/domains/dispatch/execution-role.ts +277 -0
  497. package/src/domains/dispatch/execution-scheduler.ts +583 -0
  498. package/src/domains/dispatch/extension.ts +6006 -0
  499. package/src/domains/dispatch/failure-classification.ts +147 -0
  500. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  501. package/src/domains/dispatch/fleet-plan.ts +225 -0
  502. package/src/domains/dispatch/fleet-preflight.ts +394 -0
  503. package/src/domains/dispatch/gate-decisions.ts +1040 -0
  504. package/src/domains/dispatch/gate-role-prompts.ts +58 -0
  505. package/src/domains/dispatch/heartbeat.ts +27 -0
  506. package/src/domains/dispatch/index.ts +137 -0
  507. package/src/domains/dispatch/joint-route-adapter.ts +114 -0
  508. package/src/domains/dispatch/joint-route-resolver.ts +283 -0
  509. package/src/domains/dispatch/manifest.ts +6 -0
  510. package/src/domains/dispatch/orphan-recovery.ts +266 -0
  511. package/src/domains/dispatch/outcome.ts +109 -0
  512. package/src/domains/dispatch/phase-timing.ts +47 -0
  513. package/src/domains/dispatch/placement.ts +202 -0
  514. package/src/domains/dispatch/receipt-findings.ts +255 -0
  515. package/src/domains/dispatch/receipt-integrity.ts +383 -0
  516. package/src/domains/dispatch/recovery-candidates.ts +74 -0
  517. package/src/domains/dispatch/reproducibility.ts +48 -0
  518. package/src/domains/dispatch/reservation-store.ts +501 -0
  519. package/src/domains/dispatch/route-approval.ts +177 -0
  520. package/src/domains/dispatch/route-candidates.ts +57 -0
  521. package/src/domains/dispatch/route-decision.ts +1079 -0
  522. package/src/domains/dispatch/route-facts.ts +187 -0
  523. package/src/domains/dispatch/route-history.ts +238 -0
  524. package/src/domains/dispatch/route-observer.ts +488 -0
  525. package/src/domains/dispatch/route-policy.ts +327 -0
  526. package/src/domains/dispatch/route-quality.ts +256 -0
  527. package/src/domains/dispatch/route-readiness.ts +120 -0
  528. package/src/domains/dispatch/routing-intent.ts +287 -0
  529. package/src/domains/dispatch/run-identity.ts +56 -0
  530. package/src/domains/dispatch/scout-transition.ts +130 -0
  531. package/src/domains/dispatch/state.ts +302 -0
  532. package/src/domains/dispatch/tool-stats.ts +132 -0
  533. package/src/domains/dispatch/transport.ts +210 -0
  534. package/src/domains/dispatch/types.ts +799 -0
  535. package/src/domains/dispatch/validation-grounding.ts +154 -0
  536. package/src/domains/dispatch/validation.ts +721 -0
  537. package/src/domains/dispatch/worker-protocol.ts +275 -0
  538. package/src/domains/dispatch/worker-spawn.ts +585 -0
  539. package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
  540. package/src/domains/dispatch/write-boundary.ts +426 -0
  541. package/src/domains/eval/artifacts/redact.ts +42 -0
  542. package/src/domains/eval/artifacts/store.ts +173 -0
  543. package/src/domains/eval/compare/compare.ts +33 -0
  544. package/src/domains/eval/compare/gates.ts +66 -0
  545. package/src/domains/eval/compare/thresholds.ts +92 -0
  546. package/src/domains/eval/harness-metrics.ts +62 -0
  547. package/src/domains/eval/index.ts +66 -0
  548. package/src/domains/eval/metrics/chaos-stream.ts +93 -0
  549. package/src/domains/eval/metrics/context.ts +34 -0
  550. package/src/domains/eval/metrics/coverage.ts +21 -0
  551. package/src/domains/eval/metrics/evidence.ts +182 -0
  552. package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
  553. package/src/domains/eval/metrics/invariants.ts +736 -0
  554. package/src/domains/eval/metrics/latency.ts +4 -0
  555. package/src/domains/eval/metrics/token-stream.ts +139 -0
  556. package/src/domains/eval/metrics/tokens.ts +51 -0
  557. package/src/domains/eval/metrics/tool-calls.ts +7 -0
  558. package/src/domains/eval/proactive-memory.ts +279 -0
  559. package/src/domains/eval/provenance.ts +35 -0
  560. package/src/domains/eval/report.ts +234 -0
  561. package/src/domains/eval/reports/json.ts +5 -0
  562. package/src/domains/eval/reports/junit.ts +23 -0
  563. package/src/domains/eval/reports/markdown.ts +20 -0
  564. package/src/domains/eval/reports/swe-jsonl.ts +16 -0
  565. package/src/domains/eval/reports/text.ts +25 -0
  566. package/src/domains/eval/run-compare.ts +274 -0
  567. package/src/domains/eval/runner.ts +244 -0
  568. package/src/domains/eval/runners/clio-run.ts +148 -0
  569. package/src/domains/eval/runners/context-index.ts +56 -0
  570. package/src/domains/eval/runners/context-init.ts +203 -0
  571. package/src/domains/eval/runners/external-command.ts +350 -0
  572. package/src/domains/eval/runtime-paths.ts +171 -0
  573. package/src/domains/eval/schema/artifact.ts +75 -0
  574. package/src/domains/eval/schema/suite.ts +235 -0
  575. package/src/domains/eval/schema/validate.ts +339 -0
  576. package/src/domains/eval/store.ts +392 -0
  577. package/src/domains/eval/suites/load.ts +74 -0
  578. package/src/domains/eval/suites/matrix.ts +19 -0
  579. package/src/domains/eval/suites/resolve.ts +44 -0
  580. package/src/domains/eval/suites/run.ts +325 -0
  581. package/src/domains/eval/task-file.ts +186 -0
  582. package/src/domains/eval/types.ts +140 -0
  583. package/src/domains/eval/verifiers/command.ts +27 -0
  584. package/src/domains/eval/verifiers/file-exists.ts +6 -0
  585. package/src/domains/eval/verifiers/patch.ts +22 -0
  586. package/src/domains/eval/workspaces/git.ts +41 -0
  587. package/src/domains/eval/workspaces/local.ts +17 -0
  588. package/src/domains/eval/workspaces/temp-copy.ts +29 -0
  589. package/src/domains/evidence/build.ts +1754 -0
  590. package/src/domains/evidence/eval.ts +605 -0
  591. package/src/domains/evidence/failure-attribution.ts +54 -0
  592. package/src/domains/evidence/finish-contract-map.ts +42 -0
  593. package/src/domains/evidence/index.ts +55 -0
  594. package/src/domains/evidence/provenance.ts +200 -0
  595. package/src/domains/evidence/redact.ts +81 -0
  596. package/src/domains/evidence/store.ts +291 -0
  597. package/src/domains/evidence/types.ts +325 -0
  598. package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
  599. package/src/domains/evolution/index.ts +26 -0
  600. package/src/domains/evolution/manifest.ts +154 -0
  601. package/src/domains/evolution/validate.ts +304 -0
  602. package/src/domains/extensions/contract.ts +22 -0
  603. package/src/domains/extensions/discovery.ts +193 -0
  604. package/src/domains/extensions/extension.ts +46 -0
  605. package/src/domains/extensions/index.ts +34 -0
  606. package/src/domains/extensions/manager.ts +30 -0
  607. package/src/domains/extensions/manifest.ts +6 -0
  608. package/src/domains/extensions/resources.ts +38 -0
  609. package/src/domains/extensions/state.ts +224 -0
  610. package/src/domains/extensions/types.ts +83 -0
  611. package/src/domains/interop/consent.ts +185 -0
  612. package/src/domains/interop/contract.ts +29 -0
  613. package/src/domains/interop/detect.ts +173 -0
  614. package/src/domains/interop/extension.ts +59 -0
  615. package/src/domains/interop/index.ts +34 -0
  616. package/src/domains/interop/manifest.ts +6 -0
  617. package/src/domains/interop/registry.ts +139 -0
  618. package/src/domains/interop/state.ts +92 -0
  619. package/src/domains/interop/types.ts +109 -0
  620. package/src/domains/lifecycle/contract.ts +11 -0
  621. package/src/domains/lifecycle/doctor.ts +536 -0
  622. package/src/domains/lifecycle/extension.ts +23 -0
  623. package/src/domains/lifecycle/index.ts +21 -0
  624. package/src/domains/lifecycle/install-method.ts +51 -0
  625. package/src/domains/lifecycle/manifest.ts +6 -0
  626. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  627. package/src/domains/lifecycle/migrations/index.ts +114 -0
  628. package/src/domains/lifecycle/state.ts +93 -0
  629. package/src/domains/lifecycle/upgrade-notice.ts +35 -0
  630. package/src/domains/lifecycle/version.ts +35 -0
  631. package/src/domains/memory/index.ts +128 -0
  632. package/src/domains/memory/operations.ts +143 -0
  633. package/src/domains/memory/prompt-section.ts +86 -0
  634. package/src/domains/memory/proposal.ts +180 -0
  635. package/src/domains/memory/store.ts +163 -0
  636. package/src/domains/memory/task-bank.ts +229 -0
  637. package/src/domains/memory/task-memory-handoff.ts +222 -0
  638. package/src/domains/memory/task-memory-policy.ts +602 -0
  639. package/src/domains/memory/task-memory-status.ts +58 -0
  640. package/src/domains/memory/task-memory-telemetry.ts +346 -0
  641. package/src/domains/memory/task-memory-trace.ts +89 -0
  642. package/src/domains/memory/types.ts +74 -0
  643. package/src/domains/memory/validate.ts +297 -0
  644. package/src/domains/middleware/budget.ts +216 -0
  645. package/src/domains/middleware/contract.ts +35 -0
  646. package/src/domains/middleware/dispatch-nudge.ts +469 -0
  647. package/src/domains/middleware/extension.ts +129 -0
  648. package/src/domains/middleware/hook-receipts.ts +70 -0
  649. package/src/domains/middleware/hooks-io.ts +186 -0
  650. package/src/domains/middleware/hooks.ts +432 -0
  651. package/src/domains/middleware/index.ts +154 -0
  652. package/src/domains/middleware/manifest.ts +6 -0
  653. package/src/domains/middleware/memory-intervention.ts +701 -0
  654. package/src/domains/middleware/rules.ts +42 -0
  655. package/src/domains/middleware/runtime.ts +333 -0
  656. package/src/domains/middleware/skills-reminder.ts +202 -0
  657. package/src/domains/middleware/snapshot.ts +71 -0
  658. package/src/domains/middleware/stalled-turn.ts +71 -0
  659. package/src/domains/middleware/task-board-reminder.ts +87 -0
  660. package/src/domains/middleware/task-nudge.ts +77 -0
  661. package/src/domains/middleware/tool-choice-control.ts +42 -0
  662. package/src/domains/middleware/types.ts +131 -0
  663. package/src/domains/middleware/validate.ts +329 -0
  664. package/src/domains/observability/accountability.ts +67 -0
  665. package/src/domains/observability/contract.ts +168 -0
  666. package/src/domains/observability/cost.ts +206 -0
  667. package/src/domains/observability/evidence-index.ts +123 -0
  668. package/src/domains/observability/extension.ts +281 -0
  669. package/src/domains/observability/index.ts +78 -0
  670. package/src/domains/observability/manifest.ts +10 -0
  671. package/src/domains/observability/metrics.ts +37 -0
  672. package/src/domains/observability/projection.ts +477 -0
  673. package/src/domains/observability/telemetry.ts +89 -0
  674. package/src/domains/observability/trace-store.ts +1454 -0
  675. package/src/domains/prompts/compiler.ts +614 -0
  676. package/src/domains/prompts/contract.ts +46 -0
  677. package/src/domains/prompts/extension.ts +336 -0
  678. package/src/domains/prompts/fragment-loader.ts +138 -0
  679. package/src/domains/prompts/fragments/identity/clio.md +5 -6
  680. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  681. package/src/domains/prompts/fragments/identity/self-awareness.md +19 -0
  682. package/src/domains/prompts/fragments/operating/contract.md +4 -41
  683. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  684. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  685. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  686. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  687. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  688. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  689. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  690. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  691. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  692. package/src/domains/prompts/hash.ts +73 -0
  693. package/src/domains/prompts/index.ts +32 -0
  694. package/src/domains/prompts/manifest.ts +8 -0
  695. package/src/domains/prompts/memory-intervention.ts +57 -0
  696. package/src/domains/prompts/preload.ts +82 -0
  697. package/src/domains/providers/auth/api-key.ts +47 -0
  698. package/src/domains/providers/auth/backend-file.ts +79 -0
  699. package/src/domains/providers/auth/backend-memory.ts +72 -0
  700. package/src/domains/providers/auth/boot-status.ts +65 -0
  701. package/src/domains/providers/auth/index.ts +37 -0
  702. package/src/domains/providers/auth/oauth.ts +37 -0
  703. package/src/domains/providers/auth/storage.ts +726 -0
  704. package/src/domains/providers/capabilities.ts +58 -0
  705. package/src/domains/providers/catalog.ts +162 -0
  706. package/src/domains/providers/contract.ts +162 -0
  707. package/src/domains/providers/credentials.ts +20 -0
  708. package/src/domains/providers/eligibility.ts +24 -0
  709. package/src/domains/providers/errors.ts +64 -0
  710. package/src/domains/providers/extension.ts +548 -0
  711. package/src/domains/providers/index.ts +142 -0
  712. package/src/domains/providers/knowledge-base-path.ts +102 -0
  713. package/src/domains/providers/manifest.ts +6 -0
  714. package/src/domains/providers/model-capabilities.ts +136 -0
  715. package/src/domains/providers/model-discovery.ts +144 -0
  716. package/src/domains/providers/model-family.ts +32 -0
  717. package/src/domains/providers/model-runtime-capabilities.ts +723 -0
  718. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +120 -37
  719. package/src/domains/providers/plugins.ts +61 -0
  720. package/src/domains/providers/probe/fingerprint.ts +64 -0
  721. package/src/domains/providers/probe/http.ts +114 -0
  722. package/src/domains/providers/probe/reasoning.ts +111 -0
  723. package/src/domains/providers/registry.ts +187 -0
  724. package/src/domains/providers/resolver.ts +156 -0
  725. package/src/domains/providers/runtime-resolution.ts +720 -0
  726. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
  727. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  728. package/src/domains/providers/runtimes/builtins.ts +78 -0
  729. package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
  730. package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
  731. package/src/domains/providers/runtimes/claude/common.ts +55 -0
  732. package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
  733. package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
  734. package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
  735. package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
  736. package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
  737. package/src/domains/providers/runtimes/cloud/google.ts +41 -0
  738. package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
  739. package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
  740. package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
  741. package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
  742. package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
  743. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  744. package/src/domains/providers/runtimes/common/local-synth.ts +164 -0
  745. package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
  746. package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
  747. package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
  748. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
  749. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
  750. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
  751. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
  752. package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
  753. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  754. package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
  755. package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
  756. package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
  757. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
  758. package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
  759. package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
  760. package/src/domains/providers/runtimes/protocol/google.ts +27 -0
  761. package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
  762. package/src/domains/providers/support.ts +241 -0
  763. package/src/domains/providers/thinking-control-policy.ts +85 -0
  764. package/src/domains/providers/types/capability-flags.ts +114 -0
  765. package/src/domains/providers/types/cost-provenance.ts +7 -0
  766. package/src/domains/providers/types/inference.ts +41 -0
  767. package/src/domains/providers/types/knowledge-base.ts +156 -0
  768. package/src/domains/providers/types/local-model-quirks.ts +216 -0
  769. package/src/domains/providers/types/runtime-descriptor.ts +181 -0
  770. package/src/domains/providers/types/target-descriptor.ts +60 -0
  771. package/src/domains/resources/collision.ts +92 -0
  772. package/src/domains/resources/common-loader.ts +140 -0
  773. package/src/domains/resources/contract.ts +24 -0
  774. package/src/domains/resources/extension.ts +59 -0
  775. package/src/domains/resources/index.ts +74 -0
  776. package/src/domains/resources/loader.ts +85 -0
  777. package/src/domains/resources/manifest.ts +6 -0
  778. package/src/domains/resources/prompts/loader.ts +246 -0
  779. package/src/domains/resources/prompts/substitute.ts +1 -0
  780. package/src/domains/resources/skills/content-hash.ts +107 -0
  781. package/src/domains/resources/skills/evals.ts +175 -0
  782. package/src/domains/resources/skills/install.ts +427 -0
  783. package/src/domains/resources/skills/loader.ts +985 -0
  784. package/src/domains/resources/skills/marketplace.ts +301 -0
  785. package/src/domains/resources/skills/provenance-pin.ts +115 -0
  786. package/src/domains/safety/action-classifier.ts +270 -0
  787. package/src/domains/safety/approval-axis.ts +23 -0
  788. package/src/domains/safety/audit.ts +493 -0
  789. package/src/domains/safety/autonomy.ts +174 -0
  790. package/src/domains/safety/call-target.ts +59 -0
  791. package/src/domains/safety/contract.ts +65 -0
  792. package/src/domains/safety/damage-control.ts +44 -0
  793. package/src/domains/safety/default-path-policy.ts +117 -0
  794. package/src/domains/safety/extension.ts +383 -0
  795. package/src/domains/safety/finish-contract-registration.ts +128 -0
  796. package/src/domains/safety/finish-contract.ts +554 -0
  797. package/src/domains/safety/index.ts +44 -0
  798. package/src/domains/safety/loop-detector.ts +143 -0
  799. package/src/domains/safety/manifest.ts +6 -0
  800. package/src/domains/safety/path-policy.ts +164 -0
  801. package/src/domains/safety/policy-engine.ts +994 -0
  802. package/src/domains/safety/project-policy.ts +391 -0
  803. package/src/domains/safety/protected-artifacts-registration.ts +189 -0
  804. package/src/domains/safety/protected-artifacts.ts +993 -0
  805. package/src/domains/safety/rejection-feedback.ts +102 -0
  806. package/src/domains/safety/rigor.ts +72 -0
  807. package/src/domains/safety/rule-compiler.ts +48 -0
  808. package/src/domains/safety/rule-pack-loader.ts +92 -0
  809. package/src/domains/safety/run-effects.ts +197 -0
  810. package/src/domains/safety/scope.ts +61 -0
  811. package/src/domains/scheduling/budget.ts +35 -0
  812. package/src/domains/scheduling/cluster.ts +175 -0
  813. package/src/domains/scheduling/contract.ts +30 -0
  814. package/src/domains/scheduling/extension.ts +91 -0
  815. package/src/domains/scheduling/index.ts +12 -0
  816. package/src/domains/scheduling/manifest.ts +6 -0
  817. package/src/domains/session/archive-readers.ts +208 -0
  818. package/src/domains/session/checkpoint.ts +38 -0
  819. package/src/domains/session/compaction/auto.ts +89 -0
  820. package/src/domains/session/compaction/branch-summary.ts +187 -0
  821. package/src/domains/session/compaction/compact.ts +493 -0
  822. package/src/domains/session/compaction/cut-point.ts +172 -0
  823. package/src/domains/session/compaction/defaults.ts +34 -0
  824. package/src/domains/session/compaction/mask-observations.ts +265 -0
  825. package/src/domains/session/compaction/session-entries.ts +18 -0
  826. package/src/domains/session/compaction/tokens.ts +148 -0
  827. package/src/domains/session/context-accounting.ts +583 -0
  828. package/src/domains/session/context-ledger.ts +362 -0
  829. package/src/domains/session/contract.ts +159 -0
  830. package/src/domains/session/cwd-fallback.ts +65 -0
  831. package/src/domains/session/decision-board.ts +190 -0
  832. package/src/domains/session/entries.ts +572 -0
  833. package/src/domains/session/extension.ts +403 -0
  834. package/src/domains/session/history.ts +172 -0
  835. package/src/domains/session/index.ts +84 -0
  836. package/src/domains/session/manager.ts +128 -0
  837. package/src/domains/session/manifest.ts +6 -0
  838. package/src/domains/session/migrations/index.ts +27 -0
  839. package/src/domains/session/prompt-manifest.ts +173 -0
  840. package/src/domains/session/protected-artifact-journal.ts +241 -0
  841. package/src/domains/session/protected-artifacts.ts +90 -0
  842. package/src/domains/session/retry.ts +230 -0
  843. package/src/domains/session/session-artifacts.ts +107 -0
  844. package/src/domains/session/task-board.ts +569 -0
  845. package/src/domains/session/tree/active-path.ts +137 -0
  846. package/src/domains/session/tree/fork.ts +159 -0
  847. package/src/domains/session/tree/manager.ts +128 -0
  848. package/src/domains/session/tree/navigator.ts +177 -0
  849. package/src/domains/session/tree/preview.ts +259 -0
  850. package/src/domains/session/usage.ts +148 -0
  851. package/src/domains/session/workspace/git-probe.ts +167 -0
  852. package/src/domains/session/workspace/index.ts +4 -0
  853. package/src/domains/session/workspace/project-type.ts +217 -0
  854. package/src/domains/session/workspace/snapshot.ts +74 -0
  855. package/src/domains/share/archive.ts +684 -0
  856. package/src/domains/share/contract.ts +9 -0
  857. package/src/domains/share/extension.ts +26 -0
  858. package/src/domains/share/index.ts +28 -0
  859. package/src/domains/share/manifest.ts +6 -0
  860. package/src/domains/user-tasks/store.ts +297 -0
  861. package/src/engine/acp/adapter.ts +397 -0
  862. package/src/engine/acp/errors.ts +128 -0
  863. package/src/engine/acp/event-mapper.ts +154 -0
  864. package/src/engine/acp/server.ts +2238 -0
  865. package/src/engine/acp/tool-mediator.ts +686 -0
  866. package/src/engine/acp/transport.ts +775 -0
  867. package/src/engine/acp/types.ts +196 -0
  868. package/src/engine/agent.ts +29 -0
  869. package/src/engine/ai.ts +207 -0
  870. package/src/engine/alcf-oauth.ts +205 -0
  871. package/src/engine/antigravity/subprocess-runtime.ts +205 -0
  872. package/src/engine/api-registry.ts +223 -0
  873. package/src/engine/apis/degraded-inference.ts +95 -0
  874. package/src/engine/apis/index.ts +16 -0
  875. package/src/engine/apis/llamacpp-residency.ts +292 -0
  876. package/src/engine/apis/lmstudio-residency.ts +76 -0
  877. package/src/engine/apis/lmstudio.ts +243 -0
  878. package/src/engine/apis/ollama-native.ts +528 -0
  879. package/src/engine/apis/openai-completions.ts +795 -0
  880. package/src/engine/apis/output-budget.ts +99 -0
  881. package/src/engine/apis/residency-lock.ts +29 -0
  882. package/src/engine/apis/residency.ts +776 -0
  883. package/src/engine/apis/resident-models.ts +42 -0
  884. package/src/engine/apis/sampling-overrides.ts +38 -0
  885. package/src/engine/apis/types.ts +16 -0
  886. package/src/engine/claude/sdk-runtime.ts +685 -0
  887. package/src/engine/claude/session-id.ts +5 -0
  888. package/src/engine/claude/subprocess-runtime.ts +316 -0
  889. package/src/engine/claude/tool-safety.ts +400 -0
  890. package/src/engine/env-api-keys.ts +98 -0
  891. package/src/engine/external-subprocess.ts +23 -0
  892. package/src/engine/gemma-channel-filter.ts +223 -0
  893. package/src/engine/harmony-response.ts +165 -0
  894. package/src/engine/instrumented-tui.ts +192 -0
  895. package/src/engine/loop-guard.ts +1127 -0
  896. package/src/engine/messages.ts +14 -0
  897. package/src/engine/models.ts +42 -0
  898. package/src/engine/oauth.ts +196 -0
  899. package/src/engine/pi-mono-names.ts +13 -0
  900. package/src/engine/prompt-templates.ts +1 -0
  901. package/src/engine/provider-payload.ts +272 -0
  902. package/src/engine/select-list.ts +53 -0
  903. package/src/engine/session.ts +834 -0
  904. package/src/engine/strip-tokenizer-sentinels.ts +125 -0
  905. package/src/engine/truncate.ts +9 -0
  906. package/src/engine/tui.ts +111 -0
  907. package/src/engine/types.ts +63 -0
  908. package/src/engine/worker-events.ts +100 -0
  909. package/src/engine/worker-runtime-capabilities.ts +5 -0
  910. package/src/engine/worker-runtime.ts +1022 -0
  911. package/src/engine/worker-tools.ts +208 -0
  912. package/src/entry/boot-options.ts +50 -0
  913. package/src/entry/orchestrator.ts +2011 -0
  914. package/src/interactive/application-controller.ts +433 -0
  915. package/src/interactive/bus-notices.ts +265 -0
  916. package/src/interactive/chat-loop-messages.ts +626 -0
  917. package/src/interactive/chat-loop-policy.ts +18 -0
  918. package/src/interactive/chat-loop.ts +1090 -0
  919. package/src/interactive/chat-panel.ts +1820 -0
  920. package/src/interactive/chat-renderer.ts +1228 -0
  921. package/src/interactive/clio-editor.ts +161 -0
  922. package/src/interactive/command-fallbacks.ts +23 -0
  923. package/src/interactive/command-output.ts +85 -0
  924. package/src/interactive/context-activity.ts +203 -0
  925. package/src/interactive/context-meter.ts +223 -0
  926. package/src/interactive/context-overlay.ts +246 -0
  927. package/src/interactive/cost-overlay.ts +279 -0
  928. package/src/interactive/dispatch-board.ts +1319 -0
  929. package/src/interactive/dispatch-steering.ts +86 -0
  930. package/src/interactive/editor-bash.ts +46 -0
  931. package/src/interactive/editor-steer.ts +51 -0
  932. package/src/interactive/editor-submit.ts +507 -0
  933. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  934. package/src/interactive/export-html/index.ts +51 -0
  935. package/src/interactive/export-html/template.ts +45 -0
  936. package/src/interactive/export-html/tool-renderer.ts +54 -0
  937. package/src/interactive/external-editor.ts +67 -0
  938. package/src/interactive/follow-up-queue-panel.ts +75 -0
  939. package/src/interactive/footer/dashboard.ts +538 -0
  940. package/src/interactive/footer/notifications.ts +275 -0
  941. package/src/interactive/footer/widgets.ts +1264 -0
  942. package/src/interactive/footer-panel.ts +187 -0
  943. package/src/interactive/format-time.ts +97 -0
  944. package/src/interactive/index.ts +11 -0
  945. package/src/interactive/interactive-application.ts +939 -0
  946. package/src/interactive/interactive-event-projection.ts +385 -0
  947. package/src/interactive/interactive-input-runtime.ts +307 -0
  948. package/src/interactive/interactive-presentation.ts +584 -0
  949. package/src/interactive/interactive-shell.ts +388 -0
  950. package/src/interactive/interactive-slash-runtime.ts +554 -0
  951. package/src/interactive/interactive-subscriptions.ts +111 -0
  952. package/src/interactive/interactive-tickers.ts +183 -0
  953. package/src/interactive/keybinding-manager.ts +496 -0
  954. package/src/interactive/layout.ts +57 -0
  955. package/src/interactive/leader-key.ts +143 -0
  956. package/src/interactive/loop-guard-interrupt.ts +101 -0
  957. package/src/interactive/memory-overlay.ts +280 -0
  958. package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
  959. package/src/interactive/overlay-auth-lifecycle.ts +308 -0
  960. package/src/interactive/overlay-frame.ts +502 -0
  961. package/src/interactive/overlay-general-openers.ts +274 -0
  962. package/src/interactive/overlay-key-routing.ts +216 -0
  963. package/src/interactive/overlay-lifecycle.ts +426 -0
  964. package/src/interactive/overlay-model-selectors.ts +127 -0
  965. package/src/interactive/overlay-permission-lifecycle.ts +345 -0
  966. package/src/interactive/overlay-resource-openers.ts +112 -0
  967. package/src/interactive/overlay-session-lifecycle.ts +327 -0
  968. package/src/interactive/overlay-transitions.ts +57 -0
  969. package/src/interactive/overlays/agents.ts +69 -0
  970. package/src/interactive/overlays/ask-user.ts +921 -0
  971. package/src/interactive/overlays/auth-dialog.ts +221 -0
  972. package/src/interactive/overlays/context-reset.ts +108 -0
  973. package/src/interactive/overlays/cwd-fallback.ts +141 -0
  974. package/src/interactive/overlays/decisions.ts +300 -0
  975. package/src/interactive/overlays/extensions.ts +54 -0
  976. package/src/interactive/overlays/help-reference.ts +145 -0
  977. package/src/interactive/overlays/interop.ts +139 -0
  978. package/src/interactive/overlays/keybinding-detail.ts +90 -0
  979. package/src/interactive/overlays/list-overlay.ts +606 -0
  980. package/src/interactive/overlays/message-picker.ts +155 -0
  981. package/src/interactive/overlays/model-selector.ts +1109 -0
  982. package/src/interactive/overlays/prompts.ts +72 -0
  983. package/src/interactive/overlays/session-selector-search.ts +31 -0
  984. package/src/interactive/overlays/session-selector.ts +284 -0
  985. package/src/interactive/overlays/settings.ts +3451 -0
  986. package/src/interactive/overlays/skills-hub.ts +237 -0
  987. package/src/interactive/overlays/tree-selector.ts +422 -0
  988. package/src/interactive/permission-overlay.ts +170 -0
  989. package/src/interactive/render-trace.ts +534 -0
  990. package/src/interactive/renderers/branch-summary.ts +86 -0
  991. package/src/interactive/renderers/code-ink.ts +420 -0
  992. package/src/interactive/renderers/compaction-summary.ts +112 -0
  993. package/src/interactive/renderers/diff.ts +137 -0
  994. package/src/interactive/renderers/mermaid.ts +53 -0
  995. package/src/interactive/renderers/notice.ts +28 -0
  996. package/src/interactive/renderers/retry-status.ts +31 -0
  997. package/src/interactive/renderers/structured.ts +89 -0
  998. package/src/interactive/renderers/tool-execution.ts +1357 -0
  999. package/src/interactive/renderers/worker-entry.ts +280 -0
  1000. package/src/interactive/session-last-turn.ts +186 -0
  1001. package/src/interactive/session-switch-settlement.ts +10 -0
  1002. package/src/interactive/session-transcript.ts +105 -0
  1003. package/src/interactive/session-usage-reseed.ts +74 -0
  1004. package/src/interactive/slash-autocomplete.ts +256 -0
  1005. package/src/interactive/slash-commands.ts +1407 -0
  1006. package/src/interactive/slash-spec.ts +424 -0
  1007. package/src/interactive/status/controller.ts +260 -0
  1008. package/src/interactive/status/index.ts +23 -0
  1009. package/src/interactive/status/state-machine.ts +530 -0
  1010. package/src/interactive/status/summary.ts +170 -0
  1011. package/src/interactive/status/types.ts +121 -0
  1012. package/src/interactive/status/verbs.ts +163 -0
  1013. package/src/interactive/status/watchdog.ts +24 -0
  1014. package/src/interactive/stdout-backpressure.ts +99 -0
  1015. package/src/interactive/stream-pacer.ts +530 -0
  1016. package/src/interactive/stream-pacing-policy.ts +66 -0
  1017. package/src/interactive/tasks-overlay.ts +540 -0
  1018. package/src/interactive/terminal-lease.ts +485 -0
  1019. package/src/interactive/theme/components.ts +55 -0
  1020. package/src/interactive/theme/glyphs.ts +70 -0
  1021. package/src/interactive/theme/index.ts +15 -0
  1022. package/src/interactive/theme/labels.ts +88 -0
  1023. package/src/interactive/theme/rules.ts +138 -0
  1024. package/src/interactive/theme/segments.ts +88 -0
  1025. package/src/interactive/theme/tokens.ts +121 -0
  1026. package/src/interactive/thinking-level-policy.ts +6 -0
  1027. package/src/interactive/tool-prose-loop.ts +122 -0
  1028. package/src/interactive/tool-prose-registration.ts +48 -0
  1029. package/src/interactive/turn-context.ts +855 -0
  1030. package/src/interactive/turn-middleware.ts +283 -0
  1031. package/src/interactive/turn-persistence.ts +458 -0
  1032. package/src/interactive/turn-queues.ts +181 -0
  1033. package/src/interactive/turn-recovery.ts +323 -0
  1034. package/src/interactive/turn-runtime.ts +869 -0
  1035. package/src/interactive/turn-state.ts +133 -0
  1036. package/src/interactive/view/artifacts.ts +1452 -0
  1037. package/src/interactive/view/view-overlay.ts +735 -0
  1038. package/src/interactive/welcome-dashboard.ts +537 -0
  1039. package/src/interactive/worker-receipts.ts +143 -0
  1040. package/src/interactive/worker-replay.ts +111 -0
  1041. package/src/interactive/worker-share.ts +100 -0
  1042. package/src/interactive/worker-stream.ts +446 -0
  1043. package/src/interactive/workspace-facts.ts +141 -0
  1044. package/src/tools/agent-tools.ts +402 -0
  1045. package/src/tools/artifact.ts +103 -0
  1046. package/src/tools/ask-user.ts +666 -0
  1047. package/src/tools/bash.ts +204 -0
  1048. package/src/tools/bootstrap.ts +77 -0
  1049. package/src/tools/builtin-tool-catalog.ts +265 -0
  1050. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  1051. package/src/tools/codewiki/code-nav.ts +549 -0
  1052. package/src/tools/codewiki/shared.ts +118 -0
  1053. package/src/tools/compete-worktrees.ts +898 -0
  1054. package/src/tools/context/docs-engine.ts +630 -0
  1055. package/src/tools/context/index.ts +514 -0
  1056. package/src/tools/context/surface.ts +19 -0
  1057. package/src/tools/core-bootstrap.ts +168 -0
  1058. package/src/tools/credential-present.ts +151 -0
  1059. package/src/tools/dispatch-admission.ts +533 -0
  1060. package/src/tools/dispatch-arguments.ts +228 -0
  1061. package/src/tools/dispatch-background.ts +54 -0
  1062. package/src/tools/dispatch-event-text.ts +6 -0
  1063. package/src/tools/dispatch-plan.ts +746 -0
  1064. package/src/tools/dispatch-run-events.ts +238 -0
  1065. package/src/tools/dispatch-runner.ts +2370 -0
  1066. package/src/tools/dispatch-scout-admission.ts +295 -0
  1067. package/src/tools/dispatch-scout.ts +461 -0
  1068. package/src/tools/dispatch-types.ts +77 -0
  1069. package/src/tools/dispatch.ts +244 -0
  1070. package/src/tools/edit-diff.ts +534 -0
  1071. package/src/tools/edit.ts +128 -0
  1072. package/src/tools/executables.ts +22 -0
  1073. package/src/tools/file-mutation-queue.ts +35 -0
  1074. package/src/tools/find.ts +294 -0
  1075. package/src/tools/grep.ts +495 -0
  1076. package/src/tools/ignore-policy.ts +169 -0
  1077. package/src/tools/lazy-tool.ts +60 -0
  1078. package/src/tools/ledger.ts +206 -0
  1079. package/src/tools/ls.ts +110 -0
  1080. package/src/tools/monitor-surface.ts +36 -0
  1081. package/src/tools/monitor.ts +767 -0
  1082. package/src/tools/network-policy.ts +29 -0
  1083. package/src/tools/observation.ts +421 -0
  1084. package/src/tools/observers.ts +99 -0
  1085. package/src/tools/path-utils.ts +79 -0
  1086. package/src/tools/policy.ts +154 -0
  1087. package/src/tools/profiles.ts +108 -0
  1088. package/src/tools/read.ts +173 -0
  1089. package/src/tools/registry.ts +1169 -0
  1090. package/src/tools/result-shaping.ts +204 -0
  1091. package/src/tools/safe-exec.ts +128 -0
  1092. package/src/tools/spawn-hygiene.ts +182 -0
  1093. package/src/tools/steer-surface.ts +17 -0
  1094. package/src/tools/steer.ts +77 -0
  1095. package/src/tools/tasks.ts +265 -0
  1096. package/src/tools/truncate-utf8.ts +17 -0
  1097. package/src/tools/truncate.ts +43 -0
  1098. package/src/tools/verify/frontend.ts +687 -0
  1099. package/src/tools/verify/index.ts +31 -0
  1100. package/src/tools/verify/scripts.ts +108 -0
  1101. package/src/tools/verify/surface.ts +46 -0
  1102. package/src/tools/web-fetch-surface.ts +23 -0
  1103. package/src/tools/web-fetch.ts +759 -0
  1104. package/src/tools/worker-evidence.ts +215 -0
  1105. package/src/tools/write.ts +57 -0
  1106. package/src/utils/exif-orientation.ts +192 -0
  1107. package/src/utils/git.ts +24 -0
  1108. package/src/utils/image-resize.ts +148 -0
  1109. package/src/utils/photon.ts +103 -0
  1110. package/src/worker/control-lane.ts +22 -0
  1111. package/src/worker/entry.ts +294 -0
  1112. package/src/worker/event-projection.ts +56 -0
  1113. package/src/worker/heartbeat.ts +24 -0
  1114. package/src/worker/ledger-mirror.ts +95 -0
  1115. package/src/worker/ndjson.ts +40 -0
  1116. package/src/worker/protocol.ts +529 -0
  1117. package/src/worker/resource-facts.ts +79 -0
  1118. package/src/worker/runtime-registry.ts +12 -0
  1119. package/src/worker/spec-contract.ts +675 -0
  1120. package/src/worker/stdin-demux.ts +316 -0
  1121. package/dist/acp-UMLFVA3F.js +0 -92
  1122. package/dist/chunk-262G75JS.js +0 -35
  1123. package/dist/chunk-6CWDTGUC.js +0 -20
  1124. package/dist/chunk-BYEU76JP.js +0 -899
  1125. package/dist/chunk-GNGDQYDU.js +0 -34688
  1126. package/dist/chunk-GOTUR54M.js +0 -9
  1127. package/dist/chunk-NI4DEJMC.js +0 -88
  1128. package/dist/chunk-TPOCL34A.js +0 -2876
  1129. package/dist/chunk-UU3R62TT.js +0 -128
  1130. package/dist/clio-KIQ5SNDS.js +0 -53
  1131. package/dist/configure-G4E3A2PG.js +0 -27
  1132. package/dist/doctor-M5HJJZOL.js +0 -61
  1133. package/dist/domains/agents/builtins/architect.md +0 -33
  1134. package/dist/domains/agents/builtins/coder.md +0 -31
  1135. package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
  1136. package/dist/domains/agents/builtins/debugger.md +0 -30
  1137. package/dist/domains/agents/builtins/documenter.md +0 -31
  1138. package/dist/domains/agents/builtins/git-master.md +0 -30
  1139. package/dist/domains/agents/builtins/provenance.md +0 -30
  1140. package/dist/domains/agents/builtins/researcher.md +0 -71
  1141. package/dist/domains/agents/builtins/scout.md +0 -42
  1142. package/dist/domains/agents/builtins/tester.md +0 -31
  1143. package/dist/domains/agents/builtins/verifier.md +0 -30
  1144. package/dist/domains/agents/builtins/wiki-writer.md +0 -41
  1145. package/dist/fleet-preflight-CLIAX7YR.js +0 -21
  1146. package/dist/preload-KZVHET2B.js +0 -11
  1147. package/dist/version-ROZ6CZKH.js +0 -16
  1148. package/docs/html/agents_blueprint.html +0 -936
  1149. package/docs/html/alcf_blueprint.html +0 -324
  1150. package/docs/html/architecture_blueprint.html +0 -850
  1151. package/docs/html/commands_blueprint.html +0 -794
  1152. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  1153. package/docs/html/configuration_blueprint.html +0 -1080
  1154. package/docs/html/context_blueprint.html +0 -603
  1155. package/docs/html/documentation_blueprint.html +0 -832
  1156. package/docs/html/environment_blueprint.html +0 -404
  1157. package/docs/html/eval_blueprint.html +0 -743
  1158. package/docs/html/evals_internal_blueprint.html +0 -190
  1159. package/docs/html/evolution_blueprint.html +0 -674
  1160. package/docs/html/extensions_blueprint.html +0 -2065
  1161. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  1162. package/docs/html/index.html +0 -919
  1163. package/docs/html/lifecycle_blueprint.html +0 -723
  1164. package/docs/html/memory_blueprint.html +0 -699
  1165. package/docs/html/middleware_blueprint.html +0 -664
  1166. package/docs/html/models_blueprint.html +0 -2366
  1167. package/docs/html/observability_blueprint.html +0 -683
  1168. package/docs/html/provider_adapter_blueprint.html +0 -245
  1169. package/docs/html/safety_blueprint.html +0 -1386
  1170. package/docs/html/shared.css +0 -571
  1171. package/docs/html/shared.js +0 -143
  1172. package/docs/html/skills_blueprint.html +0 -671
  1173. package/docs/html/soak_blueprint.html +0 -182
  1174. package/docs/html/tool_usage_blueprint.html +0 -350
  1175. package/docs/html/tools_blueprint.html +0 -2249
  1176. package/docs/html/trace_blueprint.html +0 -235
  1177. package/docs/html/tui_design_blueprint.html +0 -314
  1178. package/docs/html/validation_blueprint.html +0 -961
  1179. package/docs/html/worker_dispatch_blueprint.html +0 -231
  1180. package/skills/git/commit-crafting/SKILL.md +0 -79
  1181. package/skills/git/commit-crafting/evals.md +0 -92
  1182. package/skills/git/create-pr/SKILL.md +0 -116
  1183. package/skills/git/create-pr/evals.md +0 -114
  1184. package/skills/git/investigate-issue/SKILL.md +0 -139
  1185. package/skills/git/investigate-issue/evals.md +0 -94
  1186. package/skills/git/review-changes/SKILL.md +0 -103
  1187. package/skills/git/review-changes/evals.md +0 -85
@@ -0,0 +1,1079 @@
1
+ /**
2
+ * RouteDecisionV1: the sealed, explainable artifact behind one route choice.
3
+ *
4
+ * A routing decision selects an admissible execution system, not a difficulty
5
+ * label for a prompt. The selectable object is the whole tuple of agent,
6
+ * target, model, runtime, node, and operational composition, and the operator
7
+ * chooses the operating point on the cost-quality-latency frontier by naming a
8
+ * posture.
9
+ *
10
+ * Three invariants hold at every mode:
11
+ *
12
+ * - Hard constraints eliminate. A candidate the admission chain rejected can
13
+ * never appear as `selected` or in `approvedFallbacks`, at any posture,
14
+ * for any score. It stays in `candidateEvaluations` with its reason, which
15
+ * is what makes the decision explainable rather than merely recorded.
16
+ * - The decision is deterministic. `decisionHash` covers the inputs, not the
17
+ * wall clock, so equal inputs produce an equal hash and an offline replay
18
+ * of a stored decision reproduces it exactly.
19
+ * - Shadow mode is advisory. In shadow mode the caller has already resolved
20
+ * and is already executing a route; this module records what the policy
21
+ * would have chosen and never returns anything the caller feeds back into
22
+ * placement. `executedRoute` is carried in the artifact precisely so regret
23
+ * is computable later without re-running the decision.
24
+ *
25
+ * Pure by construction: no I/O, no clock, no engine state.
26
+ */
27
+
28
+ import { createHash } from "node:crypto";
29
+ import { isAgentCapabilityClass } from "../agents/spec.js";
30
+ import type { AgentCandidateEvaluation, AgentRoleReadinessReport } from "./agent-candidates.js";
31
+ import {
32
+ type ExecutionRole,
33
+ gateRouteCorrelation,
34
+ isExecutionRole,
35
+ type RouteCorrelationFacts,
36
+ } from "./execution-role.js";
37
+ import {
38
+ clearsPostureFloors,
39
+ compareRankedRoutes,
40
+ DEFAULT_ROUTE_PRIOR,
41
+ dominatesRoute,
42
+ estimateRoute,
43
+ ROUTE_POLICY_VERSION,
44
+ type RouteEstimate,
45
+ type RoutingPosture,
46
+ routeScoreScale,
47
+ scoreRoute,
48
+ } from "./route-policy.js";
49
+ import { evaluateRouteReadiness, type RouteReadinessReport } from "./route-readiness.js";
50
+
51
+ function routeCorrelationFacts(candidate: RouteCandidate): RouteCorrelationFacts {
52
+ return {
53
+ agentId: candidate.agentId,
54
+ targetId: candidate.targetId,
55
+ wireModelId: candidate.modelId,
56
+ runtimeId: candidate.runtimeId,
57
+ nodeId: candidate.nodeId,
58
+ };
59
+ }
60
+
61
+ /**
62
+ * The unit of selection. It is the agent and its whole operational
63
+ * composition, not a model name: a cheap model that strips the Coder's editing
64
+ * tools is not a cheap route, so the tool surface and prompt composition are
65
+ * part of the candidate's identity.
66
+ */
67
+ export interface RouteCandidate {
68
+ agentId: string;
69
+ specFingerprint: string;
70
+ executionRole: ExecutionRole;
71
+ targetId: string;
72
+ modelId: string;
73
+ runtimeId: string;
74
+ nodeId: string;
75
+ thinkingLevel?: string;
76
+ toolSignature: string;
77
+ promptCompositionHash: string;
78
+ /** Hash of the effective endpoint URL. Raw endpoint data never enters the decision. */
79
+ endpointIdentityHash: string;
80
+ /** Fingerprint of the immutable settings snapshot used to construct this route. */
81
+ settingsFingerprint: string;
82
+ }
83
+
84
+ export type RouteDecisionMode = "fixed" | "shadow" | "active";
85
+
86
+ export type AgentSelectionAuthorityBasis = "operator-plan-approval" | "full-auto-policy";
87
+
88
+ export interface RouteDecisionAgentSelectionInput {
89
+ request: "explicit" | "auto";
90
+ baselineAgentId: string;
91
+ evaluations: ReadonlyArray<AgentCandidateEvaluation>;
92
+ readiness: ReadonlyArray<AgentRoleReadinessReport>;
93
+ authorityBasis: AgentSelectionAuthorityBasis | null;
94
+ }
95
+
96
+ export interface RouteDecisionAgentSelection {
97
+ request: "explicit" | "auto";
98
+ activation: "shadow" | "active";
99
+ baselineAgentId: string;
100
+ recommendedAgentId: string;
101
+ evaluations: AgentCandidateEvaluation[];
102
+ readiness: AgentRoleReadinessReport[];
103
+ /** Input authority provenance is retained even when no transition was selected, so replay can reproduce the hash. */
104
+ authorityBasis: AgentSelectionAuthorityBasis | null;
105
+ authorityTransition: null | {
106
+ from: string;
107
+ to: string;
108
+ basis: "same-authority" | AgentSelectionAuthorityBasis;
109
+ };
110
+ }
111
+
112
+ function exactKeys(value: Record<string, unknown>, keys: ReadonlyArray<string>): boolean {
113
+ return Object.keys(value).sort().join("\u0000") === [...keys].sort().join("\u0000");
114
+ }
115
+
116
+ function decisionRecord(value: unknown): value is Record<string, unknown> {
117
+ return typeof value === "object" && value !== null && !Array.isArray(value);
118
+ }
119
+
120
+ const READINESS_GAPS = new Set([
121
+ "hard-constraint-validity-below-one",
122
+ "integrity-failures-in-window",
123
+ "insufficient-quality-labels",
124
+ "quality-lower-bound-below-posture-floor",
125
+ "quality-lower-bound-below-requested-minimum",
126
+ "reliability-below-posture-floor",
127
+ "cost-upper-bound-unknown",
128
+ "route-facts-stale",
129
+ "decision-latency-above-budget",
130
+ ]);
131
+
132
+ function decisionRouteCandidate(value: unknown): value is RouteCandidate {
133
+ if (!decisionRecord(value)) return false;
134
+ const required = [
135
+ "agentId",
136
+ "specFingerprint",
137
+ "executionRole",
138
+ "targetId",
139
+ "modelId",
140
+ "runtimeId",
141
+ "nodeId",
142
+ "toolSignature",
143
+ "promptCompositionHash",
144
+ "endpointIdentityHash",
145
+ "settingsFingerprint",
146
+ ];
147
+ const keys = Object.keys(value);
148
+ if (keys.some((key) => !required.includes(key) && key !== "thinkingLevel")) return false;
149
+ if (required.some((key) => !Object.hasOwn(value, key))) return false;
150
+ return (
151
+ isExecutionRole(value.executionRole) &&
152
+ required
153
+ .filter((key) => key !== "executionRole")
154
+ .every((key) => typeof value[key] === "string" && String(value[key]).length > 0) &&
155
+ (value.thinkingLevel === undefined || (typeof value.thinkingLevel === "string" && value.thinkingLevel.length > 0))
156
+ );
157
+ }
158
+
159
+ function decisionReadinessReport(value: unknown): value is RouteReadinessReport {
160
+ if (!decisionRecord(value) || !exactKeys(value, ["ready", "gaps", "labelsNeeded"])) return false;
161
+ return (
162
+ typeof value.ready === "boolean" &&
163
+ Array.isArray(value.gaps) &&
164
+ value.gaps.length <= READINESS_GAPS.size &&
165
+ value.gaps.every((gap) => typeof gap === "string" && READINESS_GAPS.has(gap)) &&
166
+ new Set(value.gaps).size === value.gaps.length &&
167
+ value.ready === (value.gaps.length === 0) &&
168
+ Number.isInteger(value.labelsNeeded) &&
169
+ Number(value.labelsNeeded) >= 0
170
+ );
171
+ }
172
+
173
+ /** Strict validator for the required agent-selection evidence sealed in decisions and approvals. */
174
+ export function isRouteDecisionAgentSelection(value: unknown): value is RouteDecisionAgentSelection {
175
+ if (!decisionRecord(value)) return false;
176
+ if (
177
+ !exactKeys(value, [
178
+ "request",
179
+ "activation",
180
+ "baselineAgentId",
181
+ "recommendedAgentId",
182
+ "evaluations",
183
+ "readiness",
184
+ "authorityBasis",
185
+ "authorityTransition",
186
+ ]) ||
187
+ (value.request !== "explicit" && value.request !== "auto") ||
188
+ (value.activation !== "shadow" && value.activation !== "active") ||
189
+ typeof value.baselineAgentId !== "string" ||
190
+ value.baselineAgentId.length === 0 ||
191
+ typeof value.recommendedAgentId !== "string" ||
192
+ value.recommendedAgentId.length === 0 ||
193
+ (value.authorityBasis !== null &&
194
+ value.authorityBasis !== "operator-plan-approval" &&
195
+ value.authorityBasis !== "full-auto-policy") ||
196
+ !Array.isArray(value.evaluations) ||
197
+ value.evaluations.length === 0 ||
198
+ value.evaluations.length > 64 ||
199
+ !Array.isArray(value.readiness) ||
200
+ value.readiness.length === 0 ||
201
+ value.readiness.length > 64
202
+ )
203
+ return false;
204
+ const priorKeys = [
205
+ "qualityMean",
206
+ "firstPassSuccessProbability",
207
+ "costUpperBoundUsd",
208
+ "expectedEndToEndMs",
209
+ "reliability",
210
+ "queueWaitMs",
211
+ ];
212
+ if (
213
+ !value.evaluations.every((entry) => {
214
+ if (
215
+ !decisionRecord(entry) ||
216
+ !exactKeys(entry, [
217
+ "agentId",
218
+ "specFingerprint",
219
+ "executionRole",
220
+ "authority",
221
+ "rejections",
222
+ "coldPrior",
223
+ "priorReasons",
224
+ ])
225
+ )
226
+ return false;
227
+ const prior = entry.coldPrior;
228
+ if (
229
+ typeof entry.agentId !== "string" ||
230
+ entry.agentId.length === 0 ||
231
+ typeof entry.specFingerprint !== "string" ||
232
+ entry.specFingerprint.length === 0 ||
233
+ !isExecutionRole(entry.executionRole) ||
234
+ !isAgentCapabilityClass(entry.authority) ||
235
+ !Array.isArray(entry.rejections) ||
236
+ entry.rejections.length > 64 ||
237
+ !entry.rejections.every((reason) => typeof reason === "string") ||
238
+ !Array.isArray(entry.priorReasons) ||
239
+ entry.priorReasons.length > 64 ||
240
+ !entry.priorReasons.every((reason) => typeof reason === "string") ||
241
+ !decisionRecord(prior) ||
242
+ !exactKeys(prior, priorKeys) ||
243
+ !priorKeys.every((key) => typeof prior[key] === "number" && Number.isFinite(prior[key]))
244
+ )
245
+ return false;
246
+ return true;
247
+ })
248
+ )
249
+ return false;
250
+ if (
251
+ !value.readiness.every((entry) => {
252
+ if (
253
+ !decisionRecord(entry) ||
254
+ !exactKeys(entry, [
255
+ "agentId",
256
+ "specFingerprint",
257
+ "executionRole",
258
+ "ready",
259
+ "candidateCount",
260
+ "readyCandidateCount",
261
+ "routes",
262
+ ])
263
+ )
264
+ return false;
265
+ if (
266
+ !Array.isArray(entry.routes) ||
267
+ entry.routes.length === 0 ||
268
+ entry.routes.length > 64 ||
269
+ !entry.routes.every(
270
+ (route) =>
271
+ decisionRecord(route) &&
272
+ exactKeys(route, ["candidate", "report"]) &&
273
+ decisionRouteCandidate(route.candidate) &&
274
+ decisionReadinessReport(route.report) &&
275
+ route.candidate.agentId === entry.agentId &&
276
+ route.candidate.specFingerprint === entry.specFingerprint &&
277
+ route.candidate.executionRole === entry.executionRole,
278
+ )
279
+ )
280
+ return false;
281
+ const readyCandidateCount = entry.routes.filter(
282
+ (route) => decisionRecord(route) && decisionRecord(route.report) && route.report.ready === true,
283
+ ).length;
284
+ return (
285
+ typeof entry.agentId === "string" &&
286
+ entry.agentId.length > 0 &&
287
+ typeof entry.specFingerprint === "string" &&
288
+ entry.specFingerprint.length > 0 &&
289
+ isExecutionRole(entry.executionRole) &&
290
+ typeof entry.ready === "boolean" &&
291
+ Number.isInteger(entry.candidateCount) &&
292
+ Number(entry.candidateCount) === entry.routes.length &&
293
+ Number.isInteger(entry.readyCandidateCount) &&
294
+ Number(entry.readyCandidateCount) === readyCandidateCount &&
295
+ entry.ready === readyCandidateCount > 0
296
+ );
297
+ })
298
+ )
299
+ return false;
300
+ if (value.authorityTransition !== null) {
301
+ const transition = value.authorityTransition;
302
+ if (
303
+ !decisionRecord(transition) ||
304
+ !exactKeys(transition, ["from", "to", "basis"]) ||
305
+ typeof transition.from !== "string" ||
306
+ transition.from.length === 0 ||
307
+ typeof transition.to !== "string" ||
308
+ transition.to.length === 0 ||
309
+ (transition.basis !== "same-authority" &&
310
+ transition.basis !== "operator-plan-approval" &&
311
+ transition.basis !== "full-auto-policy")
312
+ ) {
313
+ return false;
314
+ }
315
+ if (
316
+ value.request !== "auto" ||
317
+ value.activation !== "active" ||
318
+ transition.from !== value.baselineAgentId ||
319
+ transition.to !== value.recommendedAgentId
320
+ )
321
+ return false;
322
+ const from = value.evaluations.find((entry) => entry.agentId === transition.from);
323
+ const to = value.evaluations.find((entry) => entry.agentId === transition.to);
324
+ if (from === undefined || to === undefined) return false;
325
+ if (transition.basis === "same-authority") {
326
+ if (from.authority !== to.authority) return false;
327
+ } else if (transition.basis !== value.authorityBasis) return false;
328
+ }
329
+ return (
330
+ (value.request !== "explicit" || value.authorityBasis === null) &&
331
+ new Set(
332
+ value.evaluations.map((entry) => `${entry.agentId}\u0000${entry.specFingerprint}\u0000${entry.executionRole}`),
333
+ ).size === value.evaluations.length &&
334
+ value.evaluations.some((entry) => entry.agentId === value.baselineAgentId) &&
335
+ value.evaluations.some((entry) => entry.agentId === value.recommendedAgentId)
336
+ );
337
+ }
338
+
339
+ export interface CandidateEvaluation {
340
+ candidate: RouteCandidate;
341
+ estimate: RouteEstimate;
342
+ /** Exact prerequisite report used by active admission for this tuple. */
343
+ activeReadiness: RouteReadinessReport;
344
+ /** Null when every hard constraint passed; otherwise the constraint that rejected it. */
345
+ rejection: string | null;
346
+ /** Posture score. Null for a rejected candidate: a rejected route is never scored. */
347
+ score: number | null;
348
+ /** True when an admissible candidate is no worse on all three objectives and better on one. */
349
+ dominated: boolean;
350
+ }
351
+
352
+ export interface RouteDecisionV1 {
353
+ policyVersion: string;
354
+ mode: RouteDecisionMode;
355
+ posture: RoutingPosture;
356
+ selected: RouteCandidate;
357
+ approvedFallbacks: RouteCandidate[];
358
+ hardConstraints: string[];
359
+ candidateEvaluations: CandidateEvaluation[];
360
+ reasonCodes: string[];
361
+ decisionDurationMs: number;
362
+ confidence: number;
363
+ decisionHash: string;
364
+ /** Required agent hard-filter, prior, readiness, and authority explanation. */
365
+ agentSelection: RouteDecisionAgentSelection;
366
+ /**
367
+ * The route the caller actually ran. Equal to `selected` at fixed and active
368
+ * mode; in shadow mode it is the production route the decision did not
369
+ * touch, and the pair is what route regret is computed from.
370
+ */
371
+ executedRoute: RouteCandidate;
372
+ }
373
+
374
+ /** Candidate plus verdict, before scoring. The caller owns hard-filter truth. */
375
+ export interface RouteCandidateInput {
376
+ candidate: RouteCandidate;
377
+ estimate: RouteEstimate;
378
+ activeReadiness: RouteReadinessReport;
379
+ rejection: string | null;
380
+ }
381
+
382
+ export interface RouteDecisionInput {
383
+ mode: RouteDecisionMode;
384
+ posture: RoutingPosture;
385
+ /** The route the production pipeline resolved and is executing. */
386
+ executedRoute: RouteCandidate;
387
+ /** Every enumerated tuple with its hard-filter verdict; order is the caller's approval order. */
388
+ candidates: ReadonlyArray<RouteCandidateInput>;
389
+ /** Builder route being judged or reviewed, for the post-filter independence tie-break. */
390
+ independenceSubject: RouteCorrelationFacts | null;
391
+ /** Names of the hard constraints the caller applied, for the explanation. */
392
+ hardConstraints: ReadonlyArray<string>;
393
+ /** Envelope width; the selected route does not count against it. */
394
+ maxFallbacks: number;
395
+ /** Measured resolver duration. Excluded from the hash: it is not an input. */
396
+ decisionDurationMs: number;
397
+ agentSelection: RouteDecisionAgentSelectionInput;
398
+ }
399
+
400
+ /**
401
+ * The dimensions history aggregates over: what the route can do, not how this
402
+ * particular run was worded or configured. Two candidates with equal capability
403
+ * keys are the same route for the purpose of accumulating quality evidence.
404
+ *
405
+ * Editing the session prompt or an unrelated settings key must not restart the
406
+ * evidence count for an unchanged agent, model, runtime, and node. Measured on
407
+ * real history, prompt-composition edits alone sharded 28 observations into
408
+ * buckets no larger than four, which no posture floor can ever clear.
409
+ */
410
+ export function routeCapabilityKey(candidate: RouteCandidate): string {
411
+ return [
412
+ candidate.agentId,
413
+ candidate.specFingerprint,
414
+ candidate.executionRole,
415
+ candidate.targetId,
416
+ candidate.modelId,
417
+ candidate.runtimeId,
418
+ candidate.nodeId,
419
+ candidate.thinkingLevel ?? "",
420
+ ].join("\u0000");
421
+ }
422
+
423
+ /**
424
+ * The remaining identity dimensions. They are sealed on every observation so
425
+ * offline replay reconstructs exactly which prompt and settings produced it,
426
+ * and they are checked for staleness, but they do not create parallel buckets.
427
+ */
428
+ export interface RouteDriftGuard {
429
+ promptCompositionHash: string;
430
+ settingsFingerprint: string;
431
+ toolSignature: string;
432
+ endpointIdentityHash: string;
433
+ }
434
+
435
+ export function routeDriftGuard(candidate: RouteCandidate): RouteDriftGuard {
436
+ return {
437
+ promptCompositionHash: candidate.promptCompositionHash,
438
+ settingsFingerprint: candidate.settingsFingerprint,
439
+ toolSignature: candidate.toolSignature,
440
+ endpointIdentityHash: candidate.endpointIdentityHash,
441
+ };
442
+ }
443
+
444
+ /**
445
+ * Whether drift between an observation and the route being estimated makes that
446
+ * observation stale. The rule is deliberately written out rather than folded
447
+ * into a hash, because which drift matters is a judgement and a hash hides it.
448
+ *
449
+ * Invalidating, because the route no longer does the same work:
450
+ *
451
+ * - `toolSignature`. An agent that gained or lost a tool solves a different
452
+ * problem. Evidence from the old surface does not describe the new one.
453
+ * - `endpointIdentityHash`. The target id is stable but the URL behind it moved,
454
+ * so the observations describe some other physical service.
455
+ *
456
+ * Not invalidating, because the route behaves the same:
457
+ *
458
+ * - `promptCompositionHash`. Session-prompt and skill-framing wording. It
459
+ * changes what the model is told, not what the route is capable of, and it
460
+ * changes on nearly every release.
461
+ * - `settingsFingerprint`. It covers the whole settings snapshot, almost all of
462
+ * which is unrelated to this route. Every part of settings that does change
463
+ * this route's behavior is already in the capability key or in one of the two
464
+ * invalidating guards above, so treating the whole fingerprint as drift only
465
+ * discards evidence for edits to unrelated targets.
466
+ */
467
+ export function routeDriftInvalidates(observed: RouteDriftGuard, current: RouteDriftGuard): boolean {
468
+ return (
469
+ observed.toolSignature !== current.toolSignature || observed.endpointIdentityHash !== current.endpointIdentityHash
470
+ );
471
+ }
472
+
473
+ /** Exact identity of a tuple. Two candidates with equal keys are the same route. */
474
+ export function routeCandidateKey(candidate: RouteCandidate): string {
475
+ return [
476
+ candidate.agentId,
477
+ candidate.specFingerprint,
478
+ candidate.executionRole,
479
+ candidate.targetId,
480
+ candidate.modelId,
481
+ candidate.runtimeId,
482
+ candidate.nodeId,
483
+ candidate.thinkingLevel ?? "",
484
+ candidate.toolSignature,
485
+ candidate.promptCompositionHash,
486
+ candidate.endpointIdentityHash,
487
+ candidate.settingsFingerprint,
488
+ ].join("\u0000");
489
+ }
490
+
491
+ export function sameRouteIdentity(left: RouteCandidate, right: RouteCandidate): boolean {
492
+ return routeCandidateKey(left) === routeCandidateKey(right);
493
+ }
494
+
495
+ /** The route facts a resolved or probed tuple supplies, in the resolver's shape. */
496
+ export interface RouteIdentityInput {
497
+ agentId: string;
498
+ specFingerprint: string;
499
+ targetId: string;
500
+ wireModelId: string;
501
+ runtimeId: string;
502
+ nodeId: string;
503
+ thinkingLevel: string | null;
504
+ toolSignature: string;
505
+ endpointIdentityHash: string;
506
+ settingsFingerprint: string;
507
+ }
508
+
509
+ /**
510
+ * The request facts that decide a tuple's prompt composition. The role itself is
511
+ * derived once by `execution-role.ts` and passed in, so candidate construction
512
+ * cannot invent a second, divergent role policy.
513
+ */
514
+ export interface RouteRoleInput {
515
+ executionRole: ExecutionRole;
516
+ /** Persona override prompt when the request substituted one, else undefined. */
517
+ personaPrompt?: string;
518
+ }
519
+
520
+ /**
521
+ * Prompt composition identity for a tuple that may never have run.
522
+ *
523
+ * The real compiled prompt hash requires composing the prompt, which is async
524
+ * and would multiply the cost of enumerating alternates. This is the identity
525
+ * of the composition's inputs instead: the recipe surface, the tool surface the
526
+ * runtime actually leaves, and any persona override. Two candidates with the
527
+ * same value would compose the same worker prompt, which is the grouping route
528
+ * statistics need, and it is computable for a tuple never dispatched.
529
+ */
530
+ function promptCompositionIdentity(identity: RouteIdentityInput, role: RouteRoleInput): string {
531
+ const persona =
532
+ role.personaPrompt !== undefined ? createHash("sha256").update(role.personaPrompt, "utf8").digest("hex") : null;
533
+ return createHash("sha256")
534
+ .update(
535
+ JSON.stringify({
536
+ specFingerprint: identity.specFingerprint,
537
+ toolSignature: identity.toolSignature,
538
+ persona,
539
+ }),
540
+ "utf8",
541
+ )
542
+ .digest("hex");
543
+ }
544
+
545
+ export function toRouteCandidate(identity: RouteIdentityInput, role: RouteRoleInput): RouteCandidate {
546
+ return {
547
+ agentId: identity.agentId,
548
+ specFingerprint: identity.specFingerprint,
549
+ executionRole: role.executionRole,
550
+ targetId: identity.targetId,
551
+ modelId: identity.wireModelId,
552
+ runtimeId: identity.runtimeId,
553
+ nodeId: identity.nodeId,
554
+ ...(identity.thinkingLevel !== null ? { thinkingLevel: identity.thinkingLevel } : {}),
555
+ toolSignature: identity.toolSignature,
556
+ promptCompositionHash: promptCompositionIdentity(identity, role),
557
+ endpointIdentityHash: identity.endpointIdentityHash,
558
+ settingsFingerprint: identity.settingsFingerprint,
559
+ };
560
+ }
561
+
562
+ function hashNumber(value: number): number {
563
+ if (!Number.isFinite(value)) throw new Error(`route decision: non-finite number ${String(value)}`);
564
+ // Estimates are floats derived from division; a fixed precision keeps the
565
+ // hash stable against the last bits of otherwise-equal computations.
566
+ return Number(value.toFixed(9));
567
+ }
568
+
569
+ function estimateHashProjection(estimate: RouteEstimate): ReadonlyArray<number> {
570
+ return [
571
+ hashNumber(estimate.qualityLabeledCount),
572
+ hashNumber(estimate.unmeasuredCount),
573
+ hashNumber(estimate.qualityCoverage),
574
+ hashNumber(estimate.qualityMean),
575
+ hashNumber(estimate.qualityLowerBound),
576
+ hashNumber(estimate.firstPassSuccessProbability),
577
+ hashNumber(estimate.expectedCostUsd),
578
+ hashNumber(estimate.costUpperBoundUsd),
579
+ hashNumber(estimate.expectedEndToEndMs),
580
+ hashNumber(estimate.p95EndToEndMs),
581
+ hashNumber(estimate.reliability),
582
+ hashNumber(estimate.cacheHitProbability),
583
+ hashNumber(estimate.queueWaitMs),
584
+ hashNumber(estimate.sampleCount),
585
+ hashNumber(estimate.confidence),
586
+ ];
587
+ }
588
+
589
+ function readinessHashProjection(report: RouteReadinessReport): readonly [boolean, ReadonlyArray<string>, number] {
590
+ return [report.ready, report.gaps, hashNumber(report.labelsNeeded)];
591
+ }
592
+
593
+ /**
594
+ * The hash covers exactly the decision's inputs: policy version, mode, posture,
595
+ * the executed route, the enumerated candidates with their estimates and
596
+ * verdicts, the declared hard constraints, and the envelope width. It excludes
597
+ * `decisionDurationMs`, which is a measurement of the decision rather than an
598
+ * input to it, so a replay on a faster machine still reproduces the hash.
599
+ */
600
+ export function routeDecisionHash(input: RouteDecisionInput): string {
601
+ // Arrays give every field an explicit position, so native JSON serialization
602
+ // is deterministic without recursively sorting hundreds of short-lived
603
+ // objects at the maximum universe bound. Candidate identity uses the same
604
+ // exact-route key as admission, ranking, and fallback selection.
605
+ const candidates = input.candidates.map((entry) => [
606
+ routeCandidateKey(entry.candidate),
607
+ estimateHashProjection(entry.estimate),
608
+ readinessHashProjection(entry.activeReadiness),
609
+ entry.rejection,
610
+ ]);
611
+ const agentSelection = [
612
+ input.agentSelection.request,
613
+ input.agentSelection.baselineAgentId,
614
+ input.agentSelection.evaluations.map((entry) => [
615
+ entry.agentId,
616
+ entry.specFingerprint,
617
+ entry.executionRole,
618
+ entry.authority,
619
+ entry.rejections,
620
+ [
621
+ hashNumber(entry.coldPrior.qualityMean),
622
+ hashNumber(entry.coldPrior.firstPassSuccessProbability),
623
+ hashNumber(entry.coldPrior.costUpperBoundUsd),
624
+ hashNumber(entry.coldPrior.expectedEndToEndMs),
625
+ hashNumber(entry.coldPrior.reliability),
626
+ hashNumber(entry.coldPrior.queueWaitMs),
627
+ ],
628
+ entry.priorReasons,
629
+ ]),
630
+ input.agentSelection.readiness.map((entry) => [
631
+ entry.agentId,
632
+ entry.specFingerprint,
633
+ entry.executionRole,
634
+ entry.ready,
635
+ hashNumber(entry.candidateCount),
636
+ hashNumber(entry.readyCandidateCount),
637
+ entry.routes.map((route) => [routeCandidateKey(route.candidate), readinessHashProjection(route.report)]),
638
+ ]),
639
+ input.agentSelection.authorityBasis,
640
+ ];
641
+ const independenceSubject =
642
+ input.independenceSubject === null
643
+ ? null
644
+ : [
645
+ input.independenceSubject.agentId,
646
+ input.independenceSubject.targetId,
647
+ input.independenceSubject.wireModelId,
648
+ input.independenceSubject.runtimeId,
649
+ input.independenceSubject.nodeId,
650
+ ];
651
+ return createHash("sha256")
652
+ .update(
653
+ JSON.stringify([
654
+ ROUTE_POLICY_VERSION,
655
+ input.mode,
656
+ input.posture,
657
+ routeCandidateKey(input.executedRoute),
658
+ candidates,
659
+ independenceSubject,
660
+ agentSelection,
661
+ input.hardConstraints,
662
+ hashNumber(input.maxFallbacks),
663
+ ]),
664
+ "utf8",
665
+ )
666
+ .digest("hex");
667
+ }
668
+
669
+ /**
670
+ * Build the decision.
671
+ *
672
+ * Order of operations is the whole point: hard filters eliminate, then floors
673
+ * eliminate, then the remaining candidates are scored and ordered. A candidate
674
+ * that never cleared a hard filter is scored `null` and cannot reach `selected`
675
+ * or `approvedFallbacks` regardless of how attractive its estimate looks.
676
+ *
677
+ * At `manual` posture the operator named the route, so the executed route is
678
+ * selected and the alternates are recorded but never promoted.
679
+ */
680
+ export function decideRoute(input: RouteDecisionInput): RouteDecisionV1 {
681
+ const reasonCodes: string[] = [];
682
+ const candidateKeys = new Map(input.candidates.map((entry) => [entry, routeCandidateKey(entry.candidate)]));
683
+ const candidateKey = (entry: RouteCandidateInput): string => candidateKeys.get(entry) as string;
684
+ const hardAdmissible = input.candidates.filter((entry) => entry.rejection === null);
685
+ const rejectedCount = input.candidates.length - hardAdmissible.length;
686
+ if (rejectedCount > 0) reasonCodes.push(`hard-filter-rejected-${rejectedCount}`);
687
+ const readinessExcluded =
688
+ input.mode === "active" ? hardAdmissible.filter((entry) => !entry.activeReadiness.ready).length : 0;
689
+ if (readinessExcluded > 0) reasonCodes.push(`active-readiness-excluded-${readinessExcluded}`);
690
+ const admissible =
691
+ input.mode === "active" ? hardAdmissible.filter((entry) => entry.activeReadiness.ready) : hardAdmissible;
692
+
693
+ const scale = routeScoreScale(admissible.map((entry) => entry.estimate));
694
+ const clearing = admissible.filter((entry) => clearsPostureFloors(entry.estimate, input.posture));
695
+ if (clearing.length < admissible.length) {
696
+ reasonCodes.push(`posture-floor-excluded-${admissible.length - clearing.length}`);
697
+ }
698
+ if (clearing.length === 0 && admissible.length > 0) {
699
+ reasonCodes.push("posture-floors-unsatisfiable");
700
+ // Shadow reports the failed floor without changing execution. Active mode
701
+ // must fail closed instead of reviving a merely hard-admissible route.
702
+ if (input.mode === "active") throw new Error("route decision: posture-floors-unsatisfiable");
703
+ }
704
+ const selectable = clearing.length > 0 ? clearing : admissible;
705
+
706
+ // Approval order is the caller's enumeration order, with the resolved route
707
+ // first, so it is the stable tie-break the comparator needs.
708
+ const approvalOrder = new Map(input.candidates.map((entry, index) => [candidateKey(entry), index]));
709
+ const ranked = selectable
710
+ .map((entry) => {
711
+ const key = candidateKey(entry);
712
+ return {
713
+ entry,
714
+ ranked: {
715
+ key,
716
+ order: approvalOrder.get(key) ?? input.candidates.length,
717
+ estimate: entry.estimate,
718
+ score: scoreRoute(entry.estimate, input.posture, scale),
719
+ },
720
+ };
721
+ })
722
+ .sort((left, right) => {
723
+ const policyOrder = compareRankedRoutes(
724
+ { ...left.ranked, key: "", order: 0 },
725
+ { ...right.ranked, key: "", order: 0 },
726
+ );
727
+ if (policyOrder !== 0) return policyOrder;
728
+ if (
729
+ input.independenceSubject !== null &&
730
+ (input.executedRoute.executionRole === "reviewer" || input.executedRoute.executionRole === "judge")
731
+ ) {
732
+ const leftIndependent = gateRouteCorrelation(
733
+ input.independenceSubject,
734
+ routeCorrelationFacts(left.entry.candidate),
735
+ ).independent;
736
+ const rightIndependent = gateRouteCorrelation(
737
+ input.independenceSubject,
738
+ routeCorrelationFacts(right.entry.candidate),
739
+ ).independent;
740
+ if (leftIndependent !== rightIndependent) return leftIndependent ? -1 : 1;
741
+ }
742
+ return compareRankedRoutes(left.ranked, right.ranked);
743
+ });
744
+
745
+ const dominatedKeys = new Set<string>();
746
+ for (const outer of admissible) {
747
+ for (const inner of admissible) {
748
+ if (inner === outer) continue;
749
+ if (dominatesRoute(inner.estimate, outer.estimate)) {
750
+ dominatedKeys.add(candidateKey(outer));
751
+ break;
752
+ }
753
+ }
754
+ }
755
+
756
+ const scores = new Map(ranked.map((entry) => [entry.ranked.key, entry.ranked.score]));
757
+ const candidateEvaluations: CandidateEvaluation[] = input.candidates.map((entry) => {
758
+ const key = candidateKey(entry);
759
+ return {
760
+ candidate: { ...entry.candidate },
761
+ estimate: { ...entry.estimate },
762
+ activeReadiness: { ...entry.activeReadiness, gaps: [...entry.activeReadiness.gaps] },
763
+ rejection: entry.rejection,
764
+ score: entry.rejection === null ? (scores.get(key) ?? null) : null,
765
+ dominated: entry.rejection === null && dominatedKeys.has(key),
766
+ };
767
+ });
768
+
769
+ const executedKey = routeCandidateKey(input.executedRoute);
770
+ const executedAdmissible = admissible.some((entry) => candidateKey(entry) === executedKey);
771
+ const manual = input.posture === "manual";
772
+ const best = ranked[0]?.entry.candidate;
773
+ if (input.mode === "active" && best === undefined) {
774
+ const gaps = hardAdmissible.flatMap((entry) => entry.activeReadiness.gaps);
775
+ const detail = [...new Set(gaps)].join(", ") || "no-hard-admissible-candidate";
776
+ throw new Error(`route decision: no-active-eligible-candidate (${detail})`);
777
+ }
778
+ const selected = manual || best === undefined ? { ...input.executedRoute } : { ...best };
779
+ if (manual) reasonCodes.push("manual-posture-exact-route");
780
+ if (best === undefined) reasonCodes.push("no-admissible-candidate");
781
+ if (!executedAdmissible) reasonCodes.push("executed-route-not-admissible");
782
+ if (input.mode === "shadow") reasonCodes.push("shadow-advisory-only");
783
+ if (input.mode !== "active" && best !== undefined && routeCandidateKey(selected) !== executedKey) {
784
+ reasonCodes.push("shadow-differs-from-executed");
785
+ }
786
+
787
+ const selectedKey = routeCandidateKey(selected);
788
+ const approvedFallbacks: RouteCandidate[] = [];
789
+ if (!manual) {
790
+ for (const entry of ranked) {
791
+ if (approvedFallbacks.length >= Math.max(0, input.maxFallbacks)) break;
792
+ if (entry.ranked.key === selectedKey) continue;
793
+ approvedFallbacks.push({ ...entry.entry.candidate });
794
+ }
795
+ }
796
+
797
+ const selectedEstimate = candidateEvaluations.find(
798
+ (evaluation) => routeCandidateKey(evaluation.candidate) === selectedKey,
799
+ )?.estimate;
800
+ const coldShare =
801
+ admissible.length === 0
802
+ ? 1
803
+ : admissible.filter((entry) => entry.estimate.sampleCount === 0).length / admissible.length;
804
+ const confidence = Math.max(0, Math.min(1, (selectedEstimate?.confidence ?? 0) * (1 - coldShare) + coldShare * 0));
805
+ const recommendedAgentId = best?.agentId ?? input.agentSelection.baselineAgentId;
806
+ let authorityTransition: RouteDecisionAgentSelection["authorityTransition"] = null;
807
+ if (input.mode === "active" && selected.agentId !== input.agentSelection.baselineAgentId) {
808
+ if (input.agentSelection.request !== "auto") {
809
+ throw new Error("route decision: explicit agent selection cannot change authority");
810
+ }
811
+ const from = input.agentSelection.evaluations.find(
812
+ (evaluation) => evaluation.agentId === input.agentSelection.baselineAgentId,
813
+ )?.authority;
814
+ const to = input.agentSelection.evaluations.find((evaluation) => evaluation.agentId === selected.agentId)?.authority;
815
+ const basis =
816
+ from !== undefined && to !== undefined && from === to ? "same-authority" : input.agentSelection.authorityBasis;
817
+ if (basis === null) throw new Error("route decision: active agent authority transition lacks trusted approval");
818
+ authorityTransition = { from: input.agentSelection.baselineAgentId, to: selected.agentId, basis };
819
+ }
820
+
821
+ return {
822
+ policyVersion: ROUTE_POLICY_VERSION,
823
+ mode: input.mode,
824
+ posture: input.posture,
825
+ selected,
826
+ approvedFallbacks,
827
+ hardConstraints: [...input.hardConstraints],
828
+ candidateEvaluations,
829
+ reasonCodes,
830
+ decisionDurationMs: input.decisionDurationMs,
831
+ confidence,
832
+ agentSelection: {
833
+ request: input.agentSelection.request,
834
+ activation: input.mode === "active" ? "active" : "shadow",
835
+ baselineAgentId: input.agentSelection.baselineAgentId,
836
+ recommendedAgentId,
837
+ evaluations: structuredClone([...input.agentSelection.evaluations]),
838
+ readiness: structuredClone([...input.agentSelection.readiness]),
839
+ authorityBasis: input.agentSelection.authorityBasis,
840
+ authorityTransition,
841
+ },
842
+ decisionHash: routeDecisionHash({
843
+ ...input,
844
+ executedRoute: input.mode === "active" ? selected : input.executedRoute,
845
+ }),
846
+ executedRoute: { ...(input.mode === "active" ? selected : input.executedRoute) },
847
+ };
848
+ }
849
+
850
+ /**
851
+ * Failure-isolated production fallback. Observation cannot make a receipt lose
852
+ * its routing evidence, so callers seal this exact one-candidate decision when
853
+ * the shadow observer or its durable inputs fail.
854
+ */
855
+ export function fixedRouteDecision(
856
+ executedRoute: RouteCandidate,
857
+ reasonCode = "observer-failure-fixed-route",
858
+ ): RouteDecisionV1 {
859
+ const estimate = estimateRoute([], DEFAULT_ROUTE_PRIOR);
860
+ const activeReadiness = evaluateRouteReadiness({
861
+ estimate,
862
+ posture: "manual",
863
+ hardConstraintValidity: 1,
864
+ integrityFailures: 0,
865
+ costUpperBoundUsd: null,
866
+ factsFresh: false,
867
+ decisionP95Ms: Number.POSITIVE_INFINITY,
868
+ requestedMinimumQuality: null,
869
+ });
870
+ const input: RouteDecisionInput = {
871
+ mode: "fixed",
872
+ posture: "manual",
873
+ executedRoute,
874
+ candidates: [
875
+ {
876
+ candidate: executedRoute,
877
+ estimate,
878
+ activeReadiness,
879
+ rejection: null,
880
+ },
881
+ ],
882
+ independenceSubject: null,
883
+ hardConstraints: ["fixed-executed-route"],
884
+ maxFallbacks: 0,
885
+ decisionDurationMs: 0,
886
+ agentSelection: {
887
+ request: "explicit",
888
+ baselineAgentId: executedRoute.agentId,
889
+ evaluations: [
890
+ {
891
+ agentId: executedRoute.agentId,
892
+ specFingerprint: executedRoute.specFingerprint,
893
+ executionRole: executedRoute.executionRole,
894
+ authority: "internal",
895
+ rejections: [],
896
+ coldPrior: { ...DEFAULT_ROUTE_PRIOR },
897
+ priorReasons: ["fixed-route"],
898
+ },
899
+ ],
900
+ readiness: [
901
+ {
902
+ agentId: executedRoute.agentId,
903
+ specFingerprint: executedRoute.specFingerprint,
904
+ executionRole: executedRoute.executionRole,
905
+ ready: activeReadiness.ready,
906
+ candidateCount: 1,
907
+ readyCandidateCount: activeReadiness.ready ? 1 : 0,
908
+ routes: [{ candidate: { ...executedRoute }, report: { ...activeReadiness, gaps: [...activeReadiness.gaps] } }],
909
+ },
910
+ ],
911
+ authorityBasis: null,
912
+ },
913
+ };
914
+ const decision = decideRoute(input);
915
+ return { ...decision, reasonCodes: [...decision.reasonCodes, reasonCode] };
916
+ }
917
+
918
+ // ---------------------------------------------------------------------------
919
+ // Decision evaluation, computed from a stored decision and its settled receipt
920
+ // ---------------------------------------------------------------------------
921
+
922
+ /**
923
+ * What the run actually did, read back off its own receipt. Every field here
924
+ * exists on a sealed receipt, which is what lets an offline replay reproduce
925
+ * the metrics below without the process that made the decision.
926
+ */
927
+ export interface RouteRealizedOutcome {
928
+ route: RouteCandidate;
929
+ outcome: string;
930
+ qualityLabel: "pass" | "fail" | "unmeasured";
931
+ /** True when the assignment's first attempt is the one that settled it. */
932
+ firstPass: boolean;
933
+ /** Zero-based attempt index of the settling run. */
934
+ attempt: number;
935
+ costUsd: number;
936
+ endToEndMs: number;
937
+ }
938
+
939
+ /**
940
+ * Distance between the operating point the policy chose and the one that ran.
941
+ * Zero regret means the executed route was the policy's own pick. Regret is
942
+ * measured against the decision's own recorded estimates, never against a
943
+ * re-estimation, so it is stable under replay.
944
+ */
945
+ export interface RouteRegret {
946
+ /** Selected score minus executed score. Zero when they are the same route. */
947
+ score: number;
948
+ /** Selected expected cost minus executed expected cost; negative means the executed route was cheaper. */
949
+ expectedCostUsd: number;
950
+ expectedLatencyMs: number;
951
+ /** True when the executed route was dominated by an admissible alternate. */
952
+ executedOffFrontier: boolean;
953
+ /** True when the policy would have run a different route. */
954
+ routeDiffered: boolean;
955
+ }
956
+
957
+ function evaluationFor(decision: RouteDecisionV1, candidate: RouteCandidate): CandidateEvaluation | undefined {
958
+ const key = routeCandidateKey(candidate);
959
+ return decision.candidateEvaluations.find((evaluation) => routeCandidateKey(evaluation.candidate) === key);
960
+ }
961
+
962
+ function routeRegret(decision: RouteDecisionV1): RouteRegret {
963
+ const selected = evaluationFor(decision, decision.selected);
964
+ const executed = evaluationFor(decision, decision.executedRoute);
965
+ return {
966
+ score: (selected?.score ?? 0) - (executed?.score ?? 0),
967
+ expectedCostUsd: (selected?.estimate.expectedCostUsd ?? 0) - (executed?.estimate.expectedCostUsd ?? 0),
968
+ expectedLatencyMs: (selected?.estimate.expectedEndToEndMs ?? 0) - (executed?.estimate.expectedEndToEndMs ?? 0),
969
+ executedOffFrontier: executed?.dominated ?? false,
970
+ routeDiffered: !sameRouteIdentity(decision.selected, decision.executedRoute),
971
+ };
972
+ }
973
+
974
+ /**
975
+ * Did the decision respect its own hard constraints? This is the check that
976
+ * replaces "did Clio dispatch to the agent it was asked for", which was true by
977
+ * construction and therefore measured nothing.
978
+ */
979
+ export interface RouteConstraintValidity {
980
+ selectedAdmissible: boolean;
981
+ executedAdmissible: boolean;
982
+ fallbacksAdmissible: boolean;
983
+ /** True when all three hold, which is the invariant the router must never break. */
984
+ valid: boolean;
985
+ }
986
+
987
+ export function routeConstraintValidity(decision: RouteDecisionV1): RouteConstraintValidity {
988
+ const admissible = (candidate: RouteCandidate): boolean => evaluationFor(decision, candidate)?.rejection === null;
989
+ const selectedAdmissible = admissible(decision.selected);
990
+ const executedAdmissible = admissible(decision.executedRoute);
991
+ const fallbacksAdmissible = decision.approvedFallbacks.every(admissible);
992
+ return {
993
+ selectedAdmissible,
994
+ executedAdmissible,
995
+ fallbacksAdmissible,
996
+ valid: selectedAdmissible && executedAdmissible && fallbacksAdmissible,
997
+ };
998
+ }
999
+
1000
+ /**
1001
+ * How wrong the estimate for the route that actually ran turned out to be.
1002
+ * Ratios are reported alongside absolute errors because a $0.01 miss on a $0.02
1003
+ * route and a $0.01 miss on a $5 route are not the same kind of wrong.
1004
+ */
1005
+ export interface RoutePredictionCalibration {
1006
+ costErrorUsd: number;
1007
+ costRatio: number;
1008
+ latencyErrorMs: number;
1009
+ latencyRatio: number;
1010
+ /** Squared error of the quality estimate against a measured label; null when unmeasured. */
1011
+ qualityBrier: number | null;
1012
+ firstPassBrier: number;
1013
+ /** Samples that backed the executed route's estimate at decision time. */
1014
+ sampleCount: number;
1015
+ }
1016
+
1017
+ function ratio(actual: number, expected: number): number {
1018
+ if (expected === 0) return actual === 0 ? 1 : Number.POSITIVE_INFINITY;
1019
+ return actual / expected;
1020
+ }
1021
+
1022
+ function routePredictionCalibration(
1023
+ decision: RouteDecisionV1,
1024
+ realized: RouteRealizedOutcome,
1025
+ ): RoutePredictionCalibration {
1026
+ const executed = evaluationFor(decision, realized.route);
1027
+ const estimate = executed?.estimate;
1028
+ const quality = realized.qualityLabel === "unmeasured" ? null : realized.qualityLabel === "pass" ? 1 : 0;
1029
+ const firstPass = realized.firstPass ? 1 : 0;
1030
+ return {
1031
+ costErrorUsd: realized.costUsd - (estimate?.expectedCostUsd ?? 0),
1032
+ costRatio: ratio(realized.costUsd, estimate?.expectedCostUsd ?? 0),
1033
+ latencyErrorMs: realized.endToEndMs - (estimate?.expectedEndToEndMs ?? 0),
1034
+ latencyRatio: ratio(realized.endToEndMs, estimate?.expectedEndToEndMs ?? 0),
1035
+ qualityBrier: quality === null ? null : (quality - (estimate?.qualityMean ?? 0)) ** 2,
1036
+ firstPassBrier: (firstPass - (estimate?.firstPassSuccessProbability ?? 0)) ** 2,
1037
+ sampleCount: estimate?.sampleCount ?? 0,
1038
+ };
1039
+ }
1040
+
1041
+ /** What the run produced, independent of what any router predicted. */
1042
+ export interface RouteOutcomeMetrics {
1043
+ outcome: string;
1044
+ qualityLabel: "pass" | "fail" | "unmeasured";
1045
+ firstPass: boolean;
1046
+ escalated: boolean;
1047
+ attempts: number;
1048
+ costUsd: number;
1049
+ endToEndMs: number;
1050
+ }
1051
+
1052
+ function routeOutcomeMetrics(realized: RouteRealizedOutcome): RouteOutcomeMetrics {
1053
+ return {
1054
+ outcome: realized.outcome,
1055
+ qualityLabel: realized.qualityLabel,
1056
+ firstPass: realized.firstPass,
1057
+ escalated: realized.attempt > 0,
1058
+ attempts: realized.attempt + 1,
1059
+ costUsd: realized.costUsd,
1060
+ endToEndMs: realized.endToEndMs,
1061
+ };
1062
+ }
1063
+
1064
+ /** The four evaluation families for one settled decision, in one record. */
1065
+ export interface RouteEvaluation {
1066
+ regret: RouteRegret;
1067
+ validity: RouteConstraintValidity;
1068
+ calibration: RoutePredictionCalibration;
1069
+ outcome: RouteOutcomeMetrics;
1070
+ }
1071
+
1072
+ export function evaluateRouteDecision(decision: RouteDecisionV1, realized: RouteRealizedOutcome): RouteEvaluation {
1073
+ return {
1074
+ regret: routeRegret(decision),
1075
+ validity: routeConstraintValidity(decision),
1076
+ calibration: routePredictionCalibration(decision, realized),
1077
+ outcome: routeOutcomeMetrics(realized),
1078
+ };
1079
+ }