deepline 0.3.296 → 0.3.298

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 (90) hide show
  1. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  2. package/dist/bundling-sources/shared_libs/monitors/quickstart-prompts.ts +15 -0
  3. package/dist/bundling-sources/shared_libs/monitors/starter-templates.ts +9 -98
  4. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +3 -1
  5. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +80 -33
  6. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +136 -62
  7. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +15 -3
  8. package/dist/cli/auth-AQCORSG5.js +31 -0
  9. package/dist/cli/{auth-JCGIDVDF.mjs → auth-TJGQB4RK.mjs} +4 -4
  10. package/dist/cli/{billing-OQBSIXRG.mjs → billing-BUHGVESC.mjs} +4 -4
  11. package/dist/cli/{billing-YBK3J4WP.js → billing-HSBXETYG.js} +70 -70
  12. package/dist/cli/{chunk-6HPEDBSJ.js → chunk-2Q4LGPVP.js} +4 -4
  13. package/dist/cli/{chunk-A7427JJH.js → chunk-4TOJTO4S.js} +6 -6
  14. package/dist/cli/{chunk-QSIO4TX2.mjs → chunk-6IOQ43VG.mjs} +1 -1
  15. package/dist/cli/{chunk-2C3AVPTY.js → chunk-7ZA3OMYT.js} +6 -6
  16. package/dist/cli/{chunk-AQRTLPHZ.js → chunk-B5R4IGNU.js} +6 -6
  17. package/dist/cli/{chunk-LIKFCE7Z.js → chunk-BUKTFUM7.js} +1 -1
  18. package/dist/cli/{chunk-ZDOC4HFL.js → chunk-BXYKLY5T.js} +48 -48
  19. package/dist/cli/{chunk-4ZB3CJRD.js → chunk-CVNG2LB7.js} +15 -15
  20. package/dist/cli/{chunk-J2D3VDOU.mjs → chunk-FJTNI2TE.mjs} +1 -1
  21. package/dist/cli/{chunk-DYWHXO7O.mjs → chunk-FT4JXVAD.mjs} +1 -1
  22. package/dist/cli/{chunk-2MZ5EQZE.mjs → chunk-IZKS7OGL.mjs} +2 -2
  23. package/dist/cli/{chunk-GLKUGBTP.mjs → chunk-MJWD6SJR.mjs} +3 -3
  24. package/dist/cli/{chunk-4Y6CG4GE.js → chunk-NHNFNVLD.js} +58 -58
  25. package/dist/cli/{chunk-UC6GHEL4.js → chunk-OXCFNXS5.js} +26 -26
  26. package/dist/cli/{chunk-BZ77OTRF.mjs → chunk-RES6RQXX.mjs} +2 -2
  27. package/dist/cli/{chunk-G46HHFNB.mjs → chunk-S5CEMBUJ.mjs} +4 -4
  28. package/dist/cli/{chunk-7D6QG5KF.js → chunk-TOAXEXTC.js} +6 -6
  29. package/dist/cli/{chunk-NTEZFZLE.mjs → chunk-U6G52KUV.mjs} +1 -1
  30. package/dist/cli/{chunk-RCUE5C5C.mjs → chunk-XZNFOO5U.mjs} +1 -1
  31. package/dist/cli/{chunk-NPPJX3BL.mjs → chunk-YE5PJMFK.mjs} +1 -1
  32. package/dist/cli/{chunk-7UAO5MWV.mjs → chunk-YFNB2GPD.mjs} +3 -3
  33. package/dist/cli/{chunk-L4HBNHFW.js → chunk-YJX7FY4F.js} +2 -2
  34. package/dist/cli/{client-CZDA4JKO.mjs → client-2TV2OKUH.mjs} +3 -3
  35. package/dist/cli/client-QKZ6CTWN.js +20 -0
  36. package/dist/cli/{csv-6KOMZA2H.mjs → csv-7XFZ333H.mjs} +3 -3
  37. package/dist/cli/{csv-UTEQY3NA.js → csv-N2CI4OLO.js} +12 -12
  38. package/dist/cli/{db-D5EP6TKO.mjs → db-R37F3UHM.mjs} +4 -4
  39. package/dist/cli/{db-SIBLPIKC.js → db-UXTCDLUO.js} +20 -20
  40. package/dist/cli/{executions-2PHT57IO.js → executions-AVGJESD2.js} +6 -6
  41. package/dist/cli/{executions-DFWM2YYY.mjs → executions-SQ3CYCNF.mjs} +4 -4
  42. package/dist/cli/{feedback-IQVWIJZ4.js → feedback-DY5GZCHY.js} +6 -6
  43. package/dist/cli/{feedback-GZW37JMI.mjs → feedback-VRUQVLR2.mjs} +3 -3
  44. package/dist/cli/git-72HXNB6W.js +23 -0
  45. package/dist/cli/{git-B72Y4FFQ.mjs → git-YCT5WDUM.mjs} +4 -4
  46. package/dist/cli/index.js +73 -73
  47. package/dist/cli/index.mjs +30 -30
  48. package/dist/cli/{legacy-noops-IFGVDCOM.js → legacy-noops-EC6NUDQG.js} +7 -7
  49. package/dist/cli/{legacy-noops-37F5MX2P.mjs → legacy-noops-TPKXHLEJ.mjs} +4 -4
  50. package/dist/cli/{monitors-42H6LOVT.mjs → monitors-BVIPCPTM.mjs} +4 -4
  51. package/dist/cli/{monitors-GQCHXBXZ.js → monitors-RAJW7CTX.js} +85 -85
  52. package/dist/cli/{org-4GCPBTGR.js → org-CYBSXWOL.js} +60 -60
  53. package/dist/cli/{org-JYZA3ZRJ.mjs → org-FQ6DJMPU.mjs} +4 -4
  54. package/dist/cli/{play-Q2XV3FZZ.mjs → play-5KQLW4UV.mjs} +6 -6
  55. package/dist/cli/{play-46ZJ4FMI.js → play-W5UAFX62.js} +200 -200
  56. package/dist/cli/{providers-PCNF5E3K.js → providers-2YN7WGZW.js} +7 -7
  57. package/dist/cli/{providers-CTKQP45X.mjs → providers-NPP7DKNJ.mjs} +4 -4
  58. package/dist/cli/{quickstart-FTHWRVWN.js → quickstart-F3UEWVYN.js} +5 -5
  59. package/dist/cli/{quickstart-X7EVVWRG.mjs → quickstart-NRCBIY5D.mjs} +3 -3
  60. package/dist/cli/{search-73YPOFDO.mjs → search-3HZ7PFXE.mjs} +5 -5
  61. package/dist/cli/{search-XA5UVC3G.js → search-HOHTWO7A.js} +6 -6
  62. package/dist/cli/{secrets-OUMPT4FX.mjs → secrets-44DTR7F7.mjs} +4 -4
  63. package/dist/cli/{secrets-UOEVR73Q.js → secrets-ROFLUSZW.js} +13 -13
  64. package/dist/cli/{sessions-CMKXCN5Y.js → sessions-U7T5MEHM.js} +5 -5
  65. package/dist/cli/{sessions-ZIFGDZE7.mjs → sessions-ZGKRSQ7U.mjs} +4 -4
  66. package/dist/cli/{settings-ULZT2NIC.js → settings-SAFOFNX3.js} +74 -74
  67. package/dist/cli/{settings-OO5R3G52.mjs → settings-WDAIAP72.mjs} +7 -7
  68. package/dist/cli/{setup-DHGERXPZ.js → setup-SO5Y5PPR.js} +41 -41
  69. package/dist/cli/{setup-6GZH52OZ.mjs → setup-VZWFB35G.mjs} +6 -6
  70. package/dist/cli/skills-PVOBZRLZ.js +28 -0
  71. package/dist/cli/{skills-T3EY2656.mjs → skills-YUNBWLQ2.mjs} +4 -4
  72. package/dist/cli/{tools-BIMOAOTX.mjs → tools-HSBS6CL6.mjs} +5 -5
  73. package/dist/cli/{tools-ODXVCKO7.js → tools-HYYND5GY.js} +50 -50
  74. package/dist/cli/update-KTAZKIHP.js +28 -0
  75. package/dist/cli/{update-X4HX7Z3M.mjs → update-MENMYHFK.mjs} +6 -6
  76. package/dist/cli/{workflow-IVLCPFTG.js → workflow-JZIB3YKI.js} +15 -15
  77. package/dist/cli/{workflow-EAUFVPIP.mjs → workflow-TWGYS6II.mjs} +5 -5
  78. package/dist/index.js +6 -6
  79. package/dist/index.mjs +3 -3
  80. package/dist/install-integrity.json +68 -68
  81. package/dist/release.d.mts +1 -1
  82. package/dist/release.d.ts +1 -1
  83. package/dist/release.js +2 -2
  84. package/dist/release.mjs +1 -1
  85. package/package.json +1 -1
  86. package/dist/cli/auth-QDWV3TXX.js +0 -31
  87. package/dist/cli/client-IZGIN2ZA.js +0 -20
  88. package/dist/cli/git-563GYLMA.js +0 -23
  89. package/dist/cli/skills-Q7NUCS2W.js +0 -28
  90. package/dist/cli/update-UMB3ULBR.js +0 -28
@@ -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
@@ -63,6 +74,7 @@ export const RUN_LEDGER_OUTBOX_RECOVERY_MAX_IN_FLIGHT = 32;
63
74
  // The higher exported ceiling remains available to isolated recovery callers,
64
75
  // but it is not the steady-state production setting.
65
76
  const RUN_LEDGER_OUTBOX_RECOVERY_PRODUCTION_IN_FLIGHT = 8;
77
+ const RUN_LEDGER_OUTBOX_RECOVERY_INDEX_IN_FLIGHT = 4;
66
78
  // Admissions retain three of four claim opportunities. The fourth selects
67
79
  // the oldest eligible causal head across all runs, preventing terminal work
68
80
  // from starving behind continuous new admissions. An empty class never costs
@@ -78,12 +90,17 @@ export type RunLedgerOutboxRecoveryDeps = {
78
90
  dispatchOnce: (
79
91
  headPriority: RunLedgerOutboxHeadPriority,
80
92
  ) => Promise<PostgresSchedulerOutboxProjectionResult>;
93
+ /** Independent index deliveries share this controller and notification source. */
94
+ dispatchObservabilityOnce?: () => Promise<PostgresSchedulerOutboxProjectionResult>;
95
+ observabilityParallelism?: number;
81
96
  /** Earliest pending retry time or active lease expiry in the durable outbox. */
82
97
  readNextDueAt: () => Promise<Date | null>;
83
98
  /** A direct LISTEN connection. It is a hint only; a null lease is safe. */
84
99
  acquireNotifyHub: () => PgNotifyHubLease | null;
85
100
  /** Bounded number of independent runs this replica may deliver at once. */
86
101
  parallelism?: number;
102
+ /** Fast polling is used only when the topology intentionally has no LISTEN session. */
103
+ notifyUnavailableSafetyWakeMs?: number;
87
104
  now?: () => number;
88
105
  setTimer?: (callback: () => void, delayMs: number) => RecoveryTimer;
89
106
  clearTimer?: (timer: RecoveryTimer) => void;
@@ -135,6 +152,8 @@ export function startRunLedgerOutboxRecovery(
135
152
  const clearTimer = deps.clearTimer ?? clearTimeout;
136
153
  const logger = deps.logger ?? console;
137
154
  const requestedParallelism = Math.floor(deps.parallelism ?? 1);
155
+ const notifyUnavailableSafetyWakeMs =
156
+ deps.notifyUnavailableSafetyWakeMs ?? NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS;
138
157
  const parallelism = Number.isFinite(requestedParallelism)
139
158
  ? Math.max(
140
159
  1,
@@ -144,6 +163,22 @@ export function startRunLedgerOutboxRecovery(
144
163
  ),
145
164
  )
146
165
  : 1;
166
+ if (deps.dispatchObservabilityOnce && parallelism < 2) {
167
+ throw new Error(
168
+ 'Independent observability delivery requires at least two slots.',
169
+ );
170
+ }
171
+ const observabilityParallelism = deps.dispatchObservabilityOnce
172
+ ? Math.min(
173
+ Math.max(1, deps.observabilityParallelism ?? 1),
174
+ Math.max(1, parallelism - 1),
175
+ )
176
+ : 0;
177
+ const lifecycleParallelism = Math.max(
178
+ 1,
179
+ parallelism - observabilityParallelism,
180
+ );
181
+ let observabilityRequested = false;
147
182
  let closed = false;
148
183
  let requested = false;
149
184
  let failureCount = 0;
@@ -159,22 +194,24 @@ export function startRunLedgerOutboxRecovery(
159
194
  let nextDispatchId = 0;
160
195
  let lastDispatchSettledAt: number | null = null;
161
196
  let admissionTurns = 0;
162
- const dispatchOnce =
163
- async (): Promise<PostgresSchedulerOutboxProjectionResult> => {
164
- const oldestReady =
165
- admissionTurns === ADMISSION_TURNS_PER_OLDEST_READY_TURN;
166
- admissionTurns = oldestReady ? 0 : admissionTurns + 1;
167
- const id = nextDispatchId++;
168
- inFlightStartedAt.set(id, now());
169
- try {
170
- return await deps.dispatchOnce(
171
- oldestReady ? 'oldest_ready' : 'admission_first',
172
- );
173
- } finally {
174
- inFlightStartedAt.delete(id);
175
- lastDispatchSettledAt = now();
176
- }
177
- };
197
+ const dispatchOnce = async (
198
+ observability = false,
199
+ ): Promise<PostgresSchedulerOutboxProjectionResult> => {
200
+ const oldestReady =
201
+ admissionTurns === ADMISSION_TURNS_PER_OLDEST_READY_TURN;
202
+ if (!observability) admissionTurns = oldestReady ? 0 : admissionTurns + 1;
203
+ const id = nextDispatchId++;
204
+ inFlightStartedAt.set(id, now());
205
+ try {
206
+ if (observability) return await deps.dispatchObservabilityOnce!();
207
+ return await deps.dispatchOnce(
208
+ oldestReady ? 'oldest_ready' : 'admission_first',
209
+ );
210
+ } finally {
211
+ inFlightStartedAt.delete(id);
212
+ lastDispatchSettledAt = now();
213
+ }
214
+ };
178
215
 
179
216
  const clearWakeTimer = () => {
180
217
  if (!timer) return;
@@ -205,6 +242,7 @@ export function startRunLedgerOutboxRecovery(
205
242
  requestDrain = (reason: string) => {
206
243
  if (closed) return;
207
244
  requested = true;
245
+ observabilityRequested = !!deps.dispatchObservabilityOnce;
208
246
  if (cooldownUntilMs !== null && now() < cooldownUntilMs) return;
209
247
  clearWakeTimer();
210
248
  if (drainPromise) {
@@ -240,13 +278,13 @@ export function startRunLedgerOutboxRecovery(
240
278
  failureCount += 1;
241
279
  // A rejected pooled query is normally worth exponential backoff. The
242
280
  // exception is an unavailable LISTEN session: this dedicated projector is
243
- // the one durable poller, and its one-second safety wake is what keeps
281
+ // the one durable poller, and its topology-specific safety wake keeps
244
282
  // `run.created` delivery live while a direct PostgreSQL connection is
245
283
  // refused (for example, during a connection-capacity spike). Do not let a
246
284
  // process-local exponential cooldown silently disable that fallback.
247
285
  const delayMs = listenerIsAvailable()
248
286
  ? boundedFailureDelayMs(failureCount)
249
- : NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS;
287
+ : notifyUnavailableSafetyWakeMs;
250
288
  logger.warn('[run-ledger-outbox.recovery_retry]', {
251
289
  stage,
252
290
  delayMs,
@@ -281,7 +319,7 @@ export function startRunLedgerOutboxRecovery(
281
319
  const exactDueMs = dueAt ? Math.max(0, dueAt.getTime() - now()) : null;
282
320
  const delayMs = listenerIsAvailable()
283
321
  ? exactDueMs
284
- : Math.min(exactDueMs ?? Infinity, NOTIFY_UNAVAILABLE_SAFETY_WAKE_MS);
322
+ : Math.min(exactDueMs ?? Infinity, notifyUnavailableSafetyWakeMs);
285
323
  if (delayMs === null || !Number.isFinite(delayMs)) return;
286
324
  clearWakeTimer();
287
325
  timer = setTimer(
@@ -298,11 +336,13 @@ export function startRunLedgerOutboxRecovery(
298
336
  const drain = async (reason: string): Promise<void> => {
299
337
  type Delivery = {
300
338
  id: symbol;
339
+ observability: boolean;
301
340
  result:
302
341
  | PromiseSettledResult<PostgresSchedulerOutboxProjectionResult>
303
342
  | { status: 'skipped' };
304
343
  };
305
344
  const pending = new Set<symbol>();
345
+ const pendingObservability = new Set<symbol>();
306
346
  const deliveries: Delivery[] = [];
307
347
  let refill = false;
308
348
  let dispatchFailed = false;
@@ -330,15 +370,16 @@ export function startRunLedgerOutboxRecovery(
330
370
  completed = attempted = projected = retrying = blocked = 0;
331
371
  };
332
372
 
333
- const launch = () => {
373
+ const launch = (observability = false) => {
334
374
  const id = Symbol();
335
375
  pending.add(id);
376
+ if (observability) pendingObservability.add(id);
336
377
  const settle = (result: Delivery['result']) => {
337
378
  if (result.status === 'rejected' && !dispatchFailed) {
338
379
  dispatchFailed = true;
339
380
  scheduleFailureRetry('dispatch', result.reason);
340
381
  }
341
- deliveries.push({ id, result });
382
+ deliveries.push({ id, observability, result });
342
383
  wakeActiveDrain?.();
343
384
  };
344
385
  // Subscribe once per delivery. Repeated Promise.race calls would retain
@@ -349,26 +390,54 @@ export function startRunLedgerOutboxRecovery(
349
390
  return;
350
391
  }
351
392
  try {
352
- settle({ status: 'fulfilled', value: await dispatchOnce() });
393
+ settle({
394
+ status: 'fulfilled',
395
+ value: await dispatchOnce(observability),
396
+ });
353
397
  } catch (reason) {
354
398
  settle({ status: 'rejected', reason });
355
399
  }
356
400
  });
357
401
  };
358
402
 
403
+ const canProbeLifecycle = () =>
404
+ !closed &&
405
+ !dispatchFailed &&
406
+ requested &&
407
+ pending.size < parallelism &&
408
+ pending.size - pendingObservability.size < lifecycleParallelism;
409
+ const canProbeObservability = () =>
410
+ !closed &&
411
+ !dispatchFailed &&
412
+ observabilityRequested &&
413
+ pending.size < parallelism &&
414
+ pendingObservability.size < observabilityParallelism;
415
+
359
416
  for (;;) {
360
417
  if (!closed && !dispatchFailed) {
361
418
  // A wake grants one indexed probe, including when other slots are
362
419
  // still delivering. Keep it pending when full so an empty result
363
420
  // cannot consume a notification that arrived after its query began.
364
- if (requested && pending.size < parallelism) {
421
+ if (canProbeObservability()) {
422
+ observabilityRequested = false;
423
+ while (
424
+ pendingObservability.size < observabilityParallelism &&
425
+ pending.size < parallelism
426
+ )
427
+ launch(true);
428
+ }
429
+ if (canProbeLifecycle()) {
365
430
  requested = false;
366
431
  launch();
367
432
  }
368
433
  // Productive completion permits immediate use of every free slot.
369
434
  // Empty results grant no refill, so idle work cannot spin on scans.
370
435
  if (refill) {
371
- while (pending.size < parallelism) launch();
436
+ while (
437
+ pending.size < parallelism &&
438
+ pending.size - pendingObservability.size < lifecycleParallelism
439
+ )
440
+ launch();
372
441
  refill = false;
373
442
  }
374
443
  }
@@ -383,10 +452,8 @@ export function startRunLedgerOutboxRecovery(
383
452
  wakeActiveDrain = resolve;
384
453
  if (
385
454
  deliveries.length > 0 ||
386
- (requested &&
387
- !closed &&
388
- !dispatchFailed &&
389
- pending.size < parallelism)
455
+ canProbeLifecycle() ||
456
+ canProbeObservability()
390
457
  )
391
458
  resolve();
392
459
  });
@@ -394,6 +461,7 @@ export function startRunLedgerOutboxRecovery(
394
461
  const delivery = deliveries.shift();
395
462
  if (!delivery) continue;
396
463
  pending.delete(delivery.id);
464
+ pendingObservability.delete(delivery.id);
397
465
  if (delivery.result.status !== 'fulfilled') {
398
466
  // Stop new claims but settle every already-started delivery before
399
467
  // cooldown or close can hand ownership to another drain.
@@ -408,7 +476,9 @@ export function startRunLedgerOutboxRecovery(
408
476
  if (completed >= parallelism) reportDeliveries();
409
477
  // Retryable rows own durable retry clocks. The SQL claim keeps their
410
478
  // run ordered while successful slots keep unrelated runs moving.
411
- refill = result.attempted > 0;
479
+ if (delivery.observability) {
480
+ if (result.attempted > 0) observabilityRequested = true;
481
+ } else refill = result.attempted > 0;
412
482
  }
413
483
  };
414
484
 
@@ -583,12 +653,37 @@ export function startRunLedgerOutboxRecoveryController(input: {
583
653
  onDelivered?: (deliveries: readonly RunLedgerOutboxDeliveredRow[]) => void;
584
654
  }): RunLedgerOutboxRecoveryController {
585
655
  const schedulerOptions = input.schedulerOptions ?? {};
586
- let dispatchOrdinal = 0;
587
- let searchInFlight = 0;
588
- const maxSearchInFlight = Math.max(
589
- 1,
590
- Math.floor(RUN_LEDGER_OUTBOX_RECOVERY_PRODUCTION_IN_FLIGHT / 2),
591
- );
656
+ const observabilityPoolOptions: RuntimeSchedulerPoolOptions = {
657
+ ...input.poolOptions,
658
+ purpose: 'observability',
659
+ applicationName: 'deepline-runtime-observability',
660
+ maxClients: RUN_LEDGER_OUTBOX_RECOVERY_INDEX_IN_FLIGHT,
661
+ };
662
+ const dispatch = (
663
+ headPriority: RunLedgerOutboxHeadPriority,
664
+ searchOnly: boolean,
665
+ ) =>
666
+ dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
667
+ (operation) =>
668
+ withRuntimeSchedulerClient(
669
+ searchOnly ? observabilityPoolOptions : input.poolOptions,
670
+ operation,
671
+ ),
672
+ {
673
+ tokenAuthority: 'gateway',
674
+ materializeObservability: true,
675
+ searchOnly,
676
+ withObservabilityClient: (operation) =>
677
+ withRuntimeSchedulerClient(observabilityPoolOptions, operation),
678
+ limit: 8,
679
+ headPriority,
680
+ // The lease holder delivers a run's terminal committed during its
681
+ // append, instead of leaving it for the next wave.
682
+ continueThroughTerminal: true,
683
+ ...(input.onDelivered ? { onDelivered: input.onDelivered } : {}),
684
+ },
685
+ schedulerOptions,
686
+ );
592
687
  return startRunLedgerOutboxRecovery({
593
688
  acquireNotifyHub: () =>
594
689
  input.useDirectNotify === false
@@ -599,38 +694,17 @@ export function startRunLedgerOutboxRecoveryController(input: {
599
694
  schedulerOptions,
600
695
  }),
601
696
  ),
602
- dispatchOnce: async (headPriority) => {
603
- const searchOnly =
604
- dispatchOrdinal++ % 2 === 1 && searchInFlight < maxSearchInFlight;
605
- if (searchOnly) searchInFlight += 1;
606
- try {
607
- return await dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
608
- (operation) =>
609
- withRuntimeSchedulerClient(input.poolOptions, operation),
610
- {
611
- tokenAuthority: 'gateway',
612
- materializeObservability: true,
613
- // One durable controller, with half its capacity reserved for
614
- // lifecycle delivery even when every search operation is blocked.
615
- searchOnly,
616
- limit: 8,
617
- headPriority,
618
- // The lease holder delivers a run's terminal committed during its
619
- // append, instead of leaving it for the next wave.
620
- continueThroughTerminal: true,
621
- ...(input.onDelivered ? { onDelivered: input.onDelivered } : {}),
622
- },
623
- schedulerOptions,
624
- );
625
- } finally {
626
- if (searchOnly) searchInFlight -= 1;
627
- }
628
- },
697
+ dispatchOnce: (headPriority) => dispatch(headPriority, false),
698
+ dispatchObservabilityOnce: () => dispatch('oldest_ready', true),
699
+ observabilityParallelism: RUN_LEDGER_OUTBOX_RECOVERY_INDEX_IN_FLIGHT,
629
700
  // `dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope` releases each
630
701
  // short scheduler checkout before it calls the Vercel gateway. The two
631
702
  // replicas therefore drain up to sixteen independent runs concurrently
632
703
  // without turning one outbox notification into sixty-four head scans.
633
704
  parallelism: RUN_LEDGER_OUTBOX_RECOVERY_PRODUCTION_IN_FLIGHT,
705
+ notifyUnavailableSafetyWakeMs: runLedgerOutboxNotifySafetyWakeMs(
706
+ schedulerOptions.schema,
707
+ ),
634
708
  readNextDueAt: () =>
635
709
  withRuntimeSchedulerClient(input.poolOptions, (client) =>
636
710
  readPostgresSchedulerOutboxNextDueAt(client, schedulerOptions),
@@ -61,7 +61,7 @@ const RUNTIME_EVENT_LOG_POSITION_EXPRESSION = `jsonb_set(
61
61
  // Migration readiness tracks this projection body independently of scheduler
62
62
  // wire and schema versions. Bump when a changed trigger must be reinstalled.
63
63
  export const RUNTIME_EVENT_SEARCH_OUTBOX_PROJECTION_MARKER =
64
- 'runtime-event-search-origin-batches-log-metadata';
64
+ 'runtime-event-search-origin-batches-log-metadata-point-replay';
65
65
  /** Trusted trigger-authored state; absent on already-projected legacy rows. */
66
66
  export const RUNTIME_EVENT_DEFERRED_PROJECTION_FIELD =
67
67
  '_runtimeSearchProjectionPending';
@@ -1310,8 +1310,16 @@ export async function attachRuntimeEventSearchTriggers(
1310
1310
  -- Tombstones retain digest/identity: retry never restores an expired body.
1311
1311
  SELECT count(*) INTO mismatches
1312
1312
  FROM jsonb_array_elements(item->'lines') WITH ORDINALITY AS entries(body, ordinal)
1313
- LEFT JOIN runtime_observability.events event ON event.runtime_scope = ${quoteLiteral(scope)} AND event.org_id = run_org
1314
- AND event.event_id = 'log-origin:' || observation.run_id || ':' || (item->'lineIds'->>(ordinal-1)::int)
1313
+ -- Keep each replay proof on the journal primary key. An unrestricted
1314
+ -- join can hash the whole shared org history for a small JSON batch.
1315
+ LEFT JOIN LATERAL (
1316
+ SELECT event.run_id, event.kind, event.source_digest
1317
+ FROM runtime_observability.events event
1318
+ WHERE event.runtime_scope = ${quoteLiteral(scope)} AND event.org_id = run_org
1319
+ AND event.event_id = 'log-origin:' || observation.run_id || ':' || (item->'lineIds'->>(ordinal-1)::int)
1320
+ -- The primary key admits one row; retain a parameterized point lookup.
1321
+ LIMIT 1
1322
+ ) event ON true
1315
1323
  WHERE event.run_id IS DISTINCT FROM observation.run_id OR event.kind IS DISTINCT FROM ${RUN_EVENT_KIND_SQL_LITERAL.logAppended}
1316
1324
  OR event.source_digest IS DISTINCT FROM CASE WHEN NULLIF(item->'lineContexts'->(ordinal-1)::int, 'null'::jsonb) IS NULL
1317
1325
  THEN encode(sha256(convert_to(body #>> '{}','UTF8')),'hex')
@@ -1982,11 +1990,15 @@ export async function attachRuntimeEventSearchTriggers(
1982
1990
  DO UPDATE SET last_seq = runtime_observability.run_log_cursors.last_seq + EXCLUDED.last_seq,
1983
1991
  updated_at = clock_timestamp()
1984
1992
  RETURNING last_seq INTO assigned_seq;
1993
+ -- Bound sequence assignment before joining the variable-size ID list.
1994
+ -- Shared-journal history from other runs is never a candidate.
1985
1995
  UPDATE runtime_observability.events AS event
1986
1996
  SET log_seq = assigned_seq - line_count + fresh.ordinality
1987
1997
  FROM unnest(fresh_event_ids) WITH ORDINALITY AS fresh(event_id, ordinality)
1988
1998
  WHERE event.runtime_scope = ${quoteLiteral(scope)}
1989
1999
  AND event.org_id = run_org
2000
+ AND event.run_id = observation.run_id
2001
+ AND event.event_id = ANY(fresh_event_ids)
1990
2002
  AND event.event_id = fresh.event_id;
1991
2003
  END IF;
1992
2004
  RETURN;
@@ -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 _chunkBXYKLY5Tjs = require('./chunk-BXYKLY5T.js');
13
+ require('./chunk-TOAXEXTC.js');
14
+ require('./chunk-2Q4LGPVP.js');
15
+ require('./chunk-XNYIZMNQ.js');
16
+ require('./chunk-BUKTFUM7.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 = _chunkBXYKLY5Tjs.EXIT_WORKSPACE_MISMATCH; exports.clearPendingClaim = _chunkBXYKLY5Tjs.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunkBXYKLY5Tjs.clearSatisfiedPendingClaim; exports.handleRegister = _chunkBXYKLY5Tjs.handleRegister; exports.handleStatus = _chunkBXYKLY5Tjs.handleStatus; exports.handleWait = _chunkBXYKLY5Tjs.handleWait; exports.readPendingAuthClaim = _chunkBXYKLY5Tjs.readPendingAuthClaim; exports.registerAuthCommands = _chunkBXYKLY5Tjs.registerAuthCommands; exports.reportSetupCompleted = _chunkBXYKLY5Tjs.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunkBXYKLY5Tjs.resolvePendingAuthClaimForResume;
@@ -9,11 +9,11 @@ import {
9
9
  registerAuthCommands,
10
10
  reportSetupCompleted,
11
11
  resolvePendingAuthClaimForResume
12
- } from "./chunk-BZ77OTRF.mjs";
13
- import "./chunk-NTEZFZLE.mjs";
14
- import "./chunk-NPPJX3BL.mjs";
12
+ } from "./chunk-RES6RQXX.mjs";
13
+ import "./chunk-U6G52KUV.mjs";
14
+ import "./chunk-YE5PJMFK.mjs";
15
15
  import "./chunk-DLIRSHV6.mjs";
16
- import "./chunk-QSIO4TX2.mjs";
16
+ import "./chunk-6IOQ43VG.mjs";
17
17
  import "./chunk-NXGCO4JB.mjs";
18
18
  import "./chunk-WZYKRD7T.mjs";
19
19
  import "./chunk-KRD6H754.mjs";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DeeplineClient,
3
3
  iterateCursorPages
4
- } from "./chunk-J2D3VDOU.mjs";
4
+ } from "./chunk-FJTNI2TE.mjs";
5
5
  import "./chunk-CBVIJSHF.mjs";
6
6
  import {
7
7
  createTimestampedName,
@@ -9,13 +9,13 @@ import {
9
9
  openInBrowser,
10
10
  printCommandEnvelope,
11
11
  shouldEmitJson
12
- } from "./chunk-NTEZFZLE.mjs";
12
+ } from "./chunk-U6G52KUV.mjs";
13
13
  import {
14
14
  AuthError,
15
15
  ConfigError
16
- } from "./chunk-NPPJX3BL.mjs";
16
+ } from "./chunk-YE5PJMFK.mjs";
17
17
  import "./chunk-DLIRSHV6.mjs";
18
- import "./chunk-QSIO4TX2.mjs";
18
+ import "./chunk-6IOQ43VG.mjs";
19
19
  import "./chunk-GVUJJJ5G.mjs";
20
20
  import {
21
21
  DeeplineError