@stigmer/server 3.40.0 → 3.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. package/dist/authorization/authorizer.d.ts +16 -10
  2. package/dist/authorization/authorizer.d.ts.map +1 -1
  3. package/dist/authorization/authorizer.js +17 -9
  4. package/dist/authorization/authorizer.js.map +1 -1
  5. package/dist/authorization/derived-tuples.d.ts +7 -3
  6. package/dist/authorization/derived-tuples.d.ts.map +1 -1
  7. package/dist/authorization/derived-tuples.js +62 -6
  8. package/dist/authorization/derived-tuples.js.map +1 -1
  9. package/dist/authorization/evaluator.d.ts +11 -7
  10. package/dist/authorization/evaluator.d.ts.map +1 -1
  11. package/dist/authorization/evaluator.js +16 -10
  12. package/dist/authorization/evaluator.js.map +1 -1
  13. package/dist/authorization/list-read-scope.d.ts +4 -0
  14. package/dist/authorization/list-read-scope.d.ts.map +1 -1
  15. package/dist/authorization/list-read-scope.js +1 -0
  16. package/dist/authorization/list-read-scope.js.map +1 -1
  17. package/dist/authorization/model/data/authorization-model.json +830 -67
  18. package/dist/authorization/model/execution-viewer.d.ts.map +1 -1
  19. package/dist/authorization/model/execution-viewer.js +26 -24
  20. package/dist/authorization/model/execution-viewer.js.map +1 -1
  21. package/dist/authorization/model/index.d.ts +4 -1
  22. package/dist/authorization/model/index.d.ts.map +1 -1
  23. package/dist/authorization/model/index.js +4 -1
  24. package/dist/authorization/model/index.js.map +1 -1
  25. package/dist/authorization/model/rewrite.d.ts +5 -3
  26. package/dist/authorization/model/rewrite.d.ts.map +1 -1
  27. package/dist/authorization/organization-directory.d.ts +44 -0
  28. package/dist/authorization/organization-directory.d.ts.map +1 -1
  29. package/dist/authorization/organization-directory.js +1 -0
  30. package/dist/authorization/organization-directory.js.map +1 -1
  31. package/dist/authorization/person.d.ts +14 -1
  32. package/dist/authorization/person.d.ts.map +1 -1
  33. package/dist/authorization/person.js +16 -0
  34. package/dist/authorization/person.js.map +1 -1
  35. package/dist/authorization/policy-check.d.ts +52 -0
  36. package/dist/authorization/policy-check.d.ts.map +1 -0
  37. package/dist/authorization/policy-check.js +35 -0
  38. package/dist/authorization/policy-check.js.map +1 -0
  39. package/dist/authorization/posture.d.ts +30 -4
  40. package/dist/authorization/posture.d.ts.map +1 -1
  41. package/dist/authorization/posture.js +58 -0
  42. package/dist/authorization/posture.js.map +1 -1
  43. package/dist/authorization/resource-creators.d.ts +4 -0
  44. package/dist/authorization/resource-creators.d.ts.map +1 -0
  45. package/dist/authorization/resource-creators.js +44 -0
  46. package/dist/authorization/resource-creators.js.map +1 -0
  47. package/dist/authorization/trusted-local-authorizer.d.ts +9 -0
  48. package/dist/authorization/trusted-local-authorizer.d.ts.map +1 -0
  49. package/dist/authorization/trusted-local-authorizer.js +70 -0
  50. package/dist/authorization/trusted-local-authorizer.js.map +1 -0
  51. package/dist/authorization/tuples.d.ts +12 -0
  52. package/dist/authorization/tuples.d.ts.map +1 -1
  53. package/dist/authorization/tuples.js +3 -0
  54. package/dist/authorization/tuples.js.map +1 -1
  55. package/dist/boot/compose.d.ts.map +1 -1
  56. package/dist/boot/compose.js +133 -43
  57. package/dist/boot/compose.js.map +1 -1
  58. package/dist/boot/config.d.ts +22 -7
  59. package/dist/boot/config.d.ts.map +1 -1
  60. package/dist/boot/config.js +2 -1
  61. package/dist/boot/config.js.map +1 -1
  62. package/dist/boot/inprocess.d.ts.map +1 -1
  63. package/dist/boot/inprocess.js +10 -4
  64. package/dist/boot/inprocess.js.map +1 -1
  65. package/dist/boot/list-indexes.d.ts.map +1 -1
  66. package/dist/boot/list-indexes.js +6 -1
  67. package/dist/boot/list-indexes.js.map +1 -1
  68. package/dist/boot/logger.d.ts +3 -1
  69. package/dist/boot/logger.d.ts.map +1 -1
  70. package/dist/boot/logger.js +3 -1
  71. package/dist/boot/logger.js.map +1 -1
  72. package/dist/boot/oauth-redirect-uri.d.ts +33 -12
  73. package/dist/boot/oauth-redirect-uri.d.ts.map +1 -1
  74. package/dist/boot/oauth-redirect-uri.js +43 -14
  75. package/dist/boot/oauth-redirect-uri.js.map +1 -1
  76. package/dist/boot/skill-transfer-origin.d.ts +46 -14
  77. package/dist/boot/skill-transfer-origin.d.ts.map +1 -1
  78. package/dist/boot/skill-transfer-origin.js +53 -13
  79. package/dist/boot/skill-transfer-origin.js.map +1 -1
  80. package/dist/domain/agentchannel/steps.d.ts +8 -6
  81. package/dist/domain/agentchannel/steps.d.ts.map +1 -1
  82. package/dist/domain/agentchannel/steps.js +9 -7
  83. package/dist/domain/agentchannel/steps.js.map +1 -1
  84. package/dist/domain/agentexecution/controller.d.ts +7 -0
  85. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  86. package/dist/domain/agentexecution/controller.js +1 -1
  87. package/dist/domain/agentexecution/controller.js.map +1 -1
  88. package/dist/domain/agentexecution/create-steps.d.ts +26 -12
  89. package/dist/domain/agentexecution/create-steps.d.ts.map +1 -1
  90. package/dist/domain/agentexecution/create-steps.js +61 -43
  91. package/dist/domain/agentexecution/create-steps.js.map +1 -1
  92. package/dist/domain/agentexecution/submit-approval.d.ts.map +1 -1
  93. package/dist/domain/agentexecution/submit-approval.js +9 -6
  94. package/dist/domain/agentexecution/submit-approval.js.map +1 -1
  95. package/dist/domain/agentexecution/submit-file-decision.d.ts.map +1 -1
  96. package/dist/domain/agentexecution/submit-file-decision.js +5 -4
  97. package/dist/domain/agentexecution/submit-file-decision.js.map +1 -1
  98. package/dist/domain/agentshare/steps.d.ts +5 -3
  99. package/dist/domain/agentshare/steps.d.ts.map +1 -1
  100. package/dist/domain/agentshare/steps.js +6 -4
  101. package/dist/domain/agentshare/steps.js.map +1 -1
  102. package/dist/domain/apikey/verifier.d.ts +7 -0
  103. package/dist/domain/apikey/verifier.d.ts.map +1 -1
  104. package/dist/domain/apikey/verifier.js +34 -1
  105. package/dist/domain/apikey/verifier.js.map +1 -1
  106. package/dist/domain/channelapp/controller.d.ts +9 -4
  107. package/dist/domain/channelapp/controller.d.ts.map +1 -1
  108. package/dist/domain/channelapp/controller.js +19 -9
  109. package/dist/domain/channelapp/controller.js.map +1 -1
  110. package/dist/domain/executioncontext/steps.d.ts +2 -1
  111. package/dist/domain/executioncontext/steps.d.ts.map +1 -1
  112. package/dist/domain/executioncontext/steps.js +2 -1
  113. package/dist/domain/executioncontext/steps.js.map +1 -1
  114. package/dist/domain/iampolicy/access-lists.d.ts.map +1 -1
  115. package/dist/domain/iampolicy/access-lists.js +57 -2
  116. package/dist/domain/iampolicy/access-lists.js.map +1 -1
  117. package/dist/domain/iampolicy/change.d.ts +53 -0
  118. package/dist/domain/iampolicy/change.d.ts.map +1 -0
  119. package/dist/domain/iampolicy/change.js +44 -0
  120. package/dist/domain/iampolicy/change.js.map +1 -0
  121. package/dist/domain/iampolicy/constants.d.ts +6 -0
  122. package/dist/domain/iampolicy/constants.d.ts.map +1 -1
  123. package/dist/domain/iampolicy/constants.js +6 -0
  124. package/dist/domain/iampolicy/constants.js.map +1 -1
  125. package/dist/domain/iampolicy/controller.d.ts.map +1 -1
  126. package/dist/domain/iampolicy/controller.js +9 -5
  127. package/dist/domain/iampolicy/controller.js.map +1 -1
  128. package/dist/domain/iampolicy/grant-path.d.ts +31 -13
  129. package/dist/domain/iampolicy/grant-path.d.ts.map +1 -1
  130. package/dist/domain/iampolicy/grant-path.js +216 -19
  131. package/dist/domain/iampolicy/grant-path.js.map +1 -1
  132. package/dist/domain/iampolicy/membership.d.ts +11 -3
  133. package/dist/domain/iampolicy/membership.d.ts.map +1 -1
  134. package/dist/domain/iampolicy/membership.js +18 -13
  135. package/dist/domain/iampolicy/membership.js.map +1 -1
  136. package/dist/domain/iampolicy/resource-store.d.ts.map +1 -1
  137. package/dist/domain/iampolicy/resource-store.js +4 -0
  138. package/dist/domain/iampolicy/resource-store.js.map +1 -1
  139. package/dist/domain/iampolicy/role-lifecycle.d.ts.map +1 -1
  140. package/dist/domain/iampolicy/role-lifecycle.js +2 -2
  141. package/dist/domain/iampolicy/role-lifecycle.js.map +1 -1
  142. package/dist/domain/iampolicy/roles.d.ts.map +1 -1
  143. package/dist/domain/iampolicy/roles.js +7 -0
  144. package/dist/domain/iampolicy/roles.js.map +1 -1
  145. package/dist/domain/iampolicy/steps.d.ts +4 -3
  146. package/dist/domain/iampolicy/steps.d.ts.map +1 -1
  147. package/dist/domain/iampolicy/steps.js +7 -7
  148. package/dist/domain/iampolicy/steps.js.map +1 -1
  149. package/dist/domain/iampolicy/store-contract.d.ts.map +1 -1
  150. package/dist/domain/iampolicy/store-contract.js +22 -1
  151. package/dist/domain/iampolicy/store-contract.js.map +1 -1
  152. package/dist/domain/iampolicy/store.d.ts +18 -5
  153. package/dist/domain/iampolicy/store.d.ts.map +1 -1
  154. package/dist/domain/iampolicy/store.js.map +1 -1
  155. package/dist/domain/identityaccount/constants.d.ts +15 -0
  156. package/dist/domain/identityaccount/constants.d.ts.map +1 -1
  157. package/dist/domain/identityaccount/constants.js +17 -0
  158. package/dist/domain/identityaccount/constants.js.map +1 -1
  159. package/dist/domain/identityaccount/controller.d.ts.map +1 -1
  160. package/dist/domain/identityaccount/controller.js +17 -6
  161. package/dist/domain/identityaccount/controller.js.map +1 -1
  162. package/dist/domain/identityaccount/resolve.d.ts +47 -0
  163. package/dist/domain/identityaccount/resolve.d.ts.map +1 -1
  164. package/dist/domain/identityaccount/resolve.js +38 -1
  165. package/dist/domain/identityaccount/resolve.js.map +1 -1
  166. package/dist/domain/identityaccount/resource-store.d.ts.map +1 -1
  167. package/dist/domain/identityaccount/resource-store.js +11 -1
  168. package/dist/domain/identityaccount/resource-store.js.map +1 -1
  169. package/dist/domain/identityaccount/steps.d.ts +2 -1
  170. package/dist/domain/identityaccount/steps.d.ts.map +1 -1
  171. package/dist/domain/identityaccount/steps.js +4 -3
  172. package/dist/domain/identityaccount/steps.js.map +1 -1
  173. package/dist/domain/identityaccount/store-contract.js +2 -2
  174. package/dist/domain/identityaccount/store-contract.js.map +1 -1
  175. package/dist/domain/identityaccount/store.d.ts +6 -1
  176. package/dist/domain/identityaccount/store.d.ts.map +1 -1
  177. package/dist/domain/mcpserver/connect-sandbox.d.ts +67 -0
  178. package/dist/domain/mcpserver/connect-sandbox.d.ts.map +1 -0
  179. package/dist/domain/mcpserver/connect-sandbox.js +64 -0
  180. package/dist/domain/mcpserver/connect-sandbox.js.map +1 -0
  181. package/dist/domain/mcpserver/connect.d.ts +42 -10
  182. package/dist/domain/mcpserver/connect.d.ts.map +1 -1
  183. package/dist/domain/mcpserver/connect.js +147 -40
  184. package/dist/domain/mcpserver/connect.js.map +1 -1
  185. package/dist/domain/mcpserver/controller.js +4 -2
  186. package/dist/domain/mcpserver/controller.js.map +1 -1
  187. package/dist/domain/mcpserver/engine.d.ts +26 -7
  188. package/dist/domain/mcpserver/engine.d.ts.map +1 -1
  189. package/dist/domain/mcpserver/engine.js.map +1 -1
  190. package/dist/domain/mcpserver/start-connect.d.ts +5 -0
  191. package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
  192. package/dist/domain/mcpserver/start-connect.js +38 -15
  193. package/dist/domain/mcpserver/start-connect.js.map +1 -1
  194. package/dist/domain/memory/controller.js +2 -1
  195. package/dist/domain/memory/controller.js.map +1 -1
  196. package/dist/domain/memory/list-index.d.ts +2 -0
  197. package/dist/domain/memory/list-index.d.ts.map +1 -0
  198. package/dist/domain/memory/list-index.js +31 -0
  199. package/dist/domain/memory/list-index.js.map +1 -0
  200. package/dist/domain/memory/queries.d.ts +10 -0
  201. package/dist/domain/memory/queries.d.ts.map +1 -0
  202. package/dist/domain/memory/queries.js +54 -0
  203. package/dist/domain/memory/queries.js.map +1 -0
  204. package/dist/domain/memory/steps.d.ts +13 -11
  205. package/dist/domain/memory/steps.d.ts.map +1 -1
  206. package/dist/domain/memory/steps.js +26 -57
  207. package/dist/domain/memory/steps.js.map +1 -1
  208. package/dist/domain/organization/steps.d.ts.map +1 -1
  209. package/dist/domain/organization/steps.js +1 -1
  210. package/dist/domain/organization/steps.js.map +1 -1
  211. package/dist/domain/platformclient/mint.d.ts.map +1 -1
  212. package/dist/domain/platformclient/mint.js +2 -2
  213. package/dist/domain/platformclient/mint.js.map +1 -1
  214. package/dist/domain/platformclient/verifier.d.ts.map +1 -1
  215. package/dist/domain/platformclient/verifier.js +6 -3
  216. package/dist/domain/platformclient/verifier.js.map +1 -1
  217. package/dist/domain/plugin/push.d.ts.map +1 -1
  218. package/dist/domain/plugin/push.js +1 -0
  219. package/dist/domain/plugin/push.js.map +1 -1
  220. package/dist/domain/schedule/steps.d.ts +3 -1
  221. package/dist/domain/schedule/steps.d.ts.map +1 -1
  222. package/dist/domain/schedule/steps.js +3 -1
  223. package/dist/domain/schedule/steps.js.map +1 -1
  224. package/dist/domain/skill/push.d.ts.map +1 -1
  225. package/dist/domain/skill/push.js +1 -0
  226. package/dist/domain/skill/push.js.map +1 -1
  227. package/dist/domain/workflow/registry/data/task-kind-registry.json +27 -1
  228. package/dist/domain/workflowexecution/submit-approval.d.ts +5 -2
  229. package/dist/domain/workflowexecution/submit-approval.d.ts.map +1 -1
  230. package/dist/domain/workflowexecution/submit-approval.js +1 -1
  231. package/dist/domain/workflowexecution/submit-approval.js.map +1 -1
  232. package/dist/domain/workflowexecution/submit-file-decision.d.ts +5 -2
  233. package/dist/domain/workflowexecution/submit-file-decision.d.ts.map +1 -1
  234. package/dist/domain/workflowexecution/submit-file-decision.js +1 -1
  235. package/dist/domain/workflowexecution/submit-file-decision.js.map +1 -1
  236. package/dist/domain/workflowexecution/submit-workflow-task-approval.d.ts.map +1 -1
  237. package/dist/domain/workflowexecution/submit-workflow-task-approval.js +12 -1
  238. package/dist/domain/workflowexecution/submit-workflow-task-approval.js.map +1 -1
  239. package/dist/domain/workflowinstance/controller.d.ts +6 -3
  240. package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
  241. package/dist/domain/workflowinstance/controller.js +12 -7
  242. package/dist/domain/workflowinstance/controller.js.map +1 -1
  243. package/dist/domain/workflowinstance/steps.d.ts +31 -0
  244. package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
  245. package/dist/domain/workflowinstance/steps.js +88 -1
  246. package/dist/domain/workflowinstance/steps.js.map +1 -1
  247. package/dist/extensions/composed-services.d.ts +56 -0
  248. package/dist/extensions/composed-services.d.ts.map +1 -0
  249. package/dist/extensions/composed-services.js +2 -0
  250. package/dist/extensions/composed-services.js.map +1 -0
  251. package/dist/extensions/drivers.d.ts +32 -1
  252. package/dist/extensions/drivers.d.ts.map +1 -1
  253. package/dist/extensions/identity.d.ts +4 -1
  254. package/dist/extensions/identity.d.ts.map +1 -1
  255. package/dist/extensions/identity.js +4 -1
  256. package/dist/extensions/identity.js.map +1 -1
  257. package/dist/extensions/registry.d.ts +37 -0
  258. package/dist/extensions/registry.d.ts.map +1 -1
  259. package/dist/extensions/registry.js +50 -0
  260. package/dist/extensions/registry.js.map +1 -1
  261. package/dist/extensions/resource-authorization.d.ts +78 -0
  262. package/dist/extensions/resource-authorization.d.ts.map +1 -1
  263. package/dist/extensions/resource-row-reader.d.ts +43 -0
  264. package/dist/extensions/resource-row-reader.d.ts.map +1 -0
  265. package/dist/extensions/resource-row-reader.js +2 -0
  266. package/dist/extensions/resource-row-reader.js.map +1 -0
  267. package/dist/extensions/visitor-classifier.d.ts +41 -0
  268. package/dist/extensions/visitor-classifier.d.ts.map +1 -0
  269. package/dist/extensions/visitor-classifier.js +2 -0
  270. package/dist/extensions/visitor-classifier.js.map +1 -0
  271. package/dist/identity/oidc-userinfo.d.ts +6 -1
  272. package/dist/identity/oidc-userinfo.d.ts.map +1 -1
  273. package/dist/identity/oidc-userinfo.js.map +1 -1
  274. package/dist/identity/oidc-verifier.d.ts.map +1 -1
  275. package/dist/identity/oidc-verifier.js +37 -8
  276. package/dist/identity/oidc-verifier.js.map +1 -1
  277. package/dist/index.d.ts +14 -6
  278. package/dist/index.d.ts.map +1 -1
  279. package/dist/index.js +25 -9
  280. package/dist/index.js.map +1 -1
  281. package/dist/pipeline/errors.d.ts +8 -0
  282. package/dist/pipeline/errors.d.ts.map +1 -1
  283. package/dist/pipeline/errors.js +25 -16
  284. package/dist/pipeline/errors.js.map +1 -1
  285. package/dist/pipeline/interceptors/auth.d.ts +17 -9
  286. package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
  287. package/dist/pipeline/interceptors/auth.js +17 -9
  288. package/dist/pipeline/interceptors/auth.js.map +1 -1
  289. package/dist/pipeline/steps/authorization-tuples.d.ts +23 -1
  290. package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
  291. package/dist/pipeline/steps/authorization-tuples.js +42 -0
  292. package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
  293. package/dist/pipeline/steps/authorize.d.ts +6 -5
  294. package/dist/pipeline/steps/authorize.d.ts.map +1 -1
  295. package/dist/pipeline/steps/authorize.js +6 -5
  296. package/dist/pipeline/steps/authorize.js.map +1 -1
  297. package/dist/pipeline/steps/defaults.d.ts +12 -0
  298. package/dist/pipeline/steps/defaults.d.ts.map +1 -1
  299. package/dist/pipeline/steps/defaults.js +42 -7
  300. package/dist/pipeline/steps/defaults.js.map +1 -1
  301. package/dist/pipeline/steps/guard-memory-capture.d.ts +13 -15
  302. package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
  303. package/dist/pipeline/steps/guard-memory-capture.js +2 -3
  304. package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
  305. package/dist/runnerauth/built-in-runner-credential-provider.d.ts +0 -2
  306. package/dist/runnerauth/built-in-runner-credential-provider.d.ts.map +1 -1
  307. package/dist/runnerauth/built-in-runner-credential-provider.js +8 -17
  308. package/dist/runnerauth/built-in-runner-credential-provider.js.map +1 -1
  309. package/dist/runnerauth/runner-credential-provider.d.ts +17 -7
  310. package/dist/runnerauth/runner-credential-provider.d.ts.map +1 -1
  311. package/dist/runnerauth/runner-credential-provider.js.map +1 -1
  312. package/dist/sandbox/docker.d.ts.map +1 -1
  313. package/dist/sandbox/docker.js +3 -0
  314. package/dist/sandbox/docker.js.map +1 -1
  315. package/dist/sandbox/kubernetes.d.ts.map +1 -1
  316. package/dist/sandbox/kubernetes.js +3 -0
  317. package/dist/sandbox/kubernetes.js.map +1 -1
  318. package/dist/sandbox/local-process.d.ts.map +1 -1
  319. package/dist/sandbox/local-process.js +4 -0
  320. package/dist/sandbox/local-process.js.map +1 -1
  321. package/dist/sandbox/provisioner.d.ts +18 -6
  322. package/dist/sandbox/provisioner.d.ts.map +1 -1
  323. package/dist/sandbox/provisioner.js.map +1 -1
  324. package/dist/temporal/manager.d.ts +5 -0
  325. package/dist/temporal/manager.d.ts.map +1 -1
  326. package/dist/temporal/manager.js +9 -0
  327. package/dist/temporal/manager.js.map +1 -1
  328. package/dist/temporal/mcpserver/engine-client.d.ts +2 -2
  329. package/dist/temporal/mcpserver/engine-client.d.ts.map +1 -1
  330. package/dist/temporal/mcpserver/engine-client.js +6 -4
  331. package/dist/temporal/mcpserver/engine-client.js.map +1 -1
  332. package/dist/temporal/mcpserver/names.d.ts +13 -2
  333. package/dist/temporal/mcpserver/names.d.ts.map +1 -1
  334. package/dist/temporal/mcpserver/names.js +15 -2
  335. package/dist/temporal/mcpserver/names.js.map +1 -1
  336. package/dist/temporal/sdk-logger.d.ts +74 -0
  337. package/dist/temporal/sdk-logger.d.ts.map +1 -0
  338. package/dist/temporal/sdk-logger.js +143 -0
  339. package/dist/temporal/sdk-logger.js.map +1 -0
  340. package/package.json +6 -6
  341. package/src/authorization/README.md +18 -6
  342. package/src/authorization/__tests__/authorizer.test.ts +5 -1
  343. package/src/authorization/__tests__/derived-tuples.test.ts +26 -0
  344. package/src/authorization/__tests__/evaluator.test.ts +4 -0
  345. package/src/authorization/__tests__/list-read-scope.test.ts +11 -5
  346. package/src/authorization/__tests__/store-tests.test.ts +3 -1
  347. package/src/authorization/__tests__/trusted-local-authorizer.test.ts +155 -0
  348. package/src/authorization/__tests__/unit-owned-kinds.test.ts +420 -0
  349. package/src/authorization/__tests__/wire-permissions.test.ts +31 -2
  350. package/src/authorization/authorizer.ts +21 -10
  351. package/src/authorization/derived-tuples.ts +92 -18
  352. package/src/authorization/evaluator.ts +30 -15
  353. package/src/authorization/list-read-scope.ts +4 -0
  354. package/src/authorization/model/__tests__/registry.test.ts +23 -0
  355. package/src/authorization/model/data/authorization-model.json +830 -67
  356. package/src/authorization/model/execution-viewer.ts +32 -27
  357. package/src/authorization/model/index.ts +4 -1
  358. package/src/authorization/model/rewrite.ts +5 -3
  359. package/src/authorization/organization-directory.ts +4 -0
  360. package/src/authorization/person.ts +32 -1
  361. package/src/authorization/policy-check.ts +105 -0
  362. package/src/authorization/posture.ts +45 -4
  363. package/src/authorization/resource-creators.ts +48 -0
  364. package/src/authorization/trusted-local-authorizer.ts +91 -0
  365. package/src/authorization/tuples.ts +17 -0
  366. package/src/boot/__tests__/compose.test.ts +120 -4
  367. package/src/boot/__tests__/list-indexes.test.ts +4 -0
  368. package/src/boot/__tests__/oauth-redirect-uri.test.ts +121 -10
  369. package/src/boot/__tests__/skill-transfer-origin.test.ts +96 -25
  370. package/src/boot/compose.ts +154 -61
  371. package/src/boot/config.ts +28 -12
  372. package/src/boot/inprocess.ts +18 -4
  373. package/src/boot/list-indexes.ts +6 -1
  374. package/src/boot/logger.ts +3 -1
  375. package/src/boot/oauth-redirect-uri.ts +62 -17
  376. package/src/boot/skill-transfer-origin.ts +71 -16
  377. package/src/domain/agent/__tests__/agent.test.ts +42 -1
  378. package/src/domain/agentchannel/__tests__/agentchannel.test.ts +9 -0
  379. package/src/domain/agentchannel/__tests__/channel-runtime.test.ts +2 -0
  380. package/src/domain/agentchannel/__tests__/create-authorization.test.ts +7 -6
  381. package/src/domain/agentchannel/steps.ts +9 -7
  382. package/src/domain/agentexecution/__tests__/agentexecution.test.ts +148 -56
  383. package/src/domain/agentexecution/__tests__/create-steps.test.ts +175 -12
  384. package/src/domain/agentexecution/__tests__/file-review-seed.ts +91 -0
  385. package/src/domain/agentexecution/controller.ts +8 -0
  386. package/src/domain/agentexecution/create-steps.ts +74 -44
  387. package/src/domain/agentexecution/submit-approval.ts +9 -6
  388. package/src/domain/agentexecution/submit-file-decision.ts +5 -4
  389. package/src/domain/agentinstance/__tests__/agentinstance.test.ts +2 -0
  390. package/src/domain/agentshare/__tests__/agentshare.test.ts +17 -0
  391. package/src/domain/agentshare/__tests__/create-authorization.test.ts +5 -4
  392. package/src/domain/agentshare/steps.ts +6 -4
  393. package/src/domain/apikey/__tests__/verifier.test.ts +73 -1
  394. package/src/domain/apikey/verifier.ts +45 -1
  395. package/src/domain/artifact/__tests__/artifact.test.ts +13 -24
  396. package/src/domain/channelapp/__tests__/channelapp.test.ts +7 -0
  397. package/src/domain/channelapp/controller.ts +35 -12
  398. package/src/domain/environment/__tests__/environment.test.ts +13 -0
  399. package/src/domain/executioncontext/__tests__/executioncontext.test.ts +2 -0
  400. package/src/domain/executioncontext/steps.ts +2 -1
  401. package/src/domain/iampolicy/__tests__/access-lists.test.ts +79 -0
  402. package/src/domain/iampolicy/__tests__/change.test.ts +63 -0
  403. package/src/domain/iampolicy/__tests__/controller.test.ts +39 -3
  404. package/src/domain/iampolicy/__tests__/grant-path.test.ts +595 -27
  405. package/src/domain/iampolicy/__tests__/iampolicy.test.ts +33 -2
  406. package/src/domain/iampolicy/__tests__/membership.test.ts +47 -5
  407. package/src/domain/iampolicy/__tests__/resource-store.test.ts +1 -0
  408. package/src/domain/iampolicy/__tests__/role-lifecycle.test.ts +41 -8
  409. package/src/domain/iampolicy/__tests__/roles.test.ts +3 -2
  410. package/src/domain/iampolicy/__tests__/steps.test.ts +75 -6
  411. package/src/domain/iampolicy/__tests__/support.ts +68 -4
  412. package/src/domain/iampolicy/access-lists.ts +70 -2
  413. package/src/domain/iampolicy/change.ts +109 -0
  414. package/src/domain/iampolicy/constants.ts +8 -0
  415. package/src/domain/iampolicy/controller.ts +17 -3
  416. package/src/domain/iampolicy/grant-path.ts +349 -31
  417. package/src/domain/iampolicy/membership.ts +32 -12
  418. package/src/domain/iampolicy/resource-store.ts +4 -0
  419. package/src/domain/iampolicy/role-lifecycle.ts +2 -0
  420. package/src/domain/iampolicy/roles.ts +8 -0
  421. package/src/domain/iampolicy/steps.ts +15 -5
  422. package/src/domain/iampolicy/store-contract.ts +37 -1
  423. package/src/domain/iampolicy/store.ts +19 -5
  424. package/src/domain/identityaccount/__tests__/resolve.test.ts +246 -2
  425. package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -1
  426. package/src/domain/identityaccount/constants.ts +20 -0
  427. package/src/domain/identityaccount/controller.ts +20 -5
  428. package/src/domain/identityaccount/resolve.ts +80 -1
  429. package/src/domain/identityaccount/resource-store.ts +14 -1
  430. package/src/domain/identityaccount/steps.ts +4 -3
  431. package/src/domain/identityaccount/store-contract.ts +4 -4
  432. package/src/domain/identityaccount/store.ts +6 -1
  433. package/src/domain/mcpserver/__tests__/connect-authorization.test.ts +1 -0
  434. package/src/domain/mcpserver/__tests__/connect.test.ts +358 -15
  435. package/src/domain/mcpserver/__tests__/mcpserver.test.ts +2 -0
  436. package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +2 -0
  437. package/src/domain/mcpserver/__tests__/store-faults.test.ts +2 -0
  438. package/src/domain/mcpserver/connect-sandbox.ts +135 -0
  439. package/src/domain/mcpserver/connect.ts +226 -56
  440. package/src/domain/mcpserver/controller.ts +8 -2
  441. package/src/domain/mcpserver/engine.ts +24 -6
  442. package/src/domain/mcpserver/start-connect.ts +49 -10
  443. package/src/domain/memory/__tests__/memory.test.ts +92 -22
  444. package/src/domain/memory/__tests__/queries.test.ts +173 -0
  445. package/src/domain/memory/controller.ts +2 -1
  446. package/src/domain/memory/list-index.ts +32 -0
  447. package/src/domain/memory/queries.ts +72 -0
  448. package/src/domain/memory/steps.ts +26 -63
  449. package/src/domain/oauthapp/__tests__/oauthapp.test.ts +14 -0
  450. package/src/domain/organization/__tests__/support.ts +41 -0
  451. package/src/domain/organization/steps.ts +1 -0
  452. package/src/domain/platformclient/mint.ts +6 -2
  453. package/src/domain/platformclient/verifier.ts +6 -3
  454. package/src/domain/plugin/__tests__/plugin.test.ts +11 -24
  455. package/src/domain/plugin/push.ts +1 -0
  456. package/src/domain/schedule/__tests__/schedule.composed.test.ts +2 -0
  457. package/src/domain/schedule/steps.ts +3 -1
  458. package/src/domain/session/__tests__/session.test.ts +2 -0
  459. package/src/domain/skill/__tests__/skill.test.ts +7 -25
  460. package/src/domain/skill/push.ts +1 -0
  461. package/src/domain/workflow/__tests__/workflow.test.ts +2 -0
  462. package/src/domain/workflow/registry/data/task-kind-registry.json +27 -1
  463. package/src/domain/workflowexecution/__tests__/forward-attribution-composed.test.ts +270 -0
  464. package/src/domain/workflowexecution/__tests__/submit-workflow-task-approval.test.ts +196 -0
  465. package/src/domain/workflowexecution/__tests__/workflowexecution.test.ts +3 -57
  466. package/src/domain/workflowexecution/submit-approval.ts +9 -2
  467. package/src/domain/workflowexecution/submit-file-decision.ts +6 -1
  468. package/src/domain/workflowexecution/submit-workflow-task-approval.ts +23 -5
  469. package/src/domain/workflowinstance/controller.ts +27 -9
  470. package/src/domain/workflowinstance/steps.ts +123 -1
  471. package/src/extensions/__tests__/apikey-before-sign-in-composed.test.ts +172 -0
  472. package/src/extensions/__tests__/built-in-authorization-composed.test.ts +80 -1
  473. package/src/extensions/__tests__/composed-services-composed.test.ts +236 -0
  474. package/src/extensions/__tests__/extension-composition.test.ts +229 -16
  475. package/src/extensions/__tests__/identity-account-composed.test.ts +84 -4
  476. package/src/extensions/__tests__/list-read-scope-composed.test.ts +41 -1
  477. package/src/extensions/__tests__/registry.test.ts +147 -1
  478. package/src/extensions/__tests__/secret-cleanup-composed.test.ts +2 -0
  479. package/src/extensions/__tests__/visitor-classifier-points.test.ts +42 -0
  480. package/src/extensions/composed-services.ts +61 -0
  481. package/src/extensions/drivers.ts +33 -1
  482. package/src/extensions/identity.ts +4 -1
  483. package/src/extensions/registry.ts +105 -0
  484. package/src/extensions/resource-authorization.ts +87 -0
  485. package/src/extensions/resource-row-reader.ts +43 -0
  486. package/src/extensions/visitor-classifier.ts +41 -0
  487. package/src/identity/__tests__/oidc-verifier.test.ts +38 -12
  488. package/src/identity/oidc-userinfo.ts +6 -1
  489. package/src/identity/oidc-verifier.ts +42 -8
  490. package/src/index.ts +61 -6
  491. package/src/pipeline/__tests__/steps.test.ts +31 -4
  492. package/src/pipeline/errors.ts +30 -16
  493. package/src/pipeline/interceptors/auth.ts +17 -9
  494. package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +20 -0
  495. package/src/pipeline/steps/__tests__/guard-memory-capture.test.ts +72 -15
  496. package/src/pipeline/steps/authorization-tuples.ts +54 -0
  497. package/src/pipeline/steps/authorize.ts +6 -5
  498. package/src/pipeline/steps/defaults.ts +52 -7
  499. package/src/pipeline/steps/guard-memory-capture.ts +15 -20
  500. package/src/runnerauth/__tests__/built-in-runner-credential-provider.test.ts +1 -1
  501. package/src/runnerauth/__tests__/runner-subject-composed.test.ts +13 -0
  502. package/src/runnerauth/bound-execution.ts +2 -2
  503. package/src/runnerauth/built-in-runner-credential-provider.ts +8 -21
  504. package/src/runnerauth/runner-credential-provider.ts +17 -7
  505. package/src/sandbox/__tests__/docker.integration.test.ts +4 -0
  506. package/src/sandbox/__tests__/kubernetes.test.ts +18 -1
  507. package/src/sandbox/__tests__/local-process.integration.test.ts +4 -0
  508. package/src/sandbox/__tests__/provisioner.test.ts +1 -0
  509. package/src/sandbox/docker.ts +3 -0
  510. package/src/sandbox/kubernetes.ts +3 -0
  511. package/src/sandbox/local-process.ts +4 -0
  512. package/src/sandbox/provisioner.ts +18 -6
  513. package/src/store/postgres/__tests__/support.ts +11 -2
  514. package/src/temporal/README.md +1 -0
  515. package/src/temporal/__tests__/manager.test.ts +56 -4
  516. package/src/temporal/__tests__/sdk-log-workflows.ts +26 -0
  517. package/src/temporal/__tests__/sdk-logger.e2e.test.ts +150 -0
  518. package/src/temporal/__tests__/sdk-logger.test.ts +238 -0
  519. package/src/temporal/manager.ts +9 -0
  520. package/src/temporal/mcpserver/engine-client.ts +8 -3
  521. package/src/temporal/mcpserver/names.ts +16 -2
  522. package/src/temporal/sdk-logger.ts +173 -0
  523. package/dist/authorization/lane-admission.d.ts +0 -50
  524. package/dist/authorization/lane-admission.d.ts.map +0 -1
  525. package/dist/authorization/lane-admission.js +0 -13
  526. package/dist/authorization/lane-admission.js.map +0 -1
  527. package/src/authorization/__tests__/lane-admission.test.ts +0 -115
  528. package/src/authorization/lane-admission.ts +0 -73
@@ -11,7 +11,7 @@
11
11
  * resolves an agent-less blueprint. Nothing here resolves a stored default
12
12
  * agent into that shape.
13
13
  */
14
- import { create, fromBinary } from "@bufbuild/protobuf";
14
+ import { create } from "@bufbuild/protobuf";
15
15
 
16
16
  import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
17
17
  import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
@@ -28,8 +28,6 @@ import {
28
28
  } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
29
29
  import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
30
30
  import { MemoryLifecycleState } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/enum_pb";
31
- import type { Memory } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/api_pb";
32
- import { MemorySchema } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/api_pb";
33
31
  import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
34
32
  import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
35
33
  import type { SessionSpec } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
@@ -43,6 +41,7 @@ import { clone } from "@bufbuild/protobuf";
43
41
  import type { Logger } from "../../boot/logger.js";
44
42
  import type { CallerIdentity } from "../../extensions/identity.js";
45
43
  import { isFirstPartyHumanOperator } from "../../extensions/identity.js";
44
+ import type { VisitorClassifier } from "../../extensions/visitor-classifier.js";
46
45
  import type { ResourceAuthorizationLifecycle } from "../../extensions/resource-authorization.js";
47
46
  import { notifyDefaultInstanceLinked } from "../../pipeline/steps/authorization-tuples.js";
48
47
  import {
@@ -61,6 +60,7 @@ import type { Store } from "../../store/interface.js";
61
60
  import { buildDefaultInstanceRequest } from "../agentinstance/defaultinstance.js";
62
61
  import type { AccountsByCaller } from "../identityaccount/resolve.js";
63
62
  import { accountForCaller } from "../identityaccount/resolve.js";
63
+ import { listSubjectMemories } from "../memory/queries.js";
64
64
 
65
65
  import type { AgentExecutionStatusObserver } from "../../extensions/status-hooks.js";
66
66
 
@@ -424,24 +424,38 @@ export function newCreateSessionIfNeededStep(deps: {
424
424
  * Snapshots the declared standing context onto the execution spec
425
425
  * (DD-002, stigmer/stigmer#293). SERVER-OWNED: stamped unconditionally,
426
426
  * overwriting anything the caller supplied. Two independent halves:
427
- * org_context, the organization's, for every run; and user_context, the
428
- * run's person's own (stigmer#1397) — composed only where callers are
429
- * persons (`personAccounts`, the require-authentication posture) and only
430
- * for a first-party human operator (runPersonOf), as the Java step did.
431
- * The single-operator posture composes org_context alone: its one
432
- * operator's context is the organization's. The org half deliberately
433
- * keeps running for every lane (schedule and channel runs carry the
434
- * organization's instructions today); only the person's half is about a
435
- * person. BEST-EFFORT: an execution must never fail to start because its
427
+ *
428
+ * - org_context, the organization's, for every run but a VISITOR's
429
+ * (stigmer/stigmer#1401). Its admins wrote it for the organization's
430
+ * own work, so the organization's own lanes keep it — a person, a
431
+ * schedule, a workflow's agent_call, the platform's pipelines — and
432
+ * a caller the composed classifier names a visitor (the hosted
433
+ * edition's shared-agent guests and channel senders) never gets it;
434
+ * the organization is not even read. Open source composes no
435
+ * classifier and has no visitors. Not first-party-only like the
436
+ * person's half: that would strip it from every schedule and
437
+ * workflow run, and from the single operator, whose only standing
438
+ * context this is.
439
+ * - user_context, the run's person's own (stigmer#1397), composed only
440
+ * where callers are persons (`personAccounts`, the
441
+ * require-authentication posture) and only for a first-party human
442
+ * operator (runPersonOf), as the Java step did. The single-operator
443
+ * posture composes org_context alone: its one operator's context is
444
+ * the organization's.
445
+ *
446
+ * BEST-EFFORT: an execution must never fail to start because its
436
447
  * optional preferences could not load — genuine failures log at ERROR
437
448
  * (quiet degradation of a should-work path must stay visible) and degrade
438
- * that half to empty. Snapshot-at-create is the point: preferences are
439
- * mutable, executions are immutable audit records.
449
+ * that half to empty; a classifier that throws withholds the org half,
450
+ * logged the same way (extensions/visitor-classifier.ts, fail-closed).
451
+ * Snapshot-at-create is the point: preferences are mutable, executions
452
+ * are immutable audit records.
440
453
  */
441
454
  export function newComposeDeclaredPreferencesStep(
442
455
  store: Store,
443
456
  logger: Logger,
444
457
  personAccounts?: AccountsByCaller,
458
+ visitorClassifier?: VisitorClassifier,
445
459
  ): PipelineStep<CreateDesc> {
446
460
  return {
447
461
  name: "ComposeDeclaredPreferences",
@@ -453,8 +467,15 @@ export function newComposeDeclaredPreferencesStep(
453
467
 
454
468
  // Verbatim per DD-002 D2: the server stamps content only;
455
469
  // blank-is-absent is the runner's read-side convention.
456
- execution.spec.declaredPreferences.orgContext =
457
- await loadOrgStandingContext(store, logger, orgIdOf(ctx));
470
+ if (isVisitor(visitorClassifier, ctx.callerIdentity, logger)) {
471
+ logger.debug(
472
+ "Caller is a visitor, composing no organization standing context",
473
+ { identityId: ctx.callerIdentity.identityId },
474
+ );
475
+ } else {
476
+ execution.spec.declaredPreferences.orgContext =
477
+ await loadOrgStandingContext(store, logger, orgIdOf(ctx));
478
+ }
458
479
 
459
480
  if (personAccounts === undefined) {
460
481
  return;
@@ -471,6 +492,32 @@ export function newComposeDeclaredPreferencesStep(
471
492
  };
472
493
  }
473
494
 
495
+ /**
496
+ * Whether the composed classifier names `caller` a visitor: absent, nobody
497
+ * is; a throw is one, logged at ERROR (the point's fail-closed contract).
498
+ */
499
+ function isVisitor(
500
+ classifier: VisitorClassifier | undefined,
501
+ caller: CallerIdentity,
502
+ logger: Logger,
503
+ ): boolean {
504
+ if (classifier === undefined) {
505
+ return false;
506
+ }
507
+ try {
508
+ return classifier.isVisitor(caller);
509
+ } catch (error) {
510
+ logger.error(
511
+ "Visitor classifier failed - composing no organization standing context (fail-closed contract)",
512
+ {
513
+ identityId: caller.identityId,
514
+ error: error instanceof Error ? error.message : String(error),
515
+ },
516
+ );
517
+ return true;
518
+ }
519
+ }
520
+
474
521
  /** The org a create addresses: the execution's metadata, else the input's. */
475
522
  function orgIdOf(ctx: RequestContext<CreateDesc>): string {
476
523
  const orgId = ctx.newState.metadata?.org ?? "";
@@ -678,40 +725,23 @@ export function newComposeRecalledMemoriesStep(
678
725
  }
679
726
 
680
727
  /**
681
- * Scans the memory kind for `subject`'s confirmed records in the org,
682
- * oldest-first — the run's person's account id, or the single-operator
683
- * "" sentinel. Facts carry only memory_id + content (the id is the
684
- * transparency link back to the addressable record). Undecodable rows are
685
- * skipped — one bad record must not take recall down.
728
+ * Reads `subject`'s confirmed records in the org through the memory list
729
+ * index (domain/memory/queries.ts), oldest-first — the run's person's
730
+ * account id, or the single-operator "" sentinel. Facts carry only
731
+ * memory_id + content (the id is the transparency link back to the
732
+ * addressable record). Undecodable rows are skipped — one bad record must
733
+ * not take recall down.
686
734
  */
687
735
  async function loadConfirmedFacts(
688
736
  store: Store,
689
737
  orgId: string,
690
738
  subject: string,
691
739
  ) {
692
- const rows = await store.listResources(ApiResourceKind.memory);
693
- const memories: Memory[] = [];
694
- for (const data of rows) {
695
- let memory: Memory;
696
- try {
697
- memory = fromBinary(MemorySchema, data);
698
- } catch {
699
- continue;
700
- }
701
- if ((memory.metadata?.org ?? "") !== orgId) {
702
- continue;
703
- }
704
- if ((memory.spec?.subjectIdentityAccountId ?? "") !== subject) {
705
- continue;
706
- }
707
- if (
708
- memory.status?.lifecycleState !==
709
- MemoryLifecycleState.lifecycle_state_confirmed
710
- ) {
711
- continue;
712
- }
713
- memories.push(memory);
714
- }
740
+ const memories = (await listSubjectMemories(store, orgId, subject)).filter(
741
+ (memory) =>
742
+ memory.status?.lifecycleState ===
743
+ MemoryLifecycleState.lifecycle_state_confirmed,
744
+ );
715
745
 
716
746
  // Oldest-first on created_at (seconds then nanos; untimestamped rows
717
747
  // first) — mirrors the cloud repo's ORDER BY created_at ASC.
@@ -223,10 +223,14 @@ export async function submitApproval(
223
223
  const action = ctx.input.action;
224
224
  const comment = ctx.input.comment;
225
225
  const now = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
226
- // Decider identity for the approval ledger. OSS is single-user
227
- // with no multi-tenant auth context, so the principal is empty;
228
- // the Cloud edition populates it from the authenticated caller.
229
- const decidedBy = "";
226
+ // The decider is the principal this chain authorized at position
227
+ // 1 — the same id auditActorFor stamps as created_by.id, so the
228
+ // approval ledger and the audit trail name one person the same
229
+ // way in every edition (the trusted-local operator on a laptop,
230
+ // the account on a signed-in server; stigmer/stigmer#1385). A
231
+ // decision forwarded by a workflow arrives as the server acting
232
+ // for that workflow's caller, so the person is named there too.
233
+ const decidedBy = ctx.callerIdentity.identityId;
230
234
 
231
235
  let updated: AgentExecution;
232
236
  try {
@@ -385,8 +389,6 @@ export async function submitApproval(
385
389
  name: "BuildResponse",
386
390
  execute(ctx) {
387
391
  const execution = ctx.get(TARGET_RESOURCE_KEY) as AgentExecution;
388
- // Audit log the approval decision (caller identity arrives with
389
- // the cloud edition's auth context).
390
392
  const tc = findToolCallInExecution(execution, ctx.input.toolCallId);
391
393
  deps.logger.info("AUDIT: Approval decision submitted", {
392
394
  executionId: execution.metadata?.id ?? "",
@@ -394,6 +396,7 @@ export async function submitApproval(
394
396
  toolCallId: ctx.input.toolCallId,
395
397
  toolName: tc?.name ?? "unknown",
396
398
  action: protoName(ApprovalActionSchema, ctx.input.action),
399
+ decidedBy: ctx.callerIdentity.identityId,
397
400
  comment: ctx.input.comment,
398
401
  });
399
402
  },
@@ -173,10 +173,10 @@ export async function submitFileDecision(
173
173
  }
174
174
  const executionId = ctx.input.agentExecutionId;
175
175
  const now = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
176
- // OSS is single-user with no multi-tenant auth context, so the
177
- // reviewer is empty; the Cloud edition populates reviewer_id from
178
- // the authenticated caller.
179
- const reviewerId = "";
176
+ // The reviewer is the principal this chain authorized, recorded
177
+ // exactly as the approval writer records its decider (see
178
+ // submit-approval.ts RecordApprovalDecision; stigmer/stigmer#1385).
179
+ const reviewerId = ctx.callerIdentity.identityId;
180
180
 
181
181
  let updated: AgentExecution;
182
182
  try {
@@ -310,6 +310,7 @@ export async function submitFileDecision(
310
310
  fileChangeId: ctx.input.fileChangeId,
311
311
  scope: enumToJson(FileDecisionScopeSchema, ctx.input.scope),
312
312
  action: enumToJson(FileDecisionActionSchema, ctx.input.action),
313
+ reviewerId: ctx.callerIdentity.identityId,
313
314
  });
314
315
  },
315
316
  })
@@ -50,6 +50,7 @@ import {
50
50
  buildDefaultInstanceRequest,
51
51
  defaultInstanceSlug,
52
52
  } from "../defaultinstance.js";
53
+ import { seedOrganizations } from "../../organization/__tests__/support.js";
53
54
 
54
55
  const silentLogger = createLogger({
55
56
  level: "error",
@@ -94,6 +95,7 @@ beforeAll(async () => {
94
95
  });
95
96
  const port = await server.start();
96
97
  transport = createGrpcTransport({ baseUrl: `http://127.0.0.1:${port}` });
98
+ await seedOrganizations(transport, [ORG]);
97
99
  agentCommand = createClient(AgentCommandController, transport);
98
100
  command = createClient(AgentInstanceCommandController, transport);
99
101
  query = createClient(AgentInstanceQueryController, transport);
@@ -52,6 +52,7 @@ import {
52
52
  sameOrgInvariantMessage,
53
53
  } from "../constants.js";
54
54
  import { findShareByOrgAndSlug, sharingLinkTokenAllowed } from "../steps.js";
55
+ import { seedOrganizations } from "../../organization/__tests__/support.js";
55
56
 
56
57
  const silentLogger = createLogger({
57
58
  level: "error",
@@ -96,6 +97,22 @@ beforeAll(async () => {
96
97
  const transport: Transport = createGrpcTransport({
97
98
  baseUrl: `http://127.0.0.1:${port}`,
98
99
  });
100
+ // Every Organization a describe below writes into (each names its own).
101
+ await seedOrganizations(transport, [
102
+ "create-test-org",
103
+ "launchgate-test-org",
104
+ "update-test-org",
105
+ "profile-test-org",
106
+ "audience-test-org",
107
+ "rotate-test-org",
108
+ "apply-isolation-org",
109
+ "apply-sem-org",
110
+ "gba-bystander-org",
111
+ "gba-provider-org",
112
+ "gba-org",
113
+ "provider-org",
114
+ "consumer-org",
115
+ ]);
99
116
  shares = createClient(AgentShareCommandController, transport);
100
117
  query = createClient(AgentShareQueryController, transport);
101
118
  agents = createClient(AgentCommandController, transport);
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * Pins the create lane's two questions (steps.ts, resolveShareCreateTargets):
3
- * can_edit on the referenced agent, then can_create_agent_share on the
3
+ * can_manage_audience on the referenced agent, then can_create_agent_share on the
4
4
  * share's organization, in that order, each with its byte-pinned copy. A
5
5
  * share's agent lives in the share's organization (the resolve step refuses
6
6
  * anything else before this runs), so the two bars are one organization's:
7
- * sharing puts the agent in front of a wider audience (an editor's act) and
7
+ * sharing puts the agent in front of a wider audience (the owner's act, not
8
+ * an editor's) and
8
9
  * spends the organization's credits on the open internet (an admin's). A
9
10
  * missing referenced agent throws.
10
11
  */
@@ -46,10 +47,10 @@ function ctxFor(shareOrg: string, stash = true) {
46
47
  }
47
48
 
48
49
  describe("resolveShareCreateTargets", () => {
49
- it("asks can_edit on the referenced agent, then can_create_agent_share on the share's organization", () => {
50
+ it("asks can_manage_audience on the referenced agent, then can_create_agent_share on the share's organization", () => {
50
51
  expect(resolveShareCreateTargets(ctxFor("publisher-org"))).toEqual([
51
52
  {
52
- permission: IamPermission.can_edit,
53
+ permission: IamPermission.can_manage_audience,
53
54
  resourceKind: ApiResourceKind.agent,
54
55
  resourceId: "agt_01helper",
55
56
  deniedMessage: SHARE_AGENT_DENIED_MESSAGE,
@@ -86,9 +86,11 @@ export const SHARE_ORGANIZATION_DENIED_MESSAGE =
86
86
 
87
87
  /**
88
88
  * The create lane's authorization questions, for AuthorizeResolvedTarget
89
- * after ResolveShareDefaults, agent first: can_edit on the agent (sharing
90
- * puts it in front of a wider audience, an editor's act) and then
91
- * can_create_agent_share on the organization (a share spends the
89
+ * after ResolveShareDefaults, agent first: can_manage_audience on the
90
+ * agent (sharing puts it in front of a wider audience, so it decides who
91
+ * reaches the agent: the owner's act, never an editor's, who may change the
92
+ * definition but not its audience) and then can_create_agent_share on the
93
+ * organization (a share spends the
92
94
  * organization's credits on the open internet, an admin-level act). The
93
95
  * RPC is is_skip_authorization because the target is the referenced agent,
94
96
  * resolved from a slug, not a request field. The resolve step has already
@@ -104,7 +106,7 @@ export function resolveShareCreateTargets(
104
106
  }
105
107
  return [
106
108
  {
107
- permission: IamPermission.can_edit,
109
+ permission: IamPermission.can_manage_audience,
108
110
  resourceKind: ApiResourceKind.agent,
109
111
  resourceId: agent.metadata?.id ?? "",
110
112
  deniedMessage: SHARE_AGENT_DENIED_MESSAGE,
@@ -16,6 +16,15 @@
16
16
  * in, so what is pinned is the production pair; only the fault arm
17
17
  * substitutes a one-method lookup that rejects.
18
18
  *
19
+ * A key created before sign-in was turned on is refused by name
20
+ * (stigmer/stigmer#1169): its stamp is the trusted-local operator's email
21
+ * (or "system"), which names nobody once sign-in is on, so the verifier
22
+ * answers UNAUTHENTICATED with the sentence and the
23
+ * API_KEY_CREATED_BEFORE_SIGN_IN reason instead of admitting the email
24
+ * and letting every later check fail as "Permission denied". An issuer
25
+ * subject that merely looks like an email is still admitted idp-shaped,
26
+ * and an account-stamped key costs no extra read.
27
+ *
19
28
  * An accepted key's use lands on its own row (stigmer/stigmer#1255):
20
29
  * stamped on the first verify, left alone inside the resolution, moved
21
30
  * forward after it; a refused key records nothing; a stamp that cannot be
@@ -28,6 +37,7 @@ import path from "node:path";
28
37
  import { create } from "@bufbuild/protobuf";
29
38
  import { timestampDate, timestampFromDate } from "@bufbuild/protobuf/wkt";
30
39
  import { Code, ConnectError } from "@connectrpc/connect";
40
+ import { ErrorInfoSchema } from "@stigmer/protos/google/rpc/error_details_pb";
31
41
  import { afterAll, beforeAll, describe, expect, it } from "vitest";
32
42
 
33
43
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
@@ -40,12 +50,17 @@ import type { Logger } from "../../../boot/logger.js";
40
50
  import { LAST_USED_RESOLUTION_MS } from "../../../identity/credential-use.js";
41
51
  import type { Store } from "../../../store/interface.js";
42
52
  import { SqliteStore } from "../../../store/sqlite/store.js";
43
- import { accountIdFor } from "../../identityaccount/constants.js";
53
+ import {
54
+ accountIdFor,
55
+ localIdpIdFor,
56
+ } from "../../identityaccount/constants.js";
44
57
  import type { AccountsBySubject } from "../../identityaccount/resolve.js";
45
58
  import { newResourceIdentityAccountStore } from "../../identityaccount/resource-store.js";
46
59
  import type { IdentityAccountStore } from "../../identityaccount/store.js";
47
60
  import { generateApiKeyPlaintext, hashApiKey } from "../keymaterial.js";
48
61
  import {
62
+ API_KEY_CREATED_BEFORE_SIGN_IN,
63
+ API_KEY_CREATED_BEFORE_SIGN_IN_MESSAGE,
49
64
  INVALID_TOKEN_MESSAGE,
50
65
  TOKEN_EXPIRED_MESSAGE,
51
66
  newApiKeyIdentityVerifier,
@@ -326,6 +341,63 @@ describe("creator stamp → account resolution (20260911.11 A6)", () => {
326
341
  });
327
342
  });
328
343
 
344
+ describe("a key created before sign-in was turned on (stigmer/stigmer#1169)", () => {
345
+ /** The refusal a pre-sign-in key must answer: the code, the copy, the reason. */
346
+ function expectRefusedBeforeSignIn(error: unknown): true {
347
+ const refusal = ConnectError.from(error);
348
+ expect(refusal.code).toBe(Code.Unauthenticated);
349
+ expect(refusal.rawMessage).toBe(API_KEY_CREATED_BEFORE_SIGN_IN_MESSAGE);
350
+ const [info] = refusal.findDetails(ErrorInfoSchema);
351
+ expect(info?.reason).toBe(API_KEY_CREATED_BEFORE_SIGN_IN);
352
+ expect(info?.domain).toBe("stigmer.ai");
353
+ return true;
354
+ }
355
+
356
+ it("a key stamped with the configured operator's email is refused by name and records no use", async () => {
357
+ await provisionAccount(localIdpIdFor("laptop@example.com"), "laptop@example.com");
358
+ const { plaintext, id } = await seedKey({
359
+ ownerId: "laptop@example.com",
360
+ email: "laptop@example.com",
361
+ });
362
+
363
+ await expect(verifier().verify(plaintext)).rejects.toSatisfy(
364
+ expectRefusedBeforeSignIn,
365
+ );
366
+ expect((await storedKey(id)).status?.lastUsedAt).toBeUndefined();
367
+ });
368
+
369
+ it("a key stamped \"system\" by the unconfigured laptop is refused by name", async () => {
370
+ const { plaintext } = await seedKey({ ownerId: "system", email: "" });
371
+
372
+ await expect(verifier().verify(plaintext)).rejects.toSatisfy(
373
+ expectRefusedBeforeSignIn,
374
+ );
375
+ });
376
+
377
+ it("an unprovisioned issuer subject that looks like an email is still admitted idp-shaped", async () => {
378
+ const { plaintext } = await seedKey({ ownerId: "stranger@example.com" });
379
+
380
+ expect((await verifier().verify(plaintext))?.identityId).toBe(
381
+ "stranger@example.com",
382
+ );
383
+ });
384
+
385
+ it("an account-stamped key makes exactly the one read it made before", async () => {
386
+ const reads: string[] = [];
387
+ const counting: AccountsBySubject = {
388
+ findDirectByIdpId: async (idpId) => {
389
+ reads.push(idpId);
390
+ return accounts.findDirectByIdpId(idpId);
391
+ },
392
+ };
393
+ const owner = accountIdFor("auth0|steady");
394
+ const { plaintext } = await seedKey({ ownerId: owner });
395
+
396
+ expect((await verifier(counting).verify(plaintext))?.identityId).toBe(owner);
397
+ expect(reads).toEqual([owner]);
398
+ });
399
+ });
400
+
329
401
  describe("last use (stigmer/stigmer#1255)", () => {
330
402
  it("an accepted key stamps its last use on its own row, once per resolution, forward after it", async () => {
331
403
  const { plaintext, id } = await seedKey();
@@ -34,6 +34,27 @@
34
34
  * actor the key recorded at minting. The credential checks run first, so
35
35
  * a revoked or expired key never reaches the account store.
36
36
  *
37
+ * One stamp names nobody by construction: the operator's from before
38
+ * sign-in was turned on (stigmer/stigmer#1169). A key created while the
39
+ * server trusted every caller carries the operator's email, or "system",
40
+ * and once sign-in is on the operator is a different account, derived
41
+ * from the issuer's subject. Carrying the key to either account was
42
+ * weighed and refused. Carried to the pre-sign-in account, it would be a
43
+ * live credential no signed-in person could see or revoke, since only a
44
+ * key's owner may. Carried to the signed-in account, a credential would
45
+ * change hands on an email match. So such a key is refused by name:
46
+ * UNAUTHENTICATED, API_KEY_CREATED_BEFORE_SIGN_IN_MESSAGE and the
47
+ * API_KEY_CREATED_BEFORE_SIGN_IN reason, which the CLI turns into the two
48
+ * commands that fix it. The alternative, admitting a bare email, made
49
+ * every later check fail as a misleading "Permission denied". The
50
+ * question is asked only of a stamp that resolved to nobody, through the
51
+ * identity-account domain's `isPreSignInOperatorStamp`, which makes no
52
+ * read for an account-id stamp. This verifier is composed only under an
53
+ * authentication posture (boot/compose.ts), so a server that trusts every
54
+ * caller never reaches the refusal. The reason is documented where a
55
+ * key's authentication is (apis/ai/stigmer/iam/apikey/v1/README.md): it
56
+ * can refuse any RPC, so no single RPC comment owns it.
57
+ *
37
58
  * An accepted key's use is then recorded on its status.last_used_at
38
59
  * (identity/credential-use.ts): at most once a resolution, judged from the
39
60
  * row this read already holds, written atomically through
@@ -55,8 +76,12 @@ import type {
55
76
  IdentityVerifier,
56
77
  } from "../../extensions/identity.js";
57
78
  import { recordCredentialUse } from "../../identity/credential-use.js";
79
+ import { unauthenticatedWithReasonError } from "../../pipeline/errors.js";
58
80
  import type { Store } from "../../store/interface.js";
59
- import { identityIdForSubject } from "../identityaccount/resolve.js";
81
+ import {
82
+ identityIdForSubject,
83
+ isPreSignInOperatorStamp,
84
+ } from "../identityaccount/resolve.js";
60
85
  import type { AccountsBySubject } from "../identityaccount/resolve.js";
61
86
  import { hashApiKey, isApiKeyToken } from "./keymaterial.js";
62
87
  import { findApiKeyByHash } from "./lookup.js";
@@ -67,6 +92,16 @@ export const INVALID_TOKEN_MESSAGE = "invalid token";
67
92
  /** Java classifyAuthError's "expired" arm. */
68
93
  export const TOKEN_EXPIRED_MESSAGE = "token has expired";
69
94
 
95
+ /**
96
+ * The ErrorInfo reason a key created before sign-in was turned on is
97
+ * refused with (stigmer/stigmer#1169). Wire contract, no metadata.
98
+ */
99
+ export const API_KEY_CREATED_BEFORE_SIGN_IN = "API_KEY_CREATED_BEFORE_SIGN_IN";
100
+
101
+ /** The copy of that refusal: what happened and what to do. */
102
+ export const API_KEY_CREATED_BEFORE_SIGN_IN_MESSAGE =
103
+ "this API key was created before sign-in was turned on and no longer authenticates anyone; sign in and create a new key";
104
+
70
105
  export interface ApiKeyVerifierDeps {
71
106
  /** Where the keys live — the generic Store, by hash (lookup.ts). */
72
107
  readonly store: Store;
@@ -105,6 +140,15 @@ export function newApiKeyIdentityVerifier(
105
140
  throw new ConnectError(INVALID_TOKEN_MESSAGE, Code.Unauthenticated);
106
141
  }
107
142
  const identityId = await identityIdForSubject(accounts, owner.id);
143
+ if (
144
+ identityId === owner.id &&
145
+ (await isPreSignInOperatorStamp(accounts, owner.id))
146
+ ) {
147
+ throw unauthenticatedWithReasonError(
148
+ API_KEY_CREATED_BEFORE_SIGN_IN_MESSAGE,
149
+ { reason: API_KEY_CREATED_BEFORE_SIGN_IN },
150
+ );
151
+ }
108
152
  await recordKeyUse(store, logger, key, now);
109
153
  return {
110
154
  identityId,
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Pins the artifact domain against Go's artifact_controller_test.go —
3
- * through the real stack (composed server, native gRPC client, the port+1
4
- * file server on a pre-picked free port).
3
+ * through the real stack (composed server, native gRPC client, the file
4
+ * server on the ephemeral port it binds beside the server's, reached through
5
+ * the download URLs the server mints).
5
6
  *
6
7
  * The load-bearing pins the conformance suite CANNOT cover:
7
8
  * - the 50MB domain cap → ResourceExhausted with Go's copy (sits behind
@@ -19,7 +20,6 @@
19
20
  import { newPermissiveSingleTeamAuthorizer } from "../../../pipeline/steps/authorize.js";
20
21
  import { mkdtempSync, rmSync } from "node:fs";
21
22
  import { createHash } from "node:crypto";
22
- import net from "node:net";
23
23
  import { tmpdir } from "node:os";
24
24
  import path from "node:path";
25
25
 
@@ -59,29 +59,13 @@ const silentLogger = createLogger({
59
59
  type CommandClient = Client<typeof ArtifactCommandController>;
60
60
  type QueryClient = Client<typeof ArtifactQueryController>;
61
61
 
62
- /** A free loopback port, picked ahead so the file server can pin it. */
63
- async function freePort(): Promise<number> {
64
- return new Promise((resolve, reject) => {
65
- const probe = net.createServer();
66
- probe.once("error", reject);
67
- probe.listen(0, "127.0.0.1", () => {
68
- const address = probe.address();
69
- const port =
70
- address !== null && typeof address === "object" ? address.port : 0;
71
- probe.close(() => resolve(port));
72
- });
73
- });
74
- }
75
-
76
62
  let server: ComposedServer;
77
63
  let command: CommandClient;
78
64
  let query: QueryClient;
79
65
  let dir: string;
80
- let artifactPort: number;
81
66
 
82
67
  beforeAll(async () => {
83
68
  dir = mkdtempSync(path.join(tmpdir(), "artifact-domain-test-"));
84
- artifactPort = await freePort();
85
69
  vi.stubEnv("STIGMER_ENCRYPTION_KEY", Buffer.alloc(32, 3).toString("base64"));
86
70
  vi.stubEnv(
87
71
  "STIGMER_RUNNER_TOKEN_KEY",
@@ -96,7 +80,6 @@ beforeAll(async () => {
96
80
  TEMPORAL_HOST_PORT: "127.0.0.1:1",
97
81
  DB_PATH: path.join(dir, "stigmer.db"),
98
82
  ARTIFACT_LOCAL_BASE_PATH: path.join(dir, "artifacts"),
99
- ARTIFACT_HTTP_PORT: String(artifactPort),
100
83
  }),
101
84
  logger: silentLogger,
102
85
  portOverride: 0,
@@ -397,14 +380,20 @@ describe("artifact domain — the local file-server lane", () => {
397
380
  });
398
381
 
399
382
  it("answers 404 for missing keys and refuses path traversal out of the root", async () => {
400
- const missing = await fetch(`http://127.0.0.1:${artifactPort}/nope`);
383
+ // The lane binds an ephemeral port; a minted URL is how a caller learns
384
+ // its origin, so the probes below address the same listener.
385
+ const created = await command.create(artifactInput());
386
+ const download = await query.getDownloadUrl({
387
+ value: created.metadata!.id,
388
+ });
389
+ const lane = new URL(download.url).origin;
390
+
391
+ const missing = await fetch(`${lane}/nope`);
401
392
  expect(missing.status).toBe(404);
402
393
 
403
394
  // The SQLite db sits one level above the artifact root — a traversal
404
395
  // escape would serve it.
405
- const traversal = await fetch(
406
- `http://127.0.0.1:${artifactPort}/..%2Fstigmer.db`,
407
- );
396
+ const traversal = await fetch(`${lane}/..%2Fstigmer.db`);
408
397
  expect(traversal.status).toBe(404);
409
398
  });
410
399
  });
@@ -50,6 +50,7 @@ import {
50
50
  noExistingSecretMessage,
51
51
  plaintextRequiredMessage,
52
52
  } from "../constants.js";
53
+ import { seedOrganizations } from "../../organization/__tests__/support.js";
53
54
 
54
55
  const silentLogger = createLogger({
55
56
  level: "error",
@@ -100,6 +101,12 @@ beforeAll(async () => {
100
101
  const transport: Transport = createGrpcTransport({
101
102
  baseUrl: `http://127.0.0.1:${port}`,
102
103
  });
104
+ await seedOrganizations(transport, [
105
+ ORG,
106
+ "some-other-org",
107
+ "acme-slack-queries",
108
+ "acme-wa-queries",
109
+ ]);
103
110
  command = createClient(ChannelAppCommandController, transport);
104
111
  query = createClient(ChannelAppQueryController, transport);
105
112
  });