@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
@@ -50,18 +50,22 @@ const FIXTURES = new URL("./fixtures/fga/", import.meta.url);
50
50
  */
51
51
  const DOCUMENTS = [
52
52
  "agent-channel-owner.fga.yaml",
53
+ "agent-instance-creation.fga.yaml",
53
54
  "agent-share-owner.fga.yaml",
54
55
  "artifact-org-and-owner.fga.yaml",
55
56
  "blueprint-private-visibility.fga.yaml",
56
57
  "channel-app-owner.fga.yaml",
57
58
  "channel-participation.fga.yaml",
58
59
  "channel-session-visibility.fga.yaml",
60
+ "cross-org-share-creation.fga.yaml",
59
61
  "default-instance-inheritance.fga.yaml",
62
+ "mcp-server-authoring.fga.yaml",
60
63
  "memory-subject-only.fga.yaml",
61
64
  "org-admin-owner-inheritance.fga.yaml",
62
65
  "org-shared-environment.fga.yaml",
63
66
  "platform-visibility.fga.yaml",
64
67
  "provider-standing-viewer.fga.yaml",
68
+ "public-visibility-setter.fga.yaml",
65
69
  "reserved-label-writer.fga.yaml",
66
70
  "schedule-owner.fga.yaml",
67
71
  "schedule-session-visibility.fga.yaml",
@@ -98,7 +102,7 @@ const SKIPPED_PINNED: ReadonlyArray<string> = [
98
102
  "artifact-org-and-owner :: listing reflects org inheritance plus creator ownership :: identity_account:eve <artifact> :: list-objects",
99
103
  "artifact-org-and-owner :: listing reflects org inheritance plus creator ownership :: identity_account:victor <artifact> :: list-objects",
100
104
  "blueprint-private-visibility :: org admin's listable agents include private ones (T08) :: identity_account:oscar <agent> :: list-objects",
101
- "blueprint-private-visibility :: org member's listable agents exclude private ones :: identity_account:dave <agent> :: list-objects",
105
+ "blueprint-private-visibility :: org member's listable agents exclude private ones (wildcard suppressed) :: identity_account:dave <agent> :: list-objects",
102
106
  "blueprint-private-visibility :: org viewer's listable agents are exactly the viewer-shaped org-visible ones :: identity_account:vera <agent> :: list-objects",
103
107
  "blueprint-private-visibility :: owner's listable agents include everything they authored :: identity_account:carol <agent> :: list-objects",
104
108
  "channel-app-owner :: listing channel apps reflects ownership and grants, not membership :: identity_account:alice <channel_app> :: list-objects",
@@ -128,6 +132,9 @@ const SKIPPED_PINNED: ReadonlyArray<string> = [
128
132
  // undeclared-kind: platform
129
133
  "provider-standing-viewer :: operator may view provider standing, tenants may not :: identity_account:mallory platform:stigmer :: undeclared-kind",
130
134
  "provider-standing-viewer :: operator may view provider standing, tenants may not :: identity_account:opal platform:stigmer :: undeclared-kind",
135
+ "public-visibility-setter :: operators may set public visibility, tenants may not :: identity_account:machine platform:stigmer :: undeclared-kind",
136
+ "public-visibility-setter :: operators may set public visibility, tenants may not :: identity_account:mallory platform:stigmer :: undeclared-kind",
137
+ "public-visibility-setter :: operators may set public visibility, tenants may not :: identity_account:opal platform:stigmer :: undeclared-kind",
131
138
  "reserved-label-writer :: operator may write reserved labels, tenants may not :: identity_account:machine platform:stigmer :: undeclared-kind",
132
139
  "reserved-label-writer :: operator may write reserved labels, tenants may not :: identity_account:mallory platform:stigmer :: undeclared-kind",
133
140
  // undeclared-subject-type: identity_provider#platform_user
@@ -13,7 +13,7 @@ import {
13
13
  } from "../tuples.js";
14
14
 
15
15
  describe("the string notation", () => {
16
- it("parses an object and a userset, and an id may carry a colon (issuer subjects do)", () => {
16
+ it("parses an object, a userset and the wildcard, and an id may carry a colon (issuer subjects do)", () => {
17
17
  expect(parseObjectRef("agent:agt_1")).toEqual({
18
18
  type: "agent",
19
19
  id: "agt_1",
@@ -27,6 +27,11 @@ describe("the string notation", () => {
27
27
  object: { type: "organization", id: "acme" },
28
28
  relation: "viewer",
29
29
  });
30
+ expect(parseSubject("identity_account:*")).toEqual({
31
+ form: "wildcard",
32
+ type: "identity_account",
33
+ condition: undefined,
34
+ });
30
35
  expect(parseSubject("identity_account:ida_x")).toEqual({
31
36
  form: "object",
32
37
  object: { type: "identity_account", id: "ida_x" },
@@ -38,24 +43,18 @@ describe("the string notation", () => {
38
43
  expect(() => parseObjectRef(":id")).toThrow("not an object reference");
39
44
  });
40
45
 
41
- it("refuses the wildcard notation — no line of the model admits one", () => {
42
- expect(() => parseSubject("identity_account:*")).toThrow(
43
- "wildcard subject 'identity_account:*' is not admitted",
44
- );
45
- });
46
-
47
- it("formats a tuple in the proto's notation", () => {
46
+ it("formats a tuple in the proto's notation, the condition spelled after `with`", () => {
48
47
  expect(
49
48
  formatTuple({
50
49
  object: parseObjectRef("agent:a"),
51
50
  relation: "viewer",
52
51
  subject: {
53
- form: "userset",
54
- object: { type: "organization", id: "acme" },
55
- relation: "viewer",
52
+ form: "wildcard",
53
+ type: "identity_account",
54
+ condition: "allow_public",
56
55
  },
57
56
  }),
58
- ).toBe("agent:a#viewer@organization:acme#viewer");
57
+ ).toBe("agent:a#viewer@identity_account:* with allow_public");
59
58
  expect(formatSubject(parseSubject("organization:acme#member"))).toBe(
60
59
  "organization:acme#member",
61
60
  );
@@ -17,7 +17,9 @@
17
17
  * 2. A kind this edition does not serve is `deny` (`kindServedByEdition`,
18
18
  * the predicate 2b's `checkMyPermission` arm 1 uses, so the console
19
19
  * and the server agree by construction). `platform` is the one that
20
- * can arrive, through an operator capability no self-host holds.
20
+ * arrives, through `can_set_public_visibility` — under the built-in
21
+ * posture nobody sets public visibility, the model's own reason for
22
+ * making it a platform operator's act.
21
23
  * 3. The caller as a person (person.ts) and one derived tuple source for
22
24
  * them; the target loaded ONCE through the source's memoised loader,
23
25
  * so the read that decides not-found is the read the derivation
@@ -29,9 +31,11 @@
29
31
  * member cannot learn which account ids exist. Present or exempt, the
30
32
  * row is then evaluated: the cloud asks OpenFGA whether or not the row
31
33
  * exists, and so does this driver.
32
- * 5. `checkRelation`. True is `allow`; false is `deny` with an EMPTY
33
- * reason, so the method annotation's byte-pinned `error_msg` wins on
34
- * the wire, exactly the cloud's genuine-denial path.
34
+ * 5. `checkRelation` with the point-check context (`allow: true`: a
35
+ * public resource reads for any authenticated caller, the cloud's
36
+ * posture). True is `allow`; false is `deny` with an EMPTY reason, so
37
+ * the method annotation's byte-pinned `error_msg` wins on the wire,
38
+ * exactly the cloud's genuine-denial path.
35
39
  *
36
40
  * Faults. Everything past the pre-checks runs under one guard: a store
37
41
  * fault, a person that names nobody (`personFor`), an evaluation fault
@@ -175,6 +179,7 @@ export function newBuiltInAuthorizer(deps: BuiltInAuthorizerDeps): Authorizer {
175
179
  object,
176
180
  relation,
177
181
  person,
182
+ { allow: true },
178
183
  );
179
184
  if (allowed) {
180
185
  return { kind: "allow" };
@@ -12,6 +12,7 @@
12
12
  * - owner SELF: <row>#owner@identity_account:<row id>
13
13
  * - creator: <row>#creator@identity_account:<creator stamp> (kinds flagged requires_creator_tuple)
14
14
  * - org-viewer: <row>#viewer@organization:<org>#viewer (visibility_org; cloud#257's shape)
15
+ * - public-viewer: <row>#viewer@identity_account:* with allow_public
15
16
  * - platform-viewer: none — it fans out over identity providers, a kind this edition does not serve
16
17
  *
17
18
  * Two facts are this edition's own and are stated here, nowhere else:
@@ -90,7 +91,11 @@ import type {
90
91
  Tuple,
91
92
  TupleSource,
92
93
  } from "./tuples.js";
93
- import { ACCOUNT_TYPE, formatObjectRef } from "./tuples.js";
94
+ import {
95
+ ACCOUNT_TYPE,
96
+ ALLOW_PUBLIC_CONDITION,
97
+ formatObjectRef,
98
+ } from "./tuples.js";
94
99
 
95
100
  /**
96
101
  * Kinds whose `[identity_account]` owner is recorded as an IamPolicy row
@@ -179,6 +184,12 @@ function visibilitySubject(
179
184
  object: { type: "organization", id: org },
180
185
  relation: "viewer",
181
186
  };
187
+ case "public-viewer":
188
+ return {
189
+ form: "wildcard",
190
+ type: ACCOUNT_TYPE,
191
+ condition: ALLOW_PUBLIC_CONDITION,
192
+ };
182
193
  case "platform-viewer":
183
194
  return undefined;
184
195
  default: {
@@ -350,18 +361,24 @@ function tupleOfRow(row: IamPolicy): Tuple {
350
361
  type: principal?.kind ?? "",
351
362
  id: principal?.id ?? "",
352
363
  };
353
- // A principal id of `*` (a wildcard row a cloud database may still hold
354
- // from the retired public level) is read as an ordinary object id here:
355
- // no person carries `*` among their aliases, so the row matches nobody
356
- // and reads as the inert grant it is, never as a fault that would turn
357
- // the resource unreadable.
358
- const subject: Subject =
359
- principal !== undefined && principal.relation !== ""
360
- ? {
361
- form: "userset",
362
- object: principalObject,
363
- relation: principal.relation,
364
- }
365
- : { form: "object", object: principalObject };
364
+ let subject: Subject;
365
+ if (principal !== undefined && principal.relation !== "") {
366
+ subject = {
367
+ form: "userset",
368
+ object: principalObject,
369
+ relation: principal.relation,
370
+ };
371
+ } else if (principalObject.id === "*") {
372
+ // A wildcard row carries no condition of its own; the evaluator
373
+ // honours it only where a line admits an unconditioned wildcard,
374
+ // which no line in the model does.
375
+ subject = {
376
+ form: "wildcard",
377
+ type: principalObject.type,
378
+ condition: undefined,
379
+ };
380
+ } else {
381
+ subject = { form: "object", object: principalObject };
382
+ }
366
383
  return { object, relation: spec?.relation ?? "", subject };
367
384
  }
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * The evaluator — OpenFGA's check, over the built-in model and a tuple
3
3
  * source, small because the model uses four rewrite forms and nothing
4
- * else (model/rewrite.ts). `checkRelation(object, relation, person)`
4
+ * else (model/rewrite.ts). `checkRelation(object, relation, person, context)`
5
5
  * answers "does this person hold this relation on this object" the way
6
6
  * the cloud's engine answers it over stored tuples, so the two editions
7
- * share one meaning of authorization. There is no context parameter: the
8
- * model declares no condition, so a check has no posture to state.
7
+ * share one meaning of authorization.
9
8
  *
10
9
  * The walk, in the order a `.fga` line reads:
11
10
  * - `this`: the tuples on (object, relation). A tuple counts only if
@@ -13,7 +12,9 @@
13
12
  * OpenFGA makes at write time, made here at read time, so a derived
14
13
  * tuple the model no longer admits denies instead of allowing. An
15
14
  * object subject matches when it names one of the person's aliases;
16
- * a userset subject is resolved on its own object.
15
+ * a userset subject is resolved on its own object; the wildcard is
16
+ * honoured only under its condition (`allow_public` reads the
17
+ * context's `allow`; an unknown condition is a fault).
17
18
  * - `computed`: the same object, another relation.
18
19
  * - `from`: every object the tupleset relation links to (again within
19
20
  * the tupleset line's type restriction), resolved for the relation.
@@ -43,8 +44,19 @@
43
44
  */
44
45
  import type { Model } from "./model/index.js";
45
46
  import type { Rewrite, SubjectType } from "./model/rewrite.js";
46
- import type { ObjectRef, Person, Subject, TupleSource } from "./tuples.js";
47
- import { ACCOUNT_TYPE, formatObjectRef, pairKey } from "./tuples.js";
47
+ import type {
48
+ CheckContext,
49
+ ObjectRef,
50
+ Person,
51
+ Subject,
52
+ TupleSource,
53
+ } from "./tuples.js";
54
+ import {
55
+ ACCOUNT_TYPE,
56
+ ALLOW_PUBLIC_CONDITION,
57
+ formatObjectRef,
58
+ pairKey,
59
+ } from "./tuples.js";
48
60
 
49
61
  /**
50
62
  * OpenFGA's default resolution-depth limit (its `resolveNodeLimit`), so
@@ -65,7 +77,8 @@ export type EvaluationFault =
65
77
  | "undeclared-target-kind"
66
78
  | "internal-caller-offered"
67
79
  | "resolution-depth-exceeded"
68
- | "resolution-cycle";
80
+ | "resolution-cycle"
81
+ | "unknown-condition";
69
82
 
70
83
  /** A fault in the model or its evaluation — never a denial; the driver maps it to `unavailable`. */
71
84
  export class AuthorizationEvaluationError extends Error {
@@ -88,6 +101,7 @@ export async function checkRelation(
88
101
  object: ObjectRef,
89
102
  relation: string,
90
103
  person: Person,
104
+ context: CheckContext,
91
105
  ): Promise<boolean> {
92
106
  if (deps.model.byType(object.type) === undefined) {
93
107
  throw new AuthorizationEvaluationError(
@@ -95,7 +109,7 @@ export async function checkRelation(
95
109
  `no declaration for kind '${object.type}' (target ${formatObjectRef(object)})`,
96
110
  );
97
111
  }
98
- return new Walk(deps, person).resolve(object, relation, 0);
112
+ return new Walk(deps, person, context).resolve(object, relation, 0);
99
113
  }
100
114
 
101
115
  /** One check's state: the memo and the in-progress set, over one source. */
@@ -106,6 +120,7 @@ class Walk {
106
120
  constructor(
107
121
  private readonly deps: EvaluationDeps,
108
122
  private readonly person: Person,
123
+ private readonly context: CheckContext,
109
124
  ) {}
110
125
 
111
126
  resolve(
@@ -219,6 +234,15 @@ class Walk {
219
234
  allowed.relation === subject.relation,
220
235
  ) && (await this.resolve(subject.object, subject.relation, depth + 1))
221
236
  );
237
+ case "wildcard": {
238
+ const allowed = restriction.some(
239
+ (entry) =>
240
+ entry.form === "wildcard" &&
241
+ entry.type === subject.type &&
242
+ entry.condition === subject.condition,
243
+ );
244
+ return allowed && this.conditionHolds(subject.condition);
245
+ }
222
246
  default: {
223
247
  const exhaustive: never = subject;
224
248
  throw new Error(`unknown subject form: ${JSON.stringify(exhaustive)}`);
@@ -226,6 +250,18 @@ class Walk {
226
250
  }
227
251
  }
228
252
 
253
+ private conditionHolds(condition: string | undefined): boolean {
254
+ switch (condition) {
255
+ case ALLOW_PUBLIC_CONDITION:
256
+ return this.context.allow;
257
+ default:
258
+ throw new AuthorizationEvaluationError(
259
+ "unknown-condition",
260
+ `the model declares no condition '${String(condition)}'`,
261
+ );
262
+ }
263
+ }
264
+
229
265
  /** The object types the tupleset line admits — `[organization]`, `[session]` — from its `this` nodes. */
230
266
  private objectTypesOf(
231
267
  object: ObjectRef,
@@ -11,10 +11,12 @@
11
11
  * row a second time. A self-host's lists show a person exactly what a
12
12
  * `get` would let them read.
13
13
  *
14
- * Both verbs ask the same question a point check asks, `can_view` on the
15
- * candidate: the model has no subject whose answer differs between a
16
- * listing and a get, so a list is exactly the set of rows a get would
17
- * read.
14
+ * Both verbs ask under the LISTING context, `allow: false` — the public
15
+ * wildcard suppressed, the cloud's own posture (its Java
16
+ * listAuthorizedResourceIds set it): a legacy PUBLIC row reads for any
17
+ * signed-in person on a point check and never expands into an outsider's
18
+ * listing; the organization's own people still reach it through the
19
+ * org-viewer shape public also emits.
18
20
  *
19
21
  * - `restrictListEntries`: one derived source for the caller, seeded
20
22
  * with every candidate's facts; one `checkRelation` per unique id —
@@ -82,11 +84,14 @@ import { builtInModel } from "./model/index.js";
82
84
  import type { KindDeclaration } from "./model/rewrite.js";
83
85
  import type { AccountsByCaller } from "./person.js";
84
86
  import { resolvePerson } from "./person.js";
85
- import type { ObjectRef, Person } from "./tuples.js";
87
+ import type { CheckContext, ObjectRef, Person } from "./tuples.js";
86
88
 
87
89
  /** The relation every list lane reads through (the cloud's LIST_RELATION). */
88
90
  const LIST_RELATION = "can_view";
89
91
 
92
+ /** The listing context: the public wildcard suppressed (the module header). */
93
+ const LISTING: CheckContext = { allow: false };
94
+
90
95
  export interface BuiltInListReadScopeDeps {
91
96
  readonly store: Store;
92
97
  /** The port the grant path writes through — the person's rows are read from the same instance. */
@@ -133,6 +138,7 @@ export function newBuiltInListReadScope(
133
138
  object,
134
139
  LIST_RELATION,
135
140
  person,
141
+ LISTING,
136
142
  );
137
143
  return allowed ? facts.id : undefined;
138
144
  }),
@@ -4,8 +4,9 @@
4
4
  * read by whoever the visibility axis lets in. The `organization#member`
5
5
  * and `organization#viewer` usersets on `viewer` are the org-visibility
6
6
  * tuple's two shapes (the cloud writes `#viewer` since cloud#257; `#member`
7
- * is the legacy shape it still honours), and `platform_viewer` is an
8
- * identity-provider userset no open-source tuple ever names.
7
+ * is the legacy shape it still honours), the conditional wildcard is the
8
+ * public level, and `platform_viewer` is an identity-provider userset no
9
+ * open-source tuple ever names.
9
10
  */
10
11
  import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
11
12
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
@@ -16,6 +17,7 @@ import {
16
17
  direct,
17
18
  from,
18
19
  objectOf,
20
+ publicWith,
19
21
  union,
20
22
  usersetOf,
21
23
  } from "./rewrite.js";
@@ -42,6 +44,7 @@ export const agentDeclaration = declareKind({
42
44
  union(
43
45
  direct(
44
46
  objectOf("identity_account"),
47
+ publicWith("identity_account", "allow_public"),
45
48
  usersetOf("organization", "member"),
46
49
  usersetOf("organization", "viewer"),
47
50
  ),
@@ -19,6 +19,7 @@ import {
19
19
  direct,
20
20
  from,
21
21
  objectOf,
22
+ publicWith,
22
23
  union,
23
24
  usersetOf,
24
25
  } from "./rewrite.js";
@@ -37,6 +38,7 @@ export const agentInstanceDeclaration = declareKind({
37
38
  union(
38
39
  direct(
39
40
  objectOf("identity_account"),
41
+ publicWith("identity_account", "allow_public"),
40
42
  usersetOf("organization", "member"),
41
43
  usersetOf("organization", "viewer"),
42
44
  ),
@@ -12,6 +12,7 @@ import {
12
12
  direct,
13
13
  from,
14
14
  objectOf,
15
+ publicWith,
15
16
  union,
16
17
  usersetOf,
17
18
  } from "./rewrite.js";
@@ -38,6 +39,7 @@ export const mcpServerDeclaration = declareKind({
38
39
  union(
39
40
  direct(
40
41
  objectOf("identity_account"),
42
+ publicWith("identity_account", "allow_public"),
41
43
  usersetOf("organization", "member"),
42
44
  usersetOf("organization", "viewer"),
43
45
  ),
@@ -2,7 +2,8 @@
2
2
  * Transcript of fga/model/agentic/plugin.fga — the unit of install, shaped
3
3
  * exactly like a skill: an organization-owned blueprint whose owner is the
4
4
  * installer (and, through the organization, its admins), whose viewers are
5
- * the org's members and viewers and the platform viewer. Its verbs are the blueprint set: `can_view`, `can_edit`
5
+ * the org's members and viewers, public readers when published, and the
6
+ * platform viewer. Its verbs are the blueprint set: `can_view`, `can_edit`
6
7
  * (visibility), `can_delete` (uninstall), `can_grant_access`,
7
8
  * `can_view_access`; `can_use` is carried as the model's word for
8
9
  * "install from" though no wire permission names it yet.
@@ -20,6 +21,7 @@ import {
20
21
  direct,
21
22
  from,
22
23
  objectOf,
24
+ publicWith,
23
25
  union,
24
26
  usersetOf,
25
27
  } from "./rewrite.js";
@@ -46,6 +48,7 @@ export const pluginDeclaration = declareKind({
46
48
  union(
47
49
  direct(
48
50
  objectOf("identity_account"),
51
+ publicWith("identity_account", "allow_public"),
49
52
  usersetOf("organization", "member"),
50
53
  usersetOf("organization", "viewer"),
51
54
  ),
@@ -6,17 +6,12 @@
6
6
  * define organization: [organization] → direct(objectOf("organization"))
7
7
  * define owner: [identity_account] or admin from organization
8
8
  * → union(direct(objectOf("identity_account")), from("admin", "organization"))
9
- * define viewer: [identity_account, organization#member, organization#viewer]
10
- * or owner or platform_viewer
11
- * → union(direct(objectOf(...), usersetOf(...), usersetOf(...)),
9
+ * define viewer: [identity_account, identity_account:* with allow_public,
10
+ * organization#member, organization#viewer] or owner or platform_viewer
11
+ * → union(direct(objectOf(...), publicWith(...), usersetOf(...), usersetOf(...)),
12
12
  * computed("owner"), computed("platform_viewer"))
13
13
  * define can_view: viewer → computed("viewer")
14
14
  *
15
- * A subject type is an object type or a userset; the model admits no
16
- * wildcard (`type:*`) and declares no condition, so neither has a form
17
- * here. The day a line needs one, the transcript cannot be written and
18
- * the gap is a design act.
19
- *
20
15
  * A declaration file (model/<kind>.ts) is a TRANSCRIPT of its `.fga`
21
16
  * file: the same relations, in the file's order, each line rewritten in
22
17
  * these builders so a reader with the model open sees the same text, and
@@ -58,6 +53,12 @@ export type SubjectType =
58
53
  readonly form: "userset";
59
54
  readonly type: string;
60
55
  readonly relation: string;
56
+ }
57
+ /** `[identity_account:* with allow_public]` — every object of the type, under the condition. */
58
+ | {
59
+ readonly form: "wildcard";
60
+ readonly type: string;
61
+ readonly condition: string;
61
62
  };
62
63
 
63
64
  export type Rewrite =
@@ -86,6 +87,10 @@ export function usersetOf(type: string, relation: string): SubjectType {
86
87
  return { form: "userset", type, relation };
87
88
  }
88
89
 
90
+ export function publicWith(type: string, condition: string): SubjectType {
91
+ return { form: "wildcard", type, condition };
92
+ }
93
+
89
94
  export function direct(...subjects: ReadonlyArray<SubjectType>): Rewrite {
90
95
  return { node: "this", subjects };
91
96
  }
@@ -14,6 +14,7 @@ import {
14
14
  direct,
15
15
  from,
16
16
  objectOf,
17
+ publicWith,
17
18
  union,
18
19
  usersetOf,
19
20
  } from "./rewrite.js";
@@ -40,6 +41,7 @@ export const skillDeclaration = declareKind({
40
41
  union(
41
42
  direct(
42
43
  objectOf("identity_account"),
44
+ publicWith("identity_account", "allow_public"),
43
45
  usersetOf("organization", "member"),
44
46
  usersetOf("organization", "viewer"),
45
47
  ),
@@ -14,6 +14,7 @@ import {
14
14
  direct,
15
15
  from,
16
16
  objectOf,
17
+ publicWith,
17
18
  union,
18
19
  usersetOf,
19
20
  } from "./rewrite.js";
@@ -40,6 +41,7 @@ export const workflowDeclaration = declareKind({
40
41
  union(
41
42
  direct(
42
43
  objectOf("identity_account"),
44
+ publicWith("identity_account", "allow_public"),
43
45
  usersetOf("organization", "member"),
44
46
  usersetOf("organization", "viewer"),
45
47
  ),
@@ -30,6 +30,7 @@ import {
30
30
  direct,
31
31
  from,
32
32
  objectOf,
33
+ publicWith,
33
34
  union,
34
35
  usersetOf,
35
36
  } from "./rewrite.js";
@@ -83,6 +84,7 @@ export const workflowInstanceDeclaration = declareKind({
83
84
  union(
84
85
  direct(
85
86
  objectOf("identity_account"),
87
+ publicWith("identity_account", "allow_public"),
86
88
  usersetOf("organization", "member"),
87
89
  usersetOf("organization", "viewer"),
88
90
  ),
@@ -32,7 +32,8 @@
32
32
  * annotation, which is why this driver meets that caller at all: a
33
33
  * skip lane hands the directory the identity the interceptor stamped,
34
34
  * and no Authorize arm ran before it. Every other caller gets the
35
- * evaluated list.
35
+ * evaluated list. The listing context (`allow: false`) is the cloud's,
36
+ * though no organization line admits a wildcard.
36
37
  * The controller loads each id it is handed and skips the ones whose row
37
38
  * is gone (grants can outlive rows); the source has already loaded the
38
39
  * row once for the evaluation — two primary-key reads per organization,
@@ -101,6 +102,7 @@ export function newBuiltInOrganizationDirectory(
101
102
  { type: ORGANIZATION, id },
102
103
  "can_view",
103
104
  person,
105
+ { allow: false },
104
106
  )
105
107
  ) {
106
108
  visible.push(id);