spec-lite 1.4.0 → 1.4.2

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.
package/README.md CHANGED
@@ -22,11 +22,14 @@ Chạy một lần để bootstrap main artifacts, sau đó vào Integration Pip
22
22
  /spec-prd → /spec-sad
23
23
 
24
24
 
25
+ /spec-frd [F-XXX] (tùy chọn — BA author frd.md trước, spec-first)
26
+
27
+
25
28
  Integration Pipeline
26
29
  ```
27
30
 
28
31
  #### `/spec-prd`
29
- Tạo hoặc cập nhật `specs/main/prd.md` thông qua interview có cấu trúc. Đồng thời scaffold `specs/main/domain.md` skeleton.
32
+ Tạo hoặc cập nhật `specs/main/prd.md` thông qua interview có cấu trúc. Đồng thời scaffold `specs/main/domain.md` skeleton. Nhận tùy chọn một nguồn baseline (path/@file/paste proposal/BRD) để pre-fill interview.
30
33
 
31
34
  Sections: Problem Statement · Target Users · Scope · Features · Components · Non-Functional Requirements · Business Constraints
32
35
 
@@ -35,6 +38,15 @@ Tạo hoặc cập nhật `specs/main/sad.md`. Yêu cầu `prd.md` và `domain.m
35
38
 
36
39
  Sections: Architectural Style · System Overview · Tech Stack · Cross-Cutting Concerns · Inter-Service Communication · Infrastructure Overview · Architectural Guardrails
37
40
 
41
+ #### `/spec-frd [F-XXX]` *(tùy chọn)*
42
+ BA author `specs/main/feature/{F-XXX}-*/frd.md` trực tiếp qua interview, **trước** khi DEV bắt đầu integration — spec-first ở feature level. Cặp greenfield đối xứng với `/spec-brownfield-feature`. Nhận F-XXX (hoặc chọn từ Feature Index) + tùy chọn nguồn baseline (path/@file/paste).
43
+
44
+ **Hai gate input (làm chặt):** (1) **Single-feature** — nguồn liên quan đúng 1 feature; xác định >1 → dừng, mô tả rõ lý do tách, redirect `/spec-prd`. (2) **Create-only** — frd.md đã tồn tại → dừng, redirect `/spec-new` (thay đổi feature đã spec đi qua integration để delta cascade + tech/test). Feature mới đơn lẻ chưa có trong Index → skill offer **register một row vào prd Features** rồi author.
45
+
46
+ Phạm vi hẹp: **chủ yếu frd.md** (+ tối đa một feature row vào prd nếu register). Reference component frd phụ thuộc (Components Used); component cần-nhưng-chưa-có ghi như *candidate* để `/spec-sad`/architect chốt boundary. **KHÔNG** tạo `crd.md`/`cdd.md` — component artifacts sinh ở integration time qua `/spec-new` cascade. Change History operation = `manual`. Nếu bỏ qua bước này, `/spec-new` vẫn tự tạo frd làm fallback.
47
+
48
+ Sections: Overview · User Flows · Feature Acceptance Criteria · User Stories · Verification Rules · Scope · Dependencies
49
+
38
50
  ---
39
51
 
40
52
  ## Brownfield — project đã có code
@@ -152,6 +164,7 @@ Pre-flight yêu cầu git working tree clean — rollback dùng `git checkout --
152
164
  |---------|--------|
153
165
  | `/spec-prd` | `specs/main/prd.md`, `specs/main/domain.md` (skeleton) |
154
166
  | `/spec-sad` | `specs/main/sad.md` |
167
+ | `/spec-frd` | `specs/main/feature/{F-XXX}-*/frd.md` *(+ register feature row vào `prd.md` nếu feature mới)* |
155
168
  | `/spec-brownfield-init` | `specs/main/prd.md`, `specs/main/domain.md`, `specs/main/sad.md` |
156
169
  | `/spec-brownfield-component` | `specs/main/component/{C-XXX}-*/crd.md + cdd.md` |
157
170
  | `/spec-brownfield-feature` | `specs/main/feature/{F-XXX}-*/frd.md + fdd.md` |
@@ -165,4 +178,4 @@ Pre-flight yêu cầu git working tree clean — rollback dùng `git checkout --
165
178
  | `/review-integration` | *(findings report — không tạo file)* |
166
179
  | `/review-everything` | `specs/integrations/{NNN}-{slug}/review-findings.md` *(qua /spec-new)* |
167
180
 
168
- Component feature artifacts trong greenfield mọc dần qua **cascade proposals** từ integrations — không có skill chuyên biệt để tạo.
181
+ Feature artifacts (`frd.md`) greenfield có thể author trước bằng `/spec-frd`, hoặc mọc dần qua **cascade proposals** từ integrations (`/spec-new` fallback). Component artifacts (`crd.md`/`cdd.md`) ở greenfield chỉ mọc qua cascade — không có skill author trực tiếp (`/spec-frd` chỉ reference component, không tạo crd/cdd).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-lite",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Spec-driven development kit for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,311 @@
1
+ ---
2
+ name: spec-frd
3
+ description: Author MỚI frd.md (Feature Requirements Document) trực tiếp ở feature level qua interview. Role BA, chạy trước integration. CREATE-only, đúng một feature/lần: frd đã tồn tại → redirect /spec-new (delta cascade); nguồn nhiều feature → redirect /spec-prd. Nhận F-XXX từ argument (hoặc chọn từ prd Feature Index) + tùy chọn nguồn baseline (path/@file/paste). Chỉ author frd.md (+ register feature row vào prd nếu feature mới) — reference component, KHÔNG tạo crd/cdd.
4
+ ---
5
+
6
+ # spec-frd
7
+
8
+ ## Overview
9
+
10
+ Author `specs/main/feature/{F-XXX}-{feature-slug}/frd.md` trực tiếp qua interview — **spec-first ở feature level**, do **BA** chạy trước khi bất kỳ integration nào bắt đầu.
11
+
12
+ `frd.md` là **what to build** của một feature: Overview, User Flows, Feature AC, User Stories, Verification Rules, Scope, Dependencies. Đây là baseline ổn định, **author một lần** — mọi thay đổi sau đó đi qua `/spec-new` (delta cascade).
13
+
14
+ Skill này là cặp greenfield đối xứng với `/spec-brownfield-feature` (vốn reverse-engineer frd từ code). Khác biệt: `/spec-frd` author *forward* từ interview, không scan code.
15
+
16
+ **Hai ràng buộc input (làm chặt):**
17
+ 1. **Đúng một feature mỗi lần chạy** — xác định > 1 feature → DỪNG, mô tả rõ lý do, redirect `/spec-prd` (Bước 1a).
18
+ 2. **CREATE-only** — frd.md đã tồn tại → DỪNG, redirect `/spec-new` để phân tích delta + cascade + downstream (tech/test) (Bước 1c).
19
+
20
+ **Phạm vi hẹp — chủ yếu frd.md:**
21
+ - ✅ Author frd.md (7 sections) cho **một** feature **chưa có frd**.
22
+ - ✅ *Reference* component frd phụ thuộc (Components Used) + ghi component cần-nhưng-chưa-có như **candidate**.
23
+ - ✅ Nếu feature mục tiêu là feature mới chưa có trong Index → **register một row vào `prd.md > Features`** (side-effect hợp lệ duy nhất lên prd).
24
+ - ❌ KHÔNG tạo/sửa `crd.md`/`cdd.md` — component artifacts ra đời ở integration time qua `/spec-new` cascade.
25
+ - ❌ KHÔNG tạo `fdd.md` (inter-component design) hay `tsd.md` (test) — để skill/role khác lo.
26
+ - ❌ KHÔNG đổi status feature đã có, không đụng sad/domain.
27
+
28
+ ## When to Use
29
+
30
+ - Greenfield: BA muốn đặc tả **một feature chưa có frd** *trước* khi DEV bắt đầu integration.
31
+ - `prd.md` đã tồn tại (feature có thể đã trong Index, hoặc là feature mới đơn lẻ → skill offer register vào Index).
32
+
33
+ ## When NOT to Use
34
+
35
+ - `prd.md` chưa có → chạy `/spec-prd` trước.
36
+ - **frd.md đã tồn tại** (thay đổi feature đã spec) → dùng `/spec-new` (delta cascade + tech/test). `/spec-frd` không update frd.
37
+ - **Nguồn trải nhiều feature** → dùng `/spec-prd` để khai Feature Index trước.
38
+ - Brownfield onboarding (reverse-engineer từ code) → dùng `/spec-brownfield-feature`.
39
+ - Muốn thiết kế technical / inter-component → `/spec-tech` (integration) hoặc fdd qua cascade.
40
+
41
+ ---
42
+
43
+ ## Process
44
+
45
+ ### Bước 0: Nạp nguồn yêu cầu (tùy chọn)
46
+
47
+ Giống `/spec-prd` Bước 0. Xác định có nguồn baseline cho feature không (proposal, mô tả feature, ghi chú họp, wireframe note):
48
+
49
+ 1. **ARGUMENT chứa path / `@file`** → đọc file đó (`.md`/`.txt`/PDF).
50
+ 2. **ARGUMENT chứa text dài (paste)** → dùng làm nguồn.
51
+ 3. **Không có** → hỏi một lần:
52
+ > Bạn có tài liệu/nguồn cho feature này không? Nhập **đường dẫn file**, **paste nội dung**, hoặc `không` để interview từ đầu.
53
+
54
+ Lưu ý: ARGUMENT thường vừa chứa **F-XXX** (Bước 1) vừa có thể kèm path — tách hai phần. Nếu chỉ có F-XXX thì hỏi nguồn như trên.
55
+
56
+ Có nguồn → trích baseline cho từng section frd (overview, flows, stories, AC, rules, scope, dependencies). Đánh dấu cái nào trích được, cái nào nguồn không đề cập. Áp **quy tắc baseline** giống `/spec-prd`: reuse những gì có; validate; phần thiếu mới hỏi.
57
+
58
+ ---
59
+
60
+ ### Bước 1: Xác định feature
61
+
62
+ **Precondition:** đọc `specs/main/prd.md`. Nếu không tồn tại / template rỗng → dừng:
63
+ > `prd.md` chưa có nội dung. Hãy chạy `/spec-prd` trước.
64
+
65
+ `/spec-frd` là skill **CREATE-only, đúng một feature mỗi lần chạy**. Xác định feature mục tiêu qua ba gate — phải pass cả ba mới vào interview.
66
+
67
+ #### 1a. Single-feature gate — chỉ liên quan đúng 1 feature
68
+
69
+ Đánh giá ARGUMENT + nguồn baseline mô tả **bao nhiêu feature riêng biệt** — mỗi feature = một outcome/luồng nghiệp vụ độc lập (dùng litmus test trong `/spec-prd`).
70
+
71
+ - **Xác định > 1 feature** → **DỪNG** và **mô tả rõ lý do** tại sao là nhiều feature, không chỉ báo chung chung:
72
+ > Mình xác định nguồn này trải **{N} feature** riêng biệt:
73
+ > 1. {tên feature A} — outcome: {…}; persona: {…}; luồng: {…}
74
+ > 2. {tên feature B} — outcome: {…}; persona: {…}; luồng: {…}
75
+ > Lý do tách: {mỗi cái có outcome/luồng độc lập, không phải biến thể của cùng một luồng — chiếu litmus test}.
76
+ >
77
+ > `/spec-frd` chỉ author một feature mỗi lần. Hãy chạy `/spec-prd` để khai {N} feature này vào Feature Index trước, rồi chạy `/spec-frd F-XXX` cho từng cái.
78
+
79
+ (Nếu có F-XXX chỉ định nhưng nguồn vẫn trải nhiều feature → vẫn dừng và mô tả lý do; không tự ý cắt phần thuộc F-XXX, vì BA cần thấy bức tranh đầy đủ để khai Index.)
80
+ - **Đúng 1 feature** → tiếp 1b.
81
+
82
+ #### 1b. Resolve feature mục tiêu
83
+
84
+ - **F-XXX có trong Feature Index** → dùng.
85
+ - **Feature mới — KHÔNG có trong Index** (đúng một) → **offer register**:
86
+ > Feature "{tên}" chưa có trong prd Feature Index. Mình sẽ thêm vào Index rồi author frd:
87
+ > F-{auto next} | {tên} | {mô tả 1 câu} | {priority?} | TODO
88
+ > Đồng ý? [y / sửa / n]
89
+ - `y` → auto-pick `F-XXX` = max(seq)+1 trong Index; **giữ lại để Bước 7 ghi row `[NEW]` vào prd + Change History**.
90
+ - `n` → dừng, gợi ý `/spec-prd` để khai feature trước.
91
+ - **Không có F-XXX và không có nguồn** → hiển thị Feature Index để chọn (chỉ feature **chưa có frd.md**):
92
+
93
+ ```
94
+ Features chưa có frd.md:
95
+
96
+ [1] F-001 — Authentication (High) [TODO]
97
+ [3] F-003 — App Browsing & Opt-in (High) [TODO]
98
+
99
+ (F-002 đã có frd.md → thay đổi đi qua /spec-new)
100
+
101
+ Chọn feature để author frd:
102
+ ```
103
+
104
+ #### 1c. Create-only gate — frd.md CHƯA tồn tại
105
+
106
+ Kiểm tra `specs/main/feature/{F-XXX}-*/frd.md`.
107
+
108
+ - **Chưa tồn tại** → tiếp Bước 2 (author mới).
109
+ - **Đã tồn tại** → **DỪNG**, redirect `/spec-new`:
110
+ > frd.md cho {F-XXX} đã tồn tại. Mọi thay đổi feature đã được spec phải đi qua `/spec-new` — skill đó phân tích delta, cascade lên frd/crd/prd/domain, và kéo theo việc kỹ thuật/test (`/spec-tech`, `/spec-test`).
111
+ > Chạy: `/spec-new {F-XXX}` (hoặc `/spec-new <mô tả thay đổi>`).
112
+
113
+ `/spec-frd` **không** update frd đã có — giữ một làn ghi delta duy nhất (`/spec-new`) để đảm bảo traceability và downstream không bị bỏ sót.
114
+
115
+ ---
116
+
117
+ ### Bước 2: Load context
118
+
119
+ Load:
120
+ - `specs/main/prd.md` — Problem Statement, Target Users (personas), Scope, **row của feature này** trong Feature Index (tên, mô tả, priority), Component Index, **cột ADO** (nếu feature có ticket → lưu lại để spec.md sau này không tạo duplicate).
121
+ - `specs/main/domain.md` — Glossary + Shared Entities liên quan.
122
+ - `specs/main/sad.md` — bảng Components (góc nhìn kiến trúc, để biết C-XXX nào đã có boundary).
123
+ - `specs/main/component/{C-XXX}-*/crd.md` — Public Interface của các component khả năng feature sẽ dùng (nếu đã tồn tại).
124
+
125
+ Tóm tắt context + surface assumptions:
126
+
127
+ ```
128
+ TỪ PRD & DOMAIN TÔI HIỂU:
129
+ - Feature: {F-XXX — tên — mô tả ngắn từ prd} (priority: {...})
130
+ - Vấn đề tổng: {problem statement ngắn}
131
+ - Personas liên quan: {từ Target Users}
132
+ - Glossary/entities liên quan: {từ domain.md}
133
+ - Components có sẵn có thể dùng: {C-XXX — tên}
134
+
135
+ ASSUMPTIONS TÔI ĐANG ĐẶT RA:
136
+ 1. {scope của feature}
137
+ 2. {component feature có thể phụ thuộc}
138
+ → Sửa lại nếu sai trước khi tiếp tục.
139
+ ```
140
+
141
+ ---
142
+
143
+ ### Bước 3: Interview
144
+
145
+ Hỏi tuần tự, từng phần — không hỏi tất cả cùng lúc. Nếu Bước 0 có nguồn → trình bày baseline đã trích rồi xin confirm/sửa; phần nguồn không đề cập mới hỏi từ đầu.
146
+
147
+ **Phần 1 — Overview:**
148
+ > Feature này giải quyết vấn đề gì, cho persona nào? (2-3 câu, góc nhìn user/business)
149
+
150
+ **Phần 2 — User Flows:**
151
+ > User thao tác qua những bước nào để đạt mục tiêu? Có những nhánh edge case / thất bại nào quan trọng?
152
+ > (Mình sẽ vẽ mỗi luồng thành một Mermaid flowchart — happy case + edge cases.)
153
+
154
+ **Phần 3 — User Stories:**
155
+ > Liệt kê các stories ở cấp feature: "{Persona} muốn {hành động} để {mục tiêu}". Mỗi story có priority (Must/Should/Could) và acceptance criteria (Given/When/Then).
156
+
157
+ **Phần 4 — Feature Acceptance Criteria:**
158
+ > Có criteria nào áp cho *toàn* feature mà story lẻ không cover? (e2e liên story, cross-story consistency, NFR như performance/accessibility, data & migration)
159
+ > Mỗi cái Given/When/Then, **Then phải đo được**.
160
+
161
+ **Phần 5 — Verification Rules:**
162
+ > Với mỗi input field trong các stories, mình sẽ suggest 2-4 phương án validation để BA chọn (xem "Verification Rules — quy ước sinh" bên dưới). BA là người quyết định.
163
+
164
+ **Phần 6 — Scope:**
165
+ > Feature này làm gì (In Scope)? Có gì liên quan nhưng KHÔNG làm (Out of Scope) + lý do?
166
+
167
+ **Phần 7 — Dependencies:**
168
+ > - **Feature dependencies:** feature này cần feature nào xong trước, hay chạy song song?
169
+ > - **Components Used:** feature này dùng component nào? (Mình sẽ map sang C-XXX có sẵn; component cần-nhưng-chưa-có sẽ ghi như candidate — xem Bước 4.)
170
+
171
+ Câu trả lời vague → hỏi lại để làm rõ (ngưỡng đo được, field cụ thể, nhánh xử lý).
172
+
173
+ ---
174
+
175
+ ### Bước 4: Xử lý component (mức reference + candidate)
176
+
177
+ `/spec-frd` **không carve component**. Chỉ làm hai việc:
178
+
179
+ 1. **Component đã có C-XXX** (trong prd Component Index) → ghi vào `Dependencies > Components Used` với vai trò trong feature.
180
+
181
+ 2. **Component feature cần nhưng chưa có** → KHÔNG tạo crd/cdd, KHÔNG tự thêm vào prd Component Index. Thay vào đó:
182
+ - Ghi trong Components Used với **tên đề xuất** + flag `(candidate — chưa carve)`.
183
+ - Thêm một mục vào draft **Open Questions** (hoặc note cuối draft) để `/spec-sad`/architect chốt boundary, hoặc `/spec-new` formal-register + tạo crd/cdd ở integration time.
184
+
185
+ Lý do: giữ **một authority duy nhất** cho việc carve component (architect qua `/spec-sad`, hoặc cascade qua `/spec-new`). BA chỉ khai báo *nhu cầu*, không quyết boundary. (Xem quy tắc Given/Derived trong `/spec-prd`.)
186
+
187
+ ---
188
+
189
+ ### Bước 5: Write — sinh draft
190
+
191
+ Dùng `.claude/templates/main/feature/frd-template.md` làm skeleton, điền nội dung từ interview.
192
+
193
+ **ID assignment** (luôn là create — frd mới): US `US-F{NNN}-001+`, Story AC `AC-F{NNN}-001+`, Feature AC `FAC-F{NNN}-001+` (counter độc lập với Story AC), VR `VR-F{NNN}-001+`. `NNN` = số của F-XXX. Flow đánh số từ 1.
194
+
195
+ **Frontmatter** frd mới: theo template, `status: draft`, `owner: BA`, `feature_id: F-XXX`.
196
+
197
+ Hiển thị **toàn bộ draft** cho user — chưa ghi file. Kèm danh sách component candidate (nếu có) và VR còn `TBD`.
198
+
199
+ #### Verification Rules — quy ước sinh
200
+
201
+ Áp dụng khi sinh section Verification Rules. **Tái dùng nguyên quy ước của `/spec-new`** (xem [spec-new SKILL.md](../spec-new/SKILL.md) → "Verification Rules — quy ước sinh"). Tóm tắt:
202
+
203
+ - VR là **business decision — BA owns**. Agent đóng vai **option-suggester**, KHÔNG tự assert rule.
204
+ - Mỗi input field → suggest 2-4 phương án validation + luôn có `Custom` và `TBD`.
205
+ - BA chọn → auto-assign `VR-F{NNN}-{seq}`. `TBD` → vẫn assign ID, ghi `TBD` ở cột Rule, list ra cuối draft.
206
+ - **Cấm:** tự điền rule chưa hỏi BA; đưa regex/validator/error message vào bảng (đó là HOW/UI copy); dùng tech type (`varchar(255)`) thay vì semantic type.
207
+ - Heuristic suggest theo field name: xem bảng trong spec-new.
208
+
209
+ ---
210
+
211
+ ### Bước 6: Review — xác nhận với user
212
+
213
+ > Draft frd trên đã đúng chưa?
214
+ > - User Flows có cover đủ happy + edge case không?
215
+ > - User Stories + AC đo được chưa?
216
+ > - Verification Rules đã confirm với BA chưa (không còn TBD ngoài ý muốn)?
217
+ > - Components Used đúng chưa? Component candidate (nếu có) có hợp lý để chuyển cho /spec-sad không?
218
+
219
+ Chỉ ghi file sau khi user confirm. Yêu cầu chỉnh → cập nhật draft → hỏi lại.
220
+
221
+ ---
222
+
223
+ ### Bước 7: Save
224
+
225
+ **7a. Ghi `specs/main/feature/{F-XXX}-{slug}/frd.md`** — tạo thư mục nếu chưa có. Status `draft` (lifecycle riêng của artifact).
226
+
227
+ Slug feature lấy từ tên trong prd Feature Index, kebab-case (ví dụ F-001 "Authentication" → `F-001-authentication`).
228
+
229
+ **7b. Append Change History entry** vào `## Change History` cuối frd.md — operation = `manual` (author trực tiếp, không qua integration; cùng quy ước với brownfield skills, theo `conventions.md` §5.5):
230
+
231
+ ```markdown
232
+ ### {YYYY-MM-DD} — manual — create
233
+
234
+ - **All sections**: initial feature authoring qua /spec-frd
235
+ ```
236
+
237
+ (Luôn là `create` — `/spec-frd` không update frd đã có; thay đổi đi qua `/spec-new`.)
238
+
239
+ **7b'. (Chỉ khi Bước 1b register feature mới)** Ghi row `[NEW]` vào `prd.md > Features`:
240
+
241
+ ```
242
+ F-{XXX} | {tên} | {mô tả 1 câu} | {priority} | TODO
243
+ ```
244
+
245
+ Và append Change History entry vào prd.md (theo `conventions.md` §5.5):
246
+
247
+ ```markdown
248
+ ### {YYYY-MM-DD} — manual — update
249
+
250
+ - **Features**:
251
+ - [NEW] F-XXX — {tên} (registered qua /spec-frd)
252
+ ```
253
+
254
+ Đây là **side-effect hợp lệ duy nhất** của `/spec-frd` lên prd — thêm một feature row. Việc này atomic với 7a/7b: nếu fail thì rollback cả frd.
255
+
256
+ **7c. KHÔNG đụng gì khác.** Không đổi status của các feature *đã có* (frd tồn tại ≠ integration bắt đầu; marker "→ frd.md tồn tại" derive từ file existence). Không thêm component vào Index (chỉ candidate). Không tạo crd/cdd/fdd/tsd. Không đụng sad/domain.
257
+
258
+ **7d. Thông báo kết quả:**
259
+
260
+ ```
261
+ ✓ specs/main/feature/{F-XXX}-{slug}/frd.md đã được tạo (status: draft)
262
+
263
+ {nếu có} Component candidate cần carve (chuyển cho architect / integration):
264
+ - {tên đề xuất} — {vai trò}
265
+
266
+ {nếu có} Verification Rules còn TBD:
267
+ - VR-F{NNN}-{seq} — {field}
268
+
269
+ Bước tiếp theo:
270
+ - /spec-tsd F-XXX → QC bootstrap test spec từ frd này
271
+ - /spec-new F-XXX → DEV bắt đầu integration (frd sẽ được consume, crd/cdd sinh qua cascade)
272
+ {nếu có candidate} - /spec-sad → architect chốt boundary cho component candidate
273
+ ```
274
+
275
+ ---
276
+
277
+ ## Common Rationalizations
278
+
279
+ | Rationalization | Reality |
280
+ | --- | --- |
281
+ | "Để /spec-new tự đẻ frd cho nhanh" | frd là *feature requirements* — việc của BA. Để integration đẻ ra = DEV phải đoán yêu cầu. |
282
+ | "BA cứ tạo luôn crd cho component cần" | Carve component là quyết định kiến trúc. BA tạo crd sớm = boundary sai sớm. Chỉ reference. |
283
+ | "Verification rule mình tự điền cho nhanh" | VR là business decision. Agent tự assert = rule sai mà không ai review. |
284
+ | "User Flows vẽ sau cũng được" | Flow buộc phải nghĩ edge case. Không có flow = AC thiếu nhánh thất bại. |
285
+
286
+ ## Red Flags
287
+
288
+ - frd dùng từ không đo được trong AC ("hoạt động đúng", "nhanh", "đẹp")
289
+ - User Stories không có persona rõ hoặc không có AC
290
+ - Verification Rules tự điền mà chưa hỏi BA
291
+ - Tạo crd.md/cdd.md (vượt phạm vi — đó là integration time)
292
+ - Component candidate không được surface cho architect
293
+ - **Update frd đã tồn tại** thay vì redirect `/spec-new` (vi phạm CREATE-only)
294
+ - Cắt phần thuộc một F-XXX từ nguồn nhiều feature thay vì dừng + mô tả lý do
295
+
296
+ ## Verification
297
+
298
+ - [ ] `prd.md` tồn tại
299
+ - [ ] **Single-feature gate**: nguồn liên quan đúng 1 feature; nếu >1 đã DỪNG và mô tả rõ lý do tách + redirect `/spec-prd`
300
+ - [ ] **Create-only gate**: frd.md của feature mục tiêu CHƯA tồn tại; nếu đã có đã redirect `/spec-new`
301
+ - [ ] Feature mục tiêu có trong Index, HOẶC feature mới đơn lẻ đã được user đồng ý register (Bước 1b)
302
+ - [ ] frd.md có đủ 7 sections (luôn create mới)
303
+ - [ ] Mỗi User Story có persona + priority + ít nhất 1 AC Given/When/Then
304
+ - [ ] Feature AC dùng ID `FAC-F{NNN}-{seq}` (counter độc lập với `AC-F{NNN}`), Then đo được
305
+ - [ ] Verification Rules đã confirm với BA (không tự assert); không chứa regex/code/error message; semantic type
306
+ - [ ] ID bắt đầu từ 001 (create mới)
307
+ - [ ] Components Used reference C-XXX có sẵn; component mới ghi candidate + surface cho /spec-sad
308
+ - [ ] Nếu register feature mới: prd Features có row [NEW] + Change History entry; status feature đã có KHÔNG đổi
309
+ - [ ] KHÔNG tạo crd/cdd/fdd/tsd; KHÔNG đụng sad/domain
310
+ - [ ] Change History entry operation = `manual` (luôn `create`)
311
+ - [ ] User đã confirm trước khi ghi file
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spec-prd
3
- description: Điền hoặc cập nhật prd.md — Product Requirements Document ở product level. Cũng scaffold domain.md skeleton (glossary placeholder + Shared Entities rỗng). Dùng khi prd.md còn là template rỗng hoặc cần review/cập nhật.
3
+ description: Điền hoặc cập nhật prd.md — Product Requirements Document ở product level. Nhận tùy chọn một nguồn yêu cầu (đường dẫn file/@file hoặc paste proposal/BRD/ghi chú) làm baseline để pre-fill interview. Cũng scaffold domain.md skeleton (glossary placeholder + Shared Entities rỗng). Dùng khi prd.md còn là template rỗng hoặc cần review/cập nhật.
4
4
  ---
5
5
 
6
6
  # spec-prd
@@ -26,8 +26,96 @@ PRD không chứa: tech stack, implementation details, entity schema, glossary,
26
26
 
27
27
  ---
28
28
 
29
+ ## Khái niệm: Feature vs Component
30
+
31
+ Section này là nền tảng để điền **Phần 4 (Features)** và **Phần 5 (Components)**. Đọc trước khi interview.
32
+
33
+ ### Nguyên tắc gốc
34
+
35
+ **Component là đơn vị ownership; Feature là đơn vị delivery.** Component bền vững theo thời gian; Feature là một luồng nghiệp vụ consume một hoặc nhiều component. Quan hệ giữa hai khái niệm là **N–N** — không mechanical-derive cái này từ cái kia.
36
+
37
+ ### Litmus test — phân loại một mục là Feature hay Component
38
+
39
+ Chạy qua các phép thử; đa số phiếu nghiêng đâu thì xếp vào đó:
40
+
41
+ | Phép thử | → Component | → Feature |
42
+ | --- | --- | --- |
43
+ | **Ownership** (quan trọng nhất) | Sở hữu entity + rule + interface | Điều phối/tiêu thụ dữ liệu & rule của thứ khác |
44
+ | **Lifetime** | Xóa hết luồng nghiệp vụ vẫn còn tồn tại | Bỏ đi, không component nào mất gì |
45
+ | **Hướng cắt** | Ngang — một năng lực dùng lại bởi N luồng | Dọc — UI→logic→data cho một luồng |
46
+ | **Đặt tên** | Danh từ hệ thống (`auth`, `payment`) | Luồng nghiệp vụ (`checkout-flow`, `password-reset`) |
47
+ | **Trả lời** | "Phần nào của hệ thống chịu trách nhiệm X?" | "User làm được gì, nhận giá trị gì?" |
48
+
49
+ ### Quy tắc đặt tên (cho cả Feature và Component)
50
+
51
+ **Goldilocks:** đặt tên ở mức trừu tượng **cao nhất mà vẫn truyền đạt đúng MỘT trách nhiệm/luồng rõ ràng**. Cao hơn → mất boundary; thấp hơn → rò rỉ chi tiết. Tên dùng kebab-case.
52
+
53
+ **Component — theo năng lực bền vững, không theo công nghệ hiện tại:**
54
+ - ✅ `notification`, `auth`, `file-storage`, `payment-gateway`
55
+ - ❌ Quá cụ thể (rò rỉ impl): `email-sender` (mai thêm SMS/push?), `stripe-client`, `s3-uploader`
56
+ - ❌ Quá mơ hồ (mất boundary): `core`, `utils`, `manager`, `engine`, `service`, `data`
57
+ - Phép thử: *"Mai đổi nhà cung cấp / thêm kênh, tên còn đúng không?"* Không → quá cụ thể.
58
+
59
+ **Feature — theo outcome của một luồng hoàn chỉnh:**
60
+ - ✅ `user-registration`, `password-reset`, `checkout`
61
+ - ❌ Quá rộng (thành feature area, ôm nhiều luồng): `user-management`, `account`, `admin`
62
+ - ❌ Quá hẹp (chỉ một biến thể của luồng): `register-with-google`, `reset-password-via-sms-otp`
63
+ - Phép thử: *"Đây là MỘT luồng, hay cái ô chứa nhiều luồng?"* Cái ô → quá rộng.
64
+
65
+ ### Định nghĩa một Component
66
+
67
+ **Một component = một khối có (1) boundary rõ + interface tường minh, và (2) một lý do duy nhất để thay đổi.**
68
+
69
+ - Tính chất (1) là điều kiện *cần*; (2) là guardrail chống "tầng kỹ thuật" lọt vào. "Tầng controller" có boundary rõ nhưng đổi vì N lý do (auth đổi, payment đổi...) → cohesion bằng 0 → **không** phải component.
70
+ - Áp đúng tiêu chí "một lý do thay đổi" thì ranh giới theo capability/domain sẽ **tự hiện ra** — không cần áp luật "phải chia theo domain" từ ngoài vào.
71
+ - Mỗi component đồng thời có **mặt domain** (`crd.md` — WHAT/contract) và **mặt kỹ thuật** (`cdd.md` — HOW/internal design). Đừng phân loại component thành "domain component" hay "kỹ thuật component" — đó chỉ là mô tả *nguồn* cohesion, không phải luật cấu trúc.
72
+
73
+ ### Component nào khai ở PRD? — Logic Given vs Derived
74
+
75
+ Feature Index điền **đầy đủ** ở PRD. Component thì **không** — chỉ khai những component có boundary đã *chín*. Độ chín xác định bằng thủ tục quyết định, không cảm tính.
76
+
77
+ **Litmus gốc:** *"Cùng bộ yêu cầu này, một architect giỏi khác có thể vẽ boundary này khác đi một cách hợp lý không?"* — KHÔNG (bị ép, một cách vẽ) → **Given, khai ở PRD**. CÓ (một lựa chọn đánh đổi) → **Derived, để `/spec-sad`**.
78
+
79
+ **Thủ tục 3 câu** (YES đầu tiên thắng):
80
+
81
+ | # | Câu hỏi | Nếu YES |
82
+ | --- | --- | --- |
83
+ | 1. External | Nó bọc/adapt một hệ thống hay bên thứ ba **ngoài codebase** mà ta buộc phải tích hợp? | **Given** → khai PRD (vd `payment-gateway` tích hợp Stripe, `email-service` tích hợp SendGrid) |
84
+ | 2. Mandated-substrate | Nó là nền tảng kỹ thuật dùng chung mà yêu cầu nói rõ phải có, **độc lập với cách carve lõi nghiệp vụ**? | **Given** → khai PRD (vd `auth`, `file-storage`, `notification`) |
85
+ | 3. Còn lại | Boundary phụ thuộc cách carve lõi nghiệp vụ, hoặc phụ thuộc đánh đổi NFR (scale, isolation, consistency, team topology)? | **Derived** → KHÔNG khai, để `/spec-sad` (vd `order`, `pricing`, `inventory`) |
86
+
87
+ Ranh giới câu 2 vs câu 3 = **"boundary có độc lập với quyết định chia lõi nghiệp vụ không?"** Độc lập → Given; phụ thuộc → Derived.
88
+
89
+ ### Khi input context đã có sẵn feature/component
90
+
91
+ Input là **baseline, không phải chân lý tuyệt đối**:
92
+
93
+ - Reuse tên/ID/boundary nếu input đã có → không tự đẻ cấu trúc song song.
94
+ - Vẫn chạy litmus test (phân loại) + Given/Derived để **validate**. Nếu input gọi X là "component" mà nó fail ownership test → flag, đề xuất reclassify thành feature (không im lặng bê nguyên).
95
+ - Component **Derived** do input cung cấp → ghi nhận như *candidate*, chuyển sang `/spec-sad`, **không** nhồi vào Component Index của PRD.
96
+ - Phần input thiếu → mới interview để bù.
97
+
98
+ ---
99
+
29
100
  ## Process
30
101
 
102
+ ### Bước 0: Nạp nguồn yêu cầu (tùy chọn)
103
+
104
+ Trước khi interview, xác định có **nguồn yêu cầu** (proposal, BRD, ghi chú họp, draft cũ) để dùng làm baseline không. Thứ tự ưu tiên:
105
+
106
+ 1. **ARGUMENT là path / `@file`** → đọc file đó. Hỗ trợ `.md`, `.txt`, PDF.
107
+ 2. **ARGUMENT là text dài (paste trực tiếp)** → dùng luôn làm nguồn.
108
+ 3. **Không có ARGUMENT** → hỏi một lần:
109
+ > Bạn có tài liệu/nguồn yêu cầu nào để mình tham khảo không? Nhập **đường dẫn file**, **paste nội dung**, hoặc `không` để interview từ đầu.
110
+
111
+ Nếu có nguồn → đọc và **trích baseline** cho từng section PRD (problem, users, scope, features, components, NFR, constraints). Đánh dấu cái nào trích được, cái nào nguồn không đề cập.
112
+
113
+ Áp **quy tắc baseline** (xem section "Khi input context đã có sẵn feature/component"): reuse tên/ID/boundary; validate feature/component qua litmus + Given/Derived; flag mục phân loại sai; component Derived → candidate cho `/spec-sad`, không nhồi vào Component Index.
114
+
115
+ Nếu không có nguồn → bỏ qua, interview từ đầu như bình thường.
116
+
117
+ ---
118
+
31
119
  ### Bước 1: Kiểm tra preconditions
32
120
 
33
121
  Đọc `specs/main/prd.md`:
@@ -79,6 +167,10 @@ PRD không chứa: tech stack, implementation details, entity schema, glossary,
79
167
 
80
168
  ### Bước 2: Gather — interview requirements
81
169
 
170
+ **Nếu Bước 0 đã nạp được nguồn:** interview chuyển từ "hỏi trắng" thành **xác nhận + bù chỗ thiếu**. Với mỗi phần, trình bày baseline đã trích rồi hỏi user confirm/sửa; chỉ những phần nguồn không đề cập mới hỏi từ đầu. Bỏ qua phần nào nguồn đã đủ rõ và user xác nhận.
171
+
172
+ **Nếu không có nguồn:** interview từ đầu như mô tả bên dưới.
173
+
82
174
  Trước khi hỏi, list ra các assumptions đang tạm thời:
83
175
 
84
176
  ```
@@ -105,9 +197,15 @@ Sau đó hỏi tuần tự, từng phần một — không hỏi tất cả cùn
105
197
  > Hệ thống cần implement những features gì? Mỗi feature gồm: tên ngắn, mô tả 1 câu (làm gì, cho ai), priority (Must/Should/Could).
106
198
  > (Đây sẽ là Feature Index mà các FRD sau này sẽ tham chiếu.)
107
199
 
108
- **Phần 5 — Components:**
109
- > Hệ thống những thành phần kỹ thuật (component) nào? Mỗi component gồm: tên ngắn (kebab-case, dụ `auth`, `payment`), tả 1 câu component chịu trách nhiệm gì.
110
- > (Đây là Component Index — agent có thể bỏ trống nếu user chưa rõ; component sẽ được thêm dần qua cascade từ integrations sau này.)
200
+ **Phần 5 — Components (chỉ component có boundary Given):**
201
+ > Hệ thống chắc chắn phải tích hợp hệ thống ngoài nào (vd `payment-gateway`, `email-service`), hoặc cần nền tảng kỹ thuật dùng chung nào độc lập với cách carve lõi nghiệp vụ (vd `auth`, `file-storage`, `notification`)?
202
+ > Mỗi component gồm: tên kebab-case + 1 câu tả responsibility.
203
+ >
204
+ > Áp **thủ tục Given vs Derived** (xem section "Khái niệm: Feature vs Component" ở trên) cho mỗi ứng viên:
205
+ > - **Given** (trúng câu 1 External hoặc câu 2 Mandated-substrate) → khai vào Component Index.
206
+ > - **Derived** (câu 3 — boundary phụ thuộc cách carve lõi nghiệp vụ hoặc đánh đổi NFR, vd `order`, `pricing`) → **KHÔNG** khai. Để `/spec-sad` chốt, hoặc mọc qua `/spec-new F-XXX` cascade.
207
+ >
208
+ > **KHÔNG** mechanical-derive components từ feature areas (vd: thấy "Pricing" trong yêu cầu → tạo ngay `C-pricing`; đó là Derived). Section này có thể chỉ có 3-6 entries, hoặc thậm chí trống. Đừng cố fill cho đủ.
111
209
 
112
210
  **Phần 6 — Non-Functional Requirements:**
113
211
  > Có yêu cầu về performance, security, availability, scalability không?
@@ -200,8 +298,9 @@ Trước khi kết thúc, kiểm tra:
200
298
  - [ ] Problem Statement từ góc nhìn business, không mention tech stack
201
299
  - [ ] Mỗi persona có: tên vai trò, mục tiêu, pain point
202
300
  - [ ] Out of Scope có ít nhất 1 item với lý do
203
- - [ ] Features có ít nhất 1 item, mỗi item có ID (F-XXX), tên, mô tả, priority
204
- - [ ] Components: nếuitem, mỗi item có ID (C-XXX), tên, mô tả ngắn (có thể trống nếu chưa rõ)
301
+ - [ ] Features có ít nhất 1 item, mỗi item có ID (F-XXX), tên, mô tả, priority. Mỗi item pass litmus test (đơn vị delivery, không phải ownership)
302
+ - [ ] Components: mọi entry là **Given** (trúng câu 1 External hoặc câu 2 Mandated-substrate). Không component **Derived** (boundary phụ thuộc carve lõi nghiệp vụ — thuộc `/spec-sad`). Có thể trống. Mỗi item có ID (C-XXX), tên kebab-case, mô tả 1 câu
303
+ - [ ] Nếu input context có sẵn feature/component: đã reuse làm baseline, đã validate qua litmus + Given/Derived, đã flag mục phân loại sai (nếu có)
205
304
  - [ ] Mỗi NFR có target đo được (không phải "nhanh", "bảo mật chung chung")
206
305
  - [ ] domain.md tồn tại (đã scaffold skeleton hoặc có nội dung sẵn)
207
306
  - [ ] User đã confirm trước khi file được ghi
@@ -0,0 +1,588 @@
1
+ ---
2
+ name: spec-remove
3
+ description: Remove một feature toàn diện — tạo removal integration với Code Inventory, Reverse Dependency Audit, reverse-TDD test strategy, và Finalize Plan (move feature artifacts sang specs/removed/ + đóng ADO tickets) như task cuối trong todo.md. Nhận F-XXX làm argument.
4
+ ---
5
+
6
+ # spec-remove
7
+
8
+ ## Overview
9
+
10
+ Tạo removal integration cho 1 feature đã tồn tại. Output là `spec.md` với đầy đủ:
11
+
12
+ - **Code Inventory** — code, route, DB, feature flag, config liên quan
13
+ - **Reverse Dependency Audit** — ai còn reference, an toàn xoá hay không
14
+ - **Test Strategy** — reverse-TDD (regression test "thing is gone")
15
+ - **Finalize Plan** — move feature artifacts sang `specs/removed/` + đóng ADO tickets, được DEV chạy như task cuối trong `todo.md`
16
+ - **Changes blocks** — `[REMOVE]` markers cho mọi artifact bị touched
17
+
18
+ Skill **không** sinh `tech.md` / `plan.md` / `todo.md`. Sau khi `spec.md` được approve, chạy `/spec-tech` → `/plan` → `/build` như flow thường. `spec.md` đủ giàu để 3 skill đó hoạt động không cần modification.
19
+
20
+ ## When to Use
21
+
22
+ - Một feature đã ship và cần decommission (deprecated, business pivot, replaced by feature khác)
23
+ - Cần xoá toàn bộ code + spec + ADO state một cách an toàn, có audit trail
24
+ - Có nhiều reverse-dep cần được liệt kê và quyết định rõ ràng trước khi xoá
25
+
26
+ ## When NOT to Use
27
+
28
+ - Chỉ muốn xoá 1 US / 1 AC / 1 VR khỏi feature → dùng `/spec-new` với marker `[REMOVE]` cho item đó. Feature vẫn sống.
29
+ - Feature chưa từng được implement (chỉ có frd.md, chưa có code) → dùng `/spec-new` với block `[REMOVE]` cho frd.md, không cần workflow này.
30
+ - Muốn pause / disable tạm thời mà giữ code → đây không phải removal, dùng feature flag thay vì skill này.
31
+
32
+ ---
33
+
34
+ ## Prerequisites
35
+
36
+ - `specs/main/feature/{F-XXX}-*/frd.md` tồn tại
37
+ - `specs/main/prd.md` có row của feature trong Feature Index
38
+ - (Optional) `.claude/ado.yaml` cấu hình nếu muốn đóng ADO tickets ở finalize step
39
+
40
+ ---
41
+
42
+ ## Process
43
+
44
+ ### Bước 1: Validate argument
45
+
46
+ Argument BẮT BUỘC là Feature ID dạng `F-XXX` (3 chữ số). Nếu argument thiếu hoặc sai format → dừng:
47
+
48
+ ```
49
+ spec-remove cần Feature ID. Ví dụ: /spec-remove F-001
50
+ ```
51
+
52
+ Tìm thư mục `specs/main/feature/F-XXX-*/`:
53
+ - 0 matches → báo lỗi feature không tồn tại, dừng.
54
+ - ≥ 2 matches → báo lỗi data inconsistency (nhiều thư mục cùng prefix), dừng.
55
+ - 1 match → tiếp.
56
+
57
+ Đọc `frd.md` frontmatter:
58
+ - Nếu `status: removed` → hỏi:
59
+
60
+ ```
61
+ F-XXX đã có status `removed`. Bạn muốn:
62
+ [1] Re-finalize (move artifacts + close ADO lại, idempotent)
63
+ [2] Tạo removal integration mới (có thể bạn chưa cleanup code lần trước)
64
+ [3] Hủy
65
+ ```
66
+
67
+ ---
68
+
69
+ ### Bước 2: Load context
70
+
71
+ Đọc các file sau:
72
+
73
+ **Bắt buộc:**
74
+ - `specs/main/feature/{F-XXX}-*/frd.md` — full content
75
+ - `specs/main/feature/{F-XXX}-*/fdd.md` — nếu tồn tại
76
+ - `specs/main/prd.md` — Feature Index (capture ADO ticket ID cho F-XXX), Component Index, NFR
77
+ - `specs/main/domain.md` — Glossary + Shared Entities (xác định entity nào owned bởi component thuộc F-XXX)
78
+
79
+ **Components used by F-XXX:**
80
+
81
+ Trích từ `frd.md` section `Components Used` + `fdd.md` section `Components Touched`. Với mỗi C-YYY:
82
+ - `specs/main/component/{C-YYY}-*/crd.md`
83
+ - `specs/main/component/{C-YYY}-*/cdd.md` — nếu tồn tại
84
+
85
+ **Reverse dependency scan:**
86
+
87
+ Với mỗi C-YYY mà F-XXX sử dụng, grep `specs/main/feature/F-*/frd.md` (trừ F-XXX) tìm references tới C-YYY. Mọi feature khác có reference → load `frd.md` của feature đó để hiểu nó dùng C-YYY làm gì.
88
+
89
+ Output context summary cho user:
90
+
91
+ ```
92
+ F-XXX — {feature title}
93
+ Status: {Done/In Progress/...}
94
+ ADO: #{ticket_id} ({current state}) {nếu prd.md có cột ADO}
95
+
96
+ Components dùng bởi F-XXX:
97
+ - C-YYY-{slug} — {role} ({exclusive | shared with F-AAA, F-BBB})
98
+ - ...
99
+
100
+ Reverse-dep features (dùng chung component với F-XXX):
101
+ ⚠ F-AAA {title} — dùng C-YYY {interface_name}
102
+ ⚠ F-BBB {title} — dùng C-ZZZ {interface_name}
103
+ {hoặc} ✓ Không có reverse-dep — F-XXX hoàn toàn cô lập
104
+
105
+ Glossary terms từ domain.md tham chiếu trong F-XXX:
106
+ - {term} {(unique to F-XXX | shared)}
107
+ - ...
108
+
109
+ Shared entities owned bởi components của F-XXX:
110
+ - {Entity} (Owner: C-YYY) — {used by F-XXX only | also F-AAA}
111
+ - ...
112
+ ```
113
+
114
+ ---
115
+
116
+ ### Bước 3: Interview ngắn
117
+
118
+ Hỏi 2 câu, tuần tự:
119
+
120
+ **3.1 — Lý do remove:**
121
+
122
+ ```
123
+ Lý do remove F-XXX? (sẽ ghi vào Change History + ADO closure comment)
124
+ > ___
125
+ ```
126
+
127
+ **3.2 — Removal strategy:**
128
+
129
+ Dùng `AskUserQuestion`:
130
+
131
+ ```
132
+ Removal strategy:
133
+ [1] Single-shot — xoá hết trong 1 deploy. Phù hợp khi feature off-traffic, internal-only, không có DB schema lớn.
134
+ [2] Phased — disable trước (feature flag off + deprecation banner), soak period, sau đó xoá code. Phù hợp khi có DB / external API / traffic gradual.
135
+ [3] Phased + drop schema riêng — như Phased nhưng tách thêm 1 integration cho DROP TABLE/COLUMN sau khi code đã xoá và observed.
136
+ ```
137
+
138
+ Nếu chọn `[2]` hoặc `[3]` → hỏi soak period (1-2 tuần là baseline):
139
+
140
+ ```
141
+ Soak period giữa các phase (ngày)?
142
+ > ___
143
+ ```
144
+
145
+ Phased và Phased+drop schema → ghi nhận để Bước 6 (sinh draft) có Removal Phases section.
146
+
147
+ ---
148
+
149
+ ### Bước 4: Code Discovery
150
+
151
+ Mục tiêu: build **Code Inventory** — danh sách code cụ thể sẽ bị xoá.
152
+
153
+ **Nguồn discovery (kết hợp):**
154
+
155
+ 1. **fdd.md / cdd.md** — nếu artifact có ghi file path / module path cụ thể trong section như "Implementation Notes" → dùng làm seed trực tiếp.
156
+ 2. **Component slug** — search filesystem cho directory matching `{C-YYY}-{slug}` (kebab) hoặc camelCase variant.
157
+ 3. **Public Interface signatures** — từ `crd.md` Public Interface, lấy function/class/endpoint name → grep codebase.
158
+ 4. **Route paths** — từ `frd.md` User Flows / `fdd.md` sequence diagrams, extract API path patterns (`/api/...`) → grep route registrations.
159
+ 5. **Owned Entities** — từ `domain.md` Shared Entities (owned bởi component của F-XXX), table name → grep migrations + queries.
160
+ 6. **Feature flag names** — nếu được nhắc trong artifact → grep config files.
161
+ 7. **Test files** — sau khi xác định module paths, grep `tests/` cho cùng prefix / cùng tên.
162
+
163
+ **Tools:** `Grep`, `Glob`, `Bash` (`rg`, `find`). Khi không chắc filesystem layout, hỏi user 1 câu: "Codebase root ở `src/` hay project có monorepo structure khác?"
164
+
165
+ **Output Code Inventory** dạng table, group theo category:
166
+
167
+ ```
168
+ Code Inventory for F-XXX:
169
+
170
+ ROUTES / API ENDPOINTS:
171
+ [1] POST /api/auth/login → src/routes/auth.ts:12-50
172
+ [2] POST /api/auth/logout → src/routes/auth.ts:52-80
173
+ [3] POST /api/auth/refresh → src/routes/auth.ts:82-115
174
+
175
+ SOURCE MODULES:
176
+ [4] src/services/auth/ → entire directory (8 files)
177
+ [5] src/middleware/auth-token.ts
178
+ [6] src/utils/jwt.ts → ⚠ also used by F-007 (reverse-dep)
179
+
180
+ TESTS:
181
+ [7] tests/auth/ → 12 files
182
+ [8] tests/integration/auth-flow.test.ts
183
+
184
+ DATABASE:
185
+ [9] table `sessions` → migration drop_sessions.sql cần tạo
186
+ [10] table `refresh_tokens` → migration cần tạo
187
+ [11] users.last_login_at column → ⚠ used by F-007 analytics
188
+
189
+ FEATURE FLAGS:
190
+ [12] ff_new_auth → src/config/flags.ts:12
191
+
192
+ CONFIG / ENV:
193
+ [13] AUTH_SECRET, AUTH_TTL → .env.example, src/config/index.ts
194
+
195
+ OTHER (best-effort, manual verify):
196
+ - Grafana dashboard "Auth metrics" — không scan được tự động, BA verify tay
197
+ - Docs site có section /docs/auth/ — verify tay
198
+ ```
199
+
200
+ Mỗi item có thể là `safe` (xanh) hoặc `⚠ has external ref` (cần quyết định ở Bước 5).
201
+
202
+ ---
203
+
204
+ ### Bước 5: Reverse Dependency Audit
205
+
206
+ Với mỗi item trong Code Inventory, grep external references (ngoài thư mục chính của F-XXX). Mọi reference `⚠` cần user quyết định.
207
+
208
+ ```
209
+ Reverse-dep audit:
210
+
211
+ [6] src/utils/jwt.ts
212
+ External refs found:
213
+ - src/services/admin/sessions.ts:34 — imports `verifyJWT`
214
+ - src/services/api-gateway/auth-check.ts:12 — imports `signJWT`
215
+
216
+ Quyết định:
217
+ [a] Keep file — không xoá src/utils/jwt.ts (chỉ xoá phần exclusive của F-XXX bên trong nếu có)
218
+ [b] Migrate consumer first — abort removal, tạo integration migration F-007 + api-gateway sang alternative trước
219
+ [c] Remove anyway — xoá luôn, downstream tự fix (rủi ro cao, cần justify)
220
+ Chọn: ___
221
+
222
+ [11] users.last_login_at column
223
+ External refs found:
224
+ - src/analytics/login-tracking.ts:88 — SELECT this column
225
+ Quyết định: ___
226
+ ```
227
+
228
+ Mọi item `⚠` đều phải có quyết định trước khi sang Bước 6. Nếu user chọn `[b]` cho bất kỳ item nào → dừng skill, instruct:
229
+
230
+ ```
231
+ F-XXX chưa thể remove vì có reverse-dep chưa migrate:
232
+ - {item} blocked by {consumer}
233
+
234
+ Tạo integration migration trước:
235
+ /spec-new "Migrate {consumer} away from {item}"
236
+
237
+ Sau khi migration deploy xong, chạy lại /spec-remove F-XXX.
238
+ ```
239
+
240
+ ---
241
+
242
+ ### Bước 6: Sinh draft spec.md
243
+
244
+ Xác định slug và NNN giống `/spec-new`:
245
+ - Slug: `remove-{f-xxx-slug}` (ví dụ `remove-f001-authentication`)
246
+ - NNN: max của thư mục hiện có trong `specs/integrations/` + 1, format 3 chữ số.
247
+
248
+ Output path: `specs/integrations/{NNN}-remove-{f-xxx-slug}/spec.md`
249
+
250
+ Cấu trúc spec.md:
251
+
252
+ ```markdown
253
+ ---
254
+ id: "{NNN}"
255
+ slug: "remove-{f-xxx-slug}"
256
+ title: "Remove {F-XXX} {feature title}"
257
+ features: [{F-XXX}]
258
+ components: [{C-YYY list những component bị touched}]
259
+ status: approved
260
+ removal: true
261
+ created: {YYYY-MM-DD}
262
+ ---
263
+
264
+ ## Context
265
+ {tóm tắt frd/fdd/components/reverse-deps đã load ở Bước 2}
266
+
267
+ ## Problem Statement
268
+ {lý do remove từ Bước 3.1 — ghi từ góc nhìn business/product, không phải tech}
269
+
270
+ ## Removal Strategy
271
+ {Single-shot | Phased | Phased + schema drop} — chi tiết theo lựa chọn:
272
+
273
+ ### Phase 1: Disable (chỉ khi Phased)
274
+ - Tắt feature flag `ff_xxx`
275
+ - Deprecation banner trên UI (nếu user-facing)
276
+ - Telemetry warning log mỗi lần feature được hit
277
+ - Soak: {N} ngày, monitor traffic = 0
278
+
279
+ ### Phase 2: Remove code
280
+ - Xoá code per Code Inventory dưới
281
+ - Regression tests (xem Test Strategy)
282
+
283
+ ### Phase 3: Drop schema (chỉ khi Phased + schema drop)
284
+ - Tạo integration riêng sau {N} ngày Phase 2 deployed
285
+ - Migration DROP TABLE / DROP COLUMN
286
+
287
+ ## Code Inventory
288
+ {copy table từ Bước 4, đã loại bỏ các item user quyết định `[a] Keep`}
289
+
290
+ ## Reverse Dependency Audit
291
+ {liệt kê mỗi item ⚠ + quyết định user đã chọn, kèm lý do/justify}
292
+
293
+ ## Test Strategy (Reverse-TDD)
294
+
295
+ Pattern cho mỗi target:
296
+
297
+ 1. **Baseline check (trước khi xoá):** ghi nhận test hiện có hoặc viết quick smoke test xác nhận thing exists và functional. Mục đích: confirm mental model trước khi xoá.
298
+
299
+ 2. **Delete trong 1 commit:**
300
+ - Xoá source code
301
+ - Xoá test files cũ tương ứng
302
+ - Update import statements
303
+
304
+ 3. **Regression assertion (sau khi xoá):** thêm test khẳng định thing is gone:
305
+ - Route → assert GET/POST trả 404 (hoặc proper error code)
306
+ - Exported function/class → assert import fails (compile-time check, không cần runtime test)
307
+ - DB table/column → migration test confirm DROP applied, query trả error
308
+ - Feature flag → assert flag key không tồn tại trong config
309
+
310
+ 4. **Full suite run:** mọi test khác phải pass. Nếu có test fail → reverse-dep chưa detect đủ, rollback commit, audit lại.
311
+
312
+ Regression tests **được giữ lại** trong codebase như guardrail — future-self không vô tình re-add feature đã removed.
313
+
314
+ ## Finalize Plan
315
+
316
+ Đây là **task cuối** trong todo.md (sẽ được /plan tự nhặt). DEV thực thi sau khi mọi removal task khác xong và đã deploy verify.
317
+
318
+ ### Actions:
319
+
320
+ 1. **Move feature artifacts:**
321
+ ```bash
322
+ mkdir -p specs/removed
323
+ mv specs/main/feature/{F-XXX}-{slug}/ specs/removed/{F-XXX}-{slug}/
324
+ ```
325
+
326
+ 2. **Append Change History** vào `specs/removed/{F-XXX}-{slug}/frd.md` (nếu file còn tồn tại sau move):
327
+ ```markdown
328
+ ### {YYYY-MM-DD} — [{NNN}-remove-{slug}](../../integrations/{NNN}-remove-{slug}/spec.md) — removed
329
+ - **Feature decommissioned**: moved from specs/main/feature/ to specs/removed/
330
+ - Reason: {lý do từ Problem Statement}
331
+ ```
332
+
333
+ 3. **Update prd.md Feature Index:**
334
+ - Row F-XXX: status → `Removed`
335
+ - Add note column hoặc inline: `(see specs/removed/{F-XXX}-{slug}/)`
336
+
337
+ 4. **Close ADO tickets** (nếu prd.md có ADO ticket ID cho F-XXX):
338
+ - Feature ticket → state `Removed`
339
+ - Tất cả User Story tickets thuộc F-XXX → state `Removed`
340
+ - Comment trên mỗi ticket: "Decommissioned per integration {NNN}-remove-{slug}. Reason: {lý do}"
341
+ - Dùng `mcp__azure-devops__wit_update_work_item` (state) + `mcp__azure-devops__wit_add_work_item_comment` (comment)
342
+ - Nếu ADO state name khác (vd "Closed") → xem `.claude/ado.yaml` hoặc fetch từ `wit_get_work_item_type`
343
+
344
+ 5. **Verify finalize:**
345
+ - `ls specs/main/feature/ | grep {F-XXX}` → không còn match
346
+ - `ls specs/removed/{F-XXX}-{slug}/` → tồn tại
347
+ - prd.md grep `F-XXX` → status `Removed`
348
+ - ADO ticket fetch → state khớp
349
+
350
+ ## Changes
351
+ <!-- Changes blocks theo format chuẩn của spec-template.md, áp dụng cho mọi artifact bị touched. Xem markers [NEW]/[MODIFY {field}]/[REMOVE] theo conventions §5.5. -->
352
+
353
+ ### prd.md
354
+ **Operation:** update
355
+ **Format reference:** [prd-template.md](../../templates/main/prd-template.md)
356
+
357
+ #### Features (Feature Index)
358
+ - Row [MODIFY status]: `F-XXX` {current status} → `Removed`
359
+ - {nếu có note column} Row [MODIFY note]: `F-XXX` add note "see specs/removed/"
360
+
361
+ #### Components (Component Index) — chỉ component exclusive với F-XXX
362
+ - Row [MODIFY status]: `C-YYY` {current status} → `Removed`
363
+ - ... (component shared thì KHÔNG đổi status)
364
+
365
+ ### feature/{F-XXX}-{slug}/frd.md
366
+ **Operation:** update
367
+ **Format reference:** [frd-template.md](../../templates/main/feature/frd-template.md)
368
+
369
+ <!--
370
+ Đánh dấu mọi item bằng [REMOVE]. File sẽ bị move sang specs/removed/ ở Finalize step
371
+ nhưng cascade content vẫn ghi vào file gốc trước (để Change History entry được apply).
372
+ -->
373
+
374
+ #### User Stories
375
+ - US-FXXX-001 [REMOVE] — feature decommissioned
376
+ - US-FXXX-002 [REMOVE] — feature decommissioned
377
+ - ... (mọi US)
378
+
379
+ #### Acceptance Criteria
380
+ - AC-FXXX-* [REMOVE] — feature decommissioned
381
+
382
+ #### Verification Rules
383
+ - VR-FXXX-* [REMOVE] — feature decommissioned
384
+
385
+ #### Frontmatter
386
+ - [MODIFY status]: `draft|approved|...` → `removed`
387
+
388
+ ### feature/{F-XXX}-{slug}/fdd.md *(nếu tồn tại)*
389
+ **Operation:** update
390
+ **Format reference:** [fdd-template.md](../../templates/main/feature/fdd-template.md)
391
+
392
+ #### Flow Sequences
393
+ - [REMOVE] FS-FXXX-* — feature decommissioned
394
+
395
+ #### Data Models
396
+ - [REMOVE] {model} — feature decommissioned
397
+
398
+ #### Frontmatter
399
+ - [MODIFY status]: → `removed`
400
+
401
+ ### component/{C-YYY}-{slug}/crd.md *(lặp cho mỗi component bị touched)*
402
+ **Operation:** update
403
+ **Format reference:** [crd-template.md](../../templates/main/component/crd-template.md)
404
+
405
+ <!--
406
+ Component exclusive với F-XXX:
407
+ - Toàn bộ sections [REMOVE]
408
+ - Frontmatter status → removed
409
+
410
+ Component shared (vẫn còn feature khác dùng):
411
+ - Chỉ [REMOVE] những Public Interface / Responsibility / Owned Entity
412
+ chỉ phục vụ F-XXX (đã audit ở Bước 5)
413
+ - Giữ nguyên phần còn lại
414
+ - Frontmatter status KHÔNG đổi
415
+ -->
416
+
417
+ #### Public Interface
418
+ - {interface} [REMOVE] — only used by F-XXX, no other consumer
419
+
420
+ #### Owned Entities
421
+ - {Entity} [REMOVE] — exclusive to F-XXX
422
+
423
+ ### domain.md
424
+ **Operation:** update
425
+ **Format reference:** [domain-template.md](../../templates/main/domain-template.md)
426
+
427
+ #### Glossary
428
+ - {term} [REMOVE] — unique to F-XXX, no other reference
429
+
430
+ #### Shared Entities
431
+ - {Entity} [REMOVE] — orphan after F-XXX removal, no other component owns
432
+
433
+ ## Out of Scope
434
+ - {Migration của reverse-dep features tới alternative — separate integration nếu có}
435
+ - {Documentation site cleanup — manual task ngoài integration}
436
+ - {Grafana dashboard cleanup — manual task}
437
+
438
+ ## Cascade Summary
439
+
440
+ | Artifact | Operation | Summary |
441
+ | --- | --- | --- |
442
+ | `prd.md` | update | F-XXX status → Removed; {N} components status → Removed |
443
+ | `feature/F-XXX-*/frd.md` | update | All items [REMOVE]; status → removed; folder move tại Finalize |
444
+ | `feature/F-XXX-*/fdd.md` | update | All items [REMOVE]; status → removed |
445
+ | `component/C-YYY-*/crd.md` | update | All [REMOVE] (exclusive) / {N} items [REMOVE] (shared) |
446
+ | `domain.md` | update | {N} glossary [REMOVE], {N} entity [REMOVE] |
447
+ ```
448
+
449
+ ---
450
+
451
+ ### Bước 7: Review — xác nhận với user
452
+
453
+ Hiển thị toàn bộ draft. Hỏi:
454
+
455
+ ```
456
+ Draft trên đã đúng chưa?
457
+ - Code Inventory đầy đủ và chính xác?
458
+ - Reverse-dep audit đã quyết định hết các ⚠?
459
+ - Removal Strategy phù hợp (single-shot vs phased)?
460
+ - Finalize Plan đủ steps?
461
+ - Changes blocks dùng [REMOVE] đúng chỗ (exclusive vs shared)?
462
+
463
+ Sau khi confirm, agent sẽ auto-apply Changes blocks lên main artifacts.
464
+ File feature artifacts (frd/fdd) KHÔNG bị move ngay — chỉ apply [REMOVE] markers
465
+ + Change History entry. Move sang specs/removed/ là task cuối trong todo.md,
466
+ do /build chạy sau khi mọi deletion task khác xong.
467
+ ```
468
+
469
+ Chỉ tiến hành Bước 8 sau khi user confirm.
470
+
471
+ ---
472
+
473
+ ### Bước 8: Save + Auto-cascade
474
+
475
+ Giống `/spec-new` Bước 7, nhưng với removal-specific extensions.
476
+
477
+ **[8.1] Ghi spec.md** với status `approved`, `removal: true` trong frontmatter. Frontmatter `features` chứa F-XXX, `components` chứa list components touched.
478
+
479
+ **[8.2] Auto-apply Changes blocks** vào main artifacts. Thứ tự: `prd.md` → `domain.md` → `sad.md` → `component/*/crd.md` → `component/*/cdd.md` → `feature/F-XXX-*/frd.md` → `feature/F-XXX-*/fdd.md`.
480
+
481
+ Áp dụng marker [REMOVE] theo conventions §5.5:
482
+ - Xoá item khỏi artifact, ID không tái sử dụng, không renumber.
483
+ - Khi toàn bộ items trong frd/fdd của F-XXX bị [REMOVE] → đổi frontmatter `status: removed`.
484
+
485
+ **[8.3] Append Change History entry** vào mọi artifact bị touched (conventions §5.5). Entry format chuẩn:
486
+
487
+ ```markdown
488
+ ### {YYYY-MM-DD} — [{NNN}-remove-{slug}](../../integrations/{NNN}-remove-{slug}/spec.md) — update
489
+
490
+ - **{Section name}**:
491
+ - [REMOVE] {ID/item} — feature decommissioned ({lý do ngắn})
492
+ ```
493
+
494
+ **[8.4] Side-effects:**
495
+
496
+ - Trong prd.md: row F-XXX status đổi `Removed` ngay (không chờ finalize). Lý do: spec.md đã approved tức là quyết định removal đã được ký, status reflect quyết định ngay.
497
+ - ADO tickets KHÔNG transition ngay. Chỉ transition khi DEV chạy task Finalize ở `/build`. Lý do: tránh case rollback removal sau khi spec approve nhưng chưa deploy.
498
+ - File feature/F-XXX-*/ KHÔNG move ngay. Lý do giống ADO — chỉ move sau khi code thật đã xoá và verified.
499
+
500
+ **[8.5] Thông báo kết quả:**
501
+
502
+ ```
503
+ ✓ specs/integrations/{NNN}-remove-{f-xxx-slug}/spec.md đã được tạo (status: approved, removal: true)
504
+
505
+ Auto-cascade applied:
506
+ ✓ prd.md — F-XXX status → Removed; {N} components status → Removed
507
+ ✓ domain.md — {N} glossary/entity [REMOVE]
508
+ ✓ component/C-YYY-*/crd.md — {summary}
509
+ ✓ feature/F-XXX-*/frd.md — all items [REMOVE], status → removed
510
+ ✓ feature/F-XXX-*/fdd.md — all items [REMOVE], status → removed
511
+
512
+ ⚠ File feature/F-XXX-*/ vẫn ở specs/main/feature/. Sẽ được move sang specs/removed/ ở task cuối todo.md.
513
+ ⚠ ADO tickets giữ nguyên state. Sẽ được close ở task cuối todo.md (cần .claude/ado.yaml).
514
+
515
+ Bước tiếp theo:
516
+ /spec-tech → thiết kế delete order, migration SQL, regression test cases
517
+ /plan → break down deletion tasks + finalize task cuối
518
+ /build → execute deletion + finalize
519
+ ```
520
+
521
+ **Nếu apply fail** (markers reference ID không tồn tại, reverse-dep audit chưa hoàn tất, file không ghi được) → dừng, báo lỗi cụ thể, **không** ghi spec.md. Yêu cầu user fix draft.
522
+
523
+ ---
524
+
525
+ ## Downstream Integration (informational)
526
+
527
+ Skill này chỉ sinh `spec.md`. Để biết các skill sau xử lý removal flavor như nào:
528
+
529
+ - **`/spec-tech`** đọc `spec.md`, thấy `removal: true` + Code Inventory + Test Strategy + Finalize Plan → sinh `tech.md` với:
530
+ - Section "Delete Order" liệt kê file paths theo Code Inventory
531
+ - Section "Migration SQL" nếu có DB target (DROP + rollback)
532
+ - Section "Regression Tests" theo Test Strategy pattern
533
+ - Section "Finalize Task" passthrough nguyên xi từ spec.md Finalize Plan
534
+
535
+ - **`/plan`** đọc cả spec.md + tech.md → sinh `plan.md` + `todo.md`. Task cuối todo.md = Finalize task với 5 sub-actions như Finalize Plan của spec.md.
536
+
537
+ - **`/build`** chạy tuần tự todo.md. Khi tới Finalize task:
538
+ - Move folder bằng shell mv
539
+ - Edit prd.md
540
+ - Append Change History
541
+ - Gọi ADO API để transition tickets (cần `.claude/ado.yaml` configured)
542
+ - Verify outputs
543
+
544
+ Nếu `/spec-tech` hoặc `/plan` hiện tại chưa nhặt được removal flavor → có thể cần update sau (separate work). Trong v1, spec.md đủ rõ ràng để 2 skill đó produce reasonable output kể cả không có removal-awareness explicit.
545
+
546
+ ---
547
+
548
+ ## Common Rationalizations
549
+
550
+ | Rationalization | Reality |
551
+ | --- | --- |
552
+ | "Grep nhanh, không cần Code Inventory chi tiết" | Inventory sót item = code chết nằm trong repo vô thời hạn. Audit trail mất. |
553
+ | "Reverse-dep nhỏ thôi, xoá luôn rồi fix sau" | Một import dangling phá CI cả team. Audit trước rẻ hơn rollback. |
554
+ | "Feature flag off là xong, không cần xoá code" | Code dead vẫn phải maintain (security patch, dependency upgrade). Xoá hẳn mới sạch. |
555
+ | "Single-shot cho nhanh, soak period làm gì" | Có DB / external traffic mà single-shot = rollback đắt khi phát hiện consumer chưa migrate. |
556
+ | "Skip Finalize, để folder ở main feature là được" | Active dir bị noise. Sau 5 features removed, không phân biệt được active vs dead. |
557
+
558
+ ## Red Flags
559
+
560
+ - Code Inventory empty hoặc chỉ có 1-2 file cho 1 feature đã ship → discovery chưa đủ rộng, xem lại sources
561
+ - Reverse-dep audit không có ⚠ nào cho component shared → grep chưa đủ kỹ
562
+ - Removal Strategy single-shot nhưng có DB schema lớn hoặc external traffic > 0 → cân nhắc Phased
563
+ - Test Strategy chỉ có "delete code" mà không có regression test → future re-add risk
564
+ - Finalize Plan thiếu ADO closure mà prd.md có ticket ID → audit trail không đầy đủ
565
+ - Changes block frd.md mark [REMOVE] nhưng không đổi `status: removed` trong frontmatter → inconsistent state
566
+
567
+ ## Verification
568
+
569
+ Trước khi user confirm (Bước 7):
570
+
571
+ - [ ] Code Inventory liệt kê đủ 7 category (route / module / test / DB / flag / config / other)
572
+ - [ ] Mỗi item ⚠ trong Reverse-dep audit đã có quyết định rõ ràng (a/b/c)
573
+ - [ ] Nếu có item chọn `[b] Migrate first` → skill đã dừng, không tạo spec
574
+ - [ ] Removal Strategy match scale: single-shot cho nhỏ, phased cho lớn
575
+ - [ ] Test Strategy có 4 sub-step: baseline / delete / regression / full-suite
576
+ - [ ] Finalize Plan có 5 actions: move folder / change history / prd update / ADO close / verify
577
+ - [ ] Changes blocks: exclusive component → all [REMOVE]; shared component → chỉ items của F-XXX [REMOVE]
578
+ - [ ] frd.md / fdd.md frontmatter có [MODIFY status] → removed
579
+
580
+ Sau khi user confirm (Bước 8):
581
+
582
+ - [ ] spec.md frontmatter `removal: true`
583
+ - [ ] Auto-cascade chạy đúng thứ tự prd → domain → sad → crd → cdd → frd → fdd
584
+ - [ ] Mọi artifact bị touched có Change History entry
585
+ - [ ] prd.md row F-XXX status = Removed (đổi ngay sau approve)
586
+ - [ ] File feature/F-XXX-*/ VẪN ở specs/main/feature/ (chưa move — chỉ move ở Finalize task)
587
+ - [ ] ADO tickets KHÔNG bị transition (chưa close — chỉ close ở Finalize task)
588
+ - [ ] Notification cuối ghi rõ 2 ⚠ về việc folder + ADO chưa được động vào
@@ -8,8 +8,9 @@ Dùng khi bắt đầu dự án mới chưa có code. Mục tiêu: bootstrap `pr
8
8
 
9
9
  | Command | Reads | Writes |
10
10
  | --- | --- | --- |
11
- | `/spec-prd` | — | `specs/main/prd.md`, `specs/main/domain.md` *(skeleton)* |
11
+ | `/spec-prd` | — *(tùy chọn: nguồn baseline path/@file/paste)* | `specs/main/prd.md`, `specs/main/domain.md` *(skeleton)* |
12
12
  | `/spec-sad` | `prd.md`, `domain.md` | `specs/main/sad.md` |
13
+ | `/spec-frd [F-XXX]` *(tùy chọn)* | `prd.md`, `domain.md`, `sad.md`, `crd(s)` *(+ nguồn baseline)* | `specs/main/feature/{F-XXX}-*/frd.md` *(+ register feature row vào `prd.md` nếu feature mới)* |
13
14
 
14
15
  ### `/spec-prd`
15
16
 
@@ -48,12 +49,36 @@ Nếu `prd.md` chưa có → dừng, yêu cầu chạy `/spec-prd` trước.
48
49
 
49
50
  ---
50
51
 
52
+ ### `/spec-frd [F-XXX]` *(tùy chọn)*
53
+
54
+ BA author `specs/main/feature/{F-XXX}-*/frd.md` trực tiếp qua interview — **spec-first ở feature level**, chạy *trước* khi DEV bắt đầu integration. Cặp greenfield đối xứng với `/spec-brownfield-feature` (vốn reverse-engineer frd từ code).
55
+
56
+ Nhận F-XXX từ argument (hoặc chọn từ prd Feature Index) + tùy chọn nguồn baseline (path/@file/paste như `/spec-prd`). Yêu cầu `prd.md` tồn tại.
57
+
58
+ **Hai gate input (làm chặt) — phải pass cả hai mới author:**
59
+ - **Single-feature**: nguồn liên quan **đúng 1 feature**. Xác định > 1 feature → **dừng + mô tả rõ lý do tách** (outcome/luồng/persona của từng cái) → redirect `/spec-prd` để khai Feature Index.
60
+ - **Create-only**: frd.md của feature mục tiêu **chưa tồn tại**. Đã tồn tại → **dừng, redirect `/spec-new`** (thay đổi feature đã spec phải đi qua integration để delta cascade + kéo theo `/spec-tech`/`/spec-test`).
61
+ - Feature mới **đơn lẻ** chưa có trong Index → offer **register một row vào `prd.md > Features`** rồi author.
62
+
63
+ **Sections template** (7): Overview · User Flows · Feature Acceptance Criteria · User Stories · Verification Rules · Scope · Dependencies
64
+
65
+ **Phạm vi hẹp — chủ yếu `frd.md`:**
66
+ - Reference component frd phụ thuộc (Components Used → C-XXX có sẵn).
67
+ - Component cần-nhưng-chưa-có → ghi *candidate* + Open Question cho `/spec-sad`/architect chốt boundary.
68
+ - Có thể register **một** feature row vào prd (side-effect hợp lệ duy nhất lên prd). **KHÔNG** tạo `crd.md`/`cdd.md` (sinh ở integration time qua `/spec-new` cascade), không tạo `fdd.md`/`tsd.md`, không đổi status feature đã có, không đụng sad/domain.
69
+ - Change History operation = `manual`. Verification Rules dùng quy ước option-suggester của `/spec-new` (BA owns).
70
+
71
+ Bỏ qua bước này cũng được — `/spec-new` sẽ tự tạo frd làm fallback khi integration đầu tiên chạm tới feature.
72
+
73
+ ---
74
+
51
75
  ### Thứ tự thực hiện
52
76
 
53
77
  ```
54
78
  /spec-prd → /spec-sad
55
79
 
56
80
  │ (có thể chạy /scaffold để khởi tạo project structure)
81
+ │ (tùy chọn /spec-frd [F-XXX] — BA author frd.md trước)
57
82
 
58
83
 
59
84
  → Integration Pipeline
@@ -595,7 +620,7 @@ Cập nhật state đồng loạt cho User Story (và tuỳ chọn Feature) tick
595
620
  ## Ghi chú
596
621
 
597
622
  - Cascade proposals trong `spec.md` và `tech.md` do human review và apply thủ công — không có skill riêng.
598
- - **Greenfield**: Component và Feature artifacts mọc dần qua cascade từ integrations — không skill chuyên biệt để tạo.
623
+ - **Greenfield**: Feature artifacts (`frd.md`) có thể author trước bằng `/spec-frd`, hoặc mọc dần qua cascade từ integrations (`/spec-new` fallback). Component artifacts (`crd.md`/`cdd.md`) chỉ mọc qua cascade `/spec-frd` chỉ reference component, không tạo crd/cdd.
599
624
  - **Brownfield**: Component và Feature artifacts được bootstrap bởi `spec-brownfield-component` và `spec-brownfield-feature` — sau đó tiếp tục mọc qua cascade như bình thường.
600
625
  - Thứ tự trong một integration: `spec-new` → `spec-tech` → `plan` → `build`.
601
626
  - `frontend-design` và `frontend-ui-engineering` được `build` invoke tự động — không cần gọi thủ công.
@@ -6,6 +6,7 @@ owner: "{BA}"
6
6
  feature_id: "{Feature ID từ PRD Feature Index}"
7
7
  referenced_by:
8
8
  - conventions.md > 3. Main Artifacts > 3.3 Feature level > frd.md > Cấu trúc
9
+ - skills/spec-frd/SKILL.md > Process > Bước 5: Write — sinh draft
9
10
  - skills/spec-new/SKILL.md > Process > Bước 5: Write — sinh draft > feature/{F-XXX}/frd.md
10
11
  - templates/integrations/spec-template.md > Changes > feature/{F-XXX}/frd.md
11
12
  ---
@@ -35,13 +35,28 @@ Tại sao cần giải quyết bây giờ.
35
35
 
36
36
  ## Features
37
37
 
38
+ Đặt tên feature theo **outcome của một luồng hoàn chỉnh**, kebab-case, đủ khái quát mà vẫn là *một* luồng — không quá rộng (`user-management` là feature area), không quá hẹp (`register-with-google` chỉ là biến thể). ✅ `user-registration`, `password-reset`, `checkout`.
39
+
38
40
  | ID | Feature | Mô tả | Priority | Status |
39
41
  | --- | --- | --- | --- | --- |
40
42
  | F-001 | {tên feature} | {mô tả ngắn — feature làm gì, cho ai} | High/Medium/Low | TODO/DONE |
41
43
 
42
44
  ## Components
43
45
 
44
- Các thành phần kỹ thuật của hệ thống chi tiết về vai trò thiết kế nằm trong `specs/main/component/{C-XXX}-{component-name}/`.
46
+ Một component = một khối có **boundary rõ + interface tường minh** và **một lý do duy nhất để thay đổi**. Không phân loại component thành "domain" hay "kỹ thuật" mỗi component đều mặt domain (`crd.md`) lẫn mặt kỹ thuật (`cdd.md`).
47
+
48
+ Đặt tên component theo **năng lực bền vững**, không theo công nghệ hiện tại, kebab-case. ✅ `notification`, `auth`, `file-storage`. ❌ quá cụ thể (`email-sender`, `stripe-client`) hoặc quá mơ hồ (`core`, `utils`, `manager`).
49
+
50
+ Section này **chỉ liệt kê component có boundary _Given_** — tức boundary bị ép từ ngoài, chỉ có một cách vẽ hợp lý. Áp thủ tục:
51
+ - **Câu 1 (External):** bọc/adapt hệ thống ngoài ta buộc phải tích hợp? (vd `payment-gateway` tích hợp Stripe, `email-service` tích hợp SendGrid) → Given, khai ở đây.
52
+ - **Câu 2 (Mandated-substrate):** nền tảng kỹ thuật dùng chung mà yêu cầu bắt buộc, độc lập với cách carve lõi nghiệp vụ? (vd `auth`, `file-storage`, `notification`) → Given, khai ở đây.
53
+ - **Còn lại (Derived):** boundary phụ thuộc cách carve lõi nghiệp vụ hoặc đánh đổi NFR (vd `order`, `pricing`, `inventory`) → **KHÔNG** khai ở đây.
54
+
55
+ **Component Derived mọc dần qua:**
56
+ - `/spec-sad` — architect lock component boundaries dựa trên full feature index + NFRs
57
+ - `/spec-new F-XXX` cascade — khi analyze 1 feature, discover component mới nếu cần và register vào đây qua Change History
58
+
59
+ Chi tiết về vai trò và thiết kế nằm trong `specs/main/component/{C-XXX}-{component-name}/`.
45
60
 
46
61
  | ID | Component | Mô tả ngắn | Status |
47
62
  | --- | --- | --- | --- |