KB-F5C3

RP DOT Pivot-Update — 04 Rehearsal (BEGIN..ROLLBACK, 0 mutations, bug found+fixed)

3 min read Revision 1
registries-pivotrehearsalbegin-rollbackzero-mutation2026-06-03

04 — Rehearsal (BEGIN..ROLLBACK on production)

Full log: artifacts/rehearsal_log.txt. Channel: ssh contabo → docker exec -i postgres psql -U directus -d directus. Every run committed nothing.

Method

BEGIN..ROLLBACK on production was chosen over a fresh clone: the refresh trigger functions are transaction-safe (xact-scoped advisory lock, no NOTIFY/dblink), so an UPDATE applied then ROLLBACK leaves the database byte-identical while exercising the real trigger path. The mission lists this as "strongly preferred". The tool's default DRY-RUN mode performs exactly this internally.

Fingerprint invariant

ENTRY  pivot_definitions md5 = 70d6df05501a7de91e24b848168c5b03   n=37 active=35
EXIT   pivot_definitions md5 = 70d6df05501a7de91e24b848168c5b03   n=37 active=35   ← IDENTICAL

The 3 composition fixes — DRY-RUN result

Pivot species comp change AFTER_FIELD mapping-view composition_status txn
PIV-001 catalog molecule→atom atom match (was mismatch) ROLLBACK
PIV-016 species atom→meta meta match ROLLBACK
PIV-021 checkpoint_support atom→molecule molecule match ROLLBACK

Each proves the fix is correct against the live governance view, committing nothing.

Rejection / edge battery (10 cases, all correct)

# Case Result
1 invalid field foobar reject exit 1
2 invalid species not_a_species reject exit 1
3 composition compound on governed-atom PIV-001 reject exit 1 (governed guard)
4 no-op registry_group=cấu_trúc (PIV-001) OK no-change exit 0
5 inactive row PIV-020 / MTX-TEST reject exit 1 (after fix)
6 unknown registry_group=bogus_zzz reject exit 1
7 valid in-use registry_group=công_cụ DRY-RUN plan + ROLLBACK exit 0
8 missing --value / no --auto reject exit 1
9 nonexistent code PIV-999 reject exit 1

Bug found + fixed during rehearsal (rehearsal earned its keep)

The inactive-row guard compared is_active to 'f', but is_active || '|' casts the boolean to 'true'/'false' (psql renders a bare boolean as t/f, but a concatenated one as true/false). The guard therefore never fired — a retired row could have been updated. Fix: SQL now emits CASE WHEN is_active THEN 'active' ELSE 'inactive' and the guard checks != 'active'. Re-tested PIV-020 + MTX-TEST → both correctly refused. Tool redeployed; fingerprint re-verified identical.

Trigger behaviour observed

UPDATE 1 inside each txn fired the statement-level refresh once, with no error and within normal time. No birth/matrix trigger fired (INSERT-only / matrix_spec NULL). Confirms the "no refresh explosion" + "integrates with existing trigger behaviour intentionally" reqs.

Back to Knowledge Hub knowledge/dev/reports/architecture/registries-pivot-dot-pivot-update-author-register-cleanup-2026-06-03/04-clone-or-rollback-rehearsal.md