deepline 0.3.285 → 0.3.287

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 (45) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +48 -26
  2. package/dist/bundling-sources/sdk/src/index.ts +4 -0
  3. package/dist/bundling-sources/sdk/src/release.ts +7 -1
  4. package/dist/bundling-sources/sdk/src/types.ts +36 -0
  5. package/dist/bundling-sources/shared_libs/play-runtime/cell-provenance.ts +16 -0
  6. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +21 -0
  7. package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +2 -0
  8. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +18 -0
  9. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +16 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +38 -3
  11. package/dist/bundling-sources/shared_libs/play-runtime/run-observation.ts +12 -0
  12. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +3 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +43 -1
  14. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +28 -0
  15. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +88 -1
  16. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +243 -90
  17. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +53 -25
  18. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +40 -7
  19. package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +83 -1
  20. package/dist/bundling-sources/shared_libs/play-runtime/test-async-batching.ts +4 -1
  21. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +68 -0
  22. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +2 -0
  23. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +10 -1
  24. package/dist/bundling-sources/shared_libs/plays/enrich-compat-adapter.ts +2 -0
  25. package/dist/cli/index.js +30615 -34474
  26. package/dist/cli/index.mjs +30310 -34181
  27. package/dist/{client-T2jVnZrq.d.ts → client-FR_u0dxT.d.ts} +40 -4
  28. package/dist/{client-Cl-zj2oS.d.mts → client-phK1Ixcl.d.mts} +40 -4
  29. package/dist/{compiler-manifest-B1zo3igW.d.mts → compiler-manifest-9SQtUuKb.d.mts} +1 -1
  30. package/dist/{compiler-manifest-B1zo3igW.d.ts → compiler-manifest-9SQtUuKb.d.ts} +1 -1
  31. package/dist/index.d.mts +4 -4
  32. package/dist/index.d.ts +4 -4
  33. package/dist/index.js +57 -28
  34. package/dist/index.mjs +57 -28
  35. package/dist/install-integrity.json +4 -4
  36. package/dist/plays/bundle-play-file.d.mts +2 -2
  37. package/dist/plays/bundle-play-file.d.ts +2 -2
  38. package/dist/plays/bundle-play-file.mjs +8 -1
  39. package/dist/plays/run-request.d.mts +2 -2
  40. package/dist/plays/run-request.d.ts +2 -2
  41. package/dist/release.d.mts +5 -1
  42. package/dist/release.d.ts +5 -1
  43. package/dist/release.js +6 -1
  44. package/dist/release.mjs +6 -1
  45. package/package.json +1 -1
@@ -334,7 +334,9 @@ const POSTGRES_SCHEDULER_SCHEMA_INIT_STATEMENT_TIMEOUT_MS = 60_000;
334
334
  // index stays operator-prepared concurrently before marked-run admission.
335
335
  // v56 adds a release-leading index for fixed-controller runner-terminal
336
336
  // recovery, which scans only active runs for each release lane.
337
- export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 56;
337
+ // v57 refreshes log-position lookups after the operator concurrently prepares
338
+ // channel-specific indexes; outgoing readers retain the existing GIN index.
339
+ export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 57;
338
340
  const POSTGRES_SCHEDULER_SCHEMA_MIGRATIONS_TABLE =
339
341
  'scheduler_schema_migrations';
340
342
  export const POSTGRES_SCHEDULER_OPEN_RECOVERY_INDEX =
@@ -7400,7 +7402,7 @@ export async function markPostgresSchedulerAttemptWaiting(
7400
7402
  );
7401
7403
  const waiting = await client.query<{ run_id: string; event_id: string }>(
7402
7404
  `
7403
- WITH waiting_attempt AS (
7405
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, waiting_attempt AS (
7404
7406
  UPDATE ${tableName('attempts', options)}
7405
7407
  SET status = 'waiting',
7406
7408
  resource_json = CASE
@@ -7436,6 +7438,7 @@ export async function markPostgresSchedulerAttemptWaiting(
7436
7438
  END,
7437
7439
  heartbeat_at = CASE WHEN $8::boolean THEN heartbeat_at ELSE now() END,
7438
7440
  updated_at = now()
7441
+ FROM (SELECT count(*) FROM custody_attempts) AS attempt_locks
7439
7442
  WHERE run_id = $1
7440
7443
  AND attempt = $2
7441
7444
  AND status = 'running'
@@ -8164,13 +8167,14 @@ export async function deferPostgresSchedulerAttemptForCapacity(
8164
8167
  ): Promise<boolean> {
8165
8168
  const deferred = await client.query<{ run_id: string }>(
8166
8169
  `
8167
- WITH deferred_attempt AS (
8170
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, deferred_attempt AS (
8168
8171
  UPDATE ${tableName('attempts', options)}
8169
8172
  SET status = 'stale',
8170
8173
  lease_expires_at = NULL,
8171
8174
  heartbeat_at = now(),
8172
8175
  error_json = $4::jsonb,
8173
8176
  updated_at = now()
8177
+ FROM (SELECT count(*) FROM custody_attempts) AS attempt_locks
8174
8178
  WHERE run_id = $1
8175
8179
  AND attempt = $2
8176
8180
  AND status IN ('claimed', 'running', 'waiting')
@@ -8232,9 +8236,9 @@ export async function deferPostgresSchedulerAttemptForExecutorTokenOutage(
8232
8236
  deferred: boolean;
8233
8237
  }>(
8234
8238
  `
8235
- WITH current_attempt AS (
8239
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, current_attempt AS (
8236
8240
  SELECT created_at
8237
- FROM ${tableName('attempts', options)}
8241
+ FROM custody_attempts
8238
8242
  WHERE run_id = $1
8239
8243
  AND attempt = $2
8240
8244
  AND lease_token = $3
@@ -8267,6 +8271,7 @@ export async function deferPostgresSchedulerAttemptForExecutorTokenOutage(
8267
8271
  heartbeat_at = now(),
8268
8272
  error_json = $4::jsonb,
8269
8273
  updated_at = now()
8274
+ FROM (SELECT count(*) FROM custody_attempts) AS attempt_locks
8270
8275
  WHERE run_id = $1
8271
8276
  AND attempt = $2
8272
8277
  AND status IN ('claimed', 'running')
@@ -8326,10 +8331,10 @@ export async function claimPostgresSchedulerWaitingDetachedAttemptForTerminal(
8326
8331
  ): Promise<boolean> {
8327
8332
  const claimed = await client.query<{ run_id: string }>(
8328
8333
  `
8329
- WITH candidate AS MATERIALIZED (
8334
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, candidate AS MATERIALIZED (
8330
8335
  SELECT runs.run_id, attempts.attempt
8331
- FROM ${tableName('runs', options)} AS runs
8332
- JOIN ${tableName('attempts', options)} AS attempts
8336
+ FROM custody_runs AS runs
8337
+ JOIN custody_attempts AS attempts
8333
8338
  ON attempts.run_id = runs.run_id
8334
8339
  AND attempts.attempt = (runs.suspension_json ->> 'runnerAttempt')::integer
8335
8340
  WHERE runs.run_id = $1
@@ -8349,7 +8354,6 @@ export async function claimPostgresSchedulerWaitingDetachedAttemptForTerminal(
8349
8354
  AND newer.attempt > attempts.attempt
8350
8355
  AND newer.status IN ('claimed', 'running', 'waiting', 'completed', 'failed')
8351
8356
  )
8352
- FOR UPDATE OF runs, attempts
8353
8357
  ),
8354
8358
  running_attempt AS (
8355
8359
  UPDATE ${tableName('attempts', options)} AS target
@@ -8588,19 +8592,18 @@ export async function deferPostgresSchedulerAttemptForRecovery(
8588
8592
  deadline_at_ms: string | null;
8589
8593
  }>(
8590
8594
  `
8591
- WITH candidate AS (
8595
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, candidate AS (
8592
8596
  SELECT runs.run_id,
8593
8597
  runs.recovery_json,
8594
8598
  attempts.run_id AS attempt_run_id
8595
- FROM ${tableName('runs', options)} AS runs
8596
- JOIN ${tableName('attempts', options)} AS attempts
8599
+ FROM custody_runs AS runs
8600
+ JOIN custody_attempts AS attempts
8597
8601
  ON attempts.run_id = runs.run_id
8598
8602
  WHERE attempts.run_id = $1
8599
8603
  AND attempts.attempt = $2
8600
8604
  AND attempts.lease_token = $3
8601
8605
  AND attempts.status IN ('claimed', 'running', 'waiting')
8602
8606
  AND runs.status IN ('queued', 'running', 'waiting')
8603
- FOR UPDATE OF runs, attempts
8604
8607
  ), computed AS (
8605
8608
  SELECT run_id,
8606
8609
  coalesce((recovery_json ->> 'deferCount')::integer, 0) + 1
@@ -9322,20 +9325,24 @@ export async function recordPostgresSchedulerManagedSandboxOperationLive(
9322
9325
  'production';
9323
9326
  const recorded = await client.query<{ operation_key: string }>(
9324
9327
  `
9325
- WITH eligible_attempt AS (
9328
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, eligible_attempt AS (
9326
9329
  SELECT run_id
9327
- FROM ${tableName('attempts', options)}
9330
+ FROM custody_attempts
9328
9331
  WHERE run_id = $1
9329
9332
  AND attempt = $2
9330
9333
  AND lease_token = $3
9331
9334
  AND status IN ('claimed', 'running', 'waiting')
9335
+ AND EXISTS (SELECT 1 FROM custody_runs WHERE status IN ('queued', 'running', 'waiting'))
9336
+ AND NOT EXISTS (SELECT 1 FROM custody_attempts AS newer WHERE newer.attempt > $2)
9332
9337
  ), eligible_lease AS MATERIALIZED (
9333
9338
  SELECT lease_id
9334
- FROM ${tableName('runtime_sandbox_capacity_leases', options)}
9339
+ FROM custody_leases
9340
+ CROSS JOIN (SELECT count(*) FROM custody_operations) AS operation_locks
9335
9341
  WHERE lease_id = $5
9342
+ AND run_id = $1 AND provider = $10
9343
+ AND (sandbox_id IS NULL OR (sandbox_id = $6 AND routing_domain IS NOT DISTINCT FROM $7))
9336
9344
  AND released_at IS NULL
9337
9345
  AND expires_at > clock_timestamp()
9338
- FOR UPDATE
9339
9346
  ), live_operation AS (
9340
9347
  UPDATE ${tableName('runtime_sandbox_operations', options)} AS operation
9341
9348
  SET sandbox_id = $6,
@@ -9378,7 +9385,6 @@ export async function recordPostgresSchedulerManagedSandboxOperationLive(
9378
9385
  JOIN recorded_attempt ON TRUE
9379
9386
  WHERE lease.lease_id = live_operation.operation_key
9380
9387
  AND lease.released_at IS NULL
9381
- AND lease.expires_at > clock_timestamp()
9382
9388
  RETURNING lease.lease_id
9383
9389
  )
9384
9390
  SELECT live_operation.operation_key
@@ -9413,42 +9419,52 @@ export async function recordPostgresSchedulerManagedSandboxOperationLive(
9413
9419
  return false;
9414
9420
  }
9415
9421
  const updated = await client.query<{ run_id: string }>(
9416
- `UPDATE ${tableName('attempts', options)} AS attempt
9417
- SET resource_json = (
9418
- SELECT jsonb_agg(
9419
- CASE
9420
- WHEN resource->>'sandboxCapacityLeaseId' = $5
9421
- AND resource->>'sandboxId' = $6
9422
- AND resource->>'kind' = $4::jsonb->>'kind'
9423
- THEN resource || jsonb_build_object(
9424
- 'billingEndedAt', $4::jsonb->'billingEndedAt'
9425
- )
9426
- ELSE resource
9427
- END ORDER BY ordinal
9428
- )
9429
- FROM jsonb_array_elements(attempt.resource_json)
9430
- WITH ORDINALITY AS resources(resource, ordinal)
9431
- ),
9432
- updated_at = clock_timestamp()
9433
- FROM ${tableName('runtime_sandbox_operations', options)} AS operation
9434
- JOIN ${tableName('runtime_sandbox_capacity_leases', options)} AS lease
9435
- ON lease.lease_id = operation.operation_key
9436
- WHERE attempt.run_id = $1
9437
- AND attempt.attempt = $2
9438
- AND attempt.lease_token = $3
9439
- AND attempt.status IN ('claimed', 'running', 'waiting')
9440
- AND operation.operation_key = $5
9441
- AND operation.run_id = attempt.run_id
9442
- AND operation.attempt = attempt.attempt
9443
- AND operation.sandbox_id = $6
9444
- AND operation.provider = $7
9445
- AND operation.state = $8
9446
- AND operation.environment = $9
9447
- AND operation.routing_domain IS NOT DISTINCT FROM $10
9448
- AND lease.sandbox_id = $6
9449
- AND lease.released_at IS NULL
9450
- AND lease.expires_at > clock_timestamp()
9451
- RETURNING attempt.run_id`,
9422
+ `WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, eligible_retirement AS MATERIALIZED (
9423
+ SELECT operation.operation_key, operation.run_id, operation.attempt
9424
+ FROM custody_operations AS operation
9425
+ JOIN custody_attempts AS attempt ON attempt.run_id = operation.run_id AND attempt.attempt = operation.attempt
9426
+ JOIN custody_leases AS lease ON lease.lease_id = operation.operation_key
9427
+ WHERE attempt.run_id = $1 AND attempt.attempt = $2 AND attempt.lease_token = $3
9428
+ AND attempt.status IN ('claimed', 'running', 'waiting')
9429
+ AND NOT EXISTS (SELECT 1 FROM custody_attempts AS newer WHERE newer.attempt > $2)
9430
+ AND EXISTS (SELECT 1 FROM custody_runs WHERE status IN ('queued', 'running', 'waiting'))
9431
+ AND operation.operation_key = $5 AND operation.sandbox_id = $6
9432
+ AND operation.provider = $7 AND operation.state IN ($8, 'deleting')
9433
+ AND operation.environment = $9 AND operation.routing_domain IS NOT DISTINCT FROM $10
9434
+ AND lease.sandbox_id = $6 AND lease.released_at IS NULL
9435
+ AND EXISTS (
9436
+ SELECT 1 FROM jsonb_array_elements(attempt.resource_json) AS fact
9437
+ WHERE fact->>'sandboxCapacityLeaseId' = $5 AND fact->>'sandboxId' = $6
9438
+ AND fact->>'kind' = $4::jsonb->>'kind'
9439
+ )
9440
+ ), retiring_operation AS (
9441
+ UPDATE ${tableName('runtime_sandbox_operations', options)} AS operation
9442
+ SET state = 'deleting', updated_at = clock_timestamp()
9443
+ FROM eligible_retirement
9444
+ WHERE operation.operation_key = eligible_retirement.operation_key
9445
+ RETURNING operation.operation_key
9446
+ ), closed_resource AS (
9447
+ UPDATE ${tableName('attempts', options)} AS attempt
9448
+ SET resource_json = (
9449
+ SELECT jsonb_agg(
9450
+ CASE
9451
+ WHEN resource->>'sandboxCapacityLeaseId' = $5 AND resource->>'sandboxId' = $6
9452
+ AND resource->>'kind' = $4::jsonb->>'kind'
9453
+ AND (resource->'billingEndedAt' IS NULL OR resource->'billingEndedAt' = 'null'::jsonb)
9454
+ THEN resource || jsonb_build_object('billingEndedAt', $4::jsonb->'billingEndedAt')
9455
+ ELSE resource END ORDER BY ordinal
9456
+ ) FROM jsonb_array_elements(attempt.resource_json) WITH ORDINALITY AS resources(resource, ordinal)
9457
+ ), updated_at = clock_timestamp()
9458
+ FROM retiring_operation
9459
+ WHERE attempt.run_id = $1 AND attempt.attempt = $2 AND attempt.lease_token = $3
9460
+ RETURNING attempt.run_id
9461
+ ), queued AS (
9462
+ INSERT INTO ${tableName('sandbox_cleanup_jobs_v2', options)} (
9463
+ provider, sandbox_id, run_id, attempt, environment, routing_domain
9464
+ ) SELECT $7, $6, $1, $2, $9, $10 FROM closed_resource
9465
+ ON CONFLICT (provider, sandbox_id, routing_domain_key) DO NOTHING
9466
+ )
9467
+ SELECT run_id FROM closed_resource`,
9452
9468
  [
9453
9469
  input.runId,
9454
9470
  input.attempt,
@@ -9492,14 +9508,17 @@ export async function readPostgresSchedulerManagedSandboxOperationAlreadyLive(
9492
9508
  operationKey: string;
9493
9509
  provider: RuntimeSandboxProvider;
9494
9510
  sandboxId: string;
9511
+ environment?: 'preview' | 'production';
9512
+ routingDomain?: string | null;
9495
9513
  },
9496
9514
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
9497
9515
  ): Promise<boolean> {
9498
9516
  const found = await client.query<{ operation_key: string }>(
9499
9517
  `
9518
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}
9500
9519
  SELECT operation.operation_key
9501
- FROM ${tableName('runtime_sandbox_operations', options)} AS operation
9502
- JOIN ${tableName('attempts', options)} AS attempt
9520
+ FROM custody_operations AS operation
9521
+ JOIN custody_attempts AS attempt
9503
9522
  ON attempt.run_id = operation.run_id
9504
9523
  AND attempt.attempt = operation.attempt
9505
9524
  WHERE operation.operation_key = $4
@@ -9508,8 +9527,12 @@ export async function readPostgresSchedulerManagedSandboxOperationAlreadyLive(
9508
9527
  AND operation.provider = $5
9509
9528
  AND operation.state = $6
9510
9529
  AND operation.sandbox_id = $7
9530
+ AND ($8::text IS NULL OR operation.environment = $8)
9531
+ AND (NOT $9::boolean OR operation.routing_domain IS NOT DISTINCT FROM $10::text)
9511
9532
  AND attempt.lease_token = $3
9512
9533
  AND attempt.status IN ('claimed', 'running', 'waiting')
9534
+ AND NOT EXISTS (SELECT 1 FROM custody_attempts AS newer WHERE newer.attempt > $2)
9535
+ AND EXISTS (SELECT 1 FROM custody_runs WHERE status IN ('queued', 'running', 'waiting'))
9513
9536
  `,
9514
9537
  [
9515
9538
  input.runId,
@@ -9519,6 +9542,9 @@ export async function readPostgresSchedulerManagedSandboxOperationAlreadyLive(
9519
9542
  input.provider,
9520
9543
  RuntimeSandboxOperationState.Live,
9521
9544
  input.sandboxId,
9545
+ input.environment ?? null,
9546
+ input.routingDomain !== undefined,
9547
+ input.routingDomain?.trim() || null,
9522
9548
  ],
9523
9549
  );
9524
9550
  return found.rows.length === 1;
@@ -9671,9 +9697,10 @@ export async function resolvePostgresSchedulerAmbiguousModalCreateIntentFromProv
9671
9697
  ): Promise<boolean> {
9672
9698
  const resolved = await client.query<{ run_id: string }>(
9673
9699
  `
9674
- WITH resolved AS (
9700
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, resolved AS (
9675
9701
  UPDATE ${tableName('ambiguous_modal_creates', options)}
9676
9702
  SET status = 'resolved', resolved_at = clock_timestamp()
9703
+ FROM (SELECT count(*) FROM custody_operations) AS operation_locks
9677
9704
  WHERE run_id = $1
9678
9705
  AND attempt = $2
9679
9706
  AND modal_app_id = $3
@@ -9726,9 +9753,10 @@ export async function recordPostgresSchedulerReconciledModalResourcesForCleanup(
9726
9753
  const payload = stringifyPostgresJson(resources);
9727
9754
  const recorded = await client.query<{ run_id: string }>(
9728
9755
  `
9729
- WITH claimed_intent AS (
9756
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, claimed_intent AS (
9730
9757
  UPDATE ${tableName('ambiguous_modal_creates', options)}
9731
9758
  SET status = 'resolved', resolved_at = clock_timestamp()
9759
+ FROM (SELECT count(*) FROM custody_operations) AS operation_locks
9732
9760
  WHERE run_id = $1
9733
9761
  AND attempt = $2
9734
9762
  AND modal_app_id = $3
@@ -9951,16 +9979,16 @@ export async function recordPostgresSchedulerLateManagedSandboxOperationForClean
9951
9979
  'production';
9952
9980
  const result = await client.query<{ operation_key: string }>(
9953
9981
  `
9954
- WITH eligible_lease AS MATERIALIZED (
9982
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, eligible_lease AS MATERIALIZED (
9955
9983
  SELECT lease_id
9956
- FROM ${tableName('runtime_sandbox_capacity_leases', options)}
9984
+ FROM custody_leases
9985
+ CROSS JOIN (SELECT count(*) FROM custody_operations) AS operation_locks
9957
9986
  WHERE lease_id = $4
9958
9987
  AND released_at IS NULL
9959
9988
  AND expires_at > clock_timestamp()
9960
- FOR UPDATE
9961
9989
  ), eligible_attempt AS (
9962
9990
  SELECT run_id
9963
- FROM ${tableName('attempts', options)}
9991
+ FROM custody_attempts
9964
9992
  WHERE run_id = $1
9965
9993
  AND attempt = $2
9966
9994
  AND lease_token = $3
@@ -10215,12 +10243,14 @@ export async function settlePostgresSchedulerRuntimeResources(
10215
10243
  ): Promise<number> {
10216
10244
  const stamped = await client.query<{ run_id: string }>(
10217
10245
  `
10246
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}
10218
10247
  UPDATE ${tableName('attempts', options)}
10219
10248
  SET resource_json = (
10220
10249
  SELECT COALESCE(
10221
10250
  jsonb_agg(
10222
10251
  CASE
10223
10252
  WHEN elem->>'kind' IN ('daytona_sandbox', 'modal_sandbox')
10253
+ AND NOT ${protectedManagedSandboxSql({ runId: '$1', provider: "(CASE elem->>'kind' WHEN 'modal_sandbox' THEN 'modal' ELSE 'daytona' END)", sandboxId: "elem->>'sandboxId'", routingDomain: "(CASE elem->>'kind' WHEN 'modal_sandbox' THEN NULLIF(elem->>'modalAppId', '') ELSE NULLIF(elem->>'daytonaOrganizationId', '') END)" }, options, true)}
10224
10254
  AND (
10225
10255
  elem->'billingEndedAt' IS NULL
10226
10256
  OR elem->'billingEndedAt' = 'null'::jsonb
@@ -10241,6 +10271,7 @@ export async function settlePostgresSchedulerRuntimeResources(
10241
10271
  FROM jsonb_array_elements(resource_json) AS elem
10242
10272
  ),
10243
10273
  updated_at = now()
10274
+ FROM (SELECT count(*) FROM custody_operations) AS operation_locks
10244
10275
  WHERE run_id = $1
10245
10276
  AND ($4::integer IS NULL OR attempt <= $4)
10246
10277
  AND resource_json IS NOT NULL
@@ -11539,6 +11570,79 @@ export async function completePostgresSchedulerComputeBillingSessionBootstrap(
11539
11570
  return completed.rows.length > 0;
11540
11571
  }
11541
11572
 
11573
+ function runtimeSandboxCustodyLocksSql(
11574
+ runPredicate: string,
11575
+ options?: Pick<PostgresSchedulerOptions, 'schema'>,
11576
+ skipLocked = false,
11577
+ ): string {
11578
+ return `custody_runs AS MATERIALIZED (
11579
+ SELECT run.* FROM ${tableName('runs', options)} AS run
11580
+ WHERE ${runPredicate}
11581
+ ORDER BY run.run_id FOR NO KEY UPDATE ${skipLocked ? 'SKIP LOCKED' : ''}
11582
+ ), custody_attempts AS MATERIALIZED (
11583
+ SELECT attempt.* FROM ${tableName('attempts', options)} AS attempt
11584
+ WHERE attempt.run_id IN (SELECT run_id FROM custody_runs)
11585
+ ORDER BY attempt.run_id, attempt.attempt FOR UPDATE
11586
+ ), custody_leases AS MATERIALIZED (
11587
+ SELECT lease.* FROM ${tableName('runtime_sandbox_capacity_leases', options)} AS lease
11588
+ CROSS JOIN (SELECT count(*) FROM custody_attempts) AS attempt_locks
11589
+ WHERE lease.run_id IN (SELECT run_id FROM custody_runs)
11590
+ ORDER BY lease.run_id, lease.lease_id FOR UPDATE OF lease
11591
+ ), custody_operations AS MATERIALIZED (
11592
+ SELECT operation.* FROM ${tableName('runtime_sandbox_operations', options)} AS operation
11593
+ CROSS JOIN (SELECT count(*) FROM custody_leases) AS lease_locks
11594
+ WHERE operation.run_id IN (SELECT run_id FROM custody_runs)
11595
+ ORDER BY operation.run_id, operation.operation_key FOR UPDATE OF operation
11596
+ )`;
11597
+ }
11598
+
11599
+ function protectedManagedSandboxSql(
11600
+ identity: {
11601
+ runId: string;
11602
+ provider: string;
11603
+ sandboxId: string;
11604
+ routingDomain: string;
11605
+ },
11606
+ options?: Pick<PostgresSchedulerOptions, 'schema'>,
11607
+ locked = false,
11608
+ ): string {
11609
+ const runs = locked ? 'custody_runs' : tableName('runs', options);
11610
+ const attempts = locked ? 'custody_attempts' : tableName('attempts', options);
11611
+ const operations = locked
11612
+ ? 'custody_operations'
11613
+ : tableName('runtime_sandbox_operations', options);
11614
+ const leases = locked
11615
+ ? 'custody_leases'
11616
+ : tableName('runtime_sandbox_capacity_leases', options);
11617
+ return `EXISTS (
11618
+ SELECT 1 FROM ${runs} AS managed_run
11619
+ JOIN ${operations} AS managed_operation ON managed_operation.run_id = managed_run.run_id
11620
+ JOIN ${leases} AS managed_lease ON managed_lease.lease_id = managed_operation.operation_key
11621
+ WHERE managed_run.run_id = ${identity.runId}
11622
+ AND managed_run.status IN ('queued', 'running', 'waiting')
11623
+ AND managed_operation.provider = ${identity.provider}
11624
+ AND COALESCE(managed_operation.sandbox_id, managed_lease.sandbox_id) = ${identity.sandboxId}
11625
+ AND COALESCE(managed_operation.routing_domain, managed_lease.routing_domain)
11626
+ IS NOT DISTINCT FROM ${identity.routingDomain}
11627
+ AND managed_lease.released_at IS NULL
11628
+ AND NOT EXISTS (SELECT 1 FROM ${tableName('control', options)} AS cancel
11629
+ WHERE cancel.key = 'runtime_cancel:' || managed_run.run_id)
11630
+ AND (
11631
+ (managed_operation.state = 'reserved' AND managed_lease.expires_at > clock_timestamp())
11632
+ OR (managed_operation.state = 'live' AND EXISTS (
11633
+ SELECT 1 FROM ${attempts} AS owner_attempt
11634
+ WHERE owner_attempt.run_id = managed_run.run_id
11635
+ AND owner_attempt.attempt = managed_operation.attempt
11636
+ AND owner_attempt.status IN ('claimed', 'running', 'waiting')
11637
+ AND owner_attempt.runner_result_json IS NULL
11638
+ AND NOT EXISTS (SELECT 1 FROM ${attempts} AS newer
11639
+ WHERE newer.run_id = owner_attempt.run_id AND newer.attempt > owner_attempt.attempt)
11640
+ AND (owner_attempt.lease_expires_at IS NULL OR owner_attempt.lease_expires_at > clock_timestamp())
11641
+ ))
11642
+ )
11643
+ )`;
11644
+ }
11645
+
11542
11646
  /** Deletion needs terminal/cancellation/retired-resource authority. An old
11543
11647
  * worker error (including a billing end) is not evidence the runner stopped. */
11544
11648
  function protectedDetachedSandboxSql(
@@ -11549,10 +11653,11 @@ function protectedDetachedSandboxSql(
11549
11653
  routingDomain: string;
11550
11654
  },
11551
11655
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
11656
+ locked = false,
11552
11657
  ): string {
11553
- return `EXISTS (
11554
- SELECT 1 FROM ${tableName('runs', options)} AS detached_run
11555
- JOIN ${tableName('attempts', options)} AS detached_attempt
11658
+ return `(${protectedManagedSandboxSql(identity, options, locked)} OR EXISTS (
11659
+ SELECT 1 FROM ${locked ? 'custody_runs' : tableName('runs', options)} AS detached_run
11660
+ JOIN ${locked ? 'custody_attempts' : tableName('attempts', options)} AS detached_attempt
11556
11661
  ON detached_attempt.run_id = detached_run.run_id
11557
11662
  CROSS JOIN LATERAL jsonb_array_elements(
11558
11663
  CASE WHEN jsonb_typeof(detached_attempt.resource_json) = 'array'
@@ -11580,18 +11685,19 @@ function protectedDetachedSandboxSql(
11580
11685
  AND detached_resource -> 'executionDetachedAt' IS NOT NULL
11581
11686
  AND detached_resource -> 'executionDetachedAt' <> 'null'::jsonb)
11582
11687
  )
11583
- AND NOT EXISTS (SELECT 1 FROM ${tableName('attempts', options)} AS newer
11688
+ AND NOT EXISTS (SELECT 1 FROM ${locked ? 'custody_attempts' : tableName('attempts', options)} AS newer
11584
11689
  WHERE newer.run_id = detached_run.run_id
11585
11690
  AND newer.attempt > detached_attempt.attempt
11586
11691
  AND newer.status IN ('claimed', 'running', 'waiting', 'completed', 'failed'))
11587
11692
  AND NOT EXISTS (SELECT 1 FROM ${tableName('control', options)} AS cancel
11588
11693
  WHERE cancel.key = 'runtime_cancel:' || detached_run.run_id)
11589
- )`;
11694
+ ))`;
11590
11695
  }
11591
11696
 
11592
11697
  function protectedDetachedResourceSql(
11593
11698
  runId: string,
11594
11699
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
11700
+ locked = false,
11595
11701
  ): string {
11596
11702
  return protectedDetachedSandboxSql(
11597
11703
  {
@@ -11603,6 +11709,7 @@ function protectedDetachedResourceSql(
11603
11709
  "(CASE resource->>'kind' WHEN 'modal_sandbox' THEN NULLIF(resource->>'modalAppId', '') ELSE NULLIF(resource->>'daytonaOrganizationId', '') END)",
11604
11710
  },
11605
11711
  options,
11712
+ locked,
11606
11713
  );
11607
11714
  }
11608
11715
 
@@ -11632,9 +11739,10 @@ export async function enqueuePostgresSchedulerSandboxCleanupForAttempt(
11632
11739
  ): Promise<number> {
11633
11740
  const enqueued = await client.query<{ sandbox_id: string }>(
11634
11741
  `
11635
- WITH attempt_resources AS (
11742
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, attempt_resources AS (
11636
11743
  SELECT run_id, attempt, resource_json
11637
- FROM ${tableName('attempts', options)}
11744
+ FROM custody_attempts
11745
+ CROSS JOIN (SELECT count(*) FROM custody_operations) AS operation_locks
11638
11746
  WHERE run_id = $1
11639
11747
  AND attempt = $2
11640
11748
  AND resource_json IS NOT NULL
@@ -11669,7 +11777,7 @@ export async function enqueuePostgresSchedulerSandboxCleanupForAttempt(
11669
11777
  ) AS resource
11670
11778
  WHERE resource->>'kind' IN ('daytona_sandbox', 'modal_sandbox')
11671
11779
  AND NULLIF(resource->>'sandboxId', '') IS NOT NULL
11672
- AND NOT ${protectedDetachedResourceSql('$1', options)}
11780
+ AND NOT ${protectedDetachedResourceSql('$1', options, true)}
11673
11781
  ON CONFLICT (provider, sandbox_id, routing_domain_key) DO NOTHING
11674
11782
  RETURNING sandbox_id
11675
11783
  )
@@ -11689,6 +11797,7 @@ export async function enqueuePostgresSchedulerSandboxCleanupForRun(
11689
11797
  ): Promise<void> {
11690
11798
  await client.query(
11691
11799
  `
11800
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}
11692
11801
  INSERT INTO ${tableName('sandbox_cleanup_jobs_v2', options)} (
11693
11802
  provider, sandbox_id, run_id, attempt, environment, routing_domain
11694
11803
  )
@@ -11709,7 +11818,8 @@ export async function enqueuePostgresSchedulerSandboxCleanupForRun(
11709
11818
  WHEN 'modal_sandbox' THEN NULLIF(resource->>'modalAppId', '')
11710
11819
  ELSE NULLIF(resource->>'daytonaOrganizationId', '')
11711
11820
  END
11712
- FROM ${tableName('attempts', options)} AS attempt
11821
+ FROM custody_attempts AS attempt
11822
+ CROSS JOIN (SELECT count(*) FROM custody_operations) AS operation_locks
11713
11823
  CROSS JOIN LATERAL jsonb_array_elements(
11714
11824
  CASE
11715
11825
  WHEN jsonb_typeof(attempt.resource_json) = 'array'
@@ -11722,16 +11832,16 @@ export async function enqueuePostgresSchedulerSandboxCleanupForRun(
11722
11832
  AND attempt.resource_json IS NOT NULL
11723
11833
  AND resource->>'kind' IN ('daytona_sandbox', 'modal_sandbox')
11724
11834
  AND NULLIF(resource->>'sandboxId', '') IS NOT NULL
11725
- AND NOT ${protectedDetachedResourceSql('$1', options)}
11835
+ AND NOT ${protectedDetachedResourceSql('$1', options, true)}
11726
11836
  UNION ALL
11727
11837
  SELECT operation.provider, operation.sandbox_id, operation.run_id,
11728
11838
  operation.attempt, operation.environment, operation.routing_domain
11729
- FROM ${tableName('runtime_sandbox_operations', options)} AS operation
11839
+ FROM custody_operations AS operation
11730
11840
  WHERE operation.run_id = $1
11731
11841
  AND ($2::integer IS NULL OR operation.attempt <= $2)
11732
11842
  AND operation.state IN ('live', 'deleting')
11733
11843
  AND operation.sandbox_id IS NOT NULL
11734
- AND NOT ${protectedDetachedSandboxSql({ runId: 'operation.run_id', provider: 'operation.provider', sandboxId: 'operation.sandbox_id', routingDomain: 'operation.routing_domain' }, options)}
11844
+ AND NOT ${protectedDetachedSandboxSql({ runId: 'operation.run_id', provider: 'operation.provider', sandboxId: 'operation.sandbox_id', routingDomain: 'operation.routing_domain' }, options, true)}
11735
11845
  ON CONFLICT (provider, sandbox_id, routing_domain_key) DO NOTHING
11736
11846
  `,
11737
11847
  [input.runId, input.throughAttempt ?? null],
@@ -11746,9 +11856,10 @@ export async function abandonUnstartedModalCancellationReservations(
11746
11856
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
11747
11857
  ): Promise<void> {
11748
11858
  await client.query(
11749
- `WITH abandoned AS (
11859
+ `WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, abandoned AS (
11750
11860
  UPDATE ${tableName('runtime_sandbox_operations', options)} AS operation
11751
11861
  SET state = 'abandoned', updated_at = clock_timestamp()
11862
+ FROM (SELECT count(*) FROM custody_operations) AS operation_locks
11752
11863
  WHERE operation.run_id = $1
11753
11864
  AND operation.provider = 'modal'
11754
11865
  AND operation.state = 'reserved'
@@ -11890,7 +12001,21 @@ export async function claimPostgresSchedulerSandboxCleanupJobs(
11890
12001
  diagnostic_json: unknown | null;
11891
12002
  }>(
11892
12003
  `
11893
- WITH candidates AS (
12004
+ WITH candidate_jobs AS MATERIALIZED (
12005
+ SELECT cleanup.provider, cleanup.sandbox_id, cleanup.routing_domain_key, cleanup.run_id
12006
+ FROM ${tableName('sandbox_cleanup_jobs_v2', options)} AS cleanup
12007
+ WHERE cleanup.status <> 'deleted' AND cleanup.blocked_at IS NULL
12008
+ AND (cleanup.available_at <= now() OR cleanup.diagnostic_json IS NOT NULL)
12009
+ AND (cleanup.lease_expires_at IS NULL OR cleanup.lease_expires_at <= now())
12010
+ AND ($4::text IS NULL OR cleanup.environment = $4)
12011
+ AND ($5::text[] IS NULL OR cleanup.provider = ANY($5::text[]))
12012
+ AND ($8::text IS NULL OR cleanup.run_id = $8)
12013
+ AND ($9::integer IS NULL OR cleanup.attempt <= $9)
12014
+ AND NOT ${protectedDetachedSandboxSql({ runId: 'cleanup.run_id', provider: 'cleanup.provider', sandboxId: 'cleanup.sandbox_id', routingDomain: 'cleanup.routing_domain' }, options)}
12015
+ ORDER BY CASE WHEN cleanup.diagnostic_json IS NOT NULL THEN 0 ELSE 1 END,
12016
+ cleanup.available_at, cleanup.created_at, cleanup.provider, cleanup.sandbox_id, cleanup.routing_domain_key
12017
+ LIMIT $2
12018
+ ), ${runtimeSandboxCustodyLocksSql('EXISTS (SELECT 1 FROM candidate_jobs WHERE candidate_jobs.run_id = run.run_id)', options, true)}, candidates AS (
11894
12019
  SELECT
11895
12020
  cleanup.provider,
11896
12021
  cleanup.sandbox_id,
@@ -11898,9 +12023,14 @@ export async function claimPostgresSchedulerSandboxCleanupJobs(
11898
12023
  cleanup.routing_domain_key,
11899
12024
  run.status AS terminal_status
11900
12025
  FROM ${tableName('sandbox_cleanup_jobs_v2', options)} AS cleanup
11901
- JOIN ${tableName('runs', options)} AS run
12026
+ JOIN custody_runs AS run
11902
12027
  ON run.run_id = cleanup.run_id
11903
- WHERE cleanup.status <> 'deleted'
12028
+ CROSS JOIN (SELECT count(*) FROM custody_operations) AS operation_locks
12029
+ WHERE EXISTS (SELECT 1 FROM candidate_jobs AS selected
12030
+ WHERE selected.provider = cleanup.provider
12031
+ AND selected.sandbox_id = cleanup.sandbox_id
12032
+ AND selected.routing_domain_key = cleanup.routing_domain_key)
12033
+ AND cleanup.status <> 'deleted'
11904
12034
  AND cleanup.blocked_at IS NULL
11905
12035
  AND (
11906
12036
  cleanup.available_at <= now()
@@ -11911,7 +12041,7 @@ export async function claimPostgresSchedulerSandboxCleanupJobs(
11911
12041
  AND ($5::text[] IS NULL OR cleanup.provider = ANY($5::text[]))
11912
12042
  AND ($8::text IS NULL OR cleanup.run_id = $8)
11913
12043
  AND ($9::integer IS NULL OR cleanup.attempt <= $9)
11914
- AND NOT ${protectedDetachedSandboxSql({ runId: 'cleanup.run_id', provider: 'cleanup.provider', sandboxId: 'cleanup.sandbox_id', routingDomain: 'cleanup.routing_domain' }, options)}
12044
+ AND NOT ${protectedDetachedSandboxSql({ runId: 'cleanup.run_id', provider: 'cleanup.provider', sandboxId: 'cleanup.sandbox_id', routingDomain: 'cleanup.routing_domain' }, options, true)}
11915
12045
  ORDER BY
11916
12046
  CASE WHEN cleanup.diagnostic_json IS NOT NULL THEN 0 ELSE 1 END ASC,
11917
12047
  cleanup.available_at ASC,
@@ -11948,12 +12078,28 @@ export async function claimPostgresSchedulerSandboxCleanupJobs(
11948
12078
  operation_claimed AS (
11949
12079
  UPDATE ${tableName('runtime_sandbox_operations', options)} AS operation
11950
12080
  SET state = $6,
12081
+ sandbox_id = claimed.sandbox_id,
12082
+ routing_domain = claimed.routing_domain,
12083
+ provider_created_at = COALESCE(operation.provider_created_at, clock_timestamp()),
11951
12084
  updated_at = clock_timestamp()
11952
12085
  FROM claimed
11953
- WHERE operation.provider = claimed.provider
11954
- AND operation.sandbox_id = claimed.sandbox_id
11955
- AND operation.routing_domain IS NOT DISTINCT FROM claimed.routing_domain
11956
- AND operation.state = $7
12086
+ WHERE operation.run_id = claimed.run_id
12087
+ AND operation.provider = claimed.provider
12088
+ AND (
12089
+ (operation.state = $7
12090
+ AND operation.sandbox_id = claimed.sandbox_id
12091
+ AND operation.routing_domain IS NOT DISTINCT FROM claimed.routing_domain)
12092
+ OR (operation.state = 'reserved'
12093
+ AND operation.sandbox_id IS NULL
12094
+ AND EXISTS (
12095
+ SELECT 1 FROM custody_leases AS lease
12096
+ WHERE lease.lease_id = operation.operation_key
12097
+ AND lease.run_id = claimed.run_id
12098
+ AND lease.provider = claimed.provider
12099
+ AND lease.sandbox_id = claimed.sandbox_id
12100
+ AND lease.routing_domain IS NOT DISTINCT FROM claimed.routing_domain
12101
+ ))
12102
+ )
11957
12103
  RETURNING operation.operation_key
11958
12104
  ),
11959
12105
  claim_events AS (
@@ -12165,12 +12311,14 @@ export async function completePostgresSchedulerSandboxCleanupJob(
12165
12311
  > {
12166
12312
  const completed = await client.query<{ outcome: string }>(
12167
12313
  `
12168
- WITH current_job AS MATERIALIZED (
12314
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $3', options)}, current_job AS MATERIALIZED (
12169
12315
  SELECT status, attempt_count, lease_owner, routing_domain
12170
- FROM ${tableName('sandbox_cleanup_jobs_v2', options)}
12316
+ FROM ${tableName('sandbox_cleanup_jobs_v2', options)} AS sandbox_cleanup_jobs_v2
12317
+ CROSS JOIN (SELECT count(*) FROM custody_operations) AS operation_locks
12171
12318
  WHERE provider = $8
12172
12319
  AND sandbox_id = $1
12173
12320
  AND routing_domain IS NOT DISTINCT FROM $9
12321
+ FOR UPDATE OF sandbox_cleanup_jobs_v2
12174
12322
  ),
12175
12323
  completed AS (
12176
12324
  UPDATE ${tableName('sandbox_cleanup_jobs_v2', options)} AS target
@@ -12246,7 +12394,8 @@ export async function completePostgresSchedulerSandboxCleanupJob(
12246
12394
  SET resource_json = (
12247
12395
  SELECT jsonb_agg(
12248
12396
  CASE
12249
- WHEN resource->>'kind' = 'modal_sandbox'
12397
+ WHEN resource->>'kind' = CASE $8::text WHEN 'modal' THEN 'modal_sandbox' ELSE 'daytona_sandbox' END
12398
+ AND (CASE $8::text WHEN 'modal' THEN NULLIF(resource->>'modalAppId', '') ELSE NULLIF(resource->>'daytonaOrganizationId', '') END) IS NOT DISTINCT FROM $9::text
12250
12399
  AND resource->>'sandboxId' = $1
12251
12400
  AND resource->>'lateAcquired' = 'true'
12252
12401
  AND (
@@ -12287,7 +12436,8 @@ export async function completePostgresSchedulerSandboxCleanupJob(
12287
12436
  ELSE jsonb_build_array(attempt.resource_json)
12288
12437
  END
12289
12438
  ) AS candidate
12290
- WHERE candidate->>'kind' = 'modal_sandbox'
12439
+ WHERE candidate->>'kind' = CASE $8::text WHEN 'modal' THEN 'modal_sandbox' ELSE 'daytona_sandbox' END
12440
+ AND (CASE $8::text WHEN 'modal' THEN NULLIF(candidate->>'modalAppId', '') ELSE NULLIF(candidate->>'daytonaOrganizationId', '') END) IS NOT DISTINCT FROM $9::text
12291
12441
  AND candidate->>'sandboxId' = $1
12292
12442
  AND candidate->>'lateAcquired' = 'true'
12293
12443
  )
@@ -13014,7 +13164,7 @@ export async function completePostgresSchedulerAttempt(
13014
13164
  );
13015
13165
  const completed = await client.query<{ run_id: string }>(
13016
13166
  `
13017
- WITH completed AS (
13167
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, completed AS (
13018
13168
  UPDATE ${tableName('attempts', options)}
13019
13169
  SET status = 'completed',
13020
13170
  terminalization_mode = 'compatibility_wake',
@@ -13051,6 +13201,7 @@ export async function completePostgresSchedulerAttempt(
13051
13201
  )
13052
13202
  END,
13053
13203
  updated_at = now()
13204
+ FROM (SELECT count(*) FROM custody_attempts) AS attempt_locks
13054
13205
  WHERE run_id = $1
13055
13206
  AND attempt = $2
13056
13207
  AND status = 'running'
@@ -13291,7 +13442,7 @@ export async function failPostgresSchedulerAttempt(
13291
13442
  );
13292
13443
  const failed = await client.query<{ run_id: string }>(
13293
13444
  `
13294
- WITH failed AS (
13445
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, failed AS (
13295
13446
  UPDATE ${tableName('attempts', options)}
13296
13447
  SET status = 'failed',
13297
13448
  lease_expires_at = NULL,
@@ -13338,6 +13489,7 @@ export async function failPostgresSchedulerAttempt(
13338
13489
  )
13339
13490
  END,
13340
13491
  updated_at = now()
13492
+ FROM (SELECT count(*) FROM custody_attempts) AS attempt_locks
13341
13493
  WHERE run_id = $1
13342
13494
  AND attempt = $2
13343
13495
  AND status = 'running'
@@ -13625,7 +13777,7 @@ export async function cancelPostgresSchedulerRun(
13625
13777
  launch_json: PlaySchedulerSubmitInput;
13626
13778
  }>(
13627
13779
  `
13628
- WITH cancelled_run AS (
13780
+ WITH ${runtimeSandboxCustodyLocksSql('run.run_id = $1', options)}, cancelled_run AS (
13629
13781
  UPDATE ${tableName('runs', options)} AS target
13630
13782
  SET status = 'cancelled',
13631
13783
  terminal_result_json = NULL,
@@ -13634,6 +13786,7 @@ export async function cancelPostgresSchedulerRun(
13634
13786
  wait_deadline = NULL,
13635
13787
  finished_at = now(),
13636
13788
  updated_at = now()
13789
+ FROM (SELECT count(*) FROM custody_attempts) AS attempt_locks
13637
13790
  WHERE target.run_id = $1
13638
13791
  AND target.status IN ('queued', 'running', 'waiting')
13639
13792
  ${strandedEligibility}