@stigmer/server 3.21.0 → 3.22.1-dev.20260922095755

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 (383) hide show
  1. package/dist/authorization/authorizer.d.ts +4 -8
  2. package/dist/authorization/authorizer.d.ts.map +1 -1
  3. package/dist/authorization/authorizer.js +5 -9
  4. package/dist/authorization/authorizer.js.map +1 -1
  5. package/dist/authorization/derived-tuples.d.ts.map +1 -1
  6. package/dist/authorization/derived-tuples.js +10 -25
  7. package/dist/authorization/derived-tuples.js.map +1 -1
  8. package/dist/authorization/evaluator.d.ts +13 -8
  9. package/dist/authorization/evaluator.d.ts.map +1 -1
  10. package/dist/authorization/evaluator.js +4 -20
  11. package/dist/authorization/evaluator.js.map +1 -1
  12. package/dist/authorization/list-read-scope.d.ts.map +1 -1
  13. package/dist/authorization/list-read-scope.js +24 -20
  14. package/dist/authorization/list-read-scope.js.map +1 -1
  15. package/dist/authorization/model/agent.d.ts.map +1 -1
  16. package/dist/authorization/model/agent.js +4 -5
  17. package/dist/authorization/model/agent.js.map +1 -1
  18. package/dist/authorization/model/agent_instance.d.ts.map +1 -1
  19. package/dist/authorization/model/agent_instance.js +2 -2
  20. package/dist/authorization/model/agent_instance.js.map +1 -1
  21. package/dist/authorization/model/mcp_server.d.ts.map +1 -1
  22. package/dist/authorization/model/mcp_server.js +2 -2
  23. package/dist/authorization/model/mcp_server.js.map +1 -1
  24. package/dist/authorization/model/organization.d.ts.map +1 -1
  25. package/dist/authorization/model/organization.js +2 -0
  26. package/dist/authorization/model/organization.js.map +1 -1
  27. package/dist/authorization/model/plugin.d.ts.map +1 -1
  28. package/dist/authorization/model/plugin.js +3 -4
  29. package/dist/authorization/model/plugin.js.map +1 -1
  30. package/dist/authorization/model/rewrite.d.ts +8 -10
  31. package/dist/authorization/model/rewrite.d.ts.map +1 -1
  32. package/dist/authorization/model/rewrite.js +0 -3
  33. package/dist/authorization/model/rewrite.js.map +1 -1
  34. package/dist/authorization/model/skill.d.ts.map +1 -1
  35. package/dist/authorization/model/skill.js +2 -2
  36. package/dist/authorization/model/skill.js.map +1 -1
  37. package/dist/authorization/model/workflow.d.ts.map +1 -1
  38. package/dist/authorization/model/workflow.js +2 -2
  39. package/dist/authorization/model/workflow.js.map +1 -1
  40. package/dist/authorization/model/workflow_instance.d.ts.map +1 -1
  41. package/dist/authorization/model/workflow_instance.js +2 -2
  42. package/dist/authorization/model/workflow_instance.js.map +1 -1
  43. package/dist/authorization/organization-directory.d.ts.map +1 -1
  44. package/dist/authorization/organization-directory.js +2 -3
  45. package/dist/authorization/organization-directory.js.map +1 -1
  46. package/dist/authorization/store-test-kit.d.ts +0 -6
  47. package/dist/authorization/store-test-kit.d.ts.map +1 -1
  48. package/dist/authorization/store-test-kit.js +16 -62
  49. package/dist/authorization/store-test-kit.js.map +1 -1
  50. package/dist/authorization/tuples.d.ts +13 -32
  51. package/dist/authorization/tuples.d.ts.map +1 -1
  52. package/dist/authorization/tuples.js +3 -11
  53. package/dist/authorization/tuples.js.map +1 -1
  54. package/dist/domain/agent/controller.d.ts.map +1 -1
  55. package/dist/domain/agent/controller.js +6 -4
  56. package/dist/domain/agent/controller.js.map +1 -1
  57. package/dist/domain/agentchannel/controller.d.ts.map +1 -1
  58. package/dist/domain/agentchannel/controller.js +9 -2
  59. package/dist/domain/agentchannel/controller.js.map +1 -1
  60. package/dist/domain/agentchannel/steps.d.ts +19 -0
  61. package/dist/domain/agentchannel/steps.d.ts.map +1 -1
  62. package/dist/domain/agentchannel/steps.js +32 -0
  63. package/dist/domain/agentchannel/steps.js.map +1 -1
  64. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  65. package/dist/domain/agentexecution/controller.js +3 -1
  66. package/dist/domain/agentexecution/controller.js.map +1 -1
  67. package/dist/domain/agentinstance/controller.d.ts +5 -5
  68. package/dist/domain/agentinstance/controller.d.ts.map +1 -1
  69. package/dist/domain/agentinstance/controller.js +9 -5
  70. package/dist/domain/agentinstance/controller.js.map +1 -1
  71. package/dist/domain/agentinstance/steps.d.ts +43 -8
  72. package/dist/domain/agentinstance/steps.d.ts.map +1 -1
  73. package/dist/domain/agentinstance/steps.js +71 -8
  74. package/dist/domain/agentinstance/steps.js.map +1 -1
  75. package/dist/domain/agentshare/constants.d.ts +6 -11
  76. package/dist/domain/agentshare/constants.d.ts.map +1 -1
  77. package/dist/domain/agentshare/constants.js +8 -16
  78. package/dist/domain/agentshare/constants.js.map +1 -1
  79. package/dist/domain/agentshare/controller.d.ts.map +1 -1
  80. package/dist/domain/agentshare/controller.js +10 -2
  81. package/dist/domain/agentshare/controller.js.map +1 -1
  82. package/dist/domain/agentshare/steps.d.ts +61 -10
  83. package/dist/domain/agentshare/steps.d.ts.map +1 -1
  84. package/dist/domain/agentshare/steps.js +121 -117
  85. package/dist/domain/agentshare/steps.js.map +1 -1
  86. package/dist/domain/artifact/controller.js +21 -25
  87. package/dist/domain/artifact/controller.js.map +1 -1
  88. package/dist/domain/channelapp/controller.d.ts.map +1 -1
  89. package/dist/domain/channelapp/controller.js +2 -0
  90. package/dist/domain/channelapp/controller.js.map +1 -1
  91. package/dist/domain/environment/controller.d.ts.map +1 -1
  92. package/dist/domain/environment/controller.js +4 -3
  93. package/dist/domain/environment/controller.js.map +1 -1
  94. package/dist/domain/executioncontext/controller.d.ts.map +1 -1
  95. package/dist/domain/executioncontext/controller.js +4 -1
  96. package/dist/domain/executioncontext/controller.js.map +1 -1
  97. package/dist/domain/executioncontext/steps.d.ts.map +1 -1
  98. package/dist/domain/executioncontext/steps.js +2 -1
  99. package/dist/domain/executioncontext/steps.js.map +1 -1
  100. package/dist/domain/mcpserver/connect.d.ts.map +1 -1
  101. package/dist/domain/mcpserver/connect.js +8 -7
  102. package/dist/domain/mcpserver/connect.js.map +1 -1
  103. package/dist/domain/mcpserver/controller.d.ts.map +1 -1
  104. package/dist/domain/mcpserver/controller.js +5 -4
  105. package/dist/domain/mcpserver/controller.js.map +1 -1
  106. package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
  107. package/dist/domain/mcpserver/start-connect.js +8 -7
  108. package/dist/domain/mcpserver/start-connect.js.map +1 -1
  109. package/dist/domain/memory/controller.d.ts.map +1 -1
  110. package/dist/domain/memory/controller.js +6 -1
  111. package/dist/domain/memory/controller.js.map +1 -1
  112. package/dist/domain/memory/steps.d.ts +23 -0
  113. package/dist/domain/memory/steps.d.ts.map +1 -1
  114. package/dist/domain/memory/steps.js +35 -0
  115. package/dist/domain/memory/steps.js.map +1 -1
  116. package/dist/domain/oauthapp/controller.d.ts.map +1 -1
  117. package/dist/domain/oauthapp/controller.js +2 -0
  118. package/dist/domain/oauthapp/controller.js.map +1 -1
  119. package/dist/domain/plugin/controller.d.ts.map +1 -1
  120. package/dist/domain/plugin/controller.js +6 -27
  121. package/dist/domain/plugin/controller.js.map +1 -1
  122. package/dist/domain/plugin/push.d.ts +7 -5
  123. package/dist/domain/plugin/push.d.ts.map +1 -1
  124. package/dist/domain/plugin/push.js +8 -14
  125. package/dist/domain/plugin/push.js.map +1 -1
  126. package/dist/domain/schedule/controller.d.ts.map +1 -1
  127. package/dist/domain/schedule/controller.js +10 -2
  128. package/dist/domain/schedule/controller.js.map +1 -1
  129. package/dist/domain/schedule/steps.d.ts +19 -0
  130. package/dist/domain/schedule/steps.d.ts.map +1 -1
  131. package/dist/domain/schedule/steps.js +32 -0
  132. package/dist/domain/schedule/steps.js.map +1 -1
  133. package/dist/domain/session/controller.d.ts.map +1 -1
  134. package/dist/domain/session/controller.js +3 -2
  135. package/dist/domain/session/controller.js.map +1 -1
  136. package/dist/domain/session/steps.d.ts +8 -9
  137. package/dist/domain/session/steps.d.ts.map +1 -1
  138. package/dist/domain/session/steps.js +17 -21
  139. package/dist/domain/session/steps.js.map +1 -1
  140. package/dist/domain/skill/controller.d.ts.map +1 -1
  141. package/dist/domain/skill/controller.js +8 -19
  142. package/dist/domain/skill/controller.js.map +1 -1
  143. package/dist/domain/workflow/agent-call-references.d.ts +54 -0
  144. package/dist/domain/workflow/agent-call-references.d.ts.map +1 -0
  145. package/dist/domain/workflow/agent-call-references.js +97 -0
  146. package/dist/domain/workflow/agent-call-references.js.map +1 -0
  147. package/dist/domain/workflow/controller.d.ts.map +1 -1
  148. package/dist/domain/workflow/controller.js +44 -113
  149. package/dist/domain/workflow/controller.js.map +1 -1
  150. package/dist/domain/workflow/registry/data/task-kind-registry.json +1 -1
  151. package/dist/domain/workflow/validation/task-config-constraints.d.ts +10 -1
  152. package/dist/domain/workflow/validation/task-config-constraints.d.ts.map +1 -1
  153. package/dist/domain/workflow/validation/task-config-constraints.js +3 -2
  154. package/dist/domain/workflow/validation/task-config-constraints.js.map +1 -1
  155. package/dist/domain/workflow/version-resolution.d.ts +5 -0
  156. package/dist/domain/workflow/version-resolution.d.ts.map +1 -0
  157. package/dist/domain/workflow/version-resolution.js +113 -0
  158. package/dist/domain/workflow/version-resolution.js.map +1 -0
  159. package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
  160. package/dist/domain/workflowexecution/controller.js +4 -2
  161. package/dist/domain/workflowexecution/controller.js.map +1 -1
  162. package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
  163. package/dist/domain/workflowinstance/controller.js +9 -5
  164. package/dist/domain/workflowinstance/controller.js.map +1 -1
  165. package/dist/domain/workflowinstance/steps.d.ts +20 -0
  166. package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
  167. package/dist/domain/workflowinstance/steps.js +39 -0
  168. package/dist/domain/workflowinstance/steps.js.map +1 -1
  169. package/dist/extensions/authorization-queries.d.ts +6 -5
  170. package/dist/extensions/authorization-queries.d.ts.map +1 -1
  171. package/dist/extensions/identity.d.ts +19 -0
  172. package/dist/extensions/identity.d.ts.map +1 -1
  173. package/dist/extensions/identity.js +22 -3
  174. package/dist/extensions/identity.js.map +1 -1
  175. package/dist/extensions/list-read-scope.d.ts +42 -8
  176. package/dist/extensions/list-read-scope.d.ts.map +1 -1
  177. package/dist/extensions/list-read-scope.js +13 -2
  178. package/dist/extensions/list-read-scope.js.map +1 -1
  179. package/dist/extensions/resource-authorization.d.ts +3 -2
  180. package/dist/extensions/resource-authorization.d.ts.map +1 -1
  181. package/dist/index.d.ts +1 -1
  182. package/dist/index.d.ts.map +1 -1
  183. package/dist/index.js.map +1 -1
  184. package/dist/pipeline/apiresource-meta.d.ts +12 -3
  185. package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
  186. package/dist/pipeline/apiresource-meta.js +21 -10
  187. package/dist/pipeline/apiresource-meta.js.map +1 -1
  188. package/dist/pipeline/steps/authorization-tuples.d.ts +9 -3
  189. package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
  190. package/dist/pipeline/steps/authorization-tuples.js +9 -11
  191. package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
  192. package/dist/pipeline/steps/authorize-resolved-target.d.ts +88 -0
  193. package/dist/pipeline/steps/authorize-resolved-target.d.ts.map +1 -0
  194. package/dist/pipeline/steps/authorize-resolved-target.js +36 -0
  195. package/dist/pipeline/steps/authorize-resolved-target.js.map +1 -0
  196. package/dist/pipeline/steps/authorize.d.ts +27 -0
  197. package/dist/pipeline/steps/authorize.d.ts.map +1 -1
  198. package/dist/pipeline/steps/authorize.js +49 -10
  199. package/dist/pipeline/steps/authorize.js.map +1 -1
  200. package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
  201. package/dist/pipeline/steps/guard-memory-capture.js +2 -1
  202. package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
  203. package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
  204. package/dist/pipeline/steps/guard-reserved-labels.js +6 -7
  205. package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
  206. package/dist/pipeline/steps/helpers.d.ts +9 -5
  207. package/dist/pipeline/steps/helpers.d.ts.map +1 -1
  208. package/dist/pipeline/steps/helpers.js +11 -15
  209. package/dist/pipeline/steps/helpers.js.map +1 -1
  210. package/dist/pipeline/steps/references.d.ts +178 -20
  211. package/dist/pipeline/steps/references.d.ts.map +1 -1
  212. package/dist/pipeline/steps/references.js +344 -43
  213. package/dist/pipeline/steps/references.js.map +1 -1
  214. package/dist/pipeline/steps/version-history.d.ts +11 -0
  215. package/dist/pipeline/steps/version-history.d.ts.map +1 -1
  216. package/dist/pipeline/steps/version-history.js +26 -0
  217. package/dist/pipeline/steps/version-history.js.map +1 -1
  218. package/dist/query/search/controller.js +0 -1
  219. package/dist/query/search/controller.js.map +1 -1
  220. package/dist/query/search/criteria.d.ts +1 -5
  221. package/dist/query/search/criteria.d.ts.map +1 -1
  222. package/dist/query/search/criteria.js +3 -13
  223. package/dist/query/search/criteria.js.map +1 -1
  224. package/dist/query/search/handler.d.ts +5 -4
  225. package/dist/query/search/handler.d.ts.map +1 -1
  226. package/dist/query/search/handler.js +7 -6
  227. package/dist/query/search/handler.js.map +1 -1
  228. package/dist/query/search/query-store.d.ts.map +1 -1
  229. package/dist/query/search/query-store.js +0 -2
  230. package/dist/query/search/query-store.js.map +1 -1
  231. package/dist/store/interface.d.ts +3 -6
  232. package/dist/store/interface.d.ts.map +1 -1
  233. package/dist/store/interface.js.map +1 -1
  234. package/dist/store/postgres/migrations.d.ts +3 -1
  235. package/dist/store/postgres/migrations.d.ts.map +1 -1
  236. package/dist/store/postgres/migrations.js +35 -1
  237. package/dist/store/postgres/migrations.js.map +1 -1
  238. package/dist/store/postgres/store.d.ts.map +1 -1
  239. package/dist/store/postgres/store.js +4 -9
  240. package/dist/store/postgres/store.js.map +1 -1
  241. package/dist/store/public-visibility-retired.d.ts +67 -0
  242. package/dist/store/public-visibility-retired.d.ts.map +1 -0
  243. package/dist/store/public-visibility-retired.js +55 -0
  244. package/dist/store/public-visibility-retired.js.map +1 -0
  245. package/dist/store/sqlite/migrations.d.ts +3 -1
  246. package/dist/store/sqlite/migrations.d.ts.map +1 -1
  247. package/dist/store/sqlite/migrations.js +36 -1
  248. package/dist/store/sqlite/migrations.js.map +1 -1
  249. package/dist/store/sqlite/store.d.ts.map +1 -1
  250. package/dist/store/sqlite/store.js +4 -8
  251. package/dist/store/sqlite/store.js.map +1 -1
  252. package/package.json +6 -6
  253. package/src/authorization/README.md +24 -26
  254. package/src/authorization/__tests__/authorizer.test.ts +10 -9
  255. package/src/authorization/__tests__/derived-tuples.test.ts +4 -11
  256. package/src/authorization/__tests__/evaluator.test.ts +14 -73
  257. package/src/authorization/__tests__/facts.test.ts +2 -2
  258. package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +6 -98
  259. package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +4 -61
  260. package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +1 -21
  261. package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +1 -25
  262. package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +1 -3
  263. package/src/authorization/__tests__/list-read-scope.test.ts +41 -29
  264. package/src/authorization/__tests__/skip-lane-inventory.test.ts +160 -0
  265. package/src/authorization/__tests__/store-tests.test.ts +1 -6
  266. package/src/authorization/__tests__/tuples.test.ts +12 -11
  267. package/src/authorization/__tests__/wire-permissions.test.ts +5 -5
  268. package/src/authorization/authorizer.ts +4 -9
  269. package/src/authorization/derived-tuples.ts +14 -31
  270. package/src/authorization/evaluator.ts +15 -44
  271. package/src/authorization/list-read-scope.ts +27 -22
  272. package/src/authorization/model/__tests__/registry.test.ts +2 -0
  273. package/src/authorization/model/agent.ts +2 -5
  274. package/src/authorization/model/agent_instance.ts +0 -2
  275. package/src/authorization/model/mcp_server.ts +0 -2
  276. package/src/authorization/model/organization.ts +2 -0
  277. package/src/authorization/model/plugin.ts +1 -4
  278. package/src/authorization/model/rewrite.ts +8 -13
  279. package/src/authorization/model/skill.ts +0 -2
  280. package/src/authorization/model/workflow.ts +0 -2
  281. package/src/authorization/model/workflow_instance.ts +0 -2
  282. package/src/authorization/organization-directory.ts +1 -3
  283. package/src/authorization/store-test-kit.ts +16 -75
  284. package/src/authorization/tuples.ts +16 -39
  285. package/src/domain/agent/__tests__/agent.test.ts +11 -4
  286. package/src/domain/agent/controller.ts +17 -7
  287. package/src/domain/agentchannel/__tests__/agentchannel.test.ts +223 -48
  288. package/src/domain/agentchannel/__tests__/create-authorization.test.ts +58 -0
  289. package/src/domain/agentchannel/controller.ts +25 -1
  290. package/src/domain/agentchannel/steps.ts +40 -0
  291. package/src/domain/agentexecution/controller.ts +6 -1
  292. package/src/domain/agentinstance/__tests__/create-authorization.composed.test.ts +243 -0
  293. package/src/domain/agentinstance/__tests__/create-authorization.test.ts +144 -0
  294. package/src/domain/agentinstance/controller.ts +30 -17
  295. package/src/domain/agentinstance/steps.ts +82 -8
  296. package/src/domain/agentshare/__tests__/agentshare.test.ts +196 -172
  297. package/src/domain/agentshare/__tests__/create-authorization.test.ts +71 -0
  298. package/src/domain/agentshare/__tests__/member-audience.test.ts +113 -0
  299. package/src/domain/agentshare/constants.ts +14 -26
  300. package/src/domain/agentshare/controller.ts +27 -1
  301. package/src/domain/agentshare/steps.ts +168 -155
  302. package/src/domain/artifact/controller.ts +18 -22
  303. package/src/domain/channelapp/controller.ts +10 -0
  304. package/src/domain/environment/controller.ts +15 -8
  305. package/src/domain/executioncontext/__tests__/executioncontext.test.ts +1 -0
  306. package/src/domain/executioncontext/controller.ts +15 -1
  307. package/src/domain/executioncontext/steps.ts +2 -1
  308. package/src/domain/mcpserver/__tests__/mcpserver.test.ts +115 -28
  309. package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +53 -18
  310. package/src/domain/mcpserver/connect.ts +11 -10
  311. package/src/domain/mcpserver/controller.ts +19 -13
  312. package/src/domain/mcpserver/start-connect.ts +17 -11
  313. package/src/domain/memory/__tests__/create-authorization.test.ts +59 -0
  314. package/src/domain/memory/controller.ts +11 -0
  315. package/src/domain/memory/steps.ts +41 -0
  316. package/src/domain/oauthapp/controller.ts +10 -0
  317. package/src/domain/plugin/controller.ts +23 -44
  318. package/src/domain/plugin/push.ts +8 -16
  319. package/src/domain/schedule/__tests__/create-authorization.test.ts +58 -0
  320. package/src/domain/schedule/controller.ts +26 -1
  321. package/src/domain/schedule/steps.ts +45 -2
  322. package/src/domain/session/controller.ts +12 -4
  323. package/src/domain/session/steps.ts +24 -32
  324. package/src/domain/skill/controller.ts +24 -30
  325. package/src/domain/workflow/__tests__/agent-call-references.test.ts +222 -0
  326. package/src/domain/workflow/agent-call-references.ts +157 -0
  327. package/src/domain/workflow/controller.ts +86 -155
  328. package/src/domain/workflow/registry/data/task-kind-registry.json +1 -1
  329. package/src/domain/workflow/validation/task-config-constraints.ts +7 -3
  330. package/src/domain/workflow/version-resolution.ts +166 -0
  331. package/src/domain/workflowexecution/controller.ts +7 -2
  332. package/src/domain/workflowinstance/__tests__/create-authorization.test.ts +109 -0
  333. package/src/domain/workflowinstance/controller.ts +25 -12
  334. package/src/domain/workflowinstance/steps.ts +49 -1
  335. package/src/extensions/__tests__/built-in-authorization-composed.test.ts +32 -19
  336. package/src/extensions/__tests__/composed-support.ts +38 -4
  337. package/src/extensions/__tests__/extension-composition.test.ts +4 -4
  338. package/src/extensions/__tests__/identity.test.ts +44 -1
  339. package/src/extensions/__tests__/list-read-scope-composed.test.ts +96 -7
  340. package/src/extensions/__tests__/list-read-scope.test.ts +63 -0
  341. package/src/extensions/authorization-queries.ts +6 -5
  342. package/src/extensions/identity.ts +23 -5
  343. package/src/extensions/list-read-scope.ts +48 -8
  344. package/src/extensions/resource-authorization.ts +3 -5
  345. package/src/index.ts +0 -1
  346. package/src/pipeline/__tests__/supports-visibility.test.ts +112 -0
  347. package/src/pipeline/apiresource-meta.ts +21 -10
  348. package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +18 -31
  349. package/src/pipeline/steps/__tests__/authorize-resolved-target.test.ts +285 -0
  350. package/src/pipeline/steps/__tests__/references.test.ts +703 -0
  351. package/src/pipeline/steps/authorization-tuples.ts +9 -11
  352. package/src/pipeline/steps/authorize-resolved-target.ts +129 -0
  353. package/src/pipeline/steps/authorize.ts +70 -13
  354. package/src/pipeline/steps/guard-memory-capture.ts +2 -1
  355. package/src/pipeline/steps/guard-reserved-labels.ts +6 -9
  356. package/src/pipeline/steps/helpers.ts +11 -15
  357. package/src/pipeline/steps/references.ts +578 -70
  358. package/src/pipeline/steps/version-history.ts +34 -0
  359. package/src/query/search/__tests__/criteria.test.ts +0 -4
  360. package/src/query/search/__tests__/query-store.test.ts +11 -40
  361. package/src/query/search/controller.ts +0 -1
  362. package/src/query/search/criteria.ts +0 -14
  363. package/src/query/search/handler.ts +6 -7
  364. package/src/query/search/query-store.ts +0 -2
  365. package/src/store/__tests__/public-visibility-retired.test.ts +127 -0
  366. package/src/store/__tests__/store-contract.ts +6 -51
  367. package/src/store/interface.ts +3 -6
  368. package/src/store/postgres/__tests__/migrations.test.ts +187 -6
  369. package/src/store/postgres/__tests__/store-contract.test.ts +0 -2
  370. package/src/store/postgres/migrations.ts +48 -1
  371. package/src/store/postgres/store.ts +4 -11
  372. package/src/store/public-visibility-retired.ts +119 -0
  373. package/src/store/sqlite/__tests__/migrations.test.ts +191 -5
  374. package/src/store/sqlite/migrations.ts +45 -1
  375. package/src/store/sqlite/store.ts +4 -10
  376. package/dist/pipeline/steps/visibility-gates.d.ts +0 -27
  377. package/dist/pipeline/steps/visibility-gates.d.ts.map +0 -1
  378. package/dist/pipeline/steps/visibility-gates.js +0 -139
  379. package/dist/pipeline/steps/visibility-gates.js.map +0 -1
  380. package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +0 -98
  381. package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +0 -52
  382. package/src/pipeline/steps/__tests__/visibility-gates.test.ts +0 -187
  383. package/src/pipeline/steps/visibility-gates.ts +0 -174
@@ -1,10 +1,19 @@
1
1
  /**
2
2
  * AgentShare domain steps — ports pkg/domain/agentshare/controller/steps.go
3
- * and the get_shared_profile.go helpers: share defaults + the cross-org
4
- * public-dependency contract (decision 013), the agent-id rebind pin, the
3
+ * and the get_shared_profile.go helpers: share defaults and the
4
+ * same-organization invariant on agent_ref, the agent-id rebind pin, the
5
5
  * update immutability rules, the uniform-NotFound profile resolution
6
6
  * helpers, and the constant-time link-token predicate.
7
7
  *
8
+ * A share's agent lives in the share's own organization. The
9
+ * cross-organization arm this domain once carried (a share of another
10
+ * organization's public agent, gated on a public audience and a sweep of
11
+ * the agent's dependencies for public visibility) left with the public
12
+ * level; sharing another organization's agent is done by installing the
13
+ * plugin that carries it and sharing the installed copy. A stored share
14
+ * whose agent is in another organization — a row from before — fails
15
+ * closed at the profile like a dangling reference.
16
+ *
8
17
  * OD-1 (deliberate exclusion): Go's boot migration
9
18
  * (pkg/domain/agentshare/migration/bootstrap_shares.go — protowire
10
19
  * decoding of the REMOVED Agent.spec.sharing fields into AgentShare rows)
@@ -29,12 +38,8 @@ import type { AgentShare } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v
29
38
  import { AgentShareStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/status_pb";
30
39
  import { SharedAgentProfileSchema } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/io_pb";
31
40
  import type { SharedAgentProfile } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/io_pb";
32
- import { AgentShareAudience } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/spec_pb";
33
- import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
34
- import { SkillSchema } from "@stigmer/protos/ai/stigmer/agentic/skill/v1/api_pb";
35
- import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
36
- import type { ApiResourceReference } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
37
41
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
42
+ import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
38
43
 
39
44
  import {
40
45
  failedPreconditionError,
@@ -44,7 +49,13 @@ import {
44
49
  } from "../../pipeline/errors.js";
45
50
  import type { PipelineStep } from "../../pipeline/pipeline.js";
46
51
  import type { RequestContext } from "../../pipeline/request-context.js";
47
- import { findResourceBySlug } from "../../pipeline/steps/helpers.js";
52
+ import type { Authorizer } from "../../extensions/authorizer.js";
53
+ import {
54
+ AUTHORIZATION_UNAVAILABLE_MESSAGE,
55
+ evaluateAuthorizer,
56
+ } from "../../pipeline/steps/authorize.js";
57
+ import type { AuthorizationTarget } from "../../pipeline/steps/authorize.js";
58
+ import type { GetByReferenceDesc } from "../../pipeline/steps/authorize-resolved-target.js";
48
59
  import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
49
60
  import type { Store } from "../../store/interface.js";
50
61
  import {
@@ -52,8 +63,7 @@ import {
52
63
  ORG_REQUIRED_MESSAGE,
53
64
  SHARE_LINK_TOKEN_BYTES,
54
65
  agentRefImmutableMessage,
55
- crossOrgAudienceMessage,
56
- crossOrgBlockersMessage,
66
+ sameOrgInvariantMessage,
57
67
  } from "./constants.js";
58
68
 
59
69
  type AgentShareDesc = typeof AgentShareSchema;
@@ -61,10 +71,52 @@ type AgentShareDesc = typeof AgentShareSchema;
61
71
  /**
62
72
  * Context key for the agent resolved from spec.agent_ref during
63
73
  * create/apply, so later steps never re-load it — Go referencedAgentKey.
64
- * Module-private: only ResolveShareDefaults writes it and StampAgentPin
65
- * reads it, both in this file.
74
+ * ResolveShareDefaults writes it; the create lane's authorization step and
75
+ * StampAgentPin read it.
66
76
  */
67
- const REFERENCED_AGENT_KEY = "agentShareReferencedAgent";
77
+ export const REFERENCED_AGENT_KEY = "agentShareReferencedAgent";
78
+
79
+ /** The deny copy of the agent's bar, the Java AgentShareCreateHandler's. */
80
+ export const SHARE_AGENT_DENIED_MESSAGE =
81
+ "You don't have permission to share this agent";
82
+
83
+ /** The deny copy of the sharing organization's bar, the Java handler's. */
84
+ export const SHARE_ORGANIZATION_DENIED_MESSAGE =
85
+ "You don't have permission to create agent shares in this organization";
86
+
87
+ /**
88
+ * The create lane's authorization questions, for AuthorizeResolvedTarget
89
+ * after ResolveShareDefaults, agent first: can_edit on the agent (sharing
90
+ * puts it in front of a wider audience, an editor's act) and then
91
+ * can_create_agent_share on the organization (a share spends the
92
+ * organization's credits on the open internet, an admin-level act). The
93
+ * RPC is is_skip_authorization because the target is the referenced agent,
94
+ * resolved from a slug, not a request field. The resolve step has already
95
+ * made the reference absolute and refused an agent outside the share's
96
+ * organization, so the two bars are always the same organization's.
97
+ */
98
+ export function resolveShareCreateTargets(
99
+ ctx: RequestContext<AgentShareDesc>,
100
+ ): ReadonlyArray<AuthorizationTarget> {
101
+ const agent = ctx.get(REFERENCED_AGENT_KEY) as Agent | undefined;
102
+ if (agent === undefined) {
103
+ throw new Error("referenced agent not found in context");
104
+ }
105
+ return [
106
+ {
107
+ permission: IamPermission.can_edit,
108
+ resourceKind: ApiResourceKind.agent,
109
+ resourceId: agent.metadata?.id ?? "",
110
+ deniedMessage: SHARE_AGENT_DENIED_MESSAGE,
111
+ },
112
+ {
113
+ permission: IamPermission.can_create_agent_share,
114
+ resourceKind: ApiResourceKind.organization,
115
+ resourceId: ctx.newState.metadata?.org ?? "",
116
+ deniedMessage: SHARE_ORGANIZATION_DENIED_MESSAGE,
117
+ },
118
+ ];
119
+ }
68
120
 
69
121
  /**
70
122
  * The single refusal for every anonymous/member resolution miss: share
@@ -78,6 +130,71 @@ export function sharedNotFound(slug: string): ConnectError {
78
130
  return notFoundError("Agent", slug);
79
131
  }
80
132
 
133
+ /**
134
+ * AuthorizeMemberAudience — the member-profile lane's gate, membership
135
+ * BEFORE existence: the Java AgentShareGetSharedProfileForMemberHandler
136
+ * order. getSharedProfileForMember is the signed-in resolution path for a
137
+ * share URL, and the proto pins its contract: a share that does not exist,
138
+ * is disabled, or is asked for by someone who is not a member of the
139
+ * sharing organization all answer the SAME NOT_FOUND, so a share URL
140
+ * teaches a non-member nothing — not even whether the share exists. A
141
+ * non-member resolving a public share uses the anonymous lane instead.
142
+ *
143
+ * The question is can_view on the organization named in the reference (the
144
+ * viewer set: members and above), asked live on every call so a revoked
145
+ * member loses access at once; the RPC is is_skip_authorization because
146
+ * the target is the reference's organization, not a request field the
147
+ * annotation can key on. This is deliberately NOT the shared
148
+ * AuthorizeResolvedTarget step: that step answers deny with
149
+ * PERMISSION_DENIED, and this lane's wire contract is the indistinguishable
150
+ * NOT_FOUND above, so the lane keeps its own mapping over the same
151
+ * evaluation (the decision form checkMyPermission uses). An empty org is
152
+ * left to the loader's INVALID_ARGUMENT, the proto's own copy for it; an
153
+ * unavailable authorizer is INTERNAL, never softened into a refusal; the
154
+ * `internal` class is exempt as everywhere.
155
+ */
156
+ export function newAuthorizeMemberAudienceStep(
157
+ authorizer: Authorizer,
158
+ ): PipelineStep<GetByReferenceDesc> {
159
+ return {
160
+ name: "AuthorizeMemberAudience",
161
+ async execute(ctx: RequestContext<GetByReferenceDesc>): Promise<void> {
162
+ const ref = ctx.input;
163
+ if (ref.org === "" || ctx.callerIdentity.callerClass === "internal") {
164
+ return;
165
+ }
166
+ const decision = await evaluateAuthorizer(
167
+ authorizer,
168
+ ctx.callerIdentity,
169
+ {
170
+ permission: IamPermission.can_view,
171
+ resourceKind: ApiResourceKind.organization,
172
+ resourceId: ref.org,
173
+ },
174
+ );
175
+ switch (decision.kind) {
176
+ case "allow":
177
+ return;
178
+ case "deny":
179
+ case "not-found":
180
+ throw sharedNotFound(ref.slug);
181
+ case "unavailable":
182
+ throw internalError(
183
+ decision.cause,
184
+ AUTHORIZATION_UNAVAILABLE_MESSAGE,
185
+ );
186
+ default: {
187
+ const exhaustive: never = decision;
188
+ throw internalError(
189
+ new Error(`unknown decision ${JSON.stringify(exhaustive)}`),
190
+ AUTHORIZATION_UNAVAILABLE_MESSAGE,
191
+ );
192
+ }
193
+ }
194
+ },
195
+ };
196
+ }
197
+
81
198
  /**
82
199
  * The link-token predicate — Go sharingLinkTokenAllowed, the mirror of the
83
200
  * cloud edition's SharingLinkTokenPolicy:
@@ -90,7 +207,10 @@ export function sharedNotFound(slug: string): ConnectError {
90
207
  * guard restores Go's semantics; the length of a token is not secret (all
91
208
  * server-minted tokens are 27 chars).
92
209
  */
93
- export function sharingLinkTokenAllowed(presented: string, live: string): boolean {
210
+ export function sharingLinkTokenAllowed(
211
+ presented: string,
212
+ live: string,
213
+ ): boolean {
94
214
  if (live === "") {
95
215
  return true;
96
216
  }
@@ -174,15 +294,19 @@ export async function findShareByOrgAndSlug(
174
294
  /**
175
295
  * ResolveShareDefaults — Go resolveShareDefaultsStep:
176
296
  * 1. Requires metadata.org (URL + billing identity, never inferred).
177
- * 2. Normalizes spec.agent_ref.org (empty means same-org) and loads the
178
- * referenced agent — a nonexistent agent is refused with the same
179
- * NOT_FOUND a direct agent lookup would produce.
180
- * 3. For a CROSS-ORG share, enforces the decision-013 contract.
297
+ * 2. Normalizes spec.agent_ref.org (empty means same-org) and refuses an
298
+ * agent_ref that names another organization (the module header) with
299
+ * the same-organization sentence, BEFORE any lookup, so the share
300
+ * lane never says whether another organization's slug exists.
301
+ * 3. Loads the referenced agent — a nonexistent agent is refused with
302
+ * the same NOT_FOUND a direct agent lookup would produce.
181
303
  * 4. Defaults metadata.slug (and name) from the agent when the caller
182
304
  * provided neither — the canonical share keeps the agent's hosted URL.
183
305
  * Runs before ResolveSlug, which skips already-set slugs.
184
306
  */
185
- export function newResolveShareDefaultsStep(store: Store): PipelineStep<AgentShareDesc> {
307
+ export function newResolveShareDefaultsStep(
308
+ store: Store,
309
+ ): PipelineStep<AgentShareDesc> {
186
310
  return {
187
311
  name: "ResolveShareDefaults",
188
312
  async execute(ctx: RequestContext<AgentShareDesc>): Promise<void> {
@@ -203,16 +327,19 @@ export function newResolveShareDefaultsStep(store: Store): PipelineStep<AgentSha
203
327
  if (agentRef!.org === "") {
204
328
  agentRef!.org = metadata!.org;
205
329
  }
330
+ if (agentRef!.org !== metadata!.org) {
331
+ throw failedPreconditionError(sameOrgInvariantMessage(agentRef!.org));
332
+ }
206
333
 
207
- const agent = await findAgentByOrgAndSlug(store, agentRef!.org, agentRef!.slug);
334
+ const agent = await findAgentByOrgAndSlug(
335
+ store,
336
+ agentRef!.org,
337
+ agentRef!.slug,
338
+ );
208
339
  if (agent === undefined) {
209
340
  throw notFoundError("Agent", agentRef!.slug);
210
341
  }
211
342
 
212
- if (agentRef!.org !== metadata!.org) {
213
- await validateCrossOrgShare(store, share, agent);
214
- }
215
-
216
343
  ctx.set(REFERENCED_AGENT_KEY, agent);
217
344
 
218
345
  // Canonical-share default: no slug and no name means "share this
@@ -226,118 +353,6 @@ export function newResolveShareDefaultsStep(store: Store): PipelineStep<AgentSha
226
353
  };
227
354
  }
228
355
 
229
- /**
230
- * The cross-org share contract (decision 013) — Go validateCrossOrgShare:
231
- * - The agent must be marketplace-public; a non-public agent is refused
232
- * with the same NOT_FOUND as a missing one (no existence probe for
233
- * private slugs).
234
- * - The audience must be public — org-audience semantics don't carry
235
- * across the org boundary.
236
- * - Every declared dependency must itself be public; the refusal names
237
- * every blocker (sorted) so the sharing org knows exactly what to ask
238
- * the agent's org to publish.
239
- * Runtime re-enforcement is cloud-side; this create-time sweep is the
240
- * fail-loud half, mirrored in both editions.
241
- */
242
- async function validateCrossOrgShare(
243
- store: Store,
244
- share: AgentShare,
245
- agent: Agent,
246
- ): Promise<void> {
247
- const agentMeta = agent.metadata;
248
-
249
- if (agentMeta?.visibility !== ApiResourceVisibility.visibility_public) {
250
- throw notFoundError("Agent", agentMeta?.slug ?? "");
251
- }
252
-
253
- // protobuf-es strips the shared enum prefix: proto
254
- // agent_share_audience_org generates as AgentShareAudience.org.
255
- if (share.spec?.audience === AgentShareAudience.org) {
256
- throw failedPreconditionError(crossOrgAudienceMessage(agentMeta.org));
257
- }
258
-
259
- const blockers = await findNonPublicDependencies(store, agent);
260
- if (blockers.length > 0) {
261
- throw failedPreconditionError(
262
- crossOrgBlockersMessage(agentMeta.org, agentMeta.slug, blockers),
263
- );
264
- }
265
- }
266
-
267
- /**
268
- * Sweeps the agent's declared blueprint dependencies — skill_refs
269
- * (including every sub-agent's) and mcp_server_usages — and returns a
270
- * deterministic "kind org/slug" entry for each that is missing or not
271
- * visibility_public — Go findNonPublicDependencies. A reference with an
272
- * empty org is relative to the AGENT's org (defensive parity with the
273
- * cloud edition's referenceMatches; agent writes normalize refs to
274
- * absolute form).
275
- */
276
- async function findNonPublicDependencies(
277
- store: Store,
278
- agent: Agent,
279
- ): Promise<string[]> {
280
- const spec = agent.spec;
281
- const agentOrg = agent.metadata?.org ?? "";
282
-
283
- interface DepRef {
284
- kind: ApiResourceKind;
285
- org: string;
286
- slug: string;
287
- }
288
-
289
- const seen = new Set<string>();
290
- const deps: DepRef[] = [];
291
- const add = (kind: ApiResourceKind, ref: ApiResourceReference | undefined): void => {
292
- if (ref === undefined || ref.slug === "") {
293
- return;
294
- }
295
- const org = ref.org !== "" ? ref.org : agentOrg;
296
- const key = `${kind}|${org}|${ref.slug}`;
297
- if (!seen.has(key)) {
298
- seen.add(key);
299
- deps.push({ kind, org, slug: ref.slug });
300
- }
301
- };
302
-
303
- for (const ref of spec?.skillRefs ?? []) {
304
- add(ApiResourceKind.skill, ref);
305
- }
306
- for (const sub of spec?.subAgents ?? []) {
307
- for (const ref of sub.skillRefs) {
308
- add(ApiResourceKind.skill, ref);
309
- }
310
- }
311
- for (const usage of spec?.mcpServerUsages ?? []) {
312
- add(ApiResourceKind.mcp_server, usage.mcpServerRef);
313
- }
314
-
315
- const blockers: string[] = [];
316
- for (const dep of deps) {
317
- let visibility: ApiResourceVisibility | undefined;
318
- try {
319
- // Per-kind resolution, exactly Go's switch — skill and mcp_server
320
- // are the only dependency kinds an agent blueprint declares.
321
- const resolved =
322
- dep.kind === ApiResourceKind.skill
323
- ? await findResourceBySlug(store, dep.kind, SkillSchema, dep.slug, dep.org)
324
- : await findResourceBySlug(store, dep.kind, McpServerSchema, dep.slug, dep.org);
325
- visibility = resolved?.metadata?.visibility;
326
- } catch (error) {
327
- throw internalError(
328
- error,
329
- `failed to resolve ${ApiResourceKind[dep.kind]} ${dep.org}/${dep.slug} while validating cross-org share`,
330
- );
331
- }
332
- if (visibility !== ApiResourceVisibility.visibility_public) {
333
- blockers.push(`${ApiResourceKind[dep.kind]} ${dep.org}/${dep.slug}`);
334
- }
335
- }
336
-
337
- blockers.sort();
338
- return blockers;
339
- }
340
-
341
356
  /**
342
357
  * StampAgentPin — Go stampAgentPinStep: writes status.agent_id, the
343
358
  * server-owned rebind pin (decision 013). agent_ref is org+slug and slugs
@@ -371,10 +386,8 @@ export function newStampAgentPinStep(): PipelineStep<AgentShareDesc> {
371
386
 
372
387
  /**
373
388
  * ValidateShareUpdate — Go validateShareUpdateStep: spec.agent_ref must
374
- * keep referencing the same agent, and the cross-org public-audience rule
375
- * must hold on update too (update replaces the spec wholesale and must not
376
- * open a side door to an org-audience cross-org share). Runs after
377
- * LoadExisting. metadata.slug/org immutability needs no step — the generic
389
+ * keep referencing the same agent. Runs after LoadExisting.
390
+ * metadata.slug/org immutability needs no step — the generic
378
391
  * BuildUpdateState preserves both, and status (including the pin and link
379
392
  * token) wholesale.
380
393
  */
@@ -396,21 +409,21 @@ export function newValidateShareUpdateStep(): PipelineStep<AgentShareDesc> {
396
409
  // Normalize the input ref's org the same way create does (empty
397
410
  // means the share's own org) before comparing.
398
411
  const inputOrg =
399
- (inputRef?.org ?? "") !== "" ? inputRef!.org : (existing.metadata?.org ?? "");
412
+ (inputRef?.org ?? "") !== ""
413
+ ? inputRef!.org
414
+ : (existing.metadata?.org ?? "");
400
415
 
401
416
  if (
402
417
  (inputRef?.slug ?? "") !== (existingRef?.slug ?? "") ||
403
418
  inputOrg !== (existingRef?.org ?? "")
404
419
  ) {
405
420
  throw failedPreconditionError(
406
- agentRefImmutableMessage(existingRef?.org ?? "", existingRef?.slug ?? ""),
421
+ agentRefImmutableMessage(
422
+ existingRef?.org ?? "",
423
+ existingRef?.slug ?? "",
424
+ ),
407
425
  );
408
426
  }
409
-
410
- const isCrossOrg = (existingRef?.org ?? "") !== (existing.metadata?.org ?? "");
411
- if (isCrossOrg && ctx.input.spec?.audience === AgentShareAudience.org) {
412
- throw failedPreconditionError(crossOrgAudienceMessage(existingRef?.org ?? ""));
413
- }
414
427
  },
415
428
  };
416
429
  }
@@ -422,15 +435,19 @@ export function newValidateShareUpdateStep(): PipelineStep<AgentShareDesc> {
422
435
  * SHARE; display fields and default_instance_id from the AGENT. Three
423
436
  * misses all fail closed with the uniform refusal, indistinguishable from
424
437
  * absence: a dangling agent_ref, a stale agent-id pin (the rebind guard),
425
- * and a cross-org agent no longer visibility_public (withdrawing public
426
- * visibility must kill every external channel).
438
+ * and an agent in another organization (a share written before the
439
+ * same-organization invariant; this release serves no such share).
427
440
  */
428
441
  export async function buildSharedAgentProfile(
429
442
  store: Store,
430
443
  share: AgentShare,
431
444
  ): Promise<SharedAgentProfile> {
432
445
  const ref = share.spec?.agentRef;
433
- const agent = await findAgentByOrgAndSlug(store, ref?.org ?? "", ref?.slug ?? "");
446
+ const agent = await findAgentByOrgAndSlug(
447
+ store,
448
+ ref?.org ?? "",
449
+ ref?.slug ?? "",
450
+ );
434
451
  if (agent === undefined) {
435
452
  throw sharedNotFound(share.metadata?.slug ?? "");
436
453
  }
@@ -440,11 +457,7 @@ export async function buildSharedAgentProfile(
440
457
  throw sharedNotFound(share.metadata?.slug ?? "");
441
458
  }
442
459
 
443
- const isCrossOrg = (share.metadata?.org ?? "") !== (agent.metadata?.org ?? "");
444
- if (
445
- isCrossOrg &&
446
- agent.metadata?.visibility !== ApiResourceVisibility.visibility_public
447
- ) {
460
+ if ((share.metadata?.org ?? "") !== (agent.metadata?.org ?? "")) {
448
461
  throw sharedNotFound(share.metadata?.slug ?? "");
449
462
  }
450
463
 
@@ -66,9 +66,9 @@ import { callerIdentityOf } from "../../pipeline/interceptors/auth.js";
66
66
  import { RequestContext } from "../../pipeline/request-context.js";
67
67
  import {
68
68
  authorizeDirect,
69
- authorizeResolvedResource,
70
69
  newAuthorizeStep,
71
70
  } from "../../pipeline/steps/authorize.js";
71
+ import { newAuthorizeResolvedTargetStep } from "../../pipeline/steps/authorize-resolved-target.js";
72
72
  import {
73
73
  generateId,
74
74
  setAuditFieldsForCreate,
@@ -426,23 +426,18 @@ async function listByExecution(
426
426
  }
427
427
  },
428
428
  })
429
- .addStep({
430
- name: "AuthorizeParentExecution",
431
- async execute(stepCtx): Promise<void> {
432
- // The Java ArtifactListByExecutionHandler's hand-rolled gate
433
- // (20260830.01 ruling Q8): can_view on the PARENT execution —
434
- // "if you can view an execution, you can list its artifacts."
435
- // The two-field dispatch (workflow-execution first, the Java
436
- // order) is why the declarative annotation cannot express this
437
- // lane and the proto carries is_skip_authorization. Deny copy is
438
- // the Java handler's byte-pinned error_msg; a nonexistent id
439
- // answers NOT_FOUND through the authorizer's probe — the ruled
440
- // uniform unknown-id posture (DD-007 addendum), a recorded
441
- // divergence from Java's deny-everyone arm on this lane.
442
- const input = stepCtx.input;
443
- await authorizeResolvedResource(
444
- deps.authorizer,
445
- stepCtx.callerIdentity,
429
+ // The Java ArtifactListByExecutionHandler's gate: can_view on the PARENT
430
+ // execution — "if you can view an execution, you can list its
431
+ // artifacts." The two-field dispatch (workflow-execution first, the Java
432
+ // order) is why the declarative annotation cannot express this lane and
433
+ // the proto carries is_skip_authorization. Deny copy is the Java
434
+ // handler's byte-pinned error_msg; a nonexistent id answers NOT_FOUND
435
+ // through the authorizer's probe — the ruled uniform unknown-id
436
+ // posture, a recorded divergence from Java's deny-everyone arm here.
437
+ .addStep(
438
+ newAuthorizeResolvedTargetStep(
439
+ deps.authorizer,
440
+ ({ input }) => [
446
441
  {
447
442
  permission: IamPermission.can_view,
448
443
  resourceKind:
@@ -453,11 +448,12 @@ async function listByExecution(
453
448
  input.workflowExecutionId !== ""
454
449
  ? input.workflowExecutionId
455
450
  : input.agentExecutionId,
451
+ deniedMessage: "unauthorized to list artifacts for this execution",
456
452
  },
457
- "unauthorized to list artifacts for this execution",
458
- );
459
- },
460
- })
453
+ ],
454
+ "AuthorizeParentExecution",
455
+ ),
456
+ )
461
457
  .addStep({
462
458
  name: "QueryArtifactsByExecution",
463
459
  async execute(stepCtx): Promise<void> {
@@ -51,6 +51,10 @@ import type { PipelineStep } from "../../pipeline/pipeline.js";
51
51
  import { callerIdentityOf } from "../../pipeline/interceptors/auth.js";
52
52
  import { RequestContext } from "../../pipeline/request-context.js";
53
53
  import { newAuthorizeStep } from "../../pipeline/steps/authorize.js";
54
+ import {
55
+ loadedTargetAsMethod,
56
+ newAuthorizeResolvedTargetStep,
57
+ } from "../../pipeline/steps/authorize-resolved-target.js";
54
58
  import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
55
59
  import { newBuildNewStateStep } from "../../pipeline/steps/defaults.js";
56
60
  import { newBuildUpdateStateStep } from "../../pipeline/steps/build-update-state.js";
@@ -369,6 +373,12 @@ async function getByReference(
369
373
  )
370
374
  .addStep(newValidateProtoStep())
371
375
  .addStep(newLoadByReferenceStep(deps.store, ChannelAppSchema))
376
+ .addStep(
377
+ newAuthorizeResolvedTargetStep(
378
+ deps.authorizer,
379
+ loadedTargetAsMethod(ChannelAppQueryController.method.get),
380
+ ),
381
+ )
372
382
  .build()
373
383
  .execute(reqCtx);
374
384
  const app = reqCtx.get(TARGET_RESOURCE_KEY) as ChannelApp;
@@ -58,8 +58,11 @@ import type { PipelineStep } from "../../pipeline/pipeline.js";
58
58
  import { callerIdentityOf } from "../../pipeline/interceptors/auth.js";
59
59
  import { RequestContext } from "../../pipeline/request-context.js";
60
60
  import { newAuthorizeStep } from "../../pipeline/steps/authorize.js";
61
+ import {
62
+ loadedTargetAsMethod,
63
+ newAuthorizeResolvedTargetStep,
64
+ } from "../../pipeline/steps/authorize-resolved-target.js";
61
65
  import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
62
- import { newAuthorizeVisibilityTransitionStep } from "../../pipeline/steps/visibility-gates.js";
63
66
  import {
64
67
  newBuildNewStateStep,
65
68
  setAuditFieldsForUpdate,
@@ -93,7 +96,10 @@ import {
93
96
  TARGET_RESOURCE_KEY,
94
97
  newLoadTargetStep,
95
98
  } from "../../pipeline/steps/load-target.js";
96
- import { newNormalizeReferencesStep } from "../../pipeline/steps/references.js";
99
+ import {
100
+ newNormalizeReferencesStep,
101
+ newValidateReferencesStep,
102
+ } from "../../pipeline/steps/references.js";
97
103
  import {
98
104
  newCleanupIamPoliciesStep,
99
105
  newCreateAuthorizationTuplesStep,
@@ -240,6 +246,7 @@ async function update(
240
246
  .addStep(newPreserveRedactedSecretsStep())
241
247
  .addStep(newEncryptSecretValuesStep(deps.secretService, deps.logger))
242
248
  .addStep(newNormalizeReferencesStep())
249
+ .addStep(newValidateReferencesStep(deps.store))
243
250
  .addStep(newPersistStep(deps.store))
244
251
  .addStep(
245
252
  newDestroyDroppedEnvironmentSecretsStep(deps.secretService, deps.logger),
@@ -394,12 +401,6 @@ async function updateVisibility(
394
401
  // After load, per the cross-edition error precedence: unknown id +
395
402
  // bad level = NOT_FOUND on both editions.
396
403
  .addStep(newValidateVisibilityUpdateStep())
397
- .addStep(
398
- newAuthorizeVisibilityTransitionStep(
399
- UPDATE_VISIBILITY_ENVIRONMENT_KEY,
400
- deps.authorizer,
401
- ),
402
- )
403
404
  .addStep(newValidateEnvironmentShareRestrictionStep())
404
405
  .addStep(newSetEnvironmentVisibilityStep())
405
406
  .addStep(newPersistEnvironmentForVisibilityUpdateStep(deps.store))
@@ -682,6 +683,12 @@ async function getByReference(
682
683
  )
683
684
  .addStep(newValidateProtoStep())
684
685
  .addStep(newLoadByReferenceStep(deps.store, EnvironmentSchema))
686
+ .addStep(
687
+ newAuthorizeResolvedTargetStep(
688
+ deps.authorizer,
689
+ loadedTargetAsMethod(EnvironmentQueryController.method.get),
690
+ ),
691
+ )
685
692
  .build()
686
693
  .execute(reqCtx);
687
694
  const env = reqCtx.get(TARGET_RESOURCE_KEY) as Environment;
@@ -277,6 +277,7 @@ describe("executioncontext domain (encryption + runner auth enabled)", () => {
277
277
  () =>
278
278
  ts.query.getByReference({
279
279
  kind: ApiResourceKind.execution_context,
280
+ org: created.metadata!.org,
280
281
  slug: created.metadata!.slug,
281
282
  }),
282
283
  ],
@@ -56,6 +56,10 @@ import { newPipeline } from "../../pipeline/pipeline.js";
56
56
  import { callerIdentityOf } from "../../pipeline/interceptors/auth.js";
57
57
  import { RequestContext } from "../../pipeline/request-context.js";
58
58
  import { newAuthorizeStep } from "../../pipeline/steps/authorize.js";
59
+ import {
60
+ loadedTargetAsMethod,
61
+ newAuthorizeResolvedTargetStep,
62
+ } from "../../pipeline/steps/authorize-resolved-target.js";
59
63
  import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
60
64
  import { newBuildNewStateStep } from "../../pipeline/steps/defaults.js";
61
65
  import {
@@ -78,7 +82,10 @@ import {
78
82
  TARGET_RESOURCE_KEY,
79
83
  newLoadTargetStep,
80
84
  } from "../../pipeline/steps/load-target.js";
81
- import { newNormalizeReferencesStep } from "../../pipeline/steps/references.js";
85
+ import {
86
+ newNormalizeReferencesStep,
87
+ newValidateReferencesStep,
88
+ } from "../../pipeline/steps/references.js";
82
89
  import {
83
90
  newCleanupIamPoliciesStep,
84
91
  newCreateAuthorizationTuplesStep,
@@ -182,6 +189,7 @@ async function createExecutionContext(
182
189
  .addStep(newBuildNewStateStep())
183
190
  .addStep(newGuardReservedLabelsStep(deps.authorizer))
184
191
  .addStep(newNormalizeReferencesStep())
192
+ .addStep(newValidateReferencesStep(deps.store))
185
193
  .addStep(newEncryptSecretValuesStep(deps.secretService, deps.logger))
186
194
  .addStep(newPersistStep(deps.store))
187
195
  .addStep(
@@ -361,6 +369,12 @@ async function getByReference(
361
369
  )
362
370
  .addStep(newValidateProtoStep())
363
371
  .addStep(newLoadByReferenceStep(deps.store, ExecutionContextSchema))
372
+ .addStep(
373
+ newAuthorizeResolvedTargetStep(
374
+ deps.authorizer,
375
+ loadedTargetAsMethod(ExecutionContextQueryController.method.get),
376
+ ),
377
+ )
364
378
  .build()
365
379
  .execute(reqCtx);
366
380
  const ec = reqCtx.get(TARGET_RESOURCE_KEY) as ExecutionContext;
@@ -34,6 +34,7 @@ import { isCiphertextShaped } from "../../encryption/encryption.js";
34
34
  import type { SecretService } from "../../encryption/encryption.js";
35
35
  import { EncryptionScope } from "../../encryption/encryption.js";
36
36
  import type { Authorizer, AuthzDecision } from "../../extensions/authorizer.js";
37
+ import { isServerComposedRequest } from "../../extensions/identity.js";
37
38
  import {
38
39
  internalError,
39
40
  invalidArgumentError,
@@ -240,7 +241,7 @@ export function newAuthorizeExecutionContextCreateStep(
240
241
  ctx: RequestContext<typeof ExecutionContextSchema>,
241
242
  ): Promise<void> {
242
243
  const caller = ctx.callerIdentity;
243
- if (caller.callerClass === "internal" || caller.origin === "in-process") {
244
+ if (isServerComposedRequest(caller)) {
244
245
  return; // authorized upstream — the Java in-process trust arm
245
246
  }
246
247
  let decision: AuthzDecision;