a0ce55f066
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>
194 lines
6.7 KiB
PL/PgSQL
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;
|