@opengeni/db 0.28.9 → 0.36.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 (225) 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 +299 -0
  4. package/dist/browser-downloads.d.ts +51 -0
  5. package/dist/browser-identities.d.ts +137 -0
  6. package/dist/browser-sessions.d.ts +354 -0
  7. package/dist/browser-state-artifacts.d.ts +91 -0
  8. package/dist/canonical-human-identities.d.ts +48 -0
  9. package/dist/canonical-human-identities.js +28 -0
  10. package/dist/canonical-human-identities.js.map +1 -0
  11. package/dist/capability-components.d.ts +37 -0
  12. package/dist/capability-integrations.d.ts +194 -0
  13. package/dist/chunk-5KTIEDX7.js +13200 -0
  14. package/dist/chunk-5KTIEDX7.js.map +1 -0
  15. package/dist/chunk-CQZ4QSP5.js +995 -0
  16. package/dist/chunk-CQZ4QSP5.js.map +1 -0
  17. package/dist/chunk-F32YT7MP.js +117 -0
  18. package/dist/chunk-F32YT7MP.js.map +1 -0
  19. package/dist/chunk-JC5QPLUM.js +666 -0
  20. package/dist/chunk-JC5QPLUM.js.map +1 -0
  21. package/dist/chunk-P3RE4D2B.js +3535 -0
  22. package/dist/chunk-P3RE4D2B.js.map +1 -0
  23. package/dist/chunk-TAUTWOS5.js +259 -0
  24. package/dist/chunk-TAUTWOS5.js.map +1 -0
  25. package/dist/chunk-VKLB2ZGI.js +2389 -0
  26. package/dist/chunk-VKLB2ZGI.js.map +1 -0
  27. package/dist/codemode-operations.d.ts +117 -0
  28. package/dist/codex-token-resolver.d.ts +2 -2
  29. package/dist/company-profile-schema.d.ts +798 -0
  30. package/dist/company-profile.d.ts +268 -0
  31. package/dist/computer-sessions.d.ts +109 -0
  32. package/dist/connection-token-resolver.d.ts +9 -4
  33. package/dist/database.d.ts +57 -3
  34. package/dist/editable-artifact-durable-export.d.ts +153 -0
  35. package/dist/editable-artifact-durable-export.js +788 -0
  36. package/dist/editable-artifact-durable-export.js.map +1 -0
  37. package/dist/editable-artifact-materialization.d.ts +123 -0
  38. package/dist/editable-artifacts-schema.d.ts +4152 -0
  39. package/dist/editable-artifacts.d.ts +610 -0
  40. package/dist/editable-artifacts.js +26 -0
  41. package/dist/editable-artifacts.js.map +1 -0
  42. package/dist/generated-images.d.ts +139 -0
  43. package/dist/index.d.ts +1122 -126
  44. package/dist/index.js +42329 -18407
  45. package/dist/index.js.map +1 -1
  46. package/dist/insights.d.ts +73 -10
  47. package/dist/integration-bindings.d.ts +70 -0
  48. package/dist/integration-facets.d.ts +99 -0
  49. package/dist/interaction-revisions.d.ts +14 -0
  50. package/dist/interaction-schema.d.ts +6036 -0
  51. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  52. package/dist/knowledge-source-sync.d.ts +274 -0
  53. package/dist/memory-governance.d.ts +2 -2
  54. package/dist/memory-slack-delivery.d.ts +101 -0
  55. package/dist/new-session-drafts.d.ts +2 -2
  56. package/dist/pack-components.d.ts +76 -0
  57. package/dist/pack-installations.d.ts +86 -0
  58. package/dist/persistence-errors.d.ts +3 -3
  59. package/dist/plugin-packages.d.ts +126 -0
  60. package/dist/preference-registry.d.ts +1 -1
  61. package/dist/provision-roles.d.ts +9 -1
  62. package/dist/provision-roles.js +1 -1
  63. package/dist/runtime-posture.d.ts +19 -6
  64. package/dist/schema.d.ts +22654 -9359
  65. package/dist/schema.js +209 -3
  66. package/dist/scoped-knowledge.d.ts +97 -1
  67. package/dist/session-control.d.ts +33 -7
  68. package/dist/session-queue-commands.d.ts +19 -11
  69. package/dist/session-realtime-context.d.ts +2 -2
  70. package/dist/session-realtime-ledger.d.ts +4 -4
  71. package/dist/session-realtime-mirror.d.ts +2 -2
  72. package/dist/session-realtime-state.d.ts +1 -1
  73. package/dist/session-realtime-terminal.d.ts +1 -1
  74. package/dist/session-realtime.d.ts +7 -7
  75. package/dist/session-tenancy.d.ts +44 -0
  76. package/dist/session-tenancy.js +16 -0
  77. package/dist/session-tenancy.js.map +1 -0
  78. package/dist/session-tool-call-settlement.d.ts +1 -1
  79. package/dist/slack-task-policy-schema.d.ts +847 -0
  80. package/dist/slack-task-policy.d.ts +65 -0
  81. package/dist/slack-user-link-access.d.ts +54 -0
  82. package/dist/task-notes-schema.d.ts +924 -0
  83. package/dist/task-notes.d.ts +85 -0
  84. package/dist/transcription-recordings.d.ts +2 -2
  85. package/dist/turn-initiator.d.ts +2 -2
  86. package/dist/video-generation.d.ts +225 -0
  87. package/dist/video-generation.js +68 -0
  88. package/dist/video-generation.js.map +1 -0
  89. package/dist/workspace-artifacts.d.ts +1 -1
  90. package/dist/workspace-instruction-policies.d.ts +1 -1
  91. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  92. package/dist/workspace-learning-policy.d.ts +161 -0
  93. package/dist/xai-subscription.d.ts +326 -0
  94. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  95. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  96. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  97. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  98. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  99. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  100. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  101. package/drizzle/0190_timeline_annotations.sql +31 -0
  102. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  103. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  104. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  105. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  106. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  107. package/drizzle/0196_rig_provider_images.sql +152 -0
  108. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  109. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  110. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  111. package/drizzle/0201_company_profile_authority.sql +849 -0
  112. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  113. package/drizzle/0203_durable_video_generation.sql +353 -0
  114. package/drizzle/0204_video_generation_funding.sql +44 -0
  115. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  116. package/drizzle/0206_browser_sessions.sql +646 -0
  117. package/drizzle/0207_browser_identities.sql +379 -0
  118. package/drizzle/0208_attached_browser_devices.sql +165 -0
  119. package/drizzle/0209_computer_sessions.sql +575 -0
  120. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  121. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  122. package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
  123. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  124. package/drizzle/0213_browser_interaction_authority.sql +67 -0
  125. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  126. package/drizzle/0214_browser_download_saves.sql +34 -0
  127. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  128. package/drizzle/0215_browser_controller_host.sql +385 -0
  129. package/drizzle/0215_capabilities_platform.sql +980 -0
  130. package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
  131. package/drizzle/0216_pack_component_ownership.sql +235 -0
  132. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  133. package/drizzle/0217_external_browser_auth_operations.sql +22 -0
  134. package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
  135. package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
  136. package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
  137. package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
  138. package/drizzle/0220_session_channels.sql +54 -0
  139. package/drizzle/0221_sessions_channel_index.sql +5 -0
  140. package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
  141. package/drizzle/0222_sessions_channel_fk.sql +89 -0
  142. package/drizzle/0223_pending_tool_event_output.sql +55 -0
  143. package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
  144. package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
  145. package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
  146. package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
  147. package/drizzle/0227_slack_native_actions.sql +145 -0
  148. package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
  149. package/drizzle/0228_slack_task_policy.sql +400 -0
  150. package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
  151. package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
  152. package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
  153. package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
  154. package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
  155. package/drizzle/0234_xai_subscription_authority.sql +1139 -0
  156. package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
  157. package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
  158. package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
  159. package/drizzle/0237_interaction_transition_reaper.sql +263 -0
  160. package/drizzle/0238_goal_persistence_policy.sql +471 -0
  161. package/drizzle/0238_supergrok_realtime_model.sql +29 -0
  162. package/drizzle/0239_supergrok_video_funding.sql +50 -0
  163. package/drizzle/0239_task_tree_notes.sql +990 -0
  164. package/package.json +26 -5
  165. package/src/attached-browser-devices.ts +371 -0
  166. package/src/attempt-tool-catalogs.ts +131 -0
  167. package/src/browser-auth.ts +4373 -0
  168. package/src/browser-downloads.ts +517 -0
  169. package/src/browser-identities.ts +1385 -0
  170. package/src/browser-sessions.ts +2294 -0
  171. package/src/browser-state-artifacts.ts +449 -0
  172. package/src/canonical-human-identities.ts +317 -0
  173. package/src/capability-components.ts +166 -0
  174. package/src/capability-integrations.ts +1571 -0
  175. package/src/codemode-operations.ts +674 -0
  176. package/src/company-profile-schema.ts +143 -0
  177. package/src/company-profile.ts +968 -0
  178. package/src/computer-sessions.ts +1130 -0
  179. package/src/connection-token-resolver.ts +270 -25
  180. package/src/database.ts +468 -24
  181. package/src/editable-artifact-durable-export.ts +1201 -0
  182. package/src/editable-artifact-materialization.ts +893 -0
  183. package/src/editable-artifacts-schema.ts +879 -0
  184. package/src/editable-artifacts.ts +5404 -0
  185. package/src/generated-images.ts +740 -0
  186. package/src/index.ts +9963 -1465
  187. package/src/insights.ts +251 -23
  188. package/src/integration-bindings.ts +455 -0
  189. package/src/integration-facets.ts +862 -0
  190. package/src/interaction-revisions.ts +70 -0
  191. package/src/interaction-schema.ts +1606 -0
  192. package/src/knowledge-source-sync-schema.ts +192 -0
  193. package/src/knowledge-source-sync.ts +1922 -0
  194. package/src/memory-slack-delivery.ts +801 -0
  195. package/src/pack-components.ts +954 -0
  196. package/src/pack-installations.ts +886 -0
  197. package/src/persistence-errors.ts +4 -7
  198. package/src/plugin-packages.ts +1186 -0
  199. package/src/provision-roles.ts +534 -1
  200. package/src/runtime-posture-cli.ts +9 -0
  201. package/src/runtime-posture.ts +721 -5
  202. package/src/schema.ts +6270 -3159
  203. package/src/scoped-knowledge-schema.ts +1 -1
  204. package/src/scoped-knowledge.ts +655 -3
  205. package/src/session-control.ts +130 -42
  206. package/src/session-queue-commands.ts +265 -15
  207. package/src/session-realtime-context.ts +2 -2
  208. package/src/session-realtime-ledger.ts +3 -3
  209. package/src/session-realtime.ts +7 -7
  210. package/src/session-tenancy.ts +188 -0
  211. package/src/session-tool-call-settlement.ts +18 -3
  212. package/src/slack-task-policy-schema.ts +130 -0
  213. package/src/slack-task-policy.ts +341 -0
  214. package/src/slack-user-link-access.ts +702 -0
  215. package/src/task-notes-schema.ts +135 -0
  216. package/src/task-notes.ts +178 -0
  217. package/src/video-generation.ts +1530 -0
  218. package/src/workspace-artifacts.ts +1 -1
  219. package/src/workspace-learning-policy-schema.ts +139 -0
  220. package/src/workspace-learning-policy.ts +595 -0
  221. package/src/xai-subscription.ts +1887 -0
  222. package/dist/chunk-P6CUHXQZ.js +0 -7248
  223. package/dist/chunk-P6CUHXQZ.js.map +0 -1
  224. package/dist/chunk-VHBFHMPC.js +0 -1219
  225. package/dist/chunk-VHBFHMPC.js.map +0 -1
@@ -0,0 +1,234 @@
1
+ -- deployment-mode: maintenance
2
+ -- Crash-safe SiteAuth maintenance claims. A claim owns one hidden session id
3
+ -- and one operation id; retries repair the same session rather than dispatching
4
+ -- duplicate health or repair agents.
5
+ SET LOCAL lock_timeout = '5s';
6
+ SET LOCAL statement_timeout = '30s';
7
+
8
+ ALTER TABLE "site_auth_connections"
9
+ ADD COLUMN "maintenance_operation_id" uuid,
10
+ ADD COLUMN "maintenance_action" text,
11
+ ADD COLUMN "maintenance_due_at" timestamptz,
12
+ ADD COLUMN "maintenance_claimed_at" timestamptz,
13
+ ADD COLUMN "maintenance_session_id" uuid,
14
+ ADD COLUMN "maintenance_started_at" timestamptz;
15
+
16
+ ALTER TABLE "site_auth_connections"
17
+ ADD CONSTRAINT "site_auth_connections_maintenance_check" CHECK (
18
+ (
19
+ "maintenance_operation_id" IS NULL
20
+ AND "maintenance_action" IS NULL
21
+ AND "maintenance_due_at" IS NULL
22
+ AND "maintenance_claimed_at" IS NULL
23
+ AND "maintenance_session_id" IS NULL
24
+ AND "maintenance_started_at" IS NULL
25
+ ) OR (
26
+ "status" = 'active'
27
+ AND "health_policy"->>'mode' = 'maintained'
28
+ AND "maintenance_operation_id" IS NOT NULL
29
+ AND "maintenance_action" IN ('health_check', 'repair')
30
+ AND "maintenance_due_at" IS NOT NULL
31
+ AND "maintenance_claimed_at" IS NOT NULL
32
+ AND "maintenance_session_id" IS NOT NULL
33
+ AND (
34
+ "maintenance_started_at" IS NULL
35
+ OR "maintenance_started_at" >= "maintenance_due_at"
36
+ )
37
+ )
38
+ );
39
+
40
+ ALTER TABLE "auth_runs"
41
+ ADD COLUMN "maintenance_operation_id" uuid,
42
+ ADD CONSTRAINT "auth_runs_maintenance_check" CHECK (
43
+ "maintenance_operation_id" IS NULL
44
+ OR "purpose" IN ('health_check', 'repair')
45
+ );
46
+
47
+ DROP INDEX "site_auth_connections_health_maintenance_idx";
48
+ CREATE INDEX "site_auth_connections_health_maintenance_idx"
49
+ ON "site_auth_connections" (
50
+ "next_check_at", "maintenance_claimed_at", "id"
51
+ );
52
+
53
+ CREATE UNIQUE INDEX "auth_runs_workspace_maintenance_operation_uq"
54
+ ON "auth_runs" ("workspace_id", "maintenance_operation_id")
55
+ WHERE "maintenance_operation_id" IS NOT NULL;
56
+
57
+ -- Sole cross-workspace claim boundary. An undispatched stale claim reuses its
58
+ -- exact ids. A completed/failed maintenance session without a live AuthRun is
59
+ -- replaced only after the claim timeout. Active sessions and interventions are
60
+ -- never stolen.
61
+ DO $migration$
62
+ DECLARE target_schema text := current_schema();
63
+ BEGIN
64
+ EXECUTE format($create$
65
+ CREATE OR REPLACE FUNCTION opengeni_private.claim_site_auth_maintenance(
66
+ p_claim_timeout_ms bigint,
67
+ p_limit integer
68
+ )
69
+ RETURNS TABLE (
70
+ operation_id uuid,
71
+ session_id uuid,
72
+ account_id uuid,
73
+ workspace_id uuid,
74
+ site_auth_connection_id uuid,
75
+ connection_version bigint,
76
+ action text,
77
+ due_at timestamptz,
78
+ claimed_at timestamptz,
79
+ name text,
80
+ account_label text,
81
+ login_url text,
82
+ verification_url_prefixes jsonb,
83
+ preferred_identity_id uuid,
84
+ preferred_placement jsonb,
85
+ preferred_network_route_id uuid,
86
+ health_policy jsonb,
87
+ verification_state text
88
+ )
89
+ LANGUAGE sql
90
+ SECURITY DEFINER
91
+ SET search_path = pg_catalog
92
+ AS $function$
93
+ WITH candidates AS MATERIALIZED (
94
+ SELECT
95
+ C.id,
96
+ C.maintenance_operation_id,
97
+ C.maintenance_session_id,
98
+ C.maintenance_started_at,
99
+ S.status AS session_status
100
+ FROM %1$I.site_auth_connections C
101
+ LEFT JOIN %1$I.sessions S
102
+ ON S.workspace_id = C.workspace_id
103
+ AND S.id = C.maintenance_session_id
104
+ WHERE C.status = 'active'
105
+ AND C.health_policy->>'mode' = 'maintained'
106
+ AND C.next_check_at <= clock_timestamp()
107
+ AND (
108
+ C.maintenance_operation_id IS NULL
109
+ OR (
110
+ C.maintenance_started_at IS NULL
111
+ AND C.maintenance_claimed_at <= clock_timestamp() - (
112
+ greatest(coalesce(p_claim_timeout_ms, 0), 0)::double precision * interval '1 millisecond'
113
+ )
114
+ )
115
+ OR (
116
+ C.maintenance_started_at IS NOT NULL
117
+ AND S.status = 'queued'
118
+ AND NOT EXISTS (
119
+ SELECT 1
120
+ FROM %1$I.auth_runs R
121
+ WHERE R.workspace_id = C.workspace_id
122
+ AND R.maintenance_operation_id = C.maintenance_operation_id
123
+ AND R.settled_at IS NULL
124
+ )
125
+ AND C.maintenance_claimed_at <= clock_timestamp() - (
126
+ greatest(coalesce(p_claim_timeout_ms, 0), 0)::double precision * interval '1 millisecond'
127
+ )
128
+ )
129
+ OR (
130
+ C.maintenance_started_at IS NOT NULL
131
+ AND (S.id IS NULL OR S.status IN ('idle', 'failed', 'cancelled'))
132
+ AND NOT EXISTS (
133
+ SELECT 1
134
+ FROM %1$I.auth_runs R
135
+ WHERE R.workspace_id = C.workspace_id
136
+ AND R.maintenance_operation_id = C.maintenance_operation_id
137
+ AND R.settled_at IS NULL
138
+ )
139
+ AND C.maintenance_claimed_at <= clock_timestamp() - (
140
+ greatest(coalesce(p_claim_timeout_ms, 0), 0)::double precision * interval '1 millisecond'
141
+ )
142
+ )
143
+ )
144
+ ORDER BY C.next_check_at, C.id
145
+ LIMIT least(greatest(coalesce(p_limit, 0), 0), 1000)
146
+ FOR UPDATE OF C SKIP LOCKED
147
+ ), prepared AS (
148
+ SELECT
149
+ X.id,
150
+ CASE
151
+ WHEN X.maintenance_operation_id IS NOT NULL
152
+ AND (
153
+ X.maintenance_started_at IS NULL
154
+ OR X.session_status = 'queued'
155
+ )
156
+ THEN X.maintenance_operation_id
157
+ ELSE gen_random_uuid()
158
+ END AS operation_id,
159
+ CASE
160
+ WHEN X.maintenance_session_id IS NOT NULL
161
+ AND (
162
+ X.maintenance_started_at IS NULL
163
+ OR X.session_status = 'queued'
164
+ )
165
+ THEN X.maintenance_session_id
166
+ ELSE gen_random_uuid()
167
+ END AS session_id
168
+ FROM candidates X
169
+ ), claimed AS (
170
+ UPDATE %1$I.site_auth_connections C
171
+ SET
172
+ maintenance_operation_id = P.operation_id,
173
+ maintenance_action = CASE
174
+ WHEN C.verification_state IN ('needs_repair', 'failed')
175
+ AND (C.health_policy->>'automaticRepair')::boolean
176
+ THEN 'repair'
177
+ ELSE 'health_check'
178
+ END,
179
+ maintenance_due_at = C.next_check_at,
180
+ maintenance_claimed_at = clock_timestamp(),
181
+ maintenance_session_id = P.session_id,
182
+ maintenance_started_at = NULL,
183
+ version = C.version + 1,
184
+ updated_by_subject_id = 'site-auth-maintenance',
185
+ updated_at = clock_timestamp()
186
+ FROM prepared P
187
+ WHERE C.id = P.id
188
+ RETURNING C.*
189
+ ), revisions AS (
190
+ INSERT INTO %1$I.workspace_interaction_revisions (
191
+ workspace_id, account_id, revision, updated_at
192
+ )
193
+ SELECT DISTINCT C.workspace_id, C.account_id, 1, clock_timestamp()
194
+ FROM claimed C
195
+ ON CONFLICT (workspace_id) DO UPDATE
196
+ SET revision = %1$I.workspace_interaction_revisions.revision + 1,
197
+ updated_at = excluded.updated_at
198
+ RETURNING workspace_id
199
+ )
200
+ SELECT
201
+ C.maintenance_operation_id,
202
+ C.maintenance_session_id,
203
+ C.account_id,
204
+ C.workspace_id,
205
+ C.id,
206
+ C.version,
207
+ C.maintenance_action,
208
+ C.maintenance_due_at,
209
+ C.maintenance_claimed_at,
210
+ C.name,
211
+ C.account_label,
212
+ C.login_url,
213
+ C.verification_url_prefixes,
214
+ C.preferred_identity_id,
215
+ C.preferred_placement,
216
+ C.preferred_network_route_id,
217
+ C.health_policy,
218
+ C.verification_state
219
+ FROM claimed C;
220
+ $function$;
221
+ $create$, target_schema);
222
+ END $migration$;
223
+
224
+ REVOKE ALL ON FUNCTION opengeni_private.claim_site_auth_maintenance(bigint, integer)
225
+ FROM PUBLIC;
226
+
227
+ DO $site_auth_maintenance_role_grants$
228
+ BEGIN
229
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
230
+ GRANT EXECUTE ON FUNCTION opengeni_private.claim_site_auth_maintenance(bigint, integer)
231
+ TO opengeni_app;
232
+ END IF;
233
+ END
234
+ $site_auth_maintenance_role_grants$;
@@ -0,0 +1,38 @@
1
+ -- deployment-mode: rolling
2
+ SET lock_timeout = '5s';
3
+ SET statement_timeout = '30s';
4
+
5
+ -- Configuration revisions and delivery receipts remain immutable while their
6
+ -- workspace exists. Parent account/workspace deletion must still be able to
7
+ -- cascade through that history, including on embedded non-public schemas.
8
+ CREATE OR REPLACE FUNCTION opengeni_private.reject_memory_slack_immutable_mutation()
9
+ RETURNS trigger
10
+ LANGUAGE plpgsql
11
+ SECURITY DEFINER
12
+ SET search_path = pg_catalog
13
+ AS $function$
14
+ DECLARE
15
+ workspace_exists boolean;
16
+ BEGIN
17
+ IF TG_OP = 'DELETE' THEN
18
+ IF pg_trigger_depth() > 1 THEN
19
+ RETURN OLD;
20
+ END IF;
21
+
22
+ EXECUTE format(
23
+ 'SELECT EXISTS (SELECT 1 FROM %I.workspaces WHERE id = $1)',
24
+ TG_TABLE_SCHEMA
25
+ )
26
+ INTO workspace_exists
27
+ USING OLD.workspace_id;
28
+ IF NOT workspace_exists THEN
29
+ RETURN OLD;
30
+ END IF;
31
+ END IF;
32
+
33
+ RAISE EXCEPTION '% is append-only', TG_TABLE_NAME USING ERRCODE = '55000';
34
+ END;
35
+ $function$;
36
+
37
+ REVOKE ALL ON FUNCTION opengeni_private.reject_memory_slack_immutable_mutation()
38
+ FROM PUBLIC;
@@ -0,0 +1,54 @@
1
+ -- deployment-mode: rolling
2
+
3
+ -- Workspace-shared channels organize root sessions ("workstreams") by work
4
+ -- type in the rail. A channel is pure organizational metadata: filing a
5
+ -- session into one never affects execution, authority, memory, or history,
6
+ -- and deleting a channel only detaches its sessions (channel_id -> NULL).
7
+ CREATE TABLE "channels" (
8
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
9
+ "account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
10
+ "workspace_id" uuid NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
11
+ "name" text NOT NULL,
12
+ "description" text,
13
+ -- Attribution string: 'user:<subject>' | 'session:<id>' | 'system'.
14
+ "created_by" text,
15
+ "created_at" timestamptz NOT NULL DEFAULT now(),
16
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
17
+ CONSTRAINT "channels_name_chk"
18
+ CHECK (length(btrim("name")) BETWEEN 1 AND 80 AND "name" = btrim("name")),
19
+ CONSTRAINT "channels_workspace_account_fk"
20
+ FOREIGN KEY ("workspace_id", "account_id")
21
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE
22
+ );
23
+
24
+ CREATE UNIQUE INDEX "channels_workspace_name_idx"
25
+ ON "channels" ("workspace_id", lower("name"));
26
+ CREATE UNIQUE INDEX "channels_workspace_id_uq"
27
+ ON "channels" ("workspace_id", "id");
28
+
29
+ ALTER TABLE "channels" ENABLE ROW LEVEL SECURITY;
30
+ ALTER TABLE "channels" FORCE ROW LEVEL SECURITY;
31
+ CREATE POLICY workspace_isolation ON "channels"
32
+ USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
33
+ WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
34
+
35
+ DO $grants$
36
+ DECLARE target_schema text := current_schema();
37
+ BEGIN
38
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
39
+ EXECUTE format(
40
+ 'GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE %I.channels TO opengeni_app',
41
+ target_schema
42
+ );
43
+ END IF;
44
+ END
45
+ $grants$;
46
+
47
+ -- A root session may be filed into one channel; NULL means unfiled (the
48
+ -- inbox). Keep this transaction to the metadata-only nullable column addition:
49
+ -- both the supporting index and the foreign-key validation need table scans,
50
+ -- so migrations 0221-0223 perform those steps without retaining this ADD
51
+ -- COLUMN transaction's ACCESS EXCLUSIVE lock for the duration of a scan.
52
+ SET LOCAL lock_timeout = '5s';
53
+ ALTER TABLE "sessions"
54
+ ADD COLUMN "channel_id" uuid;
@@ -0,0 +1,5 @@
1
+ -- deployment-mode: rolling
2
+ -- opengeni:concurrent-index lock-timeout=5s
3
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS "sessions_workspace_channel_idx"
4
+ ON "sessions" ("workspace_id", "channel_id")
5
+ WHERE "channel_id" IS NOT NULL;
@@ -0,0 +1,158 @@
1
+ -- deployment-mode: rolling
2
+ -- Activate the existing Slice-A session tenancy facts at the accepted-attempt
3
+ -- boundary. This migration is additive: legacy rows remain workspace-shared at
4
+ -- epoch 1, while new claim writers persist the exact session authority they
5
+ -- admitted.
6
+
7
+ SET LOCAL lock_timeout = '5s';
8
+ SET LOCAL statement_timeout = '10min';
9
+
10
+ ALTER TABLE "session_turn_attempts"
11
+ ADD COLUMN IF NOT EXISTS "authority_epoch" integer,
12
+ ADD COLUMN IF NOT EXISTS "authority_visibility" text,
13
+ ADD COLUMN IF NOT EXISTS "authority_owner_organization_membership_id" uuid;
14
+
15
+ UPDATE "session_turn_attempts" attempts
16
+ SET
17
+ authority_epoch = sessions.authority_epoch,
18
+ authority_visibility = sessions.visibility,
19
+ authority_owner_organization_membership_id = sessions.owner_organization_membership_id
20
+ FROM "sessions" sessions
21
+ WHERE sessions.workspace_id = attempts.workspace_id
22
+ AND sessions.id = attempts.session_id;
23
+
24
+ DO $session_visibility_attempt_compatibility$
25
+ DECLARE
26
+ data_schema text := current_schema();
27
+ BEGIN
28
+ EXECUTE format($ddl$
29
+ CREATE OR REPLACE FUNCTION %1$I.session_turn_attempts_fill_authority_snapshot()
30
+ RETURNS trigger
31
+ LANGUAGE plpgsql
32
+ AS $body$
33
+ DECLARE
34
+ workspace_marker boolean;
35
+ source_epoch integer;
36
+ source_visibility text;
37
+ source_owner uuid;
38
+ BEGIN
39
+ SELECT true
40
+ INTO STRICT workspace_marker
41
+ FROM %1$I.workspaces workspace_row
42
+ WHERE workspace_row.id = NEW.workspace_id
43
+ AND workspace_row.account_id = NEW.account_id
44
+ FOR KEY SHARE;
45
+
46
+ SELECT
47
+ source.authority_epoch,
48
+ source.visibility,
49
+ source.owner_organization_membership_id
50
+ INTO STRICT source_epoch, source_visibility, source_owner
51
+ FROM %1$I.sessions source
52
+ WHERE source.workspace_id = NEW.workspace_id
53
+ AND source.account_id = NEW.account_id
54
+ AND source.id = NEW.session_id
55
+ FOR UPDATE;
56
+
57
+ NEW.authority_epoch := source_epoch;
58
+ NEW.authority_visibility := source_visibility;
59
+ NEW.authority_owner_organization_membership_id := source_owner;
60
+ RETURN NEW;
61
+ EXCEPTION
62
+ WHEN NO_DATA_FOUND THEN
63
+ RAISE EXCEPTION 'session authority snapshot source workspace/session not found: %%/%%',
64
+ NEW.workspace_id, NEW.session_id
65
+ USING ERRCODE = '23503';
66
+ END;
67
+ $body$;
68
+ $ddl$, data_schema);
69
+
70
+ EXECUTE format(
71
+ 'DROP TRIGGER IF EXISTS session_turn_attempts_fill_authority_snapshot_trg ON %I.session_turn_attempts',
72
+ data_schema
73
+ );
74
+ EXECUTE format($ddl$
75
+ CREATE TRIGGER session_turn_attempts_fill_authority_snapshot_trg
76
+ BEFORE INSERT ON %1$I.session_turn_attempts
77
+ FOR EACH ROW
78
+ WHEN (
79
+ NEW.authority_epoch IS NULL
80
+ AND NEW.authority_visibility IS NULL
81
+ AND NEW.authority_owner_organization_membership_id IS NULL
82
+ )
83
+ EXECUTE FUNCTION %1$I.session_turn_attempts_fill_authority_snapshot()
84
+ $ddl$, data_schema);
85
+ END;
86
+ $session_visibility_attempt_compatibility$;
87
+
88
+ ALTER TABLE "session_turn_attempts"
89
+ ADD CONSTRAINT "session_turn_attempts_authority_epoch_check"
90
+ CHECK (
91
+ "authority_epoch" IS NOT NULL
92
+ AND "authority_visibility" IS NOT NULL
93
+ AND "authority_epoch" > 0
94
+ ) NOT VALID,
95
+ ADD CONSTRAINT "session_turn_attempts_authority_visibility_check"
96
+ CHECK (
97
+ "authority_epoch" IS NOT NULL
98
+ AND "authority_visibility" IS NOT NULL
99
+ AND "authority_visibility" IN ('user_private', 'workspace_shared')
100
+ ) NOT VALID,
101
+ ADD CONSTRAINT "session_turn_attempts_authority_owner_shape_check"
102
+ CHECK (
103
+ "authority_visibility" <> 'user_private'
104
+ OR "authority_owner_organization_membership_id" IS NOT NULL
105
+ ) NOT VALID,
106
+ ADD CONSTRAINT "session_turn_attempts_authority_owner_fk"
107
+ FOREIGN KEY ("authority_owner_organization_membership_id", "account_id")
108
+ REFERENCES "organization_memberships"("id", "account_id")
109
+ ON DELETE RESTRICT NOT VALID;
110
+
111
+ ALTER TABLE "session_turn_attempts"
112
+ VALIDATE CONSTRAINT "session_turn_attempts_authority_epoch_check",
113
+ VALIDATE CONSTRAINT "session_turn_attempts_authority_visibility_check",
114
+ VALIDATE CONSTRAINT "session_turn_attempts_authority_owner_shape_check",
115
+ VALIDATE CONSTRAINT "session_turn_attempts_authority_owner_fk";
116
+
117
+ ALTER TABLE "session_turn_attempts"
118
+ ALTER COLUMN "authority_epoch" SET NOT NULL,
119
+ ALTER COLUMN "authority_visibility" SET NOT NULL;
120
+
121
+ CREATE INDEX IF NOT EXISTS "session_turn_attempts_authority_epoch_idx"
122
+ ON "session_turn_attempts" ("workspace_id", "session_id", "authority_epoch");
123
+
124
+ DO $session_visibility_attempt_immutability$
125
+ DECLARE
126
+ data_schema text := current_schema();
127
+ BEGIN
128
+ EXECUTE format($ddl$
129
+ CREATE OR REPLACE FUNCTION %1$I.session_turn_attempts_guard_authority_snapshot_immutable()
130
+ RETURNS trigger
131
+ LANGUAGE plpgsql
132
+ AS $body$
133
+ BEGIN
134
+ IF NEW.authority_epoch IS DISTINCT FROM OLD.authority_epoch
135
+ OR NEW.authority_visibility IS DISTINCT FROM OLD.authority_visibility
136
+ OR NEW.authority_owner_organization_membership_id IS DISTINCT FROM OLD.authority_owner_organization_membership_id
137
+ THEN
138
+ RAISE EXCEPTION 'session turn attempt authority snapshot is immutable'
139
+ USING ERRCODE = '23514';
140
+ END IF;
141
+ RETURN NEW;
142
+ END;
143
+ $body$;
144
+ $ddl$, data_schema);
145
+
146
+ EXECUTE format(
147
+ 'DROP TRIGGER IF EXISTS session_turn_attempts_guard_authority_snapshot_immutable_trg ON %I.session_turn_attempts',
148
+ data_schema
149
+ );
150
+ EXECUTE format($ddl$
151
+ CREATE TRIGGER session_turn_attempts_guard_authority_snapshot_immutable_trg
152
+ BEFORE UPDATE OF authority_epoch, authority_visibility, authority_owner_organization_membership_id
153
+ ON %1$I.session_turn_attempts
154
+ FOR EACH ROW
155
+ EXECUTE FUNCTION %1$I.session_turn_attempts_guard_authority_snapshot_immutable()
156
+ $ddl$, data_schema);
157
+ END;
158
+ $session_visibility_attempt_immutability$;
@@ -0,0 +1,89 @@
1
+ -- deployment-mode: rolling
2
+ -- Install the channel foreign key without scanning the populated sessions
3
+ -- table while holding ACCESS EXCLUSIVE. New writes are checked immediately;
4
+ -- migration 0223 performs the bounded online validation scan separately.
5
+ --
6
+ -- The equivalent auto-named constraint may already exist on a database that
7
+ -- applied the original unreleased 0220 migration. Preserve that validated
8
+ -- constraint only when its complete catalog semantics match this migration.
9
+ SET LOCAL lock_timeout = '5s';
10
+
11
+ DO $migration$
12
+ DECLARE
13
+ same_name_count integer;
14
+ exact_count integer;
15
+ BEGIN
16
+ SELECT count(*)::integer
17
+ INTO same_name_count
18
+ FROM pg_catalog.pg_constraint AS constraint_row
19
+ WHERE constraint_row.conrelid = 'sessions'::regclass
20
+ AND constraint_row.conname IN ('sessions_channel_id_fk', 'sessions_channel_id_fkey');
21
+
22
+ SELECT count(*)::integer
23
+ INTO exact_count
24
+ FROM pg_catalog.pg_constraint AS constraint_row
25
+ JOIN pg_catalog.pg_attribute AS local_column
26
+ ON local_column.attrelid = constraint_row.conrelid
27
+ AND local_column.attnum = constraint_row.conkey[1]
28
+ JOIN pg_catalog.pg_attribute AS referenced_column
29
+ ON referenced_column.attrelid = constraint_row.confrelid
30
+ AND referenced_column.attnum = constraint_row.confkey[1]
31
+ WHERE constraint_row.conrelid = 'sessions'::regclass
32
+ AND constraint_row.confrelid = 'channels'::regclass
33
+ AND constraint_row.contype = 'f'
34
+ AND constraint_row.conname IN ('sessions_channel_id_fk', 'sessions_channel_id_fkey')
35
+ AND cardinality(constraint_row.conkey) = 1
36
+ AND cardinality(constraint_row.confkey) = 1
37
+ AND local_column.attname = 'channel_id'
38
+ AND referenced_column.attname = 'id'
39
+ AND constraint_row.confdeltype = 'n'
40
+ AND constraint_row.confupdtype = 'a'
41
+ AND constraint_row.confmatchtype = 's'
42
+ AND NOT constraint_row.condeferrable
43
+ AND NOT constraint_row.condeferred;
44
+
45
+ IF same_name_count <> exact_count OR exact_count > 1 THEN
46
+ RAISE EXCEPTION
47
+ 'sessions channel foreign key name is occupied by an incompatible constraint';
48
+ END IF;
49
+
50
+ IF exact_count = 0 THEN
51
+ ALTER TABLE "sessions"
52
+ ADD CONSTRAINT "sessions_channel_id_fk"
53
+ FOREIGN KEY ("channel_id")
54
+ REFERENCES "channels"("id")
55
+ MATCH SIMPLE
56
+ ON UPDATE NO ACTION
57
+ ON DELETE SET NULL
58
+ NOT DEFERRABLE
59
+ NOT VALID;
60
+
61
+ SELECT count(*)::integer
62
+ INTO exact_count
63
+ FROM pg_catalog.pg_constraint AS constraint_row
64
+ JOIN pg_catalog.pg_attribute AS local_column
65
+ ON local_column.attrelid = constraint_row.conrelid
66
+ AND local_column.attnum = constraint_row.conkey[1]
67
+ JOIN pg_catalog.pg_attribute AS referenced_column
68
+ ON referenced_column.attrelid = constraint_row.confrelid
69
+ AND referenced_column.attnum = constraint_row.confkey[1]
70
+ WHERE constraint_row.conrelid = 'sessions'::regclass
71
+ AND constraint_row.confrelid = 'channels'::regclass
72
+ AND constraint_row.contype = 'f'
73
+ AND constraint_row.conname = 'sessions_channel_id_fk'
74
+ AND cardinality(constraint_row.conkey) = 1
75
+ AND cardinality(constraint_row.confkey) = 1
76
+ AND local_column.attname = 'channel_id'
77
+ AND referenced_column.attname = 'id'
78
+ AND constraint_row.confdeltype = 'n'
79
+ AND constraint_row.confupdtype = 'a'
80
+ AND constraint_row.confmatchtype = 's'
81
+ AND NOT constraint_row.condeferrable
82
+ AND NOT constraint_row.condeferred;
83
+
84
+ IF exact_count <> 1 THEN
85
+ RAISE EXCEPTION 'failed to install the exact sessions channel foreign key';
86
+ END IF;
87
+ END IF;
88
+ END
89
+ $migration$;
@@ -0,0 +1,55 @@
1
+ -- deployment-mode: rolling
2
+ -- Preserve the exact audit-event output separately from the bounded
3
+ -- model-facing result item so crash recovery can reproduce the live event.
4
+
5
+ SET lock_timeout = '5s';
6
+ SET statement_timeout = '10min';
7
+
8
+ ALTER TABLE session_pending_tool_calls
9
+ ADD COLUMN IF NOT EXISTS event_output jsonb,
10
+ ADD COLUMN IF NOT EXISTS event_output_codec_version integer;
11
+
12
+ ALTER TABLE session_pending_tool_calls
13
+ DROP CONSTRAINT IF EXISTS session_pending_tool_calls_event_output_codec_version_chk;
14
+
15
+ ALTER TABLE session_pending_tool_calls
16
+ ADD CONSTRAINT session_pending_tool_calls_event_output_codec_version_chk
17
+ CHECK (
18
+ (event_output IS NULL AND event_output_codec_version IS NULL)
19
+ OR (event_output IS NOT NULL AND event_output_codec_version = 1)
20
+ ) NOT VALID;
21
+
22
+ ALTER TABLE session_pending_tool_calls
23
+ VALIDATE CONSTRAINT session_pending_tool_calls_event_output_codec_version_chk;
24
+
25
+ COMMENT ON COLUMN session_pending_tool_calls.event_output IS
26
+ 'Lossless {value} envelope for the exact agent.toolCall.output projection retained until live publish or recovery.';
27
+ COMMENT ON COLUMN session_pending_tool_calls.event_output_codec_version IS
28
+ 'Out-of-band lossless JSON codec version for event_output; NULL denotes an older writer or no retained event output.';
29
+
30
+ CREATE OR REPLACE FUNCTION opengeni_private.guard_pending_tool_event_output_delete()
31
+ RETURNS trigger
32
+ LANGUAGE plpgsql
33
+ SET search_path = pg_catalog
34
+ AS $$
35
+ BEGIN
36
+ IF OLD.event_output IS NOT NULL
37
+ AND nullif(current_setting('opengeni.account_id', true), '') IS NOT NULL
38
+ AND current_setting('opengeni.pending_tool_event_output_v1', true) IS DISTINCT FROM '1' THEN
39
+ RAISE EXCEPTION USING
40
+ ERRCODE = '55000',
41
+ MESSAGE = 'rich pending tool output requires a v1-aware settlement worker';
42
+ END IF;
43
+ RETURN OLD;
44
+ END;
45
+ $$;
46
+
47
+ DROP TRIGGER IF EXISTS session_pending_tool_calls_event_output_delete_guard
48
+ ON session_pending_tool_calls;
49
+
50
+ CREATE TRIGGER session_pending_tool_calls_event_output_delete_guard
51
+ BEFORE DELETE ON session_pending_tool_calls
52
+ FOR EACH ROW
53
+ EXECUTE FUNCTION opengeni_private.guard_pending_tool_event_output_delete();
54
+
55
+ REVOKE ALL ON FUNCTION opengeni_private.guard_pending_tool_event_output_delete() FROM PUBLIC;