@opengeni/db 0.36.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.
- 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-GYO7ED2Q.js → chunk-EULAN2NP.js} +2 -2
- package/dist/{chunk-VTPRIXKG.js → chunk-NJVZPWXY.js} +3 -3
- package/dist/{chunk-HSOWSYOX.js → chunk-NMUBV7Z5.js} +19 -11
- package/dist/chunk-NMUBV7Z5.js.map +1 -0
- package/dist/chunk-OF5OBB76.js +4457 -0
- package/dist/chunk-OF5OBB76.js.map +1 -0
- package/dist/{chunk-5KTIEDX7.js → chunk-PR2WMLOQ.js} +7714 -4443
- package/dist/chunk-PR2WMLOQ.js.map +1 -0
- package/dist/{chunk-Z7VYMNPZ.js → chunk-SCPUJS53.js} +41 -4
- package/dist/chunk-SCPUJS53.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-TIKF3KTI.js +383 -0
- package/dist/chunk-TIKF3KTI.js.map +1 -0
- package/dist/chunk-ZZ5LJEFX.js +516 -0
- package/dist/chunk-ZZ5LJEFX.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 +41 -0
- package/dist/connection-token-resolver.d.ts +30 -1
- package/dist/database.d.ts +19 -0
- package/dist/editable-artifact-durable-export.d.ts +10 -0
- package/dist/editable-artifact-durable-export.js +18 -3
- package/dist/editable-artifact-durable-export.js.map +1 -1
- 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 +1633 -87
- package/dist/index.js +22004 -8109
- 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/knowledge-source-sync-schema.d.ts +730 -0
- package/dist/knowledge-source-sync.d.ts +60 -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 +23 -9
- package/dist/schema.d.ts +24925 -13697
- package/dist/schema.js +103 -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 +42 -5
- package/dist/session-realtime-ledger.d.ts +3 -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 +153 -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 +1 -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/0240_model_context_user_messages.sql +204 -0
- package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
- package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
- package/drizzle/0243_google_drive_object_acl_authority.sql +554 -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/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 +81 -0
- package/src/connection-token-resolver.ts +263 -31
- package/src/database.ts +75 -2
- package/src/editable-artifact-durable-export.ts +27 -0
- 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 +12001 -1699
- 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/knowledge-source-sync-schema.ts +83 -0
- package/src/knowledge-source-sync.ts +530 -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 +985 -0
- package/src/pr-review.ts +890 -0
- package/src/preference-registry.ts +31 -1
- package/src/provision-roles.ts +931 -24
- package/src/runtime-posture-cli.ts +2 -0
- package/src/runtime-posture.ts +1315 -52
- package/src/schema.ts +3336 -438
- 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 +450 -98
- package/src/session-realtime-context.ts +19 -3
- package/src/session-realtime-ledger.ts +75 -12
- package/src/session-realtime-mirror.ts +1 -1
- package/src/session-tenancy.ts +403 -49
- package/src/session-tool-call-settlement.ts +38 -29
- package/src/slack-routing-personal-workspace.ts +67 -0
- package/src/slack-routing.ts +469 -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 +17 -1
- 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-5KTIEDX7.js.map +0 -1
- package/dist/chunk-FPVAD4CO.js +0 -117
- package/dist/chunk-FPVAD4CO.js.map +0 -1
- package/dist/chunk-HSOWSYOX.js.map +0 -1
- package/dist/chunk-SK7YYHBI.js.map +0 -1
- package/dist/chunk-VKLB2ZGI.js +0 -2389
- package/dist/chunk-VKLB2ZGI.js.map +0 -1
- package/dist/chunk-Z7VYMNPZ.js.map +0 -1
- /package/dist/{chunk-GYO7ED2Q.js.map → chunk-EULAN2NP.js.map} +0 -0
- /package/dist/{chunk-VTPRIXKG.js.map → chunk-NJVZPWXY.js.map} +0 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Migration 0302: own sessions created in a managed human's OWN personal
|
|
3
|
+
-- workspace, and stop the write fence from silently minting a NULL owner when
|
|
4
|
+
-- an owner does exist.
|
|
5
|
+
--
|
|
6
|
+
-- THE DEFECT
|
|
7
|
+
-- ----------
|
|
8
|
+
-- 0225's `guard_session_authority_write` resolves a new session's owner from
|
|
9
|
+
-- the creator's active `organization_memberships` row, but gates that
|
|
10
|
+
-- resolution on an `EXISTS (workspace_memberships ...)` row in the session's
|
|
11
|
+
-- workspace. A managed human's personal workspace DELIBERATELY has no
|
|
12
|
+
-- `workspace_memberships` row: 0219's provisioning capability treats one as a
|
|
13
|
+
-- hard error ('managed-human personal workspace already has runtime access',
|
|
14
|
+
-- 42501), and docs/organization-tenancy.md states the owner-only access
|
|
15
|
+
-- projection is an `AccessContext` grant rather than a durable membership row.
|
|
16
|
+
--
|
|
17
|
+
-- The EXISTS can therefore never be satisfied in a personal workspace, the
|
|
18
|
+
-- `SELECT ... INTO` finds nothing, and the session is written with
|
|
19
|
+
-- `owner_organization_membership_id = NULL`. Consequence: a human in the one
|
|
20
|
+
-- workspace where they are by construction the ONLY possible member cannot own
|
|
21
|
+
-- their own sessions, so those sessions can never become `user_private` and can
|
|
22
|
+
-- never carry that human's personal connections or Documents. 0297 already
|
|
23
|
+
-- names this exact population ("A MANAGED HUMAN IN THEIR OWN PERSONAL
|
|
24
|
+
-- WORKSPACE") and repairs it historically; nothing stopped the mint.
|
|
25
|
+
--
|
|
26
|
+
-- THE FIX, AND WHY IT IS NOT AN INFERENCE
|
|
27
|
+
-- ---------------------------------------
|
|
28
|
+
-- Accept `membership.personal_workspace_id = NEW.workspace_id` as an
|
|
29
|
+
-- ALTERNATIVE to the `workspace_memberships` EXISTS. This is exactly the shape
|
|
30
|
+
-- 0258's `ensure_personal_document_authority` already uses for Documents
|
|
31
|
+
-- (`IF member_row.personal_workspace_id IS DISTINCT FROM p_workspace_id THEN`
|
|
32
|
+
-- require the workspace membership), and exactly the convergence 0297's
|
|
33
|
+
-- backfill uses.
|
|
34
|
+
--
|
|
35
|
+
-- Phase D forbids inferring user authority from `created_by`, connection
|
|
36
|
+
-- attribution, a default workspace, a resource name, or current access. This is
|
|
37
|
+
-- none of those: the membership row ITSELF names the workspace in its own
|
|
38
|
+
-- `personal_workspace_id` column, written by the 0219 lifecycle capability. It
|
|
39
|
+
-- is STATED authority read from the authority table, not derived evidence. The
|
|
40
|
+
-- pointer is 1:1 - 0218's unique
|
|
41
|
+
-- `organization_memberships_personal_workspace_idx` on
|
|
42
|
+
-- (account_id, personal_workspace_id) means at most one membership can name a
|
|
43
|
+
-- given workspace, and `organization_memberships_account_subject_idx` means at
|
|
44
|
+
-- most one membership exists per (account, subject). There is no second
|
|
45
|
+
-- candidate to disambiguate.
|
|
46
|
+
--
|
|
47
|
+
-- The ordinary shared-workspace path is UNCHANGED. A human with no
|
|
48
|
+
-- `workspace_memberships` row in an ordinary workspace still resolves to no
|
|
49
|
+
-- owner there, because the new disjunct only fires for the workspace their own
|
|
50
|
+
-- membership row points at.
|
|
51
|
+
--
|
|
52
|
+
-- MAKING THE SILENT MISS LOUD
|
|
53
|
+
-- ---------------------------
|
|
54
|
+
-- The original `SELECT ... INTO` has no `IF NOT FOUND` handling, so "this
|
|
55
|
+
-- session legitimately has no human owner" and "the resolver failed to project
|
|
56
|
+
-- an owner that exists" are byte-identical outcomes. That is precisely why the
|
|
57
|
+
-- defect above stayed invisible for seven migrations.
|
|
58
|
+
--
|
|
59
|
+
-- Genuinely-ownerless cases are preserved verbatim and must stay NULL:
|
|
60
|
+
-- * `created_by_kind <> 'subject'` (service initiators, the scheduler, the
|
|
61
|
+
-- pre-0096 `unattributed-legacy` default) never enters this branch at all;
|
|
62
|
+
-- * `api_key:*` / `configured:*` subjects, which 0219 and 0263 gate to
|
|
63
|
+
-- `user:%` and which can therefore never acquire an organization anchor;
|
|
64
|
+
-- * a `user:` subject with no ACTIVE organization membership;
|
|
65
|
+
-- * a `user:` subject with an active membership but no stated authority over
|
|
66
|
+
-- an ordinary shared workspace.
|
|
67
|
+
--
|
|
68
|
+
-- What is now loud instead: a `subject`-kind creator who HAS an active
|
|
69
|
+
-- organization membership, inserting into a workspace that is the
|
|
70
|
+
-- `personal_workspace_id` of an active membership, that still resolved to no
|
|
71
|
+
-- owner. A personal workspace has exactly one possible human owner by
|
|
72
|
+
-- construction (the 1:1 unique index above) and deliberately carries no
|
|
73
|
+
-- `workspace_memberships` row, so an unowned subject-created session there is a
|
|
74
|
+
-- resolver defect, not a legitimate `workspace_shared` session. It raises
|
|
75
|
+
-- SQLSTATE 55000 rather than writing NULL.
|
|
76
|
+
--
|
|
77
|
+
-- This cannot fire on the repaired path: when the creator IS the personal
|
|
78
|
+
-- workspace's member the new disjunct resolves them. It fires only when the two
|
|
79
|
+
-- durable facts disagree - a subject creating a session inside somebody else's
|
|
80
|
+
-- personal workspace, which 0219's access model makes unreachable - or if a
|
|
81
|
+
-- future change breaks the resolver again. A SUSPENDED or REVOKED member is
|
|
82
|
+
-- excluded from both the resolver and the classifier by the same
|
|
83
|
+
-- `status = 'active'` predicate, so their personal-workspace sessions stay
|
|
84
|
+
-- ownerless without raising, exactly as before.
|
|
85
|
+
--
|
|
86
|
+
-- ROLLING SAFETY
|
|
87
|
+
-- --------------
|
|
88
|
+
-- This migration replaces one function body and nothing else: no column, index,
|
|
89
|
+
-- constraint, policy, grant, or trigger definition changes. Old API and worker
|
|
90
|
+
-- images keep running against it unchanged - they never name the owner columns
|
|
91
|
+
-- on INSERT, which is what makes the derivation branch fire in the first place.
|
|
92
|
+
-- The new behaviour is strictly a widening plus an assertion over a population
|
|
93
|
+
-- that 0219 makes unreachable. There is no data rewrite here; historical rows
|
|
94
|
+
-- remain the shipped `bun run db:backfill-session-ownership` seam's job (0297).
|
|
95
|
+
|
|
96
|
+
SET LOCAL lock_timeout = '5s';
|
|
97
|
+
SET LOCAL statement_timeout = '5min';
|
|
98
|
+
|
|
99
|
+
DO $session_personal_workspace_ownership$
|
|
100
|
+
DECLARE
|
|
101
|
+
data_schema text := current_schema();
|
|
102
|
+
BEGIN
|
|
103
|
+
EXECUTE format($ddl$
|
|
104
|
+
CREATE OR REPLACE FUNCTION %1$I.guard_session_authority_write()
|
|
105
|
+
RETURNS trigger
|
|
106
|
+
LANGUAGE plpgsql
|
|
107
|
+
SECURITY DEFINER
|
|
108
|
+
SET search_path = %1$I, pg_catalog
|
|
109
|
+
AS $body$
|
|
110
|
+
DECLARE
|
|
111
|
+
resolved_owner_id uuid;
|
|
112
|
+
resolved_owner_subject_id text;
|
|
113
|
+
creator_has_active_membership boolean;
|
|
114
|
+
owner_provenance_supplied boolean :=
|
|
115
|
+
NEW.owner_organization_membership_id IS NOT NULL
|
|
116
|
+
OR NEW.owner_subject_id IS NOT NULL;
|
|
117
|
+
previous_lifecycle_marker text := pg_catalog.current_setting(
|
|
118
|
+
'opengeni.organization_tenancy_lifecycle', true
|
|
119
|
+
);
|
|
120
|
+
BEGIN
|
|
121
|
+
IF TG_OP = 'INSERT'
|
|
122
|
+
AND NEW.owner_organization_membership_id IS NULL
|
|
123
|
+
AND NEW.owner_subject_id IS NULL
|
|
124
|
+
THEN
|
|
125
|
+
IF NEW.parent_session_id IS NOT NULL THEN
|
|
126
|
+
SELECT parent.owner_organization_membership_id, parent.owner_subject_id
|
|
127
|
+
INTO resolved_owner_id, resolved_owner_subject_id
|
|
128
|
+
FROM sessions parent
|
|
129
|
+
WHERE parent.account_id = NEW.account_id
|
|
130
|
+
AND parent.workspace_id = NEW.workspace_id
|
|
131
|
+
AND parent.id = NEW.parent_session_id;
|
|
132
|
+
ELSIF NEW.created_by_kind = 'subject'
|
|
133
|
+
AND NEW.created_by_subject_id IS NOT NULL
|
|
134
|
+
THEN
|
|
135
|
+
PERFORM pg_catalog.set_config(
|
|
136
|
+
'opengeni.organization_tenancy_lifecycle',
|
|
137
|
+
'session_visibility_activation',
|
|
138
|
+
true
|
|
139
|
+
);
|
|
140
|
+
SELECT membership.id, membership.subject_id
|
|
141
|
+
INTO resolved_owner_id, resolved_owner_subject_id
|
|
142
|
+
FROM organization_memberships membership
|
|
143
|
+
WHERE membership.account_id = NEW.account_id
|
|
144
|
+
AND membership.subject_id = NEW.created_by_subject_id
|
|
145
|
+
AND membership.status = 'active'
|
|
146
|
+
AND (
|
|
147
|
+
-- Stated authority, read from the authority row itself: a managed
|
|
148
|
+
-- human's personal workspace has no workspace_memberships row by
|
|
149
|
+
-- design (0219), so the membership's own personal-workspace
|
|
150
|
+
-- pointer is the authority for exactly that one workspace. Same
|
|
151
|
+
-- shape as 0258's personal Document authority.
|
|
152
|
+
--
|
|
153
|
+
-- Restricted to `user:%%` because 0219 and 0263 gate the ENTIRE
|
|
154
|
+
-- managed-human lifecycle - provisioning, invitation, acceptance
|
|
155
|
+
-- - to that prefix. A personal-workspace pointer on an
|
|
156
|
+
-- `api_key:`/`configured:` membership is not a shape any
|
|
157
|
+
-- lifecycle can produce, and 0297's classifier calls that lane
|
|
158
|
+
-- (`external_lane_owns_row`) permanently unrepairable. The write
|
|
159
|
+
-- path must not attribute what the classifier refuses.
|
|
160
|
+
(
|
|
161
|
+
NEW.created_by_subject_id LIKE 'user:%%'
|
|
162
|
+
AND membership.personal_workspace_id = NEW.workspace_id
|
|
163
|
+
)
|
|
164
|
+
OR EXISTS (
|
|
165
|
+
SELECT 1
|
|
166
|
+
FROM workspace_memberships workspace_membership
|
|
167
|
+
WHERE workspace_membership.account_id = NEW.account_id
|
|
168
|
+
AND workspace_membership.workspace_id = NEW.workspace_id
|
|
169
|
+
AND workspace_membership.subject_id = membership.subject_id
|
|
170
|
+
)
|
|
171
|
+
);
|
|
172
|
+
IF NOT FOUND THEN
|
|
173
|
+
-- Classify the miss instead of writing an indistinguishable NULL.
|
|
174
|
+
SELECT EXISTS (
|
|
175
|
+
SELECT 1
|
|
176
|
+
FROM organization_memberships creator_membership
|
|
177
|
+
WHERE creator_membership.account_id = NEW.account_id
|
|
178
|
+
AND creator_membership.subject_id = NEW.created_by_subject_id
|
|
179
|
+
AND creator_membership.status = 'active'
|
|
180
|
+
AND NEW.created_by_subject_id LIKE 'user:%%'
|
|
181
|
+
) INTO creator_has_active_membership;
|
|
182
|
+
IF creator_has_active_membership
|
|
183
|
+
AND EXISTS (
|
|
184
|
+
SELECT 1
|
|
185
|
+
FROM organization_memberships personal_owner
|
|
186
|
+
WHERE personal_owner.account_id = NEW.account_id
|
|
187
|
+
AND personal_owner.personal_workspace_id = NEW.workspace_id
|
|
188
|
+
AND personal_owner.status = 'active'
|
|
189
|
+
AND personal_owner.subject_id LIKE 'user:%%'
|
|
190
|
+
)
|
|
191
|
+
THEN
|
|
192
|
+
RAISE EXCEPTION
|
|
193
|
+
'session owner authority is unresolved in a personal workspace'
|
|
194
|
+
USING ERRCODE = '55000';
|
|
195
|
+
END IF;
|
|
196
|
+
-- Otherwise genuinely ownerless: no active organization membership,
|
|
197
|
+
-- or no stated authority over an ordinary shared workspace.
|
|
198
|
+
END IF;
|
|
199
|
+
END IF;
|
|
200
|
+
NEW.owner_organization_membership_id := resolved_owner_id;
|
|
201
|
+
NEW.owner_subject_id := resolved_owner_subject_id;
|
|
202
|
+
PERFORM pg_catalog.set_config(
|
|
203
|
+
'opengeni.organization_tenancy_lifecycle',
|
|
204
|
+
CASE WHEN previous_lifecycle_marker IS NULL THEN '' ELSE previous_lifecycle_marker END,
|
|
205
|
+
true
|
|
206
|
+
);
|
|
207
|
+
END IF;
|
|
208
|
+
|
|
209
|
+
IF (NEW.owner_organization_membership_id IS NULL)
|
|
210
|
+
<> (NEW.owner_subject_id IS NULL)
|
|
211
|
+
OR (NEW.visibility = 'user_private'
|
|
212
|
+
AND NEW.owner_organization_membership_id IS NULL)
|
|
213
|
+
THEN
|
|
214
|
+
RAISE EXCEPTION 'session authority owner provenance is incomplete'
|
|
215
|
+
USING ERRCODE = '23514';
|
|
216
|
+
END IF;
|
|
217
|
+
|
|
218
|
+
IF TG_OP = 'UPDATE'
|
|
219
|
+
AND (
|
|
220
|
+
NEW.visibility IS DISTINCT FROM OLD.visibility
|
|
221
|
+
OR NEW.owner_organization_membership_id
|
|
222
|
+
IS DISTINCT FROM OLD.owner_organization_membership_id
|
|
223
|
+
OR NEW.owner_subject_id IS DISTINCT FROM OLD.owner_subject_id
|
|
224
|
+
OR NEW.authority_epoch IS DISTINCT FROM OLD.authority_epoch
|
|
225
|
+
OR NEW.forked_from_session_id IS DISTINCT FROM OLD.forked_from_session_id
|
|
226
|
+
OR NEW.forked_from_authority_epoch
|
|
227
|
+
IS DISTINCT FROM OLD.forked_from_authority_epoch
|
|
228
|
+
OR NEW.forked_from_visibility IS DISTINCT FROM OLD.forked_from_visibility
|
|
229
|
+
OR NEW.forked_at IS DISTINCT FROM OLD.forked_at
|
|
230
|
+
OR NEW.forked_by_organization_membership_id
|
|
231
|
+
IS DISTINCT FROM OLD.forked_by_organization_membership_id
|
|
232
|
+
)
|
|
233
|
+
AND NOT EXISTS (
|
|
234
|
+
SELECT 1
|
|
235
|
+
FROM session_visibility_write_capabilities capability
|
|
236
|
+
WHERE capability.backend_pid = pg_catalog.pg_backend_pid()
|
|
237
|
+
AND capability.transaction_id = pg_catalog.pg_current_xact_id()
|
|
238
|
+
AND capability.capability_id = nullif(
|
|
239
|
+
pg_catalog.current_setting(
|
|
240
|
+
'opengeni.session_visibility_write_capability', true
|
|
241
|
+
),
|
|
242
|
+
''
|
|
243
|
+
)::uuid
|
|
244
|
+
)
|
|
245
|
+
THEN
|
|
246
|
+
RAISE EXCEPTION 'session authority changes require the lifecycle capability'
|
|
247
|
+
USING ERRCODE = '42501';
|
|
248
|
+
END IF;
|
|
249
|
+
|
|
250
|
+
IF TG_OP = 'INSERT'
|
|
251
|
+
AND (
|
|
252
|
+
NEW.visibility <> 'workspace_shared'
|
|
253
|
+
OR NEW.authority_epoch <> 1
|
|
254
|
+
OR NEW.forked_from_session_id IS NOT NULL
|
|
255
|
+
OR NEW.forked_from_authority_epoch IS NOT NULL
|
|
256
|
+
OR NEW.forked_from_visibility IS NOT NULL
|
|
257
|
+
OR NEW.forked_at IS NOT NULL
|
|
258
|
+
OR NEW.forked_by_organization_membership_id IS NOT NULL
|
|
259
|
+
OR owner_provenance_supplied
|
|
260
|
+
)
|
|
261
|
+
AND NOT EXISTS (
|
|
262
|
+
SELECT 1
|
|
263
|
+
FROM session_visibility_write_capabilities capability
|
|
264
|
+
WHERE capability.backend_pid = pg_catalog.pg_backend_pid()
|
|
265
|
+
AND capability.transaction_id = pg_catalog.pg_current_xact_id()
|
|
266
|
+
AND capability.capability_id = nullif(
|
|
267
|
+
pg_catalog.current_setting(
|
|
268
|
+
'opengeni.session_visibility_write_capability', true
|
|
269
|
+
),
|
|
270
|
+
''
|
|
271
|
+
)::uuid
|
|
272
|
+
)
|
|
273
|
+
THEN
|
|
274
|
+
RAISE EXCEPTION 'non-default session authority requires the lifecycle capability'
|
|
275
|
+
USING ERRCODE = '42501';
|
|
276
|
+
END IF;
|
|
277
|
+
RETURN NEW;
|
|
278
|
+
EXCEPTION WHEN OTHERS THEN
|
|
279
|
+
PERFORM pg_catalog.set_config(
|
|
280
|
+
'opengeni.organization_tenancy_lifecycle',
|
|
281
|
+
CASE WHEN previous_lifecycle_marker IS NULL THEN '' ELSE previous_lifecycle_marker END,
|
|
282
|
+
true
|
|
283
|
+
);
|
|
284
|
+
RAISE;
|
|
285
|
+
END;
|
|
286
|
+
$body$;
|
|
287
|
+
$ddl$, data_schema);
|
|
288
|
+
|
|
289
|
+
EXECUTE format(
|
|
290
|
+
'COMMENT ON FUNCTION %I.guard_session_authority_write() IS %L',
|
|
291
|
+
data_schema,
|
|
292
|
+
'Session authority write fence (0225, repaired by 0302). On INSERT it '
|
|
293
|
+
|| 'derives the owner pair from the parent session, or from the '
|
|
294
|
+
|| 'creator''s active organization membership when that membership '
|
|
295
|
+
|| 'states authority over the session workspace - either an explicit '
|
|
296
|
+
|| 'workspace_memberships row or the membership''s own '
|
|
297
|
+
|| 'personal_workspace_id pointer, which is the only authority a managed '
|
|
298
|
+
|| 'human''s membershipless personal workspace has. A subject-created '
|
|
299
|
+
|| 'session that resolves to no owner inside an active membership''s '
|
|
300
|
+
|| 'personal workspace raises 55000 instead of silently writing NULL.'
|
|
301
|
+
);
|
|
302
|
+
END
|
|
303
|
+
$session_personal_workspace_ownership$;
|