@opengeni/db 0.28.9 → 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 (163) 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-VHBFHMPC.js → chunk-YHZXQ7HP.js} +754 -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/generated-images.d.ts +139 -0
  35. package/dist/index.d.ts +698 -111
  36. package/dist/index.js +27573 -10322
  37. package/dist/index.js.map +1 -1
  38. package/dist/insights.d.ts +51 -4
  39. package/dist/integration-bindings.d.ts +70 -0
  40. package/dist/integration-features.d.ts +99 -0
  41. package/dist/interaction-revisions.d.ts +3 -0
  42. package/dist/interaction-schema.d.ts +5372 -0
  43. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  44. package/dist/knowledge-source-sync.d.ts +274 -0
  45. package/dist/memory-governance.d.ts +2 -2
  46. package/dist/memory-slack-delivery.d.ts +101 -0
  47. package/dist/new-session-drafts.d.ts +2 -2
  48. package/dist/pack-components.d.ts +76 -0
  49. package/dist/pack-installations.d.ts +86 -0
  50. package/dist/persistence-errors.d.ts +3 -3
  51. package/dist/plugin-packages.d.ts +126 -0
  52. package/dist/preference-registry.d.ts +1 -1
  53. package/dist/provision-roles.d.ts +9 -1
  54. package/dist/provision-roles.js +1 -1
  55. package/dist/runtime-posture.d.ts +18 -6
  56. package/dist/schema.d.ts +18342 -9099
  57. package/dist/schema.js +165 -1
  58. package/dist/scoped-knowledge.d.ts +97 -1
  59. package/dist/session-control.d.ts +4 -4
  60. package/dist/session-queue-commands.d.ts +19 -11
  61. package/dist/session-realtime-context.d.ts +2 -2
  62. package/dist/session-realtime-ledger.d.ts +4 -4
  63. package/dist/session-realtime-mirror.d.ts +2 -2
  64. package/dist/session-realtime-state.d.ts +1 -1
  65. package/dist/session-realtime-terminal.d.ts +1 -1
  66. package/dist/session-realtime.d.ts +7 -7
  67. package/dist/session-tool-call-settlement.d.ts +1 -1
  68. package/dist/slack-user-link-access.d.ts +54 -0
  69. package/dist/transcription-recordings.d.ts +2 -2
  70. package/dist/turn-initiator.d.ts +2 -2
  71. package/dist/video-generation.d.ts +216 -0
  72. package/dist/video-generation.js +66 -0
  73. package/dist/video-generation.js.map +1 -0
  74. package/dist/workspace-artifacts.d.ts +1 -1
  75. package/dist/workspace-instruction-policies.d.ts +1 -1
  76. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  77. package/dist/workspace-learning-policy.d.ts +161 -0
  78. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  79. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  80. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  81. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  82. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  83. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  84. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  85. package/drizzle/0190_timeline_annotations.sql +31 -0
  86. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  87. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  88. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  89. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  90. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  91. package/drizzle/0196_rig_provider_images.sql +152 -0
  92. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  93. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  94. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  95. package/drizzle/0201_company_profile_authority.sql +849 -0
  96. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  97. package/drizzle/0203_durable_video_generation.sql +353 -0
  98. package/drizzle/0204_video_generation_funding.sql +44 -0
  99. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  100. package/drizzle/0206_browser_sessions.sql +646 -0
  101. package/drizzle/0207_browser_identities.sql +379 -0
  102. package/drizzle/0208_attached_browser_devices.sql +165 -0
  103. package/drizzle/0209_computer_sessions.sql +575 -0
  104. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  105. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  106. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  107. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  108. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  109. package/drizzle/0215_capabilities_platform.sql +980 -0
  110. package/drizzle/0216_pack_component_ownership.sql +235 -0
  111. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  112. package/package.json +18 -5
  113. package/src/attached-browser-devices.ts +371 -0
  114. package/src/attempt-tool-catalogs.ts +131 -0
  115. package/src/browser-auth.ts +1896 -0
  116. package/src/browser-identities.ts +1168 -0
  117. package/src/browser-sessions.ts +2005 -0
  118. package/src/browser-state-artifacts.ts +59 -0
  119. package/src/capability-components.ts +166 -0
  120. package/src/capability-integrations.ts +1663 -0
  121. package/src/codemode-operations.ts +674 -0
  122. package/src/company-profile-schema.ts +143 -0
  123. package/src/company-profile.ts +968 -0
  124. package/src/computer-sessions.ts +1130 -0
  125. package/src/connection-token-resolver.ts +270 -25
  126. package/src/database.ts +427 -23
  127. package/src/editable-artifact-durable-export.ts +1201 -0
  128. package/src/editable-artifact-materialization.ts +893 -0
  129. package/src/editable-artifacts-schema.ts +879 -0
  130. package/src/editable-artifacts.ts +5404 -0
  131. package/src/generated-images.ts +740 -0
  132. package/src/index.ts +5917 -1182
  133. package/src/insights.ts +160 -13
  134. package/src/integration-bindings.ts +455 -0
  135. package/src/integration-features.ts +859 -0
  136. package/src/interaction-revisions.ts +40 -0
  137. package/src/interaction-schema.ts +1303 -0
  138. package/src/knowledge-source-sync-schema.ts +192 -0
  139. package/src/knowledge-source-sync.ts +1922 -0
  140. package/src/memory-slack-delivery.ts +801 -0
  141. package/src/pack-components.ts +954 -0
  142. package/src/pack-installations.ts +929 -0
  143. package/src/persistence-errors.ts +4 -7
  144. package/src/plugin-packages.ts +1186 -0
  145. package/src/provision-roles.ts +302 -1
  146. package/src/runtime-posture-cli.ts +9 -0
  147. package/src/runtime-posture.ts +508 -5
  148. package/src/schema.ts +5117 -3119
  149. package/src/scoped-knowledge-schema.ts +1 -1
  150. package/src/scoped-knowledge.ts +655 -3
  151. package/src/session-control.ts +8 -5
  152. package/src/session-queue-commands.ts +187 -14
  153. package/src/session-realtime-context.ts +2 -2
  154. package/src/session-realtime-ledger.ts +3 -3
  155. package/src/session-realtime.ts +7 -7
  156. package/src/session-tool-call-settlement.ts +9 -0
  157. package/src/slack-user-link-access.ts +702 -0
  158. package/src/video-generation.ts +1452 -0
  159. package/src/workspace-learning-policy-schema.ts +139 -0
  160. package/src/workspace-learning-policy.ts +595 -0
  161. package/dist/chunk-P6CUHXQZ.js +0 -7248
  162. package/dist/chunk-P6CUHXQZ.js.map +0 -1
  163. package/dist/chunk-VHBFHMPC.js.map +0 -1
@@ -0,0 +1,203 @@
1
+ -- deployment-mode: rolling
2
+ -- Treat artifact creation and Office import as scope-level origin operations.
3
+
4
+ SET LOCAL lock_timeout = '5s';
5
+ SET LOCAL statement_timeout = '5min';
6
+
7
+ CREATE UNIQUE INDEX "files_scope_id_uq"
8
+ ON "files" ("account_id", "workspace_id", "id");
9
+
10
+ ALTER TABLE "editable_artifact_blob_refs"
11
+ ADD COLUMN "source_file_id" uuid,
12
+ ADD CONSTRAINT "editable_artifact_blob_refs_source_kind_chk" CHECK (
13
+ ("kind" = 'original_import') = ("source_file_id" IS NOT NULL)
14
+ ) NOT VALID,
15
+ ADD CONSTRAINT "editable_artifact_blob_refs_source_file_fk"
16
+ FOREIGN KEY ("account_id", "workspace_id", "source_file_id")
17
+ REFERENCES "files" ("account_id", "workspace_id", "id")
18
+ ON DELETE RESTRICT NOT VALID;
19
+
20
+ ALTER TABLE "editable_artifact_blob_refs"
21
+ VALIDATE CONSTRAINT "editable_artifact_blob_refs_source_kind_chk";
22
+ ALTER TABLE "editable_artifact_blob_refs"
23
+ VALIDATE CONSTRAINT "editable_artifact_blob_refs_source_file_fk";
24
+
25
+ CREATE OR REPLACE FUNCTION opengeni_private.authorize_editable_artifact_actor(
26
+ p_account_id uuid,
27
+ p_workspace_id uuid,
28
+ p_artifact_id text,
29
+ p_actor_kind text,
30
+ p_actor_subject_id text,
31
+ p_agent_session_id text,
32
+ p_agent_turn_id text,
33
+ p_agent_attempt_id text,
34
+ p_agent_generation integer,
35
+ p_service_name text,
36
+ p_permission text,
37
+ p_data_schema name DEFAULT pg_catalog.current_schema()
38
+ ) RETURNS TABLE (allowed boolean, authorization_revision bigint)
39
+ LANGUAGE plpgsql
40
+ SECURITY DEFINER
41
+ SET search_path = pg_catalog, pg_temp
42
+ AS $body$
43
+ DECLARE data_schema name;
44
+ DECLARE required_permission text;
45
+ DECLARE current_revision bigint;
46
+ DECLARE principal_allowed boolean := false;
47
+ BEGIN
48
+ IF p_account_id IS NULL OR p_workspace_id IS NULL
49
+ OR p_artifact_id IS NULL
50
+ OR p_artifact_id !~ '^[0-9a-f]{32}$' OR p_artifact_id ~ '^0+$'
51
+ OR p_actor_kind IS NULL OR p_actor_kind NOT IN ('human', 'agent', 'service')
52
+ OR p_actor_subject_id IS NULL
53
+ OR octet_length(p_actor_subject_id) NOT BETWEEN 1 AND 1024
54
+ OR p_actor_subject_id <> btrim(p_actor_subject_id)
55
+ OR p_permission IS NULL
56
+ OR p_permission NOT IN ('create', 'read', 'edit', 'import', 'export', 'manage')
57
+ OR NOT opengeni_private.editable_artifact_scope_matches_context(
58
+ p_account_id, p_workspace_id
59
+ )
60
+ THEN
61
+ RAISE EXCEPTION 'editable artifact authorization request is invalid'
62
+ USING ERRCODE = '22023';
63
+ END IF;
64
+ IF (p_actor_kind = 'human' AND (
65
+ p_agent_session_id IS NOT NULL OR p_agent_turn_id IS NOT NULL
66
+ OR p_agent_attempt_id IS NOT NULL OR p_agent_generation IS NOT NULL
67
+ OR p_service_name IS NOT NULL
68
+ )) OR (p_actor_kind = 'agent' AND (
69
+ p_agent_session_id IS NULL OR p_agent_turn_id IS NULL
70
+ OR p_agent_attempt_id IS NULL OR p_agent_generation IS NULL
71
+ OR p_agent_generation < 0 OR p_service_name IS NOT NULL
72
+ )) OR (p_actor_kind = 'service' AND (
73
+ p_agent_session_id IS NOT NULL OR p_agent_turn_id IS NOT NULL
74
+ OR p_agent_attempt_id IS NOT NULL OR p_agent_generation IS NOT NULL
75
+ OR p_service_name IS NULL
76
+ ))
77
+ THEN
78
+ RAISE EXCEPTION 'editable artifact authorization actor is invalid'
79
+ USING ERRCODE = '22023';
80
+ END IF;
81
+
82
+ data_schema := opengeni_private.resolve_editable_artifact_data_schema(p_data_schema);
83
+ required_permission := CASE
84
+ WHEN p_permission IN ('read', 'export') THEN 'artifacts:read'
85
+ ELSE 'artifacts:publish'
86
+ END;
87
+
88
+ IF p_permission IN ('create', 'import') THEN
89
+ current_revision := opengeni_private.ensure_editable_artifact_scope_authorization_head(
90
+ p_account_id, p_workspace_id, data_schema
91
+ );
92
+ ELSE
93
+ EXECUTE pg_catalog.format($query$
94
+ SELECT artifact.authorization_revision
95
+ FROM %I.editable_artifacts artifact
96
+ WHERE artifact.account_id = $1 AND artifact.workspace_id = $2
97
+ AND artifact.id = $3
98
+ $query$, data_schema)
99
+ INTO current_revision
100
+ USING p_account_id, p_workspace_id, p_artifact_id;
101
+ current_revision := coalesce(current_revision, 1);
102
+ END IF;
103
+
104
+ IF p_actor_kind = 'agent' THEN
105
+ EXECUTE pg_catalog.format($query$
106
+ SELECT true
107
+ FROM %I.sessions session
108
+ JOIN %I.session_turns turn
109
+ ON turn.account_id = session.account_id
110
+ AND turn.workspace_id = session.workspace_id
111
+ AND turn.session_id = session.id
112
+ JOIN %I.session_turn_attempts attempt
113
+ ON attempt.account_id = turn.account_id
114
+ AND attempt.workspace_id = turn.workspace_id
115
+ AND attempt.session_id = turn.session_id
116
+ AND attempt.turn_id = turn.id
117
+ WHERE session.account_id = $1 AND session.workspace_id = $2
118
+ AND session.id::text = $3
119
+ AND turn.id::text = $4
120
+ AND attempt.id::text = $5
121
+ AND session.active_turn_id = turn.id
122
+ AND turn.active_attempt_id = attempt.id
123
+ AND turn.execution_generation = $6
124
+ AND attempt.execution_generation = $6
125
+ AND turn.status IN ('running', 'requires_action', 'recovering', 'waiting_capacity')
126
+ AND attempt.state IN ('claimed', 'running')
127
+ AND attempt.closed_at IS NULL AND attempt.quiesced_at IS NULL
128
+ AND NOT EXISTS (
129
+ SELECT 1
130
+ FROM %I.session_attempt_interruptions interruption
131
+ WHERE interruption.account_id = session.account_id
132
+ AND interruption.workspace_id = session.workspace_id
133
+ AND interruption.session_id = session.id
134
+ AND interruption.attempt_id = attempt.id
135
+ AND interruption.state IN ('pending', 'delivered', 'acknowledged')
136
+ )
137
+ AND (
138
+ session.first_party_mcp_permissions IS NULL
139
+ OR session.first_party_mcp_permissions ? $7
140
+ OR session.first_party_mcp_permissions ? 'workspace:admin'
141
+ )
142
+ LIMIT 1
143
+ FOR SHARE OF session, turn, attempt
144
+ $query$, data_schema, data_schema, data_schema, data_schema)
145
+ INTO principal_allowed
146
+ USING p_account_id, p_workspace_id, p_agent_session_id,
147
+ p_agent_turn_id, p_agent_attempt_id, p_agent_generation,
148
+ required_permission;
149
+ ELSIF p_actor_kind = 'service'
150
+ AND p_service_name = 'api_key'
151
+ AND p_actor_subject_id ~ '^api_key:[0-9a-fA-F-]{36}$'
152
+ THEN
153
+ EXECUTE pg_catalog.format($query$
154
+ SELECT true
155
+ FROM %I.api_keys api_key
156
+ WHERE api_key.account_id = $1 AND api_key.workspace_id = $2
157
+ AND api_key.id::text = substring($3 from 9)
158
+ AND api_key.revoked_at IS NULL
159
+ AND (api_key.expires_at IS NULL OR api_key.expires_at > pg_catalog.clock_timestamp())
160
+ AND (api_key.permissions ? $4 OR api_key.permissions ? 'workspace:admin')
161
+ LIMIT 1
162
+ FOR SHARE OF api_key
163
+ $query$, data_schema)
164
+ INTO principal_allowed
165
+ USING p_account_id, p_workspace_id, p_actor_subject_id, required_permission;
166
+ ELSIF p_actor_kind = 'human'
167
+ OR (p_actor_kind = 'service' AND p_service_name = 'configured_key')
168
+ THEN
169
+ EXECUTE pg_catalog.format($query$
170
+ SELECT true
171
+ FROM %I.workspace_memberships membership
172
+ WHERE membership.account_id = $1 AND membership.workspace_id = $2
173
+ AND membership.subject_id = $3
174
+ AND (membership.permissions ? $4 OR membership.permissions ? 'workspace:admin')
175
+ LIMIT 1
176
+ FOR SHARE OF membership
177
+ $query$, data_schema)
178
+ INTO principal_allowed
179
+ USING p_account_id, p_workspace_id, p_actor_subject_id, required_permission;
180
+ ELSE
181
+ principal_allowed := false;
182
+ END IF;
183
+
184
+ RETURN QUERY SELECT coalesce(principal_allowed, false), current_revision;
185
+ END;
186
+ $body$;
187
+
188
+ REVOKE ALL ON FUNCTION opengeni_private.authorize_editable_artifact_actor(
189
+ uuid, uuid, text, text, text, text, text, text, integer, text, text, name
190
+ ) FROM PUBLIC;
191
+
192
+ DO $runtime_authorization_grant$
193
+ BEGIN
194
+ IF EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = 'opengeni_app') THEN
195
+ GRANT EXECUTE ON FUNCTION opengeni_private.authorize_editable_artifact_actor(
196
+ uuid, uuid, text, text, text, text, text, text, integer, text, text, name
197
+ ) TO opengeni_app;
198
+ END IF;
199
+ END;
200
+ $runtime_authorization_grant$;
201
+
202
+ RESET statement_timeout;
203
+ RESET lock_timeout;
@@ -0,0 +1,152 @@
1
+ -- deployment-mode: rolling
2
+ -- Exact rig-version definitions remain immutable. This additive operational
3
+ -- metadata records build-once provider image status and immutable identities.
4
+
5
+ ALTER TABLE rig_versions
6
+ ADD COLUMN provider_images jsonb NOT NULL DEFAULT '{}'::jsonb;
7
+
8
+ ALTER TABLE rig_versions
9
+ ADD CONSTRAINT rig_versions_provider_images_object_chk
10
+ CHECK (jsonb_typeof(provider_images) = 'object');
11
+
12
+ -- Reuse the existing provider-artifact ledger and global GC. A rig-version
13
+ -- reference protects the exact image for that immutable version. A verified
14
+ -- change protects it only while its base remains active/promotable; rejected,
15
+ -- failed, abandoned-after-supersession, and deleted targets fall back to the
16
+ -- ordinary candidate/current collection path.
17
+ DO $rig_provider_image_checkpoint_gc$
18
+ DECLARE data_schema text := current_schema();
19
+ BEGIN
20
+ EXECUTE format($create$
21
+ CREATE OR REPLACE FUNCTION opengeni_private.claim_sandbox_checkpoint_artifacts(
22
+ p_claim_id uuid,
23
+ p_limit integer,
24
+ p_claim_ttl_ms bigint
25
+ )
26
+ RETURNS TABLE (
27
+ id uuid,
28
+ provider_backend text,
29
+ provider_binding_key text,
30
+ provider_binding jsonb,
31
+ object_kind text,
32
+ object_id text,
33
+ delete_attempts integer
34
+ )
35
+ LANGUAGE plpgsql
36
+ SECURITY DEFINER
37
+ SET search_path = pg_catalog
38
+ AS $function$
39
+ BEGIN
40
+ IF p_claim_id IS NULL THEN
41
+ RAISE EXCEPTION 'checkpoint artifact claim id is required'
42
+ USING ERRCODE = '22023';
43
+ END IF;
44
+ IF p_limit IS NULL OR p_limit < 1 OR p_limit > 500 THEN
45
+ RAISE EXCEPTION 'checkpoint artifact claim limit must be between 1 and 500'
46
+ USING ERRCODE = '22023';
47
+ END IF;
48
+ IF p_claim_ttl_ms IS NULL
49
+ OR p_claim_ttl_ms < 1000
50
+ OR p_claim_ttl_ms > 3600000
51
+ THEN
52
+ RAISE EXCEPTION 'checkpoint artifact claim TTL must be between 1s and 1h'
53
+ USING ERRCODE = '22023';
54
+ END IF;
55
+
56
+ PERFORM pg_catalog.set_config('opengeni.sandbox_recovery_protocol_v2', '1', true);
57
+
58
+ WITH stale_claims AS MATERIALIZED (
59
+ SELECT artifact.id
60
+ FROM %1$I.sandbox_checkpoint_artifacts artifact
61
+ WHERE artifact.state = 'deleting'
62
+ AND artifact.delete_claimed_at
63
+ < pg_catalog.now()
64
+ - pg_catalog.make_interval(secs => p_claim_ttl_ms / 1000.0)
65
+ ORDER BY artifact.delete_claimed_at, artifact.id
66
+ FOR UPDATE SKIP LOCKED
67
+ LIMIT p_limit
68
+ )
69
+ UPDATE %1$I.sandbox_checkpoint_artifacts artifact SET
70
+ state = 'delete_failed',
71
+ delete_after = pg_catalog.now(),
72
+ delete_claim_id = null,
73
+ delete_claimed_at = null,
74
+ last_delete_error = coalesce(
75
+ last_delete_error, 'stale delete claim recovered'
76
+ ),
77
+ updated_at = pg_catalog.now()
78
+ FROM stale_claims
79
+ WHERE artifact.id = stale_claims.id;
80
+
81
+ RETURN QUERY
82
+ WITH candidates AS (
83
+ SELECT artifact.id
84
+ FROM %1$I.sandbox_checkpoint_artifacts artifact
85
+ WHERE (
86
+ (
87
+ artifact.state = 'candidate'
88
+ AND artifact.created_at < pg_catalog.now() - interval '15 minutes'
89
+ )
90
+ OR (
91
+ artifact.state IN ('current', 'previous')
92
+ AND artifact.created_at < pg_catalog.now() - interval '15 minutes'
93
+ )
94
+ OR (
95
+ artifact.state IN ('delete_pending', 'delete_failed')
96
+ AND coalesce(artifact.delete_after, artifact.created_at)
97
+ <= pg_catalog.now()
98
+ )
99
+ )
100
+ AND NOT EXISTS (
101
+ SELECT 1 FROM %1$I.sandbox_leases lease
102
+ WHERE lease.current_checkpoint_artifact_id = artifact.id
103
+ OR lease.previous_checkpoint_artifact_id = artifact.id
104
+ OR (
105
+ artifact.provenance = 'native_capture'
106
+ AND lease.id = artifact.source_lease_id
107
+ AND lease.lease_epoch = artifact.source_lease_epoch
108
+ AND lease.instance_id = artifact.source_instance_id
109
+ AND lease.backend = artifact.provider_backend
110
+ AND lease.archive_capture_id IS NOT NULL
111
+ AND lease.archive_capture_generation
112
+ = artifact.source_workspace_generation
113
+ )
114
+ )
115
+ AND NOT EXISTS (
116
+ SELECT 1
117
+ FROM %1$I.rig_versions version
118
+ CROSS JOIN LATERAL pg_catalog.jsonb_each(version.provider_images) provider_image
119
+ WHERE provider_image.value ->> 'artifactId' = artifact.id::text
120
+ AND provider_image.value ->> 'status' = 'ready'
121
+ )
122
+ AND NOT EXISTS (
123
+ SELECT 1
124
+ FROM %1$I.rig_changes change
125
+ JOIN %1$I.rig_versions base
126
+ ON base.id = change.base_version_id
127
+ AND base.workspace_id = change.workspace_id
128
+ AND base.active = true
129
+ WHERE change.status IN ('verifying', 'proposed')
130
+ AND change.verification #>> '{providerImage,artifactId}' = artifact.id::text
131
+ AND change.verification #>> '{providerImage,status}' = 'ready'
132
+ )
133
+ ORDER BY coalesce(artifact.delete_after, artifact.created_at), artifact.id
134
+ FOR UPDATE SKIP LOCKED
135
+ LIMIT p_limit
136
+ )
137
+ UPDATE %1$I.sandbox_checkpoint_artifacts artifact SET
138
+ state = 'deleting',
139
+ delete_attempts = artifact.delete_attempts + 1,
140
+ delete_claim_id = p_claim_id,
141
+ delete_claimed_at = pg_catalog.now(),
142
+ updated_at = pg_catalog.now()
143
+ FROM candidates
144
+ WHERE artifact.id = candidates.id
145
+ RETURNING artifact.id, artifact.provider_backend, artifact.provider_binding_key,
146
+ artifact.provider_binding, artifact.object_kind, artifact.object_id,
147
+ artifact.delete_attempts;
148
+ END;
149
+ $function$;
150
+ $create$, data_schema);
151
+ END
152
+ $rig_provider_image_checkpoint_gc$;