deepline 0.3.270 → 0.3.272

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 (29) 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 +3 -2
  3. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +11 -9
  4. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +5 -4
  5. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +2 -1
  6. package/dist/bundling-sources/shared_libs/play-runtime/run-event-catalog.ts +610 -0
  7. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +3 -1
  8. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-projection-diagnostics.ts +3 -2
  9. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +80 -67
  10. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +5 -4
  11. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +59 -20
  12. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +3 -2
  13. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +19 -9
  14. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +205 -107
  15. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +125 -81
  16. package/dist/cli/getting-started.d.mts +13 -9
  17. package/dist/cli/getting-started.d.ts +13 -9
  18. package/dist/cli/getting-started.js +15 -3
  19. package/dist/cli/getting-started.mjs +13 -3
  20. package/dist/cli/index.js +447 -11
  21. package/dist/cli/index.mjs +447 -11
  22. package/dist/index.js +420 -1
  23. package/dist/index.mjs +420 -1
  24. package/dist/install-integrity.json +1 -0
  25. package/dist/release.d.mts +1 -1
  26. package/dist/release.d.ts +1 -1
  27. package/dist/release.js +1 -1
  28. package/dist/release.mjs +1 -1
  29. package/package.json +1 -1
@@ -98,6 +98,15 @@ import {
98
98
  type PlayRunLedgerIngressEvent,
99
99
  type PlayRunLedgerTerminalWorkCounterSegment,
100
100
  } from '../run-ledger';
101
+ import {
102
+ RUN_EVENT_KIND_SQL_LITERAL,
103
+ RUN_EVENT_KIND,
104
+ RUN_SCHEDULER_OUTBOX_START_EVENT_TYPES,
105
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE,
106
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL,
107
+ RUN_SCHEDULER_OUTBOX_PREFIX_STOP_EVENT_TYPES,
108
+ RUN_SCHEDULER_OUTBOX_TERMINAL_EVENT_TYPES,
109
+ } from '../run-event-catalog';
101
110
  import { stableStringify } from '../../plays/row-identity';
102
111
  import {
103
112
  runtimeWorkCountersFromResources,
@@ -322,7 +331,9 @@ const POSTGRES_SCHEDULER_SCHEMA_INIT_STATEMENT_TIMEOUT_MS = 60_000;
322
331
  // v54 expands the optional per-run canonical event-store marker.
323
332
  // v55 refreshes the unified event journal projection. The canonical retention
324
333
  // index stays operator-prepared concurrently before marked-run admission.
325
- export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 55;
334
+ // v56 adds a release-leading index for fixed-controller runner-terminal
335
+ // recovery, which scans only active runs for each release lane.
336
+ export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 56;
326
337
  const POSTGRES_SCHEDULER_SCHEMA_MIGRATIONS_TABLE =
327
338
  'scheduler_schema_migrations';
328
339
  export const POSTGRES_SCHEDULER_OPEN_RECOVERY_INDEX =
@@ -926,13 +937,13 @@ export const POSTGRES_SCHEDULER_OUTBOX_DELIVERED_RETENTION_BATCH_LIMIT = 1_000;
926
937
  // eligibility test, including present-but-null log fields.
927
938
  const DELIVERED_OUTBOX_RAW_LOG_BODY_PREDICATE = `
928
939
  (
929
- (event_type = 'run.events'
940
+ (event_type = ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents}
930
941
  AND jsonb_typeof(payload_json->'events') = 'array'
931
- AND payload_json @? 'strict $.events[*] ? (@.type == "log.appended" && (exists(@.lines) || exists(@.lineContexts)))'::jsonpath)
932
- OR (event_type IN ('run.completed', 'run.failed')
942
+ AND payload_json @? 'strict $.events[*] ? (@.type == "${RUN_EVENT_KIND.logAppended}" && (exists(@.lines) || exists(@.lineContexts)))'::jsonpath)
943
+ OR (event_type IN (${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed})
933
944
  AND (payload_json ? 'terminalLogLines'
934
945
  OR (jsonb_typeof(payload_json->'terminalProgressEvents') = 'array'
935
- AND payload_json @? 'strict $.terminalProgressEvents[*] ? (@.type == "log.appended" && (exists(@.lines) || exists(@.lineContexts)))'::jsonpath)))
946
+ AND payload_json @? 'strict $.terminalProgressEvents[*] ? (@.type == "${RUN_EVENT_KIND.logAppended}" && (exists(@.lines) || exists(@.lineContexts)))'::jsonpath)))
936
947
  )`;
937
948
  const RUN_LEDGER_DISPATCH_TOKEN_TIMEOUT_MS = 15_000;
938
949
  const COMPUTE_BILLING_DISPATCH_TOKEN_TIMEOUT_MS = 15_000;
@@ -2034,6 +2045,15 @@ export async function hasCurrentPostgresSchedulerSchemaShape(
2034
2045
  AND index_row.indrelid = to_regclass($4)
2035
2046
  AND index_row.indisready AND index_row.indisvalid
2036
2047
  )
2048
+ AND EXISTS (
2049
+ SELECT 1 FROM pg_index AS index_row
2050
+ JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
2051
+ JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
2052
+ WHERE index_namespace.nspname = $1
2053
+ AND index_class.relname = 'runtime_scheduler_runs_absurd_release_active_idx'
2054
+ AND index_row.indrelid = to_regclass($4)
2055
+ AND index_row.indisready AND index_row.indisvalid
2056
+ )
2037
2057
  AND EXISTS (
2038
2058
  SELECT 1 FROM pg_index AS index_row
2039
2059
  JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
@@ -2241,7 +2261,7 @@ async function ensurePostgresSchedulerTerminalComputeBillingOutboxTrigger(
2241
2261
  LANGUAGE plpgsql
2242
2262
  AS $$
2243
2263
  BEGIN
2244
- IF NEW.event_type NOT IN ('run.completed', 'run.failed', 'run.cancelled') THEN
2264
+ IF NEW.event_type NOT IN (${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed}, ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled}) THEN
2245
2265
  RETURN NEW;
2246
2266
  END IF;
2247
2267
 
@@ -3896,7 +3916,7 @@ export async function ensurePostgresSchedulerSchema(
3896
3916
  await client.query(`
3897
3917
  CREATE INDEX IF NOT EXISTS runtime_scheduler_outbox_admission_pending_idx
3898
3918
  ON ${tableName('outbox', options)} (
3899
- (CASE WHEN event_type = 'run.created' THEN 0 ELSE 1 END),
3919
+ (CASE WHEN event_type = ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0 ELSE 1 END),
3900
3920
  coalesce(next_attempt_at, created_at),
3901
3921
  created_at,
3902
3922
  event_id
@@ -3912,7 +3932,7 @@ export async function ensurePostgresSchedulerSchema(
3912
3932
  CREATE INDEX IF NOT EXISTS runtime_scheduler_outbox_run_pending_order_idx
3913
3933
  ON ${tableName('outbox', options)} (
3914
3934
  run_id,
3915
- (CASE event_type WHEN 'run.created' THEN 0 WHEN 'run.started' THEN 1 ELSE 2 END),
3935
+ (CASE event_type WHEN ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0 WHEN ${RUN_EVENT_KIND_SQL_LITERAL.runStarted} THEN 1 ELSE 2 END),
3916
3936
  created_at,
3917
3937
  event_id
3918
3938
  )
@@ -3990,6 +4010,11 @@ export async function ensurePostgresSchedulerSchema(
3990
4010
  WHERE status IN ('completed', 'failed', 'cancelled')
3991
4011
  AND started_at IS NOT NULL
3992
4012
  `);
4013
+ await client.query(`
4014
+ CREATE INDEX IF NOT EXISTS runtime_scheduler_runs_absurd_release_active_idx
4015
+ ON ${tableName('runs', options)} ((launch_json ->> 'absurdReleaseId'), run_id)
4016
+ WHERE status IN ('queued', 'running', 'waiting')
4017
+ `);
3993
4018
  }
3994
4019
  await client.query(`
3995
4020
  CREATE INDEX IF NOT EXISTS runtime_scheduler_receipts_run_idx
@@ -4059,7 +4084,7 @@ const POSTGRES_SCHEDULER_RUNTIME_ADMIN_INDEXES = [
4059
4084
  name: 'runtime_scheduler_outbox_run_pending_order_idx',
4060
4085
  table: 'outbox',
4061
4086
  definition: `(run_id,
4062
- (CASE event_type WHEN 'run.created' THEN 0 WHEN 'run.started' THEN 1 ELSE 2 END),
4087
+ (CASE event_type WHEN ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0 WHEN ${RUN_EVENT_KIND_SQL_LITERAL.runStarted} THEN 1 ELSE 2 END),
4063
4088
  created_at, event_id)
4064
4089
  WHERE delivered_at IS NULL`,
4065
4090
  },
@@ -4089,7 +4114,7 @@ const POSTGRES_SCHEDULER_RUNTIME_ADMIN_INDEXES = [
4089
4114
  name: 'runtime_scheduler_outbox_admission_pending_idx',
4090
4115
  table: 'outbox',
4091
4116
  definition: `(
4092
- (CASE WHEN event_type = 'run.created' THEN 0 ELSE 1 END),
4117
+ (CASE WHEN event_type = ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0 ELSE 1 END),
4093
4118
  coalesce(next_attempt_at, created_at),
4094
4119
  created_at,
4095
4120
  event_id
@@ -4165,6 +4190,12 @@ const POSTGRES_SCHEDULER_RUNTIME_ADMIN_INDEXES = [
4165
4190
  WHERE status IN ('completed', 'failed', 'cancelled')
4166
4191
  AND started_at IS NOT NULL`,
4167
4192
  },
4193
+ {
4194
+ name: 'runtime_scheduler_runs_absurd_release_active_idx',
4195
+ table: 'runs',
4196
+ definition: `((launch_json ->> 'absurdReleaseId'), run_id)
4197
+ WHERE status IN ('queued', 'running', 'waiting')`,
4198
+ },
4168
4199
  {
4169
4200
  name: 'runtime_scheduler_rate_reservation_bucket_expiry_idx',
4170
4201
  table: 'rate_reservations',
@@ -5123,7 +5154,7 @@ async function submitPostgresSchedulerRunTransaction(
5123
5154
  SELECT
5124
5155
  'run-created:' || run_insert.run_id,
5125
5156
  run_insert.run_id,
5126
- 'run.created',
5157
+ ${RUN_EVENT_KIND_SQL_LITERAL.runCreated},
5127
5158
  jsonb_strip_nulls(jsonb_build_object(
5128
5159
  'orgId', $2::text,
5129
5160
  'playId', $3::text,
@@ -6210,7 +6241,7 @@ export async function firePostgresSchedulerCronSchedule(
6210
6241
  SELECT
6211
6242
  'run-created:' || run_insert.run_id,
6212
6243
  run_insert.run_id,
6213
- 'run.created',
6244
+ ${RUN_EVENT_KIND_SQL_LITERAL.runCreated},
6214
6245
  jsonb_strip_nulls(jsonb_build_object(
6215
6246
  'orgId', launch_payload.launch_json ->> 'orgId',
6216
6247
  'playId', launch_payload.launch_json ->> 'playId',
@@ -7225,7 +7256,7 @@ export async function resumePostgresSchedulerDetachedRunnerAttempt(
7225
7256
  INSERT INTO ${tableName('outbox', options)} (
7226
7257
  event_id, run_id, event_type, payload_json, created_at
7227
7258
  )
7228
- SELECT $4, run_id, 'run.waiting', jsonb_build_object('kind', 'detached_runner'),
7259
+ SELECT $4, run_id, ${RUN_EVENT_KIND_SQL_LITERAL.runWaiting}, jsonb_build_object('kind', 'detached_runner'),
7229
7260
  ${causalOutboxCreatedAt('restored_run.run_id', options)}
7230
7261
  FROM restored_run
7231
7262
  RETURNING run_id
@@ -7364,7 +7395,7 @@ export async function markPostgresSchedulerAttemptWaiting(
7364
7395
  SELECT
7365
7396
  $6,
7366
7397
  waiting_run.run_id,
7367
- 'run.waiting',
7398
+ ${RUN_EVENT_KIND_SQL_LITERAL.runWaiting},
7368
7399
  jsonb_strip_nulls(jsonb_build_object(
7369
7400
  'kind', NULLIF(btrim($4::jsonb ->> 'kind'), ''),
7370
7401
  'eventKey', NULLIF($7::text, ''),
@@ -7510,7 +7541,7 @@ export async function markPostgresSchedulerAttemptRunning(
7510
7541
  SELECT
7511
7542
  $4,
7512
7543
  running_run.run_id,
7513
- 'run.resumed',
7544
+ ${RUN_EVENT_KIND_SQL_LITERAL.runResumed},
7514
7545
  jsonb_strip_nulls(jsonb_build_object(
7515
7546
  'kind', NULLIF(btrim(running_run.suspension_json ->> 'kind'), ''),
7516
7547
  'eventKey',
@@ -7608,7 +7639,7 @@ export async function claimPostgresSchedulerCompletedDetachedRunnerTerminal(
7608
7639
  SELECT
7609
7640
  $3,
7610
7641
  run_id,
7611
- 'run.resumed',
7642
+ ${RUN_EVENT_KIND_SQL_LITERAL.runResumed},
7612
7643
  jsonb_build_object(
7613
7644
  'kind', 'detached_runner',
7614
7645
  'eventKey', 'detached_runner_terminal'
@@ -7754,7 +7785,7 @@ export async function claimPostgresSchedulerOverdueDetachedRunnerCeilings(
7754
7785
  SELECT
7755
7786
  $3 || ':' || running_runs.run_id,
7756
7787
  running_runs.run_id,
7757
- 'run.resumed',
7788
+ ${RUN_EVENT_KIND_SQL_LITERAL.runResumed},
7758
7789
  jsonb_build_object(
7759
7790
  'kind', 'detached_runner',
7760
7791
  'eventKey', 'detached_runner_hard_ceiling'
@@ -8015,7 +8046,7 @@ export async function failPostgresSchedulerScheduledChildWaits(
8015
8046
  SELECT
8016
8047
  'run-terminal:' || run_id,
8017
8048
  terminal_runs.run_id,
8018
- 'run.failed',
8049
+ ${RUN_EVENT_KIND_SQL_LITERAL.runFailed},
8019
8050
  jsonb_build_object('error', $2::text),
8020
8051
  ${causalOutboxCreatedAt('terminal_runs.run_id', options)}
8021
8052
  FROM terminal_runs
@@ -8281,7 +8312,7 @@ export async function claimPostgresSchedulerWaitingDetachedAttemptForTerminal(
8281
8312
  SELECT
8282
8313
  $4,
8283
8314
  running_run.run_id,
8284
- 'run.resumed',
8315
+ ${RUN_EVENT_KIND_SQL_LITERAL.runResumed},
8285
8316
  jsonb_build_object(
8286
8317
  'kind', 'detached_runner',
8287
8318
  'eventKey', 'detached_runner_terminal_salvage'
@@ -8690,7 +8721,7 @@ export async function handoffPostgresSchedulerAttemptContinuation(
8690
8721
  SELECT
8691
8722
  $6,
8692
8723
  continuation_run.run_id,
8693
- 'run.resumed',
8724
+ ${RUN_EVENT_KIND_SQL_LITERAL.runResumed},
8694
8725
  jsonb_strip_nulls(jsonb_build_object(
8695
8726
  'kind', NULLIF(btrim(continuation_run.suspension_json ->> 'kind'), ''),
8696
8727
  'eventKey',
@@ -10610,7 +10641,7 @@ export async function directCompletePostgresSchedulerRunnerTerminal(
10610
10641
  SELECT
10611
10642
  'run-terminal:' || run_id,
10612
10643
  run_terminal.run_id,
10613
- 'run.completed',
10644
+ ${RUN_EVENT_KIND_SQL_LITERAL.runCompleted},
10614
10645
  jsonb_build_object(
10615
10646
  'output', $6::jsonb,
10616
10647
  'producerAttempt', $2::integer,
@@ -12521,6 +12552,7 @@ async function readPostgresSchedulerRunnerTerminalReceivedAtMs(
12521
12552
  * there is no release stamp.
12522
12553
  */
12523
12554
  export type PostgresSchedulerCompletedRunnerTerminal = {
12555
+ releaseId: string | null;
12524
12556
  runId: string;
12525
12557
  attempt: number;
12526
12558
  leaseToken: string;
@@ -12532,45 +12564,95 @@ export async function listPostgresSchedulerCompletedRunnerTerminals(
12532
12564
  input: {
12533
12565
  limit?: number;
12534
12566
  absurdReleaseId?: string | null;
12567
+ absurdReleaseIds?: readonly string[];
12535
12568
  includeFailed?: boolean;
12536
12569
  } = {},
12537
12570
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
12538
12571
  ): Promise<PostgresSchedulerCompletedRunnerTerminal[]> {
12539
12572
  const limit = Math.min(500, Math.max(1, Math.floor(input.limit ?? 100)));
12573
+ const releaseIds = input.absurdReleaseIds
12574
+ ? [
12575
+ ...new Set(
12576
+ input.absurdReleaseIds.map((id) => id.trim()).filter(Boolean),
12577
+ ),
12578
+ ]
12579
+ : null;
12580
+ if (releaseIds && releaseIds.length === 0) return [];
12581
+ const activeAttemptStatus = input.includeFailed
12582
+ ? `attempts.status IN ('running', 'waiting')`
12583
+ : `attempts.status = 'running'`;
12584
+ const runnerTerminalStatus = input.includeFailed
12585
+ ? `attempts.runner_result_json ->> 'status' IN ('completed', 'failed')`
12586
+ : `attempts.runner_result_json ->> 'status' = 'completed'`;
12587
+ const terminalQuery = releaseIds
12588
+ ? {
12589
+ sql: `
12590
+ WITH requested_lanes AS (
12591
+ SELECT DISTINCT btrim(release_id) AS release_id
12592
+ FROM unnest($1::text[]) AS requested(release_id)
12593
+ WHERE btrim(release_id) <> ''
12594
+ )
12595
+ SELECT terminals.release_id,
12596
+ terminals.run_id,
12597
+ terminals.attempt,
12598
+ terminals.lease_token,
12599
+ terminals.runner_result_json
12600
+ FROM requested_lanes AS lanes
12601
+ CROSS JOIN LATERAL (
12602
+ SELECT runs.launch_json ->> 'absurdReleaseId' AS release_id,
12603
+ attempts.run_id,
12604
+ attempts.attempt,
12605
+ attempts.lease_token,
12606
+ attempts.runner_result_json
12607
+ FROM ${tableName('runs', options)} AS runs
12608
+ JOIN ${tableName('attempts', options)} AS attempts
12609
+ ON attempts.run_id = runs.run_id
12610
+ WHERE runs.launch_json ->> 'absurdReleaseId' = lanes.release_id
12611
+ AND runs.status IN ('queued', 'running', 'waiting')
12612
+ AND ${activeAttemptStatus}
12613
+ AND attempts.lease_token IS NOT NULL
12614
+ AND ${runnerTerminalStatus}
12615
+ ORDER BY attempts.updated_at ASC, attempts.run_id ASC
12616
+ LIMIT $2
12617
+ ) AS terminals
12618
+ `,
12619
+ params: [releaseIds, limit],
12620
+ }
12621
+ : (() => {
12622
+ const releaseId = input.absurdReleaseId?.trim() || null;
12623
+ const releasePredicate = releaseId
12624
+ ? `AND runs.launch_json ->> 'absurdReleaseId' = $1::text`
12625
+ : '';
12626
+ return {
12627
+ sql: `
12628
+ SELECT runs.launch_json ->> 'absurdReleaseId' AS release_id,
12629
+ attempts.run_id,
12630
+ attempts.attempt,
12631
+ attempts.lease_token,
12632
+ attempts.runner_result_json
12633
+ FROM ${tableName('attempts', options)} AS attempts
12634
+ JOIN ${tableName('runs', options)} AS runs
12635
+ ON runs.run_id = attempts.run_id
12636
+ WHERE ${activeAttemptStatus}
12637
+ AND attempts.lease_token IS NOT NULL
12638
+ AND ${runnerTerminalStatus}
12639
+ AND runs.status IN ('queued', 'running', 'waiting')
12640
+ ${releasePredicate}
12641
+ ORDER BY attempts.updated_at ASC, attempts.run_id ASC
12642
+ LIMIT $${releaseId ? 2 : 1}
12643
+ `,
12644
+ params: releaseId ? [releaseId, limit] : [limit],
12645
+ };
12646
+ })();
12540
12647
  const terminals = await client.query<{
12648
+ release_id: string | null;
12541
12649
  run_id: string;
12542
12650
  attempt: number;
12543
12651
  lease_token: string;
12544
12652
  runner_result_json: unknown;
12545
- }>(
12546
- `
12547
- SELECT
12548
- attempts.run_id,
12549
- attempts.attempt,
12550
- attempts.lease_token,
12551
- attempts.runner_result_json
12552
- FROM ${tableName('attempts', options)} AS attempts
12553
- JOIN ${tableName('runs', options)} AS runs
12554
- ON runs.run_id = attempts.run_id
12555
- WHERE attempts.status = ANY($4::text[])
12556
- AND attempts.lease_token IS NOT NULL
12557
- AND attempts.runner_result_json ->> 'status' = ANY($3::text[])
12558
- AND runs.status IN ('queued', 'running', 'waiting')
12559
- AND (
12560
- $1::text IS NULL
12561
- OR runs.launch_json ->> 'absurdReleaseId' = $1::text
12562
- )
12563
- ORDER BY attempts.updated_at ASC, attempts.run_id ASC
12564
- LIMIT $2
12565
- `,
12566
- [
12567
- input.absurdReleaseId?.trim() || null,
12568
- limit,
12569
- input.includeFailed ? ['completed', 'failed'] : ['completed'],
12570
- input.includeFailed ? ['running', 'waiting'] : ['running'],
12571
- ],
12572
- );
12653
+ }>(terminalQuery.sql, terminalQuery.params);
12573
12654
  return terminals.rows.map((row) => ({
12655
+ releaseId: row.release_id,
12574
12656
  runId: row.run_id,
12575
12657
  attempt: row.attempt,
12576
12658
  leaseToken: row.lease_token,
@@ -13016,7 +13098,7 @@ export async function completePostgresSchedulerAttempt(
13016
13098
  SELECT
13017
13099
  'run-terminal:' || run_id,
13018
13100
  run_terminal.run_id,
13019
- 'run.completed',
13101
+ ${RUN_EVENT_KIND_SQL_LITERAL.runCompleted},
13020
13102
  jsonb_build_object(
13021
13103
  'output', $9::jsonb,
13022
13104
  'producerAttempt', $2::integer,
@@ -13352,7 +13434,7 @@ export async function failPostgresSchedulerAttempt(
13352
13434
  SELECT
13353
13435
  'run-terminal:' || run_id,
13354
13436
  run_terminal.run_id,
13355
- 'run.failed',
13437
+ ${RUN_EVENT_KIND_SQL_LITERAL.runFailed},
13356
13438
  jsonb_build_object(
13357
13439
  'error', $4::jsonb ->> 'message',
13358
13440
  'result', $8::jsonb,
@@ -13610,7 +13692,7 @@ export async function cancelPostgresSchedulerRun(
13610
13692
  SELECT
13611
13693
  'run-terminal:' || run_id,
13612
13694
  cancelled_run.run_id,
13613
- 'run.cancelled',
13695
+ ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled},
13614
13696
  jsonb_build_object('error', $5::text),
13615
13697
  ${causalOutboxCreatedAt('cancelled_run.run_id', options)},
13616
13698
  NULL,
@@ -16998,7 +17080,12 @@ export async function appendPostgresRunLedgerEvents(
16998
17080
  const eventId = `run-events:${input.runId}:${createHash('sha256').update(payload).digest('hex')}`;
16999
17081
  return appendRunLedgerOutboxFact(
17000
17082
  client,
17001
- { ...input, eventId, eventType: 'run.events', payload },
17083
+ {
17084
+ ...input,
17085
+ eventId,
17086
+ eventType: RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runEvents,
17087
+ payload,
17088
+ },
17002
17089
  options,
17003
17090
  );
17004
17091
  }
@@ -17023,7 +17110,7 @@ export async function appendPostgresRunLedgerStart(
17023
17110
  orgId: input.orgId,
17024
17111
  runId: input.runId,
17025
17112
  eventId: `run-start-callback:${input.runId}`,
17026
- eventType: 'run.started',
17113
+ eventType: RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runStarted,
17027
17114
  payload: stableStringify(
17028
17115
  prepareRetainedPlayPipelinesForTransport(input.start),
17029
17116
  ),
@@ -17038,7 +17125,9 @@ async function appendRunLedgerOutboxFact(
17038
17125
  orgId: string;
17039
17126
  runId: string;
17040
17127
  eventId: string;
17041
- eventType: 'run.events' | 'run.started';
17128
+ eventType:
17129
+ | typeof RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runEvents
17130
+ | typeof RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runStarted;
17042
17131
  payload: string;
17043
17132
  },
17044
17133
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
@@ -17176,14 +17265,16 @@ export async function assertPostgresRunLedgerDelivery(
17176
17265
  prefixStopReason = 'predecessor_failed';
17177
17266
  break;
17178
17267
  }
17179
- if (prefix.length > 0 && row.event_type === 'run.events') break;
17268
+ if (
17269
+ prefix.length > 0 &&
17270
+ row.event_type === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runEvents
17271
+ )
17272
+ break;
17180
17273
  prefix.push(row);
17181
17274
 
17182
17275
  const first = prefix[0]!;
17183
17276
  const terminal = prefix.find((candidate) =>
17184
- ['run.completed', 'run.failed', 'run.cancelled'].includes(
17185
- candidate.event_type,
17186
- ),
17277
+ RUN_SCHEDULER_OUTBOX_TERMINAL_EVENT_TYPES.includes(candidate.event_type),
17187
17278
  );
17188
17279
  const prefixDigest = createHash('sha256')
17189
17280
  .update(prefix.map((candidate) => candidate.delivery_key).join('\n'))
@@ -17196,7 +17287,7 @@ export async function assertPostgresRunLedgerDelivery(
17196
17287
  });
17197
17288
  } else if (
17198
17289
  prefix.length === 1 &&
17199
- ['run.created', 'run.started'].includes(first.event_type)
17290
+ RUN_SCHEDULER_OUTBOX_START_EVENT_TYPES.includes(first.event_type)
17200
17291
  ) {
17201
17292
  expectedKey = buildRunLedgerStartIdempotencyKey({
17202
17293
  runId: input.runId,
@@ -17219,7 +17310,7 @@ export async function assertPostgresRunLedgerDelivery(
17219
17310
  // Preserve the old singleton key for non-start, nonterminal facts.
17220
17311
  const legacySingletonKey =
17221
17312
  prefix.length === 1 &&
17222
- !['run.created', 'run.started'].includes(first.event_type) &&
17313
+ !RUN_SCHEDULER_OUTBOX_START_EVENT_TYPES.includes(first.event_type) &&
17223
17314
  input.idempotencyKey ===
17224
17315
  buildRunLedgerTerminalIdempotencyKey({
17225
17316
  runId: input.runId,
@@ -17270,7 +17361,7 @@ export async function assertPostgresRunLedgerDelivery(
17270
17361
 
17271
17362
  if (
17272
17363
  prefix.length === 1 &&
17273
- ['run.created', 'run.started', 'run.events'].includes(first.event_type)
17364
+ RUN_SCHEDULER_OUTBOX_PREFIX_STOP_EVENT_TYPES.includes(first.event_type)
17274
17365
  ) {
17275
17366
  break;
17276
17367
  }
@@ -17297,7 +17388,7 @@ function runLedgerPositionSql(alias: string): string {
17297
17388
  }
17298
17389
 
17299
17390
  function runLedgerOrderSql(alias: string): string {
17300
- return `CASE ${alias}.event_type WHEN 'run.created' THEN 0 WHEN 'run.started' THEN 1 ELSE 2 END, ${alias}.created_at, ${alias}.event_id`;
17391
+ return `CASE ${alias}.event_type WHEN ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0 WHEN ${RUN_EVENT_KIND_SQL_LITERAL.runStarted} THEN 1 ELSE 2 END, ${alias}.created_at, ${alias}.event_id`;
17301
17392
  }
17302
17393
 
17303
17394
  /**
@@ -17380,7 +17471,7 @@ export async function readPendingPostgresSchedulerOutboxEvents(
17380
17471
  -- commit to first claim while the projector drained continuously).
17381
17472
  ORDER BY
17382
17473
  CASE
17383
- WHEN candidate.event_type = 'run.created' THEN 0
17474
+ WHEN candidate.event_type = ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0
17384
17475
  WHEN candidate.event_id LIKE 'run-terminal:%' THEN 1
17385
17476
  ELSE 2
17386
17477
  END,
@@ -17398,12 +17489,12 @@ export async function readPendingPostgresSchedulerOutboxEvents(
17398
17489
  -- Admission is causally first and must be projected alone. A later
17399
17490
  -- start/terminal append may not leapfrog a delayed queued row.
17400
17491
  AND (
17401
- head.event_type NOT IN ('run.created', 'run.started', 'run.events')
17492
+ head.event_type NOT IN (${RUN_EVENT_KIND_SQL_LITERAL.runCreated}, ${RUN_EVENT_KIND_SQL_LITERAL.runStarted}, ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents})
17402
17493
  OR outbox.event_id = head.event_id
17403
17494
  )
17404
17495
  -- An ingress row already contains a producer's bounded batch. Keep
17405
17496
  -- its receipt stable independently of the recovery caller's limit.
17406
- AND (outbox.event_type <> 'run.events' OR outbox.event_id = head.event_id)
17497
+ AND (outbox.event_type <> ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents} OR outbox.event_id = head.event_id)
17407
17498
  AND coalesce(outbox.next_attempt_at, outbox.created_at) <= now()
17408
17499
  AND (
17409
17500
  $3::text IS NULL
@@ -17433,7 +17524,7 @@ export async function readPendingPostgresSchedulerOutboxEvents(
17433
17524
  : 'true'
17434
17525
  }
17435
17526
  AND terminal_predecessor.event_type IN (
17436
- 'run.completed', 'run.failed', 'run.cancelled'
17527
+ ${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed}, ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled}
17437
17528
  )
17438
17529
  AND ${runLedgerPrecedesSql('terminal_predecessor', 'outbox')}
17439
17530
  )
@@ -17446,7 +17537,7 @@ export async function readPendingPostgresSchedulerOutboxEvents(
17446
17537
  AND predecessor.delivered_at IS NULL
17447
17538
  AND ${runLedgerPrecedesSql('predecessor', 'outbox')}
17448
17539
  AND (
17449
- predecessor.event_type = 'run.events'
17540
+ predecessor.event_type = ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents}
17450
17541
  OR predecessor.failed_at IS NOT NULL
17451
17542
  OR coalesce(predecessor.next_attempt_at, predecessor.created_at) > now()
17452
17543
  OR (
@@ -17465,7 +17556,7 @@ export async function readPendingPostgresSchedulerOutboxEvents(
17465
17556
  SELECT 1
17466
17557
  FROM ${tableName('outbox', options)} AS candidate
17467
17558
  JOIN candidates ON candidates.event_id = candidate.event_id
17468
- WHERE candidate.event_type IN ('run.completed', 'run.failed', 'run.cancelled')
17559
+ WHERE candidate.event_type IN (${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed}, ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled})
17469
17560
  ) AS has_terminal
17470
17561
  ), claimed AS (
17471
17562
  UPDATE ${tableName('outbox', options)} outbox
@@ -17788,11 +17879,11 @@ export async function purgePostgresSchedulerDeliveredOutboxRetentionBatch(
17788
17879
  )
17789
17880
  UPDATE ${tableName('outbox', options)} AS outbox
17790
17881
  SET payload_json = CASE
17791
- WHEN outbox.event_type = 'run.events' THEN jsonb_set(
17882
+ WHEN outbox.event_type = ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents} THEN jsonb_set(
17792
17883
  outbox.payload_json,
17793
17884
  '{events}',
17794
17885
  (SELECT jsonb_agg(
17795
- CASE WHEN item.value->>'type' = 'log.appended'
17886
+ CASE WHEN item.value->>'type' = ${RUN_EVENT_KIND_SQL_LITERAL.logAppended}
17796
17887
  THEN item.value - 'lines' - 'lineContexts'
17797
17888
  ELSE item.value
17798
17889
  END ORDER BY item.ordinality
@@ -17809,7 +17900,7 @@ export async function purgePostgresSchedulerDeliveredOutboxRetentionBatch(
17809
17900
  outbox.payload_json - 'terminalLogLines' - 'terminalLogContexts',
17810
17901
  '{terminalProgressEvents}',
17811
17902
  coalesce((SELECT jsonb_agg(
17812
- CASE WHEN item.value->>'type' = 'log.appended'
17903
+ CASE WHEN item.value->>'type' = ${RUN_EVENT_KIND_SQL_LITERAL.logAppended}
17813
17904
  THEN item.value - 'lines' - 'lineContexts'
17814
17905
  ELSE item.value
17815
17906
  END ORDER BY item.ordinality
@@ -18164,7 +18255,10 @@ export async function releasePostgresSchedulerOutboxLease(
18164
18255
  function normalizeOutboxIngressPreview(
18165
18256
  event: PlayRunLedgerIngressEvent,
18166
18257
  ): PlayRunLedgerIngressEvent {
18167
- if (event.type !== 'step.progress' && event.key !== 'step.progress') {
18258
+ if (
18259
+ event.type !== RUN_EVENT_KIND.stepProgress &&
18260
+ event.key !== RUN_EVENT_KIND.stepProgress
18261
+ ) {
18168
18262
  return event;
18169
18263
  }
18170
18264
  const progress = recordPayload(event.progress);
@@ -18180,7 +18274,7 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18180
18274
  event: PostgresSchedulerOutboxEvent,
18181
18275
  ): PlayRunLedgerIngressEvent[] {
18182
18276
  const occurredAt = event.createdAt.getTime();
18183
- if (event.eventType === 'run.events') {
18277
+ if (event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runEvents) {
18184
18278
  const events = payloadField(event.payload, 'events');
18185
18279
  const logsStored =
18186
18280
  payloadField(event.payload, 'logBodyStore') === 'planet_scale';
@@ -18208,10 +18302,10 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18208
18302
  normalizeOutboxIngressPreview,
18209
18303
  );
18210
18304
  }
18211
- if (event.eventType === 'run.started') {
18305
+ if (event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runStarted) {
18212
18306
  return [
18213
18307
  {
18214
- type: 'run.started',
18308
+ type: RUN_EVENT_KIND.runStarted,
18215
18309
  runId: event.runId,
18216
18310
  occurredAt,
18217
18311
  source: 'system',
@@ -18220,7 +18314,7 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18220
18314
  },
18221
18315
  ];
18222
18316
  }
18223
- if (event.eventType === 'run.completed') {
18317
+ if (event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCompleted) {
18224
18318
  const terminalWorkCounterSegment =
18225
18319
  normalizePlayRunLedgerTerminalWorkCounterSegment(
18226
18320
  payloadField(event.payload, 'terminalWorkCounterSegment'),
@@ -18239,7 +18333,7 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18239
18333
  ? []
18240
18334
  : [
18241
18335
  {
18242
- type: 'log.appended',
18336
+ type: RUN_EVENT_KIND.logAppended,
18243
18337
  runId: event.runId,
18244
18338
  occurredAt,
18245
18339
  source: 'worker',
@@ -18248,7 +18342,7 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18248
18342
  } as PlayRunLedgerEvent,
18249
18343
  ]),
18250
18344
  {
18251
- type: 'run.completed',
18345
+ type: RUN_EVENT_KIND.runCompleted,
18252
18346
  runId: event.runId,
18253
18347
  occurredAt,
18254
18348
  source: 'system',
@@ -18262,7 +18356,7 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18262
18356
  },
18263
18357
  ];
18264
18358
  }
18265
- if (event.eventType === 'run.failed') {
18359
+ if (event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runFailed) {
18266
18360
  const terminalWorkCounterSegment =
18267
18361
  normalizePlayRunLedgerTerminalWorkCounterSegment(
18268
18362
  payloadField(event.payload, 'terminalWorkCounterSegment'),
@@ -18284,7 +18378,7 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18284
18378
  ? []
18285
18379
  : [
18286
18380
  {
18287
- type: 'log.appended',
18381
+ type: RUN_EVENT_KIND.logAppended,
18288
18382
  runId: event.runId,
18289
18383
  occurredAt,
18290
18384
  source: 'worker',
@@ -18293,7 +18387,7 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18293
18387
  } as PlayRunLedgerEvent,
18294
18388
  ]),
18295
18389
  {
18296
- type: 'run.failed',
18390
+ type: RUN_EVENT_KIND.runFailed,
18297
18391
  runId: event.runId,
18298
18392
  occurredAt,
18299
18393
  source: 'system',
@@ -18306,10 +18400,10 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18306
18400
  },
18307
18401
  ];
18308
18402
  }
18309
- if (event.eventType === 'run.cancelled') {
18403
+ if (event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCancelled) {
18310
18404
  return [
18311
18405
  {
18312
- type: 'run.cancelled',
18406
+ type: RUN_EVENT_KIND.runCancelled,
18313
18407
  runId: event.runId,
18314
18408
  occurredAt,
18315
18409
  source: 'system',
@@ -18317,7 +18411,10 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18317
18411
  } as PlayRunLedgerEvent,
18318
18412
  ];
18319
18413
  }
18320
- if (event.eventType === 'run.waiting' || event.eventType === 'run.resumed') {
18414
+ if (
18415
+ event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaiting ||
18416
+ event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runResumed
18417
+ ) {
18321
18418
  const waitKind = stringPayloadField(event.payload, 'kind');
18322
18419
  // A detached runner is still actively executing in a managed sandbox.
18323
18420
  // The scheduler parks its worker claim as an internal transport detail;
@@ -18331,10 +18428,12 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18331
18428
  runId: event.runId,
18332
18429
  occurredAt,
18333
18430
  source: 'system',
18334
- ...(event.eventType === 'run.waiting' && waitKind !== null
18431
+ ...(event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaiting &&
18432
+ waitKind !== null
18335
18433
  ? { waitKind }
18336
18434
  : {}),
18337
- ...(event.eventType === 'run.waiting' && waitUntil !== null
18435
+ ...(event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaiting &&
18436
+ waitUntil !== null
18338
18437
  ? { waitUntil }
18339
18438
  : {}),
18340
18439
  } as PlayRunLedgerEvent;
@@ -18353,13 +18452,13 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18353
18452
  if (waitKind !== null && !eventKey) return [lifecycle];
18354
18453
  const renderedEventKey = eventKey ?? 'event';
18355
18454
  const line =
18356
- event.eventType === 'run.waiting'
18455
+ event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaiting
18357
18456
  ? `Waiting for integration_event:${renderedEventKey}.`
18358
18457
  : `Resumed integration_event:${renderedEventKey}.`;
18359
18458
  return [
18360
18459
  lifecycle,
18361
18460
  {
18362
- type: 'log.appended',
18461
+ type: RUN_EVENT_KIND.logAppended,
18363
18462
  runId: event.runId,
18364
18463
  occurredAt,
18365
18464
  source: 'system',
@@ -18367,11 +18466,11 @@ export function buildRunLedgerEventsFromPostgresSchedulerOutbox(
18367
18466
  } as PlayRunLedgerEvent,
18368
18467
  ];
18369
18468
  }
18370
- if (event.eventType === 'run.wait_timeout') {
18469
+ if (event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaitTimeout) {
18371
18470
  const eventKey = stringPayloadField(event.payload, 'eventKey') ?? 'event';
18372
18471
  return [
18373
18472
  {
18374
- type: 'log.appended',
18473
+ type: RUN_EVENT_KIND.logAppended,
18375
18474
  runId: event.runId,
18376
18475
  occurredAt,
18377
18476
  source: 'system',
@@ -18409,15 +18508,15 @@ export type PostgresSchedulerOutboxMaterializationPlan = {
18409
18508
  failureCode: string | null;
18410
18509
  };
18411
18510
 
18412
- const RUN_LEDGER_KNOWN_OUTBOX_EVENT_TYPES = new Set([
18413
- 'run.events',
18414
- 'run.started',
18415
- 'run.completed',
18416
- 'run.failed',
18417
- 'run.cancelled',
18418
- 'run.waiting',
18419
- 'run.resumed',
18420
- 'run.wait_timeout',
18511
+ const RUN_LEDGER_KNOWN_OUTBOX_EVENT_TYPES: ReadonlySet<string> = new Set([
18512
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runEvents,
18513
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runStarted,
18514
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCompleted,
18515
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runFailed,
18516
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCancelled,
18517
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaiting,
18518
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runResumed,
18519
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaitTimeout,
18421
18520
  ]);
18422
18521
 
18423
18522
  /**
@@ -18435,7 +18534,8 @@ export function planPostgresSchedulerOutboxMaterialization(
18435
18534
  const projected = buildRunLedgerEventsFromPostgresSchedulerOutbox(event);
18436
18535
  const terminalRef = projected.some(
18437
18536
  (candidate) =>
18438
- (candidate.type === 'run.completed' || candidate.type === 'run.failed') &&
18537
+ (candidate.type === RUN_EVENT_KIND.runCompleted ||
18538
+ candidate.type === RUN_EVENT_KIND.runFailed) &&
18439
18539
  isLedgerTerminalResultRef(candidate.result),
18440
18540
  );
18441
18541
  const delivery = terminalRef
@@ -18894,7 +18994,7 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
18894
18994
  input.headPriority === 'oldest_ready'
18895
18995
  ? ''
18896
18996
  : `CASE
18897
- WHEN head.event_type = 'run.created' THEN 0
18997
+ WHEN head.event_type = ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0
18898
18998
  WHEN head.event_id LIKE 'run-terminal:%' THEN 1
18899
18999
  ELSE 2
18900
19000
  END,`
@@ -19007,9 +19107,9 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
19007
19107
  // A pending start is always claimed alone because later events require its
19008
19108
  // snapshot. It cannot share the append endpoint, so retain that mutation
19009
19109
  // as its own exact delivery.
19010
- if (first.eventType === 'run.created') {
19110
+ if (first.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCreated) {
19011
19111
  await projectPostgresSchedulerCreatedEvent(runtimeApi, first);
19012
- } else if (first.eventType === 'run.started') {
19112
+ } else if (first.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runStarted) {
19013
19113
  const leaseOwner = first.leaseOwner;
19014
19114
  const launch = leaseOwner
19015
19115
  ? await withClient((client) =>
@@ -19033,9 +19133,7 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
19033
19133
  const terminal = [...events]
19034
19134
  .reverse()
19035
19135
  .find((event) =>
19036
- ['run.completed', 'run.failed', 'run.cancelled'].includes(
19037
- event.eventType,
19038
- ),
19136
+ RUN_SCHEDULER_OUTBOX_TERMINAL_EVENT_TYPES.includes(event.eventType),
19039
19137
  );
19040
19138
  const batchDeliveryKey = createHash('sha256')
19041
19139
  .update(events.map((event) => event.deliveryKey).join('\n'))