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
@@ -0,0 +1,610 @@
1
+ /**
2
+ * The persisted Play run event vocabulary and its storage/projection contract.
3
+ *
4
+ * For runs marked runEventStore=planet_scale, PlanetScale owns the complete
5
+ * accepted event and log history. Convex consumes only the projections named
6
+ * here. Unmarked legacy runs keep their existing Convex event/log history.
7
+ */
8
+ export const RUN_EVENT_KIND = {
9
+ runCreated: 'run.created',
10
+ runStarted: 'run.started',
11
+ runWaiting: 'run.waiting',
12
+ runResumed: 'run.resumed',
13
+ runCompleted: 'run.completed',
14
+ runFailed: 'run.failed',
15
+ runCancelled: 'run.cancelled',
16
+ stepStarted: 'step.started',
17
+ stepProgress: 'step.progress',
18
+ stepCompleted: 'step.completed',
19
+ stepFailed: 'step.failed',
20
+ stepSkipped: 'step.skipped',
21
+ logAppended: 'log.appended',
22
+ datasetLifecycle: 'dataset.lifecycle',
23
+ activityObserved: 'activity.observed',
24
+ workCounters: 'work.counters',
25
+ } as const;
26
+
27
+ export type RunEventKind = (typeof RUN_EVENT_KIND)[keyof typeof RUN_EVENT_KIND];
28
+ export type KnownRunEventKind = RunEventKind;
29
+
30
+ export const RUN_EVENT_SOURCE = {
31
+ worker: 'worker',
32
+ convex: 'convex',
33
+ coordinator: 'coordinator',
34
+ system: 'system',
35
+ } as const;
36
+
37
+ export type RunEventSource =
38
+ (typeof RUN_EVENT_SOURCE)[keyof typeof RUN_EVENT_SOURCE];
39
+
40
+ export type RunEventSearchField =
41
+ | 'kind'
42
+ | 'runId'
43
+ | 'playName'
44
+ | 'source'
45
+ | 'occurredAt';
46
+
47
+ export type RunEventPlanetScaleContent = 'event_payload' | 'log_body';
48
+ export type RunEventConvexProjection = 'run_snapshot' | null;
49
+ export type RunEventLegacyConvexDestination =
50
+ | 'run_ledger_history'
51
+ | 'run_log_stream';
52
+ export type RunEventConvexRetainedFact =
53
+ | 'admission_fence'
54
+ | 'saved_play_rollup_if_eligible';
55
+
56
+ export type RunEventOutboxCarrier =
57
+ | 'run.events'
58
+ | 'run.created'
59
+ | 'run.started'
60
+ | 'run.waiting'
61
+ | 'run.resumed'
62
+ | 'run.completed'
63
+ | 'run.failed'
64
+ | 'run.cancelled'
65
+ | 'runner.logs'
66
+ | 'run.wait_timeout';
67
+
68
+ export type RunEventDestination = {
69
+ /** Shared bounded runtime-event and log search read model. */
70
+ searchIndex: 'planet_scale_runtime_event_index';
71
+ /** Canonical history destination for a run explicitly marked PScale-backed. */
72
+ markedRunStore: 'planet_scale';
73
+ /** Which part of runtime_observability.events owns the original content. */
74
+ planetScaleContent: RunEventPlanetScaleContent;
75
+ /** Live control/UI projection delivered to Convex for marked runs. */
76
+ convexProjection: RunEventConvexProjection;
77
+ /** Small Convex facts retained alongside the snapshot for marked runs. */
78
+ convexRetainedFacts: readonly RunEventConvexRetainedFact[];
79
+ /** Existing destination for unmarked legacy runs. */
80
+ legacyConvexDestination: RunEventLegacyConvexDestination;
81
+ explanation: string;
82
+ };
83
+
84
+ export type RunEventKindDescriptor = {
85
+ description: string;
86
+ /** Trusted bounded search fields; event-specific detail stays in payload. */
87
+ searchableFields: readonly RunEventSearchField[];
88
+ /** Outbox transports that can produce this canonical kind. */
89
+ outboxCarriers: readonly RunEventOutboxCarrier[];
90
+ destination: RunEventDestination;
91
+ example: Readonly<Record<string, unknown>>;
92
+ };
93
+
94
+ const SEARCHABLE_EVENT_FIELDS = [
95
+ 'kind',
96
+ 'runId',
97
+ 'playName',
98
+ 'source',
99
+ 'occurredAt',
100
+ ] as const satisfies readonly RunEventSearchField[];
101
+
102
+ const RUN_SNAPSHOT_DESTINATION: RunEventDestination = {
103
+ searchIndex: 'planet_scale_runtime_event_index',
104
+ markedRunStore: 'planet_scale',
105
+ planetScaleContent: 'event_payload',
106
+ convexProjection: 'run_snapshot',
107
+ convexRetainedFacts: ['saved_play_rollup_if_eligible'],
108
+ legacyConvexDestination: 'run_ledger_history',
109
+ explanation:
110
+ 'PlanetScale retains the complete event. Convex reduces it into bounded current run state and keeps only selected saved-Play rollup facts when eligible; unmarked legacy runs retain Convex event history.',
111
+ };
112
+
113
+ const RUN_CREATED_DESTINATION: RunEventDestination = {
114
+ ...RUN_SNAPSHOT_DESTINATION,
115
+ convexRetainedFacts: ['admission_fence', 'saved_play_rollup_if_eligible'],
116
+ explanation:
117
+ 'PlanetScale retains the complete event. Convex uses it for the live run snapshot, retains the admission fence, and may retain a saved-Play rollup fact; unmarked legacy runs retain Convex event history.',
118
+ };
119
+
120
+ const RUN_LOG_DESTINATION: RunEventDestination = {
121
+ searchIndex: 'planet_scale_runtime_event_index',
122
+ markedRunStore: 'planet_scale',
123
+ planetScaleContent: 'log_body',
124
+ convexProjection: null,
125
+ convexRetainedFacts: [],
126
+ legacyConvexDestination: 'run_log_stream',
127
+ explanation:
128
+ 'PlanetScale retains the canonical log line and its search metadata. Marked-run log bodies are not copied into Convex; unmarked legacy runs continue to use the Convex Run Log Stream.',
129
+ };
130
+
131
+ /**
132
+ * Adding a known kind requires naming its search fields, outbox carrier,
133
+ * PlanetScale content shape, Convex projection, and legacy destination here.
134
+ */
135
+ export const RUN_EVENT_KIND_CATALOG = {
136
+ [RUN_EVENT_KIND.runCreated]: {
137
+ description: 'The run was admitted and received its run ID.',
138
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
139
+ outboxCarriers: ['run.created'],
140
+ destination: RUN_CREATED_DESTINATION,
141
+ example: {
142
+ runId: 'play/enrich/run/abc123',
143
+ type: RUN_EVENT_KIND.runCreated,
144
+ seq: 1,
145
+ },
146
+ },
147
+ [RUN_EVENT_KIND.runStarted]: {
148
+ description: 'The run began execution.',
149
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
150
+ outboxCarriers: ['run.started'],
151
+ destination: RUN_SNAPSHOT_DESTINATION,
152
+ example: {
153
+ runId: 'play/enrich/run/abc123',
154
+ type: RUN_EVENT_KIND.runStarted,
155
+ seq: 2,
156
+ },
157
+ },
158
+ [RUN_EVENT_KIND.runWaiting]: {
159
+ description: 'The run entered a durable wait.',
160
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
161
+ outboxCarriers: ['run.waiting'],
162
+ destination: RUN_SNAPSHOT_DESTINATION,
163
+ example: {
164
+ runId: 'play/enrich/run/abc123',
165
+ type: RUN_EVENT_KIND.runWaiting,
166
+ waitKind: 'sleep',
167
+ },
168
+ },
169
+ [RUN_EVENT_KIND.runResumed]: {
170
+ description: 'The run resumed after a durable wait.',
171
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
172
+ outboxCarriers: ['run.resumed'],
173
+ destination: RUN_SNAPSHOT_DESTINATION,
174
+ example: {
175
+ runId: 'play/enrich/run/abc123',
176
+ type: RUN_EVENT_KIND.runResumed,
177
+ },
178
+ },
179
+ [RUN_EVENT_KIND.runCompleted]: {
180
+ description: 'The run completed successfully.',
181
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
182
+ outboxCarriers: ['run.completed', 'runner.logs'],
183
+ destination: RUN_SNAPSHOT_DESTINATION,
184
+ example: {
185
+ runId: 'play/enrich/run/abc123',
186
+ type: RUN_EVENT_KIND.runCompleted,
187
+ },
188
+ },
189
+ [RUN_EVENT_KIND.runFailed]: {
190
+ description: 'The run ended with a failure.',
191
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
192
+ outboxCarriers: ['run.failed', 'runner.logs'],
193
+ destination: RUN_SNAPSHOT_DESTINATION,
194
+ example: {
195
+ runId: 'play/enrich/run/abc123',
196
+ type: RUN_EVENT_KIND.runFailed,
197
+ error: 'Request timed out',
198
+ },
199
+ },
200
+ [RUN_EVENT_KIND.runCancelled]: {
201
+ description: 'The run was cancelled.',
202
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
203
+ outboxCarriers: ['run.cancelled'],
204
+ destination: RUN_SNAPSHOT_DESTINATION,
205
+ example: {
206
+ runId: 'play/enrich/run/abc123',
207
+ type: RUN_EVENT_KIND.runCancelled,
208
+ },
209
+ },
210
+ [RUN_EVENT_KIND.stepStarted]: {
211
+ description: 'A named step began execution.',
212
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
213
+ outboxCarriers: [
214
+ 'run.events',
215
+ 'run.completed',
216
+ 'run.failed',
217
+ 'runner.logs',
218
+ ],
219
+ destination: RUN_SNAPSHOT_DESTINATION,
220
+ example: {
221
+ runId: 'play/enrich/run/abc123',
222
+ type: RUN_EVENT_KIND.stepStarted,
223
+ stepId: 'lookup',
224
+ },
225
+ },
226
+ [RUN_EVENT_KIND.stepProgress]: {
227
+ description: 'A named step reported progress.',
228
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
229
+ outboxCarriers: [
230
+ 'run.events',
231
+ 'run.completed',
232
+ 'run.failed',
233
+ 'runner.logs',
234
+ ],
235
+ destination: RUN_SNAPSHOT_DESTINATION,
236
+ example: {
237
+ runId: 'play/enrich/run/abc123',
238
+ type: RUN_EVENT_KIND.stepProgress,
239
+ stepId: 'lookup',
240
+ },
241
+ },
242
+ [RUN_EVENT_KIND.stepCompleted]: {
243
+ description: 'A named step completed.',
244
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
245
+ outboxCarriers: [
246
+ 'run.events',
247
+ 'run.completed',
248
+ 'run.failed',
249
+ 'runner.logs',
250
+ ],
251
+ destination: RUN_SNAPSHOT_DESTINATION,
252
+ example: {
253
+ runId: 'play/enrich/run/abc123',
254
+ type: RUN_EVENT_KIND.stepCompleted,
255
+ stepId: 'lookup',
256
+ },
257
+ },
258
+ [RUN_EVENT_KIND.stepFailed]: {
259
+ description: 'A named step failed.',
260
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
261
+ outboxCarriers: [
262
+ 'run.events',
263
+ 'run.completed',
264
+ 'run.failed',
265
+ 'runner.logs',
266
+ ],
267
+ destination: RUN_SNAPSHOT_DESTINATION,
268
+ example: {
269
+ runId: 'play/enrich/run/abc123',
270
+ type: RUN_EVENT_KIND.stepFailed,
271
+ stepId: 'lookup',
272
+ },
273
+ },
274
+ [RUN_EVENT_KIND.stepSkipped]: {
275
+ description: 'A named step was skipped.',
276
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
277
+ outboxCarriers: [
278
+ 'run.events',
279
+ 'run.completed',
280
+ 'run.failed',
281
+ 'runner.logs',
282
+ ],
283
+ destination: RUN_SNAPSHOT_DESTINATION,
284
+ example: {
285
+ runId: 'play/enrich/run/abc123',
286
+ type: RUN_EVENT_KIND.stepSkipped,
287
+ stepId: 'lookup',
288
+ },
289
+ },
290
+ [RUN_EVENT_KIND.logAppended]: {
291
+ description:
292
+ 'A text log line was appended to the unified run history and log view.',
293
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
294
+ outboxCarriers: [
295
+ 'run.events',
296
+ 'run.waiting',
297
+ 'run.resumed',
298
+ 'run.completed',
299
+ 'run.failed',
300
+ 'runner.logs',
301
+ 'run.wait_timeout',
302
+ ],
303
+ destination: RUN_LOG_DESTINATION,
304
+ example: {
305
+ runId: 'play/enrich/run/abc123',
306
+ type: RUN_EVENT_KIND.logAppended,
307
+ lines: ['Waiting for integration_event:contact.updated.'],
308
+ },
309
+ },
310
+ [RUN_EVENT_KIND.datasetLifecycle]: {
311
+ description: 'A run dataset was registered, made available, or failed.',
312
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
313
+ outboxCarriers: [
314
+ 'run.events',
315
+ 'run.completed',
316
+ 'run.failed',
317
+ 'runner.logs',
318
+ ],
319
+ destination: RUN_SNAPSHOT_DESTINATION,
320
+ example: {
321
+ runId: 'play/enrich/run/abc123',
322
+ type: RUN_EVENT_KIND.datasetLifecycle,
323
+ phase: 'available',
324
+ },
325
+ },
326
+ [RUN_EVENT_KIND.activityObserved]: {
327
+ description: 'The runtime recorded an activity observation.',
328
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
329
+ outboxCarriers: [
330
+ 'run.events',
331
+ 'run.completed',
332
+ 'run.failed',
333
+ 'runner.logs',
334
+ ],
335
+ destination: RUN_SNAPSHOT_DESTINATION,
336
+ example: {
337
+ runId: 'play/enrich/run/abc123',
338
+ type: RUN_EVENT_KIND.activityObserved,
339
+ },
340
+ },
341
+ [RUN_EVENT_KIND.workCounters]: {
342
+ description:
343
+ 'A work segment reported logical call, provider request, and rate-limit counters.',
344
+ searchableFields: SEARCHABLE_EVENT_FIELDS,
345
+ outboxCarriers: [
346
+ 'run.events',
347
+ 'run.completed',
348
+ 'run.failed',
349
+ 'runner.logs',
350
+ ],
351
+ destination: RUN_SNAPSHOT_DESTINATION,
352
+ example: {
353
+ runId: 'play/enrich/run/abc123',
354
+ type: RUN_EVENT_KIND.workCounters,
355
+ attempt: 1,
356
+ logicalCalls: 4,
357
+ providerRequests: 4,
358
+ provider429s: 0,
359
+ final: true,
360
+ },
361
+ },
362
+ } satisfies Record<RunEventKind, RunEventKindDescriptor>;
363
+
364
+ export const RUN_EVENT_KINDS = Object.freeze(
365
+ Object.keys(RUN_EVENT_KIND_CATALOG) as RunEventKind[],
366
+ );
367
+
368
+ export const RUN_EVENT_UNKNOWN_KIND_DESTINATION: RunEventDestination = {
369
+ searchIndex: 'planet_scale_runtime_event_index',
370
+ markedRunStore: 'planet_scale',
371
+ planetScaleContent: 'event_payload',
372
+ convexProjection: null,
373
+ convexRetainedFacts: [],
374
+ legacyConvexDestination: 'run_ledger_history',
375
+ explanation:
376
+ 'An unknown kind inside a run.events batch is retained in PlanetScale and not projected to the marked-run Convex snapshot. Unmarked legacy runs keep their existing Convex opaque-event history.',
377
+ };
378
+
379
+ /** Scheduler transport envelopes; these are carriers, not ledger kinds. */
380
+ export const RUN_SCHEDULER_OUTBOX_EVENT_TYPE = {
381
+ runCreated: RUN_EVENT_KIND.runCreated,
382
+ runStarted: RUN_EVENT_KIND.runStarted,
383
+ runWaiting: RUN_EVENT_KIND.runWaiting,
384
+ runResumed: RUN_EVENT_KIND.runResumed,
385
+ runCompleted: RUN_EVENT_KIND.runCompleted,
386
+ runFailed: RUN_EVENT_KIND.runFailed,
387
+ runCancelled: RUN_EVENT_KIND.runCancelled,
388
+ runEvents: 'run.events',
389
+ runnerLogs: 'runner.logs',
390
+ runWaitTimeout: 'run.wait_timeout',
391
+ } as const;
392
+
393
+ export const RUN_SCHEDULER_OUTBOX_EVENT_TYPES = Object.freeze(
394
+ Object.values(RUN_SCHEDULER_OUTBOX_EVENT_TYPE),
395
+ );
396
+
397
+ export const RUN_SCHEDULER_OUTBOX_START_EVENT_TYPES: readonly string[] = [
398
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCreated,
399
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runStarted,
400
+ ];
401
+
402
+ export const RUN_SCHEDULER_OUTBOX_PREFIX_STOP_EVENT_TYPES: readonly string[] = [
403
+ ...RUN_SCHEDULER_OUTBOX_START_EVENT_TYPES,
404
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runEvents,
405
+ ];
406
+
407
+ export const RUN_SCHEDULER_OUTBOX_TERMINAL_EVENT_TYPES: readonly string[] = [
408
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCompleted,
409
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runFailed,
410
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCancelled,
411
+ ];
412
+
413
+ export type RunSchedulerOutboxEventType =
414
+ (typeof RUN_SCHEDULER_OUTBOX_EVENT_TYPES)[number];
415
+
416
+ /** Convex-only facts used for saved-Play membership corrections. */
417
+ export const RUN_EVENT_CONVEX_INTERNAL_KIND = {
418
+ rollupMembershipAdded: 'rollup.membership.added',
419
+ rollupMembershipRemoved: 'rollup.membership.removed',
420
+ } as const;
421
+
422
+ /** Receipt outcomes are searchable beside run events but are not run events. */
423
+ export const RUN_RECEIPT_SEARCH_KIND = {
424
+ completed: 'receipt.completed',
425
+ failed: 'receipt.failed',
426
+ skipped: 'receipt.skipped',
427
+ } as const;
428
+
429
+ export const RUN_RECEIPT_SEARCH_KIND_CATALOG = {
430
+ [RUN_RECEIPT_SEARCH_KIND.completed]: {
431
+ description: 'A durable work receipt completed.',
432
+ searchIndex: 'planet_scale_runtime_event_index',
433
+ payloadStore: 'authoritative_work_receipt',
434
+ },
435
+ [RUN_RECEIPT_SEARCH_KIND.failed]: {
436
+ description: 'A durable work receipt failed.',
437
+ searchIndex: 'planet_scale_runtime_event_index',
438
+ payloadStore: 'authoritative_work_receipt',
439
+ },
440
+ [RUN_RECEIPT_SEARCH_KIND.skipped]: {
441
+ description: 'A durable work receipt was skipped.',
442
+ searchIndex: 'planet_scale_runtime_event_index',
443
+ payloadStore: 'authoritative_work_receipt',
444
+ },
445
+ } as const;
446
+
447
+ export const RUN_EVENT_SEARCH_FALLBACK_KIND = 'runtime.event' as const;
448
+
449
+ /** Complete vocabulary accepted by the runtime-event search --kind filter. */
450
+ export const RUN_EVENT_SEARCH_KIND_VALUES = Object.freeze([
451
+ ...RUN_EVENT_KINDS,
452
+ ...Object.keys(RUN_RECEIPT_SEARCH_KIND_CATALOG),
453
+ RUN_EVENT_SEARCH_FALLBACK_KIND,
454
+ ] as const);
455
+
456
+ export const RUN_EVENT_TERMINAL_KIND_VALUES: readonly string[] = [
457
+ RUN_EVENT_KIND.runCompleted,
458
+ RUN_EVENT_KIND.runFailed,
459
+ RUN_EVENT_KIND.runCancelled,
460
+ ];
461
+
462
+ /** Live UI timeline names are projections; persisted kinds stay canonical. */
463
+ export const PLAY_RUN_TIMELINE_EVENT_TYPE = {
464
+ status: 'play.run.status',
465
+ snapshot: 'play.run.snapshot',
466
+ finalStatus: 'play.run.final_status',
467
+ stepStatus: 'play.step.status',
468
+ stepProgress: 'play.step.progress',
469
+ health: 'play.run.health',
470
+ log: 'play.run.log',
471
+ sheetSummary: 'play.sheet.summary',
472
+ sheetDelta: 'play.sheet.delta',
473
+ } as const;
474
+
475
+ export const RUN_EVENT_SEARCH_DEFAULT_WINDOW_HOURS = 24;
476
+ export const RUN_EVENT_SEARCH_DEFAULT_LIMIT = 50;
477
+ export const RUN_EVENT_SEARCH_MAX_LIMIT = 200;
478
+ export const RUN_EVENT_SEARCH_MAX_RUNS = 50;
479
+ export const RUN_EVENT_SEARCH_EVENTS_PER_RUN = 200;
480
+ export const RUN_EVENT_SEARCH_MAX_SCANNED_EVENTS = 32;
481
+
482
+ export const RUN_LOG_LINE_MAX_CHARS = 2_000;
483
+ export const RUN_LOG_RETENTION_MAX_LINES = 25_000;
484
+ export const RUN_LOG_RETENTION_MAX_BYTES = 5 * 1024 * 1024;
485
+ export const RUN_LOG_PAGE_MAX_LIMIT = 1_000;
486
+ export const RUN_LOG_PAGE_DEFAULT_LIMIT = RUN_LOG_PAGE_MAX_LIMIT;
487
+ export const RUN_LOG_TAIL_DEFAULT_LIMIT = 200;
488
+ export const RUN_LOG_FAILED_VIEW_MAX_LINES = 20;
489
+ export const RUN_LOG_RATE_LIMIT_POLICY = {
490
+ debug: { first: 200, every: 100 },
491
+ info: { first: 1_000, every: 100 },
492
+ } as const;
493
+ export const RUN_LOG_RATE_LIMIT_MARKER_EVERY = 1_000;
494
+ export const RUN_LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;
495
+ export type RunLogLevel = (typeof RUN_LOG_LEVELS)[number];
496
+
497
+ function sqlStringLiteral(value: string): string {
498
+ return "'" + value.replaceAll("'", "''") + "'";
499
+ }
500
+
501
+ /** SQL fragments used by the generated PlanetScale event recorder. */
502
+ export const RUN_EVENT_KNOWN_KIND_SQL_LIST =
503
+ RUN_EVENT_KINDS.map(sqlStringLiteral).join(', ');
504
+
505
+ export const RUN_EVENT_LIFECYCLE_KIND_SQL_LIST = [
506
+ RUN_EVENT_KIND.runCreated,
507
+ RUN_EVENT_KIND.runStarted,
508
+ RUN_EVENT_KIND.runWaiting,
509
+ RUN_EVENT_KIND.runResumed,
510
+ RUN_EVENT_KIND.runCompleted,
511
+ RUN_EVENT_KIND.runFailed,
512
+ RUN_EVENT_KIND.runCancelled,
513
+ ]
514
+ .map(sqlStringLiteral)
515
+ .join(', ');
516
+
517
+ export const RUN_EVENT_SNAPSHOT_KIND_SQL_LIST = RUN_EVENT_KINDS.filter(
518
+ (kind) => kind !== RUN_EVENT_KIND.logAppended,
519
+ )
520
+ .map(sqlStringLiteral)
521
+ .join(', ');
522
+
523
+ export const RUN_EVENT_KIND_SQL_LITERAL = {
524
+ runCreated: sqlStringLiteral(RUN_EVENT_KIND.runCreated),
525
+ runStarted: sqlStringLiteral(RUN_EVENT_KIND.runStarted),
526
+ runWaiting: sqlStringLiteral(RUN_EVENT_KIND.runWaiting),
527
+ runResumed: sqlStringLiteral(RUN_EVENT_KIND.runResumed),
528
+ runCompleted: sqlStringLiteral(RUN_EVENT_KIND.runCompleted),
529
+ runFailed: sqlStringLiteral(RUN_EVENT_KIND.runFailed),
530
+ runCancelled: sqlStringLiteral(RUN_EVENT_KIND.runCancelled),
531
+ stepStarted: sqlStringLiteral(RUN_EVENT_KIND.stepStarted),
532
+ stepProgress: sqlStringLiteral(RUN_EVENT_KIND.stepProgress),
533
+ stepCompleted: sqlStringLiteral(RUN_EVENT_KIND.stepCompleted),
534
+ stepFailed: sqlStringLiteral(RUN_EVENT_KIND.stepFailed),
535
+ stepSkipped: sqlStringLiteral(RUN_EVENT_KIND.stepSkipped),
536
+ logAppended: sqlStringLiteral(RUN_EVENT_KIND.logAppended),
537
+ datasetLifecycle: sqlStringLiteral(RUN_EVENT_KIND.datasetLifecycle),
538
+ activityObserved: sqlStringLiteral(RUN_EVENT_KIND.activityObserved),
539
+ workCounters: sqlStringLiteral(RUN_EVENT_KIND.workCounters),
540
+ } as const;
541
+
542
+ export const RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL = {
543
+ runCreated: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCreated),
544
+ runStarted: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runStarted),
545
+ runWaiting: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaiting),
546
+ runResumed: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runResumed),
547
+ runCompleted: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCompleted),
548
+ runFailed: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runFailed),
549
+ runCancelled: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCancelled),
550
+ runEvents: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runEvents),
551
+ runnerLogs: sqlStringLiteral(RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runnerLogs),
552
+ runWaitTimeout: sqlStringLiteral(
553
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runWaitTimeout,
554
+ ),
555
+ } as const;
556
+
557
+ export const RUN_EVENT_CONVEX_INTERNAL_KIND_SQL_LITERAL = {
558
+ rollupMembershipAdded: sqlStringLiteral(
559
+ RUN_EVENT_CONVEX_INTERNAL_KIND.rollupMembershipAdded,
560
+ ),
561
+ rollupMembershipRemoved: sqlStringLiteral(
562
+ RUN_EVENT_CONVEX_INTERNAL_KIND.rollupMembershipRemoved,
563
+ ),
564
+ } as const;
565
+
566
+ export const RUN_EVENT_TERMINAL_LOG_CARRIER_SQL_LIST = [
567
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runCompleted,
568
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runFailed,
569
+ RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runnerLogs,
570
+ ]
571
+ .map(sqlStringLiteral)
572
+ .join(', ');
573
+
574
+ export const RUN_SCHEDULER_OUTBOX_TERMINAL_EVENT_TYPE_SQL_LIST = [
575
+ ...RUN_SCHEDULER_OUTBOX_TERMINAL_EVENT_TYPES,
576
+ ]
577
+ .map(sqlStringLiteral)
578
+ .join(', ');
579
+
580
+ export const RUN_EVENT_SEARCH_FALLBACK_KIND_SQL_LITERAL = sqlStringLiteral(
581
+ RUN_EVENT_SEARCH_FALLBACK_KIND,
582
+ );
583
+
584
+ export function isKnownRunEventKind(value: string): value is RunEventKind {
585
+ return Object.prototype.hasOwnProperty.call(RUN_EVENT_KIND_CATALOG, value);
586
+ }
587
+
588
+ export function getRunEventDestination(kind: string): RunEventDestination {
589
+ if (!isKnownRunEventKind(kind)) return RUN_EVENT_UNKNOWN_KIND_DESTINATION;
590
+ return RUN_EVENT_KIND_CATALOG[kind].destination;
591
+ }
592
+
593
+ export function describeRunEventDestination(kind: string): string {
594
+ const destination = getRunEventDestination(kind);
595
+ const projection = destination.convexProjection
596
+ ? 'Convex live run snapshot'
597
+ : 'no marked-run Convex projection';
598
+ const legacy =
599
+ destination.legacyConvexDestination === 'run_log_stream'
600
+ ? 'legacy Convex Run Log Stream'
601
+ : 'legacy Convex event history';
602
+ return (
603
+ 'PlanetScale ' +
604
+ destination.planetScaleContent +
605
+ '; ' +
606
+ projection +
607
+ '; ' +
608
+ legacy
609
+ );
610
+ }
@@ -1,3 +1,4 @@
1
+ import { RUN_EVENT_KIND } from './run-event-catalog';
1
2
  import type { PlayRunLedgerIngressEvent } from './run-ledger';
2
3
  import type { PlayLogContext } from './log-context';
3
4
  import type { RunLedgerProjectionChunk } from './run-ledger-projection-contract';
@@ -26,7 +27,8 @@ function splitRunEventForAppRuntime(
26
27
  const lines = Array.isArray(rawLines)
27
28
  ? rawLines.filter((line): line is string => typeof line === 'string')
28
29
  : [];
29
- if (eventType !== 'log.appended' || lines.length === 0) return [event];
30
+ if (eventType !== RUN_EVENT_KIND.logAppended || lines.length === 0)
31
+ return [event];
30
32
  const payloadOwnsLineContexts =
31
33
  payload !== null && Object.hasOwn(payload, 'lineContexts');
32
34
  const eventOwnsLineContexts = Object.hasOwn(event, 'lineContexts');
@@ -1,3 +1,4 @@
1
+ import { RUN_EVENT_KIND } from './run-event-catalog';
1
2
  import { stableStringify } from '../plays/row-identity';
2
3
  import type {
3
4
  AcceptedPlayRunLedgerEvent,
@@ -31,8 +32,8 @@ function normalizeLegacyRunWaitingProjectionFields(
31
32
  const expected = expectedEvents[index];
32
33
  if (
33
34
  isPlayRunLedgerOpaqueEvent(event) ||
34
- event.type !== 'run.waiting' ||
35
- expected?.type !== 'run.waiting' ||
35
+ event.type !== RUN_EVENT_KIND.runWaiting ||
36
+ expected?.type !== RUN_EVENT_KIND.runWaiting ||
36
37
  ('opaque' in expected && expected.opaque === true)
37
38
  ) {
38
39
  return event;