@stigmer/server 3.20.0 → 3.22.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 (257) hide show
  1. package/dist/authorization/evaluator.d.ts +7 -1
  2. package/dist/authorization/evaluator.d.ts.map +1 -1
  3. package/dist/authorization/evaluator.js.map +1 -1
  4. package/dist/authorization/list-read-scope.d.ts.map +1 -1
  5. package/dist/authorization/list-read-scope.js +19 -11
  6. package/dist/authorization/list-read-scope.js.map +1 -1
  7. package/dist/authorization/model/organization.d.ts.map +1 -1
  8. package/dist/authorization/model/organization.js +2 -0
  9. package/dist/authorization/model/organization.js.map +1 -1
  10. package/dist/boot/compose.d.ts.map +1 -1
  11. package/dist/boot/compose.js +0 -1
  12. package/dist/boot/compose.js.map +1 -1
  13. package/dist/boot/inprocess.d.ts +0 -2
  14. package/dist/boot/inprocess.d.ts.map +1 -1
  15. package/dist/boot/inprocess.js +0 -6
  16. package/dist/boot/inprocess.js.map +1 -1
  17. package/dist/domain/agent/controller.d.ts +2 -2
  18. package/dist/domain/agent/controller.d.ts.map +1 -1
  19. package/dist/domain/agent/controller.js +3 -17
  20. package/dist/domain/agent/controller.js.map +1 -1
  21. package/dist/domain/agent/steps.d.ts +0 -1
  22. package/dist/domain/agent/steps.d.ts.map +1 -1
  23. package/dist/domain/agent/steps.js +1 -40
  24. package/dist/domain/agent/steps.js.map +1 -1
  25. package/dist/domain/agentchannel/controller.d.ts.map +1 -1
  26. package/dist/domain/agentchannel/controller.js +6 -1
  27. package/dist/domain/agentchannel/controller.js.map +1 -1
  28. package/dist/domain/agentchannel/steps.d.ts +19 -0
  29. package/dist/domain/agentchannel/steps.d.ts.map +1 -1
  30. package/dist/domain/agentchannel/steps.js +32 -0
  31. package/dist/domain/agentchannel/steps.js.map +1 -1
  32. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  33. package/dist/domain/agentexecution/controller.js +7 -9
  34. package/dist/domain/agentexecution/controller.js.map +1 -1
  35. package/dist/domain/agentexecution/create-execution-context-step.d.ts +0 -2
  36. package/dist/domain/agentexecution/create-execution-context-step.d.ts.map +1 -1
  37. package/dist/domain/agentexecution/create-execution-context-step.js +179 -60
  38. package/dist/domain/agentexecution/create-execution-context-step.js.map +1 -1
  39. package/dist/domain/agentexecution/create-steps.d.ts +16 -31
  40. package/dist/domain/agentexecution/create-steps.d.ts.map +1 -1
  41. package/dist/domain/agentexecution/create-steps.js +36 -102
  42. package/dist/domain/agentexecution/create-steps.js.map +1 -1
  43. package/dist/domain/agentexecution/run-target.d.ts +7 -3
  44. package/dist/domain/agentexecution/run-target.d.ts.map +1 -1
  45. package/dist/domain/agentexecution/run-target.js.map +1 -1
  46. package/dist/domain/agentinstance/controller.d.ts +5 -5
  47. package/dist/domain/agentinstance/controller.d.ts.map +1 -1
  48. package/dist/domain/agentinstance/controller.js +6 -1
  49. package/dist/domain/agentinstance/controller.js.map +1 -1
  50. package/dist/domain/agentinstance/steps.d.ts +43 -8
  51. package/dist/domain/agentinstance/steps.d.ts.map +1 -1
  52. package/dist/domain/agentinstance/steps.js +71 -8
  53. package/dist/domain/agentinstance/steps.js.map +1 -1
  54. package/dist/domain/agentshare/controller.d.ts.map +1 -1
  55. package/dist/domain/agentshare/controller.js +7 -1
  56. package/dist/domain/agentshare/controller.js.map +1 -1
  57. package/dist/domain/agentshare/steps.d.ts +58 -0
  58. package/dist/domain/agentshare/steps.d.ts.map +1 -1
  59. package/dist/domain/agentshare/steps.js +109 -4
  60. package/dist/domain/agentshare/steps.js.map +1 -1
  61. package/dist/domain/artifact/controller.js +21 -25
  62. package/dist/domain/artifact/controller.js.map +1 -1
  63. package/dist/domain/channelapp/controller.d.ts.map +1 -1
  64. package/dist/domain/channelapp/controller.js +2 -0
  65. package/dist/domain/channelapp/controller.js.map +1 -1
  66. package/dist/domain/environment/controller.d.ts.map +1 -1
  67. package/dist/domain/environment/controller.js +2 -0
  68. package/dist/domain/environment/controller.js.map +1 -1
  69. package/dist/domain/environment/personal.d.ts +42 -0
  70. package/dist/domain/environment/personal.d.ts.map +1 -0
  71. package/dist/domain/environment/personal.js +96 -0
  72. package/dist/domain/environment/personal.js.map +1 -0
  73. package/dist/domain/executioncontext/controller.d.ts.map +1 -1
  74. package/dist/domain/executioncontext/controller.js +2 -0
  75. package/dist/domain/executioncontext/controller.js.map +1 -1
  76. package/dist/domain/executioncontext/steps.d.ts.map +1 -1
  77. package/dist/domain/executioncontext/steps.js +2 -1
  78. package/dist/domain/executioncontext/steps.js.map +1 -1
  79. package/dist/domain/mcpserver/connect.d.ts +0 -2
  80. package/dist/domain/mcpserver/connect.d.ts.map +1 -1
  81. package/dist/domain/mcpserver/connect.js +24 -79
  82. package/dist/domain/mcpserver/connect.js.map +1 -1
  83. package/dist/domain/mcpserver/controller.d.ts.map +1 -1
  84. package/dist/domain/mcpserver/controller.js +2 -0
  85. package/dist/domain/mcpserver/controller.js.map +1 -1
  86. package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
  87. package/dist/domain/mcpserver/start-connect.js +8 -7
  88. package/dist/domain/mcpserver/start-connect.js.map +1 -1
  89. package/dist/domain/memory/controller.d.ts.map +1 -1
  90. package/dist/domain/memory/controller.js +6 -1
  91. package/dist/domain/memory/controller.js.map +1 -1
  92. package/dist/domain/memory/steps.d.ts +23 -0
  93. package/dist/domain/memory/steps.d.ts.map +1 -1
  94. package/dist/domain/memory/steps.js +35 -0
  95. package/dist/domain/memory/steps.js.map +1 -1
  96. package/dist/domain/oauthapp/controller.d.ts.map +1 -1
  97. package/dist/domain/oauthapp/controller.js +2 -0
  98. package/dist/domain/oauthapp/controller.js.map +1 -1
  99. package/dist/domain/plugin/controller.d.ts.map +1 -1
  100. package/dist/domain/plugin/controller.js +5 -24
  101. package/dist/domain/plugin/controller.js.map +1 -1
  102. package/dist/domain/plugin/overlay/sanitize.js +2 -2
  103. package/dist/domain/schedule/controller.d.ts.map +1 -1
  104. package/dist/domain/schedule/controller.js +7 -1
  105. package/dist/domain/schedule/controller.js.map +1 -1
  106. package/dist/domain/schedule/steps.d.ts +19 -0
  107. package/dist/domain/schedule/steps.d.ts.map +1 -1
  108. package/dist/domain/schedule/steps.js +32 -0
  109. package/dist/domain/schedule/steps.js.map +1 -1
  110. package/dist/domain/session/controller.d.ts +0 -7
  111. package/dist/domain/session/controller.d.ts.map +1 -1
  112. package/dist/domain/session/controller.js +11 -16
  113. package/dist/domain/session/controller.js.map +1 -1
  114. package/dist/domain/session/run-target.d.ts +9 -8
  115. package/dist/domain/session/run-target.d.ts.map +1 -1
  116. package/dist/domain/session/run-target.js.map +1 -1
  117. package/dist/domain/session/steps.d.ts +8 -36
  118. package/dist/domain/session/steps.d.ts.map +1 -1
  119. package/dist/domain/session/steps.js +27 -172
  120. package/dist/domain/session/steps.js.map +1 -1
  121. package/dist/domain/skill/controller.d.ts.map +1 -1
  122. package/dist/domain/skill/controller.js +8 -17
  123. package/dist/domain/skill/controller.js.map +1 -1
  124. package/dist/domain/workflow/controller.d.ts.map +1 -1
  125. package/dist/domain/workflow/controller.js +30 -107
  126. package/dist/domain/workflow/controller.js.map +1 -1
  127. package/dist/domain/workflow/version-resolution.d.ts +5 -0
  128. package/dist/domain/workflow/version-resolution.d.ts.map +1 -0
  129. package/dist/domain/workflow/version-resolution.js +113 -0
  130. package/dist/domain/workflow/version-resolution.js.map +1 -0
  131. package/dist/domain/workflowexecution/create-steps.d.ts +4 -3
  132. package/dist/domain/workflowexecution/create-steps.d.ts.map +1 -1
  133. package/dist/domain/workflowexecution/create-steps.js +4 -3
  134. package/dist/domain/workflowexecution/create-steps.js.map +1 -1
  135. package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
  136. package/dist/domain/workflowinstance/controller.js +6 -1
  137. package/dist/domain/workflowinstance/controller.js.map +1 -1
  138. package/dist/domain/workflowinstance/steps.d.ts +20 -0
  139. package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
  140. package/dist/domain/workflowinstance/steps.js +39 -0
  141. package/dist/domain/workflowinstance/steps.js.map +1 -1
  142. package/dist/extensions/identity.d.ts +19 -0
  143. package/dist/extensions/identity.d.ts.map +1 -1
  144. package/dist/extensions/identity.js +22 -3
  145. package/dist/extensions/identity.js.map +1 -1
  146. package/dist/extensions/list-read-scope.d.ts +41 -7
  147. package/dist/extensions/list-read-scope.d.ts.map +1 -1
  148. package/dist/extensions/list-read-scope.js +13 -2
  149. package/dist/extensions/list-read-scope.js.map +1 -1
  150. package/dist/pipeline/apiresource-labels.d.ts +2 -2
  151. package/dist/pipeline/apiresource-labels.js +2 -2
  152. package/dist/pipeline/errors.d.ts +2 -2
  153. package/dist/pipeline/errors.js +2 -2
  154. package/dist/pipeline/steps/authorize-resolved-target.d.ts +88 -0
  155. package/dist/pipeline/steps/authorize-resolved-target.d.ts.map +1 -0
  156. package/dist/pipeline/steps/authorize-resolved-target.js +36 -0
  157. package/dist/pipeline/steps/authorize-resolved-target.js.map +1 -0
  158. package/dist/pipeline/steps/authorize.d.ts +27 -0
  159. package/dist/pipeline/steps/authorize.d.ts.map +1 -1
  160. package/dist/pipeline/steps/authorize.js +49 -10
  161. package/dist/pipeline/steps/authorize.js.map +1 -1
  162. package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
  163. package/dist/pipeline/steps/guard-memory-capture.js +2 -1
  164. package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
  165. package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
  166. package/dist/pipeline/steps/guard-reserved-labels.js +12 -12
  167. package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
  168. package/dist/pipeline/steps/helpers.d.ts +9 -5
  169. package/dist/pipeline/steps/helpers.d.ts.map +1 -1
  170. package/dist/pipeline/steps/helpers.js +11 -15
  171. package/dist/pipeline/steps/helpers.js.map +1 -1
  172. package/dist/pipeline/steps/version-history.d.ts +11 -0
  173. package/dist/pipeline/steps/version-history.d.ts.map +1 -1
  174. package/dist/pipeline/steps/version-history.js +26 -0
  175. package/dist/pipeline/steps/version-history.js.map +1 -1
  176. package/package.json +6 -6
  177. package/src/authorization/__tests__/list-read-scope.test.ts +23 -12
  178. package/src/authorization/__tests__/skip-lane-inventory.test.ts +160 -0
  179. package/src/authorization/__tests__/wire-permissions.test.ts +5 -5
  180. package/src/authorization/evaluator.ts +7 -0
  181. package/src/authorization/list-read-scope.ts +22 -11
  182. package/src/authorization/model/__tests__/registry.test.ts +2 -0
  183. package/src/authorization/model/organization.ts +2 -0
  184. package/src/boot/compose.ts +0 -1
  185. package/src/boot/inprocess.ts +0 -9
  186. package/src/domain/agent/__tests__/agent.test.ts +0 -68
  187. package/src/domain/agent/controller.ts +11 -36
  188. package/src/domain/agent/steps.ts +1 -60
  189. package/src/domain/agentchannel/__tests__/create-authorization.test.ts +58 -0
  190. package/src/domain/agentchannel/controller.ts +19 -0
  191. package/src/domain/agentchannel/steps.ts +40 -0
  192. package/src/domain/agentexecution/__tests__/create-execution-context-step.test.ts +216 -0
  193. package/src/domain/agentexecution/__tests__/create-steps.test.ts +70 -145
  194. package/src/domain/agentexecution/controller.ts +6 -10
  195. package/src/domain/agentexecution/create-execution-context-step.ts +271 -83
  196. package/src/domain/agentexecution/create-steps.ts +38 -138
  197. package/src/domain/agentexecution/run-target.ts +7 -3
  198. package/src/domain/agentinstance/__tests__/create-authorization.composed.test.ts +243 -0
  199. package/src/domain/agentinstance/__tests__/create-authorization.test.ts +144 -0
  200. package/src/domain/agentinstance/controller.ts +24 -5
  201. package/src/domain/agentinstance/steps.ts +82 -8
  202. package/src/domain/agentshare/__tests__/create-authorization.test.ts +86 -0
  203. package/src/domain/agentshare/__tests__/member-audience.test.ts +113 -0
  204. package/src/domain/agentshare/controller.ts +21 -0
  205. package/src/domain/agentshare/steps.ts +181 -15
  206. package/src/domain/artifact/controller.ts +18 -22
  207. package/src/domain/channelapp/controller.ts +10 -0
  208. package/src/domain/environment/__tests__/personal.test.ts +143 -0
  209. package/src/domain/environment/controller.ts +10 -0
  210. package/src/domain/environment/personal.ts +141 -0
  211. package/src/domain/executioncontext/__tests__/executioncontext.test.ts +1 -0
  212. package/src/domain/executioncontext/controller.ts +10 -0
  213. package/src/domain/executioncontext/steps.ts +2 -1
  214. package/src/domain/mcpserver/connect.ts +32 -92
  215. package/src/domain/mcpserver/controller.ts +13 -1
  216. package/src/domain/mcpserver/start-connect.ts +17 -11
  217. package/src/domain/memory/__tests__/create-authorization.test.ts +59 -0
  218. package/src/domain/memory/controller.ts +11 -0
  219. package/src/domain/memory/steps.ts +41 -0
  220. package/src/domain/oauthapp/controller.ts +10 -0
  221. package/src/domain/plugin/controller.ts +22 -36
  222. package/src/domain/plugin/overlay/sanitize.ts +2 -2
  223. package/src/domain/schedule/__tests__/create-authorization.test.ts +58 -0
  224. package/src/domain/schedule/controller.ts +20 -0
  225. package/src/domain/schedule/steps.ts +45 -2
  226. package/src/domain/session/__tests__/run-gate.test.ts +19 -52
  227. package/src/domain/session/__tests__/session.test.ts +27 -203
  228. package/src/domain/session/controller.ts +10 -30
  229. package/src/domain/session/run-target.ts +9 -8
  230. package/src/domain/session/steps.ts +33 -267
  231. package/src/domain/skill/controller.ts +24 -23
  232. package/src/domain/workflow/controller.ts +58 -145
  233. package/src/domain/workflow/version-resolution.ts +166 -0
  234. package/src/domain/workflowexecution/create-steps.ts +4 -3
  235. package/src/domain/workflowinstance/__tests__/create-authorization.test.ts +109 -0
  236. package/src/domain/workflowinstance/controller.ts +19 -0
  237. package/src/domain/workflowinstance/steps.ts +49 -1
  238. package/src/extensions/__tests__/composed-support.ts +38 -4
  239. package/src/extensions/__tests__/identity.test.ts +44 -1
  240. package/src/extensions/__tests__/list-read-scope-composed.test.ts +87 -1
  241. package/src/extensions/__tests__/list-read-scope.test.ts +63 -0
  242. package/src/extensions/identity.ts +23 -5
  243. package/src/extensions/list-read-scope.ts +47 -7
  244. package/src/pipeline/apiresource-labels.ts +2 -2
  245. package/src/pipeline/errors.ts +2 -2
  246. package/src/pipeline/steps/__tests__/authorize-resolved-target.test.ts +285 -0
  247. package/src/pipeline/steps/authorize-resolved-target.ts +129 -0
  248. package/src/pipeline/steps/authorize.ts +70 -13
  249. package/src/pipeline/steps/guard-memory-capture.ts +2 -1
  250. package/src/pipeline/steps/guard-reserved-labels.ts +12 -14
  251. package/src/pipeline/steps/helpers.ts +11 -15
  252. package/src/pipeline/steps/version-history.ts +34 -0
  253. package/dist/domain/agent/defaultagent.d.ts +0 -37
  254. package/dist/domain/agent/defaultagent.d.ts.map +0 -1
  255. package/dist/domain/agent/defaultagent.js +0 -104
  256. package/dist/domain/agent/defaultagent.js.map +0 -1
  257. package/src/domain/agent/defaultagent.ts +0 -135
@@ -66,6 +66,10 @@ import {
66
66
  authorizeDirect,
67
67
  newAuthorizeStep,
68
68
  } from "../../pipeline/steps/authorize.js";
69
+ import {
70
+ loadedTargetAsMethod,
71
+ newAuthorizeResolvedTargetStep,
72
+ } from "../../pipeline/steps/authorize-resolved-target.js";
69
73
  import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
70
74
  import { newBuildNewStateStep } from "../../pipeline/steps/defaults.js";
71
75
  import { newBuildUpdateStateStep } from "../../pipeline/steps/build-update-state.js";
@@ -110,6 +114,7 @@ import {
110
114
  newResolveChannelDefaultsStep,
111
115
  newTeardownChannelRuntimeStep,
112
116
  newValidateChannelUpdateStep,
117
+ resolveChannelCreateTargets,
113
118
  } from "./steps.js";
114
119
 
115
120
  export interface AgentChannelControllerDeps {
@@ -191,6 +196,14 @@ async function createChannel(
191
196
  deps.channelRuntime,
192
197
  ),
193
198
  )
199
+ // Before the duplicate check and the install state (steps.ts,
200
+ // resolveChannelCreateTargets).
201
+ .addStep(
202
+ newAuthorizeResolvedTargetStep(
203
+ deps.authorizer,
204
+ resolveChannelCreateTargets,
205
+ ),
206
+ )
194
207
  .addStep(newResolveSlugStep())
195
208
  .addStep(newCheckDuplicateStep(deps.store))
196
209
  .addStep(newBuildNewStateStep())
@@ -499,6 +512,12 @@ async function getByReference(
499
512
  )
500
513
  .addStep(newValidateProtoStep())
501
514
  .addStep(newLoadByReferenceStep(deps.store, AgentChannelSchema))
515
+ .addStep(
516
+ newAuthorizeResolvedTargetStep(
517
+ deps.authorizer,
518
+ loadedTargetAsMethod(AgentChannelQueryController.method.get),
519
+ ),
520
+ )
502
521
  .build()
503
522
  .execute(reqCtx);
504
523
  return reqCtx.get(TARGET_RESOURCE_KEY) as AgentChannel;
@@ -21,7 +21,9 @@ import {
21
21
  AgentChannelStatusSchema,
22
22
  } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/status_pb";
23
23
  import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
24
+ import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
24
25
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
26
+ import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
25
27
 
26
28
  import {
27
29
  failedPreconditionError,
@@ -31,6 +33,7 @@ import {
31
33
  } from "../../pipeline/errors.js";
32
34
  import type { PipelineStep } from "../../pipeline/pipeline.js";
33
35
  import type { RequestContext } from "../../pipeline/request-context.js";
36
+ import type { AuthorizationTarget } from "../../pipeline/steps/authorize.js";
34
37
  import { findResourceBySlug } from "../../pipeline/steps/helpers.js";
35
38
  import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
36
39
  import type { Store } from "../../store/interface.js";
@@ -161,6 +164,7 @@ export function newResolveChannelDefaultsStep(
161
164
  }
162
165
 
163
166
  agentRef!.org = refOrg;
167
+ ctx.set(REFERENCED_AGENT_KEY, agent);
164
168
 
165
169
  // Write-time constraints only a serving runtime can state (the
166
170
  // pin-REQUIRED rule and its successors — channel-runtime.ts).
@@ -174,6 +178,42 @@ export function newResolveChannelDefaultsStep(
174
178
  };
175
179
  }
176
180
 
181
+ /**
182
+ * Context key for the agent ResolveChannelDefaults resolved from
183
+ * spec.agent_ref, read by the create lane's authorization step.
184
+ */
185
+ export const REFERENCED_AGENT_KEY = "agentChannelReferencedAgent";
186
+
187
+ /** The deny copy of the create bar, the Java AgentChannelCreateHandler's. */
188
+ export const CHANNEL_CREATE_DENIED_MESSAGE =
189
+ "You don't have permission to connect this agent to a channel";
190
+
191
+ /**
192
+ * The create lane's authorization question, for AuthorizeResolvedTarget
193
+ * after ResolveChannelDefaults: can_edit on the REFERENCED AGENT. The RPC
194
+ * is is_skip_authorization because its target is that agent, resolved from
195
+ * a slug, not a request field. Binding an agent to a channel puts it in
196
+ * front of a wider audience, an editor's act; the same-org invariant the
197
+ * resolve step enforces already binds the channel's organization to the
198
+ * agent's, so there is no separate organization bar (command.proto).
199
+ */
200
+ export function resolveChannelCreateTargets(
201
+ ctx: RequestContext<AgentChannelDesc>,
202
+ ): ReadonlyArray<AuthorizationTarget> {
203
+ const agent = ctx.get(REFERENCED_AGENT_KEY) as Agent | undefined;
204
+ if (agent === undefined) {
205
+ throw new Error("referenced agent not found in context");
206
+ }
207
+ return [
208
+ {
209
+ permission: IamPermission.can_edit,
210
+ resourceKind: ApiResourceKind.agent,
211
+ resourceId: agent.metadata?.id ?? "",
212
+ deniedMessage: CHANNEL_CREATE_DENIED_MESSAGE,
213
+ },
214
+ ];
215
+ }
216
+
177
217
  /**
178
218
  * InitInstallState — Go initInstallStateStep: writes
179
219
  * status.install_state = pending_install; the channel exists but serves
@@ -6,6 +6,11 @@
6
6
  * test driving a NON-EMPTY environment and a real token injection through
7
7
  * buildAndPersistExecutionContext. Go has no unit twin (its coverage is
8
8
  * the execution conformance suites); this pin is TS-only by design.
9
+ *
10
+ * Also pins the one declaration rule (the module header of the step): the
11
+ * agent's env united with the session servers' env, and a session
12
+ * server's saved key reaching the run from the personal environment — for
13
+ * an agent-bound run and for the built-in assistant alike.
9
14
  */
10
15
  import { mkdtempSync, rmSync } from "node:fs";
11
16
  import { tmpdir } from "node:os";
@@ -20,6 +25,7 @@ import { AgentInstanceSchema } from "@stigmer/protos/ai/stigmer/agentic/agentins
20
25
  import { AgentExecutionSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
21
26
  import { EnvironmentSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
22
27
  import type { EnvironmentValue } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
28
+ import { EnvironmentValueSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
23
29
  import type { ExecutionContext } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/api_pb";
24
30
  import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
25
31
  import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
@@ -284,3 +290,213 @@ it("assembles merge → filter → OAuth injection → EC persist over a non-emp
284
290
  const grant = await store.oauthGrants.find("", "mcps_vendor", ORG);
285
291
  expect(grant?.accessTokenExpiresAt ?? 0).toBeGreaterThan(now);
286
292
  });
293
+
294
+ // ---------------------------------------------------------------------------
295
+ // The one declaration rule: the run declares what its agent declares AND
296
+ // what its session's MCP servers declare, and a session server's declared
297
+ // variables the merge chain never carried (no instance layer can) come
298
+ // from the caller's personal environment by declared key. Two shapes, one
299
+ // rule: an agent-bound run whose session added a server, and the built-in
300
+ // assistant, which is the case with no agent half at all.
301
+ // ---------------------------------------------------------------------------
302
+
303
+ /** A personal environment reader over a fixed map; every read is recorded. */
304
+ function personalEnvironmentOver(
305
+ org: string,
306
+ data: Record<string, string>,
307
+ reads: string[],
308
+ ): ReturnType<ExecutionContextBuilderDeps["environmentReader"]> {
309
+ return {
310
+ list: async () => ({
311
+ $typeName: "ai.stigmer.agentic.environment.v1.EnvironmentList",
312
+ totalCount: 1,
313
+ items: [
314
+ create(EnvironmentSchema, {
315
+ metadata: { id: "env_personal", org, slug: "personal" },
316
+ spec: {
317
+ data: Object.fromEntries(
318
+ Object.keys(data).map((key) => [key, { value: "***", isSecret: true }]),
319
+ ),
320
+ },
321
+ }),
322
+ ],
323
+ }),
324
+ getSecretValue: async (input) => {
325
+ const key = input.key ?? "";
326
+ reads.push(key);
327
+ return create(EnvironmentValueSchema, {
328
+ value: data[key] ?? "",
329
+ isSecret: true,
330
+ });
331
+ },
332
+ };
333
+ }
334
+
335
+ it("a session-level server's declared key saved in the personal environment reaches an agent-bound run", async () => {
336
+ const ORG = "acme";
337
+ await store.saveResource(
338
+ ApiResourceKind.mcp_server,
339
+ "mcps_github",
340
+ McpServerSchema,
341
+ create(McpServerSchema, {
342
+ metadata: { id: "mcps_github", org: ORG, slug: "github" },
343
+ spec: {
344
+ env: {
345
+ GITHUB_PAT: { isSecret: true },
346
+ GITHUB_ORG: { isSecret: false, optional: true },
347
+ },
348
+ },
349
+ }),
350
+ );
351
+ const agent = create(AgentSchema, {
352
+ metadata: { id: "agt_rule", org: ORG, slug: "rule-agent" },
353
+ // The agent declares its own key and nothing of the session's server.
354
+ spec: { env: { API_KEY: { isSecret: true } } },
355
+ });
356
+ const reads: string[] = [];
357
+ const createdEcs: ExecutionContext[] = [];
358
+ const deps: ExecutionContextBuilderDeps = {
359
+ store,
360
+ logger: silentLogger,
361
+ agentLoader: () => ({ get: async () => agent }),
362
+ agentInstanceLoader: () => ({
363
+ get: async (instanceId) =>
364
+ create(AgentInstanceSchema, {
365
+ metadata: { id: instanceId, org: ORG },
366
+ spec: { agentId: "agt_rule" },
367
+ }),
368
+ }),
369
+ sessionLoader: () => ({
370
+ get: async (sessionId) =>
371
+ create(SessionSchema, {
372
+ metadata: { id: sessionId, org: ORG },
373
+ spec: {
374
+ agentInstanceId: "agi_rule",
375
+ // Added at the session level: no instance, no environment_refs.
376
+ mcpServerUsages: [{ mcpServerRef: { slug: "github", org: ORG } }],
377
+ },
378
+ }),
379
+ }),
380
+ environmentReader: () =>
381
+ personalEnvironmentOver(ORG, { GITHUB_PAT: "ghp-saved", API_KEY: "never-read" }, reads),
382
+ environmentResolution: {
383
+ resolveByReference: async () => {
384
+ throw new Error("no environment refs on this instance");
385
+ },
386
+ } as unknown as ExecutionContextBuilderDeps["environmentResolution"],
387
+ executionContextCreator: () => ({
388
+ create: async (ec) => {
389
+ createdEcs.push(ec);
390
+ return ec;
391
+ },
392
+ }),
393
+ managedEnvService: {
394
+ readSecretValue: async () => "",
395
+ updateSecrets: async () => {},
396
+ } as unknown as ManagedEnvironmentService,
397
+ };
398
+ const execution = create(AgentExecutionSchema, {
399
+ metadata: { id: "aexec_rule", org: ORG },
400
+ spec: {
401
+ sessionId: "ses_rule",
402
+ message: "hi",
403
+ runtimeEnv: {
404
+ API_KEY: { value: "runtime", isSecret: true },
405
+ UNDECLARED: { value: "stripped", isSecret: false },
406
+ },
407
+ },
408
+ });
409
+
410
+ await buildAndPersistExecutionContext(deps, execution, "");
411
+
412
+ const data = createdEcs[0]?.spec?.data ?? {};
413
+ // The agent's own key still flows as before.
414
+ expect(data["API_KEY"]?.value).toBe("runtime");
415
+ // The session server's declared key survives the filter (the union) and
416
+ // is resolved from the personal environment, marked secret as declared.
417
+ expect(data["GITHUB_PAT"]?.value).toBe("ghp-saved");
418
+ expect(data["GITHUB_PAT"]?.isSecret).toBe(true);
419
+ // A key nobody declared is filtered, as before.
420
+ expect(data["UNDECLARED"]).toBeUndefined();
421
+ // Least privilege: only the session server's still-missing declared key
422
+ // the personal environment HOLDS was read — never the agent's (already
423
+ // present), never a key the environment lacks (the optional one is
424
+ // skipped on the stored-keys check, no secret read), never the whole
425
+ // environment.
426
+ expect(reads).toEqual(["GITHUB_PAT"]);
427
+ expect(data["GITHUB_ORG"]).toBeUndefined();
428
+ });
429
+
430
+ it("the built-in assistant: no instance, no agent, the session's servers are the declared set", async () => {
431
+ const ORG = "acme";
432
+ await store.saveResource(
433
+ ApiResourceKind.mcp_server,
434
+ "mcps_notes",
435
+ McpServerSchema,
436
+ create(McpServerSchema, {
437
+ metadata: { id: "mcps_notes", org: ORG, slug: "notes" },
438
+ spec: { env: { NOTES_TOKEN: { isSecret: true } } },
439
+ }),
440
+ );
441
+ const reads: string[] = [];
442
+ const createdEcs: ExecutionContext[] = [];
443
+ const deps: ExecutionContextBuilderDeps = {
444
+ store,
445
+ logger: silentLogger,
446
+ // Neither lane may be reached: there is no instance and no agent.
447
+ agentLoader: () => ({
448
+ get: async () => {
449
+ throw new Error("agent loader must not be reached");
450
+ },
451
+ }),
452
+ agentInstanceLoader: () => ({
453
+ get: async () => {
454
+ throw new Error("instance loader must not be reached");
455
+ },
456
+ }),
457
+ sessionLoader: () => ({
458
+ get: async (sessionId) =>
459
+ create(SessionSchema, {
460
+ metadata: { id: sessionId, org: ORG },
461
+ spec: {
462
+ agentInstanceId: "",
463
+ mcpServerUsages: [{ mcpServerRef: { slug: "notes", org: ORG } }],
464
+ },
465
+ }),
466
+ }),
467
+ environmentReader: () => personalEnvironmentOver(ORG, { NOTES_TOKEN: "nt-saved" }, reads),
468
+ environmentResolution: {
469
+ resolveByReference: async () => {
470
+ throw new Error("no environment refs without an instance");
471
+ },
472
+ } as unknown as ExecutionContextBuilderDeps["environmentResolution"],
473
+ executionContextCreator: () => ({
474
+ create: async (ec) => {
475
+ createdEcs.push(ec);
476
+ return ec;
477
+ },
478
+ }),
479
+ managedEnvService: {
480
+ readSecretValue: async () => "",
481
+ updateSecrets: async () => {},
482
+ } as unknown as ManagedEnvironmentService,
483
+ };
484
+ const execution = create(AgentExecutionSchema, {
485
+ metadata: { id: "aexec_assistant", org: ORG },
486
+ spec: {
487
+ sessionId: "ses_assistant",
488
+ message: "hi",
489
+ runtimeEnv: { STRAY: { value: "stripped", isSecret: false } },
490
+ },
491
+ });
492
+
493
+ await buildAndPersistExecutionContext(deps, execution, "");
494
+
495
+ expect(createdEcs).toHaveLength(1);
496
+ const data = createdEcs[0]?.spec?.data ?? {};
497
+ expect(data["NOTES_TOKEN"]?.value).toBe("nt-saved");
498
+ // The declared set is the session servers' alone, so the filter is
499
+ // live: a stray runtime key is stripped, not passed through.
500
+ expect(data["STRAY"]).toBeUndefined();
501
+ expect(reads).toEqual(["NOTES_TOKEN"]);
502
+ });
@@ -19,7 +19,6 @@ import type { JsonObject } from "@bufbuild/protobuf";
19
19
  import { Code, ConnectError } from "@connectrpc/connect";
20
20
  import { afterEach, beforeEach, describe, expect, it } from "vitest";
21
21
 
22
- import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
23
22
  import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
24
23
  import {
25
24
  AgentExecutionSchema,
@@ -32,6 +31,8 @@ import {
32
31
  } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
33
32
  import { MemorySchema } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/api_pb";
34
33
  import { MemoryLifecycleState } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/enum_pb";
34
+ import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
35
+ import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
35
36
  import type { SessionSpec } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
36
37
  import { SessionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
37
38
  import {
@@ -42,7 +43,6 @@ import type { Workflow } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/ap
42
43
  import { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/api_pb";
43
44
  import { WorkflowTaskKind } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/enum_pb";
44
45
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
45
- import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
46
46
  import { OrganizationSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
47
47
 
48
48
  import { createLogger } from "../../../boot/logger.js";
@@ -59,8 +59,6 @@ import {
59
59
  newComposeRecalledMemoriesStep,
60
60
  newCreateDefaultInstanceIfNeededStep,
61
61
  newCreateSessionIfNeededStep,
62
- newEnsureSessionOrAgentResolvedStep,
63
- newResolveDefaultAgentStep,
64
62
  newStartWorkflowStep,
65
63
  } from "../create-steps.js";
66
64
  import type { AgentExecutionStatusTransition } from "../../../extensions/status-hooks.js";
@@ -105,28 +103,6 @@ function newContext(
105
103
  );
106
104
  }
107
105
 
108
- async function seedDefaultAgent(
109
- id: string,
110
- visibility: ApiResourceVisibility,
111
- ): Promise<void> {
112
- await store.saveResource(
113
- ApiResourceKind.agent,
114
- id,
115
- AgentSchema,
116
- create(AgentSchema, {
117
- apiVersion: "agentic.stigmer.ai/v1",
118
- kind: "Agent",
119
- metadata: {
120
- id,
121
- name: "assistant",
122
- org: "stigmer",
123
- visibility,
124
- labels: { "stigmer.ai/default-agent": "true" },
125
- },
126
- }),
127
- );
128
- }
129
-
130
106
  async function expectCode(
131
107
  fn: () => Promise<unknown> | unknown,
132
108
  code: Code,
@@ -141,140 +117,89 @@ async function expectCode(
141
117
  throw new Error(`expected code ${Code[code]}, call succeeded`);
142
118
  }
143
119
 
144
- // The post-resolution invariant guard: a resolved reference passes; an
145
- // unresolved one is an Internal invariant violation (never
146
- // InvalidArgument — issue #196).
147
- describe("newEnsureSessionOrAgentResolvedStep", () => {
148
- const step = newEnsureSessionOrAgentResolvedStep(silentLogger);
149
-
150
- const cases: Array<{
151
- name: string;
152
- sessionId?: string;
153
- agentId?: string;
154
- specInstanceId?: string;
155
- wantCode?: Code;
156
- }> = [
157
- { name: "session_id resolved -> pass", sessionId: "ses_1" },
158
- { name: "agent_id resolved -> pass", agentId: "agt_1" },
159
- {
160
- name: "both resolved -> pass",
161
- sessionId: "ses_1",
162
- agentId: "agt_1",
163
- },
164
- {
165
- name: "session_spec instance resolved -> pass",
166
- specInstanceId: "inst_1",
167
- },
168
- {
169
- name: "none resolved -> Internal invariant violation",
170
- wantCode: Code.Internal,
171
- },
172
- ];
173
-
174
- for (const tt of cases) {
175
- it(tt.name, async () => {
176
- const execution = newExecution(tt.sessionId ?? "", tt.agentId ?? "");
177
- if (tt.specInstanceId !== undefined) {
178
- execution.spec!.sessionSpec = create(SessionSpecSchema, {
179
- agentInstanceId: tt.specInstanceId,
180
- });
181
- }
182
- const ctx = newContext(execution);
183
- if (tt.wantCode === undefined) {
184
- await step.execute(ctx);
185
- } else {
186
- await expectCode(() => step.execute(ctx), tt.wantCode);
187
- }
120
+ // The built-in assistant's shape through the two side-effecting steps: an
121
+ // execution naming no session, no agent and no session_spec instance is
122
+ // legal (agentexecution/v1/spec.proto), so CreateDefaultInstanceIfNeeded
123
+ // has nothing to load or mint and CreateSessionIfNeeded creates the
124
+ // session with an EMPTY agent_instance_id. The throwing providers prove
125
+ // the first step never reaches a client (Go's nil clients would panic).
126
+ describe("the built-in assistant (no session, agent or instance named)", () => {
127
+ it("createDefaultInstanceIfNeeded skips without touching the agent lane", async () => {
128
+ const step = newCreateDefaultInstanceIfNeededStep({
129
+ store,
130
+ logger: silentLogger,
131
+ agentLoader: () => {
132
+ throw new Error("agent loader must not be reached");
133
+ },
134
+ agentInstanceCreator: () => {
135
+ throw new Error("instance creator must not be reached");
136
+ },
188
137
  });
189
- }
190
- });
191
-
192
- // The reachable contract of default-agent resolution: NotFound when
193
- // unseeded, resolution onto newState when a public default exists, and
194
- // FailedPrecondition when the default is not visibility_public.
195
- describe("newResolveDefaultAgentStep", () => {
196
- it("no default agent seeded -> NotFound", async () => {
197
- const step = newResolveDefaultAgentStep(store, silentLogger);
198
- await expectCode(
199
- () => step.execute(newContext(newExecution("", ""))),
200
- Code.NotFound,
201
- );
202
- });
203
-
204
- it("public default agent -> resolves agent_id onto newState", async () => {
205
- await seedDefaultAgent(
206
- "agt_default",
207
- ApiResourceVisibility.visibility_public,
208
- );
209
- const step = newResolveDefaultAgentStep(store, silentLogger);
210
138
  const ctx = newContext(newExecution("", ""));
211
-
212
139
  await step.execute(ctx);
213
-
214
- expect(ctx.newState.spec?.agentId).toBe("agt_default");
215
- // The original request must remain immutable.
216
- expect(ctx.input.spec?.agentId).toBe("");
217
- });
218
-
219
- it("non-public default agent -> FailedPrecondition", async () => {
220
- await seedDefaultAgent(
221
- "agt_private",
222
- ApiResourceVisibility.visibility_private,
223
- );
224
- const step = newResolveDefaultAgentStep(store, silentLogger);
225
- await expectCode(
226
- () => step.execute(newContext(newExecution("", ""))),
227
- Code.FailedPrecondition,
228
- );
140
+ expect(ctx.get(DEFAULT_INSTANCE_ID_KEY)).toBeUndefined();
229
141
  });
230
142
 
231
- // The oss#356 defect through this step's lens: a first-match lookup
232
- // could land on the non-public labeled agent and fail even though a
233
- // valid public default existed. Both insertion orders must resolve the
234
- // public agent.
235
- for (const [name, ids] of Object.entries({
236
- "private inserted first": ["agt_0private", "agt_1public"],
237
- "public inserted first": ["agt_1public", "agt_0private"],
238
- })) {
239
- it(`non-public labeled agent alongside a public one -> public wins (${name})`, async () => {
240
- for (const id of ids) {
241
- await seedDefaultAgent(
242
- id,
243
- id === "agt_1public"
244
- ? ApiResourceVisibility.visibility_public
245
- : ApiResourceVisibility.visibility_private,
246
- );
247
- }
248
- const step = newResolveDefaultAgentStep(store, silentLogger);
249
- const ctx = newContext(newExecution("", ""));
250
- await step.execute(ctx);
251
- expect(ctx.newState.spec?.agentId).toBe("agt_1public");
143
+ it("createSessionIfNeeded creates the session with no instance and no context key", async () => {
144
+ let created: Session | undefined;
145
+ const step = newCreateSessionIfNeededStep({
146
+ logger: silentLogger,
147
+ sessionCreator: () => ({
148
+ createAsCaller: async (session) => {
149
+ created = clone(SessionSchema, session);
150
+ created.metadata!.id = "ses_assistant";
151
+ return created;
152
+ },
153
+ }),
252
154
  });
253
- }
155
+ const execution = newExecution("", "");
156
+ execution.metadata!.org = "acme";
157
+ const ctx = newContext(execution);
254
158
 
255
- it("reference already provided -> no-op", async () => {
256
- const step = newResolveDefaultAgentStep(store, silentLogger);
257
- const ctx = newContext(newExecution("", "agt_explicit"));
258
159
  await step.execute(ctx);
259
- expect(ctx.newState.spec?.agentId).toBe("agt_explicit");
160
+
161
+ expect(created?.spec?.agentInstanceId).toBe("");
162
+ expect(created?.spec?.subject).toBe(AUTO_CREATED_SESSION_SUBJECT);
163
+ expect(created?.metadata?.org).toBe("acme");
164
+ expect(ctx.newState.spec?.sessionId).toBe("ses_assistant");
165
+ expect(ctx.newState.spec?.sessionSpec).toBeUndefined();
260
166
  });
261
167
 
262
- it("session_spec instance provided -> no-op even with a seeded default agent", async () => {
263
- // A one-call bootstrap naming an explicit instance must NOT resolve
264
- // the platform default agent: doing so would stamp misleading
265
- // metadata pointing at an agent the session does not run against.
266
- await seedDefaultAgent(
267
- "agt_default",
268
- ApiResourceVisibility.visibility_public,
269
- );
270
- const step = newResolveDefaultAgentStep(store, silentLogger);
168
+ it("createSessionIfNeeded forwards a caller session_spec that names no instance", async () => {
169
+ let created: Session | undefined;
170
+ const step = newCreateSessionIfNeededStep({
171
+ logger: silentLogger,
172
+ sessionCreator: () => ({
173
+ createAsCaller: async (session) => {
174
+ created = clone(SessionSchema, session);
175
+ created.metadata!.id = "ses_assistant_tools";
176
+ return created;
177
+ },
178
+ }),
179
+ });
271
180
  const execution = newExecution("", "");
272
181
  execution.spec!.sessionSpec = create(SessionSpecSchema, {
273
- agentInstanceId: "inst_explicit",
182
+ mcpServerUsages: [{ mcpServerRef: { org: "acme", slug: "github" } }],
274
183
  });
275
184
  const ctx = newContext(execution);
185
+
276
186
  await step.execute(ctx);
277
- expect(ctx.newState.spec?.agentId).toBe("");
187
+
188
+ expect(created?.spec?.agentInstanceId).toBe("");
189
+ expect(created?.spec?.mcpServerUsages.map((u) => u.mcpServerRef?.slug)).toEqual(["github"]);
190
+ });
191
+
192
+ // An agent WAS named but the previous step left no key: the invariant
193
+ // guard stays Internal, unchanged — only the all-empty shape is legal.
194
+ it("createSessionIfNeeded still refuses a named agent whose instance was never resolved", async () => {
195
+ const step = newCreateSessionIfNeededStep({
196
+ logger: silentLogger,
197
+ sessionCreator: () => {
198
+ throw new Error("session creator must not be reached");
199
+ },
200
+ });
201
+ const ctx = newContext(newExecution("", "agt_named"));
202
+ await expectCode(() => step.execute(ctx), Code.Internal);
278
203
  });
279
204
  });
280
205
 
@@ -94,9 +94,7 @@ import {
94
94
  newComposeRecalledMemoriesStep,
95
95
  newCreateDefaultInstanceIfNeededStep,
96
96
  newCreateSessionIfNeededStep,
97
- newEnsureSessionOrAgentResolvedStep,
98
97
  newProcessAttachmentsStep,
99
- newResolveDefaultAgentStep,
100
98
  newSetInitialPhaseStep,
101
99
  newStartWorkflowStep,
102
100
  } from "./create-steps.js";
@@ -280,12 +278,12 @@ export function registerAgentExecutionServices(
280
278
 
281
279
  /**
282
280
  * Create — create.go buildCreatePipeline, step-for-step: validation
283
- * (proto → visibility → tier #357 → thinking #772) → target resolution
284
- * (default agent → invariant guard) → the run gate (AuthorizeRunTarget,
285
- * P1 sp.run-gate: the first step after the target is guaranteed, asking
286
- * the target's own permission by request shape — session, instance or
287
- * blueprint — before the engine gate so a denied caller learns nothing
288
- * about engine state, and before every side effect) → the standard build
281
+ * (proto → visibility → tier #357 → thinking #772) → the run gate
282
+ * (AuthorizeRunTarget, P1 sp.run-gate: asking the target's own permission
283
+ * by request shape — session, instance or blueprint; the all-empty shape
284
+ * is the built-in assistant, admitted by Authorize's organization check
285
+ * and gated on nothing further — before the engine gate so a denied caller
286
+ * learns nothing about engine state, and before every side effect) → the standard build
289
287
  * → the engine gate (fail fast BEFORE the first side effect, so a down
290
288
  * engine orphans nothing) → the pre-side-effect gate slot (O4; empty in OSS) → the
291
289
  * side-effecting steps (default instance, session bootstrap,
@@ -319,8 +317,6 @@ async function createExecution(
319
317
  .addStep(newValidateVisibilityStep())
320
318
  .addStep(newValidateServiceTierStep(deps.modelRegistry))
321
319
  .addStep(newValidateThinkingModeStep(deps.modelRegistry))
322
- .addStep(newResolveDefaultAgentStep(deps.store, deps.logger))
323
- .addStep(newEnsureSessionOrAgentResolvedStep(deps.logger))
324
320
  .addStep(
325
321
  newAuthorizeRunTargetStep(deps.authorizer, agentExecutionRunTarget),
326
322
  )