@opengeni/db 3.1.0-canary.0 → 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/canonical-human-identities.js +3 -3
- package/dist/{chunk-NMUBV7Z5.js → chunk-2EH4WRHL.js} +2 -2
- package/dist/{chunk-NJVZPWXY.js → chunk-2PRS4J5Q.js} +3 -3
- package/dist/{chunk-TIKF3KTI.js → chunk-6HMM2R5T.js} +11 -4
- package/dist/chunk-6HMM2R5T.js.map +1 -0
- package/dist/{chunk-SCPUJS53.js → chunk-AZHW7R5V.js} +17 -9
- package/dist/chunk-AZHW7R5V.js.map +1 -0
- package/dist/{chunk-EULAN2NP.js → chunk-E6CLMKEE.js} +2 -2
- package/dist/{chunk-PR2WMLOQ.js → chunk-KRLPEMLH.js} +12 -1
- package/dist/chunk-KRLPEMLH.js.map +1 -0
- package/dist/{chunk-ZZ5LJEFX.js → chunk-NAB6FKFN.js} +3 -3
- package/dist/{chunk-OF5OBB76.js → chunk-UZNXG44K.js} +56 -5
- package/dist/chunk-UZNXG44K.js.map +1 -0
- package/dist/connection-tenancy-backfill.d.ts +44 -0
- package/dist/database.d.ts +4 -4
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +12 -1
- package/dist/index.js +1384 -1078
- package/dist/index.js.map +1 -1
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +9 -2
- package/dist/schema.js +1 -1
- package/dist/session-background-commands.js +3 -3
- package/dist/session-queue-commands.d.ts +2 -0
- package/dist/session-tenancy.js +3 -3
- package/dist/slack-routing.d.ts +115 -0
- package/dist/slack-user-link-access.d.ts +27 -0
- package/dist/video-generation.js +3 -3
- 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 +6 -6
- package/src/connection-tenancy-backfill.ts +86 -0
- package/src/database.ts +12 -0
- package/src/index.ts +25 -2
- package/src/organization-membership-lifecycle.ts +15 -5
- package/src/provision-roles.ts +28 -0
- package/src/runtime-posture.ts +31 -1
- package/src/schema.ts +13 -0
- package/src/session-queue-commands.ts +4 -1
- package/src/session-realtime-context.ts +1 -3
- package/src/session-realtime-ledger.ts +6 -3
- package/src/session-tenancy.ts +7 -0
- package/src/slack-routing.ts +399 -1
- package/src/slack-user-link-access.ts +121 -10
- package/dist/chunk-OF5OBB76.js.map +0 -1
- package/dist/chunk-PR2WMLOQ.js.map +0 -1
- package/dist/chunk-SCPUJS53.js.map +0 -1
- package/dist/chunk-TIKF3KTI.js.map +0 -1
- /package/dist/{chunk-NMUBV7Z5.js.map → chunk-2EH4WRHL.js.map} +0 -0
- /package/dist/{chunk-NJVZPWXY.js.map → chunk-2PRS4J5Q.js.map} +0 -0
- /package/dist/{chunk-EULAN2NP.js.map → chunk-E6CLMKEE.js.map} +0 -0
- /package/dist/{chunk-ZZ5LJEFX.js.map → chunk-NAB6FKFN.js.map} +0 -0
package/dist/provision-roles.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { Database, RlsStrategy } from "./database.js";
|
|
2
|
-
export declare const RUNTIME_TARGET_SCHEMA_CAPABILITY_ROUTINES: readonly ["company_brain_inspect_context_receipts(uuid, uuid, text, uuid, timestamp with time zone, uuid, integer)", "company_brain_context_get_or_create_selection(uuid, uuid, uuid, uuid, uuid, integer)", "propose_company_profile_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, text, text)", "confirm_company_profile_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid)", "evaluate_governed_learning_proposal(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid, uuid, uuid)", "activate_governed_learning_decision(uuid, uuid, uuid, uuid)", "activate_human_confirmed_learning_decision(uuid, uuid, uuid, uuid, uuid)", "confirm_remember_knowledge_claim(uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid)", "undo_governed_learning_activation(uuid, uuid, uuid, uuid)", "inspect_governed_learning_decisions(uuid, uuid, text, integer)", "inspect_governed_learning_activations(uuid, uuid, text, integer)", "inspect_governed_learning_activation_undos(uuid, uuid, text, integer)", "fork_session_content(uuid, uuid, uuid, text, uuid, text, boolean, text, text, integer)", "fork_session_content(uuid, uuid, uuid, text, uuid, text, text, text, integer)", "replay_applied_session_fork(uuid, uuid, uuid, text, uuid, text, boolean, text, text, integer)", "session_tenancy_product_activated(uuid, integer)", "session_tenancy_any_product_activation()", "xai_subscription_authority_live(uuid, uuid, text, uuid, text, uuid, uuid, bigint)", "create_xai_subscription_credential(uuid, uuid, text, text, text, text, text, text, text, timestamp with time zone)", "disconnect_xai_subscription_credential(uuid, uuid, text, uuid, jsonb)", "google_drive_document_citation(uuid, uuid, text, uuid, uuid)", "google_drive_file_authorized(uuid, uuid, text, uuid)", "knowledge_source_sync_lock_authority(uuid, uuid, uuid)", "ensure_managed_human_personal_workspace(uuid, text, uuid)", "list_self_organization_memberships(text)", "list_self_organization_invitations(text)", "list_self_organization_invitations(text, uuid, integer)", "get_self_organization_invitation(text, uuid)", "list_organization_invitations(uuid, text, uuid, integer)", "list_organization_members(uuid, text)", "get_organization_administration_overview(uuid, text)", "create_managed_organization(text, text, text, uuid)", "assert_organization_shared_workspace_administrator(uuid, uuid, text)", "open_organization_shared_workspace_administration_capability(uuid, uuid, text)", "close_organization_shared_workspace_administration_capability(uuid)", "create_organization_shared_workspace(uuid, text, text, text, text, uuid)", "upsert_organization_shared_workspace_member(uuid, uuid, text, uuid, text, text, jsonb, boolean)", "update_organization_name(uuid, text, text, timestamp with time zone, uuid)", "create_organization_invitation_v2(jsonb)", "bind_pending_organization_invitations_for_verified_email(text, text)", "has_pending_organization_invitation_for_subject(text)", "accept_organization_invitation_v2(jsonb)", "organization_membership_command(jsonb)", "prepare_organization_membership_protocol_settlements(jsonb)", "assert_active_managed_human_organization_membership(uuid, text)", "resolve_workspace_writer_grant_identity(uuid, text)", "prepare_workspace_membership_removal_settlements(jsonb)", "workspace_membership_removal_command(jsonb)", "get_organization_retention_policy(uuid, text)", "preview_organization_retention_deletions(uuid, integer)", "claim_organization_retention_deletion(uuid, uuid, uuid[])", "list_organization_retention_deletion_objects(uuid, uuid, uuid, text, integer)", "record_organization_retention_object_deleted(uuid, uuid, uuid, text, text, text, text)", "fail_organization_retention_deletion(uuid, uuid, uuid, text)", "finalize_organization_retention_deletion(uuid, uuid, uuid, text)", "complete_organization_retention_deletion(uuid, uuid, uuid, text)", ...string[], "open_private_session_create_capability(uuid, uuid, uuid, text)", "open_private_child_session_create_capability(uuid, uuid, uuid, uuid, uuid, uuid, integer)", "close_private_session_create_capability(uuid)", "resolve_session_attempt_personal_resources(uuid, uuid, uuid)", "accept_turn_personal_resource_attachment(uuid, uuid, uuid, uuid, text, integer, boolean, integer)", "list_self_user_resource_authorities(uuid, uuid, text, uuid, integer)", "issue_self_user_resource_grant(uuid, uuid, uuid, text, text, text, uuid, integer, boolean)", "revoke_self_user_resource_grant(uuid, uuid, uuid)", "authorize_session_attempt_personal_resource_reads(uuid, uuid, uuid)", "preference_registry_create_knowledge_proposal_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, uuid, text, text, text, text, integer, text, jsonb, timestamp with time zone, text)", "create_scoped_variable_set(uuid, uuid, text, text, text, jsonb, boolean)", "list_scoped_variable_sets(uuid, uuid, uuid, text, text)", "count_scoped_variable_sets(uuid, uuid, text)", "mutate_scoped_variable_set(uuid, uuid, uuid, text, text, boolean, text, boolean, text, text, boolean)", "read_scoped_variable_set_secret(uuid, uuid, uuid, text, text, text, uuid, uuid, uuid, integer)", "materialize_scoped_variable_set_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid)", "materialize_scoped_variable_set_for_session(uuid, uuid, uuid, uuid)", "resolve_personal_connection_authority_selection(uuid, uuid, text, uuid, jsonb)", "resolve_accepted_connection_use(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, text, uuid, text, text, text, text)", "resolve_connection_use_authority(uuid, uuid, uuid, jsonb)", "get_self_personal_github_repository_selection(uuid, uuid, text, uuid)", "mutate_self_personal_github_repository_selection(uuid, uuid, text, uuid, bigint, bigint, text, jsonb, boolean)", "create_personal_document_authority(uuid, uuid, uuid)", "resolve_document_original_file(uuid, uuid, text, uuid)", "resolve_session_attempt_personal_document_reads(uuid, uuid, uuid, uuid)", "list_document_authority_reclassifications(uuid, uuid, text, uuid, integer, timestamp with time zone, uuid)", "reclassify_document_authority(jsonb)", "run_document_default_collection_backfill(jsonb)", "create_scoped_rig(uuid, uuid, text, text, text, text, jsonb, boolean)", "list_scoped_rigs(uuid, uuid, uuid, text, text)", "count_scoped_rigs(uuid, uuid, text)", "mutate_scoped_rig(uuid, uuid, uuid, text, text, boolean, text, boolean, boolean)", "finalize_scoped_enrollment(uuid, uuid, text, text, boolean, boolean, text, text, text, boolean)", "list_scoped_enrollments(uuid, uuid, uuid, text)", "get_scoped_sandbox(uuid, uuid, uuid)", "authorize_scoped_sandbox_attach(uuid, uuid, uuid)", "materialize_scoped_rig_version_for_attempt(uuid, uuid, uuid, uuid, uuid, integer)", "authorize_session_attempt_personal_machine(uuid, uuid, uuid, uuid, uuid, integer, uuid)", "assert_session_attempt_personal_machine(uuid, uuid, uuid, uuid, uuid, integer, uuid, boolean)", "list_scoped_machine_dependent_sessions(uuid, uuid, uuid)", "detach_scoped_machine_dependent_sessions(uuid, uuid, uuid)", "freeze_scheduled_task_personal_resources(uuid, uuid, uuid, bigint)", "clone_scheduled_task_personal_resource_authority(uuid, uuid, uuid, bigint, bigint)", "refresh_scheduled_task_personal_resources_clone_connections(uuid, uuid, uuid, bigint, bigint)", "create_scheduled_agent_run_with_admission(uuid, uuid, uuid, uuid, bigint, text, text, text, timestamp with time zone, timestamp with time zone, jsonb)", "materialize_scheduled_task_reusable_session_from_run(uuid, uuid, uuid, uuid, uuid, bigint, text)", "scheduled_task_run_personal_resource_authority(uuid, uuid, uuid)", "scheduled_task_run_connection_authority_subject(uuid, uuid, uuid)", "scheduled_task_personal_resource_authority_subject(uuid, uuid, uuid, bigint)", "record_scheduled_task_revision_authority(uuid, uuid, uuid, bigint)", "clone_scheduled_task_revision_authority(uuid, uuid, uuid, bigint, bigint)", "scheduled_task_revision_authority_subject(uuid, uuid, uuid, bigint)", "scheduled_task_revision_authority_snapshot(uuid, uuid, uuid, bigint)", "validate_scheduled_agent_run_live_authority(uuid, uuid, uuid)", "scheduled_scoped_rig_version_metadata(uuid, uuid, text, uuid, uuid)", "scheduled_variable_set_expected_generation_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid)", "bind_scheduled_task_run_session(uuid, uuid, uuid, uuid)", "transition_scheduled_agent_run(uuid, uuid, uuid, uuid, uuid, text, text)", "ensure_canonical_human_identity(text, text)", "validate_canonical_human_session(text, text, boolean)", "get_canonical_human_identity_projection(text)", "apply_canonical_human_identity_operation(uuid, text, bigint, text, uuid, text, text, text)", "create_task_note_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, text, integer)", "archive_task_note_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, integer, text)", "list_task_notes_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, boolean, integer)", "replace_task_note_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid, uuid, integer, text, text, integer, text)", "resolve_task_note_knowledge_promotion_source(uuid, uuid, uuid, uuid, uuid, integer, uuid, integer, text, text, text)", "session_private_actor_visible(uuid, uuid, uuid, text)", "session_reference_visible(uuid, uuid, uuid)", "session_visibility_lifecycle_capability_held()", "transition_session_visibility(uuid, uuid, uuid, text, text, integer, text, text, integer)", "xai_subscription_pool_visible(uuid, uuid, text, text, uuid)", "resolve_xai_authority_pool(uuid, uuid, text, jsonb)", "revalidate_xai_subscription_authority(uuid, text, uuid, jsonb)", "xai_provider_account_authority_snapshot_v1_valid(jsonb)"];
|
|
2
|
+
export declare const RUNTIME_TARGET_SCHEMA_CAPABILITY_ROUTINES: readonly ["company_brain_inspect_context_receipts(uuid, uuid, text, uuid, timestamp with time zone, uuid, integer)", "company_brain_context_get_or_create_selection(uuid, uuid, uuid, uuid, uuid, integer)", "propose_company_profile_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, text, text)", "confirm_company_profile_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid)", "evaluate_governed_learning_proposal(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid, uuid, uuid)", "activate_governed_learning_decision(uuid, uuid, uuid, uuid)", "activate_human_confirmed_learning_decision(uuid, uuid, uuid, uuid, uuid)", "confirm_remember_knowledge_claim(uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid)", "undo_governed_learning_activation(uuid, uuid, uuid, uuid)", "inspect_governed_learning_decisions(uuid, uuid, text, integer)", "inspect_governed_learning_activations(uuid, uuid, text, integer)", "inspect_governed_learning_activation_undos(uuid, uuid, text, integer)", "fork_session_content(uuid, uuid, uuid, text, uuid, text, boolean, text, text, integer)", "fork_session_content(uuid, uuid, uuid, text, uuid, text, text, text, integer)", "replay_applied_session_fork(uuid, uuid, uuid, text, uuid, text, boolean, text, text, integer)", "session_tenancy_product_activated(uuid, integer)", "session_tenancy_any_product_activation()", "xai_subscription_authority_live(uuid, uuid, text, uuid, text, uuid, uuid, bigint)", "create_xai_subscription_credential(uuid, uuid, text, text, text, text, text, text, text, timestamp with time zone)", "disconnect_xai_subscription_credential(uuid, uuid, text, uuid, jsonb)", "google_drive_document_citation(uuid, uuid, text, uuid, uuid)", "google_drive_file_authorized(uuid, uuid, text, uuid)", "knowledge_source_sync_lock_authority(uuid, uuid, uuid)", "ensure_managed_human_personal_workspace(uuid, text, uuid)", "list_self_organization_memberships(text)", "list_self_organization_invitations(text)", "list_self_organization_invitations(text, uuid, integer)", "get_self_organization_invitation(text, uuid)", "list_organization_invitations(uuid, text, uuid, integer)", "list_organization_members(uuid, text)", "get_organization_administration_overview(uuid, text)", "create_managed_organization(text, text, text, uuid)", "assert_organization_shared_workspace_administrator(uuid, uuid, text)", "open_organization_shared_workspace_administration_capability(uuid, uuid, text)", "close_organization_shared_workspace_administration_capability(uuid)", "create_organization_shared_workspace(uuid, text, text, text, text, uuid)", "upsert_organization_shared_workspace_member(uuid, uuid, text, uuid, text, text, jsonb, boolean)", "update_organization_name(uuid, text, text, timestamp with time zone, uuid)", "create_organization_invitation_v2(jsonb)", "bind_pending_organization_invitations_for_verified_email(text, text)", "has_pending_organization_invitation_for_subject(text)", "accept_organization_invitation_v2(jsonb)", "organization_membership_command(jsonb)", "prepare_organization_membership_protocol_settlements(jsonb)", "assert_active_managed_human_organization_membership(uuid, text)", "resolve_workspace_writer_grant_identity(uuid, text)", "prepare_workspace_membership_removal_settlements(jsonb)", "workspace_membership_removal_command(jsonb)", "get_organization_retention_policy(uuid, text)", "preview_organization_retention_deletions(uuid, integer)", "claim_organization_retention_deletion(uuid, uuid, uuid[])", "list_organization_retention_deletion_objects(uuid, uuid, uuid, text, integer)", "record_organization_retention_object_deleted(uuid, uuid, uuid, text, text, text, text)", "fail_organization_retention_deletion(uuid, uuid, uuid, text)", "finalize_organization_retention_deletion(uuid, uuid, uuid, text)", "complete_organization_retention_deletion(uuid, uuid, uuid, text)", ...string[], "open_private_session_create_capability(uuid, uuid, uuid, text)", "open_private_child_session_create_capability(uuid, uuid, uuid, uuid, uuid, uuid, integer)", "close_private_session_create_capability(uuid)", "resolve_session_attempt_personal_resources(uuid, uuid, uuid)", "accept_turn_personal_resource_attachment(uuid, uuid, uuid, uuid, text, integer, boolean, integer)", "list_self_user_resource_authorities(uuid, uuid, text, uuid, integer)", "issue_self_user_resource_grant(uuid, uuid, uuid, text, text, text, uuid, integer, boolean)", "revoke_self_user_resource_grant(uuid, uuid, uuid)", "authorize_session_attempt_personal_resource_reads(uuid, uuid, uuid)", "preference_registry_create_knowledge_proposal_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, uuid, text, text, text, text, integer, text, jsonb, timestamp with time zone, text)", "create_scoped_variable_set(uuid, uuid, text, text, text, jsonb, boolean)", "list_scoped_variable_sets(uuid, uuid, uuid, text, text)", "count_scoped_variable_sets(uuid, uuid, text)", "mutate_scoped_variable_set(uuid, uuid, uuid, text, text, boolean, text, boolean, text, text, boolean)", "read_scoped_variable_set_secret(uuid, uuid, uuid, text, text, text, uuid, uuid, uuid, integer)", "materialize_scoped_variable_set_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid)", "materialize_scoped_variable_set_for_session(uuid, uuid, uuid, uuid)", "connection_authority_convergence_audit_capability_active(uuid)", "resolve_personal_connection_authority_selection(uuid, uuid, text, uuid, jsonb)", "resolve_accepted_connection_use(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, text, uuid, text, text, text, text)", "resolve_connection_use_authority(uuid, uuid, uuid, jsonb)", "inspect_organization_connection_authority_convergence(uuid, integer, uuid)", "get_self_personal_github_repository_selection(uuid, uuid, text, uuid)", "mutate_self_personal_github_repository_selection(uuid, uuid, text, uuid, bigint, bigint, text, jsonb, boolean)", "create_personal_document_authority(uuid, uuid, uuid)", "resolve_document_original_file(uuid, uuid, text, uuid)", "resolve_session_attempt_personal_document_reads(uuid, uuid, uuid, uuid)", "list_document_authority_reclassifications(uuid, uuid, text, uuid, integer, timestamp with time zone, uuid)", "reclassify_document_authority(jsonb)", "run_document_default_collection_backfill(jsonb)", "list_document_default_collection_backfill_runs(jsonb)", "get_document_default_collection_backfill_audit(jsonb)", "list_organization_document_authority_reclassifications(jsonb)", "create_scoped_rig(uuid, uuid, text, text, text, text, jsonb, boolean)", "list_scoped_rigs(uuid, uuid, uuid, text, text)", "count_scoped_rigs(uuid, uuid, text)", "mutate_scoped_rig(uuid, uuid, uuid, text, text, boolean, text, boolean, boolean)", "finalize_scoped_enrollment(uuid, uuid, text, text, boolean, boolean, text, text, text, boolean)", "list_scoped_enrollments(uuid, uuid, uuid, text)", "get_scoped_sandbox(uuid, uuid, uuid)", "authorize_scoped_sandbox_attach(uuid, uuid, uuid)", "materialize_scoped_rig_version_for_attempt(uuid, uuid, uuid, uuid, uuid, integer)", "authorize_session_attempt_personal_machine(uuid, uuid, uuid, uuid, uuid, integer, uuid)", "assert_session_attempt_personal_machine(uuid, uuid, uuid, uuid, uuid, integer, uuid, boolean)", "list_scoped_machine_dependent_sessions(uuid, uuid, uuid)", "detach_scoped_machine_dependent_sessions(uuid, uuid, uuid)", "freeze_scheduled_task_personal_resources(uuid, uuid, uuid, bigint)", "clone_scheduled_task_personal_resource_authority(uuid, uuid, uuid, bigint, bigint)", "refresh_scheduled_task_personal_resources_clone_connections(uuid, uuid, uuid, bigint, bigint)", "create_scheduled_agent_run_with_admission(uuid, uuid, uuid, uuid, bigint, text, text, text, timestamp with time zone, timestamp with time zone, jsonb)", "materialize_scheduled_task_reusable_session_from_run(uuid, uuid, uuid, uuid, uuid, bigint, text)", "scheduled_task_run_personal_resource_authority(uuid, uuid, uuid)", "scheduled_task_run_connection_authority_subject(uuid, uuid, uuid)", "scheduled_task_personal_resource_authority_subject(uuid, uuid, uuid, bigint)", "record_scheduled_task_revision_authority(uuid, uuid, uuid, bigint)", "clone_scheduled_task_revision_authority(uuid, uuid, uuid, bigint, bigint)", "scheduled_task_revision_authority_subject(uuid, uuid, uuid, bigint)", "scheduled_task_revision_authority_snapshot(uuid, uuid, uuid, bigint)", "validate_scheduled_agent_run_live_authority(uuid, uuid, uuid)", "scheduled_scoped_rig_version_metadata(uuid, uuid, text, uuid, uuid)", "scheduled_variable_set_expected_generation_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid)", "bind_scheduled_task_run_session(uuid, uuid, uuid, uuid)", "transition_scheduled_agent_run(uuid, uuid, uuid, uuid, uuid, text, text)", "ensure_canonical_human_identity(text, text)", "validate_canonical_human_session(text, text, boolean)", "get_canonical_human_identity_projection(text)", "apply_canonical_human_identity_operation(uuid, text, bigint, text, uuid, text, text, text)", "create_task_note_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, text, integer)", "archive_task_note_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, integer, text)", "list_task_notes_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, boolean, integer)", "replace_task_note_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid, uuid, integer, text, text, integer, text)", "resolve_task_note_knowledge_promotion_source(uuid, uuid, uuid, uuid, uuid, integer, uuid, integer, text, text, text)", "session_private_actor_visible(uuid, uuid, uuid, text)", "session_reference_visible(uuid, uuid, uuid)", "session_visibility_lifecycle_capability_held()", "transition_session_visibility(uuid, uuid, uuid, text, text, integer, text, text, integer)", "xai_subscription_pool_visible(uuid, uuid, text, text, uuid)", "resolve_xai_authority_pool(uuid, uuid, text, jsonb)", "revalidate_xai_subscription_authority(uuid, text, uuid, jsonb)", "xai_provider_account_authority_snapshot_v1_valid(jsonb)"];
|
|
3
|
+
/**
|
|
4
|
+
* Boolean-only predicates that shared-table RLS policies must be able to
|
|
5
|
+
* evaluate under table owners and SECURITY DEFINER roles unknown at migration
|
|
6
|
+
* time. The capability ledger and the routine that mints its opaque token stay
|
|
7
|
+
* private; only these exact policy predicates may be PUBLIC-executable.
|
|
8
|
+
*/
|
|
9
|
+
export declare const RUNTIME_TARGET_SCHEMA_PUBLIC_POLICY_PREDICATE_ROUTINES: readonly ["connection_authority_convergence_audit_capability_active(uuid)"];
|
|
3
10
|
/** Owner-internal helpers that must exist but must never be callable by the runtime role. */
|
|
4
|
-
export declare const RUNTIME_TARGET_SCHEMA_FORBIDDEN_ROUTINES: readonly ["organization_private_sessions_enabled(uuid)", "assert_session_tenancy_quiescent(uuid, uuid, uuid, boolean)", "check_tenancy_backfill_activation_evidence(uuid)"];
|
|
11
|
+
export declare const RUNTIME_TARGET_SCHEMA_FORBIDDEN_ROUTINES: readonly ["organization_private_sessions_enabled(uuid)", "assert_session_tenancy_quiescent(uuid, uuid, uuid, boolean)", "check_tenancy_backfill_activation_evidence(uuid)", "document_migration_audit_capability_active(text)", "assert_document_migration_audit_authority(jsonb)"];
|
|
5
12
|
export declare const RUNTIME_TARGET_SCHEMA_INVOKER_ROUTINES: readonly ["session_reference_visible(uuid, uuid, uuid)", "xai_provider_account_authority_snapshot_v1_valid(jsonb)"];
|
|
6
13
|
/**
|
|
7
14
|
* The complete standalone tenant-table contract. Adding or removing a
|
package/dist/schema.js
CHANGED
|
@@ -12,9 +12,9 @@ import {
|
|
|
12
12
|
settleClaimedConnectedMachineBackgroundCommand,
|
|
13
13
|
settleConnectedMachineSessionBackgroundCommand,
|
|
14
14
|
settleSessionBackgroundCommandForRetainedProcess
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-NAB6FKFN.js";
|
|
16
|
+
import "./chunk-AZHW7R5V.js";
|
|
17
|
+
import "./chunk-KRLPEMLH.js";
|
|
18
18
|
import "./chunk-PZ5AY32C.js";
|
|
19
19
|
export {
|
|
20
20
|
backgroundCommandActivityForSessions,
|
|
@@ -198,6 +198,8 @@ export declare function submitHumanPromptInTransaction(db: SessionActivityDataba
|
|
|
198
198
|
text: string;
|
|
199
199
|
context: string;
|
|
200
200
|
};
|
|
201
|
+
/** False when the human input originated inside the active realtime provider session. */
|
|
202
|
+
mirrorToRealtime?: boolean;
|
|
201
203
|
source: "user" | "api";
|
|
202
204
|
/** Record the admitted run's durable usage fact in this transaction. */
|
|
203
205
|
recordAgentRunUsage?: boolean;
|
package/dist/session-tenancy.js
CHANGED
|
@@ -14,9 +14,9 @@ import {
|
|
|
14
14
|
replayAppliedSessionFork,
|
|
15
15
|
sessionTenancyProductActivated,
|
|
16
16
|
transitionSessionVisibility
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-6HMM2R5T.js";
|
|
18
|
+
import "./chunk-AZHW7R5V.js";
|
|
19
|
+
import "./chunk-KRLPEMLH.js";
|
|
20
20
|
import "./chunk-PZ5AY32C.js";
|
|
21
21
|
export {
|
|
22
22
|
SessionTenancyAccessError,
|
package/dist/slack-routing.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Database } from "./database.js";
|
|
2
|
+
import * as schema from "./schema.js";
|
|
2
3
|
/** The installation binding's own tenancy: credential, identity, and inbox. */
|
|
3
4
|
export type SlackRouteHome = {
|
|
4
5
|
accountId: string;
|
|
@@ -84,6 +85,10 @@ export declare function probeSlackActionHandleTenancy(db: Database, input: {
|
|
|
84
85
|
connectionId: string;
|
|
85
86
|
handleId: string;
|
|
86
87
|
}): Promise<SlackRouteHome | null>;
|
|
88
|
+
/** Every channel route this installation has, for the admin surface. */
|
|
89
|
+
export declare function listSlackChannelRoutes(db: Database, home: SlackRouteHome, input: {
|
|
90
|
+
connectionId: string;
|
|
91
|
+
}): Promise<SlackChannelRoute[]>;
|
|
87
92
|
export declare function getSlackChannelRoute(db: Database, home: SlackRouteHome, input: {
|
|
88
93
|
connectionId: string;
|
|
89
94
|
slackChannelId: string;
|
|
@@ -151,3 +156,113 @@ export declare function listNamedSubjectSlackRoutableWorkspaces(db: Database, in
|
|
|
151
156
|
accountId: string;
|
|
152
157
|
subjectId: string;
|
|
153
158
|
}): Promise<SlackRoutableWorkspace[]>;
|
|
159
|
+
/** The trigger kinds a picker can be opened from, mirroring the table's CHECK. */
|
|
160
|
+
export type SlackRoutePromptTriggerKind = (typeof schema.slackRoutePrompts.$inferSelect)["triggerKind"];
|
|
161
|
+
/** A pending first-use picker plus the workspaces it offered. */
|
|
162
|
+
export type SlackRoutePrompt = {
|
|
163
|
+
id: string;
|
|
164
|
+
accountId: string;
|
|
165
|
+
workspaceId: string;
|
|
166
|
+
connectionId: string;
|
|
167
|
+
inboxId: string;
|
|
168
|
+
slackTeamId: string;
|
|
169
|
+
slackUserId: string;
|
|
170
|
+
slackChannelId: string;
|
|
171
|
+
slackMessageTs: string;
|
|
172
|
+
providerEventId: string;
|
|
173
|
+
triggerKind: SlackRoutePromptTriggerKind;
|
|
174
|
+
requestText: string;
|
|
175
|
+
hasFiles: boolean;
|
|
176
|
+
slackThreadTs: string | null;
|
|
177
|
+
messageOperationId: string;
|
|
178
|
+
status: "pending" | "answered" | "expired" | "cancelled";
|
|
179
|
+
expiresAt: Date;
|
|
180
|
+
options: readonly SlackRoutePromptOption[];
|
|
181
|
+
};
|
|
182
|
+
export type SlackRoutePromptOption = {
|
|
183
|
+
id: string;
|
|
184
|
+
candidateAccountId: string;
|
|
185
|
+
candidateWorkspaceId: string;
|
|
186
|
+
candidateLabel: string;
|
|
187
|
+
position: number;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Open one first-use picker for a conversation, or return the one already open.
|
|
191
|
+
*
|
|
192
|
+
* Three separate uniques make this idempotent from three directions: Slack's
|
|
193
|
+
* retries of one event collide on `(connection_id, provider_event_id)`, a
|
|
194
|
+
* replayed inbox row collides on `(connection_id, inbox_id)`, and a genuinely
|
|
195
|
+
* different message in the same conversation collides on the partial pending
|
|
196
|
+
* index. The last one is why a second message never posts a second card: the
|
|
197
|
+
* person is already being asked the same question.
|
|
198
|
+
*/
|
|
199
|
+
export declare function openSlackRoutePrompt(db: Database, home: SlackRouteHome, input: {
|
|
200
|
+
connectionId: string;
|
|
201
|
+
inboxId: string;
|
|
202
|
+
slackTeamId: string;
|
|
203
|
+
slackUserId: string;
|
|
204
|
+
slackChannelId: string;
|
|
205
|
+
slackMessageTs: string;
|
|
206
|
+
providerEventId: string;
|
|
207
|
+
triggerKind: SlackRoutePromptTriggerKind;
|
|
208
|
+
requestText: string;
|
|
209
|
+
hasFiles: boolean;
|
|
210
|
+
slackThreadTs: string | null;
|
|
211
|
+
messageOperationId: string;
|
|
212
|
+
expiresAt: Date;
|
|
213
|
+
candidates: readonly SlackRoutableWorkspace[];
|
|
214
|
+
now?: Date;
|
|
215
|
+
}): Promise<{
|
|
216
|
+
opened: boolean;
|
|
217
|
+
prompt: SlackRoutePrompt;
|
|
218
|
+
} | null>;
|
|
219
|
+
/**
|
|
220
|
+
* The prompt one offered button belongs to.
|
|
221
|
+
*
|
|
222
|
+
* The button's `value` is the option row id, which is a UUID precisely because
|
|
223
|
+
* the block-action normalizer already requires that shape. The option rows are a
|
|
224
|
+
* prompt-time SNAPSHOT and are never authority: the caller must re-authorize the
|
|
225
|
+
* chosen workspace live.
|
|
226
|
+
*/
|
|
227
|
+
export declare function getSlackRoutePromptByOption(db: Database, home: SlackRouteHome, optionId: string): Promise<{
|
|
228
|
+
prompt: SlackRoutePrompt;
|
|
229
|
+
chosen: SlackRoutePromptOption;
|
|
230
|
+
} | null>;
|
|
231
|
+
/**
|
|
232
|
+
* Settle a prompt without answering it: the person pressed the cancel action, or
|
|
233
|
+
* it aged out. Only a still-pending row moves, so this cannot overwrite an
|
|
234
|
+
* answer that landed first.
|
|
235
|
+
*/
|
|
236
|
+
export declare function settleSlackRoutePrompt(db: Database, home: SlackRouteHome, input: {
|
|
237
|
+
promptId: string;
|
|
238
|
+
status: "expired" | "cancelled";
|
|
239
|
+
}): Promise<boolean>;
|
|
240
|
+
/**
|
|
241
|
+
* Answer a picker: freeze the choice, remember it, and re-queue the request.
|
|
242
|
+
*
|
|
243
|
+
* All three commit together. The route row is the ask-once memory, so a later
|
|
244
|
+
* message in that conversation never asks again, and the re-queued inbox row is
|
|
245
|
+
* what actually starts the work the person asked for before they were
|
|
246
|
+
* interrupted by the question.
|
|
247
|
+
*
|
|
248
|
+
* The re-queued row carries a DERIVED provider event id, not the original one.
|
|
249
|
+
* The original inbox row still exists and is settled, so re-using its id would
|
|
250
|
+
* collide with the inbox's own `(connection_id, provider_event_id)` dedupe and
|
|
251
|
+
* silently queue nothing at all. Deriving it from the prompt keeps the insert
|
|
252
|
+
* idempotent for exactly this answer, so a double-click cannot create two
|
|
253
|
+
* sessions.
|
|
254
|
+
*
|
|
255
|
+
* Only a still-pending prompt answers. A second click, an expiry sweep, or a
|
|
256
|
+
* cancel that landed first all leave `answered: false` and change nothing.
|
|
257
|
+
*/
|
|
258
|
+
export declare function answerSlackRoutePrompt(db: Database, home: SlackRouteHome, input: {
|
|
259
|
+
promptId: string;
|
|
260
|
+
targetAccountId: string;
|
|
261
|
+
targetWorkspaceId: string;
|
|
262
|
+
answeredBySubjectId: string;
|
|
263
|
+
decidedBySlackUserId: string;
|
|
264
|
+
now?: Date;
|
|
265
|
+
}): Promise<{
|
|
266
|
+
answered: boolean;
|
|
267
|
+
queuedProviderEventId: string | null;
|
|
268
|
+
}>;
|
|
@@ -22,9 +22,32 @@ export type SlackUserLinkAccessMutationInput = {
|
|
|
22
22
|
expectedVersion: number;
|
|
23
23
|
idempotencyKey: string;
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* The Slack team one access request was raised from.
|
|
27
|
+
*
|
|
28
|
+
* The public request shape deliberately omits it, but an approver has to
|
|
29
|
+
* resolve the installation binding to know where the identity link belongs, and
|
|
30
|
+
* for a routed request that is not the workspace being granted.
|
|
31
|
+
*/
|
|
32
|
+
export declare function slackUserLinkAccessRequestTeam(db: Database, input: {
|
|
33
|
+
workspaceId: string;
|
|
34
|
+
requestId: string;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
slackTeamId: string;
|
|
37
|
+
connectionId: string;
|
|
38
|
+
} | null>;
|
|
39
|
+
/**
|
|
40
|
+
* The tenancy an identity link belongs to. See `withSlackIdentityHomeScope`.
|
|
41
|
+
*/
|
|
42
|
+
export type SlackIdentityHome = {
|
|
43
|
+
accountId: string;
|
|
44
|
+
workspaceId: string;
|
|
45
|
+
};
|
|
25
46
|
export type ApproveSlackUserLinkAccessInput = SlackUserLinkAccessMutationInput & {
|
|
26
47
|
role?: string;
|
|
27
48
|
permissions: Permission[];
|
|
49
|
+
/** The installation's tenancy, when it differs from the routed request's. */
|
|
50
|
+
identityHome?: SlackIdentityHome;
|
|
28
51
|
};
|
|
29
52
|
/**
|
|
30
53
|
* Persist one verified Slack bearer as token-free, subject-bound state. A
|
|
@@ -36,6 +59,8 @@ export declare function getSlackUserLinkAccessRequestForSubject(db: Database, in
|
|
|
36
59
|
workspaceId: string;
|
|
37
60
|
requestId: string;
|
|
38
61
|
subjectId: string;
|
|
62
|
+
/** The installation's tenancy, when it differs from the routed request's. */
|
|
63
|
+
identityHome?: SlackIdentityHome;
|
|
39
64
|
}, now?: Date): Promise<SlackUserLinkAccessRequest | null>;
|
|
40
65
|
export declare function requestSlackUserLinkWorkspaceAccess(db: Database, input: SlackUserLinkAccessMutationInput, now?: Date): Promise<SlackUserLinkAccessRequest>;
|
|
41
66
|
export declare function cancelSlackUserLinkAccessRequest(db: Database, input: SlackUserLinkAccessMutationInput, now?: Date): Promise<SlackUserLinkAccessRequest>;
|
|
@@ -50,6 +75,8 @@ export declare function completeSlackUserLinkAccessIfGranted(db: Database, input
|
|
|
50
75
|
workspaceId: string;
|
|
51
76
|
requestId: string;
|
|
52
77
|
subjectId: string;
|
|
78
|
+
/** The installation's tenancy, when it differs from the routed request's. */
|
|
79
|
+
identityHome?: SlackIdentityHome;
|
|
53
80
|
}, now?: Date): Promise<SlackUserLinkAccessRequest | null>;
|
|
54
81
|
export declare function listPendingSlackUserLinkAccessRequests(db: Database, workspaceId: string, now?: Date): Promise<SlackUserLinkAccessRequest[]>;
|
|
55
82
|
export declare function workspaceMembershipPermissionsAllowSlackLink(value: unknown): boolean;
|
package/dist/video-generation.js
CHANGED
|
@@ -29,9 +29,9 @@ import {
|
|
|
29
29
|
settleVideoGenerationFailure,
|
|
30
30
|
settleVideoGenerationReady,
|
|
31
31
|
updateWorkspaceVideoGenerationPolicy
|
|
32
|
-
} from "./chunk-
|
|
33
|
-
import "./chunk-
|
|
34
|
-
import "./chunk-
|
|
32
|
+
} from "./chunk-2PRS4J5Q.js";
|
|
33
|
+
import "./chunk-AZHW7R5V.js";
|
|
34
|
+
import "./chunk-KRLPEMLH.js";
|
|
35
35
|
import "./chunk-PZ5AY32C.js";
|
|
36
36
|
export {
|
|
37
37
|
ACTIVE_VIDEO_GENERATION_STATUSES,
|
|
@@ -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.';
|