@opengeni/db 0.28.1 → 0.31.1

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 (187) hide show
  1. package/dist/attached-browser-devices.d.ts +42 -0
  2. package/dist/attempt-tool-catalogs.d.ts +16 -0
  3. package/dist/browser-auth.d.ts +91 -0
  4. package/dist/browser-identities.d.ts +128 -0
  5. package/dist/browser-sessions.d.ts +272 -0
  6. package/dist/browser-state-artifacts.d.ts +17 -0
  7. package/dist/capability-components.d.ts +37 -0
  8. package/dist/capability-integrations.d.ts +192 -0
  9. package/dist/chunk-F5FT7BEZ.js +3535 -0
  10. package/dist/chunk-F5FT7BEZ.js.map +1 -0
  11. package/dist/chunk-ISI2TIUG.js +639 -0
  12. package/dist/chunk-ISI2TIUG.js.map +1 -0
  13. package/dist/chunk-MWDVXQOL.js +11639 -0
  14. package/dist/chunk-MWDVXQOL.js.map +1 -0
  15. package/dist/chunk-NBE6CHRI.js +955 -0
  16. package/dist/chunk-NBE6CHRI.js.map +1 -0
  17. package/dist/{chunk-DBS5HPEW.js → chunk-YHZXQ7HP.js} +760 -11
  18. package/dist/chunk-YHZXQ7HP.js.map +1 -0
  19. package/dist/codemode-operations.d.ts +117 -0
  20. package/dist/codex-token-resolver.d.ts +2 -2
  21. package/dist/company-profile-schema.d.ts +798 -0
  22. package/dist/company-profile.d.ts +268 -0
  23. package/dist/computer-sessions.d.ts +109 -0
  24. package/dist/connection-token-resolver.d.ts +9 -4
  25. package/dist/database.d.ts +52 -3
  26. package/dist/editable-artifact-durable-export.d.ts +153 -0
  27. package/dist/editable-artifact-durable-export.js +788 -0
  28. package/dist/editable-artifact-durable-export.js.map +1 -0
  29. package/dist/editable-artifact-materialization.d.ts +123 -0
  30. package/dist/editable-artifacts-schema.d.ts +4152 -0
  31. package/dist/editable-artifacts.d.ts +610 -0
  32. package/dist/editable-artifacts.js +26 -0
  33. package/dist/editable-artifacts.js.map +1 -0
  34. package/dist/environment-crypto.d.ts +8 -4
  35. package/dist/generated-images.d.ts +139 -0
  36. package/dist/index.d.ts +958 -126
  37. package/dist/index.js +31204 -12172
  38. package/dist/index.js.map +1 -1
  39. package/dist/insights.d.ts +51 -4
  40. package/dist/integration-bindings.d.ts +70 -0
  41. package/dist/integration-features.d.ts +99 -0
  42. package/dist/interaction-revisions.d.ts +3 -0
  43. package/dist/interaction-schema.d.ts +5372 -0
  44. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  45. package/dist/knowledge-source-sync.d.ts +274 -0
  46. package/dist/lossless-columns.d.ts +58 -0
  47. package/dist/lossless-json.d.ts +39 -0
  48. package/dist/memory-domain.d.ts +3 -6
  49. package/dist/memory-governance.d.ts +2 -2
  50. package/dist/memory-slack-delivery.d.ts +101 -0
  51. package/dist/new-session-drafts.d.ts +2 -2
  52. package/dist/pack-components.d.ts +76 -0
  53. package/dist/pack-installations.d.ts +86 -0
  54. package/dist/persistence-errors.d.ts +7 -14
  55. package/dist/plugin-packages.d.ts +126 -0
  56. package/dist/preference-registry.d.ts +1 -1
  57. package/dist/provision-roles.d.ts +9 -1
  58. package/dist/provision-roles.js +1 -1
  59. package/dist/runtime-posture.d.ts +18 -6
  60. package/dist/schema.d.ts +19122 -8731
  61. package/dist/schema.js +173 -1
  62. package/dist/scoped-knowledge.d.ts +97 -1
  63. package/dist/session-control.d.ts +4 -4
  64. package/dist/session-queue-commands.d.ts +19 -11
  65. package/dist/session-realtime-context.d.ts +2 -2
  66. package/dist/session-realtime-ledger.d.ts +4 -4
  67. package/dist/session-realtime-mirror.d.ts +2 -2
  68. package/dist/session-realtime-state.d.ts +1 -1
  69. package/dist/session-realtime-terminal.d.ts +8 -1
  70. package/dist/session-realtime.d.ts +7 -7
  71. package/dist/session-tool-call-settlement.d.ts +1 -1
  72. package/dist/slack-user-link-access.d.ts +54 -0
  73. package/dist/transcription-recordings-schema.d.ts +44 -6
  74. package/dist/transcription-recordings.d.ts +3 -3
  75. package/dist/turn-initiator.d.ts +2 -2
  76. package/dist/video-generation.d.ts +216 -0
  77. package/dist/video-generation.js +66 -0
  78. package/dist/video-generation.js.map +1 -0
  79. package/dist/workspace-artifacts.d.ts +1 -1
  80. package/dist/workspace-instruction-policies.d.ts +1 -1
  81. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  82. package/dist/workspace-learning-policy.d.ts +161 -0
  83. package/drizzle/0065_enrollment_credential_generation.sql +10 -0
  84. package/drizzle/0140_retained_screenshot_artifacts.sql +192 -0
  85. package/drizzle/0176_lossless_canonical_json.sql +975 -0
  86. package/drizzle/0177_session_events_workspace_turn_type_index.sql +5 -0
  87. package/drizzle/0178_permissioned_secret_reads.sql +14 -0
  88. package/drizzle/0179_slack_private_shortcut_delivery_gate.sql +85 -0
  89. package/drizzle/0180_retained_screenshot_lifecycle_fences.sql +273 -0
  90. package/drizzle/0181_connected_machine_removal.sql +52 -0
  91. package/drizzle/0182_connected_machine_remove_session_default.sql +77 -0
  92. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  93. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  94. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  95. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  96. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  97. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  98. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  99. package/drizzle/0190_timeline_annotations.sql +31 -0
  100. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  101. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  102. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  103. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  104. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  105. package/drizzle/0196_rig_provider_images.sql +152 -0
  106. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  107. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  108. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  109. package/drizzle/0201_company_profile_authority.sql +849 -0
  110. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  111. package/drizzle/0203_durable_video_generation.sql +353 -0
  112. package/drizzle/0204_video_generation_funding.sql +44 -0
  113. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  114. package/drizzle/0206_browser_sessions.sql +646 -0
  115. package/drizzle/0207_browser_identities.sql +379 -0
  116. package/drizzle/0208_attached_browser_devices.sql +165 -0
  117. package/drizzle/0209_computer_sessions.sql +575 -0
  118. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  119. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  120. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  121. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  122. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  123. package/drizzle/0215_capabilities_platform.sql +980 -0
  124. package/drizzle/0216_pack_component_ownership.sql +235 -0
  125. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  126. package/package.json +18 -5
  127. package/src/attached-browser-devices.ts +371 -0
  128. package/src/attempt-tool-catalogs.ts +131 -0
  129. package/src/browser-auth.ts +1896 -0
  130. package/src/browser-identities.ts +1168 -0
  131. package/src/browser-sessions.ts +2005 -0
  132. package/src/browser-state-artifacts.ts +59 -0
  133. package/src/capability-components.ts +166 -0
  134. package/src/capability-integrations.ts +1663 -0
  135. package/src/codemode-operations.ts +674 -0
  136. package/src/company-profile-schema.ts +143 -0
  137. package/src/company-profile.ts +968 -0
  138. package/src/computer-sessions.ts +1130 -0
  139. package/src/connection-token-resolver.ts +270 -25
  140. package/src/database.ts +434 -24
  141. package/src/editable-artifact-durable-export.ts +1201 -0
  142. package/src/editable-artifact-materialization.ts +893 -0
  143. package/src/editable-artifacts-schema.ts +879 -0
  144. package/src/editable-artifacts.ts +5404 -0
  145. package/src/environment-crypto.ts +22 -9
  146. package/src/generated-images.ts +740 -0
  147. package/src/index.ts +10117 -2730
  148. package/src/insights.ts +160 -13
  149. package/src/integration-bindings.ts +455 -0
  150. package/src/integration-features.ts +859 -0
  151. package/src/interaction-revisions.ts +40 -0
  152. package/src/interaction-schema.ts +1303 -0
  153. package/src/knowledge-source-sync-schema.ts +192 -0
  154. package/src/knowledge-source-sync.ts +1922 -0
  155. package/src/lossless-columns.ts +35 -0
  156. package/src/lossless-json.ts +322 -0
  157. package/src/memory-domain.ts +5 -44
  158. package/src/memory-slack-delivery.ts +801 -0
  159. package/src/pack-components.ts +954 -0
  160. package/src/pack-installations.ts +929 -0
  161. package/src/persistence-errors.ts +26 -34
  162. package/src/plugin-packages.ts +1186 -0
  163. package/src/provision-roles.ts +302 -1
  164. package/src/runtime-posture-cli.ts +9 -0
  165. package/src/runtime-posture.ts +514 -5
  166. package/src/schema.ts +5177 -2957
  167. package/src/scoped-knowledge-schema.ts +1 -1
  168. package/src/scoped-knowledge.ts +655 -3
  169. package/src/session-control.ts +133 -81
  170. package/src/session-queue-commands.ts +511 -247
  171. package/src/session-realtime-context.ts +20 -7
  172. package/src/session-realtime-ledger.ts +32 -10
  173. package/src/session-realtime-mirror.ts +4 -2
  174. package/src/session-realtime-terminal.ts +89 -21
  175. package/src/session-realtime.ts +10 -9
  176. package/src/session-tool-call-settlement.ts +38 -15
  177. package/src/slack-user-link-access.ts +702 -0
  178. package/src/transcription-recordings-schema.ts +5 -2
  179. package/src/transcription-recordings.ts +70 -40
  180. package/src/video-generation.ts +1452 -0
  181. package/src/workspace-learning-policy-schema.ts +139 -0
  182. package/src/workspace-learning-policy.ts +595 -0
  183. package/dist/chunk-DBS5HPEW.js.map +0 -1
  184. package/dist/chunk-HT5T62CC.js +0 -6803
  185. package/dist/chunk-HT5T62CC.js.map +0 -1
  186. package/dist/event-payload-sanitizer.d.ts +0 -32
  187. package/src/event-payload-sanitizer.ts +0 -377
@@ -3,7 +3,9 @@ import type { RlsStrategy } from "./database";
3
3
  import {
4
4
  RUNTIME_FULL_DML_TABLES,
5
5
  RUNTIME_READ_INSERT_TABLES,
6
+ RUNTIME_READ_INSERT_UPDATE_TABLES,
6
7
  RUNTIME_READ_ONLY_TABLES,
8
+ RUNTIME_READ_UPDATE_TABLES,
7
9
  } from "./runtime-posture";
8
10
  import {
9
11
  classifyRoleRelationships,
@@ -13,6 +15,8 @@ import {
13
15
 
14
16
  export type ProvisionResult = {
15
17
  appRole: string | null;
18
+ artifactOutboxDispatcherRole: string | null;
19
+ artifactMaterializerRole: string | null;
16
20
  hostExportRole: string | null;
17
21
  temporalRole: string | null;
18
22
  temporalDatabases: string[];
@@ -38,6 +42,12 @@ export type ProvisionRolesOptions = {
38
42
  rlsStrategy?: RlsStrategy;
39
43
  appRole?: string;
40
44
  appPassword?: string;
45
+ /** Global, EXECUTE-only artifact live-hint dispatcher capability. */
46
+ artifactOutboxDispatcherRole?: string;
47
+ artifactOutboxDispatcherPassword?: string;
48
+ /** Global, EXECUTE-only artifact materialization worker capability. */
49
+ artifactMaterializerRole?: string;
50
+ artifactMaterializerPassword?: string;
41
51
  /**
42
52
  * Optional cross-workspace projection role. It receives schema USAGE and
43
53
  * EXECUTE only on the host-export API; it receives no table privileges.
@@ -80,6 +90,24 @@ export async function provisionRoles(
80
90
  options.appRole ?? (process.env.OPENGENI_APP_DATABASE_USER?.trim() || "opengeni_app"),
81
91
  );
82
92
  const appPassword = options.appPassword ?? process.env.OPENGENI_APP_DATABASE_PASSWORD;
93
+ const artifactOutboxDispatcherRole = validateIdentifier(
94
+ "artifactOutboxDispatcherRole",
95
+ options.artifactOutboxDispatcherRole ??
96
+ (process.env.OPENGENI_ARTIFACT_OUTBOX_DATABASE_USER?.trim() ||
97
+ "opengeni_artifact_outbox_dispatcher"),
98
+ );
99
+ const artifactOutboxDispatcherPassword =
100
+ options.artifactOutboxDispatcherPassword ??
101
+ process.env.OPENGENI_ARTIFACT_OUTBOX_DATABASE_PASSWORD;
102
+ const artifactMaterializerRole = validateIdentifier(
103
+ "artifactMaterializerRole",
104
+ options.artifactMaterializerRole ??
105
+ (process.env.OPENGENI_ARTIFACT_MATERIALIZER_DATABASE_USER?.trim() ||
106
+ "opengeni_artifact_materializer"),
107
+ );
108
+ const artifactMaterializerPassword =
109
+ options.artifactMaterializerPassword ??
110
+ process.env.OPENGENI_ARTIFACT_MATERIALIZER_DATABASE_PASSWORD;
83
111
  const hostExportRole = validateIdentifier(
84
112
  "hostExportRole",
85
113
  options.hostExportRole ??
@@ -122,6 +150,40 @@ export async function provisionRoles(
122
150
  provisionedAppRole = appRole;
123
151
  }
124
152
 
153
+ let provisionedArtifactOutboxDispatcherRole: string | null = null;
154
+ if (artifactOutboxDispatcherPassword) {
155
+ await assertAppRoleSafeToNormalize(sql, artifactOutboxDispatcherRole);
156
+ await ensureRestrictedAppLoginRole(
157
+ sql,
158
+ artifactOutboxDispatcherRole,
159
+ artifactOutboxDispatcherPassword,
160
+ );
161
+ await grantArtifactCapabilityRoleIfSchemaExists(
162
+ sql,
163
+ artifactOutboxDispatcherRole,
164
+ schema,
165
+ "outbox",
166
+ );
167
+ provisionedArtifactOutboxDispatcherRole = artifactOutboxDispatcherRole;
168
+ }
169
+
170
+ let provisionedArtifactMaterializerRole: string | null = null;
171
+ if (artifactMaterializerPassword) {
172
+ await assertAppRoleSafeToNormalize(sql, artifactMaterializerRole);
173
+ await ensureRestrictedAppLoginRole(
174
+ sql,
175
+ artifactMaterializerRole,
176
+ artifactMaterializerPassword,
177
+ );
178
+ await grantArtifactCapabilityRoleIfSchemaExists(
179
+ sql,
180
+ artifactMaterializerRole,
181
+ schema,
182
+ "materializer",
183
+ );
184
+ provisionedArtifactMaterializerRole = artifactMaterializerRole;
185
+ }
186
+
125
187
  if (temporalPassword) {
126
188
  await ensureLoginRole(sql, temporalRole, temporalPassword);
127
189
  for (const database of temporalDatabases) {
@@ -141,6 +203,8 @@ export async function provisionRoles(
141
203
 
142
204
  return {
143
205
  appRole: provisionedAppRole,
206
+ artifactOutboxDispatcherRole: provisionedArtifactOutboxDispatcherRole,
207
+ artifactMaterializerRole: provisionedArtifactMaterializerRole,
144
208
  hostExportRole: hostExportPassword ? hostExportRole : null,
145
209
  temporalRole: temporalPassword ? temporalRole : null,
146
210
  temporalDatabases: temporalPassword ? temporalDatabases : [],
@@ -170,6 +234,64 @@ END $$;
170
234
  `);
171
235
  }
172
236
 
237
+ async function grantArtifactCapabilityRoleIfSchemaExists(
238
+ sql: postgres.Sql,
239
+ role: string,
240
+ dataSchema: string,
241
+ capability: "outbox" | "materializer",
242
+ ): Promise<void> {
243
+ const routines =
244
+ capability === "outbox"
245
+ ? [
246
+ "claim_editable_artifact_live_outbox(text,integer,integer,name)",
247
+ "mark_editable_artifact_live_outbox_published(text,text,integer,name)",
248
+ "renew_editable_artifact_live_outbox(text,text,integer,integer,name)",
249
+ "retry_editable_artifact_live_outbox(text,text,integer,integer,text,name)",
250
+ "dead_letter_editable_artifact_live_outbox(text,text,integer,text,name)",
251
+ "release_editable_artifact_live_outbox(text,text,integer,name)",
252
+ ]
253
+ : [
254
+ "claim_editable_artifact_materializations(text,integer,integer,name)",
255
+ "renew_editable_artifact_materialization(uuid,uuid,text,text,text,integer,integer,name)",
256
+ "succeed_editable_artifact_materialization(uuid,uuid,text,text,text,integer,text,text,text,bigint,text,text,timestamp with time zone,name)",
257
+ "fail_editable_artifact_materialization(uuid,uuid,text,text,text,integer,text,name)",
258
+ ];
259
+ const routineArray = `ARRAY[${routines.map(literal).join(", ")}]`;
260
+ await sql.unsafe(`
261
+ DO $$
262
+ DECLARE routine_signature text;
263
+ BEGIN
264
+ IF EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = ${literal(dataSchema)})
265
+ AND EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'opengeni_private')
266
+ THEN
267
+ EXECUTE format('GRANT CONNECT ON DATABASE %I TO %I', current_database(), ${literal(role)});
268
+ EXECUTE format('GRANT USAGE ON SCHEMA %I TO %I', ${literal(dataSchema)}, ${literal(role)});
269
+ EXECUTE format('GRANT USAGE ON SCHEMA opengeni_private TO %I', ${literal(role)});
270
+ EXECUTE format(
271
+ 'REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA %I FROM %I',
272
+ ${literal(dataSchema)}, ${literal(role)}
273
+ );
274
+ EXECUTE format(
275
+ 'REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA %I FROM %I',
276
+ ${literal(dataSchema)}, ${literal(role)}
277
+ );
278
+ EXECUTE format(
279
+ 'REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA opengeni_private FROM %I',
280
+ ${literal(role)}
281
+ );
282
+ FOREACH routine_signature IN ARRAY ${routineArray} LOOP
283
+ IF to_regprocedure('opengeni_private.' || routine_signature) IS NOT NULL THEN
284
+ EXECUTE format(
285
+ 'GRANT EXECUTE ON FUNCTION opengeni_private.%s TO %I',
286
+ routine_signature, ${literal(role)}
287
+ );
288
+ END IF;
289
+ END LOOP;
290
+ END IF;
291
+ END $$;
292
+ `);
293
+ }
294
+
173
295
  async function ensureLoginRole(sql: postgres.Sql, role: string, password: string): Promise<void> {
174
296
  await sql.unsafe(`
175
297
  DO $$
@@ -357,7 +479,9 @@ async function grantAppRoleIfSchemaExists(
357
479
  ): Promise<void> {
358
480
  const runtimeFullDmlTables = `ARRAY[${RUNTIME_FULL_DML_TABLES.map(literal).join(", ")}]`;
359
481
  const runtimeReadOnlyTables = `ARRAY[${RUNTIME_READ_ONLY_TABLES.map(literal).join(", ")}]`;
482
+ const runtimeReadUpdateTables = `ARRAY[${RUNTIME_READ_UPDATE_TABLES.map(literal).join(", ")}]`;
360
483
  const runtimeReadInsertTables = `ARRAY[${RUNTIME_READ_INSERT_TABLES.map(literal).join(", ")}]`;
484
+ const runtimeReadInsertUpdateTables = `ARRAY[${RUNTIME_READ_INSERT_UPDATE_TABLES.map(literal).join(", ")}]`;
361
485
  await sql.unsafe(`
362
486
  DO $$
363
487
  DECLARE
@@ -389,6 +513,16 @@ BEGIN
389
513
  );
390
514
  END IF;
391
515
  END LOOP;
516
+ FOREACH runtime_table IN ARRAY ${runtimeReadUpdateTables} LOOP
517
+ IF to_regclass(format('%I.%I', ${literal(schema)}, runtime_table)) IS NOT NULL THEN
518
+ EXECUTE format(
519
+ 'GRANT SELECT, UPDATE ON TABLE %I.%I TO %I',
520
+ ${literal(schema)},
521
+ runtime_table,
522
+ ${literal(role)}
523
+ );
524
+ END IF;
525
+ END LOOP;
392
526
  FOREACH runtime_table IN ARRAY ${runtimeReadInsertTables} LOOP
393
527
  IF to_regclass(format('%I.%I', ${literal(schema)}, runtime_table)) IS NOT NULL THEN
394
528
  EXECUTE format(
@@ -399,6 +533,16 @@ BEGIN
399
533
  );
400
534
  END IF;
401
535
  END LOOP;
536
+ FOREACH runtime_table IN ARRAY ${runtimeReadInsertUpdateTables} LOOP
537
+ IF to_regclass(format('%I.%I', ${literal(schema)}, runtime_table)) IS NOT NULL THEN
538
+ EXECUTE format(
539
+ 'GRANT SELECT, INSERT, UPDATE ON TABLE %I.%I TO %I',
540
+ ${literal(schema)},
541
+ runtime_table,
542
+ ${literal(role)}
543
+ );
544
+ END IF;
545
+ END LOOP;
402
546
  -- Migration 0110 creates this target-schema-local SECURITY DEFINER
403
547
  -- capability before opengeni_app may exist. Re-converge its exact EXECUTE
404
548
  -- grant here so the supported migrate-then-provision order is equivalent to
@@ -481,6 +625,72 @@ BEGIN
481
625
  ${literal(role)}
482
626
  );
483
627
  END IF;
628
+ IF to_regprocedure(
629
+ format(
630
+ '%I.company_profile_apply_activation(uuid,text,uuid,uuid,uuid,uuid,bigint,text,text,text,text)',
631
+ ${literal(schema)}
632
+ )
633
+ ) IS NOT NULL THEN
634
+ EXECUTE format(
635
+ 'GRANT EXECUTE ON FUNCTION %I.company_profile_apply_activation(uuid, text, uuid, uuid, uuid, uuid, bigint, text, text, text, text) TO %I',
636
+ ${literal(schema)},
637
+ ${literal(role)}
638
+ );
639
+ END IF;
640
+ IF to_regprocedure(
641
+ format(
642
+ '%I.company_profile_get_or_create_snapshot(uuid,uuid,uuid,uuid,uuid,integer)',
643
+ ${literal(schema)}
644
+ )
645
+ ) IS NOT NULL THEN
646
+ EXECUTE format(
647
+ 'GRANT EXECUTE ON FUNCTION %I.company_profile_get_or_create_snapshot(uuid, uuid, uuid, uuid, uuid, integer) TO %I',
648
+ ${literal(schema)},
649
+ ${literal(role)}
650
+ );
651
+ END IF;
652
+ IF to_regprocedure(
653
+ format(
654
+ '%I.workspace_learning_policy_apply_activation(uuid,text,uuid,uuid,uuid,uuid,bigint,text,text,text)',
655
+ ${literal(schema)}
656
+ )
657
+ ) IS NOT NULL THEN
658
+ EXECUTE format(
659
+ 'GRANT EXECUTE ON FUNCTION %I.workspace_learning_policy_apply_activation(uuid, text, uuid, uuid, uuid, uuid, bigint, text, text, text) TO %I',
660
+ ${literal(schema)},
661
+ ${literal(role)}
662
+ );
663
+ END IF;
664
+ IF to_regprocedure(
665
+ format('%I.workspace_learning_policy_source_overrides_valid(jsonb)', ${literal(schema)})
666
+ ) IS NOT NULL THEN
667
+ EXECUTE format(
668
+ 'GRANT EXECUTE ON FUNCTION %I.workspace_learning_policy_source_overrides_valid(jsonb) TO %I',
669
+ ${literal(schema)},
670
+ ${literal(role)}
671
+ );
672
+ END IF;
673
+ IF to_regprocedure(
674
+ format('%I.workspace_learning_policy_hash(text,jsonb)', ${literal(schema)})
675
+ ) IS NOT NULL THEN
676
+ EXECUTE format(
677
+ 'GRANT EXECUTE ON FUNCTION %I.workspace_learning_policy_hash(text, jsonb) TO %I',
678
+ ${literal(schema)},
679
+ ${literal(role)}
680
+ );
681
+ END IF;
682
+ IF to_regprocedure(
683
+ format(
684
+ '%I.workspace_learning_policy_get_or_create_snapshot(uuid,uuid,uuid,uuid,uuid,integer)',
685
+ ${literal(schema)}
686
+ )
687
+ ) IS NOT NULL THEN
688
+ EXECUTE format(
689
+ 'GRANT EXECUTE ON FUNCTION %I.workspace_learning_policy_get_or_create_snapshot(uuid, uuid, uuid, uuid, uuid, integer) TO %I',
690
+ ${literal(schema)},
691
+ ${literal(role)}
692
+ );
693
+ END IF;
484
694
  IF to_regprocedure(
485
695
  format(
486
696
  '%I.scoped_knowledge_apply_lifecycle(uuid,text,uuid,text,bigint,text,text,text,text,text,text)',
@@ -493,6 +703,26 @@ BEGIN
493
703
  ${literal(role)}
494
704
  );
495
705
  END IF;
706
+ -- Migration 0197 creates this target-schema-local SECURITY DEFINER lock
707
+ -- before opengeni_app may exist. Re-converge only its exact EXECUTE grant
708
+ -- for the supported migrate-then-provision install order; keep PUBLIC
709
+ -- revoked and do not widen table privileges.
710
+ IF to_regprocedure(
711
+ format(
712
+ '%I.knowledge_source_sync_lock_authority(uuid,uuid,uuid)',
713
+ ${literal(schema)}
714
+ )
715
+ ) IS NOT NULL THEN
716
+ EXECUTE format(
717
+ 'REVOKE ALL ON FUNCTION %I.knowledge_source_sync_lock_authority(uuid, uuid, uuid) FROM PUBLIC',
718
+ ${literal(schema)}
719
+ );
720
+ EXECUTE format(
721
+ 'GRANT EXECUTE ON FUNCTION %I.knowledge_source_sync_lock_authority(uuid, uuid, uuid) TO %I',
722
+ ${literal(schema)},
723
+ ${literal(role)}
724
+ );
725
+ END IF;
496
726
  IF to_regprocedure(
497
727
  format(
498
728
  '%I.scoped_knowledge_advance_source_acl(uuid,uuid,bigint,bigint,uuid,text,text,text,text,text,text)',
@@ -548,10 +778,81 @@ BEGIN
548
778
  EXECUTE format('REVOKE CREATE ON SCHEMA opengeni_private FROM %I', ${literal(role)});
549
779
  EXECUTE format('GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA opengeni_private TO %I', ${literal(role)});
550
780
  EXECUTE format(
551
- 'ALTER DEFAULT PRIVILEGES FOR ROLE %I IN SCHEMA opengeni_private GRANT EXECUTE ON FUNCTIONS TO %I',
781
+ 'ALTER DEFAULT PRIVILEGES FOR ROLE %I IN SCHEMA opengeni_private REVOKE EXECUTE ON FUNCTIONS FROM %I',
552
782
  owner_role,
553
783
  ${literal(role)}
554
784
  );
785
+ -- Global cross-workspace artifact workers are separate capabilities. Never
786
+ -- let the generic tenant-scoped app role inherit them from the historical
787
+ -- blanket grant of already-installed helpers.
788
+ IF to_regprocedure('opengeni_private.claim_editable_artifact_live_outbox(text,integer,integer,name)') IS NOT NULL THEN
789
+ EXECUTE format(
790
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.claim_editable_artifact_live_outbox(text, integer, integer, name) FROM %I',
791
+ ${literal(role)}
792
+ );
793
+ EXECUTE format(
794
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.mark_editable_artifact_live_outbox_published(text, text, integer, name) FROM %I',
795
+ ${literal(role)}
796
+ );
797
+ EXECUTE format(
798
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.renew_editable_artifact_live_outbox(text, text, integer, integer, name) FROM %I',
799
+ ${literal(role)}
800
+ );
801
+ EXECUTE format(
802
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.retry_editable_artifact_live_outbox(text, text, integer, integer, text, name) FROM %I',
803
+ ${literal(role)}
804
+ );
805
+ EXECUTE format(
806
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.dead_letter_editable_artifact_live_outbox(text, text, integer, text, name) FROM %I',
807
+ ${literal(role)}
808
+ );
809
+ EXECUTE format(
810
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.release_editable_artifact_live_outbox(text, text, integer, name) FROM %I',
811
+ ${literal(role)}
812
+ );
813
+ END IF;
814
+ IF to_regprocedure('opengeni_private.claim_editable_artifact_materializations(text,integer,integer,name)') IS NOT NULL THEN
815
+ EXECUTE format(
816
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.claim_editable_artifact_materializations(text, integer, integer, name) FROM %I',
817
+ ${literal(role)}
818
+ );
819
+ EXECUTE format(
820
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.renew_editable_artifact_materialization(uuid, uuid, text, text, text, integer, integer, name) FROM %I',
821
+ ${literal(role)}
822
+ );
823
+ EXECUTE format(
824
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.succeed_editable_artifact_materialization(uuid, uuid, text, text, text, integer, text, text, text, bigint, text, text, timestamptz, name) FROM %I',
825
+ ${literal(role)}
826
+ );
827
+ EXECUTE format(
828
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.fail_editable_artifact_materialization(uuid, uuid, text, text, text, integer, text, name) FROM %I',
829
+ ${literal(role)}
830
+ );
831
+ END IF;
832
+ IF to_regprocedure('opengeni_private.consume_editable_artifact_live_ticket(text,name)') IS NOT NULL THEN
833
+ EXECUTE format(
834
+ 'REVOKE EXECUTE ON FUNCTION opengeni_private.resolve_editable_artifact_ticket_data_schema(name) FROM %I',
835
+ ${literal(role)}
836
+ );
837
+ EXECUTE format(
838
+ 'GRANT EXECUTE ON FUNCTION opengeni_private.put_editable_artifact_live_ticket(text, uuid, uuid, text, text, text, text, text, text, text, text, integer, text, boolean, integer, timestamptz, timestamptz, name) TO %I',
839
+ ${literal(role)}
840
+ );
841
+ EXECUTE format(
842
+ 'GRANT EXECUTE ON FUNCTION opengeni_private.consume_editable_artifact_live_ticket(text, name) TO %I',
843
+ ${literal(role)}
844
+ );
845
+ EXECUTE format(
846
+ 'GRANT EXECUTE ON FUNCTION opengeni_private.cleanup_expired_editable_artifact_live_tickets(integer, name) TO %I',
847
+ ${literal(role)}
848
+ );
849
+ END IF;
850
+ IF to_regprocedure('opengeni_private.authorize_editable_artifact_actor(uuid,uuid,text,text,text,text,text,text,integer,text,text,name)') IS NOT NULL THEN
851
+ EXECUTE format(
852
+ 'GRANT EXECUTE ON FUNCTION opengeni_private.authorize_editable_artifact_actor(uuid, uuid, text, text, text, text, text, text, integer, text, text, name) TO %I',
853
+ ${literal(role)}
854
+ );
855
+ END IF;
555
856
  END IF;
556
857
  END $$;
557
858
  `);
@@ -4,9 +4,12 @@ import {
4
4
  createDb,
5
5
  FORCE_RLS_TABLES,
6
6
  PROTECTED_NO_DIRECT_DML_TABLES,
7
+ RUNTIME_TARGET_SCHEMA_CAPABILITY_ROUTINES,
7
8
  RUNTIME_FULL_DML_TABLES,
8
9
  RUNTIME_READ_INSERT_TABLES,
10
+ RUNTIME_READ_INSERT_UPDATE_TABLES,
9
11
  RUNTIME_READ_ONLY_TABLES,
12
+ RUNTIME_READ_UPDATE_TABLES,
10
13
  } from "./index";
11
14
 
12
15
  const settings = getSettings();
@@ -48,8 +51,14 @@ try {
48
51
  !table.trigger,
49
52
  ).length,
50
53
  declaredReadOnlyTables: RUNTIME_READ_ONLY_TABLES.length,
54
+ declaredReadUpdateTables: RUNTIME_READ_UPDATE_TABLES.length,
51
55
  declaredReadInsertTables: RUNTIME_READ_INSERT_TABLES.length,
56
+ declaredReadInsertUpdateTables: RUNTIME_READ_INSERT_UPDATE_TABLES.length,
52
57
  declaredProtectedNoDirectDmlTables: PROTECTED_NO_DIRECT_DML_TABLES.length,
58
+ declaredTargetSchemaCapabilities: RUNTIME_TARGET_SCHEMA_CAPABILITY_ROUTINES.length,
59
+ executableTargetSchemaCapabilities: posture.targetRoutines.filter(
60
+ (routine) => routine.execute && !routine.publicExecute && routine.securityDefiner,
61
+ ).length,
53
62
  }),
54
63
  );
55
64
  } finally {