Audit 18.10.2026
Đối chiếu từng mục của bản lệnh "dựng lại hệ thống test, quality control và harness" với repo conanplatform thật, đo ngày 18.10.2026 trên main (sau #471). Mỗi mục có một kết luận:
| Kết luận | Nghĩa |
|---|---|
| Đã có | Conan đã làm điều tương đương, không cần làm lại. |
| Làm theo | Làm đúng như bản lệnh. |
| Làm theo, sửa | Ý đúng, nhưng phải đổi cách làm cho hợp với Conan. |
| Không làm | Không hợp với Conan, hoặc giá cao hơn lợi. |
| Chờ quyết | Đảo một luật chủ dự án đã đặt; agent không tự đổi. |
Bản lệnh viết cho một repo npm workspaces chỉ có một lockfile. Conan không có workspaces: 31 package.json, 30 lockfile, mỗi app cài riêng. Nhiều bước của bản lệnh (--workspaces, "workspace bị đụng", một lần cài) phải đổi thành "mỗi thư mục có lockfile". Đó là lý do có nhiều dòng "Làm theo, sửa" ở dưới.
Năm phát hiện nặng nhất
| # | Phát hiện | Vì sao nặng |
|---|---|---|
| 1 | Phút Actions ước khoảng 2.580 mỗi tháng (1.205 phút trong 14 ngày, ±20%), trong khi gói Free có 2.000 | Repo đã bị tắt Actions một lần vì chi phí (28.09 tới 02.10): mọi merge trong khoảng đó không deploy và không gì đỏ. ci-checks chiếm khoảng 52%, deploy-docs + deploy-api khoảng 29%. |
| 2 | Deploy trên main không chờ ci-checks | Gác duy nhất là quy ước "chỉ merge khi xanh". Không có branch protection (gói Free trả 403). Merge khi đỏ đã xảy ra hai lần (#293, #416). |
| 3 | Phiên Claude Code vẫn mở ở bản clone cũ ~/ConanCode/conanplatform | Bản đó ở #422 (13.10), 50 skill thay vì 61, hook cũ. Phiên làm bản audit này cũng mở ở đó. Mọi luật mới sau 13.10 không có mặt trong phiên. |
| 4 | Các luật "không bao giờ" vẫn chưa có máy chặn | Không có hook nào chặn wrangler deploy, git reset --hard, git add -A, push --force. Bản audit 10.10 đã xếp việc này là ưu tiên 1 (H4 ở mức L1); tám ngày sau vẫn vậy. |
| 5 | Không có gate lưu trữ | Repo vừa phải viết lại lịch sử (17.10, 398 MB còn khoảng 20 MB). check-media-r2 chỉ chặn 57 ảnh đã chuyển quay lại; một file video mới vẫn vào được git. |
Theo từng mục của bản lệnh
0. Luật làm việc
| Mục | Hiện trạng | Kết luận |
|---|---|---|
| Trunk-based, không PR | PR, squash merge, 127 PR trong 14 ngày (khoảng 9 mỗi ngày); luật "chỉ merge khi CI xanh" và "CI xanh thì tự merge" | Chờ quyết. Xem phân tích. |
Cấm git add -A, reset --hard, stash, restore, clean -f, --no-verify, force push | Chỉ là trí nhớ (memory "cây làm việc dùng chung"), không hook nào chặn | Làm theo, ưu tiên 1, bằng hook PreToolUse(Bash) |
| Không deploy từ máy | Luật trong CLAUDE.md, không máy chặn | Làm theo, cùng hook trên |
| Không nhập secret | Luật | Đã có |
| Định danh tiếng Anh, chú thích nói vì sao | Định danh tiếng Anh; chú thích tiếng Việt và luôn nói vì sao | Đã có. Giữ chú thích tiếng Việt: đó là quy ước của repo, bản lệnh không bắt đổi ngôn ngữ chú thích. |
Trunk: phân tích
Lợi: bỏ được lượt ci-checks trên PR (khoảng 52% phút Actions), bỏ vòng chờ merge, và CI trên main kiểm rồi mới deploy trong cùng một job, tức chặn được phát hiện số 2, việc PR hôm nay không làm được.
Giá: main có thể đỏ trong vài phút trước khi auto-revert, và cổng cuối trước main chuyển từ CI về máy (pre-push). Hôm nay hook trước push chỉ chạy run-guards --fast (14 gác, khoảng 1,3 giây), không typecheck, không test. Conan có đường tiền và đường xác thực; đổi sang trunk khi pre-push còn mỏng như vậy là bỏ đi lớp kiểm thật duy nhất.
Đề xuất nếu chủ dự án chọn trunk, làm theo đúng thứ tự, không đảo:
- CI một job trên
main: kiểm (gác + typecheck + test của app bị đụng) rồi mới deploy. Làm được ngay, cả khi còn PR. - Pre-push typecheck + test của app bị đụng (theo
scripts/ci/select-jobs.mjs, đã có sẵn bảng app → đường dẫn). - Auto-revert khi
mainđỏ. - Lúc đó mới bỏ PR. Giữ PR cho thay đổi đụng đường tiền và xác thực nếu chủ dự án muốn một lần đọc lại.
1. Audit trước khi sửa
Đã có: chính trang này, số liệu đo ngày 18.10.2026. Lượt sau theo skill harness-audit.
2. Một danh sách gate, ba tầng
| Mục | Hiện trạng | Kết luận |
|---|---|---|
| Một nguồn danh sách | scripts/run-guards.mjs, 40 mục (26 gác + 14 tự kiểm); đỏ nếu một check-*.mjs không đăng ký | Đã có |
| Chạy song song, chỉ in gác đỏ | 4 luồng, trần 180 giây mỗi gác, chạy hết rồi báo; 13,3 giây tuần tự, 5,0 giây song song | Đã có |
| Pre-commit và CI gọi cùng danh sách | CI gọi đúng run-guards; hook trước push gọi run-guards --fast | Đã có |
Tầng report không chặn | Không có: mọi gác đều chặn | Làm theo, sửa. Chuyển sang report: whats-new, library-docs, email-docs, figures (sổ sách, không ai bị hỏng nếu bỏ qua một lượt). Giữ chặn cho mốc qc và colors: chủ dự án đã quyết "PR làm tăng bất kỳ ô nào là đỏ". |
paths cho từng gác, chế độ --staged | Có cờ fast (14 gác) nhưng không theo đường dẫn | Làm theo. Lợi nhỏ (cả bộ chỉ 5 giây) nhưng cần cho pre-commit dưới 5 giây khi có thêm typecheck. |
Xoá GIT_* cho node --test | Không cần hôm nay: chưa có git hook nào xuất GIT_DIR | Làm theo cùng lúc với git hooks (mục 3), không trước |
| Mỗi gác có test đỏ + xanh | 14 tự kiểm riêng, 8 tự kiểm nội tuyến; 8 gác không có tự kiểm nào (analytics, colors, no-auth-bypass, emdash, ui-standards, whats-new, observability, figures) | Làm theo cho 8 gác đó. Giữ kiểu --self-test của Conan, không đổi sang *.test.mjs chỉ để đúng tên. |
| Gộp gác trùng | deps-docs-guard --self-test chạy ba lần mỗi lượt | Làm theo |
3. Git hooks
Conan không có git hook nào (core.hooksPath rỗng, không .githooks/, không husky). Gác lúc push nằm trong hook của Claude Code, nên chủ dự án hay một agent khác (Codex) push thẳng thì không qua gác nào.
| Mục | Kết luận |
|---|---|
.githooks/ + core.hooksPath | Làm theo, sửa: gốc repo không có dependency nên không ai chạy npm install ở gốc, prepare sẽ không bao giờ chạy. Đặt git config core.hooksPath .githooks trong scripts/cloud-bootstrap.sh (SessionStart, chạy mỗi phiên). |
pre-commit: kiểm ổ đĩa, check-node-modules, gác --staged | Làm theo. check-node-modules đặc biệt cần: bootstrap chỉ cài 15/31 thư mục, và LaunchAgent com.nemo12.disk-cleanup xoá node_modules không đụng 21 ngày ở mọi thư mục dưới ~/ConanCode, gồm cả repo này. |
| pre-commit: tự sinh file | Làm theo cho trang module (npm run modules khi đụng package.json). Không có last_reviewed ở docs của Conan. |
| pre-commit + commit-msg: mã yêu cầu (SRC) | Không làm: Conan không có sổ mã yêu cầu. |
| pre-push: typecheck + test app bị đụng | Làm theo, sửa: theo thư mục có lockfile, chọn bằng select-jobs.mjs (đã có 29 mẫu tự kiểm), không theo workspace. Chuyển .claude/hooks/pre-push-guards.sh thành git hook để mọi người viết đều qua. |
| pre-push: không E2E | Đã có (không có E2E nào) |
4. Hooks của Claude Code
Hiện có 5 hook: SessionStart (cloud-bootstrap.sh, 42 giây khi lạnh), PreToolUse deps-docs-guard (Context7 trước khi đổi phiên bản, 80 mẫu tự kiểm), PreToolUse pre-push-guards.sh, PostToolUse (bắt gạch dài), Stop (qc-scan + workspace-deps). Gác hooks kiểm file có thật, cú pháp, khoá trùng.
| Mục | Kết luận |
|---|---|
PreToolUse(Bash) chặn lệnh git nguy hiểm, wrangler deploy, poll Actions, | tail trên script quan trọng | Làm theo, ưu tiên 1. Thêm wrangler d1 execute không phải SELECT (luật riêng của Conan). Bỏ chuỗi và heredoc trước khi so. |
| Chặn commit khi tụt quá 100 commit | Làm theo. Gác archived-migrations đã đỏ giả hôm nay chỉ vì cây tụt 3 commit. |
| Chặn mã yêu cầu chưa giành | Không làm (không có sổ mã). |
SessionStart cảnh báo nhánh tụt, ổ đĩa, node_modules cũ | Làm theo, và thêm một cảnh báo riêng của Conan: thư mục phiên là bản clone cũ (gốc lịch sử không phải e23cf394). Đây là phát hiện số 3. |
SessionStart báo production lệch main | Làm theo, sửa: đọc kết quả smoke của lượt deploy cuối (một lần, gh run list), không gọi production. |
| PostToolUse nhắc retro sau push | Không làm lúc này: chưa có trunk, chưa có quy trình retro. |
| PostToolUse chạy gác skill khi ghi skill | Làm theo cùng gác check:harness mà audit 10.10 đã đề xuất. |
| Mỗi hook có test | Làm theo: 3/5 hook chưa có tự kiểm (pre-push-guards.sh, post-edit-guards.mjs, stop-guards.mjs). |
5. CI một job
| Mục | Hiện trạng | Kết luận |
|---|---|---|
| Một job | ci-checks tới 16 job một lượt (trung bình 3,1 job, 3,38 phút tính tiền); thêm 16 workflow deploy, mỗi cái một job | Làm theo, sửa: gộp changes + build/test các app bị đụng vào một job, cài từng lockfile nối tiếp. Ước bớt khoảng 1 phút mỗi lượt (làm tròn), khoảng 400 phút mỗi tháng. |
| concurrency | ci-checks huỷ lượt cũ; deploy có cancel-in-progress: false ở api và các Worker có trạng thái | Đã có |
Scope theo event.before, bảng app → đường dẫn | scripts/ci/select-jobs.mjs theo PR base/head, 29 mẫu tự kiểm | Đã có (đổi sang event.before chỉ khi có trunk) |
Cache node_modules theo hash lockfile, chỉ lưu trên main | cache: npm ở mọi job, mọi nhánh; 8,05 GB / 10 GB | Làm theo: chỉ lưu cache trên main, nếu không cache tốt sắp bị đẩy ra |
| Typecheck, lint, test song song | Typecheck có ở 7 app; lint chỉ ở play/frontend; 14 test api mỗi file một step viết tay | Làm theo, sửa: một bộ chạy test đọc danh sách từ thư mục (thêm test không phải sửa ci-checks.yml). Nối oxlint của admin. |
| Migration trước deploy, deploy lần lượt | Đã có trong _deploy-cloudflare.yml | |
| Không E2E trên CI | Đã có | |
| Auto-revert | Không | Chỉ khi có trunk |
| Lịch hằng tuần, không hằng ngày | d1-invariants hằng ngày (4/4 xanh, khoảng 15 phút mỗi tháng); error-ledger hằng ngày, đỏ 6/6 lượt (token thiếu Zone Analytics Read) | Không làm với d1-invariants: nó kiểm dữ liệu production, rẻ, đáng chạy mỗi ngày. Sửa error-ledger: thêm quyền hoặc tắt bước đỏ; thêm deploy-aimaster, deploy-webai vào danh sách; lên checkout@v5. |
6. Lượt kiểm hằng tuần
| Mục | Kết luận |
|---|---|
| LaunchAgent Chủ nhật 22:00, worktree riêng, $0 | Làm theo. Máy đã chạy đúng mẫu này cho Nemo12 (com.nemo12.weekly-check); thêm một cái cho conanplatform, lệch giờ để hai lượt không tranh CPU và hạn mức GitHub. |
check:report | Làm theo sau khi có tầng report (mục 2) |
deps-upgrade.mjs với ncu --workspaces | Làm theo, sửa: lặp qua 30 thư mục có lockfile, không --workspaces. Gói giữ đã có lý do ở .claude/memory/deps-upgrade-holdbacks.md; chuyển thành scripts/deps-hold.json máy đọc được. Giữ hook deps-docs-guard. |
| Knip gỡ gói thừa | Làm theo, sửa: chạy theo từng app. Trang module đã đánh dấu 11 gói "nên xem lại" (vd gói npm tên cn ở 3 app, react-router-dom song song react-router, @aws-sdk/client-s3 song song aws4fetch). |
npm audit | Làm theo |
| 10% E2E | Không làm lúc này: Conan có 0 E2E. Viết E2E là một việc riêng, không phải phần của harness. |
Tự push chore(deps) lên main | Theo quyết định trunk. Khi còn PR: mở một PR, tự merge khi xanh. |
| Xoá Dependabot | Đã có (không có Dependabot ở cả ba repo) |
7. Tiêu chuẩn code
| Luật | Hiện trạng | Kết luận |
|---|---|---|
| File mới tối đa 500 dòng | Chỉ mốc huge-file > 1.000 dòng (12 file, lớn nhất 3.623 dòng) | Làm theo: gác chỉ xét file thêm mới |
Strict, không any | Mốc any-cast 1.806 (từ 2.033 ngày 10.10), ts-suppress 0 | Đã có (mốc chặn chỉ hạ) |
| Zod tại cửa | 25/284 file src của api import zod | Làm theo cho route mới, ghi vào skill api-service; không bắt sửa route cũ một lượt |
| Context7 | .mcp.json có, hook buộc tra trước khi đổi phiên bản | Đã có. Nhớ rủi ro khoá rỗng trả "Invalid API key" như kết quả thường. |
| Test hành vi, cấm regex trên mã nguồn | 14 test api; vài test đọc thẳng file nguồn của tokyo | Làm theo cho test mới |
| Gate lưu trữ | Không | Làm theo, ưu tiên 2 |
| Biến môi trường công khai của gói đăng nhập | Tokyo đi qua proxy /api cùng origin, không có gói đăng nhập dùng chung đọc env | Không làm |
8. Site harness
Đã làm: site này. Trang module sinh tự động từ 31 package.json (95 gói, đủ mô tả). Chưa có: tự sinh lại ở pre-commit (chờ mục 3).
9. Bẫy đã gặp
Xem Bẫy đã gặp thật, có thêm phần bẫy riêng của Conan. Bẫy 6 (gác ở máy đọc cây làm việc) đã xảy ra ngay trong lượt đo này: archived-migrations đỏ giả vì so với origin/main thay vì merge-base.
Thứ tự đề xuất
| Bước | Việc | Vì sao trước |
|---|---|---|
| 1 | Hook PreToolUse(Bash) chặn lệnh nguy hiểm + SessionStart cảnh báo clone cũ | Rẻ, chặn loại hỏng không gỡ lại được; H4 đã ở L1 tám ngày |
| 2 | Gate lưu trữ | Lịch sử git vừa viết lại, không muốn làm lần hai |
| 3 | CI: một job cho kiểm, cache chỉ lưu trên main, sửa error-ledger | Đang vượt hạn mức phút miễn phí |
| 4 | Git hooks .githooks/ (pre-commit, pre-push typecheck + test app bị đụng) | Điều kiện cần cho trunk; có lợi cả khi giữ PR |
| 5 | Tầng report, paths, tự kiểm cho 8 gác, gác 500 dòng | Dọn bộ gác |
| 6 | Lượt hằng tuần trên máy | Cần tầng report và bộ nâng gói theo thư mục |
| 7 | Trunk (nếu chủ dự án chọn) | Chỉ sau bước 3 và 4 |
Số liệu nền
| Đo 18.10.2026 | |
|---|---|
| Gác | 40 mục (26 gác + 14 tự kiểm), 5,0 giây song song, 13,3 giây tuần tự |
| Hook trước push | run-guards --fast: 14 gác, khoảng 1,3 giây; không typecheck, không test |
| Git hooks | 0 |
| Hooks Claude Code | 5 (2/5 có tự kiểm) |
| Workflow | 23 (1 kiểm PR, 16 deploy, 2 cron, 3 chạy tay, 1 dùng chung) |
| Lượt Actions 14 ngày | 695; ci-checks 193 lượt, đỏ 11% |
| Phút Actions ước | khoảng 2.580 mỗi tháng (hạn Free 2.000) |
| Cache Actions | 8,05 GB / 10 GB |
| Test | 14 test api + 3 file tool-plane; 4 test tích hợp api không chạy ở đâu; 0 E2E |
| Lockfile | 30 thư mục, không npm workspaces |
| Mốc qc-scan | any 1.806, lint-disable 18, catch-to-empty 39, file > 1.000 dòng 12 |
| PR merge 14 ngày | 127 |
Bản chấm 8 tiêu chí x 5 mức lần trước: docs.conan.school, 10.10.2026.