@opengeni/db 0.7.3 → 0.10.7

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 (70) hide show
  1. package/dist/{chunk-YFQ7SGE4.js → chunk-BMFDXFPA.js} +23 -1
  2. package/dist/chunk-BMFDXFPA.js.map +1 -0
  3. package/dist/chunk-KW526IJA.js +127 -0
  4. package/dist/chunk-KW526IJA.js.map +1 -0
  5. package/dist/{chunk-B22X3IEZ.js → chunk-P6PKXY5W.js} +604 -32
  6. package/dist/chunk-P6PKXY5W.js.map +1 -0
  7. package/dist/index.d.ts +4 -3
  8. package/dist/index.js +7408 -2276
  9. package/dist/index.js.map +1 -1
  10. package/dist/migrate.d.ts +29 -4
  11. package/dist/migrate.js +3 -1
  12. package/dist/provision-roles.d.ts +1122 -73
  13. package/dist/provision-roles.js +1 -1
  14. package/dist/{schema-BN5mB9xZ.d.ts → schema-CqkzrBRS.d.ts} +6967 -4457
  15. package/dist/schema.d.ts +1 -1
  16. package/dist/schema.js +19 -1
  17. package/drizzle/0053_codex_credential_leases.sql +2 -2
  18. package/drizzle/0057_durable_queue_control.sql +1 -1
  19. package/drizzle/0061_session_workflow_wake_outbox.sql +1 -1
  20. package/drizzle/0062_session_list_snapshot_reaper.sql +1 -1
  21. package/drizzle/0063_session_control_mega_foundation.sql +1 -1
  22. package/drizzle/0064_rotation_strategy_sharded_backfill.sql +15 -0
  23. package/drizzle/0065_codex_subscription_overview.sql +168 -0
  24. package/drizzle/0065_session_attempt_quiescence.sql +26 -0
  25. package/drizzle/0065_session_tool_policy.sql +38 -0
  26. package/drizzle/0066_session_interruption_attempt_lookup.sql +4 -0
  27. package/drizzle/0067_session_event_payload_bounds.sql +209 -0
  28. package/drizzle/0068_workspace_control_event_bounds.sql +134 -0
  29. package/drizzle/0069_session_event_history_backfill.sql +32 -0
  30. package/drizzle/0070_session_event_type_sequence_lookup.sql +4 -0
  31. package/drizzle/0071_session_event_monitoring_tail.sql +10 -0
  32. package/drizzle/0072_sessions_workspace_created_id_idx.sql +4 -0
  33. package/drizzle/0073_sessions_workspace_updated_id_idx.sql +4 -0
  34. package/drizzle/0074_session_activity_revisions.sql +72 -0
  35. package/drizzle/0075_sessions_workspace_activity_revision_idx.sql +4 -0
  36. package/drizzle/0076_session_workflow_wake_acl.sql +13 -0
  37. package/drizzle/0077_session_attempt_latest_lookup.sql +4 -0
  38. package/drizzle/0094_quarantine_credential_bearing_catalog_urls.sql +51 -0
  39. package/drizzle/0095_github_existing_installations.sql +84 -0
  40. package/drizzle/0096_session_turn_initiators.sql +97 -0
  41. package/drizzle/0097_host_export_outbox.sql +1220 -0
  42. package/drizzle/0098_usage_events_workspace_session_idx.sql +4 -0
  43. package/drizzle/0099_session_human_input_attempt_owner_index.sql +6 -0
  44. package/drizzle/0100_session_human_input_requests.sql +89 -0
  45. package/drizzle/0101_session_mcp_connection_refs.sql +30 -0
  46. package/drizzle/0102_session_command_receipt_service_actor.sql +16 -0
  47. package/drizzle/0103_host_export_root_session.sql +166 -0
  48. package/drizzle/0104_host_export_root_session_backfill.sql +27 -0
  49. package/drizzle/0105_session_turn_instructions.sql +9 -0
  50. package/drizzle/0106_session_attempt_mcp_approval_policies.sql +29 -0
  51. package/drizzle/0107_host_export_lineage_contract.sql +381 -0
  52. package/drizzle/0108_fence_invalidated_warming_epochs.sql +76 -0
  53. package/package.json +5 -4
  54. package/src/codex-token-resolver.ts +175 -14
  55. package/src/connection-token-resolver.ts +428 -119
  56. package/src/event-payload-sanitizer.ts +88 -20
  57. package/src/index.ts +7208 -1273
  58. package/src/memory-domain.ts +1 -1
  59. package/src/migrate.ts +86 -23
  60. package/src/persistence-errors.ts +252 -0
  61. package/src/provision-roles.ts +42 -0
  62. package/src/schema.ts +658 -34
  63. package/src/session-control.ts +520 -38
  64. package/src/session-queue-commands.ts +385 -61
  65. package/src/session-tool-call-settlement.ts +58 -7
  66. package/src/turn-initiator.ts +155 -0
  67. package/dist/chunk-7LDU7F5P.js +0 -80
  68. package/dist/chunk-7LDU7F5P.js.map +0 -1
  69. package/dist/chunk-B22X3IEZ.js.map +0 -1
  70. package/dist/chunk-YFQ7SGE4.js.map +0 -1
@@ -13,6 +13,7 @@ __export(schema_exports, {
13
13
  capabilityInstallations: () => capabilityInstallations,
14
14
  codexCapacityWaiters: () => codexCapacityWaiters,
15
15
  codexCredentialLeases: () => codexCredentialLeases,
16
+ codexResetRedemptionAttempts: () => codexResetRedemptionAttempts,
16
17
  codexRotationSettings: () => codexRotationSettings,
17
18
  codexSubscriptionCredentials: () => codexSubscriptionCredentials,
18
19
  composerDrafts: () => composerDrafts,
@@ -29,7 +30,13 @@ __export(schema_exports, {
29
30
  enrollments: () => enrollments,
30
31
  fileUploads: () => fileUploads,
31
32
  files: () => files,
33
+ githubInstallationRepositories: () => githubInstallationRepositories,
32
34
  githubInstallations: () => githubInstallations,
35
+ hostExportConfig: () => hostExportConfig,
36
+ hostExportConsumers: () => hostExportConsumers,
37
+ hostExportCursorState: () => hostExportCursorState,
38
+ hostExportDeadLetters: () => hostExportDeadLetters,
39
+ hostExportOutbox: () => hostExportOutbox,
33
40
  importBatches: () => importBatches,
34
41
  integrationOauthClients: () => integrationOauthClients,
35
42
  integrationOauthStateNonces: () => integrationOauthStateNonces,
@@ -55,6 +62,7 @@ __export(schema_exports, {
55
62
  sessionEvents: () => sessionEvents,
56
63
  sessionGoals: () => sessionGoals,
57
64
  sessionHistoryItems: () => sessionHistoryItems,
65
+ sessionHumanInputRequests: () => sessionHumanInputRequests,
58
66
  sessionListSnapshots: () => sessionListSnapshots,
59
67
  sessionMcpServers: () => sessionMcpServers,
60
68
  sessionPendingToolCalls: () => sessionPendingToolCalls,
@@ -79,6 +87,7 @@ __export(schema_exports, {
79
87
  workspaceMemberships: () => workspaceMemberships,
80
88
  workspaceModelPolicies: () => workspaceModelPolicies,
81
89
  workspacePacks: () => workspacePacks,
90
+ workspaceSessionActivityRevisions: () => workspaceSessionActivityRevisions,
82
91
  workspaceVariableSetVariables: () => workspaceVariableSetVariables,
83
92
  workspaceVariableSets: () => workspaceVariableSets,
84
93
  workspaces: () => workspaces
@@ -162,7 +171,9 @@ var workspaceInferenceControls = pgTable(
162
171
  accountId: uuid("account_id").notNull(),
163
172
  revision: bigint("revision", { mode: "number" }).notNull().default(0),
164
173
  workspaceState: text("workspace_state").notNull().default("active"),
165
- workspacePauseRevision: bigint("workspace_pause_revision", { mode: "number" }),
174
+ workspacePauseRevision: bigint("workspace_pause_revision", {
175
+ mode: "number"
176
+ }),
166
177
  reason: text("reason"),
167
178
  changedBy: text("changed_by"),
168
179
  changedAt: timestamp("changed_at", { withTimezone: true }),
@@ -194,6 +205,25 @@ var workspaceInferenceControls = pgTable(
194
205
  )
195
206
  })
196
207
  );
208
+ var workspaceSessionActivityRevisions = pgTable(
209
+ "workspace_session_activity_revisions",
210
+ {
211
+ workspaceId: uuid("workspace_id").primaryKey(),
212
+ accountId: uuid("account_id").notNull(),
213
+ revision: bigint("revision", { mode: "number" }).notNull().default(0)
214
+ },
215
+ (table) => ({
216
+ workspaceAccount: foreignKey({
217
+ name: "workspace_session_activity_revisions_workspace_account_fk",
218
+ columns: [table.workspaceId, table.accountId],
219
+ foreignColumns: [workspaces.id, workspaces.accountId]
220
+ }).onDelete("cascade"),
221
+ revisionValid: check(
222
+ "workspace_session_activity_revisions_revision_check",
223
+ sql`${table.revision} >= 0`
224
+ )
225
+ })
226
+ );
197
227
  var workspaceMemberships = pgTable(
198
228
  "workspace_memberships",
199
229
  {
@@ -221,7 +251,9 @@ var apiKeys = pgTable(
221
251
  {
222
252
  id: uuid("id").primaryKey().defaultRandom(),
223
253
  accountId: uuid("account_id").notNull().references(() => managedAccounts.id, { onDelete: "cascade" }),
224
- workspaceId: uuid("workspace_id").references(() => workspaces.id, { onDelete: "cascade" }),
254
+ workspaceId: uuid("workspace_id").references(() => workspaces.id, {
255
+ onDelete: "cascade"
256
+ }),
225
257
  name: text("name").notNull(),
226
258
  prefix: text("prefix").notNull(),
227
259
  keyHash: text("key_hash").notNull(),
@@ -332,14 +364,29 @@ var codexSubscriptionCredentials = pgTable(
332
364
  // excluded). The writer only ever sets a NON-empty set, so a flaky empty turn
333
365
  // can't false-drop coverage. connectorsCheckedAt is the freshness clock.
334
366
  connectorNamespaces: text("connector_namespaces").array(),
335
- connectorsCheckedAt: timestamp("connectors_checked_at", { withTimezone: true }),
367
+ connectorsCheckedAt: timestamp("connectors_checked_at", {
368
+ withTimezone: true
369
+ }),
336
370
  // Workspace-local, server-held fairness cursor. Provider usage headers are
337
371
  // capacity hints, never the sole allocator: live lease count is ranked first
338
372
  // and this cursor deterministically breaks equal-load/equal-capacity ties.
339
373
  // This flag controls NEW automatic allocations only. Credential health,
340
374
  // refresh, encrypted material, and already-frozen/in-flight turns are
341
- // intentionally independent. OPE-24 owns toggle OCC/audit and product UI.
375
+ // intentionally independent. account eligibility policy owns toggle OCC/audit and product UI.
342
376
  allocatorEnabled: boolean("allocator_enabled").notNull().default(true),
377
+ // Independent OCC/audit sequence for the allocator toggle. Token refresh
378
+ // continues to own `version`; quota/cache writes own neither counter.
379
+ allocatorVersion: integer("allocator_version").notNull().default(1),
380
+ allocatorUpdatedBySubjectId: text("allocator_updated_by_subject_id"),
381
+ allocatorUpdatedAt: timestamp("allocator_updated_at", { withTimezone: true }),
382
+ // Authoritative count-only summary cached from /wham/usage. Detailed rows
383
+ // are never persisted as redemption authority; every first POST preflights
384
+ // the provider's fresh detail endpoint.
385
+ resetCreditAvailableCount: integer("reset_credit_available_count"),
386
+ resetCreditsCheckedAt: timestamp("reset_credits_checked_at", { withTimezone: true }),
387
+ // Set only by a direct Better Auth cookie connection/reconnection. Legacy,
388
+ // configured, delegated, API-key, and agent-created rows remain view-only.
389
+ connectedBySubjectId: text("connected_by_subject_id"),
343
390
  selectionCount: integer("selection_count").notNull().default(0),
344
391
  lastSelectedAt: timestamp("last_selected_at", { withTimezone: true }),
345
392
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
@@ -360,6 +407,69 @@ var codexSubscriptionCredentials = pgTable(
360
407
  )
361
408
  })
362
409
  );
410
+ var codexResetRedemptionAttempts = pgTable(
411
+ "codex_reset_redemption_attempts",
412
+ {
413
+ id: uuid("id").primaryKey(),
414
+ accountId: uuid("account_id").notNull().references(() => managedAccounts.id, { onDelete: "cascade" }),
415
+ workspaceId: uuid("workspace_id").notNull().references(() => workspaces.id, { onDelete: "cascade" }),
416
+ credentialId: uuid("credential_id").notNull(),
417
+ subjectId: text("subject_id").notNull(),
418
+ browserSessionHash: text("browser_session_hash").notNull(),
419
+ creditId: text("credit_id").notNull(),
420
+ upstreamIdempotencyKey: uuid("upstream_idempotency_key").notNull().defaultRandom(),
421
+ status: text("status").notNull().default("processing"),
422
+ outcome: text("outcome"),
423
+ claimHolderId: uuid("claim_holder_id"),
424
+ claimExpiresAt: timestamp("claim_expires_at", { withTimezone: true }),
425
+ confirmationExpiresAt: timestamp("confirmation_expires_at", { withTimezone: true }).notNull(),
426
+ providerStartedAt: timestamp("provider_started_at", { withTimezone: true }),
427
+ completedAt: timestamp("completed_at", { withTimezone: true }),
428
+ lastFailureKind: text("last_failure_kind"),
429
+ retryCount: integer("retry_count").notNull().default(0),
430
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
431
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
432
+ },
433
+ (table) => ({
434
+ workspaceAccount: foreignKey({
435
+ name: "codex_reset_redemption_workspace_account_fk",
436
+ columns: [table.workspaceId, table.accountId],
437
+ foreignColumns: [workspaces.id, workspaces.accountId]
438
+ }).onDelete("cascade"),
439
+ upstreamKey: uniqueIndex("codex_reset_redemption_upstream_key_idx").on(
440
+ table.upstreamIdempotencyKey
441
+ ),
442
+ credentialCredit: uniqueIndex("codex_reset_redemption_credential_credit_idx").on(table.workspaceId, table.credentialId, table.creditId).where(
443
+ sql`${table.status} <> 'completed' or ${table.outcome} in ('reset', 'alreadyRedeemed')`
444
+ ),
445
+ workspaceCredential: index("codex_reset_redemption_workspace_credential_idx").on(
446
+ table.workspaceId,
447
+ table.credentialId,
448
+ table.createdAt
449
+ ),
450
+ claimExpiry: index("codex_reset_redemption_claim_expiry_idx").on(table.claimExpiresAt).where(sql`${table.status} <> 'completed'`),
451
+ statusValid: check(
452
+ "codex_reset_redemption_status_check",
453
+ sql`${table.status} in ('processing', 'provider_started', 'completed')`
454
+ ),
455
+ outcomeValid: check(
456
+ "codex_reset_redemption_outcome_check",
457
+ sql`${table.outcome} is null or ${table.outcome} in ('reset', 'nothingToReset', 'noCredit', 'alreadyRedeemed')`
458
+ ),
459
+ completionConsistent: check(
460
+ "codex_reset_redemption_completed_check",
461
+ sql`(${table.status} = 'completed') = (${table.outcome} is not null and ${table.completedAt} is not null)`
462
+ ),
463
+ retryCountValid: check(
464
+ "codex_reset_redemption_retry_count_check",
465
+ sql`${table.retryCount} >= 0`
466
+ ),
467
+ humanSubjectValid: check(
468
+ "codex_reset_redemption_human_subject_check",
469
+ sql`${table.subjectId} like 'user:_%'`
470
+ )
471
+ })
472
+ );
363
473
  var connections = pgTable(
364
474
  "connections",
365
475
  {
@@ -450,8 +560,8 @@ var codexRotationSettings = pgTable(
450
560
  // code reads this bit; old binaries safely ignore it and keep the legacy
451
561
  // pin/rotation policy.
452
562
  leaseRotationEnabled: boolean("lease_rotation_enabled").notNull().default(false),
453
- rotationStrategy: text("rotation_strategy").notNull().default("most_remaining"),
454
- // P3, inert
563
+ rotationStrategy: text("rotation_strategy").notNull().default("sharded"),
564
+ // sharded-rotation policy: legacy residue; behavior is always sharded
455
565
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
456
566
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
457
567
  },
@@ -512,6 +622,10 @@ var sessions = pgTable(
512
622
  workspaceId: uuid("workspace_id").notNull().references(() => workspaces.id, { onDelete: "cascade" }),
513
623
  status: text("status").notNull().default("queued"),
514
624
  initialMessage: text("initial_message").notNull(),
625
+ // Invisible host context frozen with the winning session create. The
626
+ // initial turn copies this value so an idempotent repair can never adopt a
627
+ // retrying caller's different instructions.
628
+ initialTurnInstructions: text("initial_turn_instructions"),
515
629
  title: text("title"),
516
630
  titleSource: text("title_source"),
517
631
  // Per-session agent persona/system instructions supplied at create (the
@@ -524,6 +638,11 @@ var sessions = pgTable(
524
638
  resources: jsonb("resources").$type().notNull().default([]),
525
639
  tools: jsonb("tools").$type().notNull().default([]),
526
640
  metadata: jsonb("metadata").$type().notNull().default({}),
641
+ // Frozen creator fact. This is used for creation attribution and for the
642
+ // idempotent first-turn repair only; later turns capture their own actor.
643
+ createdByKind: text("created_by_kind").notNull().default("service"),
644
+ createdBySubjectId: text("created_by_subject_id").notNull().default("unattributed-legacy"),
645
+ createdByContext: jsonb("created_by_context").$type().notNull().default({ backfill: true }),
527
646
  model: text("model").notNull(),
528
647
  sandboxBackend: text("sandbox_backend").notNull(),
529
648
  // The OS this session's box runs. Defaults to 'linux' (today's only OS, so
@@ -539,8 +658,8 @@ var sessions = pgTable(
539
658
  // The app generates the uuid and uses it for both id and sandbox_group_id in
540
659
  // one insert — it cannot SQL-default to id (id is defaultRandom()).
541
660
  sandboxGroupId: uuid("sandbox_group_id").notNull(),
542
- // The first-class swappable-sandbox POINTER (bring-your-own-compute M2,
543
- // dossier §10.3). NULL == "use the session's own group sandbox" (the
661
+ // The first-class swappable-sandbox POINTER (bring-your-own-compute M2).
662
+ // NULL == "use the session's own group sandbox" (the
544
663
  // backward-compat default — every existing/new row is a behavior-preserving
545
664
  // no-op). The routing proxy re-reads (active_sandbox_id, active_epoch) PER
546
665
  // TOOL CALL to make a Modal<->selfhosted hot-swap seamless. The FK
@@ -575,6 +694,10 @@ var sessions = pgTable(
575
694
  // Non-default first-party MCP token permissions (manager-style sessions);
576
695
  // null means the fixed worker default set in @opengeni/runtime.
577
696
  firstPartyMcpPermissions: jsonb("first_party_mcp_permissions").$type(),
697
+ // Durable tool-policy origin. NULL is retained for pre-migration rows;
698
+ // mapSession exposes those rows as `legacy` instead of guessing omitted vs
699
+ // explicit [].
700
+ toolPolicy: jsonb("tool_policy").$type(),
578
701
  // The manager session that spawned this one via session_create. Set only
579
702
  // when the creating grant carried a worker-signed sessionId claim (a session
580
703
  // spawning a worker); null for direct API creates and scheduled-task runs.
@@ -605,11 +728,15 @@ var sessions = pgTable(
605
728
  queueTailPosition: bigint("queue_tail_position", { mode: "number" }).notNull().default(0),
606
729
  directControlState: text("direct_control_state").notNull().default("active"),
607
730
  directPauseRevision: bigint("direct_pause_revision", { mode: "number" }),
608
- subtreeRunOverrideRevision: bigint("subtree_run_override_revision", { mode: "number" }),
731
+ subtreeRunOverrideRevision: bigint("subtree_run_override_revision", {
732
+ mode: "number"
733
+ }),
609
734
  controlVersion: bigint("control_version", { mode: "number" }).notNull().default(0),
610
735
  directControlReason: text("direct_control_reason"),
611
736
  directControlChangedBy: text("direct_control_changed_by"),
612
- directControlChangedAt: timestamp("direct_control_changed_at", { withTimezone: true }),
737
+ directControlChangedAt: timestamp("direct_control_changed_at", {
738
+ withTimezone: true
739
+ }),
613
740
  lastSequence: integer("last_sequence").notNull().default(0),
614
741
  // The session's PINNED Codex account (manual override from the in-session
615
742
  // switcher). NULL ⇒ follow the workspace active pointer. FK declared in the
@@ -629,7 +756,11 @@ var sessions = pgTable(
629
756
  // account).
630
757
  codexPinSource: text("codex_pin_source"),
631
758
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
632
- updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
759
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
760
+ // Assigned by the database trigger whenever canonical updated_at activity
761
+ // advances. Legacy rows remain zero until touched; raw delta-only writers
762
+ // intentionally omit updated_at and therefore do not allocate revisions.
763
+ activityRevision: bigint("activity_revision", { mode: "number" }).notNull().default(0)
633
764
  },
634
765
  (table) => ({
635
766
  workspaceIdentity: uniqueIndex("sessions_workspace_id_idx").on(table.workspaceId, table.id),
@@ -637,6 +768,25 @@ var sessions = pgTable(
637
768
  table.workspaceId,
638
769
  table.createdAt
639
770
  ),
771
+ // Model-facing monitoring pages use exact (timestamp,id) keysets. Keep the
772
+ // older prefix index during rolling deploys; these composites serve both
773
+ // deterministic traversal and updatedAfter change scans.
774
+ workspaceCreatedId: index("sessions_workspace_created_id_idx").on(
775
+ table.workspaceId,
776
+ table.createdAt.desc(),
777
+ table.id.desc()
778
+ ),
779
+ workspaceUpdatedId: index("sessions_workspace_updated_id_idx").on(
780
+ table.workspaceId,
781
+ table.updatedAt.desc(),
782
+ table.id.desc()
783
+ ),
784
+ workspaceActivityRevision: index("sessions_workspace_activity_revision_idx").on(
785
+ table.workspaceId,
786
+ table.activityRevision.desc(),
787
+ table.updatedAt.desc(),
788
+ table.id.desc()
789
+ ),
640
790
  variableSet: index("sessions_variable_set_idx").on(table.workspaceId, table.variableSetId),
641
791
  parent: index("sessions_parent_idx").on(table.workspaceId, table.parentSessionId),
642
792
  // Routing index: resolve session_id -> sandbox_group_id at every lease entry
@@ -754,6 +904,9 @@ var sessionMcpServers = pgTable(
754
904
  // Human-approval policy: `true` = every tool requires approval, a string[] of
755
905
  // UNPREFIXED tool names = only those require it, null/absent = auto-run.
756
906
  requireApproval: jsonb("require_approval").$type(),
907
+ // Non-secret pointer resolved at request time by the standalone broker or
908
+ // an embedding host. Unlike headersEncrypted, this is safe to project.
909
+ connectionRef: jsonb("connection_ref").$type(),
757
910
  // Map of header name -> AES-GCM ciphertext. Values are decrypted only by the
758
911
  // worker's run-preparation path and never returned by API helpers.
759
912
  headersEncrypted: jsonb("headers_encrypted").$type().notNull().default({}),
@@ -974,8 +1127,14 @@ var sessionTurns = pgTable(
974
1127
  source: text("source").notNull().default("user"),
975
1128
  position: bigint("position", { mode: "number" }).notNull(),
976
1129
  prompt: text("prompt").notNull(),
1130
+ // Host context for this exact turn. System-level at runtime and deliberately
1131
+ // separate from the visible prompt/event payload.
1132
+ turnInstructions: text("turn_instructions"),
977
1133
  resources: jsonb("resources").$type().notNull().default([]),
978
1134
  tools: jsonb("tools").$type().notNull().default([]),
1135
+ // false = inherit the durable session policy; true = this turn explicitly
1136
+ // replaces it with `tools` after the core subset fence.
1137
+ toolsProvided: boolean("tools_provided").notNull().default(false),
979
1138
  model: text("model").notNull(),
980
1139
  reasoningEffort: text("reasoning_effort").notNull(),
981
1140
  sandboxBackend: text("sandbox_backend").notNull(),
@@ -991,6 +1150,11 @@ var sessionTurns = pgTable(
991
1150
  // the SQL constraint is therefore DEFERRABLE INITIALLY DEFERRED.
992
1151
  activeAttemptId: uuid("active_attempt_id"),
993
1152
  lineage: jsonb("lineage").$type().notNull().default({}),
1153
+ // Required immutable authority captured when the turn is accepted. These
1154
+ // columns are deliberately outside mutable metadata/lineage.
1155
+ initiatorKind: text("initiator_kind").notNull().default("service"),
1156
+ initiatorSubjectId: text("initiator_subject_id").notNull().default("unattributed-legacy"),
1157
+ initiatorContext: jsonb("initiator_context").$type().notNull().default({ backfill: true }),
994
1158
  cancelledBy: text("cancelled_by"),
995
1159
  cancelReason: text("cancel_reason"),
996
1160
  // Atomic per-turn toolspace call budget counter (migration 0043). Incremented
@@ -1033,10 +1197,20 @@ var sessionTurnAttempts = pgTable(
1033
1197
  workerId: text("worker_id"),
1034
1198
  leaseId: text("lease_id"),
1035
1199
  leaseExpiresAt: timestamp("lease_expires_at", { withTimezone: true }),
1036
- verifiedControlRevision: bigint("verified_control_revision", { mode: "number" }).notNull(),
1200
+ verifiedControlRevision: bigint("verified_control_revision", {
1201
+ mode: "number"
1202
+ }).notNull(),
1203
+ // Immutable policy snapshot captured under the session lock at claim.
1204
+ mcpApprovalPolicies: jsonb("mcp_approval_policies").$type().notNull(),
1037
1205
  startedAt: timestamp("started_at", { withTimezone: true }).notNull().defaultNow(),
1038
1206
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1039
- closedAt: timestamp("closed_at", { withTimezone: true })
1207
+ closedAt: timestamp("closed_at", { withTimezone: true }),
1208
+ // The cancelled activity writes this after losing inference, user-visible
1209
+ // output, and workspace-persistence authority. Fenced/idempotent cleanup
1210
+ // and telemetry may still finish. Temporal activity cancellation or
1211
+ // terminalization is transport state only; queue admission and clients use
1212
+ // this durable receipt as the physical-quiescence authority.
1213
+ quiescedAt: timestamp("quiesced_at", { withTimezone: true })
1040
1214
  },
1041
1215
  (table) => ({
1042
1216
  workspaceAccount: foreignKey({
@@ -1058,8 +1232,21 @@ var sessionTurnAttempts = pgTable(
1058
1232
  table.workspaceId,
1059
1233
  table.id
1060
1234
  ),
1235
+ ownershipIdentity: uniqueIndex("session_turn_attempts_human_input_owner_uq").on(
1236
+ table.accountId,
1237
+ table.workspaceId,
1238
+ table.sessionId,
1239
+ table.turnId,
1240
+ table.id
1241
+ ),
1061
1242
  liveTurn: uniqueIndex("session_turn_attempts_live_turn_uq").on(table.workspaceId, table.turnId).where(sql`${table.state} in ('claimed', 'running')`),
1062
1243
  liveSession: uniqueIndex("session_turn_attempts_live_session_uq").on(table.workspaceId, table.sessionId).where(sql`${table.state} in ('claimed', 'running')`),
1244
+ latestSessionAttempt: index("session_turn_attempts_latest_session_idx").on(
1245
+ table.workspaceId,
1246
+ table.sessionId,
1247
+ table.startedAt.desc(),
1248
+ table.id.desc()
1249
+ ),
1063
1250
  dispatch: uniqueIndex("session_turn_attempts_dispatch_uq").on(
1064
1251
  table.workspaceId,
1065
1252
  table.temporalWorkflowRunId,
@@ -1098,7 +1285,9 @@ var sessionCommandReceipts = pgTable(
1098
1285
  targetTurnId: uuid("target_turn_id"),
1099
1286
  operationKey: text("operation_key").notNull(),
1100
1287
  canonicalRequestHash: text("canonical_request_hash").notNull(),
1101
- appliedControlRevision: bigint("applied_control_revision", { mode: "number" }),
1288
+ appliedControlRevision: bigint("applied_control_revision", {
1289
+ mode: "number"
1290
+ }),
1102
1291
  appliedQueueVersion: integer("applied_queue_version"),
1103
1292
  appliedTurnVersion: integer("applied_turn_version"),
1104
1293
  appliedDraftRevision: bigint("applied_draft_revision", { mode: "number" }),
@@ -1143,7 +1332,7 @@ var sessionCommandReceipts = pgTable(
1143
1332
  and ${table.actorAttemptId} is not null
1144
1333
  and ${table.actorSubjectId} is null
1145
1334
  ) or (
1146
- ${table.actorType} in ('human', 'operator')
1335
+ ${table.actorType} in ('human', 'operator', 'service')
1147
1336
  and ${table.actorSubjectId} is not null
1148
1337
  and ${table.actorAttemptId} is null
1149
1338
  )`
@@ -1162,7 +1351,11 @@ var workspaceControlEvents = pgTable(
1162
1351
  action: text("action").notNull(),
1163
1352
  automatic: boolean("automatic").notNull().default(false),
1164
1353
  reason: text("reason"),
1354
+ reasonOriginalBytes: integer("reason_original_bytes"),
1165
1355
  actor: text("actor").notNull(),
1356
+ // Null is the rolling-upgrade shape for untouched, already-bounded legacy
1357
+ // rows. New writes and rewritten poison rows carry exact source byte facts.
1358
+ actorOriginalBytes: integer("actor_original_bytes"),
1166
1359
  occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull().defaultNow()
1167
1360
  },
1168
1361
  (table) => ({
@@ -1257,6 +1450,7 @@ var composerDrafts = pgTable(
1257
1450
  text: text("text").notNull().default(""),
1258
1451
  resources: jsonb("resources").$type().notNull().default([]),
1259
1452
  tools: jsonb("tools").$type().notNull().default([]),
1453
+ toolsProvided: boolean("tools_provided").notNull().default(false),
1260
1454
  model: text("model").notNull(),
1261
1455
  reasoningEffort: text("reasoning_effort").notNull(),
1262
1456
  sourceTurnId: uuid("source_turn_id"),
@@ -1553,6 +1747,39 @@ var sessionEvents = pgTable(
1553
1747
  table.workspaceId,
1554
1748
  table.sessionId,
1555
1749
  table.createdAt
1750
+ ),
1751
+ sessionTypeSequence: index("session_events_workspace_session_type_sequence_idx").on(
1752
+ table.workspaceId,
1753
+ table.sessionId,
1754
+ table.type,
1755
+ table.sequence
1756
+ ),
1757
+ monitoringTail: index("session_events_workspace_session_monitoring_tail_idx").on(table.workspaceId, table.sessionId, table.sequence).where(
1758
+ sql`${table.type} not in ('agent.message.delta', 'agent.reasoning.delta', 'sandbox.command.output.delta', 'terminal.pty.output.delta')`
1759
+ ),
1760
+ payloadBytes: check(
1761
+ "session_events_payload_bytes_check",
1762
+ sql`octet_length(${table.payload}::text) <= 65536`
1763
+ ),
1764
+ typeBytes: check(
1765
+ "session_events_type_bytes_check",
1766
+ sql`octet_length(${table.type}) <= 256 and position(E'\n' in ${table.type}) = 0 and position(E'\r' in ${table.type}) = 0`
1767
+ ),
1768
+ clientEventIdBytes: check(
1769
+ "session_events_client_event_id_bytes_check",
1770
+ sql`${table.clientEventId} is null or octet_length(${table.clientEventId}) <= 1024`
1771
+ ),
1772
+ producerIdBytes: check(
1773
+ "session_events_producer_id_bytes_check",
1774
+ sql`${table.producerId} is null or octet_length(${table.producerId}) <= 1024`
1775
+ ),
1776
+ turnAssociationBytes: check(
1777
+ "session_events_turn_association_bytes_check",
1778
+ sql`${table.turnAssociation} is null or octet_length(${table.turnAssociation}) <= 64`
1779
+ ),
1780
+ duplicateReasonBytes: check(
1781
+ "session_events_duplicate_reason_bytes_check",
1782
+ sql`${table.duplicateReason} is null or octet_length(${table.duplicateReason}) <= 4096`
1556
1783
  )
1557
1784
  })
1558
1785
  );
@@ -1561,7 +1788,9 @@ var agentRunStates = pgTable("agent_run_states", {
1561
1788
  accountId: uuid("account_id").notNull().references(() => managedAccounts.id, { onDelete: "cascade" }),
1562
1789
  workspaceId: uuid("workspace_id").notNull().references(() => workspaces.id, { onDelete: "cascade" }),
1563
1790
  sessionId: uuid("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
1564
- turnId: uuid("turn_id").references(() => sessionTurns.id, { onDelete: "set null" }),
1791
+ turnId: uuid("turn_id").references(() => sessionTurns.id, {
1792
+ onDelete: "set null"
1793
+ }),
1565
1794
  stateVersion: integer("state_version").notNull(),
1566
1795
  serializedRunState: text("serialized_run_state").notNull(),
1567
1796
  pendingApprovals: jsonb("pending_approvals").$type().notNull().default([]),
@@ -1583,6 +1812,79 @@ var agentRunStates = pgTable("agent_run_states", {
1583
1812
  frozenCodexCredentialId: uuid("frozen_codex_credential_id"),
1584
1813
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
1585
1814
  });
1815
+ var sessionHumanInputRequests = pgTable(
1816
+ "session_human_input_requests",
1817
+ {
1818
+ id: uuid("id").primaryKey().defaultRandom(),
1819
+ accountId: uuid("account_id").notNull(),
1820
+ workspaceId: uuid("workspace_id").notNull(),
1821
+ sessionId: uuid("session_id").notNull(),
1822
+ turnId: uuid("turn_id").notNull(),
1823
+ turnGeneration: integer("turn_generation").notNull(),
1824
+ creationAttemptId: uuid("creation_attempt_id").notNull(),
1825
+ toolCallId: text("tool_call_id").notNull(),
1826
+ status: text("status").notNull().default("pending"),
1827
+ questions: jsonb("questions").$type().notNull(),
1828
+ allowSkip: boolean("allow_skip").notNull().default(false),
1829
+ response: jsonb("response").$type(),
1830
+ respondedBy: text("responded_by"),
1831
+ respondedAt: timestamp("responded_at", { withTimezone: true }),
1832
+ expiresAt: timestamp("expires_at", { withTimezone: true }),
1833
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1834
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
1835
+ },
1836
+ (table) => ({
1837
+ creationAttemptOwner: foreignKey({
1838
+ name: "session_human_input_requests_creation_attempt_fk",
1839
+ columns: [
1840
+ table.accountId,
1841
+ table.workspaceId,
1842
+ table.sessionId,
1843
+ table.turnId,
1844
+ table.creationAttemptId
1845
+ ],
1846
+ foreignColumns: [
1847
+ sessionTurnAttempts.accountId,
1848
+ sessionTurnAttempts.workspaceId,
1849
+ sessionTurnAttempts.sessionId,
1850
+ sessionTurnAttempts.turnId,
1851
+ sessionTurnAttempts.id
1852
+ ]
1853
+ }).onDelete("cascade"),
1854
+ toolCall: uniqueIndex("session_human_input_requests_tool_call_uq").on(
1855
+ table.workspaceId,
1856
+ table.sessionId,
1857
+ table.turnId,
1858
+ table.toolCallId
1859
+ ),
1860
+ pendingSession: index("session_human_input_requests_pending_session_idx").on(table.workspaceId, table.sessionId, table.createdAt, table.id).where(sql`${table.status} = 'pending'`),
1861
+ pendingExpiry: index("session_human_input_requests_pending_expiry_idx").on(table.expiresAt, table.id).where(sql`${table.status} = 'pending' and ${table.expiresAt} is not null`),
1862
+ status: check(
1863
+ "session_human_input_requests_status_check",
1864
+ sql`${table.status} in ('pending','answered','skipped','expired','cancelled')`
1865
+ ),
1866
+ generation: check(
1867
+ "session_human_input_requests_generation_check",
1868
+ sql`${table.turnGeneration} > 0`
1869
+ ),
1870
+ toolCallBytes: check(
1871
+ "session_human_input_requests_tool_call_bytes_check",
1872
+ sql`octet_length(${table.toolCallId}) between 1 and 1024`
1873
+ ),
1874
+ questionsBytes: check(
1875
+ "session_human_input_requests_questions_bytes_check",
1876
+ sql`octet_length(${table.questions}::text) <= 49152`
1877
+ ),
1878
+ responseBytes: check(
1879
+ "session_human_input_requests_response_bytes_check",
1880
+ sql`${table.response} is null or octet_length(${table.response}::text) <= 49152`
1881
+ ),
1882
+ actorBytes: check(
1883
+ "session_human_input_requests_actor_bytes_check",
1884
+ sql`${table.respondedBy} is null or octet_length(${table.respondedBy}) <= 1024`
1885
+ )
1886
+ })
1887
+ );
1586
1888
  var sessionHistoryItems = pgTable(
1587
1889
  "session_history_items",
1588
1890
  {
@@ -1590,7 +1892,9 @@ var sessionHistoryItems = pgTable(
1590
1892
  accountId: uuid("account_id").notNull().references(() => managedAccounts.id, { onDelete: "cascade" }),
1591
1893
  workspaceId: uuid("workspace_id").notNull().references(() => workspaces.id, { onDelete: "cascade" }),
1592
1894
  sessionId: uuid("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
1593
- turnId: uuid("turn_id").references(() => sessionTurns.id, { onDelete: "set null" }),
1895
+ turnId: uuid("turn_id").references(() => sessionTurns.id, {
1896
+ onDelete: "set null"
1897
+ }),
1594
1898
  // Numeric (not integer) so the synthetic compaction-summary row can be
1595
1899
  // inserted at a FRACTIONAL position (boundaryPosition - 0.5) that sorts ahead
1596
1900
  // of the kept tail without colliding with — and thus overwriting — the real
@@ -1778,7 +2082,9 @@ var sessionRecordings = pgTable(
1778
2082
  accountId: uuid("account_id").notNull().references(() => managedAccounts.id, { onDelete: "cascade" }),
1779
2083
  workspaceId: uuid("workspace_id").notNull().references(() => workspaces.id, { onDelete: "cascade" }),
1780
2084
  sessionId: uuid("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
1781
- turnId: uuid("turn_id").references(() => sessionTurns.id, { onDelete: "set null" }),
2085
+ turnId: uuid("turn_id").references(() => sessionTurns.id, {
2086
+ onDelete: "set null"
2087
+ }),
1782
2088
  state: text("state", { enum: sessionRecordingStateValues }).notNull(),
1783
2089
  mode: text("mode", { enum: sessionRecordingModeValues }).notNull(),
1784
2090
  codec: text("codec", { enum: sessionRecordingCodecValues }).notNull(),
@@ -1806,7 +2112,9 @@ var workspaceCaptures = pgTable(
1806
2112
  accountId: uuid("account_id").notNull().references(() => managedAccounts.id, { onDelete: "cascade" }),
1807
2113
  workspaceId: uuid("workspace_id").notNull().references(() => workspaces.id, { onDelete: "cascade" }),
1808
2114
  sessionId: uuid("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
1809
- turnId: uuid("turn_id").references(() => sessionTurns.id, { onDelete: "set null" }),
2115
+ turnId: uuid("turn_id").references(() => sessionTurns.id, {
2116
+ onDelete: "set null"
2117
+ }),
1810
2118
  revision: bigint("revision", { mode: "number" }).notNull(),
1811
2119
  leaseEpoch: integer("lease_epoch").notNull(),
1812
2120
  // 'available' on a committed capture. 'failed' reserved for a future two-phase
@@ -1941,7 +2249,9 @@ var deviceEnrollmentRequests = pgTable(
1941
2249
  machineName: text("machine_name"),
1942
2250
  // The exposure the agent REQUESTED (whole-machine in v1; loudly consented at
1943
2251
  // approve). Mirrors the enrollment column domain.
1944
- requestedExposure: text("requested_exposure", { enum: enrollmentExposureValues }).notNull().default("whole-machine"),
2252
+ requestedExposure: text("requested_exposure", {
2253
+ enum: enrollmentExposureValues
2254
+ }).notNull().default("whole-machine"),
1945
2255
  // The agent CAN offer a display (a real screen / Xvfb is available) — gates
1946
2256
  // whether screen-control consent is even meaningful. has_display on the
1947
2257
  // resulting enrollment is derived from this.
@@ -1959,8 +2269,12 @@ var deviceEnrollmentRequests = pgTable(
1959
2269
  approvedAt: timestamp("approved_at", { withTimezone: true }),
1960
2270
  // The enrollment + sandbox the approve produced (acceptance #2: an enrollment
1961
2271
  // row AND a sandbox row appear). Null until approved.
1962
- enrollmentId: uuid("enrollment_id").references(() => enrollments.id, { onDelete: "set null" }),
1963
- sandboxId: uuid("sandbox_id").references(() => sandboxes.id, { onDelete: "set null" }),
2272
+ enrollmentId: uuid("enrollment_id").references(() => enrollments.id, {
2273
+ onDelete: "set null"
2274
+ }),
2275
+ sandboxId: uuid("sandbox_id").references(() => sandboxes.id, {
2276
+ onDelete: "set null"
2277
+ }),
1964
2278
  // The short-TTL expiry; a pending row past this is EXPIRED on poll.
1965
2279
  expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
1966
2280
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
@@ -1987,7 +2301,9 @@ var sandboxes = pgTable(
1987
2301
  workspaceId: uuid("workspace_id").notNull().references(() => workspaces.id, { onDelete: "cascade" }),
1988
2302
  kind: text("kind", { enum: sandboxKindValues }).notNull(),
1989
2303
  name: text("name").notNull(),
1990
- enrollmentId: uuid("enrollment_id").references(() => enrollments.id, { onDelete: "set null" }),
2304
+ enrollmentId: uuid("enrollment_id").references(() => enrollments.id, {
2305
+ onDelete: "set null"
2306
+ }),
1991
2307
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1992
2308
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
1993
2309
  },
@@ -2104,7 +2420,9 @@ var scheduledTaskRuns = pgTable(
2104
2420
  triggerType: text("trigger_type").notNull(),
2105
2421
  scheduledAt: timestamp("scheduled_at", { withTimezone: true }),
2106
2422
  firedAt: timestamp("fired_at", { withTimezone: true }).notNull().defaultNow(),
2107
- sessionId: uuid("session_id").references(() => sessions.id, { onDelete: "set null" }),
2423
+ sessionId: uuid("session_id").references(() => sessions.id, {
2424
+ onDelete: "set null"
2425
+ }),
2108
2426
  triggerEventId: uuid("trigger_event_id"),
2109
2427
  // Stable Temporal producer identity. Activity replay/re-dispatch returns
2110
2428
  // the exact run instead of allocating a second schedule source row.
@@ -2135,6 +2453,8 @@ var githubInstallations = pgTable(
2135
2453
  installationId: integer("installation_id").notNull(),
2136
2454
  accountLogin: text("account_login"),
2137
2455
  accountType: text("account_type"),
2456
+ repositoryScope: text("repository_scope").notNull().default("all"),
2457
+ linkedBySubjectId: text("linked_by_subject_id"),
2138
2458
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
2139
2459
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
2140
2460
  },
@@ -2144,7 +2464,43 @@ var githubInstallations = pgTable(
2144
2464
  table.installationId
2145
2465
  ),
2146
2466
  installation: index("github_installations_installation_idx").on(table.installationId),
2147
- workspace: index("github_installations_workspace_idx").on(table.workspaceId)
2467
+ workspace: index("github_installations_workspace_idx").on(table.workspaceId),
2468
+ repositoryScopeCheck: check(
2469
+ "github_installations_repository_scope_check",
2470
+ sql`${table.repositoryScope} in ('all', 'selected')`
2471
+ )
2472
+ })
2473
+ );
2474
+ var githubInstallationRepositories = pgTable(
2475
+ "github_installation_repositories",
2476
+ {
2477
+ id: uuid("id").primaryKey().defaultRandom(),
2478
+ accountId: uuid("account_id").notNull().references(() => managedAccounts.id, { onDelete: "cascade" }),
2479
+ workspaceId: uuid("workspace_id").notNull().references(() => workspaces.id, { onDelete: "cascade" }),
2480
+ installationId: integer("installation_id").notNull(),
2481
+ repositoryId: bigint("repository_id", { mode: "number" }).notNull(),
2482
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
2483
+ },
2484
+ (table) => ({
2485
+ installationRepository: uniqueIndex("github_install_repo_workspace_installation_repo_idx").on(
2486
+ table.workspaceId,
2487
+ table.installationId,
2488
+ table.repositoryId
2489
+ ),
2490
+ workspaceInstallation: index("github_install_repo_workspace_installation_idx").on(
2491
+ table.workspaceId,
2492
+ table.installationId
2493
+ ),
2494
+ workspaceAccount: foreignKey({
2495
+ columns: [table.workspaceId, table.accountId],
2496
+ foreignColumns: [workspaces.id, workspaces.accountId],
2497
+ name: "github_installation_repositories_workspace_account_fk"
2498
+ }).onDelete("cascade"),
2499
+ installationBinding: foreignKey({
2500
+ columns: [table.workspaceId, table.installationId],
2501
+ foreignColumns: [githubInstallations.workspaceId, githubInstallations.installationId],
2502
+ name: "github_installation_repositories_installation_fk"
2503
+ }).onDelete("cascade")
2148
2504
  })
2149
2505
  );
2150
2506
  var usageEvents = pgTable(
@@ -2159,10 +2515,23 @@ var usageEvents = pgTable(
2159
2515
  unit: text("unit").notNull(),
2160
2516
  sourceResourceType: text("source_resource_type"),
2161
2517
  sourceResourceId: text("source_resource_id"),
2518
+ // Exact execution source for host usage export. These are deliberately
2519
+ // validated soft references rather than cascading foreign keys: usage is
2520
+ // an immutable billing/audit fact and must retain its source identity after
2521
+ // a session or turn is deleted.
2522
+ sessionId: uuid("session_id"),
2523
+ turnId: uuid("turn_id"),
2524
+ turnAttemptId: uuid("turn_attempt_id"),
2525
+ initiatorKind: text("initiator_kind"),
2526
+ initiatorSubjectId: text("initiator_subject_id"),
2527
+ initiatorContext: jsonb("initiator_context").$type().notNull().default({}),
2528
+ origin: text("origin"),
2162
2529
  idempotencyKey: text("idempotency_key").notNull(),
2163
2530
  occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
2164
2531
  recordedAt: timestamp("recorded_at", { withTimezone: true }).notNull().defaultNow(),
2165
- exportedToBillingAt: timestamp("exported_to_billing_at", { withTimezone: true }),
2532
+ exportedToBillingAt: timestamp("exported_to_billing_at", {
2533
+ withTimezone: true
2534
+ }),
2166
2535
  billingProviderEventId: text("billing_provider_event_id")
2167
2536
  },
2168
2537
  (table) => ({
@@ -2176,6 +2545,190 @@ var usageEvents = pgTable(
2176
2545
  table.accountId,
2177
2546
  table.eventType,
2178
2547
  table.occurredAt
2548
+ ),
2549
+ workspaceSession: index("usage_events_workspace_session_idx").on(
2550
+ table.workspaceId,
2551
+ table.sessionId,
2552
+ table.occurredAt
2553
+ ),
2554
+ contextHierarchy: check(
2555
+ "usage_events_context_hierarchy_check",
2556
+ sql`(${table.turnId} is null or ${table.sessionId} is not null)
2557
+ and (${table.turnAttemptId} is null or ${table.turnId} is not null)`
2558
+ ),
2559
+ initiatorConsistent: check(
2560
+ "usage_events_initiator_check",
2561
+ sql`(${table.initiatorKind} is null and ${table.initiatorSubjectId} is null)
2562
+ or (${table.initiatorKind} in ('subject', 'service')
2563
+ and ${table.initiatorSubjectId} is not null
2564
+ and octet_length(${table.initiatorSubjectId}) between 1 and 1024)`
2565
+ ),
2566
+ attributionContextBytes: check(
2567
+ "usage_events_initiator_context_bytes_check",
2568
+ sql`octet_length(${table.initiatorContext}::text) <= 4096`
2569
+ ),
2570
+ originValid: check(
2571
+ "usage_events_origin_check",
2572
+ sql`${table.origin} is null or ${table.origin} in (
2573
+ 'user', 'scheduled_task', 'api', 'goal', 'system', 'compaction'
2574
+ )`
2575
+ )
2576
+ })
2577
+ );
2578
+ var hostExportConfig = pgTable(
2579
+ "host_export_config",
2580
+ {
2581
+ id: integer("id").primaryKey().default(1),
2582
+ sessionEventsEnabled: boolean("session_events_enabled").notNull().default(false),
2583
+ usageEventsEnabled: boolean("usage_events_enabled").notNull().default(false),
2584
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
2585
+ },
2586
+ (table) => ({
2587
+ singleton: check("host_export_config_singleton_check", sql`${table.id} = 1`)
2588
+ })
2589
+ );
2590
+ var hostExportOutbox = pgTable(
2591
+ "host_export_outbox",
2592
+ {
2593
+ id: uuid("id").primaryKey().defaultRandom(),
2594
+ exportKind: text("export_kind").notNull(),
2595
+ exportCursor: bigint("export_cursor", { mode: "bigint" }),
2596
+ sourceId: uuid("source_id").notNull(),
2597
+ accountId: uuid("account_id").notNull(),
2598
+ workspaceId: uuid("workspace_id").notNull(),
2599
+ sessionId: uuid("session_id"),
2600
+ rootSessionId: uuid("root_session_id"),
2601
+ turnId: uuid("turn_id"),
2602
+ turnGeneration: integer("turn_generation"),
2603
+ turnAttemptId: uuid("turn_attempt_id"),
2604
+ sessionSequence: integer("session_sequence"),
2605
+ clientEventId: text("client_event_id"),
2606
+ turnAssociation: text("turn_association"),
2607
+ duplicateOfEventId: uuid("duplicate_of_event_id"),
2608
+ duplicateReason: text("duplicate_reason"),
2609
+ eventType: text("event_type").notNull(),
2610
+ idempotencyKey: text("idempotency_key").notNull(),
2611
+ initiator: jsonb("initiator").$type(),
2612
+ initiatorContext: jsonb("initiator_context").$type().notNull().default({}),
2613
+ origin: text("origin"),
2614
+ payload: jsonb("payload").$type().notNull(),
2615
+ envelopeBytes: integer("envelope_bytes").notNull(),
2616
+ occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
2617
+ sourceRecordedAt: timestamp("source_recorded_at", { withTimezone: true }).notNull(),
2618
+ enqueuedAt: timestamp("enqueued_at", { withTimezone: true }).notNull()
2619
+ },
2620
+ (table) => ({
2621
+ kindValid: check(
2622
+ "host_export_outbox_kind_check",
2623
+ sql`${table.exportKind} in ('session_event', 'usage_event')`
2624
+ ),
2625
+ rootSessionCaptured: check(
2626
+ "host_export_outbox_root_session_check",
2627
+ sql`${table.sessionId} is null or ${table.rootSessionId} is not null`
2628
+ ),
2629
+ sourceUnique: uniqueIndex("host_export_outbox_source_uq").on(table.exportKind, table.sourceId),
2630
+ cursorUnique: uniqueIndex("host_export_outbox_cursor_uq").on(table.exportKind, table.exportCursor).where(sql`${table.exportCursor} is not null`),
2631
+ unassigned: index("host_export_outbox_unassigned_idx").on(table.exportKind, table.enqueuedAt, table.id).where(sql`${table.exportCursor} is null`),
2632
+ unassignedSession: index("host_export_outbox_unassigned_session_idx").on(table.exportKind, table.sessionId, table.sessionSequence).where(sql`${table.exportCursor} is null and ${table.sessionId} is not null`),
2633
+ contextBytes: check(
2634
+ "host_export_outbox_context_bytes_check",
2635
+ sql`octet_length(${table.initiatorContext}::text) <= 4096`
2636
+ ),
2637
+ originValid: check(
2638
+ "host_export_outbox_origin_check",
2639
+ sql`${table.origin} is null or ${table.origin} in (
2640
+ 'user', 'scheduled_task', 'api', 'goal', 'system', 'compaction'
2641
+ )`
2642
+ )
2643
+ })
2644
+ );
2645
+ var hostExportCursorState = pgTable(
2646
+ "host_export_cursor_state",
2647
+ {
2648
+ exportKind: text("export_kind").primaryKey(),
2649
+ nextCursor: bigint("next_cursor", { mode: "bigint" }).notNull().default(1n),
2650
+ prunedThrough: bigint("pruned_through", { mode: "bigint" }).notNull().default(0n),
2651
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
2652
+ },
2653
+ (table) => ({
2654
+ kindValid: check(
2655
+ "host_export_cursor_state_kind_check",
2656
+ sql`${table.exportKind} in ('session_event', 'usage_event')`
2657
+ ),
2658
+ cursorValid: check(
2659
+ "host_export_cursor_state_next_check",
2660
+ sql`${table.nextCursor} > 0 and ${table.prunedThrough} >= 0
2661
+ and ${table.prunedThrough} < ${table.nextCursor}`
2662
+ )
2663
+ })
2664
+ );
2665
+ var hostExportConsumers = pgTable(
2666
+ "host_export_consumers",
2667
+ {
2668
+ id: uuid("id").primaryKey().defaultRandom(),
2669
+ consumerId: text("consumer_id").notNull(),
2670
+ exportKind: text("export_kind").notNull(),
2671
+ checkpoint: bigint("checkpoint", { mode: "bigint" }).notNull().default(0n),
2672
+ enabled: boolean("enabled").notNull().default(true),
2673
+ leaseToken: uuid("lease_token"),
2674
+ leaseHolderId: text("lease_holder_id"),
2675
+ leaseExpiresAt: timestamp("lease_expires_at", { withTimezone: true }),
2676
+ leaseFrom: bigint("lease_from", { mode: "bigint" }),
2677
+ leaseThrough: bigint("lease_through", { mode: "bigint" }),
2678
+ consecutiveFailures: integer("consecutive_failures").notNull().default(0),
2679
+ nextAttemptAt: timestamp("next_attempt_at", { withTimezone: true }).notNull().defaultNow(),
2680
+ lastError: text("last_error"),
2681
+ lastErrorAt: timestamp("last_error_at", { withTimezone: true }),
2682
+ blockedAt: timestamp("blocked_at", { withTimezone: true }),
2683
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
2684
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
2685
+ },
2686
+ (table) => ({
2687
+ consumerKind: uniqueIndex("host_export_consumers_kind_id_uq").on(
2688
+ table.exportKind,
2689
+ table.consumerId
2690
+ ),
2691
+ kindValid: check(
2692
+ "host_export_consumers_kind_check",
2693
+ sql`${table.exportKind} in ('session_event', 'usage_event')`
2694
+ ),
2695
+ checkpointValid: check("host_export_consumers_checkpoint_check", sql`${table.checkpoint} >= 0`),
2696
+ due: index("host_export_consumers_due_idx").on(
2697
+ table.enabled,
2698
+ table.blockedAt,
2699
+ table.nextAttemptAt
2700
+ )
2701
+ })
2702
+ );
2703
+ var hostExportDeadLetters = pgTable(
2704
+ "host_export_dead_letters",
2705
+ {
2706
+ id: uuid("id").primaryKey().defaultRandom(),
2707
+ consumerId: text("consumer_id").notNull(),
2708
+ exportKind: text("export_kind").notNull(),
2709
+ exportCursor: bigint("export_cursor", { mode: "bigint" }).notNull(),
2710
+ sourceId: uuid("source_id").notNull(),
2711
+ reason: text("reason").notNull(),
2712
+ envelope: jsonb("envelope").$type().notNull(),
2713
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
2714
+ },
2715
+ (table) => ({
2716
+ consumerCursor: uniqueIndex("host_export_dead_letters_consumer_cursor_uq").on(
2717
+ table.exportKind,
2718
+ table.consumerId,
2719
+ table.exportCursor
2720
+ ),
2721
+ kindValid: check(
2722
+ "host_export_dead_letters_kind_check",
2723
+ sql`${table.exportKind} in ('session_event', 'usage_event')`
2724
+ ),
2725
+ reasonValid: check(
2726
+ "host_export_dead_letters_reason_check",
2727
+ sql`length(${table.reason}) between 1 and 500`
2728
+ ),
2729
+ envelopeBytes: check(
2730
+ "host_export_dead_letters_envelope_bytes_check",
2731
+ sql`pg_column_size(${table.envelope}) <= 114688`
2179
2732
  )
2180
2733
  })
2181
2734
  );
@@ -2184,7 +2737,9 @@ var creditLedgerEntries = pgTable(
2184
2737
  {
2185
2738
  id: uuid("id").primaryKey().defaultRandom(),
2186
2739
  accountId: uuid("account_id").notNull().references(() => managedAccounts.id, { onDelete: "cascade" }),
2187
- workspaceId: uuid("workspace_id").references(() => workspaces.id, { onDelete: "set null" }),
2740
+ workspaceId: uuid("workspace_id").references(() => workspaces.id, {
2741
+ onDelete: "set null"
2742
+ }),
2188
2743
  type: text("type").notNull(),
2189
2744
  amountMicros: bigint("amount_micros", { mode: "number" }).notNull(),
2190
2745
  currency: text("currency").notNull().default("usd"),
@@ -2237,8 +2792,12 @@ var auditEvents = pgTable(
2237
2792
  "audit_events",
2238
2793
  {
2239
2794
  id: uuid("id").primaryKey().defaultRandom(),
2240
- accountId: uuid("account_id").references(() => managedAccounts.id, { onDelete: "set null" }),
2241
- workspaceId: uuid("workspace_id").references(() => workspaces.id, { onDelete: "set null" }),
2795
+ accountId: uuid("account_id").references(() => managedAccounts.id, {
2796
+ onDelete: "set null"
2797
+ }),
2798
+ workspaceId: uuid("workspace_id").references(() => workspaces.id, {
2799
+ onDelete: "set null"
2800
+ }),
2242
2801
  subjectId: text("subject_id"),
2243
2802
  action: text("action").notNull(),
2244
2803
  targetType: text("target_type"),
@@ -2321,8 +2880,12 @@ var capabilityCatalogItems = pgTable(
2321
2880
  "capability_catalog_items",
2322
2881
  {
2323
2882
  id: text("id").notNull(),
2324
- accountId: uuid("account_id").references(() => managedAccounts.id, { onDelete: "cascade" }),
2325
- workspaceId: uuid("workspace_id").references(() => workspaces.id, { onDelete: "cascade" }),
2883
+ accountId: uuid("account_id").references(() => managedAccounts.id, {
2884
+ onDelete: "cascade"
2885
+ }),
2886
+ workspaceId: uuid("workspace_id").references(() => workspaces.id, {
2887
+ onDelete: "cascade"
2888
+ }),
2326
2889
  kind: text("kind").notNull(),
2327
2890
  source: text("source").notNull().default("manual"),
2328
2891
  name: text("name").notNull(),
@@ -2555,11 +3118,13 @@ export {
2555
3118
  managedAccounts,
2556
3119
  workspaces,
2557
3120
  workspaceInferenceControls,
3121
+ workspaceSessionActivityRevisions,
2558
3122
  workspaceMemberships,
2559
3123
  apiKeys,
2560
3124
  workspaceVariableSets,
2561
3125
  workspaceVariableSetVariables,
2562
3126
  codexSubscriptionCredentials,
3127
+ codexResetRedemptionAttempts,
2563
3128
  connections,
2564
3129
  integrationOauthClients,
2565
3130
  integrationOauthStateNonces,
@@ -2589,6 +3154,7 @@ export {
2589
3154
  codexCapacityWaiters,
2590
3155
  sessionEvents,
2591
3156
  agentRunStates,
3157
+ sessionHumanInputRequests,
2592
3158
  sessionHistoryItems,
2593
3159
  sessionPendingToolCalls,
2594
3160
  sandboxSessionEnvelopes,
@@ -2614,7 +3180,13 @@ export {
2614
3180
  scheduledTasks,
2615
3181
  scheduledTaskRuns,
2616
3182
  githubInstallations,
3183
+ githubInstallationRepositories,
2617
3184
  usageEvents,
3185
+ hostExportConfig,
3186
+ hostExportOutbox,
3187
+ hostExportCursorState,
3188
+ hostExportConsumers,
3189
+ hostExportDeadLetters,
2618
3190
  creditLedgerEntries,
2619
3191
  billingCustomers,
2620
3192
  stripeWebhookEvents,
@@ -2631,4 +3203,4 @@ export {
2631
3203
  rigChanges,
2632
3204
  schema_exports
2633
3205
  };
2634
- //# sourceMappingURL=chunk-B22X3IEZ.js.map
3206
+ //# sourceMappingURL=chunk-P6PKXY5W.js.map