@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,930 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
SET lock_timeout = '5s';
|
|
3
|
+
SET statement_timeout = '60s';
|
|
4
|
+
|
|
5
|
+
-- Human-confirmed remember Knowledge approvals reused the 0269 service-review
|
|
6
|
+
-- adapter, whose review reason was hard-coded to
|
|
7
|
+
-- 'Automatic governed-learning activation.' - misleading for an approval the
|
|
8
|
+
-- exact initiating human explicitly confirmed. Add a reason-carrying overload
|
|
9
|
+
-- of `governed_learning_apply_knowledge_review`; the 9-arg signature becomes a
|
|
10
|
+
-- thin wrapper that keeps the legacy automatic wording byte-identical, so the
|
|
11
|
+
-- `governed_learning_guard_service_review` trigger (which resolves the 9-arg
|
|
12
|
+
-- signature's owner as the capability writer) and every existing caller keep
|
|
13
|
+
-- their exact semantics. `confirm_remember_knowledge_claim` then records a
|
|
14
|
+
-- truthful human-confirmed reason.
|
|
15
|
+
|
|
16
|
+
CREATE OR REPLACE FUNCTION governed_learning_apply_knowledge_review(
|
|
17
|
+
p_account_id uuid,
|
|
18
|
+
p_workspace_id uuid,
|
|
19
|
+
p_operation_id uuid,
|
|
20
|
+
p_claim_id uuid,
|
|
21
|
+
p_expected_review_id uuid,
|
|
22
|
+
p_expected_review_revision bigint,
|
|
23
|
+
p_state text,
|
|
24
|
+
p_actor_subject_id text,
|
|
25
|
+
p_initiating_human_subject_id text,
|
|
26
|
+
p_reason text
|
|
27
|
+
) RETURNS SETOF knowledge_claim_reviews
|
|
28
|
+
LANGUAGE plpgsql SECURITY DEFINER AS $$
|
|
29
|
+
DECLARE
|
|
30
|
+
claim_row knowledge_claims%ROWTYPE;
|
|
31
|
+
current_review knowledge_claim_reviews%ROWTYPE;
|
|
32
|
+
result_row knowledge_claim_reviews%ROWTYPE;
|
|
33
|
+
input_hash_value text;
|
|
34
|
+
BEGIN
|
|
35
|
+
IF p_state NOT IN ('approved', 'revoked')
|
|
36
|
+
OR p_actor_subject_id NOT LIKE 'service:governed-learning-activation:%'
|
|
37
|
+
OR length(btrim(p_initiating_human_subject_id)) NOT BETWEEN 1 AND 1024
|
|
38
|
+
OR length(btrim(p_reason)) NOT BETWEEN 1 AND 4096
|
|
39
|
+
THEN
|
|
40
|
+
RAISE EXCEPTION 'governed-learning Knowledge review input is invalid'
|
|
41
|
+
USING ERRCODE = '22023';
|
|
42
|
+
END IF;
|
|
43
|
+
SELECT * INTO claim_row FROM knowledge_claims claim
|
|
44
|
+
WHERE claim.account_id = p_account_id AND claim.id = p_claim_id
|
|
45
|
+
AND claim.scope_kind = 'workspace'
|
|
46
|
+
AND claim.scope_workspace_id = p_workspace_id
|
|
47
|
+
AND claim.scope_subject_id IS NULL
|
|
48
|
+
AND claim.initiating_human_subject_id = p_initiating_human_subject_id
|
|
49
|
+
FOR UPDATE;
|
|
50
|
+
IF NOT FOUND THEN
|
|
51
|
+
RAISE EXCEPTION 'governed-learning Knowledge claim is unavailable' USING ERRCODE = '42501';
|
|
52
|
+
END IF;
|
|
53
|
+
SELECT * INTO current_review FROM knowledge_claim_reviews review
|
|
54
|
+
WHERE review.account_id = p_account_id AND review.claim_id = p_claim_id
|
|
55
|
+
ORDER BY review.review_revision DESC LIMIT 1 FOR SHARE;
|
|
56
|
+
IF current_review.id IS DISTINCT FROM p_expected_review_id
|
|
57
|
+
OR current_review.review_revision IS DISTINCT FROM p_expected_review_revision
|
|
58
|
+
OR (p_state = 'approved' AND current_review.state <> 'proposed')
|
|
59
|
+
OR (p_state = 'revoked' AND current_review.state <> 'approved')
|
|
60
|
+
THEN
|
|
61
|
+
RAISE EXCEPTION 'governed-learning Knowledge review was superseded'
|
|
62
|
+
USING ERRCODE = '40001';
|
|
63
|
+
END IF;
|
|
64
|
+
input_hash_value := encode(sha256(convert_to(jsonb_build_array(
|
|
65
|
+
'governed-learning-native-review', 1, p_account_id, p_workspace_id,
|
|
66
|
+
p_operation_id, p_claim_id, p_expected_review_id,
|
|
67
|
+
p_expected_review_revision, p_state, p_actor_subject_id,
|
|
68
|
+
p_initiating_human_subject_id
|
|
69
|
+
)::text, 'UTF8')), 'hex');
|
|
70
|
+
PERFORM set_config('opengeni.governed_learning_review_operation', p_operation_id::text, true);
|
|
71
|
+
PERFORM set_config('opengeni.governed_learning_review_claim', p_claim_id::text, true);
|
|
72
|
+
INSERT INTO knowledge_claim_reviews (
|
|
73
|
+
account_id, scope_kind, scope_workspace_id, scope_subject_id, scope_key,
|
|
74
|
+
claim_id, state, reason, operation_id, input_hash, actor_kind,
|
|
75
|
+
actor_subject_id, initiating_human_subject_id
|
|
76
|
+
) VALUES (
|
|
77
|
+
p_account_id, claim_row.scope_kind, claim_row.scope_workspace_id,
|
|
78
|
+
claim_row.scope_subject_id, claim_row.scope_key, p_claim_id, p_state,
|
|
79
|
+
btrim(p_reason),
|
|
80
|
+
p_operation_id::text, input_hash_value, 'service', p_actor_subject_id,
|
|
81
|
+
p_initiating_human_subject_id
|
|
82
|
+
) RETURNING * INTO result_row;
|
|
83
|
+
PERFORM set_config('opengeni.governed_learning_review_operation', '', true);
|
|
84
|
+
PERFORM set_config('opengeni.governed_learning_review_claim', '', true);
|
|
85
|
+
RETURN NEXT result_row;
|
|
86
|
+
END;
|
|
87
|
+
$$;
|
|
88
|
+
REVOKE ALL ON FUNCTION governed_learning_apply_knowledge_review(
|
|
89
|
+
uuid, uuid, uuid, uuid, uuid, bigint, text, text, text, text
|
|
90
|
+
) FROM PUBLIC;
|
|
91
|
+
|
|
92
|
+
-- The 9-arg signature keeps its exact legacy wording; the guard trigger keeps
|
|
93
|
+
-- resolving this signature's owner as the governed-learning capability writer.
|
|
94
|
+
CREATE OR REPLACE FUNCTION governed_learning_apply_knowledge_review(
|
|
95
|
+
p_account_id uuid,
|
|
96
|
+
p_workspace_id uuid,
|
|
97
|
+
p_operation_id uuid,
|
|
98
|
+
p_claim_id uuid,
|
|
99
|
+
p_expected_review_id uuid,
|
|
100
|
+
p_expected_review_revision bigint,
|
|
101
|
+
p_state text,
|
|
102
|
+
p_actor_subject_id text,
|
|
103
|
+
p_initiating_human_subject_id text
|
|
104
|
+
) RETURNS SETOF knowledge_claim_reviews
|
|
105
|
+
LANGUAGE plpgsql SECURITY DEFINER AS $$
|
|
106
|
+
BEGIN
|
|
107
|
+
RETURN QUERY SELECT * FROM governed_learning_apply_knowledge_review(
|
|
108
|
+
p_account_id, p_workspace_id, p_operation_id, p_claim_id,
|
|
109
|
+
p_expected_review_id, p_expected_review_revision, p_state,
|
|
110
|
+
p_actor_subject_id, p_initiating_human_subject_id,
|
|
111
|
+
CASE p_state WHEN 'approved' THEN 'Automatic governed-learning activation.'
|
|
112
|
+
ELSE 'Exact governed-learning activation undo.' END
|
|
113
|
+
);
|
|
114
|
+
END;
|
|
115
|
+
$$;
|
|
116
|
+
REVOKE ALL ON FUNCTION governed_learning_apply_knowledge_review(
|
|
117
|
+
uuid, uuid, uuid, uuid, uuid, bigint, text, text, text
|
|
118
|
+
) FROM PUBLIC;
|
|
119
|
+
|
|
120
|
+
-- `activate_human_confirmed_learning_decision` is byte-identical to migration
|
|
121
|
+
-- 0272 except its knowledge-review approval, which now records the truthful
|
|
122
|
+
-- human-confirmed reason through the reason-carrying overload.
|
|
123
|
+
CREATE OR REPLACE FUNCTION activate_human_confirmed_learning_decision(
|
|
124
|
+
p_account_id uuid,
|
|
125
|
+
p_workspace_id uuid,
|
|
126
|
+
p_operation_id uuid,
|
|
127
|
+
p_decision_receipt_id uuid,
|
|
128
|
+
p_human_input_request_id uuid
|
|
129
|
+
) RETURNS SETOF governed_learning_activation_receipts
|
|
130
|
+
LANGUAGE plpgsql SECURITY DEFINER AS $$
|
|
131
|
+
DECLARE
|
|
132
|
+
caller_subject_id text := nullif(current_setting('opengeni.subject_id', true), '');
|
|
133
|
+
decision_row governed_learning_decision_receipts%ROWTYPE;
|
|
134
|
+
result_row governed_learning_activation_receipts%ROWTYPE;
|
|
135
|
+
proposal_row knowledge_change_proposals%ROWTYPE;
|
|
136
|
+
claim_row knowledge_claims%ROWTYPE;
|
|
137
|
+
evidence_row knowledge_claim_evidence%ROWTYPE;
|
|
138
|
+
review_row knowledge_claim_reviews%ROWTYPE;
|
|
139
|
+
approval_row knowledge_claim_reviews%ROWTYPE;
|
|
140
|
+
policy_head workspace_learning_policy_heads%ROWTYPE;
|
|
141
|
+
policy_revision workspace_learning_policy_revisions%ROWTYPE;
|
|
142
|
+
policy_snapshot workspace_learning_policy_snapshots%ROWTYPE;
|
|
143
|
+
task_note_row task_notes%ROWTYPE;
|
|
144
|
+
document_authority record;
|
|
145
|
+
instruction_proposal workspace_instruction_policy_onboarding_proposals%ROWTYPE;
|
|
146
|
+
instruction_event workspace_instruction_policy_activation_events%ROWTYPE;
|
|
147
|
+
preference_receipt company_brain_preference_proposal_receipts%ROWTYPE;
|
|
148
|
+
preference_row preference_registry_preferences%ROWTYPE;
|
|
149
|
+
preference_revision preference_registry_revisions%ROWTYPE;
|
|
150
|
+
preference_event preference_registry_events%ROWTYPE;
|
|
151
|
+
current_instruction_head workspace_instruction_policy_heads%ROWTYPE;
|
|
152
|
+
current_instruction_activation_version bigint;
|
|
153
|
+
input_hash_value text;
|
|
154
|
+
service_actor text;
|
|
155
|
+
current_authority_hash text;
|
|
156
|
+
current_mode text;
|
|
157
|
+
conflict_count integer;
|
|
158
|
+
destination_value text;
|
|
159
|
+
destination_proposal_id_value uuid;
|
|
160
|
+
destination_revision_id_value uuid;
|
|
161
|
+
destination_old_revision_id_value uuid;
|
|
162
|
+
destination_old_content_hash_value text;
|
|
163
|
+
destination_old_version_value bigint;
|
|
164
|
+
destination_new_content_hash_value text;
|
|
165
|
+
destination_new_version_value bigint;
|
|
166
|
+
destination_event_id_value uuid;
|
|
167
|
+
effective_at_value timestamptz;
|
|
168
|
+
review_operation_id uuid;
|
|
169
|
+
destination_operation_id uuid;
|
|
170
|
+
human_input_row session_human_input_requests%ROWTYPE;
|
|
171
|
+
human_question_id text;
|
|
172
|
+
human_question_lane text;
|
|
173
|
+
human_question_prompt text;
|
|
174
|
+
human_question_help text;
|
|
175
|
+
human_question_options jsonb := jsonb_build_array(
|
|
176
|
+
jsonb_build_object('id', 'save', 'label', 'Save'),
|
|
177
|
+
jsonb_build_object('id', 'skip', 'label', 'Don''t save')
|
|
178
|
+
);
|
|
179
|
+
BEGIN
|
|
180
|
+
IF p_account_id IS NULL OR p_workspace_id IS NULL OR p_operation_id IS NULL
|
|
181
|
+
OR p_decision_receipt_id IS NULL OR p_human_input_request_id IS NULL
|
|
182
|
+
OR caller_subject_id IS NULL
|
|
183
|
+
OR length(btrim(caller_subject_id)) NOT BETWEEN 1 AND 1024
|
|
184
|
+
OR p_account_id IS DISTINCT FROM opengeni_private.current_account_id()
|
|
185
|
+
OR p_workspace_id IS DISTINCT FROM opengeni_private.current_workspace_id()
|
|
186
|
+
THEN
|
|
187
|
+
RAISE EXCEPTION 'governed-learning activation requires exact tenant authority'
|
|
188
|
+
USING ERRCODE = '42501';
|
|
189
|
+
END IF;
|
|
190
|
+
input_hash_value := encode(sha256(convert_to(jsonb_build_array(
|
|
191
|
+
'governed-learning-human-confirmed-activation', 1, p_account_id, p_workspace_id,
|
|
192
|
+
p_operation_id, p_decision_receipt_id, p_human_input_request_id
|
|
193
|
+
)::text, 'UTF8')), 'hex');
|
|
194
|
+
SELECT * INTO result_row FROM governed_learning_activation_receipts receipt
|
|
195
|
+
WHERE receipt.workspace_id = p_workspace_id AND receipt.operation_id = p_operation_id
|
|
196
|
+
FOR SHARE;
|
|
197
|
+
IF FOUND THEN
|
|
198
|
+
IF result_row.account_id <> p_account_id OR result_row.input_hash <> input_hash_value
|
|
199
|
+
OR result_row.decision_receipt_id <> p_decision_receipt_id
|
|
200
|
+
OR result_row.initiating_human_subject_id <> caller_subject_id
|
|
201
|
+
OR result_row.authority_kind <> 'human_confirmed'
|
|
202
|
+
OR result_row.human_input_request_id IS DISTINCT FROM p_human_input_request_id
|
|
203
|
+
THEN
|
|
204
|
+
RAISE EXCEPTION 'governed-learning activation operation conflicts with immutable receipt'
|
|
205
|
+
USING ERRCODE = '23505';
|
|
206
|
+
END IF;
|
|
207
|
+
RETURN NEXT result_row;
|
|
208
|
+
RETURN;
|
|
209
|
+
END IF;
|
|
210
|
+
|
|
211
|
+
-- Canonical shared prefix. The workspace UPDATE lock also gives all three
|
|
212
|
+
-- destination adapters one order, avoiding claim/head inversion.
|
|
213
|
+
PERFORM 1 FROM workspaces workspace
|
|
214
|
+
WHERE workspace.account_id = p_account_id AND workspace.id = p_workspace_id
|
|
215
|
+
FOR UPDATE;
|
|
216
|
+
IF NOT FOUND THEN
|
|
217
|
+
RAISE EXCEPTION 'governed-learning workspace is unavailable' USING ERRCODE = '42501';
|
|
218
|
+
END IF;
|
|
219
|
+
SELECT * INTO result_row FROM governed_learning_activation_receipts receipt
|
|
220
|
+
WHERE receipt.workspace_id = p_workspace_id AND receipt.operation_id = p_operation_id
|
|
221
|
+
FOR SHARE;
|
|
222
|
+
IF FOUND THEN
|
|
223
|
+
IF result_row.account_id <> p_account_id OR result_row.input_hash <> input_hash_value
|
|
224
|
+
OR result_row.decision_receipt_id <> p_decision_receipt_id
|
|
225
|
+
OR result_row.initiating_human_subject_id <> caller_subject_id
|
|
226
|
+
OR result_row.authority_kind <> 'human_confirmed'
|
|
227
|
+
OR result_row.human_input_request_id IS DISTINCT FROM p_human_input_request_id
|
|
228
|
+
THEN
|
|
229
|
+
RAISE EXCEPTION 'governed-learning activation operation conflicts with immutable receipt'
|
|
230
|
+
USING ERRCODE = '23505';
|
|
231
|
+
END IF;
|
|
232
|
+
RETURN NEXT result_row;
|
|
233
|
+
RETURN;
|
|
234
|
+
END IF;
|
|
235
|
+
SELECT * INTO decision_row FROM governed_learning_decision_receipts receipt
|
|
236
|
+
WHERE receipt.id = p_decision_receipt_id AND receipt.account_id = p_account_id
|
|
237
|
+
AND receipt.workspace_id = p_workspace_id
|
|
238
|
+
AND receipt.initiating_human_subject_id = caller_subject_id
|
|
239
|
+
AND receipt.outcome IN ('suggest', 'automatic', 'confidence')
|
|
240
|
+
FOR UPDATE;
|
|
241
|
+
IF NOT FOUND OR NOT session_reference_visible(
|
|
242
|
+
decision_row.account_id, decision_row.workspace_id, decision_row.session_id
|
|
243
|
+
) THEN
|
|
244
|
+
RAISE EXCEPTION 'confirmable evaluator receipt is unavailable'
|
|
245
|
+
USING ERRCODE = '42501';
|
|
246
|
+
END IF;
|
|
247
|
+
IF EXISTS (
|
|
248
|
+
SELECT 1 FROM governed_learning_activation_receipts receipt
|
|
249
|
+
WHERE receipt.decision_receipt_id = p_decision_receipt_id
|
|
250
|
+
) THEN
|
|
251
|
+
RAISE EXCEPTION 'automatic evaluator receipt was consumed by another operation'
|
|
252
|
+
USING ERRCODE = '23505';
|
|
253
|
+
END IF;
|
|
254
|
+
PERFORM 1 FROM sessions session
|
|
255
|
+
WHERE session.account_id = p_account_id AND session.workspace_id = p_workspace_id
|
|
256
|
+
AND session.id = decision_row.session_id AND session.active_turn_id = decision_row.turn_id
|
|
257
|
+
AND session_reference_visible(session.account_id, session.workspace_id, session.id)
|
|
258
|
+
FOR SHARE;
|
|
259
|
+
IF NOT FOUND THEN
|
|
260
|
+
RAISE EXCEPTION 'governed-learning activation session is unavailable' USING ERRCODE = '42501';
|
|
261
|
+
END IF;
|
|
262
|
+
-- The decision receipt was minted before the human-input pause, so the
|
|
263
|
+
-- turn's active attempt is normally a later attempt of the same logical
|
|
264
|
+
-- turn and execution generation. Require that live attempt instead of the
|
|
265
|
+
-- exact minting attempt; the human answer is bound to the same generation.
|
|
266
|
+
PERFORM 1 FROM session_turns turn
|
|
267
|
+
WHERE turn.account_id = p_account_id AND turn.workspace_id = p_workspace_id
|
|
268
|
+
AND turn.session_id = decision_row.session_id AND turn.id = decision_row.turn_id
|
|
269
|
+
AND turn.execution_generation = decision_row.execution_generation
|
|
270
|
+
AND turn.status IN ('running', 'requires_action', 'recovering', 'waiting_capacity')
|
|
271
|
+
AND coalesce(turn.initiating_human_subject_id,
|
|
272
|
+
CASE WHEN turn.initiator_kind = 'subject' THEN turn.initiator_subject_id END
|
|
273
|
+
) = caller_subject_id
|
|
274
|
+
FOR SHARE;
|
|
275
|
+
IF NOT FOUND THEN
|
|
276
|
+
RAISE EXCEPTION 'governed-learning activation turn is unavailable' USING ERRCODE = '42501';
|
|
277
|
+
END IF;
|
|
278
|
+
PERFORM 1 FROM session_turns turn
|
|
279
|
+
JOIN session_turn_attempts attempt
|
|
280
|
+
ON attempt.account_id = turn.account_id AND attempt.workspace_id = turn.workspace_id
|
|
281
|
+
AND attempt.session_id = turn.session_id AND attempt.turn_id = turn.id
|
|
282
|
+
AND attempt.id = turn.active_attempt_id
|
|
283
|
+
WHERE turn.account_id = p_account_id AND turn.workspace_id = p_workspace_id
|
|
284
|
+
AND turn.session_id = decision_row.session_id AND turn.id = decision_row.turn_id
|
|
285
|
+
AND attempt.execution_generation = decision_row.execution_generation
|
|
286
|
+
AND attempt.state IN ('claimed', 'running')
|
|
287
|
+
AND NOT EXISTS (
|
|
288
|
+
SELECT 1 FROM session_attempt_interruptions interruption
|
|
289
|
+
WHERE interruption.workspace_id = p_workspace_id
|
|
290
|
+
AND interruption.attempt_id = attempt.id
|
|
291
|
+
AND interruption.state IN ('pending', 'delivered', 'acknowledged')
|
|
292
|
+
)
|
|
293
|
+
FOR SHARE OF attempt;
|
|
294
|
+
IF NOT FOUND THEN
|
|
295
|
+
RAISE EXCEPTION 'governed-learning activation attempt is unavailable' USING ERRCODE = '42501';
|
|
296
|
+
END IF;
|
|
297
|
+
|
|
298
|
+
SELECT * INTO policy_snapshot FROM workspace_learning_policy_snapshots snapshot
|
|
299
|
+
WHERE snapshot.id = decision_row.policy_snapshot_id
|
|
300
|
+
AND snapshot.account_id = p_account_id AND snapshot.workspace_id = p_workspace_id
|
|
301
|
+
AND snapshot.session_id = decision_row.session_id
|
|
302
|
+
AND snapshot.turn_id = decision_row.turn_id
|
|
303
|
+
AND snapshot.attempt_id = decision_row.attempt_id
|
|
304
|
+
AND snapshot.execution_generation = decision_row.execution_generation
|
|
305
|
+
AND snapshot.snapshot_hash = decision_row.policy_snapshot_hash
|
|
306
|
+
FOR SHARE;
|
|
307
|
+
SELECT * INTO policy_head FROM workspace_learning_policy_heads head
|
|
308
|
+
WHERE head.account_id = p_account_id AND head.workspace_id = p_workspace_id
|
|
309
|
+
FOR SHARE;
|
|
310
|
+
SELECT * INTO policy_revision FROM workspace_learning_policy_revisions revision
|
|
311
|
+
WHERE revision.account_id = p_account_id AND revision.workspace_id = p_workspace_id
|
|
312
|
+
AND revision.id = policy_head.revision_id
|
|
313
|
+
FOR SHARE;
|
|
314
|
+
IF policy_snapshot.id IS NULL
|
|
315
|
+
OR policy_head.revision_id IS DISTINCT FROM decision_row.policy_revision_id
|
|
316
|
+
OR policy_head.policy_hash IS DISTINCT FROM policy_snapshot.policy_hash
|
|
317
|
+
OR policy_head.activation_version IS DISTINCT FROM decision_row.policy_activation_version
|
|
318
|
+
OR policy_revision.policy_hash IS DISTINCT FROM policy_snapshot.policy_hash
|
|
319
|
+
THEN
|
|
320
|
+
RAISE EXCEPTION 'governed-learning policy authority changed after evaluation'
|
|
321
|
+
USING ERRCODE = '40001';
|
|
322
|
+
END IF;
|
|
323
|
+
current_mode := coalesce((
|
|
324
|
+
SELECT override.value->>'mode'
|
|
325
|
+
FROM jsonb_array_elements(policy_revision.source_overrides) override(value)
|
|
326
|
+
WHERE override.value->>'kind' = decision_row.source_kind
|
|
327
|
+
AND override.value->>'id' = decision_row.source_id::text LIMIT 1
|
|
328
|
+
), policy_revision.workspace_mode);
|
|
329
|
+
IF current_mode = 'off' THEN
|
|
330
|
+
RAISE EXCEPTION 'governed-learning source is off' USING ERRCODE = '42501';
|
|
331
|
+
END IF;
|
|
332
|
+
|
|
333
|
+
SELECT * INTO proposal_row FROM knowledge_change_proposals proposal
|
|
334
|
+
WHERE proposal.id = decision_row.proposal_id AND proposal.account_id = p_account_id
|
|
335
|
+
AND proposal.scope_kind = 'workspace' AND proposal.scope_workspace_id = p_workspace_id
|
|
336
|
+
AND proposal.scope_subject_id IS NULL AND proposal.status = 'proposed'
|
|
337
|
+
AND proposal.input_hash = decision_row.proposal_input_hash
|
|
338
|
+
AND proposal.content_hash = decision_row.proposal_content_hash
|
|
339
|
+
AND proposal.claim_id = decision_row.claim_id
|
|
340
|
+
AND proposal.evidence_id = decision_row.evidence_id
|
|
341
|
+
AND proposal.initiating_human_subject_id = caller_subject_id
|
|
342
|
+
FOR SHARE;
|
|
343
|
+
SELECT * INTO claim_row FROM knowledge_claims claim
|
|
344
|
+
WHERE claim.id = decision_row.claim_id AND claim.account_id = p_account_id
|
|
345
|
+
AND claim.scope_kind = 'workspace' AND claim.scope_workspace_id = p_workspace_id
|
|
346
|
+
AND claim.scope_subject_id IS NULL AND claim.input_hash = decision_row.claim_input_hash
|
|
347
|
+
AND claim.initiating_human_subject_id = caller_subject_id
|
|
348
|
+
AND claim.confidence_bps >= decision_row.confidence_floor_bps
|
|
349
|
+
AND claim.effective_at <= transaction_timestamp()
|
|
350
|
+
AND (claim.expires_at IS NULL OR claim.expires_at > transaction_timestamp())
|
|
351
|
+
FOR UPDATE;
|
|
352
|
+
SELECT * INTO evidence_row FROM knowledge_claim_evidence evidence
|
|
353
|
+
WHERE evidence.id = decision_row.evidence_id AND evidence.account_id = p_account_id
|
|
354
|
+
AND evidence.scope_kind = 'workspace' AND evidence.scope_workspace_id = p_workspace_id
|
|
355
|
+
AND evidence.scope_subject_id IS NULL AND evidence.claim_id = decision_row.claim_id
|
|
356
|
+
AND evidence.polarity = 'supports' AND evidence.input_hash = decision_row.evidence_input_hash
|
|
357
|
+
AND evidence.content_hash = decision_row.evidence_content_hash
|
|
358
|
+
AND evidence.initiating_human_subject_id = caller_subject_id
|
|
359
|
+
FOR SHARE;
|
|
360
|
+
IF proposal_row.id IS NULL OR claim_row.id IS NULL OR evidence_row.id IS NULL THEN
|
|
361
|
+
RAISE EXCEPTION 'governed-learning proposal lineage changed after evaluation'
|
|
362
|
+
USING ERRCODE = '42501';
|
|
363
|
+
END IF;
|
|
364
|
+
SELECT * INTO review_row FROM knowledge_claim_reviews review
|
|
365
|
+
WHERE review.account_id = p_account_id AND review.claim_id = decision_row.claim_id
|
|
366
|
+
ORDER BY review.review_revision DESC LIMIT 1 FOR SHARE;
|
|
367
|
+
IF review_row.id IS NULL OR review_row.state <> 'proposed'
|
|
368
|
+
OR review_row.review_revision <> decision_row.review_revision
|
|
369
|
+
THEN
|
|
370
|
+
RAISE EXCEPTION 'governed-learning review was superseded after evaluation'
|
|
371
|
+
USING ERRCODE = '40001';
|
|
372
|
+
END IF;
|
|
373
|
+
SELECT least(1000, count(*))::integer INTO conflict_count FROM (
|
|
374
|
+
SELECT relation.id FROM knowledge_claim_relations relation
|
|
375
|
+
WHERE relation.account_id = p_account_id AND relation.scope_kind = 'workspace'
|
|
376
|
+
AND relation.scope_workspace_id = p_workspace_id AND relation.scope_subject_id IS NULL
|
|
377
|
+
AND relation.relation_type = 'conflicts_with'
|
|
378
|
+
AND (relation.from_claim_id = decision_row.claim_id
|
|
379
|
+
OR relation.to_claim_id = decision_row.claim_id)
|
|
380
|
+
UNION ALL
|
|
381
|
+
SELECT contradiction.id FROM knowledge_claim_evidence contradiction
|
|
382
|
+
WHERE contradiction.account_id = p_account_id AND contradiction.scope_kind = 'workspace'
|
|
383
|
+
AND contradiction.scope_workspace_id = p_workspace_id
|
|
384
|
+
AND contradiction.scope_subject_id IS NULL
|
|
385
|
+
AND contradiction.claim_id = decision_row.claim_id
|
|
386
|
+
AND contradiction.polarity = 'contradicts'
|
|
387
|
+
) conflicts;
|
|
388
|
+
IF conflict_count <> 0 THEN
|
|
389
|
+
RAISE EXCEPTION 'governed-learning evidence now conflicts' USING ERRCODE = '23514';
|
|
390
|
+
END IF;
|
|
391
|
+
|
|
392
|
+
IF evidence_row.task_note_id IS NOT NULL THEN
|
|
393
|
+
SELECT * INTO task_note_row FROM task_notes note
|
|
394
|
+
WHERE note.id = evidence_row.task_note_id AND note.account_id = p_account_id
|
|
395
|
+
AND note.workspace_id = p_workspace_id
|
|
396
|
+
AND note.root_session_id = evidence_row.task_note_root_session_id
|
|
397
|
+
AND note.version = evidence_row.task_note_version
|
|
398
|
+
AND note.text_hash = evidence_row.content_hash
|
|
399
|
+
AND note.status = 'active' AND note.expires_at > transaction_timestamp()
|
|
400
|
+
AND session_reference_visible(note.account_id, note.workspace_id, note.root_session_id)
|
|
401
|
+
FOR SHARE;
|
|
402
|
+
IF NOT FOUND THEN
|
|
403
|
+
RAISE EXCEPTION 'governed-learning Task-note authority was revoked' USING ERRCODE = '42501';
|
|
404
|
+
END IF;
|
|
405
|
+
current_authority_hash := encode(sha256(convert_to(jsonb_build_array(
|
|
406
|
+
'task-note-authority', 1, evidence_row.task_note_id,
|
|
407
|
+
evidence_row.task_note_root_session_id, evidence_row.task_note_version,
|
|
408
|
+
evidence_row.content_hash, task_note_row.status, task_note_row.expires_at
|
|
409
|
+
)::text, 'UTF8')), 'hex');
|
|
410
|
+
ELSE
|
|
411
|
+
SELECT provider.id AS provider_id, provider.lifecycle_state AS provider_state,
|
|
412
|
+
provider.lifecycle_generation AS provider_generation, source.id AS source_id,
|
|
413
|
+
source.lifecycle_state AS source_state, source.lifecycle_generation AS source_generation,
|
|
414
|
+
source.current_acl_generation, object.id AS object_id,
|
|
415
|
+
object.lifecycle_state AS object_state, object.lifecycle_generation AS object_generation,
|
|
416
|
+
object.version_generation AS object_version_generation, object.current_version_id,
|
|
417
|
+
version.id AS version_id, version.version_generation, version.content_sha256,
|
|
418
|
+
version.acl_version_id, version.acl_generation, version.document_id,
|
|
419
|
+
evidence_acl.acl_hash AS evidence_acl_hash,
|
|
420
|
+
evidence_acl.agent_access AS evidence_agent_access,
|
|
421
|
+
current_acl.id AS current_acl_id, current_acl.acl_hash AS current_acl_hash,
|
|
422
|
+
current_acl.agent_access AS current_agent_access
|
|
423
|
+
INTO document_authority
|
|
424
|
+
FROM knowledge_document_versions version
|
|
425
|
+
JOIN knowledge_source_objects object ON object.account_id = version.account_id
|
|
426
|
+
AND object.id = version.object_id AND object.scope_key = version.scope_key
|
|
427
|
+
JOIN knowledge_sources source ON source.account_id = version.account_id
|
|
428
|
+
AND source.id = version.source_id AND source.scope_key = version.scope_key
|
|
429
|
+
JOIN knowledge_providers provider ON provider.account_id = source.account_id
|
|
430
|
+
AND provider.id = source.provider_id AND provider.scope_key = source.scope_key
|
|
431
|
+
JOIN knowledge_source_acl_versions evidence_acl ON evidence_acl.account_id = version.account_id
|
|
432
|
+
AND evidence_acl.id = version.acl_version_id AND evidence_acl.source_id = version.source_id
|
|
433
|
+
AND evidence_acl.generation = version.acl_generation
|
|
434
|
+
LEFT JOIN knowledge_source_acl_versions current_acl ON current_acl.account_id = source.account_id
|
|
435
|
+
AND current_acl.source_id = source.id AND current_acl.generation = source.current_acl_generation
|
|
436
|
+
WHERE version.id = evidence_row.document_version_id AND version.account_id = p_account_id
|
|
437
|
+
AND version.scope_kind = 'workspace' AND version.scope_workspace_id = p_workspace_id
|
|
438
|
+
AND version.scope_subject_id IS NULL
|
|
439
|
+
FOR SHARE OF version, object, source, provider, evidence_acl;
|
|
440
|
+
IF document_authority.version_id IS NULL
|
|
441
|
+
OR document_authority.provider_state IS DISTINCT FROM 'active'
|
|
442
|
+
OR document_authority.source_state IS DISTINCT FROM 'active'
|
|
443
|
+
OR document_authority.object_state IS DISTINCT FROM 'active'
|
|
444
|
+
OR document_authority.current_version_id IS DISTINCT FROM document_authority.version_id
|
|
445
|
+
OR document_authority.object_version_generation IS DISTINCT FROM document_authority.version_generation
|
|
446
|
+
OR document_authority.current_acl_id IS NULL
|
|
447
|
+
OR NOT coalesce(document_authority.evidence_agent_access, false)
|
|
448
|
+
OR NOT coalesce(document_authority.current_agent_access, false)
|
|
449
|
+
OR (document_authority.document_id IS NOT NULL AND NOT EXISTS (
|
|
450
|
+
SELECT 1 FROM documents document WHERE document.id = document_authority.document_id
|
|
451
|
+
AND document.account_id = p_account_id AND document.workspace_id = p_workspace_id
|
|
452
|
+
AND document.status = 'ready' AND document.agent_access
|
|
453
|
+
AND (document.visibility <> 'private' OR document.created_by = caller_subject_id)
|
|
454
|
+
))
|
|
455
|
+
OR (evidence_row.document_chunk_id IS NOT NULL AND NOT EXISTS (
|
|
456
|
+
SELECT 1 FROM document_chunks chunk WHERE chunk.id = evidence_row.document_chunk_id
|
|
457
|
+
AND chunk.account_id = p_account_id AND chunk.workspace_id = p_workspace_id
|
|
458
|
+
AND chunk.document_id = document_authority.document_id
|
|
459
|
+
))
|
|
460
|
+
THEN
|
|
461
|
+
RAISE EXCEPTION 'governed-learning document authority was revoked' USING ERRCODE = '42501';
|
|
462
|
+
END IF;
|
|
463
|
+
current_authority_hash := encode(sha256(convert_to(jsonb_build_array(
|
|
464
|
+
'document-evidence-authority', 1, evidence_row.document_version_id,
|
|
465
|
+
document_authority.provider_id, document_authority.provider_state,
|
|
466
|
+
document_authority.provider_generation, document_authority.source_id,
|
|
467
|
+
document_authority.source_state, document_authority.source_generation,
|
|
468
|
+
document_authority.current_acl_generation, document_authority.object_id,
|
|
469
|
+
document_authority.object_state, document_authority.object_generation,
|
|
470
|
+
document_authority.object_version_generation, document_authority.current_version_id,
|
|
471
|
+
document_authority.version_id, document_authority.version_generation,
|
|
472
|
+
document_authority.content_sha256, document_authority.acl_version_id,
|
|
473
|
+
document_authority.acl_generation, document_authority.evidence_acl_hash,
|
|
474
|
+
document_authority.current_acl_id, document_authority.current_acl_hash,
|
|
475
|
+
evidence_row.document_chunk_id, false
|
|
476
|
+
)::text, 'UTF8')), 'hex');
|
|
477
|
+
END IF;
|
|
478
|
+
|
|
479
|
+
-- The exact human must have answered the bound question for this proposal
|
|
480
|
+
-- on the same session/turn, in the same execution generation, with `save`.
|
|
481
|
+
-- The question the human saw is reconstructed here from the proposal itself
|
|
482
|
+
-- (canonical prompt, exact proposal content as help text, fixed options), so
|
|
483
|
+
-- an agent cannot obtain confirmation through a misleading prompt.
|
|
484
|
+
human_question_id := 'remember:' || decision_row.proposal_id::text;
|
|
485
|
+
-- Only Task-note evidence (the exact user-directed text) is confirmable; the
|
|
486
|
+
-- proposal content of a preference is a normalized envelope, not the words
|
|
487
|
+
-- the human was shown.
|
|
488
|
+
IF task_note_row.id IS NULL THEN
|
|
489
|
+
RAISE EXCEPTION 'human confirmation requires exact Task-note evidence' USING ERRCODE = '42501';
|
|
490
|
+
END IF;
|
|
491
|
+
human_question_lane := proposal_row.target_kind;
|
|
492
|
+
human_question_help := left(task_note_row.text, 2000);
|
|
493
|
+
human_question_prompt := 'Save this as a ' || CASE human_question_lane
|
|
494
|
+
WHEN 'instruction_policy' THEN 'mandatory workspace rule'
|
|
495
|
+
WHEN 'preference' THEN 'workspace preference'
|
|
496
|
+
ELSE 'workspace knowledge' END
|
|
497
|
+
|| ' for everyone in this workspace?';
|
|
498
|
+
SELECT * INTO human_input_row FROM session_human_input_requests request
|
|
499
|
+
WHERE request.id = p_human_input_request_id
|
|
500
|
+
AND request.account_id = p_account_id AND request.workspace_id = p_workspace_id
|
|
501
|
+
AND request.session_id = decision_row.session_id
|
|
502
|
+
AND request.turn_id = decision_row.turn_id
|
|
503
|
+
AND request.turn_generation = decision_row.execution_generation
|
|
504
|
+
AND request.status = 'answered'
|
|
505
|
+
AND request.responded_by = caller_subject_id
|
|
506
|
+
AND request.response->>'outcome' = 'answered'
|
|
507
|
+
AND EXISTS (
|
|
508
|
+
SELECT 1 FROM jsonb_array_elements(request.questions) question(value)
|
|
509
|
+
WHERE question.value->>'id' = human_question_id
|
|
510
|
+
AND question.value->>'kind' = 'single_select'
|
|
511
|
+
AND question.value->>'prompt' = human_question_prompt
|
|
512
|
+
AND question.value->>'helpText' = human_question_help
|
|
513
|
+
AND question.value->'options' = human_question_options
|
|
514
|
+
AND coalesce((question.value->>'allowOther')::boolean, false) = false
|
|
515
|
+
)
|
|
516
|
+
AND EXISTS (
|
|
517
|
+
SELECT 1 FROM jsonb_array_elements(request.response->'answers') answer(value)
|
|
518
|
+
WHERE answer.value->>'questionId' = human_question_id
|
|
519
|
+
AND answer.value->'values' = to_jsonb(ARRAY['save'])
|
|
520
|
+
)
|
|
521
|
+
FOR SHARE;
|
|
522
|
+
IF NOT FOUND THEN
|
|
523
|
+
RAISE EXCEPTION 'human confirmation for this proposal is unavailable'
|
|
524
|
+
USING ERRCODE = '42501';
|
|
525
|
+
END IF;
|
|
526
|
+
IF current_authority_hash IS DISTINCT FROM decision_row.evidence_authority_hash THEN
|
|
527
|
+
RAISE EXCEPTION 'governed-learning evidence authority changed after evaluation'
|
|
528
|
+
USING ERRCODE = '40001';
|
|
529
|
+
END IF;
|
|
530
|
+
|
|
531
|
+
IF proposal_row.target_kind = 'instruction_policy' THEN
|
|
532
|
+
SELECT * INTO instruction_proposal
|
|
533
|
+
FROM workspace_instruction_policy_onboarding_proposals proposal
|
|
534
|
+
WHERE proposal.account_id = p_account_id AND proposal.workspace_id = p_workspace_id
|
|
535
|
+
AND proposal.source_id = proposal_row.id::text
|
|
536
|
+
AND proposal.source_version = proposal_row.content_hash
|
|
537
|
+
AND proposal.status = 'proposed'
|
|
538
|
+
FOR SHARE;
|
|
539
|
+
IF NOT FOUND OR instruction_proposal.draft_content_hash <> proposal_row.content_hash THEN
|
|
540
|
+
RAISE EXCEPTION 'exact inactive instruction-policy proposal is unavailable'
|
|
541
|
+
USING ERRCODE = '42501';
|
|
542
|
+
END IF;
|
|
543
|
+
SELECT * INTO current_instruction_head FROM workspace_instruction_policy_heads head
|
|
544
|
+
WHERE head.account_id = p_account_id AND head.workspace_id = p_workspace_id
|
|
545
|
+
AND head.kind = instruction_proposal.kind AND head.scope = instruction_proposal.scope
|
|
546
|
+
AND head.role_key IS NOT DISTINCT FROM instruction_proposal.role_key FOR SHARE;
|
|
547
|
+
IF NOT FOUND THEN
|
|
548
|
+
SELECT event.activation_version INTO current_instruction_activation_version
|
|
549
|
+
FROM workspace_instruction_policy_deactivation_events event
|
|
550
|
+
WHERE event.account_id = p_account_id AND event.workspace_id = p_workspace_id
|
|
551
|
+
AND event.kind = instruction_proposal.kind AND event.scope = instruction_proposal.scope
|
|
552
|
+
AND event.role_key IS NOT DISTINCT FROM instruction_proposal.role_key
|
|
553
|
+
ORDER BY event.activation_version DESC, event.id DESC
|
|
554
|
+
LIMIT 1;
|
|
555
|
+
END IF;
|
|
556
|
+
current_instruction_activation_version := coalesce(
|
|
557
|
+
current_instruction_head.activation_version,
|
|
558
|
+
current_instruction_activation_version,
|
|
559
|
+
0
|
|
560
|
+
);
|
|
561
|
+
IF current_instruction_head.revision_id IS DISTINCT FROM instruction_proposal.baseline_revision_id
|
|
562
|
+
OR current_instruction_activation_version
|
|
563
|
+
IS DISTINCT FROM instruction_proposal.baseline_activation_version
|
|
564
|
+
THEN
|
|
565
|
+
RAISE EXCEPTION 'instruction-policy proposal baseline is stale' USING ERRCODE = '40001';
|
|
566
|
+
END IF;
|
|
567
|
+
destination_value := 'instruction_policy';
|
|
568
|
+
destination_proposal_id_value := instruction_proposal.id;
|
|
569
|
+
destination_revision_id_value := instruction_proposal.draft_revision_id;
|
|
570
|
+
destination_old_revision_id_value := instruction_proposal.baseline_revision_id;
|
|
571
|
+
destination_old_content_hash_value := instruction_proposal.baseline_content_hash;
|
|
572
|
+
destination_old_version_value := instruction_proposal.baseline_activation_version;
|
|
573
|
+
destination_new_content_hash_value := instruction_proposal.draft_content_hash;
|
|
574
|
+
ELSIF proposal_row.target_kind = 'preference' THEN
|
|
575
|
+
SELECT * INTO preference_receipt FROM company_brain_preference_proposal_receipts receipt
|
|
576
|
+
WHERE receipt.account_id = p_account_id AND receipt.workspace_id = p_workspace_id
|
|
577
|
+
AND receipt.knowledge_proposal_id = proposal_row.id FOR SHARE;
|
|
578
|
+
SELECT * INTO preference_row FROM preference_registry_preferences preference
|
|
579
|
+
WHERE preference.account_id = p_account_id AND preference.id = preference_receipt.preference_id
|
|
580
|
+
AND preference.scope = 'workspace' AND preference.scope_workspace_id = p_workspace_id
|
|
581
|
+
AND preference.scope_subject_id IS NULL AND preference.status = 'proposed'
|
|
582
|
+
AND preference.active_revision_id IS NULL AND preference.activation_version = 0
|
|
583
|
+
AND preference.scope_version = 1 FOR SHARE;
|
|
584
|
+
SELECT * INTO preference_revision FROM preference_registry_revisions revision
|
|
585
|
+
WHERE revision.account_id = p_account_id AND revision.id = preference_receipt.revision_id
|
|
586
|
+
AND revision.preference_id = preference_receipt.preference_id
|
|
587
|
+
AND revision.provenance_source = 'knowledge_proposal'
|
|
588
|
+
AND revision.provenance_source_id = proposal_row.id::text
|
|
589
|
+
AND revision.trust = 'untrusted_proposal'
|
|
590
|
+
AND (revision.expires_at IS NULL OR revision.expires_at > transaction_timestamp())
|
|
591
|
+
FOR SHARE;
|
|
592
|
+
IF preference_receipt.id IS NULL OR preference_row.id IS NULL OR preference_revision.id IS NULL
|
|
593
|
+
OR proposal_row.target_scope <> 'workspace'
|
|
594
|
+
OR proposal_row.target_key <> preference_row.stable_key
|
|
595
|
+
THEN
|
|
596
|
+
RAISE EXCEPTION 'exact inactive preference proposal is unavailable'
|
|
597
|
+
USING ERRCODE = '42501';
|
|
598
|
+
END IF;
|
|
599
|
+
destination_value := 'preference';
|
|
600
|
+
destination_proposal_id_value := preference_row.id;
|
|
601
|
+
destination_revision_id_value := preference_revision.id;
|
|
602
|
+
destination_old_revision_id_value := NULL;
|
|
603
|
+
destination_old_content_hash_value := NULL;
|
|
604
|
+
destination_old_version_value := 0;
|
|
605
|
+
destination_new_content_hash_value := preference_revision.content_hash;
|
|
606
|
+
ELSE
|
|
607
|
+
RAISE EXCEPTION 'unsupported governed-learning destination' USING ERRCODE = '23514';
|
|
608
|
+
END IF;
|
|
609
|
+
|
|
610
|
+
service_actor := 'service:governed-learning-activation:' || input_hash_value;
|
|
611
|
+
review_operation_id := opengeni_private.governed_learning_derived_uuid(
|
|
612
|
+
p_operation_id, 'knowledge-approve'
|
|
613
|
+
);
|
|
614
|
+
destination_operation_id := opengeni_private.governed_learning_derived_uuid(
|
|
615
|
+
p_operation_id, 'destination-activate'
|
|
616
|
+
);
|
|
617
|
+
SELECT * INTO approval_row FROM governed_learning_apply_knowledge_review(
|
|
618
|
+
p_account_id, p_workspace_id, review_operation_id, decision_row.claim_id,
|
|
619
|
+
review_row.id, review_row.review_revision, 'approved', service_actor, caller_subject_id,
|
|
620
|
+
'Approved by the exact initiating human through human-confirmed learning activation.'
|
|
621
|
+
);
|
|
622
|
+
IF destination_value = 'instruction_policy' THEN
|
|
623
|
+
SELECT * INTO instruction_event FROM governed_learning_apply_instruction_policy(
|
|
624
|
+
'activate', p_account_id, p_workspace_id, destination_operation_id,
|
|
625
|
+
destination_proposal_id_value, destination_old_revision_id_value,
|
|
626
|
+
destination_old_version_value, destination_revision_id_value, service_actor
|
|
627
|
+
);
|
|
628
|
+
destination_new_version_value := instruction_event.activation_version;
|
|
629
|
+
destination_event_id_value := instruction_event.id;
|
|
630
|
+
effective_at_value := instruction_event.created_at;
|
|
631
|
+
ELSE
|
|
632
|
+
SELECT * INTO preference_event FROM governed_learning_apply_preference(
|
|
633
|
+
'activate', p_account_id, p_workspace_id, destination_operation_id,
|
|
634
|
+
proposal_row.id, destination_proposal_id_value, destination_revision_id_value,
|
|
635
|
+
NULL, 0, service_actor
|
|
636
|
+
);
|
|
637
|
+
SELECT activation_version INTO destination_new_version_value
|
|
638
|
+
FROM preference_registry_preferences WHERE id = destination_proposal_id_value;
|
|
639
|
+
destination_event_id_value := preference_event.id;
|
|
640
|
+
effective_at_value := preference_event.created_at;
|
|
641
|
+
END IF;
|
|
642
|
+
|
|
643
|
+
INSERT INTO governed_learning_activation_receipts (
|
|
644
|
+
account_id, workspace_id, operation_id, input_hash, decision_receipt_id,
|
|
645
|
+
initiating_human_subject_id, service_actor_subject_id, policy_revision_id,
|
|
646
|
+
policy_hash, policy_activation_version, source_kind, source_id,
|
|
647
|
+
source_authority_hash, proposal_id, claim_id, evidence_id,
|
|
648
|
+
knowledge_previous_review_id, knowledge_previous_review_revision,
|
|
649
|
+
knowledge_approval_review_id, knowledge_approval_review_revision,
|
|
650
|
+
knowledge_approval_input_hash, destination, destination_proposal_id,
|
|
651
|
+
destination_revision_id, destination_old_revision_id,
|
|
652
|
+
destination_old_content_hash, destination_old_version,
|
|
653
|
+
destination_new_content_hash, destination_new_version, destination_event_id,
|
|
654
|
+
effective_at, authority_kind, human_input_request_id
|
|
655
|
+
) VALUES (
|
|
656
|
+
p_account_id, p_workspace_id, p_operation_id, input_hash_value,
|
|
657
|
+
p_decision_receipt_id, caller_subject_id, service_actor, policy_revision.id,
|
|
658
|
+
policy_revision.policy_hash, policy_head.activation_version,
|
|
659
|
+
decision_row.source_kind, decision_row.source_id, current_authority_hash,
|
|
660
|
+
decision_row.proposal_id, decision_row.claim_id, decision_row.evidence_id,
|
|
661
|
+
review_row.id, review_row.review_revision, approval_row.id,
|
|
662
|
+
approval_row.review_revision, approval_row.input_hash, destination_value,
|
|
663
|
+
destination_proposal_id_value, destination_revision_id_value,
|
|
664
|
+
destination_old_revision_id_value, destination_old_content_hash_value,
|
|
665
|
+
destination_old_version_value, destination_new_content_hash_value,
|
|
666
|
+
destination_new_version_value, destination_event_id_value, effective_at_value,
|
|
667
|
+
'human_confirmed', p_human_input_request_id
|
|
668
|
+
) RETURNING * INTO result_row;
|
|
669
|
+
RETURN NEXT result_row;
|
|
670
|
+
END;
|
|
671
|
+
$$;
|
|
672
|
+
REVOKE ALL ON FUNCTION activate_human_confirmed_learning_decision(uuid, uuid, uuid, uuid, uuid) FROM PUBLIC;
|
|
673
|
+
|
|
674
|
+
-- `confirm_remember_knowledge_claim` is byte-identical to migration 0274
|
|
675
|
+
-- except the approval call, which now records the truthful human-confirmed
|
|
676
|
+
-- reason through the reason-carrying overload.
|
|
677
|
+
CREATE OR REPLACE FUNCTION confirm_remember_knowledge_claim(
|
|
678
|
+
p_account_id uuid,
|
|
679
|
+
p_workspace_id uuid,
|
|
680
|
+
p_session_id uuid,
|
|
681
|
+
p_turn_id uuid,
|
|
682
|
+
p_execution_generation integer,
|
|
683
|
+
p_operation_id uuid,
|
|
684
|
+
p_claim_id uuid,
|
|
685
|
+
p_human_input_request_id uuid
|
|
686
|
+
) RETURNS SETOF remember_knowledge_confirmation_receipts
|
|
687
|
+
LANGUAGE plpgsql SECURITY DEFINER AS $$
|
|
688
|
+
DECLARE
|
|
689
|
+
caller_subject_id text := nullif(current_setting('opengeni.subject_id', true), '');
|
|
690
|
+
result_row remember_knowledge_confirmation_receipts%ROWTYPE;
|
|
691
|
+
claim_row knowledge_claims%ROWTYPE;
|
|
692
|
+
evidence_row knowledge_claim_evidence%ROWTYPE;
|
|
693
|
+
task_note_row task_notes%ROWTYPE;
|
|
694
|
+
review_row knowledge_claim_reviews%ROWTYPE;
|
|
695
|
+
approval_row knowledge_claim_reviews%ROWTYPE;
|
|
696
|
+
human_input_row session_human_input_requests%ROWTYPE;
|
|
697
|
+
input_hash_value text;
|
|
698
|
+
service_actor text;
|
|
699
|
+
human_question_id text;
|
|
700
|
+
human_question_prompt text := 'Save this as workspace knowledge for everyone in this workspace?';
|
|
701
|
+
human_question_help text;
|
|
702
|
+
human_question_options jsonb := jsonb_build_array(
|
|
703
|
+
jsonb_build_object('id', 'save', 'label', 'Save'),
|
|
704
|
+
jsonb_build_object('id', 'skip', 'label', 'Don''t save')
|
|
705
|
+
);
|
|
706
|
+
conflict_count integer;
|
|
707
|
+
BEGIN
|
|
708
|
+
IF p_account_id IS NULL OR p_workspace_id IS NULL OR p_session_id IS NULL OR p_turn_id IS NULL
|
|
709
|
+
OR p_execution_generation IS NULL OR p_execution_generation <= 0
|
|
710
|
+
OR p_operation_id IS NULL OR p_claim_id IS NULL OR p_human_input_request_id IS NULL
|
|
711
|
+
OR caller_subject_id IS NULL OR length(btrim(caller_subject_id)) NOT BETWEEN 1 AND 1024
|
|
712
|
+
OR p_account_id IS DISTINCT FROM opengeni_private.current_account_id()
|
|
713
|
+
OR p_workspace_id IS DISTINCT FROM opengeni_private.current_workspace_id()
|
|
714
|
+
THEN
|
|
715
|
+
RAISE EXCEPTION 'remember Knowledge confirmation requires exact tenant authority'
|
|
716
|
+
USING ERRCODE = '42501';
|
|
717
|
+
END IF;
|
|
718
|
+
input_hash_value := encode(sha256(convert_to(jsonb_build_array(
|
|
719
|
+
'remember-knowledge-confirmation', 1, p_account_id, p_workspace_id, p_session_id,
|
|
720
|
+
p_turn_id, p_execution_generation, p_operation_id, p_claim_id, p_human_input_request_id
|
|
721
|
+
)::text, 'UTF8')), 'hex');
|
|
722
|
+
service_actor := 'service:governed-learning-activation:' || input_hash_value;
|
|
723
|
+
|
|
724
|
+
PERFORM 1 FROM workspaces workspace
|
|
725
|
+
WHERE workspace.account_id = p_account_id AND workspace.id = p_workspace_id FOR UPDATE;
|
|
726
|
+
IF NOT FOUND THEN
|
|
727
|
+
RAISE EXCEPTION 'remember Knowledge workspace is unavailable' USING ERRCODE = '42501';
|
|
728
|
+
END IF;
|
|
729
|
+
SELECT * INTO result_row FROM remember_knowledge_confirmation_receipts receipt
|
|
730
|
+
WHERE receipt.workspace_id = p_workspace_id AND receipt.operation_id = p_operation_id FOR SHARE;
|
|
731
|
+
IF FOUND THEN
|
|
732
|
+
IF result_row.account_id <> p_account_id OR result_row.input_hash <> input_hash_value
|
|
733
|
+
OR result_row.initiating_human_subject_id <> caller_subject_id
|
|
734
|
+
THEN
|
|
735
|
+
RAISE EXCEPTION 'remember Knowledge confirmation conflicts with immutable receipt'
|
|
736
|
+
USING ERRCODE = '23505';
|
|
737
|
+
END IF;
|
|
738
|
+
RETURN NEXT result_row;
|
|
739
|
+
RETURN;
|
|
740
|
+
END IF;
|
|
741
|
+
IF EXISTS (SELECT 1 FROM remember_knowledge_confirmation_receipts receipt WHERE receipt.claim_id = p_claim_id) THEN
|
|
742
|
+
RAISE EXCEPTION 'remember Knowledge claim was already confirmed by another operation'
|
|
743
|
+
USING ERRCODE = '23505';
|
|
744
|
+
END IF;
|
|
745
|
+
|
|
746
|
+
-- The live turn must belong to the caller (the initiating human) and hold a
|
|
747
|
+
-- running attempt of the given execution generation without a pending
|
|
748
|
+
-- interruption; the human-input pause resumes on a later attempt.
|
|
749
|
+
PERFORM 1 FROM sessions session
|
|
750
|
+
WHERE session.account_id = p_account_id AND session.workspace_id = p_workspace_id
|
|
751
|
+
AND session.id = p_session_id AND session.active_turn_id = p_turn_id
|
|
752
|
+
AND session_reference_visible(session.account_id, session.workspace_id, session.id)
|
|
753
|
+
FOR SHARE;
|
|
754
|
+
IF NOT FOUND THEN
|
|
755
|
+
RAISE EXCEPTION 'remember Knowledge session is unavailable' USING ERRCODE = '42501';
|
|
756
|
+
END IF;
|
|
757
|
+
PERFORM 1 FROM session_turns turn
|
|
758
|
+
JOIN session_turn_attempts attempt
|
|
759
|
+
ON attempt.account_id = turn.account_id AND attempt.workspace_id = turn.workspace_id
|
|
760
|
+
AND attempt.session_id = turn.session_id AND attempt.turn_id = turn.id
|
|
761
|
+
AND attempt.id = turn.active_attempt_id
|
|
762
|
+
WHERE turn.account_id = p_account_id AND turn.workspace_id = p_workspace_id
|
|
763
|
+
AND turn.session_id = p_session_id AND turn.id = p_turn_id
|
|
764
|
+
AND turn.execution_generation = p_execution_generation
|
|
765
|
+
AND turn.status IN ('running', 'requires_action', 'recovering', 'waiting_capacity')
|
|
766
|
+
AND coalesce(turn.initiating_human_subject_id,
|
|
767
|
+
CASE WHEN turn.initiator_kind = 'subject' THEN turn.initiator_subject_id END
|
|
768
|
+
) = caller_subject_id
|
|
769
|
+
AND attempt.execution_generation = p_execution_generation
|
|
770
|
+
AND attempt.state IN ('claimed', 'running')
|
|
771
|
+
AND NOT EXISTS (
|
|
772
|
+
SELECT 1 FROM session_attempt_interruptions interruption
|
|
773
|
+
WHERE interruption.workspace_id = p_workspace_id
|
|
774
|
+
AND interruption.attempt_id = attempt.id
|
|
775
|
+
AND interruption.state IN ('pending', 'delivered', 'acknowledged')
|
|
776
|
+
)
|
|
777
|
+
FOR SHARE OF attempt;
|
|
778
|
+
IF NOT FOUND THEN
|
|
779
|
+
RAISE EXCEPTION 'remember Knowledge turn is unavailable' USING ERRCODE = '42501';
|
|
780
|
+
END IF;
|
|
781
|
+
|
|
782
|
+
SELECT * INTO claim_row FROM knowledge_claims claim
|
|
783
|
+
WHERE claim.id = p_claim_id AND claim.account_id = p_account_id
|
|
784
|
+
AND claim.scope_kind = 'workspace' AND claim.scope_workspace_id = p_workspace_id
|
|
785
|
+
AND claim.scope_subject_id IS NULL
|
|
786
|
+
AND claim.initiating_human_subject_id = caller_subject_id
|
|
787
|
+
AND claim.effective_at <= transaction_timestamp()
|
|
788
|
+
AND (claim.expires_at IS NULL OR claim.expires_at > transaction_timestamp())
|
|
789
|
+
FOR UPDATE;
|
|
790
|
+
IF NOT FOUND THEN
|
|
791
|
+
RAISE EXCEPTION 'remember Knowledge claim is unavailable' USING ERRCODE = '42501';
|
|
792
|
+
END IF;
|
|
793
|
+
SELECT * INTO evidence_row FROM knowledge_claim_evidence evidence
|
|
794
|
+
WHERE evidence.account_id = p_account_id AND evidence.scope_kind = 'workspace'
|
|
795
|
+
AND evidence.scope_workspace_id = p_workspace_id AND evidence.scope_subject_id IS NULL
|
|
796
|
+
AND evidence.claim_id = p_claim_id AND evidence.polarity = 'supports'
|
|
797
|
+
AND evidence.task_note_id IS NOT NULL
|
|
798
|
+
AND evidence.initiating_human_subject_id = caller_subject_id
|
|
799
|
+
ORDER BY evidence.created_at ASC LIMIT 1 FOR SHARE;
|
|
800
|
+
IF NOT FOUND THEN
|
|
801
|
+
RAISE EXCEPTION 'remember Knowledge confirmation requires exact Task-note evidence'
|
|
802
|
+
USING ERRCODE = '42501';
|
|
803
|
+
END IF;
|
|
804
|
+
SELECT count(*) INTO conflict_count FROM knowledge_claim_evidence contradiction
|
|
805
|
+
WHERE contradiction.account_id = p_account_id AND contradiction.scope_kind = 'workspace'
|
|
806
|
+
AND contradiction.scope_workspace_id = p_workspace_id AND contradiction.scope_subject_id IS NULL
|
|
807
|
+
AND contradiction.claim_id = p_claim_id AND contradiction.polarity = 'contradicts';
|
|
808
|
+
IF conflict_count <> 0 THEN
|
|
809
|
+
RAISE EXCEPTION 'remember Knowledge evidence now conflicts' USING ERRCODE = '23514';
|
|
810
|
+
END IF;
|
|
811
|
+
SELECT * INTO task_note_row FROM task_notes note
|
|
812
|
+
WHERE note.id = evidence_row.task_note_id AND note.account_id = p_account_id
|
|
813
|
+
AND note.workspace_id = p_workspace_id
|
|
814
|
+
AND note.root_session_id = evidence_row.task_note_root_session_id
|
|
815
|
+
AND note.version = evidence_row.task_note_version
|
|
816
|
+
AND note.text_hash = evidence_row.content_hash
|
|
817
|
+
AND note.status = 'active' AND note.expires_at > transaction_timestamp()
|
|
818
|
+
AND session_reference_visible(note.account_id, note.workspace_id, note.root_session_id)
|
|
819
|
+
FOR SHARE;
|
|
820
|
+
IF NOT FOUND THEN
|
|
821
|
+
RAISE EXCEPTION 'remember Knowledge Task-note authority was revoked' USING ERRCODE = '42501';
|
|
822
|
+
END IF;
|
|
823
|
+
SELECT * INTO review_row FROM knowledge_claim_reviews review
|
|
824
|
+
WHERE review.account_id = p_account_id AND review.claim_id = p_claim_id
|
|
825
|
+
ORDER BY review.review_revision DESC LIMIT 1 FOR SHARE;
|
|
826
|
+
IF NOT FOUND OR review_row.state <> 'proposed' THEN
|
|
827
|
+
RAISE EXCEPTION 'remember Knowledge claim is not awaiting confirmation' USING ERRCODE = '42501';
|
|
828
|
+
END IF;
|
|
829
|
+
|
|
830
|
+
-- The exact human must have answered the canonical bound question with
|
|
831
|
+
-- `save` on this session/turn generation. The question is reconstructed
|
|
832
|
+
-- here from the note text, so an agent cannot obtain confirmation through a
|
|
833
|
+
-- misleading prompt.
|
|
834
|
+
human_question_id := 'remember:' || p_claim_id::text;
|
|
835
|
+
human_question_help := left(task_note_row.text, 2000);
|
|
836
|
+
SELECT * INTO human_input_row FROM session_human_input_requests request
|
|
837
|
+
WHERE request.id = p_human_input_request_id
|
|
838
|
+
AND request.account_id = p_account_id AND request.workspace_id = p_workspace_id
|
|
839
|
+
AND request.session_id = p_session_id AND request.turn_id = p_turn_id
|
|
840
|
+
AND request.turn_generation = p_execution_generation
|
|
841
|
+
AND request.status = 'answered'
|
|
842
|
+
AND request.responded_by = caller_subject_id
|
|
843
|
+
AND request.response->>'outcome' = 'answered'
|
|
844
|
+
AND EXISTS (
|
|
845
|
+
SELECT 1 FROM jsonb_array_elements(request.questions) question(value)
|
|
846
|
+
WHERE question.value->>'id' = human_question_id
|
|
847
|
+
AND question.value->>'kind' = 'single_select'
|
|
848
|
+
AND question.value->>'prompt' = human_question_prompt
|
|
849
|
+
AND question.value->>'helpText' = human_question_help
|
|
850
|
+
AND question.value->'options' = human_question_options
|
|
851
|
+
AND coalesce((question.value->>'allowOther')::boolean, false) = false
|
|
852
|
+
)
|
|
853
|
+
AND EXISTS (
|
|
854
|
+
SELECT 1 FROM jsonb_array_elements(request.response->'answers') answer(value)
|
|
855
|
+
WHERE answer.value->>'questionId' = human_question_id
|
|
856
|
+
AND answer.value->'values' = to_jsonb(ARRAY['save'])
|
|
857
|
+
)
|
|
858
|
+
FOR SHARE;
|
|
859
|
+
IF NOT FOUND THEN
|
|
860
|
+
RAISE EXCEPTION 'human confirmation for this Knowledge claim is unavailable'
|
|
861
|
+
USING ERRCODE = '42501';
|
|
862
|
+
END IF;
|
|
863
|
+
|
|
864
|
+
SELECT * INTO approval_row FROM governed_learning_apply_knowledge_review(
|
|
865
|
+
p_account_id, p_workspace_id,
|
|
866
|
+
opengeni_private.governed_learning_derived_uuid(p_operation_id, 'remember-knowledge-approval'),
|
|
867
|
+
p_claim_id, review_row.id, review_row.review_revision, 'approved',
|
|
868
|
+
service_actor, caller_subject_id,
|
|
869
|
+
'Approved by the exact initiating human through the bound remember confirmation.'
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
INSERT INTO remember_knowledge_confirmation_receipts (
|
|
873
|
+
account_id, workspace_id, operation_id, input_hash, session_id, turn_id,
|
|
874
|
+
execution_generation, initiating_human_subject_id, service_actor_subject_id,
|
|
875
|
+
claim_id, evidence_id, task_note_id, task_note_text_hash, human_input_request_id,
|
|
876
|
+
previous_review_id, previous_review_revision, approval_review_id, approval_review_revision
|
|
877
|
+
) VALUES (
|
|
878
|
+
p_account_id, p_workspace_id, p_operation_id, input_hash_value, p_session_id, p_turn_id,
|
|
879
|
+
p_execution_generation, caller_subject_id, service_actor,
|
|
880
|
+
p_claim_id, evidence_row.id, task_note_row.id, task_note_row.text_hash, p_human_input_request_id,
|
|
881
|
+
review_row.id, review_row.review_revision, approval_row.id, approval_row.review_revision
|
|
882
|
+
) RETURNING * INTO result_row;
|
|
883
|
+
RETURN NEXT result_row;
|
|
884
|
+
END;
|
|
885
|
+
$$;
|
|
886
|
+
REVOKE ALL ON FUNCTION confirm_remember_knowledge_claim(uuid, uuid, uuid, uuid, integer, uuid, uuid, uuid) FROM PUBLIC;
|
|
887
|
+
|
|
888
|
+
DO $governed_learning_truthful_reason_hardening$
|
|
889
|
+
DECLARE
|
|
890
|
+
target_schema text := current_schema();
|
|
891
|
+
capability_owner text;
|
|
892
|
+
BEGIN
|
|
893
|
+
-- The guard trigger resolves the 9-arg signature's owner as the
|
|
894
|
+
-- governed-learning capability writer, but the review INSERT now runs inside
|
|
895
|
+
-- the new 10-arg overload. Align its owner with the preserved 9-arg owner so
|
|
896
|
+
-- a deployment whose 0284 migration role differs from the 0269 role cannot
|
|
897
|
+
-- fail every service Knowledge review with 42501.
|
|
898
|
+
SELECT pg_catalog.pg_get_userbyid(procedure_row.proowner) INTO capability_owner
|
|
899
|
+
FROM pg_catalog.pg_proc procedure_row
|
|
900
|
+
WHERE procedure_row.oid = pg_catalog.to_regprocedure(pg_catalog.format(
|
|
901
|
+
'%I.governed_learning_apply_knowledge_review(uuid,uuid,uuid,uuid,uuid,bigint,text,text,text)',
|
|
902
|
+
target_schema
|
|
903
|
+
));
|
|
904
|
+
IF capability_owner IS NOT NULL THEN
|
|
905
|
+
EXECUTE format(
|
|
906
|
+
'ALTER FUNCTION %I.governed_learning_apply_knowledge_review('
|
|
907
|
+
|| 'uuid,uuid,uuid,uuid,uuid,bigint,text,text,text,text) OWNER TO %I',
|
|
908
|
+
target_schema, capability_owner
|
|
909
|
+
);
|
|
910
|
+
END IF;
|
|
911
|
+
EXECUTE format(
|
|
912
|
+
'ALTER FUNCTION %I.governed_learning_apply_knowledge_review('
|
|
913
|
+
|| 'uuid,uuid,uuid,uuid,uuid,bigint,text,text,text,text) '
|
|
914
|
+
|| 'SET search_path = pg_catalog, %I, pg_temp', target_schema, target_schema
|
|
915
|
+
);
|
|
916
|
+
EXECUTE format(
|
|
917
|
+
'ALTER FUNCTION %I.governed_learning_apply_knowledge_review('
|
|
918
|
+
|| 'uuid,uuid,uuid,uuid,uuid,bigint,text,text,text) '
|
|
919
|
+
|| 'SET search_path = pg_catalog, %I, pg_temp', target_schema, target_schema
|
|
920
|
+
);
|
|
921
|
+
EXECUTE format(
|
|
922
|
+
'ALTER FUNCTION %I.confirm_remember_knowledge_claim(uuid,uuid,uuid,uuid,integer,uuid,uuid,uuid) '
|
|
923
|
+
|| 'SET search_path = pg_catalog, %I, pg_temp', target_schema, target_schema
|
|
924
|
+
);
|
|
925
|
+
EXECUTE format(
|
|
926
|
+
'ALTER FUNCTION %I.activate_human_confirmed_learning_decision(uuid,uuid,uuid,uuid,uuid) '
|
|
927
|
+
|| 'SET search_path = pg_catalog, %I, pg_temp', target_schema, target_schema
|
|
928
|
+
);
|
|
929
|
+
END
|
|
930
|
+
$governed_learning_truthful_reason_hardening$;
|