Biến kinh nghiệm thành luật
Vòng lặp biến mỗi sự cố thành một dòng luật không bao giờ tái phạm. Cách viết luật đúng, chỗ cất, và khi nào gỡ luật ra.
Khác biệt giữa người làm một năm và người làm một năm lặp lại mười hai lần nằm ở đúng một việc: có ghi lại hay không.
Vòng lặp bốn bước
SỰ CỐ → XỬ LÝ → VIẾT THÀNH LUẬT → ĐẶT VÀO CHỖ TỰ ĐỘNG ĐƯỢC ĐỌC
↑ │
└──────────── không bao giờ tái phạm ──────────┘
Bước 3 là bước ai cũng bỏ, vì lúc vừa xử lý xong sự cố thì bạn mệt và chỉ muốn nghỉ. Nhưng đó là lúc duy nhất bạn còn nhớ đủ chi tiết. Một tuần sau, bạn chỉ còn nhớ "có lần app treo".
Luật thực hành: chưa viết xong dòng luật thì sự cố chưa đóng.
Viết luật thế nào cho dùng được
Một dòng luật tốt có bốn phần:
[LÀM GÌ / CẤM GÌ] + [VÌ SAO] + [DẤU HIỆU NHẬN RA] + [CÁCH ĐÚNG]
So sánh:
❌ "Cẩn thận với waitUntil." Vô dụng. Cẩn thận thế nào? Khi nào?
✅ "Không đặt việc nhiều lượt gọi D1 vào
ctx.waitUntil— nó giữ D1 dùng chung khiến mọi request khác xếp hàng, app treo mà log không đường nào có vẻ chậm (sự cố 20/08, dọn 40 ảnh làm sập đường tải). Dấu hiệu: app treo nhưng tỉ lệ lỗi bình thường. Cách đúng: chuyển sang Cron Trigger riêng hoặc lệnh thủ công/admin."
Phần dấu hiệu nhận ra là phần quý nhất và hay thiếu nhất. Nó biến luật từ "điều cần nhớ khi viết mã" thành "công cụ chẩn đoán khi có sự cố".
Ba chỗ cất luật, theo phạm vi
| Luật áp dụng cho | Cất ở | Ai đọc |
|---|---|---|
| Một project | CLAUDE.md của project |
Claude Code mỗi phiên, và bạn |
| Mọi project của bạn | Một skill dùng chung | Claude Code khi hợp tình huống |
| Môi trường máy bạn | Mục "Bẫy môi trường" trong skill đó | Như trên |
Và một chỗ thứ tư, quan trọng không kém: chỗ nào tự động chặn được thì đừng chỉ viết thành chữ.
Luật: "Không deploy thẳng lên bản thật khi chưa test preview"
→ chữ: một dòng trong CLAUDE.md
→ chặn: một hook chặn lệnh `wrangler deploy`
→ chặn: cổng duyệt `environment: production` trong GitHub Actions
Luật viết bằng chữ thì phụ thuộc vào việc có ai đọc. Luật dựng thành cổng chặn thì không quên được.
Năm loại luật đáng ghi nhất
Theo trải nghiệm, năm nhóm này cho giá trị cao nhất:
1. Bẫy môi trường — thứ chỉ xảy ra trên máy bạn, không có trong tài liệu nào.
Dữ liệu tiếng Việt chết trên dòng lệnh Windows (chữ một dấu rụng dấu, chữ nhiều dấu thành
?) → ghi ra file rồicurl --data-binary @file.
2. Bẫy nền tảng — hành vi của Cloudflare/Git mà bạn phải trả giá mới biết.
Static Assets phục vụ thẳng từ biên, mã Worker không chạy → header phải đặt trong
public/_headers.
3. Luật nghiệp vụ — quy ước của chính dữ liệu của bạn.
Tiền lưu
INTEGERđơn vị đồng. Thời gian lưu UTC,+7 hourskhi hiển thị. Không bao giờ trộn hai cách.
4. Sở thích và cấm kỵ về giao diện — thứ AI không đoán được.
Nền trắng, một màu nhấn. Không gradient, không bóng đổ, không viền trái màu bo tròn. Không đặt nền phía dưới chữ.
5. Ranh giới quyền hạn — việc gì AI không được tự làm.
Không tự deploy lên bản thật. Không nhập đăng nhập hộ. Không đụng dữ liệu thật khi chưa có bản sao lưu.
Tôi đã thử cách ngược lại: đọc tài liệu rồi viết sẵn 50 luật. Kết quả — không ai theo, kể cả tôi. Chúng quá nhiều, quá chung chung, và không gắn với ký ức nào.
Bộ luật thật sự có tác dụng của tôi chỉ khoảng 25 dòng, và mỗi dòng tôi đều nhớ hôm nó ra đời. Dòng về waitUntil là buổi chiều app treo. Dòng về rate limit là sáng hàng trăm nhân viên không đăng nhập được. Dòng về tài khoản test chỉ-xem là lần một lỗi đường ghi lọt lên bản thật.
Nên lời khuyên của tôi: đừng ngồi viết bộ luật. Hãy viết đúng một dòng sau mỗi lần đau. Một năm sau bạn có một thứ mà không ai mua được.
Ngoại lệ — khi không theo được luật
Có lúc bạn phải vi phạm chính luật của mình: deadline, hoặc cách đúng quá tốn kém lúc này. Đừng im lặng vi phạm. Ghi một ngoại lệ có thời hạn:
## NGOẠI LỆ
### Vi phạm luật "danh sách phải có LIMIT"
- **Chỗ:** `/api/xuat-excel` — phải lấy cả năm dữ liệu.
- **Lý do:** kế toán cần một file duy nhất, chia trang không dùng được.
- **Giảm thiểu:** chỉ admin gọi được; chạy ngoài giờ; đã đo 4.200 dòng
mất 6 giây, chấp nhận được.
- **Hạn xét lại:** 01/2027 — nếu quá 10.000 dòng thì chuyển sang
xuất nền và gửi link tải.
Ba lợi ích: bạn không tự lừa mình, người sau hiểu vì sao có chỗ "sai", và hạn xét lại đảm bảo nó không thành vĩnh viễn.
Gỡ luật — việc cũng quan trọng không kém
Bộ luật phình mãi thì không ai đọc. Mỗi quý, rà lại và gỡ:
- Luật đã được chặn tự động — hook hoặc CI đã lo, không cần nhắc nữa bằng chữ.
- Luật về một công cụ không còn dùng.
- Luật mà bạn không nhớ nổi vì sao có. Nếu không có phần "vì sao", và không ai nhớ, nó đã hết giá trị.
Mục tiêu: CLAUDE.md dưới ~100 dòng. Dài hơn thì nó thành tài liệu, mà tài liệu thì không ai đọc.
Đọc lịch sử commit 3 tháng gần đây (git log --oneline -200) và các
commit có từ khóa "sua loi", "fix", "revert", "rollback", "hotfix".
Với mỗi nhóm lỗi lặp lại từ 2 lần trở lên, viết MỘT dòng luật
theo đúng khuôn:
CẤM/PHẢI [gì] — vì [hậu quả cụ thể đã xảy ra] —
dấu hiệu nhận ra: [triệu chứng] — cách đúng: [làm gì thay thế]
Chỉ dựa trên những gì ĐỌC ĐƯỢC trong lịch sử. Không bịa luật chung
chung kiểu "nên viết mã sạch". Nếu không tìm thấy mẫu lặp lại nào,
nói thẳng là không có.
Lần đầu chạy đề này trên một repo đã chạy lâu thường cho 3–8 dòng luật thật — và chúng chính xác hơn bất kỳ danh sách "best practice" nào, vì chúng là lỗi của bạn.
Tôi làm một mình, tôi nhớ hết, cần gì ghi.
Rồi tôi nghỉ Tết hai tuần. Quay lại, tôi không nhớ vì sao mình để một đoạn mã trông rất kỳ quặc trong file đăng nhập. Tôi "dọn" nó cho gọn. Hai ngày sau app lỗi đúng cái lỗi mà đoạn mã kỳ quặc đó đang vá.
Giờ tôi có hai thói quen rất nhỏ:
1. Chú thích ngay tại chỗ kỳ quặc: // Đừng gộp dòng này — xem CLAUDE.md mục "phiên hết hạn".
2. Mỗi tối thứ Sáu, 5 phút: tuần này có gì làm mình mất hơn 30 phút không? Có thì viết một dòng.
Năm phút mỗi tuần. Đó là toàn bộ "hệ thống" của tôi, và nó đủ.
- Đủ: vòng lặp 4 bước, khuôn viết luật 4 phần, ba chỗ cất, năm loại luật đáng ghi, ngoại lệ có hạn, kỷ luật gỡ luật.
- Điểm mạnh nhất: phần "dấu hiệu nhận ra" — biến luật thành công cụ chẩn đoán, không chỉ là điều răn.
- Rủi ro còn lại: hệ thống này chỉ chạy nếu bạn đóng vòng lặp ngay sau sự cố. Không có cách nào ép ngoài kỷ luật cá nhân — hoặc biến nó thành bước cuối bắt buộc trong quy trình xử lý sự cố của bạn.
- Chạy đề rút luật từ lịch sử commit. Đọc kết quả, giữ lại những dòng đúng.
- Viết lại 3 dòng luật của bạn theo đủ bốn phần (làm gì / vì sao / dấu hiệu / cách đúng).
- Chọn một luật trong số đó và biến nó thành cổng chặn tự động (hook, hoặc một bước trong CI).
- Thêm mục "NGOẠI LỆ" vào
CLAUDE.md, ghi ít nhất một chỗ bạn đang cố ý vi phạm luật của chính mình, kèm hạn xét lại.
Việc 3 là việc có giá trị lâu dài nhất: một luật được chặn tự động là một luật bạn không bao giờ phải nhớ nữa.