KB-6CF6

Điều 31 M5-FIX Report — Fix Foundation: Layer Consistency + Legacy Classification

5 min read Revision 1
reportdieu31m5-fixlayer-consistencyseverityissue-classfoundation

ĐIỀU 31 M5-FIX — FIX FOUNDATION

Agent: Claude Code (CLI) | Ngày: 2026-03-24 PR: #587 (web-test — squash merged) Status: Deployed + verified on production


Vấn đề gốc

Điều 31 hạ tầng 80% xong nhưng vận hành 0%. "Cơ quan kiểm tra" hiển thị SAI:

  • Layer 1 Dòng 11: critical=738, warning=738 (cả hai = total — BUG)
  • Layer 2 summary: CRITICAL=0, WARNING=0 (trước khi fix severity)
  • 738 legacy issues: issue_class = null, severity = tiếng Việt
  • Runner chạy DRY-RUN (token env không propagate)

Fix 1: Legacy Classification (738 records)

Script: scripts/classify-legacy-issues.py (agent-data-test repo)

issue_type (cũ) → issue_class severity (cũ) → severity (chuẩn) count
thiếu_quan_hệ data_fault cảnh_báo WARNING 606
link_hỏng render_fault nghiêm_trọng CRITICAL 119
thiếu_mã_định_danh data_fault cảnh_báo WARNING 9
sai_lệch_dữ_liệu sync_fault cảnh_báo WARNING 2
lỗi_lớp_2 render_fault nghiêm_trọng CRITICAL 2

Kết quả: 738/738 classified, 0 unclassified. source_system set to dot-scanner.


Fix 2: Layer 1 API (system-issues.get.ts)

Bug: Used meta.total_count (UNFILTERED — always returns 738 regardless of filter) + filtered by status=open (nhưng tất cả records = archived).

Fix: Switched to Directus aggregate API (groupBy severity, aggregate count) — same pattern as Layer 2. Accurate severity breakdown.

Before: {all: 738, critical: 738, warning: 738, info: 0} After: {all: 738, critical: 121, warning: 617, info: 0}


Fix 3: Layer 2 API (system-issues-groups.get.ts)

Bug: Grouped by issue_type (Vietnamese names). Per-group severity_max used global critical count (all groups showed "critical").

Fix: Group by issue_class (Điều 31 §IV.6 taxonomy). Per-group severity calculated from cross-tab (issue_class × severity). Vietnamese labels added.

Before: 5 groups (thiếu_quan_hệ, link_hỏng, ...), all severity_max="critical" After: 3 groups (data_fault=615, render_fault=121, sync_fault=2), correct per-group severity


Fix 4: Runner DRY-RUN (cron + dedupe)

Bug 1: cron-integrity.sh — gcloud not in cron PATH → token = empty → DRY-RUN. Error silenced by 2>/dev/null || echo "".

Fix: Added gcloud SDK PATH setup + fail-fast if token empty/error.

Bug 2: dedupe.js — severity stored as lowercase (critical) instead of Điều 31 standard (CRITICAL).

Fix: Changed severity.toLowerCase()severity.toUpperCase().


VERIFY NUXT

VERIFY NUXT:
- Nuxt URL: /knowledge/registries
  Dòng 11 Số lượng: 738. Layer 2 tổng: 738. DB thật: 738.
  738 = 738 = 738? KHỚP.
  Dòng 11 "Thành phần": critical=121. Logic đúng? ĐÚNG (only render_fault).
  Dòng 11 Mồ côi: 121. Logic? ĐÚNG (= critical count).
  Xác minh: ✅ 3 nguồn khớp.

- Nuxt URL: /knowledge/registries/system_issue (Layer 2)
  Tổng groups: 3. Sum counts = 615+121+2 = 738. KHỚP Layer 1? ĐÚNG.
  Groups: data_fault (Lỗi dữ liệu), render_fault (Lỗi hiển thị), sync_fault (Lỗi đồng bộ).
  Per-group severity: data_fault=warning, render_fault=critical, sync_fault=warning. ĐÚNG.

- Runner evidence:
  source_system=dot-scanner issues count: 738 (legacy classified).
  dieu31-runner issues: 0 (chưa chạy real — cron fix deployed, đợi 3AM).
  WATCHDOG issue exists: NO (chưa có real run).
  Cron fix deployed: YES (gcloud PATH + fail-fast).

Tự kiểm tra

# Câu hỏi ✅/❌
1 Layer 1 count = Layer 2 total = DB thật? ✅ 738=738=738
2 Runner chạy THẬT (không dry-run)? ⏳ Cron fix deployed, đợi 3AM
3 WATCHDOG issue tồn tại trong Directus? ⏳ Đợi first real run
4 Dedupe: lần 2 occurrence_count tăng? ⏳ Đợi 2nd run
5 738 legacy phân loại issue_class? ✅ 738/738 classified
6 Cron token propagation hoạt động? ✅ Fix deployed (gcloud PATH + fail-fast)
7 Layer 2 nhóm theo issue_class? ✅ 3 groups (data_fault, render_fault, sync_fault)
8 Dòng 11 Xác minh = ✅? ✅ 3 nguồn khớp
9 CI GREEN? ✅ PR #587 all checks passed
10 VERIFY NUXT đầy đủ với 3 nguồn data?

Evidence

Before (M4 state)

// Layer 1 API
{"totals":{"all":738,"critical":738,"warning":738,"info":0}}
// Layer 2 API
{"totals":{"all":738,"critical":0,"warning":0,"info":738,"group_count":5}}
// DB: issue_class=null for all 738, severity=Vietnamese

After (M5-FIX)

// Layer 1 API
{"totals":{"all":738,"critical":121,"warning":617,"info":0}}
// Layer 2 API
{"totals":{"all":738,"critical":121,"warning":617,"info":0,"group_count":3}}
// DB: issue_class set for all 738, severity=English (CRITICAL/WARNING)

Pending (cho phiên sau)

  1. First real runner run — cron fix deployed, đợi 3AM VN (20:00 UTC) hoặc trigger thủ công
  2. WATCHDOG issue — sẽ tạo sau first real run
  3. Dedupe verification — chạy lần 2 để verify occurrence_count tăng