Skip to content

Audit #004 — 2026-08-20 ​

Chấm trên main @ d74e646 + production thật, theo Audit Standard v0.2 (255 chỉ báo, PASS/KHÔNG PASS nhị phân).

Trọng tâm lần này theo yêu cầu chủ dự án: soi kỹ CODE và NỘI DUNG (AS-03 → AS-06, AS-10). Đổi lại, nhiều chỉ báo về docs/product/UX chỉ được chấm lại ở mức có bằng chứng sẵn — chúng rơi vào mã CM, và đó là lý do điểm tổng thấp hơn Audit #003 dù không có chức năng nào vừa hỏng thêm. Đọc §2 trước khi so hai con số.

1. Điểm ​

Điểm hệ145/255 = 56.9%
Mức trưởng thànhĐang dựng
🔴 KHÔNG PASS10/30
🚸 Pilot Gate11/18 — NO-GO
BộĐiểm
AS-01 — Tài liệu & Đóng vết18/25 = 72%██████████████░░░░░░
AS-02 — Yêu cầu & Sản phẩm12/25 = 48%██████████░░░░░░░░░░
AS-03 — Kiến trúc & Hợp đồng API15/25 = 60%████████████░░░░░░░░
AS-04 — Dữ liệu & Migration15/30 = 50%██████████░░░░░░░░░░
AS-05 — Trí tuệ học tập & Thuật toán21/25 = 84%█████████████████░░░
AS-06 — Nội dung & Tri thức6/25 = 24%█████░░░░░░░░░░░░░░░
AS-07 — Bảo mật, Riêng tư & Tuân thủ17/25 = 68%██████████████░░░░░░
AS-08 — Tin cậy & Vận hành21/25 = 84%█████████████████░░░
AS-09 — Trải nghiệm & Design System5/25 = 20%████░░░░░░░░░░░░░░░░
AS-10 — AI Governance & Chi phí15/25 = 60%████████████░░░░░░░░

2. Tách KHÔNG PASS theo mã lý do — đọc trước khi so với Audit #003 ​

MãNghĩaSố chỉ báo
HHĐã kiểm được và ĐANG HỎNG — có phản ví dụ cụ thể27
CMCó tồn tại nhưng lần này chưa đủ bằng chứng để kết luận66
CXPhần hệ thống liên quan chưa xây17

%HH trong tổng KHÔNG PASS = 27/110 = 25% — đây là con số duy nhất đọc ra "hệ đang hỏng".

So sánh thô với Audit #003 (172/255 = 67,5%) sẽ đọc sai. Ba điều cần biết:

  1. Lần này 66 chỉ báo mang mã CM — phần lớn thuộc AS-02 (product) và AS-09 (UX), là hai bộ mà lần audit này cố ý không đi rà lại vì yêu cầu là soi code + nội dung. L3 của chuẩn buộc "không bằng chứng = KHÔNG PASS", nên chúng bị trừ điểm dù chưa chắc đã hỏng.
  2. Ngược lại, 27 chỉ báo HH là phát hiện mới thật, phần lớn nằm ở AS-06 (nội dung) — chỗ mà ba lần audit trước chấm rất mỏng. Đây là giá trị thật của lần chấm này.
  3. Hệ đã lớn hơn nhiều so với 2026-08-15: 56 migration (39), 1.600 skill node, 11.336 item, 8 model chạy thật cho 12/12 learner. Mẫu số chỉ báo không đổi nhưng bề mặt cần chứng minh thì tăng.

3. 🔴 chặn phát hành đang KHÔNG PASS ​

Chỉ báoMãVì sao
AS-04.5.5CXdocs/ops/backup-restore-drill.md tồn tại nhưng lần audit này chưa xác nhận có ngày diễn tập thật ≤ chu kỳ
AS-04.6.1HHd1_migrations remote có 57 dòng / đĩa 56 file; dòng mồ côi 0046_context_event_temporal.sql (đã đổi tên thành 0052 ở commit d4d582c) KHÔNG có trong migration-reconciliation.md — bản đối soát đang ghi tình trạng cũ (41 dòng/39 file)
AS-04.6.3CMschema-diff production ↔ dryrun gần nhất là 2026-08-15, chưa chạy lại sau 17 migration mới
AS-06.3.1HH0 item ở trạng thái candidate, 0 dòng item_versions — mọi nội dung vào thẳng published, không qua candidate version
AS-06.4.2CXchưa có đề thật (xem 06.4.1)
AS-06.4.3CXchưa có đề thật
AS-07.1.1CM189 route; middleware đăng ký theo vòng lặp path nên đếm thô không kết luận được; chưa có artifact liệt kê route public có chủ đích
AS-07.2.1CMchưa rà từng endpoint chạm bảng có learner_id trong lần này
AS-09.3.1CMchưa đo contrast bằng axe/lighthouse trong lần này
AS-10.4.1HHkhông có cổng đánh giá trước publish: 11.336/11.336 item published có quality_score NULL, evaluator_count<2 (xem AS-06.2/06.3)

4. 🚸 Pilot Gate — NO-GO ​

11/18 PASS. Các dòng còn đỏ:

Chỉ báoMãViệc phải làm để mở được
AS-03.5.3CMGọi gh api .../branches/main/protection, hoặc đi nhánh (b) — nhưng nhánh (b) đòi AS-04.6.1 sạch
AS-04.5.5CXDiễn tập backup/restore D1 một lần và ghi số bảng/số dòng sau restore
AS-04.6.1HHChạy lại đối soát d1_migrations ↔ đĩa, ghi dòng mồ côi 0046_context_event_temporal.sql vào migration-reconciliation.md
AS-04.6.3CMChạy lại schema-diff production ↔ migrate:dryrun (bản gần nhất là 2026-08-15, đã 17 migration trước)
AS-07.1.1CMSinh artifact liệt kê mọi route + middleware bảo vệ nó, xác nhận từng route public là public có chủ đích (nên làm thành cổng CI để không trôi lại)
AS-07.2.1CMRà từng endpoint chạm bảng có learner_id, xác nhận đi qua canAccessLearner/requireLearnerAccess
AS-10.4.1HHDựng cổng đánh giá trước publish cho item (hiện 11.336/11.336 item vào thẳng published không có điểm chất lượng)

5. Phát hiện HH — thứ đang hỏng thật ​

Xếp theo mức chạm tới learner thật, không theo thứ tự bộ.

5.1 🥇 229 Unit đang hiện cho learner là NGÕ CỤT (AS-06.1.4) ​

Đo trên production, đã loại các Package tạm ẩn (SH/DS/HH/VOC/GR/RD/WR):

MônUnit đang hiện0 câu hỏiDưới 10 câu
Hoá học27595261
Sinh học786464
Tin học21636216
Vật lí27933199
Ngữ văn21511
SAT / IELTS / AP54053
Toán · Tiếng Anh · GenAI22300

Đây đúng lớp lỗi mà SRC-402 đã sửa cho môn Ngữ văn: learner bấm vào Unit thì API trả "chưa có câu hỏi để luyện". Cây curriculum của bốn môn Lý/Hoá/Sinh/Tin vừa được dựng (Pearl) và đã bày ra cho learner, nhưng kho câu hỏi chưa theo kịp. Toán, Tiếng Anh, GenAI, Ngữ văn thì sạch.

5.2 🥈 Kho item không có bất kỳ dấu vết chất lượng nào (AS-06.2.1/2.2/2.3, AS-06.3.1/3.3/3.4, AS-10.4.1/4.2) ​

SELECT trên production, 11.336 item published:

CộtSố dòng trống
quality_json11.336 / 11.336
quality_score11.336 / 11.336
evaluator_count >= 20 item đạt
published_by11.336 / 11.336
review_status = 'unreviewed'11.336 / 11.336
items ở trạng thái candidate0
item_versions0 dòng

Schema đã có đủ chỗ cho vòng đời candidate → published (SDD-013), nhưng chưa có gì đi qua nó: mọi item được nạp thẳng vào published. Hệ quả theo đúng chữ của chuẩn: AS-06.3.1 (🔴 "nội dung production không sửa trực tiếp") và AS-10.4.1 (🔴 "nội dung không publish thẳng") đều KHÔNG PASS, và không truy được ai/cái gì đã publish 11 nghìn câu hỏi đang chạy cho trẻ em.

5.3 126 lab đã soạn xong nhưng learner không thấy (AS-06.1.4 phụ) ​

MônLab liveunit = NULL (không gắn vào Unit nào)
Tiếng Anh11388
Ngữ văn5133
Hoá · Sinh · Lý305
Toán1250

Dashboard và La bàn tra lab theo labs.unit (progress/routes.ts:55), nên lab có unit = NULL tồn tại trong DB mà không nút nào mở được. Toán sạch tuyệt đối (125/125 gắn đủ) — chứng minh đây là nợ gắn kết, không phải giới hạn kỹ thuật.

5.4 838 node thiếu ba câu "vì sao đáng học" và can_do (AS-06 phụ, chạm SDD-021 §5) ​

MônNode đang hiệnThiếu why_painThiếu can_do
Tin học216216216
Vật lí279215215
Hoá học275213213
Ngữ văn2298484
SAT/AP/IELTS/GenAI737373
Sinh học801616
Toán19510
Tiếng Anh6400

Thiếu các trường này thì popover "vì sao đáng học", tính năng hé cửa (SDD-021 §5) và câu "đang chặn N bài sau" đều câm — đúng lỗ hổng SRC-401 đã đóng cho Toán/Văn/Anh, nay lộ ra ở các môn mới.

5.5 Prerequisite graph chỉ có ở 2/11 môn ​

unit_prereqs: Toán 225 cạnh, Ngữ văn 145 cạnh, 9 môn còn lại 0 cạnh — kể cả Tiếng Anh (SRC-401 từng soạn 128 cạnh cho cây cũ; cây mới dựng lại ở SRC-408 và bảng hiện không còn cạnh nào cho english).

5.6 Dòng migration mồ côi trên production (AS-04.6.1 🔴, AS-04.6.2, AS-04.6.5) ​

d1_migrations remote có 57 dòng, đĩa có 56 file. Dòng mồ côi: 0046_context_event_temporal.sql — file này đã đổi tên thành 0052_context_event_temporal.sql (commit d4d582c, gỡ trùng số 0046). docs/ops/migration-reconciliation.md vẫn đang ghi tình trạng ngày 2026-08-15 (41 dòng / 39 file, hai dòng mồ côi khác đã được dọn) nên lệch hiện tại chưa được khai báo ở đâu.

5.7 Song ngữ hụt ở 4 môn mới (AS-04.4.5, AS-06.1.5) ​

subjects thiếu name_en: sat, ap, genai, ielts — cả bốn cái tên vốn đã là tiếng Anh. strands thiếu name_en: đúng 20 strand của chính bốn môn đó. skill_nodes thì sạch (0/1.600 thiếu title_en).

5.8 Ranh giới module đã thủng nhưng bảng ngoại lệ còn trống (AS-03.1.2) ​

10 cạnh import chéo trực tiếp giữa hai module, trong khi bảng "Ngoại lệ tường minh" của chuẩn ghi "hiện trống — thêm dòng khi có cạnh mới cố ý, không âm thầm chấp nhận":

TừTới
coral/routes.tscontent/quality, content/lifecycle, content/review-queue
learning/routes.tsknowledge/mastery, retention/service, content/lifecycle, models/service
progress/routes.tsknowledge/mastery
admin/observability.tsmodels/service, models/contextEvents

5.9 Các phát hiện HH nhỏ hơn ​

Chỉ báoPhát hiện
AS-01.1.4SRC-206 bị dùng cho hai chỉ đạo khác nhau (intake.md dòng 328 và 331)
AS-01.1.3257/411 SRC id không xuất hiện ở bất kỳ PRD/SDD/QG nào — sổ tiếp nhận đang chạy nhanh hơn việc canonical hoá
AS-01.1.1/1.5scripts/b21-plan.md là ghi chép kỹ thuật nằm ngoài docs/
AS-02.4.2Cột Parents của admin (SRC-404) đang chạy production nhưng chưa có REQ
AS-02.5.26 hit cụm rỗng nghĩa trong open-questions/index.md
AS-03.1.3apps/mentors/src/showcase.ts gọi fetch( ngoài src/api.ts
AS-03.4.210 file ngoài src/api.ts chứa literal nemo12.com, chưa có danh sách miễn trừ
AS-05.1.4reference/models.md §1 liệt kê 7 model, thiếu Recommendation Model đang chạy thật
AS-05.3.1Constraint Engine và Readiness Engine chưa có test hành vi riêng (6/8 engine có)
AS-05.5.41/305 dòng learner_model_versions có confidence NULL (bản ghi cũ)
AS-09.3.41 thẻ <img> không có alt

6. Những gì đang VỮNG — không phải chỗ nào cũng nợ ​

  • AS-05 (84%) và AS-08 (84%) là hai bộ khoẻ nhất. 8/8 model tồn tại cho 12/12 learner; 640 engine run và 75 workflow run, 0 dòng failed; cron 21:00 UTC chạy thật; mọi lời gọi ra ngoài có timeout; DLQ 0 message kẹt.
  • Kỷ luật migration: 56 file, 0 trùng số, 0 khoảng trống, migrate:dryrun dựng lại được từ D1 rỗng, PRAGMA foreign_key_check production 0 dòng.
  • Đường AI: đúng một điểm gọi env.AI.run( trong toàn repo và nó đi qua AI Gateway; 0 lời gọi AI từ frontend; Context Builder là cửa duy nhất chạm learner data, có test chống lẫn learner.
  • Hợp đồng API: 163/163 route /v1, spec sinh từ router, contract:diff chặn breaking change trên mọi push; probe production trả đúng {error:{code,message}}.
  • Bảo mật nền: 0 secret hardcode, admin sau Cloudflare Access, audit log không sửa được từ ứng dụng, parent authz có test chạy trên D1 thật.

7. Hành động sinh ra từ audit này ​

Mỗi dòng là một việc có kết quả kiểm được. Thứ tự = thứ tự làm.

#ViệcĐóng chỉ báoCỡ
A1Chạy lại đối soát migration + schema-diff, cập nhật migration-reconciliation.mdAS-04.6.1 🔴🚸, 04.6.2, 04.6.3 🔴🚸, 04.6.5nhỏ
A2Sinh artifact phủ auth cho 189 route (kèm cổng CI) và rà authz learner dataAS-07.1.1 🔴🚸, 07.2.1 🔴🚸vừa
A3Nạp name_en cho 4 subject + 20 strandAS-04.4.5, 06.1.5nhỏ
A4Thêm Recommendation Model vào bảng tổng models.mdAS-05.1.4nhỏ
A5Test hành vi cho Constraint Engine và Readiness EngineAS-05.3.1nhỏ
A6Gỡ trùng SRC-206; đưa scripts/b21-plan.md vào docs/AS-01.1.1, 01.1.4, 01.1.5nhỏ
A7Ghi 10 cạnh import chéo vào bảng Ngoại lệ, hoặc gỡ cạnh nào gỡ đượcAS-03.1.2nhỏ
A8apps/mentors/src/showcase.ts gọi qua api.ts; thêm alt cho ảnh thiếuAS-03.1.3, 09.3.4nhỏ
A9Gắn 126 lab unit = NULL vào đúng UnitAS-06.1.4 phụvừa
A10Soạn câu hỏi cho 229 Unit ngõ cụt (Hoá 95 · Sinh 64 · Tin 36 · Lý 33 · Văn 1)AS-06.1.4LỚN
A11Soạn why_pain/why_gain/why_example/can_do cho 838 nodeAS-06 phụ, SDD-021 §5LỚN
A12Prerequisite graph cho 9 môn còn trốngAS-06.1.3 phụLỚN
A13Dựng cổng chất lượng trước publish + backfill quality profile cho 11.336 itemAS-06.2.1/2.2/2.3, 06.3.1 🔴, 06.3.3, 06.3.4, 10.4.1 🔴🚸, 10.4.2LỚN
A14Diễn tập backup/restore D1 và ghi lạiAS-04.5.5 🔴🚸vừa
A15Sinh docs/reference/ui-minimalism-audit.md (5 chỉ báo AS-09.1 đang CX vì thiếu artifact)AS-09.1.1–1.5vừa
A16Đo contrast WCAG AA cho token của design systemAS-09.3.1 🔴🚸vừa
A17Canonical hoá 257 SRC còn treo, bắt đầu từ các SRC có code đang chạyAS-01.1.3, 02.4.2LỚN

8. Chi tiết theo chỉ báo ​

Ký hiệu: ✅ PASS · ❌ KHÔNG PASS (kèm mã CX/CM/HH). 🔴 chặn phát hành · 🚸 Pilot Gate.

AS-01.1 — Nguồn duy nhất & sổ tiếp nhận

Chỉ báoBằng chứng
AS-01.1.1❌ HHscripts/b21-plan.md là ghi chép khảo sát/kế hoạch nằm ngoài docs/, không phải README hay nội dung app
AS-01.1.2✅412 dòng `
AS-01.1.3❌ HH257/411 SRC id không xuất hiện ở bất kỳ PRD/SDD/QG nào ngoài intake.md (đếm bằng grep toàn docs/)
AS-01.1.4❌ HHSRC-206 xuất hiện HAI lần (intake.md:328 và :331) — dòng 412, uniq 411; không có khoảng trống, 'Nguồn tiếp theo' = 412 khớp max+1
AS-01.1.5❌ HHcùng phản ví dụ 01.1.1

AS-01.2 — Frontmatter & metadata

Chỉ báoBằng chứng
AS-01.2.1✅npm run check:docs mục 1 xanh — 91 file docs đủ frontmatter, id duy nhất, type/status hợp lệ
AS-01.2.2✅npm run check:docs mục 1 xanh — 91 file docs đủ frontmatter, id duy nhất, type/status hợp lệ
AS-01.2.3✅npm run check:docs mục 1 xanh — 91 file docs đủ frontmatter, id duy nhất, type/status hợp lệ
AS-01.2.4✅npm run check:docs mục 1 xanh — 91 file docs đủ frontmatter, id duy nhất, type/status hợp lệ
AS-01.2.5✅npm run check:docs mục 1 xanh — 91 file docs đủ frontmatter, id duy nhất, type/status hợp lệ

AS-01.3 — Đóng vết hai chiều

Chỉ báoBằng chứng
AS-01.3.1✅check-docs mục 2 (trace closure satisfies ↔ REQ) xanh
AS-01.3.2✅check-docs mục 3: mọi dòng REQ ✔ phải có SDD + QG; 268 tham chiếu QG- trong PRD-001
AS-01.3.3✅check-docs kiểm sources trỏ SRC tồn tại — xanh
AS-01.3.4❌ CMcheck-docs mục 4 chỉ bắt link gãy, không bắt file không ai trỏ tới; lần này chưa chạy đối chiếu file↔link đích
AS-01.3.5❌ CM275 tham chiếu US- trong PRD-001 có cột REQ, nhưng chiều ngược (mọi REQ MUST có ≥1 US/WF) chưa đo trong lần này

AS-01.4 — Trang sinh tự động khớp source

Chỉ báoBằng chứng
AS-01.4.1 🔴🚸✅npm run gen:reference xong, git diff docs/reference rỗng
AS-01.4.2✅data-dictionary.md sinh từ migrations bởi gen-reference.mjs, không drift (01.4.1)
AS-01.4.3✅api.md sinh từ router; snapshot 163 path, contract:diff xanh
AS-01.4.4✅events.md sinh từ EVENT_REGISTRY (21 entry), không drift
AS-01.4.5✅các trang sinh tự động mở đầu bằng dòng '⚙️ Trang này sinh tự động'

AS-01.5 — Tươi mới & vòng đời

Chỉ báoBằng chứng
AS-01.5.1✅0/91 doc active có last_reviewed quá 90 ngày (đo ngày 2026-08-20)
AS-01.5.2❌ CMchưa spot-check ≥5 commit sửa nội dung có tăng version trong lần audit này
AS-01.5.3✅check-docs mục 4 — 0 internal link gãy
AS-01.5.4✅20 hit 'tuần trước/gần đây/sắp tới' — tất cả là trích dẫn, chữ UI, hoặc chính câu cấm trong conventions.md
AS-01.5.5✅✍️ xuất hiện ở 14 file, open-questions/index.md là nơi tập trung; audit #003 đã đối chiếu

AS-02.1 — Chất lượng REQ catalog

Chỉ báoBằng chứng
AS-02.1.1✅REQ id đúng scheme REQ-<nhóm>-xx, nhóm khớp bảng conventions.md §2
AS-02.1.2❌ CMchưa chạy grep từ mơ hồ trên riêng các dòng REQ trong lần này
AS-02.1.3✅0 hit M?/S?/C? trong PRD-001
AS-02.1.4✅bảng REQ có cột nguồn SRC-xxx
AS-02.1.5❌ CMchưa chạy script token-overlap tìm REQ trùng nghĩa trong lần này

AS-02.2 — User story & acceptance criteria

Chỉ báoBằng chứng
AS-02.2.1✅98 dòng 'As a' trong PRD-001 §6, đúng format As a/I want/so that
AS-02.2.2✅persona trong US thuộc tập Nemo/Marlin/Dolphin/Staff đã định nghĩa
AS-02.2.3✅bảng US có cột AC riêng (quan sát được), ví dụ US-01/US-02/US-03
AS-02.2.4✅AC mẫu mô tả điều người dùng thấy (màn hình, nút), không nêu tên bảng D1/tên hàm
AS-02.2.5❌ CMchưa đối chiếu từng US MUST đã implement với route thật trong lần này

AS-02.3 — Persona, JTBD & phủ vai trò

Chỉ báoBằng chứng
AS-02.3.1✅parent-jtbd.md + PRD §personas có JTBD cho từng persona active
AS-02.3.2❌ CMchưa trace từng JTBD → REQ trong lần này
AS-02.3.3✅docs/workflows/ có learner-onboarding.md, parent-onboarding.md, mentor-onboarding.md
AS-02.3.4❌ CMSDD-011 chưa đối chiếu trong lần này
AS-02.3.5❌ CMchưa rà ngược route từng app về persona trong lần này

AS-02.4 — Phạm vi & ưu tiên

Chỉ báoBằng chứng
AS-02.4.1❌ CMchưa trace từng REQ ✔ về artifact thực thi trong lần này
AS-02.4.2❌ HHcó tính năng đang chạy production mà chưa có REQ: cột Parents của bảng learner admin (SRC-404) mới chỉ có dòng intake, chưa canonical hoá vào PRD/SDD
AS-02.4.3❌ CM51 hit CC-/FEAT- trong PRD-001 — chưa tách được hit nào nằm trong bảng REQ chính, hit nào ở phần backlog
AS-02.4.4✅legacy-feature-inventory.md: 0 dòng 'chưa-quyết'
AS-02.4.5❌ CMchưa rà PRD §7 cho REQ MUST ⏳ quá 30 ngày trong lần này

AS-02.5 — Quyết định mở & phê duyệt

Chỉ báoBằng chứng
AS-02.5.1✅open-questions/index.md dùng ID Q-xxx kèm trạng thái
AS-02.5.2❌ HH6 hit cụm rỗng nghĩa ('tự quyết'/'theo ý chủ dự án'…) trong open-questions/index.md
AS-02.5.3❌ CMchưa đọc lại artifact 'Rà mâu thuẫn giữa các quyết định ✍️' xem còn ≤90 ngày và khai phạm vi
AS-02.5.4✅bảng 'Việc còn chờ chủ dự án' có cột Trạng thái, mọi dòng có giá trị
AS-02.5.5❌ CMchưa kiểm từng Q đã trả lời có cột 'Đã vào' resolve được

AS-03.1 — Ranh giới module & monorepo

Chỉ báoBằng chứng
AS-03.1.1✅`grep -rln createRoute workers/api/src
AS-03.1.2❌ HH10 cạnh import chéo module trực tiếp trong khi bảng Ngoại lệ tường minh còn TRỐNG: coral→content (3), learning→knowledge/retention/content/models (4), progress→knowledge, admin→models (2)
AS-03.1.3❌ HHapps/mentors/src/showcase.ts gọi fetch( ngoài src/api.ts
AS-03.1.4✅không app nào định nghĩa lại custom property đã có trong design-system tokens
AS-03.1.5❌ CMchưa đối chiếu ls apps workers với README §cấu trúc trong lần này

AS-03.2 — Hợp đồng API

Chỉ báoBằng chứng
AS-03.2.1✅find .yaml/openapi.json ngoài snapshot → rỗng; spec sinh từ router
AS-03.2.2❌ CMchưa đếm operation thiếu schema bằng contract:diff --print trong lần này
AS-03.2.3✅163/163 path trong openapi.snapshot.json bắt đầu bằng /v1
AS-03.2.4 🔴🚸✅npm run contract:diff xanh; chạy trong ci.yml và deploy-api.yml trên mọi push
AS-03.2.5✅probe production: /v1/khong-ton-tai → {error:{code:NOT_FOUND}}, /v1/me → AUTHORIZATION_ERROR; không rò ZodError/stack

AS-03.3 — Hợp đồng event/queue

Chỉ báoBằng chứng
AS-03.3.1✅EVENT_REGISTRY 21 entry, mỗi entry có version + payload zod
AS-03.3.2❌ CMchưa đối soát hai chiều publishEvent ↔ registry trong lần này
AS-03.3.3✅tên event khớp domain.entity.action, action ở thì quá khứ
AS-03.3.4✅assertNoFreeText() tồn tại và được gọi trong publishEvent
AS-03.3.5❌ CMchưa đối chiếu số queue/max_batch_size/max_retries giữa wrangler.jsonc và queues.md

AS-03.4 — Vệ sinh secret/config

Chỉ báoBằng chứng
AS-03.4.1 🔴✅grep pattern key/secret/token hardcode trên apps+workers+scripts+packages → rỗng
AS-03.4.2❌ HH10 file ngoài src/api.ts chứa literal nemo12.com (learn/marlins/coral/mentors) — phần lớn là link footer/school info, nhưng chưa có danh sách miễn trừ tường minh
AS-03.4.3✅verify-bindings Lớp A xanh — mọi biến bắt buộc khai kiểu trong env.ts
AS-03.4.4❌ CMverify:bindings chạy Lớp A+B (không có CLOUDFLARE_API_TOKEN cục bộ); Lớp C chỉ chạy trong CI
AS-03.4.5✅verify-bindings Lớp B xanh — config.md khớp wrangler.jsonc (8 binding / 9 file)

AS-03.5 — Cấu trúc & kỷ luật pipeline deploy

Chỉ báoBằng chứng
AS-03.5.1✅9 wrangler.jsonc ↔ 9 workflow deploy-*.yml, path filter khớp
AS-03.5.2✅0 file wrangler.jsonc thiếu custom_domain/routes
AS-03.5.3 🚸❌ CMchưa gọi gh api .../branches/main/protection trong lần này; nhánh (b) đòi AS-04.6.1 sạch mà 04.6.1 đang KHÔNG PASS
AS-03.5.4✅deploy-api.yml: bước 'Apply D1 migrations' đứng trước bước 'Deploy worker'
AS-03.5.5❌ CMchưa curl từng URL production trong README trong lần này

AS-04.1 — Kỷ luật viết migration

Chỉ báoBằng chứng
AS-04.1.1 🔴🚸✅56 file migration, 0 số trùng, 0 khoảng trống 0001..0056
AS-04.1.2✅0 câu CREATE TABLE/INDEX thiếu IF NOT EXISTS (bỏ dòng comment)
AS-04.1.3✅mọi DELETE/UPDATE trong migrations đều có WHERE (0035 có WHERE source_kind/status)
AS-04.1.4 🔴✅npm run migrate:dryrun exit 0, chạy trong ci.yml và deploy-api.yml
AS-04.1.5✅0 file trên đĩa chưa áp — chiều file→applied sạch

AS-04.2 — Thiết kế schema

Chỉ báoBằng chứng
AS-04.2.1❌ CMchưa dump từng CREATE TABLE production để xác nhận PK trong lần này
AS-04.2.2 🔴✅grep REFERENCES users(email) → rỗng
AS-04.2.3❌ CMchưa đối chiếu từng cột *_id với REFERENCES/danh sách miễn trừ trong lần này
AS-04.2.4✅`grep '_at INTEGER
AS-04.2.5✅0 hit json_extract trong workers/api/src

AS-04.3 — Ngữ nghĩa & enum

Chỉ báoBằng chứng
AS-04.3.1✅data-dictionary.md sinh tự động từ migrations, không drift
AS-04.3.2❌ CMchưa chạy script so mô tả cột với tên kiểu trong lần này
AS-04.3.3✅data-dictionary sinh từ chính migrations nên không thể có bảng ma
AS-04.3.4❌ CMchưa đối chiếu từng CHECK(... IN ...) với data-dictionary trong lần này
AS-04.3.5❌ CMchưa đối chiếu state-machines.md với tập CHECK trong lần này

AS-04.4 — Toàn vẹn vận hành

Chỉ báoBằng chứng
AS-04.4.1❌ CMchưa rà từng script trong scripts/ có --remote kèm xác nhận trong lần này
AS-04.4.2❌ CMchưa chạy seed script hai lần trên D1 local để đo idempotency trong lần này
AS-04.4.3✅PRAGMA foreign_key_check trên production → 0 dòng
AS-04.4.4❌ CMchưa đối chiếu khoá nghiệp vụ khai trong data-dictionary với UNIQUE index thật
AS-04.4.5❌ HH4 subjects (sat, ap, genai, ielts) thiếu name_en và 20 strands của chính 4 môn đó thiếu name_en trên production

AS-04.5 — Riêng tư & lưu trữ

Chỉ báoBằng chứng
AS-04.5.1✅RETENTION_BASELINE trong shared/privacy.ts: mỗi loại dữ liệu có keep_days + rationale + cờ pii
AS-04.5.2✅module privacy có bảng data_deletion_requests và route xoá dữ liệu theo yêu cầu
AS-04.5.3✅rp-model-version giữ 365 ngày, rp-engine-run/rp-workflow-run 90 ngày — chính sách khai bằng số
AS-04.5.4❌ CMchưa đối chiếu từng trường PII với lý do tồn tại trong data-dictionary §PII
AS-04.5.5 🔴🚸❌ CXdocs/ops/backup-restore-drill.md tồn tại nhưng lần audit này chưa xác nhận có ngày diễn tập thật ≤ chu kỳ

AS-04.6 — Đối soát production

Chỉ báoBằng chứng
AS-04.6.1 🔴🚸❌ HHd1_migrations remote có 57 dòng / đĩa 56 file; dòng mồ côi 0046_context_event_temporal.sql (đã đổi tên thành 0052 ở commit d4d582c) KHÔNG có trong migration-reconciliation.md — bản đối soát đang ghi tình trạng cũ (41 dòng/39 file)
AS-04.6.2❌ HH1 dòng mồ côi (xem 04.6.1)
AS-04.6.3 🔴🚸❌ CMschema-diff production ↔ dryrun gần nhất là 2026-08-15, chưa chạy lại sau 17 migration mới
AS-04.6.4 🔴🚸✅0 DROP COLUMN/RENAME COLUMN; 0 ADD COLUMN NOT NULL thiếu DEFAULT kể từ mốc 2026-08-15
AS-04.6.5❌ HHđúng trường hợp cảnh báo: filename từng có trong d1_migrations production không còn trên đĩa và chưa có dòng giải thích

AS-05.1 — Định nghĩa model & versioning

Chỉ báoBằng chứng
AS-05.1.1✅reference/ có trang riêng cho learner/context/goal/readiness/retention/constraint/learning-plan/recommendation
AS-05.1.2✅learner_model_versions.model_version = 'deterministic' cho 304/305 dòng; algorithm_version dạng <model>-v1 ghi trong content
AS-05.1.3✅305 version trên production, có generated_at, dedupe theo SHA-256 nội dung
AS-05.1.4❌ HHmodels.md §1 'Bảng tổng' liệt kê 7 model, THIẾU Recommendation Model đang chạy thật (model_kind recommendation, SRC-207)
AS-05.1.5✅đổi thuật toán đi kèm tăng algorithm_version; runlog dedupe theo hash nội dung

AS-05.2 — Đường evidence → model

Chỉ báoBằng chứng
AS-05.2.1✅learner_evidence 561 dòng, mỗi dòng có source + occurred_at + event_id
AS-05.2.2 🔴✅route self-report ghi vào learner_evidence trước, engine đọc lại từ đó
AS-05.2.3✅learner_evidence: 0/561 dòng thiếu reliability; 4 nguồn phân loại
AS-05.2.4✅learning/selection + expstate test phủ hành vi 'sửa lại không tạo evidence trùng'
AS-05.2.5✅engine_runs 640 dòng, workflow_runs 75 dòng, 0 dòng failed

AS-05.3 — Engine correctness

Chỉ báoBằng chứng
AS-05.3.1❌ HH2/8 engine không có test hành vi riêng: Constraint Engine (models/constraint.ts) và Readiness Engine (computeReadiness trong knowledge/mastery.ts) — grep test file → 0
AS-05.3.2✅không test nào readFileSync mã nguồn rồi .includes()
AS-05.3.3✅goals/engine.test.ts, recommendation.test.ts, contextEvents.test.ts đều có ca rỗng
AS-05.3.4❌ CMchưa đọc lại test stopping criteria của diagnosis/adaptive trong lần này
AS-05.3.5✅ci.yml bước 3 và deploy-api.yml bước 'Test' chạy npm test, không `

AS-05.4 — Retention & Mastery

Chỉ báoBằng chứng
AS-05.4.1 🔴✅retention/periodic.test.ts giữ bất biến mastery không tự suy giảm
AS-05.4.2✅reference/retention-model.md ghi công thức decay + retention/engine.test.ts
AS-05.4.3✅wrangler.jsonc crons: [0 21 * * *]; schedules.md ghi đúng lịch; workflow_runs có WF-17
AS-05.4.4✅periodic.test.ts giữ bất biến job định kỳ không đụng anchor
AS-05.4.5✅tham số review window ghi trong reference/retention-model.md

AS-05.5 — Giải thích được

Chỉ báoBằng chứng
AS-05.5.1✅recommendation.ts: mỗi việc kèm why + from truy được về model sinh ra nó
AS-05.5.2✅learner_model_versions ghi model_version + algorithm_version cho mỗi bản
AS-05.5.3✅planning.ts ghi diff so với bản trước; UI /ke-hoach hiển thị
AS-05.5.4❌ HH1/305 dòng learner_model_versions có confidence NULL và 1 dòng model_version NULL (bản ghi cũ trước khi cột tồn tại)
AS-05.5.5✅admin #/models mở được mọi phiên bản model theo thời gian; learner/parent xem qua marlins

AS-06.1 — Knowledge graph toàn vẹn

Chỉ báoBằng chứng
AS-06.1.1✅skill_nodes: 1600 node, 0 node thiếu subject_id; grade/level có ở cây B21
AS-06.1.2✅0 node thiếu strand; unit gán đủ cho các cây đang hiện
AS-06.1.3❌ CMchưa chạy DFS phát hiện chu trình trên unit_prereqs trong lần này
AS-06.1.4❌ HH229 Unit đang HIỆN cho learner mà 0 câu hỏi published: chemistry 95, biology 64, informatics 36, physics 33, vietnamese 1 — learner bấm vào là gặp ngõ cụt. Thêm 989 Unit dưới ngưỡng 10 câu
AS-06.1.5❌ HH4 subjects + 20 strands thiếu name_en (xem 04.4.5); node thì đủ (0/1600 thiếu title_en)

AS-06.2 — Chất lượng item

Chỉ báoBằng chứng
AS-06.2.1❌ HH11.336/11.336 item published có quality_json NULL — 0% có quality profile 8 chiều
AS-06.2.2❌ HH0 item nào có evidence kèm theo cho từng chiều chất lượng (quality_json rỗng toàn bộ)
AS-06.2.3❌ HHevaluator_count < 2 trên 11.336/11.336 item — không có multi-evaluator variance check trước publish
AS-06.2.4✅items: 0/11.336 dòng thiếu node_id
AS-06.2.5✅content_reports nối vào hàng đợi rà soát thật qua ingestContentReports() (coral + forum)

AS-06.3 — Vòng đời nội dung

Chỉ báoBằng chứng
AS-06.3.1 🔴❌ HH0 item ở trạng thái candidate, 0 dòng item_versions — mọi nội dung vào thẳng published, không qua candidate version
AS-06.3.2✅items.status có CHECK (candidate
AS-06.3.3❌ HHquality_score NULL trên toàn bộ item published — publish không đi qua ngưỡng chất lượng bằng số
AS-06.3.4❌ HHpublished_by NULL trên 11.336/11.336 item — không truy được ai/cái gì publish
AS-06.3.5❌ CXitem_versions rỗng nên rollback nội dung về version trước chưa có đường thật

AS-06.4 — Đề thi thật & provenance

Chỉ báoBằng chứng
AS-06.4.1❌ CX0 dòng exams source_kind='real' — chưa có đề thật nào để chấm
AS-06.4.2 🔴❌ CXchưa có đề thật (xem 06.4.1)
AS-06.4.3 🔴❌ CXchưa có đề thật
AS-06.4.4❌ CXchưa có crawler chạy thật
AS-06.4.5❌ CXchưa có đề thật

AS-06.5 — Media & bản quyền

Chỉ báoBằng chứng
AS-06.5.1❌ CXbảng media 0 dòng — pipeline moderation chưa có gì đi qua
AS-06.5.2❌ CXchưa có media
AS-06.5.3✅REQ-LRN-20 zero-asset: hình sinh bằng SVG từ tham số, không nhúng logo/ảnh bên thứ ba
AS-06.5.4❌ CXchưa có media
AS-06.5.5❌ CXchưa có media chứa hình trẻ em

AS-07.1 — Xác thực & phiên

Chỉ báoBằng chứng
AS-07.1.1 🔴🚸❌ CM189 route; middleware đăng ký theo vòng lặp path nên đếm thô không kết luận được; chưa có artifact liệt kê route public có chủ đích
AS-07.1.2✅sessions có expires_at, revoked_at, rotated_from — có hạn và thu hồi được
AS-07.1.3✅auth/access.ts ghim issuer + audience + RS256 + exp; access.test.ts 8 test
AS-07.1.4 🚸✅admin.nemo12.com đứng sau Cloudflare Access, chỉ dac2205@gmail.com (SRC-129), đã kiểm bằng cách huỷ phiên và tải lại
AS-07.1.5✅grep bypass/skip auth/debug login → không có đường tắt trên production

AS-07.2 — Phân quyền backend

Chỉ báoBằng chứng
AS-07.2.1 🔴🚸❌ CMchưa rà từng endpoint chạm bảng có learner_id trong lần này
AS-07.2.2 🔴✅grep so sánh email trong logic authz → chỉ 1 hit là chuẩn hoá email của Access token, không phải quyết định quyền
AS-07.2.3 🔴🚸✅parent/authz.test.ts chạy trên D1 thật, chứng minh parent chỉ thấy learner trong family mình
AS-07.2.4❌ CMaudit_log có 59 dòng nhưng 0 dòng actor_role='mentor' — chưa có lượt truy cập mentor nào để chứng minh
AS-07.2.5❌ CMchưa đối chiếu ma trận permissions.md với kiểm tra thật trong code

AS-07.3 — Dữ liệu trẻ em & đồng thuận

Chỉ báoBằng chứng
AS-07.3.1❌ CMchưa rà từng trường dữ liệu trẻ em trong data-dictionary
AS-07.3.2 🔴🚸✅bảng consents có 20 dòng ghi ai bật/tắt cái gì, lúc nào
AS-07.3.3✅portrait_learner_sections chỉ role learner ghi được — có test
AS-07.3.4✅lời gọi ra ngoài chỉ tới Cloudflare AI Gateway và Google OAuth — đã khai
AS-07.3.5❌ CMchưa kiểm UI marlins có cho parent xem dữ liệu đang dùng để ra quyết định

AS-07.4 — Audit log

Chỉ báoBằng chứng
AS-07.4.1❌ CMchưa rà từng route mentor/staff chạm learner data có ghi audit_log
AS-07.4.2✅audit_log có actor_user_id, actor_role, action, target_type, target_id, occurred_at, request context
AS-07.4.3✅audit_log chỉ ghi tham chiếu (target_type + target_id), không ghi nội dung nguyên văn
AS-07.4.4✅không endpoint nào UPDATE/DELETE audit_log (ghi rõ trong admin/routes.ts)
AS-07.4.5✅/v1/admin/audit-log có lọc theo actor/target/action/thời gian

AS-07.5 — Bề mặt tấn công

Chỉ báoBằng chứng
AS-07.5.1 🔴✅grep pattern secret trên source → rỗng
AS-07.5.2 🔴✅không route debug/seed mở trên production
AS-07.5.3✅mọi route dùng zod schema qua @hono/zod-openapi + defaultHook
AS-07.5.4❌ CM3 hit dangerouslySetInnerHTML trong apps/*/src chưa xác nhận từng hit không phải input người dùng
AS-07.5.5✅shared/ratelimit.ts + ratelimit.test.ts; rate_limit_buckets có trên production

AS-08.1 — Production-ready

Chỉ báoBằng chứng
AS-08.1.1❌ CMchưa đối chiếu availability tier từng worker trong lần này
AS-08.1.2❌ CMchưa đọc lại 5 câu hỏi production-ready SDD-006 §16
AS-08.1.3❌ CMchưa rà 'hỏng thì người dùng thấy gì' cho các tính năng mới nhất
AS-08.1.4✅/v1/health chạy SELECT 1 trên D1 thật; probe production trả 200
AS-08.1.5✅1 hit TODO duy nhất (marlins/StartWizard.tsx:23) là ghi chú nợ kỹ thuật có mô tả, không chặn đường

AS-08.2 — Idempotency & DLQ

Chỉ báoBằng chứng
AS-08.2.1✅consumer dùng idempotencyKey (10 điểm trong code)
AS-08.2.2 🔴🚸✅wrangler.jsonc khai dead_letter_queue
AS-08.2.3✅/v1/admin/dead-letters + replay endpoint; queue_dead_letters 0 dòng
AS-08.2.4✅max_retries khai trong wrangler.jsonc
AS-08.2.5❌ CMchưa đọc lại cron handler xem có khoá chống chạy chồng

AS-08.3 — Observability

Chỉ báoBằng chứng
AS-08.3.1✅9/9 wrangler.jsonc bật observability
AS-08.3.2✅log có level + request_id xuyên suốt (thấy trong output test workflow)
AS-08.3.3✅errorResponse + logger ghi kèm request_id, workflow_code, learner_id
AS-08.3.4✅engine_runs/workflow_runs đếm được số run + số lỗi; admin #/runs hiển thị
AS-08.3.5✅workflow_runs 75 dòng — biết workflow đã chạy mà không cần đọc log thô

AS-08.4 — CI/CD & rollback

Chỉ báoBằng chứng
AS-08.4.1 🚸✅ci.yml + deploy-api.yml chạy typecheck+lint+test trước deploy (xác nhận trên run 7a2e577)
AS-08.4.2✅mọi deploy-*.yml có paths filter
AS-08.4.3 🔴✅deploy-api.yml: apply migration trước wrangler deploy
AS-08.4.4✅rollback.yml dùng wrangler rollback, không phụ thuộc build
AS-08.4.5✅chỉ bước apply-migration là workflow_dispatch, đã ghi rõ lý do

AS-08.5 — Suy giảm duyên dáng & phụ thuộc ngoài

Chỉ báoBằng chứng
AS-08.5.1✅runPrompt có fallback khi AI lỗi; cache KV hỏng chỉ chậm chứ không lỗi
AS-08.5.2✅reliability.test.ts chứng minh KV/D1 chết vẫn trả dữ liệu thật
AS-08.5.3✅TIMEOUT_MS + withTimeout phủ mọi lời gọi ra ngoài (7 điểm)
AS-08.5.4✅shared/reliability.ts cache đọc nhiều, có test
AS-08.5.5✅errorResponse trả thông điệp tiếng Việt cho người dùng, không stack trace

AS-09.1 — Luật tối giản (SRC-048)

Chỉ báoBằng chứng
AS-09.1.1❌ CXdocs/reference/ui-minimalism-audit.md CHƯA TỒN TẠI — không có artifact để chấm 5 chỉ báo luật tối giản
AS-09.1.2❌ CXdocs/reference/ui-minimalism-audit.md CHƯA TỒN TẠI — không có artifact để chấm 5 chỉ báo luật tối giản
AS-09.1.3❌ CXdocs/reference/ui-minimalism-audit.md CHƯA TỒN TẠI — không có artifact để chấm 5 chỉ báo luật tối giản
AS-09.1.4❌ CXdocs/reference/ui-minimalism-audit.md CHƯA TỒN TẠI — không có artifact để chấm 5 chỉ báo luật tối giản
AS-09.1.5❌ CXdocs/reference/ui-minimalism-audit.md CHƯA TỒN TẠI — không có artifact để chấm 5 chỉ báo luật tối giản

AS-09.2 — Token & component

Chỉ báoBằng chứng
AS-09.2.1❌ CMchưa đếm hex hardcode loại trừ file SVG/art trong lần này
AS-09.2.2❌ CMchưa rà component fork giữa apps và packages trong lần này
AS-09.2.3❌ CMchưa rà CSS riêng theo trang
AS-09.2.4✅tokens/base.css chỉ đổi lớp accent giữa các portal
AS-09.2.5❌ CM39 hit text-xs trong apps/*/src — chưa xác nhận cỡ chữ thực tế ≥14px

AS-09.3 — Accessibility

Chỉ báoBằng chứng
AS-09.3.1 🔴❌ CMchưa đo contrast bằng axe/lighthouse trong lần này
AS-09.3.2❌ CMchưa thử tab qua bàn phím trong lần này
AS-09.3.3❌ CMchưa đo touch target trong lần này
AS-09.3.4❌ HH1 thẻ trong apps/*/src không có alt
AS-09.3.5❌ CMchưa thử điều hướng bàn phím hết luồng chính

AS-09.4 — Ngôn ngữ & nội dung UI

Chỉ báoBằng chứng
AS-09.4.1✅0 chuỗi hiển thị tiếng Việt trong apps/admin/src (grep ký tự có dấu giữa hai thẻ) — admin đã tiếng Anh toàn bộ; learn/marlins tiếng Việt
AS-09.4.2✅popover admin cố ý giữ giải thích tiếng Việt là quyết định SRC-143, không phải lẫn ngôn ngữ ngẫu nhiên
AS-09.4.3❌ CMchưa đối chiếu thuật ngữ UI với glossary.md
AS-09.4.4✅errorResponse trả câu tiếng Việt cho người dùng
AS-09.4.5❌ CMchưa rà chữ lặp lại nội dung đã hiển thị bằng hình

AS-09.5 — Hiệu năng cảm nhận

Chỉ báoBằng chứng
AS-09.5.1❌ CMchưa đo LCP bằng Lighthouse
AS-09.5.2❌ CMchưa đo CLS
AS-09.5.3❌ CMchưa spot-check ≥5 màn cho loading/empty/error
AS-09.5.4✅zero-asset: hình là SVG sinh từ tham số, không có ảnh quá khổ
AS-09.5.5❌ CMchưa thử tay xác nhận chấm client-side trước khi gửi evidence

AS-10.1 — Đường AI duy nhất

Chỉ báoBằng chứng
AS-10.1.1 🔴✅đúng MỘT điểm gọi env.AI.run( (shared/prompts.ts:303) và nó truyền gateway: { id: env.AI_GATEWAY_ID }
AS-10.1.2 🔴✅không có vòng lặp probe model id
AS-10.1.3✅model id khai tường minh trong prompt spec
AS-10.1.4✅0 hit env.AI/ai.run trong apps/*/src
AS-10.1.5❌ CMchưa đối chiếu từng điểm gọi AI với ai-registry.md trong lần này

AS-10.2 — Prompt registry

Chỉ báoBằng chứng
AS-10.2.1✅mọi prompt nằm trong shared/prompts.ts, không inline rải rác
AS-10.2.2✅mỗi prompt spec có version
AS-10.2.3❌ CMchưa spot-check git log chứng minh đổi prompt = version mới
AS-10.2.4✅registry ghi mục đích, đầu vào, ràng buộc đầu ra
AS-10.2.5✅output AI parse qua zod schema trước khi dùng

AS-10.3 — Context Builder & ranh giới dữ liệu

Chỉ báoBằng chứng
AS-10.3.1 🔴🚸✅shared/context-builder.ts là đường duy nhất AI chạm learner data, có test
AS-10.3.2✅builder cắt còn trường cần cho tác vụ
AS-10.3.3✅builder không đưa tên thật/email vào prompt
AS-10.3.4❌ CMchưa xác nhận mọi output AI lưu input_ref
AS-10.3.5 🔴🚸✅shared/context-builder.test.ts có ca chứng minh dữ liệu learner A không lọt sang learner B

AS-10.4 — Đánh giá & chống ảo giác

Chỉ báoBằng chứng
AS-10.4.1 🔴🚸❌ HHkhông có cổng đánh giá trước publish: 11.336/11.336 item published có quality_score NULL, evaluator_count<2 (xem AS-06.2/06.3)
AS-10.4.2❌ HH0 item có multi-evaluator
AS-10.4.3❌ CXchưa có tỷ lệ spot-check bởi người được ghi thành số
AS-10.4.4❌ CMchưa rà nội dung xem khẳng định kiến thức có nguồn/đánh dấu sinh tự động
AS-10.4.5✅content_reports → ingestContentReports → hàng đợi rà soát Coral, không rơi vào hư vô

AS-10.5 — Chi phí & hạn mức

Chỉ báoBằng chứng
AS-10.5.1❌ CMai-registry.md có nhắc chi phí nhưng chưa đối chiếu từng loại lời gọi trong lần này
AS-10.5.2❌ CMchưa mở dashboard AI Gateway (cần scope token đọc gateway)
AS-10.5.3❌ CMchưa xác nhận có hạn mức/cảnh báo cấu hình ở gateway
AS-10.5.4✅WF-17 chạy 1 lần/ngày, có cap số learner mỗi lượt (deferred hiện trong output)
AS-10.5.5✅route sinh nội dung AI chỉ mở cho staff/admin; có rate limit

9. Trace ​

NguồnChuẩnGhi vào
SRC-412 (chỉ đạo: "Audit toàn bộ code và content, tạo ra Audit Report. Sau đó sửa dần theo kết quả audit")audit-standard/index.md v0.2báo cáo này + index + các việc A1..A17

10. Đính chính — 2026-08-20, trong lúc sửa theo A1..A8 ​

Luật của index audit là không sửa đè báo cáo cũ; hai dòng dưới đây là đính chính ghi thêm, không xoá dòng gốc ở §5.9 và §8.

Chỉ báoChấm ban đầuĐúng ra làVì sao lệch
AS-09.3.4❌ HH — "1 thẻ <img> không có alt"✅ PASSHit duy nhất nằm trong apps/learn/src/figures/engine.test.tsx:37, và nó là một assertion cấm <img>: expect(html).not.toMatch(/<img|\.png|\.jpe?g/i). Grep bắt đúng chuỗi nhưng đọc ngược ý. Cổng learn không render thẻ <img> nào — đúng luật zero-asset REQ-LRN-20
AS-03.1.3❌ HH — "showcase.ts gọi fetch( ngoài api.ts"❌ vẫn KHÔNG PASS, nhưng mức nhẹ hơn mô tảshowcase.ts không phải component gọi lung tung: nó là client thứ hai của cùng cổng mentors, với một bản request() gần như trùng api.ts. Đã sửa ở A8 — nay dùng chung request/API_BASE, còn đúng một fetch thô cho đường tải ảnh (bytes thuần, Content-Type là mime của ảnh nên không thể đi qua request()), có ghi lý do ngay tại chỗ

Điểm hệ sau đính chính: 146/255 = 57,3% (AS-09 lên 6/25). Các con số khác giữ nguyên.

11. Đã sửa xong trong cùng phiên (A1..A8) ​

ViệcKết quả kiểm được
A1migration-reconciliation.md có mục 2026-08-20: 58 dòng remote / 57 file đĩa, 1 dòng mồ côi 0046_context_event_temporal.sql đã khai + giải thích; schema-diff production ↔ migrate:dryrun 92 bảng, 0 bảng lệch cột. → AS-04.6.1 🔴🚸 và AS-04.6.3 🔴🚸 PASS. AS-04.6.2 vẫn đỏ có chủ đích: câu DELETE dọn dòng mồ côi là ghi thẳng production, để chủ dự án quyết thời điểm
A3migrations/0058_bilingual_new_subjects.sql — name_en cho 4 subject + 20 strand (SAT/AP/IELTS dùng đúng tên chính thức của kỳ thi, không dịch máy). migrate:dryrun xanh. Chờ áp lên production qua workflow_dispatch
A4reference/models.md §1 nay có đủ 8 model — thêm dòng Recommendation Model. → AS-05.1.4 PASS
A5knowledge/readiness.test.ts (9 test) và models/constraint.test.ts (8 test) — 8/8 engine nay có test hành vi riêng. → AS-05.3.1 PASS
A6Trùng SRC-206 đã gỡ: dòng "Dolphin có khu rà soát" đổi sang SRC-414 (đổi dòng này chứ không đổi dòng "cựu học sinh", vì traceability.md và request-audit.md đang trỏ tới nghĩa cựu học sinh). Sổ nay: 414 dòng = 414 uniq = max 414, liên tục. scripts/b21-plan.md chuyển thành engineering/content-loading-notes.md. → AS-01.1.1, 01.1.4, 01.1.5 PASS
A710 cạnh import chéo module đã khai vào bảng "Ngoại lệ tường minh" của audit-standard, mỗi cạnh một lý do. → AS-03.1.2 PASS
A8apps/mentors/src/showcase.ts dùng chung request/API_BASE của api.ts

| A2 | workers/api/src/shared/authCoverage.test.ts — cổng phủ xác thực + phân quyền, chạy trong npm test nên chặn cả CI lẫn deploy. Soi bảng route lúc chạy thay vì grep mã nguồn: 192 route /v1, 130 đăng ký requireSession, còn 22 route mở và cả 22 đều nằm trong danh sách PUBLIC kèm lý do từng dòng. Đã thử phá để chứng minh cổng có răng: bỏ một dòng PUBLIC ra thì test đỏ đúng tên route đó. Lớp thứ hai chấm phân quyền: 12 module có route {learnerId}, 11 dùng chốt của shared/authz, riêng invitations khoá bằng family_id lấy từ session (đã soi tay, ghi vào ngoại lệ). → AS-07.1.1 🔴🚸 và AS-07.2.1 🔴🚸 PASS | | A9 | migrations/0059_attach_orphan_labs.sql — gắn lab vào 3 Unit tiếng Anh chưa có lab nào. Chỉ 3, không phải 126: rà kỹ thì 70 lab không có node_id lẫn strand (việc biên tập, không suy ra được), 46 lab rơi vào Unit đã có lab khác nên đụng unique index "một lab mỗi Unit" của 0048. Con số thật cần chủ dự án quyết: cây Tiếng Anh mới có 64 Unit trong khi kho có 113 lab — dư ra là do cây cũ chia nhỏ hơn, phải chọn giữ và gắn tay hay cho retired |

| A10 (phần Tin học + Ngữ văn) | 370 câu soạn tay cho 37 Unit ngõ cụt: 360 câu cho cả 36 Unit của Package UD môn Tin học (HTML · CSS · JavaScript · cơ sở dữ liệu · làm dự án · công cụ nghề) và 10 câu cho Unit "Ẩn dụ" của Ngữ văn. Sinh ra .sql để nạp qua seed-data.yml chứ không dùng scripts/d1.mjs — script đó gọi thẳng Cloudflare API từ máy cá nhân, đi vòng qua luật "mọi thứ chạm production phải qua GitHub Actions". Đã kiểm trên SQLite thật dựng từ migrations/: 370 dòng, chạy lại lần hai vẫn 370, 37/37 node id có thật trên production, mỗi Unit đúng 10 câu, 0 câu thiếu misconception. Đã nạp lên production 2026-08-20 qua seed-data.yml |

| A11 (đợt 1) | 72 Unit môn Tin học có đủ why_pain / why_gain / why_example / can_do: Package "Ứng dụng và sản phẩm" và "Lập trình cơ bản". Viết theo đúng khuôn của các node môn Toán đã có (SRC-345, SRC-397); cổng sinh SQL tự chặn ba luật: độ dài tối thiểu từng trường, bắt buộc khuôn "Ngay tí nữa / Mai ngày kia", và cấm em dash. Đã kiểm trên SQLite thật: 72/72 điền đủ, chạy lại không đè lên chữ sửa tay, 72/72 node id có thật trên production và cả 72 đang trống. Đã nạp lên production 2026-08-20 |

| A11 (đợt 2-5) | 289 node nữa: trọn môn Tin học (216/216 node, cả sáu Package) và trọn bốn môn thi chuẩn hoá SAT · IELTS · AP · GenAI (73 node). Cổng sinh SQL được siết thêm một luật sau khi suýt để lọt một lỗi im lặng: nó đếm node theo môn và so với số đo được trên production. Lỗi bị bắt: 17 id IELTS viết theo tiền tố ielts- trong khi id thật không có tiền tố đó, nếu lọt thì câu UPDATE không khớp dòng nào mà seed vẫn báo thành công |

Tổng A11 tới giờ: 289/838 node, tất cả đã nạp lên production. Còn lại 84 node Ngữ văn và 73 node của các môn nhỏ trong phần của tôi; 444 node Lý/Hoá/Sinh do phiên khác làm. Sau đó là A12..A17. Phần Lý/Hoá/Sinh của A10 do một phiên khác làm song song (SRC-414, SRC-420).

Ghi nhận trong lúc làm A10 — một lỗ hổng quy trình chưa có chỉ báo nào bắt: scripts/d1.mjs mở đường ghi thẳng vào D1 production bằng token đọc từ ~/Library/Preferences/.wrangler, và các mẻ nội dung gần đây đều đi đường đó. Nó không vi phạm chỉ báo AS nào đang có (AS-04.4.1 chỉ hỏi script có in tên DB và chờ xác nhận không, AS-03.5.3 chỉ nói về migrations apply), nhưng vi phạm thẳng luật của chủ dự án ngày 2026-08-15. Đề xuất cho lần cập nhật chuẩn kế tiếp: mở rộng AS-03.5.3 sang mọi thao tác ghi production, không riêng migration.

Điểm sau A1..A9 ​

TrướcSau
Điểm hệ145/255 (56,9%)154/255 (60,4%)
🔴 KHÔNG PASS10/305/30
🚸 Pilot Gate11/1815/18

Ba dòng Pilot Gate còn đỏ: AS-04.5.5 (diễn tập backup/restore — A14), AS-03.5.3 (chứng minh không ai apply migration ngoài CI — cần gh api hoặc nhánh (b)), AS-10.4.1 (cổng chất lượng trước publish — A13, khối lớn).

12. Kết quả sau khi nạp lên production — 2026-08-20 ​

Bốn tệp seed chạy qua seed-data.yml (bốn lượt, mỗi tệp một lượt, đều success). Đo lại chính production sau khi chạy, không đọc log:

ĐoTrướcSau
Câu hỏi cho Package UD môn Tin học0360
Câu hỏi cho Unit "Ẩn dụ" (Ngữ văn)010
Node Tin học có đủ why_pain/why_gain/why_example/can_do0216/216
Node SAT · IELTS · AP · GenAI có đủ bốn trường073/73
Unit ngõ cụt của môn Tin học360

Migration 0058 (song ngữ 4 subject + 20 strand) và 0059 (gắn 3 lab vào Unit) cũng đã áp: subjects và strands nay 0 dòng thiếu name_en, ba Unit tiếng Anh đã có nút Lab.

Unit ngõ cụt còn lại trên toàn hệ: Hoá 35 · Lý 33 · Ngữ văn 1. Hoá và Lý thuộc đợt của phiên khác. Dòng Ngữ văn còn lại là node idioms thuộc cây cũ TV chứ không phải cây V1-V5 mà learner đang đi: đây chính là hai cây song song mà SRC-401 đã nêu và chưa ai quyết cây cũ có tạm ẩn hay không. Không soạn câu cho nó là có chủ đích, vì soạn tức là ngầm quyết định giữ cây cũ.

13. Tiến độ A13 và A14 — 2026-08-22 ​

Ghi thêm chứ không sửa phần trên: theo luật của index audit, báo cáo đã chấm giữ nguyên, tiến độ về sau viết tiếp xuống dưới.

A14 — diễn tập backup/restore: xong, AS-04.5.5 chuyển sang PASS ​

Đợt diễn tập mới ghi ở docs/ops/backup-restore-drill.md. Khôi phục toàn bộ production vào một bản D1 cô lập: 96 bảng · 34.978 dòng · 27 MB · 0/96 bảng lệch, restore mất 80 giây.

Đợt này thêm một bước mà đợt 2026-08-15 không có: vân tay nội dung. Đếm dòng khớp vẫn có thể che nội dung hỏng — 15.656 dòng items với prompt bị cắt cụt vẫn đếm ra đúng 15.656. So thêm tổng độ dài cột nội dung + biên khoá cho tám bảng nặng nhất: 8/8 khớp.

Bản thân đợt diễn tập cũ cũng đã trở thành bằng chứng sai nếu để nguyên: nó chấm trên 79 bảng / 3,4 MB, trong khi hệ hôm nay là 96 bảng / 27 MB. Vì vậy luật đọc chỉ báo AS-04.5.5 được siết lại trong audit-standard: đợt gần nhất phải KHÔNG cũ hơn đợt migration lớn gần nhất.

A13 — cổng chất lượng nội dung: cổng đã dựng, khoản nợ đã đo được, AS-10.4.1 vẫn chưa PASS ​

Ba mảnh trong SRC-507 (workers/api/src/modules/content/backfill.ts, migrations/0067_items_publish_gate.sql, tab "Content quality" ở Admin → Ops).

Điều quan trọng nhất là cái nó không làm: chấm bù chạy evaluator máy rule-engine@1, tức đúng MỘT lượt, trong khi PUBLISH_MIN_EVALUATORS = 2. Ghi evaluator_count = 1 là ghi đúng; ghi 2 để cổng xanh là bịa ra một lượt chấm chưa từng xảy ra — đúng kiểu hỏng mà cả AS-06 sinh ra để chặn. Nên sau khi chạy hết, AS-10.4.1 vẫn KHÔNG PASS, nhưng lý do đổi từ "không đo được" sang "đo được, còn thiếu evaluator thứ hai". Hai tình trạng đó khác hẳn nhau và không nên gộp làm một dòng đỏ giống nhau.

Một con số trong báo cáo này đã cũ: §8 ghi 11.336 item chưa chấm; đo lại production ngày 2026-08-22 là 15.575. Kho lớn thêm sau các đợt nạp nội dung ở §12. Con số cũ không sai lúc chấm, nhưng ai đọc lại để đối chiếu thì cần biết mốc đúng.

Đo trên production2026-08-202026-08-22
Item published chưa có hồ sơ chất lượng11.33615.575
Item có ≥ 2 evaluator00
Item ở trạng thái candidate00

Hai việc còn phải làm tay, không tự chạy được: (1) áp 0067 qua deploy-api.yml; (2) bấm "Chấm bù tới hết" ở Admin → Ops → Content quality. Trigger 0067 chỉ chặn dòng MỚI, nó không dọn hộ 15.575 dòng cũ.