@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
@@ -0,0 +1,523 @@
1
+ -- deployment-mode: maintenance
2
+ -- Add provider-neutral deterministic knowledge-source actions to shared
3
+ -- Schedules. This is one cutover because pre-0197 control workers route every
4
+ -- schedule through session/model/billing dispatch, and the document identity
5
+ -- indexes below require bounded exclusive locks. Stop every API/control/turn
6
+ -- worker before activation and never restart an older image after commit.
7
+
8
+ SET LOCAL lock_timeout = '5s';
9
+ SET LOCAL statement_timeout = '30min';
10
+
11
+ -- Reject mixed old/new application writers before waiting on the cutover
12
+ -- locks. Repeat after the locks to close the connect-before-lock race.
13
+ DO $knowledge_source_sync_maintenance_preflight$
14
+ BEGIN
15
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app')
16
+ AND EXISTS (
17
+ SELECT 1
18
+ FROM pg_stat_activity
19
+ WHERE datname = current_database()
20
+ AND usename = 'opengeni_app'
21
+ AND pid <> pg_backend_pid()
22
+ )
23
+ THEN
24
+ RAISE EXCEPTION
25
+ 'knowledge source sync activation requires all opengeni_app sessions to be stopped'
26
+ USING ERRCODE = '55000';
27
+ END IF;
28
+ END
29
+ $knowledge_source_sync_maintenance_preflight$;
30
+
31
+ LOCK TABLE "scheduled_tasks" IN ACCESS EXCLUSIVE MODE;
32
+ LOCK TABLE "scheduled_task_runs" IN ACCESS EXCLUSIVE MODE;
33
+ LOCK TABLE "documents" IN ACCESS EXCLUSIVE MODE;
34
+ LOCK TABLE "knowledge_document_versions" IN ACCESS EXCLUSIVE MODE;
35
+
36
+ DO $knowledge_source_sync_maintenance_guard$
37
+ BEGIN
38
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app')
39
+ AND EXISTS (
40
+ SELECT 1
41
+ FROM pg_stat_activity
42
+ WHERE datname = current_database()
43
+ AND usename = 'opengeni_app'
44
+ AND pid <> pg_backend_pid()
45
+ )
46
+ THEN
47
+ RAISE EXCEPTION
48
+ 'knowledge source sync activation requires all opengeni_app sessions to be stopped'
49
+ USING ERRCODE = '55000';
50
+ END IF;
51
+ END
52
+ $knowledge_source_sync_maintenance_guard$;
53
+
54
+ ALTER TABLE "scheduled_tasks"
55
+ ADD COLUMN IF NOT EXISTS "action" jsonb NOT NULL DEFAULT '{"kind":"agent_turn"}'::jsonb;
56
+
57
+ UPDATE "scheduled_tasks"
58
+ SET "action" = '{"kind":"agent_turn"}'::jsonb
59
+ WHERE "action" IS NULL OR jsonb_typeof("action") <> 'object' OR "action"->>'kind' IS NULL;
60
+
61
+ ALTER TABLE "scheduled_tasks"
62
+ ADD CONSTRAINT "scheduled_tasks_action_chk" CHECK (
63
+ jsonb_typeof("action") = 'object'
64
+ AND "action"->>'kind' IN ('agent_turn', 'knowledge_source_sync')
65
+ AND octet_length(convert_to("action"::text, 'UTF8')) <= 32768
66
+ AND (
67
+ "action"->>'kind' = 'agent_turn'
68
+ OR (
69
+ "run_mode" = 'new_session_per_run'
70
+ AND "reusable_session_id" IS NULL
71
+ AND "variable_set_id" IS NULL
72
+ AND "rig_id" IS NULL
73
+ AND "overlap_policy" IN ('skip', 'buffer_one')
74
+ )
75
+ )
76
+ ) NOT VALID;
77
+
78
+ ALTER TABLE "scheduled_tasks" VALIDATE CONSTRAINT "scheduled_tasks_action_chk";
79
+
80
+ ALTER TABLE "scheduled_task_runs"
81
+ ADD COLUMN IF NOT EXISTS "action_kind" text NOT NULL DEFAULT 'agent_turn',
82
+ ADD COLUMN IF NOT EXISTS "knowledge_sync_run_id" uuid,
83
+ ADD COLUMN IF NOT EXISTS "knowledge_summary" jsonb,
84
+ ADD COLUMN IF NOT EXISTS "completed_at" timestamptz;
85
+
86
+ ALTER TABLE "scheduled_task_runs"
87
+ ADD CONSTRAINT "scheduled_task_runs_action_chk" CHECK (
88
+ "action_kind" IN ('agent_turn', 'knowledge_source_sync')
89
+ AND ("knowledge_summary" IS NULL OR (
90
+ jsonb_typeof("knowledge_summary") = 'object'
91
+ AND octet_length(convert_to("knowledge_summary"::text, 'UTF8')) <= 16384
92
+ ))
93
+ ) NOT VALID;
94
+
95
+ ALTER TABLE "scheduled_task_runs" VALIDATE CONSTRAINT "scheduled_task_runs_action_chk";
96
+
97
+ -- Content-addressed files may be shared by multiple provider objects. Preserve
98
+ -- the legacy per-base file uniqueness only for ordinary documents, and give
99
+ -- connector documents an independent immutable source-object/version key.
100
+ ALTER TABLE "documents"
101
+ ADD COLUMN IF NOT EXISTS "knowledge_source_identity" text;
102
+
103
+ DROP INDEX IF EXISTS "documents_workspace_base_file_idx";
104
+
105
+ CREATE UNIQUE INDEX "documents_workspace_base_file_idx"
106
+ ON "documents" ("workspace_id", "base_id", "file_id")
107
+ WHERE "knowledge_source_identity" IS NULL;
108
+
109
+ CREATE UNIQUE INDEX "documents_workspace_knowledge_source_identity_uq"
110
+ ON "documents" ("workspace_id", "knowledge_source_identity")
111
+ WHERE "knowledge_source_identity" IS NOT NULL;
112
+
113
+ ALTER TABLE "documents"
114
+ ADD CONSTRAINT "documents_knowledge_source_identity_chk" CHECK (
115
+ "knowledge_source_identity" IS NULL
116
+ OR length(btrim("knowledge_source_identity")) BETWEEN 1 AND 512
117
+ ) NOT VALID;
118
+
119
+ ALTER TABLE "documents" VALIDATE CONSTRAINT "documents_knowledge_source_identity_chk";
120
+
121
+ -- Provider revisions identify provider observations, not immutable OpenGeni
122
+ -- observations. Metadata/ACL-only observations may legitimately share bytes
123
+ -- and provider revision while retaining a distinct ingestion identity.
124
+ ALTER TABLE "knowledge_document_versions"
125
+ DROP CONSTRAINT IF EXISTS "knowledge_document_versions_object_external_version_uq";
126
+ CREATE INDEX IF NOT EXISTS "knowledge_document_versions_object_external_version_idx"
127
+ ON "knowledge_document_versions" ("object_id", "external_version_id");
128
+
129
+ ALTER TABLE "scheduled_task_runs"
130
+ ADD CONSTRAINT "scheduled_task_runs_knowledge_sync_fk"
131
+ FOREIGN KEY ("knowledge_sync_run_id") REFERENCES "knowledge_sync_runs"("id") ON DELETE SET NULL NOT VALID;
132
+
133
+ ALTER TABLE "scheduled_task_runs"
134
+ VALIDATE CONSTRAINT "scheduled_task_runs_knowledge_sync_fk";
135
+
136
+ CREATE INDEX IF NOT EXISTS "scheduled_task_runs_knowledge_sync_idx"
137
+ ON "scheduled_task_runs" ("workspace_id", "knowledge_sync_run_id")
138
+ WHERE "knowledge_sync_run_id" IS NOT NULL;
139
+
140
+ CREATE TABLE "knowledge_source_sync_states" (
141
+ "source_id" uuid PRIMARY KEY,
142
+ "account_id" uuid NOT NULL,
143
+ "workspace_id" uuid NOT NULL,
144
+ "scheduled_task_id" uuid NOT NULL,
145
+ "source_sync_generation" bigint NOT NULL,
146
+ "source_lifecycle_generation" bigint NOT NULL,
147
+ "source_config_generation" bigint NOT NULL,
148
+ "control_workspace_id" uuid NOT NULL,
149
+ "provider_coordination_key" text NOT NULL,
150
+ "connection_id" uuid NOT NULL,
151
+ "connection_version" bigint NOT NULL,
152
+ "connection_provider_domain" text NOT NULL,
153
+ "connection_kind" text NOT NULL,
154
+ "connection_owner_subject_id" text NOT NULL,
155
+ "initiating_subject_id" text NOT NULL,
156
+ "destination" jsonb NOT NULL,
157
+ "execution_checkpoint" jsonb,
158
+ "execution_checkpoint_generation" bigint NOT NULL DEFAULT 0,
159
+ "active_scan_generation" bigint NOT NULL DEFAULT 0,
160
+ "provider_cursor" jsonb,
161
+ "wake_revision" bigint NOT NULL DEFAULT 0,
162
+ "pending_wake_count" integer NOT NULL DEFAULT 0,
163
+ "lease_id" uuid,
164
+ "lease_until" timestamptz,
165
+ "buffered_wake" boolean NOT NULL DEFAULT false,
166
+ "buffered_scheduled_task_run_id" uuid,
167
+ "reconnect_required" boolean NOT NULL DEFAULT false,
168
+ "last_success_at" timestamptz,
169
+ "last_completed_at" timestamptz,
170
+ "last_summary" jsonb,
171
+ "created_at" timestamptz NOT NULL DEFAULT now(),
172
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
173
+ CONSTRAINT "knowledge_source_sync_states_source_fk"
174
+ FOREIGN KEY ("source_id") REFERENCES "knowledge_sources"("id") ON DELETE CASCADE,
175
+ CONSTRAINT "knowledge_source_sync_states_workspace_fk"
176
+ FOREIGN KEY ("workspace_id", "account_id")
177
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
178
+ CONSTRAINT "knowledge_source_sync_states_task_fk"
179
+ FOREIGN KEY ("scheduled_task_id") REFERENCES "scheduled_tasks"("id") ON DELETE CASCADE,
180
+ CONSTRAINT "knowledge_source_sync_states_buffered_run_fk"
181
+ FOREIGN KEY ("buffered_scheduled_task_run_id") REFERENCES "scheduled_task_runs"("id") ON DELETE SET NULL,
182
+ CONSTRAINT "knowledge_source_sync_states_task_uq" UNIQUE ("scheduled_task_id"),
183
+ CONSTRAINT "knowledge_source_sync_states_authority_chk" CHECK (
184
+ "source_sync_generation" >= 0
185
+ AND "source_lifecycle_generation" > 0
186
+ AND "source_config_generation" > 0
187
+ AND "control_workspace_id" = "workspace_id"
188
+ AND length(btrim("provider_coordination_key")) BETWEEN 1 AND 1024
189
+ AND "connection_version" > 0
190
+ AND length(btrim("connection_provider_domain")) BETWEEN 1 AND 2048
191
+ AND "connection_kind" IN ('oauth2', 'api_key', 'app_install', 'delegated')
192
+ AND length(btrim("connection_owner_subject_id")) BETWEEN 1 AND 1024
193
+ AND length(btrim("initiating_subject_id")) BETWEEN 1 AND 1024
194
+ AND jsonb_typeof("destination") = 'object'
195
+ AND ("execution_checkpoint" IS NULL OR (
196
+ jsonb_typeof("execution_checkpoint") = 'object'
197
+ AND octet_length(convert_to("execution_checkpoint"::text, 'UTF8')) <= 2097152
198
+ ))
199
+ AND "execution_checkpoint_generation" >= 0
200
+ AND "active_scan_generation" >= 0
201
+ AND ("provider_cursor" IS NULL OR (
202
+ jsonb_typeof("provider_cursor") = 'object'
203
+ AND octet_length(convert_to("provider_cursor"::text, 'UTF8')) <= 1048576
204
+ ))
205
+ AND "wake_revision" >= 0
206
+ AND "pending_wake_count" >= 0
207
+ AND (("lease_id" IS NULL AND "lease_until" IS NULL)
208
+ OR ("lease_id" IS NOT NULL AND "lease_until" IS NOT NULL))
209
+ AND (("buffered_wake" = true AND "buffered_scheduled_task_run_id" IS NOT NULL)
210
+ OR ("buffered_wake" = false AND "buffered_scheduled_task_run_id" IS NULL))
211
+ AND ("last_summary" IS NULL OR (
212
+ jsonb_typeof("last_summary") = 'object'
213
+ AND octet_length(convert_to("last_summary"::text, 'UTF8')) <= 16384
214
+ ))
215
+ )
216
+ );
217
+
218
+ CREATE TABLE "knowledge_source_sync_object_observations" (
219
+ "source_id" uuid NOT NULL,
220
+ "external_object_id" text NOT NULL,
221
+ "account_id" uuid NOT NULL,
222
+ "workspace_id" uuid NOT NULL,
223
+ "scheduled_task_run_id" uuid,
224
+ "scan_generation" bigint NOT NULL,
225
+ "provider_revision" text,
226
+ "metadata_hash" text,
227
+ "observed_at" timestamptz NOT NULL DEFAULT now(),
228
+ CONSTRAINT "knowledge_source_sync_object_observations_identity_uq"
229
+ UNIQUE ("source_id", "external_object_id"),
230
+ CONSTRAINT "knowledge_source_sync_object_observations_source_fk"
231
+ FOREIGN KEY ("source_id") REFERENCES "knowledge_sources"("id") ON DELETE CASCADE,
232
+ CONSTRAINT "knowledge_source_sync_object_observations_workspace_fk"
233
+ FOREIGN KEY ("workspace_id", "account_id") REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
234
+ CONSTRAINT "knowledge_source_sync_object_observations_run_fk"
235
+ FOREIGN KEY ("scheduled_task_run_id") REFERENCES "scheduled_task_runs"("id") ON DELETE SET NULL,
236
+ CONSTRAINT "knowledge_source_sync_object_observations_bounds_chk" CHECK (
237
+ length(btrim("external_object_id")) BETWEEN 1 AND 1024
238
+ AND "scan_generation" > 0
239
+ AND ("provider_revision" IS NULL OR length("provider_revision") BETWEEN 1 AND 1024)
240
+ AND ("metadata_hash" IS NULL OR "metadata_hash" ~ '^[0-9a-f]{64}$')
241
+ )
242
+ );
243
+
244
+ CREATE INDEX "knowledge_source_sync_object_observations_scan_idx"
245
+ ON "knowledge_source_sync_object_observations" ("workspace_id", "source_id", "scan_generation");
246
+
247
+ CREATE INDEX "knowledge_source_sync_states_due_idx"
248
+ ON "knowledge_source_sync_states" ("workspace_id", "buffered_wake", "lease_until", "updated_at");
249
+
250
+ CREATE TABLE "knowledge_source_sync_item_outcomes" (
251
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
252
+ "account_id" uuid NOT NULL,
253
+ "workspace_id" uuid NOT NULL,
254
+ "scheduled_task_run_id" uuid NOT NULL,
255
+ "knowledge_sync_run_id" uuid,
256
+ "source_id" uuid NOT NULL,
257
+ "source_config_generation" bigint NOT NULL,
258
+ "source_lifecycle_generation" bigint NOT NULL,
259
+ "external_object_id" text NOT NULL,
260
+ "provider_revision" text,
261
+ "metadata_hash" text,
262
+ "acl_eligibility" text NOT NULL DEFAULT 'pending',
263
+ "acl_evidence" jsonb,
264
+ "index_obligation_id" uuid,
265
+ "outcome" text NOT NULL,
266
+ "reason_code" text,
267
+ "detail" text,
268
+ "content_sha256" text,
269
+ "size_bytes" bigint,
270
+ "created_at" timestamptz NOT NULL DEFAULT now(),
271
+ CONSTRAINT "knowledge_source_sync_item_outcomes_task_run_fk"
272
+ FOREIGN KEY ("scheduled_task_run_id") REFERENCES "scheduled_task_runs"("id") ON DELETE CASCADE,
273
+ CONSTRAINT "knowledge_source_sync_item_outcomes_sync_run_fk"
274
+ FOREIGN KEY ("knowledge_sync_run_id") REFERENCES "knowledge_sync_runs"("id") ON DELETE SET NULL,
275
+ CONSTRAINT "knowledge_source_sync_item_outcomes_source_fk"
276
+ FOREIGN KEY ("source_id") REFERENCES "knowledge_sources"("id") ON DELETE CASCADE,
277
+ CONSTRAINT "knowledge_source_sync_item_outcomes_workspace_fk"
278
+ FOREIGN KEY ("workspace_id", "account_id") REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
279
+ CONSTRAINT "knowledge_source_sync_item_outcomes_identity_uq"
280
+ UNIQUE ("scheduled_task_run_id", "external_object_id"),
281
+ CONSTRAINT "knowledge_source_sync_item_outcomes_bounds_chk" CHECK (
282
+ length(btrim("external_object_id")) BETWEEN 1 AND 1024
283
+ AND "source_config_generation" > 0
284
+ AND "source_lifecycle_generation" > 0
285
+ AND "outcome" IN ('imported', 'unchanged', 'skipped', 'failed', 'tombstoned')
286
+ AND ("provider_revision" IS NULL OR length("provider_revision") BETWEEN 1 AND 1024)
287
+ AND ("metadata_hash" IS NULL OR "metadata_hash" ~ '^[0-9a-f]{64}$')
288
+ AND "acl_eligibility" IN ('pending', 'eligible', 'denied')
289
+ AND ("acl_evidence" IS NULL OR (
290
+ jsonb_typeof("acl_evidence") = 'object'
291
+ AND octet_length(convert_to("acl_evidence"::text, 'UTF8')) <= 16384
292
+ ))
293
+ AND ("reason_code" IS NULL OR length(btrim("reason_code")) BETWEEN 1 AND 128)
294
+ AND ("detail" IS NULL OR length("detail") <= 1000)
295
+ AND ("content_sha256" IS NULL OR "content_sha256" ~ '^[0-9a-f]{64}$')
296
+ AND ("size_bytes" IS NULL OR "size_bytes" >= 0)
297
+ )
298
+ );
299
+
300
+ CREATE INDEX "knowledge_source_sync_item_outcomes_run_idx"
301
+ ON "knowledge_source_sync_item_outcomes" ("workspace_id", "scheduled_task_run_id", "created_at");
302
+
303
+ CREATE TABLE "knowledge_source_sync_wakes" (
304
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
305
+ "account_id" uuid NOT NULL,
306
+ "workspace_id" uuid NOT NULL,
307
+ "source_id" uuid NOT NULL,
308
+ "scheduled_task_id" uuid NOT NULL,
309
+ "scheduled_task_run_id" uuid NOT NULL,
310
+ "cause" text NOT NULL,
311
+ "producer_key" text NOT NULL,
312
+ "source_config_generation" bigint NOT NULL,
313
+ "source_lifecycle_generation" bigint NOT NULL,
314
+ "coalesced" boolean NOT NULL DEFAULT false,
315
+ "claimed_at" timestamptz,
316
+ "completed_at" timestamptz,
317
+ "created_at" timestamptz NOT NULL DEFAULT now(),
318
+ CONSTRAINT "knowledge_source_sync_wakes_workspace_fk"
319
+ FOREIGN KEY ("workspace_id", "account_id") REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
320
+ CONSTRAINT "knowledge_source_sync_wakes_source_fk"
321
+ FOREIGN KEY ("source_id") REFERENCES "knowledge_sources"("id") ON DELETE CASCADE,
322
+ CONSTRAINT "knowledge_source_sync_wakes_task_fk"
323
+ FOREIGN KEY ("scheduled_task_id") REFERENCES "scheduled_tasks"("id") ON DELETE CASCADE,
324
+ CONSTRAINT "knowledge_source_sync_wakes_run_fk"
325
+ FOREIGN KEY ("scheduled_task_run_id") REFERENCES "scheduled_task_runs"("id") ON DELETE CASCADE,
326
+ CONSTRAINT "knowledge_source_sync_wakes_run_uq" UNIQUE ("scheduled_task_run_id"),
327
+ CONSTRAINT "knowledge_source_sync_wakes_bounds_chk" CHECK (
328
+ "cause" IN ('scheduled', 'manual', 'initial', 'provider_event', 'retry', 'repair')
329
+ AND length(btrim("producer_key")) BETWEEN 1 AND 1024
330
+ AND "source_config_generation" > 0
331
+ AND "source_lifecycle_generation" > 0
332
+ AND ("completed_at" IS NULL OR "claimed_at" IS NOT NULL)
333
+ )
334
+ );
335
+
336
+ CREATE INDEX "knowledge_source_sync_wakes_pending_idx"
337
+ ON "knowledge_source_sync_wakes" ("workspace_id", "source_id", "completed_at", "created_at");
338
+
339
+ CREATE TABLE "knowledge_source_sync_index_obligations" (
340
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
341
+ "account_id" uuid NOT NULL,
342
+ "workspace_id" uuid NOT NULL,
343
+ "scheduled_task_run_id" uuid,
344
+ "source_id" uuid NOT NULL,
345
+ "source_sync_generation" bigint NOT NULL,
346
+ "initiating_subject_id" text NOT NULL,
347
+ "external_object_id" text NOT NULL,
348
+ "knowledge_source_object_id" uuid NOT NULL,
349
+ "knowledge_document_version_id" uuid NOT NULL,
350
+ "document_id" uuid NOT NULL,
351
+ "source_config_generation" bigint NOT NULL,
352
+ "source_lifecycle_generation" bigint NOT NULL,
353
+ "object_lifecycle_generation" bigint NOT NULL,
354
+ "object_version_generation" bigint NOT NULL,
355
+ "citation_locator" jsonb NOT NULL,
356
+ "acl_eligibility" text NOT NULL DEFAULT 'pending',
357
+ "status" text NOT NULL DEFAULT 'pending',
358
+ "failure_code" text,
359
+ "created_at" timestamptz NOT NULL DEFAULT now(),
360
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
361
+ CONSTRAINT "knowledge_source_sync_index_obligations_workspace_fk"
362
+ FOREIGN KEY ("workspace_id", "account_id") REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
363
+ CONSTRAINT "knowledge_source_sync_index_obligations_run_fk"
364
+ FOREIGN KEY ("scheduled_task_run_id") REFERENCES "scheduled_task_runs"("id") ON DELETE SET NULL,
365
+ CONSTRAINT "knowledge_source_sync_index_obligations_source_fk"
366
+ FOREIGN KEY ("source_id") REFERENCES "knowledge_sources"("id") ON DELETE CASCADE,
367
+ CONSTRAINT "knowledge_source_sync_index_obligations_object_fk"
368
+ FOREIGN KEY ("knowledge_source_object_id") REFERENCES "knowledge_source_objects"("id") ON DELETE CASCADE,
369
+ CONSTRAINT "knowledge_source_sync_index_obligations_version_fk"
370
+ FOREIGN KEY ("knowledge_document_version_id") REFERENCES "knowledge_document_versions"("id") ON DELETE CASCADE,
371
+ CONSTRAINT "knowledge_source_sync_index_obligations_document_fk"
372
+ FOREIGN KEY ("document_id") REFERENCES "documents"("id") ON DELETE CASCADE,
373
+ CONSTRAINT "knowledge_source_sync_index_obligations_version_uq" UNIQUE ("knowledge_document_version_id"),
374
+ CONSTRAINT "knowledge_source_sync_index_obligations_bounds_chk" CHECK (
375
+ length(btrim("external_object_id")) BETWEEN 1 AND 1024
376
+ AND "source_sync_generation" >= 0
377
+ AND length(btrim("initiating_subject_id")) BETWEEN 1 AND 1024
378
+ AND "source_config_generation" > 0
379
+ AND "source_lifecycle_generation" > 0
380
+ AND "object_lifecycle_generation" > 0
381
+ AND "object_version_generation" > 0
382
+ AND jsonb_typeof("citation_locator") = 'object'
383
+ AND octet_length(convert_to("citation_locator"::text, 'UTF8')) <= 16384
384
+ AND "acl_eligibility" IN ('pending', 'eligible', 'denied')
385
+ AND "status" IN ('pending', 'indexed', 'failed', 'invalidated')
386
+ AND ("failure_code" IS NULL OR length(btrim("failure_code")) BETWEEN 1 AND 128)
387
+ )
388
+ );
389
+
390
+ ALTER TABLE "knowledge_source_sync_item_outcomes"
391
+ ADD CONSTRAINT "knowledge_source_sync_item_outcomes_index_obligation_fk"
392
+ FOREIGN KEY ("index_obligation_id") REFERENCES "knowledge_source_sync_index_obligations"("id") ON DELETE SET NULL;
393
+
394
+ CREATE INDEX "knowledge_source_sync_index_obligations_pending_idx"
395
+ ON "knowledge_source_sync_index_obligations" ("workspace_id", "status", "created_at");
396
+
397
+ -- Runtime code needs row locks on the mutable source/object heads without
398
+ -- granting direct UPDATE on the scoped-knowledge tables. The helper observes
399
+ -- the existing account/workspace/subject RLS GUCs and follows the same
400
+ -- object-then-source order as scoped_knowledge_advance_object_version.
401
+ DO $knowledge_source_sync_lock_authority$
402
+ DECLARE data_schema text := current_schema();
403
+ BEGIN
404
+ EXECUTE format($ddl$
405
+ CREATE OR REPLACE FUNCTION %1$I.knowledge_source_sync_lock_authority(
406
+ p_account_id uuid,
407
+ p_source_id uuid,
408
+ p_object_id uuid
409
+ ) RETURNS void
410
+ LANGUAGE plpgsql SECURITY DEFINER SET search_path = %1$I, pg_catalog
411
+ AS $body$
412
+ DECLARE object_found boolean := false;
413
+ DECLARE source_found boolean := false;
414
+ BEGIN
415
+ IF p_account_id IS DISTINCT FROM opengeni_private.current_account_id() THEN
416
+ RAISE EXCEPTION 'knowledge source sync account authority is invalid'
417
+ USING ERRCODE = '42501';
418
+ END IF;
419
+ IF p_object_id IS NOT NULL THEN
420
+ SELECT true INTO object_found
421
+ FROM knowledge_source_objects object_row
422
+ WHERE object_row.account_id = p_account_id
423
+ AND object_row.id = p_object_id
424
+ AND object_row.source_id = p_source_id
425
+ AND opengeni_private.scoped_knowledge_scope_visible(
426
+ object_row.account_id,
427
+ object_row.scope_kind,
428
+ object_row.scope_workspace_id,
429
+ object_row.scope_subject_id
430
+ )
431
+ FOR UPDATE;
432
+ IF NOT coalesce(object_found, false) THEN
433
+ RAISE EXCEPTION 'knowledge source sync object authority was not found'
434
+ USING ERRCODE = 'P0002';
435
+ END IF;
436
+ END IF;
437
+ SELECT true INTO source_found
438
+ FROM knowledge_sources source_row
439
+ WHERE source_row.account_id = p_account_id
440
+ AND source_row.id = p_source_id
441
+ AND opengeni_private.scoped_knowledge_scope_visible(
442
+ source_row.account_id,
443
+ source_row.scope_kind,
444
+ source_row.scope_workspace_id,
445
+ source_row.scope_subject_id
446
+ )
447
+ FOR UPDATE;
448
+ IF NOT coalesce(source_found, false) THEN
449
+ RAISE EXCEPTION 'knowledge source sync source authority was not found'
450
+ USING ERRCODE = 'P0002';
451
+ END IF;
452
+ END;
453
+ $body$;
454
+ $ddl$, data_schema);
455
+ EXECUTE format(
456
+ 'REVOKE ALL ON FUNCTION %I.knowledge_source_sync_lock_authority(uuid,uuid,uuid) FROM PUBLIC',
457
+ data_schema
458
+ );
459
+ END
460
+ $knowledge_source_sync_lock_authority$;
461
+
462
+ ALTER TABLE "knowledge_source_sync_states" ENABLE ROW LEVEL SECURITY;
463
+ ALTER TABLE "knowledge_source_sync_states" FORCE ROW LEVEL SECURITY;
464
+ ALTER TABLE "knowledge_source_sync_item_outcomes" ENABLE ROW LEVEL SECURITY;
465
+ ALTER TABLE "knowledge_source_sync_item_outcomes" FORCE ROW LEVEL SECURITY;
466
+ ALTER TABLE "knowledge_source_sync_wakes" ENABLE ROW LEVEL SECURITY;
467
+ ALTER TABLE "knowledge_source_sync_wakes" FORCE ROW LEVEL SECURITY;
468
+ ALTER TABLE "knowledge_source_sync_index_obligations" ENABLE ROW LEVEL SECURITY;
469
+ ALTER TABLE "knowledge_source_sync_index_obligations" FORCE ROW LEVEL SECURITY;
470
+ ALTER TABLE "knowledge_source_sync_object_observations" ENABLE ROW LEVEL SECURITY;
471
+ ALTER TABLE "knowledge_source_sync_object_observations" FORCE ROW LEVEL SECURITY;
472
+
473
+ CREATE POLICY "knowledge_source_sync_states_workspace_isolation"
474
+ ON "knowledge_source_sync_states"
475
+ USING ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
476
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid)
477
+ WITH CHECK ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
478
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid);
479
+
480
+ CREATE POLICY "knowledge_source_sync_item_outcomes_workspace_isolation"
481
+ ON "knowledge_source_sync_item_outcomes"
482
+ USING ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
483
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid)
484
+ WITH CHECK ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
485
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid);
486
+
487
+ CREATE POLICY "knowledge_source_sync_wakes_workspace_isolation"
488
+ ON "knowledge_source_sync_wakes"
489
+ USING ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
490
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid)
491
+ WITH CHECK ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
492
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid);
493
+
494
+ CREATE POLICY "knowledge_source_sync_index_obligations_workspace_isolation"
495
+ ON "knowledge_source_sync_index_obligations"
496
+ USING ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
497
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid)
498
+ WITH CHECK ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
499
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid);
500
+
501
+ CREATE POLICY "knowledge_source_sync_object_observations_workspace_isolation"
502
+ ON "knowledge_source_sync_object_observations"
503
+ USING ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
504
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid)
505
+ WITH CHECK ("account_id" = nullif(current_setting('opengeni.account_id', true), '')::uuid
506
+ AND "workspace_id" = nullif(current_setting('opengeni.workspace_id', true), '')::uuid);
507
+
508
+ DO $runtime_grants$
509
+ DECLARE data_schema text := current_schema();
510
+ BEGIN
511
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
512
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "knowledge_source_sync_states" TO opengeni_app;
513
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "knowledge_source_sync_item_outcomes" TO opengeni_app;
514
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "knowledge_source_sync_wakes" TO opengeni_app;
515
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "knowledge_source_sync_index_obligations" TO opengeni_app;
516
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "knowledge_source_sync_object_observations" TO opengeni_app;
517
+ EXECUTE format(
518
+ 'GRANT EXECUTE ON FUNCTION %I.knowledge_source_sync_lock_authority(uuid,uuid,uuid) TO opengeni_app',
519
+ data_schema
520
+ );
521
+ END IF;
522
+ END
523
+ $runtime_grants$;