@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
@@ -42,6 +42,7 @@
42
42
  import type { DescMessage } from "@bufbuild/protobuf";
43
43
  import type { ConnectRouter } from "@connectrpc/connect";
44
44
 
45
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
45
46
  import { ServerEdition } from "@stigmer/protos/ai/stigmer/platform/v1/server_info_pb";
46
47
 
47
48
  import type { ArtifactStorageDriverFactory } from "../artifactstorage/artifact-storage.js";
@@ -62,21 +63,28 @@ import type { ListReadScope } from "./list-read-scope.js";
62
63
  import type { PolicyGrantScope } from "./policy-grant-scope.js";
63
64
  import type { PrincipalDisplay } from "./principal-display.js";
64
65
  import type { ModelCatalogProvider } from "../domain/workflow/registry/model-catalog-provider.js";
66
+ import {
67
+ kindEnumName,
68
+ kindServedByEdition,
69
+ } from "../pipeline/apiresource-meta.js";
65
70
  import type { VisitorErrorPolicy } from "../pipeline/interceptors/error-boundary.js";
66
71
  import type { PipelineStep } from "../pipeline/pipeline.js";
67
72
  import type { RunnerCredentialProvider } from "../runnerauth/runner-credential-provider.js";
68
73
  import type { SandboxProvisionerFactory } from "../sandbox/provisioner.js";
69
74
  import type { ScheduleFireCallerMint } from "./schedule-fire-caller.js";
75
+ import type { VisitorClassifier } from "./visitor-classifier.js";
70
76
  import { BUILT_IN_SANDBOX_PROVISIONER_TYPES } from "../sandbox/provisioner.js";
71
77
  import type { WorkerFactory } from "../temporal/manager.js";
72
78
  import type { Authorizer } from "./authorizer.js";
73
79
  import type { CallerGuard } from "./caller-guards.js";
80
+ import type { ComposedServices } from "./composed-services.js";
74
81
  import type { ExtensionDrivers } from "./drivers.js";
75
82
  import { DECLARED_GATE_SLOTS } from "./gate-slots.js";
76
83
  import type { GateSlotName, ResolvedGateSteps } from "./gate-slots.js";
77
84
  import type { IdentityVerifier } from "./identity.js";
78
85
  import type { OrganizationDirectory } from "./organization-directory.js";
79
86
  import type { ResourceAuthorizationLifecycle } from "./resource-authorization.js";
87
+ import type { ResourceRowReader } from "./resource-row-reader.js";
80
88
  import type {
81
89
  AgentExecutionResponseDecorator,
82
90
  AgentExecutionStatusHooks,
@@ -172,6 +180,24 @@ export interface ServerExtension {
172
180
  readonly services?: ReadonlyArray<ExtensionServiceRegistration>;
173
181
  /** Temporal worker factories, appended to the manager's OSS factory list. */
174
182
  readonly workers?: ReadonlyArray<WorkerFactory>;
183
+ /**
184
+ * Receives the composition's own instances — the Authorizer, the list
185
+ * read scope, the policy check, the tuple lifecycle and the in-process
186
+ * transport — once, in unit order, at the end of `composeServer`
187
+ * (extensions/composed-services.ts carries the contract).
188
+ */
189
+ readonly onComposed?: (composed: ComposedServices) => void;
190
+ /**
191
+ * Boot work that must finish before anything serves, run in unit order
192
+ * first in the server's `start()`; a throw fails the start.
193
+ */
194
+ readonly start?: () => Promise<void>;
195
+ }
196
+
197
+ /** A unit's hand-over or start hook with the unit that contributed it, so a failing start names its unit. */
198
+ export interface ResolvedUnitHook<T> {
199
+ readonly unit: string;
200
+ readonly hook: T;
175
201
  }
176
202
 
177
203
  /**
@@ -208,6 +234,12 @@ export interface ResolvedExtensions {
208
234
  readonly drivers: ResolvedExtensionDrivers;
209
235
  readonly services: ReadonlyArray<ResolvedServiceRegistration>;
210
236
  readonly workers: ReadonlyArray<WorkerFactory>;
237
+ /** The units' hand-over hooks, in unit order. */
238
+ readonly onComposed: ReadonlyArray<
239
+ ResolvedUnitHook<(composed: ComposedServices) => void>
240
+ >;
241
+ /** The units' start hooks, in unit order. */
242
+ readonly start: ReadonlyArray<ResolvedUnitHook<() => Promise<void>>>;
211
243
  }
212
244
 
213
245
  /**
@@ -320,6 +352,18 @@ export interface ResolvedExtensionDrivers {
320
352
  * UNIMPLEMENTED with the edition sentence.
321
353
  */
322
354
  readonly guestTokenMinting: GuestTokenMinting | undefined;
355
+ /**
356
+ * The visitor classifier — undefined = nobody is a visitor, so every
357
+ * run carries its organization's standing context.
358
+ */
359
+ readonly visitorClassifier: VisitorClassifier | undefined;
360
+ /**
361
+ * Kind → the reader of that kind's rows (extensions/resource-row-reader.ts),
362
+ * validated against the kinds open source keeps itself. Empty = the
363
+ * built-in authorizer reads every row from the generic Store and identity
364
+ * accounts through the account port, OSS behavior byte-identical.
365
+ */
366
+ readonly resourceRowReaders: ReadonlyMap<ApiResourceKind, ResourceRowReader>;
323
367
  }
324
368
 
325
369
  /**
@@ -339,6 +383,9 @@ export function resolveExtensions(
339
383
  const responseDecorators: AgentExecutionResponseDecorator[] = [];
340
384
  const services: ResolvedServiceRegistration[] = [];
341
385
  const workers: WorkerFactory[] = [];
386
+ const onComposed: ResolvedUnitHook<(composed: ComposedServices) => void>[] =
387
+ [];
388
+ const start: ResolvedUnitHook<() => Promise<void>>[] = [];
342
389
 
343
390
  let edition: ServerEdition | undefined;
344
391
  let editionDeclaredBy: string | undefined;
@@ -385,6 +432,8 @@ export function resolveExtensions(
385
432
  let platformTokenKeysDeclaredBy: string | undefined;
386
433
  let guestTokenMinting: GuestTokenMinting | undefined;
387
434
  let guestTokenMintingDeclaredBy: string | undefined;
435
+ let visitorClassifier: VisitorClassifier | undefined;
436
+ let visitorClassifierDeclaredBy: string | undefined;
388
437
  const artifactStorageDrivers = new Map<
389
438
  string,
390
439
  ArtifactStorageDriverFactory
@@ -397,6 +446,8 @@ export function resolveExtensions(
397
446
  const sandboxDriverDeclaredBy = new Map<string, string>();
398
447
  const secretCodecs = new Map<string, SecretCodec>();
399
448
  const secretCodecDeclaredBy = new Map<string, string>();
449
+ const resourceRowReaders = new Map<ApiResourceKind, ResourceRowReader>();
450
+ const rowReaderDeclaredBy = new Map<ApiResourceKind, string>();
400
451
 
401
452
  for (const unit of units) {
402
453
  if (unit.name === "") {
@@ -636,6 +687,16 @@ export function resolveExtensions(
636
687
  guestTokenMintingDeclaredBy = unit.name;
637
688
  }
638
689
 
690
+ if (unit.drivers?.visitorClassifier !== undefined) {
691
+ if (visitorClassifierDeclaredBy !== undefined) {
692
+ throw new Error(
693
+ `extension '${unit.name}' registers a VisitorClassifier, but '${visitorClassifierDeclaredBy}' already did — exactly one may be composed`,
694
+ );
695
+ }
696
+ visitorClassifier = unit.drivers.visitorClassifier;
697
+ visitorClassifierDeclaredBy = unit.name;
698
+ }
699
+
639
700
  if (unit.drivers?.artifactStorageDrivers !== undefined) {
640
701
  for (const [name, factory] of unit.drivers.artifactStorageDrivers) {
641
702
  if ((BUILT_IN_STORAGE_TYPES as ReadonlyArray<string>).includes(name)) {
@@ -703,6 +764,40 @@ export function resolveExtensions(
703
764
  }
704
765
  }
705
766
 
767
+ if (unit.drivers?.resourceRowReaders !== undefined) {
768
+ for (const [kind, reader] of unit.drivers.resourceRowReaders) {
769
+ if (kind === ApiResourceKind.api_resource_kind_unknown) {
770
+ throw new Error(
771
+ `extension '${unit.name}' registers a row reader for the unknown kind — a reader names the kind whose rows it reads`,
772
+ );
773
+ }
774
+ const name = kindEnumName(kind);
775
+ if (kind === ApiResourceKind.identity_account) {
776
+ // Accounts are read through the account port, the binding every
777
+ // other reader of accounts follows; a composition substitutes it
778
+ // as drivers.identityAccountStore, never as a second reader.
779
+ throw new Error(
780
+ `extension '${unit.name}' registers a row reader for '${name}', which is reserved — identity accounts are read through the account port (drivers.identityAccountStore)`,
781
+ );
782
+ }
783
+ if (kindServedByEdition(kind, ServerEdition.oss)) {
784
+ // Open source keeps its own kinds' rows in its own store; a
785
+ // reader would answer checks from rows its lanes never wrote.
786
+ throw new Error(
787
+ `extension '${unit.name}' registers a row reader for '${name}', which open source serves from its own store — readers are for kinds a unit keeps itself`,
788
+ );
789
+ }
790
+ const declaredBy = rowReaderDeclaredBy.get(kind);
791
+ if (declaredBy !== undefined) {
792
+ throw new Error(
793
+ `extension '${unit.name}' registers a row reader for '${name}', but '${declaredBy}' already did — one reader per kind across the composed set`,
794
+ );
795
+ }
796
+ resourceRowReaders.set(kind, reader);
797
+ rowReaderDeclaredBy.set(kind, unit.name);
798
+ }
799
+ }
800
+
706
801
  if (unit.gateSteps !== undefined) {
707
802
  for (const [slot, steps] of unit.gateSteps) {
708
803
  if (!DECLARED_GATE_SLOTS.has(slot)) {
@@ -734,6 +829,12 @@ export function resolveExtensions(
734
829
  })),
735
830
  );
736
831
  workers.push(...(unit.workers ?? []));
832
+ if (unit.onComposed !== undefined) {
833
+ onComposed.push({ unit: unit.name, hook: unit.onComposed });
834
+ }
835
+ if (unit.start !== undefined) {
836
+ start.push({ unit: unit.name, hook: unit.start });
837
+ }
737
838
  }
738
839
 
739
840
  return {
@@ -772,8 +873,12 @@ export function resolveExtensions(
772
873
  platformClientStore,
773
874
  platformTokenKeys,
774
875
  guestTokenMinting,
876
+ visitorClassifier,
877
+ resourceRowReaders,
775
878
  },
776
879
  services,
777
880
  workers,
881
+ onComposed,
882
+ start,
778
883
  };
779
884
  }
@@ -52,6 +52,17 @@
52
52
  * before the row mirror existed.
53
53
  * Absent method = no mirror is written (the OSS posture: rows are the
54
54
  * record).
55
+ *
56
+ * One more structural relation rides the seam the way `default_of` does:
57
+ * a workflow instance's run audience, `execution_viewer`, which open
58
+ * source derives from `spec.execution_visibility` when a check asks
59
+ * (authorization/model/execution-viewer.ts) and an edition that stores
60
+ * tuples must write. `onExecutionVisibilityChanged` hands the driver the
61
+ * audience the stored level names, from the two doors that may set it
62
+ * (create, and updateExecutionVisibility; Update and Apply keep the
63
+ * stored level, domain/workflowinstance/steps.ts). Synchronous,
64
+ * post-persist; a throw fails the request with the level persisted, and a
65
+ * retry converges because the event is the whole target state.
55
66
  */
56
67
  import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
57
68
  import type { OwnerAttributionType } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/authorization_config_pb";
@@ -72,6 +83,16 @@ import type { CallerIdentity } from "./identity.js";
72
83
  */
73
84
  export type VisibilityTupleShape = "org-viewer" | "platform-viewer";
74
85
 
86
+ /**
87
+ * The run-audience shapes of a workflow instance's execution visibility,
88
+ * named edition-neutrally. The driver maps each to its tuple:
89
+ * - org-viewer: <instanceKind>:<id>#execution_viewer@organization:<org>#viewer
90
+ * The same word as the resource visibility's org shape, a different
91
+ * relation: making an instance's RUNS observable never widens who can see
92
+ * or run the instance itself (fga/model/agentic/workflow_instance.fga).
93
+ */
94
+ export type ExecutionAudienceShape = "org-viewer";
95
+
75
96
  /**
76
97
  * One resolved structural link from the created resource to a parent
77
98
  * object — the scope link (relation `organization` for ORGANIZATION
@@ -160,6 +181,8 @@ export interface VisibilityChangedEvent {
160
181
  readonly kind: ApiResourceKind;
161
182
  readonly resourceId: string;
162
183
  readonly orgId: string;
184
+ /** Who changed the visibility — the audience rows a driver writes are theirs to answer for. */
185
+ readonly caller: CallerIdentity;
163
186
  /** Shapes present in the new level but not the old — to be written. */
164
187
  readonly shapesToCreate: ReadonlyArray<VisibilityTupleShape>;
165
188
  /** Shapes present in the old level but not the new — to be deleted. */
@@ -185,6 +208,22 @@ export interface DefaultInstanceLinkedEvent {
185
208
  readonly blueprintId: string;
186
209
  }
187
210
 
211
+ /**
212
+ * Fired synchronously after a workflow instance's
213
+ * `spec.execution_visibility` is persisted at create (only when the level
214
+ * names an audience) or by updateExecutionVisibility (always). `shapes` is
215
+ * the audience the stored level names — ["org-viewer"] for ORGANIZATION,
216
+ * [] for PRIVATE and unset — never a diff: the driver makes its tuples
217
+ * match it, so a retry, a repeat, or a transition whose old level it never
218
+ * saw all converge.
219
+ */
220
+ export interface ExecutionVisibilityChangedEvent {
221
+ readonly instanceKind: ApiResourceKind;
222
+ readonly instanceId: string;
223
+ readonly orgId: string;
224
+ readonly shapes: ReadonlyArray<ExecutionAudienceShape>;
225
+ }
226
+
188
227
  /**
189
228
  * Fired synchronously AFTER an IamPolicy row is persisted by the domain's
190
229
  * grant path — and on the duplicate arm, when the triple was already held
@@ -210,6 +249,22 @@ export interface PolicyRevokedEvent {
210
249
  readonly policy: IamPolicy | undefined;
211
250
  }
212
251
 
252
+ /**
253
+ * A person's organization rows are about to change, or have changed. The
254
+ * model's `organization#affiliated` (fga/model/tenancy/organization.fga)
255
+ * stands exactly while the person holds at least one row on the
256
+ * organization; the grant path announces every change of those rows and an
257
+ * edition that stores tuples keeps the relation from the announcements.
258
+ * The grant path never says whether the person is still affiliated: the
259
+ * driver derives that from the committed rows, so two changes racing on
260
+ * one person cannot leave the tuple standing on the word of the one that
261
+ * read first.
262
+ */
263
+ export interface OrganizationAffiliationEvent {
264
+ readonly identityAccountId: string;
265
+ readonly organizationId: string;
266
+ }
267
+
213
268
  /**
214
269
  * The driver interface (single-instance point, registered via
215
270
  * ExtensionDrivers.resourceAuthorizationLifecycle). Implementations must
@@ -227,6 +282,15 @@ export interface ResourceAuthorizationLifecycle {
227
282
  * (the OSS posture: local access control needs none).
228
283
  */
229
284
  onDefaultInstanceLinked?(event: DefaultInstanceLinkedEvent): Promise<void>;
285
+ /**
286
+ * OPTIONAL (stigmer-cloud#720): synchronous, post-persist; a throw fails
287
+ * the request (the level survives — retry converges, the event is the
288
+ * target state). Absent method = no run-audience tuple is written (the
289
+ * OSS posture: the relation is derived from the row at check time).
290
+ */
291
+ onExecutionVisibilityChanged?(
292
+ event: ExecutionVisibilityChangedEvent,
293
+ ): Promise<void>;
230
294
  /**
231
295
  * OPTIONAL (added 20260913.01 slice 2): synchronous, AFTER the row
232
296
  * persist, on the duplicate arm too; a throw fails the grant with the
@@ -239,4 +303,27 @@ export interface ResourceAuthorizationLifecycle {
239
303
  * rows are the record (the OSS posture).
240
304
  */
241
305
  onPolicyRevoked?(event: PolicyRevokedEvent): Promise<void>;
306
+ /**
307
+ * OPTIONAL: synchronous, BEFORE a row naming an account on an
308
+ * organization is deleted, ahead of that row's `onPolicyRevoked`. A
309
+ * driver removes the organization's `affiliated` tuple for the account
310
+ * here, so a crash anywhere after it leaves the person denied, never
311
+ * admitted. A throw leaves every row in place for the retry. Absent
312
+ * method = the edition derives the relation from rows (the OSS posture).
313
+ */
314
+ onOrganizationAffiliationChanging?(
315
+ event: OrganizationAffiliationEvent,
316
+ ): Promise<void>;
317
+ /**
318
+ * OPTIONAL: synchronous, AFTER a row naming an account on an organization
319
+ * is written (the duplicate arm too, the inline heal) or deleted, and
320
+ * after a revoke that found no row. A driver re-derives the
321
+ * organization's `affiliated` tuple for the account from the committed
322
+ * rows: written while one remains, removed when none does. A throw fails
323
+ * the request with the rows committed; the next change or the driver's
324
+ * own reconcile converges. Absent method = as above.
325
+ */
326
+ onOrganizationAffiliationChanged?(
327
+ event: OrganizationAffiliationEvent,
328
+ ): Promise<void>;
242
329
  }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The resource-row-reader driver point: where the built-in authorizer
3
+ * reads the rows of a kind a unit keeps in a store of its own. Keyed by
4
+ * kind, registered as `drivers.resourceRowReaders`.
5
+ *
6
+ * The built-in authorizer evaluates the one authorization model over the
7
+ * tuples each row stands for, derived from the row when a check asks
8
+ * (authorization/derived-tuples.ts). It reads open source's kinds from the
9
+ * generic Store and identity accounts through the account port. A kind an
10
+ * edition above open source serves (an identity provider, an invitation,
11
+ * a team) lives wherever the unit that serves it keeps it, so the unit
12
+ * says where: it registers a reader for each such kind, and the built-in
13
+ * loader asks that reader before the generic Store. A unit that keeps its
14
+ * rows in the generic Store registers a reader over it; one with tables of
15
+ * its own registers a reader over those. Under a composition's own
16
+ * Authorizer nothing reads them.
17
+ *
18
+ * The contract:
19
+ * - `findById` answers the row decoded with the kind's model schema
20
+ * (authorization/model/bindings.ts), or undefined when no row has the
21
+ * id. Undefined is a real answer: the authorizer then denies, and never
22
+ * reports the row missing, for the kinds whose existence it does not
23
+ * disclose (authorization/authorizer.ts, NOT_FOUND_EXEMPT_KINDS).
24
+ * - A fault it cannot answer through THROWS (the ListReadScope rule: an
25
+ * absent row is never an outage in disguise), and the check answers
26
+ * unavailable, never a denial.
27
+ * - The row's organization, creator stamp and visibility are the ones
28
+ * its unit wrote: the tuples derive from them, so a reader that hands
29
+ * back a different organization grants that organization's members.
30
+ *
31
+ * The merge rules (extensions/registry.ts): one reader per kind across the
32
+ * composed set; never for an open-source kind, whose rows are open
33
+ * source's own store's; never for `identity_account`, whose rows are read
34
+ * through the account port a composition substitutes as
35
+ * `drivers.identityAccountStore`. Each is a boot throw naming the unit.
36
+ */
37
+ import type { Message } from "@bufbuild/protobuf";
38
+
39
+ /** The row-reader contract (keyed point, ExtensionDrivers.resourceRowReaders). */
40
+ export interface ResourceRowReader {
41
+ /** The row with this id, decoded with the kind's model schema, or undefined when absent. */
42
+ findById(id: string): Promise<Message | undefined>;
43
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The visitor-classifier driver point: which callers are VISITORS, people
3
+ * the organization lets reach its agents without belonging to it.
4
+ * Single instance, registered as `drivers.visitorClassifier`.
5
+ *
6
+ * Open source has no visitor lanes: every caller it authenticates is the
7
+ * organization's own (a person, a runner, a machine account, the server
8
+ * itself). An edition that admits outsiders mints their credentials (the
9
+ * cloud's shared-agent guests and channel senders, each a caller class of
10
+ * its own) and says here which callers those are. OSS never learns the
11
+ * lane names (the guard-memory-capture.ts doctrine); it asks this point.
12
+ * Absent means nobody is a visitor, which is true of open source.
13
+ *
14
+ * A core step reads it wherever an outsider must be treated differently
15
+ * from a member. Today that is ComposeDeclaredPreferences: the
16
+ * organization's standing context, written by its admins for its own
17
+ * work, is never composed onto a visitor's run (stigmer/stigmer#1401).
18
+ * The error boundary's VisitorErrorPolicy stays its own seam: its
19
+ * eligibility is method-aware and must answer before an identity exists
20
+ * (pipeline/interceptors/error-boundary.ts).
21
+ *
22
+ * The contract:
23
+ * - Synchronous and cheap: it runs on every execution create. The
24
+ * classification keys on the verified identity alone (its class,
25
+ * its raw token), never on a store read.
26
+ * - It classifies the caller whatever the transport: in-process
27
+ * propagation keeps the forwarded identity's class
28
+ * (pipeline/interceptors/auth.ts), so a visitor's request the server
29
+ * composes further stays a visitor's.
30
+ * - A throw counts as a visitor at every consumer, which logs it:
31
+ * withholding the organization's context from a member is
32
+ * recoverable, handing it to an outsider is not (the error boundary's
33
+ * posture).
34
+ */
35
+ import type { CallerIdentity } from "./identity.js";
36
+
37
+ /** The visitor-classifier contract (single-instance point, ExtensionDrivers.visitorClassifier). */
38
+ export interface VisitorClassifier {
39
+ /** Whether `caller` is a visitor: admitted to the organization's agents without belonging to it. */
40
+ isVisitor(caller: CallerIdentity): boolean;
41
+ }
@@ -2,7 +2,8 @@
2
2
  * Pins the OIDC identity verifier against a hermetic local issuer (an
3
3
  * in-process HTTP server serving real discovery + JWKS documents, tokens
4
4
  * signed with a real RS256 keypair — no network, no mocks of jose):
5
- * claim-or-pass (non-JWT shapes pass, JWT shapes are claimed), the
5
+ * claim-or-pass (non-JWT shapes and JWTs naming another issuer pass;
6
+ * this issuer's JWTs are claimed, and a JWT naming no issuer is refused), the
6
7
  * identity mapping (sub/iss/email/name), the four byte-pinned Java
7
8
  * classifyAuthError arms, and the infrastructure-fault posture (discovery
8
9
  * failures are plain errors for the chassis's INTERNAL arm — never
@@ -151,6 +152,32 @@ describe("claim-or-pass", () => {
151
152
  expect(await verifier().verify("two.segments")).toBeNull();
152
153
  expect(await verifier().verify("a..c")).toBeNull();
153
154
  });
155
+
156
+ it("passes (null) on a JWT naming another issuer — a composition's own lane for that issuer stays reachable — and fetches nothing", async () => {
157
+ const token = await mintToken({
158
+ sub: "s",
159
+ issuerClaim: "https://tenant.example",
160
+ });
161
+ const before = { ...hits };
162
+ expect(await verifier().verify(token)).toBeNull();
163
+ expect(hits).toEqual(before);
164
+ });
165
+
166
+ it("passes (null) on an issuer that differs only by a trailing slash: the comparison is exact, as discovery's is", async () => {
167
+ const token = await mintToken({ sub: "s", issuerClaim: `${issuer}/` });
168
+ expect(await verifier().verify(token)).toBeNull();
169
+ });
170
+
171
+ it("refuses a JWT naming no issuer with 'invalid token': it is malformed, not another lane's", async () => {
172
+ const segment = (value: unknown): string =>
173
+ Buffer.from(JSON.stringify(value)).toString("base64url");
174
+ const noIssuer = `${segment({ alg: "RS256", kid: "test-key" })}.${segment({
175
+ sub: "s",
176
+ })}.${segment("sig")}`;
177
+ const error = await rejectionOf(verifier().verify(noIssuer));
178
+ expect(ConnectError.from(error).code).toBe(Code.Unauthenticated);
179
+ expect(ConnectError.from(error).rawMessage).toBe(INVALID_TOKEN_MESSAGE);
180
+ });
154
181
  });
155
182
 
156
183
  describe("identity mapping", () => {
@@ -204,15 +231,6 @@ describe("the byte-pinned classifyAuthError arms", () => {
204
231
  expect(ConnectError.from(error).rawMessage).toBe(TOKEN_SIGNATURE_MESSAGE);
205
232
  });
206
233
 
207
- it("issuer-claim mismatch → 'invalid token' (the fallback arm)", async () => {
208
- const token = await mintToken({
209
- sub: "s",
210
- issuerClaim: "https://evil.test",
211
- });
212
- const error = await rejectionOf(verifier().verify(token));
213
- expect(ConnectError.from(error).rawMessage).toBe(INVALID_TOKEN_MESSAGE);
214
- });
215
-
216
234
  it("a garbage three-segment token → 'invalid token'", async () => {
217
235
  const error = await rejectionOf(verifier().verify("aaa.bbb.ccc"));
218
236
  expect(ConnectError.from(error).code).toBe(Code.Unauthenticated);
@@ -375,7 +393,13 @@ describe("infrastructure faults are never credential rejections", () => {
375
393
  accounts: fakeIdentityAccountStore(),
376
394
  discovery: newIssuerDiscovery(),
377
395
  });
378
- const error = await rejectionOf(dead.verify(await mintToken({ sub: "s" })));
396
+ // The token names the dead issuer, so this lane claims it and must
397
+ // reach the network: a token naming another issuer passes first.
398
+ const error = await rejectionOf(
399
+ dead.verify(
400
+ await mintToken({ sub: "s", issuerClaim: "http://127.0.0.1:1" }),
401
+ ),
402
+ );
379
403
  expect(error).not.toBeInstanceOf(ConnectError);
380
404
  });
381
405
 
@@ -389,7 +413,9 @@ describe("infrastructure faults are never credential rejections", () => {
389
413
  discovery: newIssuerDiscovery(),
390
414
  });
391
415
  const error = await rejectionOf(
392
- misconfigured.verify(await mintToken({ sub: "s" })),
416
+ misconfigured.verify(
417
+ await mintToken({ sub: "s", issuerClaim: `${issuer}/` }),
418
+ ),
393
419
  );
394
420
  expect(error).not.toBeInstanceOf(ConnectError);
395
421
  expect(String(error)).toContain("does not match configured issuer");
@@ -11,7 +11,12 @@
11
11
  * the cloud's verifiers name theirs on the CallerIdentity they mint. The
12
12
  * one issuer whose userinfo can answer for a token is the one that issued
13
13
  * it — and a verifier already trusted it, so the token goes only where it
14
- * came from.
14
+ * came from. The domain calls this only for a caller the platform's own
15
+ * sign-in vouched for (domain/identityaccount/resolve.ts
16
+ * `mayProvisionDirectAccount`), so the issuer is always the operator's own
17
+ * configuration: an issuer an organization admin registered, whose
18
+ * discovery document could name any address, never reaches this plain
19
+ * fetch.
15
20
  *
16
21
  * The endpoint is the discovery document's word, never a guessed
17
22
  * `<issuer>/userinfo`: a document that names no `userinfo_endpoint` is
@@ -6,11 +6,19 @@
6
6
  * Cloud points STIGMER_OIDC_ISSUER at Auth0 and registers NO code here;
7
7
  * any self-host points it at their own issuer (Keycloak, Okta, Dex, …).
8
8
  *
9
- * Claim rule: any JWT-shaped token (three non-empty dot-separated
10
- * segments). API keys never look like JWTs (`stk_` + one Base64URL run),
11
- * so ordering after the apikey verifier keeps both claims disjoint; a
12
- * JWT-shaped token that fails verification THROWS (identity.ts contract)
13
- * with the Java classifyAuthError copy, byte-pinned:
9
+ * Claim rule: a JWT-shaped token (three non-empty dot-separated segments)
10
+ * whose `iss` is this lane's issuer, compared exactly, as discovery
11
+ * compares it. API keys never look like JWTs (`stk_` + one Base64URL run),
12
+ * so ordering after the apikey verifier keeps both claims disjoint. A JWT
13
+ * naming another issuer PASSES, so a lane composed after this one (a
14
+ * composition's own sign-in lane for another issuer) can claim it, and a
15
+ * token no lane claims is refused by the verifier chain as unclaimed —
16
+ * UNAUTHENTICATED either way. The `iss` read before verification only
17
+ * routes the token; it grants nothing, because a claimed token is then
18
+ * verified whole against this issuer's keys. A JWT-shaped token with no
19
+ * readable string `iss` is malformed and THROWS "invalid token". A claimed
20
+ * token that fails verification THROWS (identity.ts contract) with the
21
+ * Java classifyAuthError copy, byte-pinned:
14
22
  *
15
23
  * - expiry → "token has expired"
16
24
  * - audience mismatch → "token audience does not match the expected audience"
@@ -41,10 +49,15 @@
41
49
  * issuer is the configured issuer; email/displayName come from the
42
50
  * standard `email`/`name` claims when present (the DD-007 Q5 addendum
43
51
  * added the fields for exactly these claims), whichever way the subject
44
- * resolved. Claim-or-pass runs before any of this: a non-JWT token
45
- * passes with no network.
52
+ * resolved. Claim-or-pass runs before any of this: a non-JWT token, and a
53
+ * JWT from another issuer, passes with no network.
46
54
  */
47
- import { createRemoteJWKSet, jwtVerify, errors as joseErrors } from "jose";
55
+ import {
56
+ createRemoteJWKSet,
57
+ decodeJwt,
58
+ jwtVerify,
59
+ errors as joseErrors,
60
+ } from "jose";
48
61
  import type { JWTPayload } from "jose";
49
62
  import { Code, ConnectError } from "@connectrpc/connect";
50
63
 
@@ -98,6 +111,9 @@ export function newOidcIdentityVerifier(
98
111
  if (!isJwtShaped(token)) {
99
112
  return null;
100
113
  }
114
+ if (unverifiedIssuerOf(token) !== config.issuer) {
115
+ return null;
116
+ }
101
117
  const keys = await jwksFor();
102
118
  let payload: JWTPayload;
103
119
  try {
@@ -127,6 +143,24 @@ export function newOidcIdentityVerifier(
127
143
  };
128
144
  }
129
145
 
146
+ /**
147
+ * The `iss` a JWT-shaped token names, read without verifying it — only to
148
+ * decide which lane verifies it. A payload that does not decode, or names
149
+ * no string issuer, is a malformed credential this lane refuses outright.
150
+ */
151
+ function unverifiedIssuerOf(token: string): string {
152
+ let issuer: unknown;
153
+ try {
154
+ issuer = decodeJwt(token).iss;
155
+ } catch {
156
+ throw new ConnectError(INVALID_TOKEN_MESSAGE, Code.Unauthenticated);
157
+ }
158
+ if (typeof issuer !== "string" || issuer === "") {
159
+ throw new ConnectError(INVALID_TOKEN_MESSAGE, Code.Unauthenticated);
160
+ }
161
+ return issuer;
162
+ }
163
+
130
164
  /** Three non-empty dot-separated segments — the JWS compact shape. */
131
165
  function isJwtShaped(token: string): boolean {
132
166
  const segments = token.split(".");