spec-lite 1.4.1 → 1.4.3
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 +31 -18
- package/package.json +1 -1
- package/skills/ado-config/SKILL.md +1 -1
- package/skills/ado-create/SKILL.md +7 -7
- package/skills/ado-update/SKILL.md +1 -1
- package/skills/archive/SKILL.md +19 -19
- package/skills/build/SKILL.md +5 -5
- package/skills/plan/SKILL.md +6 -6
- package/skills/review-everything/SKILL.md +9 -9
- package/skills/review-integration/SKILL.md +7 -7
- package/skills/scaffold/SKILL.md +9 -9
- package/skills/spec-brownfield-component/SKILL.md +11 -11
- package/skills/spec-brownfield-feature/SKILL.md +13 -13
- package/skills/spec-brownfield-init/SKILL.md +13 -13
- package/skills/spec-frd/SKILL.md +311 -0
- package/skills/spec-frd-update/SKILL.md +9 -9
- package/skills/spec-new/SKILL.md +11 -11
- package/skills/spec-prd/SKILL.md +115 -16
- package/skills/spec-remove/SKILL.md +27 -27
- package/skills/spec-sad/SKILL.md +6 -6
- package/skills/spec-tech/SKILL.md +16 -16
- package/skills/spec-test/SKILL.md +15 -15
- package/skills/spec-tsd/SKILL.md +10 -10
- package/skills-overview.md +49 -24
- package/templates/main/domain-template.md +1 -1
- package/templates/main/feature/frd-template.md +2 -1
- package/templates/main/prd-template.md +16 -1
|
@@ -7,7 +7,7 @@ description: Discover features từ code, generate frd.md + fdd.md cho từng fe
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Tạo
|
|
10
|
+
Tạo `.specs/main/feature/{F-XXX}-{feature-name}/frd.md` và `fdd.md` cho các features trong brownfield project.
|
|
11
11
|
|
|
12
12
|
Skill này **tự discover** features từ routes, use cases, và test files, sau đó scan sâu để extract user stories, AC, và inter-component flows. Khi hoàn thành, **điền Feature Index vào prd.md**.
|
|
13
13
|
|
|
@@ -33,9 +33,9 @@ Skill này **tự discover** features từ routes, use cases, và test files, sa
|
|
|
33
33
|
**Path:** Nếu có ARGUMENT là path → dùng làm root. Nếu không → CWD.
|
|
34
34
|
|
|
35
35
|
**Load:**
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
36
|
+
- `.specs/main/prd.md` — kiểm tra Component Index đã được điền
|
|
37
|
+
- `.specs/main/domain.md` — đọc Glossary và Shared Entities
|
|
38
|
+
- `.specs/main/component/*/crd.md` — đọc Public Interface của từng component (để cross-reference trong fdd.md)
|
|
39
39
|
|
|
40
40
|
**Kiểm tra preconditions:**
|
|
41
41
|
|
|
@@ -46,7 +46,7 @@ Nếu `prd.md` Component Index còn trống (không có C-XXX entries) → dừn
|
|
|
46
46
|
> Component Index chưa có entries. Hãy chạy `/spec-brownfield-component` trước.
|
|
47
47
|
> fdd.md cần tham chiếu C-XXX để mô tả inter-component flows.
|
|
48
48
|
|
|
49
|
-
Nếu
|
|
49
|
+
Nếu `.specs/main/component/` không có crd.md nào → cảnh báo tương tự và dừng.
|
|
50
50
|
|
|
51
51
|
**Attachments:**
|
|
52
52
|
> Bạn có tài liệu bổ sung nào không? (user stories, test plans, wireframes, existing specs)
|
|
@@ -216,10 +216,10 @@ Với mỗi feature, generate 2 files dùng templates tương ứng:
|
|
|
216
216
|
|
|
217
217
|
```
|
|
218
218
|
Sẽ tạo {N} features ({2N} files):
|
|
219
|
-
✓ specs/main/feature/F-001-user-registration/frd.md (4 NEEDS_CLARIFY)
|
|
220
|
-
✓ specs/main/feature/F-001-user-registration/fdd.md (2 NEEDS_CLARIFY)
|
|
221
|
-
✓ specs/main/feature/F-002-authentication/frd.md (1 NEEDS_CLARIFY)
|
|
222
|
-
✓ specs/main/feature/F-002-authentication/fdd.md (0 NEEDS_CLARIFY)
|
|
219
|
+
✓ .specs/main/feature/F-001-user-registration/frd.md (4 NEEDS_CLARIFY)
|
|
220
|
+
✓ .specs/main/feature/F-001-user-registration/fdd.md (2 NEEDS_CLARIFY)
|
|
221
|
+
✓ .specs/main/feature/F-002-authentication/frd.md (1 NEEDS_CLARIFY)
|
|
222
|
+
✓ .specs/main/feature/F-002-authentication/fdd.md (0 NEEDS_CLARIFY)
|
|
223
223
|
...
|
|
224
224
|
|
|
225
225
|
Ghi tất cả? [y] hoặc review từng file trước [r]:
|
|
@@ -237,7 +237,7 @@ Ghi tất cả? [y] hoặc review từng file trước [r]:
|
|
|
237
237
|
|
|
238
238
|
### Bước 8: Điền Feature Index vào prd.md
|
|
239
239
|
|
|
240
|
-
Sau khi artifacts đã được ghi, update
|
|
240
|
+
Sau khi artifacts đã được ghi, update `.specs/main/prd.md` Feature Index:
|
|
241
241
|
|
|
242
242
|
```
|
|
243
243
|
Sẽ điền Feature Index vào prd.md:
|
|
@@ -267,8 +267,8 @@ Khi apply → đồng thời append entry vào `## Change History` của prd.md
|
|
|
267
267
|
|
|
268
268
|
```
|
|
269
269
|
✓ Generated {N} features:
|
|
270
|
-
specs/main/feature/F-001-user-registration/ (frd.md + fdd.md)
|
|
271
|
-
specs/main/feature/F-002-authentication/ (frd.md + fdd.md)
|
|
270
|
+
.specs/main/feature/F-001-user-registration/ (frd.md + fdd.md)
|
|
271
|
+
.specs/main/feature/F-002-authentication/ (frd.md + fdd.md)
|
|
272
272
|
...
|
|
273
273
|
|
|
274
274
|
✓ prd.md Feature Index: {N} entries đã được điền
|
|
@@ -279,7 +279,7 @@ NEEDS_CLARIFY summary — {total} items:
|
|
|
279
279
|
...
|
|
280
280
|
|
|
281
281
|
Brownfield init hoàn tất! Main artifacts:
|
|
282
|
-
specs/main/
|
|
282
|
+
.specs/main/
|
|
283
283
|
├── prd.md (Component Index: {N} | Feature Index: {N})
|
|
284
284
|
├── domain.md (Glossary: {N} terms | Shared Entities: {N})
|
|
285
285
|
├── sad.md
|
|
@@ -7,7 +7,7 @@ description: Khởi tạo main artifacts (prd.md, domain.md, sad.md) cho brownfi
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Tạo
|
|
10
|
+
Tạo `.specs/main/prd.md`, `.specs/main/domain.md`, và `.specs/main/sad.md` cho một project đã tồn tại.
|
|
11
11
|
|
|
12
12
|
Skill này chỉ tập trung vào **product và architecture level** — những gì có thể extract từ README, docs, config, và kiến trúc tổng thể. Component Index và Feature Index trong prd.md sẽ **để trống** — chúng sẽ được điền bởi `/spec-brownfield-component` và `/spec-brownfield-feature` sau khi scan code chuyên sâu.
|
|
13
13
|
|
|
@@ -17,9 +17,9 @@ Mỗi file output được sinh ra từ template tương ứng — đọc templa
|
|
|
17
17
|
|
|
18
18
|
| Output file | Template |
|
|
19
19
|
| --- | --- |
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
20
|
+
| `.specs/main/prd.md` | `templates/main/prd-template.md` |
|
|
21
|
+
| `.specs/main/domain.md` | `templates/main/domain-template.md` |
|
|
22
|
+
| `.specs/main/sad.md` | `templates/main/sad-template.md` |
|
|
23
23
|
|
|
24
24
|
Giữ nguyên cấu trúc section và frontmatter từ template. Điền nội dung thu thập được từ scan và interview vào đúng vị trí.
|
|
25
25
|
|
|
@@ -32,7 +32,7 @@ Thông tin không thể detect từ code được đánh dấu nhất quán:
|
|
|
32
32
|
## When to Use
|
|
33
33
|
|
|
34
34
|
- Onboarding một brownfield project vào SDD workflow
|
|
35
|
-
-
|
|
35
|
+
- `.specs/main/prd.md` chưa có hoặc còn trống
|
|
36
36
|
|
|
37
37
|
## When NOT to Use
|
|
38
38
|
|
|
@@ -63,14 +63,14 @@ Load tất cả attachments trước khi scan. Dùng làm context bổ sung tron
|
|
|
63
63
|
|
|
64
64
|
### Bước 2: Kiểm tra existing specs
|
|
65
65
|
|
|
66
|
-
Kiểm tra
|
|
66
|
+
Kiểm tra `.specs/main/prd.md`, `.specs/main/domain.md`, `.specs/main/sad.md`:
|
|
67
67
|
|
|
68
68
|
Nếu một trong ba đã có nội dung thực → cảnh báo:
|
|
69
69
|
|
|
70
70
|
```
|
|
71
71
|
⚠ File đã có nội dung:
|
|
72
|
-
- specs/main/prd.md
|
|
73
|
-
- specs/main/sad.md
|
|
72
|
+
- .specs/main/prd.md
|
|
73
|
+
- .specs/main/sad.md
|
|
74
74
|
|
|
75
75
|
Skill này sẽ overwrite các file trên. Tiếp tục? [y/n]
|
|
76
76
|
```
|
|
@@ -253,7 +253,7 @@ Hiển thị draft từng file lần lượt. Với mỗi file:
|
|
|
253
253
|
|
|
254
254
|
```
|
|
255
255
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
256
|
-
DRAFT: specs/main/{file}
|
|
256
|
+
DRAFT: .specs/main/{file}
|
|
257
257
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
258
258
|
{nội dung draft}
|
|
259
259
|
|
|
@@ -270,7 +270,7 @@ Confirm? [y] Bỏ qua [n] Chỉnh sửa [e]:
|
|
|
270
270
|
|
|
271
271
|
### Bước 9: Save
|
|
272
272
|
|
|
273
|
-
Tạo
|
|
273
|
+
Tạo `.specs/main/` nếu chưa có. Ghi các files đã được confirm.
|
|
274
274
|
|
|
275
275
|
**Change History:** Append entry vào section `## Change History` cuối mỗi file vừa ghi (`prd.md`, `domain.md`, `sad.md`) theo `conventions.md` §5.5:
|
|
276
276
|
|
|
@@ -281,9 +281,9 @@ Tạo `specs/main/` nếu chưa có. Ghi các files đã được confirm.
|
|
|
281
281
|
```
|
|
282
282
|
|
|
283
283
|
```
|
|
284
|
-
✓ specs/main/prd.md (Component Index và Feature Index: placeholder — chưa có)
|
|
285
|
-
✓ specs/main/domain.md (Glossary: {n} terms | Shared Entities: trống — sẽ mọc qua cascade)
|
|
286
|
-
✓ specs/main/sad.md
|
|
284
|
+
✓ .specs/main/prd.md (Component Index và Feature Index: placeholder — chưa có)
|
|
285
|
+
✓ .specs/main/domain.md (Glossary: {n} terms | Shared Entities: trống — sẽ mọc qua cascade)
|
|
286
|
+
✓ .specs/main/sad.md
|
|
287
287
|
|
|
288
288
|
NEEDS_CLARIFY summary — {total} items cần làm rõ:
|
|
289
289
|
prd.md: {n} — [Problem Statement, Business Constraints, ...]
|
|
@@ -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
|
|
@@ -7,7 +7,7 @@ description: Migrate frd.md hiện có lên cấu trúc template mới nhất
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Migrate các file
|
|
10
|
+
Migrate các file `.specs/main/feature/{F-XXX}-{slug}/frd.md` hiện có sang **format mới nhất** của [templates/main/feature/frd-template.md](../../templates/main/feature/frd-template.md).
|
|
11
11
|
|
|
12
12
|
Skill này **chỉ làm migration mechanical + propose** — không phải BA interview. Mọi quyết định nội dung mới (Verification Rules content) đều cần user approve trước khi ghi.
|
|
13
13
|
|
|
@@ -67,7 +67,7 @@ Chạy `git status --porcelain`. Nếu output không rỗng (có file modified /
|
|
|
67
67
|
Hãy commit hoặc stash thay đổi hiện tại trước khi chạy `/spec-frd-update`, rồi chạy lại.
|
|
68
68
|
|
|
69
69
|
Files dirty:
|
|
70
|
-
M specs/main/feature/F-001-auth/frd.md
|
|
70
|
+
M .specs/main/feature/F-001-auth/frd.md
|
|
71
71
|
?? notes.md
|
|
72
72
|
```
|
|
73
73
|
|
|
@@ -80,7 +80,7 @@ Nếu repo không phải git repo → cảnh báo và yêu cầu confirm:
|
|
|
80
80
|
|
|
81
81
|
### Bước 1: Discover & classify
|
|
82
82
|
|
|
83
|
-
Quét
|
|
83
|
+
Quét `.specs/main/feature/*/frd.md`. Với mỗi file:
|
|
84
84
|
|
|
85
85
|
1. Parse headings và frontmatter.
|
|
86
86
|
2. Run detection cho V1–V8.
|
|
@@ -123,11 +123,11 @@ Với mỗi FRD đã chọn, load các file sau (chỉ những gì cần thiết
|
|
|
123
123
|
|
|
124
124
|
| File | Bắt buộc | Mục đích |
|
|
125
125
|
|---|---|---|
|
|
126
|
-
|
|
|
126
|
+
| `.specs/main/feature/{F-XXX}-{slug}/frd.md` | ✓ | File cần migrate |
|
|
127
127
|
| [templates/main/feature/frd-template.md](../../templates/main/feature/frd-template.md) | ✓ | Target structure — copy text cho V2/V3/V5 |
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
128
|
+
| `.specs/main/feature/{F-XXX}-{slug}/fdd.md` | nếu tồn tại | Cascade target cho V4 (AC→FAC rename) |
|
|
129
|
+
| `.specs/main/feature/{F-XXX}-{slug}/tsd.md` | nếu tồn tại | Cascade target cho V4 |
|
|
130
|
+
| `.specs/main/domain.md` (Shared Entities block) | optional | Cho V6 — match field name với entity glossary để pick semantic type consistent |
|
|
131
131
|
|
|
132
132
|
**KHÔNG load:**
|
|
133
133
|
- `conventions.md` — template đã self-contained, load là thừa
|
|
@@ -183,7 +183,7 @@ Với mỗi FRD đã chọn, load các file sau (chỉ những gì cần thiết
|
|
|
183
183
|
```
|
|
184
184
|
|
|
185
185
|
#### 4.3 Scan cascade references
|
|
186
|
-
- Grep toàn
|
|
186
|
+
- Grep toàn `.specs/` cho từng ID cũ.
|
|
187
187
|
- **CRITICAL**: chỉ remap những match THUỘC Feature AC (Bước 4.1 list). KHÔNG đụng Story AC trùng namespace `AC-F{NNN}-{seq}` — đây là string overlap nhưng khác counter.
|
|
188
188
|
- Tạo bảng impact:
|
|
189
189
|
```
|
|
@@ -358,7 +358,7 @@ Cho mỗi FRD đã migrate:
|
|
|
358
358
|
|
|
359
359
|
Nếu artifact chưa có section `## Change History` (vì template cũ) → tạo section mới ở cuối file rồi append entry. Đây cũng là một migration vector ngầm — đảm bảo mọi main artifact sau migration đều có Change History section.
|
|
360
360
|
|
|
361
|
-
Rollback (nếu user phát hiện sai sau khi skill xong): `git checkout -- specs/main/feature/{F-XXX}-{slug}/` để revert toàn bộ feature dir, hoặc `git restore -p` để revert per-hunk.
|
|
361
|
+
Rollback (nếu user phát hiện sai sau khi skill xong): `git checkout -- .specs/main/feature/{F-XXX}-{slug}/` để revert toàn bộ feature dir, hoặc `git restore -p` để revert per-hunk.
|
|
362
362
|
|
|
363
363
|
Append vào [changelogs.md](../../changelogs.md) `## [Unreleased]`:
|
|
364
364
|
|
package/skills/spec-new/SKILL.md
CHANGED
|
@@ -7,7 +7,7 @@ description: Tạo spec.md cho một integration mới thông qua interview có
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Tạo `spec.md` cho một integration mới trong
|
|
10
|
+
Tạo `spec.md` cho một integration mới trong `.specs/integrations/{NNN}-{slug}/`.
|
|
11
11
|
|
|
12
12
|
`spec.md` là functional spec — định nghĩa **what to build**: vấn đề, requirements, acceptance criteria, out of scope. Không chứa technical design.
|
|
13
13
|
|
|
@@ -33,7 +33,7 @@ Tạo `spec.md` cho một integration mới trong `specs/integrations/{NNN}-{slu
|
|
|
33
33
|
|
|
34
34
|
**Nếu không có ARGUMENT:**
|
|
35
35
|
|
|
36
|
-
Đọc
|
|
36
|
+
Đọc `.specs/main/prd.md`. Nếu file không tồn tại hoặc là template rỗng → dừng:
|
|
37
37
|
> `prd.md` chưa có nội dung. Hãy chạy `/spec-prd` trước.
|
|
38
38
|
|
|
39
39
|
Đọc toàn bộ bảng Features. Hiển thị **tất cả** features kèm trạng thái — không lọc — để thấy rõ feature nào có FRD cần update:
|
|
@@ -50,7 +50,7 @@ Features trong PRD:
|
|
|
50
50
|
Chọn số feature để bắt đầu spec:
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
Ghi chú `→ frd.md tồn tại` nếu file
|
|
53
|
+
Ghi chú `→ frd.md tồn tại` nếu file `.specs/main/feature/{F-XXX}-*/frd.md` đã có.
|
|
54
54
|
|
|
55
55
|
Nếu tất cả features đều Done → thông báo:
|
|
56
56
|
> Tất cả features trong prd.md đã được implement. Nếu có yêu cầu mới, hãy truyền nó trực tiếp: `/spec-new <yêu cầu>`.
|
|
@@ -88,10 +88,10 @@ Lưu lại lựa chọn section.
|
|
|
88
88
|
|
|
89
89
|
Từ raw requirement, agent xác định features và components liên quan, rồi load các file sau:
|
|
90
90
|
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
91
|
+
- `.specs/main/prd.md` — đọc Problem Statement, Target Users, Scope, Feature Index, Component Index; **đặc biệt ghi nhận cột `ADO` trong bảng Features** — nếu feature đã có ticket ID thì lưu lại `{feature_id → ado_ticket_id, ado_ticket_title, ado_ticket_url}`
|
|
92
|
+
- `.specs/main/domain.md` — đọc Glossary và Shared Entities
|
|
93
|
+
- `.specs/main/feature/{F-XXX}-{slug}/frd.md` — cho mỗi feature liên quan (nếu file đã tồn tại)
|
|
94
|
+
- `.specs/main/component/{C-XXX}-{slug}/crd.md` — cho mỗi component bị touched (nếu file đã tồn tại)
|
|
95
95
|
|
|
96
96
|
Tóm tắt context và surface assumptions:
|
|
97
97
|
|
|
@@ -150,11 +150,11 @@ Từ title của integration, sinh slug:
|
|
|
150
150
|
- Nếu từ prd.md: dùng `{feature-id}-{feature-slug}`, ví dụ: `f001-authentication`
|
|
151
151
|
|
|
152
152
|
Xác định số thứ tự (`NNN`):
|
|
153
|
-
- Liệt kê các thư mục hiện có trong
|
|
153
|
+
- Liệt kê các thư mục hiện có trong `.specs/integrations/` theo pattern `{NNN}-*`
|
|
154
154
|
- Lấy số lớn nhất hiện có và cộng thêm 1, format 3 chữ số (ví dụ: `001`, `002`, `012`)
|
|
155
155
|
- Nếu chưa có thư mục nào → bắt đầu từ `001`
|
|
156
156
|
|
|
157
|
-
Output path:
|
|
157
|
+
Output path: `.specs/integrations/{NNN}-{slug}/spec.md`
|
|
158
158
|
|
|
159
159
|
---
|
|
160
160
|
|
|
@@ -339,7 +339,7 @@ Chỉ tiến hành Bước 7 sau khi user confirm. Nếu user yêu cầu chỉnh
|
|
|
339
339
|
|
|
340
340
|
### Bước 7: Save + Auto-cascade
|
|
341
341
|
|
|
342
|
-
Tạo thư mục
|
|
342
|
+
Tạo thư mục `.specs/integrations/{NNN}-{slug}/` nếu chưa có.
|
|
343
343
|
|
|
344
344
|
**[7.1] Ghi spec.md** với status `approved` (không phải `draft` — human đã confirm ở Bước 6 chính là approval). Frontmatter `features` và `components` phải được điền theo những gì đã nhận diện ở Bước 2.
|
|
345
345
|
|
|
@@ -391,7 +391,7 @@ Cho mỗi artifact:
|
|
|
391
391
|
**[7.4] Thông báo kết quả:**
|
|
392
392
|
|
|
393
393
|
```
|
|
394
|
-
✓ specs/integrations/{NNN}-{slug}/spec.md đã được tạo (status: approved)
|
|
394
|
+
✓ .specs/integrations/{NNN}-{slug}/spec.md đã được tạo (status: approved)
|
|
395
395
|
|
|
396
396
|
Auto-cascade applied:
|
|
397
397
|
✓ prd.md — {summary}
|