agent-nuvira 3.3.13 → 3.3.15

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 (398) hide show
  1. package/README.md +67 -1
  2. package/dist/agents/agents/planner.d.ts.map +1 -1
  3. package/dist/agents/agents/planner.js +9 -0
  4. package/dist/agents/agents/planner.js.map +1 -1
  5. package/dist/agents/orchestrator.d.ts +31 -0
  6. package/dist/agents/orchestrator.d.ts.map +1 -1
  7. package/dist/agents/orchestrator.js +74 -126
  8. package/dist/agents/orchestrator.js.map +1 -1
  9. package/dist/cli/chat.d.ts +89 -0
  10. package/dist/cli/chat.d.ts.map +1 -1
  11. package/dist/cli/chat.js +765 -33
  12. package/dist/cli/chat.js.map +1 -1
  13. package/dist/cli/cli-program.d.ts.map +1 -1
  14. package/dist/cli/cli-program.js +12 -0
  15. package/dist/cli/cli-program.js.map +1 -1
  16. package/dist/cli/config.d.ts +12 -0
  17. package/dist/cli/config.d.ts.map +1 -1
  18. package/dist/cli/config.js +86 -0
  19. package/dist/cli/config.js.map +1 -1
  20. package/dist/cli/decisions.d.ts +28 -0
  21. package/dist/cli/decisions.d.ts.map +1 -0
  22. package/dist/cli/decisions.js +140 -0
  23. package/dist/cli/decisions.js.map +1 -0
  24. package/dist/cli/doctor.d.ts +6 -0
  25. package/dist/cli/doctor.d.ts.map +1 -1
  26. package/dist/cli/doctor.js +46 -0
  27. package/dist/cli/doctor.js.map +1 -1
  28. package/dist/cli/failover-runner.d.ts.map +1 -1
  29. package/dist/cli/failover-runner.js +19 -1
  30. package/dist/cli/failover-runner.js.map +1 -1
  31. package/dist/cli/feedback.d.ts.map +1 -1
  32. package/dist/cli/feedback.js +5 -1
  33. package/dist/cli/feedback.js.map +1 -1
  34. package/dist/cli/hooks.d.ts +30 -0
  35. package/dist/cli/hooks.d.ts.map +1 -0
  36. package/dist/cli/hooks.js +224 -0
  37. package/dist/cli/hooks.js.map +1 -0
  38. package/dist/cli/knowledge.d.ts +9 -1
  39. package/dist/cli/knowledge.d.ts.map +1 -1
  40. package/dist/cli/knowledge.js +93 -2
  41. package/dist/cli/knowledge.js.map +1 -1
  42. package/dist/cli/loop-executor.d.ts.map +1 -1
  43. package/dist/cli/loop-executor.js +47 -12
  44. package/dist/cli/loop-executor.js.map +1 -1
  45. package/dist/cli/model.d.ts +20 -0
  46. package/dist/cli/model.d.ts.map +1 -1
  47. package/dist/cli/model.js +294 -14
  48. package/dist/cli/model.js.map +1 -1
  49. package/dist/cli/rate.d.ts +78 -0
  50. package/dist/cli/rate.d.ts.map +1 -0
  51. package/dist/cli/rate.js +294 -0
  52. package/dist/cli/rate.js.map +1 -0
  53. package/dist/config/process-env.d.ts.map +1 -1
  54. package/dist/config/process-env.js +10 -0
  55. package/dist/config/process-env.js.map +1 -1
  56. package/dist/enterprise/vault.d.ts.map +1 -1
  57. package/dist/enterprise/vault.js +5 -21
  58. package/dist/enterprise/vault.js.map +1 -1
  59. package/dist/gateway/hook-contract.d.ts +33 -0
  60. package/dist/gateway/hook-contract.d.ts.map +1 -1
  61. package/dist/gateway/hook-contract.js +97 -0
  62. package/dist/gateway/hook-contract.js.map +1 -1
  63. package/dist/inference/gemini-adapter.d.ts.map +1 -1
  64. package/dist/inference/gemini-adapter.js +4 -0
  65. package/dist/inference/gemini-adapter.js.map +1 -1
  66. package/dist/inference/interface.d.ts +37 -0
  67. package/dist/inference/interface.d.ts.map +1 -1
  68. package/dist/inference/native-tools.d.ts +16 -1
  69. package/dist/inference/native-tools.d.ts.map +1 -1
  70. package/dist/inference/native-tools.js +34 -10
  71. package/dist/inference/native-tools.js.map +1 -1
  72. package/dist/inference/route-resolver.d.ts +30 -0
  73. package/dist/inference/route-resolver.d.ts.map +1 -1
  74. package/dist/inference/route-resolver.js +158 -1
  75. package/dist/inference/route-resolver.js.map +1 -1
  76. package/dist/inference/tools.d.ts +16 -1
  77. package/dist/inference/tools.d.ts.map +1 -1
  78. package/dist/inference/tools.js +51 -18
  79. package/dist/inference/tools.js.map +1 -1
  80. package/dist/learning/acceptance-model.d.ts +247 -0
  81. package/dist/learning/acceptance-model.d.ts.map +1 -0
  82. package/dist/learning/acceptance-model.js +708 -0
  83. package/dist/learning/acceptance-model.js.map +1 -0
  84. package/dist/learning/auto-router.d.ts +68 -24
  85. package/dist/learning/auto-router.d.ts.map +1 -1
  86. package/dist/learning/auto-router.js +301 -96
  87. package/dist/learning/auto-router.js.map +1 -1
  88. package/dist/learning/autonomy-policy.d.ts +12 -16
  89. package/dist/learning/autonomy-policy.d.ts.map +1 -1
  90. package/dist/learning/autonomy-policy.js +50 -48
  91. package/dist/learning/autonomy-policy.js.map +1 -1
  92. package/dist/learning/behavioural-labels.d.ts +86 -0
  93. package/dist/learning/behavioural-labels.d.ts.map +1 -0
  94. package/dist/learning/behavioural-labels.js +166 -0
  95. package/dist/learning/behavioural-labels.js.map +1 -0
  96. package/dist/learning/capability-evidence.d.ts +167 -0
  97. package/dist/learning/capability-evidence.d.ts.map +1 -0
  98. package/dist/learning/capability-evidence.js +210 -0
  99. package/dist/learning/capability-evidence.js.map +1 -0
  100. package/dist/learning/capability-readiness.d.ts +64 -0
  101. package/dist/learning/capability-readiness.d.ts.map +1 -0
  102. package/dist/learning/capability-readiness.js +74 -0
  103. package/dist/learning/capability-readiness.js.map +1 -0
  104. package/dist/learning/capability-types.d.ts +169 -0
  105. package/dist/learning/capability-types.d.ts.map +1 -0
  106. package/dist/learning/capability-types.js +20 -0
  107. package/dist/learning/capability-types.js.map +1 -0
  108. package/dist/learning/catalog-feed.d.ts +89 -0
  109. package/dist/learning/catalog-feed.d.ts.map +1 -0
  110. package/dist/learning/catalog-feed.js +211 -0
  111. package/dist/learning/catalog-feed.js.map +1 -0
  112. package/dist/learning/cli-intent-effects.d.ts +60 -0
  113. package/dist/learning/cli-intent-effects.d.ts.map +1 -0
  114. package/dist/learning/cli-intent-effects.js +153 -0
  115. package/dist/learning/cli-intent-effects.js.map +1 -0
  116. package/dist/learning/command-adaptation.d.ts +41 -0
  117. package/dist/learning/command-adaptation.d.ts.map +1 -0
  118. package/dist/learning/command-adaptation.js +122 -0
  119. package/dist/learning/command-adaptation.js.map +1 -0
  120. package/dist/learning/consent-picture.d.ts +42 -0
  121. package/dist/learning/consent-picture.d.ts.map +1 -0
  122. package/dist/learning/consent-picture.js +53 -0
  123. package/dist/learning/consent-picture.js.map +1 -0
  124. package/dist/learning/context-budget.d.ts +37 -6
  125. package/dist/learning/context-budget.d.ts.map +1 -1
  126. package/dist/learning/context-budget.js +38 -9
  127. package/dist/learning/context-budget.js.map +1 -1
  128. package/dist/learning/decision-log.d.ts +114 -0
  129. package/dist/learning/decision-log.d.ts.map +1 -0
  130. package/dist/learning/decision-log.js +296 -0
  131. package/dist/learning/decision-log.js.map +1 -0
  132. package/dist/learning/deliverable-class.d.ts.map +1 -1
  133. package/dist/learning/deliverable-class.js +19 -0
  134. package/dist/learning/deliverable-class.js.map +1 -1
  135. package/dist/learning/deliverable-corpus.d.ts +117 -0
  136. package/dist/learning/deliverable-corpus.d.ts.map +1 -0
  137. package/dist/learning/deliverable-corpus.js +176 -0
  138. package/dist/learning/deliverable-corpus.js.map +1 -0
  139. package/dist/learning/error-repair.d.ts +22 -1
  140. package/dist/learning/error-repair.d.ts.map +1 -1
  141. package/dist/learning/error-repair.js +37 -0
  142. package/dist/learning/error-repair.js.map +1 -1
  143. package/dist/learning/exhaustion-report.d.ts +136 -0
  144. package/dist/learning/exhaustion-report.d.ts.map +1 -0
  145. package/dist/learning/exhaustion-report.js +239 -0
  146. package/dist/learning/exhaustion-report.js.map +1 -0
  147. package/dist/learning/failure-bookkeeping.d.ts +16 -0
  148. package/dist/learning/failure-bookkeeping.d.ts.map +1 -1
  149. package/dist/learning/failure-bookkeeping.js +51 -5
  150. package/dist/learning/failure-bookkeeping.js.map +1 -1
  151. package/dist/learning/gate-friction.d.ts +39 -0
  152. package/dist/learning/gate-friction.d.ts.map +1 -0
  153. package/dist/learning/gate-friction.js +91 -0
  154. package/dist/learning/gate-friction.js.map +1 -0
  155. package/dist/learning/harness-narration.d.ts +34 -0
  156. package/dist/learning/harness-narration.d.ts.map +1 -0
  157. package/dist/learning/harness-narration.js +58 -0
  158. package/dist/learning/harness-narration.js.map +1 -0
  159. package/dist/learning/hub-skill-catalog.d.ts.map +1 -1
  160. package/dist/learning/hub-skill-catalog.js +1 -2
  161. package/dist/learning/hub-skill-catalog.js.map +1 -1
  162. package/dist/learning/hybrid-router.d.ts +65 -0
  163. package/dist/learning/hybrid-router.d.ts.map +1 -1
  164. package/dist/learning/hybrid-router.js +186 -0
  165. package/dist/learning/hybrid-router.js.map +1 -1
  166. package/dist/learning/knowledge-base.d.ts +229 -3
  167. package/dist/learning/knowledge-base.d.ts.map +1 -1
  168. package/dist/learning/knowledge-base.js +603 -25
  169. package/dist/learning/knowledge-base.js.map +1 -1
  170. package/dist/learning/knowledge-eval.d.ts +171 -0
  171. package/dist/learning/knowledge-eval.d.ts.map +1 -0
  172. package/dist/learning/knowledge-eval.js +196 -0
  173. package/dist/learning/knowledge-eval.js.map +1 -0
  174. package/dist/learning/knowledge-turn.d.ts +92 -0
  175. package/dist/learning/knowledge-turn.d.ts.map +1 -0
  176. package/dist/learning/knowledge-turn.js +190 -0
  177. package/dist/learning/knowledge-turn.js.map +1 -0
  178. package/dist/learning/learned-commands.d.ts +64 -0
  179. package/dist/learning/learned-commands.d.ts.map +1 -0
  180. package/dist/learning/learned-commands.js +108 -0
  181. package/dist/learning/learned-commands.js.map +1 -0
  182. package/dist/learning/lexical-search.d.ts +50 -0
  183. package/dist/learning/lexical-search.d.ts.map +1 -0
  184. package/dist/learning/lexical-search.js +111 -0
  185. package/dist/learning/lexical-search.js.map +1 -0
  186. package/dist/learning/machine-facts.d.ts +71 -0
  187. package/dist/learning/machine-facts.d.ts.map +1 -0
  188. package/dist/learning/machine-facts.js +164 -0
  189. package/dist/learning/machine-facts.js.map +1 -0
  190. package/dist/learning/markdown-outline.d.ts +73 -0
  191. package/dist/learning/markdown-outline.d.ts.map +1 -0
  192. package/dist/learning/markdown-outline.js +136 -0
  193. package/dist/learning/markdown-outline.js.map +1 -0
  194. package/dist/learning/model-first-router.d.ts +33 -1
  195. package/dist/learning/model-first-router.d.ts.map +1 -1
  196. package/dist/learning/model-first-router.js +123 -9
  197. package/dist/learning/model-first-router.js.map +1 -1
  198. package/dist/learning/model-identity.d.ts +80 -0
  199. package/dist/learning/model-identity.d.ts.map +1 -0
  200. package/dist/learning/model-identity.js +115 -0
  201. package/dist/learning/model-identity.js.map +1 -0
  202. package/dist/learning/model-registry.d.ts +141 -2
  203. package/dist/learning/model-registry.d.ts.map +1 -1
  204. package/dist/learning/model-registry.js +324 -38
  205. package/dist/learning/model-registry.js.map +1 -1
  206. package/dist/learning/model-scoring.d.ts.map +1 -1
  207. package/dist/learning/model-scoring.js +8 -1
  208. package/dist/learning/model-scoring.js.map +1 -1
  209. package/dist/learning/model-selection.d.ts.map +1 -1
  210. package/dist/learning/model-selection.js +41 -0
  211. package/dist/learning/model-selection.js.map +1 -1
  212. package/dist/learning/outcome-observation.d.ts +49 -0
  213. package/dist/learning/outcome-observation.d.ts.map +1 -0
  214. package/dist/learning/outcome-observation.js +95 -0
  215. package/dist/learning/outcome-observation.js.map +1 -0
  216. package/dist/learning/pair-entitlement.d.ts +184 -0
  217. package/dist/learning/pair-entitlement.d.ts.map +1 -0
  218. package/dist/learning/pair-entitlement.js +214 -0
  219. package/dist/learning/pair-entitlement.js.map +1 -0
  220. package/dist/learning/provider-fallback.d.ts +23 -1
  221. package/dist/learning/provider-fallback.d.ts.map +1 -1
  222. package/dist/learning/provider-fallback.js +24 -0
  223. package/dist/learning/provider-fallback.js.map +1 -1
  224. package/dist/learning/reasoning-trace.d.ts +65 -1
  225. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  226. package/dist/learning/reasoning-trace.js +123 -1
  227. package/dist/learning/reasoning-trace.js.map +1 -1
  228. package/dist/learning/requirement-probe.d.ts +55 -0
  229. package/dist/learning/requirement-probe.d.ts.map +1 -0
  230. package/dist/learning/requirement-probe.js +77 -0
  231. package/dist/learning/requirement-probe.js.map +1 -0
  232. package/dist/learning/resilient-call.d.ts +20 -1
  233. package/dist/learning/resilient-call.d.ts.map +1 -1
  234. package/dist/learning/resilient-call.js +42 -4
  235. package/dist/learning/resilient-call.js.map +1 -1
  236. package/dist/learning/response-usability.d.ts +85 -0
  237. package/dist/learning/response-usability.d.ts.map +1 -0
  238. package/dist/learning/response-usability.js +135 -0
  239. package/dist/learning/response-usability.js.map +1 -0
  240. package/dist/learning/router-bandit.d.ts +132 -0
  241. package/dist/learning/router-bandit.d.ts.map +1 -1
  242. package/dist/learning/router-bandit.js +253 -0
  243. package/dist/learning/router-bandit.js.map +1 -1
  244. package/dist/learning/routing-history.d.ts +41 -2
  245. package/dist/learning/routing-history.d.ts.map +1 -1
  246. package/dist/learning/routing-history.js.map +1 -1
  247. package/dist/learning/run-trace.d.ts +21 -0
  248. package/dist/learning/run-trace.d.ts.map +1 -1
  249. package/dist/learning/run-trace.js +38 -0
  250. package/dist/learning/run-trace.js.map +1 -1
  251. package/dist/learning/session-grant.d.ts +75 -0
  252. package/dist/learning/session-grant.d.ts.map +1 -0
  253. package/dist/learning/session-grant.js +112 -0
  254. package/dist/learning/session-grant.js.map +1 -0
  255. package/dist/learning/task-model-continuity.d.ts +73 -0
  256. package/dist/learning/task-model-continuity.d.ts.map +1 -0
  257. package/dist/learning/task-model-continuity.js +87 -0
  258. package/dist/learning/task-model-continuity.js.map +1 -0
  259. package/dist/learning/turn-feedback.d.ts +93 -0
  260. package/dist/learning/turn-feedback.d.ts.map +1 -0
  261. package/dist/learning/turn-feedback.js +127 -0
  262. package/dist/learning/turn-feedback.js.map +1 -0
  263. package/dist/learning/turn-report.d.ts +104 -2
  264. package/dist/learning/turn-report.d.ts.map +1 -1
  265. package/dist/learning/turn-report.js +161 -6
  266. package/dist/learning/turn-report.js.map +1 -1
  267. package/dist/learning/verdict-routing.d.ts +51 -0
  268. package/dist/learning/verdict-routing.d.ts.map +1 -0
  269. package/dist/learning/verdict-routing.js +122 -0
  270. package/dist/learning/verdict-routing.js.map +1 -0
  271. package/dist/mcp/client.d.ts.map +1 -1
  272. package/dist/mcp/client.js +5 -0
  273. package/dist/mcp/client.js.map +1 -1
  274. package/dist/mcp/manager.d.ts +10 -0
  275. package/dist/mcp/manager.d.ts.map +1 -1
  276. package/dist/mcp/manager.js +20 -0
  277. package/dist/mcp/manager.js.map +1 -1
  278. package/dist/mcp/mcp-discovery.d.ts +34 -0
  279. package/dist/mcp/mcp-discovery.d.ts.map +1 -0
  280. package/dist/mcp/mcp-discovery.js +71 -0
  281. package/dist/mcp/mcp-discovery.js.map +1 -0
  282. package/dist/mcp/mcp-schema-cache.d.ts +17 -0
  283. package/dist/mcp/mcp-schema-cache.d.ts.map +1 -1
  284. package/dist/mcp/mcp-schema-cache.js +47 -3
  285. package/dist/mcp/mcp-schema-cache.js.map +1 -1
  286. package/dist/mcp/types.d.ts +28 -0
  287. package/dist/mcp/types.d.ts.map +1 -1
  288. package/dist/mcp/types.js.map +1 -1
  289. package/dist/parity/drivers.d.ts.map +1 -1
  290. package/dist/parity/drivers.js +3 -0
  291. package/dist/parity/drivers.js.map +1 -1
  292. package/dist/parity/observation.d.ts +12 -0
  293. package/dist/parity/observation.d.ts.map +1 -1
  294. package/dist/parity/observation.js +14 -0
  295. package/dist/parity/observation.js.map +1 -1
  296. package/dist/tools/ask-user.d.ts.map +1 -1
  297. package/dist/tools/ask-user.js +4 -0
  298. package/dist/tools/ask-user.js.map +1 -1
  299. package/dist/tools/capability-registry.d.ts +150 -0
  300. package/dist/tools/capability-registry.d.ts.map +1 -0
  301. package/dist/tools/capability-registry.js +400 -0
  302. package/dist/tools/capability-registry.js.map +1 -0
  303. package/dist/tools/child-agent-runtime.d.ts.map +1 -1
  304. package/dist/tools/child-agent-runtime.js +19 -5
  305. package/dist/tools/child-agent-runtime.js.map +1 -1
  306. package/dist/tools/coding-tools.d.ts +17 -5
  307. package/dist/tools/coding-tools.d.ts.map +1 -1
  308. package/dist/tools/coding-tools.js +80 -11
  309. package/dist/tools/coding-tools.js.map +1 -1
  310. package/dist/tools/command-memo.d.ts +116 -0
  311. package/dist/tools/command-memo.d.ts.map +1 -0
  312. package/dist/tools/command-memo.js +202 -0
  313. package/dist/tools/command-memo.js.map +1 -0
  314. package/dist/tools/git-tool.d.ts.map +1 -1
  315. package/dist/tools/git-tool.js +13 -3
  316. package/dist/tools/git-tool.js.map +1 -1
  317. package/dist/tools/harness-directive.d.ts +42 -0
  318. package/dist/tools/harness-directive.d.ts.map +1 -0
  319. package/dist/tools/harness-directive.js +45 -0
  320. package/dist/tools/harness-directive.js.map +1 -0
  321. package/dist/tools/loop-skill-hint.d.ts +74 -174
  322. package/dist/tools/loop-skill-hint.d.ts.map +1 -1
  323. package/dist/tools/loop-skill-hint.js +110 -536
  324. package/dist/tools/loop-skill-hint.js.map +1 -1
  325. package/dist/tools/mcp-client-tool.d.ts +2 -0
  326. package/dist/tools/mcp-client-tool.d.ts.map +1 -1
  327. package/dist/tools/mcp-client-tool.js +3 -0
  328. package/dist/tools/mcp-client-tool.js.map +1 -1
  329. package/dist/tools/modality/shared.d.ts +1 -4
  330. package/dist/tools/modality/shared.d.ts.map +1 -1
  331. package/dist/tools/modality/shared.js +7 -22
  332. package/dist/tools/modality/shared.js.map +1 -1
  333. package/dist/tools/plan-store.d.ts +20 -2
  334. package/dist/tools/plan-store.d.ts.map +1 -1
  335. package/dist/tools/plan-store.js +51 -7
  336. package/dist/tools/plan-store.js.map +1 -1
  337. package/dist/tools/registry.d.ts +76 -3
  338. package/dist/tools/registry.d.ts.map +1 -1
  339. package/dist/tools/registry.js +486 -26
  340. package/dist/tools/registry.js.map +1 -1
  341. package/dist/tools/remediation-ladder.d.ts.map +1 -1
  342. package/dist/tools/remediation-ladder.js +8 -0
  343. package/dist/tools/remediation-ladder.js.map +1 -1
  344. package/dist/tools/run-cli.d.ts.map +1 -1
  345. package/dist/tools/run-cli.js +29 -4
  346. package/dist/tools/run-cli.js.map +1 -1
  347. package/dist/tools/run-terminal.d.ts +11 -0
  348. package/dist/tools/run-terminal.d.ts.map +1 -1
  349. package/dist/tools/run-terminal.js +265 -10
  350. package/dist/tools/run-terminal.js.map +1 -1
  351. package/dist/tools/tool-loop.d.ts +321 -13
  352. package/dist/tools/tool-loop.d.ts.map +1 -1
  353. package/dist/tools/tool-loop.js +867 -66
  354. package/dist/tools/tool-loop.js.map +1 -1
  355. package/dist/utils/atomic-store.d.ts +53 -0
  356. package/dist/utils/atomic-store.d.ts.map +1 -0
  357. package/dist/utils/atomic-store.js +178 -0
  358. package/dist/utils/atomic-store.js.map +1 -0
  359. package/dist/utils/binary-probe.d.ts +25 -0
  360. package/dist/utils/binary-probe.d.ts.map +1 -0
  361. package/dist/utils/binary-probe.js +48 -0
  362. package/dist/utils/binary-probe.js.map +1 -0
  363. package/dist/utils/workspace-path.d.ts +50 -0
  364. package/dist/utils/workspace-path.d.ts.map +1 -0
  365. package/dist/utils/workspace-path.js +86 -0
  366. package/dist/utils/workspace-path.js.map +1 -0
  367. package/dist/web-dashboard/chat-console.d.ts +24 -0
  368. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  369. package/dist/web-dashboard/chat-console.js +38 -0
  370. package/dist/web-dashboard/chat-console.js.map +1 -1
  371. package/dist/web-dashboard/project-context.d.ts +27 -2
  372. package/dist/web-dashboard/project-context.d.ts.map +1 -1
  373. package/dist/web-dashboard/project-context.js +32 -2
  374. package/dist/web-dashboard/project-context.js.map +1 -1
  375. package/dist/web-dashboard/server.d.ts +11 -0
  376. package/dist/web-dashboard/server.d.ts.map +1 -1
  377. package/dist/web-dashboard/server.js +362 -11
  378. package/dist/web-dashboard/server.js.map +1 -1
  379. package/dist/web-dashboard/src/types.d.ts +170 -1
  380. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  381. package/dist/web-dashboard/workspace-guard.d.ts +11 -2
  382. package/dist/web-dashboard/workspace-guard.d.ts.map +1 -1
  383. package/dist/web-dashboard/workspace-guard.js +24 -12
  384. package/dist/web-dashboard/workspace-guard.js.map +1 -1
  385. package/dist/web-dashboard/workspace-resolution.d.ts +87 -0
  386. package/dist/web-dashboard/workspace-resolution.d.ts.map +1 -0
  387. package/dist/web-dashboard/workspace-resolution.js +105 -0
  388. package/dist/web-dashboard/workspace-resolution.js.map +1 -0
  389. package/package.json +1 -1
  390. package/src/web-dashboard/public/assets/index-zjbdJnO-.js +210 -0
  391. package/src/web-dashboard/public/assets/index-zjbdJnO-.js.map +1 -0
  392. package/src/web-dashboard/public/index.html +1 -1
  393. package/dist/agents/nvda-addon.d.ts +0 -14
  394. package/dist/agents/nvda-addon.js +0 -52
  395. package/dist/forwarded.d.ts +0 -2
  396. package/dist/forwarded.js +0 -2
  397. package/src/web-dashboard/public/assets/index-DhiuR4S2.js +0 -210
  398. package/src/web-dashboard/public/assets/index-DhiuR4S2.js.map +0 -1
package/dist/cli/model.js CHANGED
@@ -25,16 +25,26 @@ import inquirer from 'inquirer';
25
25
  import { resolveNuviraHome } from '../config/paths.js';
26
26
  import { BaseCommand } from './commands.js';
27
27
  import { showModelPicker } from './model-picker.js';
28
+ import { CATALOG_PROVIDER_IDS } from '../inference/provider-catalog.js';
28
29
  import { getPluginRegistry } from '../plugins/registry.js';
29
30
  import { recommendModel } from '../learning/model-router.js';
30
31
  import { getModelBadge } from '../inference/model-catalog.js';
31
32
  import { getHybridRouter } from '../learning/hybrid-router.js';
32
33
  import { AUTO_MODEL, AUTO_PROVIDER, getAutoRouter, isAutoModel, isAutoProvider, PIIPolicyError, GovernancePolicyError, } from '../learning/auto-router.js';
33
34
  import { buildAutoResolveOptions } from '../learning/resolve-options.js';
35
+ import { parseRequestSync } from '../nlu/parser.js';
36
+ import { resolveDispatch } from '../nlu/actions.js';
34
37
  import { recordRoutingDecision, getExplainSnapshots } from '../learning/routing-history.js';
35
38
  import { diffRoutingDecisions, formatDecisionDiff } from '../learning/decision-diff.js';
36
39
  import { getRouterBandit, COMPLEXITY_BUCKETS, } from '../learning/router-bandit.js';
37
40
  import { getQuotaLedger } from '../learning/quota-ledger.js';
41
+ import { getModelRegistry } from '../learning/model-registry.js';
42
+ import { ENTITLEMENT_LABEL, areTwins, classifyPairEntitlement, entitlementNote, } from '../learning/pair-entitlement.js';
43
+ import { identityKey, identityProvenance } from '../learning/model-identity.js';
44
+ import { DEFAULT_PRIORS, capabilityLines, deriveTier, effectiveParameter, } from '../learning/capability-evidence.js';
45
+ import { externalPriorsFor } from '../learning/catalog-feed.js';
46
+ import { acceptanceSummary, formatAcceptanceSummary } from '../learning/acceptance-model.js';
47
+ import { getProviderFallback } from '../learning/provider-fallback.js';
38
48
  import { getRouterPromotion, DEFAULT_MIN_PROMOTION_DECISIONS, } from '../learning/router-promotion.js';
39
49
  import { getMlRouter } from '../learning/ml-router.js';
40
50
  import { logger } from '../utils/logger.js';
@@ -124,6 +134,17 @@ const EXPLAIN_SAMPLES = [
124
134
  { label: '🟠 complex', task: 'design a distributed event-driven microservices architecture' },
125
135
  { label: '🔴 critical', task: 'deploy to production with zero downtime' },
126
136
  ];
137
+ /** Repeatable `--exclude-provider <provider>` collector. */
138
+ function collectProvider(value, previous) {
139
+ previous.push(value);
140
+ return previous;
141
+ }
142
+ /**
143
+ * A session failure sinks a provider by scoring exactly like a live cooldown
144
+ * (`circuitBreakerStatus`). Any positive value parks it, so this is not a real
145
+ * duration — it says "this provider is out for this decision".
146
+ */
147
+ const SESSION_EXCLUDE_COOLDOWN_MS = 60_000;
127
148
  // ─── ModelCommand ───────────────────────────────────────────────────────────
128
149
  export class ModelCommand extends BaseCommand {
129
150
  create() {
@@ -159,7 +180,15 @@ export class ModelCommand extends BaseCommand {
159
180
  .option('-a, --agent <type>', 'Agent type to route for (default: chat)', 'chat')
160
181
  .option('-j, --json', 'Output as JSON (for scripting and CI)', false)
161
182
  .option('--since <ref>', 'P3-M3.3: diff against a previous decision — an explain id, @n (nth most recent explain), or an epoch-ms timestamp', undefined)
162
- .action((task, opts) => this.showExplain(task, opts));
183
+ .option('--context-tokens <n>', 'Item 14: the prompt token count the runtime would have seen (context preflight basis) — reproduce a decision made with a large history', undefined)
184
+ .option('--exclude-provider <provider>', 'Item 14: a provider already failed THIS SESSION, repeatable — it sinks by scoring exactly as the runtime excludes it', collectProvider, [])
185
+ .action((task, opts) => this.showExplain(task, {
186
+ agent: opts.agent,
187
+ json: opts.json,
188
+ since: opts.since,
189
+ contextTokens: opts.contextTokens !== undefined ? Number(opts.contextTokens) : undefined,
190
+ excludeProviders: opts.excludeProvider,
191
+ }));
163
192
  cmd
164
193
  .command('health')
165
194
  .description('Quick health check for the currently active provider')
@@ -197,7 +226,33 @@ export class ModelCommand extends BaseCommand {
197
226
  }
198
227
  // ── Subcommand: list ───────────────────────────────────────────────────
199
228
  async listProviders(opts) {
200
- const builtinTypes = ['local', 'groq', 'nim', 'gemini', 'openrouter'];
229
+ /**
230
+ * The provider set the ROUTER uses — not a hand-written list of five.
231
+ *
232
+ * `rankAvailableProviders` (the router's source of truth) builds its candidate
233
+ * set from the catalog PLUS whatever the user configured. A literal array here
234
+ * made `model list` disagree with routing about which providers even exist:
235
+ * measured live, a machine whose turns were served by `deepseek` — with the
236
+ * debug header and the trace both naming it — printed only
237
+ * local/groq/nim/gemini/openrouter, so `deepseek` (and every other catalog
238
+ * provider: bedrock, openai, mistral, …) was invisible in the one command whose
239
+ * whole job is "what can I use?". One source, one inventory.
240
+ *
241
+ * The familiar five keep their place at the top so the table does not reorder
242
+ * itself for existing users; the rest follow in catalog order.
243
+ */
244
+ const builtinTypes = (() => {
245
+ const preferred = ['local', 'groq', 'nim', 'gemini', 'openrouter'];
246
+ let configured = [];
247
+ try {
248
+ configured = Object.keys(this.configManager.getAll().providers ?? {});
249
+ }
250
+ catch {
251
+ // Best-effort — an unreadable config must not empty the table.
252
+ }
253
+ const all = new Set([...preferred, ...CATALOG_PROVIDER_IDS, ...configured]);
254
+ return [...all];
255
+ })();
201
256
  const registry = getPluginRegistry();
202
257
  const pluginTypes = registry.getAllPlugins().map((p) => p.getProviderType());
203
258
  const active = readActiveModelState();
@@ -291,7 +346,14 @@ export class ModelCommand extends BaseCommand {
291
346
  console.log(' ┌──────────────────────────────────┬──────────┬──────────┬──────────────────┐');
292
347
  console.log(' │ Provider │ Status │ Available│ Model │');
293
348
  console.log(' ├──────────────────────────────────┼──────────┼──────────┼──────────────────┤');
294
- for (const r of results) {
349
+ // Usable first. The table now carries the WHOLE catalog (so it agrees with
350
+ // routing), which means most rows are providers this machine has no key for.
351
+ // Putting the callable ones on top keeps the answer to "what can I use?" in
352
+ // the first few lines rather than below a dozen `Needs key` rows. Stable
353
+ // sort, so the familiar five keep their relative order.
354
+ const rankOf = (r) => r.available ? 0 : r.configured ? 1 : 2;
355
+ const ordered = [...results].sort((a, b) => rankOf(a) - rankOf(b));
356
+ for (const r of ordered) {
295
357
  const name = `${r.icon} ${r.label}`.padEnd(30).slice(0, 30);
296
358
  const status = r.isActive ? '✅ Active' : r.configured ? '⚙️ Ready' : '⏳ Needs key';
297
359
  const avail = r.available ? '✅' : '⛔';
@@ -304,6 +366,45 @@ export class ModelCommand extends BaseCommand {
304
366
  logger.success(`Active: ${active.provider}/${active.model}`);
305
367
  console.log(` (set ${new Date(active.updatedAt).toLocaleString()})`);
306
368
  }
369
+ // ── A1: the SAME model, opposite verdicts ──────────────────────────────
370
+ // Two rows for one model can disagree completely (`openrouter` refuses a
371
+ // model `deepseek` serves), and the table above shows only each provider's own
372
+ // default — so the pair was invisible. Print only the groups whose verdicts
373
+ // genuinely DISAGREE: same identity, different answer about whether it can be
374
+ // called. Each verdict is read from its own row (identity groups capability
375
+ // and legibility, never availability).
376
+ try {
377
+ const registry = getModelRegistry();
378
+ const rows = registry.getTrackedProviders().flatMap((p) => registry.getAllModelsForProvider(p));
379
+ const groups = new Map();
380
+ for (const r of rows) {
381
+ const key = identityKey(r.model);
382
+ if (!key)
383
+ continue;
384
+ const list = groups.get(key);
385
+ if (list)
386
+ list.push(r);
387
+ else
388
+ groups.set(key, [r]);
389
+ }
390
+ const mixed = [...groups.values()].filter((g) => new Set(g.map((r) => classifyPairEntitlement(r))).size > 1);
391
+ if (mixed.length > 0) {
392
+ console.log('');
393
+ logger.highlight(' ── The same model, different verdicts (A1) ──');
394
+ for (const g of mixed.slice(0, 5)) {
395
+ console.log(` ${g[0].model}`);
396
+ for (const r of g) {
397
+ const e = classifyPairEntitlement(r);
398
+ console.log(` ${ENTITLEMENT_LABEL[e]} ${r.provider} — ${entitlementNote(e, r)}`);
399
+ }
400
+ }
401
+ if (mixed.length > 5)
402
+ console.log(` … and ${mixed.length - 5} more.`);
403
+ }
404
+ }
405
+ catch {
406
+ // Best-effort — this section must never break `model list`.
407
+ }
307
408
  console.log('');
308
409
  logger.info('Run `nuvira model switch` to change the active provider/model.');
309
410
  logger.info('Run `nuvira doctor` for full diagnostic checks.');
@@ -505,9 +606,13 @@ export class ModelCommand extends BaseCommand {
505
606
  showExplain(task, opts) {
506
607
  const router = getAutoRouter();
507
608
  const agentType = opts.agent || 'chat';
609
+ const runtime = {
610
+ contextTokens: opts.contextTokens,
611
+ excludeProviders: opts.excludeProviders,
612
+ };
508
613
  if (opts.json) {
509
614
  try {
510
- console.log(JSON.stringify(this.buildExplainJSON(router, agentType, task, opts.since), null, 2));
615
+ console.log(JSON.stringify(this.buildExplainJSON(router, agentType, task, opts.since, runtime), null, 2));
511
616
  }
512
617
  catch (err) {
513
618
  // A PII/governance policy block must not crash the JSON contract —
@@ -526,6 +631,14 @@ export class ModelCommand extends BaseCommand {
526
631
  console.log('');
527
632
  logger.highlight('═══ Auto Model Routing — Explain ═══');
528
633
  console.log('');
634
+ // Item 14 — say plainly what this decision could NOT see, so an offline
635
+ // answer is never read as the live one. `explain` has no session: a
636
+ // continuation's routing text and the session's failed-provider set exist
637
+ // only at runtime, and both change the pick.
638
+ logger.info(`Runtime inputs: context ${runtime.contextTokens !== undefined ? `~${runtime.contextTokens} tokens` : '(estimated from the task)'} · ` +
639
+ `excluded providers: ${runtime.excludeProviders?.length ? runtime.excludeProviders.join(', ') : 'none'}`);
640
+ logger.info('A live session also carries its own failed-provider set; pass --exclude-provider to reproduce it, and --context-tokens to match a large history.');
641
+ console.log('');
529
642
  if (task) {
530
643
  logger.info(`Task: "${task}" · Agent: ${agentType}`);
531
644
  console.log('');
@@ -533,10 +646,10 @@ export class ModelCommand extends BaseCommand {
533
646
  // P3-M3.3: `--since <ref>` renders a before → after diff against a
534
647
  // previous explain snapshot instead of the full decision view.
535
648
  if (opts.since) {
536
- this.renderRoutingDecisionDiff(router, agentType, task, opts.since);
649
+ this.renderRoutingDecisionDiff(router, agentType, task, opts.since, runtime);
537
650
  }
538
651
  else {
539
- this.renderRoutingDecision(router, agentType, task);
652
+ this.renderRoutingDecision(router, agentType, task, false, runtime);
540
653
  }
541
654
  }
542
655
  catch (err) {
@@ -560,7 +673,7 @@ export class ModelCommand extends BaseCommand {
560
673
  for (const s of EXPLAIN_SAMPLES) {
561
674
  logger.highlight(` ${s.label} — "${s.task}"`);
562
675
  try {
563
- this.renderRoutingDecision(router, agentType, s.task, true);
676
+ this.renderRoutingDecision(router, agentType, s.task, true, runtime);
564
677
  }
565
678
  catch (err) {
566
679
  // A single sample that violates a PII/governance policy renders the
@@ -599,9 +712,9 @@ export class ModelCommand extends BaseCommand {
599
712
  * Single task → one decision object; no task → all 5 sample complexities.
600
713
  * Includes effective per-provider pricing (with override flags).
601
714
  */
602
- buildExplainJSON(router, agentType, task, since) {
715
+ buildExplainJSON(router, agentType, task, since, runtime = {}) {
603
716
  const toJSON = (t, agent) => {
604
- const d = router.resolve(agent, t, buildAutoResolveOptions(this.configManager), this.configManager);
717
+ const d = this.resolveExplainDecision(router, agent, t, runtime);
605
718
  const snapshot = this.buildSnapshot(d);
606
719
  // Record the explain snapshot for the dashboard audit trail + usage stats
607
720
  // (JSON mode returns early in showExplain, so this is the only hook here)
@@ -678,6 +791,12 @@ export class ModelCommand extends BaseCommand {
678
791
  : undefined,
679
792
  pricing,
680
793
  explanation: d.explanation,
794
+ // Item 14 — the runtime inputs this decision was reproduced with, so a
795
+ // script can tell a hypothetical from a reproduced live decision.
796
+ runtimeInputs: {
797
+ contextTokens: runtime.contextTokens,
798
+ excludedProviders: runtime.excludeProviders ?? [],
799
+ },
681
800
  ...(diff ? { diff } : {}),
682
801
  };
683
802
  };
@@ -688,6 +807,62 @@ export class ModelCommand extends BaseCommand {
688
807
  decisions: EXPLAIN_SAMPLES.map((s) => toJSON(s.task, agentType)),
689
808
  };
690
809
  }
810
+ /**
811
+ * D4 — resolve an explain decision through the SAME options the RUNTIME uses.
812
+ *
813
+ * `chat.ts` layers two things on top of the shared resolve-options assembly
814
+ * before calling the router, and `explain` passed neither:
815
+ *
816
+ * - `circuitBreakerStatus`, which is what SUNKS a provider sitting in a
817
+ * cooling-down circuit breaker. Without it every row looked healthy and
818
+ * `explain` could name a provider the runtime would never serve.
819
+ * - the NLU `taskIntentHint`, which the runtime derives from the same task
820
+ * string via `parseRequestSync`/`resolveDispatch` and which overrides the
821
+ * profile's intent (e.g. a creative ask), so the two could classify one
822
+ * task differently.
823
+ *
824
+ * Sharing the assembly is the only way the two can agree: both divergences
825
+ * were options the explain path never passed. The NLU derivation is
826
+ * deterministic in the task text, so seeding it here is reproducing the
827
+ * runtime's assembly, not guessing.
828
+ */
829
+ resolveExplainDecision(router, agentType, task, runtime = {}) {
830
+ let circuitBreakerStatus = [];
831
+ try {
832
+ circuitBreakerStatus = getProviderFallback(this.configManager).getCircuitBreakerStatus();
833
+ }
834
+ catch {
835
+ // Best-effort — a breaker read must never break `explain`.
836
+ }
837
+ // Item 14 — the session's failed-provider set exists only at runtime, so
838
+ // `explain` could not see it and could name a provider the session had
839
+ // already parked. Fold each caller-named exclusion in as an active cooldown:
840
+ // the router sinks it by scoring, exactly as it sinks a live failure.
841
+ if (runtime.excludeProviders?.length) {
842
+ const byProvider = new Map(circuitBreakerStatus.map((c) => [c.provider, c.cooldownRemaining]));
843
+ for (const p of runtime.excludeProviders) {
844
+ byProvider.set(p, Math.max(byProvider.get(p) ?? 0, SESSION_EXCLUDE_COOLDOWN_MS));
845
+ }
846
+ circuitBreakerStatus = [...byProvider].map(([provider, cooldownRemaining]) => ({ provider, cooldownRemaining }));
847
+ }
848
+ // Same NLU seed as the runtime: one parser call on the same text, so an
849
+ // intent the runtime honours is never invisible to `explain`.
850
+ let taskIntentHint;
851
+ try {
852
+ taskIntentHint = resolveDispatch(parseRequestSync(task)).taskIntentHint;
853
+ }
854
+ catch {
855
+ // Best-effort — a parse failure must never break `explain`.
856
+ }
857
+ return router.resolve(agentType, task, {
858
+ // Item 14 — the context preflight is part of the pickup, so the token
859
+ // count the runtime saw must reach it; otherwise `explain` estimates
860
+ // from the task and can name a different provider under a large history.
861
+ ...buildAutoResolveOptions(this.configManager, { contextHintTokens: runtime.contextTokens }),
862
+ circuitBreakerStatus,
863
+ ...(taskIntentHint ? { taskIntentHint } : {}),
864
+ }, this.configManager);
865
+ }
691
866
  /**
692
867
  * Build a RoutingSnapshot from a live decision — the ranked breakdown with
693
868
  * dimensions and governance context, persisted with explain decisions so
@@ -750,9 +925,9 @@ export class ModelCommand extends BaseCommand {
750
925
  * P3-M3.3: resolve the previous explain decision and render the before →
751
926
  * after diff for the current decision (which is also recorded).
752
927
  */
753
- renderRoutingDecisionDiff(router, agentType, task, ref) {
928
+ renderRoutingDecisionDiff(router, agentType, task, ref, runtime = {}) {
754
929
  const prev = this.resolveExplainRef(ref);
755
- const decision = router.resolve(agentType, task, buildAutoResolveOptions(this.configManager), this.configManager);
930
+ const decision = this.resolveExplainDecision(router, agentType, task, runtime);
756
931
  const snapshot = this.buildSnapshot(decision);
757
932
  recordRoutingDecision({
758
933
  source: 'explain',
@@ -782,8 +957,8 @@ export class ModelCommand extends BaseCommand {
782
957
  console.log('');
783
958
  }
784
959
  /** Render a single routing decision (compact or detailed). */
785
- renderRoutingDecision(router, agentType, task, compact = false) {
786
- const decision = router.resolve(agentType, task, buildAutoResolveOptions(this.configManager), this.configManager);
960
+ renderRoutingDecision(router, agentType, task, compact = false, runtime = {}) {
961
+ const decision = this.resolveExplainDecision(router, agentType, task, runtime);
787
962
  // Record the explain snapshot for the dashboard audit trail + usage stats
788
963
  recordRoutingDecision({
789
964
  source: 'explain',
@@ -809,9 +984,17 @@ export class ModelCommand extends BaseCommand {
809
984
  }
810
985
  console.log('');
811
986
  logger.highlight(' ── Ranked providers ──');
987
+ // D5 — the list is ordered by AVAILABILITY FIRST (a cooling-down provider
988
+ // sinks, then a quota-parked one, and only then by score within each group),
989
+ // because that IS the routing precedence. But only `score` was printed, so a
990
+ // lower-scored healthy row sitting above a higher-scored cooling one read as
991
+ // an unsorted list (measured: 0.351, 0.465, 0.397, 0.396). The ranking was
992
+ // never wrong — the header was silent about the key. State it, so the display
993
+ // can never appear to contradict the numbers it prints.
994
+ console.log(' (ordered availability-first — cooling-down, then quota-parked, then score within each group)');
812
995
  decision.ranked.forEach((r, i) => {
813
996
  const mark = r.provider === decision.provider ? '✅' : ' ';
814
- const cd = r.inCooldown ? ' (circuit-breaker cooldown)' : '';
997
+ const cd = r.inCooldown ? ' (circuit-breaker cooldown)' : r.quotaParked ? ' (quota-parked)' : '';
815
998
  const fit = r.capabilityFit !== undefined ? ` 🎯 fit ${Math.round(r.capabilityFit * 100)}%` : '';
816
999
  // M2.2/visibility: cost source on EVERY ranked row — 📏 measured (with
817
1000
  // the real wire-token basis) or 📐 estimated (length-based default).
@@ -833,6 +1016,103 @@ export class ModelCommand extends BaseCommand {
833
1016
  console.log('');
834
1017
  logger.success(` Decision: ${decision.provider}/${decision.model}`);
835
1018
  console.log(` ${decision.explanation}`);
1019
+ // D7 — PAIR ENTITLEMENT (2026-10-07). Rank said WHICH model; it never said
1020
+ // whether this ACCOUNT may call it. The reported case was four providers
1021
+ // offering one model where only one key had access — identical ranks, so the
1022
+ // decision was not explainable from the ranking at all. Print the verdict for
1023
+ // the chosen pair, and every same-model twin on another provider with ITS
1024
+ // OWN verdict, so "why this provider and not that one" is answerable from the
1025
+ // output instead of from the registry file. Twins are grouped by the honest
1026
+ // exact/bare-id rule (`areTwins`), and each verdict is read from its own row —
1027
+ // never inherited from a sibling.
1028
+ try {
1029
+ const registry = getModelRegistry();
1030
+ const chosenEntry = registry.getEntry(decision.provider, decision.model);
1031
+ const chosen = classifyPairEntitlement(chosenEntry);
1032
+ const twins = registry
1033
+ .getTrackedProviders()
1034
+ .flatMap((p) => registry.getAllModelsForProvider(p))
1035
+ .filter((e) => e.provider !== decision.provider && areTwins(e.model, decision.model));
1036
+ if (chosen !== 'funded' || twins.length > 0) {
1037
+ console.log('');
1038
+ logger.highlight(' ── Pair entitlement ──');
1039
+ console.log(` ${ENTITLEMENT_LABEL[chosen]} ${decision.provider}/${decision.model} — ${entitlementNote(chosen, chosenEntry)}`);
1040
+ if (twins.length > 0) {
1041
+ // WHERE the grouping came from: a declared alias is an assertion, the
1042
+ // bare-id rule is a derivation, and a reader must be able to tell them
1043
+ // apart (`learning/model-identity.ts`).
1044
+ const provenance = identityProvenance(decision.model);
1045
+ console.log(` (grouped as the same model${provenance ? ` — ${provenance}` : ' — exact/bare id rule'})`);
1046
+ }
1047
+ for (const t of twins) {
1048
+ const e = classifyPairEntitlement(t);
1049
+ console.log(` ${ENTITLEMENT_LABEL[e]} ${t.provider}/${t.model} — ${entitlementNote(e, t)}`);
1050
+ }
1051
+ }
1052
+ }
1053
+ catch {
1054
+ // Best-effort — an audit section must never break `model explain`.
1055
+ }
1056
+ // Bundle 3b — CAPABILITY BY MEASUREMENT. The scorecard the decision was made
1057
+ // from, in the terms the user asked for: five named parameters, each with its
1058
+ // SAMPLE COUNT, so a number can be weighed instead of trusted. A parameter on
1059
+ // 0 samples is the declared prior by definition (`capability-evidence.ts`),
1060
+ // which is why it is labelled rather than hidden — a bare number with no
1061
+ // basis was the defect, and the same number printed as "prior" is honest.
1062
+ try {
1063
+ const router = getAutoRouter();
1064
+ const registry = getModelRegistry();
1065
+ const base = router.getCapabilities(decision.provider);
1066
+ const record = registry.getCapability(decision.provider, decision.model);
1067
+ // §6 — the external catalogue supplies `cost`/`ecosystem` PRIORS only (never measurements), and
1068
+ // only while the feed is switched on; `externalPriorsFor` enforces that gate itself. Each one
1069
+ // carries the source it came from, so the scorecard can print a borrowed number AS borrowed.
1070
+ const external = externalPriorsFor(decision.provider, decision.model);
1071
+ const externalPriors = {};
1072
+ const priorLabels = {};
1073
+ for (const p of external) {
1074
+ externalPriors[p.parameter] = p.value;
1075
+ priorLabels[p.parameter] = { source: p.source, fetchedAt: p.fetchedAt };
1076
+ }
1077
+ const priors = {
1078
+ accuracy: base.reasoning,
1079
+ performance: base.speed,
1080
+ ...externalPriors,
1081
+ };
1082
+ // `accuracy`'s prior is the provider's own declared baseline (the same one
1083
+ // the router's floor uses); anything the feed supplied beats the declared default, so the TIER
1084
+ // below is derived from the same value the line above prints — they cannot disagree.
1085
+ const view = (parameter) => parameter === 'accuracy'
1086
+ ? effectiveParameter(record, 'accuracy', base.reasoning)
1087
+ : effectiveParameter(record, parameter, priors[parameter] ?? DEFAULT_PRIORS[parameter] ?? 0);
1088
+ console.log('');
1089
+ logger.highlight(' ── Capability scorecard (measured) ──');
1090
+ console.log(` ${decision.provider}/${decision.model}`);
1091
+ for (const line of capabilityLines(record, priors, priorLabels))
1092
+ console.log(` ${line}`);
1093
+ console.log(` tier ${deriveTier({ accuracy: view('accuracy'), robustness: view('robustness'), ecosystem: view('ecosystem') })}`);
1094
+ console.log(' (0 samples = the declared prior; values fold in real turns, calls and latencies — never from the model id)');
1095
+ }
1096
+ catch {
1097
+ // Best-effort — an audit section must never break `model explain`.
1098
+ }
1099
+ // Bundle 31/33 — ACCEPTANCE BY MEASUREMENT, read-only. Rendered through the
1100
+ // SAME `formatAcceptanceSummary` that `nuvira rate --stats` and the dashboard
1101
+ // Trace card use, so all three surfaces describe the one corpus identically. The
1102
+ // decision's own pair is focused first; the harness-level fit
1103
+ // `P(accepted | features)` follows. NOTHING routes on it, and when the sample is
1104
+ // too thin it says WHY instead of printing a number that would read as one.
1105
+ try {
1106
+ const pairKey = `${decision.provider}/${decision.model}`;
1107
+ console.log('');
1108
+ logger.highlight(' ── Acceptance (labelled turns, read-only) ──');
1109
+ for (const line of formatAcceptanceSummary(acceptanceSummary(), pairKey)) {
1110
+ console.log(` ${line}`);
1111
+ }
1112
+ }
1113
+ catch {
1114
+ // Best-effort — an audit section must never break `model explain`.
1115
+ }
836
1116
  // M2.4: governance transparency — show policy-eliminated providers so the
837
1117
  // user sees WHY a provider is absent from the ranking (not just that it
838
1118
  // is). Renders only when the admin policy actually blocked something.