09 · UI Architecture Design Review (generic drill renderer, badges, fallback; source UNVERIFIED)
09 · UI Architecture Design Review
Area 9 verdict: PARTIAL — design sound, source UNVERIFIED (P1 for one binding fix).
Source access: UNVERIFIED_SOURCE_ACCESS — this read-only run has no Nuxt git/source access (the UI repo is on contabo, divergent, no push creds; prior runs confirm). Review is of the design/package as described in the drill/grouping checkpoints, not the live source.
1. What the checkpoints describe (the UI package)
ui-package/ui-package-v2under…/rp-dynamic-drill-*-2026-06-05/: genericdrill.vue+ 7 render-model components + 4–7 pass-through API routes (server/api/...returningrpQueryresults verbatim — no business logic in Nuxt).- Assembly-first: PG renders all business logic; Nuxt is the screen (no direct-PG-from-Nuxt; routes are pass-through). This matches the constitutional
PG → Directus → Nuxtrule. - Not deployed:
feat/process-axis-dashboarddivergent (ahead17/behind13), no push creds → operator handoff.
2. Will the UI remain generic? (design assessment)
| Generic-UI requirement | Design status | Risk |
|---|---|---|
| no axis-specific math in Nuxt | PASS (design) — all logic in PG views; routes pass-through | low (verify no creeping .vue math) |
| no hardcoded depth | PASS (design) — drill follows has_children/drill_action recursively |
low |
| no hardcoded routes per axis | AT RISK — next_route comes from PG, but the pass-through routes are bound to specific view names (v_rp_..._v2), not _current |
P1 — see §3 |
| one generic drill renderer | PASS (design) — single drill.vue consuming the contract |
low |
| badges for reliability/governance/source-scope | PARTIAL — v2 package predates the reliability fields; badges for reliability_label/source_scope/warning_flags/gov_sync_state not yet in the renderer |
P1/P2 |
| fallback for a new axis | PASS (design, conditional) — generic renderer + registry-driven _current ⇒ a new axis renders with no UI code (doc 03), once UI binds _current |
depends on §3 |
3. The one binding fix (P1)
The UI package binds versioned view names (v_rp_universal_node_ui_contract / …_v2) via its pass-through routes. Per doc 02, UI must bind …_current exclusively. Until then, the UI shows the stale v1 (the 12 false-affordance nodes) or a frozen v2.
Spec: every RP pass-through API route must SELECT … FROM v_rp_universal_node_ui_contract_current (and …_proof_matrix_current, …_acceptance_dashboard analogues). A grep gate (doc 02 §6) must show zero _v1/_v2/_reliability references in server/api/**, pages/**, composables/**. T1 must run this grep when source access is available; this run cannot (UNVERIFIED).
4. Render contract (what the generic renderer must consume from _current)
node: axis_code, node_code, label, count_value, count_status
drill: has_children, child_count, child_node_codes, grouping_status,
drill_action ∈ {DRILL, DRILL_GROUPS, SHOW_SUBSTRATE, SHOW_EMPTY_BANNER, DISPLAY},
next_route, grouping_children_source, final_substrate_ref, substrate_available, empty_reason
status:drill_integrity (from invariant, doc 04) → drives PASS/EXPECTED/WARN/FAIL render branch
badges:reliability_label, source_scope, confidence_score, lane_code, count_semantics,
warning_flags[], blocker_type, next_action, gov_sync_state, owner_blocker
Render branch (the generic switch):
drill_action=DRILL→ list children (recurse).DRILL_GROUPS→ list groups fromgrouping_children_source, then recurse to substrate.SHOW_SUBSTRATE→ renderfinal_substrate_reftable (only ifsubstrate_available).SHOW_EMPTY_BANNER→ empty banner withempty_reason.drill_integrityoverrides:EXPECTED_NEEDS_GROUPING→capped list + "grouping pending";EXPECTED_AUTHORITY_BLOCKED→status chip not green;FAIL_*→safe fallback (doc 04 §5).- Badges always rendered: a count never appears without
source_scope+reliability_label;warning_flagsshown as chips.
The renderer is axis-agnostic: it switches on drill_action/drill_integrity, never on axis_code. That is the generic-UI invariant. (A new axis from the registry, doc 03, renders with zero new components.)
5. Fallback behavior for a new/unknown axis
- Unknown
drill_action→DISPLAY(leaf, show label + count + badges); never crash. - Missing
final_substrate_refwithSHOW_SUBSTRATE→ treated asFAIL_DEAD_ENDby the invariant → safe-fallback notice. - New axis with
governance_class=CANDIDATE/SYNTHETIC/DERIVED→ render + governance badge; no officialize affordance for DERIVED.
6. Classification
| Issue | Class | Severity |
|---|---|---|
UI binds versioned views, not _current |
DESIGN_DRIFT / UI_DEBT | P1 |
| Reliability/governance badges not in renderer yet | UI_DEBT | P1/P2 |
| UI not deployed (divergent git, no creds) | OPERATIONAL_DEBT | P3 (operator) |
| UI source not auditable this run | (audit limitation) | UNVERIFIED_SOURCE_ACCESS |
7. Required technical spec for T1 (Area 9)
- Repoint all RP pass-through routes to
_currentviews; run the grep gate (no_vNreferences). - Extend
drill.vue(or its render model) to consume + render the reliability/governance badges and thedrill_integrityrender branch (doc 04 §5). - Keep the renderer axis-agnostic (switch on
drill_action/drill_integrity, neveraxis_code) — add a lint check. - Acceptance (when source access available): grep shows 0
_vNrefs; a synthetic test axis renders with no new component; FAIL nodes never render as green.