Rà soát đồng bộ tài liệu ↔ mã nguồn: 08.09.2026
Câu hỏi của lượt rà soát này: luật đã ghi và mã đang chạy có khớp nhau không? Không phải "tính năng nào hỏng" (đó là rà soát tính năng), cũng không phải "kiến trúc có đúng không" (đó là rà soát 03.09), mà: mỗi luật trong CLAUDE.md có một chỗ nào trong mã phản bội nó không, và có gác nào bắt được không.
Kết luận ngắn: 8/9 luật khớp; luật màu thì không, và lý do là nó là luật duy nhất không có gác. Số chỗ vi phạm luật màu đi từ 618 (03.09.2026) lên 3.445 (08.09.2026) trong năm ngày.
Cách kiểm
Mỗi luật được kiểm bằng một phép đo chạy được, không phải bằng đọc:
Luật CLAUDE.md | Phép đo | Kết quả |
|---|---|---|
| Chỉ Cloudflare Email Service | grep -ri "resend|sendgrid|nodemailer|smtp" api/src | ✅ sạch, chỉ còn một dòng chú thích ghi ngày gỡ Resend |
env.EMAIL.send chỉ trong một cổng | grep -rn "EMAIL.send" api/src | ✅ 2 kết quả, cả hai trong shared/email/send.ts |
| Tool plane không có tool GHI nội dung | duyệt registry/tools.ts + executors/conan.ts | ✅ chỉ conan.list_courses, conan.get_course, đều đọc |
| Không deploy từ máy | duyệt 16 workflow | ✅ mọi lượt deploy đi qua GitHub Actions |
| Migration do CI áp, từng file | apply-d1-migrations.mjs + sổ schema_migrations | ✅ 516 file, sắp theo tên |
| Sidebar docs không có trang mồ côi | so 56 file .md với 57 link: trong config.mts | ✅ 0 mồ côi, 0 link chết |
Mục lục skill trong CLAUDE.md | so với ls .claude/skills/ | ✅ khớp đủ 25 |
| Bộ ba UI đúng gói | check-ui-standards.mjs | ❌ mam khai framer-motion, gác không bắt |
| Chỉ dùng token màu | (không có gác) | ❌ 3.445 chỗ |
Phát hiện, và đã xử lý thế nào
1. mam.conan.school dùng tên gói cũ framer-motion: và gác vẫn xanh
CLAUDE.md viết rõ: "gói npm tên motion (Framer Motion từ v12 phát hành dưới tên này); import from "motion/react"". mam.conan.school/package.json khai framer-motion: ^12.38.0 và bốn component import thẳng từ đó.
Vì sao không ai thấy: gói motion re-export framer-motion, và framer-motion vẫn nằm trong cây phụ thuộc của mọi site đã làm đúng (www, com đều có framer-motion@13.2.0 trong lockfile, dưới dạng phụ thuộc bắc cầu). Nên bản dựng chạy, giao diện chạy, không có gì báo. Và check-ui-standards.mjs chỉ kiểm sàn phiên bản của những gói có mặt, một gói bị cấm mà nó không biết tên thì nó không nhìn tới.
Đã sửa: đổi sang motion@^13.2.0 + motion/react ở 4 component, npm ci + npm run build xanh. Và bịt lỗ gác: check-ui-standards.mjs giờ bắt cả phụ thuộc trực tiếp framer-motion lẫn import ... from 'framer-motion'. Đã tự kiểm hai chiều (thả một file vi phạm vào repo → gác đỏ).
2. Luật màu là luật duy nhất không có gác: và nó là luật bị vi phạm nhiều nhất
CLAUDE.md dành cho luật màu nhiều chữ nhất trong cả file, kể cả một mục "Vì sao luật này nghiêm đến vậy" với sự cố có thật (114 chỗ / 27 file, 31.08.2026). Nhưng phần "Kiểm trước khi xong" chỉ là một dòng grep để người sửa tự nhớ chạy. Không job CI nào gọi nó.
Kết quả đo được:
| Thư mục | Chỗ dùng màu ngoài token |
|---|---|
admin.conan.school | 1.653 → 1.602 |
www.conan.school | 1.127 |
com.conan.school | 325 |
mam.conan.school | 175 |
play.conan.school | 57 |
mentors.conan.school | 53 |
packages | 53 → 32 |
docs (thư mục cũ) | 12 |
video.conan.school | 11 |
api.conan.school | 10 |
Sổ rà soát 03.09.2026 ghi con số này là 618. Năm ngày sau là 3.445. Một luật không có gác không giữ được gì cả, nó chỉ ghi lại rằng ta từng muốn điều đó.
Đã sửa: thêm scripts/check-color-tokens.mjs, chạy trong job guards của ci-checks.yml (job này không cài phụ thuộc nên gần như miễn phí về quota Actions).
Nó là mốc chặn, không phải cổng tuyệt đối, cùng lối với mốc tsc = 194 của job api. Dọn 3.445 chỗ trong một lần là không làm được, và một gác đỏ vĩnh viễn là một gác không ai đọc. Cái phải chặn ngay là con số đi lên. Mốc ghi ở scripts/color-token-baseline.json, tính riêng cho từng thư mục app (để một site tệ không che một site vừa xấu đi), và chỉ được hạ:
npm run check:colors # kiểm
npm run check:colors -- --update-baseline # hạ mốc sau khi dọnGác chỉ bắt hai thứ không thể nhầm: lớp tiện ích Tailwind có bậc số (bg-emerald-700) và mã hex nằm trong một khai báo màu (color:, fill:, backgroundColor:). Hex ở chỗ khác không bị bắt, một gác báo sai là một gác không ai đọc.
Gác đã bắt được một lần lùi ngay trong lượt này. Khi rebase lên main, nó báo admin.conan.school: 1653 chỗ, mốc là 1622, commit này THÊM 31 chỗ: hai PR gộp hôm trước (#140, #143) mang thêm 35 lớp slate-* / red-* vào StoryEditor.tsx và LearnerStoriesPage.tsx. Cả hai PR đều xanh, vì lúc đó chưa có gác này. Đã quy đổi hết sang token (slate-900 → foreground, slate-200 → border, slate-400/500/600 → muted-foreground, red-* → destructive, text-white trên nền token → text-background), admin xuống 1.602, thấp hơn cả mốc đo trước rebase. Mốc chỉ được hạ, nâng mốc để đi tiếp là hợp thức hoá đúng thứ gác sinh ra để chặn.
Đã dọn packages/admin-shared 53 → 32, vì trong đó có chỗ tệ nhất có thể có:
StyleGuidePage.tsx, bảng hướng dẫn phong cách dùng chung của cả cụm admin, kê đơn chính sự vi phạm:- **Destructive/Delete:** text-red-600 hover:bg-red-50 border-red-200.
Tài liệu thiết kế dạy người đọc phá luật thiết kế. Đã đổi sang text-destructive hover:bg-destructive/10 border-destructive/40 ở cả dòng hướng dẫn lẫn nút ví dụ ngay bên dưới (hai chỗ này lệch nhau thì bảng hướng dẫn nói một đằng, hiện một nẻo). LoginPage.tsx, màn hình đăng nhập của mọi app admin, viết toàn bộ bằng style= với hex tự chế, kể cả một gradient tím #6366f1 → #8b5cf6 không liên quan gì tới thương hiệu; đã viết lại bằng token.
DebugFooter.tsx (32 chỗ còn lại) là lớp phủ gỡ lỗi với bảng màu tối riêng và màu theo HTTP method, chuyển nó là một lần viết lại thật, rủi ro hiển thị có thật, giá trị cho người dùng bằng không. Để lại ở mốc, có chủ ý.
3. DDL lúc chạy: lý do ghi trong mã đã hết đúng từ 04.09
Bốn domain dựng bảng lười ở lần gọi đầu tiên, với lý do viết ngay trong mã:
"phiên deploy và phiên áp migration là hai việc tách rời trong repo này, và mã đọc một bảng chưa tồn tại thì hỏng âm thầm."
Lý do đó đúng lúc viết. Nó hết đúng từ 04.09.2026, khi CI bắt đầu áp migration trước bước deploy trong cùng một job, worker mới không bao giờ chạy trước schema của nó nữa. Chú thích thì ở lại. Đây là dạng lệch tài liệu ↔ mã khó thấy nhất: không phải tài liệu sai, mà là lý do đã mục vẫn được đọc như lý do đang sống.
Giá phải trả trong lúc đó: một lượt DB.batch DDL thừa trên mọi request của diễn đàn và Thư viện Prompt (15 chỗ gọi), và bảy bảng không nằm ở đâu trong git nên data-model không thể mô tả đúng.
Đã sửa: 20260915a_runtime_ddl_to_migrations.sql chép nguyên văn 14 câu lệnh (giữ IF NOT EXISTS, nên áp lên production, nơi các bảng đã tồn tại, là phép không). Gỡ ensureTables / ensureVoteTable và 15 chỗ gọi. Kiểm: migration chạy hai lần liên tiếp trên SQLite thật (idempotent), tsc đúng 194 lỗi = mốc cũ, wrangler deploy --dry-run xanh.
4. skills-map đứng lại ở 21 skill trong khi repo có 25
skills-map là ảnh chụp ngày 04.09 và ghi "hệ skill sau nâng cấp (21)". Bốn skill thêm sau đó, story-world, book-pack, course-covers, business-model-canvas, có trong .claude/skills/ và có trong mục lục CLAUDE.md, nhưng không có ở trang này.
Đã sửa: thêm bảng bốn skill mới và bảng "hệ skill hiện tại (25)", kèm câu chỉ rõ nguồn sự thật là ls .claude/skills/ và ba chỗ phải sửa cùng lúc.
Còn mở: và vì sao chưa đụng vào
| Việc | Vì sao chưa làm trong lượt này |
|---|---|
3.372 chỗ màu còn lại (chủ yếu admin 1.602, www 1.127) | Việc dọn thật, nhiều ngày, mỗi màu phải quyết ánh xạ sang token nào. Mốc chặn đã ngăn nó lớn thêm. |
| 1.084/1.110 tài liệu Thư viện rỗng ruột | Đã ghi ở known-risks. Là việc nội dung, không phải mã. |
video.conan.school chưa có Tailwind, chép token bằng tay | Nợ đã ghi trong CLAUDE.md từ 03.09. Đưa Tailwind vào là một lượt sửa riêng. |
admin.conan.school không có motion | Luật đòi bộ ba; admin mới có hai. Thêm chuyển động cho một SPA 6 cụm là việc thiết kế, không phải việc gác. |
mam, video, mentors, play, docs không có job kiểm nào trên PR | ci-checks.yml chỉ dựng api, admin, com, www, tool-plane, admin-router. Năm site còn lại chỉ biết mình hỏng ở lượt deploy. Thêm job là thêm quota, chính thứ repo này vừa cắt (xem known-risks). Cần một quyết định, không phải một commit. Giảm nhẹ một phần: job guards (không cài phụ thuộc) nay soi luật màu và tên gói motion trên toàn repo, kể cả năm site đó. |
Xoay RESEND_API_KEY, MIXPANEL_TOKEN, CRON_SECRET; đặt PAYMENT_WEBHOOK_SECRET | P0 từ 03.09, chỉ chủ repo làm được. |
Bài học chung của lượt này
Cả bốn phát hiện có cùng một hình dạng: luật đúng, tài liệu đúng, mã sai, và không có gì báo. Ba trong bốn cái sống sót được chính xác vì thứ đáng lẽ bắt chúng lại xanh, gác kiểm sàn phiên bản của gói có mặt chứ không kiểm gói bị cấm; gác màu thì không tồn tại; chú thích trong mã thì không có hạn dùng.
Nên phép thử cho một luật mới không phải "đã ghi vào CLAUDE.md chưa" mà là "cái gì đỏ khi ai đó phá nó, và ta đã thấy nó đỏ chưa". Cả hai gác sửa trong lượt này đều được tự kiểm hai chiều: thả một vi phạm vào repo, xem gác đỏ, rồi gỡ ra.