KB-476B

Phân Tích Đồng Bộ Chí Mạng — S140

6 min read Revision 1
synccriticalS140vectordirectusagent-dataheartbeatblind-spots

Phân Tích Đồng Bộ Chí Mạng — S140 Huyên Directive

v1.0 | 2026-03-26 S140. Huyên: "Chí mạng. Cần câu trả lời rõ ràng và chắc chắn." SSOT: search_knowledge("sync critical analysis S140")


KIẾN TRÚC ĐỒNG BỘ HIỆN TẠI

HƯỚNG 1: Directus → Agent Data (27 Flows)
  ├── 21 [DOT-REG] Registry sync (7 collections × 3 events)
  ├── 6 [DOT] Task/Comment sync (2 collections × 3 events)
  └── Mechanism: Directus Flow → HTTP request → AD API → PG + Qdrant

HƯỚNG 2: Agent Data → Directus (Event system)
  ├── knowledge_documents sync via webhook ≤15s
  └── Mechanism: event_system.py → webhook → Directus update

HƯỚNG 3: Agent Data → Qdrant (Vectors)
  ├── Realtime embedding on doc create/update
  └── Mechanism: AD API → OpenAI embedding → Qdrant upsert

HƯỚNG 4: Directus Internal (13 Auto-ID)
  └── items.create → auto-assign PREFIX-NNN code

7 LỖ HỔNG CHÍ MẠNG

1. 27 Directus Flows Liveness — MÙ HOÀN TOÀN [CRITICAL]

  • 27 flows sync data Directus → AD. Nếu 1+ flow chết âm thầm → Directus data thay đổi nhưng AD không cập nhật.
  • Hiện tại: KHÔNG có monitor. Flows có thể fail silently (Directus 11.5.1 exec ops fail silently).
  • Hậu quả: AD stale. Vector search trả kết quả cũ. Registry info sai.
  • Scanner A5: Chỉ check count (AD ≥ Directus). Count KHỚP ≠ content đúng.

2. Event System (event_system.py) Liveness — BASIC [CRITICAL]

  • event_system.py crash → AD → Directus knowledge sync đứt.
  • Hiện tại: /api/health chỉ check enabled=true, listeners=1. KHÔNG test event thật fire.
  • Hậu quả: Knowledge docs trong AD cập nhật nhưng Directus knowledge_documents stale.

3. Content Sync Correctness — MÙ [CRITICAL]

  • Count khớp ≠ nội dung khớp. Record A sửa trong Directus nhưng AD vẫn giữ version cũ.
  • Hiện tại: KHÔNG có content comparison. Scanner chỉ đếm.
  • Hậu quả: Sai lệch thông tin giữa 2 hệ thống. User nhìn Directus thấy 1, AI search thấy khác.

4. Duplicate Detection — CHƯA BUILD [HIGH]

  • dot-duplicate-engine (Điều 14) = PLANNED (TD-083). Chưa xây.
  • Directus Flow fire 2 lần → AD có 2 docs cho 1 entity → không ai biết.
  • Hậu quả: Search trả duplicate. Count sai. Entity confusion.

5. Lớp 2 Safety Net — CHƯA TRIỂN KHAI [CRITICAL]

  • Thiết kế có 3 tool: dot-orphan-scan, dot-registry-diff, dot-registry-crosscheck.
  • Thực tế: Tool TỒN TẠI nhưng KHÔNG CÓ CRON. Phải chạy bằng tay.
  • Hậu quả: Lớp 1 (Flows) fail → Lớp 2 KHÔNG tự phát hiện. Vi phạm §0-AI (tự động tối đa).

6. Vector Pipeline Health — BASIC [HIGH]

  • Scanner A6: ratio < 2.0. NHƯNG: vector embedding fail → count giảm CHẬM → detect trễ.
  • Qdrant internal health: chỉ ok/not ok. Không check index corruption, search quality.
  • Hậu quả: Search trả kết quả sai nhưng ratio "OK".

7. AD → Directus Knowledge Sync — MÙ [HIGH]

  • Event system ghi knowledge_documents. KHÔNG CÓ check ngược.
  • AD có 590 docs, Directus knowledge_documents có bao nhiêu? Không ai so.
  • Hậu quả: Directus UI hiện thông tin cũ cho knowledge.

PHƯƠNG PHÁP LUẬN 3 TẦNG

Tầng 1: HEARTBEAT (phát hiện trong 6h)

"Sync pipeline còn sống không?"

-- PG table mới: sync_heartbeats
CREATE TABLE sync_heartbeats (
  flow_name TEXT PRIMARY KEY,
  flow_type TEXT, -- 'directus_flow', 'event_system', 'cron_job'
  last_success_at TIMESTAMPTZ,
  last_error TEXT,
  expected_interval INTERVAL DEFAULT '1 hour'
);

-- Mỗi Directus Flow cuối chain → UPDATE heartbeat
-- Event system → UPDATE heartbeat mỗi cycle
-- Cron jobs → UPDATE heartbeat mỗi run

-- Scanner check: pipeline nào stale?
-- Thêm vào measurement_registry: MSR-SYNC-HEARTBEAT
SELECT flow_name, flow_type, 
  NOW() - last_success_at as stale_duration,
  CASE WHEN NOW() - last_success_at > expected_interval 
    THEN 'STALE' ELSE 'ALIVE' END as status
FROM sync_heartbeats;

Tầng 2: CROSS-CHECK (phát hiện trong 6h)

"Dữ liệu khớp không?"

-- Per-collection count comparison: Directus vs AD
-- Scanner check: MSR-SYNC-COUNT per collection
-- Directus side: SELECT COUNT(*) FROM {collection}
-- AD side: query AD API count per registries/{collection}/*

-- Sample content check (5 random records per collection):
-- Directus updated_at vs AD doc updated_at
-- Nếu chênh > 1h → content drift → CRITICAL

Tầng 3: RECONCILIATION (phát hiện trong 24h)

"Đầy đủ chưa?"

Daily full scan:
1. Directus → AD: iterate ALL records per 7 synced collections
   → verify AD doc exists with matching content
2. AD → Directus: iterate ALL knowledge_documents
   → verify Directus record exists
3. AD → Qdrant: iterate ALL docs
   → verify vector exists + embedding age < 7 days
4. Output: reconciliation report + system_issues for mismatches

GIẢI PHÁP ASSEMBLY FIRST

Lỗ hổng PG/Directus giải quyết Code mới
Flow liveness PG table sync_heartbeats + Directus Flow tail step Scanner measurement MSR-SYNC-HEARTBEAT
Event system PG heartbeat from event_system.py Scanner check
Content correctness PG query sample records + compare Scanner measurement
Duplicate PG UNIQUE constraint + duplicate scan dot-duplicate-engine (Điều 14)
Lớp 2 Safety Net Cron schedule cho dot-orphan-scan, dot-registry-diff Crontab entries
Vector pipeline PG log embedding results + scanner check health endpoint expand
AD→Directus PG count both sides Scanner measurement

ROADMAP FIX

S167H:     Chaos test + audit (liệt kê đầy đủ gaps) — ĐANG LÀM
S168:      Fix sync monitoring (heartbeat table + scanner measurements)
S168b:     Cron Lớp 2 tools (orphan-scan, registry-diff, crosscheck)
S169:      Điều 32 Luật Registries
S170:      Điều 14 dot-duplicate-engine

S140 Huyên: "Hệ thống đáng tin cậy = câu trả lời chắc chắn cho mỗi câu hỏi đồng bộ."