KB-7D3E

11 — Sync to PG Truth & Birth Promotion (promotion transaction, five-layer sync, idempotency, rollback, design-only, 2026-06-02)

5 min read Revision 1
one-roof-governancebirth-promotionsyncfive-layeridempotencyrollbackprojection-refreshdieu45qdrantdesign-only2026-06-01

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:

  1. pre-check (read-only): quorum passed (v_build_auth_valid); proposal still fresh (base not stale — unit_edit_draft.stale_at / axis_assignment revision); idempotency key unused.
  2. write truth: create/activate the taxonomy node (status='active') or axis_registry row; insert the birth_registry entry (the born identity); set owner + coverage status.
  3. flip working state: axis_assignment.zone='candidate'→'approved' for that node (close old valid_time, bump revision); reconcile into entity_labels for the topic facet.
  4. record: apr_approvals/approval_requests.applied_at, registry_changelog, change-set id, governance_build_authorization.consumed_at (single-use).
  5. COMMIT (or ROLLBACK on any failed invariant — entry==exit guaranteed).

11.2 Idempotency & concurrency

  • Idempotency: reuse the iu_merge_set/iu_split_set pattern — idempotency_key + change_set_id; a replayed apply is a no-op.
  • Concurrency: optimistic via base-version/content-hash (unit_edit_draft) and revision/valid_time (axis_assignment); NĐ-36-01 advises pg_advisory_xact_lock(entity_id) for entity-resolution races.
  • Staleness: if the base moved since the proposal (stale_at set), 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_id reverse + governance_build_authorization revoke + a rollback runbook (implementation-index doc 71 style: preflight pg_dump, DDL/DML rollback statements, separate-session verification, idle_in_transaction=0 check). 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.

Back to Knowledge Hub knowledge/dev/reports/architecture/one-roof-axis-proposal-authorization-operating-substrate-design-2026-06-01/11-sync-to-pg-truth-and-birth-promotion.md