@kindgi/api 0.1.4 → 0.1.5-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. package/dist/agent-binding.d.ts +13 -0
  2. package/dist/agent-binding.d.ts.map +1 -1
  3. package/dist/agent-pins.d.ts.map +1 -1
  4. package/dist/agent-pins.js +18 -2
  5. package/dist/agent-pins.js.map +1 -1
  6. package/dist/app.d.ts +110 -17
  7. package/dist/app.d.ts.map +1 -1
  8. package/dist/app.js +163 -35
  9. package/dist/app.js.map +1 -1
  10. package/dist/block-publish.d.ts +56 -0
  11. package/dist/block-publish.d.ts.map +1 -0
  12. package/dist/block-publish.js +132 -0
  13. package/dist/block-publish.js.map +1 -0
  14. package/dist/caller.d.ts +24 -0
  15. package/dist/caller.d.ts.map +1 -0
  16. package/dist/caller.js +47 -0
  17. package/dist/caller.js.map +1 -0
  18. package/dist/capability-binding.d.ts +11 -0
  19. package/dist/capability-binding.d.ts.map +1 -1
  20. package/dist/derive-agent-version.d.ts +7 -0
  21. package/dist/derive-agent-version.d.ts.map +1 -1
  22. package/dist/derive-agent-version.js +4 -0
  23. package/dist/derive-agent-version.js.map +1 -1
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +73 -7
  26. package/dist/errors.js.map +1 -1
  27. package/dist/eval-case-binding.d.ts +16 -4
  28. package/dist/eval-case-binding.d.ts.map +1 -1
  29. package/dist/eval-run-binding.d.ts +31 -0
  30. package/dist/eval-run-binding.d.ts.map +1 -1
  31. package/dist/eval-run-dispatcher.d.ts +7 -0
  32. package/dist/eval-run-dispatcher.d.ts.map +1 -1
  33. package/dist/eval-run-dispatcher.js.map +1 -1
  34. package/dist/eval-sample.d.ts +11 -0
  35. package/dist/eval-sample.d.ts.map +1 -0
  36. package/dist/eval-sample.js +34 -0
  37. package/dist/eval-sample.js.map +1 -0
  38. package/dist/eval-suite-binding.d.ts +13 -0
  39. package/dist/eval-suite-binding.d.ts.map +1 -1
  40. package/dist/eval-suite-binding.js.map +1 -1
  41. package/dist/flow-binding.d.ts +18 -0
  42. package/dist/flow-binding.d.ts.map +1 -1
  43. package/dist/flow-pins.d.ts.map +1 -1
  44. package/dist/flow-pins.js +18 -2
  45. package/dist/flow-pins.js.map +1 -1
  46. package/dist/gate.d.ts.map +1 -1
  47. package/dist/gate.js +25 -0
  48. package/dist/gate.js.map +1 -1
  49. package/dist/handler-binding.d.ts +32 -0
  50. package/dist/handler-binding.d.ts.map +1 -1
  51. package/dist/hitl-binding.d.ts +23 -0
  52. package/dist/hitl-binding.d.ts.map +1 -1
  53. package/dist/identity-directory-binding.d.ts +82 -4
  54. package/dist/identity-directory-binding.d.ts.map +1 -1
  55. package/dist/identity-provider-binding.d.ts +197 -17
  56. package/dist/identity-provider-binding.d.ts.map +1 -1
  57. package/dist/improvement-pass-binding.d.ts +196 -0
  58. package/dist/improvement-pass-binding.d.ts.map +1 -0
  59. package/dist/improvement-pass-binding.js +9 -0
  60. package/dist/improvement-pass-binding.js.map +1 -0
  61. package/dist/index.d.ts +35 -17
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +11 -3
  64. package/dist/index.js.map +1 -1
  65. package/dist/judged-dispatcher.d.ts +25 -4
  66. package/dist/judged-dispatcher.d.ts.map +1 -1
  67. package/dist/judged-dispatcher.js +43 -6
  68. package/dist/judged-dispatcher.js.map +1 -1
  69. package/dist/judgment-binding.d.ts +25 -1
  70. package/dist/judgment-binding.d.ts.map +1 -1
  71. package/dist/mcp-endpoint-binding.d.ts +7 -0
  72. package/dist/mcp-endpoint-binding.d.ts.map +1 -1
  73. package/dist/memory-binding.d.ts +124 -17
  74. package/dist/memory-binding.d.ts.map +1 -1
  75. package/dist/memory-erasure-binding.d.ts +145 -0
  76. package/dist/memory-erasure-binding.d.ts.map +1 -0
  77. package/dist/memory-erasure-binding.js +4 -0
  78. package/dist/memory-erasure-binding.js.map +1 -0
  79. package/dist/middleware/auth.d.ts +66 -13
  80. package/dist/middleware/auth.d.ts.map +1 -1
  81. package/dist/middleware/auth.js +150 -50
  82. package/dist/middleware/auth.js.map +1 -1
  83. package/dist/middleware/authorize.d.ts +6 -0
  84. package/dist/middleware/authorize.d.ts.map +1 -1
  85. package/dist/middleware/authorize.js +113 -4
  86. package/dist/middleware/authorize.js.map +1 -1
  87. package/dist/middleware/error-mapper.d.ts +5 -0
  88. package/dist/middleware/error-mapper.d.ts.map +1 -1
  89. package/dist/middleware/error-mapper.js +14 -1
  90. package/dist/middleware/error-mapper.js.map +1 -1
  91. package/dist/middleware/idempotency.d.ts +70 -5
  92. package/dist/middleware/idempotency.d.ts.map +1 -1
  93. package/dist/middleware/idempotency.js +174 -41
  94. package/dist/middleware/idempotency.js.map +1 -1
  95. package/dist/middleware/key-project.d.ts +17 -0
  96. package/dist/middleware/key-project.d.ts.map +1 -0
  97. package/dist/middleware/key-project.js +75 -0
  98. package/dist/middleware/key-project.js.map +1 -0
  99. package/dist/middleware/principal.d.ts.map +1 -1
  100. package/dist/middleware/principal.js +9 -5
  101. package/dist/middleware/principal.js.map +1 -1
  102. package/dist/middleware/project-ref.d.ts.map +1 -1
  103. package/dist/middleware/project-ref.js +3 -0
  104. package/dist/middleware/project-ref.js.map +1 -1
  105. package/dist/openapi/generate.d.ts.map +1 -1
  106. package/dist/openapi/generate.js +5 -2
  107. package/dist/openapi/generate.js.map +1 -1
  108. package/dist/openapi/operations.d.ts.map +1 -1
  109. package/dist/openapi/operations.js +918 -139
  110. package/dist/openapi/operations.js.map +1 -1
  111. package/dist/openapi/schemas.d.ts +90 -13
  112. package/dist/openapi/schemas.d.ts.map +1 -1
  113. package/dist/openapi/schemas.js +2081 -359
  114. package/dist/openapi/schemas.js.map +1 -1
  115. package/dist/person-grants-binding.d.ts +77 -0
  116. package/dist/person-grants-binding.d.ts.map +1 -0
  117. package/dist/person-grants-binding.js +4 -0
  118. package/dist/person-grants-binding.js.map +1 -0
  119. package/dist/proposal-service.d.ts +121 -0
  120. package/dist/proposal-service.d.ts.map +1 -0
  121. package/dist/proposal-service.js +447 -0
  122. package/dist/proposal-service.js.map +1 -0
  123. package/dist/proposal-status.d.ts +60 -0
  124. package/dist/proposal-status.d.ts.map +1 -0
  125. package/dist/proposal-status.js +109 -0
  126. package/dist/proposal-status.js.map +1 -0
  127. package/dist/provider-binding.d.ts +10 -0
  128. package/dist/provider-binding.d.ts.map +1 -1
  129. package/dist/publish-refused.d.ts +18 -3
  130. package/dist/publish-refused.d.ts.map +1 -1
  131. package/dist/publish-refused.js +18 -3
  132. package/dist/publish-refused.js.map +1 -1
  133. package/dist/routes/adapters.d.ts +2 -1
  134. package/dist/routes/adapters.d.ts.map +1 -1
  135. package/dist/routes/adapters.js +3 -1
  136. package/dist/routes/adapters.js.map +1 -1
  137. package/dist/routes/agent-releases.d.ts +55 -3
  138. package/dist/routes/agent-releases.d.ts.map +1 -1
  139. package/dist/routes/agent-releases.js +85 -55
  140. package/dist/routes/agent-releases.js.map +1 -1
  141. package/dist/routes/agents.d.ts +12 -1
  142. package/dist/routes/agents.d.ts.map +1 -1
  143. package/dist/routes/agents.js +100 -2
  144. package/dist/routes/agents.js.map +1 -1
  145. package/dist/routes/approvals.d.ts +15 -3
  146. package/dist/routes/approvals.d.ts.map +1 -1
  147. package/dist/routes/approvals.js +133 -122
  148. package/dist/routes/approvals.js.map +1 -1
  149. package/dist/routes/artifacts.d.ts +25 -3
  150. package/dist/routes/artifacts.d.ts.map +1 -1
  151. package/dist/routes/artifacts.js +116 -7
  152. package/dist/routes/artifacts.js.map +1 -1
  153. package/dist/routes/auth.d.ts +25 -1
  154. package/dist/routes/auth.d.ts.map +1 -1
  155. package/dist/routes/auth.js +655 -281
  156. package/dist/routes/auth.js.map +1 -1
  157. package/dist/routes/blocks.d.ts.map +1 -1
  158. package/dist/routes/blocks.js +2 -42
  159. package/dist/routes/blocks.js.map +1 -1
  160. package/dist/routes/capabilities.d.ts +2 -1
  161. package/dist/routes/capabilities.d.ts.map +1 -1
  162. package/dist/routes/capabilities.js +6 -1
  163. package/dist/routes/capabilities.js.map +1 -1
  164. package/dist/routes/compliance.d.ts +9 -10
  165. package/dist/routes/compliance.d.ts.map +1 -1
  166. package/dist/routes/compliance.js +42 -61
  167. package/dist/routes/compliance.js.map +1 -1
  168. package/dist/routes/conversations.d.ts +8 -1
  169. package/dist/routes/conversations.d.ts.map +1 -1
  170. package/dist/routes/conversations.js +87 -8
  171. package/dist/routes/conversations.js.map +1 -1
  172. package/dist/routes/cost.d.ts +7 -1
  173. package/dist/routes/cost.d.ts.map +1 -1
  174. package/dist/routes/cost.js +22 -3
  175. package/dist/routes/cost.js.map +1 -1
  176. package/dist/routes/denied.d.ts +11 -0
  177. package/dist/routes/denied.d.ts.map +1 -0
  178. package/dist/routes/denied.js +17 -0
  179. package/dist/routes/denied.js.map +1 -0
  180. package/dist/routes/deployments.d.ts +2 -1
  181. package/dist/routes/deployments.d.ts.map +1 -1
  182. package/dist/routes/deployments.js +44 -12
  183. package/dist/routes/deployments.js.map +1 -1
  184. package/dist/routes/eval-comparison.d.ts.map +1 -1
  185. package/dist/routes/eval-comparison.js +69 -1
  186. package/dist/routes/eval-comparison.js.map +1 -1
  187. package/dist/routes/eval-overrides.d.ts +18 -0
  188. package/dist/routes/eval-overrides.d.ts.map +1 -0
  189. package/dist/routes/eval-overrides.js +81 -0
  190. package/dist/routes/eval-overrides.js.map +1 -0
  191. package/dist/routes/eval-runs.d.ts +10 -1
  192. package/dist/routes/eval-runs.d.ts.map +1 -1
  193. package/dist/routes/eval-runs.js +63 -7
  194. package/dist/routes/eval-runs.js.map +1 -1
  195. package/dist/routes/eval-suites.d.ts.map +1 -1
  196. package/dist/routes/eval-suites.js +20 -1
  197. package/dist/routes/eval-suites.js.map +1 -1
  198. package/dist/routes/event-triggers.d.ts +5 -1
  199. package/dist/routes/event-triggers.d.ts.map +1 -1
  200. package/dist/routes/event-triggers.js +26 -3
  201. package/dist/routes/event-triggers.js.map +1 -1
  202. package/dist/routes/export-signing-keys.d.ts +12 -0
  203. package/dist/routes/export-signing-keys.d.ts.map +1 -0
  204. package/dist/routes/export-signing-keys.js +24 -0
  205. package/dist/routes/export-signing-keys.js.map +1 -0
  206. package/dist/routes/flows.d.ts.map +1 -1
  207. package/dist/routes/flows.js +9 -1
  208. package/dist/routes/flows.js.map +1 -1
  209. package/dist/routes/gate-policies.d.ts +4 -1
  210. package/dist/routes/gate-policies.d.ts.map +1 -1
  211. package/dist/routes/gate-policies.js +29 -5
  212. package/dist/routes/gate-policies.js.map +1 -1
  213. package/dist/routes/guardrails.d.ts +16 -14
  214. package/dist/routes/guardrails.d.ts.map +1 -1
  215. package/dist/routes/guardrails.js +39 -3
  216. package/dist/routes/guardrails.js.map +1 -1
  217. package/dist/routes/identity.d.ts +20 -4
  218. package/dist/routes/identity.d.ts.map +1 -1
  219. package/dist/routes/identity.js +246 -6
  220. package/dist/routes/identity.js.map +1 -1
  221. package/dist/routes/improvement-passes.d.ts +52 -0
  222. package/dist/routes/improvement-passes.d.ts.map +1 -0
  223. package/dist/routes/improvement-passes.js +449 -0
  224. package/dist/routes/improvement-passes.js.map +1 -0
  225. package/dist/routes/judged-suites.d.ts +50 -0
  226. package/dist/routes/judged-suites.d.ts.map +1 -1
  227. package/dist/routes/judged-suites.js +66 -27
  228. package/dist/routes/judged-suites.js.map +1 -1
  229. package/dist/routes/judgment-context.d.ts +18 -2
  230. package/dist/routes/judgment-context.d.ts.map +1 -1
  231. package/dist/routes/judgment-context.js +63 -5
  232. package/dist/routes/judgment-context.js.map +1 -1
  233. package/dist/routes/judgment-flow-context.d.ts.map +1 -1
  234. package/dist/routes/judgment-flow-context.js +14 -2
  235. package/dist/routes/judgment-flow-context.js.map +1 -1
  236. package/dist/routes/judgments.d.ts.map +1 -1
  237. package/dist/routes/judgments.js +8 -1
  238. package/dist/routes/judgments.js.map +1 -1
  239. package/dist/routes/mcp.d.ts.map +1 -1
  240. package/dist/routes/mcp.js +26 -1
  241. package/dist/routes/mcp.js.map +1 -1
  242. package/dist/routes/memory-access.d.ts +43 -0
  243. package/dist/routes/memory-access.d.ts.map +1 -0
  244. package/dist/routes/memory-access.js +129 -0
  245. package/dist/routes/memory-access.js.map +1 -0
  246. package/dist/routes/memory-erasures.d.ts +25 -0
  247. package/dist/routes/memory-erasures.d.ts.map +1 -0
  248. package/dist/routes/memory-erasures.js +214 -0
  249. package/dist/routes/memory-erasures.js.map +1 -0
  250. package/dist/routes/memory-parse.d.ts +38 -0
  251. package/dist/routes/memory-parse.d.ts.map +1 -0
  252. package/dist/routes/memory-parse.js +199 -0
  253. package/dist/routes/memory-parse.js.map +1 -0
  254. package/dist/routes/memory.d.ts +9 -4
  255. package/dist/routes/memory.d.ts.map +1 -1
  256. package/dist/routes/memory.js +226 -234
  257. package/dist/routes/memory.js.map +1 -1
  258. package/dist/routes/observations.d.ts +4 -1
  259. package/dist/routes/observations.d.ts.map +1 -1
  260. package/dist/routes/observations.js +8 -2
  261. package/dist/routes/observations.js.map +1 -1
  262. package/dist/routes/pagination.d.ts +7 -0
  263. package/dist/routes/pagination.d.ts.map +1 -1
  264. package/dist/routes/pagination.js +10 -0
  265. package/dist/routes/pagination.js.map +1 -1
  266. package/dist/routes/policies.d.ts +2 -1
  267. package/dist/routes/policies.d.ts.map +1 -1
  268. package/dist/routes/policies.js +3 -1
  269. package/dist/routes/policies.js.map +1 -1
  270. package/dist/routes/project-mismatch.d.ts +22 -0
  271. package/dist/routes/project-mismatch.d.ts.map +1 -0
  272. package/dist/routes/project-mismatch.js +34 -0
  273. package/dist/routes/project-mismatch.js.map +1 -0
  274. package/dist/routes/projects.d.ts +15 -4
  275. package/dist/routes/projects.d.ts.map +1 -1
  276. package/dist/routes/projects.js +100 -9
  277. package/dist/routes/projects.js.map +1 -1
  278. package/dist/routes/proposals.d.ts +25 -17
  279. package/dist/routes/proposals.d.ts.map +1 -1
  280. package/dist/routes/proposals.js +340 -507
  281. package/dist/routes/proposals.js.map +1 -1
  282. package/dist/routes/provenance.d.ts +17 -3
  283. package/dist/routes/provenance.d.ts.map +1 -1
  284. package/dist/routes/provenance.js +79 -103
  285. package/dist/routes/provenance.js.map +1 -1
  286. package/dist/routes/providers.d.ts +17 -1
  287. package/dist/routes/providers.d.ts.map +1 -1
  288. package/dist/routes/providers.js +110 -3
  289. package/dist/routes/providers.js.map +1 -1
  290. package/dist/routes/public-run-tokens.d.ts.map +1 -1
  291. package/dist/routes/public-run-tokens.js +3 -0
  292. package/dist/routes/public-run-tokens.js.map +1 -1
  293. package/dist/routes/runs.d.ts +10 -0
  294. package/dist/routes/runs.d.ts.map +1 -1
  295. package/dist/routes/runs.js +92 -42
  296. package/dist/routes/runs.js.map +1 -1
  297. package/dist/routes/schedules.d.ts +21 -13
  298. package/dist/routes/schedules.d.ts.map +1 -1
  299. package/dist/routes/schedules.js +416 -55
  300. package/dist/routes/schedules.js.map +1 -1
  301. package/dist/routes/segments.d.ts +2 -0
  302. package/dist/routes/segments.d.ts.map +1 -1
  303. package/dist/routes/segments.js +5 -0
  304. package/dist/routes/segments.js.map +1 -1
  305. package/dist/routes/service-accounts.d.ts +17 -0
  306. package/dist/routes/service-accounts.d.ts.map +1 -0
  307. package/dist/routes/service-accounts.js +212 -0
  308. package/dist/routes/service-accounts.js.map +1 -0
  309. package/dist/routes/sign-in-options.d.ts +50 -0
  310. package/dist/routes/sign-in-options.d.ts.map +1 -0
  311. package/dist/routes/sign-in-options.js +98 -0
  312. package/dist/routes/sign-in-options.js.map +1 -0
  313. package/dist/routes/signing-keys.d.ts +2 -1
  314. package/dist/routes/signing-keys.d.ts.map +1 -1
  315. package/dist/routes/signing-keys.js +3 -1
  316. package/dist/routes/signing-keys.js.map +1 -1
  317. package/dist/routes/tenant-access.d.ts +13 -0
  318. package/dist/routes/tenant-access.d.ts.map +1 -0
  319. package/dist/routes/tenant-access.js +26 -0
  320. package/dist/routes/tenant-access.js.map +1 -0
  321. package/dist/routes/tenant.d.ts.map +1 -1
  322. package/dist/routes/tenant.js +4 -0
  323. package/dist/routes/tenant.js.map +1 -1
  324. package/dist/routes/token-sign-in.d.ts +36 -0
  325. package/dist/routes/token-sign-in.d.ts.map +1 -0
  326. package/dist/routes/token-sign-in.js +101 -0
  327. package/dist/routes/token-sign-in.js.map +1 -0
  328. package/dist/routes/tokens.d.ts +15 -5
  329. package/dist/routes/tokens.d.ts.map +1 -1
  330. package/dist/routes/tokens.js +162 -43
  331. package/dist/routes/tokens.js.map +1 -1
  332. package/dist/routes/tools.d.ts.map +1 -1
  333. package/dist/routes/tools.js +9 -1
  334. package/dist/routes/tools.js.map +1 -1
  335. package/dist/routes/trigger-access.d.ts +29 -0
  336. package/dist/routes/trigger-access.d.ts.map +1 -0
  337. package/dist/routes/trigger-access.js +33 -0
  338. package/dist/routes/trigger-access.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +2 -1
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -1
  341. package/dist/routes/webhook-endpoints.js +11 -3
  342. package/dist/routes/webhook-endpoints.js.map +1 -1
  343. package/dist/routes/webhooks.d.ts +5 -1
  344. package/dist/routes/webhooks.d.ts.map +1 -1
  345. package/dist/routes/webhooks.js +25 -2
  346. package/dist/routes/webhooks.js.map +1 -1
  347. package/dist/run-failure.d.ts +21 -0
  348. package/dist/run-failure.d.ts.map +1 -0
  349. package/dist/run-failure.js +29 -0
  350. package/dist/run-failure.js.map +1 -0
  351. package/dist/service-account-binding.d.ts +108 -0
  352. package/dist/service-account-binding.d.ts.map +1 -0
  353. package/dist/service-account-binding.js +4 -0
  354. package/dist/service-account-binding.js.map +1 -0
  355. package/dist/session-store-binding.d.ts +61 -13
  356. package/dist/session-store-binding.d.ts.map +1 -1
  357. package/dist/signed-export.d.ts +89 -0
  358. package/dist/signed-export.d.ts.map +1 -0
  359. package/dist/signed-export.js +149 -0
  360. package/dist/signed-export.js.map +1 -0
  361. package/dist/supervisor-binding.d.ts +186 -413
  362. package/dist/supervisor-binding.d.ts.map +1 -1
  363. package/dist/testing/app-bindings.d.ts +33 -0
  364. package/dist/testing/app-bindings.d.ts.map +1 -0
  365. package/dist/testing/app-bindings.js +112 -0
  366. package/dist/testing/app-bindings.js.map +1 -0
  367. package/dist/testing/index.d.ts +11 -0
  368. package/dist/testing/index.d.ts.map +1 -0
  369. package/dist/testing/index.js +13 -0
  370. package/dist/testing/index.js.map +1 -0
  371. package/dist/testing/stub-binding.d.ts +34 -0
  372. package/dist/testing/stub-binding.d.ts.map +1 -0
  373. package/dist/testing/stub-binding.js +42 -0
  374. package/dist/testing/stub-binding.js.map +1 -0
  375. package/dist/testing/trigger-registry.d.ts +21 -0
  376. package/dist/testing/trigger-registry.d.ts.map +1 -0
  377. package/dist/testing/trigger-registry.js +206 -0
  378. package/dist/testing/trigger-registry.js.map +1 -0
  379. package/dist/token-admin.d.ts +46 -8
  380. package/dist/token-admin.d.ts.map +1 -1
  381. package/dist/token-admin.js.map +1 -1
  382. package/dist/tool-binding.d.ts +13 -0
  383. package/dist/tool-binding.d.ts.map +1 -1
  384. package/dist/trigger-binding.d.ts +2 -2
  385. package/dist/trigger-binding.d.ts.map +1 -1
  386. package/dist/trigger-binding.js +1 -1
  387. package/dist/trigger-binding.js.map +1 -1
  388. package/dist/types.d.ts +16 -0
  389. package/dist/types.d.ts.map +1 -1
  390. package/dist/webhook-endpoint-binding.d.ts +19 -3
  391. package/dist/webhook-endpoint-binding.d.ts.map +1 -1
  392. package/dist/webhook-endpoint-binding.js +1 -1
  393. package/dist/webhook-endpoint-binding.js.map +1 -1
  394. package/openapi.json +15385 -8788
  395. package/package.json +26 -22
  396. package/src/agent-binding.ts +14 -0
  397. package/src/agent-pins.ts +18 -2
  398. package/src/app.ts +366 -80
  399. package/src/block-publish.ts +181 -0
  400. package/src/caller.ts +62 -0
  401. package/src/capability-binding.ts +12 -0
  402. package/src/derive-agent-version.ts +9 -1
  403. package/src/errors.ts +73 -7
  404. package/src/eval-case-binding.ts +17 -1
  405. package/src/eval-run-binding.ts +31 -0
  406. package/src/eval-run-dispatcher.ts +7 -0
  407. package/src/eval-sample.ts +42 -0
  408. package/src/eval-suite-binding.ts +14 -0
  409. package/src/flow-binding.ts +19 -0
  410. package/src/flow-pins.ts +18 -2
  411. package/src/gate.ts +26 -0
  412. package/src/handler-binding.ts +36 -1
  413. package/src/hitl-binding.ts +24 -0
  414. package/src/identity-directory-binding.ts +85 -4
  415. package/src/identity-provider-binding.ts +216 -21
  416. package/src/improvement-pass-binding.ts +193 -0
  417. package/src/index.ts +153 -31
  418. package/src/judged-dispatcher.ts +78 -11
  419. package/src/judgment-binding.ts +25 -1
  420. package/src/mcp-endpoint-binding.ts +7 -0
  421. package/src/memory-binding.ts +121 -17
  422. package/src/memory-erasure-binding.ts +156 -0
  423. package/src/middleware/auth.ts +228 -62
  424. package/src/middleware/authorize.ts +139 -3
  425. package/src/middleware/error-mapper.ts +15 -1
  426. package/src/middleware/idempotency.ts +230 -43
  427. package/src/middleware/key-project.ts +86 -0
  428. package/src/middleware/principal.ts +9 -5
  429. package/src/middleware/project-ref.ts +3 -0
  430. package/src/openapi/generate.ts +11 -2
  431. package/src/openapi/operations.ts +1059 -142
  432. package/src/openapi/schemas.ts +2387 -469
  433. package/src/person-grants-binding.ts +76 -0
  434. package/src/proposal-service.ts +640 -0
  435. package/src/proposal-status.ts +176 -0
  436. package/src/provider-binding.ts +10 -0
  437. package/src/publish-refused.ts +38 -9
  438. package/src/routes/adapters.ts +4 -0
  439. package/src/routes/agent-releases.ts +121 -69
  440. package/src/routes/agents.ts +128 -1
  441. package/src/routes/approvals.ts +164 -154
  442. package/src/routes/artifacts.ts +181 -11
  443. package/src/routes/auth.ts +804 -336
  444. package/src/routes/blocks.ts +2 -53
  445. package/src/routes/capabilities.ts +10 -1
  446. package/src/routes/compliance.ts +60 -99
  447. package/src/routes/conversations.ts +101 -7
  448. package/src/routes/cost.ts +32 -3
  449. package/src/routes/denied.ts +28 -0
  450. package/src/routes/deployments.ts +62 -16
  451. package/src/routes/eval-comparison.ts +81 -2
  452. package/src/routes/eval-overrides.ts +108 -0
  453. package/src/routes/eval-runs.ts +86 -6
  454. package/src/routes/eval-suites.ts +25 -1
  455. package/src/routes/event-triggers.ts +27 -3
  456. package/src/routes/export-signing-keys.ts +31 -0
  457. package/src/routes/flows.ts +12 -1
  458. package/src/routes/gate-policies.ts +37 -6
  459. package/src/routes/guardrails.ts +61 -2
  460. package/src/routes/identity.ts +328 -10
  461. package/src/routes/improvement-passes.ts +541 -0
  462. package/src/routes/judged-suites.ts +113 -43
  463. package/src/routes/judgment-context.ts +76 -5
  464. package/src/routes/judgment-flow-context.ts +16 -2
  465. package/src/routes/judgments.ts +17 -3
  466. package/src/routes/mcp.ts +29 -1
  467. package/src/routes/memory-access.ts +179 -0
  468. package/src/routes/memory-erasures.ts +240 -0
  469. package/src/routes/memory-parse.ts +250 -0
  470. package/src/routes/memory.ts +244 -286
  471. package/src/routes/observations.ts +15 -2
  472. package/src/routes/pagination.ts +12 -0
  473. package/src/routes/policies.ts +7 -1
  474. package/src/routes/project-mismatch.ts +56 -0
  475. package/src/routes/projects.ts +107 -13
  476. package/src/routes/proposals.ts +370 -611
  477. package/src/routes/provenance.ts +99 -133
  478. package/src/routes/providers.ts +142 -3
  479. package/src/routes/public-run-tokens.ts +3 -0
  480. package/src/routes/runs.ts +119 -39
  481. package/src/routes/schedules.ts +472 -60
  482. package/src/routes/segments.ts +11 -0
  483. package/src/routes/service-accounts.ts +262 -0
  484. package/src/routes/sign-in-options.ts +168 -0
  485. package/src/routes/signing-keys.ts +7 -1
  486. package/src/routes/tenant-access.ts +37 -0
  487. package/src/routes/tenant.ts +6 -0
  488. package/src/routes/token-sign-in.ts +161 -0
  489. package/src/routes/tokens.ts +172 -46
  490. package/src/routes/tools.ts +12 -1
  491. package/src/routes/trigger-access.ts +72 -0
  492. package/src/routes/webhook-endpoints.ts +15 -3
  493. package/src/routes/webhooks.ts +26 -2
  494. package/src/run-failure.ts +42 -0
  495. package/src/service-account-binding.ts +113 -0
  496. package/src/session-store-binding.ts +65 -13
  497. package/src/signed-export.ts +250 -0
  498. package/src/supervisor-binding.ts +169 -409
  499. package/src/testing/app-bindings.ts +142 -0
  500. package/src/testing/index.ts +21 -0
  501. package/src/testing/stub-binding.ts +53 -0
  502. package/src/testing/trigger-registry.ts +259 -0
  503. package/src/token-admin.ts +40 -8
  504. package/src/tool-binding.ts +14 -0
  505. package/src/trigger-binding.ts +8 -1
  506. package/src/types.ts +16 -0
  507. package/src/webhook-endpoint-binding.ts +18 -3
@@ -9,7 +9,12 @@ import type { Agent, AgentId, AgentPins } from '@kindgi/agents';
9
9
  import { tuplesForCreate } from '@kindgi/authz';
10
10
  import { parsePublicKeyPem, verifyEd25519 } from '@kindgi/crypto';
11
11
  import type { Flow, FlowPins } from '@kindgi/flow';
12
- import { type Guardrail, validateGuardrailSpec } from '@kindgi/guardrails';
12
+ import {
13
+ GUARDRAIL_SPEC_KEYS,
14
+ type Guardrail,
15
+ createCheckRegistry,
16
+ validateGuardrailSpec,
17
+ } from '@kindgi/guardrails';
13
18
  import type { ProjectBinding, Scope } from '@kindgi/platform';
14
19
  import { validateToolManifest } from '@kindgi/tools';
15
20
  import type {
@@ -42,6 +47,7 @@ import { type FlowPinsLive, publishDeployedFlow, resolveFlowPins } from '../flow
42
47
  import type { GuardrailRegistryBinding } from '../guardrail-binding.js';
43
48
  import type { ImageRegistryBinding } from '../image-registry-binding.js';
44
49
  import type { LiveVersionBinding } from '../live-version-binding.js';
50
+ import type { Authorizer } from '../middleware/authorize.js';
45
51
  import { PublishRefused } from '../publish-refused.js';
46
52
  import { type RegistryReadOnly, refuseReadOnly } from '../registry-read-only.js';
47
53
  import type { SecretBinding } from '../secrets-binding.js';
@@ -51,6 +57,7 @@ import type { AppEnv } from '../types.js';
51
57
  import { hasCapability, requireEnvName } from './env.js';
52
58
  import type { GuardrailWriteHook } from './guardrails.js';
53
59
  import { clampLimit } from './pagination.js';
60
+ import { tenantResourceAccess } from './tenant-access.js';
54
61
  import type { ToolWriteHook } from './tools.js';
55
62
 
56
63
  /**
@@ -167,8 +174,12 @@ export interface DeploymentsRouterBindings {
167
174
  readonly onGuardrailWrite?: GuardrailWriteHook;
168
175
  }
169
176
 
170
- export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<AppEnv> {
177
+ export function deploymentsRouter(
178
+ bindings: DeploymentsRouterBindings,
179
+ authorizer?: Authorizer,
180
+ ): Hono<AppEnv> {
171
181
  const r = new Hono<AppEnv>();
182
+ r.use('*', tenantResourceAccess(authorizer));
172
183
 
173
184
  // ---------- GET / (list, cursor-paginated) ----------
174
185
  r.get('/', async (c) => {
@@ -476,10 +487,11 @@ export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<App
476
487
  }
477
488
 
478
489
  // ---- Manifest validation ----
479
- const validation = validatePrimitives(imageIndex, {
480
- imageRef: wire.imageRef,
481
- artifactVersion: wire.artifactVersion,
482
- });
490
+ const validation = validatePrimitives(
491
+ imageIndex,
492
+ { imageRef: wire.imageRef, artifactVersion: wire.artifactVersion },
493
+ c.get('log'),
494
+ );
483
495
  if (validation.kind === 'err') {
484
496
  c.status(statusFor('deployment-validation-failed') as never);
485
497
  return c.json(
@@ -580,7 +592,7 @@ export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<App
580
592
  await bindings.toolRegistry?.unregister({ tenantId, toolId, version });
581
593
  });
582
594
  } else if (outcome.kind !== 'already-registered') {
583
- throw new PublishRefused('tool', `${tool.id}@${tool.version}`, outcome.kind);
595
+ throw new PublishRefused('tool', `${tool.id}@${tool.version}`, outcome);
584
596
  }
585
597
  }
586
598
  }
@@ -605,7 +617,7 @@ export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<App
605
617
  await bindings.guardrailRegistry?.unregister({ tenantId, guardrailId });
606
618
  });
607
619
  } else if (outcome.kind !== 'already-registered') {
608
- throw new PublishRefused('guardrail', guardrail.id, outcome.kind);
620
+ throw new PublishRefused('guardrail', guardrail.id, outcome);
609
621
  }
610
622
  }
611
623
  }
@@ -645,6 +657,13 @@ export function deploymentsRouter(bindings: DeploymentsRouterBindings): Hono<App
645
657
  // A primitive refused with a typed outcome is the caller's to fix:
646
658
  // that outcome's own status and code. Anything thrown is a 500.
647
659
  if (cause instanceof PublishRefused) {
660
+ if (cause.projectId !== undefined) {
661
+ c.get('log').info(`${cause.message}: deploy refused`, {
662
+ primitive: cause.primitive,
663
+ id: cause.id,
664
+ ownerProjectId: cause.projectId as unknown as string,
665
+ });
666
+ }
648
667
  c.status(statusFor(cause.code) as never);
649
668
  return c.json(
650
669
  toWireError(
@@ -1236,9 +1255,13 @@ function ociCodeArtifactRef(image: DeployedImage, modulePath: unknown) {
1236
1255
  * a guardrail's `checkId` becomes its `check`, as `kindgi dev`'s disk
1237
1256
  * registry maps it.
1238
1257
  */
1258
+ /** The built-in checks, for the config of a guardrail naming one. */
1259
+ const builtInChecks = createCheckRegistry();
1260
+
1239
1261
  function validatePrimitives(
1240
1262
  index: Readonly<Record<string, unknown>>,
1241
1263
  image: DeployedImage,
1264
+ log?: { debug(message: string): void },
1242
1265
  ): ValidateResult {
1243
1266
  const details: ValidationDetail[] = [];
1244
1267
 
@@ -1286,12 +1309,20 @@ function validatePrimitives(
1286
1309
  details.push({ primitive: 'guardrail', index: i, path: '', message: 'must be an object' });
1287
1310
  return;
1288
1311
  }
1289
- const {
1290
- checkModulePath,
1291
- checkId,
1292
- configSchema: _configSchema,
1293
- ...rest
1294
- } = raw as Record<string, unknown>;
1312
+ // The rest is the guardrail as registered, its `configSchema` included:
1313
+ // the runtime checks a guardrail naming this check against it. A field
1314
+ // the guardrail spec doesn't have (an index from a newer CLI) is dropped,
1315
+ // never refused, so a newer CLI never breaks a deployment.
1316
+ const { checkModulePath, checkId, ...indexed } = raw as Record<string, unknown>;
1317
+ const dropped = Object.keys(indexed).filter((k) => !GUARDRAIL_SPEC_KEYS.includes(k));
1318
+ const rest = Object.fromEntries(
1319
+ Object.entries(indexed).filter(([k]) => GUARDRAIL_SPEC_KEYS.includes(k)),
1320
+ );
1321
+ if (dropped.length > 0) {
1322
+ log?.debug(
1323
+ `deployment: guardrail ${String(indexed.id)}: ignored index field(s) this runtime doesn't know: ${dropped.join(', ')}`,
1324
+ );
1325
+ }
1295
1326
  const r = validateGuardrailSpec({
1296
1327
  ...rest,
1297
1328
  check: checkId ?? rest.check ?? rest.id,
@@ -1325,6 +1356,21 @@ function validatePrimitives(
1325
1356
  }
1326
1357
  return;
1327
1358
  }
1359
+ // A guardrail naming a built-in check: its config against the built-in's.
1360
+ const builtIn = builtInChecks.get(r.value.check);
1361
+ const configProblems = builtIn?.configProblems?.(r.value.config) ?? [];
1362
+ if (configProblems.length > 0) {
1363
+ for (const problem of configProblems) {
1364
+ details.push({
1365
+ primitive: 'guardrail',
1366
+ index: i,
1367
+ id: r.value.id as unknown as string,
1368
+ path: problem.path,
1369
+ message: problem.message,
1370
+ });
1371
+ }
1372
+ return;
1373
+ }
1328
1374
  validatedGuardrails.push(r.value);
1329
1375
  });
1330
1376
 
@@ -1524,7 +1570,7 @@ async function registerAgents(input: {
1524
1570
  const outcome = await agents.publish({ tenantId, projectId, agent, enqueueTuples });
1525
1571
  if (outcome.kind === 'ok') written(outcome.agentId, outcome.version);
1526
1572
  else if (outcome.kind !== 'already-registered') {
1527
- throw new PublishRefused('agent', `${agent.id}@${agent.version}`, outcome.kind);
1573
+ throw new PublishRefused('agent', `${agent.id}@${agent.version}`, outcome);
1528
1574
  }
1529
1575
  }
1530
1576
  return input.defined.map(deployedPrimitive);
@@ -1588,7 +1634,7 @@ async function registerFlows(input: {
1588
1634
  const outcome = await flows.publish({ tenantId, projectId, flow, enqueueTuples });
1589
1635
  if (outcome.kind === 'ok') written(outcome.flowId, outcome.version as unknown as string);
1590
1636
  else if (outcome.kind !== 'already-registered') {
1591
- throw new PublishRefused('flow', `${flow.id}@${flow.version}`, outcome.kind);
1637
+ throw new PublishRefused('flow', `${flow.id}@${flow.version}`, outcome);
1592
1638
  }
1593
1639
  }
1594
1640
  return input.defined.map(deployedPrimitive);
@@ -5,12 +5,18 @@ import type { AgentId } from '@kindgi/agents';
5
5
  import type { FlowVersionOverrides } from '@kindgi/flow';
6
6
  import type { ProjectId, Semver } from '@kindgi/types';
7
7
 
8
- import type { EvalBaseline, EvalComparison } from '../eval-run-binding.js';
8
+ import type {
9
+ EvalBaseline,
10
+ EvalComparison,
11
+ EvalOverrides,
12
+ EvalSample,
13
+ } from '../eval-run-binding.js';
9
14
  import { DEFAULT_COMPARISON } from '../judged-dispatcher.js';
10
15
  import { parseSegmentsBody } from './segments.js';
11
16
 
12
17
  const MAX_REPETITIONS = 10;
13
18
  const MAX_K = 100;
19
+ const MAX_OVERRIDDEN_BLOCKS = 20;
14
20
 
15
21
  function obj(value: unknown): Record<string, unknown> | undefined {
16
22
  return typeof value === 'object' && value !== null && !Array.isArray(value)
@@ -84,6 +90,71 @@ function integerIn(raw: unknown, name: string, max: number): number | string {
84
90
  : `\`${name}\` must be an integer from 1 to ${max}`;
85
91
  }
86
92
 
93
+ /** `overrides: { settings?, prompts? }`; `undefined` when it names nothing. */
94
+ function parseOverrides(raw: unknown): EvalOverrides | undefined | string {
95
+ const o = obj(raw);
96
+ if (o === undefined) return '`overrides` must be an object: { settings?, prompts? }';
97
+ const extra = Object.keys(o).filter((key) => key !== 'settings' && key !== 'prompts');
98
+ if (extra.length > 0) {
99
+ return `\`overrides\` takes \`settings\` and \`prompts\`, not \`${extra[0]}\``;
100
+ }
101
+ const settings = o.settings === undefined ? {} : obj(o.settings);
102
+ const prompts = o.prompts === undefined ? {} : obj(o.prompts);
103
+ const settingsBlocks = settings === undefined ? [] : Object.entries(settings);
104
+ const promptBlocks = prompts === undefined ? [] : Object.entries(prompts);
105
+ if (
106
+ settings === undefined ||
107
+ settingsBlocks.length > MAX_OVERRIDDEN_BLOCKS ||
108
+ settingsBlocks.some(([id, values]) => id === '' || obj(values) === undefined)
109
+ ) {
110
+ return `\`overrides.settings\` must be an object of { blockId: { …values } } (at most ${MAX_OVERRIDDEN_BLOCKS} blocks)`;
111
+ }
112
+ if (
113
+ prompts === undefined ||
114
+ promptBlocks.length > 1 ||
115
+ promptBlocks.some(([id, content]) => {
116
+ const c = obj(content);
117
+ return (
118
+ id === '' ||
119
+ c === undefined ||
120
+ typeof c.template !== 'string' ||
121
+ Object.keys(c).length !== 1
122
+ );
123
+ })
124
+ ) {
125
+ return '`overrides.prompts` must be { blockId: { template } } for the prompt block (one)';
126
+ }
127
+ if (settingsBlocks.length === 0 && promptBlocks.length === 0) return undefined;
128
+ return {
129
+ ...(settingsBlocks.length > 0 && {
130
+ settings: settings as Readonly<Record<string, Readonly<Record<string, unknown>>>>,
131
+ }),
132
+ ...(promptBlocks.length > 0 && {
133
+ prompts: prompts as Readonly<Record<string, { readonly template: string }>>,
134
+ }),
135
+ };
136
+ }
137
+
138
+ /** `sample: { part, seed, holdOutShare }`, or an error message. */
139
+ function parseSample(raw: unknown): EvalSample | string {
140
+ const o = obj(raw);
141
+ const share = o?.holdOutShare;
142
+ if (
143
+ o === undefined ||
144
+ (o.part !== 'search' && o.part !== 'hold-out') ||
145
+ typeof o.seed !== 'string' ||
146
+ o.seed === '' ||
147
+ o.seed.length > 200 ||
148
+ typeof share !== 'number' ||
149
+ share < 0.1 ||
150
+ share > 0.9 ||
151
+ Object.keys(o).some((key) => !['part', 'seed', 'holdOutShare'].includes(key))
152
+ ) {
153
+ return "`sample` must be { part: 'search' | 'hold-out', seed, holdOutShare } with holdOutShare from 0.1 to 0.9";
154
+ }
155
+ return { part: o.part, seed: o.seed, holdOutShare: share };
156
+ }
157
+
87
158
  /**
88
159
  * A comparison eval run's settings from the start body: `baseline`,
89
160
  * `reads`, `repetitions`, `k`, `classWeights` and a flow candidate's
@@ -99,13 +170,19 @@ export function parseComparison(
99
170
  const { baseline, reads, repetitions, k, classWeights } = b;
100
171
  const versions = b.versions === undefined ? undefined : parseVersions(b.versions);
101
172
  if (typeof versions === 'string') return { kind: 'err', message: versions };
173
+ const overrides = b.overrides === undefined ? undefined : parseOverrides(b.overrides);
174
+ if (typeof overrides === 'string') return { kind: 'err', message: overrides };
175
+ const sample = b.sample === undefined ? undefined : parseSample(b.sample);
176
+ if (typeof sample === 'string') return { kind: 'err', message: sample };
102
177
  if (
103
178
  baseline === undefined &&
104
179
  reads === undefined &&
105
180
  repetitions === undefined &&
106
181
  k === undefined &&
107
182
  versions === undefined &&
108
- classWeights === undefined
183
+ classWeights === undefined &&
184
+ overrides === undefined &&
185
+ sample === undefined
109
186
  ) {
110
187
  return { kind: 'ok' };
111
188
  }
@@ -144,6 +221,8 @@ export function parseComparison(
144
221
  k: topK,
145
222
  ...(versions !== undefined && { versions }),
146
223
  ...(classWeights !== undefined && { classWeights }),
224
+ ...(overrides !== undefined && { overrides }),
225
+ ...(sample !== undefined && { sample }),
147
226
  },
148
227
  };
149
228
  }
@@ -0,0 +1,108 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ /**
5
+ * An agent candidate's `overrides`, checked when the comparison starts:
6
+ * each settings block must be one the version pins, its values satisfying
7
+ * the schema of the version it pins (model settings, for the
8
+ * model-settings block); a prompt template must be for the prompt block
9
+ * the version pins, and pass `checkDraftedTemplate` (it reads and names
10
+ * only what the agent has). Checked once, here, before any run exists:
11
+ * the replays use them as given, on resume too.
12
+ */
13
+
14
+ import {
15
+ type AgentId,
16
+ MODEL_SETTINGS_SCHEMA,
17
+ checkDraftedTemplate,
18
+ settingsSchemaIssues,
19
+ } from '@kindgi/agents';
20
+ import type { Semver, TenantId } from '@kindgi/types';
21
+
22
+ import type { AgentRegistryBinding } from '../agent-binding.js';
23
+ import type { BlockRegistryBinding } from '../block-binding.js';
24
+ import type { EvalOverrides } from '../eval-run-binding.js';
25
+
26
+ /** Where the check reads the agent version and its blocks. */
27
+ export interface SettingsOverridesCheck {
28
+ readonly agents: AgentRegistryBinding;
29
+ readonly blocks: BlockRegistryBinding;
30
+ }
31
+
32
+ export interface OverridesIssue {
33
+ readonly path: string;
34
+ readonly message: string;
35
+ }
36
+
37
+ /** A JSON Pointer token: `~` and `/` escaped. */
38
+ const token = (id: string): string => id.replaceAll('~', '~0').replaceAll('/', '~1');
39
+
40
+ export async function checkSettingsOverrides(
41
+ check: SettingsOverridesCheck,
42
+ tenantId: TenantId,
43
+ candidate: { readonly agentId: string; readonly version: string },
44
+ overrides: EvalOverrides,
45
+ ): Promise<OverridesIssue[]> {
46
+ const settings = overrides.settings ?? {};
47
+ const label = `${candidate.agentId} ${candidate.version}`;
48
+ const found = await check.agents.getVersion({
49
+ tenantId,
50
+ agentId: candidate.agentId as AgentId,
51
+ version: candidate.version as Semver,
52
+ });
53
+ if (found === null) {
54
+ return [{ path: '/agentRef/version', message: `agent ${label} isn't registered` }];
55
+ }
56
+ if (found.pins === undefined) {
57
+ return [
58
+ {
59
+ path: '/overrides/settings',
60
+ message: `${label} was published before pins: it has no pinned settings to replace`,
61
+ },
62
+ ];
63
+ }
64
+ const issues: OverridesIssue[] = [];
65
+ for (const [id, values] of Object.entries(settings)) {
66
+ const path = `/overrides/settings/${token(id)}`;
67
+ const version = found.pins.settings[id];
68
+ if (version === undefined) {
69
+ issues.push({ path, message: `${label} doesn't pin settings block "${id}"` });
70
+ continue;
71
+ }
72
+ const block = await check.blocks.getVersion({ tenantId, blockId: id, version });
73
+ if (block === null || block.kind !== 'settings') {
74
+ issues.push({ path, message: `settings block "${id}" version ${version} isn't published` });
75
+ continue;
76
+ }
77
+ const schema = found.modelSettings?.id === id ? MODEL_SETTINGS_SCHEMA : block.content.schema;
78
+ if (schema === undefined) continue;
79
+ for (const issue of settingsSchemaIssues(values, schema)) {
80
+ issues.push({ path: `${path}${issue.path}`, message: issue.message });
81
+ }
82
+ }
83
+ for (const [id, { template }] of Object.entries(overrides.prompts ?? {})) {
84
+ const path = `/overrides/prompts/${token(id)}`;
85
+ const version = found.pins.prompts[id];
86
+ if (version === undefined) {
87
+ issues.push({ path, message: `${label} doesn't pin prompt block "${id}"` });
88
+ continue;
89
+ }
90
+ const block = await check.blocks.getVersion({ tenantId, blockId: id, version });
91
+ if (block === null || block.kind !== 'prompt') {
92
+ issues.push({ path, message: `prompt block "${id}" version ${version} isn't published` });
93
+ continue;
94
+ }
95
+ const drafted = checkDraftedTemplate(template, {
96
+ current: block.content,
97
+ settingsBlocks: Object.keys(found.pins.settings),
98
+ knownIds: [
99
+ candidate.agentId,
100
+ ...Object.keys(found.pins.tools),
101
+ ...Object.keys(found.pins.prompts),
102
+ ...Object.keys(found.pins.settings),
103
+ ],
104
+ });
105
+ for (const issue of drafted) issues.push({ path, message: issue.message });
106
+ }
107
+ return issues;
108
+ }
@@ -2,8 +2,10 @@
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
 
4
4
  import { Hono } from 'hono';
5
+ import type { Context } from 'hono';
5
6
 
6
7
  import type { AgentId } from '@kindgi/agents';
8
+ import { type Action, ref } from '@kindgi/authz';
7
9
  import type { Cursor, FlowId, ProjectId, RunId, Semver, TenantId, Timestamp } from '@kindgi/types';
8
10
 
9
11
  import { statusFor, toWireError } from '../errors.js';
@@ -18,8 +20,11 @@ import {
18
20
  type FlowRef,
19
21
  } from '../eval-run-binding.js';
20
22
  import { VERSIONS_NEED_A_FLOW } from '../judged-dispatcher.js';
23
+ import type { Authorizer } from '../middleware/authorize.js';
21
24
  import type { AppEnv } from '../types.js';
25
+ import { deniedBy } from './denied.js';
22
26
  import { parseComparison } from './eval-comparison.js';
27
+ import { type SettingsOverridesCheck, checkSettingsOverrides } from './eval-overrides.js';
23
28
  import { type FlowVersionsCheck, checkFlowVersions } from './eval-versions.js';
24
29
  import { clampLimit } from './pagination.js';
25
30
  import { parseScopeParams } from './scope-params.js';
@@ -43,6 +48,13 @@ import { formatSseFrame } from './sse.js';
43
48
  * The binding chooses its underlying substrate (the in-process
44
49
  * reference keeps runs in memory; a durable binding can back them with
45
50
  * runs and their journal); this route only sees the surface.
51
+ *
52
+ * With an authorizer (T243 A): starting a run needs `write` on the
53
+ * project it lands in and `execute` on what it evaluates (the agent or
54
+ * flow), on top of the eval-suites router's own check on the suite. An
55
+ * eval run is read through its suite: `read` on the suite to list, get or
56
+ * follow it, `write` to cancel it. A run that isn't there is still the
57
+ * handler's 404.
46
58
  */
47
59
  export interface EvalRunsRouters {
48
60
  readonly start: Hono<AppEnv>;
@@ -57,10 +69,12 @@ export interface EvalRunsRouters {
57
69
  export function evalRunsRouters(
58
70
  binding: EvalRunBinding,
59
71
  versionsCheck?: FlowVersionsCheck,
72
+ overridesCheck?: SettingsOverridesCheck,
73
+ authorizer?: Authorizer,
60
74
  ): EvalRunsRouters {
61
75
  return {
62
- start: startRouter(binding, versionsCheck),
63
- readback: readbackRouter(binding),
76
+ start: startRouter(binding, versionsCheck, overridesCheck, authorizer),
77
+ readback: readbackRouter(binding, authorizer),
64
78
  };
65
79
  }
66
80
 
@@ -91,7 +105,42 @@ async function versionsRefusal(
91
105
  };
92
106
  }
93
107
 
94
- function startRouter(binding: EvalRunBinding, versionsCheck?: FlowVersionsCheck): Hono<AppEnv> {
108
+ /** The `validation-failed` error for an agent candidate's settings `overrides` that don't fit it; `undefined` when they do. */
109
+ async function overridesRefusal(
110
+ check: SettingsOverridesCheck | undefined,
111
+ tenantId: TenantId,
112
+ start: ParsedStartBody,
113
+ ) {
114
+ const overrides = start.comparison?.overrides;
115
+ const agentRef = start.agentRef;
116
+ if (overrides === undefined || agentRef?.version === undefined) return undefined;
117
+ if (check === undefined) {
118
+ return {
119
+ code: 'validation-failed' as const,
120
+ message: "This runtime can't check overrides (it serves no agent or block registry).",
121
+ issues: [],
122
+ };
123
+ }
124
+ const issues = await checkSettingsOverrides(
125
+ check,
126
+ tenantId,
127
+ { agentId: agentRef.agentId as unknown as string, version: agentRef.version },
128
+ overrides,
129
+ );
130
+ if (issues.length === 0) return undefined;
131
+ return {
132
+ code: 'validation-failed' as const,
133
+ message: `The overrides don't fit ${agentRef.agentId as unknown as string} ${agentRef.version} (${issues.length} issue${issues.length === 1 ? '' : 's'})`,
134
+ issues: issues as unknown as Record<string, unknown>[],
135
+ };
136
+ }
137
+
138
+ function startRouter(
139
+ binding: EvalRunBinding,
140
+ versionsCheck?: FlowVersionsCheck,
141
+ overridesCheck?: SettingsOverridesCheck,
142
+ authorizer?: Authorizer,
143
+ ): Hono<AppEnv> {
95
144
  const r = new Hono<AppEnv>();
96
145
 
97
146
  r.post('/:suiteId/runs', async (c) => {
@@ -119,7 +168,18 @@ function startRouter(binding: EvalRunBinding, versionsCheck?: FlowVersionsCheck)
119
168
  c.status(statusFor(parsed.error.code) as never);
120
169
  return c.json(toWireError(parsed.error, requestId));
121
170
  }
122
- const refusal = await versionsRefusal(versionsCheck, tenantId, parsed.value);
171
+ const { projectId, agentRef, flowRef } = parsed.value;
172
+ const target =
173
+ agentRef !== undefined
174
+ ? ref('agent', agentRef.agentId as unknown as string)
175
+ : ref('flow', flowRef?.flowId as unknown as string);
176
+ const refused =
177
+ (await deniedBy(authorizer, c, 'write', ref('project', projectId as unknown as string))) ??
178
+ (await deniedBy(authorizer, c, 'execute', target));
179
+ if (refused !== undefined) return refused;
180
+ const refusal =
181
+ (await versionsRefusal(versionsCheck, tenantId, parsed.value)) ??
182
+ (await overridesRefusal(overridesCheck, tenantId, parsed.value));
123
183
  if (refusal !== undefined) {
124
184
  c.status(statusFor(refusal.code) as never);
125
185
  return c.json(toWireError(refusal, requestId));
@@ -206,8 +266,16 @@ function startRouter(binding: EvalRunBinding, versionsCheck?: FlowVersionsCheck)
206
266
 
207
267
  // ---------- /v1/eval-runs/* (readback + cancel + SSE) ----------
208
268
 
209
- function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
269
+ function readbackRouter(binding: EvalRunBinding, authorizer?: Authorizer): Hono<AppEnv> {
210
270
  const r = new Hono<AppEnv>();
271
+ /** The refusal, if any, of `action` on the suite of the run named in the path. */
272
+ const onRunSuite = async (c: Context<AppEnv>, action: Action): Promise<Response | undefined> => {
273
+ if (authorizer === undefined) return undefined;
274
+ const tenantId = c.get('tenantId') as TenantId;
275
+ const run = await binding.get({ tenantId, runId: c.req.param('runId') as RunId });
276
+ if (run === null) return undefined;
277
+ return deniedBy(authorizer, c, action, ref('eval_suite', run.suiteId));
278
+ };
211
279
 
212
280
  // ---------- GET / (list) ----------
213
281
  r.get('/', async (c) => {
@@ -270,8 +338,14 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
270
338
  ...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
271
339
  ...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
272
340
  });
341
+ const visible =
342
+ authorizer === undefined
343
+ ? page.data
344
+ : await authorizer.filterByCan(c, 'read', page.data, (run) =>
345
+ ref('eval_suite', run.suiteId),
346
+ );
273
347
  return c.json({
274
- data: page.data.map(serializeEvalRun),
348
+ data: visible.map(serializeEvalRun),
275
349
  hasMore: page.nextCursor !== undefined,
276
350
  ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
277
351
  });
@@ -279,6 +353,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
279
353
 
280
354
  // ---------- GET /:runId ----------
281
355
  r.get('/:runId', async (c) => {
356
+ const refused = await onRunSuite(c, 'read');
357
+ if (refused !== undefined) return refused;
282
358
  const requestId = c.get('requestId');
283
359
  const tenantId = c.get('tenantId') as TenantId;
284
360
  const runId = c.req.param('runId') as RunId;
@@ -298,6 +374,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
298
374
 
299
375
  // ---------- POST /:runId/cancel ----------
300
376
  r.post('/:runId/cancel', async (c) => {
377
+ const refused = await onRunSuite(c, 'write');
378
+ if (refused !== undefined) return refused;
301
379
  const requestId = c.get('requestId');
302
380
  const tenantId = c.get('tenantId') as TenantId;
303
381
  const runId = c.req.param('runId') as RunId;
@@ -340,6 +418,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
340
418
 
341
419
  // ---------- GET /:runId/events (SSE) ----------
342
420
  r.get('/:runId/events', async (c) => {
421
+ const refused = await onRunSuite(c, 'read');
422
+ if (refused !== undefined) return refused;
343
423
  const requestId = c.get('requestId');
344
424
  const tenantId = c.get('tenantId') as TenantId;
345
425
  const runId = c.req.param('runId') as RunId;
@@ -16,6 +16,7 @@ import {
16
16
  import type { Authorizer } from '../middleware/authorize.js';
17
17
  import type { AppEnv } from '../types.js';
18
18
  import { clampLimit } from './pagination.js';
19
+ import { projectMismatch } from './project-mismatch.js';
19
20
  import { parseScopeParams } from './scope-params.js';
20
21
 
21
22
  /**
@@ -77,6 +78,19 @@ export function evalSuitesRouter(
77
78
  r.use('/:suiteId/*', async (c, next) => {
78
79
  const action = c.req.method === 'GET' ? 'read' : 'admin';
79
80
  const suiteId = c.req.param('suiteId') ?? '';
81
+ // A test set built from judgments under a suite id never registered
82
+ // (no head row) has no suite to check yet: the build checks `admin`
83
+ // on the project it names, the project the new suite belongs to. A
84
+ // tombstoned suite keeps its head row, so it's checked as an existing
85
+ // one. Anything else under a suite id, and a build under an existing
86
+ // suite, checks the suite.
87
+ if (
88
+ c.req.method === 'POST' &&
89
+ c.req.path.endsWith('/versions/from-judgments') &&
90
+ !(await binding.headExists({ tenantId: c.get('tenantId') as TenantId, suiteId }))
91
+ ) {
92
+ return next();
93
+ }
80
94
  const mw = authorizer.authorize(action, () => ref('eval_suite', suiteId));
81
95
  return mw(c, next);
82
96
  });
@@ -128,8 +142,15 @@ export function evalSuitesRouter(
128
142
  ...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
129
143
  ...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
130
144
  });
145
+ // Only what the caller may read (T243 A), as `GET …/:id` asks.
146
+ const visible =
147
+ authorizer === undefined
148
+ ? page.data
149
+ : await authorizer.filterByCan(c, 'read', page.data, (a) =>
150
+ ref('eval_suite', a.id as unknown as string),
151
+ );
131
152
  return c.json({
132
- data: page.data.map(serializeEvalSuite),
153
+ data: visible.map(serializeEvalSuite),
133
154
  hasMore: page.nextCursor !== undefined,
134
155
  ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
135
156
  });
@@ -318,6 +339,9 @@ export function evalSuitesRouter(
318
339
  ),
319
340
  );
320
341
  }
342
+ if (outcome.kind === 'project-mismatch') {
343
+ return projectMismatch(c, 'eval-suite', outcome.suiteId, outcome.projectId);
344
+ }
321
345
  if (outcome.kind === 'project-not-found') {
322
346
  // Caller supplied a `projectId` that does not resolve within
323
347
  // this tenant. Distinct signal from `already-registered` so the