@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.
- package/dist/attached-browser-devices.d.ts +7 -0
- package/dist/automations.d.ts +154 -0
- package/dist/canonical-human-identities.js +3 -3
- package/dist/capability-integrations.d.ts +13 -0
- package/dist/child-lifecycle-notices.d.ts +68 -0
- package/dist/{chunk-4SR4HKKA.js → chunk-2EH4WRHL.js} +19 -11
- package/dist/chunk-2EH4WRHL.js.map +1 -0
- package/dist/{chunk-CUPM3FGB.js → chunk-2PRS4J5Q.js} +3 -3
- package/dist/chunk-6HMM2R5T.js +390 -0
- package/dist/chunk-6HMM2R5T.js.map +1 -0
- package/dist/{chunk-ZWREYEWA.js → chunk-AZHW7R5V.js} +56 -11
- package/dist/chunk-AZHW7R5V.js.map +1 -0
- package/dist/{chunk-LTG3S6ZY.js → chunk-E6CLMKEE.js} +2 -2
- package/dist/{chunk-6ZYKCRFO.js → chunk-KRLPEMLH.js} +7591 -4417
- package/dist/chunk-KRLPEMLH.js.map +1 -0
- package/dist/chunk-NAB6FKFN.js +516 -0
- package/dist/chunk-NAB6FKFN.js.map +1 -0
- package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
- package/dist/chunk-SIBYBA2D.js.map +1 -0
- package/dist/chunk-UZNXG44K.js +4508 -0
- package/dist/chunk-UZNXG44K.js.map +1 -0
- package/dist/codemode-operations.d.ts +1 -6
- package/dist/company-brain-context-selection-schema.d.ts +705 -0
- package/dist/company-brain-context-selection.d.ts +94 -0
- package/dist/company-brain-governed-writes.d.ts +24 -0
- package/dist/company-brain.d.ts +55 -0
- package/dist/company-profile-agent-admin.d.ts +15 -0
- package/dist/company-profile-schema.d.ts +619 -2
- package/dist/company-profile.d.ts +9 -4
- package/dist/connection-authority.d.ts +95 -0
- package/dist/connection-scopes.d.ts +8 -0
- package/dist/connection-tenancy-backfill.d.ts +85 -0
- package/dist/connection-token-resolver.d.ts +30 -1
- package/dist/database.d.ts +23 -4
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.d.ts +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/governed-learning-activation-schema.d.ts +984 -0
- package/dist/governed-learning-activation.d.ts +98 -0
- package/dist/governed-learning-evaluator-schema.d.ts +633 -0
- package/dist/governed-learning-evaluator.d.ts +28 -0
- package/dist/index.d.ts +1606 -81
- package/dist/index.js +21898 -8147
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +18 -0
- package/dist/integration-bindings.d.ts +1 -0
- package/dist/integration-facets.d.ts +30 -0
- package/dist/interaction-placement-loss.d.ts +22 -0
- package/dist/managed-human-provisioning.d.ts +25 -0
- package/dist/memory-domain.d.ts +3 -3
- package/dist/migrate.d.ts +11 -1
- package/dist/migrate.js +1 -1
- package/dist/new-session-drafts.d.ts +43 -5
- package/dist/organization-membership-backfill.d.ts +174 -0
- package/dist/organization-membership-lifecycle.d.ts +162 -0
- package/dist/pr-review.d.ts +107 -0
- package/dist/preference-registry-schema.d.ts +2 -0
- package/dist/preference-registry.d.ts +2 -0
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +29 -8
- package/dist/schema.d.ts +24914 -13703
- package/dist/schema.js +99 -1
- package/dist/scoped-knowledge-schema.d.ts +52 -1
- package/dist/session-background-commands.d.ts +125 -0
- package/dist/session-background-commands.js +34 -0
- package/dist/session-background-commands.js.map +1 -0
- package/dist/session-control.d.ts +156 -3
- package/dist/session-goal-pacing.d.ts +68 -0
- package/dist/session-queue-commands.d.ts +43 -4
- package/dist/session-realtime-ledger.d.ts +2 -0
- package/dist/session-tenancy.d.ts +71 -1
- package/dist/session-tenancy.js +25 -3
- package/dist/session-tool-call-settlement.d.ts +9 -4
- package/dist/slack-routing-personal-workspace.d.ts +23 -0
- package/dist/slack-routing.d.ts +268 -0
- package/dist/slack-task-policy-schema.d.ts +34 -0
- package/dist/slack-task-policy.d.ts +8 -0
- package/dist/slack-user-link-access.d.ts +28 -0
- package/dist/task-notes-schema.d.ts +594 -0
- package/dist/task-notes.d.ts +39 -0
- package/dist/turn-initiator.d.ts +2 -0
- package/dist/user-resource-authority.d.ts +109 -0
- package/dist/video-generation.js +3 -3
- package/dist/workspace-authority.d.ts +81 -0
- package/dist/workspace-instruction-policies-schema.d.ts +279 -0
- package/dist/workspace-instruction-policies.d.ts +62 -0
- package/dist/workspace-learning-policy.d.ts +1 -0
- package/dist/workspace-membership-permissions.d.ts +2 -0
- package/drizzle/0240_enrollment_connection_authority.sql +39 -0
- package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
- package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
- package/drizzle/0244_slack_app_home_refresh_queue.sql +120 -0
- package/drizzle/0245_model_context_contribution_facts.sql +88 -0
- package/drizzle/0246_integration_personal_instance_authority.sql +70 -0
- package/drizzle/0247_terraform_stacks_provenance_repair.sql +428 -0
- package/drizzle/0248_terraform_stacks_component_resolution_fence.sql +83 -0
- package/drizzle/0249_personal_resource_delegation_authority_correction.sql +662 -0
- package/drizzle/0250_direct_retained_process_owner_liveness.sql +199 -0
- package/drizzle/0251_connected_machine_operation_policy.sql +45 -0
- package/drizzle/0252_scheduled_personal_resource_delegation.sql +1867 -0
- package/drizzle/0253_common_user_resource_authority_lifecycle.sql +1555 -0
- package/drizzle/0254_scoped_variable_set_authority.sql +1255 -0
- package/drizzle/0255_company_brain_governed_write_proposals.sql +524 -0
- package/drizzle/0256_connection_authority_delegation.sql +703 -0
- package/drizzle/0257_goal_revision_decisions_and_root_constraints.sql +436 -0
- package/drizzle/0258_three_scope_document_knowledge_authority.sql +1273 -0
- package/drizzle/0259_company_brain_context_selection_receipts.sql +869 -0
- package/drizzle/0260_task_note_knowledge_promotion.sql +820 -0
- package/drizzle/0261_preference_knowledge_proposal_actor_binding.sql +471 -0
- package/drizzle/0262_scoped_connected_machines_and_rigs.sql +1700 -0
- package/drizzle/0263_organization_membership_lifecycle.sql +3284 -0
- package/drizzle/0264_connection_authority_runtime_activation.sql +1084 -0
- package/drizzle/0266_company_brain_context_receipt_inspection.sql +156 -0
- package/drizzle/0268_governed_learning_decision_receipts.sql +825 -0
- package/drizzle/0269_governed_learning_activation_controller.sql +1874 -0
- package/drizzle/0270_governed_learning_history_inspection.sql +170 -0
- package/drizzle/0271_company_brain_retrieval_only_default.sql +524 -0
- package/drizzle/0272_human_confirmed_learning_activation.sql +591 -0
- package/drizzle/0273_scheduled_variable_set_materialization.sql +268 -0
- package/drizzle/0274_human_confirmed_knowledge_review.sql +310 -0
- package/drizzle/0275_scheduled_connection_authority.sql +5527 -0
- package/drizzle/0276_onboarding_proposal_initiating_human_guc.sql +198 -0
- package/drizzle/0277_workspace_writer_authority_attribution.sql +393 -0
- package/drizzle/0278_workspace_membership_removal_fencing.sql +1174 -0
- package/drizzle/0279_workspace_connection_use_lane.sql +343 -0
- package/drizzle/0280_connection_and_variable_set_audit_attribution.sql +773 -0
- package/drizzle/0281_viewer_holder_authority_claims.sql +52 -0
- package/drizzle/0282_variable_set_session_attach_attribution.sql +178 -0
- package/drizzle/0283_editable_spreadsheet_authored_state.sql +82 -0
- package/drizzle/0284_truthful_human_confirmed_review_reason.sql +930 -0
- package/drizzle/0285_organization_tenancy_inventory.sql +329 -0
- package/drizzle/0286_widen_task_note_expiry_ceiling.sql +391 -0
- package/drizzle/0287_open_suffix_pending_tool_calls.sql +18 -0
- package/drizzle/0288_attached_browser_reenrollment.sql +64 -0
- package/drizzle/0289_session_composer_policy_authority.sql +597 -0
- package/drizzle/0290_organization_membership_backfill.sql +268 -0
- package/drizzle/0291_resource_authority_classification_assertion.sql +371 -0
- package/drizzle/0292_truthful_tenancy_inventory_counters.sql +291 -0
- package/drizzle/0293_confirm_time_rule_rebaseline.sql +615 -0
- package/drizzle/0294_preference_activation_authority.sql +237 -0
- package/drizzle/0295_retire_legacy_standing_memory_mode.sql +476 -0
- package/drizzle/0296_force_rls_backfill_noop_repair.sql +215 -0
- package/drizzle/0297_session_ownership_classification_and_backfill.sql +752 -0
- package/drizzle/0298_organization_tenancy_parity.sql +609 -0
- package/drizzle/0299_organization_membership_lock_order.sql +291 -0
- package/drizzle/0300_tenancy_backfill_ledger.sql +459 -0
- package/drizzle/0301_session_snapshot_and_pin_visibility.sql +181 -0
- package/drizzle/0302_personal_workspace_session_ownership.sql +303 -0
- package/drizzle/0303_session_tenancy_product_activation.sql +919 -0
- package/drizzle/0304_personal_workspace_private_session_reads.sql +97 -0
- package/drizzle/0305_personal_resource_grant_management.sql +584 -0
- package/drizzle/0306_atomic_personal_resource_attachments.sql +1374 -0
- package/drizzle/0307_session_attention_state.sql +51 -0
- package/drizzle/0308_session_archives.sql +35 -0
- package/drizzle/0309_channel_project_pins.sql +6 -0
- package/drizzle/0310_channel_project_order.sql +27 -0
- package/drizzle/0311_company_scope_and_private_session_create.sql +656 -0
- package/drizzle/0312_quiescent_session_tree_deletion.sql +39 -0
- package/drizzle/0313_private_child_session_authority.sql +365 -0
- package/drizzle/0314_unregistered_organization_invitations.sql +606 -0
- package/drizzle/0315_personal_github_repository_selection.sql +624 -0
- package/drizzle/0316_human_confirmed_activation_resumed_generation.sql +869 -0
- package/drizzle/0317_session_goal_continuation_hold.sql +64 -0
- package/drizzle/0318_session_turn_startup_milestones.sql +115 -0
- package/drizzle/0319_event_triggered_automations.sql +254 -0
- package/drizzle/0320_pr_review_pack.sql +113 -0
- package/drizzle/0321_slack_bot_environment_display_name.sql +15 -0
- package/drizzle/0322_session_turns_unclaimed_prompt_trigger_index.sql +5 -0
- package/drizzle/0323_organization_private_session_enablement.sql +489 -0
- package/drizzle/0324_human_confirmed_company_profile_agent_admin.sql +856 -0
- package/drizzle/0325_child_lifecycle_notices.sql +44 -0
- package/drizzle/0326_interaction_operation_error_codes.sql +62 -0
- package/drizzle/0327_slack_first_task_hint.sql +29 -0
- package/drizzle/0328_session_background_commands.sql +590 -0
- package/drizzle/0329_slack_orchestration_delivery_events.sql +91 -0
- package/drizzle/0330_api_key_descriptions.sql +20 -0
- package/drizzle/0331_managed_organization_creation.sql +163 -0
- package/drizzle/0332_organization_shared_workspace_control_plane.sql +539 -0
- package/drizzle/0333_session_turn_prompt_routing.sql +45 -0
- package/drizzle/0334_connected_machine_workspace_root.sql +99 -0
- package/drizzle/0335_slack_workspace_routing.sql +460 -0
- package/drizzle/0336_atomic_session_fork_visibility.sql +667 -0
- package/drizzle/0337_slack_routed_action_handles.sql +189 -0
- package/drizzle/0338_atomic_connected_machine_attachments.sql +410 -0
- package/drizzle/0339_document_authority_reclassification.sql +1153 -0
- package/drizzle/0340_tenancy_backfill_activation_evidence.sql +1347 -0
- package/drizzle/0341_slack_routing_probe_organization_fence.sql +109 -0
- package/drizzle/0342_slack_route_prompt_single_pending.sql +32 -0
- package/drizzle/0343_personal_document_force_rls_lock_repair.sql +146 -0
- package/drizzle/0344_private_session_visibility_transition_gate.sql +85 -0
- package/drizzle/0345_tenant_scoped_session_tenancy_fence.sql +2839 -0
- package/drizzle/0346_document_migration_audit_surface.sql +454 -0
- package/drizzle/0347_connection_authority_convergence_evidence.sql +396 -0
- package/package.json +10 -6
- package/src/attached-browser-devices.ts +233 -5
- package/src/automations.ts +911 -0
- package/src/browser-sessions.ts +10 -0
- package/src/capability-integrations.ts +175 -1
- package/src/child-lifecycle-notices.ts +241 -0
- package/src/codemode-operations.ts +1 -35
- package/src/company-brain-context-selection-schema.ts +100 -0
- package/src/company-brain-context-selection.ts +359 -0
- package/src/company-brain-governed-writes.ts +1170 -0
- package/src/company-brain.ts +309 -0
- package/src/company-profile-agent-admin.ts +225 -0
- package/src/company-profile-schema.ts +121 -1
- package/src/company-profile.ts +21 -0
- package/src/computer-sessions.ts +10 -1
- package/src/connection-authority.ts +290 -0
- package/src/connection-scopes.ts +20 -0
- package/src/connection-tenancy-backfill.ts +167 -0
- package/src/connection-token-resolver.ts +263 -31
- package/src/database.ts +87 -2
- package/src/editable-artifacts-schema.ts +10 -5
- package/src/editable-artifacts.ts +21 -11
- package/src/governed-learning-activation-schema.ts +121 -0
- package/src/governed-learning-activation.ts +588 -0
- package/src/governed-learning-evaluator-schema.ts +72 -0
- package/src/governed-learning-evaluator.ts +217 -0
- package/src/index.ts +11676 -1550
- package/src/insights.ts +107 -0
- package/src/integration-bindings.ts +88 -6
- package/src/integration-facets.ts +287 -84
- package/src/interaction-placement-loss.ts +234 -0
- package/src/managed-human-provisioning.ts +116 -0
- package/src/memory-domain.ts +27 -32
- package/src/migrate.ts +77 -1
- package/src/new-session-drafts.ts +229 -35
- package/src/organization-membership-backfill.ts +735 -0
- package/src/organization-membership-lifecycle.ts +995 -0
- package/src/pr-review.ts +890 -0
- package/src/preference-registry.ts +31 -1
- package/src/provision-roles.ts +905 -6
- package/src/runtime-posture-cli.ts +2 -0
- package/src/runtime-posture.ts +1317 -72
- package/src/schema.ts +3316 -428
- package/src/scoped-knowledge-schema.ts +16 -8
- package/src/scoped-knowledge.ts +1 -1
- package/src/session-background-commands.ts +759 -0
- package/src/session-control.ts +640 -74
- package/src/session-goal-pacing.ts +126 -0
- package/src/session-queue-commands.ts +441 -85
- package/src/session-realtime-context.ts +4 -6
- package/src/session-realtime-ledger.ts +28 -14
- package/src/session-realtime-mirror.ts +1 -1
- package/src/session-tenancy.ts +410 -49
- package/src/session-tool-call-settlement.ts +38 -29
- package/src/slack-routing-personal-workspace.ts +67 -0
- package/src/slack-routing.ts +867 -0
- package/src/slack-task-policy-schema.ts +5 -0
- package/src/slack-task-policy.ts +18 -0
- package/src/slack-user-link-access.ts +138 -11
- package/src/task-notes-schema.ts +74 -0
- package/src/task-notes.ts +124 -2
- package/src/turn-initiator.ts +8 -0
- package/src/user-resource-authority.ts +377 -0
- package/src/workspace-authority.ts +160 -0
- package/src/workspace-instruction-policies-schema.ts +53 -1
- package/src/workspace-instruction-policies.ts +528 -77
- package/src/workspace-learning-policy.ts +21 -5
- package/src/workspace-membership-permissions.ts +9 -0
- package/dist/chunk-4SR4HKKA.js.map +0 -1
- package/dist/chunk-6ZYKCRFO.js.map +0 -1
- package/dist/chunk-NXAFLCQX.js +0 -2468
- package/dist/chunk-NXAFLCQX.js.map +0 -1
- package/dist/chunk-SK7YYHBI.js.map +0 -1
- package/dist/chunk-WD5ROSLL.js +0 -117
- package/dist/chunk-WD5ROSLL.js.map +0 -1
- package/dist/chunk-ZWREYEWA.js.map +0 -1
- /package/dist/{chunk-CUPM3FGB.js.map → chunk-2PRS4J5Q.js.map} +0 -0
- /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.';
|