@opengeni/db 5.0.1 → 6.0.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/automations.d.ts +0 -2
- package/dist/canonical-human-identities.d.ts +4 -0
- package/dist/canonical-human-identities.js +3 -3
- package/dist/capability-components.d.ts +5 -13
- package/dist/capability-integrations.d.ts +23 -8
- package/dist/capability-reconciliation.d.ts +5 -0
- package/dist/capability-reconciliation.js +21 -0
- package/dist/capability-reconciliation.js.map +1 -0
- package/dist/{chunk-6T2GGYWE.js → chunk-4UJCXBR2.js} +4 -5800
- package/dist/chunk-4UJCXBR2.js.map +1 -0
- package/dist/{chunk-MWMXWHJD.js → chunk-7JCDSMX2.js} +2 -2
- package/dist/chunk-AJA2ZIUW.js +219 -0
- package/dist/chunk-AJA2ZIUW.js.map +1 -0
- package/dist/chunk-CDAT6EKW.js +247 -0
- package/dist/chunk-CDAT6EKW.js.map +1 -0
- package/dist/{chunk-DPONPYJD.js → chunk-CJI6G254.js} +70 -18
- package/dist/chunk-CJI6G254.js.map +1 -0
- package/dist/chunk-G32NVMRJ.js +276 -0
- package/dist/chunk-G32NVMRJ.js.map +1 -0
- package/dist/chunk-GABXCG3N.js +5811 -0
- package/dist/chunk-GABXCG3N.js.map +1 -0
- package/dist/{chunk-ERKVSPDX.js → chunk-LVY33EWL.js} +3 -3
- package/dist/{chunk-45CP2YKY.js → chunk-MAMBI2HR.js} +9 -3
- package/dist/{chunk-45CP2YKY.js.map → chunk-MAMBI2HR.js.map} +1 -1
- package/dist/{chunk-F73UKJY6.js → chunk-MN5PZMEK.js} +91 -108
- package/dist/chunk-MN5PZMEK.js.map +1 -0
- package/dist/chunk-PJI4MUZ7.js +131 -0
- package/dist/chunk-PJI4MUZ7.js.map +1 -0
- package/dist/{chunk-T6BWIGWJ.js → chunk-RIYHP2WU.js} +2 -2
- package/dist/{chunk-7HMK3B45.js → chunk-RL2MUXM3.js} +16 -7
- package/dist/chunk-RL2MUXM3.js.map +1 -0
- package/dist/{chunk-HQDVI2DB.js → chunk-SYKHLPTK.js} +4 -3
- package/dist/{chunk-HQDVI2DB.js.map → chunk-SYKHLPTK.js.map} +1 -1
- package/dist/{chunk-T6YLHJLS.js → chunk-XIXVVBW2.js} +198 -51
- package/dist/chunk-XIXVVBW2.js.map +1 -0
- package/dist/chunk-ZPJ6V2VG.js +156 -0
- package/dist/chunk-ZPJ6V2VG.js.map +1 -0
- package/dist/codex-capacity-recovery.d.ts +12 -0
- package/dist/codex-failure-eligibility.d.ts +9 -0
- package/dist/company-profile-schema.d.ts +4 -2
- package/dist/connect-attempts.d.ts +15 -0
- package/dist/connect-attempts.js +25 -0
- package/dist/connect-attempts.js.map +1 -0
- package/dist/connection-authority.d.ts +7 -63
- package/dist/connection-refresh-lock.d.ts +4 -0
- package/dist/connection-token-resolver.d.ts +8 -43
- package/dist/database-timing.d.ts +10 -0
- package/dist/database.d.ts +4 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.d.ts +9 -0
- package/dist/editable-artifacts.js +7 -5
- package/dist/index.d.ts +447 -78
- package/dist/index.js +12705 -12872
- package/dist/index.js.map +1 -1
- package/dist/insights-usage-bundle.d.ts +3 -0
- package/dist/integration-bindings.d.ts +1 -1
- package/dist/integration-facets.d.ts +18 -1
- package/dist/knowledge-entries-schema.d.ts +2 -0
- package/dist/knowledge-entries.d.ts +1 -0
- package/dist/knowledge-indexing.d.ts +1 -0
- package/dist/live-session-attempt.d.ts +35 -137
- package/dist/managed-auth-session-sets.js +3 -3
- package/dist/mcp-account-bindings.d.ts +4 -0
- package/dist/mcp-oauth.d.ts +11 -0
- package/dist/mcp-operations.js +2 -2
- package/dist/migrate.js +1 -1
- package/dist/organization-integration-policy.d.ts +51 -0
- package/dist/organization-integration-policy.js +18 -0
- package/dist/organization-integration-policy.js.map +1 -0
- package/dist/organization-usage.d.ts +20 -0
- package/dist/plugin-packages.d.ts +9 -12
- package/dist/pr-review.d.ts +0 -11
- package/dist/preference-registry-schema.d.ts +17 -0
- package/dist/provision-roles.js +1 -1
- package/dist/retained-provider-commands.d.ts +124 -6
- package/dist/retained-provider-commands.js +29 -97
- package/dist/retained-provider-commands.js.map +1 -1
- package/dist/retired-session-create-metadata.d.ts +4 -0
- package/dist/runtime-posture.d.ts +7 -5
- package/dist/schema.d.ts +876 -656
- package/dist/schema.js +5 -7
- package/dist/session-admission-block.d.ts +32 -0
- package/dist/session-attempt-writers.d.ts +4 -0
- package/dist/session-background-commands.js +5 -4
- package/dist/session-command-output.js +8 -126
- package/dist/session-command-output.js.map +1 -1
- package/dist/session-control.d.ts +5 -1
- package/dist/session-event-slices.d.ts +10 -0
- package/dist/session-event-slices.js +8 -222
- package/dist/session-event-slices.js.map +1 -1
- package/dist/session-file-attachments.d.ts +28 -0
- package/dist/session-goal-reports.d.ts +43 -0
- package/dist/session-mcp-approval.d.ts +4 -0
- package/dist/session-mcp-credential-rotation.js +5 -4
- package/dist/session-mcp-credential-rotation.js.map +1 -1
- package/dist/session-message-search.d.ts +22 -0
- package/dist/session-queue-commands.d.ts +2 -6
- package/dist/session-retry.d.ts +36 -0
- package/dist/session-tenancy.js +3 -3
- package/dist/skill-source-release-impact.d.ts +18 -0
- package/dist/skill-source-release.d.ts +9 -0
- package/dist/skills.d.ts +7 -1
- package/dist/user-resource-authority.d.ts +0 -8
- package/dist/video-generation.js +3 -3
- package/dist/workspace-tool-defaults.js +5 -4
- package/dist/workspace-tool-defaults.js.map +1 -1
- package/drizzle/0468_knowledge_relationship_projection.sql +30 -0
- package/drizzle/0469_knowledge_source_discovery.sql +85 -0
- package/drizzle/0470_organization_integration_policy.sql +151 -0
- package/drizzle/0471_usage_events_account_recent_index.sql +4 -0
- package/drizzle/0472_usage_events_workspace_recent_index.sql +4 -0
- package/drizzle/0473_organization_usage_analytical_capability.sql +237 -0
- package/drizzle/0474_goal_report_requirements.sql +156 -0
- package/drizzle/0475_session_event_history_statistics.sql +15 -0
- package/drizzle/0476_session_event_history_policy_planning.sql +29 -0
- package/drizzle/0477_managed_sign_in_methods.sql +303 -0
- package/drizzle/0478_sender_owned_connections.sql +2772 -0
- package/drizzle/0479_connection_create_idempotency.sql +16 -0
- package/drizzle/0480_private_session_organization_key_administration.sql +154 -0
- package/drizzle/0481_personal_connection_visibility_cleanup.sql +45 -0
- package/drizzle/0482_remove_packs.sql +417 -0
- package/drizzle/0483_preclaim_admission_block.sql +85 -0
- package/drizzle/0484_insights_usage_projection.sql +211 -0
- package/drizzle/0485_inherited_mcp_approval_policies.sql +6 -0
- package/drizzle/0486_reasoning_configuration_message_forks.sql +35 -0
- package/drizzle/0487_skill_catalog_message_forks.sql +26 -0
- package/drizzle/0488_permanent_skill_removal.sql +207 -0
- package/drizzle/0489_modal_command_byte_offsets.sql +17 -0
- package/drizzle/0490_periodic_capture_attempt_cadence.sql +6 -0
- package/drizzle/0491_warm_capture_holder_reclamation.sql +57 -0
- package/drizzle/0492_codex_accepted_source_authority.sql +249 -0
- package/drizzle/0493_stopping_command_error_containment.sql +58 -0
- package/drizzle/0494_mcp_account_bindings.sql +334 -0
- package/drizzle/0495_consented_sandbox_recovery.sql +220 -0
- package/drizzle/0496_supervised_command_settlement.sql +386 -0
- package/drizzle/0497_modal_inventory_owner_read_capability.sql +112 -0
- package/drizzle/0498_enrollment_membership_fence.sql +87 -0
- package/drizzle/0499_session_attachment_access.sql +224 -0
- package/drizzle/0500_session_execution_epoch.sql +37 -0
- package/drizzle/0501_session_sharing_execution.sql +591 -0
- package/drizzle/0502_active_message_boundary_forks.sql +30 -0
- package/package.json +17 -5
- package/src/automations.ts +17 -73
- package/src/canonical-human-identities.ts +17 -5
- package/src/capability-components.ts +7 -24
- package/src/capability-integrations.ts +301 -21
- package/src/capability-reconciliation.ts +19 -0
- package/src/codex-capacity-recovery.ts +47 -0
- package/src/codex-failure-eligibility.ts +93 -0
- package/src/connect-attempts.ts +49 -18
- package/src/connection-authority.ts +12 -158
- package/src/connection-refresh-lock.ts +22 -0
- package/src/connection-token-resolver.ts +58 -530
- package/src/database-timing.ts +43 -0
- package/src/database.ts +61 -26
- package/src/editable-artifacts.ts +1 -1
- package/src/index.ts +3578 -1273
- package/src/insights-model-bundle.ts +19 -7
- package/src/insights-usage-bundle.ts +16 -19
- package/src/integration-bindings.ts +2 -7
- package/src/integration-facets.ts +73 -6
- package/src/knowledge-entries.ts +8 -1
- package/src/live-session-attempt.ts +0 -22
- package/src/mcp-account-bindings.ts +12 -0
- package/src/mcp-oauth.ts +26 -0
- package/src/organization-integration-policy.ts +235 -0
- package/src/organization-usage.ts +83 -0
- package/src/plugin-packages.ts +226 -42
- package/src/pr-review.ts +7 -69
- package/src/preference-registry-schema.ts +1 -0
- package/src/provision-roles.ts +50 -37
- package/src/retained-provider-commands.ts +286 -9
- package/src/retired-session-create-metadata.ts +16 -0
- package/src/runtime-posture.ts +217 -13
- package/src/schema.ts +104 -120
- package/src/session-admission-block.ts +29 -0
- package/src/session-attempt-writers.ts +48 -0
- package/src/session-control.ts +21 -5
- package/src/session-event-slices.ts +76 -26
- package/src/session-file-attachments.ts +66 -0
- package/src/session-goal-reports.ts +255 -0
- package/src/session-mcp-approval.ts +30 -0
- package/src/session-message-search.ts +348 -0
- package/src/session-queue-commands.ts +60 -36
- package/src/session-retry.ts +319 -0
- package/src/skill-config-migration.ts +11 -2
- package/src/skill-source-release-impact.ts +33 -0
- package/src/skill-source-release.ts +67 -26
- package/src/skills.ts +44 -6
- package/src/user-resource-authority.ts +0 -56
- package/dist/chunk-6T2GGYWE.js.map +0 -1
- package/dist/chunk-7HMK3B45.js.map +0 -1
- package/dist/chunk-DPONPYJD.js.map +0 -1
- package/dist/chunk-F73UKJY6.js.map +0 -1
- package/dist/chunk-T6YLHJLS.js.map +0 -1
- package/dist/host-mcp-binding-match.d.ts +0 -5
- package/dist/host-mcp-bindings.d.ts +0 -79
- package/dist/host-mcp-resolvers.d.ts +0 -47
- package/dist/host-mcp-task-authority.d.ts +0 -43
- package/dist/host-selection-identity.d.ts +0 -6
- package/dist/pack-components.d.ts +0 -83
- package/dist/pack-installations.d.ts +0 -86
- package/src/host-mcp-binding-match.ts +0 -34
- package/src/host-mcp-bindings.ts +0 -777
- package/src/host-mcp-resolvers.ts +0 -266
- package/src/host-mcp-task-authority.ts +0 -384
- package/src/host-selection-identity.ts +0 -29
- package/src/pack-components.ts +0 -980
- package/src/pack-installations.ts +0 -950
- /package/dist/{chunk-MWMXWHJD.js.map → chunk-7JCDSMX2.js.map} +0 -0
- /package/dist/{chunk-ERKVSPDX.js.map → chunk-LVY33EWL.js.map} +0 -0
- /package/dist/{chunk-T6BWIGWJ.js.map → chunk-RIYHP2WU.js.map} +0 -0
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
-- deployment-mode: maintenance
|
|
2
|
+
-- Sharing changes audience, not accepted execution authority. Privatization
|
|
3
|
+
-- and actual authority revocation still invalidate older execution receipts.
|
|
4
|
+
SET LOCAL lock_timeout = '5s';
|
|
5
|
+
SET LOCAL statement_timeout = '5min';
|
|
6
|
+
DO $sharing_execution$
|
|
7
|
+
DECLARE target regprocedure; source text; before_text text; after_text text; patch jsonb; change jsonb;
|
|
8
|
+
BEGIN
|
|
9
|
+
FOR patch IN SELECT jsonb_build_object('signature', value->>'signature', 'patches', jsonb_agg(value ORDER BY ordinal)) FROM jsonb_array_elements($patches$[
|
|
10
|
+
{
|
|
11
|
+
"signature": "admit_session_attempt_personal_resources()",
|
|
12
|
+
"before": "NEW.authority_visibility IS DISTINCT FROM session_row.visibility\n OR NEW.authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
13
|
+
"after": "NOT (NEW.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"signature": "admit_session_attempt_personal_machine()",
|
|
17
|
+
"before": "NEW.authority_visibility IS DISTINCT FROM session_row.visibility\n OR NEW.authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
18
|
+
"after": "NOT (NEW.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"signature": "authorize_session_attempt_personal_machine(uuid,uuid,uuid,uuid,uuid,integer,uuid)",
|
|
22
|
+
"before": "attempt_row.authority_visibility IS DISTINCT FROM session_row.visibility\n OR attempt_row.authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
23
|
+
"after": "NOT (attempt_row.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"signature": "prepare_session_attempt_personal_document_reads(uuid,uuid,uuid,uuid)",
|
|
27
|
+
"before": "attempt_row.authority_visibility IS DISTINCT FROM session_row.visibility\n OR attempt_row.authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
28
|
+
"after": "NOT (attempt_row.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"signature": "admit_session_attempt_personal_resources_v1()",
|
|
32
|
+
"before": "NEW.authority_visibility IS DISTINCT FROM session_row.visibility\n OR NEW.authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
33
|
+
"after": "NOT (NEW.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"signature": "admit_session_attempt_personal_resources_v1()",
|
|
37
|
+
"before": "receipt_row.session_visibility IS DISTINCT FROM session_row.visibility\n OR receipt_row.session_authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
38
|
+
"after": "NOT (receipt_row.session_authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"signature": "admit_session_attempt_personal_machine_v1()",
|
|
42
|
+
"before": "snapshot_row.session_visibility IS DISTINCT FROM session_row.visibility\n OR snapshot_row.session_authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
43
|
+
"after": "NOT (snapshot_row.session_authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"signature": "assert_scoped_variable_set_attempt(uuid,uuid,uuid,uuid,uuid,integer)",
|
|
47
|
+
"before": "attempt.authority_epoch = session_value.authority_epoch\n AND attempt.authority_visibility = session_value.visibility",
|
|
48
|
+
"after": "(attempt.authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"signature": "assert_scoped_variable_set_materialization_attempt(uuid,uuid,uuid,uuid,uuid,integer)",
|
|
52
|
+
"before": "attempt.authority_epoch = session_value.authority_epoch\n AND attempt.authority_visibility = session_value.visibility",
|
|
53
|
+
"after": "(attempt.authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"signature": "bind_scheduled_task_run_connection_authorities(uuid,uuid,uuid,uuid)",
|
|
57
|
+
"before": "snapshot_row.session_visibility IS DISTINCT FROM session_row.visibility\n OR snapshot_row.session_authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
58
|
+
"after": "NOT (snapshot_row.session_authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"signature": "resolve_accepted_connection_use(uuid,uuid,uuid,uuid,uuid,integer,uuid,text,text,uuid,text,text,text,text)",
|
|
62
|
+
"before": "session_row.visibility IS DISTINCT FROM snapshot.session_visibility\n OR session_row.authority_epoch IS DISTINCT FROM snapshot.session_authority_epoch",
|
|
63
|
+
"after": "NOT (snapshot.session_authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"signature": "resolve_accepted_connection_use(uuid,uuid,uuid,uuid,uuid,integer,uuid,text,text,uuid,text,text,text,text)",
|
|
67
|
+
"before": "attempt.authority_visibility = session_row.visibility\n AND attempt.authority_epoch = session_row.authority_epoch",
|
|
68
|
+
"after": "(attempt.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"signature": "resolve_session_attempt_personal_document_reads(uuid,uuid,uuid,uuid)",
|
|
72
|
+
"before": "session_value.visibility = snapshot.session_visibility\n AND session_value.authority_epoch = snapshot.session_authority_epoch",
|
|
73
|
+
"after": "(snapshot.session_authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"signature": "resolve_session_attempt_personal_resources(uuid,uuid,uuid)",
|
|
77
|
+
"before": "session_value.visibility = admission_row.session_visibility\n AND session_value.authority_epoch = admission_row.session_authority_epoch",
|
|
78
|
+
"after": "(admission_row.session_authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"signature": "resolve_session_attempt_personal_resources_legacy_0305(uuid,uuid,uuid)",
|
|
82
|
+
"before": "session_value.visibility = snapshot.session_visibility\n AND session_value.authority_epoch = snapshot.session_authority_epoch",
|
|
83
|
+
"after": "(snapshot.session_authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"signature": "opengeni_private.read_session_file_attachments(uuid,uuid,uuid,integer,uuid[],jsonb)",
|
|
87
|
+
"before": "a.authority_epoch=caller_row.authority_epoch AND a.authority_visibility=caller_row.visibility",
|
|
88
|
+
"after": "(a.authority_epoch BETWEEN caller_row.execution_authority_epoch AND caller_row.authority_epoch)"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"signature": "opengeni_private.mcp_operation_command_scoped(jsonb,text,jsonb)",
|
|
92
|
+
"before": "a.authority_epoch=s.authority_epoch AND a.authority_visibility=s.visibility",
|
|
93
|
+
"after": "(a.authority_epoch BETWEEN s.execution_authority_epoch AND s.authority_epoch)"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"signature": "admit_scheduled_task_run_personal_resources()",
|
|
97
|
+
"before": "session_value.visibility = authority_row.session_visibility\n AND session_value.authority_epoch = authority_row.session_authority_epoch",
|
|
98
|
+
"after": "(authority_row.session_authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"signature": "materialize_scheduled_task_reusable_session_from_run(uuid,uuid,uuid,uuid,uuid,bigint,text)",
|
|
102
|
+
"before": "snapshot_row.session_visibility IS DISTINCT FROM session_row.visibility\n OR snapshot_row.session_authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
103
|
+
"after": "NOT (snapshot_row.session_authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"signature": "materialize_scheduled_task_reusable_session_from_run(uuid,uuid,uuid,uuid,uuid,bigint,text)",
|
|
107
|
+
"before": "snapshot_row.session_visibility IS DISTINCT FROM session_row.visibility\n OR snapshot_row.session_authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
108
|
+
"after": "NOT (snapshot_row.session_authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"signature": "materialize_scheduled_task_reusable_session_from_run(uuid,uuid,uuid,uuid,uuid,bigint,text)",
|
|
112
|
+
"before": "snapshot_row.session_visibility IS DISTINCT FROM session_row.visibility\n OR snapshot_row.session_authority_epoch IS DISTINCT FROM session_row.authority_epoch",
|
|
113
|
+
"after": "NOT (snapshot_row.session_authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"signature": "resolve_session_attempt_personal_resources(uuid,uuid,uuid)",
|
|
117
|
+
"before": "attempt.authority_visibility = admission_row.session_visibility\n AND attempt.authority_epoch = admission_row.session_authority_epoch",
|
|
118
|
+
"after": "(attempt.authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"signature": "resolve_session_attempt_personal_resources_legacy_0305(uuid,uuid,uuid)",
|
|
122
|
+
"before": "attempt.authority_visibility = snapshot.session_visibility\n AND attempt.authority_epoch = snapshot.session_authority_epoch",
|
|
123
|
+
"after": "(attempt.authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"signature": "admit_scheduled_agent_run_execution()",
|
|
127
|
+
"before": "target_snapshot ->> 'visibility' IS DISTINCT FROM target_row.visibility\n OR (target_snapshot ->> 'authorityEpoch')::integer\n IS DISTINCT FROM target_row.authority_epoch",
|
|
128
|
+
"after": "NOT ((target_snapshot ->> 'authorityEpoch')::integer BETWEEN target_row.execution_authority_epoch AND target_row.authority_epoch)"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"signature": "admit_session_attempt_personal_resources()",
|
|
132
|
+
"before": "grant_value.context = session_row.visibility",
|
|
133
|
+
"after": "(grant_value.context = session_row.visibility OR (\n grant_value.context = 'user_private' AND session_row.visibility = 'workspace_shared'\n AND grant_value.mode IN ('once','session') AND grant_value.session_id = session_row.id\n AND (grant_value.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)))"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"signature": "admit_session_attempt_personal_resources()",
|
|
137
|
+
"before": "grant_value.authority_epoch = session_row.authority_epoch",
|
|
138
|
+
"after": "(grant_value.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"signature": "admit_session_attempt_personal_machine()",
|
|
142
|
+
"before": "grant_value.context = session_row.visibility",
|
|
143
|
+
"after": "(grant_value.context = session_row.visibility OR (\n grant_value.context = 'user_private' AND session_row.visibility = 'workspace_shared'\n AND grant_value.mode IN ('once','session') AND grant_value.session_id = session_row.id\n AND (grant_value.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)))"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"signature": "admit_session_attempt_personal_machine()",
|
|
147
|
+
"before": "grant_value.authority_epoch = session_row.authority_epoch",
|
|
148
|
+
"after": "(grant_value.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"signature": "authorize_session_attempt_personal_machine(uuid,uuid,uuid,uuid,uuid,integer,uuid)",
|
|
152
|
+
"before": "grant_value.context = session_row.visibility",
|
|
153
|
+
"after": "(grant_value.context = session_row.visibility OR (\n grant_value.context = 'user_private' AND session_row.visibility = 'workspace_shared'\n AND grant_value.mode IN ('once','session') AND grant_value.session_id = session_row.id\n AND (grant_value.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)))"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"signature": "authorize_session_attempt_personal_machine(uuid,uuid,uuid,uuid,uuid,integer,uuid)",
|
|
157
|
+
"before": "grant_value.authority_epoch = session_row.authority_epoch",
|
|
158
|
+
"after": "(grant_value.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"signature": "prepare_session_attempt_personal_document_reads(uuid,uuid,uuid,uuid)",
|
|
162
|
+
"before": "grant_value.context = session_row.visibility",
|
|
163
|
+
"after": "(grant_value.context = session_row.visibility OR (\n grant_value.context = 'user_private' AND session_row.visibility = 'workspace_shared'\n AND grant_value.mode IN ('once','session') AND grant_value.session_id = session_row.id\n AND (grant_value.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)))"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"signature": "prepare_session_attempt_personal_document_reads(uuid,uuid,uuid,uuid)",
|
|
167
|
+
"before": "grant_value.authority_epoch = session_row.authority_epoch",
|
|
168
|
+
"after": "(grant_value.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"signature": "opengeni_private.fence_mcp_account_bindings()",
|
|
172
|
+
"before": " bindings := '[]'::jsonb;",
|
|
173
|
+
"after": " bindings := CASE WHEN document ->> 'visibility' = 'workspace_shared'\n THEN old_bindings ELSE '[]'::jsonb END;"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"signature": "derive_session_execution_authority_epoch()",
|
|
177
|
+
"before": " IF TG_OP = 'INSERT' THEN\n NEW.execution_authority_epoch := NEW.authority_epoch;\n ELSIF NEW.execution_authority_epoch IS DISTINCT FROM OLD.execution_authority_epoch THEN\n RAISE EXCEPTION 'execution authority floor is lifecycle-owned' USING ERRCODE='42501';\n ELSIF NEW.authority_epoch IS DISTINCT FROM OLD.authority_epoch THEN\n NEW.execution_authority_epoch := NEW.authority_epoch;\n END IF;\n RETURN NEW;",
|
|
178
|
+
"after": " IF TG_OP = 'INSERT' THEN\n NEW.execution_authority_epoch := NEW.authority_epoch;\n ELSIF NEW.execution_authority_epoch IS DISTINCT FROM OLD.execution_authority_epoch THEN\n RAISE EXCEPTION 'execution authority floor is lifecycle-owned' USING ERRCODE='42501';\n ELSIF NEW.authority_epoch IS DISTINCT FROM OLD.authority_epoch THEN\n IF NOT (OLD.visibility = 'user_private' AND NEW.visibility = 'workspace_shared'\n AND NEW.authority_epoch = OLD.authority_epoch + 1\n AND NEW.owner_subject_id IS NOT DISTINCT FROM OLD.owner_subject_id\n AND NEW.owner_organization_membership_id IS NOT DISTINCT FROM OLD.owner_organization_membership_id) THEN\n NEW.execution_authority_epoch := NEW.authority_epoch;\n END IF;\n END IF;\n RETURN NEW;"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"signature": "opengeni_private.read_session_file_attachments(uuid,uuid,uuid,integer,uuid[],jsonb)",
|
|
182
|
+
"before": "session_row.authority_epoch IS DISTINCT FROM p_epoch",
|
|
183
|
+
"after": "NOT COALESCE((session_row.authority_epoch = p_epoch OR (\n p_actor->>'kind'='agent_attempt' AND (p_actor->>'callerSessionId')::uuid=p_session\n AND p_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch)), false)"
|
|
184
|
+
}
|
|
185
|
+
]$patches$::jsonb) WITH ORDINALITY AS ordered(value,ordinal) GROUP BY value->>'signature' LOOP
|
|
186
|
+
target := to_regprocedure(patch->>'signature');
|
|
187
|
+
IF target IS NULL THEN RAISE EXCEPTION 'sharing execution routine missing: %',patch->>'signature'; END IF;
|
|
188
|
+
source := pg_get_functiondef(target);
|
|
189
|
+
FOR change IN SELECT value FROM jsonb_array_elements(patch->'patches') LOOP
|
|
190
|
+
before_text := change->>'before'; after_text := change->>'after';
|
|
191
|
+
IF strpos(source,before_text)=0 THEN RAISE EXCEPTION 'sharing execution routine drift: %',target; END IF;
|
|
192
|
+
source := replace(source,before_text,after_text);
|
|
193
|
+
END LOOP;
|
|
194
|
+
EXECUTE source;
|
|
195
|
+
END LOOP;
|
|
196
|
+
END $sharing_execution$;
|
|
197
|
+
|
|
198
|
+
-- Keep the visibility lifecycle body explicit; this is DDL, not a data backfill.
|
|
199
|
+
CREATE OR REPLACE FUNCTION transition_session_visibility(p_account_id uuid, p_workspace_id uuid, p_session_id uuid, p_actor_subject_id text, p_target_visibility text, p_expected_authority_epoch integer, p_operation_key text, p_canonical_request_hash text, p_activation_version integer)
|
|
200
|
+
RETURNS TABLE(operation_id uuid, event_id uuid, event_sequence integer, visibility text, authority_epoch integer, owner_organization_membership_id uuid, changed boolean, replay boolean, interrupted_attempt_count integer, cancelled_turn_count integer, cancelled_update_count integer, paused_goal_count integer, revoked_grant_count integer)
|
|
201
|
+
LANGUAGE plpgsql
|
|
202
|
+
SECURITY DEFINER
|
|
203
|
+
SET search_path FROM CURRENT
|
|
204
|
+
AS $function$
|
|
205
|
+
DECLARE
|
|
206
|
+
actor_membership organization_memberships%ROWTYPE;
|
|
207
|
+
session_row sessions%ROWTYPE;
|
|
208
|
+
receipt_row session_command_receipts%ROWTYPE;
|
|
209
|
+
new_epoch integer;
|
|
210
|
+
grant_count integer := 0;
|
|
211
|
+
event_row_id uuid;
|
|
212
|
+
event_row_sequence integer;
|
|
213
|
+
visibility_write_capability_id uuid := gen_random_uuid();
|
|
214
|
+
previous_visibility_capability text := current_setting(
|
|
215
|
+
'opengeni.session_visibility_write_capability', true
|
|
216
|
+
);
|
|
217
|
+
previous_lifecycle text := current_setting('opengeni.organization_tenancy_lifecycle', true);
|
|
218
|
+
BEGIN
|
|
219
|
+
IF p_account_id IS NULL OR p_workspace_id IS NULL OR p_session_id IS NULL
|
|
220
|
+
OR p_actor_subject_id IS NULL OR p_target_visibility IS NULL
|
|
221
|
+
OR p_expected_authority_epoch IS NULL OR p_operation_key IS NULL
|
|
222
|
+
OR p_canonical_request_hash IS NULL OR p_activation_version IS NULL
|
|
223
|
+
THEN RAISE EXCEPTION 'session visibility transition requires complete authority'
|
|
224
|
+
USING ERRCODE = '42501'; END IF;
|
|
225
|
+
IF p_account_id IS DISTINCT FROM opengeni_private.current_account_id()
|
|
226
|
+
OR p_workspace_id IS DISTINCT FROM opengeni_private.current_workspace_id()
|
|
227
|
+
OR p_actor_subject_id IS DISTINCT FROM opengeni_private.current_subject_id()
|
|
228
|
+
THEN RAISE EXCEPTION 'session visibility transition authority is invalid'
|
|
229
|
+
USING ERRCODE = '42501'; END IF;
|
|
230
|
+
IF p_target_visibility NOT IN ('user_private', 'workspace_shared')
|
|
231
|
+
OR p_expected_authority_epoch < 1
|
|
232
|
+
OR p_actor_subject_id <> btrim(p_actor_subject_id)
|
|
233
|
+
OR length(p_actor_subject_id) NOT BETWEEN 1 AND 1024
|
|
234
|
+
OR p_operation_key <> btrim(p_operation_key)
|
|
235
|
+
OR length(p_operation_key) NOT BETWEEN 1 AND 1024
|
|
236
|
+
OR p_canonical_request_hash !~ '^[0-9a-f]{64}$'
|
|
237
|
+
OR p_activation_version <> 1
|
|
238
|
+
THEN RAISE EXCEPTION 'session visibility transition request is invalid'
|
|
239
|
+
USING ERRCODE = '22023'; END IF;
|
|
240
|
+
IF NOT session_tenancy_product_activated(p_account_id, p_activation_version) THEN
|
|
241
|
+
RAISE EXCEPTION 'session tenancy product surface is not activated for this organization'
|
|
242
|
+
USING ERRCODE = '55000';
|
|
243
|
+
END IF;
|
|
244
|
+
|
|
245
|
+
-- Match the canonical organization-membership lifecycle prefix before any
|
|
246
|
+
-- table/row lock. This keeps visibility changes from reintroducing the
|
|
247
|
+
-- workspace/account lock cycle repaired by migration 0299.
|
|
248
|
+
PERFORM pg_catalog.pg_advisory_xact_lock(pg_catalog.hashtextextended(
|
|
249
|
+
'organization-membership:' || p_account_id::text, 0
|
|
250
|
+
));
|
|
251
|
+
|
|
252
|
+
PERFORM pg_catalog.pg_advisory_xact_lock(pg_catalog.hashtextextended(
|
|
253
|
+
'session-tenancy:' || p_workspace_id::text, 0
|
|
254
|
+
));
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
PERFORM set_config('opengeni.organization_tenancy_lifecycle',
|
|
258
|
+
'session_visibility_activation', true);
|
|
259
|
+
PERFORM 1 FROM workspaces workspace_row
|
|
260
|
+
WHERE workspace_row.id = p_workspace_id AND workspace_row.account_id = p_account_id
|
|
261
|
+
FOR UPDATE;
|
|
262
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'session visibility transition workspace is unavailable'
|
|
263
|
+
USING ERRCODE = '42501'; END IF;
|
|
264
|
+
|
|
265
|
+
SELECT membership.* INTO actor_membership
|
|
266
|
+
FROM organization_memberships membership
|
|
267
|
+
WHERE membership.account_id = p_account_id
|
|
268
|
+
AND membership.subject_id = p_actor_subject_id
|
|
269
|
+
AND membership.status = 'active'
|
|
270
|
+
FOR UPDATE;
|
|
271
|
+
IF NOT FOUND OR NOT (
|
|
272
|
+
actor_membership.personal_workspace_id = p_workspace_id
|
|
273
|
+
OR EXISTS (
|
|
274
|
+
SELECT 1 FROM workspace_memberships workspace_membership
|
|
275
|
+
WHERE workspace_membership.account_id = p_account_id
|
|
276
|
+
AND workspace_membership.workspace_id = p_workspace_id
|
|
277
|
+
AND workspace_membership.subject_id = p_actor_subject_id
|
|
278
|
+
)
|
|
279
|
+
) THEN RAISE EXCEPTION 'session visibility transition requires active membership'
|
|
280
|
+
USING ERRCODE = '42501'; END IF;
|
|
281
|
+
|
|
282
|
+
SELECT session.* INTO session_row FROM sessions session
|
|
283
|
+
WHERE session.account_id = p_account_id AND session.workspace_id = p_workspace_id
|
|
284
|
+
AND session.id = p_session_id
|
|
285
|
+
FOR UPDATE;
|
|
286
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'session visibility transition session is unavailable'
|
|
287
|
+
USING ERRCODE = 'P0002'; END IF;
|
|
288
|
+
IF session_row.owner_organization_membership_id IS DISTINCT FROM actor_membership.id
|
|
289
|
+
OR session_row.owner_subject_id IS DISTINCT FROM actor_membership.subject_id
|
|
290
|
+
THEN RAISE EXCEPTION 'session visibility transition is owner-only'
|
|
291
|
+
USING ERRCODE = '42501'; END IF;
|
|
292
|
+
|
|
293
|
+
INSERT INTO session_command_receipts (
|
|
294
|
+
account_id, workspace_id, actor_type, actor_subject_id, action,
|
|
295
|
+
target_session_id, operation_key, canonical_request_hash
|
|
296
|
+
) VALUES (
|
|
297
|
+
p_account_id, p_workspace_id, 'human', p_actor_subject_id,
|
|
298
|
+
'session.visibility.change', p_session_id, p_operation_key, p_canonical_request_hash
|
|
299
|
+
) ON CONFLICT DO NOTHING;
|
|
300
|
+
SELECT receipt.* INTO receipt_row FROM session_command_receipts receipt
|
|
301
|
+
WHERE receipt.workspace_id = p_workspace_id AND receipt.actor_type = 'human'
|
|
302
|
+
AND receipt.actor_subject_id = p_actor_subject_id
|
|
303
|
+
AND receipt.actor_attempt_id IS NULL
|
|
304
|
+
AND receipt.action = 'session.visibility.change'
|
|
305
|
+
AND receipt.target_session_id = p_session_id AND receipt.target_turn_id IS NULL
|
|
306
|
+
AND receipt.operation_key = p_operation_key
|
|
307
|
+
FOR UPDATE;
|
|
308
|
+
IF receipt_row.canonical_request_hash <> p_canonical_request_hash THEN
|
|
309
|
+
RAISE EXCEPTION 'session visibility transition idempotency conflict'
|
|
310
|
+
USING ERRCODE = '23505';
|
|
311
|
+
END IF;
|
|
312
|
+
IF receipt_row.result ->> 'status' = 'applied' THEN
|
|
313
|
+
operation_id := receipt_row.id;
|
|
314
|
+
event_id := nullif(receipt_row.result ->> 'eventId', '')::uuid;
|
|
315
|
+
event_sequence := nullif(receipt_row.result ->> 'eventSequence', '')::integer;
|
|
316
|
+
visibility := receipt_row.result ->> 'visibility';
|
|
317
|
+
authority_epoch := (receipt_row.result ->> 'authorityEpoch')::integer;
|
|
318
|
+
owner_organization_membership_id := actor_membership.id;
|
|
319
|
+
changed := (receipt_row.result ->> 'changed')::boolean;
|
|
320
|
+
replay := true;
|
|
321
|
+
interrupted_attempt_count := 0; cancelled_turn_count := 0;
|
|
322
|
+
cancelled_update_count := 0; paused_goal_count := 0;
|
|
323
|
+
revoked_grant_count := (receipt_row.result ->> 'revokedGrantCount')::integer;
|
|
324
|
+
RETURN NEXT; RETURN;
|
|
325
|
+
END IF;
|
|
326
|
+
IF session_row.authority_epoch <> p_expected_authority_epoch THEN
|
|
327
|
+
RAISE EXCEPTION 'session visibility transition authority epoch conflict'
|
|
328
|
+
USING ERRCODE = '40001';
|
|
329
|
+
END IF;
|
|
330
|
+
|
|
331
|
+
new_epoch := session_row.authority_epoch;
|
|
332
|
+
IF session_row.visibility <> p_target_visibility THEN
|
|
333
|
+
IF p_target_visibility = 'user_private' THEN
|
|
334
|
+
PERFORM assert_session_tenancy_quiescent(p_account_id, p_workspace_id, p_session_id, true);
|
|
335
|
+
END IF;
|
|
336
|
+
new_epoch := session_row.authority_epoch + 1;
|
|
337
|
+
IF new_epoch < 2 THEN RAISE EXCEPTION 'session authority epoch exhausted'
|
|
338
|
+
USING ERRCODE = '22003'; END IF;
|
|
339
|
+
|
|
340
|
+
IF p_target_visibility = 'user_private' THEN
|
|
341
|
+
UPDATE organization_user_resource_grants grant_row
|
|
342
|
+
SET status = 'revoked', revoked_at = clock_timestamp(),
|
|
343
|
+
generation = grant_row.generation + 1, updated_at = clock_timestamp()
|
|
344
|
+
WHERE grant_row.account_id = p_account_id
|
|
345
|
+
AND grant_row.workspace_id = p_workspace_id
|
|
346
|
+
AND grant_row.session_id = p_session_id
|
|
347
|
+
AND grant_row.authority_epoch BETWEEN session_row.execution_authority_epoch AND session_row.authority_epoch
|
|
348
|
+
AND grant_row.status = 'active';
|
|
349
|
+
GET DIAGNOSTICS grant_count = ROW_COUNT;
|
|
350
|
+
END IF;
|
|
351
|
+
|
|
352
|
+
INSERT INTO session_visibility_write_capabilities (
|
|
353
|
+
backend_pid, transaction_id, capability_id
|
|
354
|
+
) VALUES (pg_backend_pid(), pg_current_xact_id(), visibility_write_capability_id);
|
|
355
|
+
PERFORM set_config('opengeni.session_visibility_write_capability',
|
|
356
|
+
visibility_write_capability_id::text, true);
|
|
357
|
+
UPDATE sessions transition_target SET
|
|
358
|
+
visibility = p_target_visibility,
|
|
359
|
+
authority_epoch = new_epoch,
|
|
360
|
+
initial_personal_connection_delegations = CASE WHEN p_target_visibility = 'user_private'
|
|
361
|
+
THEN '[]'::jsonb ELSE transition_target.initial_personal_connection_delegations END,
|
|
362
|
+
last_sequence = session_row.last_sequence + 1,
|
|
363
|
+
updated_at = clock_timestamp()
|
|
364
|
+
WHERE transition_target.id = p_session_id
|
|
365
|
+
AND transition_target.authority_epoch = session_row.authority_epoch;
|
|
366
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'session visibility transition lost authority epoch CAS'
|
|
367
|
+
USING ERRCODE = '40001'; END IF;
|
|
368
|
+
|
|
369
|
+
INSERT INTO session_events (
|
|
370
|
+
account_id, workspace_id, session_id, sequence, type, payload, occurred_at
|
|
371
|
+
) VALUES (
|
|
372
|
+
p_account_id, p_workspace_id, p_session_id, session_row.last_sequence + 1,
|
|
373
|
+
'session.visibility.changed',
|
|
374
|
+
jsonb_build_object(
|
|
375
|
+
'operationId', receipt_row.id,
|
|
376
|
+
'fromVisibility', CASE session_row.visibility WHEN 'user_private' THEN 'private' ELSE 'workspace' END,
|
|
377
|
+
'toVisibility', CASE p_target_visibility WHEN 'user_private' THEN 'private' ELSE 'workspace' END,
|
|
378
|
+
'previousAuthorityEpoch', session_row.authority_epoch,
|
|
379
|
+
'authorityEpoch', new_epoch,
|
|
380
|
+
'interruptedAttemptCount', 0, 'cancelledTurnCount', 0,
|
|
381
|
+
'cancelledUpdateCount', 0, 'pausedGoalCount', 0,
|
|
382
|
+
'revokedGrantCount', grant_count
|
|
383
|
+
), clock_timestamp()
|
|
384
|
+
) RETURNING id, sequence INTO event_row_id, event_row_sequence;
|
|
385
|
+
DELETE FROM session_visibility_write_capabilities capability
|
|
386
|
+
WHERE capability.backend_pid = pg_backend_pid()
|
|
387
|
+
AND capability.transaction_id = pg_current_xact_id()
|
|
388
|
+
AND capability.capability_id = visibility_write_capability_id;
|
|
389
|
+
PERFORM set_config('opengeni.session_visibility_write_capability',
|
|
390
|
+
CASE WHEN previous_visibility_capability IS NULL THEN '' ELSE previous_visibility_capability END,
|
|
391
|
+
true);
|
|
392
|
+
END IF;
|
|
393
|
+
|
|
394
|
+
UPDATE session_command_receipts SET result = jsonb_build_object(
|
|
395
|
+
'status', 'applied', 'eventId', event_row_id,
|
|
396
|
+
'eventSequence', event_row_sequence, 'visibility', p_target_visibility,
|
|
397
|
+
'authorityEpoch', new_epoch, 'changed', session_row.visibility <> p_target_visibility,
|
|
398
|
+
'revokedGrantCount', grant_count
|
|
399
|
+
), updated_at = clock_timestamp() WHERE id = receipt_row.id;
|
|
400
|
+
|
|
401
|
+
operation_id := receipt_row.id; event_id := event_row_id;
|
|
402
|
+
event_sequence := event_row_sequence; visibility := p_target_visibility;
|
|
403
|
+
authority_epoch := new_epoch;
|
|
404
|
+
owner_organization_membership_id := actor_membership.id;
|
|
405
|
+
changed := session_row.visibility <> p_target_visibility; replay := false;
|
|
406
|
+
interrupted_attempt_count := 0; cancelled_turn_count := 0;
|
|
407
|
+
cancelled_update_count := 0; paused_goal_count := 0;
|
|
408
|
+
revoked_grant_count := grant_count;
|
|
409
|
+
PERFORM set_config('opengeni.organization_tenancy_lifecycle',
|
|
410
|
+
CASE WHEN previous_lifecycle IS NULL THEN '' ELSE previous_lifecycle END, true);
|
|
411
|
+
RETURN NEXT;
|
|
412
|
+
EXCEPTION WHEN OTHERS THEN
|
|
413
|
+
PERFORM set_config('opengeni.organization_tenancy_lifecycle',
|
|
414
|
+
CASE WHEN previous_lifecycle IS NULL THEN '' ELSE previous_lifecycle END, true);
|
|
415
|
+
PERFORM set_config('opengeni.session_visibility_write_capability',
|
|
416
|
+
CASE WHEN previous_visibility_capability IS NULL THEN '' ELSE previous_visibility_capability END,
|
|
417
|
+
true);
|
|
418
|
+
RAISE;
|
|
419
|
+
END
|
|
420
|
+
$function$
|
|
421
|
+
;
|
|
422
|
+
|
|
423
|
+
-- Existing machine receipts still require exact live grant and attempt authority.
|
|
424
|
+
CREATE OR REPLACE FUNCTION assert_session_attempt_personal_machine(p_account_id uuid, p_workspace_id uuid, p_session_id uuid, p_turn_id uuid, p_attempt_id uuid, p_execution_generation integer, p_enrollment_id uuid, p_require_active_sandbox boolean)
|
|
425
|
+
RETURNS boolean
|
|
426
|
+
LANGUAGE plpgsql
|
|
427
|
+
SECURITY DEFINER
|
|
428
|
+
SET search_path FROM CURRENT
|
|
429
|
+
AS $function$
|
|
430
|
+
DECLARE
|
|
431
|
+
authorization_row session_attempt_connected_machine_authorizations%ROWTYPE;
|
|
432
|
+
caller_subject text := coalesce(
|
|
433
|
+
nullif(pg_catalog.current_setting('opengeni.initiating_human_subject_id', true), ''),
|
|
434
|
+
nullif(pg_catalog.current_setting('opengeni.subject_id', true), '')
|
|
435
|
+
);
|
|
436
|
+
BEGIN
|
|
437
|
+
IF p_account_id IS DISTINCT FROM nullif(
|
|
438
|
+
pg_catalog.current_setting('opengeni.account_id', true), '')::uuid
|
|
439
|
+
OR p_workspace_id IS DISTINCT FROM nullif(
|
|
440
|
+
pg_catalog.current_setting('opengeni.workspace_id', true), '')::uuid
|
|
441
|
+
THEN RAISE EXCEPTION 'machine runtime scope mismatch' USING ERRCODE = '42501'; END IF;
|
|
442
|
+
INSERT INTO opengeni_private.scoped_compute_capabilities(
|
|
443
|
+
backend_pid, transaction_id, capability_kind
|
|
444
|
+
) VALUES (pg_catalog.pg_backend_pid(), pg_catalog.pg_current_xact_id(), 'runtime')
|
|
445
|
+
ON CONFLICT DO NOTHING;
|
|
446
|
+
SELECT authorization_value.* INTO authorization_row
|
|
447
|
+
FROM session_attempt_connected_machine_authorizations authorization_value
|
|
448
|
+
WHERE authorization_value.attempt_id = p_attempt_id
|
|
449
|
+
AND authorization_value.account_id = p_account_id
|
|
450
|
+
AND authorization_value.workspace_id = p_workspace_id
|
|
451
|
+
AND authorization_value.session_id = p_session_id
|
|
452
|
+
AND authorization_value.turn_id = p_turn_id
|
|
453
|
+
AND authorization_value.execution_generation = p_execution_generation
|
|
454
|
+
AND authorization_value.enrollment_id = p_enrollment_id;
|
|
455
|
+
IF authorization_row.attempt_id IS NULL THEN
|
|
456
|
+
DELETE FROM opengeni_private.scoped_compute_capabilities
|
|
457
|
+
WHERE backend_pid = pg_catalog.pg_backend_pid()
|
|
458
|
+
AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
|
|
459
|
+
AND capability_kind = 'runtime';
|
|
460
|
+
RETURN false;
|
|
461
|
+
END IF;
|
|
462
|
+
IF caller_subject IS DISTINCT FROM authorization_row.initiating_human_subject_id
|
|
463
|
+
OR NOT EXISTS (
|
|
464
|
+
SELECT 1 FROM sessions session_value
|
|
465
|
+
JOIN session_turns turn_value ON turn_value.id = p_turn_id
|
|
466
|
+
AND turn_value.account_id = session_value.account_id
|
|
467
|
+
AND turn_value.workspace_id = session_value.workspace_id
|
|
468
|
+
AND turn_value.session_id = session_value.id
|
|
469
|
+
JOIN session_turn_attempts attempt ON attempt.id = p_attempt_id
|
|
470
|
+
AND attempt.turn_id = turn_value.id AND attempt.session_id = session_value.id
|
|
471
|
+
AND attempt.account_id = session_value.account_id
|
|
472
|
+
AND attempt.workspace_id = session_value.workspace_id
|
|
473
|
+
JOIN sandboxes sandbox ON sandbox.id = authorization_row.sandbox_id
|
|
474
|
+
AND sandbox.account_id = session_value.account_id
|
|
475
|
+
WHERE session_value.id = p_session_id AND session_value.account_id = p_account_id
|
|
476
|
+
AND session_value.workspace_id = p_workspace_id
|
|
477
|
+
AND session_value.active_turn_id = p_turn_id
|
|
478
|
+
AND (NOT p_require_active_sandbox
|
|
479
|
+
OR session_value.active_sandbox_id = authorization_row.sandbox_id)
|
|
480
|
+
AND (authorization_row.session_authority_epoch BETWEEN session_value.execution_authority_epoch AND session_value.authority_epoch)
|
|
481
|
+
AND turn_value.active_attempt_id = p_attempt_id
|
|
482
|
+
AND turn_value.execution_generation = p_execution_generation
|
|
483
|
+
AND turn_value.status = 'running'
|
|
484
|
+
AND attempt.execution_generation = p_execution_generation
|
|
485
|
+
AND attempt.state IN ('claimed','running') AND attempt.closed_at IS NULL
|
|
486
|
+
AND attempt.quiesced_at IS NULL
|
|
487
|
+
AND sandbox.enrollment_id = p_enrollment_id
|
|
488
|
+
)
|
|
489
|
+
OR EXISTS (
|
|
490
|
+
SELECT 1 FROM session_attempt_interruptions interruption
|
|
491
|
+
WHERE interruption.attempt_id = p_attempt_id AND interruption.account_id = p_account_id
|
|
492
|
+
AND interruption.workspace_id = p_workspace_id
|
|
493
|
+
AND interruption.state IN ('pending','delivered','acknowledged')
|
|
494
|
+
)
|
|
495
|
+
OR NOT EXISTS (
|
|
496
|
+
SELECT 1 FROM organization_memberships membership
|
|
497
|
+
WHERE membership.id = authorization_row.owner_organization_membership_id
|
|
498
|
+
AND membership.account_id = p_account_id
|
|
499
|
+
AND membership.subject_id = authorization_row.initiating_human_subject_id
|
|
500
|
+
AND membership.status = 'active' AND membership.revoked_at IS NULL
|
|
501
|
+
AND membership.authorization_revision
|
|
502
|
+
= authorization_row.membership_authorization_revision
|
|
503
|
+
AND (membership.personal_workspace_id = p_workspace_id OR EXISTS (
|
|
504
|
+
SELECT 1 FROM workspace_memberships workspace_membership
|
|
505
|
+
WHERE workspace_membership.account_id = p_account_id
|
|
506
|
+
AND workspace_membership.workspace_id = p_workspace_id
|
|
507
|
+
AND workspace_membership.subject_id = membership.subject_id
|
|
508
|
+
))
|
|
509
|
+
)
|
|
510
|
+
OR NOT EXISTS (
|
|
511
|
+
SELECT 1 FROM enrollments enrollment
|
|
512
|
+
WHERE enrollment.id = p_enrollment_id AND enrollment.account_id = p_account_id
|
|
513
|
+
AND enrollment.authority_scope = 'user'
|
|
514
|
+
AND enrollment.owner_organization_membership_id
|
|
515
|
+
= authorization_row.owner_organization_membership_id
|
|
516
|
+
AND enrollment.authority_id = authorization_row.authority_id
|
|
517
|
+
AND enrollment.generation = authorization_row.enrollment_generation
|
|
518
|
+
AND enrollment.status = 'active' AND enrollment.revoked_at IS NULL
|
|
519
|
+
)
|
|
520
|
+
OR NOT EXISTS (
|
|
521
|
+
SELECT 1 FROM organization_user_resource_authorities authority
|
|
522
|
+
WHERE authority.id = authorization_row.authority_id
|
|
523
|
+
AND authority.account_id = p_account_id
|
|
524
|
+
AND authority.organization_membership_id
|
|
525
|
+
= authorization_row.owner_organization_membership_id
|
|
526
|
+
AND authority.resource_kind = 'connected_machine'
|
|
527
|
+
AND authority.resource_id = p_enrollment_id
|
|
528
|
+
AND authority.generation = authorization_row.authority_generation
|
|
529
|
+
AND authority.status = 'active' AND authority.revoked_at IS NULL
|
|
530
|
+
)
|
|
531
|
+
OR NOT EXISTS (
|
|
532
|
+
SELECT 1 FROM organization_user_resource_grants grant_value
|
|
533
|
+
WHERE grant_value.id = authorization_row.grant_id
|
|
534
|
+
AND grant_value.account_id = p_account_id
|
|
535
|
+
AND grant_value.authority_id = authorization_row.authority_id
|
|
536
|
+
AND grant_value.owner_organization_membership_id
|
|
537
|
+
= authorization_row.owner_organization_membership_id
|
|
538
|
+
AND grant_value.workspace_id = p_workspace_id
|
|
539
|
+
AND grant_value.generation = authorization_row.grant_generation
|
|
540
|
+
AND grant_value.action = 'connected_machine.use'
|
|
541
|
+
AND grant_value.context = authorization_row.session_visibility
|
|
542
|
+
AND grant_value.mode = authorization_row.grant_mode
|
|
543
|
+
AND (grant_value.expires_at IS NULL OR grant_value.expires_at > clock_timestamp())
|
|
544
|
+
AND ((authorization_row.grant_mode = 'once' AND grant_value.status = 'consumed'
|
|
545
|
+
AND grant_value.session_id = p_session_id
|
|
546
|
+
AND EXISTS (SELECT 1 FROM sessions grant_session WHERE grant_session.account_id=p_account_id AND grant_session.workspace_id=p_workspace_id AND grant_session.id=p_session_id AND grant_value.authority_epoch BETWEEN grant_session.execution_authority_epoch AND grant_session.authority_epoch)
|
|
547
|
+
AND EXISTS (SELECT 1 FROM personal_resource_once_consumption_receipts receipt
|
|
548
|
+
WHERE receipt.grant_id = grant_value.id AND receipt.attempt_id = p_attempt_id
|
|
549
|
+
AND receipt.account_id = p_account_id))
|
|
550
|
+
OR (authorization_row.grant_mode = 'session' AND grant_value.status = 'active'
|
|
551
|
+
AND grant_value.session_id = p_session_id
|
|
552
|
+
AND EXISTS (SELECT 1 FROM sessions grant_session WHERE grant_session.account_id=p_account_id AND grant_session.workspace_id=p_workspace_id AND grant_session.id=p_session_id AND grant_value.authority_epoch BETWEEN grant_session.execution_authority_epoch AND grant_session.authority_epoch))
|
|
553
|
+
OR (authorization_row.grant_mode = 'always' AND grant_value.status = 'active'
|
|
554
|
+
AND grant_value.session_id IS NULL AND grant_value.authority_epoch IS NULL))
|
|
555
|
+
)
|
|
556
|
+
THEN RAISE EXCEPTION 'personal machine authority is no longer live'
|
|
557
|
+
USING ERRCODE = '42501'; END IF;
|
|
558
|
+
INSERT INTO audit_events(
|
|
559
|
+
account_id, workspace_id, subject_id, action, target_type, target_id,
|
|
560
|
+
metadata, metadata_codec_version
|
|
561
|
+
) VALUES (
|
|
562
|
+
p_account_id, p_workspace_id, authorization_row.initiating_human_subject_id,
|
|
563
|
+
'connected_machine.used', 'enrollment', p_enrollment_id::text,
|
|
564
|
+
pg_catalog.jsonb_build_object(
|
|
565
|
+
'ownerOrganizationMembershipId', authorization_row.owner_organization_membership_id,
|
|
566
|
+
'scope', 'user', 'sessionId', p_session_id, 'turnId', p_turn_id,
|
|
567
|
+
'attemptId', p_attempt_id, 'executionGeneration', p_execution_generation,
|
|
568
|
+
'generation', authorization_row.enrollment_generation
|
|
569
|
+
), 1
|
|
570
|
+
);
|
|
571
|
+
DELETE FROM opengeni_private.scoped_compute_capabilities
|
|
572
|
+
WHERE backend_pid = pg_catalog.pg_backend_pid()
|
|
573
|
+
AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
|
|
574
|
+
AND capability_kind = 'runtime';
|
|
575
|
+
RETURN true;
|
|
576
|
+
EXCEPTION WHEN OTHERS THEN
|
|
577
|
+
DELETE FROM opengeni_private.scoped_compute_capabilities
|
|
578
|
+
WHERE backend_pid = pg_catalog.pg_backend_pid()
|
|
579
|
+
AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned();
|
|
580
|
+
RAISE;
|
|
581
|
+
END
|
|
582
|
+
$function$
|
|
583
|
+
;
|
|
584
|
+
|
|
585
|
+
-- Pin the installation schema, including dedicated non-public deployments.
|
|
586
|
+
DO $sharing_routine_paths$
|
|
587
|
+
DECLARE target_schema text := current_schema();
|
|
588
|
+
BEGIN
|
|
589
|
+
EXECUTE format('ALTER FUNCTION transition_session_visibility(uuid,uuid,uuid,text,text,integer,text,text,integer) SET search_path=pg_catalog,%I,pg_temp', target_schema);
|
|
590
|
+
EXECUTE format('ALTER FUNCTION assert_session_attempt_personal_machine(uuid,uuid,uuid,uuid,uuid,integer,uuid,boolean) SET search_path=pg_catalog,%I,pg_temp', target_schema);
|
|
591
|
+
END $sharing_routine_paths$;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- A message fork copies a validated prefix, not live execution or sandbox state.
|
|
3
|
+
-- The existing exclusive workspace tenancy fence, workspace FOR UPDATE and
|
|
4
|
+
-- source session FOR UPDATE serialize history append, replacement/compaction,
|
|
5
|
+
-- attachment grants and authority changes through validation and spool copying.
|
|
6
|
+
-- Writers retain their ordinary shared tenancy / canonical row-lock protocol.
|
|
7
|
+
-- Do not relax quiescence for the whole-session overload or visibility changes.
|
|
8
|
+
DO $migration$
|
|
9
|
+
DECLARE
|
|
10
|
+
definition text;
|
|
11
|
+
updated text;
|
|
12
|
+
target regprocedure := 'fork_session_content(uuid,uuid,uuid,text,uuid,text,boolean,text,text,integer,uuid)'::regprocedure;
|
|
13
|
+
anchor constant text := $anchor$ PERFORM assert_session_tenancy_quiescent(
|
|
14
|
+
p_account_id, p_source_workspace_id, p_source_session_id, true
|
|
15
|
+
);$anchor$;
|
|
16
|
+
BEGIN
|
|
17
|
+
definition := pg_get_functiondef(target);
|
|
18
|
+
IF (length(definition) - length(replace(definition, anchor, ''))) / length(anchor) <> 1 THEN
|
|
19
|
+
RAISE EXCEPTION 'active message fork quiescence rewrite did not match exactly once';
|
|
20
|
+
END IF;
|
|
21
|
+
updated := replace(definition, anchor,
|
|
22
|
+
' -- Active source work is allowed: the held locks stabilize the selected prefix.');
|
|
23
|
+
updated := replace(updated,
|
|
24
|
+
'-- Authority, source locks, keyed replay, and quiescence have already been',
|
|
25
|
+
'-- Authority, source locks, and keyed replay have already been');
|
|
26
|
+
-- Reuse the current definition, preserving ordered JSON, fractional controls,
|
|
27
|
+
-- attachment boundaries, authorization, receipt replay and routine posture.
|
|
28
|
+
EXECUTE updated;
|
|
29
|
+
END
|
|
30
|
+
$migration$;
|