@stigmer/server 3.15.3-dev.20260914121148 → 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 (555) 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 +47 -20
  304. package/dist/extensions/list-read-scope.d.ts.map +1 -1
  305. package/dist/extensions/list-read-scope.js +20 -24
  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/errors.d.ts.map +1 -1
  325. package/dist/pipeline/errors.js.map +1 -1
  326. package/dist/pipeline/steps/authorization-facts.d.ts +12 -0
  327. package/dist/pipeline/steps/authorization-facts.d.ts.map +1 -0
  328. package/dist/pipeline/steps/authorization-facts.js +100 -0
  329. package/dist/pipeline/steps/authorization-facts.js.map +1 -0
  330. package/dist/pipeline/steps/delete.d.ts.map +1 -1
  331. package/dist/pipeline/steps/delete.js +1 -1
  332. package/dist/pipeline/steps/delete.js.map +1 -1
  333. package/dist/pipeline/steps/duplicate.d.ts.map +1 -1
  334. package/dist/pipeline/steps/duplicate.js.map +1 -1
  335. package/dist/pipeline/steps/guard-plugin-managed.d.ts +12 -0
  336. package/dist/pipeline/steps/guard-plugin-managed.d.ts.map +1 -0
  337. package/dist/pipeline/steps/guard-plugin-managed.js +96 -0
  338. package/dist/pipeline/steps/guard-plugin-managed.js.map +1 -0
  339. package/dist/pipeline/steps/guard-reserved-labels.d.ts +16 -2
  340. package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
  341. package/dist/pipeline/steps/guard-reserved-labels.js +11 -7
  342. package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
  343. package/dist/pipeline/steps/helpers.d.ts.map +1 -1
  344. package/dist/pipeline/steps/helpers.js.map +1 -1
  345. package/dist/pipeline/steps/index-search.d.ts.map +1 -1
  346. package/dist/pipeline/steps/index-search.js.map +1 -1
  347. package/dist/pipeline/steps/load-existing.d.ts.map +1 -1
  348. package/dist/pipeline/steps/load-existing.js +1 -1
  349. package/dist/pipeline/steps/load-existing.js.map +1 -1
  350. package/dist/pipeline/steps/references.d.ts +16 -0
  351. package/dist/pipeline/steps/references.d.ts.map +1 -1
  352. package/dist/pipeline/steps/references.js +18 -0
  353. package/dist/pipeline/steps/references.js.map +1 -1
  354. package/dist/pipeline/steps/resolve-artifact-source.d.ts +35 -0
  355. package/dist/pipeline/steps/resolve-artifact-source.d.ts.map +1 -0
  356. package/dist/pipeline/steps/resolve-artifact-source.js +27 -0
  357. package/dist/pipeline/steps/resolve-artifact-source.js.map +1 -0
  358. package/dist/pipeline/steps/server-stamped-reserved-labels.d.ts.map +1 -1
  359. package/dist/pipeline/steps/server-stamped-reserved-labels.js.map +1 -1
  360. package/dist/pipeline/steps/slug.d.ts.map +1 -1
  361. package/dist/pipeline/steps/slug.js.map +1 -1
  362. package/dist/pipeline/steps/validate-visibility.d.ts +9 -0
  363. package/dist/pipeline/steps/validate-visibility.d.ts.map +1 -1
  364. package/dist/pipeline/steps/validate-visibility.js +6 -1
  365. package/dist/pipeline/steps/validate-visibility.js.map +1 -1
  366. package/dist/pipeline/steps/validation.d.ts.map +1 -1
  367. package/dist/pipeline/steps/validation.js.map +1 -1
  368. package/dist/pipeline/steps/version-archive.d.ts +63 -0
  369. package/dist/pipeline/steps/version-archive.d.ts.map +1 -0
  370. package/dist/pipeline/steps/version-archive.js +129 -0
  371. package/dist/pipeline/steps/version-archive.js.map +1 -0
  372. package/dist/pipeline/steps/version-history.d.ts +49 -0
  373. package/dist/pipeline/steps/version-history.d.ts.map +1 -0
  374. package/dist/pipeline/steps/version-history.js +229 -0
  375. package/dist/pipeline/steps/version-history.js.map +1 -0
  376. package/dist/pipeline/steps/visibility-gates.d.ts +8 -0
  377. package/dist/pipeline/steps/visibility-gates.d.ts.map +1 -1
  378. package/dist/pipeline/steps/visibility-gates.js +7 -2
  379. package/dist/pipeline/steps/visibility-gates.js.map +1 -1
  380. package/dist/query/search/registry.d.ts.map +1 -1
  381. package/dist/query/search/registry.js +2 -0
  382. package/dist/query/search/registry.js.map +1 -1
  383. package/dist/temporal/schedule/run-starter.d.ts +1 -1
  384. package/dist/temporal/schedule/run-starter.d.ts.map +1 -1
  385. package/dist/temporal/schedule/run-starter.js +14 -1
  386. package/dist/temporal/schedule/run-starter.js.map +1 -1
  387. package/package.json +5 -4
  388. package/src/archive/__tests__/archive.test.ts +233 -0
  389. package/src/{domain/skill → archive}/__tests__/prefilter.test.ts +1 -1
  390. package/src/archive/content-store.ts +132 -0
  391. package/src/archive/inflate.ts +107 -0
  392. package/src/archive/limits.ts +42 -0
  393. package/src/archive/open.ts +131 -0
  394. package/src/{domain/skill/storage → archive}/prefilter.ts +5 -0
  395. package/src/archive/write.ts +54 -0
  396. package/src/authorization/README.md +124 -0
  397. package/src/authorization/__tests__/authorizer.test.ts +719 -0
  398. package/src/authorization/__tests__/derived-tuples.test.ts +802 -0
  399. package/src/authorization/__tests__/drivers.ts +70 -0
  400. package/src/authorization/__tests__/evaluator.test.ts +359 -0
  401. package/src/authorization/__tests__/facts.test.ts +155 -0
  402. package/src/authorization/__tests__/fixtures/fga/agent-channel-owner.fga.yaml +112 -0
  403. package/src/authorization/__tests__/fixtures/fga/agent-share-owner.fga.yaml +109 -0
  404. package/src/authorization/__tests__/fixtures/fga/artifact-org-and-owner.fga.yaml +128 -0
  405. package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +410 -0
  406. package/src/authorization/__tests__/fixtures/fga/channel-app-owner.fga.yaml +125 -0
  407. package/src/authorization/__tests__/fixtures/fga/channel-participation.fga.yaml +201 -0
  408. package/src/authorization/__tests__/fixtures/fga/channel-session-visibility.fga.yaml +187 -0
  409. package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +98 -0
  410. package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +271 -0
  411. package/src/authorization/__tests__/fixtures/fga/memory-subject-only.fga.yaml +72 -0
  412. package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +328 -0
  413. package/src/authorization/__tests__/fixtures/fga/org-shared-environment.fga.yaml +144 -0
  414. package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +223 -0
  415. package/src/authorization/__tests__/fixtures/fga/provider-standing-viewer.fga.yaml +40 -0
  416. package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +52 -0
  417. package/src/authorization/__tests__/fixtures/fga/reserved-label-writer.fga.yaml +41 -0
  418. package/src/authorization/__tests__/fixtures/fga/schedule-owner.fga.yaml +113 -0
  419. package/src/authorization/__tests__/fixtures/fga/schedule-session-visibility.fga.yaml +214 -0
  420. package/src/authorization/__tests__/fixtures/fga/session-personal-resource.fga.yaml +117 -0
  421. package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +192 -0
  422. package/src/authorization/__tests__/list-read-scope.measure.test.ts +317 -0
  423. package/src/authorization/__tests__/list-read-scope.test.ts +796 -0
  424. package/src/authorization/__tests__/organization-directory.test.ts +236 -0
  425. package/src/authorization/__tests__/person.test.ts +114 -0
  426. package/src/authorization/__tests__/posture.test.ts +25 -0
  427. package/src/authorization/__tests__/schedule-fire-caller.test.ts +134 -0
  428. package/src/authorization/__tests__/store-tests.test.ts +306 -0
  429. package/src/authorization/__tests__/support.ts +101 -0
  430. package/src/authorization/__tests__/tuples.test.ts +62 -0
  431. package/src/authorization/__tests__/wire-permissions.test.ts +154 -0
  432. package/src/authorization/authorizer.ts +208 -0
  433. package/src/authorization/derived-tuples.ts +384 -0
  434. package/src/authorization/evaluator.ts +283 -0
  435. package/src/authorization/facts.ts +47 -0
  436. package/src/authorization/list-read-scope.ts +216 -0
  437. package/src/authorization/model/__tests__/registry.test.ts +317 -0
  438. package/src/authorization/model/agent.ts +64 -0
  439. package/src/authorization/model/agent_channel.ts +49 -0
  440. package/src/authorization/model/agent_execution.ts +33 -0
  441. package/src/authorization/model/agent_instance.ts +66 -0
  442. package/src/authorization/model/agent_share.ts +40 -0
  443. package/src/authorization/model/api_key.ts +28 -0
  444. package/src/authorization/model/artifact.ts +38 -0
  445. package/src/authorization/model/channel_app.ts +39 -0
  446. package/src/authorization/model/default-of.ts +99 -0
  447. package/src/authorization/model/environment.ts +48 -0
  448. package/src/authorization/model/execution_context.ts +20 -0
  449. package/src/authorization/model/iam_policy.ts +42 -0
  450. package/src/authorization/model/identity_account.ts +26 -0
  451. package/src/authorization/model/index.ts +108 -0
  452. package/src/authorization/model/mcp_server.ts +59 -0
  453. package/src/authorization/model/memory.ts +27 -0
  454. package/src/authorization/model/oauth_app.ts +42 -0
  455. package/src/authorization/model/organization.ts +55 -0
  456. package/src/authorization/model/plugin.ts +66 -0
  457. package/src/authorization/model/project.ts +47 -0
  458. package/src/authorization/model/rewrite.ts +213 -0
  459. package/src/authorization/model/schedule.ts +40 -0
  460. package/src/authorization/model/session.ts +50 -0
  461. package/src/authorization/model/skill.ts +60 -0
  462. package/src/authorization/model/workflow.ts +60 -0
  463. package/src/authorization/model/workflow_execution.ts +44 -0
  464. package/src/authorization/model/workflow_instance.ts +122 -0
  465. package/src/authorization/organization-directory.ts +114 -0
  466. package/src/authorization/person.ts +68 -0
  467. package/src/authorization/posture.ts +49 -0
  468. package/src/authorization/schedule-fire-caller.ts +91 -0
  469. package/src/authorization/store-test-kit.ts +454 -0
  470. package/src/authorization/tuples.ts +190 -0
  471. package/src/boot/compose.ts +175 -38
  472. package/src/boot/inprocess.ts +108 -30
  473. package/src/domain/agent/controller.ts +11 -0
  474. package/src/domain/iampolicy/__tests__/membership.test.ts +357 -3
  475. package/src/domain/iampolicy/constants.ts +12 -0
  476. package/src/domain/iampolicy/membership.ts +221 -66
  477. package/src/domain/identityaccount/actor.ts +44 -0
  478. package/src/domain/mcpserver/controller.ts +11 -0
  479. package/src/domain/plugin/__tests__/materialize.test.ts +303 -0
  480. package/src/domain/plugin/__tests__/overlay-parse.test.ts +85 -0
  481. package/src/domain/plugin/__tests__/plugin.test.ts +681 -0
  482. package/src/domain/plugin/__tests__/sanitize.test.ts +174 -0
  483. package/src/domain/plugin/archive.ts +89 -0
  484. package/src/domain/plugin/constants.ts +53 -0
  485. package/src/domain/plugin/controller.ts +913 -0
  486. package/src/domain/plugin/materialize/agent.ts +186 -0
  487. package/src/domain/plugin/materialize/default-agent-instructions.ts +59 -0
  488. package/src/domain/plugin/materialize/identity.ts +67 -0
  489. package/src/domain/plugin/materialize/mcp-servers.ts +175 -0
  490. package/src/domain/plugin/materialize/plan.ts +124 -0
  491. package/src/domain/plugin/materialize/ports.ts +53 -0
  492. package/src/domain/plugin/materialize/skills.ts +68 -0
  493. package/src/domain/plugin/materialize/workflows.ts +51 -0
  494. package/src/domain/plugin/members.ts +180 -0
  495. package/src/domain/plugin/overlay/documents.ts +78 -0
  496. package/src/domain/plugin/overlay/parse.ts +115 -0
  497. package/src/domain/plugin/overlay/sanitize.ts +149 -0
  498. package/src/domain/plugin/push.ts +1062 -0
  499. package/src/domain/plugin/search-extractor.ts +60 -0
  500. package/src/domain/skill/constants.ts +11 -14
  501. package/src/domain/skill/controller.ts +44 -36
  502. package/src/domain/skill/push.ts +61 -156
  503. package/src/domain/skill/search-extractor.ts +3 -1
  504. package/src/domain/skill/storage/artifact-storage.ts +23 -124
  505. package/src/domain/skill/storage/zip-gate.ts +58 -154
  506. package/src/domain/skill/version-resolution.ts +67 -269
  507. package/src/domain/workflow/controller.ts +38 -4
  508. package/src/domain/workflow/registry/data/task-kind-registry.json +1 -0
  509. package/src/extensions/__tests__/built-in-authorization-composed.test.ts +835 -0
  510. package/src/extensions/__tests__/composed-support.ts +32 -1
  511. package/src/extensions/__tests__/extension-composition.test.ts +35 -0
  512. package/src/extensions/__tests__/list-read-scope.test.ts +137 -33
  513. package/src/extensions/__tests__/role-reconciliation-composed.test.ts +209 -0
  514. package/src/extensions/__tests__/tier-truthfulness.test.ts +6 -14
  515. package/src/extensions/authorizer.ts +10 -5
  516. package/src/extensions/drivers.ts +4 -1
  517. package/src/extensions/list-read-scope.ts +67 -45
  518. package/src/extensions/organization-directory.ts +13 -9
  519. package/src/extensions/resource-authorization.ts +34 -0
  520. package/src/extensions/schedule-fire-caller.ts +49 -18
  521. package/src/index.ts +51 -1
  522. package/src/pipeline/__tests__/router-transport.test.ts +1 -3
  523. package/src/pipeline/apiresource-labels.ts +31 -3
  524. package/src/pipeline/errors.ts +5 -5
  525. package/src/pipeline/steps/__tests__/authorize-annotation-completeness.test.ts +1 -20
  526. package/src/pipeline/steps/__tests__/guard-memory-capture.test.ts +3 -9
  527. package/src/pipeline/steps/__tests__/guard-plugin-managed.test.ts +151 -0
  528. package/src/pipeline/steps/__tests__/guard-reserved-labels.test.ts +83 -8
  529. package/src/pipeline/steps/authorization-facts.ts +131 -0
  530. package/src/pipeline/steps/delete.ts +11 -3
  531. package/src/pipeline/steps/duplicate.ts +8 -2
  532. package/src/pipeline/steps/guard-plugin-managed.ts +133 -0
  533. package/src/pipeline/steps/guard-reserved-labels.ts +29 -8
  534. package/src/pipeline/steps/helpers.ts +4 -1
  535. package/src/pipeline/steps/index-search.ts +28 -15
  536. package/src/pipeline/steps/load-existing.ts +12 -3
  537. package/src/pipeline/steps/references.ts +36 -2
  538. package/src/pipeline/steps/resolve-artifact-source.ts +66 -0
  539. package/src/pipeline/steps/server-stamped-reserved-labels.ts +2 -1
  540. package/src/pipeline/steps/slug.ts +7 -2
  541. package/src/pipeline/steps/validate-visibility.ts +9 -2
  542. package/src/pipeline/steps/validation.ts +3 -1
  543. package/src/pipeline/steps/version-archive.ts +225 -0
  544. package/src/pipeline/steps/version-history.ts +362 -0
  545. package/src/pipeline/steps/visibility-gates.ts +12 -9
  546. package/src/query/README.md +1 -1
  547. package/src/query/search/__tests__/criteria.test.ts +6 -7
  548. package/src/query/search/__tests__/query-store.test.ts +9 -2
  549. package/src/query/search/__tests__/registry.test.ts +6 -4
  550. package/src/query/search/registry.ts +6 -1
  551. package/src/temporal/schedule/__tests__/run-starter.test.ts +86 -24
  552. package/src/temporal/schedule/run-starter.ts +31 -8
  553. package/dist/domain/skill/storage/prefilter.d.ts.map +0 -1
  554. package/dist/domain/skill/storage/prefilter.js.map +0 -1
  555. /package/dist/{domain/skill/storage → archive}/prefilter.js +0 -0
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Pins the plugin-managed write guard's two-fact decision: a stored
3
+ * resource labelled with an EXISTING plugin's id refuses a client write
4
+ * with FAILED_PRECONDITION naming the plugin; a label whose plugin is gone
5
+ * locks nothing; an unlabelled resource passes; in-process and internal
6
+ * callers pass by structure; the request's own labels are never consulted;
7
+ * and the step reads the context key the chain names.
8
+ */
9
+ import { describe, expect, it } from "vitest";
10
+ import { Code, ConnectError } from "@connectrpc/connect";
11
+ import { create } from "@bufbuild/protobuf";
12
+
13
+ import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
14
+ import { PluginSchema } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/api_pb";
15
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
16
+
17
+ import type { CallerIdentity } from "../../../extensions/identity.js";
18
+ import { PLUGIN_LABEL } from "../../apiresource-labels.js";
19
+ import { RequestContext } from "../../request-context.js";
20
+ import { ResourceNotFoundError } from "../../../store/interface.js";
21
+ import type { Store } from "../../../store/interface.js";
22
+ import { newGuardPluginManagedStep } from "../guard-plugin-managed.js";
23
+ import { EXISTING_RESOURCE_KEY } from "../load-existing.js";
24
+
25
+ const USER: CallerIdentity = {
26
+ identityId: "ida_alice",
27
+ callerClass: "user",
28
+ issuer: "stigmer",
29
+ rawToken: "tok",
30
+ };
31
+ const IN_PROCESS: CallerIdentity = { ...USER, origin: "in-process" };
32
+ const INTERNAL: CallerIdentity = { ...USER, callerClass: "internal" };
33
+
34
+ /** A store that knows one plugin row; everything else is not found. */
35
+ function storeWith(pluginId: string | undefined): Store {
36
+ return {
37
+ getResource: (kind: ApiResourceKind, id: string) => {
38
+ if (kind === ApiResourceKind.plugin && id === pluginId) {
39
+ return Promise.resolve(
40
+ create(PluginSchema, { metadata: { id, slug: "thermos" } }),
41
+ );
42
+ }
43
+ return Promise.reject(
44
+ new ResourceNotFoundError(`${ApiResourceKind[kind]}/${id}`),
45
+ );
46
+ },
47
+ } as unknown as Store;
48
+ }
49
+
50
+ function ctxWithStored(
51
+ labels: Record<string, string>,
52
+ caller: CallerIdentity,
53
+ key = EXISTING_RESOURCE_KEY,
54
+ ) {
55
+ const ctx = new RequestContext(
56
+ AgentSchema,
57
+ // The REQUEST carries no plugin label: the guard must not read it.
58
+ create(AgentSchema, { metadata: { name: "reviewer", labels: {} } }),
59
+ caller,
60
+ ApiResourceKind.agent,
61
+ );
62
+ ctx.set(
63
+ key,
64
+ create(AgentSchema, {
65
+ metadata: { name: "reviewer", slug: "reviewer", labels },
66
+ }),
67
+ );
68
+ return ctx;
69
+ }
70
+
71
+ async function outcome(
72
+ promise: Promise<void> | void,
73
+ ): Promise<ConnectError | undefined> {
74
+ try {
75
+ await promise;
76
+ return undefined;
77
+ } catch (error) {
78
+ return error as ConnectError;
79
+ }
80
+ }
81
+
82
+ describe("GuardPluginManaged", () => {
83
+ it("refuses a client write to a member whose plugin exists, naming the plugin", async () => {
84
+ const step = newGuardPluginManagedStep<typeof AgentSchema>(
85
+ storeWith("plg_1"),
86
+ );
87
+ const error = await outcome(
88
+ step.execute(ctxWithStored({ [PLUGIN_LABEL]: "plg_1" }, USER)),
89
+ );
90
+ expect(error).toBeInstanceOf(ConnectError);
91
+ expect(error?.code).toBe(Code.FailedPrecondition);
92
+ expect(error?.rawMessage).toBe(
93
+ "agent 'reviewer' is managed by plugin 'thermos'; change the plugin and push it again, or compose your own agent over it",
94
+ );
95
+ });
96
+
97
+ it("locks nothing when the labelled plugin is gone", async () => {
98
+ const step = newGuardPluginManagedStep<typeof AgentSchema>(
99
+ storeWith(undefined),
100
+ );
101
+ expect(
102
+ await outcome(
103
+ step.execute(ctxWithStored({ [PLUGIN_LABEL]: "plg_gone" }, USER)),
104
+ ),
105
+ ).toBeUndefined();
106
+ });
107
+
108
+ it("passes an unlabelled resource without touching the store", async () => {
109
+ const step = newGuardPluginManagedStep<typeof AgentSchema>({
110
+ getResource: () => Promise.reject(new Error("must not be called")),
111
+ } as unknown as Store);
112
+ expect(
113
+ await outcome(step.execute(ctxWithStored({ team: "x" }, USER))),
114
+ ).toBeUndefined();
115
+ });
116
+
117
+ it("passes in-process and internal callers by structure", async () => {
118
+ const step = newGuardPluginManagedStep<typeof AgentSchema>(
119
+ storeWith("plg_1"),
120
+ );
121
+ expect(
122
+ await outcome(
123
+ step.execute(ctxWithStored({ [PLUGIN_LABEL]: "plg_1" }, IN_PROCESS)),
124
+ ),
125
+ ).toBeUndefined();
126
+ expect(
127
+ await outcome(
128
+ step.execute(ctxWithStored({ [PLUGIN_LABEL]: "plg_1" }, INTERNAL)),
129
+ ),
130
+ ).toBeUndefined();
131
+ });
132
+
133
+ it("reads the stored resource from the key the chain names", async () => {
134
+ const step = newGuardPluginManagedStep<typeof AgentSchema>(
135
+ storeWith("plg_1"),
136
+ { existingKey: "customKey" },
137
+ );
138
+ const error = await outcome(
139
+ step.execute(
140
+ ctxWithStored({ [PLUGIN_LABEL]: "plg_1" }, USER, "customKey"),
141
+ ),
142
+ );
143
+ expect(error?.code).toBe(Code.FailedPrecondition);
144
+ // Under the default key nothing is loaded, so nothing is refused.
145
+ expect(
146
+ await outcome(
147
+ step.execute(ctxWithStored({ [PLUGIN_LABEL]: "plg_1" }, USER)),
148
+ ),
149
+ ).toBeUndefined();
150
+ });
151
+ });
@@ -11,7 +11,9 @@ import { describe, expect, it } from "vitest";
11
11
  import { Code, ConnectError } from "@connectrpc/connect";
12
12
  import { create } from "@bufbuild/protobuf";
13
13
 
14
+ import type { Message } from "@bufbuild/protobuf";
14
15
  import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
16
+ import { PushSkillRequestSchema } from "@stigmer/protos/ai/stigmer/agentic/skill/v1/io_pb";
15
17
  import { EnvironmentSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
16
18
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
17
19
  import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
@@ -74,6 +76,75 @@ describe("reservedLabelMutations", () => {
74
76
  });
75
77
  });
76
78
 
79
+ describe("GuardReservedLabels on a push-shaped chain (named positions)", () => {
80
+ // Skill push builds its resource from an artifact and rides SKILL_KEY /
81
+ // EXISTING_SKILL_KEY rather than newState / EXISTING_RESOURCE_KEY; the
82
+ // positions parameter points the guard at them. Pins that a reserved
83
+ // introduction on the BUILT resource is judged (the request itself has
84
+ // no metadata), that a stored echo under the named existing key passes,
85
+ // and that the in-process origin passes by structure.
86
+ const BUILT_KEY = "builtResource";
87
+ const STORED_KEY = "storedResource";
88
+ function pushCtx(
89
+ labels: Record<string, string>,
90
+ stored?: Record<string, string>,
91
+ caller: CallerIdentity = USER,
92
+ ) {
93
+ const ctx = new RequestContext(
94
+ PushSkillRequestSchema,
95
+ create(PushSkillRequestSchema, {
96
+ org: "acme",
97
+ artifact: new Uint8Array(1),
98
+ labels,
99
+ }),
100
+ caller,
101
+ ApiResourceKind.skill,
102
+ );
103
+ ctx.set(
104
+ BUILT_KEY,
105
+ create(AgentSchema, { metadata: { name: "s", labels } }),
106
+ );
107
+ if (stored !== undefined) {
108
+ ctx.set(
109
+ STORED_KEY,
110
+ create(AgentSchema, { metadata: { name: "s", labels: stored } }),
111
+ );
112
+ }
113
+ return ctx;
114
+ }
115
+ const positioned = (authorizer: Authorizer) =>
116
+ newGuardReservedLabelsStep<typeof PushSkillRequestSchema>(authorizer, {
117
+ stateOf: (ctx) => ctx.get(BUILT_KEY) as Message,
118
+ existingKey: STORED_KEY,
119
+ });
120
+
121
+ it("rejects a reserved introduction read from the named state", async () => {
122
+ const error = await positioned(denying())
123
+ .execute(pushCtx({ "stigmer.ai/plugin": "plg_1" }))
124
+ ?.catch((e: unknown) => e);
125
+ expect(error).toBeInstanceOf(ConnectError);
126
+ expect((error as ConnectError).code).toBe(Code.InvalidArgument);
127
+ });
128
+
129
+ it("passes an echo of the label stored under the named existing key", async () => {
130
+ await positioned(denying()).execute(
131
+ pushCtx(
132
+ { "stigmer.ai/plugin": "plg_1" },
133
+ { "stigmer.ai/plugin": "plg_1" },
134
+ ),
135
+ );
136
+ });
137
+
138
+ it("passes the in-process origin by structure", async () => {
139
+ await positioned(denying()).execute(
140
+ pushCtx({ "stigmer.ai/plugin": "plg_1" }, undefined, {
141
+ ...USER,
142
+ origin: "in-process",
143
+ }),
144
+ );
145
+ });
146
+ });
147
+
77
148
  describe("GuardReservedLabels", () => {
78
149
  it("rejects an introduction with the byte-pinned copy when denied", async () => {
79
150
  const step = newGuardReservedLabelsStep<typeof AgentSchema>(denying());
@@ -133,9 +204,8 @@ describe("GuardReservedLabels", () => {
133
204
  });
134
205
 
135
206
  it("the Environment personal-label client contract passes", async () => {
136
- const step = newGuardReservedLabelsStep<typeof EnvironmentSchema>(
137
- denying(),
138
- );
207
+ const step =
208
+ newGuardReservedLabelsStep<typeof EnvironmentSchema>(denying());
139
209
  const ctx = new RequestContext(
140
210
  EnvironmentSchema,
141
211
  create(EnvironmentSchema, {
@@ -151,7 +221,12 @@ describe("GuardReservedLabels", () => {
151
221
  const step = newGuardReservedLabelsStep<typeof AgentSchema>(denying());
152
222
  const ctx = agentCtx(
153
223
  { "stigmer.ai/default-instance": "true" },
154
- { identityId: "internal", callerClass: "internal", issuer: "", rawToken: "" },
224
+ {
225
+ identityId: "internal",
226
+ callerClass: "internal",
227
+ issuer: "",
228
+ rawToken: "",
229
+ },
155
230
  );
156
231
  await expect(Promise.resolve(step.execute(ctx))).resolves.toBeUndefined();
157
232
  });
@@ -166,7 +241,9 @@ describe("GuardReservedLabels", () => {
166
241
  vouched,
167
242
  "stigmer.ai/workflow-execution-id",
168
243
  );
169
- await expect(Promise.resolve(step.execute(vouched))).resolves.toBeUndefined();
244
+ await expect(
245
+ Promise.resolve(step.execute(vouched)),
246
+ ).resolves.toBeUndefined();
170
247
 
171
248
  const smuggled = agentCtx({
172
249
  "stigmer.ai/workflow-execution-id": "wfe_1",
@@ -176,9 +253,7 @@ describe("GuardReservedLabels", () => {
176
253
  smuggled,
177
254
  "stigmer.ai/workflow-execution-id",
178
255
  );
179
- const error = await step
180
- .execute(smuggled)
181
- ?.catch((e: unknown) => e);
256
+ const error = await step.execute(smuggled)?.catch((e: unknown) => e);
182
257
  expect(error).toBeInstanceOf(ConnectError);
183
258
  expect((error as ConnectError).rawMessage).toContain(
184
259
  "stigmer.ai/default-agent",
@@ -0,0 +1,131 @@
1
+ /**
2
+ * The facts a stored row's authorization tuples derive from, read back
3
+ * from the row (`RowAuthorizationFacts`, extensions/resource-authorization.ts)
4
+ * — the read-time twin of the tuple lifecycle's create-time resolution in
5
+ * authorization-tuples.ts, and deliberately not that function: the
6
+ * create-time one throws when a row is missing its organization or its
7
+ * parent (a create must not half-succeed), while a row read back years
8
+ * later is a fact, missing pieces included — an empty organization
9
+ * resolves `admin from organization` to nobody, it does not fault a read.
10
+ * The two cannot drift unnoticed: src/authorization/__tests__/facts.test.ts
11
+ * pins that a well-formed row resolves to the same links through both.
12
+ *
13
+ * Two readers share this one resolver, which is the reason it is a leaf
14
+ * of its own: the list lanes' shared helper (extensions/list-read-scope.ts)
15
+ * builds every candidate's `ListEntryMeta` through it, and the built-in
16
+ * authorizer (src/authorization/facts.ts) derives a loaded row's tuples
17
+ * through it. It imports the two pure leaves it needs (apiresource-meta,
18
+ * shapes) and the protos, and nothing else, so the seam may import it by
19
+ * value without a cycle — the third such leaf, beside those two.
20
+ *
21
+ * Every read is structural (shapes.ts's own premise: protobuf-es messages
22
+ * are plain objects sharing the generated metadata and audit types), so
23
+ * the resolver needs no schema — a list lane holds decoded rows of a kind
24
+ * it names, not their descriptors.
25
+ */
26
+ import { AuthorizationScopeType } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/authorization_config_pb";
27
+ import type { ParentRelationConfig } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/authorization_config_pb";
28
+ import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
29
+ import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
30
+ import type { ApiResourceAudit } from "@stigmer/protos/ai/stigmer/commons/apiresource/status_pb";
31
+
32
+ import type {
33
+ ResolvedParentLink,
34
+ RowAuthorizationFacts,
35
+ } from "../../extensions/resource-authorization.js";
36
+ import { getKindEnum, getKindMeta } from "../apiresource-meta.js";
37
+ import { parentIdOf } from "./shapes.js";
38
+ import type { HasMetadataShape } from "./shapes.js";
39
+
40
+ /** The one path every stored API resource keeps its audit under. */
41
+ interface HasAuditShape {
42
+ status?: { audit?: ApiResourceAudit };
43
+ }
44
+
45
+ /** The row's facts, read structurally; every absence is the empty value, never a throw. */
46
+ export function rowAuthorizationFactsOf(
47
+ kind: ApiResourceKind,
48
+ resource: object,
49
+ ): RowAuthorizationFacts {
50
+ const metadata = (resource as HasMetadataShape).metadata;
51
+ const org = metadata?.org ?? "";
52
+ return {
53
+ id: metadata?.id ?? "",
54
+ org,
55
+ visibility:
56
+ metadata?.visibility ??
57
+ ApiResourceVisibility.api_resource_visibility_unspecified,
58
+ createdBy: createdByOf(resource),
59
+ parentLinks: parentLinksOf(kind, resource, org),
60
+ };
61
+ }
62
+
63
+ /** `status.audit.spec_audit.created_by.id` as stamped — "" when any link is absent. */
64
+ export function createdByOf(resource: object): string {
65
+ return (
66
+ (resource as HasAuditShape).status?.audit?.specAudit?.createdBy?.id ?? ""
67
+ );
68
+ }
69
+
70
+ /**
71
+ * The scope link and every configured additional parent the row names, in
72
+ * the tuple lifecycle's order. A parent the row does not name is left out.
73
+ */
74
+ export function parentLinksOf(
75
+ kind: ApiResourceKind,
76
+ resource: object,
77
+ org: string,
78
+ ): ReadonlyArray<ResolvedParentLink> {
79
+ const config = getKindMeta(kind).authorization;
80
+ if (config === undefined) {
81
+ return [];
82
+ }
83
+ const links: ResolvedParentLink[] = [];
84
+ switch (config.scopeType) {
85
+ case AuthorizationScopeType.ORGANIZATION:
86
+ if (org !== "") {
87
+ links.push({
88
+ relation: "organization",
89
+ parentKind: getKindEnum("organization"),
90
+ parentId: org,
91
+ });
92
+ }
93
+ break;
94
+ case AuthorizationScopeType.PARENT:
95
+ if (config.parent !== undefined) {
96
+ pushLink(links, resource, config.parent);
97
+ }
98
+ break;
99
+ case AuthorizationScopeType.OWNER_ONLY:
100
+ case AuthorizationScopeType.PLATFORM:
101
+ case AuthorizationScopeType.NONE:
102
+ case AuthorizationScopeType.UNSPECIFIED:
103
+ // No scope link: OWNER_ONLY by design; PLATFORM is dead config in
104
+ // both editions (the lifecycle warns and writes none); NONE and
105
+ // UNSPECIFIED are kinds outside the model.
106
+ break;
107
+ default: {
108
+ const exhaustive: never = config.scopeType;
109
+ throw new Error(`unknown scope type: ${String(exhaustive)}`);
110
+ }
111
+ }
112
+ for (const parent of config.additionalParents) {
113
+ pushLink(links, resource, parent);
114
+ }
115
+ return links;
116
+ }
117
+
118
+ function pushLink(
119
+ links: ResolvedParentLink[],
120
+ resource: object,
121
+ parent: ParentRelationConfig,
122
+ ): void {
123
+ const parentId = parentIdOf(resource, parent.specField);
124
+ if (parentId !== "") {
125
+ links.push({
126
+ relation: parent.relation,
127
+ parentKind: getKindEnum(parent.kind),
128
+ parentId,
129
+ });
130
+ }
131
+ }
@@ -15,7 +15,11 @@ import type { DescMessage, MessageShape } from "@bufbuild/protobuf";
15
15
  import { ResourceNotFoundError } from "../../store/interface.js";
16
16
  import type { Store } from "../../store/interface.js";
17
17
  import { getKindName } from "../apiresource-meta.js";
18
- import { internalError, invalidArgumentError, notFoundError } from "../errors.js";
18
+ import {
19
+ internalError,
20
+ invalidArgumentError,
21
+ notFoundError,
22
+ } from "../errors.js";
19
23
  import type { PipelineStep } from "../pipeline.js";
20
24
  import type { RequestContext } from "../request-context.js";
21
25
  import { EXISTING_RESOURCE_KEY } from "./load-existing.js";
@@ -24,7 +28,9 @@ import { idValueOf } from "./shapes.js";
24
28
  /** Context key for the extracted id (Go ResourceIdKey). */
25
29
  export const RESOURCE_ID_KEY = "resourceId";
26
30
 
27
- export function newExtractResourceIdStep<Desc extends DescMessage>(): PipelineStep<Desc> {
31
+ export function newExtractResourceIdStep<
32
+ Desc extends DescMessage,
33
+ >(): PipelineStep<Desc> {
28
34
  return {
29
35
  name: "ExtractResourceId",
30
36
  execute(ctx: RequestContext<Desc>): void {
@@ -90,7 +96,9 @@ function requireResourceId<Desc extends DescMessage>(
90
96
  const id = ctx.get(RESOURCE_ID_KEY);
91
97
  if (typeof id !== "string" || id === "") {
92
98
  throw internalError(
93
- new Error("resource id not found in context (ExtractResourceId must run first)"),
99
+ new Error(
100
+ "resource id not found in context (ExtractResourceId must run first)",
101
+ ),
94
102
  "delete pipeline ordering",
95
103
  );
96
104
  }
@@ -24,10 +24,16 @@ export function newCheckDuplicateStep<Desc extends DescMessage>(
24
24
  const metadata = metadataOf(ctx.newState);
25
25
  if (metadata === undefined) {
26
26
  // Established by earlier steps — a server-side programming error.
27
- throw internalError(new Error("resource metadata is nil"), "duplicate check");
27
+ throw internalError(
28
+ new Error("resource metadata is nil"),
29
+ "duplicate check",
30
+ );
28
31
  }
29
32
  if (metadata.slug === "") {
30
- throw internalError(new Error("resource slug is empty"), "duplicate check");
33
+ throw internalError(
34
+ new Error("resource slug is empty"),
35
+ "duplicate check",
36
+ );
31
37
  }
32
38
 
33
39
  let existing;
@@ -0,0 +1,133 @@
1
+ /**
2
+ * GuardPluginManaged — the write boundary for resources a plugin
3
+ * materialised. A plugin's skills, MCP servers, agent and workflows are
4
+ * ordinary resources in the organization, labelled `stigmer.ai/plugin:
5
+ * <plugin id>` by the controller that installed them; the plugin owns
6
+ * their definition, so a client edit would be silently overwritten by the
7
+ * next upgrade and a client delete would leave the plugin claiming a
8
+ * member it no longer has. Customisation is composition: the user writes
9
+ * their own agent over the plugin's skills and servers, which stay readable
10
+ * and usable by everyone the visibility admits.
11
+ *
12
+ * Two facts decide, together (the apiresource-labels.ts doctrine: a label
13
+ * restricts only beside server-owned state):
14
+ * - the STORED resource carries the plugin label — the request's labels
15
+ * are never consulted, so a client cannot detach a child by omitting
16
+ * the label on an update;
17
+ * - AND the plugin row it names exists. A label whose plugin is gone (a
18
+ * cascade that failed part-way; a label a self-hosted operator stamped
19
+ * by hand under the permissive authorizer) leaves the resource editable
20
+ * and deletable, so nothing can be locked forever.
21
+ *
22
+ * Server-composed writes pass by structure: the plugin controller is the
23
+ * one writer of these resources and rides the in-process lane as the
24
+ * installing caller (`origin: "in-process"`), exactly the arm
25
+ * GuardReservedLabels passes. Operational RPCs (connect, OAuth flows,
26
+ * instances, sessions, executions) never splice this step: they read or
27
+ * enrich a server, they do not redefine it.
28
+ *
29
+ * Placement: after the chain's load of the stored resource (LoadExisting,
30
+ * LoadExistingForDelete, a kind's visibility loader, skill push's
31
+ * FindExistingBySlug), before any state is built or persisted. The
32
+ * refusal is FAILED_PRECONDITION with the plugin named, so the user knows
33
+ * which door to use instead.
34
+ *
35
+ * Proven by __tests__/guard-plugin-managed.test.ts and the plugin
36
+ * conformance suite's managed-child arms.
37
+ */
38
+ import { Code, ConnectError } from "@connectrpc/connect";
39
+ import type { DescMessage, Message } from "@bufbuild/protobuf";
40
+
41
+ import { PluginSchema } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/api_pb";
42
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
43
+
44
+ import { pluginIdOf } from "../apiresource-labels.js";
45
+ import { internalError } from "../errors.js";
46
+ import type { PipelineStep } from "../pipeline.js";
47
+ import type { RequestContext } from "../request-context.js";
48
+ import { ResourceNotFoundError } from "../../store/interface.js";
49
+ import type { Store } from "../../store/interface.js";
50
+ import { EXISTING_RESOURCE_KEY } from "./load-existing.js";
51
+ import { metadataOf } from "./shapes.js";
52
+
53
+ /** The kinds a plugin materialises; the noun opens the refusal sentence. */
54
+ const MANAGED_KIND_NOUNS: ReadonlyMap<ApiResourceKind, string> = new Map([
55
+ [ApiResourceKind.skill, "skill"],
56
+ [ApiResourceKind.mcp_server, "MCP server"],
57
+ [ApiResourceKind.agent, "agent"],
58
+ [ApiResourceKind.workflow, "workflow"],
59
+ ]);
60
+
61
+ /** The one sentence a refused mutation carries; the CLI and console render it as is. */
62
+ export function pluginManagedRefusal(
63
+ kind: ApiResourceKind,
64
+ slug: string,
65
+ pluginSlug: string,
66
+ ): string {
67
+ const noun =
68
+ MANAGED_KIND_NOUNS.get(kind) ?? ApiResourceKind[kind] ?? String(kind);
69
+ return (
70
+ `${noun} '${slug}' is managed by plugin '${pluginSlug}'; change the plugin and ` +
71
+ "push it again, or compose your own agent over it"
72
+ );
73
+ }
74
+
75
+ export interface GuardPluginManagedPositions {
76
+ /** The context key the stored resource rides; defaults to EXISTING_RESOURCE_KEY. */
77
+ readonly existingKey?: string;
78
+ }
79
+
80
+ export function newGuardPluginManagedStep<Desc extends DescMessage>(
81
+ store: Store,
82
+ positions: GuardPluginManagedPositions = {},
83
+ ): PipelineStep<Desc> {
84
+ const existingKey = positions.existingKey ?? EXISTING_RESOURCE_KEY;
85
+ return {
86
+ name: "GuardPluginManaged",
87
+ async execute(ctx: RequestContext<Desc>): Promise<void> {
88
+ if (
89
+ ctx.callerIdentity.callerClass === "internal" ||
90
+ ctx.callerIdentity.origin === "in-process"
91
+ ) {
92
+ // The plugin controller's own materialisation, upgrade and cascade
93
+ // writes; the same structural pass GuardReservedLabels takes.
94
+ return;
95
+ }
96
+ const existing = ctx.get(existingKey);
97
+ if (existing === undefined) {
98
+ return;
99
+ }
100
+ const metadata = metadataOf(existing as Message);
101
+ const pluginId = pluginIdOf(metadata);
102
+ if (pluginId === undefined) {
103
+ return;
104
+ }
105
+
106
+ let pluginSlug: string;
107
+ try {
108
+ const plugin = await store.getResource(
109
+ ApiResourceKind.plugin,
110
+ pluginId,
111
+ PluginSchema,
112
+ );
113
+ pluginSlug = plugin.metadata?.slug ?? pluginId;
114
+ } catch (error) {
115
+ if (error instanceof ResourceNotFoundError) {
116
+ // A dangling label locks nothing: the plugin that would own this
117
+ // resource is gone, so the resource is the user's again.
118
+ return;
119
+ }
120
+ throw internalError(error, "plugin ownership could not be checked");
121
+ }
122
+
123
+ throw new ConnectError(
124
+ pluginManagedRefusal(
125
+ ctx.apiResourceKind,
126
+ metadata?.slug ?? "",
127
+ pluginSlug,
128
+ ),
129
+ Code.FailedPrecondition,
130
+ );
131
+ },
132
+ };
133
+ }
@@ -40,12 +40,15 @@
40
40
  *
41
41
  * Placement: after BuildNewState/BuildUpdateState — the step inspects the
42
42
  * state that will persist, and update chains have LoadExisting's stored
43
- * labels for echo detection. The infrastructure-failure arm answers a
43
+ * labels for echo detection. A push-shaped chain (skill push, whose
44
+ * PushSkillRequest carries `labels`) places it after its populate step and
45
+ * names its own positions (GuardReservedLabelsPositions), since its
46
+ * resource rides a domain key, not newState. The infrastructure-failure arm answers a
44
47
  * sanitized INTERNAL (the TS store-fault doctrine, #478) where Java
45
48
  * echoes raw exception text — an unpinned outage-lane difference.
46
49
  */
47
50
  import { Code, ConnectError } from "@connectrpc/connect";
48
- import type { DescMessage } from "@bufbuild/protobuf";
51
+ import type { DescMessage, Message } from "@bufbuild/protobuf";
49
52
 
50
53
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
51
54
  import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
@@ -69,9 +72,7 @@ export const RESERVED_LABEL_PREFIX = "stigmer.ai/";
69
72
  const CLIENT_CONTRACT_ALLOWLIST: ReadonlyMap<
70
73
  ApiResourceKind,
71
74
  ReadonlySet<string>
72
- > = new Map([
73
- [ApiResourceKind.environment, new Set(["stigmer.ai/personal"])],
74
- ]);
75
+ > = new Map([[ApiResourceKind.environment, new Set(["stigmer.ai/personal"])]]);
75
76
 
76
77
  /**
77
78
  * The reserved keys `requested` would introduce or change relative to
@@ -91,9 +92,27 @@ export function reservedLabelMutations(
91
92
  return mutations.sort();
92
93
  }
93
94
 
95
+ /**
96
+ * Where the guard finds the state that will persist and the stored state
97
+ * it is judged against. The create and update chains carry both in the
98
+ * shared positions (`ctx.newState`, EXISTING_RESOURCE_KEY); a push-shaped
99
+ * chain builds its resource from an artifact and rides its own keys, so
100
+ * it names them here. Defaults are the shared positions.
101
+ */
102
+ export interface GuardReservedLabelsPositions<Desc extends DescMessage> {
103
+ /** The resource about to persist; defaults to the chain's newState. */
104
+ readonly stateOf?: (ctx: RequestContext<Desc>) => Message | undefined;
105
+ /** The context key the stored resource rides; defaults to EXISTING_RESOURCE_KEY. */
106
+ readonly existingKey?: string;
107
+ }
108
+
94
109
  export function newGuardReservedLabelsStep<Desc extends DescMessage>(
95
110
  authorizer: Authorizer,
111
+ positions: GuardReservedLabelsPositions<Desc> = {},
96
112
  ): PipelineStep<Desc> {
113
+ const stateOf =
114
+ positions.stateOf ?? ((ctx: RequestContext<Desc>) => ctx.newState);
115
+ const existingKey = positions.existingKey ?? EXISTING_RESOURCE_KEY;
97
116
  return {
98
117
  name: "GuardReservedLabels",
99
118
  async execute(ctx: RequestContext<Desc>): Promise<void> {
@@ -108,12 +127,14 @@ export function newGuardReservedLabelsStep<Desc extends DescMessage>(
108
127
  // identity for attribution (ruling R5).
109
128
  return;
110
129
  }
111
- const requested = metadataOf(ctx.newState)?.labels ?? {};
112
- const existing = ctx.get(EXISTING_RESOURCE_KEY);
130
+ const state = stateOf(ctx);
131
+ const requested =
132
+ state === undefined ? {} : (metadataOf(state)?.labels ?? {});
133
+ const existing = ctx.get(existingKey);
113
134
  const stored =
114
135
  existing === undefined
115
136
  ? {}
116
- : (metadataOf(existing as typeof ctx.newState)?.labels ?? {});
137
+ : (metadataOf(existing as Message)?.labels ?? {});
117
138
 
118
139
  const allowlist =
119
140
  CLIENT_CONTRACT_ALLOWLIST.get(ctx.apiResourceKind) ?? new Set();