KB-5CBF

S176-INVESTIGATE K2 — L3 Bypass Writers

30 min read Revision 1
s176investigateddldmlphaseCk2bypass

title: "S176-INVESTIGATE K2 — L3 Bypass Writers" sprint: S176 phase: INVESTIGATE block: K2 date: 2026-04-13 status: done tags: ['s176','investigate','ddl','dml','phaseC','k2','bypass']

S176-INVESTIGATE · K2 — L3 Bypass Writers

Mục tiêu: quét toàn bộ repo (ngoài dot/bin/) tìm mọi writer ghi PG. Gắn L1/L2/L3 + H1/H2/H3 cho từng writer. Chế độ: CHỈ ĐỌC. Không sửa code/schema/quyền. Phát hiện lớn: Scope S176 không chỉ là DB directus — cluster postgres4 database.


0. Mở rộng scope: 4 database trong cluster postgres

Trước khi vào chi tiết, phải ghi nhận: K0/K1 chỉ điều tra DB directus, nhưng cluster PG thực tế có nhiều hơn.

-- ssh root@38.242.240.89 → docker exec postgres psql -U directus -d directus
SELECT datname, pg_get_userbyid(datdba) AS owner FROM pg_database;
Database Owner Ghi chú
directus workflow_admin DB chính — mọi phân tích K0/K1 ở đây
incomex_metadata workflow_admin Agent Data document store (9 table, phần lớn owner incomex)
workflow workflow_admin Rỗng (\dt → no relations) — dormant DB
postgres workflow_admin Default

Tables trong incomex_metadata:

 chat_messages            | incomex      <- DML writer: agent_data/pg_store.py
 cron_heartbeat           | incomex
 kb_audit_log             | incomex
 kb_documents             | incomex
 kb_documents_history     | incomex
 metadata_store           | incomex
 kb_config                | workflow_admin
 trigger_guard_alerts     | workflow_admin
 trigger_guard_exceptions | workflow_admin

Có 2 PG user active: directus (K0/K1) và incomex (K2 phát hiện). K3 sẽ làm rõ quyền.


1. Phương pháp

  • Grep toàn repo /Users/nmhuyen/Documents/Manual Deploy/web-test (không node_modules) + /Users/nmhuyen/agent-data-test.
  • Patterns: psycopg2|psycopg|asyncpg|pg\.Pool|new Pool|pg\.Client|INSERT INTO|ALTER TABLE|CREATE TABLE|DROP TABLE|UPDATE.*SET|DELETE FROM|docker exec.*postgres|PGPASSWORD|psql -U.
  • Verify 9 S175 writers theo danh sách K0 prompt.
  • Kiểm tra Directus Flows (/flows + /operations) xem có raw SQL / exec / webhook bypass.
  • Đối chiếu mỗi hit với dot_tools (từ K1) để gắn nhãn L1/L2/L3.

2. Kết quả — phân vùng theo thư mục

2.1 scripts/integrity/ — Runner Điều 31 (Node.js)

File: scripts/integrity/pg-client.js (228 dòng)

const { Client } = require('pg');
async function connect() {
  const connStr = process.env.DATABASE_URL;   // postgres://incomex:***@postgres:5432/directus
  client = new Client({ connectionString: connStr, ssl: false });
}
async function logMeasurementResult(runId, measurementId, result, srcVal, tgtVal, delta) {
  await client.query(
    `INSERT INTO measurement_log (run_id, measurement_id, result, source_value, target_value, delta)
     VALUES ($1, $2, $3, $4, $5, $6)`, [...]);
}

Bảng ghi: directus.public.measurement_log (INSERT only). Credential: DATABASE_URL → user incomex (xác nhận qua sql/s134_pg_grants.sql). Trigger: cron 0 */6 * * * scripts/integrity/cron-integrity.sh + post-deploy hook. Coverage trong dot_tools: KHÔNGpg-client.js và runner main.js không có record nào trong dot_tools.

Đồng đội:

  • scripts/integrity/dedupe.jsKHÔNG ghi PG trực tiếp, dùng Directus API POST/PATCH /items/system_issues (L1 via Directus). Tính vào "9 writer S175" dưới.
  • scripts/integrity/main.js — gọi pg-client.logMeasurementResult() + dedupeAndReport(). Là orchestrator.
  • scripts/integrity/runners/pg-vs-nuxt-check.js — tiêu thụ pg-client, read-only.

Nhãn L1/L2/L3:

File DDL DML Loại H Lý do
pg-client.js INSERT measurement_log L3 BYPASS (ghi PG directus.public trực tiếp, không qua Directus, không có DOT) H3 Điều 31 v2.0 (S133) — post-DOT-100%
dedupe.js + main.js system_issues create/update L1 via Directus H3 Nhưng orchestrator KHÔNG trong dot_tools → "L1 yếu"
runners/pg-vs-nuxt-check.js read-only L1 read H3

2.2 sql/ — 36 raw SQL migration files

Danh sách đầy đủ (36 file) được auto-apply bởi CI:

# .github/workflows/deploy-vps.yml dòng 197-222
for sql_file in "$MIGRATION_DIR"/*.sql; do
  if [ ! -f "$MARKER_DIR/$base.done" ]; then
    docker exec -i postgres psql -U directus -d directus < "$sql_file"
    touch "$MARKER_DIR/$base.done"
  fi
done

Cơ chế: marker one-shot (/opt/incomex/deploys/web-test/.sql-applied/*.done). Một khi đã apply, script sẽ skip — nhưng vẫn tồn tại trong repo vô thời hạn.

Nhóm theo nội dung (đọc file thứ tự):

Group Files Loại Ví dụ
Grants s134_pg_grants.sql DDL — GRANT GRANT SELECT,INSERT ON measurement_log TO incomex;
Measurement framework s133_*, s134_m5* DDL+DML s133_measurement_framework.sql tạo bảng measurement_*, trigger, policy
Pivot scaffolding s146_*, s147_*, s149_*, s167_*, s168_*, s170_* DDL+DML meta_catalog virtual rows, refresh functions
KB protection kb_protection_phase2_* DDL+DML trigger_guard_*, kb_audit_log
S161/S162 repair s161b_*, s162b_*, s164_* DML one-shot UPDATE/DELETE patches
S175 dedupe s175_law_dedupe_p1.sql, s175_source_id_current_unique_p2.sql DML direct UPDATE + DDL UPDATE public.knowledge_documents SET is_current_version=false WHERE id IN (...); với hardcoded ID
Legacy 0047c_antigravity_proposal.sql DDL+DML
Data dump vps_pg_schema_incomex_metadata_kb_20260405.sql pg_dump snapshot của incomex_metadata Không phải writer, là dump file để restore

Nhãn L1/L2/L3 toàn bộ thư mục sql/:

  • L2 "Tắt hợp lệ tạm" với điều kiện có vòng đời. Điều kiện chưa đạt: không có DOT retire file SQL sau khi apply; file nằm vĩnh viễn trong sql/. Marker .done chỉ ngăn chạy lại, không xoá file.
  • Không có DOT sql-migration-* nào đăng ký — CI workflow tự apply, không qua dot_tools.
  • Một số file là DML patch one-shot (s175_*, s161b_*, s164_*) — về bản chất L3 BYPASS vì:
    1. Không đi qua Directus API,
    2. Không có DOT tương ứng,
    3. Sửa trực tiếp user data (knowledge_documents, meta_catalog, system_issues),
    4. Không được audit bởi directus_activity.

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

  • vps_pg_schema_incomex_metadata_kb_20260405.sql — pg_dump header có dòng \restrict CXVxjNLuHYBTI14Sc... (restore key). Đây là file sensitive restore snapshot bị commit vào git. Tiềm ẩn rò rỉ schema.
  • s175_law_dedupe_p1.sql dùng hardcoded ID list (854, 986, 748, 752, 763, 874, 875, 880, 960, 993, 1004, 586, 1074) → nếu re-run ở DB khác sẽ UPDATE sai rows.

2.3 scripts/0047c_*.ts, scripts/0048_*.ts|.sql, scripts/e1-*.ts, scripts/migrate-s6-fields.ts

scripts/0048_link_policies_mysql.sql (H2 di tích MySQL)

INSERT INTO directus_access (id, role, user, policy, sort)
SELECT UUID(), '...', NULL, '...', 1
WHERE NOT EXISTS (SELECT 1 FROM directus_access WHERE ...);
  • Dùng UUID()WHERE NOT EXISTS → cú pháp MySQL, KHÔNG tương thích PG.
  • S115 Final Report (K0) nói "added DEPRECATED headers to 3 scripts 0047c_*.sh" nhưng KHÔNG đụng đến 0048_link_policies_mysql.sql.
  • Nếu CI deploy-vps.yml auto-apply .sql file này trên PG, sẽ lỗi cú pháp (không có function UUID() trong PG, phải là gen_random_uuid()). → Dead code hoặc đã fail một lần rồi marker bỏ qua.
  • Nhãn: H2 dead code, L3 nếu còn chạy. Cần check marker file trên VPS (K4).

scripts/0047c_migration_knowledge.ts, e1-*.ts, setup-directus-flows.ts — đi qua Directus SDK, L1 (có dry-run, idempotent).

scripts/migrate-s6-fields.ts, dieu31-m2-migrate.sh — migration one-shot, cần check có đang scheduled không.

2.4 scripts/s133-deploy-measurement.sh

cat sql/s133_measurement_framework.sql | docker exec -i postgres psql -U directus -d directus
  • Deploy wrapper cho s133_measurement_framework.sql — nhưng CI đã tự apply (mục 2.2). Script này trùng với CI auto-migration → cần 1 nguồn.
  • Không có trong dot_tools.
  • Nhãn: L2 manual emergency, H3. Nếu còn chạy = redundant.

2.5 scripts/vps/*.sh — 14 file trên VPS

File PG writes Nhãn
dot-kb-restore.sh run_pg()psql -U incomex -d incomex_metadata. Restore table data từ backup L2 (script khẩn cấp). Có metadata DOT_KB_RESTORE không? Chưa xác định — cần K4 check
dot-kb-verify.sh run_pg()psql -U incomex -d incomex_metadata. Audit check — paired với DOT_KB_PROTECT L1 (verify tier-A) — DOT_API_HEALTH tier-A có paired DOT_KB_PROTECT nhưng file_path=None → L1 yếu
backup-to-gdrive.sh docker exec postgres pg_dump -U directus -d directus L1 read-only (backup, không phải writer)
reconcile-tasks.sh chưa kiểm nội dung chưa verify
check-config-integrity.sh chưa kiểm chưa verify
ensure-code-backup-kuma-monitors.sh chưa kiểm chưa verify

2.6 crontab/production.crontab — 45 entries, 6 PG functions 10 phút/lần

*/10 * * * * cd /opt/incomex/docker && docker exec postgres psql -U directus -d directus -c "SELECT refresh_meta_catalog_from_pivot();"
*/10 * * * * docker exec postgres psql -U directus -d directus -c "SELECT refresh_pivot_results();"
*/10 * * * * docker exec postgres psql -U directus -d directus -c "SELECT fn_refresh_orphan_species(); SELECT fn_refresh_orphan_dot(); SELECT fn_refresh_orphan_col(); SELECT fn_refresh_species_per_level();"
0   5 * * * docker exec postgres psql -U directus -d directus -c "SELECT fn_expire_stale_approvals();"
30  4 * * * docker exec postgres psql -U directus -d directus -c "SELECT auto_apply_approval();"
*/10 * * * * docker exec postgres psql -U directus -d directus -c "SELECT refresh_matrix_results();"
  • 6 cron jobs gọi 6 PG function trực tiếp qua docker exec postgres psql -U directus.
  • Installer: chỉ dot-cron-pivot-setup (DOT-308) đăng ký, cài cron gọi fn_refresh_orphan_*. Các cron khác (meta_catalog, pivot_results, matrix_results, expire_stale, auto_apply) không có DOT installer đăng ký trong K1 — cần check ai cài.
  • Nhãn L1/L2/L3: L1 cho fn_refresh_orphan_* (installer DOT-308); còn lại L3 installer unknown — cron là side-effect, writer thực là PG function (gateway phôi).

Phát hiện bất thường: Cron dòng 0 2 * * * /opt/workflow/postgres/backup.sh trong infra/cron/incomex-crontab → không trùng file với crontab/production.crontab. Hai bản crontab cùng tồn tại trong repo — 1 live, 1 dead. Cần K4 verify file nào đang deploy trên VPS.

2.7 .github/workflows/deploy-vps.ymlCI bypass rõ ràng

Hai pattern:

(a) Auto-apply sql/*.sql (dòng 197-222):

for sql_file in "$MIGRATION_DIR"/*.sql; do
  docker exec -i postgres psql -U directus -d directus < "$sql_file"
  touch "$MARKER_DIR/$base.done"
done

→ Mỗi deploy, CI duyệt toàn bộ sql/ và apply file chưa có marker. Đây là con đường chính đưa 36 SQL file vào PGL2 (migration bootstrap) nếu có vòng đời, L3 nếu file vĩnh viễn.

(b) CAT-ALL update với guard bypass (dòng 328-336):

docker exec postgres psql -U directus -d directus -c "
  SELECT set_config('app.allow_meta_update', 'true', true);
  UPDATE meta_catalog SET record_count=(SELECT SUM(...)) WHERE code='CAT-ALL';
  UPDATE meta_catalog SET record_count=(SELECT SUM(...)) WHERE code='CAT-MOL';
  ... (6 UPDATE hardcoded codes)
"

Bypass có chủ đích qua session variable app.allow_meta_update=true. Có guard PG (fn_guard_meta_catalog_update, thấy ở K1) bảo vệ meta_catalog, nhưng CI dùng set_config để tắt guard trong session.

Đây là bằng chứng rõ ràng nhất của pattern "Directus không cover → tạo backdoor trong PG + tắt trong CI":

  1. Directus API patch vào meta_catalog sẽ bị guard block (đúng yêu cầu).
  2. CI cần update CAT-ALL sau deploy → không thể qua Directus → ghi thẳng PG với session bypass.
  3. Guard logic check current_setting('app.allow_meta_update') = backdoor.
  4. Comment trong refresh-counts.post.ts (K2 mục 2.9) xác nhận pattern này.

Nhãn:

Pattern L H Credential Tần suất
SQL auto-apply L2→L3 drift H3 SSH root→docker exec directus Mỗi deploy (1-5/ngày)
CAT-ALL bypass L3 BYPASS có chủ đích H3 SSH root→docker exec directus Mỗi deploy

2.8 web/server/api/registry/refresh-counts.post.ts — Nuxt endpoint

  • Đi qua Directus API PATCH /items/meta_catalog/:idL1 via Directus.
  • Comment trong code thừa nhận CAT-ALL không thể update qua đây → phải nhờ CI backdoor (mục 2.7 b).
  • Nhãn: L1 legit, nhưng phần CAT-ALL được đẩy sang L3 CI bypass.

2.9 agent-data-test/agent_data/pg_store.py — Agent Data writer

File: /Users/nmhuyen/agent-data-test/agent_data/pg_store.py (228 dòng)

import psycopg2
import psycopg2.pool

# Connection: postgresql://incomex:***@postgres:5432/incomex_metadata

def ensure_tables() -> None:
    CREATE TABLE IF NOT EXISTS kb_documents (key TEXT PRIMARY KEY, data JSONB ...);
    CREATE INDEX IF NOT EXISTS idx_kb_documents_doc_id ON kb_documents ...;
    CREATE TABLE IF NOT EXISTS metadata_store ...;
    CREATE TABLE IF NOT EXISTS chat_messages ...;

def upsert(tbl, key, data):
    INSERT INTO {tbl} (key, data) VALUES (%s, %s)
    ON CONFLICT (key) DO UPDATE SET data = EXCLUDED.data
  • Bảng ghi: incomex_metadata.public.{kb_documents, metadata_store, chat_messages}.
  • Credential: incomex user, hardcoded pool.
  • DDL: CREATE TABLE IF NOT EXISTS × 3 + 2 INDEX — idempotent, chạy mỗi lần start Agent Data.
  • DML: INSERT ... ON CONFLICT DO UPDATE — có pattern chống trùng (tốt).
  • Paired DOT: DOT_KB_PROTECT (event-triggered) + DOT_KB_VERIFY (cron 4am). Nhưng cả 2 metadata tier-A có file_path=None (K1 phát hiện L1 yếu).

Phân loại:

  • DB incomex_metadata KHÔNG thuộc scope Directus → không có "Directus API" để đi qua → mọi write PHẢI trực tiếp PG.
  • Agent Data là gateway duy nhất vào incomex_metadata theo thiết kế (giống như Directus là gateway vào directus).
  • Nhãn: L1 chuẩn (theo thiết kế Agent Data) cho pg_store.py, nhưng từ góc độ NT13 "PG FIRST" vs "Directus FIRST", đây là con đường song song không có DOT registry audit.

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

  • scripts/import_firestore_to_pg.pyhardcoded password: PG_PASSWORD=Incomex2026PG_306ac539ad365fce. Rò rỉ trong git history. Cần K3 verify password còn dùng không, có đổi chưa.

2.10 Directus Flows — SẠCH (không có raw SQL)

GET /flows?limit=-1  → 128 flows (111 active + 17 inactive)
  Trigger: event=121, schedule=5, webhook=2
GET /operations      → 320 operations
  Type distribution:
    log=108, item-create=78, request=50, item-read=44, exec=15,
    item-update=14, condition=7, trigger=2, item-delete=1, transform=1

Scan 15 exec ops: grep code field tìm INSERT|UPDATE|DELETE|ALTER|CREATE TABLE|pg|psql|psycopg|fetch|http|child_process|require|process.env|exec:

0/15 có raw SQL hoặc outbound call. Toàn bộ 15 exec ops là code generation cho assign_code (tăng code CAT-NNN, KB-NNN...) và flow_start entry points — pure JS logic, không ghi PG.

50 request ops:

  • 19 calls đến {{$env.AGENT_DATA_URL}}/documents?upsert=true — flows đẩy doc sang Agent Data (sync chain knowledge_documents → AD).
  • 2 calls đến https://ai.incomexsaigoncorp.vn/knowledge/*.
  • Còn lại đa phần self-call Directus (lookup last code).

Kết luận Directus Flows: KHÔNG phải nguồn bypass. Tất cả 78 item-create + 14 item-update + 1 item-delete đi qua Directus item ops = L1. 15 exec ops là JS pure. Flows "sạch" hoàn toàn.


3. Verify 9 writer S175 (theo yêu cầu K0 prompt)

# Writer Nơi Tồn tại? Credential L H Ghi chú
1 dedupe.js scripts/integrity/dedupe.js via Directus API (DIRECTUS_TOKEN) L1 via Directus H3 Không trong dot_tools, orchestrator L1 yếu
2 dot-collection-health dot/bin/dot-collection-health Directus API L1 H3 DOT-COL-HEALTH tier A, paired=None (K1)
3 dot-apr-health dot/bin/dot-apr-health Directus API L1 H3 DOT-311 tier A
4 dot-layer-integrity-audit dot/bin/dot-layer-integrity-audit Directus API L1 H3 Registered K1
5 dot-registry-crosscheck dot/bin/dot-registry-crosscheck Directus API L1 H3 Registered K1
6 dot-pg-audit-ensure dot/bin/dot-pg-audit-ensure docker exec postgres psql direct L2 (DDL bootstrap) H3 DOT-127 tier B, paired=None. Idempotent CREATE TABLE + fn_audit
7 dot-id-collision-check dot/bin/dot-id-collision-check Directus API L1 (read) H3 Registered K1
8 dedupeAndReport (#1 main.js:157, :221, :236, :330, :392, :417, :437) scripts/integrity/main.js via dedupe.js → Directus API L1 via Directus H3 7 call sites trong main.js
9 dedupeAndReport (#2) idem idem idem idem Phần "#1+#2" trong prompt K0 trỏ cùng function; K2 đếm 7 invocation sites

Tất cả 9 writer còn tồn tại. Không có "zombie" bị xoá. Tồn tại nhất quán với trạng thái trong repo.

Credential tổng hợp cho cụm S175:

  • Node.js integrity runner: DATABASE_URL (→ incomex user, trực tiếp PG directus.public.measurement_log) DIRECTUS_TOKEN (→ Directus API ghi system_issues).
  • Pattern 2 cửa: cùng 1 process có 2 credential, 2 đường ghi — khó dedupe quyền.

4. Phát hiện bất thường (tổng hợp)

  1. Scope PG thực tế = 4 database, không phải chỉ directus. Mọi cân nhắc REVOKE phải tính cả incomex_metadata.
  2. 2 PG user (directus, incomex) chia sẻ cluster. s134_pg_grants.sql grant cho incomex quyền SELECT+INSERT+UPDATE trên một số bảng trong DB directuscross-DB cross-user coupling.
  3. CI auto-apply sql/*.sql qua docker exec postgres psql -U directus -d directus < file.sql — bypass thẳng mọi DOT, mọi flow, mọi Directus guard. 36 file đang nằm vĩnh viễn trong sql/.
  4. CI CAT-ALL UPDATE với app.allow_meta_update session bypass — guard PG có backdoor có chủ đích, CI tận dụng. Cần K3 confirm logic guard đọc current_setting(...).
  5. scripts/integrity/pg-client.js là writer L3 thuần: Node.js pg lib, connect trực tiếp user incomex, INSERT thẳng measurement_log. Không qua Directus, không có DOT.
  6. agent-data-test/scripts/import_firestore_to_pg.pyhardcoded password PG: Incomex2026PG_306ac539ad365fce. Rò rỉ trong git history. Xem K3.
  7. sql/vps_pg_schema_incomex_metadata_kb_20260405.sqlpg_dump snapshot commit vào repo — có \restrict <token> key. Nhạy cảm.
  8. scripts/0048_link_policies_mysql.sql dùng MySQL UUID() — sẽ fail trên PG. Dead code nếu auto-apply. Cần check marker K4.
  9. infra/cron/incomex-crontab dead crontab vẫn còn gọi mysql-backup.sh, /opt/workflow/postgres/backup.sh. Nếu deploy sẽ đánh nhau với crontab/production.crontab. Di tích H2.
  10. 6 cron PG function trong production.crontab — chỉ 1 có installer DOT (DOT-308). 5 installer khác không xác định ai cài — có thể manual setup trên VPS.
  11. dedupe.js là L1 via Directus nhưng orchestrator chính (main.js) không trong dot_tools — cả hệ thống Điều 31 integrity runner không được audit qua DOT registry, vi phạm §0-AY tinh thần.
  12. refresh-counts.post.ts self-documenting bypass: comment trong code nói rõ "Directus API PATCH is blocked by guard. CAT-ALL is updated by deploy step (ssh: docker exec postgres psql with app.allow_meta_update bypass)". Bypass được tài liệu hoá, ai cũng biết — không phải shadow, là "known hack".

5. Phân loại tổng hợp (K2)

# Writer / script DB target DDL/DML Credential L H Ghi chú
1 scripts/integrity/pg-client.js + main.js directus DML INSERT measurement_log PG user incomex (DATABASE_URL) L3 BYPASS H3 Không trong dot_tools. Điều 31 runner
2 scripts/integrity/dedupe.js directus DML system_issues via API Directus token L1 via API H3 Orchestrator ngoài dot_tools → L1 yếu
3 scripts/integrity/runners/pg-vs-nuxt-check.js directus read incomex L1 read H3
4 .github/workflows/deploy-vps.yml — SQL auto-apply directus Bulk DDL+DML cho sql/*.sql SSH→docker exec directus L2→L3 drift H3 36 file, marker-based
5 .github/workflows/deploy-vps.yml — CAT-ALL UPDATE directus DML UPDATE meta_catalog + set_config SSH→docker exec directus L3 BYPASS chủ đích H3 session var app.allow_meta_update
6 sql/s175_law_dedupe_p1.sql directus DML UPDATE knowledge_documents CI auto-apply L3 H3 Hardcoded ID list
7 sql/s175_source_id_current_unique_p2.sql directus DDL+DML CI auto-apply L2 H3
8 sql/s161b_archive_*, s162b_*, s164_* directus DML one-shot UPDATE/DELETE CI auto-apply L3 H3 Patch style
9 sql/0047c_antigravity_proposal.sql directus DDL+DML CI auto-apply L2 H2-H3 Legacy
10 sql/0048_link_policies_mysql.sql directus DML INSERT directus_access (MySQL cú pháp) CI auto-apply (nếu chạy sẽ fail) H2 dead code H2 UUID() không có trong PG
11 sql/kb_protection_phase2_*.sql incomex_metadata? DDL trigger_guard_* + trigger CI auto-apply L2 H3 Target DB chưa verify trong file
12 sql/vps_pg_schema_incomex_metadata_kb_20260405.sql incomex_metadata pg_dump snapshot CI auto-apply (?) Sensitive restore file H3 Không phải writer, là dump
13 scripts/s133-deploy-measurement.sh directus DDL+DML (wrapper cho s133_*.sql) SSH L2 redundant H3 Trùng với CI auto-apply
14 scripts/vps/dot-kb-verify.sh incomex_metadata read/verify (psql → incomex) incomex user L1 yếu (paired DOT_KB_PROTECT file_path None) H3 Cron 4am
15 scripts/vps/dot-kb-restore.sh incomex_metadata DDL+DML restore incomex user L2 (emergency) H3
16 scripts/vps/backup-to-gdrive.sh directus pg_dump read directus user L1 read H3 Backup
17 crontab/production.crontab — 6 PG fn calls */10 directus DML via fn_* directus user L2 + 1 có installer (DOT-308) H3 5 còn lại installer unknown
18 infra/cron/incomex-crontab — MySQL/workflow backup H2 dead H1-H2 Dead code
19 agent-data-test/agent_data/pg_store.py incomex_metadata DDL CREATE IF NOT EXISTS + DML upsert incomex user (psycopg2) L1 chuẩn (AD gateway) nhưng không audit DOT H3 Service startup
20 agent-data-test/scripts/import_firestore_to_pg.py incomex_metadata DML bulk INSERT incomex user, hardcoded pw L2 (one-shot migration) H2 (S109 Firestore retire) Password leak
21 web/server/api/registry/refresh-counts.post.ts directus DML via Directus PATCH NUXT_DIRECTUS_SERVICE_TOKEN L1 via Directus H3
22 dot/bin/dot-script-lint (K1 phát hiện) directus psql SELECT (lint) docker exec directus L3 BYPASS H3 Không trong dot_tools
23 dot/bin/dot-cron-matrix-setup (K1) directus cron installer docker exec directus L3 BYPASS H3 Không trong dot_tools

Tổng writer ngoài dot/bin ghi PG: ~10 file core (exclude sql/*.sql as CI-managed batch). Bypass rõ ràng L3 chủ đích: 4 pattern (integrity pg-client, CI CAT-ALL bypass, CI SQL auto-apply với file L3, dot-script-lint/cron-matrix-setup).


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

  1. app.allow_meta_update session variable: logic guard đọc ở đâu? function nào? Tạo bởi SQL nào? (K3)
  2. 36 file sql/: bao nhiêu đã có marker .done trên VPS? File nào còn hiệu lực? (K4 — cần SSH check /opt/incomex/deploys/web-test/.sql-applied/)
  3. 5 cron PG function không có installer DOT (refresh_meta_catalog_from_pivot, refresh_pivot_results, fn_expire_stale_approvals, auto_apply_approval, refresh_matrix_results): ai cài, qua script nào, có manual setup không? (K4)
  4. User incomex quyền thật trên DB directus: ngoài s134_pg_grants.sql, còn GRANT nào không? (K3 \du + SELECT FROM information_schema.role_table_grants)
  5. incomex_metadata có được Directus API access không? Hay hoàn toàn private cho Agent Data? (K3)
  6. Password leak scripts/import_firestore_to_pg.py: còn dùng không? (K3 verify trên VPS .env)
  7. 0048_link_policies_mysql.sql có marker .done không? Có từng apply thành công không? (K4)
  8. dedupe.js + main.js (Điều 31 runner): có kế hoạch đăng ký vào dot_tools không? Nếu có DOT tương ứng thì là code nào? (K4)
  9. infra/cron/incomex-crontab — có deploy target không, hay dead file trong repo? (K4)

  • Backward: K1 — Official Channels
    • Áp dụng: mọi phát hiện K1 về dot_tools được làm giàu bằng danh sách K2 "ngoài dot/bin/".
    • 15 script unregistered K1 + ~10 writer K2 ngoài dot/bin = tổng ~25 writer cần đối chiếu với gateway design.
  • Forward:
    • K3 sẽ liệt kê quyền PG thực tế (\du, role_table_grants, table_owner), đối chiếu với các credential K2 đã phát hiện (directus user, incomex user, DATABASE_URL, hardcoded pw).
    • K3 cũng sẽ kiểm kê fn_* (79 từ K1 + thêm) xem cái nào SECURITY DEFINER — tức đang đóng vai trò gateway ngầm.
    • K4 verify markers .sql-applied, dead code 0048_mysql, infra/cron/incomex-crontab, 5 cron installer không rõ.

8. Evidence trích dẫn

# 4 databases
SELECT datname, pg_get_userbyid(datdba) FROM pg_database;
→ directus|workflow_admin  incomex_metadata|workflow_admin  workflow|workflow_admin (empty)  postgres

# incomex_metadata tables
kb_documents kb_documents_history metadata_store chat_messages cron_heartbeat kb_audit_log (owner: incomex)
kb_config trigger_guard_alerts trigger_guard_exceptions (owner: workflow_admin)

# scripts/integrity/pg-client.js
const { Client } = require('pg');
const connStr = process.env.DATABASE_URL;
await client.query(`INSERT INTO measurement_log (run_id, measurement_id, ...) VALUES (...)`, [...]);

# sql/s134_pg_grants.sql
GRANT SELECT ON law_catalog TO incomex;
GRANT SELECT ON measurement_registry TO incomex;
GRANT SELECT, INSERT ON measurement_log TO incomex;
GRANT UPDATE ON measurement_registry TO incomex;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO incomex;

# sql/s175_law_dedupe_p1.sql
UPDATE public.knowledge_documents SET is_current_version=false
WHERE id IN (854, 986, 748, 752, 763, 874, 875, 880, 960, 993, 1004, 586, 1074);

# sql/0048_link_policies_mysql.sql — MySQL syntax
INSERT INTO directus_access (id, role, user, policy, sort)
SELECT UUID(), '...', NULL, '...', 1
WHERE NOT EXISTS (SELECT 1 FROM directus_access WHERE ...);

# .github/workflows/deploy-vps.yml L197-222 (SQL auto-apply)
for sql_file in "$MIGRATION_DIR"/*.sql; do
  docker exec -i postgres psql -U directus -d directus < "$sql_file"
  touch "$MARKER_DIR/$base.done"
done

# .github/workflows/deploy-vps.yml L328-336 (CAT-ALL bypass)
docker exec postgres psql -U directus -d directus -c "
  SELECT set_config('app.allow_meta_update', 'true', true);
  UPDATE meta_catalog SET record_count=... WHERE code='CAT-ALL';
  UPDATE meta_catalog SET record_count=... WHERE code='CAT-MOL';
  UPDATE meta_catalog SET record_count=... WHERE code='CAT-CMP';
  UPDATE meta_catalog SET record_count=... WHERE code='CAT-MAT';
  UPDATE meta_catalog SET record_count=... WHERE code='CAT-PRD';
  UPDATE meta_catalog SET record_count=... WHERE code='CAT-BLD';
"

# web/server/api/registry/refresh-counts.post.ts — self-documented bypass
// CAT-ALL is updated by deploy step (ssh: docker exec postgres psql with app.allow_meta_update bypass).

# Directus Flows scan
GET /flows  → 128 (111 active, 17 inactive; 121 event, 5 schedule, 2 webhook)
GET /operations → 320 (log=108, item-create=78, request=50, item-read=44, exec=15, item-update=14, ...)
exec ops = 15/15 pure JS code generation (assign_code, flow_start), 0 raw SQL

# agent-data-test/agent_data/pg_store.py
Connection: postgresql://incomex:***@postgres:5432/incomex_metadata
CREATE TABLE IF NOT EXISTS kb_documents ...
INSERT INTO {tbl} (key, data) VALUES (%s, %s) ON CONFLICT (key) DO UPDATE SET data = EXCLUDED.data

# agent-data-test/scripts/import_firestore_to_pg.py
PG_USER=incomex
PG_PASSWORD=Incomex2026PG_306ac539ad365fce   # HARDCODED LEAK

# crontab/production.crontab — 6 PG fn calls
*/10 * * * * docker exec postgres psql -U directus -d directus -c "SELECT refresh_meta_catalog_from_pivot();"
*/10 * * * * docker exec postgres psql -U directus -d directus -c "SELECT refresh_pivot_results();"
*/10 * * * * docker exec postgres psql -U directus -d directus -c "SELECT fn_refresh_orphan_species(); SELECT fn_refresh_orphan_dot(); SELECT fn_refresh_orphan_col(); SELECT fn_refresh_species_per_level();"
0   5 * * * SELECT fn_expire_stale_approvals();
30  4 * * * SELECT auto_apply_approval();
*/10 * * * * SELECT refresh_matrix_results();

9. Trạng thái

  • K2 DONE. Chờ duyệt để chuyển sang K3 (Credentials + quyền PG thực tế).
  • Không sửa gì. Toàn bộ là SELECT / GET / grep.
  • Đề xuất K3 focus: \du, role_table_grants cho cả 4 DB, list fn_* với SECURITY DEFINER, map credential nguồn .env/GSM/secret → writer.