KB-2928

04 — normative_registry / law_catalog / KB Drift Analysis

4 min read Revision 1
architecturesecond-passnormative-registrylaw-catalogdriftreconcile

04 — normative_registry / law_catalog / KB Drift Analysis

Three law-record surfaces exist. This doc makes their drift explicit (mission §3/§8).

The three surfaces

Surface Rows Role Authority
normative_registry 47 (45 law + 2 constitution) PG metadata SoT: code/article/version/status/parent_code/kb_path AUTHORITATIVE
law_catalog 5 (dieu26/28/29/30/31) legacy SSOT-pointer (law→ssot_collection→ssot_document) STALE — deprecate
KB markdown (knowledge/dev/laws/*, information_unit law_unit 187) the law text + IU body of record authoritative for text

Drift register (live-verified)

D1 — Enacted laws absent from normative_registry (HIGH)

  • Đ23dot-scanning-system.md enacted/frozen in KB; no NRM row. PG law-queries miss the tam-quyền scanning law.
  • Đ45dieu45-…-law.md v1.0 BAN HÀNH 2026-05-26 (enactment_approved=true, user+council approved); no NRM row. An enacted law invisible to PG.
  • Đ44 — controlled DRAFT v0.1.2; absent is correct (not enacted) but note it WILL need a row on enactment.
  • Impact: any enforcement/scanner that enumerates "active laws" from PG silently under-counts by ≥2. The first pass flagged this; second pass confirms it live and adds Đ45's exact enactment evidence.

D2 — law_catalog is stale AND mislabeled (MEDIUM)

law_code name (LC) version (LC) normative_registry drift
dieu26 Luật Đếm v2.1.1 NRM-LAW-26 v4.0 version 2.1.1 vs 4.0
dieu28 Luật Khai Sinh v1.0 NRM-LAW-28 v2.0 (Display/Nuxt) WRONG LAW — name+ssot describe Đ0-G birth, not article 28
dieu29 Luật Species v1.1 NRM-LAW-29 v2.0 version 1.1 vs 2.0
dieu30 Luật Hồi Quy v1.0 NRM-LAW-30 v1.2 version 1.0 vs 1.2
dieu31 Luật Toàn Vẹn v1.3 NRM-LAW-31 v1.2 version 1.3 vs 1.2 (LC ahead)
  • All 5 rows created/updated 2026-03-24 and never maintained since. 2 of 5 disagree on version, 1 of 5 names the wrong law. Treat as a frozen legacy artifact; do not cite for current law metadata.

D3 — Version currency between KB and NRM (LOW, healthy)

  • Spot-checked: Đ35 (KB v5.2 FINAL = NRM -V5P2), Đ37 (KB v3.3 = NRM v3.3), Đ38/39 (v2.3=v2.3), Đ43 (v1.2=v1.2), HP (v4.6.3=-V4P6P3). KB↔NRM are in sync for enacted laws. The retirement-via-parent_code amendment chain (22/32/33/35/HP) is intact. NRM is a well-maintained SoT — the drift is confined to the legacy law_catalog and the unregistered Đ23/45.

Reconciliation targets (classification in doc 11)

  1. RECONCILE — register Đ23 and Đ45 into normative_registry (enacted, absent) via the Đ38 enactment/approval process. Closes the "law no PG query sees" gap.
  2. DEPRECATE / RECONCILE — retire or rebuild law_catalog (5 rows) against normative_registry; at minimum fix the dieu28 mislabel; preferably mark status='deprecated' and point consumers to normative_registry.
  3. DEFER — Đ44 registration until it is enacted (it is a controlled DRAFT; registering a draft as law would itself be a governance error).
  4. NEW (proven absent) — a count pivot for normative_registry (no PIV today counts the law registry).

Anti-forgetting note

The drift is NOT a discovery gap — the first pass found all three surfaces. The second-pass addition is exactness: law_catalog's dieu28 is not "version drift," it is the wrong law, and Đ45's absence is from an enacted (not draft) law with a dated user approval. Both sharpen the RECONCILE packet's justification.

Back to Knowledge Hub knowledge/dev/reports/architecture/law-capability-discovery-second-pass-cross-check-2026-05-30/04-normative-lawcatalog-drift-analysis.md