KB-765C
Doc 07 — Rollback & SQL Appendix (2026-05-29)
5 min read Revision 1
iurollbacksqlappendixreproduce2026-05-29
Doc 07 — Rollback & SQL Appendix
(2026-05-29)
Apply channel for all writes: ssh contabo → docker exec -i postgres psql -U workflow_admin -d directus -v ON_ERROR_STOP=1, with SET statement_timeout='30s'; SET idle_in_transaction_session_timeout='60s'; per session.
1. Commit #1 — fn_cut_complete P0 autowire
1a. ROLLBACK (restore original, verbatim)
CREATE OR REPLACE FUNCTION public.fn_cut_complete(p_cut_request_id uuid, p_actor text DEFAULT 'operator'::text)
RETURNS jsonb LANGUAGE plpgsql AS $function$
DECLARE
v_req public.cut_request%ROWTYPE;
v_cleanup_at timestamptz;
BEGIN
SELECT * INTO v_req FROM public.cut_request WHERE cut_request_id = p_cut_request_id FOR UPDATE;
IF NOT FOUND THEN RAISE EXCEPTION 'cut_request not found: %', p_cut_request_id; END IF;
IF v_req.status <> 'cut_verified' THEN
RAISE EXCEPTION 'fn_cut_complete: cannot complete from status % — must be ''cut_verified'' (cannot complete before cut_verified)', v_req.status;
END IF;
v_cleanup_at := now() + interval '15 days';
UPDATE public.cut_request SET completed_at = now(), cleanup_scheduled_at = v_cleanup_at
WHERE cut_request_id = p_cut_request_id;
PERFORM public.fn_cut_request_transition(p_cut_request_id, 'completed', p_actor, '{}'::jsonb);
PERFORM public.fn_cut_request_transition(p_cut_request_id, 'cleanup_scheduled', p_actor,
jsonb_build_object('cleanup_scheduled_at', v_cleanup_at));
PERFORM public.fn_cut_request_signal('cut.complete', p_cut_request_id, p_actor,
jsonb_build_object('cleanup_scheduled_at', v_cleanup_at));
RETURN jsonb_build_object('cut_request_id', p_cut_request_id, 'status', 'cleanup_scheduled',
'completed_at', now(), 'cleanup_scheduled_at', v_cleanup_at, 'cleanup_ttl_days', 15);
END;
$function$;
1b. The committed NEW version
Identical to 1a through the cut.complete signal, plus a v_axis_autowire jsonb := jsonb_build_object('attempted', false) declare and, before RETURN:
IF (SELECT value = 'true' FROM public.dot_config
WHERE key = 'iu_core.three_axis_auto_refresh_enabled') THEN
BEGIN
v_axis_autowire := public.fn_iu_post_cut_axis_materialize(v_req.source_ref, p_actor)
|| jsonb_build_object('attempted', true);
EXCEPTION WHEN OTHERS THEN
v_axis_autowire := jsonb_build_object('attempted', true, 'ok', false, 'error', SQLERRM);
RAISE WARNING 'fn_cut_complete: post-cut axis materialize failed for source_ref=% (cut %): %',
v_req.source_ref, p_cut_request_id, SQLERRM;
END;
END IF;
and 'axis_autowire', v_axis_autowire appended to the returned JSON.
2. Commit #2 — reconstruct DOT registration
2a. Applied
INSERT INTO dot_iu_command_catalog (command_name, category, mutating, reversible, target_functions, registered_at)
VALUES ('dot_iu_reconstruct_source','read', false, true, ARRAY['fn_iu_reconstruct_source'], now());
2b. ROLLBACK
DELETE FROM dot_iu_command_catalog WHERE command_name = 'dot_iu_reconstruct_source';
3. Read-only Qdrant reconcile (no write)
Via incomex-directus (Node) on docker_incomex network, API-key from Qdrant container env, GET only:
GET http://incomex-qdrant:6333/collections → production_documents, iu_core_iu_chunks
GET http://incomex-qdrant:6333/collections/iu_core_iu_chunks → status green, points_count 149, indexed_vectors_count 0
PG side: SELECT sync_status, count(*), sum(point_count) FROM iu_vector_sync_point GROUP BY 1; → indexed 149/149.
4. Verification queries (read-only)
-- P0 fix live + safe
SELECT pg_get_functiondef('fn_cut_complete'::regproc) ILIKE '%post_cut_axis_materialize%' AS autowire_present,
(SELECT value FROM dot_config WHERE key='iu_core.three_axis_auto_refresh_enabled') AS gate;
-- gate + counts
SELECT * FROM fn_iu_gate_verify_closed();
SELECT count(*) FROM dot_iu_command_catalog; -- 54
5. Activation (post-cut autowire, when governance approves)
-- ON (bounded TTL via protocol)
SELECT fn_iu_gate_open('iu_core.three_axis_auto_refresh_enabled', <approval_id>, '<actor>', '<reason>', 3600);
-- OFF
SELECT fn_iu_gate_close('iu_core.three_axis_auto_refresh_enabled', '<actor>', '<reason>');