KB-4893

S176-INVESTIGATE K1 — L1 Official Channels (DOT tools ghi PG)

20 min read Revision 1
s176investigateddldmlphaseCk1official-channels

title: "S176-INVESTIGATE K1 — L1 Chính thức: DOT tools ghi PG" sprint: S176 phase: INVESTIGATE block: K1 date: 2026-04-13 status: done tags: ['s176','investigate','ddl','dml','phaseC','k1','official-channels']

S176-INVESTIGATE · K1 — L1 Chính thức (DOT tools ghi PG)

Mục tiêu: trả lời "AI ghi PG qua con đường chính thức?" — liệt kê toàn bộ DOT đã đăng ký trong dot_tools, phân loại DDL/DML, kiểm tra pattern an toàn và tỉ lệ DOT cặp NT12. Chế độ: CHỈ ĐỌC. Không GRANT/REVOKE/ALTER.


1. Tổng quan dot_tools (272 records)

Phương pháp

  • GET /items/dot_tools?limit=-1 qua Directus REST (token admin login).
  • Field trả về: code, tier, domain, operation, paired_dot, trigger_type, script_path, file_path, last_executed, coverage_status, status.
  • Đối chiếu từng record với file thật tại dot/bin/ (cloud branch) bằng cross-ref basename.

Phân phối

Thuộc tính Giá trị Ghi chú
Tổng 272 Bao gồm cả trùng (xem #4)
Tier A (kiểm tra) 49 Theo lý thuyết = writer verifier
Tier B (hành động) 223 Writer
status=active 256
status=published 16
file_path set 212/272 (78%) 60 record KHÔNG có file_path
script_path set 119/272 (44%) Redundant với file_path
paired_dot set 107/272 (39%) NT12 gap — xem #5
last_executed set 157/272 (58%) 157/157 = cùng một timestamp 2026-03-31T08:08:57.064Z → bulk backfill, KHÔNG phải run log thật
coverage_status = complete 13/272 (5%) partial=158, =101

Domain top 10

collection=49  infrastructure.schema=38  infrastructure.sync=20  sync=16
monitoring.integrity=15  infrastructure.deploy=15  lifecycle=11  normative=11
workflow=10  data_quality=8  pivot=8  kg.*=34

Trigger type

∅=203  on-demand=31  cron=28  dual=4  manual=3  event=2  on-deploy=1

203/272 (75%) record KHÔNG khai trigger_type — coverage metadata yếu.


2. Phân loại theo con đường ghi PG

2.1 Con đường A — Directus REST API (/items/<collection>)

  • ~56 file trong dot/bin/ dùng curl / items/ / directus.*_item → Directus là gateway; Directus tự viết PG.
  • Đây mới là "L1 chính thức" theo NT13 "PG FIRST" + 5 tầng đồng bộ PG→Directus→Nuxt (Directus là cổng).
  • Mẫu: dot-collection-register, dot-task-*, dot-species-*, dot-registry-*, dot-nav-*, dot-content-*, dot-audit-create, dot-layer-integrity-audit, dot-id-collision-check, dot-knowledge-sync*.

2.2 Con đường B — Trực tiếp PG (run_pg()psqldocker exec postgres)

  • 12 script trực tiếp gọi psql. Pattern chuẩn:
    run_pg() { ssh root@VPS 'cd /opt/incomex/docker && docker compose exec -T postgres psql -U directus -d directus'; }
    
  • Với DDL bootstrap: chấp nhận được (L2 Tắt hợp lệ tạm) nếu có vòng đời retire.
  • Với DML runtime: đi vòng qua Directus → rủi ro bypass (L3 về bản chất, dù DOT có đăng ký).
# Script DOT code Tier Domain Op paired_dot Nội dung chính DDL cnt Loại
1 dot-schema-taxonomy-pg-apply DOT-143 + DOT_SCHEMA_TAXONOMY_PG_APPLY (trùng) B infrastructure.schema (num) / collection (sem) None / DOT-HEALTH-DOT CREATE TYPE, ALTER TABLE, CREATE INDEX, CREATE OR REPLACE FUNCTION (system_issues, registry_*) 28 DDL
2 dot-pg-views-ensure DOT-129 B infrastructure.schema None CREATE OR REPLACE VIEW (v_registry_counts v.v.) 12 DDL
3 dot-pg-triggers-ensure DOT-128 B infrastructure.schema None CREATE TRIGGER 6 DDL
4 dot-pg-audit-ensure DOT-127 B infrastructure.schema None CREATE TABLE audit + fn_audit + trigger 4 DDL
5 dot-label-trigger-setup DOT-123 B classification.label None CREATE TRIGGER label 2 DDL
6 dot-entity-retire DOT-112 B lifecycle None SELECT fn_transition_lifecycle(...) — DML qua function 0 DML (gateway)
7 dot-entity-deprecate DOT-111 B lifecycle None SELECT fn_transition_lifecycle(...) 0 DML (gateway)
8 dot-production-truth-gate DOT-109 B monitoring.integrity None psql SELECT (read-only?) 2 SELECT chủ yếu
9 dot-coverage-inspector DOT-110 A monitoring.integrity None run_pg SELECT 2 Checker (ĐÚNG tier)
10 dot-cron-pivot-setup DOT-308 B pivot None Cài cron gọi fn_refresh_orphan_* 10 phút/lần 3 Cron installer
11 dot-cron-matrix-setup KHÔNG REGISTER Cài cron 1 L3 candidate
12 dot-script-lint KHÔNG REGISTER Lint script có gọi psql 4 L3 candidate

2.3 Con đường C — PG function gateway (fn_*)

  • 79 function fn_* đã tồn tại trong schema public (pg_proc WHERE proname LIKE 'fn\_%').
  • 3 nhóm:
    1. Guard/validate/enforce (fn_guard_*, fn_enforce_*, fn_validate_*, fn_nrm_*_gate, fn_law_*_immutable) — trigger-based, bảo vệ invariants.
    2. Reconcile/refresh (fn_refresh_*, fn_reconcile_*, fn_sync_*) — vật chất hoá cache/count.
    3. Action (fn_transition_lifecycle, fn_bulk_transition, fn_gov_retire_cascade, fn_law_retire_cascade) — thực sự đổi state.
  • Đã có "phôi" gateway: fn_transition_lifecycle(collection, entity_id, new_state, reason, source) được dùng bởi DOT-111 + DOT-112. Đây là hạt giống cho Phương án C (Single Writer Gateway) — có thể đóng vai trò cổng duy nhất cho lifecycle transitions, nhưng hiện chỉ bao phủ retire/deprecate, không bao phủ create/update nội dung.

3. Pattern an toàn (anti-duplicate) — NT #14 / §0-AV

Kết quả grep

Chỉ số Số lần Nguồn
ON CONFLICT trong dot/bin/ 47 occurrences / 29 file grep
File dùng pattern "SELECT-rồi-IF-NOT-FOUND-INSERT" 12 file (multiline heuristic) grep

Tóm lược

  • Tất cả script DDL bootstrap (DOT-063..144, dot-pg-*-ensure) đều dùng CREATE TABLE IF NOT EXISTS + CREATE INDEX IF NOT EXISTS + CREATE OR REPLACE VIEW/FUNCTIONidempotent DDL, an toàn.
  • dot-pg-audit-ensure, dot-schema-taxonomy-pg-apply, dot-schema-dot-origin-ensure, dot-schema-trigger-registry-ensure, dot-schema-birth-registry-ensure dùng ON CONFLICT DO NOTHING/UPDATE cho seed row → tốt.
  • 12 file vẫn còn mẫu SELECT-then-INSERT (dot-orphan-scanner, dot-gov-seed, dot-nrm-enact, dot-collection-health, dot-matrix-declare, dot-collection-create, dot-pivot-declare, dot-schema-dot-origin-ensure, dot-birth-trigger-setup, v.v.). Race condition tiềm ẩn dưới tải, vi phạm NT "Nhầm được không?".
  • AP-12 risk (DOT verify phải so COUNT(*) thật): chưa check khối này ở K1 — để K4.

Phát hiện bất thường

  • dot-nrm-amend (không có file_path trong dot_tools nhưng tồn tại trên disk) dùng ON CONFLICT 2 lần — tốt — nhưng ghi trực tiếp PG bên ngoài Directus, vi phạm NT13 tinh thần "PG FIRST nhưng qua Directus".

4. Trùng đăng ký — 2 quy ước đặt tên

Phát hiện

  • 42 script bị đăng ký 2 lần trong dot_tools:
    • Lần 1 dưới code số: DOT-063, DOT-064, … DOT-144 — đợt sớm, naming DOT-NNN.
    • Lần 2 dưới code semantic: DOT_SCHEMA_APPLY, DOT_SCHEMA_BLOG_ENSURE, … DOT_SCHEMA_TAXONOMY_PG_APPLY — đợt sau, naming DOT_UPPER_SNAKE.
  • Tổng 42 pair × 2 = 84 record thừa. Unique thực tế ≈ 272 − 42 ≈ 230 DOT.
  • Không có luật nào quy định cái nào là canonical. DOT-NNNlast_executed nhồi bulk, DOT_SEMANTIC thường có last_executed=None.
  • Ví dụ xung đột:
    • dot-schema-taxonomy-pg-apply = DOT-143 (domain infrastructure.schema, paired=None) DOT_SCHEMA_TAXONOMY_PG_APPLY (domain collection, paired=DOT-HEALTH-DOT) → 2 bản ghi khác domain, khác paired, khác ý nghĩa.

Hệ quả

  • Khi query "DOT nào write bảng X" sẽ đếm trùng.
  • registry_changelog và NT11 "Khai tối thiểu" bị vi phạm: khai thông tin lặp.
  • Phải làm sạch trước khi thiết kế gateway (K3/DESIGN).

5. NT12 — DOT cặp (Cấp A kiểm tra Cấp B)

Số liệu

Chỉ số Giá trị Đánh giá
Writer (tier B) 223
Writer có paired_dot 75/223 = 33.6% 148 writer không có verifier
Writer có pair TRỎ ĐÚNG về tier-A 75/75 (100%) của nhóm có pair Khi khai thì khai đúng
Checker (tier A) 49
Checker có paired_dot 32/49 = 65% 17 checker không khai đối tượng kiểm tra
66% writer KHÔNG có DOT cặp Vi phạm NT12 ở quy mô lớn

Phân loại khuyết cặp

  • 38/38 DOT domain infrastructure.schema (DOT-063..DOT-144, tất cả dot-schema-*-ensure, dot-pg-*): toàn bộ paired_dot=None. Không có verifier cho bất kỳ DDL nào trong lớp bootstrap schema.
  • 20/20 DOT infrastructure.sync: phần lớn paired=None.
  • 15/15 DOT infrastructure.deploy: paired=None.
  • Cụm KG (kg.*)cụm Normative (nrm.*) có cặp đầy đủ nhất — do đây là các cụm ra đời muộn (S155-S159) khi luật cặp đã được ban hành.

Phát hiện bất thường

  • Toàn bộ 10 writer gọi PG trực tiếp (mục 2.2) đều có paired_dot=None. Các writer rủi ro cao nhất lại không có verifier → NT12 thất thủ ngay tại tuyến đầu.
  • DOT-COL-HEALTH tier A check nhưng paired_dot=None — không khai nó kiểm tra DOT nào → rỗng xích.
  • DOT trong cụm DOT_KG_*, DOT_NRM_* tier A có file_path=None — tồn tại dưới dạng metadata nhưng KHÔNG có script → tier A rỗng, verify không chạy được.

6. Scripts trong dot/bin/ KHÔNG nằm trong dot_tools — §0-AY

15 script mồ côi

Sau khi normalize (strip .ts/.js/.py) và cross-ref với file_path/script_path, còn 15 script trên disk không được dot_tools trỏ tới:

# Script Direct PG API calls Loại
1 dot-cron-matrix-setup ✓ (1) Cron installer (giống DOT-308 nhưng chưa đăng ký)
2 dot-script-lint ✓ (4) Linter có query PG
3 dot-doc-generate ✓ (4) Normative doc generate
4 dot-doc-partition ✓ (4) Doc partition
5 dot-doc-render ✓ (2) Doc render
6 dot-nrm-amend ✓ (5) Normative amend
7 dot-nrm-binding ✓ (2) Normative bind
8 dot-nrm-config ✓ (3) Normative config
9 dot-nrm-discover ✓ (5) Normative discover
10 dot-nrm-enact ✓ (4) Normative enact
11 dot-nrm-impact ✓ (5) Normative impact
12 dot-nrm-lifecycle ✓ (5) Normative lifecycle
13 dot-nrm-retire ✓ (3) Normative retire
14 dot-nrm-sync ✓ (4) Normative sync
15 dot-nrm-verify ✓ (8) Normative verify

Cả 15 đều ghi PG trực tiếp, KHÔNG gọi Directus API.

Làm rõ cụm dot-nrm-*dot-doc-*

  • Trong dot_tools record metadata cho DOT_NRM_DISCOVER, DOT_NRM_VERIFY, DOT_NRM_IMPACT, DOT_NRM_LIFECYCLE, DOT_NRM_SYNC, DOT_DOC_PARTITION, v.v. nhưng file_path=None → metadata có, không link script.
    • Đây là L1 yếu: đăng ký tên nhưng không có trace file.
    • Từ góc độ §0-AY "Writer KHÔNG nằm trong dot_tools mà vẫn chạy" thì chúng ĐƯỢC đăng ký.
    • Từ góc độ audit pipeline (K4 sẽ check) thì KHÔNG TÌM ĐƯỢC script bằng join dot_tools.file_path.
  • dot-cron-matrix-setupdot-script-lint: Không có metadata hằng số nào trong dot_toolsL3 BYPASS thật.

Số liệu kết luận

  • 2 script L3 bypass thuần (dot-cron-matrix-setup, dot-script-lint).
  • 13 script L1 yếu (NRM + DOC): có metadata nhưng không có file_path → phải verify bằng code-grep, không đảm bảo audit.

7. Coverage gap — DOT cover hết nhu cầu chưa?

Chỉ số coverage_status do dot_tools tự khai

Trạng thái Số lượng Tỉ lệ
complete 13 4.8%
partial 158 58.1%
(không khai) 101 37.1%

→ Chính hệ thống tự nhận chỉ 4.8% DOT đạt mức "complete".

last_executed không đáng tin

  • 157/272 record có last_executed = 2026-03-31T08:08:57.064Z (đúng đến mili-giây) → đây là kết quả bulk-set bởi một migration chạy ngày đó, KHÔNG phải log thực thi thực tế.
  • 115 record last_executed=None.
  • Không thể trả lời câu hỏi "DOT X có thực sự chạy không" từ dot_tools.last_executed → khớp với phát hiện K0 "không có dot_run_log".

Vùng "cần nhưng không có"

Dựa vào dữ liệu PG/Directus + các script bypass, 4 nhóm CẦN nhưng không có DOT verifier chính thức:

  1. Normative writes (nrm_*, law_* tables): 9 tier-B writer trực tiếp PG (dot-nrm-*). Có tier-A metadata nhưng file_path trống → verifier "rỗng".
  2. Schema bootstrap (infrastructure.schema, 38 DOT): toàn bộ paired=None. Không có "schema drift checker" tự động chạy sau mỗi DDL.
  3. Cron installer (dot-cron-*-setup): chỉ dot-cron-pivot-setup có trong registry, dot-cron-matrix-setup bypass. Không có DOT theo dõi vòng đời cron đã cài.
  4. Doc partition / render (dot-doc-*): ghi PG bảng normative_* nhưng không đăng ký file_path.

Vùng cover tốt nhất

  • KG (knowledge graph) — ra đời muộn (S159), có đủ cặp tier-A ↔ tier-B ở mức metadata.
  • Task sync — các DOT dot-task-* đều đi qua Directus API → L1 đầy đủ.

Kết luận

  • KHÔNG cover hết. Có 3 nguyên nhân đồng thời:
    1. DOT cũ (đợt DOT-001..DOT-150, trước S148) không tuân luật cặp → di tích.
    2. Lớp schema bootstrap về bản chất khó có verifier tự nhiên (DDL idempotent không cần "check sau khi tạo").
    3. Cụm normative/doc đi thẳng PG bỏ qua Directus → L1 yếu.
  • Người viết bị buộc tự tạo writer riêng khi:
    • Directus không có collection cho domain đó (đúng với normative_* vì phần lớn tables PG-only).
    • Cần gọi function/trigger PG mà Directus REST không expose.
  • Đây là bằng chứng "Directus không cover hết nhu cầu writer" — đẩy đến L2/L3.

8. Tổng hợp ma trận L1 (phần điền được ở K1)

Writer (DOT code) Bảng/Object Thao tác Credential L1/L2/L3 H1/H2/H3 Paired
DOT-143 dot-schema-taxonomy-pg-apply system_issues, registry_* (types/constraints) DDL (ALTER/CREATE/FN) × 28 docker exec postgres (user directus) L2 (bootstrap idempotent) H3 (last_touch 2026-03-31) None
DOT-129 dot-pg-views-ensure v_* views DDL CREATE OR REPLACE VIEW × 12 docker exec postgres L2 H3 None
DOT-128 dot-pg-triggers-ensure triggers DDL × 6 docker exec postgres L2 H3 None
DOT-127 dot-pg-audit-ensure audit tables + fn DDL × 4 docker exec postgres L2 H3 None
DOT-123 dot-label-trigger-setup label triggers DDL × 2 docker exec postgres L2 H3 None
DOT-112 dot-entity-retire directus_* items lifecycle DML qua fn_transition_lifecycle docker exec postgres L1 (gateway partial) H3 None
DOT-111 dot-entity-deprecate idem idem idem L1 partial H3 None
DOT-109 dot-production-truth-gate SELECT only read docker exec postgres L1 (read) H3 None
DOT-110 dot-coverage-inspector (A) SELECT only read docker exec postgres L1 (read checker) H3 None
DOT-308 dot-cron-pivot-setup installs cron → fn_refresh_orphan_* DML via scheduled fn docker exec postgres L1 (installer) + L2 residual cron H3 None
dot-cron-matrix-setup cron matrix DDL/DML docker exec postgres L3 BYPASS H3
dot-script-lint ? psql docker exec postgres L3 BYPASS H3
dot-nrm-* (9) normative PG tables DML ON CONFLICT docker exec postgres L1 yếu (meta có, file_path trống) H3 có (metadata)
dot-doc-* (3) normative rendered docs DML docker exec postgres L1 yếu hoặc L3 H3 có (metadata)
~56 script Directus API mọi items/<coll> qua Directus ADMIN_TOKEN hoặc DIRECTUS_TOKEN L1 chuẩn H3 75/223 có pair

9. Câu hỏi mở (chuyển K2-K4)

  1. Trùng đăng ký: có luật nào chọn DOT-NNN vs DOT_SEMANTIC là canonical không? Phải dedupe trước khi thiết kế gateway.
  2. Lớp dot-nrm-*dot-doc-*: tại sao không có file_path? Có phải cố tình (vì đi thẳng PG không kiểm soát được) hay là metadata chưa catch-up?
  3. Function fn_transition_lifecycle: có bao nhiêu entity state transitions hiện đi qua nó? Có bao nhiêu đi đường khác (UPDATE thẳng status column)? (K2)
  4. dot-script-lint gọi psql: nó đang linting cái gì? Có phải "audit tool" nhưng bản thân nó là bypass? (K2)
  5. Những DOT trong dot_toolsfile_path KHÔNG tồn tại trên disk (chiều ngược lại với §0-AY)? Cần check ở K4.
  6. coverage_status=partial 158 record: do ai đánh? Có tiêu chí chưa? (K4)

  • Backward: K0 — Timeline + Retention
    • Áp dụng: dùng mốc 2026-03-30 (DOT 100%) để gán H3 cho mọi last_touch > ngày này.
    • Áp dụng: vì không có dot_run_log, last_executed không đáng tin → chuyển tất cả "có last_executed" thành "nghi vấn H3" trong ma trận.
  • Forward:
    • K2 sẽ quét code toàn repo (không chỉ dot/bin/) để bắt bypass writers (scripts/, server/, agent-data/, layers portal, Directus flows).
    • K3 sẽ \du PG để check quyền user directus và so sánh với 79 fn_* — xem các function nào SECURITY DEFINER (phôi gateway).
    • K4 sẽ check: Directus Flows có raw SQL không; migration scripts on-deploy; code dead còn ghi MySQL/Firestore; writer không tên.

11. Evidence trích dẫn

# Directus REST
GET /items/dot_tools?limit=-1  → 272 records
GET /fields/dot_tools          → 28 fields (tier, paired_dot, coverage_status, ...)

# Distribution
tier={'A':49,'B':223}
status={'active':256,'published':16}
coverage_status={'partial':158,'∅':101,'complete':13}
last_executed={'2026-03-31T08:08:57.064Z':157, None:115}

# Direct PG writers (grep psycopg|asyncpg|docker exec postgres|psql)
dot/bin/dot-script-lint             ← NOT in dot_tools
dot/bin/dot-cron-matrix-setup       ← NOT in dot_tools
dot/bin/dot-cron-pivot-setup        DOT-308
dot/bin/dot-entity-retire           DOT-112  (→ fn_transition_lifecycle)
dot/bin/dot-entity-deprecate        DOT-111  (→ fn_transition_lifecycle)
dot/bin/dot-production-truth-gate   DOT-109
dot/bin/dot-coverage-inspector      DOT-110 (tier A)
dot/bin/dot-label-trigger-setup     DOT-123
dot/bin/dot-schema-taxonomy-pg-apply DOT-143 + DOT_SCHEMA_TAXONOMY_PG_APPLY (dup)

# DDL counters
dot-schema-taxonomy-pg-apply: 28
dot-pg-views-ensure:          12
dot-pg-triggers-ensure:        6
dot-pg-audit-ensure:           4
dot-label-trigger-setup:       2

# ON CONFLICT presence (anti-duplicate pattern)
47 occurrences / 29 files (positive — idempotent)
12 files still have SELECT-then-INSERT multiline pattern (race risk)

# Pairing
Writers(B)=223, with paired_dot=75 (33.6%) → 148 writers without verifier
Checkers(A)=49, with paired_dot=32 (65%)
100% of paired_dot strings on tier-B resolve to existing tier-A record

# Unregistered scripts (disk − dot_tools)
15 scripts (all direct PG, zero via Directus API)
Of these: 2 hard-bypass (cron-matrix, script-lint), 13 L1-weak (nrm-*, doc-*)

# PG gateway prototype
SELECT COUNT(*) FROM pg_proc WHERE proname LIKE 'fn_%'
→ 79 functions (guards + reconcile + transitions)
fn_transition_lifecycle(collection, entity_id, new_state, reason, source)
fn_bulk_transition(5 args)
fn_refresh_orphan_{species,dot,col}, fn_refresh_species_per_level → scheduled by DOT-308 cron

12. Trạng thái

  • K1 DONE. Chờ duyệt để chuyển sang K2 (L3 BYPASS — quét toàn repo ngoài dot/bin/).
  • Không chỉnh sửa code/schema/quyền. Toàn bộ query là SELECT / GET.
  • Đề xuất cho K2 khi duyệt: sẽ grep scripts/, server/, agent-data-test/, web-test/web/, infra/, directus/ cho psycopg/asyncpg/psql/Directus flow exec; verify 9 writer S175; đối chiếu với danh sách 15 unregistered tại K1.