@opengeni/worker-bundle 1.0.0-canary.1 → 1.0.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 (244) hide show
  1. package/dist/activities/agent-run-admission.d.ts +3 -1
  2. package/dist/activities/agent-turn/admission.d.ts +24 -3
  3. package/dist/activities/agent-turn/agent-build.d.ts +4 -0
  4. package/dist/activities/agent-turn/claude-usage-observer.d.ts +58 -0
  5. package/dist/activities/agent-turn/code-search.d.ts +60 -0
  6. package/dist/activities/agent-turn/codex-capacity.d.ts +13 -0
  7. package/dist/activities/agent-turn/codex-plan-entitlement.d.ts +105 -0
  8. package/dist/activities/agent-turn/codex.d.ts +3 -2
  9. package/dist/activities/agent-turn/compaction-prep.d.ts +21 -5
  10. package/dist/activities/agent-turn/credential-leases.d.ts +19 -33
  11. package/dist/activities/agent-turn/credential-restriction.d.ts +3 -0
  12. package/dist/activities/agent-turn/errors.d.ts +82 -11
  13. package/dist/activities/agent-turn/failure-settlement.d.ts +6 -3
  14. package/dist/activities/agent-turn/final-reply.d.ts +18 -0
  15. package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
  16. package/dist/activities/agent-turn/finalization.d.ts +4 -2
  17. package/dist/activities/agent-turn/github-repository-bindings.d.ts +2 -0
  18. package/dist/activities/agent-turn/governance-model.d.ts +9 -2
  19. package/dist/activities/agent-turn/history-sink.d.ts +2 -0
  20. package/dist/activities/agent-turn/history.d.ts +2 -0
  21. package/dist/activities/agent-turn/input-wait-reply.d.ts +41 -0
  22. package/dist/activities/agent-turn/media-artifacts.d.ts +5 -3
  23. package/dist/activities/agent-turn/model-call-admission.d.ts +15 -0
  24. package/dist/activities/agent-turn/model-usage.d.ts +6 -0
  25. package/dist/activities/agent-turn/model-wire-dispatch.d.ts +15 -0
  26. package/dist/activities/agent-turn/optional-repositories.d.ts +59 -0
  27. package/dist/activities/agent-turn/provider-dispatch-barrier.d.ts +12 -1
  28. package/dist/activities/agent-turn/quiescence.d.ts +7 -7
  29. package/dist/activities/agent-turn/recovery-warning.d.ts +9 -0
  30. package/dist/activities/agent-turn/refresh-credentials.d.ts +6 -0
  31. package/dist/activities/agent-turn/run-credentials.d.ts +8 -3
  32. package/dist/activities/agent-turn/sandbox-establish.d.ts +2 -1
  33. package/dist/activities/agent-turn/sandbox-provision.d.ts +3 -1
  34. package/dist/activities/agent-turn/sandbox-route.d.ts +3 -20
  35. package/dist/activities/agent-turn/sandbox-runtime.d.ts +2 -2
  36. package/dist/activities/agent-turn/session-title.d.ts +34 -2
  37. package/dist/activities/agent-turn/skill-checkout.d.ts +25 -6
  38. package/dist/activities/agent-turn/skill-read.d.ts +70 -2
  39. package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
  40. package/dist/activities/agent-turn/skill-search.d.ts +3 -1
  41. package/dist/activities/agent-turn/skill-tools.d.ts +15 -2
  42. package/dist/activities/agent-turn/skill-transfer.d.ts +18 -6
  43. package/dist/activities/agent-turn/stream-attempt.d.ts +7 -3
  44. package/dist/activities/agent-turn/subscription-lease.d.ts +38 -0
  45. package/dist/activities/agent-turn/tool-environment.d.ts +56 -6
  46. package/dist/activities/agent-turn/tool-policy.d.ts +43 -0
  47. package/dist/activities/agent-turn/turn-context.d.ts +29 -0
  48. package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
  49. package/dist/activities/agent-turn/xai-capacity.d.ts +2 -1
  50. package/dist/activities/automations.d.ts +3 -1
  51. package/dist/activities/browser-deadline-checkpoint.d.ts +29 -0
  52. package/dist/activities/codemode-dispatcher.d.ts +9 -2
  53. package/dist/activities/codex-capacity.d.ts +18 -2
  54. package/dist/activities/codex-rotation.d.ts +7 -1
  55. package/dist/activities/context-compaction.d.ts +16 -2
  56. package/dist/activities/gmail-files.d.ts +32 -0
  57. package/dist/activities/goals.d.ts +8 -0
  58. package/dist/activities/knowledge-indexing.d.ts +19 -0
  59. package/dist/activities/mcp-account-routes.d.ts +3 -0
  60. package/dist/activities/mcp-credentials.d.ts +12 -13
  61. package/dist/activities/mcp-operation-authority.d.ts +0 -5
  62. package/dist/activities/model-call-fact-reconciler.d.ts +34 -0
  63. package/dist/activities/open-suffix-resume.d.ts +13 -0
  64. package/dist/activities/parent-wake.d.ts +6 -12
  65. package/dist/activities/retained-screenshots.d.ts +7 -2
  66. package/dist/activities/rig-verification.d.ts +2 -3
  67. package/dist/activities/run-credential-renewal.d.ts +1 -0
  68. package/dist/activities/run-credentials.d.ts +15 -3
  69. package/dist/activities/sandbox-images.d.ts +1 -1
  70. package/dist/activities/sandbox-lease.d.ts +47 -9
  71. package/dist/activities/scheduled-tasks.d.ts +4 -35
  72. package/dist/activities/session-state.d.ts +70 -3
  73. package/dist/activities/types.d.ts +55 -6
  74. package/dist/activities/workspace-capture.d.ts +2 -0
  75. package/dist/activities/workspace-credential-provider.d.ts +46 -0
  76. package/dist/{activities-control-HMFGSKC5.js → activities-control-BNPTRTOE.js} +1896 -418
  77. package/dist/activities-control-BNPTRTOE.js.map +1 -0
  78. package/dist/activities-control.d.ts +182 -4
  79. package/dist/{activities-turn-AP67JADS.js → activities-turn-5LGZOSVU.js} +4476 -1327
  80. package/dist/activities-turn-5LGZOSVU.js.map +1 -0
  81. package/dist/activities.d.ts +182 -4
  82. package/dist/artifact-materializer-entry.js +5 -2
  83. package/dist/artifact-materializer-entry.js.map +1 -1
  84. package/dist/artifact-outbox-entry.js +5 -2
  85. package/dist/artifact-outbox-entry.js.map +1 -1
  86. package/dist/browser-deadline-checkpoint-contract.d.ts +2 -0
  87. package/dist/{chunk-A4XQWVZK.js → chunk-3ZTRWDMN.js} +307 -4
  88. package/dist/chunk-3ZTRWDMN.js.map +1 -0
  89. package/dist/{chunk-RAMNYSAW.js → chunk-4ER3YXOT.js} +22 -4
  90. package/dist/chunk-4ER3YXOT.js.map +1 -0
  91. package/dist/{chunk-CYITU5UH.js → chunk-LJX7Z2KP.js} +1445 -343
  92. package/dist/chunk-LJX7Z2KP.js.map +1 -0
  93. package/dist/editable-artifact-materializer-service.d.ts +2 -2
  94. package/dist/editable-artifact-outbox-service.d.ts +2 -2
  95. package/dist/host-export-pump.d.ts +3 -1
  96. package/dist/host-export.d.ts +1 -1
  97. package/dist/host-export.js +1 -1
  98. package/dist/http.d.ts +1 -1
  99. package/dist/index.d.ts +95 -3
  100. package/dist/index.js +137 -43
  101. package/dist/index.js.map +1 -1
  102. package/dist/observability-metrics.d.ts +118 -8
  103. package/dist/retained-process-diagnostics.d.ts +4 -0
  104. package/dist/retained-process-retry.d.ts +7 -0
  105. package/dist/sandbox-resume.d.ts +55 -13
  106. package/dist/sandbox-routing.d.ts +5 -3
  107. package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
  108. package/dist/session-event-fanout.d.ts +6 -0
  109. package/dist/warm-capture-holder.d.ts +3 -0
  110. package/dist/worker-service-lifecycle.d.ts +12 -0
  111. package/dist/workflow-bundle.js +273 -41
  112. package/dist/workflows/activities.d.ts +1 -1
  113. package/dist/workflows/browser-deadline-checkpoint.d.ts +9 -0
  114. package/dist/workflows/scheduled-tasks.d.ts +4 -0
  115. package/dist/workflows/session.d.ts +36 -0
  116. package/dist/workflows.d.ts +1 -0
  117. package/package.json +21 -19
  118. package/src/activities/agent-run-admission.ts +17 -1
  119. package/src/activities/agent-turn/admission.ts +66 -3
  120. package/src/activities/agent-turn/agent-build.ts +84 -10
  121. package/src/activities/agent-turn/claim.ts +186 -43
  122. package/src/activities/agent-turn/claude-usage-observer.ts +221 -0
  123. package/src/activities/agent-turn/code-search.ts +275 -0
  124. package/src/activities/agent-turn/codex-capacity.ts +172 -8
  125. package/src/activities/agent-turn/codex-plan-entitlement.ts +254 -0
  126. package/src/activities/agent-turn/codex.ts +13 -5
  127. package/src/activities/agent-turn/compaction-prep.ts +170 -102
  128. package/src/activities/agent-turn/credential-leases.ts +122 -216
  129. package/src/activities/agent-turn/credential-restriction.ts +14 -0
  130. package/src/activities/agent-turn/errors.ts +647 -48
  131. package/src/activities/agent-turn/failure-settlement.ts +682 -130
  132. package/src/activities/agent-turn/final-reply.ts +46 -0
  133. package/src/activities/agent-turn/finalization-monitor.ts +120 -0
  134. package/src/activities/agent-turn/finalization.ts +146 -43
  135. package/src/activities/agent-turn/github-repository-bindings.ts +3 -1
  136. package/src/activities/agent-turn/governance-model.ts +69 -28
  137. package/src/activities/agent-turn/history-sink.ts +16 -2
  138. package/src/activities/agent-turn/history.ts +38 -11
  139. package/src/activities/agent-turn/input-wait-reply.ts +103 -0
  140. package/src/activities/agent-turn/knowledge-source-tools.ts +2 -0
  141. package/src/activities/agent-turn/media-artifacts.ts +2 -1
  142. package/src/activities/agent-turn/model-call-admission.ts +94 -0
  143. package/src/activities/agent-turn/model-usage.ts +64 -3
  144. package/src/activities/agent-turn/model-wire-dispatch.ts +27 -0
  145. package/src/activities/agent-turn/optional-repositories.ts +224 -0
  146. package/src/activities/agent-turn/provider-dispatch-barrier.ts +22 -0
  147. package/src/activities/agent-turn/quiescence.ts +10 -7
  148. package/src/activities/agent-turn/recovery-warning.ts +16 -0
  149. package/src/activities/agent-turn/refresh-credentials.ts +44 -0
  150. package/src/activities/agent-turn/run-credentials.ts +116 -55
  151. package/src/activities/agent-turn/run.ts +320 -93
  152. package/src/activities/agent-turn/sandbox-establish.ts +84 -8
  153. package/src/activities/agent-turn/sandbox-provision.ts +3 -1
  154. package/src/activities/agent-turn/sandbox-route.ts +4 -21
  155. package/src/activities/agent-turn/sandbox-runtime.ts +343 -18
  156. package/src/activities/agent-turn/session-title.ts +81 -5
  157. package/src/activities/agent-turn/skill-checkout.ts +111 -24
  158. package/src/activities/agent-turn/skill-install.ts +1 -1
  159. package/src/activities/agent-turn/skill-read.ts +374 -28
  160. package/src/activities/agent-turn/skill-remove.ts +46 -0
  161. package/src/activities/agent-turn/skill-save.ts +1 -1
  162. package/src/activities/agent-turn/skill-search.ts +10 -1
  163. package/src/activities/agent-turn/skill-selection.ts +4 -0
  164. package/src/activities/agent-turn/skill-tools.ts +112 -18
  165. package/src/activities/agent-turn/skill-transfer.ts +68 -23
  166. package/src/activities/agent-turn/stream-attempt.ts +313 -77
  167. package/src/activities/agent-turn/subscription-lease.ts +115 -0
  168. package/src/activities/agent-turn/tool-environment.ts +316 -167
  169. package/src/activities/agent-turn/tool-policy.ts +80 -1
  170. package/src/activities/agent-turn/turn-context.ts +35 -0
  171. package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
  172. package/src/activities/agent-turn/xai-capacity.ts +94 -51
  173. package/src/activities/automations.ts +76 -4
  174. package/src/activities/browser-deadline-checkpoint.ts +279 -0
  175. package/src/activities/capabilities.ts +108 -11
  176. package/src/activities/codemode-dispatcher.ts +36 -8
  177. package/src/activities/codex-capacity.ts +60 -25
  178. package/src/activities/codex-rotation.ts +39 -17
  179. package/src/activities/context-compaction.ts +75 -18
  180. package/src/activities/gmail-files.ts +88 -0
  181. package/src/activities/goals.ts +116 -121
  182. package/src/activities/google-drive-publication.ts +1 -3
  183. package/src/activities/image-generation-operation.ts +1 -1
  184. package/src/activities/knowledge-indexing.ts +269 -15
  185. package/src/activities/knowledge-source-sync.ts +10 -0
  186. package/src/activities/mcp-account-routes.ts +17 -0
  187. package/src/activities/mcp-credentials.ts +83 -194
  188. package/src/activities/mcp-operation-authority.ts +16 -41
  189. package/src/activities/model-call-fact-reconciler.ts +112 -0
  190. package/src/activities/open-suffix-resume.ts +15 -2
  191. package/src/activities/parent-wake.ts +46 -21
  192. package/src/activities/retained-screenshots.ts +82 -11
  193. package/src/activities/rig-verification.ts +38 -37
  194. package/src/activities/run-credential-renewal.ts +13 -1
  195. package/src/activities/run-credentials.ts +59 -17
  196. package/src/activities/run-input.ts +25 -16
  197. package/src/activities/sandbox-images.ts +0 -1
  198. package/src/activities/sandbox-lease.ts +798 -82
  199. package/src/activities/scheduled-tasks.ts +550 -178
  200. package/src/activities/session-state.ts +245 -6
  201. package/src/activities/site-auth-maintenance.ts +3 -0
  202. package/src/activities/types.ts +72 -5
  203. package/src/activities/workflow-wake.ts +2 -17
  204. package/src/activities/workspace-capture.ts +13 -2
  205. package/src/activities/workspace-credential-provider.ts +283 -0
  206. package/src/activities-control.ts +4 -0
  207. package/src/activities-turn.ts +5 -0
  208. package/src/activities.ts +13 -0
  209. package/src/activity-services.ts +16 -4
  210. package/src/browser-deadline-checkpoint-contract.ts +5 -0
  211. package/src/editable-artifact-hint-broker.ts +3 -0
  212. package/src/editable-artifact-materializer-service.ts +7 -3
  213. package/src/editable-artifact-outbox-service.ts +4 -4
  214. package/src/github-rest-mcp.ts +1 -2
  215. package/src/host-export-pump.ts +26 -4
  216. package/src/host-export.ts +3 -0
  217. package/src/http.ts +4 -2
  218. package/src/index.ts +99 -37
  219. package/src/observability-metrics.ts +510 -5
  220. package/src/personal-github-git-credentials.ts +2 -1
  221. package/src/pr-review-credentials.ts +1 -3
  222. package/src/retained-process-diagnostics.ts +50 -0
  223. package/src/retained-process-retry.ts +36 -0
  224. package/src/sandbox-resume.ts +388 -101
  225. package/src/sandbox-routing.ts +150 -25
  226. package/src/sandbox-snapshot-diagnostics.ts +112 -0
  227. package/src/session-event-fanout.ts +23 -0
  228. package/src/warm-capture-holder.ts +15 -0
  229. package/src/worker-service-lifecycle.ts +53 -0
  230. package/src/workflows/activities.ts +16 -1
  231. package/src/workflows/browser-deadline-checkpoint.ts +50 -0
  232. package/src/workflows/file-upload-reaper.ts +2 -0
  233. package/src/workflows/scheduled-tasks.ts +26 -13
  234. package/src/workflows/session.ts +242 -22
  235. package/src/workflows.ts +4 -0
  236. package/dist/activities/agent-turn/knowledge-sources.d.ts +0 -20
  237. package/dist/activities/packs.d.ts +0 -55
  238. package/dist/activities-control-HMFGSKC5.js.map +0 -1
  239. package/dist/activities-turn-AP67JADS.js.map +0 -1
  240. package/dist/chunk-A4XQWVZK.js.map +0 -1
  241. package/dist/chunk-CYITU5UH.js.map +0 -1
  242. package/dist/chunk-RAMNYSAW.js.map +0 -1
  243. package/src/activities/agent-turn/knowledge-sources.ts +0 -86
  244. package/src/activities/packs.ts +0 -166
@@ -2,6 +2,7 @@ import { getSessionRootId, resolvePrReviewGitCredential } from "@opengeni/db";
2
2
  import { prReviewRegistrationIdFromCredentialBinding } from "@opengeni/core";
3
3
  import {
4
4
  materializeRunCredentials,
5
+ repositoryHasExplicitGitConnection,
5
6
  clearRunCredentials,
6
7
  clearRunCredentialsForAttempt,
7
8
  refreshGitCredentialBindingTokenFiles,
@@ -11,6 +12,8 @@ import {
11
12
  type NormalizedRunCredentialMaterial,
12
13
  type RunCredentialCommandSession,
13
14
  type CodemodeTokenWriterSession,
15
+ RunMcpCredentials,
16
+ selectedSessionRemoteMcpTargets,
14
17
  } from "@opengeni/runtime";
15
18
  import { codemodeWorkspaceUrl, type Settings } from "@opengeni/config";
16
19
  import {
@@ -25,10 +28,13 @@ import {
25
28
  type loadWorkspaceEnvironmentForRunWithCredentials,
26
29
  } from "../environment";
27
30
  import type { mergeResourceRefs } from "../common";
31
+ import type { withFirstPartyTools } from "../goals";
32
+ import { expandMcpAccountRoutes } from "../mcp-account-routes";
28
33
  import { startGitCredentialRenewalLoop } from "../git-credential-renewal";
29
34
  import {
30
35
  RUN_CREDENTIAL_EXPIRY_LEAD_MS,
31
36
  startRunCredentialRenewalLoop,
37
+ runCredentialRenewalExpiry,
32
38
  } from "../run-credential-renewal";
33
39
  import {
34
40
  CODEMODE_TOKEN_EXPIRY_LEAD_MS,
@@ -59,6 +65,7 @@ import {
59
65
  sandboxSettingsForRoute,
60
66
  } from "./sandbox-route";
61
67
  import type { ClaimTurnOk } from "./claim";
68
+ import { turnCredentialRestriction } from "./credential-restriction";
62
69
  import type { GovernanceModelOk } from "./governance-model";
63
70
  import type { SandboxTurnRuntime } from "./sandbox-runtime";
64
71
  import type {
@@ -69,6 +76,8 @@ import type {
69
76
  } from "./turn-context";
70
77
 
71
78
  export type PrepareRunCredentialsDeps = {
79
+ localMcpServerIds?: readonly string[];
80
+ turnTools: ReturnType<typeof withFirstPartyTools>;
72
81
  input: RunAgentTurnInput;
73
82
  settings: Settings;
74
83
  db: ActivityServices["db"];
@@ -83,6 +92,7 @@ export type PrepareRunCredentialsDeps = {
83
92
  sandboxRuntime: SandboxTurnRuntime;
84
93
  turn: ClaimTurnOk["turn"];
85
94
  session: ClaimTurnOk["session"];
95
+ turnExecutionPolicy: ClaimTurnOk["turnExecutionPolicy"];
86
96
  fileAuthoritySubjectId: ClaimTurnOk["fileAuthoritySubjectId"];
87
97
  runSettings: GovernanceModelOk["runSettings"];
88
98
  workspaceVariableSet: Awaited<ReturnType<typeof loadWorkspaceEnvironmentForRunWithCredentials>>;
@@ -121,6 +131,7 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
121
131
  sandboxState,
122
132
  turn,
123
133
  session,
134
+ turnExecutionPolicy,
124
135
  fileAuthoritySubjectId,
125
136
  runSettings,
126
137
  workspaceVariableSet,
@@ -145,14 +156,29 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
145
156
  machinePrimary,
146
157
  groupBoxBackend,
147
158
  });
159
+ const platformGitResources = turnResources.filter(
160
+ (resource) => resource.kind !== "repository" || repositoryHasExplicitGitConnection(resource),
161
+ );
162
+ // Credential targets follow the same accepted-account narrowing as execution.
163
+ // A canonical connection without an accepted account does not execute, and
164
+ // account-qualified aliases never inherit an attachment's product headers.
165
+ const accountRoutes = expandMcpAccountRoutes({
166
+ settings: runSettings,
167
+ tools: deps.turnTools,
168
+ bindings: turn.mcpAccountBindings,
169
+ });
148
170
 
149
171
  const runCredentialResolver =
150
- effectiveRunCredentialBackend === "none"
172
+ effectiveRunCredentialBackend === "none" || effectiveRunCredentialBackend === "selfhosted"
151
173
  ? null
152
174
  : await waitForTurnOperation(
153
175
  bindRunCredentialResolver({
154
176
  db,
177
+ settings: accountRoutes.settings,
178
+ initiatingHumanSubjectId: turn.initiatingHumanSubjectId ?? null,
155
179
  connectionCredentials: connectionCredentials ?? null,
180
+ localMcpServerIds: deps.localMcpServerIds ?? [],
181
+ effectiveTools: accountRoutes.tools,
156
182
  accountId: input.accountId,
157
183
  workspaceId: input.workspaceId,
158
184
  session,
@@ -188,8 +214,9 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
188
214
  // Resolve once before model preparation so partial/auth-needed host state
189
215
  // is available as bounded model context and reconnect UI even when an
190
216
  // on-demand turn never provisions a box. Resolution alone performs no
191
- // sandbox write or renewal; both paths reuse this exact material and the
192
- // lazy path materializes it only inside its first-operation single-flight.
217
+ // sandbox write. The worker-local renewal below supports remote MCPs before
218
+ // discovery; a lazy sandbox materializes the latest resolved material only
219
+ // inside its first-operation single-flight.
193
220
  const initialRunCredentialMaterial = runCredentialResolver
194
221
  ? await waitForTurnOperation(
195
222
  runCredentialResolver.resolve({
@@ -200,6 +227,20 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
200
227
  undefined,
201
228
  )
202
229
  : null;
230
+ const runMcpCredentials = new RunMcpCredentials(
231
+ selectedSessionRemoteMcpTargets(
232
+ accountRoutes.settings,
233
+ session.mcpServers ?? [],
234
+ accountRoutes.tools,
235
+ (deps.localMcpServerIds ?? []).map((id) => ({ id })),
236
+ ),
237
+ {
238
+ ...(cancellationSignal ? { signal: cancellationSignal } : {}),
239
+ },
240
+ );
241
+ renewals.runMcpCredentials = runMcpCredentials;
242
+ runMcpCredentials.replace(initialRunCredentialMaterial);
243
+ let currentRunCredentialMaterial = initialRunCredentialMaterial;
203
244
  if (initialRunCredentialMaterial) {
204
245
  for (const payload of runCredentialAuthNeededPayloads(initialRunCredentialMaterial)) {
205
246
  renewals.publishedRunCredentialNotices.add(JSON.stringify(payload));
@@ -287,13 +328,10 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
287
328
  // provider may supply it; unset still self-mints GitHub from settings.
288
329
  // gitToken/gitTokens are undefined on the selfhosted skip path (the machine
289
330
  // uses its own git creds).
290
- // Git and MCP credentials share one lineage snapshot for this turn. A
291
- // host that supplies both ports must never see two independently resolved
292
- // roots for the same execution merely because the call sites are far apart.
331
+ // Git credential providers share one lineage snapshot for this turn.
332
+ // MCP access uses the native accepted connection context independently.
293
333
  const needsHostCredentialRoot = Boolean(
294
- connectionCredentials?.gitCredentials ||
295
- personalGitHubCredentials ||
296
- connectionCredentials?.mcpCredentials,
334
+ connectionCredentials?.gitCredentials || personalGitHubCredentials,
297
335
  );
298
336
  const hostCredentialRootSessionId = needsHostCredentialRoot
299
337
  ? await getSessionRootId(db, input.workspaceId, input.sessionId)
@@ -311,11 +349,13 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
311
349
  turn,
312
350
  })
313
351
  : undefined;
352
+ const credentialRestriction = turnCredentialRestriction(turnExecutionPolicy, session.metadata);
314
353
  const codemodeAuthority = {
315
354
  sessionId: input.sessionId,
316
355
  turnId: turn.id,
317
356
  attemptId: input.attemptId,
318
357
  executionGeneration: turn.executionGeneration,
358
+ ...(credentialRestriction ? { credentialRestriction } : {}),
319
359
  };
320
360
  const sandboxArtifactRuntime = sandboxArtifactRuntimeAdmission(
321
361
  settings,
@@ -333,7 +373,7 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
333
373
  } = await waitForTurnOperation(
334
374
  sandboxEnvironmentForRun(
335
375
  sandboxEnvironmentSettings,
336
- turnResources,
376
+ platformGitResources,
337
377
  // Rig default sets merged BELOW the session set (session wins); rig-less
338
378
  // turns pass exactly workspaceVariableSet?.values (byte-for-byte today).
339
379
  sandboxWorkspaceEnvironmentValues,
@@ -394,7 +434,7 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
394
434
  return Promise.resolve(undefined);
395
435
  }
396
436
  runGitCredentialsMint ??= waitForTurnOperation(
397
- mintRunGitCredentials(runSettings, turnResources, {
437
+ mintRunGitCredentials(runSettings, platformGitResources, {
398
438
  scope: connectionScope,
399
439
  ...(gitCredentialAuthority ? { authority: gitCredentialAuthority } : {}),
400
440
  gitCredentials: connectionCredentials?.gitCredentials,
@@ -428,7 +468,7 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
428
468
  mint: async () => {
429
469
  const binding = await mintRunGitCredentialBinding(
430
470
  runSettings,
431
- turnResources,
471
+ platformGitResources,
432
472
  initialBinding.provider,
433
473
  initialBinding.credentialBindingId,
434
474
  {
@@ -609,7 +649,7 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
609
649
  }
610
650
 
611
651
  const attachRunCredentialRenewal = async (
612
- credentialSession: RunCredentialCommandSession,
652
+ credentialSession: RunCredentialCommandSession | undefined,
613
653
  initialMaterial: NormalizedRunCredentialMaterial | null,
614
654
  initialSandbox?: ResumedTurnSandbox,
615
655
  ): Promise<void> => {
@@ -618,7 +658,8 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
618
658
  renewals.runCredentialRenewal = null;
619
659
  await previous?.stop();
620
660
  if (renewals.runCredentialRenewalClosed) return;
621
- renewals.runCredentialSession = credentialSession;
661
+ renewals.runCredentialSession = credentialSession ?? null;
662
+ initialMaterial = currentRunCredentialMaterial;
622
663
 
623
664
  const requireTargetSandbox = (): ResumedTurnSandbox => {
624
665
  const targetSandbox = sandboxState.resolvedSandbox ?? initialSandbox;
@@ -628,7 +669,7 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
628
669
  return targetSandbox;
629
670
  };
630
671
 
631
- if (!initialMaterial) {
672
+ if (!initialMaterial && credentialSession) {
632
673
  await runWorkspaceMutationForSandbox(
633
674
  requireTargetSandbox(),
634
675
  "runCredentialClear",
@@ -645,49 +686,60 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
645
686
  );
646
687
  return;
647
688
  }
689
+ if (!initialMaterial) return;
648
690
 
649
691
  const write = async (
650
692
  material: NormalizedRunCredentialMaterial | null,
651
693
  pruneOtherAttempts = false,
652
694
  ): Promise<void> => {
695
+ throwIfTurnOperationCancelled(cancellationSignal);
696
+ const applyMcpCredentials = runMcpCredentials.prepare(material);
653
697
  if (!material) {
698
+ if (credentialSession)
699
+ await runWorkspaceMutationForSandbox(
700
+ requireTargetSandbox(),
701
+ "runCredentialAttemptClear",
702
+ async () =>
703
+ await clearRunCredentialsForAttempt(credentialSession, {
704
+ sessionId: input.sessionId,
705
+ attemptId: input.attemptId,
706
+ executionGeneration: attempt.executionGeneration,
707
+ }),
708
+ );
709
+ throwIfTurnOperationCancelled(cancellationSignal);
710
+ applyMcpCredentials();
711
+ currentRunCredentialMaterial = material;
712
+ return;
713
+ }
714
+
715
+ if (credentialSession)
654
716
  await runWorkspaceMutationForSandbox(
655
717
  requireTargetSandbox(),
656
- "runCredentialAttemptClear",
718
+ "runCredentialMaterialization",
657
719
  async () =>
658
- await clearRunCredentialsForAttempt(credentialSession, {
720
+ await materializeRunCredentials(credentialSession, material, {
659
721
  sessionId: input.sessionId,
660
722
  attemptId: input.attemptId,
661
723
  executionGeneration: attempt.executionGeneration,
724
+ ...(pruneOtherAttempts ? { pruneOtherAttempts: true } : {}),
725
+ ...(!pruneOtherAttempts ? { pruneSupersededGenerations: true } : {}),
726
+ ...(material.authNeeded.length > 0 &&
727
+ Object.keys(material.environment).length === 0 &&
728
+ material.files.length === 0
729
+ ? { prunePreviousGenerations: true }
730
+ : {}),
731
+ ...(eventing.toolCancellationFenceRef.current
732
+ ? {
733
+ commandRunner: eventing.toolCancellationFenceRef.current.runSandboxCommand.bind(
734
+ eventing.toolCancellationFenceRef.current,
735
+ ),
736
+ }
737
+ : {}),
662
738
  }),
663
739
  );
664
- return;
665
- }
666
-
667
- await runWorkspaceMutationForSandbox(
668
- requireTargetSandbox(),
669
- "runCredentialMaterialization",
670
- async () =>
671
- await materializeRunCredentials(credentialSession, material, {
672
- sessionId: input.sessionId,
673
- attemptId: input.attemptId,
674
- executionGeneration: attempt.executionGeneration,
675
- ...(pruneOtherAttempts ? { pruneOtherAttempts: true } : {}),
676
- ...(!pruneOtherAttempts ? { pruneSupersededGenerations: true } : {}),
677
- ...(material.authNeeded.length > 0 &&
678
- Object.keys(material.environment).length === 0 &&
679
- material.files.length === 0
680
- ? { prunePreviousGenerations: true }
681
- : {}),
682
- ...(eventing.toolCancellationFenceRef.current
683
- ? {
684
- commandRunner: eventing.toolCancellationFenceRef.current.runSandboxCommand.bind(
685
- eventing.toolCancellationFenceRef.current,
686
- ),
687
- }
688
- : {}),
689
- }),
690
- );
740
+ throwIfTurnOperationCancelled(cancellationSignal);
741
+ applyMcpCredentials();
742
+ currentRunCredentialMaterial = material;
691
743
  for (const payload of runCredentialAuthNeededPayloads(material)) {
692
744
  const key = JSON.stringify(payload);
693
745
  if (renewals.publishedRunCredentialNotices.has(key)) continue;
@@ -696,18 +748,13 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
696
748
  }
697
749
  };
698
750
 
699
- const initialExpiryMs = initialMaterial.expiresAt?.getTime() ?? null;
700
- const seed =
701
- initialExpiryMs !== null && initialExpiryMs <= Date.now() + RUN_CREDENTIAL_EXPIRY_LEAD_MS
702
- ? await runCredentialResolver.resolve({
703
- purpose: "provision",
704
- forceRefresh: true,
705
- })
706
- : initialMaterial;
707
- await write(seed, true);
751
+ // Preserve the last good material even when an early refresh fails. Such
752
+ // refreshes are renewals, not fresh provisions that degrade to empty
753
+ // auth-needed state on a provider transport failure.
754
+ await write(initialMaterial, true);
708
755
  if (renewals.runCredentialRenewalClosed) return;
709
756
  const controller = startRunCredentialRenewalLoop({
710
- initialExpiresAt: seed?.expiresAt ?? null,
757
+ initialExpiresAt: runCredentialRenewalExpiry(initialMaterial),
711
758
  resolve: async () =>
712
759
  await runCredentialResolver.resolve({
713
760
  purpose: "renewal",
@@ -715,6 +762,7 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
715
762
  }),
716
763
  write: async (material) => await write(material),
717
764
  onSuccess: ({ authNeeded }) => {
765
+ renewals.runCredentialRenewalOutcome = authNeeded ? "auth_needed" : "completed";
718
766
  observability.incrementCounter({
719
767
  name: "opengeni_run_credential_renewals_total",
720
768
  help: "Host-managed run credential renewal attempts by outcome.",
@@ -722,6 +770,7 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
722
770
  });
723
771
  },
724
772
  onFailure: ({ retryDelayMs, errorClass }) => {
773
+ renewals.runCredentialRenewalOutcome = "error";
725
774
  observability.incrementCounter({
726
775
  name: "opengeni_run_credential_renewals_total",
727
776
  help: "Host-managed run credential renewal attempts by outcome.",
@@ -740,15 +789,27 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
740
789
  return;
741
790
  }
742
791
  renewals.runCredentialRenewal = controller;
792
+ const initialExpiryMs = runCredentialRenewalExpiry(initialMaterial)?.getTime() ?? null;
793
+ if (initialExpiryMs !== null && initialExpiryMs <= Date.now() + RUN_CREDENTIAL_EXPIRY_LEAD_MS) {
794
+ await controller.refreshNow();
795
+ throwIfTurnOperationCancelled(cancellationSignal);
796
+ }
743
797
  };
744
798
 
799
+ // Remote MCP-only turns may never establish a sandbox. Start the same
800
+ // single-flight, finalization-owned loop before transport discovery; attaching
801
+ // a sandbox later replaces its writer, not its credential authority.
802
+ if (initialRunCredentialMaterial) {
803
+ await attachRunCredentialRenewal(undefined, initialRunCredentialMaterial);
804
+ }
805
+
745
806
  return {
807
+ runMcpCredentials,
746
808
  runCredentialResolver,
747
809
  establishPolicy,
748
810
  initialRunCredentialMaterial,
749
811
  runCredentialsNote,
750
812
  authorizeGitHubTokenMint,
751
- hostCredentialRootSessionId,
752
813
  gitCredentialAuthority,
753
814
  codemodeAuthority,
754
815
  sandboxArtifactRuntime,