@opengeni/worker-bundle 0.27.3 → 0.28.3-canary.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 (37) hide show
  1. package/dist/activities/agent-turn/model-usage.d.ts +1 -1
  2. package/dist/activities/mcp-credentials.d.ts +3 -1
  3. package/dist/activities/sandbox-lease.d.ts +4 -4
  4. package/dist/activities/workspace-capture.d.ts +12 -1
  5. package/dist/{activities-control-WZRFEIJH.js → activities-control-JUBMDBDZ.js} +58 -73
  6. package/dist/activities-control-JUBMDBDZ.js.map +1 -0
  7. package/dist/{activities-turn-V7J34ZOF.js → activities-turn-I2ZKGZE6.js} +268 -187
  8. package/dist/activities-turn-I2ZKGZE6.js.map +1 -0
  9. package/dist/{chunk-BARTLVBK.js → chunk-A4XQWVZK.js} +25 -25
  10. package/dist/chunk-A4XQWVZK.js.map +1 -0
  11. package/dist/{chunk-C54VDT6I.js → chunk-ZNIKZQMN.js} +148 -111
  12. package/dist/chunk-ZNIKZQMN.js.map +1 -0
  13. package/dist/index.js +2 -2
  14. package/dist/observability-metrics.d.ts +12 -4
  15. package/dist/sandbox-archive-storage.d.ts +15 -3
  16. package/dist/sandbox-resume.d.ts +1 -1
  17. package/package.json +17 -17
  18. package/src/activities/agent-turn/agent-build.ts +30 -1
  19. package/src/activities/agent-turn/claim.ts +3 -3
  20. package/src/activities/agent-turn/finalization.ts +62 -41
  21. package/src/activities/agent-turn/model-usage.ts +10 -1
  22. package/src/activities/agent-turn/skill-read.ts +2 -21
  23. package/src/activities/agent-turn/stream-attempt.ts +3 -2
  24. package/src/activities/agent-turn/tool-environment.ts +52 -10
  25. package/src/activities/goals.ts +2 -0
  26. package/src/activities/mcp-credentials.ts +42 -2
  27. package/src/activities/sandbox-lease.ts +64 -71
  28. package/src/activities/scheduled-tasks.ts +8 -6
  29. package/src/activities/workspace-capture.ts +148 -126
  30. package/src/observability-metrics.ts +28 -24
  31. package/src/pr-review-credentials.ts +2 -0
  32. package/src/sandbox-archive-storage.ts +82 -18
  33. package/src/sandbox-resume.ts +79 -63
  34. package/dist/activities-control-WZRFEIJH.js.map +0 -1
  35. package/dist/activities-turn-V7J34ZOF.js.map +0 -1
  36. package/dist/chunk-BARTLVBK.js.map +0 -1
  37. package/dist/chunk-C54VDT6I.js.map +0 -1
@@ -48,7 +48,7 @@ export type CompactionModelUsageEventState = {
48
48
  export declare function createModelResponseEventState(claimedSourceKeys?: Set<string>): ModelResponseEventState;
49
49
  export declare function createCompactionModelUsageEventState(claimedSourceKeys?: Set<string>): CompactionModelUsageEventState;
50
50
  export declare const createSessionTitleModelUsageEventState: typeof createCompactionModelUsageEventState;
51
- export declare function modelResponseContextSignal(state: ModelResponseEventState): {
51
+ export declare function modelResponseContextSignal(state: ModelResponseEventState, responseCountBeforeStream?: number): {
52
52
  revision: number;
53
53
  totalTokens: number;
54
54
  } | null;
@@ -1,6 +1,6 @@
1
1
  import type { Settings } from "@opengeni/config";
2
2
  import type { ConnectionCredentialsPort } from "@opengeni/contracts";
3
- import { resolveAcceptedConnectionUse, sessionTenancyProductActivated, type Database, type ResolveConnectionCredentialInput, type ResolveConnectionCredentialResult, type SessionTurnForExecution } from "@opengeni/db";
3
+ import { getSessionTurnForAttempt, resolveAcceptedConnectionUse, sessionTenancyProductActivated, type Database, type ResolveConnectionCredentialInput, type ResolveConnectionCredentialResult, type SessionTurnForExecution } from "@opengeni/db";
4
4
  import { type Observability } from "@opengeni/observability";
5
5
  export declare function connectionTokenResolverForTurn(input: {
6
6
  db: Database;
@@ -13,6 +13,8 @@ export declare function connectionTokenResolverForTurn(input: {
13
13
  attemptId: string;
14
14
  turn: SessionTurnForExecution;
15
15
  authorizeAcceptedUse?: typeof resolveAcceptedConnectionUse;
16
+ /** Test seam; production always reads the canonical active-attempt projection. */
17
+ getHostTurnForAttempt?: typeof getSessionTurnForAttempt;
16
18
  /** Test seam for the activation fence on pre-snapshot workspace refs. */
17
19
  isSessionTenancyProductActivated?: typeof sessionTenancyProductActivated;
18
20
  /** Optional; used only for content-free compatibility-lane counters. */
@@ -2,7 +2,7 @@ import type { ProviderCommandPersistence } from "@opengeni/runtime";
2
2
  import { type OpStatus } from "@opengeni/agent-proto";
3
3
  import { listLiveModalSandboxLeaseAttributions, readLease, type ReapDrainable, type RetainedProcessProviderProof, type SandboxRetainedProcess, type LeaseSnapshot } from "@opengeni/db";
4
4
  import { type ConnectedMachineBackgroundCommandClaim, type ConnectedMachineBackgroundCommandProof } from "@opengeni/db/session-background-commands";
5
- import { createSandboxClientForBackend, inspectModalSandboxLifecycle, resolveModalCheckpointProviderBindingForSession, terminateModalSandboxById, type ModalOrphanSweepTermination, type ModalCheckpointProviderBinding, type ProviderWorkspaceCapturePolicy, type WorkspaceArchiveDescriptor, type ControlRpc } from "@opengeni/runtime/sandbox";
5
+ import { type VerifiedHostWorkspaceArchive, createSandboxClientForBackend, inspectModalSandboxLifecycle, resolveModalCheckpointProviderBindingForSession, terminateModalSandboxById, type ModalOrphanSweepTermination, type ModalCheckpointProviderBinding, type ProviderWorkspaceCapturePolicy, type WorkspaceArchiveDescriptor, type ControlRpc } from "@opengeni/runtime/sandbox";
6
6
  import { type SandboxDrainActivityInput, type SandboxLeaseSweepMaintenanceInput } from "../sandbox-reaper-contract.js";
7
7
  import type { ControlActivityServices as ActivityServices } from "./types.js";
8
8
  import { type RetainedProcessReconciliationOutcome } from "../observability-metrics.js";
@@ -40,7 +40,7 @@ type CreateSandboxClientForBackendFn = typeof createSandboxClientForBackend;
40
40
  * backends with no persistWorkspace — ensures a re-arm during the snapshot window
41
41
  * aborts the terminate before client.delete()).
42
42
  */
43
- export type PersistArchiveFn = (archiveBase64: string | null, archiveMetadata?: WorkspaceArchiveDescriptor, providerSession?: unknown, providerBinding?: Awaited<ReturnType<typeof resolveModalCheckpointProviderBindingForSession>> | null) => Promise<{
43
+ export type PersistArchiveFn = (archiveBase64: string | VerifiedHostWorkspaceArchive | null, archiveMetadata?: WorkspaceArchiveDescriptor, providerSession?: unknown, providerBinding?: Awaited<ReturnType<typeof resolveModalCheckpointProviderBindingForSession>> | null) => Promise<{
44
44
  wrote: boolean;
45
45
  archiveRevision?: string | null;
46
46
  }>;
@@ -60,7 +60,7 @@ export type DrainCaptureDisposition = "capture_required" | "archive_published";
60
60
  * Test seams may return the legacy boolean shorthand. Production returns the
61
61
  * typed outcome so the cold commit can distinguish a clean stop from definitive
62
62
  * provider disappearance before capture. */
63
- export type TerminateBoxFn = (settings: ActivityServices["settings"], lease: NonNullable<Awaited<ReturnType<typeof readLease>>>, observability: ActivityServices["observability"], persistArchive: PersistArchiveFn, providerCaptureRequestId?: string, captureDisposition?: DrainCaptureDisposition, capturePolicy?: ProviderWorkspaceCapturePolicy | null) => Promise<boolean | ProviderTerminationOutcome>;
63
+ export type TerminateBoxFn = (settings: ActivityServices["settings"], lease: NonNullable<Awaited<ReturnType<typeof readLease>>>, observability: ActivityServices["observability"], persistArchive: PersistArchiveFn, providerCaptureRequestId?: string, captureDisposition?: DrainCaptureDisposition, capturePolicy?: ProviderWorkspaceCapturePolicy | null, diskBackedArchives?: boolean) => Promise<boolean | ProviderTerminationOutcome>;
64
64
  export type SweepModalOrphansFn = (settings: ActivityServices["settings"], db: ActivityServices["db"], observability: ActivityServices["observability"]) => Promise<number>;
65
65
  export type InspectOpenSandboxKubernetesInventoryFn = (input: {
66
66
  namespace: string;
@@ -199,4 +199,4 @@ export declare function sandboxDrainReason(lease: Pick<LeaseSnapshot, "rotationR
199
199
  * draining until its adapter can prove termination. A truly instance-less or
200
200
  * `none`-backed row is a no-op.
201
201
  */
202
- export declare function terminateProviderBox(settings: ActivityServices["settings"], lease: NonNullable<Awaited<ReturnType<typeof readLease>>>, observability: ActivityServices["observability"], persistArchive: PersistArchiveFn, createClientForBackend?: CreateSandboxClientForBackendFn, terminateModalById?: typeof terminateModalSandboxById, providerCaptureRequestId?: string, captureDisposition?: DrainCaptureDisposition, claimedCapturePolicy?: ProviderWorkspaceCapturePolicy | null): Promise<ProviderTerminationOutcome>;
202
+ export declare function terminateProviderBox(settings: ActivityServices["settings"], lease: NonNullable<Awaited<ReturnType<typeof readLease>>>, observability: ActivityServices["observability"], persistArchive: PersistArchiveFn, createClientForBackend?: CreateSandboxClientForBackendFn, terminateModalById?: typeof terminateModalSandboxById, providerCaptureRequestId?: string, captureDisposition?: DrainCaptureDisposition, claimedCapturePolicy?: ProviderWorkspaceCapturePolicy | null, diskBackedArchives?: boolean): Promise<ProviderTerminationOutcome>;
@@ -92,6 +92,15 @@ export declare function openFreshWorkspaceCaptureSession(input: {
92
92
  /** One discovered repository is all-or-nothing capture authority. A provider
93
93
  * transport failure must never be represented as an authoritative empty diff. */
94
94
  export declare function readCaptureRepository(svc: Pick<SandboxChannelAService, "gitStatus" | "gitDiff">, root: string): Promise<CaptureRepositoryReadResult>;
95
+ /** Review work may use idle time, but must yield to the next turn. Poll durable
96
+ * queue state rather than relying on best-effort event delivery. The capture
97
+ * already fences every continuation on this signal; no replacement writer is
98
+ * admitted until its caller returns. */
99
+ export declare function captureWhileIdle(input: {
100
+ hasPendingWork: () => Promise<boolean>;
101
+ capture: (signal: AbortSignal) => Promise<void>;
102
+ signal?: AbortSignal;
103
+ }): Promise<void>;
95
104
  /**
96
105
  * Turn-end entrypoint. Gates on the flag + configured object storage, races the
97
106
  * whole capture against a 120s cap, and swallows every failure ("turn outcome
@@ -110,6 +119,8 @@ export declare function captureWorkspaceRevision(input: CaptureWorkspaceRevision
110
119
  export declare function changeFingerprint(repos: WorkspaceCaptureRepo[], files: WorkspaceCaptureFile[]): string;
111
120
  /** Join a repo-root-relative path onto its workspace-relative repo root. */
112
121
  export declare function joinRepoPath(repoRoot: string, repoRelPath: string): string;
113
- /** Content-addressed after-image blob key (shared across revisions → GC input). */
122
+ /** Content-addressed after-image blob key, optionally in a unique capture namespace. */
114
123
  export declare function blobKey(workspaceId: string, sessionId: string, sha256Hex: string): string;
124
+ /** Only pass the latest retained revision's keys: older refs may be under deletion. */
125
+ export declare function retainedCaptureBlobRefs(workspaceId: string, sessionId: string, latestKeys: string[]): Map<string, string>;
115
126
  export {};
@@ -10,18 +10,16 @@ import {
10
10
  MAX_AUTOMATIC_PROVIDER_RECOVERIES,
11
11
  assertReusableSessionRevivable,
12
12
  captureConnectedCommandOutput,
13
- collectWorkspaceArchiveObjectKeys,
14
13
  createCodexCapacityActivities,
15
14
  createGoalActivities,
16
15
  createSharedActivityServices,
17
16
  currentActivityContext,
18
- deleteUnpublishedWorkspaceArchiveObject,
19
- deleteWorkspaceArchiveObjectKeys,
20
17
  deliverFailedChildTurnToParent,
21
18
  evaluateIncidentTelemetryPreflight,
22
19
  incidentTelemetryAuthorityFence,
23
20
  incidentTelemetryPreflightDeclaration,
24
21
  notifyParentOfChildIdle,
22
+ persistWorkspaceArchiveCandidate,
25
23
  providerRecoveryCountFromMetadata,
26
24
  putVersion1TarArchiveOrInline,
27
25
  reconcileAutomaticSessionTitleFanout,
@@ -33,7 +31,7 @@ import {
33
31
  scheduledUserMessagePayload,
34
32
  withFirstPartyTools,
35
33
  workflowIdForSession
36
- } from "./chunk-C54VDT6I.js";
34
+ } from "./chunk-ZNIKZQMN.js";
37
35
  import {
38
36
  inspectOpenSandboxKubernetesInventory,
39
37
  recordCreditBalanceGauges,
@@ -53,7 +51,7 @@ import {
53
51
  recordTurnsQueuedGauge,
54
52
  recordWorkerDeathRecoveryMetrics,
55
53
  runtimeMetricsHooksForObservability
56
- } from "./chunk-BARTLVBK.js";
54
+ } from "./chunk-A4XQWVZK.js";
57
55
 
58
56
  // src/activities/browser-state-artifact-reaper.ts
59
57
  import {
@@ -5243,7 +5241,8 @@ import { sandboxWarmRateMicrosPerSecond } from "@opengeni/config";
5243
5241
  import { appendSessionCommandOutput } from "@opengeni/db/session-command-output";
5244
5242
  import { sandboxLeaseTelemetryKey } from "@opengeni/observability";
5245
5243
  import {
5246
- captureVerifiedWorkspaceArchive,
5244
+ captureWorkspaceArchiveForStorage,
5245
+ disposeWorkspaceArchive,
5247
5246
  cancelSelfhostedOp,
5248
5247
  assertConsistentSandboxProviderIdentity,
5249
5248
  createSandboxClientForBackend,
@@ -5362,7 +5361,7 @@ function sandboxDrainActivityAttempt() {
5362
5361
  }
5363
5362
  }
5364
5363
  function createSandboxLeaseActivities(services, options = {}) {
5365
- const terminateBox = options.terminateBox ?? (async (settings, lease, observability, persistArchive, providerCaptureRequestId, captureDisposition, capturePolicy) => await terminateProviderBox(
5364
+ const terminateBox = options.terminateBox ?? (async (settings, lease, observability, persistArchive, providerCaptureRequestId, captureDisposition, capturePolicy, diskBackedArchives) => await terminateProviderBox(
5366
5365
  settings,
5367
5366
  lease,
5368
5367
  observability,
@@ -5371,7 +5370,8 @@ function createSandboxLeaseActivities(services, options = {}) {
5371
5370
  terminateModalSandboxById,
5372
5371
  providerCaptureRequestId,
5373
5372
  captureDisposition,
5374
- capturePolicy
5373
+ capturePolicy,
5374
+ diskBackedArchives
5375
5375
  ));
5376
5376
  const sweepModalOrphans = options.sweepModalOrphans ?? sweepModalOrphansForConfiguredBackend;
5377
5377
  const inspectOpenSandboxInventory = options.inspectOpenSandboxKubernetesInventory ?? inspectOpenSandboxKubernetesInventory;
@@ -7044,7 +7044,7 @@ async function terminateDrainableBox(db, settings, row, observability, terminate
7044
7044
  }
7045
7045
  const archiveMetrics = runtimeMetricsHooksForObservability(observability);
7046
7046
  let checkpointArtifactId = null;
7047
- if (archiveBase64 && archiveMetadata?.version === 2 && (archiveMetadata.provider === "modal_snapshot_filesystem" || archiveMetadata.provider === "modal_snapshot_directory")) {
7047
+ if (typeof archiveBase64 === "string" && archiveBase64 && archiveMetadata?.version === 2 && (archiveMetadata.provider === "modal_snapshot_filesystem" || archiveMetadata.provider === "modal_snapshot_directory")) {
7048
7048
  if (!providerBinding) {
7049
7049
  throw new Error("Modal native snapshot has no exact session provider identity");
7050
7050
  }
@@ -7084,57 +7084,29 @@ async function terminateDrainableBox(db, settings, row, observability, terminate
7084
7084
  if (!archiveMetadata) {
7085
7085
  throw new Error("Sandbox snapshot publication requires a verified archive descriptor");
7086
7086
  }
7087
- const priorKeys = collectWorkspaceArchiveObjectKeys(
7088
- lease.resumeState ?? null
7089
- );
7090
- let workspaceArchiveRef;
7091
- try {
7092
- const published = await putVersion1TarArchiveOrInline({
7093
- backend: lease.backend,
7094
- objectStorage,
7095
- accountId,
7096
- workspaceId: row.workspaceId,
7097
- sandboxGroupId: row.sandboxGroupId,
7098
- archive: {
7099
- bytes: Buffer.from(archiveBase64, "base64"),
7100
- descriptor: archiveMetadata,
7101
- base64: archiveBase64
7102
- },
7103
- metrics: archiveMetrics
7104
- });
7105
- workspaceArchiveRef = published.workspaceArchiveRef;
7106
- result = await persistDrainSnapshot(db, {
7087
+ const published = await putVersion1TarArchiveOrInline({
7088
+ backend: lease.backend,
7089
+ objectStorage,
7090
+ accountId,
7091
+ workspaceId: row.workspaceId,
7092
+ sandboxGroupId: row.sandboxGroupId,
7093
+ archive: typeof archiveBase64 === "object" ? archiveBase64 : {
7094
+ bytes: Buffer.from(archiveBase64, "base64"),
7095
+ descriptor: archiveMetadata,
7096
+ base64: archiveBase64
7097
+ },
7098
+ metrics: archiveMetrics
7099
+ });
7100
+ result = await persistWorkspaceArchiveCandidate({
7101
+ objectStorage,
7102
+ ...published.workspaceArchiveRef ? { ref: published.workspaceArchiveRef } : {},
7103
+ persist: () => persistDrainSnapshot(db, {
7107
7104
  ...baseInput,
7108
7105
  workspaceArchiveMeta: archiveMetadata,
7109
7106
  ...published,
7110
7107
  ...checkpointArtifactId ? { checkpointArtifactId } : {}
7111
- });
7112
- if (published.workspaceArchiveRef && objectStorage) {
7113
- if (!result.wrote) {
7114
- await deleteUnpublishedWorkspaceArchiveObject(
7115
- objectStorage,
7116
- published.workspaceArchiveRef,
7117
- archiveMetrics
7118
- );
7119
- } else {
7120
- const afterLease = await readLease(db, row.workspaceId, row.sandboxGroupId);
7121
- const afterKeys = collectWorkspaceArchiveObjectKeys(
7122
- afterLease?.resumeState ?? null
7123
- );
7124
- await deleteWorkspaceArchiveObjectKeys(
7125
- objectStorage,
7126
- [...priorKeys].filter((key) => !afterKeys.has(key))
7127
- ).catch(() => void 0);
7128
- }
7129
- }
7130
- } catch (error) {
7131
- await deleteUnpublishedWorkspaceArchiveObject(
7132
- objectStorage,
7133
- workspaceArchiveRef,
7134
- archiveMetrics
7135
- );
7136
- throw error;
7137
- }
7108
+ })
7109
+ });
7138
7110
  }
7139
7111
  if (!result.wrote && checkpointArtifactId) {
7140
7112
  await markSandboxCheckpointArtifactDeletePending2(db, {
@@ -7157,7 +7129,8 @@ async function terminateDrainableBox(db, settings, row, observability, terminate
7157
7129
  persistArchive,
7158
7130
  captureClaim?.providerRequestId ?? attempt.operationId,
7159
7131
  captureDisposition,
7160
- capturePolicy
7132
+ capturePolicy,
7133
+ Boolean(objectStorage)
7161
7134
  );
7162
7135
  const terminated = typeof termination === "boolean" ? termination : termination.terminated;
7163
7136
  if (!terminated) {
@@ -7213,7 +7186,7 @@ function providerDrainLogIdentity(lease, backend) {
7213
7186
  instanceId: lease.instanceId
7214
7187
  };
7215
7188
  }
7216
- async function terminateProviderBox(settings, lease, observability, persistArchive, createClientForBackend = createSandboxClientForBackend, terminateModalById = terminateModalSandboxById, providerCaptureRequestId, captureDisposition = "capture_required", claimedCapturePolicy) {
7189
+ async function terminateProviderBox(settings, lease, observability, persistArchive, createClientForBackend = createSandboxClientForBackend, terminateModalById = terminateModalSandboxById, providerCaptureRequestId, captureDisposition = "capture_required", claimedCapturePolicy, diskBackedArchives = false) {
7217
7190
  const durableBackendId = lease.resumeBackendId ?? lease.backend;
7218
7191
  const backend = sandboxBackendForSdkBackendId(durableBackendId) ?? durableBackendId;
7219
7192
  const logIdentity = providerDrainLogIdentity(lease, backend);
@@ -7335,10 +7308,15 @@ async function terminateProviderBox(settings, lease, observability, persistArchi
7335
7308
  ) : null;
7336
7309
  try {
7337
7310
  if (captureDisposition !== "archive_published" && session?.persistWorkspace) {
7338
- const capture = captureVerifiedWorkspaceArchive(session, Date.now(), {
7339
- requestId: providerCaptureRequestId ?? randomUUID2(),
7340
- strategy: liveCapturePolicy.strategy
7341
- });
7311
+ const capture = captureWorkspaceArchiveForStorage(
7312
+ session,
7313
+ Date.now(),
7314
+ {
7315
+ requestId: providerCaptureRequestId ?? randomUUID2(),
7316
+ strategy: liveCapturePolicy.strategy
7317
+ },
7318
+ diskBackedArchives
7319
+ );
7342
7320
  verifiedArchive = await awaitProviderCaptureWithLatePublication({
7343
7321
  capture,
7344
7322
  timeoutMs: settings.sandboxSnapshotTimeoutMs,
@@ -7352,7 +7330,7 @@ async function terminateProviderBox(settings, lease, observability, persistArchi
7352
7330
  publishLate: async (archive) => {
7353
7331
  try {
7354
7332
  const result = await persistArchive(
7355
- archive.base64,
7333
+ archive.kind === "host_spool" ? archive : archive.base64,
7356
7334
  archive.descriptor,
7357
7335
  session,
7358
7336
  checkpointBinding
@@ -7368,6 +7346,8 @@ async function terminateProviderBox(settings, lease, observability, persistArchi
7368
7346
  ...logIdentity,
7369
7347
  error: error instanceof Error ? error.message : String(error)
7370
7348
  });
7349
+ } finally {
7350
+ await disposeWorkspaceArchive(archive);
7371
7351
  }
7372
7352
  },
7373
7353
  observeLateFailure: (error) => {
@@ -7399,12 +7379,17 @@ async function terminateProviderBox(settings, lease, observability, persistArchi
7399
7379
  ...logIdentity
7400
7380
  });
7401
7381
  } else if (verifiedArchive) {
7402
- const { wrote } = await persistArchive(
7403
- verifiedArchive.base64,
7404
- verifiedArchive.descriptor,
7405
- session,
7406
- checkpointBinding
7407
- );
7382
+ let wrote;
7383
+ try {
7384
+ ({ wrote } = await persistArchive(
7385
+ verifiedArchive.kind === "host_spool" ? verifiedArchive : verifiedArchive.base64,
7386
+ verifiedArchive.descriptor,
7387
+ session,
7388
+ checkpointBinding
7389
+ ));
7390
+ } finally {
7391
+ await disposeWorkspaceArchive(verifiedArchive);
7392
+ }
7408
7393
  if (!wrote) {
7409
7394
  observability.info(
7410
7395
  "sandbox reaper: lease re-armed during persist \u2014 leaving box RUNNING (no terminate)",
@@ -7448,7 +7433,6 @@ import {
7448
7433
  SCHEDULED_TASK_OCCURRENCE_PAYLOAD_MAX_BYTES,
7449
7434
  ScheduledTaskRunAcceptedExecution,
7450
7435
  SessionAgentAccess,
7451
- SessionEndUser,
7452
7436
  SessionMemoryScope,
7453
7437
  normalizeAutomaticSessionTitle,
7454
7438
  scheduledOccurrencePayloadUtf8Bytes,
@@ -9564,11 +9548,12 @@ async function replayScheduledTaskDispatch(input) {
9564
9548
  function scheduledCreatorSessionPolicyInput(policy) {
9565
9549
  if (!policy) return {};
9566
9550
  const agentAccess = SessionAgentAccess.safeParse(policy.agentAccess);
9567
- const endUser = SessionEndUser.safeParse(policy.endUser);
9568
9551
  const memoryScope = SessionMemoryScope.safeParse(policy.memoryScope);
9569
9552
  return {
9570
9553
  ...agentAccess.success ? { agentAccess: agentAccess.data } : {},
9571
- ...endUser.success ? { endUser: endUser.data } : {},
9554
+ // This is a trusted DB admission input, not the public create payload.
9555
+ // Preserve the immutable creator policy through scheduled materialization.
9556
+ ...policy.scopeSubjectId && /^(?:user:|external_user:).+/u.test(policy.scopeSubjectId) ? { scopeSubjectId: policy.scopeSubjectId } : {},
9572
9557
  ...memoryScope.success ? { memoryScope: memoryScope.data } : {}
9573
9558
  };
9574
9559
  }
@@ -10350,4 +10335,4 @@ export {
10350
10335
  createControlActivities,
10351
10336
  createControlActivitiesFromServices
10352
10337
  };
10353
- //# sourceMappingURL=activities-control-WZRFEIJH.js.map
10338
+ //# sourceMappingURL=activities-control-JUBMDBDZ.js.map