deepline 0.3.295 → 0.3.297

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 (87) hide show
  1. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  2. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +108 -35
  3. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +21 -3
  4. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +25 -0
  5. package/dist/cli/auth-DLGUNY3B.js +31 -0
  6. package/dist/cli/{auth-EDTRERZP.mjs → auth-FOHTQKQV.mjs} +4 -4
  7. package/dist/cli/{billing-ELIDPILY.js → billing-NRKIBTKJ.js} +70 -70
  8. package/dist/cli/{billing-EXGXJVAU.mjs → billing-ZY3KZNZD.mjs} +4 -4
  9. package/dist/cli/{chunk-F35VOIQL.js → chunk-34A5RSXF.js} +6 -6
  10. package/dist/cli/{chunk-U3PI7HBM.js → chunk-4NYMO67X.js} +2 -2
  11. package/dist/cli/{chunk-YWNDYCXR.mjs → chunk-AC3SC3AC.mjs} +1 -1
  12. package/dist/cli/{chunk-CFVVCN4A.js → chunk-B52G7BYN.js} +6 -6
  13. package/dist/cli/{chunk-YWWAF7KZ.mjs → chunk-DBZX2IWV.mjs} +2 -2
  14. package/dist/cli/{chunk-WQICC2B3.js → chunk-FHO5PO6Q.js} +6 -6
  15. package/dist/cli/{chunk-5KDKFHZI.js → chunk-FSPE246W.js} +15 -15
  16. package/dist/cli/{chunk-D4AZUZO4.js → chunk-IJGJKU4L.js} +1 -1
  17. package/dist/cli/{chunk-XRK2TZT5.js → chunk-OSUS6K5I.js} +4 -4
  18. package/dist/cli/{chunk-GHRQQPW2.mjs → chunk-PLKA4WFH.mjs} +2 -2
  19. package/dist/cli/{chunk-XL2FO6CW.mjs → chunk-PYXPP7NX.mjs} +1 -1
  20. package/dist/cli/{chunk-2S5Y3TZP.js → chunk-QIJ32UEW.js} +6 -6
  21. package/dist/cli/{chunk-UI37DQE7.mjs → chunk-QPBTAYNK.mjs} +2 -2
  22. package/dist/cli/{chunk-LDWT7RJK.mjs → chunk-R2COLUYE.mjs} +1 -1
  23. package/dist/cli/{chunk-OQYEC4GL.mjs → chunk-R5BISWXF.mjs} +1 -1
  24. package/dist/cli/{chunk-6O5YZOVN.mjs → chunk-SZJM7D7W.mjs} +1 -1
  25. package/dist/cli/{chunk-SVIIIYIQ.js → chunk-V24XJVLX.js} +48 -48
  26. package/dist/cli/{chunk-4NEFYBF7.js → chunk-VIOM5OEQ.js} +57 -57
  27. package/dist/cli/{chunk-YJYPL5OK.mjs → chunk-YCCDPYIV.mjs} +4 -4
  28. package/dist/cli/{chunk-EACVZI6N.mjs → chunk-YFPOHUWQ.mjs} +1 -1
  29. package/dist/cli/{chunk-M2V26OR5.js → chunk-YH2XATMF.js} +26 -26
  30. package/dist/cli/{chunk-MROPCKW2.mjs → chunk-ZXJWXNGA.mjs} +3 -3
  31. package/dist/cli/{client-EEN2IJN2.mjs → client-65MCTEMR.mjs} +3 -3
  32. package/dist/cli/client-QLERARAF.js +20 -0
  33. package/dist/cli/{csv-S5NYRUEX.js → csv-SHCW3IJL.js} +12 -12
  34. package/dist/cli/{csv-BOHBEP2I.mjs → csv-TJWBSMR2.mjs} +3 -3
  35. package/dist/cli/{db-F6PKFOOV.js → db-DN6YHQTC.js} +20 -20
  36. package/dist/cli/{db-CLODWCOB.mjs → db-K7QXXM5C.mjs} +4 -4
  37. package/dist/cli/{executions-5TQAKLJU.js → executions-2POJWTCH.js} +6 -6
  38. package/dist/cli/{executions-MAKW6QOY.mjs → executions-FRQO6SJF.mjs} +4 -4
  39. package/dist/cli/{feedback-XY24TW7H.mjs → feedback-A6232HB5.mjs} +3 -3
  40. package/dist/cli/{feedback-GV4QJFEN.js → feedback-EEYZOH3S.js} +6 -6
  41. package/dist/cli/{git-OZLBD5HH.mjs → git-FRVNZNIA.mjs} +4 -4
  42. package/dist/cli/git-SZHVHZWU.js +23 -0
  43. package/dist/cli/index.js +73 -73
  44. package/dist/cli/index.mjs +30 -30
  45. package/dist/cli/{legacy-noops-LLCGDPQE.js → legacy-noops-NREP3YMQ.js} +7 -7
  46. package/dist/cli/{legacy-noops-TYH3TW2D.mjs → legacy-noops-WEN2VQKS.mjs} +4 -4
  47. package/dist/cli/{monitors-TTD55HMK.mjs → monitors-2F7GLG24.mjs} +4 -4
  48. package/dist/cli/{monitors-CABMB4DW.js → monitors-EHHO4IGT.js} +85 -85
  49. package/dist/cli/{org-SFJ77MWY.mjs → org-JONFO5PV.mjs} +4 -4
  50. package/dist/cli/{org-MSF3RG76.js → org-TTFZKSMD.js} +60 -60
  51. package/dist/cli/{play-OKSFNNO4.js → play-N3JMRLKG.js} +200 -200
  52. package/dist/cli/{play-NXHJSCKL.mjs → play-Y7U2XU2K.mjs} +6 -6
  53. package/dist/cli/{providers-TIIAZEUA.mjs → providers-CWPT5L3U.mjs} +4 -4
  54. package/dist/cli/{providers-QC2ERERL.js → providers-I4V4QCOM.js} +7 -7
  55. package/dist/cli/{quickstart-ICANHLMI.js → quickstart-2DDUIWC5.js} +5 -5
  56. package/dist/cli/{quickstart-KWUOP3FI.mjs → quickstart-UBONJ6EY.mjs} +3 -3
  57. package/dist/cli/{search-U5H2FDOO.mjs → search-BHCCYLF2.mjs} +5 -5
  58. package/dist/cli/{search-XQRQOLWS.js → search-Z72FUFXL.js} +6 -6
  59. package/dist/cli/{secrets-YNMNZNOM.js → secrets-AE22MX42.js} +13 -13
  60. package/dist/cli/{secrets-3J6YTWFA.mjs → secrets-BGD4PNTG.mjs} +4 -4
  61. package/dist/cli/{sessions-J6VR47FG.js → sessions-7SIBBFHF.js} +5 -5
  62. package/dist/cli/{sessions-CLEES4L6.mjs → sessions-JYSG6SUN.mjs} +4 -4
  63. package/dist/cli/{settings-UVLOQZRH.mjs → settings-4XWN4JFT.mjs} +7 -7
  64. package/dist/cli/{settings-EEKZMTY4.js → settings-LCA42CL3.js} +74 -74
  65. package/dist/cli/{setup-HC4Q7QM4.js → setup-NID2M4GQ.js} +41 -41
  66. package/dist/cli/{setup-DLMDXPGJ.mjs → setup-WMOKDWHV.mjs} +6 -6
  67. package/dist/cli/{skills-33PHFBSB.mjs → skills-6IL3LQUJ.mjs} +4 -4
  68. package/dist/cli/skills-AYCZ4UXS.js +28 -0
  69. package/dist/cli/{tools-3COEPKML.mjs → tools-BOIRKQA4.mjs} +5 -5
  70. package/dist/cli/{tools-QXEVCN45.js → tools-TZLX4WAL.js} +50 -50
  71. package/dist/cli/update-EEFUC76J.js +28 -0
  72. package/dist/cli/{update-LSAC4FF5.mjs → update-VF3BB3R7.mjs} +6 -6
  73. package/dist/cli/{workflow-QPZWYSZE.js → workflow-RUTOLKOS.js} +15 -15
  74. package/dist/cli/{workflow-7S44OECF.mjs → workflow-UZKD5KU2.mjs} +5 -5
  75. package/dist/index.js +6 -6
  76. package/dist/index.mjs +3 -3
  77. package/dist/install-integrity.json +68 -68
  78. package/dist/release.d.mts +1 -1
  79. package/dist/release.d.ts +1 -1
  80. package/dist/release.js +2 -2
  81. package/dist/release.mjs +1 -1
  82. package/package.json +1 -1
  83. package/dist/cli/auth-TDHKB277.js +0 -31
  84. package/dist/cli/client-4JVOYVC5.js +0 -20
  85. package/dist/cli/git-6S2C22T5.js +0 -23
  86. package/dist/cli/skills-LFRY3KPX.js +0 -28
  87. package/dist/cli/update-NXHSPYXA.js +0 -28
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
200
200
  // getters keep their established compatibility behavior.
201
201
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
202
202
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
203
- version: '0.3.295',
203
+ version: '0.3.297',
204
204
  updateSummary:
205
205
  'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
206
206
  packageCapabilities: {
@@ -193,6 +193,7 @@ import {
193
193
  readAbsurdSchemaSql,
194
194
  } from './absurd-pool';
195
195
  import {
196
+ isImmutableRuntimeExecutionRecoveryOrigin,
196
197
  runtimeApiBaseUrlFromLaunch,
197
198
  runtimeTokenOriginFromLaunch,
198
199
  } from './runtime-api-origin';
@@ -349,11 +350,15 @@ const POSTGRES_SCHEDULER_SCHEMA_INIT_STATEMENT_TIMEOUT_MS = 60_000;
349
350
  // v58 installs deferred outbox readers while retaining synchronous writers
350
351
  // until the separately operated, reader-first cutover.
351
352
  // v59 adds origin identity bulk projection and independent durable search progress.
352
- export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 59;
353
+ // v60 indexes all sandbox leases by Run, including released custody history.
354
+ // This marker records deployment work, never a runtime schema floor.
355
+ export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 60;
353
356
  const POSTGRES_SCHEDULER_SCHEMA_MIGRATIONS_TABLE =
354
357
  'scheduler_schema_migrations';
355
358
  export const POSTGRES_SCHEDULER_OPEN_RECOVERY_INDEX =
356
359
  'runtime_scheduler_runs_open_recovery_idx';
360
+ export const POSTGRES_SCHEDULER_SANDBOX_CUSTODY_INDEX =
361
+ 'runtime_scheduler_sandbox_capacity_leases_custody_idx';
357
362
  const POSTGRES_SCHEDULER_DEPENDENCY_CIRCUITS_TABLE =
358
363
  'runtime_dependency_circuits';
359
364
  /**
@@ -2693,6 +2698,12 @@ export async function ensurePostgresSchedulerSchema(
2693
2698
  const hasLegacyAdmissionRows =
2694
2699
  legacyAdmissionRows?.rows[0]?.present === true;
2695
2700
  if (schemaCoreIsCurrent) {
2701
+ if (!options?.deferRuntimeAdminIndexes) {
2702
+ await ensurePostgresSchedulerSandboxCustodyIndex(client, {
2703
+ schema,
2704
+ concurrently: false,
2705
+ });
2706
+ }
2696
2707
  await ensurePostgresSchedulerLaunchAdmissionFunctions(client, options);
2697
2708
  if (!schemaIsCurrent) {
2698
2709
  await ensurePostgresSchedulerTerminalComputeBillingOutboxTrigger(
@@ -3163,6 +3174,12 @@ export async function ensurePostgresSchedulerSchema(
3163
3174
  (run_id, provider, sandbox_id)
3164
3175
  WHERE released_at IS NULL
3165
3176
  `);
3177
+ if (!options?.deferRuntimeAdminIndexes) {
3178
+ await client.query(`
3179
+ CREATE INDEX IF NOT EXISTS ${POSTGRES_SCHEDULER_SANDBOX_CUSTODY_INDEX}
3180
+ ON ${tableName('runtime_sandbox_capacity_leases', options)} (run_id, lease_id)
3181
+ `);
3182
+ }
3166
3183
  // Deletion note: runtime outbox producers were removed from the legacy
3167
3184
  // store path, but the table stays in bootstrap while run-read-model/admin
3168
3185
  // callers still import the projector against existing runtime_scheduler
@@ -4122,7 +4139,17 @@ export type PostgresSchedulerIndexState =
4122
4139
  | { kind: 'invalid'; ready: boolean }
4123
4140
  | { kind: 'ready' };
4124
4141
 
4142
+ // Custody locks include released history. The active-resource partial index
4143
+ // cannot serve that read while the transaction owns the Run and attempt locks.
4144
+ // This is a deploy-owned optimization, never a runtime admission prerequisite.
4145
+ const POSTGRES_SCHEDULER_SANDBOX_CUSTODY_INDEX_DEFINITION = {
4146
+ name: POSTGRES_SCHEDULER_SANDBOX_CUSTODY_INDEX,
4147
+ table: 'runtime_sandbox_capacity_leases',
4148
+ definition: '(run_id, lease_id)',
4149
+ } as const;
4150
+
4125
4151
  const POSTGRES_SCHEDULER_RUNTIME_ADMIN_INDEXES = [
4152
+ POSTGRES_SCHEDULER_SANDBOX_CUSTODY_INDEX_DEFINITION,
4126
4153
  {
4127
4154
  name: 'runtime_scheduler_attempts_active_status_created_idx',
4128
4155
  table: 'attempts',
@@ -4337,38 +4364,73 @@ export async function ensurePostgresSchedulerRuntimeAdminIndexesConcurrently(
4337
4364
  client: PostgresSchedulerQueryClient,
4338
4365
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
4339
4366
  ): Promise<void> {
4340
- const schema = schemaName(options);
4341
4367
  for (const index of POSTGRES_SCHEDULER_RUNTIME_ADMIN_INDEXES) {
4342
- const state = await readPostgresSchedulerIndexState(
4343
- client,
4344
- index.name,
4345
- index.table,
4346
- options,
4368
+ await ensurePostgresSchedulerIndex(client, index, options, true);
4369
+ }
4370
+ }
4371
+
4372
+ async function ensurePostgresSchedulerIndex(
4373
+ client: PostgresSchedulerQueryClient,
4374
+ index: { name: string; table: string; definition: string },
4375
+ options: Pick<PostgresSchedulerOptions, 'schema'> | undefined,
4376
+ concurrently: boolean,
4377
+ ): Promise<void> {
4378
+ const schema = schemaName(options);
4379
+ const state = await readPostgresSchedulerIndexState(
4380
+ client,
4381
+ index.name,
4382
+ index.table,
4383
+ options,
4384
+ );
4385
+ if (state.kind === 'ready') return;
4386
+ const mode = concurrently ? 'CONCURRENTLY ' : '';
4387
+ if (state.kind === 'invalid') {
4388
+ await client.query(
4389
+ `DROP INDEX ${mode}IF EXISTS ${quoteIdent(schema)}.${quoteIdent(index.name)}`,
4347
4390
  );
4348
- if (state.kind === 'ready') continue;
4349
- if (state.kind === 'invalid') {
4350
- await client.query(
4351
- `DROP INDEX CONCURRENTLY IF EXISTS ${quoteIdent(schema)}.${quoteIdent(index.name)}`,
4352
- );
4353
- }
4354
- await client.query(`
4355
- CREATE INDEX CONCURRENTLY IF NOT EXISTS ${quoteIdent(index.name)}
4356
- ON ${tableName(index.table, options)} ${index.definition}
4357
- `);
4358
- const installed = await readPostgresSchedulerIndexState(
4359
- client,
4360
- index.name,
4361
- index.table,
4362
- options,
4391
+ }
4392
+ await client.query(`
4393
+ CREATE INDEX ${mode}IF NOT EXISTS ${quoteIdent(index.name)}
4394
+ ON ${tableName(index.table, options)} ${index.definition}
4395
+ `);
4396
+ const installed = await readPostgresSchedulerIndexState(
4397
+ client,
4398
+ index.name,
4399
+ index.table,
4400
+ options,
4401
+ );
4402
+ if (installed.kind !== 'ready') {
4403
+ throw new Error(
4404
+ `Runtime scheduler index ${schema}.${index.name} is not valid and ready after creation.`,
4363
4405
  );
4364
- if (installed.kind !== 'ready') {
4365
- throw new Error(
4366
- `Runtime scheduler index ${schema}.${index.name} is not valid and ready after concurrent creation.`,
4367
- );
4368
- }
4369
4406
  }
4370
4407
  }
4371
4408
 
4409
+ export async function readPostgresSchedulerSandboxCustodyIndexState(
4410
+ client: PostgresSchedulerQueryClient,
4411
+ options?: Pick<PostgresSchedulerOptions, 'schema'>,
4412
+ ): Promise<PostgresSchedulerIndexState> {
4413
+ return readPostgresSchedulerIndexState(
4414
+ client,
4415
+ POSTGRES_SCHEDULER_SANDBOX_CUSTODY_INDEX,
4416
+ 'runtime_sandbox_capacity_leases',
4417
+ options,
4418
+ );
4419
+ }
4420
+
4421
+ /** Shared schemas build concurrently; only quiesced run-scoped schemas opt out. */
4422
+ export async function ensurePostgresSchedulerSandboxCustodyIndex(
4423
+ client: PostgresSchedulerQueryClient,
4424
+ options: Pick<PostgresSchedulerOptions, 'schema'> & { concurrently: boolean },
4425
+ ): Promise<void> {
4426
+ await ensurePostgresSchedulerIndex(
4427
+ client,
4428
+ POSTGRES_SCHEDULER_SANDBOX_CUSTODY_INDEX_DEFINITION,
4429
+ options,
4430
+ options.concurrently,
4431
+ );
4432
+ }
4433
+
4372
4434
  export async function readPostgresSchedulerOpenRecoveryIndexState(
4373
4435
  client: PostgresSchedulerQueryClient,
4374
4436
  options?: Pick<PostgresSchedulerOptions, 'schema'>,
@@ -20976,12 +21038,12 @@ async function loadPostgresSchedulerRuntimeApiForRun(
20976
21038
  );
20977
21039
  }
20978
21040
 
20979
- // Only freshly gateway-issued legacy run.progress authority is reused.
20980
- // Prefix advertisements are reacquired for each drain because they select its
20981
- // receipt shape, including recovery across receiver capability changes. This is not
20982
- // a lease cache: every delivery still claims, renews, and proves its own lease
20983
- // at append. Include the complete pinned authority/routing and internal-token
20984
- // fingerprint so a different run, schema, origin, or authority never shares it.
21041
+ // Reuse only gateway-issued run.progress authority. A prefix advertisement
21042
+ // remains reusable only for the same immutable app build; mutable receivers
21043
+ // must reacquire their current receipt shape on every drain. Every delivery
21044
+ // still claims, renews, and proves its own live lease at append. The complete
21045
+ // authority/routing and internal-token fingerprint isolates each run, schema,
21046
+ // origin, and authority. Cache loss or signer rotation never owns delivery.
20985
21047
  const RUN_LEDGER_DISPATCH_TOKEN_CACHE_MS = 30_000;
20986
21048
  const RUN_LEDGER_DISPATCH_TOKEN_CACHE_ENTRIES = 256;
20987
21049
  const runLedgerDispatchTokens = new Map<
@@ -21025,6 +21087,9 @@ async function requestRunLedgerDispatchToken(
21025
21087
  executorToken: cached.token,
21026
21088
  reused: true,
21027
21089
  cacheKey,
21090
+ ...(cached.runLedgerIngressPrefixBatching
21091
+ ? { runLedgerIngressPrefixBatching: true as const }
21092
+ : {}),
21028
21093
  };
21029
21094
  runLedgerDispatchTokens.delete(cacheKey);
21030
21095
  const url = `${runtimeApiBaseUrlFromLaunch(input.launch).replace(/\/$/, '')}/api/v2/internal/play-runtime/run-ledger-dispatch-token`;
@@ -21096,6 +21161,11 @@ async function requestRunLedgerDispatchToken(
21096
21161
  : 'invalid response',
21097
21162
  });
21098
21163
  }
21164
+ const reusablePrefix =
21165
+ body.runLedgerIngressPrefixBatching === true &&
21166
+ isImmutableRuntimeExecutionRecoveryOrigin(
21167
+ runtimeApiBaseUrlFromLaunch(input.launch),
21168
+ );
21099
21169
  // Decode only the lifetime, never an authentication decision: the app
21100
21170
  // validates the signature, run scope, and live delivery lease on append.
21101
21171
  // Opaque/older token formats continue to work without this optimization.
@@ -21107,7 +21177,7 @@ async function requestRunLedgerDispatchToken(
21107
21177
  ).toString(),
21108
21178
  ) as { exp?: unknown };
21109
21179
  if (
21110
- body.runLedgerIngressPrefixBatching === undefined &&
21180
+ (body.runLedgerIngressPrefixBatching === undefined || reusablePrefix) &&
21111
21181
  typeof claims.exp === 'number' &&
21112
21182
  Number.isFinite(claims.exp)
21113
21183
  ) {
@@ -21119,6 +21189,9 @@ async function requestRunLedgerDispatchToken(
21119
21189
  runLedgerDispatchTokens.set(cacheKey, {
21120
21190
  token: body.executorToken,
21121
21191
  expiresAt,
21192
+ ...(reusablePrefix
21193
+ ? { runLedgerIngressPrefixBatching: true as const }
21194
+ : {}),
21122
21195
  });
21123
21196
  while (
21124
21197
  runLedgerDispatchTokens.size > RUN_LEDGER_DISPATCH_TOKEN_CACHE_ENTRIES
@@ -21132,7 +21205,7 @@ async function requestRunLedgerDispatchToken(
21132
21205
  } catch {
21133
21206
  // A cache miss never changes delivery or hides a gateway rejection.
21134
21207
  }
21135
- if (body.runLedgerIngressPrefixBatching !== undefined) {
21208
+ if (body.runLedgerIngressPrefixBatching !== undefined && !reusablePrefix) {
21136
21209
  runLedgerDispatchTokens.delete(cacheKey);
21137
21210
  }
21138
21211
  return {
@@ -8,6 +8,7 @@
8
8
  * as a wake hint, and one exact timer for the next due row. There is
9
9
  * deliberately no worker fleet polling cadence.
10
10
  */
11
+ import { isIsolatedRuntimeSchedulerSchema } from '../runtime-scheduler-topology';
11
12
  import {
12
13
  dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope,
13
14
  postgresSchedulerNotifyChannel,
@@ -36,7 +37,17 @@ const RECOVERY_FAILURE_RETRY_MAX_MS = 60_000;
36
37
  // seconds of worker deferrals. Only the dedicated projector performs this
37
38
  // fallback; the worker fleet still never polls the outbox.
38
39
  export const NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS = 1_000;
40
+ /** Isolated Preview/dev schemas have no LISTEN session, so halve discovery latency. */
41
+ export const ISOLATED_NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS = 500;
39
42
  const MAX_TIMEOUT_MS = 2_147_483_647;
43
+
44
+ export function runLedgerOutboxNotifySafetyWakeMs(
45
+ schedulerSchema: string | null | undefined,
46
+ ): number {
47
+ return isIsolatedRuntimeSchedulerSchema(schedulerSchema)
48
+ ? ISOLATED_NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS
49
+ : NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS;
50
+ }
40
51
  /**
41
52
  * One projector can keep this many independent Run Ledger deliveries in
42
53
  * flight after it has found durable work. Each delivery owns only short
@@ -84,6 +95,8 @@ export type RunLedgerOutboxRecoveryDeps = {
84
95
  acquireNotifyHub: () => PgNotifyHubLease | null;
85
96
  /** Bounded number of independent runs this replica may deliver at once. */
86
97
  parallelism?: number;
98
+ /** Fast polling is used only when the topology intentionally has no LISTEN session. */
99
+ notifyUnavailableSafetyWakeMs?: number;
87
100
  now?: () => number;
88
101
  setTimer?: (callback: () => void, delayMs: number) => RecoveryTimer;
89
102
  clearTimer?: (timer: RecoveryTimer) => void;
@@ -135,6 +148,8 @@ export function startRunLedgerOutboxRecovery(
135
148
  const clearTimer = deps.clearTimer ?? clearTimeout;
136
149
  const logger = deps.logger ?? console;
137
150
  const requestedParallelism = Math.floor(deps.parallelism ?? 1);
151
+ const notifyUnavailableSafetyWakeMs =
152
+ deps.notifyUnavailableSafetyWakeMs ?? NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS;
138
153
  const parallelism = Number.isFinite(requestedParallelism)
139
154
  ? Math.max(
140
155
  1,
@@ -240,13 +255,13 @@ export function startRunLedgerOutboxRecovery(
240
255
  failureCount += 1;
241
256
  // A rejected pooled query is normally worth exponential backoff. The
242
257
  // exception is an unavailable LISTEN session: this dedicated projector is
243
- // the one durable poller, and its one-second safety wake is what keeps
258
+ // the one durable poller, and its topology-specific safety wake keeps
244
259
  // `run.created` delivery live while a direct PostgreSQL connection is
245
260
  // refused (for example, during a connection-capacity spike). Do not let a
246
261
  // process-local exponential cooldown silently disable that fallback.
247
262
  const delayMs = listenerIsAvailable()
248
263
  ? boundedFailureDelayMs(failureCount)
249
- : NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS;
264
+ : notifyUnavailableSafetyWakeMs;
250
265
  logger.warn('[run-ledger-outbox.recovery_retry]', {
251
266
  stage,
252
267
  delayMs,
@@ -281,7 +296,7 @@ export function startRunLedgerOutboxRecovery(
281
296
  const exactDueMs = dueAt ? Math.max(0, dueAt.getTime() - now()) : null;
282
297
  const delayMs = listenerIsAvailable()
283
298
  ? exactDueMs
284
- : Math.min(exactDueMs ?? Infinity, NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS);
299
+ : Math.min(exactDueMs ?? Infinity, notifyUnavailableSafetyWakeMs);
285
300
  if (delayMs === null || !Number.isFinite(delayMs)) return;
286
301
  clearWakeTimer();
287
302
  timer = setTimer(
@@ -631,6 +646,9 @@ export function startRunLedgerOutboxRecoveryController(input: {
631
646
  // replicas therefore drain up to sixteen independent runs concurrently
632
647
  // without turning one outbox notification into sixty-four head scans.
633
648
  parallelism: RUN_LEDGER_OUTBOX_RECOVERY_PRODUCTION_IN_FLIGHT,
649
+ notifyUnavailableSafetyWakeMs: runLedgerOutboxNotifySafetyWakeMs(
650
+ schedulerOptions.schema,
651
+ ),
634
652
  readNextDueAt: () =>
635
653
  withRuntimeSchedulerClient(input.poolOptions, (client) =>
636
654
  readPostgresSchedulerOutboxNextDueAt(client, schedulerOptions),
@@ -1,5 +1,30 @@
1
1
  import type { PlaySchedulerSubmitInput } from '../scheduler-backend';
2
2
 
3
+ const RUNTIME_EXECUTION_RECOVERY_DEPLOYMENT_HOST_RE =
4
+ /^deepline(?:-api-[a-z0-9]+|-(?!api-)[a-z0-9]+)-aero-team-0f650658\.vercel\.app$/;
5
+
6
+ /** A recovery reader must remain on one immutable, Deepline-owned app build. */
7
+ export function isImmutableRuntimeExecutionRecoveryOrigin(
8
+ origin: string,
9
+ ): boolean {
10
+ try {
11
+ const url = new URL(origin);
12
+ return (
13
+ url.origin === origin &&
14
+ url.protocol === 'https:' &&
15
+ url.username === '' &&
16
+ url.password === '' &&
17
+ url.port === '' &&
18
+ url.pathname === '/' &&
19
+ url.search === '' &&
20
+ url.hash === '' &&
21
+ RUNTIME_EXECUTION_RECOVERY_DEPLOYMENT_HOST_RE.test(url.hostname)
22
+ );
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+
3
28
  /**
4
29
  * Resolve the app origin used for authenticated runtime API calls.
5
30
  *
@@ -0,0 +1,31 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+ var _chunkV24XJVLXjs = require('./chunk-V24XJVLX.js');
13
+ require('./chunk-34A5RSXF.js');
14
+ require('./chunk-OSUS6K5I.js');
15
+ require('./chunk-XNYIZMNQ.js');
16
+ require('./chunk-IJGJKU4L.js');
17
+ require('./chunk-7P5AA3SN.js');
18
+ require('./chunk-OG64RBAC.js');
19
+ require('./chunk-COGTRVWW.js');
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+ exports.EXIT_WORKSPACE_MISMATCH = _chunkV24XJVLXjs.EXIT_WORKSPACE_MISMATCH; exports.clearPendingClaim = _chunkV24XJVLXjs.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunkV24XJVLXjs.clearSatisfiedPendingClaim; exports.handleRegister = _chunkV24XJVLXjs.handleRegister; exports.handleStatus = _chunkV24XJVLXjs.handleStatus; exports.handleWait = _chunkV24XJVLXjs.handleWait; exports.readPendingAuthClaim = _chunkV24XJVLXjs.readPendingAuthClaim; exports.registerAuthCommands = _chunkV24XJVLXjs.registerAuthCommands; exports.reportSetupCompleted = _chunkV24XJVLXjs.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunkV24XJVLXjs.resolvePendingAuthClaimForResume;
@@ -9,11 +9,11 @@ import {
9
9
  registerAuthCommands,
10
10
  reportSetupCompleted,
11
11
  resolvePendingAuthClaimForResume
12
- } from "./chunk-YWWAF7KZ.mjs";
13
- import "./chunk-6O5YZOVN.mjs";
14
- import "./chunk-EACVZI6N.mjs";
12
+ } from "./chunk-DBZX2IWV.mjs";
13
+ import "./chunk-SZJM7D7W.mjs";
14
+ import "./chunk-YFPOHUWQ.mjs";
15
15
  import "./chunk-DLIRSHV6.mjs";
16
- import "./chunk-LDWT7RJK.mjs";
16
+ import "./chunk-R2COLUYE.mjs";
17
17
  import "./chunk-NXGCO4JB.mjs";
18
18
  import "./chunk-WZYKRD7T.mjs";
19
19
  import "./chunk-KRD6H754.mjs";