@stigmer/server 3.15.3-dev.20260914100347 → 3.15.3-dev.20260916211208

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 (570) hide show
  1. package/README.md +3 -3
  2. package/dist/archive/content-store.d.ts +35 -0
  3. package/dist/archive/content-store.d.ts.map +1 -0
  4. package/dist/archive/content-store.js +98 -0
  5. package/dist/archive/content-store.js.map +1 -0
  6. package/dist/archive/inflate.d.ts +22 -0
  7. package/dist/archive/inflate.d.ts.map +1 -0
  8. package/dist/archive/inflate.js +75 -0
  9. package/dist/archive/inflate.js.map +1 -0
  10. package/dist/archive/limits.d.ts +33 -0
  11. package/dist/archive/limits.d.ts.map +1 -0
  12. package/dist/archive/limits.js +31 -0
  13. package/dist/archive/limits.js.map +1 -0
  14. package/dist/archive/open.d.ts +24 -0
  15. package/dist/archive/open.d.ts.map +1 -0
  16. package/dist/archive/open.js +93 -0
  17. package/dist/archive/open.js.map +1 -0
  18. package/dist/{domain/skill/storage → archive}/prefilter.d.ts +5 -0
  19. package/dist/archive/prefilter.d.ts.map +1 -0
  20. package/dist/archive/prefilter.js.map +1 -0
  21. package/dist/archive/write.d.ts +8 -0
  22. package/dist/archive/write.d.ts.map +1 -0
  23. package/dist/archive/write.js +44 -0
  24. package/dist/archive/write.js.map +1 -0
  25. package/dist/authorization/authorizer.d.ts +98 -0
  26. package/dist/authorization/authorizer.d.ts.map +1 -0
  27. package/dist/authorization/authorizer.js +156 -0
  28. package/dist/authorization/authorizer.js.map +1 -0
  29. package/dist/authorization/derived-tuples.d.ts +42 -0
  30. package/dist/authorization/derived-tuples.d.ts.map +1 -0
  31. package/dist/authorization/derived-tuples.js +240 -0
  32. package/dist/authorization/derived-tuples.js.map +1 -0
  33. package/dist/authorization/evaluator.d.ts +66 -0
  34. package/dist/authorization/evaluator.d.ts.map +1 -0
  35. package/dist/authorization/evaluator.js +153 -0
  36. package/dist/authorization/evaluator.js.map +1 -0
  37. package/dist/authorization/facts.d.ts +29 -0
  38. package/dist/authorization/facts.d.ts.map +1 -0
  39. package/dist/authorization/facts.js +17 -0
  40. package/dist/authorization/facts.js.map +1 -0
  41. package/dist/authorization/list-read-scope.d.ts +18 -0
  42. package/dist/authorization/list-read-scope.d.ts.map +1 -0
  43. package/dist/authorization/list-read-scope.js +155 -0
  44. package/dist/authorization/list-read-scope.js.map +1 -0
  45. package/dist/authorization/model/agent.d.ts +2 -0
  46. package/dist/authorization/model/agent.d.ts.map +1 -0
  47. package/dist/authorization/model/agent.js +42 -0
  48. package/dist/authorization/model/agent.js.map +1 -0
  49. package/dist/authorization/model/agent_channel.d.ts +2 -0
  50. package/dist/authorization/model/agent_channel.d.ts.map +1 -0
  51. package/dist/authorization/model/agent_channel.js +38 -0
  52. package/dist/authorization/model/agent_channel.js.map +1 -0
  53. package/dist/authorization/model/agent_execution.d.ts +2 -0
  54. package/dist/authorization/model/agent_execution.d.ts.map +1 -0
  55. package/dist/authorization/model/agent_execution.js +25 -0
  56. package/dist/authorization/model/agent_execution.js.map +1 -0
  57. package/dist/authorization/model/agent_instance.d.ts +2 -0
  58. package/dist/authorization/model/agent_instance.d.ts.map +1 -0
  59. package/dist/authorization/model/agent_instance.js +47 -0
  60. package/dist/authorization/model/agent_instance.js.map +1 -0
  61. package/dist/authorization/model/agent_share.d.ts +2 -0
  62. package/dist/authorization/model/agent_share.d.ts.map +1 -0
  63. package/dist/authorization/model/agent_share.js +29 -0
  64. package/dist/authorization/model/agent_share.js.map +1 -0
  65. package/dist/authorization/model/api_key.d.ts +2 -0
  66. package/dist/authorization/model/api_key.d.ts.map +1 -0
  67. package/dist/authorization/model/api_key.js +27 -0
  68. package/dist/authorization/model/api_key.js.map +1 -0
  69. package/dist/authorization/model/artifact.d.ts +2 -0
  70. package/dist/authorization/model/artifact.d.ts.map +1 -0
  71. package/dist/authorization/model/artifact.js +27 -0
  72. package/dist/authorization/model/artifact.js.map +1 -0
  73. package/dist/authorization/model/channel_app.d.ts +2 -0
  74. package/dist/authorization/model/channel_app.d.ts.map +1 -0
  75. package/dist/authorization/model/channel_app.js +28 -0
  76. package/dist/authorization/model/channel_app.js.map +1 -0
  77. package/dist/authorization/model/default-of.d.ts +38 -0
  78. package/dist/authorization/model/default-of.d.ts.map +1 -0
  79. package/dist/authorization/model/default-of.js +39 -0
  80. package/dist/authorization/model/default-of.js.map +1 -0
  81. package/dist/authorization/model/environment.d.ts +2 -0
  82. package/dist/authorization/model/environment.d.ts.map +1 -0
  83. package/dist/authorization/model/environment.js +33 -0
  84. package/dist/authorization/model/environment.js.map +1 -0
  85. package/dist/authorization/model/execution_context.d.ts +2 -0
  86. package/dist/authorization/model/execution_context.d.ts.map +1 -0
  87. package/dist/authorization/model/execution_context.js +19 -0
  88. package/dist/authorization/model/execution_context.js.map +1 -0
  89. package/dist/authorization/model/iam_policy.d.ts +2 -0
  90. package/dist/authorization/model/iam_policy.d.ts.map +1 -0
  91. package/dist/authorization/model/iam_policy.js +31 -0
  92. package/dist/authorization/model/iam_policy.js.map +1 -0
  93. package/dist/authorization/model/identity_account.d.ts +2 -0
  94. package/dist/authorization/model/identity_account.d.ts.map +1 -0
  95. package/dist/authorization/model/identity_account.js +25 -0
  96. package/dist/authorization/model/identity_account.js.map +1 -0
  97. package/dist/authorization/model/index.d.ts +36 -0
  98. package/dist/authorization/model/index.d.ts.map +1 -0
  99. package/dist/authorization/model/index.js +72 -0
  100. package/dist/authorization/model/index.js.map +1 -0
  101. package/dist/authorization/model/mcp_server.d.ts +2 -0
  102. package/dist/authorization/model/mcp_server.d.ts.map +1 -0
  103. package/dist/authorization/model/mcp_server.js +37 -0
  104. package/dist/authorization/model/mcp_server.js.map +1 -0
  105. package/dist/authorization/model/memory.d.ts +2 -0
  106. package/dist/authorization/model/memory.d.ts.map +1 -0
  107. package/dist/authorization/model/memory.js +26 -0
  108. package/dist/authorization/model/memory.js.map +1 -0
  109. package/dist/authorization/model/oauth_app.d.ts +2 -0
  110. package/dist/authorization/model/oauth_app.d.ts.map +1 -0
  111. package/dist/authorization/model/oauth_app.js +30 -0
  112. package/dist/authorization/model/oauth_app.js.map +1 -0
  113. package/dist/authorization/model/organization.d.ts +2 -0
  114. package/dist/authorization/model/organization.d.ts.map +1 -0
  115. package/dist/authorization/model/organization.js +54 -0
  116. package/dist/authorization/model/organization.js.map +1 -0
  117. package/dist/authorization/model/plugin.d.ts +2 -0
  118. package/dist/authorization/model/plugin.d.ts.map +1 -0
  119. package/dist/authorization/model/plugin.js +44 -0
  120. package/dist/authorization/model/plugin.js.map +1 -0
  121. package/dist/authorization/model/project.d.ts +2 -0
  122. package/dist/authorization/model/project.d.ts.map +1 -0
  123. package/dist/authorization/model/project.js +32 -0
  124. package/dist/authorization/model/project.js.map +1 -0
  125. package/dist/authorization/model/rewrite.d.ts +127 -0
  126. package/dist/authorization/model/rewrite.d.ts.map +1 -0
  127. package/dist/authorization/model/rewrite.js +82 -0
  128. package/dist/authorization/model/rewrite.js.map +1 -0
  129. package/dist/authorization/model/schedule.d.ts +2 -0
  130. package/dist/authorization/model/schedule.d.ts.map +1 -0
  131. package/dist/authorization/model/schedule.js +29 -0
  132. package/dist/authorization/model/schedule.js.map +1 -0
  133. package/dist/authorization/model/session.d.ts +2 -0
  134. package/dist/authorization/model/session.d.ts.map +1 -0
  135. package/dist/authorization/model/session.js +38 -0
  136. package/dist/authorization/model/session.js.map +1 -0
  137. package/dist/authorization/model/skill.d.ts +2 -0
  138. package/dist/authorization/model/skill.d.ts.map +1 -0
  139. package/dist/authorization/model/skill.js +38 -0
  140. package/dist/authorization/model/skill.js.map +1 -0
  141. package/dist/authorization/model/workflow.d.ts +2 -0
  142. package/dist/authorization/model/workflow.d.ts.map +1 -0
  143. package/dist/authorization/model/workflow.js +38 -0
  144. package/dist/authorization/model/workflow.js.map +1 -0
  145. package/dist/authorization/model/workflow_execution.d.ts +2 -0
  146. package/dist/authorization/model/workflow_execution.d.ts.map +1 -0
  147. package/dist/authorization/model/workflow_execution.js +32 -0
  148. package/dist/authorization/model/workflow_execution.js.map +1 -0
  149. package/dist/authorization/model/workflow_instance.d.ts +2 -0
  150. package/dist/authorization/model/workflow_instance.d.ts.map +1 -0
  151. package/dist/authorization/model/workflow_instance.js +92 -0
  152. package/dist/authorization/model/workflow_instance.js.map +1 -0
  153. package/dist/authorization/organization-directory.d.ts +13 -0
  154. package/dist/authorization/organization-directory.d.ts.map +1 -0
  155. package/dist/authorization/organization-directory.js +83 -0
  156. package/dist/authorization/organization-directory.js.map +1 -0
  157. package/dist/authorization/person.d.ts +42 -0
  158. package/dist/authorization/person.d.ts.map +1 -0
  159. package/dist/authorization/person.js +19 -0
  160. package/dist/authorization/person.js.map +1 -0
  161. package/dist/authorization/posture.d.ts +38 -0
  162. package/dist/authorization/posture.d.ts.map +1 -0
  163. package/dist/authorization/posture.js +7 -0
  164. package/dist/authorization/posture.js.map +1 -0
  165. package/dist/authorization/schedule-fire-caller.d.ts +12 -0
  166. package/dist/authorization/schedule-fire-caller.d.ts.map +1 -0
  167. package/dist/authorization/schedule-fire-caller.js +67 -0
  168. package/dist/authorization/schedule-fire-caller.js.map +1 -0
  169. package/dist/authorization/store-test-kit.d.ts +68 -0
  170. package/dist/authorization/store-test-kit.d.ts.map +1 -0
  171. package/dist/authorization/store-test-kit.js +311 -0
  172. package/dist/authorization/store-test-kit.js.map +1 -0
  173. package/dist/authorization/tuples.d.ts +115 -0
  174. package/dist/authorization/tuples.d.ts.map +1 -0
  175. package/dist/authorization/tuples.js +83 -0
  176. package/dist/authorization/tuples.js.map +1 -0
  177. package/dist/boot/compose.d.ts.map +1 -1
  178. package/dist/boot/compose.js +157 -32
  179. package/dist/boot/compose.js.map +1 -1
  180. package/dist/boot/inprocess.d.ts +12 -0
  181. package/dist/boot/inprocess.d.ts.map +1 -1
  182. package/dist/boot/inprocess.js +62 -20
  183. package/dist/boot/inprocess.js.map +1 -1
  184. package/dist/domain/agent/controller.d.ts.map +1 -1
  185. package/dist/domain/agent/controller.js +9 -0
  186. package/dist/domain/agent/controller.js.map +1 -1
  187. package/dist/domain/iampolicy/constants.d.ts +11 -0
  188. package/dist/domain/iampolicy/constants.d.ts.map +1 -1
  189. package/dist/domain/iampolicy/constants.js +11 -0
  190. package/dist/domain/iampolicy/constants.js.map +1 -1
  191. package/dist/domain/iampolicy/membership.d.ts +72 -1
  192. package/dist/domain/iampolicy/membership.d.ts.map +1 -1
  193. package/dist/domain/iampolicy/membership.js +141 -56
  194. package/dist/domain/iampolicy/membership.js.map +1 -1
  195. package/dist/domain/identityaccount/actor.d.ts +26 -0
  196. package/dist/domain/identityaccount/actor.d.ts.map +1 -0
  197. package/dist/domain/identityaccount/actor.js +17 -0
  198. package/dist/domain/identityaccount/actor.js.map +1 -0
  199. package/dist/domain/mcpserver/controller.d.ts.map +1 -1
  200. package/dist/domain/mcpserver/controller.js +9 -0
  201. package/dist/domain/mcpserver/controller.js.map +1 -1
  202. package/dist/domain/plugin/archive.d.ts +37 -0
  203. package/dist/domain/plugin/archive.d.ts.map +1 -0
  204. package/dist/domain/plugin/archive.js +50 -0
  205. package/dist/domain/plugin/archive.js.map +1 -0
  206. package/dist/domain/plugin/constants.d.ts +38 -0
  207. package/dist/domain/plugin/constants.d.ts.map +1 -0
  208. package/dist/domain/plugin/constants.js +46 -0
  209. package/dist/domain/plugin/constants.js.map +1 -0
  210. package/dist/domain/plugin/controller.d.ts +25 -0
  211. package/dist/domain/plugin/controller.d.ts.map +1 -0
  212. package/dist/domain/plugin/controller.js +493 -0
  213. package/dist/domain/plugin/controller.js.map +1 -0
  214. package/dist/domain/plugin/materialize/agent.d.ts +13 -0
  215. package/dist/domain/plugin/materialize/agent.d.ts.map +1 -0
  216. package/dist/domain/plugin/materialize/agent.js +128 -0
  217. package/dist/domain/plugin/materialize/agent.js.map +1 -0
  218. package/dist/domain/plugin/materialize/default-agent-instructions.d.ts +22 -0
  219. package/dist/domain/plugin/materialize/default-agent-instructions.d.ts.map +1 -0
  220. package/dist/domain/plugin/materialize/default-agent-instructions.js +31 -0
  221. package/dist/domain/plugin/materialize/default-agent-instructions.js.map +1 -0
  222. package/dist/domain/plugin/materialize/identity.d.ts +28 -0
  223. package/dist/domain/plugin/materialize/identity.d.ts.map +1 -0
  224. package/dist/domain/plugin/materialize/identity.js +40 -0
  225. package/dist/domain/plugin/materialize/identity.js.map +1 -0
  226. package/dist/domain/plugin/materialize/mcp-servers.d.ts +15 -0
  227. package/dist/domain/plugin/materialize/mcp-servers.d.ts.map +1 -0
  228. package/dist/domain/plugin/materialize/mcp-servers.js +131 -0
  229. package/dist/domain/plugin/materialize/mcp-servers.js.map +1 -0
  230. package/dist/domain/plugin/materialize/plan.d.ts +24 -0
  231. package/dist/domain/plugin/materialize/plan.d.ts.map +1 -0
  232. package/dist/domain/plugin/materialize/plan.js +77 -0
  233. package/dist/domain/plugin/materialize/plan.js.map +1 -0
  234. package/dist/domain/plugin/materialize/ports.d.ts +42 -0
  235. package/dist/domain/plugin/materialize/ports.d.ts.map +1 -0
  236. package/dist/domain/plugin/materialize/ports.js +2 -0
  237. package/dist/domain/plugin/materialize/ports.js.map +1 -0
  238. package/dist/domain/plugin/materialize/skills.d.ts +12 -0
  239. package/dist/domain/plugin/materialize/skills.d.ts.map +1 -0
  240. package/dist/domain/plugin/materialize/skills.js +44 -0
  241. package/dist/domain/plugin/materialize/skills.js.map +1 -0
  242. package/dist/domain/plugin/materialize/workflows.d.ts +15 -0
  243. package/dist/domain/plugin/materialize/workflows.d.ts.map +1 -0
  244. package/dist/domain/plugin/materialize/workflows.js +31 -0
  245. package/dist/domain/plugin/materialize/workflows.js.map +1 -0
  246. package/dist/domain/plugin/members.d.ts +42 -0
  247. package/dist/domain/plugin/members.d.ts.map +1 -0
  248. package/dist/domain/plugin/members.js +97 -0
  249. package/dist/domain/plugin/members.js.map +1 -0
  250. package/dist/domain/plugin/overlay/documents.d.ts +31 -0
  251. package/dist/domain/plugin/overlay/documents.d.ts.map +1 -0
  252. package/dist/domain/plugin/overlay/documents.js +38 -0
  253. package/dist/domain/plugin/overlay/documents.js.map +1 -0
  254. package/dist/domain/plugin/overlay/parse.d.ts +16 -0
  255. package/dist/domain/plugin/overlay/parse.d.ts.map +1 -0
  256. package/dist/domain/plugin/overlay/parse.js +79 -0
  257. package/dist/domain/plugin/overlay/parse.js.map +1 -0
  258. package/dist/domain/plugin/overlay/sanitize.d.ts +10 -0
  259. package/dist/domain/plugin/overlay/sanitize.d.ts.map +1 -0
  260. package/dist/domain/plugin/overlay/sanitize.js +101 -0
  261. package/dist/domain/plugin/overlay/sanitize.js.map +1 -0
  262. package/dist/domain/plugin/push.d.ts +133 -0
  263. package/dist/domain/plugin/push.d.ts.map +1 -0
  264. package/dist/domain/plugin/push.js +800 -0
  265. package/dist/domain/plugin/push.js.map +1 -0
  266. package/dist/domain/plugin/search-extractor.d.ts +3 -0
  267. package/dist/domain/plugin/search-extractor.d.ts.map +1 -0
  268. package/dist/domain/plugin/search-extractor.js +41 -0
  269. package/dist/domain/plugin/search-extractor.js.map +1 -0
  270. package/dist/domain/skill/constants.d.ts +6 -11
  271. package/dist/domain/skill/constants.d.ts.map +1 -1
  272. package/dist/domain/skill/constants.js +6 -11
  273. package/dist/domain/skill/constants.js.map +1 -1
  274. package/dist/domain/skill/controller.d.ts.map +1 -1
  275. package/dist/domain/skill/controller.js +33 -30
  276. package/dist/domain/skill/controller.js.map +1 -1
  277. package/dist/domain/skill/push.d.ts +9 -10
  278. package/dist/domain/skill/push.d.ts.map +1 -1
  279. package/dist/domain/skill/push.js +53 -122
  280. package/dist/domain/skill/push.js.map +1 -1
  281. package/dist/domain/skill/search-extractor.d.ts.map +1 -1
  282. package/dist/domain/skill/search-extractor.js.map +1 -1
  283. package/dist/domain/skill/storage/artifact-storage.d.ts +26 -29
  284. package/dist/domain/skill/storage/artifact-storage.d.ts.map +1 -1
  285. package/dist/domain/skill/storage/artifact-storage.js +6 -103
  286. package/dist/domain/skill/storage/artifact-storage.js.map +1 -1
  287. package/dist/domain/skill/storage/zip-gate.d.ts +1 -2
  288. package/dist/domain/skill/storage/zip-gate.d.ts.map +1 -1
  289. package/dist/domain/skill/storage/zip-gate.js +56 -126
  290. package/dist/domain/skill/storage/zip-gate.js.map +1 -1
  291. package/dist/domain/skill/version-resolution.d.ts +5 -5
  292. package/dist/domain/skill/version-resolution.d.ts.map +1 -1
  293. package/dist/domain/skill/version-resolution.js +34 -216
  294. package/dist/domain/skill/version-resolution.js.map +1 -1
  295. package/dist/domain/workflow/controller.d.ts.map +1 -1
  296. package/dist/domain/workflow/controller.js +30 -3
  297. package/dist/domain/workflow/controller.js.map +1 -1
  298. package/dist/domain/workflow/registry/data/task-kind-registry.json +1 -0
  299. package/dist/extensions/authorizer.d.ts +10 -5
  300. package/dist/extensions/authorizer.d.ts.map +1 -1
  301. package/dist/extensions/drivers.d.ts +4 -1
  302. package/dist/extensions/drivers.d.ts.map +1 -1
  303. package/dist/extensions/list-read-scope.d.ts +75 -11
  304. package/dist/extensions/list-read-scope.d.ts.map +1 -1
  305. package/dist/extensions/list-read-scope.js +40 -7
  306. package/dist/extensions/list-read-scope.js.map +1 -1
  307. package/dist/extensions/organization-directory.d.ts +13 -9
  308. package/dist/extensions/organization-directory.d.ts.map +1 -1
  309. package/dist/extensions/organization-directory.js.map +1 -1
  310. package/dist/extensions/resource-authorization.d.ts +33 -0
  311. package/dist/extensions/resource-authorization.d.ts.map +1 -1
  312. package/dist/extensions/schedule-fire-caller.d.ts +45 -18
  313. package/dist/extensions/schedule-fire-caller.d.ts.map +1 -1
  314. package/dist/extensions/schedule-fire-caller.js +12 -1
  315. package/dist/extensions/schedule-fire-caller.js.map +1 -1
  316. package/dist/index.d.ts +10 -0
  317. package/dist/index.d.ts.map +1 -1
  318. package/dist/index.js +8 -0
  319. package/dist/index.js.map +1 -1
  320. package/dist/pipeline/apiresource-labels.d.ts +23 -3
  321. package/dist/pipeline/apiresource-labels.d.ts.map +1 -1
  322. package/dist/pipeline/apiresource-labels.js +20 -0
  323. package/dist/pipeline/apiresource-labels.js.map +1 -1
  324. package/dist/pipeline/apiresource-meta.d.ts +21 -0
  325. package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
  326. package/dist/pipeline/apiresource-meta.js +28 -0
  327. package/dist/pipeline/apiresource-meta.js.map +1 -1
  328. package/dist/pipeline/errors.d.ts.map +1 -1
  329. package/dist/pipeline/errors.js.map +1 -1
  330. package/dist/pipeline/steps/authorization-facts.d.ts +12 -0
  331. package/dist/pipeline/steps/authorization-facts.d.ts.map +1 -0
  332. package/dist/pipeline/steps/authorization-facts.js +100 -0
  333. package/dist/pipeline/steps/authorization-facts.js.map +1 -0
  334. package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
  335. package/dist/pipeline/steps/authorization-tuples.js +7 -26
  336. package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
  337. package/dist/pipeline/steps/delete.d.ts.map +1 -1
  338. package/dist/pipeline/steps/delete.js +1 -1
  339. package/dist/pipeline/steps/delete.js.map +1 -1
  340. package/dist/pipeline/steps/duplicate.d.ts.map +1 -1
  341. package/dist/pipeline/steps/duplicate.js.map +1 -1
  342. package/dist/pipeline/steps/guard-plugin-managed.d.ts +12 -0
  343. package/dist/pipeline/steps/guard-plugin-managed.d.ts.map +1 -0
  344. package/dist/pipeline/steps/guard-plugin-managed.js +96 -0
  345. package/dist/pipeline/steps/guard-plugin-managed.js.map +1 -0
  346. package/dist/pipeline/steps/guard-reserved-labels.d.ts +16 -2
  347. package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
  348. package/dist/pipeline/steps/guard-reserved-labels.js +11 -7
  349. package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
  350. package/dist/pipeline/steps/helpers.d.ts.map +1 -1
  351. package/dist/pipeline/steps/helpers.js.map +1 -1
  352. package/dist/pipeline/steps/index-search.d.ts.map +1 -1
  353. package/dist/pipeline/steps/index-search.js.map +1 -1
  354. package/dist/pipeline/steps/load-existing.d.ts.map +1 -1
  355. package/dist/pipeline/steps/load-existing.js +1 -1
  356. package/dist/pipeline/steps/load-existing.js.map +1 -1
  357. package/dist/pipeline/steps/references.d.ts +16 -0
  358. package/dist/pipeline/steps/references.d.ts.map +1 -1
  359. package/dist/pipeline/steps/references.js +18 -0
  360. package/dist/pipeline/steps/references.js.map +1 -1
  361. package/dist/pipeline/steps/resolve-artifact-source.d.ts +35 -0
  362. package/dist/pipeline/steps/resolve-artifact-source.d.ts.map +1 -0
  363. package/dist/pipeline/steps/resolve-artifact-source.js +27 -0
  364. package/dist/pipeline/steps/resolve-artifact-source.js.map +1 -0
  365. package/dist/pipeline/steps/server-stamped-reserved-labels.d.ts.map +1 -1
  366. package/dist/pipeline/steps/server-stamped-reserved-labels.js.map +1 -1
  367. package/dist/pipeline/steps/shapes.d.ts +18 -0
  368. package/dist/pipeline/steps/shapes.d.ts.map +1 -1
  369. package/dist/pipeline/steps/shapes.js +29 -0
  370. package/dist/pipeline/steps/shapes.js.map +1 -1
  371. package/dist/pipeline/steps/slug.d.ts.map +1 -1
  372. package/dist/pipeline/steps/slug.js.map +1 -1
  373. package/dist/pipeline/steps/validate-visibility.d.ts +9 -0
  374. package/dist/pipeline/steps/validate-visibility.d.ts.map +1 -1
  375. package/dist/pipeline/steps/validate-visibility.js +6 -1
  376. package/dist/pipeline/steps/validate-visibility.js.map +1 -1
  377. package/dist/pipeline/steps/validation.d.ts.map +1 -1
  378. package/dist/pipeline/steps/validation.js.map +1 -1
  379. package/dist/pipeline/steps/version-archive.d.ts +63 -0
  380. package/dist/pipeline/steps/version-archive.d.ts.map +1 -0
  381. package/dist/pipeline/steps/version-archive.js +129 -0
  382. package/dist/pipeline/steps/version-archive.js.map +1 -0
  383. package/dist/pipeline/steps/version-history.d.ts +49 -0
  384. package/dist/pipeline/steps/version-history.d.ts.map +1 -0
  385. package/dist/pipeline/steps/version-history.js +229 -0
  386. package/dist/pipeline/steps/version-history.js.map +1 -0
  387. package/dist/pipeline/steps/visibility-gates.d.ts +8 -0
  388. package/dist/pipeline/steps/visibility-gates.d.ts.map +1 -1
  389. package/dist/pipeline/steps/visibility-gates.js +7 -2
  390. package/dist/pipeline/steps/visibility-gates.js.map +1 -1
  391. package/dist/query/search/registry.d.ts.map +1 -1
  392. package/dist/query/search/registry.js +2 -0
  393. package/dist/query/search/registry.js.map +1 -1
  394. package/dist/temporal/schedule/run-starter.d.ts +1 -1
  395. package/dist/temporal/schedule/run-starter.d.ts.map +1 -1
  396. package/dist/temporal/schedule/run-starter.js +14 -1
  397. package/dist/temporal/schedule/run-starter.js.map +1 -1
  398. package/package.json +5 -4
  399. package/src/archive/__tests__/archive.test.ts +233 -0
  400. package/src/{domain/skill → archive}/__tests__/prefilter.test.ts +1 -1
  401. package/src/archive/content-store.ts +132 -0
  402. package/src/archive/inflate.ts +107 -0
  403. package/src/archive/limits.ts +42 -0
  404. package/src/archive/open.ts +131 -0
  405. package/src/{domain/skill/storage → archive}/prefilter.ts +5 -0
  406. package/src/archive/write.ts +54 -0
  407. package/src/authorization/README.md +124 -0
  408. package/src/authorization/__tests__/authorizer.test.ts +719 -0
  409. package/src/authorization/__tests__/derived-tuples.test.ts +802 -0
  410. package/src/authorization/__tests__/drivers.ts +70 -0
  411. package/src/authorization/__tests__/evaluator.test.ts +359 -0
  412. package/src/authorization/__tests__/facts.test.ts +155 -0
  413. package/src/authorization/__tests__/fixtures/fga/agent-channel-owner.fga.yaml +112 -0
  414. package/src/authorization/__tests__/fixtures/fga/agent-share-owner.fga.yaml +109 -0
  415. package/src/authorization/__tests__/fixtures/fga/artifact-org-and-owner.fga.yaml +128 -0
  416. package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +410 -0
  417. package/src/authorization/__tests__/fixtures/fga/channel-app-owner.fga.yaml +125 -0
  418. package/src/authorization/__tests__/fixtures/fga/channel-participation.fga.yaml +201 -0
  419. package/src/authorization/__tests__/fixtures/fga/channel-session-visibility.fga.yaml +187 -0
  420. package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +98 -0
  421. package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +271 -0
  422. package/src/authorization/__tests__/fixtures/fga/memory-subject-only.fga.yaml +72 -0
  423. package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +328 -0
  424. package/src/authorization/__tests__/fixtures/fga/org-shared-environment.fga.yaml +144 -0
  425. package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +223 -0
  426. package/src/authorization/__tests__/fixtures/fga/provider-standing-viewer.fga.yaml +40 -0
  427. package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +52 -0
  428. package/src/authorization/__tests__/fixtures/fga/reserved-label-writer.fga.yaml +41 -0
  429. package/src/authorization/__tests__/fixtures/fga/schedule-owner.fga.yaml +113 -0
  430. package/src/authorization/__tests__/fixtures/fga/schedule-session-visibility.fga.yaml +214 -0
  431. package/src/authorization/__tests__/fixtures/fga/session-personal-resource.fga.yaml +117 -0
  432. package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +192 -0
  433. package/src/authorization/__tests__/list-read-scope.measure.test.ts +317 -0
  434. package/src/authorization/__tests__/list-read-scope.test.ts +796 -0
  435. package/src/authorization/__tests__/organization-directory.test.ts +236 -0
  436. package/src/authorization/__tests__/person.test.ts +114 -0
  437. package/src/authorization/__tests__/posture.test.ts +25 -0
  438. package/src/authorization/__tests__/schedule-fire-caller.test.ts +134 -0
  439. package/src/authorization/__tests__/store-tests.test.ts +306 -0
  440. package/src/authorization/__tests__/support.ts +101 -0
  441. package/src/authorization/__tests__/tuples.test.ts +62 -0
  442. package/src/authorization/__tests__/wire-permissions.test.ts +154 -0
  443. package/src/authorization/authorizer.ts +208 -0
  444. package/src/authorization/derived-tuples.ts +384 -0
  445. package/src/authorization/evaluator.ts +283 -0
  446. package/src/authorization/facts.ts +47 -0
  447. package/src/authorization/list-read-scope.ts +216 -0
  448. package/src/authorization/model/__tests__/registry.test.ts +317 -0
  449. package/src/authorization/model/agent.ts +64 -0
  450. package/src/authorization/model/agent_channel.ts +49 -0
  451. package/src/authorization/model/agent_execution.ts +33 -0
  452. package/src/authorization/model/agent_instance.ts +66 -0
  453. package/src/authorization/model/agent_share.ts +40 -0
  454. package/src/authorization/model/api_key.ts +28 -0
  455. package/src/authorization/model/artifact.ts +38 -0
  456. package/src/authorization/model/channel_app.ts +39 -0
  457. package/src/authorization/model/default-of.ts +99 -0
  458. package/src/authorization/model/environment.ts +48 -0
  459. package/src/authorization/model/execution_context.ts +20 -0
  460. package/src/authorization/model/iam_policy.ts +42 -0
  461. package/src/authorization/model/identity_account.ts +26 -0
  462. package/src/authorization/model/index.ts +108 -0
  463. package/src/authorization/model/mcp_server.ts +59 -0
  464. package/src/authorization/model/memory.ts +27 -0
  465. package/src/authorization/model/oauth_app.ts +42 -0
  466. package/src/authorization/model/organization.ts +55 -0
  467. package/src/authorization/model/plugin.ts +66 -0
  468. package/src/authorization/model/project.ts +47 -0
  469. package/src/authorization/model/rewrite.ts +213 -0
  470. package/src/authorization/model/schedule.ts +40 -0
  471. package/src/authorization/model/session.ts +50 -0
  472. package/src/authorization/model/skill.ts +60 -0
  473. package/src/authorization/model/workflow.ts +60 -0
  474. package/src/authorization/model/workflow_execution.ts +44 -0
  475. package/src/authorization/model/workflow_instance.ts +122 -0
  476. package/src/authorization/organization-directory.ts +114 -0
  477. package/src/authorization/person.ts +68 -0
  478. package/src/authorization/posture.ts +49 -0
  479. package/src/authorization/schedule-fire-caller.ts +91 -0
  480. package/src/authorization/store-test-kit.ts +454 -0
  481. package/src/authorization/tuples.ts +190 -0
  482. package/src/boot/compose.ts +175 -38
  483. package/src/boot/inprocess.ts +108 -30
  484. package/src/domain/agent/controller.ts +11 -0
  485. package/src/domain/iampolicy/__tests__/membership.test.ts +357 -3
  486. package/src/domain/iampolicy/constants.ts +12 -0
  487. package/src/domain/iampolicy/membership.ts +221 -66
  488. package/src/domain/identityaccount/actor.ts +44 -0
  489. package/src/domain/mcpserver/controller.ts +11 -0
  490. package/src/domain/plugin/__tests__/materialize.test.ts +303 -0
  491. package/src/domain/plugin/__tests__/overlay-parse.test.ts +85 -0
  492. package/src/domain/plugin/__tests__/plugin.test.ts +681 -0
  493. package/src/domain/plugin/__tests__/sanitize.test.ts +174 -0
  494. package/src/domain/plugin/archive.ts +89 -0
  495. package/src/domain/plugin/constants.ts +53 -0
  496. package/src/domain/plugin/controller.ts +913 -0
  497. package/src/domain/plugin/materialize/agent.ts +186 -0
  498. package/src/domain/plugin/materialize/default-agent-instructions.ts +59 -0
  499. package/src/domain/plugin/materialize/identity.ts +67 -0
  500. package/src/domain/plugin/materialize/mcp-servers.ts +175 -0
  501. package/src/domain/plugin/materialize/plan.ts +124 -0
  502. package/src/domain/plugin/materialize/ports.ts +53 -0
  503. package/src/domain/plugin/materialize/skills.ts +68 -0
  504. package/src/domain/plugin/materialize/workflows.ts +51 -0
  505. package/src/domain/plugin/members.ts +180 -0
  506. package/src/domain/plugin/overlay/documents.ts +78 -0
  507. package/src/domain/plugin/overlay/parse.ts +115 -0
  508. package/src/domain/plugin/overlay/sanitize.ts +149 -0
  509. package/src/domain/plugin/push.ts +1062 -0
  510. package/src/domain/plugin/search-extractor.ts +60 -0
  511. package/src/domain/skill/constants.ts +11 -14
  512. package/src/domain/skill/controller.ts +44 -36
  513. package/src/domain/skill/push.ts +61 -156
  514. package/src/domain/skill/search-extractor.ts +3 -1
  515. package/src/domain/skill/storage/artifact-storage.ts +23 -124
  516. package/src/domain/skill/storage/zip-gate.ts +58 -154
  517. package/src/domain/skill/version-resolution.ts +67 -269
  518. package/src/domain/workflow/controller.ts +38 -4
  519. package/src/domain/workflow/registry/data/task-kind-registry.json +1 -0
  520. package/src/extensions/__tests__/built-in-authorization-composed.test.ts +835 -0
  521. package/src/extensions/__tests__/composed-support.ts +32 -1
  522. package/src/extensions/__tests__/extension-composition.test.ts +35 -0
  523. package/src/extensions/__tests__/list-read-scope.test.ts +245 -3
  524. package/src/extensions/__tests__/role-reconciliation-composed.test.ts +209 -0
  525. package/src/extensions/__tests__/tier-truthfulness.test.ts +6 -14
  526. package/src/extensions/authorizer.ts +10 -5
  527. package/src/extensions/drivers.ts +4 -1
  528. package/src/extensions/list-read-scope.ts +116 -16
  529. package/src/extensions/organization-directory.ts +13 -9
  530. package/src/extensions/resource-authorization.ts +34 -0
  531. package/src/extensions/schedule-fire-caller.ts +49 -18
  532. package/src/index.ts +51 -1
  533. package/src/pipeline/__tests__/inherited-authorization-parent.test.ts +51 -0
  534. package/src/pipeline/__tests__/router-transport.test.ts +1 -3
  535. package/src/pipeline/apiresource-labels.ts +31 -3
  536. package/src/pipeline/apiresource-meta.ts +37 -0
  537. package/src/pipeline/errors.ts +5 -5
  538. package/src/pipeline/steps/__tests__/authorize-annotation-completeness.test.ts +1 -20
  539. package/src/pipeline/steps/__tests__/guard-memory-capture.test.ts +3 -9
  540. package/src/pipeline/steps/__tests__/guard-plugin-managed.test.ts +151 -0
  541. package/src/pipeline/steps/__tests__/guard-reserved-labels.test.ts +83 -8
  542. package/src/pipeline/steps/authorization-facts.ts +131 -0
  543. package/src/pipeline/steps/authorization-tuples.ts +7 -28
  544. package/src/pipeline/steps/delete.ts +11 -3
  545. package/src/pipeline/steps/duplicate.ts +8 -2
  546. package/src/pipeline/steps/guard-plugin-managed.ts +133 -0
  547. package/src/pipeline/steps/guard-reserved-labels.ts +29 -8
  548. package/src/pipeline/steps/helpers.ts +4 -1
  549. package/src/pipeline/steps/index-search.ts +28 -15
  550. package/src/pipeline/steps/load-existing.ts +12 -3
  551. package/src/pipeline/steps/references.ts +36 -2
  552. package/src/pipeline/steps/resolve-artifact-source.ts +66 -0
  553. package/src/pipeline/steps/server-stamped-reserved-labels.ts +2 -1
  554. package/src/pipeline/steps/shapes.ts +31 -0
  555. package/src/pipeline/steps/slug.ts +7 -2
  556. package/src/pipeline/steps/validate-visibility.ts +9 -2
  557. package/src/pipeline/steps/validation.ts +3 -1
  558. package/src/pipeline/steps/version-archive.ts +225 -0
  559. package/src/pipeline/steps/version-history.ts +362 -0
  560. package/src/pipeline/steps/visibility-gates.ts +12 -9
  561. package/src/query/README.md +1 -1
  562. package/src/query/search/__tests__/criteria.test.ts +6 -7
  563. package/src/query/search/__tests__/query-store.test.ts +9 -2
  564. package/src/query/search/__tests__/registry.test.ts +6 -4
  565. package/src/query/search/registry.ts +6 -1
  566. package/src/temporal/schedule/__tests__/run-starter.test.ts +86 -24
  567. package/src/temporal/schedule/run-starter.ts +31 -8
  568. package/dist/domain/skill/storage/prefilter.d.ts.map +0 -1
  569. package/dist/domain/skill/storage/prefilter.js.map +0 -1
  570. /package/dist/{domain/skill/storage → archive}/prefilter.js +0 -0
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The two store drivers as test fixtures, for every authorization test
3
+ * that must hold on sqlite AND Postgres (the source, the Authorizer, the
4
+ * directory, the fire caller): `describe.each(driverFixtures(kinds))`
5
+ * opens a fresh sqlite file per test, or the shared Postgres test
6
+ * database with the named kinds cleared — the shape derived-tuples.test.ts
7
+ * established, lifted here so four files do not carry four copies.
8
+ *
9
+ * Postgres is skipped, never failed, when no `TEST_DATABASE_URL` is set
10
+ * (the store's own convention); `dropPostgresFixture` is the `afterAll`
11
+ * each file registers so the database it created is dropped.
12
+ */
13
+ import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
14
+
15
+ import type { Store } from "../../store/interface.js";
16
+ import { PostgresStore } from "../../store/postgres/store.js";
17
+ import {
18
+ createTestDatabase,
19
+ testDatabaseAdminUrl,
20
+ type TestDatabase,
21
+ } from "../../store/postgres/__tests__/support.js";
22
+ import { tempStore } from "../../store/sqlite/__tests__/support.js";
23
+
24
+ export interface OpenedStore {
25
+ readonly store: Store;
26
+ close(): Promise<void>;
27
+ }
28
+
29
+ export interface DriverFixture {
30
+ readonly name: string;
31
+ readonly skip: boolean;
32
+ open(): Promise<OpenedStore>;
33
+ }
34
+
35
+ let postgresDatabase: TestDatabase | undefined;
36
+
37
+ /** Both drivers; `seededKinds` are cleared on the shared Postgres database before each open. */
38
+ export function driverFixtures(
39
+ seededKinds: ReadonlyArray<ApiResourceKind>,
40
+ ): ReadonlyArray<DriverFixture> {
41
+ return [
42
+ {
43
+ name: "sqlite",
44
+ skip: false,
45
+ async open() {
46
+ const temp = tempStore();
47
+ return { store: temp.store, close: () => temp.cleanup() };
48
+ },
49
+ },
50
+ {
51
+ name: "postgres",
52
+ skip: testDatabaseAdminUrl() === undefined,
53
+ async open() {
54
+ if (postgresDatabase === undefined) {
55
+ postgresDatabase = await createTestDatabase();
56
+ }
57
+ const store = await PostgresStore.open(postgresDatabase.databaseUrl);
58
+ for (const kind of seededKinds) {
59
+ await store.deleteResourcesByKind(kind);
60
+ }
61
+ return { store, close: () => store.close() };
62
+ },
63
+ },
64
+ ];
65
+ }
66
+
67
+ export async function dropPostgresFixture(): Promise<void> {
68
+ await postgresDatabase?.drop();
69
+ postgresDatabase = undefined;
70
+ }
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Pins the evaluator's semantics the store tests cannot express (the
3
+ * cloud's `.fga.yaml` documents prove the model's answers; this file
4
+ * proves the machinery under them): how a person matches a tuple, what
5
+ * the `allow_public` context does, that a direct tuple outside the line's
6
+ * type restriction is ignored (model drift fails closed), how far a
7
+ * resolution may walk, and that a declaration cycle or an undeclared
8
+ * target is a thrown fault and never a silent deny.
9
+ *
10
+ * The fixture source is the in-memory one the store-test kit uses, so the
11
+ * two proofs share one tuple vocabulary. Where a case needs a shape the
12
+ * real model does not have (a cycle, a chain past the depth bound), it
13
+ * declares a throwaway model with `declareKind`; everything else runs
14
+ * over the built-in model so the fixtures are real relations.
15
+ */
16
+ import { describe, expect, it } from "vitest";
17
+
18
+ import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
19
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
20
+
21
+ import {
22
+ AuthorizationEvaluationError,
23
+ MAX_RESOLUTION_DEPTH,
24
+ checkRelation,
25
+ } from "../evaluator.js";
26
+ import { builtInModel, newModel } from "../model/index.js";
27
+ import {
28
+ computed,
29
+ declareKind,
30
+ direct,
31
+ from,
32
+ objectOf,
33
+ publicWith,
34
+ union,
35
+ usersetOf,
36
+ } from "../model/rewrite.js";
37
+ import type { Person, Tuple, TupleSource } from "../tuples.js";
38
+ import {
39
+ newInMemoryTupleSource,
40
+ parseObjectRef,
41
+ parseSubject,
42
+ } from "../tuples.js";
43
+
44
+ /** `object#relation@subject` in the FGA tuple notation, the fixtures' own spelling. */
45
+ function tuple(text: string): Tuple {
46
+ const [objectAndRelation, subject] = text.split("@") as [string, string];
47
+ const [object, relation] = objectAndRelation.split("#") as [string, string];
48
+ return {
49
+ object: parseObjectRef(object),
50
+ relation,
51
+ subject: parseSubject(subject),
52
+ };
53
+ }
54
+
55
+ function person(accountId: string, ...aliases: string[]): Person {
56
+ return { accountId, aliases: new Set([accountId, ...aliases]) };
57
+ }
58
+
59
+ const RESOLVE = { allow: true };
60
+ const LIST = { allow: false };
61
+
62
+ async function allowed(
63
+ source: TupleSource,
64
+ object: string,
65
+ relation: string,
66
+ who: Person,
67
+ context = RESOLVE,
68
+ ): Promise<boolean> {
69
+ return checkRelation(
70
+ { model: builtInModel, source },
71
+ parseObjectRef(object),
72
+ relation,
73
+ who,
74
+ context,
75
+ );
76
+ }
77
+
78
+ describe("a person against a direct tuple", () => {
79
+ const source = newInMemoryTupleSource([
80
+ tuple("agent:a#organization@organization:acme"),
81
+ tuple("agent:a#owner@identity_account:auth0|carol"),
82
+ ]);
83
+
84
+ it("matches on any alias, so a row stamped with the 3.14 issuer subject is still its creator's", async () => {
85
+ const carol = person("ida_carol", "auth0|carol");
86
+ expect(await allowed(source, "agent:a", "can_edit", carol)).toBe(true);
87
+ expect(
88
+ await allowed(source, "agent:a", "can_edit", person("ida_carol")),
89
+ ).toBe(false);
90
+ });
91
+
92
+ it("a tuple naming the empty stamp or the laptop's `system` placeholder reaches no person — the derivation never emits one, and `personFor` never builds one (tuples.test.ts)", async () => {
93
+ const stamped = newInMemoryTupleSource([
94
+ tuple("agent:b#owner@identity_account:"),
95
+ tuple("agent:c#owner@identity_account:system"),
96
+ ]);
97
+ const someone = person("ida_someone", "auth0|someone");
98
+ expect(await allowed(stamped, "agent:b", "can_edit", someone)).toBe(false);
99
+ expect(await allowed(stamped, "agent:c", "can_edit", someone)).toBe(false);
100
+ });
101
+ });
102
+
103
+ describe("the public wildcard and its condition", () => {
104
+ const publicViewer = (object: string): Tuple => ({
105
+ object: parseObjectRef(object),
106
+ relation: "viewer",
107
+ subject: {
108
+ form: "wildcard",
109
+ type: "identity_account",
110
+ condition: "allow_public",
111
+ },
112
+ });
113
+ const source = newInMemoryTupleSource([
114
+ tuple("agent:open#organization@organization:acme"),
115
+ publicViewer("agent:open"),
116
+ ]);
117
+ const stranger = person("ida_mallory");
118
+
119
+ it("reads for anyone on a point check (the cloud's `allow: true`) and for nobody in a listing (`allow: false`)", async () => {
120
+ expect(await allowed(source, "agent:open", "can_view", stranger)).toBe(
121
+ true,
122
+ );
123
+ expect(
124
+ await allowed(source, "agent:open", "can_view", stranger, LIST),
125
+ ).toBe(false);
126
+ });
127
+
128
+ it("ignores a wildcard tuple that carries no condition where the line demands one — a tuple the cloud could never have written", async () => {
129
+ const bare = newInMemoryTupleSource([
130
+ tuple("agent:open#viewer@identity_account:*"),
131
+ ]);
132
+ expect(await allowed(bare, "agent:open", "can_view", stranger)).toBe(false);
133
+ });
134
+
135
+ it("is a thrown fault under a condition the transcript names but the evaluator does not know — a model that grew a condition", async () => {
136
+ const grown = declareKind({
137
+ kind: ApiResourceKind.agent,
138
+ schema: AgentSchema,
139
+ source: "test/grown.fga",
140
+ relations: [
141
+ ["viewer", direct(publicWith("identity_account", "after_hours"))],
142
+ ],
143
+ });
144
+ const afterHours = newInMemoryTupleSource([
145
+ {
146
+ object: parseObjectRef("agent:open"),
147
+ relation: "viewer",
148
+ subject: {
149
+ form: "wildcard",
150
+ type: "identity_account",
151
+ condition: "after_hours",
152
+ },
153
+ },
154
+ ]);
155
+ await expect(
156
+ checkRelation(
157
+ { model: newModel([grown]), source: afterHours },
158
+ parseObjectRef("agent:open"),
159
+ "viewer",
160
+ stranger,
161
+ RESOLVE,
162
+ ),
163
+ ).rejects.toMatchObject({ reason: "unknown-condition" });
164
+ });
165
+ });
166
+
167
+ describe("type restrictions on a direct line", () => {
168
+ it("honours a userset subject only where the line lists it — `organization.owner` is `[identity_account]`, so another organization's member userset on it grants nothing", async () => {
169
+ // A tuple the cloud could never have written (the write would be
170
+ // rejected by the type restriction); the evaluator refuses it the
171
+ // same way, so a derivation that drifts from the model denies
172
+ // instead of allowing.
173
+ const source = newInMemoryTupleSource([
174
+ tuple("organization:acme#member@identity_account:ida_dave"),
175
+ tuple("organization:other#owner@organization:acme#member"),
176
+ ]);
177
+ expect(
178
+ await allowed(
179
+ source,
180
+ "organization:other",
181
+ "can_delete",
182
+ person("ida_dave"),
183
+ ),
184
+ ).toBe(false);
185
+ });
186
+
187
+ it("resolves an allowed userset through the parent's own relation, ladder included", async () => {
188
+ const source = newInMemoryTupleSource([
189
+ tuple("organization:acme#owner@identity_account:ida_root"),
190
+ tuple("agent:team#organization@organization:acme"),
191
+ tuple("agent:team#viewer@organization:acme#viewer"),
192
+ ]);
193
+ // owner ⊂ admin ⊂ member ⊂ viewer: the owner satisfies organization#viewer.
194
+ expect(
195
+ await allowed(source, "agent:team", "can_view", person("ida_root")),
196
+ ).toBe(true);
197
+ });
198
+ });
199
+
200
+ describe("relations and kinds the model does not declare", () => {
201
+ const source = newInMemoryTupleSource([
202
+ tuple("agent:a#organization@organization:acme"),
203
+ tuple("agent:a#owner@identity_account:ida_carol"),
204
+ ]);
205
+
206
+ it("an undeclared relation on a declared kind is false — the ruled answer: deny, never INTERNAL", async () => {
207
+ expect(
208
+ await allowed(source, "agent:a", "can_read_secrets", person("ida_carol")),
209
+ ).toBe(false);
210
+ });
211
+
212
+ it("an undeclared kind as the TARGET is a thrown fault — the driver refused unserved kinds before, so reaching here is a registry gap", async () => {
213
+ await expect(
214
+ allowed(source, "identity_provider:idp", "can_view", person("ida_carol")),
215
+ ).rejects.toMatchObject({ reason: "undeclared-target-kind" });
216
+ });
217
+
218
+ it("an undeclared kind reached through a hop yields nothing — `agent.platform_viewer` walks `identity_provider#platform_user`", async () => {
219
+ const platform = newInMemoryTupleSource([
220
+ tuple("agent:p#organization@organization:acme"),
221
+ tuple("agent:p#platform_viewer@identity_provider:idp#platform_user"),
222
+ ]);
223
+ expect(
224
+ await allowed(platform, "agent:p", "can_view", person("ida_zed")),
225
+ ).toBe(false);
226
+ });
227
+ });
228
+
229
+ describe("the walk itself", () => {
230
+ it("asks the source once per (object, relation) — the memo — and stops at the first true member of a union", async () => {
231
+ const asked: string[] = [];
232
+ const inner = newInMemoryTupleSource([
233
+ tuple("organization:acme#owner@identity_account:ida_root"),
234
+ tuple("agent:a#organization@organization:acme"),
235
+ tuple("agent:a#owner@identity_account:ida_carol"),
236
+ ]);
237
+ const counting: TupleSource = {
238
+ tuplesOf(object, relation) {
239
+ asked.push(`${object.type}:${object.id}#${relation}`);
240
+ return inner.tuplesOf(object, relation);
241
+ },
242
+ };
243
+ // can_view → viewer → this | owner | platform_viewer; owner → this | admin from organization;
244
+ // organization.admin → this | owner; organization.owner → this (root: true).
245
+ expect(
246
+ await allowed(counting, "agent:a", "can_view", person("ida_root")),
247
+ ).toBe(true);
248
+ const distinct = new Set(asked);
249
+ expect(asked.length, `each pair asked once: ${asked.join(", ")}`).toBe(
250
+ distinct.size,
251
+ );
252
+ // The platform_viewer arm sits AFTER owner in the union and is never reached.
253
+ expect(asked).not.toContain("agent:a#platform_viewer");
254
+ });
255
+
256
+ it("bounds the resolution at OpenFGA's own limit and reports the overrun as a fault", async () => {
257
+ // A chain of `next from link` deeper than the bound, on a throwaway model.
258
+ const deep = declareKind({
259
+ kind: ApiResourceKind.agent,
260
+ schema: AgentSchema,
261
+ source: "test/deep.fga",
262
+ relations: [
263
+ ["link", direct(objectOf("agent"))],
264
+ [
265
+ "next",
266
+ union(direct(objectOf("identity_account")), from("next", "link")),
267
+ ],
268
+ ],
269
+ });
270
+ const chain: Tuple[] = [];
271
+ for (let i = 0; i < MAX_RESOLUTION_DEPTH + 2; i += 1) {
272
+ chain.push(tuple(`agent:n${i}#link@agent:n${i + 1}`));
273
+ }
274
+ await expect(
275
+ checkRelation(
276
+ { model: newModel([deep]), source: newInMemoryTupleSource(chain) },
277
+ parseObjectRef("agent:n0"),
278
+ "next",
279
+ person("ida_nobody"),
280
+ RESOLVE,
281
+ ),
282
+ ).rejects.toMatchObject({ reason: "resolution-depth-exceeded" });
283
+ });
284
+
285
+ it("a declaration that re-enters itself on one object is a cycle fault, never a silent false", async () => {
286
+ const cyclic = declareKind({
287
+ kind: ApiResourceKind.agent,
288
+ schema: AgentSchema,
289
+ source: "test/cyclic.fga",
290
+ relations: [
291
+ ["a", computed("b")],
292
+ ["b", computed("a")],
293
+ ],
294
+ });
295
+ await expect(
296
+ checkRelation(
297
+ { model: newModel([cyclic]), source: newInMemoryTupleSource([]) },
298
+ parseObjectRef("agent:x"),
299
+ "a",
300
+ person("ida_nobody"),
301
+ RESOLVE,
302
+ ),
303
+ ).rejects.toBeInstanceOf(AuthorizationEvaluationError);
304
+ });
305
+ });
306
+
307
+ describe("declareKind validates a transcript at load", () => {
308
+ it("refuses a computed or tupleset reference to a relation the kind does not declare", () => {
309
+ expect(() =>
310
+ declareKind({
311
+ kind: ApiResourceKind.agent,
312
+ schema: AgentSchema,
313
+ source: "test/bad.fga",
314
+ relations: [["can_view", computed("viewer")]],
315
+ }),
316
+ ).toThrow("relation 'viewer'");
317
+ expect(() =>
318
+ declareKind({
319
+ kind: ApiResourceKind.agent,
320
+ schema: AgentSchema,
321
+ source: "test/bad.fga",
322
+ relations: [["owner", from("admin", "organization")]],
323
+ }),
324
+ ).toThrow("tupleset 'organization'");
325
+ });
326
+
327
+ it("refuses a relation declared twice", () => {
328
+ expect(() =>
329
+ declareKind({
330
+ kind: ApiResourceKind.agent,
331
+ schema: AgentSchema,
332
+ source: "test/bad.fga",
333
+ relations: [
334
+ ["viewer", direct(objectOf("identity_account"))],
335
+ ["viewer", direct(publicWith("identity_account", "allow_public"))],
336
+ ],
337
+ }),
338
+ ).toThrow("declared twice");
339
+ });
340
+
341
+ it("carries the FGA type name of its kind and its relations in file order", () => {
342
+ const declaration = declareKind({
343
+ kind: ApiResourceKind.mcp_server,
344
+ schema: AgentSchema,
345
+ source: "test/order.fga",
346
+ relations: [
347
+ ["organization", direct(objectOf("organization"))],
348
+ ["owner", direct(usersetOf("organization", "admin"))],
349
+ ["can_edit", computed("owner")],
350
+ ],
351
+ });
352
+ expect(declaration.type).toBe("mcp_server");
353
+ expect([...declaration.relations.keys()]).toEqual([
354
+ "organization",
355
+ "owner",
356
+ "can_edit",
357
+ ]);
358
+ });
359
+ });
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Pins the one place two readers of `kind_meta.authorization` could
3
+ * drift: the tuple lifecycle resolves a just-persisted row into the facts
4
+ * a driver writes tuples from (`resolveResourceCreatedEvent`), and the
5
+ * built-in authorizer resolves a LOADED row into the facts it derives
6
+ * tuples from (`rowFactsOf`). The two are separate functions on purpose —
7
+ * the create-time one throws on a missing organization or parent (a
8
+ * create must not half-succeed), the read-time one carries what the row
9
+ * says (a legacy row is a fact, not a fault) — so for every declared kind
10
+ * a well-formed row must resolve to the same parent links and the same
11
+ * visibility shapes through both, and this file is where that is proven
12
+ * rather than remembered.
13
+ *
14
+ * The facts have a second producer since the list scope: the list lanes'
15
+ * shared helper builds every candidate's `ListEntryMeta` through the same
16
+ * structural resolver, so the second half pins that a row offered to a
17
+ * list carries exactly the facts the point-check driver would derive
18
+ * from the loaded row — the "two producers" the module header promised,
19
+ * proven equal.
20
+ */
21
+ import { create } from "@bufbuild/protobuf";
22
+ import { describe, expect, it } from "vitest";
23
+
24
+ import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
25
+
26
+ import { silentLogger } from "../../extensions/__tests__/composed-support.js";
27
+ import type { CallerIdentity } from "../../extensions/identity.js";
28
+ import type {
29
+ ListEntryMeta,
30
+ ListReadScope,
31
+ } from "../../extensions/list-read-scope.js";
32
+ import { restrictListByReadScope } from "../../extensions/list-read-scope.js";
33
+ import {
34
+ resolveResourceCreatedEvent,
35
+ visibilityShapesFor,
36
+ } from "../../pipeline/steps/authorization-tuples.js";
37
+ import { rowFactsOf, rowFactsOfEntry } from "../facts.js";
38
+ import { builtInModel } from "../model/index.js";
39
+ import { fixtureRow } from "./support.js";
40
+
41
+ const CREATOR: CallerIdentity = {
42
+ identityId: "ida_carol",
43
+ callerClass: "user",
44
+ issuer: "https://issuer.example",
45
+ rawToken: "opaque",
46
+ };
47
+
48
+ describe("rowFactsOf against the tuple lifecycle's own resolution", () => {
49
+ for (const declaration of builtInModel.declarations) {
50
+ for (const visibility of [
51
+ ApiResourceVisibility.visibility_private,
52
+ ApiResourceVisibility.visibility_org,
53
+ ApiResourceVisibility.visibility_public,
54
+ ]) {
55
+ it(`${declaration.type} at ${ApiResourceVisibility[visibility]}: the same parent links and visibility shapes`, () => {
56
+ const row = fixtureRow(declaration, {
57
+ id: `${declaration.type}-1`,
58
+ org: declaration.type === "organization" ? "" : "acme",
59
+ visibility,
60
+ createdBy: CREATOR.identityId,
61
+ });
62
+ const facts = rowFactsOf(declaration.kind, row);
63
+ const event = resolveResourceCreatedEvent(
64
+ declaration.kind,
65
+ row,
66
+ CREATOR,
67
+ silentLogger,
68
+ );
69
+ expect(facts.parentLinks).toEqual(event?.parentLinks ?? []);
70
+ expect([
71
+ ...visibilityShapesFor(declaration.kind, facts.visibility),
72
+ ]).toEqual(event?.visibilityShapes ?? []);
73
+ expect(facts.createdBy).toBe(CREATOR.identityId);
74
+ expect(facts.id).toBe(`${declaration.type}-1`);
75
+ });
76
+ }
77
+ }
78
+
79
+ it("carries a legacy row's missing organization as no scope link, where the create-time resolver throws", () => {
80
+ const agent = builtInModel.byType("agent");
81
+ if (agent === undefined) {
82
+ throw new Error("agent is declared in this slice");
83
+ }
84
+ const row = fixtureRow(agent, {
85
+ id: "agent-legacy",
86
+ org: "",
87
+ visibility: ApiResourceVisibility.visibility_org,
88
+ createdBy: "ida_carol",
89
+ });
90
+ expect(rowFactsOf(agent.kind, row).parentLinks).toEqual([]);
91
+ expect(() =>
92
+ resolveResourceCreatedEvent(agent.kind, row, CREATOR, silentLogger),
93
+ ).toThrow();
94
+ });
95
+
96
+ it("reads an absent creator stamp as the empty string", () => {
97
+ const agent = builtInModel.byType("agent");
98
+ if (agent === undefined) {
99
+ throw new Error("agent is declared in this slice");
100
+ }
101
+ const bare = create(agent.schema, {
102
+ metadata: { id: "agent-bare", org: "acme" },
103
+ });
104
+ expect(rowFactsOf(agent.kind, bare).createdBy).toBe("");
105
+ });
106
+ });
107
+
108
+ describe("a list candidate against the loaded row — the facts' two producers", () => {
109
+ /** What the list lanes' helper offers a scope for `rows`, captured. */
110
+ async function candidatesOf(
111
+ kind: (typeof builtInModel.declarations)[number]["kind"],
112
+ rows: ReadonlyArray<object>,
113
+ ): Promise<ReadonlyArray<ListEntryMeta>> {
114
+ let offered: ReadonlyArray<ListEntryMeta> = [];
115
+ const recording: ListReadScope = {
116
+ authorizedResourceIds: () => Promise.resolve(new Set<string>()),
117
+ restrictListEntries: (_caller, _kind, entries) => {
118
+ offered = entries;
119
+ return Promise.resolve(new Set<string>());
120
+ },
121
+ };
122
+ await restrictListByReadScope(
123
+ recording,
124
+ CREATOR,
125
+ kind,
126
+ rows as Array<{ metadata?: { id?: string } }>,
127
+ "",
128
+ );
129
+ return offered;
130
+ }
131
+
132
+ for (const declaration of builtInModel.declarations) {
133
+ for (const visibility of [
134
+ ApiResourceVisibility.visibility_private,
135
+ ApiResourceVisibility.visibility_org,
136
+ ApiResourceVisibility.visibility_public,
137
+ ]) {
138
+ it(`${declaration.type} at ${ApiResourceVisibility[visibility]}: the candidate the helper builds carries the facts the driver derives from`, async () => {
139
+ const row = fixtureRow(declaration, {
140
+ id: `${declaration.type}-1`,
141
+ org: declaration.type === "organization" ? "" : "acme",
142
+ visibility,
143
+ createdBy: CREATOR.identityId,
144
+ });
145
+ const [candidate] = await candidatesOf(declaration.kind, [row]);
146
+ if (candidate === undefined) {
147
+ throw new Error("the helper offers every row it is given");
148
+ }
149
+ expect(rowFactsOfEntry(declaration.kind, candidate)).toEqual(
150
+ rowFactsOf(declaration.kind, row),
151
+ );
152
+ });
153
+ }
154
+ }
155
+ });
@@ -0,0 +1,112 @@
1
+ # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/agent-channel-owner.fga.yaml
2
+ # at commit b87dd1170 (the OpenFGA store test the cloud runs against its live model).
3
+ # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
+ # file against this evaluator at the re-pin, so a stale copy is caught there.
5
+ # Agent channels are owner-scoped connection config (channel-integrations
6
+ # decision 001, cloned from the agent_share model): the creator owns the
7
+ # channel; view/edit/delete/install require ownership or an explicit grant.
8
+ # Plain org members get NO implicit access, and — critically — no
9
+ # workspace-visitor tuples exist at all: workspace-user admission to the
10
+ # channel runtime is app-level (webhook signature + channel caller identity
11
+ # + per-turn gates), never FGA.
12
+ #
13
+ # Org ADMINS inherit owner (T08, consistent with agents and shares — an
14
+ # admin who can edit the agent can manage its distribution channels). The
15
+ # narrowness these tests pin: owner + admins have control, granted viewers
16
+ # read, plain members have nothing.
17
+ #
18
+ # Run: fga model test --tests agent-channel-owner.fga.yaml
19
+
20
+ name: agent-channel-owner
21
+ model_file: ../model/fga.mod
22
+
23
+ tuples:
24
+ # Org membership for both accounts — proving membership grants nothing.
25
+ - user: identity_account:alice
26
+ relation: member
27
+ object: organization:acme
28
+ - user: identity_account:mallory
29
+ relation: member
30
+ object: organization:acme
31
+
32
+ # Org admin — proving T08 inheritance reaches channels.
33
+ - user: identity_account:ana
34
+ relation: admin
35
+ object: organization:acme
36
+
37
+ # The channel, created by alice (the config-driven create tuples).
38
+ - user: organization:acme
39
+ relation: organization
40
+ object: agent_channel:support-bot-slack
41
+ - user: identity_account:alice
42
+ relation: owner
43
+ object: agent_channel:support-bot-slack
44
+
45
+ # An explicit viewer grant to carol (not even an org member).
46
+ - user: identity_account:carol
47
+ relation: viewer
48
+ object: agent_channel:support-bot-slack
49
+
50
+ tests:
51
+ - name: owner has full control including grant management
52
+ check:
53
+ - user: identity_account:alice
54
+ object: agent_channel:support-bot-slack
55
+ assertions:
56
+ can_view: true
57
+ can_edit: true
58
+ can_delete: true
59
+ can_grant_access: true
60
+ can_view_access: true
61
+
62
+ - name: explicitly granted viewer can read but not mutate
63
+ check:
64
+ - user: identity_account:carol
65
+ object: agent_channel:support-bot-slack
66
+ assertions:
67
+ can_view: true
68
+ can_edit: false
69
+ can_delete: false
70
+ can_grant_access: false
71
+ can_view_access: true
72
+
73
+ - name: fellow org member has no implicit access
74
+ check:
75
+ - user: identity_account:mallory
76
+ object: agent_channel:support-bot-slack
77
+ assertions:
78
+ can_view: false
79
+ can_edit: false
80
+ can_delete: false
81
+ can_grant_access: false
82
+ can_view_access: false
83
+
84
+ - name: org admin inherits channel management (T08)
85
+ check:
86
+ - user: identity_account:ana
87
+ object: agent_channel:support-bot-slack
88
+ assertions:
89
+ can_view: true
90
+ can_edit: true
91
+ can_delete: true
92
+ can_grant_access: true
93
+
94
+ - name: listing channels reflects ownership and grants, not membership
95
+ list_objects:
96
+ - user: identity_account:alice
97
+ type: agent_channel
98
+ assertions:
99
+ can_view:
100
+ - agent_channel:support-bot-slack
101
+ can_edit:
102
+ - agent_channel:support-bot-slack
103
+ - user: identity_account:carol
104
+ type: agent_channel
105
+ assertions:
106
+ can_view:
107
+ - agent_channel:support-bot-slack
108
+ can_edit: []
109
+ - user: identity_account:mallory
110
+ type: agent_channel
111
+ assertions:
112
+ can_view: []