@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
@@ -36,24 +36,21 @@ import { createGrpcTransport } from "@connectrpc/connect-node";
36
36
  import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
37
37
 
38
38
  import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
39
+ import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
39
40
  import { AgentExecutionSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
40
41
  import { AgentExecutionCommandController } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/command_pb";
41
42
  import {
42
43
  ApprovalAction,
43
44
  ApprovalEventType,
44
- DiffCompleteness,
45
45
  ExecutionPhase,
46
- FileChangeKind,
47
46
  FileChangeSetStatus,
48
47
  FileDecisionAction,
49
48
  FileDecisionOrigin,
50
49
  FileDecisionScope,
51
- FileReviewEventType,
52
50
  MessageType,
53
51
  ServiceTier,
54
52
  ToolCallStatus,
55
53
  } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
56
- import { CapturedFileChangeSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
57
54
  import {
58
55
  SubmitApprovalInputSchema,
59
56
  SubmitFileDecisionInputSchema,
@@ -66,16 +63,18 @@ import { loadConfig } from "../../../boot/config.js";
66
63
  import { composeServer } from "../../../boot/compose.js";
67
64
  import type { ComposedServer } from "../../../boot/compose.js";
68
65
  import { createLogger } from "../../../boot/logger.js";
66
+ import { trustedLocalIdentity } from "../../../pipeline/interceptors/auth.js";
69
67
  import type { AgentExecutionStatusTransition } from "../../../extensions/status-hooks.js";
70
68
  import type {
71
69
  ConnectedExecutionEngine,
72
70
  ExecutionEngineState,
73
71
  } from "../engine.js";
74
- import { EngineWorkflowNotFoundError } from "../engine.js";
75
- import { aggregateDigest, fileDigest } from "../filereview/digest.js";
72
+ import { ENGINE_DISCONNECTED, EngineWorkflowNotFoundError } from "../engine.js";
76
73
  import { submitApproval } from "../submit-approval.js";
77
74
  import { submitFileDecision } from "../submit-file-decision.js";
78
75
  import { stubConnectedEngine } from "./engine-stub.js";
76
+ import { fileReviewSeed } from "./file-review-seed.js";
77
+ import { seedOrganizations } from "../../organization/__tests__/support.js";
79
78
 
80
79
  const silentLogger = createLogger({
81
80
  level: "error",
@@ -125,6 +124,15 @@ beforeAll(async () => {
125
124
  const transport: Transport = createGrpcTransport({
126
125
  baseUrl: `http://127.0.0.1:${port}`,
127
126
  });
127
+ await seedOrganizations(transport, [
128
+ ORG,
129
+ "org-a",
130
+ "org-b",
131
+ "org-report",
132
+ "org-summary",
133
+ "other-org",
134
+ "org-never-used",
135
+ ]);
128
136
  command = createClient(AgentExecutionCommandController, transport);
129
137
  query = createClient(AgentExecutionQueryController, transport);
130
138
  });
@@ -939,6 +947,16 @@ describe("submitApproval over the wire (submit_approval_contract_test.go arms)",
939
947
  expect(
940
948
  decided?.payload.case === "decided" ? decided.payload.value.comment : "",
941
949
  ).toBe("go ahead");
950
+
951
+ // A tokenless laptop request is decided by the trusted-local operator,
952
+ // recorded exactly as its audit actor is (#1385).
953
+ const operator = trustedLocalIdentity().identityId;
954
+ expect(tc?.approvedBy).toBe(operator);
955
+ expect(
956
+ decided?.payload.case === "decided"
957
+ ? decided.payload.value.decidedBy
958
+ : "",
959
+ ).toBe(operator);
942
960
  });
943
961
 
944
962
  it("is idempotent for a repeated identical submit and refuses a conflicting change", async () => {
@@ -1331,80 +1349,154 @@ describe("the engine-connected signal arms (stubbed engine, direct calls)", () =
1331
1349
  });
1332
1350
  });
1333
1351
 
1352
+ describe("the decider is the authorized caller (direct calls, #1385)", () => {
1353
+ const decider = testCallerIdentity({ identityId: "usr_decider" });
1354
+
1355
+ function deps() {
1356
+ return {
1357
+ store: server.store,
1358
+ logger: silentLogger,
1359
+ authorizer: newPermissiveSingleTeamAuthorizer(),
1360
+ broker: server.agentExecutionStreamBroker,
1361
+ engineState: () => ENGINE_DISCONNECTED,
1362
+ gateSteps: new Map(),
1363
+ statusObservers: [],
1364
+ };
1365
+ }
1366
+
1367
+ function decidedByOf(
1368
+ execution: AgentExecution,
1369
+ toolCallId: string,
1370
+ ): string | undefined {
1371
+ const event = (execution.status?.approvalEventStream?.events ?? []).find(
1372
+ (ev) =>
1373
+ ev.approvalRequestId === toolCallId && ev.payload.case === "decided",
1374
+ );
1375
+ return event?.payload.case === "decided"
1376
+ ? event.payload.value.decidedBy
1377
+ : undefined;
1378
+ }
1379
+
1380
+ it("an APPROVE records the caller on the tool call and its decision event", async () => {
1381
+ const id = await seed(gatedSeed());
1382
+
1383
+ const result = await submitApproval(
1384
+ deps(),
1385
+ create(SubmitApprovalInputSchema, {
1386
+ agentExecutionId: id,
1387
+ toolCallId: "tc-1",
1388
+ action: ApprovalAction.APPROVE,
1389
+ }),
1390
+ decider,
1391
+ );
1392
+
1393
+ expect(result.status?.messages[0]?.toolCalls[0]?.approvedBy).toBe(
1394
+ "usr_decider",
1395
+ );
1396
+ expect(decidedByOf(result, "tc-1")).toBe("usr_decider");
1397
+ });
1398
+
1399
+ it("APPROVE_ALL records the caller on the clicked call and every co-pending call it settles", async () => {
1400
+ const id = await seed(
1401
+ gatedSeed({
1402
+ toolCalls: [
1403
+ { id: "tc-shell-1", name: "shell" },
1404
+ { id: "tc-shell-2", name: "bash" },
1405
+ { id: "tc-write", name: "Write" },
1406
+ ],
1407
+ }),
1408
+ );
1409
+
1410
+ const result = await submitApproval(
1411
+ deps(),
1412
+ create(SubmitApprovalInputSchema, {
1413
+ agentExecutionId: id,
1414
+ toolCallId: "tc-shell-1",
1415
+ action: ApprovalAction.APPROVE_ALL,
1416
+ }),
1417
+ decider,
1418
+ );
1419
+
1420
+ const byId = new Map(
1421
+ (result.status?.messages[0]?.toolCalls ?? []).map((tc) => [tc.id, tc]),
1422
+ );
1423
+ for (const settled of ["tc-shell-1", "tc-shell-2"]) {
1424
+ expect(byId.get(settled)?.approvedBy, settled).toBe("usr_decider");
1425
+ expect(decidedByOf(result, settled), settled).toBe("usr_decider");
1426
+ }
1427
+ // The call of another lease class is undecided, so nobody is recorded.
1428
+ expect(byId.get("tc-write")?.approvedBy).toBe("");
1429
+ });
1430
+
1431
+ it("a file decision records the caller as the reviewer, at either scope", async () => {
1432
+ for (const scope of [
1433
+ FileDecisionScope.CHANGE_SET,
1434
+ FileDecisionScope.FILE,
1435
+ ]) {
1436
+ counter += 1;
1437
+ const id = `aexec_reviewer_${counter}`;
1438
+ const slug = `exec-${id.replaceAll("_", "-")}`;
1439
+ const changeSetId = `cs_reviewer_${counter}`;
1440
+ const { status, change, aggregate } = fileReviewSeed(id, changeSetId);
1441
+ await seed({
1442
+ apiVersion: API_VERSION,
1443
+ kind: KIND,
1444
+ metadata: { id, name: slug, slug, org: ORG },
1445
+ spec: { message: "Say hello." },
1446
+ status,
1447
+ });
1448
+
1449
+ const result = await submitFileDecision(
1450
+ deps(),
1451
+ create(SubmitFileDecisionInputSchema, {
1452
+ agentExecutionId: id,
1453
+ changeSetId,
1454
+ scope,
1455
+ action: FileDecisionAction.APPROVE,
1456
+ ...(scope === FileDecisionScope.FILE
1457
+ ? { fileChangeId: change.id, expectedDigest: change.fileDigest }
1458
+ : { expectedDigest: aggregate }),
1459
+ }),
1460
+ decider,
1461
+ );
1462
+
1463
+ const decisions =
1464
+ result.status?.fileChangeSets.find((cs) => cs.id === changeSetId)
1465
+ ?.decisions ?? [];
1466
+ expect(decisions, FileDecisionScope[scope]).toHaveLength(1);
1467
+ expect(decisions[0]?.reviewerId, FileDecisionScope[scope]).toBe(
1468
+ "usr_decider",
1469
+ );
1470
+ }
1471
+ });
1472
+ });
1473
+
1334
1474
  describe("submitFileDecision over the wire", () => {
1335
1475
  function ledgerSeed(): {
1336
1476
  init: MessageInitShape<typeof AgentExecutionSchema> & {
1337
1477
  metadata: { id: string };
1338
1478
  };
1339
1479
  changeSetId: string;
1340
- change: ReturnType<typeof buildChange>;
1341
1480
  aggregate: string;
1342
1481
  } {
1343
1482
  counter += 1;
1344
1483
  const id = `aexec_review_${counter}`;
1345
1484
  const slug = `exec-${id.replaceAll("_", "-")}`;
1346
1485
  const changeSetId = `cs_${counter}`;
1347
- const change = buildChange();
1348
- const aggregate = aggregateDigest([change]);
1486
+ const { status, aggregate } = fileReviewSeed(id, changeSetId);
1349
1487
  return {
1350
1488
  init: {
1351
1489
  apiVersion: API_VERSION,
1352
1490
  kind: KIND,
1353
1491
  metadata: { id, name: slug, slug, org: ORG },
1354
1492
  spec: { message: "Say hello." },
1355
- status: {
1356
- phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
1357
- fileReviewEventStream: {
1358
- executionId: id,
1359
- events: [
1360
- {
1361
- eventId: `${changeSetId}:${changeSetId}:BASELINE`,
1362
- changeSetId,
1363
- eventType: FileReviewEventType.BASELINE_CAPTURED,
1364
- actor: "runner",
1365
- payload: {
1366
- case: "baselineCaptured",
1367
- value: { turnId: "turn-1", harnessId: "harness-1" },
1368
- },
1369
- },
1370
- {
1371
- eventId: `${changeSetId}:${changeSetId}:CANDIDATE`,
1372
- changeSetId,
1373
- eventType: FileReviewEventType.CANDIDATE_CAPTURED,
1374
- actor: "runner",
1375
- payload: {
1376
- case: "candidateCaptured",
1377
- value: {
1378
- changes: [change],
1379
- aggregateDigest: aggregate,
1380
- diffCompleteness: DiffCompleteness.COMPLETE,
1381
- },
1382
- },
1383
- },
1384
- ],
1385
- },
1386
- },
1493
+ status,
1387
1494
  },
1388
1495
  changeSetId,
1389
- change,
1390
1496
  aggregate,
1391
1497
  };
1392
1498
  }
1393
1499
 
1394
- function buildChange() {
1395
- const change = create(CapturedFileChangeSchema, {
1396
- id: "fc-1",
1397
- pathBefore: "src/a.ts",
1398
- pathAfter: "src/a.ts",
1399
- kind: FileChangeKind.MODIFY,
1400
- beforeSha256: "a".repeat(64),
1401
- afterSha256: "b".repeat(64),
1402
- diffComplete: true,
1403
- });
1404
- change.fileDigest = fileDigest(change);
1405
- return change;
1406
- }
1407
-
1408
1500
  it("records a CHANGE_SET keep, projects DECIDED, and is idempotent on resubmit", async () => {
1409
1501
  const { init, changeSetId, aggregate } = ledgerSeed();
1410
1502
  const id = await seed(init);
@@ -12,11 +12,15 @@
12
12
  * (stigmer#1387, stigmer#1397): recall is the run's person's own
13
13
  * confirmed facts, behind the first-party gate, the org switch and the
14
14
  * person's own, and user_context is that person's standing context — the
15
- * retired Java steps' gates, in their order.
15
+ * retired Java steps' gates, in their order. The organization's half is
16
+ * pinned against the composed visitor classifier (stigmer/stigmer#1401):
17
+ * every lane keeps it but a visitor, whose run never reads the
18
+ * organization, and a classifier that throws withholds it.
16
19
  */
17
20
  import { testCallerIdentity } from "../../../pipeline/__tests__/support.js";
18
21
  import { IdentityAccountSchema } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/api_pb";
19
22
  import type { CallerIdentity } from "../../../extensions/identity.js";
23
+ import type { VisitorClassifier } from "../../../extensions/visitor-classifier.js";
20
24
  import type { AccountsByCaller } from "../../identityaccount/resolve.js";
21
25
  import { fakeIdentityAccountStore } from "../../identityaccount/__tests__/support.js";
22
26
  import { mkdtempSync, rmSync } from "node:fs";
@@ -57,6 +61,7 @@ import { OrganizationSchema } from "@stigmer/protos/ai/stigmer/tenancy/organizat
57
61
 
58
62
  import { createLogger } from "../../../boot/logger.js";
59
63
  import { RequestContext } from "../../../pipeline/request-context.js";
64
+ import { LIST_INDEXES } from "../../../boot/list-indexes.js";
60
65
  import { SqliteStore } from "../../../store/sqlite/store.js";
61
66
  import type { Store } from "../../../store/interface.js";
62
67
 
@@ -86,7 +91,9 @@ let store: Store;
86
91
 
87
92
  beforeEach(() => {
88
93
  dir = mkdtempSync(path.join(tmpdir(), "aexec-create-test-"));
89
- store = SqliteStore.open(path.join(dir, "stigmer.db"));
94
+ store = SqliteStore.open(path.join(dir, "stigmer.db"), undefined, {
95
+ listIndexes: LIST_INDEXES,
96
+ });
90
97
  });
91
98
 
92
99
  afterEach(() => {
@@ -403,11 +410,11 @@ function failingGetStore(): Store {
403
410
  });
404
411
  }
405
412
 
406
- /** Wraps the real store but fails every listResources (the scan-fault arm). */
407
- function failingListStore(): Store {
413
+ /** Wraps the real store but fails every queryResources (the read-fault arm). */
414
+ function failingQueryStore(): Store {
408
415
  return new Proxy(store, {
409
416
  get(target, prop, receiver) {
410
- if (prop === "listResources") {
417
+ if (prop === "queryResources") {
411
418
  return async () => {
412
419
  throw new Error("simulated store fault");
413
420
  };
@@ -493,6 +500,108 @@ describe("newComposeDeclaredPreferencesStep", () => {
493
500
  }
494
501
  });
495
502
 
503
+ describe("newComposeDeclaredPreferencesStep for visitors", () => {
504
+ const ORG_CONTEXT = "We deploy to us-east-1.";
505
+ const channelSender = testCallerIdentity({ callerClass: "channel" });
506
+ const member = testCallerIdentity();
507
+
508
+ /** The hosted edition's shape: a visitor is a caller of a visitor class. */
509
+ const channelIsVisitor: VisitorClassifier = {
510
+ isVisitor: (caller) => caller.callerClass === "channel",
511
+ };
512
+
513
+ /** Wraps the real store, counting organization reads. */
514
+ function countingStore(): { store: Store; orgReads: () => number } {
515
+ let reads = 0;
516
+ const counted = new Proxy(store, {
517
+ get(target, prop, receiver) {
518
+ if (prop === "getResource") {
519
+ return (kind: ApiResourceKind, ...rest: unknown[]) => {
520
+ if (kind === ApiResourceKind.organization) {
521
+ reads += 1;
522
+ }
523
+ return Reflect.apply(target.getResource, target, [kind, ...rest]);
524
+ };
525
+ }
526
+ return Reflect.get(target, prop, receiver);
527
+ },
528
+ });
529
+ return { store: counted, orgReads: () => reads };
530
+ }
531
+
532
+ async function compose(
533
+ caller: CallerIdentity,
534
+ classifier: VisitorClassifier | undefined,
535
+ options: { store?: Store; logger?: typeof silentLogger } = {},
536
+ ) {
537
+ await seedOrg("test-org", ORG_CONTEXT);
538
+ const step = newComposeDeclaredPreferencesStep(
539
+ options.store ?? store,
540
+ options.logger ?? silentLogger,
541
+ undefined,
542
+ classifier,
543
+ );
544
+ const execution = newExecution("ses_1", "agt_1");
545
+ // The injection attempt: the field is server-owned on this path too.
546
+ execution.spec!.declaredPreferences = create(DeclaredPreferencesSchema, {
547
+ orgContext: "injected org context",
548
+ });
549
+ const ctx = newContext(execution, caller);
550
+ await step.execute(ctx);
551
+ return ctx.newState.spec?.declaredPreferences;
552
+ }
553
+
554
+ it("composes no organization context for a visitor, and never reads the organization", async () => {
555
+ const counted = countingStore();
556
+ const got = await compose(channelSender, channelIsVisitor, {
557
+ store: counted.store,
558
+ });
559
+ expect(got, "server-owned field stamped for a visitor").toBeDefined();
560
+ expect(got?.orgContext).toBe("");
561
+ expect(counted.orgReads()).toBe(0);
562
+ });
563
+
564
+ it("keeps the organization's context for a member when a classifier is composed", async () => {
565
+ const got = await compose(member, channelIsVisitor);
566
+ expect(got?.orgContext).toBe(ORG_CONTEXT);
567
+ });
568
+
569
+ it("keeps the organization's context for every caller when no classifier is composed", async () => {
570
+ const got = await compose(channelSender, undefined);
571
+ expect(got?.orgContext).toBe(ORG_CONTEXT);
572
+ });
573
+
574
+ it("classifies a propagated visitor as a visitor (in-process keeps the class)", async () => {
575
+ const got = await compose(
576
+ testCallerIdentity({ callerClass: "channel", origin: "in-process" }),
577
+ channelIsVisitor,
578
+ );
579
+ expect(got?.orgContext).toBe("");
580
+ });
581
+
582
+ it("withholds the organization's context when the classifier throws, and logs it at ERROR", async () => {
583
+ const lines: string[] = [];
584
+ const logger = createLogger({
585
+ level: "error",
586
+ pretty: false,
587
+ write: (line) => lines.push(line),
588
+ });
589
+ const got = await compose(
590
+ member,
591
+ {
592
+ isVisitor: () => {
593
+ throw new Error("classifier fault");
594
+ },
595
+ },
596
+ { logger },
597
+ );
598
+ expect(got?.orgContext).toBe("");
599
+ expect(lines).toHaveLength(1);
600
+ expect(lines[0]).toContain("Visitor classifier failed");
601
+ expect(lines[0]).toContain("classifier fault");
602
+ });
603
+ });
604
+
496
605
  // ---------------------------------------------------------------------------
497
606
  // ComposeRecalledMemories (compose_recalled_memories_step_test.go).
498
607
  // ---------------------------------------------------------------------------
@@ -567,7 +676,7 @@ describe("newComposeRecalledMemoriesStep", () => {
567
676
  memoryEnabled?: boolean;
568
677
  memories?: SeededMemory[];
569
678
  failingGet?: boolean;
570
- failingList?: boolean;
679
+ failingQuery?: boolean;
571
680
  wantEnabled: boolean;
572
681
  wantMemoryIds: string[];
573
682
  }> = [
@@ -716,11 +825,11 @@ describe("newComposeRecalledMemoriesStep", () => {
716
825
  wantMemoryIds: [],
717
826
  },
718
827
  {
719
- name: "memory scan fault -> DISABLED, never enabled-with-zero-facts",
828
+ name: "memory read fault -> DISABLED, never enabled-with-zero-facts",
720
829
  orgId: "test-org",
721
830
  seedOrg: true,
722
831
  memoryEnabled: true,
723
- failingList: true,
832
+ failingQuery: true,
724
833
  wantEnabled: false,
725
834
  wantMemoryIds: [],
726
835
  },
@@ -748,8 +857,8 @@ describe("newComposeRecalledMemoriesStep", () => {
748
857
  if (tt.failingGet) {
749
858
  stepStore = failingGetStore();
750
859
  }
751
- if (tt.failingList) {
752
- stepStore = failingListStore();
860
+ if (tt.failingQuery) {
861
+ stepStore = failingQueryStore();
753
862
  }
754
863
  const step = newComposeRecalledMemoriesStep(stepStore, silentLogger);
755
864
 
@@ -895,6 +1004,26 @@ describe("the compose steps where callers are persons", () => {
895
1004
  state: MemoryLifecycleState.lifecycle_state_proposed,
896
1005
  createdAt: new Date("2026-09-04T00:00:00Z"),
897
1006
  });
1007
+ // Carol's own confirmed fact in another organization: the subject key
1008
+ // reads her rows everywhere, and the org narrows them (stigmer#1405).
1009
+ await seedMemory({
1010
+ id: "mem_carol_elsewhere",
1011
+ orgId: "other-org",
1012
+ subject: CAROL,
1013
+ content: "Carol's, elsewhere",
1014
+ state: confirmed,
1015
+ createdAt: new Date("2026-08-15T00:00:00Z"),
1016
+ });
1017
+ // Seeded last and dated first: recall's order is created_at, not the
1018
+ // index's newest-first read or the write order.
1019
+ await seedMemory({
1020
+ id: "mem_carol_first",
1021
+ orgId: "test-org",
1022
+ subject: CAROL,
1023
+ content: "Carol's first",
1024
+ state: confirmed,
1025
+ createdAt: new Date("2026-08-31T00:00:00Z"),
1026
+ });
898
1027
  }
899
1028
 
900
1029
  async function recall(
@@ -907,11 +1036,14 @@ describe("the compose steps where callers are persons", () => {
907
1036
  return ctx.newState.spec?.recalledMemories;
908
1037
  }
909
1038
 
910
- it("recalls exactly the run's person's confirmed facts", async () => {
1039
+ it("recalls exactly the run's person's confirmed facts in its organization, oldest first", async () => {
911
1040
  await seedRecallRows();
912
1041
  const got = await recall(directory({ memoryEnabled: true }), carol);
913
1042
  expect(got?.enabled).toBe(true);
914
- expect(got?.facts.map((f) => f.memoryId)).toEqual(["mem_carol"]);
1043
+ expect(got?.facts.map((f) => f.memoryId)).toEqual([
1044
+ "mem_carol_first",
1045
+ "mem_carol",
1046
+ ]);
915
1047
  });
916
1048
 
917
1049
  it("recalls nothing and offers no remember tool when the person's own switch is off", async () => {
@@ -954,12 +1086,14 @@ describe("the compose steps where callers are persons", () => {
954
1086
  async function declared(
955
1087
  accounts: AccountsByCaller | undefined,
956
1088
  caller: CallerIdentity,
1089
+ classifier?: VisitorClassifier,
957
1090
  ) {
958
1091
  await seedOrg("test-org", "We deploy to us-east-1.");
959
1092
  const step = newComposeDeclaredPreferencesStep(
960
1093
  store,
961
1094
  silentLogger,
962
1095
  accounts,
1096
+ classifier,
963
1097
  );
964
1098
  const execution = newExecution("ses_1", "agt_1");
965
1099
  execution.spec!.declaredPreferences = create(DeclaredPreferencesSchema, {
@@ -1001,6 +1135,35 @@ describe("the compose steps where callers are persons", () => {
1001
1135
  expect(got?.userContext).toBe("");
1002
1136
  });
1003
1137
  }
1138
+
1139
+ // The hosted edition's classifier composed beside the person directory:
1140
+ // the channel sender is its one visitor here, so it alone loses the
1141
+ // organization's half; every other lane keeps it (stigmer/stigmer#1401).
1142
+ const hostedClassifier: VisitorClassifier = {
1143
+ isVisitor: (caller) => caller.callerClass === "channel",
1144
+ };
1145
+ for (const [name, caller] of notFirstParty) {
1146
+ const visitor = hostedClassifier.isVisitor(caller);
1147
+ it(`${visitor ? "withholds" : "keeps"} the organization's context for ${name} under a visitor classifier`, async () => {
1148
+ const got = await declared(
1149
+ directory({ standingContext: "Call me Carol." }),
1150
+ caller,
1151
+ hostedClassifier,
1152
+ );
1153
+ expect(got?.orgContext).toBe(visitor ? "" : "We deploy to us-east-1.");
1154
+ expect(got?.userContext).toBe("");
1155
+ });
1156
+ }
1157
+
1158
+ it("keeps both halves for Carol herself under a visitor classifier", async () => {
1159
+ const got = await declared(
1160
+ directory({ standingContext: "Call me Carol." }),
1161
+ carol,
1162
+ hostedClassifier,
1163
+ );
1164
+ expect(got?.orgContext).toBe("We deploy to us-east-1.");
1165
+ expect(got?.userContext).toBe("Call me Carol.");
1166
+ });
1004
1167
  });
1005
1168
 
1006
1169
  // ---------------------------------------------------------------------------
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Test seed for an agent execution parked on file review: the status block
3
+ * a runner leaves behind when it offers one captured change set — the
4
+ * BASELINE and CANDIDATE events on the file-review ledger, one complete
5
+ * MODIFY change with real digests, the execution WAITING_FOR_APPROVAL —
6
+ * so a submitFileDecision against it passes the completeness and digest
7
+ * gates. Shared by every suite that decides on a seeded change set (the
8
+ * agentexecution wire suite, the workflow forwarding suite, the forwarded
9
+ * attribution test) so the ledger shape lives once.
10
+ */
11
+ import { create } from "@bufbuild/protobuf";
12
+ import type { MessageInitShape } from "@bufbuild/protobuf";
13
+
14
+ import type { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
15
+ import {
16
+ DiffCompleteness,
17
+ ExecutionPhase,
18
+ FileChangeKind,
19
+ FileReviewEventType,
20
+ } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
21
+ import { CapturedFileChangeSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
22
+ import type { CapturedFileChange } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
23
+
24
+ import { aggregateDigest, fileDigest } from "../filereview/digest.js";
25
+
26
+ export interface FileReviewSeed {
27
+ /** The execution status to seed: parked, with the change set captured. */
28
+ readonly status: MessageInitShape<typeof AgentExecutionStatusSchema>;
29
+ readonly change: CapturedFileChange;
30
+ /** The change set's aggregate digest — a CHANGE_SET decision's expected_digest. */
31
+ readonly aggregate: string;
32
+ }
33
+
34
+ /** One complete MODIFY of `src/a.ts`, its file digest computed. */
35
+ export function reviewableChange(): CapturedFileChange {
36
+ const change = create(CapturedFileChangeSchema, {
37
+ id: "fc-1",
38
+ pathBefore: "src/a.ts",
39
+ pathAfter: "src/a.ts",
40
+ kind: FileChangeKind.MODIFY,
41
+ beforeSha256: "a".repeat(64),
42
+ afterSha256: "b".repeat(64),
43
+ diffComplete: true,
44
+ });
45
+ change.fileDigest = fileDigest(change);
46
+ return change;
47
+ }
48
+
49
+ export function fileReviewSeed(
50
+ executionId: string,
51
+ changeSetId: string,
52
+ ): FileReviewSeed {
53
+ const change = reviewableChange();
54
+ const aggregate = aggregateDigest([change]);
55
+ return {
56
+ status: {
57
+ phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
58
+ fileReviewEventStream: {
59
+ executionId,
60
+ events: [
61
+ {
62
+ eventId: `${changeSetId}:${changeSetId}:BASELINE`,
63
+ changeSetId,
64
+ eventType: FileReviewEventType.BASELINE_CAPTURED,
65
+ actor: "runner",
66
+ payload: {
67
+ case: "baselineCaptured",
68
+ value: { turnId: "turn-1", harnessId: "harness-1" },
69
+ },
70
+ },
71
+ {
72
+ eventId: `${changeSetId}:${changeSetId}:CANDIDATE`,
73
+ changeSetId,
74
+ eventType: FileReviewEventType.CANDIDATE_CAPTURED,
75
+ actor: "runner",
76
+ payload: {
77
+ case: "candidateCaptured",
78
+ value: {
79
+ changes: [change],
80
+ aggregateDigest: aggregate,
81
+ diffCompleteness: DiffCompleteness.COMPLETE,
82
+ },
83
+ },
84
+ },
85
+ ],
86
+ },
87
+ },
88
+ change,
89
+ aggregate,
90
+ };
91
+ }
@@ -39,6 +39,7 @@ import type { ListReadScope } from "../../extensions/list-read-scope.js";
39
39
  import type { AccountsByCaller } from "../identityaccount/resolve.js";
40
40
  import type { ResourceAuthorizationLifecycle } from "../../extensions/resource-authorization.js";
41
41
  import type { ResolvedGateSteps } from "../../extensions/gate-slots.js";
42
+ import type { VisitorClassifier } from "../../extensions/visitor-classifier.js";
42
43
  import { stepsForSlot } from "../../extensions/gate-slots.js";
43
44
  import type {
44
45
  AgentExecutionResponseDecorator,
@@ -165,6 +166,12 @@ export interface AgentExecutionControllerDeps {
165
166
  * empty-string sentinel.
166
167
  */
167
168
  readonly personAccounts: AccountsByCaller | undefined;
169
+ /**
170
+ * The composed visitor classifier (stigmer/stigmer#1401) —
171
+ * ComposeDeclaredPreferences composes no organization standing context
172
+ * onto a visitor's run; undefined = nobody is a visitor (open source).
173
+ */
174
+ readonly visitorClassifier: VisitorClassifier | undefined;
168
175
  /**
169
176
  * The shared broadcast fabric for subscribe streams. ONE instance spans
170
177
  * both routers (serving + in-process) — see stream-broker.ts; the
@@ -379,6 +386,7 @@ async function createExecution(
379
386
  deps.store,
380
387
  deps.logger,
381
388
  deps.personAccounts,
389
+ deps.visitorClassifier,
382
390
  ),
383
391
  )
384
392
  .addStep(