KB-4780

04 — Function fixes (mig 054)

5 min read Revision 1
dieu44dieu39mig-054function-fix

04 — Function fixes (mig 054)

Single TX, COMMITTED 2026-05-27 02:51 UTC. File: /tmp/mig_054_dieu39_verify_mark_root_cause_fix.sql.

Fix 1 — fn_iu_verify_mark

before after
md5 923263c84d5b37070eaa0fc8f9017bb7 04e5191c430a142712bfe63089863d44

Patch summary

  • Bug: v_problems := v_problems || 'literal' — PG resolved this as text[] || 'literal'::text[], requiring {...} array-literal syntax, raised malformed array literal and aborted.
  • Fix: every bare string literal on the right of || is wrapped as ARRAY['…'] (5 sites: manifest.pieces missing or empty, Axis A/B/C messages, coverage_proof…, manifest_digest is not 32-hex).
  • Hardening: Axis A now pre-checks source_position is a non-negative-integer string before casting; if any piece has a missing or malformed source_position, it emits "Axis A: source_position missing or non-integer on at least one piece" instead of raising in (p->>'source_position')::int.
  • Hardening: Axis B now also rejects empty/whitespace piece_role and section_type (previously only IS NULL).
  • Preserved: lifecycle/approval guards, dot_iu_command_run audit insert, manifest_digest 32-hex check, coverage_proof.covered_bytes = manifest.source_bytes check, signature and return shape.

Fix 2 + 3 — fn_cut_mark_staged_file

before after
md5 0a6feadddc8f70efe5c35d6b252167d2 67721b42a55315858e3c377654c2a5b1

Patch summary

  • Schema gate (Fix 2): per-piece validation block now enforces cut_manifest_piece_schema_v1 BEFORE any state transition. New checks: local_piece_id non-empty + unique-within-manifest, source_position integer-like and >= 1, piece_role non-empty, section_type non-empty AND present in public.dot_config as vocab.section_type.<value>. Existing mig 053 checks (content_text, canonical_address) preserved.
  • Re-mark path (Fix 3): status precondition relaxed from = 'copied' to IN ('copied','mark_rejected'). Both transitions remain → mark_in_progress → marked, both legal under fn_cut_request_transition state machine.
  • Idempotency: p_idempotency_key now includes md5(p_pieces::text) so a re-mark with different pieces yields a fresh manifest record (no idempotent reuse of stale manifest).
  • Forensics: result JSON now returns piece_schema_validated: 'cut_manifest_piece_schema_v1'; transition metadata stamps piece_schema='cut_manifest_piece_schema_v1' and from_status_was=<prior status>.
  • Unchanged: source_copy read path, alias call (fn_iu_op_mark_file body md5 ffaa47fff7a906d93060141661080cd4 untouched), cut_request_signal('cut.mark', …), signature, return-shape additive only.

Refusal messages (operator-readable)

fn_cut_mark_staged_file: piece[%].local_piece_id is required (cut_manifest_piece_schema_v1)
fn_cut_mark_staged_file: piece[%].local_piece_id % is duplicated (cut_manifest_piece_schema_v1)
fn_cut_mark_staged_file: piece[%].content_text is required (would cause "body required" at CUT)
fn_cut_mark_staged_file: piece[%].canonical_address is required (cut_manifest_piece_schema_v1)
fn_cut_mark_staged_file: piece[%].source_position must be a non-negative integer (cut_manifest_piece_schema_v1)
fn_cut_mark_staged_file: piece[%].source_position must be >= 1 (got %) (cut_manifest_piece_schema_v1)
fn_cut_mark_staged_file: piece[%].piece_role is required (cut_manifest_piece_schema_v1)
fn_cut_mark_staged_file: piece[%].section_type is required (cut_manifest_piece_schema_v1)
fn_cut_mark_staged_file: piece[%].section_type % not in dot_config vocab.section_type.* (cut_manifest_piece_schema_v1)
fn_cut_mark_staged_file: cannot mark from status % — must be 'copied' or 'mark_rejected' (re-mark path)

Rollback

-- Restores prior bodies; preserved in /tmp/mig_054_*.sql diff against pg_proc bodies
-- captured pre-apply with md5 923263c8… (verify) and 0a6feadd… (mark).
-- Single TX: BEGIN; CREATE OR REPLACE … (paste prior bodies) … ; COMMIT;

The prior bodies are reproducible from the pre-fix pg_dump (/tmp/pre_dieu39_verify_mark_fix_20260527_094407.dump) via pg_restore --schema-only and selection of the two function definitions.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-cut-dieu39-verify-mark-root-cause-and-contract-fix/04-function-fixes.md