·

Tiếng Việt: Hands-on: Run the full agentic QA workflow

Hands-on: Run the full agentic QA workflow

Bảy chủ đề trước của module này đã tách rời từng mảnh của agentic QA loop (vòng lặp kiểm thử có AI đóng vai trò tác nhân chủ động): test planning, sinh manual test case, sinh automated test, exploratory testing, context cho CI/CD agent, và feedback loop liên tục. Nhưng trong công việc thật, bạn không chạy từng mảnh riêng lẻ — bạn chạy cả một chuỗi, nối tiếp nhau, trên một feature cụ thể, với deadline cụ thể, và với một Pull Request đang chờ review. Chủ đề capstone (bài tổng kết) này sẽ mô phỏng đúng trải nghiệm đó: lấy một feature thực tế — "Password Reset with Email Verification" — và đi qua toàn bộ workflow từ setup context, generate test plan, sinh manual case, sinh automated test E2E/API, triage (phân loại và xác định nguyên nhân) lỗi, exploratory testing, đến coverage report (báo cáo mức độ phủ kiểm thử) cuối cùng để ra quyết định go/no-go (đi tiếp hay dừng release). Ở mỗi bước, bạn sẽ thấy prompt thật, output thật, và quan trọng nhất — điểm nào bạn phải dừng lại để review bằng con người trước khi đi tiếp.

Đây là bài lab dài nhất và chi tiết nhất của toàn khóa học. Mục tiêu không phải để bạn đọc lướt, mà để bạn có thể mở terminal, tạo một feature branch (nhánh Git riêng cho một feature) tương tự, và chạy lại đúng quy trình này trên project thật của mình ngay trong tuần này.

Làm Sao Setup Agentic Workflow — Spec, Diff Của Feature Branch, Và Codebase Context?

Trước khi gõ prompt đầu tiên, AI cần hai loại context hoàn toàn khác nhau: context "muốn gì" (spec — đặc tả nghiệp vụ, acceptance criteria) và context "đã làm gì" (diff — code thực tế đã thay đổi trên feature branch). Thiếu một trong hai, AI chỉ có thể đoán. Có spec mà không có diff, AI sinh test dựa trên giả định về implementation — dễ sai với code thật. Có diff mà không có spec, AI chỉ test được "code làm đúng như nó viết" mà không biết code có làm đúng cái business cần hay không. Đây gọi là dual-context setup (thiết lập song song hai nguồn context), và nó là nền tảng của toàn bộ workflow phía sau.

Feature Thực Hành: Password Reset with Email Verification

Feature chúng ta dùng cho toàn bộ bài lab, ticket AUTH-482, branch feature/AUTH-482-password-reset-email-verification.

User Story:

As a registered user who forgot their password,
I want to request a password reset via a link sent to my email,
So that I can regain access to my account without contacting support.

Acceptance Criteria:

AC1: Given a registered user submits their email on the "Forgot Password" screen,
     When the email matches an existing account,
     Then a reset link with a token is sent to that email, valid for 30 minutes.

AC2: Given an email that does NOT match any account is submitted,
     Then the system shows the same generic message
     ("If this email exists, a reset link has been sent.")
     to prevent account enumeration.

AC3: Given a user clicks a valid, unexpired reset link,
     Then they can set a new password that satisfies the existing password policy
     (min 8 characters, at least 1 uppercase letter, at least 1 number).

AC4: Given a user clicks an expired or already-used reset link,
     Then they see an explicit error and a CTA to request a new link.

AC5: Given a password reset completes successfully,
     Then all existing sessions/refresh tokens for that user are invalidated
     (force re-login on all devices).

AC6: Given a single email address,
     Then reset requests are rate-limited to 3 requests per hour per email,
     returning HTTP 429 beyond that limit.

Đây là một feature lý tưởng để thực hành vì nó có đủ mọi thứ khiến QA đau đầu: security-sensitive logic (chống account enumeration — dò xem một email có tồn tại trong hệ thống hay không qua sự khác biệt của response), business rule dễ bị code sai (rate limit, token expiry), side-effect ẩn (session invalidation), và một dependency ngoài (email delivery). Nói cách khác — thừa đủ "rủi ro" để agentic workflow chứng minh giá trị của nó.

Step 1: Xác Minh Environment Đã Sẵn Sàng

Trước khi bắt đầu, chạy một checklist môi trường nhanh — bỏ qua bước này là nguyên nhân phổ biến nhất khiến cả session agentic bị lãng phí giữa đường vì thiếu API key hoặc đứng nhầm branch.

claude --version

[ -n "$ANTHROPIC_API_KEY" ] && echo "API key is set" || echo "MISSING API KEY"

pwd
ls package.json go.mod pom.xml 2>/dev/null

git fetch origin
git checkout feature/AUTH-482-password-reset-email-verification
git diff main...HEAD --stat

Output của lệnh cuối phải cho thấy có file thay đổi thật — nếu diff trống, nghĩa là branch chưa có code, và toàn bộ agentic loop phía sau vô nghĩa (không có gì để test). Đây là lý do bước "confirm feature branch exists with code changes" luôn đứng trước bất kỳ prompt AI nào.

Step 2: Capture Toàn Bộ Context Artifact

Tạo một workspace riêng cho session QA này — đừng làm việc rải rác trong thư mục gốc, vì bạn sẽ cần tái sử dụng các artifact này ở mọi stage phía sau.

mkdir -p qa-sessions/AUTH-482-password-reset
cd qa-sessions/AUTH-482-password-reset

Capture spec — trong bài lab này spec đã viết sẵn ở trên, nhưng trong công việc thật bạn sẽ copy nguyên văn từ Jira/Confluence/Notion (không paraphrase, không tóm tắt — copy đúng để AI thấy đúng những gì Product Owner viết, kể cả câu chữ mơ hồ nếu có, vì đó cũng là tín hiệu review):

cat > spec.md << 'EOF'
[... paste User Story + Acceptance Criteria as above ...]
EOF

Capture diff — đây là nguồn "sự thật" về những gì thực sự đã code, không phải những gì spec nói sẽ code:

git diff main...HEAD > diff.patch
git diff main...HEAD --stat > diff-summary.txt
cat diff-summary.txt
 src/auth/reset-password.controller.ts     | 86 ++++++++++++++
 src/auth/reset-password.service.ts        | 134 +++++++++++++++++++
 src/auth/reset-token.repository.ts        | 41 +++++++
 src/email/templates/reset-password.hbs    | 22 ++++
 src/middleware/rate-limiter.ts            | 12 ++
 test/auth/reset-password.spec.ts          | 58 +++++++++
 6 files changed, 353 insertions(+)

Verify codebase context files — xác nhận các file context sống (CLAUDE.md, AGENTS.md, docs kiến trúc) mà bạn đã học ở chủ đề 6 vẫn tồn tại và up-to-date, vì đây là "bộ nhớ ngầm" giúp AI hiểu convention của project mà không cần bạn giải thích lại mỗi lần:

ls ../../CLAUDE.md ../../docs/ARCHITECTURE.md ../../docs/auth-flow.md 2>/dev/null
git log -1 --format="%ad" -- ../../CLAUDE.md

Verify test infrastructure exists — không có ý nghĩa gì khi yêu cầu AI sinh automated test nếu project chưa có test runner được cấu hình:

ls ../../tests/e2e ../../tests/api 2>/dev/null
cat ../../playwright.config.ts | grep -E "baseURL|testDir"
npm run test:api -- --list 2>/dev/null | head -5

Step 3: Validate Dual-Context Setup

Bước cuối trước khi bắt đầu vòng lặp thật: yêu cầu AI đọc cả hai artifact (spec.mddiff.patch) và tự báo cáo lại xem chúng có "nói cùng một chuyện" hay không. Đây chính là bước validate dual-context — không phải để sinh test, mà để bắt sớm những khoảng lệch giữa "muốn gì" và "đã làm gì" trước khi bạn tốn thời gian sinh cả bộ test dựa trên một hiểu lầm.

Prompt:

Read spec.md and diff.patch in this session workspace.

Task: Summarize, in your own words, what the specification requires
and what the code diff actually implements. Then explicitly list any
discrepancy between the two — anything the spec requires that the diff
does not appear to implement, and anything the diff implements that
is not mentioned in the spec.

Do not generate any tests yet. Only report alignment status.

Output thật trong session này đã lộ ra một khoảng lệch đáng chú ý:

Spec-vs-diff alignment report:

- AC1, AC2, AC3, AC4: fully implemented in reset-password.service.ts.
- AC5 (session invalidation): NOT found in diff. reset-password.service.ts
  updates the password hash but does not call any session/token revocation
  method. No changes to src/auth/session.service.ts in this diff.
- AC6 (rate limiting): implemented in middleware/rate-limiter.ts, but the
  limit is configured as 5 requests/hour, not 3 as specified in AC6.

Recommendation: confirm with the developer/PO before proceeding —
AC5 may be an implementation gap, and AC6 may be a spec/config mismatch.

Đây là giá trị thật của bước validate: bạn vừa phát hiện một acceptance criteria (AC5 — session invalidation) có thể chưa được code, và một mismatch số liệu (rate limit 5 vs 3) — tất cả trước khi viết một test case nào. Đưa hai điểm này lên Slack hỏi dev/PO ngay, đừng để agentic loop tiếp tục chạy trên một nền tảng đã biết có lỗ hổng.

Mẹo: Luôn lưu output của bước validate dual-context vào file riêng (alignment-report.md) trong session workspace — đến Stage 6 khi viết coverage report, bạn sẽ cần trích lại đúng câu này để giải thích lý do một AC bị đánh dấu "at risk" ngay từ đầu, thay vì phải nhớ lại từ đầu.

Làm Sao Thực Thi Từng Bước Của Agentic QA Loop Với Sự Hỗ Trợ Của AI?

Với context đã được capture và validate, giờ là lúc chạy chuỗi 6 stage nối tiếp — mỗi stage nhận input là output đã qua review của con người ở stage trước, không phải output thô. Đây là nguyên tắc controlled chaining (chaining có kiểm soát): tự động hoá việc sinh nội dung, nhưng không tự động hoá việc quyết định nội dung đó có đúng hay không.

Stage 1: Generate Test Plan

Prompt, đưa kèm spec.md, diff.patch, và alignment-report.md:

You are a senior QA engineer creating a test plan for AUTH-482
(Password Reset with Email Verification).

Context attached: spec.md, diff.patch, alignment-report.md

Generate a test plan with these sections:
1. Spec-Implementation Alignment Check (reuse alignment-report.md, flag any
   AC that is at risk)
2. Risk Assessment (rank by likelihood x impact; call out security-sensitive
   logic explicitly)
3. Test Scope (in-scope / out-of-scope)
4. Test Scenarios (Risk-Ordered) — group by AC, highest risk first
5. Coverage Goals (what % / which layers must be covered before ship)
6. Entry and Exit Criteria
7. Automation Decision (which scenarios should be automated vs manual-only,
   and why)
8. Estimated Effort (rough hours, split manual vs automation)

Trích đoạn output thật (đã rút gọn để dễ đọc):


## 1. Spec-Implementation Alignment Check
- AC5 (session invalidation) NOT implemented in current diff — flagged HIGH RISK,
  must be re-verified before test execution; treat as a defect candidate, not
  just a test gap.
- AC6 rate limit configured as 5/hour vs spec's 3/hour — flagged for
  clarification; test scenarios will cover BOTH values until resolved.

## 2. Risk Assessment
| Risk | Likelihood | Impact | Priority |
|---|---|---|---|
| Account enumeration via error message difference | Medium | High | P0 |
| Session not invalidated after reset (AC5 gap) | High (known gap) | High | P0 |
| Token reused after first successful reset | Low | High | P0 |
| Rate limit bypass via case-varied email | Medium | Medium | P1 |
| Reset email delayed/undelivered (3rd-party dependency) | Medium | Medium | P1 |
| Password policy not enforced on reset form | Low | Medium | P2 |

## 3. Test Scope
In-scope: reset request flow, token validation, password update, rate
limiting, session invalidation, email content/link correctness.
Out-of-scope: email deliverability infrastructure (SES/SendGrid uptime),
load testing beyond rate-limit thresholds.

## 4. Test Scenarios (Risk-Ordered)
[P0] TS-01: Reset with non-existent email returns identical generic message
     as existing email (anti-enumeration)
[P0] TS-02: All sessions invalidated after successful reset
[P0] TS-03: Reset token cannot be reused after first successful reset
[P0] TS-04: Expired token (>30 min) is rejected with explicit error
...

## 7. Automation Decision
Automate: TS-01 through TS-06 (deterministic, no manual timing needed) as
API tests; TS-07/TS-08 (full UI flow) as E2E.
Manual-only: email client rendering across providers (Gmail/Outlook clipping),
exploratory abuse scenarios.

## 8. Estimated Effort
Manual case writing: 2h. API automation: 3h. E2E automation: 2h.
Exploratory session: 1.5h. Total: ~8.5h.

Điểm đáng chú ý trong test plan này: AI không chỉ liệt kê lại 6 acceptance criteria thành test scenario, mà tự nâng "session not invalidated" (gap đã phát hiện ở Step 3) lên P0 ngay trong bảng risk assessment, và giữ nguyên cách xử lý "test cả 2 giá trị 3 và 5" cho rate limit — đúng như alignment-report.md đã cảnh báo. Đây là bằng chứng cụ thể cho việc chain context (đưa alignment-report.md vào cùng prompt) thực sự lan truyền được sang stage kế tiếp, không bị rơi mất giữa đường.

Stage 2: Generate Manual Test Case

Sau khi test plan được review (xem Review Gate 1 ở phần sau) và được approve, chain trực tiếp từ chính test plan đó — không viết prompt mới từ đầu, để AI giữ nguyên đúng thứ tự ưu tiên theo risk đã thống nhất:

Using the approved test plan above (test-plan.md), generate detailed
manual test cases for all P0 and P1 scenarios. Each test case must include:
Test Case ID, Title, Preconditions, Steps, Test Data, Expected Result,
and Priority. Group by scenario ID (TS-01, TS-02, ...).

Format as a markdown table suitable for import into TestRail/Xray.

Ví dụ một case được sinh cho TS-02 (session invalidation — đúng AC đang có gap):

| TC ID | Title | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| TC-482-07 | Session invalidated after password reset | User logged in on 2 devices (Device A, Device B) | 1. On Device A, trigger forgot-password flow and complete reset with new password 2. Attempt any authenticated API call from Device B using its existing session token | Device B's request returns 401 Unauthorized; user must re-login on all devices | P0 |

Chú ý cách AI viết Steps đủ cụ thể (tên thiết bị, hành động theo thứ tự, điều kiện) để một tester khác — không phải người viết prompt — có thể chạy đúng case này mà không cần hỏi lại. Đây chính là tiêu chí quan trọng nhất khi review Gate 2 ở phần sau: test data và bước thực hiện phải cụ thể, không mơ hồ.

Stage 3: Generate Automated Test

Bốn việc trong stage này, chạy theo thứ tự: sinh test E2E, sinh test API, chạy smoke check cho E2E, chạy smoke check cho API. Smoke check ở đây nghĩa là chạy test ngay sau khi sinh — không chờ đến CI — để bắt lỗi rõ ràng nhất (sai selector, sai cú pháp, import lỗi) ngay tại chỗ.

Sinh E2E test (Playwright), chain từ manual case đã approve:

Generate Playwright E2E tests (TypeScript) for TC-482-01 through TC-482-06
from the approved manual test cases. Use getByTestId selectors only. Assert
both UI state and the underlying API response (page.waitForResponse). Place
in tests/e2e/auth/reset-password.spec.ts.

Sinh API test (ví dụ dùng Supertest/Postman-style), tập trung vào các case không cần UI như rate limit và token reuse:

Generate API-level tests (Supertest, TypeScript) covering:
- TS-03: reset token rejected after first successful use
- TS-04: reset token rejected after 30-minute expiry (mock system clock)
- TS-05: 4th reset request within 1 hour for same email returns 429
Place in tests/api/auth/reset-password.api.spec.ts. Do not hit the real
email provider — assume an EmailService mock/spy is available at
test/mocks/email.mock.ts.

E2E smoke check — chạy ngay sau khi sinh, KHÔNG chờ đến CI, để bắt lỗi cú pháp/selector sai sớm nhất có thể:

npx playwright test tests/e2e/auth/reset-password.spec.ts --headed --repeat-each=2

API smoke check — tương tự cho lớp API:

npm run test:api -- tests/api/auth/reset-password.api.spec.ts

Chạy --repeat-each=2 ở bước smoke E2E không phải ngẫu nhiên — đây là cách rẻ nhất để bắt được flaky test do AI sinh ra ngay tại chỗ, trước khi nó lọt vào CI và gây nhiễu cho cả team.

Stage 4: Triage Failure

Sau khi chạy full suite (bao gồm cả các test cũ đã có sẵn trong repo, không chỉ test mới sinh), một số test fail. Bước đầu tiên: capture toàn bộ failure vào một file duy nhất, không xử lý thủ công từng cái.

npm run test:e2e -- --reporter=json > results-e2e.json
npm run test:api -- --reporter=json > results-api.json

Prompt triage:

Analyze results-e2e.json and results-api.json. For each failing test:
1. Classify as: PRODUCT BUG / TEST BUG (bad selector, bad assertion,
   outdated expectation) / FLAKY (env/timing) / ENVIRONMENT ISSUE
   (infra/config, not code)
2. Give a one-line root-cause hypothesis with the specific evidence
   (error message, stack line) that supports it
3. Suggest the next action: file a bug / fix the test / rerun / ignore

Output as a table sorted by classification, PRODUCT BUG first.

Trích output thật:

| Test | Classification | Root Cause Hypothesis | Next Action |
|---|---|---|---|
| TC-482-07 (session invalidation) | PRODUCT BUG | Device B request still returns 200; reset-password.service.ts never calls session.revokeAllForUser() — matches AC5 gap flagged in alignment-report.md | File bug, block release |
| TS-05 (rate limit 429) | PRODUCT BUG (spec mismatch) | Limiter allows 5 requests, spec says 3; not a code defect per se but a spec/impl conflict | Escalate to PO for decision, then fix test OR fix code |
| reset-password.spec.ts > "shows error on invalid token" | TEST BUG | Assertion expects text "Invalid or expired link" but UI shows "Link is invalid or expired" — copy changed, test not updated | Fix assertion |
| checkout.spec.ts (pre-existing, unrelated) | FLAKY | waitForTimeout(2000) followed by click; intermittent timing, unrelated to AUTH-482 diff | Rerun; separate flaky-test ticket |

Đây chính xác là giá trị AI mang lại ở stage này: nó không chỉ báo "fail", nó nối failure với evidence cụ thể và với context đã biết trước (alignment-report.md), giúp bạn không phải đọc lại từ đầu để nhớ AC5 từng bị flag.

Stage 5: Exploratory Testing

Dùng chính kết quả automated test + triage ở trên làm input để sinh charter khám phá — không sinh charter chung chung, mà nhắm vào đúng vùng vừa lộ ra rủi ro:

Based on the triage results above (session invalidation bug confirmed,
rate-limit spec mismatch, and the overall risk assessment in test-plan.md),
generate 4 exploratory testing charters for AUTH-482. Each charter needs:
Mission, Areas to explore, Time-box, and Specific hypotheses to try to break.
Prioritize charters that probe adjacent risk the automated suite likely
did NOT cover.

Một charter tiêu biểu được sinh ra, nhắm đúng vào một góc automated test chưa chạm tới:

Charter 3: Session Invalidation Edge Cases
Mission: Explore whether the (still-buggy) session invalidation logic has
partial fixes that create inconsistent behavior across session types.
Areas: mobile app refresh token, "remember me" persistent cookie, active
WebSocket connection during reset.
Time-box: 30 minutes.
Hypotheses to try:
- Does a WebSocket connection opened before reset stay alive after reset?
- Does "remember me" cookie survive reset even if access token doesn't?

Chú ý Charter 3 không lặp lại phạm vi automated test đã chạy (vốn chỉ test session revocation ở tầng API) mà đào sâu vào các loại session khác nhau — mobile refresh token, cookie "remember me", WebSocket đang mở — đúng tinh thần "nhắm vào vùng automated suite chưa cover" mà prompt đã yêu cầu. Đây là cách AI biến kết quả triage thành hành động điều tra tiếp theo, thay vì để charter khám phá trôi nổi không gắn với rủi ro thật đang mở.

Stage 6: Generate Coverage Report

Input cuối cùng gộp toàn bộ: test plan đã approve, kết quả automated test, triage table, và note từ exploratory session.

Generate a final coverage report for AUTH-482 to support a ship/no-ship
decision. Include: AC-by-AC coverage status (covered/not covered/blocked),
open defects with severity, residual risk after this test cycle, and an
explicit go/no-go recommendation with justification.

Trích đoạn:


## AC Coverage
| AC | Status | Evidence |
|---|---|---|
| AC1-AC4 | COVERED | Automated E2E/API pass, manual verified |
| AC5 (session invalidation) | BLOCKED — DEFECT | TC-482-07 confirms bug; not fixed as of this report |
| AC6 (rate limit) | AT RISK | Spec/impl mismatch (3 vs 5) unresolved with PO |

## Open Defects
- BUG-1231 (Critical): sessions not invalidated after password reset. Blocks release.
- Spec clarification needed: rate limit threshold (3 vs 5/hour).

## Recommendation: NO-GO
Rationale: AC5 is a security-relevant defect (stale sessions after a
security-sensitive action) with confirmed evidence. Recommend blocking
release until BUG-1231 is fixed and TC-482-07 passes on rerun.

Coverage report này chính là artifact cuối cùng đưa lên bàn review ở Gate 5 — không phải để thay thế quyết định của con người, mà để đảm bảo người ký quyết định có đủ evidence cụ thể (AC nào covered, defect nào đang mở, mức độ rủi ro còn lại) gói trong một trang duy nhất, thay vì phải tự đi lục lại từng kết quả rời rạc từ 5 stage trước.

Mẹo: Ở mọi stage trong vòng lặp 6 bước này, đừng cho AI chạy stage kế tiếp bằng cách dán lại toàn bộ output cũ vào một prompt mới trong một chat mới — hãy giữ nguyên một session/thread liên tục (hoặc trỏ rõ đường dẫn file) từ Stage 1 đến Stage 6. Khi context bị "khởi động lại" giữa các stage, AI dễ quên các gap đã flag từ đầu (như AC5) và bạn sẽ phải tự nhắc lại thủ công — mất đúng cái lợi thế mà bạn build workflow này để có.

Làm Sao Review Output Ở Mỗi Stage Và Ra Quyết Định Go/No-Go?

Agentic QA loop không phải là "để AI làm hết rồi merge" — nó là chuỗi các bước sinh nội dung xen giữa các review gate (điểm chốt bắt buộc phải có con người review trước khi được đi tiếp). Mỗi gate có một câu hỏi quyết định riêng, và một checklist riêng để trả lời câu hỏi đó nhanh mà không bỏ sót.

Review Gate 1: Phê Duyệt Test Plan

Câu hỏi quyết định: "Test plan này có phản ánh đúng rủi ro thật của feature, và có đủ để làm căn cứ cho mọi stage phía sau không?"

Checklist:

[ ] Alignment check đã nêu rõ mọi gap phát hiện ở Step 3 (không bị bỏ sót)?
[ ] Risk ranking có hợp lý với domain (security-sensitive logic phải luôn
    ở P0, không được AI đánh thấp vì "trông đơn giản")?
[ ] Test scope loại trừ đúng những gì thật sự ngoài phạm vi (không loại trừ
    nhầm phần rủi ro)?
[ ] Automation decision có khả thi với hạ tầng CI hiện tại (không đề xuất
    tool/framework project chưa có)?
[ ] Effort estimate có thực tế so với deadline sprint?

Quyết định trong bài lab này: APPROVE với 1 điều kiện — thêm rõ TS-05 phải test cả 2 giá trị (3 và 5) cho đến khi PO chốt số đúng.

Review Gate 2: Chất Lượng Test Được Sinh Ra

Câu hỏi quyết định: "Test được sinh ra — manual case và automated script — có đáng tin để chạy làm căn cứ quyết định release, hay chỉ là code 'trông sạch'?"

Checklist (áp dụng cho cả manual case và automated script):

[ ] Test data có cụ thể, không có placeholder mơ hồ ("some valid email")?
[ ] Automated test không dùng waitForTimeout() cố định?
[ ] Assertion kiểm cả network/API, không chỉ UI hiển thị?
[ ] Selector dùng data-testid/role, không dùng CSS class/nth-child?
[ ] Test độc lập — không phụ thuộc thứ tự chạy hoặc data từ test khác?
[ ] Chạy smoke với --repeat-each >=2 không có flaky?

Trong bài lab, checkout.spec.ts bị phát hiện dùng waitForTimeout(2000) — không thuộc scope AUTH-482 nhưng vẫn được note vào backlog vì chặn kết quả smoke chung.

Review Gate 3: Phân Loại Triage

Câu hỏi quyết định: "AI đã phân loại đúng PRODUCT BUG vs TEST BUG vs FLAKY chưa, và root-cause hypothesis có đủ evidence để tin không?"

Checklist:

[ ] Mỗi PRODUCT BUG có trace được cụ thể tới dòng code/log, không chỉ suy
    diễn chung?
[ ] Case nào AI gắn "FLAKY" có thực sự không liên quan đến diff hiện tại
    (không phải AI né trách nhiệm bug thật bằng cách gọi nó là flaky)?
[ ] TEST BUG được đề xuất fix có đúng theo spec mới nhất, không fix để
    "test pass" mà sai với business logic?

Trong bài lab, dòng "TEST BUG — copy thay đổi" được double-check lại với changelog UI để chắc chắn AI không tự bịa lý do.

Review Gate 4: Ưu Tiên Exploratory Charter

Câu hỏi quyết định: "Trong số charter được sinh ra, cái nào đáng đầu tư 30-60 phút thời gian tester thật, và cái nào bỏ qua?"

Checklist:

[ ] Charter có nhắm vào vùng automated suite chưa cover, hay lặp lại việc
    automated test đã làm?
[ ] Charter có phù hợp với risk cao nhất đang mở (ví dụ: session
    invalidation) thay vì risk đã đóng?
[ ] Time-box có thực tế với deadline hiện tại của sprint?

Quyết định: ưu tiên Charter 3 (session invalidation edge case) vì bug AC5 đang mở, hạ charter về "email rendering across providers" xuống mức optional vì rủi ro thấp hơn nhiều so với effort.

Review Gate 5: Coverage Report Và Quyết Định Ship

Câu hỏi quyết định cuối cùng, cũng là quan trọng nhất: "Dựa trên toàn bộ evidence, feature này go hay no-go?"

Checklist:

[ ] Mọi AC P0 có status rõ ràng (COVERED / BLOCKED / AT RISK), không có
    ô nào bị bỏ trống?
[ ] Recommendation của AI có nhất quán với severity của defect đang mở?
[ ] Người ra quyết định cuối (Lead QA/Eng Manager) đã đọc rationale, không
    chỉ đọc dòng "GO/NO-GO"?

Quyết định trong bài lab: giữ nguyên NO-GO như AI đề xuất — nhưng quyết định này được QA Lead ký tên, không phải AI. AI cung cấp evidence và khuyến nghị; con người chịu trách nhiệm cho quyết định release.

Mẹo: Đừng để 5 review gate biến thành 5 lần đọc lại toàn bộ output từ đầu — hãy thiết kế mỗi checklist chỉ trả lời ĐÚNG MỘT câu hỏi quyết định của gate đó. Một gate cố trả lời quá nhiều câu hỏi cùng lúc (ví dụ Gate 2 mà lẫn cả câu hỏi go/no-go của Gate 5) sẽ khiến review chậm lại và dễ bỏ sót đúng thứ gate đó cần bắt.

Agentic Workflow Tự Động Bắt Được Gì, Và Cái Gì Vẫn Cần Đánh Giá Của Con Người?

Sau khi chạy hết vòng lặp trên AUTH-482, đây là lúc lùi lại và tổng kết ranh giới thật giữa "AI làm được" và "con người phải làm" — không phải lý thuyết, mà đúc từ chính những gì vừa xảy ra ở bài lab trên.

Những Gì Agentic Workflow Tự Động Bắt Được

  • Khoảng lệch spec-implementation rõ ràng — như AC5 (session invalidation) bị thiếu hoàn toàn trong diff. Đây là pattern-matching giữa hai văn bản, việc AI làm nhanh và triệt để hơn con người đọc lướt.
  • Test case lặp đi lặp lại theo cấu trúc đã biết — CRUD, validation, permutation của input hợp lệ/không hợp lệ, boundary value cho password policy.
  • Selector/assertion pattern chuẩn cho automated test khi đã có convention rõ (data-testid, response assertion).
  • Phân loại failure hàng loạt theo pattern lỗi đã thấy nhiều lần (timeout pattern = flaky, assertion text mismatch = test bug lỗi thời).
  • Tổng hợp và trình bày — biến hàng chục kết quả rời rạc thành một coverage report có cấu trúc, tiết kiệm hàng giờ soạn tài liệu thủ công.

Những Gì Vẫn Cần Đánh Giá Của Con Người

  • Đánh giá mức độ nghiêm trọng thật của một gap — AI phát hiện AC5 thiếu, nhưng việc quyết định "đây là blocker hay chấp nhận được với workaround tạm" là quyết định nghiệp vụ + rủi ro pháp lý/bảo mật, không phải suy luận từ text.
  • Giải quyết mâu thuẫn spec — mismatch 3 vs 5 request/hour ở AC6 cần một cuộc trao đổi thật với PO, AI chỉ nêu ra chứ không tự quyết được số nào đúng.
  • Đánh giá charter exploratory nào đáng đầu tư thời gian con người — đây là ưu tiên hoá dựa trên ngân sách thời gian thực và cảm nhận rủi ro nghiệp vụ, thứ AI không có quyền tự quyết.
  • Quyết định go/no-go cuối cùng và chịu trách nhiệm — AI đưa ra recommendation có lý lẽ, nhưng ký tên chấp nhận rủi ro release luôn phải là một con người có vai trò đó.
  • Đánh giá "test có thực sự đo đúng risk nghiệp vụ" hay chỉ "trông đủ" — một test suite pass 100% vẫn có thể bỏ sót đúng cái người dùng sẽ gặp thật, và chỉ kinh nghiệm domain của QA Engineer mới cảm nhận được lỗ hổng dạng này.

Operating Model Tổng Kết

Mô hình vận hành rút ra từ toàn bộ bài lab này có thể tóm gọn thành một nguyên tắc duy nhất: AI làm generate, human làm decide — và mọi ranh giới giữa generate/decide phải được đánh dấu rõ bằng một review gate cụ thể, không để ngầm hiểu. Cụ thể hoá thành quy trình lặp lại được cho mọi feature khác:

1. Capture dual-context (spec + diff) → Validate alignment → [GATE: fix gap trước khi tiếp]
2. Generate Test Plan → [GATE 1: approve risk ranking & scope]
3. Generate Manual Cases (chain từ plan đã approve) → [GATE 2: chất lượng]
4. Generate Automated Tests + smoke check → [GATE 2: chất lượng]
5. Run full suite → Capture results → AI Triage → [GATE 3: đúng phân loại]
6. Generate Exploratory Charters (từ triage) → [GATE 4: ưu tiên đúng]
7. Generate Coverage Report → [GATE 5: go/no-go — người ký tên]

Bảy stage này chính là agentic QA loop đầy đủ mà cả module 8 đã xây dựng, giờ được chứng minh chạy được trên một feature security-sensitive thật, với một bug thật (AC5) được phát hiện đủ sớm để chặn một release có lỗ hổng nghiêm trọng. Đó là bằng chứng thực tế nhất cho giá trị của agentic workflow — không phải vì nó nhanh hơn, mà vì nó buộc bạn capture, validate, và review có hệ thống ở từng bước, thay vì để một khâu nào đó trôi qua trong im lặng.

Mẹo: Sau khi hoàn tất một vòng agentic QA loop đầy đủ như trong bài lab này, hãy lưu lại toàn bộ session workspace (spec.md, diff.patch, alignment-report.md, test-plan.md, kết quả triage, coverage report) làm "case mẫu" tham khảo cho feature tiếp theo cùng domain (ví dụ mọi flow liên quan authentication). Việc có sẵn một bộ artifact tham chiếu chất lượng cao giúp prompt ở những lần sau ngắn hơn, và giúp AI "học" đúng chuẩn output team bạn kỳ vọng nhanh hơn nhiều so với giải thích lại bằng lời mỗi lần.