Ba năm trước mình bị page lúc 2 giờ sáng vì một config đổi timeout từ 30 giây xuống 3 giây, và chẳng ai để ý cho tới khi một queue phía sau nghẽn đủ mạnh để kích cảnh báo ở tận service khác, cách hai tầng. PR gây ra chuyện đó có hai người approve. Cả hai đọc diff, thấy một con số đổi, rồi cho qua — không ai trong hai người đó mang sẵn trong đầu cái mental model “cái timeout này liên quan tới retry policy ở service cách ba tầng” vào lúc 4 giờ chiều một ngày thứ Năm bình thường. Đó không phải lỗi của reviewer. Đó là bản chất của code review: một phán đoán chớp nhoáng trên một cái diff, do một người không thể mô phỏng cả hệ thống production trong đầu, dù senior cỡ nào.

Nên khi Cursor công bố hai agent mới ngày 23/9 — Rollouts và Security Reviewer — phản ứng đầu tiên của mình không phải hoài nghi. Là nhận ra ngay: cả hai nhắm đúng vào cái lỗ hổng đã page mình đêm đó — thứ mà đọc diff không thể bắt được, hoặc vì rủi ro có hình dạng bảo mật nằm ẩn trong đoạn code trông rất bình thường, hoặc vì rủi ro chỉ lộ ra khi traffic thật chạm vào.

Hai con agent này thật sự làm gì

Security Reviewer chạy trên mọi PR, đọc thay đổi trong bối cảnh toàn bộ codebase xung quanh, không đọc tách rời. Điểm đáng nói ở đây không phải “nó kiểm tra pattern xấu” — linter nào cũng làm được — mà là nó lần theo đường đi thật sự của input người dùng tới nơi nó được dùng (sink), thay vì so khớp những hình dạng code đã biết là xấu. Đó là khác biệt giữa bắt được eval(userInput) — quá dễ, static analyzer nào cũng bắt được — và bắt được một input người dùng bị nối chuỗi qua ba lớp hàm gọi rồi mới thành SQL injection, chỉ vì cách một hàm helper phía trên xử lý escaping. Nó phủ injection (SQL, command, template, LDAP), auth bị hỏng hoặc thiếu, secret hardcode trong code, deserialization không an toàn, redirect không kiểm tra, dependency có lỗ hổng đã biết, và cấu hình hạ tầng mặc định không an toàn. Mỗi phát hiện đi kèm mức độ nghiêm trọng, đường tấn công cụ thể, và một nút sửa nhanh. Số liệu Cursor tự công bố: thời gian review trung bình giảm từ 4.8 xuống 3.8 phút mỗi PR, tỷ lệ chấp nhận comment tăng từ 45-50% lên 60-70%.

Rollouts mới là con thú vị hơn, vì nó không dừng lại ở lúc merge. Trước khi PR được merge, nó đọc diff và viết ra một kế hoạch giám sát — theo dõi cái gì, regression sẽ trông ra sao, chỗ nào đang thiếu instrumentation. Bạn có thể sửa tay kế hoạch đó trước khi nó chạy thật. Sau khi deploy, nó kéo tín hiệu sống từ Datadog, Grafana, hoặc Honeycomb, so với baseline trước khi deploy, cố tách “metric này đổi vì tính năng vốn dĩ phải làm vậy” ra khỏi “metric này đổi vì có gì đó hỏng.” Ví dụ Cursor đưa ra khá đắt: nó bắt được một regression chỉ giới hạn ở một endpoint, một khu vực địa lý — kiểu lỗi không bao giờ chạm ngưỡng cảnh báo toàn cục vì bán kính ảnh hưởng quá nhỏ so với con số tổng. Khi nó nghĩ đã tìm ra regression thật, nó có thể nhắn cho tác giả PR, tạm dừng một progressive rollout, hoặc mở một PR revert chờ người duyệt.

Cả hai đều chỉ có ở gói Teams và Enterprise, và điều đó nói lên Cursor nghĩ ai nên là người ra quyết định này — không phải dev đơn lẻ, mà các tổ chức đã có sẵn quy trình on-call và review để gắn tính năng này vào.

Mình thật sự đứng ở đâu với chuyện này

Security Reviewer thì mình thoải mái, một khi đã tinh chỉnh ngưỡng nghiêm trọng nào cần làm phiền ai. Failure mode tệ nhất của nó là một false positive tốn mười phút, hoặc một false negative mà con người cũng có thể bỏ lỡ y vậy — giống hệt failure mode của một linter chặt, chỉ khác là độ chính xác phía false-positive có thể tốt hơn nếu cái tuyên bố “lần theo sink thật” của Cursor đứng vững khi dùng thật. Không ai chết nếu nó ảo giác ra một lỗ hổng không có thật. Chỉ có người phải đọc lại diff thêm lần nữa.

Rollouts mới là chỗ mình muốn đi chậm lại, cụ thể là ở cụm “tạo PR revert chờ duyệt.” Đọc lại cụm đó hai lần — “chờ duyệt” chính là van an toàn, và đó là mặc định đúng. Một agent có thể tự ý revert production mà không cần người trong vòng lặp sẽ là một sản phẩm hoàn toàn khác với cái Cursor vừa ra mắt, và đáng sợ hơn nhiều. Nhưng “chờ duyệt” chỉ có giá trị nếu người ở cuối chuỗi coi bước duyệt đó là một phán đoán thật, chứ không phải một cú click cho có — và mình đã biết, từ việc quan sát cách người ta xử lý permission prompt nói chung, rằng mệt mỏi vì phải duyệt liên tục (approval fatigue) là chuyện có thật, được đo đạc hẳn hoi, không phải giả thuyết. Một PR revert xuất hiện trông rất có thẩm quyền, kèm biểu đồ và một câu chuyện tự tin về commit nào gây ra regression, chính là thứ một kỹ sư on-call đang mệt lúc 3 giờ sáng sẽ duyệt mà không tự lần lại chuỗi nhân quả. Agent không loại con người ra khỏi vòng lặp. Nó chỉ đổi việc của con người từ “chẩn đoán regression” thành “tin vào một phân tích trông có vẻ hợp lý” — đó là một thay đổi thật sự về việc gì đang được kiểm chứng.

Đây mới là failure mode khiến mình lo thật sự: một false positive rơi đúng vào một sự cố có thật. Giả sử một regression thật xảy ra cùng lúc với một biến động metric vô hại, không liên quan — một batch job chạy theo lịch, một chiến dịch marketing đẩy traffic vào một khu vực cụ thể, bất cứ gì. Rollouts gán nhầm regression thật cho sai deploy, vì phát hiện regression dựa trên tương quan (correlation) sẽ làm vậy khi nhiễu đủ lớn. Nó mở một PR revert nhắm vào sai commit, đầy tự tin, kèm biểu đồ hẳn hoi. Giờ bạn có hai vấn đề: sự cố thật vẫn đang diễn ra, và một kỹ sư on-call bị kéo sự chú ý sang việc revert nhầm thứ, vì công cụ đưa cho họ một câu trả lời trông hợp lý thay vì một câu hỏi mở. Phát hiện regression tự động là tín hiệu triage tốt. Nó là một phán quyết cuối cùng tệ, và giao diện không nên để nó trông như một phán quyết cuối cùng.

Chính sách mình sẽ đặt quanh việc này

Nếu là mình triển khai hai con này cho team của mình, đây là ranh giới mình sẽ vẽ:

security_reviewer:
  pr_comment_only:
    - low
    - medium
  page_human_on_open:
    - high
    - critical
  auto_block_merge:
    - critical: hardcoded_secret
    - critical: auth_bypass
  # cái giá thật sự đắt ở đây là false negative trên một finding critical,
  # nên critical luôn cần người, kể cả khi bản sửa trông rất đơn giản

rollouts:
  auto_actions_allowed:
    - ping_pr_author
    - annotate_dashboard
  requires_human_approval:
    - pause_progressive_rollout   # rẻ để đảo ngược, nhưng vẫn ảnh hưởng traffic thật
    - open_revert_pr              # giữ đúng mặc định của Cursor
  never_auto_execute:
    - merge_revert_pr             # đây là dòng duy nhất bắt buộc luôn phải là con người
  confidence_threshold_to_notify: 0.7
  minimum_baseline_window: 30m    # đừng so với baseline ngắn hơn chu kỳ traffic nhiễu
                                   # định kỳ ồn ào nhất mà bạn từng biết
  concurrent_incident_check: true # nếu đã có incident đang mở, hạ xuống thành
                                   # "ghi chú vào kênh incident," không mở PR revert mới

Quy tắc duy nhất mình sẽ không nhân nhượng: PR revert được tạo tự động, nhưng không bao giờ tự merge, và không bao giờ merge trong lúc đang có một incident mở mà chưa có ai thật sự nhìn vào tương quan mà agent dùng để suy luận — không chỉ nhìn kết luận cuối. Nếu team bạn không đủ người để làm cái bước kiểm tra năm phút đó lúc 3 giờ sáng, đó là một lỗ hổng thật trong cách bạn vận hành on-call — công cụ này chỉ đang phơi bày nó ra, không phải tạo ra nó — và cách sửa là tăng độ phủ on-call, không phải hạ tiêu chuẩn để cho auto-merge.

Checklist thực tế nếu bạn định bật hai tính năng này trong quý này:

  • Đặt ngưỡng page người của Security Reviewer chỉ ở mức critical/high — mọi thứ khác nên dừng ở PR comment, nếu không bạn sẽ tự huấn luyện cả team lờ đi thông báo chỉ sau một tuần.
  • Bắt buộc một người cụ thể, có tên, phải bấm merge cho bất kỳ PR revert nào do Rollouts tạo ra. Không có ngoại lệ, không có kiểu “nếu confidence > 95% thì auto-merge” — đúng chỗ ngoại lệ đó là nơi kịch bản false-positive-trong-lúc-có-sự-cố-thật cắn bạn.
  • Kiểm tra xem Rollouts có biết phát hiện đã có một incident đang mở trước khi mở thêm cái thứ hai không. Nếu nó chưa làm được điều đó, ai đó trong team phải chịu trách nhiệm tự kiểm tra sự trùng lặp này trước khi duyệt bất kỳ revert nào nó đề xuất.
  • Đọc lại kế hoạch giám sát mà Rollouts soạn trước khi merge, đừng chấp nhận nó mặc định — đó là bước duy nhất Cursor để con người chỉnh tay, bỏ qua nó là phí luôn lý do nó tồn tại.
  • Theo dõi tỷ lệ false positive của cả hai agent trong tháng đầu tiên, giống cách bạn theo dõi tỷ lệ nhiễu của một rule cảnh báo mới. Nếu không ai để mắt tới con số đó, bạn sẽ không biết mình có vấn đề cho tới khi một PR revert sai được duyệt qua mà chẳng ai kiểm tra kỹ.
Xuất nội dung

Bình luận