@opengeni/db 1.0.1 → 3.2.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/dist/attached-browser-devices.d.ts +7 -0
  2. package/dist/automations.d.ts +154 -0
  3. package/dist/canonical-human-identities.js +3 -3
  4. package/dist/capability-integrations.d.ts +13 -0
  5. package/dist/child-lifecycle-notices.d.ts +68 -0
  6. package/dist/{chunk-4SR4HKKA.js → chunk-2EH4WRHL.js} +19 -11
  7. package/dist/chunk-2EH4WRHL.js.map +1 -0
  8. package/dist/{chunk-CUPM3FGB.js → chunk-2PRS4J5Q.js} +3 -3
  9. package/dist/chunk-6HMM2R5T.js +390 -0
  10. package/dist/chunk-6HMM2R5T.js.map +1 -0
  11. package/dist/{chunk-ZWREYEWA.js → chunk-AZHW7R5V.js} +56 -11
  12. package/dist/chunk-AZHW7R5V.js.map +1 -0
  13. package/dist/{chunk-LTG3S6ZY.js → chunk-E6CLMKEE.js} +2 -2
  14. package/dist/{chunk-6ZYKCRFO.js → chunk-KRLPEMLH.js} +7591 -4417
  15. package/dist/chunk-KRLPEMLH.js.map +1 -0
  16. package/dist/chunk-NAB6FKFN.js +516 -0
  17. package/dist/chunk-NAB6FKFN.js.map +1 -0
  18. package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
  19. package/dist/chunk-SIBYBA2D.js.map +1 -0
  20. package/dist/chunk-UZNXG44K.js +4508 -0
  21. package/dist/chunk-UZNXG44K.js.map +1 -0
  22. package/dist/codemode-operations.d.ts +1 -6
  23. package/dist/company-brain-context-selection-schema.d.ts +705 -0
  24. package/dist/company-brain-context-selection.d.ts +94 -0
  25. package/dist/company-brain-governed-writes.d.ts +24 -0
  26. package/dist/company-brain.d.ts +55 -0
  27. package/dist/company-profile-agent-admin.d.ts +15 -0
  28. package/dist/company-profile-schema.d.ts +619 -2
  29. package/dist/company-profile.d.ts +9 -4
  30. package/dist/connection-authority.d.ts +95 -0
  31. package/dist/connection-scopes.d.ts +8 -0
  32. package/dist/connection-tenancy-backfill.d.ts +85 -0
  33. package/dist/connection-token-resolver.d.ts +30 -1
  34. package/dist/database.d.ts +23 -4
  35. package/dist/editable-artifact-durable-export.js +2 -2
  36. package/dist/editable-artifacts.d.ts +2 -2
  37. package/dist/editable-artifacts.js +3 -3
  38. package/dist/governed-learning-activation-schema.d.ts +984 -0
  39. package/dist/governed-learning-activation.d.ts +98 -0
  40. package/dist/governed-learning-evaluator-schema.d.ts +633 -0
  41. package/dist/governed-learning-evaluator.d.ts +28 -0
  42. package/dist/index.d.ts +1606 -81
  43. package/dist/index.js +21898 -8147
  44. package/dist/index.js.map +1 -1
  45. package/dist/insights.d.ts +18 -0
  46. package/dist/integration-bindings.d.ts +1 -0
  47. package/dist/integration-facets.d.ts +30 -0
  48. package/dist/interaction-placement-loss.d.ts +22 -0
  49. package/dist/managed-human-provisioning.d.ts +25 -0
  50. package/dist/memory-domain.d.ts +3 -3
  51. package/dist/migrate.d.ts +11 -1
  52. package/dist/migrate.js +1 -1
  53. package/dist/new-session-drafts.d.ts +43 -5
  54. package/dist/organization-membership-backfill.d.ts +174 -0
  55. package/dist/organization-membership-lifecycle.d.ts +162 -0
  56. package/dist/pr-review.d.ts +107 -0
  57. package/dist/preference-registry-schema.d.ts +2 -0
  58. package/dist/preference-registry.d.ts +2 -0
  59. package/dist/provision-roles.js +1 -1
  60. package/dist/runtime-posture.d.ts +29 -8
  61. package/dist/schema.d.ts +24914 -13703
  62. package/dist/schema.js +99 -1
  63. package/dist/scoped-knowledge-schema.d.ts +52 -1
  64. package/dist/session-background-commands.d.ts +125 -0
  65. package/dist/session-background-commands.js +34 -0
  66. package/dist/session-background-commands.js.map +1 -0
  67. package/dist/session-control.d.ts +156 -3
  68. package/dist/session-goal-pacing.d.ts +68 -0
  69. package/dist/session-queue-commands.d.ts +43 -4
  70. package/dist/session-realtime-ledger.d.ts +2 -0
  71. package/dist/session-tenancy.d.ts +71 -1
  72. package/dist/session-tenancy.js +25 -3
  73. package/dist/session-tool-call-settlement.d.ts +9 -4
  74. package/dist/slack-routing-personal-workspace.d.ts +23 -0
  75. package/dist/slack-routing.d.ts +268 -0
  76. package/dist/slack-task-policy-schema.d.ts +34 -0
  77. package/dist/slack-task-policy.d.ts +8 -0
  78. package/dist/slack-user-link-access.d.ts +28 -0
  79. package/dist/task-notes-schema.d.ts +594 -0
  80. package/dist/task-notes.d.ts +39 -0
  81. package/dist/turn-initiator.d.ts +2 -0
  82. package/dist/user-resource-authority.d.ts +109 -0
  83. package/dist/video-generation.js +3 -3
  84. package/dist/workspace-authority.d.ts +81 -0
  85. package/dist/workspace-instruction-policies-schema.d.ts +279 -0
  86. package/dist/workspace-instruction-policies.d.ts +62 -0
  87. package/dist/workspace-learning-policy.d.ts +1 -0
  88. package/dist/workspace-membership-permissions.d.ts +2 -0
  89. package/drizzle/0240_enrollment_connection_authority.sql +39 -0
  90. package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
  91. package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
  92. package/drizzle/0244_slack_app_home_refresh_queue.sql +120 -0
  93. package/drizzle/0245_model_context_contribution_facts.sql +88 -0
  94. package/drizzle/0246_integration_personal_instance_authority.sql +70 -0
  95. package/drizzle/0247_terraform_stacks_provenance_repair.sql +428 -0
  96. package/drizzle/0248_terraform_stacks_component_resolution_fence.sql +83 -0
  97. package/drizzle/0249_personal_resource_delegation_authority_correction.sql +662 -0
  98. package/drizzle/0250_direct_retained_process_owner_liveness.sql +199 -0
  99. package/drizzle/0251_connected_machine_operation_policy.sql +45 -0
  100. package/drizzle/0252_scheduled_personal_resource_delegation.sql +1867 -0
  101. package/drizzle/0253_common_user_resource_authority_lifecycle.sql +1555 -0
  102. package/drizzle/0254_scoped_variable_set_authority.sql +1255 -0
  103. package/drizzle/0255_company_brain_governed_write_proposals.sql +524 -0
  104. package/drizzle/0256_connection_authority_delegation.sql +703 -0
  105. package/drizzle/0257_goal_revision_decisions_and_root_constraints.sql +436 -0
  106. package/drizzle/0258_three_scope_document_knowledge_authority.sql +1273 -0
  107. package/drizzle/0259_company_brain_context_selection_receipts.sql +869 -0
  108. package/drizzle/0260_task_note_knowledge_promotion.sql +820 -0
  109. package/drizzle/0261_preference_knowledge_proposal_actor_binding.sql +471 -0
  110. package/drizzle/0262_scoped_connected_machines_and_rigs.sql +1700 -0
  111. package/drizzle/0263_organization_membership_lifecycle.sql +3284 -0
  112. package/drizzle/0264_connection_authority_runtime_activation.sql +1084 -0
  113. package/drizzle/0266_company_brain_context_receipt_inspection.sql +156 -0
  114. package/drizzle/0268_governed_learning_decision_receipts.sql +825 -0
  115. package/drizzle/0269_governed_learning_activation_controller.sql +1874 -0
  116. package/drizzle/0270_governed_learning_history_inspection.sql +170 -0
  117. package/drizzle/0271_company_brain_retrieval_only_default.sql +524 -0
  118. package/drizzle/0272_human_confirmed_learning_activation.sql +591 -0
  119. package/drizzle/0273_scheduled_variable_set_materialization.sql +268 -0
  120. package/drizzle/0274_human_confirmed_knowledge_review.sql +310 -0
  121. package/drizzle/0275_scheduled_connection_authority.sql +5527 -0
  122. package/drizzle/0276_onboarding_proposal_initiating_human_guc.sql +198 -0
  123. package/drizzle/0277_workspace_writer_authority_attribution.sql +393 -0
  124. package/drizzle/0278_workspace_membership_removal_fencing.sql +1174 -0
  125. package/drizzle/0279_workspace_connection_use_lane.sql +343 -0
  126. package/drizzle/0280_connection_and_variable_set_audit_attribution.sql +773 -0
  127. package/drizzle/0281_viewer_holder_authority_claims.sql +52 -0
  128. package/drizzle/0282_variable_set_session_attach_attribution.sql +178 -0
  129. package/drizzle/0283_editable_spreadsheet_authored_state.sql +82 -0
  130. package/drizzle/0284_truthful_human_confirmed_review_reason.sql +930 -0
  131. package/drizzle/0285_organization_tenancy_inventory.sql +329 -0
  132. package/drizzle/0286_widen_task_note_expiry_ceiling.sql +391 -0
  133. package/drizzle/0287_open_suffix_pending_tool_calls.sql +18 -0
  134. package/drizzle/0288_attached_browser_reenrollment.sql +64 -0
  135. package/drizzle/0289_session_composer_policy_authority.sql +597 -0
  136. package/drizzle/0290_organization_membership_backfill.sql +268 -0
  137. package/drizzle/0291_resource_authority_classification_assertion.sql +371 -0
  138. package/drizzle/0292_truthful_tenancy_inventory_counters.sql +291 -0
  139. package/drizzle/0293_confirm_time_rule_rebaseline.sql +615 -0
  140. package/drizzle/0294_preference_activation_authority.sql +237 -0
  141. package/drizzle/0295_retire_legacy_standing_memory_mode.sql +476 -0
  142. package/drizzle/0296_force_rls_backfill_noop_repair.sql +215 -0
  143. package/drizzle/0297_session_ownership_classification_and_backfill.sql +752 -0
  144. package/drizzle/0298_organization_tenancy_parity.sql +609 -0
  145. package/drizzle/0299_organization_membership_lock_order.sql +291 -0
  146. package/drizzle/0300_tenancy_backfill_ledger.sql +459 -0
  147. package/drizzle/0301_session_snapshot_and_pin_visibility.sql +181 -0
  148. package/drizzle/0302_personal_workspace_session_ownership.sql +303 -0
  149. package/drizzle/0303_session_tenancy_product_activation.sql +919 -0
  150. package/drizzle/0304_personal_workspace_private_session_reads.sql +97 -0
  151. package/drizzle/0305_personal_resource_grant_management.sql +584 -0
  152. package/drizzle/0306_atomic_personal_resource_attachments.sql +1374 -0
  153. package/drizzle/0307_session_attention_state.sql +51 -0
  154. package/drizzle/0308_session_archives.sql +35 -0
  155. package/drizzle/0309_channel_project_pins.sql +6 -0
  156. package/drizzle/0310_channel_project_order.sql +27 -0
  157. package/drizzle/0311_company_scope_and_private_session_create.sql +656 -0
  158. package/drizzle/0312_quiescent_session_tree_deletion.sql +39 -0
  159. package/drizzle/0313_private_child_session_authority.sql +365 -0
  160. package/drizzle/0314_unregistered_organization_invitations.sql +606 -0
  161. package/drizzle/0315_personal_github_repository_selection.sql +624 -0
  162. package/drizzle/0316_human_confirmed_activation_resumed_generation.sql +869 -0
  163. package/drizzle/0317_session_goal_continuation_hold.sql +64 -0
  164. package/drizzle/0318_session_turn_startup_milestones.sql +115 -0
  165. package/drizzle/0319_event_triggered_automations.sql +254 -0
  166. package/drizzle/0320_pr_review_pack.sql +113 -0
  167. package/drizzle/0321_slack_bot_environment_display_name.sql +15 -0
  168. package/drizzle/0322_session_turns_unclaimed_prompt_trigger_index.sql +5 -0
  169. package/drizzle/0323_organization_private_session_enablement.sql +489 -0
  170. package/drizzle/0324_human_confirmed_company_profile_agent_admin.sql +856 -0
  171. package/drizzle/0325_child_lifecycle_notices.sql +44 -0
  172. package/drizzle/0326_interaction_operation_error_codes.sql +62 -0
  173. package/drizzle/0327_slack_first_task_hint.sql +29 -0
  174. package/drizzle/0328_session_background_commands.sql +590 -0
  175. package/drizzle/0329_slack_orchestration_delivery_events.sql +91 -0
  176. package/drizzle/0330_api_key_descriptions.sql +20 -0
  177. package/drizzle/0331_managed_organization_creation.sql +163 -0
  178. package/drizzle/0332_organization_shared_workspace_control_plane.sql +539 -0
  179. package/drizzle/0333_session_turn_prompt_routing.sql +45 -0
  180. package/drizzle/0334_connected_machine_workspace_root.sql +99 -0
  181. package/drizzle/0335_slack_workspace_routing.sql +460 -0
  182. package/drizzle/0336_atomic_session_fork_visibility.sql +667 -0
  183. package/drizzle/0337_slack_routed_action_handles.sql +189 -0
  184. package/drizzle/0338_atomic_connected_machine_attachments.sql +410 -0
  185. package/drizzle/0339_document_authority_reclassification.sql +1153 -0
  186. package/drizzle/0340_tenancy_backfill_activation_evidence.sql +1347 -0
  187. package/drizzle/0341_slack_routing_probe_organization_fence.sql +109 -0
  188. package/drizzle/0342_slack_route_prompt_single_pending.sql +32 -0
  189. package/drizzle/0343_personal_document_force_rls_lock_repair.sql +146 -0
  190. package/drizzle/0344_private_session_visibility_transition_gate.sql +85 -0
  191. package/drizzle/0345_tenant_scoped_session_tenancy_fence.sql +2839 -0
  192. package/drizzle/0346_document_migration_audit_surface.sql +454 -0
  193. package/drizzle/0347_connection_authority_convergence_evidence.sql +396 -0
  194. package/package.json +10 -6
  195. package/src/attached-browser-devices.ts +233 -5
  196. package/src/automations.ts +911 -0
  197. package/src/browser-sessions.ts +10 -0
  198. package/src/capability-integrations.ts +175 -1
  199. package/src/child-lifecycle-notices.ts +241 -0
  200. package/src/codemode-operations.ts +1 -35
  201. package/src/company-brain-context-selection-schema.ts +100 -0
  202. package/src/company-brain-context-selection.ts +359 -0
  203. package/src/company-brain-governed-writes.ts +1170 -0
  204. package/src/company-brain.ts +309 -0
  205. package/src/company-profile-agent-admin.ts +225 -0
  206. package/src/company-profile-schema.ts +121 -1
  207. package/src/company-profile.ts +21 -0
  208. package/src/computer-sessions.ts +10 -1
  209. package/src/connection-authority.ts +290 -0
  210. package/src/connection-scopes.ts +20 -0
  211. package/src/connection-tenancy-backfill.ts +167 -0
  212. package/src/connection-token-resolver.ts +263 -31
  213. package/src/database.ts +87 -2
  214. package/src/editable-artifacts-schema.ts +10 -5
  215. package/src/editable-artifacts.ts +21 -11
  216. package/src/governed-learning-activation-schema.ts +121 -0
  217. package/src/governed-learning-activation.ts +588 -0
  218. package/src/governed-learning-evaluator-schema.ts +72 -0
  219. package/src/governed-learning-evaluator.ts +217 -0
  220. package/src/index.ts +11676 -1550
  221. package/src/insights.ts +107 -0
  222. package/src/integration-bindings.ts +88 -6
  223. package/src/integration-facets.ts +287 -84
  224. package/src/interaction-placement-loss.ts +234 -0
  225. package/src/managed-human-provisioning.ts +116 -0
  226. package/src/memory-domain.ts +27 -32
  227. package/src/migrate.ts +77 -1
  228. package/src/new-session-drafts.ts +229 -35
  229. package/src/organization-membership-backfill.ts +735 -0
  230. package/src/organization-membership-lifecycle.ts +995 -0
  231. package/src/pr-review.ts +890 -0
  232. package/src/preference-registry.ts +31 -1
  233. package/src/provision-roles.ts +905 -6
  234. package/src/runtime-posture-cli.ts +2 -0
  235. package/src/runtime-posture.ts +1317 -72
  236. package/src/schema.ts +3316 -428
  237. package/src/scoped-knowledge-schema.ts +16 -8
  238. package/src/scoped-knowledge.ts +1 -1
  239. package/src/session-background-commands.ts +759 -0
  240. package/src/session-control.ts +640 -74
  241. package/src/session-goal-pacing.ts +126 -0
  242. package/src/session-queue-commands.ts +441 -85
  243. package/src/session-realtime-context.ts +4 -6
  244. package/src/session-realtime-ledger.ts +28 -14
  245. package/src/session-realtime-mirror.ts +1 -1
  246. package/src/session-tenancy.ts +410 -49
  247. package/src/session-tool-call-settlement.ts +38 -29
  248. package/src/slack-routing-personal-workspace.ts +67 -0
  249. package/src/slack-routing.ts +867 -0
  250. package/src/slack-task-policy-schema.ts +5 -0
  251. package/src/slack-task-policy.ts +18 -0
  252. package/src/slack-user-link-access.ts +138 -11
  253. package/src/task-notes-schema.ts +74 -0
  254. package/src/task-notes.ts +124 -2
  255. package/src/turn-initiator.ts +8 -0
  256. package/src/user-resource-authority.ts +377 -0
  257. package/src/workspace-authority.ts +160 -0
  258. package/src/workspace-instruction-policies-schema.ts +53 -1
  259. package/src/workspace-instruction-policies.ts +528 -77
  260. package/src/workspace-learning-policy.ts +21 -5
  261. package/src/workspace-membership-permissions.ts +9 -0
  262. package/dist/chunk-4SR4HKKA.js.map +0 -1
  263. package/dist/chunk-6ZYKCRFO.js.map +0 -1
  264. package/dist/chunk-NXAFLCQX.js +0 -2468
  265. package/dist/chunk-NXAFLCQX.js.map +0 -1
  266. package/dist/chunk-SK7YYHBI.js.map +0 -1
  267. package/dist/chunk-WD5ROSLL.js +0 -117
  268. package/dist/chunk-WD5ROSLL.js.map +0 -1
  269. package/dist/chunk-ZWREYEWA.js.map +0 -1
  270. /package/dist/{chunk-CUPM3FGB.js.map → chunk-2PRS4J5Q.js.map} +0 -0
  271. /package/dist/{chunk-LTG3S6ZY.js.map → chunk-E6CLMKEE.js.map} +0 -0
@@ -0,0 +1,365 @@
1
+ -- deployment-mode: rolling
2
+ -- Lets one exact live attempt of a private session create one private child.
3
+ -- The capability is transaction-local, target-bound, and cannot authorize an
4
+ -- UPDATE or a second/multi-row INSERT.
5
+
6
+ SET LOCAL lock_timeout = '5s';
7
+ SET LOCAL statement_timeout = '10min';
8
+
9
+ ALTER TABLE private_session_create_capabilities
10
+ ADD COLUMN parent_session_id uuid,
11
+ ADD COLUMN actor_turn_id uuid,
12
+ ADD COLUMN actor_attempt_id uuid,
13
+ ADD COLUMN actor_execution_generation integer,
14
+ ADD CONSTRAINT private_session_create_capability_lane_check CHECK (
15
+ (parent_session_id IS NULL
16
+ AND actor_turn_id IS NULL
17
+ AND actor_attempt_id IS NULL
18
+ AND actor_execution_generation IS NULL)
19
+ OR
20
+ (parent_session_id IS NOT NULL
21
+ AND actor_turn_id IS NOT NULL
22
+ AND actor_attempt_id IS NOT NULL
23
+ AND actor_execution_generation > 0)
24
+ );
25
+
26
+ CREATE FUNCTION open_private_child_session_create_capability(
27
+ p_account_id uuid,
28
+ p_workspace_id uuid,
29
+ p_session_id uuid,
30
+ p_parent_session_id uuid,
31
+ p_actor_turn_id uuid,
32
+ p_actor_attempt_id uuid,
33
+ p_actor_execution_generation integer
34
+ ) RETURNS TABLE (
35
+ capability_id uuid,
36
+ owner_membership_id uuid,
37
+ owner_subject_id text
38
+ )
39
+ LANGUAGE plpgsql SECURITY DEFINER
40
+ SET search_path FROM CURRENT
41
+ AS $body$
42
+ DECLARE
43
+ new_capability_id uuid := gen_random_uuid();
44
+ parent_row sessions%ROWTYPE;
45
+ owner_membership organization_memberships%ROWTYPE;
46
+ owner_workspace_access_id uuid;
47
+ actor_human_subject_id text;
48
+ actor_interrupted boolean;
49
+ BEGIN
50
+ IF p_account_id IS NULL OR p_workspace_id IS NULL OR p_session_id IS NULL
51
+ OR p_parent_session_id IS NULL OR p_actor_turn_id IS NULL
52
+ OR p_actor_attempt_id IS NULL OR p_actor_execution_generation IS NULL
53
+ OR p_actor_execution_generation < 1
54
+ OR p_session_id = p_parent_session_id
55
+ OR p_account_id IS DISTINCT FROM opengeni_private.current_account_id()
56
+ OR p_workspace_id IS DISTINCT FROM opengeni_private.current_workspace_id()
57
+ OR NOT session_tenancy_product_activated(p_account_id, 1)
58
+ THEN
59
+ RAISE EXCEPTION 'private child session create authority required'
60
+ USING ERRCODE = '42501';
61
+ END IF;
62
+
63
+ PERFORM 1 FROM workspace_inference_controls control
64
+ WHERE control.account_id = p_account_id AND control.workspace_id = p_workspace_id
65
+ FOR SHARE;
66
+ PERFORM 1 FROM workspaces workspace
67
+ WHERE workspace.account_id = p_account_id AND workspace.id = p_workspace_id
68
+ FOR KEY SHARE;
69
+
70
+ SELECT parent.* INTO parent_row
71
+ FROM sessions parent
72
+ WHERE parent.account_id = p_account_id
73
+ AND parent.workspace_id = p_workspace_id
74
+ AND parent.id = p_parent_session_id
75
+ FOR NO KEY UPDATE;
76
+ IF NOT FOUND
77
+ OR parent_row.visibility <> 'user_private'
78
+ OR parent_row.owner_organization_membership_id IS NULL
79
+ OR parent_row.owner_subject_id IS NULL
80
+ OR parent_row.active_turn_id IS DISTINCT FROM p_actor_turn_id
81
+ THEN
82
+ RAISE EXCEPTION 'private child session create authority required'
83
+ USING ERRCODE = '42501';
84
+ END IF;
85
+
86
+ SELECT membership.* INTO owner_membership
87
+ FROM organization_memberships membership
88
+ WHERE membership.id = parent_row.owner_organization_membership_id
89
+ AND membership.account_id = p_account_id
90
+ AND membership.subject_id = parent_row.owner_subject_id
91
+ AND membership.status = 'active'
92
+ FOR KEY SHARE;
93
+ IF NOT FOUND THEN
94
+ RAISE EXCEPTION 'private child session owner authority is no longer active'
95
+ USING ERRCODE = '42501';
96
+ END IF;
97
+ IF NOT (
98
+ owner_membership.subject_id LIKE 'user:%'
99
+ AND owner_membership.personal_workspace_id = p_workspace_id
100
+ ) THEN
101
+ -- Match the top-level private-create lock prefix: in an ordinary shared
102
+ -- workspace the exact access row is authority, so hold it through INSERT.
103
+ SELECT access.id INTO owner_workspace_access_id
104
+ FROM workspace_memberships access
105
+ WHERE access.account_id = p_account_id
106
+ AND access.workspace_id = p_workspace_id
107
+ AND access.subject_id = owner_membership.subject_id
108
+ FOR KEY SHARE;
109
+ IF NOT FOUND THEN
110
+ RAISE EXCEPTION 'private child session owner authority is no longer active'
111
+ USING ERRCODE = '42501';
112
+ END IF;
113
+ END IF;
114
+
115
+ SELECT
116
+ coalesce(
117
+ turn_row.initiating_human_subject_id,
118
+ CASE WHEN turn_row.initiator_kind = 'subject'
119
+ THEN turn_row.initiator_subject_id ELSE NULL END
120
+ ),
121
+ EXISTS (
122
+ SELECT 1 FROM session_attempt_interruptions interruption
123
+ WHERE interruption.workspace_id = p_workspace_id
124
+ AND interruption.attempt_id = p_actor_attempt_id
125
+ AND interruption.state IN ('pending', 'delivered', 'acknowledged')
126
+ )
127
+ INTO actor_human_subject_id, actor_interrupted
128
+ FROM session_turns turn_row
129
+ JOIN session_turn_attempts attempt
130
+ ON attempt.workspace_id = turn_row.workspace_id
131
+ AND attempt.session_id = turn_row.session_id
132
+ AND attempt.turn_id = turn_row.id
133
+ WHERE turn_row.account_id = p_account_id
134
+ AND turn_row.workspace_id = p_workspace_id
135
+ AND turn_row.session_id = p_parent_session_id
136
+ AND turn_row.id = p_actor_turn_id
137
+ AND turn_row.active_attempt_id = p_actor_attempt_id
138
+ AND turn_row.execution_generation = p_actor_execution_generation
139
+ AND turn_row.status IN ('running', 'requires_action', 'recovering', 'waiting_capacity')
140
+ AND attempt.id = p_actor_attempt_id
141
+ AND attempt.execution_generation = p_actor_execution_generation
142
+ AND attempt.state IN ('claimed', 'running')
143
+ FOR UPDATE OF turn_row, attempt;
144
+ IF NOT FOUND OR actor_interrupted
145
+ OR actor_human_subject_id IS DISTINCT FROM parent_row.owner_subject_id
146
+ THEN
147
+ RAISE EXCEPTION 'private child session create attempt is stale or unauthorized'
148
+ USING ERRCODE = '42501';
149
+ END IF;
150
+
151
+ PERFORM pg_catalog.set_config(
152
+ 'opengeni.private_session_create_lifecycle', 'private_session_create', true
153
+ );
154
+ INSERT INTO private_session_create_capabilities (
155
+ backend_pid, transaction_id, capability_id, account_id, workspace_id,
156
+ session_id, actor_subject_id, owner_membership_id, parent_session_id,
157
+ actor_turn_id, actor_attempt_id, actor_execution_generation
158
+ ) VALUES (
159
+ pg_backend_pid(), pg_current_xact_id(), new_capability_id, p_account_id,
160
+ p_workspace_id, p_session_id, parent_row.owner_subject_id,
161
+ parent_row.owner_organization_membership_id, p_parent_session_id,
162
+ p_actor_turn_id, p_actor_attempt_id, p_actor_execution_generation
163
+ );
164
+ INSERT INTO session_visibility_write_capabilities (
165
+ backend_pid, transaction_id, capability_id
166
+ ) VALUES (pg_backend_pid(), pg_current_xact_id(), new_capability_id);
167
+ PERFORM pg_catalog.set_config(
168
+ 'opengeni.private_child_session_create_capability', new_capability_id::text, true
169
+ );
170
+ PERFORM pg_catalog.set_config(
171
+ 'opengeni.session_visibility_write_capability', new_capability_id::text, true
172
+ );
173
+ capability_id := new_capability_id;
174
+ owner_membership_id := parent_row.owner_organization_membership_id;
175
+ owner_subject_id := parent_row.owner_subject_id;
176
+ RETURN NEXT;
177
+ END
178
+ $body$;
179
+
180
+ CREATE OR REPLACE FUNCTION close_private_session_create_capability(p_capability_id uuid)
181
+ RETURNS void
182
+ LANGUAGE plpgsql SECURITY DEFINER
183
+ SET search_path FROM CURRENT
184
+ AS $body$
185
+ BEGIN
186
+ PERFORM pg_catalog.set_config(
187
+ 'opengeni.private_session_create_lifecycle', 'private_session_create', true
188
+ );
189
+ DELETE FROM private_session_create_capabilities capability
190
+ WHERE capability.backend_pid = pg_backend_pid()
191
+ AND capability.transaction_id = pg_current_xact_id()
192
+ AND capability.capability_id = p_capability_id;
193
+ DELETE FROM session_visibility_write_capabilities capability
194
+ WHERE capability.backend_pid = pg_backend_pid()
195
+ AND capability.transaction_id = pg_current_xact_id()
196
+ AND capability.capability_id = p_capability_id;
197
+ PERFORM pg_catalog.set_config('opengeni.private_session_create_capability', '', true);
198
+ PERFORM pg_catalog.set_config('opengeni.private_child_session_create_capability', '', true);
199
+ PERFORM pg_catalog.set_config('opengeni.session_visibility_write_capability', '', true);
200
+ END
201
+ $body$;
202
+
203
+ CREATE FUNCTION guard_private_child_session_create()
204
+ RETURNS trigger
205
+ LANGUAGE plpgsql SECURITY DEFINER
206
+ SET search_path FROM CURRENT
207
+ AS $body$
208
+ DECLARE
209
+ child_capability private_session_create_capabilities%ROWTYPE;
210
+ parent_sandbox_group_id uuid;
211
+ BEGIN
212
+ IF nullif(pg_catalog.current_setting(
213
+ 'opengeni.private_child_session_create_capability', true
214
+ ), '') IS NULL THEN
215
+ RETURN NEW;
216
+ END IF;
217
+ IF TG_OP <> 'INSERT' THEN
218
+ RAISE EXCEPTION 'private child create capability cannot authorize session updates'
219
+ USING ERRCODE = '42501';
220
+ END IF;
221
+ PERFORM pg_catalog.set_config(
222
+ 'opengeni.private_session_create_lifecycle', 'private_session_create', true
223
+ );
224
+ SELECT capability.* INTO child_capability
225
+ FROM private_session_create_capabilities capability
226
+ WHERE capability.backend_pid = pg_catalog.pg_backend_pid()
227
+ AND capability.transaction_id = pg_catalog.pg_current_xact_id()
228
+ AND capability.capability_id = nullif(pg_catalog.current_setting(
229
+ 'opengeni.private_child_session_create_capability', true
230
+ ), '')::uuid;
231
+ IF NOT FOUND OR child_capability.parent_session_id IS NULL THEN
232
+ RAISE EXCEPTION 'private child create capability is unavailable'
233
+ USING ERRCODE = '42501';
234
+ END IF;
235
+ SELECT parent.sandbox_group_id INTO parent_sandbox_group_id
236
+ FROM sessions parent
237
+ WHERE parent.account_id = NEW.account_id
238
+ AND parent.workspace_id = NEW.workspace_id
239
+ AND parent.id = child_capability.parent_session_id;
240
+ IF NOT FOUND
241
+ OR child_capability.account_id IS DISTINCT FROM NEW.account_id
242
+ OR child_capability.workspace_id IS DISTINCT FROM NEW.workspace_id
243
+ OR child_capability.session_id IS DISTINCT FROM NEW.id
244
+ OR child_capability.parent_session_id IS DISTINCT FROM NEW.parent_session_id
245
+ OR child_capability.actor_subject_id IS DISTINCT FROM NEW.created_by_subject_id
246
+ OR child_capability.owner_membership_id
247
+ IS DISTINCT FROM NEW.owner_organization_membership_id
248
+ OR child_capability.actor_subject_id IS DISTINCT FROM NEW.owner_subject_id
249
+ OR NEW.created_by_kind <> 'subject'
250
+ OR NEW.visibility <> 'user_private'
251
+ OR NEW.create_requested_visibility <> 'user_private'
252
+ OR NEW.authority_epoch <> 1
253
+ OR NEW.sandbox_group_id IS NULL
254
+ OR (
255
+ NEW.sandbox_group_id IS DISTINCT FROM NEW.id
256
+ AND NEW.sandbox_group_id IS DISTINCT FROM parent_sandbox_group_id
257
+ )
258
+ OR NEW.forked_from_session_id IS NOT NULL
259
+ OR NEW.forked_from_authority_epoch IS NOT NULL
260
+ OR NEW.forked_from_visibility IS NOT NULL
261
+ OR NEW.forked_at IS NOT NULL
262
+ OR NEW.forked_by_organization_membership_id IS NOT NULL
263
+ THEN
264
+ RAISE EXCEPTION 'private child session insert does not match its exact capability'
265
+ USING ERRCODE = '42501';
266
+ END IF;
267
+ RETURN NEW;
268
+ END
269
+ $body$;
270
+
271
+ CREATE FUNCTION fence_child_session_authority()
272
+ RETURNS trigger
273
+ LANGUAGE plpgsql SECURITY DEFINER
274
+ SET search_path FROM CURRENT
275
+ AS $body$
276
+ DECLARE
277
+ parent_visibility text;
278
+ parent_owner_membership_id uuid;
279
+ parent_owner_subject_id text;
280
+ BEGIN
281
+ IF NEW.parent_session_id IS NULL THEN
282
+ RETURN NEW;
283
+ END IF;
284
+ -- The row lock closes the core-read/insert race with a concurrent visibility
285
+ -- transition. It is held through child INSERT and follows the existing
286
+ -- workspace -> parent ordering used by session creation.
287
+ SELECT parent.visibility,
288
+ parent.owner_organization_membership_id,
289
+ parent.owner_subject_id
290
+ INTO parent_visibility, parent_owner_membership_id, parent_owner_subject_id
291
+ FROM sessions parent
292
+ WHERE parent.account_id = NEW.account_id
293
+ AND parent.workspace_id = NEW.workspace_id
294
+ AND parent.id = NEW.parent_session_id
295
+ FOR SHARE;
296
+ IF NOT FOUND
297
+ OR NEW.visibility IS DISTINCT FROM parent_visibility
298
+ OR NEW.create_requested_visibility IS DISTINCT FROM parent_visibility
299
+ OR (
300
+ parent_visibility = 'user_private'
301
+ AND (
302
+ NEW.owner_organization_membership_id IS DISTINCT FROM parent_owner_membership_id
303
+ OR NEW.owner_subject_id IS DISTINCT FROM parent_owner_subject_id
304
+ )
305
+ )
306
+ THEN
307
+ RAISE EXCEPTION 'child session authority must match its locked parent'
308
+ USING ERRCODE = '42501';
309
+ END IF;
310
+ RETURN NEW;
311
+ END
312
+ $body$;
313
+
314
+ DROP TRIGGER IF EXISTS session_00_private_child_create_fence ON sessions;
315
+ CREATE TRIGGER session_00_private_child_create_fence
316
+ BEFORE INSERT OR UPDATE ON sessions
317
+ FOR EACH ROW EXECUTE FUNCTION guard_private_child_session_create();
318
+
319
+ DROP TRIGGER IF EXISTS sessions_child_authority_fence ON sessions;
320
+ CREATE TRIGGER sessions_child_authority_fence
321
+ BEFORE INSERT ON sessions
322
+ FOR EACH ROW EXECUTE FUNCTION fence_child_session_authority();
323
+
324
+ REVOKE ALL ON FUNCTION open_private_child_session_create_capability(
325
+ uuid,uuid,uuid,uuid,uuid,uuid,integer
326
+ ) FROM PUBLIC;
327
+ REVOKE ALL ON FUNCTION close_private_session_create_capability(uuid) FROM PUBLIC;
328
+ REVOKE ALL ON FUNCTION guard_private_child_session_create() FROM PUBLIC;
329
+ REVOKE ALL ON FUNCTION fence_child_session_authority() FROM PUBLIC;
330
+
331
+ DO $pin_and_grant$
332
+ DECLARE data_schema text := current_schema();
333
+ BEGIN
334
+ EXECUTE format(
335
+ 'ALTER FUNCTION %I.open_private_child_session_create_capability(uuid,uuid,uuid,uuid,uuid,uuid,integer) SET search_path = pg_catalog, %I, pg_temp',
336
+ data_schema, data_schema
337
+ );
338
+ EXECUTE format(
339
+ 'ALTER FUNCTION %I.close_private_session_create_capability(uuid) SET search_path = pg_catalog, %I, pg_temp',
340
+ data_schema, data_schema
341
+ );
342
+ EXECUTE format(
343
+ 'ALTER FUNCTION %I.guard_private_child_session_create() SET search_path = pg_catalog, %I, pg_temp',
344
+ data_schema, data_schema
345
+ );
346
+ EXECUTE format(
347
+ 'ALTER FUNCTION %I.fence_child_session_authority() SET search_path = pg_catalog, %I, pg_temp',
348
+ data_schema, data_schema
349
+ );
350
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
351
+ EXECUTE format(
352
+ 'GRANT EXECUTE ON FUNCTION %I.open_private_child_session_create_capability(uuid,uuid,uuid,uuid,uuid,uuid,integer) TO opengeni_app',
353
+ data_schema
354
+ );
355
+ EXECUTE format(
356
+ 'GRANT EXECUTE ON FUNCTION %I.close_private_session_create_capability(uuid) TO opengeni_app',
357
+ data_schema
358
+ );
359
+ END IF;
360
+ END
361
+ $pin_and_grant$;
362
+
363
+ COMMENT ON FUNCTION open_private_child_session_create_capability(
364
+ uuid,uuid,uuid,uuid,uuid,uuid,integer
365
+ ) IS 'One exact live private-parent attempt may insert one same-owner private child.';