357 lines
14 KiB
PL/PgSQL
357 lines
14 KiB
PL/PgSQL
-- Schema-only rollback for ops/teleo_v3_epistemic_contract.sql.
|
|
--
|
|
-- The rollback refuses to discard proposal-linked V3 data. A disposable
|
|
-- verifier may delete its own canary rows first; a real migration needs an
|
|
-- explicit export/port decision before this file can run.
|
|
|
|
\set ON_ERROR_STOP on
|
|
set timezone = 'UTC';
|
|
|
|
begin;
|
|
|
|
do $ownership_guard$
|
|
declare
|
|
v_artifacts_present boolean;
|
|
v_ledger_owner_valid boolean;
|
|
v_ledger_row_valid boolean;
|
|
v_missing_objects text;
|
|
begin
|
|
select
|
|
pg_catalog.to_regclass('kb_stage.teleo_v3_installation_ownership') is not null
|
|
or pg_catalog.to_regclass('public.claim_evidence_assessments') is not null
|
|
or exists (
|
|
select 1
|
|
from information_schema.columns columns
|
|
where columns.table_schema = 'public'
|
|
and (columns.table_name, columns.column_name) in (
|
|
('claims', 'owner_agent_id'),
|
|
('claims', 'proposition'),
|
|
('claims', 'body_markdown'),
|
|
('claims', 'scope'),
|
|
('claims', 'access_scope'),
|
|
('claims', 'admission_state'),
|
|
('claims', 'revision_criteria'),
|
|
('claims', 'revision_kind'),
|
|
('claims', 'supersedes_id'),
|
|
('claims', 'accepted_by_proposal_id'),
|
|
('sources', 'canonical_url'),
|
|
('sources', 'storage_uri'),
|
|
('sources', 'content_hash'),
|
|
('sources', 'access_scope'),
|
|
('sources', 'ingestion_origin'),
|
|
('sources', 'provenance_status'),
|
|
('sources', 'source_class'),
|
|
('sources', 'auto_promotion_policy'),
|
|
('sources', 'accepted_by_proposal_id'),
|
|
('claim_evidence', 'excerpt'),
|
|
('claim_evidence', 'locator_json'),
|
|
('claim_evidence', 'source_content_hash'),
|
|
('claim_evidence', 'rationale'),
|
|
('claim_evidence', 'polarity'),
|
|
('claim_evidence', 'accepted_from_proposal_id'),
|
|
('claim_edges', 'relation_type'),
|
|
('claim_edges', 'rationale'),
|
|
('claim_edges', 'scope_or_conditions'),
|
|
('claim_edges', 'accepted_by_proposal_id')
|
|
)
|
|
)
|
|
or exists (
|
|
select 1
|
|
from pg_catalog.pg_proc procedure
|
|
join pg_catalog.pg_namespace namespace on namespace.oid = procedure.pronamespace
|
|
where namespace.nspname = 'kb_stage'
|
|
and procedure.proname like 'teleo\_v3\_%' escape '\'
|
|
)
|
|
or exists (
|
|
select 1
|
|
from pg_catalog.pg_trigger trigger_row
|
|
where not trigger_row.tgisinternal
|
|
and trigger_row.tgname like 'teleo\_v3\_%' escape '\'
|
|
)
|
|
or exists (
|
|
select 1
|
|
from pg_catalog.pg_constraint constraint_row
|
|
where constraint_row.conname like 'teleo\_v3\_%' escape '\'
|
|
)
|
|
or exists (
|
|
select 1
|
|
from pg_catalog.pg_class index_row
|
|
where index_row.relkind = 'i'
|
|
and index_row.relname like 'teleo\_v3\_%' escape '\'
|
|
)
|
|
into v_artifacts_present;
|
|
|
|
if pg_catalog.to_regclass('kb_stage.teleo_v3_installation_ownership') is null then
|
|
if v_artifacts_present then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = 'teleo_v3 rollback refused: V3-named objects lack exact installation ownership';
|
|
end if;
|
|
return;
|
|
end if;
|
|
|
|
select owner_role.rolname = 'kb_gate_owner'
|
|
into v_ledger_owner_valid
|
|
from pg_catalog.pg_class relation
|
|
join pg_catalog.pg_namespace namespace on namespace.oid = relation.relnamespace
|
|
join pg_catalog.pg_roles owner_role on owner_role.oid = relation.relowner
|
|
where namespace.nspname = 'kb_stage'
|
|
and relation.relname = 'teleo_v3_installation_ownership'
|
|
and relation.relkind in ('r', 'p');
|
|
if not coalesce(v_ledger_owner_valid, false) then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = 'teleo_v3 rollback refused: installation ownership ledger owner is invalid';
|
|
end if;
|
|
|
|
execute $ownership_query$
|
|
select count(*) = 1
|
|
and bool_and(
|
|
contract_name = 'livingip.teleo-v3-epistemic-contract'
|
|
and contract_version = 1
|
|
and installation_token = 'collision-free-install-v1'
|
|
)
|
|
from kb_stage.teleo_v3_installation_ownership
|
|
$ownership_query$ into v_ledger_row_valid;
|
|
if not coalesce(v_ledger_row_valid, false) then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = 'teleo_v3 rollback refused: installation ownership ledger is not exact';
|
|
end if;
|
|
|
|
with expected_columns(table_name, column_name) as (
|
|
values
|
|
('claims', 'owner_agent_id'),
|
|
('claims', 'proposition'),
|
|
('claims', 'body_markdown'),
|
|
('claims', 'scope'),
|
|
('claims', 'access_scope'),
|
|
('claims', 'admission_state'),
|
|
('claims', 'revision_criteria'),
|
|
('claims', 'revision_kind'),
|
|
('claims', 'supersedes_id'),
|
|
('claims', 'accepted_by_proposal_id'),
|
|
('sources', 'canonical_url'),
|
|
('sources', 'storage_uri'),
|
|
('sources', 'content_hash'),
|
|
('sources', 'access_scope'),
|
|
('sources', 'ingestion_origin'),
|
|
('sources', 'provenance_status'),
|
|
('sources', 'source_class'),
|
|
('sources', 'auto_promotion_policy'),
|
|
('sources', 'accepted_by_proposal_id'),
|
|
('claim_evidence', 'excerpt'),
|
|
('claim_evidence', 'locator_json'),
|
|
('claim_evidence', 'source_content_hash'),
|
|
('claim_evidence', 'rationale'),
|
|
('claim_evidence', 'polarity'),
|
|
('claim_evidence', 'accepted_from_proposal_id'),
|
|
('claim_edges', 'relation_type'),
|
|
('claim_edges', 'rationale'),
|
|
('claim_edges', 'scope_or_conditions'),
|
|
('claim_edges', 'accepted_by_proposal_id')
|
|
), missing(object_name) as (
|
|
select pg_catalog.format('%I.%I', expected.table_name, expected.column_name)
|
|
from expected_columns expected
|
|
where not exists (
|
|
select 1
|
|
from information_schema.columns columns
|
|
where columns.table_schema = 'public'
|
|
and columns.table_name = expected.table_name
|
|
and columns.column_name = expected.column_name
|
|
)
|
|
union all
|
|
select 'public.claim_evidence_assessments'
|
|
where pg_catalog.to_regclass('public.claim_evidence_assessments') is null
|
|
)
|
|
select pg_catalog.string_agg(object_name, ', ' order by object_name)
|
|
into v_missing_objects
|
|
from missing;
|
|
if v_missing_objects is not null then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = pg_catalog.format(
|
|
'teleo_v3 rollback refused: installation-owned object set is incomplete: %s',
|
|
v_missing_objects
|
|
);
|
|
end if;
|
|
end
|
|
$ownership_guard$;
|
|
|
|
do $data_guard$
|
|
declare
|
|
contract_rows_exist boolean := false;
|
|
begin
|
|
if to_regclass('public.claim_evidence_assessments') is not null then
|
|
execute 'select exists (select 1 from public.claim_evidence_assessments)'
|
|
into contract_rows_exist;
|
|
if contract_rows_exist then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = 'teleo_v3 rollback refused: claim_evidence_assessments contains V3 data';
|
|
end if;
|
|
end if;
|
|
|
|
if exists (
|
|
select 1 from information_schema.columns
|
|
where table_schema = 'public' and table_name = 'claim_edges'
|
|
and column_name = 'accepted_by_proposal_id'
|
|
) then
|
|
execute 'select exists (select 1 from public.claim_edges where accepted_by_proposal_id is not null)'
|
|
into contract_rows_exist;
|
|
if contract_rows_exist then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = 'teleo_v3 rollback refused: claim_edges contains proposal-linked V3 data';
|
|
end if;
|
|
end if;
|
|
|
|
if exists (
|
|
select 1 from information_schema.columns
|
|
where table_schema = 'public' and table_name = 'claim_evidence'
|
|
and column_name = 'accepted_from_proposal_id'
|
|
) then
|
|
execute 'select exists (select 1 from public.claim_evidence where accepted_from_proposal_id is not null)'
|
|
into contract_rows_exist;
|
|
if contract_rows_exist then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = 'teleo_v3 rollback refused: claim_evidence contains proposal-linked V3 data';
|
|
end if;
|
|
end if;
|
|
|
|
if exists (
|
|
select 1 from information_schema.columns
|
|
where table_schema = 'public' and table_name = 'sources'
|
|
and column_name = 'accepted_by_proposal_id'
|
|
) then
|
|
execute 'select exists (select 1 from public.sources where accepted_by_proposal_id is not null)'
|
|
into contract_rows_exist;
|
|
if contract_rows_exist then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = 'teleo_v3 rollback refused: sources contains proposal-linked V3 data';
|
|
end if;
|
|
end if;
|
|
|
|
if exists (
|
|
select 1 from information_schema.columns
|
|
where table_schema = 'public' and table_name = 'claims'
|
|
and column_name = 'admission_state'
|
|
) then
|
|
execute $query$
|
|
select exists (
|
|
select 1 from public.claims
|
|
where admission_state = 'admitted' or accepted_by_proposal_id is not null
|
|
)
|
|
$query$ into contract_rows_exist;
|
|
if contract_rows_exist then
|
|
raise exception using
|
|
errcode = '55000',
|
|
message = 'teleo_v3 rollback refused: claims contains admitted or proposal-linked V3 data';
|
|
end if;
|
|
end if;
|
|
end
|
|
$data_guard$;
|
|
|
|
drop trigger if exists teleo_v3_guard_linked_proposal_decision on kb_stage.kb_proposals;
|
|
drop trigger if exists teleo_v3_00_enforce_apply_contract_cutover on kb_stage.kb_proposals;
|
|
alter table kb_stage.kb_proposals
|
|
drop constraint if exists teleo_v3_proposal_apply_receipt_check;
|
|
|
|
drop trigger if exists teleo_v3_edge_immutable on public.claim_edges;
|
|
drop trigger if exists teleo_v3_edge_reject_delete on public.claim_edges;
|
|
drop trigger if exists teleo_v3_edge_validate_endpoints on public.claim_edges;
|
|
drop trigger if exists teleo_v3_edge_require_accepted_proposal on public.claim_edges;
|
|
drop trigger if exists teleo_v3_00_edge_require_linked_insert on public.claim_edges;
|
|
|
|
drop trigger if exists teleo_v3_evidence_immutable on public.claim_evidence;
|
|
drop trigger if exists teleo_v3_evidence_reject_delete on public.claim_evidence;
|
|
drop trigger if exists teleo_v3_evidence_validate_provenance on public.claim_evidence;
|
|
drop trigger if exists teleo_v3_evidence_require_accepted_proposal on public.claim_evidence;
|
|
drop trigger if exists teleo_v3_00_evidence_require_linked_insert on public.claim_evidence;
|
|
|
|
drop trigger if exists teleo_v3_source_immutable on public.sources;
|
|
drop trigger if exists teleo_v3_source_reject_delete on public.sources;
|
|
drop trigger if exists teleo_v3_source_require_accepted_proposal on public.sources;
|
|
drop trigger if exists teleo_v3_00_source_require_linked_insert on public.sources;
|
|
|
|
drop trigger if exists teleo_v3_claim_immutable on public.claims;
|
|
drop trigger if exists teleo_v3_claim_reject_delete on public.claims;
|
|
drop trigger if exists teleo_v3_claim_require_accepted_proposal on public.claims;
|
|
drop trigger if exists teleo_v3_00_claim_require_linked_insert on public.claims;
|
|
|
|
drop index if exists public.teleo_v3_edge_typed_adjacency_idx;
|
|
drop index if exists public.teleo_v3_evidence_claim_polarity_idx;
|
|
drop index if exists public.teleo_v3_assessment_one_successor_idx;
|
|
drop index if exists public.teleo_v3_claim_one_admitted_successor_idx;
|
|
|
|
drop table if exists public.claim_evidence_assessments;
|
|
|
|
alter table public.claim_edges
|
|
drop constraint if exists teleo_v3_edge_contract_check,
|
|
drop constraint if exists teleo_v3_edge_accepted_proposal_fkey,
|
|
drop column if exists relation_type,
|
|
drop column if exists rationale,
|
|
drop column if exists scope_or_conditions,
|
|
drop column if exists accepted_by_proposal_id;
|
|
|
|
alter table public.claim_evidence
|
|
drop constraint if exists teleo_v3_evidence_contract_check,
|
|
drop constraint if exists teleo_v3_evidence_accepted_proposal_fkey,
|
|
drop column if exists excerpt,
|
|
drop column if exists locator_json,
|
|
drop column if exists source_content_hash,
|
|
drop column if exists rationale,
|
|
drop column if exists polarity,
|
|
drop column if exists accepted_from_proposal_id;
|
|
|
|
alter table public.sources
|
|
drop constraint if exists teleo_v3_source_contract_check,
|
|
drop constraint if exists teleo_v3_source_accepted_proposal_fkey,
|
|
drop column if exists canonical_url,
|
|
drop column if exists storage_uri,
|
|
drop column if exists content_hash,
|
|
drop column if exists access_scope,
|
|
drop column if exists ingestion_origin,
|
|
drop column if exists provenance_status,
|
|
drop column if exists source_class,
|
|
drop column if exists auto_promotion_policy,
|
|
drop column if exists accepted_by_proposal_id;
|
|
|
|
alter table public.claims
|
|
drop constraint if exists teleo_v3_claim_admission_check,
|
|
drop constraint if exists teleo_v3_claim_accepted_proposal_fkey,
|
|
drop constraint if exists teleo_v3_claim_supersedes_fkey,
|
|
drop constraint if exists teleo_v3_claim_owner_agent_fkey,
|
|
drop column if exists owner_agent_id,
|
|
drop column if exists proposition,
|
|
drop column if exists body_markdown,
|
|
drop column if exists scope,
|
|
drop column if exists access_scope,
|
|
drop column if exists admission_state,
|
|
drop column if exists revision_criteria,
|
|
drop column if exists revision_kind,
|
|
drop column if exists supersedes_id,
|
|
drop column if exists accepted_by_proposal_id;
|
|
|
|
drop function if exists kb_stage.teleo_v3_guard_linked_proposal_decision();
|
|
drop function if exists kb_stage.teleo_v3_acquire_protected_relation_locks();
|
|
drop function if exists kb_stage.teleo_v3_enforce_apply_contract_cutover();
|
|
drop function if exists kb_stage.teleo_v3_validate_evidence_assessment();
|
|
drop function if exists kb_stage.teleo_v3_validate_claim_edge();
|
|
drop function if exists kb_stage.teleo_v3_validate_claim_evidence();
|
|
drop function if exists kb_stage.teleo_v3_guard_immutable_fields();
|
|
drop function if exists kb_stage.teleo_v3_reject_delete();
|
|
drop function if exists kb_stage.teleo_v3_require_linked_insert();
|
|
drop function if exists kb_stage.teleo_v3_require_accepted_proposal();
|
|
|
|
drop table if exists kb_stage.teleo_v3_installation_ownership;
|
|
|
|
commit;
|
|
|
|
select jsonb_build_object(
|
|
'contract', 'livingip.teleo-v3-epistemic-contract',
|
|
'version', 1,
|
|
'migration', 'rolled_back'
|
|
)::text;
|