---
url: https://docs.nemo12.com/architecture/sdd-057-error-learning.md
description: >-
  Error Learning (SDD-057): ghi mọi lỗi GitHub Actions và Cloudflare theo
  fingerprint, lần 1 rà và chặn, lần 2 là chốt hỏng; số đo nền 30 ngày.
---

# SDD-057 - Error Learning

**Nguyên tắc:** *Một lỗi đã gặp thì không được gặp lại theo cùng một đường.* Ghi nhận lỗi chưa đủ;
mỗi lỗi phải đổi lấy một chốt chặn do MÁY thi hành, đặt càng gần lúc sinh code càng tốt.

Lý do có domain này: trong 30 ngày đo (§6), CI đỏ 463 lần, khoảng 15 lần mỗi ngày, và phần lớn
là cùng một vài lỗi lặp lại. Mỗi lần CI đỏ trên `main` là deploy của mọi phiên đứng lại. Bài học
cũ chủ yếu được ghi thành memory, nhưng memory là thứ agent sau CÓ THỂ đọc; chốt chặn là thứ agent
sau KHÔNG THỂ vượt qua.

## 1. Phạm vi: nguồn lỗi (REQ-NFR-16)

| Nguồn | Thu gì | Cách đọc |
| --- | --- | --- |
| GitHub Actions | Mọi run `failure`, `startup_failure`, `cancelled`; tên job, tên bước hỏng, log bước hỏng | `gh api .../actions/runs`, `gh run view --log-failed` |
| Cloudflare Workers | Exception theo worker (`scriptThrewException`, `exceededResources`), tỉ lệ trên tổng lượt gọi | GraphQL `workersInvocationsAdaptive` |
| Cloudflare deploy và D1 | Deploy hỏng, migration hỏng | Đã nằm trong log GitHub Actions vì deploy chỉ đi qua CI (skill `deploy`) |
| Cloudflare lỗi 5xx do code tự trả | Response 5xx không ném exception | Cần bật Workers Logs; **chưa đo được**, xem §7 |

`clientDisconnected` (người dùng đóng tab giữa chừng) không phải lỗi và không vào sổ.

## 2. Sổ lỗi và fingerprint (REQ-NFR-16)

Mỗi lần lỗi là một dòng: nguồn, thời điểm, commit, nhánh, app hoặc worker, tên bước, đoạn log
lỗi. Nhiều dòng cùng một **fingerprint** là cùng một lỗi.

Fingerprint lấy từ các dòng đánh dấu lỗi (`##[error]`, `✗`, `FAIL`, `error TS`, `[chromium] ›`)
sau khi chuẩn hoá: bỏ hash commit, số dòng và cột, thời lượng, mọi con số. Dòng log phụ của test
đang XANH (vd `KV down` trong test cố ý giả lỗi) không được tính; phép đo nền đã dính đúng bẫy
này ở lượt đầu và đếm nhầm 355 run thành "lỗi Cloudflare".

Mỗi fingerprint mang: số lần gặp, lần đầu, lần gần nhất, loại (§3), chốt chặn (§4), trạng thái.

## 3. Luật xử lý: lần 1 rà và chặn, lần 2 là chốt hỏng (REQ-NFR-17)

Chủ dự án chốt ngày 13.10.2026: không chờ lỗi xảy ra lần hai mới chặn. Chờ lần hai nghĩa là trả
thêm một lần CI đỏ và deploy đứng cho một lỗi đã biết.

**Lần 1, mọi fingerprint mới:** rà nguyên nhân gốc ngay, xếp vào đúng một loại:

| Loại | Ví dụ | Chốt bắt buộc |
| --- | --- | --- |
| **Máy phát hiện được** | Quên `gen:reference`, lint, số migration trùng | Chốt máy ngay (§4) |
| **Ngoại cảnh** | GitHub, npm hay Cloudflare sập, mạng chập chờn | Không thêm cổng; retry tự động và gắn nhãn ngoại cảnh để không làm nhiễu số đo |
| **Phán đoán** | Hiểu sai yêu cầu, chọn sai thiết kế | Ghi vào rule, skill hoặc PRD mà agent đọc TRƯỚC khi viết |

**Lần 2 cùng fingerprint:** không phải lỗi mới mà là bằng chứng chốt lần 1 hỏng hoặc chọn sai
loại. Xử lý trước mọi việc khác.

Vì sao không chốt máy cho MỌI lỗi: mỗi cổng có giá (thời gian commit, bảo trì, báo oan). Hook
chậm và báo oan dạy người ta dùng `--no-verify`, tức là mất luôn mọi cổng. Nên ngưỡng nằm ở
**chọn đúng loại chốt**, không nằm ở **chờ lần hai**.

## 4. Thang chốt chặn: càng sớm càng rẻ (REQ-NFR-18)

| Bậc | Chốt | Chặn lúc |
| --- | --- | --- |
| 1 | Rule `.claude/rules/`, skill, CLAUDE.md | Agent đang SINH code |
| 2 | Hook PreToolUse (`.claude/hooks/block-dangerous.mjs`) | Agent sắp chạy lệnh nguy hiểm |
| 3 | Pre-commit TỰ SỬA (`scripts/precommit-autofix.mjs`) | Commit; máy sửa luôn, không cần ai nhớ |
| 4 | Pre-commit CHẶN (lint, typecheck, `check:code`, `check:docs`) | Commit, trên máy, vài giây |
| 5 | Cổng CI, test hồi quy | Sau push, khoảng 10 phút |

Chọn bậc thấp nhất làm được. Một bước "phải nhớ làm" mà máy làm được thì phải ở bậc 3, không được
dừng ở bậc 4 hay 5: cổng chỉ BÁO đỏ vẫn cần người nhớ sửa.

Đã có (PR [#649](https://github.com/dac2205/nemo12.com/pull/649), 13.10.2026): bậc 3 tự bump
`last_reviewed`, tự sinh lại `docs/reference` và catalog skill; bậc 4 chạy ESLint trên file đã
stage và typecheck đúng workspace bị đụng. Script không bao giờ `git add` file còn phần chưa stage
(luật cây chung SRC-457).

## 5. Đo: hệ có đang tốt lên không (REQ-NFR-19)

| Chỉ số | Định nghĩa | Đích |
| --- | --- | --- |
| **Tỉ lệ lỗi lặp** | Số lần gặp của các fingerprint ĐÃ có chốt, trên tổng số lần lỗi | 0 |
| Run CI đỏ mỗi ngày | Trung bình 7 ngày, chỉ tính `main` | Giảm theo tuần |
| Fingerprint chưa phân loại | Fingerprint mới quá 24 giờ chưa có loại và chốt | 0 |
| Nhiễu | Run đỏ không do code (workflow hỏng cấu hình, ngoại cảnh) | Tách riêng, không trộn vào hai số trên |

Báo cáo tuần: lỗi mới, lỗi lặp, chốt mới thêm, chốt hỏng.

## 6. Số đo nền 13.09.2026 - 13.10.2026

GitHub Actions: **463 run đỏ** (305 trên `main`), 416 run huỷ, 90 run không khởi động được.

| Nhóm nguyên nhân | Run | Loại | Chốt |
| --- | --- | --- | --- |
| Docs quên cập nhật: `last_reviewed` 65, SRC thiếu ở canonical 36, `docs/reference` lệch 31, catalog skill 6 | ~138 | Máy | Bậc 3 đã có, trừ SRC canonical (cần người viết nội dung) |
| e2e learn | 81 | Máy | Chưa rà từng ca |
| Thiếu secret `AUTOMERGE_TOKEN` | 69 | Nhiễu cấu hình | Đã tắt workflow `automerge` 13.10.2026 |
| Lint 46, typecheck 26 | 72 | Máy | Bậc 4 đã có |
| Test API (16 ca route thiếu xác thực) | 44 | Máy | Cổng `authCoverage` có sẵn, chặn ở bậc 5 |
| Ký tự cấm, SEO keyword, tương phản, bindings, số migration | ~42 | Máy | Cổng có sẵn, phần lớn đã ở bậc 4 |
| Startup failure từ workflow `BuildFailed` đã xoá | 81 | Nhiễu | Chưa tìm nhánh còn giữ file |
| `seed-data` tự huỷ khi chờ production | 69 huỷ | Nhiễu | Chưa xử lý |

Cloudflare Workers (cả tài khoản): `nemo12-api` có 2.180 lượt không thành công trên 94.287, gần như
toàn bộ là `clientDisconnected`, chỉ khoảng 4 exception thật. Nguồn exception lớn nhất là dự án cũ
chung tài khoản: `chuyenchon-diagnosis-quality` (2.176 exception, 100% lượt gọi) và
`chuyenchon-mori-quality` (429, 27%).

## 7. Chưa dựng

* Bộ thu tự động và sổ lỗi trong D1. Số đo §6 làm tay bằng `gh` và GraphQL. Theo luật dự án, bộ
  thu chạy định kỳ là Cloudflare Workflows.
* Đọc lỗi 5xx do code tự trả về (cần Workers Logs).
* Trang báo cáo tuần trên admin.
* Rà từng ca e2e đỏ để xếp loại.

## Trace

| REQ | Section |
| --- | --- |
| REQ-NFR-16 | §1, §2 |
| REQ-NFR-17 | §3 |
| REQ-NFR-18 | §4 |
| REQ-NFR-19 | §5, §6 |
