@opengeni/db 0.31.1 → 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.
- package/dist/browser-auth.d.ts +209 -1
- package/dist/browser-downloads.d.ts +51 -0
- package/dist/browser-identities.d.ts +11 -2
- package/dist/browser-sessions.d.ts +83 -1
- package/dist/browser-state-artifacts.d.ts +75 -1
- package/dist/canonical-human-identities.d.ts +48 -0
- package/dist/canonical-human-identities.js +28 -0
- package/dist/canonical-human-identities.js.map +1 -0
- package/dist/capability-integrations.d.ts +8 -6
- package/dist/{chunk-MWDVXQOL.js → chunk-5KTIEDX7.js} +5773 -4212
- package/dist/chunk-5KTIEDX7.js.map +1 -0
- package/dist/{chunk-NBE6CHRI.js → chunk-CQZ4QSP5.js} +49 -9
- package/dist/chunk-CQZ4QSP5.js.map +1 -0
- package/dist/chunk-F32YT7MP.js +117 -0
- package/dist/chunk-F32YT7MP.js.map +1 -0
- package/dist/{chunk-ISI2TIUG.js → chunk-JC5QPLUM.js} +30 -3
- package/dist/chunk-JC5QPLUM.js.map +1 -0
- package/dist/{chunk-F5FT7BEZ.js → chunk-P3RE4D2B.js} +2 -2
- package/dist/chunk-TAUTWOS5.js +259 -0
- package/dist/chunk-TAUTWOS5.js.map +1 -0
- package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
- package/dist/chunk-VKLB2ZGI.js.map +1 -0
- package/dist/database.d.ts +5 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +438 -29
- package/dist/index.js +35640 -28969
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +23 -7
- package/dist/integration-bindings.d.ts +24 -24
- package/dist/integration-facets.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +11 -0
- package/dist/interaction-schema.d.ts +698 -34
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +8 -7
- package/dist/schema.d.ts +9464 -5412
- package/dist/schema.js +51 -9
- package/dist/session-control.d.ts +29 -3
- package/dist/session-tenancy.d.ts +44 -0
- package/dist/session-tenancy.js +16 -0
- package/dist/session-tenancy.js.map +1 -0
- package/dist/slack-task-policy-schema.d.ts +847 -0
- package/dist/slack-task-policy.d.ts +65 -0
- package/dist/task-notes-schema.d.ts +924 -0
- package/dist/task-notes.d.ts +85 -0
- package/dist/video-generation.d.ts +9 -0
- package/dist/video-generation.js +5 -3
- package/dist/xai-subscription.d.ts +326 -0
- package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
- package/drizzle/0213_browser_interaction_authority.sql +67 -0
- package/drizzle/0214_browser_download_saves.sql +34 -0
- package/drizzle/0215_browser_controller_host.sql +385 -0
- package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
- package/drizzle/0217_external_browser_auth_operations.sql +22 -0
- package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
- package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
- package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
- package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
- package/drizzle/0220_session_channels.sql +54 -0
- package/drizzle/0221_sessions_channel_index.sql +5 -0
- package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
- package/drizzle/0222_sessions_channel_fk.sql +89 -0
- package/drizzle/0223_pending_tool_event_output.sql +55 -0
- package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
- package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
- package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
- package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
- package/drizzle/0227_slack_native_actions.sql +145 -0
- package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
- package/drizzle/0228_slack_task_policy.sql +400 -0
- package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
- package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
- package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
- package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
- package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
- package/drizzle/0234_xai_subscription_authority.sql +1139 -0
- package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
- package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
- package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
- package/drizzle/0237_interaction_transition_reaper.sql +263 -0
- package/drizzle/0238_goal_persistence_policy.sql +471 -0
- package/drizzle/0238_supergrok_realtime_model.sql +29 -0
- package/drizzle/0239_supergrok_video_funding.sql +50 -0
- package/drizzle/0239_task_tree_notes.sql +990 -0
- package/package.json +13 -5
- package/src/browser-auth.ts +2600 -123
- package/src/browser-downloads.ts +517 -0
- package/src/browser-identities.ts +220 -3
- package/src/browser-sessions.ts +334 -45
- package/src/browser-state-artifacts.ts +402 -12
- package/src/canonical-human-identities.ts +317 -0
- package/src/capability-integrations.ts +121 -213
- package/src/database.ts +41 -1
- package/src/index.ts +4157 -394
- package/src/insights.ts +109 -28
- package/src/integration-bindings.ts +101 -101
- package/src/{integration-features.ts → integration-facets.ts} +187 -184
- package/src/interaction-revisions.ts +33 -3
- package/src/interaction-schema.ts +311 -8
- package/src/pack-components.ts +43 -43
- package/src/pack-installations.ts +0 -43
- package/src/plugin-packages.ts +9 -9
- package/src/provision-roles.ts +232 -0
- package/src/runtime-posture.ts +227 -14
- package/src/schema.ts +1188 -75
- package/src/session-control.ts +122 -37
- package/src/session-queue-commands.ts +78 -1
- package/src/session-tenancy.ts +188 -0
- package/src/session-tool-call-settlement.ts +9 -3
- package/src/slack-task-policy-schema.ts +130 -0
- package/src/slack-task-policy.ts +341 -0
- package/src/task-notes-schema.ts +135 -0
- package/src/task-notes.ts +178 -0
- package/src/video-generation.ts +90 -12
- package/src/workspace-artifacts.ts +1 -1
- package/src/xai-subscription.ts +1887 -0
- package/dist/chunk-ISI2TIUG.js.map +0 -1
- package/dist/chunk-MWDVXQOL.js.map +0 -1
- package/dist/chunk-NBE6CHRI.js.map +0 -1
- package/dist/chunk-YHZXQ7HP.js.map +0 -1
- package/dist/integration-features.d.ts +0 -99
- /package/dist/{chunk-F5FT7BEZ.js.map → chunk-P3RE4D2B.js.map} +0 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
-- deployment-mode: maintenance
|
|
2
|
+
-- Separate a remote browser's logical placement from the sandbox that hosts
|
|
3
|
+
-- its sole browserd mutation controller. Existing managed sessions preserve
|
|
4
|
+
-- their current home placement; remote rows are backfilled from their immutable
|
|
5
|
+
-- creation association.
|
|
6
|
+
SET LOCAL lock_timeout = '5s';
|
|
7
|
+
SET LOCAL statement_timeout = '30s';
|
|
8
|
+
|
|
9
|
+
ALTER TABLE "browser_sessions"
|
|
10
|
+
ADD COLUMN "controller_host_sandbox_group_id" uuid;
|
|
11
|
+
|
|
12
|
+
UPDATE "browser_sessions"
|
|
13
|
+
SET "controller_host_sandbox_group_id" = "sandbox_group_id"
|
|
14
|
+
WHERE "placement_kind" = 'sandbox_group';
|
|
15
|
+
|
|
16
|
+
UPDATE "browser_sessions" browser
|
|
17
|
+
SET "controller_host_sandbox_group_id" = source."sandbox_group_id"
|
|
18
|
+
FROM "browser_session_associations" association
|
|
19
|
+
JOIN "sessions" source
|
|
20
|
+
ON source."workspace_id" = association."workspace_id"
|
|
21
|
+
AND source."id" = association."session_id"
|
|
22
|
+
WHERE browser."workspace_id" = association."workspace_id"
|
|
23
|
+
AND browser."id" = association."browser_session_id"
|
|
24
|
+
AND browser."placement_kind" = 'external_provider'
|
|
25
|
+
AND association."relationship" = 'created';
|
|
26
|
+
|
|
27
|
+
ALTER TABLE "browser_sessions"
|
|
28
|
+
ADD CONSTRAINT "browser_sessions_controller_host_check" CHECK (
|
|
29
|
+
("placement_kind" = 'sandbox_group'
|
|
30
|
+
AND "controller_host_sandbox_group_id" = "sandbox_group_id")
|
|
31
|
+
OR
|
|
32
|
+
("placement_kind" = 'external_provider'
|
|
33
|
+
AND "controller_host_sandbox_group_id" IS NOT NULL)
|
|
34
|
+
OR
|
|
35
|
+
("placement_kind" IN ('connected_machine', 'attached_device')
|
|
36
|
+
AND "controller_host_sandbox_group_id" IS NULL)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
CREATE INDEX "browser_sessions_controller_host_sandbox_group_idx"
|
|
40
|
+
ON "browser_sessions"
|
|
41
|
+
("workspace_id", "controller_host_sandbox_group_id", "lifecycle");
|
|
42
|
+
|
|
43
|
+
-- Reinstall the interaction-aware lease reaper against controller locality,
|
|
44
|
+
-- not logical browser locality. This keeps a remote browser alive exactly while
|
|
45
|
+
-- its home browserd lease and holder remain authoritative.
|
|
46
|
+
DO $interaction_aware_reaper$
|
|
47
|
+
DECLARE data_schema text := current_schema();
|
|
48
|
+
BEGIN
|
|
49
|
+
EXECUTE format($create$
|
|
50
|
+
CREATE OR REPLACE FUNCTION opengeni_private.reap_sandbox_leases(
|
|
51
|
+
p_viewer_holder_ttl_ms bigint,
|
|
52
|
+
p_turn_holder_ttl_ms bigint,
|
|
53
|
+
p_interaction_holder_ttl_ms bigint,
|
|
54
|
+
p_idle_grace_ms bigint
|
|
55
|
+
)
|
|
56
|
+
RETURNS TABLE (
|
|
57
|
+
workspace_id uuid,
|
|
58
|
+
sandbox_group_id uuid,
|
|
59
|
+
instance_id text,
|
|
60
|
+
lease_epoch integer
|
|
61
|
+
)
|
|
62
|
+
LANGUAGE plpgsql
|
|
63
|
+
SECURITY DEFINER
|
|
64
|
+
SET search_path = pg_catalog
|
|
65
|
+
AS $function$
|
|
66
|
+
DECLARE
|
|
67
|
+
locked_ids uuid[];
|
|
68
|
+
stale_interaction_ids uuid[];
|
|
69
|
+
changed_interaction_workspaces uuid[];
|
|
70
|
+
BEGIN
|
|
71
|
+
PERFORM pg_catalog.set_config('opengeni.sandbox_recovery_protocol_v2', '1', true);
|
|
72
|
+
|
|
73
|
+
SELECT coalesce(pg_catalog.array_agg(candidate.id), ARRAY[]::uuid[])
|
|
74
|
+
INTO locked_ids
|
|
75
|
+
FROM (
|
|
76
|
+
SELECT lease.id
|
|
77
|
+
FROM %1$I.sandbox_leases lease
|
|
78
|
+
WHERE lease.liveness <> 'cold'
|
|
79
|
+
OR EXISTS (
|
|
80
|
+
SELECT 1
|
|
81
|
+
FROM %1$I.sandbox_lease_holders holder
|
|
82
|
+
WHERE holder.lease_id = lease.id
|
|
83
|
+
)
|
|
84
|
+
ORDER BY lease.updated_at, lease.id
|
|
85
|
+
LIMIT 500
|
|
86
|
+
FOR UPDATE OF lease SKIP LOCKED
|
|
87
|
+
) candidate;
|
|
88
|
+
|
|
89
|
+
IF pg_catalog.cardinality(locked_ids) = 0 THEN
|
|
90
|
+
RETURN;
|
|
91
|
+
END IF;
|
|
92
|
+
|
|
93
|
+
DELETE FROM %1$I.sandbox_lease_holders holder
|
|
94
|
+
USING (
|
|
95
|
+
SELECT stale.id
|
|
96
|
+
FROM %1$I.sandbox_lease_holders stale
|
|
97
|
+
WHERE stale.lease_id = ANY(locked_ids)
|
|
98
|
+
AND stale.kind IN ('viewer', 'direct')
|
|
99
|
+
AND stale.last_heartbeat_at
|
|
100
|
+
< pg_catalog.now()
|
|
101
|
+
- pg_catalog.make_interval(secs => p_viewer_holder_ttl_ms / 1000.0)
|
|
102
|
+
FOR UPDATE OF stale SKIP LOCKED
|
|
103
|
+
) victim
|
|
104
|
+
WHERE holder.id = victim.id;
|
|
105
|
+
|
|
106
|
+
IF p_turn_holder_ttl_ms > 0 THEN
|
|
107
|
+
DELETE FROM %1$I.sandbox_lease_holders holder
|
|
108
|
+
USING (
|
|
109
|
+
SELECT stale.id
|
|
110
|
+
FROM %1$I.sandbox_lease_holders stale
|
|
111
|
+
WHERE stale.lease_id = ANY(locked_ids)
|
|
112
|
+
AND stale.kind = 'turn'
|
|
113
|
+
AND (
|
|
114
|
+
stale.last_heartbeat_at
|
|
115
|
+
< pg_catalog.now()
|
|
116
|
+
- pg_catalog.make_interval(secs => p_turn_holder_ttl_ms / 1000.0)
|
|
117
|
+
OR (
|
|
118
|
+
stale.holder_id ~* '^turn-attempt:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$'
|
|
119
|
+
AND NOT EXISTS (
|
|
120
|
+
SELECT 1
|
|
121
|
+
FROM %1$I.session_turn_attempts attempt
|
|
122
|
+
JOIN %1$I.session_turns turn
|
|
123
|
+
ON turn.account_id = attempt.account_id
|
|
124
|
+
AND turn.workspace_id = attempt.workspace_id
|
|
125
|
+
AND turn.session_id = attempt.session_id
|
|
126
|
+
AND turn.id = attempt.turn_id
|
|
127
|
+
AND turn.execution_generation = attempt.execution_generation
|
|
128
|
+
AND turn.active_attempt_id = attempt.id
|
|
129
|
+
WHERE stale.holder_id = ('turn-attempt:' || attempt.id::text)
|
|
130
|
+
AND attempt.account_id = stale.account_id
|
|
131
|
+
AND attempt.workspace_id = stale.workspace_id
|
|
132
|
+
AND attempt.session_id = stale.subject_id
|
|
133
|
+
AND attempt.state IN ('claimed', 'running')
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
FOR UPDATE OF stale SKIP LOCKED
|
|
138
|
+
) victim
|
|
139
|
+
WHERE holder.id = victim.id;
|
|
140
|
+
END IF;
|
|
141
|
+
|
|
142
|
+
IF p_interaction_holder_ttl_ms > 0 THEN
|
|
143
|
+
SELECT coalesce(pg_catalog.array_agg(candidate.id), ARRAY[]::uuid[])
|
|
144
|
+
INTO stale_interaction_ids
|
|
145
|
+
FROM (
|
|
146
|
+
SELECT stale.id
|
|
147
|
+
FROM %1$I.sandbox_lease_holders stale
|
|
148
|
+
JOIN %1$I.sandbox_leases lease ON lease.id = stale.lease_id
|
|
149
|
+
WHERE stale.lease_id = ANY(locked_ids)
|
|
150
|
+
AND stale.kind = 'interaction'
|
|
151
|
+
AND (
|
|
152
|
+
stale.last_heartbeat_at
|
|
153
|
+
< pg_catalog.now()
|
|
154
|
+
- pg_catalog.make_interval(
|
|
155
|
+
secs => p_interaction_holder_ttl_ms / 1000.0
|
|
156
|
+
)
|
|
157
|
+
OR NOT (
|
|
158
|
+
EXISTS (
|
|
159
|
+
SELECT 1
|
|
160
|
+
FROM %1$I.browser_sessions browser
|
|
161
|
+
WHERE stale.holder_id = ('browser-session:' || browser.id::text)
|
|
162
|
+
AND browser.account_id = stale.account_id
|
|
163
|
+
AND browser.workspace_id = stale.workspace_id
|
|
164
|
+
AND browser.controller_host_sandbox_group_id = lease.sandbox_group_id
|
|
165
|
+
AND browser.lifecycle IN (
|
|
166
|
+
'starting', 'active', 'suspending', 'restoring', 'ending'
|
|
167
|
+
)
|
|
168
|
+
)
|
|
169
|
+
OR EXISTS (
|
|
170
|
+
SELECT 1
|
|
171
|
+
FROM %1$I.computer_sessions computer
|
|
172
|
+
WHERE stale.holder_id = ('computer-session:' || computer.id::text)
|
|
173
|
+
AND computer.account_id = stale.account_id
|
|
174
|
+
AND computer.workspace_id = stale.workspace_id
|
|
175
|
+
AND computer.sandbox_group_id = lease.sandbox_group_id
|
|
176
|
+
AND computer.lifecycle IN (
|
|
177
|
+
'starting', 'active', 'suspending', 'restoring', 'ending'
|
|
178
|
+
)
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
FOR UPDATE OF stale SKIP LOCKED
|
|
183
|
+
) candidate;
|
|
184
|
+
|
|
185
|
+
IF pg_catalog.cardinality(stale_interaction_ids) > 0 THEN
|
|
186
|
+
WITH updated_browser AS (
|
|
187
|
+
UPDATE %1$I.browser_sessions browser
|
|
188
|
+
SET lifecycle = 'lost',
|
|
189
|
+
controller_id = null,
|
|
190
|
+
controller_generation = null,
|
|
191
|
+
placement_instance_id = null,
|
|
192
|
+
controller_heartbeat_at = null,
|
|
193
|
+
failure_code = 'controller_heartbeat_expired',
|
|
194
|
+
updated_at = pg_catalog.now()
|
|
195
|
+
FROM %1$I.sandbox_lease_holders holder
|
|
196
|
+
WHERE holder.id = ANY(stale_interaction_ids)
|
|
197
|
+
AND holder.holder_id = ('browser-session:' || browser.id::text)
|
|
198
|
+
AND holder.account_id = browser.account_id
|
|
199
|
+
AND holder.workspace_id = browser.workspace_id
|
|
200
|
+
AND browser.lifecycle IN (
|
|
201
|
+
'starting', 'active', 'suspending', 'restoring', 'ending'
|
|
202
|
+
)
|
|
203
|
+
RETURNING browser.workspace_id
|
|
204
|
+
), updated_computer AS (
|
|
205
|
+
UPDATE %1$I.computer_sessions computer
|
|
206
|
+
SET lifecycle = 'lost',
|
|
207
|
+
controller_id = null,
|
|
208
|
+
controller_generation = null,
|
|
209
|
+
placement_instance_id = null,
|
|
210
|
+
controller_heartbeat_at = null,
|
|
211
|
+
failure_code = 'controller_heartbeat_expired',
|
|
212
|
+
updated_at = pg_catalog.now()
|
|
213
|
+
FROM %1$I.sandbox_lease_holders holder
|
|
214
|
+
WHERE holder.id = ANY(stale_interaction_ids)
|
|
215
|
+
AND holder.holder_id = ('computer-session:' || computer.id::text)
|
|
216
|
+
AND holder.account_id = computer.account_id
|
|
217
|
+
AND holder.workspace_id = computer.workspace_id
|
|
218
|
+
AND computer.lifecycle IN (
|
|
219
|
+
'starting', 'active', 'suspending', 'restoring', 'ending'
|
|
220
|
+
)
|
|
221
|
+
RETURNING computer.workspace_id
|
|
222
|
+
), updated AS (
|
|
223
|
+
SELECT updated_browser.workspace_id AS interaction_workspace_id
|
|
224
|
+
FROM updated_browser
|
|
225
|
+
UNION
|
|
226
|
+
SELECT updated_computer.workspace_id AS interaction_workspace_id
|
|
227
|
+
FROM updated_computer
|
|
228
|
+
)
|
|
229
|
+
SELECT coalesce(
|
|
230
|
+
pg_catalog.array_agg(DISTINCT updated.interaction_workspace_id),
|
|
231
|
+
ARRAY[]::uuid[]
|
|
232
|
+
)
|
|
233
|
+
INTO changed_interaction_workspaces
|
|
234
|
+
FROM updated;
|
|
235
|
+
|
|
236
|
+
DELETE FROM %1$I.sandbox_lease_holders holder
|
|
237
|
+
WHERE holder.id = ANY(stale_interaction_ids);
|
|
238
|
+
|
|
239
|
+
UPDATE %1$I.workspace_interaction_revisions revision
|
|
240
|
+
SET revision = revision.revision + 1,
|
|
241
|
+
updated_at = pg_catalog.now()
|
|
242
|
+
WHERE revision.workspace_id = ANY(changed_interaction_workspaces);
|
|
243
|
+
END IF;
|
|
244
|
+
END IF;
|
|
245
|
+
|
|
246
|
+
UPDATE %1$I.sandbox_leases lease SET
|
|
247
|
+
refcount = counts.total,
|
|
248
|
+
turn_holders = counts.turns,
|
|
249
|
+
viewer_holders = counts.viewers,
|
|
250
|
+
liveness = CASE
|
|
251
|
+
WHEN lease.liveness = 'warm'
|
|
252
|
+
AND counts.total = 0
|
|
253
|
+
AND counts.turns = 0
|
|
254
|
+
AND (
|
|
255
|
+
lease.reaper_hold_id IS NULL
|
|
256
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
257
|
+
)
|
|
258
|
+
THEN 'draining' ELSE lease.liveness END,
|
|
259
|
+
expires_at = CASE
|
|
260
|
+
WHEN lease.liveness = 'warm'
|
|
261
|
+
AND counts.total = 0
|
|
262
|
+
AND counts.turns = 0
|
|
263
|
+
AND (
|
|
264
|
+
lease.reaper_hold_id IS NULL
|
|
265
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
266
|
+
)
|
|
267
|
+
THEN CASE
|
|
268
|
+
WHEN lease.rotation_requested_at IS NOT NULL
|
|
269
|
+
OR lease.archive_capture_id IS NOT NULL
|
|
270
|
+
THEN pg_catalog.now() - interval '1 millisecond'
|
|
271
|
+
ELSE pg_catalog.now()
|
|
272
|
+
+ pg_catalog.make_interval(secs => p_idle_grace_ms / 1000.0)
|
|
273
|
+
END
|
|
274
|
+
ELSE lease.expires_at END,
|
|
275
|
+
updated_at = pg_catalog.now()
|
|
276
|
+
FROM (
|
|
277
|
+
SELECT candidate.id,
|
|
278
|
+
pg_catalog.count(holder.id)::int AS total,
|
|
279
|
+
pg_catalog.count(holder.id)
|
|
280
|
+
FILTER (WHERE holder.kind = 'turn')::int AS turns,
|
|
281
|
+
pg_catalog.count(holder.id)
|
|
282
|
+
FILTER (WHERE holder.kind = 'viewer')::int AS viewers
|
|
283
|
+
FROM pg_catalog.unnest(locked_ids) candidate(id)
|
|
284
|
+
LEFT JOIN %1$I.sandbox_lease_holders holder
|
|
285
|
+
ON holder.lease_id = candidate.id
|
|
286
|
+
GROUP BY candidate.id
|
|
287
|
+
) counts
|
|
288
|
+
WHERE lease.id = counts.id;
|
|
289
|
+
|
|
290
|
+
UPDATE %1$I.sandbox_leases lease SET
|
|
291
|
+
liveness = 'cold',
|
|
292
|
+
instance_id = null,
|
|
293
|
+
lease_epoch = lease.lease_epoch + 1,
|
|
294
|
+
reaper_hold_id = null,
|
|
295
|
+
reaper_hold_until = null,
|
|
296
|
+
reaper_hold_reason = null,
|
|
297
|
+
resume_state = opengeni_private.warming_reset_resume_state_v2(
|
|
298
|
+
lease.backend,
|
|
299
|
+
lease.resume_backend_id,
|
|
300
|
+
lease.resume_state,
|
|
301
|
+
lease.workspace_generation,
|
|
302
|
+
lease.archive_generation,
|
|
303
|
+
pg_catalog.clock_timestamp()
|
|
304
|
+
),
|
|
305
|
+
resume_backend_id = CASE
|
|
306
|
+
WHEN coalesce(
|
|
307
|
+
lease.resume_state #>> '{sessionState,workspaceArchive}', ''
|
|
308
|
+
) <> ''
|
|
309
|
+
OR coalesce(
|
|
310
|
+
lease.resume_state #>> '{sessionState,workspaceArchivePrev}', ''
|
|
311
|
+
) <> ''
|
|
312
|
+
THEN coalesce(lease.resume_backend_id, lease.backend)
|
|
313
|
+
ELSE null END,
|
|
314
|
+
data_plane_url = null,
|
|
315
|
+
terminal_data_plane_url = null,
|
|
316
|
+
provider_created_at = null,
|
|
317
|
+
provider_deadline_at = null,
|
|
318
|
+
rotation_requested_at = null,
|
|
319
|
+
rotation_reason = null,
|
|
320
|
+
updated_at = pg_catalog.now()
|
|
321
|
+
WHERE lease.id = ANY(locked_ids)
|
|
322
|
+
AND lease.liveness = 'warming'
|
|
323
|
+
AND lease.expires_at < pg_catalog.now()
|
|
324
|
+
AND lease.instance_id IS NULL
|
|
325
|
+
AND (
|
|
326
|
+
lease.reaper_hold_id IS NULL
|
|
327
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
UPDATE %1$I.sandbox_leases lease SET
|
|
331
|
+
liveness = 'draining',
|
|
332
|
+
refcount = 0,
|
|
333
|
+
turn_holders = 0,
|
|
334
|
+
viewer_holders = 0,
|
|
335
|
+
data_plane_url = null,
|
|
336
|
+
terminal_data_plane_url = null,
|
|
337
|
+
lease_epoch = lease.lease_epoch + 1,
|
|
338
|
+
reaper_hold_id = null,
|
|
339
|
+
reaper_hold_until = null,
|
|
340
|
+
reaper_hold_reason = null,
|
|
341
|
+
expires_at = pg_catalog.now() - interval '1 millisecond',
|
|
342
|
+
updated_at = pg_catalog.now()
|
|
343
|
+
WHERE lease.id = ANY(locked_ids)
|
|
344
|
+
AND lease.liveness = 'warming'
|
|
345
|
+
AND lease.expires_at < pg_catalog.now()
|
|
346
|
+
AND lease.instance_id IS NOT NULL
|
|
347
|
+
AND (
|
|
348
|
+
lease.reaper_hold_id IS NULL
|
|
349
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
RETURN QUERY
|
|
353
|
+
SELECT lease.workspace_id, lease.sandbox_group_id,
|
|
354
|
+
lease.instance_id, lease.lease_epoch
|
|
355
|
+
FROM %1$I.sandbox_leases lease
|
|
356
|
+
WHERE lease.id = ANY(locked_ids)
|
|
357
|
+
AND lease.liveness = 'draining'
|
|
358
|
+
AND lease.expires_at < pg_catalog.now()
|
|
359
|
+
AND lease.refcount = 0
|
|
360
|
+
AND (
|
|
361
|
+
lease.reaper_hold_id IS NULL
|
|
362
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
363
|
+
);
|
|
364
|
+
END;
|
|
365
|
+
$function$;
|
|
366
|
+
$create$, data_schema);
|
|
367
|
+
END
|
|
368
|
+
$interaction_aware_reaper$;
|
|
369
|
+
|
|
370
|
+
REVOKE ALL ON FUNCTION opengeni_private.reap_sandbox_leases(
|
|
371
|
+
bigint, bigint, bigint, bigint
|
|
372
|
+
) FROM PUBLIC;
|
|
373
|
+
|
|
374
|
+
DO $reaper_grant$
|
|
375
|
+
BEGIN
|
|
376
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
377
|
+
GRANT EXECUTE ON FUNCTION opengeni_private.reap_sandbox_leases(
|
|
378
|
+
bigint, bigint, bigint, bigint
|
|
379
|
+
) TO opengeni_app;
|
|
380
|
+
END IF;
|
|
381
|
+
END
|
|
382
|
+
$reaper_grant$;
|
|
383
|
+
|
|
384
|
+
RESET statement_timeout;
|
|
385
|
+
RESET lock_timeout;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
-- deployment-mode: maintenance
|
|
2
|
+
-- Causally ordered SiteAuth health evidence. Browser runs remain independent;
|
|
3
|
+
-- only the newest-started terminal evidence may change the shared projection.
|
|
4
|
+
SET LOCAL lock_timeout = '5s';
|
|
5
|
+
SET LOCAL statement_timeout = '30s';
|
|
6
|
+
|
|
7
|
+
CREATE SEQUENCE "auth_runs_health_sequence_seq" AS bigint;
|
|
8
|
+
|
|
9
|
+
ALTER TABLE "auth_runs"
|
|
10
|
+
ADD COLUMN "purpose" text NOT NULL DEFAULT 'authenticate',
|
|
11
|
+
ADD COLUMN "health_sequence" bigint NOT NULL
|
|
12
|
+
DEFAULT nextval('auth_runs_health_sequence_seq'::regclass);
|
|
13
|
+
|
|
14
|
+
ALTER SEQUENCE "auth_runs_health_sequence_seq"
|
|
15
|
+
OWNED BY "auth_runs"."health_sequence";
|
|
16
|
+
|
|
17
|
+
-- The volatile default gives legacy rows values, but physical row order is not
|
|
18
|
+
-- causal. Re-rank the bounded pre-cutover history before admitting writers.
|
|
19
|
+
WITH ordered AS (
|
|
20
|
+
SELECT
|
|
21
|
+
"id",
|
|
22
|
+
row_number() OVER (ORDER BY "created_at", "id")::bigint AS "health_sequence"
|
|
23
|
+
FROM "auth_runs"
|
|
24
|
+
)
|
|
25
|
+
UPDATE "auth_runs" AS run
|
|
26
|
+
SET "health_sequence" = ordered."health_sequence"
|
|
27
|
+
FROM ordered
|
|
28
|
+
WHERE run."id" = ordered."id";
|
|
29
|
+
|
|
30
|
+
SELECT setval(
|
|
31
|
+
'auth_runs_health_sequence_seq'::regclass,
|
|
32
|
+
greatest(coalesce((SELECT max("health_sequence") FROM "auth_runs"), 0), 1),
|
|
33
|
+
coalesce((SELECT max("health_sequence") FROM "auth_runs"), 0) > 0
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
ALTER TABLE "auth_runs"
|
|
37
|
+
ADD CONSTRAINT "auth_runs_health_evidence_check" CHECK (
|
|
38
|
+
"purpose" IN ('authenticate', 'health_check', 'repair')
|
|
39
|
+
AND "health_sequence" > 0
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
ALTER TABLE "site_auth_connections"
|
|
43
|
+
ADD COLUMN "last_checked_at" timestamptz,
|
|
44
|
+
ADD COLUMN "next_check_at" timestamptz,
|
|
45
|
+
ADD COLUMN "health_sequence" bigint NOT NULL DEFAULT 0;
|
|
46
|
+
|
|
47
|
+
-- Existing successful verification is preserved. Existing terminal failures,
|
|
48
|
+
-- which the old writer failed to project, become repair evidence now.
|
|
49
|
+
WITH latest AS (
|
|
50
|
+
SELECT DISTINCT ON (run."site_auth_connection_id")
|
|
51
|
+
run."site_auth_connection_id",
|
|
52
|
+
run."id",
|
|
53
|
+
run."state",
|
|
54
|
+
run."purpose",
|
|
55
|
+
run."health_sequence",
|
|
56
|
+
run."verified_url",
|
|
57
|
+
run."failure_code",
|
|
58
|
+
run."settled_at"
|
|
59
|
+
FROM "auth_runs" AS run
|
|
60
|
+
WHERE run."state" IN ('verified', 'failed')
|
|
61
|
+
AND run."settled_at" IS NOT NULL
|
|
62
|
+
ORDER BY run."site_auth_connection_id", run."health_sequence" DESC
|
|
63
|
+
)
|
|
64
|
+
UPDATE "site_auth_connections" AS connection
|
|
65
|
+
SET
|
|
66
|
+
"verification_state" = CASE
|
|
67
|
+
WHEN latest."state" = 'verified' THEN 'verified'
|
|
68
|
+
WHEN latest."purpose" = 'repair' THEN 'failed'
|
|
69
|
+
ELSE 'needs_repair'
|
|
70
|
+
END,
|
|
71
|
+
"last_verified_at" = CASE
|
|
72
|
+
WHEN latest."state" = 'verified' THEN latest."settled_at"
|
|
73
|
+
ELSE connection."last_verified_at"
|
|
74
|
+
END,
|
|
75
|
+
"last_verified_url" = CASE
|
|
76
|
+
WHEN latest."state" = 'verified' THEN latest."verified_url"
|
|
77
|
+
ELSE connection."last_verified_url"
|
|
78
|
+
END,
|
|
79
|
+
"repair_code" = CASE
|
|
80
|
+
WHEN latest."state" = 'verified' THEN NULL
|
|
81
|
+
ELSE latest."failure_code"
|
|
82
|
+
END,
|
|
83
|
+
"last_checked_at" = latest."settled_at",
|
|
84
|
+
"health_sequence" = latest."health_sequence"
|
|
85
|
+
FROM latest
|
|
86
|
+
WHERE connection."id" = latest."site_auth_connection_id";
|
|
87
|
+
|
|
88
|
+
UPDATE "site_auth_connections"
|
|
89
|
+
SET
|
|
90
|
+
"next_check_at" = CASE
|
|
91
|
+
WHEN "status" = 'active' AND "health_policy"->>'mode' = 'maintained'
|
|
92
|
+
THEN CASE
|
|
93
|
+
WHEN "last_checked_at" IS NULL THEN now()
|
|
94
|
+
ELSE "last_checked_at"
|
|
95
|
+
+ ((("health_policy"->>'intervalSeconds')::bigint) * interval '1 second')
|
|
96
|
+
END
|
|
97
|
+
ELSE NULL
|
|
98
|
+
END,
|
|
99
|
+
"version" = "version" + 1,
|
|
100
|
+
"updated_at" = now();
|
|
101
|
+
|
|
102
|
+
ALTER TABLE "site_auth_connections"
|
|
103
|
+
ADD CONSTRAINT "site_auth_connections_health_check" CHECK (
|
|
104
|
+
(
|
|
105
|
+
(
|
|
106
|
+
"health_sequence" = 0
|
|
107
|
+
AND "last_checked_at" IS NULL
|
|
108
|
+
) OR (
|
|
109
|
+
"health_sequence" > 0
|
|
110
|
+
AND "last_checked_at" IS NOT NULL
|
|
111
|
+
)
|
|
112
|
+
) AND (
|
|
113
|
+
(
|
|
114
|
+
"status" = 'active'
|
|
115
|
+
AND "health_policy"->>'mode' = 'maintained'
|
|
116
|
+
AND "next_check_at" IS NOT NULL
|
|
117
|
+
) OR (
|
|
118
|
+
NOT ("status" = 'active' AND "health_policy"->>'mode' = 'maintained')
|
|
119
|
+
AND "next_check_at" IS NULL
|
|
120
|
+
)
|
|
121
|
+
)
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
CREATE INDEX "site_auth_connections_health_maintenance_idx"
|
|
125
|
+
ON "site_auth_connections" ("workspace_id", "next_check_at", "id");
|
|
126
|
+
|
|
127
|
+
REVOKE ALL ON SEQUENCE "auth_runs_health_sequence_seq" FROM PUBLIC;
|
|
128
|
+
DO $browser_auth_health_role_grants$
|
|
129
|
+
BEGIN
|
|
130
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
131
|
+
EXECUTE format(
|
|
132
|
+
'GRANT USAGE, SELECT ON SEQUENCE %I.auth_runs_health_sequence_seq TO opengeni_app',
|
|
133
|
+
current_schema()
|
|
134
|
+
);
|
|
135
|
+
END IF;
|
|
136
|
+
END
|
|
137
|
+
$browser_auth_health_role_grants$;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- deployment-mode: maintenance
|
|
2
|
+
-- Extend the durable interaction-operation journal with provider-managed
|
|
3
|
+
-- browser authentication. No rows are rewritten and no authority is exposed.
|
|
4
|
+
SET LOCAL lock_timeout = '5s';
|
|
5
|
+
SET LOCAL statement_timeout = '30s';
|
|
6
|
+
|
|
7
|
+
ALTER TABLE "interaction_resource_operations"
|
|
8
|
+
DROP CONSTRAINT "interaction_resource_operations_kind_check";
|
|
9
|
+
|
|
10
|
+
ALTER TABLE "interaction_resource_operations"
|
|
11
|
+
ADD CONSTRAINT "interaction_resource_operations_kind_check"
|
|
12
|
+
CHECK ("kind" IN (
|
|
13
|
+
'create',
|
|
14
|
+
'update',
|
|
15
|
+
'start',
|
|
16
|
+
'report',
|
|
17
|
+
'protected_fill',
|
|
18
|
+
'external_auth',
|
|
19
|
+
'verify',
|
|
20
|
+
'resolve',
|
|
21
|
+
'save'
|
|
22
|
+
));
|