KB-3541
RP Classification Cleanup — 02 Mapping View Apply (APPLIED)
6 min read Revision 1
registries-pivotmapping-viewview-appliedddlrollbackentry-exit2026-06-03
02 — Mapping View: APPLY (✅ APPLIED LIVE)
Decision: APPLY (user-confirmed, Option 2). Preflight proved the view is a pure read-only projection — safe, reversible, no-island, no side effects — and the mission authorizes persistent read-only mapping DDL.
Why it is safe (preflight-proven)
- Pure SELECT — no INSERT/UPDATE/DELETE.
- Fires no triggers — views do not fire DML triggers; the 3 enabled
pivot_definitionstriggers act only on base-table DML. - No island — it LEFT JOINs governed truth (
entity_species,taxonomyFAC-02) and copies nothing; it is a derived projection over the live single source of truth. - Reversible —
DROP VIEW v_rp_classification_governance_map;leaves zero residue. - Does not touch L2 — no reference to ownership/axis/topic/ospa.
Apply protocol executed (exactly as requested)
- Re-ran preflight immediately before DDL → baseline matched (37/126/42/58/10/38/824230; ospa0/own0/gap210/emit0/idle0; view absent;
pivot_def md5=5a060f5460c3d9e02c4a6754cdee4fcc). - Applied only
CREATE OR REPLACE VIEWinside an explicit transaction with fail-closed guards (aDOblock raising on any deviation;ON_ERROR_STOP). - No UPDATE/INSERT/DELETE; no DOT; no event/system_issues/UI/Directus/Qdrant/Nuxt.
Apply output (prod)
BEGIN
CREATE VIEW
COMMENT
DO
COMMIT
NOTICE: GUARDS PASSED: rows=37 orphan=0 domain=15 shape=22
Verification (read-only, post-apply) — see doc 05 for the full suite
| Check | Expected | Got |
|---|---|---|
| view_rows = base_rows | 37 = 37 | ✅ 37=37 |
| registry_group_kind | domain 15 / pivot_shape 22 | ✅ |
| FAC-02 exact | LBL-101×3, LBL-104×4, LBL-105×2 | ✅ |
| species_status | clean 31 / missing 4 / ambiguous_meta 2 / orphan 0 | ✅ |
| composition_status | match 21 / mismatch 3 / drill_overload 9 / no_ref 4 | ✅ |
| classification_lane | governance_home 15 / rp_local 20 / inactive_retire 2 | ✅ |
| L2 gate (no false claim) | ospa 0 / own 0 / gap 210 / emit 0 | ✅ |
Entry == Exit proof (0 base-table mutations)
| Counter | Entry | Exit | Δ |
|---|---|---|---|
| pivot_definitions | 37 | 37 | 0 |
| pivot_results | 126 | 126 | 0 |
| entity_species | 42 | 42 | 0 |
| taxonomy / facets | 58 / 10 | 58 / 10 | 0 |
| label_rules | 38 | 38 | 0 |
| entity_labels | 824,230 | 824,230 | 0 |
| ospa / ownership / gap / gov_emit | 0/0/210/0 | 0/0/210/0 | 0 |
| idle_in_txn | 0 | 0 | 0 |
| pivot_definitions md5 | 5a060f5460c3d9e02c4a6754cdee4fcc |
5a060f5460c3d9e02c4a6754cdee4fcc |
identical |
v_rp_classification_governance_map |
absent | present | +1 view (only delta) |
Rollback — staged and tested non-destructively
DROP VIEW IF EXISTS v_rp_classification_governance_map;
Tested by dropping inside a transaction and rolling back:
before_test = v_rp_classification_governance_map
inside_after_drop = (null) -- DROP works
after_rollback_restored= v_rp_classification_governance_map -- restored; view still live
Canonical DDL (as applied)
CREATE OR REPLACE VIEW v_rp_classification_governance_map AS
WITH fac02 AS (
SELECT t.code, t.name FROM taxonomy t
JOIN taxonomy_facets f ON t.facet_id = f.id
WHERE f.code = 'FAC-02'
)
SELECT
pd.code AS pivot_code, pd.name AS pivot_name, pd.source_object, pd.is_active,
pd.registry_group AS raw_registry_group,
CASE WHEN pd.registry_group IN ('cấu_trúc','nội_dung','quy_tắc','công_cụ','giám_sát','quy_trình','dữ_liệu') THEN 'domain'
WHEN pd.registry_group IN ('default','cross-table','l2-drill','matrix_l1','matrix_l2','test') THEN 'pivot_shape'
ELSE 'unknown' END AS registry_group_kind,
CASE pd.registry_group WHEN 'cấu_trúc' THEN 'LBL-101' WHEN 'nội_dung' THEN 'LBL-102'
WHEN 'quy_tắc' THEN 'LBL-103' WHEN 'công_cụ' THEN 'LBL-104' WHEN 'giám_sát' THEN 'LBL-105'
ELSE NULL END AS fac02_label_code,
fac.name AS fac02_label_name,
CASE pd.registry_group WHEN 'default' THEN 'default' WHEN 'cross-table' THEN 'cross_table'
WHEN 'l2-drill' THEN 'l2_drill' WHEN 'matrix_l1' THEN 'matrix' WHEN 'matrix_l2' THEN 'matrix'
WHEN 'test' THEN 'test' ELSE NULL END AS pivot_kind,
pd.species AS raw_species, es.code AS species_governed_code, es.display_name AS species_display_name,
es.composition_level AS species_governed_composition,
CASE WHEN pd.species IS NULL THEN 'missing' WHEN es.species_code IS NULL THEN 'orphan'
WHEN pd.species='species' THEN 'ambiguous_meta' ELSE 'clean' END AS species_status,
pd.composition_level AS raw_composition_level,
(pd.composition_level IN ('atom','molecule','compound','meta')) AS composition_is_canonical,
CASE WHEN pd.species IS NULL OR es.composition_level IS NULL THEN 'no_ref'
WHEN pd.composition_level = es.composition_level THEN 'match'
WHEN pd.registry_group IN ('cross-table','l2-drill','matrix_l1','matrix_l2','test') THEN 'drill_overload'
ELSE 'mismatch' END AS composition_status,
CASE WHEN pd.is_active = false THEN 'inactive_retire_candidate'
WHEN pd.registry_group IN ('default','cross-table','l2-drill','matrix_l1','matrix_l2','test') THEN 'rp_local'
ELSE 'governance_home' END AS classification_lane
FROM pivot_definitions pd
LEFT JOIN entity_species es ON pd.species = es.species_code
LEFT JOIN fac02 fac ON fac.code = (CASE pd.registry_group
WHEN 'cấu_trúc' THEN 'LBL-101' WHEN 'nội_dung' THEN 'LBL-102' WHEN 'quy_tắc' THEN 'LBL-103'
WHEN 'công_cụ' THEN 'LBL-104' WHEN 'giám_sát' THEN 'LBL-105' END);
Verdict: APPLIED. Production byte-equivalent except for the one inert read-only view. L2 gate untouched.