@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,109 @@
1
+ -- deployment-mode: rolling
2
+ -- Fence both Slack routing tenancy probes on the organization the caller is
3
+ -- acting for.
4
+ --
5
+ -- Neither probe carried an account predicate. Both are SECURITY DEFINER and
6
+ -- both return tenancy ids, so a caller holding another organization's
7
+ -- connection UUID plus a route key or a handle id learned that organization's
8
+ -- account, workspace and interaction ids. Exploitability is low today, because
9
+ -- connection ids are never caller-supplied and the Slack signature check
10
+ -- already fences the team, but the predicate is one line and every sibling
11
+ -- authority routine carries it.
12
+ --
13
+ -- Rolling by expand-and-contract: the fenced three-argument routines are added
14
+ -- alongside the existing two-argument ones rather than replacing them, so an
15
+ -- old image keeps resolving thread continuation and button clicks through the
16
+ -- signature it knows. A later migration drops the unfenced pair once the fleet
17
+ -- is on an image that calls the fenced one; dropping them here would break
18
+ -- every running old worker the moment this commits.
19
+
20
+ SET LOCAL lock_timeout = '5s';
21
+ SET LOCAL statement_timeout = '10min';
22
+
23
+ DO $slack_fenced_interaction_probe$
24
+ DECLARE data_schema text := current_schema();
25
+ BEGIN
26
+ EXECUTE format($ddl$
27
+ CREATE FUNCTION opengeni_private.resolve_slack_interaction_tenancy(
28
+ p_account_id uuid,
29
+ p_connection_id uuid,
30
+ p_route_key text
31
+ )
32
+ RETURNS TABLE (account_id uuid, workspace_id uuid, interaction_id uuid)
33
+ LANGUAGE plpgsql
34
+ SECURITY DEFINER
35
+ SET search_path = %1$I, pg_catalog
36
+ AS $body$
37
+ BEGIN
38
+ IF p_account_id IS NULL OR p_connection_id IS NULL OR p_route_key IS NULL THEN
39
+ RETURN;
40
+ END IF;
41
+ INSERT INTO opengeni_private.slack_routing_runtime_capabilities (
42
+ backend_pid, transaction_id, capability_kind
43
+ ) VALUES (
44
+ pg_catalog.pg_backend_pid(), pg_catalog.pg_current_xact_id(), 'interaction_tenancy'
45
+ ) ON CONFLICT DO NOTHING;
46
+ BEGIN
47
+ RETURN QUERY
48
+ SELECT I.account_id, I.workspace_id, I.id
49
+ FROM slack_interactions I
50
+ WHERE I.account_id = p_account_id
51
+ AND I.connection_id = p_connection_id
52
+ AND I.route_key = p_route_key
53
+ LIMIT 1;
54
+ DELETE FROM opengeni_private.slack_routing_runtime_capabilities
55
+ WHERE backend_pid = pg_catalog.pg_backend_pid()
56
+ AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
57
+ AND capability_kind = 'interaction_tenancy';
58
+ RETURN;
59
+ EXCEPTION WHEN OTHERS THEN
60
+ DELETE FROM opengeni_private.slack_routing_runtime_capabilities
61
+ WHERE backend_pid = pg_catalog.pg_backend_pid()
62
+ AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
63
+ AND capability_kind = 'interaction_tenancy';
64
+ RAISE;
65
+ END;
66
+ END;
67
+ $body$
68
+ $ddl$, data_schema);
69
+ END
70
+ $slack_fenced_interaction_probe$;
71
+
72
+ REVOKE ALL ON FUNCTION opengeni_private.resolve_slack_interaction_tenancy(uuid, uuid, text)
73
+ FROM PUBLIC;
74
+
75
+ CREATE FUNCTION opengeni_private.resolve_slack_action_handle_tenancy(
76
+ p_account_id uuid,
77
+ p_connection_id uuid,
78
+ p_handle_id uuid
79
+ )
80
+ RETURNS TABLE (account_id uuid, workspace_id uuid)
81
+ LANGUAGE sql
82
+ STABLE
83
+ SECURITY DEFINER
84
+ SET search_path = opengeni_private, pg_catalog
85
+ AS $$
86
+ SELECT T.account_id, T.workspace_id
87
+ FROM slack_action_handle_tenancy T
88
+ WHERE T.account_id = p_account_id
89
+ AND T.handle_id = p_handle_id
90
+ AND T.connection_id = p_connection_id
91
+ LIMIT 1
92
+ $$;
93
+
94
+ REVOKE ALL ON FUNCTION
95
+ opengeni_private.resolve_slack_action_handle_tenancy(uuid, uuid, uuid) FROM PUBLIC;
96
+
97
+ DO $grants$
98
+ BEGIN
99
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
100
+ GRANT EXECUTE ON FUNCTION
101
+ opengeni_private.resolve_slack_interaction_tenancy(uuid, uuid, text) TO opengeni_app;
102
+ GRANT EXECUTE ON FUNCTION
103
+ opengeni_private.resolve_slack_action_handle_tenancy(uuid, uuid, uuid) TO opengeni_app;
104
+ END IF;
105
+ END
106
+ $grants$;
107
+
108
+ RESET statement_timeout;
109
+ RESET lock_timeout;
@@ -0,0 +1,32 @@
1
+ -- deployment-mode: rolling
2
+ -- One pending Slack route picker per person per conversation.
3
+ --
4
+ -- `slack_route_prompts` is unique on `(connection_id, inbox_id)` and
5
+ -- `(connection_id, provider_event_id)`, both keyed to the originating event, so
6
+ -- Slack's retries of one event cannot post a second card but two DIFFERENT
7
+ -- messages each open their own. One person would get two cards for the same
8
+ -- question, and answering either would write the route while the other stayed
9
+ -- live and answerable.
10
+ --
11
+ -- The key includes `slack_user_id` on purpose. A shared channel has many people
12
+ -- in it, and asking one of them must not swallow another's request: each person
13
+ -- is asked once. A direct message is already one channel per person, so the same
14
+ -- index covers both surfaces.
15
+ --
16
+ -- Expiry is not part of the predicate, because `now()` is not immutable and a
17
+ -- partial index cannot call it. A timed-out row is settled `expired`
18
+ -- opportunistically by the writer before it opens a new prompt, which is what
19
+ -- keeps a card nobody ever clicked from holding the slot forever.
20
+ --
21
+ -- Rolling and safe to build without CONCURRENTLY: the table has no rows and no
22
+ -- writer until the picker ships in this same change.
23
+
24
+ SET LOCAL lock_timeout = '5s';
25
+ SET LOCAL statement_timeout = '10min';
26
+
27
+ CREATE UNIQUE INDEX "slack_route_prompts_pending_conversation_uq"
28
+ ON "slack_route_prompts" ("connection_id", "slack_channel_id", "slack_user_id")
29
+ WHERE "status" = 'pending';
30
+
31
+ RESET statement_timeout;
32
+ RESET lock_timeout;
@@ -0,0 +1,146 @@
1
+ -- deployment-mode: rolling
2
+ -- Repair the two personal-Document membership reads shipped by 0258. A
3
+ -- row-locking SELECT is also subject to an UPDATE policy; the capability only
4
+ -- grants SELECT, so a real NOSUPERUSER/NOBYPASSRLS migration owner saw zero
5
+ -- memberships and silently selected the legacy workspace-anchored lane.
6
+
7
+ SET LOCAL lock_timeout = '5s';
8
+ SET LOCAL statement_timeout = '5min';
9
+
10
+ -- The checker cannot distinguish the function-body source strings below from
11
+ -- top-level executable membership probes. Keep the migration owner's own
12
+ -- transformation/assertion block inside the house owner-only window; ordinary
13
+ -- runtime roles remain RLS-bound throughout and FORCE is restored atomically.
14
+ ALTER TABLE organization_memberships NO FORCE ROW LEVEL SECURITY;
15
+
16
+ DO $repair_personal_document_membership_reads$
17
+ DECLARE
18
+ data_schema text := pg_catalog.current_schema();
19
+ function_oid regprocedure;
20
+ definition text;
21
+ repaired text;
22
+ old_fragment text;
23
+ new_fragment text;
24
+ BEGIN
25
+ function_oid := pg_catalog.to_regprocedure(
26
+ pg_catalog.format('%I.create_personal_document_authority(uuid,uuid,uuid)', data_schema)
27
+ );
28
+ IF function_oid IS NULL THEN
29
+ RAISE EXCEPTION 'create_personal_document_authority is unavailable for repair'
30
+ USING ERRCODE = '55000';
31
+ END IF;
32
+ definition := pg_catalog.pg_get_functiondef(function_oid);
33
+ old_fragment := $old$
34
+ SELECT membership.* INTO member_row
35
+ FROM organization_memberships membership
36
+ WHERE membership.account_id = p_account_id
37
+ AND membership.subject_id = caller_subject
38
+ AND membership.status = 'active'
39
+ AND membership.revoked_at IS NULL
40
+ FOR SHARE;
41
+ $old$;
42
+ new_fragment := $new$
43
+ SELECT membership.* INTO member_row
44
+ FROM organization_memberships membership
45
+ WHERE membership.account_id = p_account_id
46
+ AND membership.subject_id = caller_subject
47
+ AND membership.status = 'active'
48
+ AND membership.revoked_at IS NULL;
49
+
50
+ -- The plain control probe makes a future command/policy mismatch loud.
51
+ -- With this migration's non-locking read the two predicates are
52
+ -- identical. If a later revision restores a locking read without its
53
+ -- exact policy, the capability-visible control row cannot silently fall
54
+ -- through to the legacy authority lane.
55
+ IF NOT FOUND AND EXISTS (
56
+ SELECT 1
57
+ FROM organization_memberships membership
58
+ WHERE membership.account_id = p_account_id
59
+ AND membership.subject_id = caller_subject
60
+ AND membership.status = 'active'
61
+ AND membership.revoked_at IS NULL
62
+ ) THEN
63
+ RAISE EXCEPTION 'personal document membership read was RLS-blinded'
64
+ USING ERRCODE = '55000';
65
+ END IF;
66
+ $new$;
67
+ repaired := pg_catalog.replace(definition, old_fragment, new_fragment);
68
+ IF repaired = definition THEN
69
+ RAISE EXCEPTION 'create_personal_document_authority repair shape changed'
70
+ USING ERRCODE = '55000';
71
+ END IF;
72
+ EXECUTE repaired;
73
+
74
+ function_oid := pg_catalog.to_regprocedure(
75
+ pg_catalog.format(
76
+ '%I.prepare_session_attempt_personal_document_reads(uuid,uuid,uuid,uuid)',
77
+ data_schema
78
+ )
79
+ );
80
+ IF function_oid IS NULL THEN
81
+ RAISE EXCEPTION 'prepare_session_attempt_personal_document_reads is unavailable for repair'
82
+ USING ERRCODE = '55000';
83
+ END IF;
84
+ definition := pg_catalog.pg_get_functiondef(function_oid);
85
+ old_fragment := $old$
86
+ SELECT membership.* INTO member_row
87
+ FROM organization_memberships membership
88
+ WHERE membership.account_id = p_account_id
89
+ AND membership.subject_id = initiating_subject
90
+ AND membership.status = 'active'
91
+ AND membership.revoked_at IS NULL
92
+ FOR SHARE;
93
+ $old$;
94
+ new_fragment := $new$
95
+ SELECT membership.* INTO member_row
96
+ FROM organization_memberships membership
97
+ WHERE membership.account_id = p_account_id
98
+ AND membership.subject_id = initiating_subject
99
+ AND membership.status = 'active'
100
+ AND membership.revoked_at IS NULL;
101
+
102
+ IF NOT FOUND AND EXISTS (
103
+ SELECT 1
104
+ FROM organization_memberships membership
105
+ WHERE membership.account_id = p_account_id
106
+ AND membership.subject_id = initiating_subject
107
+ AND membership.status = 'active'
108
+ AND membership.revoked_at IS NULL
109
+ ) THEN
110
+ RAISE EXCEPTION 'personal document admission membership read was RLS-blinded'
111
+ USING ERRCODE = '55000';
112
+ END IF;
113
+ $new$;
114
+ repaired := pg_catalog.replace(definition, old_fragment, new_fragment);
115
+ IF repaired = definition THEN
116
+ RAISE EXCEPTION 'prepare_session_attempt_personal_document_reads repair shape changed'
117
+ USING ERRCODE = '55000';
118
+ END IF;
119
+
120
+ -- The later portable-document scan has the same command mismatch: locking
121
+ -- both documents and authorities makes PostgreSQL require UPDATE-applicable
122
+ -- policies, while this admission capability is intentionally read-only.
123
+ -- Snapshot foreign keys take the durable referential pins at insertion.
124
+ definition := repaired;
125
+ old_fragment := $old$
126
+ ORDER BY document_value.id
127
+ FOR SHARE OF document_value, authority
128
+ $old$;
129
+ new_fragment := $new$
130
+ ORDER BY document_value.id
131
+ $new$;
132
+ repaired := pg_catalog.replace(definition, old_fragment, new_fragment);
133
+ IF repaired = definition THEN
134
+ RAISE EXCEPTION 'prepare_session_attempt_personal_document_reads document scan repair shape changed'
135
+ USING ERRCODE = '55000';
136
+ END IF;
137
+ EXECUTE repaired;
138
+ END
139
+ $repair_personal_document_membership_reads$;
140
+
141
+ ALTER TABLE organization_memberships FORCE ROW LEVEL SECURITY;
142
+
143
+ COMMENT ON FUNCTION create_personal_document_authority(uuid, uuid, uuid) IS
144
+ 'Creates portable personal Document authority for an exact active organization membership; 0343 removes an RLS-blind row lock and fails loudly on visibility drift.';
145
+ COMMENT ON FUNCTION prepare_session_attempt_personal_document_reads(uuid, uuid, uuid, uuid) IS
146
+ 'Freezes exact-attempt personal Document reads; 0343 removes RLS-blind membership and portable-document row locks and fails loudly on definition or visibility drift.';
@@ -0,0 +1,85 @@
1
+ -- deployment-mode: rolling
2
+ -- A committed visibility transition replays from its applied command receipt
3
+ -- without issuing another sessions UPDATE. Gate the actual state change so
4
+ -- replay remains recoverable after an owner disables private sessions, while a
5
+ -- fresh shared-workspace transition fails closed. Personal workspaces retain
6
+ -- the same exemption as private create and private fork destinations.
7
+
8
+ -- Migration 0323's settings routines install this marker before reading the
9
+ -- actor membership, but the shared lifecycle policy never admitted it. Keep
10
+ -- this authority narrow and separate from that shared marker list. The UPDATE
11
+ -- policy is required because the mutating seam locks the actor with FOR SHARE.
12
+ DO $organization_private_session_settings_membership_policies$
13
+ DECLARE
14
+ data_schema text := pg_catalog.current_schema();
15
+ migration_owner text := current_user;
16
+ marker constant text :=
17
+ 'current_setting(''opengeni.organization_tenancy_lifecycle'', true) '
18
+ || '= ''organization_private_session_settings'' AND account_id = nullif('
19
+ || 'current_setting(''opengeni.account_id'', true), '''')::uuid';
20
+ BEGIN
21
+ EXECUTE pg_catalog.format(
22
+ 'CREATE POLICY organization_private_session_settings_membership_read '
23
+ || 'ON %I.organization_memberships FOR SELECT '
24
+ || 'USING (current_user = %L AND %s)',
25
+ data_schema, migration_owner, marker
26
+ );
27
+ EXECUTE pg_catalog.format(
28
+ 'CREATE POLICY organization_private_session_settings_membership_lock '
29
+ || 'ON %I.organization_memberships FOR UPDATE '
30
+ || 'USING (current_user = %L AND %s)',
31
+ data_schema, migration_owner, marker
32
+ );
33
+ END
34
+ $organization_private_session_settings_membership_policies$;
35
+
36
+ CREATE FUNCTION guard_private_session_visibility_transition()
37
+ RETURNS trigger
38
+ LANGUAGE plpgsql
39
+ SECURITY DEFINER
40
+ SET search_path FROM CURRENT
41
+ AS $$
42
+ BEGIN
43
+ IF OLD.visibility IS DISTINCT FROM NEW.visibility
44
+ AND NEW.visibility = 'user_private'
45
+ AND NOT EXISTS (
46
+ SELECT 1
47
+ FROM organization_memberships membership
48
+ WHERE membership.account_id = NEW.account_id
49
+ AND membership.personal_workspace_id = NEW.workspace_id
50
+ AND membership.status = 'active'
51
+ )
52
+ AND NOT organization_private_sessions_enabled(NEW.account_id)
53
+ THEN
54
+ RAISE EXCEPTION
55
+ 'private sessions are not enabled for this organization''s shared workspaces'
56
+ USING ERRCODE = '55000';
57
+ END IF;
58
+ RETURN NEW;
59
+ END
60
+ $$;
61
+
62
+ REVOKE ALL ON FUNCTION guard_private_session_visibility_transition() FROM PUBLIC;
63
+
64
+ DROP TRIGGER IF EXISTS session_01_private_visibility_setting_fence ON sessions;
65
+ CREATE TRIGGER session_01_private_visibility_setting_fence
66
+ BEFORE UPDATE OF visibility ON sessions
67
+ FOR EACH ROW
68
+ WHEN (OLD.visibility IS DISTINCT FROM NEW.visibility AND NEW.visibility = 'user_private')
69
+ EXECUTE FUNCTION guard_private_session_visibility_transition();
70
+
71
+ DO $$
72
+ DECLARE
73
+ data_schema text := current_schema();
74
+ BEGIN
75
+ EXECUTE format(
76
+ 'ALTER FUNCTION %I.guard_private_session_visibility_transition() '
77
+ || 'SET search_path = pg_catalog, %I, pg_temp',
78
+ data_schema,
79
+ data_schema
80
+ );
81
+ END
82
+ $$;
83
+
84
+ COMMENT ON FUNCTION guard_private_session_visibility_transition() IS
85
+ 'Refuses a fresh transition to user_private in a shared workspace while the organization private-session setting is disabled; applied receipt replay performs no UPDATE and remains valid.';