deepline 0.3.284 → 0.3.285

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 (34) hide show
  1. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  2. package/dist/bundling-sources/shared_libs/play-runtime/activity-observation.ts +26 -2
  3. package/dist/bundling-sources/shared_libs/play-runtime/batch-runtime.ts +7 -0
  4. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +817 -2236
  5. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +19 -6
  6. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +127 -789
  7. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +180 -14
  8. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +1 -0
  9. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +3 -22
  10. package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +26 -0
  11. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +50 -8
  12. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +122 -18
  13. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +218 -41
  14. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +20 -2
  15. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +13 -2
  16. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/receipt-cohort.ts +181 -326
  17. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +38 -151
  18. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +8 -0
  19. package/dist/cli/index.js +28 -3
  20. package/dist/cli/index.mjs +28 -3
  21. package/dist/{client-B0AjIkgb.d.mts → client-Cl-zj2oS.d.mts} +4 -0
  22. package/dist/{client-BCXQ_Ftc.d.ts → client-T2jVnZrq.d.ts} +4 -0
  23. package/dist/index.d.mts +2 -2
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +25 -1
  26. package/dist/index.mjs +25 -1
  27. package/dist/install-integrity.json +2 -2
  28. package/dist/plays/run-request.d.mts +1 -1
  29. package/dist/plays/run-request.d.ts +1 -1
  30. package/dist/release.d.mts +1 -1
  31. package/dist/release.d.ts +1 -1
  32. package/dist/release.js +1 -1
  33. package/dist/release.mjs +1 -1
  34. package/package.json +1 -1
@@ -606,6 +606,8 @@ export type PostgresSchedulerRunStatusSnapshot = {
606
606
  runId: string;
607
607
  /** Owning org from the scheduler runs row; '' on pre-org legacy rows. */
608
608
  orgId: string;
609
+ /** Included only for callers that explicitly request admission identity. */
610
+ definitionScope?: 'org' | 'system';
609
611
  status: string;
610
612
  playName: string;
611
613
  graphHash: string | null;
@@ -630,6 +632,7 @@ type RunStatusRow = RunRow & {
630
632
  graph_hash: string | null;
631
633
  runtime_profile: string | null;
632
634
  launch_json: unknown;
635
+ definition_scope?: string | null;
633
636
  suspension_json: unknown | null;
634
637
  updated_at: Date | null;
635
638
  };
@@ -5649,6 +5652,7 @@ export class PostgresSchedulerCronLaunchConflictError extends PostgresSchedulerC
5649
5652
  */
5650
5653
  export type PostgresSchedulerCronSourcePin = {
5651
5654
  orgId: string;
5655
+ definitionScope?: 'org' | 'system';
5652
5656
  userId: string | null;
5653
5657
  playName: string;
5654
5658
  revisionId: string | null;
@@ -5675,6 +5679,9 @@ export function postgresSchedulerCronSourcePinFromLaunch(
5675
5679
  : null;
5676
5680
  return {
5677
5681
  orgId: launch.orgId,
5682
+ ...(launch.definitionScope === 'org' || launch.definitionScope === 'system'
5683
+ ? { definitionScope: launch.definitionScope }
5684
+ : {}),
5678
5685
  userId: launch.userId ?? null,
5679
5686
  playName: launch.playName,
5680
5687
  revisionId: launch.revisionId ?? null,
@@ -5785,7 +5792,23 @@ export async function seedPostgresSchedulerCronSchedule(
5785
5792
  schedule.cron = $4::text
5786
5793
  AND schedule.timezone IS NOT DISTINCT FROM $5::text
5787
5794
  AND schedule.current_due_at = to_timestamp($3::double precision / 1000.0)
5788
- AND schedule.source_pin_json = $6::jsonb
5795
+ AND (
5796
+ schedule.source_pin_json = $6::jsonb
5797
+ OR (
5798
+ schedule.source_pin_json - 'definitionScope' =
5799
+ $6::jsonb - 'definitionScope'
5800
+ AND (
5801
+ (
5802
+ NOT (schedule.source_pin_json ? 'definitionScope')
5803
+ AND $6::jsonb ->> 'definitionScope' = 'org'
5804
+ )
5805
+ OR (
5806
+ NOT ($6::jsonb ? 'definitionScope')
5807
+ AND schedule.source_pin_json ->> 'definitionScope' = 'org'
5808
+ )
5809
+ )
5810
+ )
5811
+ )
5789
5812
  ) AS matches_input
5790
5813
  FROM schedule_lock
5791
5814
  JOIN ${tableName(POSTGRES_SCHEDULER_CRON_SCHEDULES_TABLE, options)} AS schedule
@@ -7083,16 +7106,21 @@ export async function assignPostgresSchedulerRunAttempt(
7083
7106
  SELECT
7084
7107
  runs.run_id,
7085
7108
  runs.started_at,
7086
- max(attempts.attempt) AS active_attempt
7109
+ max(attempts.attempt) FILTER (
7110
+ WHERE attempts.status IN ('claimed', 'running', 'waiting')
7111
+ ) AS active_attempt
7087
7112
  FROM locked_run AS runs
7088
7113
  LEFT JOIN ${tableName('attempts', options)} AS attempts
7089
7114
  ON attempts.run_id = runs.run_id
7090
- AND attempts.status IN ('claimed', 'running', 'waiting')
7091
7115
  WHERE runs.run_id = $1
7092
7116
  AND runs.status IN ('queued', 'running', 'waiting')
7093
7117
  GROUP BY runs.run_id, runs.started_at
7094
- HAVING max(attempts.attempt) IS NULL
7095
- OR max(attempts.attempt) < $2
7118
+ HAVING max(attempts.attempt) FILTER (
7119
+ WHERE attempts.status IN ('claimed', 'running', 'waiting')
7120
+ ) IS NULL
7121
+ OR max(attempts.attempt) FILTER (
7122
+ WHERE attempts.status IN ('claimed', 'running', 'waiting')
7123
+ ) < $2
7096
7124
  ),
7097
7125
  assigned AS (
7098
7126
  INSERT INTO ${tableName('attempts', options)} (
@@ -7124,6 +7152,45 @@ export async function assignPostgresSchedulerRunAttempt(
7124
7152
  AND attempt < $2
7125
7153
  AND status IN ('claimed', 'running', 'waiting')
7126
7154
  ),
7155
+ -- A run can only have one live, unbound Daytona create in flight. Reuse
7156
+ -- its durable provider identity across attempt retries and move its
7157
+ -- fence to the new owner; the provider idempotency key makes replay safe.
7158
+ adopted_daytona_operations AS (
7159
+ UPDATE ${tableName('runtime_sandbox_operations', options)} AS operation
7160
+ SET attempt = $2,
7161
+ updated_at = clock_timestamp()
7162
+ FROM target_run
7163
+ JOIN assigned USING (run_id)
7164
+ WHERE operation.run_id = target_run.run_id
7165
+ AND operation.attempt < $2
7166
+ AND operation.provider = 'daytona'
7167
+ AND operation.state = 'reserved'
7168
+ AND EXISTS (
7169
+ SELECT 1
7170
+ FROM ${tableName('runtime_sandbox_capacity_leases', options)} AS lease
7171
+ WHERE lease.lease_id = operation.operation_key
7172
+ AND lease.released_at IS NULL
7173
+ AND lease.sandbox_id IS NULL
7174
+ AND lease.expires_at > clock_timestamp()
7175
+ )
7176
+ AND 1 = (
7177
+ SELECT count(*)
7178
+ FROM ${tableName('runtime_sandbox_operations', options)} AS pending
7179
+ WHERE pending.run_id = target_run.run_id
7180
+ AND pending.attempt < $2
7181
+ AND pending.provider = 'daytona'
7182
+ AND pending.state = 'reserved'
7183
+ AND EXISTS (
7184
+ SELECT 1
7185
+ FROM ${tableName('runtime_sandbox_capacity_leases', options)} AS pending_lease
7186
+ WHERE pending_lease.lease_id = pending.operation_key
7187
+ AND pending_lease.released_at IS NULL
7188
+ AND pending_lease.sandbox_id IS NULL
7189
+ AND pending_lease.expires_at > clock_timestamp()
7190
+ )
7191
+ )
7192
+ RETURNING operation.operation_key
7193
+ ),
7127
7194
  first_start AS (
7128
7195
  SELECT assigned.run_id
7129
7196
  FROM assigned
@@ -10096,7 +10163,11 @@ export async function markPostgresSchedulerRuntimeResourceDetached(
10096
10163
 
10097
10164
  export async function readPostgresSchedulerRuntimeResourcesForRun(
10098
10165
  client: PostgresSchedulerQueryClient,
10099
- input: { runId: string; attempt?: number | null },
10166
+ input: {
10167
+ runId: string;
10168
+ attempt?: number | null;
10169
+ throughAttempt?: number;
10170
+ },
10100
10171
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
10101
10172
  ): Promise<unknown[]> {
10102
10173
  const resources = await client.query<{ resource_json: unknown }>(
@@ -10105,10 +10176,11 @@ export async function readPostgresSchedulerRuntimeResourcesForRun(
10105
10176
  FROM ${tableName('attempts', options)}
10106
10177
  WHERE run_id = $1
10107
10178
  AND ($2::integer IS NULL OR attempt = $2)
10179
+ AND ($3::integer IS NULL OR attempt <= $3)
10108
10180
  AND resource_json IS NOT NULL
10109
10181
  ORDER BY attempt DESC
10110
10182
  `,
10111
- [input.runId, input.attempt ?? null],
10183
+ [input.runId, input.attempt ?? null, input.throughAttempt ?? null],
10112
10184
  );
10113
10185
  return resources.rows.flatMap((row) =>
10114
10186
  Array.isArray(row.resource_json) ? row.resource_json : [row.resource_json],
@@ -10137,6 +10209,7 @@ export async function settlePostgresSchedulerRuntimeResources(
10137
10209
  | 'runtime_limit'
10138
10210
  | 'cancelled'
10139
10211
  | 'lease_expired';
10212
+ throughAttempt?: number;
10140
10213
  },
10141
10214
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
10142
10215
  ): Promise<number> {
@@ -10169,6 +10242,7 @@ export async function settlePostgresSchedulerRuntimeResources(
10169
10242
  ),
10170
10243
  updated_at = now()
10171
10244
  WHERE run_id = $1
10245
+ AND ($4::integer IS NULL OR attempt <= $4)
10172
10246
  AND resource_json IS NOT NULL
10173
10247
  AND jsonb_typeof(resource_json) = 'array'
10174
10248
  AND EXISTS (
@@ -10182,7 +10256,12 @@ export async function settlePostgresSchedulerRuntimeResources(
10182
10256
  )
10183
10257
  RETURNING run_id
10184
10258
  `,
10185
- [input.runId, input.billingEndedAt, input.terminalReason],
10259
+ [
10260
+ input.runId,
10261
+ input.billingEndedAt,
10262
+ input.terminalReason,
10263
+ input.throughAttempt ?? null,
10264
+ ],
10186
10265
  );
10187
10266
  return stamped.rows.length;
10188
10267
  }
@@ -11605,7 +11684,7 @@ export async function enqueuePostgresSchedulerSandboxCleanupForAttempt(
11605
11684
  * admits the current runner before cancellation terminalizes. */
11606
11685
  export async function enqueuePostgresSchedulerSandboxCleanupForRun(
11607
11686
  client: PostgresSchedulerQueryClient,
11608
- input: { runId: string },
11687
+ input: { runId: string; throughAttempt?: number },
11609
11688
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
11610
11689
  ): Promise<void> {
11611
11690
  await client.query(
@@ -11639,6 +11718,7 @@ export async function enqueuePostgresSchedulerSandboxCleanupForRun(
11639
11718
  END
11640
11719
  ) AS resource
11641
11720
  WHERE attempt.run_id = $1
11721
+ AND ($2::integer IS NULL OR attempt.attempt <= $2)
11642
11722
  AND attempt.resource_json IS NOT NULL
11643
11723
  AND resource->>'kind' IN ('daytona_sandbox', 'modal_sandbox')
11644
11724
  AND NULLIF(resource->>'sandboxId', '') IS NOT NULL
@@ -11648,12 +11728,13 @@ export async function enqueuePostgresSchedulerSandboxCleanupForRun(
11648
11728
  operation.attempt, operation.environment, operation.routing_domain
11649
11729
  FROM ${tableName('runtime_sandbox_operations', options)} AS operation
11650
11730
  WHERE operation.run_id = $1
11731
+ AND ($2::integer IS NULL OR operation.attempt <= $2)
11651
11732
  AND operation.state IN ('live', 'deleting')
11652
11733
  AND operation.sandbox_id IS NOT NULL
11653
11734
  AND NOT ${protectedDetachedSandboxSql({ runId: 'operation.run_id', provider: 'operation.provider', sandboxId: 'operation.sandbox_id', routingDomain: 'operation.routing_domain' }, options)}
11654
11735
  ON CONFLICT (provider, sandbox_id, routing_domain_key) DO NOTHING
11655
11736
  `,
11656
- [input.runId],
11737
+ [input.runId, input.throughAttempt ?? null],
11657
11738
  );
11658
11739
  }
11659
11740
 
@@ -11734,6 +11815,7 @@ export async function claimPostgresSchedulerSandboxCleanupJobs(
11734
11815
  input: {
11735
11816
  leaseOwner: string;
11736
11817
  runId?: string;
11818
+ throughAttempt?: number;
11737
11819
  limit?: number;
11738
11820
  leaseSeconds?: number;
11739
11821
  environment?: string | null;
@@ -11828,6 +11910,7 @@ export async function claimPostgresSchedulerSandboxCleanupJobs(
11828
11910
  AND ($4::text IS NULL OR cleanup.environment = $4)
11829
11911
  AND ($5::text[] IS NULL OR cleanup.provider = ANY($5::text[]))
11830
11912
  AND ($8::text IS NULL OR cleanup.run_id = $8)
11913
+ AND ($9::integer IS NULL OR cleanup.attempt <= $9)
11831
11914
  AND NOT ${protectedDetachedSandboxSql({ runId: 'cleanup.run_id', provider: 'cleanup.provider', sandboxId: 'cleanup.sandbox_id', routingDomain: 'cleanup.routing_domain' }, options)}
11832
11915
  ORDER BY
11833
11916
  CASE WHEN cleanup.diagnostic_json IS NOT NULL THEN 0 ELSE 1 END ASC,
@@ -11914,6 +11997,7 @@ export async function claimPostgresSchedulerSandboxCleanupJobs(
11914
11997
  RuntimeSandboxOperationState.Deleting,
11915
11998
  RuntimeSandboxOperationState.Live,
11916
11999
  input.runId ?? null,
12000
+ input.throughAttempt ?? null,
11917
12001
  ],
11918
12002
  );
11919
12003
  return claimed.rows.map((row) => ({
@@ -16914,8 +16998,12 @@ export async function readPostgresSchedulerRunStatus(
16914
16998
  runId: string,
16915
16999
  options?: Pick<PostgresSchedulerOptions, 'schema'> & {
16916
17000
  includeDetails?: boolean;
17001
+ includeAdmissionScope?: boolean;
16917
17002
  },
16918
17003
  ): Promise<PostgresSchedulerRunStatusSnapshot | null> {
17004
+ const admissionScopeSelection = options?.includeAdmissionScope
17005
+ ? ", launch_json ->> 'definitionScope' AS definition_scope"
17006
+ : '';
16919
17007
  if (options?.includeDetails === false) {
16920
17008
  // An admission projection gap needs lifecycle truth only. Launch, result,
16921
17009
  // suspension and error JSON may contain row/call-sized detail: never even
@@ -16933,11 +17021,12 @@ export async function readPostgresSchedulerRunStatus(
16933
17021
  | 'updated_at'
16934
17022
  | 'started_at'
16935
17023
  | 'finished_at'
17024
+ | 'definition_scope'
16936
17025
  >
16937
17026
  >(
16938
17027
  `
16939
17028
  SELECT run_id, org_id, status, play_name, graph_hash, runtime_profile,
16940
- created_at, updated_at, started_at, finished_at
17029
+ created_at, updated_at, started_at, finished_at${admissionScopeSelection}
16941
17030
  FROM ${tableName('runs', options)}
16942
17031
  WHERE run_id = $1
16943
17032
  `,
@@ -16948,6 +17037,10 @@ export async function readPostgresSchedulerRunStatus(
16948
17037
  return {
16949
17038
  runId: row.run_id,
16950
17039
  orgId: row.org_id ?? '',
17040
+ ...(options.includeAdmissionScope &&
17041
+ (row.definition_scope === 'org' || row.definition_scope === 'system')
17042
+ ? { definitionScope: row.definition_scope }
17043
+ : {}),
16951
17044
  status: row.status,
16952
17045
  playName: row.play_name,
16953
17046
  graphHash: row.graph_hash,
@@ -16973,7 +17066,7 @@ export async function readPostgresSchedulerRunStatus(
16973
17066
  `
16974
17067
  SELECT run_id, org_id, status, play_name, graph_hash, runtime_profile,
16975
17068
  launch_json, suspension_json, terminal_result_json, terminal_error_json,
16976
- runtime_timing_json, created_at, updated_at, started_at, finished_at
17069
+ runtime_timing_json, created_at, updated_at, started_at, finished_at${admissionScopeSelection}
16977
17070
  FROM ${tableName('runs', options)}
16978
17071
  WHERE run_id = $1
16979
17072
  `,
@@ -16990,6 +17083,10 @@ export async function readPostgresSchedulerRunStatus(
16990
17083
  return {
16991
17084
  runId: row.run_id,
16992
17085
  orgId: row.org_id ?? '',
17086
+ ...(options?.includeAdmissionScope &&
17087
+ (row.definition_scope === 'org' || row.definition_scope === 'system')
17088
+ ? { definitionScope: row.definition_scope }
17089
+ : {}),
16993
17090
  status: row.status,
16994
17091
  playName: row.play_name,
16995
17092
  graphHash: row.graph_hash,
@@ -18810,9 +18907,14 @@ type RunLedgerOutboxDrainScope = {
18810
18907
  leaseOwner: string;
18811
18908
  targetEventId: string;
18812
18909
  nextClaimed: PostgresSchedulerOutboxEvent[];
18910
+ };
18911
+
18912
+ type RunLedgerOutboxAuthorityScope = {
18813
18913
  authority: {
18914
+ runId: string;
18915
+ leaseOwner: string;
18814
18916
  runtimeApi: WorkerRuntimeApiContext;
18815
- expiresAtMs: number;
18917
+ expiresAtMs: number | null;
18816
18918
  } | null;
18817
18919
  };
18818
18920
 
@@ -18826,6 +18928,7 @@ async function dispatchRunLedgerOutboxThroughEventWithScope(
18826
18928
  },
18827
18929
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
18828
18930
  scope?: RunLedgerOutboxDrainScope,
18931
+ authorityScope: RunLedgerOutboxAuthorityScope = { authority: null },
18829
18932
  ): Promise<PostgresSchedulerOutboxDrainResult> {
18830
18933
  const runId = input.runId?.trim();
18831
18934
  if (!runId) {
@@ -18841,6 +18944,11 @@ async function dispatchRunLedgerOutboxThroughEventWithScope(
18841
18944
  input.maxEvents === undefined
18842
18945
  ? null
18843
18946
  : Math.max(1, Math.min(32, input.maxEvents));
18947
+ const leaseOwner =
18948
+ input.leaseOwner?.trim() ||
18949
+ scope?.leaseOwner ||
18950
+ `run-ledger-outbox-dispatch:${randomUUID()}`;
18951
+ const scopedInput = { ...input, leaseOwner };
18844
18952
  const batchSize = RUN_LEDGER_PROJECTION_PREFIX_MAX_FACTS;
18845
18953
  const eventIds: string[] = [];
18846
18954
  const failedEventIds: string[] = [];
@@ -18855,13 +18963,14 @@ async function dispatchRunLedgerOutboxThroughEventWithScope(
18855
18963
  const result = await dispatchRunLedgerOutboxBatchWithScope(
18856
18964
  withClient,
18857
18965
  {
18858
- ...input,
18966
+ ...scopedInput,
18859
18967
  waitForRunLock: true,
18860
18968
  continueThroughTerminal: false,
18861
18969
  limit: remaining === null ? batchSize : Math.min(batchSize, remaining),
18862
18970
  },
18863
18971
  options,
18864
18972
  scope,
18973
+ authorityScope,
18865
18974
  );
18866
18975
  attempted += result.attempted;
18867
18976
  projected += result.projected;
@@ -18940,7 +19049,13 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
18940
19049
  input: RunLedgerOutboxDispatchInput & { waitForRunLock?: boolean },
18941
19050
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
18942
19051
  ): Promise<PostgresSchedulerOutboxProjectionResult> {
18943
- return dispatchRunLedgerOutboxBatchWithScope(withClient, input, options);
19052
+ return dispatchRunLedgerOutboxBatchWithScope(
19053
+ withClient,
19054
+ input,
19055
+ options,
19056
+ undefined,
19057
+ { authority: null },
19058
+ );
18944
19059
  }
18945
19060
 
18946
19061
  async function dispatchRunLedgerOutboxBatchWithScope(
@@ -18950,6 +19065,7 @@ async function dispatchRunLedgerOutboxBatchWithScope(
18950
19065
  input: RunLedgerOutboxDispatchInput & { waitForRunLock?: boolean },
18951
19066
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
18952
19067
  scope?: RunLedgerOutboxDrainScope,
19068
+ authorityScope: RunLedgerOutboxAuthorityScope = { authority: null },
18953
19069
  ): Promise<PostgresSchedulerOutboxProjectionResult> {
18954
19070
  const dispatchStartedAtMs = Date.now();
18955
19071
  const leaseOwner =
@@ -19126,23 +19242,45 @@ async function dispatchRunLedgerOutboxBatchWithScope(
19126
19242
  ) {
19127
19243
  throw new Error('Run-ledger continuation is outside its dispatch scope.');
19128
19244
  }
19129
- if (scope?.authority && scope.authority.expiresAtMs <= Date.now()) {
19130
- throw new Error('Run-ledger continuation authority expired.');
19131
- }
19245
+ // Minted executor authority is reused only inside this finite run/owner
19246
+ // drain and only while it can cover the HTTP request plus its SQL renewal.
19247
+ const reuseMarginMs =
19248
+ Math.max(
19249
+ 1,
19250
+ Math.floor(
19251
+ input.runtimeApi?.requestTimeoutMs ??
19252
+ RUNTIME_CAPACITY_POLICY.receiptGateway.requestTimeoutMs,
19253
+ ),
19254
+ ) + RUNTIME_RELIABILITY_POLICY.schedulerDatabase.queryTimeoutMs;
19255
+ const cachedAuthority = authorityScope.authority;
19132
19256
  const gatewayRuntimeApi =
19133
19257
  tokenAuthority === 'gateway'
19134
- ? (scope?.authority?.runtimeApi ??
19135
- (await loadPostgresSchedulerRuntimeApiForRun(
19136
- withClient,
19137
- first.runId,
19138
- first.leaseOwner
19139
- ? { eventId: first.eventId, leaseOwner: first.leaseOwner }
19140
- : null,
19141
- tokenAuthority,
19142
- options,
19143
- input.runtimeApi?.signal,
19144
- )))
19258
+ ? cachedAuthority?.runId === first.runId &&
19259
+ cachedAuthority.leaseOwner === leaseOwner &&
19260
+ cachedAuthority.expiresAtMs !== null &&
19261
+ cachedAuthority.expiresAtMs > Date.now() + reuseMarginMs
19262
+ ? cachedAuthority.runtimeApi
19263
+ : await loadPostgresSchedulerRuntimeApiForRun(
19264
+ withClient,
19265
+ first.runId,
19266
+ first.leaseOwner
19267
+ ? { eventId: first.eventId, leaseOwner: first.leaseOwner }
19268
+ : null,
19269
+ tokenAuthority,
19270
+ options,
19271
+ input.runtimeApi?.signal,
19272
+ )
19145
19273
  : null;
19274
+ if (
19275
+ gatewayRuntimeApi &&
19276
+ cachedAuthority?.runId === first.runId &&
19277
+ cachedAuthority.leaseOwner === leaseOwner &&
19278
+ cachedAuthority.runtimeApi.baseUrl !== gatewayRuntimeApi.baseUrl
19279
+ ) {
19280
+ throw new Error(
19281
+ 'Run Ledger dispatch origin changed within an immutable launch.',
19282
+ );
19283
+ }
19146
19284
  const resolvedRuntimeApi =
19147
19285
  gatewayRuntimeApi ??
19148
19286
  input.runtimeApi ??
@@ -19186,12 +19324,48 @@ async function dispatchRunLedgerOutboxBatchWithScope(
19186
19324
  const tokenExpiresAtMs = runtimeApiTokenExpiresAtMs(
19187
19325
  runtimeApi.executorToken,
19188
19326
  );
19189
- if (scope && gatewayRuntimeApi && tokenExpiresAtMs !== null) {
19190
- scope.authority = { runtimeApi, expiresAtMs: tokenExpiresAtMs };
19327
+ if (tokenAuthority === 'gateway' && gatewayRuntimeApi) {
19328
+ authorityScope.authority = {
19329
+ runId: first.runId,
19330
+ leaseOwner,
19331
+ runtimeApi,
19332
+ expiresAtMs: tokenExpiresAtMs,
19333
+ };
19191
19334
  }
19192
19335
  authorityReadyAtMs = Date.now();
19193
- const renewDelivery = () =>
19194
- withClient((client) =>
19336
+ const renewDelivery = async () => {
19337
+ const currentAuthority = authorityScope.authority;
19338
+ if (
19339
+ tokenAuthority === 'gateway' &&
19340
+ currentAuthority?.runId === first.runId &&
19341
+ currentAuthority.leaseOwner === leaseOwner &&
19342
+ currentAuthority.expiresAtMs !== null &&
19343
+ currentAuthority.expiresAtMs <= Date.now() + reuseMarginMs
19344
+ ) {
19345
+ const refreshed = await loadPostgresSchedulerRuntimeApiForRun(
19346
+ withClient,
19347
+ first.runId,
19348
+ { eventId: first.eventId, leaseOwner },
19349
+ tokenAuthority,
19350
+ options,
19351
+ runtimeApi.signal,
19352
+ );
19353
+ if (refreshed.baseUrl !== runtimeApi.baseUrl) {
19354
+ throw new Error(
19355
+ 'Run Ledger dispatch origin changed within an immutable launch.',
19356
+ );
19357
+ }
19358
+ runtimeApi.executorToken = refreshed.executorToken;
19359
+ runtimeApi.vercelProtectionBypassToken =
19360
+ refreshed.vercelProtectionBypassToken;
19361
+ authorityScope.authority = {
19362
+ runId: first.runId,
19363
+ leaseOwner,
19364
+ runtimeApi,
19365
+ expiresAtMs: runtimeApiTokenExpiresAtMs(refreshed.executorToken),
19366
+ };
19367
+ }
19368
+ await withClient((client) =>
19195
19369
  renewPostgresRunLedgerDelivery(
19196
19370
  client,
19197
19371
  {
@@ -19202,6 +19376,7 @@ async function dispatchRunLedgerOutboxBatchWithScope(
19202
19376
  options,
19203
19377
  ),
19204
19378
  );
19379
+ };
19205
19380
  // A pending start is always claimed alone because later events require its
19206
19381
  // snapshot. It cannot share the append endpoint, so retain that mutation
19207
19382
  // as its own exact delivery.
@@ -19299,6 +19474,7 @@ async function dispatchRunLedgerOutboxBatchWithScope(
19299
19474
  withClient,
19300
19475
  { input, delivered, scope: acknowledgement.continuation },
19301
19476
  options,
19477
+ authorityScope,
19302
19478
  );
19303
19479
  } catch (error) {
19304
19480
  await releasePendingContinuation();
@@ -19404,6 +19580,7 @@ async function continueRunLedgerOutboxThroughTerminal(
19404
19580
  scope: RunLedgerOutboxDrainScope;
19405
19581
  },
19406
19582
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
19583
+ authorityScope: RunLedgerOutboxAuthorityScope = { authority: null },
19407
19584
  ): Promise<PostgresSchedulerOutboxProjectionResult> {
19408
19585
  const drained = await dispatchRunLedgerOutboxThroughEventWithScope(
19409
19586
  withClient,
@@ -19415,6 +19592,7 @@ async function continueRunLedgerOutboxThroughTerminal(
19415
19592
  },
19416
19593
  options,
19417
19594
  input.scope,
19595
+ authorityScope,
19418
19596
  );
19419
19597
  return {
19420
19598
  attempted: input.delivered.attempted + drained.attempted,
@@ -19430,7 +19608,10 @@ async function continueRunLedgerOutboxThroughTerminal(
19430
19608
  function runtimeApiTokenExpiresAtMs(token: string): number | null {
19431
19609
  try {
19432
19610
  const expiresAt = decodeJwt(token).exp;
19433
- return typeof expiresAt === 'number' && Number.isFinite(expiresAt)
19611
+ return typeof expiresAt === 'number' &&
19612
+ Number.isSafeInteger(expiresAt) &&
19613
+ expiresAt > 0 &&
19614
+ Number.isSafeInteger(expiresAt * 1_000)
19434
19615
  ? expiresAt * 1_000
19435
19616
  : null;
19436
19617
  } catch {
@@ -19514,18 +19695,11 @@ async function acknowledgeRunLedgerPrefixWithContinuation(
19514
19695
  options,
19515
19696
  );
19516
19697
  if (nextClaimed.length > 0) {
19517
- const expiresAtMs = runtimeApiTokenExpiresAtMs(
19518
- input.runtimeApi.executorToken,
19519
- );
19520
19698
  continuation = input.scope ?? {
19521
19699
  runId,
19522
19700
  leaseOwner: input.leaseOwner,
19523
19701
  targetEventId,
19524
19702
  nextClaimed: [],
19525
- authority:
19526
- input.input.tokenAuthority === 'gateway' && expiresAtMs !== null
19527
- ? { runtimeApi: input.runtimeApi, expiresAtMs }
19528
- : null,
19529
19703
  };
19530
19704
  continuation.nextClaimed = nextClaimed;
19531
19705
  input.continuation.current = continuation;
@@ -20127,6 +20301,9 @@ function parsePostgresSchedulerCronSourcePin(
20127
20301
  return {
20128
20302
  ...pin,
20129
20303
  orgId: pin.orgId,
20304
+ ...(pin.definitionScope === 'org' || pin.definitionScope === 'system'
20305
+ ? { definitionScope: pin.definitionScope }
20306
+ : {}),
20130
20307
  userId: typeof pin.userId === 'string' ? pin.userId : null,
20131
20308
  playName: pin.playName,
20132
20309
  revisionId: typeof pin.revisionId === 'string' ? pin.revisionId : null,
@@ -539,12 +539,19 @@ export async function reserveRuntimeSandboxCapacityLease(
539
539
  provider: RuntimeSandboxProviderId;
540
540
  operation_attempt: number | null;
541
541
  operation_environment: 'preview' | 'production' | null;
542
+ operation_provider: RuntimeSandboxProviderId | null;
542
543
  provider_operation_token: string | null;
544
+ operation_state: RuntimeSandboxOperationState | null;
545
+ released_at: Date | null;
546
+ sandbox_id: string | null;
543
547
  }>(
544
548
  `SELECT lease.org_id, lease.run_id, lease.provider,
545
549
  operation.attempt AS operation_attempt,
546
550
  operation.environment AS operation_environment,
547
- operation.provider_operation_token
551
+ operation.provider AS operation_provider,
552
+ operation.provider_operation_token,
553
+ operation.state AS operation_state,
554
+ lease.released_at, lease.sandbox_id
548
555
  FROM ${leases} AS lease
549
556
  LEFT JOIN ${operations} AS operation
550
557
  ON operation.operation_key = lease.lease_id
@@ -559,12 +566,23 @@ export async function reserveRuntimeSandboxCapacityLease(
559
566
  row.provider !== input.provider ||
560
567
  (input.attempt !== undefined &&
561
568
  (row.operation_attempt !== input.attempt ||
562
- row.operation_environment !== (input.environment ?? 'production')))
569
+ row.operation_environment !== (input.environment ?? 'production') ||
570
+ row.operation_provider !== input.provider))
563
571
  ) {
564
572
  throw new Error(
565
573
  'operationKey reservation did not persist the requested sandbox operation.',
566
574
  );
567
575
  }
576
+ if (
577
+ input.attempt !== undefined &&
578
+ (row.operation_state !== RuntimeSandboxOperationState.Reserved ||
579
+ row.released_at !== null ||
580
+ row.sandbox_id !== null)
581
+ ) {
582
+ throw new RuntimeSandboxOperationNotRetryableError(
583
+ row.operation_state ?? RuntimeSandboxOperationState.Abandoned,
584
+ );
585
+ }
568
586
  const resolvedProviderOperationToken =
569
587
  row.provider_operation_token === null && input.attempt !== undefined
570
588
  ? await backfillReservedProviderOperationToken(
@@ -124,13 +124,24 @@ function parseRuntimeTestFaultHeader(
124
124
  const count =
125
125
  rawCount === undefined || rawCount.trim() === ''
126
126
  ? 1
127
- : Number.parseInt(rawCount.trim(), 10);
127
+ : name === 'execution_upstream_response_loss'
128
+ ? Number(rawCount.trim())
129
+ : Number.parseInt(rawCount.trim(), 10);
128
130
  if (!Number.isInteger(count) || count < 1) {
129
131
  return {
130
132
  error: `Runtime test fault "${name}" count must be a positive integer.`,
131
133
  };
132
134
  }
133
- faults.set(name, (faults.get(name) ?? 0) + count);
135
+ const total = (faults.get(name) ?? 0) + count;
136
+ // This seam deliberately interrupts only the first buffered response of
137
+ // each invocation. Repeated losses would test retry exhaustion instead of
138
+ // the durable-result recovery contract.
139
+ if (name === 'execution_upstream_response_loss' && total !== 1) {
140
+ return {
141
+ error: `Runtime test fault "${name}" count must be 1.`,
142
+ };
143
+ }
144
+ faults.set(name, total);
134
145
  }
135
146
  return faults;
136
147
  }