@opengeni/db 0.7.0 → 0.7.2

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.
package/src/schema.ts CHANGED
@@ -60,11 +60,6 @@ export const workspaces = pgTable(
60
60
  // Growth-ready per-workspace settings bag (migration 0045). Holds memoryEnabled
61
61
  // and future workspace-level toggles; validated/merged via WorkspaceSettingsSchema.
62
62
  settings: jsonb("settings").$type<Record<string, unknown>>().notNull().default({}),
63
- inferenceState: text("inference_state").notNull().default("active"),
64
- inferenceGeneration: integer("inference_generation").notNull().default(0),
65
- inferenceReason: text("inference_reason"),
66
- inferenceChangedBy: text("inference_changed_by"),
67
- inferenceChangedAt: timestamp("inference_changed_at", { withTimezone: true }),
68
63
  // The workspace's default rig (migration 0047). NULL ⇒ no default; sessions
69
64
  // created without an explicit rig ride no rig (today's behavior exactly). FK
70
65
  // (-> rigs(id) ON DELETE SET NULL) lives in migration 0047, not a Drizzle
@@ -83,6 +78,49 @@ export const workspaces = pgTable(
83
78
  }),
84
79
  );
85
80
 
81
+ // One mandatory workspace-wide admission barrier. Every inference-admitting
82
+ // transaction locks this row before it touches a session; Pause/Resume and
83
+ // foreground Send/Steer advance its monotonic revision under FOR UPDATE.
84
+ export const workspaceInferenceControls = pgTable(
85
+ "workspace_inference_controls",
86
+ {
87
+ workspaceId: uuid("workspace_id").primaryKey(),
88
+ accountId: uuid("account_id").notNull(),
89
+ revision: bigint("revision", { mode: "number" }).notNull().default(0),
90
+ workspaceState: text("workspace_state").notNull().default("active"),
91
+ workspacePauseRevision: bigint("workspace_pause_revision", { mode: "number" }),
92
+ reason: text("reason"),
93
+ changedBy: text("changed_by"),
94
+ changedAt: timestamp("changed_at", { withTimezone: true }),
95
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
96
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
97
+ },
98
+ (table) => ({
99
+ workspaceAccount: foreignKey({
100
+ name: "workspace_inference_controls_workspace_account_fk",
101
+ columns: [table.workspaceId, table.accountId],
102
+ foreignColumns: [workspaces.id, workspaces.accountId],
103
+ }).onDelete("cascade"),
104
+ workspaceAccountIdentity: uniqueIndex("workspace_inference_controls_workspace_account_uq").on(
105
+ table.workspaceId,
106
+ table.accountId,
107
+ ),
108
+ stateValid: check(
109
+ "workspace_inference_controls_state_check",
110
+ sql`${table.workspaceState} in ('active', 'paused')`,
111
+ ),
112
+ pauseRevisionConsistent: check(
113
+ "workspace_inference_controls_pause_revision_check",
114
+ sql`(${table.workspaceState} = 'active' and ${table.workspacePauseRevision} is null)
115
+ or (${table.workspaceState} = 'paused' and ${table.workspacePauseRevision} is not null)`,
116
+ ),
117
+ revisionValid: check(
118
+ "workspace_inference_controls_revision_check",
119
+ sql`${table.revision} >= 0 and (${table.workspacePauseRevision} is null or ${table.workspacePauseRevision} <= ${table.revision})`,
120
+ ),
121
+ }),
122
+ );
123
+
86
124
  export const workspaceMemberships = pgTable(
87
125
  "workspace_memberships",
88
126
  {
@@ -580,17 +618,13 @@ export const sessions = pgTable(
580
618
  queueVersion: integer("queue_version").notNull().default(0),
581
619
  queueHeadPosition: bigint("queue_head_position", { mode: "number" }).notNull().default(0),
582
620
  queueTailPosition: bigint("queue_tail_position", { mode: "number" }).notNull().default(0),
583
- controlState: text("control_state").notNull().default("active"),
584
- controlGeneration: integer("control_generation").notNull().default(0),
585
- controlReason: text("control_reason"),
586
- controlChangedBy: text("control_changed_by"),
587
- controlChangedAt: timestamp("control_changed_at", { withTimezone: true }),
588
- pendingControlEventId: uuid("pending_control_event_id"),
589
- pendingControlKind: text("pending_control_kind"),
590
- pendingControlExpectedTurnId: uuid("pending_control_expected_turn_id"),
591
- pendingControlExpectedGeneration: integer("pending_control_expected_generation"),
592
- pendingControlExpectedAttemptId: uuid("pending_control_expected_attempt_id"),
593
- workspaceRunExceptionGeneration: integer("workspace_run_exception_generation"),
621
+ directControlState: text("direct_control_state").notNull().default("active"),
622
+ directPauseRevision: bigint("direct_pause_revision", { mode: "number" }),
623
+ subtreeRunOverrideRevision: bigint("subtree_run_override_revision", { mode: "number" }),
624
+ controlVersion: bigint("control_version", { mode: "number" }).notNull().default(0),
625
+ directControlReason: text("direct_control_reason"),
626
+ directControlChangedBy: text("direct_control_changed_by"),
627
+ directControlChangedAt: timestamp("direct_control_changed_at", { withTimezone: true }),
594
628
  lastSequence: integer("last_sequence").notNull().default(0),
595
629
  // The session's PINNED Codex account (manual override from the in-session
596
630
  // switcher). NULL ⇒ follow the workspace active pointer. FK declared in the
@@ -1054,6 +1088,10 @@ export const sessionTurns = pgTable(
1054
1088
  metadata: jsonb("metadata").$type<Record<string, unknown>>().notNull().default({}),
1055
1089
  version: integer("version").notNull().default(1),
1056
1090
  executionGeneration: integer("execution_generation").notNull().default(0),
1091
+ // Composite FK to session_turn_attempts is installed by migration 0063.
1092
+ // It lives in SQL because attempts carry the reciprocal turn FK and because
1093
+ // the claim transaction preallocates this ID before inserting the attempt;
1094
+ // the SQL constraint is therefore DEFERRABLE INITIALLY DEFERRED.
1057
1095
  activeAttemptId: uuid("active_attempt_id"),
1058
1096
  lineage: jsonb("lineage").$type<Record<string, unknown>>().notNull().default({}),
1059
1097
  cancelledBy: text("cancelled_by"),
@@ -1084,6 +1122,310 @@ export const sessionTurns = pgTable(
1084
1122
  }),
1085
1123
  );
1086
1124
 
1125
+ // First-class ownership for one accepted execution attempt. A workflow may
1126
+ // preallocate id, but this row is inserted only by the activity transaction
1127
+ // that actually claims the logical turn and registers its exact dispatch.
1128
+ export const sessionTurnAttempts = pgTable(
1129
+ "session_turn_attempts",
1130
+ {
1131
+ id: uuid("id").primaryKey(),
1132
+ accountId: uuid("account_id").notNull(),
1133
+ workspaceId: uuid("workspace_id").notNull(),
1134
+ sessionId: uuid("session_id").notNull(),
1135
+ turnId: uuid("turn_id").notNull(),
1136
+ executionGeneration: integer("execution_generation").notNull(),
1137
+ state: text("state").notNull().default("claimed"),
1138
+ outcome: text("outcome"),
1139
+ temporalWorkflowId: text("temporal_workflow_id").notNull(),
1140
+ temporalWorkflowRunId: text("temporal_workflow_run_id").notNull(),
1141
+ temporalActivityId: text("temporal_activity_id").notNull(),
1142
+ workerId: text("worker_id"),
1143
+ leaseId: text("lease_id"),
1144
+ leaseExpiresAt: timestamp("lease_expires_at", { withTimezone: true }),
1145
+ verifiedControlRevision: bigint("verified_control_revision", { mode: "number" }).notNull(),
1146
+ startedAt: timestamp("started_at", { withTimezone: true }).notNull().defaultNow(),
1147
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1148
+ closedAt: timestamp("closed_at", { withTimezone: true }),
1149
+ },
1150
+ (table) => ({
1151
+ workspaceAccount: foreignKey({
1152
+ name: "session_turn_attempts_workspace_account_fk",
1153
+ columns: [table.workspaceId, table.accountId],
1154
+ foreignColumns: [workspaces.id, workspaces.accountId],
1155
+ }).onDelete("cascade"),
1156
+ workspaceSession: foreignKey({
1157
+ name: "session_turn_attempts_workspace_session_fk",
1158
+ columns: [table.workspaceId, table.sessionId],
1159
+ foreignColumns: [sessions.workspaceId, sessions.id],
1160
+ }).onDelete("restrict"),
1161
+ workspaceTurn: foreignKey({
1162
+ name: "session_turn_attempts_workspace_turn_fk",
1163
+ columns: [table.workspaceId, table.turnId],
1164
+ foreignColumns: [sessionTurns.workspaceId, sessionTurns.id],
1165
+ }).onDelete("restrict"),
1166
+ workspaceIdentity: uniqueIndex("session_turn_attempts_workspace_id_uq").on(
1167
+ table.workspaceId,
1168
+ table.id,
1169
+ ),
1170
+ liveTurn: uniqueIndex("session_turn_attempts_live_turn_uq")
1171
+ .on(table.workspaceId, table.turnId)
1172
+ .where(sql`${table.state} in ('claimed', 'running')`),
1173
+ liveSession: uniqueIndex("session_turn_attempts_live_session_uq")
1174
+ .on(table.workspaceId, table.sessionId)
1175
+ .where(sql`${table.state} in ('claimed', 'running')`),
1176
+ dispatch: uniqueIndex("session_turn_attempts_dispatch_uq").on(
1177
+ table.workspaceId,
1178
+ table.temporalWorkflowRunId,
1179
+ table.temporalActivityId,
1180
+ ),
1181
+ leaseExpiry: index("session_turn_attempts_lease_expiry_idx")
1182
+ .on(table.leaseExpiresAt, table.workspaceId, table.sessionId)
1183
+ .where(sql`${table.state} in ('claimed', 'running')`),
1184
+ stateValid: check(
1185
+ "session_turn_attempts_state_check",
1186
+ sql`${table.state} in ('claimed', 'running', 'closed')`,
1187
+ ),
1188
+ outcomeValid: check(
1189
+ "session_turn_attempts_outcome_check",
1190
+ sql`${table.outcome} is null or ${table.outcome} in (
1191
+ 'completed', 'failed', 'cancelled', 'superseded', 'requires_action',
1192
+ 'interrupted_recoverable', 'lease_lost_recoverable', 'pre_cutover_closed'
1193
+ )`,
1194
+ ),
1195
+ closedConsistent: check(
1196
+ "session_turn_attempts_closed_check",
1197
+ sql`(${table.state} = 'closed' and ${table.outcome} is not null and ${table.closedAt} is not null)
1198
+ or (${table.state} <> 'closed' and ${table.outcome} is null and ${table.closedAt} is null)`,
1199
+ ),
1200
+ }),
1201
+ );
1202
+
1203
+ // One durable idempotency/operation record for every queue, control,
1204
+ // foreground Send/Steer, and Agent MCP mutation. The database migration owns
1205
+ // the NULLS NOT DISTINCT uniqueness form because Drizzle does not model it.
1206
+ export const sessionCommandReceipts = pgTable(
1207
+ "session_command_receipts",
1208
+ {
1209
+ id: uuid("id").primaryKey().defaultRandom(),
1210
+ accountId: uuid("account_id").notNull(),
1211
+ workspaceId: uuid("workspace_id").notNull(),
1212
+ actorType: text("actor_type").notNull(),
1213
+ actorSubjectId: text("actor_subject_id"),
1214
+ actorAttemptId: uuid("actor_attempt_id"),
1215
+ action: text("action").notNull(),
1216
+ targetSessionId: uuid("target_session_id"),
1217
+ targetTurnId: uuid("target_turn_id"),
1218
+ operationKey: text("operation_key").notNull(),
1219
+ canonicalRequestHash: text("canonical_request_hash").notNull(),
1220
+ appliedControlRevision: bigint("applied_control_revision", { mode: "number" }),
1221
+ appliedQueueVersion: integer("applied_queue_version"),
1222
+ appliedTurnVersion: integer("applied_turn_version"),
1223
+ appliedDraftRevision: bigint("applied_draft_revision", { mode: "number" }),
1224
+ result: jsonb("result").$type<Record<string, unknown>>().notNull().default({}),
1225
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1226
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1227
+ },
1228
+ (table) => ({
1229
+ workspaceAccount: foreignKey({
1230
+ name: "session_command_receipts_workspace_account_fk",
1231
+ columns: [table.workspaceId, table.accountId],
1232
+ foreignColumns: [workspaces.id, workspaces.accountId],
1233
+ }).onDelete("cascade"),
1234
+ actorAttempt: foreignKey({
1235
+ name: "session_command_receipts_actor_attempt_fk",
1236
+ columns: [table.workspaceId, table.actorAttemptId],
1237
+ foreignColumns: [sessionTurnAttempts.workspaceId, sessionTurnAttempts.id],
1238
+ }).onDelete("restrict"),
1239
+ targetSession: foreignKey({
1240
+ name: "session_command_receipts_target_session_fk",
1241
+ columns: [table.workspaceId, table.targetSessionId],
1242
+ foreignColumns: [sessions.workspaceId, sessions.id],
1243
+ }).onDelete("restrict"),
1244
+ targetTurn: foreignKey({
1245
+ name: "session_command_receipts_target_turn_fk",
1246
+ columns: [table.workspaceId, table.targetTurnId],
1247
+ foreignColumns: [sessionTurns.workspaceId, sessionTurns.id],
1248
+ }).onDelete("restrict"),
1249
+ workspaceIdentity: uniqueIndex("session_command_receipts_workspace_id_uq").on(
1250
+ table.workspaceId,
1251
+ table.id,
1252
+ ),
1253
+ targetCreated: index("session_command_receipts_target_created_idx").on(
1254
+ table.workspaceId,
1255
+ table.targetSessionId,
1256
+ table.createdAt,
1257
+ ),
1258
+ actorValid: check(
1259
+ "session_command_receipts_actor_check",
1260
+ sql`(
1261
+ ${table.actorType} = 'agent_attempt'
1262
+ and ${table.actorAttemptId} is not null
1263
+ and ${table.actorSubjectId} is null
1264
+ ) or (
1265
+ ${table.actorType} in ('human', 'operator')
1266
+ and ${table.actorSubjectId} is not null
1267
+ and ${table.actorAttemptId} is null
1268
+ )`,
1269
+ ),
1270
+ }),
1271
+ );
1272
+
1273
+ // One workspace-scoped durable invalidation per committed control revision.
1274
+ // This is deliberately separate from conversation/session events: a parent or
1275
+ // workspace Pause can change thousands of effective projections without
1276
+ // manufacturing one event (or queue row) per descendant.
1277
+ export const workspaceControlEvents = pgTable(
1278
+ "workspace_control_events",
1279
+ {
1280
+ id: uuid("id").primaryKey().defaultRandom(),
1281
+ accountId: uuid("account_id").notNull(),
1282
+ workspaceId: uuid("workspace_id").notNull(),
1283
+ revision: bigint("revision", { mode: "number" }).notNull(),
1284
+ scope: text("scope").notNull(),
1285
+ rootSessionId: uuid("root_session_id"),
1286
+ action: text("action").notNull(),
1287
+ automatic: boolean("automatic").notNull().default(false),
1288
+ reason: text("reason"),
1289
+ actor: text("actor").notNull(),
1290
+ occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull().defaultNow(),
1291
+ },
1292
+ (table) => ({
1293
+ workspaceAccount: foreignKey({
1294
+ name: "workspace_control_events_workspace_account_fk",
1295
+ columns: [table.workspaceId, table.accountId],
1296
+ foreignColumns: [workspaces.id, workspaces.accountId],
1297
+ }).onDelete("cascade"),
1298
+ rootSession: foreignKey({
1299
+ name: "workspace_control_events_root_session_fk",
1300
+ columns: [table.workspaceId, table.rootSessionId],
1301
+ foreignColumns: [sessions.workspaceId, sessions.id],
1302
+ }).onDelete("restrict"),
1303
+ workspaceRevision: uniqueIndex("workspace_control_events_workspace_revision_uq").on(
1304
+ table.workspaceId,
1305
+ table.revision,
1306
+ ),
1307
+ revisionValid: check("workspace_control_events_revision_check", sql`${table.revision} > 0`),
1308
+ shapeValid: check(
1309
+ "workspace_control_events_shape_check",
1310
+ sql`(${table.scope} = 'workspace' and ${table.rootSessionId} is null)
1311
+ or (${table.scope} = 'session' and ${table.rootSessionId} is not null)`,
1312
+ ),
1313
+ actionValid: check(
1314
+ "workspace_control_events_action_check",
1315
+ sql`${table.action} in ('pause', 'resume')`,
1316
+ ),
1317
+ }),
1318
+ );
1319
+
1320
+ // An interruption is an independently durable request against an exact live
1321
+ // attempt. Multiple Pause/Steer causes coexist; no scalar session field owns
1322
+ // delivery or settlement.
1323
+ export const sessionAttemptInterruptions = pgTable(
1324
+ "session_attempt_interruptions",
1325
+ {
1326
+ id: uuid("id").primaryKey().defaultRandom(),
1327
+ accountId: uuid("account_id").notNull(),
1328
+ workspaceId: uuid("workspace_id").notNull(),
1329
+ sessionId: uuid("session_id").notNull(),
1330
+ operationId: uuid("operation_id").notNull(),
1331
+ attemptId: uuid("attempt_id").notNull(),
1332
+ kind: text("kind").notNull(),
1333
+ controlRevision: bigint("control_revision", { mode: "number" }).notNull(),
1334
+ state: text("state").notNull().default("pending"),
1335
+ requestedAt: timestamp("requested_at", { withTimezone: true }).notNull().defaultNow(),
1336
+ deliveredAt: timestamp("delivered_at", { withTimezone: true }),
1337
+ acknowledgedAt: timestamp("acknowledged_at", { withTimezone: true }),
1338
+ settledAt: timestamp("settled_at", { withTimezone: true }),
1339
+ },
1340
+ (table) => ({
1341
+ workspaceAccount: foreignKey({
1342
+ name: "session_attempt_interruptions_workspace_account_fk",
1343
+ columns: [table.workspaceId, table.accountId],
1344
+ foreignColumns: [workspaces.id, workspaces.accountId],
1345
+ }).onDelete("cascade"),
1346
+ workspaceSession: foreignKey({
1347
+ name: "session_attempt_interruptions_workspace_session_fk",
1348
+ columns: [table.workspaceId, table.sessionId],
1349
+ foreignColumns: [sessions.workspaceId, sessions.id],
1350
+ }).onDelete("restrict"),
1351
+ operation: foreignKey({
1352
+ name: "session_attempt_interruptions_operation_fk",
1353
+ columns: [table.workspaceId, table.operationId],
1354
+ foreignColumns: [sessionCommandReceipts.workspaceId, sessionCommandReceipts.id],
1355
+ }).onDelete("restrict"),
1356
+ attempt: foreignKey({
1357
+ name: "session_attempt_interruptions_attempt_fk",
1358
+ columns: [table.workspaceId, table.attemptId],
1359
+ foreignColumns: [sessionTurnAttempts.workspaceId, sessionTurnAttempts.id],
1360
+ }).onDelete("restrict"),
1361
+ operationAttempt: uniqueIndex("session_attempt_interruptions_operation_attempt_uq").on(
1362
+ table.operationId,
1363
+ table.attemptId,
1364
+ ),
1365
+ unsettled: index("session_attempt_interruptions_unsettled_idx")
1366
+ .on(table.workspaceId, table.sessionId, table.requestedAt)
1367
+ .where(sql`${table.state} in ('pending', 'delivered', 'acknowledged')`),
1368
+ kindValid: check(
1369
+ "session_attempt_interruptions_kind_check",
1370
+ sql`${table.kind} in ('session_pause', 'workspace_pause', 'steer', 'maintenance')`,
1371
+ ),
1372
+ stateValid: check(
1373
+ "session_attempt_interruptions_state_check",
1374
+ sql`${table.state} in ('pending', 'delivered', 'acknowledged', 'settled', 'rejected_stale')`,
1375
+ ),
1376
+ }),
1377
+ );
1378
+
1379
+ // Private, authenticated-subject composer truth. Editing a queued prompt and
1380
+ // restoring it here is one transaction; human drafts are never agent-visible.
1381
+ export const composerDrafts = pgTable(
1382
+ "composer_drafts",
1383
+ {
1384
+ id: uuid("id").primaryKey().defaultRandom(),
1385
+ accountId: uuid("account_id").notNull(),
1386
+ workspaceId: uuid("workspace_id").notNull(),
1387
+ sessionId: uuid("session_id").notNull(),
1388
+ subjectId: text("subject_id").notNull(),
1389
+ revision: bigint("revision", { mode: "number" }).notNull().default(1),
1390
+ text: text("text").notNull().default(""),
1391
+ resources: jsonb("resources").$type<unknown[]>().notNull().default([]),
1392
+ tools: jsonb("tools").$type<unknown[]>().notNull().default([]),
1393
+ model: text("model").notNull(),
1394
+ reasoningEffort: text("reasoning_effort").notNull(),
1395
+ sourceTurnId: uuid("source_turn_id"),
1396
+ sourceTurnVersion: integer("source_turn_version"),
1397
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1398
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1399
+ },
1400
+ (table) => ({
1401
+ workspaceAccount: foreignKey({
1402
+ name: "composer_drafts_workspace_account_fk",
1403
+ columns: [table.workspaceId, table.accountId],
1404
+ foreignColumns: [workspaces.id, workspaces.accountId],
1405
+ }).onDelete("cascade"),
1406
+ workspaceSession: foreignKey({
1407
+ name: "composer_drafts_workspace_session_fk",
1408
+ columns: [table.workspaceId, table.sessionId],
1409
+ foreignColumns: [sessions.workspaceId, sessions.id],
1410
+ }).onDelete("cascade"),
1411
+ sourceTurn: foreignKey({
1412
+ name: "composer_drafts_source_turn_fk",
1413
+ columns: [table.workspaceId, table.sourceTurnId],
1414
+ foreignColumns: [sessionTurns.workspaceId, sessionTurns.id],
1415
+ }).onDelete("restrict"),
1416
+ subjectSession: uniqueIndex("composer_drafts_subject_session_uq").on(
1417
+ table.workspaceId,
1418
+ table.sessionId,
1419
+ table.subjectId,
1420
+ ),
1421
+ subjectValid: check(
1422
+ "composer_drafts_subject_check",
1423
+ sql`length(btrim(${table.subjectId})) > 0`,
1424
+ ),
1425
+ revisionValid: check("composer_drafts_revision_check", sql`${table.revision} >= 1`),
1426
+ }),
1427
+ );
1428
+
1087
1429
  export const sessionSystemUpdates = pgTable(
1088
1430
  "session_system_updates",
1089
1431
  {
@@ -1116,6 +1458,18 @@ export const sessionSystemUpdates = pgTable(
1116
1458
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1117
1459
  },
1118
1460
  (table) => ({
1461
+ kindValid: check(
1462
+ "system_updates_kind_check",
1463
+ sql`${table.kind} in ('scheduled_occurrence', 'goal_continuation', 'agent_message', 'agent_steer_instruction', 'child_terminal_result')`,
1464
+ ),
1465
+ payloadKindValid: check(
1466
+ "system_updates_payload_kind_check",
1467
+ sql`${table.payload} ->> 'type' = ${table.kind}`,
1468
+ ),
1469
+ stateValid: check(
1470
+ "system_updates_state_check",
1471
+ sql`${table.state} in ('pending', 'deferred', 'delivered', 'cancelled', 'superseded', 'failed')`,
1472
+ ),
1119
1473
  dedupe: uniqueIndex("session_system_updates_dedupe_uq").on(
1120
1474
  table.workspaceId,
1121
1475
  table.sessionId,
@@ -1130,46 +1484,6 @@ export const sessionSystemUpdates = pgTable(
1130
1484
  }),
1131
1485
  );
1132
1486
 
1133
- /**
1134
- * Stable idempotency record for session and workspace pause operations.
1135
- * `result` contains only durable IDs/state
1136
- * snapshots; delivery repair always revalidates those exact IDs against the
1137
- * current pending fence instead of consulting an unrelated newer operation.
1138
- */
1139
- export const runtimeControlOperations = pgTable(
1140
- "runtime_control_operations",
1141
- {
1142
- id: uuid("id").primaryKey().defaultRandom(),
1143
- accountId: uuid("account_id")
1144
- .notNull()
1145
- .references(() => managedAccounts.id, { onDelete: "cascade" }),
1146
- workspaceId: uuid("workspace_id")
1147
- .notNull()
1148
- .references(() => workspaces.id, { onDelete: "cascade" }),
1149
- scope: text("scope").notNull(),
1150
- targetId: uuid("target_id").notNull(),
1151
- clientEventId: text("client_event_id").notNull(),
1152
- requestedState: text("requested_state").notNull(),
1153
- expectedState: text("expected_state"),
1154
- expectedGeneration: integer("expected_generation"),
1155
- result: jsonb("result").$type<Record<string, unknown>>().notNull().default({}),
1156
- createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1157
- updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1158
- },
1159
- (table) => ({
1160
- idempotency: uniqueIndex("runtime_control_operations_client_uq").on(
1161
- table.workspaceId,
1162
- table.clientEventId,
1163
- ),
1164
- target: index("runtime_control_operations_target_idx").on(
1165
- table.workspaceId,
1166
- table.scope,
1167
- table.targetId,
1168
- table.createdAt,
1169
- ),
1170
- }),
1171
- );
1172
-
1173
1487
  /**
1174
1488
  * Durable child-terminal producer outbox. The source terminal transaction
1175
1489
  * inserts this row; fan-in delivery marks it delivered inside
@@ -1208,6 +1522,14 @@ export const sessionSystemUpdateOutbox = pgTable(
1208
1522
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1209
1523
  },
1210
1524
  (table) => ({
1525
+ kindValid: check(
1526
+ "system_update_outbox_kind_check",
1527
+ sql`${table.kind} = 'child_terminal_result'`,
1528
+ ),
1529
+ payloadKindValid: check(
1530
+ "system_update_outbox_payload_kind_check",
1531
+ sql`${table.payload} ->> 'type' = 'child_terminal_result'`,
1532
+ ),
1211
1533
  dedupe: uniqueIndex("session_system_update_outbox_dedupe_uq").on(
1212
1534
  table.workspaceId,
1213
1535
  table.dedupeKey,
@@ -1315,9 +1637,9 @@ export const sessionGoals = pgTable(
1315
1637
  //
1316
1638
  // The session/goal/turn foreign keys are declared in migration 0053 so the
1317
1639
  // table keeps the same composite workspace-integrity posture as credential
1318
- // leases. OPE-18 may later supply a non-zero controlGeneration; legacy rows use
1319
- // zero and remain fenced by goal version + session/queue/turn truth. OPE-32
1320
- // supplies policyHash when accepted-turn pool routing lands.
1640
+ // leases. Control is evaluated independently at admission and never changes a
1641
+ // capacity waiter's identity. OPE-32 supplies policyHash when accepted-turn
1642
+ // pool routing lands.
1321
1643
  export const codexCapacityWaiters = pgTable(
1322
1644
  "codex_capacity_waiters",
1323
1645
  {
@@ -1335,7 +1657,6 @@ export const codexCapacityWaiters = pgTable(
1335
1657
  generation: integer("generation").notNull().default(1),
1336
1658
  status: text("status").notNull().default("waiting"), // waiting | resumed | superseded
1337
1659
  goalVersion: integer("goal_version").notNull(),
1338
- controlGeneration: integer("control_generation").notNull().default(0),
1339
1660
  policyHash: text("policy_hash"),
1340
1661
  earliestResetAt: timestamp("earliest_reset_at", { withTimezone: true }),
1341
1662
  nextCheckAt: timestamp("next_check_at", { withTimezone: true }).notNull(),
@@ -1402,6 +1723,11 @@ export const sessionEvents = pgTable(
1402
1723
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1403
1724
  },
1404
1725
  (table) => ({
1726
+ workspaceAttempt: foreignKey({
1727
+ name: "session_events_workspace_attempt_fk",
1728
+ columns: [table.workspaceId, table.turnAttemptId],
1729
+ foreignColumns: [sessionTurnAttempts.workspaceId, sessionTurnAttempts.id],
1730
+ }).onDelete("restrict"),
1405
1731
  sessionSequence: uniqueIndex("session_events_workspace_session_sequence_idx").on(
1406
1732
  table.workspaceId,
1407
1733
  table.sessionId,
@@ -1542,6 +1868,11 @@ export const sessionPendingToolCalls = pgTable(
1542
1868
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1543
1869
  },
1544
1870
  (table) => ({
1871
+ workspaceAttempt: foreignKey({
1872
+ name: "pending_tool_calls_workspace_attempt_fk",
1873
+ columns: [table.workspaceId, table.attemptId],
1874
+ foreignColumns: [sessionTurnAttempts.workspaceId, sessionTurnAttempts.id],
1875
+ }).onDelete("restrict"),
1545
1876
  turnCall: uniqueIndex("session_pending_tool_calls_turn_call_idx").on(
1546
1877
  table.workspaceId,
1547
1878
  table.turnId,