@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,5 +1,5 @@
1
1
  # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/org-admin-owner-inheritance.fga.yaml
2
- # as changed by stigmer-cloud#757 (the OpenFGA store test the cloud runs against its live model).
2
+ # as changed by stigmer-cloud#765 (the OpenFGA store test the cloud runs against its live model).
3
3
  # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
4
  # file against this evaluator at the re-pin, so a stale copy is caught there.
5
5
  # Store tests for org-admin owner inheritance (T08).
@@ -131,8 +131,6 @@ tests:
131
131
  check:
132
132
  - user: identity_account:ana
133
133
  object: agent:carols-bot
134
- context:
135
- allow: false
136
134
  assertions:
137
135
  can_view: true
138
136
  can_edit: true
@@ -169,8 +167,6 @@ tests:
169
167
  can_grant_access: true
170
168
  - user: identity_account:ana
171
169
  object: skill:carols-notes
172
- context:
173
- allow: false
174
170
  assertions:
175
171
  can_view: true
176
172
  can_edit: true
@@ -178,8 +174,6 @@ tests:
178
174
  can_grant_access: true
179
175
  - user: identity_account:ana
180
176
  object: workflow:carols-flow
181
- context:
182
- allow: false
183
177
  assertions:
184
178
  can_view: true
185
179
  can_edit: true
@@ -197,8 +191,6 @@ tests:
197
191
  check:
198
192
  - user: identity_account:root
199
193
  object: agent:carols-bot
200
- context:
201
- allow: false
202
194
  assertions:
203
195
  can_edit: true
204
196
  can_delete: true
@@ -218,8 +210,6 @@ tests:
218
210
  check:
219
211
  - user: identity_account:dave
220
212
  object: agent:carols-bot
221
- context:
222
- allow: false
223
213
  assertions:
224
214
  can_view: false
225
215
  can_edit: false
@@ -250,8 +240,6 @@ tests:
250
240
  check:
251
241
  - user: identity_account:zara
252
242
  object: agent:carols-bot
253
- context:
254
- allow: false
255
243
  assertions:
256
244
  can_view: false
257
245
  can_edit: false
@@ -266,8 +254,6 @@ tests:
266
254
  check:
267
255
  - user: identity_account:ana
268
256
  object: agent_instance:carols-instance
269
- context:
270
- allow: false
271
257
  assertions:
272
258
  can_view: false
273
259
  can_edit: false
@@ -297,8 +283,6 @@ tests:
297
283
  check:
298
284
  - user: identity_account:carol
299
285
  object: agent:carols-bot
300
- context:
301
- allow: false
302
286
  assertions:
303
287
  can_view: true
304
288
  can_edit: true
@@ -309,8 +293,6 @@ tests:
309
293
  list_objects:
310
294
  - user: identity_account:ana
311
295
  type: agent
312
- context:
313
- allow: false
314
296
  assertions:
315
297
  can_view:
316
298
  - agent:carols-bot
@@ -318,8 +300,6 @@ tests:
318
300
  - agent:carols-bot
319
301
  - user: identity_account:ana
320
302
  type: agent_instance
321
- context:
322
- allow: false
323
303
  assertions:
324
304
  can_view: []
325
305
  - user: identity_account:ana
@@ -1,5 +1,5 @@
1
1
  # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/platform-visibility.fga.yaml
2
- # at commit b87dd1170 (the OpenFGA store test the cloud runs against its live model).
2
+ # as changed by stigmer-cloud#765 (the OpenFGA store test the cloud runs against its live model).
3
3
  # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
4
  # file against this evaluator at the re-pin, so a stale copy is caught there.
5
5
  # Store tests for platform visibility (visibility_platform).
@@ -102,8 +102,6 @@ tests:
102
102
  check:
103
103
  - user: identity_account:alice
104
104
  object: agent:sara
105
- context:
106
- allow: false
107
105
  assertions:
108
106
  can_view: true
109
107
  can_execute: true
@@ -112,8 +110,6 @@ tests:
112
110
  can_delete: false
113
111
  - user: identity_account:bob
114
112
  object: agent:sara
115
- context:
116
- allow: false
117
113
  assertions:
118
114
  can_view: true
119
115
  can_execute: true
@@ -122,8 +118,6 @@ tests:
122
118
  check:
123
119
  - user: identity_account:mallory
124
120
  object: agent:sara
125
- context:
126
- allow: false
127
121
  assertions:
128
122
  can_view: false
129
123
  can_execute: false
@@ -133,8 +127,6 @@ tests:
133
127
  check:
134
128
  - user: identity_account:priya
135
129
  object: agent:sara
136
- context:
137
- allow: false
138
130
  assertions:
139
131
  can_view: true
140
132
  can_execute: true
@@ -144,8 +136,6 @@ tests:
144
136
  # narrower: platform_user resolves member-from-managed_org.)
145
137
  - user: identity_account:veda
146
138
  object: agent:sara
147
- context:
148
- allow: false
149
139
  assertions:
150
140
  can_view: true
151
141
  can_edit: false
@@ -154,8 +144,6 @@ tests:
154
144
  check:
155
145
  - user: identity_account:alice
156
146
  object: agent:internal-bot
157
- context:
158
- allow: false
159
147
  assertions:
160
148
  can_view: false
161
149
  can_execute: false
@@ -163,8 +151,6 @@ tests:
163
151
  # without an explicit visibility tuple.
164
152
  - user: identity_account:priya
165
153
  object: agent:internal-bot
166
- context:
167
- allow: false
168
154
  assertions:
169
155
  can_view: false
170
156
  can_execute: false
@@ -173,8 +159,6 @@ tests:
173
159
  check:
174
160
  - user: identity_account:alice
175
161
  object: skill:research
176
- context:
177
- allow: false
178
162
  assertions:
179
163
  can_view: true
180
164
  can_use: true
@@ -184,8 +168,6 @@ tests:
184
168
  check:
185
169
  - user: identity_account:alice
186
170
  object: workflow:onboarding
187
- context:
188
- allow: false
189
171
  assertions:
190
172
  can_view: true
191
173
  can_execute: true
@@ -194,8 +176,6 @@ tests:
194
176
  check:
195
177
  - user: identity_account:alice
196
178
  object: mcp_server:github
197
- context:
198
- allow: false
199
179
  assertions:
200
180
  can_view: true
201
181
  can_use: true
@@ -205,8 +185,6 @@ tests:
205
185
  check:
206
186
  - user: identity_account:swarup
207
187
  object: agent:sara
208
- context:
209
- allow: false
210
188
  assertions:
211
189
  can_view: true
212
190
  can_edit: true
@@ -216,8 +194,6 @@ tests:
216
194
  list_objects:
217
195
  - user: identity_account:alice
218
196
  type: agent
219
- context:
220
- allow: false
221
197
  assertions:
222
198
  can_view:
223
199
  - agent:sara
@@ -1,5 +1,5 @@
1
1
  # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/workflow-execution-sharing.fga.yaml
2
- # at commit b87dd1170 (the OpenFGA store test the cloud runs against its live model).
2
+ # as changed by stigmer-cloud#765 (the OpenFGA store test the cloud runs against its live model).
3
3
  # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
4
  # file against this evaluator at the re-pin, so a stale copy is caught there.
5
5
  # Store tests for workflow_execution sharing and run observability.
@@ -173,8 +173,6 @@ tests:
173
173
  # never alice's run history.
174
174
  - user: identity_account:vera
175
175
  object: workflow_instance:inst1
176
- context:
177
- allow: false
178
176
  assertions:
179
177
  can_view: true
180
178
  - user: identity_account:vera
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * Pins the built-in list read scope on both store drivers as the twin of
3
3
  * the cloud's driver (stigmer-cloud iam/list-read-scope.ts): every
4
- * candidate a list lane offers is answered by `can_view` under the
5
- * LISTING context (`allow: false`, the public wildcard suppressed) through
6
- * the same evaluator the Authorizer uses, over tuples derived from the
7
- * facts the candidate carries — no candidate row is read twice.
4
+ * candidate a list lane offers is answered by `can_view` through the same
5
+ * evaluator the Authorizer uses, over tuples derived from the facts the
6
+ * candidate carries — no candidate row is read twice.
8
7
  *
9
8
  * The adversarial cells come first, because until slice 5's sibling
10
9
  * cells this file and the composed proof are the only proof that a
11
- * member's list is a member's list: the outsider sees nothing (a legacy
12
- * PUBLIC row included); the viewer rung sees the org-visible blueprints
10
+ * member's list is a member's list: the outsider sees nothing (a row
11
+ * still carrying the retired public level included); the viewer rung sees
12
+ * the org-visible blueprints
13
13
  * and nothing personal; the founder — an admin — sees the organization's
14
14
  * blueprints and NOT its members' sessions, keys, environments or
15
15
  * memories (the model's own line, now list-visible); an execution is its session's and
@@ -17,7 +17,9 @@
17
17
  * org-observable reaches the organization's viewers; a memory with no
18
18
  * subject is nobody's; an instance reaches whoever reads its blueprint
19
19
  * only when it is the default. Then the contract: a scope only narrows
20
- * and never reorders; the `internal` class is the in-process skip; an
20
+ * and never reorders; the `internal` class is the in-process skip on the
21
+ * enumeration verb and a loud consumer bug on the restrict verb (the
22
+ * shared helper answers the class before any driver, stigmer#1207); an
21
23
  * unprovisioned subject is their raw subject (the 3.14 verifiers' stamp); a
22
24
  * fault throws and is never an empty answer; an undeclared kind is a
23
25
  * consumer bug, loud; the enumeration verb equals the restrict verb over
@@ -278,9 +280,10 @@ describe.each(driverFixtures(SEEDED_KINDS))(
278
280
  await grant(orgRole(VIEWER, "viewer", ORG));
279
281
 
280
282
  // Blueprints: the founder's private and org-visible agents, a
281
- // member's private one, a legacy PUBLIC one (nobody can set public
282
- // under the built-in posture; a row from before it can carry it),
283
- // and one stamped by the 3.14 verifiers' raw subject.
283
+ // member's private one, one still carrying the retired public
284
+ // level (a row the store migration has not met, which derives no
285
+ // viewer grant and so reads as its owner's alone), and one
286
+ // stamped by the 3.14 verifiers' raw subject.
284
287
  await save("agent", {
285
288
  id: "agt_private",
286
289
  org: ORG,
@@ -425,7 +428,7 @@ describe.each(driverFixtures(SEEDED_KINDS))(
425
428
  });
426
429
 
427
430
  describe("the adversarial cells", () => {
428
- it("an OUTSIDER lists nothing of the organization's — not even the legacy PUBLIC blueprint, which the listing context suppresses", async () => {
431
+ it("an OUTSIDER lists nothing of the organization's — a row still carrying the retired public level included", async () => {
429
432
  for (const kind of SEEDED_KINDS.filter(
430
433
  (k) =>
431
434
  k !== ApiResourceKind.iam_policy &&
@@ -439,13 +442,13 @@ describe.each(driverFixtures(SEEDED_KINDS))(
439
442
  }
440
443
  });
441
444
 
442
- it("a VIEWER lists the org-visible and the public blueprints and nothing private; a MEMBER adds their own private one", async () => {
445
+ it("a VIEWER lists the org-visible blueprint and nothing private; a MEMBER adds their own private one; the retired level grants neither anything", async () => {
443
446
  expect(
444
447
  await listAs(resolved(VIEWER), ApiResourceKind.agent),
445
- ).toEqual(["agt_org", "agt_public"]);
448
+ ).toEqual(["agt_org"]);
446
449
  expect(
447
450
  await listAs(resolved(MEMBER), ApiResourceKind.agent),
448
- ).toEqual(["agt_org", "agt_member_private", "agt_public"]);
451
+ ).toEqual(["agt_org", "agt_member_private"]);
449
452
  });
450
453
 
451
454
  it("the FOUNDER and the ADMIN list every blueprint (`owner: … or admin from organization`), including a member's private one", async () => {
@@ -540,7 +543,7 @@ describe.each(driverFixtures(SEEDED_KINDS))(
540
543
  const offered = [
541
544
  entryOf(
542
545
  ApiResourceKind.agent,
543
- rows.get(ApiResourceKind.agent)!.get("agt_public")!,
546
+ rows.get(ApiResourceKind.agent)!.get("agt_member_private")!,
544
547
  ),
545
548
  entryOf(
546
549
  ApiResourceKind.agent,
@@ -560,15 +563,15 @@ describe.each(driverFixtures(SEEDED_KINDS))(
560
563
  ApiResourceKind.agent,
561
564
  offered,
562
565
  );
563
- expect([...kept]).toEqual(["agt_public", "agt_org"]);
566
+ expect([...kept]).toEqual(["agt_member_private", "agt_org"]);
564
567
  // The lane's order is the lane's: the helper filters its own
565
568
  // array by the kept set.
566
569
  expect(
567
570
  await listAs(resolved(MEMBER), ApiResourceKind.agent, [
568
- rows.get(ApiResourceKind.agent)!.get("agt_public")!,
571
+ rows.get(ApiResourceKind.agent)!.get("agt_member_private")!,
569
572
  rows.get(ApiResourceKind.agent)!.get("agt_org")!,
570
573
  ]),
571
- ).toEqual(["agt_public", "agt_org"]);
574
+ ).toEqual(["agt_member_private", "agt_org"]);
572
575
  });
573
576
 
574
577
  it("no candidates: the empty set, with no read of any kind", async () => {
@@ -583,17 +586,7 @@ describe.each(driverFixtures(SEEDED_KINDS))(
583
586
  expect(accountReads).toBe(0);
584
587
  });
585
588
 
586
- it("the `internal` class — the server acting as itself — keeps every offered id and enumerates every id of the kind: the in-process authorization skip, with no account even asked for", async () => {
587
- const offered = rowsOf(ApiResourceKind.agent).map((row) =>
588
- entryOf(ApiResourceKind.agent, row),
589
- );
590
- expect([
591
- ...(await scope().restrictListEntries(
592
- INTERNAL,
593
- ApiResourceKind.agent,
594
- offered,
595
- )),
596
- ]).toEqual(offered.map((entry) => entry.id));
589
+ it("the `internal` class on the enumeration verb — the server acting as itself — is every id of the kind, with no account even asked for (the in-process skip; no helper stands before this verb)", async () => {
597
590
  expect(
598
591
  [
599
592
  ...(await scope().authorizedResourceIds(
@@ -605,6 +598,25 @@ describe.each(driverFixtures(SEEDED_KINDS))(
605
598
  expect(accountReads).toBe(0);
606
599
  });
607
600
 
601
+ it("the `internal` class on the restrict verb is a consumer bug, loud: the shared helper answers that class before any driver, so a driver offered it was reached around the idiom", async () => {
602
+ const offered = rowsOf(ApiResourceKind.agent).map((row) =>
603
+ entryOf(ApiResourceKind.agent, row),
604
+ );
605
+ const refusal = await scope()
606
+ .restrictListEntries(INTERNAL, ApiResourceKind.agent, offered)
607
+ .then(
608
+ () => undefined,
609
+ (error: unknown) => error,
610
+ );
611
+ expect(refusal).toBeInstanceOf(AuthorizationEvaluationError);
612
+ expect((refusal as AuthorizationEvaluationError).reason).toBe(
613
+ "internal-caller-offered",
614
+ );
615
+ // Refused before any read: the server was never evaluated as a person.
616
+ expect(accountReads).toBe(0);
617
+ expect(storeReads).toEqual({ rows: 0, scans: 0 });
618
+ });
619
+
608
620
  it("an unprovisioned subject is their raw subject and nothing else: the 3.14-stamped row is theirs, the organization's rows are not", async () => {
609
621
  // `agt_legacy` is stamped with LEGACY's raw subject; a caller
610
622
  // who IS that subject and holds no account reaches it through
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Pins the coverage inventory's own rule for `is_skip_authorization` lanes
3
+ * (docs/authorization-coverage.md, "How to read the tables"): a skip lane
4
+ * reaches no Authorizer in either edition, so what guards it is whatever
5
+ * its Handler cell names — and a cell that names nothing is a lane open to
6
+ * every authenticated caller that nobody has said so about. Two things are
7
+ * held here, so the doc cannot drift from the server it describes:
8
+ *
9
+ * 1. The set of skip-annotated methods the open-source server SERVES
10
+ * (the empty composition's routes replayed into a recorder, a method
11
+ * counted only when its service's implementation map carries it — a
12
+ * partially implemented service lists more on its descriptor than it
13
+ * serves) equals the set of skip rows in the doc, service by method.
14
+ * A new skip lane without a row, or a row for a lane that is no
15
+ * longer a skip, fails here.
16
+ * 2. Every skip row's Handler cell carries one of the three markers the
17
+ * doc defines — `guard: <Name>`, `driver: <Seam>`,
18
+ * `by design: <reason>` — and every `guard:` names a pipeline step or
19
+ * a handler's guard function that exists by that name in `src/`
20
+ * outside the tests, so a renamed or removed guard cannot leave the
21
+ * doc pointing at nothing.
22
+ *
23
+ * The rule lives in the doc; this test only enforces it. The doc is the
24
+ * one inventory (the package guide mandates updating it with every
25
+ * annotation change), and a second list here would be the drift this
26
+ * test exists to prevent.
27
+ */
28
+ import {
29
+ mkdtempSync,
30
+ readFileSync,
31
+ readdirSync,
32
+ rmSync,
33
+ statSync,
34
+ } from "node:fs";
35
+ import { tmpdir } from "node:os";
36
+ import path from "node:path";
37
+ import { fileURLToPath } from "node:url";
38
+
39
+ import { getOption } from "@bufbuild/protobuf";
40
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
41
+
42
+ import { is_skip_authorization } from "@stigmer/protos/ai/stigmer/commons/rpc/method_options_pb";
43
+
44
+ import { loadConfig } from "../../boot/config.js";
45
+ import { composeServer } from "../../boot/compose.js";
46
+ import type { ComposedServer } from "../../boot/compose.js";
47
+ import {
48
+ baseConfig,
49
+ servedMethods,
50
+ silentLogger,
51
+ } from "../../extensions/__tests__/composed-support.js";
52
+
53
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
54
+ const PACKAGE_ROOT = path.resolve(HERE, "../../..");
55
+ const COVERAGE_DOC = path.join(PACKAGE_ROOT, "docs/authorization-coverage.md");
56
+ const SRC = path.join(PACKAGE_ROOT, "src");
57
+
58
+ /** A skip row: `| Service.method | is_skip_authorization | <handler cell> |`. */
59
+ const SKIP_ROW =
60
+ /^\| ([A-Za-z]+)\.([A-Za-z]+) \| is_skip_authorization \| (.*) \|$/;
61
+
62
+ const MARKERS = ["guard:", "driver:", "by design:"] as const;
63
+
64
+ interface SkipRow {
65
+ readonly method: string;
66
+ readonly handler: string;
67
+ }
68
+
69
+ function skipRowsOf(doc: string): SkipRow[] {
70
+ const rows: SkipRow[] = [];
71
+ for (const line of doc.split("\n")) {
72
+ const m = SKIP_ROW.exec(line);
73
+ if (m !== null) {
74
+ rows.push({ method: `${m[1]}.${m[2]}`, handler: m[3] ?? "" });
75
+ }
76
+ }
77
+ return rows;
78
+ }
79
+
80
+ /** Every `guard: <Name>` a handler cell names. */
81
+ function guardsOf(handler: string): string[] {
82
+ return [...handler.matchAll(/guard: ([A-Za-z]+)/g)].map((m) => m[1] ?? "");
83
+ }
84
+
85
+ /** Every non-test `.ts` source under `src/`, read once. */
86
+ function sourceText(): string {
87
+ const parts: string[] = [];
88
+ const walk = (dir: string): void => {
89
+ for (const entry of readdirSync(dir)) {
90
+ const full = path.join(dir, entry);
91
+ if (statSync(full).isDirectory()) {
92
+ if (entry !== "__tests__") {
93
+ walk(full);
94
+ }
95
+ } else if (full.endsWith(".ts") && !full.endsWith(".test.ts")) {
96
+ parts.push(readFileSync(full, "utf8"));
97
+ }
98
+ }
99
+ };
100
+ walk(SRC);
101
+ return parts.join("\n");
102
+ }
103
+
104
+ describe("the skip-lane inventory (docs/authorization-coverage.md) is true to the served server", () => {
105
+ let dir: string;
106
+ let server: ComposedServer;
107
+
108
+ beforeAll(async () => {
109
+ dir = mkdtempSync(path.join(tmpdir(), "skip-lane-inventory-test-"));
110
+ server = await composeServer({
111
+ config: loadConfig(baseConfig(dir)),
112
+ logger: silentLogger,
113
+ portOverride: 0,
114
+ host: "127.0.0.1",
115
+ });
116
+ });
117
+
118
+ afterAll(async () => {
119
+ await server.shutdown();
120
+ rmSync(dir, { recursive: true, force: true });
121
+ });
122
+
123
+ it("the doc's skip rows are exactly the skip-annotated methods the server serves", () => {
124
+ const served = new Set<string>();
125
+ for (const method of servedMethods(server.routes)) {
126
+ if (getOption(method, is_skip_authorization)) {
127
+ const serviceName = method.parent.typeName.split(".").at(-1) ?? "";
128
+ served.add(`${serviceName}.${method.name}`);
129
+ }
130
+ }
131
+ const documented = new Set(
132
+ skipRowsOf(readFileSync(COVERAGE_DOC, "utf8")).map((r) => r.method),
133
+ );
134
+ expect([...served].sort()).toEqual([...documented].sort());
135
+ });
136
+
137
+ it("every skip row names its guard, its driver or says the lane is open by design", () => {
138
+ const bare = skipRowsOf(readFileSync(COVERAGE_DOC, "utf8"))
139
+ .filter((r) => !MARKERS.some((marker) => r.handler.includes(marker)))
140
+ .map((r) => r.method);
141
+ expect(bare).toEqual([]);
142
+ });
143
+
144
+ it("every guard a skip row names is a step or a guard function that exists by that name in src/", () => {
145
+ const source = sourceText();
146
+ const dangling: string[] = [];
147
+ for (const row of skipRowsOf(readFileSync(COVERAGE_DOC, "utf8"))) {
148
+ for (const guard of guardsOf(row.handler)) {
149
+ // A step is registered by its quoted name; a guard function by its
150
+ // declaration.
151
+ const isStep = source.includes(`"${guard}"`);
152
+ const isFunction = new RegExp(`function ${guard}\\(`).test(source);
153
+ if (!isStep && !isFunction) {
154
+ dangling.push(`${row.method} names guard ${guard}`);
155
+ }
156
+ }
157
+ }
158
+ expect(dangling).toEqual([]);
159
+ });
160
+ });
@@ -56,14 +56,12 @@ const DOCUMENTS = [
56
56
  "channel-app-owner.fga.yaml",
57
57
  "channel-participation.fga.yaml",
58
58
  "channel-session-visibility.fga.yaml",
59
- "cross-org-share-creation.fga.yaml",
60
59
  "default-instance-inheritance.fga.yaml",
61
60
  "memory-subject-only.fga.yaml",
62
61
  "org-admin-owner-inheritance.fga.yaml",
63
62
  "org-shared-environment.fga.yaml",
64
63
  "platform-visibility.fga.yaml",
65
64
  "provider-standing-viewer.fga.yaml",
66
- "public-visibility-setter.fga.yaml",
67
65
  "reserved-label-writer.fga.yaml",
68
66
  "schedule-owner.fga.yaml",
69
67
  "schedule-session-visibility.fga.yaml",
@@ -100,7 +98,7 @@ const SKIPPED_PINNED: ReadonlyArray<string> = [
100
98
  "artifact-org-and-owner :: listing reflects org inheritance plus creator ownership :: identity_account:eve <artifact> :: list-objects",
101
99
  "artifact-org-and-owner :: listing reflects org inheritance plus creator ownership :: identity_account:victor <artifact> :: list-objects",
102
100
  "blueprint-private-visibility :: org admin's listable agents include private ones (T08) :: identity_account:oscar <agent> :: list-objects",
103
- "blueprint-private-visibility :: org member's listable agents exclude private ones (wildcard suppressed) :: identity_account:dave <agent> :: list-objects",
101
+ "blueprint-private-visibility :: org member's listable agents exclude private ones :: identity_account:dave <agent> :: list-objects",
104
102
  "blueprint-private-visibility :: org viewer's listable agents are exactly the viewer-shaped org-visible ones :: identity_account:vera <agent> :: list-objects",
105
103
  "blueprint-private-visibility :: owner's listable agents include everything they authored :: identity_account:carol <agent> :: list-objects",
106
104
  "channel-app-owner :: listing channel apps reflects ownership and grants, not membership :: identity_account:alice <channel_app> :: list-objects",
@@ -130,9 +128,6 @@ const SKIPPED_PINNED: ReadonlyArray<string> = [
130
128
  // undeclared-kind: platform
131
129
  "provider-standing-viewer :: operator may view provider standing, tenants may not :: identity_account:mallory platform:stigmer :: undeclared-kind",
132
130
  "provider-standing-viewer :: operator may view provider standing, tenants may not :: identity_account:opal platform:stigmer :: undeclared-kind",
133
- "public-visibility-setter :: operators may set public visibility, tenants may not :: identity_account:machine platform:stigmer :: undeclared-kind",
134
- "public-visibility-setter :: operators may set public visibility, tenants may not :: identity_account:mallory platform:stigmer :: undeclared-kind",
135
- "public-visibility-setter :: operators may set public visibility, tenants may not :: identity_account:opal platform:stigmer :: undeclared-kind",
136
131
  "reserved-label-writer :: operator may write reserved labels, tenants may not :: identity_account:machine platform:stigmer :: undeclared-kind",
137
132
  "reserved-label-writer :: operator may write reserved labels, tenants may not :: identity_account:mallory platform:stigmer :: undeclared-kind",
138
133
  // 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, a userset and the wildcard, and an id may carry a colon (issuer subjects do)", () => {
16
+ it("parses an object and a userset, 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,11 +27,6 @@ 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
- });
35
30
  expect(parseSubject("identity_account:ida_x")).toEqual({
36
31
  form: "object",
37
32
  object: { type: "identity_account", id: "ida_x" },
@@ -43,18 +38,24 @@ describe("the string notation", () => {
43
38
  expect(() => parseObjectRef(":id")).toThrow("not an object reference");
44
39
  });
45
40
 
46
- it("formats a tuple in the proto's notation, the condition spelled after `with`", () => {
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", () => {
47
48
  expect(
48
49
  formatTuple({
49
50
  object: parseObjectRef("agent:a"),
50
51
  relation: "viewer",
51
52
  subject: {
52
- form: "wildcard",
53
- type: "identity_account",
54
- condition: "allow_public",
53
+ form: "userset",
54
+ object: { type: "organization", id: "acme" },
55
+ relation: "viewer",
55
56
  },
56
57
  }),
57
- ).toBe("agent:a#viewer@identity_account:* with allow_public");
58
+ ).toBe("agent:a#viewer@organization:acme#viewer");
58
59
  expect(formatSubject(parseSubject("organization:acme#member"))).toBe(
59
60
  "organization:acme#member",
60
61
  );
@@ -117,12 +117,11 @@ describe("every static (kind, permission) the served RPCs ask about is a declare
117
117
  expect(undeclared).toEqual([]);
118
118
  });
119
119
 
120
- it("asks about every served kind the model declares except the two no RPC targets statically", () => {
120
+ it("asks about every served kind the model declares except the one no RPC targets statically", () => {
121
121
  // iam_policy's RPCs target the policy's RESOURCE (`resource_kind_path`
122
- // or the load-then-authorize `get`); execution_context's RPCs are
123
- // `is_skip_authorization` lanes (or unannotated) whose handlers gate on
124
- // the runner's execution-scoped token. Every other declared kind is
125
- // asked about by at least one static annotation.
122
+ // or the load-then-authorize `get`). Every other declared kind is asked
123
+ // about by at least one static annotation — execution_context through
124
+ // its `get` and `delete`; its runner-token lane stays a skip.
126
125
  const asked = new Set(wireQuestions().map((q) => kindEnumName(q.kind)));
127
126
  expect([...asked].sort()).toEqual(
128
127
  [
@@ -135,6 +134,7 @@ describe("every static (kind, permission) the served RPCs ask about is a declare
135
134
  "artifact",
136
135
  "channel_app",
137
136
  "environment",
137
+ "execution_context",
138
138
  "identity_account",
139
139
  "mcp_server",
140
140
  "memory",
@@ -17,9 +17,7 @@
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
- * 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.
20
+ * can arrive, through an operator capability no self-host holds.
23
21
  * 3. The caller as a person (person.ts) and one derived tuple source for
24
22
  * them; the target loaded ONCE through the source's memoised loader,
25
23
  * so the read that decides not-found is the read the derivation
@@ -31,11 +29,9 @@
31
29
  * member cannot learn which account ids exist. Present or exempt, the
32
30
  * row is then evaluated: the cloud asks OpenFGA whether or not the row
33
31
  * exists, and so does this driver.
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.
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.
39
35
  *
40
36
  * Faults. Everything past the pre-checks runs under one guard: a store
41
37
  * fault, a person that names nobody (`personFor`), an evaluation fault
@@ -179,7 +175,6 @@ export function newBuiltInAuthorizer(deps: BuiltInAuthorizerDeps): Authorizer {
179
175
  object,
180
176
  relation,
181
177
  person,
182
- { allow: true },
183
178
  );
184
179
  if (allowed) {
185
180
  return { kind: "allow" };