deepline 0.3.306 → 0.3.307

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/absurd-shared.ts +10 -5
  3. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +4 -1
  4. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +125 -19
  5. package/dist/cli/{auth-WTC7LCQ6.mjs → auth-AJPTFFC7.mjs} +4 -4
  6. package/dist/cli/auth-TUQTQIH4.js +31 -0
  7. package/dist/cli/{billing-VQM65LVP.mjs → billing-LPDYJLIL.mjs} +4 -4
  8. package/dist/cli/{billing-3DYTHO32.js → billing-SPBWUEOS.js} +70 -70
  9. package/dist/cli/{chunk-2KR56MPF.js → chunk-76MFV3AC.js} +2 -2
  10. package/dist/cli/{chunk-6CRUYVU7.mjs → chunk-7ONALPWY.mjs} +4 -4
  11. package/dist/cli/{chunk-M6HCRRV2.js → chunk-AKE6ZFIJ.js} +4 -4
  12. package/dist/cli/{chunk-5HS5EEFE.mjs → chunk-BDFVIOLY.mjs} +3 -3
  13. package/dist/cli/{chunk-5V56XCQN.mjs → chunk-D55NIPGU.mjs} +1 -1
  14. package/dist/cli/{chunk-U37SW6IK.js → chunk-DF3XJ2V2.js} +48 -48
  15. package/dist/cli/{chunk-FJ3DANI4.mjs → chunk-G4SSYZND.mjs} +1 -1
  16. package/dist/cli/{chunk-SZQPJW2L.js → chunk-GUIQWUCB.js} +6 -6
  17. package/dist/cli/{chunk-RODIZCGU.js → chunk-HWCB5MHF.js} +57 -57
  18. package/dist/cli/{chunk-QDC4XTO3.mjs → chunk-ILOCS73R.mjs} +2 -2
  19. package/dist/cli/{chunk-OF7QP2XX.js → chunk-IVXD2KA2.js} +15 -15
  20. package/dist/cli/{chunk-MMNZ6GBT.js → chunk-JNHXSZPB.js} +6 -6
  21. package/dist/cli/{chunk-FZNO6B4W.js → chunk-K2CQ2RBJ.js} +6 -6
  22. package/dist/cli/{chunk-PHNAFCSB.js → chunk-KCHBE2J3.js} +6 -6
  23. package/dist/cli/{chunk-4PSSDZQB.mjs → chunk-MPVXXDWH.mjs} +1 -1
  24. package/dist/cli/{chunk-OZIFVQRY.js → chunk-MZQP7CIL.js} +1 -1
  25. package/dist/cli/{chunk-WV64SNDV.mjs → chunk-O4OESDIN.mjs} +1 -1
  26. package/dist/cli/{chunk-WWPI4GJI.mjs → chunk-QACDLYNO.mjs} +1 -1
  27. package/dist/cli/{chunk-UT3VLSLM.mjs → chunk-RXYYANYP.mjs} +2 -2
  28. package/dist/cli/{chunk-LLGF6V6I.mjs → chunk-TLTKAJ6S.mjs} +1 -1
  29. package/dist/cli/{chunk-7XORS6WQ.mjs → chunk-ZGICKTW7.mjs} +2 -2
  30. package/dist/cli/{chunk-W7ELTWDM.js → chunk-ZIF6JOOI.js} +26 -26
  31. package/dist/cli/{client-DCEK34D5.mjs → client-7ZL4ROII.mjs} +3 -3
  32. package/dist/cli/client-S3MIFPM2.js +20 -0
  33. package/dist/cli/{csv-H42JDJ6G.js → csv-JUDFG7JV.js} +12 -12
  34. package/dist/cli/{csv-LXBF5UIV.mjs → csv-Y3LYCTGD.mjs} +3 -3
  35. package/dist/cli/{db-DP5GU4MU.js → db-5IXGEXNT.js} +20 -20
  36. package/dist/cli/{db-3O5CFLNP.mjs → db-GCOJD2BD.mjs} +4 -4
  37. package/dist/cli/{executions-QC2UZKIP.mjs → executions-FIICTMSY.mjs} +4 -4
  38. package/dist/cli/{executions-5FFTPHEX.js → executions-LIEQKFT7.js} +6 -6
  39. package/dist/cli/{feedback-JCGE6JFW.mjs → feedback-3OVAA3C7.mjs} +3 -3
  40. package/dist/cli/{feedback-XAU3FI5S.js → feedback-FAADYNAR.js} +6 -6
  41. package/dist/cli/{git-S3Y3E2NL.mjs → git-ESMYCYJO.mjs} +4 -4
  42. package/dist/cli/git-GG6LWE2R.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-FQF2IRVS.mjs → legacy-noops-KP5CPZRK.mjs} +4 -4
  46. package/dist/cli/{legacy-noops-TXOUX4FX.js → legacy-noops-PKI3RFZW.js} +7 -7
  47. package/dist/cli/{monitors-F3PELPSH.mjs → monitors-A6KGGSBO.mjs} +4 -4
  48. package/dist/cli/{monitors-4BQCO6B7.js → monitors-KCFBLAFZ.js} +85 -85
  49. package/dist/cli/{org-ER5J3ATG.mjs → org-DHI24UOK.mjs} +4 -4
  50. package/dist/cli/{org-VQM6OOLK.js → org-WI6DEXZQ.js} +60 -60
  51. package/dist/cli/{play-B5H2RN4N.mjs → play-2YXLQD24.mjs} +6 -6
  52. package/dist/cli/{play-WKZPAOW3.js → play-4EUUN76H.js} +200 -200
  53. package/dist/cli/{providers-6ODEAYC2.mjs → providers-2WZ6KHH2.mjs} +4 -4
  54. package/dist/cli/{providers-5TEA2FJG.js → providers-DWS3XIM6.js} +7 -7
  55. package/dist/cli/{quickstart-GJYCNMFC.js → quickstart-TDTDKM6F.js} +5 -5
  56. package/dist/cli/{quickstart-BCYT7BCY.mjs → quickstart-ZFZVG6UO.mjs} +3 -3
  57. package/dist/cli/{search-RY547KOT.mjs → search-BBE2ZMCI.mjs} +5 -5
  58. package/dist/cli/{search-KKJ535OX.js → search-GMPXRQF4.js} +6 -6
  59. package/dist/cli/{secrets-U42ZEYIU.mjs → secrets-JEJL3KIM.mjs} +4 -4
  60. package/dist/cli/{secrets-RFGDXSEW.js → secrets-SMBX4IE6.js} +13 -13
  61. package/dist/cli/{sessions-YWEFB62D.mjs → sessions-AVU353UT.mjs} +4 -4
  62. package/dist/cli/{sessions-ZRTWHMIH.js → sessions-S6AWG747.js} +5 -5
  63. package/dist/cli/{settings-AS4U6NVP.mjs → settings-GY5CYRLF.mjs} +7 -7
  64. package/dist/cli/{settings-XUWFXIL7.js → settings-KBW4ROHC.js} +74 -74
  65. package/dist/cli/{setup-2GUIV2EW.mjs → setup-4CW3XGGX.mjs} +6 -6
  66. package/dist/cli/{setup-2QPWP2FI.js → setup-WSVIDSEV.js} +41 -41
  67. package/dist/cli/skills-6AU3RRAD.js +28 -0
  68. package/dist/cli/{skills-5QS7ERVF.mjs → skills-U3NXFSFK.mjs} +4 -4
  69. package/dist/cli/{tools-J47LIO2H.js → tools-KZKELW25.js} +50 -50
  70. package/dist/cli/{tools-PVWSGCZD.mjs → tools-XU6KLJZT.mjs} +5 -5
  71. package/dist/cli/update-LVXXQF4A.js +28 -0
  72. package/dist/cli/{update-KS4TRSZI.mjs → update-RZLH46DR.mjs} +6 -6
  73. package/dist/cli/{workflow-HQRUUTTL.js → workflow-GDOGDGTZ.js} +15 -15
  74. package/dist/cli/{workflow-QCLR7GVC.mjs → workflow-ZQUKQI35.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-ZT3UF33R.js +0 -31
  84. package/dist/cli/client-UQXVU2T6.js +0 -20
  85. package/dist/cli/git-CNO2UFZE.js +0 -23
  86. package/dist/cli/skills-4E5KYW2Y.js +0 -28
  87. package/dist/cli/update-GZKGOMKD.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.306',
203
+ version: '0.3.307',
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: {
@@ -614,9 +614,15 @@ export function ensureAbsurdRuntimeReady(
614
614
  const existing = absurdReadyPromises.get(key);
615
615
  if (existing) return existing;
616
616
  const promise = (async () => {
617
- await withRuntimeSchedulerClient(poolOptions, (client) =>
618
- assertAbsurdSchemaReady(client),
619
- );
617
+ const absurd = createAbsurdRuntimeClient(poolOptions, runsQueue);
618
+ // Cold admission pays both reads. Queue inventory does not depend on the
619
+ // compatibility result, but maintenance and queue writes require both.
620
+ const [, queueNames] = await Promise.all([
621
+ withRuntimeSchedulerClient(poolOptions, (client) =>
622
+ assertAbsurdSchemaReady(client),
623
+ ),
624
+ absurd.listQueues(),
625
+ ]);
620
626
  // Hard-cutover cleanup: an old worker may have persisted a run waiting
621
627
  // on a scheduled ctx.runPlay child. This runtime intentionally has no such
622
628
  // scheduler anymore, so make the affected run visibly failed and emit
@@ -624,8 +630,7 @@ export function ensureAbsurdRuntimeReady(
624
630
  await withRuntimeSchedulerClient(poolOptions, (client) =>
625
631
  failPostgresSchedulerScheduledChildWaits(client, schedulerOptions),
626
632
  );
627
- const absurd = createAbsurdRuntimeClient(poolOptions, runsQueue);
628
- const existingQueues = new Set(await absurd.listQueues());
633
+ const existingQueues = new Set(queueNames);
629
634
  if (!existingQueues.has(runsQueue)) {
630
635
  await absurd.createQueue(runsQueue);
631
636
  }
@@ -351,8 +351,10 @@ const POSTGRES_SCHEDULER_SCHEMA_INIT_STATEMENT_TIMEOUT_MS = 60_000;
351
351
  // until the separately operated, reader-first cutover.
352
352
  // v59 adds origin identity bulk projection and independent durable search progress.
353
353
  // v60 indexes all sandbox leases by Run, including released custody history.
354
+ // v61 adds an operator-owned new-run projection cutover and admission pin.
355
+ // Existing namespace mode values and unpinned runs keep their behavior.
354
356
  // This marker records deployment work, never a runtime schema floor.
355
- export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 60;
357
+ export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 61;
356
358
  const POSTGRES_SCHEDULER_SCHEMA_MIGRATIONS_TABLE =
357
359
  'scheduler_schema_migrations';
358
360
  export const POSTGRES_SCHEDULER_OPEN_RECOVERY_INDEX =
@@ -2499,6 +2501,7 @@ export async function ensurePostgresSchedulerLaunchAdmissionFunctions(
2499
2501
  launch_json - ARRAY[
2500
2502
  'launchIdentityDigest',
2501
2503
  'runtimeLogIdentity',
2504
+ 'runtimeEventProjection',
2502
2505
  'executorToken',
2503
2506
  'inputFileId',
2504
2507
  'preloadedDbSessionUnwrapKey',
@@ -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-point-replay';
64
+ 'runtime-event-search-origin-batches-new-run-cutover-fresh-origin';
65
65
  /** Trusted trigger-authored state; absent on already-projected legacy rows. */
66
66
  export const RUNTIME_EVENT_DEFERRED_PROJECTION_FIELD =
67
67
  '_runtimeSearchProjectionPending';
@@ -976,6 +976,7 @@ export async function setRuntimeEventDeferredProjection(
976
976
  runtimeScope: string,
977
977
  deferred: boolean,
978
978
  independent?: boolean,
979
+ newRunsOnly?: true,
979
980
  ): Promise<void> {
980
981
  const schema = quoteIdent(requiredScope(runtimeScope));
981
982
  if (!(await hasRuntimeEventSearchShape(client, runtimeScope))) {
@@ -991,11 +992,38 @@ export async function setRuntimeEventDeferredProjection(
991
992
  await client.query('BEGIN');
992
993
  try {
993
994
  await client.query("SELECT set_config('lock_timeout', '1000', true)");
995
+ // Fence admission before outbox writes, in the normal Run -> outbox order.
996
+ // The admission pin and producer flags change at one committed boundary.
997
+ await client.query(`LOCK TABLE ${schema}.runs IN SHARE ROW EXCLUSIVE MODE`);
994
998
  // Fence trigger execution while changing mode. This operator-only lock
995
999
  // never spans projection; normal producer writes acquire no such lock.
996
1000
  await client.query(
997
1001
  `LOCK TABLE ${schema}.outbox IN SHARE ROW EXCLUSIVE MODE`,
998
1002
  );
1003
+ const previous = await client.query<{
1004
+ deferred: boolean;
1005
+ new_runs_only: boolean;
1006
+ }>(`SELECT ${schema}.defer_runtime_event_projection() AS deferred,
1007
+ ${schema}.new_runs_only_runtime_event_projection() AS new_runs_only`);
1008
+ const scoped =
1009
+ newRunsOnly === true || previous.rows[0]?.new_runs_only === true;
1010
+ if (deferred && scoped && independent === false) {
1011
+ throw new Error(
1012
+ 'Scoped cutover requires independent projection; use disable to stop it.',
1013
+ );
1014
+ }
1015
+ if (newRunsOnly === true) {
1016
+ if (!deferred || independent !== true) {
1017
+ throw new Error(
1018
+ 'New-run cutover requires independent deferred projection.',
1019
+ );
1020
+ }
1021
+ if (previous.rows[0]?.deferred && !previous.rows[0]?.new_runs_only) {
1022
+ throw new Error(
1023
+ 'Drain and disable global deferred projection before a new-run cutover.',
1024
+ );
1025
+ }
1026
+ }
999
1027
  if (!deferred) {
1000
1028
  const pending = await client.query<{ event_id: string }>(
1001
1029
  `SELECT event_id FROM ${schema}.outbox
@@ -1019,12 +1047,14 @@ export async function setRuntimeEventDeferredProjection(
1019
1047
  );
1020
1048
  }
1021
1049
  await installRuntimeEventProjectionMode(client, schema, deferred);
1022
- if (independent !== undefined || !deferred)
1050
+ if (independent !== undefined || !deferred || scoped)
1023
1051
  await installIndependentProjectionMode(
1024
1052
  client,
1025
1053
  schema,
1026
- deferred && independent === true,
1054
+ deferred && (independent === true || scoped),
1027
1055
  );
1056
+ if (newRunsOnly !== undefined)
1057
+ await installNewRunProjectionMode(client, schema, newRunsOnly);
1028
1058
  await client.query('COMMIT');
1029
1059
  } catch (error) {
1030
1060
  await client.query('ROLLBACK');
@@ -1036,10 +1066,12 @@ export type RuntimeEventProjectionModes = {
1036
1066
  runtimeScope: string;
1037
1067
  deferred: boolean | null;
1038
1068
  independent: boolean | null;
1069
+ newRunsOnly?: boolean | null;
1039
1070
  unavailableReason:
1040
1071
  | 'projection_mode_readers_missing'
1041
1072
  | 'deferred_projection_reader_missing'
1042
1073
  | 'independent_projection_reader_missing'
1074
+ | 'new_run_projection_reader_missing'
1043
1075
  | null;
1044
1076
  };
1045
1077
 
@@ -1053,25 +1085,31 @@ export async function readRuntimeEventProjectionModes(
1053
1085
  const installed = await client.query<{
1054
1086
  deferred_installed: boolean;
1055
1087
  independent_installed: boolean;
1088
+ new_runs_only_installed: boolean;
1056
1089
  }>(
1057
1090
  `SELECT to_regprocedure($1) IS NOT NULL AS deferred_installed,
1058
- to_regprocedure($2) IS NOT NULL AS independent_installed`,
1091
+ to_regprocedure($2) IS NOT NULL AS independent_installed,
1092
+ to_regprocedure($3) IS NOT NULL AS new_runs_only_installed`,
1059
1093
  [
1060
1094
  `${schema}.defer_runtime_event_projection()`,
1061
1095
  `${schema}.independent_runtime_event_projection()`,
1096
+ `${schema}.new_runs_only_runtime_event_projection()`,
1062
1097
  ],
1063
1098
  );
1064
1099
  const readers = installed.rows[0];
1065
1100
  if (
1066
1101
  !readers ||
1067
1102
  typeof readers.deferred_installed !== 'boolean' ||
1068
- typeof readers.independent_installed !== 'boolean'
1103
+ typeof readers.independent_installed !== 'boolean' ||
1104
+ typeof readers.new_runs_only_installed !== 'boolean'
1069
1105
  ) {
1070
1106
  throw new Error('Runtime projection mode lookup returned no reader state.');
1071
1107
  }
1072
1108
  const unavailableReason = readers.deferred_installed
1073
1109
  ? readers.independent_installed
1074
- ? null
1110
+ ? readers.new_runs_only_installed
1111
+ ? null
1112
+ : 'new_run_projection_reader_missing'
1075
1113
  : 'independent_projection_reader_missing'
1076
1114
  : readers.independent_installed
1077
1115
  ? 'deferred_projection_reader_missing'
@@ -1081,6 +1119,7 @@ export async function readRuntimeEventProjectionModes(
1081
1119
  runtimeScope: scope,
1082
1120
  deferred: null,
1083
1121
  independent: null,
1122
+ newRunsOnly: null,
1084
1123
  unavailableReason,
1085
1124
  };
1086
1125
  }
@@ -1091,18 +1130,25 @@ export async function readRuntimeEventProjectionModes(
1091
1130
  const independentExpression = readers.independent_installed
1092
1131
  ? `${schema}.independent_runtime_event_projection()`
1093
1132
  : 'NULL::boolean';
1133
+ const newRunsOnlyExpression = readers.new_runs_only_installed
1134
+ ? `${schema}.new_runs_only_runtime_event_projection()`
1135
+ : 'NULL::boolean';
1094
1136
  const result = await client.query<{
1095
1137
  deferred: boolean | null;
1096
1138
  independent: boolean | null;
1139
+ new_runs_only: boolean | null;
1097
1140
  }>(
1098
1141
  `SELECT ${deferredExpression} AS deferred,
1099
- ${independentExpression} AS independent`,
1142
+ ${independentExpression} AS independent,
1143
+ ${newRunsOnlyExpression} AS new_runs_only`,
1100
1144
  );
1101
1145
  const modes = result.rows[0];
1102
1146
  if (
1103
1147
  !modes ||
1104
1148
  (readers.deferred_installed && typeof modes.deferred !== 'boolean') ||
1105
- (readers.independent_installed && typeof modes.independent !== 'boolean')
1149
+ (readers.independent_installed && typeof modes.independent !== 'boolean') ||
1150
+ (readers.new_runs_only_installed &&
1151
+ typeof modes.new_runs_only !== 'boolean')
1106
1152
  ) {
1107
1153
  throw new Error('Runtime projection mode lookup returned invalid values.');
1108
1154
  }
@@ -1110,6 +1156,7 @@ export async function readRuntimeEventProjectionModes(
1110
1156
  runtimeScope: scope,
1111
1157
  deferred: modes.deferred,
1112
1158
  independent: modes.independent,
1159
+ newRunsOnly: modes.new_runs_only,
1113
1160
  unavailableReason,
1114
1161
  };
1115
1162
  }
@@ -1121,27 +1168,32 @@ export async function inspectRuntimeEventProjection(
1121
1168
  ): Promise<{
1122
1169
  deferred: boolean;
1123
1170
  independent: boolean;
1171
+ newRunsOnly: boolean | null;
1124
1172
  pending: number;
1125
1173
  blocked: number;
1126
1174
  oldestPendingAt: string | null;
1127
1175
  }> {
1128
1176
  const schema = quoteIdent(requiredScope(runtimeScope));
1177
+ const modes = await readRuntimeEventProjectionModes(client, runtimeScope);
1178
+ if (modes.deferred === null || modes.independent === null) {
1179
+ throw new Error(
1180
+ 'Install the deferred projection readers before inspecting the outbox.',
1181
+ );
1182
+ }
1129
1183
  const result = await client.query<{
1130
- deferred: boolean;
1131
- independent: boolean;
1132
1184
  pending: string | number;
1133
1185
  blocked: string | number;
1134
1186
  oldest: Date | string | null;
1135
- }>(`SELECT ${schema}.defer_runtime_event_projection() AS deferred, ${schema}.independent_runtime_event_projection() AS independent,
1136
- count(*) AS pending, count(*) FILTER (WHERE failed_at IS NOT NULL) AS blocked,
1187
+ }>(`SELECT count(*) AS pending, count(*) FILTER (WHERE failed_at IS NOT NULL) AS blocked,
1137
1188
  min(created_at) AS oldest
1138
1189
  FROM ${schema}.outbox
1139
1190
  WHERE delivered_at IS NULL
1140
1191
  AND payload_json->'${RUNTIME_EVENT_DEFERRED_PROJECTION_FIELD}' = 'true'::jsonb`);
1141
1192
  const state = result.rows[0]!;
1142
1193
  return {
1143
- deferred: state.deferred,
1144
- independent: state.independent,
1194
+ deferred: modes.deferred,
1195
+ independent: modes.independent,
1196
+ newRunsOnly: modes.newRunsOnly ?? null,
1145
1197
  pending: Number(state.pending),
1146
1198
  blocked: Number(state.blocked),
1147
1199
  oldestPendingAt: state.oldest === null ? null : iso(state.oldest),
@@ -1173,6 +1225,18 @@ async function installIndependentProjectionMode(
1173
1225
  );
1174
1226
  }
1175
1227
 
1228
+ async function installNewRunProjectionMode(
1229
+ client: PostgresSchedulerQueryClient,
1230
+ schema: string,
1231
+ enabled: boolean,
1232
+ ): Promise<void> {
1233
+ await client.query(`CREATE OR REPLACE FUNCTION ${schema}.new_runs_only_runtime_event_projection()
1234
+ RETURNS boolean LANGUAGE sql VOLATILE SET search_path = pg_catalog AS 'SELECT ${enabled ? 'true' : 'false'}'`);
1235
+ await client.query(
1236
+ `REVOKE ALL ON FUNCTION ${schema}.new_runs_only_runtime_event_projection() FROM PUBLIC`,
1237
+ );
1238
+ }
1239
+
1176
1240
  /**
1177
1241
  * Migration installs readers with synchronous production unchanged. After
1178
1242
  * cutover, the producer persists raw input and only the leased dispatcher
@@ -1198,6 +1262,19 @@ export async function attachRuntimeEventSearchTriggers(
1198
1262
  );
1199
1263
  if (!independentMode.rows[0]?.installed)
1200
1264
  await installIndependentProjectionMode(client, schema, false);
1265
+ const newRunMode = await client.query<{ installed: boolean }>(
1266
+ `SELECT to_regprocedure($1) IS NOT NULL AS installed`,
1267
+ [`${schema}.new_runs_only_runtime_event_projection()`],
1268
+ );
1269
+ if (!newRunMode.rows[0]?.installed)
1270
+ await installNewRunProjectionMode(client, schema, false);
1271
+ await client.query(`CREATE OR REPLACE FUNCTION ${schema}.defer_runtime_event_projection_for_run(rid text)
1272
+ RETURNS boolean LANGUAGE sql VOLATILE SECURITY DEFINER SET search_path = pg_catalog AS $function$
1273
+ SELECT ${schema}.defer_runtime_event_projection() AND
1274
+ (NOT ${schema}.new_runs_only_runtime_event_projection() OR coalesce(
1275
+ (SELECT admission_json->>'runtimeEventProjection' = 'independent'
1276
+ FROM ${schema}.runs WHERE run_id = rid), false))
1277
+ $function$`);
1201
1278
  // Stamp new admissions once. Existing launches never acquire a producer pin
1202
1279
  // on replay or worker upgrade. Ignore a caller-supplied pin before cutover.
1203
1280
  await client.query(`CREATE OR REPLACE FUNCTION ${schema}.pin_runtime_log_identity() RETURNS trigger
@@ -1205,6 +1282,25 @@ export async function attachRuntimeEventSearchTriggers(
1205
1282
  BEGIN
1206
1283
  NEW.launch_json := NEW.launch_json - 'runtimeLogIdentity';
1207
1284
  NEW.admission_json := NEW.admission_json - 'runtimeLogIdentity';
1285
+ NEW.launch_json := NEW.launch_json - 'runtimeEventProjection';
1286
+ NEW.admission_json := NEW.admission_json - 'runtimeEventProjection';
1287
+ IF ${schema}.new_runs_only_runtime_event_projection()
1288
+ AND ${schema}.defer_runtime_event_projection()
1289
+ AND ${schema}.independent_runtime_event_projection() THEN
1290
+ -- Older writers may omit admission_json. Preserve their authority
1291
+ -- using the same transport-free projection as normal admission.
1292
+ NEW.admission_json := coalesce(NEW.admission_json,
1293
+ NEW.launch_json - ARRAY[
1294
+ 'executorToken',
1295
+ 'preloadedDbSessionUnwrapKey',
1296
+ 'preloadedDbSessions',
1297
+ 'submittedAtMs',
1298
+ 'runtimeDeployVersion',
1299
+ 'coordinatorInternalToken',
1300
+ 'vercelProtectionBypassToken'
1301
+ ]::text[])
1302
+ || '{"runtimeEventProjection":"independent"}'::jsonb;
1303
+ END IF;
1208
1304
  IF ${schema}.independent_runtime_event_projection() THEN
1209
1305
  NEW.launch_json := NEW.launch_json || '{"runtimeLogIdentity":"origin"}'::jsonb;
1210
1306
  NEW.admission_json := NEW.admission_json || '{"runtimeLogIdentity":"origin"}'::jsonb;
@@ -1227,7 +1323,7 @@ export async function attachRuntimeEventSearchTriggers(
1227
1323
  IF NEW.run_id IS NULL OR NEW.org_id IS NULL THEN
1228
1324
  RAISE EXCEPTION 'Terminal receipt search projection requires run and organization';
1229
1325
  END IF;
1230
- IF ${schema}.defer_runtime_event_projection() THEN
1326
+ IF ${schema}.defer_runtime_event_projection_for_run(NEW.run_id) THEN
1231
1327
  IF NOT EXISTS (SELECT 1 FROM ${schema}.runs
1232
1328
  WHERE run_id = NEW.run_id AND org_id = NEW.org_id) THEN
1233
1329
  RAISE EXCEPTION 'Terminal receipt search projection has no matching run';
@@ -1388,6 +1484,12 @@ export async function attachRuntimeEventSearchTriggers(
1388
1484
  ON CONFLICT (runtime_scope, org_id, event_id) DO NOTHING RETURNING event_id
1389
1485
  ) SELECT coalesce(array_agg(inserted.event_id ORDER BY entries.ordinal), ARRAY[]::text[])
1390
1486
  INTO fresh FROM inserted JOIN entries ON entries.eid = inserted.event_id;
1487
+ -- The INSERT already proves the content of every fresh identity. Only
1488
+ -- retries or a concurrent uniqueness winner need a journal read-back.
1489
+ -- This fast path serves both inline and background origin projection.
1490
+ IF cardinality(fresh) = jsonb_array_length(item->'lines') THEN
1491
+ RETURN fresh;
1492
+ END IF;
1391
1493
  -- A new READ COMMITTED statement sees a concurrent uniqueness winner.
1392
1494
  -- Tombstones retain digest/identity: retry never restores an expired body.
1393
1495
  SELECT count(*) INTO mismatches
@@ -1432,7 +1534,7 @@ export async function attachRuntimeEventSearchTriggers(
1432
1534
  -- writers lock attempt before Run; this recorder must not invert that.
1433
1535
  -- Stable batches are ordered by the leased background prefix and cursor row.
1434
1536
  -- The legacy alias path still needs its old transaction mutex.
1435
- IF NOT ${schema}.defer_runtime_event_projection() THEN
1537
+ IF NOT ${schema}.defer_runtime_event_projection_for_run(observation.run_id) THEN
1436
1538
  PERFORM pg_advisory_xact_lock(hashtext(${quoteLiteral(scope)}), hashtext(observation.run_id));
1437
1539
  END IF;
1438
1540
  SELECT org_id, play_name, run_log_store = 'planet_scale', status,
@@ -1549,7 +1651,7 @@ export async function attachRuntimeEventSearchTriggers(
1549
1651
  ));
1550
1652
  END IF;
1551
1653
  IF event_batch IS NOT NULL THEN
1552
- IF ${schema}.defer_runtime_event_projection() AND EXISTS (SELECT 1 FROM jsonb_array_elements(event_batch) entry WHERE entry->>'type' = ${RUN_EVENT_KIND_SQL_LITERAL.logAppended} AND (NOT (entry ? 'lineIds') OR jsonb_typeof(entry->'lineIds') IS DISTINCT FROM 'array' OR EXISTS (SELECT 1 FROM jsonb_array_elements(CASE WHEN jsonb_typeof(entry->'lineIds') = 'array' THEN entry->'lineIds' ELSE '[]'::jsonb END) id WHERE id = 'null'::jsonb))) THEN
1654
+ IF ${schema}.defer_runtime_event_projection_for_run(observation.run_id) AND EXISTS (SELECT 1 FROM jsonb_array_elements(event_batch) entry WHERE entry->>'type' = ${RUN_EVENT_KIND_SQL_LITERAL.logAppended} AND (NOT (entry ? 'lineIds') OR jsonb_typeof(entry->'lineIds') IS DISTINCT FROM 'array' OR EXISTS (SELECT 1 FROM jsonb_array_elements(CASE WHEN jsonb_typeof(entry->'lineIds') = 'array' THEN entry->'lineIds' ELSE '[]'::jsonb END) id WHERE id = 'null'::jsonb))) THEN
1553
1655
  PERFORM pg_advisory_xact_lock(hashtext(${quoteLiteral(scope)}), hashtext(observation.run_id));
1554
1656
  END IF;
1555
1657
  -- Normalize old positional writers once per batch under the run mutex.
@@ -2252,7 +2354,7 @@ export async function attachRuntimeEventSearchTriggers(
2252
2354
  DECLARE run_closed boolean; search_payload jsonb;
2253
2355
  BEGIN
2254
2356
  IF NEW.payload_json->'${RUNTIME_EVENT_SEARCH_ONLY_FIELD}' = 'true'::jsonb THEN RETURN NEW; END IF;
2255
- IF ${schema}.defer_runtime_event_projection()
2357
+ IF ${schema}.defer_runtime_event_projection_for_run(NEW.run_id)
2256
2358
  AND NEW.event_type <> ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runCreated} THEN
2257
2359
  IF NEW.event_type = ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents} THEN
2258
2360
  -- One cheap Run fence captures whether ingress preceded terminal
@@ -2378,7 +2480,7 @@ export async function attachRuntimeEventSearchTriggers(
2378
2480
  THEN NEW.runner_log_payload_json->'terminalProgressEvents'
2379
2481
  ELSE '[]'::jsonb END) WITH ORDINALITY AS progress(event, position)
2380
2482
  ));
2381
- IF ${schema}.defer_runtime_event_projection() THEN
2483
+ IF ${schema}.defer_runtime_event_projection_for_run(NEW.run_id) THEN
2382
2484
  INSERT INTO ${schema}.outbox (event_id, run_id, event_type, payload_json, created_at)
2383
2485
  VALUES (observation.event_id, observation.run_id, observation.event_type,
2384
2486
  observation.payload_json,
@@ -2474,6 +2576,8 @@ export async function attachRuntimeEventSearchTriggers(
2474
2576
  await client.query(`REVOKE ALL ON FUNCTION ${schema}.project_outbox_event(${schema}.outbox),
2475
2577
  ${schema}.project_origin_log_batch(${schema}.outbox, jsonb, text, text, boolean, boolean, timestamptz, jsonb, boolean),
2476
2578
  ${schema}.independent_runtime_event_projection(),
2579
+ ${schema}.new_runs_only_runtime_event_projection(),
2580
+ ${schema}.defer_runtime_event_projection_for_run(text),
2477
2581
  ${schema}.pin_runtime_log_identity(),
2478
2582
  ${schema}.materialize_runtime_outbox_event(text, text),
2479
2583
  ${schema}.guard_runtime_outbox_ack(),
@@ -2499,6 +2603,8 @@ export async function hasRuntimeEventSearchShape(
2499
2603
  AND EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = to_regclass('${schema}.outbox')
2500
2604
  AND tgname = 'runtime_outbox_projection_ack_v1' AND tgenabled <> 'D')
2501
2605
  AND to_regprocedure('${schema}.defer_runtime_event_projection()') IS NOT NULL
2606
+ AND to_regprocedure('${schema}.new_runs_only_runtime_event_projection()') IS NOT NULL
2607
+ AND to_regprocedure('${schema}.defer_runtime_event_projection_for_run(text)') IS NOT NULL
2502
2608
  AND to_regclass('runtime_observability.events') IS NOT NULL
2503
2609
  AND to_regclass('runtime_observability.run_log_cursors') IS NOT NULL
2504
2610
  AND EXISTS (SELECT 1 FROM pg_attribute
@@ -9,11 +9,11 @@ import {
9
9
  registerAuthCommands,
10
10
  reportSetupCompleted,
11
11
  resolvePendingAuthClaimForResume
12
- } from "./chunk-7XORS6WQ.mjs";
13
- import "./chunk-5V56XCQN.mjs";
14
- import "./chunk-4PSSDZQB.mjs";
12
+ } from "./chunk-ZGICKTW7.mjs";
13
+ import "./chunk-D55NIPGU.mjs";
14
+ import "./chunk-MPVXXDWH.mjs";
15
15
  import "./chunk-DLIRSHV6.mjs";
16
- import "./chunk-WWPI4GJI.mjs";
16
+ import "./chunk-QACDLYNO.mjs";
17
17
  import "./chunk-NXGCO4JB.mjs";
18
18
  import "./chunk-WZYKRD7T.mjs";
19
19
  import "./chunk-KRD6H754.mjs";
@@ -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 _chunkDF3XJ2V2js = require('./chunk-DF3XJ2V2.js');
13
+ require('./chunk-JNHXSZPB.js');
14
+ require('./chunk-AKE6ZFIJ.js');
15
+ require('./chunk-XNYIZMNQ.js');
16
+ require('./chunk-MZQP7CIL.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 = _chunkDF3XJ2V2js.EXIT_WORKSPACE_MISMATCH; exports.clearPendingClaim = _chunkDF3XJ2V2js.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunkDF3XJ2V2js.clearSatisfiedPendingClaim; exports.handleRegister = _chunkDF3XJ2V2js.handleRegister; exports.handleStatus = _chunkDF3XJ2V2js.handleStatus; exports.handleWait = _chunkDF3XJ2V2js.handleWait; exports.readPendingAuthClaim = _chunkDF3XJ2V2js.readPendingAuthClaim; exports.registerAuthCommands = _chunkDF3XJ2V2js.registerAuthCommands; exports.reportSetupCompleted = _chunkDF3XJ2V2js.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunkDF3XJ2V2js.resolvePendingAuthClaimForResume;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DeeplineClient,
3
3
  iterateCursorPages
4
- } from "./chunk-LLGF6V6I.mjs";
4
+ } from "./chunk-TLTKAJ6S.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-5V56XCQN.mjs";
12
+ } from "./chunk-D55NIPGU.mjs";
13
13
  import {
14
14
  AuthError,
15
15
  ConfigError
16
- } from "./chunk-4PSSDZQB.mjs";
16
+ } from "./chunk-MPVXXDWH.mjs";
17
17
  import "./chunk-DLIRSHV6.mjs";
18
- import "./chunk-WWPI4GJI.mjs";
18
+ import "./chunk-QACDLYNO.mjs";
19
19
  import "./chunk-6IKARAYD.mjs";
20
20
  import {
21
21
  DeeplineError