@iowarp/clio-coder 0.3.8 → 0.4.0

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 (552) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/NOTICE +33 -0
  3. package/README.md +12 -3
  4. package/dist/{acp-U67UHUK2.js → acp-G5WJBNCT.js} +13 -12
  5. package/dist/{agents-YU6SGALZ.js → agents-FMV2Q5G4.js} +41 -36
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-5ZPJOIVG.js → auth-3IDSJEIK.js} +18 -18
  8. package/dist/{builtins-C6JMZVV6.js → builtins-XCZWXSC7.js} +5 -5
  9. package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
  10. package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
  11. package/dist/{chunk-XWSF374K.js → chunk-2OQE55CK.js} +3 -3
  12. package/dist/{chunk-5H3GB5BO.js → chunk-32KWKNSF.js} +8 -384
  13. package/dist/{chunk-KTYTFRMB.js → chunk-36EJLSQQ.js} +34 -36
  14. package/dist/{chunk-FHJEP5SW.js → chunk-3BT2XMV4.js} +19 -13
  15. package/dist/chunk-3DPEIQKN.js +113 -0
  16. package/dist/{chunk-GU2UIAFZ.js → chunk-3URVFKWK.js} +7 -7
  17. package/dist/{chunk-WEH5XRJQ.js → chunk-3XML7CDN.js} +3 -3
  18. package/dist/chunk-42FMPA75.js +101 -0
  19. package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
  20. package/dist/{chunk-VCBR6CU7.js → chunk-5PSMVOLM.js} +2 -2
  21. package/dist/{chunk-NMPKI6XL.js → chunk-6DB53AJS.js} +203 -25
  22. package/dist/{chunk-3BINW3FP.js → chunk-76ONBSIA.js} +2 -2
  23. package/dist/{chunk-26LEYJZH.js → chunk-7MCTRUCE.js} +2 -2
  24. package/dist/{chunk-TYPGUK6W.js → chunk-AB44T6BB.js} +111 -5
  25. package/dist/{chunk-K4XHGFR5.js → chunk-B7OBL7PK.js} +317 -721
  26. package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
  27. package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
  28. package/dist/{chunk-ZVJ5BLO2.js → chunk-BKFJHQCA.js} +154 -16
  29. package/dist/chunk-BKFM6EJV.js +462 -0
  30. package/dist/chunk-BMS5RKQY.js +27 -0
  31. package/dist/{chunk-ZNLWCMVZ.js → chunk-BPKCPIL7.js} +2 -2
  32. package/dist/{chunk-TLQJPP24.js → chunk-BUMFYQFY.js} +1394 -1349
  33. package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
  34. package/dist/chunk-C2LTL2W6.js +2447 -0
  35. package/dist/{chunk-ME6CCNFO.js → chunk-CODPRO7Q.js} +8 -8
  36. package/dist/{chunk-E77JEWSD.js → chunk-CTJ4RNAA.js} +7 -37
  37. package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
  38. package/dist/{chunk-7RFXX52T.js → chunk-DQITNCXG.js} +642 -172
  39. package/dist/{chunk-TTHACPOM.js → chunk-DYJP44XW.js} +578 -117
  40. package/dist/{chunk-2HFZQUHL.js → chunk-F4CKPOEQ.js} +18 -8
  41. package/dist/{chunk-DGSYXYMX.js → chunk-FEFIFZTL.js} +3 -3
  42. package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
  43. package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
  44. package/dist/chunk-GKF55TAZ.js +391 -0
  45. package/dist/{chunk-VWZOAB7K.js → chunk-GR5G2PVF.js} +9 -8
  46. package/dist/{chunk-4DGYLA73.js → chunk-GXNLGKAB.js} +80 -9
  47. package/dist/chunk-HHV2GANA.js +88 -0
  48. package/dist/{chunk-IIZWH4XA.js → chunk-HI63TFOG.js} +5 -4
  49. package/dist/{chunk-WLFILSD5.js → chunk-HJJTYUHX.js} +113 -83
  50. package/dist/{chunk-TT36MB5S.js → chunk-HLW2MRKE.js} +3 -1
  51. package/dist/{chunk-PMDBGQSJ.js → chunk-HWHKMHUA.js} +7 -7
  52. package/dist/chunk-HZHHCK24.js +1631 -0
  53. package/dist/{chunk-WSB3FPX7.js → chunk-I5VEOC6I.js} +39 -143
  54. package/dist/chunk-IBEBSCYA.js +564 -0
  55. package/dist/chunk-IQ7KR472.js +362 -0
  56. package/dist/{chunk-A3WNZD3P.js → chunk-J4W7KFM7.js} +949 -972
  57. package/dist/{chunk-TB5666IT.js → chunk-JDG2WCRO.js} +5 -5
  58. package/dist/{chunk-N22QMJKY.js → chunk-K5C3NCBD.js} +4 -4
  59. package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
  60. package/dist/{chunk-5C3AQNDW.js → chunk-KFZI4NIL.js} +216 -38
  61. package/dist/chunk-KMVISBZR.js +132 -0
  62. package/dist/{chunk-WXY7KU3G.js → chunk-LDQ2ZF2M.js} +2 -2
  63. package/dist/{chunk-XN3L4EYL.js → chunk-LQ3DZAMX.js} +3 -3
  64. package/dist/{chunk-U6MBIEMB.js → chunk-LY4S7GJC.js} +173 -144
  65. package/dist/{chunk-4SPRNWDE.js → chunk-MLKNTWH2.js} +19 -19
  66. package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
  67. package/dist/chunk-NEKRRTYW.js +56 -0
  68. package/dist/{chunk-SPULKLCF.js → chunk-NHCZP4K7.js} +3 -3
  69. package/dist/chunk-NHLBIGRH.js +1506 -0
  70. package/dist/chunk-NQQH3YT7.js +302 -0
  71. package/dist/chunk-NYS75XW5.js +15 -0
  72. package/dist/{chunk-GN57SG4G.js → chunk-O4XIVISU.js} +10 -8
  73. package/dist/{chunk-EMYUUSFG.js → chunk-O6TL7WWY.js} +6 -6
  74. package/dist/chunk-OQBA45DZ.js +97 -0
  75. package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
  76. package/dist/chunk-PMZCIOCJ.js +25 -0
  77. package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
  78. package/dist/{chunk-J3YUBZWY.js → chunk-QBJA7R7N.js} +62 -6
  79. package/dist/chunk-QDC3K2U3.js +262 -0
  80. package/dist/{chunk-2HEJ2F35.js → chunk-QLFS5GO2.js} +22 -10
  81. package/dist/{chunk-7RGZWPB6.js → chunk-QLL7ILRG.js} +95 -32
  82. package/dist/{chunk-YS5VLNH5.js → chunk-QREDIESB.js} +6 -6
  83. package/dist/chunk-QSNYB6ZV.js +195 -0
  84. package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
  85. package/dist/chunk-RKKLTLYB.js +45 -0
  86. package/dist/{chunk-P43ETTHK.js → chunk-SJ5ZKQ4S.js} +2 -2
  87. package/dist/{chunk-GPIEI3LY.js → chunk-SP2RXXYO.js} +6 -54
  88. package/dist/chunk-SUCTJL45.js +45 -0
  89. package/dist/{chunk-DYIM5TJT.js → chunk-SUW5DORT.js} +263 -7
  90. package/dist/chunk-T56WDKA5.js +183 -0
  91. package/dist/chunk-TVHHYFHE.js +255 -0
  92. package/dist/{chunk-FJ3H4MN5.js → chunk-TZ3SGWZZ.js} +3 -3
  93. package/dist/{chunk-MXKJU4JB.js → chunk-U77AMWDL.js} +91 -10
  94. package/dist/{chunk-5DHKRSMQ.js → chunk-ULC6OTWO.js} +11 -7
  95. package/dist/{chunk-RWSI4YD7.js → chunk-UM7N4G5A.js} +33 -12
  96. package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
  97. package/dist/{chunk-IGWKHNIQ.js → chunk-UXMFQ54G.js} +44 -37
  98. package/dist/{chunk-HFSBBKSQ.js → chunk-V5DHCITQ.js} +171 -3
  99. package/dist/{chunk-5WIGXA4T.js → chunk-VAZSBTKF.js} +111 -4
  100. package/dist/{chunk-VHN4MY6O.js → chunk-VEO4AP2K.js} +2 -2
  101. package/dist/{chunk-IJ7RPIYJ.js → chunk-VFA6GDY5.js} +65 -4
  102. package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
  103. package/dist/chunk-VO67MWHC.js +75 -0
  104. package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
  105. package/dist/{chunk-TANS5ZJS.js → chunk-VYMXRQI6.js} +36 -22
  106. package/dist/{chunk-WWCZ5F23.js → chunk-W5VSYASO.js} +77 -16
  107. package/dist/{chunk-WNIJTQQK.js → chunk-WZR7K7ZX.js} +72 -116
  108. package/dist/{chunk-5Q2VVUKB.js → chunk-X3YGUTOB.js} +4 -4
  109. package/dist/chunk-X75E3D2N.js +686 -0
  110. package/dist/{chunk-VAWNZU7Z.js → chunk-YDFRH54B.js} +4 -4
  111. package/dist/chunk-YJX4SHTD.js +40 -0
  112. package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
  113. package/dist/chunk-Z2RR6MAK.js +127 -0
  114. package/dist/{chunk-FBVTI2TJ.js → chunk-Z4TXYIEG.js} +12 -131
  115. package/dist/cli/index.js +47 -36
  116. package/dist/{clio-QVTYJ57A.js → clio-2JXHBBY5.js} +7 -7
  117. package/dist/{code-nav-FGGFIE7L.js → code-nav-3YYRMYNF.js} +8 -8
  118. package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
  119. package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
  120. package/dist/{config-LW5IJFQN.js → config-QZPCMYSO.js} +99 -63
  121. package/dist/{configure-7XIZCOU4.js → configure-TEGEBYCA.js} +23 -22
  122. package/dist/{context-Y6Y7QPR6.js → context-AV7OEZ4D.js} +12 -12
  123. package/dist/{context-L3WL3X7K.js → context-E6H5RNMC.js} +56 -47
  124. package/dist/{context-N52ZA626.js → context-GSXUE4CT.js} +29 -27
  125. package/dist/{context-clear-MBQRLSDQ.js → context-clear-SHIBYK6T.js} +55 -46
  126. package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
  127. package/dist/{context-working-set-GS6DSO7F.js → context-working-set-5ZGKPGZQ.js} +13 -13
  128. package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-EFMJT4LD.js} +93 -64
  129. package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
  130. package/dist/doctor-QOA5FNY5.js +313 -0
  131. package/dist/{eval-BEC2WHDA.js → eval-TFBYQH4H.js} +2032 -156
  132. package/dist/eval-inventory-SXH7PDKX.js +316 -0
  133. package/dist/{evidence-REJUMSKM.js → evidence-ERGESKGN.js} +203 -48
  134. package/dist/{evolve-PY5ZBA5K.js → evolve-VDXTSYCJ.js} +52 -43
  135. package/dist/{extensions-HVKU65YU.js → extensions-7BGBHN57.js} +13 -7
  136. package/dist/{fleet-7WZEWRFA.js → fleet-2RRVDF2V.js} +228 -108
  137. package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-VJ726XIA.js} +11 -11
  138. package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
  139. package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-JF5QOATM.js} +18 -15
  140. package/dist/fleet-inspect-VLY4S7QM.js +442 -0
  141. package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-AIZUEJOY.js} +5 -5
  142. package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-AJRPDMDV.js} +22 -19
  143. package/dist/fleet-verify-JFEL2L3H.js +175 -0
  144. package/dist/fleet-view-ZCON35AG.js +102 -0
  145. package/dist/{init-OG3TPGQG.js → init-DN2WWLFE.js} +72 -62
  146. package/dist/install-XGLBQY5E.js +13 -0
  147. package/dist/interop-OZBKXAYL.js +114 -0
  148. package/dist/{library-CNTMPLRF.js → library-YWZG7IMW.js} +21 -18
  149. package/dist/{memory-6IS7F275.js → memory-I4C4HMLW.js} +54 -45
  150. package/dist/{models-ENRJDA5W.js → models-CEYXJBO6.js} +33 -30
  151. package/dist/{monitor-XLDVO7TN.js → monitor-NZ6GCI3P.js} +59 -52
  152. package/dist/{orchestrator-6KSPYRHA.js → orchestrator-GCGQ4N5I.js} +7827 -7328
  153. package/dist/panes-HMABYVO4.js +58 -0
  154. package/dist/panes-KY6W3V2E.js +103 -0
  155. package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
  156. package/dist/{reset-RZ4ER727.js → reset-DQ6FGCSH.js} +13 -11
  157. package/dist/resources-BB3MVJMD.js +111 -0
  158. package/dist/{run-Y2CNK5RU.js → run-H2GQDUER.js} +119 -87
  159. package/dist/{share-A55GYP6Z.js → share-GTJN6A5O.js} +20 -17
  160. package/dist/{skills-ALC5J6AT.js → skills-L55TEW6R.js} +33 -24
  161. package/dist/{skills-eval-JPBEBYQU.js → skills-eval-XVXPH2JI.js} +67 -56
  162. package/dist/skills-inventory-S4MXPJFV.js +126 -0
  163. package/dist/slash-commands-ZSGASKJC.js +77 -0
  164. package/dist/{steer-GGWFUJUD.js → steer-RZGSCY4R.js} +4 -4
  165. package/dist/{support-MIETYA5E.js → support-PKEUNNQL.js} +6 -6
  166. package/dist/{targets-VGNXIR3S.js → targets-NCPZ644J.js} +68 -40
  167. package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-44SV3YCN.js} +6 -4
  168. package/dist/tools-DAF3DI3C.js +27 -0
  169. package/dist/{trace-PNCASAXC.js → trace-FYVW2MQA.js} +207 -10
  170. package/dist/tui-primitives-2AKXQNZK.js +13 -0
  171. package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
  172. package/dist/{upgrade-FUSUAGHR.js → upgrade-3XPP6OQL.js} +27 -24
  173. package/dist/{usage-N4MKVHKD.js → usage-3NLHGTU2.js} +114 -62
  174. package/dist/{verifiers-YAWOJ3H2.js → verifiers-SSQONKRT.js} +172 -13
  175. package/dist/{verify-LTDHYBGY.js → verify-3U6J7FZI.js} +10 -10
  176. package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
  177. package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-CEHYGPGQ.js} +75 -65
  178. package/dist/with-panes-MKB46MPQ.js +782 -0
  179. package/dist/worker/entry.js +106 -75
  180. package/docs/README.md +3 -2
  181. package/docs/acp.md +24 -3
  182. package/docs/alcf-provider.md +1 -1
  183. package/docs/architecture.md +2 -2
  184. package/docs/artifact-versions.md +9 -1
  185. package/docs/built-in-agents.md +1 -1
  186. package/docs/capacity-and-scheduling.md +62 -3
  187. package/docs/commands-and-modes.md +31 -2
  188. package/docs/configuration-and-targets.md +69 -12
  189. package/docs/context-engine.md +63 -4
  190. package/docs/development-pipeline.md +19 -0
  191. package/docs/dispatch-typed-intent.md +385 -0
  192. package/docs/documentation-coverage.md +5 -5
  193. package/docs/documentation-guide.md +1 -1
  194. package/docs/environment-variables.md +3 -0
  195. package/docs/eval-runner.md +262 -11
  196. package/docs/evals-internal.md +72 -2
  197. package/docs/evidence-and-memory.md +12 -11
  198. package/docs/evolution.md +1 -1
  199. package/docs/exit-codes-and-output.md +1 -1
  200. package/docs/extensions-and-sharing.md +27 -1
  201. package/docs/fleet-dispatch.md +25 -4
  202. package/docs/installation-and-lifecycle.md +15 -2
  203. package/docs/middleware-and-components.md +1 -1
  204. package/docs/model-catalog.md +10 -1
  205. package/docs/observability.md +55 -4
  206. package/docs/proactive-memory.md +127 -14
  207. package/docs/prompt-envelope-and-tools.md +19 -1
  208. package/docs/provider-adapter-cookbook.md +1 -1
  209. package/docs/release-cut-checklist.md +19 -3
  210. package/docs/safety-model.md +2 -2
  211. package/docs/scientific-validation.md +3 -3
  212. package/docs/session-lifecycle.md +1 -1
  213. package/docs/skills-marketplace.md +1 -1
  214. package/docs/tool-usage.md +18 -8
  215. package/docs/trace-store.md +1 -1
  216. package/docs/troubleshooting.md +88 -1
  217. package/docs/tui-design.md +1 -1
  218. package/docs/worker-dispatch-mechanics.md +1 -1
  219. package/package.json +5 -2
  220. package/src/cli/acp.ts +6 -2
  221. package/src/cli/agents.ts +1 -1
  222. package/src/cli/argv.ts +25 -0
  223. package/src/cli/config-inspect.ts +33 -6
  224. package/src/cli/config.ts +1 -1
  225. package/src/cli/configure.ts +23 -21
  226. package/src/cli/doctor-panes.ts +124 -0
  227. package/src/cli/doctor-state-size.ts +82 -0
  228. package/src/cli/doctor-toolchain.ts +57 -0
  229. package/src/cli/doctor.ts +22 -1
  230. package/src/cli/eval-inventory.ts +436 -0
  231. package/src/cli/eval.ts +93 -16
  232. package/src/cli/evidence-detail.ts +88 -0
  233. package/src/cli/evidence-inventory.ts +183 -0
  234. package/src/cli/evidence.ts +30 -5
  235. package/src/cli/extensions.ts +5 -1
  236. package/src/cli/fleet-decisions.ts +69 -0
  237. package/src/cli/fleet-inspect.ts +334 -0
  238. package/src/cli/fleet-verify.ts +133 -0
  239. package/src/cli/fleet-view.ts +810 -0
  240. package/src/cli/fleet.ts +179 -39
  241. package/src/cli/index.ts +14 -2
  242. package/src/cli/interop-inspect.ts +128 -0
  243. package/src/cli/interop.ts +34 -0
  244. package/src/cli/panes.ts +35 -0
  245. package/src/cli/reset.ts +5 -2
  246. package/src/cli/run.ts +58 -0
  247. package/src/cli/skills-inventory.ts +185 -0
  248. package/src/cli/skills.ts +16 -13
  249. package/src/cli/targets.ts +44 -13
  250. package/src/cli/tools.ts +321 -0
  251. package/src/cli/trace-inspect.ts +252 -0
  252. package/src/cli/trace.ts +85 -5
  253. package/src/cli/usage.ts +63 -14
  254. package/src/cli/verifiers-inspect.ts +347 -0
  255. package/src/cli/verifiers.ts +9 -0
  256. package/src/core/bus-events.ts +33 -1
  257. package/src/core/cache-telemetry.ts +42 -0
  258. package/src/core/config.ts +67 -0
  259. package/src/core/defaults.ts +124 -8
  260. package/src/core/endpoint-key.ts +27 -0
  261. package/src/core/residency-target-key.ts +25 -0
  262. package/src/core/response-schema.ts +80 -6
  263. package/src/core/theme-token-hex.ts +43 -0
  264. package/src/core/tool-names.ts +2 -1
  265. package/src/core/xdg.ts +1 -1
  266. package/src/domains/agents/fleets/build-review.md +0 -3
  267. package/src/domains/agents/fleets/build-test.md +0 -3
  268. package/src/domains/agents/result-contract-filesystem.ts +32 -0
  269. package/src/domains/agents/result-contract.ts +164 -35
  270. package/src/domains/config/classify.ts +6 -0
  271. package/src/domains/context/codewiki/coordinator.ts +12 -4
  272. package/src/domains/dispatch/admission-error.ts +9 -0
  273. package/src/domains/dispatch/admission.ts +52 -14
  274. package/src/domains/dispatch/capacity-lease.ts +118 -9
  275. package/src/domains/dispatch/contract.ts +11 -0
  276. package/src/domains/dispatch/council-topology.ts +398 -0
  277. package/src/domains/dispatch/execution-plan.ts +44 -4
  278. package/src/domains/dispatch/extension.ts +378 -82
  279. package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
  280. package/src/domains/dispatch/fleet-plan.ts +7 -2
  281. package/src/domains/dispatch/fleet-run.ts +87 -4
  282. package/src/domains/dispatch/gate-decisions.ts +11 -1
  283. package/src/domains/dispatch/gate-role-prompts.ts +9 -0
  284. package/src/domains/dispatch/gate-topology.ts +289 -0
  285. package/src/domains/dispatch/heartbeat.ts +32 -8
  286. package/src/domains/dispatch/index.ts +22 -0
  287. package/src/domains/dispatch/intent-compatibility.ts +330 -0
  288. package/src/domains/dispatch/intent.ts +85 -1
  289. package/src/domains/dispatch/orphan-recovery.ts +5 -0
  290. package/src/domains/dispatch/reservation-store.ts +139 -11
  291. package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
  292. package/src/domains/dispatch/run-event-journal.ts +598 -0
  293. package/src/domains/dispatch/state.ts +49 -1
  294. package/src/domains/dispatch/types.ts +13 -0
  295. package/src/domains/dispatch/validation.ts +33 -8
  296. package/src/domains/dispatch/worker-spawn.ts +25 -11
  297. package/src/domains/dispatch/write-boundary-enforcer.ts +20 -3
  298. package/src/domains/dispatch/write-boundary.ts +62 -1
  299. package/src/domains/eval/artifacts/store.ts +62 -0
  300. package/src/domains/eval/compare/behavioral.ts +224 -0
  301. package/src/domains/eval/compare/compare.ts +342 -2
  302. package/src/domains/eval/compare/envelope.ts +128 -0
  303. package/src/domains/eval/compare/gates.ts +24 -6
  304. package/src/domains/eval/compare/thresholds.ts +30 -3
  305. package/src/domains/eval/execution-provenance.ts +240 -0
  306. package/src/domains/eval/inventory.ts +113 -0
  307. package/src/domains/eval/metrics/aggregate.ts +136 -0
  308. package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
  309. package/src/domains/eval/metrics/tracked.ts +413 -0
  310. package/src/domains/eval/provenance.ts +117 -0
  311. package/src/domains/eval/reports/comparison.ts +128 -0
  312. package/src/domains/eval/reports/junit.ts +17 -3
  313. package/src/domains/eval/reports/markdown.ts +3 -3
  314. package/src/domains/eval/reports/text.ts +14 -0
  315. package/src/domains/eval/run-compare.ts +20 -0
  316. package/src/domains/eval/runners/clio-run.ts +127 -0
  317. package/src/domains/eval/runners/external-command.ts +28 -3
  318. package/src/domains/eval/schema/adapter.ts +111 -0
  319. package/src/domains/eval/schema/artifact.ts +20 -0
  320. package/src/domains/eval/schema/behavioral-metrics.ts +204 -0
  321. package/src/domains/eval/schema/behavioral.ts +520 -0
  322. package/src/domains/eval/schema/execution-envelope.ts +194 -0
  323. package/src/domains/eval/schema/serving.ts +105 -0
  324. package/src/domains/eval/schema/suite.ts +38 -8
  325. package/src/domains/eval/schema/validate.ts +58 -3
  326. package/src/domains/eval/schema/verdict.ts +237 -0
  327. package/src/domains/eval/suites/resolve.ts +2 -0
  328. package/src/domains/eval/suites/run.ts +264 -33
  329. package/src/domains/eval/verifiers/command.ts +2 -1
  330. package/src/domains/eval/workspaces/temp-copy.ts +145 -13
  331. package/src/domains/evidence/build.ts +2 -13
  332. package/src/domains/evidence/eval.ts +2 -12
  333. package/src/domains/evidence/findings-markdown.ts +33 -0
  334. package/src/domains/evidence/run-trust.ts +7 -113
  335. package/src/domains/evidence/store.ts +6 -0
  336. package/src/domains/evidence/trust-projection.ts +2 -2
  337. package/src/domains/extensions/compatibility.ts +285 -0
  338. package/src/domains/extensions/discovery.ts +38 -3
  339. package/src/domains/extensions/resources.ts +1 -1
  340. package/src/domains/extensions/state.ts +12 -3
  341. package/src/domains/extensions/types.ts +2 -0
  342. package/src/domains/lifecycle/doctor.ts +69 -1
  343. package/src/domains/memory/index.ts +14 -1
  344. package/src/domains/memory/task-bank-promotion.ts +64 -0
  345. package/src/domains/memory/task-memory-policy.ts +82 -17
  346. package/src/domains/memory/task-memory-spend.ts +131 -0
  347. package/src/domains/memory/task-memory-status.ts +7 -0
  348. package/src/domains/memory/task-memory-telemetry.ts +3 -0
  349. package/src/domains/middleware/index.ts +1 -0
  350. package/src/domains/middleware/memory-intervention.ts +97 -21
  351. package/src/domains/middleware/memory-step-endpoint.ts +71 -0
  352. package/src/domains/mux/contract.ts +434 -0
  353. package/src/domains/mux/detect.ts +158 -0
  354. package/src/domains/mux/extension.ts +47 -0
  355. package/src/domains/mux/index.ts +96 -0
  356. package/src/domains/mux/manifest.ts +6 -0
  357. package/src/domains/mux/operations.ts +164 -0
  358. package/src/domains/mux/pane-registry.ts +90 -0
  359. package/src/domains/mux/protocol.ts +49 -0
  360. package/src/domains/mux/socket-client.ts +816 -0
  361. package/src/domains/mux/types.ts +222 -0
  362. package/src/domains/mux/viewer-command.ts +59 -0
  363. package/src/domains/mux/yazi/assets/init.lua +2 -0
  364. package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
  365. package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
  366. package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
  367. package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
  368. package/src/domains/mux/yazi/assets/yazi.toml +17 -0
  369. package/src/domains/mux/yazi/event-stream.ts +180 -0
  370. package/src/domains/mux/yazi/profile.ts +299 -0
  371. package/src/domains/mux/yazi/session.ts +228 -0
  372. package/src/domains/mux/yazi/theme.ts +30 -0
  373. package/src/domains/observability/background-memory-usage.ts +140 -0
  374. package/src/domains/observability/cost.ts +22 -1
  375. package/src/domains/observability/index.ts +9 -0
  376. package/src/domains/observability/out-of-turn-usage.ts +51 -2
  377. package/src/domains/observability/trace-store.ts +234 -2
  378. package/src/domains/prompts/compiler.ts +100 -13
  379. package/src/domains/providers/endpoint-capacity.ts +228 -0
  380. package/src/domains/providers/endpoint-slots-store.ts +189 -0
  381. package/src/domains/providers/extension.ts +20 -3
  382. package/src/domains/providers/index.ts +32 -0
  383. package/src/domains/providers/model-runtime-capabilities.ts +32 -0
  384. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +243 -1
  385. package/src/domains/providers/runtime-resolution.ts +8 -1
  386. package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
  387. package/src/domains/providers/runtimes/builtins.ts +2 -0
  388. package/src/domains/providers/runtimes/common/probe-helpers.ts +31 -9
  389. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +1 -1
  390. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
  391. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +1 -1
  392. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +1 -1
  393. package/src/domains/providers/runtimes/local-native/llamacpp.ts +4 -1
  394. package/src/domains/providers/runtimes/local-native/lmstudio.ts +4 -1
  395. package/src/domains/providers/runtimes/local-native/ollama-native.ts +6 -1
  396. package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
  397. package/src/domains/providers/support.ts +1 -0
  398. package/src/domains/providers/target-model-cache.ts +124 -0
  399. package/src/domains/providers/types/capability-flags.ts +2 -0
  400. package/src/domains/providers/types/target-descriptor.ts +2 -0
  401. package/src/domains/resources/index.ts +3 -0
  402. package/src/domains/resources/prompts/loader.ts +95 -33
  403. package/src/domains/resources/skills/loader.ts +33 -0
  404. package/src/domains/safety/action-classifier.ts +6 -0
  405. package/src/domains/safety/call-target.ts +52 -0
  406. package/src/domains/safety/run-effects.ts +35 -4
  407. package/src/domains/session/context-accounting.ts +52 -1
  408. package/src/domains/session/context-ledger.ts +37 -13
  409. package/src/domains/session/index.ts +6 -0
  410. package/src/domains/session/prompt-cache.ts +140 -0
  411. package/src/domains/session/prompt-manifest.ts +42 -0
  412. package/src/domains/toolchain/archive.ts +175 -0
  413. package/src/domains/toolchain/contract.ts +28 -0
  414. package/src/domains/toolchain/extension.ts +47 -0
  415. package/src/domains/toolchain/index.ts +39 -0
  416. package/src/domains/toolchain/install.ts +327 -0
  417. package/src/domains/toolchain/manifest.ts +8 -0
  418. package/src/domains/toolchain/paths.ts +34 -0
  419. package/src/domains/toolchain/registry.ts +265 -0
  420. package/src/domains/toolchain/remove.ts +218 -0
  421. package/src/domains/toolchain/resolve.ts +182 -0
  422. package/src/domains/toolchain/types.ts +113 -0
  423. package/src/domains/toolchain/version.ts +88 -0
  424. package/src/engine/acp/adapter.ts +18 -3
  425. package/src/engine/acp/server.ts +413 -70
  426. package/src/engine/acp/types.ts +19 -1
  427. package/src/engine/ai.ts +35 -0
  428. package/src/engine/apis/llamacpp-residency.ts +55 -3
  429. package/src/engine/apis/lmstudio.ts +25 -5
  430. package/src/engine/apis/ollama-native.ts +2 -1
  431. package/src/engine/apis/openai-completions.ts +80 -17
  432. package/src/engine/apis/residency-lock.ts +3 -1
  433. package/src/engine/apis/residency.ts +34 -1
  434. package/src/engine/claude/sdk-module.ts +98 -0
  435. package/src/engine/claude/sdk-runtime.ts +19 -11
  436. package/src/engine/provider-payload.ts +29 -1
  437. package/src/engine/tui-primitives.ts +21 -0
  438. package/src/engine/tui.ts +1 -0
  439. package/src/engine/worker-runtime.ts +2 -13
  440. package/src/entry/boot-options.ts +2 -0
  441. package/src/entry/orchestrator.ts +279 -35
  442. package/src/entry/panes-activation.ts +31 -0
  443. package/src/entry/with-panes.ts +20 -0
  444. package/src/interactive/chat-loop-messages.ts +26 -7
  445. package/src/interactive/chat-loop.ts +318 -41
  446. package/src/interactive/chat-panel.ts +62 -8
  447. package/src/interactive/clio-editor.ts +45 -8
  448. package/src/interactive/context-activity.ts +5 -1
  449. package/src/interactive/context-meter.ts +1 -1
  450. package/src/interactive/context-overlay.ts +41 -10
  451. package/src/interactive/cost-overlay.ts +66 -6
  452. package/src/interactive/council-grid.ts +1 -3
  453. package/src/interactive/council.ts +11 -0
  454. package/src/interactive/dispatch-board.ts +102 -20
  455. package/src/interactive/fleet-run-preview.ts +41 -15
  456. package/src/interactive/handoff-round.ts +41 -2
  457. package/src/interactive/interactive-application.ts +177 -7
  458. package/src/interactive/interactive-input-runtime.ts +15 -0
  459. package/src/interactive/interactive-presentation.ts +4 -0
  460. package/src/interactive/interactive-shell.ts +20 -17
  461. package/src/interactive/interactive-slash-runtime.ts +63 -10
  462. package/src/interactive/memory-overlay.ts +9 -0
  463. package/src/interactive/modal-marker.ts +170 -0
  464. package/src/interactive/mutation-preview.ts +295 -0
  465. package/src/interactive/mux-bridge.ts +214 -0
  466. package/src/interactive/overlay-frame.ts +58 -2
  467. package/src/interactive/overlay-general-openers.ts +17 -0
  468. package/src/interactive/overlay-key-routing.ts +52 -3
  469. package/src/interactive/overlay-lifecycle.ts +56 -7
  470. package/src/interactive/overlay-model-selectors.ts +40 -3
  471. package/src/interactive/overlay-permission-lifecycle.ts +112 -24
  472. package/src/interactive/overlay-session-lifecycle.ts +73 -9
  473. package/src/interactive/overlay-transitions.ts +18 -4
  474. package/src/interactive/overlays/agents.ts +1 -0
  475. package/src/interactive/overlays/ask-user.ts +227 -49
  476. package/src/interactive/overlays/auth-dialog.ts +1 -0
  477. package/src/interactive/overlays/context-reset.ts +1 -0
  478. package/src/interactive/overlays/cwd-fallback.ts +1 -0
  479. package/src/interactive/overlays/decisions.ts +11 -11
  480. package/src/interactive/overlays/extensions.ts +1 -0
  481. package/src/interactive/overlays/fleet-run-approval.ts +1 -0
  482. package/src/interactive/overlays/handoff-review.ts +1 -0
  483. package/src/interactive/overlays/help-reference.ts +6 -0
  484. package/src/interactive/overlays/interop.ts +1 -0
  485. package/src/interactive/overlays/library-install-confirm.ts +1 -0
  486. package/src/interactive/overlays/library-tabs.ts +28 -0
  487. package/src/interactive/overlays/list-overlay.ts +10 -1
  488. package/src/interactive/overlays/message-picker.ts +1 -0
  489. package/src/interactive/overlays/model-scope.ts +86 -0
  490. package/src/interactive/overlays/model-selector.ts +1 -0
  491. package/src/interactive/overlays/prompts.ts +12 -1
  492. package/src/interactive/overlays/session-selector.ts +1 -0
  493. package/src/interactive/overlays/settings-sections.ts +30 -0
  494. package/src/interactive/overlays/settings.ts +614 -45
  495. package/src/interactive/overlays/side-question.ts +1 -0
  496. package/src/interactive/overlays/skills-hub.ts +3 -11
  497. package/src/interactive/overlays/tree-selector.ts +1 -0
  498. package/src/interactive/pane-policy.ts +46 -0
  499. package/src/interactive/panes-runtime.ts +292 -0
  500. package/src/interactive/permission-hint.ts +34 -2
  501. package/src/interactive/permission-overlay.ts +159 -9
  502. package/src/interactive/prewarm.ts +197 -0
  503. package/src/interactive/render-trace.ts +162 -15
  504. package/src/interactive/renderers/compaction-summary.ts +29 -0
  505. package/src/interactive/renderers/tool-execution.ts +4 -0
  506. package/src/interactive/renderers/worker-entry.ts +122 -14
  507. package/src/interactive/side-question.ts +58 -1
  508. package/src/interactive/slash-commands.ts +251 -15
  509. package/src/interactive/status/controller.ts +11 -0
  510. package/src/interactive/status/state-machine.ts +54 -2
  511. package/src/interactive/status/types.ts +7 -0
  512. package/src/interactive/tasks-overlay.ts +1 -0
  513. package/src/interactive/terminal-lease.ts +2 -0
  514. package/src/interactive/theme/tokens.ts +3 -14
  515. package/src/interactive/turn-context.ts +346 -33
  516. package/src/interactive/turn-persistence.ts +14 -4
  517. package/src/interactive/turn-prewarm.ts +364 -0
  518. package/src/interactive/turn-queues.ts +7 -4
  519. package/src/interactive/turn-runtime.ts +8 -1
  520. package/src/interactive/turn-state.ts +23 -0
  521. package/src/interactive/view/artifacts.ts +109 -1
  522. package/src/interactive/view/view-overlay.ts +29 -3
  523. package/src/interactive/watch-pane.ts +152 -0
  524. package/src/interactive/worker-progress.ts +7 -1
  525. package/src/interactive/worker-receipts.ts +19 -1
  526. package/src/interactive/worker-stream.ts +5 -0
  527. package/src/interactive/yazi-bridge.ts +444 -0
  528. package/src/tools/ask-user.ts +43 -2
  529. package/src/tools/bootstrap.ts +26 -2
  530. package/src/tools/builtin-tool-catalog.ts +15 -0
  531. package/src/tools/compete-worktrees.ts +83 -2
  532. package/src/tools/core-bootstrap.ts +2 -1
  533. package/src/tools/dispatch-admission.ts +14 -3
  534. package/src/tools/dispatch-arguments.ts +20 -20
  535. package/src/tools/dispatch-plan.ts +17 -9
  536. package/src/tools/dispatch-run-events.ts +134 -19
  537. package/src/tools/dispatch-runner.ts +29 -7
  538. package/src/tools/dispatch-scout.ts +1 -1
  539. package/src/tools/dispatch-types.ts +15 -3
  540. package/src/tools/dispatch.ts +1 -1
  541. package/src/tools/executables.ts +17 -14
  542. package/src/tools/observation.ts +54 -4
  543. package/src/tools/panes-surface.ts +38 -0
  544. package/src/tools/panes.ts +112 -0
  545. package/src/tools/policy.ts +10 -1
  546. package/src/tools/presentation.ts +1 -0
  547. package/src/tools/registry.ts +16 -0
  548. package/dist/chunk-AOCYTWAV.js +0 -449
  549. package/dist/chunk-HLE42MG7.js +0 -37
  550. package/dist/chunk-HWUFFB6L.js +0 -83
  551. package/dist/chunk-JOZYP4GM.js +0 -279
  552. package/dist/doctor-M7YEDGAE.js +0 -91
@@ -48,12 +48,22 @@ export interface SessionPromptInputs {
48
48
  memorySection?: string;
49
49
  }
50
50
 
51
+ /**
52
+ * Which section order `compile()` lays down. `volatility` is the product
53
+ * order; `legacy-0.3.8` reproduces the order shipped before issue #249 and
54
+ * exists so a test can prove the change is a pure permutation. Nothing in
55
+ * `src/` may pass `legacy-0.3.8`; the boundary is the test suite.
56
+ */
57
+ export type SessionPromptSectionOrder = "volatility" | "legacy-0.3.8";
58
+
51
59
  export interface CompileInputs {
52
60
  identity: string;
53
61
  operatingContract: string;
54
62
  safety: string;
55
63
  sessionInputs: SessionPromptInputs;
56
64
  additionalFragments?: ReadonlyArray<RenderedPromptFragment>;
65
+ /** Test-only escape hatch; see `SessionPromptSectionOrder`. Defaults to `volatility`. */
66
+ sectionOrder?: SessionPromptSectionOrder;
57
67
  }
58
68
 
59
69
  /** Stable inputs for one mediated fleet worker's canonical system prompt. */
@@ -439,21 +449,93 @@ function renderProjectBlock(contextFiles: string | undefined): string {
439
449
  return trimmedFiles.length === 0 ? "" : `# Project\n\n${trimmedFiles}`;
440
450
  }
441
451
 
442
- function renderMemoryBlock(memorySection: string | undefined): string {
452
+ /**
453
+ * The rendered memory section already opens with its own `# Memory` heading
454
+ * (`domains/memory/prompt-section.ts`), so prepending one unconditionally put
455
+ * the header in the prompt twice. Callers that pass a bare body still get a
456
+ * header; callers that pass a rendered section keep the one they wrote.
457
+ *
458
+ * `legacyDuplicateHeader` reproduces the 0.3.8 behavior and is reachable only
459
+ * through `sectionOrder: "legacy-0.3.8"`, so the permutation test compares
460
+ * against the whole prompt 0.3.8 emitted rather than a half-corrected one.
461
+ */
462
+ function renderMemoryBlock(memorySection: string | undefined, legacyDuplicateHeader = false): string {
443
463
  const trimmed = memorySection?.trim() ?? "";
444
- return trimmed.length === 0 ? "" : `# Memory\n\n${trimmed}`;
464
+ if (trimmed.length === 0) return "";
465
+ if (legacyDuplicateHeader) return `# Memory\n\n${trimmed}`;
466
+ return /^#\s+Memory\s*$/.test(trimmed.split("\n", 1)[0] ?? "") ? trimmed : `# Memory\n\n${trimmed}`;
445
467
  }
446
468
 
447
469
  function estimatePromptTokens(text: string): number {
448
470
  return ceilChars(text.trim().length);
449
471
  }
450
472
 
473
+ /**
474
+ * The session prompt's section order, stable prefix first (issue #249).
475
+ *
476
+ * The rule, and it is the only rule: a section goes as late as its
477
+ * volatility, and anything that reads a clock, a probe, or a mutable store
478
+ * goes after everything that does not. Every backend Clio targets caches by
479
+ * exact prefix and re-prefills from the earliest changed byte, so a section
480
+ * that can change between two turns must not sit ahead of sections that
481
+ * cannot. That is why `runtime` is last of the compiled sections: its
482
+ * `Context window: N` moves when the backend reloads a model or a
483
+ * co-residency clamp lands, and before this order a single changed digit
484
+ * re-prefilled the tool contract, the roster, the hints, memory, and the
485
+ * project context behind it. `memory` sits just ahead of it because an
486
+ * approved memory record rewrites that section mid-session, and
487
+ * `project-context` is stable for the session's lifetime.
488
+ *
489
+ * The tail fragments (`workspace-root`, `clio-repo-awareness`,
490
+ * `project-rules`, `operator-profile`) are appended after this list in their
491
+ * own order: path-scoped project rules grow mid-session by design, which is
492
+ * exactly why they belong at the very end.
493
+ *
494
+ * Moving an entry here is a deliberate cache decision. `tests/contracts/
495
+ * prompt-prefix-layout.test.ts` pins this list so the move has to be made on
496
+ * purpose.
497
+ */
498
+ export const SESSION_PROMPT_SECTION_ORDER: ReadonlyArray<string> = [
499
+ "identity",
500
+ "operating-contract",
501
+ "delegation",
502
+ "skills",
503
+ "safety",
504
+ "tool-contract",
505
+ "fleet",
506
+ "retrieval-hints",
507
+ "project-context",
508
+ "memory",
509
+ "runtime",
510
+ ];
511
+
512
+ /**
513
+ * The order shipped through 0.3.8, kept only so a test can prove the new order
514
+ * is a permutation of it rather than a rewrite. Never reachable from `src/`.
515
+ */
516
+ export const LEGACY_SESSION_PROMPT_SECTION_ORDER: ReadonlyArray<string> = [
517
+ "identity",
518
+ "operating-contract",
519
+ "delegation",
520
+ "skills",
521
+ "safety",
522
+ "runtime",
523
+ "tool-contract",
524
+ "fleet",
525
+ "retrieval-hints",
526
+ "memory",
527
+ "project-context",
528
+ ];
529
+
451
530
  /**
452
531
  * Compile the session system prompt. Identity and the operating contract
453
532
  * render verbatim from disk fragments; safety renders a one-line directive
454
533
  * plus the safety fragment body; everything else renders inline from typed
455
534
  * SessionPromptInputs. Output is one string, one sha256, one token estimate,
456
535
  * and a flat section breakdown for the /context overlay.
536
+ *
537
+ * Sections are laid down in `SESSION_PROMPT_SECTION_ORDER`, whose doc comment
538
+ * states the volatility rule that fixes it.
457
539
  */
458
540
  export function compile(table: FragmentTable, inputs: CompileInputs): CompiledSessionPrompt {
459
541
  const identity = lookupFragment(table, inputs.identity, "identity");
@@ -493,17 +575,22 @@ export function compile(table: FragmentTable, inputs: CompileInputs): CompiledSe
493
575
  const delegation = sessionCanDispatch(session) ? table.byId.get("operating.delegation") : undefined;
494
576
  const skills = sessionHasContext(session) ? table.byId.get("operating.skills") : undefined;
495
577
 
496
- push("identity", identityBody);
497
- push("operating-contract", operatingContract.body);
498
- if (delegation) push("delegation", delegation.body);
499
- if (skills) push("skills", skills.body);
500
- push("safety", renderSafetySection(safety, autonomyLevel));
501
- push("runtime", renderRuntimeBlock(session));
502
- push("tool-contract", renderToolContractBlock(session));
503
- push("fleet", renderFleetBlock(session));
504
- push("retrieval-hints", renderRetrievalHintsBlock(session));
505
- push("memory", renderMemoryBlock(session.memorySection));
506
- push("project-context", renderProjectBlock(session.contextFiles));
578
+ const legacy = inputs.sectionOrder === "legacy-0.3.8";
579
+ const rendered = new Map<string, string>([
580
+ ["identity", identityBody],
581
+ ["operating-contract", operatingContract.body],
582
+ ["delegation", delegation?.body ?? ""],
583
+ ["skills", skills?.body ?? ""],
584
+ ["safety", renderSafetySection(safety, autonomyLevel)],
585
+ ["runtime", renderRuntimeBlock(session)],
586
+ ["tool-contract", renderToolContractBlock(session)],
587
+ ["fleet", renderFleetBlock(session)],
588
+ ["retrieval-hints", renderRetrievalHintsBlock(session)],
589
+ ["memory", renderMemoryBlock(session.memorySection, legacy)],
590
+ ["project-context", renderProjectBlock(session.contextFiles)],
591
+ ]);
592
+ const order = legacy ? LEGACY_SESSION_PROMPT_SECTION_ORDER : SESSION_PROMPT_SECTION_ORDER;
593
+ for (const id of order) push(id, rendered.get(id) ?? "");
507
594
  for (const fragment of inputs.additionalFragments ?? []) {
508
595
  push(fragment.id, fragment.body);
509
596
  }
@@ -0,0 +1,228 @@
1
+ import { canonicalEndpointUrl } from "../../core/endpoint-key.js";
2
+ import type { TargetStatus } from "./contract.js";
3
+ import {
4
+ type DiscoveredEndpointSlots,
5
+ readDiscoveredEndpointSlots,
6
+ recordDiscoveredEndpointSlots,
7
+ } from "./endpoint-slots-store.js";
8
+ import type { RuntimeDescriptor } from "./types/runtime-descriptor.js";
9
+ import type { TargetDescriptor } from "./types/target-descriptor.js";
10
+
11
+ /**
12
+ * Where an endpoint's slot bound came from, weakest first.
13
+ *
14
+ * `discovered-prior` is a slot count a previous process probed and persisted
15
+ * (endpoint-slots-store.ts). It outranks the blind local default because it is
16
+ * evidence, and it yields to a probe this process ran because that evidence is
17
+ * newer.
18
+ */
19
+ export type EndpointCapacitySource = "override" | "discovered" | "discovered-prior" | "local-native-default";
20
+
21
+ export interface EndpointCapacity {
22
+ key: string;
23
+ label: string;
24
+ limit: number;
25
+ source: EndpointCapacitySource;
26
+ }
27
+
28
+ /** Endpoint priors keyed by canonical endpoint key. */
29
+ export type EndpointSlotPriors = Readonly<Record<string, DiscoveredEndpointSlots>>;
30
+
31
+ /** Runtime ids whose request schedulers are intentionally not modeled as fixed local slots. */
32
+ const UNBOUNDED_LOCAL_NATIVE_RUNTIMES = new Set(["vllm", "sglang"]);
33
+
34
+ /**
35
+ * Canonical identity of the inference scheduler behind a configured target.
36
+ * Scheme, normalized host and port, and normalized base path participate. DNS
37
+ * aliases do not collapse because Clio cannot prove they reach the same server.
38
+ */
39
+ export function canonicalEndpointKey(value: TargetDescriptor | string): string | null {
40
+ return canonicalEndpointUrl(typeof value === "string" ? value : value.url);
41
+ }
42
+
43
+ /** Compact operator-facing identity. A non-root base path remains visible. */
44
+ export function endpointLabel(endpointKey: string): string {
45
+ try {
46
+ const url = new URL(endpointKey);
47
+ return `${url.host}${url.pathname === "/" ? "" : url.pathname}`;
48
+ } catch {
49
+ return endpointKey;
50
+ }
51
+ }
52
+
53
+ function positiveInteger(value: unknown): number | undefined {
54
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : undefined;
55
+ }
56
+
57
+ /** The runtime facts capacity resolution needs; a full descriptor satisfies it. */
58
+ export type EndpointRuntimeIdentity = Pick<RuntimeDescriptor, "id" | "tier">;
59
+
60
+ export interface EndpointCapacityInput {
61
+ target: TargetDescriptor;
62
+ /** Null when no runtime descriptor has resolved yet for `target.runtime`. */
63
+ runtime: EndpointRuntimeIdentity | null;
64
+ /** Slot count a probe in this process discovered, if one has landed. */
65
+ discoveredSlots?: number | undefined;
66
+ }
67
+
68
+ /**
69
+ * Resolve one endpoint's concurrency bound.
70
+ *
71
+ * The order is the whole contract, because it is what makes the answer
72
+ * independent of when it is asked:
73
+ *
74
+ * 1. `maxConcurrentRequests` on the target. The operator said so.
75
+ * 2. A probe this process ran.
76
+ * 3. A probe a previous process ran and persisted, still inside its
77
+ * staleness bound and still describing the same runtime.
78
+ * 4. The conservative local-native default of one slot.
79
+ *
80
+ * Steps 2 and 3 answer with the same number for the same server, so a dispatch
81
+ * typed one second after boot and one typed a minute later resolve identically.
82
+ * Runtimes whose schedulers are not fixed local slots stay unbounded (null).
83
+ */
84
+ export function endpointCapacityFor(
85
+ input: EndpointCapacityInput,
86
+ priors: EndpointSlotPriors = readDiscoveredEndpointSlots(),
87
+ ): EndpointCapacity | null {
88
+ const key = canonicalEndpointKey(input.target);
89
+ if (key === null) return null;
90
+ const label = endpointLabel(key);
91
+ const override = positiveInteger(input.target.maxConcurrentRequests);
92
+ if (override !== undefined) return { key, label, limit: override, source: "override" };
93
+ const discovered = positiveInteger(input.discoveredSlots);
94
+ if (discovered !== undefined) return { key, label, limit: discovered, source: "discovered" };
95
+ const prior = priors[key];
96
+ // A record written by another runtime describes another server that once
97
+ // answered on this host and port, which is not evidence about this one.
98
+ if (prior !== undefined && prior.runtimeId === (input.runtime?.id ?? input.target.runtime)) {
99
+ return { key, label, limit: prior.slots, source: "discovered-prior" };
100
+ }
101
+ if (input.runtime?.tier !== "local-native" || UNBOUNDED_LOCAL_NATIVE_RUNTIMES.has(input.runtime.id)) return null;
102
+ return { key, label, limit: 1, source: "local-native-default" };
103
+ }
104
+
105
+ /** Resolve the endpoint bound from configuration, discovery, priors, or the local-native fallback. */
106
+ export function endpointCapacityForStatus(
107
+ status: TargetStatus,
108
+ priors: EndpointSlotPriors = readDiscoveredEndpointSlots(),
109
+ ): EndpointCapacity | null {
110
+ return endpointCapacityFor(
111
+ {
112
+ target: status.target,
113
+ runtime: status.runtime ?? null,
114
+ discoveredSlots: status.probeCapabilities?.parallelSlots,
115
+ },
116
+ priors,
117
+ );
118
+ }
119
+
120
+ function sourceRank(source: EndpointCapacitySource): number {
121
+ switch (source) {
122
+ case "override":
123
+ return 3;
124
+ case "discovered":
125
+ return 2;
126
+ case "discovered-prior":
127
+ return 1;
128
+ default:
129
+ return 0;
130
+ }
131
+ }
132
+
133
+ /** Strongest evidence wins; among equals the smaller bound wins. */
134
+ function foldCapacity(capacities: Record<string, EndpointCapacity>, candidate: EndpointCapacity | null): void {
135
+ if (candidate === null) return;
136
+ const current = capacities[candidate.key];
137
+ if (
138
+ current === undefined ||
139
+ sourceRank(candidate.source) > sourceRank(current.source) ||
140
+ (sourceRank(candidate.source) === sourceRank(current.source) && candidate.limit < current.limit)
141
+ ) {
142
+ capacities[candidate.key] = candidate;
143
+ }
144
+ }
145
+
146
+ /** Resolve one conservative limit per scheduler, preferring an explicit override. */
147
+ export function endpointCapacitiesForStatuses(
148
+ statuses: ReadonlyArray<TargetStatus>,
149
+ ): Readonly<Record<string, EndpointCapacity>> {
150
+ const priors = readDiscoveredEndpointSlots();
151
+ const capacities: Record<string, EndpointCapacity> = {};
152
+ for (const status of statuses) foldCapacity(capacities, endpointCapacityForStatus(status, priors));
153
+ return capacities;
154
+ }
155
+
156
+ /**
157
+ * Every endpoint the configured fleet can reach, whether or not a probe has
158
+ * built a status for it yet.
159
+ *
160
+ * Resolving from `statuses` alone made the endpoint set depend on how far
161
+ * provider startup had progressed. An endpoint missing from that set carries no
162
+ * limit, and a capacity check with no limit is not a conservative check, it is
163
+ * no check: a plan needing two slots on a one-slot server was admitted whole
164
+ * when it was typed before the provider domain had finished building statuses,
165
+ * and denied afterwards. Configured targets fill the gap so the set is the same
166
+ * at both moments.
167
+ */
168
+ export function resolveEndpointCapacities(input: {
169
+ statuses: ReadonlyArray<TargetStatus>;
170
+ targets?: ReadonlyArray<TargetDescriptor>;
171
+ runtimeFor?: (runtimeId: string) => EndpointRuntimeIdentity | null | undefined;
172
+ }): Readonly<Record<string, EndpointCapacity>> {
173
+ const priors = readDiscoveredEndpointSlots();
174
+ const capacities: Record<string, EndpointCapacity> = {};
175
+ const covered = new Set<string>();
176
+ for (const status of input.statuses) {
177
+ covered.add(status.target.id);
178
+ foldCapacity(capacities, endpointCapacityForStatus(status, priors));
179
+ }
180
+ for (const target of input.targets ?? []) {
181
+ if (covered.has(target.id)) continue;
182
+ foldCapacity(
183
+ capacities,
184
+ endpointCapacityFor({ target, runtime: input.runtimeFor?.(target.runtime) ?? null }, priors),
185
+ );
186
+ }
187
+ return capacities;
188
+ }
189
+
190
+ /**
191
+ * Persist what a live probe just learned about this target's endpoint so the
192
+ * next process starts with the count instead of the blind default. A status
193
+ * with no probed slot count writes nothing: absence is not an observation, and
194
+ * overwriting a good record with silence would lose the fact this exists to
195
+ * keep.
196
+ */
197
+ export function recordEndpointSlotsFromStatus(
198
+ status: TargetStatus,
199
+ options?: { nowMs?: number; onError?: (error: unknown) => void },
200
+ ): Promise<void> {
201
+ const key = canonicalEndpointKey(status.target);
202
+ const slots = positiveInteger(status.probeCapabilities?.parallelSlots);
203
+ const runtimeId = status.runtime?.id ?? status.target.runtime;
204
+ if (key === null || slots === undefined || runtimeId === undefined) return Promise.resolve();
205
+ return recordDiscoveredEndpointSlots({ endpointKey: key, runtimeId, slots }, options);
206
+ }
207
+
208
+ /**
209
+ * The orchestrator's own request lives only in this process. It deliberately
210
+ * never enters dispatch-admission.json because process exit releases it.
211
+ */
212
+ const foregroundStreams = new Map<string, number>();
213
+
214
+ export function registerForegroundStream(endpointKey: string): () => void {
215
+ foregroundStreams.set(endpointKey, (foregroundStreams.get(endpointKey) ?? 0) + 1);
216
+ let held = true;
217
+ return () => {
218
+ if (!held) return;
219
+ held = false;
220
+ const next = (foregroundStreams.get(endpointKey) ?? 1) - 1;
221
+ if (next <= 0) foregroundStreams.delete(endpointKey);
222
+ else foregroundStreams.set(endpointKey, next);
223
+ };
224
+ }
225
+
226
+ export function foregroundStreamUsage(): Readonly<Record<string, number>> {
227
+ return Object.fromEntries(foregroundStreams);
228
+ }
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Durable endpoint slot discovery.
3
+ *
4
+ * On-disk layout under `clioStateDir()`:
5
+ * endpoint-slots.json { version: 1, endpoints: { <canonical key>: record } }
6
+ *
7
+ * A probe that reads a server's own parallel slot count learns a fact about a
8
+ * machine, not about the process that asked. Holding it in memory made every
9
+ * fresh process start ignorant, so a four-slot llama.cpp server resolved at the
10
+ * conservative local-native default of 1 until something in that process
11
+ * happened to probe it again. This file is what carries the count across
12
+ * process boundaries.
13
+ *
14
+ * Conventions follow the rest of dispatch state (see dispatch/state.ts and
15
+ * dispatch/assignment-store.ts): reads are lock-free and tolerate a partially
16
+ * written or foreign-versioned file by answering empty, writes take the shared
17
+ * cross-process `withStateFileLock` on the target path and land through the
18
+ * canonical atomic writer.
19
+ *
20
+ * Three things bound what a persisted count may claim:
21
+ *
22
+ * 1. Age. A record older than {@link endpointSlotsTtlMs} is not returned and
23
+ * is pruned by the next write. A server restarted with a different
24
+ * `--parallel` must not keep over-admitting against yesterday's number.
25
+ * 2. Runtime identity. The record names the runtime that observed it. A
26
+ * different inference server now listening on the same host and port is a
27
+ * different scheduler, and its predecessor's slot count says nothing about
28
+ * it.
29
+ * 3. Precedence. A fresh probe in this process always outranks the record,
30
+ * and an explicit `maxConcurrentRequests` outranks both. See
31
+ * endpoint-capacity.ts.
32
+ *
33
+ * Reads are deliberately uncached. The file holds at most
34
+ * MAX_ENDPOINT_SLOT_RECORDS small rows, callers read it once per capacity
35
+ * resolution rather than once per target, and a cache keyed on mtime would
36
+ * reintroduce exactly the kind of timing-dependent answer this file exists to
37
+ * remove.
38
+ */
39
+
40
+ import { existsSync, readFileSync } from "node:fs";
41
+ import { join } from "node:path";
42
+ import { safeResourceWrite } from "../../core/safe-resource-write.js";
43
+ import { withStateFileLock } from "../../core/state-file-lock.js";
44
+ import { clioStateDir, stateRootRemoved } from "../../core/xdg.js";
45
+
46
+ /**
47
+ * How long a persisted slot count may answer for an endpoint nothing has
48
+ * probed in this process. A day spans an ordinary working session while still
49
+ * expiring across the reconfigure-and-restart cycle that changes the number.
50
+ */
51
+ export const DEFAULT_ENDPOINT_SLOTS_TTL_MS = 24 * 60 * 60 * 1000;
52
+
53
+ export const ENDPOINT_SLOTS_TTL_ENV_VAR = "CLIO_CODER_ENDPOINT_SLOTS_TTL_MS";
54
+
55
+ /** Bounded ring. An operator's target list is small; a runaway file is not. */
56
+ const MAX_ENDPOINT_SLOT_RECORDS = 64;
57
+
58
+ export interface DiscoveredEndpointSlots {
59
+ /** Canonical endpoint key, as produced by `canonicalEndpointKey`. */
60
+ endpointKey: string;
61
+ /** Runtime that observed the count. A different runtime invalidates it. */
62
+ runtimeId: string;
63
+ slots: number;
64
+ observedAt: string;
65
+ }
66
+
67
+ interface EndpointSlotsFile {
68
+ version: 1;
69
+ endpoints: Record<string, DiscoveredEndpointSlots>;
70
+ }
71
+
72
+ export function endpointSlotsPath(): string {
73
+ return join(clioStateDir(), "endpoint-slots.json");
74
+ }
75
+
76
+ /** env override > built-in default, mirroring core/guardrails.ts resolution order. */
77
+ export function endpointSlotsTtlMs(env: NodeJS.ProcessEnv = process.env): number {
78
+ const raw = env[ENDPOINT_SLOTS_TTL_ENV_VAR]?.trim();
79
+ if (raw !== undefined && /^[1-9]\d*$/.test(raw)) {
80
+ const parsed = Number(raw);
81
+ if (Number.isSafeInteger(parsed)) return parsed;
82
+ }
83
+ return DEFAULT_ENDPOINT_SLOTS_TTL_MS;
84
+ }
85
+
86
+ function validRecord(key: string, value: unknown): value is DiscoveredEndpointSlots {
87
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
88
+ const record = value as Partial<DiscoveredEndpointSlots>;
89
+ return (
90
+ record.endpointKey === key &&
91
+ typeof record.runtimeId === "string" &&
92
+ record.runtimeId.length > 0 &&
93
+ typeof record.slots === "number" &&
94
+ Number.isInteger(record.slots) &&
95
+ record.slots > 0 &&
96
+ typeof record.observedAt === "string" &&
97
+ Number.isFinite(Date.parse(record.observedAt))
98
+ );
99
+ }
100
+
101
+ /** Every well-formed row on disk, regardless of age. */
102
+ function readRecords(): DiscoveredEndpointSlots[] {
103
+ const path = endpointSlotsPath();
104
+ if (!existsSync(path)) return [];
105
+ try {
106
+ const parsed = JSON.parse(readFileSync(path, "utf8")) as EndpointSlotsFile;
107
+ if (parsed?.version !== 1 || typeof parsed.endpoints !== "object" || parsed.endpoints === null) return [];
108
+ return Object.entries(parsed.endpoints)
109
+ .filter(([key, value]) => validRecord(key, value))
110
+ .map(([, value]) => ({ ...value }));
111
+ } catch {
112
+ // A truncated or hand-edited file cannot bound anything. Answering empty
113
+ // falls back to the conservative default rather than to a guess.
114
+ return [];
115
+ }
116
+ }
117
+
118
+ function fresh(record: DiscoveredEndpointSlots, nowMs: number, ttlMs: number): boolean {
119
+ const observedMs = Date.parse(record.observedAt);
120
+ // A stamp from the future is a clock that moved, not evidence of freshness.
121
+ return observedMs <= nowMs && nowMs - observedMs < ttlMs;
122
+ }
123
+
124
+ /**
125
+ * The slot counts a new process may treat as priors: well-formed, and observed
126
+ * inside the staleness bound. Keyed by canonical endpoint key.
127
+ */
128
+ export function readDiscoveredEndpointSlots(options?: {
129
+ nowMs?: number;
130
+ ttlMs?: number;
131
+ }): Readonly<Record<string, DiscoveredEndpointSlots>> {
132
+ const nowMs = options?.nowMs ?? Date.now();
133
+ const ttlMs = options?.ttlMs ?? endpointSlotsTtlMs();
134
+ const out: Record<string, DiscoveredEndpointSlots> = {};
135
+ for (const record of readRecords()) {
136
+ if (!fresh(record, nowMs, ttlMs)) continue;
137
+ out[record.endpointKey] = record;
138
+ }
139
+ return Object.freeze(out);
140
+ }
141
+
142
+ function writeRecords(records: ReadonlyArray<DiscoveredEndpointSlots>): void {
143
+ const kept = [...records]
144
+ .sort((a, b) => Date.parse(b.observedAt) - Date.parse(a.observedAt))
145
+ .slice(0, MAX_ENDPOINT_SLOT_RECORDS);
146
+ const file: EndpointSlotsFile = {
147
+ version: 1,
148
+ endpoints: Object.fromEntries(kept.map((record) => [record.endpointKey, { ...record }])),
149
+ };
150
+ safeResourceWrite(endpointSlotsPath(), `${JSON.stringify(file, null, 2)}\n`, { encoding: "utf8" });
151
+ }
152
+
153
+ /**
154
+ * Record what a probe just learned about one endpoint. A fresh observation
155
+ * always replaces the stored one, including downward: a server restarted with
156
+ * fewer slots must be able to lower its own bound.
157
+ *
158
+ * Never throws. Losing a capacity prior degrades a later process to the
159
+ * conservative default; failing a probe over it would be worse.
160
+ */
161
+ export async function recordDiscoveredEndpointSlots(
162
+ entry: { endpointKey: string; runtimeId: string; slots: number },
163
+ options?: { nowMs?: number; ttlMs?: number; onError?: (error: unknown) => void },
164
+ ): Promise<void> {
165
+ if (!Number.isInteger(entry.slots) || entry.slots <= 0) return;
166
+ if (entry.endpointKey.length === 0 || entry.runtimeId.length === 0) return;
167
+ // Checked before the lock because acquiring it recreates the state root, and
168
+ // again under it because an uninstall can land while this call waits.
169
+ if (stateRootRemoved()) return;
170
+ const nowMs = options?.nowMs ?? Date.now();
171
+ const ttlMs = options?.ttlMs ?? endpointSlotsTtlMs();
172
+ try {
173
+ await withStateFileLock(endpointSlotsPath(), () => {
174
+ if (stateRootRemoved()) return;
175
+ const kept = readRecords().filter(
176
+ (record) => record.endpointKey !== entry.endpointKey && fresh(record, nowMs, ttlMs),
177
+ );
178
+ kept.push({
179
+ endpointKey: entry.endpointKey,
180
+ runtimeId: entry.runtimeId,
181
+ slots: entry.slots,
182
+ observedAt: new Date(nowMs).toISOString(),
183
+ });
184
+ writeRecords(kept);
185
+ });
186
+ } catch (error) {
187
+ options?.onError?.(error);
188
+ }
189
+ }
@@ -11,12 +11,14 @@ import { mergeCapabilities } from "./capabilities.js";
11
11
  import { capabilitiesFromCatalogModel, getCatalogModelForRuntime } from "./catalog.js";
12
12
  import type { ContextWindowProvenance, ProvidersContract, TargetHealth, TargetStatus } from "./contract.js";
13
13
  import { credentialsPresent } from "./credentials.js";
14
+ import { recordEndpointSlotsFromStatus } from "./endpoint-capacity.js";
14
15
  import { resolveProviderKnowledgeBaseRoots } from "./knowledge-base-path.js";
15
16
  import { probeCapabilitiesForModel } from "./model-capabilities.js";
16
17
  import { loadPluginRuntimes } from "./plugins.js";
17
18
  import { getRuntimeRegistry } from "./registry.js";
18
19
  import { registerBuiltinRuntimes } from "./runtimes/builtins.js";
19
20
  import { listKnownModelsForRuntime } from "./support.js";
21
+ import { readTargetModelSnapshot, recordTargetModelSnapshot } from "./target-model-cache.js";
20
22
  import type { CapabilityFlags } from "./types/capability-flags.js";
21
23
  import { EMPTY_CAPABILITIES } from "./types/capability-flags.js";
22
24
  import {
@@ -133,10 +135,12 @@ function discoveredModelsSource(
133
135
  probe: ProbeResult | null,
134
136
  preservePreviousProbe: boolean,
135
137
  previous: TargetStatus | undefined,
138
+ cachedModels: ReadonlyArray<string>,
136
139
  desc: RuntimeDescriptor,
137
140
  ): "probe" | "cache" | "runtime" | "none" {
138
141
  if (probe?.models !== undefined) return "probe";
139
142
  if (preservePreviousProbe && previous?.discoveredModels && previous.discoveredModels.length > 0) return "cache";
143
+ if (cachedModels.length > 0) return "cache";
140
144
  if (desc.knownModels && desc.knownModels.length > 0) return "runtime";
141
145
  return "none";
142
146
  }
@@ -174,6 +178,7 @@ export function mergeProbeResult(
174
178
  target: TargetDescriptor,
175
179
  probe: ProbeResult | null,
176
180
  previous: TargetStatus | undefined,
181
+ cachedModels: ReadonlyArray<string> = [],
177
182
  ): ProbeMerge {
178
183
  const probeSucceeded = probe?.ok ?? false;
179
184
  const preservePrevious = !probeSucceeded && previous !== undefined && sameProbeIdentity(previous.target, target);
@@ -189,12 +194,16 @@ export function mergeProbeResult(
189
194
  probe?.notes && probe.notes.length > 0 ? probe.notes : preservePrevious ? previous.probeNotes : undefined;
190
195
  const probeSurfaces = probe?.surfaces ?? (preservePrevious ? previous.probeSurfaces : undefined);
191
196
  const discoveredModels = uniqueModels(
192
- probe?.models ?? (preservePrevious ? previous.discoveredModels : undefined) ?? desc.knownModels ?? [],
197
+ probe?.models ??
198
+ (preservePrevious ? previous.discoveredModels : undefined) ??
199
+ (cachedModels.length > 0 ? cachedModels : undefined) ??
200
+ desc.knownModels ??
201
+ [],
193
202
  );
194
203
  const discoveredModelStates = probe?.modelStates ?? (preservePrevious ? previous.discoveredModelStates : null) ?? null;
195
204
  const merge: ProbeMerge = {
196
205
  discoveredModels,
197
- discoveredModelsSource: discoveredModelsSource(probe, preservePrevious, previous, desc),
206
+ discoveredModelsSource: discoveredModelsSource(probe, preservePrevious, previous, cachedModels, desc),
198
207
  discoveredModelStates,
199
208
  probeCapabilities,
200
209
  probeModelCapabilities,
@@ -316,7 +325,8 @@ export function createProvidersBundle(context: DomainContext): DomainBundle<Prov
316
325
  return out;
317
326
  }
318
327
  const availability = availabilityFor(desc, target, authStatusFor);
319
- const merge = mergeProbeResult(desc, target, probe, previous);
328
+ const cachedModels = readTargetModelSnapshot(target)?.models ?? [];
329
+ const merge = mergeProbeResult(desc, target, probe, previous, cachedModels);
320
330
  const { capabilities, contextWindowProvenance } = capabilitiesFor(desc, target, merge, kb);
321
331
  const healthy = probe !== null ? probe.ok : null;
322
332
  const unservedDefault = probe?.ok ? unservedDefaultModelReason(desc, target, merge) : null;
@@ -414,6 +424,13 @@ export function createProvidersBundle(context: DomainContext): DomainBundle<Prov
414
424
  }
415
425
  const status = buildStatus(target, desc, probeResult, previous);
416
426
  statuses.set(target.id, status);
427
+ if (probeResult.ok && probeResult.models !== undefined) {
428
+ recordTargetModelSnapshot(target, probeResult.models);
429
+ }
430
+ // Durable so the next process resolves this endpoint's real slot count
431
+ // instead of the conservative default. Fire and forget: the probe's answer
432
+ // is already in `statuses`, and a failed write must not fail the probe.
433
+ void recordEndpointSlotsFromStatus(status);
417
434
  context.bus.emit(BusChannels.ProviderHealth, { id: target.id, status });
418
435
  return status;
419
436
  }