@kindgi/api 0.1.4 → 0.1.5

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 (516) 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/cost-binding.d.ts +19 -0
  21. package/dist/cost-binding.d.ts.map +1 -1
  22. package/dist/cost-binding.js.map +1 -1
  23. package/dist/derive-agent-version.d.ts +7 -0
  24. package/dist/derive-agent-version.d.ts.map +1 -1
  25. package/dist/derive-agent-version.js +4 -0
  26. package/dist/derive-agent-version.js.map +1 -1
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/errors.js +75 -7
  29. package/dist/errors.js.map +1 -1
  30. package/dist/eval-case-binding.d.ts +16 -4
  31. package/dist/eval-case-binding.d.ts.map +1 -1
  32. package/dist/eval-run-binding.d.ts +31 -0
  33. package/dist/eval-run-binding.d.ts.map +1 -1
  34. package/dist/eval-run-dispatcher.d.ts +7 -0
  35. package/dist/eval-run-dispatcher.d.ts.map +1 -1
  36. package/dist/eval-run-dispatcher.js.map +1 -1
  37. package/dist/eval-sample.d.ts +11 -0
  38. package/dist/eval-sample.d.ts.map +1 -0
  39. package/dist/eval-sample.js +34 -0
  40. package/dist/eval-sample.js.map +1 -0
  41. package/dist/eval-suite-binding.d.ts +13 -0
  42. package/dist/eval-suite-binding.d.ts.map +1 -1
  43. package/dist/eval-suite-binding.js.map +1 -1
  44. package/dist/flow-binding.d.ts +18 -0
  45. package/dist/flow-binding.d.ts.map +1 -1
  46. package/dist/flow-pins.d.ts.map +1 -1
  47. package/dist/flow-pins.js +18 -2
  48. package/dist/flow-pins.js.map +1 -1
  49. package/dist/gate.d.ts.map +1 -1
  50. package/dist/gate.js +25 -0
  51. package/dist/gate.js.map +1 -1
  52. package/dist/handler-binding.d.ts +32 -0
  53. package/dist/handler-binding.d.ts.map +1 -1
  54. package/dist/hitl-binding.d.ts +23 -0
  55. package/dist/hitl-binding.d.ts.map +1 -1
  56. package/dist/identity-directory-binding.d.ts +82 -4
  57. package/dist/identity-directory-binding.d.ts.map +1 -1
  58. package/dist/identity-provider-binding.d.ts +197 -17
  59. package/dist/identity-provider-binding.d.ts.map +1 -1
  60. package/dist/improvement-pass-binding.d.ts +196 -0
  61. package/dist/improvement-pass-binding.d.ts.map +1 -0
  62. package/dist/improvement-pass-binding.js +9 -0
  63. package/dist/improvement-pass-binding.js.map +1 -0
  64. package/dist/index.d.ts +35 -17
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +11 -3
  67. package/dist/index.js.map +1 -1
  68. package/dist/judged-dispatcher.d.ts +25 -4
  69. package/dist/judged-dispatcher.d.ts.map +1 -1
  70. package/dist/judged-dispatcher.js +43 -6
  71. package/dist/judged-dispatcher.js.map +1 -1
  72. package/dist/judgment-binding.d.ts +25 -1
  73. package/dist/judgment-binding.d.ts.map +1 -1
  74. package/dist/mcp-endpoint-binding.d.ts +7 -0
  75. package/dist/mcp-endpoint-binding.d.ts.map +1 -1
  76. package/dist/memory-binding.d.ts +124 -17
  77. package/dist/memory-binding.d.ts.map +1 -1
  78. package/dist/memory-erasure-binding.d.ts +145 -0
  79. package/dist/memory-erasure-binding.d.ts.map +1 -0
  80. package/dist/memory-erasure-binding.js +4 -0
  81. package/dist/memory-erasure-binding.js.map +1 -0
  82. package/dist/middleware/auth.d.ts +66 -13
  83. package/dist/middleware/auth.d.ts.map +1 -1
  84. package/dist/middleware/auth.js +150 -50
  85. package/dist/middleware/auth.js.map +1 -1
  86. package/dist/middleware/authorize.d.ts +9 -0
  87. package/dist/middleware/authorize.d.ts.map +1 -1
  88. package/dist/middleware/authorize.js +122 -4
  89. package/dist/middleware/authorize.js.map +1 -1
  90. package/dist/middleware/error-mapper.d.ts +5 -0
  91. package/dist/middleware/error-mapper.d.ts.map +1 -1
  92. package/dist/middleware/error-mapper.js +14 -1
  93. package/dist/middleware/error-mapper.js.map +1 -1
  94. package/dist/middleware/idempotency.d.ts +70 -5
  95. package/dist/middleware/idempotency.d.ts.map +1 -1
  96. package/dist/middleware/idempotency.js +174 -41
  97. package/dist/middleware/idempotency.js.map +1 -1
  98. package/dist/middleware/key-project.d.ts +17 -0
  99. package/dist/middleware/key-project.d.ts.map +1 -0
  100. package/dist/middleware/key-project.js +75 -0
  101. package/dist/middleware/key-project.js.map +1 -0
  102. package/dist/middleware/principal.d.ts.map +1 -1
  103. package/dist/middleware/principal.js +9 -5
  104. package/dist/middleware/principal.js.map +1 -1
  105. package/dist/middleware/project-ref.d.ts.map +1 -1
  106. package/dist/middleware/project-ref.js +3 -0
  107. package/dist/middleware/project-ref.js.map +1 -1
  108. package/dist/openapi/generate.d.ts.map +1 -1
  109. package/dist/openapi/generate.js +5 -2
  110. package/dist/openapi/generate.js.map +1 -1
  111. package/dist/openapi/operations.d.ts.map +1 -1
  112. package/dist/openapi/operations.js +919 -140
  113. package/dist/openapi/operations.js.map +1 -1
  114. package/dist/openapi/schemas.d.ts +90 -13
  115. package/dist/openapi/schemas.d.ts.map +1 -1
  116. package/dist/openapi/schemas.js +2081 -359
  117. package/dist/openapi/schemas.js.map +1 -1
  118. package/dist/person-grants-binding.d.ts +77 -0
  119. package/dist/person-grants-binding.d.ts.map +1 -0
  120. package/dist/person-grants-binding.js +4 -0
  121. package/dist/person-grants-binding.js.map +1 -0
  122. package/dist/proposal-service.d.ts +121 -0
  123. package/dist/proposal-service.d.ts.map +1 -0
  124. package/dist/proposal-service.js +447 -0
  125. package/dist/proposal-service.js.map +1 -0
  126. package/dist/proposal-status.d.ts +60 -0
  127. package/dist/proposal-status.d.ts.map +1 -0
  128. package/dist/proposal-status.js +109 -0
  129. package/dist/proposal-status.js.map +1 -0
  130. package/dist/provider-binding.d.ts +10 -0
  131. package/dist/provider-binding.d.ts.map +1 -1
  132. package/dist/publish-refused.d.ts +28 -3
  133. package/dist/publish-refused.d.ts.map +1 -1
  134. package/dist/publish-refused.js +24 -3
  135. package/dist/publish-refused.js.map +1 -1
  136. package/dist/routes/adapters.d.ts +2 -1
  137. package/dist/routes/adapters.d.ts.map +1 -1
  138. package/dist/routes/adapters.js +3 -1
  139. package/dist/routes/adapters.js.map +1 -1
  140. package/dist/routes/agent-releases.d.ts +55 -3
  141. package/dist/routes/agent-releases.d.ts.map +1 -1
  142. package/dist/routes/agent-releases.js +85 -55
  143. package/dist/routes/agent-releases.js.map +1 -1
  144. package/dist/routes/agents.d.ts +12 -1
  145. package/dist/routes/agents.d.ts.map +1 -1
  146. package/dist/routes/agents.js +100 -2
  147. package/dist/routes/agents.js.map +1 -1
  148. package/dist/routes/approvals.d.ts +15 -3
  149. package/dist/routes/approvals.d.ts.map +1 -1
  150. package/dist/routes/approvals.js +133 -122
  151. package/dist/routes/approvals.js.map +1 -1
  152. package/dist/routes/artifacts.d.ts +25 -3
  153. package/dist/routes/artifacts.d.ts.map +1 -1
  154. package/dist/routes/artifacts.js +116 -7
  155. package/dist/routes/artifacts.js.map +1 -1
  156. package/dist/routes/auth.d.ts +25 -1
  157. package/dist/routes/auth.d.ts.map +1 -1
  158. package/dist/routes/auth.js +655 -281
  159. package/dist/routes/auth.js.map +1 -1
  160. package/dist/routes/blocks.d.ts.map +1 -1
  161. package/dist/routes/blocks.js +2 -42
  162. package/dist/routes/blocks.js.map +1 -1
  163. package/dist/routes/capabilities.d.ts +2 -1
  164. package/dist/routes/capabilities.d.ts.map +1 -1
  165. package/dist/routes/capabilities.js +6 -1
  166. package/dist/routes/capabilities.js.map +1 -1
  167. package/dist/routes/compliance.d.ts +9 -10
  168. package/dist/routes/compliance.d.ts.map +1 -1
  169. package/dist/routes/compliance.js +42 -61
  170. package/dist/routes/compliance.js.map +1 -1
  171. package/dist/routes/conversations.d.ts +8 -1
  172. package/dist/routes/conversations.d.ts.map +1 -1
  173. package/dist/routes/conversations.js +87 -8
  174. package/dist/routes/conversations.js.map +1 -1
  175. package/dist/routes/cost.d.ts +12 -1
  176. package/dist/routes/cost.d.ts.map +1 -1
  177. package/dist/routes/cost.js +74 -3
  178. package/dist/routes/cost.js.map +1 -1
  179. package/dist/routes/denied.d.ts +11 -0
  180. package/dist/routes/denied.d.ts.map +1 -0
  181. package/dist/routes/denied.js +17 -0
  182. package/dist/routes/denied.js.map +1 -0
  183. package/dist/routes/deployments.d.ts +10 -1
  184. package/dist/routes/deployments.d.ts.map +1 -1
  185. package/dist/routes/deployments.js +171 -13
  186. package/dist/routes/deployments.js.map +1 -1
  187. package/dist/routes/eval-comparison.d.ts.map +1 -1
  188. package/dist/routes/eval-comparison.js +69 -1
  189. package/dist/routes/eval-comparison.js.map +1 -1
  190. package/dist/routes/eval-overrides.d.ts +18 -0
  191. package/dist/routes/eval-overrides.d.ts.map +1 -0
  192. package/dist/routes/eval-overrides.js +81 -0
  193. package/dist/routes/eval-overrides.js.map +1 -0
  194. package/dist/routes/eval-runs.d.ts +10 -1
  195. package/dist/routes/eval-runs.d.ts.map +1 -1
  196. package/dist/routes/eval-runs.js +66 -7
  197. package/dist/routes/eval-runs.js.map +1 -1
  198. package/dist/routes/eval-suites.d.ts.map +1 -1
  199. package/dist/routes/eval-suites.js +28 -2
  200. package/dist/routes/eval-suites.js.map +1 -1
  201. package/dist/routes/event-triggers.d.ts +5 -1
  202. package/dist/routes/event-triggers.d.ts.map +1 -1
  203. package/dist/routes/event-triggers.js +26 -3
  204. package/dist/routes/event-triggers.js.map +1 -1
  205. package/dist/routes/export-signing-keys.d.ts +12 -0
  206. package/dist/routes/export-signing-keys.d.ts.map +1 -0
  207. package/dist/routes/export-signing-keys.js +24 -0
  208. package/dist/routes/export-signing-keys.js.map +1 -0
  209. package/dist/routes/flows.d.ts.map +1 -1
  210. package/dist/routes/flows.js +9 -1
  211. package/dist/routes/flows.js.map +1 -1
  212. package/dist/routes/gate-policies.d.ts +4 -1
  213. package/dist/routes/gate-policies.d.ts.map +1 -1
  214. package/dist/routes/gate-policies.js +29 -5
  215. package/dist/routes/gate-policies.js.map +1 -1
  216. package/dist/routes/guardrails.d.ts +16 -14
  217. package/dist/routes/guardrails.d.ts.map +1 -1
  218. package/dist/routes/guardrails.js +39 -3
  219. package/dist/routes/guardrails.js.map +1 -1
  220. package/dist/routes/identity.d.ts +20 -4
  221. package/dist/routes/identity.d.ts.map +1 -1
  222. package/dist/routes/identity.js +246 -6
  223. package/dist/routes/identity.js.map +1 -1
  224. package/dist/routes/improvement-passes.d.ts +52 -0
  225. package/dist/routes/improvement-passes.d.ts.map +1 -0
  226. package/dist/routes/improvement-passes.js +449 -0
  227. package/dist/routes/improvement-passes.js.map +1 -0
  228. package/dist/routes/judged-suites.d.ts +50 -0
  229. package/dist/routes/judged-suites.d.ts.map +1 -1
  230. package/dist/routes/judged-suites.js +66 -27
  231. package/dist/routes/judged-suites.js.map +1 -1
  232. package/dist/routes/judgment-context.d.ts +18 -2
  233. package/dist/routes/judgment-context.d.ts.map +1 -1
  234. package/dist/routes/judgment-context.js +63 -5
  235. package/dist/routes/judgment-context.js.map +1 -1
  236. package/dist/routes/judgment-flow-context.d.ts.map +1 -1
  237. package/dist/routes/judgment-flow-context.js +14 -2
  238. package/dist/routes/judgment-flow-context.js.map +1 -1
  239. package/dist/routes/judgments.d.ts.map +1 -1
  240. package/dist/routes/judgments.js +8 -1
  241. package/dist/routes/judgments.js.map +1 -1
  242. package/dist/routes/mcp.d.ts.map +1 -1
  243. package/dist/routes/mcp.js +26 -1
  244. package/dist/routes/mcp.js.map +1 -1
  245. package/dist/routes/memory-access.d.ts +43 -0
  246. package/dist/routes/memory-access.d.ts.map +1 -0
  247. package/dist/routes/memory-access.js +114 -0
  248. package/dist/routes/memory-access.js.map +1 -0
  249. package/dist/routes/memory-erasures.d.ts +25 -0
  250. package/dist/routes/memory-erasures.d.ts.map +1 -0
  251. package/dist/routes/memory-erasures.js +214 -0
  252. package/dist/routes/memory-erasures.js.map +1 -0
  253. package/dist/routes/memory-parse.d.ts +38 -0
  254. package/dist/routes/memory-parse.d.ts.map +1 -0
  255. package/dist/routes/memory-parse.js +199 -0
  256. package/dist/routes/memory-parse.js.map +1 -0
  257. package/dist/routes/memory.d.ts +9 -4
  258. package/dist/routes/memory.d.ts.map +1 -1
  259. package/dist/routes/memory.js +226 -234
  260. package/dist/routes/memory.js.map +1 -1
  261. package/dist/routes/observations.d.ts +4 -1
  262. package/dist/routes/observations.d.ts.map +1 -1
  263. package/dist/routes/observations.js +8 -2
  264. package/dist/routes/observations.js.map +1 -1
  265. package/dist/routes/pagination.d.ts +7 -0
  266. package/dist/routes/pagination.d.ts.map +1 -1
  267. package/dist/routes/pagination.js +10 -0
  268. package/dist/routes/pagination.js.map +1 -1
  269. package/dist/routes/policies.d.ts +2 -1
  270. package/dist/routes/policies.d.ts.map +1 -1
  271. package/dist/routes/policies.js +3 -1
  272. package/dist/routes/policies.js.map +1 -1
  273. package/dist/routes/project-mismatch.d.ts +22 -0
  274. package/dist/routes/project-mismatch.d.ts.map +1 -0
  275. package/dist/routes/project-mismatch.js +34 -0
  276. package/dist/routes/project-mismatch.js.map +1 -0
  277. package/dist/routes/projects.d.ts +15 -4
  278. package/dist/routes/projects.d.ts.map +1 -1
  279. package/dist/routes/projects.js +100 -9
  280. package/dist/routes/projects.js.map +1 -1
  281. package/dist/routes/proposals.d.ts +25 -17
  282. package/dist/routes/proposals.d.ts.map +1 -1
  283. package/dist/routes/proposals.js +340 -507
  284. package/dist/routes/proposals.js.map +1 -1
  285. package/dist/routes/provenance.d.ts +17 -3
  286. package/dist/routes/provenance.d.ts.map +1 -1
  287. package/dist/routes/provenance.js +79 -103
  288. package/dist/routes/provenance.js.map +1 -1
  289. package/dist/routes/providers.d.ts +17 -1
  290. package/dist/routes/providers.d.ts.map +1 -1
  291. package/dist/routes/providers.js +110 -3
  292. package/dist/routes/providers.js.map +1 -1
  293. package/dist/routes/public-run-tokens.d.ts.map +1 -1
  294. package/dist/routes/public-run-tokens.js +3 -0
  295. package/dist/routes/public-run-tokens.js.map +1 -1
  296. package/dist/routes/readable-projects.d.ts +26 -0
  297. package/dist/routes/readable-projects.d.ts.map +1 -0
  298. package/dist/routes/readable-projects.js +39 -0
  299. package/dist/routes/readable-projects.js.map +1 -0
  300. package/dist/routes/runs.d.ts +10 -0
  301. package/dist/routes/runs.d.ts.map +1 -1
  302. package/dist/routes/runs.js +92 -42
  303. package/dist/routes/runs.js.map +1 -1
  304. package/dist/routes/schedules.d.ts +21 -13
  305. package/dist/routes/schedules.d.ts.map +1 -1
  306. package/dist/routes/schedules.js +416 -55
  307. package/dist/routes/schedules.js.map +1 -1
  308. package/dist/routes/segments.d.ts +2 -0
  309. package/dist/routes/segments.d.ts.map +1 -1
  310. package/dist/routes/segments.js +5 -0
  311. package/dist/routes/segments.js.map +1 -1
  312. package/dist/routes/service-accounts.d.ts +17 -0
  313. package/dist/routes/service-accounts.d.ts.map +1 -0
  314. package/dist/routes/service-accounts.js +212 -0
  315. package/dist/routes/service-accounts.js.map +1 -0
  316. package/dist/routes/sign-in-options.d.ts +50 -0
  317. package/dist/routes/sign-in-options.d.ts.map +1 -0
  318. package/dist/routes/sign-in-options.js +98 -0
  319. package/dist/routes/sign-in-options.js.map +1 -0
  320. package/dist/routes/signing-keys.d.ts +2 -1
  321. package/dist/routes/signing-keys.d.ts.map +1 -1
  322. package/dist/routes/signing-keys.js +3 -1
  323. package/dist/routes/signing-keys.js.map +1 -1
  324. package/dist/routes/tenant-access.d.ts +13 -0
  325. package/dist/routes/tenant-access.d.ts.map +1 -0
  326. package/dist/routes/tenant-access.js +26 -0
  327. package/dist/routes/tenant-access.js.map +1 -0
  328. package/dist/routes/tenant.d.ts.map +1 -1
  329. package/dist/routes/tenant.js +4 -0
  330. package/dist/routes/tenant.js.map +1 -1
  331. package/dist/routes/token-sign-in.d.ts +36 -0
  332. package/dist/routes/token-sign-in.d.ts.map +1 -0
  333. package/dist/routes/token-sign-in.js +101 -0
  334. package/dist/routes/token-sign-in.js.map +1 -0
  335. package/dist/routes/tokens.d.ts +15 -5
  336. package/dist/routes/tokens.d.ts.map +1 -1
  337. package/dist/routes/tokens.js +162 -43
  338. package/dist/routes/tokens.js.map +1 -1
  339. package/dist/routes/tools.d.ts.map +1 -1
  340. package/dist/routes/tools.js +9 -1
  341. package/dist/routes/tools.js.map +1 -1
  342. package/dist/routes/trigger-access.d.ts +29 -0
  343. package/dist/routes/trigger-access.d.ts.map +1 -0
  344. package/dist/routes/trigger-access.js +33 -0
  345. package/dist/routes/trigger-access.js.map +1 -0
  346. package/dist/routes/webhook-endpoints.d.ts +2 -1
  347. package/dist/routes/webhook-endpoints.d.ts.map +1 -1
  348. package/dist/routes/webhook-endpoints.js +11 -3
  349. package/dist/routes/webhook-endpoints.js.map +1 -1
  350. package/dist/routes/webhooks.d.ts +5 -1
  351. package/dist/routes/webhooks.d.ts.map +1 -1
  352. package/dist/routes/webhooks.js +25 -2
  353. package/dist/routes/webhooks.js.map +1 -1
  354. package/dist/run-failure.d.ts +21 -0
  355. package/dist/run-failure.d.ts.map +1 -0
  356. package/dist/run-failure.js +29 -0
  357. package/dist/run-failure.js.map +1 -0
  358. package/dist/service-account-binding.d.ts +108 -0
  359. package/dist/service-account-binding.d.ts.map +1 -0
  360. package/dist/service-account-binding.js +4 -0
  361. package/dist/service-account-binding.js.map +1 -0
  362. package/dist/session-store-binding.d.ts +61 -13
  363. package/dist/session-store-binding.d.ts.map +1 -1
  364. package/dist/signed-export.d.ts +89 -0
  365. package/dist/signed-export.d.ts.map +1 -0
  366. package/dist/signed-export.js +149 -0
  367. package/dist/signed-export.js.map +1 -0
  368. package/dist/supervisor-binding.d.ts +186 -413
  369. package/dist/supervisor-binding.d.ts.map +1 -1
  370. package/dist/testing/app-bindings.d.ts +33 -0
  371. package/dist/testing/app-bindings.d.ts.map +1 -0
  372. package/dist/testing/app-bindings.js +112 -0
  373. package/dist/testing/app-bindings.js.map +1 -0
  374. package/dist/testing/index.d.ts +11 -0
  375. package/dist/testing/index.d.ts.map +1 -0
  376. package/dist/testing/index.js +13 -0
  377. package/dist/testing/index.js.map +1 -0
  378. package/dist/testing/stub-binding.d.ts +34 -0
  379. package/dist/testing/stub-binding.d.ts.map +1 -0
  380. package/dist/testing/stub-binding.js +42 -0
  381. package/dist/testing/stub-binding.js.map +1 -0
  382. package/dist/testing/trigger-registry.d.ts +21 -0
  383. package/dist/testing/trigger-registry.d.ts.map +1 -0
  384. package/dist/testing/trigger-registry.js +206 -0
  385. package/dist/testing/trigger-registry.js.map +1 -0
  386. package/dist/token-admin.d.ts +46 -8
  387. package/dist/token-admin.d.ts.map +1 -1
  388. package/dist/token-admin.js.map +1 -1
  389. package/dist/tool-binding.d.ts +13 -0
  390. package/dist/tool-binding.d.ts.map +1 -1
  391. package/dist/trigger-binding.d.ts +2 -2
  392. package/dist/trigger-binding.d.ts.map +1 -1
  393. package/dist/trigger-binding.js +1 -1
  394. package/dist/trigger-binding.js.map +1 -1
  395. package/dist/types.d.ts +16 -0
  396. package/dist/types.d.ts.map +1 -1
  397. package/dist/webhook-endpoint-binding.d.ts +19 -3
  398. package/dist/webhook-endpoint-binding.d.ts.map +1 -1
  399. package/dist/webhook-endpoint-binding.js +1 -1
  400. package/dist/webhook-endpoint-binding.js.map +1 -1
  401. package/openapi.json +15387 -8789
  402. package/package.json +26 -22
  403. package/src/agent-binding.ts +14 -0
  404. package/src/agent-pins.ts +18 -2
  405. package/src/app.ts +366 -80
  406. package/src/block-publish.ts +181 -0
  407. package/src/caller.ts +62 -0
  408. package/src/capability-binding.ts +12 -0
  409. package/src/cost-binding.ts +19 -0
  410. package/src/derive-agent-version.ts +9 -1
  411. package/src/errors.ts +75 -7
  412. package/src/eval-case-binding.ts +17 -1
  413. package/src/eval-run-binding.ts +31 -0
  414. package/src/eval-run-dispatcher.ts +7 -0
  415. package/src/eval-sample.ts +42 -0
  416. package/src/eval-suite-binding.ts +14 -0
  417. package/src/flow-binding.ts +19 -0
  418. package/src/flow-pins.ts +18 -2
  419. package/src/gate.ts +26 -0
  420. package/src/handler-binding.ts +36 -1
  421. package/src/hitl-binding.ts +24 -0
  422. package/src/identity-directory-binding.ts +85 -4
  423. package/src/identity-provider-binding.ts +216 -21
  424. package/src/improvement-pass-binding.ts +193 -0
  425. package/src/index.ts +153 -31
  426. package/src/judged-dispatcher.ts +78 -11
  427. package/src/judgment-binding.ts +25 -1
  428. package/src/mcp-endpoint-binding.ts +7 -0
  429. package/src/memory-binding.ts +121 -17
  430. package/src/memory-erasure-binding.ts +156 -0
  431. package/src/middleware/auth.ts +228 -62
  432. package/src/middleware/authorize.ts +155 -3
  433. package/src/middleware/error-mapper.ts +15 -1
  434. package/src/middleware/idempotency.ts +230 -43
  435. package/src/middleware/key-project.ts +86 -0
  436. package/src/middleware/principal.ts +9 -5
  437. package/src/middleware/project-ref.ts +3 -0
  438. package/src/openapi/generate.ts +11 -2
  439. package/src/openapi/operations.ts +1060 -143
  440. package/src/openapi/schemas.ts +2387 -469
  441. package/src/person-grants-binding.ts +76 -0
  442. package/src/proposal-service.ts +640 -0
  443. package/src/proposal-status.ts +176 -0
  444. package/src/provider-binding.ts +10 -0
  445. package/src/publish-refused.ts +56 -9
  446. package/src/routes/adapters.ts +4 -0
  447. package/src/routes/agent-releases.ts +121 -69
  448. package/src/routes/agents.ts +128 -1
  449. package/src/routes/approvals.ts +164 -154
  450. package/src/routes/artifacts.ts +181 -11
  451. package/src/routes/auth.ts +804 -336
  452. package/src/routes/blocks.ts +2 -53
  453. package/src/routes/capabilities.ts +10 -1
  454. package/src/routes/compliance.ts +60 -99
  455. package/src/routes/conversations.ts +101 -7
  456. package/src/routes/cost.ts +110 -4
  457. package/src/routes/denied.ts +28 -0
  458. package/src/routes/deployments.ts +210 -17
  459. package/src/routes/eval-comparison.ts +81 -2
  460. package/src/routes/eval-overrides.ts +108 -0
  461. package/src/routes/eval-runs.ts +89 -6
  462. package/src/routes/eval-suites.ts +32 -2
  463. package/src/routes/event-triggers.ts +27 -3
  464. package/src/routes/export-signing-keys.ts +31 -0
  465. package/src/routes/flows.ts +12 -1
  466. package/src/routes/gate-policies.ts +37 -6
  467. package/src/routes/guardrails.ts +61 -2
  468. package/src/routes/identity.ts +328 -10
  469. package/src/routes/improvement-passes.ts +541 -0
  470. package/src/routes/judged-suites.ts +113 -43
  471. package/src/routes/judgment-context.ts +76 -5
  472. package/src/routes/judgment-flow-context.ts +16 -2
  473. package/src/routes/judgments.ts +17 -3
  474. package/src/routes/mcp.ts +29 -1
  475. package/src/routes/memory-access.ts +160 -0
  476. package/src/routes/memory-erasures.ts +240 -0
  477. package/src/routes/memory-parse.ts +250 -0
  478. package/src/routes/memory.ts +244 -286
  479. package/src/routes/observations.ts +15 -2
  480. package/src/routes/pagination.ts +12 -0
  481. package/src/routes/policies.ts +7 -1
  482. package/src/routes/project-mismatch.ts +56 -0
  483. package/src/routes/projects.ts +107 -13
  484. package/src/routes/proposals.ts +370 -611
  485. package/src/routes/provenance.ts +99 -133
  486. package/src/routes/providers.ts +142 -3
  487. package/src/routes/public-run-tokens.ts +3 -0
  488. package/src/routes/readable-projects.ts +66 -0
  489. package/src/routes/runs.ts +119 -39
  490. package/src/routes/schedules.ts +472 -60
  491. package/src/routes/segments.ts +11 -0
  492. package/src/routes/service-accounts.ts +262 -0
  493. package/src/routes/sign-in-options.ts +168 -0
  494. package/src/routes/signing-keys.ts +7 -1
  495. package/src/routes/tenant-access.ts +37 -0
  496. package/src/routes/tenant.ts +6 -0
  497. package/src/routes/token-sign-in.ts +161 -0
  498. package/src/routes/tokens.ts +172 -46
  499. package/src/routes/tools.ts +12 -1
  500. package/src/routes/trigger-access.ts +72 -0
  501. package/src/routes/webhook-endpoints.ts +15 -3
  502. package/src/routes/webhooks.ts +26 -2
  503. package/src/run-failure.ts +42 -0
  504. package/src/service-account-binding.ts +113 -0
  505. package/src/session-store-binding.ts +65 -13
  506. package/src/signed-export.ts +250 -0
  507. package/src/supervisor-binding.ts +169 -409
  508. package/src/testing/app-bindings.ts +142 -0
  509. package/src/testing/index.ts +21 -0
  510. package/src/testing/stub-binding.ts +53 -0
  511. package/src/testing/trigger-registry.ts +259 -0
  512. package/src/token-admin.ts +40 -8
  513. package/src/tool-binding.ts +14 -0
  514. package/src/trigger-binding.ts +8 -1
  515. package/src/types.ts +16 -0
  516. package/src/webhook-endpoint-binding.ts +18 -3
@@ -0,0 +1,176 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type { EvalRun, EvalRunStatus } from './eval-run-binding.js';
5
+ import type { JudgedComparisonSummary } from './judged-dispatcher.js';
6
+ import type { Promotion } from './live-version-binding.js';
7
+ import type { ProposalObjective, StoredProposal } from './supervisor-binding.js';
8
+
9
+ /**
10
+ * Where an improvement proposal stands. Never stored: it follows from the
11
+ * proposal's own steps, its comparison eval run and its promotion.
12
+ *
13
+ * - `draft`: not evaluated yet.
14
+ * - `evaluating`: its comparison is queued or running.
15
+ * - `evaluated`: the comparison finished and the candidate beat the
16
+ * recorded outputs on the objective metric by more than the noise.
17
+ * - `not-better`: the comparison finished; the candidate didn't.
18
+ * - `evaluation-failed`: the comparison failed or was cancelled.
19
+ * - `in-review`: requested; the gate passed and an approval is open.
20
+ * - `promoted`: the candidate went live for the scope.
21
+ * - `refused`: requested; the gate refused it.
22
+ * - `rejected`: the reviewer rejected it.
23
+ * - `expired`: the approval expired undecided.
24
+ * - `superseded`: approved after the scope's live version or policy changed.
25
+ * - `rolled-back`: rolled back through the proposal.
26
+ * - `withdrawn`: withdrawn.
27
+ */
28
+ export type FixProposalStatus =
29
+ | 'draft'
30
+ | 'evaluating'
31
+ | 'evaluated'
32
+ | 'not-better'
33
+ | 'evaluation-failed'
34
+ | 'in-review'
35
+ | 'promoted'
36
+ | 'refused'
37
+ | 'rejected'
38
+ | 'expired'
39
+ | 'superseded'
40
+ | 'rolled-back'
41
+ | 'withdrawn';
42
+
43
+ export const FIX_PROPOSAL_STATUSES: readonly FixProposalStatus[] = [
44
+ 'draft',
45
+ 'evaluating',
46
+ 'evaluated',
47
+ 'not-better',
48
+ 'evaluation-failed',
49
+ 'in-review',
50
+ 'promoted',
51
+ 'refused',
52
+ 'rejected',
53
+ 'expired',
54
+ 'superseded',
55
+ 'rolled-back',
56
+ 'withdrawn',
57
+ ];
58
+
59
+ /** What a finished comparison says about the candidate, on the proposal's objective. */
60
+ export interface ProposalEvaluationOutcome {
61
+ readonly runStatus: EvalRunStatus;
62
+ readonly objective: ProposalObjective;
63
+ /** The recorded (judged) outputs' score. `null` without judged evidence. */
64
+ readonly baseline?: number | null;
65
+ readonly candidate?: number | null;
66
+ readonly delta?: number | null;
67
+ /** With more than one repetition: the candidate's max − min. The noise a delta must beat. */
68
+ readonly spread?: number;
69
+ readonly cases?: number;
70
+ /** Set once the comparison finished. */
71
+ readonly better?: boolean;
72
+ }
73
+
74
+ /** Room for float rounding. */
75
+ const EPSILON = 1e-9;
76
+
77
+ /** A finished comparison's summary, or `null` for any other eval run. */
78
+ export function comparisonSummaryOf(run: EvalRun): JudgedComparisonSummary | null {
79
+ const summary = run.result?.summary;
80
+ return run.kind === 'judged' && summary !== null && typeof summary === 'object'
81
+ ? (summary as JudgedComparisonSummary)
82
+ : null;
83
+ }
84
+
85
+ /** The proposal's evaluation, read off its eval run. */
86
+ export function evaluationOutcome(
87
+ objective: ProposalObjective,
88
+ run: EvalRun,
89
+ ): ProposalEvaluationOutcome {
90
+ const summary = run.status === 'completed' ? comparisonSummaryOf(run) : null;
91
+ if (summary === null) return { runStatus: run.status, objective };
92
+ const metric = summary.metrics[objective];
93
+ const noise = metric.spread ?? 0;
94
+ return {
95
+ runStatus: run.status,
96
+ objective,
97
+ baseline: metric.baseline,
98
+ candidate: metric.candidate,
99
+ delta: metric.delta,
100
+ ...(metric.spread !== undefined && { spread: metric.spread }),
101
+ cases: summary.cases,
102
+ better: metric.delta !== null && metric.delta > noise + EPSILON,
103
+ };
104
+ }
105
+
106
+ const PROMOTION_STATUS: Readonly<Record<NonNullable<Promotion['status']>, FixProposalStatus>> = {
107
+ 'pending-approval': 'in-review',
108
+ promoted: 'promoted',
109
+ refused: 'refused',
110
+ rejected: 'rejected',
111
+ expired: 'expired',
112
+ superseded: 'superseded',
113
+ };
114
+
115
+ /**
116
+ * A proposal's status from what's recorded: its own steps first
117
+ * (withdrawn, rolled back), then its promotion, then its comparison.
118
+ * `promotion` and `evaluation` are what the proposal's ids resolve to
119
+ * (`undefined` when it has none).
120
+ */
121
+ export function proposalStatus(
122
+ proposal: StoredProposal,
123
+ promotion: Promotion | null | undefined,
124
+ evaluation: ProposalEvaluationOutcome | null | undefined,
125
+ ): FixProposalStatus {
126
+ if (proposal.withdrawn !== undefined) return 'withdrawn';
127
+ if (proposal.rolledBack !== undefined) return 'rolled-back';
128
+ if (promotion !== undefined && promotion !== null) {
129
+ return PROMOTION_STATUS[promotion.status ?? 'promoted'];
130
+ }
131
+ if (evaluation === undefined || evaluation === null) {
132
+ return proposal.evaluation === undefined ? 'draft' : 'evaluation-failed';
133
+ }
134
+ switch (evaluation.runStatus) {
135
+ case 'pending':
136
+ case 'running':
137
+ return 'evaluating';
138
+ case 'failed':
139
+ case 'cancelled':
140
+ return 'evaluation-failed';
141
+ case 'completed':
142
+ return evaluation.better === true ? 'evaluated' : 'not-better';
143
+ }
144
+ }
145
+
146
+ /** The lifecycle calls, and the statuses each starts from. */
147
+ export const PROPOSAL_ACTIONS = {
148
+ evaluate: [
149
+ 'draft',
150
+ 'evaluated',
151
+ 'not-better',
152
+ 'evaluation-failed',
153
+ 'refused',
154
+ 'superseded',
155
+ 'expired',
156
+ ],
157
+ // The gate decides what goes live: a candidate that isn't measurably
158
+ // better (a wording change) can still be requested through it.
159
+ request: ['evaluated', 'not-better', 'refused', 'superseded', 'expired'],
160
+ rollback: ['promoted'],
161
+ withdraw: [
162
+ 'draft',
163
+ 'evaluated',
164
+ 'not-better',
165
+ 'evaluation-failed',
166
+ 'refused',
167
+ 'superseded',
168
+ 'expired',
169
+ ],
170
+ } as const satisfies Readonly<Record<string, readonly FixProposalStatus[]>>;
171
+
172
+ export type ProposalAction = keyof typeof PROPOSAL_ACTIONS;
173
+
174
+ export function proposalActionAllowed(action: ProposalAction, status: FixProposalStatus): boolean {
175
+ return (PROPOSAL_ACTIONS[action] as readonly FixProposalStatus[]).includes(status);
176
+ }
@@ -131,6 +131,14 @@ export interface ProviderRegisterInput {
131
131
  * to the runtime, never returned by `list` / `get`.
132
132
  */
133
133
  readonly adapterConfig?: AdapterConfig;
134
+ /**
135
+ * Whether the runtime sends each model call's W3C `traceparent` to this
136
+ * provider (as a header; ids only, never content), so the vendor's
137
+ * request logs can be matched to the run. Opt-in: absent or `false`
138
+ * sends none. The runtime enforces it, not the adapter: it sets
139
+ * `ModelCallInput.traceparent` only for a provider that opted in.
140
+ */
141
+ readonly sendTraceparent?: boolean;
134
142
  }
135
143
 
136
144
  export interface ProviderSecretRef {
@@ -152,6 +160,8 @@ export interface ProviderRuntimeEntry {
152
160
  readonly adapterId: string;
153
161
  readonly secretRef?: ProviderSecretRef;
154
162
  readonly adapterConfig?: AdapterConfig;
163
+ /** `ProviderRegisterInput.sendTraceparent`: absent is `false`. */
164
+ readonly sendTraceparent?: boolean;
155
165
  }
156
166
 
157
167
  export interface ProviderResolveForRuntimeInput {
@@ -1,31 +1,78 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
 
4
+ import type { ProjectId } from '@kindgi/types';
5
+
4
6
  import type { AgentRegistryBinding } from './agent-binding.js';
5
7
  import type { FlowRegistryBinding } from './flow-binding.js';
6
8
  import type { GuardrailRegistryBinding } from './guardrail-binding.js';
7
9
  import type { ToolRegistryBinding } from './tool-binding.js';
8
10
 
11
+ type PublishedPrimitive = 'tool' | 'guardrail' | 'agent' | 'flow';
12
+
13
+ /** A registry's answer to a deploy's publish, other than `ok` or `already-registered`. */
14
+ type RefusedOutcome = Exclude<
15
+ | Awaited<ReturnType<ToolRegistryBinding['publish']>>
16
+ | Awaited<ReturnType<GuardrailRegistryBinding['register']>>
17
+ | Awaited<ReturnType<AgentRegistryBinding['publish']>>
18
+ | Awaited<ReturnType<FlowRegistryBinding['publish']>>,
19
+ { readonly kind: 'ok' | 'already-registered' }
20
+ >;
21
+
22
+ /**
23
+ * A refusal the deploy decides itself, when its registry answered
24
+ * `already-registered` for a live guardrail it can't keep: one in another
25
+ * project (whose project the registry doesn't say), or one in its own
26
+ * project with a different definition.
27
+ */
28
+ interface DeployRefusal {
29
+ readonly code: 'guardrail-project-mismatch' | 'guardrail-already-registered';
30
+ readonly reason: string;
31
+ }
32
+
9
33
  /**
10
34
  * A deploy's primitive came back from its registry with an outcome other
11
35
  * than `ok` or `already-registered` (e.g. `project-not-found`): the deploy
12
36
  * stops, what it published is rolled back, and the route answers with
13
37
  * that outcome's own status and code (T205). Before, such an outcome was
14
38
  * skipped, and the deployment was recorded without that primitive.
39
+ *
40
+ * A primitive whose id belongs to another project answers
41
+ * `<primitive>-project-mismatch`, as publishing it on its own does: a
42
+ * deploy never moves it. The project it belongs to (`projectId`) is for
43
+ * the log, never the answer.
15
44
  */
16
45
  export class PublishRefused extends Error {
46
+ /** The code the deploy answers with. */
47
+ readonly code:
48
+ | Exclude<RefusedOutcome['kind'], 'project-mismatch'>
49
+ | `${PublishedPrimitive}-project-mismatch`
50
+ | DeployRefusal['code'];
51
+ /** With `…-project-mismatch`: the project the primitive belongs to, for the log only. */
52
+ readonly projectId?: ProjectId;
53
+
17
54
  constructor(
18
- readonly primitive: 'tool' | 'guardrail' | 'agent' | 'flow',
55
+ readonly primitive: PublishedPrimitive,
19
56
  readonly id: string,
20
- readonly code: Exclude<
21
- | Awaited<ReturnType<ToolRegistryBinding['publish']>>['kind']
22
- | Awaited<ReturnType<GuardrailRegistryBinding['register']>>['kind']
23
- | Awaited<ReturnType<AgentRegistryBinding['publish']>>['kind']
24
- | Awaited<ReturnType<FlowRegistryBinding['publish']>>['kind'],
25
- 'ok' | 'already-registered'
26
- >,
57
+ outcome: RefusedOutcome | DeployRefusal,
27
58
  ) {
28
- super(`The ${primitive} ${id} wasn't published: ${code}`);
59
+ if ('code' in outcome) {
60
+ super(`The ${primitive} ${id} wasn't published: ${outcome.reason}`);
61
+ this.name = 'PublishRefused';
62
+ this.code = outcome.code;
63
+ return;
64
+ }
65
+ const code =
66
+ outcome.kind === 'project-mismatch'
67
+ ? (`${primitive}-project-mismatch` as const)
68
+ : outcome.kind;
69
+ super(
70
+ outcome.kind === 'project-mismatch'
71
+ ? `The ${primitive} ${id} wasn't published: it belongs to another project`
72
+ : `The ${primitive} ${id} wasn't published: ${code}`,
73
+ );
29
74
  this.name = 'PublishRefused';
75
+ this.code = code;
76
+ if (outcome.kind === 'project-mismatch') this.projectId = outcome.projectId;
30
77
  }
31
78
  }
@@ -17,8 +17,10 @@ import {
17
17
  type AdapterTestOutcome,
18
18
  } from '../adapter-binding.js';
19
19
  import { statusFor, toWireError } from '../errors.js';
20
+ import type { Authorizer } from '../middleware/authorize.js';
20
21
  import type { AppEnv } from '../types.js';
21
22
  import { clampLimit } from './pagination.js';
23
+ import { tenantResourceAccess } from './tenant-access.js';
22
24
 
23
25
  /**
24
26
  * Adapters resource routes — part of the admin control plane. Unified
@@ -46,8 +48,10 @@ import { clampLimit } from './pagination.js';
46
48
  export function adaptersRouter(
47
49
  binding: AdapterRegistryBinding,
48
50
  factories?: AdapterFactoryRegistry,
51
+ authorizer?: Authorizer,
49
52
  ): Hono<AppEnv> {
50
53
  const r = new Hono<AppEnv>();
54
+ r.use('*', tenantResourceAccess(authorizer));
51
55
 
52
56
  // ---------- GET / (list, cursor-paginated) ----------
53
57
  r.get('/', async (c) => {
@@ -12,11 +12,12 @@ import type { AgentRegistryBinding } from '../agent-binding.js';
12
12
  import { statusFor, toWireError } from '../errors.js';
13
13
  import type { EvalRun, EvalRunBinding } from '../eval-run-binding.js';
14
14
  import type { GatePolicy } from '../gate-policy-binding.js';
15
- import { type GateResult, evaluateGate } from '../gate.js';
15
+ import { type GateApproval, type GateCheck, type GateResult, evaluateGate } from '../gate.js';
16
16
  import type { JudgedComparisonSummary } from '../judged-dispatcher.js';
17
17
  import type {
18
18
  AgentReleaseBindings,
19
19
  LiveResolveInput,
20
+ PromoteInput,
20
21
  Promotion,
21
22
  PromotionActor,
22
23
  } from '../live-version-binding.js';
@@ -137,79 +138,17 @@ export function mountAgentReleaseRoutes(
137
138
  const requestId = c.get('requestId');
138
139
  const parsed = await readPromotionBody(c);
139
140
  if (parsed.kind === 'err') return badInput(c, requestId, parsed.message);
140
- const tenantId = c.get('tenantId') as TenantId;
141
141
  const agentId = c.req.param('agentId');
142
- const input = {
143
- tenantId,
142
+ const outcome = await requestPromotion(registry, releases, deps, {
143
+ tenantId: c.get('tenantId') as TenantId,
144
144
  agentId,
145
145
  version: parsed.value.version,
146
146
  scope: parsed.value.scope,
147
147
  requestedBy: actorOf(c),
148
148
  ...(parsed.value.reason !== undefined && { reason: parsed.value.reason }),
149
149
  ...(parsed.value.evalRunId !== undefined && { evalRunId: parsed.value.evalRunId }),
150
- };
151
- const policy = await policyFor(releases, tenantId, agentId, parsed.value.scope);
152
- if (releases.promotions.request === undefined) {
153
- if (policy !== null) {
154
- c.status(statusFor('promotion-gate-unsupported') as never);
155
- return c.json(
156
- toWireError(
157
- {
158
- code: 'promotion-gate-unsupported',
159
- message: `Gate policy ${policy.id} ${policy.version} applies to this promotion, and this deployment can't record a gated promotion yet.`,
160
- },
161
- requestId,
162
- ),
163
- );
164
- }
165
- // No gate, and a binding from before gates: promote as before.
166
- const outcome = await releases.promotions.promote(input);
167
- if (outcome.kind === 'err') return failed(c, requestId, outcome.error);
168
- c.status(201);
169
- return c.json(serializePromotion(outcome.value));
170
- }
171
- const gate = await runGate(
172
- registry,
173
- releases,
174
- deps,
175
- { ...parsed.value, tenantId, agentId },
176
- policy,
177
- );
178
- if (gate.kind === 'err') return failed(c, requestId, gate.error);
179
- const outcome = await releases.promotions.request({
180
- ...input,
181
- gate: {
182
- policy: policy === null ? null : { id: policy.id, version: policy.version },
183
- checks: gate.result.checks,
184
- passed: gate.result.passed,
185
- ...(gate.result.approval !== undefined && { approval: gate.result.approval }),
186
- servingVersion: gate.servingVersion as Semver,
187
- ...(gate.pinInPlace && { pinInPlace: true }),
188
- },
189
150
  });
190
- if (outcome.kind === 'err') return failed(c, requestId, outcome.error);
191
- const promotion = outcome.value;
192
- if (promotion.status === 'refused') {
193
- const checks = promotion.checks ?? gate.result.checks;
194
- c.status(statusFor('gate-failed') as never);
195
- return c.json(
196
- toWireError(
197
- {
198
- code: 'gate-failed',
199
- message: `The gate refused ${agentId} ${parsed.value.version}: ${checks
200
- .filter((check) => !check.passed)
201
- .map((check) => check.message)
202
- .join(' ')}`,
203
- promotionId: promotion.id,
204
- policy: promotion.policy ?? null,
205
- checks,
206
- },
207
- requestId,
208
- ),
209
- );
210
- }
211
- c.status(promotion.status === 'pending-approval' ? 202 : 201);
212
- return c.json(serializePromotion(promotion));
151
+ return promotionResponse(c, outcome);
213
152
  });
214
153
 
215
154
  r.post('/:agentId/promotions/check', async (c) => {
@@ -341,6 +280,119 @@ export function mountAgentReleaseRoutes(
341
280
 
342
281
  type Ctx = Context<AppEnv>;
343
282
 
283
+ /** A promotion request's outcome: recorded, refused before recording, or unsupported here. */
284
+ export type PromotionRequestOutcome =
285
+ | {
286
+ readonly kind: 'ok';
287
+ readonly promotion: Promotion;
288
+ /** The gate's checks as they ran (a binding may not echo them on the row). */
289
+ readonly checks?: readonly GateCheck[];
290
+ }
291
+ | { readonly kind: 'err'; readonly error: { code: string; message: string } }
292
+ | { readonly kind: 'gate-unsupported'; readonly policy: GatePolicy };
293
+
294
+ /**
295
+ * Request that `version` go live for `scope`, through the scope's gate:
296
+ * the binding records it as promoted, waiting for approval, or refused
297
+ * (`promotion.status`). Without gated requests in this deployment, an
298
+ * ungated scope promotes as before and a gated one is unsupported.
299
+ */
300
+ export async function requestPromotion(
301
+ registry: AgentRegistryBinding,
302
+ releases: AgentReleaseBindings,
303
+ deps: AgentReleaseGateDeps,
304
+ input: PromoteInput,
305
+ options: {
306
+ /** An approval the promotion waits for even when the scope's policy asks for none. */
307
+ readonly requireApproval?: GateApproval;
308
+ } = {},
309
+ ): Promise<PromotionRequestOutcome> {
310
+ const policy = await policyFor(releases, input.tenantId, input.agentId, input.scope);
311
+ if (releases.promotions.request === undefined) {
312
+ if (policy !== null) return { kind: 'gate-unsupported', policy };
313
+ if (options.requireApproval !== undefined) {
314
+ return {
315
+ kind: 'err',
316
+ error: {
317
+ code: 'promotion-gate-unsupported',
318
+ message:
319
+ "This promotion waits for a reviewer's approval, and this deployment can't record a gated promotion yet.",
320
+ },
321
+ };
322
+ }
323
+ // No gate, and a binding from before gates: promote as before.
324
+ const outcome = await releases.promotions.promote(input);
325
+ return outcome.kind === 'err'
326
+ ? { kind: 'err', error: outcome.error }
327
+ : { kind: 'ok', promotion: outcome.value };
328
+ }
329
+ const gate = await runGate(registry, releases, deps, input, policy);
330
+ if (gate.kind === 'err') return gate;
331
+ const approval = gate.result.approval ?? options.requireApproval;
332
+ const outcome = await releases.promotions.request({
333
+ ...input,
334
+ gate: {
335
+ policy: policy === null ? null : { id: policy.id, version: policy.version },
336
+ checks: gate.result.checks,
337
+ passed: gate.result.passed,
338
+ ...(approval !== undefined && { approval }),
339
+ servingVersion: gate.servingVersion as Semver,
340
+ ...(gate.pinInPlace && { pinInPlace: true }),
341
+ },
342
+ });
343
+ return outcome.kind === 'err'
344
+ ? { kind: 'err', error: outcome.error }
345
+ : { kind: 'ok', promotion: outcome.value, checks: gate.result.checks };
346
+ }
347
+
348
+ /**
349
+ * The answer to a promotion request: 201 promoted, 202 waiting for
350
+ * approval, 422 `gate-failed` with the checks, or the error.
351
+ */
352
+ export function promotionResponse(
353
+ c: Ctx,
354
+ outcome: PromotionRequestOutcome,
355
+ extra: Readonly<Record<string, unknown>> = {},
356
+ ) {
357
+ const requestId = c.get('requestId');
358
+ if (outcome.kind === 'gate-unsupported') {
359
+ c.status(statusFor('promotion-gate-unsupported') as never);
360
+ return c.json(
361
+ toWireError(
362
+ {
363
+ code: 'promotion-gate-unsupported',
364
+ message: `Gate policy ${outcome.policy.id} ${outcome.policy.version} applies to this promotion, and this deployment can't record a gated promotion yet.`,
365
+ },
366
+ requestId,
367
+ ),
368
+ );
369
+ }
370
+ if (outcome.kind === 'err') return failed(c, requestId, outcome.error);
371
+ const { promotion } = outcome;
372
+ if (promotion.status === 'refused') {
373
+ const checks = promotion.checks ?? outcome.checks ?? [];
374
+ c.status(statusFor('gate-failed') as never);
375
+ return c.json(
376
+ toWireError(
377
+ {
378
+ code: 'gate-failed',
379
+ message: `The gate refused ${promotion.agentId} ${promotion.toVersion as unknown as string}: ${checks
380
+ .filter((check) => !check.passed)
381
+ .map((check) => check.message)
382
+ .join(' ')}`,
383
+ promotionId: promotion.id,
384
+ policy: promotion.policy ?? null,
385
+ checks,
386
+ ...extra,
387
+ },
388
+ requestId,
389
+ ),
390
+ );
391
+ }
392
+ c.status(promotion.status === 'pending-approval' ? 202 : 201);
393
+ return c.json({ ...serializePromotion(promotion), ...extra });
394
+ }
395
+
344
396
  async function readBody(c: Ctx): Promise<Record<string, unknown> | undefined> {
345
397
  try {
346
398
  const body: unknown = await c.req.json();
@@ -409,7 +461,7 @@ async function readPromotionBody(c: Ctx): Promise<
409
461
  }
410
462
 
411
463
  /** The gate policy for a promotion of `agentId` for `scope`; `null` when none applies. */
412
- async function policyFor(
464
+ export async function policyFor(
413
465
  releases: AgentReleaseBindings,
414
466
  tenantId: TenantId,
415
467
  agentId: string,
@@ -421,7 +473,7 @@ async function policyFor(
421
473
  }
422
474
 
423
475
  /** The scope's coordinates, as a run in it would resolve its version. */
424
- function coordinatesOf(scope: LiveScope): Omit<LiveResolveInput, 'tenantId' | 'agentId'> {
476
+ export function coordinatesOf(scope: LiveScope): Omit<LiveResolveInput, 'tenantId' | 'agentId'> {
425
477
  switch (scope.kind) {
426
478
  case 'tenant':
427
479
  return {};
@@ -566,7 +618,7 @@ async function runGate(
566
618
  }
567
619
 
568
620
  /** Who asked, from the request's principal. */
569
- function actorOf(c: Ctx): PromotionActor {
621
+ export function actorOf(c: Ctx): PromotionActor {
570
622
  const actor = c.get('principal')?.actor;
571
623
  if (actor === undefined) return { kind: 'service', id: 'unknown' };
572
624
  return { kind: actor.kind === 'user' ? 'user' : 'service', id: actor.id };