08 — Reuse-First Rebuild Blueprint (VERIFIED v2)
08 — Reuse-First Rebuild Blueprint (VERIFIED v2)
Thesis: the foundation exists. "Rebuild" = reconcile counting to a single pivot truth + consolidate the two pages onto the clean render-shell. No new engine. All steps are DESIGN — none applied this session; every PG change is additive/reversible and Đ32/Đ30-gated.
Invariants (Đ26/Đ28/Atom Law/P3D)
- PG is the source of count truth —
pivot_definitions/pivot_results/pivot_count()are canonical (verified: 37 defs, PIV-007=309 fresh). - meta_catalog = list of lists, NO numbers (Đ26 MT5) — today 164/169 rows store numbers; that is the breach to undo.
- Nuxt = render shell only (Đ28) — no business/count logic, no hardcoded rows/arrays.
- New list/species/layer = a DATA ROW.
Target flow
source tables (dot_tools, collection_registry, birth_registry, ui_pages, …)
│ read live (MT7)
▼
pivot_definitions ─run─▶ pivot_count() / refresh_pivot_results() ─▶ pivot_results (metric_values, refreshed_at)
│
└─ refresh_meta_catalog_from_pivot() ─▶ meta_catalog (list-of-lists; numbers READ from pivot, not stored)
│
Directus REST ─▶ Nuxt render shell (display only)
Reconciliation steps (design order; reversible)
R1 — Single count writer. Make refresh_meta_catalog_from_pivot() the ONLY writer of meta_catalog numbers; stop the competing writers (trg_auto_sync_registry_counts on meta_catalog, refresh_registry_count(s)()) from setting independent counts. Resolves V1/V4/V5.
R2 — Deduplicate DOT. Collapse CAT-006 + CAT-DOT → one canonical CAT bound to PIV-007 (already live=309); drop the stale 307 and the broken actual_count 163. Resolves V2.
R3 — Reconcile record≠actual rows. For the 7 rows where record_count ≠ actual_count (CAT-006, CAT-007 37↔52, +5) bind each to its pivot and recompute; add a read-only test_counting_contract() (total ≤ count(*) of source_object; grouped sums == total). Resolves V3. (Retraction: v1's "fix PIV-104 309>219" was based on a false reading — PIV-104 is dot_tools-by-category.)
R4 — Heal & expose freshness. Clear the 3 needs_refresh rows; schedule refresh_pivot_results(); surface refreshed_at in both pages. Resolves V7.
R5 — De-hardcode registries page. Remove the hardcoded phantom rows (CAT-SPE/ORP/PHA/UNM/017 at index.vue:308–322) and the in-page gap math (/api/registry/health totalGap); drive all rows from meta_catalog + pivots. Resolves V6.
R6 — Build the missing 6-layer reference table. composition_levels does NOT exist (doc 06). Build it (atom..building, ordered) so layer groups + dimension selectors read from data instead of a hardcoded array, and clean dirty composition_level values ('meta','1'). Resolves V9 + enables true R5 anti-hardcode.
R7 — Backfill navigability. Set ui_page across meta_catalog (today 18/169) so every list links to a surface + its profile (Đ38/44). Resolves V10.
R8 — Consolidate read path. Standardize on pivot_count(p_code) for reads; treat pivot_query/refresh_registry_count* as internal. Resolves V11.
REUSE verbatim (do not rebuild)
/knowledge/pivotrender-shell + Directuspivot_resultsfetch — the reference pattern.- Pivot engine + the 37 definitions (fix the 2 inactive / the DOT binding).
entity_species,species_collection_map,birth_registry,governance_registry, birth function family — untouched canonical.
Anti-hardcode contract for rebuilt UI
- Layers: from a to-be-built
composition_levelstable (until then, do NOT hardcode the 6 — this is a blocked precondition, R6). - Species:
SELECT * FROM entity_species(flat today; tree when built). - Lists + metadata:
meta_catalog. Numbers: pivot only — every on-screen number carriespivot_code+refreshed_at; a list with no pivot shows "no pivot", never a stored number.
Governance
R1–R8 touching PG (writers, dedupe, new reference table, backfill) are additive/reversible and require human Đ32-class approval per Đ30/Đ31. R5 is a Đ28-gated Nuxt-shell edit. This blueprint is document-only.