KB-6F84

dot-iu-cutter v0.2 — P0-5 decision_backlog_history Design (2026-05-16)

6 min read Revision 1
dot-iu-cutterdieu44v0.2p0-5-remainderdecision-backlog-historydesignno-ddl

dot-iu-cutter v0.2 — P0-5 decision_backlog_history Design

document_path: knowledge/dev/laws/dieu44-trien-khai/v0.2-design/dot-iu-cutter-v0.2-p0-5-decision-backlog-history-design-2026-05-16.md
revision: r1
date: 2026-05-16
author: Agent (Claude Code CLI, Opus 4.7 1M)
verifier: GPT (PENDING)
phase: v0.2 — P0-5-remainder decision_backlog_history DESIGN (LOGICAL ONLY; no DDL)
master: dot-iu-cutter-v0.2-p0-6-p0-5-remainder-batch-design-master-2026-05-16.md
v0.1_predecessor: migration-design/dot-iu-cutter-v0.1-p0-5-decision-backlog-entry-migration-design-2026-05-15.md §4.2
mutation_performed: false
ddl_written: false

§1 — Purpose

decision_backlog_history is the version trail for decision_backlog_entry (Đ38 manifest-as-code discipline): every create / status change / field update / closure / re-open / supersede on a backlog entry produces an immutable history row. In v0.1 it was specified as a P0-5 companion; in v0.2 its parent (decision_backlog_entry) is already LIVE & empty as a v0.1 table — so this is a pure additive empty-table design into cutter_governance.

§2 — Source Design References

  • v0.1 P0-5 migration design §4.2 (fields baseline) — schema-placement OPEN item is now resolved to cutter_governance (batch master §6).
  • D5 §4.7 (diffability/versioning); G-2 closure §5.3–§5.5; Đ38 versioning discipline.

§3 — Logical Object / Table Intent

primary_table: cutter_governance.decision_backlog_history
becomes: cutter_governance table #10 (post-create, gated; design only now)
target_schema: cutter_governance   # resolved (batch master §6)
target_layer: Lớp KHO (registry trail; co-located with its live parent)
authority_pattern: PG = SSOT; KB mirror only

§4 — Proposed Fields (conceptual — NO DDL)

Field Type-class Nullable Notes
history_id uuid NO history row identifier
decision_id in-schema FK → decision_backlog_entry NO parent entry (LIVE)
entry_version_before text semver YES null for create event
entry_version_after text semver NO resulting version after change
change_kind enum-ref NO create / status_change / field_update / closure / re_open / supersede
change_diff JSONB (intent) YES field-level delta for field_update; app-layer shape (no PG json-schema)
changed_by text actor NO actor performing change
changed_at timestamptz NO when
rationale text YES human-readable change rationale

§5 — Field Ownership / Vocabulary Dependency

Field Owner v0.2 note
change_kind enum cutter-local DBH-2 — Đ24 confirm or accept cutter-local
change_diff JSONB cutter-local intent app-layer only in v0.2

§6 — Lifecycle

Append-only. History rows are never updated or deleted (immutable trail per Đ38). A create event has entry_version_before = null. Granularity is governed by DBH-1 (lean: status/version changes + critical-field updates — owner_role, risk_class, next_review_date; fine-grained per-field logging deferred).

§7 — Relationship to Live v0.1 / Phase α / P0-2 Objects

v0.1 decision_backlog_entry (LIVE, empty):
  - parent; decision_backlog_history.decision_id → decision_backlog_entry (in-schema FK)
  - NO column / trigger added to decision_backlog_entry by this design
  - history is written by the application/P1 write path, not by a PG trigger in P0-5
Phase α objects: NONE (no relationship)
P0-2 objects: NONE (no relationship)
public.* : NO FK, no reference
no_existing_live_table_modified: TRUE

§8 — FK Policy (this table)

in_schema_FK:
  - decision_id -> decision_backlog_entry   (tight parent-child, same family, same schema)
soft_uuid: none
no_cross_schema_FK: TRUE
rationale: parent-child within the SAME registry family + both in cutter_governance →
  in-schema FK is the correct integrity guarantee (mirrors P0-2 block→envelope pattern).

§9 — Empty-at-Create & Rollback Posture

empty_at_create: TRUE — 0 rows; NO backfill of historical entry changes (P1/operational)
rollback: DROP TABLE decision_backlog_history (empty) → cutter_governance to its pre-state
data_loss_on_rollback: NONE at create-time
deferred_concern: AFTER P1 backfill, history-preservation-across-rollback becomes
  HIGH-severity (v0.1 §10) — flagged for Đ32 attention; NOT a create-time risk

§10 — Đ32 Risk Class (estimate)

STANDARD (estimate). Additive empty table; single in-schema FK; no live-table touch; append-only; no data mutation. Full surface table: File 6.

§11 — Open Decisions (registration only; Agent does NOT self-close)

  • DBH-1 history granularity: status/version + critical fields (lean) vs every-field. Owner GPT.
  • DBH-2 change_kind enum ownership: cutter-local v0.2 (lean) vs Đ24. Owner Đ24 + GPT.
  • BATCH-1 enum implementation strategy (shared). Owner Đ24 + GPT.

All block DDL freeze; NONE block this design review.

§12 — Dependencies

upstream (SATISFIED — LIVE): decision_backlog_entry (v0.1 LIVE, empty); Đ38 versioning
downstream: decision_backlog_sweep_log reads history for re-surface metrics;
            KB mirror regenerator (P1) reads history
no_new_parent_table_required: TRUE

§13 — Explicit Confirmation

no_ddl_written: true
no_sql_written: true
no_create_or_alter_table: true
no_column_or_index_or_constraint_ddl: true
no_trigger_or_function_or_rls_policy: true
no_migration_executed: true
no_pg_mutation: true
no_data_writes: true
no_backfill: true
no_existing_file_or_table_modified: true
open_decision_self_closed: false
output_form: logical_design_only

End of P0-5 decision_backlog_history design.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.2-design/dot-iu-cutter-v0.2-p0-5-decision-backlog-history-design-2026-05-16.md