KB-53C0
02 CUT-Time Refusal Matrix
5 min read Revision 1
dieu44refusal-matrixpreflightgovernance2026-05-27
02 — CUT-Time Refusal Matrix
Goal: enumerate every condition under which fn_iu_cut_from_manifest + the per-piece fn_iu_create it calls would refuse a manifest, and confirm each one has an upstream check in fn_iu_cut_preflight_validate (so VERIFY_MARK never approves a doomed manifest).
Legend:
- VM(before) — checked by
fn_iu_verify_markmd51db15847(pre-mig 055) - VM(after) — checked via
fn_iu_cut_preflight_validatemd5914e26d6invoked fromfn_iu_verify_markmd5c9c0553f(post-mig 055) - CUT — checked at
fn_iu_cut_from_manifest/fn_iu_createruntime - MARK — checked at
fn_cut_mark_staged_filepercut_manifest_piece_schema_v1(md5e85065ac)
| # | check_name | VM(before) | CUT | MARK | VM(after) | fix_required |
|---|---|---|---|---|---|---|
| 1 | manifest is a non-empty array | YES | implicit | YES | YES | none |
| 2 | source_position dense from 1 (Axis A) | YES | NO | (regex only) | YES | none |
| 3 | piece_role non-empty (Axis B) | YES | NO | YES | YES | none |
| 4 | section_type non-empty (Axis B) | YES | NO | YES | YES | none |
| 5 | section_type ∈ vocab.section_type.* (E1) |
NO | YES (fn_iu_create) | YES | YES | NEW E1 added |
| 6 | parent_local_id resolvable in manifest (Axis C) | YES | RAISES at CUT loop | NO | YES | none |
| 7 | unit_kind non-empty AND ∈ vocab.unit_kind.* (Axis D) |
YES (mig 054) | YES (fn_iu_create) | YES (mig 054) | YES | none |
| 8 | canonical_address non-empty | implicit | YES | YES | E4-adjacent | none |
| 9 | canonical_address collision with existing IU (E2) | NO | YES (fn_iu_classify_existing) |
NO | YES | NEW E2 added |
| 10 | publication_type valid if present (E3) | NO | YES (fn_iu_create, opt) | NO | YES | NEW E3 added |
| 11 | title derivable: COALESCE(NULLIF(split_part(content_text,'\n',1),''), canonical_address) non-empty (E4) |
NO | RAISES at fn_iu_create | implicit | YES | NEW E4 added |
| 12 | local_piece_id non-empty + unique (E5) | NO | implicit (v_local_to_unit) |
YES | YES | NEW E5 added |
| 13 | manifest_digest = ^[0-9a-f]{32}$ (E6) |
YES | YES (G5) | NO | YES | none |
| 14 | coverage_proof.covered_bytes = manifest.source_bytes (E7) | YES | NO | NO | YES | none |
| 15 | source_hash match (E0, optional) | NO | YES (G6, op-supplied) | NO | YES (optional caller arg) | added pass-through |
| 16 | staging_kind = 'mark_manifest' | YES | YES (G2) | YES | YES | none |
| 17 | lifecycle_status pending_review (verify) / approved (cut) | YES (pending_review) | YES (G3, approved) | YES (copied/mark_rejected) | YES (pending_review) | preflight is read-only on any lifecycle |
| 18 | approval completeness: approved_at/by/doc_id NOT NULL | (set at p_apply) | YES (G4) | n/a | (set at p_apply) | none |
| 19 | composer gate enabled (runtime) | NO | YES (G7) | n/a | NO (intentional) | runtime, not contract |
| 20 | actor non-empty | n/a | YES (fn_iu_create) | n/a | (caller-supplied at apply) | none |
| 21 | body non-NULL | n/a | YES (fn_iu_create) | n/a | covered by E4 + content_text non-empty | none |
| 22 | invariant verification (fn_iu_verify_invariants) | n/a | YES (post-insert) | n/a | post-create runtime | none |
Gaps closed by mig 055
Five upstream checks added (E1, E2, E3, E4, E5) — these were the gaps that allowed manifests to reach mark_verified while CUT-time would still refuse. E0/E6/E7 already existed but are now restated in the centralized preflight verdict for forensic clarity.
Conditions intentionally NOT moved upstream
- G7 composer gate — runtime toggle, can flip after approval; gating verify_mark on it would cause spurious rejects.
- Approval completeness — produced by
p_apply=truepath itself. - fn_iu_verify_invariants — post-insert; requires actual IU rows to exist.
Source-of-truth diagram
cut_manifest_piece_schema_v1 (MARK)
+
fn_iu_create boundary checks (CUT)
‖
‖ union
‖
▼
fn_iu_cut_preflight_validate (single read-only verdict)
▲
│
│ delegates
│
fn_iu_verify_mark
▲
│
fn_iu_op_verify_mark (alias, governance-pinned)