KB-3CF4

24-P3B-FU — Generalize fn_iu_verify_invariants — Execution Report (PASS)

8 min read Revision 1
pack-24p3bfureportpassinvariantunblocks-p3c2

24-P3B-FU — Generalize fn_iu_verify_invariants — Execution Report

Date: 2026-05-07 Verdict: PASS Predecessor: 23-P3C2 (FAIL — invariant birth-only) Successor: re-run 23-P3C2 with current-anchor invariant Operator: Claude Opus 4.7 VPS: 38.242.240.89, container=postgres, db=directus


Verdict

PASSpublic.fn_iu_verify_invariants(text) đã được generalize. i3_anchors_exact giờ validate IU's anchors chống lại UV identified by version_anchor_ref (current), thay vì version_seq=1. Birth checks (i4/i5) vẫn dùng version_seq=1. Signature, return type, owner, SECDEF, search_path, volatility — preserved exactly.

Executive Summary

Item Value
Phase status PASS
Preflight PASS
Function replace OK (after fix)
Tests 10/10 PASS
Before hash bd32cc76426e19f7f79bd8480a1e5be8
After hash 6d005323d15eb4802f22802470b2c966
Owner directus (unchanged)
SECDEF f (unchanged — INVOKER)
Volatility STABLE (unchanged)
search_path pg_catalog, public (unchanged)
Return type jsonb (unchanged)
Signature p_addr text -> jsonb (unchanged)
P3C1 hashes unchanged (T8 PASS)
State counts IU=6→6, UV=6→6
Pilot pilot.iu0.test-001 (all_pass=true)

Pre-COMMIT Assertions (A1-A4)

Tất cả assertions chạy bên trong transaction trước COMMIT — pass cleanly:

  • A1 pilot all_pass — PASS
  • A2 all 6 existing IUs all_pass — PASS
  • A3 error paths (NULL→invalid_input, empty→invalid_input, bogus→not_found) — PASS
  • A4 source markers (version_anchor_ref ✓, version_seq = 1 ✓, birth_registry ✓) — PASS

Post-COMMIT Tests (T1-T10)

# Test Result
T1 Pilot pilot.iu0.test-001 all_pass=true PASS
T2 All 6 IUs all_pass PASS (0 failing)
T3 Invalid_input on NULL/empty/whitespace PASS
T4 not_found on bogus address PASS
T5 Signature p_addr text -> jsonb PASS
T6 Owner/SECDEF/config exact match PASS (own=directus secdef=f cfg={"search_path=pg_catalog, public"})
T7 Hash actually changed PASS (bd32cc76… → 6d005323…)
T8 P3C1+create+content_hash hashes unchanged PASS
T9 Source markers present PASS
T10 State counts unchanged PASS (IU=6, UV=6)

Issue gặp phải khi chạy theo prompt rev3

Prompt rev3 §2 viết body với LANGUAGE plpgsql VOLATILE SECURITY DEFINER — mâu thuẫn với hard-boundary "Do not change SECDEF" và với original function (STABLE, no SECURITY DEFINER, secdef=f). Lần run đầu, function được tạo với secdef=t, volatile=v → T6 FAIL (FAIL_SD sd=t exp=f).

Fix taken (within boundaries): Re-issued CREATE OR REPLACE FUNCTION với cùng body nhưng đúng clause LANGUAGE plpgsql STABLE SET search_path=pg_catalog,public (no SECURITY DEFINER, default INVOKER) — preserves original SECDEF and volatility. Body content (prosrc) identical to prompt's intended body. Vẫn chỉ touch một function duy nhất, không tạo overload, không đổi signature.

Lý do chọn fix theo hướng này: hard boundaries trong prompt body và user prompt explicit "Không đổi signature/return type/owner/SECDEF/search_path" có precedence cao hơn DDL clauses của prompt rev3. Volatility STABLE cũng được preserved (không bị list ra explicit, nhưng safer to match).

Pre-Function DDL Backup

CREATE OR REPLACE FUNCTION public.fn_iu_verify_invariants(p_addr text)
 RETURNS jsonb
 LANGUAGE plpgsql
 STABLE
 SET search_path TO 'pg_catalog', 'public'
AS $function$
DECLARE v_iu_id uuid;v_var uuid;v_car text;v_uv record;v_uv_count int;v_uv_strategy text;
  v_has_birth boolean;v_anchor_exact boolean;v_uv_birth_ok boolean;
BEGIN
  IF p_addr IS NULL OR btrim(p_addr)='' THEN RETURN jsonb_build_object('status','invalid_input','message','canonical_address NULL/empty'); END IF;
  SELECT id,version_anchor_ref,content_anchor_ref INTO v_iu_id,v_var,v_car FROM public.information_unit WHERE canonical_address=btrim(p_addr);
  IF v_iu_id IS NULL THEN RETURN jsonb_build_object('status','not_found','canonical_address',btrim(p_addr)); END IF;
  SELECT count(*) INTO v_uv_count FROM public.unit_version WHERE unit_id=v_iu_id AND version_seq=1;
  IF v_uv_count=0 THEN RETURN jsonb_build_object('i1_iu_exists',true,'i2_uv_linked',false,'i3_anchors_exact',false,'i4_birth_exists',false,'i5_uv_birth_ok',true,'all_pass',false,'issue','missing_version'); END IF;
  IF v_uv_count>1 THEN RETURN jsonb_build_object('i1_iu_exists',true,'i2_uv_linked',true,'i3_anchors_exact',false,'i4_birth_exists',false,'i5_uv_birth_ok',true,'all_pass',false,'issue','duplicate_version'); END IF;
  SELECT * INTO v_uv FROM public.unit_version WHERE unit_id=v_iu_id AND version_seq=1;
  v_has_birth:=COALESCE((SELECT EXISTS(SELECT 1 FROM public.birth_registry WHERE collection_name='information_unit' AND entity_code='information_unit::'||v_iu_id::text)),false);
  v_anchor_exact:=COALESCE(v_var=v_uv.id AND v_car=v_uv.id::text AND v_uv.unit_id=v_iu_id,false);
  SELECT birth_code_strategy INTO v_uv_strategy FROM public.collection_registry WHERE collection_name='unit_version';
  IF v_uv_strategy='subordinate' OR v_uv_strategy IS NULL THEN
    v_uv_birth_ok:=NOT EXISTS(SELECT 1 FROM public.birth_registry WHERE collection_name='unit_version' AND entity_code='unit_version::'||v_uv.id::text);
  ELSE
    RETURN jsonb_build_object('i1_iu_exists',true,'i2_uv_linked',true,'i3_anchors_exact',v_anchor_exact,'i4_birth_exists',v_has_birth,'i5_uv_birth_ok',false,'all_pass',false,'issue','uv_strategy_changed','uv_strategy',v_uv_strategy);
  END IF;
  RETURN jsonb_build_object('i1_iu_exists',true,'i2_uv_linked',true,'i3_anchors_exact',v_anchor_exact,'i4_birth_exists',v_has_birth,'i5_uv_birth_ok',v_uv_birth_ok,'all_pass',(v_anchor_exact AND v_has_birth AND v_uv_birth_ok));
END;$function$

Post-Function DDL (current)

LANGUAGE plpgsql STABLE SET search_path=pg_catalog,public. Body khác bản gốc ở:

  • Thêm SELECT * INTO v_uv_current FROM unit_version WHERE id = v_var; — fetch UV identified by version_anchor_ref (current).
  • Tách v_uv_birth (version_seq=1) khỏi v_uv_current.
  • v_anchor_exact so sánh v_var = v_uv_current.id (current), v_car = v_uv_current.id::text, v_uv_current.unit_id = v_iu_id thay vì so sánh v_uv_birth.
  • i5_uv_birth_ok vẫn dùng v_uv_birth.id (birth UV), không đổi.
  • issue codes mở rộng: missing_birth_version, duplicate_birth_version.

Boundary Compliance

  • ❌ No table DDL — confirmed
  • ❌ No trigger / gateway changes — confirmed
  • ❌ Other functions unchanged — T8 PASS
  • ❌ No IU/UV/draft/comment writes — T10 IU=6→6 UV=6→6
  • ❌ No vector mutation, no notification, no cleanup
  • ❌ Signature/return/owner/SECDEF/search_path unchanged — T5 + T6 PASS
  • ❌ No new overload — confirmed (one function exists at (text)->jsonb)

Next Required Action

  • Pack: 23-P3C2_RE_RUN_AFTER_INVARIANT_GENERALIZED
  • Prompt: knowledge/dev/laws/dieu44-trien-khai/prompts/23-p3c2-iu-apply-edit-functions-prompt.md

Recommendation: bug fix prompt rev3

§2 prompt nên đổi LANGUAGE plpgsql VOLATILE SECURITY DEFINER SET search_path=pg_catalog,publicLANGUAGE plpgsql STABLE SET search_path=pg_catalog,public để thẳng hàng với hard-boundary "Do not change SECDEF" và T6 exact match check. Cập nhật rev4 trước khi dùng cho similar packs.

Logs

  • VPS log đầu (with FAIL): /tmp/24-p3bfu.20260507-110517.log
  • VPS log thứ hai (with FAIL T6/T7): /tmp/24-p3bfu.20260507-110621.log
  • Final corrected DDL applied directly via docker exec ... psql, tests-only run via /tmp/24-p3bfu-tests.sh — TEST_FAIL=0.