@kindgi/api 0.1.4-rc.5 → 0.1.5-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. package/dist/agent-binding.d.ts +13 -0
  2. package/dist/agent-binding.d.ts.map +1 -1
  3. package/dist/agent-pins.d.ts.map +1 -1
  4. package/dist/agent-pins.js +18 -2
  5. package/dist/agent-pins.js.map +1 -1
  6. package/dist/app.d.ts +110 -17
  7. package/dist/app.d.ts.map +1 -1
  8. package/dist/app.js +163 -35
  9. package/dist/app.js.map +1 -1
  10. package/dist/block-publish.d.ts +56 -0
  11. package/dist/block-publish.d.ts.map +1 -0
  12. package/dist/block-publish.js +132 -0
  13. package/dist/block-publish.js.map +1 -0
  14. package/dist/caller.d.ts +24 -0
  15. package/dist/caller.d.ts.map +1 -0
  16. package/dist/caller.js +47 -0
  17. package/dist/caller.js.map +1 -0
  18. package/dist/capability-binding.d.ts +11 -0
  19. package/dist/capability-binding.d.ts.map +1 -1
  20. package/dist/derive-agent-version.d.ts +7 -0
  21. package/dist/derive-agent-version.d.ts.map +1 -1
  22. package/dist/derive-agent-version.js +4 -0
  23. package/dist/derive-agent-version.js.map +1 -1
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +73 -7
  26. package/dist/errors.js.map +1 -1
  27. package/dist/eval-case-binding.d.ts +16 -4
  28. package/dist/eval-case-binding.d.ts.map +1 -1
  29. package/dist/eval-run-binding.d.ts +31 -0
  30. package/dist/eval-run-binding.d.ts.map +1 -1
  31. package/dist/eval-run-dispatcher.d.ts +7 -0
  32. package/dist/eval-run-dispatcher.d.ts.map +1 -1
  33. package/dist/eval-run-dispatcher.js.map +1 -1
  34. package/dist/eval-sample.d.ts +11 -0
  35. package/dist/eval-sample.d.ts.map +1 -0
  36. package/dist/eval-sample.js +34 -0
  37. package/dist/eval-sample.js.map +1 -0
  38. package/dist/eval-suite-binding.d.ts +13 -0
  39. package/dist/eval-suite-binding.d.ts.map +1 -1
  40. package/dist/eval-suite-binding.js.map +1 -1
  41. package/dist/flow-binding.d.ts +18 -0
  42. package/dist/flow-binding.d.ts.map +1 -1
  43. package/dist/flow-pins.d.ts.map +1 -1
  44. package/dist/flow-pins.js +18 -2
  45. package/dist/flow-pins.js.map +1 -1
  46. package/dist/gate.d.ts.map +1 -1
  47. package/dist/gate.js +25 -0
  48. package/dist/gate.js.map +1 -1
  49. package/dist/handler-binding.d.ts +32 -0
  50. package/dist/handler-binding.d.ts.map +1 -1
  51. package/dist/hitl-binding.d.ts +23 -0
  52. package/dist/hitl-binding.d.ts.map +1 -1
  53. package/dist/identity-directory-binding.d.ts +82 -4
  54. package/dist/identity-directory-binding.d.ts.map +1 -1
  55. package/dist/identity-provider-binding.d.ts +197 -17
  56. package/dist/identity-provider-binding.d.ts.map +1 -1
  57. package/dist/improvement-pass-binding.d.ts +196 -0
  58. package/dist/improvement-pass-binding.d.ts.map +1 -0
  59. package/dist/improvement-pass-binding.js +9 -0
  60. package/dist/improvement-pass-binding.js.map +1 -0
  61. package/dist/index.d.ts +35 -17
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +11 -3
  64. package/dist/index.js.map +1 -1
  65. package/dist/judged-dispatcher.d.ts +25 -4
  66. package/dist/judged-dispatcher.d.ts.map +1 -1
  67. package/dist/judged-dispatcher.js +43 -6
  68. package/dist/judged-dispatcher.js.map +1 -1
  69. package/dist/judgment-binding.d.ts +25 -1
  70. package/dist/judgment-binding.d.ts.map +1 -1
  71. package/dist/mcp-endpoint-binding.d.ts +7 -0
  72. package/dist/mcp-endpoint-binding.d.ts.map +1 -1
  73. package/dist/memory-binding.d.ts +124 -17
  74. package/dist/memory-binding.d.ts.map +1 -1
  75. package/dist/memory-erasure-binding.d.ts +145 -0
  76. package/dist/memory-erasure-binding.d.ts.map +1 -0
  77. package/dist/memory-erasure-binding.js +4 -0
  78. package/dist/memory-erasure-binding.js.map +1 -0
  79. package/dist/middleware/auth.d.ts +66 -13
  80. package/dist/middleware/auth.d.ts.map +1 -1
  81. package/dist/middleware/auth.js +150 -50
  82. package/dist/middleware/auth.js.map +1 -1
  83. package/dist/middleware/authorize.d.ts +6 -0
  84. package/dist/middleware/authorize.d.ts.map +1 -1
  85. package/dist/middleware/authorize.js +113 -4
  86. package/dist/middleware/authorize.js.map +1 -1
  87. package/dist/middleware/error-mapper.d.ts +5 -0
  88. package/dist/middleware/error-mapper.d.ts.map +1 -1
  89. package/dist/middleware/error-mapper.js +14 -1
  90. package/dist/middleware/error-mapper.js.map +1 -1
  91. package/dist/middleware/idempotency.d.ts +70 -5
  92. package/dist/middleware/idempotency.d.ts.map +1 -1
  93. package/dist/middleware/idempotency.js +174 -41
  94. package/dist/middleware/idempotency.js.map +1 -1
  95. package/dist/middleware/key-project.d.ts +17 -0
  96. package/dist/middleware/key-project.d.ts.map +1 -0
  97. package/dist/middleware/key-project.js +75 -0
  98. package/dist/middleware/key-project.js.map +1 -0
  99. package/dist/middleware/principal.d.ts.map +1 -1
  100. package/dist/middleware/principal.js +9 -5
  101. package/dist/middleware/principal.js.map +1 -1
  102. package/dist/middleware/project-ref.d.ts.map +1 -1
  103. package/dist/middleware/project-ref.js +3 -0
  104. package/dist/middleware/project-ref.js.map +1 -1
  105. package/dist/openapi/generate.d.ts.map +1 -1
  106. package/dist/openapi/generate.js +5 -2
  107. package/dist/openapi/generate.js.map +1 -1
  108. package/dist/openapi/operations.d.ts.map +1 -1
  109. package/dist/openapi/operations.js +918 -139
  110. package/dist/openapi/operations.js.map +1 -1
  111. package/dist/openapi/schemas.d.ts +92 -13
  112. package/dist/openapi/schemas.d.ts.map +1 -1
  113. package/dist/openapi/schemas.js +2122 -370
  114. package/dist/openapi/schemas.js.map +1 -1
  115. package/dist/person-grants-binding.d.ts +77 -0
  116. package/dist/person-grants-binding.d.ts.map +1 -0
  117. package/dist/person-grants-binding.js +4 -0
  118. package/dist/person-grants-binding.js.map +1 -0
  119. package/dist/proposal-service.d.ts +121 -0
  120. package/dist/proposal-service.d.ts.map +1 -0
  121. package/dist/proposal-service.js +447 -0
  122. package/dist/proposal-service.js.map +1 -0
  123. package/dist/proposal-status.d.ts +60 -0
  124. package/dist/proposal-status.d.ts.map +1 -0
  125. package/dist/proposal-status.js +109 -0
  126. package/dist/proposal-status.js.map +1 -0
  127. package/dist/provider-binding.d.ts +10 -0
  128. package/dist/provider-binding.d.ts.map +1 -1
  129. package/dist/publish-refused.d.ts +18 -3
  130. package/dist/publish-refused.d.ts.map +1 -1
  131. package/dist/publish-refused.js +18 -3
  132. package/dist/publish-refused.js.map +1 -1
  133. package/dist/routes/adapters.d.ts +2 -1
  134. package/dist/routes/adapters.d.ts.map +1 -1
  135. package/dist/routes/adapters.js +3 -1
  136. package/dist/routes/adapters.js.map +1 -1
  137. package/dist/routes/agent-releases.d.ts +55 -3
  138. package/dist/routes/agent-releases.d.ts.map +1 -1
  139. package/dist/routes/agent-releases.js +85 -55
  140. package/dist/routes/agent-releases.js.map +1 -1
  141. package/dist/routes/agents.d.ts +12 -1
  142. package/dist/routes/agents.d.ts.map +1 -1
  143. package/dist/routes/agents.js +100 -2
  144. package/dist/routes/agents.js.map +1 -1
  145. package/dist/routes/approvals.d.ts +15 -3
  146. package/dist/routes/approvals.d.ts.map +1 -1
  147. package/dist/routes/approvals.js +133 -122
  148. package/dist/routes/approvals.js.map +1 -1
  149. package/dist/routes/artifacts.d.ts +25 -3
  150. package/dist/routes/artifacts.d.ts.map +1 -1
  151. package/dist/routes/artifacts.js +116 -7
  152. package/dist/routes/artifacts.js.map +1 -1
  153. package/dist/routes/auth.d.ts +25 -1
  154. package/dist/routes/auth.d.ts.map +1 -1
  155. package/dist/routes/auth.js +655 -281
  156. package/dist/routes/auth.js.map +1 -1
  157. package/dist/routes/blocks.d.ts.map +1 -1
  158. package/dist/routes/blocks.js +2 -42
  159. package/dist/routes/blocks.js.map +1 -1
  160. package/dist/routes/capabilities.d.ts +2 -1
  161. package/dist/routes/capabilities.d.ts.map +1 -1
  162. package/dist/routes/capabilities.js +6 -1
  163. package/dist/routes/capabilities.js.map +1 -1
  164. package/dist/routes/compliance.d.ts +9 -10
  165. package/dist/routes/compliance.d.ts.map +1 -1
  166. package/dist/routes/compliance.js +42 -61
  167. package/dist/routes/compliance.js.map +1 -1
  168. package/dist/routes/conversations.d.ts +8 -1
  169. package/dist/routes/conversations.d.ts.map +1 -1
  170. package/dist/routes/conversations.js +87 -8
  171. package/dist/routes/conversations.js.map +1 -1
  172. package/dist/routes/cost.d.ts +7 -1
  173. package/dist/routes/cost.d.ts.map +1 -1
  174. package/dist/routes/cost.js +22 -3
  175. package/dist/routes/cost.js.map +1 -1
  176. package/dist/routes/denied.d.ts +11 -0
  177. package/dist/routes/denied.d.ts.map +1 -0
  178. package/dist/routes/denied.js +17 -0
  179. package/dist/routes/denied.js.map +1 -0
  180. package/dist/routes/deployments.d.ts +2 -1
  181. package/dist/routes/deployments.d.ts.map +1 -1
  182. package/dist/routes/deployments.js +44 -12
  183. package/dist/routes/deployments.js.map +1 -1
  184. package/dist/routes/eval-comparison.d.ts.map +1 -1
  185. package/dist/routes/eval-comparison.js +69 -1
  186. package/dist/routes/eval-comparison.js.map +1 -1
  187. package/dist/routes/eval-overrides.d.ts +18 -0
  188. package/dist/routes/eval-overrides.d.ts.map +1 -0
  189. package/dist/routes/eval-overrides.js +81 -0
  190. package/dist/routes/eval-overrides.js.map +1 -0
  191. package/dist/routes/eval-runs.d.ts +10 -1
  192. package/dist/routes/eval-runs.d.ts.map +1 -1
  193. package/dist/routes/eval-runs.js +63 -7
  194. package/dist/routes/eval-runs.js.map +1 -1
  195. package/dist/routes/eval-suites.d.ts.map +1 -1
  196. package/dist/routes/eval-suites.js +20 -1
  197. package/dist/routes/eval-suites.js.map +1 -1
  198. package/dist/routes/event-triggers.d.ts +5 -1
  199. package/dist/routes/event-triggers.d.ts.map +1 -1
  200. package/dist/routes/event-triggers.js +26 -3
  201. package/dist/routes/event-triggers.js.map +1 -1
  202. package/dist/routes/export-signing-keys.d.ts +12 -0
  203. package/dist/routes/export-signing-keys.d.ts.map +1 -0
  204. package/dist/routes/export-signing-keys.js +24 -0
  205. package/dist/routes/export-signing-keys.js.map +1 -0
  206. package/dist/routes/flows.d.ts.map +1 -1
  207. package/dist/routes/flows.js +9 -1
  208. package/dist/routes/flows.js.map +1 -1
  209. package/dist/routes/gate-policies.d.ts +4 -1
  210. package/dist/routes/gate-policies.d.ts.map +1 -1
  211. package/dist/routes/gate-policies.js +29 -5
  212. package/dist/routes/gate-policies.js.map +1 -1
  213. package/dist/routes/guardrails.d.ts +16 -14
  214. package/dist/routes/guardrails.d.ts.map +1 -1
  215. package/dist/routes/guardrails.js +39 -3
  216. package/dist/routes/guardrails.js.map +1 -1
  217. package/dist/routes/identity.d.ts +20 -4
  218. package/dist/routes/identity.d.ts.map +1 -1
  219. package/dist/routes/identity.js +246 -6
  220. package/dist/routes/identity.js.map +1 -1
  221. package/dist/routes/improvement-passes.d.ts +52 -0
  222. package/dist/routes/improvement-passes.d.ts.map +1 -0
  223. package/dist/routes/improvement-passes.js +449 -0
  224. package/dist/routes/improvement-passes.js.map +1 -0
  225. package/dist/routes/judged-suites.d.ts +50 -0
  226. package/dist/routes/judged-suites.d.ts.map +1 -1
  227. package/dist/routes/judged-suites.js +66 -27
  228. package/dist/routes/judged-suites.js.map +1 -1
  229. package/dist/routes/judgment-context.d.ts +18 -2
  230. package/dist/routes/judgment-context.d.ts.map +1 -1
  231. package/dist/routes/judgment-context.js +63 -5
  232. package/dist/routes/judgment-context.js.map +1 -1
  233. package/dist/routes/judgment-flow-context.d.ts.map +1 -1
  234. package/dist/routes/judgment-flow-context.js +14 -2
  235. package/dist/routes/judgment-flow-context.js.map +1 -1
  236. package/dist/routes/judgments.d.ts.map +1 -1
  237. package/dist/routes/judgments.js +8 -1
  238. package/dist/routes/judgments.js.map +1 -1
  239. package/dist/routes/mcp.d.ts.map +1 -1
  240. package/dist/routes/mcp.js +26 -1
  241. package/dist/routes/mcp.js.map +1 -1
  242. package/dist/routes/memory-access.d.ts +43 -0
  243. package/dist/routes/memory-access.d.ts.map +1 -0
  244. package/dist/routes/memory-access.js +129 -0
  245. package/dist/routes/memory-access.js.map +1 -0
  246. package/dist/routes/memory-erasures.d.ts +25 -0
  247. package/dist/routes/memory-erasures.d.ts.map +1 -0
  248. package/dist/routes/memory-erasures.js +214 -0
  249. package/dist/routes/memory-erasures.js.map +1 -0
  250. package/dist/routes/memory-parse.d.ts +38 -0
  251. package/dist/routes/memory-parse.d.ts.map +1 -0
  252. package/dist/routes/memory-parse.js +199 -0
  253. package/dist/routes/memory-parse.js.map +1 -0
  254. package/dist/routes/memory.d.ts +9 -4
  255. package/dist/routes/memory.d.ts.map +1 -1
  256. package/dist/routes/memory.js +226 -234
  257. package/dist/routes/memory.js.map +1 -1
  258. package/dist/routes/observations.d.ts +4 -1
  259. package/dist/routes/observations.d.ts.map +1 -1
  260. package/dist/routes/observations.js +8 -2
  261. package/dist/routes/observations.js.map +1 -1
  262. package/dist/routes/pagination.d.ts +7 -0
  263. package/dist/routes/pagination.d.ts.map +1 -1
  264. package/dist/routes/pagination.js +10 -0
  265. package/dist/routes/pagination.js.map +1 -1
  266. package/dist/routes/policies.d.ts +2 -1
  267. package/dist/routes/policies.d.ts.map +1 -1
  268. package/dist/routes/policies.js +3 -1
  269. package/dist/routes/policies.js.map +1 -1
  270. package/dist/routes/project-mismatch.d.ts +22 -0
  271. package/dist/routes/project-mismatch.d.ts.map +1 -0
  272. package/dist/routes/project-mismatch.js +34 -0
  273. package/dist/routes/project-mismatch.js.map +1 -0
  274. package/dist/routes/projects.d.ts +15 -4
  275. package/dist/routes/projects.d.ts.map +1 -1
  276. package/dist/routes/projects.js +100 -9
  277. package/dist/routes/projects.js.map +1 -1
  278. package/dist/routes/proposals.d.ts +25 -17
  279. package/dist/routes/proposals.d.ts.map +1 -1
  280. package/dist/routes/proposals.js +340 -507
  281. package/dist/routes/proposals.js.map +1 -1
  282. package/dist/routes/provenance.d.ts +17 -3
  283. package/dist/routes/provenance.d.ts.map +1 -1
  284. package/dist/routes/provenance.js +79 -103
  285. package/dist/routes/provenance.js.map +1 -1
  286. package/dist/routes/providers.d.ts +17 -1
  287. package/dist/routes/providers.d.ts.map +1 -1
  288. package/dist/routes/providers.js +188 -8
  289. package/dist/routes/providers.js.map +1 -1
  290. package/dist/routes/public-run-tokens.d.ts.map +1 -1
  291. package/dist/routes/public-run-tokens.js +3 -0
  292. package/dist/routes/public-run-tokens.js.map +1 -1
  293. package/dist/routes/runs.d.ts +10 -0
  294. package/dist/routes/runs.d.ts.map +1 -1
  295. package/dist/routes/runs.js +92 -42
  296. package/dist/routes/runs.js.map +1 -1
  297. package/dist/routes/schedules.d.ts +21 -13
  298. package/dist/routes/schedules.d.ts.map +1 -1
  299. package/dist/routes/schedules.js +416 -55
  300. package/dist/routes/schedules.js.map +1 -1
  301. package/dist/routes/segments.d.ts +2 -0
  302. package/dist/routes/segments.d.ts.map +1 -1
  303. package/dist/routes/segments.js +5 -0
  304. package/dist/routes/segments.js.map +1 -1
  305. package/dist/routes/service-accounts.d.ts +17 -0
  306. package/dist/routes/service-accounts.d.ts.map +1 -0
  307. package/dist/routes/service-accounts.js +212 -0
  308. package/dist/routes/service-accounts.js.map +1 -0
  309. package/dist/routes/sign-in-options.d.ts +50 -0
  310. package/dist/routes/sign-in-options.d.ts.map +1 -0
  311. package/dist/routes/sign-in-options.js +98 -0
  312. package/dist/routes/sign-in-options.js.map +1 -0
  313. package/dist/routes/signing-keys.d.ts +2 -1
  314. package/dist/routes/signing-keys.d.ts.map +1 -1
  315. package/dist/routes/signing-keys.js +3 -1
  316. package/dist/routes/signing-keys.js.map +1 -1
  317. package/dist/routes/tenant-access.d.ts +13 -0
  318. package/dist/routes/tenant-access.d.ts.map +1 -0
  319. package/dist/routes/tenant-access.js +26 -0
  320. package/dist/routes/tenant-access.js.map +1 -0
  321. package/dist/routes/tenant.d.ts.map +1 -1
  322. package/dist/routes/tenant.js +4 -0
  323. package/dist/routes/tenant.js.map +1 -1
  324. package/dist/routes/token-sign-in.d.ts +36 -0
  325. package/dist/routes/token-sign-in.d.ts.map +1 -0
  326. package/dist/routes/token-sign-in.js +101 -0
  327. package/dist/routes/token-sign-in.js.map +1 -0
  328. package/dist/routes/tokens.d.ts +15 -5
  329. package/dist/routes/tokens.d.ts.map +1 -1
  330. package/dist/routes/tokens.js +162 -43
  331. package/dist/routes/tokens.js.map +1 -1
  332. package/dist/routes/tools.d.ts.map +1 -1
  333. package/dist/routes/tools.js +9 -1
  334. package/dist/routes/tools.js.map +1 -1
  335. package/dist/routes/trigger-access.d.ts +29 -0
  336. package/dist/routes/trigger-access.d.ts.map +1 -0
  337. package/dist/routes/trigger-access.js +33 -0
  338. package/dist/routes/trigger-access.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +2 -1
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -1
  341. package/dist/routes/webhook-endpoints.js +11 -3
  342. package/dist/routes/webhook-endpoints.js.map +1 -1
  343. package/dist/routes/webhooks.d.ts +5 -1
  344. package/dist/routes/webhooks.d.ts.map +1 -1
  345. package/dist/routes/webhooks.js +25 -2
  346. package/dist/routes/webhooks.js.map +1 -1
  347. package/dist/run-failure.d.ts +21 -0
  348. package/dist/run-failure.d.ts.map +1 -0
  349. package/dist/run-failure.js +29 -0
  350. package/dist/run-failure.js.map +1 -0
  351. package/dist/service-account-binding.d.ts +108 -0
  352. package/dist/service-account-binding.d.ts.map +1 -0
  353. package/dist/service-account-binding.js +4 -0
  354. package/dist/service-account-binding.js.map +1 -0
  355. package/dist/session-store-binding.d.ts +61 -13
  356. package/dist/session-store-binding.d.ts.map +1 -1
  357. package/dist/signed-export.d.ts +89 -0
  358. package/dist/signed-export.d.ts.map +1 -0
  359. package/dist/signed-export.js +149 -0
  360. package/dist/signed-export.js.map +1 -0
  361. package/dist/supervisor-binding.d.ts +186 -413
  362. package/dist/supervisor-binding.d.ts.map +1 -1
  363. package/dist/testing/app-bindings.d.ts +33 -0
  364. package/dist/testing/app-bindings.d.ts.map +1 -0
  365. package/dist/testing/app-bindings.js +112 -0
  366. package/dist/testing/app-bindings.js.map +1 -0
  367. package/dist/testing/index.d.ts +11 -0
  368. package/dist/testing/index.d.ts.map +1 -0
  369. package/dist/testing/index.js +13 -0
  370. package/dist/testing/index.js.map +1 -0
  371. package/dist/testing/stub-binding.d.ts +34 -0
  372. package/dist/testing/stub-binding.d.ts.map +1 -0
  373. package/dist/testing/stub-binding.js +42 -0
  374. package/dist/testing/stub-binding.js.map +1 -0
  375. package/dist/testing/trigger-registry.d.ts +21 -0
  376. package/dist/testing/trigger-registry.d.ts.map +1 -0
  377. package/dist/testing/trigger-registry.js +206 -0
  378. package/dist/testing/trigger-registry.js.map +1 -0
  379. package/dist/token-admin.d.ts +46 -8
  380. package/dist/token-admin.d.ts.map +1 -1
  381. package/dist/token-admin.js.map +1 -1
  382. package/dist/tool-binding.d.ts +13 -0
  383. package/dist/tool-binding.d.ts.map +1 -1
  384. package/dist/trigger-binding.d.ts +2 -2
  385. package/dist/trigger-binding.d.ts.map +1 -1
  386. package/dist/trigger-binding.js +1 -1
  387. package/dist/trigger-binding.js.map +1 -1
  388. package/dist/types.d.ts +16 -0
  389. package/dist/types.d.ts.map +1 -1
  390. package/dist/webhook-endpoint-binding.d.ts +19 -3
  391. package/dist/webhook-endpoint-binding.d.ts.map +1 -1
  392. package/dist/webhook-endpoint-binding.js +1 -1
  393. package/dist/webhook-endpoint-binding.js.map +1 -1
  394. package/openapi.json +15286 -8653
  395. package/package.json +26 -22
  396. package/src/agent-binding.ts +14 -0
  397. package/src/agent-pins.ts +18 -2
  398. package/src/app.ts +366 -80
  399. package/src/block-publish.ts +181 -0
  400. package/src/caller.ts +62 -0
  401. package/src/capability-binding.ts +12 -0
  402. package/src/derive-agent-version.ts +9 -1
  403. package/src/errors.ts +73 -7
  404. package/src/eval-case-binding.ts +17 -1
  405. package/src/eval-run-binding.ts +31 -0
  406. package/src/eval-run-dispatcher.ts +7 -0
  407. package/src/eval-sample.ts +42 -0
  408. package/src/eval-suite-binding.ts +14 -0
  409. package/src/flow-binding.ts +19 -0
  410. package/src/flow-pins.ts +18 -2
  411. package/src/gate.ts +26 -0
  412. package/src/handler-binding.ts +36 -1
  413. package/src/hitl-binding.ts +24 -0
  414. package/src/identity-directory-binding.ts +85 -4
  415. package/src/identity-provider-binding.ts +216 -21
  416. package/src/improvement-pass-binding.ts +193 -0
  417. package/src/index.ts +153 -31
  418. package/src/judged-dispatcher.ts +78 -11
  419. package/src/judgment-binding.ts +25 -1
  420. package/src/mcp-endpoint-binding.ts +7 -0
  421. package/src/memory-binding.ts +121 -17
  422. package/src/memory-erasure-binding.ts +156 -0
  423. package/src/middleware/auth.ts +228 -62
  424. package/src/middleware/authorize.ts +139 -3
  425. package/src/middleware/error-mapper.ts +15 -1
  426. package/src/middleware/idempotency.ts +230 -43
  427. package/src/middleware/key-project.ts +86 -0
  428. package/src/middleware/principal.ts +9 -5
  429. package/src/middleware/project-ref.ts +3 -0
  430. package/src/openapi/generate.ts +11 -2
  431. package/src/openapi/operations.ts +1059 -142
  432. package/src/openapi/schemas.ts +2438 -485
  433. package/src/person-grants-binding.ts +76 -0
  434. package/src/proposal-service.ts +640 -0
  435. package/src/proposal-status.ts +176 -0
  436. package/src/provider-binding.ts +10 -0
  437. package/src/publish-refused.ts +38 -9
  438. package/src/routes/adapters.ts +4 -0
  439. package/src/routes/agent-releases.ts +121 -69
  440. package/src/routes/agents.ts +128 -1
  441. package/src/routes/approvals.ts +164 -154
  442. package/src/routes/artifacts.ts +181 -11
  443. package/src/routes/auth.ts +804 -336
  444. package/src/routes/blocks.ts +2 -53
  445. package/src/routes/capabilities.ts +10 -1
  446. package/src/routes/compliance.ts +60 -99
  447. package/src/routes/conversations.ts +101 -7
  448. package/src/routes/cost.ts +32 -3
  449. package/src/routes/denied.ts +28 -0
  450. package/src/routes/deployments.ts +62 -16
  451. package/src/routes/eval-comparison.ts +81 -2
  452. package/src/routes/eval-overrides.ts +108 -0
  453. package/src/routes/eval-runs.ts +86 -6
  454. package/src/routes/eval-suites.ts +25 -1
  455. package/src/routes/event-triggers.ts +27 -3
  456. package/src/routes/export-signing-keys.ts +31 -0
  457. package/src/routes/flows.ts +12 -1
  458. package/src/routes/gate-policies.ts +37 -6
  459. package/src/routes/guardrails.ts +61 -2
  460. package/src/routes/identity.ts +328 -10
  461. package/src/routes/improvement-passes.ts +541 -0
  462. package/src/routes/judged-suites.ts +113 -43
  463. package/src/routes/judgment-context.ts +76 -5
  464. package/src/routes/judgment-flow-context.ts +16 -2
  465. package/src/routes/judgments.ts +17 -3
  466. package/src/routes/mcp.ts +29 -1
  467. package/src/routes/memory-access.ts +179 -0
  468. package/src/routes/memory-erasures.ts +240 -0
  469. package/src/routes/memory-parse.ts +250 -0
  470. package/src/routes/memory.ts +244 -286
  471. package/src/routes/observations.ts +15 -2
  472. package/src/routes/pagination.ts +12 -0
  473. package/src/routes/policies.ts +7 -1
  474. package/src/routes/project-mismatch.ts +56 -0
  475. package/src/routes/projects.ts +107 -13
  476. package/src/routes/proposals.ts +370 -611
  477. package/src/routes/provenance.ts +99 -133
  478. package/src/routes/providers.ts +223 -8
  479. package/src/routes/public-run-tokens.ts +3 -0
  480. package/src/routes/runs.ts +119 -39
  481. package/src/routes/schedules.ts +472 -60
  482. package/src/routes/segments.ts +11 -0
  483. package/src/routes/service-accounts.ts +262 -0
  484. package/src/routes/sign-in-options.ts +168 -0
  485. package/src/routes/signing-keys.ts +7 -1
  486. package/src/routes/tenant-access.ts +37 -0
  487. package/src/routes/tenant.ts +6 -0
  488. package/src/routes/token-sign-in.ts +161 -0
  489. package/src/routes/tokens.ts +172 -46
  490. package/src/routes/tools.ts +12 -1
  491. package/src/routes/trigger-access.ts +72 -0
  492. package/src/routes/webhook-endpoints.ts +15 -3
  493. package/src/routes/webhooks.ts +26 -2
  494. package/src/run-failure.ts +42 -0
  495. package/src/service-account-binding.ts +113 -0
  496. package/src/session-store-binding.ts +65 -13
  497. package/src/signed-export.ts +250 -0
  498. package/src/supervisor-binding.ts +169 -409
  499. package/src/testing/app-bindings.ts +142 -0
  500. package/src/testing/index.ts +21 -0
  501. package/src/testing/stub-binding.ts +53 -0
  502. package/src/testing/trigger-registry.ts +259 -0
  503. package/src/token-admin.ts +40 -8
  504. package/src/tool-binding.ts +14 -0
  505. package/src/trigger-binding.ts +8 -1
  506. package/src/types.ts +16 -0
  507. package/src/webhook-endpoint-binding.ts +18 -3
@@ -1,14 +1,33 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
 
4
- import { Hono } from 'hono';
4
+ import { type Context, Hono } from 'hono';
5
5
 
6
- import type { Fact, MemoryScope, Retention } from '@kindgi/memory';
6
+ import type { Fact, MemoryReaders, MemoryScope } from '@kindgi/memory';
7
7
  import type { FactId, TenantId } from '@kindgi/types';
8
8
 
9
9
  import { statusFor, toWireError } from '../errors.js';
10
- import type { MemoryBinding, MemoryRetrievalHit, MemoryRetrieveIntent } from '../memory-binding.js';
10
+ import type {
11
+ MemoryBinding,
12
+ MemoryFactChangeOutcome,
13
+ MemoryRetrievalHit,
14
+ } from '../memory-binding.js';
11
15
  import type { AppEnv } from '../types.js';
16
+ import {
17
+ type MemoryAccessDeps,
18
+ callerAttribution,
19
+ callerRef,
20
+ memoryReadersFor,
21
+ memoryWriteProblem,
22
+ } from './memory-access.js';
23
+ import {
24
+ parseScopeParam,
25
+ parseTime,
26
+ parseVersion,
27
+ validateRetrieveIntent,
28
+ validateSupersedeBody,
29
+ validateWriteFactBody,
30
+ } from './memory-parse.js';
12
31
  import { clampLimit } from './pagination.js';
13
32
  import { parseScopeParams } from './scope-params.js';
14
33
 
@@ -16,14 +35,18 @@ import { parseScopeParams } from './scope-params.js';
16
35
  * Memory resource routes.
17
36
  *
18
37
  * Storage is caller-plugged via `MemoryBinding`. The API package does
19
- * not own memory persistence, retrieval, or embeddings — deployments
38
+ * not own memory persistence, retrieval, or embeddings: deployments
20
39
  * wire a binding that wraps the memory subsystem alongside their own
21
40
  * `EmbeddingProviderRegistry` and per-type retrieval policies.
22
41
  *
23
- * Facts are append-only: supersession replaces delete. Physical removal
24
- * is left to the retention sweep.
42
+ * A fact keeps its id across revisions: supersede writes the next one,
43
+ * delete tombstones it (the retention sweep removes it later), verify
44
+ * marks it verified. Every read sees only what the caller may
45
+ * (`memory-access.ts`): the binding applies it inside its query, and a
46
+ * fact the caller can't see is not found. Every write is checked against
47
+ * the scope it names.
25
48
  */
26
- export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
49
+ export function memoryRouter(binding: MemoryBinding, access: MemoryAccessDeps = {}): Hono<AppEnv> {
27
50
  const r = new Hono<AppEnv>();
28
51
 
29
52
  // ---------- GET /facts (list, cursor-paginated) ----------
@@ -31,7 +54,6 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
31
54
  const requestId = c.get('requestId');
32
55
  const tenantId = c.get('tenantId') as TenantId;
33
56
  const limit = clampLimit(c.req.query('limit'));
34
-
35
57
  const cursorRaw = c.req.query('cursor');
36
58
  const typeRaw = c.req.query('type');
37
59
  const scopeRaw = c.req.query('scope');
@@ -40,25 +62,16 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
40
62
  if (scopeRaw !== undefined && scopeRaw.length > 0) {
41
63
  const parsed = parseScopeParam(scopeRaw);
42
64
  if (parsed === null) {
43
- c.status(statusFor('bad-input') as never);
44
- return c.json(
45
- toWireError(
46
- { code: 'bad-input', message: 'Query parameter `scope` must be a JSON object' },
47
- requestId,
48
- ),
49
- );
65
+ return fail(c, 'bad-input', 'Query parameter `scope` must be a JSON object');
50
66
  }
51
67
  scope = parsed;
52
68
  }
53
- if (scopeNamesOtherTenant(scope, tenantId)) {
54
- c.status(statusFor('scope-mismatch') as never);
55
- return c.json(toWireError(SCOPE_MISMATCH, requestId));
56
- }
69
+ if (scopeNamesOtherTenant(scope, tenantId)) return failScopeMismatch(c);
70
+ const asOf = parseTime(c.req.query('asOf'), 'asOf');
71
+ if (asOf.kind === 'err') return fail(c, 'bad-input', asOf.message);
57
72
 
58
- // Thread the ?scopeKind + ?scopeId + ?inherit
59
- // triplet into `platformScope` (NOT `scope`). The JSON-encoded
60
- // `?scope=` query param + `scope: Partial<MemoryScope>` field above
61
- // are a separate filter — both coexist by design.
73
+ // `?scopeKind` + `?scopeId` + `?inherit` narrow by the platform scope
74
+ // (`platformScope`); `?scope=` is the memory scope. Both coexist.
62
75
  const scopeParsed = parseScopeParams(c.req.query(), { tenantId });
63
76
  if (scopeParsed.kind === 'err') {
64
77
  c.status(statusFor('scope-invalid') as never);
@@ -69,7 +82,9 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
69
82
 
70
83
  const page = await binding.listFacts({
71
84
  tenantId,
85
+ readers: await memoryReadersFor(c, access),
72
86
  limit,
87
+ ...(asOf.value !== undefined && { asOf: asOf.value }),
73
88
  ...(cursorRaw !== undefined &&
74
89
  cursorRaw.length > 0 && {
75
90
  cursor: cursorRaw as import('@kindgi/types').Cursor,
@@ -86,154 +101,232 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
86
101
  });
87
102
  });
88
103
 
89
- // ---------- GET /facts/:factId ----------
104
+ // ---------- GET /facts/:factId (?version | ?asOf) ----------
90
105
  r.get('/facts/:factId', async (c) => {
91
- const requestId = c.get('requestId');
92
106
  const tenantId = c.get('tenantId') as TenantId;
93
107
  const factId = c.req.param('factId') as FactId;
94
-
95
- const fact = await binding.getFact({ tenantId, factId });
96
- if (fact === null) {
97
- c.status(statusFor('fact-not-found') as never);
98
- return c.json(
99
- toWireError(
100
- {
101
- code: 'fact-not-found',
102
- message: `No fact with id "${factId as unknown as string}"`,
103
- factId: factId as unknown as string,
104
- },
105
- requestId,
106
- ),
107
- );
108
- }
108
+ const version = parseVersion(c.req.query('version'), 'version');
109
+ if (version.kind === 'err') return fail(c, 'bad-input', version.message);
110
+ const asOf = parseTime(c.req.query('asOf'), 'asOf');
111
+ if (asOf.kind === 'err') return fail(c, 'bad-input', asOf.message);
112
+ const fact = await binding.getFact({
113
+ tenantId,
114
+ factId,
115
+ readers: await memoryReadersFor(c, access),
116
+ ...(version.value !== undefined && { version: version.value }),
117
+ ...(asOf.value !== undefined && { asOf: asOf.value }),
118
+ });
119
+ if (fact === null) return failNotFound(c, factId);
109
120
  return c.json(serializeFact(fact));
110
121
  });
111
122
 
123
+ // ---------- GET /facts/:factId/revisions ----------
124
+ r.get('/facts/:factId/revisions', async (c) => {
125
+ const tenantId = c.get('tenantId') as TenantId;
126
+ const factId = c.req.param('factId') as FactId;
127
+ if (binding.listRevisions === undefined) return unsupported(c, 'fact history');
128
+ const revisions = await binding.listRevisions({
129
+ tenantId,
130
+ factId,
131
+ readers: await memoryReadersFor(c, access),
132
+ });
133
+ if (revisions === null) return failNotFound(c, factId);
134
+ return c.json({ data: revisions.map(serializeFact) });
135
+ });
136
+
112
137
  // ---------- POST /facts (write) ----------
113
138
  r.post('/facts', async (c) => {
114
- const requestId = c.get('requestId');
115
139
  const tenantId = c.get('tenantId') as TenantId;
116
-
117
- let body: unknown;
118
- try {
119
- body = await c.req.json();
120
- } catch {
121
- c.status(statusFor('bad-input') as never);
122
- return c.json(
123
- toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
124
- );
125
- }
126
- if (body === null || typeof body !== 'object') {
127
- c.status(statusFor('bad-input') as never);
128
- return c.json(
129
- toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
130
- );
131
- }
132
-
133
- const validation = validateWriteFactBody(body as Record<string, unknown>);
134
- if (validation.kind === 'err') {
135
- c.status(statusFor('bad-input') as never);
136
- return c.json(toWireError({ code: 'bad-input', message: validation.message }, requestId));
137
- }
138
- const { type, scope, content, retention, contentHash } = validation.value;
139
- if (scopeNamesOtherTenant(scope, tenantId)) {
140
- c.status(statusFor('scope-mismatch') as never);
141
- return c.json(toWireError(SCOPE_MISMATCH, requestId));
142
- }
140
+ const body = await readObject(c);
141
+ if (typeof body === 'string') return fail(c, 'bad-input', body);
142
+ const validation = validateWriteFactBody(body);
143
+ if (validation.kind === 'err') return fail(c, 'bad-input', validation.message);
144
+ const { scope, ...rest } = validation.value;
145
+ if (scopeNamesOtherTenant(scope, tenantId)) return failScopeMismatch(c);
146
+ const refused = await memoryWriteProblem(c, access, scope);
147
+ if (refused !== undefined) return fail(c, 'permission-denied', refused);
143
148
 
144
149
  const outcome = await binding.writeFact({
145
150
  tenantId,
146
- type,
147
151
  scope,
148
- content,
149
- ...(retention !== undefined && { retention }),
150
- ...(contentHash !== undefined && { contentHash }),
152
+ ...rest,
153
+ attributedTo: callerAttribution(c),
151
154
  });
152
- if (outcome.kind === 'embedding-unavailable') {
153
- c.status(statusFor('bad-input') as never);
154
- return c.json(toWireError({ code: 'bad-input', message: outcome.message }, requestId));
155
- }
156
- if (outcome.kind === 'error') {
157
- c.status(statusFor(outcome.code) as never);
158
- return c.json(toWireError({ code: outcome.code, message: outcome.message }, requestId));
159
- }
155
+ if (outcome.kind === 'embedding-unavailable') return fail(c, 'bad-input', outcome.message);
156
+ if (outcome.kind === 'error') return fail(c, outcome.code, outcome.message);
160
157
  c.status(201);
161
158
  return c.json(serializeFact(outcome.fact));
162
159
  });
163
160
 
164
161
  // ---------- POST /facts/:factId/supersede ----------
165
162
  r.post('/facts/:factId/supersede', async (c) => {
166
- const requestId = c.get('requestId');
167
163
  const tenantId = c.get('tenantId') as TenantId;
168
164
  const factId = c.req.param('factId') as FactId;
165
+ const body = await readObject(c);
166
+ if (typeof body === 'string') return fail(c, 'bad-input', body);
167
+ const validation = validateSupersedeBody(body);
168
+ if (validation.kind === 'err') return fail(c, 'bad-input', validation.message);
169
+ const target = await writableFact(c, factId);
170
+ if (target.kind === 'response') return target.response;
171
+ const outcome = await binding.supersedeFact({
172
+ tenantId,
173
+ factId,
174
+ readers: target.readers,
175
+ ...validation.value,
176
+ attributedTo: callerAttribution(c),
177
+ });
178
+ return changeResponse(c, factId, outcome);
179
+ });
180
+
181
+ // ---------- DELETE /facts/:factId (tombstone) ----------
182
+ r.delete('/facts/:factId', async (c) => {
183
+ const tenantId = c.get('tenantId') as TenantId;
184
+ const factId = c.req.param('factId') as FactId;
185
+ if (binding.deleteFact === undefined) return unsupported(c, 'deleting facts');
186
+ const expectVersion = parseVersion(c.req.query('expectVersion'), 'expectVersion');
187
+ if (expectVersion.kind === 'err') return fail(c, 'bad-input', expectVersion.message);
188
+ const target = await writableFact(c, factId);
189
+ if (target.kind === 'response') return target.response;
190
+ const outcome = await binding.deleteFact({
191
+ tenantId,
192
+ factId,
193
+ readers: target.readers,
194
+ by: callerRef(c),
195
+ ...(expectVersion.value !== undefined && { expectVersion: expectVersion.value }),
196
+ });
197
+ return changeResponse(c, factId, outcome);
198
+ });
169
199
 
170
- const outcome = await binding.supersedeFact({ tenantId, factId });
171
- if (!outcome.superseded) {
172
- c.status(statusFor('fact-not-found') as never);
173
- return c.json(
174
- toWireError(
175
- {
176
- code: 'fact-not-found',
177
- message: `No fact with id "${factId as unknown as string}" to supersede`,
178
- factId: factId as unknown as string,
179
- },
180
- requestId,
181
- ),
182
- );
183
- }
184
- return c.json({
185
- factId: factId as unknown as string,
186
- superseded: true,
200
+ // ---------- POST /facts/:factId/verify ----------
201
+ r.post('/facts/:factId/verify', async (c) => {
202
+ const tenantId = c.get('tenantId') as TenantId;
203
+ const factId = c.req.param('factId') as FactId;
204
+ if (binding.verifyFact === undefined) return unsupported(c, 'verifying facts');
205
+ const body = await readObject(c, { emptyIsObject: true });
206
+ if (typeof body === 'string') return fail(c, 'bad-input', body);
207
+ const expectVersion = parseVersion(body.expectVersion, 'expectVersion');
208
+ if (expectVersion.kind === 'err') return fail(c, 'bad-input', expectVersion.message);
209
+ const target = await writableFact(c, factId);
210
+ if (target.kind === 'response') return target.response;
211
+ const outcome = await binding.verifyFact({
212
+ tenantId,
213
+ factId,
214
+ readers: target.readers,
215
+ by: callerRef(c),
216
+ ...(expectVersion.value !== undefined && { expectVersion: expectVersion.value }),
187
217
  });
218
+ return changeResponse(c, factId, outcome);
188
219
  });
189
220
 
190
221
  // ---------- POST /retrieve ----------
191
222
  r.post('/retrieve', async (c) => {
192
- const requestId = c.get('requestId');
193
223
  const tenantId = c.get('tenantId') as TenantId;
194
-
195
- let body: unknown;
196
- try {
197
- body = await c.req.json();
198
- } catch {
199
- c.status(statusFor('bad-input') as never);
200
- return c.json(
201
- toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
202
- );
203
- }
204
- if (body === null || typeof body !== 'object') {
205
- c.status(statusFor('bad-input') as never);
206
- return c.json(
207
- toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
208
- );
224
+ const body = await readObject(c);
225
+ if (typeof body === 'string') return fail(c, 'bad-input', body);
226
+ const validation = validateRetrieveIntent(body);
227
+ if (validation.kind === 'err') return fail(c, 'bad-input', validation.message);
228
+ if (scopeNamesOtherTenant(validation.value.scope, tenantId)) return failScopeMismatch(c);
229
+ const outcome = await binding.retrieve({
230
+ tenantId,
231
+ intent: validation.value,
232
+ readers: await memoryReadersFor(c, access),
233
+ });
234
+ // Search by meaning on a deployment without embeddings: not the
235
+ // request's fault, and never an empty success.
236
+ if (outcome.kind === 'embedding-unavailable') {
237
+ return fail(c, 'semantic-unavailable', outcome.message);
209
238
  }
239
+ if (outcome.kind === 'error') return fail(c, outcome.code, outcome.message);
240
+ return c.json({ results: outcome.results.map(serializeRetrievalHit) });
241
+ });
210
242
 
211
- const validation = validateRetrieveIntent(body as Record<string, unknown>);
212
- if (validation.kind === 'err') {
213
- c.status(statusFor('bad-input') as never);
214
- return c.json(toWireError({ code: 'bad-input', message: validation.message }, requestId));
243
+ /**
244
+ * The fact the caller may see and change: its current revision is read
245
+ * (as the caller sees it), and the caller must be allowed to write in
246
+ * its scope.
247
+ */
248
+ async function writableFact(
249
+ c: Context<AppEnv>,
250
+ factId: FactId,
251
+ ): Promise<
252
+ | { readonly kind: 'ok'; readonly readers: MemoryReaders }
253
+ | { readonly kind: 'response'; readonly response: Response }
254
+ > {
255
+ const tenantId = c.get('tenantId') as TenantId;
256
+ const readers = await memoryReadersFor(c, access);
257
+ const current = await binding.getFact({ tenantId, factId, readers });
258
+ if (current === null) return { kind: 'response', response: failNotFound(c, factId) };
259
+ const refused = await memoryWriteProblem(c, access, current.scope);
260
+ if (refused !== undefined) {
261
+ return { kind: 'response', response: fail(c, 'permission-denied', refused) };
215
262
  }
263
+ return { kind: 'ok', readers };
264
+ }
216
265
 
217
- if (scopeNamesOtherTenant(validation.value.scope, tenantId)) {
218
- c.status(statusFor('scope-mismatch') as never);
219
- return c.json(toWireError(SCOPE_MISMATCH, requestId));
220
- }
266
+ return r;
267
+ }
221
268
 
222
- const outcome = await binding.retrieve({ tenantId, intent: validation.value });
223
- if (outcome.kind === 'embedding-unavailable') {
224
- c.status(statusFor('bad-input') as never);
225
- return c.json(toWireError({ code: 'bad-input', message: outcome.message }, requestId));
226
- }
227
- if (outcome.kind === 'error') {
228
- c.status(statusFor(outcome.code) as never);
229
- return c.json(toWireError({ code: outcome.code, message: outcome.message }, requestId));
230
- }
231
- return c.json({
232
- results: outcome.results.map(serializeRetrievalHit),
233
- });
269
+ // -------------------- responses --------------------
270
+
271
+ function fail(c: Context<AppEnv>, code: string, message: string, extra = {}): Response {
272
+ c.status(statusFor(code) as never);
273
+ return c.json(toWireError({ code, message, ...extra }, c.get('requestId')));
274
+ }
275
+
276
+ function failNotFound(c: Context<AppEnv>, factId: FactId): Response {
277
+ return fail(c, 'fact-not-found', `No fact with id "${factId as unknown as string}"`, {
278
+ factId: factId as unknown as string,
234
279
  });
280
+ }
235
281
 
236
- return r;
282
+ function failScopeMismatch(c: Context<AppEnv>): Response {
283
+ return fail(c, 'scope-mismatch', '`scope.tenantId` does not match the caller tenant.');
284
+ }
285
+
286
+ function unsupported(c: Context<AppEnv>, what: string): Response {
287
+ return fail(c, 'memory-operation-unsupported', `This runtime's memory doesn't support ${what}.`);
288
+ }
289
+
290
+ function changeResponse(
291
+ c: Context<AppEnv>,
292
+ factId: FactId,
293
+ outcome: MemoryFactChangeOutcome,
294
+ ): Response {
295
+ switch (outcome.kind) {
296
+ case 'ok':
297
+ return c.json(serializeFact(outcome.fact));
298
+ case 'not-found':
299
+ return failNotFound(c, factId);
300
+ case 'fact-changed':
301
+ return fail(
302
+ c,
303
+ 'fact-changed',
304
+ `Fact "${factId as unknown as string}" is at revision ${outcome.current.version} now: read it again, then retry.`,
305
+ { factId: factId as unknown as string, currentVersion: outcome.current.version },
306
+ );
307
+ case 'legal-hold':
308
+ return fail(c, 'legal-hold', outcome.message, { factId: factId as unknown as string });
309
+ case 'error':
310
+ return fail(c, outcome.code, outcome.message);
311
+ }
312
+ }
313
+
314
+ async function readObject(
315
+ c: Context<AppEnv>,
316
+ options: { readonly emptyIsObject?: boolean } = {},
317
+ ): Promise<Record<string, unknown> | string> {
318
+ const text = await c.req.text();
319
+ if (text.trim() === '' && options.emptyIsObject === true) return {};
320
+ let body: unknown;
321
+ try {
322
+ body = JSON.parse(text);
323
+ } catch {
324
+ return 'Request body must be valid JSON';
325
+ }
326
+ if (body === null || typeof body !== 'object' || Array.isArray(body)) {
327
+ return 'Request body must be an object';
328
+ }
329
+ return body as Record<string, unknown>;
237
330
  }
238
331
 
239
332
  // -------------------- serialization --------------------
@@ -241,6 +334,7 @@ export function memoryRouter(binding: MemoryBinding): Hono<AppEnv> {
241
334
  function serializeFact(f: Fact): Record<string, unknown> {
242
335
  return {
243
336
  id: f.id as unknown as string,
337
+ ...(f.revisionId !== undefined && { revisionId: f.revisionId }),
244
338
  type: f.type,
245
339
  scope: f.scope,
246
340
  version: f.version,
@@ -255,6 +349,20 @@ function serializeFact(f: Fact): Record<string, unknown> {
255
349
  ...(f.source !== undefined && { source: f.source }),
256
350
  ...(f.causedByLogId !== undefined && { causedByLogId: f.causedByLogId }),
257
351
  ...(f.supersedes !== undefined && { supersedes: f.supersedes as unknown as string }),
352
+ ...(f.trust !== undefined && { trust: f.trust }),
353
+ ...(f.verifiedBy !== undefined && { verifiedBy: f.verifiedBy }),
354
+ ...(f.verifiedAt !== undefined && { verifiedAt: f.verifiedAt }),
355
+ ...(f.attributedTo !== undefined && { attributedTo: f.attributedTo }),
356
+ ...(f.generatedBy !== undefined && { generatedBy: f.generatedBy }),
357
+ ...(f.subjects !== undefined && { subjects: f.subjects }),
358
+ ...(f.validFrom !== undefined && { validFrom: f.validFrom }),
359
+ ...(f.validUntil !== undefined && { validUntil: f.validUntil }),
360
+ ...(f.observedAt !== undefined && { observedAt: f.observedAt }),
361
+ ...(f.invalidatedAt !== undefined && { invalidatedAt: f.invalidatedAt }),
362
+ ...(f.invalidatedBy !== undefined && { invalidatedBy: f.invalidatedBy }),
363
+ ...(f.invalidationReason !== undefined && { invalidationReason: f.invalidationReason }),
364
+ ...(f.review !== undefined && { review: f.review }),
365
+ ...(f.expiresAt !== undefined && { expiresAt: f.expiresAt }),
258
366
  };
259
367
  }
260
368
 
@@ -267,15 +375,10 @@ function serializeRetrievalHit(h: MemoryRetrievalHit): Record<string, unknown> {
267
375
 
268
376
  // -------------------- request parsing --------------------
269
377
 
270
- const SCOPE_MISMATCH = {
271
- code: 'scope-mismatch',
272
- message: '`scope.tenantId` does not match the caller tenant.',
273
- } as const;
274
-
275
378
  /**
276
379
  * A memory scope in a request may name a tenant; it must be the caller's
277
380
  * (derived from the token). Same rule as the secrets, env and policy
278
- * routes — a request can never read or write another tenant's memory.
381
+ * routes: a request can never read or write another tenant's memory.
279
382
  */
280
383
  function scopeNamesOtherTenant(
281
384
  scope: Partial<MemoryScope> | undefined,
@@ -283,148 +386,3 @@ function scopeNamesOtherTenant(
283
386
  ): boolean {
284
387
  return scope?.tenantId !== undefined && scope.tenantId !== tenantId;
285
388
  }
286
-
287
- function parseScopeParam(raw: string): Partial<MemoryScope> | null {
288
- try {
289
- const decoded = JSON.parse(raw) as unknown;
290
- if (decoded === null || typeof decoded !== 'object' || Array.isArray(decoded)) return null;
291
- return decoded as Partial<MemoryScope>;
292
- } catch {
293
- return null;
294
- }
295
- }
296
-
297
- // -------------------- validators --------------------
298
-
299
- type ValidationResult<T> =
300
- | { readonly kind: 'ok'; readonly value: T }
301
- | { readonly kind: 'err'; readonly message: string };
302
-
303
- interface ValidatedWriteFactBody {
304
- readonly type: string;
305
- readonly scope: MemoryScope;
306
- readonly content: unknown;
307
- readonly retention?: Retention;
308
- readonly contentHash?: string;
309
- }
310
-
311
- function validateWriteFactBody(
312
- body: Record<string, unknown>,
313
- ): ValidationResult<ValidatedWriteFactBody> {
314
- const type = body.type;
315
- if (typeof type !== 'string' || type.length === 0) {
316
- return { kind: 'err', message: 'Field `type` must be a non-empty string' };
317
- }
318
- const rawScope = body.scope;
319
- if (rawScope === null || typeof rawScope !== 'object' || Array.isArray(rawScope)) {
320
- return { kind: 'err', message: 'Field `scope` must be an object' };
321
- }
322
- const scope = rawScope as MemoryScope;
323
- if (typeof (scope as { tenantId?: unknown }).tenantId !== 'string') {
324
- return { kind: 'err', message: 'Field `scope.tenantId` must be a string' };
325
- }
326
- if (!('content' in body)) {
327
- return { kind: 'err', message: 'Field `content` is required' };
328
- }
329
- const rawRetention = body.retention;
330
- let retention: Retention | undefined;
331
- if (rawRetention !== undefined) {
332
- if (rawRetention === null || typeof rawRetention !== 'object' || Array.isArray(rawRetention)) {
333
- return { kind: 'err', message: 'Field `retention` must be an object when present' };
334
- }
335
- retention = rawRetention as Retention;
336
- }
337
- const rawContentHash = body.contentHash;
338
- let contentHash: string | undefined;
339
- if (rawContentHash !== undefined) {
340
- if (typeof rawContentHash !== 'string' || rawContentHash.length === 0) {
341
- return {
342
- kind: 'err',
343
- message: 'Field `contentHash` must be a non-empty string when present',
344
- };
345
- }
346
- contentHash = rawContentHash;
347
- }
348
- return {
349
- kind: 'ok',
350
- value: {
351
- type,
352
- scope,
353
- content: body.content,
354
- ...(retention !== undefined && { retention }),
355
- ...(contentHash !== undefined && { contentHash }),
356
- },
357
- };
358
- }
359
-
360
- function validateRetrieveIntent(
361
- body: Record<string, unknown>,
362
- ): ValidationResult<MemoryRetrieveIntent> {
363
- const mode = body.mode;
364
- if (mode !== 'list' && mode !== 'keyword' && mode !== 'semantic' && mode !== 'both') {
365
- return {
366
- kind: 'err',
367
- message: 'Field `mode` must be one of "list", "keyword", "semantic", "both"',
368
- };
369
- }
370
- let query: string | undefined;
371
- const rawQuery = body.query;
372
- if (rawQuery !== undefined) {
373
- if (typeof rawQuery !== 'string') {
374
- return { kind: 'err', message: 'Field `query` must be a string when present' };
375
- }
376
- query = rawQuery;
377
- }
378
- if ((mode === 'keyword' || mode === 'semantic' || mode === 'both') && query === undefined) {
379
- return {
380
- kind: 'err',
381
- message: `Field \`query\` is required when \`mode\` is "${mode}"`,
382
- };
383
- }
384
- let type: string | undefined;
385
- const rawType = body.type;
386
- if (rawType !== undefined) {
387
- if (typeof rawType !== 'string' || rawType.length === 0) {
388
- return { kind: 'err', message: 'Field `type` must be a non-empty string when present' };
389
- }
390
- type = rawType;
391
- }
392
- let scope: Partial<MemoryScope> | undefined;
393
- const rawScope = body.scope;
394
- if (rawScope !== undefined) {
395
- if (rawScope === null || typeof rawScope !== 'object' || Array.isArray(rawScope)) {
396
- return { kind: 'err', message: 'Field `scope` must be an object when present' };
397
- }
398
- scope = rawScope as Partial<MemoryScope>;
399
- }
400
- let limit: number | undefined;
401
- const rawLimit = body.limit;
402
- if (rawLimit !== undefined) {
403
- if (typeof rawLimit !== 'number' || !Number.isFinite(rawLimit) || rawLimit < 1) {
404
- return { kind: 'err', message: 'Field `limit` must be a positive number when present' };
405
- }
406
- limit = Math.floor(rawLimit);
407
- }
408
- let embeddingModel: string | undefined;
409
- const rawEmbeddingModel = body.embeddingModel;
410
- if (rawEmbeddingModel !== undefined) {
411
- if (typeof rawEmbeddingModel !== 'string' || rawEmbeddingModel.length === 0) {
412
- return {
413
- kind: 'err',
414
- message: 'Field `embeddingModel` must be a non-empty string when present',
415
- };
416
- }
417
- embeddingModel = rawEmbeddingModel;
418
- }
419
- return {
420
- kind: 'ok',
421
- value: {
422
- mode,
423
- ...(query !== undefined && { query }),
424
- ...(type !== undefined && { type }),
425
- ...(scope !== undefined && { scope }),
426
- ...(limit !== undefined && { limit }),
427
- ...(embeddingModel !== undefined && { embeddingModel }),
428
- },
429
- };
430
- }