spec-lite 1.4.3 → 1.4.5
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 +2 -2
- package/package.json +1 -1
- package/skills/spec-brownfield-init/SKILL.md +3 -1
- package/skills/spec-frd/SKILL.md +65 -9
- package/skills/spec-new/SKILL.md +2 -1
- package/skills/spec-prd/SKILL.md +32 -2
- package/skills/spec-sad/SKILL.md +41 -4
- package/skills-overview.md +10 -6
- package/templates/main/domain-template.md +10 -4
- package/templates/main/sad-template.md +8 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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ừ
|
|
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
|
|
|
@@ -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
|
@@ -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
|
|
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
|
package/skills/spec-frd/SKILL.md
CHANGED
|
@@ -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ệ
|
|
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
|
|
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,33 @@ 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
|
+
- Điền đầy đủ definition + attributes từ frd.
|
|
208
|
+
- Để **`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.
|
|
209
|
+
- 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.
|
|
210
|
+
|
|
211
|
+
> 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ỏ]
|
|
212
|
+
|
|
213
|
+
BA quyết **định nghĩa entity** (WHAT); `Owner` để `/spec-sad` cascade bổ sung (HOW). Xem two-phase cascade ở `conventions.md` §5.5.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
189
217
|
### Bước 5: Write — sinh draft
|
|
190
218
|
|
|
191
219
|
Dùng `.claude/templates/main/feature/frd-template.md` làm skeleton, điền nội dung từ interview.
|
|
@@ -194,7 +222,9 @@ Dùng `.claude/templates/main/feature/frd-template.md` làm skeleton, điền n
|
|
|
194
222
|
|
|
195
223
|
**Frontmatter** frd mới: theo template, `status: draft`, `owner: BA`, `feature_id: F-XXX`.
|
|
196
224
|
|
|
197
|
-
Hiển thị **toàn bộ draft** cho user — chưa ghi file. Kèm
|
|
225
|
+
Hiển thị **toàn bộ draft** cho user — chưa ghi file. Kèm:
|
|
226
|
+
- danh sách component candidate (nếu có) và VR còn `TBD`;
|
|
227
|
+
- **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
228
|
|
|
199
229
|
#### Verification Rules — quy ước sinh
|
|
200
230
|
|
|
@@ -215,6 +245,7 @@ Hiển thị **toàn bộ draft** cho user — chưa ghi file. Kèm danh sách c
|
|
|
215
245
|
> - User Stories + AC đo được chưa?
|
|
216
246
|
> - Verification Rules đã confirm với BA chưa (không còn TBD ngoài ý muốn)?
|
|
217
247
|
> - Components Used đúng chưa? Component candidate (nếu có) có hợp lý để chuyển cho /spec-sad không?
|
|
248
|
+
> - 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
249
|
|
|
219
250
|
Chỉ ghi file sau khi user confirm. Yêu cầu chỉnh → cập nhật draft → hỏi lại.
|
|
220
251
|
|
|
@@ -251,15 +282,37 @@ Và append Change History entry vào prd.md (theo `conventions.md` §5.5):
|
|
|
251
282
|
- [NEW] F-XXX — {tên} (registered qua /spec-frd)
|
|
252
283
|
```
|
|
253
284
|
|
|
254
|
-
Đây là
|
|
285
|
+
Đâ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.
|
|
286
|
+
|
|
287
|
+
**7b''. (Chỉ khi Bước 4b/6 BA đã confirm vocabulary)** Cascade lên `.specs/main/domain.md`:
|
|
288
|
+
|
|
289
|
+
- **Glossary** → append row `[NEW]` cho mỗi term đã confirm: `| {term} | {định nghĩa} | {example/context} |`.
|
|
290
|
+
- **Shared Entities** → cho mỗi entity đã confirm, thêm một entry mới theo template với definition + attributes đầy đủ, để `**Owner:** TBD (điền ở /spec-sad — design time)` và `**Used by:** TBD`.
|
|
255
291
|
|
|
256
|
-
**
|
|
292
|
+
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):
|
|
293
|
+
|
|
294
|
+
```markdown
|
|
295
|
+
### {YYYY-MM-DD} — manual — update
|
|
296
|
+
|
|
297
|
+
- **Glossary**:
|
|
298
|
+
- [NEW] {term} — {mô tả ngắn} (qua /spec-frd F-XXX)
|
|
299
|
+
- **Shared Entities**:
|
|
300
|
+
- [NEW] {Entity} — định nghĩa + attributes; Owner TBD chờ /spec-sad (qua /spec-frd F-XXX)
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
(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]`.
|
|
304
|
+
|
|
305
|
+
**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
306
|
|
|
258
307
|
**7d. Thông báo kết quả:**
|
|
259
308
|
|
|
260
309
|
```
|
|
261
310
|
✓ .specs/main/feature/{F-XXX}-{slug}/frd.md đã được tạo (status: draft)
|
|
262
311
|
|
|
312
|
+
{nếu có} Domain cascade (pha mô tả hệ thống):
|
|
313
|
+
- Glossary: +{N} term
|
|
314
|
+
- Shared Entities: +{N} entity (định nghĩa đầy đủ; Owner TBD — chờ /spec-sad gán ở pha thiết kế)
|
|
315
|
+
|
|
263
316
|
{nếu có} Component candidate cần carve (chuyển cho architect / integration):
|
|
264
317
|
- {tên đề xuất} — {vai trò}
|
|
265
318
|
|
|
@@ -269,7 +322,7 @@ Và append Change History entry vào prd.md (theo `conventions.md` §5.5):
|
|
|
269
322
|
Bước tiếp theo:
|
|
270
323
|
- /spec-tsd F-XXX → QC bootstrap test spec từ frd này
|
|
271
324
|
- /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
|
|
325
|
+
{nếu có candidate hoặc entity Owner TBD} - /spec-sad → architect chốt boundary component + gán Owner cho shared entity
|
|
273
326
|
```
|
|
274
327
|
|
|
275
328
|
---
|
|
@@ -282,6 +335,8 @@ Bước tiếp theo:
|
|
|
282
335
|
| "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
336
|
| "Verification rule mình tự điền cho nhanh" | VR là business decision. Agent tự assert = rule sai mà không ai review. |
|
|
284
337
|
| "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. |
|
|
338
|
+
| "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. |
|
|
339
|
+
| "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
340
|
|
|
286
341
|
## Red Flags
|
|
287
342
|
|
|
@@ -306,6 +361,7 @@ Bước tiếp theo:
|
|
|
306
361
|
- [ ] ID bắt đầu từ 001 (create mới)
|
|
307
362
|
- [ ] Components Used reference C-XXX có sẵn; component mới ghi candidate + surface cho /spec-sad
|
|
308
363
|
- [ ] Nếu register feature mới: prd Features có row [NEW] + Change History entry; status feature đã có KHÔNG đổi
|
|
309
|
-
- [ ]
|
|
310
|
-
- [ ]
|
|
364
|
+
- [ ] 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`
|
|
365
|
+
- [ ] KHÔNG tạo crd/cdd/fdd/tsd; KHÔNG carve component / gán Owner entity; KHÔNG đụng sad
|
|
366
|
+
- [ ] Change History entry (frd) operation = `manual` (luôn `create`)
|
|
311
367
|
- [ ] User đã confirm trước khi ghi file
|
package/skills/spec-new/SKILL.md
CHANGED
|
@@ -258,7 +258,8 @@ 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`
|
|
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` (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`
|
|
262
263
|
- Sửa định nghĩa entity hiện có → entity [MODIFY ...]
|
|
263
264
|
|
|
264
265
|
**`sad.md`**
|
package/skills/spec-prd/SKILL.md
CHANGED
|
@@ -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
|
|
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
|
-
- [ ]
|
|
332
|
+
- [ ] Đã chạy **Phép thử tính kép** cho mọi component Given: mục có cả mặt UX riêng (vd auth/notification/file-storage) được đăng ký ở **CẢ** Feature Index lẫn Component Index, mô 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
|
package/skills/spec-sad/SKILL.md
CHANGED
|
@@ -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]
|
|
77
|
-
[7]
|
|
78
|
-
[8]
|
|
79
|
+
[6] Infrastructure Overview ✓ đã có
|
|
80
|
+
[7] Architectural Guardrails ✓ đã có
|
|
81
|
+
[8] ADR Log ✗ chưa có — 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
|
package/skills-overview.md
CHANGED
|
@@ -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
|
|
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
|
-
**
|
|
40
|
+
**Cascade lên `domain.md` (pha thiết kế/HOW):** carve component là 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
|
|
69
|
-
-
|
|
70
|
+
- Có thể register **một** feature row vào prd (side-effect lên prd).
|
|
71
|
+
- **Cascade vocabulary lên `domain.md`** (pha mô 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
|
|
|
@@ -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** (
|
|
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,17 @@ referenced_by:
|
|
|
26
28
|
|
|
27
29
|
## Shared Entities
|
|
28
30
|
|
|
29
|
-
|
|
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`.
|
|
34
|
+
|
|
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 đó.
|
|
30
36
|
|
|
31
37
|
### {Entity Name}
|
|
32
38
|
|
|
33
|
-
**Owner:** `{C-XXX}-{component-name}` *(component sở hữu canonical definition)*
|
|
39
|
+
**Owner:** `{C-XXX}-{component-name}` *(component sở hữu canonical definition; `TBD` nếu chưa carve — `/spec-sad` điền)*
|
|
34
40
|
|
|
35
|
-
**Used by:** `{C-XXX}`, `{C-YYY}` *(các component reference entity này)*
|
|
41
|
+
**Used by:** `{C-XXX}`, `{C-YYY}` *(các component reference entity này; `TBD` cho tới khi gán Owner)*
|
|
36
42
|
|
|
37
43
|
{Mô tả entity này đại diện cho cái gì trong business context.}
|
|
38
44
|
|
|
@@ -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.
|