RS3B-08 — Trigger Side-Effect Inventory and Closed-at-Registration Proof — 2026-06-21
RS3B-08 — Trigger Side-Effect Inventory and Closed-at-Registration Proof — 2026-06-21
Macro: RS3B-REGISTRAR-HARDENING-DESIGN (read-only / KB-design)
Deliverable: 08 of 10 · Trigger side-effect + closed-at-registration (Mục tiêu H)
Date: 2026-06-21 · 0 mutations · NO_CODEX_LIVE_READ
Deliverable status: TRIGGER_SIDE_EFFECT_INVENTORIED with one activation-signal side-effect (trg_context_pack_dot_register → pg_notify) that must be fenced by the closed-at-registration proof.
Method note:
information_schema.triggersis privilege-blind for the read-only role (returns 0). The full set below was read viapg_catalog.pg_trigger+pg_get_triggerdef(source-tier). Trigger enable flags:O=enabled,D=disabled.
1. dot_tools trigger inventory (14 triggers; 13 enabled, 1 disabled)
| Trigger | Timing / event | Function | Side effect | Activates? | Notifies automation? | Birth/context-pack effect? |
|---|---|---|---|---|---|---|
trg_before_birth_gate_dot_tools |
BEFORE INSERT | fn_birth_gate() |
may block insert (gate) | no | no | gate (fail-closed-friendly) |
trg_auto_code_dot_tools |
BEFORE INSERT | gen_code_dot_tools() |
auto-generate code |
no | no | no |
trg_normalize_dot_filepath |
BEFORE INSERT/UPDATE OF file_path | fn_normalize_dot_filepath() |
normalize file_path |
no | no | no |
trg_desc_guard_dot_tools |
BEFORE INSERT/UPDATE OF description | fn_description_birth_guard() |
description guard | no | no | no |
trg_validate_dot_origin_dot_tools |
BEFORE INSERT/UPDATE OF _dot_origin | fn_validate_dot_origin() |
validate _dot_origin |
no | no | origin gate |
birth_trigger_dot_tools |
AFTER INSERT | fn_birth_registry_auto('code') |
create birth-registry row | no | no | birth side-effect |
trg_birth_dot_tools |
AFTER INSERT | fn_birth_registry_auto('code') |
duplicate of above | no | no | birth side-effect (dup) |
trg_desc_provenance_dot_tools |
AFTER INSERT | fn_auto_label_provenance() |
auto provenance label | no | no | no |
trg_label_assign_dot_tools |
AFTER INSERT/UPDATE OF name,description | fn_auto_label_assignment() |
auto label | no | no | no |
trg_context_pack_dot_register |
AFTER INSERT OR UPDATE OF status, tier | fn_context_pack_on_dot_register() |
pg_notify('context_pack_event', …) |
potential | YES | context-pack |
trg_refresh_dot_count |
AFTER INSERT/DELETE/UPDATE OF status (statement) | fn_refresh_dot_count() |
refresh count | no | no | no |
trg_refresh_orphan_dot |
AFTER INSERT/DELETE/UPDATE (statement) | trg_fn_refresh_orphan_dot() |
refresh orphan view | no | no | no |
trg_count_dot_tools |
AFTER … (statement) | refresh_registry_count() |
count refresh | no | no | DISABLED (D) |
The one activation-signal trigger (verbatim function body, source-tier)
fn_context_pack_on_dot_register():
SELECT value::jsonb INTO v_tiers FROM dot_config WHERE key='context_pack_dot_register_watch_tiers';
IF v_tiers IS NULL OR jsonb_array_length(v_tiers)=0 THEN RETURN NEW; END IF;
IF EXISTS (SELECT 1 FROM jsonb_array_elements_text(v_tiers) t WHERE t=COALESCE(NEW.tier,''))
AND NEW.status='active' THEN
PERFORM pg_notify('context_pack_event',
json_build_object('kind','dot_register','code',NEW.code,'tier',NEW.tier,'op',TG_OP)::text);
END IF;
RETURN NEW;
Live config: dot_config.context_pack_dot_register_watch_tiers = ["A","B","C"]. DOT-REGISTER and DOT-015 are tier B. ⇒ inserting/updating a tier-A/B/C dot_tools row to status='active' fires a pg_notify('context_pack_event', {kind:dot_register, code, tier, op}) that downstream context-pack automation may consume. The notify is a signal only (no row write), but it is an automation activation surface.
2. Adjacent surfaces
dot_config(119 rows):trg_dot_config_touchBEFORE UPDATE (fn_dot_config_touch);trg_sync_cp_patternsAFTER INSERT/UPDATE OF value (fn_sync_cp_patterns_to_meta). Gates here (process_dot_runtime.real_run,iu_core.operator_runtime) are closed; registration must not touch them.law_dot_enforcement(272 rows):trg_birth_law_dot_enforcementAFTER INSERT (fn_birth_registry_auto_id);trg_enforcement_validate_dot_codeBEFORE INSERT/UPDATE (fn_enforcement_validate_dot). Not written by registration.- Audit sinks (RS3B-06):
event_outboxhastrg_event_outbox_type_validateBEFORE INSERT (type validation, no immutability);registry_changeloghas birth/label triggers + DISABLED count trigger (no immutability, mutable resolve columns);governance_audit_log,context_pack_manifest,iu_route_attempthave no triggers.
3. Closed-at-Registration Proof Obligations
For the hardened registrar to prove registration is closed (registers without activating):
- No activation status. The registration INSERT must not set
status='active'for a watch-tier (A/B/C) DOT, sotrg_context_pack_dot_registerdoes not firepg_notify. Register a closed/inert status; activation is a separate, Owner-gated UPDATE with its own authority nonce (RS3B-03 §6, RS3B-05). RejectACTIVATION_AT_REGISTRATION/WOULD_OPEN_GATE. - If a notify is unavoidable, prove the consumer is inert. If any registration path must set a watch-tier row active, the proof must show the
context_pack_eventconsumer performs no auto-activation / no birth pipeline / no gate flip (currentlycontext_pack_mode = warn). Until proven, treat the notify as an activation risk → fail-closed. - Account for birth side-effects.
birth_trigger_dot_tools+trg_birth_dot_tools(duplicate) auto-create a birth-registry row on INSERT;fn_birth_gatemay block. The contract must treat birth auto-creation as expected, idempotent, and non-activating; the duplicate birth trigger must not double-effect in a way the verifier misreads. - Gates stay closed. Post-commit verifier (RS3B-03 §5) must confirm:
dot_configruntime gates unchanged (real_run=false,operator_runtime=false),dot_agent_api_contractnot wired, nolaw_dot_enforcementwrite,statusnot active. - No durable activation via audit sink. Writing the failure/audit envelope to
event_outbox(RS3B-06) must not emit an event on adelivery_lane/event_typethat triggers downstream execution.
4. Status block
- Deliverable status:
TRIGGER_SIDE_EFFECT_INVENTORIED - Activation surface =
trg_context_pack_dot_register→pg_notify('context_pack_event')on watch-tier +status='active'; fenced by obligation #1 - 14
dot_toolstriggers accounted (1 disabled); no immutability triggers on any audit sink (RS3B-06) - Registration gate:
REGISTRATION_HOLD·REGISTRATION_CAN_PROCEED = NO· 0 mutations