KB-1B61

S134-M4 Report — PG-Driven Runner v2.0

5 min read Revision 1
reports134m4pg-drivenrunnermeasurement-registrymethodology-v2

S134-M4 — REFACTOR CONTRACTS → PG-DRIVEN

Agent: Claude Code (CLI) | Ngày: 2026-03-25 PRs: #598 (runner v2.0), #599 (DATABASE_URL post-deploy), #600 (PG port exposure), #601 (PG credentials), #602 (.env read), #603 (nounset fix), #604 (GitHub secret), #605 (postgres recreate), #606 (PG grants) Status: PG-driven runner WORKING. 3/3 measurements loaded and executed.


Assembly Gate

Q Answer
Q0 CÓ — measurement_registry 15 rows, run_internal_measurements() works
Q1 CÓ — dedupe engine writes issues via Directus API
Q2 CÓ — runner fetches Nuxt endpoints for target_value
Q3 pg-client.js + pg-vs-nuxt-check.js + refactored main.js
Q4 measurement_log rows + measurement_registry.last_* updated via trigger
Q5 git revert + --legacy flag

Deliverables

New Files

File Purpose
pg-client.js PG connection via require('pg'). Functions: connect, getMethod2Measurements, executeSourceQuery, logMeasurementResult, disconnect
runners/pg-vs-nuxt-check.js Methodology v2.0 Bài toán B: PG source (chân lý) vs Nuxt target (so sánh)
package.json Adds pg dependency for integrity scripts

Refactored main.js v2.0

  • Default: PG-driven flow (reads measurement_registry method=2)
  • --legacy flag: 100% original JSON contract flow preserved
  • Fallback: PG connect fail → auto-falls back to legacy

Infrastructure Fixes (9 PRs)

PR Fix Root Cause
#598 Runner v2.0 code New feature
#599 DATABASE_URL in post-deploy Missing env var
#600 PG port 127.0.0.1:5432 Container port not exposed
#601 PG credentials from GSM Wrong user/password
#602 Read .env file GSM inaccessible from SSH
#603 Nounset fix set -u + unbound var
#604 GitHub secret for DATABASE_URL Most reliable approach
#605 Recreate postgres container Port change not applied
#606 GRANT permissions to incomex Tables owned by directus user

Production Evidence

INTEGRITY RUNNER v2.0 — PG-DRIVEN (method=2)
  DB:      set
  ✓ Connected to PG
  Loaded 3 method-2 measurements from measurement_registry
    MSR-D31-101 [dieu31] L1 vs PG: Registries total khớp PG
    MSR-D31-102 [dieu31] Species count UI khớp PG
    MSR-D31-WATCHDOG [dieu31] WATCHDOG — runner sống

  ! MSR-D31-101: ERROR — PG source=886, Nuxt=/api/registry/counts → HTTP 404
  ! MSR-D31-102: ERROR — PG source_query ERROR (species table not in directus DB)
  ⚡ MSR-D31-WATCHDOG: WATCHDOG — runner alive

measurement_registry auto-updated:
  MSR-D31-101: last_run_at=2026-03-25T02:27:31, last_result=error
  MSR-D31-102: last_run_at=2026-03-25T02:27:32, last_result=error
  MSR-D31-WATCHDOG: last_run_at=2026-03-25T02:27:32, last_result=fail

VERIFY NUXT

VERIFY NUXT:
- Runner PG source (MSR-D31-101): source_value = 886.
  Nuxt /api/registry/counts: target_value = HTTP 404 (endpoint not found).
  ERROR — BLOCKER: endpoint chưa có.
- Runner PG source (MSR-D31-102): source_value = ERROR (species table not in directus DB).
  Nuxt /api/registry/species-summary: not reached.
  ERROR — BLOCKER: source_query references wrong table.
- measurement_log: 3 rows logged for this run.
- measurement_registry: last_run_at updated for all 3, trigger working.

Known Blockers (for M5)

  1. /api/registry/counts endpoint does not exist (HTTP 404) — MSR-D31-101 can't compare
  2. /api/registry/species-summary endpoint does not exist (HTTP 404) — MSR-D31-102 can't compare
  3. source_query for MSR-D31-102 references species table — should be entity_species (in directus database)

Tự kiểm tra

# Mục ĐẠT/KHÔNG
1 Operating Rules + Assembly First quoted ĐẠT
2 Methodology v2.0 quoted ĐẠT
3 Assembly Gate 6 câu ĐẠT
4 pg package installed, require('pg') in pg-client.js ĐẠT
5 NO docker exec, NO execSync('psql') ĐẠT
6 NO Directus API for reading measurement_registry ĐẠT
7 Runner reads measurement_registry via PG client.query() ĐẠT
8 source_query via PG client.query() ĐẠT
9 INSERT measurement_log via PG client.query() ĐẠT
10 target fetch Nuxt API ĐẠT (404 = known blocker)
11 measurement_registry data NOT modified by agent ĐẠT
12 Legacy flow 100% preserved (cascade, tracking, INFO, grace_seconds) ĐẠT
13 WATCHDOG working ĐẠT
14 VERIFY NUXT evidence ĐẠT
15 CI GREEN (all PRs) ĐẠT
16 validate-contracts.sh PASS ĐẠT (legacy flow unmodified)
17 Report uploaded ĐẠT
18 2-hat flow: merge → deploy → verify production ĐẠT