"Code lên trước bảng"
Triệu chứng: API trả 500 với no such column / no such table trong observability log ngay sau một lần deploy; một màn hình mới trống hoặc lỗi trong khi typecheck và test đều xanh.
Vì sao từng xảy ra, và luồng hiện tại
Tới 2026-09-03, push vào main chỉ deploy code; migration D1 chỉ áp khi bấm tay deploy-api.yml. Quên bấm một lần là code đọc cột chưa có (SRC-464: 0064/0065 nằm PENDING nhiều giờ). Trong 7 ngày trước 2026-09-04 có 20 commit migration cần 30 lần bấm tay.
Từ 2026-09-04 (Audit #013 I-1): push đụng migrations/ thì ci.yml tự áp migration lên production ngay trước bước deploy foundry/api/tool-plane, sau khi cùng lượt đã migrate:dryrun từ D1 rỗng, và xác nhận lại bằng wrangler d1 migrations list --remote phải ra "No migrations to apply". Áp hỏng thì job đỏ và không worker nào lên.
Khi vẫn gặp
| Tình huống | Xử lý |
|---|---|
Deploy tay deploy-<app>.yml trên commit cũ hơn migration mới nhất | Bản cũ phải chịu được schema mới (AS-04.1.3). Nếu không, deploy lại main |
| ci đỏ ở bước "Apply D1 migrations" | Đọc log: migration nào hỏng. Sửa nội dung migration (README §1: chỉ khi ra cùng schema cuối) hoặc thêm migration mới, push lại. Không chạy --remote từ máy |
| Cần áp bù mà không sửa code | gh workflow run deploy-app.yml --ref main -f app=api — bước apply + migrations list xác nhận, rồi deploy lại api |
Nghi sổ d1_migrations lệch với đĩa | Theo migration-reconciliation |
Kiểm nhanh production còn pending không (chỉ đọc):
gh workflow run deploy-app.yml --ref main -f app=api # log của bước apply in "No migrations to apply"Cấm wrangler d1 migrations apply --remote và d1 execute --remote từ máy cá nhân (README). scripts/d1.mjs chặn câu ghi trừ khi đặt NEMO12_ALLOW_REMOTE_WRITE=1 có chủ đích.