## [BA] 4-Gate Spec Creation Workflow

> **For:** `create-spec`
> **Persona:** Business Analyst (BA)
> **Goal:** Chuyển đổi yêu cầu thô (Jira / Backlog / file) thành tài liệu Đặc tả Use Case (UC Spec) hoàn chỉnh để bàn giao Dev/Test, tuân theo quy trình UCflow.
> **Interaction Rules:** Hỏi ONE câu hỏi tại một thời điểm — đợi BA trả lời trước khi tiếp tục. KHÔNG hỏi nhiều câu cùng lúc. Số lượng câu hỏi KHÔNG cố định — phải phản ánh đúng độ phức tạp thực tế của yêu cầu (xem chi tiết ở Gate 1 Bước 2).

---

### Quy ước Blocking / Non-blocking & đánh dấu PENDING

> Áp dụng cho **cả 4 Gate** — dùng để quyết định câu hỏi nào bắt buộc phải Confirmed trước khi tiến gate tiếp theo, và câu nào được phép defer mà vẫn cho qua.

Mỗi Gap/Assumption/câu hỏi Q&A phải được gắn nhãn mức độ ảnh hưởng ngay khi phát hiện:

- **🔴 Blocking** — chưa trả lời thì KHÔNG thể tiến gate tiếp theo một cách đáng tin cậy. Gồm: ảnh hưởng cấu trúc dữ liệu (thêm/sửa field, quan hệ), luồng chính (happy path) của use case, phân quyền/bảo mật, hoặc quyết định kiến trúc khó đảo ngược sau khi đã code.
- **🟡 Non-blocking** — có thể tạm ghi Open (deferred) và vẫn đi tiếp. Gồm: chi tiết UI/text hiển thị, giá trị mặc định có thể chỉnh sau, alternative/exception flow hiếm gặp, câu hỏi cần chờ khách hàng xác nhận nhưng không chặn thiết kế các phần khác.

**Khi BA/khách hàng defer (chưa trả lời ngay) một câu hỏi:**

- 🟡 Non-blocking → đánh dấu **Open**, tiếp tục ngay sang câu hỏi kế tiếp hoặc gate kế tiếp — KHÔNG chặn.
- 🔴 Blocking → AI phải hiển thị cảnh báo rõ lý do đây là blocking + hệ quả nếu bỏ qua, rồi hỏi xác nhận BA có chắc muốn tiếp tục không. Nếu BA xác nhận đồng ý tiếp tục dù chưa trả lời → vẫn đánh dấu Open nhưng giữ nhãn 🔴 Blocking (không được hạ xuống Non-blocking) — mục "Điều kiện dừng chặn APPROVED" ở mỗi Gate dựa vào nhãn này.

**Đánh dấu PENDING trong tài liệu output:** bất kỳ nội dung nào phụ thuộc vào một câu hỏi còn Open (Blocking hoặc Non-blocking) phải ghi rõ marker tại đúng vị trí liên quan trong `Analysis_v(n).md` / `UI-Prototype` / `UC-Spec_v{N}.md`, thay vì tự suy diễn nội dung để lấp đầy:

```
⚠️ [PENDING - QA-0N] <mô tả ngắn nội dung còn thiếu>
```

---

### Pre-flight BẮT BUỘC — Đồng bộ Source & Docs (đầu MỖI Gate)

> Áp dụng cho **cả 4 Gate** bên dưới — không chỉ Gate 1. Chạy đủ các bước sau **trước khi** thực hiện bất kỳ hành động nào khác của gate đó.

1. **Sync repo source (bên trong, không phải AK-Docs/Shared-Docs):** xác định thư mục repo source liên quan (field `repo` trong context, hoặc repo duy nhất mở trong workspace) → `cd` vào đó → chạy `git status --porcelain`; nếu working tree sạch, chạy `git pull --ff-only`. Nếu có thay đổi chưa commit, branch diverged, hoặc không có remote tracking branch → bỏ qua pull (không phải lỗi).
2. **Sync `AK-Docs/`:** `cd` vào `AK-Docs/` (sibling folder ở workspace root) → chạy `git pull`.
3. **Sync `Shared-Docs/`:** `cd` vào `Shared-Docs/` (sibling folder ở workspace root) → chạy `git pull`.
4. Sau khi xong, `cd` quay lại thư mục làm việc ban đầu trước khi tiếp tục các bước khác của gate.

Nếu `AK-Docs/` hoặc `Shared-Docs/` chưa tồn tại tại workspace root, hoặc không phải git repo → bỏ qua bước tương ứng, không cảnh báo.

**Nếu bất kỳ lệnh `git pull` nào ở Bước 1–3 thất bại** → **KHÔNG dừng workflow** — hiển thị cảnh báo và tiếp tục gate với dữ liệu local hiện có:

```
⚠️ CẢNH BÁO: Không thể pull [tên repo] — [lý do lỗi].
→ Đang tiếp tục Gate [N] với dữ liệu local hiện tại, có thể chưa mới nhất.
```

---

### BA Skills

Các skill sau đây được cài tự động vào `.claude/skills/ba-skills/` khi chạy `ak init` hoặc `ak up`.

| Skill | File |
|---|---|
| `skill-ba-phan-tich-ban-dau` | `.claude/skills/ba-skills/skill-ba-initial-analysis-v1.md` |
| `skill-ba-qa` | `.claude/skills/ba-skills/skill-ba-qna-v1.md` |
| `skill-ba-prototype` | `.claude/skills/ba-skills/skill-ba-ui-prototype-v1.md` |
| `skill-ba-ve-luong-mermaid` | `.claude/skills/ba-skills/skill-ba-mermaid-flowchart-v1.md` |
| `skill-ba-xay-dung-business-rules` | `.claude/skills/ba-skills/skill-ba-build-business-rules-v1.md` |
| `skill-ba-viet-spec-uc` | `.claude/skills/ba-skills/skill-ba-write-uc-spec-v1.md` |
| `template-phan-tich-ban-dau` | `.claude/skills/ba-skills/skill-ba-initial-analysis-template-v1.md` |
| `template-qa` | `.claude/skills/ba-skills/skill-ba-qna-template-v1.md` |
| `template-uc` | `.claude/skills/ba-skills/skill-ba-uc-template-v1.md` |

---

### Cấu trúc thư mục đầu ra

```
02.BA-Specs/
├── 01.Analysis/
│   ├── [functionId]/Analysis_v1.md      ← Gate 1 tạo
│   └── [functionId]/Analysis_vn.md      ← Gate 2 cập nhật (tăng version)
├── 02.QnA/
│   ├── [functionId]/QnA-Log_v1.md       ← Gate 1 tạo
│   └── [functionId]/QnA-Log_vm.md       ← Gate 2 tạo thêm nếu còn Open
├── 03.UI-Prototypes/
│   └── [functionId]/UI-Prototype_v1.html← Gate 3 tạo
└── 04.UC-Specs/
    └── [functionId]/UC-Spec_v{N}.md       ← Gate 4 tạo (N=1 nếu CREATE, N=version mới nếu UPDATE)
```

Ví dụ: `functionId = AD10` → thư mục gốc là `02.BA-Specs/`

---

### Quy trình tổng quan 4 Gates

```
(BA-Specs/ = 02.BA-Specs/ — viết tắt cho ngắn gọn)

[Input: Jira / Backlog / file] → Pre-flight: BẮT BUỘC xác định functionId
    ↓
Gate 1: Phân tích yêu cầu & Tạo Q&A       → BA-Specs/01.Analysis/ + BA-Specs/02.QnA/
    ↓ APPROVED
Gate 2: Cập nhật phản hồi Q&A ←─────────────────────────────────────────┐
    ↓ còn Open → tạo QnA-Log_v(m+1) → đợi BA phản hồi → lặp lại ────────┘
    ↓ tất cả Confirmed + APPROVED
Gate 3: Thiết kế UI Prototype HTML/CSS     → BA-Specs/03.UI-Prototypes/
    ↓ APPROVED
Gate 4: Viết đặc tả Use Case Spec          → BA-Specs/04.UC-Specs/
    ↓ APPROVED
Bàn giao Dev/Test
```

---

### GATE 1 — Phân tích yêu cầu ban đầu & Tạo Q&A (auto-start)

**Mục tiêu:** Tiếp nhận đầu vào, hiểu nghiệp vụ, phát hiện khoảng trống (Gaps), lập bản phân tích sơ bộ và danh sách Q&A.

**Đầu ra (Outputs):**
- `02.BA-Specs/01.Analysis/[functionId]/Analysis_v1.md`
- `02.BA-Specs/02.QnA/[functionId]/QnA-Log_v1.md`

**Bước thực hiện:**

**Pre-flight (bắt buộc, chạy trước Bước 0):** chạy [Pre-flight — Đồng bộ Source & Docs](#pre-flight-bắt-buộc--đồng-bộ-source--docs-đầu-mỗi-gate) ở đầu file. Lỗi → hiển thị ⚠️ cảnh báo, không dừng gate.

#### Bước 0: Pre-flight — Xác định functionId và thư mục đầu ra

**Xác định `functionId` (BẮT BUỘC):**

Kiểm tra theo thứ tự ưu tiên:
1. Trường `functionId` hoặc `screenId` trong `.aiflow/context/current.json`
2. Rút gọn từ `ticketId` — bỏ dấu gạch, giữ ký hiệu (ví dụ: `AD-10` → `AD10`)
3. Nếu không tìm thấy → **BẮT BUỘC hỏi BA ngay**:

```
Không tìm thấy functionId trong context.
Vui lòng cung cấp mã định danh cho chức năng này (ví dụ: AD10, UC-LOGIN, PM-003):
```

→ Đợi BA trả lời, ghi nhận giá trị, dùng cho toàn bộ workflow. KHÔNG ĐƯỢC TIẾP TỤC NẾU CHƯA CÓ functionId.

**Xác định Mode (CREATE / UPDATE) — BẮT BUỘC, chạy ngay sau khi có `functionId`:**

> Đây là cơ chế trả lời Vấn đề A ở `docs/internal/Token Problems.md` (§2.1/§3.1) — trước bản này, mọi lần chạy `create-spec` đều mặc định CREATE (`_v1`), kể cả khi UC Spec cho `functionId` đó đã tồn tại và được PM merge — khiến BA phải điều tra/hỏi lại từ đầu mỗi khi cần sửa 1 UC Spec đã duyệt.

1. Tìm `04.UC-Specs/[functionId]/UC-Spec_v{N_prev}.md` (version cao nhất, không phải bản archive) — gọi version tìm được là `N_prev`.
2. **Không tìm thấy** → Mode = **CREATE**. Version output của toàn bộ Gate 1–4 (`N`, dùng xuyên suốt các bước bên dưới và trong `UC-Spec_v{N}.md`) = `1` (hành vi giữ nguyên như trước — không đổi gì với BA đang tạo UC Spec lần đầu).
3. **Tìm thấy, đã PM merge (`UC-Spec_v{N_prev}.md` tồn tại trong `main` — không phải bản đang ở branch task khác)** → Mode = **UPDATE**. Version output `N = N_prev + 1`. Đọc `UC-Spec_v{N_prev}.md` và `Analysis_v(n).md` (bản mới nhất trong `01.Analysis/[functionId]/`) làm baseline — dùng ở Bước 1/1b/2 bên dưới.
4. **Tìm thấy nhưng chưa PM merge** (task trước của cùng `functionId` đang dở, chưa qua Gate 4 hoặc chưa submit MR) → hỏi BA: "`functionId` này đang có UC Spec v{N_prev} chưa merge (task [taskId cũ nếu biết]) — bạn muốn tiếp tục task đó (resume) hay đây là task/thay đổi mới sau khi task đó merge xong (chờ)?" Không tự đoán.

⚠️ **Chưa "triệt để" 100%** (xem `docs/internal/Token Problems.md` §4): Mode UPDATE đặt cược vào việc input mới mô tả đúng phạm vi thay đổi — Bước 2 bên dưới có 1 bước bắt buộc "quét side-effect" để giảm rủi ro bỏ sót, nhưng không loại bỏ hoàn toàn. Nếu BA nghi ngờ thay đổi lần này lớn tới mức ảnh hưởng gần như toàn bộ UC (đổi luồng chính, đổi actor, đổi mô hình dữ liệu cốt lõi) → cân nhắc chạy Mode CREATE thủ công (bỏ qua Mode UPDATE, coi như viết lại UC Spec từ đầu) thay vì ép vào UPDATE.

**Xác định thư mục đầu ra:**

1. Kiểm tra tồn tại thư mục `02.BA-Specs/` trong root dự án:
   - **Tìm thấy** → thông báo xác nhận:
     ```
     ✓ Thư mục đầu ra: 02.BA-Specs/
     ✓ functionId: [functionId]
     ✓ Mode: [CREATE | UPDATE] (version mới: v{N})
     → Bắt đầu Gate 1...
     ```
   - **Không tìm thấy** → tạo toàn bộ cây thư mục:
     ```
     02.BA-Specs/01.Analysis/
     02.BA-Specs/02.QnA/
     02.BA-Specs/03.UI-Prototypes/
     02.BA-Specs/04.UC-Specs/
     ```
     → Thông báo:
     ```
     ✓ Đã tạo thư mục: 02.BA-Specs/
     ✓ functionId: [functionId]
     ✓ Mode: [CREATE | UPDATE] (version mới: v{N})
     → Bắt đầu Gate 1...
     ```

#### Bước 0.5: Đảm bảo đang làm việc trên branch riêng của task (AK-Docs)

Trước khi ghi bất kỳ file nào vào `02.BA-Specs/`, đảm bảo AK-Docs đang ở branch riêng của task này, không phải `main` (mọi thay đổi `AK-Docs` phải qua branch + Merge Request, PM duyệt cuối cùng trước khi merge vào `main`):

1. Lấy `taskId` từ trường `taskId` trong `.aiflow/context/current.json`.
2. Kiểm tra `AK-Docs` hiện đang ở branch nào (`git -C AK-Docs branch --show-current`).
3. Nếu **chưa** ở branch `feature/[functionId]/[taskId]`:
   - Hỏi BA: "Chưa có branch riêng cho task này trong AK-Docs. Tạo branch `feature/[functionId]/[taskId]` từ `main` — đồng ý không?"
   - BA đồng ý → chạy `ak docs branch [functionId] [taskId] --yes`
   - BA từ chối → tiếp tục Gate 1 trên nhánh hiện tại của AK-Docs (BA tự quản lý branch)
4. Nếu **đã** ở đúng branch (ví dụ resume từ session trước) → bỏ qua, tiếp tục.

> ❌ Không tự thêm `--yes` khi chưa thấy BA gõ xác nhận rõ ràng trong hội thoại.

#### Bước 1: Đọc và tổng hợp đầu vào
- Đọc `.aiflow/context/current.json` — tiêu đề, mô tả, acceptance criteria, liên kết tài liệu
- Nếu description có URL → chạy `ak fetch-links <url>` để tải nội dung
- Nếu có `supplementaryContext[]` → đọc từng item (file đính kèm, ticket liên quan, comment PM)
- Nếu có file yêu cầu thô được chỉ định → đọc file đó

**Mode UPDATE:** input ở bước này (ticket/CR mới) thường mô tả **phần thay đổi**, không phải toàn bộ feature — coi đó là "yêu cầu thay đổi" cần đối chiếu với `UC-Spec_v{N}.md`/`Analysis_v(n).md` đã đọc ở Bước 0, không phải điều tra lại từ trắng. Nếu input không đủ rõ phạm vi ảnh hưởng (chỉ nói chung chung, không chỉ rõ field/luồng/BR nào đổi) → hỏi BA 1 câu để khoanh vùng trước khi sang Bước 1b/2.

> ❌ **KHÔNG** dùng `superpowers:brainstorming` ở gate này. Skill đó thiết kế cho thiết kế giải pháp kỹ thuật và có terminal state bắt buộc là invoke `writing-plans` (implementation plan) — sai bối cảnh cho BA workflow, vốn kết thúc Gate 1 bằng `Analysis_v1.md` + `QnA-Log_v1.md`, không phải code plan. Kỹ thuật "hỏi từng câu, đề xuất phương án" cần thiết đã có sẵn trong `skill-ba-qna` ở Bước 2/4 bên dưới.

#### Bước 1b: Đọc Source Code

Chạy ngay sau Bước 1, trước khi bắt đầu phân tích.

Nếu workspace mở dạng parent folder chứa cả `ak docs` lẫn source code repos:

1. Xác định repo liên quan: đọc field `repo` trong `.aiflow/context/current.json`, hoặc suy từ tên module/màn hình. Nếu không rõ → hỏi BA 1 câu: "Feature này thuộc repo nào?"
2. **Nếu GitNexus MCP có sẵn** (`.mcp.json` có entry `gitnexus`): dùng GitNexus thay vì đọc file trực tiếp:
   - `gitnexus: query("tên màn hình hoặc chức năng")` → tìm code liên quan
   - `gitnexus: context("ClassName")` → xem toàn bộ class/service/entity
3. **Nếu không có GitNexus**: đọc trực tiếp các file liên quan trong repo:
   - Data models / Entity / DB schema — hiểu cấu trúc dữ liệu hiện tại
   - API endpoints / Routes — hiểu những gì đã tồn tại
   - Service / Business Logic — hiểu behavior hiện tại
   - Config / Constants — ràng buộc kỹ thuật, giới hạn hệ thống
4. Tích hợp vào phân tích:
   - Constraints kỹ thuật từ DB schema (kiểu dữ liệu, độ dài, nullable)
   - Behavior hiện tại của hệ thống (để xác định delta — cái gì cần thêm/sửa/xóa)
   - Pattern kiến trúc đang dùng (để đề xuất solution phù hợp)
   - Các API hiện có (tránh đề xuất trùng lặp hoặc mâu thuẫn)

> ⚠️ Source code dùng để **hiểu hệ thống hiện tại** và phát hiện constraints kỹ thuật — giúp BA đặt câu hỏi chuẩn xác hơn và tránh đề xuất giải pháp mâu thuẫn với architecture. Business requirement vẫn đến từ stakeholder, không từ code.

Áp dụng `custom/rules/investigation-cost-control.md` cho bước đọc source code này (GitNexus-first → `Explore` sub-agent delegation → điều tra theo module một lần, không mở lại file cho từng aspect ở Bước 2 → Investigation Notes table). Ở Mode UPDATE (xem Gate 1 Bước 0 ở trên), phạm vi điều tra chỉ giới hạn trong phần bị ảnh hưởng bởi thay đổi — không quét lại toàn bộ module như Mode CREATE.

#### Bước 2: Phân tích yêu cầu, xác định Gaps và hỏi làm rõ ngay (vòng lặp đồng bộ)

- **READ skill:** `.claude/skills/ba-skills/skill-ba-phan-tich-ban-dau-v1.md` và làm theo
- Phân biệt Facts (thông tin đã chốt) vs Assumptions (tự suy luận cần kiểm chứng)
- Xem xét các khía cạnh: validate dữ liệu, định dạng nhập liệu, phân quyền, xử lý ngoại lệ, thông báo lỗi
- Liệt kê **toàn bộ** Gap/Assumption tìm được — không chỉ những điểm "cốt yếu"

**Mode UPDATE — chỉ phân tích trên phần delta, cộng 1 bước quét side-effect bắt buộc:**

1. Đọc `Analysis_v(n).md`/`UC-Spec_v{N}.md` hiện tại (đã đọc ở Bước 0) làm baseline — mọi Fact/Decision đã Confirmed ở version trước **giữ nguyên, không hỏi lại** (tương tự cách `create-testcase` cấm hỏi lại điều đã có câu trả lời trong artifact gate trước).
2. Chỉ liệt kê Gap/Assumption cho nội dung **mới hoặc bị ảnh hưởng trực tiếp** bởi thay đổi mô tả ở Bước 1.
3. **Bắt buộc, không được bỏ qua:** quét nhanh xem thay đổi có chạm Business Rule/Flow/UI Component nào khác không nằm trong mô tả ban đầu của BA/khách hàng không — cách làm rẻ nhất: tìm mọi chỗ khác trong `UC-Spec_v{N}.md` nhắc tới cùng field/entity/actor với phần vừa đổi (grep theo tên field/entity, không cần LLM suy luận lại toàn bộ). Tìm thấy chỗ nhắc tới khác → thêm vào phạm vi Gap/Assumption của vòng này, không bỏ qua chỉ vì BA/khách hàng không nhắc tới.
4. ⚠️ Bước quét này **không triệt để 100%** — chỉ bắt được phụ thuộc hiển lộ qua từ khoá/tên field trùng nhau, không bắt được phụ thuộc ngầm/semantic. Đây là đánh đổi có chủ đích giữa tốc độ và độ đầy đủ (xem `docs/internal/Token Problems.md` §4) — nếu nghi ngờ có phụ thuộc ngầm, hỏi BA/Dev liên quan thay vì tự suy diễn "chắc không ảnh hưởng gì".

> ❌ **KHÔNG** tự giới hạn số câu hỏi theo một số cố định (ví dụ luôn dừng ở 5-6 câu) bất kể độ phức tạp của input. Số câu hỏi phải phản ánh đúng số Gap/Assumption thực sự tồn tại: yêu cầu đơn giản (1 field, 1 luồng) có thể chỉ cần 2-3 câu; yêu cầu phức tạp (nhiều actor, nhiều luồng, tích hợp hệ thống khác) có thể cần 15-20+ câu. Nếu trong lúc hỏi/nghe trả lời phát hiện thêm Gap mới, bổ sung ngay câu hỏi mới vào cuối vòng lặp — không đóng vòng lặp sớm chỉ vì đã hỏi "đủ nhiều".

**Phân loại mức ảnh hưởng:** trước khi hỏi, gắn nhãn mỗi Gap là 🔴 Blocking hoặc 🟡 Non-blocking theo [Quy ước Blocking / Non-blocking](#quy-ước-blocking--non-blocking--đánh-dấu-pending) ở đầu file.

**Vòng lặp hỏi-đáp:** Với từng Gap/Assumption trong danh sách, hỏi **ONE câu một lúc**, đợi BA trả lời trước khi hỏi câu tiếp theo:

- BA trả lời đủ rõ → đánh dấu **Confirmed**, tích hợp ngay vào bản phân tích đang xây dựng, chuyển sang câu hỏi tiếp theo
- BA trả lời "chưa biết" / "để hỏi lại [stakeholder]" / "chưa chốt được ngay":
  - 🟡 Non-blocking → đánh dấu **Open** (deferred), ghi chú lý do, chuyển ngay sang câu hỏi tiếp theo — KHÔNG chặn
  - 🔴 Blocking → hiển thị cảnh báo lý do đây là blocking + hệ quả nếu bỏ qua, hỏi BA xác nhận có chắc muốn tiếp tục không; BA xác nhận → đánh dấu **Open** nhưng giữ nhãn 🔴 Blocking, vẫn chuyển sang câu tiếp theo
- Lặp lại cho tới khi **mọi** Gap/Assumption trong danh sách đã được hỏi (mỗi câu ở trạng thái Confirmed hoặc Open tường minh, kèm nhãn Blocking/Non-blocking)

Chỉ sau khi vòng lặp này hoàn tất (không còn Gap nào **chưa được hỏi**) mới chuyển sang Bước 3. Số lượng câu hỏi Open còn lại (và nhãn Blocking/Non-blocking của chúng) chính là input cho Gate 2.

#### Bước 3: Soạn thảo Kết quả phân tích sơ bộ
- **READ template:** `.claude/skills/ba-skills/skill-ba-initial-analysis-template-v1.md`
- Điền đầy đủ các mục theo template: Actors, Facts, Assumptions, Gap Analysis table — dùng câu trả lời **Confirmed** từ vòng lặp Bước 2 làm nội dung chính, không phải giả định của AI
- Gap Analysis table chỉ còn liệt kê các Gap **Open** (deferred) từ vòng lặp Bước 2, kèm nhãn 🔴 Blocking / 🟡 Non-blocking
- Với mỗi Gap Open, chèn marker `⚠️ [PENDING - QA-0N]` tại đúng vị trí nội dung liên quan (mục 3/4 của template) thay vì bỏ trống hoặc tự suy diễn
- Nếu tài liệu còn ít nhất 1 Gap Open → thêm banner đầu tài liệu: `⚠️ TÀI LIỆU CHƯA ĐẦY ĐỦ — còn [N] câu hỏi Open ([X] Blocking, [Y] Non-blocking), xem QnA-Log_v1.md`
- **Mode UPDATE:** mọi mục **không** nằm trong phạm vi delta (đã xác định ở Bước 2) giữ nguyên nội dung từ `Analysis_v(n).md` cũ — không viết lại. Thêm 1 dòng đầu tài liệu: `Mode: UPDATE — hướng tới UC-Spec v{N+1} (hiện tại: v{N})`. Đặt tên file tiếp nối đúng counter hiện có của `functionId` này (không phải `_v1`) — nếu `Analysis_v(n).md` cao nhất hiện có là ví dụ `Analysis_v3.md` (từ vòng đàm phán của UC Spec v{N} trước đó), file mới của vòng UPDATE này là `Analysis_v4.md`, không phải reset lại `_v1` (tránh ghi đè/nhầm lẫn với bản cũ).
- Lưu: `02.BA-Specs/01.Analysis/[functionId]/Analysis_v1.md` (Mode CREATE) hoặc `Analysis_v(n+1).md` tiếp nối counter hiện có (Mode UPDATE, xem trên)

#### Bước 4: Soạn thảo danh sách Q&A

- **READ skill:** `.claude/skills/ba-skills/skill-ba-qna-v1.md`
- **READ template:** `.claude/skills/ba-skills/skill-ba-qna-template-v1.md`
- Ghi lại **toàn bộ** câu hỏi đã hỏi ở vòng lặp Bước 2 dưới dạng log: mỗi câu kèm câu trả lời, nhãn Blocking/Non-blocking, và trạng thái cuối cùng
  - **Confirmed** — BA đã trả lời trong Bước 2, ghi kèm câu trả lời
  - **Open** — BA đã xác nhận chưa trả lời được ngay (cần hỏi lại stakeholder khác), ghi kèm lý do deferred + nhãn 🔴 Blocking hoặc 🟡 Non-blocking
- Không tạo câu hỏi mới ở bước này — đây là bản ghi (log) của vòng lặp đã chạy ở Bước 2, không phải một vòng hỏi mới
- Lưu: `02.BA-Specs/02.QnA/[functionId]/QnA-Log_v1.md`

#### Bước 5: Gate Review & Pause
- **INVOKE** `gate-review` skill (generate mode) — ghi `.aiflow/review/gate-1-[functionId].md`
- **Kiểm tra Q&A bắt buộc:** Đọc `QnA-Log_v1.md` — đếm số câu **Open**, tách riêng theo nhãn 🔴 Blocking và 🟡 Non-blocking
- Hiển thị gate pause message — chờ phản hồi từ BA

**Nếu còn câu Open 🔴 Blocking → từ chối APPROVED ngay, hiển thị:**

⛔ GATE 1 BLOCKED — Còn [N] câu hỏi Blocking chưa được trả lời trong QnA-Log_v1.md.

| ID | Câu hỏi còn Open (Blocking) |
|----|-----------------|
| [Q_ID] | [nội dung câu hỏi] |

Vui lòng cung cấp câu trả lời theo một trong 3 cách:
→ Option A: nhập trực tiếp — `Q1: [trả lời], Q2: [trả lời]`
→ Option B: paste nội dung bảng Q&A đã điền vào chat
→ Option C: đặt file `QnA-Log_v1_response.md` vào thư mục `02.QnA/[functionId]/` rồi gõ NEXT

❌ APPROVED không được chấp nhận cho đến khi mọi câu hỏi **Blocking** đã Confirmed.

**Nếu chỉ còn câu Open 🟡 Non-blocking (không còn Blocking) → cho phép APPROVED, nhưng hiển thị cảnh báo ngay trong gate pause message trước khi BA gõ APPROVED:**

⚠️ Còn [N] câu hỏi Non-blocking chưa Confirmed — có thể APPROVED để tiếp tục, tài liệu sẽ giữ marker `[PENDING - QA-0N]` tại các phần liên quan cho tới khi được bổ sung ở Gate 2.

| ID | Câu hỏi còn Open (Non-blocking) |
|----|-----------------|
| [Q_ID] | [nội dung câu hỏi] |

**Khi APPROVED (không còn câu Blocking Open — câu Non-blocking Open được phép tồn tại):**
→ **INVOKE** `gate-review` skill (verify mode) — chạy `ak review check --gate 1 --ticket [functionId]`
→ Nếu passed: `ak gate 1 approved --ticket [functionId]` → chuyển Gate 2
→ Nếu blocked: làm theo gate-review skill response protocol

**Definition of Done:**
- [ ] `functionId` đã được xác định và thư mục đầu ra đã sẵn sàng
- [ ] File `Analysis_v1.md` tạo đúng vị trí, cấu trúc đúng template, có bảng Gap Analysis, số Gap phản ánh đúng độ phức tạp thực tế (không bị gò về một số cố định)
- [ ] File `QnA-Log_v1.md` có ít nhất 1 câu hỏi cho mỗi Gap, mỗi câu có nhãn Blocking/Non-blocking rõ ràng
- [ ] Không còn câu hỏi 🔴 Blocking ở trạng thái Open
- [ ] Không có giả định nào được tự ý chốt thành Spec mà không đưa vào Q&A

> **Telemetry:** Run `ak gate 1 start --ticket [functionId]` khi bắt đầu gate này.
> Run `ak gate 1 approved --ticket [functionId]` sau khi gate-review verify passed. Run as-is — không thêm shell redirects.

---

### GATE 2 — Cập nhật phản hồi Q&A (lặp đến khi tất cả Confirmed)

**Mục tiêu:** Tiếp nhận câu trả lời từ BA/khách hàng, cập nhật trạng thái Q&A, tích hợp thông tin vào tài liệu phân tích, và quyết định vòng Q&A tiếp theo hay chốt để tiến Gate 3.

**Đầu vào (Inputs):**
- Phản hồi Q&A từ BA (xem 3 option bên dưới)
- `02.BA-Specs/01.Analysis/[functionId]/Analysis_v(n).md` — phiên bản hiện tại
- `02.BA-Specs/02.QnA/[functionId]/QnA-Log_v(m).md` — danh sách câu hỏi hiện tại

**Cách BA cung cấp phản hồi (BA chọn một trong 3):**
- **Option A** — Nhập trực tiếp vào chat: `Q&A: Q1: [trả lời], Q2: [trả lời]`
- **Option B** — Paste nội dung bảng Q&A đã điền vào chat
- **Option C** — Đặt file tại: `02.BA-Specs/02.QnA/[functionId]/QnA-Log_v(m)_response.md`

**Bước thực hiện:**

**Pre-flight (bắt buộc, chạy trước Bước 1):** chạy [Pre-flight — Đồng bộ Source & Docs](#pre-flight-bắt-buộc--đồng-bộ-source--docs-đầu-mỗi-gate) ở đầu file. Lỗi → hiển thị ⚠️ cảnh báo, không dừng gate.

#### Bước 1: Tiếp nhận và đánh giá câu trả lời
- Đối chiếu từng câu trả lời với câu hỏi trong `QnA-Log_v(m).md`
- Phân loại:
  - Đủ thông tin → cập nhật trạng thái: **Confirmed**, xóa marker `[PENDING - QA-ID]` liên quan
  - Chưa rõ hoặc phát sinh nghiệp vụ mới → giữ trạng thái **Open**, bổ sung ghi chú, giữ nguyên nhãn 🔴 Blocking / 🟡 Non-blocking đã gắn từ Gate 1 (hoặc gắn mới nếu là Gap phát sinh)

#### Bước 2: Tích hợp thông tin vào tài liệu phân tích
- Lấy thông tin từ các câu Confirmed → cập nhật vào `Analysis_v(n).md`
- Xóa các Gap đã được giải quyết khỏi bảng Gap Analysis
- Tạo phiên bản mới: `02.BA-Specs/01.Analysis/[functionId]/Analysis_v(n+1).md`

#### Bước 3: Rẽ nhánh theo trạng thái Q&A

**Kịch bản A — Còn câu hỏi Open 🔴 Blocking:**
1. Kiểm tra `Analysis_v(n+1).md` có phát sinh Gap mới không
2. Tạo: `02.BA-Specs/02.QnA/[functionId]/QnA-Log_v(m+1).md` — chỉ giữ câu Open và câu mới phát sinh
3. **INVOKE** `gate-review` skill (generate mode) — ghi `.aiflow/review/gate-2-[functionId]-round-[m+1].md`
4. Hiển thị:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⏸️  GATE 2 — VÒNG Q&A [m+1]

Câu hỏi còn Open (🔴 Blocking): [N]
Câu hỏi còn Open (🟡 Non-blocking): [M]
File Q&A mới:     [02.BA-Specs/02.QnA/[functionId]/QnA-Log_v(m+1).md](02.BA-Specs/02.QnA/[functionId]/QnA-Log_v(m+1).md)
File phân tích:   [02.BA-Specs/01.Analysis/[functionId]/Analysis_v(n+1).md](02.BA-Specs/01.Analysis/[functionId]/Analysis_v(n+1).md)

→ BA điền câu trả lời và cung cấp theo một trong 3 option (A/B/C)
→ Sau khi cung cấp phản hồi, type NEXT để AI xử lý vòng tiếp theo
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

5. Lặp lại Bước 1 khi nhận phản hồi mới

**Nếu BA gõ APPROVED khi đang ở Kịch bản A (còn câu hỏi Open 🔴 Blocking) → từ chối ngay:**

⛔ GATE 2 BLOCKED — Còn [N] câu hỏi Blocking chưa Confirmed.

| ID | Câu hỏi còn Open (Blocking) |
|----|-----------------|
| [Q_ID] | [nội dung câu hỏi] |

→ Cung cấp câu trả lời (Option A/B/C) rồi gõ NEXT để AI xử lý tiếp.
❌ APPROVED chỉ được chấp nhận khi mọi câu hỏi **Blocking** đã Confirmed.

**Kịch bản B — Chỉ còn câu hỏi Open 🟡 Non-blocking (không còn Blocking):**

1. Tạo `QnA-Log_v(m+1).md` như Kịch bản A (giữ câu Non-blocking Open + câu mới phát sinh)
2. Hiển thị cho BA 2 lựa chọn, không tự chọn thay:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⏸️  GATE 2 — CÒN [M] CÂU HỎI NON-BLOCKING CHƯA CONFIRMED

Các câu hỏi này không chặn thiết kế Gate 3/4, nhưng output sẽ giữ marker `[PENDING - QA-ID]` tại các phần liên quan cho tới khi được bổ sung.

→ Cách 1: cung cấp câu trả lời (Option A/B/C) rồi gõ NEXT để xử lý tiếp
→ Cách 2: gõ APPROVED để chấp nhận tiếp tục dù output chưa đầy đủ ở các mục này
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. BA gõ NEXT với phản hồi mới → lặp lại Bước 1
2. BA gõ APPROVED → coi là đã xác nhận chấp nhận output chưa đầy đủ, chuyển sang xử lý APPROVED bên dưới

**Kịch bản C — Tất cả đã Confirmed:**
1. Chốt tài liệu phân tích (phiên bản cuối cùng là đầu vào Gate 3)
2. **INVOKE** `gate-review` skill (generate mode) — ghi `.aiflow/review/gate-2-[functionId].md`
3. Hiển thị gate pause message — đợi **APPROVED**

**Khi APPROVED (Kịch bản B hoặc C — không còn câu Blocking Open):**
→ **INVOKE** `gate-review` skill (verify mode) — chạy `ak review check --gate 2 --ticket [functionId]`
→ Nếu passed: `ak gate 2 approved --ticket [functionId]` → chuyển Gate 3
→ Nếu blocked: làm theo gate-review skill response protocol

**Definition of Done:**
- [ ] Mọi câu trả lời đều được phân tích và phân loại trạng thái
- [ ] Tài liệu phân tích phiên bản mới tích hợp đầy đủ thông tin nghiệp vụ mới nhất
- [ ] Không còn câu hỏi 🔴 Blocking ở trạng thái Open trước khi tiến Gate 3
- [ ] Nếu còn câu 🟡 Non-blocking Open, BA đã xác nhận rõ ràng (gõ APPROVED sau khi thấy cảnh báo) và các mục liên quan trong Analysis đã có marker `[PENDING - QA-ID]`

> **Telemetry:** Run `ak gate 2 start --ticket [functionId]` khi bắt đầu gate này.
> Run `ak gate 2 approved --ticket [functionId]` sau khi gate-review verify passed. Run as-is — không thêm shell redirects.

---

### GATE 3 — Thiết kế giao diện Prototype HTML/CSS

**Mục tiêu:** Dựa trên tài liệu phân tích đã chốt, thiết kế bản mẫu giao diện (Prototype) độc lập bằng HTML/CSS để trực quan hóa các thành phần và luồng tương tác.

**Điều kiện vào Gate 3:** Không còn câu hỏi 🔴 Blocking Open và Gate 2 đã **APPROVED** (câu 🟡 Non-blocking Open, nếu còn, mang marker `[PENDING - QA-ID]` sang cùng Analysis).

**Đầu vào (Inputs):**
- `02.BA-Specs/01.Analysis/[functionId]/Analysis_v(n).md` — phiên bản cuối

**Đầu ra (Outputs):**
- `02.BA-Specs/03.UI-Prototypes/[functionId]/UI-Prototype_v1.html`

**Bước thực hiện:**

**Pre-flight (bắt buộc, chạy trước Bước 1):** chạy [Pre-flight — Đồng bộ Source & Docs](#pre-flight-bắt-buộc--đồng-bộ-source--docs-đầu-mỗi-gate) ở đầu file. Lỗi → hiển thị ⚠️ cảnh báo, không dừng gate.

#### Bước 1: Liệt kê thành phần giao diện
- Đọc tài liệu phân tích đã chốt
- Xác định: ô nhập liệu, nút bấm, liên kết, vùng hiển thị lỗi, vùng hiển thị dữ liệu
- Nếu Analysis còn marker `[PENDING - QA-ID]` liên quan đến thành phần giao diện nào → giữ nguyên placeholder trực quan cho thành phần đó (không tự bịa nội dung/behavior để lấp đầy) và ghi chú `<!-- PENDING - QA-ID -->` cạnh phần tử HTML tương ứng

#### Bước 2: Thiết kế và viết code HTML/CSS
- **READ skill:** `.claude/skills/ba-skills/skill-ba-prototype-v1.md` và làm theo
- Viết HTML ngữ nghĩa cao (semantic HTML)
- Đặt `id` và `name` **duy nhất** cho MỌI thẻ tương tác (`input`, `button`, `a`, `select`, `textarea`) — phục vụ automation test
- Nhúng CSS trong thẻ `<style>` ở `<head>` — không gọi external link (offline-friendly)
- Mã hóa hiệu ứng hover, focus bằng CSS

#### Bước 3: Dựng sẵn Error UI Placeholders
- Thẻ lỗi tại vị trí tương ứng (dưới ô nhập liệu hoặc banner trên)
- CSS nổi bật lỗi (chữ đỏ, viền đỏ), mặc định ẩn (`display: none`)

#### Bước 4: Lưu file
- `02.BA-Specs/03.UI-Prototypes/[functionId]/UI-Prototype_v1.html`

#### Bước 5: Gate Review & Pause
- **INVOKE** `gate-review` skill (generate mode) — ghi `.aiflow/review/gate-3-[functionId].md`
- Hiển thị gate pause message — đợi **APPROVED**

**Khi APPROVED:**
→ **INVOKE** `gate-review` skill (verify mode) — chạy `ak review check --gate 3 --ticket [functionId]`
→ Nếu passed: `ak gate 3 approved --ticket [functionId]` → chuyển Gate 4
→ Nếu blocked: làm theo gate-review skill response protocol

**Definition of Done:**
- [ ] File `UI-Prototype_v1.html` tạo đúng vị trí
- [ ] Giao diện hiển thị đủ tất cả thành phần nghiệp vụ
- [ ] 100% thẻ tương tác có `id` duy nhất
- [ ] CSS tự chứa trong file HTML

> **Telemetry:** Run `ak gate 3 start --ticket [functionId]` khi bắt đầu gate này.
> Run `ak gate 3 approved --ticket [functionId]` sau khi gate-review verify passed. Run as-is — không thêm shell redirects.

---

### GATE 4 — Viết đặc tả Use Case Spec hoàn chỉnh

**Mục tiêu:** Tổng hợp tất cả thông tin nghiệp vụ, giao diện HTML, sơ đồ Mermaid và Business Rules thành tài liệu UC Spec hoàn chỉnh để bàn giao Dev/Test.

**Điều kiện vào Gate 4:** Gate 3 đã **APPROVED** và `design.html` đã hoàn chỉnh.

**Đầu vào (Inputs):**
- `02.BA-Specs/01.Analysis/[functionId]/Analysis_v(n).md` — phiên bản cuối
- `02.BA-Specs/03.UI-Prototypes/[functionId]/UI-Prototype_v1.html`

**Đầu ra (Outputs):**
- `02.BA-Specs/04.UC-Specs/[functionId]/UC-Spec_v{N}.md` (`N` = 1 nếu Mode CREATE; `N` = version xác định ở Gate 1 Bước 0 nếu Mode UPDATE)

**Bước thực hiện:**

**Pre-flight (bắt buộc, chạy trước Bước 1):** chạy [Pre-flight — Đồng bộ Source & Docs](#pre-flight-bắt-buộc--đồng-bộ-source--docs-đầu-mỗi-gate) ở đầu file. Lỗi → hiển thị ⚠️ cảnh báo, không dừng gate.

#### Bước 1: Khởi tạo Spec từ Template
- **READ template:** `.claude/skills/ba-skills/skill-ba-uc-template-v1.md`
- **READ skill:** `.claude/skills/ba-skills/skill-ba-write-uc-spec-v1.md`
- Tạo: `02.BA-Specs/04.UC-Specs/[functionId]/UC-Spec_v{N}.md`
- Điền General Information: Use Case ID, Title, Version, Actors, Preconditions, Postconditions
- **Header bắt buộc** (mọi Mode — template `skill-ba-uc-template-v1.md` đã có sẵn khối này ở đầu tài liệu): `UC-Spec-Version: v{N}` + `Date` + `Status`.
- Nếu Analysis/Prototype đầu vào còn marker `[PENDING - QA-ID]` (câu Non-blocking chưa Confirmed) → giữ nguyên marker tại đúng vị trí liên quan (Business Rule, UI Component, Flow step) trong UC Spec, không tự bịa nội dung để lấp đầy; thêm banner đầu tài liệu: `⚠️ UC SPEC CHƯA ĐẦY ĐỦ — còn [N] mục PENDING, xem QnA-Log_v(m).md`
- **Mode UPDATE:** khởi tạo `UC-Spec_v{N}.md` bằng cách copy `UC-Spec_v{N-1}.md` làm nền, rồi chỉ sửa đúng phần đã đổi (theo delta đã xác định ở Gate 1 Bước 2) — không viết lại từ template trắng. Mỗi thay đổi phải thêm 1 dòng vào section **"Change Log"** ở cuối tài liệu (thêm section này nếu UC Spec chưa có — xem `skill-ba-uc-template-v1.md`): `| v{N} | [ngày] | [Flow/BR nào đổi] | [tóm tắt thay đổi] | [ticket/CR nguồn] |`. Không được âm thầm bỏ 1 mục mà không ghi lý do vào Change Log.

#### Bước 2: Mô tả luồng sự kiện (Flow of Events)
- **Main Flow** — happy path
- **Alternative Flow** — các trường hợp hợp lệ khác
- **Exception Flow** — lỗi, điều kiện thất bại
- Viết rõ tương tác Actor ↔ System ở từng bước

#### Bước 3: Tích hợp giao diện Prototype
- Copy toàn bộ mã HTML/CSS từ `UI-Prototype_v1.html` vào phần Screen Description

#### Bước 4: Mô tả chi tiết UI Components
- Lập bảng: Tên | Loại | Bắt buộc | Độ dài tối đa | Giá trị mặc định | Ràng buộc validation
- `id` trong bảng phải khớp chính xác với `id` trong HTML

#### Bước 5: Vẽ sơ đồ hoạt động Mermaid
- **READ skill:** `.claude/skills/ba-skills/skill-ba-ve-luong-mermaid-v1.md` và làm theo
- Vẽ Activity Diagram: Main Flow, điểm quyết định (hình thoi), Alternative Flow, Exception Flow
- Nhúng mã Mermaid vào section Activity Flow của Spec

#### Bước 6: Đặc tả Business Rules (BR)
- **READ skill:** `.claude/skills/ba-skills/skill-ba-xay-dung-business-rules-v1.md` và làm theo
- Đặc tả:
  - **Validation BR**: định dạng, giá trị, bắt buộc
  - **Processing BR**: logic xử lý khi lưu/cập nhật
  - **Authorization BR**: phân quyền theo role
- Mỗi BR có mã `[BR-NNN]`, liên kết với câu thông báo lỗi chính xác trên màn hình

#### Bước 7: Gate Review & Pause
- **INVOKE** `gate-review` skill (generate mode) — ghi `.aiflow/review/gate-4-[functionId].md`
- Hiển thị gate pause message — đợi **APPROVED**

**Khi APPROVED:**
→ **INVOKE** `gate-review` skill (verify mode) — chạy `ak review check --gate 4 --ticket [functionId]`
→ Nếu passed: `ak gate 4 approved --ticket [functionId]` → UC Spec hoàn thành, sẵn sàng bàn giao Dev/Test
→ Nếu blocked: làm theo gate-review skill response protocol

**Phản hồi đặc biệt:**
- BA gõ `REVISION: [nội dung]` → **trước khi sửa**, tạo ngay 1 memory draft ghi lại chính xác điều BA vừa chỉnh (`ak memory draft --category 01.Lessons/ba --function-id [functionId] --slug <slug> --content "<điều BA sửa + vì sao>" --workflows create-spec --source "[functionId] / Gate 4 BA feedback"`) — đây là tín hiệu giá trị nhất, đừng chờ Bước 7.5 mới bắt lại theo trí nhớ → cập nhật section liên quan → re-generate review file → hiển thị lại gate pause

**Definition of Done:**
- [ ] File `UC-Spec_v{N}.md` đúng vị trí và cấu trúc template, có `UC-Spec-Version` header đúng `N`
- [ ] 100% element HTML được mô tả trong bảng UI Components (id, loại, ràng buộc)
- [ ] Mã Mermaid hợp lệ, thể hiện đủ Main/Alternative/Exception Flow
- [ ] Business Rules đầy đủ với mã `[BR-NNN]` và thông báo lỗi chính xác
- [ ] Không còn giả định ngầm chưa Confirm bị viết như thể đã chốt; mọi nội dung Non-blocking Open còn lại đã có marker `[PENDING - QA-ID]` rõ ràng tại đúng vị trí (không phải ghi chú mơ hồ chung)

> **Telemetry:** Run `ak gate 4 start --ticket [functionId]` khi bắt đầu gate này.
> Run `ak gate 4 approved --ticket [functionId]` sau khi gate-review verify passed. Run as-is — không thêm shell redirects.

#### Bước 7.5: Retrospect + đề xuất memory draft

Sau khi Gate 4 APPROVED, đúc kết những gì học được. **Ưu tiên feedback của BA trước:** nếu có vòng `REVISION` nào đã xảy ra, đảm bảo điều BA sửa đã có draft (thường đã tạo ngay lúc REVISION ở trên — kiểm tra lại, đừng bỏ sót). Sau đó mới thêm những gì mới khác: business rule mới confirm, thuật ngữ cần làm rõ, quyết định đặc tả và lý do. Tạo **draft local** cho từng candidate (chưa cần duyệt — `_pending/` chỉ ở local, xem `docs/common/Memory-Architecture-v1.0.md`):

```
ak memory draft --category 00.Shared/domain --function-id [functionId] \
  --slug <slug-ngắn> --content "<≤150 từ, 1 fact>" \
  --tags <tag1,tag2> --workflows create-spec --source "[functionId] / Gate 4"
```

Category khác hữu ích ở đây: `00.Shared/glossary` (thuật ngữ JP↔VN↔EN mới xác nhận — flat, không cần `--function-id`), `01.Lessons/ba` (bài học khi làm spec), `00.Shared/decisions` (quyết định đặc tả). Bỏ qua bước này nếu không có gì thực sự mới. Nếu `ak memory draft` báo trùng, đừng tạo bản mới — báo cho BA để họ quyết định sửa bản cũ.

#### Bước 8: Submit AK-Docs lên remote qua Merge Request

Sau khi Gate 4 đã APPROVED (UC Spec hoàn thành):

1. Soạn title + description cho Merge Request (tóm tắt UC Spec vừa hoàn thành, link ticket gốc), hiển thị cho BA xem trước.
2. Hỏi BA: "Nội dung commit/MR như trên — đồng ý submit AK-Docs không?"
   - BA đồng ý → chạy `ak docs submit --title "..." --description "..." --yes`
   - BA từ chối → dừng, để BA tự commit/tạo MR khi sẵn sàng
3. Thông báo BA: MR đã mở, chờ **PM review & merge vào `main`** — đây là bước duyệt cuối cùng cho tài liệu, không phải BA tự merge.

> ❌ Không tự thêm `--yes` khi chưa thấy BA gõ xác nhận rõ ràng trong hội thoại.

---

### Bản đồ Skills theo Gate

| Gate | Skills đọc | Output |
|---|---|---|
| Gate 1 | `skill-ba-initial-analysis`, `skill-ba-initial-analysis-template`, `skill-ba-qna`, `skill-ba-qna-template` | `Analysis_v1.md`, `QnA-Log_v1.md` |
| Gate 2 | `skill-ba-qna`, `skill-ba-initial-analysis` | `Analysis_v(n+1).md`, `QnA-Log_v(m+1).md` (nếu còn Open) |
| Gate 3 | `skill-ba-ui-prototype` | `UI-Prototype_v1.html` |
| Gate 4 | `skill-ba-write-uc-spec`, `skill-ba-uc-template`, `skill-ba-mermaid-flowchart`, `skill-ba-build-business-rules` | `UC-Spec_v{N}.md` |

---

### Quy tắc bắt buộc

- ❌ **KHÔNG** bỏ qua thứ tự Gate — luôn đi từ Gate 1 → 2 → 3 → 4
- ❌ **KHÔNG** tự chốt giả định nghiệp vụ mà không đưa vào Q&A
- ❌ **KHÔNG** dùng `superpowers:brainstorming` ở Gate 1 — terminal state của skill đó invoke `writing-plans`, bypass cấu trúc BA workflow
- ✅ **BẮT BUỘC** ở Gate 1 Bước 2: hỏi hết **toàn bộ** Gap/Assumption xác định được, từng câu một, ngay trong hội thoại — không giới hạn ở "điểm mơ hồ cốt yếu" và **không giới hạn theo một số câu hỏi cố định** bất kể độ phức tạp input. Chỉ được ghi Open (deferred sang QnA-Log) khi BA xác nhận rõ ràng là chưa trả lời được ngay
- ✅ **BẮT BUỘC** gắn nhãn 🔴 Blocking / 🟡 Non-blocking cho mỗi Gap/câu hỏi ngay khi phát hiện (xem [Quy ước Blocking / Non-blocking](#quy-ước-blocking--non-blocking--đánh-dấu-pending))
- ❌ **KHÔNG** tiến Gate 3 khi vẫn còn câu hỏi 🔴 Blocking ở trạng thái Open
- ❌ **KHÔNG chấp nhận APPROVED** ở Gate 1 hoặc Gate 2 khi còn bất kỳ câu hỏi 🔴 **Blocking** nào ở trạng thái **Open** — từ chối và hiển thị danh sách câu hỏi cần trả lời
- ✅ **ĐƯỢC PHÉP chấp nhận APPROVED** ở Gate 1/2/4 khi chỉ còn câu hỏi 🟡 **Non-blocking** Open, với điều kiện: đã hiển thị cảnh báo rõ ràng cho BA trước khi nhận APPROVED, và mọi nội dung phụ thuộc câu hỏi đó được đánh dấu `[PENDING - QA-ID]` tại đúng vị trí trong output — không được tự suy diễn nội dung để lấp đầy
- ✅ **BẮT BUỘC** chạy Bước 0 ở Gate 1 — xác nhận `functionId` và thư mục đầu ra trước khi làm bất cứ điều gì
- ✅ **BẮT BUỘC** chạy Bước 0.5 ở Gate 1 — đảm bảo AK-Docs đang ở branch `feature/[functionId]/[taskId]` trước khi ghi file đầu tiên
- ✅ **BẮT BUỘC** đọc skill từ `.claude/skills/ba-skills/` — không suy luận từ bộ nhớ
- ✅ **BẮT BUỘC** invoke `gate-review` cuối mỗi gate và chờ APPROVED
- ✅ **BẮT BUỘC** mọi thẻ tương tác trong HTML có `id` duy nhất
- ✅ **BẮT BUỘC** CSS tự chứa trong HTML (không external link)
- ✅ **BẮT BUỘC** mỗi BR có mã `[BR-NNN]` và câu thông báo lỗi cụ thể
- ✅ **BẮT BUỘC** chạy bước "Xác định Mode (CREATE / UPDATE)" ở Gate 1 Bước 0 trước khi làm bất cứ điều gì khác — không mặc định CREATE nếu chưa kiểm tra UC Spec cũ đã tồn tại và PM merge chưa
- ❌ **KHÔNG** hỏi lại (Mode UPDATE) điều đã Confirmed ở version trước — chỉ hỏi cho phần delta + phần phát hiện qua bước quét side-effect bắt buộc (Gate 1 Bước 2)
- ✅ **BẮT BUỘC** (Mode UPDATE) ghi mọi thay đổi vào section "Change Log" của `UC-Spec_v{N}.md` — không âm thầm sửa/xoá nội dung mà không ghi lý do
