11 — Sync to PG Truth & Birth Promotion (promotion transaction, five-layer sync, idempotency, rollback, design-only, 2026-06-02)
11 — Sync to PG Truth & Birth Promotion
Connects the proposal layer (doc 05) + storage (doc 04) + authorization (doc 02): how an approved proposal result becomes governed PG truth and propagates across the five layers. Verdict: RECOMMENDED — promotion is one idempotent, build-authorized transaction (PG truth + Birth), then derived projections refresh (envelope/tree/Qdrant/KB) by signal, never by direct authoring.
11.0 Principle
PG is truth; everything else is a projection that must be recomputable from PG. Promotion writes PG truth once, under an L3 build-authorization if it COMMITs born substrate; derived layers (Directus cache, Nuxt screens, AgentData/KB, Qdrant vectors) follow by signal (Điều 45) — they are never authored directly and never become a second source of truth.
11.1 The promotion transaction (candidate → born/active)
A single transaction, gated by governance_build_authorization (doc 02 L3) when it creates born substrate:
- pre-check (read-only): quorum passed (
v_build_auth_valid); proposal still fresh (base not stale —unit_edit_draft.stale_at/axis_assignmentrevision); idempotency key unused. - write truth: create/activate the
taxonomynode (status='active') oraxis_registryrow; insert thebirth_registryentry (the born identity); set owner + coverage status. - flip working state:
axis_assignment.zone='candidate'→'approved'for that node (close oldvalid_time, bumprevision); reconcile intoentity_labelsfor the topic facet. - record:
apr_approvals/approval_requests.applied_at,registry_changelog, change-set id,governance_build_authorization.consumed_at(single-use). - COMMIT (or ROLLBACK on any failed invariant — entry==exit guaranteed).
11.2 Idempotency & concurrency
- Idempotency: reuse the
iu_merge_set/iu_split_setpattern —idempotency_key+change_set_id; a replayed apply is a no-op. - Concurrency: optimistic via base-version/content-hash (
unit_edit_draft) andrevision/valid_time(axis_assignment); NĐ-36-01 advisespg_advisory_xact_lock(entity_id)for entity-resolution races. - Staleness: if the base moved since the proposal (
stale_atset), the apply fails closed and the proposal must be rebased/re-reviewed.
11.3 Five-layer sync (charter guardrail)
| Layer | Role | How it syncs after promotion |
|---|---|---|
| PG | source of truth | the promotion transaction (above) |
| Directus | API / edit surface | reads PG; cache invalidated; e-sign flows (L4) live here |
| Nuxt | screens | reads Directus/projection views; never PG-direct; shows new active node |
| AgentData / KB | reports/knowledge | report upload/list/read/search (this package itself); design docs |
| Qdrant | vectors | re-embed affected IUs; one vector/chunk = one IU; provisional/draft nodes not indexed into production Qdrant (content-policy) |
Sync is by signal (event_outbox, Điều 45: signal-not-data, register-before-emit, executor boundary, heartbeat) — a refresh worker recomputes the envelope (iu_three_axis_envelope refresh), iu_tree_path, and Qdrant embeddings. The governance event domain must be registered before emit (currently 0 — doc 01); until then promotion is synchronous + manual refresh.
11.4 What gets a Birth row (recap, doc 04)
Born: axis_registry rows, active taxonomy topic nodes, IUs. Not born: relations/edges, assignments, candidates, projection rows. Birth uses the existing birth_registry (canonical identity spine, ~1.04M rows, organic). Note the live correction (memory/implementation-index): birth_registry.canonical_address is NULL across rows → the candidate key is collection_name:entity_code, not canonical_address.
11.5 Rollback
- pre-apply: drop the draft / leave the candidate — zero truth touched.
- post-apply:
change_set_idreverse +governance_build_authorizationrevoke + a rollback runbook (implementation-index doc 71 style: preflightpg_dump, DDL/DML rollback statements, separate-session verification,idle_in_transaction=0check). Deprecate-not-delete for born nodes (status='deprecated',replaced_by) preserves audit/temporal history (NĐ-36-01).
11.6 Verdict
RECOMMENDED. Promotion is one idempotent, build-authorized PG transaction that writes truth + Birth and closes the proposal; projections (Directus/Nuxt/KB/Qdrant) follow by Điều-45 signal and are always recomputable. No second source of truth; deprecate-not-delete; full rollback story.