KB-49F7

Next Pack — Điều 39 Retry Plan

6 min read Revision 1
iu-cutdieu39retrynext-packcomposer-gatephantom-cut-state

Phase H — Next pack: IU_CUT_DIEU39_RETRY (DRY-RUN-FIRST)

Current Điều 39 state (as left by this macro)

field value note
cut_request_id c7133284-a579-4266-aed8-c91f75a22283 unchanged
status cut_failed terminal per state machine (no legal exit)
cut_run_id c42ebc50-20eb-459e-9099-eb46638f63b1 LEGACY phantom — pre-fix bug audit
cut_done_at 2026-05-27 05:45:54.928814+00 LEGACY phantom — pre-fix bug audit
cut_verified_at NULL
completed_at NULL
mark_verdict approved
manifest 5ef349ac… lifecycle_status approved not consumed (no IU created)
iu_dieu39_count 0
ready_for_cut_now (live preflight) false composer gate closed

Blocker — state-machine carry-forward (parent CF-1 of mig 054)

cut_failed is a terminal state in fn_cut_request_transition:

WHEN 'cut_failed' THEN ARRAY[]::text[]

There is no legal cut_failed → ? exit. To retry, we need either:

Option A (preferred) — add a recovery transition

Extend the state machine with cut_failed → marked (or cut_failed → mark_verified) gated on:

  • mark_approval_doc_id still present (audit chain),
  • cut_run_id and cut_done_at cleared (no phantom state inherited),
  • explicit audit_reason in metadata.

This belongs to the next macro IU_CUT_STATE_MACHINE_ROLLBACK_AFTER_APPROVAL_POLICY (already named in [[project_iu_cut_cut_readiness_gate_pass_2026_05_27]] CF-1 and [[project_iu_cut_dieu39_unit_kind_root_cause_and_contract_fix_partial_2026_05_27]] CF-1) — same family.

Option B — fresh cut_request for the same source_ref

Create a new cut_request for knowledge/dev/laws/dieu39-knowledge-graph-law.md. The old request remains as an audit artefact (status=cut_failed with phantom cut_done_at). New request flows REQUEST → COPY → MARK → VERIFY → APPROVE → CUT cleanly because manifest cross-binding (mig 056) and E8 composer gate are now enforced.

Either option requires opening the composer gate intentionally before the CUT step:

UPDATE public.dot_config SET value='true', updated_at=now()
  WHERE key='iu_core.composer_enabled';
  1. Pre-flight: confirm preflight E8 reads composer_enabled=true live.
  2. Phantom-state cleanup (CF-1 of THIS macro): write fn_cut_request_clear_phantom_cut_state(p_cut_request_id) to NULL cut_run_id + cut_done_at on the legacy cut_failed row — purely for audit hygiene, optional.
  3. New cut_request:
    SELECT public.fn_cut_request_add('knowledge/dev/laws/dieu39-knowledge-graph-law.md', 'law', 'codex_dieu39_retry_<date>');
    
  4. Copy zone via lo_export + chown + pg_read_file per [[feedback_iu_cut_copy_to_zone_lo_export_pg_read_file_pattern]].
  5. fn_cut_copy_to_staging → cut_request becomes copied.
  6. MARK via fn_iu_op_mark_file with 7-field per-piece schema per [[feedback_cut_manifest_piece_schema_v1_now_7_field_unit_kind_required_in_dot_config_vocab]]:
    • local_piece_id non-empty + unique
    • content_text non-empty
    • canonical_address non-empty
    • source_position ^[0-9]+$ ≥ 1
    • piece_role non-empty
    • section_typevocab.section_type.*
    • unit_kindvocab.unit_kind.* (use law_unit, NOT law_section)
  7. VERIFY (dry-run) via fn_cut_verify_mark(p_approve=false) — expect mark_valid=true, cut_readiness_ok=true, e8_composer_ok=true.
  8. APPROVE via fn_cut_verify_mark(p_approve=true, doc, approver) — expect verdict=approved, status=mark_verified. APPROVE will perform cut_request cross-binding (mig 056) AND re-run preflight.
  9. CUT via fn_cut_apply(cut_request_id, true, actor) — expect verdict=applied, status=cut_done, cut_run_id non-NULL, pieces_created_count=16. Preflight re-runs immediately before CUT (mig 056).
  10. VERIFY_CUT via fn_cut_verify_cut(...) — manifest axes A/B/C + no_vector_ok.
  11. COMPLETE via fn_cut_complete(...).

Strict non-goals for the retry macro

  • No vocab widening.
  • No silent unit_kind mapping (law_section → law_unit is REJECTED).
  • No alias body rewrite.
  • No Qdrant writes (still excluded; vector_excluded=true).
  • No production_documents creation.
  • No pg_cron / broad worker.

Gates to flip & restore (retry macro)

key from to (during) restore to
iu_core.composer_enabled false true false (after CUT proven) OR keep open if §15.5 closure is part of next macro
queue.job_substrate.enabled false unchanged false
queue.heartbeat.enabled true unchanged true
  • [[project_iu_cut_verify_mark_cut_readiness_gate_pass_2026_05_27]] (mig 055 — preflight + verify delegation, the foundation for E0..E7)
  • [[project_iu_cut_dieu39_unit_kind_root_cause_and_contract_fix_partial_2026_05_27]] (mig 054 — Axis D unit_kind)
  • [[project_iu_cut_dieu39_verify_mark_root_cause_and_contract_fix_pass_2026_05_27]] (mig 054 — 6→7-field piece schema)
  • [[project_iu_cut_operational_pipeline_runtime_hardening_pass_2026_05_27]] (mig 053 — heartbeat + cleanup)
  • [[project_iu_cut_operational_pipeline_copy_mark_verify_cut_pass_2026_05_26]] (mig 052 — pipeline foundation)
Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-cut-verify-approve-cut-gate-consistency-fix/07-next-dieu39-retry-plan.md