Audit #003 — 2026-08-15
Chấm theo Audit Standard AS-01..AS-10 v0.2 (255 chỉ báo, 10 bộ, AS-04 có 6 tiêu chí) trên một snapshot ghim tại commit 70e80a9 (branch main), cộng production thật (D1 nemo12-platform remote, GitHub Actions thật qua gh run list/gh api, Cloudflare Queues thật) — snapshot vì thư mục làm việc chính đang bị ~10 phiên AI khác chỉnh sửa liên tục trong lúc chấm.
Bối cảnh: đây là lần chấm thứ ba. Audit #001 (57dc4fa, chuẩn v0.1/250 chỉ báo): 109/250 (44%). Audit #002 (89a3db4, chuẩn v0.2/255 chỉ báo): 157/255 (61,6%), Pilot Gate 12/18 → NO-GO, 6 chỉ báo chặn (AS-07.1.1, AS-07.3.2, AS-04.6.3, AS-04.5.5, AS-03.5.3, AS-10.3.1). Giữa #002 và #003: một đợt vá trực tiếp nhắm đúng 6 chỉ báo đó (nhánh pilot-gate-fix, đã merge), cộng vài việc khác (xoá 2 dòng mồ côi migration, viết docs/ops/backup-restore-drill.md, thêm câu cấm apply migration ngoài CI vào README), cộng nhiều commit không liên quan từ các phiên AI khác vẫn chạy song song (tính năng mới, sửa UI…). Snapshot #003 là trạng thái cộng dồn của tất cả, không chỉ phần vá.
Phương pháp: ba lượt chấm độc lập được hợp nhất theo đúng thứ tự ưu tiên — (1) chấm gốc theo cả 10 bộ (255/255 chỉ báo có bằng chứng, không chỉ báo nào bị bỏ sót so với audit-standard/index.md nên không cần tự chấm bổ sung), (2) chấm sâu riêng 18 chỉ báo 🚸 Pilot Gate, (3) một lượt phản biện chạy lại 67 chỉ báo bằng lệnh độc lập (không tin lời agent trước). Với mỗi chỉ báo: verdict của phản biện thắng nếu có chạm tới; nếu không, verdict Pilot Gate thắng nếu chỉ báo thuộc 18 chỉ báo đó; còn lại dùng verdict chấm gốc. Kết quả: 178/255 chỉ báo giữ nguyên verdict chấm gốc, 10/255 dùng verdict Pilot Gate (8 trong số 18 chỉ báo Pilot Gate bị phản biện chạm và ghi đè tiếp), 67/255 dùng verdict phản biện.
1. Tổng kết
| Bộ | PASS/tổng | % | Mức |
|---|---|---|---|
| AS-01 Tài liệu & Đóng vết | 17/25 | 68% | Đang dựng |
| AS-02 Yêu cầu & Sản phẩm | 19/25 | 76% | Vững |
| AS-03 Kiến trúc & Hợp đồng API | 20/25 | 80% | Vững |
| AS-04 Dữ liệu & Migration | 19/30 | 63% | Đang dựng |
| AS-05 Trí tuệ học tập & Thuật toán | 19/25 | 76% | Vững |
| AS-06 Nội dung & Tri thức | 12/25 | 48% | Sơ khai |
| AS-07 Bảo mật, Riêng tư & Tuân thủ | 19/25 | 76% | Vững |
| AS-08 Tin cậy & Vận hành | 17/25 | 68% | Đang dựng |
| AS-09 Trải nghiệm & Design System | 10/25 | 40% | Sơ khai |
| AS-10 AI Governance & Chi phí | 20/25 | 80% | Vững |
| Toàn hệ | 172/255 | 67,5% | Đang dựng |
Mức trưởng thành: Sơ khai < 50% │ Đang dựng 50-69% │ Vững 70-84% │ Chín 85-94% │ Chuẩn mực ≥95%
AS-03 ████████████████░░░░ 80%
AS-10 ████████████████░░░░ 80%
AS-02 ███████████████░░░░░ 76%
AS-05 ███████████████░░░░░ 76%
AS-07 ███████████████░░░░░ 76%
AS-01 ██████████████░░░░░░ 68%
AS-08 ██████████████░░░░░░ 68%
AS-04 █████████████░░░░░░░ 63%
AS-06 ██████████░░░░░░░░░░ 48%
AS-09 ████████░░░░░░░░░░░░ 40%Điểm hệ so với sàn REQ-DOC-06 (≥225/255, ~88%): 172/255 = 67,5% — thiếu 53 chỉ báo để chạm sàn mở người dùng thật theo REQ-DOC-06 (giảm từ 68 chỉ báo thiếu ở #002 — tiến 15 chỉ báo trong khoảng thời gian giữa hai lần chấm). Đây là ngưỡng dài hạn, không phải điều kiện cho một đợt pilot ngắn cụ thể — điều kiện đó là Pilot Gate (§4 dưới đây).
Điều kiện release (dài hạn, §3.1 audit-standard/index.md): KHÔNG ĐẠT — còn 2/30 chỉ báo 🔴 KHÔNG PASS (xem §3), 2 bộ dưới 60% (AS-06 48%, AS-09 40%), điểm hệ 67,5% < 70%. Rất gần ngưỡng "Vững" (70%) nhưng chưa chạm.
2. Đọc đúng — tách KHÔNG PASS theo mã lý do
| Mã | Số lượng | % trong tổng 83 KHÔNG PASS |
|---|---|---|
| HH (hỏng — có phản ví dụ thật) | 47 | 56,6% |
| CX (chưa xây) | 26 | 31,3% |
| CM (chưa chứng minh) | 10 | 12,0% |
Chỉ số đáng lo thật sự là %HH = 56,6% — gần như nguyên trạng so với #002 (57%). Nghĩa là hơn một nửa số điểm trừ vẫn là "có bằng chứng cụ thể cho thấy sai", không phải "chưa kịp làm". Về số tuyệt đối, tổng KHÔNG PASS giảm từ 98 (#002) xuống 83 (#003, −15), và cả ba loại đều giảm nhẹ về số tuyệt đối (HH 56→47, CX 29→26, CM 13→10) nhưng tỷ lệ HH/tổng gần như không đổi — hệ đang đóng nợ đều ở cả ba loại, không thiên lệch về phía dễ (CM) hay tránh phía khó (HH).
3. 🔴 Chặn release — 30 chỉ báo (v0.2), 2 đang KHÔNG PASS
| Chỉ báo | Mã | Sự thật quan sát được |
|---|---|---|
| AS-06.4.3 | CX | 0 đề thi thật (source_kind='real') tồn tại trong production — không có gì để spot-check lời giải tự biên soạn so với nguồn |
| AS-08.4.3 | HH | deploy-api.yml bước "Apply D1 migrations" có if: github.event_name == 'workflow_dispatch' — SKIP trên 19/20 lần chạy push gần nhất (gh run view 31898121357: Apply=skipped, Deploy=success). Đọc thứ tự dòng lệnh thì apply đứng trước deploy (đúng như #002 từng chấm PASS), nhưng đọc thứ tự thi hành thật trên đường push chuẩn (không phải workflow_dispatch thủ công) thì migration không hề chạy trước khi code deploy — bất biến chỉ đứng vững nhờ một lần dispatch tay tình cờ chạy sát giờ audit |
28/30 🔴 còn lại đã PASS, bao gồm cả 4/6 chỉ báo Pilot Gate từng chặn ở #002 (AS-04.6.3, AS-04.5.5, AS-03.5.3, AS-07.1.1 — đối chiếu chi tiết ở §6) và 2 chỉ báo mới/nâng cấp còn lại của AS-04.6 (AS-04.6.1, AS-04.6.4).
Cảnh báo quan trọng — một 🔴 "ẩn" khỏi Pilot Gate do lỗi soạn thảo của chính chuẩn: AS-08.4.3 mang tag 🔴🚸 ngay trong dòng của nó ở bảng AS-08.4, nhưng KHÔNG có mặt trong bảng "Pilot Gate — danh sách đầy đủ" ở cuối audit-standard/index.md (18 dòng, không có AS-08.4.3) — cùng kiểu không nhất quán mà chính dữ liệu chấm gốc đã ghi nhận cho AS-05.3.5 ở lần chấm này. Hậu quả: Pilot Gate theo đúng câu chữ của chuẩn đạt 18/18 (§4), nhưng rủi ro thật mà AS-08.4.3 đo — migration không được áp trước khi code deploy trên đường push chuẩn — chính là đúng loại lỗi đã gây ra sự cố production làm phát sinh AS-04.6 trong v0.2. Khuyến nghị coi đây là gate thứ 19 trên thực tế trước khi mở thử, dù về mặt kỹ thuật không nằm trong 18 chỉ báo bắt buộc.
4. 🚸 Pilot Gate — điều kiện mở thử
18/18 — 100% PASS theo đúng câu chữ của chuẩn v0.2.
| Chỉ báo | PASS? | Bằng chứng | Ghi chú |
|---|---|---|---|
| AS-07.1.1 | ✅ | Script đối chiếu toàn bộ route↔guard; curl production /v1/coral/labs → 401 | Fix thật |
| AS-07.2.1 | ✅ | authz.ts chốt quyền backend; mọi module chạm learner_id đều gọi canAccessLearner/tương đương | |
| AS-07.2.3 | ✅ | parent/authz.test.ts 22/22 PASS trên D1 thật, có case cross-family | |
| AS-07.3.2 | ✅ | Chuẩn v0.2 hiện hành đã tự đổi nội dung chỉ báo thành "ghi dấu vết, KHÔNG chặn" (SRC-137) | Không phải fix kỹ thuật — xem §6 |
| AS-07.1.4 | ✅ | admin/dolphin/coral đều 302 Cloudflare Access | |
| AS-04.6.1 | ✅ | 39 remote = 39 đĩa, diff rỗng; migration-reconciliation.md ≤7 ngày | |
| AS-04.6.3 | ✅ | Tự chạy độc lập: PRAGMA table_info khớp tuyệt đối 79/79 bảng | Fix thật, mở rộng hơn cả doc gốc |
| AS-04.6.4 | ✅ | 0 DROP/RENAME COLUMN toàn lịch sử; 0 ADD COLUMN NOT NULL thiếu DEFAULT | |
| AS-04.1.1 | ✅ | 39 file liên tục 0001-0039, CI enforce | |
| AS-04.5.5 | ✅ | backup-restore-drill.md tồn tại; spot-check độc lập 5/6 số khớp tuyệt đối | Fix thật |
| AS-03.5.3 | ✅ | 403 Pro xác nhận lại; README dòng 49 có câu cấm; 0 lệch migration mới | Fix thật |
| AS-08.4.1 | ✅ | 0 continue-on-error cho 3 bước Typecheck/Lint/Test; 313/313 test PASS thật | |
| AS-08.2.2 | ✅ | dead_letter_queue khớp; wrangler queues list xác nhận cả 2 queue tồn tại thật | |
| AS-01.4.1 | ✅ | gen:reference → 0 diff | |
| AS-03.2.4 | ✅ | contract:diff 140 route, 0 breaking change, ở cả 2 workflow | |
| AS-10.3.1 | ✅ | Q-129 ghi nhận: 0 route sản xuất chạm buildLearnerContext — AI vẫn không chạm learner data qua đường nào | Không phải fix — xem §6 |
| AS-10.3.5 | ✅ | context-builder.test.ts 12/12 PASS, cách ly A/B thật | |
| AS-10.4.1 | ✅ | createCandidate → item_versions candidate; INSERT INTO items chỉ 1 điểm, sau gate.ok |
Go/No-go theo đúng 18 chỉ báo của chuẩn: GO. Nhưng đọc §3 và §6 trước khi quyết định — 2 trong 18 dòng trên (AS-07.3.2, AS-10.3.1) là PASS bằng cách tài liệu hoá lại một khoảng trống chứ không phải đóng nó, và có một chỉ báo 🔴🚸 ngoài danh sách 18 (AS-08.4.3) đang KHÔNG PASS với rủi ro cùng loại sự cố production đã xảy ra trước đây.
5. Chi tiết theo chỉ báo (10 bộ, 255 chỉ báo)
AS-01 · 17/25 (68%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 | ❌ | HH | migrations/README.md §3 nói ngược thực tế; wrangler xác nhận 0031 tồn tại, 0022_whale không tồn tại. |
| 1.2 | ✅ | — | docs/intake.md 213 dòng; 143 dòng SRC-001..143 đủ 5 cột; dòng cuối khớp SRC-144. |
| 1.3 | ❌ | HH | 36/144 SRC id không có hit ngoài intake.md (khớp gần như tuyệt đối vòng trước). |
| 1.4 | ✅ | — | 143 dòng SRC duy nhất, liên tục 001→143; dòng cuối = max+1. |
| 1.5 | ❌ | HH | migrations/README.md là đặc tả, sai thực tế production. |
| 2.1 | ✅ | — | check-docs.mjs PASS, 73 docs sạch. |
| 2.2 | ✅ | — | 73/73 đủ 8 trường. |
| 2.3 | ✅ | — | 73 id duy nhất, lowercase, khớp vai trò. |
| 2.4 | ✅ | — | 0 type ngoài tập cho phép. |
| 2.5 | ✅ | — | 0 status ngoài tập, 0 deprecated. |
| 3.1 | ❌ | HH | 25 REQ ✔ không nằm trong satisfies[] nào — khớp chính xác danh sách gốc. |
| 3.2 | ✅ | — | 235 dòng REQ ✔, 0 thiếu QG-\d+. |
| 3.3 | ✅ | — | 0 tham chiếu SRC không tồn tại. |
| 3.4 | ❌ | HH | 2 file mồ côi: backup-restore-drill.md, reference/config.md — khớp chính xác. |
| 3.5 | ❌ | HH | REQ-LRN-19/20/21 thiếu khỏi §6. |
| 4.1 🔴🚸 | ✅ | — | Tự chạy gen:reference, git diff exit 0. |
| 4.2 | ✅ | — | 79/79 bảng khớp. |
| 4.3 | ✅ | — | 140 route khớp. |
| 4.4 | ✅ | — | 21/21 event khớp. |
| 4.5 | ✅ | — | 3/3 trang có dòng cảnh báo sinh tự động. |
| 5.1 | ✅ | — | 0 file active >90 ngày. |
| 5.2 | ❌ | HH | 5/5 commit không bump version; PRD-001 vẫn 0.6. |
| 5.3 | ✅ | — | 0 link gãy. |
| 5.4 | ❌ | HH | 3 hit thật trong audit #002 report, văn xuôi không có mốc tuyệt đối. |
| 5.5 | ✅ | — | 0 quyết định AI trôi nổi không gắn Q-id. |
AS-02 · 19/25 (76%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 | ✅ | — | REQ-ORC có subsection riêng tại PRD §5 dòng 372, đúng như 27 nhóm khác; conventions.md tự nhận không phải nguồn sự thật. |
| 1.2 | ❌ | HH | 4 hit đúng theo lệnh literal của chuẩn, L4 không cho lọc ngữ nghĩa. |
| 1.3 | ✅ | — | 0 dòng M?/S?/C?. |
| 1.4 | ✅ | — | 0 dòng Nguồn rỗng. |
| 1.5 | ✅ | — | 0 cặp ≥80%, cao nhất 75%. |
| 2.1 | ✅ | — | 83/83 US đúng format. |
| 2.2 | ✅ | — | 12 biến thể persona, resolve về 4 persona gốc. |
| 2.3 | ✅ | — | cột AC riêng, 0/83 rỗng. |
| 2.4 | ✅ | — | 0 hit tên bảng/hàm/biến kỹ thuật. |
| 2.5 | ✅ | — | 4/4 route mẫu tồn tại thật. |
| 3.1 | ✅ | — | 4 persona active đều có ≥1 JTBD. |
| 3.2 | ✅ | — | mọi JTBD có REQ phục vụ. |
| 3.3 | ✅ | — | 3 file onboarding riêng. |
| 3.4 | ❌ | HH | Octopus 0 hit trong SDD-011; REQ-SCH-10 trỏ SDD-011 làm nguồn. |
| 3.5 | ✅ | — | §8 bản đồ đủ 8 app, spot-check khớp. |
| 4.1 | ✅ | — | 230/230 REQ ✔ có SDD+QG. |
| 4.2 | ✅ | — | route /hai-dang có REQ dù thiếu ở §8 (không tính KHÔNG PASS). |
| 4.3 | ✅ | — | 0 dòng CC-/FEAT- trong bảng REQ chính. |
| 4.4 | ❌ | CX | legacy-feature-inventory.md không có cột Phân loại 4 giá trị. |
| 4.5 | ✅ | — | 3 REQ M ⏳/🔵 đều có lý do+ngày. |
| 5.1 | ✅ | — | 130 Q, 0 unresolved. |
| 5.2 | ❌ | HH | Parser lại: 10/29 dòng Lý do rỗng tuyệt đối (nặng hơn số cũ 9/25). |
| 5.3 | ✅ | — | artifact rà mâu thuẫn có ngày, luật ưu tiên, liệt kê 6 lệch, khai phạm vi. |
| 5.4 | ❌ | HH | bảng chỉ 2 cột, thiếu Trạng thái, xác nhận lại. |
| 5.5 | ❌ | CX | 0 kết quả 'Đã vào' trong file. |
AS-03 · 20/25 (80%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 | ✅ | — | 1 hit createRoute ngoài modules/, khớp bảng ngoại lệ. |
| 1.2 | ❌ | HH | Lệnh literal 135 hit nhưng toàn bộ là ../../env hoặc shared/* (khớp ngoại lệ chuẩn tự ghi); lệnh đúng độ sâu lộ 24 dòng import chéo qua 11-13 module. |
| 1.3 | ✅ | — | fetch( chỉ 5 file src/api.ts. |
| 1.4 | ✅ | — | 0 property tự định nghĩa lại trong app CSS. |
| 1.5 | ✅ | — | ls khớp README 1-1. |
| 2.1 | ✅ | — | 0 file openapi ngoài snapshot. |
| 2.2 | ❌ | HH | PATCH /v1/content/items/{itemId} chỉ có {401,409}, 0 response 2xx — route chủ ý luôn từ chối nhưng chuẩn không có carve-out. |
| 2.3 | ✅ | — | 125 path đều bắt đầu /v1. |
| 2.4 🔴🚸 | ✅ | — | contract:diff 140 route, 0 breaking change, ở cả 2 workflow. |
| 2.5 | ❌ | HH | Tự curl production: POST /v1/auth/google bad body → 400 rò ZodError; 404/401 khác vẫn đúng chuẩn. |
| 3.1 | ✅ | — | 21/21 entry có version+payload. |
| 3.2 | ✅ | — | đối soát 2 chiều khớp 100%. |
| 3.3 | ✅ | — | 21 tên event domain.entity.action, action thì quá khứ. |
| 3.4 | ✅ | — | assertNoFreeText tồn tại+được gọi, 0 z.string() trần. |
| 3.5 | ✅ | — | số khớp queues.md. |
| 4.1 🔴 | ✅ | — | Mở rộng pattern (AIza/sk-/xox/PRIVATE KEY) → 0 hit; .env.production commit chứa Google Client ID công khai, không phải secret thật. |
| 4.2 | ✅ | — | base URL chỉ trong api.ts, còn lại là host README hợp lệ. |
| 4.3 | ✅ | — | verify-bindings.mjs --offline Lớp A sạch. |
| 4.4 | ❌ | CM | thiếu CLOUDFLARE_API_TOKEN, lùi về A+B. |
| 4.5 | ✅ | — | verify-bindings.mjs Lớp B sạch. |
| 5.1 | ✅ | — | 9 wrangler.jsonc ↔ 9 deploy-*.yml. |
| 5.2 | ✅ | — | 9/9 custom_domain, 0 workers.dev. |
| 5.3 🚸 | ✅ | — | 403 xác nhận lại; README có câu cấm; diff disk-vs-remote rỗng ngay lúc chấm. |
| 5.4 | ❌ | HH | Cùng phản ví dụ AS-08.4.3 — 'apply trước deploy' chỉ đúng về dòng lệnh, không đúng về thi hành thật trên 19/20 lần push. |
| 5.5 | ✅ | — | 10/10 URL 2xx/3xx. |
AS-04 · 19/30 (63%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 🔴🚸 | ✅ | — | 39 file liên tục 0001-0039, CI enforce. |
| 1.2 | ✅ | — | 0 câu lệnh thật thiếu IF NOT EXISTS. |
| 1.3 | ✅ | — | 0 DELETE, 4 UPDATE có WHERE. |
| 1.4 🔴 | ✅ | — | migrate:dryrun 39/39 OK. |
| 1.5 | ✅ | — | No migrations to apply. |
| 2.1 | ✅ | — | 0 bảng thiếu PK. |
| 2.2 🔴 | ✅ | — | 0 REFERENCES users(email). |
| 2.3 | ❌ | HH | 68 cột *_id không REFERENCES (gần khớp 69 cũ); 0 hit miễn trừ trong data-dictionary.md. |
| 2.4 | ✅ | — | 0 lệch định dạng thời gian. |
| 2.5 | ✅ | — | 0 json_extract/LIKE trong WHERE/ORDER BY. |
| 3.1 | ✅ | — | 78/78 bảng thật có mô tả. |
| 3.2 | ❌ | HH | Parser độc lập: khớp CHÍNH XÁC 761 cột, 160 cột (21%) rỗng. |
| 3.3 | ❌ | HH | interaction_votes_rebuilt không tồn tại thật trên production (SELECT rỗng) nhưng có mục trong data-dictionary.md. |
| 3.4 | ❌ | HH | CHECK 8 giá trị bị cắt cụt trong data-dictionary.md, lỗi parser hệ thống lan sang cột kế tiếp. |
| 3.5 | ❌ | HH | community_events/community_event_registrations status enum 0 mục trong state-machines.md. |
| 4.1 | ❌ | HH | seed-labs.mjs mặc định remote trừ khi thêm --local; seed-orca-math.mjs/attach-figures.mjs luôn --remote, --yes không xác nhận. |
| 4.2 | ✅ | — | Tự setup D1 local sạch, chạy seed-labs 2 lần độc lập từ đầu: 71/71 cả 2 lần, không đổi. |
| 4.3 | ✅ | — | PRAGMA foreign_key_check rỗng (giá trị thông tin thấp vì AS-04.2.3 KHÔNG PASS). |
| 4.4 | ✅ | — | 4/4 UNIQUE index thật tồn tại. |
| 4.5 | ❌ | HH | subjects 4 + strands 20 thiếu name_en (khớp chính xác); skill_nodes 0 đạt riêng. |
| 5.1 | ❌ | HH | chỉ 10 bảng có retention_policies trên tổng 79 bảng thật. |
| 5.2 | ❌ | CX | chỉ có ghi nhận yêu cầu, không có code xoá thật. |
| 5.3 | ❌ | HH | state-machines.md §25 không có 365/keep_days; chính sách chỉ tồn tại trong retention_policies. |
| 5.4 | ❌ | CX | 0 mục §PII trong data-dictionary.md. |
| 5.5 🔴🚸 | ✅ | — | Đối chiếu số liệu độc lập với DB sống: 5/6 khớp tuyệt đối, items lệch có lý do hợp lý (ghi thêm liên tục); toán 79 vs 80 bảng tự giải thích được. |
| 6.1 🔴🚸 | ✅ | — | 39 remote = 39 đĩa, diff rỗng; migration-reconciliation.md ≤7 ngày. |
| 6.2 | ✅ | — | 0 dòng mồ côi hiện tại. |
| 6.3 🔴🚸 | ✅ | — | Tự chạy độc lập: 80 bảng chung, lệch text ở đúng 2 bảng (lịch sử ALTER), PRAGMA table_info khớp tuyệt đối từng cột. |
| 6.4 🔴🚸 | ✅ | — | 0 DROP/RENAME COLUMN toàn lịch sử; 0 ADD COLUMN NOT NULL thiếu DEFAULT. |
| 6.5 | ✅ | — | 39 khớp 39, không cần cảnh báo. |
AS-05 · 19/25 (76%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 | ❌ | HH | Constraint+Learning Plan Model chỉ 1 dòng bảng tổng, không trang riêng; cả hai đang chạy production thật (model_kind trong learner_model_versions). |
| 1.2 | ✅ | — | 7/7 model_kind có algorithm_version. |
| 1.3 | ✅ | — | COUNT=20>0, có generated_at. |
| 1.4 | ❌ | HH | engine_runs xác nhận constraint/planning chạy thật; 0 trang mô tả riêng. |
| 1.5 | ✅ | — | content_json bất biến, mọi thay đổi qua INSERT version mới. |
| 2.1 | ✅ | — | evidence ghi cùng batch với model update. |
| 2.2 🔴 | ✅ | — | 3 điểm INSERT learner_skill_state duy nhất; route self-report (warmup) chỉ INSERT learner_evidence, 0 lời gọi skill_state. |
| 2.3 | ✅ | — | reliability REAL NOT NULL, evidenceTier() phân loại rõ. |
| 2.4 | ❌ | CM | code hợp lý nhưng 0 test chứng minh. |
| 2.5 | ✅ | — | COUNT=22>0, started_at NOT NULL. |
| 3.1 | ❌ | HH | 0 hit runContextEngine/runReadinessEngine trong bất kỳ *.test.ts; chỉ đụng gián tiếp qua WF-04 chung. |
| 3.2 | ✅ | — | 0 test dùng readFileSync source-regex. |
| 3.3 | ✅ | — | test learner rỗng cho cả 7 model. |
| 3.4 | ✅ | — | test 3 lần chạy lặp không đẻ version vô hạn. |
| 3.5 🚸 | ✅ | — | ci.yml nguyên tắc "mỗi bước phải fail thật"; 0 continue-on-error/|| true gắn với bước Test. |
| 4.1 🔴 | ✅ | — | refreshRetentionProjections UPDATE không có historical_mastery trong cột SET; applyEvidence dùng Math.max đơn điệu tăng; periodic.test.ts 7/7 PASS. |
| 4.2 | ✅ | — | công thức khớp reference, test memoryless. |
| 4.3 | ✅ | — | cron khớp schedules.md. |
| 4.4 | ✅ | — | test bất biến refresh không ghi anchor. |
| 4.5 | ✅ | — | CFG constants khớp reference. |
| 5.1 | ✅ | — | reason bắt buộc, hiển thị UI. |
| 5.2 | ❌ | HH | 1/20 dòng model_version NULL (retention, bản ghi lịch sử sớm nhất) — dữ liệu thật vẫn vi phạm dù code hiện tại đã sửa. |
| 5.3 | ✅ | — | diffPlans() + UI lịch sử phiên bản. |
| 5.4 | ❌ | HH | 1/20 dòng confidence NULL, cùng dòng lịch sử với 5.2. |
| 5.5 | ✅ | — | API model-versions gate learner access; UI PlanPage có lịch sử. |
AS-06 · 12/25 (48%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 | ✅ | — | 0/274 thiếu subject_id/grade/level. |
| 1.2 | ✅ | — | 0/274 thiếu strand/unit. |
| 1.3 | ✅ | — | Viết lại DFS độc lập, tự phát hiện+sửa 1 bug trong chính script, kết quả cuối khớp 152 node out-degree>0, 0 chu trình. |
| 1.4 | ❌ | HH | 69/222 unit <10 item khớp chính xác; 222/222 thiếu đủ discriminator/boundary; code tự cảnh báo kho câu mỏng. |
| 1.5 | ✅ | — | 0/274 thiếu title_en. |
| 2.1 | ❌ | HH | total=2314 (tăng từ 2146), null_quality=2314 — vẫn 100% thiếu quality profile. |
| 2.2 | ❌ | CM | 0 bản ghi quality_json để đọc, cơ chế có test nhưng chưa chạy thật. |
| 2.3 | ✅ | — | 27/27 test pipeline multi-evaluator variance. |
| 2.4 | ✅ | — | 0/2146 thiếu node_id/role. |
| 2.5 | ❌ | CX | UI Coral chỉ placeholder, không có màn hình hàng đợi. |
| 3.1 🔴 | ✅ | — | PATCH luôn 409, đường sửa duy nhất qua candidate. |
| 3.2 | ✅ | — | item_versions.status CHECK enum rõ. |
| 3.3 | ✅ | — | ngưỡng số cụ thể, publishVersion gọi evaluatePublishGate. |
| 3.4 | ❌ | HH | total=2314, published_by/published_at đều 0 (100% NULL). |
| 3.5 | ✅ | — | endpoint rollback tồn tại, gọi publishVersion. |
| 4.1 | ❌ | CX | 0 dòng source_kind='real'. |
| 4.2 🔴 | ✅ | — | source_url/ref TEXT, R2 object_count=0, 0 đường ghi file đề. |
| 4.3 🔴 | ❌ | CX | 0 đề real để spot-check. |
| 4.4 | ❌ | CX | 0 bảng crawl_runs, 0 code crawler thật. |
| 4.5 | ❌ | CX | immutable_after_publish 0 route đọc/chặn. |
| 5.1 | ❌ | CX | 0 bảng media, 0 route /v1/media. |
| 5.2 | ❌ | CX | 0 registry nguồn/giấy phép media. |
| 5.3 | ✅ | — | 8 SVG thủ công, GoogleButton dùng script chính thức. |
| 5.4 | ❌ | CX | Media Service chưa tồn tại. |
| 5.5 | ❌ | CX | 0 pipeline media, 0 scope đồng thuận ảnh. |
AS-07 · 19/25 (76%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 🔴🚸 | ✅ | — | Script đối chiếu toàn bộ path: đúng 9-11 route public có comment lý do; curl production xác nhận gated đúng, public đúng khai báo. |
| 1.2 | ✅ | — | resolveSession lọc revoked/expired, rotate 7 ngày. |
| 1.3 | ✅ | — | verifyGoogleIdToken/verifyAccessJwt verify issuer+audience+alg. |
| 1.4 🚸 | ✅ | — | admin/dolphin/coral 302 Access; learn/marlins/nemo12.com 200. |
| 1.5 | ✅ | — | 0 hit bypass/skip auth. |
| 2.1 🔴🚸 | ✅ | — | authz.ts chốt quyền backend thật; 11 module gọi trực tiếp, còn lại qua wrapper tương đương. |
| 2.2 🔴 | ✅ | — | 1 hit không phải so sánh phân quyền, authz dựa user_id/role. |
| 2.3 🔴🚸 | ✅ | — | parent/authz.test.ts 22/22 PASS trên D1 thật. |
| 2.4 | ❌ | CM | audit_log actor_role='mentor' COUNT=0. |
| 2.5 | ✅ | — | gen-reference 0 diff, permissions.md khớp code. |
| 3.1 | ❌ | CX | data-dictionary.md không có mục đích thu thập cấp trường. |
| 3.2 🔴🚸 | ✅ | — | requireConsent chỉ có 1 định nghĩa + test, không route nào gọi để chặn; privacy/routes.ts tự ghi rõ "từ 2026-08-15 consent là DẤU VẾT, không phải cổng chặn". |
| 3.3 | ❌ | CM | code đúng nhưng 0 file portraittest. |
| 3.4 | ✅ | — | chỉ 2 URL ngoài đã khai, không có domain lạ. |
| 3.5 | ❌ | CX | backend đủ nhưng 0 UI marlins gọi data-usage. |
| 4.1 | ❌ | HH | 4 route admin/observability.ts chỉ gate requireAdmin, 0 hit logAccess/canAccessLearner trong toàn file. |
| 4.2 | ✅ | — | audit_log đủ actor/action/target/occurred_at/ip/user_agent/request_id. |
| 4.3 | ❌ | HH | 1 dòng audit_log thật chứa note nguyên văn, ghi tay qua wrangler không qua sanitiseDetail. |
| 4.4 | ✅ | — | 0 UPDATE/DELETE audit_log thật. |
| 4.5 | ✅ | — | GET /v1/admin/audit-log filter đầy đủ. |
| 5.1 🔴 | ✅ | — | git log -p --all toàn lịch sử → 0 hit; .env.production đã xác minh không phải secret. |
| 5.2 🔴 | ✅ | — | 0 hit debug//seed route. |
| 5.3 | ✅ | — | 0 c.req.json thô, mọi route qua zod. |
| 5.4 | ✅ | — | 1 hit dangerouslySetInnerHTML, nguồn không phải input trực tiếp. |
| 5.5 🚸 | ✅ | — | rate limit trước login/AI/privacy write, 8/8 test PASS. |
AS-08 · 17/25 (68%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 | ❌ | CX | 0 hit availability tier gắn worker cụ thể. |
| 1.2 | ❌ | CX | SDD-006 §16 chỉ nêu câu hỏi, 0 bản trả lời. |
| 1.3 | ❌ | CX | 12/18 SDD 0 hit fallback/degrad. |
| 1.4 🚸 | ❌ | HH | curl production /v1/health → 200 dù logic set database=error khi lỗi; rollback.yml chỉ đọc mã HTTP. |
| 1.5 | ✅ | — | 0 TODO/FIXME. |
| 2.1 | ✅ | — | dedupeKey/claimMessage/markProcessed, 20/20 test PASS. |
| 2.2 🔴🚸 | ✅ | — | wrangler queues list thật xác nhận cả 2 queue tồn tại. |
| 2.3 | ✅ | — | admin/routes.ts dòng 189-294 GET/POST dead-letters xác nhận; recordDeadLetter gọi thật trong index.ts queue() handler. |
| 2.4 | ✅ | — | max_retries=5 khớp, backoff có trần. |
| 2.5 | ✅ | — | withLock KV, test song song chỉ 1 chạy. |
| 3.1 | ✅ | — | 9/9 wrangler.jsonc có observability. |
| 3.2 | ✅ | — | requestId middleware, X-Request-Id header. |
| 3.3 | ❌ | HH | onError chỉ log message+stack, không request_id/path/method dù c.get('requestId') sẵn có nhưng code không gọi. |
| 3.4 | ✅ | — | GET /v1/admin/run-metrics query engine_runs/workflow_runs. |
| 3.5 | ✅ | — | workflow_runs COUNT=4>0. |
| 4.1 🚸 | ✅ | — | 0 continue-on-error toàn ci.yml cho 3 bước Typecheck/Lint/Test; chạy vô điều kiện. |
| 4.2 | ✅ | — | 9/9 path filter khớp. |
| 4.3 🔴 | ❌ | HH | deploy-api.yml dòng 48 if: workflow_dispatch — bước Apply D1 migrations SKIP trên 19/20 lần chạy push gần nhất; gh run view 31898121357 xác nhận Apply=skipped, Deploy=success. Thứ tự văn bản đúng nhưng thứ tự THI HÀNH sai trên đường push thật. |
| 4.4 | ✅ | — | rollback.yml đủ 9 worker, quy trình ghi lại (0 lần chạy thật, độ tin cậy lý thuyết). |
| 4.5 | ✅ | — | 0 gate thủ công ngoài migration-apply. |
| 5.1 | ✅ | — | AI/OAuth/R2 đều có try/catch fallback. |
| 5.2 | ❌ | CM | 0 test mock lỗi AI, không an toàn để tự phá gateway thật. |
| 5.3 | ✅ | — | 1 hit AbortSignal.timeout, AI dùng withTimeout riêng. |
| 5.4 | ✅ | — | withCache KV, dùng thật ở /v1/subjects. |
| 5.5 | ❌ | HH | curl production POST /v1/auth/google garbage → 400 rò ZodError, không qua errorResponse taxonomy; 0 defaultHook tuỳ biến. |
AS-09 · 10/25 (40%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 | ❌ | CX | ui-minimalism-audit.md không tồn tại. |
| 1.2 | ❌ | CX | artifact không tồn tại. |
| 1.3 | ❌ | CX | artifact không tồn tại. |
| 1.4 | ❌ | CX | artifact không tồn tại. |
| 1.5 | ❌ | CX | artifact không tồn tại. |
| 2.1 | ❌ | HH | ProgressViews.tsx dòng 22 hardcode #fff ngoài file art/palette. |
| 2.2 | ❌ | HH | 5 bản N12Art.tsx lệch nhau (md5 3 nhóm khác nhau), vi phạm cả luật "copy y hệt" riêng của dự án. |
| 2.3 | ✅ | — | chỉ 6 index.css, 0 CSS riêng theo route. |
| 2.4 | ✅ | — | mỗi .theme-X chỉ redefine 4 biến accent. |
| 2.5 | ❌ | HH | 8 hit text-xs thật, dưới sàn --text-floor:14px, không override nào. |
| 3.1 🔴🚸 | ✅ | — | raw --accent vs #fff fail AA cho 5/9 theme nhưng KHÔNG có usage sống nào kích hoạt (chỉ 1 usage, ở app theme cố định, đạt AA); giữ PASS, ghi rủi ro thiết kế. |
| 3.2 | ✅ | — | Tab thật hiện outline rõ trên 3 màn. |
| 3.3 | ❌ | HH | Đo thật trên production 375px: 5 phần tử dưới 44px, khớp chính xác kích thước gốc. |
| 3.4 | ✅ | — | 5/5 |
| 3.5 | ❌ | CM | rào OAuth thật, không thử tay được luồng đầu-cuối. |
| 4.1 | ✅ | — | admin 100% tiếng Anh, learn dùng tiếng Việt. |
| 4.2 | ✅ | — | 0 hit lẫn ngôn ngữ trong cùng màn. |
| 4.3 | ❌ | HH | glossary.md 0 hit "Vững/Lung lay/Hổng" dù dùng xuyên suốt UI tiến độ thật. |
| 4.4 | ✅ | — | message tiếng Việt, không phơi stack/exception. |
| 4.5 | ❌ | CM | phần lớn màn sau OAuth không rà được. |
| 5.1 | ❌ | CX | 0 hit ngưỡng LCP khai trong docs. |
| 5.2 | ❌ | CM | CLS 0.107/0.117 trên 2/3 màn, không rõ ngưỡng để phán HH hay PASS. |
| 5.3 | ✅ | — | 13 file dùng n12-skeleton/n12-empty. |
| 5.4 | ✅ | — | find toàn repo (không giới hạn apps/) mọi định dạng bitmap → 0 kết quả. |
| 5.5 | ❌ | HH | Learning.tsx submit() nhánh đầu tiên: setReveal chỉ chạy trong .then() của API — chờ round-trip; nhánh "seen" mới chấm client-side thật. |
AS-10 · 20/25 (80%)
| Chỉ báo | Mã | Bằng chứng | |
|---|---|---|---|
| 1.1 🔴 | ✅ | — | 1 hit env.AI.run qua gateway id. |
| 1.2 🔴 | ✅ | — | 0 fallback model, gọi 1 model 1 lần. |
| 1.3 | ✅ | — | 1 hit @cf/ model id đầy đủ. |
| 1.4 | ✅ | — | 0 hit env.AI/ai.run trong apps. |
| 1.5 | ❌ | HH | ai-registry.md last_reviewed 2026-08-14 (trước khi prompts.ts tạo 2026-08-15); vị trí dòng cũ, mục "chưa có version" mâu thuẫn code thật đã có version. |
| 2.1 | ✅ | — | 0 prompt inline, cả 3 trong prompts.ts. |
| 2.2 | ✅ | — | mỗi PromptSpec có version. |
| 2.3 | ✅ | — | version 1 retired, version 2 mới — đúng mẫu tạo version mới. |
| 2.4 | ✅ | — | purpose/expects/constraints đầy đủ. |
| 2.5 | ✅ | — | output là z.ZodType thật, safeParse trước khi trả. |
| 3.1 🔴🚸 | ✅ | — | Q-129 xác nhận: 0 điểm AI chạm learner data qua bất kỳ đường nào — bất biến đúng một cách rỗng. |
| 3.2 | ✅ | — | PURPOSE_FIELDS khai rõ, 12/12 test PASS. |
| 3.3 | ✅ | — | learnerRef hash SHA-256, assertNoIdentifiers chặn cứng. |
| 3.4 | ❌ | HH | item_versions không có cột model/prompt_version/input_ref; learning_experiences CÓ provenance_json — bất đối xứng thật giữa 2 đường AI output. |
| 3.5 🔴🚸 | ✅ | — | context-builder.test.ts 12/12 PASS, cách ly A/B thật với D1 giả ghi lại SQL+bind. |
| 4.1 🔴🚸 | ✅ | — | createCandidate → item_versions status=candidate; INSERT INTO items chỉ 1 điểm, trong publishVersion() sau gate.ok. |
| 4.2 | ✅ | — | evaluateItemProfiles luôn có rule-engine + ≥1 LLM = 2 evaluator độc lập kể cả khi passes mặc định=1; PUBLISH_MIN_EVALUATORS=2 chặn nếu thiếu. |
| 4.3 | ✅ | — | HUMAN_SPOT_CHECK_RATE=0.2 hằng số, test PASS. |
| 4.4 | ✅ | — | source='ai-generated' gán tường minh. |
| 4.5 | ✅ | — | content_reports nối review_queue, resolveReview khép vòng. |
| 5.1 | ❌ | CX | ai-registry.md không có ước tính chi phí. |
| 5.2 | ❌ | CM | 403 thiếu scope ai_gateway. |
| 5.3 | ✅ | — | RATE_LIMITS.aiGenerate trước route AI, 8/8 test PASS. |
| 5.4 | ❌ | CX | 0 cron/queue gọi AI, đều đồng bộ HTTP staff. |
| 5.5 | ✅ | — | requireStaff+rate-limit trước runPrompt. |
6. Đường tiến — đối chiếu #001 → #002 → #003, đặc biệt 6 chỉ báo Pilot Gate vừa vá
| Lần chấm | Chuẩn | Điểm | Pilot Gate |
|---|---|---|---|
| #001 (57dc4fa) | v0.1/250 | 109/250 (44%) | — |
| #002 (89a3db4) | v0.2/255 | 157/255 (61,6%) | 12/18 — NO-GO |
| #003 (70e80a9) | v0.2/255 | 172/255 (67,5%) | 18/18 — GO (đọc kỹ ghi chú dưới) |
Đây là phần quan trọng nhất của báo cáo: đợt vá Pilot Gate giữa #002 và #003 có thật không, hay chỉ trông như sửa? Xét từng chỉ báo trong 6 chỉ báo từng chặn ở #002:
AS-07.1.1 (endpoint thiếu xác thực) — FIX THẬT. #002 tái hiện được HTTP 500 trên
GET /v1/coral/labs(thiếurequireSession). #003: dòng.use("/v1/coral/labs", requireSession)đã được thêm, kèm comment trực tiếp trích chỉ báo này; một script đối chiếu toàn bộ route↔guard (không chỉ grep đếm) xác nhận không còn route nào thiếu guard mà không có lý do "public có chủ đích";curlproduction xác nhận 401 sạch. Vá đúng chỗ, đúng cách.AS-04.6.3 (schema-diff production vs local) — FIX THẬT (qua xác minh kỹ hơn). #002 phát hiện
whale_scholarshipslệch DDL text giữa production vàmigrate:dryruncục bộ. #003: chạy lại độc lập với phạm vi RỘNG HƠN (so sánhPRAGMA table_infocho toàn bộ 79 bảng, không chỉ 1 bảng như tài liệu tự nhận) — 0 lệch cấu trúc thật; 2 bảng lệch text DDL (do lịch sửCREATE+ALTERkhácCREATEgộp) cóPRAGMA table_infogiống hệt nhau. Kết luận: cấu trúc chưa từng lệch thật, lệch chỉ ở cách SQLite lưu lại lịch sử câu lệnh — nhưng đây là một kết luận chắc chắn hơn hẳn #002 nhờ kiểm tra sâu hơn, không phải một "vá" theo nghĩa sửa code.AS-04.5.5 (diễn tập backup/restore) — FIX THẬT. #002: file chưa tồn tại, 0 lần diễn tập. #003:
docs/ops/backup-restore-drill.mdmô tả một đợt diễn tập thật (export → restore vào D1 local cô lập → đối chiếu COUNT(*) toàn bộ bảng); phản biện tự đối chiếu độc lập với số liệu SỐNG trên production ngay lúc chấm — 5/6 số khớp tuyệt đối, số còn lại (sốitems) lệch có lý do hợp lý (nội dung mới sinh ra liên tục bởi các phiên AI khác đang chạy song song). Vá đúng, có bằng chứng độc lập xác nhận không phải số bịa.AS-03.5.3 (apply migration ngoài CI) — FIX THẬT (đúng phần được đo). #002: không có câu cấm tường minh trong README, 403 Pro (hạ tầng không mua được), và có 2 dòng mồ côi mới phát sinh cùng ngày. #003: README dòng 49 nay có câu cấm tường minh; 403 vẫn còn (đúng như dự kiến — đây là giới hạn hạ tầng không đổi được, không phải lỗi); và diff disk-vs-remote migration hiện tại = 0. Ba nhánh thoát của "cách kiểm" đều đạt. Nhưng — xem điểm quan trọng bên dưới: chính đường ống mà AS-03.5.3 bảo vệ (migration không được áp thủ công) đang tồn tại một lỗ hổng liền kề mà AS-03.5.3 không đo tới:
AS-08.4.3/AS-03.5.4phát hiện migration cũng không được áp tự động trên đường push chuẩn (chỉ chạy khi ai đó bấmworkflow_dispatchtay) — nghĩa là con đường "đúng" (CI tự động áp trước khi deploy) hiện KHÔNG hoạt động thật, dự án đang sống sót nhờ một người thỉnh thoảng bấm nút tay, đúng loại rủi ro vận hành mà AS-03.5.3 được sinh ra để chặn, chỉ khác góc đo.AS-07.3.2 (đồng thuận dữ liệu trẻ em) — KHÔNG PHẢI FIX KỸ THUẬT, LÀ QUYẾT ĐỊNH SẢN PHẨM. #002:
enforceConsent()không có lời gọi thật, không chặn được learner chưa từng được hỏi — rủi ro pháp lý trực tiếp. #003:enforceConsent()/cơ chế chặn đã bị XOÁ HẲN khỏi code; bản thânaudit-standard/index.mdcũng đã tự đổi nội dung chỉ báo AS-07.3.2 thành "ghi dấu vết đồng thuận (KHÔNG chặn)" theo chỉ đạo SRC-137 ngày 2026-08-15 ("không cần bố mẹ phải đồng ý — bỏ toàn bộ tính năng bắt phụ huynh bấm đồng thuận"). Nói cách khác: đây PASS vì chủ dự án đã quyết định bỏ yêu cầu chặn, không phải vì kỹ sư đã xây được cổng chặn đúng. Rủi ro dữ liệu trẻ em mà #002 nêu ra chưa biến mất về bản chất — nó chỉ không còn là điều chỉ báo này đo nữa, theo đúng quyết định có thẩm quyền của chủ dự án. Đáng lưu ý thêm: chuẩn trích dẫn "SRC-130" cho quyết định này ở cả bảng AS-07.3 lẫn bảng Pilot Gate, nhưng SRC-130 trong intake.md là một chỉ đạo khác hẳn (bỏ số thứ tự câu trong luyện đề) — quyết định thật là SRC-137. Đây là lỗi trích dẫn cần chủ dự án/người viết chuẩn sửa lại.AS-10.3.1 (Context Builder là đường duy nhất) — KHÔNG PHẢI FIX, LÀ GHI NỢ CHÍNH THỨC CHO MỘT THỰC TRẠNG KHÔNG ĐỔI. #002:
buildLearnerContext()chỉ được gọi trong test, 0 route sản xuất gọi — bất biến "đường duy nhất" đúng một cách rỗng vì tính năng nó bảo vệ chưa tồn tại. #003: kiểm tra độc lập cho kết quả giống hệt — vẫn 0 route sản xuất nào gọibuildLearnerContext, AI vẫn không chạm dữ liệu learner qua bất kỳ đường nào. Khác biệt duy nhất:open-questions/index.mdnay có Q-129 ghi nhận đây là "nợ chấp nhận được" kèm điều kiện đảo ngược. Đây là PASS-theo-tài-liệu-hoá, không phải PASS-vì-đã-đóng-khoảng-trống — và tự Q-129 dùng đúng ngôn ngữ "nợ", ngầm định chưa xong, mâu thuẫn với yêu cầu "100% phải PASS" của chính Pilot Gate. Vì lượt phản biện không chạm chỉ báo này, verdict cuối theo đúng thứ tự ưu tiên đã định vẫn là PASS — nhưng đây là quyết định biên, cần chủ dự án biết rõ bản chất trước khi coi đây là một ô đã đóng thật.
Tóm lại: 4/6 là fix thật có bằng chứng độc lập xác nhận (AS-07.1.1, AS-04.6.3, AS-04.5.5, AS-03.5.3), 2/6 là PASS nhờ thay đổi định nghĩa/ghi nợ chứ không phải đóng khoảng trống kỹ thuật (AS-07.3.2 — quyết định sản phẩm hợp lệ nhưng rủi ro chưa biến mất; AS-10.3.1 — thực trạng y hệt #002, chỉ mới được đặt tên). Đồng thời, đúng lúc 4 fix thật đóng lại, một lỗ hổng liền kề mới lộ ra (AS-08.4.3/AS-03.5.4: migration không tự áp trên đường push chuẩn) — cùng họ rủi ro với AS-03.5.3 nhưng nằm ngoài phạm vi đo của nó.
Số chỉ báo bị phản biện lật verdict trong lần chấm này (không tính so với #002): 4 — AS-02.1.1 (KHÔNG PASS→PASS: chỉ báo tự trỏ PRD-001 §5, nơi REQ-ORC đã có mục riêng, thay vì conventions.md — nguồn phụ tự nhận không phải nguồn sự thật), AS-03.5.4 và AS-08.4.3 (PASS→KHÔNG PASS: phát hiện bằng gh run view thật rằng bước apply-migration bị skip trên đường push chuẩn dù đứng đúng thứ tự dòng lệnh), và AS-10.3.1 (KHÔNG PASS→PASS trong nội bộ vòng Pilot Gate, xem điểm 6 ở trên).
Việc tiếp tục từ #001: các fix đã đứng vững qua cả ba lần chấm (AS-04.1.1 numbering, AS-01.4.1 gen:reference, AS-03.2.4 contract:diff, AS-10.3.5 cách ly context A/B, AS-10.4.1 publish gate) tiếp tục PASS ở #003 — không có dấu hiệu thoái lui. Các nợ mới phát sinh do tính năng mới (Orca, community events, Whale, Coral labs) từ #002 phần lớn vẫn còn (AS-04.2.3 REFERENCES, AS-04.3.x enum/mô tả cột, AS-06.1.4 kho câu mỏng) — không tệ hơn nhưng cũng chưa được dọn.
7. Kết luận
Pilot Gate: 18/18 theo đúng câu chữ chuẩn v0.2 → GO. Nhưng đây là một GO có điều kiện đọc kỹ: 2 trong 18 dòng (AS-07.3.2, AS-10.3.1) là PASS-vì-đổi-định-nghĩa/ghi-nợ chứ không phải đóng khoảng trống kỹ thuật, và có một chỉ báo 🔴🚸 nằm ngoài 18 dòng do lỗi soạn thảo của chuẩn (AS-08.4.3) đang KHÔNG PASS với đúng loại rủi ro (migration không tự áp trước deploy) đã từng gây sự cố production trước đây. Khuyến nghị: chủ dự án tự quyết có coi AS-08.4.3 là gate thứ 19 trước khi mở thử hay không — đây không phải quyết định audit này có thẩm quyền tự đưa ra.
Điểm hệ toàn phần: 172/255 (67,5%), mức "Đang dựng" — tiến 15 chỉ báo so với #002 (157/255), còn cách sàn REQ-DOC-06 (≥225/255) 53 chỉ báo. Rất gần ngưỡng "Vững" (70%) nhưng chưa chạm.
%HH = 56,6% trong tổng KHÔNG PASS — gần như nguyên trạng so với #002 (57%). Cả ba loại nợ (HH/CX/CM) đều giảm nhẹ về số tuyệt đối nhưng tỷ trọng không đổi nhiều — tiến bộ đang dàn đều, không thiên về phía dễ.
Về đợt vá Pilot Gate cụ thể (câu hỏi trọng tâm của lần chấm này): có thật, nhưng không toàn vẹn 100%. 4/6 việc là sửa kỹ thuật thật, có bằng chứng độc lập xác nhận không phải "trông như sửa". 2/6 là PASS nhờ đổi định nghĩa chỉ báo (một quyết định sản phẩm hợp lệ của chủ dự án, không phải sơ hở kỹ thuật) hoặc ghi nợ chính thức cho một khoảng trống chưa đổi — cả hai đều minh bạch, có nguồn (SRC-137, Q-129), nhưng không phải "đóng lỗ hổng" theo nghĩa đen. Và ngay khi 4 lỗ hổng cũ đóng lại, một lỗ hổng liền kề (migration không tự áp trên đường push) lộ ra ở đúng khu vực rủi ro cũ.
8. Hành động ưu tiên
Xếp theo đúng thứ tự yêu cầu: Pilot Gate chưa PASS lên đầu (hiện không còn mục nào theo đúng câu chữ, nhưng có 1 mục cận-Pilot-Gate cần quyết định), sau đó 🔴 chặn release còn lại, rồi HH (đã hỏng, có phản ví dụ), CM (chứng minh — rẻ), cuối cùng CX (xây — tốn nhất).
8.0 Cận-Pilot-Gate — cần chủ dự án quyết trước khi mở thử (1 việc)
| # | Hành động | Đóng được chỉ báo | Ước lượng |
|---|---|---|---|
| G1 | Bỏ if: github.event_name == 'workflow_dispatch' khỏi bước "Apply D1 migrations" trong deploy-api.yml (hoặc thêm bước apply tự động riêng trên mọi push) để migration thật sự áp trước khi code deploy trên đường push chuẩn, không chỉ khi có người bấm tay | AS-08.4.3 🔴, AS-03.5.4 | nửa ngày |
8.1 🔴 chặn release còn lại (2 việc — 1 trùng G1)
| # | Hành động | Đóng được chỉ báo | Ước lượng |
|---|---|---|---|
| R1 | (= G1 ở trên) | AS-08.4.3 🔴 | — |
| R2 | Thu thập ≥1 đề thi thật (source_kind='real') kèm URL nguồn, để có dữ liệu spot-check lời giải tự biên soạn | AS-06.4.3 🔴 | 2-3 ngày (phụ thuộc nguồn đề) |
8.2 HH — có phản ví dụ, cần sửa code/dữ liệu/docs (47 chỉ báo, nhóm theo chủ đề)
| # | Hành động | Đóng được chỉ báo | Ước lượng |
|---|---|---|---|
| H1 | Sửa migrations/README.md §3 khớp thực tế production hiện tại (production đã có 0031, không có 0022_whale) | AS-01.1.1, 1.1.5 | 1 giờ |
| H2 | Nối 25 REQ ✔ còn thiếu vào satisfies[] của SDD đích đã khai trong PRD; thêm REQ-LRN-19/20/21 vào PRD §6; thêm link markdown trỏ tới backup-restore-drill.md/reference/config.md từ index.md | AS-01.3.1, 1.3.4, 1.3.5 | 1 ngày |
| H3 | Bump version PRD-001 đúng quy ước khi sửa REQ đáng kể; thêm cột "Trạng thái" vào bảng "Việc còn chờ chủ dự án"; sửa 10 dòng ✍️ Đợt 1 dưới ngưỡng 15 ký tự; sửa 35+ SRC id chưa xuất hiện ngoài intake.md (nối vào PRD/SDD tương ứng) | AS-01.1.3, 1.5.2, 2.5.2, 2.5.4 | 1 ngày |
| H4 | Đăng ký nhóm Octopus vào SDD-011 (hiện 0 hit dù REQ-SCH-10 trỏ tới); sửa "tốt hơn"/"nhanh" ở 4 dòng REQ dính từ mơ hồ nếu muốn triệt để theo L4 cơ học | AS-02.1.2, 2.3.4 | nửa ngày |
| H5 | Vá 68 cột *_id thiếu REFERENCES (hoặc miễn trừ tường minh trong dictionary); xoá mục ma interaction_votes_rebuilt; sửa generator cho CHECK nhiều dòng (0027/0030/0033); thêm community_events/community_event_registrations vào state-machines.md; điền 160 mô tả cột rỗng | AS-04.2.3, 4.3.2, 4.3.3, 4.3.4, 4.3.5 | 2 ngày |
| H6 | Sửa 3 seed script (seed-labs, seed-orca-math, attach-figures) thêm mặc định --local/xác nhận trước --remote; điền 24 dòng thiếu cặp _en (subjects 4, strands 20); mở rộng retention_policies cho các bảng chạm learner còn thiếu (sessions, exam_attempts, interactions, portraits, learner_goals…); nối 365 ngày/model-version vào state-machines.md §25 | AS-04.4.1, 4.4.5, 4.5.1, 4.5.3 | 1-2 ngày |
| H7 | Gắn trang mô tả riêng cho Constraint Model + Learning Plan Model trong models.md (đang chạy production nhưng chỉ có 1 dòng bảng); lưu model/prompt_version/input_ref vào item_versions khi tạo qua AI (đã có ở learning_experiences, thiếu ở items) | AS-05.1.1, 5.1.4, 10.3.4 | 1 ngày |
| H8 | Thêm test hành vi riêng cho Context Engine + Readiness Engine (hiện chỉ đụng gián tiếp qua WF-04 chung) | AS-05.3.1 | 1 ngày |
| H9 | Chạy 1 lượt chấm quality 8 chiều cho 2314 item published thật, ghi evaluator_count/quality_json; điền published_by/published_at khi publish qua đúng pipeline | AS-06.1.4, 6.2.1, 6.3.4 | 2 ngày |
| H10 | Thêm logAccess() vào 4 route admin/observability.ts; xoá/redact 1 dòng audit_log chứa note nguyên văn (ghi tay qua wrangler) | AS-07.4.1, 7.4.3 | nửa ngày |
| H11 | Sửa health route trả HTTP 503 khi database=error thay vì luôn 200; sửa app.onError ghi kèm request_id (đã có sẵn qua c.get)+path+method vào log | AS-08.1.4, 8.3.3 | nửa ngày |
| H12 | Thêm defaultHook tuỳ biến cho lỗi validate zod của OpenAPIHono (POST /v1/auth/google và mọi route khác đang rò ZodError thô khi body sai định dạng) | AS-03.2.5, 8.5.5 | nửa ngày |
| H13 | Import palette.ts vào ProgressViews.tsx (xoá hex trần #fff); hợp nhất 5 bản N12Art.tsx đang lệch nhau về đúng một nguồn (hoặc đồng bộ lại theo đúng luật "copy y hệt" của dự án); nâng 8 chỗ text-xs; nối "Vững/Lung lay/Hổng" vào glossary.md; sửa nav/hero link ≥44px trên mobile trang chủ | AS-09.2.1, 9.2.2, 9.2.5, 9.4.3, 9.3.3 | 1-2 ngày |
| H14 | UI "chấm client-side trước, gửi evidence async" cho câu trả lời đầu tiên trong Learning.tsx (nhánh seen đã làm đúng, nhánh đầu tiên còn chờ round-trip) | AS-09.5.5 | 1 ngày |
| H15 | Cập nhật ai-registry.md (last_reviewed, vị trí dòng 3 điểm gọi runPrompt thật, xoá tuyên bố "chưa có prompt version") | AS-10.1.5 | 1 giờ |
| H16 | Đối chiếu lại đúng nguyên nhân AS-03.1.2 phát hiện: 24 dòng import chéo trực tiếp qua 11-13 module không qua shared//event — dọn dần theo module | AS-03.1.2 | 1-2 ngày |
8.3 CM — chứng minh, thường rẻ (10 chỉ báo)
| # | Hành động | Đóng được chỉ báo | Ước lượng |
|---|---|---|---|
| C1 | Xin/renew Cloudflare API token có scope KV+R2+AI Gateway đọc, chạy lại verify:bindings Lớp C và kiểm chi phí AI Gateway | AS-03.4.4, 10.5.2 | 1 giờ (phụ thuộc quyền cấp token) |
| C2 | Viết test dedupe event_id cho modules/learning | AS-05.2.4 | nửa ngày |
| C3 | Chạy pipeline quality 8 chiều thật trên ≥1 item để có bản ghi quality_json đọc được (đã gộp vào H9) | AS-06.2.2 | — |
| C4 | Viết portraits/*.test.ts; ghi audit_log mẫu khi có mentor thật đầu tiên dùng hệ | AS-07.3.3, 7.2.4 | nửa ngày |
| C5 | Tạo tài khoản test đăng nhập Google thật để rà Tab đầu-cuối và ngôn ngữ ở màn sau đăng nhập | AS-09.3.5, 9.4.5 | nửa ngày |
| C6 | Khai ngưỡng CLS/LCP cụ thể trong SDD để có căn cứ phán PASS/HH thay vì CM | AS-09.5.2 | nửa ngày |
| C7 | Viết test mô phỏng lỗi AI (mock env.AI.run throw), xác nhận UI/response vẫn sống | AS-08.5.2 | nửa ngày |
8.4 CX — xây mới, tốn nhất (26 chỉ báo, nhóm lớn)
| # | Hành động | Đóng được chỉ báo | Ước lượng |
|---|---|---|---|
| X1 | Dựng docs/reference/ui-minimalism-audit.md (bảng route×app×5 cột, kèm ảnh/file:line) | AS-09.1.1..5 | 2 ngày |
| X2 | Ngân hàng đề thật + crawler tôn trọng robots/ToS | AS-06.4.1, 6.4.4, 6.4.5 | 3-5 ngày |
| X3 | Media System tối thiểu (bảng media, route upload, moderation) nếu tính năng ảnh thật sự cần trước khi mở rộng ngoài pilot | AS-06.5.1, 6.5.2, 6.5.4, 6.5.5 | 3 ngày |
| X4 | Viết 5 câu trả lời production-ready SDD-006 §16 cho từng subsystem; khai tier availability theo worker; định nghĩa "hỏng thì thấy gì" cho Orca/Whale/community events | AS-08.1.1, 8.1.2, 8.1.3 | 1 ngày |
| X5 | Cột "Phân loại" 4 giá trị cho legacy-feature-inventory.md; cột "Đã vào" cho mọi Q trong open-questions/index.md; xây đường xoá dữ liệu thật (hiện chỉ ghi nhận yêu cầu); mục §PII trong data-dictionary.md; mục đích thu thập cấp trường cho dữ liệu trẻ em; nối UI marlins vào endpoint data-usage có sẵn | AS-02.4.4, 2.5.5, 4.5.2, 4.5.4, 7.3.1, 7.3.5 | 2 ngày |
| X6 | Khai ngưỡng LCP trong SDD; ước tính chi phí AI theo loại lời gọi trong ai-registry.md; xác nhận 0 cron/queue gọi AI là chủ đích | AS-09.5.1, 10.5.1, 10.5.4 | nửa ngày |
| X7 | Dựng UI Coral "Chất Lượng" thật (thay placeholder) nối content_review_queue | AS-06.2.5 | 1-2 ngày |
9. Ghi chú phương pháp
- Bằng chứng thu bằng lệnh thật trên snapshot ghim tại commit
70e80a9(bản sao độc lập, không phải thư mục làm việc chính đang bị nhiều phiên AI khác sửa song song), cộng production thật (D1nemo12-platformremote,wrangler queues list,gh run list/gh api) — CHỈ ĐỌC, không migrate/deploy/commit từ phiên chấm này. - Ba lượt hợp nhất theo đúng thứ tự ưu tiên: chấm gốc (255/255 chỉ báo có bằng chứng, 0 chỉ báo bị bỏ sót so với
audit-standard/index.mdnên không có mục nào phải tự chấm bổ sung) → chấm sâu 18 chỉ báo Pilot Gate → một lượt phản biện chạm 67/255 chỉ báo. Verdict cuối ở mỗi ID dùng lớp muộn nhất đã chạm tới nó (phản biện > Pilot Gate > chấm gốc). - 4 chỉ báo bị lật verdict trong nội bộ lần chấm này (không tính đối chiếu với #002 — xem §6 cho phần đó):
AS-02.1.1(KHÔNG PASS→PASS),AS-03.5.4vàAS-08.4.3(PASS→KHÔNG PASS, phát hiện bằnggh run viewthật rằng migration-apply bị skip trên đường push chuẩn),AS-10.3.1(KHÔNG PASS ở chấm gốc → PASS ở Pilot Gate, giữ nguyên vì phản biện không chạm tới — xem cảnh báo ở §6 điểm 6). - Theo L2 (cấm N/A) và L3 (không bằng chứng = KHÔNG PASS): mọi KHÔNG PASS đều kèm mã CX/CM/HH theo đúng định nghĩa §1.1 audit-standard/index.md.
- Một vài chỉ báo có bằng chứng dựa trên số liệu production đang thay đổi liên tục (vd
itemscount 2146→2314 giữa các lần chấm do các phiên AI khác vẫn ghi thêm nội dung song song) — đã ghi rõ trong bằng chứng khi số tuyệt đối lệch giữa các lần chấm nhưng bản chất vi phạm không đổi. - AS-09.3.5 và một phần AS-09.4.5 vẫn bị chặn bởi rào Google OAuth thật (không có tài khoản test) — chưa rà được các màn sau đăng nhập; ghi CM thay vì suy đoán PASS, đúng như #002.