@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
|
@@ -1,59 +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`.
|
|
24
36
|
|
|
25
|
-
**Output:**
|
|
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
|
+
```
|
|
43
|
+
|
|
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ý
|
|
49
|
+
|
|
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.
|
|
30
54
|
|
|
31
|
-
|
|
32
|
-
2. **Review focus** — kiểm test case (đủ phủ, đúng SC) hoặc script (đúng logic, selector, không fake-pass).
|
|
33
|
-
3. Verdict: APPROVED → đi tiếp; NEEDS_FIX → sửa rồi review lại.
|
|
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.
|
|
34
56
|
|
|
35
57
|
---
|
|
36
58
|
|
|
37
59
|
## Checkpoint & Gate
|
|
38
60
|
|
|
39
|
-
-
|
|
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.
|
|
40
63
|
|
|
41
64
|
---
|
|
42
65
|
|
|
43
66
|
## Cơ chế đặc biệt
|
|
44
67
|
|
|
45
|
-
- **
|
|
46
|
-
-
|
|
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.*
|
|
47
72
|
|
|
48
73
|
---
|
|
49
74
|
|
|
50
75
|
## 👓 Góc nhìn tối ưu
|
|
51
76
|
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
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.
|
|
54
79
|
|
|
55
80
|
---
|
|
56
81
|
|
|
57
82
|
## Kết nối
|
|
58
83
|
|
|
59
|
-
**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
|
---
|
|
@@ -36,20 +39,41 @@
|
|
|
36
39
|
1. **Role & stack** — qc-playwright (`stack-profile.yaml`): Python, pytest-playwright fixture, Page Object; mỗi test độc lập; gom theo (role, account) để auth không xen kẽ.
|
|
37
40
|
2. **Skills** — nạp một file skill `qa-runner` theo layer.
|
|
38
41
|
3. **Sinh script** từ `.Test.md`; tag `@trace.verifies={UC-ID}-SC{N}`.
|
|
39
|
-
4. **Chạy**
|
|
42
|
+
4. **Chạy.** Test đỏ **một lần** chưa nói được nó đỏ vì cái gì → **chạy lại riêng test đó, tối đa 2 lần**, rồi mới phân loại thành **ba** nhãn:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
đỏ → đỏ → đỏ ⇒ NHẤT QUÁN → sang bước điều tra: script-bug | product-gap
|
|
46
|
+
đỏ → xanh ⇒ KHÔNG NHẤT QUÁN → flaky
|
|
47
|
+
đỏ → đỏ → xanh ⇒ KHÔNG NHẤT QUÁN → flaky
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Nhãn | Khi nào | Hệ quả |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `script-bug` | Sai locator / logic test / timing / dữ liệu test | QC tự sửa. **Không** mở bug |
|
|
53
|
+
| `product-gap` | Hành vi thật ≠ spec — defect thật | Mở bug qua `/report-bug`. Giữ `fail` + evidence, **không bao giờ fake-pass** |
|
|
54
|
+
| `flaky` | Không nhất quán ở bước chạy lại — **chưa đủ căn cứ** | Cách ly + ghi **nghi vấn** nguyên nhân. **Không** mở bug từ một lần chạy hên xui |
|
|
55
|
+
|
|
56
|
+
**Điều tra bằng bằng chứng, không đoán** — đọc trace/video/log: timeline, DOM snapshot, network, console **tại thời điểm fail**. Không chắc giữa `script-bug` và `product-gap` → **mời Dev cùng xem trace**.
|
|
57
|
+
|
|
58
|
+
🛑 **Người xác nhận TRƯỚC khi hành động** — lệnh in đề xuất kèm evidence cụ thể rồi **dừng chờ**. **Không ghi `qc_status`** cho scenario nào còn FAIL chưa được xác nhận nhãn.
|
|
40
59
|
5. **Write Trace State — `qc_status`** (kết quả QC chính thức) + `qc_run_at`, `qc_owner`, `qc_blocked_by`, `last_updated`.
|
|
41
60
|
|
|
42
61
|
⚠️ **ĐỌC cột `status` TRƯỚC KHI GHI `pass`** *(GAPS-v4 G55, đối xứng `/dev-run-test`)*: row `DRIFT`/`ORPHANED` + test xanh → **`not_run`**, không bao giờ `pass`. `fail` và `skip` ghi bình thường — chỉ giá trị **khẳng định** cần giấy phép.
|
|
43
62
|
|
|
44
63
|
Và ở lệnh này hậu quả đi **xa hơn** `/dev-run-test`: một `pass` sai còn **đóng một bug** (§Đóng bug đã verify). Nên khi hạ về `not_run`, lệnh **KHÔNG** clear `qc_owner`/`qc_blocked_by` và **KHÔNG** chạy bước đóng bug — đóng bug dựa trên một lần QC chạy trên spec đã đổi là đóng sai.
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
`flaky` → `qc_status = not_run`, `qc_owner = qc`. Không tạo trạng thái mới: `not_run` đúng nghĩa *"chưa có kết luận"*, và `qc_owner = qc` để nó không rơi vào khoảng không ai nhận.
|
|
65
|
+
6. **Self-Review** *(mới)* — nạp `skills/qc/_shared/self-review-principles.md`, soát một lượt trước khi in report.
|
|
66
|
+
7. **Đóng bug đã verify** — chạy **TRƯỚC** bước clear cột (xem dưới).
|
|
67
|
+
8. **Refresh Panel Mirror** — Living Docs local.
|
|
47
68
|
|
|
48
69
|
---
|
|
49
70
|
|
|
50
71
|
## Checkpoint & Gate
|
|
51
72
|
|
|
52
|
-
- 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.
|
|
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.
|
|
75
|
+
|
|
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.
|
|
53
77
|
|
|
54
78
|
---
|
|
55
79
|
|
|
@@ -57,6 +81,7 @@
|
|
|
57
81
|
|
|
58
82
|
- **`qc_status` là trục authoritative** — khác `dev_selftest`; có evidence.
|
|
59
83
|
- **Không fake-pass** — product-gap giữ nguyên FAIL, đẩy về PO/Dev.
|
|
84
|
+
- **Chạy lại để QUAN SÁT, không để cho qua** — ba nhãn FAIL tách *chưa đủ căn cứ* (`flaky`) ra khỏi *đã đủ căn cứ* (`script-bug` / `product-gap`). Trước đây hai nhãn gộp cả ba tình huống, nên một test hên xui hoặc bị gán bừa `script-bug` (giấu bug), hoặc thành một bug ma gửi cho dev.
|
|
60
85
|
- **Stack QC tách hẳn dev** — `@trace.verifies` nối script ↔ SC.
|
|
61
86
|
- **`active_platform` khoá sổ trace** — `qc_status` ghi đúng `{UC-ID}-{platform}.tsv`.
|
|
62
87
|
- **Chủ sở hữu bước `🟡 Fixed → 🟢 Closed`.** `/report-bug` mở bug (`🟢 Open`), `/fix-bug` đặt `🟡 Fixed`, và **chỉ QC re-verify mới đóng được** — dev không tự đóng bug của mình.
|
|
@@ -67,7 +92,7 @@ Khi `qc_status` flip `pass`, lệnh clear `qc_owner`/`qc_blocked_by` về `—`.
|
|
|
67
92
|
|
|
68
93
|
| `State` của bug | SC vừa `pass` → làm gì |
|
|
69
94
|
|---|---|
|
|
70
|
-
| `🟡 Fixed` | → `🟢 Closed` + dòng `Verified: /qc-run-
|
|
95
|
+
| `🟡 Fixed` | → `🟢 Closed` + dòng `Verified: /qc-run-script {today} — {UC-ID}-SC{N} pass` |
|
|
71
96
|
| `🟢 Open` (chưa ai fix) | **KHÔNG đóng.** Giữ `Open` + ghi chú kiểm tra lại test |
|
|
72
97
|
| `GAP-*` thay vì `BUG-*` | không đụng — spec-gap thuộc PO, không phải QC |
|
|
73
98
|
|
|
@@ -80,12 +105,13 @@ Bug report đã đổi phải **commit + push** vào spec repo — file local l
|
|
|
80
105
|
## 👓 Góc nhìn tối ưu
|
|
81
106
|
|
|
82
107
|
- **Trạm nặng nhất của QC** — sinh + chạy + phân loại + ghi trace. Chạy thật phụ thuộc môi trường (browser, data, service lên).
|
|
83
|
-
- **Phân loại script-bug
|
|
84
|
-
- **Selector
|
|
85
|
-
- **Chạy lại tốn tài nguyên** —
|
|
108
|
+
- **Phân loại vẫn phụ thuộc người đọc evidence** — nhưng giờ có **tiêu chí và thứ tự bắt buộc**: chạy lại ×2 → đọc trace/log → đề xuất nhãn → **người xác nhận**. Chỗ mềm còn lại là ranh giới `script-bug` ↔ `product-gap` khi hành vi nằm ở **biên của spec**; đường ra đã ghi rõ là **mời Dev cùng xem trace**, không đoán cho xong.
|
|
109
|
+
- **Selector bám hợp đồng `/map-testids`** — §4.5.6 đã được chốt **trước** `/generate-code`, nên trạm này có bảng selector sẵn. Ca còn lại: §4.5.6 rỗng (dự án cũ chưa từng chạy `/map-testids`) → script quay về dò DOM và **giòn**.
|
|
110
|
+
- **Chạy lại tốn tài nguyên** — ×2 cho mỗi FAIL là chi phí thật. Đánh đổi có chủ đích: rẻ hơn nhiều so với một bug ma gửi cho dev, hoặc một defect thật bị gán `script-bug` rồi chôn.
|
|
111
|
+
- **`flaky` không có cột riêng trong sổ trace** — nó nằm ở `qc_status = not_run` + `qc_owner = qc` + nghi vấn ghi trong report. Cố ý: thêm một giá trị enum mới sẽ kéo theo sửa schema, lint, mọi lệnh đọc cột đó — trong khi `not_run` đã đúng nghĩa *chưa có kết luận*. Cái giá là **không truy được lịch sử flaky bằng máy**, phải đọc report.
|
|
86
112
|
|
|
87
113
|
---
|
|
88
114
|
|
|
89
115
|
## Kết nối
|
|
90
116
|
|
|
91
|
-
**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
|
|
|
@@ -30,8 +30,11 @@ Kết quả chạy cần được trình bày có bằng chứng và **định t
|
|
|
30
30
|
|
|
31
31
|
1. **Role qa-runner/report** — nạp skill report.
|
|
32
32
|
2. **Procedure** — tổng hợp kết quả run (pass/fail per SC), đính evidence.
|
|
33
|
-
3. Tách **product-gap** → định tuyến về PO/Dev (có thể thành `/report-bug`).
|
|
34
|
-
4. **
|
|
33
|
+
3. Tách **product-gap** → định tuyến về PO/Dev (có thể thành `/report-bug`). Scenario mang nhãn **`flaky`** **không** thành bug — nó là *chưa có kết luận*, `qc_status` để `not_run`.
|
|
34
|
+
4. **Self-Review** *(mới)* — nạp `skills/qc/_shared/self-review-principles.md`, soát một lượt trước khi in report.
|
|
35
|
+
5. **Output** report.
|
|
36
|
+
> **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.
|
|
37
|
+
|
|
35
38
|
|
|
36
39
|
---
|
|
37
40
|
|
|
@@ -58,4 +61,4 @@ Kết quả chạy cần được trình bày có bằng chứng và **định t
|
|
|
58
61
|
|
|
59
62
|
## Kết nối
|
|
60
63
|
|
|
61
|
-
**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
|
@@ -98,12 +98,15 @@ Kết thúc bằng: **Status badge** (✅/❌/⚠️) · **Output Artifacts** (f
|
|
|
98
98
|
- [05 · `/generate-design-spec`](05-generate-design-spec.md)
|
|
99
99
|
- [06 · `/generate-bdd`](06-generate-bdd.md)
|
|
100
100
|
- [07 · `/generate-tech-docs`](07-generate-tech-docs.md)
|
|
101
|
+
- [**11** · `/map-testids`](11-map-testids.md) ← **chốt hợp đồng test-id, TRƯỚC code**
|
|
101
102
|
- [08 · `/review-tech-docs`](08-review-tech-docs.md)
|
|
102
103
|
|
|
104
|
+
> Danh sách này xếp theo **thứ tự chạy**, không theo số file. `/map-testids` giữ số `11` vì lý do lịch sử — giữ tên file để không gãy link cũ.
|
|
105
|
+
> §4.5.6 chốt ở đây là lý do **Phase Implementation** và **Phase QC Automation** chạy được **song song**.
|
|
106
|
+
|
|
103
107
|
### Phase Implementation
|
|
104
108
|
- [09 · `/generate-code`](09-generate-code.md)
|
|
105
109
|
- [10 · `/review-code`](10-review-code.md)
|
|
106
|
-
- [11 · `/map-testids`](11-map-testids.md)
|
|
107
110
|
|
|
108
111
|
### Phase Dev Self-Test
|
|
109
112
|
- [12 · `/dev-gen-test`](12-dev-gen-test.md)
|
|
@@ -114,8 +117,8 @@ Kết thúc bằng: **Status badge** (✅/❌/⚠️) · **Output Artifacts** (f
|
|
|
114
117
|
- [15 · `/qc-analyze`](15-qc-analyze.md)
|
|
115
118
|
- [16 · `/qc-plan`](16-qc-plan.md)
|
|
116
119
|
- [17 · `/qc-design-test`](17-qc-design-test.md)
|
|
117
|
-
- [18 · `/qc-review`](18-qc-review.md)
|
|
118
|
-
- [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)
|
|
119
122
|
- [20 · `/qc-report`](20-qc-report.md)
|
|
120
123
|
|
|
121
124
|
### Phase Trace & Quality
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Checklist 20 bước — đợt đại phẫu QC
|
|
3
|
-
updated: 2026-09-
|
|
3
|
+
updated: 2026-09-16
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Checklist — đang ở đâu
|
|
@@ -19,9 +19,9 @@ updated: 2026-09-11
|
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
node bin/build.js # đúc .tmpl → .md → core/
|
|
22
|
-
node bin/self-check.js # R1–
|
|
22
|
+
node bin/self-check.js # R1–R18 (R17/R18 thêm ở 0.9.6)
|
|
23
23
|
node test/run.js # gồm test ngân sách dung lượng core/commands
|
|
24
|
-
node bin/lint-trace.js # T1–
|
|
24
|
+
node bin/lint-trace.js # T1–T20 trên sổ trace thật (T19/T20 thêm ở 0.9.6)
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
---
|
|
@@ -73,20 +73,73 @@ node bin/lint-trace.js # T1–T14 trên sổ trace thật
|
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
76
|
-
## Việc dọn bắt buộc —
|
|
76
|
+
## Việc dọn bắt buộc — đo lại tại HEAD 0.9.6
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
| [ ] | Bổ nhãn `*Checkpoint: …*` cho lệnh còn thiếu | 6 file |
|
|
83
|
-
| [ ] | Gỡ comment provenance 10+ dòng ở đầu file lệnh → chuyển vào `bin/qc-base-map.json` | 12 file |
|
|
84
|
-
| [ ] | Thay gate cắt tay (5.4 KB) bằng `{{include:steps/gate.md}}` (11.1 KB) | 12 file |
|
|
78
|
+
> **Bốn trong năm dòng đã xong từ trước mà chưa ai tích.** Cột *Ghi* là số của lần lập bảng
|
|
79
|
+
> (2026-09-11); cột *Đo lại* là số đếm thật trên `commands/*.tmpl` + `skills/` ngày 2026-09-15,
|
|
80
|
+
> **đo trước khi sửa file này** — xem cách đếm ở cuối mục. Để nguyên `[ ]` thì người sau đi làm
|
|
81
|
+
> lại bốn việc đã xong.
|
|
85
82
|
|
|
86
|
-
|
|
83
|
+
| | Việc | Ghi | Đo lại 2026-09-15 |
|
|
84
|
+
|:-:|---|---|---|
|
|
85
|
+
| [x] | Sửa file skill còn gọi `TC_<FEATURE>.md` thay `.Test.md` | 14 file | **0 file.** Đúng 2 chỗ còn chuỗi đó, **cả hai** trong `qc-design-test` và là **phản ví dụ có chủ ý** — *"ghi ra thứ không trạm nào tìm thấy"*. Đừng `grep` rồi báo lỗi lại |
|
|
86
|
+
| [x] | Sửa tham chiếu skill treo `qa-script-runner/report/coverage-evaluator.md` | 1 chỗ | **Không phải lỗi — chưa bao giờ hỏng.** Mọi tham chiếu nằm gọn trong `upstream/qc-base/`, và `upstream/qc-base/skills/qa-gate/coverage-evaluator.md` có thật. Không có commit sửa nào để đi tìm |
|
|
87
|
+
| [ ] | Bổ nhãn `*Checkpoint: …*` cho lệnh còn thiếu | 6 file | **18 file** — chỉ 15/33 lệnh có nhãn; số cũ nhỏ hơn thực tế 3 lần *(lần lập bảng đếm trên tập lệnh QC rồi ghi như thể đếm toàn bộ 33 lệnh)*. **Không lệnh nào trong 18 đó được miễn**: cả 5 lệnh mức `none` — `review-code` `validate-traces` `debug` `review-context` `review-tech-docs` — đều ĐÃ có nhãn. 18 là nợ thật |
|
|
88
|
+
| [x] | Gỡ comment provenance 10+ dòng ở đầu file lệnh → `bin/qc-base-map.json` | 12 file | **0 file.** Không tmpl nào còn khối `<!-- -->` ở đầu; provenance rút còn đúng 1 dòng `ported_from:` ở 6 lệnh QC, phần còn lại đã nằm trong `bin/qc-base-map.json` (snapshot `596149f`) |
|
|
89
|
+
| [x] | Thay gate cắt tay (5.4 KB) bằng `{{include:steps/gate.md}}` (11.1 KB) | 12 file | **0 lệnh còn gate cắt tay.** 31/33 tmpl dùng `{{include:steps/gate.md}}`. Hai lệnh còn lại — `sync`, `update-framework` — không phải cắt tay: chúng **không có gate nào cả**, xem cảnh báo dưới |
|
|
90
|
+
|
|
91
|
+
> ⚠️ **Phát sinh khi đo — KHÔNG thuộc đợt dọn này.** `sync` và `update-framework` đều GHI file
|
|
92
|
+
> (`{service.path}/.agent/project-context.yaml`, `{living_docs_dir}/trace-report.json`, và
|
|
93
|
+
> `--init` copy đè cả `.agent/`) nhưng **không include gate và không có tên trong
|
|
94
|
+
> `gate.checkpoint_levels`** → rơi vào mặc định `normal`, mức lỏng nhất. Đây đúng hình dạng lỗi
|
|
95
|
+
> mà R18 sinh ra để bắt (G67 · G77 · G78 · G79). Xử ở việc **khai nốt registry
|
|
96
|
+
> `artifact_writers`**, không phải ở đây.
|
|
97
|
+
|
|
98
|
+
<details>
|
|
99
|
+
<summary>Cách đếm — chạy lại được, ra đúng số trên</summary>
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# 1 — gate: 31 file có include; 2 file thiếu là sync, update-framework
|
|
103
|
+
grep -l "include:steps/gate.md" commands/*.tmpl | wc -l
|
|
104
|
+
|
|
105
|
+
# 2 — TC_<FEATURE>.md: đúng 2 hit, cả hai trong qc-design-test (phản ví dụ)
|
|
106
|
+
grep -rn 'TC_<FEATURE>.md' skills/ commands/
|
|
87
107
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
108
|
+
# 3 — coverage-evaluator: file đích tồn tại ⇒ tham chiếu không treo
|
|
109
|
+
ls upstream/qc-base/skills/qa-gate/coverage-evaluator.md
|
|
110
|
+
|
|
111
|
+
# 4 — nhãn Checkpoint: 15 có / 18 thiếu trên 33 lệnh
|
|
112
|
+
for f in commands/*.tmpl; do grep -qE '^s**Checkpoint:' "$f" || basename "$f" .tmpl; done | wc -l
|
|
113
|
+
|
|
114
|
+
# 5 — provenance: 0 dòng <!-- ở đầu tmpl
|
|
115
|
+
head -30 commands/*.tmpl | grep -c '^<!--'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Vì sao mục này phải mang theo cách đếm:** không máy nào canh file kế hoạch. `self-check` canh
|
|
119
|
+
schema, `lint-trace` canh sổ trace, `test/run.js` canh build — cả ba xanh trong lúc bảng này sai
|
|
120
|
+
bốn dòng. Ghi kết quả đo mà không ghi cách đo thì người sau vẫn phải đo lại từ đầu, tức ô tích
|
|
121
|
+
không tiết kiệm được gì.
|
|
122
|
+
|
|
123
|
+
</details>
|
|
124
|
+
|
|
125
|
+
## Câu đã chốt với chị QC *(2026-09-16)*
|
|
126
|
+
|
|
127
|
+
| | Câu hỏi | Trả lời | Chặn bước nào |
|
|
128
|
+
|:-:|---|---|---|
|
|
129
|
+
| [x] | `/qc-run-manualtest` ghi kết quả test tay thế nào — nhập từng TC, hay đọc từ file checklist? | **Nhập từng TC.** Nguyên văn: *"ghi kết quả test tay em nhé. Chị sợ đọc checklist mà lệch thông tin lại ghi kết quả sai."* | d2-b2 — **hết chặn** |
|
|
130
|
+
| [x] | Smoke suite đặt tên gì (không được nhầm `/dev-smoke-test` đã có) | **`/qc-smoke-test`** — đúng quy ước hai làn `qc-`/`dev-` | d4-b2 — **hết chặn** |
|
|
131
|
+
| [x] | Ngưỡng dung lượng chốt bao nhiêu | **Không cần hỏi — đo được.** `1309 / 1450 KB` sau d2-b1 (còn 141 KB). Đo lại sau khi viết 3 lệnh của d2-b2 | d2-b2 |
|
|
132
|
+
|
|
133
|
+
> **Vì sao câu 1 quan trọng hơn vẻ ngoài của nó.** Phương án *"đọc file checklist"* nghe tiện hơn
|
|
134
|
+
> (điền offline, nhiều người điền dần), và đó là phương án được khuyến nghị lúc đầu. Chị QC chỉ ra
|
|
135
|
+
> một rủi ro nặng hơn sự tiện: một file điền tay là **nguồn thứ hai có thể trôi** — TC bị đánh số
|
|
136
|
+
> lại sau một lần `/qc-design-test`, TC mới thêm, dòng cũ còn sót — và khi nó lệch thì lệnh ghi
|
|
137
|
+
> `qc_status` cho **đúng SC sai**. Kiểu hỏng đó là **Nói dối** (sổ trace báo `pass` cho scenario
|
|
138
|
+
> chưa ai chạy); cái giá của phương án hỏi-từng-TC chỉ là **Ồn**. Đổi một rủi ro nói dối lấy một
|
|
139
|
+
> rủi ro phiền là đúng chiều, và cùng họ với `positive_assertion_guards` — luật đã có sẵn để
|
|
140
|
+
> **không bao giờ** ghi `pass` khi dữ liệu nền không chắc.
|
|
141
|
+
>
|
|
142
|
+
> **Điều chỉnh giữ nguyên tính an toàn đó:** lệnh **ghi ngay vào sổ trace sau mỗi câu trả lời**,
|
|
143
|
+
> không gom cuối phiên; chạy lại thì chỉ hỏi những SC còn `not_run` — tức **tự resume**. Như vậy
|
|
144
|
+
> sổ trace là nguồn duy nhất (không artifact trung gian nào để trôi) mà vẫn làm được nhiều buổi,
|
|
145
|
+
> nhiều người. Mỗi lần ghi kèm người chạy + ngày, khớp luật *"`pass` phải có bằng chứng"*.
|