@educa-corp/sdd-framework 0.9.7 → 0.9.8
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/qc-base-map.json +13 -11
- package/bin/self-check.js +49 -4
- package/bin/trace-schema.json +3226 -3187
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/qc-analyze.md +2 -2
- package/core/commands/qc-automation-assess.md +3 -3
- package/core/commands/qc-design-script.md +60 -30
- package/core/commands/qc-design-test.md +79 -7
- package/core/commands/qc-plan.md +1 -1
- package/core/commands/qc-report.md +85 -76
- package/core/commands/qc-review-script.md +25 -16
- package/core/commands/qc-review-testcase.md +8 -7
- package/core/commands/qc-run-manualtest.md +1 -1
- package/core/commands/qc-run-script.md +15 -8
- package/core/modules/qc-playwright-ts/module.yaml +13 -0
- package/core/modules/qc-playwright-ts/stack-profile.yaml +99 -0
- package/core/modules/qc-wdio-appium/module.yaml +20 -0
- package/core/modules/qc-wdio-appium/stack-profile.yaml +107 -0
- package/core/skills/qc/qa-analyst/data-flow.md +1 -1
- package/core/skills/qc/qa-automation-assess/matrix.md +6 -3
- package/core/skills/qc/{qa-runner → qa-designer}/exploratory/session.md +8 -2
- package/core/skills/qc/qa-designer/functional/api.md +1 -1
- package/core/skills/qc/qa-designer/functional/job.md +128 -0
- 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/{kafka.md → queue.md} +20 -4
- package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +17 -0
- package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +17 -0
- package/core/skills/qc/qa-reviewer/script/_shared/review-rules.md +121 -0
- package/core/skills/qc/qa-reviewer/script/api/auth.md +49 -0
- package/core/skills/qc/qa-reviewer/script/api/endpoint.md +89 -0
- package/core/skills/qc/qa-reviewer/script/api/security.md +46 -0
- package/core/skills/qc/qa-reviewer/script/exploratory.md +2 -2
- package/core/skills/qc/qa-reviewer/script/mobile/e2e.md +41 -0
- package/core/skills/qc/qa-reviewer/script/mobile/functional.md +90 -0
- package/core/skills/qc/qa-reviewer/script/mobile/integration.md +41 -0
- package/core/skills/qc/qa-reviewer/script/mobile/non-functional.md +43 -0
- package/core/skills/qc/qa-reviewer/script/web/e2e.md +46 -0
- package/core/skills/qc/qa-reviewer/script/web/functional.md +111 -0
- package/core/skills/qc/qa-reviewer/script/web/integration.md +46 -0
- package/core/skills/qc/qa-reviewer/script/web/non-functional.md +49 -0
- package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +1 -1
- package/core/skills/qc/qa-reviewer/shared/review-file-template.md +26 -7
- package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/exploratory.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-script-designer/_shared/api-conventions.md +94 -0
- package/core/skills/qc/qa-script-designer/_shared/file-naming-and-folders.md +109 -0
- package/core/skills/qc/qa-script-designer/_shared/mobile-conventions.md +196 -0
- package/core/skills/qc/qa-script-designer/_shared/web-conventions.md +257 -0
- package/core/skills/qc/qa-script-designer/api/auth.md +43 -0
- package/core/skills/qc/qa-script-designer/api/endpoint.md +61 -0
- package/core/skills/qc/qa-script-designer/api/security.md +41 -0
- package/core/skills/qc/qa-script-designer/mobile/e2e.md +35 -0
- package/core/skills/qc/qa-script-designer/mobile/functional/feature.md +32 -0
- package/core/skills/qc/qa-script-designer/mobile/functional/screen.md +42 -0
- package/core/skills/qc/qa-script-designer/mobile/integration.md +39 -0
- package/core/skills/qc/qa-script-designer/mobile/non-functional.md +39 -0
- package/core/skills/qc/qa-script-designer/web/e2e.md +36 -0
- package/core/skills/qc/qa-script-designer/web/functional/api.md +39 -0
- package/core/skills/qc/qa-script-designer/web/functional/gui-feature.md +34 -0
- package/core/skills/qc/qa-script-designer/web/functional/gui-screen.md +42 -0
- package/core/skills/qc/qa-script-designer/web/integration.md +43 -0
- package/core/skills/qc/qa-script-designer/web/non-functional.md +42 -0
- package/core/skills/qc/qa-script-runner/mobile/run.md +38 -0
- package/core/skills/qc/qa-script-runner/report.md +41 -0
- package/core/skills/qc/qa-script-runner/web/run.md +48 -0
- package/core/steps/qc-scope.md +43 -0
- package/core/steps/report-footer.md +2 -2
- package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +10 -10
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +1 -1
- package/docs/02-concepts/traceability.md +1 -1
- package/docs/03-guides/developer.md +1 -1
- package/docs/03-guides/tester-qa.md +40 -12
- package/docs/04-reference/commands.md +1 -1
- package/docs/04-reference/modules.md +2 -1
- package/docs/explain/17-qc-design-test.md +2 -2
- package/docs/explain/19-qc-run-test.md +4 -4
- package/docs/explain/20-qc-report.md +1 -1
- package/docs/explain/23-fix-bug.md +2 -2
- package/docs/plans/qc-surgery/01-checklist.md +18 -6
- package/docs/plans/qc-surgery/PLAN_v2.md +295 -0
- package/docs/plans/qc-surgery/exec-S-ap-stack-typescript.md +420 -0
- package/docs/plans/qc-surgery/exec-S0-guard-cam-stack-cu.md +400 -0
- package/docs/plans/qc-surgery/exec-S1-hai-module-thay-qc-playwright.md +267 -0
- package/docs/plans/qc-surgery/exec-S2-qa-runner-thanh-script-designer-runner.md +340 -0
- package/docs/plans/qc-surgery/exec-S3-viet-lai-tieu-chi-review-script.md +322 -0
- package/docs/plans/qc-surgery/exec-S5-an-theo-don-dau-vet-stack-cu.md +292 -0
- package/package.json +1 -1
- package/core/modules/qc-playwright/stack-profile.yaml +0 -66
- package/core/skills/qc/qa-reviewer/script/e2e.md +0 -95
- package/core/skills/qc/qa-reviewer/script/functional.md +0 -109
- package/core/skills/qc/qa-reviewer/script/integration.md +0 -99
- package/core/skills/qc/qa-reviewer/script/non-functional.md +0 -134
- package/core/skills/qc/qa-runner/e2e.md +0 -49
- package/core/skills/qc/qa-runner/functional/api.md +0 -35
- package/core/skills/qc/qa-runner/functional/gui-feature.md +0 -57
- package/core/skills/qc/qa-runner/functional/gui-screen.md +0 -61
- package/core/skills/qc/qa-runner/integration.md +0 -47
- package/core/skills/qc/qa-runner/non-functional.md +0 -49
- package/core/skills/qc/qa-runner/report/report.md +0 -37
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: PLAN v2 — phần còn lại của đợt đại phẫu QC
|
|
3
|
+
updated: 2026-09-17
|
|
4
|
+
trang_thai: Đợt 0–2 xong · **Bước S XONG 2026-09-17** · kế tiếp Đợt 3
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# PLAN v2 — cái gì còn lại, theo thứ tự nào, và vì sao
|
|
8
|
+
|
|
9
|
+
← [`01-checklist.md`](01-checklist.md) · [`02-lo-trinh.md`](02-lo-trinh.md) · [`00-nhat-ky.md`](00-nhat-ky.md)
|
|
10
|
+
|
|
11
|
+
> **Vì sao có file này.** `01-checklist.md` theo dõi **bước nào xong**; nó không chứa được
|
|
12
|
+
> *quyết định đã chốt*, *nguồn tài liệu nào dùng cho việc nào*, và *những chỗ bản kế hoạch cũ
|
|
13
|
+
> khai sai*. Ba thứ đó là thứ **quên là làm lại** — và đã suýt xảy ra ba lần *(xem §5)*.
|
|
14
|
+
>
|
|
15
|
+
> **Cách dùng:** trước mỗi bước, đọc §3 *(thứ tự)* → §4 *(nguồn)* → §5 *(bẫy đã biết)*. Sau mỗi
|
|
16
|
+
> bước, cập nhật §1 và §2.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1 · Hiện trạng đo được — 2026-09-17 *(sau Bước S)*
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
lệnh 37 · trong đó QC 10
|
|
24
|
+
skill qc 78 file · qa-script-designer 18 · qa-script-runner 3 · qa-reviewer/script 13
|
|
25
|
+
module qc 2 · qc-playwright-ts (web+api) · qc-wdio-appium (app)
|
|
26
|
+
rule self-check R1–R22 + forbidden_patterns 17 entry (11 cũ + 6 của S0, có trường scope)
|
|
27
|
+
test 244/244 PASS
|
|
28
|
+
ngân sách 1372 / 1450 KB (còn 78 KB)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> **Bốn lệnh kiểm XANH cả bốn** từ 2026-09-17 — lần đầu kể từ khi dựng đèn S0. Trong suốt Bước S
|
|
32
|
+
> `self-check` cố ý đỏ *(`G3`)*, và số đỏ giảm đúng theo từng việc: **27 → 19 → 18 → 14 → 9 → 2 → 0**.
|
|
33
|
+
|
|
34
|
+
> **Phép đếm của ngân sách** *(`test/run.js:697`)*: tổng `size` của **`core/commands/*.md`** —
|
|
35
|
+
> **chỉ thế**. `core/skills/` **không** tính. Nên thêm skill không chạm ngưỡng; rủi ro duy nhất
|
|
36
|
+
> là **3 file lệnh** phình lên. Ghi rõ ở đây vì đã đọc nhầm thành *"cả bộ"* một lần.
|
|
37
|
+
|
|
38
|
+
**Bốn lệnh kiểm phải xanh sau mỗi bước:**
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
node bin/build.js # đúc .tmpl → .md → core/
|
|
42
|
+
node bin/self-check.js # R1–R22
|
|
43
|
+
node test/run.js # 244 test
|
|
44
|
+
node bin/lint-trace.js # T1–T20 trên sổ trace thật
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 2 · Lệnh QC: cái nào **đúng và đủ**, cái nào chưa
|
|
50
|
+
|
|
51
|
+
> **"Chạy được" ≠ "đúng và đủ".** Một lệnh sinh output theo stack đã bị thay thì **chưa xong**,
|
|
52
|
+
> dù mọi rule đều xanh. Bảng này dùng tiêu chí thứ hai.
|
|
53
|
+
|
|
54
|
+
| # | Lệnh | Trạng thái | Chặn bởi |
|
|
55
|
+
|:-:|---|---|---|
|
|
56
|
+
| 1 | `/qc-analyze` | ✅ đủ | — |
|
|
57
|
+
| 2 | `/qc-plan` | ✅ đủ | — |
|
|
58
|
+
| 3 | `/qc-design-test` | ✅ đủ | — |
|
|
59
|
+
| 4 | `/qc-review-testcase` | ✅ đủ *(mới, Đợt 2 b1)* | — |
|
|
60
|
+
| 5 | `/qc-automation-assess` | ✅ đủ *(mới, Đợt 2 b3)* | — |
|
|
61
|
+
| 6 | `/qc-design-script` | ✅ đủ *(Bước S · S2+S4)* — sinh theo nền, 3 lane | — |
|
|
62
|
+
| 7 | `/qc-review-script` | ✅ đủ *(Bước S · S3)* — tiêu chí theo nền, severity + 4 verdict | — |
|
|
63
|
+
| 8 | `/qc-run-script` | ✅ đủ *(Bước S · S2+S4)* | — |
|
|
64
|
+
| 8b | `/qc-run-manualtest` | ✅ đủ *(mới, Đợt 2 b2)* | — |
|
|
65
|
+
| 9 | `/qc-report` | ❌ bản cũ — chưa có coverage kép + verdict | **Đợt 3** |
|
|
66
|
+
|
|
67
|
+
**QC test được ngay hôm nay — một lát cắt dọc trọn vẹn, không chạm stack:**
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
1 analyze → 2 plan → 3 design-test → 4 review-testcase → 5 automation-assess
|
|
71
|
+
→ 6 design-script → 7 review-script → 8 run-script ∥ 8b run-manualtest
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Tám trạm đầu đã đúng và đủ.** Chỉ `/qc-report` *(trạm 9)* còn chờ Đợt 3. Phép thử quyết định
|
|
75
|
+
vẫn như cũ: chạy hết rồi mở sổ trace — **mọi SC của TC `Automatable: N` phải có
|
|
76
|
+
`qc_status ≠ not_run`**.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 3 · Thứ tự còn lại
|
|
81
|
+
|
|
82
|
+
### ✅ Bước S — Áp stack đã chốt · **XONG 2026-09-17**
|
|
83
|
+
|
|
84
|
+
Sáu việc, bốn commit, thứ tự `S-ORDER`: **S0 → S1 → S5 → S3 → S2 → S4**.
|
|
85
|
+
|
|
86
|
+
| Việc | Làm gì | Đèn sau đó |
|
|
87
|
+
|---|---|:-:|
|
|
88
|
+
| **S0** | Đèn cơ học cấm dấu vết stack cũ — 6 entry `forbidden_patterns` có trường `scope` mới, chạy qua `R5` sẵn có | 27 → 19 |
|
|
89
|
+
| **S1** | `qc-playwright` **gỡ** → `qc-playwright-ts` *(web+api)* + `qc-wdio-appium` *(app)*; bảng phân giải nền vào `qc-scope.md` §2b | 18 |
|
|
90
|
+
| **S5** | Dọn ăn theo *(4 lệnh · `trace-schema` · `qc-base-map` · 5 `docs/`)* + **đánh số lại dây chuyền 10 trạm** | 14 |
|
|
91
|
+
| **S3** | `qa-reviewer/script/` 5 file phẳng → **xoá, viết mới** 12 file theo 3 nền + `_shared/review-rules.md` | 9 |
|
|
92
|
+
| **S2** | `qa-runner` **gỡ** → `qa-script-designer` *(18)* + `qa-script-runner` *(3)* | 2 |
|
|
93
|
+
| **S4** | 2 lệnh cuối: gỡ bảng `testid_attr` trùng bản, đổi 6 dòng còn lại | **0** ✅ |
|
|
94
|
+
|
|
95
|
+
Hồ sơ: [`exec-S`](exec-S-ap-stack-typescript.md) · [`S0`](exec-S0-guard-cam-stack-cu.md) ·
|
|
96
|
+
[`S1`](exec-S1-hai-module-thay-qc-playwright.md) · [`S2`](exec-S2-qa-runner-thanh-script-designer-runner.md) ·
|
|
97
|
+
[`S3`](exec-S3-viet-lai-tieu-chi-review-script.md) · [`S5`](exec-S5-an-theo-don-dau-vet-stack-cu.md)
|
|
98
|
+
|
|
99
|
+
**Chín quyết định** sinh ra ở bước này, xem §7: `S-API` · `H1` · `H2` · `H3` · `S-SCOPE` ·
|
|
100
|
+
`S3′` · `S-PATH` · `S-VERDICT` · `S-ORDER` · `S-SHARED`.
|
|
101
|
+
|
|
102
|
+
> **Ba điều Bước S dạy được, ghi ở đây vì chúng áp cho Đợt 3 và 4:**
|
|
103
|
+
>
|
|
104
|
+
> **① Dựng đèn trước, dọn sau** *(`G3`)* — và **lấy số đỏ làm thước đo tiến độ**, không chỉ làm
|
|
105
|
+
> cổng chặn. Mỗi việc phải làm con số giảm **đúng bằng phần nó nhận**; giảm ít hơn là sót, nhiều
|
|
106
|
+
> hơn là đã lấn sang việc khác. Phép này bắt được lỗi **ba lần** trong Bước S.
|
|
107
|
+
>
|
|
108
|
+
> **② Cảnh báo `scope khớp 0 file`** chạy đúng cả hai chiều: tự tắt khi thư mục ra đời, tự bật
|
|
109
|
+
> khi thư mục bị xoá. Bật lên **chính là bằng chứng** việc xoá đã xảy ra thật.
|
|
110
|
+
>
|
|
111
|
+
> **③ Đèn có ba giới hạn đã biết** — nó canh **tên công nghệ**, nên **không** bắt được: luật đã
|
|
112
|
+
> hết đúng mà không chứa tên nào *(ca "Không Allure")* · hai file của ta nói khác nhau *(ca
|
|
113
|
+
> `stack-profile` ↔ tiêu chí review)* · port hụt một mục. Cả ba ghi ở §3 nợ. **Chưa dựng rule
|
|
114
|
+
> cho chúng** — chưa biết có tái diễn không.
|
|
115
|
+
|
|
116
|
+
### Đợt 3 — `/qc-report`
|
|
117
|
+
|
|
118
|
+
Coverage kép + 8 ngưỡng + verdict `PASS`/`FAIL`/`INCOMPLETE`. Phụ thuộc **cứng** vào d2-b2 *(đã
|
|
119
|
+
xong)* và **nên chờ Bước S** — verdict dựng trên kết quả của `/qc-run-script`, đừng dựng trên
|
|
120
|
+
một trạm còn sai stack.
|
|
121
|
+
|
|
122
|
+
File: [`exec-d3-b1-qc-report-gate-decision.md`](exec-d3-b1-qc-report-gate-decision.md)
|
|
123
|
+
|
|
124
|
+
### Đợt 4 — 4 bước utility
|
|
125
|
+
|
|
126
|
+
| Bước | Việc | Trạng thái chặn |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| d4-b1 | `/qc-design-testdata` | phụ thuộc d2-b3 ✅ |
|
|
129
|
+
| d4-b2 | **`/qc-smoke-test`** | ✅ **hết chặn** — chị QC chốt tên 2026-09-16. Trạm 6 đã gắn tag `@smoke` cho `P0` |
|
|
130
|
+
| d4-b3 | `/qc-metrics` + `bin/lint-metrics.js` | — |
|
|
131
|
+
| d4-b4 | `bin/lint-spec.js` — máy quét injection | phụ thuộc d1-b5 ✅ |
|
|
132
|
+
|
|
133
|
+
### Nợ độc lập — làm lúc nào cũng được
|
|
134
|
+
|
|
135
|
+
| Việc | Đo được |
|
|
136
|
+
|---|---|
|
|
137
|
+
| **18 lệnh thiếu nhãn `*Checkpoint: …*`** | 19/37 có nhãn. Số cũ trong checklist ghi "6 file" — sai gấp 3 |
|
|
138
|
+
| Sửa `08-qc-automation.md` + `tester-qa.md`: *"Trạm 1–4 chưa cần code"* | Đúng phải là **1–7**; chỉ **8 · 8b · 9** cần app chạy được |
|
|
139
|
+
| `docs/explain/18-qc-review.md` · `19-qc-run-test.md` **giải thích 2 lệnh đã bị tách bỏ ở Đợt 2** | `commands/` không còn `qc-review.tmpl` · `qc-run-test.tmpl`; 5 lệnh mới chưa có file `explain` *(phát hiện 09-16 khi soạn Bước S)* |
|
|
140
|
+
| **Lane DEV:** `generate-bdd.tmpl:270` suy `active_platform` theo *"`platform_type` của stack-profile"* | **0/16 module khai `platform_type`** — luật trỏ vào field không tồn tại ở đâu. Đúng lớp lỗi `R1`/`R3` nhưng ngoài tầm chúng *(phát hiện 09-17 khi soạn S1)* |
|
|
141
|
+
| 🔴 **Lane INSTALLER — `G44` thoái hoá im lặng.** `.gitignore:23` loại `.agent/.install-manifest.json` khỏi git, trong khi `index.js:624` dặn *"Commit `.agent/` to git"*. Manifest lệch với đĩa trên mọi máy khác ⇒ điều kiện (3) *"hash khớp manifest"* sai với **cả file chưa ai đụng** ⇒ prune backup-rồi-giữ thay vì xoá | **Bằng chứng 09-17:** `.agent/modules/qc-playwright/stack-profile.yaml` `sha1=e195bcc8…`, `git diff HEAD` **trống** (không ai sửa), vẫn bị xếp *"đã sửa"* và giữ lại sau `--init`. Hệ quả: lệnh bị bỏ **vì nó sai** vẫn nằm trong `.claude/commands/` của cả đội. Hướng xử: đưa manifest vào git, **hoặc** đối chiếu theo `core/` thay vì theo manifest |
|
|
142
|
+
| **4 lệnh kiểm không phủ `.agent/`** | `build.js` dựng `core/`; chỉ `--init` đồng bộ sang `.agent/` kèm prune. Sau một bước **xoá** file framework, phải chạy thêm `node bin/index.js --init` rồi kiểm `.agent/` *(09-17)* |
|
|
143
|
+
| ~~`tech_stack.qc_module` hứa trong comment~~ | ✅ **XONG** — file mang comment đó đã bị gỡ cùng `modules/qc-playwright/` ở S1; cơ chế chọn module nay là bảng §2b của `steps/qc-scope.md` |
|
|
144
|
+
| 🟡 **5 chỗ khác còn dùng mẫu "im lặng khi đạt"** | `qc-design-script:134,141` · `qc-review-testcase:94,106` · `qc-stamp:101,134`. **Chưa sửa** — chúng không phải cổng vào cửa mà là guard *có phạm vi* (*"không có §4.5 → không kiểm gì"*), và chúng chạy giữa một lệnh đã in nhiều thứ khác nên bỏ qua vẫn thấy. Rà lại nếu có ca thật *(09-17, `G-GATE`)* |
|
|
145
|
+
| 🔴 **Lane `job` · `queue` có TC nhưng CHƯA có bộ sinh script** | Trạm 3 hỗ trợ đủ 3 hình dạng; trạm 6 mới có lane `api`. Đã cắm cổng: trạm 6 **DỪNG** khi gặp TC lane `job`/`queue` thay vì lặng lẽ sinh API Object cho thứ không có endpoint. Đường vòng hiện tại: chạy tay qua `/qc-run-manualtest`, hoặc đánh `Automatable: N` kèm lý do. **Mở lane script khi có dự án thật cần** *(09-17, ca LESS-22)* |
|
|
146
|
+
| 🟡 **Từ vựng System BDD chỉ có trigger "ngoài gọi vào"** | `generate-bdd.tmpl:197` cho đúng hai dạng — `the system receives {event}` · `a {actor} submits {action}`. Đo: `schedule`·`cron`·`định kỳ`·`queue` = **0 lần**. Nên BDD của một job **bị ép** viết như thể có người gọi, và đó là gốc của ca LESS-22. Bù bằng câu hỏi ở trạm 3 *(`S-SHAPE`)*; **sửa gốc là lane DEV**, chưa làm *(09-17)* |
|
|
147
|
+
| 🟡 **Không rule nào đối chiếu `stack-profile` với tiêu chí review** | S3 chốt `S-PATH` làm **5 dòng của S1 hết đúng** *(`tests/<feature>/` → `tests/{TICKET-ID}/`)*, và không gì bắt được — chỉ lộ khi đọc lại bằng mắt. Đèn canh **tên công nghệ**, không canh **hai file của ta nói khác nhau**. **Chưa dựng rule** — chưa biết lớp lỗi này có tái diễn không *(09-17, S2 §0.4②)* |
|
|
148
|
+
| 🟡 **Đèn không bắt được luật đã hết đúng nếu nó không chứa tên công nghệ** | Ca thật: `qc-review-script.tmpl` từng ghi *"Không Allure"* *(nay sai với mobile)* và thứ tự locator của web áp cho cả ba nền. Cả hai **không** chứa chữ bị cấm nên `R5` im *(09-17, S3 B5)* |
|
|
149
|
+
| 🟡 **Đèn không bắt được "port hụt một mục"** | File thiếu mục vẫn hợp lệ, vẫn được nạp, vẫn sinh script chạy được. Thứ duy nhất canh là **đếm lại từng mục trên bộ mới** — đã làm ở S2 #4, nhưng đó là phép thủ công, không có rule *(09-17)* |
|
|
150
|
+
| **`docs/` nằm ngoài phạm vi đèn** | Cố ý *(S0 §1.2)*: `docs/` là nơi duy nhất **cần** nói *"trước đây là X"*. Giá phải trả: stack cũ quay lại qua đường tài liệu thì không ai biết. Rà lại sau Đợt 4 |
|
|
151
|
+
| **Nhóm A + D** — 4 dòng ở 5 tầng tài liệu vẫn khai stack cũ | `qa-planner/test-plan.md` ×3 *(Test Plan là tài liệu chị QC **ký** — đang mô tả `pytest-html`)* · `qa-reviewer/test-case/functional.md:18` ×1. Ngoài tầm đèn sau `S-SCOPE`, không chặn ai *(09-17)* |
|
|
152
|
+
| **Nhóm B** — 10 dòng `@pytest.mark.flaky` / `conftest.py` làm quy ước viết TC | **Chủ: chị QC.** Không phải đổi cú pháp: `@pytest.mark.flaky(reruns=2)` = *tự chạy lại, vẫn trong suite*; `@flaky` của chuẩn mới §11 = *quarantine, exclude khỏi main suite*. Cộng thêm: **retry ×2 đã chuyển sang runner ở Đợt 1 b3** → marker là nguồn thứ hai cho cùng một quyết định. **Hệ quả đang chấp nhận:** `.Test.md` dặn ghi marker pytest mà script TS không hiểu *(09-17)* |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 4 · Nguồn tài liệu — cái nào dùng cho việc nào
|
|
157
|
+
|
|
158
|
+
### 4.1 `upstream/qc-base-new/` — chị trưởng phòng QC gửi, **7 file** *(mới nhận 2026-09-16)*
|
|
159
|
+
|
|
160
|
+
| File | Status | Dùng cho |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| **`Automation-Standards.md`** *(527 dòng)* | Approved | **Bước S — web.** §1 Tech Stack · §2 Project Structure · §4 Page Object · §5 Test Spec · §6 Locator · §7 Assertion · §8 Wait · §9 Code Quality · §10 Anti-patterns · §11 Flaky Policy |
|
|
163
|
+
| **`Mobile-Automation-Standards.md`** *(656 dòng)* | Approved | **Bước S — mobile.** Thêm §6 API Helper · §9 Gesture Helper · §12 Environment Validation Checklist |
|
|
164
|
+
| **`API-Testing-Standards.md`** *(714 dòng)* | Approved | **Bước S — lane API** *(xem ⚠️ dưới)*. §4 API Object Pattern · §8 Test Design Techniques · §9 Security Testing |
|
|
165
|
+
| `AGT-005-automation_builder.md` | Draft | làm giàu **`/qc-design-script`** — Skills Inventory · Rules · Boundary · Error Handling · Evaluation Criteria |
|
|
166
|
+
| `AGT-010-api_automation_builder.md` | **Approved** | nhánh **API** của `/qc-design-script` |
|
|
167
|
+
| `AGT-006-code_reviewer.md` | Draft | làm giàu **`/qc-review-script`** — *"quality gate tự động, KHÔNG sửa code, chỉ phân tích và report"*, có **scoring rules** |
|
|
168
|
+
| `AGT-007-defect_analyzer.md` | Draft | **CHƯA CÓ LỆNH TƯƠNG ỨNG** — gần `/qc-metrics` (d4-b3). Xem §6 |
|
|
169
|
+
|
|
170
|
+
> **Ba file Standards là nguồn TỐT HƠN bộ đề xuất** cho Bước S: chúng là *Official Project
|
|
171
|
+
> Knowledge*, status **Approved**, và nêu cả phiên bản cụ thể *(Appium v2.x · WebdriverIO v9.x ·
|
|
172
|
+
> TypeScript v5.x · UiAutomator2)*. Bộ đề xuất chỉ nói tên stack.
|
|
173
|
+
|
|
174
|
+
> ⚠️ **PHÁT SINH — lane API là nhánh thứ BA.** `API-Testing-Standards.md` khai một *API Object
|
|
175
|
+
> Pattern* riêng và `AGT-010` là agent riêng (**Approved**, không phải Draft). Framework hiện chỉ
|
|
176
|
+
> tách `web`/`mobile`. Cần quyết: API là **nền thứ ba** *(`qa-script-designer/api/*`)* hay là
|
|
177
|
+
> **một layer trong web** *(đã có `qa-designer/functional/api.md` + `qa-designer/api/*`)*.
|
|
178
|
+
> **Chưa chốt — không tự quyết.**
|
|
179
|
+
|
|
180
|
+
### 4.2 `D:\base\qcframework_proposal\` — đề xuất của đội QC
|
|
181
|
+
|
|
182
|
+
12 file lệnh + `skills/qc/{qa-script-designer,qa-script-runner,qa-automation-assess,qa-testdata,qa-metrics,_shared}`.
|
|
183
|
+
Vẫn dùng cho **bố cục thư mục skill** và **khuôn lệnh**; phần **nội dung stack** ưu tiên
|
|
184
|
+
`qc-base-new/` vì nó Approved.
|
|
185
|
+
|
|
186
|
+
### 4.3 `upstream/qc-base/` — bản port gốc
|
|
187
|
+
|
|
188
|
+
Provenance ở `bin/qc-base-map.json` *(snapshot `596149f`)*. Chỉ tra cứu lịch sử.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## 5 · Bẫy đã biết — đọc trước mỗi bước
|
|
193
|
+
|
|
194
|
+
### Bẫy 1 · **Bản kế hoạch mang số đo thì có hạn dùng, và nó không tự báo**
|
|
195
|
+
|
|
196
|
+
Ba lần liên tiếp:
|
|
197
|
+
|
|
198
|
+
| Kế hoạch | Khai | Thật |
|
|
199
|
+
|---|---|---|
|
|
200
|
+
| `exec-d2-b1` | `grep '"qc-review"' schema` → **0**, *"tách không đụng schema"* | **3** *(7 chỗ kể cả nhắc tên)* |
|
|
201
|
+
| `exec-d2-b2` | `qc-run-test` xuất hiện **21 chỗ** | **34** |
|
|
202
|
+
| `exec-d2-b2` §4.6 | 5 việc dọn bắt buộc | **4/5 đã xong từ trước** |
|
|
203
|
+
| **`PLAN_v2` §3** *(chính file này!)* | `qa-runner` **6 file · 44 KB** → đích **12 file · 88 KB** | **8 file · 26.3 KB** → **14 file · 56.5 KB** |
|
|
204
|
+
|
|
205
|
+
**Luật:** chạy lại **mọi lệnh đếm** trong kế hoạch **trước** khi làm theo nó.
|
|
206
|
+
|
|
207
|
+
> 🔴 **Lần thứ tư, và lần này nạn nhân là chính file viết ra luật.** Nguyên nhân thật: số được
|
|
208
|
+
> **chép từ bản kế hoạch trước** chứ không đo lại. Viết luật ra không miễn nhiễm với luật đó.
|
|
209
|
+
> Từ nay **mọi `exec-*` mở đầu bằng một bảng đo lại**, kể cả khi bản trước vừa viết hôm qua.
|
|
210
|
+
|
|
211
|
+
### Bẫy 2 · Một lệnh **không phải là file của nó**
|
|
212
|
+
|
|
213
|
+
`{{include:steps/*}}` mang theo thao tác ghi. Kết luận *"lệnh này không ghi gì"* chỉ có giá trị
|
|
214
|
+
khi đo trên bản **đã đúc** (`core/commands/*.md`). *(Đã sai một lần với `/review-code` và
|
|
215
|
+
`/debug` — cả hai ghi `{lessons_path}` qua `capture-lesson.md`.)*
|
|
216
|
+
|
|
217
|
+
### Bẫy 3 · Kế hoạch mô tả sai **bản chất** thứ nó định giữ
|
|
218
|
+
|
|
219
|
+
`exec-d2-b2` §4.4 khai `skills/qc/qa-runner/**` là *"bộ hướng dẫn chạy test"*, **9 file**, kết
|
|
220
|
+
luận **GIỮ**. Thật ra: **6 file**, và là bộ **SINH MÃ Python** — dòng đầu file:
|
|
221
|
+
*"Gen Script — convert `.Test.md` → Python pytest + Playwright"*.
|
|
222
|
+
Nó là **đối tượng phải thay**, không phải thứ giữ lại.
|
|
223
|
+
|
|
224
|
+
### Bẫy 4 · `{{include:…}}` là **chỉ thị**, không phải chữ
|
|
225
|
+
|
|
226
|
+
Viết nó xen trong câu *(vd để giải thích lệnh ghi file ở đâu)* làm build **inline nguyên file**
|
|
227
|
+
vào giữa câu — một dòng Checkpoint từng nuốt trọn 113 dòng. Có test canh *(`test/run.js`)*.
|
|
228
|
+
|
|
229
|
+
### Bẫy 5 · Hỏi *"tách được không"* khác hỏi *"tách rồi cái còn lại có dùng được không"*
|
|
230
|
+
|
|
231
|
+
**F3** kết luận tách commit đổi-stack là đúng *(ràng buộc nguyên tử chỉ áp cho tên lệnh ↔
|
|
232
|
+
contract)*. Đúng về commit — nhưng để lại **3 lệnh sinh output theo stack đã bỏ**, tức **chưa
|
|
233
|
+
xong**. Ràng buộc nguyên tử nói về **thứ tự commit**, không nói về **độ hoàn thành**.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 6 · Câu chưa có lời đáp
|
|
238
|
+
|
|
239
|
+
> **Bốn câu chặn Bước S đã chốt 2026-09-17** → chuyển xuống §7 với mã `S-API` · `H1` · `H2` ·
|
|
240
|
+
> `H3`. Bằng chứng và các phương án không chọn giữ ở
|
|
241
|
+
> [`exec-S-ap-stack-typescript.md §1`](exec-S-ap-stack-typescript.md).
|
|
242
|
+
|
|
243
|
+
| Câu | Chặn gì | Ai trả lời |
|
|
244
|
+
|---|---|---|
|
|
245
|
+
| **`AGT-007-defect_analyzer` đưa vào đâu?** — *"intelligence layer, chuyển defect data thành insight, feed back vào Knowledge Base"*. Gần `/qc-metrics` (d4-b3) nhưng rộng hơn | d4-b3 | anh + chị QC |
|
|
246
|
+
| Ngưỡng dung lượng khi vượt 1450 KB | bất kỳ bước nào | đo lại rồi chốt, **kèm lý do đo được** |
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 7 · Quyết định đã chốt — đừng mở lại
|
|
251
|
+
|
|
252
|
+
| Mã | Quyết định | Ngày |
|
|
253
|
+
|---|---|---|
|
|
254
|
+
| **D1** | `writes` là **list object**, `mode`+`regenerable` ở **cấp artifact** | 09-15 |
|
|
255
|
+
| **D4** | thêm `when` ở cấp artifact; luật (B) chỉ ép `hard` khi `when: always` | 09-15 |
|
|
256
|
+
| **E1** | tái cấu trúc skill `script/` → `web`/`mobile` **dời sang Bước S** | 09-16 |
|
|
257
|
+
| **E2** | `/qc-review-script` ghi **file riêng** `REVIEW_SCRIPT_<FEATURE>.md` | 09-16 |
|
|
258
|
+
| **E3** | gỡ `/qc-review` ngay, không giữ cầu | 09-16 |
|
|
259
|
+
| **F1** | `/qc-run-manualtest` **hỏi từng TC**, ghi ngay, tự resume — **không** đọc file checklist *(chị QC: "sợ đọc checklist mà lệch thông tin lại ghi kết quả sai")* | 09-16 |
|
|
260
|
+
| **F2** | `positive_assertion_guards.owner` thành **mảng** *(hai chủ cho cột `qc_status`)* | 09-16 |
|
|
261
|
+
| **G1** | `Automatable` sống ở **đúng một chỗ** — `AUTOMATION_ASSESSMENT.md` | 09-16 |
|
|
262
|
+
| **G2** | `/qc-automation-assess` mức **`hard` + narrowing** | 09-16 |
|
|
263
|
+
| **G3** | dựng rule **trước** khi vá, để chứng minh nó bắt lỗi đang sống | 09-16 |
|
|
264
|
+
| **S-API** | lane API là **nền thứ ba ở tầng skill** (`qa-script-designer/api/*`, khoá theo `active_platform: system`) nhưng **dùng chung module `qc-playwright-ts`** — cùng Playwright+TS *(AD-API-001)*, hai module là chép hai lần một dãy phiên bản. `qa-designer/api/*` **không bị đụng** (khác trục: thiết kế TC ≠ sinh mã) | **09-17** |
|
|
265
|
+
| **H1** | Bước S đổi **lệnh + module cho cả 3 lane trong một commit** *(Bẫy 5)*; **nội dung skill khác độ sâu** — web+api đầy đủ, mobile port khung. Lane mobile **phải tự khai là hẹp** *(§8 luật 4)* | **09-17** |
|
|
266
|
+
| **H2** | **gỡ hẳn** `modules/qc-playwright` — theo tiền lệ `E3`; 3/82 entry `qc-base-map` đều `targets: []` nên `R16` không đỏ | **09-17** |
|
|
267
|
+
| **H3** | **không** port `qa-script-runner/smoke.md` ở Bước S — để **d4-b2**, tránh skill mồ côi | **09-17** |
|
|
268
|
+
| **S-SCOPE** | Đổi stack **chỉ ở tầng script** *(trạm 5–9)*, theo `qc-base-new`. **5 tầng tài liệu KHÔNG đổi**: phân tích yêu cầu · doc-gap · test plan · thiết kế TC · review TC. Căn cứ đo được: 5 tầng đó là **41 file · 0 file chạy được** (100 % `.md`), **0 lệnh QC gọi script framework**, và `qc-base-new` **không nhắc Python một lần nào** — nên *"Python vs TypeScript"* không phải một trục có thật ở đấy. Phạm vi đèn S0 thu theo: **đỏ 27 → 19 file** | **09-17** |
|
|
269
|
+
| **S-PATH** | Bố cục thư mục test: **gốc theo chuẩn Approved, `tests/` phân tách theo `{TICKET-ID}`, `pages/`·`api/`·`screens/` để PHẲNG**. Bất đối xứng có chủ ý: một spec **thuộc về** một PRD; một Page Object **được dùng bởi** nhiều PRD. **KHÔNG khai `qc_automation_dir`** — gốc đã nằm ở `§layout` của module *(cùng lập luận đã bỏ `tech_stack.qc_module`)*. Bộ đề xuất dùng key này ở **29 file**, `R4` là lưới bắt | **09-17** |
|
|
270
|
+
| **S-VERDICT** | Lane QC dùng **4 verdict** của `AGT-006` cho **cả** `/qc-review-testcase` lẫn `/qc-review-script`; lane DEV **giữ 2**. Verdict suy từ **số đếm severity**, không từ điểm; điểm `XX/100` giữ để so hai vòng. Ngưỡng đi tiếp **`≥ APPROVED_WITH_SUGGESTIONS`** *(`AGT-005:132`)*. Ánh xạ nhãn cũ: `FAIL ≡ BLOCKER ∪ MAJOR` · `WARN ≡ MINOR ∪ SUGGESTION` | **09-17** |
|
|
271
|
+
| **S-ORDER** | Thứ tự Bước S đổi thành **S0→S1→S5→S3→S2→S4**. Đo được: **16/18 file đỏ không có phụ thuộc nào** — chỉ S4 bị ép. Lý do đổi: S5 rẻ và đã được S1 quyết hết; **S3 trước S2** là `G3` áp ở tầng nội dung *(viết tiêu chí chấm trước bộ sinh)*. **Đã trả cổ tức**: S3 lộ ra `S-PATH` — một quyết định S2 phụ thuộc, mà nếu làm S2 trước thì bộ sinh đã nướng sẵn một câu trả lời | **09-17** |
|
|
272
|
+
| **G-GATE** | **Cổng vào cửa PHẢI in bằng chứng, kể cả khi đạt.** Mẫu cũ *"đủ → im lặng, đi tiếp"* nghe hợp lý *(cổng là điều kiện, không phải phép đo)* nhưng **cổng đạt trong im lặng không phân biệt được với cổng chưa bao giờ chạy**. Ca thật 09-17: lệnh chạy khi `qc_artifact_dir` **chưa tồn tại**, tự tường thuật *"đủ ba file đầu vào"*, đi tiếp, không dấu vết. Phân biệt: **phép đo** in con số · **cổng vào cửa** in bằng chứng đã chạy. Cổng không bằng chứng thì nó là một lời đề nghị | **09-17** |
|
|
273
|
+
| **S-SHAPE** | `system` **KHÔNG đồng nghĩa với API** — nó có ít nhất **ba hình dạng**: `api` *(ai đó gọi vào)* · `job` *(tự chạy theo lịch)* · `queue` *(nằm chờ message)*. Sửa `S-API`, vốn ánh xạ `system → api` vô điều kiện. **Máy không suy được** vì từ vựng System BDD (`generate-bdd.tmpl:197`) chỉ có hai trigger, **cả hai đều là "ngoài gọi vào"** — nên **QC trả lời ở trạm 3**, câu trả lời ghi vào `Tags` → `<lane>`, trạm 5/6 **ĐỌC chứ không suy lại**. Chỉ hỏi khi `system` **và** 0 dấu hiệu endpoint; `--yes` thì DỪNG. **Cố ý KHÔNG sửa `generate-bdd`** *(lane DEV, đổi mọi dự án, BDD đã viết không tự đổi)* — bù bằng người, và nếu về sau nhiều dự án dạng job thì lúc đó sửa gốc mới đáng | **09-17** |
|
|
274
|
+
| **S-SHARED** | Luật dùng cho nhiều file thì viết **một bản** ở `_shared/`, file lane trỏ vào. Áp ở ba chỗ: `qa-reviewer/script/_shared/review-rules.md` *(11 lane dùng)* · `qa-script-designer/_shared/*-conventions.md` · bảng `testid_attr` **gỡ khỏi lệnh** ở S4 vì nó từng có hai bản và hai bản **đã lệch nhau** | **09-17** |
|
|
275
|
+
| **S3′** | `qa-reviewer/script/` — **xoá 5 file, viết mới**, không vá. Vì mật độ nhiễm **11,2 %** và **9,2 %** ở 2 file: tái bố cục dưới tên *"sửa"* dẫn thẳng vào bẫy B1 *(đúng từ vựng TS, đúng cấu trúc Python)* | **09-17** |
|
|
276
|
+
| — | smoke suite tên **`/qc-smoke-test`** *(chị QC)* | 09-16 |
|
|
277
|
+
| — | stack **TypeScript** + Playwright/WDIO+Appium — *chốt chính thức, xác nhận email* | **09-10** |
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 8 · Luật vẫn giữ nguyên qua mọi bước
|
|
282
|
+
|
|
283
|
+
1. ~~**Mỗi commit đều xanh** — 4 lệnh kiểm.~~ → **sửa 2026-09-17 (`S-WIP`):**
|
|
284
|
+
**Không mở PR, không publish khi 4 lệnh kiểm chưa xanh.** Commit WIP trên **nhánh việc** thì
|
|
285
|
+
được, miễn nhãn ghi rõ đỏ vì sao.
|
|
286
|
+
*Vì sao đổi:* đèn `S0` đỏ **theo thiết kế** (`G3`) và **chỉ hết đỏ khi S5 xong** — nên luật cũ
|
|
287
|
+
ép phơi toàn bộ S0→S5 ngoài git. Đã phơi **19 giờ / 29 file**, và một session của đợt này
|
|
288
|
+
**đã chết vì hết token**. Đo chỗ luật thật sự cắn: `npm run build` = `build.js && self-check.js`
|
|
289
|
+
→ đỏ ⇒ **chặn `prepublishOnly`**; CI `on: pull_request` *(mọi nhánh)* + `push: branches:[main]`
|
|
290
|
+
⇒ **`git push` lên nhánh việc KHÔNG kích CI**. Đường chung gãy ở **PR và publish**, không ở
|
|
291
|
+
từng commit của nhánh việc — nên luật mới **chặt hơn ở đúng chỗ**, lỏng hơn ở chỗ không ai đau.
|
|
292
|
+
2. **Trình bày trước → duyệt → mới làm**, theo khuôn `_TEMPLATE-BUOC.md` của `sdd-re-engine`.
|
|
293
|
+
3. **Ngân sách cổng cứng vô điều kiện = 3.** Vượt là `R20` đỏ; nâng được nhưng phải kèm lý do —
|
|
294
|
+
và đó là **một quyết định, không phải một hệ quả**.
|
|
295
|
+
4. **Khai một phạm vi hẹp và nói rõ là hẹp** thì trung thực hơn khai đầy đủ mà chưa rà.
|