Files
Jyotisha/frontend/supabase/migrations/20260826010000_rectification_inference_round_audit.sql
T
Jesse_Chen a0ce55f066
Independent Staging Quality Gate / validate (push) Successful in 11m17s
Independent Staging Quality Gate / publish (push) Failing after 9m28s
fix(web): drive rectification from candidate contrast and allow range close
Showing a choice card is no longer treated as completion. Distinguish probes
require real candidate groups, holdout stays out of scoring, and ordinary
sessions can finish with a credible range instead of an exact-minute gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-26 17:19:26 +08:00

194 lines
6.7 KiB
PL/PgSQL

-- Persist first-class inference-round audit fields without changing RPC signatures.
-- Entropy, eliminated IDs and round_kind are extracted from inference_state.
begin;
alter table public.agentic_rectification_inference_transitions
add column if not exists entropy_before double precision,
add column if not exists entropy_after double precision,
add column if not exists eliminated_candidate_ids jsonb not null default '[]'::jsonb,
add column if not exists round_kind text;
alter table public.agentic_rectification_inference_transitions
drop constraint if exists agentic_rectification_inference_round_kind_check;
alter table public.agentic_rectification_inference_transitions
add constraint agentic_rectification_inference_round_kind_check
check (round_kind is null or round_kind in ('informative', 'low_information'));
alter table public.agentic_rectification_inference_transitions
drop constraint if exists agentic_rectification_inference_eliminated_ids_check;
alter table public.agentic_rectification_inference_transitions
add constraint agentic_rectification_inference_eliminated_ids_check
check (jsonb_typeof(eliminated_candidate_ids) = 'array');
create or replace function public.fill_agentic_rectification_inference_round()
returns trigger
language plpgsql
set search_path = ''
as $$
declare
v_round jsonb;
v_len integer;
begin
v_round := case
when jsonb_typeof(new.inference_state -> 'last_inference_round') = 'object'
then new.inference_state -> 'last_inference_round'
else null
end;
if v_round is null then
v_len := jsonb_array_length(coalesce(new.inference_state -> 'rounds', '[]'::jsonb));
if v_len > 0 then
v_round := new.inference_state -> 'rounds' -> (v_len - 1);
end if;
end if;
if v_round is not null and jsonb_typeof(v_round) = 'object' then
begin
new.entropy_before := (v_round ->> 'entropy_before')::double precision;
exception when others then
new.entropy_before := new.entropy_before;
end;
begin
new.entropy_after := (v_round ->> 'entropy_after')::double precision;
exception when others then
new.entropy_after := new.entropy_after;
end;
if jsonb_typeof(v_round -> 'eliminated_ids') = 'array' then
new.eliminated_candidate_ids := v_round -> 'eliminated_ids';
end if;
if v_round ->> 'kind' in ('informative', 'low_information') then
new.round_kind := v_round ->> 'kind';
end if;
end if;
if new.round_kind is null
and new.posterior_before = new.posterior_after
and new.score_deltas = '{}'::jsonb then
new.round_kind := 'low_information';
end if;
return new;
end;
$$;
drop trigger if exists fill_agentic_rectification_inference_round
on public.agentic_rectification_inference_transitions;
create trigger fill_agentic_rectification_inference_round
before insert or update of inference_state, posterior_before, posterior_after, score_deltas
on public.agentic_rectification_inference_transitions
for each row
execute function public.fill_agentic_rectification_inference_round();
create or replace function public.get_agentic_rectification_latest_inference_transition(
p_user_id uuid,
p_case_id uuid
)
returns jsonb
language plpgsql
stable
security definer
set search_path = ''
as $$
declare
v_case public.agentic_rectification_cases%rowtype;
v_transition public.agentic_rectification_inference_transitions%rowtype;
begin
if p_user_id is null or p_case_id is null then
raise exception 'agentic_rectification_invalid_input' using errcode = 'P0001';
end if;
select * into v_case
from public.agentic_rectification_cases
where id = p_case_id and user_id = p_user_id;
if not found then
raise exception 'agentic_rectification_case_not_found' using errcode = 'P0001';
end if;
select * into v_transition
from public.agentic_rectification_inference_transitions
where case_id = p_case_id
order by revision desc
limit 1;
if not found then
return null;
end if;
return jsonb_build_object(
'id', v_transition.id,
'result_id', v_transition.result_id,
'previous_revision', v_transition.previous_revision,
'revision', v_transition.revision,
'probe_id', v_transition.probe_id,
'reason', v_transition.reason,
'decision_state_fingerprint', v_transition.decision_state_fingerprint,
'inference_state', v_transition.inference_state,
'posterior_before', v_transition.posterior_before,
'posterior_after', v_transition.posterior_after,
'score_deltas', v_transition.score_deltas,
'entropy_before', v_transition.entropy_before,
'entropy_after', v_transition.entropy_after,
'eliminated_candidate_ids', v_transition.eliminated_candidate_ids,
'round_kind', v_transition.round_kind
);
end;
$$;
revoke all on function public.get_agentic_rectification_latest_inference_transition(uuid, uuid)
from public, anon, authenticated;
grant execute on function public.get_agentic_rectification_latest_inference_transition(uuid, uuid)
to service_role;
create or replace function public.list_agentic_rectification_inference_transitions(
p_user_id uuid,
p_case_id uuid
)
returns jsonb
language plpgsql
stable
security definer
set search_path = ''
as $$
declare
v_case public.agentic_rectification_cases%rowtype;
v_rows jsonb;
begin
if p_user_id is null or p_case_id is null then
raise exception 'agentic_rectification_invalid_input' using errcode = 'P0001';
end if;
select * into v_case
from public.agentic_rectification_cases
where id = p_case_id and user_id = p_user_id;
if not found then
raise exception 'agentic_rectification_case_not_found' using errcode = 'P0001';
end if;
select coalesce(jsonb_agg(jsonb_build_object(
'id', item.id,
'result_id', item.result_id,
'previous_revision', item.previous_revision,
'revision', item.revision,
'probe_id', item.probe_id,
'semantic_key', item.semantic_key,
'candidate_split_hash', item.candidate_split_hash,
'answer_class', item.answer_class,
'reason', item.reason,
'decision_state_fingerprint', item.decision_state_fingerprint,
'inference_state', item.inference_state,
'posterior_before', item.posterior_before,
'posterior_after', item.posterior_after,
'score_deltas', item.score_deltas,
'entropy_before', item.entropy_before,
'entropy_after', item.entropy_after,
'eliminated_candidate_ids', item.eliminated_candidate_ids,
'round_kind', item.round_kind
) order by item.revision), '[]'::jsonb)
into v_rows
from public.agentic_rectification_inference_transitions item
where item.case_id = p_case_id;
return v_rows;
end;
$$;
revoke all on function public.list_agentic_rectification_inference_transitions(uuid, uuid)
from public, anon, authenticated;
grant execute on function public.list_agentic_rectification_inference_transitions(uuid, uuid)
to service_role;
commit;