@educa-corp/sdd-framework 0.9.5 → 0.9.7
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/bin/build.js +11 -1
- package/bin/lint-trace.js +397 -28
- package/bin/self-check.js +623 -16
- package/bin/trace-schema.json +3187 -1981
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/amend-prd.md +7 -1
- package/core/commands/debug.md +8 -2
- package/core/commands/define-product.md +38 -1
- package/core/commands/dev-gen-test.md +70 -2
- package/core/commands/dev-run-test.md +8 -2
- package/core/commands/dev-smoke-test.md +7 -1
- package/core/commands/extend-prd.md +7 -1
- package/core/commands/fix-bug.md +11 -5
- package/core/commands/generate-architecture.md +9 -1
- package/core/commands/generate-bdd.md +45 -5
- package/core/commands/generate-code.md +44 -5
- package/core/commands/generate-design-spec.md +7 -1
- package/core/commands/generate-prd.md +9 -1
- package/core/commands/generate-spec-manifest.md +7 -1
- package/core/commands/generate-tech-docs.md +44 -4
- package/core/commands/learn.md +7 -1
- package/core/commands/map-testids.md +96 -13
- package/core/commands/propose-scenario.md +7 -1
- package/core/commands/qc-analyze.md +516 -426
- package/core/commands/qc-automation-assess.md +356 -0
- package/core/commands/qc-design-script.md +400 -0
- package/core/commands/qc-design-test.md +482 -248
- package/core/commands/qc-plan.md +141 -94
- package/core/commands/qc-report.md +9 -3
- package/core/commands/{qc-review.md → qc-review-script.md} +172 -132
- package/core/commands/qc-review-testcase.md +409 -0
- package/core/commands/qc-run-manualtest.md +401 -0
- package/core/commands/{qc-run-test.md → qc-run-script.md} +200 -232
- package/core/commands/refine-prd.md +7 -1
- package/core/commands/report-bug.md +9 -3
- package/core/commands/review-code.md +9 -3
- package/core/commands/review-context.md +11 -3
- package/core/commands/review-tech-docs.md +11 -3
- package/core/commands/setup-ai-first.md +7 -1
- package/core/commands/validate-traces.md +27 -6
- package/core/modules/qc-playwright/stack-profile.yaml +1 -1
- package/core/rules/workflow.md +42 -2
- package/core/skills/qc/_shared/self-review-principles.md +2 -2
- package/core/skills/qc/qa-analyst/DOC_GAP.template.md +10 -2
- package/core/skills/qc/qa-analyst/spec-issue-reporter.md +1 -1
- package/core/skills/qc/qa-automation-assess/matrix.md +120 -0
- 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-designer/shared/duplicate-check-procedure.md +33 -5
- package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +34 -5
- package/core/skills/qc/qa-planner/test-plan.md +7 -0
- package/core/skills/qc/qa-reviewer/script/e2e.md +1 -1
- package/core/skills/qc/qa-reviewer/script/exploratory.md +1 -1
- package/core/skills/qc/qa-reviewer/script/functional.md +1 -1
- package/core/skills/qc/qa-reviewer/script/integration.md +1 -1
- package/core/skills/qc/qa-reviewer/script/non-functional.md +1 -1
- package/core/skills/qc/qa-reviewer/shared/review-file-template.md +3 -3
- package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/functional.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/integration.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
- package/core/skills/qc/qa-runner/e2e.md +2 -2
- package/core/skills/qc/qa-runner/functional/gui-feature.md +4 -4
- package/core/skills/qc/qa-runner/functional/gui-screen.md +4 -4
- package/core/skills/qc/qa-runner/integration.md +1 -1
- package/core/skills/qc/qa-runner/non-functional.md +1 -1
- package/core/steps/context-loader.md +1 -1
- package/core/steps/gate.md +7 -1
- package/core/steps/qc-scope.md +67 -11
- package/core/steps/qc-stamp.md +142 -0
- package/core/steps/report-footer.md +19 -10
- package/core/templates/tech-design.template.md +3 -3
- package/docs/01-getting-started/quickstart.md +4 -3
- package/docs/02-concepts/architecture.md +14 -0
- package/docs/02-concepts/glossary.md +8 -0
- package/docs/02-concepts/overview.md +3 -2
- package/docs/02-concepts/pipeline-steps/04-bdd.md +1 -1
- package/docs/02-concepts/pipeline-steps/05-tech-docs.md +21 -5
- package/docs/02-concepts/pipeline-steps/06-code.md +12 -2
- package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +65 -16
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +3 -3
- package/docs/02-concepts/pipeline-steps/README.md +4 -3
- package/docs/02-concepts/traceability.md +2 -2
- package/docs/03-guides/architect.md +2 -2
- package/docs/03-guides/developer.md +6 -3
- package/docs/03-guides/tester-qa.md +23 -10
- package/docs/04-reference/commands.md +9 -4
- package/docs/04-reference/trace-schema.md +5 -5
- package/docs/explain/07-generate-tech-docs.md +5 -3
- package/docs/explain/08-review-tech-docs.md +15 -3
- package/docs/explain/09-generate-code.md +30 -4
- package/docs/explain/10-review-code.md +1 -1
- package/docs/explain/11-map-testids.md +72 -70
- package/docs/explain/12-dev-gen-test.md +1 -1
- package/docs/explain/15-qc-analyze.md +14 -2
- package/docs/explain/16-qc-plan.md +5 -1
- package/docs/explain/17-qc-design-test.md +30 -7
- package/docs/explain/18-qc-review.md +43 -17
- package/docs/explain/19-qc-run-test.md +38 -12
- package/docs/explain/20-qc-report.md +8 -5
- package/docs/explain/23-fix-bug.md +2 -2
- package/docs/explain/README.md +6 -3
- package/docs/plans/qc-surgery/01-checklist.md +70 -17
- package/package.json +1 -1
|
@@ -5,7 +5,12 @@ ported_from: ui-automation-testing
|
|
|
5
5
|
upstream_path: skills/qa-tc-designer/shared/tc-metadata-format.md
|
|
6
6
|
upstream_sha: a31d66a7a8dab19cf821c9102a88282b09e16cb9
|
|
7
7
|
---
|
|
8
|
-
# TC Metadata Format
|
|
8
|
+
# TC Metadata Format
|
|
9
|
+
|
|
10
|
+
> **`Automatable` KHÔNG phải một field của `.Test.md`.** Quyết định *"TC này máy chạy được hay
|
|
11
|
+
> phải chạy tay"* sống ở **đúng một chỗ**: `{qc_artifact_dir}AUTOMATION_ASSESSMENT.md`, do
|
|
12
|
+
> `/qc-automation-assess` ghi. Đừng chép giá trị đó vào đây — hai nơi ghi cùng một quyết định
|
|
13
|
+
> thì một nơi sẽ lệch, và lúc đó không ai biết nơi nào đúng. (Chuẩn chung)
|
|
9
14
|
|
|
10
15
|
## ⚠️ Nguyên tắc format file TC (BẮT BUỘC — QC yêu cầu)
|
|
11
16
|
|
|
@@ -57,9 +62,14 @@ Mỗi trường 1 dòng, không bảng, không emoji dư:
|
|
|
57
62
|
- **Author:** AI
|
|
58
63
|
- **Tags:** <lane>, <loại: smoke|sanity|regression>, <feature-tag>
|
|
59
64
|
- **Trace:** BR-xx (ID gốc trong PRD/BDD ở `{paths.specs_dir}`)
|
|
65
|
+
- **@trace.verifies:** {UC-ID}-SC{N}
|
|
60
66
|
- **🚫 Block:** [GAP-UC{N}-{nnn}](../DOC_GAP.md) — <lý do> *(chỉ khi có)*
|
|
61
67
|
```
|
|
62
68
|
|
|
69
|
+
> **`@trace.verifies` là trường BẮT BUỘC, không phải tuỳ chọn** — §Trace dưới đây gọi nó là
|
|
70
|
+
> **join key**: thiếu nó thì kết quả chạy **không vào được sổ trace**. Nó từng vắng mặt ở hai khối
|
|
71
|
+
> mẫu này trong khi §Trace vẫn đòi nó — nên ai copy khối mẫu là bỏ sót đúng trường quan trọng nhất.
|
|
72
|
+
|
|
63
73
|
## Quy tắc Trace & Block
|
|
64
74
|
|
|
65
75
|
- **Trace:** ghi `BR-xx` lấy từ ID trong `{paths.specs_dir}`; không có BR → `⚠️ Chưa có Business Rule`.
|
|
@@ -76,6 +86,7 @@ Mỗi trường 1 dòng, không bảng, không emoji dư:
|
|
|
76
86
|
- **Author:** AI
|
|
77
87
|
- **Tags:** ...
|
|
78
88
|
- **Trace:** BR-xx
|
|
89
|
+
- **@trace.verifies:** {UC-ID}-SC{N}
|
|
79
90
|
- **🚫 Block:** (nếu có)
|
|
80
91
|
|
|
81
92
|
#### Preconditions
|
|
@@ -199,7 +210,7 @@ Mọi thứ trên là chuẩn của đội QC. Bốn thứ dưới đây là **c
|
|
|
199
210
|
**Câu hỏi phân file:** *"TC này verify được mà **không cần UI** không?"*
|
|
200
211
|
→ **có** = file API · **không** = file giao diện. *(Trùng Bước 2 của `skill-decision-tree.md`.)*
|
|
201
212
|
|
|
202
|
-
⚠️ **Đuôi file là `.Test.md`, không phải `.md`.** `/qc-
|
|
213
|
+
⚠️ **Đuôi file là `.Test.md`, không phải `.md`.** `/qc-design-script` và `/qc-review-testcase` tìm `*.Test.md`;
|
|
203
214
|
ghi ra file thiếu phần `.Test` là ghi ra thứ **không trạm nào tìm thấy**, và không có gì báo lỗi.
|
|
204
215
|
|
|
205
216
|
Đánh số `TC_<FEATURE>_NNN` **liên tục toàn file**, không đánh lại theo từng nhóm.
|
|
@@ -209,7 +220,7 @@ ghi ra file thiếu phần `.Test` là ghi ra thứ **không trạm nào tìm th
|
|
|
209
220
|
| Trường | Dạng | Vì sao cần |
|
|
210
221
|
|---|---|---|
|
|
211
222
|
| `**Trace:**` | `[BR-xx](../REQUIREMENT_ANALYSIS.md#3-business-rules)` — không có BR → `⚠️ Chưa có Business Rule` | truy về luật nghiệp vụ |
|
|
212
|
-
| `**@trace.verifies:**` | `{UC-ID}-SC{N}` (lấy từ `@trace.scenario` của file `.feature`) | **join key** để `/qc-run-
|
|
223
|
+
| `**@trace.verifies:**` | `{UC-ID}-SC{N}` (lấy từ `@trace.scenario` của file `.feature`) | **join key** để `/qc-run-script` ghi `qc_status` theo từng kịch bản vào sổ trace |
|
|
213
224
|
|
|
214
225
|
Một `SC` map được nhiều TC. **Thiếu `@trace.verifies` thì kết quả chạy không vào được sổ** — TC
|
|
215
226
|
vẫn chạy, vẫn pass/fail, nhưng không ai biết nó phủ kịch bản nào.
|
|
@@ -226,6 +237,24 @@ sách**, không bảng (§Nguyên tắc format file đầu tài liệu này).
|
|
|
226
237
|
`DOC_GAP.md` nằm ở **thư mục cha** của `test-cases/`, nên liên kết đi lên một cấp. Mã gap mang
|
|
227
238
|
UC (`GAP-UC1-001`) vì một file gap phủ cả PRD.
|
|
228
239
|
|
|
240
|
+
## Khối `Nguồn & phiên bản` *(metadata đầu file)*
|
|
241
|
+
|
|
242
|
+
Ghi ngay dưới dòng `Test-ID attribute`:
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
Nguồn & phiên bản: BDD {UC-ID} `<vX.Y>` · tech-doc `<rev | —>`
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Lấy `<vX.Y>` từ `| **Version** |` ở header `.feature` của **chính UC này**, và `<rev>` từ header
|
|
249
|
+
tech-doc gộp. `/qc-review-testcase` và `/qc-design-script` **so** khối này với version hiện tại để biết bộ TC còn
|
|
250
|
+
khớp spec không (`steps/qc-stamp.md` · `bin/trace-schema.json` → `qc_artifact_stamp`).
|
|
251
|
+
|
|
252
|
+
**Vì sao cần, khi sổ trace đã có `qc_status`.** `/generate-bdd` hạ `qc_status → not_run` khi spec đổi
|
|
253
|
+
— đó là *"**kết quả chạy** hết hiệu lực"*, và việc phải làm là **chạy lại**. Khối này trả lời câu
|
|
254
|
+
khác: *"**bộ TC** còn khớp không?"*, và việc phải làm là **viết lại**. Thiếu nó thì người ta thấy
|
|
255
|
+
`not_run` rồi chạy lại một bộ TC lỗi thời — ra `pass`, và `pass` đó **hợp lệ theo mọi phép kiểm hiện
|
|
256
|
+
có**.
|
|
257
|
+
|
|
229
258
|
## Dòng `Test-ID attribute`
|
|
230
259
|
|
|
231
260
|
Ghi một dòng ở phần metadata **đầu file**:
|
|
@@ -235,8 +264,8 @@ Test-ID attribute: {attr}
|
|
|
235
264
|
```
|
|
236
265
|
|
|
237
266
|
Đọc `@trace.testid_attr` từ header tech-doc gộp (do `/map-testids` ghi). Bảng §4.5.6 chỉ cho
|
|
238
|
-
**giá trị** test-id; đây là **tên thuộc tính** chứa chúng. `/qc-
|
|
239
|
-
locator, `/qc-review` cần nó để biết selector trong script có đúng hợp đồng không.
|
|
267
|
+
**giá trị** test-id; đây là **tên thuộc tính** chứa chúng. `/qc-design-script` cần nó để cấu hình
|
|
268
|
+
locator, `/qc-review-script` cần nó để biết selector trong script có đúng hợp đồng không.
|
|
240
269
|
|
|
241
270
|
Thiếu field trong tech-doc → ghi `Test-ID attribute: — (thiếu @trace.testid_attr, chạy /map-testids)`.
|
|
242
271
|
**Đừng bỏ trống và đừng tự đoán** — đoán sai thì mọi locator trượt 100%, và trượt vì lý do
|
|
@@ -72,6 +72,13 @@ Tổng hợp **output của qa-analyst** thành **Test Plan** cho một feature
|
|
|
72
72
|
| Người lập | qa-planner |
|
|
73
73
|
| Ngày / Phiên bản | … |
|
|
74
74
|
| Nguồn | REQUIREMENT_ANALYSIS · DOC_GAP |
|
|
75
|
+
| **Nguồn & phiên bản** | PRD `<vX.Y>` · tech-doc `<rev \| —>` · design-spec `<vX.Y \| —>` |
|
|
76
|
+
| **BDD theo UC** | `<UC-ID>` `<vX.Y>` · `<UC-ID>` `<vX.Y>` … |
|
|
77
|
+
|
|
78
|
+
> **Hai hàng cuối: CHÉP LẠI từ khối stamp của `DOC_GAP.md`, KHÔNG tự đi lấy từ spec.**
|
|
79
|
+
> Trạm này không đọc spec trực tiếp — đầu vào của nó là output trạm 1. Tự đi lấy là tạo **hai
|
|
80
|
+
> nguồn cho một số**, rồi chúng lệch nhau và không ai biết bên nào đúng.
|
|
81
|
+
> `/qc-design-test` so hai hàng này với version hiện tại (`steps/qc-stamp.md`).
|
|
75
82
|
|
|
76
83
|
## 1. Mục tiêu
|
|
77
84
|
Mục tiêu test của feature (1–3 câu).
|
|
@@ -92,4 +92,4 @@ Severity: 🔴 fix ngay (missing cleanup, dữ liệu không verify cross-module
|
|
|
92
92
|
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
93
93
|
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
94
94
|
|
|
95
|
-
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-
|
|
95
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-design-script`.
|
|
@@ -47,7 +47,7 @@ Review session note sau khi test, coaching QC cải thiện kỹ năng.
|
|
|
47
47
|
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
48
48
|
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
49
49
|
|
|
50
|
-
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-
|
|
50
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-design-script`.
|
|
51
51
|
Mỗi tiêu chí: ✅/⚠️/❌ + feedback cụ thể
|
|
52
52
|
Top 3 improvement suggestions (coaching tone)
|
|
53
53
|
Đề xuất charter tiếp theo nếu chưa đủ coverage
|
|
@@ -106,4 +106,4 @@ Severity: 🔴 fix ngay (sai logic, POM breach, silent fail) · 🟠 quan trọn
|
|
|
106
106
|
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
107
107
|
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
108
108
|
|
|
109
|
-
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-
|
|
109
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-design-script`.
|
|
@@ -96,4 +96,4 @@ Severity: 🔴 fix ngay (mock thay real call, missing DB verify, no cleanup) ·
|
|
|
96
96
|
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
97
97
|
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
98
98
|
|
|
99
|
-
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-
|
|
99
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-design-script`.
|
|
@@ -131,4 +131,4 @@ Severity: 🔴 fix ngay (assertion không có ngưỡng, gọi production endpoi
|
|
|
131
131
|
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
132
132
|
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
133
133
|
|
|
134
|
-
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-
|
|
134
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-design-script`.
|
|
@@ -31,7 +31,7 @@ upstream_sha: bd596393ecc016cbea106835681a4979c0a9ca0e
|
|
|
31
31
|
giữa tài-liệu-nền-cũ và PRD đã duyệt là **lệch đồng bộ, KHÔNG chặn** — không phải mâu thuẫn
|
|
32
32
|
chặn. *(Khung "gap thật = QA KHÔNG tự quyết được" — xem `steps/gap-verify.md`.)*
|
|
33
33
|
- **KHÔNG tự sửa** kịch bản hay code. Chỉ nhận xét, chấm điểm, và nêu cụ thể sửa gì. Người sửa là
|
|
34
|
-
trạm 3 (`/qc-design-test`) hoặc trạm 5 (`/qc-run-
|
|
34
|
+
trạm 3 (`/qc-design-test`) hoặc trạm 5 (`/qc-run-script`).
|
|
35
35
|
|
|
36
36
|
## Kiểm tra cấu trúc TC (bắt buộc mỗi vòng)
|
|
37
37
|
|
|
@@ -126,7 +126,7 @@ soát:
|
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
⚠️ **Tên file review KHÔNG có đuôi `.Test.md`.** Đuôi đó là của file test case; gắn vào file
|
|
129
|
-
review sẽ làm `/qc-
|
|
129
|
+
review sẽ làm `/qc-design-script` nhặt nó lên như một file test case rồi cố sinh script từ một bảng
|
|
130
130
|
điểm.
|
|
131
131
|
|
|
132
132
|
- **Chưa tồn tại** → `Write` toàn bộ khuôn bên dưới, điền hàng của tầng vừa soát, các tầng khác
|
|
@@ -147,7 +147,7 @@ review sẽ làm `/qc-run-test` nhặt nó lên như một file test case rồi
|
|
|
147
147
|
```markdown
|
|
148
148
|
# Review Report — <FEATURE>
|
|
149
149
|
|
|
150
|
-
> Sinh bởi /qc-review. Cập nhật sau mỗi vòng soát. Bảng Tổng quan tích luỹ theo vòng.
|
|
150
|
+
> Sinh bởi /qc-review-testcase hoặc /qc-review-script (mỗi vai một file). Cập nhật sau mỗi vòng soát. Bảng Tổng quan tích luỹ theo vòng.
|
|
151
151
|
|
|
152
152
|
## Tổng quan
|
|
153
153
|
|
|
@@ -12,7 +12,7 @@ Review bộ TC end-to-end và đánh giá chất lượng.
|
|
|
12
12
|
|
|
13
13
|
## Khi nào trigger
|
|
14
14
|
- "review TC E2E cho [Feature]" / "check coverage E2E"
|
|
15
|
-
- Sau khi qa-designer/e2e/journey xong, trước khi /qc-
|
|
15
|
+
- Sau khi qa-designer/e2e/journey xong, trước khi /qc-design-script
|
|
16
16
|
|
|
17
17
|
## Khi KHÔNG trigger
|
|
18
18
|
- Review TC functional 1 màn → `test-case/functional`
|
|
@@ -12,7 +12,7 @@ Review bộ functional TC và đánh giá chất lượng.
|
|
|
12
12
|
|
|
13
13
|
## Khi nào trigger
|
|
14
14
|
- "review TC cho [Feature]" / "check coverage"
|
|
15
|
-
- Sau khi qa-designer xong, trước khi PO approve hoặc trước khi /qc-
|
|
15
|
+
- Sau khi qa-designer xong, trước khi PO approve hoặc trước khi /qc-design-script
|
|
16
16
|
|
|
17
17
|
## Khi KHÔNG trigger
|
|
18
18
|
- Review Python script → dùng qa-reviewer
|
|
@@ -12,7 +12,7 @@ Review bộ TC tích hợp (GUI↔Backend, API, DB) và đánh giá chất lư
|
|
|
12
12
|
|
|
13
13
|
## Khi nào trigger
|
|
14
14
|
- "review TC integration cho [Feature]" / "check TC tích hợp"
|
|
15
|
-
- Sau khi qa-designer/integration/* xong, trước khi /qc-
|
|
15
|
+
- Sau khi qa-designer/integration/* xong, trước khi /qc-design-script
|
|
16
16
|
|
|
17
17
|
## Khi KHÔNG trigger
|
|
18
18
|
- Review TC functional 1 màn/endpoint → `test-case/functional`
|
|
@@ -12,7 +12,7 @@ Review bộ TC phi chức năng (performance, security, accessibility, compatibi
|
|
|
12
12
|
|
|
13
13
|
## Khi nào trigger
|
|
14
14
|
- "review TC non-functional cho [Feature]" / "check TC hiệu năng/bảo mật/accessibility"
|
|
15
|
-
- Sau khi qa-designer/non-functional xong, trước khi /qc-
|
|
15
|
+
- Sau khi qa-designer/non-functional xong, trước khi /qc-design-script
|
|
16
16
|
|
|
17
17
|
## Khi KHÔNG trigger
|
|
18
18
|
- Review TC chức năng → `test-case/functional`
|
|
@@ -30,7 +30,7 @@ Journey còn phụ thuộc gap → tạo test `@pytest.mark.skip(reason="GAP-UC{
|
|
|
30
30
|
|
|
31
31
|
## Phase 3 — Verify
|
|
32
32
|
`py_compile` + `pytest --collect-only -q` · chạy (môi trường staging + CRM) · cập nhật Status TC.
|
|
33
|
-
**Phân loại FAIL — 3 nhãn, luật ở `/qc-run-
|
|
33
|
+
**Phân loại FAIL — 3 nhãn, luật ở `/qc-run-script` §Chạy lại trước khi kết luận** (chạy lại ×2 trước, rồi người xác nhận; **không chép lại luật ở đây**). Đặc thù E2E: journey fail vì 1 bước feature chưa wire = `product-gap` (giữ FAIL/skip + bằng chứng), không phải lỗi script; sai selector/state → `script-bug`. Journey dài qua nhiều bước **dễ ra `flaky` hơn test đơn lẻ** — một bước chậm bất thường là đủ; nên đừng vội gọi `product-gap` khi chưa chạy lại.
|
|
34
34
|
|
|
35
35
|
## Output
|
|
36
36
|
Script `tests/<project>/e2e/test_<feature>.py` + Page Object/client tái dùng. Bàn giao `qa-reviewer`.
|
|
@@ -46,4 +46,4 @@ Report = **Playwright Trace viewer + pytest-html** (KHÔNG Allure, KHÔNG dashbo
|
|
|
46
46
|
- HTML report: `reports/<feature>/report.html` (self-contained, mở trực tiếp).
|
|
47
47
|
- Trace từng test (debug step-by-step): `python3 -m playwright show-trace test-results/<nodeid>/trace.zip`.
|
|
48
48
|
- Tóm tắt: **TOTAL / PASS / FAIL / SKIP** + duration.
|
|
49
|
-
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-
|
|
49
|
+
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-script` §Chạy lại trước khi kết luận, **không chép lại ở đây**; ghi mô tả lỗi tiếng Việt dễ hiểu vào Status/khối kết quả của `.Test.md`.
|
|
@@ -22,9 +22,9 @@ Skill **tự chứa**: convert `.Test.md` feature span ≥2 màn → Python pyte
|
|
|
22
22
|
|
|
23
23
|
## Phase 1 — Clarify
|
|
24
24
|
Đọc `.Test.md` · liệt kê các màn/PO cần · state truyền giữa màn · fixture dựng tiền điều kiện (data qua nhiều bước).
|
|
25
|
-
**Locator: đọc hợp đồng TRƯỚC, dò DOM là bước cuối.** Thứ tự bắt buộc (luật đầy đủ + lý do ở `/qc-
|
|
25
|
+
**Locator: đọc hợp đồng TRƯỚC, dò DOM là bước cuối.** Thứ tự bắt buộc (luật đầy đủ + lý do ở `/qc-design-script` §Role & stack — **không chép lại ở đây**):
|
|
26
26
|
|
|
27
|
-
1. **Test-id contract** — bảng *Test Selectors* §4.5.6 của tech-doc gộp, lọc theo cột "
|
|
27
|
+
1. **Test-id contract** — bảng *Test Selectors* §4.5.6 của tech-doc gộp, lọc theo cột "Serves SC" khớp SC của UC này. TÊN thuộc tính đọc từ `@trace.testid_attr` ở header tech-doc (đừng suy từ platform). Feature đa màn: một UC chạm nhiều màn nhưng **vẫn một bảng §4.5.6** cho cả platform — lọc theo SC, không theo màn.
|
|
28
28
|
2. **Role + accessible name** — cho element có action mà §4.5.6 chưa phủ.
|
|
29
29
|
3. **Dò DOM** — CHỈ khi 1 và 2 đều không định vị được. Dump class/`aria-label`/role, rồi nhìn kết quả:
|
|
30
30
|
- **3a. Element ĐÃ mang test-id trong code** → **DỪNG, đừng tự dùng id nhặt được.** Đây là ca *code đi trước hợp đồng*: chạy `/map-testids {UC-ID}` để đưa id đó vào §4.5.6 (nhánh `existing` — reverse-document), rồi quay lại bậc 1.
|
|
@@ -38,7 +38,7 @@ Phủ TC điều hướng forward/back/giữ-reset state. Data từ `test_data/`
|
|
|
38
38
|
## Phase 3 — Verify
|
|
39
39
|
`py_compile` + `pytest --collect-only -q` (**số collect = tổng TC**; thiếu → sinh nốt) · chạy · cập nhật Status TC (verify KHÔNG còn Draft) · in mapping.
|
|
40
40
|
**Gom nhóm role/account** tự áp qua `utils/test_ordering.py` (root conftest); fixture auth mới → `register_auth_fixtures([...])`. ⚠️ Run dài bị **WSL suspend** có thể gây flaky login/timeout → re-run TC đó + merge report.
|
|
41
|
-
**Phân loại FAIL — 3 nhãn, luật ở `/qc-run-
|
|
41
|
+
**Phân loại FAIL — 3 nhãn, luật ở `/qc-run-script` §Chạy lại trước khi kết luận** (chạy lại ×2 trước, rồi người xác nhận; **không chép lại ở đây**). Đặc thù đa màn: sai selector/logic → `script-bug`, sửa & chạy lại; feature chưa wire/defect **đỏ nhất quán** → `product-gap`, giữ FAIL + ghi bằng chứng vào khối "Kết quả thực thi" đầu `.Test.md`, không fake-pass. **State truyền giữa màn là nguồn `flaky` phổ biến** — điều hướng nhanh hơn/chậm hơn một nhịp là đủ đổi kết quả; ghi nghi vấn đó vào phần nguyên nhân.
|
|
42
42
|
|
|
43
43
|
## Output
|
|
44
44
|
Script + nhiều Page Object (mỗi màn) trong `pages/<project>/...`. Bàn giao `qa-reviewer` (script).
|
|
@@ -54,4 +54,4 @@ Report = **Playwright Trace viewer + pytest-html** (KHÔNG Allure, KHÔNG dashbo
|
|
|
54
54
|
- HTML report: `reports/<feature>/report.html` (self-contained, mở trực tiếp).
|
|
55
55
|
- Trace từng test (debug step-by-step): `python3 -m playwright show-trace test-results/<nodeid>/trace.zip`.
|
|
56
56
|
- Tóm tắt: **TOTAL / PASS / FAIL / SKIP** + duration.
|
|
57
|
-
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-
|
|
57
|
+
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-script` §Chạy lại trước khi kết luận, **không chép lại ở đây**; ghi mô tả lỗi tiếng Việt dễ hiểu vào Status/khối kết quả của `.Test.md`.
|
|
@@ -23,9 +23,9 @@ Skill **tự chứa**: convert `.Test.md` (1 màn) → Python pytest + Playwrigh
|
|
|
23
23
|
|
|
24
24
|
## Phase 1 — Clarify
|
|
25
25
|
Đọc `.Test.md` (confirm Reviewed) · platform (web Playwright/mobile) · Page Object đã có chưa → tạo nếu cần · fixture setup data?
|
|
26
|
-
**Locator: đọc hợp đồng TRƯỚC, dò DOM là bước cuối.** Thứ tự bắt buộc (luật đầy đủ + lý do ở `/qc-
|
|
26
|
+
**Locator: đọc hợp đồng TRƯỚC, dò DOM là bước cuối.** Thứ tự bắt buộc (luật đầy đủ + lý do ở `/qc-design-script` §Role & stack — **không chép lại ở đây**):
|
|
27
27
|
|
|
28
|
-
1. **Test-id contract** — bảng *Test Selectors* §4.5.6 của tech-doc gộp, lọc theo cột "
|
|
28
|
+
1. **Test-id contract** — bảng *Test Selectors* §4.5.6 của tech-doc gộp, lọc theo cột "Serves SC" khớp SC của UC này. TÊN thuộc tính đọc từ `@trace.testid_attr` ở header tech-doc (đừng suy từ platform).
|
|
29
29
|
2. **Role + accessible name** — cho element có action mà §4.5.6 chưa phủ.
|
|
30
30
|
3. **Dò DOM** — CHỈ khi 1 và 2 đều không định vị được. Dump class/`aria-label`/role bằng script tạm, rồi nhìn kết quả:
|
|
31
31
|
- **3a. Element ĐÃ mang test-id trong code** → **DỪNG, đừng tự dùng id nhặt được.** Đây là ca *code đi trước hợp đồng*: chạy `/map-testids {UC-ID}` để đưa id đó vào §4.5.6 (nhánh `existing` — reverse-document), rồi quay lại bậc 1. Dùng thẳng là bỏ qua review, và id đó không bao giờ thành hợp đồng — lần sau lại phải đi khám phá lại.
|
|
@@ -41,7 +41,7 @@ Map nhóm GUI→`TestFeatureUI`, Functional→`TestFeatureFunctional`, Negative
|
|
|
41
41
|
**Gom nhóm role/account**: thứ tự chạy đã tự gom cùng (role, account) liền nhau qua `utils/test_ordering.py` (hook ở root conftest) — fixture auth mới thì `register_auth_fixtures([...])`.
|
|
42
42
|
⚠️ Run dài có thể bị **WSL suspend** (máy ngủ) làm vài TC lỗi login/timeout = flaky (không phải gap SP) → re-run đúng các TC đó + merge vào report (xem `report/report.md`).
|
|
43
43
|
**Verify KHÔNG còn Draft**: `grep -c "Status: Draft" <file>.Test.md` = 0 trước khi bàn giao.
|
|
44
|
-
**Mỗi FAIL phân loại theo 3 nhãn — luật ở `/qc-run-
|
|
44
|
+
**Mỗi FAIL phân loại theo 3 nhãn — luật ở `/qc-run-script` §Chạy lại trước khi kết luận** (chạy lại ×2 trước, rồi người xác nhận; **không chép lại ở đây**). Đặc thù màn đơn: sai selector/expectation → `script-bug`, sửa script & chạy lại; feature không phản hồi sau timeout **và đỏ nhất quán qua các lần chạy lại** → `product-gap`, giữ FAIL + ghi bằng chứng (không fake-pass); timeout **chỉ xảy ra một số lần** → `flaky`, đừng ghi `fail`.
|
|
45
45
|
|
|
46
46
|
## Output
|
|
47
47
|
Script `tests/<project>/.../test_<screen>.py` + Page Object `pages/<project>/.../<Screen>Page.py` (nếu mới).
|
|
@@ -58,4 +58,4 @@ Report = **Playwright Trace viewer + pytest-html** (KHÔNG Allure, KHÔNG dashbo
|
|
|
58
58
|
- HTML report: `reports/<feature>/report.html` (self-contained, mở trực tiếp).
|
|
59
59
|
- Trace từng test (debug step-by-step): `python3 -m playwright show-trace test-results/<nodeid>/trace.zip`.
|
|
60
60
|
- Tóm tắt: **TOTAL / PASS / FAIL / SKIP** + duration.
|
|
61
|
-
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-
|
|
61
|
+
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-script` §Chạy lại trước khi kết luận, **không chép lại ở đây**; ghi mô tả lỗi tiếng Việt dễ hiểu vào Status/khối kết quả của `.Test.md`.
|
|
@@ -44,4 +44,4 @@ Report = **Playwright Trace viewer + pytest-html** (KHÔNG Allure, KHÔNG dashbo
|
|
|
44
44
|
- HTML report: `reports/<feature>/report.html` (self-contained, mở trực tiếp).
|
|
45
45
|
- Trace từng test (debug step-by-step): `python3 -m playwright show-trace test-results/<nodeid>/trace.zip`.
|
|
46
46
|
- Tóm tắt: **TOTAL / PASS / FAIL / SKIP** + duration.
|
|
47
|
-
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-
|
|
47
|
+
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-script` §Chạy lại trước khi kết luận, **không chép lại ở đây**; ghi mô tả lỗi tiếng Việt dễ hiểu vào Status/khối kết quả của `.Test.md`.
|
|
@@ -46,4 +46,4 @@ Report = **Playwright Trace viewer + pytest-html** (KHÔNG Allure, KHÔNG dashbo
|
|
|
46
46
|
- HTML report: `reports/<feature>/report.html` (self-contained, mở trực tiếp) + số đo thực tế.
|
|
47
47
|
- Trace từng test (debug step-by-step): `python3 -m playwright show-trace test-results/<nodeid>/trace.zip`.
|
|
48
48
|
- Tóm tắt: **TOTAL / PASS / FAIL / SKIP** + duration.
|
|
49
|
-
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-
|
|
49
|
+
3. TC Fail → mở trace tương ứng để xem timeline/DOM snapshot/network, phân loại theo **3 nhãn** (`script-bug` · `product-gap` · `flaky`) — luật đầy đủ + bước chạy lại ×2 ở `/qc-run-script` §Chạy lại trước khi kết luận, **không chép lại ở đây**; ghi mô tả lỗi tiếng Việt dễ hiểu + số đo vào Status/khối kết quả của `.Test.md`.
|
|
@@ -190,7 +190,7 @@ services:
|
|
|
190
190
|
- Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
|
|
191
191
|
- Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
|
|
192
192
|
- Override `paths.prd_change_requests_dir` → `{spec_source}/feedback/prd-change-requests`
|
|
193
|
-
- Override `paths.trace_dir` → `{spec_source}/.trace` — **luôn khi `spec_source` được đặt.** Trace TSV được gộp vào spec repo (một nơi authoritative duy nhất, không tách theo service) để PM/PO có một chỗ duy nhất quản lý trạng thái. Cấu trúc bên trong: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv`. Các lệnh phía code (`/generate-code`, `/dev-run-test`, `/qc-run-
|
|
193
|
+
- Override `paths.trace_dir` → `{spec_source}/.trace` — **luôn khi `spec_source` được đặt.** Trace TSV được gộp vào spec repo (một nơi authoritative duy nhất, không tách theo service) để PM/PO có một chỗ duy nhất quản lý trạng thái. Cấu trúc bên trong: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv`. Các lệnh phía code (`/generate-code`, `/dev-run-test`, `/qc-run-script`) chạy từ `service_root` nhưng **ghi trace row của chúng vào `{spec_source}/.trace/{domain}/{prd-slug}/`** — giống như chúng đã push `feedback/` vào đó. *(`.trace` theo service chỉ khi không có `spec_source`.)*
|
|
194
194
|
- Override `paths.refinement_dir` → `{spec_source}/.agent/review` — **luôn khi `spec_source` được đặt.** Findings review (`/refine-prd`, `/review-context`, `/review-tech-docs`) là artifact liên-team *về* tài liệu trong spec repo (PRD/BDD/tech-design) — thuộc cùng khu vực ghi với `.trace/` và `feedback/`. Các lệnh review chạy từ working dir của service (BE repo) nhưng **ghi findings vào `{spec_source}/.agent/review/`**, KHÔNG phải `.agent/review` của service repo. Bên trong flat, phân biệt bằng tên file đã prefix `{prd-slug}`/`{UC-ID}`/`{TICKET-ID}`. *(`.agent/review` theo service chỉ khi không có `spec_source`.)*
|
|
195
195
|
|
|
196
196
|
> **Vì sao đặt dưới `spec_source`:** PRD, BDD, tech-docs, design-spec, domain knowledge, feedback của tester, **trạng thái coverage `.trace/`**, **và findings review `.agent/review/`** đều là **artifact liên team** — chúng nằm trong **spec repo dùng chung** theo bố cục feature-package để mọi umbrella (FE/App/BE) và PM đọc từ một nguồn qua `/sync`. Trong bố cục feature-package, một folder `specs/{domain}/{prd-slug}/` gom tất cả loại artifact của một PRD, giúp spec repo tự đủ và dễ điều hướng theo feature. Service submodule chỉ chứa **code** (+ tooling build/test). `.trace/`, `.agent/review/` và `feedback/` là khu vực **ghi** của dev/QC/reviewer trong spec repo. Ở chế độ single-service (không có `spec_source`), mọi thứ mặc định dưới gốc repo — vẫn là một repo.
|
package/core/steps/gate.md
CHANGED
|
@@ -77,7 +77,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
|
|
|
77
77
|
|
|
78
78
|
| Mức | Lệnh nào | `--yes` bỏ qua được? |
|
|
79
79
|
|---|---|:---:|
|
|
80
|
-
| **Không chặn** |
|
|
80
|
+
| **Không chặn** | `/review-code` · `/validate-traces` · `/debug` — **KHÔNG phải vì read-only**: cả ba đều CÓ ghi file. Chúng không chặn vì thao tác ghi của chúng hoặc nằm sau một câu hỏi `(Y/N)`, hoặc nằm sau một cờ, hoặc là `append`/dựng-lại-được | — (vốn không có) |
|
|
81
81
|
| **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
|
|
82
82
|
| **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
|
|
83
83
|
|
|
@@ -85,6 +85,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
|
|
|
85
85
|
`--` khỏi phần resolve target, nên cờ này không ảnh hưởng việc tìm file.) Mở đường chạy
|
|
86
86
|
headless: `claude -p "/generate-code UC1 --yes"`.
|
|
87
87
|
|
|
88
|
+
> **Tên lệnh trong bảng trên có máy canh — `R19`.** Mỗi hàng bảng vừa nêu một mức vừa nêu
|
|
89
|
+
> tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
|
|
90
|
+
> ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
|
|
91
|
+
> mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
|
|
92
|
+
> `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
|
|
93
|
+
|
|
88
94
|
> **KHÔNG tự suy mức từ bảng này.** Mỗi lệnh **tự khai** mức của nó ở một dòng `*Checkpoint: …*`
|
|
89
95
|
> ngay dưới `## Gate` của chính nó — đọc dòng đó, đừng suy diễn. Bảng trên chỉ giải thích ba mức
|
|
90
96
|
> **nghĩa là gì**.
|
package/core/steps/qc-scope.md
CHANGED
|
@@ -99,21 +99,77 @@ Phạm vi QC — {TICKET-ID} / {active_platform}
|
|
|
99
99
|
→ {n} UC trong phạm vi · {m} chưa xét
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
**Cờ `--
|
|
103
|
-
trong artifact là dựa trên BDD nháp.
|
|
102
|
+
**Cờ `--force`:** xử lý cả UC chưa duyệt, nhưng **vẫn in bảng trên**, in dòng khai đã bỏ qua gì,
|
|
103
|
+
và đánh dấu trong artifact là dựa trên BDD nháp. *(Tên cờ chung cho mọi chỗ "biết mà vẫn chạy" —
|
|
104
|
+
`rules/workflow.md` §Cờ bỏ qua điều kiện. Cờ cũ `--include-draft` đã bỏ, không có alias.)*
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
### 4a — Cổng cấp PRD: có việc để làm không?
|
|
107
|
+
|
|
108
|
+
**Không UC nào `approved` và không có `--force` → DỪNG:**
|
|
106
109
|
```
|
|
107
110
|
❌ {TICKET-ID} ({active_platform}): 0/{n} UC có BDD approved — không có gì để chạy.
|
|
108
111
|
Cách đúng: người duyệt đặt `# @trace.status: approved` rồi chạy lại.
|
|
109
|
-
Muốn chạy sớm trên BDD nháp (prototype): thêm --
|
|
112
|
+
Muốn chạy sớm trên BDD nháp (prototype): thêm --force
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 4b — Cổng cấp UC: **cái UC vừa được gọi tên** có làm được không?
|
|
116
|
+
|
|
117
|
+
Bảy lệnh nhận target là **UC-ID** — `/qc-design-test` · `/qc-review-testcase` · `/qc-review-script` · `/qc-design-script` · `/qc-run-script` · `/qc-run-manualtest` · `/qc-report`
|
|
118
|
+
— phải đối chiếu target với **bảng vừa in ở trên**. Hai lệnh cấp PRD (`/qc-analyze` · `/qc-plan`)
|
|
119
|
+
**bỏ qua mục này**: target của chúng là `TICKET-ID`, và cổng 4a đã trả lời đúng câu hỏi của chúng.
|
|
120
|
+
|
|
121
|
+
| Target | Xử lý |
|
|
122
|
+
|---|---|
|
|
123
|
+
| Có trong `uc_list`, nhóm **Trong phạm vi** | đi tiếp |
|
|
124
|
+
| Có trong `uc_list`, nhóm **⏸ Chưa xét** | **DỪNG** — trừ khi có `--force` |
|
|
125
|
+
| **Không** có trong `uc_list` | **DỪNG** — sai UC-ID hoặc sai nền. **`--force` KHÔNG qua được** |
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
❌ {UC-ID} có BDD `{status}` — chưa approved, không nằm trong phạm vi QC pass này.
|
|
129
|
+
Cách đúng: người duyệt đặt `# @trace.status: approved` rồi chạy lại.
|
|
130
|
+
Cố ý làm sớm trên BDD nháp: thêm --force (artifact sẽ ghi rõ nó dựa trên bản nháp)
|
|
110
131
|
```
|
|
132
|
+
```
|
|
133
|
+
❌ {UC-ID} không có trong {TICKET-ID} ({active_platform}).
|
|
134
|
+
UC có mặt: {danh sách uc_list}
|
|
135
|
+
Kiểm lại UC-ID, hoặc UC này thuộc nền khác — nêu nền tường minh.
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
> **Vì sao 4a không thay được 4b.** Điều kiện của 4a là **`0/n`** — *"cả PRD không có gì để chạy"*,
|
|
139
|
+
> đúng câu hỏi của một lệnh **cấp PRD**. Lệnh **cấp UC** hỏi câu khác hẳn. Với PRD `UC1 draft` +
|
|
140
|
+
> `UC2 approved`, cổng 4a thấy `1/2` → không phải `0/n` → **mở cửa**, và `/qc-design-test {UC1}`
|
|
141
|
+
> đi thẳng vào một spec chưa ai duyệt.
|
|
142
|
+
>
|
|
143
|
+
> Cái giá không dừng ở "thiết kế trên bản nháp". `Guard SC coverage` của trạm 3 sẽ **khẳng định**
|
|
144
|
+
> `khớp K/K` trên spec chưa duyệt, và `/qc-run-script` sẽ ghi `qc_status = pass` **chính thức** vào sổ
|
|
145
|
+
> trace cho nó. Đó là **báo cáo sai** — `rules/workflow.md` §*"ai KHẲNG ĐỊNH một giá trị dương phải
|
|
146
|
+
> được phép khẳng định"*.
|
|
147
|
+
>
|
|
148
|
+
> **Vì sao gộp luôn ca "UC-ID không có trong `uc_list`".** Cùng **một** phép so (`target ∈ nhóm
|
|
149
|
+
> Trong phạm vi`), và ca đó hiện **không ai bắt**: §1 đối chiếu `TICKET-ID` với tên file PRD thật và
|
|
150
|
+
> DỪNG nếu lệch, nhưng không có bước tương đương cho `UC-ID`. Gõ `/qc-design-test FT-001-UC7` khi PRD
|
|
151
|
+
> chỉ có UC1–UC3 thì không bước nào phát hiện.
|
|
152
|
+
|
|
153
|
+
### Có `--force` thì artifact phải TỰ KHAI
|
|
154
|
+
|
|
155
|
+
In dòng khai ở report:
|
|
156
|
+
```
|
|
157
|
+
⚠️ --force: bỏ qua {điều kiện} — {UC-ID} @trace.status: {status}
|
|
158
|
+
```
|
|
159
|
+
Và **mọi** file ghi ra trong lần chạy đó mang một dòng ở metadata:
|
|
160
|
+
```
|
|
161
|
+
⚠️ Dựa trên BDD NHÁP ({UC-ID} @trace.status: {status}) — spec có thể đổi.
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
> **Vì sao cả hai chỗ.** Cờ nằm ở dòng lệnh thì **biến mất** sau khi lệnh chạy xong. Dòng ở report
|
|
165
|
+
> cho người đang ngồi đó; dòng trong file đi cùng file tới người đọc sau — người sẽ mở `.Test.md`
|
|
166
|
+
> ba tuần nữa và không có cách nào biết nó sinh ra từ bản nháp.
|
|
111
167
|
|
|
112
|
-
> **Vì sao có `--
|
|
113
|
-
>
|
|
114
|
-
>
|
|
115
|
-
>
|
|
168
|
+
> **Vì sao có `--force` chứ không chặn cứng.** QC sớm trên BDD nháp là một cách dùng **cố ý được
|
|
169
|
+
> cho phép** từ trước (guard cũ là cảnh báo mềm, không phải chặn). Bỏ hẳn nó là lấy đi một năng lực
|
|
170
|
+
> đang có mà không ai khai. Còn để mặc định `approved`-only thì cái thường gặp là cái an toàn, và
|
|
171
|
+
> cái sớm phải nói ra.
|
|
116
172
|
|
|
117
|
-
> **Vì sao `--yes` không thay được `--
|
|
118
|
-
>
|
|
119
|
-
>
|
|
173
|
+
> **Vì sao `--yes` không thay được `--force`.** `--yes` nghĩa *"tôi không ngồi đây để trả lời"*;
|
|
174
|
+
> `--force` nghĩa *"tôi biết BDD còn nháp và vẫn muốn chạy"*. Gộp hai cái là để một lần chạy headless
|
|
175
|
+
> âm thầm phân tích spec chưa chốt rồi bàn giao như thể đã chốt.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# QC artifact stamp — ghi mình sinh ra từ bản nào, và đọc cái người trước đã ghi
|
|
2
|
+
|
|
3
|
+
> Nguồn máy đọc: `bin/trace-schema.json` → `qc_artifact_stamp`. Đổi contract thì **sửa schema TRƯỚC**.
|
|
4
|
+
>
|
|
5
|
+
> **Hai vế, không tách.** Vế ghi (đóng dấu) và vế đọc (so dấu) phải cùng có mặt. Chỉ ghi mà không
|
|
6
|
+
> ai đọc là nhân thêm một con số vô dụng — `DOC_GAP.template.md` đã có sẵn cột `Phiên bản` như thế:
|
|
7
|
+
> được điền mỗi lần chạy, **0 consumer**.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Vì sao tầng artifact QC cần cái này
|
|
12
|
+
|
|
13
|
+
`/generate-bdd` hạ `qc_status → not_run` khi spec đổi — đúng luật, và nó trả lời câu *"**kết quả chạy**
|
|
14
|
+
còn hiệu lực không?"*.
|
|
15
|
+
|
|
16
|
+
Câu chưa ai trả lời là *"**tài liệu thiết kế test** còn khớp không?"*. Hai câu dẫn tới hai việc khác nhau:
|
|
17
|
+
|
|
18
|
+
| Tín hiệu | Nghĩa | Việc phải làm |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `qc_status = not_run` | kết quả cũ hết hiệu lực | **chạy lại** `/qc-run-script` |
|
|
21
|
+
| **stamp lệch** | TC/gap/plan mô tả spec cũ | **viết lại** — `/qc-analyze` hoặc `/qc-design-test` |
|
|
22
|
+
|
|
23
|
+
Thiếu vế sau thì người ta thấy `not_run` và **chạy lại** — đúng phản xạ, sai việc. Một bộ TC lỗi thời
|
|
24
|
+
chạy xanh ra `pass`, và `pass` đó **hợp lệ theo mọi phép kiểm hiện có**.
|
|
25
|
+
|
|
26
|
+
> **Vì sao phép kiểm nằm ở đây chứ không ở `/validate-traces`.** `qc_dir` là path QC **duy nhất
|
|
27
|
+
> không được remap** khi `setup.spec_source` được đặt — `specs_dir`, `tech_docs_dir`,
|
|
28
|
+
> `domain_knowledge_dir`, `trace_dir` đều remap, `qc_dir` ở lại `docs` của **repo QC**. Nên ở chế độ
|
|
29
|
+
> umbrella (`trace-mirror.md` gọi là *"trường hợp phổ biến"*), sổ trace và artifact QC nằm ở **hai
|
|
30
|
+
> repo khác nhau** và `/validate-traces` không với tới artifact QC.
|
|
31
|
+
>
|
|
32
|
+
> Các trạm QC thì **đã đọc cả hai** — artifact từ `{qc_artifact_dir}`, spec từ `{paths.specs_dir}`.
|
|
33
|
+
> Phép so nằm trong tầm với, không phải vượt repo.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1 — Khối stamp: ghi gì, ở đâu
|
|
38
|
+
|
|
39
|
+
Đặt ở **bảng metadata đầu file** (cả bốn artifact đều đã có bảng đó — đây là **thêm hàng**, không
|
|
40
|
+
phải dựng cấu trúc mới):
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
| Nguồn & phiên bản | PRD `<vX.Y>` · tech-doc `<rev>` · design-spec `<vX.Y \| —>` |
|
|
44
|
+
| BDD theo UC | `<UC-ID>` `<vX.Y>` · `<UC-ID>` `<vX.Y>` … |
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Lấy từng giá trị ở ĐÂU** — mỗi nguồn một định dạng khác nhau, đừng suy từ cái này sang cái kia:
|
|
48
|
+
|
|
49
|
+
| Giá trị | Lấy từ | Định dạng |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `prd_version` | `\| **Version** \|` — bảng metadata đầu PRD | Markdown |
|
|
52
|
+
| **`bdd_version`** | **`@trace.bdd_version`** — header `.feature` | **Gherkin** — khối comment `# @trace.*`, **KHÔNG có bảng** |
|
|
53
|
+
| `tech_doc_revision` | `@trace.revision` — header tech-doc gộp | khối `@trace` |
|
|
54
|
+
| `design_spec_version` | `\| **Version** \|` — bảng metadata đầu design-spec | Markdown |
|
|
55
|
+
| `testid_attr` | `@trace.testid_attr` — header tech-doc | khối `@trace` |
|
|
56
|
+
|
|
57
|
+
> **Vì sao bảng này tồn tại** *(G85)*. Bản trước mô tả cả bốn nguồn bằng **một khuôn** —
|
|
58
|
+
> *"`| **Version** |` của header …"* — vì cả bốn "đều là tài liệu có metadata đầu file". Ba đúng,
|
|
59
|
+
> **một không thể đúng**: `.feature` là **Gherkin**, không có bảng Markdown nào. Đo thật: **0/278**
|
|
60
|
+
> file có dạng cũ, **276/278** có `@trace.bdd_version`.
|
|
61
|
+
>
|
|
62
|
+
> *Một khuôn cho N nguồn chỉ đúng khi N nguồn **cùng định dạng**. "Đều có metadata đầu file" không đủ.*
|
|
63
|
+
|
|
64
|
+
**Nguồn THIẾU → ghi `—` VÀ nói ra.** Đo thật: 2/278 `.feature` không có `@trace.bdd_version`.
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
⚠️ {UC-ID}: .feature thiếu @trace.bdd_version — stamp ghi '—', không so được ở trạm sau.
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Đừng bỏ trống, đừng đoán.** Bỏ trống im lặng thì *"không lấy được"* trông **y hệt** *"artifact cũ
|
|
71
|
+
chưa có stamp"* — mà §2 bảo **đừng báo lệch** ở ca đó. Điều khoản tương thích ngược sẽ **nuốt luôn**
|
|
72
|
+
lỗi này. *(Cùng khuôn `@trace.testid_attr` của `/qc-design-test` đã dùng.)*
|
|
73
|
+
|
|
74
|
+
| Artifact | Ai ghi | Stamp gì |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `REQUIREMENT_ANALYSIS.md` · `DOC_GAP.md` | `/qc-analyze` | `prd_version` · `bdd_version` **theo từng UC** · `tech_doc_revision` · `design_spec_version` |
|
|
77
|
+
| `TEST_PLAN.md` | `/qc-plan` | **chép lại** stamp của `DOC_GAP.md` |
|
|
78
|
+
| `test-cases/*.Test.md` | `/qc-design-test` | `bdd_version` của UC này · `tech_doc_revision` · `@trace.testid_attr` |
|
|
79
|
+
|
|
80
|
+
**`bdd_version` phải theo TỪNG UC.** `DOC_GAP.md` và `REQUIREMENT_ANALYSIS.md` phủ **cả PRD**, mà mỗi
|
|
81
|
+
UC là một file `.feature` riêng với version riêng — một số duy nhất cho cả file sẽ **sai cho `n−1` UC**.
|
|
82
|
+
|
|
83
|
+
**`/qc-plan` CHÉP LẠI, không tự đi lấy.** Nó không đọc spec trực tiếp (đầu vào của nó là output trạm 1).
|
|
84
|
+
Tự đi lấy là tạo **hai nguồn cho một số**, rồi chúng lệch nhau — và lúc đó không ai biết bên nào đúng.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 2 — Phép so: đọc dấu người trước đã ghi
|
|
89
|
+
|
|
90
|
+
Chạy **ngay sau guard tiền đề** (phần "có file không?"), trước mọi việc khác. Guard tiền đề hỏi
|
|
91
|
+
*"có không?"*; bước này hỏi *"còn khớp không?"*.
|
|
92
|
+
|
|
93
|
+
Với mỗi artifact mà lệnh này đọc:
|
|
94
|
+
|
|
95
|
+
1. Đọc khối stamp của nó.
|
|
96
|
+
2. Đọc version **hiện tại** của các nguồn tương ứng (`.feature` của UC · PRD · tech-doc · design-spec).
|
|
97
|
+
3. So từng cặp.
|
|
98
|
+
|
|
99
|
+
| Kết quả | Xử lý |
|
|
100
|
+
|---|---|
|
|
101
|
+
| Khớp hết | **im lặng, đi tiếp** |
|
|
102
|
+
| **Không có khối stamp** | `⚠️ {file}: chưa có stamp (sinh trước G63) — chạy lại {lệnh} để đóng dấu.` **KHÔNG báo lệch** |
|
|
103
|
+
| Lệch | theo bảng mức dưới đây |
|
|
104
|
+
|
|
105
|
+
> **Điều khoản tương thích ngược là bắt buộc, không phải lịch sự.** Artifact sinh ra trước khi có
|
|
106
|
+
> contract này thì đương nhiên không có stamp. Báo "lệch" ở đó là **bắt oan mọi dự án đang chạy ngay
|
|
107
|
+
> ngày nâng version** — và việc đầu tiên người ta làm là tìm cách tắt cảnh báo. Cùng điều khoản mà
|
|
108
|
+
> `testid_contract` đã dùng: *"doc không có block §4.5 client thì KHÔNG kiểm gì"*.
|
|
109
|
+
|
|
110
|
+
### Mức phản ứng — KHÔNG đồng nhất
|
|
111
|
+
|
|
112
|
+
| Trạm | Lệch thì | Vì sao |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `/qc-plan` · `/qc-design-test` · `/qc-review-testcase` | **⚠️ cảnh báo, đi tiếp** | Cùng họ `TECHDOC_DRIFT`/`BDD_DRIFT` — 13/17 cờ audit không chặn. Thiết kế TC trên bản hơi cũ vẫn ra sản phẩm dùng được; chặn ở đây là **ồn** |
|
|
115
|
+
| `/qc-run-script` | **chặn `pass`, KHÔNG chặn chạy** | Lớp **báo cáo sai** |
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
⚠️ Stamp lệch — {file} dựng trên {nguồn} {ver_cũ}, hiện tại {ver_mới}.
|
|
119
|
+
UC ảnh hưởng: {danh sách}
|
|
120
|
+
Nên chạy lại: {lệnh} (đi tiếp vẫn được, nhưng {hệ quả cụ thể})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**`/qc-run-script` — nhập vào cơ chế đã có, không phát minh cơ chế mới.** Stamp lệch xử lý **y hệt**
|
|
124
|
+
row `DRIFT`/`ORPHANED` của `positive_assertion_guards` + lint **T12** (G55): test vẫn chạy, nhưng
|
|
125
|
+
xanh → ghi `not_run` chứ **không** ghi `pass`, và **không đóng bug nào** ở lần chạy đó.
|
|
126
|
+
|
|
127
|
+
> **`fail` vẫn ghi `fail` bình thường.** Đây là guard chống **báo cáo sai**, không phải guard **che
|
|
128
|
+
> tin xấu** — nguyên văn lập luận của `positive_assertion_guards`.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 3 — Phép so đi theo từng UC, không theo cả file
|
|
133
|
+
|
|
134
|
+
Bump `bdd_version` của **UC2** thì `/qc-design-test {UC1}` phải **im lặng hoàn toàn**.
|
|
135
|
+
|
|
136
|
+
Trạm 3–5 chạy **per-UC**, nhiều lần cho mỗi PRD. Một cảnh báo báo oan ở đây không chỉ sai một lần —
|
|
137
|
+
nó lặp lại mỗi lần chạy, và cảnh báo lặp mà không đúng là cách nhanh nhất để người ta ngừng đọc **mọi**
|
|
138
|
+
cảnh báo của lệnh này.
|
|
139
|
+
|
|
140
|
+
Nên khi so `DOC_GAP.md` / `REQUIREMENT_ANALYSIS.md` (phủ cả PRD): **chỉ lấy hàng `bdd_version` của UC
|
|
141
|
+
đang chạy** để so. `prd_version` / `tech_doc_revision` / `design_spec_version` là số chung cả PRD nên
|
|
142
|
+
so trực tiếp.
|