Incident đầu tiên làm tôi đổi cách dùng AI coding không phải outage lớn. Nó chỉ là một bug nhỏ trong màn hình export CSV. Khách bấm export, file tải về rỗng. API vẫn 200. Monitoring không báo đỏ. Support gửi screenshot vào chat. Người vừa merge change nói: “Có thể do cache, để em nhờ AI fix nhanh.” Câu đó nghe vô hại, nhưng trong incident nó là câu nguy hiểm.

Khi production đang sai, mục tiêu không phải sửa nhanh nhất bằng mọi giá. Mục tiêu là khôi phục dịch vụ đúng và giữ lại bằng chứng để hiểu vì sao sai. AI rất hữu ích trong incident, nhưng nếu để nó kéo bạn vào thêm một diff nữa khi chưa khoanh vùng, bạn đang biến incident một lỗi thành incident hai lỗi.

Việc đầu tiên: freeze scope

Incident cần một câu đầu tiên rất khô:

Freeze deploy. No unrelated changes until incident owner clears.

Với nhiều worker hoặc nhiều AI assistant chạy song song, freeze scope càng quan trọng. Một người đang sửa bài blog, một người đang đổi build config, một người đang debug export CSV. Nếu tất cả cùng sửa trên cùng branch hoặc cùng deploy target, bạn sẽ không biết change nào tạo ra symptom mới.

Freeze scope không có nghĩa dừng mọi việc. Nó có nghĩa chỉ làm việc phục vụ incident:

  • Xác nhận symptom.
  • Xác định blast radius.
  • Chọn rollback hoặc hotfix.
  • Deploy khôi phục.
  • Smoke test.
  • Ghi timeline.

Mọi refactor, cleanup, “sẵn tiện sửa luôn” đều để sau.

Đừng bắt đầu bằng root cause

Trong incident, root cause là việc sau. Trước tiên là restore. Đây là tradeoff nhiều developer không thích, vì chúng ta muốn hiểu bug. Nhưng khách không cần bạn hiểu ngay. Khách cần hệ thống chạy lại.

Tôi dùng checklist ba câu:

  1. Impact là gì? Người dùng nào bị ảnh hưởng, flow nào sai, data có mất không.
  2. Có rollback point an toàn không? Nếu có, rollback trước rồi investigate sau.
  3. Nếu rollback không an toàn, hotfix nhỏ nhất là gì?

AI có thể đọc log và đề xuất root cause, nhưng tôi không để nó quyết định thứ tự. Nếu change vừa deploy rõ ràng liên quan symptom và rollback không có migration nguy hiểm, rollback thường đúng hơn hotfix. Hotfix trong incident dễ thêm lỗi vì bạn đang code dưới áp lực.

Rollback không phải thất bại

Nhiều team ngại rollback vì cảm giác mất mặt. Tôi nghĩ ngược lại: rollback nhanh là dấu hiệu pipeline trưởng thành. Bạn đã chuẩn bị đường quay lại, nên khi production sai bạn dùng nó.

Rollback tốt có vài tính chất:

  • Nhanh: thao tác rõ, không phải mò trong CI.
  • Hẹp: quay lại đúng artifact gây lỗi, không kéo theo change khác nếu có thể.
  • Có bằng chứng: log ghi ai rollback, lúc nào, từ version nào về version nào.
  • Có smoke sau rollback: không assume rollback thành công chỉ vì command exit 0.

Ví dụ deploy frontend bằng static hosting, rollback có thể là promote previous deploy. Với container, redeploy previous image digest. Với feature flag, tắt flag. Với database migration destructive, rollback có thể không tồn tại theo nghĩa đơn giản. Lúc đó bạn cần mitigation: disable UI path, block job, hoặc patch forward rất nhỏ.

Điểm này phải được biết trước deploy. Nếu trong incident mới phát hiện migration không rollback được, đó là lỗi của deploy planning, không phải lỗi của incident response.

Khi nào hotfix thay rollback

Rollback không phải lúc nào cũng đúng. Có những case hotfix tốt hơn:

  • Rollback sẽ gỡ nhiều fix khác đã deploy chung.
  • Bug nằm ở config production mới, rollback code không giúp.
  • Data đã migrate forward và code cũ không còn compatible.
  • Hotfix là một dòng guard, risk thấp hơn rollback.
  • Incident do external API thay đổi, version cũ cũng fail.

Nhưng “AI sửa được nhanh” không phải lý do chọn hotfix. Lý do phải là risk. Nếu hotfix, scope phải cực nhỏ. Không refactor. Không đổi naming. Không “làm sạch luôn”. Mở file liên quan, sửa một điểm, test đúng symptom, deploy.

Một hotfix tốt có commit message và deploy note đọc lên thấy chán:

fix billing export when paidAt is null

Nếu hotfix description phải giải thích năm concept mới hiểu, có lẽ bạn đang làm quá nhiều trong incident.

AI đọc log rất tốt, nhưng cần khung câu hỏi

Trong incident, AI hữu ích nhất ở phần đọc log, diff, và timeline. Nhưng prompt phải có ranh giới. Tôi không hỏi “fix this incident”. Tôi hỏi:

Read these logs and group errors by endpoint and first-seen timestamp.
Do not propose code changes yet.
Return only:
- suspected failing path
- first error time
- repeated stack traces
- unknowns

Hoặc:

Compare this deploy diff with the symptom "CSV export returns empty file".
List changed functions that can affect export rows.
Do not suggest refactors.

Bạn muốn AI làm analyst, không phải firefighter tự lái. Firefighter vẫn là người có context production, quyền deploy, và trách nhiệm với khách.

Timeline là artifact chính của incident

Sau khi hệ thống khôi phục, nhiều team nhảy ngay sang sửa root cause. Tôi muốn timeline trước, khi trí nhớ còn nóng.

Timeline tối thiểu:

Incident timeline
- 09:42 deploy commit abc123 to production.
- 09:51 first support report: CSV export empty.
- 09:55 owner confirmed impact: export CSV for paid invoices.
- 10:02 rollback to deploy def456 started.
- 10:06 rollback completed.
- 10:09 smoke test passed: export returns 128 rows.
- 10:20 root cause investigation started.

Timeline không cần văn chương. Nó cần chính xác. Sau này khi viết postmortem, timeline cứu bạn khỏi kiểu kể chuyện theo trí nhớ. AI có thể format timeline từ Slack, logs, CI output, nhưng timestamps phải lấy từ nguồn thật.

Smoke test sau rollback

Rollback cũng là deploy. Nó cần smoke.

Sau rollback, tôi chạy hai loại smoke:

  • Symptom smoke: flow đang lỗi đã hết lỗi chưa.
  • Regression smoke: flow chính khác có bị rollback làm hỏng không.

Nếu rollback export CSV, symptom smoke là export ra file có rows. Regression smoke có thể là login, dashboard load, invoice detail open. Không cần full suite, nhưng cần đủ để tự tin rằng bạn không đổi một lỗi thành lỗi khác.

Một pattern tốt là ghi sẵn smoke command hoặc manual path trong deploy note. Khi incident đến, bạn không phải nghĩ nhiều.

Không để AI chạm secret và production config trong hoảng loạn

Incident hay tạo cám dỗ nguy hiểm: dán log, env, token, config vào AI để nó phân tích. Đừng. Nếu cần dùng AI, sanitize trước. Secret trong incident thường xuất hiện ở headers, connection string, signed URL, stack trace có env dump.

Rule của tôi:

  • Không dán .env thật.
  • Không dán full request headers nếu có Authorization/Cookie.
  • Không dán database URL.
  • Không cho AI tự chạy command remote trừ khi user hoặc incident owner explicit approve.
  • Không chạy destructive command trong lúc “thử xem”.

AI có thể phân tích shape của lỗi mà không cần secret. Nếu thật sự cần production access, đó là bước con người kiểm soát riêng.

Postmortem không phải nơi đổ lỗi cho AI

“AI generated bad code” là root cause tệ. Nó không actionable. Root cause tốt phải chỉ ra control nào thiếu.

Ví dụ:

  • Tệ: AI sửa sai logic export.
  • Tốt: PR thiếu smoke test cho invoice paid có paidAt = null.
  • Tệ: assistant hallucinated API contract.
  • Tốt: reviewer không kiểm tra existing hook và không chạy staging data case.
  • Tệ: deploy bị lỗi.
  • Tốt: pipeline không ghi rollback artifact nên mất 18 phút tìm previous version.

AI là một phần của workflow. Nếu AI tạo ra bug và bug ra production, câu hỏi là tại sao review, test, preview, deploy gate không bắt được. Đổ cho AI nghe dễ chịu nhưng không cải thiện hệ thống.

Incident runbook tối thiểu

Tôi thích một runbook ngắn, để ở repo hoặc wiki, ai cũng đọc được:

Production incident flow
1. Assign incident owner.
2. Freeze unrelated deploys.
3. Confirm impact and affected user path.
4. Check latest deploy artifact and changed files.
5. Choose rollback unless rollback risk is higher than hotfix.
6. Execute rollback/hotfix with one owner.
7. Run symptom smoke and regression smoke.
8. Record timeline.
9. Open root cause task after restore.

Runbook này không phụ thuộc tool. Dùng GitHub Actions, Vercel, S3, Docker Swarm, Kubernetes đều áp dụng được. Phần tool chỉ là command cụ thể.

Điều tôi muốn thấy trong team dùng AI coding

Tôi không cần team promise rằng AI sẽ không bao giờ tạo bug. Promise đó vô nghĩa. Tôi muốn thấy ba thói quen:

  • Mỗi deploy có rollback point.
  • Mỗi incident freeze scope trước khi sửa.
  • Mỗi postmortem sửa control, không chỉ sửa code.

AI coding tăng throughput. Throughput cao làm incident nhỏ xảy ra thường hơn nếu pipeline không lớn lên cùng. Cách phản ứng đúng không phải cấm AI, mà là đưa AI vào một operational loop rõ: AI giúp đọc, tóm tắt, đề xuất; người giữ quyền rollback, quyền deploy, và quyền kết luận.

Khi production đang cháy, câu hỏi không phải “AI có fix được không”. Câu hỏi là “đường khôi phục an toàn nhất là gì”. Trả lời được câu đó, incident đã đi đúng hướng.