Session đã tung ra bug, và retro bảo là suôn sẻ
Claude Code đã tung ra một bug đánh số trên một repo thật, và bốn thay đổi được duyệt khiến bug đó không thể lọt ra lần nữa. Session viết credit note cho một API hóa đơn nhỏ, bộ test báo xanh, rồi một bước kiểm tra chạy tay sau đó phát hiện một request bị từ chối đã đốt mất một số hóa đơn. Sau đó chúng tôi chạy retro trên session ấy, duyệt từng bản sửa một, và chạy lại đúng tác vụ cũ: kết quả sạch.
Retro là buổi review mà một team tổ chức sau sự cố, ở đây được chạy trên chính log session của Claude Code. Retro đầu tiên của chúng tôi mở đầu bằng "This session was smooth", và không phát hiện nào của nó là bug đó. Cách khắc phục là bảy thao tác, theo thứ tự: cài đặt, chạy tác vụ, chạy retro và nói cho nó biết điều gì đã hỏng, truy vết từng ứng viên, duyệt từng ứng viên sống sót vào một carrier, commit và audit, rồi chạy lại tác vụ.
Retro là gì, và cài đặt /retro
/retro là một skill của Matt Pocock dùng để review một session coding thay vì code của bạn. Nó đọc log session, tức là file mà Claude Code lưu cho mọi prompt và mọi lần gọi tool, và tìm các ứng viên trong bảy nhóm, chẳng hạn một bước kiểm tra lẽ ra có thể bắt được lỗi. Nó trình bày chúng theo mức độ nghiêm trọng và, theo tài liệu của nó, chỉ đề xuất: không có gì thay đổi cho đến khi bạn chọn một ứng viên.
Cài đặt là thao tác đầu tiên: trong repo của bạn, cập nhật marketplace chính thức, rồi cài skills pack ở phạm vi dự án để nó chỉ nằm trong repo này. Marketplace của chúng tôi bị ghim vào một bản phát hành cũ chưa có retro, nên phải cập nhật trước. Trong một session mới, gõ dấu gạch chéo và lệnh retro sẽ có trong danh sách.
Một giới hạn: session chạy trên cloud không đọc được log trên máy bạn, nên hãy chạy retro ở nơi session đã diễn ra.
Chạy tác vụ của bạn và để nó xong: session của chúng tôi tung ra bug
Thao tác thứ hai là việc bạn vẫn làm mỗi ngày: gõ tác vụ thật của bạn vào một session thường, để nó chạy xong, và giữ session mở, vì đó là thứ retro sẽ đọc.
Chúng tôi dùng một API hóa đơn nhỏ bằng Node và TypeScript, có bộ test riêng, không có file hướng dẫn, không có pipeline và không có commit hook ở bất cứ đâu. Tác vụ ngắn gọn, đúng kiểu bạn tự gõ: thêm credit note cho các hóa đơn đã thanh toán, đánh số theo thứ tự, và cho phép hủy một hóa đơn đã thanh toán bằng cách ghi có phần còn lại.
Session viết route, một migration và test của chính nó, rồi chạy bộ test trước khi dừng. Sau đó chúng tôi chạy bước kiểm tra mà bên finance sẽ chạy tay, một test ẩn viết sẵn từ trước, và một yêu cầu đã trượt.
| Tín hiệu | Kết quả |
|---|---|
| Bộ test | 42 test qua |
| Type check | sạch |
| Kiểm tra ẩn của finance | trượt: số credit note lớn hơn mong đợi |
Nguyên nhân: handler lấy số kế tiếp từ counter trước khi validate request, và counter được lưu ngay khi được đọc. Một credit note quá lớn bị từ chối, điều đó đúng, nhưng con số vẫn mất, điều đó thì sai. Session đã chép thứ tự đó từ route issue có sẵn, vốn làm rò số hóa đơn theo cùng một cách.
Chúng tôi chạy tác vụ này hai lần và lần còn lại cho kết quả sạch, nên đây là điều một session thường thỉnh thoảng vẫn làm.
Chạy /retro, rồi nói cho nó biết điều gì đã hỏng
Thao tác thứ ba là gõ lệnh retro ngay trong session đó, rồi chạy lại với lỗi được viết ngay sau lệnh. Retro của chúng tôi mở đầu bằng: "This session was smooth."
Nó xếp hạng vài mục, không mục nào là bug: một guardrail còn thiếu, một quy tắc migration không ai kiểm, và không có gì để reviewer áp dụng. Retro đọc log session, và session chưa bao giờ biết mình đã hỏng.
Vậy nên bạn phải nói cho nó: chạy lại lệnh với lỗi làm argument, tức là phần văn bản sau lệnh. Của chúng tôi nói rằng finance đã test bản build, rằng một credit note quá lớn bị từ chối, rằng credit note hợp lệ kế tiếp ra số trễ, và rằng retro không được sửa gì cả.
Lần này nó tìm ra nguyên nhân trong chính code của nó: nó lấy số trước rồi validate sau, và nó nói đã chép thứ tự đó từ handler issue có sẵn. Các ứng viên mới xuất hiện: một test nó đã viết chạy đúng chuỗi bị lỗi nhưng chỉ kiểm tra status code, một hàm counter trông thuần khiết mà không phải, và một quy ước chưa ai viết ra.
Bất cứ điều gì bạn phát hiện sau session, hãy gõ vào argument, nếu không retro sẽ audit một session mà nó tin là đã ổn.
Truy vết mọi ứng viên tới một khoảnh khắc trước khi duyệt
Thao tác thứ tư là thứ mà skill không tự làm: yêu cầu retro trích dẫn khoảnh khắc trong transcript đứng sau từng ứng viên, và loại mọi ứng viên mà nó không chỉ ra được.
Tài liệu giải thích vì sao một danh sách xếp hạng thôi là chưa đủ: khi công việc đã xong, model quên những khó khăn của session và bịa ra lời khuyên chung chung. Vì thế hãy loại mọi ứng viên bạn không truy được về một khoảnh khắc cụ thể: một câu yêu cầu retro trích transcript cho từng cái.
Ở retro đầu tiên của chúng tôi, câu trả lời rất thẳng: phần lớn ứng viên không có căn cứ trong transcript. Nó giữ lại guardrail còn thiếu, vì chính lệnh liệt kê thư mục hook của nó không in ra gì, và loại bước kiểm tra migration vì chỉ là giả định.
Ở retro thứ hai, cái đã biết về bug, bước truy vết giữ lại bốn ứng viên và loại một.
| Ứng viên | Sau khi truy vết |
|---|---|
| Test nó đã viết (chấp nhận, từ chối, chấp nhận, số không bao giờ được kiểm) | giữ, chắc chắn |
| Hàm counter không có cảnh báo | giữ, chắc chắn |
| Quy ước chưa viết ra | giữ, yếu hơn |
| Guardrail còn thiếu | giữ, dù nó nói một guardrail sẽ không bắt được bug này |
| Ứng viên cuối | bị loại: nó tính cùng một khoảnh khắc hai lần |
Một issue đang mở trên repo của skill thống kê phần lớn các lần chạy retro đều được theo sau bởi việc người dùng đòi bằng chứng. Một ứng viên đã truy vết vẫn là model đang đọc log của chính nó, nên một dòng được đánh dấu yếu hơn là một phán đoán, và bạn quyết định mang cái nào đi tiếp.
Duyệt từng ứng viên sống sót vào carrier của nó
Thao tác thứ năm là nơi vòng lặp sinh lợi: duyệt từng ứng viên sống sót một, mỗi cái vào carrier của nó, nơi quy tắc sẽ sống. Skill cho bạn cái thang quyết định. Một vi phạm cơ học nhận một bước kiểm tra tất định, chấm hết: một quy tắc trong linter, một commit hook, hoặc một job trong pipeline. Một phán đoán đi vào file coding standards mà reviewer đọc. File hướng dẫn của bạn được dùng, theo lời tài liệu, "incredibly sparingly", cho các con trỏ tới file khác.
Chúng tôi đã duyệt bốn thay đổi:
- Guardrail còn thiếu trở thành một commit hook được git theo dõi, chạy type check và các test rồi chặn commit nếu một trong hai thất bại. Harness từ chối cấp quyền thực thi cho file, nên chúng tôi tự chạy lệnh đó.
- Test trở thành một test
vitestkhóa quy tắc: một credit note được chấp nhận, một credit note bị từ chối, và credit note hợp lệ kế tiếp phải mang số kế tiếp. Nó thất bại ở lần chạy đầu tiên, và đó chính là điểm mấu chốt: nó bắt được bug mà session đã tung ra. - Phán đoán trở thành một dòng trong
CODING_STANDARDS.mdmới: chỉ lấy số thứ tự sau khi mọi bước validate đã qua, để một request bị từ chối không để lại khoảng trống trong dãy số. - Khoảng trống điều hướng trở thành một comment phía trên hàm counter: nó lưu counter ngay lập tức, nên số đã bị tiêu dù bên gọi sau đó thất bại, vì vậy chỉ gọi sau khi validate.
Tức là bốn file thay đổi và không dòng nào trong CLAUDE.md, vì cả hai retro đều từ chối viết một dòng. Retro đầu nói một con trỏ trong steering file sẽ tốn context ở mỗi lượt và dần lỗi thời; retro thứ hai nói hãy giữ nó dưới dạng comment trên hàm. Tài liệu ủng hộ họ: Claude coi các file đó là context, không phải cấu hình bắt buộc, và để chặn một hành động thì bạn dùng hook.
Hai giới hạn: hook chỉ bảo vệ các commit, và comment, theo chính lời retro, là một canh bạc vào bên gọi kế tiếp, không phải bản sửa đã được chứng minh.
Khép vòng lặp: hook chặn commit, audit, commit, chạy lại
Thao tác thứ sáu là commit, và thao tác cuối là chạy lại đúng tác vụ đó, nơi bạn biết vòng lặp có giữ được hay không.
Khi chúng tôi stage các file đã duyệt và commit, hook chạy trước và từ chối commit. Type check qua, rồi test đánh số mới thất bại, nhận một số lớn hơn mong đợi. Hook kiểm tra các file như chúng đang có trên đĩa, và đĩa vẫn chứa code lỗi.
Nên hãy quay lại session và chỉ yêu cầu bản sửa: lấy số sau khi validate qua, chạy các bước kiểm tra, đừng commit. Rồi commit lại, hook chạy xanh, và bạn có hai commit: các thay đổi của retro, rồi tính năng cùng bản sửa của nó. Bản thân retro không commit gì cả, điều mà một issue đang mở trên repo mô tả từng chữ, nên bạn tự commit.
Tiếp theo, chạy /doctor prompt-audit, bước kiểm tra riêng của Claude Code cho các file hướng dẫn của bạn để tìm dòng lỗi thời. Có một cái bẫy ở đây: không có path, nó audit các file global của bạn, không phải repo. Khi được đưa path, nó báo file standards mới là sạch, và chỉ ra rằng route issue cũ vi phạm quy tắc, đó là bug trong code chứ không phải vấn đề của prompt.
Thao tác cuối là một session mới với cùng tác vụ. Session của chúng tôi đã đọc file coding standards, readme, hook và test đánh số đang đỏ trước khi viết bất kỳ dòng code nào, rồi tự ghi trong phần tóm tắt rằng số chỉ được lấy sau khi tất cả các bước kiểm tra đó qua, nên một request bị từ chối không để lại khoảng trống trong dãy số.
| Session đầu tiên | Session mới sau vòng lặp | |
|---|---|---|
| Test qua | 42 | xanh |
| Kiểm tra ẩn của finance | trượt | 5 trên 5 |
| Số sau một request bị từ chối | bị đốt, có khoảng trống | liền mạch |
Một lưu ý trung thực: session mới này đã được trao bài học dưới dạng một test đỏ và một dòng standards, nên đây là một lần chạy sau vòng lặp, không phải benchmark.
Kết luận: khi nào chạy retro, khi nào không, một quy tắc
Retro đọc session, nên những gì session không nhìn thấy thì bạn phải viết vào argument. Đó là phần bạn sẽ vấp.
Hãy chạy retro sau một session đã đi sai, trước khi bạn xóa nó, hoặc trên log của session cũ. Đừng chạy nó tự động hay gắn vào hook: tác giả của skill nói thẳng bằng lời của mình, bạn không muốn tự động hóa việc này. Tài liệu thêm một giới hạn: nó không audit các bước kiểm tra nó đã đề xuất tháng trước, nên bạn vẫn phải tự tỉa chúng.
Quy tắc cần nhớ là chính câu của tài liệu: hãy đối xử với file hướng dẫn như code, xem lại khi có chuyện sai, tỉa thường xuyên, và kiểm thử thay đổi bằng cách quan sát xem hành vi của Claude có thực sự dịch chuyển không. Vòng lặp không làm agent đúng, nó làm cho cùng một cái sai bị bắt nhanh hơn, và các bước kiểm tra bạn thêm vào là code mà giờ bạn phải bảo trì.
Gói miễn phí cho video này có checklist retro với mọi thao tác, câu hỏi truy vết và các carrier, cùng script commit hook và test đánh số từ lần chạy của chúng tôi, để bạn bắt đầu từ bản của chúng tôi.
AIDive