KB-EB73

Dieu43 Phase 1.5 APPLY Report v1.2 S178 Fix 12

10 min read Revision 1
dieu43phase1-5v1-2applyreports178-fix12

Đ43 Phase 1.5 APPLY — Report (v1.2 rev 2 infrastructure)

Date: 2026-04-17 UTC+7 Phiên: S178 Fix 12 Agent: Claude CLI qua SSH contabo VPS: vmi3080463 (38.242.240.89), PG 16.13, DBs: directus + incomex_metadata + workflow

CHECKPOINT

Đã đọc: Đ43 v1.2 rev 2 §5.7+§5.8+§5.9+§11 Bước 6.1-6.4+§11 Bước 12 P11; HP v4.6.2 NT2/NT4/NT11/NT13; Đ35 v5.1 §4.1 KHOẢN 1B (fn_is_in_grace_period dùng dot_config); Đ33 §13; Đ41; memory #30 rà NT 3 tầng.

1. TRẠNG THÁI TRƯỚC

  • dot_config table: MISSING (không tồn tại bất kỳ DB nào)
  • context_pack_section_definitions: MISSING
  • context_pack_health_checks: MISSING
  • PG role context_pack_readonly: MISSING
  • FDW, trigger function fn_context_pack_on_law_enact: MISSING

Phase 1 v1.1 core tables (context_pack_manifest etc.) đã có. Phase 2 FS + Q2 user đã PASS.

2. QUYẾT ĐỊNH CLI CHỐT (trả lời Q2/Q4/Q6)

Q2 — Role có quyền CREATEROLE + superuser

Duy nhất workflow_admin (rolcreaterole=true, rolsuper=true, rolcanlogin=true). File 04 dùng user này cho:

  • CREATE ROLE context_pack_readonly cluster-level
  • ALTER DEFAULT PRIVILEGES cross-DB
  • CREATE EXTENSION postgres_fdw
  • CREATE FOREIGN TABLE / USER MAPPING
  • CREATE FUNCTION fn_context_pack_on_law_enact + CREATE TRIGGER on kb_documents

Q4 — placeholder_style seed value

Giữ nguyên spec §5.7 seed: 'mustache'. Không chọn khác vì §5.7 render_config key whitelist chỉ cho 2 giá trị (mustache | jinja). Python modules chevron/jinja2 không cài sẵn trên VPS — Phase 4a P3 sẽ cần pip install chevron (1 file lib, ~100KB) hoặc tương đương. CLI KHÔNG đổi default ở Phase 1.5 vì đó là decision của Phase 4a P3 engine chọn.

Q6 — kb_documents.key format

Test thực tế:

  • key LIKE 'knowledge/dev/laws/%'0 matches
  • key LIKE 'knowledge__dev__laws__%'59 matches

Agent Data sync pipeline normalize /__ khi insert vào PG. Seed context_pack_watched_key_patterns dùng __ format để LIKE match thực tế. Flag TD-S178-18: Desktop quyết sau — (a) amend §5.9 wording dùng __, hoặc (b) fix sync pipeline preserve /.

3. LỆNH CHẠY

3 migration SQL files soạn thẳng trên VPS (Đ41), apply tuần tự:

File DB target User Nội dung
02-prereq-dot-config.sql directus directus CREATE TABLE dot_config + touch trigger
03-dieu43-v1-2-extensions.sql directus directus section_definitions (CHECK path whitelist) + health_checks (CHECK SQL path whitelist) + 7 dot_config keys §5.9
04-dieu43-v1-2-role-fdw-trigger.sql directus → \c incomex_metadata workflow_admin (superuser) CREATE ROLE context_pack_readonly LOGIN NOINHERIT + GRANT DEFAULT PRIVILEGES cross-DB + postgres_fdw + foreign table dot_config + function + trigger

Apply sequence:

psql -U directus -d directus -f 02-prereq-dot-config.sql
psql -U directus -d directus -f 03-dieu43-v1-2-extensions.sql
psql -U workflow_admin -d directus -f 04-dieu43-v1-2-role-fdw-trigger.sql

Exit codes: tất cả 0. Post-check trong mỗi file: all PASS.

SHA256:

  • 02-prereq-dot-config.sql (patched v2): 7e1635b1bc10c0afdd12744b517622673f49595559dad396243ce64e752e1f24
  • 03-dieu43-v1-2-extensions.sql: 692a6d396d656a1f244aab65de0af6c6dbebb397631088757639fcc33a749282
  • 04-dieu43-v1-2-role-fdw-trigger.sql (patched v2): dd36ac5117961414b15653ae03d595d17c7a888f07ceea213539c456ff789a5c

4. 7 TIÊU CHÍ PASS — EVIDENCE

T1 — SELECT FROM dot_config chạy + ≥7 keys Đ43

dot_config_dieu43_keys=7

Keys: context_pack_scan_paths, context_pack_scan_db_whitelist, context_pack_watched_key_patterns, context_pack_retry_policy, context_pack_mode, context_pack_output_root, context_pack_grace_period_days. PASS

T2 — context_pack_section_definitions 8 rows + CHECK path whitelist

section_definitions_count=8
chk_query_kb_path_whitelist: YES
chk_template_kb_path_whitelist: YES

PASS

T3 — context_pack_health_checks 9 rows + CHECK SQL path whitelist

health_checks_count=9
chk_sql_executor_path: YES

PASS

T4 — Role context_pack_readonly SELECT cross-DB

directus DB:           count(section_definitions) = 8
incomex_metadata DB:   count(kb_documents) = 1969
Negative test (INSERT): ERROR: permission denied for table context_pack_requests

PASS — SELECT ở 2 DB OK, INSERT bị chặn đúng.

T5 — DEFAULT PRIVILEGES (P10 rev 2)

-- directus user creates _cp_test_default_priv (new table, no explicit GRANT)
-- readonly role SELECT _cp_test_default_priv → 1 row, note='priv_test'

PASS — Table mới owned by directus → readonly có SELECT quyền NGAY qua ALTER DEFAULT PRIVILEGES FOR ROLE directus. Mở rộng table nguồn mới = tự quyền đọc, không sửa code.

T6 — Trigger runtime P11 rev 2

Test 1 (match existing pattern): UPDATE kb_documents WHERE key='knowledge__dev__laws__law-14-no-duplicate.md' → LISTEN capture:

Asynchronous notification "context_pack_event" with payload 
"{"kind":"law_enact","key":"knowledge__dev__laws__law-14-no-duplicate.md","pattern":"knowledge__dev__laws__%"}"

Test 2 (runtime pattern update — ★ KEY P11 test):

  • STEP 1: baseline patterns ["knowledge__dev__laws__%","knowledge__dev__ssot__%","knowledge__dev__architecture__%"]
  • STEP 2: UPDATE dot_config SET value = '[...existing, "_phase15_probe_%"]' — CHỈ UPDATE, KHÔNG DROP+CREATE trigger
  • STEP 3: INSERT kb_docs key=_phase15_probe_runtime_test → LISTEN capture:
    payload "{"kind":"law_enact","key":"_phase15_probe_runtime_test","pattern":"_phase15_probe_%"}"
    
  • STEP 4 cleanup: DELETE test rows + restore dot_config

PASS — Pattern mới có hiệu lực NGAY ở event tiếp theo, xác nhận trigger function body đọc dot_config runtime qua FDW. P11 rev 2 compliance confirmed.

T7 — Idempotent (rerun 3 files)

Sau rerun cả 3 files 2+ lần:
def_count=8 (không đổi)
health_count=9 (không đổi)
dot_config_cp_keys=7 (không đổi)
trigger_count=1 (không đổi)

PASS

5. VẤN ĐỀ PHÁT SINH + FIX TRONG PHASE 1.5

Issue 1: CREATE ROLE ... NOINHERIT default NOLOGIN → readonly không login được

Fix: ALTER ROLE context_pack_readonly LOGIN; + patch File 04 thành CREATE ROLE ... LOGIN NOINHERIT.

Issue 2: DROP TRIGGER IF EXISTS xung đột event trigger fn_evt_trigger_guard_drop hệ thống

Khi trigger đã tồn tại, DROP TRIGGER fire event trigger fn_evt_trigger_guard_drop() (audit trigger cluster-wide) → INSERT vào trigger_guard_alerts với trigger_name=NULL → NOT NULL violation → TX rollback.

Fix: Thay DROP TRIGGER IF EXISTS + CREATE TRIGGER bằng DO $$ IF NOT EXISTS CREATE TRIGGER END $$ block. Pattern này:

  • Không DROP → không fire event guard
  • Idempotent (IF NOT EXISTS check pg_trigger)
  • Áp dụng cho cả trg_dot_config_touch (File 02) và trg_context_pack_law_enact (File 04)

Issue 3: FDW cross-DB architecture cho trigger P11 rev 2

Vấn đề: dot_config sống ở DB directus. Trigger kb_documents fire ở DB incomex_metadata. Luật §11 Bước 12 example assumes cùng DB.

Giải pháp: Dùng postgres_fdw extension + foreign table dot_config trong incomex_metadata trỏ tới directus.public.dot_config. User mapping trust auth (local socket). Trigger function SELECT FROM dot_config → transparent cross-DB read.

Ảnh hưởng perf: Mỗi INSERT/UPDATE kb_documents → trigger fire → FDW query → 1 remote SELECT. Với sync pipeline chạy 1000+ records sẽ có overhead. Chưa bench. Flag TD-S178-20 nếu cần tối ưu.

Triết lý giữ: KHÔNG thay WHEN NEW.key LIKE 'knowledge%' để prefilter vì vi phạm P11 "CẤM bind pattern cố định vào WHEN clause". Chấp nhận perf cost.

6. TECHNICAL DEBT ĐÃ GHI NHẬN

  • TD-S178-18: KB key format normalize / vs __ — sync pipeline vs §5.9 wording
  • TD-S178-20: FDW cross-DB query overhead per trigger fire (sync pipeline rate)
  • TD-S178-12: dot_run_log + fn_log_issue vẫn chưa có (Đ35 v5.1 BLOCK 4 chưa enact)
  • TD-S178-15: mmdc Mermaid validate fallback grep (chưa cài mmdc)
  • TD-S178-17: vps_deploy_log table chưa có — on-deploy gate Phase 4a sẽ permissive WARN+skip
  • TD-S178-14: Đ33 §14 user/env path khớp thực tế (directus + docker/.env)

7. SCOPE MỞ RỘNG SO VỚI PROMPT

Prompt §SCOPE LOCK: "4 artifacts chính". CLI thực hiện đúng 4 artifacts. Trigger function ATTACH trên kb_documents cũng làm (cần cho tiêu chí T6 test) — coi như thuộc "trigger function" artifact chứ không tách riêng "Phase 7 install".

Phase 7 còn lại: trigger on-dot-register (trên dot_tools INSERT → NOTIFY cho DOT change events). Chưa cài ở Phase 1.5.

8. SCOPE NGOÀI PHASE 1.5 — chưa làm (đúng SCOPE LOCK)

  • Schema migrate context_pack_sections v1.1 CHECK enum → v1.2 FK section_code (§5.4). Sẽ cần cho Phase 4a P4 INSERT sections. Flag: prompt Phase 4a P4 cần migrate trước.
  • Schema migrate context_pack_requests thêm retry_count, next_retry_at, last_error (§5.2). Cần cho Phase 4a P5 retry logic. Flag: prompt Phase 4a P5 cần migrate trước.
  • Chưa register DOT vào dot_tools (Phase 5)
  • Chưa install cron (Phase 6)
  • Chưa cài on-dot-register trigger (Phase 7 scope)

9. KẾT LUẬN

Phase 1.5 PASS — 7/7 tiêu chí.

Hạ tầng v1.2 Đ43 đã đầy đủ để Phase 4a build.sh chạy live test ở P3/P5:

  • dot_config + 7 keys seed OK
  • 8 section_definitions + CHECK path whitelist OK
  • 9 health_checks + CHECK SQL path whitelist OK
  • Role context_pack_readonly cross-DB LOGIN OK (DEFAULT PRIVILEGES ♦ P10 compliance)
  • FDW + trigger fn_context_pack_on_law_enact + attach kb_documents (♦ P11 compliance)
  • Idempotent 100% (DO block pattern thay DROP+CREATE)

Sẵn sàng sang P1 Phase 4a (code skeleton build.sh).


Report by Claude CLI — S178 Fix 12 Phase 1.5 — 2026-04-17