KB-2D54

07 — Direct-PG API Exception (Q7)

6 min read Revision 1
direct-pgrpgatewaydbdieu41dieu33api-exceptionvps-deploy-logfact-finding

07 — Direct-PG API Exception (Q7)

Verdict: DIRECT_PG_EXCEPTION_UNRATIFIED_BLOCKER — the direct read-only pg-Pool path is documented in prior ship reports, but live PG shows it has no approval, no vps_deploy_log entry, and its only plausible host law (Đ41) is itself agency-orphaned. Recommended long-term fix is a tie between ratify a read-only PG adapter under Đ41/Đ33 and DIRECTUS_EXPOSURE_FIX_REQUIRED (add a PK to the views and route via Directus) — the latter being the cleaner long-term convention.

1–5. Is direct-PG present? Which files? Role? Read-only? Bypass scope?

Documented (KB ship reports + session memory), but NOT re-verifiable through my read-only channel:

  • Files (per …/registries-pivot-final-production-route-shipped-2026-05-31 + memory): web/server/utils/rpGatewayDb.ts (read-only pg Pool), Nitro endpoints web/server/api/registries-pivot/{rows,summary,node}.get.ts, page web/pages/knowledge/registries-pivot/index.vue.
  • Credentials/role: RP_PG_* env reusing ${DB_*} (a separate read-only Pool, distinct from this audit's context_pack_readonly).
  • Read-only: described as read-only (queries six committed views only).
  • Bypass scope: bypasses PG→Directus→Nuxt only for views, because Directus returns 403 on the PK-less views (law_registry 403 even as admin; views have no primary key → Directus refuses to serve them).
  • Limitation: read_file is allow-listed to /opt/incomex/docs, /opt/incomex/dot/specs, /var/log/nginx only; the Nuxt source lives at /opt/incomex/docker/nuxt-repo/web (and is compiled into the image), so I could not independently re-read the code. The above is documented-fact, flagged as not-live-verified by this audit.

6. Does any law/design currently allow this exception?

  • Đ41 "Luật Vận hành Mã VPS" v1.1 = BAN HÀNH (enacted 2026-04-18) — governs how code is modified/deployed directly on the VPS while the VPS is the operating SSOT; mandates app-dev/app-production split, atomic release+symlink deploy, smoke test + auto-rollback, lock, a PG ledger (vps_deploy_log), and DOT guard. It is the closest host for a runtime-data-access exception but does not explicitly sanction a Nitro runtime read-only pg Pool (it is about code modify/deploy).
  • Đ33 "Luật PostgreSQL" §13.1 Exception E1 sanctions DDL via specialized DOTs (dot-pg-*-ensure, dot-schema-*-apply) going direct to PG via docker exec — because Directus REST cannot express CREATE TABLE/ALTER/TRIGGER. This covers DDL bootstrap by DOTs, not a runtime read pool inside Nuxt/Nitro.
  • Đ28 "Luật Kỹ thuật Hiển thị" (enacted) governs display but is agency-orphaned (no owner, no enforcing DOT — doc 02).
  • No enacted law explicitly authorizes the Nitro direct-pg read Pool. It sits in the gap between Đ33-E1 (DDL-by-DOT) and Đ41 (code-deploy).

7. Temporary, documented, or unratified? — Unratified AND un-ledgered.

  • No approval: approval_requests has zero governed (council/human) entries for any registries-pivot / rpGateway / API-exception target (doc 06). os_proposal_approvals = 0.
  • No deploy ledger entry: vps_deploy_log (the Đ41-mandated ledger) holds 18 rows, all mission_code S178-Fix16…Fix22 (deploy_kinds ops-code/schema-ddl/schema_register/directus-metadata-register/dot_update/script-patch). There is NO registries-pivot entry (max id 19 = "S178-Fix22-Step5"). So the RP production ship is not recorded under Đ41 — it is documented in KB session reports but absent from the live deploy ledger.
  • Host law orphaned: Đ41 (NRM-LAW-41) has no law_jurisdiction domain row and no governance_relations owner edge (it has only 1 law_dot_enforcement executor DOT). No agency owns the exception's governing law.
  1. DIRECTUS_EXPOSURE_FIX (preferred): add a stable PK / PK-compatible wrapper to the six views (or expose materialized tables) so Directus can serve them → eliminates the runtime pg Pool entirely and restores the PG→Directus→Nuxt convention.
  2. Ratify a read-only PG adapter: add an explicit Đ41 (or Đ33) clause sanctioning a read-only Nitro adapter for PK-less views, with the ledger/guard requirements (vps_deploy_log entry, env-pinned read-only role, no write path).
  3. PK-compatible view wrapper as a bridge between (1) and (2). Whichever path: the existing ship must be back-filled into vps_deploy_log to satisfy Đ41's audit clause.

9. Which governance owner should approve it?

  • Surface (route/API/template): GOV-MOUT under Đ28 — but GOV-MOUT is draft and Đ28 is agency-orphaned (doc 02), so this owner must first be activated/bound.
  • Code-operation exception (Đ41/Đ33): GOV-DOT (DOT-mediated PG access) and/or GOV-NRM-SYS (Đ33 schema law); ultimately GOV-COUNCIL §4.12(d) must assign Đ41's orphaned ownership and minute it to governance_audit_log.

Bottom line

The direct-PG path is a convention island, not a data island: read-only, narrow (views only), but unapproved, un-ledgered, and resting on an orphaned law. It must be either eliminated (Directus view-PK exposure) or explicitly ratified under Đ41/Đ33 — and either way recorded in vps_deploy_log.

Back to Knowledge Hub knowledge/dev/reports/architecture/governance-alignment-followup-fact-finding-registries-pivot-2026-06-01/07-direct-pg-api-exception.md