@opengeni/db 3.6.0 → 3.7.4-canary.0

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 (92) hide show
  1. package/dist/automations.d.ts +4 -0
  2. package/dist/canonical-human-identities.js +3 -3
  3. package/dist/{chunk-UGDVSQ6U.js → chunk-3ZMN4EXC.js} +2 -2
  4. package/dist/{chunk-744DFC65.js → chunk-6FIVOJ3V.js} +96 -6
  5. package/dist/chunk-6FIVOJ3V.js.map +1 -0
  6. package/dist/{chunk-UJ2EW3QI.js → chunk-DXJ2WY6W.js} +427 -85
  7. package/dist/chunk-DXJ2WY6W.js.map +1 -0
  8. package/dist/{chunk-CDMMSUWJ.js → chunk-JP6IYGYI.js} +3 -3
  9. package/dist/{chunk-Q5YUGQVK.js → chunk-JS3AWDKZ.js} +3 -3
  10. package/dist/{chunk-G3732M3T.js → chunk-LHKB62GC.js} +2 -2
  11. package/dist/{chunk-2NT476HD.js → chunk-QL4AHBYD.js} +2 -2
  12. package/dist/{chunk-IW6O6G7R.js → chunk-VDXHLVDE.js} +2 -2
  13. package/dist/{chunk-WW7AJ5IC.js → chunk-ZTSJPFDH.js} +5 -7
  14. package/dist/chunk-ZTSJPFDH.js.map +1 -0
  15. package/dist/codex-token-resolver.d.ts +12 -1
  16. package/dist/company-profile-agent-admin.d.ts +4 -2
  17. package/dist/company-profile-agent-policy.d.ts +20 -0
  18. package/dist/company-profile-schema.d.ts +573 -0
  19. package/dist/editable-artifact-durable-export.js +2 -2
  20. package/dist/editable-artifacts.js +3 -3
  21. package/dist/index.d.ts +487 -20
  22. package/dist/index.js +9489 -6041
  23. package/dist/index.js.map +1 -1
  24. package/dist/managed-auth-session-sets.js +3 -3
  25. package/dist/managed-human-provisioning.d.ts +3 -3
  26. package/dist/memory-domain.d.ts +5 -3
  27. package/dist/model-catalog.d.ts +153 -0
  28. package/dist/pr-review.d.ts +9 -0
  29. package/dist/provision-roles.js +1 -1
  30. package/dist/runtime-posture.d.ts +7 -7
  31. package/dist/schema.d.ts +1069 -6
  32. package/dist/schema.js +17 -1
  33. package/dist/session-background-commands.js +3 -3
  34. package/dist/session-control.d.ts +75 -5
  35. package/dist/session-queue-commands.d.ts +19 -0
  36. package/dist/session-tenancy.js +3 -3
  37. package/dist/user-resource-authority.d.ts +8 -0
  38. package/dist/video-generation.js +3 -3
  39. package/dist/xai-subscription.d.ts +8 -0
  40. package/drizzle/0369_local_human_personal_authority.sql +350 -0
  41. package/drizzle/0370_workspace_member_management_scope.sql +98 -0
  42. package/drizzle/0371_workspace_member_candidate_inventory.sql +128 -0
  43. package/drizzle/0372_ordered_variable_set_runtime_authority.sql +287 -0
  44. package/drizzle/0373_sandbox_shared_preparation.sql +59 -0
  45. package/drizzle/0374_session_event_cursors.sql +315 -0
  46. package/drizzle/0375_session_recovery_observability.sql +73 -0
  47. package/drizzle/0376_organization_workspace_inventory.sql +88 -0
  48. package/drizzle/0377_scoped_rig_health_projection.sql +80 -0
  49. package/drizzle/0378_scoped_rig_health_audit_timestamp.sql +77 -0
  50. package/drizzle/0379_session_event_raw_lane_activation.sql +518 -0
  51. package/drizzle/0380_autonomous_company_profile_agent_policy.sql +829 -0
  52. package/drizzle/0381_organization_codex_subscription_inheritance.sql +720 -0
  53. package/drizzle/0382_organization_api_key_provenance.sql +91 -0
  54. package/drizzle/0383_codex_cooldown_reconciliation.sql +51 -0
  55. package/drizzle/0384_codex_cooldown_revision_guard_privileges.sql +6 -0
  56. package/drizzle/0385_connected_machine_legacy_tilde_workdirs.sql +25 -0
  57. package/drizzle/0386_local_organization_administration.sql +157 -0
  58. package/drizzle/0387_bound_host_export_session_payloads.sql +165 -0
  59. package/drizzle/0388_sandbox_provider_deadline_interactions.sql +491 -0
  60. package/drizzle/0389_model_catalog_and_gateway_custom_models.sql +241 -0
  61. package/package.json +6 -6
  62. package/src/automations.ts +9 -1
  63. package/src/codex-token-resolver.ts +26 -1
  64. package/src/company-brain-governed-writes.ts +30 -1
  65. package/src/company-profile-agent-admin.ts +68 -1
  66. package/src/company-profile-agent-policy.ts +126 -0
  67. package/src/company-profile-schema.ts +115 -1
  68. package/src/database.ts +3 -5
  69. package/src/index.ts +4473 -570
  70. package/src/insights.ts +21 -7
  71. package/src/managed-human-provisioning.ts +3 -3
  72. package/src/memory-domain.ts +9 -4
  73. package/src/model-catalog.ts +682 -0
  74. package/src/organization-membership-lifecycle.ts +0 -1
  75. package/src/pr-review.ts +19 -0
  76. package/src/provision-roles.ts +83 -4
  77. package/src/runtime-posture.ts +26 -0
  78. package/src/schema.ts +259 -10
  79. package/src/session-control.ts +347 -59
  80. package/src/session-queue-commands.ts +303 -122
  81. package/src/session-tool-call-settlement.ts +34 -7
  82. package/src/user-resource-authority.ts +56 -0
  83. package/src/xai-subscription.ts +66 -14
  84. package/dist/chunk-744DFC65.js.map +0 -1
  85. package/dist/chunk-UJ2EW3QI.js.map +0 -1
  86. package/dist/chunk-WW7AJ5IC.js.map +0 -1
  87. /package/dist/{chunk-UGDVSQ6U.js.map → chunk-3ZMN4EXC.js.map} +0 -0
  88. /package/dist/{chunk-CDMMSUWJ.js.map → chunk-JP6IYGYI.js.map} +0 -0
  89. /package/dist/{chunk-Q5YUGQVK.js.map → chunk-JS3AWDKZ.js.map} +0 -0
  90. /package/dist/{chunk-G3732M3T.js.map → chunk-LHKB62GC.js.map} +0 -0
  91. /package/dist/{chunk-2NT476HD.js.map → chunk-QL4AHBYD.js.map} +0 -0
  92. /package/dist/{chunk-IW6O6G7R.js.map → chunk-VDXHLVDE.js.map} +0 -0
package/src/pr-review.ts CHANGED
@@ -318,6 +318,8 @@ export async function createPrReviewRepositoryBinding(
318
318
  eventTypes: string[];
319
319
  configuration: Record<string, unknown>;
320
320
  sessionTemplate: AutomationSessionTemplate;
321
+ /** Trusted database-only admission seam. Throwing rolls the binding and trigger back. */
322
+ beforeCreateCommit?: (tx: Database) => Promise<void>;
321
323
  },
322
324
  ): Promise<PrReviewRepositoryBinding> {
323
325
  return await withRlsContext(db, input, async (scopedDb) => {
@@ -345,6 +347,7 @@ export async function createPrReviewRepositoryBinding(
345
347
  "PR Review repository provider does not match its app",
346
348
  );
347
349
  }
350
+ await input.beforeCreateCommit?.(tx);
348
351
  const bindingId = randomUUID();
349
352
  const [trigger] = await tx
350
353
  .insert(schema.automationTriggers)
@@ -842,6 +845,16 @@ export async function updatePrReviewRepositoryBinding(
842
845
  model?: string | null;
843
846
  additionalInstructions?: string | null;
844
847
  status?: "active" | "disabled";
848
+ /** Trusted database-only admission seam. Throwing rolls the binding revision back. */
849
+ beforeUpdateCommit?: (
850
+ tx: Database,
851
+ context: {
852
+ currentModel: string | null;
853
+ currentStatus: "active" | "disabled";
854
+ nextModel: string | null;
855
+ nextStatus: "active" | "disabled";
856
+ },
857
+ ) => Promise<void>;
845
858
  },
846
859
  ): Promise<PrReviewRepositoryBinding | null> {
847
860
  return await withRlsContext(db, input, async (scopedDb) => {
@@ -891,6 +904,12 @@ export async function updatePrReviewRepositoryBinding(
891
904
  : input.additionalInstructions,
892
905
  status: input.status ?? (current.binding.status as "active" | "disabled"),
893
906
  };
907
+ await input.beforeUpdateCommit?.(tx, {
908
+ currentModel: current.binding.model,
909
+ currentStatus: current.binding.status as "active" | "disabled",
910
+ nextModel: next.model,
911
+ nextStatus: next.status,
912
+ });
894
913
  const nextRevision = current.trigger.currentRevision + 1;
895
914
  await tx.insert(schema.automationTriggerRevisions).values({
896
915
  triggerId: current.trigger.id,
@@ -294,7 +294,9 @@ END $$;
294
294
  }
295
295
 
296
296
  async function ensureLoginRole(sql: postgres.Sql, role: string, password: string): Promise<void> {
297
- await sql.unsafe(`
297
+ await executeRoleConvergence(
298
+ sql,
299
+ `
298
300
  DO $$
299
301
  BEGIN
300
302
  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = ${literal(role)}) THEN
@@ -303,7 +305,8 @@ BEGIN
303
305
  EXECUTE format('ALTER ROLE %I LOGIN PASSWORD %L', ${literal(role)}, ${literal(password)});
304
306
  END IF;
305
307
  END $$;
306
- `);
308
+ `,
309
+ );
307
310
  }
308
311
 
309
312
  async function ensureRestrictedAppLoginRole(
@@ -311,7 +314,9 @@ async function ensureRestrictedAppLoginRole(
311
314
  role: string,
312
315
  password: string,
313
316
  ): Promise<void> {
314
- await sql.unsafe(`
317
+ await executeRoleConvergence(
318
+ sql,
319
+ `
315
320
  DO $$
316
321
  BEGIN
317
322
  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = ${literal(role)}) THEN
@@ -339,7 +344,41 @@ BEGIN
339
344
  );
340
345
  END IF;
341
346
  END $$;
342
- `);
347
+ `,
348
+ );
349
+ }
350
+
351
+ const ROLE_CONVERGENCE_MAX_ATTEMPTS = 20;
352
+
353
+ function isRetryableConcurrentRoleMutation(error: unknown): boolean {
354
+ const details = error as { code?: unknown; message?: unknown; routine?: unknown };
355
+ return (
356
+ (details.code === "XX000" &&
357
+ details.message === "tuple concurrently updated" &&
358
+ details.routine === "simple_heap_update") ||
359
+ (details.code === "42710" &&
360
+ typeof details.message === "string" &&
361
+ /^role ".+" already exists$/u.test(details.message))
362
+ );
363
+ }
364
+
365
+ async function executeRoleConvergence(sql: postgres.Sql, statement: string): Promise<void> {
366
+ // Roles live in a cluster-global catalog. Two otherwise independent
367
+ // databases can therefore race an identical CREATE/ALTER during parallel
368
+ // deployment or test setup. PostgreSQL exposes no cross-database advisory
369
+ // lock, so retry only its exact concurrent-catalog outcomes and keep every
370
+ // other provisioning failure immediate.
371
+ for (let attempt = 1; attempt <= ROLE_CONVERGENCE_MAX_ATTEMPTS; attempt += 1) {
372
+ try {
373
+ await sql.unsafe(statement);
374
+ return;
375
+ } catch (error) {
376
+ if (!isRetryableConcurrentRoleMutation(error) || attempt === ROLE_CONVERGENCE_MAX_ATTEMPTS) {
377
+ throw error;
378
+ }
379
+ await new Promise((resolve) => setTimeout(resolve, Math.min(25 * attempt, 250)));
380
+ }
381
+ }
343
382
  }
344
383
 
345
384
  /**
@@ -494,6 +533,8 @@ async function grantAppRoleIfSchemaExists(
494
533
  "list_organization_invitations(uuid,text,uuid,integer)",
495
534
  "get_organization_administration_overview(uuid,text)",
496
535
  "get_workspace_kind(uuid,uuid)",
536
+ "resolve_workspace_codex_subscription_source(uuid,uuid)",
537
+ "list_organization_workspace_ids(uuid)",
497
538
  "organization_workspace_command(jsonb)",
498
539
  "resolve_organization_workspace_removal_subject(uuid,text,uuid)",
499
540
  "prepare_organization_workspace_member_removal(jsonb)",
@@ -1063,6 +1104,18 @@ BEGIN
1063
1104
  ${literal(role)}
1064
1105
  );
1065
1106
  END IF;
1107
+ IF to_regprocedure(
1108
+ format(
1109
+ '%I.propose_company_profile_for_attempt_v2(uuid,uuid,uuid,uuid,uuid,integer,uuid,uuid,text,text,text)',
1110
+ ${literal(schema)}
1111
+ )
1112
+ ) IS NOT NULL THEN
1113
+ EXECUTE format(
1114
+ 'GRANT EXECUTE ON FUNCTION %I.propose_company_profile_for_attempt_v2(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, text, text, text) TO %I',
1115
+ ${literal(schema)},
1116
+ ${literal(role)}
1117
+ );
1118
+ END IF;
1066
1119
  IF to_regprocedure(
1067
1120
  format(
1068
1121
  '%I.confirm_company_profile_for_attempt(uuid,uuid,uuid,uuid,uuid,integer,uuid,uuid,uuid)',
@@ -1075,6 +1128,27 @@ BEGIN
1075
1128
  ${literal(role)}
1076
1129
  );
1077
1130
  END IF;
1131
+ IF to_regprocedure(
1132
+ format('%I.get_company_profile_agent_policy(uuid,uuid,text)', ${literal(schema)})
1133
+ ) IS NOT NULL THEN
1134
+ EXECUTE format(
1135
+ 'GRANT EXECUTE ON FUNCTION %I.get_company_profile_agent_policy(uuid, uuid, text) TO %I',
1136
+ ${literal(schema)},
1137
+ ${literal(role)}
1138
+ );
1139
+ END IF;
1140
+ IF to_regprocedure(
1141
+ format(
1142
+ '%I.update_company_profile_agent_policy(uuid,uuid,text,text,bigint,uuid)',
1143
+ ${literal(schema)}
1144
+ )
1145
+ ) IS NOT NULL THEN
1146
+ EXECUTE format(
1147
+ 'GRANT EXECUTE ON FUNCTION %I.update_company_profile_agent_policy(uuid, uuid, text, text, bigint, uuid) TO %I',
1148
+ ${literal(schema)},
1149
+ ${literal(role)}
1150
+ );
1151
+ END IF;
1078
1152
  IF to_regprocedure(
1079
1153
  format(
1080
1154
  '%I.workspace_learning_policy_apply_activation(uuid,text,uuid,uuid,uuid,uuid,bigint,text,text,text)',
@@ -1661,6 +1735,11 @@ BEGIN
1661
1735
  EXECUTE format('REVOKE ALL ON FUNCTION %I.authorize_session_attempt_personal_resource_reads(uuid, uuid, uuid) FROM PUBLIC', ${literal(schema)});
1662
1736
  EXECUTE format('GRANT EXECUTE ON FUNCTION %I.authorize_session_attempt_personal_resource_reads(uuid, uuid, uuid) TO %I', ${literal(schema)}, ${literal(role)});
1663
1737
  END IF;
1738
+ IF to_regprocedure(format('%I.issue_self_local_connection_use_grant(uuid,uuid,uuid,text,boolean)', ${literal(schema)}))
1739
+ IS NOT NULL THEN
1740
+ EXECUTE format('REVOKE ALL ON FUNCTION %I.issue_self_local_connection_use_grant(uuid, uuid, uuid, text, boolean) FROM PUBLIC', ${literal(schema)});
1741
+ EXECUTE format('GRANT EXECUTE ON FUNCTION %I.issue_self_local_connection_use_grant(uuid, uuid, uuid, text, boolean) TO %I', ${literal(schema)}, ${literal(role)});
1742
+ END IF;
1664
1743
  IF to_regprocedure(format('%I.resolve_connection_use_authority(uuid,uuid,uuid,jsonb)', ${literal(schema)}))
1665
1744
  IS NOT NULL THEN
1666
1745
  EXECUTE format('REVOKE ALL ON FUNCTION %I.list_self_connection_authorities(uuid) FROM PUBLIC', ${literal(schema)});
@@ -91,6 +91,8 @@ const ORGANIZATION_MEMBERSHIP_LIFECYCLE_ROUTINES = [
91
91
  "list_organization_administration_members(uuid, text)",
92
92
  "get_organization_administration_overview(uuid, text)",
93
93
  "get_workspace_kind(uuid, uuid)",
94
+ "resolve_workspace_codex_subscription_source(uuid, uuid)",
95
+ "list_organization_workspace_ids(uuid)",
94
96
  "organization_workspace_command(jsonb)",
95
97
  "resolve_organization_workspace_removal_subject(uuid, text, uuid)",
96
98
  "prepare_organization_workspace_member_removal(jsonb)",
@@ -212,6 +214,7 @@ const USER_RESOURCE_LIFECYCLE_ROUTINES = [
212
214
  "accept_turn_personal_resource_attachment(uuid, uuid, uuid, uuid, text, integer, boolean, integer)",
213
215
  "list_self_user_resource_authorities(uuid, uuid, text, uuid, integer)",
214
216
  "issue_self_user_resource_grant(uuid, uuid, uuid, text, text, text, uuid, integer, boolean)",
217
+ "issue_self_local_connection_use_grant(uuid, uuid, uuid, text, boolean)",
215
218
  "revoke_self_user_resource_grant(uuid, uuid, uuid)",
216
219
  "authorize_session_attempt_personal_resource_reads(uuid, uuid, uuid)",
217
220
  ] as const;
@@ -407,15 +410,21 @@ const GOVERNED_LEARNING_INSPECTION_AUTHORITY_TABLES = [
407
410
  ] as const;
408
411
  const COMPANY_PROFILE_AGENT_ADMIN_ROUTINES = [
409
412
  "propose_company_profile_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, text, text)",
413
+ "propose_company_profile_for_attempt_v2(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, text, text, text)",
410
414
  "confirm_company_profile_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid)",
415
+ "get_company_profile_agent_policy(uuid, uuid, text)",
416
+ "update_company_profile_agent_policy(uuid, uuid, text, text, bigint, uuid)",
411
417
  ] as const;
412
418
  const COMPANY_PROFILE_AGENT_ADMIN_AUTHORITY_TABLES = [
413
419
  "company_profile_activation_events",
420
+ "company_profile_agent_automatic_activation_receipts",
414
421
  "company_profile_agent_confirmation_receipts",
415
422
  "company_profile_agent_proposal_receipts",
416
423
  "company_profile_heads",
417
424
  "company_profile_revisions",
418
425
  "managed_accounts",
426
+ "organization_company_profile_agent_policies",
427
+ "organization_company_profile_agent_policy_events",
419
428
  "organization_memberships",
420
429
  "session_human_input_requests",
421
430
  "session_turn_attempts",
@@ -597,6 +606,7 @@ export const RUNTIME_TARGET_SCHEMA_FORBIDDEN_ROUTINES = [
597
606
  ] as const;
598
607
 
599
608
  export const RUNTIME_TARGET_SCHEMA_INVOKER_ROUTINES = [
609
+ "resolve_workspace_codex_subscription_source(uuid, uuid)",
600
610
  SESSION_REFERENCE_VISIBLE_ROUTINE,
601
611
  XAI_SNAPSHOT_VALIDATOR_ROUTINE,
602
612
  ] as const;
@@ -659,6 +669,7 @@ export const FORCE_RLS_TABLES = [
659
669
  "company_brain_preference_proposal_receipts",
660
670
  "company_brain_turn_context_snapshots",
661
671
  "company_profile_activation_events",
672
+ "company_profile_agent_automatic_activation_receipts",
662
673
  "company_profile_agent_confirmation_receipts",
663
674
  "company_profile_agent_proposal_receipts",
664
675
  "company_profile_heads",
@@ -767,6 +778,9 @@ export const FORCE_RLS_TABLES = [
767
778
  "model_call_facts",
768
779
  "network_routes",
769
780
  "new_session_drafts",
781
+ "organization_codex_rotation_settings",
782
+ "organization_company_profile_agent_policies",
783
+ "organization_company_profile_agent_policy_events",
770
784
  "organization_invitation_binding_events",
771
785
  "organization_membership_invitations",
772
786
  "organization_membership_lifecycle_events",
@@ -849,6 +863,7 @@ export const FORCE_RLS_TABLES = [
849
863
  "session_attempt_tool_catalogs",
850
864
  "session_background_commands",
851
865
  "session_command_receipts",
866
+ "session_event_cursors",
852
867
  "session_events",
853
868
  "session_goal_revisions",
854
869
  "session_goals",
@@ -925,7 +940,9 @@ export const FORCE_RLS_TABLES = [
925
940
  "workspace_artifact_versions",
926
941
  "workspace_artifacts",
927
942
  "workspace_captures",
943
+ "workspace_codex_subscription_preferences",
928
944
  "workspace_control_events",
945
+ "workspace_gateway_custom_models",
929
946
  "workspace_inference_controls",
930
947
  "workspace_instruction_policy_activation_events",
931
948
  "workspace_instruction_policy_deactivation_events",
@@ -965,6 +982,7 @@ export const NON_RLS_RUNTIME_TABLES = [
965
982
  "auth_users",
966
983
  "auth_verifications",
967
984
  "automation_webhook_endpoints",
985
+ "deployment_model_catalog",
968
986
  "integration_oauth_clients",
969
987
  "managed_accounts",
970
988
  "nested_agent_depth_configuration",
@@ -1050,6 +1068,7 @@ export const RUNTIME_FULL_DML_TABLES = [
1050
1068
  "memory_slack_publications",
1051
1069
  "model_call_facts",
1052
1070
  "new_session_drafts",
1071
+ "organization_codex_rotation_settings",
1053
1072
  "pack_installation_components",
1054
1073
  "pack_installations",
1055
1074
  "pr_review_app_registrations",
@@ -1070,6 +1089,7 @@ export const RUNTIME_FULL_DML_TABLES = [
1070
1089
  "session_attempt_interruptions",
1071
1090
  "session_background_commands",
1072
1091
  "session_command_receipts",
1092
+ "session_event_cursors",
1073
1093
  "session_events",
1074
1094
  "session_goals",
1075
1095
  "session_history_items",
@@ -1115,7 +1135,9 @@ export const RUNTIME_FULL_DML_TABLES = [
1115
1135
  "video_generation_references",
1116
1136
  "workspace_artifacts",
1117
1137
  "workspace_captures",
1138
+ "workspace_codex_subscription_preferences",
1118
1139
  "workspace_control_events",
1140
+ "workspace_gateway_custom_models",
1119
1141
  "workspace_inference_controls",
1120
1142
  "workspace_instruction_policy_heads",
1121
1143
  "workspace_memberships",
@@ -1137,6 +1159,7 @@ export const RUNTIME_READ_ONLY_TABLES = [
1137
1159
  "company_profile_activation_events",
1138
1160
  "company_profile_heads",
1139
1161
  "company_profile_snapshots",
1162
+ "deployment_model_catalog",
1140
1163
  "document_authority_reclassifications",
1141
1164
  "knowledge_lifecycle_events",
1142
1165
  "knowledge_memory_lifecycle_events",
@@ -1258,6 +1281,7 @@ export const PROTECTED_NO_DIRECT_DML_TABLES = [
1258
1281
  "company_brain_context_selection_receipts",
1259
1282
  "company_brain_preference_proposal_receipts",
1260
1283
  "company_brain_turn_context_snapshots",
1284
+ "company_profile_agent_automatic_activation_receipts",
1261
1285
  "company_profile_agent_confirmation_receipts",
1262
1286
  "company_profile_agent_proposal_receipts",
1263
1287
  "connection_use_audit_facts",
@@ -1283,6 +1307,8 @@ export const PROTECTED_NO_DIRECT_DML_TABLES = [
1283
1307
  "managed_auth_login_transactions",
1284
1308
  "managed_auth_session_set_operations",
1285
1309
  "managed_auth_session_sets",
1310
+ "organization_company_profile_agent_policies",
1311
+ "organization_company_profile_agent_policy_events",
1286
1312
  "organization_invitation_binding_events",
1287
1313
  "organization_membership_invitations",
1288
1314
  "organization_membership_lifecycle_events",
package/src/schema.ts CHANGED
@@ -1090,6 +1090,8 @@ export const organizationUserResourceAuthorities = pgTable(
1090
1090
  }),
1091
1091
  );
1092
1092
 
1093
+ export type ApiKeyCredentialKind = "workspace" | "organization" | "legacy_account";
1094
+
1093
1095
  export const apiKeys = pgTable(
1094
1096
  "api_keys",
1095
1097
  {
@@ -1102,6 +1104,7 @@ export const apiKeys = pgTable(
1102
1104
  }),
1103
1105
  name: text("name").notNull(),
1104
1106
  description: text("description"),
1107
+ credentialKind: text("credential_kind").$type<ApiKeyCredentialKind>().notNull(),
1105
1108
  prefix: text("prefix").notNull(),
1106
1109
  keyHash: text("key_hash").notNull(),
1107
1110
  permissions: jsonb("permissions").$type<string[]>().notNull().default([]),
@@ -1120,6 +1123,20 @@ export const apiKeys = pgTable(
1120
1123
  "api_keys_description_check",
1121
1124
  sql`${table.description} is null or length(${table.description}) between 1 and 500`,
1122
1125
  ),
1126
+ credentialKindValid: check(
1127
+ "api_keys_credential_kind_check",
1128
+ sql`(
1129
+ ${table.workspaceId} is not null
1130
+ and ${table.credentialKind} = 'workspace'
1131
+ ) or (
1132
+ ${table.workspaceId} is null
1133
+ and ${table.credentialKind} = 'organization'
1134
+ ) or (
1135
+ ${table.workspaceId} is null
1136
+ and ${table.credentialKind} = 'legacy_account'
1137
+ and ${table.revokedAt} is not null
1138
+ )`,
1139
+ ),
1123
1140
  }),
1124
1141
  );
1125
1142
 
@@ -1232,8 +1249,9 @@ export const workspaceVariableSetVariables = pgTable(
1232
1249
  }),
1233
1250
  );
1234
1251
 
1235
- // Per-workspace ChatGPT/Codex subscription credential. One row per connected
1236
- // ChatGPT account within a workspace.
1252
+ // Workspace- or organization-owned ChatGPT/Codex subscription credential. One
1253
+ // row per connected ChatGPT account in the owning pool. Organization rows have
1254
+ // workspace_id = NULL and are selected only for inheriting shared workspaces.
1237
1255
  // access/refresh/id tokens live INSIDE credential_encrypted (v1 AES-256-GCM,
1238
1256
  // same envelope as workspace_variable_set_variables); the other columns are
1239
1257
  // plaintext metadata (header value + UI). RLS-isolated per workspace.
@@ -1244,9 +1262,18 @@ export const codexSubscriptionCredentials = pgTable(
1244
1262
  accountId: uuid("account_id")
1245
1263
  .notNull()
1246
1264
  .references(() => managedAccounts.id, { onDelete: "cascade" }),
1247
- workspaceId: uuid("workspace_id")
1248
- .notNull()
1249
- .references(() => workspaces.id, { onDelete: "cascade" }),
1265
+ workspaceId: uuid("workspace_id").references(() => workspaces.id, { onDelete: "cascade" }),
1266
+ organizationId: uuid("organization_id").references(() => managedAccounts.id, {
1267
+ onDelete: "cascade",
1268
+ }),
1269
+ authorityScope: text("authority_scope").notNull().default("workspace"),
1270
+ ownerOrganizationMembershipId: uuid("owner_organization_membership_id"),
1271
+ organizationUserResourceAuthorityId: uuid("organization_user_resource_authority_id"),
1272
+ organizationUserResourceKind: text("organization_user_resource_kind"),
1273
+ organizationUserResourceAuthorityGeneration: bigint(
1274
+ "organization_user_resource_authority_generation",
1275
+ { mode: "number" },
1276
+ ),
1250
1277
  // Format: v1:<base64 iv>:<base64 ciphertext||gcm-tag>. JSON {access_token, refresh_token, id_token}. Never returned by any API.
1251
1278
  credentialEncrypted: text("credential_encrypted").notNull(),
1252
1279
  chatgptAccountId: text("chatgpt_account_id"), // plaintext ChatGPT-Account-ID header value (non-secret)
@@ -1268,10 +1295,13 @@ export const codexSubscriptionCredentials = pgTable(
1268
1295
  secondaryUsedPercent: integer("secondary_used_percent"),
1269
1296
  secondaryResetAt: timestamp("secondary_reset_at", { withTimezone: true }),
1270
1297
  usageCheckedAt: timestamp("usage_checked_at", { withTimezone: true }), // snapshot freshness → cache TTL clock
1271
- // P3 rotation cooldown (plaintext metadata; NEVER a token). Set when this account hit its
1272
- // usage cap on a rotation turn; the rotation engine treats `exhausted_until > now()` as
1273
- // capped/skip so it isn't immediately re-picked. Self-clears via the now() comparison.
1298
+ // P3 rotation cooldown (plaintext metadata; NEVER a token). The kind keeps
1299
+ // quota refusals distinct from generic provider backpressure. The independent
1300
+ // revision fences a live usage response against a concurrently newer refusal;
1301
+ // neither field participates in token-refresh OCC.
1274
1302
  exhaustedUntil: timestamp("exhausted_until", { withTimezone: true }),
1303
+ exhaustedKind: text("exhausted_kind"), // quota | rate_limit | null (legacy/cleared)
1304
+ exhaustedRevision: bigint("exhausted_revision", { mode: "number" }).notNull().default(0),
1275
1305
  // Workspace-local, server-held fairness cursor. Provider usage headers are
1276
1306
  // capacity hints, never the sole allocator: live lease count is ranked first
1277
1307
  // and this cursor deterministically breaks equal-load/equal-capacity ties.
@@ -1319,6 +1349,69 @@ export const codexSubscriptionCredentials = pgTable(
1319
1349
  workspaceAccountIdentity: uniqueIndex(
1320
1350
  "codex_subscription_credentials_workspace_account_id_idx",
1321
1351
  ).on(table.workspaceId, table.accountId, table.id),
1352
+ accountIdentity: uniqueIndex("codex_subscription_credentials_account_id_idx").on(
1353
+ table.accountId,
1354
+ table.id,
1355
+ ),
1356
+ organizationAccount: uniqueIndex("codex_subscription_credentials_organization_account_idx")
1357
+ .on(table.organizationId, table.chatgptAccountId)
1358
+ .where(
1359
+ sql`${table.authorityScope} = 'organization' and ${table.chatgptAccountId} is not null`,
1360
+ ),
1361
+ organizationLookup: index("codex_subscription_credentials_organization_lookup_idx")
1362
+ .on(table.organizationId, table.createdAt, table.id)
1363
+ .where(sql`${table.authorityScope} = 'organization'`),
1364
+ }),
1365
+ );
1366
+
1367
+ export const workspaceCodexSubscriptionPreferences = pgTable(
1368
+ "workspace_codex_subscription_preferences",
1369
+ {
1370
+ workspaceId: uuid("workspace_id")
1371
+ .primaryKey()
1372
+ .references(() => workspaces.id, { onDelete: "cascade" }),
1373
+ accountId: uuid("account_id")
1374
+ .notNull()
1375
+ .references(() => managedAccounts.id, { onDelete: "cascade" }),
1376
+ mode: text("mode").notNull().default("automatic"),
1377
+ updatedBySubjectId: text("updated_by_subject_id"),
1378
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1379
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1380
+ },
1381
+ (table) => ({
1382
+ workspaceAccount: foreignKey({
1383
+ name: "workspace_codex_subscription_preferences_workspace_account_fk",
1384
+ columns: [table.workspaceId, table.accountId],
1385
+ foreignColumns: [workspaces.id, workspaces.accountId],
1386
+ }).onDelete("cascade"),
1387
+ modeValid: check(
1388
+ "workspace_codex_subscription_preferences_mode_chk",
1389
+ sql`${table.mode} in ('automatic', 'workspace', 'organization', 'disabled')`,
1390
+ ),
1391
+ }),
1392
+ );
1393
+
1394
+ export const organizationCodexRotationSettings = pgTable(
1395
+ "organization_codex_rotation_settings",
1396
+ {
1397
+ id: uuid("id").primaryKey().defaultRandom(),
1398
+ accountId: uuid("account_id")
1399
+ .notNull()
1400
+ .references(() => managedAccounts.id, { onDelete: "cascade" }),
1401
+ activeCredentialId: uuid("active_credential_id"),
1402
+ rotationEnabled: boolean("rotation_enabled").notNull().default(false),
1403
+ leaseRotationEnabled: boolean("lease_rotation_enabled").notNull().default(false),
1404
+ rotationStrategy: text("rotation_strategy").notNull().default("sharded"),
1405
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1406
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1407
+ },
1408
+ (table) => ({
1409
+ account: uniqueIndex("organization_codex_rotation_settings_account_idx").on(table.accountId),
1410
+ activeCredential: foreignKey({
1411
+ name: "organization_codex_rotation_settings_active_fk",
1412
+ columns: [table.activeCredentialId],
1413
+ foreignColumns: [codexSubscriptionCredentials.id],
1414
+ }).onDelete("set null"),
1322
1415
  }),
1323
1416
  );
1324
1417
 
@@ -6987,6 +7080,15 @@ export const sessionCommandReceipts = pgTable(
6987
7080
  table.targetSessionId,
6988
7081
  table.createdAt,
6989
7082
  ),
7083
+ promptActorOperation: index("session_command_receipts_prompt_actor_operation_idx")
7084
+ .on(
7085
+ table.workspaceId,
7086
+ table.actorType,
7087
+ table.actorSubjectId,
7088
+ table.actorAttemptId,
7089
+ table.operationKey,
7090
+ )
7091
+ .where(sql`${table.action} in ('prompt.send', 'prompt.steer')`),
6990
7092
  goalUpdateOperation: uniqueIndex("session_command_receipts_goal_update_operation_uq")
6991
7093
  .on(table.workspaceId, table.action, table.targetSessionId, table.operationKey)
6992
7094
  .where(sql`${table.action} = 'goal.update'`),
@@ -7800,6 +7902,43 @@ export const xaiCapacityWaiters = pgTable(
7800
7902
  }),
7801
7903
  );
7802
7904
 
7905
+ export const sessionEventCursors = pgTable(
7906
+ "session_event_cursors",
7907
+ {
7908
+ sessionId: uuid("session_id")
7909
+ .primaryKey()
7910
+ .references(() => sessions.id, { onDelete: "cascade" }),
7911
+ accountId: uuid("account_id")
7912
+ .notNull()
7913
+ .references(() => managedAccounts.id, { onDelete: "cascade" }),
7914
+ workspaceId: uuid("workspace_id")
7915
+ .notNull()
7916
+ .references(() => workspaces.id, { onDelete: "cascade" }),
7917
+ lastSequence: integer("last_sequence").notNull().default(0),
7918
+ revision: bigint("revision", { mode: "number" }).notNull().default(0),
7919
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
7920
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
7921
+ },
7922
+ (table) => ({
7923
+ workspaceAccount: foreignKey({
7924
+ name: "session_event_cursors_workspace_account_fk",
7925
+ columns: [table.workspaceId, table.accountId],
7926
+ foreignColumns: [workspaces.id, workspaces.accountId],
7927
+ }).onDelete("cascade"),
7928
+ workspaceSession: foreignKey({
7929
+ name: "session_event_cursors_workspace_session_fk",
7930
+ columns: [table.workspaceId, table.sessionId],
7931
+ foreignColumns: [sessions.workspaceId, sessions.id],
7932
+ }).onDelete("cascade"),
7933
+ workspaceIdentity: uniqueIndex("session_event_cursors_workspace_session_idx").on(
7934
+ table.workspaceId,
7935
+ table.sessionId,
7936
+ ),
7937
+ sequenceValid: check("session_event_cursors_sequence_check", sql`${table.lastSequence} >= 0`),
7938
+ revisionValid: check("session_event_cursors_revision_check", sql`${table.revision} >= 0`),
7939
+ }),
7940
+ );
7941
+
7803
7942
  export const sessionEvents = pgTable(
7804
7943
  "session_events",
7805
7944
  {
@@ -8472,6 +8611,29 @@ export const sandboxLeases = pgTable(
8472
8611
  currentCheckpointArtifactId: uuid("current_checkpoint_artifact_id"),
8473
8612
  previousCheckpointArtifactId: uuid("previous_checkpoint_artifact_id"),
8474
8613
 
8614
+ // Durable single-flight for immutable machine setup (currently exact rig
8615
+ // setup only). Per-turn credentials, repositories, files, and cloud login
8616
+ // deliberately remain outside this lease-scoped receipt.
8617
+ sharedPreparationLeaseEpoch: integer("shared_preparation_lease_epoch"),
8618
+ sharedPreparationInstanceId: text("shared_preparation_instance_id"),
8619
+ sharedPreparationSpecHash: text("shared_preparation_spec_hash"),
8620
+ sharedPreparationStatus: text("shared_preparation_status", {
8621
+ enum: ["running", "completed", "failed"],
8622
+ }),
8623
+ sharedPreparationClaimId: uuid("shared_preparation_claim_id"),
8624
+ sharedPreparationOwnerAttemptId: uuid("shared_preparation_owner_attempt_id"),
8625
+ sharedPreparationAttempt: integer("shared_preparation_attempt"),
8626
+ sharedPreparationRevision: integer("shared_preparation_revision").notNull().default(0),
8627
+ sharedPreparationStartedAt: timestamp("shared_preparation_started_at", {
8628
+ withTimezone: true,
8629
+ }),
8630
+ sharedPreparationDeadlineAt: timestamp("shared_preparation_deadline_at", {
8631
+ withTimezone: true,
8632
+ }),
8633
+ sharedPreparationSettledAt: timestamp("shared_preparation_settled_at", {
8634
+ withTimezone: true,
8635
+ }),
8636
+
8475
8637
  expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
8476
8638
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
8477
8639
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
@@ -10874,8 +11036,9 @@ export const hostExportConfig = pgTable(
10874
11036
  /**
10875
11037
  * Transactional delivery buffer. It intentionally has no tenant/source FKs:
10876
11038
  * a workspace deletion must not erase an already-committed, unacknowledged
10877
- * host fact. Session-event payloads retain their exact storage bytes plus
10878
- * explicit codec truth; usage payloads remain ordinary JSON.
11039
+ * host fact. Session-event rows retain exact storage bytes while they fit the
11040
+ * bounded host wire; larger canonical events carry an explicit content-free
11041
+ * projection plus literal-JSON codec truth. Usage payloads remain ordinary JSON.
10879
11042
  */
10880
11043
  export const hostExportOutbox = pgTable(
10881
11044
  "host_export_outbox",
@@ -12475,6 +12638,92 @@ export const rigChanges = pgTable(
12475
12638
  }),
12476
12639
  );
12477
12640
 
12641
+ export const deploymentModelCatalog = pgTable(
12642
+ "deployment_model_catalog",
12643
+ {
12644
+ singleton: boolean("singleton").primaryKey().notNull().default(true),
12645
+ document: jsonb("document").$type<unknown>().notNull(),
12646
+ version: bigint("version", { mode: "number" }).notNull().default(1),
12647
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
12648
+ },
12649
+ (table) => ({
12650
+ singletonCheck: check("deployment_model_catalog_singleton_chk", sql`${table.singleton}`),
12651
+ documentCheck: check(
12652
+ "deployment_model_catalog_document_chk",
12653
+ sql`jsonb_typeof(${table.document}) = 'object'`,
12654
+ ),
12655
+ versionCheck: check("deployment_model_catalog_version_chk", sql`${table.version} > 0`),
12656
+ }),
12657
+ );
12658
+
12659
+ export const workspaceGatewayCustomModels = pgTable(
12660
+ "workspace_gateway_custom_models",
12661
+ {
12662
+ id: uuid("id").primaryKey().defaultRandom(),
12663
+ accountId: uuid("account_id")
12664
+ .notNull()
12665
+ .references(() => managedAccounts.id, { onDelete: "cascade" }),
12666
+ workspaceId: uuid("workspace_id")
12667
+ .notNull()
12668
+ .references(() => workspaces.id, { onDelete: "cascade" }),
12669
+ providerKind: text("provider_kind").$type<"vercel_gateway" | "openrouter">().notNull(),
12670
+ upstreamModelId: text("upstream_model_id").notNull(),
12671
+ label: text("label"),
12672
+ version: integer("version").notNull().default(1),
12673
+ createOperationId: uuid("create_operation_id").notNull(),
12674
+ createRequestHash: text("create_request_hash").notNull(),
12675
+ deleteOperationId: uuid("delete_operation_id"),
12676
+ deleteRequestHash: text("delete_request_hash"),
12677
+ createdBySubjectId: text("created_by_subject_id").notNull(),
12678
+ retiredAt: timestamp("retired_at", { withTimezone: true }),
12679
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
12680
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
12681
+ },
12682
+ (table) => ({
12683
+ workspaceAccountFk: foreignKey({
12684
+ name: "workspace_gateway_custom_models_workspace_account_fk",
12685
+ columns: [table.workspaceId, table.accountId],
12686
+ foreignColumns: [workspaces.id, workspaces.accountId],
12687
+ }).onDelete("cascade"),
12688
+ workspaceUpstream: uniqueIndex("workspace_gateway_custom_models_workspace_upstream_uq")
12689
+ .on(table.workspaceId, table.providerKind, table.upstreamModelId)
12690
+ .where(sql`${table.retiredAt} is null`),
12691
+ createOperation: uniqueIndex("workspace_gateway_custom_models_create_operation_uq").on(
12692
+ table.workspaceId,
12693
+ table.providerKind,
12694
+ table.createOperationId,
12695
+ ),
12696
+ deleteOperation: uniqueIndex("workspace_gateway_custom_models_delete_operation_uq")
12697
+ .on(table.workspaceId, table.providerKind, table.deleteOperationId)
12698
+ .where(sql`${table.deleteOperationId} is not null`),
12699
+ providerKindCheck: check(
12700
+ "workspace_gateway_custom_models_provider_kind_chk",
12701
+ sql`${table.providerKind} in ('vercel_gateway', 'openrouter')`,
12702
+ ),
12703
+ upstreamCheck: check(
12704
+ "workspace_gateway_custom_models_upstream_chk",
12705
+ sql`octet_length(${table.upstreamModelId}) between 1 and 238 and ${table.upstreamModelId} ~ '^[!-~]+$' and ${table.upstreamModelId} !~ '[|]'`,
12706
+ ),
12707
+ labelCheck: check(
12708
+ "workspace_gateway_custom_models_label_chk",
12709
+ sql`${table.label} is null or (octet_length(${table.label}) between 1 and 128 and ${table.label} !~ '[\r\n|]')`,
12710
+ ),
12711
+ actorCheck: check(
12712
+ "workspace_gateway_custom_models_actor_chk",
12713
+ sql`octet_length(${table.createdBySubjectId}) between 1 and 1024`,
12714
+ ),
12715
+ versionCheck: check("workspace_gateway_custom_models_version_chk", sql`${table.version} > 0`),
12716
+ createHashCheck: check(
12717
+ "workspace_gateway_custom_models_create_hash_chk",
12718
+ sql`${table.createRequestHash} ~ '^[a-f0-9]{64}$'`,
12719
+ ),
12720
+ deleteReceiptCheck: check(
12721
+ "workspace_gateway_custom_models_delete_receipt_chk",
12722
+ sql`(${table.deleteOperationId} is null and ${table.deleteRequestHash} is null) or (${table.deleteOperationId} is not null and ${table.deleteRequestHash} ~ '^[a-f0-9]{64}$' and ${table.retiredAt} is not null)`,
12723
+ ),
12724
+ }),
12725
+ );
12726
+
12478
12727
  export * from "./workspace-instruction-policies-schema";
12479
12728
  export * from "./company-profile-schema";
12480
12729
  export * from "./workspace-learning-policy-schema";