KB-44F2

Dieu43 Phase 4a P0 Design Plan v1.2 rev 2

19 min read Revision 1
dieu43phase4ap0design-planv1-2s178-fix12

Đ43 Phase 4a — P0 Design Plan (v1.2 rev 2)

Date: 2026-04-17 UTC+7 Script target: /opt/incomex/dot/bin/dot-context-pack-build.sh Agent: Claude CLI, S178 Fix 12 Luật nền: Đ43 v1.2 FINAL rev 2 (KB rev 10), HP v4.6.2 (rev 23), Đ33 §13, Đ35 v5.1, Đ41


0. CHECKPOINT — Đã đọc

  • Đ43 v1.2 rev 2 §0+§3+§5.2-5.9+§6 (8 bước + §6.X)+§7+§8+§9+§11 (17 bước bootstrap)
  • HP v4.6.2 — 13 NT (đặc biệt NT2/NT4/NT10/NT11/NT12/NT13)
  • Đ33 §13 — DOT template
  • Đ35 v5.1 §4.1 schema 11 fields + §5.1 CẤM POST partial
  • Đ41 — VPS-as-SSOT
  • Handoff S178 Fix 11 FINAL — đặc biệt §2.2 rà NT 3 tầng
  • Phụ lục Đ43 §3.4 Phase 4a
  • 2 Phase 2 scripts (pattern shebang/trap/logging/11-fields header)

1. VPS SNAPSHOT (state hiện tại, trước P1)

1.1 — Filesystem (Phase 2 đã done)

/opt/incomex/context-pack/          incomex:incomex 755  (main, empty)
/opt/incomex/context-pack.tmp/      incomex:incomex 755  (temp, empty)
/opt/incomex/context-pack-staging/  incomex:incomex 755  (staging, empty)

/opt/incomex/dot/bin/dot-dieu43-fs-init.sh     138 lines  (Tier B, Phase 2)
/opt/incomex/dot/bin/dot-dieu43-fs-verify.sh   124 lines  (Tier A, Phase 2)
/opt/incomex/dot/bin/archive/
  - README.md (invalidate note)
  - dot-context-pack-build-v1-1-INVALIDATED-2026-04-17.sh (v1.1 archived)

1.2 — PG directus DB (Phase 1 đã done — SCHEMA v1.1)

  • context_trigger_sources: 6 rows
  • dot_operations: 20 rows
  • context_pack_requests: 0 rows
  • context_pack_manifest: 0 rows
  • context_pack_sections: 0 rows (FK v1.1 CHECK enum, SẼ cần migrate v1.2 FK section_code)
  • v_context_pack_latest: view (v1.1)

1.3 — v1.2 extensions CHƯA tồn tại

  • Tables: context_pack_section_definitions MISSING, context_pack_health_checks MISSING, dot_config MISSING (xem Q1 dưới)
  • Role: context_pack_readonly MISSING
  • Config: 7 dot_config keys Đ43 §5.9 MISSING

1.4 — Tools OS VPS

Tool Status
sha256sum OK (coreutils 9.4)
curl OK 8.5.0
jq OK 1.7
ln OK (atomic rename support)
find / stat / awk / sed / realpath OK
docker (postgres container) OK, psql 16.13
python3 OK (có thể dùng cho rendering)
mmdc (Mermaid CLI) MISSING (fallback grep)
shellcheck MISSING

1.5 — KB Agent Data

  • Endpoint: https://vps.incomexsaigoncorp.vn/api (health 200)
  • Auth: X-API-Key header từ /opt/incomex/docker/.env (AGENT_DATA_API_KEY + AGENT_DATA_URL)
  • Endpoints chính: GET /documents/{id}?full=true, POST /documents?upsert=true, GET /health, GET /kb/list?prefix=

2. THIẾT KẾ SCRIPT — THÀNH PHẦN + TRÁCH NHIỆM

Script chia 10 module logic (1 file .sh duy nhất, section rõ ràng bằng comment banner):

# Module Trách nhiệm Bước §6
M1 Bootstrap shebang, set -euo pipefail, globals, arg parse, usage, log helpers, error trap, exit trap (lock release), load KB env
M2 PG client run_pg_rw() (user=directus/incomex cho write) + run_pg_ro() (role=context_pack_readonly cho SQL executor); table_exists(), role_exists()
M3 KB client kb_get_document(path) → body, kb_upload(path, body, mime), kb_health() 7a/7d
M4 Config loader dot_config_get(key) → JSONB text, dot_config_list_array(key) → bash array, fail-fast khi key thiếu (CẤM fallback §6.X)
M5 Precheck PG health, KB health, 5-tier git_commit fallback, on-deploy gate (Đ41 §6.5) Bước 1
M6 Lock + request pg_try_advisory_lock(43,1), INSERT request (running/skipped), retry_count logic per §5.9 context_pack_retry_policy Bước 2
M7 Data gathering query_pg() đọc context_pack_scan_db_whitelist → loop (rỗng → pg_database catalog NT11); scan_fs() đọc context_pack_scan_paths Bước 3+4
M8 Section engine ★ Core — query section_definitions WHERE is_active=true ORDER BY order_index, dispatch data_source (pg_query/filesystem_scan/static/kb_query/custom), áp render_config contract (§5.7 P9 key whitelist, FAIL-FAST key lạ), render template từ template_kb_path (path whitelist), output $OUTPUT_ROOT/$build_id/$output_filename; SQL executor cho kb_query áp 5 guard §5.8 P8 Bước 5 (gen)
M9 Checksum + validate logical_checksum (strip <!-- VOLATILE HEADER ... --> block) + file_checksum (full sha256); validate min/max từ section_definitions, format validators theo format col; compare logical với v_context_pack_latest → skip unchanged Bước 5 (chk) + Bước 6
M10 Publish + release + repair 7a upload KB staging (path dynamic), 7b PG TX manifest+sections (KHÔNG partial), 7c symlink swap atomic (ln -sfn), 7d promote KB live (diff-by-checksum), 7e finalize UPDATE, 7f compensate KB fail (no cross-rollback), 7g repair mode, Bước 8 release Bước 7+8

2.1 — Main flow

parse_args -> load_kb_env -> M5 precheck -> M6 lock -> M7 gather
 -> M8 generate-sections -> M9 checksum+validate -> (compare_unchanged? exit 0)
 -> M10 publish(7a..7e) -> release(8)  [EXIT trap unlock]

Alternative: --repair-publish -> M10 repair_publish -> exit

2.2 — Output structure trong $OUTPUT_ROOT/<build_id>/

File list + sizes đều ĐỘNG từ context_pack_section_definitions. Seed v1.2 có 8 file nhưng KHÔNG hardcode: script render tất cả row is_active=true.

2.3 — Header volatile marker convention

  • Opening: <!-- VOLATILE HEADER — excluded from logical_checksum --> (có text trailing)
  • Closing: <!-- END VOLATILE HEADER -->
  • Logical checksum strip regex (sed): /<!-- VOLATILE HEADER/,/<!-- END VOLATILE HEADER -->/d (anchor opening loosely, closing exact) — đúng spec §7.1 v1.1 giữ nguyên v1.2

3. RUNTIME REQUIREMENTS

3.1 — Phase 1.5 BẮT BUỘC chạy TRƯỚC khi script build test được end-to-end

(Phase 1.5 KHÔNG thuộc scope Phase 4a)

Artifact Mô tả Block phase nào
Table dot_config Schema đầy đủ (key TEXT PK, value JSONB, description TEXT) — Đ35 v5.1 §4.1 KHOẢN 1B mô tả nhưng CHƯA có trên VPS P3 skeleton test, P5 live test
Seed 7 dot_config keys Đ43 §5.9 context_pack_scan_paths, scan_db_whitelist, watched_key_patterns, retry_policy, mode, output_root, grace_period_days P3 live test
context_pack_section_definitions + seed 8 rows + 2 CHECK path whitelist Seed §5.7 P3 live test (script query to render)
context_pack_health_checks + seed 9 rows builtin + 1 CHECK SQL path whitelist Seed §5.8 Phase 4b (verify.sh), không block build.sh
Role context_pack_readonly + GRANT DEFAULT PRIVILEGES cross-DB (directus + incomex_metadata) per §11 Bước 6.4 P10 rev 2 P3 live test khi có section data_source='kb_query' (M8 SQL executor)
Schema migrate context_pack_sections: v1.1 CHECK enum → v1.2 FK section_code -> section_definitions.code §5.4 Bước 7b INSERT sections (P4)
Schema migrate context_pack_requests: thêm retry_count, next_retry_at, last_error cols §5.2 Bước 8 retry logic (P5)

3.2 — Quyền + DB access

  • OS user chạy script: incomex (1001) — cron sẽ chạy dưới user này (Phase 6). Manual invocation root OK tạm.
  • PG users cần:
    • directus@directus — INSERT/UPDATE/SELECT trên context_pack_*, dot_config
    • incomex@incomex_metadata — SELECT kb_documents (read-only đã có)
    • context_pack_readonly cross-DB — CHỈ dùng cho M8 SQL executor khi data_source=kb_query
  • KB API: AGENT_DATA_API_KEY từ /opt/incomex/docker/.env

3.3 — Trace cho Phase 4b (verify.sh paired)

Build script phải để lại artifacts verify.sh đọc được:

  • context_pack_manifest row với 2 checksum đầy đủ
  • context_pack_sections 8+ rows với file_checksum_sha256 khớp FS
  • Symlink $OUTPUT_ROOT/current + previous valid
  • KB mirror path tương ứng kb_document_path column
  • health_status + publish_step columns để §9 H9 check state consistency

4. ĐIỂM DỄ GÃY NHẤT + XỬ LÝ

# Rủi ro Hậu quả Cách xử lý
R1 Checksum logical WRONG regex — dư/thiếu strip 1 ký tự Logical checksum thay đổi mỗi run → compare unchanged KHÔNG BAO GIỜ skip → build storms cron 3h vô ích vĩnh viễn Unit test trong P3: render 2 file cùng content khác timestamp → assert logical EQUAL + file DIFFER. Fixture pin regex.
R2 Template rendering trong bash thuần Bash sed/awk khó substitute JSONB nested + escape đúng cho markdown/JSON/Mermaid Plan: dùng python3 inline one-liner (có sẵn OS, không Node dependency). Bash load data, python render. Q4 cần Desktop confirm.
R3 SQL injection qua render_config/data User-controlled config → data exfil Config JSONB admin-only write qua dot-config-* DOT. KHÔNG dùng config value làm SQL string. M8 SQL executor chỉ load từ KB path whitelist + 5 guard §5.8. render_config.filters dùng như bash dict lookup, không concat SQL.
R4 2-phase publish half-state Mất điện giữa 7c và 7e → FS live + DB staging → H9 CRITICAL 7g repair 2 branch: (A) FS+KB OK → finalize UPDATE; (B) FS mismatch → ln -sfn previous + UPDATE failed. Idempotent.
R5 KB API flaky 1 file upload fail → state lệch 7a atomic batch 8 file: any fail → cleanup staging + abort trước 7b. 7d partial fail → kb_mirror='failed', KHÔNG rollback FS. Retry via context_pack_retry_policy queue.
R6 dot_config fallback vi phạm §6.X P2 Ẩn lỗi config dot_config_get() FAIL-FAST, exit 1 + log_fatal. CẤM pattern ${var:-default} cho config values.
R7 Bootstrap paradox: dot_config chưa tồn tại Script không chạy được lần đầu M5 precheck verify dot_config table + 7 keys. Thiếu → exit 3 + log hướng dẫn "chạy Phase 1.5 trước".
R8 KB key format / vs __ drift Sync pipeline normalize mâu thuẫn §6 wording Dùng patterns từ dot_config.context_pack_watched_key_patterns. Script normalize pattern REPLACE(pattern, '/', '__') nếu PG dùng __. Q6.
R9 Mermaid validate không có mmdc H7 fallback grep miss syntax errors tinh vi P3 fallback: grep -qE '^(graph|flowchart)' + balanced brackets. TD-S178-15 retrofit.
R10 section_count manifest không khớp file rendered CHECK > 0 v1.2 nhưng nếu 1 section fail validate thì 7 hay 8? M10 7b trong TX: section_count := COUNT(*) FROM section_definitions WHERE is_active=true. Nếu 1 section render fail → abort toàn build trước 7a. Confirm Q5.

5. CHIA P1-P5 + REVIEW FOCUS

P1 — Skeleton (15 phút)

  • Shebang + set -euo pipefail + error/exit traps
  • Header comment ~35 dòng: purpose, luật, paired, 11 fields Phase 5 v1.2 (cron_schedule là seed mặc định, domain=context.pack, operation=CONTEXT_PACK_BUILD), exit codes, TD list
  • M1+M2+M3+M4 skeleton stubs: bootstrap + PG/KB/config helpers đủ cho M5 gọi được
  • M5-M10 function stubs in "TODO"
  • Arg parse: --help, --dry-run, --trigger-source=<code>, --repair-publish, --verbose, --build-id=<id> (mới — repair mode target 1 build cụ thể?)
  • Tests: bash -n, --help, no-flag dry-run, unknown flag exit 2, invalid trigger exit 2, --repair-publish bypass, --dry-run PG down exit 3
  • Desktop review: header + flow order + exit codes + 11 fields v1.2

P2 — Bước 1-4 (20 phút)

  • M4 config loader fail-fast
  • M5 precheck: PG/KB health, 5-tier git_commit, on-deploy gate, verify 7 dot_config keys + dot_config table
  • M6 try-lock + INSERT request + retry_count §5.9
  • M7 query_pg (scan_db_whitelist loop → pg_database catalog) + scan_fs (scan_paths array)
  • Tests: dry-run Bước 1-4, PG down exit 3, lock busy coalesce, on-deploy gate missing, dot_config key missing fail-fast
  • Desktop review: config loader FAIL-FAST + §6.X compliance

P3 — Bước 5 GENERATE + 2 CHECKSUM ★ CRITICAL (25 phút)

  • M8 section engine: query section_definitions, dispatch data_source (pg_query/kb_query/filesystem_scan/static/custom), render_config contract FAIL-FAST key lạ, template path whitelist, output dynamic filename
  • Builtin pg_query handlers: project_map, dot_registry, entities_overview, db_map, architecture_mmd, project_map_json (6 sections)
  • kb_query handler with 5 guard §5.8 for SQL executor
  • M9 checksum: logical (sed strip) + file (full)
  • Tests: render 8 section live data; checksum unit (same content diff timestamp = logical EQUAL file DIFFER); render_config key lạ FAIL-FAST; path không whitelist REJECT; SQL có DELETE REJECT; SQL timeout 30s abort
  • Desktop review KỸ P3 — 2 checksum + 5 guard là nhạy cảm nhất

P4 — Bước 6 VALIDATE + Bước 7 PUBLISH ★★ SENSITIVE NHẤT (25 phút)

  • Validate min/max size, format validators, compare logical skip unchanged
  • 7a upload KB staging atomic batch (any fail → cleanup + abort)
  • 7b PG TX: INSERT manifest (section_count động) + 8 sections, KHÔNG partial
  • 7c atomic symlink swap (ln -sfn current + previous)
  • 7d promote KB diff-by-checksum
  • 7e finalize UPDATE live
  • 7f compensate KB fail (no cross-rollback)
  • 7g repair (detect post_fs_pre_db_finalize >15min → finalize OR rollback symlink, idempotent)
  • Tests: dry-run 7a-7e, real publish test build_id (manual cleanup), 7f giả lập KB fail, 7g giả lập state lệch, atomic swap test
  • Desktop review CỰC KỲ KỸ P4

P5 — Bước 8 + edge cases + integration (15 phút)

  • release: advisory_unlock, UPDATE request done, UPDATE dot_tools.last_executed (stub-safe cho Phase 5 register sau)
  • Retry §5.9 retry_policy on fail
  • Edge: PG/KB down, disk full, lock busy 2 instances, concurrent manifest insert, empty DB, timeout >10min
  • Idempotent verify: dry-run 2 consecutive = unchanged skip
  • shellcheck (hoặc justify warnings)

P6 — Report + backup + cleanup (10 phút)

  • Upload knowledge/dev/laws/dieu43-migrations/dot-context-pack-build.sh mirror
  • Upload knowledge/current-state/reports/phase4a-report.md 13 tiêu chí
  • Cleanup /tmp/dieu43-*, DELETE test rows

6. CÂU HỎI CẦN DESKTOP TRẢ LỜI TRƯỚC P1

Q1 — dot_config table CHƯA tồn tại trên VPS

Đ35 v5.1 §4.1 KHOẢN 1B mô tả bảng + function fn_is_in_grace_period dùng bảng này. Handoff §1.5 ghi "7 rows dot_config keys" (nghe như bảng có sẵn chỉ cần seed). Thực tế: SELECT ... FROM dot_config -> relation "dot_config" does not exist.

Quyết định cần:

  • (a) Phase 1.5 tạo bảng + seed 7 keys trước Phase 4a tiếp
  • (b) Nhét CREATE TABLE vào build.sh bootstrap (VI PHẠM tách biệt — script build không nên DDL)
  • (c) Tạo ngay trong P0 như side-task

Q2 — Role context_pack_readonly cross-DB GRANT

Ai/phase nào tạo role + GRANT? Role cluster-level, cần superuser. VPS không có postgres role. -U workflow_admin có là superuser? Cần verify Phase 1.5.

Q3 — On-deploy gate với vps_deploy_log vẫn missing (TD-S178-17)

Trigger on_deploy + table missing:

  • (a) permissive (log WARN, tiếp build) — Fix 11 P2 đã chọn
  • (b) strict (log_skip, exit 0)

Confirm v1.2 giữ (a)?

Q4 — Template rendering engine

  • (a) Bash sed/awk substitute (ASCII-safe only)
  • (b) python3 inline (mượn python có sẵn OS)
  • (c) khác

render_config.placeholder_style v1.2 seed = 'mustache' → (a) không support. Chọn (b)? Mustache engine nào? Hay thay default sang simpler?

Q5 — section_count trong INSERT manifest với partial render fail

Nếu 1/8 section validate fail (Bước 6):

  • abort toàn build (giữ live cũ) — vote của CLI theo §6.X "CẤM partial"
  • render 7/8 với section_count=7

Q6 — KB key format normalize (/ vs __)

Agent Data kb_documents.key dùng __. Script:

  • (a) Pattern từ context_pack_watched_key_patterns đã normalize __ trong JSONB
  • (b) Script tự normalize /__ khi dùng
  • (c) Đợi sync pipeline fix (TD-S178-18)

Q7 — Rev 2 P10 + P11 DDL artifacts

P10 cross-DB GRANT + P11 trigger function — ai làm? Phase 1.5 hay Phase 7 (trigger install)?


7. TUÂN THỦ LUẬT — CHECKLIST

7.1 — §6.X P1-P11 CẤM HARDCODE

Điểm Module Compliance plan
CẤM hardcode section list M8 Query section_definitions WHERE is_active=true
CẤM hardcode folder list M7 scan_fs Đọc dot_config.context_pack_scan_paths
CẤM hardcode DB list M7 query_pg Đọc scan_db_whitelist, rỗng → pg_database catalog
CẤM hardcode law pattern M8 laws_index Đọc watched_key_patterns JSONB
CẤM hardcode min/max size M9 validate Đọc min_size_bytes/max_size_bytes per row
CẤM hardcode health threshold Phase 4b (ngoài scope) build.sh KHÔNG set health_status qua hardcode
CẤM hardcode output root M1+M8+M10 Đọc output_root, apply $OUTPUT_ROOT
CẤM fallback hardcode default M4 config loader FAIL-FAST khi key thiếu, exit 1
CẤM switch-case hardcode check names Phase 4b Không ảnh hưởng build.sh
CẤM executor_type='sql' không 5 guard M8 kb_query Áp đủ 5 guard §5.8
P10 GRANT từng table Phase 1.5 ngoài scope Build.sh chỉ DÙNG role, không GRANT
P11 WHEN bind pattern Phase 7 trigger install Không ảnh hưởng build.sh

7.2 — 13 NT HP v4.6.2

NT Compliance
NT1 SSOT Mọi config từ dot_config + reference tables
NT2 Tự động 100% Thêm section = INSERT row, không sửa code
NT3 DOT 100% Script này LÀ DOT, register Phase 5
NT4 Thay đổi = config dot_config UPDATE → hiệu lực ngay build sau
NT5 Tự phát hiện retry_policy + health_checks + compare unchanged
NT7 Dual-trigger cron + 4 secondary triggers
NT8 Assembly First Query PG → render → KB upload
NT9 Không chắc = sai FAIL-FAST; 7 Q trên cần trả lời trước P1
NT10 PG Native section_definitions + health_checks + dot_config sống PG
NT11 Khai tối thiểu pg_database catalog thay hardcode 3 DB
NT12 DOT cặp Paired dot-context-pack-verify (Phase 4b) — §3.3 trace
NT13 PG Native Advisory lock PG native, JSONB config

7.3 — Rà NT 3 tầng (memory #29)

Plan nào CÓ THỂ lọt tầng 2 DDL? Câu trả lời: KHÔNG — build.sh không làm DDL, chỉ dùng.

  • Tầng 1 code: bash — rà bằng shellcheck ở P5
  • Tầng 2 DDL: N/A build.sh
  • Tầng 3 data seed: N/A build.sh (tạo row runtime qua INSERT — idempotent, không seed cứng)

8. SCOPE CLARIFY

Phase 1.5 là implicit prerequisite của Phase 4a. Nếu không tạo Phase 1.5 trước P3, P3 tests block ở precheck "dot_config missing".

Đề nghị:

  • Option A: Desktop ra prompt Phase 1.5 TRƯỚC P1 — tạo dot_config + role + section_definitions + health_checks + migrate v1.1→v1.2 schema
  • Option B: CLI P1+P2 với test "PG missing" mock OK, dừng trước P3; Desktop chạy Phase 1.5 rồi CLI tiếp P3
  • Option C: Script build.sh tự detect thiếu → stub config bằng env var cho dry-run test

CLI vote Option A vì separation of concerns (schema DDL ≠ DOT script).


P0 Design Plan — Đ43 Phase 4a v1.2 rev 2 — Claude CLI S178 Fix 12 — 2026-04-17