03 — Count-Integrity Read-Only Rehearsal (Branch C)
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:
- Tier-1 (record vs actual, in-catalog): 3 leaf drift rows. FAILED-small.
- 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.
D. Drift table → recommended action (Branch C deliverable)
| 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_objects— no 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_labels718,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.