@edupia-tutor/spec-driven-docs 0.14.8 → 0.14.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,259 +1,120 @@
1
1
  # ============================================================
2
- # BDD Feature Template — KVLoyalty AI Native Pipeline (v2)
2
+ # @trace.id: {TICKET-ID}-UC{N}
3
+ # @trace.title: <Feature name>
4
+ # @trace.revision: 1 ← field tĩnh; dùng @trace.bdd_version để theo dõi version (tăng bởi /review-context --fix hoặc --resume)
5
+ # @trace.domain: <domain>
6
+ # @trace.platform: {active_platform — web | app | system | (bỏ trong umbrella mode)}
7
+ # @trace.service: {active_service — bỏ trong spec repo mode}
8
+ # @trace.module: {active_module trong umbrella mode; "unknown" trong spec repo mode}
9
+ # @trace.status: draft
10
+ # @trace.author: AI-generated
11
+ # @trace.created_at: {YYYY-MM-DD}
12
+ # @trace.prd: {TICKET-ID}
13
+ # @trace.prd_version: {đọc từ metadata PRD "| **Version** |"}
14
+ # @trace.bdd_version: {1.0 nếu gen mới; tăng 0.1 khi gen lại — vd 1.0 → 1.1}
15
+ # @trace.business_rules: {TICKET-ID}-UC{N}-BR1, {TICKET-ID}-UC{N}-BR2
16
+ # @trace.dataset: {domain}.testdata.yaml
3
17
  # ============================================================
4
- # Instructions:
5
- # 1. Copy this file và rename: {TICKET_ID}-UC{N}-feature-name.feature
6
- # 2. Điền @trace metadata (required)
7
- # 3. Khai báo Context của UC (1 lần, đầu file)
8
- # 4. Tạo/cập nhật dataset YAML cùng domain: specs/features/{domain}.testdata.yaml
9
- # 5. Viết Scenario — mỗi SC PHẢI có dòng `# Side-effects:` ngay trên
10
- # 6. Đặt file ở: specs/features/{domain}/
11
- # 7. Chạy: /generate-code
12
- # ============================================================
13
- #
14
- # RULE VIẾT BDD BẮT BUỘC (xem bdd-writing-guide.md PART A + C):
15
- # R1 Given/When/Then Semantics — Given=state, When=action, Then=outcome (mỗi SC đủ G/W/T)
16
- # R2 One Behavior Per Scenario — 1 SC = 1 behavior; KHÔNG chain When-Then
17
- # R3 Ubiquitous Language — KHÔNG dùng UI selector / API name / tech term
18
- # R4 Outside-in Naming — Tên SC mô tả business outcome, KHÔNG có "click"/"(Case X)"/component name
19
- # R5 Declarative over Imperative — Mô tả WHAT (intent business), KHÔNG HOW (UI mechanic)
20
- # R6 Observable Outcomes Only — Then assert outcome quan sát được, KHÔNG UI trung gian/internal state
21
- # R7 Key Examples / Concrete — Dùng concrete values, KHÔNG "hợp lệ" chung chung
22
- # R8 Independence — SC chạy độc lập, KHÔNG phụ thuộc state SC khác
23
- # R9 Test Data Completeness — Data table có đủ field external system để derive expected Then
24
- # R10 Scope Boundary Explicit — Cross-UC reference dùng wording navigation + Note comment
25
- # PROJECT COMPLIANCE (must-pass, fail review nếu thiếu):
26
- # C.1 Wireframe Coverage — Mọi component/action wireframe có ≥1 SC
27
- # C.2 PRD Traceability — Mọi AC/BR (kèm bullet) map về ≥1 SC
28
- # C.3 Business Dictionary — Dùng đúng term, đề xuất term mới qua DICTIONARY-SUGGESTION
29
- # C.4 Banned Terms Compliance — 0 banned term (auto-grep): SKU/Customer/JS SDK/Cửa hàng/...
30
- # C.5 NHÓM Grouping Convention — Scenarios gom theo CHỦ ĐỀ NGHIỆP VỤ (NHÓM N) — xem §NHÓM GROUPING CONVENTION dưới
31
- # ============================================================
32
-
33
- # --- TRACE METADATA (REQUIRED) ---
34
- # @trace.id: {TICKET_ID}-UC{N}
35
- # @trace.title: <Tên tính năng bằng tiếng Việt>
36
- # @trace.revision: 1
37
- # @trace.domain: <identity|loyalty|membership|messaging|store-management>
38
- # @trace.service: <KVLoyalty.Identity|KVLoyalty.Loyalty|...>
39
- # @trace.status: draft|review|approved
40
- # @trace.author: <tên tác giả>
41
- # @trace.created_at: <YYYY-MM-DD>
42
- # @trace.prd: <TICKET-ID hoặc để trống>
43
- # @trace.prd_version: <version PRD tại thời điểm viết — để drift-detector so sánh>
44
- # @trace.business_rules: <{TICKET_ID}-UC{N}-BR{M}, ...>
45
- # @trace.dataset: <{domain}.testdata.yaml — bắt buộc nếu BDD reference dataset>
46
18
 
47
- # === CONTEXT (áp dụng cho toàn Feature) ===
19
+ # === CONTEXT ===
48
20
  # Actor: <vai trò thực hiện hành động, vd: Consumer, Staff, System>
49
21
  # Screens: <các màn liên quan, vd: Cart → Confirm Order → Order Detail>
50
- # Entities: <entity nghiệp vụ, vd: Order, OrderItem, Consumer, Branch>
51
- # Pre-state: <state chung trước khi vào các scenario>
22
+ # Entities: <business entity, vd: Order, OrderItem, Consumer>
23
+ # Pre-state: <state dùng chung trước khi vào các scenario>
52
24
 
53
25
  # === SCOPE ===
54
- # In: <những gì UC này cover>
55
- # Out: <những gì KHÔNG thuộc UC này — link sang UC khác / feature khác (R10)>
26
+ # In: <UC này phủ gì>
27
+ # Out: <cái gì KHÔNG thuộc UC này — link tới UC/feature khác (R10)>
56
28
 
57
- # === BUSINESS DEFINITION (MANDATORY) ===
58
- # Quick reference các thuật ngữ dùng trong feature này. SoT chi tiết: business-dictionary.md
59
- # Mục đích: reader đọc 1 lần hiểu ngay khái niệm trước khi xem scenarios.
29
+ # === BUSINESS DEFINITION ===
30
+ # Tham chiếu nhanh các term dùng trong feature này. Chi tiết SoT: business-dictionary.md
31
+ # <Term 1>: <định nghĩa ngắn>
32
+ # <Term 2>: <định nghĩa ngắn>
60
33
  #
61
- # <Term 1> (English mapping): <định nghĩa ngắn gọn, vd cấu trúc, scope>
62
- # <Term 2>: <định nghĩa>
63
- # ...
64
- #
65
- # === Test data convention (R9) ===
66
- # Khai báo default value khi data table không có cột tương ứng.
67
- # VD: "SC không khai báo cột customerOrdered → ngầm hiểu customerOrdered = 0 (chưa có khách đặt)"
68
- # VD: "SC không khai báo cột toggle → ngầm hiểu toggle = Hiện (default Ẩn/Hiện trạng thái)"
69
- #
70
- # === Popup/Modal Lifecycle (B.2.4 — bắt buộc nếu feature là popup/modal) ===
34
+ # --- Popup/Modal Lifecycle (tùy chọn BẮT BUỘC nếu feature popup/modal; Pre-merge yêu cầu) ---
71
35
  # - Open trigger: <khi nào popup hiển thị, vd: click menu sidebar>
72
36
  # - Close trigger: <khi nào popup đóng, vd: F5 / click X / ESC / navigate away>
73
37
  # - Refresh model: <data refresh khi nào, vd: mỗi lần open (NO CACHE) / persisted / polling>
74
38
  # - State reset: <state nào reset khi đóng/mở lại, vd: pagination, expand, dropdown selection>
75
-
76
- # === DISPLAY LOGIC MATRIX (optional — bắt buộc nếu display logic phụ thuộc ≥2 dimension, B.1.7) ===
77
- # Enumerate full matrix N×M case + map mỗi case → SC.
78
- # Tên SC theo pattern: `<cấu trúc>: <outcome>` — KHÔNG dùng "(Case X)" suffix.
79
- # VD ma trận `{số thuộc tính: 0/1/≥2} × {số đơn vị tính: 0/1/≥2}` = 9 case:
80
39
  #
81
- # | # | Dim1 | Dim2 | Format hiển thị | SC |
82
- # |---|------|------|----------------------------------------------|------|
83
- # | 1 | 0 | 0 | `Tên hàng` | SC{} |
84
- # | 2 | 0 | 1 | `Tên hàng (đơn vị)` | SC{} |
85
- # | ... | ... | ... | ... | ... |
86
-
87
- # === DICTIONARY REFERENCES (R3 + C.4) ===
88
- # Liệt kê các term từ business-dictionary.md mà feature này dùng → pointer cho reviewer auto-check.
89
- # Banned terms (xem business-dictionary.md § Banned Terms) MUST NOT appear: 0 match khi grep.
90
- #
91
- # Terms dùng trong feature này:
92
- # - <Term 1> (xem dictionary line {N})
93
- # - <Term 2> (xem dictionary line {M})
94
- # - ...
95
-
96
- Feature: <Tên tính năng bằng tiếng Việt>
97
- Với vai trò là <vai trò>
98
- Tôi muốn <hành động>
99
- Để <lợi ích nghiệp vụ>
100
-
101
- # --- DATASET REFERENCE CONVENTION ---
102
- # Ưu tiên dùng ALIAS (tiếng Việt) thay vì ID kỹ thuật, để BDD dễ đọc.
103
- # Backtick ID chỉ dùng khi cần precision (vd: assertion về mã đơn).
104
- #
105
- # Ví dụ:
106
- # ✅ Given đơn hàng draft "Đơn COD giao hàng — 2× áo + 1× quần, total 650K"
107
- # ✅ Then đơn được gán mã `ZMA{id}` nhận từ Retail
108
- # ❌ Given đơn hàng draft là `ORD_COD_DRAFT_001` ← khó đọc, hạn chế
40
+ # --- Display Logic Matrix (tùy chọn BẮT BUỘC nếu display logic phụ thuộc ≥2 chiều; Pre-merge yêu cầu) ---
41
+ # Liệt kê đủ ma trận N×M case + map mỗi case → SC. Tên SC theo pattern `<cấu trúc>: <outcome>` (KHÔNG dùng "(Case X)").
42
+ # | # | Dim1 | Dim2 | Format hiển thị | SC |
43
+ # |---|------|------|------------------------|------|
44
+ # | 1 | 0 | 0 | `Tên hàng` | SC{} |
45
+ # | 2 | 0 | 1 | `Tên hàng (đơn vị)` | SC{} |
46
+ # | ... | ... | ... | ... | ... |
47
+
48
+ Feature: <Feature name>
49
+ As a <role>
50
+ I want to <action>
51
+ So that <business value>
109
52
 
110
53
  Background:
111
- Given <điều kiện tiên quyết chung — dùng alias từ dataset>
112
- # Ví dụ: Given consumer "Khách mới đã cấp quyền Zalo" ở màn "Xác nhận đơn hàng"
113
- # của gian hàng "Cửa hàng Thời Trang (đang kích hoạt)"
114
-
115
- # ============================================================
116
- # § NHÓM GROUPING CONVENTION (C.5 — bắt buộc cho mọi feature ≥3 SCs)
117
- # ============================================================
118
- # Mục đích: organize scenarios theo CHỦ ĐỀ NGHIỆP VỤ để dễ navigate + scope-awareness, KHÔNG
119
- # theo phân loại happy/negative/edge (deprecated section markers HAPPY-PATH / NEGATIVE-CASE / EDGE-CASE).
120
- #
121
- # Quy tắc:
122
- # 1. **Gom theo chủ đề business** — mỗi NHÓM = 1 business theme (flow / state / behavior subset).
123
- # ✅ NHÓM 1: Khởi tạo gian hàng thành công với dữ liệu mặc định (BR1, BR2)
124
- # ✅ NHÓM 2: Resume khi onboarding bị gián đoạn (BR1 resume)
125
- # ✅ NHÓM 3: Xử lý lỗi khởi tạo (BR3)
126
- # ❌ NHÓM 1: HAPPY-PATH ← chia theo loại path, không phải chủ đề
127
- # ❌ NHÓM 1: COD scenarios ← UI feature, không phải business theme
128
- #
129
- # 2. **Mỗi NHÓM có thể chứa cả @happy + @edge + @negative SCs cùng chủ đề** — KHÔNG tách happy/edge ra 2 NHÓM riêng.
130
- # Ví dụ: NHÓM "Xử lý lỗi khi khởi tạo" chứa SC happy retry + SC edge X close + SC negative no retry.
131
- # Tag taxonomy (@happy/@edge/@cross-system per B.2.3) áp dụng ở SC level — KHÔNG ở NHÓM level.
132
- #
133
- # 3. **Format NHÓM header** (3 dòng comment box):
134
- # # ==========================================================
135
- # # NHÓM N: <Chủ đề> (<BR refs nếu áp dụng>)
136
- # # ==========================================================
137
- # Indent 2 spaces (cùng level với Background + Scenario).
138
- #
139
- # 4. **Đánh số NHÓM tuần tự** từ 1 → N. Không skip số. Reorder NHÓM được — KHÔNG ảnh hưởng SC IDs.
140
- #
141
- # 5. **SC trong NHÓM KHÔNG cần theo thứ tự ID** — VD NHÓM 2 có thể chứa SC8, SC4, SC11 nếu cùng chủ đề.
142
- # SC IDs tuần tự theo lifecycle (skill §3.4), KHÔNG theo NHÓM ordering.
143
- #
144
- # 6. **Khi nào skip NHÓM**: feature có <3 SCs → có thể bỏ NHÓM headers (không value to organize so few).
145
- # Đơn giản đặt SCs nối tiếp sau Background. Feature ≥3 SCs → BẮT BUỘC NHÓM.
146
- #
147
- # Pattern thường gặp (gợi ý theme — tuỳ chỉnh per UC):
148
- # - "Khởi tạo / Lưu thành công — các tổ hợp data hợp lệ" (gom happy + alternative)
149
- # - "Validation / Chặn lưu khi không hợp lệ" (gom negative + edge validation)
150
- # - "Xử lý lỗi — API fail / system error" (gom negative + recovery)
151
- # - "Hủy thay đổi / Đóng modal không lưu" (gom edge UX)
152
- # - "Hành vi popup / dialog — multi-select / persist / boundary" (gom edge UX behavior)
153
- # - "Hiệu ứng cross-system / Consumer view" (gom @cross-system SCs)
154
- # - "Idempotency & Concurrency" (gom edge concurrency)
155
- # - "State transition / Recovery completion" (gom @cross-UC behavior chains)
156
- #
157
- # Ví dụ NHÓM structure cho UC có 9 SCs (LOYAL-32-UC1 reference):
158
- # NHÓM 1: Lưu cấu hình thành công — các tổ hợp PTTT hợp lệ (BR1, BR2) → SC1, SC2, SC3, SC4
159
- # NHÓM 2: Chặn lưu khi cấu hình không hợp lệ (BR1, BR2) + lỗi hệ thống → SC5, SC6, SC7
160
- # NHÓM 3: Hủy thay đổi — đóng Modal không lưu → SC8
161
- # NHÓM 4: Initial State — Modal phản ánh cấu hình hiện tại → SC10
54
+ Given <precondition dùng chung — dùng alias từ dataset, không phải ID kỹ thuật>
162
55
 
163
56
  # ==========================================================
164
- # NHÓM 1: <Chủ đề business 1> (<BR refs nếu cần>)
57
+ # NHÓM 1: <Business theme> (<BR refs>)
165
58
  # ==========================================================
166
59
 
167
- # Side-effects: <liệt kê NGẮN GỌN các hậu quả Then phải verify — 1 dòng>
168
- # @trace.scenario: {TICKET_ID}-UC{N}-SC1
60
+ # Side-effects: <liệt kê ngắn các Then side-effect cần verify>
61
+ # @trace.scenario: {TICKET-ID}-UC{N}-SC1
169
62
  # @trace.sc_version: 1.0
170
- # @trace.business_rules: {TICKET_ID}-UC{N}-BR{M}
63
+ # @trace.business_rules: {TICKET-ID}-UC{N}-BR1
171
64
  @happy
172
-
173
- Scenario: < tả luồng chính dùng động từ CHÍNH XÁC (tạo/nhận/gán/đồng bộ)>
174
- Given <state đầu vào — dùng alias từ dataset, vd: "Đơn COD giao hàng — 2× áo + 1× quần">
175
- When <hành động duy nhất>
176
- Then <kết quả chính dùng backtick ID khi cần precision, vd: mã `ZMA{id}`>
177
- And <side-effect 1 đã khai báo ở header>
178
- And <side-effect 2 đã khai báo ở header>
179
- # ... đủ với danh sách Side-effects ở trên (Rule R2)
65
+ Scenario: <mô tả business outcome — dùng động từ chính xác: create/receive/assign/block>
66
+ Given <input statealias từ dataset>
67
+ When <single action>
68
+ Then <main observable outcome>
69
+ And <side-effect 1 khai báo trong header>
180
70
 
181
71
  # Side-effects: <...>
182
- # @trace.scenario: {TICKET_ID}-UC{N}-SC2
72
+ # @trace.scenario: {TICKET-ID}-UC{N}-SC2
183
73
  # @trace.sc_version: 1.0
184
- # @trace.business_rules: {TICKET_ID}-UC{N}-BR{M}
74
+ # @trace.business_rules: {TICKET-ID}-UC{N}-BR1
185
75
  @happy @alternative
186
-
187
- Scenario: <Cùng chủ đề NHÓM 1 nhưng path khác — vd enum value khác (Rule R4 enum symmetry)>
188
- Given <state đầu vào>
189
- When <hành động>
190
- Then <kết quả>
76
+ Scenario: <cùng theme NHÓM 1 nhưng path khác — vd: giá trị enum khác>
77
+ Given <state>
78
+ When <action>
79
+ Then <outcome>
191
80
 
192
81
  # ==========================================================
193
- # NHÓM 2: <Chủ đề business 2 — VD: Xử lý lỗi / Validation> (<BR refs>)
82
+ # NHÓM 2: <Business theme 2> (<BR refs>)
194
83
  # ==========================================================
195
84
 
196
85
  # Side-effects: <...>
197
- # @trace.scenario: {TICKET_ID}-UC{N}-SC3
86
+ # @trace.scenario: {TICKET-ID}-UC{N}-SC3
198
87
  # @trace.sc_version: 1.0
199
- # @trace.business_rules: {TICKET_ID}-UC{N}-BR{M}
88
+ # @trace.business_rules: {TICKET-ID}-UC{N}-BR2
200
89
  @edge
90
+ Scenario: <scenario boundary / error>
91
+ Given <state>
92
+ When <action>
93
+ Then <expected error handling>
201
94
 
202
- Scenario: <Tình huống biên / lỗi cùng chủ đề NHÓM 2>
203
- Given <state đầu vào>
204
- When <hành động>
205
- Then <xử lý lỗi mong đợi>
206
-
207
- # ==========================================================
208
- # NHÓM 3: <Chủ đề business 3 — VD: Cross-system / Hiệu ứng downstream> (<BR refs>)
209
- # ==========================================================
210
-
211
- # Side-effects: <...>
212
- # @trace.scenario: {TICKET_ID}-UC{N}-SC4
213
- # @trace.sc_version: 1.0
214
- # @trace.business_rules: {TICKET_ID}-UC{N}-BR{M}
215
- @happy @cross-system
216
-
217
- Scenario: <Scenario span ≥2 service hoặc hiệu ứng đồng bộ cross-UC>
218
- Given <state đầu vào>
219
- When <hành động>
220
- Then <kết quả tại service A>
221
- And <kết quả đồng bộ sang service B>
222
-
223
- # === TECHNICAL HINTS (optional, giúp AI gen code chính xác hơn) ===
224
- # Dependencies: <UC/service phụ thuộc, vd: LOYAL-28 upstream>
225
- # Entities: <Entity1, Entity2>
226
- # Events: <EventName> (publish to <topic>)
227
- # Cache: <cache invalidation notes>
228
- # Validation: <validation rules>
229
-
230
- # === PRD COVERAGE (C.1 + C.2 — wireframe action + AC/BR checklist) ===
95
+ # === PRD COVERAGE (C.1 + C.2) ===
231
96
  # AC mapping:
232
97
  # AC1 (...) → SC1, SC2
233
98
  # AC2 (...) → SC3
234
- # BR mapping (mỗi bullet trong BR PHẢI có ≥1 SC — C.2):
235
- # BR1 (...) → SC1
236
- # BR2 (...) → SC1, SC2
237
- # Wireframe mapping (mọi component/action ≥1 SC — C.1):
238
- # Screen "<tên màn>":
239
- # [x] Click "<button A>" → SC1
240
- # [x] Click "<button B>" → SC2
241
- # [ ] Click "<" back → MISSING ← BLOCK MERGE
242
- # Display Logic Matrix mapping (nếu áp dụng B.1.7):
243
- # Case 1 (...) → SC{N}
244
- # Case 2 (...) → SC{N}
245
- # User Flow: <path name> → SC1, SC2, SC3
246
-
247
- # === BUSINESS RULES ===
248
- # {TICKET_ID}-UC{N}-BR1: <mô tả rule>
249
- # {TICKET_ID}-UC{N}-BR2: <mô tả rule>
250
-
251
- # === PRE-MERGE CHECKLIST (auto-verify) ===
252
- # - [ ] Mọi SC Side-effects + @trace.scenario + @trace.sc_version + @trace.ac + @trace.business_rules
253
- # - [ ] Coverage Matrix0 dòng `[ ]` MISSING (C.1)
254
- # - [ ] Mọi AC/BR (kèm từng bullet) map về ≥1 SC (C.2)
255
- # - [ ] CI grep banned terms = 0 match (C.4) xem business-dictionary.md § Banned Terms
256
- # - [ ] Nếu là popup/modal: Popup/Modal Lifecycle khai báo trong BUSINESS DEFINITION (B.2.4)
257
- # - [ ] Nếu display logic ≥2 dimension: Display Logic Matrix enumerated (B.1.7)
258
- # - [ ] Feature ≥3 SCs có NHÓM grouping theo chủ đề business (C.5) — KHÔNG dùng section markers cũ HAPPY-PATH/NEGATIVE-CASE/EDGE-CASE
259
- # - [ ] /review-context score ≥90 (project gate)
99
+ # BR mapping (mỗi bullet PHẢI có ≥1 SC — C.2):
100
+ # {TICKET-ID}-UC{N}-BR1 (...) → SC1, SC2
101
+ # {TICKET-ID}-UC{N}-BR2 (...) → SC3
102
+ # Wireframe mapping (mỗi component/action ≥1 SC — C.1):
103
+ # Screen "<screen name>":
104
+ # [x] <action 1> → SC1
105
+ # [x] <action 2> → SC2
106
+ # [ ] <action 3> → MISSING ← BLOCK MERGE
107
+ # Design Spec coverage (chỉ FE/AppC.1 mở rộng; bỏ khối này nếu không nạp design-spec):
108
+ # Screen "<screen>": loading → SC?, error → SC?, empty → SC?
109
+ # AC-UI behavioral: AC-UI3 (lỗi+khôi phục) → SC?, AC-UI4 (empty CTA) → SC?
110
+ # (bỏ AC-UI visual thuần: AC-UI1 khớp Figma, AC-UI5 WCAG — Designer/QA review riêng)
111
+
112
+ # === PRE-MERGE CHECKLIST ===
113
+ # - [ ] Mỗi SC có Side-effects + @trace.scenario + @trace.sc_version + @trace.business_rules
114
+ # - [ ] Coverage Matrix: 0 dòng MISSING (C.1)
115
+ # - [ ] FE/App: mỗi Screen State (≠default) + AC-UI behavioral của design-spec có ≥1 SC (C.1 mở rộng)
116
+ # - [ ] Mỗi AC/BR map tới ≥1 SC (C.2)
117
+ # - [ ] 0 banned term (C.4) grep file trước khi merge
118
+ # - [ ] Feature ≥3 SC NHÓM grouping theo business theme (C.5)
119
+ # - [ ] Nếu popup/modal: khai báo Popup/Modal Lifecycle trong BUSINESS DEFINITION
120
+ # - [ ] Nếu display logic ≥2 chiều: Display Logic Matrix trong BUSINESS DEFINITION
@@ -69,6 +69,8 @@
69
69
 
70
70
  ## b. Phạm vi
71
71
 
72
+ > **Scope = ranh giới, KHÔNG phải đặc tả.** Mỗi mục một dòng ngắn "làm gì / không làm gì". Đừng nhét **cơ chế** (retry/timeout/nhánh lỗi → BR/BL) hay **định nghĩa thuật ngữ** (vd "điểm khởi tạo = …" → Business Definition / business-dictionary) vào đây.
73
+
72
74
  **In Scope**
73
75
  - {hạng mục trong phạm vi 1}
74
76
  - {hạng mục trong phạm vi 2}
@@ -87,10 +89,14 @@
87
89
  # 2. Acceptance Criteria
88
90
 
89
91
  > Mỗi AC kế thừa liên kết "Bắt nguồn từ BR" của Product Definition (Phase 6), remap sang BR ID của PRD. Vì BR ID đã chứa số UC nên ref BR truy ngược được tới đúng UC.
92
+ >
93
+ > **1 AC = 1 tiêu chí NGHIỆM THU (outcome quan sát/kiểm được) + ref BR.** KHÔNG viết cơ chế trong AC (số lần retry, timeout, tên/chủ cờ, nhánh lỗi chi tiết) — cái đó thuộc **BR/BL** ở §3, AC chỉ trỏ tới. Nếu tiêu chí có **nhiều nhánh** → tách **bullet con** (mỗi ý một dòng), đừng dồn thành câu dài. Khi `/refine-prd` làm rõ thêm: chi tiết cơ chế → đẩy sang BR/BL; ở tầng AC thì tách bullet/AC mới — KHÔNG nối mệnh đề vào câu cũ (tránh AC thành "đoạn văn" và trùng BR).
90
94
 
91
95
  **AC1:** {Tiêu chí nghiệm thu, văn xuôi, kiểm chứng được.} _(BR: {TICKET}-{N}-UC{n}-BR{m})_
92
96
 
93
- **AC2:** {} _(BR: {TICKET}-{N}-UC{n}-BR{m})_
97
+ **AC2:** {Tiêu chí có nhiều nhánh — tách bullet:} _(BR: {TICKET}-{N}-UC{n}-BR{m})_
98
+ - {nhánh/điều kiện 1 → kết quả kỳ vọng}
99
+ - {nhánh/điều kiện 2 → kết quả kỳ vọng}
94
100
 
95
101
  ---
96
102
 
@@ -35,7 +35,7 @@ paths:
35
35
  # prd-slug is derived from the PRD folder path — not a separate config variable.
36
36
  specs_dir: "specs"
37
37
  templates_dir: "specs/templates"
38
- feature_template: "specs/templates/feature.template"
38
+ feature_template: ".agent/templates/feature.template" # SoT skeleton .feature (dùng bởi /generate-bdd qua {{include}})
39
39
  bdd_writing_guide: "specs/templates/bdd-writing-guide.md"
40
40
  trace_report: "specs/.trace/trace-report.md"
41
41