dot-iu-cutter v0.1 — P0-5 decision_backlog_entry Migration Design
dot-iu-cutter v0.1 — P0-5 decision_backlog_entry Migration Design
Date: 2026-05-15 Status: P0 MIGRATION DESIGN — Item 1 of 6 (foundational; topologically root) Scope: DESIGN ONLY. No DDL, no SQL, no CREATE/ALTER TABLE, no column DDL, no migration execution, no PG mutation. Master:
migration-design/dot-iu-cutter-v0.1-p0-migration-design-master-2026-05-15.md
1. Purpose
P0-5 establishes the persistent SSOT for the Decision Backlog Registry — the anti-forgetting infrastructure (D5 §4.11). This is the foundational P0 item: until P0-5 exists in PG, all governance entries (gaps, decisions, escalations, vocabulary requests, threshold tunes) live only as KB markdown closure files. After P0-5 ships, those markdown files become regenerable mirrors and PG becomes the authoritative store.
2. Source Design References
- D5 Decision Backlog Registry Design — §4.1 (SSOT in directus, Lớp KHO), §4.2 (entry envelope), §4.3 (lifecycle), §4.4 (sweep cadence), §4.5 (routing), §4.7 (diffability/versioning), §4.8 (markdown mirror), §4.10 (closure criteria), §4.11 (anti-forgetting), §5 (PG storage table), §6 (schema gaps), §8 (open questions).
- G-2 closure §5.1 (lifecycle), §5.2 (sweep), §5.3 (schema gap tracking), §5.4 (governance gap tracking), §5.5 (User decision tracking), §5.6 (review cadence), §5.7 (report generation).
- Đ44 Step 3 outcome —
governance_eventumbrella acceptsdecision_backlog_entryas a P0 sub-kind. - Đ24 Step 1 ratified —
risk_class(Standard ratified), event-kind P0 subset. - User Decision Confirmation §4.4 — Decision 4: cutter-only scope.
3. Logical Object / Table Intent
Primary table: decision_backlog_entry
Companion tables:
decision_backlog_history(version trail per Đ38 manifest-as-code discipline)decision_backlog_dependency(entry-to-entry directed graph)decision_backlog_sweep_log(sweep audit trail per G-2 §5.7)
Target DB: directus (existing). Target Schema: new schema class for governance artifacts OR reuse existing TAC schema — open decision (§9 below). Target Layer: Lớp KHO (per D5 §4.1; this is binding — not Não, not generic Kho).
Authority pattern: PG = SSOT. KB markdown mirror at knowledge/dev/laws/dieu44-trien-khai/registry/ is regenerated on every sweep.
4. Proposed Fields at Conceptual Level
4.1 decision_backlog_entry
| Field name | Type-class | Nullable | Notes |
|---|---|---|---|
decision_id |
text identifier | NO | deterministic ID; format proposal: DBE-<YYYYMMDD>-<seq> OR uuid (open decision §9) |
decision_id_human |
text | YES | optional human-readable alias (e.g. G-2, P0-5) for cross-link with closure files |
date_discussed |
date | NO | when raised; absolute date per memory convention |
summary |
text | NO | one-line description per D5 §4.2 |
status |
enum-ref | NO | values: proposed / open / in_review / resolved / deferred / superseded / re_opened per D5 §4.3 |
kind |
enum-ref | NO | values: gap / decision / threshold_tune / vocabulary_request / escalation / open_question per D5 §4.2 |
risk_class |
enum-ref | NO | low / standard / high per Đ24/Đ32 Step 1 |
priority |
enum-ref | YES | P0 / P1 / P2 / P3 per D8 §6 gap categorization (G-2 §5.3); only applicable when kind = gap |
owner_role |
enum-ref OR text | NO | Đ37 role identifier (e.g. Registry Custodian, Threading Domain Owner, Access Control Authority); shape decision §9 |
owner_seat |
text | YES | named occupant placeholder (currently TBD-*); future operational seat name |
source_discussion |
text | YES | reference to manifest_id / closure file path / health signal ref that surfaced this entry |
related_law_or_design |
text | YES | references to laws (Đ24, Đ32, Đ37, …) or design files |
next_review_date |
date | YES | re-surface date (D5 §4.4 anti-forgetting) |
dependencies |
(junction; see decision_backlog_dependency) |
— | foreign-edge table for entry-to-entry deps |
closure_rationale |
text | YES | populated when status = resolved; required by D5 §4.10 |
closure_evidence |
JSONB | YES | structured evidence at closure (per Đ44 outcome A.6 #3) |
entry_version |
text (semver) | NO | per Đ38 versioning; e.g. 1.0.0 |
emitted_by |
text actor reference | NO | producer (D1/D2/D3/D4/D5/D9/D11) |
emitted_at |
timestamp UTC | NO | creation time |
updated_at |
timestamp UTC | NO | last modification |
tool_revision |
text | YES | cutter revision at creation per D4 §4.6 |
4.2 decision_backlog_history
| Field name | Type-class | Nullable | Notes |
|---|---|---|---|
history_id |
bigserial OR uuid (open decision §9) | NO | history row identifier |
decision_id |
FK ref to decision_backlog_entry |
NO | parent entry |
entry_version_before |
text semver | YES | for create event this is null |
entry_version_after |
text semver | NO | resulting version after this change |
change_kind |
enum-ref | NO | values: create / status_change / field_update / closure / re_open / supersede |
change_diff |
JSONB | YES | field-level delta for field_update |
changed_by |
text actor | NO | actor performing change |
changed_at |
timestamp UTC | NO | when |
rationale |
text | YES | human-readable change rationale |
4.3 decision_backlog_dependency
| Field name | Type-class | Nullable | Notes |
|---|---|---|---|
dependency_id |
bigserial OR uuid | NO | edge identifier |
from_decision_id |
FK ref | NO | source of dependency edge |
to_decision_id |
FK ref | NO | target of dependency edge |
dependency_kind |
enum-ref | NO | values: blocks / supersedes / refines / related_to |
created_at |
timestamp UTC | NO | |
created_by |
text actor | NO |
4.4 decision_backlog_sweep_log
| Field name | Type-class | Nullable | Notes |
|---|---|---|---|
sweep_id |
bigserial OR uuid | NO | per-sweep identifier |
swept_at |
timestamp UTC | NO | sweep start time |
swept_by |
text actor | NO | Registry Custodian (or deputy) |
trigger_kind |
enum-ref | NO | values: scheduled / governance_review / health_report / self_review / ad_hoc |
entries_evaluated_count |
integer | NO | how many entries this sweep evaluated |
entries_re_surfaced_count |
integer | NO | how many past-due entries re-surfaced |
escalations_routed_count |
integer | NO | how many entries routed for escalation this sweep |
mirror_regenerated_at |
timestamp UTC | YES | when markdown mirror was regenerated |
mirror_path |
text | YES | path to mirror artifact at this sweep |
findings |
JSONB | YES | sweep-level structured findings |
5. Field Ownership / Vocabulary Dependency
| Field | Vocabulary owner |
|---|---|
status enum |
Đ24 (Step 1 needs to ratify; if not yet, propose to Đ24 group 1 umbrella sub-enum) — open decision §9 |
kind enum |
Đ24 (Step 1) — ratified via group 11 P0 subset extension |
risk_class enum |
Đ24 Step 1 + Đ32 cross-law (ratified [low, standard, high]) |
priority enum |
cutter-local (P0/P1/P2/P3 is design-phase taxonomy, not Đ24); recommend stay cutter-local OR Đ24 confirm |
owner_role enum |
Đ37 SOP roles (Registry Custodian, Threading Domain Owner, Access Control Authority, TAC Reviewer, KG Reviewer, DOT Registry Custodian — all per Council Ratification Outcome) |
change_kind enum (history) |
cutter-local (Đ38 manifest-as-code style; recommend Đ24 confirm or accept cutter-local) |
trigger_kind enum (sweep) |
cutter-local (per G-2 §5.2 triggers) |
dependency_kind enum |
cutter-local (per Đ44 G3 relations group) |
6. Lifecycle
proposed
↓
open
↓
in_review
↓
├──→ resolved (terminal unless re-opened)
├──→ deferred (with next_review_date set; re-surfaces via sweep)
└──→ superseded (with FK to replacing entry via dependency_kind='supersedes')
re_opened ← from resolved if new evidence (creates new entry version; history records `re_open`)
State transitions are recorded in decision_backlog_history per Đ38 versioning.
Sweep cadence per Council Ratification Outcome G-2 §5.1:
- Default every 7 calendar days.
- Triggered additionally by Đ37 governance review, D3 Segmentation Health Report, D4 Cutter Self-Review.
- Ad-hoc on user/council request.
7. Dependencies
upstream_dependencies:
governance_ratifications:
- Council Ratification Outcome G-2 (Backlog Custodian) — ratified_with_notes
- Đ44 governance_event umbrella ratification (Step 3) — ratified_with_notes
- Đ24 Step 1 ratifications for status/kind/risk_class enums
no_data_dependencies: this is foundational; no other P0 item must exist first
downstream_dependents:
- P0-1 canonical_address: any open decisions logged here
- P0-2 manifest_envelope: vocabulary gaps + schema gaps logged here
- P0-6 review_decision: review escalations logged here
- P0-3 cut_change_set: rollback events + DOT-pair drift signals logged here
- P0-4 verify_result: verify failures + NEEDS_HUMAN escalations logged here
- all health/retrieval signals (D3 §4.2, D9 §4.8, D11 §4.9) — route here
operational_dependencies:
- Registry Custodian (G-2) seat naming (future operational phase)
- Markdown mirror generator (G-2 §5.7) — implementation is FUTURE
8. Risks
| Risk | Severity | Mitigation in this design |
|---|---|---|
| Bootstrap chicken-and-egg: backlog entry tracking the closure of backlog itself doesn't exist yet | Standard | KB closure files serve as temporary SSOT until P0-5 lands; backfill plan at migration execution time |
| Markdown mirror drift from PG | Standard | sweep_log records mirror_regenerated_at; drift is observable |
Cycle in decision_backlog_dependency graph |
Standard | open decision §9 item 5 |
owner_role enum drift if Đ37 SOP changes mid-cycle |
Standard | history table records changes; Đ32 review at migration time |
| Closure rationale missing on resolved entries | Standard | application-layer enforcement (D5 §4.10); FUTURE constraint design |
| Schema gap routing volume overwhelms custodian | Low (v0.1) | sweep cadence + batching; cadence tunable via D4 capability intake |
closure_evidence JSONB grows unbounded |
Standard | size cap policy is FUTURE; design records JSONB acceptance per Đ44 A.6 #3 |
| Cross-DOT federation (deferred per Decision 4) | Low (v0.1) | scope is cutter-only; federation upgrade via FUTURE D4 capability intake |
9. Open Decisions
These remain open for resolution during Đ32 review or before migration execution:
- Schema placement — new schema class for governance artifacts OR reuse existing TAC schema? Recommendation: new schema class (e.g.
gov) to avoid TAC pollution; Đ44 + Đ33/Đ43 confirm. - Primary ID form — text identifier with deterministic pattern (
DBE-YYYYMMDD-seq) OR bigserial OR uuid. Recommendation: uuid for global uniqueness; human-readable alias viadecision_id_human. statusandkindenum implementation — PG enum type OR FK to Đ24-controlled lookup table OR PG check-constraint. Recommendation: FK to Đ24 lookup table for vocabulary discipline.owner_roleshape — enum FK (rigid) vs text identifier (flexible). Recommendation: FK to Đ37 role table (or its proxy); cross-link G-1/G-3/G-4/G-5 closures.- Dependency graph cycle detection — PG-level (recursive CTE check at insert) OR application-level. Recommendation: application-level enforcement v0.1; PG-level via trigger is FUTURE.
priorityfield — keep cutter-local OR ratify to Đ24. Recommendation: cutter-local for v0.1; revisit at Đ24 group 1 extension.closure_evidenceJSONB schema — formal JSONB schema validation (PGjsonb_check) OR application-level only. Recommendation: application-level v0.1.- Markdown mirror generator location — batch job in directus flow OR external script OR sweep-triggered. Recommendation: sweep-triggered batch; implementation FUTURE.
re_openedstate — distinct status OR sub-state ofopen. Recommendation: distinct status to preserve history clarity.- History granularity — every field update OR only status/version changes. Recommendation: status/version + critical field updates (owner_role, risk_class, next_review_date); fine-grained logging FUTURE.
10. Đ32 Risk Review Notes
proposed_risk_class: Standard
review_inputs_for_dieu32:
- logical design content (this document)
- downstream impact (all other P0 items + governance closures depend on this)
- rollback implications: P0-5 itself rolling back deletes governance trail — must NOT lose history
- data exposure surface: owner_seat may contain PII (named occupants); access-control class needed
- migration execution preconditions:
- backup directus database before migration
- migration window: low-traffic period
- bootstrap data plan: backfill from KB closure files into PG SSOT
- mirror generator readiness: NOT required at migration time; can be FUTURE
review_outputs_expected:
- Đ32 approval / approval_with_notes
- residual-risk register entries (if any)
- migration execution preconditions confirmed
review_authority: Đ32 council quorum + Registry Custodian (Đ37) co-sign per Council Ratification Outcome G-2 §4.1
review_phase: NOT_STARTED (begins after this design document is reviewed by GPT)
Special Đ32 attention points:
- History preservation across rollback — if migration rolls back,
decision_backlog_historymust survive (or be reproducible from KB closures). Loss of governance trail is a HIGH-severity event even though P0-5 itself is Standard risk. owner_seatPII handling — if names of human seats are stored, audience-scope policy from G-5 applies (employee-internal). Đ32 confirm.- Markdown mirror access — mirror path
knowledge/dev/laws/dieu44-trien-khai/registry/is internal-only by default per Decision 3.
11. Explicit Confirmation
no_ddl_written: true
no_sql_written: true
no_create_table_in_this_document: true
no_alter_table_in_this_document: true
no_column_ddl_in_this_document: true
no_index_ddl: true
no_constraint_ddl: true
no_trigger_or_function_or_rls_policy_written: true
no_migration_executed: true
no_pg_mutation: true
no_qdrant_mutation: true
no_data_writes: true
no_implementation_planning: true
no_existing_file_modified: true
output_form: logical_design_only
This document is a logical migration design. Any DDL/SQL/migration content is OUT OF SCOPE for this document and for this phase.