@opengeni/db 3.2.2 → 3.3.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 (81) hide show
  1. package/dist/canonical-human-identities.js +3 -3
  2. package/dist/capability-reconciliation.js +2 -2
  3. package/dist/{chunk-V2X2NK7T.js → chunk-5MPQZI43.js} +2675 -2540
  4. package/dist/{chunk-V2X2NK7T.js.map → chunk-5MPQZI43.js.map} +1 -1
  5. package/dist/{chunk-L3NT43Z5.js → chunk-7K5AVQUZ.js} +3 -3
  6. package/dist/{chunk-JYPBOJ2Y.js → chunk-AAOKWNHE.js} +4 -4
  7. package/dist/{chunk-D7LTIG33.js → chunk-B4RMLA2X.js} +2 -2
  8. package/dist/{chunk-OXO32LTK.js → chunk-CEJ3NQ3B.js} +11 -1
  9. package/dist/chunk-CEJ3NQ3B.js.map +1 -0
  10. package/dist/{chunk-AYZC65QU.js → chunk-CGSINPLW.js} +2 -2
  11. package/dist/{chunk-VCJAYIPH.js → chunk-FX2PSMGH.js} +2 -2
  12. package/dist/{chunk-HMKUJ6NI.js → chunk-HQWXEF77.js} +57 -9
  13. package/dist/chunk-HQWXEF77.js.map +1 -0
  14. package/dist/{chunk-V22DUH4C.js → chunk-HWEHZKHA.js} +5 -5
  15. package/dist/{chunk-6UU7OVUN.js → chunk-JTBJGSUZ.js} +37 -7
  16. package/dist/chunk-JTBJGSUZ.js.map +1 -0
  17. package/dist/{chunk-YH4GWEDM.js → chunk-KPC7I5WG.js} +2 -2
  18. package/dist/{chunk-XQHABE23.js → chunk-OWM6XG55.js} +4 -4
  19. package/dist/{chunk-YWHG45TK.js → chunk-PNEJVKKV.js} +6 -6
  20. package/dist/{chunk-4BAKPTPG.js → chunk-S74WULCK.js} +3 -3
  21. package/dist/{chunk-K6NT66NP.js → chunk-SDKFRIAN.js} +4 -4
  22. package/dist/{chunk-RCDMYTLP.js → chunk-UWS5DJQ6.js} +2 -2
  23. package/dist/{chunk-LRRGVHAQ.js → chunk-VUR5U5B3.js} +2 -2
  24. package/dist/{chunk-IF63BST7.js → chunk-Y4ERASEM.js} +2 -2
  25. package/dist/{chunk-VBG4TW5C.js → chunk-ZZOEKHGU.js} +2 -2
  26. package/dist/connect-attempts.js +3 -3
  27. package/dist/database.d.ts +9 -0
  28. package/dist/editable-artifact-durable-export.js +2 -2
  29. package/dist/editable-artifacts.js +3 -3
  30. package/dist/index.d.ts +93 -22
  31. package/dist/index.js +31 -19
  32. package/dist/insights-site-usage.d.ts +10 -0
  33. package/dist/managed-auth-session-sets.js +3 -3
  34. package/dist/mcp-operations.js +2 -2
  35. package/dist/migrate.js +19 -19
  36. package/dist/organization-integration-policy.js +3 -3
  37. package/dist/provision-roles.js +1 -1
  38. package/dist/retained-provider-commands.js +6 -6
  39. package/dist/schema.d.ts +102 -0
  40. package/dist/schema.js +1 -1
  41. package/dist/session-background-commands.js +5 -5
  42. package/dist/session-command-output.js +5 -5
  43. package/dist/session-event-slices.js +3 -3
  44. package/dist/session-mcp-credential-rotation.js +6 -6
  45. package/dist/session-tenancy.js +6 -6
  46. package/dist/site-publishing.d.ts +11 -0
  47. package/dist/{subscription-core-codex-4G4CCOJU.js → subscription-core-codex-HIAP7CY2.js} +6 -6
  48. package/dist/{subscription-core-codex-compat-64ACIZVP.js → subscription-core-codex-compat-IBERN7DU.js} +8 -8
  49. package/dist/video-generation.js +3 -3
  50. package/dist/workspace-tool-defaults.js +5 -5
  51. package/drizzle/0793_private_site_sessions.sql +166 -0
  52. package/drizzle/0794_site_ai_insights.sql +175 -0
  53. package/drizzle/0795_site_lifecycle_cancellation.sql +121 -0
  54. package/package.json +9 -9
  55. package/src/database.ts +44 -3
  56. package/src/index.ts +142 -11
  57. package/src/insights-site-usage.ts +37 -0
  58. package/src/provision-roles.ts +15 -0
  59. package/src/runtime-posture.ts +76 -7
  60. package/src/schema.ts +10 -0
  61. package/src/site-publishing.ts +35 -0
  62. package/dist/chunk-6UU7OVUN.js.map +0 -1
  63. package/dist/chunk-HMKUJ6NI.js.map +0 -1
  64. package/dist/chunk-OXO32LTK.js.map +0 -1
  65. /package/dist/{chunk-L3NT43Z5.js.map → chunk-7K5AVQUZ.js.map} +0 -0
  66. /package/dist/{chunk-JYPBOJ2Y.js.map → chunk-AAOKWNHE.js.map} +0 -0
  67. /package/dist/{chunk-D7LTIG33.js.map → chunk-B4RMLA2X.js.map} +0 -0
  68. /package/dist/{chunk-AYZC65QU.js.map → chunk-CGSINPLW.js.map} +0 -0
  69. /package/dist/{chunk-VCJAYIPH.js.map → chunk-FX2PSMGH.js.map} +0 -0
  70. /package/dist/{chunk-V22DUH4C.js.map → chunk-HWEHZKHA.js.map} +0 -0
  71. /package/dist/{chunk-YH4GWEDM.js.map → chunk-KPC7I5WG.js.map} +0 -0
  72. /package/dist/{chunk-XQHABE23.js.map → chunk-OWM6XG55.js.map} +0 -0
  73. /package/dist/{chunk-YWHG45TK.js.map → chunk-PNEJVKKV.js.map} +0 -0
  74. /package/dist/{chunk-4BAKPTPG.js.map → chunk-S74WULCK.js.map} +0 -0
  75. /package/dist/{chunk-K6NT66NP.js.map → chunk-SDKFRIAN.js.map} +0 -0
  76. /package/dist/{chunk-RCDMYTLP.js.map → chunk-UWS5DJQ6.js.map} +0 -0
  77. /package/dist/{chunk-LRRGVHAQ.js.map → chunk-VUR5U5B3.js.map} +0 -0
  78. /package/dist/{chunk-IF63BST7.js.map → chunk-Y4ERASEM.js.map} +0 -0
  79. /package/dist/{chunk-VBG4TW5C.js.map → chunk-ZZOEKHGU.js.map} +0 -0
  80. /package/dist/{subscription-core-codex-4G4CCOJU.js.map → subscription-core-codex-HIAP7CY2.js.map} +0 -0
  81. /package/dist/{subscription-core-codex-compat-64ACIZVP.js.map → subscription-core-codex-compat-IBERN7DU.js.map} +0 -0
@@ -511,6 +511,13 @@ const SCHEDULED_PERSONAL_RESOURCE_CAPABILITY_PREDICATE_ROUTINE =
511
511
  const SCHEDULED_PERSONAL_RESOURCE_CAPABILITY_TABLE = "scheduled_personal_resource_capabilities";
512
512
  const VARIABLE_SET_CAPABILITY_PREDICATE_ROUTINE = "variable_set_authority_capability_active(text)";
513
513
  const VARIABLE_SET_CAPABILITY_TABLE = "variable_set_authority_capabilities";
514
+ const SITE_CANCELLATION_CAPABILITY_TABLE = "site_session_cancellation_capabilities";
515
+ const SITE_CANCELLATION_PREDICATE =
516
+ "site_session_cancellation_capability_active(uuid, uuid, uuid, uuid)";
517
+ const SITE_CANCELLATION_PRIVATE_ROUTINES = [
518
+ "begin_site_session_cancellation(uuid, uuid, uuid, uuid)",
519
+ "end_site_session_cancellation(uuid)",
520
+ ] as const;
514
521
  const PERSONAL_DOCUMENT_CAPABILITY_PREDICATE_ROUTINE =
515
522
  "personal_document_authority_capability_active(text)";
516
523
  const PERSONAL_DOCUMENT_CAPABILITY_TABLE = "personal_document_authority_capabilities";
@@ -3031,15 +3038,15 @@ export async function inspectRuntimeDatabasePosture(
3031
3038
  -- Column-only grants on capability tables are also unsafe; a pin
3032
3039
  -- table must remain EXECUTE-only even after column ACL drift.
3033
3040
  (has_table_privilege(current_user, c.oid, 'SELECT') or
3034
- ((c.relname in ('modal_native_origin_read_capabilities','modal_inventory_read_capabilities','usage_allowance_capabilities','session_import_batches', ${ARTIFACT_PINS_TABLE}) or
3041
+ ((c.relname in ('modal_native_origin_read_capabilities','modal_inventory_read_capabilities','usage_allowance_capabilities','session_import_batches', ${ARTIFACT_PINS_TABLE}, ${SITE_CANCELLATION_CAPABILITY_TABLE}) or
3035
3042
  c.relname in (select jsonb_array_elements_text(${JSON.stringify([...RUNTIME_ALLOWANCE_PRIVATE_TABLES, ...RUNTIME_SESSION_USAGE_LIMIT_PRIVATE_TABLES, "session_usage_limit_capabilities"])}::jsonb))) and
3036
3043
  has_any_column_privilege(current_user, c.oid, 'SELECT'))) as can_select,
3037
3044
  (has_table_privilege(current_user, c.oid, 'INSERT') or
3038
- ((c.relname in ('modal_native_origin_read_capabilities','modal_inventory_read_capabilities','usage_allowance_capabilities','session_import_batches', ${ARTIFACT_PINS_TABLE}) or
3045
+ ((c.relname in ('modal_native_origin_read_capabilities','modal_inventory_read_capabilities','usage_allowance_capabilities','session_import_batches', ${ARTIFACT_PINS_TABLE}, ${SITE_CANCELLATION_CAPABILITY_TABLE}) or
3039
3046
  c.relname in (select jsonb_array_elements_text(${JSON.stringify([...RUNTIME_ALLOWANCE_PRIVATE_TABLES, ...RUNTIME_SESSION_USAGE_LIMIT_PRIVATE_TABLES, "session_usage_limit_capabilities"])}::jsonb))) and
3040
3047
  has_any_column_privilege(current_user, c.oid, 'INSERT'))) as can_insert,
3041
3048
  (has_table_privilege(current_user, c.oid, 'UPDATE') or
3042
- ((c.relname in ('modal_native_origin_read_capabilities','modal_inventory_read_capabilities','usage_allowance_capabilities','session_import_batches', ${ARTIFACT_PINS_TABLE}) or
3049
+ ((c.relname in ('modal_native_origin_read_capabilities','modal_inventory_read_capabilities','usage_allowance_capabilities','session_import_batches', ${ARTIFACT_PINS_TABLE}, ${SITE_CANCELLATION_CAPABILITY_TABLE}) or
3043
3050
  c.relname in (select jsonb_array_elements_text(${JSON.stringify([...RUNTIME_ALLOWANCE_PRIVATE_TABLES, ...RUNTIME_SESSION_USAGE_LIMIT_PRIVATE_TABLES, "session_usage_limit_capabilities"])}::jsonb))) and
3044
3051
  has_any_column_privilege(current_user, c.oid, 'UPDATE'))) as can_update,
3045
3052
  has_table_privilege(current_user, c.oid, 'DELETE') as can_delete,
@@ -3061,6 +3068,7 @@ export async function inspectRuntimeDatabasePosture(
3061
3068
  ${PERSONAL_RESOURCE_CAPABILITY_TABLE},
3062
3069
  ${SCHEDULED_PERSONAL_RESOURCE_CAPABILITY_TABLE},
3063
3070
  ${VARIABLE_SET_CAPABILITY_TABLE},
3071
+ ${SITE_CANCELLATION_CAPABILITY_TABLE},
3064
3072
  ${VAULT_CAPABILITY_TABLE},
3065
3073
  ${PERSONAL_DOCUMENT_CAPABILITY_TABLE},
3066
3074
  ${DOCUMENT_MIGRATION_CAPABILITY_TABLE},
@@ -3121,6 +3129,7 @@ export async function inspectRuntimeDatabasePosture(
3121
3129
  can_execute: boolean;
3122
3130
  public_execute: boolean;
3123
3131
  security_definer: boolean;
3132
+ configuration: string[] | null;
3124
3133
  }>(
3125
3134
  await tx.execute(sql`
3126
3135
  select
@@ -3132,7 +3141,8 @@ export async function inspectRuntimeDatabasePosture(
3132
3141
  from aclexplode(coalesce(p.proacl, acldefault('f', p.proowner))) acl
3133
3142
  where acl.grantee = 0 and acl.privilege_type = 'EXECUTE'
3134
3143
  ) as public_execute,
3135
- p.prosecdef as security_definer
3144
+ p.prosecdef as security_definer,
3145
+ p.proconfig as configuration
3136
3146
  from pg_proc p
3137
3147
  join pg_namespace n on n.oid = p.pronamespace
3138
3148
  where n.nspname = ${targetSchema}
@@ -3140,9 +3150,11 @@ export async function inspectRuntimeDatabasePosture(
3140
3150
  and (p.proname || '(' || pg_catalog.oidvectortypes(p.proargtypes) || ')') = any(
3141
3151
  array[
3142
3152
  ${sql.join(
3143
- [...targetSchemaCapabilityRoutines, ...targetSchemaForbiddenRoutines].map(
3144
- (name) => sql`${name}`,
3145
- ),
3153
+ [
3154
+ ...targetSchemaCapabilityRoutines,
3155
+ ...targetSchemaForbiddenRoutines,
3156
+ SITE_CANCELLATION_PREDICATE,
3157
+ ].map((name) => sql`${name}`),
3146
3158
  sql`, `,
3147
3159
  )}
3148
3160
  ]::text[]
@@ -3156,6 +3168,7 @@ export async function inspectRuntimeDatabasePosture(
3156
3168
  execute: row.can_execute,
3157
3169
  publicExecute: row.public_execute,
3158
3170
  securityDefiner: row.security_definer,
3171
+ configuration: row.configuration,
3159
3172
  }))
3160
3173
  .sort((left, right) => left.name.localeCompare(right.name));
3161
3174
 
@@ -5459,6 +5472,62 @@ export function evaluateRuntimeDatabasePosture(
5459
5472
  violations.push("organization usage aggregate capability is missing or unsafe");
5460
5473
  }
5461
5474
  }
5475
+ const siteCancellation = posture.privateTables.find(
5476
+ (table) => table.name === SITE_CANCELLATION_CAPABILITY_TABLE,
5477
+ );
5478
+ const siteCancellationPredicate = posture.targetRoutines.filter(
5479
+ (routine) => routine.name === SITE_CANCELLATION_PREDICATE,
5480
+ );
5481
+ const siteCancellationRoutines = posture.privateRoutines.filter((routine) =>
5482
+ (SITE_CANCELLATION_PRIVATE_ROUTINES as readonly string[]).includes(routine.name),
5483
+ );
5484
+ // Require the current production contract; reduced fixture/embedding inventories
5485
+ // may omit Sites, but any installed half must satisfy the complete capability.
5486
+ if (
5487
+ !options.protectedTables ||
5488
+ siteCancellation ||
5489
+ siteCancellationPredicate.length ||
5490
+ siteCancellationRoutines.length
5491
+ ) {
5492
+ if (
5493
+ !siteCancellation ||
5494
+ siteCancellation.owner === expectedRole ||
5495
+ siteCancellation.owner !== tableByName.get("sessions")?.owner ||
5496
+ siteCancellation.select ||
5497
+ siteCancellation.insert ||
5498
+ siteCancellation.update ||
5499
+ siteCancellation.delete ||
5500
+ siteCancellation.truncate ||
5501
+ siteCancellation.references ||
5502
+ siteCancellation.trigger
5503
+ )
5504
+ violations.push("Site cancellation capability ledger is missing or unsafe");
5505
+ const predicate = siteCancellationPredicate[0];
5506
+ if (
5507
+ siteCancellationPredicate.length !== 1 ||
5508
+ !predicate?.securityDefiner ||
5509
+ !predicate.execute ||
5510
+ !predicate.publicExecute ||
5511
+ predicate.owner !== siteCancellation?.owner ||
5512
+ !predicate.configuration?.includes("search_path=pg_catalog")
5513
+ )
5514
+ violations.push("Site cancellation policy predicate is missing or unsafe");
5515
+ for (const name of SITE_CANCELLATION_PRIVATE_ROUTINES) {
5516
+ const matches = siteCancellationRoutines.filter((routine) => routine.name === name);
5517
+ const routine = matches[0];
5518
+ if (
5519
+ matches.length !== 1 ||
5520
+ !routine?.securityDefiner ||
5521
+ !routine.execute ||
5522
+ routine.publicExecute ||
5523
+ routine.owner !== siteCancellation?.owner ||
5524
+ !(name.startsWith("end_")
5525
+ ? routine.configuration?.includes("search_path=pg_catalog")
5526
+ : safeSearchPath(routine))
5527
+ )
5528
+ violations.push(`Site cancellation routine ${name} is missing or unsafe`);
5529
+ }
5530
+ }
5462
5531
  const modelCallFactsOwner = tableByName.get("model_call_facts")?.owner;
5463
5532
  const modelFactCapabilityRoutines = new Set(
5464
5533
  options.modelFactCapabilityRoutines ?? MODEL_FACT_CAPABILITY_ROUTINES.map(([name]) => name),
package/src/schema.ts CHANGED
@@ -5003,6 +5003,12 @@ export const sessions = pgTable(
5003
5003
  ownerOrganizationMembershipId: uuid("owner_organization_membership_id"),
5004
5004
  ownerSubjectId: text("owner_subject_id"),
5005
5005
  visibility: text("visibility").notNull().default("workspace_shared"),
5006
+ // Immutable server-derived Site audience. Independent of mutable metadata,
5007
+ // reservations, and native member ownership; descendants inherit the binding.
5008
+ siteId: uuid("site_id"),
5009
+ siteAccessRootId: uuid("site_access_root_id"),
5010
+ siteViewerPrincipal: text("site_viewer_principal"),
5011
+ siteOwnerSubjectId: text("site_owner_subject_id"),
5006
5012
  createRequestedVisibility: text("create_requested_visibility")
5007
5013
  .notNull()
5008
5014
  .default("workspace_shared"),
@@ -12885,6 +12891,8 @@ export const modelCallFacts = pgTable(
12885
12891
  initiatorKind: text("initiator_kind"),
12886
12892
  initiatorSubjectId: text("initiator_subject_id"),
12887
12893
  scheduledTaskId: uuid("scheduled_task_id"),
12894
+ // Source-stamped attribution survives session/Site deletion. Not a foreign key.
12895
+ siteId: uuid("site_id"),
12888
12896
  inputTokens: bigint("input_tokens", { mode: "number" }),
12889
12897
  outputTokens: bigint("output_tokens", { mode: "number" }),
12890
12898
  cachedTokens: bigint("cached_tokens", { mode: "number" }),
@@ -13251,6 +13259,8 @@ export const creditLedgerEntries = pgTable(
13251
13259
  currency: text("currency").notNull().default("usd"),
13252
13260
  sourceType: text("source_type"),
13253
13261
  sourceId: text("source_id"),
13262
+ // Immutable execution-origin attribution, not an allocated platform charge.
13263
+ siteId: uuid("site_id"),
13254
13264
  idempotencyKey: text("idempotency_key").notNull(),
13255
13265
  metadata: jsonb("metadata").$type<Record<string, unknown>>().notNull().default({}),
13256
13266
  occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull().defaultNow(),
@@ -1705,6 +1705,41 @@ export async function listActiveSiteRuntimeConversations(
1705
1705
  );
1706
1706
  }
1707
1707
 
1708
+ /** Keyset-paged lifecycle inventory; no viewer transcript or age/count cutoff. */
1709
+ export async function listSiteRuntimeCancellationCandidates(
1710
+ db: Database,
1711
+ scope: SitePublishingScope,
1712
+ input: {
1713
+ siteId: string;
1714
+ after?: string;
1715
+ limit: number;
1716
+ startedBefore: Date;
1717
+ toolsNarrowedTo?: { tools: readonly string[]; everyoneTools: boolean };
1718
+ },
1719
+ ): Promise<string[]> {
1720
+ const narrowed = input.toolsNarrowedTo;
1721
+ return withRlsContext(db, scope, async (tx) =>
1722
+ (
1723
+ await rawRows<{ session_id: string }>(
1724
+ tx,
1725
+ sql`
1726
+ select c.session_id from site_runtime_conversations c
1727
+ where c.account_id=${scope.accountId} and c.workspace_id=${scope.workspaceId}
1728
+ and c.site_id=${input.siteId} and c.created_at <= ${input.startedBefore.toISOString()}::timestamptz
1729
+ ${input.after ? sql`and c.session_id > ${input.after}::uuid` : sql``}
1730
+ ${
1731
+ narrowed
1732
+ ? sql`and (not (c.tool_ids <@ ${JSON.stringify(narrowed.tools)}::jsonb)
1733
+ or (${!narrowed.everyoneTools} and jsonb_array_length(c.tool_ids)>0 and c.viewer_kind in ('user','guest')))`
1734
+ : sql``
1735
+ }
1736
+ order by c.session_id limit ${Math.max(1, Math.min(input.limit, 200))}
1737
+ `,
1738
+ )
1739
+ ).map((row) => row.session_id),
1740
+ );
1741
+ }
1742
+
1708
1743
  export type SiteRuntimeUsageSnapshot = {
1709
1744
  visitorDay: { conversations: number; agentMicros: number; reservedMicros: number };
1710
1745
  visitorMonth: { conversations: number; agentMicros: number; reservedMicros: number };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/persistence-errors.ts","../src/database-timing.ts","../src/database.ts"],"sourcesContent":["export type DatabaseFailureCode = \"db_deadlock\" | \"db_serialization_failure\" | \"db_failure\";\n\nexport type PersistenceRetryOutcome = \"not_retryable\" | \"exhausted\";\n\nexport type SafeDatabaseErrorFacts = {\n severity?: string;\n schema?: string;\n table?: string;\n column?: string;\n dataType?: string;\n constraint?: string;\n routine?: string;\n};\n\nexport type PersistenceFailureDetails = {\n code: DatabaseFailureCode;\n sqlState: string | null;\n stage: string;\n eventTypes: string[];\n correlationId: string;\n attempts: number;\n retryOutcome: PersistenceRetryOutcome;\n database: SafeDatabaseErrorFacts;\n};\n\nconst SQLSTATE_KEYS = [\"sqlState\", \"sqlstate\", \"code\"] as const;\nconst NESTED_ERROR_KEYS = [\"cause\", \"original\", \"driverError\", \"error\", \"errors\"] as const;\nconst RETRYABLE_DATABASE_TRANSPORT_CODES = new Set([\n // postgres.js connection lifecycle failures.\n \"CONNECTION_CLOSED\",\n \"CONNECTION_DESTROYED\",\n \"CONNECTION_ENDED\",\n \"CONNECT_TIMEOUT\",\n // Node socket/DNS failures surfaced unchanged by postgres.js.\n \"EAI_AGAIN\",\n \"ECONNABORTED\",\n \"ECONNREFUSED\",\n \"ECONNRESET\",\n \"EHOSTDOWN\",\n \"EHOSTUNREACH\",\n \"ENETDOWN\",\n \"ENETRESET\",\n \"ENETUNREACH\",\n \"ENOTFOUND\",\n \"EPIPE\",\n \"ETIMEDOUT\",\n]);\nconst DATABASE_ERROR_NAMES = new Set([\"DatabaseError\", \"DrizzleQueryError\", \"PostgresError\"]);\nconst DATABASE_DIAGNOSTIC_KEYS = [\n \"severity\",\n \"schema_name\",\n \"table_name\",\n \"column_name\",\n \"data_type_name\",\n \"constraint_name\",\n \"routine\",\n] as const;\nconst SAFE_FACT_KEYS = [\n [\"severity\", \"severity\"],\n [\"schema_name\", \"schema\"],\n [\"schema\", \"schema\"],\n [\"table_name\", \"table\"],\n [\"table\", \"table\"],\n [\"column_name\", \"column\"],\n [\"column\", \"column\"],\n [\"data_type_name\", \"dataType\"],\n [\"dataType\", \"dataType\"],\n [\"constraint_name\", \"constraint\"],\n [\"constraint\", \"constraint\"],\n [\"routine\", \"routine\"],\n] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\");\n}\n\nfunction safeFact(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n return value;\n}\n\n/** Find the driver SQLSTATE even when Drizzle wrapped it under nested causes. */\nexport function nestedPostgresSqlState(error: unknown): string | null {\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n let fallback: string | null = null;\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n for (const key of SQLSTATE_KEYS) {\n const value = current[key];\n if (typeof value !== \"string\" || !/^[0-9A-Z]{5}$/i.test(value)) continue;\n const normalized = value.toUpperCase();\n // Node transport codes such as EPIPE happen to be five characters but\n // are not PostgreSQL SQLSTATEs.\n if (RETRYABLE_DATABASE_TRANSPORT_CODES.has(normalized)) continue;\n if (normalized === \"40P01\" || normalized === \"40001\") return normalized;\n fallback ??= normalized;\n }\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return fallback;\n}\n\nexport function databaseFailureCode(sqlState: string | null): DatabaseFailureCode {\n if (sqlState === \"40P01\") return \"db_deadlock\";\n if (sqlState === \"40001\") return \"db_serialization_failure\";\n return \"db_failure\";\n}\n\nexport function isRetryablePersistenceSqlState(sqlState: string | null): boolean {\n return sqlState === \"40P01\" || sqlState === \"40001\";\n}\n\n/**\n * Recognize only explicit postgres.js/Node transport codes, including nested\n * driver causes. These failures can arrive as plain Errors with no SQLSTATE or\n * database diagnostic fields when the connection dies before PostgreSQL can\n * answer. Messages are intentionally ignored: they are unstable and may\n * contain connection detail.\n */\nexport function isRetryableDatabaseTransportFailure(error: unknown): boolean {\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n\n for (const key of [\"code\", \"errno\"] as const) {\n const value = current[key];\n if (\n typeof value === \"string\" &&\n RETRYABLE_DATABASE_TRANSPORT_CODES.has(value.toUpperCase())\n ) {\n return true;\n }\n }\n\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return false;\n}\n\n/**\n * SQLSTATEs PostgreSQL sends when it ends or refuses the session itself:\n * operator intervention (`pg_terminate_backend`, shutdown, crash recovery,\n * \"the database system is starting up\") and the connection-exception class.\n */\nconst DATABASE_CONNECTION_LOSS_SQLSTATES = new Set([\n \"57P01\", // admin_shutdown (pg_terminate_backend, smart/fast shutdown)\n \"57P02\", // crash_shutdown\n \"57P03\", // cannot_connect_now\n \"08000\", // connection_exception\n \"08001\", // sqlclient_unable_to_establish_sqlconnection\n \"08003\", // connection_does_not_exist\n \"08004\", // sqlserver_rejected_establishment_of_sqlconnection\n \"08006\", // connection_failure\n]);\n\n/**\n * node-postgres (Better Auth's pool) reports a lost socket as a plain Error with\n * no code. Only these exact library sentences are recognized.\n */\nconst NODE_POSTGRES_CONNECTION_LOSS_MESSAGES = new Set([\n \"Connection terminated unexpectedly\",\n \"Connection terminated\",\n \"Connection terminated due to connection timeout\",\n \"Client has encountered a connection error and is not queryable\",\n \"Client was closed and is not queryable\",\n]);\n\n/**\n * Explicit marker for a dependency that hid its driver error behind its own\n * generic failure but is known to have failed reading the database.\n */\nexport class DatabaseUnavailableError extends Error {\n readonly code = \"DATABASE_UNAVAILABLE\";\n\n constructor(message = \"database unavailable\", options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"DatabaseUnavailableError\";\n }\n}\n\n/**\n * True when a failure means the database connection itself went away (an\n * operator drain, failover, restart, or socket loss), not that a statement was\n * rejected. Such a failure is transient: a fresh pooled connection succeeds once\n * the server accepts connections again. It says nothing about whether a write\n * in flight committed.\n *\n * Socket and postgres.js transport codes (`ECONNRESET`, `CONNECTION_CLOSED`,\n * ...) count only when the same failure proves it came from the database: a\n * query-bearing driver or ORM error, a PostgresError, or postgres.js's own\n * connection error. The same codes from NATS, a provider fetch, or a browser\n * transport are not database loss.\n */\nexport function isDatabaseConnectionLoss(error: unknown): boolean {\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n let transportFailure = false;\n let databaseOrigin = false;\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n if (current instanceof DatabaseUnavailableError) return true;\n for (const key of SQLSTATE_KEYS) {\n const value = current[key];\n if (\n typeof value === \"string\" &&\n DATABASE_CONNECTION_LOSS_SQLSTATES.has(value.toUpperCase())\n ) {\n return true;\n }\n }\n if (\n typeof current.message === \"string\" &&\n NODE_POSTGRES_CONNECTION_LOSS_MESSAGES.has(current.message)\n ) {\n return true;\n }\n if (hasTransportCode(current)) transportFailure = true;\n if (isDatabaseOrigin(current)) databaseOrigin = true;\n if (transportFailure && databaseOrigin) return true;\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return false;\n}\n\nfunction hasTransportCode(current: Record<string, unknown>): boolean {\n return ([\"code\", \"errno\"] as const).some((key) => {\n const value = current[key];\n return typeof value === \"string\" && RETRYABLE_DATABASE_TRANSPORT_CODES.has(value.toUpperCase());\n });\n}\n\nfunction isDatabaseOrigin(current: Record<string, unknown>): boolean {\n if (typeof current.name === \"string\" && DATABASE_ERROR_NAMES.has(current.name)) return true;\n // postgres.js stamps the failed query onto its error; Drizzle wraps it as\n // DrizzleQueryError with `query` + `params`.\n if (typeof current.query === \"string\") return true;\n // postgres.js connection errors: `write <CODE> <host:port>` with errno === code.\n return (\n typeof current.code === \"string\" &&\n current.errno === current.code &&\n \"address\" in current &&\n typeof current.message === \"string\" &&\n current.message.startsWith(`write ${current.code} `)\n );\n}\n\n/**\n * Distinguish database/ORM failures from expected domain exceptions when a\n * driver omitted SQLSTATE. This checks shape only; callers retain the original\n * failure independently as canonical error evidence.\n */\nexport function isDatabasePersistenceFailure(error: unknown): boolean {\n if (isRetryableDatabaseTransportFailure(error) || nestedPostgresSqlState(error) !== null) {\n return true;\n }\n\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n\n if (typeof current.name === \"string\" && DATABASE_ERROR_NAMES.has(current.name)) {\n return true;\n }\n if (\n typeof current.query === \"string\" &&\n (Object.hasOwn(current, \"params\") || Object.hasOwn(current, \"parameters\"))\n ) {\n return true;\n }\n if (DATABASE_DIAGNOSTIC_KEYS.some((key) => Object.hasOwn(current, key))) {\n return true;\n }\n\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return false;\n}\n\n/** Extract only PostgreSQL diagnostic identifiers; never query text/parameters. */\nexport function safeDatabaseErrorFacts(error: unknown): SafeDatabaseErrorFacts {\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n const facts: SafeDatabaseErrorFacts = {};\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n for (const [source, destination] of SAFE_FACT_KEYS) {\n if (facts[destination] !== undefined) continue;\n const value = safeFact(current[source]);\n if (value !== undefined) facts[destination] = value;\n }\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return facts;\n}\n\n/** Own-driver transaction boundary; callback errors never establish provenance. */\nexport class DatabaseTransactionError extends Error {\n readonly name = \"DatabaseTransactionError\";\n\n constructor(\n readonly stage: \"admission\" | \"settlement\",\n cause: unknown,\n // A rollback failure must not erase a callback's no-replay/permanent\n // evidence. The recovery classifier inspects both branches for vetoes.\n readonly original?: unknown,\n ) {\n super(`Database transaction ${stage} failed`, { cause });\n }\n}\n\n/** Typed persistence classification retaining the original cause internally.\n * Its ordinary message is stable and contains no SQL or driver parameters. */\nexport class SessionEventPersistenceError extends Error {\n readonly name = \"SessionEventPersistenceError\";\n\n constructor(\n readonly details: PersistenceFailureDetails,\n cause?: unknown,\n ) {\n const label =\n details.code === \"db_deadlock\"\n ? \"Database deadlock\"\n : details.code === \"db_serialization_failure\"\n ? \"Database serialization failure\"\n : \"Database failure\";\n const operation = `${label} while persisting ${details.eventTypes.join(\", \") || \"session events\"}`;\n super(operation, cause === undefined ? undefined : { cause });\n }\n\n get code(): DatabaseFailureCode {\n return this.details.code;\n }\n}\n\nexport function isSessionEventPersistenceError(\n error: unknown,\n): error is SessionEventPersistenceError {\n return error instanceof SessionEventPersistenceError;\n}\n\nexport type IdempotentPersistenceTransactionOptions = {\n stage: string;\n eventTypes?: string[];\n maxAttempts?: number;\n correlationId?: string;\n onRetry?: (input: { attempt: number; sqlState: \"40P01\" | \"40001\" }) => void | Promise<void>;\n};\n\n/**\n * Retry only the supplied idempotent database transaction/savepoint. Provider\n * inference, tools, NATS, and all other external effects must remain outside\n * this function. A single correlation ID follows every persistence attempt.\n */\nexport async function runIdempotentPersistenceTransaction<T>(\n options: IdempotentPersistenceTransactionOptions,\n transaction: (attempt: number) => Promise<T>,\n): Promise<T> {\n const maxAttempts = options.maxAttempts ?? 3;\n if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {\n throw new Error(\"Persistence maxAttempts must be a positive integer\");\n }\n const correlationId = options.correlationId ?? crypto.randomUUID();\n const eventTypes = [...new Set(options.eventTypes ?? [])].sort();\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n try {\n return await transaction(attempt);\n } catch (error) {\n const sqlState = nestedPostgresSqlState(error);\n const retryable = isRetryablePersistenceSqlState(sqlState);\n if (retryable && attempt < maxAttempts) {\n await options.onRetry?.({\n attempt,\n sqlState: sqlState as \"40P01\" | \"40001\",\n });\n continue;\n }\n if (!isDatabasePersistenceFailure(error)) throw error;\n throw new SessionEventPersistenceError(\n {\n code: databaseFailureCode(sqlState),\n sqlState,\n stage: options.stage,\n eventTypes,\n correlationId,\n attempts: attempt,\n retryOutcome: retryable ? \"exhausted\" : \"not_retryable\",\n database: safeDatabaseErrorFacts(error),\n },\n error,\n );\n }\n }\n throw new Error(\"Unreachable persistence retry state\");\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport type DatabaseTimingStage =\n | \"transaction_admission\"\n | \"savepoint_admission\"\n | \"rls_setup\"\n | \"scoped_callback\";\nexport type DatabaseTimingObservation = {\n stage: DatabaseTimingStage;\n outcome: \"completed\" | \"failed\";\n durationMs: number;\n};\nexport type DatabaseTimingObserver = (observation: DatabaseTimingObservation) => void;\n\nconst timingObserver = new AsyncLocalStorage<DatabaseTimingObserver>();\n\n/** Opt-in, async-local diagnostics only; no identity or query payload is retained. */\nexport function withDatabaseTimingObserver<T>(\n observer: DatabaseTimingObserver,\n work: () => Promise<T>,\n): Promise<T> {\n return timingObserver.run(observer, work);\n}\n\nexport function startDatabaseTiming(\n stage: DatabaseTimingStage,\n): (outcome: DatabaseTimingObservation[\"outcome\"]) => void {\n const observer = timingObserver.getStore();\n if (!observer) return () => undefined;\n const started = performance.now();\n let finished = false;\n return (outcome) => {\n if (finished) return;\n finished = true;\n try {\n // Do not await observers or let rejected async observers escape either.\n const result = observer({ stage, outcome, durationMs: performance.now() - started });\n void Promise.resolve(result).catch(() => undefined);\n } catch {\n // Diagnostics must not replace database results or the original error.\n }\n };\n}\n","import type { SessionAttachmentReadAccess } from \"./session-file-attachments\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { eq, sql, type SQL } from \"drizzle-orm\";\nimport type { PgDatabase, PgTransactionConfig } from \"drizzle-orm/pg-core\";\nimport { drizzle } from \"drizzle-orm/postgres-js\";\nimport postgres from \"postgres\";\nimport { databaseBootConnectOptions } from \"./boot-connect\";\n\nimport {\n DatabaseTransactionError,\n isDatabasePersistenceFailure,\n runIdempotentPersistenceTransaction,\n type IdempotentPersistenceTransactionOptions,\n} from \"./persistence-errors\";\nimport { LOSSLESS_CONTENT_WRITER_APPLICATION_NAME } from \"./lossless-json\";\nimport * as schema from \"./schema\";\nimport { startDatabaseTiming } from \"./database-timing\";\n\n// §7.7 driver widening (Step I). `Database` is the structural, cross-driver\n// query-layer port: every helper in this file accepts `db: Database` and uses\n// only the methods present on drizzle's base `PgDatabase` (select/insert/update/\n// delete/transaction/execute). Widening from the concrete\n// `PostgresJsDatabase<typeof schema>` to `PgDatabase<any, typeof schema>` is a\n// pure TYPE change — no runtime behavior changes — that lets an embedded host\n// inject ANY drizzle pg driver handle (node-postgres, neon-http, etc.) bound to\n// Opengeni's schema, not just the postgres-js handle `createDb` builds. The\n// `any` for the query-result HKT is deliberate: it keeps `db.execute(sql\\`…\\`)`\n// callable across drivers whose raw-result shapes differ (postgres-js returns a\n// row array; node-postgres returns `{ rows }`). The three raw `db.execute(…)`\n// reads that index a row array (`getManagedUserByEmail` here is the only\n// host-facing one — see `userLookup`) stay postgres-js-shaped for standalone;\n// `userLookup` is the injection seam for hosts on a different driver.\n// `PostgresJsDatabase<typeof schema>` is assignable to this, so standalone is\n// unaffected.\n\nexport type Database = PgDatabase<any, typeof schema>;\n\ndeclare const sessionActivityDatabaseBrand: unique symbol;\n\n/**\n * A workspace-scoped transaction whose session activity commit gate is open.\n * Session-row writers accept this narrower handle so new call sites cannot\n * accidentally bypass the once-per-transaction revision finalizer.\n */\nexport type SessionActivityDatabase = Database & {\n readonly [sessionActivityDatabaseBrand]: true;\n};\n\nexport type DbClient = {\n db: Database;\n close: () => Promise<void>;\n};\n\nexport type RlsContext = {\n accountId: string;\n workspaceId?: string | null;\n};\n\nexport type SessionRlsActorContext = {\n /** Server-authorized session attachment scope; never taken from request JSON. */\n sessionAttachmentReadAccess?: SessionAttachmentReadAccess;\n subjectId: string;\n /** Host-verified personal file ownership, never a request-supplied subject. */\n privateFileOwnerSubjectId?: string | null;\n initiatingHumanSubjectId?: string | null;\n};\n\nconst sessionRlsActorContext = new AsyncLocalStorage<SessionRlsActorContext>();\nexport function currentSessionAttachmentReadAccess(): SessionAttachmentReadAccess | undefined {\n return sessionRlsActorContext.getStore()?.sessionAttachmentReadAccess;\n}\n\n/**\n * The ambient session RLS actor established by the caller, if any. Read-only:\n * helpers use it to decide whether the caller already owns session access and\n * must never mutate it.\n */\nexport function currentSessionRlsActorContext(): Readonly<SessionRlsActorContext> | undefined {\n return sessionRlsActorContext.getStore();\n}\n\n/**\n * Stable identity of the ambient session RLS actor: every field that\n * `setRlsContext` turns into database-visible GUCs or that scoped reads\n * consult. Two callers with equal keys see exactly the same rows, so the key\n * is safe for sharing a read result between them; `null` means no actor, in\n * which case the subject GUC stays empty for every such caller.\n */\nexport function currentSessionRlsActorIdentityKey(): string | null {\n const actor = sessionRlsActorContext.getStore();\n if (!actor) return null;\n return JSON.stringify([\n actor.subjectId,\n actor.initiatingHumanSubjectId ?? null,\n actor.privateFileOwnerSubjectId ?? null,\n actor.sessionAttachmentReadAccess ?? null,\n ]);\n}\n\n/**\n * The ambient session RLS actor's frozen initiating human: `undefined` when\n * there is no actor, `null` when the actor has no human. Reads that must act\n * for the turn's human take it from here, never from a caller argument.\n */\nexport function currentSessionRlsActorInitiatingHumanSubjectId(): string | null | undefined {\n const actor = sessionRlsActorContext.getStore();\n if (!actor) return undefined;\n return actor.initiatingHumanSubjectId ?? null;\n}\n\nexport async function withSessionRlsActorContext<T>(\n actor: SessionRlsActorContext,\n fn: () => Promise<T>,\n): Promise<T> {\n if (!actor.subjectId.trim()) {\n throw new Error(\"withSessionRlsActorContext: a non-empty subjectId is required\");\n }\n if (\n actor.initiatingHumanSubjectId !== undefined &&\n actor.initiatingHumanSubjectId !== null &&\n !actor.initiatingHumanSubjectId.trim()\n ) {\n throw new Error(\n \"withSessionRlsActorContext: initiatingHumanSubjectId must be null or non-empty\",\n );\n }\n if (\n actor.privateFileOwnerSubjectId !== undefined &&\n actor.privateFileOwnerSubjectId !== null &&\n !actor.privateFileOwnerSubjectId.trim()\n ) {\n throw new Error(\n \"withSessionRlsActorContext: privateFileOwnerSubjectId must be null or non-empty\",\n );\n }\n return await sessionRlsActorContext.run(actor, fn);\n}\n\ntype RlsContextSettings = {\n accountId: string;\n workspaceId: string;\n subjectId: string;\n privateFileOwnerSubjectId: string;\n initiatingHumanSubjectId: string;\n personalResourceHumanSubjectId: string;\n personalResourceActorSubjectId: string;\n};\n\n/**\n * RLS posture for the connection Opengeni's query layer runs over (Step I, §7.7).\n *\n * - `\"force\"` (DEFAULT — today's standalone behavior, byte-for-byte): Opengeni\n * connects as a NON-OWNER role (`opengeni_app`) and every table carries\n * `FORCE ROW LEVEL SECURITY`, so the workspace/account GUCs set by\n * `setRlsContext` are the ONLY thing that admits rows — even the table owner\n * is subject to RLS. This is the Fork-A isolation guarantee.\n * - `\"scoped\"` (embedded Fork-B opt-in): the host runs Opengeni's queries over a\n * role that OWNS the dedicated schema (RLS need not be forced for that role),\n * relying on the host's own tenant boundary. Opengeni STILL emits the\n * `set_config('opengeni.account_id'/'workspace_id', …)` GUCs defensively on\n * every scoped query, so the application query path is byte-identical between\n * the two strategies and the app code is RLS-mode-agnostic. The strategy is a\n * declared posture (consumed by `provisionRoles` and as a documented\n * invariant), NOT a query-path branch — there is deliberately no `if\n * (strategy === …)` anywhere in the helpers below. Picking `\"scoped\"` does not\n * relax any GUC; it only changes which DB role the host provisions/connects as\n * and asserts that the host accepts owning the isolation boundary.\n */\nexport type RlsStrategy = \"force\" | \"scoped\";\n\n/**\n * Resolve a host-IdP/Better-Auth user *identifier* by email. Injected via\n * `createDb({ userLookup })` (Step I). UNSET → today's raw parameterized select\n * against Better Auth's `auth_users` table (see `getManagedUserByEmail`), which\n * relies on the postgres-js array-shaped `db.execute` result. An embedded host\n * whose identity lives elsewhere (a different IdP table, a different driver, or\n * a non-`auth_users` user store) injects this closure so Opengeni never touches\n * `auth_users` directly. Returns the user id, or null when no such user exists.\n */\nexport type UserLookup = (db: Database, email: string) => Promise<string | null>;\n\nexport type ManagedUserProfile = {\n id: string;\n name: string | null;\n email: string;\n};\n\n/** Host identity projection used by organization administration rosters. */\nexport type UserProfileLookup = (\n db: Database,\n userIds: readonly string[],\n) => Promise<ManagedUserProfile[]>;\n\nexport type CreateDbOptions = {\n /**\n * The Postgres `search_path` for this connection (Step I, §7.8 runtime half).\n * UNSET → today's behavior: NO `search_path` startup parameter is sent, so the\n * server default applies (`public` for standalone, where every table + the\n * `vector` extension + `gen_random_uuid()` live). For an embedded dedicated\n * schema, pass e.g. `\"opengeni,opengeni_private,public\"` — postgres-js sends\n * it as a per-session startup parameter (the supported, query-param-free way;\n * URL `?search_path=` is IGNORED by postgres-js). Keep `public` LAST so the\n * `vector` type and `gen_random_uuid()` (which live in `public` on the\n * pgvector image) still resolve — the schema-isolation contract live footgun.\n */\n searchPath?: string;\n /** RLS posture; defaults to `\"force\"` (today's standalone). */\n rlsStrategy?: RlsStrategy;\n /** Host-provided user-by-email resolver; unset → today's raw `auth_users` query. */\n userLookup?: UserLookup;\n /** Host-provided user profile projection; unset → standalone `auth_users`. */\n userProfileLookup?: UserProfileLookup;\n /** postgres-js pool size; defaults to today's `10`. */\n max?: number;\n /**\n * How long a refused first connection is retried while the client has never\n * reached the server; defaults to the boot grace. 0 fails immediately.\n */\n bootConnectGraceMs?: number;\n /**\n * Connection-local default transaction isolation sent in the postgres-js\n * startup parameters. This is intentionally not a role/database default:\n * tests and embedded callers can exercise a different ambient isolation\n * without mutating a shared PostgreSQL role or affecting other connections.\n */\n isolationLevel?: postgres.ConnectionParameters[\"default_transaction_isolation\"];\n};\n\n/**\n * The active RLS strategy + userLookup for an injected `Database`, recorded in a\n * side WeakMap so helpers (and `getManagedUserByEmail`) can consult the host's\n * binding without changing every call signature. A handle with no recorded\n * config (e.g. one built outside `createDb`, or in a test) falls back to the\n * standalone defaults: `rlsStrategy: \"force\"`, raw `auth_users` lookup.\n */\ntype DbBinding = {\n rlsStrategy: RlsStrategy;\n userLookup?: UserLookup;\n userProfileLookup?: UserProfileLookup;\n};\n\nconst dbBindings = new WeakMap<object, DbBinding>();\n\n/** The strategy bound to a handle (or the `\"force\"` default). */\nexport function rlsStrategyFor(db: Database): RlsStrategy {\n return dbBindings.get(db as unknown as object)?.rlsStrategy ?? \"force\";\n}\n\n/**\n * Run a raw SQL query and read its rows as a typed array.\n *\n * Why this exists: the Step I driver widening (`Database = PgDatabase<any, …>`)\n * deliberately sets the query-result HKT to `any` so `db.execute(…)` is callable\n * across drivers whose raw-result shapes differ (postgres-js → row array;\n * node-postgres → `{ rows }`). A side effect is that `db.execute<T>(…)` now\n * resolves to `any`, erasing the per-row element type at the call site. Opengeni's\n * OWN internal raw queries usually run over the postgres-js handle `createDb`\n * builds (array result), while an embedded host may inject a node-postgres style\n * driver (`{ rows }`). Normalize those two standard shapes in one place; reject\n * an unknown driver result rather than silently treating it as an empty query.\n */\nexport async function rawRows<T extends Record<string, unknown>>(\n executor: Pick<Database, \"execute\">,\n query: SQL,\n): Promise<T[]> {\n const result = await executor.execute<T>(query);\n if (Array.isArray(result)) {\n return result as unknown as T[];\n }\n const rows = (result as unknown as { rows?: unknown }).rows;\n if (Array.isArray(rows)) {\n return rows as T[];\n }\n throw new Error(\"Unsupported database execute() result shape\");\n}\n\nexport type SandboxProviderReadLockIdentity = {\n workspaceId: string;\n sandboxGroupId: string;\n leaseEpoch: number;\n instanceId: string;\n};\n\nexport class SandboxProviderReadLockUnavailableError extends Error {\n constructor() {\n super(\"Sandbox provider reads are temporarily busy. Retry the request.\");\n this.name = \"SandboxProviderReadLockUnavailableError\";\n }\n}\n\nconst SANDBOX_PROVIDER_READ_LOCK_WAIT_MS = 15_000;\nconst SANDBOX_PROVIDER_READ_LOCK_POLL_MAX_MS = 200;\n\nfunction sandboxProviderReadLockKey(identity: SandboxProviderReadLockIdentity): string {\n return [\n \"sandbox-provider-read\",\n identity.workspaceId,\n identity.sandboxGroupId,\n identity.leaseEpoch,\n identity.instanceId,\n ].join(\":\");\n}\n\nasync function waitForSandboxProviderReadLockPoll(\n delayMs: number,\n signal?: AbortSignal | undefined,\n): Promise<void> {\n if (signal?.aborted) {\n throw signal.reason ?? new DOMException(\"The operation was aborted\", \"AbortError\");\n }\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout>;\n const cleanup = () => signal?.removeEventListener(\"abort\", abort);\n const finish = () => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n };\n const abort = () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n cleanup();\n reject(signal?.reason ?? new DOMException(\"The operation was aborted\", \"AbortError\"));\n };\n timer = setTimeout(finish, delayMs);\n signal?.addEventListener(\"abort\", abort, { once: true });\n if (signal?.aborted) abort();\n });\n}\n\n/**\n * Cross-process exclusive boundary for one exact live provider instance's\n * API-direct read request. Modal accepts concurrent commands from one attached\n * handle, but independent API replicas reconstruct different handles; issuing\n * overlapping command groups through those handles can make an otherwise valid\n * read fail transiently. Keep concurrency inside one batched request while\n * serializing only separate requests that target the same lease identity.\n *\n * The callback intentionally runs while one transaction-pinned DB connection\n * holds the advisory lock. The direct lease holder separately prevents drain,\n * and the abort-aware bounded poll prevents a disconnected HTTP request from\n * occupying the connection indefinitely.\n */\nexport async function withSandboxProviderReadLock<T>(\n db: Database,\n identity: SandboxProviderReadLockIdentity,\n signal: AbortSignal | undefined,\n fn: () => Promise<T>,\n): Promise<T> {\n const key = sandboxProviderReadLockKey(identity);\n const deadline = Date.now() + SANDBOX_PROVIDER_READ_LOCK_WAIT_MS;\n return await db.transaction(async (lockedDb) => {\n let pollMs = 20;\n while (true) {\n if (signal?.aborted) {\n throw signal.reason ?? new DOMException(\"The operation was aborted\", \"AbortError\");\n }\n const [row] = await rawRows<{ acquired: boolean }>(\n lockedDb,\n sql`select pg_try_advisory_xact_lock(hashtextextended(${key}, 0)) as acquired`,\n );\n if (row?.acquired === true) return await fn();\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) throw new SandboxProviderReadLockUnavailableError();\n await waitForSandboxProviderReadLockPoll(Math.min(pollMs, remainingMs), signal);\n pollMs = Math.min(pollMs * 2, SANDBOX_PROVIDER_READ_LOCK_POLL_MAX_MS);\n }\n });\n}\n\n/** Jittered reconnect delay in seconds after `retries` consecutive connection failures. */\nexport function databaseReconnectBackoffSeconds(retries: number): number {\n return (0.5 + Math.random() / 2) * Math.min(3 ** retries / 100, 2);\n}\n\nexport function createDb(databaseUrl: string, options: CreateDbOptions = {}): DbClient {\n // `prepare: false` is REQUIRED for Azure Database for PostgreSQL Flexible\n // Server's transaction-pooling PgBouncer: postgres-js's default named prepared\n // statements (`s_N`) are bound to one backend, but a transaction pooler hands\n // each transaction a different backend, so a later `execute` intermittently\n // throws `prepared statement \"s_N\" does not exist`. Every RLS read in this\n // module (set_config + SELECT inside one db.transaction) rides on this pool, so\n // the failure surfaces as a \"worked, then didn't\" credential/permission read.\n // idle_timeout + max_lifetime recycle connections so a pooler-recycled backend\n // is never reused indefinitely; application_name aids server-side diagnostics.\n const client = postgres(databaseUrl, {\n max: options.max ?? 10,\n prepare: false,\n idle_timeout: 30,\n max_lifetime: 1800,\n // postgres.js grows one pool-wide reconnect delay after every refused or\n // reset connection (3^n / 100 s, up to 20 s) and queues queries behind it.\n // After a restart or failover that left the server refusing connections\n // for a while, requests then hung for up to 20 s after it was back. Keep\n // the same jittered growth but cap it at 2 s.\n backoff: databaseReconnectBackoffSeconds,\n // A fresh pod can be refused for a moment while its network policy and DNS\n // settle; retry that first connection briefly instead of failing boot.\n ...databaseBootConnectOptions(databaseUrl, options.bootConnectGraceMs),\n // `connection` carries per-session Postgres STARTUP parameters. The exact\n // `application_name` is also the PgBouncer-compatible current-image receipt\n // for migration 0352's restrictive sessions policy; arbitrary custom startup\n // parameters are not portable through transaction poolers. `search_path`\n // (embedded only) is the supported, query-param-free way to scope a connection\n // to a dedicated schema — postgres-js IGNORES a URL `?search_path=`. Unset\n // searchPath → omit it so the server default (`public`) is unchanged for\n // standalone.\n connection: {\n application_name: LOSSLESS_CONTENT_WRITER_APPLICATION_NAME,\n ...(options.searchPath ? { search_path: options.searchPath } : {}),\n ...(options.isolationLevel ? { default_transaction_isolation: options.isolationLevel } : {}),\n },\n });\n const db = drizzle(client, { schema });\n dbBindings.set(db as unknown as object, {\n rlsStrategy: options.rlsStrategy ?? \"force\",\n ...(options.userLookup ? { userLookup: options.userLookup } : {}),\n ...(options.userProfileLookup ? { userProfileLookup: options.userProfileLookup } : {}),\n });\n return {\n db,\n close: async () => {\n await client.end();\n },\n };\n}\n\n/**\n * Register a host's `rlsStrategy`/`userLookup` against an externally-constructed\n * `Database` handle (e.g. one the embedded host built from its own driver and\n * injected, rather than via `createDb`). Lets the same WeakMap-backed lookups\n * work for injected handles. Standalone never calls this (it uses `createDb`).\n */\nexport function registerDbBinding(\n db: Database,\n binding: {\n rlsStrategy?: RlsStrategy;\n userLookup?: UserLookup;\n userProfileLookup?: UserProfileLookup;\n },\n): void {\n dbBindings.set(db as unknown as object, {\n rlsStrategy: binding.rlsStrategy ?? \"force\",\n ...(binding.userLookup ? { userLookup: binding.userLookup } : {}),\n ...(binding.userProfileLookup ? { userProfileLookup: binding.userProfileLookup } : {}),\n });\n}\n\nexport async function setRlsContext(db: Database, context: RlsContext): Promise<void> {\n // Fail loud on an empty/blank account id: a \"\" account would set an RLS GUC\n // that matches no tenant row, silently returning zero rows from every scoped\n // read (a phantom \"not found\" / \"no active subscription\"). An RLS context with\n // no account is always a bug at the call site, never a valid query scope.\n if (typeof context.accountId !== \"string\" || context.accountId.trim() === \"\") {\n throw new Error(\"setRlsContext: a non-empty accountId is required to establish an RLS context\");\n }\n // Transaction-local writer identity covers supported injected/embedded\n // database handles whose connection-level application_name is host-owned.\n // Standalone createDb connections also carry version receipts in their exact\n // application_name, while old Opengeni binaries set neither current receipt.\n //\n // JIT is off for these short request transactions: row-level security\n // functions inflate planner cost estimates past jit_above_cost, so PostgreSQL\n // spent seconds compiling queries that execute in milliseconds (the session\n // list's tree-stats query: 0.4 s of work behind 3.8 s of JIT). Transaction-local,\n // so it is safe behind transaction poolers and never leaks to other work.\n await db.execute(sql`select\n set_config('opengeni.account_id', ${context.accountId}, true),\n set_config('opengeni.workspace_id', ${context.workspaceId ?? \"\"}, true),\n set_config('opengeni.lossless_content_writer', '1', true),\n set_config('opengeni.sandbox_recovery_protocol_v2', '1', true),\n set_config('opengeni.pending_tool_event_output_v1', '1', true),\n set_config('opengeni.session_variable_set_attachments_v1', '1', true),\n set_config('opengeni.shared_personal_choice_v1', '1', true),\n set_config('jit', 'off', true)`);\n const sessionActor = sessionRlsActorContext.getStore();\n if (sessionActor) {\n await setSubjectRlsContext(db, sessionActor.subjectId);\n await db.execute(\n sql`select set_config('opengeni.private_file_owner', ${sessionActor.privateFileOwnerSubjectId ?? \"\"}, true), set_config(\n 'opengeni.initiating_human_subject_id',\n ${sessionActor.initiatingHumanSubjectId ?? \"\"},\n true\n )`,\n );\n }\n}\n\nasync function readRlsContextSettings(db: Database): Promise<RlsContextSettings> {\n const [settings] = await rawRows<{\n account_id: string | null;\n workspace_id: string | null;\n subject_id: string | null;\n private_file_owner: string | null;\n initiating_human_subject_id: string | null;\n personal_resource_human_subject_id: string | null;\n personal_resource_actor_subject_id: string | null;\n }>(\n db,\n sql`select\n current_setting('opengeni.account_id', true) as account_id,\n current_setting('opengeni.workspace_id', true) as workspace_id,\n current_setting('opengeni.subject_id', true) as subject_id,\n current_setting('opengeni.private_file_owner', true) as private_file_owner,\n current_setting('opengeni.initiating_human_subject_id', true) as initiating_human_subject_id,\n current_setting('opengeni.personal_resource_human_subject_id', true) as personal_resource_human_subject_id,\n current_setting('opengeni.personal_resource_actor_subject_id', true) as personal_resource_actor_subject_id`,\n );\n return {\n accountId: settings?.account_id ?? \"\",\n workspaceId: settings?.workspace_id ?? \"\",\n subjectId: settings?.subject_id ?? \"\",\n privateFileOwnerSubjectId: settings?.private_file_owner ?? \"\",\n initiatingHumanSubjectId: settings?.initiating_human_subject_id ?? \"\",\n personalResourceHumanSubjectId: settings?.personal_resource_human_subject_id ?? \"\",\n personalResourceActorSubjectId: settings?.personal_resource_actor_subject_id ?? \"\",\n };\n}\n\nasync function assertRlsContextApplied(db: Database, context: RlsContext): Promise<void> {\n const applied = await readRlsContextSettings(db);\n const expectedWorkspaceId = context.workspaceId ?? \"\";\n if (applied.accountId !== context.accountId) {\n throw new Error(\n `RLS context not applied on the active backend: expected account ${context.accountId}, got \"${applied.accountId}\"`,\n );\n }\n if (applied.workspaceId !== expectedWorkspaceId) {\n throw new Error(\n `RLS context not applied on the active backend: expected workspace \"${expectedWorkspaceId}\", got \"${applied.workspaceId}\"`,\n );\n }\n}\n\nasync function restoreRlsContextSettings(\n db: Database,\n settings: RlsContextSettings,\n): Promise<void> {\n const [restored] = await rawRows<{\n account_id: string;\n workspace_id: string;\n subject_id: string;\n private_file_owner: string;\n initiating_human_subject_id: string;\n personal_resource_human_subject_id: string;\n personal_resource_actor_subject_id: string;\n }>(\n db,\n sql`select\n set_config('opengeni.account_id', ${settings.accountId}, true) as account_id,\n set_config('opengeni.workspace_id', ${settings.workspaceId}, true) as workspace_id,\n set_config('opengeni.subject_id', ${settings.subjectId}, true) as subject_id,\n set_config('opengeni.private_file_owner', ${settings.privateFileOwnerSubjectId}, true) as private_file_owner,\n set_config('opengeni.initiating_human_subject_id', ${settings.initiatingHumanSubjectId}, true) as initiating_human_subject_id,\n set_config('opengeni.personal_resource_human_subject_id', ${settings.personalResourceHumanSubjectId}, true) as personal_resource_human_subject_id,\n set_config('opengeni.personal_resource_actor_subject_id', ${settings.personalResourceActorSubjectId}, true) as personal_resource_actor_subject_id`,\n );\n if (\n restored?.account_id !== settings.accountId ||\n restored.workspace_id !== settings.workspaceId ||\n restored.subject_id !== settings.subjectId ||\n restored.private_file_owner !== settings.privateFileOwnerSubjectId ||\n restored.initiating_human_subject_id !== settings.initiatingHumanSubjectId ||\n restored.personal_resource_human_subject_id !== settings.personalResourceHumanSubjectId ||\n restored.personal_resource_actor_subject_id !== settings.personalResourceActorSubjectId\n ) {\n throw new Error(\"RLS context could not be restored after a nested scope\");\n }\n}\n\n/** Attribute only failures outside the application callback to our transaction\n * driver. BEGIN/COMMIT/ROLLBACK can throw raw postgres.js errors, unlike ORM\n * queries. This supplies provenance, never transaction retry permission. */\nasync function withDatabaseTransactionProvenance<T>(\n db: Database,\n fn: (db: Database) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n): Promise<T> {\n let entered = false;\n let callbackFailure: { error: unknown } | undefined;\n try {\n return await db.transaction(async (tx) => {\n entered = true;\n try {\n return await fn(tx as unknown as Database);\n } catch (error) {\n callbackFailure = { error };\n throw error;\n }\n }, transactionConfig);\n } catch (error) {\n // A provider/tool rejection propagated by a successful rollback is still\n // the provider/tool's error, even if it has a connection-looking code.\n if (callbackFailure && callbackFailure.error === error) throw error;\n if (!isDatabasePersistenceFailure(error)) throw error;\n throw new DatabaseTransactionError(\n entered ? \"settlement\" : \"admission\",\n error,\n callbackFailure?.error,\n );\n }\n}\n\nexport async function withRlsContext<T>(\n db: Database,\n context: RlsContext,\n fn: (db: Database) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n sessionTenancyFence: \"shared\" | \"none\" = \"shared\",\n): Promise<T> {\n const restoreParentScope = isTransactionHandle(db);\n // Callback entry includes connection admission AND BEGIN/SAVEPOINT round-trip.\n // This is deliberately not advertised as pure pool wait.\n const admission = startDatabaseTiming(\n restoreParentScope ? \"savepoint_admission\" : \"transaction_admission\",\n );\n try {\n return await withDatabaseTransactionProvenance(\n db,\n async (tx) => {\n admission(\"completed\");\n const setup = startDatabaseTiming(\"rls_setup\");\n const scoped = tx as unknown as Database;\n let parentScope: RlsContextSettings | null;\n try {\n parentScope = restoreParentScope ? await readRlsContextSettings(scoped) : null;\n await setRlsContext(scoped, context);\n if (context.workspaceId && sessionTenancyFence === \"shared\") {\n await scoped.execute(\n sql`select pg_advisory_xact_lock_shared(hashtextextended(${`session-tenancy:${context.workspaceId}`}, 0))`,\n );\n }\n // Defense-in-depth: read the LOCAL GUC back on THIS backend BEFORE running\n // the scoped query. The set_config and this read share one db.transaction,\n // which a transaction pooler pins to a single backend — so a mismatch here\n // means the context was genuinely lost (a torn transaction / pooler backend\n // swap), not normal operation. Without this guard such an event runs the\n // scoped read with an empty account_id and returns zero RLS-visible rows,\n // manufacturing a phantom \"no active subscription\" from a credential that is\n // in fact active. Convert that silent false into a loud, root-cause-bearing\n // error so the caller can retry rather than permanently mis-decide.\n await assertRlsContextApplied(scoped, context);\n setup(\"completed\");\n } catch (error) {\n setup(\"failed\");\n throw error;\n }\n const callback = startDatabaseTiming(\"scoped_callback\");\n let value: T;\n try {\n value = await fn(scoped);\n callback(\"completed\");\n } catch (error) {\n callback(\"failed\");\n throw error;\n }\n // A nested transaction is a savepoint, and SET LOCAL survives successful\n // savepoint release. Restore the parent tenant and actor proof together;\n // writer/protocol capabilities intentionally remain transaction-wide.\n if (parentScope) await restoreRlsContextSettings(scoped, parentScope);\n return value;\n },\n transactionConfig,\n );\n } catch (error) {\n // No-op after callback entry; only admission failures are counted here.\n admission(\"failed\");\n throw error;\n }\n}\n\n/**\n * Run one bounded database operation on a transaction-pinned backend.\n *\n * Callers that also have an application deadline should check their abort\n * signal before returning from `fn`; throwing there rolls the transaction back\n * even when the application deadline won a surrounding Promise race.\n */\nexport async function withDatabaseStatementTimeout<T>(\n db: Database,\n timeoutMs: number,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new Error(\"withDatabaseStatementTimeout requires a positive timeout\");\n }\n const boundedTimeoutMs = Math.max(1, Math.floor(timeoutMs));\n return await db.transaction(async (tx) => {\n const scoped = tx as unknown as Database;\n await scoped.execute(\n sql`select set_config('statement_timeout', ${`${boundedTimeoutMs}ms`}, true)`,\n );\n return await fn(scoped);\n });\n}\n\nexport async function rlsContextForWorkspace(\n db: Database,\n workspaceId: string,\n): Promise<RlsContext> {\n const [row] = await db\n .select({ accountId: schema.workspaces.accountId })\n .from(schema.workspaces)\n .where(eq(schema.workspaces.id, workspaceId))\n .limit(1);\n if (!row) {\n throw new Error(`Workspace not found: ${workspaceId}`);\n }\n return { accountId: row.accountId, workspaceId };\n}\n\nexport async function withWorkspaceRls<T>(\n db: Database,\n workspaceId: string,\n fn: (db: Database) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n): Promise<T> {\n return await withRlsContext(\n db,\n await rlsContextForWorkspace(db, workspaceId),\n fn,\n transactionConfig,\n );\n}\n\ntype SessionActivityGate = {\n db: SessionActivityDatabase;\n owner: boolean;\n};\n\n/** True for an open transaction (or savepoint) handle rather than a pool handle. */\nexport function isTransactionHandle(db: Database): boolean {\n return typeof (db as Database & { rollback?: unknown }).rollback === \"function\";\n}\n\nasync function assertSessionActivityGateEntry(db: Database): Promise<void> {\n if (!isTransactionHandle(db)) return;\n const [gate] = await rawRows<{ state: string | null }>(\n db,\n sql`\n select nullif(\n current_setting('opengeni.session_activity_gate_state', true),\n ''\n ) as state\n `,\n );\n if (gate?.state === null || gate === undefined) {\n throw new Error(\"Session activity commit gate must start at the outer transaction boundary\");\n }\n}\n\nasync function beginSessionActivityGate(\n db: Database,\n workspaceId: string,\n): Promise<SessionActivityGate> {\n const [gate] = await rawRows<{\n prior_state: string | null;\n prior_workspace_id: string | null;\n }>(\n db,\n sql`\n with current_gate as materialized (\n select\n nullif(current_setting('opengeni.session_activity_gate_state', true), '') as prior_state,\n nullif(current_setting('opengeni.session_activity_gate_workspace_id', true), '') as prior_workspace_id\n )\n select\n prior_state,\n prior_workspace_id,\n case\n when prior_state is null\n then set_config('opengeni.session_activity_gate_state', 'open', true)\n else prior_state\n end as effective_state,\n case\n when prior_state is null\n then set_config('opengeni.session_activity_gate_workspace_id', ${workspaceId}, true)\n else prior_workspace_id\n end as effective_workspace_id\n from current_gate\n `,\n );\n if (!gate) {\n throw new Error(\"Session activity commit gate could not be opened\");\n }\n if (gate.prior_state === null) {\n return { db: db as SessionActivityDatabase, owner: true };\n }\n if (gate.prior_state === \"open\" && gate.prior_workspace_id === workspaceId) {\n return { db: db as SessionActivityDatabase, owner: false };\n }\n throw new Error(\"Session activity commit gate is already owned by another transaction scope\");\n}\n\nasync function finalizeSessionActivityGate(\n db: SessionActivityDatabase,\n workspaceId: string,\n): Promise<void> {\n // Resolve every deferred FK/constraint before taking the shared workspace\n // counter. The only row writes after that point stamp session rows already\n // modified and therefore already owned by this transaction.\n await db.execute(\n sql`select set_config('opengeni.session_activity_gate_state', 'preparing', true)`,\n );\n await db.execute(sql`set constraints all immediate`);\n // The first flush proves every pre-existing deferred obligation. Re-defer\n // only our commit guard so the marker-clearing writes below queue a fresh\n // proof against the final row state, then force that proof before returning.\n await db.execute(\n sql`set constraints sessions_activity_insert_commit_guard, sessions_activity_update_commit_guard deferred`,\n );\n const [result] = await rawRows<{\n had_pending: boolean;\n pending_count: number;\n revision: string | null;\n stamped_count: number;\n }>(\n db,\n sql`\n with gate as materialized (\n select set_config('opengeni.session_activity_gate_state', 'finalizing', true) as state\n ),\n pending as materialized (\n select ${schema.sessions.id}\n from ${schema.sessions}\n cross join gate\n where ${schema.sessions.workspaceId} = ${workspaceId}\n and ${schema.sessions.activityRevisionPendingXid}\n = pg_current_xact_id()::text::bigint\n ),\n advanced as (\n update ${schema.workspaceSessionActivityRevisions} as counter\n set revision = counter.revision + 1\n where counter.workspace_id = ${workspaceId}\n and exists (select 1 from pending)\n returning counter.revision\n ),\n stamped as (\n update ${schema.sessions} as session\n set\n activity_revision = advanced.revision,\n activity_revision_pending_xid = null\n from advanced\n where session.workspace_id = ${workspaceId}\n and session.activity_revision_pending_xid\n = pg_current_xact_id()::text::bigint\n returning session.id\n ),\n stats as materialized (\n select\n exists (select 1 from pending) as had_pending,\n (select count(*)::integer from pending) as pending_count,\n (select revision::text from advanced) as revision,\n (select count(*)::integer from stamped) as stamped_count\n ),\n finalized as materialized (\n select\n had_pending,\n pending_count,\n revision,\n stamped_count,\n set_config('opengeni.session_activity_gate_state', 'finalized', true) as state\n from stats\n )\n select had_pending, pending_count, revision, stamped_count\n from finalized\n `,\n );\n if (!result) {\n throw new Error(\"Session activity commit gate did not return a finalization result\");\n }\n if (result.had_pending && result.revision === null) {\n throw new Error(\"Workspace session activity counter is unavailable\");\n }\n if (result.stamped_count !== result.pending_count) {\n throw new Error(\"Session activity commit gate did not stamp every pending row\");\n }\n await db.execute(\n sql`set constraints sessions_activity_insert_commit_guard, sessions_activity_update_commit_guard immediate`,\n );\n // A restored activity scope can be followed by another workspace scope, or\n // by a SECURITY DEFINER lifecycle that opens and finalizes its own gate in\n // the same outer transaction. Keep the guards deferred after proving this\n // scope's final state so those later writes reach their own finalizer instead\n // of firing the commit guard at the first session update.\n await db.execute(\n sql`set constraints sessions_activity_insert_commit_guard, sessions_activity_update_commit_guard deferred`,\n );\n}\n\n/**\n * Run one workspace transaction with explicit once-per-transaction session\n * activity finalization. Nested callers reuse the outer gate; only its owner\n * finalizes immediately before the enclosing RLS transaction commits.\n */\nexport async function withSessionActivityRlsContext<T>(\n db: Database,\n context: RlsContext & { workspaceId: string },\n fn: (db: SessionActivityDatabase) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n fenceMode: \"shared\" | \"none\" = \"shared\",\n organizationMembershipFence = false,\n): Promise<T> {\n await assertSessionActivityGateEntry(db);\n return await withRlsContext(\n db,\n context,\n async (scopedDb) => {\n if (organizationMembershipFence) {\n // Only callers that reauthorize or mutate under the membership\n // lifecycle lock take it, always exclusively. Acquire membership\n // before even a shared tenancy fence: an exclusive tenancy/control\n // waiter can otherwise complete the same lock cycle. The turn claim\n // deliberately takes no membership fence at all.\n await scopedDb.execute(sql`select pg_advisory_xact_lock(\n hashtextextended(${`organization-membership:${context.accountId}`}, 0))`);\n if (fenceMode === \"shared\") {\n await scopedDb.execute(sql`select pg_advisory_xact_lock_shared(\n hashtextextended(${`session-tenancy:${context.workspaceId}`}, 0))`);\n }\n }\n const gate = await beginSessionActivityGate(scopedDb, context.workspaceId);\n const value = await fn(gate.db);\n // The finalizer must never trust tenant GUCs that arbitrary callback code\n // could have changed. Nested RLS helpers restore their parent scope; this\n // assertion is the fail-closed commit-boundary proof for every other path.\n await assertRlsContextApplied(gate.db, context);\n if (gate.owner) {\n await finalizeSessionActivityGate(gate.db, context.workspaceId);\n }\n return value;\n },\n transactionConfig,\n organizationMembershipFence ? \"none\" : fenceMode,\n );\n}\n\n/**\n * `organizationMembershipFence` is required when the callback takes the\n * organization-membership lifecycle lock (for example external-actor\n * reauthorization): that lock precedes the session-tenancy fence and the\n * canonical control/workspace/session prefix, never follows it.\n */\nexport async function withWorkspaceSessionActivityRls<T>(\n db: Database,\n workspaceId: string,\n fn: (db: SessionActivityDatabase) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n organizationMembershipFence = false,\n): Promise<T> {\n return await withSessionActivityRlsContext(\n db,\n { ...(await rlsContextForWorkspace(db, workspaceId)), workspaceId },\n fn,\n transactionConfig,\n \"shared\",\n organizationMembershipFence,\n );\n}\n\n/**\n * Run one of several ordered workspace activity scopes inside a caller-owned\n * transaction. Each scope is fully finalized before restoring the caller's\n * gate GUCs, so the next workspace can reuse the same outer transaction.\n */\nexport async function withRestoredSessionActivityRlsContext<T>(\n db: Database,\n context: RlsContext & { workspaceId: string },\n fn: (db: SessionActivityDatabase) => Promise<T>,\n): Promise<T> {\n if (!isTransactionHandle(db)) {\n throw new Error(\"Sequential workspace activity scopes require a caller-owned transaction\");\n }\n const [prior] = await rawRows<{ state: string; workspace_id: string }>(\n db,\n sql`select\n coalesce(current_setting('opengeni.session_activity_gate_state', true), '') as state,\n coalesce(\n current_setting('opengeni.session_activity_gate_workspace_id', true), ''\n ) as workspace_id`,\n );\n try {\n return await withRlsContext(db, context, async (scopedDb) => {\n const gate = await beginSessionActivityGate(scopedDb, context.workspaceId);\n if (!gate.owner) {\n throw new Error(\"Sequential workspace activity scope unexpectedly reused an open gate\");\n }\n const value = await fn(gate.db);\n await assertRlsContextApplied(gate.db, context);\n await finalizeSessionActivityGate(gate.db, context.workspaceId);\n return value;\n });\n } finally {\n await db.execute(sql`select\n set_config('opengeni.session_activity_gate_state', ${prior?.state ?? \"\"}, true),\n set_config(\n 'opengeni.session_activity_gate_workspace_id', ${prior?.workspace_id ?? \"\"}, true\n )`);\n }\n}\n\n/**\n * Open one nested savepoint without losing the gate brand. Drizzle correctly\n * preserves the backend-local gate GUCs, but its structural transaction type\n * cannot express that provenance; keep the single trusted rebrand here.\n */\nexport async function withSessionActivitySavepoint<T>(\n db: SessionActivityDatabase,\n fn: (db: SessionActivityDatabase) => Promise<T>,\n): Promise<T> {\n return await db.transaction(async (tx) => await fn(tx as unknown as SessionActivityDatabase));\n}\n\nexport async function retrySessionActivityRls<T>(\n db: Database,\n workspaceId: string,\n options: IdempotentPersistenceTransactionOptions,\n fn: (db: SessionActivityDatabase) => Promise<T>,\n): Promise<T> {\n return await runIdempotentPersistenceTransaction(options, async () => {\n return await withWorkspaceSessionActivityRls(db, workspaceId, fn);\n });\n}\n\nexport async function retryWorkspacePersistence<T>(\n db: Database,\n workspaceId: string,\n options: IdempotentPersistenceTransactionOptions,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n return await runIdempotentPersistenceTransaction(options, async () => {\n return await withWorkspaceRls(db, workspaceId, fn);\n });\n}\n\nexport async function retryRlsPersistence<T>(\n db: Database,\n context: RlsContext,\n options: IdempotentPersistenceTransactionOptions,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n return await runIdempotentPersistenceTransaction(options, async () => {\n return await withRlsContext(db, context, fn);\n });\n}\n\n/**\n * Personal workspace data needs both tenant and authenticated-principal GUCs.\n * `session_pins` uses this helper so FORCE RLS rejects another member's rows\n * even if a future query accidentally omits its explicit subject predicate.\n */\nexport async function withWorkspaceSubjectRls<T>(\n db: Database,\n workspaceId: string,\n subjectId: string,\n fn: (db: Database) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n sessionTenancyFence: \"shared\" | \"none\" = \"shared\",\n): Promise<T> {\n if (!subjectId.trim()) {\n throw new Error(\"withWorkspaceSubjectRls: a non-empty subjectId is required\");\n }\n const context = await rlsContextForWorkspace(db, workspaceId);\n return await withRlsContext(\n db,\n context,\n async (scopedDb) => {\n await setSubjectRlsContext(scopedDb, subjectId);\n return await fn(scopedDb);\n },\n transactionConfig,\n sessionTenancyFence,\n );\n}\n\nexport async function withWorkspaceSubjectSessionActivityRls<T>(\n db: Database,\n workspaceId: string,\n subjectId: string,\n fn: (db: SessionActivityDatabase) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n fenceMode: \"shared\" | \"none\" = \"shared\",\n organizationMembershipFence = false,\n): Promise<T> {\n if (!subjectId.trim()) {\n throw new Error(\"withWorkspaceSubjectSessionActivityRls: a non-empty subjectId is required\");\n }\n const context = await rlsContextForWorkspace(db, workspaceId);\n return await withSessionActivityRlsContext(\n db,\n { ...context, workspaceId },\n async (scopedDb) => {\n await setSubjectRlsContext(scopedDb, subjectId);\n return await fn(scopedDb);\n },\n transactionConfig,\n fenceMode,\n organizationMembershipFence,\n );\n}\n\n/** Apply and verify actor-private RLS on an already transaction-pinned handle. */\nexport async function setSubjectRlsContext(db: Database, subjectId: string): Promise<void> {\n if (!subjectId.trim()) {\n throw new Error(\"setSubjectRlsContext: a non-empty subjectId is required\");\n }\n await db.execute(sql`select set_config('opengeni.subject_id', ${subjectId}, true)`);\n const applied = await db.execute<{ subject_id: string | null }>(\n sql`select current_setting('opengeni.subject_id', true) as subject_id`,\n );\n if ((applied[0]?.subject_id ?? \"\") !== subjectId) {\n throw new Error(\"Authenticated subject RLS context was not applied on the active backend\");\n }\n}\n\nexport async function withWorkspaceUsageLock<T>(\n db: Database,\n workspaceId: string,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n const context = await rlsContextForWorkspace(db, workspaceId);\n return await withRlsContext(db, context, async (scopedDb) => {\n await scopedDb.execute(sql`select pg_advisory_xact_lock(hashtext(${`usage:${workspaceId}`}))`);\n return await fn(scopedDb);\n });\n}\n\nexport async function withAccountRls<T>(\n db: Database,\n accountId: string,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n return await withRlsContext(db, { accountId, workspaceId: null }, fn);\n}\n\n/** Internal lookup for the host binding attached to a database handle. */\nexport function dbBindingFor(db: Database): DbBinding | undefined {\n return dbBindings.get(db as unknown as object);\n}\n"],"mappings":"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","names":["AsyncLocalStorage","AsyncLocalStorage"]}