@stigmer/server 3.22.1-dev.20260922095755 → 3.23.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 (330) hide show
  1. package/dist/artifactstorage/artifact-storage.d.ts +29 -31
  2. package/dist/artifactstorage/artifact-storage.d.ts.map +1 -1
  3. package/dist/artifactstorage/artifact-storage.js +5 -7
  4. package/dist/artifactstorage/artifact-storage.js.map +1 -1
  5. package/dist/artifactstorage/r2-storage.d.ts +12 -7
  6. package/dist/artifactstorage/r2-storage.d.ts.map +1 -1
  7. package/dist/artifactstorage/r2-storage.js +6 -14
  8. package/dist/artifactstorage/r2-storage.js.map +1 -1
  9. package/dist/authorization/authorizer.d.ts +8 -4
  10. package/dist/authorization/authorizer.d.ts.map +1 -1
  11. package/dist/authorization/authorizer.js +9 -5
  12. package/dist/authorization/authorizer.js.map +1 -1
  13. package/dist/authorization/derived-tuples.d.ts.map +1 -1
  14. package/dist/authorization/derived-tuples.js +25 -10
  15. package/dist/authorization/derived-tuples.js.map +1 -1
  16. package/dist/authorization/evaluator.d.ts +8 -7
  17. package/dist/authorization/evaluator.d.ts.map +1 -1
  18. package/dist/authorization/evaluator.js +20 -4
  19. package/dist/authorization/evaluator.js.map +1 -1
  20. package/dist/authorization/list-read-scope.d.ts.map +1 -1
  21. package/dist/authorization/list-read-scope.js +9 -5
  22. package/dist/authorization/list-read-scope.js.map +1 -1
  23. package/dist/authorization/model/agent.d.ts.map +1 -1
  24. package/dist/authorization/model/agent.js +5 -4
  25. package/dist/authorization/model/agent.js.map +1 -1
  26. package/dist/authorization/model/agent_instance.d.ts.map +1 -1
  27. package/dist/authorization/model/agent_instance.js +2 -2
  28. package/dist/authorization/model/agent_instance.js.map +1 -1
  29. package/dist/authorization/model/mcp_server.d.ts.map +1 -1
  30. package/dist/authorization/model/mcp_server.js +2 -2
  31. package/dist/authorization/model/mcp_server.js.map +1 -1
  32. package/dist/authorization/model/plugin.d.ts.map +1 -1
  33. package/dist/authorization/model/plugin.js +4 -3
  34. package/dist/authorization/model/plugin.js.map +1 -1
  35. package/dist/authorization/model/rewrite.d.ts +10 -8
  36. package/dist/authorization/model/rewrite.d.ts.map +1 -1
  37. package/dist/authorization/model/rewrite.js +3 -0
  38. package/dist/authorization/model/rewrite.js.map +1 -1
  39. package/dist/authorization/model/skill.d.ts.map +1 -1
  40. package/dist/authorization/model/skill.js +2 -2
  41. package/dist/authorization/model/skill.js.map +1 -1
  42. package/dist/authorization/model/workflow.d.ts.map +1 -1
  43. package/dist/authorization/model/workflow.js +2 -2
  44. package/dist/authorization/model/workflow.js.map +1 -1
  45. package/dist/authorization/model/workflow_instance.d.ts.map +1 -1
  46. package/dist/authorization/model/workflow_instance.js +2 -2
  47. package/dist/authorization/model/workflow_instance.js.map +1 -1
  48. package/dist/authorization/organization-directory.d.ts.map +1 -1
  49. package/dist/authorization/organization-directory.js +3 -2
  50. package/dist/authorization/organization-directory.js.map +1 -1
  51. package/dist/authorization/store-test-kit.d.ts +6 -0
  52. package/dist/authorization/store-test-kit.d.ts.map +1 -1
  53. package/dist/authorization/store-test-kit.js +62 -16
  54. package/dist/authorization/store-test-kit.js.map +1 -1
  55. package/dist/authorization/tuples.d.ts +32 -13
  56. package/dist/authorization/tuples.d.ts.map +1 -1
  57. package/dist/authorization/tuples.js +11 -3
  58. package/dist/authorization/tuples.js.map +1 -1
  59. package/dist/boot/compose.d.ts.map +1 -1
  60. package/dist/boot/compose.js +49 -24
  61. package/dist/boot/compose.js.map +1 -1
  62. package/dist/boot/config.d.ts +4 -3
  63. package/dist/boot/config.d.ts.map +1 -1
  64. package/dist/boot/config.js.map +1 -1
  65. package/dist/boot/skill-transfer-origin.d.ts +52 -0
  66. package/dist/boot/skill-transfer-origin.d.ts.map +1 -0
  67. package/dist/boot/skill-transfer-origin.js +54 -0
  68. package/dist/boot/skill-transfer-origin.js.map +1 -0
  69. package/dist/domain/agent/controller.d.ts.map +1 -1
  70. package/dist/domain/agent/controller.js +4 -4
  71. package/dist/domain/agent/controller.js.map +1 -1
  72. package/dist/domain/agentchannel/controller.d.ts.map +1 -1
  73. package/dist/domain/agentchannel/controller.js +1 -3
  74. package/dist/domain/agentchannel/controller.js.map +1 -1
  75. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  76. package/dist/domain/agentexecution/controller.js +1 -3
  77. package/dist/domain/agentexecution/controller.js.map +1 -1
  78. package/dist/domain/agentinstance/controller.d.ts.map +1 -1
  79. package/dist/domain/agentinstance/controller.js +4 -3
  80. package/dist/domain/agentinstance/controller.js.map +1 -1
  81. package/dist/domain/agentshare/constants.d.ts +11 -6
  82. package/dist/domain/agentshare/constants.d.ts.map +1 -1
  83. package/dist/domain/agentshare/constants.js +16 -8
  84. package/dist/domain/agentshare/constants.js.map +1 -1
  85. package/dist/domain/agentshare/controller.d.ts.map +1 -1
  86. package/dist/domain/agentshare/controller.js +1 -3
  87. package/dist/domain/agentshare/controller.js.map +1 -1
  88. package/dist/domain/agentshare/steps.d.ts +25 -18
  89. package/dist/domain/agentshare/steps.d.ts.map +1 -1
  90. package/dist/domain/agentshare/steps.js +142 -41
  91. package/dist/domain/agentshare/steps.js.map +1 -1
  92. package/dist/domain/environment/controller.d.ts.map +1 -1
  93. package/dist/domain/environment/controller.js +3 -2
  94. package/dist/domain/environment/controller.js.map +1 -1
  95. package/dist/domain/executioncontext/controller.d.ts.map +1 -1
  96. package/dist/domain/executioncontext/controller.js +1 -2
  97. package/dist/domain/executioncontext/controller.js.map +1 -1
  98. package/dist/domain/mcpserver/controller.d.ts.map +1 -1
  99. package/dist/domain/mcpserver/controller.js +4 -3
  100. package/dist/domain/mcpserver/controller.js.map +1 -1
  101. package/dist/domain/plugin/controller.d.ts +3 -7
  102. package/dist/domain/plugin/controller.d.ts.map +1 -1
  103. package/dist/domain/plugin/controller.js +11 -9
  104. package/dist/domain/plugin/controller.js.map +1 -1
  105. package/dist/domain/plugin/push.d.ts +5 -7
  106. package/dist/domain/plugin/push.d.ts.map +1 -1
  107. package/dist/domain/plugin/push.js +14 -8
  108. package/dist/domain/plugin/push.js.map +1 -1
  109. package/dist/domain/schedule/controller.d.ts.map +1 -1
  110. package/dist/domain/schedule/controller.js +1 -3
  111. package/dist/domain/schedule/controller.js.map +1 -1
  112. package/dist/domain/session/controller.d.ts.map +1 -1
  113. package/dist/domain/session/controller.js +2 -3
  114. package/dist/domain/session/controller.js.map +1 -1
  115. package/dist/domain/skill/constants.d.ts +26 -3
  116. package/dist/domain/skill/constants.d.ts.map +1 -1
  117. package/dist/domain/skill/constants.js +26 -3
  118. package/dist/domain/skill/constants.js.map +1 -1
  119. package/dist/domain/skill/controller.d.ts +6 -11
  120. package/dist/domain/skill/controller.d.ts.map +1 -1
  121. package/dist/domain/skill/controller.js +35 -22
  122. package/dist/domain/skill/controller.js.map +1 -1
  123. package/dist/domain/skill/push.d.ts +2 -2
  124. package/dist/domain/skill/push.d.ts.map +1 -1
  125. package/dist/domain/skill/push.js +2 -2
  126. package/dist/domain/skill/push.js.map +1 -1
  127. package/dist/domain/skill/transfer/handler.d.ts +17 -9
  128. package/dist/domain/skill/transfer/handler.d.ts.map +1 -1
  129. package/dist/domain/skill/transfer/handler.js +19 -8
  130. package/dist/domain/skill/transfer/handler.js.map +1 -1
  131. package/dist/domain/skill/transfer/slots.d.ts +26 -41
  132. package/dist/domain/skill/transfer/slots.d.ts.map +1 -1
  133. package/dist/domain/skill/transfer/slots.js +80 -87
  134. package/dist/domain/skill/transfer/slots.js.map +1 -1
  135. package/dist/domain/skill/transfer/staging.d.ts +48 -0
  136. package/dist/domain/skill/transfer/staging.d.ts.map +1 -0
  137. package/dist/domain/skill/transfer/staging.js +127 -0
  138. package/dist/domain/skill/transfer/staging.js.map +1 -0
  139. package/dist/domain/workflow/controller.d.ts.map +1 -1
  140. package/dist/domain/workflow/controller.js +6 -14
  141. package/dist/domain/workflow/controller.js.map +1 -1
  142. package/dist/domain/workflow/registry/data/task-kind-registry.json +1 -1
  143. package/dist/domain/workflow/validation/task-config-constraints.d.ts +1 -10
  144. package/dist/domain/workflow/validation/task-config-constraints.d.ts.map +1 -1
  145. package/dist/domain/workflow/validation/task-config-constraints.js +2 -3
  146. package/dist/domain/workflow/validation/task-config-constraints.js.map +1 -1
  147. package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
  148. package/dist/domain/workflowexecution/controller.js +2 -4
  149. package/dist/domain/workflowexecution/controller.js.map +1 -1
  150. package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
  151. package/dist/domain/workflowinstance/controller.js +4 -3
  152. package/dist/domain/workflowinstance/controller.js.map +1 -1
  153. package/dist/extensions/authorization-queries.d.ts +5 -6
  154. package/dist/extensions/authorization-queries.d.ts.map +1 -1
  155. package/dist/extensions/list-read-scope.d.ts +1 -1
  156. package/dist/extensions/resource-authorization.d.ts +2 -3
  157. package/dist/extensions/resource-authorization.d.ts.map +1 -1
  158. package/dist/index.d.ts +3 -1
  159. package/dist/index.d.ts.map +1 -1
  160. package/dist/index.js +13 -0
  161. package/dist/index.js.map +1 -1
  162. package/dist/pipeline/apiresource-meta.d.ts +3 -12
  163. package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
  164. package/dist/pipeline/apiresource-meta.js +10 -21
  165. package/dist/pipeline/apiresource-meta.js.map +1 -1
  166. package/dist/pipeline/steps/authorization-tuples.d.ts +3 -9
  167. package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
  168. package/dist/pipeline/steps/authorization-tuples.js +11 -9
  169. package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
  170. package/dist/pipeline/steps/references.d.ts +20 -178
  171. package/dist/pipeline/steps/references.d.ts.map +1 -1
  172. package/dist/pipeline/steps/references.js +43 -344
  173. package/dist/pipeline/steps/references.js.map +1 -1
  174. package/dist/pipeline/steps/resolve-artifact-source.d.ts +11 -8
  175. package/dist/pipeline/steps/resolve-artifact-source.d.ts.map +1 -1
  176. package/dist/pipeline/steps/resolve-artifact-source.js +8 -4
  177. package/dist/pipeline/steps/resolve-artifact-source.js.map +1 -1
  178. package/dist/pipeline/steps/visibility-gates.d.ts +27 -0
  179. package/dist/pipeline/steps/visibility-gates.d.ts.map +1 -0
  180. package/dist/pipeline/steps/visibility-gates.js +139 -0
  181. package/dist/pipeline/steps/visibility-gates.js.map +1 -0
  182. package/dist/query/search/controller.js +1 -0
  183. package/dist/query/search/controller.js.map +1 -1
  184. package/dist/query/search/criteria.d.ts +5 -1
  185. package/dist/query/search/criteria.d.ts.map +1 -1
  186. package/dist/query/search/criteria.js +13 -3
  187. package/dist/query/search/criteria.js.map +1 -1
  188. package/dist/query/search/handler.d.ts +4 -5
  189. package/dist/query/search/handler.d.ts.map +1 -1
  190. package/dist/query/search/handler.js +6 -7
  191. package/dist/query/search/handler.js.map +1 -1
  192. package/dist/query/search/query-store.d.ts.map +1 -1
  193. package/dist/query/search/query-store.js +2 -0
  194. package/dist/query/search/query-store.js.map +1 -1
  195. package/dist/store/interface.d.ts +6 -3
  196. package/dist/store/interface.d.ts.map +1 -1
  197. package/dist/store/interface.js.map +1 -1
  198. package/dist/store/postgres/migrations.d.ts +1 -3
  199. package/dist/store/postgres/migrations.d.ts.map +1 -1
  200. package/dist/store/postgres/migrations.js +1 -35
  201. package/dist/store/postgres/migrations.js.map +1 -1
  202. package/dist/store/postgres/store.d.ts.map +1 -1
  203. package/dist/store/postgres/store.js +9 -4
  204. package/dist/store/postgres/store.js.map +1 -1
  205. package/dist/store/sqlite/migrations.d.ts +1 -3
  206. package/dist/store/sqlite/migrations.d.ts.map +1 -1
  207. package/dist/store/sqlite/migrations.js +1 -36
  208. package/dist/store/sqlite/migrations.js.map +1 -1
  209. package/dist/store/sqlite/store.d.ts.map +1 -1
  210. package/dist/store/sqlite/store.js +8 -4
  211. package/dist/store/sqlite/store.js.map +1 -1
  212. package/package.json +6 -6
  213. package/src/artifactstorage/__tests__/artifact-storage.test.ts +36 -33
  214. package/src/artifactstorage/__tests__/r2-storage.test.ts +11 -13
  215. package/src/artifactstorage/artifact-storage.ts +37 -33
  216. package/src/artifactstorage/r2-storage.ts +6 -15
  217. package/src/authorization/README.md +26 -24
  218. package/src/authorization/__tests__/authorizer.test.ts +9 -10
  219. package/src/authorization/__tests__/derived-tuples.test.ts +11 -4
  220. package/src/authorization/__tests__/evaluator.test.ts +73 -14
  221. package/src/authorization/__tests__/facts.test.ts +2 -2
  222. package/src/authorization/__tests__/fixtures/fga/agent-instance-creation.fga.yaml +185 -0
  223. package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +98 -6
  224. package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +98 -0
  225. package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +61 -4
  226. package/src/authorization/__tests__/fixtures/fga/mcp-server-authoring.fga.yaml +143 -0
  227. package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +21 -1
  228. package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +25 -1
  229. package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +52 -0
  230. package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +3 -1
  231. package/src/authorization/__tests__/list-read-scope.test.ts +17 -18
  232. package/src/authorization/__tests__/store-tests.test.ts +8 -1
  233. package/src/authorization/__tests__/tuples.test.ts +11 -12
  234. package/src/authorization/authorizer.ts +9 -4
  235. package/src/authorization/derived-tuples.ts +31 -14
  236. package/src/authorization/evaluator.ts +44 -8
  237. package/src/authorization/list-read-scope.ts +11 -5
  238. package/src/authorization/model/agent.ts +5 -2
  239. package/src/authorization/model/agent_instance.ts +2 -0
  240. package/src/authorization/model/mcp_server.ts +2 -0
  241. package/src/authorization/model/plugin.ts +4 -1
  242. package/src/authorization/model/rewrite.ts +13 -8
  243. package/src/authorization/model/skill.ts +2 -0
  244. package/src/authorization/model/workflow.ts +2 -0
  245. package/src/authorization/model/workflow_instance.ts +2 -0
  246. package/src/authorization/organization-directory.ts +3 -1
  247. package/src/authorization/store-test-kit.ts +75 -16
  248. package/src/authorization/tuples.ts +39 -16
  249. package/src/boot/__tests__/skill-transfer-origin.test.ts +72 -0
  250. package/src/boot/compose.ts +62 -25
  251. package/src/boot/config.ts +4 -3
  252. package/src/boot/skill-transfer-origin.ts +76 -0
  253. package/src/domain/agent/__tests__/agent.test.ts +4 -11
  254. package/src/domain/agent/controller.ts +7 -7
  255. package/src/domain/agentchannel/__tests__/agentchannel.test.ts +48 -223
  256. package/src/domain/agentchannel/controller.ts +1 -6
  257. package/src/domain/agentexecution/controller.ts +1 -6
  258. package/src/domain/agentinstance/controller.ts +12 -6
  259. package/src/domain/agentshare/__tests__/agentshare.test.ts +172 -196
  260. package/src/domain/agentshare/__tests__/create-authorization.test.ts +31 -16
  261. package/src/domain/agentshare/constants.ts +26 -14
  262. package/src/domain/agentshare/controller.ts +1 -6
  263. package/src/domain/agentshare/steps.ts +194 -41
  264. package/src/domain/environment/controller.ts +8 -5
  265. package/src/domain/executioncontext/controller.ts +1 -5
  266. package/src/domain/mcpserver/__tests__/mcpserver.test.ts +28 -115
  267. package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +18 -53
  268. package/src/domain/mcpserver/controller.ts +12 -6
  269. package/src/domain/plugin/controller.ts +23 -18
  270. package/src/domain/plugin/push.ts +16 -8
  271. package/src/domain/schedule/controller.ts +1 -6
  272. package/src/domain/session/controller.ts +4 -12
  273. package/src/domain/skill/__tests__/skill.test.ts +5 -3
  274. package/src/domain/skill/__tests__/slots.test.ts +113 -60
  275. package/src/domain/skill/__tests__/staging.test.ts +304 -0
  276. package/src/domain/skill/constants.ts +28 -3
  277. package/src/domain/skill/controller.ts +51 -35
  278. package/src/domain/skill/push.ts +3 -3
  279. package/src/domain/skill/transfer/handler.ts +33 -15
  280. package/src/domain/skill/transfer/slots.ts +89 -100
  281. package/src/domain/skill/transfer/staging.ts +191 -0
  282. package/src/domain/workflow/controller.ts +10 -28
  283. package/src/domain/workflow/registry/data/task-kind-registry.json +1 -1
  284. package/src/domain/workflow/validation/task-config-constraints.ts +3 -7
  285. package/src/domain/workflowexecution/controller.ts +2 -7
  286. package/src/domain/workflowinstance/controller.ts +12 -6
  287. package/src/extensions/__tests__/built-in-authorization-composed.test.ts +19 -32
  288. package/src/extensions/__tests__/extension-composition.test.ts +4 -4
  289. package/src/extensions/__tests__/list-read-scope-composed.test.ts +6 -9
  290. package/src/extensions/authorization-queries.ts +5 -6
  291. package/src/extensions/list-read-scope.ts +1 -1
  292. package/src/extensions/resource-authorization.ts +5 -3
  293. package/src/index.ts +14 -0
  294. package/src/pipeline/apiresource-meta.ts +10 -21
  295. package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +31 -18
  296. package/src/pipeline/steps/__tests__/visibility-gates.test.ts +187 -0
  297. package/src/pipeline/steps/authorization-tuples.ts +11 -9
  298. package/src/pipeline/steps/references.ts +70 -578
  299. package/src/pipeline/steps/resolve-artifact-source.ts +20 -13
  300. package/src/pipeline/steps/visibility-gates.ts +174 -0
  301. package/src/query/search/__tests__/criteria.test.ts +4 -0
  302. package/src/query/search/__tests__/query-store.test.ts +40 -11
  303. package/src/query/search/controller.ts +1 -0
  304. package/src/query/search/criteria.ts +14 -0
  305. package/src/query/search/handler.ts +7 -6
  306. package/src/query/search/query-store.ts +2 -0
  307. package/src/store/__tests__/store-contract.ts +51 -6
  308. package/src/store/interface.ts +6 -3
  309. package/src/store/postgres/__tests__/migrations.test.ts +6 -187
  310. package/src/store/postgres/__tests__/store-contract.test.ts +2 -0
  311. package/src/store/postgres/migrations.ts +1 -48
  312. package/src/store/postgres/store.ts +11 -4
  313. package/src/store/sqlite/__tests__/migrations.test.ts +5 -191
  314. package/src/store/sqlite/migrations.ts +1 -45
  315. package/src/store/sqlite/store.ts +10 -4
  316. package/src/transport/registry/__tests__/lanes.test.ts +1 -1
  317. package/dist/domain/workflow/agent-call-references.d.ts +0 -54
  318. package/dist/domain/workflow/agent-call-references.d.ts.map +0 -1
  319. package/dist/domain/workflow/agent-call-references.js +0 -97
  320. package/dist/domain/workflow/agent-call-references.js.map +0 -1
  321. package/dist/store/public-visibility-retired.d.ts +0 -67
  322. package/dist/store/public-visibility-retired.d.ts.map +0 -1
  323. package/dist/store/public-visibility-retired.js +0 -55
  324. package/dist/store/public-visibility-retired.js.map +0 -1
  325. package/src/domain/workflow/__tests__/agent-call-references.test.ts +0 -222
  326. package/src/domain/workflow/agent-call-references.ts +0 -157
  327. package/src/pipeline/__tests__/supports-visibility.test.ts +0 -112
  328. package/src/pipeline/steps/__tests__/references.test.ts +0 -703
  329. package/src/store/__tests__/public-visibility-retired.test.ts +0 -127
  330. package/src/store/public-visibility-retired.ts +0 -119
@@ -266,18 +266,9 @@ function tierRank(tier: ResourceTier): number {
266
266
  }
267
267
 
268
268
  /**
269
- * Whether a kind may hold a visibility level — the one predicate behind the
270
- * ValidateVisibility doors on every create and updateVisibility chain.
271
- *
272
- * PRIVATE and UNSPECIFIED are always supported (no visibility grant is
273
- * written for them); ORG and PLATFORM require the matching supports_* flag
274
- * on the kind's VisibilityConfig, so kinds with no config are private-only.
275
- * PUBLIC is refused for every kind: the level is retired (it made a row
276
- * readable to every account on the server), no config may declare it, and
277
- * the answer is fixed here rather than read from a flag that no longer
278
- * exists. Every level is named so a level added to the enum must be taught
279
- * here before any row can hold it; the closing arm is unreachable by wire
280
- * input, because both doors validate the field `defined_only` first.
269
+ * Go SupportsVisibility: PRIVATE and UNSPECIFIED are always supported (no
270
+ * visibility grant); every other level requires the matching supports_*
271
+ * flag. Kinds with no VisibilityConfig are private-only.
281
272
  */
282
273
  export function supportsVisibility(
283
274
  kind: ApiResourceKind,
@@ -285,19 +276,14 @@ export function supportsVisibility(
285
276
  ): boolean {
286
277
  const config = getKindMeta(kind).authorization?.visibility;
287
278
  switch (visibility) {
288
- case ApiResourceVisibility.api_resource_visibility_unspecified:
289
- case ApiResourceVisibility.visibility_private:
290
- return true;
279
+ case ApiResourceVisibility.visibility_public:
280
+ return config?.supportsPublic === true;
291
281
  case ApiResourceVisibility.visibility_org:
292
282
  return config?.supportsOrg === true;
293
283
  case ApiResourceVisibility.visibility_platform:
294
284
  return config?.supportsPlatform === true;
295
- case ApiResourceVisibility.visibility_public:
296
- return false;
297
- default: {
298
- const exhaustive: never = visibility;
299
- throw new Error(`unknown visibility level: ${String(exhaustive)}`);
300
- }
285
+ default:
286
+ return true;
301
287
  }
302
288
  }
303
289
 
@@ -312,6 +298,9 @@ export function supportedVisibilityLevels(kind: ApiResourceKind): string {
312
298
  if (config?.supportsOrg === true) {
313
299
  levels += ", visibility_org";
314
300
  }
301
+ if (config?.supportsPublic === true) {
302
+ levels += ", visibility_public";
303
+ }
315
304
  if (config?.supportsPlatform === true) {
316
305
  levels += ", visibility_platform";
317
306
  }
@@ -41,10 +41,15 @@ const caller: CallerIdentity = {
41
41
  const V = ApiResourceVisibility;
42
42
 
43
43
  describe("visibilityShapesFor (the reconciler's level→shape policy)", () => {
44
- it("agent (blueprint with org floor): org / platform expansions", () => {
44
+ it("agent (blueprint with org floor): org / public / platform expansions", () => {
45
45
  expect([
46
46
  ...visibilityShapesFor(ApiResourceKind.agent, V.visibility_org),
47
47
  ]).toEqual(["org-viewer"]);
48
+ expect(
49
+ [
50
+ ...visibilityShapesFor(ApiResourceKind.agent, V.visibility_public),
51
+ ].sort(),
52
+ ).toEqual(["org-viewer", "public-viewer"]);
48
53
  expect(
49
54
  [
50
55
  ...visibilityShapesFor(ApiResourceKind.agent, V.visibility_platform),
@@ -55,27 +60,25 @@ describe("visibilityShapesFor (the reconciler's level→shape policy)", () => {
55
60
  ]).toEqual([]);
56
61
  });
57
62
 
58
- it("the retired public level expands to nothing for every kind — no wildcard shape exists", () => {
59
- for (const kind of [
60
- ApiResourceKind.agent,
61
- ApiResourceKind.workflow_instance,
62
- ApiResourceKind.plugin,
63
- ApiResourceKind.session,
64
- ]) {
65
- expect([...visibilityShapesFor(kind, V.visibility_public)]).toEqual([]);
66
- }
63
+ it("workflow_instance (no org floor): public expands to the wildcard shape alone", () => {
64
+ expect([
65
+ ...visibilityShapesFor(
66
+ ApiResourceKind.workflow_instance,
67
+ V.visibility_public,
68
+ ),
69
+ ]).toEqual(["public-viewer"]);
67
70
  });
68
71
 
69
72
  it("session (no visibility config): every level yields nothing, silently", () => {
70
73
  expect([
71
- ...visibilityShapesFor(ApiResourceKind.session, V.visibility_org),
74
+ ...visibilityShapesFor(ApiResourceKind.session, V.visibility_public),
72
75
  ]).toEqual([]);
73
76
  expect([
74
- ...visibilityShapesFor(ApiResourceKind.session, V.visibility_platform),
77
+ ...visibilityShapesFor(ApiResourceKind.session, V.visibility_org),
75
78
  ]).toEqual([]);
76
79
  });
77
80
 
78
- it("agent_instance supports org but never platform (tenant isolation)", () => {
81
+ it("agent_instance supports org+public but never platform (tenant isolation)", () => {
79
82
  expect([
80
83
  ...visibilityShapesFor(
81
84
  ApiResourceKind.agent_instance,
@@ -98,15 +101,15 @@ describe("diffVisibilityShapes (the reconciler's transition matrix, re-pinned)",
98
101
  expect(diff.shapesToDelete).toEqual([]);
99
102
  });
100
103
 
101
- it("unspecified→platform creates the platform shape + the org floor", () => {
104
+ it("unspecified→public creates public + the org floor", () => {
102
105
  const diff = diffVisibilityShapes(
103
106
  agent,
104
107
  V.api_resource_visibility_unspecified,
105
- V.visibility_platform,
108
+ V.visibility_public,
106
109
  );
107
110
  expect([...diff.shapesToCreate].sort()).toEqual([
108
111
  "org-viewer",
109
- "platform-viewer",
112
+ "public-viewer",
110
113
  ]);
111
114
  expect(diff.shapesToDelete).toEqual([]);
112
115
  });
@@ -121,13 +124,23 @@ describe("diffVisibilityShapes (the reconciler's transition matrix, re-pinned)",
121
124
  expect(diff.shapesToDelete).toEqual(["org-viewer"]);
122
125
  });
123
126
 
124
- it("platform→org deletes ONLY the platform shape — the shared org floor stays untouched", () => {
127
+ it("public→org deletes ONLY the wildcard — the shared org shape stays untouched", () => {
125
128
  const diff = diffVisibilityShapes(
126
129
  agent,
127
- V.visibility_platform,
130
+ V.visibility_public,
128
131
  V.visibility_org,
129
132
  );
130
133
  expect(diff.shapesToCreate).toEqual([]);
134
+ expect(diff.shapesToDelete).toEqual(["public-viewer"]);
135
+ });
136
+
137
+ it("platform→public swaps the family shape and never touches the org floor", () => {
138
+ const diff = diffVisibilityShapes(
139
+ agent,
140
+ V.visibility_platform,
141
+ V.visibility_public,
142
+ );
143
+ expect(diff.shapesToCreate).toEqual(["public-viewer"]);
131
144
  expect(diff.shapesToDelete).toEqual(["platform-viewer"]);
132
145
  });
133
146
 
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Pins the PUBLIC-visibility operator gates (C2 Stage 3, the Java
3
+ * PublicVisibilityEscalationPolicy port): the create door fires only on a
4
+ * new state declaring PUBLIC, the update door only on an ESCALATION to
5
+ * public (re-asserting stored public passes), both answer the Java deny
6
+ * copy on denial and pass under the permissive default (OSS
7
+ * byte-identity), internal callers skip, and a missing loaded target is
8
+ * a loud wiring fault.
9
+ */
10
+ import { describe, expect, it } from "vitest";
11
+ import { Code, ConnectError } from "@connectrpc/connect";
12
+ import { create } from "@bufbuild/protobuf";
13
+
14
+ import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
15
+ import { AgentCommandController } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/command_pb";
16
+ import { UpdateVisibilityInputSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
17
+ import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
18
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
19
+ import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
20
+
21
+ import type { Authorizer, AuthzCheck } from "../../../extensions/authorizer.js";
22
+ import type { CallerIdentity } from "../../../extensions/identity.js";
23
+ import { RequestContext } from "../../request-context.js";
24
+ import { newPermissiveSingleTeamAuthorizer } from "../authorize.js";
25
+ import {
26
+ newAuthorizeVisibilityTransitionStep,
27
+ newGuardPublicVisibilityStep,
28
+ PUBLIC_VISIBILITY_DENY_MESSAGE,
29
+ } from "../visibility-gates.js";
30
+
31
+ const USER: CallerIdentity = {
32
+ identityId: "ida_alice",
33
+ callerClass: "user",
34
+ issuer: "stigmer",
35
+ rawToken: "tok",
36
+ };
37
+
38
+ const TARGET_KEY = "updateVisibilityAgent";
39
+
40
+ function denying(observed?: AuthzCheck[]): Authorizer {
41
+ return {
42
+ authorize: (_caller, check) => {
43
+ observed?.push(check);
44
+ return Promise.resolve({ kind: "deny", reason: "" });
45
+ },
46
+ };
47
+ }
48
+
49
+ function createCtx(
50
+ visibility: ApiResourceVisibility,
51
+ ): RequestContext<typeof AgentSchema> {
52
+ return new RequestContext(
53
+ AgentSchema,
54
+ create(AgentSchema, { metadata: { name: "a", visibility } }),
55
+ USER,
56
+ ApiResourceKind.agent,
57
+ );
58
+ }
59
+
60
+ type UvDesc = typeof AgentCommandController.method.updateVisibility.input;
61
+
62
+ function updateCtx(
63
+ requested: ApiResourceVisibility,
64
+ stored: ApiResourceVisibility | undefined,
65
+ ): RequestContext<UvDesc> {
66
+ const ctx = new RequestContext(
67
+ AgentCommandController.method.updateVisibility.input,
68
+ create(UpdateVisibilityInputSchema, {
69
+ resourceId: "agt_1",
70
+ visibility: requested,
71
+ }),
72
+ USER,
73
+ ApiResourceKind.agent,
74
+ );
75
+ if (stored !== undefined) {
76
+ ctx.set(
77
+ TARGET_KEY,
78
+ create(AgentSchema, { metadata: { visibility: stored } }),
79
+ );
80
+ }
81
+ return ctx;
82
+ }
83
+
84
+ describe("GuardPublicVisibility (the create door)", () => {
85
+ it("denies a PUBLIC create for non-operators with the Java copy", async () => {
86
+ const step = newGuardPublicVisibilityStep<typeof AgentSchema>(denying());
87
+ const error = await step
88
+ .execute(createCtx(ApiResourceVisibility.visibility_public))
89
+ ?.catch((e: unknown) => e);
90
+ expect((error as ConnectError).code).toBe(Code.PermissionDenied);
91
+ expect((error as ConnectError).rawMessage).toBe(
92
+ PUBLIC_VISIBILITY_DENY_MESSAGE,
93
+ );
94
+ });
95
+
96
+ it("non-public creates never reach the Authorizer (the lazy contract)", async () => {
97
+ const observed: AuthzCheck[] = [];
98
+ const step = newGuardPublicVisibilityStep<typeof AgentSchema>(
99
+ denying(observed),
100
+ );
101
+ await step.execute(createCtx(ApiResourceVisibility.visibility_org));
102
+ expect(observed).toEqual([]);
103
+ });
104
+
105
+ it("the permissive default allows public creates (OSS byte-identity)", async () => {
106
+ const step = newGuardPublicVisibilityStep<typeof AgentSchema>(
107
+ newPermissiveSingleTeamAuthorizer(),
108
+ );
109
+ await expect(
110
+ Promise.resolve(
111
+ step.execute(createCtx(ApiResourceVisibility.visibility_public)),
112
+ ),
113
+ ).resolves.toBeUndefined();
114
+ });
115
+ });
116
+
117
+ describe("AuthorizeVisibilityTransition (the update door)", () => {
118
+ it("denies escalation to public with the operator check", async () => {
119
+ const observed: AuthzCheck[] = [];
120
+ const step = newAuthorizeVisibilityTransitionStep<UvDesc>(
121
+ TARGET_KEY,
122
+ denying(observed),
123
+ );
124
+ const error = await step
125
+ .execute(
126
+ updateCtx(
127
+ ApiResourceVisibility.visibility_public,
128
+ ApiResourceVisibility.visibility_org,
129
+ ),
130
+ )
131
+ ?.catch((e: unknown) => e);
132
+ expect((error as ConnectError).code).toBe(Code.PermissionDenied);
133
+ expect((error as ConnectError).rawMessage).toBe(
134
+ PUBLIC_VISIBILITY_DENY_MESSAGE,
135
+ );
136
+ expect(observed).toEqual([
137
+ {
138
+ permission: IamPermission.can_set_public_visibility,
139
+ resourceKind: ApiResourceKind.platform,
140
+ resourceId: "stigmer",
141
+ },
142
+ ]);
143
+ });
144
+
145
+ it("re-asserting a stored PUBLIC is not an escalation", async () => {
146
+ const step = newAuthorizeVisibilityTransitionStep<UvDesc>(
147
+ TARGET_KEY,
148
+ denying(),
149
+ );
150
+ await expect(
151
+ Promise.resolve(
152
+ step.execute(
153
+ updateCtx(
154
+ ApiResourceVisibility.visibility_public,
155
+ ApiResourceVisibility.visibility_public,
156
+ ),
157
+ ),
158
+ ),
159
+ ).resolves.toBeUndefined();
160
+ });
161
+
162
+ it("non-public targets never reach the Authorizer", async () => {
163
+ const observed: AuthzCheck[] = [];
164
+ const step = newAuthorizeVisibilityTransitionStep<UvDesc>(
165
+ TARGET_KEY,
166
+ denying(observed),
167
+ );
168
+ await step.execute(
169
+ updateCtx(
170
+ ApiResourceVisibility.visibility_org,
171
+ ApiResourceVisibility.visibility_public,
172
+ ),
173
+ );
174
+ expect(observed).toEqual([]);
175
+ });
176
+
177
+ it("a missing loaded target is a loud wiring fault, never a silent pass", async () => {
178
+ const step = newAuthorizeVisibilityTransitionStep<UvDesc>(
179
+ TARGET_KEY,
180
+ denying(),
181
+ );
182
+ const error = await step
183
+ .execute(updateCtx(ApiResourceVisibility.visibility_public, undefined))
184
+ ?.catch((e: unknown) => e);
185
+ expect((error as ConnectError).code).toBe(Code.Internal);
186
+ });
187
+ });
@@ -94,15 +94,9 @@ import { metadataOf, parentIdOf } from "./shapes.js";
94
94
  * validation).
95
95
  *
96
96
  * The org floor: kinds flagged defaults_to_org_visibility (blueprints —
97
- * shared org assets) keep the org-viewer shape at the platform level, so
98
- * sharing a blueprint beyond the org never hides it from its own org's
99
- * catalog.
100
- *
101
- * The retired public level has no shape here. No stored row holds it once
102
- * the store migration has run, so no transition FROM it reaches this
103
- * policy; a deployment that still holds public rows must move them through
104
- * updateVisibility on the release that knew the level, whose reconciler
105
- * deletes the wildcard grant, before it runs this one.
97
+ * shared org assets) keep the org-viewer shape at public and platform
98
+ * levels, so sharing a blueprint beyond the org never hides it from its
99
+ * own org's catalog (ListObjects suppresses the public wildcard).
106
100
  */
107
101
  export function visibilityShapesFor(
108
102
  kind: ApiResourceKind,
@@ -118,6 +112,14 @@ export function visibilityShapesFor(
118
112
  shapes.add("org-viewer");
119
113
  }
120
114
  break;
115
+ case ApiResourceVisibility.visibility_public:
116
+ if (config?.supportsPublic === true) {
117
+ shapes.add("public-viewer");
118
+ if (orgFloor) {
119
+ shapes.add("org-viewer");
120
+ }
121
+ }
122
+ break;
121
123
  case ApiResourceVisibility.visibility_platform:
122
124
  if (config?.supportsPlatform === true) {
123
125
  shapes.add("platform-viewer");