@stigmer/server 3.40.0 → 3.41.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 (528) hide show
  1. package/dist/authorization/authorizer.d.ts +16 -10
  2. package/dist/authorization/authorizer.d.ts.map +1 -1
  3. package/dist/authorization/authorizer.js +17 -9
  4. package/dist/authorization/authorizer.js.map +1 -1
  5. package/dist/authorization/derived-tuples.d.ts +7 -3
  6. package/dist/authorization/derived-tuples.d.ts.map +1 -1
  7. package/dist/authorization/derived-tuples.js +62 -6
  8. package/dist/authorization/derived-tuples.js.map +1 -1
  9. package/dist/authorization/evaluator.d.ts +11 -7
  10. package/dist/authorization/evaluator.d.ts.map +1 -1
  11. package/dist/authorization/evaluator.js +16 -10
  12. package/dist/authorization/evaluator.js.map +1 -1
  13. package/dist/authorization/list-read-scope.d.ts +4 -0
  14. package/dist/authorization/list-read-scope.d.ts.map +1 -1
  15. package/dist/authorization/list-read-scope.js +1 -0
  16. package/dist/authorization/list-read-scope.js.map +1 -1
  17. package/dist/authorization/model/data/authorization-model.json +830 -67
  18. package/dist/authorization/model/execution-viewer.d.ts.map +1 -1
  19. package/dist/authorization/model/execution-viewer.js +26 -24
  20. package/dist/authorization/model/execution-viewer.js.map +1 -1
  21. package/dist/authorization/model/index.d.ts +4 -1
  22. package/dist/authorization/model/index.d.ts.map +1 -1
  23. package/dist/authorization/model/index.js +4 -1
  24. package/dist/authorization/model/index.js.map +1 -1
  25. package/dist/authorization/model/rewrite.d.ts +5 -3
  26. package/dist/authorization/model/rewrite.d.ts.map +1 -1
  27. package/dist/authorization/organization-directory.d.ts +44 -0
  28. package/dist/authorization/organization-directory.d.ts.map +1 -1
  29. package/dist/authorization/organization-directory.js +1 -0
  30. package/dist/authorization/organization-directory.js.map +1 -1
  31. package/dist/authorization/person.d.ts +14 -1
  32. package/dist/authorization/person.d.ts.map +1 -1
  33. package/dist/authorization/person.js +16 -0
  34. package/dist/authorization/person.js.map +1 -1
  35. package/dist/authorization/policy-check.d.ts +52 -0
  36. package/dist/authorization/policy-check.d.ts.map +1 -0
  37. package/dist/authorization/policy-check.js +35 -0
  38. package/dist/authorization/policy-check.js.map +1 -0
  39. package/dist/authorization/posture.d.ts +30 -4
  40. package/dist/authorization/posture.d.ts.map +1 -1
  41. package/dist/authorization/posture.js +58 -0
  42. package/dist/authorization/posture.js.map +1 -1
  43. package/dist/authorization/resource-creators.d.ts +4 -0
  44. package/dist/authorization/resource-creators.d.ts.map +1 -0
  45. package/dist/authorization/resource-creators.js +44 -0
  46. package/dist/authorization/resource-creators.js.map +1 -0
  47. package/dist/authorization/trusted-local-authorizer.d.ts +9 -0
  48. package/dist/authorization/trusted-local-authorizer.d.ts.map +1 -0
  49. package/dist/authorization/trusted-local-authorizer.js +70 -0
  50. package/dist/authorization/trusted-local-authorizer.js.map +1 -0
  51. package/dist/authorization/tuples.d.ts +12 -0
  52. package/dist/authorization/tuples.d.ts.map +1 -1
  53. package/dist/authorization/tuples.js +3 -0
  54. package/dist/authorization/tuples.js.map +1 -1
  55. package/dist/boot/compose.d.ts.map +1 -1
  56. package/dist/boot/compose.js +133 -43
  57. package/dist/boot/compose.js.map +1 -1
  58. package/dist/boot/config.d.ts +22 -7
  59. package/dist/boot/config.d.ts.map +1 -1
  60. package/dist/boot/config.js +2 -1
  61. package/dist/boot/config.js.map +1 -1
  62. package/dist/boot/inprocess.d.ts.map +1 -1
  63. package/dist/boot/inprocess.js +10 -4
  64. package/dist/boot/inprocess.js.map +1 -1
  65. package/dist/boot/list-indexes.d.ts.map +1 -1
  66. package/dist/boot/list-indexes.js +6 -1
  67. package/dist/boot/list-indexes.js.map +1 -1
  68. package/dist/boot/logger.d.ts +3 -1
  69. package/dist/boot/logger.d.ts.map +1 -1
  70. package/dist/boot/logger.js +3 -1
  71. package/dist/boot/logger.js.map +1 -1
  72. package/dist/boot/oauth-redirect-uri.d.ts +33 -12
  73. package/dist/boot/oauth-redirect-uri.d.ts.map +1 -1
  74. package/dist/boot/oauth-redirect-uri.js +43 -14
  75. package/dist/boot/oauth-redirect-uri.js.map +1 -1
  76. package/dist/boot/skill-transfer-origin.d.ts +46 -14
  77. package/dist/boot/skill-transfer-origin.d.ts.map +1 -1
  78. package/dist/boot/skill-transfer-origin.js +53 -13
  79. package/dist/boot/skill-transfer-origin.js.map +1 -1
  80. package/dist/domain/agentchannel/steps.d.ts +8 -6
  81. package/dist/domain/agentchannel/steps.d.ts.map +1 -1
  82. package/dist/domain/agentchannel/steps.js +9 -7
  83. package/dist/domain/agentchannel/steps.js.map +1 -1
  84. package/dist/domain/agentexecution/controller.d.ts +7 -0
  85. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  86. package/dist/domain/agentexecution/controller.js +1 -1
  87. package/dist/domain/agentexecution/controller.js.map +1 -1
  88. package/dist/domain/agentexecution/create-steps.d.ts +26 -12
  89. package/dist/domain/agentexecution/create-steps.d.ts.map +1 -1
  90. package/dist/domain/agentexecution/create-steps.js +61 -43
  91. package/dist/domain/agentexecution/create-steps.js.map +1 -1
  92. package/dist/domain/agentexecution/submit-approval.d.ts.map +1 -1
  93. package/dist/domain/agentexecution/submit-approval.js +9 -6
  94. package/dist/domain/agentexecution/submit-approval.js.map +1 -1
  95. package/dist/domain/agentexecution/submit-file-decision.d.ts.map +1 -1
  96. package/dist/domain/agentexecution/submit-file-decision.js +5 -4
  97. package/dist/domain/agentexecution/submit-file-decision.js.map +1 -1
  98. package/dist/domain/agentshare/steps.d.ts +5 -3
  99. package/dist/domain/agentshare/steps.d.ts.map +1 -1
  100. package/dist/domain/agentshare/steps.js +6 -4
  101. package/dist/domain/agentshare/steps.js.map +1 -1
  102. package/dist/domain/apikey/verifier.d.ts +7 -0
  103. package/dist/domain/apikey/verifier.d.ts.map +1 -1
  104. package/dist/domain/apikey/verifier.js +34 -1
  105. package/dist/domain/apikey/verifier.js.map +1 -1
  106. package/dist/domain/channelapp/controller.d.ts +9 -4
  107. package/dist/domain/channelapp/controller.d.ts.map +1 -1
  108. package/dist/domain/channelapp/controller.js +19 -9
  109. package/dist/domain/channelapp/controller.js.map +1 -1
  110. package/dist/domain/executioncontext/steps.d.ts +2 -1
  111. package/dist/domain/executioncontext/steps.d.ts.map +1 -1
  112. package/dist/domain/executioncontext/steps.js +2 -1
  113. package/dist/domain/executioncontext/steps.js.map +1 -1
  114. package/dist/domain/iampolicy/access-lists.d.ts.map +1 -1
  115. package/dist/domain/iampolicy/access-lists.js +57 -2
  116. package/dist/domain/iampolicy/access-lists.js.map +1 -1
  117. package/dist/domain/iampolicy/change.d.ts +53 -0
  118. package/dist/domain/iampolicy/change.d.ts.map +1 -0
  119. package/dist/domain/iampolicy/change.js +44 -0
  120. package/dist/domain/iampolicy/change.js.map +1 -0
  121. package/dist/domain/iampolicy/constants.d.ts +6 -0
  122. package/dist/domain/iampolicy/constants.d.ts.map +1 -1
  123. package/dist/domain/iampolicy/constants.js +6 -0
  124. package/dist/domain/iampolicy/constants.js.map +1 -1
  125. package/dist/domain/iampolicy/controller.d.ts.map +1 -1
  126. package/dist/domain/iampolicy/controller.js +9 -5
  127. package/dist/domain/iampolicy/controller.js.map +1 -1
  128. package/dist/domain/iampolicy/grant-path.d.ts +31 -13
  129. package/dist/domain/iampolicy/grant-path.d.ts.map +1 -1
  130. package/dist/domain/iampolicy/grant-path.js +216 -19
  131. package/dist/domain/iampolicy/grant-path.js.map +1 -1
  132. package/dist/domain/iampolicy/membership.d.ts +11 -3
  133. package/dist/domain/iampolicy/membership.d.ts.map +1 -1
  134. package/dist/domain/iampolicy/membership.js +18 -13
  135. package/dist/domain/iampolicy/membership.js.map +1 -1
  136. package/dist/domain/iampolicy/resource-store.d.ts.map +1 -1
  137. package/dist/domain/iampolicy/resource-store.js +4 -0
  138. package/dist/domain/iampolicy/resource-store.js.map +1 -1
  139. package/dist/domain/iampolicy/role-lifecycle.d.ts.map +1 -1
  140. package/dist/domain/iampolicy/role-lifecycle.js +2 -2
  141. package/dist/domain/iampolicy/role-lifecycle.js.map +1 -1
  142. package/dist/domain/iampolicy/roles.d.ts.map +1 -1
  143. package/dist/domain/iampolicy/roles.js +7 -0
  144. package/dist/domain/iampolicy/roles.js.map +1 -1
  145. package/dist/domain/iampolicy/steps.d.ts +4 -3
  146. package/dist/domain/iampolicy/steps.d.ts.map +1 -1
  147. package/dist/domain/iampolicy/steps.js +7 -7
  148. package/dist/domain/iampolicy/steps.js.map +1 -1
  149. package/dist/domain/iampolicy/store-contract.d.ts.map +1 -1
  150. package/dist/domain/iampolicy/store-contract.js +22 -1
  151. package/dist/domain/iampolicy/store-contract.js.map +1 -1
  152. package/dist/domain/iampolicy/store.d.ts +18 -5
  153. package/dist/domain/iampolicy/store.d.ts.map +1 -1
  154. package/dist/domain/iampolicy/store.js.map +1 -1
  155. package/dist/domain/identityaccount/constants.d.ts +15 -0
  156. package/dist/domain/identityaccount/constants.d.ts.map +1 -1
  157. package/dist/domain/identityaccount/constants.js +17 -0
  158. package/dist/domain/identityaccount/constants.js.map +1 -1
  159. package/dist/domain/identityaccount/controller.d.ts.map +1 -1
  160. package/dist/domain/identityaccount/controller.js +17 -6
  161. package/dist/domain/identityaccount/controller.js.map +1 -1
  162. package/dist/domain/identityaccount/resolve.d.ts +47 -0
  163. package/dist/domain/identityaccount/resolve.d.ts.map +1 -1
  164. package/dist/domain/identityaccount/resolve.js +38 -1
  165. package/dist/domain/identityaccount/resolve.js.map +1 -1
  166. package/dist/domain/identityaccount/resource-store.d.ts.map +1 -1
  167. package/dist/domain/identityaccount/resource-store.js +11 -1
  168. package/dist/domain/identityaccount/resource-store.js.map +1 -1
  169. package/dist/domain/identityaccount/steps.d.ts +2 -1
  170. package/dist/domain/identityaccount/steps.d.ts.map +1 -1
  171. package/dist/domain/identityaccount/steps.js +4 -3
  172. package/dist/domain/identityaccount/steps.js.map +1 -1
  173. package/dist/domain/identityaccount/store-contract.js +2 -2
  174. package/dist/domain/identityaccount/store-contract.js.map +1 -1
  175. package/dist/domain/identityaccount/store.d.ts +6 -1
  176. package/dist/domain/identityaccount/store.d.ts.map +1 -1
  177. package/dist/domain/mcpserver/connect-sandbox.d.ts +67 -0
  178. package/dist/domain/mcpserver/connect-sandbox.d.ts.map +1 -0
  179. package/dist/domain/mcpserver/connect-sandbox.js +64 -0
  180. package/dist/domain/mcpserver/connect-sandbox.js.map +1 -0
  181. package/dist/domain/mcpserver/connect.d.ts +42 -10
  182. package/dist/domain/mcpserver/connect.d.ts.map +1 -1
  183. package/dist/domain/mcpserver/connect.js +147 -40
  184. package/dist/domain/mcpserver/connect.js.map +1 -1
  185. package/dist/domain/mcpserver/controller.js +4 -2
  186. package/dist/domain/mcpserver/controller.js.map +1 -1
  187. package/dist/domain/mcpserver/engine.d.ts +26 -7
  188. package/dist/domain/mcpserver/engine.d.ts.map +1 -1
  189. package/dist/domain/mcpserver/engine.js.map +1 -1
  190. package/dist/domain/mcpserver/start-connect.d.ts +5 -0
  191. package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
  192. package/dist/domain/mcpserver/start-connect.js +38 -15
  193. package/dist/domain/mcpserver/start-connect.js.map +1 -1
  194. package/dist/domain/memory/controller.js +2 -1
  195. package/dist/domain/memory/controller.js.map +1 -1
  196. package/dist/domain/memory/list-index.d.ts +2 -0
  197. package/dist/domain/memory/list-index.d.ts.map +1 -0
  198. package/dist/domain/memory/list-index.js +31 -0
  199. package/dist/domain/memory/list-index.js.map +1 -0
  200. package/dist/domain/memory/queries.d.ts +10 -0
  201. package/dist/domain/memory/queries.d.ts.map +1 -0
  202. package/dist/domain/memory/queries.js +54 -0
  203. package/dist/domain/memory/queries.js.map +1 -0
  204. package/dist/domain/memory/steps.d.ts +13 -11
  205. package/dist/domain/memory/steps.d.ts.map +1 -1
  206. package/dist/domain/memory/steps.js +26 -57
  207. package/dist/domain/memory/steps.js.map +1 -1
  208. package/dist/domain/organization/steps.d.ts.map +1 -1
  209. package/dist/domain/organization/steps.js +1 -1
  210. package/dist/domain/organization/steps.js.map +1 -1
  211. package/dist/domain/platformclient/mint.d.ts.map +1 -1
  212. package/dist/domain/platformclient/mint.js +2 -2
  213. package/dist/domain/platformclient/mint.js.map +1 -1
  214. package/dist/domain/platformclient/verifier.d.ts.map +1 -1
  215. package/dist/domain/platformclient/verifier.js +6 -3
  216. package/dist/domain/platformclient/verifier.js.map +1 -1
  217. package/dist/domain/plugin/push.d.ts.map +1 -1
  218. package/dist/domain/plugin/push.js +1 -0
  219. package/dist/domain/plugin/push.js.map +1 -1
  220. package/dist/domain/schedule/steps.d.ts +3 -1
  221. package/dist/domain/schedule/steps.d.ts.map +1 -1
  222. package/dist/domain/schedule/steps.js +3 -1
  223. package/dist/domain/schedule/steps.js.map +1 -1
  224. package/dist/domain/skill/push.d.ts.map +1 -1
  225. package/dist/domain/skill/push.js +1 -0
  226. package/dist/domain/skill/push.js.map +1 -1
  227. package/dist/domain/workflow/registry/data/task-kind-registry.json +27 -1
  228. package/dist/domain/workflowexecution/submit-approval.d.ts +5 -2
  229. package/dist/domain/workflowexecution/submit-approval.d.ts.map +1 -1
  230. package/dist/domain/workflowexecution/submit-approval.js +1 -1
  231. package/dist/domain/workflowexecution/submit-approval.js.map +1 -1
  232. package/dist/domain/workflowexecution/submit-file-decision.d.ts +5 -2
  233. package/dist/domain/workflowexecution/submit-file-decision.d.ts.map +1 -1
  234. package/dist/domain/workflowexecution/submit-file-decision.js +1 -1
  235. package/dist/domain/workflowexecution/submit-file-decision.js.map +1 -1
  236. package/dist/domain/workflowexecution/submit-workflow-task-approval.d.ts.map +1 -1
  237. package/dist/domain/workflowexecution/submit-workflow-task-approval.js +12 -1
  238. package/dist/domain/workflowexecution/submit-workflow-task-approval.js.map +1 -1
  239. package/dist/domain/workflowinstance/controller.d.ts +6 -3
  240. package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
  241. package/dist/domain/workflowinstance/controller.js +12 -7
  242. package/dist/domain/workflowinstance/controller.js.map +1 -1
  243. package/dist/domain/workflowinstance/steps.d.ts +31 -0
  244. package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
  245. package/dist/domain/workflowinstance/steps.js +88 -1
  246. package/dist/domain/workflowinstance/steps.js.map +1 -1
  247. package/dist/extensions/composed-services.d.ts +56 -0
  248. package/dist/extensions/composed-services.d.ts.map +1 -0
  249. package/dist/extensions/composed-services.js +2 -0
  250. package/dist/extensions/composed-services.js.map +1 -0
  251. package/dist/extensions/drivers.d.ts +32 -1
  252. package/dist/extensions/drivers.d.ts.map +1 -1
  253. package/dist/extensions/identity.d.ts +4 -1
  254. package/dist/extensions/identity.d.ts.map +1 -1
  255. package/dist/extensions/identity.js +4 -1
  256. package/dist/extensions/identity.js.map +1 -1
  257. package/dist/extensions/registry.d.ts +37 -0
  258. package/dist/extensions/registry.d.ts.map +1 -1
  259. package/dist/extensions/registry.js +50 -0
  260. package/dist/extensions/registry.js.map +1 -1
  261. package/dist/extensions/resource-authorization.d.ts +78 -0
  262. package/dist/extensions/resource-authorization.d.ts.map +1 -1
  263. package/dist/extensions/resource-row-reader.d.ts +43 -0
  264. package/dist/extensions/resource-row-reader.d.ts.map +1 -0
  265. package/dist/extensions/resource-row-reader.js +2 -0
  266. package/dist/extensions/resource-row-reader.js.map +1 -0
  267. package/dist/extensions/visitor-classifier.d.ts +41 -0
  268. package/dist/extensions/visitor-classifier.d.ts.map +1 -0
  269. package/dist/extensions/visitor-classifier.js +2 -0
  270. package/dist/extensions/visitor-classifier.js.map +1 -0
  271. package/dist/identity/oidc-userinfo.d.ts +6 -1
  272. package/dist/identity/oidc-userinfo.d.ts.map +1 -1
  273. package/dist/identity/oidc-userinfo.js.map +1 -1
  274. package/dist/identity/oidc-verifier.d.ts.map +1 -1
  275. package/dist/identity/oidc-verifier.js +37 -8
  276. package/dist/identity/oidc-verifier.js.map +1 -1
  277. package/dist/index.d.ts +14 -6
  278. package/dist/index.d.ts.map +1 -1
  279. package/dist/index.js +25 -9
  280. package/dist/index.js.map +1 -1
  281. package/dist/pipeline/errors.d.ts +8 -0
  282. package/dist/pipeline/errors.d.ts.map +1 -1
  283. package/dist/pipeline/errors.js +25 -16
  284. package/dist/pipeline/errors.js.map +1 -1
  285. package/dist/pipeline/interceptors/auth.d.ts +17 -9
  286. package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
  287. package/dist/pipeline/interceptors/auth.js +17 -9
  288. package/dist/pipeline/interceptors/auth.js.map +1 -1
  289. package/dist/pipeline/steps/authorization-tuples.d.ts +23 -1
  290. package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
  291. package/dist/pipeline/steps/authorization-tuples.js +42 -0
  292. package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
  293. package/dist/pipeline/steps/authorize.d.ts +6 -5
  294. package/dist/pipeline/steps/authorize.d.ts.map +1 -1
  295. package/dist/pipeline/steps/authorize.js +6 -5
  296. package/dist/pipeline/steps/authorize.js.map +1 -1
  297. package/dist/pipeline/steps/defaults.d.ts +12 -0
  298. package/dist/pipeline/steps/defaults.d.ts.map +1 -1
  299. package/dist/pipeline/steps/defaults.js +42 -7
  300. package/dist/pipeline/steps/defaults.js.map +1 -1
  301. package/dist/pipeline/steps/guard-memory-capture.d.ts +13 -15
  302. package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
  303. package/dist/pipeline/steps/guard-memory-capture.js +2 -3
  304. package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
  305. package/dist/runnerauth/built-in-runner-credential-provider.d.ts +0 -2
  306. package/dist/runnerauth/built-in-runner-credential-provider.d.ts.map +1 -1
  307. package/dist/runnerauth/built-in-runner-credential-provider.js +8 -17
  308. package/dist/runnerauth/built-in-runner-credential-provider.js.map +1 -1
  309. package/dist/runnerauth/runner-credential-provider.d.ts +17 -7
  310. package/dist/runnerauth/runner-credential-provider.d.ts.map +1 -1
  311. package/dist/runnerauth/runner-credential-provider.js.map +1 -1
  312. package/dist/sandbox/docker.d.ts.map +1 -1
  313. package/dist/sandbox/docker.js +3 -0
  314. package/dist/sandbox/docker.js.map +1 -1
  315. package/dist/sandbox/kubernetes.d.ts.map +1 -1
  316. package/dist/sandbox/kubernetes.js +3 -0
  317. package/dist/sandbox/kubernetes.js.map +1 -1
  318. package/dist/sandbox/local-process.d.ts.map +1 -1
  319. package/dist/sandbox/local-process.js +4 -0
  320. package/dist/sandbox/local-process.js.map +1 -1
  321. package/dist/sandbox/provisioner.d.ts +18 -6
  322. package/dist/sandbox/provisioner.d.ts.map +1 -1
  323. package/dist/sandbox/provisioner.js.map +1 -1
  324. package/dist/temporal/manager.d.ts +5 -0
  325. package/dist/temporal/manager.d.ts.map +1 -1
  326. package/dist/temporal/manager.js +9 -0
  327. package/dist/temporal/manager.js.map +1 -1
  328. package/dist/temporal/mcpserver/engine-client.d.ts +2 -2
  329. package/dist/temporal/mcpserver/engine-client.d.ts.map +1 -1
  330. package/dist/temporal/mcpserver/engine-client.js +6 -4
  331. package/dist/temporal/mcpserver/engine-client.js.map +1 -1
  332. package/dist/temporal/mcpserver/names.d.ts +13 -2
  333. package/dist/temporal/mcpserver/names.d.ts.map +1 -1
  334. package/dist/temporal/mcpserver/names.js +15 -2
  335. package/dist/temporal/mcpserver/names.js.map +1 -1
  336. package/dist/temporal/sdk-logger.d.ts +74 -0
  337. package/dist/temporal/sdk-logger.d.ts.map +1 -0
  338. package/dist/temporal/sdk-logger.js +143 -0
  339. package/dist/temporal/sdk-logger.js.map +1 -0
  340. package/package.json +6 -6
  341. package/src/authorization/README.md +18 -6
  342. package/src/authorization/__tests__/authorizer.test.ts +5 -1
  343. package/src/authorization/__tests__/derived-tuples.test.ts +26 -0
  344. package/src/authorization/__tests__/evaluator.test.ts +4 -0
  345. package/src/authorization/__tests__/list-read-scope.test.ts +11 -5
  346. package/src/authorization/__tests__/store-tests.test.ts +3 -1
  347. package/src/authorization/__tests__/trusted-local-authorizer.test.ts +155 -0
  348. package/src/authorization/__tests__/unit-owned-kinds.test.ts +420 -0
  349. package/src/authorization/__tests__/wire-permissions.test.ts +31 -2
  350. package/src/authorization/authorizer.ts +21 -10
  351. package/src/authorization/derived-tuples.ts +92 -18
  352. package/src/authorization/evaluator.ts +30 -15
  353. package/src/authorization/list-read-scope.ts +4 -0
  354. package/src/authorization/model/__tests__/registry.test.ts +23 -0
  355. package/src/authorization/model/data/authorization-model.json +830 -67
  356. package/src/authorization/model/execution-viewer.ts +32 -27
  357. package/src/authorization/model/index.ts +4 -1
  358. package/src/authorization/model/rewrite.ts +5 -3
  359. package/src/authorization/organization-directory.ts +4 -0
  360. package/src/authorization/person.ts +32 -1
  361. package/src/authorization/policy-check.ts +105 -0
  362. package/src/authorization/posture.ts +45 -4
  363. package/src/authorization/resource-creators.ts +48 -0
  364. package/src/authorization/trusted-local-authorizer.ts +91 -0
  365. package/src/authorization/tuples.ts +17 -0
  366. package/src/boot/__tests__/compose.test.ts +120 -4
  367. package/src/boot/__tests__/list-indexes.test.ts +4 -0
  368. package/src/boot/__tests__/oauth-redirect-uri.test.ts +121 -10
  369. package/src/boot/__tests__/skill-transfer-origin.test.ts +96 -25
  370. package/src/boot/compose.ts +154 -61
  371. package/src/boot/config.ts +28 -12
  372. package/src/boot/inprocess.ts +18 -4
  373. package/src/boot/list-indexes.ts +6 -1
  374. package/src/boot/logger.ts +3 -1
  375. package/src/boot/oauth-redirect-uri.ts +62 -17
  376. package/src/boot/skill-transfer-origin.ts +71 -16
  377. package/src/domain/agent/__tests__/agent.test.ts +42 -1
  378. package/src/domain/agentchannel/__tests__/agentchannel.test.ts +9 -0
  379. package/src/domain/agentchannel/__tests__/channel-runtime.test.ts +2 -0
  380. package/src/domain/agentchannel/__tests__/create-authorization.test.ts +7 -6
  381. package/src/domain/agentchannel/steps.ts +9 -7
  382. package/src/domain/agentexecution/__tests__/agentexecution.test.ts +148 -56
  383. package/src/domain/agentexecution/__tests__/create-steps.test.ts +175 -12
  384. package/src/domain/agentexecution/__tests__/file-review-seed.ts +91 -0
  385. package/src/domain/agentexecution/controller.ts +8 -0
  386. package/src/domain/agentexecution/create-steps.ts +74 -44
  387. package/src/domain/agentexecution/submit-approval.ts +9 -6
  388. package/src/domain/agentexecution/submit-file-decision.ts +5 -4
  389. package/src/domain/agentinstance/__tests__/agentinstance.test.ts +2 -0
  390. package/src/domain/agentshare/__tests__/agentshare.test.ts +17 -0
  391. package/src/domain/agentshare/__tests__/create-authorization.test.ts +5 -4
  392. package/src/domain/agentshare/steps.ts +6 -4
  393. package/src/domain/apikey/__tests__/verifier.test.ts +73 -1
  394. package/src/domain/apikey/verifier.ts +45 -1
  395. package/src/domain/artifact/__tests__/artifact.test.ts +13 -24
  396. package/src/domain/channelapp/__tests__/channelapp.test.ts +7 -0
  397. package/src/domain/channelapp/controller.ts +35 -12
  398. package/src/domain/environment/__tests__/environment.test.ts +13 -0
  399. package/src/domain/executioncontext/__tests__/executioncontext.test.ts +2 -0
  400. package/src/domain/executioncontext/steps.ts +2 -1
  401. package/src/domain/iampolicy/__tests__/access-lists.test.ts +79 -0
  402. package/src/domain/iampolicy/__tests__/change.test.ts +63 -0
  403. package/src/domain/iampolicy/__tests__/controller.test.ts +39 -3
  404. package/src/domain/iampolicy/__tests__/grant-path.test.ts +595 -27
  405. package/src/domain/iampolicy/__tests__/iampolicy.test.ts +33 -2
  406. package/src/domain/iampolicy/__tests__/membership.test.ts +47 -5
  407. package/src/domain/iampolicy/__tests__/resource-store.test.ts +1 -0
  408. package/src/domain/iampolicy/__tests__/role-lifecycle.test.ts +41 -8
  409. package/src/domain/iampolicy/__tests__/roles.test.ts +3 -2
  410. package/src/domain/iampolicy/__tests__/steps.test.ts +75 -6
  411. package/src/domain/iampolicy/__tests__/support.ts +68 -4
  412. package/src/domain/iampolicy/access-lists.ts +70 -2
  413. package/src/domain/iampolicy/change.ts +109 -0
  414. package/src/domain/iampolicy/constants.ts +8 -0
  415. package/src/domain/iampolicy/controller.ts +17 -3
  416. package/src/domain/iampolicy/grant-path.ts +349 -31
  417. package/src/domain/iampolicy/membership.ts +32 -12
  418. package/src/domain/iampolicy/resource-store.ts +4 -0
  419. package/src/domain/iampolicy/role-lifecycle.ts +2 -0
  420. package/src/domain/iampolicy/roles.ts +8 -0
  421. package/src/domain/iampolicy/steps.ts +15 -5
  422. package/src/domain/iampolicy/store-contract.ts +37 -1
  423. package/src/domain/iampolicy/store.ts +19 -5
  424. package/src/domain/identityaccount/__tests__/resolve.test.ts +246 -2
  425. package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -1
  426. package/src/domain/identityaccount/constants.ts +20 -0
  427. package/src/domain/identityaccount/controller.ts +20 -5
  428. package/src/domain/identityaccount/resolve.ts +80 -1
  429. package/src/domain/identityaccount/resource-store.ts +14 -1
  430. package/src/domain/identityaccount/steps.ts +4 -3
  431. package/src/domain/identityaccount/store-contract.ts +4 -4
  432. package/src/domain/identityaccount/store.ts +6 -1
  433. package/src/domain/mcpserver/__tests__/connect-authorization.test.ts +1 -0
  434. package/src/domain/mcpserver/__tests__/connect.test.ts +358 -15
  435. package/src/domain/mcpserver/__tests__/mcpserver.test.ts +2 -0
  436. package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +2 -0
  437. package/src/domain/mcpserver/__tests__/store-faults.test.ts +2 -0
  438. package/src/domain/mcpserver/connect-sandbox.ts +135 -0
  439. package/src/domain/mcpserver/connect.ts +226 -56
  440. package/src/domain/mcpserver/controller.ts +8 -2
  441. package/src/domain/mcpserver/engine.ts +24 -6
  442. package/src/domain/mcpserver/start-connect.ts +49 -10
  443. package/src/domain/memory/__tests__/memory.test.ts +92 -22
  444. package/src/domain/memory/__tests__/queries.test.ts +173 -0
  445. package/src/domain/memory/controller.ts +2 -1
  446. package/src/domain/memory/list-index.ts +32 -0
  447. package/src/domain/memory/queries.ts +72 -0
  448. package/src/domain/memory/steps.ts +26 -63
  449. package/src/domain/oauthapp/__tests__/oauthapp.test.ts +14 -0
  450. package/src/domain/organization/__tests__/support.ts +41 -0
  451. package/src/domain/organization/steps.ts +1 -0
  452. package/src/domain/platformclient/mint.ts +6 -2
  453. package/src/domain/platformclient/verifier.ts +6 -3
  454. package/src/domain/plugin/__tests__/plugin.test.ts +11 -24
  455. package/src/domain/plugin/push.ts +1 -0
  456. package/src/domain/schedule/__tests__/schedule.composed.test.ts +2 -0
  457. package/src/domain/schedule/steps.ts +3 -1
  458. package/src/domain/session/__tests__/session.test.ts +2 -0
  459. package/src/domain/skill/__tests__/skill.test.ts +7 -25
  460. package/src/domain/skill/push.ts +1 -0
  461. package/src/domain/workflow/__tests__/workflow.test.ts +2 -0
  462. package/src/domain/workflow/registry/data/task-kind-registry.json +27 -1
  463. package/src/domain/workflowexecution/__tests__/forward-attribution-composed.test.ts +270 -0
  464. package/src/domain/workflowexecution/__tests__/submit-workflow-task-approval.test.ts +196 -0
  465. package/src/domain/workflowexecution/__tests__/workflowexecution.test.ts +3 -57
  466. package/src/domain/workflowexecution/submit-approval.ts +9 -2
  467. package/src/domain/workflowexecution/submit-file-decision.ts +6 -1
  468. package/src/domain/workflowexecution/submit-workflow-task-approval.ts +23 -5
  469. package/src/domain/workflowinstance/controller.ts +27 -9
  470. package/src/domain/workflowinstance/steps.ts +123 -1
  471. package/src/extensions/__tests__/apikey-before-sign-in-composed.test.ts +172 -0
  472. package/src/extensions/__tests__/built-in-authorization-composed.test.ts +80 -1
  473. package/src/extensions/__tests__/composed-services-composed.test.ts +236 -0
  474. package/src/extensions/__tests__/extension-composition.test.ts +229 -16
  475. package/src/extensions/__tests__/identity-account-composed.test.ts +84 -4
  476. package/src/extensions/__tests__/list-read-scope-composed.test.ts +41 -1
  477. package/src/extensions/__tests__/registry.test.ts +147 -1
  478. package/src/extensions/__tests__/secret-cleanup-composed.test.ts +2 -0
  479. package/src/extensions/__tests__/visitor-classifier-points.test.ts +42 -0
  480. package/src/extensions/composed-services.ts +61 -0
  481. package/src/extensions/drivers.ts +33 -1
  482. package/src/extensions/identity.ts +4 -1
  483. package/src/extensions/registry.ts +105 -0
  484. package/src/extensions/resource-authorization.ts +87 -0
  485. package/src/extensions/resource-row-reader.ts +43 -0
  486. package/src/extensions/visitor-classifier.ts +41 -0
  487. package/src/identity/__tests__/oidc-verifier.test.ts +38 -12
  488. package/src/identity/oidc-userinfo.ts +6 -1
  489. package/src/identity/oidc-verifier.ts +42 -8
  490. package/src/index.ts +61 -6
  491. package/src/pipeline/__tests__/steps.test.ts +31 -4
  492. package/src/pipeline/errors.ts +30 -16
  493. package/src/pipeline/interceptors/auth.ts +17 -9
  494. package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +20 -0
  495. package/src/pipeline/steps/__tests__/guard-memory-capture.test.ts +72 -15
  496. package/src/pipeline/steps/authorization-tuples.ts +54 -0
  497. package/src/pipeline/steps/authorize.ts +6 -5
  498. package/src/pipeline/steps/defaults.ts +52 -7
  499. package/src/pipeline/steps/guard-memory-capture.ts +15 -20
  500. package/src/runnerauth/__tests__/built-in-runner-credential-provider.test.ts +1 -1
  501. package/src/runnerauth/__tests__/runner-subject-composed.test.ts +13 -0
  502. package/src/runnerauth/bound-execution.ts +2 -2
  503. package/src/runnerauth/built-in-runner-credential-provider.ts +8 -21
  504. package/src/runnerauth/runner-credential-provider.ts +17 -7
  505. package/src/sandbox/__tests__/docker.integration.test.ts +4 -0
  506. package/src/sandbox/__tests__/kubernetes.test.ts +18 -1
  507. package/src/sandbox/__tests__/local-process.integration.test.ts +4 -0
  508. package/src/sandbox/__tests__/provisioner.test.ts +1 -0
  509. package/src/sandbox/docker.ts +3 -0
  510. package/src/sandbox/kubernetes.ts +3 -0
  511. package/src/sandbox/local-process.ts +4 -0
  512. package/src/sandbox/provisioner.ts +18 -6
  513. package/src/store/postgres/__tests__/support.ts +11 -2
  514. package/src/temporal/README.md +1 -0
  515. package/src/temporal/__tests__/manager.test.ts +56 -4
  516. package/src/temporal/__tests__/sdk-log-workflows.ts +26 -0
  517. package/src/temporal/__tests__/sdk-logger.e2e.test.ts +150 -0
  518. package/src/temporal/__tests__/sdk-logger.test.ts +238 -0
  519. package/src/temporal/manager.ts +9 -0
  520. package/src/temporal/mcpserver/engine-client.ts +8 -3
  521. package/src/temporal/mcpserver/names.ts +16 -2
  522. package/src/temporal/sdk-logger.ts +173 -0
  523. package/dist/authorization/lane-admission.d.ts +0 -50
  524. package/dist/authorization/lane-admission.d.ts.map +0 -1
  525. package/dist/authorization/lane-admission.js +0 -13
  526. package/dist/authorization/lane-admission.js.map +0 -1
  527. package/src/authorization/__tests__/lane-admission.test.ts +0 -115
  528. package/src/authorization/lane-admission.ts +0 -73
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Pins the two unit points and the edition's sign-in rule on real boots
3
+ * (extensions/composed-services.ts, boot/compose.ts):
4
+ *
5
+ * - `onComposed` hands every unit the composition's own instances before
6
+ * `composeServer` returns: the very Authorizer a unit registered, its
7
+ * list scope, its engine's check and its lifecycle, and the one
8
+ * in-process transport; under open source's own authorization, the
9
+ * built-in Authorizer, list scope and policy check.
10
+ * - `start` runs in unit order, first in `start()`, before the server
11
+ * reports SERVING; a failing start fails `start()`, naming its unit.
12
+ * - An edition above open source with no sign-in is refused at boot,
13
+ * whichever authorizer it runs.
14
+ */
15
+ import { generateKeyPairSync } from "node:crypto";
16
+ import { mkdtempSync, rmSync } from "node:fs";
17
+ import { tmpdir } from "node:os";
18
+ import path from "node:path";
19
+
20
+ import { afterEach, describe, expect, it } from "vitest";
21
+
22
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
23
+ import { HealthCheckResponse_ServingStatus } from "@stigmer/protos/grpc/health/v1/health_pb";
24
+ import { ServerEdition } from "@stigmer/protos/ai/stigmer/platform/v1/server_info_pb";
25
+
26
+ import { loadConfig } from "../../boot/config.js";
27
+ import { composeServer } from "../../boot/compose.js";
28
+ import type { ComposedServer } from "../../boot/compose.js";
29
+ import { createLogger } from "../../boot/logger.js";
30
+ import { newPermissiveSingleTeamAuthorizer } from "../../pipeline/steps/authorize.js";
31
+ import { platformTokenKeyRingFromPem } from "../../platformtoken/key-ring.js";
32
+ import type { AuthorizationQueryEngine } from "../authorization-queries.js";
33
+ import type { ComposedServices } from "../composed-services.js";
34
+ import type { IdentityVerifier } from "../identity.js";
35
+ import type { ListReadScope } from "../list-read-scope.js";
36
+ import type { ServerExtension } from "../registry.js";
37
+ import type { ResourceAuthorizationLifecycle } from "../resource-authorization.js";
38
+ import type { ResourceRowReader } from "../resource-row-reader.js";
39
+
40
+ const silentLogger = createLogger({
41
+ level: "error",
42
+ pretty: false,
43
+ write: () => {},
44
+ });
45
+
46
+ const verifier: IdentityVerifier = {
47
+ name: "fixture-verifier",
48
+ verify: () => Promise.resolve(null),
49
+ };
50
+ const ringKeys = generateKeyPairSync("rsa", { modulusLength: 2048 });
51
+ const RING = platformTokenKeyRingFromPem({
52
+ privateKeyPem: ringKeys.privateKey
53
+ .export({ format: "pem", type: "pkcs8" })
54
+ .toString(),
55
+ publicKeyPems: [
56
+ ringKeys.publicKey.export({ format: "pem", type: "spki" }).toString(),
57
+ ],
58
+ });
59
+ const noRows: ResourceRowReader = {
60
+ findById: () => Promise.resolve(undefined),
61
+ };
62
+
63
+ /** An Enterprise unit on open source's own authorization: sign-in, a key ring, a reader per kind. */
64
+ function enterpriseUnit(extra: Partial<ServerExtension> = {}): ServerExtension {
65
+ return {
66
+ name: "enterprise-fixture",
67
+ edition: ServerEdition.enterprise,
68
+ requireAuthentication: true,
69
+ identityVerifiers: [verifier],
70
+ drivers: {
71
+ platformTokenKeys: RING,
72
+ resourceRowReaders: new Map([
73
+ [ApiResourceKind.identity_provider, noRows],
74
+ [ApiResourceKind.invitation, noRows],
75
+ [ApiResourceKind.team, noRows],
76
+ ]),
77
+ },
78
+ ...extra,
79
+ };
80
+ }
81
+
82
+ const dirs: string[] = [];
83
+ const servers: ComposedServer[] = [];
84
+
85
+ async function compose(
86
+ extensions: ReadonlyArray<ServerExtension>,
87
+ ): Promise<ComposedServer> {
88
+ const dir = mkdtempSync(path.join(tmpdir(), "composed-services-"));
89
+ dirs.push(dir);
90
+ const server = await composeServer({
91
+ config: loadConfig({
92
+ STIGMER_MODEL_REGISTRY_REFRESH: "off",
93
+ DB_PATH: path.join(dir, "stigmer.db"),
94
+ ARTIFACT_LOCAL_BASE_PATH: path.join(dir, "artifacts"),
95
+ }),
96
+ logger: silentLogger,
97
+ extensions: [...extensions],
98
+ portOverride: 0,
99
+ host: "127.0.0.1",
100
+ });
101
+ servers.push(server);
102
+ return server;
103
+ }
104
+
105
+ afterEach(async () => {
106
+ for (const server of servers.splice(0)) {
107
+ await server.shutdown();
108
+ }
109
+ for (const dir of dirs.splice(0)) {
110
+ rmSync(dir, { recursive: true, force: true });
111
+ }
112
+ });
113
+
114
+ describe("onComposed: a unit receives the composition's own instances", () => {
115
+ it("hands a unit the very Authorizer, list scope, check and lifecycle a unit registered, and the one in-process transport, before composeServer returns", async () => {
116
+ const authorizer = newPermissiveSingleTeamAuthorizer();
117
+ const listReadScope: ListReadScope = {
118
+ authorizedResourceIds: () => Promise.resolve(new Set()),
119
+ restrictListEntries: () => Promise.resolve(new Set()),
120
+ };
121
+ const queries: AuthorizationQueryEngine = {
122
+ check: () => Promise.resolve(true),
123
+ listResourceIds: () => Promise.resolve([]),
124
+ listPrincipalIds: () => Promise.resolve([]),
125
+ };
126
+ const lifecycle: ResourceAuthorizationLifecycle = {
127
+ onResourceCreated: () => Promise.resolve(),
128
+ onResourceDeleted: () => Promise.resolve(),
129
+ onVisibilityChanged: () => Promise.resolve(),
130
+ };
131
+ let received: ComposedServices | undefined;
132
+ const server = await compose([
133
+ {
134
+ name: "cloud-shaped",
135
+ edition: ServerEdition.cloud,
136
+ requireAuthentication: true,
137
+ identityVerifiers: [verifier],
138
+ authorizer,
139
+ drivers: {
140
+ platformTokenKeys: RING,
141
+ listReadScope,
142
+ authorizationQueries: queries,
143
+ resourceAuthorizationLifecycle: lifecycle,
144
+ },
145
+ },
146
+ {
147
+ name: "consumer",
148
+ onComposed: (composed) => {
149
+ received = composed;
150
+ },
151
+ },
152
+ ]);
153
+ expect(received).toBeDefined();
154
+ expect(received?.authorizer).toBe(authorizer);
155
+ expect(received?.listReadScope).toBe(listReadScope);
156
+ expect(received?.authorizationQueries).toBe(queries);
157
+ expect(received?.resourceAuthorizationLifecycle).toBe(lifecycle);
158
+ expect(received?.inProcessTransport).toBe(server.inProcessTransport);
159
+ });
160
+
161
+ it("under open source's own authorization hands the built-in Authorizer, list scope and policy check, and no lifecycle", async () => {
162
+ let received: ComposedServices | undefined;
163
+ await compose([
164
+ enterpriseUnit({
165
+ onComposed: (composed) => {
166
+ received = composed;
167
+ },
168
+ }),
169
+ ]);
170
+ expect(received?.authorizer).toBeDefined();
171
+ expect(received?.listReadScope).toBeDefined();
172
+ expect(received?.authorizationQueries).toBeDefined();
173
+ expect(received?.resourceAuthorizationLifecycle).toBeUndefined();
174
+ });
175
+ });
176
+
177
+ describe("start: a unit's boot work runs before anything serves", () => {
178
+ it("runs each unit's start in unit order, before the server reports SERVING", async () => {
179
+ const seen: string[] = [];
180
+ let server: ComposedServer | undefined;
181
+ const observe = (unit: string) => (): Promise<void> => {
182
+ seen.push(
183
+ `${unit}:${HealthCheckResponse_ServingStatus[server?.healthState.status("") ?? HealthCheckResponse_ServingStatus.UNKNOWN]}`,
184
+ );
185
+ return Promise.resolve();
186
+ };
187
+ server = await compose([
188
+ enterpriseUnit({ start: observe("first") }),
189
+ { name: "second", start: observe("second") },
190
+ ]);
191
+ await server.start();
192
+ expect(seen).toEqual(["first:NOT_SERVING", "second:NOT_SERVING"]);
193
+ expect(server.healthState.status("")).toBe(
194
+ HealthCheckResponse_ServingStatus.SERVING,
195
+ );
196
+ });
197
+
198
+ it("a failing start fails the server's start, naming its unit, and the server never reports SERVING", async () => {
199
+ const server = await compose([
200
+ enterpriseUnit({
201
+ start: () => Promise.reject(new Error("repair failed")),
202
+ }),
203
+ ]);
204
+ await expect(server.start()).rejects.toThrowError(
205
+ "extension 'enterprise-fixture' failed to start: repair failed",
206
+ );
207
+ expect(server.healthState.status("")).toBe(
208
+ HealthCheckResponse_ServingStatus.NOT_SERVING,
209
+ );
210
+ });
211
+ });
212
+
213
+ describe("an edition above open source signs its callers in", () => {
214
+ it.each([
215
+ ["on open source's own authorizer", {}],
216
+ [
217
+ "with its own Authorizer",
218
+ { authorizer: newPermissiveSingleTeamAuthorizer() },
219
+ ],
220
+ ])(
221
+ "refuses to boot trusted-local %s",
222
+ async (_label, extra: Partial<ServerExtension>) => {
223
+ await expect(
224
+ compose([
225
+ {
226
+ name: "signed-out-enterprise",
227
+ edition: ServerEdition.enterprise,
228
+ ...extra,
229
+ },
230
+ ]),
231
+ ).rejects.toThrowError(
232
+ "the composition serves edition 'enterprise' without the require-authentication posture — an edition above open source must sign its callers in: declare requireAuthentication on a unit that registers a verifier, or configure STIGMER_OIDC_ISSUER",
233
+ );
234
+ },
235
+ );
236
+ });
@@ -17,11 +17,12 @@
17
17
  * to before the parameter existed — is pinned where it belongs: the
18
18
  * platform domain suite (edition oss) and the four conformance rosters.
19
19
  */
20
+ import { generateKeyPairSync } from "node:crypto";
20
21
  import { mkdtempSync, rmSync } from "node:fs";
21
22
  import { tmpdir } from "node:os";
22
23
  import path from "node:path";
23
24
 
24
- import { create } from "@bufbuild/protobuf";
25
+ import { clone, create } from "@bufbuild/protobuf";
25
26
  import type { DescMessage } from "@bufbuild/protobuf";
26
27
  import { Code, ConnectError, createClient } from "@connectrpc/connect";
27
28
  import type { Transport } from "@connectrpc/connect";
@@ -38,6 +39,12 @@ import {
38
39
  ExecutionPhase,
39
40
  } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
40
41
  import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
42
+ import { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/api_pb";
43
+ import { WorkflowCommandController } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/command_pb";
44
+ import { WorkflowInstanceSchema } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/api_pb";
45
+ import { WorkflowInstanceCommandController } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/command_pb";
46
+ import { WorkflowInstanceQueryController } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/query_pb";
47
+ import { WorkflowExecutionVisibility } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/spec_pb";
41
48
  import { SessionCommandController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/command_pb";
42
49
  import { SessionQueryController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/query_pb";
43
50
  import { BillingQueryController } from "@stigmer/protos/ai/stigmer/billing/v1/query_pb";
@@ -66,10 +73,13 @@ import type { ComposedServer } from "../../boot/compose.js";
66
73
  import { createLogger } from "../../boot/logger.js";
67
74
  import { AUTHENTICATION_TOKEN_MISSING_MESSAGE } from "../../pipeline/interceptors/auth.js";
68
75
  import type { PipelineStep } from "../../pipeline/pipeline.js";
76
+ import { newPermissiveSingleTeamAuthorizer } from "../../pipeline/steps/authorize.js";
77
+ import { platformTokenKeyRingFromPem } from "../../platformtoken/key-ring.js";
69
78
  import type { AuthzCheck } from "../authorizer.js";
70
79
  import type { GateSlotName } from "../gate-slots.js";
71
80
  import type { OrganizationDirectory } from "../organization-directory.js";
72
81
  import type {
82
+ ExecutionVisibilityChangedEvent,
73
83
  ResourceAuthorizationLifecycle,
74
84
  ResourceCreatedEvent,
75
85
  ResourceDeletedEvent,
@@ -77,6 +87,9 @@ import type {
77
87
  } from "../resource-authorization.js";
78
88
  import type { AgentExecutionStatusTransition } from "../status-hooks.js";
79
89
  import type { ServerExtension } from "../registry.js";
90
+ import type { IdentityVerifier } from "../identity.js";
91
+ import type { ResourceRowReader } from "../resource-row-reader.js";
92
+ import { seedOrganizations } from "../../domain/organization/__tests__/support.js";
80
93
 
81
94
  /** The refusal a call answered; a call that succeeds fails the case. */
82
95
  async function refusalOf(work: Promise<unknown>): Promise<ConnectError> {
@@ -91,6 +104,50 @@ async function refusalOf(work: Promise<unknown>): Promise<ConnectError> {
91
104
  const BILLING_PROCEDURE =
92
105
  "/ai.stigmer.billing.v1.BillingQueryController/getBillingAccount";
93
106
 
107
+ /**
108
+ * What a composition serving an edition above open source must bring: its
109
+ * callers sign in (compose.ts refuses such an edition trusted-local), and
110
+ * it supplies its own platform-token key ring (platformtoken/key-ring.ts).
111
+ * One verifier claims the fixture token; the ring is generated per run.
112
+ */
113
+ const EDITION_CALLER_TOKEN = "edition-fixture-caller";
114
+ const editionVerifier: IdentityVerifier = {
115
+ name: "edition-fixture-verifier",
116
+ verify: (token) =>
117
+ Promise.resolve(
118
+ token === EDITION_CALLER_TOKEN
119
+ ? {
120
+ identityId: "ida_edition_fixture",
121
+ callerClass: "user",
122
+ issuer: "edition-fixture",
123
+ rawToken: token,
124
+ }
125
+ : null,
126
+ ),
127
+ };
128
+ const editionKeys = generateKeyPairSync("rsa", { modulusLength: 2048 });
129
+ const EDITION_RING = platformTokenKeyRingFromPem({
130
+ privateKeyPem: editionKeys.privateKey
131
+ .export({ format: "pem", type: "pkcs8" })
132
+ .toString(),
133
+ publicKeyPems: [
134
+ editionKeys.publicKey.export({ format: "pem", type: "spki" }).toString(),
135
+ ],
136
+ });
137
+
138
+ /** A client transport on the bound port presenting the fixture token. */
139
+ function editionCallerTransport(port: number): Transport {
140
+ return createGrpcTransport({
141
+ baseUrl: `http://127.0.0.1:${port}`,
142
+ interceptors: [
143
+ (next) => (request) => {
144
+ request.header.set("authorization", `Bearer ${EDITION_CALLER_TOKEN}`);
145
+ return next(request);
146
+ },
147
+ ],
148
+ });
149
+ }
150
+
94
151
  describe("extension composition (composed server)", () => {
95
152
  let server: ComposedServer;
96
153
  let dir: string;
@@ -98,9 +155,16 @@ describe("extension composition (composed server)", () => {
98
155
  // Captured NDJSON log lines — the interceptor-chain proof reads them.
99
156
  const logLines: string[] = [];
100
157
 
158
+ // A cloud-shaped unit: the cloud edition, its own sign-in, its own
159
+ // Authorizer (a permissive one; this suite pins service visibility and
160
+ // chain traversal, not authorization) and its own key ring.
101
161
  const fakeBillingExtension: ServerExtension = {
102
162
  name: "fake-billing",
103
163
  edition: ServerEdition.cloud,
164
+ requireAuthentication: true,
165
+ identityVerifiers: [editionVerifier],
166
+ authorizer: newPermissiveSingleTeamAuthorizer(),
167
+ drivers: { platformTokenKeys: EDITION_RING },
104
168
  services: [
105
169
  (router): void => {
106
170
  // Partial implementation is deliberate: the fake pins service
@@ -132,9 +196,7 @@ describe("extension composition (composed server)", () => {
132
196
  host: "127.0.0.1",
133
197
  });
134
198
  const port = await server.start();
135
- portTransport = createGrpcTransport({
136
- baseUrl: `http://127.0.0.1:${port}`,
137
- });
199
+ portTransport = editionCallerTransport(port);
138
200
  });
139
201
 
140
202
  afterAll(async () => {
@@ -194,21 +256,35 @@ describe("extension composition (composed server)", () => {
194
256
  });
195
257
 
196
258
  /**
197
- * The third edition on the wire (editions program, sp.edition-contract):
198
- * a unit declaring ServerEdition.enterprise is answered verbatim by
199
- * getServerInfo. The registry is generic over concrete editions, so this
200
- * pins the end-to-end path (declaration → resolved registry → platform
201
- * controller → wire) for the value no composition emits yet — the day
202
- * P4's Enterprise composition declares it, the wire is already proven.
259
+ * The third edition on the wire, on open source's own authorizer: a unit
260
+ * declaring ServerEdition.enterprise, signing its callers in and
261
+ * registering a row reader for each kind the edition serves beyond open
262
+ * source, boots with no Authorizer of its own and is answered verbatim by
263
+ * getServerInfo. It pins the end-to-end path (declaration → resolved
264
+ * registry → the built-in posture's row rule → platform controller →
265
+ * wire) a self-hosted Enterprise composition takes.
203
266
  */
204
267
  describe("extension composition (enterprise edition on the wire)", () => {
205
268
  let server: ComposedServer;
206
269
  let dir: string;
207
270
  let portTransport: Transport;
208
271
 
272
+ const noRows: ResourceRowReader = {
273
+ findById: () => Promise.resolve(undefined),
274
+ };
209
275
  const enterpriseUnit: ServerExtension = {
210
276
  name: "fake-enterprise",
211
277
  edition: ServerEdition.enterprise,
278
+ requireAuthentication: true,
279
+ identityVerifiers: [editionVerifier],
280
+ drivers: {
281
+ platformTokenKeys: EDITION_RING,
282
+ resourceRowReaders: new Map([
283
+ [ApiResourceKind.identity_provider, noRows],
284
+ [ApiResourceKind.invitation, noRows],
285
+ [ApiResourceKind.team, noRows],
286
+ ]),
287
+ },
212
288
  };
213
289
 
214
290
  beforeAll(async () => {
@@ -225,9 +301,7 @@ describe("extension composition (enterprise edition on the wire)", () => {
225
301
  host: "127.0.0.1",
226
302
  });
227
303
  const port = await server.start();
228
- portTransport = createGrpcTransport({
229
- baseUrl: `http://127.0.0.1:${port}`,
230
- });
304
+ portTransport = editionCallerTransport(port);
231
305
  });
232
306
 
233
307
  afterAll(async () => {
@@ -596,7 +670,7 @@ describe("extension composition (require-authentication posture)", () => {
596
670
  }
597
671
  });
598
672
 
599
- it("a wider edition under the posture with no Authorizer is a boot throw — the built-in authorizer enforces the open-source kinds only", async () => {
673
+ it("a wider edition on the built-in authorizer with no row readers is a boot throw naming every kind it cannot read", async () => {
600
674
  const enterpriseDir = mkdtempSync(
601
675
  path.join(tmpdir(), "require-auth-edition-"),
602
676
  );
@@ -616,15 +690,16 @@ describe("extension composition (require-authentication posture)", () => {
616
690
  extensions: [
617
691
  {
618
692
  ...requiringExtension,
619
- name: "enterprise-without-authorizer",
693
+ name: "enterprise-without-readers",
620
694
  edition: ServerEdition.enterprise,
695
+ drivers: { platformTokenKeys: EDITION_RING },
621
696
  },
622
697
  ],
623
698
  portOverride: 0,
624
699
  host: "127.0.0.1",
625
700
  }),
626
701
  ).rejects.toThrowError(
627
- /serves edition 'enterprise' under the require-authentication posture but registers no Authorizer/,
702
+ /serves edition 'enterprise' under the built-in authorizer but registers no row reader for 'identity_provider', 'invitation', 'team'/,
628
703
  );
629
704
  } finally {
630
705
  rmSync(enterpriseDir, { recursive: true, force: true });
@@ -846,6 +921,7 @@ describe("extension composition (O4 gate slots + status hooks)", () => {
846
921
  portTransport = createGrpcTransport({
847
922
  baseUrl: `http://127.0.0.1:${port}`,
848
923
  });
924
+ await seedOrganizations(portTransport, ["acme"]);
849
925
  });
850
926
 
851
927
  afterAll(async () => {
@@ -1010,8 +1086,10 @@ describe("extension composition (C2 tuple lifecycle + organization directory)",
1010
1086
  const createdEvents: ResourceCreatedEvent[] = [];
1011
1087
  const deletedEvents: ResourceDeletedEvent[] = [];
1012
1088
  const visibilityEvents: VisibilityChangedEvent[] = [];
1089
+ const executionVisibilityEvents: ExecutionVisibilityChangedEvent[] = [];
1013
1090
  let failCreates = false;
1014
1091
  let failDeletes = false;
1092
+ let failExecutionVisibility = false;
1015
1093
 
1016
1094
  const fakeLifecycle: ResourceAuthorizationLifecycle = {
1017
1095
  async onResourceCreated(event): Promise<void> {
@@ -1029,6 +1107,12 @@ describe("extension composition (C2 tuple lifecycle + organization directory)",
1029
1107
  async onVisibilityChanged(event): Promise<void> {
1030
1108
  visibilityEvents.push(event);
1031
1109
  },
1110
+ async onExecutionVisibilityChanged(event): Promise<void> {
1111
+ if (failExecutionVisibility) {
1112
+ throw new Error("fga is down");
1113
+ }
1114
+ executionVisibilityEvents.push(event);
1115
+ },
1032
1116
  };
1033
1117
 
1034
1118
  // The directory answers are test-mutable so each case can stage its
@@ -1330,4 +1414,133 @@ describe("extension composition (C2 tuple lifecycle + organization directory)",
1330
1414
  expect(missing.rawMessage).toBe(`Organization not found: ${externalOrgId}`);
1331
1415
  }
1332
1416
  });
1417
+
1418
+ // The run audience of a workflow instance (`spec.execution_visibility`):
1419
+ // open source derives `execution_viewer` from the row when a check asks;
1420
+ // an edition that stores tuples hears it here (stigmer-cloud#720). The
1421
+ // event carries the audience the level now names — the whole target
1422
+ // state, so a retry or a repeat converges — and fires from the two doors
1423
+ // that may set the level: create, and the dedicated RPC. Update and Apply
1424
+ // ignore a request-carried level (the oss#573 rule for
1425
+ // metadata.visibility), so neither can silently narrow run access.
1426
+ describe("the run audience of a workflow instance", () => {
1427
+ const workflows = () => createClient(WorkflowCommandController, portTransport);
1428
+ const instances = () => createClient(WorkflowInstanceCommandController, portTransport);
1429
+ const instanceQuery = () => createClient(WorkflowInstanceQueryController, portTransport);
1430
+ let workflowId = "";
1431
+
1432
+ beforeAll(async () => {
1433
+ const workflow = await workflows().create(
1434
+ create(WorkflowSchema, {
1435
+ apiVersion: "agentic.stigmer.ai/v1",
1436
+ kind: "Workflow",
1437
+ metadata: { name: "c2-run-audience-workflow", org: "c2seededorg" },
1438
+ spec: {
1439
+ document: { dsl: "1.0.0", namespace: "tests", name: "c2-run-audience", version: "0.1.0" },
1440
+ tasks: [{ name: "seed", kind: 1, taskConfig: { variables: { greeting: "hello" } } }],
1441
+ },
1442
+ }),
1443
+ );
1444
+ workflowId = workflow.metadata?.id ?? "";
1445
+ });
1446
+
1447
+ function instanceInput(name: string, level: WorkflowExecutionVisibility) {
1448
+ return create(WorkflowInstanceSchema, {
1449
+ apiVersion: "agentic.stigmer.ai/v1",
1450
+ kind: "WorkflowInstance",
1451
+ metadata: { name, org: "c2seededorg" },
1452
+ spec: { workflowId, executionVisibility: level },
1453
+ });
1454
+ }
1455
+
1456
+ it("create at ORGANIZATION fires the audience once; the workflow's default instance and a private create fire nothing", async () => {
1457
+ // The workflow's in-process default instance was created in beforeAll
1458
+ // at the unset level, which names no audience.
1459
+ expect(executionVisibilityEvents).toEqual([]);
1460
+ const shared = await instances().create(
1461
+ instanceInput("c2-shared-runs", WorkflowExecutionVisibility.organization),
1462
+ );
1463
+ await instances().create(instanceInput("c2-private-runs", WorkflowExecutionVisibility.private));
1464
+ expect(executionVisibilityEvents).toEqual([
1465
+ {
1466
+ instanceKind: ApiResourceKind.workflow_instance,
1467
+ instanceId: shared.metadata?.id,
1468
+ orgId: "c2seededorg",
1469
+ shapes: ["org-viewer"],
1470
+ },
1471
+ ]);
1472
+ });
1473
+
1474
+ it("updateExecutionVisibility fires the level's audience every time, the empty one included", async () => {
1475
+ const instance = await instances().create(
1476
+ instanceInput("c2-toggled-runs", WorkflowExecutionVisibility.private),
1477
+ );
1478
+ const id = instance.metadata?.id ?? "";
1479
+ executionVisibilityEvents.length = 0;
1480
+ await instances().updateExecutionVisibility({
1481
+ resourceId: id,
1482
+ executionVisibility: WorkflowExecutionVisibility.organization,
1483
+ });
1484
+ await instances().updateExecutionVisibility({
1485
+ resourceId: id,
1486
+ executionVisibility: WorkflowExecutionVisibility.private,
1487
+ });
1488
+ expect(executionVisibilityEvents.map((event) => [event.instanceId, event.shapes])).toEqual([
1489
+ [id, ["org-viewer"]],
1490
+ [id, []],
1491
+ ]);
1492
+ });
1493
+
1494
+ it("update and apply keep the stored level whatever the request carries, and fire nothing", async () => {
1495
+ const instance = await instances().create(
1496
+ instanceInput("c2-kept-runs", WorkflowExecutionVisibility.organization),
1497
+ );
1498
+ const id = instance.metadata?.id ?? "";
1499
+ executionVisibilityEvents.length = 0;
1500
+ const lowered = clone(WorkflowInstanceSchema, instance);
1501
+ lowered.spec!.executionVisibility = WorkflowExecutionVisibility.private;
1502
+ lowered.spec!.description = "edited";
1503
+ const updated = await instances().update(lowered);
1504
+ expect(updated.spec?.description, "the update itself landed").toBe("edited");
1505
+ expect(updated.spec?.executionVisibility).toBe(WorkflowExecutionVisibility.organization);
1506
+ const reapplied = clone(WorkflowInstanceSchema, lowered);
1507
+ reapplied.spec!.executionVisibility = WorkflowExecutionVisibility.unspecified;
1508
+ const applied = await instances().apply(reapplied);
1509
+ expect(applied.spec?.executionVisibility).toBe(WorkflowExecutionVisibility.organization);
1510
+ const stored = await instanceQuery().get({ value: id });
1511
+ expect(stored.spec?.executionVisibility).toBe(WorkflowExecutionVisibility.organization);
1512
+ expect(executionVisibilityEvents).toEqual([]);
1513
+ });
1514
+
1515
+ it("a driver failure fails the RPC with the level already persisted; the retry converges", async () => {
1516
+ const instance = await instances().create(
1517
+ instanceInput("c2-retried-runs", WorkflowExecutionVisibility.private),
1518
+ );
1519
+ const id = instance.metadata?.id ?? "";
1520
+ failExecutionVisibility = true;
1521
+ let refused: ConnectError | undefined;
1522
+ try {
1523
+ await instances().updateExecutionVisibility({
1524
+ resourceId: id,
1525
+ executionVisibility: WorkflowExecutionVisibility.organization,
1526
+ });
1527
+ } catch (error) {
1528
+ refused = ConnectError.from(error);
1529
+ } finally {
1530
+ failExecutionVisibility = false;
1531
+ }
1532
+ expect(refused?.code).toBe(Code.Internal);
1533
+ expect(refused?.rawMessage).toBe("failed to update execution visibility tuples");
1534
+ const stored = await instanceQuery().get({ value: id });
1535
+ expect(stored.spec?.executionVisibility, "post-persist: the level landed").toBe(
1536
+ WorkflowExecutionVisibility.organization,
1537
+ );
1538
+ executionVisibilityEvents.length = 0;
1539
+ await instances().updateExecutionVisibility({
1540
+ resourceId: id,
1541
+ executionVisibility: WorkflowExecutionVisibility.organization,
1542
+ });
1543
+ expect(executionVisibilityEvents.map((event) => event.shapes)).toEqual([["org-viewer"]]);
1544
+ });
1545
+ });
1333
1546
  });