@educa-corp/sdd-framework 0.9.2 → 0.9.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/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/qc-analyze.md +189 -66
- package/core/commands/qc-design-test.md +141 -2
- package/core/commands/qc-plan.md +153 -7
- package/core/commands/qc-review.md +134 -1
- package/core/commands/qc-run-test.md +134 -1
- package/core/modules/qc-playwright/stack-profile.yaml +3 -3
- package/core/skills/qc/qa-analyst/DOC_GAP.template.md +47 -17
- package/core/skills/qc/qa-analyst/acceptance-criteria.md +1 -1
- package/core/skills/qc/qa-analyst/business-rules.md +2 -2
- package/core/skills/qc/qa-analyst/data-flow.md +2 -2
- package/core/skills/qc/qa-analyst/spec-breakdown.md +2 -2
- package/core/skills/qc/qa-analyst/spec-issue-reporter.md +14 -2
- package/core/skills/qc/qa-designer/e2e/journey.md +1 -1
- package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +1 -1
- package/core/skills/qc/qa-designer/functional/api.md +1 -1
- package/core/skills/qc/qa-designer/functional/gui-feature.md +1 -1
- package/core/skills/qc/qa-designer/functional/gui-screen.md +1 -1
- package/core/skills/qc/qa-designer/integration/api.md +1 -1
- package/core/skills/qc/qa-designer/integration/db.md +1 -1
- package/core/skills/qc/qa-designer/integration/gui.md +1 -1
- package/core/skills/qc/qa-designer/integration/kafka.md +1 -1
- package/core/skills/qc/qa-designer/non-functional.md +1 -1
- package/core/skills/qc/qa-planner/test-plan.md +24 -13
- package/core/skills/qc/qa-runner/exploratory/session.md +1 -1
- package/core/steps/context-loader.md +1 -1
- package/core/steps/qc-scope.md +119 -0
- package/core/templates/project-context.yaml +3 -1
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +1 -1
- package/docs/04-reference/configuration.md +146 -146
- package/docs/explain/15-qc-analyze.md +1 -1
- package/docs/explain/16-qc-plan.md +1 -1
- package/docs/explain/17-qc-design-test.md +1 -1
- package/docs/plans/qc-implementation-log.md +145 -4
- package/docs/plans/qc-sync-command.md +2 -1
- package/package.json +1 -1
- package/scripts/migrate-qc-docs.js +261 -0
|
@@ -1,146 +1,146 @@
|
|
|
1
|
-
[← Reference](./) · [Concepts › Architecture](../02-concepts/architecture.md)
|
|
2
|
-
|
|
3
|
-
# Reference · Configuration
|
|
4
|
-
|
|
5
|
-
> Hai file cấu hình chính. `/update-framework` **không** đụng chúng — đây là nội dung của bạn.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. `project-context.yaml`
|
|
10
|
-
|
|
11
|
-
**Single source of truth** cho paths/mode/routing. Nằm ở `.agent/project-context.yaml`, sinh từ `templates/project-context.yaml` qua token substitution khi init. Mọi workflow đọc file này để biết **WHERE** tìm mọi thứ.
|
|
12
|
-
|
|
13
|
-
### Cấu trúc chính
|
|
14
|
-
|
|
15
|
-
```yaml
|
|
16
|
-
project:
|
|
17
|
-
name: "..."
|
|
18
|
-
description: "..."
|
|
19
|
-
|
|
20
|
-
paths:
|
|
21
|
-
specs_dir: "specs" # gốc mọi spec artifact
|
|
22
|
-
trace_dir: ".trace" # trace state .tsv
|
|
23
|
-
qc_dir: "docs" # working docs của QC
|
|
24
|
-
qc_skills_dir: ".agent/skills/qc" # nơi qc-* nạp skill (override sang repo QC riêng)
|
|
25
|
-
refinement_dir: ".agent/review" # findings review
|
|
26
|
-
|
|
27
|
-
setup:
|
|
28
|
-
mode: single | umbrella
|
|
29
|
-
spec_source: "..." # (umbrella) spec repo dùng chung
|
|
30
|
-
|
|
31
|
-
services: # (multi/umbrella) map domain → service
|
|
32
|
-
# dạng phẳng: {domain}: { path, module }
|
|
33
|
-
# dạng map-theo-platform: {domain}: { web: {path,module}, app: {...}, system: {...} }
|
|
34
|
-
|
|
35
|
-
conventions:
|
|
36
|
-
build_command: "..." # lệnh build verify (≤3 retry)
|
|
37
|
-
test_command: "..."
|
|
38
|
-
|
|
39
|
-
tech_stack:
|
|
40
|
-
database: "..." # vd PostgreSQL
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Bố cục feature-package (path resolution)
|
|
44
|
-
|
|
45
|
-
Mọi artifact của một feature nằm chung `specs/{domain}/{prd-slug}/`:
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
specs/{domain}/{prd-slug}/
|
|
49
|
-
├── {TICKET-ID}-{prd-slug}.md # PRD (file .md duy nhất ở gốc)
|
|
50
|
-
├── bdd/{web|app|system}/*.feature # BDD — subfolder platform LUÔN có
|
|
51
|
-
├── tech-docs/{TICKET-ID}-tech-design.md # MỘT doc gộp cho cả PRD
|
|
52
|
-
├── design-spec/{TICKET-ID}*.md # FE/App
|
|
53
|
-
└── changelog/{TICKET-ID}-{prd-slug}.changelog.md # chỉ tạo khi changelog vượt 5 version
|
|
54
|
-
.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv # MỘT sổ / UC × platform (24 cột)
|
|
55
|
-
.trace/{domain}/{prd-slug}/_seams.tsv # sổ seam/stub — nguồn 2 cờ 🔴 chặn PR
|
|
56
|
-
.trace/trace-report.json # snapshot cho panel — GHI ĐÈ mỗi lần chạy
|
|
57
|
-
.trace/trace-history.jsonl # nhật ký append-only — PHẢI commit
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
- `{domain}` = segment đầu sau `specs_dir`.
|
|
61
|
-
- `{prd-slug}` = segment kế tiếp (folder feature-package) — **không** phải folder cha trực tiếp của file lồng sâu.
|
|
62
|
-
- **Segment `{platform}` không optional** — mọi mode, kể cả umbrella. `web` và `system` của cùng một UC là hai file khác nhau; bỏ segment thì chúng va tên và **ghi đè nhau**. Trace tách theo platform nên bố cục spec phải khớp.
|
|
63
|
-
*Project còn ở bố cục phẳng: `npx @educa-corp/sdd-framework --migrate-bdd-platform` (dry-run mặc định).*
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## 2. `CLAUDE.md` (phân tầng)
|
|
68
|
-
|
|
69
|
-
Instruction cho AI agent — AI *follow* file này thay vì *invent*.
|
|
70
|
-
|
|
71
|
-
| Tầng | Nội dung |
|
|
72
|
-
|------|----------|
|
|
73
|
-
| **root** `CLAUDE.md` | Luật chung dự án/umbrella |
|
|
74
|
-
| **overlay** `{service}/CLAUDE.md` | §2 kiến trúc & thứ tự layer & package strategy · §3 coding standards · §5 error handling — **theo stack** |
|
|
75
|
-
|
|
76
|
-
> Service overlay **thắng** root khi mâu thuẫn. context-loader nạp cả hai, đặt ở **cuối** context (Lost-in-the-Middle: "follow style này").
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## 3. Single vs Umbrella
|
|
81
|
-
|
|
82
|
-
| | Single | Umbrella |
|
|
83
|
-
|---|--------|----------|
|
|
84
|
-
| `setup.mode` | `single` | `umbrella` |
|
|
85
|
-
| Spec ở đâu | Cùng repo | **Spec repo dùng chung** (`spec_source`) |
|
|
86
|
-
| Code ở đâu | Cùng repo | Service submodule (chỉ code + tooling) |
|
|
87
|
-
| Trace/feedback/findings | Cùng repo | Trong spec repo (một nơi authoritative) |
|
|
88
|
-
| Đồng bộ | — | `/sync` (pull + submodule + nổi feedback + Living Docs) |
|
|
89
|
-
|
|
90
|
-
Khi `spec_source` được đặt, **mọi** PRD/BDD/tech-doc/design-spec/`.trace`/`.agent/review`/`feedback` route về spec repo — vì đều là **artifact liên team**.
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Vùng nào bị ghi đè khi update
|
|
95
|
-
|
|
96
|
-
`.agent/` là **mirror sinh ra**: `/update-framework` chạy `npx … --init`, và `--init` copy `core/` → `.agent/` **vô điều kiện**.
|
|
97
|
-
|
|
98
|
-
| Đường dẫn | Sửa được? | Vì sao |
|
|
99
|
-
|---|:---:|---|
|
|
100
|
-
| `CLAUDE.md` | ✅ | ngoài `.agent/` |
|
|
101
|
-
| `.agent/project-context.yaml` | ✅ | file **duy nhất trong `.agent/`** có guard: chỉ tạo nếu chưa tồn tại |
|
|
102
|
-
| `.agent/project-lessons.md` · `.agent/review/` | ✅ | không nằm trong `core/` nên nâng cấp không đụng |
|
|
103
|
-
| `specs/domain-knowledge/` · `.trace/` · `feedback/` | ✅ | ngoài `.agent/` |
|
|
104
|
-
| `.agent/commands` `steps` `rules` `skills` `hooks` `templates` `modules` | ❌ | copy từ repo framework, **ghi đè mỗi lần nâng cấp** |
|
|
105
|
-
|
|
106
|
-
**Nếu bạn đã sửa gì trong vùng ❌** — từ v0.4.2 `--init` tự cứu:
|
|
107
|
-
|
|
108
|
-
- bản cũ copy sang `.agent/.overwritten-{version}-{YYYYMMDD}/` (giữ nguyên cây thư mục)
|
|
109
|
-
- danh sách file bị ghi đè in ra ngay sau bước cài
|
|
110
|
-
- `.agent/.install-manifest.json` ghi hash của **đúng những gì lần cài trước đã viết** — nhờ đó lệnh phân biệt được *bạn sửa file* với *framework tự đổi file giữa hai version* (một phép so nội dung thuần sẽ flag cả hai và báo oan hàng chục file mỗi lần nâng cấp)
|
|
111
|
-
|
|
112
|
-
Thêm vào `.gitignore` của project:
|
|
113
|
-
|
|
114
|
-
```gitignore
|
|
115
|
-
.agent/.overwritten-*/
|
|
116
|
-
.agent/.install-manifest.json
|
|
117
|
-
.trace-mirror/ # bản sao cho panel VS Code — sinh lại được
|
|
118
|
-
.living-docs/ # report gộp — sinh lại được (đặt trong .gitignore của spec repo)
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
> ### ⚠️ `.trace/` **KHÔNG** được gitignore
|
|
122
|
-
>
|
|
123
|
-
> Đây là chỗ dễ mất dữ liệu nhất trong toàn framework.
|
|
124
|
-
>
|
|
125
|
-
> | Đường dẫn | Vai trò | Git |
|
|
126
|
-
> |---|---|---|
|
|
127
|
-
> | `{paths.trace_dir}` (`.trace/`) | **AUTHORITATIVE** — `.tsv` + `trace-history.jsonl`. **Không regenerate được** | **PHẢI commit** |
|
|
128
|
-
> | `.trace-mirror/` | bản sao cho panel VS Code | gitignore |
|
|
129
|
-
> | `.living-docs/` | report gộp | gitignore |
|
|
130
|
-
>
|
|
131
|
-
> **Trước v0.4.3 cả hai cùng tên `.trace`.** Khi dev mở thẳng spec repo làm workspace thì hai đường dẫn **bằng nhau** — và `/sync` (bản cũ) gợi ý gitignore theo **tên**, không theo vai trò. Làm theo là **mất sổ gốc, im lặng**: máy vẫn chạy, dashboard vẫn có số; chỉ người thứ hai clone về mới phát hiện, và lúc đó lịch sử đã mất vĩnh viễn.
|
|
132
|
-
>
|
|
133
|
-
> **Kiểm dự án đang chạy:**
|
|
134
|
-
> ```bash
|
|
135
|
-
> git -C {spec_source} check-ignore .trace # trả về kết quả = ĐANG DÍNH
|
|
136
|
-
> ```
|
|
137
|
-
> Dính thì gỡ dòng khớp `.trace` khỏi `.gitignore` rồi `git add -f .trace && git commit`.
|
|
138
|
-
> Từ v0.4.3 `/sync` Step 4b tự kiểm và báo động 🔴 nếu phát hiện.
|
|
139
|
-
|
|
140
|
-
> Muốn thay đổi **bền vững** thì sửa trong repo framework rồi phát hành. Tuỳ biến riêng của một project thuộc về `CLAUDE.md`, `.agent/project-context.yaml`, hoặc `.agent/project-lessons.md` — cả ba đều không bị ghi đè. Ranh giới đầy đủ: `.agent/README.md`.
|
|
141
|
-
>
|
|
142
|
-
> **Template `.feature`/PRD không cấu hình được.** Skeleton được `{{include}}` nướng cứng vào file lệnh lúc build, nên sửa `.agent/templates/` **không có tác dụng** (và sẽ bị ghi đè). Đổi cấu trúc artifact = sửa `templates/*` trong repo framework rồi `npm run build`. Chi tiết: `.agent/templates/README.md`.
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
→ [Architecture › Configuration](../02-concepts/architecture.md#configuration-2-file) · [Modules](modules.md)
|
|
1
|
+
[← Reference](./) · [Concepts › Architecture](../02-concepts/architecture.md)
|
|
2
|
+
|
|
3
|
+
# Reference · Configuration
|
|
4
|
+
|
|
5
|
+
> Hai file cấu hình chính. `/update-framework` **không** đụng chúng — đây là nội dung của bạn.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. `project-context.yaml`
|
|
10
|
+
|
|
11
|
+
**Single source of truth** cho paths/mode/routing. Nằm ở `.agent/project-context.yaml`, sinh từ `templates/project-context.yaml` qua token substitution khi init. Mọi workflow đọc file này để biết **WHERE** tìm mọi thứ.
|
|
12
|
+
|
|
13
|
+
### Cấu trúc chính
|
|
14
|
+
|
|
15
|
+
```yaml
|
|
16
|
+
project:
|
|
17
|
+
name: "..."
|
|
18
|
+
description: "..."
|
|
19
|
+
|
|
20
|
+
paths:
|
|
21
|
+
specs_dir: "specs" # gốc mọi spec artifact
|
|
22
|
+
trace_dir: ".trace" # trace state .tsv
|
|
23
|
+
qc_dir: "docs" # working docs của QC — {qc_dir}/{TICKET-ID}/{platform}/
|
|
24
|
+
qc_skills_dir: ".agent/skills/qc" # nơi qc-* nạp skill (override sang repo QC riêng)
|
|
25
|
+
refinement_dir: ".agent/review" # findings review
|
|
26
|
+
|
|
27
|
+
setup:
|
|
28
|
+
mode: single | umbrella
|
|
29
|
+
spec_source: "..." # (umbrella) spec repo dùng chung
|
|
30
|
+
|
|
31
|
+
services: # (multi/umbrella) map domain → service
|
|
32
|
+
# dạng phẳng: {domain}: { path, module }
|
|
33
|
+
# dạng map-theo-platform: {domain}: { web: {path,module}, app: {...}, system: {...} }
|
|
34
|
+
|
|
35
|
+
conventions:
|
|
36
|
+
build_command: "..." # lệnh build verify (≤3 retry)
|
|
37
|
+
test_command: "..."
|
|
38
|
+
|
|
39
|
+
tech_stack:
|
|
40
|
+
database: "..." # vd PostgreSQL
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Bố cục feature-package (path resolution)
|
|
44
|
+
|
|
45
|
+
Mọi artifact của một feature nằm chung `specs/{domain}/{prd-slug}/`:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
specs/{domain}/{prd-slug}/
|
|
49
|
+
├── {TICKET-ID}-{prd-slug}.md # PRD (file .md duy nhất ở gốc)
|
|
50
|
+
├── bdd/{web|app|system}/*.feature # BDD — subfolder platform LUÔN có
|
|
51
|
+
├── tech-docs/{TICKET-ID}-tech-design.md # MỘT doc gộp cho cả PRD
|
|
52
|
+
├── design-spec/{TICKET-ID}*.md # FE/App
|
|
53
|
+
└── changelog/{TICKET-ID}-{prd-slug}.changelog.md # chỉ tạo khi changelog vượt 5 version
|
|
54
|
+
.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv # MỘT sổ / UC × platform (24 cột)
|
|
55
|
+
.trace/{domain}/{prd-slug}/_seams.tsv # sổ seam/stub — nguồn 2 cờ 🔴 chặn PR
|
|
56
|
+
.trace/trace-report.json # snapshot cho panel — GHI ĐÈ mỗi lần chạy
|
|
57
|
+
.trace/trace-history.jsonl # nhật ký append-only — PHẢI commit
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- `{domain}` = segment đầu sau `specs_dir`.
|
|
61
|
+
- `{prd-slug}` = segment kế tiếp (folder feature-package) — **không** phải folder cha trực tiếp của file lồng sâu.
|
|
62
|
+
- **Segment `{platform}` không optional** — mọi mode, kể cả umbrella. `web` và `system` của cùng một UC là hai file khác nhau; bỏ segment thì chúng va tên và **ghi đè nhau**. Trace tách theo platform nên bố cục spec phải khớp.
|
|
63
|
+
*Project còn ở bố cục phẳng: `npx @educa-corp/sdd-framework --migrate-bdd-platform` (dry-run mặc định).*
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 2. `CLAUDE.md` (phân tầng)
|
|
68
|
+
|
|
69
|
+
Instruction cho AI agent — AI *follow* file này thay vì *invent*.
|
|
70
|
+
|
|
71
|
+
| Tầng | Nội dung |
|
|
72
|
+
|------|----------|
|
|
73
|
+
| **root** `CLAUDE.md` | Luật chung dự án/umbrella |
|
|
74
|
+
| **overlay** `{service}/CLAUDE.md` | §2 kiến trúc & thứ tự layer & package strategy · §3 coding standards · §5 error handling — **theo stack** |
|
|
75
|
+
|
|
76
|
+
> Service overlay **thắng** root khi mâu thuẫn. context-loader nạp cả hai, đặt ở **cuối** context (Lost-in-the-Middle: "follow style này").
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 3. Single vs Umbrella
|
|
81
|
+
|
|
82
|
+
| | Single | Umbrella |
|
|
83
|
+
|---|--------|----------|
|
|
84
|
+
| `setup.mode` | `single` | `umbrella` |
|
|
85
|
+
| Spec ở đâu | Cùng repo | **Spec repo dùng chung** (`spec_source`) |
|
|
86
|
+
| Code ở đâu | Cùng repo | Service submodule (chỉ code + tooling) |
|
|
87
|
+
| Trace/feedback/findings | Cùng repo | Trong spec repo (một nơi authoritative) |
|
|
88
|
+
| Đồng bộ | — | `/sync` (pull + submodule + nổi feedback + Living Docs) |
|
|
89
|
+
|
|
90
|
+
Khi `spec_source` được đặt, **mọi** PRD/BDD/tech-doc/design-spec/`.trace`/`.agent/review`/`feedback` route về spec repo — vì đều là **artifact liên team**.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Vùng nào bị ghi đè khi update
|
|
95
|
+
|
|
96
|
+
`.agent/` là **mirror sinh ra**: `/update-framework` chạy `npx … --init`, và `--init` copy `core/` → `.agent/` **vô điều kiện**.
|
|
97
|
+
|
|
98
|
+
| Đường dẫn | Sửa được? | Vì sao |
|
|
99
|
+
|---|:---:|---|
|
|
100
|
+
| `CLAUDE.md` | ✅ | ngoài `.agent/` |
|
|
101
|
+
| `.agent/project-context.yaml` | ✅ | file **duy nhất trong `.agent/`** có guard: chỉ tạo nếu chưa tồn tại |
|
|
102
|
+
| `.agent/project-lessons.md` · `.agent/review/` | ✅ | không nằm trong `core/` nên nâng cấp không đụng |
|
|
103
|
+
| `specs/domain-knowledge/` · `.trace/` · `feedback/` | ✅ | ngoài `.agent/` |
|
|
104
|
+
| `.agent/commands` `steps` `rules` `skills` `hooks` `templates` `modules` | ❌ | copy từ repo framework, **ghi đè mỗi lần nâng cấp** |
|
|
105
|
+
|
|
106
|
+
**Nếu bạn đã sửa gì trong vùng ❌** — từ v0.4.2 `--init` tự cứu:
|
|
107
|
+
|
|
108
|
+
- bản cũ copy sang `.agent/.overwritten-{version}-{YYYYMMDD}/` (giữ nguyên cây thư mục)
|
|
109
|
+
- danh sách file bị ghi đè in ra ngay sau bước cài
|
|
110
|
+
- `.agent/.install-manifest.json` ghi hash của **đúng những gì lần cài trước đã viết** — nhờ đó lệnh phân biệt được *bạn sửa file* với *framework tự đổi file giữa hai version* (một phép so nội dung thuần sẽ flag cả hai và báo oan hàng chục file mỗi lần nâng cấp)
|
|
111
|
+
|
|
112
|
+
Thêm vào `.gitignore` của project:
|
|
113
|
+
|
|
114
|
+
```gitignore
|
|
115
|
+
.agent/.overwritten-*/
|
|
116
|
+
.agent/.install-manifest.json
|
|
117
|
+
.trace-mirror/ # bản sao cho panel VS Code — sinh lại được
|
|
118
|
+
.living-docs/ # report gộp — sinh lại được (đặt trong .gitignore của spec repo)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
> ### ⚠️ `.trace/` **KHÔNG** được gitignore
|
|
122
|
+
>
|
|
123
|
+
> Đây là chỗ dễ mất dữ liệu nhất trong toàn framework.
|
|
124
|
+
>
|
|
125
|
+
> | Đường dẫn | Vai trò | Git |
|
|
126
|
+
> |---|---|---|
|
|
127
|
+
> | `{paths.trace_dir}` (`.trace/`) | **AUTHORITATIVE** — `.tsv` + `trace-history.jsonl`. **Không regenerate được** | **PHẢI commit** |
|
|
128
|
+
> | `.trace-mirror/` | bản sao cho panel VS Code | gitignore |
|
|
129
|
+
> | `.living-docs/` | report gộp | gitignore |
|
|
130
|
+
>
|
|
131
|
+
> **Trước v0.4.3 cả hai cùng tên `.trace`.** Khi dev mở thẳng spec repo làm workspace thì hai đường dẫn **bằng nhau** — và `/sync` (bản cũ) gợi ý gitignore theo **tên**, không theo vai trò. Làm theo là **mất sổ gốc, im lặng**: máy vẫn chạy, dashboard vẫn có số; chỉ người thứ hai clone về mới phát hiện, và lúc đó lịch sử đã mất vĩnh viễn.
|
|
132
|
+
>
|
|
133
|
+
> **Kiểm dự án đang chạy:**
|
|
134
|
+
> ```bash
|
|
135
|
+
> git -C {spec_source} check-ignore .trace # trả về kết quả = ĐANG DÍNH
|
|
136
|
+
> ```
|
|
137
|
+
> Dính thì gỡ dòng khớp `.trace` khỏi `.gitignore` rồi `git add -f .trace && git commit`.
|
|
138
|
+
> Từ v0.4.3 `/sync` Step 4b tự kiểm và báo động 🔴 nếu phát hiện.
|
|
139
|
+
|
|
140
|
+
> Muốn thay đổi **bền vững** thì sửa trong repo framework rồi phát hành. Tuỳ biến riêng của một project thuộc về `CLAUDE.md`, `.agent/project-context.yaml`, hoặc `.agent/project-lessons.md` — cả ba đều không bị ghi đè. Ranh giới đầy đủ: `.agent/README.md`.
|
|
141
|
+
>
|
|
142
|
+
> **Template `.feature`/PRD không cấu hình được.** Skeleton được `{{include}}` nướng cứng vào file lệnh lúc build, nên sửa `.agent/templates/` **không có tác dụng** (và sẽ bị ghi đè). Đổi cấu trúc artifact = sửa `templates/*` trong repo framework rồi `npm run build`. Chi tiết: `.agent/templates/README.md`.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
→ [Architecture › Configuration](../02-concepts/architecture.md#configuration-2-file) · [Modules](modules.md)
|
|
@@ -26,7 +26,7 @@ QC chính thức cần hiểu yêu cầu **testable** trước khi viết test.
|
|
|
26
26
|
|
|
27
27
|
**Input:** UC-ID + spec (PRD/BDD từ spec repo) + skill `qa-analyst`.
|
|
28
28
|
|
|
29
|
-
**Output (per
|
|
29
|
+
**Output (per PRD × nền):** `{qc_dir}/{TICKET-ID}/{platform}/REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md` (11 cột, cột 2 là `UC`) + `{refinement_dir}/{TICKET-ID}-qa-findings.yaml`. Một lần chạy phủ **mọi UC có BDD `approved`** của PRD; UC còn nháp vào bảng *Phạm vi phân tích* với dấu `⏸ Chưa xét` (`--include-draft` để xét luôn).
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
@@ -23,7 +23,7 @@ Không phải mọi scenario rủi ro ngang nhau. Trạm này xếp ưu tiên te
|
|
|
23
23
|
|
|
24
24
|
**Input:** analysis từ trạm 1 + skill `qa-planner`.
|
|
25
25
|
|
|
26
|
-
**Output:** `{qc_dir}/{
|
|
26
|
+
**Output:** `{qc_dir}/{TICKET-ID}/{platform}/TEST_PLAN.md` — **một plan cho cả PRD** (rủi ro + câu hỏi cho dev), `Ready`/`Blocked` chấm theo từng UC.
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -22,7 +22,7 @@ Tách "thiết kế test case" (con người đọc/review được) khỏi "cod
|
|
|
22
22
|
|
|
23
23
|
**Input:** TEST_PLAN.md + skill `qa-designer` (chọn layer, nạp MỘT file).
|
|
24
24
|
|
|
25
|
-
**Output:** `{qc_dir}/{
|
|
25
|
+
**Output:** `{qc_dir}/{TICKET-ID}/{platform}/test-cases/*.Test.md` (trace mapping bắt buộc). Gọi theo **từng UC**, ghi vào thư mục test-case dùng chung cấp PRD.
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
@@ -1373,6 +1373,145 @@ Lăng kính này phân biệt được. Hiện **không ai làm**.
|
|
|
1373
1373
|
|
|
1374
1374
|
---
|
|
1375
1375
|
|
|
1376
|
+
# ✅ B11 — Gộp tài liệu QC về cấp PRD (thôi chia nhỏ theo từng UC)
|
|
1377
|
+
|
|
1378
|
+
**Việc này khởi từ một ảnh chụp thư mục.** Đội QC chạy trạm phân tích và nhận về một cây vỡ
|
|
1379
|
+
vụn: mỗi UC một thư mục gốc riêng — 10 UC là 10 thư mục, 30 file, cùng một tính năng.
|
|
1380
|
+
|
|
1381
|
+
## Điều làm tôi phải xem lại kết luận của chính mình
|
|
1382
|
+
|
|
1383
|
+
Câu hỏi ban đầu tôi hiểu là *"xếp lại thư mục cho gọn"*. Nó không phải. Nó là **đổi độ mịn của
|
|
1384
|
+
chính tài liệu**: một file gap cho cả tính năng, không phải một file mỗi UC.
|
|
1385
|
+
|
|
1386
|
+
Và khi đi kiểm, hoá ra **framework đang làm sai, không phải đội QC**. Ba bằng chứng độc lập,
|
|
1387
|
+
đều nằm sẵn trong repo từ trước:
|
|
1388
|
+
|
|
1389
|
+
| # | Bằng chứng | Nó nói gì |
|
|
1390
|
+
|---|---|---|
|
|
1391
|
+
| 1 | File thật của đội QC tên `DOC_GAP_FEAT-02-3.md` | Mã tính năng, **không có** hậu tố UC. Họ vốn làm ở cấp tính năng |
|
|
1392
|
+
| 2 | Mã gap trong template gốc là `GAP-<UC>-001` | Mã **mang tên UC** chỉ có nghĩa khi **một file chứa nhiều UC**. Trong file một-UC nó là thừa |
|
|
1393
|
+
| 3 | Kỹ năng lập kế hoạch test viết *"Test Plan cho một **feature**"*, khuôn là `# Test Plan – <Feature>` | Cấp tính năng, từ đầu |
|
|
1394
|
+
|
|
1395
|
+
Cả ba đều chỉ về cấp tính năng. **Việc chia nhỏ theo UC là framework tự áp vào lúc port** —
|
|
1396
|
+
không ai yêu cầu, và nó phá đúng cái mà mã `GAP-<UC>-…` được thiết kế để làm.
|
|
1397
|
+
|
|
1398
|
+
Thêm một chỗ bất nhất đã tồn tại: **sổ kết quả kiểm thử vốn đã gom theo tính năng**
|
|
1399
|
+
(`.trace/{domain}/{tính-năng}/…`). Nên trước B11, hai nơi cùng nói về một UC lại xếp theo hai
|
|
1400
|
+
kiểu khác nhau.
|
|
1401
|
+
|
|
1402
|
+
## Ba thứ đổi
|
|
1403
|
+
|
|
1404
|
+
```
|
|
1405
|
+
TRƯỚC SAU
|
|
1406
|
+
docs/FEAT-01-2-UC1/web/DOC_GAP.md docs/FEAT-01-2/web/DOC_GAP.md
|
|
1407
|
+
docs/FEAT-01-2-UC2/web/DOC_GAP.md ← UC1…UC5 chung một bảng,
|
|
1408
|
+
docs/FEAT-01-2-UC3/web/DOC_GAP.md phân biệt bằng cột "UC"
|
|
1409
|
+
docs/FEAT-01-2-UC4/web/DOC_GAP.md docs/FEAT-01-2/web/TEST_PLAN.md
|
|
1410
|
+
docs/FEAT-01-2-UC5/web/DOC_GAP.md docs/FEAT-01-2/web/REQUIREMENT_ANALYSIS.md
|
|
1411
|
+
(× 3 loại tài liệu = 15 file) (3 file)
|
|
1412
|
+
```
|
|
1413
|
+
|
|
1414
|
+
**Nền vẫn là một cấp thư mục — bắt buộc.** Một kịch bản `SC3` của web và `SC3` của app là hai
|
|
1415
|
+
thứ khác nhau, và sổ kết quả tách theo nền. Gộp nền lại là trộn hai bộ kịch bản.
|
|
1416
|
+
|
|
1417
|
+
## Chỗ tôi tưởng phải trả giá, mà hoá ra được lãi
|
|
1418
|
+
|
|
1419
|
+
Tôi tưởng gộp 5 UC vào một lần chạy sẽ tốn gấp 5 lần. **Ngược lại.**
|
|
1420
|
+
|
|
1421
|
+
Chạy từng UC thì tài liệu yêu cầu, bản thiết kế, tài liệu kỹ thuật **bị đọc lại mỗi lần** —
|
|
1422
|
+
5 UC là đọc 5 lượt cùng một tài liệu. Phần dùng chung chiếm đa số đầu vào; chỉ phần kịch bản
|
|
1423
|
+
test là riêng theo UC.
|
|
1424
|
+
|
|
1425
|
+
Và có lợi thêm về **chất**, không chỉ chi phí: **chỗ hai UC của cùng tính năng nói khác nhau**
|
|
1426
|
+
— UC1 một kiểu, UC3 kiểu khác — chỉ nhìn thấy được khi đọc cùng lúc. Chạy tách UC thì về
|
|
1427
|
+
**cấu trúc** là không thể thấy, không phải "khó thấy". Nên trạm phân tích giờ có thêm một mục
|
|
1428
|
+
bắt buộc: *"Mâu thuẫn chéo UC"*.
|
|
1429
|
+
|
|
1430
|
+
## Chỗ nguy hiểm — và vì sao nó đã được giải sẵn
|
|
1431
|
+
|
|
1432
|
+
Gộp nhiều UC vào một bảng thì mã gap có thể đè nhau. Nếu đánh số liền `GAP-01…GAP-60` thì
|
|
1433
|
+
**chạy lại UC1 sẽ đánh số lại toàn bộ UC2–UC5** — mà khoảng 15 kỹ năng đang ghi
|
|
1434
|
+
`🚫 Chặn bởi: GAP-xx` vào từng test case. Test case sẽ trỏ sang gap khác, **im lặng, không ai
|
|
1435
|
+
báo lỗi**.
|
|
1436
|
+
|
|
1437
|
+
Điểm hay: **template gốc đã giải sẵn** — mã của nó là `GAP-<UC>-001`, mang tên UC. Chạy lại UC1
|
|
1438
|
+
không đụng số của UC khác. B11 chỉ **định nghĩa rõ** thành `GAP-UC1-001`, và thêm `GAP-GEN-001`
|
|
1439
|
+
cho gap thuộc cả tính năng.
|
|
1440
|
+
|
|
1441
|
+
*(Kết quả đội QC chạy hôm trước ghi `GAP-01` phẳng — tức nó **không theo template**. Đó là một
|
|
1442
|
+
vấn đề khác, xem §Cố ý chưa làm.)*
|
|
1443
|
+
|
|
1444
|
+
## Một luật, một chỗ
|
|
1445
|
+
|
|
1446
|
+
Luật *"xác định tính năng nào, nền nào, những UC nào"* trước đây **bị chép ở 5 lệnh** và câu chữ
|
|
1447
|
+
đã lệch nhau. Năm bản của một luật là nơi lỗi sống: sửa bốn, quên một, và trạm bị quên ghi tài
|
|
1448
|
+
liệu vào sai thư mục **mà không báo gì**.
|
|
1449
|
+
|
|
1450
|
+
Giờ nó là **một file dùng chung**, cả 6 trạm cùng nạp. Đổi bố cục lần này buộc phải sửa cả 5
|
|
1451
|
+
bản dù sao — nên dồn về một chỗ là rẻ hơn, không đắt hơn.
|
|
1452
|
+
|
|
1453
|
+
## Trạm nào chạy cả tính năng, trạm nào vẫn theo UC
|
|
1454
|
+
|
|
1455
|
+
| Trạm | Phạm vi | Vì sao |
|
|
1456
|
+
|---|---|---|
|
|
1457
|
+
| Phân tích yêu cầu · Lập kế hoạch test | **cả tính năng × 1 nền** | Chúng sinh ra 3 tài liệu cần gộp |
|
|
1458
|
+
| Thiết kế test · Soát · Chạy test | **vẫn theo từng UC** | Thiết kế và chạy test **thật sự** làm tăng dần theo UC. Giữ được việc làm UC1 khi UC3 chưa xong là đúng — chỉ **chỗ đọc/ghi** đổi |
|
|
1459
|
+
| Sổ kết quả kiểm thử | **không đổi** | Mỗi hàng là một kịch bản; liên kết với bảng gap đi qua cột `UC` |
|
|
1460
|
+
|
|
1461
|
+
**Gap chặn theo từng UC, không chặn cả tính năng.** Một gap nghiêm trọng ở UC3 không có lý do
|
|
1462
|
+
gì dừng việc thiết kế test cho UC1.
|
|
1463
|
+
|
|
1464
|
+
## UC chưa duyệt: ghi "chưa xét", không im lặng bỏ
|
|
1465
|
+
|
|
1466
|
+
Trạm phân tích chỉ lấy UC có kịch bản test **đã duyệt**. UC còn nháp **vẫn có một hàng** trong
|
|
1467
|
+
bảng *Phạm vi phân tích*, đánh dấu `⏸ Chưa xét` kèm lý do.
|
|
1468
|
+
|
|
1469
|
+
> **Vì sao không bỏ khỏi bảng.** *"Chưa xét"* khác *"đã xét, không thấy gap"*. Bỏ khỏi bảng là
|
|
1470
|
+
> để hai chuyện đó trông giống nhau — và một UC bị bỏ sót sẽ trông như một UC sạch.
|
|
1471
|
+
|
|
1472
|
+
Giữ lại cờ `--include-draft` cho ai cố ý chạy sớm trên bản nháp. Cách dùng đó **vốn được cho
|
|
1473
|
+
phép** (cổng cũ là cảnh báo mềm, không phải chặn cứng); bỏ hẳn là lấy đi một năng lực đang có
|
|
1474
|
+
mà không ai khai.
|
|
1475
|
+
|
|
1476
|
+
## Dữ liệu cũ của đội QC: lưu trữ, không gộp tay
|
|
1477
|
+
|
|
1478
|
+
Gộp 5 thư mục về 1 thì tài liệu phân tích của UC1 và UC2 **đâm nhau ở cùng một đường dẫn** —
|
|
1479
|
+
không có cách gộp tự động hai tài liệu văn xuôi. Nên script `migrate-qc-docs.js` **không giả vờ
|
|
1480
|
+
gộp**:
|
|
1481
|
+
|
|
1482
|
+
| Loại | Xử lý |
|
|
1483
|
+
|---|---|
|
|
1484
|
+
| Test case | **dời** sang thư mục mới — tên file mang tên tính năng nên không đâm nhau |
|
|
1485
|
+
| 3 tài liệu cấp trên | **lưu trữ** vào `docs/_archive-per-uc/`, in danh sách cần sinh lại |
|
|
1486
|
+
| `DOC_GAPS.md` (tên cũ) | đổi thành `DOC_GAP.md` — trả luôn món nợ B9 còn treo |
|
|
1487
|
+
| File nằm ngoài mọi nền | **để nguyên + báo** — tài liệu QC không mang dấu nền nên không suy được |
|
|
1488
|
+
| Đích đã có file | **không ghi đè**, báo ra để người xử lý |
|
|
1489
|
+
|
|
1490
|
+
**Sinh lại tốt hơn gộp tay**, vì bản cấp tính năng thấy được mâu thuẫn chéo UC mà 5 bản rời
|
|
1491
|
+
không thấy. Không xoá gì — thư mục lưu trữ là đường lùi, và là **cách duy nhất** để đối chiếu
|
|
1492
|
+
xem bản mới có bắt thêm gap thật hay không.
|
|
1493
|
+
|
|
1494
|
+
## Đã kiểm chứng
|
|
1495
|
+
|
|
1496
|
+
| Phép kiểm | Kết quả |
|
|
1497
|
+
|---|---|
|
|
1498
|
+
| Dựng lại toàn bộ | 41/41 mẫu lệnh ✅ |
|
|
1499
|
+
| Bộ kiểm tra nội bộ (16 luật) | sạch ✅ |
|
|
1500
|
+
| Bộ test tự động | **199/199** ✅ (không tụt so với trước B11) |
|
|
1501
|
+
| Đường dẫn cũ còn sót trong mã | **0** (34 chỗ → 0) |
|
|
1502
|
+
| Luật dùng chung đã lan vào cả 6 trạm | ✅ đếm được trong bản đã đóng gói |
|
|
1503
|
+
| Script dời file — chạy thử trên cây giả lập 31 file | **31 → 31 file, không mất gì**; chạy lại lần hai không đổi gì thêm |
|
|
1504
|
+
| 5 ca biên của script (tên cũ · hai nền · file lạc · bố cục đã mới · đích bị chiếm) | đều xử lý đúng ✅ |
|
|
1505
|
+
|
|
1506
|
+
## Cố ý chưa làm — và vì sao để riêng
|
|
1507
|
+
|
|
1508
|
+
| Việc | Vì sao |
|
|
1509
|
+
|---|---|
|
|
1510
|
+
| **Máy kiểm cấu trúc file gap** | Đây mới là cách chữa thật cho bệnh *"không theo template"* (kết quả hôm trước ra 6 cột, dùng chữ `Major` — không theo template nào cả). Nhưng nó là **năng lực mới**, không phải đổi bố cục. Trộn vào thì sau này không biết cái nào chữa được bệnh gì. Làm sau khi có phép thử thật |
|
|
1511
|
+
| **`Blocker` ↔ `Critical`** | File thật của đội QC dùng `🔴 Critical`; framework đổi thành `Blocker` vì trạm chạy test đọc chữ đó. Nhìn kết quả hôm trước thì rõ là **đổi từ ngữ của họ làm tăng khả năng lệch, không giảm** — nhưng đó là quyết định riêng, một dòng, và cần bạn chốt |
|
|
1512
|
+
|
|
1513
|
+
---
|
|
1514
|
+
|
|
1376
1515
|
# Tổng kết
|
|
1377
1516
|
|
|
1378
1517
|
| | Quyết định ở B7 | Bằng chứng | |
|
|
@@ -1415,9 +1554,9 @@ rồi, giờ bắt nó **so** với hai tài liệu kia"*. Không nạp thêm fi
|
|
|
1415
1554
|
|
|
1416
1555
|
# Các bước còn lại
|
|
1417
1556
|
|
|
1418
|
-
**
|
|
1557
|
+
**Mười hai bước B0–B11 đã xong.** Không còn bước nào đang chờ quyết định để bắt đầu.
|
|
1419
1558
|
|
|
1420
|
-
Nhưng có **
|
|
1559
|
+
Nhưng có **hai việc chưa validate** và **bốn món nợ** — xem §Còn treo ở cuối.
|
|
1421
1560
|
Mô tả kế hoạch gốc nằm ở [`qc-merge-plan.md`](qc-merge-plan.md).
|
|
1422
1561
|
|
|
1423
1562
|
> **Nhật ký này chỉ ghi bước đã hoàn thành** — mỗi bước xong mới nạp vào đây, không viết trước.
|
|
@@ -1440,7 +1579,9 @@ Sau mỗi bước, toàn bộ hệ thống được dựng lại và kiểm tra
|
|
|
1440
1579
|
|
|
1441
1580
|
| # | Câu | Mức | Ai quyết |
|
|
1442
1581
|
|---|---|---|---|
|
|
1443
|
-
| **1** | Chạy thử trên một tính năng thật — **
|
|
1444
|
-
| **2** | Đưa nhật ký cho đội QC xem — họ là chủ sở hữu các kỹ năng này, và định dạng họ nhận đã đổi | 🟠 | bạn |
|
|
1582
|
+
| **1** | Chạy thử trên một tính năng thật — **mười hai bước, chưa một lần chạy**. Sau B11 phép thử này còn quan trọng hơn: nó là cách duy nhất biết bản cấp tính năng có bắt được mâu thuẫn chéo UC, và có theo đúng template hay không. Ước lượng chi phí của tôi đã sai 3 lần, đều ước thấp | 🔴 chưa validate | bạn (cần spec thật) |
|
|
1583
|
+
| **2** | Đưa nhật ký cho đội QC xem — họ là chủ sở hữu các kỹ năng này, và định dạng họ nhận đã đổi **hai lần** (B9 rồi B11) | 🟠 | bạn |
|
|
1584
|
+
| **2b** | **Máy kiểm cấu trúc file gap** — bệnh *"không theo template"* vẫn chưa có gì chặn bằng máy. Hiện chỉ có chỉ thị bằng văn xuôi, tức **cùng loại** với câu chỉ đường đã thất bại, chỉ mạnh hơn | 🟠 chưa chữa | bạn (sau khi chạy thử B11) |
|
|
1585
|
+
| **2c** | `Blocker` ↔ `Critical` — đổi trạm chạy test đọc `Critical` (một dòng) thay vì bắt đội QC đổi thói quen. Kết quả hôm trước cho thấy đổi từ ngữ của họ làm **tăng** khả năng lệch | 🟡 | bạn |
|
|
1445
1586
|
| 3 | 30 file không có bản gốc — framework tự sở hữu, gộp lại, hay ghép tay? | 🟡 nợ | bạn |
|
|
1446
1587
|
| 4 | Có lấy lại 38 dòng đã mất của phần "lập kế hoạch test" không? | 🟡 nợ | bạn |
|
|
@@ -149,7 +149,8 @@ mà bản đồ này tồn tại để chặn — và §5 để máy canh nó.
|
|
|
149
149
|
"adapt_rules": {
|
|
150
150
|
"path-placeholders": [
|
|
151
151
|
{ "from": "inputs/free-trial-spec/specs/", "to": "{paths.specs_dir}/" },
|
|
152
|
-
{ "from": "docs/<feature>/", "to": "{paths.qc_dir}/{
|
|
152
|
+
{ "from": "docs/<feature>/", "to": "{paths.qc_dir}/{TICKET-ID}/{active_platform}/",
|
|
153
|
+
"note": "sau B11 phép map này gần như đồng nhất — upstream vốn đã là cấp feature (`docs/<feature>/`); chỉ thêm một cấp nền" },
|
|
153
154
|
{ "from": "inputs/", "to": "{paths.specs_dir}/", "note": "khái niệm nguồn-evidence" }
|
|
154
155
|
],
|
|
155
156
|
"two-file-guard": { "kind": "append-block", "block": "…rào 'chỉ trả 2 file'…" },
|