spec-lite 1.4.3 → 1.4.6

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
@@ -1,13 +1,13 @@
1
1
  # spec-lite
2
2
 
3
- Bộ skills spec-driven development cho Claude Code — phỏng vấn có cấu trúc để xây dựng PRD, kiến trúc hệ thống, và integration specs. Domain knowledge và component/feature artifacts mọc dần qua cascade từ integrations.
3
+ Bộ skills spec-driven development cho Claude Code — phỏng vấn có cấu trúc để xây dựng PRD, kiến trúc hệ thống, và integration specs. Domain knowledge và component/feature artifacts mọc dần qua cascade từ pha mô tả (`/spec-frd`), pha thiết kế (`/spec-sad`), lẫn integration (`/spec-new`).
4
4
 
5
5
  > **Lưu ý:** Hiện tại chỉ hoạt động với [Claude Code](https://claude.ai/code) (thư mục `.claude/`).
6
6
 
7
7
  ## Cài đặt
8
8
 
9
9
  ```bash
10
- npx spec-lite install
10
+ npx spec-lite@latest install
11
11
  ```
12
12
 
13
13
  Lệnh này copy `skills/` và `templates/` vào thư mục `.claude/` của project.
@@ -36,7 +36,7 @@ Sections: Problem Statement · Target Users · Scope · Features · Components
36
36
  #### `/spec-sad`
37
37
  Tạo hoặc cập nhật `.specs/main/sad.md`. Yêu cầu `prd.md` và `domain.md` đã tồn tại.
38
38
 
39
- Sections: Architectural Style · System Overview · Tech Stack · Cross-Cutting Concerns · Inter-Service Communication · Infrastructure Overview · Architectural Guardrails
39
+ Sections: Architectural Style · System Overview · Tech Stack · Cross-Cutting Concerns · Inter-Service Communication · Infrastructure Overview · Architectural Guardrails · ADR Log
40
40
 
41
41
  #### `/spec-frd [F-XXX]` *(tùy chọn)*
42
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).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-lite",
3
- "version": "1.4.3",
3
+ "version": "1.4.6",
4
4
  "description": "Spec-driven development kit for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -191,14 +191,14 @@ Các entities sau được dùng bởi nhiều components.
191
191
  Apply cascade proposals vào domain.md? [y/n/edit]
192
192
  ```
193
193
 
194
- Nếu `y` → update `.specs/main/domain.md` Shared Entities section, đồng thời append entry vào `## Change History` của domain.md (theo `conventions.md` §5.5):
194
+ Nếu `y` → update `.specs/main/domain.md` Shared Entities section — mỗi entity [NEW] dùng heading `### E-XXX {Entity Name}`, cấp ID tuần tự theo quy ước `domain-template.md` (max E-XXX đã từng cấp trong `domain.md` + 1, quét cả heading lẫn Change History; ID không tái sử dụng) — đồng thời append entry vào `## Change History` của domain.md (theo `conventions.md` §5.5):
195
195
 
196
196
  ```markdown
197
197
  ### {YYYY-MM-DD} — manual — update
198
198
 
199
199
  - **Shared Entities**:
200
- - [NEW] Order — owner C-003-payment, used by inventory (detected từ /spec-brownfield-component scan)
201
- - [NEW] User — owner C-001-auth, used by user/notification
200
+ - [NEW] E-001 Order — owner C-003-payment, used by inventory (detected từ /spec-brownfield-component scan)
201
+ - [NEW] E-002 User — owner C-001-auth, used by user/notification
202
202
  ```
203
203
 
204
204
  Nếu `edit` → hỏi chỉnh sửa từng entity trước khi apply.
@@ -236,7 +236,7 @@ Phần lớn auto từ scan. Chỉ hỏi 2 câu.
236
236
  [0] Chưa rõ → NEEDS_CLARIFY tất cả
237
237
  ```
238
238
 
239
- **7c. Hỏi additional constraints:**
239
+ **7c. Hỏi architectural decisions (→ ADR Log):**
240
240
 
241
241
  ```
242
242
  ❓ Có architectural decision nào quan trọng chưa detect được không?
@@ -245,6 +245,8 @@ Phần lớn auto từ scan. Chỉ hỏi 2 câu.
245
245
  [0] Không có thêm
246
246
  ```
247
247
 
248
+ Điền **ADR Log**: tạo ADR entry (status `accepted`) cho mỗi quyết định lớn — gồm cả các quyết định infer được ở 7a (architecture style, tech stack chính, communication) lẫn câu trả lời 7c. Mỗi entry ghi context/rationale + consequences ở mức suy luận được từ code; chỗ không chắc → NEEDS_CLARIFY.
249
+
248
250
  ---
249
251
 
250
252
  ### Bước 8: Review drafts
@@ -1,6 +1,6 @@
1
1
  ---
2
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.
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; cascade glossary term + định nghĩa shared entity lên domain, Owner TBD để /spec-sad gán) — reference component, KHÔNG tạo crd/cdd.
4
4
  ---
5
5
 
6
6
  # spec-frd
@@ -20,10 +20,11 @@ Skill này là cặp greenfield đối xứng với `/spec-brownfield-feature` (
20
20
  **Phạm vi hẹp — chủ yếu frd.md:**
21
21
  - ✅ Author frd.md (7 sections) cho **một** feature **chưa có frd**.
22
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).
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ệ lên prd).
24
+ - ✅ **Cascade vocabulary lên `domain.md`** (Bước 4b — pha *mô tả hệ thống*/WHAT): glossary term + **định nghĩa entity đầy đủ** (attributes). `Owner` của entity để `TBD` cho `/spec-sad` điền ở pha *thiết kế hệ thống* (HOW). BA duyệt trước khi ghi. Đây là điểm khác với phiên bản trước (`/spec-frd` từng không đụng domain) — vocabulary sinh ra ở feature-authoring time nên seed luôn, thay vì để domain rỗng tới integration đầu tiên.
24
25
  - ❌ KHÔNG tạo/sửa `crd.md`/`cdd.md` — component artifacts ra đời ở integration time qua `/spec-new` cascade.
25
26
  - ❌ 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
+ - ❌ KHÔNG carve component / quyết `Owner` của shared entity (để `/spec-sad`/`/spec-new`); KHÔNG đổi status feature đã có; KHÔNG đụng sad.
27
28
 
28
29
  ## When to Use
29
30
 
@@ -186,6 +187,34 @@ Lý do: giữ **một authority duy nhất** cho việc carve component (archite
186
187
 
187
188
  ---
188
189
 
190
+ ### Bước 4b: Trích domain vocabulary (glossary + định nghĩa entity)
191
+
192
+ Author frd là **điểm đầu tiên** business vocabulary xuất hiện cụ thể. Để `domain.md` không nằm rỗng tới integration đầu tiên (và để term không trôi/đụng nhau giữa các frd), skill seed vocabulary mới vào `domain.md` ngay tại BA-time. Giống VR và component candidate: **agent đề xuất, BA quyết** — không tự assert.
193
+
194
+ Đọc `domain.md` (đã load ở Bước 2) để biết Glossary/Shared Entities **đã có gì**, rồi rà draft frd tìm cái **mới**:
195
+
196
+ **1. Glossary term — ghi thẳng.** Thuật ngữ business xuất hiện trong frd mà chưa có trong domain Glossary. Glossary thuần vocabulary, không phụ thuộc component → cascade trực tiếp được. Với mỗi term đề xuất:
197
+ > Term mới phát hiện: **{term}** — đề xuất định nghĩa: "{định nghĩa}". Thêm vào domain Glossary? [y / sửa / bỏ]
198
+
199
+ Cấm: định nghĩa mơ hồ, hoặc nhét term thực ra là tên feature/component (không phải vocabulary nghiệp vụ).
200
+
201
+ **2. Entity — định nghĩa đầy đủ (WHAT), `Owner` để design-time điền.** Đây là điểm tách bạch quan trọng:
202
+
203
+ - **Define entity là *mô tả hệ thống* (WHAT)** → thuộc BA, làm ngay tại frd-time. BA định nghĩa entity đầy đủ: tên, mô tả, **attributes** (business type: text/number/money/date/email/phone), state machine nếu có lifecycle nghiệp vụ. Đây là vocabulary chung, không phải artifact hạng hai.
204
+ - **Entity *nằm ở component nào* (`Owner`) là *thiết kế hệ thống* (HOW)** → thuộc architect, điền ở `/spec-sad` (hoặc `/spec-new` khi carve). `/spec-frd` **không carve component** nên **không** quyết `Owner`.
205
+
206
+ Vì vậy khi seed entity vào domain Shared Entities:
207
+ - **Cấp Entity ID `E-XXX`** theo quy ước của `domain-template.md`: ID tiếp theo = max ID đã từng cấp trong `domain.md` + 1 (quét cả heading hiện có lẫn Change History — ID của entity đã remove không tái sử dụng). Heading entity: `### E-XXX {Entity Name}`.
208
+ - Điền đầy đủ definition + attributes từ frd.
209
+ - Để **`Owner: TBD (điền ở /spec-sad — design time)`** và **`Used by: TBD`**. Không phải vì entity "chưa chắc có thật", mà vì ownership là quyết định thiết kế chưa tới lượt.
210
+ - Entity rõ ràng chỉ là cấu trúc dữ liệu kỹ thuật nội bộ (không phải vocabulary nghiệp vụ) → không thuộc domain; bỏ qua, để lộ ra ở `crd.md` lúc carve.
211
+
212
+ > Entity feature mô tả: **{Entity}** với attributes {…}. Đây là vocabulary nghiệp vụ chung → mình seed định nghĩa vào domain (Owner để architect điền ở /spec-sad). Đồng ý? [y / sửa / bỏ]
213
+
214
+ BA quyết **định nghĩa entity** (WHAT); `Owner` để `/spec-sad` cascade bổ sung (HOW). Xem two-phase cascade ở `conventions.md` §5.5.
215
+
216
+ ---
217
+
189
218
  ### Bước 5: Write — sinh draft
190
219
 
191
220
  Dùng `.claude/templates/main/feature/frd-template.md` làm skeleton, điền nội dung từ interview.
@@ -194,7 +223,9 @@ Dùng `.claude/templates/main/feature/frd-template.md` làm skeleton, điền n
194
223
 
195
224
  **Frontmatter** frd mới: theo template, `status: draft`, `owner: BA`, `feature_id: F-XXX`.
196
225
 
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`.
226
+ Hiển thị **toàn bộ draft** cho user — chưa ghi file. Kèm:
227
+ - danh sách component candidate (nếu có) và VR còn `TBD`;
228
+ - **danh sách domain vocabulary đề xuất** (Bước 4b): glossary term mới + định nghĩa shared entity (`Owner: TBD`), để BA duyệt trước khi cascade lên `domain.md`.
198
229
 
199
230
  #### Verification Rules — quy ước sinh
200
231
 
@@ -215,6 +246,7 @@ Hiển thị **toàn bộ draft** cho user — chưa ghi file. Kèm danh sách c
215
246
  > - User Stories + AC đo được chưa?
216
247
  > - Verification Rules đã confirm với BA chưa (không còn TBD ngoài ý muốn)?
217
248
  > - Components Used đúng chưa? Component candidate (nếu có) có hợp lý để chuyển cho /spec-sad không?
249
+ > - Glossary term / định nghĩa shared entity đề xuất cascade lên domain đã đúng chưa? (term có phải vocabulary nghiệp vụ thật, entity có đáng là shared không, attributes đủ chưa?)
218
250
 
219
251
  Chỉ ghi file sau khi user confirm. Yêu cầu chỉnh → cập nhật draft → hỏi lại.
220
252
 
@@ -251,15 +283,37 @@ Và append Change History entry vào prd.md (theo `conventions.md` §5.5):
251
283
  - [NEW] F-XXX — {tên} (registered qua /spec-frd)
252
284
  ```
253
285
 
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.
286
+ Đây là side-effect hợp lệ 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.
287
+
288
+ **7b''. (Chỉ khi Bước 4b/6 BA đã confirm vocabulary)** Cascade lên `.specs/main/domain.md`:
289
+
290
+ - **Glossary** → append row `[NEW]` cho mỗi term đã confirm: `| {term} | {định nghĩa} | {example/context} |`.
291
+ - **Shared Entities** → cho mỗi entity đã confirm, thêm một entry mới theo template với heading `### E-XXX {Entity Name}` (ID cấp ở Bước 4b — tuần tự, không tái sử dụng), definition + attributes đầy đủ, để `**Owner:** TBD (điền ở /spec-sad — design time)` và `**Used by:** TBD`. Trong frd, reference entity theo dạng `E-XXX {Entity Name}` để trace về domain.md.
255
292
 
256
- **7c. KHÔNG đụng 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.
293
+ Append **một** Change History entry vào `domain.md`, operation = `manual` (author trực tiếp ngoài integration cùng quy ước với 7b, theo `conventions.md` §5.5):
294
+
295
+ ```markdown
296
+ ### {YYYY-MM-DD} — manual — update
297
+
298
+ - **Glossary**:
299
+ - [NEW] {term} — {mô tả ngắn} (qua /spec-frd F-XXX)
300
+ - **Shared Entities**:
301
+ - [NEW] E-XXX {Entity} — định nghĩa + attributes; Owner TBD chờ /spec-sad (qua /spec-frd F-XXX)
302
+ ```
303
+
304
+ (Nếu domain.md đang là skeleton create lần đầu thì entry vẫn `manual`/`update` — file đã được `/spec-prd` scaffold với operation `create` từ trước.) Atomic với 7a: domain cascade fail → rollback cả frd. `Owner` của entity do `/spec-sad`/`/spec-new` cascade bổ sung sau (HOW phase) qua `[MODIFY Owner]`.
305
+
306
+ **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 carve component / không tự quyết `Owner` của shared entity. Không tạo crd/cdd/fdd/tsd. Không đụng sad.
257
307
 
258
308
  **7d. Thông báo kết quả:**
259
309
 
260
310
  ```
261
311
  ✓ .specs/main/feature/{F-XXX}-{slug}/frd.md đã được tạo (status: draft)
262
312
 
313
+ {nếu có} Domain cascade (pha mô tả hệ thống):
314
+ - Glossary: +{N} term
315
+ - Shared Entities: +{N} entity (định nghĩa đầy đủ; Owner TBD — chờ /spec-sad gán ở pha thiết kế)
316
+
263
317
  {nếu có} Component candidate cần carve (chuyển cho architect / integration):
264
318
  - {tên đề xuất} — {vai trò}
265
319
 
@@ -269,7 +323,7 @@ Và append Change History entry vào prd.md (theo `conventions.md` §5.5):
269
323
  Bước tiếp theo:
270
324
  - /spec-tsd F-XXX → QC bootstrap test spec từ frd này
271
325
  - /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
326
+ {nếu có candidate hoặc entity Owner TBD} - /spec-sad → architect chốt boundary component + gán Owner cho shared entity
273
327
  ```
274
328
 
275
329
  ---
@@ -282,6 +336,8 @@ Bước tiếp theo:
282
336
  | "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
337
  | "Verification rule mình tự điền cho nhanh" | VR là business decision. Agent tự assert = rule sai mà không ai review. |
284
338
  | "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. |
339
+ | "BA gán luôn Owner component cho entity cho gọn" | Ownership là quyết định *thiết kế* (HOW). BA gán sớm = boundary sai sớm. Để `Owner: TBD`, `/spec-sad` điền. |
340
+ | "Entity chưa biết owner thì khoan ghi vào domain" | Define entity là *mô tả* (WHAT) — độc lập với việc nó nằm ở component nào. Ghi định nghĩa luôn, Owner điền sau. |
285
341
 
286
342
  ## Red Flags
287
343
 
@@ -306,6 +362,7 @@ Bước tiếp theo:
306
362
  - [ ] ID bắt đầu từ 001 (create mới)
307
363
  - [ ] Components Used reference C-XXX có sẵn; component mới ghi candidate + surface cho /spec-sad
308
364
  - [ ] 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`)
365
+ - [ ] Domain cascade (nếu có vocabulary mới, đã BA confirm): Glossary term ghi đủ định nghĩa; Shared Entity ghi đủ definition + attributes với `Owner: TBD` (KHÔNG tự gán C-XXX); domain.md có Change History entry operation = `manual`
366
+ - [ ] KHÔNG tạo crd/cdd/fdd/tsd; KHÔNG carve component / gán Owner entity; KHÔNG đụng sad
367
+ - [ ] Change History entry (frd) operation = `manual` (luôn `create`)
311
368
  - [ ] User đã confirm trước khi ghi file
@@ -258,8 +258,10 @@ Tạo block nếu integration:
258
258
 
259
259
  Tạo block nếu integration:
260
260
  - Giới thiệu glossary term mới → row [NEW] trong Glossary
261
- - Giới thiệu shared entity mới (entity sẽ được dùng bởi 2+ component) → entity [NEW] với `Owner: C-XXX`
262
- - Sửa định nghĩa entity hiện → entity [MODIFY ...]
261
+ - Giới thiệu shared entity mới (entity sẽ được dùng bởi 2+ component) → entity [NEW] với heading `### E-XXX {Entity Name}` (auto-pick `E-XXX` next available — quy ước `domain-template.md`: max ID đã từng cấp trong `domain.md` + 1, quét cả heading lẫn Change History; ID không tái sử dụng) và `Owner: C-XXX` (component đã carve trong integration này); component chưa carve → `Owner: TBD`, `/spec-sad` gán sau (xem two-phase cascade `conventions.md` §5.5)
262
+ - Gán owner cho entity còn `Owner: TBD` (do pha mô tả seed) → entity [MODIFY Owner] `TBD → C-XXX` (giữ nguyên `E-XXX`)
263
+ - Sửa định nghĩa entity hiện có → entity [MODIFY ...] (giữ nguyên `E-XXX`)
264
+ - Remove entity → [REMOVE] kèm lý do — ID của entity đã remove vẫn giữ chỗ, không cấp lại
263
265
 
264
266
  **`sad.md`**
265
267
 
@@ -9,7 +9,7 @@ description: Điền hoặc cập nhật prd.md — Product Requirements Documen
9
9
 
10
10
  Tạo nội dung cho `.specs/main/prd.md` thông qua interview có cấu trúc. PRD là nguồn sự thật ở product level — nó định nghĩa vấn đề, users, scope, features, components, và NFRs trước khi bất kỳ technical decision nào được đưa ra.
11
11
 
12
- Skill này cũng scaffold `.specs/main/domain.md` skeleton nếu chưa tồn tại — domain.md sẽ được mọc dần qua cascade từ integrations (glossary terms, shared entities).
12
+ Skill này cũng scaffold `.specs/main/domain.md` skeleton nếu chưa tồn tại — domain.md mọc dần qua cascade hai pha: mô tả (`/spec-frd`, `/spec-new` seed glossary + định nghĩa entity, `Owner: TBD`) và thiết kế (`/spec-sad` gán `Owner`). Xem two-phase cascade `conventions.md` §5.5.
13
13
 
14
14
  PRD không chứa: tech stack, implementation details, entity schema, glossary, business rules — những thứ đó thuộc về `sad.md` hoặc `domain.md`.
15
15
 
@@ -46,6 +46,32 @@ Chạy qua các phép thử; đa số phiếu nghiêng đâu thì xếp vào đ
46
46
  | **Đặt tên** | Danh từ hệ thống (`auth`, `payment`) | Luồng nghiệp vụ (`checkout-flow`, `password-reset`) |
47
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
48
 
49
+ ### Mục có tính chất kép — vừa Feature vừa Component
50
+
51
+ Litmus test ở trên giả định mỗi mục rơi vào **một** bucket. Nhưng một số mục có **hai mặt** và xứng đáng đăng ký ở **cả hai** index — kinh điển là `auth`:
52
+
53
+ - **Mặt trải nghiệm người dùng** (đăng nhập SSO/OTP, có Flows + User Stories + Acceptance Criteria) → **Feature**.
54
+ - **Mặt năng lực cross-cutting** (RBAC enforce mọi endpoint, session) mà mọi feature khác tham chiếu → **Component**.
55
+
56
+ **Phép thử tính kép** — một mục là *cả hai* khi thỏa CẢ hai điều kiện:
57
+
58
+ 1. Nó là component **Given** (xem Given/Derived bên dưới — thường trúng câu 2 Mandated-substrate), VÀ
59
+ 2. Nó có một **trải nghiệm người dùng** (Flows/US/AC) mà (a) **không** biểu diễn được trong `crd.md` (CRD chỉ có Role/Responsibilities/Interface/Business Rules — KHÔNG có Flows/User Stories/Acceptance Criteria), và (b) **không** thuộc sở hữu của feature nào khác.
60
+
61
+ Nếu kép → đăng ký **một Feature (F-XXX)** cho mặt UX + **một Component (C-XXX)** cho mặt năng lực, và chia trách nhiệm dứt khoát:
62
+ - Flows / User Stories / Acceptance Criteria / rule của luồng → **Feature** (`frd.md`), trỏ tới component qua mục "Components Used".
63
+ - Năng lực dùng chung + interface + rule nội bộ → **Component** (`crd.md`/`cdd.md`). Mô tả component **thu hẹp** về mặt năng lực, ghi rõ "UX thuộc F-XXX".
64
+
65
+ | Ứng viên | Mặt Feature (UX) | Mặt Component (năng lực) | Kết luận |
66
+ | --- | --- | --- | --- |
67
+ | auth | login SSO/OTP, lockout | RBAC enforce, session/token | **kép** |
68
+ | notification | notification center (chuông/panel, mark-read) | kênh gửi email + push dùng chung | **kép** |
69
+ | file-storage | document repository (upload/preview/download) | blob storage + access control | **kép** |
70
+ | payment-gateway / e-signature / erp-adapter | — (UX nằm trong feature tiêu thụ) | adapter tích hợp ngoài | **component-only** |
71
+ | checkout, password-reset | luồng nghiệp vụ | — (không năng lực cross-cutting) | **feature-only** |
72
+
73
+ **Cảnh báo:** đa số component **External** (câu 1 — adapter Stripe/DocuSign/BC) là **component-only** — trải nghiệm dùng chúng (thanh toán, ký, xem dữ liệu BC) thuộc về các feature tiêu thụ, bản thân adapter không có UX riêng. Tính kép chủ yếu xuất hiện ở component **Mandated-substrate** (câu 2: auth, notification, file-storage).
74
+
49
75
  ### Quy tắc đặt tên (cho cả Feature và Component)
50
76
 
51
77
  **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.
@@ -92,6 +118,7 @@ Input là **baseline, không phải chân lý tuyệt đối**:
92
118
 
93
119
  - Reuse tên/ID/boundary nếu input đã có → không tự đẻ cấu trúc song song.
94
120
  - 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).
121
+ - Chạy **Phép thử tính kép** cho mọi component Given. Nếu input gọi X là "component" (vd `auth`) nhưng X cũng có trải nghiệm người dùng riêng (SSO/OTP flow, có Flows/US/AC) không thuộc feature khác → flag, đề xuất đăng ký **thêm** một Feature cho mặt UX và thu hẹp component về mặt năng lực — đừng để mặt UX không có nhà.
95
122
  - 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
123
  - Phần input thiếu → mới interview để bù.
97
124
 
@@ -205,6 +232,8 @@ Sau đó hỏi tuần tự, từng phần một — không hỏi tất cả cùn
205
232
  > - **Given** (trúng câu 1 External hoặc câu 2 Mandated-substrate) → khai vào Component Index.
206
233
  > - **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
234
  >
235
+ > Với mỗi component **Given** (nhất là Mandated-substrate), chạy thêm **Phép thử tính kép** (xem section "Mục có tính chất kép"): nếu nó cũng có trải nghiệm người dùng riêng (Flows/US/AC) không thuộc feature khác → đăng ký **thêm** một Feature cho mặt UX vào Phần 4, và thu hẹp mô tả component về mặt năng lực. Vd `auth` → Feature `authentication` (login UX) + Component `auth` (RBAC enforce).
236
+ >
208
237
  > **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 đủ.
209
238
 
210
239
  **Phần 6 — Non-Functional Requirements:**
@@ -300,7 +329,8 @@ Trước khi kết thúc, kiểm tra:
300
329
  - [ ] Out of Scope có ít nhất 1 item với lý do
301
330
  - [ ] 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
331
  - [ ] Components: mọi entry là **Given** (trúng câu 1 External hoặc câu 2 Mandated-substrate). Không có 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 sẵn feature/component: đã reuse làm baseline, đã validate qua litmus + Given/Derived, đã flag mục phân loại sai (nếu )
332
+ - [ ] Đã chạy **Phép thử tính kép** cho mọi component Given: mục cả mặt UX riêng (vd auth/notification/file-storage) được đăng ký ở **CẢ** Feature Index lẫn Component Index, tả mỗi mặt thu hẹp đúng phạm vi (UX→feature, năng lực→component)
333
+ - [ ] Nếu input context có sẵn feature/component: đã reuse làm baseline, đã validate qua litmus + Given/Derived + Phép thử tính kép, đã flag mục phân loại sai (nếu có)
304
334
  - [ ] Mỗi NFR có target đo được (không phải "nhanh", "bảo mật chung chung")
305
335
  - [ ] domain.md tồn tại (đã scaffold skeleton hoặc có nội dung sẵn)
306
336
  - [ ] User đã confirm trước khi file được ghi
@@ -428,7 +428,7 @@ Component shared (vẫn còn feature khác dùng):
428
428
  - {term} [REMOVE] — unique to F-XXX, no other reference
429
429
 
430
430
  #### Shared Entities
431
- - {Entity} [REMOVE] — orphan after F-XXX removal, no other component owns
431
+ - E-XXX {Entity} [REMOVE] — orphan after F-XXX removal, no other component owns. ID `E-XXX` của entity đã remove **vẫn giữ chỗ** (ghi trong Change History) — không bao giờ cấp lại cho entity mới (quy ước `domain-template.md`)
432
432
 
433
433
  ## Out of Scope
434
434
  - {Migration của reverse-dep features tới alternative — separate integration nếu có}
@@ -11,6 +11,8 @@ Tạo nội dung cho `.specs/main/sad.md` thông qua interview có cấu trúc.
11
11
 
12
12
  SAD không chứa: feature-level design, business rules, entity details — những thứ đó thuộc về `domain.md` và `fdd.md`.
13
13
 
14
+ **Một side-effect cascade lên `domain.md`:** carve component là việc *thiết kế hệ thống* (HOW), nên `/spec-sad` là nơi gán **`Owner`** cho các shared entity mà pha *mô tả hệ thống* (WHAT — qua `/spec-prd`/`/spec-frd`/`/spec-new`) đã định nghĩa nhưng để `Owner: TBD`. SAD không chứa entity content; nó chỉ điền cột ownership còn trống. Xem two-phase cascade ở `conventions.md` §5.5.
15
+
14
16
  **Guardrails là phần quan trọng nhất của SAD.** Thiếu guardrails = agent tự quyết định tech pattern mà không có constraint.
15
17
 
16
18
  ## When to Use
@@ -42,7 +44,7 @@ SAD không chứa: feature-level design, business rules, entity details — nh
42
44
  - **Chưa tồn tại** → dừng ngay:
43
45
  > `domain.md` chưa được scaffold. Hãy chạy `/spec-prd` trước (skill này scaffold cả `prd.md` và `domain.md` skeleton).
44
46
 
45
- - **Đã tồn tại** → đọc để hiểu: glossary và shared entities (nếu có). Lưu ý `domain.md` có thể chỉ mới là skeleton vì nội dung chi tiết mọc dần qua cascade từ integrations — không cần dừng nếu file mỏng.
47
+ - **Đã tồn tại** → đọc để hiểu: glossary và shared entities (nếu có). Lưu ý `domain.md` có thể chỉ mới là skeleton vì nội dung chi tiết mọc dần qua cascade từ integrations — không cần dừng nếu file mỏng. **Ghi nhận các shared entity có `Owner: TBD`** (do pha mô tả seed) → đây là danh sách cần gán owner ở Bước 2 (Phần 1.6).
46
48
 
47
49
  **Đọc `.specs/main/sad.md`:**
48
50
 
@@ -61,6 +63,7 @@ SAD không chứa: feature-level design, business rules, entity details — nh
61
63
  | 5 | Inter-Service Communication | ✓ đã có / ✗ trống/thiếu |
62
64
  | 6 | Infrastructure Overview | ✓ đã có / ✗ trống/thiếu |
63
65
  | 7 | Architectural Guardrails | ✓ đã có / ✗ trống/thiếu |
66
+ | 8 | ADR Log | ✓ đã có / ✗ trống/thiếu |
64
67
 
65
68
  Một section được coi là **trống/thiếu** nếu: không tồn tại trong file, hoặc chỉ chứa placeholder template (dấu `{}`), hoặc không có dòng nội dung thực. Ngoài các sections trên, **ghi nhận các sections thừa** — những `##` heading có trong file nhưng không có trong template.
66
69
 
@@ -73,9 +76,10 @@ SAD không chứa: feature-level design, business rules, entity details — nh
73
76
  [3] Tech Stack ✓ đã có
74
77
  [4] Cross-Cutting Concerns ✗ chưa có — cần bổ sung
75
78
  [5] Inter-Service Communication ✓ đã có
76
- [6] ADR Log ⚠ không trong template
77
- [7] Infrastructure Overview ✓ đã có
78
- [8] Architectural Guardrails ✓ đã
79
+ [6] Infrastructure Overview ✓ đã
80
+ [7] Architectural Guardrails ✓ đã có
81
+ [8] ADR Log ✗ chưa — cần bổ sung
82
+ [9] Deployment Diagram ⚠ không có trong template
79
83
  [A] Interview tất cả sections
80
84
 
81
85
  Chọn số hoặc A:
@@ -117,6 +121,20 @@ Nếu user muốn đề xuất → đề xuất 2-3 option với trade-offs rõ
117
121
 
118
122
  Nếu `prd.md > Components` còn rỗng (brownfield init chưa scan code, hoặc greenfield chưa biết component) → để placeholder và note rằng bảng này sẽ được điền khi Component Index có nội dung (qua `/spec-brownfield-component` hoặc cascade từ integration).
119
123
 
124
+ **Phần 1.6 — Gán Owner cho shared entity (cascade lên domain):**
125
+
126
+ Sau khi component boundaries đã rõ (từ Components table), với mỗi shared entity có `Owner: TBD` (ghi nhận ở Bước 1):
127
+ > Entity **{Entity}** (định nghĩa ở domain) nên được component nào sở hữu canonical definition?
128
+ > - {C-XXX} — {tên}
129
+ > - {C-YYY} — {tên}
130
+ > Và những component nào reference nó (Used by)?
131
+
132
+ - Gán `Owner: C-XXX` (component giữ canonical definition) + `Used by: C-XXX, C-YYY`.
133
+ - Nếu hoá ra entity chỉ một component dùng → vẫn ghi `Owner`, `Used by` chỉ component đó; cân nhắc note rằng nó có thể chuyển về `crd.md` nội bộ (không bắt buộc xử lý ở đây).
134
+ - Component Index còn rỗng → để nguyên `Owner: TBD`, gán sau khi component được carve.
135
+
136
+ Đây là nửa **thiết kế hệ thống (HOW)** của domain cascade — bổ sung ownership cho định nghĩa entity mà pha mô tả đã tạo. Ghi xuống ở Bước 5.
137
+
120
138
  **Phần 2 — Tech Stack:**
121
139
  > Tech stack cho từng layer: Frontend, Backend, Database, Infrastructure?
122
140
  > Với mỗi lựa chọn: lý do chọn là gì? (performance, team familiarity, ecosystem...)
@@ -146,6 +164,12 @@ Nếu user chưa quyết định layer nào → đề xuất options dựa trên
146
164
  - Nếu có external API → `GUARD-XXX: Mọi external API call phải có retry + timeout`
147
165
  - Nếu layered architecture → `GUARD-XXX: Không để business logic trong API/controller layer`
148
166
 
167
+ **Phần 7 — ADR Log:**
168
+ > Trong quá trình thảo luận vừa rồi, những quyết định nào là *quan trọng và có đánh đổi*? (chọn architectural style, tech chính, sync vs async...)
169
+ > Với mỗi cái, tôi sẽ ghi một ADR entry: quyết định + bối cảnh/lý do + hệ quả.
170
+
171
+ Tự đề xuất ADR-001+ từ chính các lựa chọn user đã chốt ở Phần 1–6 (style, tech stack, communication) — không bắt user nhập lại từ đầu. Status mặc định `accepted`. Nếu chưa có quyết định nào đáng ghi → để placeholder.
172
+
149
173
  ---
150
174
 
151
175
  ### Bước 3: Write — sinh draft
@@ -179,9 +203,21 @@ Ghi nội dung đã được confirm vào `.specs/main/sad.md`.
179
203
 
180
204
  Nếu chạy lần thứ N (sad.md đã có) → operation = `update`, body liệt kê section đã đổi với mô tả ngắn.
181
205
 
206
+ **Cascade Owner lên `domain.md` (nếu Phần 1.6 gán owner cho entity TBD):** apply `[MODIFY Owner]` + `[MODIFY Used by]` vào các entity tương ứng trong `domain.md > Shared Entities`, rồi append **một** Change History entry vào `domain.md`, operation = `manual`:
207
+
208
+ ```markdown
209
+ ### {YYYY-MM-DD} — manual — update
210
+
211
+ - **Shared Entities**:
212
+ - [MODIFY Owner] {Entity} — TBD → {C-XXX} (gán ownership qua /spec-sad)
213
+ ```
214
+
215
+ Atomic với việc ghi sad.md. Không tạo entity mới ở đây (đó là pha mô tả); chỉ điền `Owner`/`Used by` còn `TBD`.
216
+
182
217
  Thông báo kết quả:
183
218
  ```
184
219
  ✓ .specs/main/sad.md đã được cập nhật (status: draft)
220
+ {nếu có} ✓ domain.md — gán Owner cho {N} shared entity (TBD → C-XXX)
185
221
 
186
222
  Bước tiếp theo:
187
223
  - /spec-new {feature-name} → định nghĩa requirements của từng feature
@@ -216,4 +252,5 @@ Trước khi kết thúc, kiểm tra:
216
252
  - [ ] Mỗi tech stack item có lý do chọn rõ ràng
217
253
  - [ ] Tất cả 4 cross-cutting concerns đã được điền (auth, error, logging, caching)
218
254
  - [ ] Guardrails có ít nhất 3 item, mỗi item cụ thể và actionable
255
+ - [ ] Shared entity có `Owner: TBD` đã được gán `Owner: C-XXX` + `Used by` (nếu Component Index đã có nội dung); cascade `[MODIFY Owner]` lên domain.md + Change History entry operation `manual`
219
256
  - [ ] User đã confirm — đặc biệt phần Guardrails — trước khi ghi file
@@ -154,8 +154,8 @@ Tổng hợp và viết draft `tech.md`:
154
154
  ### domain.md
155
155
 
156
156
  Đề xuất cập nhật nếu integration này:
157
- - Thay đổi shared entity (entity được dùng bởi 2+ component)
158
- - Thêm shared entity mới phát sinh từ thiết kế kỹ thuật
157
+ - Thay đổi shared entity (entity được dùng bởi 2+ component) — giữ nguyên `E-XXX` đã cấp
158
+ - Thêm shared entity mới phát sinh từ thiết kế kỹ thuật — heading `### E-XXX {Entity Name}`, cấp ID theo quy ước `domain-template.md`: max E-XXX đã từng cấp trong `domain.md` + 1 (quét cả heading lẫn Change History); ID không tái sử dụng
159
159
 
160
160
  ### component/{C-XXX}-{component-name}/cdd.md
161
161
 
@@ -9,12 +9,12 @@ Dùng khi bắt đầu dự án mới chưa có code. Mục tiêu: bootstrap `pr
9
9
  | Command | Reads | Writes |
10
10
  | --- | --- | --- |
11
11
  | `/spec-prd` | — *(tùy chọn: nguồn baseline path/@file/paste)* | `.specs/main/prd.md`, `.specs/main/domain.md` *(skeleton)* |
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)* |
12
+ | `/spec-sad` | `prd.md`, `domain.md` | `.specs/main/sad.md` *(+ gán `Owner` cho shared entity còn TBD trong `domain.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; + cascade glossary/entity vào `domain.md`)* |
14
14
 
15
15
  ### `/spec-prd`
16
16
 
17
- Tạo hoặc cập nhật `.specs/main/prd.md` thông qua interview có cấu trúc. Ngoài ra **scaffold luôn `.specs/main/domain.md` skeleton** (Glossary placeholder + Shared Entities rỗng) — domain mọc dần qua cascade từ integrations.
17
+ Tạo hoặc cập nhật `.specs/main/prd.md` thông qua interview có cấu trúc. Ngoài ra **scaffold luôn `.specs/main/domain.md` skeleton** (Glossary placeholder + Shared Entities rỗng) — domain mọc dần qua cascade hai pha: mô tả (`/spec-frd`, `/spec-new` seed glossary + định nghĩa entity) và thiết kế (`/spec-sad` gán `Owner`).
18
18
 
19
19
  **Sections template** (7): Problem Statement · Target Users · Scope · Features · Components · Non-Functional Requirements · Business Constraints
20
20
 
@@ -37,7 +37,9 @@ Tạo hoặc cập nhật `.specs/main/sad.md`. Yêu cầu `prd.md` và `domain.
37
37
 
38
38
  Trước khi interview, đọc `prd.md` (NFRs, constraints) và `domain.md` (glossary, shared entities) để surface assumptions và đề xuất options phù hợp khi user chưa quyết định.
39
39
 
40
- **Sections template** (7): Architectural Style · System Overview · Tech Stack · Cross-Cutting Concerns · Inter-Service Communication · Infrastructure Overview · Architectural Guardrails
40
+ **Cascade lên `domain.md` (pha thiết kế/HOW):** carve component việc thiết kế, nên sau khi Components rõ, `/spec-sad` gán `Owner: C-XXX` + `Used by` cho shared entity mà pha mô tả (`/spec-frd`/`/spec-new`) để `Owner: TBD`. Đây là nửa HOW của domain two-phase cascade.
41
+
42
+ **Sections template** (8): Architectural Style · System Overview · Tech Stack · Cross-Cutting Concerns · Inter-Service Communication · Infrastructure Overview · Architectural Guardrails · ADR Log
41
43
 
42
44
  **Khi file chưa tồn tại** → full interview tuần tự từng section.
43
45
 
@@ -65,8 +67,10 @@ Nhận F-XXX từ argument (hoặc chọn từ prd Feature Index) + tùy chọn
65
67
  **Phạm vi hẹp — chủ yếu `frd.md`:**
66
68
  - Reference component frd phụ thuộc (Components Used → C-XXX có sẵn).
67
69
  - 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
+ - Có thể register **một** feature row vào prd (side-effect lên prd).
71
+ - **Cascade vocabulary lên `domain.md`** (pha tả/WHAT): glossary term + **định nghĩa shared entity** (attributes), `Owner: TBD` để `/spec-sad` gán ở pha thiết kế (HOW). BA define entity, KHÔNG carve/gán Owner.
72
+ - **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.
73
+ - Change History operation = `manual` (cả frd lẫn domain). Verification Rules dùng quy ước option-suggester của `/spec-new` (BA owns).
70
74
 
71
75
  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
76
 
@@ -119,7 +119,7 @@ Thường là update — thêm glossary term, thêm shared entity, sửa entity
119
119
  - Row [NEW]: `Refund — số tiền hoàn lại cho user sau khi order bị hủy`
120
120
 
121
121
  #### Shared Entities
122
- - Entity [NEW]: `Refund (Owner: C-005-refund-processor)` — { fields, relationships }
122
+ - Entity [NEW]: `E-XXX Refund (Owner: C-005-refund-processor)` — { fields, relationships } — E-XXX = next available trong domain.md (tuần tự theo thứ tự seed, không tái sử dụng — xem domain-template.md)
123
123
  -->
124
124
 
125
125
  ### sad.md *(bỏ nếu không có thay đổi)*
@@ -6,13 +6,15 @@ owner: "{BA/Domain Expert}"
6
6
  referenced_by:
7
7
  - conventions.md > 3. Main Artifacts > 3.1 Product level > domain.md > Cấu trúc
8
8
  - skills/spec-prd/SKILL.md > Process > Bước 5: Save (scaffold domain.md skeleton)
9
+ - skills/spec-frd/SKILL.md > Process > Bước 4b (cascade glossary + entity definition — WHAT)
10
+ - skills/spec-sad/SKILL.md > Process > Phần 1.6 (gán Owner cho shared entity — HOW)
9
11
  - skills/spec-new/SKILL.md > Process > Cascade Proposals > domain.md
10
12
  - skills/spec-tech/SKILL.md > Process > Cascade Proposals > domain.md
11
13
  ---
12
14
 
13
15
  # Domain
14
16
 
15
- > File này mỏng — chỉ chứa **shared vocabulary** và **shared entities** (entities được dùng bởi 2+ component).
17
+ > File này mỏng — chỉ chứa **shared vocabulary** và **shared entities** (entity mức vocabulary nghiệp vụ chung, dự kiến dùng bởi 2+ component; việc dùng-bởi-2+ và `Owner` được xác nhận ở pha thiết kế).
16
18
  >
17
19
  > Business rules, domain events, internal entities thuộc về component sở hữu — xem `.specs/main/component/{C-XXX}-{component-name}/crd.md`.
18
20
 
@@ -26,13 +28,22 @@ referenced_by:
26
28
 
27
29
  ## Shared Entities
28
30
 
29
- Chỉ liệt entity được dùng bởi **2 hoặc nhiều component**. Entity nội bộ một component không vào đây — chúng nằm trong `crd.md` của component đó.
31
+ Entity mức vocabulary nghiệp vụ chung. Hai phần thông tin tới từ hai pha (xem two-phase cascade, `conventions.md` §5.5):
32
+ - **Định nghĩa** (tên, attributes, state machine) — *mô tả hệ thống* (WHAT): seed bởi `/spec-prd`/`/spec-frd`/`/spec-new`.
33
+ - **`Owner` / `Used by`** — *thiết kế hệ thống* (HOW): gán bởi `/spec-sad` (hoặc `/spec-new` khi carve component). Khi entity vừa được seed mà component chưa carve → để `Owner: TBD`.
30
34
 
31
- ### {Entity Name}
35
+ Entity rõ ràng nội bộ một component (không phải vocabulary chung) không vào đây — chúng nằm trong `crd.md` của component đó.
32
36
 
33
- **Owner:** `{C-XXX}-{component-name}` *(component sở hữu canonical definition)*
37
+ **Entity ID (`E-XXX`):** mỗi shared entity được cấp một ID tuần tự khi seed lần đầu, theo thứ tự được thêm vào file này.
38
+ - ID tiếp theo = **max ID đã từng cấp + 1** — quét cả heading hiện có **và** Change History (entity đã `[REMOVE]` vẫn giữ chỗ ID của nó).
39
+ - ID **không bao giờ tái sử dụng** và **không đánh lại** khi entity bị remove hoặc đổi tên.
40
+ - Reference từ artifact khác (frd/crd/spec/tech) dùng dạng `E-XXX {Entity Name}`.
34
41
 
35
- **Used by:** `{C-XXX}`, `{C-YYY}` *(các component reference entity này)*
42
+ ### E-XXX {Entity Name}
43
+
44
+ **Owner:** `{C-XXX}-{component-name}` *(component sở hữu canonical definition; `TBD` nếu chưa carve — `/spec-sad` điền)*
45
+
46
+ **Used by:** `{C-XXX}`, `{C-YYY}` *(các component reference entity này; `TBD` cho tới khi gán Owner)*
36
47
 
37
48
  {Mô tả entity này đại diện cho cái gì trong business context.}
38
49
 
@@ -75,6 +75,14 @@ Các nguyên tắc sau là bất biến. Agent phải kiểm tra compliance trư
75
75
  - GUARD-002: {nguyên tắc — ví dụ: Mọi external API call phải có retry + timeout}
76
76
  - GUARD-003: {nguyên tắc — ví dụ: Không để business logic trong API layer}
77
77
 
78
+ ## ADR Log
79
+
80
+ Architecture Decision Records — ghi lại các quyết định kiến trúc quan trọng cùng bối cảnh và hệ quả. Nắm *tại sao* chọn (điều mà Guardrails và Tech Stack không giải thích), giúp người sau hiểu trade-off thay vì đoán lại. Mỗi quyết định lớn (chọn style, tech chính, đánh đổi đáng kể) nên có một entry.
81
+
82
+ | ID | Decision | Status | Context & Rationale | Consequences |
83
+ | --- | --- | --- | --- | --- |
84
+ | ADR-001 | {quyết định ngắn gọn} | proposed / accepted / deprecated / superseded | {bối cảnh + lý do chọn, các option đã cân nhắc} | {hệ quả, đánh đổi phải chấp nhận} |
85
+
78
86
  ## Change History
79
87
 
80
88
  Append-only log của các thay đổi cascade lên artifact này. Quy ước xem `conventions.md` §5.5.