KB-2D02

RP DOT Cleanup — 02 DOT Binding and Tool Analysis (headline correction)

6 min read Revision 1
registries-pivotdot-bindingdot-pivot-declareinsert-onlytooling-gap2026-06-03

02 — DOT Binding and Tool Analysis

This is the core technical deliverable. Per the mission rule "If DOT script must be inspected, inspect it. Do not guess." — the live scripts under /opt/incomex/dot/bin/ were read in full via ssh (read-only).

Authoritative behavior of each candidate DOT

DOT-113 dot-pivot-declareINSERT-only (cannot update)

Usage: dot-pivot-declare --source <table> --name "<name>" [--filter '{...}'] [--group <g>] [--level <l>]
       dot-pivot-declare --auto-from-meta-catalog
  • No --code argument. It never targets an existing pivot by code.
  • Single mode: checks source exists; duplicate-guard = SELECT code FROM pivot_definitions WHERE source_object=$SOURCE AND filter_spec=$FILTER::jsonb LIMIT 1 → if a row exists, logs Already exists and exits 0 doing nothing. The guard does not filter on is_active, so even a soft-deleted row blocks re-declare.
  • Otherwise auto-generates PIV-(max+1) and INSERTs a brand-new row.
  • Auto mode: bulk-INSERTs pivots for meta_catalog entries lacking one; ON CONFLICT (code) DO NOTHING.

It can only CREATE. It cannot change composition_level/species/registry_group on PIV-001/016/021 or anyone else.

DOT-313 dot-matrix-update — UPDATE matrix_spec / name only

Usage: dot-matrix-update --code MTX-xxx [--row-axis <f>] [--col-axis <f>] [--agg <a>] [--filter '{...}'] [--layers '[...]']
  • Requires is_active=true and an existing matrix_spec. Rebuilds the JSON spec and runs UPDATE pivot_definitions SET matrix_spec=…, name=…, updated_at=NOW().
  • Does not touch composition_level/species/registry_group. Matrix pivots only.

DOT-314 dot-matrix-retire — UPDATE is_active / superseded_by only

Usage: dot-matrix-retire --code MTX-xxx
  • Reads is_active. If already f → logs "already retired", exits 0 (no write).
  • Else UPDATE … SET is_active=false, superseded_by='deprecated', updated_at=NOW() + best-effort pivot_results.needs_refresh=false.
  • Works on any code (not matrix-restricted) — it keys solely on code.

Others

  • dot-pivot-virtual-create writes meta_catalog (--code=CAT-xxx), not a cleanup of pivot_definitions classification fields.
  • dot-pivot-health (DOT-114) is read-mostly; line 143 can auto-retire broken pivots (is_active=false) but is not a targeted field-fixer.

Binding table — each cleanup target to a real invocation

Action pivot_code field old → new DOT Exact args Bindable?
A PIV-001 composition_level molecule → atom none exists NO
A PIV-016 composition_level atom → meta none exists NO
A PIV-021 composition_level atom → molecule none exists NO
B PIV-015/017/018/019 registry_group default → domain token none exists + council NO
B PIV-004/005/006/010/012/013 registry_group quy_trình/dữ_liệu → FAC-02 none exists + council NO
B PIV-016/021 registry_group default → domain token none exists + council NO
C 14 RP-local rows no change (view derives) n/a N/A (done)
D PIV-020 retire already is_active=false DOT-314 dot-matrix-retire --code PIV-020 no-op (early-exit)
D MTX-TEST retire already is_active=false, deprecated DOT-314 dot-matrix-retire --code MTX-TEST no-op (early-exit)

Expected trigger effects (for the future lawful update path)

A targeted UPDATE pivot_definitions SET composition_level=… WHERE code IN (PIV-001/016/021):

  • fires trg_after_pivot_definitions_change (statement refresh) — wanted;
  • does not fire trg_birth_pivot_definitions (INSERT-only);
  • does not fire trg_matrix_config_changed (matrix_spec is NULL on these rows).

Rollback route (for the future lawful update path)

Re-issue the inverse value, captured here: PIV-001→molecule, PIV-016→atom, PIV-021→atom. (No mutation occurred this macro, so nothing to roll back now.)

Verification query (per fix, once executed)

SELECT pivot_code, composition_status FROM v_rp_classification_governance_map
WHERE pivot_code IN ('PIV-001','PIV-016','PIV-021');   -- EXPECT all 'match' after

The headline correction

The prior package's doc-04 packet (dot-pivot-declare PIV-001 composition_level=atom) assumed a re-declare-updates semantics that the live script does not implement. Reading the script (not guessing) revealed:

  1. dot-pivot-declare cannot take a --code or update a field — it INSERTs.
  2. There is no dot-pivot-update in the toolset at all.
  3. The matrix DOTs cover matrix_spec and is_active, nothing else.

Actions A and B are unbindable today. The lawful unblock is to author and register a governed dot-pivot-update (proposed, paste-ready, not executed: sql/05_proposed_dot_pivot_update.sh) — not a manual UPDATE (Đ26 §II-QUINQUIES). See doc 04 for the execution decision and doc 08 for the build plan.

Back to Knowledge Hub knowledge/dev/reports/architecture/registries-pivot-dot-cleanup-antidrift-ui-api-handoff-2026-06-03/02-dot-binding-and-tool-analysis.md