@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,64 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
SET lock_timeout = '5s';
|
|
3
|
+
SET statement_timeout = '10min';
|
|
4
|
+
|
|
5
|
+
-- Agent-declared goal continuation hold.
|
|
6
|
+
--
|
|
7
|
+
-- An orchestrator whose active goal depends on child sessions or an external
|
|
8
|
+
-- event can call the first-party `goal_wait` tool instead of busy-polling. The
|
|
9
|
+
-- hold is additive state on the goal row: the exact turn that declared it, the
|
|
10
|
+
-- mandatory deadline, a bounded reason, and when it was recorded. The
|
|
11
|
+
-- continuation materializer honors the hold only while the declaring turn is
|
|
12
|
+
-- still the latest finished turn and the deadline has not passed; it never
|
|
13
|
+
-- consumes the wake/observed revision ledger, so a crash cannot lose the
|
|
14
|
+
-- obligation. Any newer finished turn, a passed deadline, or a human/API/agent
|
|
15
|
+
-- goal mutation clears all four columns together.
|
|
16
|
+
--
|
|
17
|
+
-- An old worker that ignores these columns keeps the prior behaviour
|
|
18
|
+
-- (immediate continuation), so this is a rolling, additive change with no
|
|
19
|
+
-- backfill.
|
|
20
|
+
|
|
21
|
+
ALTER TABLE "session_goals"
|
|
22
|
+
ADD COLUMN IF NOT EXISTS "continuation_hold_turn_id" uuid,
|
|
23
|
+
ADD COLUMN IF NOT EXISTS "continuation_hold_until" timestamptz,
|
|
24
|
+
ADD COLUMN IF NOT EXISTS "continuation_hold_reason" text,
|
|
25
|
+
ADD COLUMN IF NOT EXISTS "continuation_hold_set_at" timestamptz;
|
|
26
|
+
|
|
27
|
+
DO $constraints$
|
|
28
|
+
BEGIN
|
|
29
|
+
IF NOT EXISTS (
|
|
30
|
+
SELECT 1 FROM pg_constraint
|
|
31
|
+
WHERE conname = 'session_goals_continuation_hold_check'
|
|
32
|
+
AND conrelid = 'session_goals'::regclass
|
|
33
|
+
) THEN
|
|
34
|
+
ALTER TABLE "session_goals"
|
|
35
|
+
ADD CONSTRAINT "session_goals_continuation_hold_check"
|
|
36
|
+
CHECK (
|
|
37
|
+
(
|
|
38
|
+
"continuation_hold_turn_id" IS NULL
|
|
39
|
+
AND "continuation_hold_until" IS NULL
|
|
40
|
+
AND "continuation_hold_reason" IS NULL
|
|
41
|
+
AND "continuation_hold_set_at" IS NULL
|
|
42
|
+
)
|
|
43
|
+
OR (
|
|
44
|
+
"continuation_hold_turn_id" IS NOT NULL
|
|
45
|
+
AND "continuation_hold_until" IS NOT NULL
|
|
46
|
+
AND "continuation_hold_set_at" IS NOT NULL
|
|
47
|
+
AND (
|
|
48
|
+
"continuation_hold_reason" IS NULL
|
|
49
|
+
OR octet_length("continuation_hold_reason") <= 2048
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
END IF;
|
|
54
|
+
END
|
|
55
|
+
$constraints$;
|
|
56
|
+
|
|
57
|
+
COMMENT ON COLUMN "session_goals"."continuation_hold_turn_id" IS
|
|
58
|
+
'Exact turn that declared the goal_wait hold; the hold applies only while this is the latest finished turn.';
|
|
59
|
+
COMMENT ON COLUMN "session_goals"."continuation_hold_until" IS
|
|
60
|
+
'Mandatory hold deadline; the materializer re-arms a delayed workflow wake at this time and clears the hold once it passes.';
|
|
61
|
+
COMMENT ON COLUMN "session_goals"."continuation_hold_reason" IS
|
|
62
|
+
'Bounded (2 KiB) agent-declared reason for the hold.';
|
|
63
|
+
COMMENT ON COLUMN "session_goals"."continuation_hold_set_at" IS
|
|
64
|
+
'When the hold was recorded.';
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Per-turn startup-milestone ledger.
|
|
3
|
+
--
|
|
4
|
+
-- The turn-startup SLO receipts (queue, provider_dispatch, first_byte) used to
|
|
5
|
+
-- be decided by re-reading the turn's `session_events` rows on every inserted
|
|
6
|
+
-- `turn.started`, `agent.model.request started|first_byte|first_event`, and
|
|
7
|
+
-- `turn.failed` event: "is the event this transaction just inserted the
|
|
8
|
+
-- lowest-sequence canonical checkpoint of its kind in the turn?". That lookup
|
|
9
|
+
-- is O(events in the turn) per model request, each examined row pays the
|
|
10
|
+
-- session-events RLS predicate, and it runs inside the event-append
|
|
11
|
+
-- transaction that holds the workspace inference-control row FOR SHARE. On a
|
|
12
|
+
-- long orchestrator turn it held that row for tens of seconds per model
|
|
13
|
+
-- request and starved every FOR UPDATE taker (Send/Steer/Pause).
|
|
14
|
+
--
|
|
15
|
+
-- This table makes "the first inserter of each checkpoint wins" a single
|
|
16
|
+
-- primary-key probe: the transaction that appends a checkpoint event performs
|
|
17
|
+
-- `INSERT ... ON CONFLICT DO NOTHING RETURNING`, and only a returned row is a
|
|
18
|
+
-- metric receipt. Ordinary attempt recovery and callback replay conflict and
|
|
19
|
+
-- stay no-ops, exactly as before. Writers already hold the turn row FOR UPDATE
|
|
20
|
+
-- (the canonical event-write lock order), so the conflict clause is
|
|
21
|
+
-- idempotency, not a race resolver.
|
|
22
|
+
--
|
|
23
|
+
-- Rollout: turns whose `turn.started` was already durable before a
|
|
24
|
+
-- ledger-aware writer touched them (in flight across the deploy, or claimed by
|
|
25
|
+
-- a pre-ledger worker during the rolling window) are recognised at their next
|
|
26
|
+
-- `turn.started` claim through one bounded index probe for an earlier current
|
|
27
|
+
-- `turn.started` row, and sealed with `pre_ledger_history` sentinel rows for
|
|
28
|
+
-- every completed checkpoint. Such a turn emits no further startup receipts
|
|
29
|
+
-- (it already observed them, or may have) instead of re-observing a checkpoint
|
|
30
|
+
-- with a duration equal to its age. No migration-time backfill over
|
|
31
|
+
-- FORCE-RLS tables is required.
|
|
32
|
+
|
|
33
|
+
SET LOCAL lock_timeout = '5s';
|
|
34
|
+
SET LOCAL statement_timeout = '10min';
|
|
35
|
+
|
|
36
|
+
CREATE TABLE "session_turn_startup_milestones" (
|
|
37
|
+
"account_id" uuid NOT NULL,
|
|
38
|
+
"workspace_id" uuid NOT NULL,
|
|
39
|
+
"session_id" uuid NOT NULL,
|
|
40
|
+
"turn_id" uuid NOT NULL,
|
|
41
|
+
"milestone" text NOT NULL,
|
|
42
|
+
"outcome" text NOT NULL,
|
|
43
|
+
"canonical_source" text NOT NULL,
|
|
44
|
+
"event_id" uuid,
|
|
45
|
+
"occurred_at" timestamptz,
|
|
46
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
47
|
+
CONSTRAINT "session_turn_startup_milestones_pkey"
|
|
48
|
+
PRIMARY KEY ("workspace_id", "turn_id", "milestone", "outcome"),
|
|
49
|
+
CONSTRAINT "session_turn_startup_milestones_workspace_account_fk"
|
|
50
|
+
FOREIGN KEY ("workspace_id", "account_id")
|
|
51
|
+
REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
|
|
52
|
+
CONSTRAINT "session_turn_startup_milestones_workspace_session_fk"
|
|
53
|
+
FOREIGN KEY ("workspace_id", "session_id")
|
|
54
|
+
REFERENCES "sessions"("workspace_id", "id") ON DELETE CASCADE,
|
|
55
|
+
CONSTRAINT "session_turn_startup_milestones_workspace_turn_fk"
|
|
56
|
+
FOREIGN KEY ("workspace_id", "turn_id")
|
|
57
|
+
REFERENCES "session_turns"("workspace_id", "id") ON DELETE CASCADE,
|
|
58
|
+
CONSTRAINT "session_turn_startup_milestones_milestone_chk"
|
|
59
|
+
CHECK ("milestone" IN ('queue', 'provider_dispatch', 'first_byte')),
|
|
60
|
+
CONSTRAINT "session_turn_startup_milestones_outcome_chk"
|
|
61
|
+
CHECK ("outcome" IN ('completed', 'failed')),
|
|
62
|
+
CONSTRAINT "session_turn_startup_milestones_checkpoint_chk"
|
|
63
|
+
CHECK ("outcome" = 'completed' OR "milestone" = 'first_byte'),
|
|
64
|
+
CONSTRAINT "session_turn_startup_milestones_canonical_source_chk" CHECK (
|
|
65
|
+
(
|
|
66
|
+
"canonical_source" = 'inserted_event'
|
|
67
|
+
AND "event_id" IS NOT NULL
|
|
68
|
+
AND "occurred_at" IS NOT NULL
|
|
69
|
+
)
|
|
70
|
+
OR (
|
|
71
|
+
"canonical_source" = 'pre_ledger_history'
|
|
72
|
+
AND "outcome" = 'completed'
|
|
73
|
+
AND "event_id" IS NULL
|
|
74
|
+
AND "occurred_at" IS NULL
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
-- The session FK cascade must not sequentially scan the ledger per deleted
|
|
80
|
+
-- session; the turn and workspace FKs are covered by the primary-key prefix.
|
|
81
|
+
CREATE INDEX "session_turn_startup_milestones_workspace_session_idx"
|
|
82
|
+
ON "session_turn_startup_milestones" ("workspace_id", "session_id");
|
|
83
|
+
|
|
84
|
+
ALTER TABLE "session_turn_startup_milestones" ENABLE ROW LEVEL SECURITY;
|
|
85
|
+
ALTER TABLE "session_turn_startup_milestones" FORCE ROW LEVEL SECURITY;
|
|
86
|
+
CREATE POLICY workspace_isolation ON "session_turn_startup_milestones"
|
|
87
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
88
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
|
89
|
+
CREATE POLICY session_visibility_isolation ON "session_turn_startup_milestones"
|
|
90
|
+
AS RESTRICTIVE
|
|
91
|
+
USING (session_reference_visible(
|
|
92
|
+
"account_id", "workspace_id", "session_id"
|
|
93
|
+
))
|
|
94
|
+
WITH CHECK (session_reference_visible(
|
|
95
|
+
"account_id", "workspace_id", "session_id"
|
|
96
|
+
));
|
|
97
|
+
|
|
98
|
+
-- The runtime role claims (INSERT), fences (SELECT), and seals pre-ledger turns
|
|
99
|
+
-- (UPDATE of the turn's own queue row); rows leave only through the turn
|
|
100
|
+
-- cascade. `db:provision-roles` re-converges the same posture.
|
|
101
|
+
DO $grants$
|
|
102
|
+
BEGIN
|
|
103
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
104
|
+
GRANT SELECT, INSERT, UPDATE ON "session_turn_startup_milestones" TO opengeni_app;
|
|
105
|
+
REVOKE DELETE ON "session_turn_startup_milestones" FROM opengeni_app;
|
|
106
|
+
END IF;
|
|
107
|
+
END
|
|
108
|
+
$grants$;
|
|
109
|
+
|
|
110
|
+
COMMENT ON TABLE "session_turn_startup_milestones" IS
|
|
111
|
+
'Per-turn startup SLO checkpoint ledger: one row per (turn, milestone, outcome). The transaction whose INSERT ... ON CONFLICT DO NOTHING returns the row is the canonical inserter and the sole metric receipt; recovery and replay conflict. pre_ledger_history rows seal a turn whose startup predates the ledger so it never re-observes a checkpoint.';
|
|
112
|
+
COMMENT ON COLUMN "session_turn_startup_milestones"."canonical_source" IS
|
|
113
|
+
'inserted_event: event_id/occurred_at name the canonical checkpoint event inserted by the claiming transaction. pre_ledger_history: the checkpoint was (or may have been) durable before any ledger-aware writer touched the turn; identity is deliberately not recovered from session_events.';
|
|
114
|
+
COMMENT ON COLUMN "session_turn_startup_milestones"."occurred_at" IS
|
|
115
|
+
'The canonical event''s own occurred_at; the receipt duration is measured from session_turns.created_at to this instant.';
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Generic event-triggered automations. Sources authenticate ingress, immutable
|
|
3
|
+
-- trigger revisions own matching/session templates, events retain normalized
|
|
4
|
+
-- occurrence truth, and runs freeze the exact session execution admitted for
|
|
5
|
+
-- one logical occurrence. Agent execution remains an ordinary session.
|
|
6
|
+
|
|
7
|
+
SET LOCAL lock_timeout = '5s';
|
|
8
|
+
SET LOCAL statement_timeout = '10min';
|
|
9
|
+
|
|
10
|
+
CREATE UNIQUE INDEX IF NOT EXISTS pack_installations_workspace_id_uq
|
|
11
|
+
ON pack_installations(workspace_id, id);
|
|
12
|
+
|
|
13
|
+
CREATE TABLE automation_sources (
|
|
14
|
+
id uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid(),
|
|
15
|
+
endpoint_id uuid NOT NULL DEFAULT pg_catalog.gen_random_uuid(),
|
|
16
|
+
account_id uuid NOT NULL REFERENCES managed_accounts(id) ON DELETE CASCADE,
|
|
17
|
+
workspace_id uuid NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
18
|
+
name text NOT NULL,
|
|
19
|
+
adapter_id text NOT NULL,
|
|
20
|
+
configuration jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
21
|
+
webhook_secret_encrypted text NOT NULL,
|
|
22
|
+
status text NOT NULL DEFAULT 'active',
|
|
23
|
+
version integer NOT NULL DEFAULT 1,
|
|
24
|
+
pack_installation_id uuid,
|
|
25
|
+
pack_connector_id text,
|
|
26
|
+
created_by_subject_id text NOT NULL,
|
|
27
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
28
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
29
|
+
CONSTRAINT automation_sources_workspace_account_fk FOREIGN KEY (workspace_id, account_id)
|
|
30
|
+
REFERENCES workspaces(id, account_id) ON DELETE CASCADE,
|
|
31
|
+
CONSTRAINT automation_sources_pack_installation_fk
|
|
32
|
+
FOREIGN KEY (workspace_id, pack_installation_id)
|
|
33
|
+
REFERENCES pack_installations(workspace_id, id) ON DELETE CASCADE,
|
|
34
|
+
CONSTRAINT automation_sources_shape_chk CHECK (
|
|
35
|
+
status IN ('active', 'disabled') AND version > 0
|
|
36
|
+
AND octet_length(name) BETWEEN 1 AND 512
|
|
37
|
+
AND octet_length(adapter_id) BETWEEN 1 AND 128
|
|
38
|
+
AND octet_length(created_by_subject_id) BETWEEN 1 AND 4096
|
|
39
|
+
AND jsonb_typeof(configuration) = 'object'
|
|
40
|
+
AND ((pack_installation_id IS NULL AND pack_connector_id IS NULL)
|
|
41
|
+
OR (pack_installation_id IS NOT NULL
|
|
42
|
+
AND octet_length(pack_connector_id) BETWEEN 1 AND 128))
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
CREATE UNIQUE INDEX automation_sources_endpoint_uq ON automation_sources(endpoint_id);
|
|
46
|
+
CREATE UNIQUE INDEX automation_sources_workspace_id_uq ON automation_sources(workspace_id, id);
|
|
47
|
+
CREATE INDEX automation_sources_workspace_status_idx ON automation_sources(workspace_id, status);
|
|
48
|
+
|
|
49
|
+
-- Credential-free routing only. The endpoint UUID discovers the tenant/source;
|
|
50
|
+
-- the FORCE-RLS source row and its encrypted secret still authenticate ingress.
|
|
51
|
+
CREATE TABLE automation_webhook_endpoints (
|
|
52
|
+
endpoint_id uuid PRIMARY KEY,
|
|
53
|
+
account_id uuid NOT NULL REFERENCES managed_accounts(id) ON DELETE CASCADE,
|
|
54
|
+
workspace_id uuid NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
55
|
+
source_id uuid NOT NULL UNIQUE REFERENCES automation_sources(id) ON DELETE CASCADE,
|
|
56
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
57
|
+
CONSTRAINT automation_webhook_endpoints_workspace_account_fk FOREIGN KEY (workspace_id, account_id)
|
|
58
|
+
REFERENCES workspaces(id, account_id) ON DELETE CASCADE
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
CREATE TABLE automation_triggers (
|
|
62
|
+
id uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid(),
|
|
63
|
+
account_id uuid NOT NULL REFERENCES managed_accounts(id) ON DELETE CASCADE,
|
|
64
|
+
workspace_id uuid NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
65
|
+
source_id uuid NOT NULL,
|
|
66
|
+
name text NOT NULL,
|
|
67
|
+
status text NOT NULL DEFAULT 'active',
|
|
68
|
+
current_revision integer NOT NULL DEFAULT 1,
|
|
69
|
+
pack_installation_id uuid,
|
|
70
|
+
pack_template_id text,
|
|
71
|
+
created_by_subject_id text NOT NULL,
|
|
72
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
73
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
74
|
+
CONSTRAINT automation_triggers_workspace_account_fk FOREIGN KEY (workspace_id, account_id)
|
|
75
|
+
REFERENCES workspaces(id, account_id) ON DELETE CASCADE,
|
|
76
|
+
CONSTRAINT automation_triggers_source_fk FOREIGN KEY (workspace_id, source_id)
|
|
77
|
+
REFERENCES automation_sources(workspace_id, id) ON DELETE CASCADE,
|
|
78
|
+
CONSTRAINT automation_triggers_pack_installation_fk
|
|
79
|
+
FOREIGN KEY (workspace_id, pack_installation_id)
|
|
80
|
+
REFERENCES pack_installations(workspace_id, id) ON DELETE CASCADE,
|
|
81
|
+
CONSTRAINT automation_triggers_shape_chk CHECK (
|
|
82
|
+
status IN ('active', 'paused', 'disabled') AND current_revision > 0
|
|
83
|
+
AND octet_length(name) BETWEEN 1 AND 512
|
|
84
|
+
AND octet_length(created_by_subject_id) BETWEEN 1 AND 4096
|
|
85
|
+
AND ((pack_installation_id IS NULL AND pack_template_id IS NULL)
|
|
86
|
+
OR (pack_installation_id IS NOT NULL AND octet_length(pack_template_id) BETWEEN 1 AND 128))
|
|
87
|
+
)
|
|
88
|
+
);
|
|
89
|
+
CREATE UNIQUE INDEX automation_triggers_workspace_id_uq ON automation_triggers(workspace_id, id);
|
|
90
|
+
CREATE UNIQUE INDEX automation_triggers_workspace_source_id_uq
|
|
91
|
+
ON automation_triggers(workspace_id, id, source_id);
|
|
92
|
+
CREATE INDEX automation_triggers_workspace_status_idx ON automation_triggers(workspace_id, status);
|
|
93
|
+
|
|
94
|
+
CREATE TABLE automation_trigger_revisions (
|
|
95
|
+
trigger_id uuid NOT NULL,
|
|
96
|
+
revision integer NOT NULL,
|
|
97
|
+
account_id uuid NOT NULL,
|
|
98
|
+
workspace_id uuid NOT NULL,
|
|
99
|
+
adapter_id text NOT NULL,
|
|
100
|
+
event_types jsonb NOT NULL,
|
|
101
|
+
configuration jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
102
|
+
parameters jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
103
|
+
session_template jsonb NOT NULL,
|
|
104
|
+
created_by_subject_id text NOT NULL,
|
|
105
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
106
|
+
PRIMARY KEY (trigger_id, revision),
|
|
107
|
+
CONSTRAINT automation_trigger_revisions_trigger_fk FOREIGN KEY (workspace_id, trigger_id)
|
|
108
|
+
REFERENCES automation_triggers(workspace_id, id) ON DELETE CASCADE,
|
|
109
|
+
CONSTRAINT automation_trigger_revisions_workspace_account_fk FOREIGN KEY (workspace_id, account_id)
|
|
110
|
+
REFERENCES workspaces(id, account_id) ON DELETE CASCADE,
|
|
111
|
+
CONSTRAINT automation_trigger_revisions_shape_chk CHECK (
|
|
112
|
+
revision > 0 AND octet_length(adapter_id) BETWEEN 1 AND 128
|
|
113
|
+
AND jsonb_typeof(event_types) = 'array' AND jsonb_array_length(event_types) BETWEEN 1 AND 64
|
|
114
|
+
AND jsonb_typeof(configuration) = 'object'
|
|
115
|
+
AND jsonb_typeof(parameters) = 'object'
|
|
116
|
+
AND jsonb_typeof(session_template) = 'object'
|
|
117
|
+
)
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
CREATE TABLE automation_trigger_events (
|
|
121
|
+
id uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid(),
|
|
122
|
+
account_id uuid NOT NULL,
|
|
123
|
+
workspace_id uuid NOT NULL,
|
|
124
|
+
source_id uuid NOT NULL,
|
|
125
|
+
source_version integer NOT NULL,
|
|
126
|
+
source_configuration jsonb NOT NULL,
|
|
127
|
+
matched_trigger_revisions jsonb NOT NULL,
|
|
128
|
+
delivery_key text NOT NULL,
|
|
129
|
+
request_digest text NOT NULL,
|
|
130
|
+
adapter_id text NOT NULL,
|
|
131
|
+
event_type text NOT NULL,
|
|
132
|
+
occurrence_key text NOT NULL,
|
|
133
|
+
normalized_event jsonb NOT NULL,
|
|
134
|
+
status text NOT NULL DEFAULT 'accepted',
|
|
135
|
+
ignored_reason text,
|
|
136
|
+
error_code text,
|
|
137
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
138
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
139
|
+
CONSTRAINT automation_trigger_events_source_fk FOREIGN KEY (workspace_id, source_id)
|
|
140
|
+
REFERENCES automation_sources(workspace_id, id) ON DELETE CASCADE,
|
|
141
|
+
CONSTRAINT automation_trigger_events_workspace_account_fk FOREIGN KEY (workspace_id, account_id)
|
|
142
|
+
REFERENCES workspaces(id, account_id) ON DELETE CASCADE,
|
|
143
|
+
CONSTRAINT automation_trigger_events_shape_chk CHECK (
|
|
144
|
+
status IN ('accepted', 'ignored', 'failed')
|
|
145
|
+
AND source_version > 0
|
|
146
|
+
AND jsonb_typeof(source_configuration) = 'object'
|
|
147
|
+
AND jsonb_typeof(matched_trigger_revisions) = 'array'
|
|
148
|
+
AND jsonb_array_length(matched_trigger_revisions) <= 32
|
|
149
|
+
AND request_digest ~ '^[0-9a-f]{64}$'
|
|
150
|
+
AND octet_length(delivery_key) BETWEEN 1 AND 1024
|
|
151
|
+
AND octet_length(event_type) BETWEEN 1 AND 256
|
|
152
|
+
AND octet_length(occurrence_key) BETWEEN 1 AND 1024
|
|
153
|
+
AND jsonb_typeof(normalized_event) = 'object'
|
|
154
|
+
)
|
|
155
|
+
);
|
|
156
|
+
CREATE UNIQUE INDEX automation_trigger_events_source_delivery_uq
|
|
157
|
+
ON automation_trigger_events(source_id, delivery_key);
|
|
158
|
+
CREATE INDEX automation_trigger_events_workspace_created_idx
|
|
159
|
+
ON automation_trigger_events(workspace_id, created_at);
|
|
160
|
+
CREATE UNIQUE INDEX automation_trigger_events_workspace_source_id_uq
|
|
161
|
+
ON automation_trigger_events(workspace_id, source_id, id);
|
|
162
|
+
|
|
163
|
+
CREATE TABLE automation_runs (
|
|
164
|
+
id uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid(),
|
|
165
|
+
account_id uuid NOT NULL,
|
|
166
|
+
workspace_id uuid NOT NULL,
|
|
167
|
+
source_id uuid NOT NULL,
|
|
168
|
+
trigger_id uuid NOT NULL,
|
|
169
|
+
trigger_revision integer NOT NULL,
|
|
170
|
+
event_id uuid NOT NULL,
|
|
171
|
+
occurrence_key text NOT NULL,
|
|
172
|
+
accepted_execution jsonb NOT NULL,
|
|
173
|
+
status text NOT NULL DEFAULT 'queued',
|
|
174
|
+
session_id uuid REFERENCES sessions(id) ON DELETE SET NULL,
|
|
175
|
+
error_code text,
|
|
176
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
177
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
178
|
+
CONSTRAINT automation_runs_trigger_revision_fk FOREIGN KEY (trigger_id, trigger_revision)
|
|
179
|
+
REFERENCES automation_trigger_revisions(trigger_id, revision) ON DELETE RESTRICT,
|
|
180
|
+
CONSTRAINT automation_runs_source_fk FOREIGN KEY (workspace_id, source_id)
|
|
181
|
+
REFERENCES automation_sources(workspace_id, id) ON DELETE RESTRICT,
|
|
182
|
+
CONSTRAINT automation_runs_trigger_source_fk FOREIGN KEY (workspace_id, trigger_id, source_id)
|
|
183
|
+
REFERENCES automation_triggers(workspace_id, id, source_id) ON DELETE RESTRICT,
|
|
184
|
+
CONSTRAINT automation_runs_event_fk FOREIGN KEY (workspace_id, source_id, event_id)
|
|
185
|
+
REFERENCES automation_trigger_events(workspace_id, source_id, id) ON DELETE RESTRICT,
|
|
186
|
+
CONSTRAINT automation_runs_workspace_account_fk FOREIGN KEY (workspace_id, account_id)
|
|
187
|
+
REFERENCES workspaces(id, account_id) ON DELETE CASCADE,
|
|
188
|
+
CONSTRAINT automation_runs_shape_chk CHECK (
|
|
189
|
+
trigger_revision > 0
|
|
190
|
+
AND status IN ('queued', 'dispatching', 'dispatched', 'skipped', 'failed')
|
|
191
|
+
AND octet_length(occurrence_key) BETWEEN 1 AND 1024
|
|
192
|
+
AND jsonb_typeof(accepted_execution) = 'object'
|
|
193
|
+
)
|
|
194
|
+
);
|
|
195
|
+
CREATE UNIQUE INDEX automation_runs_trigger_occurrence_uq
|
|
196
|
+
ON automation_runs(trigger_id, occurrence_key);
|
|
197
|
+
CREATE INDEX automation_runs_workspace_status_idx
|
|
198
|
+
ON automation_runs(workspace_id, status, created_at);
|
|
199
|
+
CREATE UNIQUE INDEX automation_runs_workspace_trigger_id_uq
|
|
200
|
+
ON automation_runs(workspace_id, trigger_id, id);
|
|
201
|
+
|
|
202
|
+
CREATE TABLE automation_run_event_links (
|
|
203
|
+
run_id uuid NOT NULL REFERENCES automation_runs(id) ON DELETE CASCADE,
|
|
204
|
+
event_id uuid NOT NULL REFERENCES automation_trigger_events(id) ON DELETE CASCADE,
|
|
205
|
+
account_id uuid NOT NULL,
|
|
206
|
+
workspace_id uuid NOT NULL,
|
|
207
|
+
source_id uuid NOT NULL,
|
|
208
|
+
trigger_id uuid NOT NULL,
|
|
209
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
210
|
+
PRIMARY KEY (run_id, event_id),
|
|
211
|
+
CONSTRAINT automation_run_event_links_workspace_account_fk FOREIGN KEY (workspace_id, account_id)
|
|
212
|
+
REFERENCES workspaces(id, account_id) ON DELETE CASCADE,
|
|
213
|
+
CONSTRAINT automation_run_event_links_run_fk FOREIGN KEY (workspace_id, trigger_id, run_id)
|
|
214
|
+
REFERENCES automation_runs(workspace_id, trigger_id, id) ON DELETE CASCADE,
|
|
215
|
+
CONSTRAINT automation_run_event_links_event_fk FOREIGN KEY (workspace_id, source_id, event_id)
|
|
216
|
+
REFERENCES automation_trigger_events(workspace_id, source_id, id) ON DELETE CASCADE
|
|
217
|
+
);
|
|
218
|
+
CREATE UNIQUE INDEX automation_run_event_links_event_trigger_uq
|
|
219
|
+
ON automation_run_event_links(event_id, trigger_id);
|
|
220
|
+
|
|
221
|
+
ALTER TABLE automation_sources ENABLE ROW LEVEL SECURITY;
|
|
222
|
+
ALTER TABLE automation_sources FORCE ROW LEVEL SECURITY;
|
|
223
|
+
ALTER TABLE automation_triggers ENABLE ROW LEVEL SECURITY;
|
|
224
|
+
ALTER TABLE automation_triggers FORCE ROW LEVEL SECURITY;
|
|
225
|
+
ALTER TABLE automation_trigger_revisions ENABLE ROW LEVEL SECURITY;
|
|
226
|
+
ALTER TABLE automation_trigger_revisions FORCE ROW LEVEL SECURITY;
|
|
227
|
+
ALTER TABLE automation_trigger_events ENABLE ROW LEVEL SECURITY;
|
|
228
|
+
ALTER TABLE automation_trigger_events FORCE ROW LEVEL SECURITY;
|
|
229
|
+
ALTER TABLE automation_runs ENABLE ROW LEVEL SECURITY;
|
|
230
|
+
ALTER TABLE automation_runs FORCE ROW LEVEL SECURITY;
|
|
231
|
+
ALTER TABLE automation_run_event_links ENABLE ROW LEVEL SECURITY;
|
|
232
|
+
ALTER TABLE automation_run_event_links FORCE ROW LEVEL SECURITY;
|
|
233
|
+
|
|
234
|
+
CREATE POLICY automation_sources_tenant ON automation_sources
|
|
235
|
+
USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
|
|
236
|
+
WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
|
|
237
|
+
CREATE POLICY automation_triggers_tenant ON automation_triggers
|
|
238
|
+
USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
|
|
239
|
+
WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
|
|
240
|
+
CREATE POLICY automation_trigger_revisions_tenant ON automation_trigger_revisions
|
|
241
|
+
USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
|
|
242
|
+
WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
|
|
243
|
+
CREATE POLICY automation_trigger_events_tenant ON automation_trigger_events
|
|
244
|
+
USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
|
|
245
|
+
WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
|
|
246
|
+
CREATE POLICY automation_runs_tenant ON automation_runs
|
|
247
|
+
USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
|
|
248
|
+
WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
|
|
249
|
+
CREATE POLICY automation_run_event_links_tenant ON automation_run_event_links
|
|
250
|
+
USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
|
|
251
|
+
WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
|
|
252
|
+
CREATE POLICY session_visibility_isolation ON automation_runs AS RESTRICTIVE
|
|
253
|
+
USING (session_reference_visible(account_id, workspace_id, session_id))
|
|
254
|
+
WITH CHECK (session_reference_visible(account_id, workspace_id, session_id));
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
SET lock_timeout = '5s';
|
|
3
|
+
SET statement_timeout = '60s';
|
|
4
|
+
|
|
5
|
+
-- The PR Review Pack is a provider-neutral adapter over the generic automation
|
|
6
|
+
-- substrate. App registrations own only provider action credentials; generic
|
|
7
|
+
-- automation sources own webhook authentication and generic triggers/runs own
|
|
8
|
+
-- event matching, idempotency, and ordinary-session dispatch.
|
|
9
|
+
|
|
10
|
+
CREATE TABLE "pr_review_app_registrations" (
|
|
11
|
+
"id" uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid(),
|
|
12
|
+
"source_id" uuid NOT NULL,
|
|
13
|
+
"account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
|
|
14
|
+
"workspace_id" uuid NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
|
|
15
|
+
"name" text NOT NULL,
|
|
16
|
+
"provider" text NOT NULL,
|
|
17
|
+
"provider_base_url" text NOT NULL,
|
|
18
|
+
"app_id" text,
|
|
19
|
+
"credential_kind" text NOT NULL,
|
|
20
|
+
"credential_encrypted" text,
|
|
21
|
+
"access_token_expires_at" timestamptz,
|
|
22
|
+
"webhook_auth_kind" text NOT NULL,
|
|
23
|
+
"webhook_username" text,
|
|
24
|
+
"status" text NOT NULL DEFAULT 'active',
|
|
25
|
+
"created_by_subject_id" text NOT NULL,
|
|
26
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
27
|
+
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
28
|
+
CONSTRAINT "pr_review_app_registrations_workspace_account_fk"
|
|
29
|
+
FOREIGN KEY ("workspace_id", "account_id")
|
|
30
|
+
REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
|
|
31
|
+
CONSTRAINT "pr_review_app_registrations_source_fk"
|
|
32
|
+
FOREIGN KEY ("workspace_id", "source_id")
|
|
33
|
+
REFERENCES "automation_sources"("workspace_id", "id") ON DELETE CASCADE,
|
|
34
|
+
CONSTRAINT "pr_review_app_registrations_provider_chk"
|
|
35
|
+
CHECK ("provider" IN ('github', 'gitlab', 'azure_devops')),
|
|
36
|
+
CONSTRAINT "pr_review_app_registrations_credential_chk" CHECK (
|
|
37
|
+
("provider" = 'github' AND "credential_kind" = 'github_app' AND "credential_encrypted" IS NOT NULL AND "app_id" IS NOT NULL)
|
|
38
|
+
OR
|
|
39
|
+
("provider" IN ('gitlab', 'azure_devops') AND "credential_kind" = 'provider_token' AND "credential_encrypted" IS NOT NULL)
|
|
40
|
+
),
|
|
41
|
+
CONSTRAINT "pr_review_app_registrations_webhook_auth_chk" CHECK (
|
|
42
|
+
("provider" = 'github' AND "webhook_auth_kind" = 'hmac_sha256')
|
|
43
|
+
OR ("provider" = 'gitlab' AND "webhook_auth_kind" = 'shared_token')
|
|
44
|
+
OR ("provider" = 'azure_devops' AND "webhook_auth_kind" = 'basic' AND "webhook_username" IS NOT NULL)
|
|
45
|
+
),
|
|
46
|
+
CONSTRAINT "pr_review_app_registrations_status_chk"
|
|
47
|
+
CHECK ("status" IN ('active', 'disabled'))
|
|
48
|
+
);
|
|
49
|
+
CREATE UNIQUE INDEX "pr_review_app_registrations_workspace_id_uq"
|
|
50
|
+
ON "pr_review_app_registrations" ("workspace_id", "id");
|
|
51
|
+
CREATE UNIQUE INDEX "pr_review_app_registrations_workspace_id_provider_uq"
|
|
52
|
+
ON "pr_review_app_registrations" ("workspace_id", "id", "provider");
|
|
53
|
+
CREATE UNIQUE INDEX "pr_review_app_registrations_workspace_provider_name_uq"
|
|
54
|
+
ON "pr_review_app_registrations" ("workspace_id", "provider", "name");
|
|
55
|
+
CREATE INDEX "pr_review_app_registrations_workspace_status_idx"
|
|
56
|
+
ON "pr_review_app_registrations" ("workspace_id", "status");
|
|
57
|
+
CREATE UNIQUE INDEX "pr_review_app_registrations_source_uq"
|
|
58
|
+
ON "pr_review_app_registrations" ("source_id");
|
|
59
|
+
|
|
60
|
+
CREATE TABLE "pr_review_repository_bindings" (
|
|
61
|
+
"id" uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid(),
|
|
62
|
+
"trigger_id" uuid NOT NULL,
|
|
63
|
+
"account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
|
|
64
|
+
"workspace_id" uuid NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
|
|
65
|
+
"registration_id" uuid NOT NULL,
|
|
66
|
+
"provider" text NOT NULL,
|
|
67
|
+
"repository_uri" text NOT NULL,
|
|
68
|
+
"repository_full_name" text NOT NULL,
|
|
69
|
+
"provider_repository_id" text NOT NULL,
|
|
70
|
+
"installation_id" text,
|
|
71
|
+
"project_id" text,
|
|
72
|
+
"model" text,
|
|
73
|
+
"additional_instructions" text,
|
|
74
|
+
"status" text NOT NULL DEFAULT 'active',
|
|
75
|
+
"created_by_subject_id" text NOT NULL,
|
|
76
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
77
|
+
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
78
|
+
CONSTRAINT "pr_review_repository_bindings_workspace_account_fk"
|
|
79
|
+
FOREIGN KEY ("workspace_id", "account_id")
|
|
80
|
+
REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
|
|
81
|
+
CONSTRAINT "pr_review_repository_bindings_trigger_fk"
|
|
82
|
+
FOREIGN KEY ("workspace_id", "trigger_id")
|
|
83
|
+
REFERENCES "automation_triggers"("workspace_id", "id") ON DELETE CASCADE,
|
|
84
|
+
CONSTRAINT "pr_review_repository_bindings_registration_fk"
|
|
85
|
+
FOREIGN KEY ("workspace_id", "registration_id", "provider")
|
|
86
|
+
REFERENCES "pr_review_app_registrations"("workspace_id", "id", "provider") ON DELETE CASCADE,
|
|
87
|
+
CONSTRAINT "pr_review_repository_bindings_provider_chk"
|
|
88
|
+
CHECK ("provider" IN ('github', 'gitlab', 'azure_devops')),
|
|
89
|
+
CONSTRAINT "pr_review_repository_bindings_status_chk"
|
|
90
|
+
CHECK ("status" IN ('active', 'disabled'))
|
|
91
|
+
);
|
|
92
|
+
CREATE UNIQUE INDEX "pr_review_repository_bindings_workspace_id_uq"
|
|
93
|
+
ON "pr_review_repository_bindings" ("workspace_id", "id");
|
|
94
|
+
CREATE UNIQUE INDEX "pr_review_repo_workspace_registration_provider_uq"
|
|
95
|
+
ON "pr_review_repository_bindings" ("workspace_id", "id", "registration_id", "provider");
|
|
96
|
+
CREATE UNIQUE INDEX "pr_review_repository_bindings_registration_repo_uq"
|
|
97
|
+
ON "pr_review_repository_bindings" ("registration_id", "provider_repository_id");
|
|
98
|
+
CREATE INDEX "pr_review_repository_bindings_workspace_status_idx"
|
|
99
|
+
ON "pr_review_repository_bindings" ("workspace_id", "status");
|
|
100
|
+
CREATE UNIQUE INDEX "pr_review_repository_bindings_trigger_uq"
|
|
101
|
+
ON "pr_review_repository_bindings" ("trigger_id");
|
|
102
|
+
|
|
103
|
+
ALTER TABLE "pr_review_app_registrations" ENABLE ROW LEVEL SECURITY;
|
|
104
|
+
ALTER TABLE "pr_review_app_registrations" FORCE ROW LEVEL SECURITY;
|
|
105
|
+
CREATE POLICY pr_review_app_registrations_tenant ON "pr_review_app_registrations"
|
|
106
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
107
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
|
108
|
+
|
|
109
|
+
ALTER TABLE "pr_review_repository_bindings" ENABLE ROW LEVEL SECURITY;
|
|
110
|
+
ALTER TABLE "pr_review_repository_bindings" FORCE ROW LEVEL SECURITY;
|
|
111
|
+
CREATE POLICY pr_review_repository_bindings_tenant ON "pr_review_repository_bindings"
|
|
112
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
113
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Slack app and bot names are environment-scoped human-facing identity. Keep
|
|
3
|
+
-- the accepted set closed while allowing the managed staging principal to be
|
|
4
|
+
-- visibly distinct from production in a shared Slack workspace.
|
|
5
|
+
ALTER TABLE slack_installation_bindings
|
|
6
|
+
DROP CONSTRAINT slack_installation_bindings_identity_check;
|
|
7
|
+
|
|
8
|
+
ALTER TABLE slack_installation_bindings
|
|
9
|
+
ADD CONSTRAINT slack_installation_bindings_identity_check CHECK (
|
|
10
|
+
octet_length(slack_team_id) BETWEEN 1 AND 64
|
|
11
|
+
AND octet_length(slack_team_name) BETWEEN 1 AND 256
|
|
12
|
+
AND octet_length(bot_id) BETWEEN 1 AND 64
|
|
13
|
+
AND octet_length(bot_user_id) BETWEEN 1 AND 64
|
|
14
|
+
AND bot_display_name IN ('OpenGeni', 'OpenGeni Staging')
|
|
15
|
+
);
|