import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; const migration = readFileSync( new URL("../supabase/migrations/20260804010000_agentic_rectification_candidate_acceptance.sql", import.meta.url), "utf8", ); const preservationMigration = readFileSync( new URL("../supabase/migrations/20260804020000_preserve_reported_birth_time_on_candidate_acceptance.sql", import.meta.url), "utf8", ); const decisionContractV2Migration = readFileSync( new URL( "../supabase/migrations/20260814030000_rectification_event_decision_contract_v2.sql", import.meta.url, ), "utf8", ); test("candidate acceptance migration adds accepted status and durable result ownership", () => { assert.match(migration, /birth_time_status in \([\s\S]*'reported'[\s\S]*'assessing'[\s\S]*'rectifying'[\s\S]*'candidate'[\s\S]*'accepted'[\s\S]*'confirmed'[\s\S]*\)/); assert.match(migration, /create table public\.agentic_rectification_results/); assert.match(migration, /user_id uuid not null references auth\.users\(id\)/); assert.match(migration, /session_id uuid not null references public\.chat_sessions\(id\)/); assert.match(migration, /expires_at timestamptz not null/); assert.match(migration, /invalidated_at timestamptz/); }); test("candidate acceptance RPC validates ownership, freshness, gate, membership, and profile baseline", () => { assert.match(migration, /where id = p_result_id[\s\S]*user_id = p_user_id[\s\S]*session_id = p_session_id/); assert.match(migration, /invalidated_at is not null or v_result\.expires_at <= pg_catalog\.now\(\)/); assert.match(migration, /if not v_result\.selection_allowed/); assert.match(migration, /jsonb_array_elements\(v_result\.candidates\)[\s\S]*candidate ->> 'time'/); assert.match(migration, /v_profile\.birth_date is distinct from v_result\.baseline_birth_date/); assert.match(migration, /v_profile\.reported_birth_time is distinct from v_result\.baseline_reported_birth_time/); assert.match(migration, /v_profile\.active_birth_time is distinct from v_result\.baseline_active_birth_time/); assert.match(migration, /v_profile\.birth_time_period is distinct from v_result\.baseline_birth_time_period/); assert.match(migration, /v_profile\.latitude is distinct from v_result\.baseline_latitude/); assert.match(migration, /v_profile\.longitude is distinct from v_result\.baseline_longitude/); assert.match(migration, /v_profile\.timezone_offset is distinct from v_result\.baseline_timezone_offset/); }); test("candidate acceptance is idempotent before baseline checks and separates accepted from confirmed", () => { const idempotent = migration.indexOf("if v_result.selected_time is not null"); const baseline = migration.indexOf("select * into v_profile"); assert.ok(idempotent >= 0 && baseline > idempotent); assert.match(migration, /v_result\.confirmation_allowed[\s\S]*v_result\.representative_time is not distinct from p_time[\s\S]*then 'engine_confirmed'[\s\S]*else 'user_accepted'/); assert.match(migration, /v_status := case when v_selection_kind = 'engine_confirmed' then 'confirmed' else 'accepted' end/); assert.match(migration, /agentic_rectification_candidate_superseded/); assert.match(migration, /v_profile\.active_birth_time is distinct from v_result\.selected_time/); }); test("candidate acceptance writes the active chart time without replacing reported time", () => { const profileUpdate = migration.slice( migration.indexOf("update public.profiles"), migration.indexOf("update public.agentic_rectification_results", migration.indexOf("update public.profiles")), ); assert.match(profileUpdate, /active_birth_time = p_time/); assert.match(profileUpdate, /birth_time = p_time/); assert.match(profileUpdate, /birth_time_status = v_status/); assert.doesNotMatch(profileUpdate, /reported_birth_time\s*=/); }); test("candidate acceptance RPC is service-role only", () => { assert.match(migration, /revoke all on function public\.accept_agentic_rectification_candidate[\s\S]*from public, anon, authenticated/); assert.match(migration, /grant execute on function public\.accept_agentic_rectification_candidate[\s\S]*to service_role/); assert.doesNotMatch(migration, /grant execute on function public\.accept_agentic_rectification_candidate[\s\S]*to authenticated/); }); test("profile declaration changes invalidate restored Agentic candidate results", () => { assert.match(migration, /create trigger profiles_invalidate_agentic_rectification_results/); assert.match(migration, /old\.birth_time_period is distinct from new\.birth_time_period/); assert.match(migration, /old\.latitude is distinct from new\.latitude/); assert.match(migration, /set invalidated_at = pg_catalog\.now\(\)/); assert.match(migration, /coalesce\(new\.birth_time_status, ''\) not in \('accepted', 'confirmed'\)/); }); test("forward repair separates original declaration from the active chart time", () => { const profileUpdate = preservationMigration.slice( preservationMigration.indexOf("update public.profiles\n set active_birth_time"), preservationMigration.indexOf("update public.agentic_rectification_results", preservationMigration.indexOf("update public.profiles\n set active_birth_time")), ); assert.match(profileUpdate, /active_birth_time = p_time/); assert.match(profileUpdate, /birth_time_status = v_status/); assert.doesNotMatch(profileUpdate, /^\s*birth_time = p_time/m); assert.doesNotMatch(profileUpdate, /reported_birth_time\s*=/); assert.doesNotMatch(preservationMigration, /v_profile\.birth_time is distinct from v_result\.selected_time/); }); test("forward repair removes legacy field mirroring and repairs already selected Agentic profiles", () => { const guard = preservationMigration.slice( preservationMigration.indexOf("create or replace function public.guard_birth_time_journey"), preservationMigration.indexOf("update public.profiles", preservationMigration.indexOf("create or replace function public.guard_birth_time_journey")), ); assert.doesNotMatch(guard, /new\.birth_time := new\.active_birth_time/); assert.doesNotMatch(guard, /new\.active_birth_time := new\.birth_time/); assert.match(preservationMigration, /p\.birth_time_status in \('accepted', 'confirmed'\)/); assert.match(preservationMigration, /p\.active_birth_time is not distinct from selected\.selected_time/); }); test("forward repair lets the user change a previously adopted candidate", () => { assert.doesNotMatch(preservationMigration, /agentic_rectification_candidate_already_selected/); assert.match(preservationMigration, /v_profile\.active_birth_time is distinct from v_result\.selected_time/); assert.match(preservationMigration, /update public\.agentic_rectification_results[\s\S]*selected_time = p_time/); }); test("decision contract V2 accepts server candidate UUIDs and never caller-supplied times", () => { const acceptStart = decisionContractV2Migration.indexOf( "create or replace function public.accept_agentic_rectification_candidate_for_case_v2(", ); const confirmStart = decisionContractV2Migration.indexOf( "create or replace function public.confirm_agentic_rectification_candidate_for_case_v2(", ); const acceptFunction = decisionContractV2Migration.slice(acceptStart, confirmStart); const confirmFunction = decisionContractV2Migration.slice(confirmStart); assert.match(acceptFunction, /p_candidate_id uuid/); assert.match(acceptFunction, /p_request_id uuid/); assert.doesNotMatch(acceptFunction, /p_time\s+time/); assert.match(confirmFunction, /p_candidate_id uuid/); assert.match(confirmFunction, /p_request_id uuid/); assert.doesNotMatch(confirmFunction, /p_time\s+time/); for (const functionBody of [acceptFunction, confirmFunction]) { assert.match(functionBody, /where id = p_result_id[\s\S]*user_id = p_user_id[\s\S]*case_id = p_case_id/); assert.match(functionBody, /where id = p_candidate_id[\s\S]*result_id = p_result_id[\s\S]*user_id = p_user_id[\s\S]*case_id = p_case_id/); assert.match(functionBody, /v_candidate\.candidate_time/); } }); test("decision contract V2 acceptance can only write accepted state", () => { const acceptStart = decisionContractV2Migration.indexOf( "create or replace function public.accept_agentic_rectification_candidate_for_case_v2(", ); const confirmStart = decisionContractV2Migration.indexOf( "create or replace function public.confirm_agentic_rectification_candidate_for_case_v2(", ); const acceptFunction = decisionContractV2Migration.slice(acceptStart, confirmStart); assert.match(acceptFunction, /birth_time_status = 'accepted'/); assert.match(acceptFunction, /selection_kind = 'user_accepted'/); assert.match(acceptFunction, /status = 'candidate_accepted'/); assert.doesNotMatch(acceptFunction, /engine_confirmed/); assert.doesNotMatch(acceptFunction, /birth_time_status = 'confirmed'/); }); test("decision contract V2 confirmation remains a separate exact and consent-grounded gate", () => { const confirmStart = decisionContractV2Migration.indexOf( "create or replace function public.confirm_agentic_rectification_candidate_for_case_v2(", ); const confirmFunction = decisionContractV2Migration.slice(confirmStart); assert.match(confirmFunction, /if not v_result\.confirmation_allowed/); assert.match(confirmFunction, /if not v_candidate\.is_representative/); assert.match(confirmFunction, /agentic_rectification_confirmation_exact_gate_blocked/); assert.match(confirmFunction, /public\.agentic_rectification_normalize_quote\(p_consent_quote\)/); assert.match(confirmFunction, /public\.agentic_rectification_normalize_quote\(v_turn\.user_message\)/); assert.match(confirmFunction, /agentic_rectification_consent_not_grounded/); assert.match(confirmFunction, /birth_time_status = 'confirmed'/); assert.match(confirmFunction, /selection_kind = 'engine_confirmed'/); });