@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.
Files changed (147) hide show
  1. package/bin/lint-trace.js +4 -4
  2. package/bin/qc-base-map.json +13 -11
  3. package/bin/self-check.js +497 -16
  4. package/bin/trace-schema.json +3226 -2656
  5. package/core/FRAMEWORK_VERSION +1 -1
  6. package/core/commands/amend-prd.md +7 -1
  7. package/core/commands/debug.md +8 -2
  8. package/core/commands/define-product.md +38 -1
  9. package/core/commands/dev-gen-test.md +9 -3
  10. package/core/commands/dev-run-test.md +8 -2
  11. package/core/commands/dev-smoke-test.md +7 -1
  12. package/core/commands/extend-prd.md +7 -1
  13. package/core/commands/fix-bug.md +11 -5
  14. package/core/commands/generate-architecture.md +9 -1
  15. package/core/commands/generate-bdd.md +45 -5
  16. package/core/commands/generate-code.md +43 -4
  17. package/core/commands/generate-design-spec.md +7 -1
  18. package/core/commands/generate-prd.md +9 -1
  19. package/core/commands/generate-spec-manifest.md +7 -1
  20. package/core/commands/generate-tech-docs.md +41 -1
  21. package/core/commands/learn.md +7 -1
  22. package/core/commands/map-testids.md +11 -5
  23. package/core/commands/propose-scenario.md +7 -1
  24. package/core/commands/qc-analyze.md +12 -6
  25. package/core/commands/qc-automation-assess.md +356 -0
  26. package/core/commands/qc-design-script.md +430 -0
  27. package/core/commands/qc-design-test.md +98 -20
  28. package/core/commands/qc-plan.md +9 -3
  29. package/core/commands/qc-report.md +92 -77
  30. package/core/commands/qc-review-script.md +342 -0
  31. package/core/commands/{qc-review.md → qc-review-testcase.md} +86 -54
  32. package/core/commands/qc-run-manualtest.md +401 -0
  33. package/core/commands/qc-run-script.md +421 -0
  34. package/core/commands/refine-prd.md +7 -1
  35. package/core/commands/report-bug.md +9 -3
  36. package/core/commands/review-code.md +9 -3
  37. package/core/commands/review-context.md +11 -3
  38. package/core/commands/review-tech-docs.md +11 -3
  39. package/core/commands/setup-ai-first.md +7 -1
  40. package/core/commands/validate-traces.md +10 -4
  41. package/core/modules/qc-playwright-ts/module.yaml +13 -0
  42. package/core/modules/qc-playwright-ts/stack-profile.yaml +99 -0
  43. package/core/modules/qc-wdio-appium/module.yaml +20 -0
  44. package/core/modules/qc-wdio-appium/stack-profile.yaml +107 -0
  45. package/core/rules/workflow.md +2 -2
  46. package/core/skills/qc/_shared/self-review-principles.md +2 -2
  47. package/core/skills/qc/qa-analyst/DOC_GAP.template.md +1 -1
  48. package/core/skills/qc/qa-analyst/data-flow.md +1 -1
  49. package/core/skills/qc/qa-analyst/spec-issue-reporter.md +1 -1
  50. package/core/skills/qc/qa-automation-assess/matrix.md +123 -0
  51. package/core/skills/qc/qa-designer/e2e/journey.md +1 -1
  52. package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +1 -1
  53. package/core/skills/qc/{qa-runner → qa-designer}/exploratory/session.md +8 -2
  54. package/core/skills/qc/qa-designer/functional/api.md +2 -2
  55. package/core/skills/qc/qa-designer/functional/gui-feature.md +1 -1
  56. package/core/skills/qc/qa-designer/functional/gui-screen.md +1 -1
  57. package/core/skills/qc/qa-designer/functional/job.md +128 -0
  58. package/core/skills/qc/qa-designer/integration/api.md +2 -2
  59. package/core/skills/qc/qa-designer/integration/db.md +2 -2
  60. package/core/skills/qc/qa-designer/integration/gui.md +1 -1
  61. package/core/skills/qc/qa-designer/integration/{kafka.md → queue.md} +21 -5
  62. package/core/skills/qc/qa-designer/non-functional.md +1 -1
  63. package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +17 -0
  64. package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +28 -6
  65. package/core/skills/qc/qa-reviewer/script/_shared/review-rules.md +121 -0
  66. package/core/skills/qc/qa-reviewer/script/api/auth.md +49 -0
  67. package/core/skills/qc/qa-reviewer/script/api/endpoint.md +89 -0
  68. package/core/skills/qc/qa-reviewer/script/api/security.md +46 -0
  69. package/core/skills/qc/qa-reviewer/script/exploratory.md +3 -3
  70. package/core/skills/qc/qa-reviewer/script/mobile/e2e.md +41 -0
  71. package/core/skills/qc/qa-reviewer/script/mobile/functional.md +90 -0
  72. package/core/skills/qc/qa-reviewer/script/mobile/integration.md +41 -0
  73. package/core/skills/qc/qa-reviewer/script/mobile/non-functional.md +43 -0
  74. package/core/skills/qc/qa-reviewer/script/web/e2e.md +46 -0
  75. package/core/skills/qc/qa-reviewer/script/web/functional.md +111 -0
  76. package/core/skills/qc/qa-reviewer/script/web/integration.md +46 -0
  77. package/core/skills/qc/qa-reviewer/script/web/non-functional.md +49 -0
  78. package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +1 -1
  79. package/core/skills/qc/qa-reviewer/shared/review-file-template.md +29 -10
  80. package/core/skills/qc/qa-reviewer/test-case/e2e.md +2 -2
  81. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
  82. package/core/skills/qc/qa-reviewer/test-case/functional.md +2 -2
  83. package/core/skills/qc/qa-reviewer/test-case/integration.md +2 -2
  84. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +2 -2
  85. package/core/skills/qc/qa-script-designer/_shared/api-conventions.md +94 -0
  86. package/core/skills/qc/qa-script-designer/_shared/file-naming-and-folders.md +109 -0
  87. package/core/skills/qc/qa-script-designer/_shared/mobile-conventions.md +196 -0
  88. package/core/skills/qc/qa-script-designer/_shared/web-conventions.md +257 -0
  89. package/core/skills/qc/qa-script-designer/api/auth.md +43 -0
  90. package/core/skills/qc/qa-script-designer/api/endpoint.md +61 -0
  91. package/core/skills/qc/qa-script-designer/api/security.md +41 -0
  92. package/core/skills/qc/qa-script-designer/mobile/e2e.md +35 -0
  93. package/core/skills/qc/qa-script-designer/mobile/functional/feature.md +32 -0
  94. package/core/skills/qc/qa-script-designer/mobile/functional/screen.md +42 -0
  95. package/core/skills/qc/qa-script-designer/mobile/integration.md +39 -0
  96. package/core/skills/qc/qa-script-designer/mobile/non-functional.md +39 -0
  97. package/core/skills/qc/qa-script-designer/web/e2e.md +36 -0
  98. package/core/skills/qc/qa-script-designer/web/functional/api.md +39 -0
  99. package/core/skills/qc/qa-script-designer/web/functional/gui-feature.md +34 -0
  100. package/core/skills/qc/qa-script-designer/web/functional/gui-screen.md +42 -0
  101. package/core/skills/qc/qa-script-designer/web/integration.md +43 -0
  102. package/core/skills/qc/qa-script-designer/web/non-functional.md +42 -0
  103. package/core/skills/qc/qa-script-runner/mobile/run.md +38 -0
  104. package/core/skills/qc/qa-script-runner/report.md +41 -0
  105. package/core/skills/qc/qa-script-runner/web/run.md +48 -0
  106. package/core/steps/context-loader.md +1 -1
  107. package/core/steps/gate.md +7 -1
  108. package/core/steps/qc-scope.md +45 -2
  109. package/core/steps/qc-stamp.md +4 -4
  110. package/core/steps/report-footer.md +10 -9
  111. package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
  112. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +13 -12
  113. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +3 -3
  114. package/docs/02-concepts/traceability.md +1 -1
  115. package/docs/03-guides/developer.md +1 -1
  116. package/docs/03-guides/tester-qa.md +40 -11
  117. package/docs/04-reference/commands.md +4 -2
  118. package/docs/04-reference/modules.md +2 -1
  119. package/docs/04-reference/trace-schema.md +4 -4
  120. package/docs/explain/17-qc-design-test.md +5 -5
  121. package/docs/explain/18-qc-review.md +42 -20
  122. package/docs/explain/19-qc-run-test.md +13 -10
  123. package/docs/explain/20-qc-report.md +3 -3
  124. package/docs/explain/23-fix-bug.md +2 -2
  125. package/docs/explain/README.md +2 -2
  126. package/docs/plans/qc-surgery/01-checklist.md +86 -21
  127. package/docs/plans/qc-surgery/PLAN_v2.md +295 -0
  128. package/docs/plans/qc-surgery/exec-S-ap-stack-typescript.md +420 -0
  129. package/docs/plans/qc-surgery/exec-S0-guard-cam-stack-cu.md +400 -0
  130. package/docs/plans/qc-surgery/exec-S1-hai-module-thay-qc-playwright.md +267 -0
  131. package/docs/plans/qc-surgery/exec-S2-qa-runner-thanh-script-designer-runner.md +340 -0
  132. package/docs/plans/qc-surgery/exec-S3-viet-lai-tieu-chi-review-script.md +322 -0
  133. package/docs/plans/qc-surgery/exec-S5-an-theo-don-dau-vet-stack-cu.md +292 -0
  134. package/package.json +1 -1
  135. package/core/commands/qc-run-test.md +0 -561
  136. package/core/modules/qc-playwright/stack-profile.yaml +0 -66
  137. package/core/skills/qc/qa-reviewer/script/e2e.md +0 -95
  138. package/core/skills/qc/qa-reviewer/script/functional.md +0 -109
  139. package/core/skills/qc/qa-reviewer/script/integration.md +0 -99
  140. package/core/skills/qc/qa-reviewer/script/non-functional.md +0 -134
  141. package/core/skills/qc/qa-runner/e2e.md +0 -49
  142. package/core/skills/qc/qa-runner/functional/api.md +0 -35
  143. package/core/skills/qc/qa-runner/functional/gui-feature.md +0 -57
  144. package/core/skills/qc/qa-runner/functional/gui-screen.md +0 -61
  145. package/core/skills/qc/qa-runner/integration.md +0 -47
  146. package/core/skills/qc/qa-runner/non-functional.md +0 -49
  147. package/core/skills/qc/qa-runner/report/report.md +0 -37
@@ -4,7 +4,7 @@ Check read-only độ phủ giữa spec, code, và test — gồm cả PRD versi
4
4
 
5
5
  ## Gate
6
6
 
7
- *Checkpoint: **không chặn** — read-only (ghi trace-report.json + TSV status, không đụng spec/code). Gate Bước 3 bỏ qua CHECKPOINT (Bước 3a).*
7
+ *Checkpoint: **không chặn** — **không phải vì read-only**. Lệnh ghi `trace-report.json`, `.trace-mirror/`, và **append** `trace-history.jsonl`; với `--reconcile-code` còn ghi row TSV `_seams.tsv`. Nó không chặn vì mọi thao tác ghi VÔ ĐIỀU KIỆN đều hoặc dựng lại được, hoặc là `append` — và hai thao tác nguy hơn đều nằm sau `--reconcile-code`. Gate Bước 3 bỏ qua CHECKPOINT (Bước 3a).*
8
8
 
9
9
  # Gate — Quy trình vào chuẩn cho mọi lệnh
10
10
 
@@ -85,7 +85,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
85
85
 
86
86
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
87
87
  |---|---|:---:|
88
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
88
+ | **Không chặn** | `/review-code` · `/validate-traces` · `/debug` **KHÔNG phải vì read-only**: cả ba đều CÓ ghi file. Chúng không chặn vì thao tác ghi của chúng hoặc nằm sau một câu hỏi `(Y/N)`, hoặc nằm sau một cờ, hoặc là `append`/dựng-lại-được | — (vốn không có) |
89
89
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
90
90
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
91
91
 
@@ -93,6 +93,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
93
93
  `--` khỏi phần resolve target, nên cờ này không ảnh hưởng việc tìm file.) Mở đường chạy
94
94
  headless: `claude -p "/generate-code UC1 --yes"`.
95
95
 
96
+ > **Tên lệnh trong bảng trên có máy canh — `R19`.** Mỗi hàng bảng vừa nêu một mức vừa nêu
97
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
98
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
99
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
100
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
101
+
96
102
  > **KHÔNG tự suy mức từ bảng này.** Mỗi lệnh **tự khai** mức của nó ở một dòng `*Checkpoint: …*`
97
103
  > ngay dưới `## Gate` của chính nó — đọc dòng đó, đừng suy diễn. Bảng trên chỉ giải thích ba mức
98
104
  > **nghĩa là gì**.
@@ -796,7 +802,7 @@ Không tìm thấy seam/stub nào → bỏ qua im lặng.
796
802
  Với mỗi file `.tsv` đã xử lý: ghi `spec_ver`, `status`, `last_updated` đã cập nhật lại disk.
797
803
  Đồng thời **đồng bộ `uc_status` ← `@trace.status`** của file `.feature` tương ứng (header `.feature` là nguồn-sự-thật về duyệt BDD — người đặt `approved` sau khi review sạch, giống PO đặt PRD Metadata `Status`). Nhờ vậy `approved_ucs` trên dashboard phản ánh đúng thay vì luôn = 0.
798
804
  Và **đồng bộ `prd_status` ← `| **Status** |`** của PRD tương ứng (`{paths.specs_dir}/{domain}/{prd-slug}/{TICKET-ID}-{prd-slug}.md`) — đối xứng với `uc_status`: PRD Metadata là nguồn-sự-thật về duyệt PRD. Không có bước này thì `prd_status` là **write-once** (chỉ `/generate-bdd` ghi một lần) và sẽ giữ `approved` vĩnh viễn sau khi `/refine-prd` hay `/review-context --fix` reset PRD về `draft`. *(Step 4 đã đọc file PRD này rồi — không phát sinh I/O.)*
799
- **Đừng** sửa `dev_selftest`/`dev_selftest_at` (do `/dev-run-test` sở hữu) hay `qc_status`/`qc_run_at`/`qc_owner`/`qc_blocked_by` (do `/qc-run-test` + `/report-bug` sở hữu); lệnh này chỉ đọc chúng cho report.
805
+ **Đừng** sửa `dev_selftest`/`dev_selftest_at` (do `/dev-run-test` sở hữu) hay `qc_status`/`qc_run_at`/`qc_owner`/`qc_blocked_by` (do `/qc-run-script` + `/qc-run-manualtest` + `/report-bug` sở hữu); lệnh này chỉ đọc chúng cho report.
800
806
 
801
807
  ### Step 6b — Ghi mốc `spec_baseline` cho lần audit sau
802
808
 
@@ -901,7 +907,7 @@ qc_passing = rows where qc_status == pass
901
907
  qc_failing = rows where qc_status == fail
902
908
  qc_skipped = rows where qc_status == skip
903
909
  qc_not_run = rows where qc_status in (not_run, —)
904
- # qc_status is the OFFICIAL QC automation result (set by /qc-run-test),
910
+ # qc_status is the OFFICIAL QC automation result (set by /qc-run-script + /qc-run-manualtest),
905
911
  # shown alongside — never merged with — dev_selftest.
906
912
  waiting_dev = rows where qc_owner == dev # PM view: QC-found, waiting on dev to fix
907
913
  waiting_po = rows where qc_owner == po # PM view: blocked, waiting on PO to confirm/clarify
@@ -0,0 +1,13 @@
1
+ name: "QC Playwright (TypeScript)"
2
+ version: "1.0.0"
3
+ description: "QC automation — Playwright + TypeScript. Phục vụ HAI nền: web (automation/) và API/system (api-automation/)"
4
+ language: "TypeScript"
5
+ framework: "Playwright Test"
6
+ stack_type: "qc-automation"
7
+ default_layer_order:
8
+ - Test case Markdown (.Test.md) — nguồn sự thật, review xong mới sinh code
9
+ - Test data (data/*.data.ts)
10
+ - Page Object (pages/*.page.ts) · API Object (api/*.api.ts)
11
+ - Fixture (fixtures/*.fixture.ts)
12
+ - Spec (tests/[feature]/*.spec.ts)
13
+ test_framework: "Playwright Test + expect"
@@ -0,0 +1,99 @@
1
+ # QC automation module — Playwright + TypeScript.
2
+ #
3
+ # Nguồn: upstream/qc-base-new/Automation-Standards.md (Approved) §1 §2.3 §3 §6.1 §9.2
4
+ # upstream/qc-base-new/API-Testing-Standards.md (Approved) §1 §2.1 §7.2 §7.3
5
+ #
6
+ # Module này phục vụ HAI nền — web và system(API) — vì cả hai dùng CÙNG stack
7
+ # (AD-API-001: "Playwright API mode thay vì framework riêng, để tái dùng infrastructure
8
+ # với Web testing"). Tách làm hai module là khai dãy phiên bản Playwright/TS hai lần.
9
+ # Nền mobile ở modules/qc-wdio-appium (stack khác hẳn: WebdriverIO + Appium).
10
+ #
11
+ # CHỌN NỀN LÚC CHẠY: theo `active_platform` đã phân giải ở trạm 1 (steps/qc-scope.md).
12
+ # KHÔNG có key cấu hình riêng cho việc này — một pass QC đã khoá đúng một nền, hỏi lại
13
+ # bằng một field thứ hai là tạo hai đáp án cho một câu.
14
+ #
15
+ # web · webview → layout.web app · app-ios · … → qc-wdio-appium
16
+ # system → layout.api
17
+
18
+ versions:
19
+ playwright: "latest" # Playwright Test — runner + assertion + reporter, không thêm Jest/Mocha
20
+ typescript: "v5.x" # strict mode
21
+
22
+ build:
23
+ web:
24
+ test: "npx playwright test"
25
+ e2e: "npx playwright test tests/ --grep @e2e"
26
+ report: "npx playwright show-report"
27
+ show_trace: "npx playwright show-trace test-results/<test>/trace.zip"
28
+ api:
29
+ test: "npx playwright test --config=api-automation/playwright.config.ts"
30
+ report: "npx playwright show-report"
31
+
32
+ layout:
33
+ # §2.3 của Automation-Standards — mirror test-suites/, KHÔNG đổi tên thư mục.
34
+ web: |
35
+ automation/
36
+ ├── playwright.config.ts
37
+ ├── package.json · tsconfig.json
38
+ ├── pages/ ← Page Object: base.page.ts · <feature>.page.ts
39
+ ├── tests/ ← spec, mirror test-suites/: {TICKET-ID}/<feature>-happy-path.spec.ts
40
+ ├── data/ ← <feature>.data.ts (ref TDS artifact)
41
+ ├── fixtures/ ← base.fixture.ts
42
+ ├── helpers/ ← <helper>.ts
43
+ └── reports/ ← sinh ra, gitignored
44
+
45
+ # §2.1 của API-Testing-Standards — thư mục gốc RIÊNG, "tách biệt với automation/ (web)
46
+ # để tránh xung đột config và dependency". api/ thay cho pages/; không có Page Object.
47
+ api: |
48
+ api-automation/
49
+ ├── playwright.config.ts ← config riêng của API mode
50
+ ├── package.json · tsconfig.json
51
+ ├── api/ ← API Object: base.api.ts · <resource>.api.ts
52
+ ├── tests/ ← {TICKET-ID}/<feature>-{happy-path,negative,security}.spec.ts
53
+ ├── data/ ← <resource>.data.ts
54
+ ├── fixtures/ ← api.fixture.ts (shared API context, auth token)
55
+ ├── helpers/ ← schema.helper.ts · auth.helper.ts
56
+ └── reports/ ← sinh ra, gitignored
57
+
58
+ naming:
59
+ # §9.2 (web) · §7.2 (api). File kebab-case; class PascalCase; method camelCase verb-first.
60
+ page_object: "pages/<feature>.page.ts → class <Feature>Page extends BasePage"
61
+ api_object: "api/<resource>.api.ts → class <Resource>API extends BaseAPI"
62
+ spec: "tests/{TICKET-ID}/<feature>-<scenario>.spec.ts"
63
+ test_data: "data/<resource>.data.ts"
64
+ fixture: "fixtures/<name>.fixture.ts"
65
+ helper: "helpers/<name>.helper.ts"
66
+ test_case_md: "{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md"
67
+
68
+ locator_priority:
69
+ # §6.1 — chỉ áp cho nền web. API không có locator.
70
+ web: "getByRole → getByLabel → getByPlaceholder → getByTestId → getByText → locator('[css]') (last resort, ghi lý do)"
71
+ note: "Giá trị test-id lấy từ bảng Test Selectors §4.5.6 của tech-doc, KHÔNG scan runtime.
72
+ Tên thuộc tính đọc từ `@trace.testid_attr`; nếu ≠ data-testid thì phải gọi
73
+ `expect.configure`/`selectors.setTestIdAttribute` trước khi dùng getByTestId."
74
+
75
+ reporting:
76
+ web: "Playwright HTML Report" # §1 + OQ-01 đã đóng 2026-06-02: Phase 1 KHÔNG cần Allure
77
+ api: "Playwright HTML Report" # Allure defer Phase 2
78
+
79
+ trace_tags:
80
+ # Dấu comment là `//` (TypeScript) — stack cũ dùng `#`. Bộ parse bám chuỗi `@trace.*`,
81
+ # không bám dấu comment (bin/lint-trace.js:733), nên đổi dấu là an toàn; lane DEV đã
82
+ # dùng `//` từ trước.
83
+ verifies: "// @trace.verifies={UC-ID}-SC{N}"
84
+ source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
85
+ test_type: "// @trace.test_type=functional|integration|e2e|non-functional"
86
+
87
+ artifact_id_prefix:
88
+ # §7.3 API-Testing-Standards — dãy API độc lập với web/mobile.
89
+ api: "TS-API · SCN-API · TC-API · AUT-API · TDS-API"
90
+
91
+ # Luật VIẾT CODE (Page Object 3 lớp, assertion, wait, anti-pattern, flaky policy) KHÔNG ở
92
+ # đây — chúng ở skills/qc/qa-script-designer/_shared/web-conventions.md.
93
+ # Ranh giới: hồ sơ này trả lời "chạy ở đâu, đặt tên gì"; skill trả lời "viết thế nào".
94
+ # Vì sao tách: hồ sơ được đọc NGUYÊN vào ngữ cảnh mỗi lần chạy lệnh, còn skill nạp MỘT
95
+ # file theo lane — nhồi luật vào đây bắt mọi lần làm web phải đọc cả luật của nền khác.
96
+
97
+ # qc_status: /qc-run-script ghi pass|fail|skip|not_run + qc_run_at vào
98
+ # {trace_dir}/{domain}/{prd-slug}/{UC-ID}-{active_platform}.tsv — song song với dev_selftest,
99
+ # và đây là kết quả QC CHÍNH THỨC hiện trên Living Docs.
@@ -0,0 +1,20 @@
1
+ name: "QC WebdriverIO + Appium (mobile)"
2
+ version: "1.0.0"
3
+ description: "QC automation cho nền app — WebdriverIO v9 + Appium v2 + UiAutomator2, TypeScript"
4
+ language: "TypeScript"
5
+ framework: "WebdriverIO + Appium"
6
+ stack_type: "qc-automation"
7
+ default_layer_order:
8
+ - Test case Markdown (.Test.md) — nguồn sự thật, review xong mới sinh code
9
+ - Test data (data/*.data.ts)
10
+ - Screen Object (screens/*.screen.ts)
11
+ - Helper (api · device · gesture)
12
+ - Spec (tests/[feature]/*.spec.ts)
13
+ test_framework: "WebdriverIO + Appium + Allure"
14
+
15
+ # ⚠️ PHẠM VI HẸP — KHAI RÕ (PLAN_v2 §8 luật 4).
16
+ # Module này được port theo KHUNG từ Mobile-Automation-Standards.md (Approved) ở Bước S,
17
+ # và CHƯA được chạy thử trên một dự án mobile thật. Ba mục riêng của nền mobile (§6 API
18
+ # Helper · §9 Gesture Helper · §12 Environment Validation) đã có mặt, nhưng các con số
19
+ # trong đó (toạ độ swipe, timeout) là giá trị mặc định của chuẩn, chưa hiệu chỉnh theo
20
+ # thiết bị thật. Lần đầu chạy thật: đối chiếu lại §12 trước khi tin kết quả.
@@ -0,0 +1,107 @@
1
+ # QC automation module — WebdriverIO + Appium, nền app (mobile).
2
+ #
3
+ # Nguồn: upstream/qc-base-new/Mobile-Automation-Standards.md (Approved)
4
+ # §1 §2 §3 §6 §7.1 §9 §10.2 §12
5
+ #
6
+ # ⚠️ ĐÂY KHÔNG PHẢI BẢN COPY CỦA qc-playwright-ts. Chuẩn mobile dài hơn chuẩn web 129 dòng,
7
+ # và phần dôi ra không phải văn vẻ: §6 API Helper · §9 Gesture Helper · §12 Environment
8
+ # Validation Checklist. Một hồ sơ mobile copy từ web sẽ im lặng thiếu ba mục đó, và cái
9
+ # thiếu chỉ lộ ra khi có người chạy thật trên máy thật — tức SAU khi đã tin là xong.
10
+ #
11
+ # CHỌN NỀN LÚC CHẠY: theo `active_platform` ở trạm 1 (steps/qc-scope.md).
12
+ # app · app-ios · app-android → module này
13
+ # web · webview · system → qc-playwright-ts
14
+
15
+ versions:
16
+ appium: "v2.x" # latest
17
+ webdriverio: "v9.x" # latest — test runner
18
+ typescript: "v5.x"
19
+ android_driver: "UiAutomator2" # driver@latest
20
+ emulator: "Genymotion" # trial, latest
21
+
22
+ build:
23
+ test: "npx wdio ./wdio.config.ts"
24
+ android: "npx wdio ./wdio.android.config.ts"
25
+ dry_run: "npx wdio ./wdio.config.ts --dry-run"
26
+ appium: "npx appium"
27
+ report: "npx allure generate reports/allure-results --clean && npx allure open"
28
+
29
+ layout:
30
+ mobile: |
31
+ projects/[ProjectName]/mobile-automation/
32
+ ├── wdio.config.ts ← WebdriverIO + Appium
33
+ ├── wdio.android.config.ts ← override riêng Android
34
+ ├── package.json ← dependency mobile RIÊNG
35
+ ├── tsconfig.json · .env.example
36
+ ├── screens/ ← Screen Object (≈ Page Object): base.screen.ts · <feature>.screen.ts
37
+ ├── tests/ ← {TICKET-ID}/<feature>-{happy-path,negative,api-sync}.spec.ts
38
+ ├── data/ ← <feature>.data.ts (dùng chung chuẩn với web)
39
+ ├── fixtures/ ← base.fixture.ts
40
+ ├── helpers/ ← api.helper.ts · device.helper.ts · gesture.helper.ts
41
+ └── reports/ ← Allure output, gitignored
42
+
43
+ naming:
44
+ # §10.2 — khác web: hậu tố "Screen", không phải "Page".
45
+ screen_object: "screens/<feature>.screen.ts → class <Feature>Screen extends BaseScreen"
46
+ spec: "tests/{TICKET-ID}/<feature>-<scenario>.spec.ts"
47
+ test_data: "data/<feature>.data.ts"
48
+ helper: "helpers/<name>.helper.ts"
49
+ test_case_md: "{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md"
50
+
51
+ locator_priority:
52
+ # §7.1 — KHÁC HẲN web. Không có getByRole/getByLabel.
53
+ order: "~accessibilityId → id (resource-id) → xpath (last resort, ghi lý do)"
54
+ note: "`~accessibilityId` dùng Android content-desc và YÊU CẦU dev gán. Giá trị lấy từ
55
+ bảng Test Selectors §4.5.6 của tech-doc, tên thuộc tính đọc từ `@trace.testid_attr`
56
+ (RN: testID · Flutter: Key/Semantics(identifier:) · native iOS: accessibilityIdentifier)."
57
+
58
+ # ── Ba mục CHỈ mobile mới có. Thiếu bất kỳ mục nào là hồ sơ chưa xong. ──
59
+
60
+ api_helper:
61
+ # §6 — mobile verify dữ liệu server bằng Playwright request, TÁI DÙNG từ automation/ (web).
62
+ file: "helpers/api.helper.ts"
63
+ impl: "class ApiHelper dùng `request`/`APIRequestContext` của @playwright/test;
64
+ baseUrl = process.env.API_BASE_URL"
65
+ why: "spec `*-api-sync.spec.ts` đối chiếu thứ hiện trên màn hình với thứ server thật có —
66
+ một màn hình hiển thị đúng dữ liệu CŨ vẫn là bug, và UI assertion không bắt được."
67
+
68
+ gesture_helper:
69
+ # §9 — web không cần mục này.
70
+ file: "helpers/gesture.helper.ts"
71
+ impl: "class GestureHelper — scrollDown · swipeLeft · … dựng bằng
72
+ browser.action('pointer', { parameters: { pointerType: 'touch' } })"
73
+ note: "Toạ độ mặc định trong chuẩn (x=540, startY=800, endY=300, duration=500) là giá trị
74
+ của MỘT cấu hình màn hình. Hiệu chỉnh theo thiết bị thật trước khi tin kết quả."
75
+
76
+ environment_validation:
77
+ # §12 — Gate 6B. Chạy TRƯỚC mọi lần execute mobile.
78
+ gate: "6B"
79
+ checklist:
80
+ - "Genymotion emulator đang chạy và `adb devices` thấy thiết bị"
81
+ - "APK đúng version đã install trên emulator"
82
+ - "App khởi động thành công (smoke check bằng tay)"
83
+ - "API_BASE_URL gọi được TỪ emulator: `adb shell curl ${API_BASE_URL}/health`"
84
+ - "Test data đã seed trên server (nếu cần)"
85
+ - ".env đã cấu hình đúng environment hiện tại"
86
+ - "Appium server connect được: `npx appium` chạy không lỗi"
87
+ - "WDIO dry-run pass: `npx wdio ./wdio.config.ts --dry-run`"
88
+ why: "Tám mục này là ranh giới giữa 'test đỏ' và 'môi trường chưa sẵn sàng'. Bỏ qua thì
89
+ mọi FAIL đều trông như product-gap, và QC đi mở bug cho một cái emulator chưa bật."
90
+
91
+ reporting:
92
+ # §1 — ⚠️ NGƯỢC với luật "No Allure" của stack cũ và của nền web.
93
+ tool: "Allure Report v2.x"
94
+ note: "Nền web dùng Playwright HTML Report (OQ-01 đóng 2026-06-02: Allure defer Phase 2).
95
+ Nền mobile thì Allure là BẮT BUỘC theo §1. Hai nền khác nhau ở điểm này — đừng
96
+ 'thống nhất' chúng lại; đó là quyết định của chuẩn, không phải chỗ sót."
97
+
98
+ trace_tags:
99
+ verifies: "// @trace.verifies={UC-ID}-SC{N}"
100
+ source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
101
+ test_type: "// @trace.test_type=functional|integration|e2e|non-functional"
102
+
103
+ # Luật VIẾT CODE ở skills/qc/qa-script-designer/_shared/mobile-conventions.md.
104
+ # Ranh giới: hồ sơ này trả lời "chạy ở đâu, đặt tên gì"; skill trả lời "viết thế nào".
105
+
106
+ # qc_status: /qc-run-script ghi pass|fail|skip|not_run + qc_run_at vào
107
+ # {trace_dir}/{domain}/{prd-slug}/{UC-ID}-{active_platform}.tsv
@@ -11,7 +11,7 @@ Ba mức, định nghĩa đầy đủ ở `steps/gate.md` Bước 3a — **đây
11
11
 
12
12
  | Mức | Lệnh nào | `--yes` bỏ qua? |
13
13
  |---|---|:---:|
14
- | **Không chặn** | read-only (`/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs`) | — |
14
+ | **Không chặn** | `/review-code` · `/validate-traces` · `/debug` **không** vì read-only (cả ba đều ghi file), mà vì thao tác ghi nằm sau `(Y/N)` / sau một cờ / là `append` | — |
15
15
  | **Chặn thường** | mọi lệnh sinh/sửa artifact | ✅ |
16
16
  | **Chặn CỨNG** | ghi đè file đã có · `--resume` · migrate · prune | ❌ |
17
17
 
@@ -95,7 +95,7 @@ kém, hay một bản **dán nhãn sai**?"* — vế sau thì không `--force`
95
95
  - Field có consumer mà **không có producer** là lỗi chặn build — đó chính là hình dạng
96
96
  của G1 (`@trace.sc_version`: 3 consumer, 0 producer, DRIFT chết mà không ai báo).
97
97
  - **Làm mất hiệu lực ≠ ghi đè.** Cột trace có chủ sở hữu rõ ràng — `dev_selftest`/`dev_selftest_at`
98
- thuộc `/dev-run-test` · `qc_status`/`qc_run_at` thuộc `/qc-run-test` · `test_count`/`test_classes`
98
+ thuộc `/dev-run-test` · `qc_status`/`qc_run_at` thuộc `/qc-run-script` + `/qc-run-manualtest` · `test_count`/`test_classes`
99
99
  thuộc `/dev-gen-test` — và **chỉ chủ được ghi giá trị KHẲNG ĐỊNH** (`pass`/`fail`/số lượng).
100
100
  Nhưng lệnh nào làm giá trị đó **HẾT ĐÚNG** (spec đổi, code đổi) thì **BẮT BUỘC** hạ nó về giá
101
101
  trị "chưa biết" (`not_run` / `—`). Giữ một `pass` đã hết hiệu lực là **báo cáo sai**, không phải
@@ -8,7 +8,7 @@ adapted: danh sách lệnh theo pipeline HIỆN TẠI (6 trạm QC) · bổ sung
8
8
  # Self-Review — 3 nhóm lỗi AI cần tự kiểm trước khi in Report
9
9
 
10
10
  Skill **tự chứa**, dùng chung cho các lệnh QC: `qc-analyze` · `qc-plan` · `qc-design-test` ·
11
- `qc-review` · `qc-run-test` · `qc-report` — và hai nhánh phụ `report-bug` · `propose-scenario`.
11
+ `qc-review-testcase` · `qc-run-script` · `qc-report` — và hai nhánh phụ `report-bug` · `propose-scenario`.
12
12
 
13
13
  Mỗi file lệnh có mục `## Self-Review` **riêng**, liệt kê tiêu chí **cụ thể cho output của chính
14
14
  nó**. File này định nghĩa **3 nhóm lỗi gốc** mà mọi tiêu chí cụ thể đó phải phủ được ít nhất một
@@ -36,7 +36,7 @@ Bảng phân định hiện tại — đừng dùng self-review cho những vi
36
36
  | BR mà BDD nhắc nhưng phân tích bỏ sót | **Guard BR-tag** (so với tag `@trace.business_rules`) | `/qc-analyze` |
37
37
  | Scenario chưa có test case nào phủ | **Guard SC coverage** (đếm TC trỏ tới từng SC) | `/qc-design-test` |
38
38
  | Bảng §4.5.6 trỏ SC không tồn tại · header thiếu `@trace.testid_attr` · bảng lệch code | **T15–T18** | `bin/lint-trace.js` |
39
- | Ghi `pass` trên row `DRIFT`/`ORPHANED` | **T12** + `positive_assertion_guards` | `bin/lint-trace.js` + `/qc-run-test` |
39
+ | Ghi `pass` trên row `DRIFT`/`ORPHANED` | **T12** + `positive_assertion_guards` | `bin/lint-trace.js` + `/qc-run-script` |
40
40
  | Sổ trace sai cấu trúc / enum / trùng `sc_id` | **T1–T8** | `bin/lint-trace.js` |
41
41
 
42
42
  Còn lại — **không có nguồn đối chiếu cơ học** — mới là việc của self-review: rủi ro bịa ra,
@@ -11,7 +11,7 @@ upstream_sha: c7ca6cfb798c609f18ffe20a38f64f95c76e1919
11
11
  > Giữ một bản kém hơn làm mặc định là để người không biết có cờ nhận bản kém.
12
12
  >
13
13
  > **Một chỗ CỐ Ý khác upstream:** mức nặng nhất dùng từ **`Blocker`**, không phải `Critical`.
14
- > Lý do: `/qc-run-test` đọc `🔴 Blocker` để đặt *"scenario đang chờ PO"* vào sổ kết quả trace.
14
+ > Lý do: `/qc-run-script` đọc `🔴 Blocker` để đặt *"scenario đang chờ PO"* vào sổ kết quả trace.
15
15
  > Đổi từ là đứt liên kết đó. Ba mức còn lại giữ nguyên upstream.
16
16
  >
17
17
  > **Phạm vi: MỘT file cho cả (PRD × nền)** *(B11)*, không phải một file mỗi UC. Đây là quay về
@@ -60,7 +60,7 @@ Ghi vào **mục Data Flow** của `{qc_artifact_dir}REQUIREMENT_ANALYSIS.md`
60
60
  - Sơ đồ/list luồng dữ liệu cho mỗi kịch bản chính.
61
61
  - Danh sách integration point + state change + failure point.
62
62
  - Gợi ý loại test cần cho từng điểm (gui-feature / integration / e2e) khi sang qa-designer.
63
- - Dữ liệu/trạng thái cần chuẩn bị & cleanup → đầu vào fixture cho qa-runner.
63
+ - Dữ liệu/trạng thái cần chuẩn bị & cleanup → đầu vào fixture cho `qa-script-designer`.
64
64
 
65
65
  Chặng nào luồng/hành vi chưa rõ (vd lỗi xử lý ra sao, retry, partial commit) →
66
66
  ghi vào `{qc_artifact_dir}DOC_GAP.md` (loại MISSING / OPEN QUESTION).
@@ -18,7 +18,7 @@ có cấu trúc, đủ thông tin để người nhận trả lời được nga
18
18
  > mỗi UC là các hàng phân biệt bằng cột `UC`. Không còn một-file-mỗi-UC.
19
19
  >
20
20
  > **Một chỗ cố ý khác upstream:** mức nặng nhất dùng `🔴 Blocker`, không phải `Critical` —
21
- > `/qc-run-test` đọc đúng từ đó để đặt *"scenario đang chờ PO"* vào sổ trace.
21
+ > `/qc-run-script` đọc đúng từ đó để đặt *"scenario đang chờ PO"* vào sổ trace.
22
22
 
23
23
  ## Đầu vào
24
24
 
@@ -0,0 +1,123 @@
1
+ ---
2
+ name: automation-feasibility-matrix
3
+ description: Đánh giá từng test case đã APPROVED là Automatable Y/N, kèm lý do chuẩn hoá và %Automated/Total. Dùng bởi /qc-automation-assess.
4
+ ---
5
+
6
+ # Automation Feasibility Matrix
7
+
8
+ Skill **tự chứa** cho `/qc-automation-assess`: đánh giá từng TC trong `TC_<FEATURE>.Test.md` đã
9
+ qua cổng `/qc-review-testcase` là `Automatable: Y/N`, kèm lý do chuẩn hoá và `%Automated/Total`.
10
+
11
+ ## Khi nào trigger
12
+
13
+ Sau `/qc-review-testcase` — TC đã `APPROVED` và chưa từng qua automation-assess, **hoặc** TC bị
14
+ gắn cờ `🔄 Re-assess` vì scenario nó verify đang `DRIFT` (BDD/spec đã đổi).
15
+
16
+ ## Tiêu chí đánh giá — trả lời TUẦN TỰ, dừng ở câu đầu tiên là "Có"
17
+
18
+ Câu nào trả lời "Có" thì **đó là lý do `N`**, và không cần xét tiếp:
19
+
20
+ 1. **Có bước nào đòi input từ con người / bên thứ ba mà script không tự lấy được?**
21
+ (OTP SMS thật · captcha · chữ ký tay · sinh trắc học trên thiết bị thật)
22
+ → `N`, nhãn **`Cần OTP/captcha thủ công`**
23
+ 2. **Có phụ thuộc hệ thống / thiết bị ngoài tầm kiểm soát của script?**
24
+ (app khác trên máy thật · máy POS vật lý · email/SMS thật không có test inbox)
25
+ → `N`, nhãn **`Phụ thuộc hệ thống ngoài`**
26
+ 3. **UI/flow có đang thay đổi liên tục?** (redesign · A/B test). Script viết hôm nay nhiều khả
27
+ năng vỡ trong < 2 tuần vì một thay đổi UI **đã biết trước**
28
+ → `N`, nhãn **`UI không ổn định`** — ghi rõ mốc dự kiến ổn định để re-assess
29
+ 4. **Element cần thao tác có test-id ổn định không, và dev có cam kết thêm nếu thiếu không?**
30
+ Không có **VÀ** không có cam kết → `N`, nhãn **`Thiếu test-id contract``**
31
+ > Khác với ca *"sẽ có nhưng chưa"* — ca đó vẫn `Y`, ghi chú chờ `IMPROVE-xxx`.
32
+ 5. **ROI có dương không?** Áp công thức dưới; âm rõ ràng → `N`, nhãn **`Effort > ROI`**
33
+ 6. Không rơi vào 1–5 → **`Y`**
34
+
35
+ ## Công thức ROI *(ước lượng nhanh, không cần chính xác tuyệt đối)*
36
+
37
+ ```
38
+ ROI ≈ (tần suất chạy lại × chi phí test tay mỗi lần)
39
+ − (chi phí viết script + chi phí bảo trì dự kiến)
40
+ ```
41
+
42
+ | Tín hiệu ROI **thấp** | Tín hiệu ROI **cao** |
43
+ |---|---|
44
+ | TC chỉ chạy **một lần** (migration một-lần, config set một lần) — viết script tốn hơn chạy tay 1 lần | TC có **nhiều biến thể dữ liệu** (boundary/negative): test tay tốn tuyến tính theo số biến thể, script chạy lại gần như miễn phí |
45
+
46
+ **Thứ tự ưu tiên khi có nhiều TC `Y` mà chưa đủ thời gian làm hết:** `P0` trước, rồi `P1`/`P2`.
47
+ TC `P0` gần như luôn ROI dương và là ứng viên trực tiếp cho smoke suite (`/qc-smoke-test` chạy
48
+ mỗi build).
49
+
50
+ > ⚠️ **`P0` mà rơi vào `N` là tín hiệu đáng chú ý hơn bình thường.** Tính năng lõi không có
51
+ > smoke test tự động là rủi ro cao cho cả mục tiêu *"phát hiện lỗi sớm mỗi build"*. Ghi rõ lý do
52
+ > **và** cân nhắc đề xuất `IMPROVE-xxx` để gỡ rào cản, thay vì chấp nhận `N` vĩnh viễn.
53
+
54
+ ## Tín hiệu ổn định — dùng cho tiêu chí 3
55
+
56
+ | Ổn định | KHÔNG ổn định |
57
+ |---|---|
58
+ | Màn hình đã ship ≥ 1 release, không đổi lớn gần đây | Đang trong sprint thiết kế lại UI |
59
+ | Có test-id contract §4.5.6 đã chốt | Element identify bằng text/class tạm thời |
60
+ | Flow nghiệp vụ ổn định | Business rule đang thử nghiệm (feature flag % rollout) |
61
+
62
+ ## Guard — Re-assessment tự động theo `DRIFT`
63
+
64
+ TC có scenario `@trace.verifies={UC-ID}-SC{N}` mà row đó trong sổ trace đang `status: DRIFT`
65
+ → **re-assess lại từ đầu 6 tiêu chí**, KHÔNG tái dùng phán quyết cũ.
66
+
67
+ Vì sao không tái dùng: spec đổi có thể đổi **cả sáu** câu hỏi — ví dụ một BR mới thêm bước OTP
68
+ biến một TC đang `Y` thành `N`.
69
+
70
+ | Đổi | Xử lý cột `Script file` |
71
+ |---|---|
72
+ | `Y → N` | **GIỮ** path cũ + ghi chú `⚠️ Script đã lỗi thời — cân nhắc gỡ ở lần /qc-design-script kế tiếp`. **KHÔNG tự xoá file** — để người quyết định |
73
+ | `N → Y` | giữ `—`, chờ `/qc-design-script` điền |
74
+
75
+ ## Output format
76
+
77
+ ```markdown
78
+ # Automation Assessment — {TICKET-ID} ({active_platform})
79
+
80
+ | TC ID | UC | Automatable | Lý do (nếu N) | Trace SC | Script file | Ghi chú |
81
+ |---|---|:---:|---|---|---|---|
82
+ | TC_LOGIN_001 | UC1 | Y | — | UC1-SC1 | — *(chưa qua qc-design-script)* | |
83
+ | TC_LOGIN_004 | UC1 | N | Cần OTP/captcha thủ công | UC1-SC4 | — *(không automate)* | Giữ trong bộ manual |
84
+ | TC_LOGIN_002 | UC1 | Y | — | UC1-SC2 | — *(chưa qua qc-design-script)* | 🔄 Re-assess (DRIFT, spec đổi {ngày}) — đã re-check: vẫn Y |
85
+
86
+ **%Automated/Total: {automatable}/{đã đánh giá} = {pct}%**
87
+ **Loại khỏi lượt:** {k} TC của UC chưa APPROVED — {danh sách UC + trạng thái thật}
88
+ ```
89
+
90
+ ### Cột `Script file` — ai ghi, khi nào
91
+
92
+ ```
93
+ /qc-automation-assess → luôn khởi tạo "—" (script chưa tồn tại ở bước này)
94
+ /qc-design-script → ĐIỀN path thật sau khi sinh
95
+ /qc-run-script → ĐỌC cột này để biết chạy file nào — KHÔNG tự suy path
96
+ ```
97
+
98
+ Đây là **chỉ mục ngược duy nhất** từ TC → file code thật; chiều xuôi (code → SC) đã có sẵn qua
99
+ tag `@trace.verifies`. Không có cột này thì `/qc-run-script` phải suy đường dẫn từ quy ước đặt
100
+ tên — suy sai thì chạy sai bộ test, hoặc **chạy 0 test mà vẫn báo xanh**.
101
+
102
+ > **Đường dẫn theo module đã phân giải ở `steps/qc-scope.md` §2b** — `qc-playwright-ts`
103
+ > *(web · system)* hoặc `qc-wdio-appium` *(app)*, mục `§layout.{web|api|mobile}` của
104
+ > `stack-profile.yaml` tương ứng. **Đừng viết cứng tên module ở đây.**
105
+ >
106
+ > *(Tên file theo `§naming` của module: `<feature>.page.ts` + `<feature>-<scenario>.spec.ts`
107
+ > (web) · `<resource>.api.ts` (system) · `<feature>.screen.ts` (app).)*
108
+ >
109
+ > *(Đề xuất gốc của đội QC viết theo TypeScript + Playwright Test / WebdriverIO. Việc đổi stack
110
+ > là một bước RIÊNG, cố ý tách khỏi đợt tách lệnh — xem quyết định F3, Đợt 2 · b2. Khi stack
111
+ > đổi, chỉ đoạn này và `stack-profile.yaml` cần sửa; cơ chế cột `Script file` không đổi.)*
112
+
113
+ ## Nhãn lý do mới phát sinh
114
+
115
+ Không khớp nhãn nào trong 5 nhãn chuẩn → **tạo nhãn mới mô tả đúng lý do** *(đừng ép vào nhãn
116
+ có sẵn)*, rồi liệt kê nó trong report để bổ sung vào danh sách lần sau.
117
+
118
+ > **Vì sao chuẩn hoá nhãn.** Để **đếm được**. *"3 TC không automate vì **thiếu test-id**"* là
119
+ > một tín hiệu hành động được — đi đàm phán với dev. *"3 TC vì lý do kỹ thuật"* thì không.
120
+ >
121
+ > Riêng nhãn `Thiếu test-id contract` nối thẳng với Đợt 0 (hợp đồng test-id §4.5.6): nếu Đợt 0
122
+ > làm đúng thì nhãn này phải **giảm dần theo thời gian** — tức nó đồng thời là **phép đo cho
123
+ > chính Đợt 0**.
@@ -43,4 +43,4 @@ Mỗi journey → 1 TC bám Format; Expected = chuỗi verify point; chuẩn b
43
43
 
44
44
  Ghi vào `{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md` — **Nhóm 6 E2E**. Mỗi journey một TC; tiền điều kiện · kết quả/định tuyến kỳ vọng · BR · phụ thuộc gap · priority ghi dạng trường danh sách.
45
45
 
46
- **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
46
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review-testcase`.
@@ -43,4 +43,4 @@ Chuyển draft → TC chính thức bám **format file `TC_<FEATURE>.Test.md`**:
43
43
 
44
44
  Ghi TC đã chuyển thành functional vào `{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md` — **Nhóm 3 Functional**.
45
45
 
46
- **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
46
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review-testcase`.
@@ -28,9 +28,15 @@ expected/actual) · `#QUESTION`, `#IDEA` placeholder · summary cuối session.
28
28
  ## Mode 2 — Convert Findings
29
29
  Input: session note (#BUG + #IDEA).
30
30
  - **Bug report** mỗi #BUG: title, severity, priority, steps to reproduce, expected/actual, hypothesis root cause.
31
- - **Functional TC mới:** mỗi #BUG đã fix 1–2 TC regression; mỗi #IDEA TC nếu đủ (hoặc backlog).
32
- Đặt đúng layer; bám format TC (Test Data list, Trace BR, 🚫 Block); trace "Origin: Exploratory session <date>".
31
+ - **Functional TC mới → KHÔNG viết luật đây.** Dùng `explore-to-functional.md` Phase 4
32
+ format `TC_<FEATURE>.Test.md` đầy đủ (metadata list, Trace BR, 🚫 Block, Test Data, Steps,
33
+ Expected 1 bullet, Trace matrix). Chỉ thêm một điều riêng của đường này: mỗi TC sinh từ session
34
+ phải mang `Origin: Exploratory session <date>`.
33
35
  - **Weekly summary** (nếu yêu cầu): overview, top findings, coverage gap, recommendations.
34
36
 
37
+ > **Vì sao Mode 2 trỏ đi chứ không tự viết** *(Bước S · S2, 2026-09-17)*: bản cũ mô tả lại format TC
38
+ > bằng một câu rút gọn, trong khi `explore-to-functional.md` Phase 4 đã có bản đủ. Hai bản của một
39
+ > format thì bản ngắn sẽ lạc hậu trước — và người đọc bản ngắn không biết mình đang đọc bản cũ.
40
+
35
41
  ## Output
36
42
  Mode 1: file session note. Mode 2: bug reports + file TC trong `{qc_artifact_dir}test-cases/` + summary.
@@ -16,7 +16,7 @@ Nạp cùng `shared/` (khuôn + độ chính xác + từ điển hành động)
16
16
 
17
17
  ## Khi KHÔNG trigger
18
18
  - Test qua giao diện → `functional/gui-screen`/`gui-feature`
19
- - Luồng dữ liệu API ↔ DB/service khác → `integration/api` · message/event → `integration/kafka`
19
+ - Luồng dữ liệu API ↔ DB/service khác → `integration/api` · message/event → `integration/queue`
20
20
 
21
21
  ---
22
22
 
@@ -111,4 +111,4 @@ Ghi vào `{qc_artifact_dir}test-cases/TC_<FEATURE>_API.Test.md` — **Nhóm 1 En
111
111
 
112
112
  File này chỉ sinh khi có cờ `--api` hoặc `--all`. Mẫu TC: `../api/endpoint.md` · chuỗi auth: `../api/auth-chain.md` · tra mã: `../api/http-status-codes.md` · header: `../api/common-headers.md`.
113
113
 
114
- **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
114
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review-testcase`.
@@ -46,4 +46,4 @@ Liệt kê các màn/route + thứ tự điều hướng · state/dữ liệu tr
46
46
 
47
47
  Ghi vào `{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md` — **Nhóm 3 Functional** (luồng đa màn trong cùng một feature).
48
48
 
49
- **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
49
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review-testcase`.
@@ -51,4 +51,4 @@ chức năng (input/action/display/nav) · constraint (required/min-max/format/e
51
51
 
52
52
  Ghi vào `{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md` — **Nhóm 1 GUI** · **Nhóm 2 Validation** · **Nhóm 3 Functional**.
53
53
 
54
- **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
54
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review-testcase`.