KB-2367

03 — Count-Integrity Read-Only Rehearsal (Branch C)

6 min read Revision 1
registries-pivotcount-integritybranch-cinvariantdrifthidden-driftpivot-missingFAILED2026-05-31verified

title: 03 — Count-Integrity Read-Only Rehearsal (Branch C) date: 2026-05-31 count_integrity_status: FAILED (leaf-scoped, small + explainable) + DEEPER FAILURE (most leaves have no live-pivot anchor) mutation: none (read-only SELECT only)

03 — Count-Integrity Read-Only Rehearsal (Branch C)

All numbers below are read-only query_pg results, leaf-scoped per doc 02, cross-checked against the BEGIN..ROLLBACK view in doc 04.

A. Leaf-scoped invariant (160 rows)

metric leaf-scoped (doc-05 unscoped, all 169)
rows 160 169
Σ record_count (counted) 1,954,686 3,638,356
Σ actual_count 1,917,903 3,838,798
Σ orphan_count 0 161
net_gap (record−actual) +36,783 +200,442
drift rows (record≠actual) 3 10
phantom-side (record>actual) 2 7
orphan-side (actual>record) 1 3
phantom magnitude 36,798
orphan magnitude 15
actual_count NULL 5

Leaf-scoping removes 7 rollup-driven drift rows and ~163k of phantom noise. Critically, Σ orphan_count = 0 over leaves — all 161 orphans live on the three excluded meta rows (CAT-DOT 140, CAT-COL 20, CAT-SPE 1). So at the leaf level the system is not orphan-failing; the orphan signal is a registry-rollup property.

count_integrity_status = FAILED (3 leaf drift rows ≠ 0). Pivots reproduce exactly: pivot_count('PIV-001')=169, ('PIV-019')=980,378, ('PIV-007')=309.

B. The 3 leaf drift rows — each explained, each with a DIFFERENT cause

code source record actual gap model true cause recommended action
CAT-023 birth_registry 980,378 943,726 +36,652 A record_count = live pivot (PIV-019=980,378 ✓); actual_count is the stale field. NOT phantom. reconcile: re-run the actual scan; align to pivot
CAT-006 dot_tools / File:dot/bin/ 309 163 +146 B record_count = live (PIV-007=309 ✓); actual_count=163 = file-backed count → 146 registry rows lack a backing file = genuine phantom/orphan (≈ CAT-DOT orphan 140) classify orphan/phantom; reconcile CAT-006↔CAT-DOT to one canonical CAT
CAT-007 ui_pages / File:web/pages/ 37 52 −15 B 37 registered pages but 52 real page files → 15 UNREGISTERED (orphan-side) investigate/register the 15 unregistered pages

Finding: the phantom direction is model-dependent. For model-A (Directus DB-backed) rows, record_count tracks the live pivot and actual_count is the stale snapshot → a record>actual surplus is stale-scan noise, not phantom. For model-B (File-backed) rows, record>actual can be genuine phantom (registry rows with no file). The proposed operational phantom def therefore cannot be applied uniformly (doc 08).

C. HIDDEN DRIFT — the failure a record-vs-actual check cannot see

A check that compares record_count vs actual_count reports these leaves as clean because both fields are equal — yet both are stale vs the live table:

code source stored (record=actual) live count hidden drift
CAT-068 entity_labels 690,341 718,744 +28,403
CAT-017 system_issue 171,939 179,074 +7,135

These are large, growing, append-only tables with no dedicated pivot refreshing their meta_catalog row. The only check that catches them is stored vs live pivot_count — which requires a per-leaf pivot. Most leaves have none → PIVOT_MISSING → silent drift.

Two-tier integrity truth:

  1. Tier-1 (record vs actual, in-catalog): 3 leaf drift rows. FAILED-small.
  2. Tier-2 (record vs live pivot): only ~13–25 of 160 leaves are pivot-anchored (doc 04/05); the rest cannot be self-verified and drift silently (CAT-068, CAT-017 proven). This is the real failure and the reason the design insists every count be pivot-backed or PIVOT_MISSING.
row classification action
CAT-023 stale actual_count (not phantom) reconcile actual scan; record already = pivot
CAT-006 phantom/orphan (model-B file gap) classify orphan; reconcile CAT-006↔CAT-DOT; one pivot (PIV-007)
CAT-007 unregistered (orphan-side) register 15 pages; recount
CAT-068 hidden drift (no pivot) create missing pivot (entity_labels total → PIV-31x) then refresh meta_catalog
CAT-017 hidden drift (no pivot) create missing pivot (system_issues total) then refresh
5 leaves w/ NULL actual unverified run actual scan

E. PIVOT_MISSING ledger (confirmed live — must become pivot_definitions rows, never Nuxt math)

  • PIV-500 grand-total / total_system_objectsno canonical total exists; four disagreeing totals live (doc 09).
  • PIV-30x orphan-total / phantom-total / drift-total (orphan_count is per-row only; no rollup pivot).
  • PIV-31x label-by-facet (entity_labels 718,744 uncounted by any pivot) — also the anchor that would catch the CAT-068 hidden drift.
  • system_issues total (would catch CAT-017 hidden drift).
  • PIV-32x registry_pin (after the NEW table is born).
  • IU 219 / KG 2,259 totals (PIVOT_MISSING).

F. Status

count_integrity_status = FAILED. The failure is honest and small at the leaf level (3 rows, all explained) but systemic at the pivot-coverage level (most leaves un-anchored). Recommended P0 outcome: accept the leaf rule + the two-tier truth, then create the missing pivots (M2) before any "green" can be claimed.

Back to Knowledge Hub knowledge/dev/reports/architecture/registries-pivot-p0-p1-count-integrity-view-rehearsal-2026-05-31/03-count-integrity-rehearsal.md