@kindgi/api 0.0.0-bootstrap.0 → 0.1.1

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 (505) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +216 -1
  3. package/dist/adapter-binding.d.ts +177 -0
  4. package/dist/adapter-binding.d.ts.map +1 -0
  5. package/dist/adapter-binding.js +12 -0
  6. package/dist/adapter-binding.js.map +1 -0
  7. package/dist/agent-binding.d.ts +207 -0
  8. package/dist/agent-binding.d.ts.map +1 -0
  9. package/dist/agent-binding.js +4 -0
  10. package/dist/agent-binding.js.map +1 -0
  11. package/dist/app.d.ts +770 -0
  12. package/dist/app.d.ts.map +1 -0
  13. package/dist/app.js +397 -0
  14. package/dist/app.js.map +1 -0
  15. package/dist/capability-binding.d.ts +76 -0
  16. package/dist/capability-binding.d.ts.map +1 -0
  17. package/dist/capability-binding.js +4 -0
  18. package/dist/capability-binding.js.map +1 -0
  19. package/dist/cost-binding.d.ts +175 -0
  20. package/dist/cost-binding.d.ts.map +1 -0
  21. package/dist/cost-binding.js +13 -0
  22. package/dist/cost-binding.js.map +1 -0
  23. package/dist/deployment-binding.d.ts +201 -0
  24. package/dist/deployment-binding.d.ts.map +1 -0
  25. package/dist/deployment-binding.js +4 -0
  26. package/dist/deployment-binding.js.map +1 -0
  27. package/dist/env-binding.d.ts +132 -0
  28. package/dist/env-binding.d.ts.map +1 -0
  29. package/dist/env-binding.js +4 -0
  30. package/dist/env-binding.js.map +1 -0
  31. package/dist/errors.d.ts +37 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +268 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/eval-run-binding.d.ts +196 -0
  36. package/dist/eval-run-binding.d.ts.map +1 -0
  37. package/dist/eval-run-binding.js +16 -0
  38. package/dist/eval-run-binding.js.map +1 -0
  39. package/dist/eval-run-dispatcher.d.ts +131 -0
  40. package/dist/eval-run-dispatcher.d.ts.map +1 -0
  41. package/dist/eval-run-dispatcher.js +368 -0
  42. package/dist/eval-run-dispatcher.js.map +1 -0
  43. package/dist/eval-suite-binding.d.ts +227 -0
  44. package/dist/eval-suite-binding.d.ts.map +1 -0
  45. package/dist/eval-suite-binding.js +24 -0
  46. package/dist/eval-suite-binding.js.map +1 -0
  47. package/dist/event-bus-binding.d.ts +107 -0
  48. package/dist/event-bus-binding.d.ts.map +1 -0
  49. package/dist/event-bus-binding.js +5 -0
  50. package/dist/event-bus-binding.js.map +1 -0
  51. package/dist/flow-binding.d.ts +194 -0
  52. package/dist/flow-binding.d.ts.map +1 -0
  53. package/dist/flow-binding.js +4 -0
  54. package/dist/flow-binding.js.map +1 -0
  55. package/dist/guardrail-binding.d.ts +138 -0
  56. package/dist/guardrail-binding.d.ts.map +1 -0
  57. package/dist/guardrail-binding.js +4 -0
  58. package/dist/guardrail-binding.js.map +1 -0
  59. package/dist/handler-binding.d.ts +126 -0
  60. package/dist/handler-binding.d.ts.map +1 -0
  61. package/dist/handler-binding.js +4 -0
  62. package/dist/handler-binding.js.map +1 -0
  63. package/dist/hitl-binding.d.ts +115 -0
  64. package/dist/hitl-binding.d.ts.map +1 -0
  65. package/dist/hitl-binding.js +4 -0
  66. package/dist/hitl-binding.js.map +1 -0
  67. package/dist/identity-directory-binding.d.ts +116 -0
  68. package/dist/identity-directory-binding.d.ts.map +1 -0
  69. package/dist/identity-directory-binding.js +4 -0
  70. package/dist/identity-directory-binding.js.map +1 -0
  71. package/dist/identity-provider-binding.d.ts +184 -0
  72. package/dist/identity-provider-binding.d.ts.map +1 -0
  73. package/dist/identity-provider-binding.js +4 -0
  74. package/dist/identity-provider-binding.js.map +1 -0
  75. package/dist/image-registry-binding.d.ts +165 -0
  76. package/dist/image-registry-binding.d.ts.map +1 -0
  77. package/dist/image-registry-binding.js +4 -0
  78. package/dist/image-registry-binding.js.map +1 -0
  79. package/dist/index.d.ts +72 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +26 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/key-management-binding.d.ts +101 -0
  84. package/dist/key-management-binding.d.ts.map +1 -0
  85. package/dist/key-management-binding.js +4 -0
  86. package/dist/key-management-binding.js.map +1 -0
  87. package/dist/mcp-endpoint-binding.d.ts +312 -0
  88. package/dist/mcp-endpoint-binding.d.ts.map +1 -0
  89. package/dist/mcp-endpoint-binding.js +12 -0
  90. package/dist/mcp-endpoint-binding.js.map +1 -0
  91. package/dist/memory-binding.d.ts +209 -0
  92. package/dist/memory-binding.d.ts.map +1 -0
  93. package/dist/memory-binding.js +4 -0
  94. package/dist/memory-binding.js.map +1 -0
  95. package/dist/middleware/auth.d.ts +168 -0
  96. package/dist/middleware/auth.d.ts.map +1 -0
  97. package/dist/middleware/auth.js +247 -0
  98. package/dist/middleware/auth.js.map +1 -0
  99. package/dist/middleware/authorize.d.ts +26 -0
  100. package/dist/middleware/authorize.d.ts.map +1 -0
  101. package/dist/middleware/authorize.js +65 -0
  102. package/dist/middleware/authorize.js.map +1 -0
  103. package/dist/middleware/error-mapper.d.ts +20 -0
  104. package/dist/middleware/error-mapper.d.ts.map +1 -0
  105. package/dist/middleware/error-mapper.js +34 -0
  106. package/dist/middleware/error-mapper.js.map +1 -0
  107. package/dist/middleware/idempotency.d.ts +43 -0
  108. package/dist/middleware/idempotency.d.ts.map +1 -0
  109. package/dist/middleware/idempotency.js +118 -0
  110. package/dist/middleware/idempotency.js.map +1 -0
  111. package/dist/middleware/principal.d.ts +4 -0
  112. package/dist/middleware/principal.d.ts.map +1 -0
  113. package/dist/middleware/principal.js +42 -0
  114. package/dist/middleware/principal.js.map +1 -0
  115. package/dist/middleware/public-run-routes.d.ts +16 -0
  116. package/dist/middleware/public-run-routes.d.ts.map +1 -0
  117. package/dist/middleware/public-run-routes.js +43 -0
  118. package/dist/middleware/public-run-routes.js.map +1 -0
  119. package/dist/middleware/request-id.d.ts +14 -0
  120. package/dist/middleware/request-id.d.ts.map +1 -0
  121. package/dist/middleware/request-id.js +24 -0
  122. package/dist/middleware/request-id.js.map +1 -0
  123. package/dist/middleware/sigv4-verify.d.ts +64 -0
  124. package/dist/middleware/sigv4-verify.d.ts.map +1 -0
  125. package/dist/middleware/sigv4-verify.js +286 -0
  126. package/dist/middleware/sigv4-verify.js.map +1 -0
  127. package/dist/middleware/sigv4.d.ts +25 -0
  128. package/dist/middleware/sigv4.d.ts.map +1 -0
  129. package/dist/middleware/sigv4.js +120 -0
  130. package/dist/middleware/sigv4.js.map +1 -0
  131. package/dist/openapi/generate.d.ts +15 -0
  132. package/dist/openapi/generate.d.ts.map +1 -0
  133. package/dist/openapi/generate.js +241 -0
  134. package/dist/openapi/generate.js.map +1 -0
  135. package/dist/openapi/operations.d.ts +70 -0
  136. package/dist/openapi/operations.d.ts.map +1 -0
  137. package/dist/openapi/operations.js +5050 -0
  138. package/dist/openapi/operations.js.map +1 -0
  139. package/dist/openapi/schemas.d.ts +590 -0
  140. package/dist/openapi/schemas.d.ts.map +1 -0
  141. package/dist/openapi/schemas.js +5820 -0
  142. package/dist/openapi/schemas.js.map +1 -0
  143. package/dist/provenance-binding.d.ts +116 -0
  144. package/dist/provenance-binding.d.ts.map +1 -0
  145. package/dist/provenance-binding.js +31 -0
  146. package/dist/provenance-binding.js.map +1 -0
  147. package/dist/provider-binding.d.ts +174 -0
  148. package/dist/provider-binding.d.ts.map +1 -0
  149. package/dist/provider-binding.js +4 -0
  150. package/dist/provider-binding.js.map +1 -0
  151. package/dist/public-run-token.d.ts +97 -0
  152. package/dist/public-run-token.d.ts.map +1 -0
  153. package/dist/public-run-token.js +167 -0
  154. package/dist/public-run-token.js.map +1 -0
  155. package/dist/retention-binding.d.ts +69 -0
  156. package/dist/retention-binding.d.ts.map +1 -0
  157. package/dist/retention-binding.js +4 -0
  158. package/dist/retention-binding.js.map +1 -0
  159. package/dist/reviewer-binding.d.ts +84 -0
  160. package/dist/reviewer-binding.d.ts.map +1 -0
  161. package/dist/reviewer-binding.js +4 -0
  162. package/dist/reviewer-binding.js.map +1 -0
  163. package/dist/rotation-status-store.d.ts +96 -0
  164. package/dist/rotation-status-store.d.ts.map +1 -0
  165. package/dist/rotation-status-store.js +106 -0
  166. package/dist/rotation-status-store.js.map +1 -0
  167. package/dist/routes/adapters.d.ts +29 -0
  168. package/dist/routes/adapters.d.ts.map +1 -0
  169. package/dist/routes/adapters.js +230 -0
  170. package/dist/routes/adapters.js.map +1 -0
  171. package/dist/routes/agents.d.ts +17 -0
  172. package/dist/routes/agents.d.ts.map +1 -0
  173. package/dist/routes/agents.js +342 -0
  174. package/dist/routes/agents.js.map +1 -0
  175. package/dist/routes/approvals.d.ts +37 -0
  176. package/dist/routes/approvals.d.ts.map +1 -0
  177. package/dist/routes/approvals.js +551 -0
  178. package/dist/routes/approvals.js.map +1 -0
  179. package/dist/routes/artifacts.d.ts +25 -0
  180. package/dist/routes/artifacts.d.ts.map +1 -0
  181. package/dist/routes/artifacts.js +265 -0
  182. package/dist/routes/artifacts.js.map +1 -0
  183. package/dist/routes/audit.d.ts +6 -0
  184. package/dist/routes/audit.d.ts.map +1 -0
  185. package/dist/routes/audit.js +162 -0
  186. package/dist/routes/audit.js.map +1 -0
  187. package/dist/routes/auth.d.ts +47 -0
  188. package/dist/routes/auth.d.ts.map +1 -0
  189. package/dist/routes/auth.js +630 -0
  190. package/dist/routes/auth.js.map +1 -0
  191. package/dist/routes/capabilities.d.ts +14 -0
  192. package/dist/routes/capabilities.d.ts.map +1 -0
  193. package/dist/routes/capabilities.js +62 -0
  194. package/dist/routes/capabilities.js.map +1 -0
  195. package/dist/routes/compliance.d.ts +37 -0
  196. package/dist/routes/compliance.d.ts.map +1 -0
  197. package/dist/routes/compliance.js +321 -0
  198. package/dist/routes/compliance.js.map +1 -0
  199. package/dist/routes/conversations.d.ts +13 -0
  200. package/dist/routes/conversations.d.ts.map +1 -0
  201. package/dist/routes/conversations.js +295 -0
  202. package/dist/routes/conversations.js.map +1 -0
  203. package/dist/routes/cost.d.ts +24 -0
  204. package/dist/routes/cost.d.ts.map +1 -0
  205. package/dist/routes/cost.js +243 -0
  206. package/dist/routes/cost.js.map +1 -0
  207. package/dist/routes/deployments.d.ts +122 -0
  208. package/dist/routes/deployments.d.ts.map +1 -0
  209. package/dist/routes/deployments.js +1036 -0
  210. package/dist/routes/deployments.js.map +1 -0
  211. package/dist/routes/env.d.ts +62 -0
  212. package/dist/routes/env.d.ts.map +1 -0
  213. package/dist/routes/env.js +311 -0
  214. package/dist/routes/env.js.map +1 -0
  215. package/dist/routes/eval-runs.d.ts +28 -0
  216. package/dist/routes/eval-runs.d.ts.map +1 -0
  217. package/dist/routes/eval-runs.js +479 -0
  218. package/dist/routes/eval-runs.js.map +1 -0
  219. package/dist/routes/eval-suites.d.ts +24 -0
  220. package/dist/routes/eval-suites.d.ts.map +1 -0
  221. package/dist/routes/eval-suites.js +381 -0
  222. package/dist/routes/eval-suites.js.map +1 -0
  223. package/dist/routes/event-triggers.d.ts +12 -0
  224. package/dist/routes/event-triggers.d.ts.map +1 -0
  225. package/dist/routes/event-triggers.js +218 -0
  226. package/dist/routes/event-triggers.js.map +1 -0
  227. package/dist/routes/flows.d.ts +23 -0
  228. package/dist/routes/flows.d.ts.map +1 -0
  229. package/dist/routes/flows.js +344 -0
  230. package/dist/routes/flows.js.map +1 -0
  231. package/dist/routes/guardrails.d.ts +33 -0
  232. package/dist/routes/guardrails.d.ts.map +1 -0
  233. package/dist/routes/guardrails.js +236 -0
  234. package/dist/routes/guardrails.js.map +1 -0
  235. package/dist/routes/identity.d.ts +39 -0
  236. package/dist/routes/identity.d.ts.map +1 -0
  237. package/dist/routes/identity.js +138 -0
  238. package/dist/routes/identity.js.map +1 -0
  239. package/dist/routes/mcp.d.ts +23 -0
  240. package/dist/routes/mcp.d.ts.map +1 -0
  241. package/dist/routes/mcp.js +727 -0
  242. package/dist/routes/mcp.js.map +1 -0
  243. package/dist/routes/memory.d.ts +16 -0
  244. package/dist/routes/memory.d.ts.map +1 -0
  245. package/dist/routes/memory.js +353 -0
  246. package/dist/routes/memory.js.map +1 -0
  247. package/dist/routes/observations.d.ts +19 -0
  248. package/dist/routes/observations.d.ts.map +1 -0
  249. package/dist/routes/observations.js +135 -0
  250. package/dist/routes/observations.js.map +1 -0
  251. package/dist/routes/orgs.d.ts +24 -0
  252. package/dist/routes/orgs.d.ts.map +1 -0
  253. package/dist/routes/orgs.js +208 -0
  254. package/dist/routes/orgs.js.map +1 -0
  255. package/dist/routes/pagination.d.ts +18 -0
  256. package/dist/routes/pagination.d.ts.map +1 -0
  257. package/dist/routes/pagination.js +35 -0
  258. package/dist/routes/pagination.js.map +1 -0
  259. package/dist/routes/policies.d.ts +23 -0
  260. package/dist/routes/policies.d.ts.map +1 -0
  261. package/dist/routes/policies.js +314 -0
  262. package/dist/routes/policies.js.map +1 -0
  263. package/dist/routes/projects.d.ts +45 -0
  264. package/dist/routes/projects.d.ts.map +1 -0
  265. package/dist/routes/projects.js +485 -0
  266. package/dist/routes/projects.js.map +1 -0
  267. package/dist/routes/proposals.d.ts +24 -0
  268. package/dist/routes/proposals.d.ts.map +1 -0
  269. package/dist/routes/proposals.js +581 -0
  270. package/dist/routes/proposals.js.map +1 -0
  271. package/dist/routes/provenance.d.ts +34 -0
  272. package/dist/routes/provenance.d.ts.map +1 -0
  273. package/dist/routes/provenance.js +274 -0
  274. package/dist/routes/provenance.js.map +1 -0
  275. package/dist/routes/providers.d.ts +32 -0
  276. package/dist/routes/providers.d.ts.map +1 -0
  277. package/dist/routes/providers.js +490 -0
  278. package/dist/routes/providers.js.map +1 -0
  279. package/dist/routes/public-run-tokens.d.ts +17 -0
  280. package/dist/routes/public-run-tokens.d.ts.map +1 -0
  281. package/dist/routes/public-run-tokens.js +69 -0
  282. package/dist/routes/public-run-tokens.js.map +1 -0
  283. package/dist/routes/retention.d.ts +19 -0
  284. package/dist/routes/retention.d.ts.map +1 -0
  285. package/dist/routes/retention.js +152 -0
  286. package/dist/routes/retention.js.map +1 -0
  287. package/dist/routes/reviewers.d.ts +5 -0
  288. package/dist/routes/reviewers.d.ts.map +1 -0
  289. package/dist/routes/reviewers.js +161 -0
  290. package/dist/routes/reviewers.js.map +1 -0
  291. package/dist/routes/runs.d.ts +34 -0
  292. package/dist/routes/runs.d.ts.map +1 -0
  293. package/dist/routes/runs.js +705 -0
  294. package/dist/routes/runs.js.map +1 -0
  295. package/dist/routes/s3.d.ts +31 -0
  296. package/dist/routes/s3.d.ts.map +1 -0
  297. package/dist/routes/s3.js +433 -0
  298. package/dist/routes/s3.js.map +1 -0
  299. package/dist/routes/schedules.d.ts +20 -0
  300. package/dist/routes/schedules.d.ts.map +1 -0
  301. package/dist/routes/schedules.js +234 -0
  302. package/dist/routes/schedules.js.map +1 -0
  303. package/dist/routes/scope-params.d.ts +57 -0
  304. package/dist/routes/scope-params.d.ts.map +1 -0
  305. package/dist/routes/scope-params.js +105 -0
  306. package/dist/routes/scope-params.js.map +1 -0
  307. package/dist/routes/secret-ref.d.ts +20 -0
  308. package/dist/routes/secret-ref.d.ts.map +1 -0
  309. package/dist/routes/secret-ref.js +42 -0
  310. package/dist/routes/secret-ref.js.map +1 -0
  311. package/dist/routes/secrets.d.ts +53 -0
  312. package/dist/routes/secrets.d.ts.map +1 -0
  313. package/dist/routes/secrets.js +715 -0
  314. package/dist/routes/secrets.js.map +1 -0
  315. package/dist/routes/signing-keys.d.ts +23 -0
  316. package/dist/routes/signing-keys.d.ts.map +1 -0
  317. package/dist/routes/signing-keys.js +212 -0
  318. package/dist/routes/signing-keys.js.map +1 -0
  319. package/dist/routes/sse.d.ts +58 -0
  320. package/dist/routes/sse.d.ts.map +1 -0
  321. package/dist/routes/sse.js +92 -0
  322. package/dist/routes/sse.js.map +1 -0
  323. package/dist/routes/teams.d.ts +30 -0
  324. package/dist/routes/teams.d.ts.map +1 -0
  325. package/dist/routes/teams.js +443 -0
  326. package/dist/routes/teams.js.map +1 -0
  327. package/dist/routes/tenant.d.ts +57 -0
  328. package/dist/routes/tenant.d.ts.map +1 -0
  329. package/dist/routes/tenant.js +352 -0
  330. package/dist/routes/tenant.js.map +1 -0
  331. package/dist/routes/tokens.d.ts +14 -0
  332. package/dist/routes/tokens.d.ts.map +1 -0
  333. package/dist/routes/tokens.js +231 -0
  334. package/dist/routes/tokens.js.map +1 -0
  335. package/dist/routes/tools.d.ts +33 -0
  336. package/dist/routes/tools.d.ts.map +1 -0
  337. package/dist/routes/tools.js +380 -0
  338. package/dist/routes/tools.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +10 -0
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -0
  341. package/dist/routes/webhook-endpoints.js +407 -0
  342. package/dist/routes/webhook-endpoints.js.map +1 -0
  343. package/dist/routes/webhooks.d.ts +21 -0
  344. package/dist/routes/webhooks.d.ts.map +1 -0
  345. package/dist/routes/webhooks.js +228 -0
  346. package/dist/routes/webhooks.js.map +1 -0
  347. package/dist/s3-credential-binding.d.ts +54 -0
  348. package/dist/s3-credential-binding.d.ts.map +1 -0
  349. package/dist/s3-credential-binding.js +4 -0
  350. package/dist/s3-credential-binding.js.map +1 -0
  351. package/dist/secrets-binding.d.ts +281 -0
  352. package/dist/secrets-binding.d.ts.map +1 -0
  353. package/dist/secrets-binding.js +10 -0
  354. package/dist/secrets-binding.js.map +1 -0
  355. package/dist/secrets-provider-binding.d.ts +164 -0
  356. package/dist/secrets-provider-binding.d.ts.map +1 -0
  357. package/dist/secrets-provider-binding.js +4 -0
  358. package/dist/secrets-provider-binding.js.map +1 -0
  359. package/dist/session-store-binding.d.ts +148 -0
  360. package/dist/session-store-binding.d.ts.map +1 -0
  361. package/dist/session-store-binding.js +4 -0
  362. package/dist/session-store-binding.js.map +1 -0
  363. package/dist/signing-key-binding.d.ts +210 -0
  364. package/dist/signing-key-binding.d.ts.map +1 -0
  365. package/dist/signing-key-binding.js +4 -0
  366. package/dist/signing-key-binding.js.map +1 -0
  367. package/dist/state-store-binding.d.ts +53 -0
  368. package/dist/state-store-binding.d.ts.map +1 -0
  369. package/dist/state-store-binding.js +38 -0
  370. package/dist/state-store-binding.js.map +1 -0
  371. package/dist/supervisor-binding.d.ts +526 -0
  372. package/dist/supervisor-binding.d.ts.map +1 -0
  373. package/dist/supervisor-binding.js +4 -0
  374. package/dist/supervisor-binding.js.map +1 -0
  375. package/dist/tenant-host-access.d.ts +41 -0
  376. package/dist/tenant-host-access.d.ts.map +1 -0
  377. package/dist/tenant-host-access.js +42 -0
  378. package/dist/tenant-host-access.js.map +1 -0
  379. package/dist/token-admin.d.ts +99 -0
  380. package/dist/token-admin.d.ts.map +1 -0
  381. package/dist/token-admin.js +4 -0
  382. package/dist/token-admin.js.map +1 -0
  383. package/dist/tool-binding.d.ts +247 -0
  384. package/dist/tool-binding.d.ts.map +1 -0
  385. package/dist/tool-binding.js +4 -0
  386. package/dist/tool-binding.js.map +1 -0
  387. package/dist/trigger-binding.d.ts +13 -0
  388. package/dist/trigger-binding.d.ts.map +1 -0
  389. package/dist/trigger-binding.js +4 -0
  390. package/dist/trigger-binding.js.map +1 -0
  391. package/dist/types.d.ts +71 -0
  392. package/dist/types.d.ts.map +1 -0
  393. package/dist/types.js +4 -0
  394. package/dist/types.js.map +1 -0
  395. package/dist/webhook-endpoint-binding.d.ts +230 -0
  396. package/dist/webhook-endpoint-binding.d.ts.map +1 -0
  397. package/dist/webhook-endpoint-binding.js +12 -0
  398. package/dist/webhook-endpoint-binding.js.map +1 -0
  399. package/dist/xml.d.ts +79 -0
  400. package/dist/xml.d.ts.map +1 -0
  401. package/dist/xml.js +115 -0
  402. package/dist/xml.js.map +1 -0
  403. package/openapi.json +29649 -0
  404. package/package.json +76 -4
  405. package/scripts/emit-openapi.mjs +44 -0
  406. package/src/adapter-binding.ts +204 -0
  407. package/src/agent-binding.ts +231 -0
  408. package/src/app.ts +1286 -0
  409. package/src/capability-binding.ts +83 -0
  410. package/src/cost-binding.ts +213 -0
  411. package/src/deployment-binding.ts +225 -0
  412. package/src/env-binding.ts +140 -0
  413. package/src/errors.ts +295 -0
  414. package/src/eval-run-binding.ts +209 -0
  415. package/src/eval-run-dispatcher.ts +497 -0
  416. package/src/eval-suite-binding.ts +257 -0
  417. package/src/event-bus-binding.ts +127 -0
  418. package/src/flow-binding.ts +213 -0
  419. package/src/guardrail-binding.ts +151 -0
  420. package/src/handler-binding.ts +132 -0
  421. package/src/hitl-binding.ts +172 -0
  422. package/src/identity-directory-binding.ts +128 -0
  423. package/src/identity-provider-binding.ts +203 -0
  424. package/src/image-registry-binding.ts +193 -0
  425. package/src/index.ts +606 -0
  426. package/src/key-management-binding.ts +91 -0
  427. package/src/mcp-endpoint-binding.ts +311 -0
  428. package/src/memory-binding.ts +239 -0
  429. package/src/middleware/auth.ts +437 -0
  430. package/src/middleware/authorize.ts +125 -0
  431. package/src/middleware/error-mapper.ts +40 -0
  432. package/src/middleware/idempotency.ts +160 -0
  433. package/src/middleware/principal.ts +64 -0
  434. package/src/middleware/public-run-routes.ts +50 -0
  435. package/src/middleware/request-id.ts +28 -0
  436. package/src/middleware/sigv4-verify.ts +374 -0
  437. package/src/middleware/sigv4.ts +165 -0
  438. package/src/openapi/generate.ts +307 -0
  439. package/src/openapi/operations.ts +5444 -0
  440. package/src/openapi/schemas.ts +6363 -0
  441. package/src/provenance-binding.ts +169 -0
  442. package/src/provider-binding.ts +196 -0
  443. package/src/public-run-token.ts +263 -0
  444. package/src/retention-binding.ts +78 -0
  445. package/src/reviewer-binding.ts +99 -0
  446. package/src/rotation-status-store.ts +209 -0
  447. package/src/routes/adapters.ts +319 -0
  448. package/src/routes/agents.ts +424 -0
  449. package/src/routes/approvals.ts +759 -0
  450. package/src/routes/artifacts.ts +317 -0
  451. package/src/routes/audit.ts +219 -0
  452. package/src/routes/auth.ts +806 -0
  453. package/src/routes/capabilities.ts +79 -0
  454. package/src/routes/compliance.ts +482 -0
  455. package/src/routes/conversations.ts +369 -0
  456. package/src/routes/cost.ts +327 -0
  457. package/src/routes/deployments.ts +1493 -0
  458. package/src/routes/env.ts +429 -0
  459. package/src/routes/eval-runs.ts +631 -0
  460. package/src/routes/eval-suites.ts +490 -0
  461. package/src/routes/event-triggers.ts +283 -0
  462. package/src/routes/flows.ts +423 -0
  463. package/src/routes/guardrails.ts +320 -0
  464. package/src/routes/identity.ts +203 -0
  465. package/src/routes/mcp.ts +940 -0
  466. package/src/routes/memory.ts +430 -0
  467. package/src/routes/observations.ts +175 -0
  468. package/src/routes/orgs.ts +273 -0
  469. package/src/routes/pagination.ts +51 -0
  470. package/src/routes/policies.ts +413 -0
  471. package/src/routes/projects.ts +634 -0
  472. package/src/routes/proposals.ts +719 -0
  473. package/src/routes/provenance.ts +406 -0
  474. package/src/routes/providers.ts +624 -0
  475. package/src/routes/public-run-tokens.ts +104 -0
  476. package/src/routes/retention.ts +193 -0
  477. package/src/routes/reviewers.ts +209 -0
  478. package/src/routes/runs.ts +892 -0
  479. package/src/routes/s3.ts +519 -0
  480. package/src/routes/schedules.ts +300 -0
  481. package/src/routes/scope-params.ts +133 -0
  482. package/src/routes/secret-ref.ts +52 -0
  483. package/src/routes/secrets.ts +975 -0
  484. package/src/routes/signing-keys.ts +259 -0
  485. package/src/routes/sse.ts +148 -0
  486. package/src/routes/teams.ts +584 -0
  487. package/src/routes/tenant.ts +530 -0
  488. package/src/routes/tokens.ts +285 -0
  489. package/src/routes/tools.ts +491 -0
  490. package/src/routes/webhook-endpoints.ts +534 -0
  491. package/src/routes/webhooks.ts +296 -0
  492. package/src/s3-credential-binding.ts +58 -0
  493. package/src/secrets-binding.ts +308 -0
  494. package/src/secrets-provider-binding.ts +167 -0
  495. package/src/session-store-binding.ts +163 -0
  496. package/src/signing-key-binding.ts +235 -0
  497. package/src/state-store-binding.ts +84 -0
  498. package/src/supervisor-binding.ts +554 -0
  499. package/src/tenant-host-access.ts +62 -0
  500. package/src/token-admin.ts +104 -0
  501. package/src/tool-binding.ts +274 -0
  502. package/src/trigger-binding.ts +38 -0
  503. package/src/types.ts +74 -0
  504. package/src/webhook-endpoint-binding.ts +246 -0
  505. package/src/xml.ts +196 -0
@@ -0,0 +1,719 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import { type Context, Hono } from 'hono';
5
+
6
+ import type {
7
+ AgentId,
8
+ Cursor,
9
+ FixProposalId,
10
+ SupervisorId,
11
+ TenantId,
12
+ Timestamp,
13
+ } from '@kindgi/types';
14
+
15
+ import { statusFor, toWireError } from '../errors.js';
16
+ import type {
17
+ FixProposal,
18
+ FixProposalStatus,
19
+ PassCriterion,
20
+ PatternRef,
21
+ ProposedChange,
22
+ SupervisorBinding,
23
+ } from '../supervisor-binding.js';
24
+ import type { AppEnv } from '../types.js';
25
+ import { clampLimit } from './pagination.js';
26
+ import { parseScopeParams } from './scope-params.js';
27
+
28
+ const FIX_PROPOSAL_STATUSES: ReadonlySet<FixProposalStatus> = new Set([
29
+ 'draft',
30
+ 'dry-running',
31
+ 'dry-run-passed',
32
+ 'dry-run-failed',
33
+ 'proposed-for-review',
34
+ 'approved',
35
+ 'rejected',
36
+ 'applied',
37
+ 'rolled-back',
38
+ 'withdrawn',
39
+ ]);
40
+
41
+ const PROPOSAL_TIERS: ReadonlySet<ProposedChange['tier']> = new Set([
42
+ 'prompt',
43
+ 'retrieval',
44
+ 'tool-config',
45
+ ]);
46
+
47
+ const REVIEWER_ROLES: ReadonlySet<'standard' | 'senior' | 'admin'> = new Set([
48
+ 'standard',
49
+ 'senior',
50
+ 'admin',
51
+ ]);
52
+
53
+ /**
54
+ * Supervisor proposals resource. Ships the full self-fix lifecycle
55
+ * over HTTP: draft → dry-run → submit-review → apply / rollback /
56
+ * withdraw — the complete supervisor loop.
57
+ *
58
+ * Persistence + runtime wiring is caller-plugged via
59
+ * `SupervisorBinding` — the API package doesn't own supervisor
60
+ * runtime, agent registry, HITL wiring, or eval invocation.
61
+ *
62
+ * `supervisorId` scoping: every route requires an `X-Supervisor-Id`
63
+ * request header. Missing / empty → `400 supervisor-header-missing`.
64
+ *
65
+ * State transitions: attempts to advance a proposal from a status
66
+ * the runtime won't accept (e.g., apply on a proposal still in
67
+ * `dry-running`) surface as `409 proposal-invalid-state-transition`.
68
+ * This is a caller/state conflict per `docs/API-ROUTE-CONVENTIONS.md`
69
+ * §4.3 — the request was well-formed but the resource is not in
70
+ * the required state.
71
+ */
72
+ export function proposalsRouter(binding: SupervisorBinding): Hono<AppEnv> {
73
+ const r = new Hono<AppEnv>();
74
+
75
+ // ---------- supervisor-id gate for the whole resource ----------
76
+ r.use('*', async (c, next) => {
77
+ const requestId = c.get('requestId');
78
+ const supervisorId = c.req.header('x-supervisor-id');
79
+ if (supervisorId === undefined || supervisorId.length === 0) {
80
+ c.status(statusFor('supervisor-header-missing') as never);
81
+ return c.json(
82
+ toWireError(
83
+ {
84
+ code: 'supervisor-header-missing',
85
+ message:
86
+ 'X-Supervisor-Id header is required on all /v1/proposals routes; supply the SupervisorId scoping the request.',
87
+ },
88
+ requestId,
89
+ ),
90
+ );
91
+ }
92
+ await next();
93
+ return;
94
+ });
95
+
96
+ // ---------- GET / (list, cursor-paginated) ----------
97
+ r.get('/', async (c) => {
98
+ const requestId = c.get('requestId');
99
+ const tenantId = c.get('tenantId') as TenantId;
100
+ const supervisorId = c.req.header('x-supervisor-id') as SupervisorId;
101
+ const limit = clampLimit(c.req.query('limit'));
102
+
103
+ const cursorRaw = c.req.query('cursor');
104
+ const statusRaw = c.req.query('status');
105
+ const agentIdRaw = c.req.query('agentId');
106
+ const tierRaw = c.req.query('tier');
107
+
108
+ let status: FixProposalStatus | undefined;
109
+ if (statusRaw !== undefined && statusRaw.length > 0) {
110
+ if (!FIX_PROPOSAL_STATUSES.has(statusRaw as FixProposalStatus)) {
111
+ c.status(statusFor('bad-input') as never);
112
+ return c.json(
113
+ toWireError(
114
+ { code: 'bad-input', message: `Unknown \`status\` value: ${statusRaw}` },
115
+ requestId,
116
+ ),
117
+ );
118
+ }
119
+ status = statusRaw as FixProposalStatus;
120
+ }
121
+
122
+ let tier: ProposedChange['tier'] | undefined;
123
+ if (tierRaw !== undefined && tierRaw.length > 0) {
124
+ if (!PROPOSAL_TIERS.has(tierRaw as ProposedChange['tier'])) {
125
+ c.status(statusFor('bad-input') as never);
126
+ return c.json(
127
+ toWireError(
128
+ { code: 'bad-input', message: `Unknown \`tier\` value: ${tierRaw}` },
129
+ requestId,
130
+ ),
131
+ );
132
+ }
133
+ tier = tierRaw as ProposedChange['tier'];
134
+ }
135
+
136
+ const scopeParsed = parseScopeParams(c.req.query(), { tenantId });
137
+ if (scopeParsed.kind === 'err') {
138
+ c.status(statusFor('scope-invalid') as never);
139
+ return c.json(
140
+ toWireError({ code: 'scope-invalid', message: scopeParsed.message }, requestId),
141
+ );
142
+ }
143
+
144
+ const page = await binding.listProposals({
145
+ tenantId,
146
+ supervisorId,
147
+ limit,
148
+ ...(cursorRaw !== undefined && cursorRaw.length > 0 && { cursor: cursorRaw as Cursor }),
149
+ ...(status !== undefined && { status }),
150
+ ...(agentIdRaw !== undefined && agentIdRaw.length > 0 && { agentId: agentIdRaw as AgentId }),
151
+ ...(tier !== undefined && { tier }),
152
+ ...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
153
+ ...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
154
+ });
155
+ return c.json({
156
+ data: page.data.map(serializeProposal),
157
+ hasMore: page.nextCursor !== undefined,
158
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
159
+ });
160
+ });
161
+
162
+ // ---------- GET /:proposalId ----------
163
+ r.get('/:proposalId', async (c) => {
164
+ const requestId = c.get('requestId');
165
+ const tenantId = c.get('tenantId') as TenantId;
166
+ const supervisorId = c.req.header('x-supervisor-id') as SupervisorId;
167
+ const proposalId = c.req.param('proposalId') as FixProposalId;
168
+
169
+ const proposal = await binding.getProposal({ tenantId, supervisorId, proposalId });
170
+ if (proposal === null) {
171
+ return proposalNotFound(c, requestId, proposalId);
172
+ }
173
+ return c.json(serializeProposal(proposal));
174
+ });
175
+
176
+ // ---------- POST / (draft) ----------
177
+ r.post('/', async (c) => {
178
+ const requestId = c.get('requestId');
179
+ const tenantId = c.get('tenantId') as TenantId;
180
+ const supervisorId = c.req.header('x-supervisor-id') as SupervisorId;
181
+
182
+ let body: unknown;
183
+ try {
184
+ body = await c.req.json();
185
+ } catch {
186
+ return badInput(c, requestId, 'Request body must be valid JSON');
187
+ }
188
+ const parsed = parseDraftBody(body);
189
+ if (parsed.kind === 'err') {
190
+ return badInput(c, requestId, parsed.message);
191
+ }
192
+
193
+ const outcome = await binding.draftProposal({
194
+ tenantId,
195
+ supervisorId,
196
+ agentId: parsed.value.agentId,
197
+ agentVersion: parsed.value.agentVersion,
198
+ tier: parsed.value.tier,
199
+ change: parsed.value.change,
200
+ patternRefs: parsed.value.patternRefs,
201
+ hypothesis: parsed.value.hypothesis,
202
+ proposerRuleId: parsed.value.proposerRuleId,
203
+ });
204
+ // Both `ok` and `dedup` return 201 — the caller ends up with a
205
+ // proposal id it can advance. Signal dedup via a header so
206
+ // consumers that care can distinguish (mirrors the
207
+ // X-Idempotent-Replay pattern from the idempotency middleware).
208
+ if (outcome.kind === 'dedup') {
209
+ c.header('X-Proposal-Deduped', 'true');
210
+ }
211
+ c.status(201);
212
+ return c.json(serializeProposal(outcome.proposal));
213
+ });
214
+
215
+ // ---------- POST /:proposalId/dry-run ----------
216
+ r.post('/:proposalId/dry-run', async (c) => {
217
+ const requestId = c.get('requestId');
218
+ const tenantId = c.get('tenantId') as TenantId;
219
+ const supervisorId = c.req.header('x-supervisor-id') as SupervisorId;
220
+ const proposalId = c.req.param('proposalId') as FixProposalId;
221
+
222
+ let body: unknown;
223
+ try {
224
+ body = await c.req.json();
225
+ } catch {
226
+ return badInput(c, requestId, 'Request body must be valid JSON');
227
+ }
228
+ const parsed = parseDryRunBody(body);
229
+ if (parsed.kind === 'err') {
230
+ return badInput(c, requestId, parsed.message);
231
+ }
232
+
233
+ const outcome = await binding.dryRunProposal({
234
+ tenantId,
235
+ supervisorId,
236
+ proposalId,
237
+ datasetId: parsed.value.datasetId,
238
+ datasetVersion: parsed.value.datasetVersion,
239
+ criterion: parsed.value.criterion,
240
+ });
241
+ if (outcome.kind === 'not-found') {
242
+ return proposalNotFound(c, requestId, proposalId);
243
+ }
244
+ if (outcome.kind === 'invalid-transition') {
245
+ return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
246
+ }
247
+ if (outcome.kind === 'runtime-error') {
248
+ return runtimeError(c, requestId, outcome.code, outcome.message);
249
+ }
250
+ return c.json({
251
+ proposal: serializeProposal(outcome.proposal),
252
+ passed: outcome.passed,
253
+ });
254
+ });
255
+
256
+ // ---------- POST /:proposalId/submit-review ----------
257
+ r.post('/:proposalId/submit-review', async (c) => {
258
+ const requestId = c.get('requestId');
259
+ const tenantId = c.get('tenantId') as TenantId;
260
+ const supervisorId = c.req.header('x-supervisor-id') as SupervisorId;
261
+ const proposalId = c.req.param('proposalId') as FixProposalId;
262
+
263
+ // Body is optional — every field on submit-review is an override.
264
+ let body: unknown = {};
265
+ try {
266
+ const raw = await c.req.text();
267
+ if (raw.length > 0) body = JSON.parse(raw);
268
+ } catch {
269
+ return badInput(c, requestId, 'Request body must be valid JSON');
270
+ }
271
+ const parsed = parseSubmitReviewBody(body);
272
+ if (parsed.kind === 'err') {
273
+ return badInput(c, requestId, parsed.message);
274
+ }
275
+
276
+ const outcome = await binding.submitReview({
277
+ tenantId,
278
+ supervisorId,
279
+ proposalId,
280
+ ...(parsed.value.requiredRole !== undefined && { requiredRole: parsed.value.requiredRole }),
281
+ ...(parsed.value.expiresAt !== undefined && { expiresAt: parsed.value.expiresAt }),
282
+ });
283
+ if (outcome.kind === 'not-found') {
284
+ return proposalNotFound(c, requestId, proposalId);
285
+ }
286
+ if (outcome.kind === 'invalid-transition') {
287
+ return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
288
+ }
289
+ if (outcome.kind === 'ground-layer-violation') {
290
+ c.status(statusFor('ground-layer-violation') as never);
291
+ return c.json(
292
+ toWireError(
293
+ {
294
+ code: 'ground-layer-violation',
295
+ message: `Proposal ${outcome.proposalId as unknown as string} violated ground guardrail ${outcome.guardrailId}: ${outcome.reason}`,
296
+ proposalId: outcome.proposalId as unknown as string,
297
+ guardrailId: outcome.guardrailId,
298
+ reason: outcome.reason,
299
+ },
300
+ requestId,
301
+ ),
302
+ );
303
+ }
304
+ if (outcome.kind === 'runtime-error') {
305
+ return runtimeError(c, requestId, outcome.code, outcome.message);
306
+ }
307
+ return c.json({
308
+ proposal: serializeProposal(outcome.proposal),
309
+ approvalId: outcome.approvalId as unknown as string,
310
+ metaFix: outcome.metaFix,
311
+ });
312
+ });
313
+
314
+ // ---------- POST /:proposalId/apply ----------
315
+ r.post('/:proposalId/apply', async (c) => {
316
+ const requestId = c.get('requestId');
317
+ const tenantId = c.get('tenantId') as TenantId;
318
+ const supervisorId = c.req.header('x-supervisor-id') as SupervisorId;
319
+ const proposalId = c.req.param('proposalId') as FixProposalId;
320
+
321
+ let body: unknown = {};
322
+ try {
323
+ const raw = await c.req.text();
324
+ if (raw.length > 0) body = JSON.parse(raw);
325
+ } catch {
326
+ return badInput(c, requestId, 'Request body must be valid JSON');
327
+ }
328
+ const parsed = parseApplyBody(body);
329
+ if (parsed.kind === 'err') {
330
+ return badInput(c, requestId, parsed.message);
331
+ }
332
+
333
+ const outcome = await binding.applyProposal({
334
+ tenantId,
335
+ supervisorId,
336
+ proposalId,
337
+ ...(parsed.value.newVersion !== undefined && { newVersion: parsed.value.newVersion }),
338
+ });
339
+ if (outcome.kind === 'not-found') {
340
+ return proposalNotFound(c, requestId, proposalId);
341
+ }
342
+ if (outcome.kind === 'invalid-transition') {
343
+ return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
344
+ }
345
+ if (outcome.kind === 'runtime-error') {
346
+ return runtimeError(c, requestId, outcome.code, outcome.message);
347
+ }
348
+ return c.json({
349
+ proposalId: outcome.proposalId as unknown as string,
350
+ appliedVersion: outcome.appliedVersion,
351
+ appliedAt: outcome.appliedAt as unknown as string,
352
+ });
353
+ });
354
+
355
+ // ---------- POST /:proposalId/rollback ----------
356
+ r.post('/:proposalId/rollback', async (c) => {
357
+ const requestId = c.get('requestId');
358
+ const tenantId = c.get('tenantId') as TenantId;
359
+ const supervisorId = c.req.header('x-supervisor-id') as SupervisorId;
360
+ const proposalId = c.req.param('proposalId') as FixProposalId;
361
+
362
+ let body: unknown;
363
+ try {
364
+ body = await c.req.json();
365
+ } catch {
366
+ return badInput(c, requestId, 'Request body must be valid JSON');
367
+ }
368
+ const parsed = parseReasonBody(body);
369
+ if (parsed.kind === 'err') {
370
+ return badInput(c, requestId, parsed.message);
371
+ }
372
+
373
+ const outcome = await binding.rollbackProposal({
374
+ tenantId,
375
+ supervisorId,
376
+ proposalId,
377
+ reason: parsed.value.reason,
378
+ });
379
+ if (outcome.kind === 'not-found') {
380
+ return proposalNotFound(c, requestId, proposalId);
381
+ }
382
+ if (outcome.kind === 'invalid-transition') {
383
+ return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
384
+ }
385
+ if (outcome.kind === 'runtime-error') {
386
+ return runtimeError(c, requestId, outcome.code, outcome.message);
387
+ }
388
+ return c.json({
389
+ proposalId: outcome.proposalId as unknown as string,
390
+ rolledBackAt: outcome.rolledBackAt as unknown as string,
391
+ });
392
+ });
393
+
394
+ // ---------- POST /:proposalId/withdraw ----------
395
+ r.post('/:proposalId/withdraw', async (c) => {
396
+ const requestId = c.get('requestId');
397
+ const tenantId = c.get('tenantId') as TenantId;
398
+ const supervisorId = c.req.header('x-supervisor-id') as SupervisorId;
399
+ const proposalId = c.req.param('proposalId') as FixProposalId;
400
+
401
+ let body: unknown;
402
+ try {
403
+ body = await c.req.json();
404
+ } catch {
405
+ return badInput(c, requestId, 'Request body must be valid JSON');
406
+ }
407
+ const parsed = parseReasonBody(body);
408
+ if (parsed.kind === 'err') {
409
+ return badInput(c, requestId, parsed.message);
410
+ }
411
+
412
+ const outcome = await binding.withdrawProposal({
413
+ tenantId,
414
+ supervisorId,
415
+ proposalId,
416
+ reason: parsed.value.reason,
417
+ });
418
+ if (outcome.kind === 'not-found') {
419
+ return proposalNotFound(c, requestId, proposalId);
420
+ }
421
+ if (outcome.kind === 'invalid-transition') {
422
+ return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
423
+ }
424
+ if (outcome.kind === 'runtime-error') {
425
+ return runtimeError(c, requestId, outcome.code, outcome.message);
426
+ }
427
+ return c.json(serializeProposal(outcome.proposal));
428
+ });
429
+
430
+ return r;
431
+ }
432
+
433
+ // -------------------- serialization --------------------
434
+
435
+ function serializeProposal(p: FixProposal): Record<string, unknown> {
436
+ return {
437
+ id: p.id as unknown as string,
438
+ tenantId: p.tenantId as unknown as string,
439
+ supervisorId: p.supervisorId as unknown as string,
440
+ agentId: p.agentId as unknown as string,
441
+ agentVersion: p.agentVersion,
442
+ tier: p.tier,
443
+ change: p.change,
444
+ patternRefs: p.patternRefs,
445
+ hypothesis: p.hypothesis,
446
+ proposerRuleId: p.proposerRuleId,
447
+ status: p.status,
448
+ fingerprint: p.fingerprint,
449
+ ...(p.resolutionReason !== undefined && { resolutionReason: p.resolutionReason }),
450
+ ...(p.reviewApprovalId !== undefined && {
451
+ reviewApprovalId: p.reviewApprovalId as unknown as string,
452
+ }),
453
+ ...(p.appliedVersion !== undefined && { appliedVersion: p.appliedVersion }),
454
+ ...(p.appliedAt !== undefined && { appliedAt: p.appliedAt as unknown as string }),
455
+ ...(p.rolledBackAt !== undefined && { rolledBackAt: p.rolledBackAt as unknown as string }),
456
+ createdAt: p.createdAt as unknown as string,
457
+ updatedAt: p.updatedAt as unknown as string,
458
+ ...(p.resolvedAt !== undefined && { resolvedAt: p.resolvedAt as unknown as string }),
459
+ };
460
+ }
461
+
462
+ // -------------------- error helpers --------------------
463
+
464
+ type Ctx = Context<AppEnv>;
465
+
466
+ function badInput(c: Ctx, requestId: string, message: string): Response {
467
+ c.status(statusFor('bad-input') as never);
468
+ return c.json(toWireError({ code: 'bad-input', message }, requestId));
469
+ }
470
+
471
+ function proposalNotFound(c: Ctx, requestId: string, proposalId: FixProposalId): Response {
472
+ c.status(statusFor('proposal-not-found') as never);
473
+ return c.json(
474
+ toWireError(
475
+ {
476
+ code: 'proposal-not-found',
477
+ message: `No proposal with id "${proposalId as unknown as string}"`,
478
+ proposalId: proposalId as unknown as string,
479
+ },
480
+ requestId,
481
+ ),
482
+ );
483
+ }
484
+
485
+ function invalidTransition(
486
+ c: Ctx,
487
+ requestId: string,
488
+ proposalId: FixProposalId,
489
+ from: FixProposalStatus,
490
+ to: FixProposalStatus,
491
+ ): Response {
492
+ c.status(statusFor('proposal-invalid-state-transition') as never);
493
+ return c.json(
494
+ toWireError(
495
+ {
496
+ code: 'proposal-invalid-state-transition',
497
+ message: `Cannot transition proposal ${proposalId as unknown as string} from ${from} to ${to}`,
498
+ proposalId: proposalId as unknown as string,
499
+ from,
500
+ to,
501
+ },
502
+ requestId,
503
+ ),
504
+ );
505
+ }
506
+
507
+ function runtimeError(c: Ctx, requestId: string, code: string, message: string): Response {
508
+ c.status(statusFor(code) as never);
509
+ return c.json(toWireError({ code, message }, requestId));
510
+ }
511
+
512
+ // -------------------- request parsing --------------------
513
+
514
+ type Parsed<T> =
515
+ | { readonly kind: 'ok'; readonly value: T }
516
+ | { readonly kind: 'err'; readonly message: string };
517
+
518
+ interface DraftPayload {
519
+ readonly agentId: AgentId;
520
+ readonly agentVersion: string;
521
+ readonly tier: ProposedChange['tier'];
522
+ readonly change: ProposedChange['change'];
523
+ readonly patternRefs: readonly PatternRef[];
524
+ readonly hypothesis: string;
525
+ readonly proposerRuleId: string;
526
+ }
527
+
528
+ function parseDraftBody(body: unknown): Parsed<DraftPayload> {
529
+ if (body === null || typeof body !== 'object') {
530
+ return { kind: 'err', message: 'Request body must be an object' };
531
+ }
532
+ const b = body as Record<string, unknown>;
533
+ const agentId = b.agentId;
534
+ if (typeof agentId !== 'string' || agentId.length === 0) {
535
+ return { kind: 'err', message: 'Field `agentId` must be a non-empty string' };
536
+ }
537
+ const agentVersion = b.agentVersion;
538
+ if (typeof agentVersion !== 'string' || agentVersion.length === 0) {
539
+ return { kind: 'err', message: 'Field `agentVersion` must be a non-empty string' };
540
+ }
541
+ const tier = b.tier;
542
+ if (typeof tier !== 'string' || !PROPOSAL_TIERS.has(tier as ProposedChange['tier'])) {
543
+ return {
544
+ kind: 'err',
545
+ message: 'Field `tier` must be one of "prompt", "retrieval", "tool-config"',
546
+ };
547
+ }
548
+ const change = b.change;
549
+ if (change === null || typeof change !== 'object') {
550
+ return { kind: 'err', message: 'Field `change` must be an object' };
551
+ }
552
+ const patternRefs = b.patternRefs;
553
+ if (!Array.isArray(patternRefs)) {
554
+ return { kind: 'err', message: 'Field `patternRefs` must be an array' };
555
+ }
556
+ const hypothesis = b.hypothesis;
557
+ if (typeof hypothesis !== 'string' || hypothesis.length === 0) {
558
+ return { kind: 'err', message: 'Field `hypothesis` must be a non-empty string' };
559
+ }
560
+ const proposerRuleId = b.proposerRuleId;
561
+ if (typeof proposerRuleId !== 'string' || proposerRuleId.length === 0) {
562
+ return { kind: 'err', message: 'Field `proposerRuleId` must be a non-empty string' };
563
+ }
564
+ return {
565
+ kind: 'ok',
566
+ value: {
567
+ agentId: agentId as AgentId,
568
+ agentVersion,
569
+ tier: tier as ProposedChange['tier'],
570
+ change: change as ProposedChange['change'],
571
+ patternRefs: patternRefs as readonly PatternRef[],
572
+ hypothesis,
573
+ proposerRuleId,
574
+ },
575
+ };
576
+ }
577
+
578
+ interface DryRunPayload {
579
+ readonly datasetId: string;
580
+ readonly datasetVersion: string;
581
+ readonly criterion: PassCriterion;
582
+ }
583
+
584
+ function parseDryRunBody(body: unknown): Parsed<DryRunPayload> {
585
+ if (body === null || typeof body !== 'object') {
586
+ return { kind: 'err', message: 'Request body must be an object' };
587
+ }
588
+ const b = body as Record<string, unknown>;
589
+ const datasetId = b.datasetId;
590
+ if (typeof datasetId !== 'string' || datasetId.length === 0) {
591
+ return { kind: 'err', message: 'Field `datasetId` must be a non-empty string' };
592
+ }
593
+ const datasetVersion = b.datasetVersion;
594
+ if (typeof datasetVersion !== 'string' || datasetVersion.length === 0) {
595
+ return { kind: 'err', message: 'Field `datasetVersion` must be a non-empty string' };
596
+ }
597
+ const rawCriterion = b.criterion;
598
+ if (rawCriterion === null || typeof rawCriterion !== 'object') {
599
+ return { kind: 'err', message: 'Field `criterion` must be an object' };
600
+ }
601
+ const cr = rawCriterion as Record<string, unknown>;
602
+ if (cr.kind === 'min-pass-rate') {
603
+ const minPassRate = cr.minPassRate;
604
+ if (typeof minPassRate !== 'number' || !Number.isFinite(minPassRate)) {
605
+ return {
606
+ kind: 'err',
607
+ message: 'Field `criterion.minPassRate` must be a finite number for kind "min-pass-rate"',
608
+ };
609
+ }
610
+ return {
611
+ kind: 'ok',
612
+ value: { datasetId, datasetVersion, criterion: { kind: 'min-pass-rate', minPassRate } },
613
+ };
614
+ }
615
+ if (cr.kind === 'strict-improvement') {
616
+ const baseline = cr.baselinePassRate;
617
+ const minDelta = cr.minDelta;
618
+ if (typeof baseline !== 'number' || !Number.isFinite(baseline)) {
619
+ return {
620
+ kind: 'err',
621
+ message:
622
+ 'Field `criterion.baselinePassRate` must be a finite number for kind "strict-improvement"',
623
+ };
624
+ }
625
+ if (typeof minDelta !== 'number' || !Number.isFinite(minDelta)) {
626
+ return {
627
+ kind: 'err',
628
+ message: 'Field `criterion.minDelta` must be a finite number for kind "strict-improvement"',
629
+ };
630
+ }
631
+ return {
632
+ kind: 'ok',
633
+ value: {
634
+ datasetId,
635
+ datasetVersion,
636
+ criterion: { kind: 'strict-improvement', baselinePassRate: baseline, minDelta },
637
+ },
638
+ };
639
+ }
640
+ return {
641
+ kind: 'err',
642
+ message: 'Field `criterion.kind` must be "min-pass-rate" or "strict-improvement"',
643
+ };
644
+ }
645
+
646
+ interface SubmitReviewPayload {
647
+ readonly requiredRole?: 'standard' | 'senior' | 'admin';
648
+ readonly expiresAt?: Timestamp;
649
+ }
650
+
651
+ function parseSubmitReviewBody(body: unknown): Parsed<SubmitReviewPayload> {
652
+ if (body === null || typeof body !== 'object') {
653
+ return { kind: 'err', message: 'Request body must be an object' };
654
+ }
655
+ const b = body as Record<string, unknown>;
656
+ const out: {
657
+ requiredRole?: 'standard' | 'senior' | 'admin';
658
+ expiresAt?: Timestamp;
659
+ } = {};
660
+ const requiredRole = b.requiredRole;
661
+ if (requiredRole !== undefined) {
662
+ if (
663
+ typeof requiredRole !== 'string' ||
664
+ !REVIEWER_ROLES.has(requiredRole as 'standard' | 'senior' | 'admin')
665
+ ) {
666
+ return {
667
+ kind: 'err',
668
+ message: 'Field `requiredRole` must be one of "standard", "senior", "admin"',
669
+ };
670
+ }
671
+ out.requiredRole = requiredRole as 'standard' | 'senior' | 'admin';
672
+ }
673
+ const expiresAt = b.expiresAt;
674
+ if (expiresAt !== undefined) {
675
+ if (typeof expiresAt !== 'string' || Number.isNaN(new Date(expiresAt).getTime())) {
676
+ return { kind: 'err', message: 'Field `expiresAt` must be an ISO date string' };
677
+ }
678
+ out.expiresAt = expiresAt as Timestamp;
679
+ }
680
+ return { kind: 'ok', value: out };
681
+ }
682
+
683
+ interface ApplyPayload {
684
+ readonly newVersion?: string;
685
+ }
686
+
687
+ function parseApplyBody(body: unknown): Parsed<ApplyPayload> {
688
+ if (body === null || typeof body !== 'object') {
689
+ return { kind: 'err', message: 'Request body must be an object' };
690
+ }
691
+ const b = body as Record<string, unknown>;
692
+ const newVersion = b.newVersion;
693
+ if (newVersion !== undefined) {
694
+ if (typeof newVersion !== 'string' || newVersion.length === 0) {
695
+ return {
696
+ kind: 'err',
697
+ message: 'Field `newVersion` must be a non-empty string when present',
698
+ };
699
+ }
700
+ return { kind: 'ok', value: { newVersion } };
701
+ }
702
+ return { kind: 'ok', value: {} };
703
+ }
704
+
705
+ interface ReasonPayload {
706
+ readonly reason: string;
707
+ }
708
+
709
+ function parseReasonBody(body: unknown): Parsed<ReasonPayload> {
710
+ if (body === null || typeof body !== 'object') {
711
+ return { kind: 'err', message: 'Request body must be an object' };
712
+ }
713
+ const b = body as Record<string, unknown>;
714
+ const reason = b.reason;
715
+ if (typeof reason !== 'string' || reason.length === 0) {
716
+ return { kind: 'err', message: 'Field `reason` must be a non-empty string' };
717
+ }
718
+ return { kind: 'ok', value: { reason } };
719
+ }