@educa-corp/sdd-framework 0.9.6 → 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/lint-trace.js +4 -4
- package/bin/self-check.js +448 -12
- package/bin/trace-schema.json +643 -112
- 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 +9 -3
- 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 +43 -4
- 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 +41 -1
- package/core/commands/learn.md +7 -1
- package/core/commands/map-testids.md +11 -5
- package/core/commands/propose-scenario.md +7 -1
- package/core/commands/qc-analyze.md +12 -6
- 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 +21 -15
- package/core/commands/qc-plan.md +9 -3
- package/core/commands/qc-report.md +9 -3
- package/core/commands/qc-review-script.md +333 -0
- package/core/commands/{qc-review.md → qc-review-testcase.md} +84 -53
- package/core/commands/qc-run-manualtest.md +401 -0
- package/core/commands/qc-run-script.md +414 -0
- 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 +10 -4
- package/core/modules/qc-playwright/stack-profile.yaml +1 -1
- package/core/rules/workflow.md +2 -2
- package/core/skills/qc/_shared/self-review-principles.md +2 -2
- package/core/skills/qc/qa-analyst/DOC_GAP.template.md +1 -1
- 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/tc-metadata-format.md +11 -6
- 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 +3 -3
- package/core/skills/qc/qa-runner/functional/gui-screen.md +3 -3
- 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 +2 -2
- package/core/steps/qc-stamp.md +4 -4
- package/core/steps/report-footer.md +10 -9
- package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +9 -8
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +3 -3
- package/docs/02-concepts/traceability.md +1 -1
- package/docs/03-guides/developer.md +1 -1
- package/docs/03-guides/tester-qa.md +8 -7
- package/docs/04-reference/commands.md +4 -2
- package/docs/04-reference/trace-schema.md +4 -4
- package/docs/explain/17-qc-design-test.md +5 -5
- package/docs/explain/18-qc-review.md +42 -20
- package/docs/explain/19-qc-run-test.md +9 -6
- package/docs/explain/20-qc-report.md +3 -3
- package/docs/explain/23-fix-bug.md +2 -2
- package/docs/explain/README.md +2 -2
- package/docs/plans/qc-surgery/01-checklist.md +70 -17
- package/package.json +1 -1
- package/core/commands/qc-run-test.md +0 -561
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
|
@@ -114,7 +114,7 @@ và đánh dấu trong artifact là dựa trên BDD nháp. *(Tên cờ chung cho
|
|
|
114
114
|
|
|
115
115
|
### 4b — Cổng cấp UC: **cái UC vừa được gọi tên** có làm được không?
|
|
116
116
|
|
|
117
|
-
|
|
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
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
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
120
|
|
|
@@ -141,7 +141,7 @@ Bốn lệnh nhận target là **UC-ID** — `/qc-design-test` · `/qc-review`
|
|
|
141
141
|
> đi thẳng vào một spec chưa ai duyệt.
|
|
142
142
|
>
|
|
143
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-
|
|
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
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
146
|
> được phép khẳng định"*.
|
|
147
147
|
>
|
package/core/steps/qc-stamp.md
CHANGED
|
@@ -17,7 +17,7 @@ Câu chưa ai trả lời là *"**tài liệu thiết kế test** còn khớp kh
|
|
|
17
17
|
|
|
18
18
|
| Tín hiệu | Nghĩa | Việc phải làm |
|
|
19
19
|
|---|---|---|
|
|
20
|
-
| `qc_status = not_run` | kết quả cũ hết hiệu lực | **chạy lại** `/qc-run-
|
|
20
|
+
| `qc_status = not_run` | kết quả cũ hết hiệu lực | **chạy lại** `/qc-run-script` |
|
|
21
21
|
| **stamp lệch** | TC/gap/plan mô tả spec cũ | **viết lại** — `/qc-analyze` hoặc `/qc-design-test` |
|
|
22
22
|
|
|
23
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
|
|
@@ -111,8 +111,8 @@ Với mỗi artifact mà lệnh này đọc:
|
|
|
111
111
|
|
|
112
112
|
| Trạm | Lệch thì | Vì sao |
|
|
113
113
|
|---|---|---|
|
|
114
|
-
| `/qc-plan` · `/qc-design-test` · `/qc-review` | **⚠️ 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-
|
|
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
116
|
|
|
117
117
|
```
|
|
118
118
|
⚠️ Stamp lệch — {file} dựng trên {nguồn} {ver_cũ}, hiện tại {ver_mới}.
|
|
@@ -120,7 +120,7 @@ Với mỗi artifact mà lệnh này đọc:
|
|
|
120
120
|
Nên chạy lại: {lệnh} (đi tiếp vẫn được, nhưng {hệ quả cụ thể})
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
**`/qc-run-
|
|
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
124
|
row `DRIFT`/`ORPHANED` của `positive_assertion_guards` + lint **T12** (G55): test vẫn chạy, nhưng
|
|
125
125
|
xanh → ghi `not_run` chứ **không** ghi `pass`, và **không đóng bug nào** ở lần chạy đó.
|
|
126
126
|
|
|
@@ -54,9 +54,9 @@ Discovery → PRD → [Design Spec] → BDD → Tech Design ─┬─ Code → D
|
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
**Sơ đồ rẽ đôi, không phải một dòng thẳng.** `/map-testids` chốt hợp đồng test-id §4.5.6 ở Tech
|
|
57
|
-
Design, nên **Code** và **QC Design** (`/qc-analyze` → `/qc-plan` → `/qc-design-test` → `/qc-review`)
|
|
57
|
+
Design, nên **Code** và **QC Design** (`/qc-analyze` → `/qc-plan` → `/qc-design-test` → `/qc-review-testcase`)
|
|
58
58
|
đọc cùng một bản đã đóng băng và **chạy song song, không chờ nhau**. Hai nhánh gặp lại ở **QC Run**
|
|
59
|
-
(`/qc-run-
|
|
59
|
+
(`/qc-run-script` → `/qc-report`) — trạm duy nhất cần code chạy được.
|
|
60
60
|
|
|
61
61
|
Tìm lệnh hiện tại trong bảng phase dưới đây và đánh dấu **phase của nó** trong sơ đồ trên:
|
|
62
62
|
|
|
@@ -69,8 +69,8 @@ Tìm lệnh hiện tại trong bảng phase dưới đây và đánh dấu **pha
|
|
|
69
69
|
| Tech Design | `/generate-tech-docs` · `/map-testids` · `/review-tech-docs` |
|
|
70
70
|
| Code | `/generate-code` · `/review-code` |
|
|
71
71
|
| Dev Self-Check | `/dev-gen-test` · `/dev-run-test` · `/dev-smoke-test` |
|
|
72
|
-
| QC Design | `/qc-analyze` · `/qc-plan` · `/qc-design-test` · `/qc-review` |
|
|
73
|
-
| QC Run | `/qc-run-
|
|
72
|
+
| QC Design | `/qc-analyze` · `/qc-plan` · `/qc-design-test` · `/qc-review-testcase` · `/qc-automation-assess` |
|
|
73
|
+
| QC Run | `/qc-design-script` · `/qc-review-script` · `/qc-run-script` · `/qc-run-manualtest` · `/qc-report` |
|
|
74
74
|
| Trace Audit | `/validate-traces` |
|
|
75
75
|
|
|
76
76
|
Với **lệnh review**, thêm vòng review 3 bước và đánh dấu bước hiện tại, vd:
|
|
@@ -97,10 +97,11 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
97
97
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` nếu APPROVED; sinh lại nếu NEEDS_FIX |
|
|
98
98
|
| /qc-analyze | `/qc-plan {TICKET-ID} {platform}` — **cấp PRD**, không phải `{UC-ID}` (xử lý các gap blocker 🔴 trước) |
|
|
99
99
|
| /qc-plan | `/qc-design-test {UC-ID}` |
|
|
100
|
-
| /qc-design-test | `/qc-review {UC-ID}`
|
|
101
|
-
| /qc-
|
|
102
|
-
| /qc-
|
|
103
|
-
| /qc-
|
|
100
|
+
| /qc-design-test | `/qc-review-testcase {UC-ID}` |
|
|
101
|
+
| /qc-automation-assess | `/qc-design-script {TICKET-ID}` (Automatable: Y) · `/qc-run-manualtest {UC-ID}` (N) |
|
|
102
|
+
| /qc-review-testcase | `/qc-automation-assess {TICKET-ID}` nếu APPROVED; sửa TC bằng `/qc-design-test` nếu NEEDS_FIX |
|
|
103
|
+
| /qc-run-script | `/qc-run-manualtest {UC-ID}` (TC Automatable: N) rồi `/qc-report {UC-ID}` |
|
|
104
|
+
| /qc-review-script | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED; sửa script nếu NEEDS_FIX |
|
|
104
105
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
105
106
|
| /generate-tech-docs | `/map-testids {UC-ID}` — chốt hợp đồng test-id §4.5.6 **trước** khi review |
|
|
106
107
|
| /map-testids | `/review-tech-docs {tech-design-file}` (review CẢ hợp đồng vừa ghi) |
|
|
@@ -112,7 +113,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
112
113
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
113
114
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
114
115
|
| /validate-traces | **Cờ 🔴 trước (chặn PR):** SEAM_UNWIRED → nối binding sang class thật, xoá/thay stub · STUB_UNRESOLVED → `/generate-code {owner_uc}` (lấp logic tại chỗ + xoá hàm song song) · ORPHANED/TRACE_ORPHAN → quyết định thủ công (xoá code+test, đưa scenario trở lại `.feature`, hoặc sửa `sc_id` của tag). **Rồi:** DRIFT/UNTRACKED → `/generate-code {UC-ID}` · BDD_DRIFT → `/generate-code {feature-file}` · tech-doc lỗi thời vs BDD → `/generate-tech-docs` → `/review-tech-docs` · PRD drift → `/generate-bdd {prd-file}` · GAP → `/dev-gen-test {UC-ID}`. **Chỉ tạo PR khi mọi cờ 🔴 = 0** |
|
|
115
|
-
| /fix-bug | `/dev-run-test {UC-ID}` (dev_selftest vừa reset về not_run) → tạo PR; nếu fix một `{BUG-ID}` → QC chạy `/qc-run-
|
|
116
|
+
| /fix-bug | `/dev-run-test {UC-ID}` (dev_selftest vừa reset về not_run) → tạo PR; nếu fix một `{BUG-ID}` → QC chạy `/qc-run-script {UC-ID}` để verify + đóng bug |
|
|
116
117
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
117
118
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
118
119
|
| /propose-scenario | **Case A** (thiếu scenario cho AC có sẵn) → báo PO/Dev review trong `feedback/bdd-proposals/`; `/generate-bdd` tự chèn khi `Status: accepted`. **Case B** (requirement mới) → `feedback/prd-change-requests/` — PO phải đưa vào PRD trước, KHÔNG tự vào BDD được; `/validate-traces` nhắc lại kèm số ngày chờ chừng nào `Status: Open` |
|
|
@@ -25,7 +25,7 @@ Trước khi đẩy sang QC chính thức, Dev cần một vòng **kiểm nhanh
|
|
|
25
25
|
|
|
26
26
|
> **`dev_selftest` ≠ `qc_status`.** Hai trục **độc lập**: dev smoke (nhanh, tự kiểm) vs QC chính thức (Playwright, evidence). Không lấn quyền nhau.
|
|
27
27
|
>
|
|
28
|
-
> ⚠️ **Nhưng "độc lập" chỉ đúng với `status` về KẾT QUẢ CHẠY, không đúng về QUYỀN KHẲNG ĐỊNH** *(GAPS-v4 G55)*. `pass` mang nghĩa *"scenario này đã được nghiệm thu theo spec **hiện tại**"* — nên trên row `DRIFT`/`ORPHANED`, `/dev-run-test` và `/qc-run-
|
|
28
|
+
> ⚠️ **Nhưng "độc lập" chỉ đúng với `status` về KẾT QUẢ CHẠY, không đúng về QUYỀN KHẲNG ĐỊNH** *(GAPS-v4 G55)*. `pass` mang nghĩa *"scenario này đã được nghiệm thu theo spec **hiện tại**"* — nên trên row `DRIFT`/`ORPHANED`, `/dev-run-test` và `/qc-design-script` → `/qc-run-script` **không được** ghi `pass`; chúng hạ về `not_run`. `fail`/`skip` thì ghi bình thường. `lint-trace` **T12** bắt trạng thái `DRIFT + pass` ở sổ thật, bất kể ai ghi ra.
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
# Bước 8 · QC Automation — Dây chuyền kiểm thử 6 trạm (QC Pipeline)
|
|
4
4
|
|
|
5
5
|
> **Tóm tắt.** Dây chuyền QC tự động 6 trạm: phân rã yêu cầu → lập kế hoạch → thiết kế test case → review → chạy Playwright → report. Ghi `qc_status` **chính thức** + evidence.
|
|
6
|
-
> **Commands:** `/qc-analyze` → `/qc-plan` → `/qc-design-test` → `/qc-review` → `/qc-run-
|
|
6
|
+
> **Commands:** `/qc-analyze` → `/qc-plan` → `/qc-design-test` → `/qc-review-testcase` → `/qc-design-script` → `/qc-run-script` → `/qc-review-script` → `/qc-report`
|
|
7
7
|
|
|
8
8
|
| | |
|
|
9
9
|
|---|---|
|
|
10
10
|
| **Giai đoạn** | QC Automation |
|
|
11
11
|
| **Owner** | 👤 QA / Tester |
|
|
12
|
-
| **Đầu vào** | **Trạm 1–4:** spec (PRD/BDD `approved`) + **hợp đồng test-id §4.5.6** (đóng băng ở bước 5) — **chưa cần code**.<br/>**Trạm 5 `/qc-run-
|
|
12
|
+
| **Đầu vào** | **Trạm 1–4:** spec (PRD/BDD `approved`) + **hợp đồng test-id §4.5.6** (đóng băng ở bước 5) — **chưa cần code**.<br/>**Trạm 5 `/qc-design-script` → `/qc-run-script` thêm:** code đã chạy được — **trạm duy nhất** cần |
|
|
13
13
|
| **Đầu ra** | Test case, script Playwright, `qc_status`, evidence, product-gap |
|
|
14
14
|
| **HITL** | 🟠 Vừa — cổng review case & script trước khi chạy |
|
|
15
15
|
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
- Phân rã yêu cầu thành test case bám scenario, phát hiện **gap tài liệu**.
|
|
23
23
|
- Chạy test thật, ghi **`qc_status` chính thức** + **evidence**.
|
|
24
|
-
⚠️ Nhưng `/qc-run-
|
|
24
|
+
⚠️ Nhưng `/qc-design-script` → `/qc-run-script` **đọc cột `status` trước khi ghi `pass`** *(GAPS-v4 G55)*: row `DRIFT`/`ORPHANED` + test xanh → hạ về `not_run`, và **không** đóng bug nào ở lần chạy đó. `fail`/`skip` ghi bình thường.
|
|
25
25
|
- Phân loại FAIL thành **ba** nhãn — `script-bug` · `product-gap` · `flaky` — **sau khi đã chạy lại tối đa 2 lần**. Một test đỏ **một lần** chưa nói được nó đỏ vì cái gì.
|
|
26
26
|
- Đẩy **product-gap** ngược về PO/Dev.
|
|
27
27
|
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
- **UC-ID** + platform (QC pass khoá 1 platform).
|
|
33
33
|
- Spec: PRD / `.feature` (từ spec repo, qua `spec_source`).
|
|
34
34
|
- **Hợp đồng test-id**: `@trace.testid_attr` (header tech-doc, **tên** thuộc tính) + §4.5.6 Test Selectors (**giá trị** test-id, cột *Serves SC* là chỉ mục ngược). Đã chốt ở [bước 5](05-tech-docs.md) **trước khi có code**.
|
|
35
|
-
- Code đã sinh & chạy được — **chỉ `/qc-run-
|
|
35
|
+
- Code đã sinh & chạy được — **chỉ `/qc-design-script` → `/qc-run-script` cần**. Bốn trạm đầu (`/qc-analyze` → `/qc-plan` → `/qc-design-test` → `/qc-review-testcase`) chạy **song song với FE** vì chỉ cần spec + hợp đồng test-id. Đó là chỗ hai nhánh của [bước 5](05-tech-docs.md) gặp lại.
|
|
36
36
|
- `qc_dir` (working docs của QC) + module `qc-playwright`.
|
|
37
37
|
|
|
38
38
|
## Output (Đầu ra)
|
|
@@ -75,8 +75,9 @@ Dây chuyền **6 trạm**, output trạm trước là input trạm sau:
|
|
|
75
75
|
| 1 | `/qc-analyze` | Phân rã yêu cầu + phát hiện **gap tài liệu** (`DOC_GAP.md`) | **Guard BR-tag** |
|
|
76
76
|
| 2 | `/qc-plan` | Đánh giá **rủi ro** + câu hỏi cho dev (`TEST_PLAN.md`) | — |
|
|
77
77
|
| 3 | `/qc-design-test` | Thiết kế **test case** dạng Markdown (`*.Test.md`) | **Guard SC coverage** |
|
|
78
|
-
| 4 | `/qc-review` | 🛑 **Cổng review**
|
|
79
|
-
|
|
|
78
|
+
| 4 | `/qc-review-testcase` | 🛑 **Cổng review test case** — verdict `APPROVED`/`NEEDS_FIX` là điều kiện tiên quyết của trạm sau | — |
|
|
79
|
+
| 6 | `/qc-review-script` | 🛑 **Cổng review script** — biên bản riêng `REVIEW_SCRIPT_<FEATURE>.md` | — |
|
|
80
|
+
| 5 | `/qc-design-script` → `/qc-run-script` | Sinh & chạy **pytest-playwright**, ghi **`qc_status`** chính thức | **chạy lại ×2 + 3 nhãn FAIL** |
|
|
80
81
|
| 6 | `/qc-report` | Report + **evidence**, đẩy **product-gap** về PO/Dev | — |
|
|
81
82
|
|
|
82
83
|
### Hai Guard cơ học — chống bỏ sót **im lặng**
|
|
@@ -127,7 +128,7 @@ Cả sáu trạm nạp chung `skills/qc/_shared/self-review-principles.md` và c
|
|
|
127
128
|
|
|
128
129
|
## HITL / Gate
|
|
129
130
|
|
|
130
|
-
- 🛑 `/qc-review` — **cổng review
|
|
131
|
+
- 🛑 `/qc-review-testcase` · `/qc-review-script` — **hai cổng review riêng**: không chạy test kém, và trạm sau đọc được verdict của ĐÚNG vai nó cần.
|
|
131
132
|
- 🛑 **Xác nhận phân loại FAIL** — mỗi FAIL phải được người chốt nhãn trước khi ghi `qc_status`. Đây là cổng chặn hiếm hoi được **thêm vào** (framework vốn đang giảm số cổng), vì **cả hai hướng sai đều không đảo ngược rẻ**.
|
|
132
133
|
- **Không fake-pass**: FAIL là product-gap → giữ nguyên FAIL + evidence, đẩy về PO/Dev.
|
|
133
134
|
|
|
@@ -137,7 +138,7 @@ Cả sáu trạm nạp chung `skills/qc/_shared/self-review-principles.md` và c
|
|
|
137
138
|
|
|
138
139
|
- ❌ Lẫn `qc_status` với `dev_selftest` — hai trục độc lập.
|
|
139
140
|
- ❌ Sửa script cho "xanh" khi thực chất là product-gap → giấu lỗi sản phẩm.
|
|
140
|
-
- ❌ Chạy `/qc-run-
|
|
141
|
+
- ❌ Chạy `/qc-design-script` → `/qc-run-script` khi chưa qua cổng `/qc-review-testcase`.
|
|
141
142
|
- ❌ **Kết luận từ một lần chạy đỏ** — chưa loại nhiễu thì chưa phân biệt được `flaky` với lỗi thật.
|
|
142
143
|
- ❌ **Tự dò selector từ DOM** thay vì đọc §4.5.6 — script giòn, dev đổi một class là vỡ mà không ai báo.
|
|
143
144
|
- ❌ Dùng self-review làm lý do **bỏ qua** một Guard.
|
|
@@ -98,9 +98,9 @@ Framework là pipeline **một chiều** — nhưng vẫn cần đường **ph
|
|
|
98
98
|
|---|---|---|
|
|
99
99
|
| `🟢 Open` | `/report-bug` | tester/QC file bug |
|
|
100
100
|
| `🟡 Fixed` | `/fix-bug` Phase 5.5 | fix đã commit + push |
|
|
101
|
-
| `🟢 Closed` | **`/qc-run-
|
|
101
|
+
| `🟢 Closed` | **`/qc-design-script` → `/qc-run-script`** | QC chạy lại và `qc_status` của SC liên kết flip `pass` |
|
|
102
102
|
|
|
103
|
-
> **Dev không tự đóng bug của mình** — QC sở hữu verification. `/qc-run-
|
|
103
|
+
> **Dev không tự đóng bug của mình** — QC sở hữu verification. `/qc-run-script` đọc `qc_blocked_by` **trước** khi clear nó (cột đó chính là con trỏ tới bug; clear xong là mất đường về).
|
|
104
104
|
>
|
|
105
105
|
> Ngoại lệ có chủ đích: SC pass mà bug còn `🟢 Open` (chưa ai fix) → **không đóng**, giữ `Open` + cảnh báo kiểm tra lại test. Test pass trên bug chưa fix là dấu hiệu **test sai**, không phải bug hết — tự đóng ở đây sẽ chôn một defect thật.
|
|
106
106
|
|
|
@@ -149,7 +149,7 @@ QC phát hiện: link reset vẫn dùng được sau khi đổi mật khẩu
|
|
|
149
149
|
→ trace: test_count +2, dev_selftest → not_run
|
|
150
150
|
→ BUG-217 State: 🟡 Fixed
|
|
151
151
|
/dev-run-test AUTH-UC2 → dev_selftest → pass
|
|
152
|
-
/qc-run-
|
|
152
|
+
/qc-run-script AUTH-UC2 → qc_status SC1 → pass
|
|
153
153
|
→ BUG-217 State: 🟢 Closed (verified)
|
|
154
154
|
/learn "luôn invalidate one-time token sau khi dùng"
|
|
155
155
|
→ project-lessons.md (nạp lại lần sau)
|
|
@@ -42,7 +42,7 @@ Chỉ tag `@trace` ở **boundary**, không tag mọi file → tránh **tag expl
|
|
|
42
42
|
| `status` | `/generate-code`, `/validate-traces` | OK / GAP / DRIFT / UNTRACKED |
|
|
43
43
|
| `implemented_by` | `/generate-code` | File code hiện thực SC |
|
|
44
44
|
| `dev_selftest` | `/dev-run-test` | Smoke của **dev** |
|
|
45
|
-
| `qc_status` | `/qc-run-
|
|
45
|
+
| `qc_status` | `/qc-design-script` → `/qc-run-script`, `/report-bug`, **`/map-testids`** | Trạng thái QC **chính thức** (Playwright). `/map-testids` **chỉ hạ về `not_run`**, không bao giờ ghi giá trị khẳng định — xem ô "Làm mất hiệu lực" dưới |
|
|
46
46
|
| `bdd_version` / `spec_ver` | spec | Version để phát hiện drift |
|
|
47
47
|
| `service` *(cột 23)* | `/generate-bdd` | Đội/submodule sở hữu SC — nguồn của `by_service` trên dashboard |
|
|
48
48
|
| `design_spec_version` *(cột 24)* | `/generate-bdd` | Version design-spec lúc sinh BDD *(FE/App; `—` cho backend)* |
|
|
@@ -88,7 +88,7 @@ public TokenDto login(...) { }
|
|
|
88
88
|
- ❌ Để AI tự review code nó vừa sinh.
|
|
89
89
|
- ❌ Tạo PR khi `/validate-traces` còn cờ 🔴 (`SEAM_UNWIRED` · `STUB_UNRESOLVED` · `ORPHANED` · `TRACE_ORPHAN`) — build xanh không chứng minh luồng ghép chạy đúng.
|
|
90
90
|
- ❌ Coi FE `fe_phase = ui` là xong vì status đã `OK` — test đang chạy trên **mock**.
|
|
91
|
-
- ❌ Tự đóng bug mình vừa fix — `/fix-bug` chỉ đặt `🟡 Fixed`; `🟢 Closed` là của `/qc-run-
|
|
91
|
+
- ❌ Tự đóng bug mình vừa fix — `/fix-bug` chỉ đặt `🟡 Fixed`; `🟢 Closed` là của `/qc-design-script` → `/qc-run-script`.
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
flowchart LR
|
|
13
13
|
M["§4.5.6 đã chốt<br/>(/map-testids, bước 5)"] --> A
|
|
14
14
|
A["/qc-analyze<br/>Guard BR-tag"] --> P["/qc-plan"] --> D["/qc-design-test<br/>Guard SC coverage"]
|
|
15
|
-
D --> R["/qc-review<br/>🛑 cổng"] --> RUN["/qc-run-
|
|
15
|
+
D --> R["/qc-review-testcase<br/>🛑 cổng"] --> RUN["/qc-run-script<br/>chạy lại ×2 · 3 nhãn<br/>ghi qc_status"] --> RS["/qc-review-script<br/>🛑 cổng"] --> REP["/qc-report<br/>product-gap"]
|
|
16
16
|
REP --> FB["/report-bug · /propose-scenario"]
|
|
17
17
|
FB --> SYNC["/sync"]
|
|
18
18
|
```
|
|
@@ -28,8 +28,9 @@ flowchart LR
|
|
|
28
28
|
| [`/qc-analyze`](../02-concepts/pipeline-steps/08-qc-automation.md) | Phân rã yêu cầu + phát hiện **gap tài liệu**. **Guard BR-tag** đối chiếu rule BDD đã gắn tag ↔ rule bạn phân tích ra; thiếu thì tự bổ sung từ PRD và in danh sách |
|
|
29
29
|
| `/qc-plan` | Đánh giá rủi ro + câu hỏi cho dev |
|
|
30
30
|
| `/qc-design-test` | Thiết kế test case Markdown (`*.Test.md`). **Guard SC coverage** bắt mọi scenario trong phạm vi phải có ≥1 TC — **không có đường thoát**: SC bị gap chặn thì TC **vẫn viết đủ**, mang dấu `🚫 Block` |
|
|
31
|
-
| `/qc-review` | 🛑 **Cổng review
|
|
32
|
-
| `/qc-
|
|
31
|
+
| `/qc-review-testcase` | 🛑 **Cổng review test case** — trước khi chạy |
|
|
32
|
+
| `/qc-review-script` | 🛑 **Cổng review script** — sau khi sinh script |
|
|
33
|
+
| `/qc-design-script` → `/qc-run-script` | Chạy pytest-playwright, ghi **`qc_status`**; **chạy lại tối đa 2 lần rồi mới phân loại FAIL thành 3 nhãn** (`script-bug` · `product-gap` · `flaky`), và **bạn xác nhận nhãn** trước khi lệnh ghi trace. **Đọc cột `status` trước khi ghi `pass`** — row `DRIFT`/`ORPHANED` + test xanh → `not_run`, và **không đóng bug nào** ở lần chạy đó *(đóng bug dựa trên một lần QC chạy trên spec đã đổi là đóng sai)* |
|
|
33
34
|
| `/qc-report` | Report + evidence, đẩy **product-gap** về PO/Dev |
|
|
34
35
|
| [Feedback](../02-concepts/pipeline-steps/10-feedback-loop.md) | `/report-bug`, `/propose-scenario` — kênh có hồ sơ spec |
|
|
35
36
|
|
|
@@ -44,9 +45,9 @@ Bạn cũng dùng `/validate-traces` để thấy **gap chưa phủ** (spec ↔
|
|
|
44
45
|
- **Một lần đỏ chưa đủ để kết luận.** Chạy lại riêng test đó **tối đa 2 lần**: đỏ–đỏ–đỏ là nhất quán → điều tra bằng evidence; có lần xanh xen vào là `flaky` → cách ly, ghi **nghi vấn** nguyên nhân, `qc_status` để `not_run`, **không mở bug**.
|
|
45
46
|
- Đây **không** phải `retries` trong config runner. `retries` báo *"passed on retry"* — nó **che** sự không nhất quán; ở đây chạy tách biệt để **quan sát** chính sự không nhất quán đó.
|
|
46
47
|
- Không chắc giữa `script-bug` và `product-gap` → **mời Dev cùng xem trace**, đừng đoán cho xong.
|
|
47
|
-
3. **Không chạy test kém** — phải qua cổng `/qc-review` trước `/qc-run-
|
|
48
|
+
3. **Không chạy test kém** — phải qua cổng `/qc-review-testcase` trước `/qc-design-script` → `/qc-run-script`.
|
|
48
49
|
4. **Bug phải spec-anchored** — `/report-bug` gắn `@trace` tới UC/SC để truy vết & regression.
|
|
49
|
-
5. **Bạn là người ĐÓNG bug** — `/fix-bug` của dev chỉ đặt `🟡 Fixed`; `🟢 Closed` do `/qc-run-
|
|
50
|
+
5. **Bạn là người ĐÓNG bug** — `/fix-bug` của dev chỉ đặt `🟡 Fixed`; `🟢 Closed` do `/qc-design-script` → `/qc-run-script` đặt khi `qc_status` của SC liên kết flip `pass`. Dev không tự đóng bug của mình.
|
|
50
51
|
- Ngoại lệ: SC pass mà bug còn `🟢 Open` (chưa ai fix) → **không đóng**, giữ `Open` + kiểm tra lại test. Test pass trên bug chưa fix là dấu hiệu **test sai**.
|
|
51
52
|
6. **`/propose-scenario` dùng đúng bộ tag canonical** — `@trace.scenario` (placeholder `SC?`, `/generate-bdd` gán số khi chèn) · `@trace.sc_version: 1.0` · `@trace.business_rules`. AC ghi thành comment `# Covers:`, **không** phải trace key. Thiếu `@trace.scenario`/`sc_version` thì scenario vào BDD mà **không có row trace** → vô hình với coverage.
|
|
52
53
|
7. Stack QC cố định: Python + pytest-playwright + Page Object (module `qc-playwright`), **độc lập** module của dev.
|
|
@@ -77,7 +78,7 @@ Bạn cũng dùng `/validate-traces` để thấy **gap chưa phủ** (spec ↔
|
|
|
77
78
|
## Anti-pattern
|
|
78
79
|
|
|
79
80
|
- ❌ Sửa script cho "xanh" khi thực chất là product-gap → giấu lỗi sản phẩm.
|
|
80
|
-
- ❌ Chạy `/qc-run-
|
|
81
|
+
- ❌ Chạy `/qc-design-script` → `/qc-run-script` khi chưa qua `/qc-review-testcase`.
|
|
81
82
|
- ❌ Lẫn `qc_status` với `dev_selftest`.
|
|
82
83
|
- ❌ Bug không gắn spec → khó truy vết, khó regression.
|
|
83
84
|
- ❌ Kết luận `product-gap` từ **một** lần chạy đỏ → đốt thời gian dev cho một test hên xui.
|
|
@@ -88,6 +89,6 @@ Bạn cũng dùng `/validate-traces` để thấy **gap chưa phủ** (spec ↔
|
|
|
88
89
|
|
|
89
90
|
## Lệnh của bạn (Your commands)
|
|
90
91
|
|
|
91
|
-
`/qc-analyze` · `/qc-plan` · `/qc-design-test` · `/qc-review` · `/qc-run-
|
|
92
|
+
`/qc-analyze` · `/qc-plan` · `/qc-design-test` · `/qc-review-testcase` · `/qc-design-script` → `/qc-run-script` · `/qc-review-script` · `/qc-report` · `/report-bug` · `/propose-scenario` · `/validate-traces`
|
|
92
93
|
|
|
93
94
|
→ [Bảng lệnh đầy đủ](../04-reference/commands.md) · [Traceability](../02-concepts/traceability.md)
|
|
@@ -92,8 +92,10 @@ Mọi lệnh chạy chung một **Gate** (model check → target → context-loa
|
|
|
92
92
|
| `/qc-analyze` | UC + spec | `REQUIREMENT_ANALYSIS.md`, `DOC_GAP.md` + **Guard BR-tag** | QA |
|
|
93
93
|
| `/qc-plan` | Analysis | `TEST_PLAN.md` (rủi ro) | QA |
|
|
94
94
|
| `/qc-design-test` | Plan + `.feature` + §4.5.6 | `test-cases/*.Test.md` + **Guard SC coverage** | QA |
|
|
95
|
-
| `/qc-review` | Test case
|
|
96
|
-
| `/qc-
|
|
95
|
+
| `/qc-review-testcase` | Test case | 🛑 Cổng review test case | QA |
|
|
96
|
+
| `/qc-automation-assess` | Test case đã duyệt | Quyết định Automatable Y/N + %Automated | QA |
|
|
97
|
+
| `/qc-review-script` | Script + Page Object | 🛑 Cổng review script | QA |
|
|
98
|
+
| `/qc-design-script` → `/qc-run-script` | `.Test.md` reviewed + §4.5.6 | Script Playwright + `qc_status`. **Chạy lại ×2 → 3 nhãn FAIL** (`script-bug`·`product-gap`·`flaky`), 🛑 người xác nhận nhãn | QA |
|
|
97
99
|
| `/qc-report` | Kết quả run | Report + evidence + product-gap | QA |
|
|
98
100
|
|
|
99
101
|
> **Cả sáu trạm chạy một lượt Self-Review trước khi in report**, theo `skills/qc/_shared/self-review-principles.md` (một file dùng chung, không sáu bản sao).
|
|
@@ -99,7 +99,7 @@ public ScoreDto calculate(...) { }
|
|
|
99
99
|
### Hợp đồng test-id — được máy canh (`testid_contract`)
|
|
100
100
|
|
|
101
101
|
Bảng **§4.5.6 Test Selectors** trong tech-doc là hợp đồng FE↔QC: **3 lệnh đọc**
|
|
102
|
-
(`generate-code`, `qc-
|
|
102
|
+
(`generate-code`, `qc-design-script`, `qc-design-test`), **2 lệnh ghi** (`generate-tech-docs`,
|
|
103
103
|
`map-testids`). Hai rule của `lint-trace` canh nó:
|
|
104
104
|
|
|
105
105
|
| Rule | Kiểm gì | Mức |
|
|
@@ -162,10 +162,10 @@ Shared code dò qua **import chain** từ boundary → tránh tag explosion.
|
|
|
162
162
|
| 7 | `test_classes` | tên test class / describe | dev-gen-test · fix-bug |
|
|
163
163
|
| 8 | `dev_selftest` | `pass`/`fail`/`not_run` — **dev tự chạy** | **chủ:** dev-run-test · *hạ hiệu lực:* generate-bdd · generate-code · fix-bug |
|
|
164
164
|
| 9 | `dev_selftest_at` | ngày | như trên |
|
|
165
|
-
| 10 | `qc_status` | `pass`/`fail`/`skip`/`not_run` — **QC chính thức** | **chủ:** qc-run-
|
|
165
|
+
| 10 | `qc_status` | `pass`/`fail`/`skip`/`not_run` — **QC chính thức** | **chủ:** qc-run-script + qc-run-manualtest · *hạ hiệu lực:* generate-bdd · generate-code |
|
|
166
166
|
| 11 | `qc_run_at` | ngày | như trên |
|
|
167
|
-
| 12 | `qc_owner` | SC đang chờ ai: `dev` / `po` | qc-run-
|
|
168
|
-
| 13 | `qc_blocked_by` | `BUG-{id}` / `GAP-{id}` | qc-run-
|
|
167
|
+
| 12 | `qc_owner` | SC đang chờ ai: `dev` / `po` | qc-run-script · qc-run-manualtest · report-bug |
|
|
168
|
+
| 13 | `qc_blocked_by` | `BUG-{id}` / `GAP-{id}` | qc-run-script · qc-run-manualtest · report-bug |
|
|
169
169
|
| 14 | `prd_version` | version PRD lúc sinh BDD | generate-bdd |
|
|
170
170
|
| 15 | `bdd_version` | version `.feature` | generate-bdd · review-context |
|
|
171
171
|
| 16 | `tech_doc_revision` | `@trace.revision` của tech-doc | generate-code · review-tech-docs |
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
[← /qc-plan](16-qc-plan.md) · [Explain Home](README.md) · [Next:
|
|
1
|
+
[← /qc-plan](16-qc-plan.md) · [Explain Home](README.md) · [Next: hai cổng review →](18-qc-review.md)
|
|
2
2
|
|
|
3
3
|
# 17 · `/qc-design-test` — Trạm 3: Thiết kế test case (Markdown)
|
|
4
4
|
|
|
5
|
-
> **Một câu.** Thiết kế **test case dạng Markdown** (`.Test.md`) từ plan — chưa sinh Python; script đến sau ở `/qc-run-
|
|
5
|
+
> **Một câu.** Thiết kế **test case dạng Markdown** (`.Test.md`) từ plan — chưa sinh Python; script đến sau ở `/qc-design-script` → `/qc-run-script`.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## Vấn đề giải quyết
|
|
10
10
|
|
|
11
|
-
Tách "thiết kế test case" (con người đọc/review được) khỏi "code test" (máy chạy). `.Test.md` là bản thiết kế mà `/qc-review` duyệt và `/qc-run-
|
|
11
|
+
Tách "thiết kế test case" (con người đọc/review được) khỏi "code test" (máy chạy). `.Test.md` là bản thiết kế mà `/qc-review` duyệt và `/qc-design-script` → `/qc-run-script` biến thành script.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -55,7 +55,7 @@ Tách "thiết kế test case" (con người đọc/review được) khỏi "cod
|
|
|
55
55
|
|
|
56
56
|
## Checkpoint & Gate
|
|
57
57
|
|
|
58
|
-
- Không gate chặn người ở đây; gate là `/qc-review` kế tiếp.
|
|
58
|
+
- Không gate chặn người ở đây; gate là `/qc-review-testcase` kế tiếp.
|
|
59
59
|
- Nhưng Guard SC coverage **có hệ quả bắt buộc**: thiếu thì lệnh **viết bù** rồi mới báo, không phải chỉ cảnh báo.
|
|
60
60
|
|
|
61
61
|
---
|
|
@@ -81,4 +81,4 @@ Tách "thiết kế test case" (con người đọc/review được) khỏi "cod
|
|
|
81
81
|
|
|
82
82
|
## Kết nối
|
|
83
83
|
|
|
84
|
-
**Trước:** [`/qc-plan`](16-qc-plan.md) · **Sau:** [`/qc-review`](18-qc-review.md) (review test case).
|
|
84
|
+
**Trước:** [`/qc-plan`](16-qc-plan.md) · **Sau:** [`/qc-review-testcase`](18-qc-review.md) (review test case).
|
|
@@ -1,63 +1,85 @@
|
|
|
1
|
-
[← /qc-design-test](17-qc-design-test.md) · [Explain Home](README.md) · [Next:
|
|
1
|
+
[← /qc-design-test](17-qc-design-test.md) · [Explain Home](README.md) · [Next: ba trạm script →](19-qc-run-test.md)
|
|
2
2
|
|
|
3
|
-
# 18 · `/qc-review` — Trạm 4:
|
|
3
|
+
# 18 · `/qc-review-testcase` + `/qc-review-script` — Trạm 4: Hai cổng review
|
|
4
4
|
|
|
5
|
-
> **Một câu.** Gate chất lượng của QC
|
|
5
|
+
> **Một câu.** Gate chất lượng của QC, **hai lệnh riêng**: `/qc-review-testcase` soát test case sau design-test; `/qc-review-script` soát code test sau khi script được sinh.
|
|
6
|
+
|
|
7
|
+
> **Trước Đợt 2 đây là MỘT lệnh `/qc-review` làm cả hai vai và tự đoán vai nào bằng cách so ngày sửa file.** Chính trang này từng ghi ở mục *Góc nhìn tối ưu*: *"Chạy 2 lần cùng một lệnh — người dùng phải nhớ gọi đúng thời điểm… **Cân nhắc tách rõ**"*. Đó là việc đã làm.
|
|
6
8
|
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
## Vấn đề giải quyết
|
|
10
12
|
|
|
11
|
-
Không chạy test kém.
|
|
13
|
+
Không chạy test kém. Hai cổng chặn hai thứ khác nhau:
|
|
14
|
+
|
|
15
|
+
1. **`/qc-review-testcase`** — test case chưa đủ tốt trước khi biến thành script.
|
|
16
|
+
2. **`/qc-review-script`** — script chưa đúng trước khi coi kết quả chạy là chính thức.
|
|
17
|
+
|
|
18
|
+
Và **cái mà một-lệnh-hai-vai không làm được:** đặt điều kiện tiên quyết cho trạm sau. `REVIEW_<FEATURE>.md` của lệnh cũ không nói nó là kết quả soát vai nào, nên trạm sau không hỏi được *"cái tôi cần đã APPROVED chưa?"*.
|
|
12
19
|
|
|
13
20
|
---
|
|
14
21
|
|
|
15
22
|
## Vị trí & tiền đề
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
| Lệnh | Chạy sau | Đọc gì | Ghi gì |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| `/qc-review-testcase` | `/qc-design-test` | `.Test.md` | `REVIEW_<FEATURE>.md` |
|
|
27
|
+
| `/qc-review-script` | trạm sinh script | code test + Page Object | `REVIEW_SCRIPT_<FEATURE>.md` |
|
|
28
|
+
|
|
29
|
+
**File riêng, không chung.** Hai lượt soát cách nhau vài trạm; chung file thì lượt sau đè bảng chi tiết của lượt trước, và trạm tiêu thụ verdict lại phải đoán — tức mang nguyên vấn đề cũ sang chỗ mới.
|
|
18
30
|
|
|
19
31
|
---
|
|
20
32
|
|
|
21
33
|
## Input / Output
|
|
22
34
|
|
|
23
|
-
**Input:** `.Test.md` (case) hoặc
|
|
35
|
+
**Input:** `.Test.md` *(vai test case)* hoặc code test + Page Object *(vai script)*, cộng skill `qa-reviewer`.
|
|
36
|
+
|
|
37
|
+
**Output:** file biên bản riêng của mỗi vai, chứa điểm `XX/100` và **một dòng verdict máy đọc được**:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
**Verdict:** APPROVED
|
|
41
|
+
**Verdict:** NEEDS_FIX
|
|
42
|
+
```
|
|
24
43
|
|
|
25
|
-
**
|
|
44
|
+
`APPROVED` khi điểm `≥80` **và** không còn `FAIL` chặn. Đây là **contract**, không phải định dạng cho đẹp — `/qc-automation-assess` loại TC chưa `APPROVED`, `/qc-run-script` dừng khi script chưa `APPROVED`.
|
|
26
45
|
|
|
27
46
|
---
|
|
28
47
|
|
|
29
|
-
## Các bước xử lý
|
|
48
|
+
## Các bước xử lý
|
|
30
49
|
|
|
31
|
-
1. **Role qa-reviewer** — nạp `{qc_skills_dir}/qa-reviewer
|
|
32
|
-
2. **Review focus** —
|
|
33
|
-
3. **Self-Review**
|
|
34
|
-
4. Verdict
|
|
35
|
-
> **Self-Review ≠ Guard.** Guard là phép **đếm cơ học**, có hệ quả bắt buộc khi lệch. Self-review là lượt đọc lại **rộng hơn nhưng mềm hơn**, soát ba nhóm lỗi mà phép đếm không bắt được (bịa dữ kiện · lẫn suy đoán với sự thật · bỏ dở giữa chừng). Một bộ nguyên tắc tự soát **không bao giờ** được dùng làm lý do gỡ một Guard — chính file `self-review-principles.md` ghi rõ ranh giới đó ngay ở đầu.
|
|
50
|
+
1. **Role qa-reviewer** — nạp `{qc_skills_dir}/qa-reviewer/`, **đúng bộ của vai mình**.
|
|
51
|
+
2. **Review focus** — test case: đủ phủ SC, expected cụ thể, trace, `🚫 Block` còn hiệu lực. Script: khớp `.Test.md` 1-1, Page Object gọn, `expect()` thật, **selector bám §4.5.6 chứ không dò DOM**, không hard-code.
|
|
52
|
+
3. **Self-Review** — nạp `skills/qc/_shared/self-review-principles.md`, soát một lượt trước khi in report.
|
|
53
|
+
4. **Verdict** — `APPROVED` → đi tiếp; `NEEDS_FIX` → sửa rồi review lại.
|
|
36
54
|
|
|
55
|
+
> **Self-Review ≠ Guard.** Guard là phép **đếm cơ học**, có hệ quả bắt buộc khi lệch. Self-review là lượt đọc lại **rộng hơn nhưng mềm hơn**, soát ba nhóm lỗi mà phép đếm không bắt được (bịa dữ kiện · lẫn suy đoán với sự thật · bỏ dở giữa chừng). Một bộ nguyên tắc tự soát **không bao giờ** được dùng làm lý do gỡ một Guard.
|
|
37
56
|
|
|
38
57
|
---
|
|
39
58
|
|
|
40
59
|
## Checkpoint & Gate
|
|
41
60
|
|
|
42
|
-
-
|
|
61
|
+
- Cả hai lệnh ở mức **không chặn** — chúng chỉ ghi **biên bản**, và sinh lại = soát lại.
|
|
62
|
+
- Cổng thật nằm ở **verdict chúng phát ra**, được trạm sau đọc.
|
|
43
63
|
|
|
44
64
|
---
|
|
45
65
|
|
|
46
66
|
## Cơ chế đặc biệt
|
|
47
67
|
|
|
48
|
-
- **
|
|
49
|
-
-
|
|
50
|
-
- **
|
|
68
|
+
- **Chân thứ tư của hợp đồng test-id** — phép so §4.5.6 ↔ `*.Test.md`, mức `warn`, một chiều. Vai này thuộc **`/qc-review-testcase`** *(`bin/trace-schema.json` → `testid_fourth_leg.checked_by`)*, vì phép so chạy trên `.Test.md`. Ở trạm script, locator dựng **lúc chạy** từ bảng tươi nên nó tự cứu.
|
|
69
|
+
- **Đọc stamp phiên bản nguồn** — cũng thuộc vai test case *(`qc_artifact_stamp.checked_by`)*.
|
|
70
|
+
- **Điểm có luật chấm** — trừ 5đ mỗi `FAIL`, 2đ mỗi `WARN`; bảng Tổng quan **thêm một hàng mỗi vòng**, không ghi đè. Đó là cách duy nhất thấy được sửa xong có tốt lên không.
|
|
71
|
+
- **Reviewer KHÔNG tự sửa** — chỉ nhận xét và chấm. *Tự sửa rồi tự duyệt là bỏ mất cái cổng.*
|
|
51
72
|
|
|
52
73
|
---
|
|
53
74
|
|
|
54
75
|
## 👓 Góc nhìn tối ưu
|
|
55
76
|
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
77
|
+
- **Verdict vẫn do LLM phát ra** — có luật chấm rõ, nhưng không có máy nào kiểm lại. Lớp CI cho nó là `T19` *(chân thứ tư)*; phần điểm số thì chưa.
|
|
78
|
+
- **Bộ tiêu chí `script/*` còn phẳng theo tầng.** Khi Đợt 2 bước 2 chốt stack, nó sẽ tách theo nền (`web`/`mobile`) vì tiêu chí khác nhau. Cố ý chưa làm ở bước 1 — viết tiêu chí cho stack chưa chốt là viết hai lần.
|
|
58
79
|
|
|
59
80
|
---
|
|
60
81
|
|
|
61
82
|
## Kết nối
|
|
62
83
|
|
|
63
|
-
**Trước:** [`/qc-design-test`](17-qc-design-test.md) (
|
|
84
|
+
**Trước:** [`/qc-design-test`](17-qc-design-test.md) *(vai test case)* · [ba trạm script](19-qc-run-test.md) *(vai script)*
|
|
85
|
+
**Sau:** test case `APPROVED` → [ba trạm script](19-qc-run-test.md) · script `APPROVED` → [`/qc-report`](20-qc-report.md) rồi tạo PR
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
[←
|
|
1
|
+
[← hai cổng review](18-qc-review.md) · [Explain Home](README.md) · [Next: /qc-report →](20-qc-report.md)
|
|
2
2
|
|
|
3
|
-
# 19 · `/qc-run-
|
|
3
|
+
# 19 · `/qc-design-script` · `/qc-run-script` · `/qc-run-manualtest` — Trạm 5–7: sinh · chạy · chạy tay
|
|
4
4
|
|
|
5
5
|
> **Một câu.** Biến `.Test.md` đã review thành **Python pytest-playwright**, chạy thật, rồi ghi **`qc_status` chính thức** (có evidence) vào trace TSV.
|
|
6
6
|
|
|
@@ -8,13 +8,16 @@
|
|
|
8
8
|
|
|
9
9
|
## Vấn đề giải quyết
|
|
10
10
|
|
|
11
|
+
> **Trước Đợt 2 · b2 đây là MỘT lệnh `/qc-run-test` gánh BỐN việc**: quyết cái nào automate được · viết mã · chạy · phán một kết quả đỏ là lỗi sản phẩm hay lỗi mã test. Bốn quyết định, không chỗ nào dừng giữa chúng — nên không ai soát được mã trước khi nó chạy, và TC **không** automate được (OTP, sinh trắc học) rơi ra ngoài: không trạm nào ghi `qc_status` cho chúng, rồi `/qc-report` chấm cả PRD là FAIL vĩnh viễn. `/qc-run-manualtest` sinh ra để bịt đúng chỗ đó.
|
|
12
|
+
|
|
13
|
+
|
|
11
14
|
Đây là nơi QC trở thành **chính thức**: chạy test thật trên Playwright, phân loại FAIL (script-bug vs product-gap, **không fake-pass**), và đóng dấu `qc_status` — trạng thái QC authoritative.
|
|
12
15
|
|
|
13
16
|
---
|
|
14
17
|
|
|
15
18
|
## Vị trí & tiền đề
|
|
16
19
|
|
|
17
|
-
- **Vị trí:** Phase QC
|
|
20
|
+
- **Vị trí:** Phase QC, **ba trạm** — 5 sinh script · 6 chạy script · 7b chạy tay. `/qc-design-script` chạy sau `/qc-review-testcase` (case APPROVED); `/qc-run-script` chạy sau `/qc-review-script` (script APPROVED).
|
|
18
21
|
- **Stack:** module `qc-playwright` (Python + pytest-playwright + Page Object) — **độc lập** module dev.
|
|
19
22
|
|
|
20
23
|
---
|
|
@@ -67,7 +70,7 @@
|
|
|
67
70
|
|
|
68
71
|
## Checkpoint & Gate
|
|
69
72
|
|
|
70
|
-
- Tiền đề: case đã APPROVED ở `/qc-review`. Script sinh ra → review lại ở `/qc-review`
|
|
73
|
+
- Tiền đề: case đã APPROVED ở `/qc-review-testcase`. Script sinh ra → review lại ở `/qc-review-script` trước PR.
|
|
71
74
|
- 🛑 **Xác nhận nhãn FAIL** — cổng chặn được **thêm vào**, trong khi framework vốn đang giảm số cổng chặn (G41). Lý do: **cả hai hướng sai đều không đảo ngược rẻ.** Gắn nhầm `script-bug` cho lỗi sản phẩm thật là **giấu bug** cho tới khi khách gặp; mở bug từ một lần chạy hên xui là **đốt thời gian dev** và làm mòn niềm tin vào QC.
|
|
72
75
|
|
|
73
76
|
> **Đây KHÔNG phải `retries` trong config test runner.** `retries` tự thử lại rồi báo *"passed on retry"* — nó **che** sự không nhất quán. Ở đây chạy **tách biệt từng lần để quan sát**, vì chính sự không nhất quán mới là thông tin cần.
|
|
@@ -89,7 +92,7 @@ Khi `qc_status` flip `pass`, lệnh clear `qc_owner`/`qc_blocked_by` về `—`.
|
|
|
89
92
|
|
|
90
93
|
| `State` của bug | SC vừa `pass` → làm gì |
|
|
91
94
|
|---|---|
|
|
92
|
-
| `🟡 Fixed` | → `🟢 Closed` + dòng `Verified: /qc-run-
|
|
95
|
+
| `🟡 Fixed` | → `🟢 Closed` + dòng `Verified: /qc-run-script {today} — {UC-ID}-SC{N} pass` |
|
|
93
96
|
| `🟢 Open` (chưa ai fix) | **KHÔNG đóng.** Giữ `Open` + ghi chú kiểm tra lại test |
|
|
94
97
|
| `GAP-*` thay vì `BUG-*` | không đụng — spec-gap thuộc PO, không phải QC |
|
|
95
98
|
|
|
@@ -111,4 +114,4 @@ Bug report đã đổi phải **commit + push** vào spec repo — file local l
|
|
|
111
114
|
|
|
112
115
|
## Kết nối
|
|
113
116
|
|
|
114
|
-
**Trước:** [`/qc-review`](18-qc-review.md)
|
|
117
|
+
**Trước:** [`/qc-review-testcase`](18-qc-review.md) · **Sau:** [`/qc-report`](20-qc-report.md) rồi [`/qc-review-script`](18-qc-review.md) (script).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[←
|
|
1
|
+
[← ba trạm script](19-qc-run-test.md) · [Explain Home](README.md) · [Next: /validate-traces →](21-validate-traces.md)
|
|
2
2
|
|
|
3
3
|
# 20 · `/qc-report` — Trạm 6: Report + evidence + product-gap
|
|
4
4
|
|
|
@@ -14,7 +14,7 @@ Kết quả chạy cần được trình bày có bằng chứng và **định t
|
|
|
14
14
|
|
|
15
15
|
## Vị trí & tiền đề
|
|
16
16
|
|
|
17
|
-
- **Vị trí:** Phase QC (trạm 6, cuối), sau `/qc-run-
|
|
17
|
+
- **Vị trí:** Phase QC (trạm 6, cuối), sau `/qc-design-script` → `/qc-run-script`.
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
@@ -61,4 +61,4 @@ Kết quả chạy cần được trình bày có bằng chứng và **định t
|
|
|
61
61
|
|
|
62
62
|
## Kết nối
|
|
63
63
|
|
|
64
|
-
**Trước:** [
|
|
64
|
+
**Trước:** [ba trạm script](19-qc-run-test.md) · **Sau:** [`/validate-traces`](21-validate-traces.md) (làm mới Living Docs); product-gap → [`/report-bug`](25-report-bug.md).
|
|
@@ -35,7 +35,7 @@ Sửa bug ad-hoc dễ tái phát và mất truy vết. Command áp một quy tr
|
|
|
35
35
|
4. **Phase 4 · Regression Test** — thêm test tái hiện bug để chống tái phát.
|
|
36
36
|
5. **Phase 4.5 · Cập nhật sổ trace** — regression test phải hiện lên coverage (xem dưới).
|
|
37
37
|
6. **Phase 5 · Build & Commit** — build verify; umbrella **push 2 tầng** (Tầng 1: fix branch trong service submodule nơi code sống; Tầng 2: umbrella pointer).
|
|
38
|
-
7. **Phase 5.5 · Đặt `🟡 Fixed`** — nếu fix một `{BUG-ID}` đã file. **Không** đặt `Closed` — bước đó thuộc `/qc-run-
|
|
38
|
+
7. **Phase 5.5 · Đặt `🟡 Fixed`** — nếu fix một `{BUG-ID}` đã file. **Không** đặt `Closed` — bước đó thuộc `/qc-design-script` → `/qc-run-script`.
|
|
39
39
|
8. **Phase 6 · Đề xuất Lesson** — nếu lỗi tái diễn → `capture-lesson` (L1–L5).
|
|
40
40
|
|
|
41
41
|
### Phase 4.5 — vì sao `/fix-bug` phải ghi sổ trace
|
|
@@ -49,7 +49,7 @@ Sửa bug ad-hoc dễ tái phát và mất truy vết. Command áp một quy tr
|
|
|
49
49
|
| `dev_selftest` → `not_run` · `dev_selftest_at` → `—` | code vừa đổi nên tín hiệu self-test cũ hết hiệu lực |
|
|
50
50
|
| `last_updated` | hôm nay |
|
|
51
51
|
|
|
52
|
-
**Hai nhóm cột cấm đụng:** `qc_*` (QC sở hữu — `/qc-run-
|
|
52
|
+
**Hai nhóm cột cấm đụng:** `qc_*` (QC sở hữu — `/qc-design-script` → `/qc-run-script` flip khi re-verify **và** chính nó đóng bug) · `spec_ver`/`gen_ver` (**fix bug không đổi spec** — đụng vào là tạo `DRIFT` giả).
|
|
53
53
|
|
|
54
54
|
Vì `dev_selftest` bị reset, Next của lệnh là **`/dev-run-test`** để lấy lại tín hiệu xanh, rồi mới tạo PR.
|
|
55
55
|
|
package/docs/explain/README.md
CHANGED
|
@@ -117,8 +117,8 @@ Kết thúc bằng: **Status badge** (✅/❌/⚠️) · **Output Artifacts** (f
|
|
|
117
117
|
- [15 · `/qc-analyze`](15-qc-analyze.md)
|
|
118
118
|
- [16 · `/qc-plan`](16-qc-plan.md)
|
|
119
119
|
- [17 · `/qc-design-test`](17-qc-design-test.md)
|
|
120
|
-
- [18 · `/qc-review`](18-qc-review.md)
|
|
121
|
-
- [19 · `/qc-run-
|
|
120
|
+
- [18 · `/qc-review-testcase` + `/qc-review-script`](18-qc-review.md)
|
|
121
|
+
- [19 · `/qc-design-script` · `/qc-run-script` · `/qc-run-manualtest`](19-qc-run-test.md)
|
|
122
122
|
- [20 · `/qc-report`](20-qc-report.md)
|
|
123
123
|
|
|
124
124
|
### Phase Trace & Quality
|