@opengeni/db 1.0.1 → 3.1.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 (265) 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-LTG3S6ZY.js → chunk-EULAN2NP.js} +2 -2
  7. package/dist/{chunk-CUPM3FGB.js → chunk-NJVZPWXY.js} +3 -3
  8. package/dist/{chunk-4SR4HKKA.js → chunk-NMUBV7Z5.js} +19 -11
  9. package/dist/chunk-NMUBV7Z5.js.map +1 -0
  10. package/dist/chunk-OF5OBB76.js +4457 -0
  11. package/dist/chunk-OF5OBB76.js.map +1 -0
  12. package/dist/{chunk-6ZYKCRFO.js → chunk-PR2WMLOQ.js} +7580 -4417
  13. package/dist/chunk-PR2WMLOQ.js.map +1 -0
  14. package/dist/{chunk-ZWREYEWA.js → chunk-SCPUJS53.js} +41 -4
  15. package/dist/chunk-SCPUJS53.js.map +1 -0
  16. package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
  17. package/dist/chunk-SIBYBA2D.js.map +1 -0
  18. package/dist/chunk-TIKF3KTI.js +383 -0
  19. package/dist/chunk-TIKF3KTI.js.map +1 -0
  20. package/dist/chunk-ZZ5LJEFX.js +516 -0
  21. package/dist/chunk-ZZ5LJEFX.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 +41 -0
  33. package/dist/connection-token-resolver.d.ts +30 -1
  34. package/dist/database.d.ts +19 -0
  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 +1595 -81
  43. package/dist/index.js +21571 -8126
  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 +22 -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 +41 -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 +153 -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 +1 -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/package.json +10 -6
  189. package/src/attached-browser-devices.ts +233 -5
  190. package/src/automations.ts +911 -0
  191. package/src/browser-sessions.ts +10 -0
  192. package/src/capability-integrations.ts +175 -1
  193. package/src/child-lifecycle-notices.ts +241 -0
  194. package/src/codemode-operations.ts +1 -35
  195. package/src/company-brain-context-selection-schema.ts +100 -0
  196. package/src/company-brain-context-selection.ts +359 -0
  197. package/src/company-brain-governed-writes.ts +1170 -0
  198. package/src/company-brain.ts +309 -0
  199. package/src/company-profile-agent-admin.ts +225 -0
  200. package/src/company-profile-schema.ts +121 -1
  201. package/src/company-profile.ts +21 -0
  202. package/src/computer-sessions.ts +10 -1
  203. package/src/connection-authority.ts +290 -0
  204. package/src/connection-scopes.ts +20 -0
  205. package/src/connection-tenancy-backfill.ts +81 -0
  206. package/src/connection-token-resolver.ts +263 -31
  207. package/src/database.ts +75 -2
  208. package/src/editable-artifacts-schema.ts +10 -5
  209. package/src/editable-artifacts.ts +21 -11
  210. package/src/governed-learning-activation-schema.ts +121 -0
  211. package/src/governed-learning-activation.ts +588 -0
  212. package/src/governed-learning-evaluator-schema.ts +72 -0
  213. package/src/governed-learning-evaluator.ts +217 -0
  214. package/src/index.ts +11651 -1548
  215. package/src/insights.ts +107 -0
  216. package/src/integration-bindings.ts +88 -6
  217. package/src/integration-facets.ts +287 -84
  218. package/src/interaction-placement-loss.ts +234 -0
  219. package/src/managed-human-provisioning.ts +116 -0
  220. package/src/memory-domain.ts +27 -32
  221. package/src/migrate.ts +77 -1
  222. package/src/new-session-drafts.ts +229 -35
  223. package/src/organization-membership-backfill.ts +735 -0
  224. package/src/organization-membership-lifecycle.ts +985 -0
  225. package/src/pr-review.ts +890 -0
  226. package/src/preference-registry.ts +31 -1
  227. package/src/provision-roles.ts +877 -6
  228. package/src/runtime-posture-cli.ts +2 -0
  229. package/src/runtime-posture.ts +1291 -76
  230. package/src/schema.ts +3303 -428
  231. package/src/scoped-knowledge-schema.ts +16 -8
  232. package/src/scoped-knowledge.ts +1 -1
  233. package/src/session-background-commands.ts +759 -0
  234. package/src/session-control.ts +640 -74
  235. package/src/session-goal-pacing.ts +126 -0
  236. package/src/session-queue-commands.ts +437 -84
  237. package/src/session-realtime-context.ts +3 -3
  238. package/src/session-realtime-ledger.ts +22 -11
  239. package/src/session-realtime-mirror.ts +1 -1
  240. package/src/session-tenancy.ts +403 -49
  241. package/src/session-tool-call-settlement.ts +38 -29
  242. package/src/slack-routing-personal-workspace.ts +67 -0
  243. package/src/slack-routing.ts +469 -0
  244. package/src/slack-task-policy-schema.ts +5 -0
  245. package/src/slack-task-policy.ts +18 -0
  246. package/src/slack-user-link-access.ts +17 -1
  247. package/src/task-notes-schema.ts +74 -0
  248. package/src/task-notes.ts +124 -2
  249. package/src/turn-initiator.ts +8 -0
  250. package/src/user-resource-authority.ts +377 -0
  251. package/src/workspace-authority.ts +160 -0
  252. package/src/workspace-instruction-policies-schema.ts +53 -1
  253. package/src/workspace-instruction-policies.ts +528 -77
  254. package/src/workspace-learning-policy.ts +21 -5
  255. package/src/workspace-membership-permissions.ts +9 -0
  256. package/dist/chunk-4SR4HKKA.js.map +0 -1
  257. package/dist/chunk-6ZYKCRFO.js.map +0 -1
  258. package/dist/chunk-NXAFLCQX.js +0 -2468
  259. package/dist/chunk-NXAFLCQX.js.map +0 -1
  260. package/dist/chunk-SK7YYHBI.js.map +0 -1
  261. package/dist/chunk-WD5ROSLL.js +0 -117
  262. package/dist/chunk-WD5ROSLL.js.map +0 -1
  263. package/dist/chunk-ZWREYEWA.js.map +0 -1
  264. /package/dist/{chunk-LTG3S6ZY.js.map → chunk-EULAN2NP.js.map} +0 -0
  265. /package/dist/{chunk-CUPM3FGB.js.map → chunk-NJVZPWXY.js.map} +0 -0
@@ -0,0 +1,597 @@
1
+ -- deployment-mode: maintenance
2
+ -- One-way authority cutover: session-default reasoning and latency become typed
3
+ -- columns. Established-session composer drafts and queued turns remain separate
4
+ -- exact authorities; metadata is no longer consulted for execution policy.
5
+
6
+ SET LOCAL lock_timeout = '5s';
7
+ SET LOCAL statement_timeout = '10min';
8
+
9
+ DO $session_policy_writer_drain_before_lock$
10
+ BEGIN
11
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app')
12
+ AND EXISTS (
13
+ SELECT 1
14
+ FROM pg_stat_activity
15
+ WHERE datname = current_database()
16
+ AND usename = 'opengeni_app'
17
+ AND pid <> pg_backend_pid()
18
+ )
19
+ THEN
20
+ RAISE EXCEPTION
21
+ 'session policy authority activation requires all opengeni_app sessions to be stopped'
22
+ USING ERRCODE = '55000';
23
+ END IF;
24
+ END
25
+ $session_policy_writer_drain_before_lock$;
26
+
27
+ LOCK TABLE "sessions" IN ACCESS EXCLUSIVE MODE;
28
+ LOCK TABLE "session_turns" IN SHARE MODE;
29
+
30
+ DO $session_policy_writer_drain_after_lock$
31
+ BEGIN
32
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app')
33
+ AND EXISTS (
34
+ SELECT 1
35
+ FROM pg_stat_activity
36
+ WHERE datname = current_database()
37
+ AND usename = 'opengeni_app'
38
+ AND pid <> pg_backend_pid()
39
+ )
40
+ THEN
41
+ RAISE EXCEPTION
42
+ 'session policy authority activation requires all opengeni_app sessions to be stopped'
43
+ USING ERRCODE = '55000';
44
+ END IF;
45
+ END
46
+ $session_policy_writer_drain_after_lock$;
47
+
48
+ ALTER TABLE "sessions"
49
+ ADD COLUMN "reasoning_effort" text,
50
+ ADD COLUMN "latency_mode" text;
51
+
52
+ UPDATE "sessions" AS session
53
+ SET
54
+ "reasoning_effort" = coalesce(
55
+ CASE
56
+ WHEN session."metadata" ->> 'reasoningEffort'
57
+ IN ('none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max')
58
+ THEN session."metadata" ->> 'reasoningEffort'
59
+ END,
60
+ (
61
+ SELECT turn."reasoning_effort"
62
+ FROM "session_turns" AS turn
63
+ WHERE turn."workspace_id" = session."workspace_id"
64
+ AND turn."session_id" = session."id"
65
+ ORDER BY turn."created_at", turn."id"
66
+ LIMIT 1
67
+ ),
68
+ 'medium'
69
+ ),
70
+ "latency_mode" = coalesce(
71
+ CASE
72
+ WHEN session."metadata" ->> 'latencyMode' IN ('standard', 'priority', 'fast')
73
+ THEN session."metadata" ->> 'latencyMode'
74
+ END,
75
+ (
76
+ SELECT turn."latency_mode"
77
+ FROM "session_turns" AS turn
78
+ WHERE turn."workspace_id" = session."workspace_id"
79
+ AND turn."session_id" = session."id"
80
+ ORDER BY turn."created_at", turn."id"
81
+ LIMIT 1
82
+ ),
83
+ 'standard'
84
+ );
85
+
86
+ ALTER TABLE "sessions"
87
+ ALTER COLUMN "reasoning_effort" SET NOT NULL,
88
+ ALTER COLUMN "latency_mode" SET NOT NULL,
89
+ ADD CONSTRAINT "sessions_reasoning_effort_check" CHECK (
90
+ "reasoning_effort" IN ('none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max')
91
+ ),
92
+ ADD CONSTRAINT "sessions_latency_mode_check" CHECK (
93
+ "latency_mode" IN ('standard', 'priority', 'fast')
94
+ );
95
+
96
+ -- Fork copies the exact source session policy. Do not invent defaults.
97
+ DO $session_fork_activation$
98
+ DECLARE
99
+ data_schema text := current_schema();
100
+ BEGIN
101
+ EXECUTE format($ddl$
102
+ CREATE OR REPLACE FUNCTION %1$I.fork_session_content(
103
+ p_account_id uuid,
104
+ p_source_workspace_id uuid,
105
+ p_source_session_id uuid,
106
+ p_actor_subject_id text,
107
+ p_destination_workspace_id uuid,
108
+ p_destination_visibility text,
109
+ p_operation_key text,
110
+ p_canonical_request_hash text
111
+ )
112
+ RETURNS TABLE (
113
+ operation_id uuid,
114
+ session_id uuid,
115
+ workspace_id uuid,
116
+ visibility text,
117
+ authority_epoch integer,
118
+ copied_history_item_count integer,
119
+ replay boolean
120
+ )
121
+ LANGUAGE plpgsql
122
+ SECURITY DEFINER
123
+ SET search_path = %1$I, pg_catalog
124
+ AS $body$
125
+ DECLARE
126
+ actor_membership organization_memberships%%ROWTYPE;
127
+ source_session sessions%%ROWTYPE;
128
+ destination_workspace workspaces%%ROWTYPE;
129
+ receipt_row session_command_receipts%%ROWTYPE;
130
+ destination_session_id uuid;
131
+ destination_owner_id uuid;
132
+ history_count integer := 0;
133
+ destination_activity_revision bigint;
134
+ destination_depth integer;
135
+ destination_depth_source text;
136
+ destination_resources jsonb := '[]'::jsonb;
137
+ previous_workspace_id text := pg_catalog.current_setting('opengeni.workspace_id', true);
138
+ previous_lifecycle_marker text := pg_catalog.current_setting(
139
+ 'opengeni.organization_tenancy_lifecycle', true
140
+ );
141
+ previous_gate_state text := pg_catalog.current_setting(
142
+ 'opengeni.session_activity_gate_state', true
143
+ );
144
+ previous_gate_workspace_id text := pg_catalog.current_setting(
145
+ 'opengeni.session_activity_gate_workspace_id', true
146
+ );
147
+ previous_visibility_marker text := pg_catalog.current_setting(
148
+ 'opengeni.session_visibility_write_capability', true
149
+ );
150
+ visibility_write_capability_id uuid := pg_catalog.gen_random_uuid();
151
+ BEGIN
152
+ IF p_account_id IS NULL OR p_source_workspace_id IS NULL
153
+ OR p_source_session_id IS NULL OR p_actor_subject_id IS NULL
154
+ OR p_destination_workspace_id IS NULL OR p_destination_visibility IS NULL
155
+ OR p_operation_key IS NULL OR p_canonical_request_hash IS NULL
156
+ THEN
157
+ RAISE EXCEPTION 'session fork requires complete authority'
158
+ USING ERRCODE = '42501';
159
+ END IF;
160
+ IF p_account_id IS DISTINCT FROM opengeni_private.current_account_id()
161
+ OR p_source_workspace_id IS DISTINCT FROM opengeni_private.current_workspace_id()
162
+ OR p_actor_subject_id IS DISTINCT FROM opengeni_private.current_subject_id()
163
+ THEN
164
+ RAISE EXCEPTION 'session fork authority is invalid'
165
+ USING ERRCODE = '42501';
166
+ END IF;
167
+ IF p_destination_visibility NOT IN ('user_private', 'workspace_shared')
168
+ OR p_actor_subject_id <> pg_catalog.btrim(p_actor_subject_id)
169
+ OR pg_catalog.length(p_actor_subject_id) NOT BETWEEN 1 AND 1024
170
+ OR p_operation_key <> pg_catalog.btrim(p_operation_key)
171
+ OR pg_catalog.length(p_operation_key) NOT BETWEEN 1 AND 1024
172
+ OR p_canonical_request_hash !~ '^[0-9a-f]{64}$'
173
+ THEN
174
+ RAISE EXCEPTION 'session fork request is invalid'
175
+ USING ERRCODE = '22023';
176
+ END IF;
177
+ IF nullif(previous_gate_state, '') IS NOT NULL
178
+ OR nullif(previous_gate_workspace_id, '') IS NOT NULL
179
+ THEN
180
+ RAISE EXCEPTION 'session fork requires ownership of the activity gate'
181
+ USING ERRCODE = '55000';
182
+ END IF;
183
+
184
+ PERFORM pg_catalog.pg_advisory_xact_lock(
185
+ pg_catalog.hashtext(
186
+ 'session-fork-workspace:' || ordered_workspaces.lock_workspace_id::text
187
+ )
188
+ )
189
+ FROM (
190
+ SELECT DISTINCT requested.lock_workspace_id
191
+ FROM (VALUES (p_source_workspace_id), (p_destination_workspace_id))
192
+ AS requested(lock_workspace_id)
193
+ ORDER BY requested.lock_workspace_id
194
+ ) AS ordered_workspaces;
195
+
196
+ PERFORM pg_catalog.set_config(
197
+ 'opengeni.workspace_id', p_source_workspace_id::text, true
198
+ );
199
+ PERFORM 1 FROM workspaces workspace_row
200
+ WHERE workspace_row.account_id = p_account_id
201
+ AND workspace_row.id = p_source_workspace_id
202
+ FOR UPDATE;
203
+ IF NOT FOUND THEN
204
+ RAISE EXCEPTION 'session fork source workspace is unavailable'
205
+ USING ERRCODE = '42501';
206
+ END IF;
207
+ PERFORM pg_catalog.set_config(
208
+ 'opengeni.workspace_id', p_destination_workspace_id::text, true
209
+ );
210
+ PERFORM 1 FROM workspaces workspace_row
211
+ WHERE workspace_row.account_id = p_account_id
212
+ AND workspace_row.id = p_destination_workspace_id
213
+ FOR UPDATE;
214
+ IF NOT FOUND THEN
215
+ RAISE EXCEPTION 'session fork destination workspace is unavailable'
216
+ USING ERRCODE = '42501';
217
+ END IF;
218
+
219
+ PERFORM pg_catalog.set_config(
220
+ 'opengeni.organization_tenancy_lifecycle',
221
+ 'session_visibility_activation',
222
+ true
223
+ );
224
+ SELECT membership.* INTO actor_membership
225
+ FROM organization_memberships membership
226
+ WHERE membership.account_id = p_account_id
227
+ AND membership.subject_id = p_actor_subject_id
228
+ AND membership.status = 'active'
229
+ FOR UPDATE;
230
+ IF NOT FOUND THEN
231
+ RAISE EXCEPTION 'session fork requires active organization membership'
232
+ USING ERRCODE = '42501';
233
+ END IF;
234
+
235
+ PERFORM pg_catalog.set_config(
236
+ 'opengeni.workspace_id', p_source_workspace_id::text, true
237
+ );
238
+ IF NOT EXISTS (
239
+ SELECT 1 FROM workspace_memberships source_access
240
+ WHERE source_access.account_id = p_account_id
241
+ AND source_access.workspace_id = p_source_workspace_id
242
+ AND source_access.subject_id = p_actor_subject_id
243
+ ) THEN
244
+ RAISE EXCEPTION 'session fork source workspace access is unavailable'
245
+ USING ERRCODE = '42501';
246
+ END IF;
247
+ SELECT session.* INTO source_session
248
+ FROM sessions session
249
+ WHERE session.account_id = p_account_id
250
+ AND session.workspace_id = p_source_workspace_id
251
+ AND session.id = p_source_session_id
252
+ FOR UPDATE;
253
+ IF NOT FOUND THEN
254
+ RAISE EXCEPTION 'session fork source session is unavailable'
255
+ USING ERRCODE = 'P0002';
256
+ END IF;
257
+ IF source_session.visibility = 'user_private'
258
+ AND source_session.owner_organization_membership_id <> actor_membership.id
259
+ THEN
260
+ RAISE EXCEPTION 'session fork source session is private'
261
+ USING ERRCODE = '42501';
262
+ END IF;
263
+
264
+ SELECT coalesce(
265
+ pg_catalog.jsonb_agg(
266
+ CASE WHEN resource.value ->> 'kind' = 'repository'
267
+ THEN resource.value
268
+ - 'credentialBindingId'
269
+ - 'connectionId'
270
+ - 'installationId'
271
+ - 'projectId'
272
+ - 'githubInstallationId'
273
+ ELSE resource.value
274
+ END
275
+ ORDER BY resource.ordinality
276
+ ),
277
+ '[]'::jsonb
278
+ ) INTO destination_resources
279
+ FROM pg_catalog.jsonb_array_elements(source_session.resources)
280
+ WITH ORDINALITY AS resource(value, ordinality);
281
+
282
+ DROP TABLE IF EXISTS pg_temp.opengeni_session_fork_history_spool;
283
+ CREATE TEMP TABLE opengeni_session_fork_history_spool (
284
+ position numeric NOT NULL,
285
+ item jsonb NOT NULL,
286
+ item_codec_version integer,
287
+ active boolean NOT NULL,
288
+ created_at timestamptz NOT NULL
289
+ ) ON COMMIT DROP;
290
+ INSERT INTO opengeni_session_fork_history_spool (
291
+ position, item, item_codec_version, active, created_at
292
+ )
293
+ SELECT source_item.position, source_item.item,
294
+ source_item.item_codec_version, source_item.active, source_item.created_at
295
+ FROM session_history_items source_item
296
+ WHERE source_item.account_id = p_account_id
297
+ AND source_item.workspace_id = p_source_workspace_id
298
+ AND source_item.session_id = p_source_session_id
299
+ ORDER BY source_item.position;
300
+ GET DIAGNOSTICS history_count = ROW_COUNT;
301
+
302
+ INSERT INTO session_command_receipts (
303
+ account_id, workspace_id, actor_type, actor_subject_id, action,
304
+ target_session_id, operation_key, canonical_request_hash
305
+ ) VALUES (
306
+ p_account_id, p_source_workspace_id, 'human', p_actor_subject_id,
307
+ 'session.fork', p_source_session_id, p_operation_key,
308
+ p_canonical_request_hash
309
+ ) ON CONFLICT DO NOTHING;
310
+ SELECT receipt.* INTO receipt_row
311
+ FROM session_command_receipts receipt
312
+ WHERE receipt.workspace_id = p_source_workspace_id
313
+ AND receipt.actor_type = 'human'
314
+ AND receipt.actor_subject_id = p_actor_subject_id
315
+ AND receipt.actor_attempt_id IS NULL
316
+ AND receipt.action = 'session.fork'
317
+ AND receipt.target_session_id = p_source_session_id
318
+ AND receipt.target_turn_id IS NULL
319
+ AND receipt.operation_key = p_operation_key
320
+ FOR UPDATE;
321
+ IF NOT FOUND THEN
322
+ RAISE EXCEPTION 'session fork receipt is unavailable'
323
+ USING ERRCODE = 'P0002';
324
+ END IF;
325
+ IF receipt_row.canonical_request_hash <> p_canonical_request_hash THEN
326
+ RAISE EXCEPTION 'session fork idempotency conflict'
327
+ USING ERRCODE = '23505';
328
+ END IF;
329
+ IF receipt_row.result ->> 'status' = 'applied' THEN
330
+ operation_id := receipt_row.id;
331
+ session_id := (receipt_row.result ->> 'sessionId')::uuid;
332
+ workspace_id := (receipt_row.result ->> 'workspaceId')::uuid;
333
+ visibility := receipt_row.result ->> 'visibility';
334
+ authority_epoch := 1;
335
+ copied_history_item_count :=
336
+ (receipt_row.result ->> 'copiedHistoryItemCount')::integer;
337
+ replay := true;
338
+ PERFORM pg_catalog.set_config(
339
+ 'opengeni.workspace_id',
340
+ CASE WHEN previous_workspace_id IS NULL THEN '' ELSE previous_workspace_id END,
341
+ true
342
+ );
343
+ PERFORM pg_catalog.set_config(
344
+ 'opengeni.organization_tenancy_lifecycle',
345
+ CASE WHEN previous_lifecycle_marker IS NULL THEN '' ELSE previous_lifecycle_marker END,
346
+ true
347
+ );
348
+ RETURN NEXT;
349
+ RETURN;
350
+ END IF;
351
+
352
+ PERFORM pg_catalog.set_config(
353
+ 'opengeni.workspace_id', p_destination_workspace_id::text, true
354
+ );
355
+ IF NOT EXISTS (
356
+ SELECT 1 FROM workspace_memberships destination_access
357
+ WHERE destination_access.account_id = p_account_id
358
+ AND destination_access.workspace_id = p_destination_workspace_id
359
+ AND destination_access.subject_id = p_actor_subject_id
360
+ ) THEN
361
+ RAISE EXCEPTION 'session fork destination workspace access is unavailable'
362
+ USING ERRCODE = '42501';
363
+ END IF;
364
+ SELECT * INTO destination_workspace
365
+ FROM workspaces workspace_row
366
+ WHERE workspace_row.account_id = p_account_id
367
+ AND workspace_row.id = p_destination_workspace_id;
368
+
369
+ SELECT
370
+ coalesce(
371
+ CASE WHEN (destination_workspace.settings ->> 'maxNestedAgentDepth') ~ '^\d+$'
372
+ THEN (destination_workspace.settings ->> 'maxNestedAgentDepth')::integer END,
373
+ configuration.max_nested_agent_depth
374
+ ),
375
+ CASE WHEN (destination_workspace.settings ->> 'maxNestedAgentDepth') ~ '^\d+$'
376
+ THEN 'workspace' ELSE configuration.policy_source END
377
+ INTO destination_depth, destination_depth_source
378
+ FROM nested_agent_depth_configuration configuration
379
+ WHERE configuration.singleton = true;
380
+ IF destination_depth IS NULL OR destination_depth_source IS NULL THEN
381
+ RAISE EXCEPTION 'session fork destination depth policy is unavailable'
382
+ USING ERRCODE = '55000';
383
+ END IF;
384
+
385
+ destination_session_id := pg_catalog.gen_random_uuid();
386
+ destination_owner_id := CASE WHEN p_destination_visibility = 'user_private'
387
+ THEN actor_membership.id ELSE actor_membership.id END;
388
+ INSERT INTO session_visibility_write_capabilities (
389
+ backend_pid, transaction_id, capability_id
390
+ ) VALUES (
391
+ pg_catalog.pg_backend_pid(),
392
+ pg_catalog.pg_current_xact_id(),
393
+ visibility_write_capability_id
394
+ );
395
+ PERFORM pg_catalog.set_config(
396
+ 'opengeni.session_visibility_write_capability',
397
+ visibility_write_capability_id::text,
398
+ true
399
+ );
400
+ PERFORM pg_catalog.set_config('opengeni.session_activity_gate_state', 'open', true);
401
+ PERFORM pg_catalog.set_config(
402
+ 'opengeni.session_activity_gate_workspace_id',
403
+ p_destination_workspace_id::text,
404
+ true
405
+ );
406
+
407
+ INSERT INTO sessions (
408
+ id, account_id, workspace_id, status,
409
+ initial_message, initial_message_codec_version,
410
+ title, title_source, instructions, policy_role,
411
+ resources, skills, tools, metadata,
412
+ created_by_kind, created_by_subject_id, created_by_context,
413
+ owner_organization_membership_id, owner_subject_id,
414
+ visibility, authority_epoch,
415
+ forked_from_session_id, forked_from_authority_epoch,
416
+ forked_from_visibility, forked_at,
417
+ forked_by_organization_membership_id,
418
+ model, reasoning_effort, latency_mode, sandbox_backend, sandbox_os, sandbox_group_id,
419
+ first_party_mcp_permissions, first_party_mcp_tools,
420
+ initial_personal_connection_delegations, tool_policy,
421
+ root_session_id, nested_agent_depth,
422
+ max_nested_agent_depth_override, effective_max_nested_agent_depth,
423
+ nested_agent_depth_policy_source, nested_agent_depth_policy_session_id,
424
+ temporal_workflow_id, active_turn_id, variable_set_id,
425
+ rig_id, rig_version_id, active_sandbox_id, active_epoch,
426
+ working_dir, codex_pinned_credential_id, codex_last_credential_id,
427
+ codex_pin_source, codex_compaction_mode,
428
+ queue_version, queue_head_position, queue_tail_position,
429
+ last_sequence
430
+ ) VALUES (
431
+ destination_session_id, p_account_id, p_destination_workspace_id, 'idle',
432
+ source_session.initial_message, source_session.initial_message_codec_version,
433
+ source_session.title, source_session.title_source,
434
+ source_session.instructions, source_session.policy_role,
435
+ destination_resources, '[]'::jsonb, '[]'::jsonb, '{}'::jsonb,
436
+ 'subject', p_actor_subject_id, '{"fork":true}'::jsonb,
437
+ destination_owner_id, actor_membership.subject_id,
438
+ p_destination_visibility, 1,
439
+ p_source_session_id, source_session.authority_epoch,
440
+ source_session.visibility, pg_catalog.clock_timestamp(), actor_membership.id,
441
+ source_session.model, source_session.reasoning_effort, source_session.latency_mode,
442
+ source_session.sandbox_backend,
443
+ source_session.sandbox_os, destination_session_id,
444
+ NULL, '[]'::jsonb, '[]'::jsonb,
445
+ '{"mode":"explicit","inheritedFromSessionId":null}'::jsonb,
446
+ destination_session_id, 0, NULL, destination_depth,
447
+ destination_depth_source, NULL,
448
+ NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL,
449
+ source_session.codex_compaction_mode,
450
+ 0, 0, 0, 1
451
+ );
452
+
453
+ INSERT INTO session_history_items (
454
+ account_id, workspace_id, session_id, turn_id,
455
+ position, item, item_codec_version, active,
456
+ provider_artifact_invalidated_at,
457
+ provider_artifact_invalidation_reason,
458
+ provider_artifact_invalidated_by_attempt_id,
459
+ created_at
460
+ )
461
+ SELECT p_account_id, p_destination_workspace_id, destination_session_id, NULL,
462
+ source_item.position, source_item.item, source_item.item_codec_version,
463
+ source_item.active, NULL, NULL, NULL, source_item.created_at
464
+ FROM opengeni_session_fork_history_spool source_item
465
+ ORDER BY source_item.position;
466
+
467
+ INSERT INTO session_events (
468
+ account_id, workspace_id, session_id, sequence, type, payload, occurred_at
469
+ ) VALUES (
470
+ p_account_id, p_destination_workspace_id, destination_session_id, 1,
471
+ 'session.created',
472
+ pg_catalog.jsonb_build_object(
473
+ 'forked', true,
474
+ 'sourceSessionId', p_source_session_id,
475
+ 'sourceAuthorityEpoch', source_session.authority_epoch,
476
+ 'sourceVisibility', CASE source_session.visibility
477
+ WHEN 'user_private' THEN 'private' ELSE 'workspace' END,
478
+ 'visibility', CASE p_destination_visibility
479
+ WHEN 'user_private' THEN 'private' ELSE 'workspace' END,
480
+ 'copiedHistoryItemCount', history_count
481
+ ),
482
+ pg_catalog.clock_timestamp()
483
+ );
484
+
485
+ PERFORM pg_catalog.set_config('opengeni.session_activity_gate_state', 'preparing', true);
486
+ SET CONSTRAINTS ALL IMMEDIATE;
487
+ SET CONSTRAINTS sessions_activity_insert_commit_guard,
488
+ sessions_activity_update_commit_guard DEFERRED;
489
+ PERFORM pg_catalog.set_config('opengeni.session_activity_gate_state', 'finalizing', true);
490
+ UPDATE workspace_session_activity_revisions counter
491
+ SET revision = counter.revision + 1
492
+ WHERE counter.workspace_id = p_destination_workspace_id
493
+ RETURNING counter.revision INTO destination_activity_revision;
494
+ IF destination_activity_revision IS NULL THEN
495
+ RAISE EXCEPTION 'session fork destination activity counter is unavailable'
496
+ USING ERRCODE = '55000';
497
+ END IF;
498
+ UPDATE sessions destination_session
499
+ SET activity_revision = destination_activity_revision,
500
+ activity_revision_pending_xid = NULL
501
+ WHERE destination_session.id = destination_session_id
502
+ AND destination_session.activity_revision_pending_xid
503
+ = pg_catalog.pg_current_xact_id()::text::bigint;
504
+ IF NOT FOUND THEN
505
+ RAISE EXCEPTION 'session fork destination activity was not finalized'
506
+ USING ERRCODE = '55000';
507
+ END IF;
508
+ SET CONSTRAINTS sessions_activity_insert_commit_guard,
509
+ sessions_activity_update_commit_guard IMMEDIATE;
510
+ PERFORM pg_catalog.set_config('opengeni.session_activity_gate_state', '', true);
511
+ PERFORM pg_catalog.set_config('opengeni.session_activity_gate_workspace_id', '', true);
512
+ PERFORM pg_catalog.set_config(
513
+ 'opengeni.session_visibility_write_capability',
514
+ CASE WHEN previous_visibility_marker IS NULL THEN '' ELSE previous_visibility_marker END,
515
+ true
516
+ );
517
+ DELETE FROM session_visibility_write_capabilities capability
518
+ WHERE capability.backend_pid = pg_catalog.pg_backend_pid()
519
+ AND capability.transaction_id = pg_catalog.pg_current_xact_id()
520
+ AND capability.capability_id = visibility_write_capability_id;
521
+
522
+ PERFORM pg_catalog.set_config(
523
+ 'opengeni.workspace_id', p_source_workspace_id::text, true
524
+ );
525
+ UPDATE session_command_receipts
526
+ SET result = pg_catalog.jsonb_build_object(
527
+ 'status', 'applied',
528
+ 'sessionId', destination_session_id,
529
+ 'workspaceId', p_destination_workspace_id,
530
+ 'visibility', p_destination_visibility,
531
+ 'authorityEpoch', 1,
532
+ 'copiedHistoryItemCount', history_count
533
+ ),
534
+ updated_at = pg_catalog.clock_timestamp()
535
+ WHERE id = receipt_row.id;
536
+
537
+ operation_id := receipt_row.id;
538
+ session_id := destination_session_id;
539
+ workspace_id := p_destination_workspace_id;
540
+ visibility := p_destination_visibility;
541
+ authority_epoch := 1;
542
+ copied_history_item_count := history_count;
543
+ replay := false;
544
+ PERFORM pg_catalog.set_config(
545
+ 'opengeni.workspace_id',
546
+ CASE WHEN previous_workspace_id IS NULL THEN '' ELSE previous_workspace_id END,
547
+ true
548
+ );
549
+ PERFORM pg_catalog.set_config(
550
+ 'opengeni.organization_tenancy_lifecycle',
551
+ CASE WHEN previous_lifecycle_marker IS NULL THEN '' ELSE previous_lifecycle_marker END,
552
+ true
553
+ );
554
+ RETURN NEXT;
555
+ EXCEPTION WHEN OTHERS THEN
556
+ PERFORM pg_catalog.set_config(
557
+ 'opengeni.workspace_id',
558
+ CASE WHEN previous_workspace_id IS NULL THEN '' ELSE previous_workspace_id END,
559
+ true
560
+ );
561
+ PERFORM pg_catalog.set_config(
562
+ 'opengeni.organization_tenancy_lifecycle',
563
+ CASE WHEN previous_lifecycle_marker IS NULL THEN '' ELSE previous_lifecycle_marker END,
564
+ true
565
+ );
566
+ PERFORM pg_catalog.set_config(
567
+ 'opengeni.session_activity_gate_state',
568
+ CASE WHEN previous_gate_state IS NULL THEN '' ELSE previous_gate_state END,
569
+ true
570
+ );
571
+ PERFORM pg_catalog.set_config(
572
+ 'opengeni.session_activity_gate_workspace_id',
573
+ CASE WHEN previous_gate_workspace_id IS NULL THEN '' ELSE previous_gate_workspace_id END,
574
+ true
575
+ );
576
+ PERFORM pg_catalog.set_config(
577
+ 'opengeni.session_visibility_write_capability',
578
+ CASE WHEN previous_visibility_marker IS NULL THEN '' ELSE previous_visibility_marker END,
579
+ true
580
+ );
581
+ RAISE;
582
+ END;
583
+ $body$;
584
+ $ddl$, data_schema);
585
+
586
+ EXECUTE format(
587
+ 'REVOKE ALL ON FUNCTION %I.fork_session_content(uuid,uuid,uuid,text,uuid,text,text,text) FROM PUBLIC',
588
+ data_schema
589
+ );
590
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
591
+ EXECUTE format(
592
+ 'GRANT EXECUTE ON FUNCTION %I.fork_session_content(uuid,uuid,uuid,text,uuid,text,text,text) TO opengeni_app',
593
+ data_schema
594
+ );
595
+ END IF;
596
+ END
597
+ $session_fork_activation$;