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
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Tier-3 behavioural labels — the verdict the harness can INFER from what the
3
+ * user DID, without the user saying anything.
4
+ *
5
+ * WHY A THIRD TIER. An explicit verdict (`nuvira rate`, the dashboard Trace tab)
6
+ * is the only source of a POSITIVE label, but it only exists when the user
7
+ * bothers to give one. Between "the user rated it" and "the user said nothing at
8
+ * all" there is behaviour the harness can OBSERVE: a re-ask, a hand-edit of the
9
+ * delivered file, an untouched artifact the user then referenced. Those are
10
+ * inferences, not statements, so they carry `source: 'derived'` and a fit can
11
+ * weigh them BELOW a human judgement.
12
+ *
13
+ * THE RULE THAT KEEPS THIS HONEST. Silence is still NOT acceptance. An untouched
14
+ * artifact is not a label on its own — it becomes a (weak) acceptance only when
15
+ * the user's next message REFERENCES that artifact without reporting a regression.
16
+ * A raw untouched file the user never mentioned stays `null`, exactly like a turn
17
+ * nobody rated. The three signals, in priority order:
18
+ *
19
+ * 1. repeat-ask — the new ask is near-identical to the delivered ask
20
+ * (Jaccard similarity), so the delivery did not land. → rejected
21
+ * 2. hand-edit — the delivered file changed after the turn made it,
22
+ * so the user had to fix it. → rejected
23
+ * 3. unchanged-referenced — the file is untouched AND the new message names it
24
+ * AND no regression was reported. → accepted
25
+ *
26
+ * NOTHING ROUTES ON THIS. It labels the deliverable corpus and the turn's trace,
27
+ * the same two places an explicit verdict writes, and that is all.
28
+ *
29
+ * The similarity and reference tests are MEASURED (token overlap, a filename
30
+ * appearing in the text) — never a phrase list of "sounds like they liked it".
31
+ */
32
+ /** Why a behavioural label was derived — kept so a reader can audit the inference. */
33
+ export type BehaviouralReason = 'repeat-ask' | 'hand-edit' | 'unchanged-referenced';
34
+ /** A derived verdict. `source` is ALWAYS `'derived'` — that is the point of the tier. */
35
+ export interface BehaviouralLabel {
36
+ verdict: 'accepted' | 'rejected';
37
+ source: 'derived';
38
+ reason: BehaviouralReason;
39
+ }
40
+ /**
41
+ * Token-set Jaccard at or above which two asks are the SAME request.
42
+ *
43
+ * Deliberately high: a re-ask is usually near-verbatim, and a false positive here
44
+ * would mark a genuinely NEW request as a rejection of the last one. Two different
45
+ * asks about the same subject share only their common words, which pulls the score
46
+ * well below this line.
47
+ */
48
+ export declare const REPEAT_ASK_SIMILARITY = 0.9;
49
+ /** Alphanumeric word tokens, lowercased. No stoplist — overlap is measured, not curated. */
50
+ export declare function normalizeAskTokens(text: string): Set<string>;
51
+ /** Jaccard similarity of two asks' token sets (0 when either is empty). */
52
+ export declare function askSimilarity(a: string, b: string): number;
53
+ /** Does the message NAME the artifact — its filename (with or without extension)? */
54
+ export declare function referencesArtifact(newAsk: string, path: string): boolean;
55
+ /** True when the file exists and its mtime is AFTER the delivery (+ slack). Never throws. */
56
+ export declare function wasModifiedAfter(path: string, deliveredAt: number, epsilonMs?: number): boolean;
57
+ /**
58
+ * The pure decision, so the inference can be unit-tested without a filesystem.
59
+ * `null` means "no label is justified" — which is the common, honest answer.
60
+ */
61
+ export declare function classifyBehaviouralLabel(input: {
62
+ newAsk: string;
63
+ previousAsk: string;
64
+ reportsRegression: boolean;
65
+ artifactPath: string | null;
66
+ artifactModified: boolean;
67
+ referencesArtifact: boolean;
68
+ }): BehaviouralLabel | null;
69
+ /**
70
+ * Read the newest UNLABELLED delivery, infer a behavioural label, and apply it.
71
+ *
72
+ * Returns the label that was applied, or null when nothing was justified. Every
73
+ * write is best-effort.
74
+ */
75
+ export declare function deriveAndApplyBehaviouralLabel(input: {
76
+ newAsk: string;
77
+ reportsRegression: boolean;
78
+ now?: number;
79
+ }): BehaviouralLabel | null;
80
+ /**
81
+ * Write a derived label to the same two places an explicit verdict writes: the
82
+ * delivery's corpus row and (when the row knows its trace) the turn's trace.
83
+ * Best-effort — a label write must never break a turn.
84
+ */
85
+ export declare function applyBehaviouralLabel(traceId: string | undefined, label: BehaviouralLabel, now?: number): void;
86
+ //# sourceMappingURL=behavioural-labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavioural-labels.d.ts","sourceRoot":"","sources":["../../src/learning/behavioural-labels.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAWH,sFAAsF;AACtF,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,WAAW,GAAG,sBAAsB,CAAC;AAEpF,yFAAyF;AACzF,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,UAAU,GAAG,UAAU,CAAC;IACjC,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAKzC,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAG5D;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ1D;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQxE;AAED,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,SAAwB,GAAG,OAAO,CAQ9G;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;CAC7B,GAAG,gBAAgB,GAAG,IAAI,CAkB1B;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,gBAAgB,GAAG,IAAI,CAyB1B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE,gBAAgB,EACvB,GAAG,GAAE,MAAmB,GACvB,IAAI,CAaN"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Tier-3 behavioural labels — the verdict the harness can INFER from what the
3
+ * user DID, without the user saying anything.
4
+ *
5
+ * WHY A THIRD TIER. An explicit verdict (`nuvira rate`, the dashboard Trace tab)
6
+ * is the only source of a POSITIVE label, but it only exists when the user
7
+ * bothers to give one. Between "the user rated it" and "the user said nothing at
8
+ * all" there is behaviour the harness can OBSERVE: a re-ask, a hand-edit of the
9
+ * delivered file, an untouched artifact the user then referenced. Those are
10
+ * inferences, not statements, so they carry `source: 'derived'` and a fit can
11
+ * weigh them BELOW a human judgement.
12
+ *
13
+ * THE RULE THAT KEEPS THIS HONEST. Silence is still NOT acceptance. An untouched
14
+ * artifact is not a label on its own — it becomes a (weak) acceptance only when
15
+ * the user's next message REFERENCES that artifact without reporting a regression.
16
+ * A raw untouched file the user never mentioned stays `null`, exactly like a turn
17
+ * nobody rated. The three signals, in priority order:
18
+ *
19
+ * 1. repeat-ask — the new ask is near-identical to the delivered ask
20
+ * (Jaccard similarity), so the delivery did not land. → rejected
21
+ * 2. hand-edit — the delivered file changed after the turn made it,
22
+ * so the user had to fix it. → rejected
23
+ * 3. unchanged-referenced — the file is untouched AND the new message names it
24
+ * AND no regression was reported. → accepted
25
+ *
26
+ * NOTHING ROUTES ON THIS. It labels the deliverable corpus and the turn's trace,
27
+ * the same two places an explicit verdict writes, and that is all.
28
+ *
29
+ * The similarity and reference tests are MEASURED (token overlap, a filename
30
+ * appearing in the text) — never a phrase list of "sounds like they liked it".
31
+ */
32
+ import { statSync } from 'node:fs';
33
+ import { basename, extname } from 'node:path';
34
+ import { readDeliverableCandidates, labelNewestUnlabelled, labelDeliverableByTrace, } from './deliverable-corpus.js';
35
+ import { recordTraceVerdict } from './reasoning-trace.js';
36
+ /**
37
+ * Token-set Jaccard at or above which two asks are the SAME request.
38
+ *
39
+ * Deliberately high: a re-ask is usually near-verbatim, and a false positive here
40
+ * would mark a genuinely NEW request as a rejection of the last one. Two different
41
+ * asks about the same subject share only their common words, which pulls the score
42
+ * well below this line.
43
+ */
44
+ export const REPEAT_ASK_SIMILARITY = 0.9;
45
+ /** Filesystem timestamp slack: a write finishing at the same instant as delivery is not an edit. */
46
+ const FILE_MTIME_EPSILON_MS = 250;
47
+ /** Alphanumeric word tokens, lowercased. No stoplist — overlap is measured, not curated. */
48
+ export function normalizeAskTokens(text) {
49
+ const tokens = (text || '').toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
50
+ return new Set(tokens.filter((t) => t.length >= 2));
51
+ }
52
+ /** Jaccard similarity of two asks' token sets (0 when either is empty). */
53
+ export function askSimilarity(a, b) {
54
+ const sa = normalizeAskTokens(a);
55
+ const sb = normalizeAskTokens(b);
56
+ if (sa.size === 0 || sb.size === 0)
57
+ return 0;
58
+ let inter = 0;
59
+ for (const t of sa)
60
+ if (sb.has(t))
61
+ inter++;
62
+ const union = sa.size + sb.size - inter;
63
+ return union === 0 ? 0 : inter / union;
64
+ }
65
+ /** Does the message NAME the artifact — its filename (with or without extension)? */
66
+ export function referencesArtifact(newAsk, path) {
67
+ if (!path)
68
+ return false;
69
+ const text = (newAsk || '').toLowerCase();
70
+ const base = basename(path).toLowerCase();
71
+ const stem = base.slice(0, base.length - extname(base).length);
72
+ if (stem.length >= 2 && normalizeAskTokens(newAsk).has(stem))
73
+ return true;
74
+ // The full filename mentioned verbatim (e.g. "guide.md") also counts.
75
+ return base.length >= 2 && text.includes(base);
76
+ }
77
+ /** True when the file exists and its mtime is AFTER the delivery (+ slack). Never throws. */
78
+ export function wasModifiedAfter(path, deliveredAt, epsilonMs = FILE_MTIME_EPSILON_MS) {
79
+ try {
80
+ const st = statSync(path);
81
+ return st.mtimeMs > deliveredAt + epsilonMs;
82
+ }
83
+ catch {
84
+ // A path we cannot resolve (different cwd, deleted file) is not evidence of an edit.
85
+ return false;
86
+ }
87
+ }
88
+ /**
89
+ * The pure decision, so the inference can be unit-tested without a filesystem.
90
+ * `null` means "no label is justified" — which is the common, honest answer.
91
+ */
92
+ export function classifyBehaviouralLabel(input) {
93
+ // A reported regression is already labelled by the explicit correction path
94
+ // (`detectRegressionSignal`). Deriving a second label for it would double-count
95
+ // one event, so the behavioural tier stands aside.
96
+ if (input.reportsRegression)
97
+ return null;
98
+ if (askSimilarity(input.newAsk, input.previousAsk) >= REPEAT_ASK_SIMILARITY) {
99
+ return { verdict: 'rejected', source: 'derived', reason: 'repeat-ask' };
100
+ }
101
+ // An edit is checked BEFORE any acceptance: a file the user rewrote is the
102
+ // strongest behavioural negative, whether or not they mentioned it.
103
+ if (input.artifactModified) {
104
+ return { verdict: 'rejected', source: 'derived', reason: 'hand-edit' };
105
+ }
106
+ if (input.referencesArtifact) {
107
+ return { verdict: 'accepted', source: 'derived', reason: 'unchanged-referenced' };
108
+ }
109
+ return null;
110
+ }
111
+ /**
112
+ * Read the newest UNLABELLED delivery, infer a behavioural label, and apply it.
113
+ *
114
+ * Returns the label that was applied, or null when nothing was justified. Every
115
+ * write is best-effort.
116
+ */
117
+ export function deriveAndApplyBehaviouralLabel(input) {
118
+ if (input.reportsRegression)
119
+ return null;
120
+ let row;
121
+ try {
122
+ const rows = readDeliverableCandidates();
123
+ row = [...rows].reverse().find((r) => r.verdict === null);
124
+ }
125
+ catch {
126
+ return null;
127
+ }
128
+ if (!row)
129
+ return null;
130
+ const artifactModified = row.path ? wasModifiedAfter(row.path, row.ts) : false;
131
+ const referenced = row.path ? referencesArtifact(input.newAsk, row.path) : false;
132
+ const label = classifyBehaviouralLabel({
133
+ newAsk: input.newAsk,
134
+ previousAsk: row.ask,
135
+ reportsRegression: false,
136
+ artifactPath: row.path ?? null,
137
+ artifactModified,
138
+ referencesArtifact: referenced,
139
+ });
140
+ if (!label)
141
+ return null;
142
+ applyBehaviouralLabel(row.traceId, label, input.now ?? Date.now());
143
+ return label;
144
+ }
145
+ /**
146
+ * Write a derived label to the same two places an explicit verdict writes: the
147
+ * delivery's corpus row and (when the row knows its trace) the turn's trace.
148
+ * Best-effort — a label write must never break a turn.
149
+ */
150
+ export function applyBehaviouralLabel(traceId, label, now = Date.now()) {
151
+ try {
152
+ if (traceId) {
153
+ labelDeliverableByTrace(traceId, label.verdict, now);
154
+ recordTraceVerdict(traceId, label.verdict, label.source, now);
155
+ }
156
+ else {
157
+ // No trace to hang it on: label the newest unlabelled row directly. The
158
+ // cue is real (we are looking at that delivery), so this is not invention.
159
+ labelNewestUnlabelled(label.verdict, now);
160
+ }
161
+ }
162
+ catch {
163
+ // Best-effort.
164
+ }
165
+ }
166
+ //# sourceMappingURL=behavioural-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavioural-labels.js","sourceRoot":"","sources":["../../src/learning/behavioural-labels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * CAPABILITY BY MEASUREMENT (Bundle 3, B1–B4) — the scorecard.
3
+ *
4
+ * THE DEFECT THIS REPLACES. `AutoModelRouter.getModelCapabilities()` judges a
5
+ * model from its NAME: `mini`/`tiny`/`flash`/`lite` each SUBTRACT 0.1 from
6
+ * reasoning (so `gemini-3.1-flash-lite` loses 0.2 for two words), `pro`/`large`/
7
+ * `opus` add, a `70b` in the id adds 0.45, and a frontier-family keyword adds
8
+ * 0.2. Nothing in the system had ever measured whether a model is any good, so
9
+ * max mode's reasoning floor was a NAME threshold, and this programme's own
10
+ * investigation fell into the trap it was reporting: it called DeepSeek V4.1
11
+ * Flash weak *because of the word "flash"* while that model served an 82-step
12
+ * build.
13
+ *
14
+ * THE REPLACEMENT. One record per provider × model holding five named
15
+ * parameters, each 0–100 with its own sample count, fed from what the harness
16
+ * OBSERVES while doing real work:
17
+ *
18
+ * accuracy did the work actually verify (TurnReport.verification)
19
+ * performance how fast it answered, per call (registry latency EMA)
20
+ * cost what the work cost (measured tokens × price)
21
+ * robustness does it hold up across many calls (errorRate / partialRate)
22
+ * ecosystem what the pair can do besides answer (tool-calling, window)
23
+ *
24
+ * THE PRIOR RULE (§3.2), and the one thing to read before changing anything:
25
+ * **0 samples returns the declared prior, byte-for-byte.** Measurement replaces
26
+ * the prior as samples accumulate (`PRIOR_FULL_SAMPLES`) — a wrong prior can
27
+ * outrank evidence for a while, but never after the record has real samples.
28
+ * The id-substring terms are REMOVED, not capped: a capped name hint is still a
29
+ * name judgement, and "the name contributes nothing" is the whole acceptance.
30
+ *
31
+ * WHAT THIS MODULE DOES NOT DO. It is pure — no registry, no I/O — so the
32
+ * arithmetic is testable in isolation and the storage layer decides when to call
33
+ * it. It never invents a sample: a turn that verified nothing contributes
34
+ * NOTHING (not a neutral 50), because a run that never checks its work has no
35
+ * accuracy evidence, and a fabricated neutral sample would dilute the real ones.
36
+ */
37
+ /** The five named parameters, in the order `model explain` prints them. */
38
+ export type CapabilityParameter = 'accuracy' | 'performance' | 'cost' | 'robustness' | 'ecosystem';
39
+ /** How many observations a parameter needs before it is reported as MEASURED. */
40
+ export declare const MIN_SAMPLES_FOR_EVIDENCE = 5;
41
+ /**
42
+ * Samples at which the prior's weight reaches zero. Between 0 and here the prior
43
+ * decays LINEARLY (`priorWeight = 1 - samples / PRIOR_FULL_SAMPLES`), so a single
44
+ * lucky or unlucky turn cannot swing a ranking, and a model with a real track
45
+ * record is judged by it. Stated here rather than inline because §7 of the design
46
+ * calls the decay rate a calibration decision, not a constant to bury.
47
+ */
48
+ export declare const PRIOR_FULL_SAMPLES: number;
49
+ /** EMA weight for one observation. Matches the registry's latency/token EMAs. */
50
+ export declare const EVIDENCE_ALPHA = 0.3;
51
+ /** Where a reported value came from. Printed beside every number. */
52
+ export type EvidenceSource = 'measured' | 'prior';
53
+ /** One parameter: the measured value (0–100), how many samples, and its source. */
54
+ export interface ParameterScore {
55
+ /** Measured value 0–100. Meaningless on its own — always pair it with `samples`. */
56
+ measured: number;
57
+ /** Observations folded in. 0 = nothing measured yet. */
58
+ samples: number;
59
+ }
60
+ /**
61
+ * The scorecard for one provider × model. Every parameter is optional: absent
62
+ * means "nothing measured", which reports as the prior rather than as a zero.
63
+ */
64
+ export interface CapabilityRecord {
65
+ accuracy?: ParameterScore;
66
+ performance?: ParameterScore;
67
+ cost?: ParameterScore;
68
+ robustness?: ParameterScore;
69
+ ecosystem?: ParameterScore;
70
+ /** Epoch ms of the last fold. */
71
+ updatedAt: number;
72
+ }
73
+ /**
74
+ * Accuracy weights per turn verdict. `verified` is the strongest evidence the
75
+ * harness can produce (a change was made AND observed). `unverified` is real but
76
+ * weak evidence: the model answered, and its work could not be confirmed — so it
77
+ * pulls the score down without being scored as an outright failure, which would
78
+ * double-count the same event (`applyReward`'s `verificationPassed: false`
79
+ * already carries that penalty).
80
+ *
81
+ * A `blocked` turn is NOT here on purpose: a wall the run hit is not a verdict
82
+ * about the model.
83
+ */
84
+ export declare const ACCURACY_BY_VERDICT: {
85
+ readonly verified: 100;
86
+ readonly unverified: 40;
87
+ };
88
+ /** A fresh record: nothing measured. */
89
+ export declare function emptyCapabilityRecord(now?: number): CapabilityRecord;
90
+ /**
91
+ * Fold a turn's verification verdict into `accuracy`. `blocked`/
92
+ * `not-applicable`/`delivered-and-read-back`/absent contribute nothing at all (see
93
+ * the header). `delivered-and-read-back` is NEUTRAL on purpose: it proves an authored
94
+ * document exists and was read back, not that it is correct or complete, so folding
95
+ * it either way would invent a quality signal the evidence does not carry.
96
+ */
97
+ export declare function foldVerification(record: CapabilityRecord, verification: 'verified' | 'unverified' | 'blocked' | 'not-applicable' | 'delivered-and-read-back' | undefined | null, now?: number): CapabilityRecord;
98
+ /** Fold one measured call's outcome into `robustness` (0–100 per call). */
99
+ export declare function foldCallOutcome(record: CapabilityRecord, ok: boolean, now?: number): CapabilityRecord;
100
+ /** Fold a measured latency into `performance` (a call under 800 ms scores 100). */
101
+ export declare function foldLatency(record: CapabilityRecord, latencyMs: number | undefined, now?: number): CapabilityRecord;
102
+ /**
103
+ * The value to USE for a parameter, and whether it is measured or borrowed.
104
+ *
105
+ * THE ONE RULE THAT DECIDES EVERYTHING: with no samples the answer is exactly the
106
+ * prior passed in. That is what makes this change safe to land before the record
107
+ * has any data — behaviour on a cold start is unchanged — and it is what makes
108
+ * the acceptance test "two ids differing only by a tier word score identically"
109
+ * true, since the prior is provider-level and cannot see the id.
110
+ */
111
+ export declare function effectiveParameter(record: CapabilityRecord | undefined, parameter: CapabilityParameter, priorFraction: number): {
112
+ value: number;
113
+ samples: number;
114
+ source: EvidenceSource;
115
+ };
116
+ /** Capability tier, DERIVED from the parameters — never parsed from an id. */
117
+ export type CapabilityTier = 'Frontier' | 'Balanced' | 'Utility';
118
+ /**
119
+ * Derive the tier. Deliberately coarse and stated in one place:
120
+ * - `Utility` — accuracy is poor, or the pair is unreliable;
121
+ * - `Frontier` — strong accuracy AND a wide ecosystem;
122
+ * - `Balanced` — everything else, which is most things.
123
+ * `ecosystem` participates because a strong answerer that cannot call tools is
124
+ * not a frontier AGENT model, and this harness only cares about agent models.
125
+ */
126
+ export declare function deriveTier(view: {
127
+ accuracy: {
128
+ value: number;
129
+ samples: number;
130
+ };
131
+ robustness: {
132
+ value: number;
133
+ samples: number;
134
+ };
135
+ ecosystem: {
136
+ value: number;
137
+ samples: number;
138
+ };
139
+ }): CapabilityTier;
140
+ /**
141
+ * Declared priors for the parameters a cold start cannot supply.
142
+ *
143
+ * `accuracy` and `performance` are deliberately ABSENT: their priors are the
144
+ * provider's own declared baseline, which only the router knows. `cost` is
145
+ * absent too — pricing belongs to a provider ACCOUNT, so with no measurement the
146
+ * honest answer is "no prior" rather than a number that reads as free:
147
+ *
148
+ * - `robustness: 0.7` — most pairs answer most of the time; a prior, replaced
149
+ * by measurement as soon as calls are recorded;
150
+ * - `ecosystem: 0.5` — nothing is known about tool-calling until observed, and
151
+ * 0.5 keeps a pair OUT of the `Frontier` gate (which needs ≥ 0.7). A pair we
152
+ * have never watched use a tool is not a frontier agent model.
153
+ */
154
+ export declare const DEFAULT_PRIORS: Record<CapabilityParameter, number | undefined>;
155
+ /**
156
+ * The whole scorecard as printable rows: `accuracy 78 (measured, n=14)`.
157
+ *
158
+ * The sample count is NOT optional — a score without one is exactly the
159
+ * plausible-looking number this programme exists to remove — and a parameter with
160
+ * neither a prior nor a sample prints `n/a` rather than a `0` that would read as
161
+ * "free" or "broken".
162
+ */
163
+ export declare function capabilityLines(record: CapabilityRecord | undefined, priors?: Partial<Record<CapabilityParameter, number>>, priorLabels?: Partial<Record<CapabilityParameter, {
164
+ source: string;
165
+ fetchedAt: number;
166
+ }>>): string[];
167
+ //# sourceMappingURL=capability-evidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-evidence.d.ts","sourceRoot":"","sources":["../../src/learning/capability-evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,210 @@
1
+ /**
2
+ * CAPABILITY BY MEASUREMENT (Bundle 3, B1–B4) — the scorecard.
3
+ *
4
+ * THE DEFECT THIS REPLACES. `AutoModelRouter.getModelCapabilities()` judges a
5
+ * model from its NAME: `mini`/`tiny`/`flash`/`lite` each SUBTRACT 0.1 from
6
+ * reasoning (so `gemini-3.1-flash-lite` loses 0.2 for two words), `pro`/`large`/
7
+ * `opus` add, a `70b` in the id adds 0.45, and a frontier-family keyword adds
8
+ * 0.2. Nothing in the system had ever measured whether a model is any good, so
9
+ * max mode's reasoning floor was a NAME threshold, and this programme's own
10
+ * investigation fell into the trap it was reporting: it called DeepSeek V4.1
11
+ * Flash weak *because of the word "flash"* while that model served an 82-step
12
+ * build.
13
+ *
14
+ * THE REPLACEMENT. One record per provider × model holding five named
15
+ * parameters, each 0–100 with its own sample count, fed from what the harness
16
+ * OBSERVES while doing real work:
17
+ *
18
+ * accuracy did the work actually verify (TurnReport.verification)
19
+ * performance how fast it answered, per call (registry latency EMA)
20
+ * cost what the work cost (measured tokens × price)
21
+ * robustness does it hold up across many calls (errorRate / partialRate)
22
+ * ecosystem what the pair can do besides answer (tool-calling, window)
23
+ *
24
+ * THE PRIOR RULE (§3.2), and the one thing to read before changing anything:
25
+ * **0 samples returns the declared prior, byte-for-byte.** Measurement replaces
26
+ * the prior as samples accumulate (`PRIOR_FULL_SAMPLES`) — a wrong prior can
27
+ * outrank evidence for a while, but never after the record has real samples.
28
+ * The id-substring terms are REMOVED, not capped: a capped name hint is still a
29
+ * name judgement, and "the name contributes nothing" is the whole acceptance.
30
+ *
31
+ * WHAT THIS MODULE DOES NOT DO. It is pure — no registry, no I/O — so the
32
+ * arithmetic is testable in isolation and the storage layer decides when to call
33
+ * it. It never invents a sample: a turn that verified nothing contributes
34
+ * NOTHING (not a neutral 50), because a run that never checks its work has no
35
+ * accuracy evidence, and a fabricated neutral sample would dilute the real ones.
36
+ */
37
+ /** How many observations a parameter needs before it is reported as MEASURED. */
38
+ export const MIN_SAMPLES_FOR_EVIDENCE = 5;
39
+ /**
40
+ * Samples at which the prior's weight reaches zero. Between 0 and here the prior
41
+ * decays LINEARLY (`priorWeight = 1 - samples / PRIOR_FULL_SAMPLES`), so a single
42
+ * lucky or unlucky turn cannot swing a ranking, and a model with a real track
43
+ * record is judged by it. Stated here rather than inline because §7 of the design
44
+ * calls the decay rate a calibration decision, not a constant to bury.
45
+ */
46
+ export const PRIOR_FULL_SAMPLES = 2 * MIN_SAMPLES_FOR_EVIDENCE;
47
+ /** EMA weight for one observation. Matches the registry's latency/token EMAs. */
48
+ export const EVIDENCE_ALPHA = 0.3;
49
+ /**
50
+ * Accuracy weights per turn verdict. `verified` is the strongest evidence the
51
+ * harness can produce (a change was made AND observed). `unverified` is real but
52
+ * weak evidence: the model answered, and its work could not be confirmed — so it
53
+ * pulls the score down without being scored as an outright failure, which would
54
+ * double-count the same event (`applyReward`'s `verificationPassed: false`
55
+ * already carries that penalty).
56
+ *
57
+ * A `blocked` turn is NOT here on purpose: a wall the run hit is not a verdict
58
+ * about the model.
59
+ */
60
+ export const ACCURACY_BY_VERDICT = {
61
+ verified: 100,
62
+ unverified: 40,
63
+ };
64
+ /** A fresh record: nothing measured. */
65
+ export function emptyCapabilityRecord(now = Date.now()) {
66
+ return { updatedAt: now };
67
+ }
68
+ /** Fold one 0–100 observation into a parameter's EMA (α = `EVIDENCE_ALPHA`). */
69
+ function foldEMA(score, observation) {
70
+ const obs = Math.max(0, Math.min(100, observation));
71
+ if (!score || score.samples <= 0)
72
+ return { measured: obs, samples: 1 };
73
+ return {
74
+ measured: EVIDENCE_ALPHA * obs + (1 - EVIDENCE_ALPHA) * score.measured,
75
+ samples: score.samples + 1,
76
+ };
77
+ }
78
+ /**
79
+ * Fold a turn's verification verdict into `accuracy`. `blocked`/
80
+ * `not-applicable`/`delivered-and-read-back`/absent contribute nothing at all (see
81
+ * the header). `delivered-and-read-back` is NEUTRAL on purpose: it proves an authored
82
+ * document exists and was read back, not that it is correct or complete, so folding
83
+ * it either way would invent a quality signal the evidence does not carry.
84
+ */
85
+ export function foldVerification(record, verification, now = Date.now()) {
86
+ if (verification !== 'verified' && verification !== 'unverified')
87
+ return record;
88
+ return {
89
+ ...record,
90
+ accuracy: foldEMA(record.accuracy, ACCURACY_BY_VERDICT[verification]),
91
+ updatedAt: now,
92
+ };
93
+ }
94
+ /** Fold one measured call's outcome into `robustness` (0–100 per call). */
95
+ export function foldCallOutcome(record, ok, now = Date.now()) {
96
+ return {
97
+ ...record,
98
+ robustness: foldEMA(record.robustness, ok ? 100 : 0),
99
+ updatedAt: now,
100
+ };
101
+ }
102
+ /** Fold a measured latency into `performance` (a call under 800 ms scores 100). */
103
+ export function foldLatency(record, latencyMs, now = Date.now()) {
104
+ if (!latencyMs || latencyMs <= 0)
105
+ return record;
106
+ // 800 ms or faster = 100; 10 s or slower = 0; linear between. The scale is
107
+ // stated, not inferred, so `model explain` can explain a number it prints.
108
+ const scaled = Math.max(0, Math.min(100, 100 * (1 - (latencyMs - 800) / (10_000 - 800))));
109
+ return {
110
+ ...record,
111
+ performance: foldEMA(record.performance, scaled),
112
+ updatedAt: now,
113
+ };
114
+ }
115
+ /**
116
+ * The value to USE for a parameter, and whether it is measured or borrowed.
117
+ *
118
+ * THE ONE RULE THAT DECIDES EVERYTHING: with no samples the answer is exactly the
119
+ * prior passed in. That is what makes this change safe to land before the record
120
+ * has any data — behaviour on a cold start is unchanged — and it is what makes
121
+ * the acceptance test "two ids differing only by a tier word score identically"
122
+ * true, since the prior is provider-level and cannot see the id.
123
+ */
124
+ export function effectiveParameter(record, parameter, priorFraction) {
125
+ const prior = Math.max(0, Math.min(1, priorFraction));
126
+ const score = record?.[parameter];
127
+ const samples = score?.samples ?? 0;
128
+ if (!score || samples <= 0)
129
+ return { value: prior, samples: 0, source: 'prior' };
130
+ const priorWeight = Math.max(0, 1 - samples / PRIOR_FULL_SAMPLES);
131
+ // Stored 0–100 (see `foldEMA`), reported 0–1 like every other capability scalar.
132
+ const measured = Math.max(0, Math.min(100, score.measured)) / 100;
133
+ const value = priorWeight * prior + (1 - priorWeight) * measured;
134
+ return {
135
+ value: Math.max(0, Math.min(1, value)),
136
+ samples,
137
+ source: samples >= MIN_SAMPLES_FOR_EVIDENCE ? 'measured' : 'prior',
138
+ };
139
+ }
140
+ /**
141
+ * Derive the tier. Deliberately coarse and stated in one place:
142
+ * - `Utility` — accuracy is poor, or the pair is unreliable;
143
+ * - `Frontier` — strong accuracy AND a wide ecosystem;
144
+ * - `Balanced` — everything else, which is most things.
145
+ * `ecosystem` participates because a strong answerer that cannot call tools is
146
+ * not a frontier AGENT model, and this harness only cares about agent models.
147
+ */
148
+ export function deriveTier(view) {
149
+ if (view.accuracy.value < 0.5 || view.robustness.value < 0.5)
150
+ return 'Utility';
151
+ if (view.accuracy.value >= 0.8 && view.ecosystem.value >= 0.7)
152
+ return 'Frontier';
153
+ return 'Balanced';
154
+ }
155
+ /**
156
+ * Declared priors for the parameters a cold start cannot supply.
157
+ *
158
+ * `accuracy` and `performance` are deliberately ABSENT: their priors are the
159
+ * provider's own declared baseline, which only the router knows. `cost` is
160
+ * absent too — pricing belongs to a provider ACCOUNT, so with no measurement the
161
+ * honest answer is "no prior" rather than a number that reads as free:
162
+ *
163
+ * - `robustness: 0.7` — most pairs answer most of the time; a prior, replaced
164
+ * by measurement as soon as calls are recorded;
165
+ * - `ecosystem: 0.5` — nothing is known about tool-calling until observed, and
166
+ * 0.5 keeps a pair OUT of the `Frontier` gate (which needs ≥ 0.7). A pair we
167
+ * have never watched use a tool is not a frontier agent model.
168
+ */
169
+ export const DEFAULT_PRIORS = {
170
+ accuracy: undefined,
171
+ performance: undefined,
172
+ cost: undefined,
173
+ robustness: 0.7,
174
+ ecosystem: 0.5,
175
+ };
176
+ /**
177
+ * The whole scorecard as printable rows: `accuracy 78 (measured, n=14)`.
178
+ *
179
+ * The sample count is NOT optional — a score without one is exactly the
180
+ * plausible-looking number this programme exists to remove — and a parameter with
181
+ * neither a prior nor a sample prints `n/a` rather than a `0` that would read as
182
+ * "free" or "broken".
183
+ */
184
+ export function capabilityLines(record, priors = {}, priorLabels = {}) {
185
+ return ['accuracy', 'performance', 'cost', 'robustness', 'ecosystem'].map((p) => {
186
+ const prior = priors[p] ?? DEFAULT_PRIORS[p];
187
+ if (prior === undefined) {
188
+ const samples = record?.[p]?.samples ?? 0;
189
+ return samples > 0
190
+ ? `${p} ${Math.round((record?.[p]?.measured ?? 0))} (measured, n=${samples})`
191
+ : `${p} n/a (no prior declared, nothing measured)`;
192
+ }
193
+ const { value, samples, source } = effectiveParameter(record, p, prior);
194
+ const pct = Math.round(value * 100);
195
+ // §6.2 rule 4: a borrowed number must say WHERE it was borrowed from, so a reader can tell an
196
+ // observation from a prior. An unlabelled prior still prints the bare `prior` it always did —
197
+ // the label is added, never substituted.
198
+ const basis = source === 'measured' ? 'measured' : describePrior(p, priorLabels);
199
+ return `${p} ${pct} (${basis}${samples > 0 ? `, n=${samples}` : ''})`;
200
+ });
201
+ }
202
+ /** `prior` alone, or `prior: <source>, <date>` when the prior came from somewhere nameable. */
203
+ function describePrior(p, labels) {
204
+ const label = labels[p];
205
+ if (!label)
206
+ return 'prior';
207
+ const day = new Date(label.fetchedAt).toISOString().slice(0, 10);
208
+ return `prior: ${label.source}, ${day}`;
209
+ }
210
+ //# sourceMappingURL=capability-evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-evidence.js","sourceRoot":"","sources":["../../src/learning/capability-evidence.ts"],"names":[],"mappings":"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"}