spec-lite 1.4.7 → 1.5.1

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
@@ -151,10 +151,13 @@ Sau khi có findings, hỏi user severity tier muốn xử lý (Critical / Criti
151
151
 
152
152
  Skill ad-hoc dùng khi template đã được update và artifacts hiện có cần migrate. Không phải pipeline — chạy khi cần.
153
153
 
154
- #### `/spec-frd-update`
155
- Migrate `feature/*/frd.md` hiện có sang format mới nhất của [frd-template.md](.claude/templates/main/feature/frd-template.md). Detect 8 migration vectors: fix Mermaid syntax `[{...}]` → `["..."]`, rename `Feature-level AC` → `Feature AC` với 4 nhóm chuẩn, rename `AC-F{NNN}-*` (Feature AC) → `FAC-F{NNN}-*` + cascade ID remap qua `fdd.md`/`tsd.md`/`integrations/*/{spec,tech,test}.md`, insert US/AC stability notes + Verification Rules, derive Mermaid User Flows từ User Stories, v.v.
154
+ Mỗi **main** template mang `template_version` (số nguyên) trong frontmatter; main artifact copy nó lúc được tạo. Khi template đổi structure, main artifact cũ thành "lỗi thời" — hai skill dưới phát hiện và migrate. **Chỉ áp dụng cho main artifacts** (integration artifacts ephemeral nên không versioned). Quy ước đầy đủ: [conventions.md](conventions.md) §7.
156
155
 
157
- Pre-flight yêu cầu git working tree clean — rollback dùng `git checkout -- {file}`, **không** tạo file `.bak`. V4 (FAC remap), V6 (Verification Rules propose), V8 (User Flows propose) đều có confirm step trước khi ghi. No-op safe: nếu mọi FRD đã clean, skill dừng mà không ghi gì.
156
+ #### `/artifact-audit [type]`
157
+ Phát hiện **main artifact** lỗi thời. So `template_version` của artifact với version đọc thẳng từ template. Versioned: `==` → up-to-date; `!=` → out-dated `(vX → vY)` → migrate. Legacy thiếu version → presence-check (đủ required `##` headings + không còn section đã `migrations.remove`): conform → stamp version; lệch → out-dated. Chỉ phát hiện + stamp, KHÔNG migrate. Scope theo arg (1 main type / list) hoặc mọi main type.
158
+
159
+ #### `/artifact-migrate [path]`
160
+ Migrate **main artifact** lỗi thời lên structure mới (mọi main type). Tự chạy `/artifact-audit` (classify-only) để phát hiện, rồi áp delta từ block `migrations` của template: **add** required section thiếu (skeleton từ template; nội dung mới → interview hoặc `NEEDS_CLARIFY`, không bịa), **remove** section đã `migrations.remove` (có confirm; giữ content tác giả khác), **update** section đổi format (giữ section + ngữ nghĩa, vd ASCII → Mermaid; show cũ + đề xuất mới, không bịa). Rename = remove+add → hỏi carry-over. Single-artifact, không cascade. Pre-flight git clean — rollback dùng git, không `.bak`. No-op nếu đã up-to-date.
158
161
 
159
162
  ---
160
163
 
@@ -169,7 +172,8 @@ Pre-flight yêu cầu git working tree clean — rollback dùng `git checkout --
169
172
  | `/spec-brownfield-component` | `.specs/main/component/{C-XXX}-*/crd.md + cdd.md` |
170
173
  | `/spec-brownfield-feature` | `.specs/main/feature/{F-XXX}-*/frd.md + fdd.md` |
171
174
  | `/spec-tsd` | `.specs/main/feature/{F-XXX}-*/tsd.md` |
172
- | `/spec-frd-update` | *(modify in-place `feature/*/frd.md` + cascade refs)* |
175
+ | `/artifact-audit` | *(báo cáo out-dated; + stamp `template_version` cho main artifact legacy conform)* |
176
+ | `/artifact-migrate` | *(modify in-place main artifact lỗi thời lên structure mới + set `template_version`)* |
173
177
  | `/spec-new` | `.specs/integrations/{slug}/spec.md` |
174
178
  | `/spec-tech` | `.specs/integrations/{slug}/tech.md` |
175
179
  | `/spec-test` | `.specs/integrations/{slug}/test.md`, cascade: `feature/{F-XXX}/tsd.md` |
package/bin/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { cpSync, mkdirSync, existsSync } from 'fs'
2
+ import { cpSync, mkdirSync, existsSync, readFileSync, writeFileSync } from 'fs'
3
3
  import { join, dirname } from 'path'
4
4
  import { fileURLToPath } from 'url'
5
5
 
@@ -11,6 +11,8 @@ if (command === 'install') {
11
11
  const pkgRoot = join(__dirname, '..')
12
12
  const claudeDir = join(cwd, '.claude')
13
13
 
14
+ const pkg = JSON.parse(readFileSync(join(pkgRoot, 'package.json'), 'utf8'))
15
+
14
16
  mkdirSync(claudeDir, { recursive: true })
15
17
 
16
18
  // Copy skills → .claude/skills/
@@ -28,6 +30,25 @@ if (command === 'install') {
28
30
  // Copy references → .claude/references/
29
31
  cpSync(join(pkgRoot, 'references'), join(claudeDir, 'references'), { recursive: true })
30
32
  console.log('✓ references → .claude/references/')
33
+
34
+ // Write install metadata → .claude/spec-lite.json
35
+ const metaPath = join(claudeDir, 'spec-lite.json')
36
+ const prev = existsSync(metaPath)
37
+ ? JSON.parse(readFileSync(metaPath, 'utf8'))
38
+ : null
39
+ const now = new Date().toISOString()
40
+ const meta = {
41
+ name: pkg.name,
42
+ version: pkg.version,
43
+ installedAt: prev?.installedAt ?? now,
44
+ updatedAt: now,
45
+ contents: ['skills', 'templates', 'references'],
46
+ }
47
+ writeFileSync(metaPath, JSON.stringify(meta, null, 2) + '\n')
48
+ const action = prev
49
+ ? `updated ${prev.version} → ${pkg.version}`
50
+ : `installed ${pkg.version}`
51
+ console.log(`✓ spec-lite.json → .claude/spec-lite.json (${action})`)
31
52
  } else {
32
53
  console.log('Usage: npx spec-lite install')
33
54
  process.exit(1)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-lite",
3
- "version": "1.4.7",
3
+ "version": "1.5.1",
4
4
  "description": "Spec-driven development kit for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: artifact-audit
3
+ description: Audit MAIN artifacts trong .specs/main/ xem có lỗi thời so với template không (chỉ main artifacts — prd/domain/sad/frd/fdd/tsd/crd/cdd; integration artifacts ngoài scope). So `template_version` của artifact với `template_version` hiện tại đọc thẳng từ template (.claude/templates/). Versioned khớp → up-to-date, lệch → out-dated (in vX → vY). Artifact thiếu version (sinh trước versioning) → đối chiếu structure với template: khớp thì stamp version, lệch thì flag out-dated. KHÔNG tự migrate — chỉ stamp khi chắc chắn khớp + báo cáo. Nhận tùy chọn 1 hay nhiều main type làm scope (vd `frd`, `frd,crd`); không có arg → audit mọi main type.
4
+ ---
5
+
6
+ # artifact-audit
7
+
8
+ ## Overview
9
+
10
+ Trả lời một câu hỏi: **main artifact nào trong `.specs/main/` đã lỗi thời so với template mới nhất?**
11
+
12
+ > **Scope = chỉ main artifacts** (`prd`, `domain`, `sad`, `frd`, `fdd`, `tsd`, `crd`, `cdd` — đều nằm dưới `.specs/main/`). Integration artifacts (`spec`, `tech`, `test`, `plan`, `todo`, `techdebt` dưới `.specs/integrations/`) **không** thuộc scope của skill này — chúng là ephemeral và immutable sau khi `done`, không audit/migrate theo version.
13
+
14
+ Cơ chế (xem `conventions.md` §7 Template Versioning):
15
+ - **Nguồn sự thật** = `template_version` trong frontmatter template đang cài (`.claude/templates/...`). Đọc thẳng lúc chạy — không manifest, không cache.
16
+ - Mỗi artifact mang `template_version` (copy lúc CREATE bởi skill sinh nó). Audit so số artifact với số template.
17
+
18
+ Skill này **chỉ phát hiện + stamp legacy**, **KHÔNG migrate**. Việc đưa structure artifact lên format mới là của `/artifact-migrate` (cho mọi main type).
19
+
20
+ ## When to Use
21
+
22
+ - Sau khi `git pull` kit mới (template có thể đã bump version) → xem artifact nào cần migrate.
23
+ - Audit định kỳ một main type cụ thể (`/artifact-audit frd`) hoặc mọi main type (`/artifact-audit`).
24
+ - Sau khi bump `template_version` của một template → tìm mọi main artifact giờ thành `out-dated`.
25
+ - Onboarding repo cũ → stamp version cho main artifact legacy khớp structure, lọc ra cái cần migrate.
26
+
27
+ ## When NOT to Use
28
+
29
+ - Muốn **migrate** artifact lên format mới → `/artifact-migrate` (skill này chỉ flag, không sửa structure).
30
+ - Muốn đổi **nội dung** artifact → integration changeset (`/spec-new`) hoặc edit tay.
31
+ - Chưa cài template vào `.claude/templates/` → skill không có nguồn version để so; dừng.
32
+
33
+ ---
34
+
35
+ ## Type → template map
36
+
37
+ Type của main artifact resolve theo **filename**. Mỗi type map tới đúng một template:
38
+
39
+ | Filename | type | Template (`.claude/templates/...`) |
40
+ | --- | --- | --- |
41
+ | `prd.md` | prd | `main/prd-template.md` |
42
+ | `domain.md` | domain | `main/domain-template.md` |
43
+ | `sad.md` | sad | `main/sad-template.md` |
44
+ | `frd.md` | frd | `main/feature/frd-template.md` |
45
+ | `fdd.md` | fdd | `main/feature/fdd-template.md` |
46
+ | `tsd.md` | tsd | `main/feature/tsd-template.md` |
47
+ | `crd.md` | crd | `main/component/crd-template.md` |
48
+ | `cdd.md` | cdd | `main/component/cdd-template.md` |
49
+
50
+ **Chỉ main artifacts.** Integration artifacts (`spec`, `tech`, `test`, `plan`, `todo`, `techdebt`) **không** thuộc scope — gặp file integration thì bỏ qua. File không khớp bảng (vd `notes.md`, `*.bak`) → cũng bỏ qua.
51
+
52
+ ---
53
+
54
+ ## Process
55
+
56
+ ### Bước 0: Resolve scope
57
+
58
+ - **ARGUMENT là 1 main type hoặc list** (vd `frd`, `frd,crd`) → chỉ audit các type đó. Type lạ hoặc type integration (`spec`/`tech`/`test`/`plan`/`todo`/`techdebt`, không có trong map) → cảnh báo và bỏ qua type đó.
59
+ - **Không có ARGUMENT** → audit **mọi** main type trong map.
60
+
61
+ ### Bước 1: Đọc current version của template
62
+
63
+ Cho mỗi type trong scope, đọc frontmatter template tương ứng tại `.claude/templates/...` → lấy `template_version`.
64
+
65
+ - Template thiếu field `template_version` → không audit được type đó (chưa versioned ở phía template); cảnh báo, skip type.
66
+ - Template không tồn tại tại `.claude/templates/` → báo kit chưa cài đủ; dừng.
67
+
68
+ Lưu bảng `currentVersion[type]`.
69
+
70
+ ### Bước 2: Discover artifacts
71
+
72
+ Quét **chỉ** main artifacts trong `.specs/main/**` (prd, domain, sad, và feature/component artifacts).
73
+
74
+ **Bỏ qua:**
75
+ - Toàn bộ `.specs/integrations/**` — integration artifacts ngoài scope skill này (ephemeral + immutable sau `done`; không audit/migrate theo version).
76
+ - `.specs/archive/**`, `.specs/removed/**`, file `*.bak.*`, file không khớp type map.
77
+
78
+ Với mỗi file khớp: resolve type theo filename, đọc frontmatter để lấy `template_version` (có thể thiếu).
79
+
80
+ ### Bước 3: Classify
81
+
82
+ Cho mỗi artifact:
83
+
84
+ **3a. Có `template_version`** → so với `currentVersion[type]`:
85
+ - `==` → **up-to-date**.
86
+ - `!=` → **out-dated** → cần migrate. Ghi `(vX → vY)`.
87
+
88
+ Version compare bắt **mọi** loại delta của các bump ở giữa — `add` / `remove` / **`update` (format)** — kể cả thay đổi format mà presence-check không thấy được. Số version là tín hiệu tổng.
89
+
90
+ **3b. Thiếu `template_version`** (unversioned — sinh trước versioning) → chưa kết luận được bằng số. Áp **conformance check** (xem `conventions.md` §7 "Conformance model — required-emptyable").
91
+
92
+ > **Điểm mù:** presence-check chỉ thấy heading có/không → **KHÔNG phát hiện được format-update** (vd section vẫn đó nhưng dùng ASCII diagram thay vì Mermaid). Artifact unversioned đủ heading sẽ bị stamp thành conform dù format cũ. Đây là giới hạn cố hữu của nhánh unversioned (format-update chỉ bắt được qua version compare ở 3a). Chấp nhận vì là edge-case pre-versioning.
93
+
94
+ **Presence-check, quan hệ BAO HÀM (superset).** Conformance = artifact **chứa đủ mọi heading required** của template (body rỗng OK). Template là skeleton tối thiểu; artifact đã điền luôn chứa nhiều hơn. KHÔNG đòi giống hệt template.
95
+ - **Required heading** = các heading **`##`** của template body, TRỪ cái đánh dấu `*(nếu có)*` (conditional). Heading `###` là instance/sub (vd `### US-F{NNN}-001`, `### Flow 1`) → KHÔNG tính. Phân biệt bằng level nên deterministic.
96
+
97
+ **Hai dấu hiệu out-dated** (artifact tụt sau template) — đọc `remove` từ block `migrations` của template để biết tên section deprecated cần dò:
98
+ 1. **Thiếu** một required heading mà template hiện tại có.
99
+ 2. **Còn chứa** một section mà `migrations.remove` ghi đã bỏ (deprecated còn sót).
100
+
101
+ (Đổi tên section được biểu diễn bằng remove + add ở block `migrations`, nên rơi vào cả 2 dấu hiệu: tên cũ nằm trong `remove` → dấu hiệu 2; tên mới là required heading bị thiếu → dấu hiệu 1.)
102
+
103
+ **KHÔNG phải out-dated** (authoring bình thường, vẫn **stamp**):
104
+ - Artifact **thêm** sub-section / heading con không có trong template (vd dưới `### Feature Acceptance Criteria` có thêm `#### NFR AC`). Required heading vẫn có mặt → conform.
105
+ - Body rỗng của một required-emptyable section.
106
+ - Thêm nội dung/bảng/ghi chú riêng **không nằm trong `migrations.remove`**; khác thứ tự; số item nhiều/ít hơn ví dụ.
107
+
108
+ > **Quan trọng — phân biệt dấu hiệu 2 với superset:** section "thừa" (có trong artifact, không trong template) chỉ là out-dated khi tên nó **nằm trong `migrations.remove`** (đã khai báo deprecated). Section thừa **không** được khai báo remove → là content tác giả → **giữ, conform** (superset). Đây là cách removal vẫn detect được bằng presence-check mà không xóa nhầm content.
109
+
110
+ Kết luận:
111
+ - **Conform** (đủ required heading, không dính 1–2) → **stamp** `template_version: <currentVersion>`. Lần audit sau so bằng số.
112
+ - **Out-dated** (dính ≥1 trong 1–2) → KHÔNG stamp. Tóm tắt đúng dấu hiệu (thiếu required heading gì / section deprecated nào còn sót) để `/artifact-migrate` xử lý.
113
+
114
+ > Nguyên tắc thận trọng — chỉ về việc **có stamp hay không**: nếu nghi ngờ một required heading có thực sự thiếu hay không (diễn đạt khác) → flag out-dated thay vì stamp (thà flag thừa còn hơn giấu artifact lỗi thời). **Nội dung thừa không khai báo remove KHÔNG bao giờ là lý do nghi ngờ** — chỉ thiếu-required / deprecated-còn-sót mới tính.
115
+
116
+ ### Bước 4: Confirm trước khi stamp
117
+
118
+ > **Chế độ classify-only** (khi `/artifact-migrate` gọi audit làm bước phát hiện): **bỏ qua Bước 4–5** — KHÔNG stamp, KHÔNG confirm, chỉ trả phân loại (up-to-date / legacy-conformant / out-dated) cho caller. Mọi ghi (stamp + migrate) do `/artifact-migrate` điều phối trong một luồng confirm duy nhất. Phần dưới chỉ áp dụng khi audit chạy **standalone**.
119
+
120
+ Nếu Bước 3b có artifact cần stamp → hiển thị danh sách **sẽ stamp** + danh sách **out-dated** trước, xin confirm:
121
+
122
+ > Sẽ ghi `template_version` vào {N} artifact legacy khớp structure (additive frontmatter change). {M} artifact out-dated sẽ KHÔNG bị đụng. Tiếp tục? [y/n]
123
+
124
+ `y` → ghi stamp (chỉ thêm field `template_version` vào frontmatter, không đụng nội dung khác). `n` → bỏ qua stamp, vẫn in báo cáo.
125
+
126
+ Stamp là thay đổi additive an toàn; khuyến nghị commit riêng để diff sạch.
127
+
128
+ ### Bước 5: Report
129
+
130
+ In bảng phân nhóm (xem Output Format). Skill **không** migrate, **không** đổi nội dung artifact ngoài việc stamp ở Bước 4.
131
+
132
+ ---
133
+
134
+ ## Output Format
135
+
136
+ ```
137
+ ARTIFACT AUDIT — scope: {all main | frd, crd}
138
+ Current template versions: prd v1 · domain v1 · sad v1 · frd v2 · crd v1 · ...
139
+
140
+ OUT-DATED ({n}) — cần migrate:
141
+ feature/F-002-payment/frd.md frd v1 → v2 → /artifact-migrate
142
+ feature/F-003-x/frd.md frd unversioned, lệch structure (thiếu: Verification Rules) → migrate
143
+
144
+ STAMPED ({n}) — legacy khớp structure, vừa ghi template_version:
145
+ feature/F-001-auth/frd.md frd → v2
146
+ component/C-001-core/crd.md crd → v1
147
+
148
+ UP-TO-DATE ({n}): {đếm, liệt kê path ngắn gọn hoặc gập lại nếu nhiều}
149
+
150
+ Bước tiếp theo (nếu có out-dated):
151
+ - /artifact-migrate [path]
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Common Rationalizations
157
+
158
+ | Rationalization | Reality |
159
+ | --- | --- |
160
+ | "Cứ stamp hết cho gọn rồi tính sau" | Stamp nhầm artifact lệch structure = giấu luôn nó khỏi audit lần sau. Chỉ stamp khi structure khớp chắc chắn. |
161
+ | "Audit luôn tiện migrate luôn" | Hai trách nhiệm khác nhau. Audit chỉ phát hiện; migrate (đổi structure) là `/artifact-migrate` với dry-run + confirm. |
162
+ | "Thiếu version thì coi như out-dated hết" | Sai — legacy khớp structure chỉ là chưa stamp, không phải lỗi thời. Phải đối chiếu structure trước khi kết luận. |
163
+ | "Artifact có thêm `#### NFR AC` mà template không có → lệch → out-dated" | Sai — template là skeleton tối thiểu; thừa sub-section/nội dung là authoring bình thường. Conformance là quan hệ bao hàm: section bắt buộc còn đó → conform. Chỉ thiếu/đổi-tên/đổi-format mới là out-dated. |
164
+
165
+ ## Red Flags
166
+
167
+ - Stamp `template_version` cho artifact mà chưa đối chiếu structure với template.
168
+ - Tự sửa structure / nội dung artifact (vượt phạm vi — đó là migration skill).
169
+ - Flag out-dated chỉ vì artifact có thêm sub-section / nội dung ngoài template (thừa ≠ lỗi thời; chỉ thiếu/đổi-tên/đổi-format mới tính).
170
+ - Audit/stamp artifact ngoài scope: bất kỳ file nào trong `.specs/integrations/` (integration artifacts ngoài scope), `.specs/archive/`, `.specs/removed/` — bỏ qua hết.
171
+ - Đọc version từ một manifest/cache thay vì đọc thẳng frontmatter template.
172
+
173
+ ## Verification
174
+
175
+ - [ ] Scope = **chỉ main artifacts** (`.specs/main/**`); resolve đúng từ argument (1 main type / list / mọi main type)
176
+ - [ ] Current version đọc thẳng từ frontmatter template tại `.claude/templates/...` (không manifest)
177
+ - [ ] Bỏ qua toàn bộ `.specs/integrations/`, `.specs/archive/`, `.specs/removed/`, `*.bak.*`, và file không khớp type map
178
+ - [ ] Versioned: `==` → up-to-date; `!=` → out-dated `(vX → vY)` → migrate
179
+ - [ ] Unversioned: conformance là quan hệ bao hàm (artifact chứa đủ structure bắt buộc; thừa sub-section/nội dung không khai báo remove KHÔNG phải lỗi thời); 2 dấu hiệu out-dated = thiếu required heading / section `migrations.remove` còn sót
180
+ - [ ] Conform → stamp; out-dated → tóm tắt đúng dấu hiệu (thiếu required heading gì / section deprecated nào còn sót). Lưu ý: presence-check KHÔNG bắt format-update (blind spot unversioned)
181
+ - [ ] Có confirm trước khi ghi stamp; stamp chỉ thêm field `template_version`, không đụng nội dung khác
182
+ - [ ] KHÔNG migrate / không sửa structure artifact
183
+ - [ ] Report phân nhóm out-dated / stamped / up-to-date + bước tiếp theo
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: artifact-migrate
3
+ description: Migrate MAIN artifact trong .specs/main/ lên structure template mới nhất (chỉ main artifacts — prd/domain/sad/frd/fdd/tsd/crd/cdd; integration artifacts ngoài scope). Tự chạy /artifact-audit (classify-only, scoped) để phát hiện out-dated, rồi áp delta từ block `migrations` của template — add section thiếu, remove section deprecated, update format section (vd ASCII→Mermaid) — set template_version = current. Tương tác: confirm add/remove/update, hỏi carry-over khi rename, section nội dung mới thì interview hoặc NEEDS_CLARIFY (không bịa). Single-artifact, KHÔNG cascade. Nhận tùy chọn 1 main artifact (path); không có arg → quét mọi main artifact, migrate từng cái có confirm + skip.
4
+ ---
5
+
6
+ # artifact-migrate
7
+
8
+ ## Overview
9
+
10
+ Đưa một main artifact (hoặc toàn bộ main artifacts) **lỗi thời** lên đúng structure của template mới nhất, rồi cập nhật `template_version`. Đây là vế **fix** đối xứng với `/artifact-audit` (vế **detect**).
11
+
12
+ > **Scope = chỉ main artifacts** (`prd`, `domain`, `sad`, `frd`, `fdd`, `tsd`, `crd`, `cdd` — đều dưới `.specs/main/`). Integration artifacts (`spec`, `tech`, `test`, `plan`, `todo`, `techdebt`) **không** thuộc scope — ephemeral + immutable sau `done`, không migrate theo version.
13
+
14
+ Cơ chế (xem `conventions.md` §7 Template Versioning):
15
+ - **Required section hiện tại** = body `##` headings của template (deterministic theo level; `###` = instance).
16
+ - **Delta giữa các version** = đọc từ block `migrations` của template: mỗi entry `to: N` ghi `add` (section thêm) + `remove` (section bỏ) + `update` (section giữ nhưng đổi format/cách thể hiện, vd ASCII → Mermaid). `remove` và `update` không suy lại được từ body → block `migrations` là nguồn duy nhất.
17
+ - Migrate **single-artifact, KHÔNG cascade**. ID format đổi (hiếm, cross-artifact) → xử lý tay theo `note`.
18
+
19
+ ## When to Use
20
+
21
+ - Sau `git pull` kit mới, `/artifact-audit` báo có artifact out-dated → migrate chúng lên template mới.
22
+ - Onboarding repo cũ: artifact legacy thiếu version / lệch structure.
23
+ - Sau khi bump `template_version` một template → migrate các artifact cùng type.
24
+
25
+ ## When NOT to Use
26
+
27
+ - Chỉ muốn **biết** artifact nào lỗi thời (không sửa) → `/artifact-audit`.
28
+ - Muốn đổi **nội dung** artifact (thêm US, đổi AC) → integration changeset (`/spec-new`) hoặc edit tay.
29
+ - Working tree đang dirty → commit/stash trước (skill rollback dựa git, không tạo `.bak`).
30
+
31
+ ---
32
+
33
+ ## Type → template map
34
+
35
+ Resolve type của main artifact theo **filename** (giống `/artifact-audit`). Mỗi type map tới đúng một template tại `.claude/templates/...`:
36
+
37
+ `prd.md`→`main/prd-template.md` · `domain.md`→`main/domain-template.md` · `sad.md`→`main/sad-template.md` · `frd.md`→`main/feature/frd-template.md` · `fdd.md`→`main/feature/fdd-template.md` · `tsd.md`→`main/feature/tsd-template.md` · `crd.md`→`main/component/crd-template.md` · `cdd.md`→`main/component/cdd-template.md`
38
+
39
+ **Chỉ main artifacts.** Integration artifacts (`spec`/`tech`/`test`/`plan`/`todo`/`techdebt`) ngoài scope → bỏ qua. File không khớp map → cũng bỏ qua.
40
+
41
+ ---
42
+
43
+ ## Process
44
+
45
+ ### Bước 0: Resolve scope
46
+
47
+ - **ARGUMENT là path tới 1 main artifact** → migrate riêng nó. Nếu path là integration artifact (`.specs/integrations/...`) → **DỪNG**, báo "integration artifact ngoài scope — chỉ migrate main artifacts". Nếu nằm trong `.specs/archive`/`.specs/removed` → **DỪNG**, báo "artifact đóng băng (immutable record) — không migrate".
48
+ - **Không có ARGUMENT** → quét **chỉ** `.specs/main/**`, áp **đúng skip list của `/artifact-audit`** (bỏ toàn bộ `.specs/integrations/`, archive/removed, `*.bak.*`).
49
+
50
+ ### Bước 1: Pre-flight — working tree clean
51
+
52
+ Chạy `git status --porcelain`. Output không rỗng → **DỪNG**:
53
+ > ⛔ Working tree không clean. Skill không tạo `.bak` — rollback dựa git. Hãy commit/stash trước rồi chạy lại.
54
+
55
+ Không phải git repo → cảnh báo, yêu cầu confirm (default no) vì không rollback được.
56
+
57
+ ### Bước 2: Detect — tự chạy `/artifact-audit` (classify-only, scoped)
58
+
59
+ Dùng **chính conformance check của `/artifact-audit`** (presence-check, conventions §7) làm bước phát hiện — một nguồn phán đoán duy nhất, không tự cài lại logic. Scoped theo Bước 0:
60
+ - Có arg → audit đúng artifact/type đó.
61
+ - Không arg → audit toàn bộ scope.
62
+
63
+ Audit chạy **classify-only** ở đây: chỉ phân loại, **không tự stamp/confirm** (migrate sẽ điều phối mọi ghi vào một luồng confirm). Kết quả mỗi artifact:
64
+ - **up-to-date** (versioned, version `==` template) → bỏ qua. Target đơn lẻ → **no-op sớm**, thoát.
65
+ - **legacy-conformant** (thiếu version nhưng đủ required `##`, không dính `migrations.remove`) → chỉ cần **stamp** version (không đổi structure).
66
+ - **out-dated** (versioned `!=` template, HOẶC unversioned thiếu required `##`, HOẶC còn section trong `migrations.remove`) → cần migrate structure.
67
+
68
+ Không arg → in danh sách phân nhóm trước, rồi xử lý **từng artifact một, có confirm + cho skip** (không bulk-auto).
69
+
70
+ ### Bước 3: Lập transform plan cho từng artifact
71
+
72
+ Resolve type→template, đọc template: `template_version` hiện tại + block `migrations` + body `##` headings.
73
+
74
+ Gộp delta các entry `to:` > version artifact (hoặc tất cả nếu artifact unversioned):
75
+
76
+ 1. **Sections cần ADD** = required `##` của template mà artifact **thiếu**. (Phát hiện bằng so `##` body, deterministic; `migrations.add` để tham khảo delta.)
77
+ 2. **Sections cần REMOVE** = section trong **`migrations.remove`** mà artifact **còn chứa**.
78
+ 3. **Sections cần UPDATE format** = section trong **`migrations.update`** (giữ section, đổi cách thể hiện — vd ASCII → Mermaid). Section vẫn còn → không add/remove; chỉ transform format theo mô tả `change`. (Không suy được từ presence-check → bắt buộc dựa `migrations.update`.)
79
+ 4. **Rename phát hiện được** khi một `remove` (tên cũ) đi kèm một `add` (tên mới) trong cùng entry — đánh dấu để hỏi carry-over content.
80
+ 5. **ID format** (nếu `note` đề cập, cross-artifact) → liệt kê để người dùng sửa tay; skill không tự remap.
81
+
82
+ ### Bước 4: Dry-run + confirm (một luồng)
83
+
84
+ Trình bày cho user **trước khi ghi**:
85
+ - sections sẽ ADD (kèm skeleton lấy từ body template) + sections sẽ REMOVE (kèm reason).
86
+ - sections sẽ UPDATE format → show **nội dung hiện tại** + **đề xuất bản chuyển format** (vd ASCII diagram → Mermaid tương ứng), giữ nguyên ngữ nghĩa.
87
+ - cặp rename phát hiện được → hỏi: "carry-over nội dung từ {cũ} sang {mới}?".
88
+ - artifact legacy-conformant trong scope → sẽ stamp version (gộp vào cùng confirm).
89
+
90
+ User confirm (toàn bộ / từng item / skip artifact). **Section nội dung mới** (vd Verification Rules) → **interview user điền** hoặc chèn `**[NEEDS_CLARIFY]**` — **KHÔNG tự bịa nội dung**. Với UPDATE format: chuyển *cách thể hiện*, **không bịa thêm/bớt thông tin** so với bản cũ; phần không chắc → giữ + `[NEEDS_CLARIFY]`.
91
+
92
+ ### Bước 5: Apply (atomic mỗi artifact)
93
+
94
+ - Chèn section ADD theo đúng thứ tự body template; nếu là rename + user đồng ý carry-over → move nội dung từ section cũ sang.
95
+ - Xóa section REMOVE (đã confirm).
96
+ - Áp UPDATE format: thay nội dung section bằng bản chuyển format đã confirm (giữ section + ngữ nghĩa).
97
+ - **Giữ nguyên** mọi sub-section / content tác giả **không nằm trong `remove`/`update`** (superset rule).
98
+ - Set frontmatter `template_version` = current.
99
+ - Main artifact có `## Change History` ở cuối → append entry, operation = `manual`:
100
+ ```markdown
101
+ ### {YYYY-MM-DD} — manual — migrate
102
+
103
+ - **Migration**: v{cũ} → v{current} qua /artifact-migrate (add: {...}; remove: {...}; update: {...})
104
+ ```
105
+ - **Single-artifact, KHÔNG cascade.** Apply fail → rollback bằng git (`git checkout -- {file}`); báo user.
106
+
107
+ ### Bước 6: Report
108
+
109
+ ```
110
+ ARTIFACT MIGRATE — scope: {file | all}
111
+
112
+ MIGRATED ({n}):
113
+ feature/F-002-payment/frd.md v0 → v1 +User Flows, −Components Consumed, ~System Overview (ASCII→Mermaid)
114
+ STAMPED ({n}) — legacy conform, chỉ set version:
115
+ feature/F-001-auth/frd.md → v1
116
+ SKIPPED / up-to-date ({n})
117
+
118
+ {nếu có} NEEDS_CLARIFY còn lại:
119
+ feature/F-002-payment/frd.md → Verification Rules (chờ điền)
120
+ {nếu có} Cần sửa tay (ID remap theo note):
121
+ ...
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Common Rationalizations
127
+
128
+ | Rationalization | Reality |
129
+ | --- | --- |
130
+ | "Tự đoán nội dung cho section mới cho nhanh" | Section nội dung mới = quyết định của BA/owner. Bịa = sai mà không ai review. Interview hoặc NEEDS_CLARIFY. |
131
+ | "Section thừa chắc là rác, xóa luôn" | Chỉ xóa section nằm trong `migrations.remove`. Thừa khác là content tác giả → giữ (superset). |
132
+ | "Format đổi thì xóa section rồi thêm lại" | remove+add làm **mất nội dung**. Format-update giữ section + ngữ nghĩa, chỉ chuyển cách thể hiện (dùng op `update`). |
133
+ | "Chuyển format thì tiện viết lại nội dung cho đẹp" | UPDATE chỉ đổi *cách thể hiện*, KHÔNG thêm/bớt thông tin. Phần không chắc → giữ + NEEDS_CLARIFY. |
134
+ | "Migrate tiện remap ID luôn" | Không có op remap; cascade đã bỏ. ID đổi (hiếm) ghi ở `note`, người dùng sửa tay. |
135
+ | "Khỏi chạy audit, tự check structure cho nhanh" | Phải dùng audit classify-only → một nguồn phán đoán duy nhất, không lệch giữa hai skill. |
136
+
137
+ ## Red Flags
138
+
139
+ - Bịa nội dung cho section ADD thay vì interview / NEEDS_CLARIFY.
140
+ - Xóa section không nằm trong `migrations.remove` (vi phạm superset).
141
+ - Tự remap ID / đụng tới artifact khác (migrate là single-artifact, không cascade).
142
+ - Chạy khi working tree dirty (mất đường rollback).
143
+ - Migrate artifact ngoài scope: bất kỳ file nào trong `.specs/integrations/` (integration artifacts ngoài scope), `.specs/archive`, `.specs/removed` (phải skip / DỪNG).
144
+ - Migrate artifact đã up-to-date (phải no-op sớm).
145
+ - Tự cài lại logic detect thay vì dùng audit classify-only.
146
+
147
+ ## Verification
148
+
149
+ - [ ] Scope = **chỉ main artifacts** (`.specs/main/**`); arg là integration artifact → DỪNG, no-arg chỉ quét `.specs/main/**`
150
+ - [ ] Pre-flight: working tree clean (hoặc user confirm khi không phải git repo)
151
+ - [ ] Detect bằng `/artifact-audit` classify-only, scoped theo target; version `==` → up-to-date → no-op sớm; `!=` → migrate
152
+ - [ ] Required `##` thiếu → ADD (skeleton từ body template); section `migrations.remove` còn sót → REMOVE (confirm)
153
+ - [ ] Section `migrations.update` → chuyển format (giữ section + ngữ nghĩa); show cũ + đề xuất mới, confirm; KHÔNG thêm/bớt thông tin
154
+ - [ ] Rename (remove+add) → hỏi carry-over content; section nội dung mới → interview / NEEDS_CLARIFY (KHÔNG bịa)
155
+ - [ ] Giữ content tác giả không nằm trong `remove`/`update` (superset)
156
+ - [ ] Set `template_version` = current; main artifact có Change History entry operation `manual`/migrate
157
+ - [ ] Single-artifact, KHÔNG cascade; ID remap (nếu có) chỉ báo để sửa tay
158
+ - [ ] Không arg → liệt kê trước, migrate từng cái có confirm + skip
159
+ - [ ] Apply fail → rollback git; user được thông báo
@@ -118,7 +118,7 @@ Invoke `planning-and-task-breakdown` với context đã load. Skill đó sẽ th
118
118
 
119
119
  ### plan.md
120
120
 
121
- Dùng `.claude/templates/integrations/plan-template.md` làm skeleton, điền nội dung từ breakdown vào từng section.
121
+ Dùng `.claude/templates/integrations/plan-template.md` làm skeleton, điền nội dung từ breakdown vào từng section. Frontmatter copy từ template (plan.md là integration artifact — **không** mang `template_version`; versioning chỉ áp dụng cho main artifacts, xem `conventions.md` §7).
122
122
 
123
123
  **Lưu ý format:**
124
124
  - Task ID dùng `·` (middle dot), không dùng `—`
@@ -128,7 +128,7 @@ Dùng `.claude/templates/integrations/plan-template.md` làm skeleton, điền n
128
128
 
129
129
  ### todo.md
130
130
 
131
- Dùng `.claude/templates/integrations/todo-template.md` làm skeleton, điền nội dung từ breakdown vào từng section.
131
+ Dùng `.claude/templates/integrations/todo-template.md` làm skeleton, điền nội dung từ breakdown vào từng section. Frontmatter copy từ template (todo.md là integration artifact — không mang `template_version`).
132
132
 
133
133
  ---
134
134
 
@@ -146,3 +146,4 @@ Nếu trong quá trình breakdown phát hiện delta cần cập nhật `sad.md`
146
146
  - [ ] plan.md có section **Dependency Graph**
147
147
  - [ ] Mỗi task có đủ: Mục tiêu / depends / Các bước / Verification
148
148
  - [ ] Không viết code trong suốt quá trình
149
+ - [ ] plan.md + todo.md (integration) KHÔNG mang `template_version` (versioning chỉ cho main artifacts)
@@ -221,6 +221,8 @@ Ghi tất cả? [y] hoặc review từng file trước [r]:
221
221
  - `y` → ghi tất cả
222
222
  - `r` → hiển thị lần lượt từng file, user confirm / skip / edit từng cái
223
223
 
224
+ **Stamp `template_version`:** frontmatter mỗi `crd.md`/`cdd.md` lấy `template_version` từ template tương ứng (xem `conventions.md` §7).
225
+
224
226
  **Change History:** Append entry vào section `## Change History` cuối mỗi `crd.md`/`cdd.md` vừa ghi (theo `conventions.md` §5.5):
225
227
 
226
228
  ```markdown
@@ -304,4 +306,5 @@ Bước tiếp theo:
304
306
  - [ ] prd.md Component Index đã được update
305
307
  - [ ] sad.md Components table đã được update — danh sách C-XXX khớp với prd.md
306
308
  - [ ] Shared Entities đã được cascade vào domain.md (nếu có)
309
+ - [ ] Mỗi crd.md/cdd.md có `template_version` copy từ template tương ứng
307
310
  - [ ] NEEDS_CLARIFY items được list đầy đủ trong summary
@@ -225,6 +225,8 @@ Sẽ tạo {N} features ({2N} files):
225
225
  Ghi tất cả? [y] hoặc review từng file trước [r]:
226
226
  ```
227
227
 
228
+ **Stamp `template_version`:** frontmatter mỗi `frd.md`/`fdd.md` lấy `template_version` từ template tương ứng (xem `conventions.md` §7).
229
+
228
230
  **Change History:** Append entry vào section `## Change History` cuối mỗi `frd.md`/`fdd.md` vừa ghi (theo `conventions.md` §5.5):
229
231
 
230
232
  ```markdown
@@ -307,4 +309,5 @@ grep "NEEDS_CLARIFY" để tìm và fill in khi có thêm context.
307
309
  - [ ] Feature không có tests → AC section có NEEDS_CLARIFY rõ ràng
308
310
  - [ ] Verification Rules: rule reverse-engineer từ code đã đánh dấu source; field thiếu validation đã NEEDS_CLARIFY; không chứa regex/code/error message
309
311
  - [ ] prd.md Feature Index đã được update
312
+ - [ ] Mỗi frd.md/fdd.md có `template_version` copy từ template tương ứng
310
313
  - [ ] NEEDS_CLARIFY items được list đầy đủ trong summary
@@ -272,7 +272,7 @@ Confirm? [y] Bỏ qua [n] Chỉnh sửa [e]:
272
272
 
273
273
  ### Bước 9: Save
274
274
 
275
- Tạo `.specs/main/` nếu chưa có. Ghi các files đã được confirm.
275
+ Tạo `.specs/main/` nếu chưa có. Ghi các files đã được confirm. Frontmatter mỗi file (`prd.md`/`domain.md`/`sad.md`) lấy `template_version` từ template tương ứng (xem `conventions.md` §7).
276
276
 
277
277
  **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:
278
278
 
@@ -320,3 +320,4 @@ Format chuẩn — dùng nhất quán trong tất cả artifacts:
320
320
  - [ ] sad.md có Architectural Guardrails section
321
321
  - [ ] NEEDS_CLARIFY items được list đầy đủ trong summary cuối
322
322
  - [ ] User đã confirm từng file trước khi ghi
323
+ - [ ] Mỗi file (prd/domain/sad) có `template_version` copy từ template tương ứng
@@ -223,7 +223,7 @@ Dùng `.claude/templates/main/feature/frd-template.md` làm skeleton, điền n
223
223
 
224
224
  **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.
225
225
 
226
- **Frontmatter** frd mới: theo template, `status: draft`, `owner: BA`, `feature_id: F-XXX`.
226
+ **Frontmatter** frd mới: theo template, `status: draft`, `owner: BA`, `feature_id: F-XXX`, `template_version` copy từ `frd-template.md` (xem `conventions.md` §7 — chỉ set lúc CREATE; thay đổi sau qua `/spec-new` không đụng version).
227
227
 
228
228
  Hiển thị **toàn bộ draft** cho user — chưa ghi file. Kèm:
229
229
  - danh sách component candidate (nếu có) và VR còn `TBD`;
@@ -360,6 +360,7 @@ Bước tiếp theo:
360
360
  - [ ] **Create-only gate**: frd.md của feature mục tiêu CHƯA tồn tại; nếu đã có đã redirect `/spec-new`
361
361
  - [ ] Feature mục tiêu có trong Index, HOẶC feature mới đơn lẻ đã được user đồng ý register (Bước 1b)
362
362
  - [ ] frd.md có đủ 7 core sections (luôn create mới); `Open Questions` chứa câu hỏi clarify + component candidate còn mở, hoặc đã xóa nếu rỗng
363
+ - [ ] Frontmatter có `template_version` copy từ `frd-template.md`
363
364
  - [ ] Mỗi User Story có persona + priority + ít nhất 1 AC Given/When/Then
364
365
  - [ ] Feature AC dùng ID `FAC-F{NNN}-{seq}` (counter độc lập với `AC-F{NNN}`), Then đo được
365
366
  - [ ] Verification Rules đã confirm với BA (không tự assert); không chứa regex/code/error message; semantic type
@@ -343,7 +343,7 @@ Chỉ tiến hành Bước 7 sau khi user confirm. Nếu user yêu cầu chỉnh
343
343
 
344
344
  Tạo thư mục `.specs/integrations/{NNN}-{slug}/` nếu chưa có.
345
345
 
346
- **[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.
346
+ **[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. (spec.md là integration artifact — **không** mang `template_version`; versioning chỉ áp dụng cho main artifacts, xem `conventions.md` §7.)
347
347
 
348
348
  **[7.2] Auto-apply mỗi Changes block** vào main artifact tương ứng. Thứ tự apply (để tránh forward reference): `prd.md` → `domain.md` → `sad.md` → `component/*/crd.md` → `feature/*/frd.md`.
349
349
 
@@ -352,7 +352,7 @@ Cho từng block:
352
352
  - **Operation=create:**
353
353
  - Tạo file mới tại path tương ứng
354
354
  - Nội dung = nội dung của Changes block (theo format của template gốc)
355
- - Frontmatter của artifact mới: lấy từ template (status `draft` cho artifact mới — separate lifecycle với spec.md)
355
+ - Frontmatter của artifact mới: lấy từ template, gồm `template_version` (status `draft` cho artifact mới — separate lifecycle với spec.md). `template_version` chỉ stamp ở operation=create; **operation=update KHÔNG đụng** version của artifact hiện có.
356
356
 
357
357
  - **Operation=update:**
358
358
  - Đọc artifact hiện tại
@@ -443,3 +443,4 @@ Sau khi user confirm (Bước 7):
443
443
  - [ ] Auto-apply chạy theo thứ tự prd → domain → sad → crd → frd
444
444
  - [ ] Mỗi artifact bị touched có entry mới được append vào `## Change History` (xem `conventions.md` §5.5)
445
445
  - [ ] Fail-safe: nếu apply fail thì không ghi spec.md (rollback luôn Change History entries)
446
+ - [ ] Main artifact create (frd/crd mới) có `template_version` copy từ template; artifact update giữ nguyên version cũ. spec.md (integration) KHÔNG mang `template_version`
@@ -279,6 +279,8 @@ Chỉ ghi file sau khi user confirm. Nếu user yêu cầu chỉnh sửa → c
279
279
 
280
280
  Nếu `domain.md` đã tồn tại với nội dung thực → không đụng tới.
281
281
 
282
+ **5b'. Stamp `template_version`:** frontmatter `prd.md` (lúc create) và `domain.md` (lúc scaffold) lấy `template_version` từ template tương ứng (xem `conventions.md` §7 Template Versioning). Lần chạy sau update `prd.md` → giữ nguyên `template_version` hiện có, KHÔNG đụng.
283
+
282
284
  **5c. Append Change History entry** vào mỗi artifact vừa ghi/scaffold (theo `conventions.md` §5.5):
283
285
 
284
286
  ```markdown
@@ -323,7 +325,7 @@ Bước tiếp theo:
323
325
 
324
326
  Trước khi kết thúc, kiểm tra:
325
327
 
326
- - [ ] Frontmatter đầy đủ và đúng schema (id, type, version, status, owner, project_name)
328
+ - [ ] Frontmatter đầy đủ và đúng schema (id, type, status, owner, project_name, `template_version`) — `template_version` copy từ template lúc create, update không đụng
327
329
  - [ ] Problem Statement từ góc nhìn business, không mention tech stack
328
330
  - [ ] Mỗi persona có: tên vai trò, mục tiêu, pain point
329
331
  - [ ] Out of Scope có ít nhất 1 item với lý do
@@ -191,7 +191,7 @@ Chỉ ghi file sau khi user confirm. Nếu user yêu cầu chỉnh sửa → c
191
191
 
192
192
  ### Bước 5: Save
193
193
 
194
- Ghi nội dung đã được confirm vào `.specs/main/sad.md`.
194
+ Ghi nội dung đã được confirm vào `.specs/main/sad.md`. Frontmatter lấy `template_version` từ `sad-template.md` lúc create (xem `conventions.md` §7); lần chạy update sau giữ nguyên, không đụng.
195
195
 
196
196
  **Change History:** Append entry vào section `## Change History` cuối `sad.md` (theo `conventions.md` §5.5):
197
197
 
@@ -246,7 +246,7 @@ Bước tiếp theo:
246
246
 
247
247
  Trước khi kết thúc, kiểm tra:
248
248
 
249
- - [ ] Frontmatter đầy đủ và đúng schema
249
+ - [ ] Frontmatter đầy đủ và đúng schema (gồm `template_version` copy từ template lúc create; update không đụng)
250
250
  - [ ] Architectural Style có lý do gắn với NFRs hoặc constraints
251
251
  - [ ] System Overview có diagram + Components table; danh sách C-XXX khớp với `prd.md > Components` (hoặc cả hai cùng rỗng nếu Component Index chưa được điền)
252
252
  - [ ] Mỗi tech stack item có lý do chọn rõ ràng
@@ -216,7 +216,7 @@ Chỉ ghi file sau khi user confirm. Nếu user yêu cầu chỉnh sửa → c
216
216
 
217
217
  ### Bước 6: Save + Auto-cascade
218
218
 
219
- **[6.1] Ghi `.specs/integrations/{slug}/tech.md`** với status `approved` (không phải `draft` — human đã confirm ở Bước 5 chính là approval). Frontmatter `features` và `components` mirror từ `spec.md`.
219
+ **[6.1] Ghi `.specs/integrations/{slug}/tech.md`** với status `approved` (không phải `draft` — human đã confirm ở Bước 5 chính là approval). Frontmatter `features` và `components` mirror từ `spec.md`. (tech.md là integration artifact — **không** mang `template_version`; versioning chỉ áp dụng cho main artifacts, xem `conventions.md` §7.)
220
220
 
221
221
  **[6.2] Auto-apply mỗi Changes block** vào main artifact tương ứng. Thứ tự apply (để tránh forward reference): `sad.md` → `domain.md` → `component/*/cdd.md` → `feature/*/fdd.md`.
222
222
 
@@ -225,7 +225,7 @@ Cho từng block:
225
225
  - **Operation=create:**
226
226
  - Tạo file mới tại path tương ứng
227
227
  - Nội dung = nội dung của Changes block (theo format của template gốc — `cdd-template.md` hoặc `fdd-template.md`)
228
- - Frontmatter: lấy từ template (status `draft` cho artifact mới — separate lifecycle với tech.md)
228
+ - Frontmatter: lấy từ template, gồm `template_version` (status `draft` cho artifact mới — separate lifecycle với tech.md). `template_version` chỉ stamp ở operation=create; **operation=update KHÔNG đụng** `template_version` của artifact hiện có.
229
229
 
230
230
  - **Operation=update:**
231
231
  - Đọc artifact hiện tại
@@ -315,3 +315,4 @@ Sau khi user confirm (Bước 6):
315
315
  - [ ] Auto-apply chạy theo thứ tự sad → domain → cdd → fdd
316
316
  - [ ] Mỗi artifact bị touched có entry mới được append vào `## Change History` (conventions §5.5)
317
317
  - [ ] Fail-safe: nếu apply fail thì không ghi tech.md (rollback luôn Change History entries)
318
+ - [ ] Main artifact create (cdd/fdd mới) có `template_version` copy từ template; artifact update giữ nguyên version cũ. tech.md (integration) KHÔNG mang `template_version`
@@ -284,7 +284,7 @@ Chỉ tiến hành Bước 6 sau khi QC confirm.
284
284
 
285
285
  ### Bước 6: Save + Auto-cascade
286
286
 
287
- **[6.1] Ghi `.specs/integrations/{slug}/test.md`** với status `approved` (không phải `draft` — human đã confirm ở Bước 5 chính là approval). Frontmatter `features` mirror từ `spec.md`.
287
+ **[6.1] Ghi `.specs/integrations/{slug}/test.md`** với status `approved` (không phải `draft` — human đã confirm ở Bước 5 chính là approval). Frontmatter `features` mirror từ `spec.md`. (test.md là integration artifact — **không** mang `template_version`; versioning chỉ áp dụng cho main artifacts, xem `conventions.md` §7.)
288
288
 
289
289
  **[6.2] Auto-apply mỗi Changes block** vào `feature/{F-XXX}/tsd.md` tương ứng. Thứ tự apply: theo thứ tự xuất hiện trong frontmatter `features` (deterministic, không có forward reference giữa các feature tsd.md). Bỏ qua feature có operation `no-op` trong Cascade Summary.
290
290
 
@@ -293,7 +293,7 @@ Cho từng block:
293
293
  - **Operation=create:**
294
294
  - Tạo file `.specs/main/feature/{F-XXX}-{slug}/tsd.md`
295
295
  - Nội dung = nội dung của Changes block (theo format `templates/main/feature/tsd-template.md`)
296
- - Frontmatter của tsd.md mới: status `draft` (separate lifecycle với integration test.md)
296
+ - Frontmatter của tsd.md mới: status `draft` + `template_version` copy từ `tsd-template.md` (separate lifecycle với integration test.md). Chỉ stamp ở operation=create; **operation=update KHÔNG đụng** version của tsd.md hiện có.
297
297
 
298
298
  - **Operation=update:**
299
299
  - Đọc tsd.md hiện tại
@@ -381,3 +381,4 @@ Sau khi QC confirm (Bước 6):
381
381
  - [ ] Mỗi tsd.md bị touched có entry mới trong `## Change History` (conventions §5.5)
382
382
  - [ ] Fail-safe: nếu apply fail thì không ghi integration test.md (rollback luôn Change History entries)
383
383
  - [ ] Mỗi feature tsd.md mới có status `draft` (separate lifecycle)
384
+ - [ ] Main artifact tsd.md create có `template_version` copy từ template; tsd.md update giữ nguyên version cũ. test.md (integration) KHÔNG mang `template_version`
@@ -183,7 +183,7 @@ Hiển thị draft đầy đủ — chưa ghi file.
183
183
 
184
184
  ### Bước 6: Save
185
185
 
186
- Ghi `.specs/main/feature/{F-XXX}-{slug}/tsd.md` với status `draft` (feature-level artifact có lifecycle riêng, không phải `approved` — QC còn fill placeholders nên status `draft` cho đến khi đầy đủ).
186
+ Ghi `.specs/main/feature/{F-XXX}-{slug}/tsd.md` với status `draft` (feature-level artifact có lifecycle riêng, không phải `approved` — QC còn fill placeholders nên status `draft` cho đến khi đầy đủ). Frontmatter lấy `template_version` từ `tsd-template.md` (xem `conventions.md` §7).
187
187
 
188
188
  Nếu overwrite — file backup `tsd.md.bak.{timestamp}` đã tạo ở Bước 2.
189
189
 
@@ -238,3 +238,4 @@ Trước khi ghi file:
238
238
  - [ ] Priority deterministic theo bảng 4.3
239
239
  - [ ] Nếu overwrite: tsd.md.bak.{timestamp} đã được tạo
240
240
  - [ ] QC đã confirm draft
241
+ - [ ] Frontmatter có `template_version` copy từ `tsd-template.md`
@@ -220,34 +220,35 @@ Nhóm skill dọn dẹp / migrate artifacts hiện có sau khi template được
220
220
 
221
221
  | Command | Reads | Writes |
222
222
  | --- | --- | --- |
223
- | `/spec-frd-update` | `feature/*/frd.md`, `frd-template.md` | `feature/*/frd.md`, cascade: `fdd.md`, `tsd.md`, `integrations/*/spec.md`, `tech.md`, `test.md` |
223
+ | `/artifact-audit [type]` | `.specs/main/**` artifacts, `.claude/templates/main/*-template.md` | *(báo cáo; + stamp `template_version` cho main artifact legacy conform)* |
224
+ | `/artifact-migrate [path]` | `.specs/main/**` artifacts, `.claude/templates/main/*-template.md` (block `migrations`) | main artifact được migrate (structure + `template_version`) |
224
225
 
225
- ### `/spec-frd-update`
226
+ ### `/artifact-audit [type]`
226
227
 
227
- Migrate frd.md hiện lên format mới nhất của `templates/main/feature/frd-template.md`. Dùng cho repo đã chạy `/spec-brownfield-feature` hoặc `/spec-new` từ trước, frd.md sinh ra theo template cũ.
228
+ Phát hiện **main artifact** lỗi thời so với template (xem `conventions.md` §7 Template Versioning). So `template_version` của artifact với `template_version` đọc thẳng từ template tại `.claude/templates/main/` — không manifest, không cache. **Chỉ main artifacts** (`prd`/`domain`/`sad`/`frd`/`fdd`/`tsd`/`crd`/`cdd`); integration artifacts ngoài scope.
228
229
 
229
- **8 migration vectors** detect tự động:
230
+ **Scope:** argument 1 main type (`/artifact-audit frd`) hoặc list (`frd,crd`); không có arg → audit mọi main type. Type resolve theo **filename**.
230
231
 
231
- | Vector | Action | Risk |
232
- |---|---|---|
233
- | V1 | Fix Mermaid syntax `[{...}]` → `["..."]` | None |
234
- | V2 | Insert "Flow numbering stable" note | None |
235
- | V3 | Rename `Feature-level AC` → `Feature AC` + 4 nhóm chuẩn | Low |
236
- | V4 | Rename `AC-F{NNN}-` (Feature AC) → `FAC-F{NNN}-` (counter riêng) + cascade refs | **HIGH** |
237
- | V5 | Insert US/AC stability notes | None |
238
- | V6 | Propose Verification Rules từ User Stories → user approve → insert | Medium |
239
- | V7 | Move `Components Consumed` → `Dependencies > Components Used` | Low |
240
- | V8 | Derive Mermaid flows từ User Stories → propose → user approve → insert | Medium |
232
+ **Phân loại mỗi artifact:**
233
+ - Có `template_version` → `==`: **up-to-date**; `!=`: **out-dated** `(vX → vY)` → migrate.
234
+ - Thiếu version (legacy) presence-check (đủ required `##` + không còn section `migrations.remove`): conform **stamp** `template_version` (có confirm); lệch → **out-dated** + tóm tắt phần thiếu.
241
235
 
242
- **Workflow:** Pre-flight git clean check discover & classify per-FRD context load apply mechanical vectors (V1/V2/V3/V5/V7) → V4 dry-run preview với cascade impact confirm → V6 propose VR → confirm → V8 propose Flows → confirm → validate → report.
236
+ **Ranh giới:** chỉ phát hiện + stamp legacy conform. **KHÔNG migrate** đổi structure việc của `/artifact-migrate`. Bỏ qua toàn bộ `.specs/integrations/`, `.specs/archive/`, `.specs/removed/`.
243
237
 
244
- **Cảnh báo:**
245
- - V4 mặc định dry-run, in remap table + cascade diff trước khi ghi.
246
- - V6 luôn propose-then-approve, không auto-apply (model dễ bịa rule).
247
- - V8 luôn propose-then-approve — model derive flow từ US journey grouping, BA phải review để catch glue step bịa hoặc grouping sai.
248
- - KHÔNG tạo file `.bak` — rollback dùng `git checkout -- {file}`. Pre-flight yêu cầu working tree clean.
238
+ ### `/artifact-migrate [path]`
249
239
 
250
- **No-op safe:** nếu mọi FRD đã clean, skill báo dừng không ghi gì.
240
+ Migrate **main artifact** lỗi thời lên structure template mới nhất, cho mọi main type (vế **fix** đối xứng với `/artifact-audit` vế **detect**). Integration artifacts ngoài scope.
241
+
242
+ **Scope:** arg = 1 main artifact (path) → migrate riêng nó; không arg → quét mọi main artifact trong `.specs/main/`, migrate từng cái có confirm + skip.
243
+
244
+ **Quy trình:** pre-flight git clean → **tự chạy `/artifact-audit` classify-only (scoped)** để phát hiện out-dated (up-to-date → no-op sớm) → đọc block `migrations` của template lấy delta `add`/`remove`/`update` → dry-run + confirm → apply (set `template_version` = current; main artifact thêm Change History `manual`/migrate).
245
+
246
+ **Quy tắc:**
247
+ - **ADD** = required `##` thiếu (skeleton từ body template); section nội dung mới → interview hoặc `NEEDS_CLARIFY`, **KHÔNG bịa**.
248
+ - **REMOVE** = section trong `migrations.remove` còn sót (có confirm); giữ content tác giả khác (superset).
249
+ - **UPDATE** = section trong `migrations.update` — giữ section + ngữ nghĩa, chỉ đổi **format/cách thể hiện** (vd ASCII → Mermaid); show cũ + đề xuất mới, confirm; KHÔNG thêm/bớt thông tin. (Không presence-check được → chỉ bắt qua version compare.)
250
+ - Rename (remove+add) → hỏi carry-over nội dung.
251
+ - **Single-artifact, KHÔNG cascade.** ID remap (hiếm) → ghi ở `note`, sửa tay. Rollback dùng git (không `.bak`).
251
252
 
252
253
  ---
253
254
 
@@ -4,6 +4,10 @@ type: cdd
4
4
  status: draft
5
5
  owner: "{Tech Lead / Senior Dev}"
6
6
  component_id: "{Component ID, ví dụ C-001}"
7
+ template_version: 1
8
+ migrations:
9
+ - to: 1
10
+ note: "baseline"
7
11
  referenced_by:
8
12
  - conventions.md > 3. Main Artifacts > 3.2 Component level > cdd.md > Cấu trúc
9
13
  - skills/spec-tech/SKILL.md > Process > Cascade Proposals > component cdd.md
@@ -4,6 +4,10 @@ type: crd
4
4
  status: draft
5
5
  owner: "{BA / Tech Lead}"
6
6
  component_id: "{Component ID từ PRD Component Index, ví dụ C-001}"
7
+ template_version: 1
8
+ migrations:
9
+ - to: 1
10
+ note: "baseline"
7
11
  referenced_by:
8
12
  - conventions.md > 3. Main Artifacts > 3.2 Component level > crd.md > Cấu trúc
9
13
  - skills/spec-new/SKILL.md > Process > Bước 5: Write — sinh draft > component/{C-XXX}/crd.md
@@ -3,6 +3,10 @@ id: domain
3
3
  type: domain
4
4
  status: draft
5
5
  owner: "{BA/Domain Expert}"
6
+ template_version: 1
7
+ migrations:
8
+ - to: 1
9
+ note: "baseline"
6
10
  referenced_by:
7
11
  - conventions.md > 3. Main Artifacts > 3.1 Product level > domain.md > Cấu trúc
8
12
  - skills/spec-prd/SKILL.md > Process > Bước 5: Save (scaffold domain.md skeleton)
@@ -4,6 +4,10 @@ type: fdd
4
4
  status: draft
5
5
  owner: "{Tech Lead / Senior Dev}"
6
6
  feature_id: "{Feature ID}"
7
+ template_version: 1
8
+ migrations:
9
+ - to: 1
10
+ note: "baseline"
7
11
  referenced_by:
8
12
  - conventions.md > 3. Main Artifacts > 3.3 Feature level > fdd.md > Cấu trúc
9
13
  - skills/spec-tech/SKILL.md > Process > Bước 4: Write — sinh draft > Cascade Proposals > fdd.md
@@ -4,6 +4,10 @@ type: frd
4
4
  status: draft
5
5
  owner: "{BA}"
6
6
  feature_id: "{Feature ID từ PRD Feature Index}"
7
+ template_version: 1
8
+ migrations:
9
+ - to: 1
10
+ note: "baseline"
7
11
  referenced_by:
8
12
  - conventions.md > 3. Main Artifacts > 3.3 Feature level > frd.md > Cấu trúc
9
13
  - skills/spec-frd/SKILL.md > Process > Bước 5: Write — sinh draft
@@ -158,7 +162,8 @@ Tham chiếu đến `.specs/main/component/{C-XXX}-...`.
158
162
  ## Open Questions
159
163
 
160
164
  <!-- Các câu hỏi cần làm rõ trong interview / với stakeholder trước khi proceed.
161
- Cũng dùng để note component candidate chưa carve (xem skills/spec-frd). Xóa section nếu không còn câu hỏi nào. -->
165
+ Cũng dùng để note component candidate chưa carve (xem skills/spec-frd).
166
+ Section required-emptyable: GIỮ heading; để trống (không có bullet) nếu không còn câu hỏi nào. -->
162
167
 
163
168
  - [ ] {câu hỏi cần clarify} — {ai trả lời / khi nào}
164
169
 
@@ -5,6 +5,10 @@ status: draft
5
5
  owner: "{QC}"
6
6
  feature_id: "{Feature ID — match frd.md}"
7
7
  frd_ref: "feature/{F-XXX}-{slug}/frd.md"
8
+ template_version: 1
9
+ migrations:
10
+ - to: 1
11
+ note: "baseline"
8
12
  referenced_by:
9
13
  - conventions.md > 3. Main Artifacts > 3.3 Feature level > tsd.md > Cấu trúc
10
14
  ---
@@ -4,6 +4,10 @@ type: prd
4
4
  status: draft
5
5
  owner: "{PM/BA}"
6
6
  project_name: "{tên dự án}"
7
+ template_version: 1
8
+ migrations:
9
+ - to: 1
10
+ note: "baseline"
7
11
  referenced_by:
8
12
  - conventions.md > 3. Main Artifacts > 3.1 Product level > prd.md > Cấu trúc
9
13
  - skills/spec-prd/SKILL.md > Process > Bước 1: Kiểm tra preconditions
@@ -3,6 +3,10 @@ id: sad
3
3
  type: sad
4
4
  status: draft
5
5
  owner: "{Tech Lead / Architect}"
6
+ template_version: 1
7
+ migrations:
8
+ - to: 1
9
+ note: "baseline"
6
10
  referenced_by:
7
11
  - conventions.md > 3. Main Artifacts > 3.1 Product level > sad.md > Cấu trúc
8
12
  - skills/spec-sad/SKILL.md > Process > Bước 1: Kiểm tra preconditions
@@ -1,398 +0,0 @@
1
- ---
2
- name: spec-frd-update
3
- description: Migrate frd.md hiện có lên cấu trúc template mới nhất — fix Mermaid syntax, rename Feature AC → FAC (counter riêng), thêm Verification Rules section, cascade ID remap qua fdd/tsd/test/spec/tech. Dùng cho repo đã onboard SDD từ trước khi template thay đổi.
4
- ---
5
-
6
- # spec-frd-update
7
-
8
- ## Overview
9
-
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
-
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
-
14
- ## When to Use
15
-
16
- - Repo đã chạy `/spec-brownfield-feature` hoặc `/spec-new` từ lâu, frd.md sinh ra theo template cũ — giờ template đã update.
17
- - Sau khi `git pull` kit mới và phát hiện frd.md hiện tại thiếu section so với template mới.
18
- - Audit định kỳ để đảm bảo mọi frd.md tuân thủ cùng format.
19
-
20
- ## When NOT to Use
21
-
22
- - frd.md chưa tồn tại → dùng `/spec-brownfield-feature` (brownfield) hoặc `/spec-new` (greenfield).
23
- - Muốn thay đổi **nội dung** frd (thêm US, đổi AC text) → edit thủ công hoặc qua integration changeset.
24
- - Template chưa thay đổi gì so với khi frd.md được tạo → skill này sẽ no-op, không có gì để làm.
25
-
26
- ---
27
-
28
- ## Cảnh báo về ID cascade
29
-
30
- Skill này có thể **rename Feature AC ID** từ `AC-F{NNN}-{seq}` sang `FAC-F{NNN}-{seq}` (counter riêng, reset từ 001). Các file sau có thể reference những ID này và cần cascade:
31
-
32
- - `feature/{F-XXX}/fdd.md` — section Verification Implementation
33
- - `feature/{F-XXX}/tsd.md` — Traceability Matrix, Test Cases
34
- - `integrations/*/spec.md` — Cascade Proposals, Changes blocks
35
- - `integrations/*/tech.md` — Changes blocks
36
- - `integrations/*/test.md` — Coverage table
37
-
38
- **Mặc định dry-run** — skill in toàn bộ ID remap + diff trước khi ghi, user xác nhận từng feature một.
39
-
40
- ---
41
-
42
- ## Migration vectors
43
-
44
- Skill detect từng frd hiện tại thuộc "era" nào và apply vectors tương ứng:
45
-
46
- | Vector | Detect bằng | Action | Risk |
47
- |---|---|---|---|
48
- | **V1 Mermaid syntax** | Có pattern `\[\{.+?\}\]` trong code block mermaid | Rewrite `[{X}]` → `["X"]` | None |
49
- | **V2 Flow stability note** | Section `## User Flows` thiếu chuỗi "Flow numbering" | Insert dòng note sau intro | None |
50
- | **V3 Section rename** | Có heading `## Feature-level Acceptance Criteria` | Rename → `## Feature Acceptance Criteria` + insert 4-group block + Out-of-scope note | Low |
51
- | **V4 FAC ID renumber** | Trong section Feature AC, IDs dùng prefix `AC-F` (chứ không phải `FAC-F`) | Remap → `FAC-F{NNN}-001..N` + cascade references trong repo | **HIGH** |
52
- | **V5 US/AC stability notes** | Section User Stories thiếu chuỗi "ID stable" | Insert 2 dòng note | None |
53
- | **V6 VR section** | Không có heading `## Verification Rules` | Propose VR table từ User Stories → user approve → insert | Medium |
54
- | **V7 Components Used location** | Section `## Components Consumed` đứng riêng (era pre-84d7303) | Move xuống `## Dependencies` thành subsection `### Components Used` | Low |
55
- | **V8 User Flows missing** | Không có heading `## User Flows` (era pre-84d7303) | Derive Mermaid flows từ User Stories → propose → user approve → insert. 1 flow / nhóm US liên quan theo journey logic. **Bắt buộc — không có option skip; FRD migration không hoàn tất nếu thiếu User Flows.** | Medium |
56
-
57
- ---
58
-
59
- ## Process
60
-
61
- ### Bước 0: Pre-flight — working tree clean
62
-
63
- Chạy `git status --porcelain`. Nếu output không rỗng (có file modified / untracked / staged):
64
-
65
- ```
66
- ⛔ Working tree không clean. Skill không tạo file backup `.bak` — rollback dựa vào git.
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
-
69
- Files dirty:
70
- M .specs/main/feature/F-001-auth/frd.md
71
- ?? notes.md
72
- ```
73
-
74
- Dừng hoàn toàn. Skill chỉ proceed khi `git status` clean — đảm bảo mọi change sau đó đều thuộc migration, dễ revert bằng `git checkout -- {path}` hoặc `git restore`.
75
-
76
- Nếu repo không phải git repo → cảnh báo và yêu cầu confirm:
77
- > ⚠ Thư mục này không phải git repo. Skill không tạo file backup. Nếu apply sai, không thể rollback. Tiếp tục? (yes / no — default no)
78
-
79
- ---
80
-
81
- ### Bước 1: Discover & classify
82
-
83
- Quét `.specs/main/feature/*/frd.md`. Với mỗi file:
84
-
85
- 1. Parse headings và frontmatter.
86
- 2. Run detection cho V1–V8.
87
- 3. Build classification table.
88
-
89
- Display kết quả:
90
-
91
- ```
92
- Detected FRDs:
93
-
94
- [1] F-001 — auth | Era: 2026-04 | Vectors needed: V1, V3, V4 (3 IDs), V5, V6
95
- [2] F-002 — checkout | Era: 2026-05 | Vectors needed: V5, V6
96
- [3] F-003 — refund | Era: current | Vectors needed: — (đã clean)
97
- [4] F-004 — admin-panel | Era: pre-flows | Vectors needed: V1, V3, V4 (2 IDs), V5, V6, V7, V8
98
-
99
- Tổng: 4 FRDs · 3 cần migration · 1 đã sạch.
100
- ```
101
-
102
- Hỏi user scope:
103
-
104
- ```
105
- Migrate FRDs nào?
106
- [A] Tất cả cần migration (3 files)
107
- [1] Chỉ F-001
108
- [2] Chỉ F-002
109
- ...
110
- [N] Chọn subset (nhập danh sách số, vd: "1 4")
111
- [X] Hủy
112
-
113
- Lựa chọn:
114
- ```
115
-
116
- Nếu không có FRD nào cần migration → thông báo `Tất cả frd.md đã clean. No-op.` rồi dừng.
117
-
118
- ---
119
-
120
- ### Bước 2: Load context per FRD
121
-
122
- Với mỗi FRD đã chọn, load các file sau (chỉ những gì cần thiết — KHÔNG load conventions.md, KHÔNG load source code):
123
-
124
- | File | Bắt buộc | Mục đích |
125
- |---|---|---|
126
- | `.specs/main/feature/{F-XXX}-{slug}/frd.md` | ✓ | File cần migrate |
127
- | [templates/main/feature/frd-template.md](../../templates/main/feature/frd-template.md) | ✓ | Target structure — copy text cho V2/V3/V5 |
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
-
132
- **KHÔNG load:**
133
- - `conventions.md` — template đã self-contained, load là thừa
134
- - Source code — frd là WHAT, derive VR từ US/AC chứ không phải implementation
135
- - `tech.md`/`cdd.md` — có thể contaminate VR bằng tech detail (regex, varchar(255)…)
136
-
137
- ---
138
-
139
- ### Bước 3: Apply mechanical vectors (V1, V2, V3, V5, V7)
140
-
141
- Đây là các vector **không cần model reasoning** — pure text manipulation. Apply tuần tự, không hỏi user.
142
-
143
- #### V1 — Mermaid syntax fix
144
- - Regex trong mỗi code block ```mermaid: `\[\{([^}]+)\}\]` → `["$1"]`
145
- - Edge case: keep escaped braces nguyên vẹn, chỉ replace pattern `[{...}]` ở edge label / node label.
146
-
147
- #### V2 — Flow stability note
148
- - Sau bullet intro của `## User Flows` (dòng `{Mỗi flow là một Mermaid…}`), insert:
149
- > Flow numbering **stable** — không renumber khi xóa flow. Nếu xóa Flow 1, Flow 2 giữ nguyên số (không tái sử dụng số 1).
150
-
151
- #### V3 — Section rename + structure
152
- - Rename heading `## Feature-level Acceptance Criteria` → `## Feature Acceptance Criteria`.
153
- - Replace block intro (dòng "Criteria áp dụng cho toàn bộ feature — không gắn với story…") bằng full block từ template (4 nhóm + Out-of-scope + Format note). Copy nguyên văn từ frd-template.md.
154
-
155
- #### V5 — US/AC stability notes
156
- - Sau dòng `US ID format: ...` trong User Stories section, đảm bảo có 2 dòng:
157
- > US ID format: `US-F{NNN}-{seq}` — đánh số tăng dần toàn feature. ID **stable** — không tái sử dụng seq khi xóa, không renumber.
158
- >
159
- > Story AC ID format: `AC-F{NNN}-{seq}` — đánh số tăng dần toàn feature (không reset giữa các story). ID **stable** — không tái sử dụng seq khi xóa, không renumber.
160
-
161
- #### V7 — Components Used relocation
162
- - Detect `## Components Consumed` section.
163
- - Cắt nội dung bảng, xóa heading.
164
- - Trong `## Dependencies`, ensure có 2 subsections: `### Feature Dependencies` (giữ bảng cũ nếu có) và `### Components Used` (chèn bảng vừa cắt).
165
-
166
- ---
167
-
168
- ### Bước 4: V4 — AC → FAC renumber với cascade
169
-
170
- **Đây là vector cao risk nhất.** Mỗi feature làm tuần tự, không batch.
171
-
172
- #### 4.1 Parse Feature AC IDs
173
- - Trong section `## Feature Acceptance Criteria` (đã rename ở V3), extract tất cả ID dạng `AC-F{NNN}-{seq}`.
174
- - List: `[AC-F001-002, AC-F001-005, AC-F001-007]` (gap OK).
175
-
176
- #### 4.2 Build remap table
177
- - Cũ → mới: reset counter từ 001, giữ thứ tự xuất hiện.
178
- - Ví dụ:
179
- ```
180
- AC-F001-002 → FAC-F001-001
181
- AC-F001-005 → FAC-F001-002
182
- AC-F001-007 → FAC-F001-003
183
- ```
184
-
185
- #### 4.3 Scan cascade references
186
- - Grep toàn `.specs/` cho từng ID cũ.
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
- - Tạo bảng impact:
189
- ```
190
- Cascade impact for F-001:
191
- feature/F-001-auth/fdd.md 3 refs
192
- feature/F-001-auth/tsd.md 5 refs
193
- integrations/003-otp-flow/spec.md 1 ref
194
- integrations/003-otp-flow/test.md 2 refs
195
- ```
196
-
197
- #### 4.4 Dry-run preview
198
- Hiển thị:
199
- - Full remap table
200
- - Per-file diff snippet (3 dòng context mỗi ref)
201
- - Confirm prompt:
202
-
203
- ```
204
- Apply remap cho F-001? (yes / no / skip-feature)
205
- yes → apply tất cả changes (frd.md + cascade files)
206
- no → hủy V4 cho feature này, vẫn giữ AC-F prefix
207
- skip-feature → bỏ qua toàn bộ migration cho F-001
208
- ```
209
-
210
- #### 4.5 Apply
211
- - Edit `frd.md`: rewrite IDs trong section Feature AC.
212
- - Edit từng cascade file: replace exact ID strings (sử dụng Edit với context dòng để tránh false-positive).
213
- - Validate: re-grep ID cũ, phải về 0 trong Feature AC scope; Story AC giữ nguyên.
214
-
215
- ---
216
-
217
- ### Bước 5: V6 — Generate Verification Rules section
218
-
219
- **Vector tiêu tốn LLM nhất.** Run nếu V6 detected.
220
-
221
- #### 5.1 Load minimal context
222
- - Section `## User Stories` của FRD đó (đã chứa AC).
223
- - Optional: `domain.md > Shared Entities` block (nếu có field match entity name).
224
-
225
- **KHÔNG load:** code, fdd.md, tech.md. Mục đích: tránh contamination bằng HOW.
226
-
227
- #### 5.2 Derive rules
228
- Quét từng AC trong User Stories:
229
- - Identify input action ("nhập email", "submit form", "chọn date", "upload file"…).
230
- - Extract field name + implicit constraint.
231
- - Output bảng VR theo format template:
232
- - **Type**: semantic (`string`, `email`, `enum<A|B|C>`, …) — không bao giờ concrete tech type.
233
- - **Rule**: human-readable diễn đạt, không regex.
234
- - **Refs**: trỏ tới US/AC source.
235
- - Sub-rule phức tạp (vd: password = letter + digit + symbol) → tách flat thành nhiều ID.
236
-
237
- #### 5.3 Propose & approve
238
- Hiển thị bảng VR đề xuất:
239
-
240
- ```
241
- Proposed Verification Rules for F-001:
242
-
243
- | ID | Field | Type | Required | Rule | Refs |
244
- |----|-------|------|----------|------|------|
245
- | VR-F001-001 | email | email | yes | định dạng email hợp lệ | US-F001-001 |
246
- | VR-F001-002 | password | string | yes | tối thiểu 8 ký tự | US-F001-001 |
247
- ...
248
-
249
- Apply? (yes / edit / skip-vr)
250
- yes → insert vào frd.md
251
- edit → user trả lời text-edit rules nào cần sửa
252
- skip-vr → giữ FRD không có VR section
253
- ```
254
-
255
- #### 5.4 Insert
256
- - Insert `## Verification Rules` section ngay trước `## Scope` (theo thứ tự template).
257
- - Copy nguyên block intro + quy ước từ template, chỉ replace bảng bằng nội dung derived.
258
-
259
- ---
260
-
261
- ### Bước 6: V8 — Derive User Flows section
262
-
263
- **Run nếu V8 detected. Bắt buộc — không có option skip.** Propose-then-approve giống V6 nhưng loop cho tới khi user approve: model derive draft, user duyệt (yes) hoặc trả phản hồi (edit) → model regenerate. FRD migration chỉ hoàn tất khi `## User Flows` đã insert.
264
-
265
- #### 6.1 Load minimal context
266
- - Section `## Overview` của FRD (framing scope + actors).
267
- - Section `## User Stories` (đã chứa AC — source của journey steps).
268
-
269
- **KHÔNG load:** code, fdd.md, tech.md, sequence diagrams hiện có. Mục đích: flow ở frd là **user-facing journey** (WHAT), không phải implementation sequence (HOW thuộc fdd).
270
-
271
- #### 6.2 Derive flows
272
- Nhóm User Stories theo journey logic, mỗi journey → 1 Mermaid flowchart:
273
-
274
- - **Grouping rule:** US chia sẻ chung trigger / actor / postcondition → cùng 1 flow. Vd `US-001 Đăng ký` + `US-002 Xác thực email` → 1 flow "Onboarding"; còn `US-003 Reset password` là journey riêng.
275
- - **Mermaid structure:**
276
- - Start node = trigger (user action mở đầu, từ Given của AC đầu tiên).
277
- - Decision nodes = branch từ AC (happy / error paths).
278
- - End node = postcondition (từ Then của AC cuối).
279
- - Edge label = user action hoặc system response (từ When / Then).
280
- - **Naming:** `Flow {N}: {tên ngắn}` — N đánh số từ 1 theo thứ tự xuất hiện trong frd.
281
- - **Mermaid syntax:** dùng `["..."]` chứ KHÔNG `[{...}]` (V1 convention).
282
-
283
- #### 6.3 Propose & approve
284
-
285
- Hiển thị draft full mermaid blocks (chưa ghi file):
286
-
287
- ```
288
- Proposed User Flows for F-001:
289
-
290
- Flow 1: Onboarding (đăng ký + xác thực email)
291
- Spans: US-F001-001, US-F001-002
292
- ```mermaid
293
- flowchart TD
294
- A["User mở trang Sign up"] --> B["Nhập email + password"]
295
- B --> C{"Validation pass?"}
296
- C -->|yes| D["Gửi email xác thực"]
297
- C -->|no| E["Hiển thị lỗi"]
298
- D --> F["User click link trong email"]
299
- F --> G["Account active"]
300
- ```
301
-
302
- Flow 2: Login
303
- Spans: US-F001-003
304
- ```mermaid
305
- ...
306
- ```
307
-
308
- Apply? (yes / edit)
309
- yes → insert vào frd.md
310
- edit → user góp ý flow nào cần sửa (vd: "Flow 1 thiếu nhánh email đã tồn tại") → regenerate draft, loop lại
311
-
312
- User Flows là **bắt buộc** — không có option skip. Nếu user muốn dừng toàn bộ migration cho feature này, dùng "skip-feature" ở Bước 4 hoặc abort skill (Ctrl-C) trước khi V8 chạy.
313
- ```
314
-
315
- #### 6.4 Insert
316
- - Insert section `## User Flows` ngay sau `## Overview` (theo thứ tự template).
317
- - Copy intro + **Flow numbering stable** note (V2 convention) từ template, sau đó list các Mermaid blocks theo flow numbering.
318
-
319
- ---
320
-
321
- ### Bước 7: Validate
322
-
323
- Sau khi apply hết vectors cho một FRD, chạy check:
324
-
325
- - [ ] `## Feature Acceptance Criteria` (không phải Feature-**level**)
326
- - [ ] Không còn ID `AC-F{NNN}-` trong scope Feature AC (chỉ có `FAC-F{NNN}-`)
327
- - [ ] Story AC vẫn dùng `AC-F{NNN}-` (không bị remap nhầm)
328
- - [ ] Mermaid blocks không còn pattern `[{...}]`
329
- - [ ] Có heading `## Verification Rules` (nếu V6 applied)
330
- - [ ] Có heading `## User Flows` với ít nhất 1 Mermaid flowchart (bắt buộc — nếu V8 detected mà section vẫn vắng thì migration chưa hoàn tất)
331
- - [ ] VR Rule column không chứa keyword UI copy: "error message", "vui lòng", "hint", "tooltip"
332
- - [ ] Frontmatter `referenced_by` trỏ tới `3.3 Feature level` (không phải `3.2`)
333
-
334
- Nếu check fail → rollback bằng `git checkout -- {file}` (skill không tạo backup vật lý vì git history đã đảm nhận vai trò này). Yêu cầu working tree clean trước khi chạy skill — nếu dirty, skill báo lỗi và dừng để tránh trộn lẫn change của user với change của migration.
335
-
336
- ---
337
-
338
- ### Bước 8: Report + changelog
339
-
340
- Cho mỗi FRD đã migrate:
341
-
342
- ```
343
- ✓ F-001 — auth
344
- Vectors applied: V1, V3, V4 (3 IDs remapped), V5, V6 (8 VRs added), V8 (2 flows added)
345
- Cascade: fdd.md (3 refs), tsd.md (5 refs), integrations/003 (3 refs)
346
-
347
- ✓ F-002 — checkout
348
- Vectors applied: V5, V6 (5 VRs added)
349
- ```
350
-
351
- **Change History append:** Cho mỗi FRD vừa migrate (và mỗi cascade target `fdd.md`/`tsd.md` bị touched), append entry vào section `## Change History` theo `conventions.md` §5.5:
352
-
353
- ```markdown
354
- ### {YYYY-MM-DD} — manual — update
355
-
356
- - **Migration**: applied vectors V1, V3, V4 (3 IDs remapped: AC-F001-001→FAC-F001-001, ...), V5, V6 (8 VRs added), V8 (2 flows added) qua /spec-frd-update
357
- ```
358
-
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
-
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
-
363
- Append vào [changelogs.md](../../changelogs.md) `## [Unreleased]`:
364
-
365
- ```
366
- - chore: migrate frd.md format cho {N} features (vectors: ...)
367
- ```
368
-
369
- ---
370
-
371
- ## Common Rationalizations
372
-
373
- | Rationalization | Reality |
374
- |---|---|
375
- | "Format mới optional, frd cũ vẫn dùng được" | Đúng cho đọc thủ công. Nhưng `/spec-test` và `/spec-tsd` derive TC theo IDs FAC/VR — frd thiếu sẽ break derivation, fallback bằng placeholder không trace được. |
376
- | "Tự sinh VR an toàn, model giỏi infer constraint" | Model dễ bịa rule không có trong AC ("password tối thiểu 12 ký tự" khi AC chỉ nói "password hợp lệ"). Luôn propose-then-approve, không auto-apply. |
377
- | "Skip cascade, chỉ rename trong frd thôi" | Sẽ break tsd.md Traceability Matrix và test.md Coverage. Hoặc cascade full, hoặc skip V4 toàn bộ. |
378
- | "Migrate batch tất cả cùng lúc cho nhanh" | V4 cascade dễ break — user cần xem diff per-feature. Batch mode chỉ áp dụng cho V1, V2, V3, V5, V7 (mechanical, low risk). V6 và V8 phải propose-then-approve. |
379
-
380
- ## Red Flags
381
-
382
- - Apply V4 không có dry-run preview → user không kịp catch cascade reference sai.
383
- - VR Rule column chứa regex `^[a-z]+$` hoặc tech type `varchar(255)` — đó là HOW, sai vị trí.
384
- - V8 flows auto-apply không qua propose-then-approve → model có thể bịa glue step / sai journey grouping mà BA không kịp catch.
385
- - V8 flow chứa step không trace được lên US nào (model bịa) → BA reject draft và yêu cầu regenerate.
386
- - Để FRD không có `## User Flows` sau migration vì "draft chưa ổn" → sai. V8 bắt buộc; nếu draft chưa ổn, dùng `edit` loop cho tới khi approve. FRD không có User Flows = migration chưa hoàn tất.
387
- - V8 Mermaid block dùng syntax `[{...}]` thay vì `["..."]` — vi phạm V1 convention.
388
- - Validate fail nhưng skip rollback → file ở trạng thái nửa migrate, khó debug sau.
389
- - Load conventions.md hoặc source code "for safety" → contamination, tốn context, không cải thiện output.
390
-
391
- ## Verification
392
-
393
- Trước khi mark feature done:
394
- - [ ] Tất cả vectors detected đã apply (hoặc skip có log lý do — riêng V8 KHÔNG được skip)
395
- - [ ] Validate Bước 6 pass
396
- - [ ] Working tree clean trước khi skill chạy (git status verified) — rollback dùng git, không có file backup
397
- - [ ] Cascade ID đã re-grep và confirm 0 false-positive
398
- - [ ] User confirm VR proposal nếu V6 applied