@stigmer/server 3.24.0 → 3.26.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 (341) hide show
  1. package/dist/authorization/authorizer.d.ts +10 -4
  2. package/dist/authorization/authorizer.d.ts.map +1 -1
  3. package/dist/authorization/authorizer.js +11 -4
  4. package/dist/authorization/authorizer.js.map +1 -1
  5. package/dist/authorization/model/index.d.ts +4 -4
  6. package/dist/authorization/model/index.d.ts.map +1 -1
  7. package/dist/authorization/model/index.js +2 -0
  8. package/dist/authorization/model/index.js.map +1 -1
  9. package/dist/authorization/model/oauth_app.d.ts.map +1 -1
  10. package/dist/authorization/model/oauth_app.js +3 -2
  11. package/dist/authorization/model/oauth_app.js.map +1 -1
  12. package/dist/authorization/model/platform_client.d.ts +2 -0
  13. package/dist/authorization/model/platform_client.d.ts.map +1 -0
  14. package/dist/authorization/model/platform_client.js +31 -0
  15. package/dist/authorization/model/platform_client.js.map +1 -0
  16. package/dist/boot/compose.d.ts.map +1 -1
  17. package/dist/boot/compose.js +99 -13
  18. package/dist/boot/compose.js.map +1 -1
  19. package/dist/boot/list-indexes.d.ts +3 -0
  20. package/dist/boot/list-indexes.d.ts.map +1 -0
  21. package/dist/boot/list-indexes.js +24 -0
  22. package/dist/boot/list-indexes.js.map +1 -0
  23. package/dist/boot/route-shadowing.d.ts +25 -0
  24. package/dist/boot/route-shadowing.d.ts.map +1 -0
  25. package/dist/boot/route-shadowing.js +17 -0
  26. package/dist/boot/route-shadowing.js.map +1 -0
  27. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  28. package/dist/domain/agentexecution/controller.js +6 -8
  29. package/dist/domain/agentexecution/controller.js.map +1 -1
  30. package/dist/domain/agentexecution/list-index.d.ts +2 -0
  31. package/dist/domain/agentexecution/list-index.d.ts.map +1 -0
  32. package/dist/domain/agentexecution/list-index.js +23 -0
  33. package/dist/domain/agentexecution/list-index.js.map +1 -0
  34. package/dist/domain/agentexecution/steps.d.ts +17 -33
  35. package/dist/domain/agentexecution/steps.d.ts.map +1 -1
  36. package/dist/domain/agentexecution/steps.js +94 -95
  37. package/dist/domain/agentexecution/steps.js.map +1 -1
  38. package/dist/domain/agentexecution/usage.d.ts.map +1 -1
  39. package/dist/domain/agentexecution/usage.js +37 -14
  40. package/dist/domain/agentexecution/usage.js.map +1 -1
  41. package/dist/domain/artifact/controller.d.ts.map +1 -1
  42. package/dist/domain/artifact/controller.js +27 -15
  43. package/dist/domain/artifact/controller.js.map +1 -1
  44. package/dist/domain/artifact/list-index.d.ts +2 -0
  45. package/dist/domain/artifact/list-index.d.ts.map +1 -0
  46. package/dist/domain/artifact/list-index.js +21 -0
  47. package/dist/domain/artifact/list-index.js.map +1 -0
  48. package/dist/domain/iampolicy/membership.d.ts +6 -1
  49. package/dist/domain/iampolicy/membership.d.ts.map +1 -1
  50. package/dist/domain/iampolicy/membership.js +8 -2
  51. package/dist/domain/iampolicy/membership.js.map +1 -1
  52. package/dist/domain/identityaccount/constants.d.ts +13 -0
  53. package/dist/domain/identityaccount/constants.d.ts.map +1 -1
  54. package/dist/domain/identityaccount/constants.js +17 -0
  55. package/dist/domain/identityaccount/constants.js.map +1 -1
  56. package/dist/domain/identityaccount/controller.d.ts +3 -1
  57. package/dist/domain/identityaccount/controller.d.ts.map +1 -1
  58. package/dist/domain/identityaccount/controller.js +15 -6
  59. package/dist/domain/identityaccount/controller.js.map +1 -1
  60. package/dist/domain/identityaccount/operator.d.ts.map +1 -1
  61. package/dist/domain/identityaccount/operator.js +1 -0
  62. package/dist/domain/identityaccount/operator.js.map +1 -1
  63. package/dist/domain/identityaccount/provisioning.d.ts +18 -0
  64. package/dist/domain/identityaccount/provisioning.d.ts.map +1 -1
  65. package/dist/domain/identityaccount/provisioning.js +1 -0
  66. package/dist/domain/identityaccount/provisioning.js.map +1 -1
  67. package/dist/domain/identityaccount/resource-store.js +9 -5
  68. package/dist/domain/identityaccount/resource-store.js.map +1 -1
  69. package/dist/domain/identityaccount/steps.d.ts +11 -2
  70. package/dist/domain/identityaccount/steps.d.ts.map +1 -1
  71. package/dist/domain/identityaccount/steps.js +42 -4
  72. package/dist/domain/identityaccount/steps.js.map +1 -1
  73. package/dist/domain/identityaccount/store-contract.d.ts.map +1 -1
  74. package/dist/domain/identityaccount/store-contract.js +33 -0
  75. package/dist/domain/identityaccount/store-contract.js.map +1 -1
  76. package/dist/domain/identityaccount/store.d.ts +7 -5
  77. package/dist/domain/identityaccount/store.d.ts.map +1 -1
  78. package/dist/domain/identityaccount/store.js.map +1 -1
  79. package/dist/domain/platform/controller.d.ts +10 -0
  80. package/dist/domain/platform/controller.d.ts.map +1 -1
  81. package/dist/domain/platform/controller.js +2 -1
  82. package/dist/domain/platform/controller.js.map +1 -1
  83. package/dist/domain/platformclient/constants.d.ts +60 -0
  84. package/dist/domain/platformclient/constants.d.ts.map +1 -0
  85. package/dist/domain/platformclient/constants.js +78 -0
  86. package/dist/domain/platformclient/constants.js.map +1 -0
  87. package/dist/domain/platformclient/controller.d.ts +59 -0
  88. package/dist/domain/platformclient/controller.d.ts.map +1 -0
  89. package/dist/domain/platformclient/controller.js +191 -0
  90. package/dist/domain/platformclient/controller.js.map +1 -0
  91. package/dist/domain/platformclient/credentials.d.ts +13 -0
  92. package/dist/domain/platformclient/credentials.d.ts.map +1 -0
  93. package/dist/domain/platformclient/credentials.js +56 -0
  94. package/dist/domain/platformclient/credentials.js.map +1 -0
  95. package/dist/domain/platformclient/mint.d.ts +23 -0
  96. package/dist/domain/platformclient/mint.d.ts.map +1 -0
  97. package/dist/domain/platformclient/mint.js +254 -0
  98. package/dist/domain/platformclient/mint.js.map +1 -0
  99. package/dist/domain/platformclient/origin-guard.d.ts +9 -0
  100. package/dist/domain/platformclient/origin-guard.d.ts.map +1 -0
  101. package/dist/domain/platformclient/origin-guard.js +81 -0
  102. package/dist/domain/platformclient/origin-guard.js.map +1 -0
  103. package/dist/domain/platformclient/resource-store.d.ts +4 -0
  104. package/dist/domain/platformclient/resource-store.d.ts.map +1 -0
  105. package/dist/domain/platformclient/resource-store.js +117 -0
  106. package/dist/domain/platformclient/resource-store.js.map +1 -0
  107. package/dist/domain/platformclient/steps.d.ts +51 -0
  108. package/dist/domain/platformclient/steps.d.ts.map +1 -0
  109. package/dist/domain/platformclient/steps.js +339 -0
  110. package/dist/domain/platformclient/steps.js.map +1 -0
  111. package/dist/domain/platformclient/store-contract.d.ts +8 -0
  112. package/dist/domain/platformclient/store-contract.d.ts.map +1 -0
  113. package/dist/domain/platformclient/store-contract.js +208 -0
  114. package/dist/domain/platformclient/store-contract.js.map +1 -0
  115. package/dist/domain/platformclient/store.d.ts +58 -0
  116. package/dist/domain/platformclient/store.d.ts.map +1 -0
  117. package/dist/domain/platformclient/store.js +13 -0
  118. package/dist/domain/platformclient/store.js.map +1 -0
  119. package/dist/domain/platformclient/system-managed.d.ts +18 -0
  120. package/dist/domain/platformclient/system-managed.d.ts.map +1 -0
  121. package/dist/domain/platformclient/system-managed.js +80 -0
  122. package/dist/domain/platformclient/system-managed.js.map +1 -0
  123. package/dist/domain/platformclient/token-controller.d.ts +11 -0
  124. package/dist/domain/platformclient/token-controller.d.ts.map +1 -0
  125. package/dist/domain/platformclient/token-controller.js +32 -0
  126. package/dist/domain/platformclient/token-controller.js.map +1 -0
  127. package/dist/domain/platformclient/verifier.d.ts +10 -0
  128. package/dist/domain/platformclient/verifier.d.ts.map +1 -0
  129. package/dist/domain/platformclient/verifier.js +76 -0
  130. package/dist/domain/platformclient/verifier.js.map +1 -0
  131. package/dist/domain/session/list-index.d.ts +4 -0
  132. package/dist/domain/session/list-index.d.ts.map +1 -0
  133. package/dist/domain/session/list-index.js +26 -0
  134. package/dist/domain/session/list-index.js.map +1 -0
  135. package/dist/domain/session/steps.d.ts +7 -8
  136. package/dist/domain/session/steps.d.ts.map +1 -1
  137. package/dist/domain/session/steps.js +76 -78
  138. package/dist/domain/session/steps.js.map +1 -1
  139. package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
  140. package/dist/domain/workflowexecution/controller.js +53 -55
  141. package/dist/domain/workflowexecution/controller.js.map +1 -1
  142. package/dist/domain/workflowexecution/execution-filter.d.ts +4 -0
  143. package/dist/domain/workflowexecution/execution-filter.d.ts.map +1 -1
  144. package/dist/domain/workflowexecution/execution-filter.js +11 -5
  145. package/dist/domain/workflowexecution/execution-filter.js.map +1 -1
  146. package/dist/domain/workflowexecution/get-execution-summary.d.ts.map +1 -1
  147. package/dist/domain/workflowexecution/get-execution-summary.js +23 -17
  148. package/dist/domain/workflowexecution/get-execution-summary.js.map +1 -1
  149. package/dist/domain/workflowexecution/list-index.d.ts +2 -0
  150. package/dist/domain/workflowexecution/list-index.d.ts.map +1 -0
  151. package/dist/domain/workflowexecution/list-index.js +21 -0
  152. package/dist/domain/workflowexecution/list-index.js.map +1 -0
  153. package/dist/domain/workflowexecution/list-pending-approvals.d.ts.map +1 -1
  154. package/dist/domain/workflowexecution/list-pending-approvals.js +69 -32
  155. package/dist/domain/workflowexecution/list-pending-approvals.js.map +1 -1
  156. package/dist/domain/workflowexecution/queries.d.ts +30 -4
  157. package/dist/domain/workflowexecution/queries.d.ts.map +1 -1
  158. package/dist/domain/workflowexecution/queries.js +76 -22
  159. package/dist/domain/workflowexecution/queries.js.map +1 -1
  160. package/dist/encryption/key-manager.d.ts +20 -3
  161. package/dist/encryption/key-manager.d.ts.map +1 -1
  162. package/dist/encryption/key-manager.js +64 -42
  163. package/dist/encryption/key-manager.js.map +1 -1
  164. package/dist/extensions/caller-guards.d.ts +8 -3
  165. package/dist/extensions/caller-guards.d.ts.map +1 -1
  166. package/dist/extensions/drivers.d.ts +37 -0
  167. package/dist/extensions/drivers.d.ts.map +1 -1
  168. package/dist/extensions/guest-token-minting.d.ts +26 -0
  169. package/dist/extensions/guest-token-minting.d.ts.map +1 -0
  170. package/dist/extensions/guest-token-minting.js +2 -0
  171. package/dist/extensions/guest-token-minting.js.map +1 -0
  172. package/dist/extensions/identity.d.ts +6 -4
  173. package/dist/extensions/identity.d.ts.map +1 -1
  174. package/dist/extensions/identity.js.map +1 -1
  175. package/dist/extensions/list-read-scope.d.ts +9 -12
  176. package/dist/extensions/list-read-scope.d.ts.map +1 -1
  177. package/dist/extensions/list-read-scope.js.map +1 -1
  178. package/dist/extensions/registry.d.ts +30 -1
  179. package/dist/extensions/registry.d.ts.map +1 -1
  180. package/dist/extensions/registry.js +34 -1
  181. package/dist/extensions/registry.js.map +1 -1
  182. package/dist/index.d.ts +15 -2
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.js +6 -0
  185. package/dist/index.js.map +1 -1
  186. package/dist/pipeline/interceptors/auth.d.ts +14 -0
  187. package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
  188. package/dist/pipeline/interceptors/auth.js +24 -0
  189. package/dist/pipeline/interceptors/auth.js.map +1 -1
  190. package/dist/pipeline/steps/build-update-state.d.ts +11 -1
  191. package/dist/pipeline/steps/build-update-state.d.ts.map +1 -1
  192. package/dist/pipeline/steps/build-update-state.js +5 -2
  193. package/dist/pipeline/steps/build-update-state.js.map +1 -1
  194. package/dist/pipeline/steps/list-page.d.ts +63 -0
  195. package/dist/pipeline/steps/list-page.d.ts.map +1 -0
  196. package/dist/pipeline/steps/list-page.js +187 -0
  197. package/dist/pipeline/steps/list-page.js.map +1 -0
  198. package/dist/platformtoken/envelope.d.ts +100 -0
  199. package/dist/platformtoken/envelope.d.ts.map +1 -0
  200. package/dist/platformtoken/envelope.js +184 -0
  201. package/dist/platformtoken/envelope.js.map +1 -0
  202. package/dist/platformtoken/key-ring.d.ts +85 -0
  203. package/dist/platformtoken/key-ring.d.ts.map +1 -0
  204. package/dist/platformtoken/key-ring.js +164 -0
  205. package/dist/platformtoken/key-ring.js.map +1 -0
  206. package/dist/query/activity/handler.d.ts +6 -7
  207. package/dist/query/activity/handler.d.ts.map +1 -1
  208. package/dist/query/activity/handler.js +42 -59
  209. package/dist/query/activity/handler.js.map +1 -1
  210. package/dist/store/interface.d.ts +29 -0
  211. package/dist/store/interface.d.ts.map +1 -1
  212. package/dist/store/interface.js.map +1 -1
  213. package/dist/store/list-index.d.ts +123 -0
  214. package/dist/store/list-index.d.ts.map +1 -0
  215. package/dist/store/list-index.js +277 -0
  216. package/dist/store/list-index.js.map +1 -0
  217. package/dist/store/logger.d.ts +3 -0
  218. package/dist/store/logger.d.ts.map +1 -1
  219. package/dist/store/logger.js +5 -1
  220. package/dist/store/logger.js.map +1 -1
  221. package/dist/store/postgres/migrations.d.ts +10 -6
  222. package/dist/store/postgres/migrations.d.ts.map +1 -1
  223. package/dist/store/postgres/migrations.js +64 -6
  224. package/dist/store/postgres/migrations.js.map +1 -1
  225. package/dist/store/postgres/store.d.ts +26 -5
  226. package/dist/store/postgres/store.d.ts.map +1 -1
  227. package/dist/store/postgres/store.js +377 -22
  228. package/dist/store/postgres/store.js.map +1 -1
  229. package/dist/store/sqlite/migrations.d.ts +11 -5
  230. package/dist/store/sqlite/migrations.d.ts.map +1 -1
  231. package/dist/store/sqlite/migrations.js +50 -4
  232. package/dist/store/sqlite/migrations.js.map +1 -1
  233. package/dist/store/sqlite/store.d.ts +18 -3
  234. package/dist/store/sqlite/store.d.ts.map +1 -1
  235. package/dist/store/sqlite/store.js +321 -15
  236. package/dist/store/sqlite/store.js.map +1 -1
  237. package/package.json +6 -6
  238. package/src/authorization/README.md +1 -1
  239. package/src/authorization/__tests__/authorizer.test.ts +6 -2
  240. package/src/authorization/__tests__/drivers.ts +6 -1
  241. package/src/authorization/__tests__/wire-permissions.test.ts +1 -0
  242. package/src/authorization/authorizer.ts +11 -4
  243. package/src/authorization/model/__tests__/registry.test.ts +8 -1
  244. package/src/authorization/model/index.ts +6 -4
  245. package/src/authorization/model/oauth_app.ts +3 -2
  246. package/src/authorization/model/platform_client.ts +43 -0
  247. package/src/boot/__tests__/auth-enabled-composition.test.ts +2 -1
  248. package/src/boot/__tests__/list-indexes.test.ts +65 -0
  249. package/src/boot/__tests__/route-shadowing.test.ts +67 -0
  250. package/src/boot/compose.ts +113 -18
  251. package/src/boot/list-indexes.ts +25 -0
  252. package/src/boot/route-shadowing.ts +47 -0
  253. package/src/domain/agentexecution/__tests__/agentexecution.test.ts +85 -3
  254. package/src/domain/agentexecution/controller.ts +8 -10
  255. package/src/domain/agentexecution/list-index.ts +24 -0
  256. package/src/domain/agentexecution/steps.ts +118 -115
  257. package/src/domain/agentexecution/usage.ts +38 -17
  258. package/src/domain/artifact/controller.ts +28 -18
  259. package/src/domain/artifact/list-index.ts +22 -0
  260. package/src/domain/iampolicy/__tests__/membership.test.ts +7 -0
  261. package/src/domain/iampolicy/membership.ts +8 -2
  262. package/src/domain/identityaccount/__tests__/platform-client-accounts.test.ts +124 -0
  263. package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -0
  264. package/src/domain/identityaccount/constants.ts +20 -0
  265. package/src/domain/identityaccount/controller.ts +16 -4
  266. package/src/domain/identityaccount/operator.ts +1 -0
  267. package/src/domain/identityaccount/provisioning.ts +17 -0
  268. package/src/domain/identityaccount/resource-store.ts +9 -5
  269. package/src/domain/identityaccount/steps.ts +58 -3
  270. package/src/domain/identityaccount/store-contract.ts +51 -0
  271. package/src/domain/identityaccount/store.ts +7 -5
  272. package/src/domain/platform/__tests__/platform.test.ts +7 -1
  273. package/src/domain/platform/controller.ts +12 -1
  274. package/src/domain/platformclient/__tests__/controller.test.ts +397 -0
  275. package/src/domain/platformclient/__tests__/credentials.test.ts +46 -0
  276. package/src/domain/platformclient/__tests__/mint.test.ts +415 -0
  277. package/src/domain/platformclient/__tests__/resource-store.test.ts +140 -0
  278. package/src/domain/platformclient/__tests__/system-managed.test.ts +101 -0
  279. package/src/domain/platformclient/__tests__/verifier-and-guard.test.ts +207 -0
  280. package/src/domain/platformclient/constants.ts +120 -0
  281. package/src/domain/platformclient/controller.ts +449 -0
  282. package/src/domain/platformclient/credentials.ts +68 -0
  283. package/src/domain/platformclient/mint.ts +412 -0
  284. package/src/domain/platformclient/origin-guard.ts +117 -0
  285. package/src/domain/platformclient/resource-store.ts +150 -0
  286. package/src/domain/platformclient/steps.ts +472 -0
  287. package/src/domain/platformclient/store-contract.ts +318 -0
  288. package/src/domain/platformclient/store.ts +63 -0
  289. package/src/domain/platformclient/system-managed.ts +115 -0
  290. package/src/domain/platformclient/token-controller.ts +49 -0
  291. package/src/domain/platformclient/verifier.ts +106 -0
  292. package/src/domain/session/list-index.ts +28 -0
  293. package/src/domain/session/steps.ts +108 -123
  294. package/src/domain/workflowexecution/__tests__/list-read-scope-summaries.test.ts +155 -99
  295. package/src/domain/workflowexecution/__tests__/workflowexecution.test.ts +193 -31
  296. package/src/domain/workflowexecution/controller.ts +54 -82
  297. package/src/domain/workflowexecution/execution-filter.ts +20 -7
  298. package/src/domain/workflowexecution/get-execution-summary.ts +31 -24
  299. package/src/domain/workflowexecution/list-index.ts +22 -0
  300. package/src/domain/workflowexecution/list-pending-approvals.ts +82 -25
  301. package/src/domain/workflowexecution/queries.ts +134 -23
  302. package/src/encryption/key-manager.ts +87 -44
  303. package/src/extensions/__tests__/extension-composition.test.ts +3 -2
  304. package/src/extensions/__tests__/platform-client-composed.test.ts +288 -0
  305. package/src/extensions/__tests__/registry.test.ts +4 -1
  306. package/src/extensions/__tests__/tier-truthfulness.test.ts +8 -0
  307. package/src/extensions/caller-guards.ts +8 -3
  308. package/src/extensions/drivers.ts +37 -0
  309. package/src/extensions/guest-token-minting.ts +32 -0
  310. package/src/extensions/identity.ts +6 -4
  311. package/src/extensions/list-read-scope.ts +9 -12
  312. package/src/extensions/registry.ts +77 -3
  313. package/src/index.ts +65 -1
  314. package/src/pipeline/interceptors/auth.ts +27 -0
  315. package/src/pipeline/steps/__tests__/list-page.test.ts +186 -0
  316. package/src/pipeline/steps/__tests__/references.test.ts +2 -0
  317. package/src/pipeline/steps/build-update-state.ts +5 -2
  318. package/src/pipeline/steps/list-page.ts +284 -0
  319. package/src/platformtoken/__tests__/envelope.test.ts +277 -0
  320. package/src/platformtoken/__tests__/key-ring.test.ts +205 -0
  321. package/src/platformtoken/envelope.ts +276 -0
  322. package/src/platformtoken/key-ring.ts +266 -0
  323. package/src/query/activity/handler.ts +57 -78
  324. package/src/runnerauth/__tests__/runner-subject-composed.test.ts +9 -3
  325. package/src/store/README.md +51 -32
  326. package/src/store/__tests__/list-index.measure.test.ts +293 -0
  327. package/src/store/__tests__/list-index.test.ts +328 -0
  328. package/src/store/__tests__/store-contract.ts +346 -3
  329. package/src/store/interface.ts +39 -0
  330. package/src/store/list-index.ts +465 -0
  331. package/src/store/logger.ts +8 -1
  332. package/src/store/postgres/__tests__/list-index-repair.test.ts +133 -0
  333. package/src/store/postgres/__tests__/migrations.test.ts +27 -19
  334. package/src/store/postgres/__tests__/store-contract.test.ts +50 -3
  335. package/src/store/postgres/migrations.ts +69 -7
  336. package/src/store/postgres/store.ts +485 -29
  337. package/src/store/sqlite/__tests__/migrations.test.ts +51 -7
  338. package/src/store/sqlite/__tests__/store-contract.test.ts +70 -16
  339. package/src/store/sqlite/__tests__/support.ts +12 -3
  340. package/src/store/sqlite/migrations.ts +57 -6
  341. package/src/store/sqlite/store.ts +462 -21
@@ -1,48 +1,159 @@
1
1
  /**
2
- * Shared full-scan load for the workflowexecution read surfaces (list,
3
- * listByWorkflow, getExecutionSummary, listPendingApprovals) — Go's
4
- * store.ListResources + proto.Unmarshal-continue loop, where malformed
5
- * rows are skipped rather than failing the read.
2
+ * The workflowexecution read surfaces' shared reads (list,
3
+ * listByWorkflow, getExecutionSummary, listPendingApprovals), all through
4
+ * the list index (list-index.ts beside this file; the store's contract in
5
+ * store/interface.ts) — the request's org or workflow key narrows in the
6
+ * store, newest created first. Malformed rows are skipped rather than
7
+ * failing the read, Go's proto.Unmarshal-continue loop.
8
+ *
9
+ * The two lists share one reader: the default order pages
10
+ * (pipeline/steps/list-page.ts), with the lane's filters and then the read
11
+ * scope on each batch; another sort field sorts the whole matching set and
12
+ * returns its first page_size entries with no token, because only the
13
+ * creation order is an index order.
6
14
  */
7
- import { fromBinary } from "@bufbuild/protobuf";
15
+ import { create, fromBinary } from "@bufbuild/protobuf";
8
16
 
9
17
  import type { WorkflowExecution } from "@stigmer/protos/ai/stigmer/agentic/workflowexecution/v1/api_pb";
10
18
  import { WorkflowExecutionSchema } from "@stigmer/protos/ai/stigmer/agentic/workflowexecution/v1/api_pb";
19
+ import {
20
+ ExecutionSortField,
21
+ WorkflowExecutionListSchema,
22
+ } from "@stigmer/protos/ai/stigmer/agentic/workflowexecution/v1/io_pb";
23
+ import type { WorkflowExecutionList } from "@stigmer/protos/ai/stigmer/agentic/workflowexecution/v1/io_pb";
11
24
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
12
25
 
13
26
  import type { Logger } from "../../boot/logger.js";
14
- import { internalError } from "../../pipeline/errors.js";
27
+ import type { CallerIdentity } from "../../extensions/identity.js";
28
+ import type { ListReadScope } from "../../extensions/list-read-scope.js";
29
+ import { restrictListByReadScope } from "../../extensions/list-read-scope.js";
30
+ import { internalError, invalidArgumentError } from "../../pipeline/errors.js";
31
+ import {
32
+ LIST_PAGE_MAX_SIZE,
33
+ listPageFingerprint,
34
+ readListPage,
35
+ } from "../../pipeline/steps/list-page.js";
36
+ import type { ListPageRequest } from "../../pipeline/steps/list-page.js";
15
37
  import type { Store } from "../../store/interface.js";
38
+ import type { ListIndexQuery, ListIndexRow } from "../../store/list-index.js";
39
+ import { applySortField } from "./execution-filter.js";
40
+ import { workflowExecutionListIndex } from "./list-index.js";
41
+
42
+ /** The keys the workflow-execution index declares. */
43
+ export type WorkflowExecutionListKey = "workflow" | "workflow_instance";
44
+
45
+ /** A stored row, or undefined (logged) when it does not decode. */
46
+ export function decodeWorkflowExecution(
47
+ data: Uint8Array,
48
+ logger: Logger,
49
+ ): WorkflowExecution | undefined {
50
+ try {
51
+ return fromBinary(WorkflowExecutionSchema, data);
52
+ } catch (error) {
53
+ logger.warn("Failed to unmarshal workflow execution, skipping", {
54
+ error: error instanceof Error ? error.message : String(error),
55
+ });
56
+ return undefined;
57
+ }
58
+ }
16
59
 
17
60
  /**
18
- * Loads every workflow execution. The Internal message varies by caller in
19
- * Go (each handler wraps the same store error with its own text), so the
20
- * caller supplies it.
61
+ * Every workflow execution the query matches, newest created first. The
62
+ * Internal message varies by caller in Go (each handler wraps the same
63
+ * store error with its own text), so the caller supplies it.
21
64
  */
22
- export async function loadAllWorkflowExecutions(
65
+ export async function loadWorkflowExecutions(
23
66
  store: Store,
24
67
  logger: Logger,
68
+ query: ListIndexQuery<WorkflowExecutionListKey>,
25
69
  internalMessage: string,
26
70
  ): Promise<WorkflowExecution[]> {
27
- let rows: Uint8Array[];
71
+ let rows: ListIndexRow[];
28
72
  try {
29
- rows = await store.listResources(ApiResourceKind.workflow_execution);
73
+ rows = await store.queryResources(workflowExecutionListIndex, query);
30
74
  } catch (error) {
31
75
  throw internalError(error, internalMessage);
32
76
  }
33
-
34
77
  const executions: WorkflowExecution[] = [];
35
- for (const data of rows) {
36
- let execution: WorkflowExecution;
37
- try {
38
- execution = fromBinary(WorkflowExecutionSchema, data);
39
- } catch (error) {
40
- logger.warn("Failed to unmarshal workflow execution, skipping", {
41
- error: error instanceof Error ? error.message : String(error),
42
- });
43
- continue;
78
+ for (const row of rows) {
79
+ const execution = decodeWorkflowExecution(row.data, logger);
80
+ if (execution !== undefined) {
81
+ executions.push(execution);
44
82
  }
45
- executions.push(execution);
46
83
  }
47
84
  return executions;
48
85
  }
86
+
87
+ export interface WorkflowExecutionListRead {
88
+ readonly store: Store;
89
+ readonly logger: Logger;
90
+ readonly listReadScope: ListReadScope | undefined;
91
+ readonly identity: CallerIdentity;
92
+ readonly query: ListIndexQuery<WorkflowExecutionListKey>;
93
+ readonly request: ListPageRequest;
94
+ readonly sortField: ExecutionSortField;
95
+ readonly sortAscending: boolean;
96
+ /** The lane's filters beyond the indexed predicates. */
97
+ readonly keep: (execution: WorkflowExecution) => boolean;
98
+ /** The request's other fields, which its token is bound to. */
99
+ readonly fingerprint: Readonly<Record<string, unknown>>;
100
+ }
101
+
102
+ /** One list response: a page in the default order, or the whole set sorted by another field. */
103
+ export async function readWorkflowExecutionList(
104
+ read: WorkflowExecutionListRead,
105
+ ): Promise<WorkflowExecutionList> {
106
+ const scope = (
107
+ executions: WorkflowExecution[],
108
+ ): Promise<WorkflowExecution[]> =>
109
+ restrictListByReadScope(
110
+ read.listReadScope,
111
+ read.identity,
112
+ ApiResourceKind.workflow_execution,
113
+ executions,
114
+ "",
115
+ );
116
+
117
+ if (read.sortField === ExecutionSortField.UNSPECIFIED) {
118
+ const page = await readListPage({
119
+ store: read.store,
120
+ declaration: workflowExecutionListIndex,
121
+ query: read.query,
122
+ request: read.request,
123
+ fingerprint: listPageFingerprint(read.fingerprint),
124
+ decode: (data) => decodeWorkflowExecution(data, read.logger),
125
+ keep: read.keep,
126
+ scope,
127
+ failure: "failed to list workflow executions",
128
+ });
129
+ return create(WorkflowExecutionListSchema, {
130
+ entries: page.entries,
131
+ nextPageToken: page.nextPageToken,
132
+ totalPages: page.nextPageToken === "" ? 1 : 0,
133
+ });
134
+ }
135
+
136
+ // Another sort field never issues a token, so none can be continued.
137
+ if (read.request.pageToken !== "") {
138
+ throw invalidArgumentError("invalid page_token");
139
+ }
140
+ if (read.request.pageSize < 0) {
141
+ throw invalidArgumentError("page_size must not be negative");
142
+ }
143
+ const executions = await scope(
144
+ (
145
+ await loadWorkflowExecutions(
146
+ read.store,
147
+ read.logger,
148
+ read.query,
149
+ "failed to list workflow executions",
150
+ )
151
+ ).filter(read.keep),
152
+ );
153
+ applySortField(executions, read.sortField, read.sortAscending);
154
+ const size = Math.min(read.request.pageSize, LIST_PAGE_MAX_SIZE);
155
+ return create(WorkflowExecutionListSchema, {
156
+ entries: size === 0 ? executions : executions.slice(0, size),
157
+ totalPages: 1,
158
+ });
159
+ }
@@ -1,20 +1,26 @@
1
1
  /**
2
2
  * Named-key loader — ports pkg/encryption/keymanager.go.
3
3
  *
4
- * One convention for every 32-byte key the server holds (sub-project
5
- * DD-002): env var (Base64) → ~/.stigmer/<file> (raw bytes, 0600) →
6
- * auto-generate and persist. The loader is generalized over the env var
7
- * and file name so sibling key material (the runner-token signing key,
8
- * oss#535) rides the same ladder instead of growing a divergent loader.
4
+ * One convention for every key the server holds: env var (Base64) →
5
+ * ~/.stigmer/<file> (0600) → auto-generate and persist. The
6
+ * loader is generalized over the env var, the file name and a KeyCodec so
7
+ * sibling key material rides the same ladder instead of growing a
8
+ * divergent loader: the runner-token signing key (oss#535) and the
9
+ * encryption key are 32 raw bytes (RAW_32_BYTE_KEY); the platform-token
10
+ * signing key is an RSA private key (platformtoken/key-ring.ts). The codec
11
+ * says what a key IS — how an env value and a file decode, how one is
12
+ * generated and written — and nothing about the ladder, which stays one.
9
13
  *
10
- * Ladder semantics, exactly Go's:
14
+ * Ladder semantics, exactly Go's, for every codec:
11
15
  * - An EXPLICITLY configured env key that is unusable (bad Base64, wrong
12
- * length) is an ERROR, never a degrade — silently ignoring deliberate
13
- * configuration would be worse than refusing to boot.
16
+ * length, not the key type the codec holds) is an ERROR, never a
17
+ * degrade — silently ignoring deliberate configuration would be worse
18
+ * than refusing to boot.
14
19
  * - A key file that fails its load checks (permissions other than 0600,
15
- * wrong size) is never adopted; the ladder FALLS THROUGH to
16
- * auto-generate, which overwrites the file's content — Go's shipped
17
- * behavior (loadKeyFromFile error → generate → save), ported as-is.
20
+ * content the codec does not accept) is never adopted; the ladder
21
+ * FALLS THROUGH to auto-generate, which overwrites the file's content —
22
+ * Go's shipped behavior (loadKeyFromFile error → generate → save),
23
+ * ported as-is.
18
24
  * - Auto-generation persists for future boots; a persist FAILURE is a
19
25
  * stderr warning only — the key is still usable for this process.
20
26
  *
@@ -50,34 +56,81 @@ export interface KeyLoaderOptions {
50
56
  }
51
57
 
52
58
  /**
53
- * Go GetOrCreateNamedKey: env var → key file → auto-generate. Throws only
54
- * on unusable EXPLICIT configuration (bad env value) or when no key can be
55
- * produced at all.
59
+ * What one kind of key is, for the ladder. `fromEnv` receives the env
60
+ * value already strictly Base64-decoded and THROWS when the bytes are not
61
+ * a usable key (explicit configuration is never silently ignored);
62
+ * `fromFile` answers `undefined` for content it does not accept, so the
63
+ * ladder falls through exactly as it does for a wrong-sized raw key.
64
+ */
65
+ export interface KeyCodec<Key> {
66
+ fromEnv(envVar: string, decoded: Buffer): Key;
67
+ fromFile(content: Buffer): Key | undefined;
68
+ generate(): Key;
69
+ toFile(key: Key): Buffer;
70
+ }
71
+
72
+ /** The 32 raw bytes the encryption and runner-token keys are. */
73
+ export const RAW_32_BYTE_KEY: KeyCodec<Buffer> = {
74
+ fromEnv(envVar, decoded) {
75
+ if (decoded.length !== KEY_SIZE) {
76
+ throw new Error(
77
+ `${envVar} must be exactly 32 bytes (256 bits) when decoded, got ${decoded.length} bytes`,
78
+ );
79
+ }
80
+ return decoded;
81
+ },
82
+ fromFile(content) {
83
+ return content.length === KEY_SIZE ? content : undefined;
84
+ },
85
+ generate() {
86
+ return randomBytes(KEY_SIZE);
87
+ },
88
+ toFile(key) {
89
+ return key;
90
+ },
91
+ };
92
+
93
+ /**
94
+ * Go GetOrCreateNamedKey: env var → key file → auto-generate, for a 32-byte
95
+ * raw key. Throws only on unusable EXPLICIT configuration (bad env value)
96
+ * or when no key can be produced at all.
56
97
  */
57
98
  export function getOrCreateNamedKey(
58
99
  envVar: string,
59
100
  fileName: string,
60
101
  options: KeyLoaderOptions = {},
61
102
  ): Buffer {
103
+ return getOrCreateKey(RAW_32_BYTE_KEY, envVar, fileName, options);
104
+ }
105
+
106
+ /** The ladder over any codec: env var → key file → auto-generate. */
107
+ export function getOrCreateKey<Key>(
108
+ codec: KeyCodec<Key>,
109
+ envVar: string,
110
+ fileName: string,
111
+ options: KeyLoaderOptions = {},
112
+ ): Key {
62
113
  const env = options.env ?? process.env;
63
114
 
64
- // 1. Environment variable (highest priority) — Base64-encoded 32 bytes.
115
+ // 1. Environment variable (highest priority) — Base64-encoded.
65
116
  const envValue = env[envVar];
66
117
  if (envValue !== undefined && envValue !== "") {
67
- return decodeEnvKey(envVar, envValue);
118
+ return codec.fromEnv(envVar, decodeEnvBase64(envVar, envValue));
68
119
  }
69
120
 
70
- // 2. Local key file — raw 32 bytes, refused on insecure permissions.
121
+ // 2. Local key file — refused on insecure permissions or content the
122
+ // codec does not accept.
71
123
  const keyPath = namedKeyFilePath(fileName, options);
72
- const fromFile = loadKeyFromFile(keyPath);
124
+ const content = readKeyFile(keyPath);
125
+ const fromFile = content === undefined ? undefined : codec.fromFile(content);
73
126
  if (fromFile !== undefined) {
74
127
  return fromFile;
75
128
  }
76
129
 
77
130
  // 3. Auto-generate (local development); persist for future boots.
78
- const key = randomBytes(KEY_SIZE);
131
+ const key = codec.generate();
79
132
  try {
80
- saveKeyToFile(keyPath, key);
133
+ saveKeyToFile(keyPath, codec.toFile(key));
81
134
  } catch (error) {
82
135
  // Warn but don't fail — the key is still usable (Go's posture).
83
136
  process.stderr.write(
@@ -87,22 +140,17 @@ export function getOrCreateNamedKey(
87
140
  return key;
88
141
  }
89
142
 
90
- /** Strict Base64 decode + length check for an env-configured key. */
91
- function decodeEnvKey(envVar: string, value: string): Buffer {
92
- const key = Buffer.from(value, "base64");
143
+ /** Strict Base64 decode for an env-configured key. */
144
+ function decodeEnvBase64(envVar: string, value: string): Buffer {
145
+ const decoded = Buffer.from(value, "base64");
93
146
  // Node's base64 decoder is lenient (skips invalid characters, accepts
94
147
  // missing padding) and never throws; Go's StdEncoding errors on any
95
148
  // non-canonical input. Round-tripping — Buffer always re-emits the
96
149
  // canonical padded form — restores Go's strictness.
97
- if (key.toString("base64") !== value) {
150
+ if (decoded.toString("base64") !== value) {
98
151
  throw new Error(`invalid Base64 encoding in ${envVar}`);
99
152
  }
100
- if (key.length !== KEY_SIZE) {
101
- throw new Error(
102
- `${envVar} must be exactly 32 bytes (256 bits) when decoded, got ${key.length} bytes`,
103
- );
104
- }
105
- return key;
153
+ return decoded;
106
154
  }
107
155
 
108
156
  /** Path to a named key file under <home>/.stigmer. */
@@ -115,13 +163,13 @@ export function namedKeyFilePath(
115
163
  }
116
164
 
117
165
  /**
118
- * Reads raw key bytes, mirroring Go loadKeyFromFile: missing file →
119
- * undefined (fall through the ladder); present-but-wrong (insecure
120
- * permissions, wrong size) also falls through — exactly Go's behavior,
121
- * where any load error falls to auto-generate. The 0600 check is skipped
122
- * on Windows, where POSIX modes are not meaningful.
166
+ * Reads a key file's bytes, mirroring Go loadKeyFromFile: missing file →
167
+ * undefined (fall through the ladder); present with insecure permissions
168
+ * also falls through — exactly Go's behavior, where any load error falls
169
+ * to auto-generate. The 0600 check is skipped on Windows, where POSIX
170
+ * modes are not meaningful.
123
171
  */
124
- function loadKeyFromFile(keyPath: string): Buffer | undefined {
172
+ function readKeyFile(keyPath: string): Buffer | undefined {
125
173
  let stat: fs.Stats;
126
174
  try {
127
175
  stat = fs.statSync(keyPath);
@@ -134,23 +182,18 @@ function loadKeyFromFile(keyPath: string): Buffer | undefined {
134
182
  return undefined;
135
183
  }
136
184
  }
137
- let key: Buffer;
138
185
  try {
139
- key = fs.readFileSync(keyPath);
186
+ return fs.readFileSync(keyPath);
140
187
  } catch {
141
188
  return undefined;
142
189
  }
143
- if (key.length !== KEY_SIZE) {
144
- return undefined;
145
- }
146
- return key;
147
190
  }
148
191
 
149
192
  /** Writes the key with secure permissions (dir 0700, file 0600). */
150
- function saveKeyToFile(keyPath: string, key: Buffer): void {
193
+ function saveKeyToFile(keyPath: string, content: Buffer): void {
151
194
  fs.mkdirSync(path.dirname(keyPath), {
152
195
  recursive: true,
153
196
  mode: KEY_DIR_PERMISSIONS,
154
197
  });
155
- fs.writeFileSync(keyPath, key, { mode: KEY_FILE_PERMISSIONS });
198
+ fs.writeFileSync(keyPath, content, { mode: KEY_FILE_PERMISSIONS });
156
199
  }
@@ -549,8 +549,9 @@ describe("extension composition (require-authentication posture)", () => {
549
549
  // composes its Authorizer, and with it the runner-subject verifier
550
550
  // between the API-key lane and the unit's own (runnerauth/
551
551
  // runner-subject-verifier.ts). A unit with its own Authorizer gets
552
- // neither (runner-subject-composed.test.ts pins that chain).
553
- expect(parsed.verifiers).toBe("apikey, runner, fake-verifier");
552
+ // neither (runner-subject-composed.test.ts pins that chain). The
553
+ // PlatformClient lane rides the posture itself, ahead of both.
554
+ expect(parsed.verifiers).toBe("apikey, platform-client, runner, fake-verifier");
554
555
  });
555
556
 
556
557
  it("a declared posture whose unit registers no verifier of its own is a boot throw naming the unit — the API-key lane alone cannot bootstrap", async () => {