@educa-corp/sdd-framework 0.9.6 → 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/lint-trace.js +4 -4
- package/bin/qc-base-map.json +13 -11
- package/bin/self-check.js +497 -16
- package/bin/trace-schema.json +3226 -2656
- 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 +430 -0
- package/core/commands/qc-design-test.md +98 -20
- package/core/commands/qc-plan.md +9 -3
- package/core/commands/qc-report.md +92 -77
- package/core/commands/qc-review-script.md +342 -0
- package/core/commands/{qc-review.md → qc-review-testcase.md} +86 -54
- package/core/commands/qc-run-manualtest.md +401 -0
- package/core/commands/qc-run-script.md +421 -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-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/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/data-flow.md +1 -1
- package/core/skills/qc/qa-analyst/spec-issue-reporter.md +1 -1
- package/core/skills/qc/qa-automation-assess/matrix.md +123 -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-runner → qa-designer}/exploratory/session.md +8 -2
- package/core/skills/qc/qa-designer/functional/api.md +2 -2
- 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/functional/job.md +128 -0
- package/core/skills/qc/qa-designer/integration/api.md +2 -2
- package/core/skills/qc/qa-designer/integration/db.md +2 -2
- package/core/skills/qc/qa-designer/integration/gui.md +1 -1
- package/core/skills/qc/qa-designer/integration/{kafka.md → queue.md} +21 -5
- package/core/skills/qc/qa-designer/non-functional.md +1 -1
- package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +17 -0
- package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +28 -6
- 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 +3 -3
- 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 +29 -10
- package/core/skills/qc/qa-reviewer/test-case/e2e.md +2 -2
- package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/functional.md +2 -2
- package/core/skills/qc/qa-reviewer/test-case/integration.md +2 -2
- package/core/skills/qc/qa-reviewer/test-case/non-functional.md +2 -2
- 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/context-loader.md +1 -1
- package/core/steps/gate.md +7 -1
- package/core/steps/qc-scope.md +45 -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 +13 -12
- 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 +40 -11
- package/docs/04-reference/commands.md +4 -2
- package/docs/04-reference/modules.md +2 -1
- 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 +13 -10
- 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 +86 -21
- 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/commands/qc-run-test.md +0 -561
- 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,420 @@
|
|
|
1
|
+
---
|
|
2
|
+
buoc: Bước S (chen giữa Đợt 2 và Đợt 3)
|
|
3
|
+
title: Áp stack đã chốt — TypeScript + Playwright / WDIO+Appium
|
|
4
|
+
phu_thuoc: Đợt 2 xong (d2-b1, d2-b2, d2-b3)
|
|
5
|
+
trang_thai: ✅ XONG 2026-09-17 — 6/6 việc · bốn lệnh kiểm XANH · R5 đỏ 27→0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Bước S — Áp stack đã chốt lên ba trạm còn sinh mã sai
|
|
9
|
+
|
|
10
|
+
← [`PLAN_v2.md`](PLAN_v2.md) · [`01-checklist.md`](01-checklist.md) · [`00-nhat-ky.md`](00-nhat-ky.md)
|
|
11
|
+
|
|
12
|
+
| | |
|
|
13
|
+
|---|---|
|
|
14
|
+
| **Lớp** | chen giữa Đợt 2 và Đợt 3 — **CHẶN Đợt 3** |
|
|
15
|
+
| **Bước** | **S/1** (một bước, một commit cho lớp lệnh) |
|
|
16
|
+
| **File code** | `modules/qc-*` · `skills/qc/qa-script-{designer,runner}/` · `skills/qc/qa-reviewer/script/` · 3 `commands/qc-*-script.tmpl` |
|
|
17
|
+
| **File test** | `test/run.js` — thêm **một guard cơ học** (xem B4 · G3) |
|
|
18
|
+
| **Ngày xong** | — |
|
|
19
|
+
| **Phụ thuộc** | Đợt 2 xong ✅ · 4 quyết định ở §1 **chốt 2026-09-17** ✅ |
|
|
20
|
+
| **Ai dùng nó** | `/qc-design-script` · `/qc-run-script` · `/qc-review-script` · gián tiếp `/qc-report` (Đợt 3) |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 0 · Đo lại trước — và PLAN_v2 dính đúng Bẫy 1 của chính nó
|
|
25
|
+
|
|
26
|
+
> Luật ở [`PLAN_v2.md §5 Bẫy 1`](PLAN_v2.md): *"chạy lại mọi lệnh đếm trong kế hoạch trước khi
|
|
27
|
+
> làm theo nó."* Chạy lại thì **3/6 con số trong §3 của PLAN_v2 sai** — lần thứ **tư** liên tiếp.
|
|
28
|
+
|
|
29
|
+
| Nơi khai | PLAN_v2 §3 khai | Đo lại 2026-09-16 | Lệch |
|
|
30
|
+
|---|---|---|---|
|
|
31
|
+
| `skills/qc/qa-runner/` | 6 file · 44 KB | **8 file · 26,931 B (26.3 KB)** | +2 file · **−40 % dung lượng** |
|
|
32
|
+
| đích `qa-script-designer/` *(proposal)* | 12 file · 88 KB | **14 file · 57,864 B (56.5 KB)** | +2 file · **−36 %** |
|
|
33
|
+
| đích `qa-script-runner/` *(proposal)* | 4 file · 20 KB | 4 file · **13,445 B (13.1 KB)** | đúng số file · **−35 %** |
|
|
34
|
+
| `modules/qc-playwright/` | 1 file · 66 dòng · thiếu `module.yaml` | ✅ **đúng y hệt** | — |
|
|
35
|
+
| ngân sách | 1368 / 1450 KB | ✅ **1368, còn 82 KB** | — |
|
|
36
|
+
| 4 lệnh kiểm | xanh · 244/244 | ✅ **244/244 PASS** | — |
|
|
37
|
+
|
|
38
|
+
**Vì sao lệch quan trọng, không phải chuyện làm tròn:** con số 44 KB → 88 KB đọc như *"thay một
|
|
39
|
+
bộ nhỏ bằng một bộ to gấp đôi"*. Số thật là **26 KB → 57 KB** — vẫn gấp đôi, nhưng **tổng khối
|
|
40
|
+
lượng nhỏ hơn ước lượng ~30 KB**, và điều đó đổi câu trả lời cho H1: gánh cả web lẫn mobile trong
|
|
41
|
+
một bước **rẻ hơn** so với bản kế hoạch mô tả.
|
|
42
|
+
|
|
43
|
+
**Ba phát hiện mới, không có trong PLAN_v2:**
|
|
44
|
+
|
|
45
|
+
| # | Phát hiện | Hệ quả |
|
|
46
|
+
|:-:|---|---|
|
|
47
|
+
| N1 | `active_platform` **đã có giá trị `system`** — `.agent/steps/qc-scope.md:9`, `bdd/system/` là hạng nhất trong `generate-bdd` | lane API **không phải trục thứ ba mới** — nó là **ô trống của một trục đã có**. Đổi hẳn câu trả lời §1.1 |
|
|
48
|
+
| N2 | Ngân sách 1450 KB **chỉ đếm `core/commands/*.md`** (`test/run.js:697`) — skill **không** tính | thêm 57 KB skill **không** chạm ngân sách. Rủi ro ngân sách chỉ nằm ở **3 file lệnh** (25+27+21 = 73 KB) |
|
|
49
|
+
| N3 | `docs/explain/18-qc-review.md` và `19-qc-run-test.md` **giải thích 2 lệnh đã bị tách bỏ từ Đợt 2** | **nợ độc lập mới** — chưa có trong PLAN_v2 §3 |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 1 · BỐN CÂU — ĐÃ CHỐT 2026-09-17
|
|
54
|
+
|
|
55
|
+
> Giữ nguyên cả phần bằng chứng và các phương án **không** được chọn. Sáu tháng nữa, câu hỏi
|
|
56
|
+
> *"sao hồi đó không làm cách kia"* chỉ trả lời được nếu cách kia còn nằm đây.
|
|
57
|
+
|
|
58
|
+
| Mã | Câu | Chốt | Ngày |
|
|
59
|
+
|---|---|---|---|
|
|
60
|
+
| **S-API** | Lane API là nền thứ ba hay layer của web? | **Nền thứ ba ở tầng SKILL, KHÔNG phải module thứ ba** | 09-17 |
|
|
61
|
+
| **H1** | web + mobile cùng lúc hay web trước? | **B — cùng lúc (lệnh+module cả 3 lane), khác độ sâu (mobile port khung)** | 09-17 |
|
|
62
|
+
| **H2** | gỡ hẳn `qc-playwright` hay giữ deprecated? | **Gỡ hẳn** | 09-17 |
|
|
63
|
+
| **H3** | port `smoke.md` luôn? | **Không — để d4-b2** | 09-17 |
|
|
64
|
+
|
|
65
|
+
### 1.1 · Lane API — nền thứ ba, hay một layer của web? ✅ **nền thứ ba ở tầng skill**
|
|
66
|
+
|
|
67
|
+
**Bằng chứng nghiêng về "nền thứ ba":**
|
|
68
|
+
|
|
69
|
+
| # | Bằng chứng | Nguồn |
|
|
70
|
+
|:-:|---|---|
|
|
71
|
+
| a | Thư mục gốc **riêng**: `api-automation/` — *"tách biệt với `automation/` (web) — tránh xung đột config và dependency"* | `API-Testing-Standards.md` §2.1 |
|
|
72
|
+
| b | `playwright.config.ts` **riêng**, `package.json` có thể riêng | §2.1 |
|
|
73
|
+
| c | **API Object ≠ Page Object**: `BaseAPI`, 1 method = 1 endpoint, **không** `expect()` trong object | §4 · `AGT-010` §2.2 |
|
|
74
|
+
| d | Dãy ID **độc lập**: `TC-API-001` ≠ `TC-001` *cùng một project* | §7.3 |
|
|
75
|
+
| e | `AGT-010` là agent riêng, **Approved** (`AGT-005` mới Draft) | `AGT-010` header |
|
|
76
|
+
| f | **`active_platform` đã có `system`** — `bdd/system/*.feature`, sổ trace `{UC}-system.tsv` | `qc-scope.md:9` **(N1)** |
|
|
77
|
+
|
|
78
|
+
**Bằng chứng nghiêng về "layer của web":**
|
|
79
|
+
|
|
80
|
+
| # | Bằng chứng | Nguồn |
|
|
81
|
+
|:-:|---|---|
|
|
82
|
+
| g | **Cùng stack**: Playwright + TypeScript + Playwright Test + `expect` — AD-API-001 nói rõ chọn Playwright API mode *"để giảm số tool, tái dùng infrastructure với Web testing"* | `API-Testing-Standards.md` §1 |
|
|
83
|
+
| h | Bộ đề xuất **đã xếp API dưới web**: `qa-script-designer/web/functional/api.md` · `qa-reviewer/script/web/functional/api.md` | `qcframework_proposal/` |
|
|
84
|
+
| i | Framework đã có `qa-designer/functional/api.md` + `qa-designer/api/*` (6 file) | `skills/qc/qa-designer/` |
|
|
85
|
+
|
|
86
|
+
> 🔑 **Chỗ hai bên tưởng mâu thuẫn nhưng không.** (i) là tầng **thiết kế test case** — *"test cái
|
|
87
|
+
> gì"*. Lane đang bàn là tầng **sinh mã** — *"code thế nào"*. Hai trục khác nhau, `qa-designer/`
|
|
88
|
+
> **không bị đụng** dù chốt kiểu gì.
|
|
89
|
+
|
|
90
|
+
**✅ CHỐT (09-17): nền thứ ba ở tầng SKILL, nhưng KHÔNG phải module thứ ba.**
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
active_platform module skill lane
|
|
94
|
+
─────────────────────────────────────────────────────────────────────────
|
|
95
|
+
web · webview → qc-playwright-ts → qa-script-designer/web/*
|
|
96
|
+
app · app-ios · … → qc-wdio-appium → qa-script-designer/mobile/*
|
|
97
|
+
system → qc-playwright-ts → qa-script-designer/api/*
|
|
98
|
+
(layout thứ hai:
|
|
99
|
+
api-automation/)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Lý do: (c)(d)(e) làm **nội dung** khác hẳn → phải là file riêng; nhưng (g) làm **stack** y hệt
|
|
103
|
+
→ dựng module thứ ba là chép hai lần cùng một dãy phiên bản `Playwright/TS v5.x`, và **hai bản
|
|
104
|
+
của một sự thật là nơi drift sống** *(đúng lý do `qc-scope.md` ra đời)*. Còn (f) nói lane API
|
|
105
|
+
không phải trục mới — nó lấp ô `system` mà **hôm nay đang hỏng im lặng**: chạy
|
|
106
|
+
`/qc-design-script` trên một PRD `system` thì lệnh vẫn sinh Page Object + Python UI script.
|
|
107
|
+
|
|
108
|
+
**Phương án KHÔNG chọn — "layer của web"** → bỏ `qa-script-designer/api/`, dồn vào
|
|
109
|
+
`web/functional/api.md` + `_shared/api-conventions.md`; `active_platform=system` map về lane
|
|
110
|
+
`web`. Rẻ hơn ~3 file, nhưng `api-automation/` (a) mất chỗ khai và ô `system` vẫn nhoè.
|
|
111
|
+
|
|
112
|
+
**Phương án KHÔNG chọn — "module thứ ba đầy đủ"** (`modules/qc-playwright-api/`) → trung thành
|
|
113
|
+
nhất với §2.1, nhưng dãy phiên bản `Playwright/TS v5.x` sống ở **hai** file.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
### 1.2 · H1 — web + mobile cùng lúc, hay web trước? ✅ **B**
|
|
118
|
+
|
|
119
|
+
**Ràng buộc cứng, không phải sở thích** — [`PLAN_v2 §5 Bẫy 5`](PLAN_v2.md): tách được ≠ cái còn
|
|
120
|
+
lại dùng được. Gỡ `qc-playwright` mà chỉ port lane web thì `/qc-design-script` trên PRD `app`
|
|
121
|
+
**vẫn trỏ vào một module không còn tồn tại** — hỏng nặng hơn hôm nay.
|
|
122
|
+
|
|
123
|
+
| Phương án | Phạm vi | Cái giá |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| **A · cùng lúc, cùng độ sâu** | 3 lane đầy đủ | to nhất; mobile chưa có dự án thật để thử |
|
|
126
|
+
| **B · cùng lúc, khác độ sâu** ⭐ | **lớp lệnh + module: cả 3 lane**; **nội dung skill: web+api đầy đủ, mobile port khung `_shared/mobile-conventions.md` (12.7 KB) + 5 file lane** | mobile chưa được chạy thử thật — ghi rõ là hẹp *(§8 luật 4)* |
|
|
127
|
+
| **C · web trước + chặn cứng** | chỉ web(+api); `/qc-design-script` **từ chối** khi `active_platform=app`, kèm câu báo rõ | commit nhỏ nhất, **không sai im lặng**; nhưng đội mobile bị khoá cửa và phải mở lại ở một bước sau |
|
|
128
|
+
|
|
129
|
+
**✅ CHỐT (09-17): B.** Vì §0 đo được mobile chỉ là **12.7 KB `_shared` + 5 file lane ≈ 22 KB** —
|
|
130
|
+
rẻ hơn con số 88 KB mà bản kế hoạch cũ dựng lên. **C** là phương án lùi hợp lệ nếu cần commit
|
|
131
|
+
nhỏ; **A** bị loại vì viết sâu cho một nền chưa có dự án thật là viết hai lần.
|
|
132
|
+
|
|
133
|
+
> 🔴 **Nghĩa vụ đi kèm B — phải ghi, không được quên.** Lane mobile port **khung**, chưa chạy
|
|
134
|
+
> thử trên dự án thật. Theo [`PLAN_v2 §8 luật 4`](PLAN_v2.md) *("khai một phạm vi hẹp và nói rõ
|
|
135
|
+
> là hẹp")*, `modules/qc-wdio-appium/module.yaml` phải mang một dòng khai đúng điều đó, và
|
|
136
|
+
> `00-nhat-ky.md` phải có một dòng nợ: *"lane mobile chờ dự án thật để xác nhận"*.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### 1.3 · H2 — gỡ hẳn `qc-playwright` hay giữ deprecated 1 version? ✅ **gỡ hẳn**
|
|
141
|
+
|
|
142
|
+
**Bằng chứng:**
|
|
143
|
+
- Tiền lệ **đã chốt 09-16**: `E3` — *"gỡ `/qc-review` ngay, không giữ cầu"*.
|
|
144
|
+
- `bin/qc-base-map.json`: chỉ **3/82 entry** dính `qa-runner`, cả ba `targets: []`, `state: undecided`
|
|
145
|
+
→ gỡ **không** làm đỏ `R16`.
|
|
146
|
+
- Giữ deprecated nghĩa là `modules/qc-playwright/stack-profile.yaml` (66 dòng Python) **vẫn ở
|
|
147
|
+
trong `core/`** — và nó là **nguồn duy nhất** mà 3 lệnh trích dẫn. Hai stack-profile QC cùng
|
|
148
|
+
sống = guard ở B4 không bao giờ xanh được.
|
|
149
|
+
|
|
150
|
+
**✅ CHỐT (09-17): gỡ hẳn.** Lịch sử đã nằm ở `qc-base-map.json` (snapshot `596149f`) và git.
|
|
151
|
+
|
|
152
|
+
**Phương án KHÔNG chọn — "giữ 1 version"** → guard S0 phải thêm ngoại lệ đường dẫn, tức **cửa
|
|
153
|
+
để Python quay lại**; và phải chốt thêm *"1 version"* là mốc nào, ai gỡ.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
### 1.4 · H3 — port `qa-script-runner/smoke.md` luôn? ✅ **không, để d4-b2**
|
|
158
|
+
|
|
159
|
+
**Bằng chứng:** `smoke.md` = 5,895 B, thuộc `/qc-smoke-test` — lệnh của **d4-b2**, chưa tồn tại.
|
|
160
|
+
Port bây giờ để lại một file **không lệnh nào nạp**. `bin/self-check.js:274` (R4) đã cảnh báo
|
|
161
|
+
đúng lớp lỗi này cho key context; skill mồ côi thì **chưa có rule nào bắt** → nó sẽ nằm im.
|
|
162
|
+
Mặt khác d4-b2 **đã hết chặn** (chị QC chốt tên 09-16) và trạm 6 đã gắn `@smoke` cho `P0`.
|
|
163
|
+
|
|
164
|
+
**✅ CHỐT (09-17): KHÔNG port ở Bước S — để d4-b2**, và ghi một dòng nợ trỏ tới nó. Bước S đã là
|
|
165
|
+
bước to nhất của cả đợt; thêm một file cho một lệnh chưa có là mở rộng phạm vi không có người
|
|
166
|
+
dùng ở đầu kia.
|
|
167
|
+
|
|
168
|
+
**Phương án KHÔNG chọn — "port luôn"** → +1 file · +5.9 KB, và d4-b2 rút ngắn còn viết lệnh.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
# PHẦN A — Chuyện gì đang xảy ra
|
|
173
|
+
*(cho người không làm kỹ thuật · đọc xong phần này là đủ hiểu)*
|
|
174
|
+
|
|
175
|
+
## A1 · Vấn đề
|
|
176
|
+
|
|
177
|
+
Đội QC đã chốt cách viết bài kiểm tra từ ngày 10/9 và xác nhận qua email. Từ hôm đó tới nay, bộ
|
|
178
|
+
khung vẫn phát ra bài viết theo cách cũ — cách đã bị bỏ. Ai nhận cũng phải viết lại từ đầu, nên
|
|
179
|
+
phần đáng lẽ được làm hộ trở thành phần phải dọn. Tệ hơn: không có gì báo sai. Mọi đèn kiểm đều
|
|
180
|
+
xanh, nên nhìn từ ngoài vào thì trạm này vẫn đang chạy tốt.
|
|
181
|
+
|
|
182
|
+
## A2 · Cách giải quyết, nói bằng một hình ảnh
|
|
183
|
+
|
|
184
|
+
Như một xưởng in vẫn in bản đồ theo tên đường cũ sau khi thành phố đổi tên. Máy vẫn chạy, giấy
|
|
185
|
+
vẫn đẹp, không ai báo hỏng — chỉ người cầm bản đồ đi mới lạc, và lạc xong thì tưởng mình đọc sai.
|
|
186
|
+
Bước này thay **bản gốc trong máy**, một lần, cho cả ba loại bản đồ: web, điện thoại, dịch vụ.
|
|
187
|
+
|
|
188
|
+
## A3 · Xong rồi thì thấy gì khác
|
|
189
|
+
|
|
190
|
+
Chạy lệnh sinh script sẽ ra file đuôi `.spec.ts` thay vì `.py`, nằm trong `automation/` (web)
|
|
191
|
+
hoặc `api-automation/` (dịch vụ), và lệnh **hỏi nền trước khi sinh** thay vì mặc định một nền.
|
|
192
|
+
Thêm một đèn kiểm mới: nếu chữ "Python" quay lại chỗ nào trong bộ QC, đèn đó đỏ.
|
|
193
|
+
|
|
194
|
+
## A4 · Thuật ngữ dùng ở trên
|
|
195
|
+
|
|
196
|
+
- **stack** — bộ công cụ + ngôn ngữ mà test được viết bằng. Ở đây: TypeScript + Playwright (web, dịch vụ), WebdriverIO + Appium (điện thoại).
|
|
197
|
+
- **script** — bài kiểm tra ở dạng máy chạy được, khác với bài kiểm tra viết cho người đọc rồi làm tay.
|
|
198
|
+
- **nền / platform** — web · điện thoại · dịch vụ (`system`). Một lần chạy QC khoá đúng **một** nền.
|
|
199
|
+
- **module** — hồ sơ khai stack của một loại dự án, để lệnh đọc mà biết sinh code theo kiểu nào.
|
|
200
|
+
- **skill** — file hướng dẫn mà lệnh nạp lúc chạy; nội dung chi tiết nằm ở đây, không nằm trong lệnh.
|
|
201
|
+
- **Page Object / API Object** — cách gom thao tác lên một màn hình / một endpoint vào một chỗ, để sửa một lần thay vì sửa khắp nơi.
|
|
202
|
+
- **đèn kiểm / guard** — một phép kiểm tự động chạy sau mỗi lần sửa; đỏ thì không được commit.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
> ### ✅ Phép thử bắt buộc trước khi coi Phần A là xong
|
|
207
|
+
> **Đã thử với:** *(chưa — tự đọc to sau khi anh chốt §1, vì phạm vi đổi thì A3 đổi)* ·
|
|
208
|
+
> **ngày:** — · **phải giải thích thêm chỗ nào:** —
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
# PHẦN B — Chi tiết kỹ thuật
|
|
213
|
+
|
|
214
|
+
## B1 · Cách hiển nhiên là gì, và vì sao nó sai
|
|
215
|
+
|
|
216
|
+
### Cách hiển nhiên 1 — tìm-thay chuỗi
|
|
217
|
+
|
|
218
|
+
Đo được: **363 dòng khớp** `pytest|python|\.py` trong `skills/ commands/ core/ templates/ rules/
|
|
219
|
+
bin/ docs/`, trải trên **47 file nguồn**. Cách hiển nhiên là thay `Python`→`TypeScript`,
|
|
220
|
+
`pytest`→`Playwright Test`, `.py`→`.spec.ts` rồi chạy 4 lệnh kiểm.
|
|
221
|
+
|
|
222
|
+
**Vì sao sai — cụ thể:** cái phải đổi **không phải từ vựng, là hình dạng**.
|
|
223
|
+
|
|
224
|
+
| Thứ đổi theo stack | `pytest-playwright` (nay) | `@playwright/test` + TS (chốt) |
|
|
225
|
+
|---|---|---|
|
|
226
|
+
| Nơi test sống | `tests/<project>/test_<feature>.py` | `automation/tests/<feature>/<feature>-happy-path.spec.ts` |
|
|
227
|
+
| Đối tượng | `pages/<feature>_page.py` · `BasePage` | `pages/<feature>.page.ts` — và **API lane dùng `api/<res>.api.ts` · `BaseAPI`, cấm `expect()` bên trong** |
|
|
228
|
+
| Cách gom setup | `conftest.py` + fixture pytest | `fixtures/*.fixture.ts` |
|
|
229
|
+
| Chạy | `python3 -m pytest` | `npx playwright test` |
|
|
230
|
+
| Mobile | *(không có)* | WDIO v9 + Appium v2 + UiAutomator2 · **gesture helper** · **environment validation checklist** |
|
|
231
|
+
|
|
232
|
+
Tìm-thay cho ra văn bản **đúng từ vựng TypeScript, đúng cấu trúc Python**. Và nó **qua cả 4 lệnh
|
|
233
|
+
kiểm** — `build.js` chỉ đúc template, `self-check.js` R1–R22 không biết stack, `run.js` không có
|
|
234
|
+
rule nào về stack QC, `lint-trace.js` soi sổ trace. Tức nó **vào được `main` với 244/244 xanh**,
|
|
235
|
+
rồi vỡ ở lần chạy thật đầu tiên của chị QC, hai tuần sau, dưới dạng *"framework sinh code không
|
|
236
|
+
chạy được"* — một câu không chỉ về đâu để sửa.
|
|
237
|
+
|
|
238
|
+
### Cách hiển nhiên 2 — bê nguyên thư mục skill của bộ đề xuất
|
|
239
|
+
|
|
240
|
+
`qcframework_proposal/skills/qc/qa-script-designer/` có sẵn 14 file đúng hình dạng cần. Cách
|
|
241
|
+
hiển nhiên là copy cả cụm.
|
|
242
|
+
|
|
243
|
+
**Vì sao sai:** bộ đề xuất **chỉ nói tên stack**; `qc-base-new/` là *Official Project Knowledge*,
|
|
244
|
+
status **Approved**, và **ghim phiên bản cụ thể** (Appium v2.x · WebdriverIO v9.x · TypeScript
|
|
245
|
+
v5.x · UiAutomator2) + §Anti-patterns + §Flaky Policy. Copy đề xuất = chốt một stack **không có
|
|
246
|
+
số hiệu phiên bản** — đúng lớp lỗi mà `AD-API-001`/`AGT-010` sinh ra để chặn.
|
|
247
|
+
|
|
248
|
+
**Luật chia nguồn** *(đã ghi ở [`PLAN_v2 §4.2`](PLAN_v2.md), nhắc lại vì đây là chỗ dễ trượt)*:
|
|
249
|
+
**bố cục thư mục ← đề xuất · nội dung stack ← `qc-base-new/`.**
|
|
250
|
+
|
|
251
|
+
## B2 · Cách làm đúng
|
|
252
|
+
|
|
253
|
+
**Thứ tự bắt buộc — guard trước, vá sau** *(quyết định `G3`, 09-16)*.
|
|
254
|
+
|
|
255
|
+
**S0 · Dựng đèn trước khi vá.** Thêm vào `test/run.js` một test: không dòng nào trong
|
|
256
|
+
`skills/qc/**` · `commands/qc-*.tmpl` · `modules/qc-*/` khớp `pytest|python3?\b|\.py\b`.
|
|
257
|
+
Chạy ngay → **đỏ với ~47 file**. Đó là bằng chứng đèn bắt được lỗi **đang sống**, không phải
|
|
258
|
+
đèn viết sau khi đã sạch nên vĩnh viễn xanh.
|
|
259
|
+
|
|
260
|
+
**S1 · Lớp module.** `modules/qc-playwright/` (1 file, 66 dòng, **thiếu `module.yaml`** — trong
|
|
261
|
+
khi `react/` và `flutter/` đều có 2 file) → hai module, mỗi cái **đủ cặp**:
|
|
262
|
+
|
|
263
|
+
| Module | `module.yaml` | `stack-profile.yaml` |
|
|
264
|
+
|---|---|---|
|
|
265
|
+
| `qc-playwright-ts` | `language: TypeScript` · `test_framework: "Playwright Test"` | `layout.web` = `automation/` · **`layout.api` = `api-automation/`** *(theo §1.1)* · locator priority · anti-patterns |
|
|
266
|
+
| `qc-wdio-appium` | `language: TypeScript` · `test_framework: "WebdriverIO + Appium"` | `layout.mobile` · gesture helper · environment validation checklist |
|
|
267
|
+
|
|
268
|
+
**S2 · Lớp skill.** `qa-runner/` **(8 file · 26.3 KB — bộ SINH MÃ Python, không phải "hướng dẫn
|
|
269
|
+
chạy test"; xem [`PLAN_v2 §5 Bẫy 3`](PLAN_v2.md))** → gỡ, thay bằng:
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
qa-script-designer/
|
|
273
|
+
_shared/ web-conventions.md (16.5 KB) · mobile-conventions.md (12.7 KB) · file-naming-and-folders.md (7.3 KB)
|
|
274
|
+
web/ functional/{gui-screen,gui-feature,api}.md · integration.md · e2e.md · non-functional.md
|
|
275
|
+
mobile/ functional/{screen,feature}.md · integration.md · e2e.md · non-functional.md
|
|
276
|
+
api/ endpoint.md · auth.md · security.md ← lane thứ ba (S-API ✅)
|
|
277
|
+
qa-script-runner/
|
|
278
|
+
web/run.md · mobile/run.md · report.md ← smoke.md để d4-b2 (H3 ✅)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Nguồn nội dung 3 file `api/`: `API-Testing-Standards.md` §4 *(API Object)* · §5 *(Test Spec, AAA)*
|
|
282
|
+
· §6 *(Assertion)* · §8 *(Test Design)* · §9 *(Security)*, cộng `AGT-010` §3 *(R01–R03)*.
|
|
283
|
+
|
|
284
|
+
**S3 · `qa-reviewer/script/`** 5 file phẳng (22 KB) → `script/{web,mobile,api}/*` — thực thi
|
|
285
|
+
`E1`, quyết định đã dời sang đây từ 09-16.
|
|
286
|
+
|
|
287
|
+
**S4 · Lớp lệnh — 3 file, và đây là chỗ duy nhất chạm ngân sách.** `qc-design-script`
|
|
288
|
+
`Role & stack` hiện **nhúng thẳng luật Python vào lệnh** (dòng 69–89 của `.tmpl`). Thay bằng
|
|
289
|
+
**bảng phân giải nền + một con trỏ sang skill**:
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
active_platform → module → lane skill (bảng 3 dòng, ~10 dòng văn bản)
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Con số và lý do:** 3 lệnh hiện **25 + 27 + 21 = 73 KB**; ngân sách còn **82 KB** và
|
|
296
|
+
`test/run.js:697` **chỉ đếm `core/commands/*.md`** *(N2)* — nên 57 KB skill **không tính vào
|
|
297
|
+
đây**. Kéo luật stack ra khỏi lệnh giúp 3 file **co lại**, và đó là cách duy nhất thêm lane thứ
|
|
298
|
+
ba mà không ăn vào 82 KB còn lại.
|
|
299
|
+
|
|
300
|
+
**S5 · Ăn theo.** `skills/qc/qa-automation-assess/matrix.md` (dòng 102–104 trỏ `qc-playwright`
|
|
301
|
+
Python) · `commands/qc-report.tmpl` (5 dòng) · `bin/trace-schema.json` (4 dòng: 1477 · 2419 ·
|
|
302
|
+
2422 · 2496) · `bin/qc-base-map.json` (3 entry `undecided` → `decided`) · 6 file `docs/`.
|
|
303
|
+
|
|
304
|
+
## B3 · Nếu làm sai thì hỏng theo kiểu nào
|
|
305
|
+
|
|
306
|
+
**Kiểu hỏng: Im lặng 🔴** *(và nó **đang** hỏng theo kiểu này ngay lúc này)*.
|
|
307
|
+
|
|
308
|
+
Hỏng ở đâu: lệnh sinh ra file `.py` mà không dự án nào chạy được — hoặc tệ hơn, `.spec.ts` đúng
|
|
309
|
+
từ vựng nhưng sai hình dạng thư mục nên `npx playwright test` không thấy file nào và báo
|
|
310
|
+
**"0 tests"**, tức **xanh**. Ai phát hiện: chị QC, ở lần chạy thật đầu tiên. Sau bao lâu: đo được
|
|
311
|
+
là **6 ngày và vẫn đang đếm** — stack chốt 09-10, hôm nay 09-16, 4 lệnh kiểm chưa đỏ một lần.
|
|
312
|
+
|
|
313
|
+
## B4 · Verify bằng gì
|
|
314
|
+
|
|
315
|
+
| # | Phép thử | Kết quả mong đợi |
|
|
316
|
+
|:-:|---|---|
|
|
317
|
+
| 1 | **S0 chạy TRƯỚC khi sửa** | **ĐỎ**, liệt kê ~47 file. Xanh ngay từ đầu = đèn viết sai, làm lại |
|
|
318
|
+
| 2 | `grep -rniE 'pytest\|python' skills/ commands/ modules/` | **0** dòng (trừ `upstream/` và `docs/plans/`) |
|
|
319
|
+
| 3 | `ls modules/qc-playwright-ts modules/qc-wdio-appium` | mỗi thư mục **đúng 2 file** — bằng `react/` và `flutter/` |
|
|
320
|
+
| 4 | `ls modules/qc-playwright` | **không tồn tại** *(H2 ✅ gỡ hẳn)* |
|
|
321
|
+
| 5 | 4 lệnh kiểm | `build` ✅ · `self-check` R1–R22 ✅ · `run.js` **245/245** (thêm S0) ✅ · `lint-trace` T1–T20 ✅ |
|
|
322
|
+
| 6 | Ngân sách | `core/commands` **< 1450 KB**, và 3 lệnh script **≤ 73 KB** (không được phình) |
|
|
323
|
+
| 7 | **Phá có chủ đích:** đặt `active_platform=system` rồi chạy `/qc-design-script` | trỏ đúng lane API + `api-automation/` — **không** ra Page Object. *(Hôm nay: ra Page Object Python.)* |
|
|
324
|
+
| 8 | **Phá có chủ đích:** `active_platform=app` | trỏ `qc-wdio-appium` + lane mobile *(H1 ✅ B — lane có mặt, nội dung ở mức khung)* |
|
|
325
|
+
| 9 | `node bin/self-check.js` sau khi sửa `qc-base-map.json` | **R16 không đỏ** — 3 entry `qa-runner` có `targets: []` nên gỡ file cục bộ không phá map |
|
|
326
|
+
|
|
327
|
+
## B5 · Bài học
|
|
328
|
+
|
|
329
|
+
- **2026-09-16** — PLAN_v2 §3 khai `qa-runner` **6 file · 44 KB**; đo lại: **8 file · 26.3 KB**. Đây là lần **thứ tư** một bản kế hoạch của đợt này mang số đã lỗi thời → nguyên nhân thật: số được chép từ bản kế hoạch trước chứ không đo lại. Sửa: §0 của mọi bước từ nay **bắt đầu bằng bảng đo lại**, kể cả khi bản trước vừa viết hôm qua.
|
|
330
|
+
- **2026-09-16** — Tưởng ngân sách 1450 KB chặn việc thêm skill. Đọc `test/run.js:697`: nó **chỉ đếm `core/commands/*.md`**. Nguyên nhân thật: PLAN_v2 ghi *"ngân sách core/commands"* nhưng để nó cạnh các số toàn repo nên đọc thành *"cả bộ"*. Sửa: ghi rõ **phép đếm**, không chỉ tên thư mục.
|
|
331
|
+
|
|
332
|
+
## B6 · Copy được / không copy được
|
|
333
|
+
|
|
334
|
+
| | |
|
|
335
|
+
|---|---|
|
|
336
|
+
| ✅ **Copy được sang dự án khác** | Thứ tự **guard-trước-vá-sau** (`G3`); tách **bố cục ← đề xuất / nội dung ← tài liệu Approved**; luật *"một lệnh phải đổi cho mọi nền nó với tới, trong một commit"* (Bẫy 5); đo lại số trước khi làm theo kế hoạch (Bẫy 1) |
|
|
337
|
+
| ⚠️ **Chỉ đúng ở đây** | Tên `web`/`app`/`system` và cách `qc-scope.md` khoá một nền; ngưỡng 1450 KB và phép đếm của nó; ba lane gắn với `TestingOS` của chị QC; tài liệu nguồn tiếng Việt |
|
|
338
|
+
|
|
339
|
+
## B7 · Link
|
|
340
|
+
|
|
341
|
+
- [`PLAN_v2.md`](PLAN_v2.md) — §3 *(thứ tự)* · §4 *(nguồn)* · §5 *(bẫy)* · §6 *(4 câu này)* · §7 `E1`·`E3`·`G3`
|
|
342
|
+
- [`exec-d2-b1-tach-qc-review.md`](exec-d2-b1-tach-qc-review.md) — §3.3, phần `E1` dời sang đây
|
|
343
|
+
- [`exec-d2-b2-tach-qc-run-test-atomic.md`](exec-d2-b2-tach-qc-run-test-atomic.md) — §4.4, chỗ khai sai bản chất `qa-runner` (Bẫy 3)
|
|
344
|
+
- [`exec-d3-b1-qc-report-gate-decision.md`](exec-d3-b1-qc-report-gate-decision.md) — bước **bị chặn** bởi bước này
|
|
345
|
+
- `upstream/qc-base-new/` — `Automation-Standards.md` · `Mobile-Automation-Standards.md` · `API-Testing-Standards.md` · `AGT-005` · `AGT-006` · `AGT-010`
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## 8 · Phạm vi đã khoá — thứ tự triển khai
|
|
350
|
+
|
|
351
|
+
> 🔄 **Thứ tự đổi 2026-09-17 (`S-ORDER`): S0 → S1 → S5 → S3 → S2 → S4.**
|
|
352
|
+
> Đo được: **16/18 file đỏ không có phụ thuộc nào** — chỉ **S4** bị ép *(cần S2+S3)*. Thứ tự
|
|
353
|
+
> đánh số 2·3·4·5 là thói quen, không phải ràng buộc. Ba lý do đổi:
|
|
354
|
+
> **①** S5 chỉ ~10 dòng và **đã được S1 quyết định hết**, lại **chứa một bug thật**
|
|
355
|
+
> *(`qc-design-test.tmpl:151` còn trỏ `/qc-review` — lệnh đã gỡ ở `E3`)*.
|
|
356
|
+
> **②** S3 trước S2 là `G3` áp ở tầng nội dung: **viết tiêu chí review trước, viết bộ sinh sau**
|
|
357
|
+
> — ngược lại thì tiêu chí bị nắn theo thứ bộ sinh vừa đẻ ra, mất đối chứng độc lập.
|
|
358
|
+
> **③** Đứt session giữa chừng thì mất ít hơn.
|
|
359
|
+
> Phạm vi **không đổi** — vẫn 6 việc, vẫn cùng nội dung.
|
|
360
|
+
|
|
361
|
+
Sau khi chốt 4 câu, Bước S là **6 việc**.
|
|
362
|
+
|
|
363
|
+
| # | Việc | Kích thước đo được | Commit |
|
|
364
|
+
|:-:|---|---|:-:|
|
|
365
|
+
| **S0** ✅ | Guard cơ học — **6 entry `forbidden_patterns` có `scope`, chạy qua R5 sẵn có**. **ĐÃ LÀM 09-17**: đỏ **19 file** *(G3)*. Bản trình bày: [`exec-S0`](exec-S0-guard-cam-stack-cu.md) | `test/run.js` **không đổi** — vẫn 244 | 1 |
|
|
366
|
+
| **S1** ✅ | `modules/qc-playwright/` **gỡ** → `qc-playwright-ts` *(layout `web` + `api`)* + `qc-wdio-appium`, mỗi cái đủ `module.yaml` + `stack-profile.yaml` | 1 file → 4 file | 2 |
|
|
367
|
+
| **S2** ✅ | `qa-runner/` (8 file · 26.3 KB) **gỡ** → `qa-script-designer/` *(web+api đầy đủ, mobile khung)* + `qa-script-runner/` *(3 file)* | 26 KB → ~57 KB skill · **không chạm ngân sách** *(N2)* | 2 |
|
|
368
|
+
| **S3** ✅ | `qa-reviewer/script/` 5 file phẳng → **XOÁ, viết mới** `script/{web,mobile,api}/*` — thực thi `E1` | 22 KB, **viết lại** *(xem §8.1)* | 2 |
|
|
369
|
+
| **S4** ✅ | 2 lệnh: gỡ bảng `testid_attr` trùng bản + 6 dòng cuối → **bảng phân giải nền + con trỏ skill** | 73 KB → **phải ≤ 73 KB** | 2 |
|
|
370
|
+
| **S5** ✅ | Ăn theo: `matrix.md` · `qc-report.tmpl` · `trace-schema.json` *(4 dòng)* · `qc-base-map.json` *(3 entry)* · 6 `docs/` | ~15 chỗ | 2 |
|
|
371
|
+
|
|
372
|
+
### 8.1 · Vì sao S3 là **viết lại**, không phải sửa — và vì sao chỉ S3
|
|
373
|
+
|
|
374
|
+
Câu hỏi *"sao không bỏ hết code Python của QC rồi xây lại từ đầu"* (09-17) được đo và trả lời
|
|
375
|
+
bằng số:
|
|
376
|
+
|
|
377
|
+
| Đo | Kết quả |
|
|
378
|
+
|---|---|
|
|
379
|
+
| Tỉ lệ nhiễm của `skills/qc/` | **112 / 5320 dòng = 2,1 %** |
|
|
380
|
+
| Phần **thật sự là Python** | `modules/qc-playwright/` + `qa-runner/` = **9 file** → **đã xoá hẳn** ở S1/S2 |
|
|
381
|
+
| 9 file nhiễm nhẹ nhất *(qa-designer · qa-planner · qa-reviewer/test-case · shared)* | cộng lại **18 dòng**, trong các file dài 120–272 dòng mà 98 % nội dung **không phụ thuộc ngôn ngữ** |
|
|
382
|
+
| `qa-reviewer/script/non-functional.md` · `functional.md` | **11,2 %** và **9,2 %** ← ngưỡng khác hẳn |
|
|
383
|
+
|
|
384
|
+
**S3 đổi vì mật độ, không vì nguyên tắc.** Tái bố cục một file sai stack 10 % *dưới cái tên
|
|
385
|
+
"sửa"* dẫn thẳng vào bẫy B1: người viết giữ khung cũ và chỉ đổi chữ. Nên: **xoá 5 file, viết mới**
|
|
386
|
+
từ `Automation-Standards` §10 · `Mobile-Automation-Standards` · `API-Testing-Standards` §10 ·
|
|
387
|
+
`AGT-006` *(có sẵn scoring rules)*. Giữ lại đúng một thứ: **cấu trúc mục của
|
|
388
|
+
`review-check-groups.md`**, để hai bên còn khớp.
|
|
389
|
+
|
|
390
|
+
**Vì sao KHÔNG xây lại cả `skills/qc/`** — nguồn không phủ đủ, và đã đo:
|
|
391
|
+
|
|
392
|
+
- `qc-base-new/` **7 file** tự khai trong header là **L4 Execution** + **L5 Governance**. Không
|
|
393
|
+
có file nào cho phân tích yêu cầu · doc-gap · test plan · thiết kế TC · review TC — **4 trạm
|
|
394
|
+
đầu**, và cả 4 đang **✅ đủ** theo §2.
|
|
395
|
+
- `qcframework_proposal/` cắt **2026-09-10**, mà nó **đã chứa** công của đợt này (`testid_attr`
|
|
396
|
+
7 file · `self-review-principles` 8 file · `script-bug`/`product-gap` · §4.5.6) → **bản phái
|
|
397
|
+
sinh của chính framework**, không phải nguồn độc lập. Xây lại từ nó là mất 6 ngày sửa: 24 GAP
|
|
398
|
+
lane QC *(`dfe5bd5`)* · R17/R18/T19 · T20/R8f *(`02642bd`)* · G84 · G86+G87 · 0.9.6 · 0.9.7.
|
|
399
|
+
|
|
400
|
+
Đổi **18 dòng sửa tay** lấy **42 file sạch + 6 ngày sửa lỗi** là lỗ. Đổi **5 file mật độ ~10 %**
|
|
401
|
+
lấy một bản viết theo chuẩn Approved là lãi.
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
**Vì sao hai commit chứ không một.** S0 **phải đỏ** — đó là bằng chứng của `G3`. Một commit đỏ
|
|
406
|
+
là vi phạm [`§8 luật 1`](PLAN_v2.md). Nên S0 vào commit 1 **cùng với** một dòng `skip` có ghi lý
|
|
407
|
+
do và hạn *(gỡ ở commit 2)*; hoặc S0 và S1–S5 gộp làm một commit và bằng chứng đỏ được ghi lại
|
|
408
|
+
trong `buoc/` thay vì trong lịch sử git. **Cách 2 gọn hơn và tôi đề xuất cách 2** — bằng chứng
|
|
409
|
+
đỏ chụp vào nhật ký bước, cây git vẫn xanh suốt.
|
|
410
|
+
|
|
411
|
+
**Bốn quyết định này vào [`PLAN_v2 §7`](PLAN_v2.md) với mã `S-API` · `H1` · `H2` · `H3`, và ra
|
|
412
|
+
khỏi §6.**
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## 9 · Nợ độc lập phát hiện thêm ở bước này *(không làm trong Bước S)*
|
|
417
|
+
|
|
418
|
+
| Việc | Đo được |
|
|
419
|
+
|---|---|
|
|
420
|
+
| `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`; `docs/explain/` chưa có file cho 5 lệnh mới **(N3)** |
|