@educa-corp/sdd-framework 0.8.1 → 0.9.1
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 +200 -1
- package/bin/self-check.js +0 -146
- package/bin/trace-schema.json +12 -3
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/generate-code.md +45 -2
- package/core/commands/propose-scenario.md +1 -1
- package/core/commands/qc-analyze.md +22 -260
- package/core/commands/qc-design-test.md +1 -1
- package/core/commands/qc-plan.md +4 -7
- package/core/commands/qc-run-test.md +1 -1
- package/core/commands/refine-prd.md +20 -47
- package/core/commands/report-bug.md +1 -1
- package/core/commands/review-context.md +1 -27
- package/core/commands/validate-traces.md +178 -3
- package/core/skills/qc/qa-analyst/DOC_GAPS.template.md +63 -0
- package/core/skills/qc/qa-analyst/acceptance-criteria.md +2 -4
- package/core/skills/qc/qa-analyst/business-rules.md +4 -38
- package/core/skills/qc/qa-analyst/data-flow.md +3 -5
- package/core/skills/qc/qa-analyst/spec-breakdown.md +7 -9
- package/core/skills/qc/qa-designer/e2e/journey.md +2 -2
- package/core/skills/qc/qa-designer/exploratory/charter.md +1 -1
- package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +1 -1
- package/core/skills/qc/qa-designer/functional/api.md +2 -2
- package/core/skills/qc/qa-designer/functional/gui-feature.md +2 -2
- package/core/skills/qc/qa-designer/functional/gui-screen.md +2 -2
- 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 +2 -2
- package/core/skills/qc/qa-designer/integration/kafka.md +2 -2
- package/core/skills/qc/qa-designer/non-functional.md +2 -2
- package/core/skills/qc/qa-planner/test-plan.md +10 -13
- package/core/skills/qc/qa-reviewer/script/e2e.md +1 -1
- package/core/skills/qc/qa-reviewer/script/exploratory.md +1 -1
- package/core/skills/qc/qa-reviewer/script/functional.md +1 -1
- package/core/skills/qc/qa-reviewer/script/integration.md +1 -1
- package/core/skills/qc/qa-reviewer/script/non-functional.md +1 -1
- package/core/skills/qc/qa-reviewer/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 +2 -2
- package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
- package/core/skills/qc/qa-runner/e2e.md +1 -1
- package/core/skills/qc/qa-runner/exploratory/session.md +1 -1
- package/core/skills/qc/qa-runner/functional/api.md +1 -1
- package/core/skills/qc/qa-runner/functional/gui-feature.md +1 -1
- package/core/skills/qc/qa-runner/functional/gui-screen.md +1 -1
- package/core/skills/qc/qa-runner/integration.md +1 -1
- package/core/skills/qc/qa-runner/non-functional.md +1 -1
- package/core/skills/qc/qa-runner/report/report.md +1 -1
- package/core/steps/review-fanout.md +1 -27
- package/core/templates/project-context.yaml +2 -2
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +2 -2
- package/docs/04-reference/commands.md +1 -1
- package/docs/explain/03-refine-prd.md +6 -8
- package/docs/explain/15-qc-analyze.md +7 -10
- package/docs/explain/16-qc-plan.md +2 -2
- package/package.json +3 -2
- package/bin/qc-base-map.json +0 -595
- package/core/skills/qc/qa-analyst/DOC_GAP.template.md +0 -117
- package/core/skills/qc/qa-analyst/exhaustive-gap-scanner.md +0 -174
- package/core/skills/qc/qa-analyst/spec-issue-reporter.md +0 -100
- package/core/skills/qc/qa-planner/risk-model.md +0 -106
- package/core/steps/gap-verify.md +0 -231
- package/docs/plans/qc-implementation-log.md +0 -1446
- package/docs/plans/qc-merge-plan.md +0 -502
- package/docs/plans/qc-sync-command.md +0 -358
|
@@ -190,6 +190,30 @@ Nhiều cờ scope cùng lúc → **DỪNG**, báo lỗi: chúng loại trừ nh
|
|
|
190
190
|
|
|
191
191
|
`--prd`/`--uc` không phân giải được về một package/UC có thật → **DỪNG** và liệt kê ứng viên. **KHÔNG** âm thầm rơi về `all` (chạy toàn bộ khi người ta xin một phần là đốt 30 phút không ai muốn) và **KHÔNG** âm thầm audit rỗng (báo cáo "sạch" trên 0 row).
|
|
192
192
|
|
|
193
|
+
**Token TRẦN (không mở đầu bằng `--`)** — vd `/validate-traces --reconcile-code LESS-06`:
|
|
194
|
+
|
|
195
|
+
| Token trần trông như | Xử |
|
|
196
|
+
|---|---|
|
|
197
|
+
| **UC-ID** (`{TICKET}-UC{n}`) | coi là `--uc {token}` |
|
|
198
|
+
| **TICKET-ID** phân giải được về đúng **một** feature-package | coi là `--prd {token}` |
|
|
199
|
+
| không phân giải được, hoặc khớp **nhiều** package | **DỪNG**, liệt kê ứng viên |
|
|
200
|
+
| có **cả** token trần **và** một cờ scope | **DỪNG** — hai nguồn phạm vi, không tự chọn hộ |
|
|
201
|
+
|
|
202
|
+
Hai hàng đầu **phải in một dòng** nói rõ đã tự suy, để người dùng thấy mình vừa được hiểu thế nào:
|
|
203
|
+
```
|
|
204
|
+
ⓘ Hiểu `{token}` là `--prd {token}` ({domain}/{prd-slug}). Gõ cờ tường minh nếu ý khác.
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
> **Vì sao không để token trần rơi về `all` (phát hiện 2026-08-27, lượt dùng `--reconcile-code` đầu tiên).**
|
|
208
|
+
> Gate Bước 1 loại mọi token `--` khỏi phần resolve target, và lệnh này **không có target file** — nên
|
|
209
|
+
> token trần trước đây **bị bỏ hoàn toàn** ⇒ `scope` = `all`. Người dùng gõ `--reconcile-code LESS-06`
|
|
210
|
+
> tin rằng đang chạy hẹp một PRD, trong khi lệnh sẽ **GHI vào sổ của cả 20+ PRD**, gồm cả phần của PO
|
|
211
|
+
> khác. Đây đúng điều chính step này cấm hai dòng ở trên — *"KHÔNG âm thầm rơi về `all`"* — chỉ khác là
|
|
212
|
+
> lỗ vào bằng cửa *"không có cờ nào"* thay vì cửa *"cờ không phân giải được"*.
|
|
213
|
+
>
|
|
214
|
+
> Với một lệnh **chỉ đọc** thì đó là đốt thời gian. Với `--reconcile-code` (có GHI) thì đó là ghi ra
|
|
215
|
+
> ngoài phạm vi mà người dùng nghĩ mình đã yêu cầu — hạng nặng hơn hẳn.
|
|
216
|
+
|
|
193
217
|
Lưu `scope` — mọi step sau dùng nó:
|
|
194
218
|
|
|
195
219
|
| Step | Hẹp thế nào |
|
|
@@ -256,11 +280,26 @@ Kiểm tra mảng `services` có tồn tại trong `project-context.yaml` không
|
|
|
256
280
|
Chạy checker xác định trên mọi trace dir đã phân giải ở Step 0:
|
|
257
281
|
|
|
258
282
|
```bash
|
|
259
|
-
npx @educa-corp/sdd-framework --lint-trace --trace {all_trace_dirs, ngăn cách bởi dấu phẩy} --specs {paths.specs_dir}
|
|
283
|
+
npx @educa-corp/sdd-framework --lint-trace --trace {all_trace_dirs, ngăn cách bởi dấu phẩy} --specs {paths.specs_dir} --code {code_roots, ngăn cách bởi dấu phẩy}
|
|
260
284
|
```
|
|
261
285
|
|
|
286
|
+
**Dựng `code_roots` — bắt buộc truyền, đây là chìa khoá kho của T14:**
|
|
287
|
+
|
|
288
|
+
| Chế độ | `code_roots` |
|
|
289
|
+
|---|---|
|
|
290
|
+
| **Umbrella** (có `services:`) | tập **duy nhất** mọi giá trị `path` xuất hiện trong `services:` — gồm cả `path` lồng trong `by_prd_slug`. Bỏ trùng (nhiều domain trỏ chung một submodule là chuyện thường). |
|
|
291
|
+
| **Single-service** | `{paths.src_dir}` |
|
|
292
|
+
| Không phân giải được cái nào | **truyền rỗng** — T14 tự bỏ qua và tự in một dòng nói rõ đã bỏ qua. **Đừng đoán** một thư mục nào đó: quét sai chỗ còn tệ hơn không quét. |
|
|
293
|
+
|
|
262
294
|
*`bin/` sống trong package npm, không được cài vào project — nên `npx` là đường duy nhất. Không có mạng / npx fail → **bỏ qua step này**, in `⚠️ Chưa lint được sổ trace (npx không khả dụng) — kết quả dưới đây chưa được kiểm cấu trúc` vào report, rồi tiếp Step 1. Đừng để nó chặn cả lệnh.*
|
|
263
295
|
|
|
296
|
+
> **Vì sao `--code` (G60).** Trước nó, checker xác định duy nhất mở file thật của dự án chỉ nhận
|
|
297
|
+
> `--trace` và `--specs` — nó **không thể thấy code**, nên ca *"code đã có tag mà sổ ghi
|
|
298
|
+
> `implemented_by` trống"* không có một mắt xác định nào canh. T14 là chiều ngược đó, ở mức
|
|
299
|
+
> **WARN**: nó **không được** chặn lệnh này, vì nợ tồn ở project đang chạy sẽ đỏ khắp nơi ở lần
|
|
300
|
+
> đầu và người ta sẽ tắt cổng — mất luôn T1–T13 thật.
|
|
301
|
+
> Cờ `LEDGER_BEHIND_CODE` ở Step 2b là bản LLM của cùng phép kiểm; `--reconcile-code` là đường ra.
|
|
302
|
+
|
|
264
303
|
**Exit 0 → tiếp Step 1.**
|
|
265
304
|
|
|
266
305
|
**Exit 1 → DỪNG NGAY.** Đừng nạp, đừng tính `status`, đừng ghi lại gì:
|
|
@@ -334,9 +373,23 @@ Với mỗi row có `service` ∈ (`unrouted`, `unresolved`), tra lại `service
|
|
|
334
373
|
> `unrouted` → path. Không sửa tay, không sinh lại BDD. Không có bước này thì `unrouted` **đọng lại
|
|
335
374
|
> vĩnh viễn** — đúng bệnh `TBD` mà G1/G28 đã chỉ ra.
|
|
336
375
|
|
|
337
|
-
### Step 2b — Reverse audit (
|
|
376
|
+
### Step 2b — Reverse audit (hai câu hỏi trên cùng một lượt quét)
|
|
377
|
+
|
|
378
|
+
*Step 2 đi chiều **spec → code** (mỗi row TSV, SC đó implement tới đâu). Step này đi **chiều ngược** — bắt lớp lỗi mà Step 2 cấu trúc không thể thấy.*
|
|
338
379
|
|
|
339
|
-
|
|
380
|
+
**Một lượt quét, HAI câu hỏi.** Đừng dừng ở câu đầu:
|
|
381
|
+
|
|
382
|
+
| | Câu hỏi | Bắt được gì |
|
|
383
|
+
|---|---|---|
|
|
384
|
+
| **A** | *"Tag này trỏ vào SC có tồn tại không?"* | code trỏ vào scenario **đã bị xoá** → `ORPHANED` / `TRACE_ORPHAN` |
|
|
385
|
+
| **B** | *"Sổ có biết SC này đã có code chưa?"* | code đã làm mà **sổ chưa ghi** → `LEDGER_BEHIND_CODE` |
|
|
386
|
+
|
|
387
|
+
> **Vì sao câu B phải nằm ở đây, và vì sao nó từng thiếu (G60).** Bản trước chỉ có câu A. Câu B dùng
|
|
388
|
+
> **đúng dữ liệu đã nạp trong bộ nhớ** — không phát sinh thêm một lần I/O nào — nên bỏ nó là bỏ
|
|
389
|
+
> không vì lý do gì. Và không có nó thì lớp lỗi *"làm rồi mà không ghi sổ"* **không có một mắt nào
|
|
390
|
+
> canh**: `self-check` R1 hỏi *"ai được phép ghi"* (`implemented_by` có producer ⇒ xanh), còn
|
|
391
|
+
> `lint-trace` trước T14 thì không thấy được code. Đo trên một project thật: **504 scenario** có code
|
|
392
|
+
> mà sổ ghi trống, làm dashboard đếm thiếu **28 điểm** phủ code.
|
|
340
393
|
|
|
341
394
|
**Quét (gộp vào cùng lượt quét code của Step 5b — không thêm pass mới):** dưới `{code_base_package}` (CLAUDE.md §2) + `{paths.src_dir}`, thu mọi `@trace.implements={UC-ID}-SC{N}`; trong thư mục test thu mọi `@trace.verifies={UC-ID}-SC{N}`.
|
|
342
395
|
|
|
@@ -352,6 +405,24 @@ Với mỗi tag, hỏi: `SC{N}` đó có tồn tại trong `.feature` của đú
|
|
|
352
405
|
|
|
353
406
|
Không tìm thấy tag mồ côi nào → bỏ qua im lặng.
|
|
354
407
|
|
|
408
|
+
#### Câu B — sổ có theo kịp code chưa?
|
|
409
|
+
|
|
410
|
+
Với mỗi `@trace.implements={UC-ID}-SC{N}` mà `SC{N}` **có** trong `.feature` (tức đã qua câu A):
|
|
411
|
+
|
|
412
|
+
| Điều kiện | Cờ | Ý nghĩa |
|
|
413
|
+
|---|---|---|
|
|
414
|
+
| Row TSV tồn tại **và** `implemented_by != —` | *(sạch)* | Sổ khớp kho |
|
|
415
|
+
| Row TSV tồn tại **nhưng** `implemented_by == —` | `LEDGER_BEHIND_CODE` 🟠 | **Làm rồi mà không ghi sổ.** Row đang hiện `UNTRACKED`, dashboard đếm thiếu, và `/generate-code` sẽ coi là "chưa làm" rồi sinh lại |
|
|
416
|
+
| Không có row TSV nào | — | Step 2 đã thêm row `UNTRACKED` từ `.feature`; lượt sau sẽ vào hàng trên |
|
|
417
|
+
|
|
418
|
+
**Ghi lại cho mỗi cờ:** `sc_id` · `platform` (từ tên file sổ) · danh sách file code mang tag · và **`has_verifies`** = có `@trace.verifies` cho đúng SC đó hay không. Field cuối là thứ quyết định `--reconcile-code` điền row đó thành *có test* hay *chưa test* — thu ngay ở đây vì lượt quét này đã đọc cả hai loại tag.
|
|
419
|
+
|
|
420
|
+
**Nguyên nhân thường gặp, nêu luôn trong report** để người đọc không phải đoán: `/generate-code` dừng ở cổng build nên §Write Trace State chưa chạy; hoặc dev sửa tay cho build pass rồi commit mà không chạy lại lệnh.
|
|
421
|
+
|
|
422
|
+
**Cờ này 🟠 KHÔNG chặn PR** — xem lý do ở Step 7 (`ledger_behind_code_count`). Đường ra là `--reconcile-code` (Step 5f).
|
|
423
|
+
|
|
424
|
+
Không tìm thấy row nào lệch → bỏ qua im lặng.
|
|
425
|
+
|
|
355
426
|
### Step 3 — Tính `status` theo từng scenario
|
|
356
427
|
|
|
357
428
|
Áp dụng quy tắc theo thứ tự ưu tiên (first-match-wins):
|
|
@@ -562,6 +633,66 @@ Parse `$ARGUMENTS`:
|
|
|
562
633
|
|
|
563
634
|
Không đụng `dev_selftest`/`qc_status` (luật G28 không áp: **không có logic nào đổi** — đó chính là tiền đề của realign).
|
|
564
635
|
|
|
636
|
+
### Step 5f — Reconcile code mode *(chỉ chạy khi có `--reconcile-code`)*
|
|
637
|
+
|
|
638
|
+
*Đường ra cho cờ `LEDGER_BEHIND_CODE` (Step 2b câu B). Không có nó thì cờ đó **không bao giờ sạch được**: `implemented_by` chỉ `/generate-code` ghi, mà nó thấy row đã có code là skip — nên lối ra duy nhất là ép sinh lại code cho hàng loạt scenario đã làm xong. Đúng vòng lặp đóng mà `--realign` được viết ra để mở, chỉ ở một cột khác.*
|
|
639
|
+
|
|
640
|
+
`--reconcile-code` (không tham số → mọi row `LEDGER_BEHIND_CODE` **trong scope** của Step 0-A; dùng `--domain`/`--prd`/`--uc` để hẹp lại).
|
|
641
|
+
|
|
642
|
+
**Điền từ bằng chứng — 5 cột, không hơn:**
|
|
643
|
+
|
|
644
|
+
| Cột | Lấy từ đâu |
|
|
645
|
+
|---|---|
|
|
646
|
+
| `implemented_by` | tên class/hàm mang `@trace.implements` cho SC đó (nhiều file → nối bằng `,`, đúng khuôn `/generate-code` đang ghi) |
|
|
647
|
+
| `gen_ver` | copy `spec_ver` của **chính row đó** *(không phải version hiện tại của `.feature` — code sinh ra từ bản nào thì `spec_ver` lúc này là bản đó; Step 2 vừa đồng bộ nó)* |
|
|
648
|
+
| `fe_phase` | **`integrated`** nếu file code có wire adapter thật theo §4.5.4 · `ui` nếu còn `@trace.mock_for`/mock adapter · `—` cho `system`. **Không suy được** → để `—`, đừng đoán. *(Vocabulary chỉ có `ui` \| `integrated` — nhớ hậu tố **-ed**. Dạng không -ed thuộc về cờ `--phase=integration`, không phải cột này.)* |
|
|
649
|
+
| `test_count` · `test_classes` | **CHỈ khi `has_verifies` = true** (Step 2b đã thu). Số test + tên class lấy từ file mang `@trace.verifies`. `has_verifies` = false → **để trống**, tuyệt đối không điền 0-giả hay tên class phỏng đoán |
|
|
650
|
+
|
|
651
|
+
> ### ⚠️ Luật cứng: KHÔNG set `status`
|
|
652
|
+
>
|
|
653
|
+
> Điền xong 5 cột rồi **để Step 3 tự tính** `status`. Đây không phải chi tiết kỹ thuật — nó là điều
|
|
654
|
+
> quyết định lệnh này hữu ích hay có hại.
|
|
655
|
+
>
|
|
656
|
+
> Có **hai loại bằng chứng, hai người ghi**: `@trace.implements` = *"đã làm"* (do `/generate-code`) ·
|
|
657
|
+
> `@trace.verifies` = *"đã kiểm"* (do `/dev-gen-test`). **Không được suy cái này ra cái kia.**
|
|
658
|
+
>
|
|
659
|
+
> Đo trên một project thật: trong 910 row lệch, **446 có cả hai** ⇒ Step 3 tính ra `OK`; **464 chỉ
|
|
660
|
+
> có cái thứ nhất** ⇒ Step 3 tính ra `GAP`, tức **lộ ra 464 chỗ thiếu test** đang bị chữ `UNTRACKED`
|
|
661
|
+
> che. Nếu lệnh này tự viết `status = OK` thì 464 scenario chưa ai kiểm lên dashboard thành xong hết,
|
|
662
|
+
> và **cổng chặn PR — thứ tồn tại để bắt đúng loại lỗi này — mở cửa cho hàng chưa kiểm.**
|
|
663
|
+
>
|
|
664
|
+
> `/generate-code` đã phát biểu cùng luật này cho chính nó: *"`status` được tính bởi
|
|
665
|
+
> `/validate-traces` — không set ở đây."* Lệnh ghi bù cũng không được là ngoại lệ.
|
|
666
|
+
|
|
667
|
+
**Ba rào an toàn — bắt buộc, cùng khuôn Step 5e:**
|
|
668
|
+
|
|
669
|
+
1. **Chỉ chạm row đang `LEDGER_BEHIND_CODE`.** Từ chối mọi row khác. Row `DRIFT`/`ORPHANED`/`GAP`/`OK` đã có `implemented_by` — ghi lên đó là ghi đè việc của `/generate-code`, không phải ghi bù. In:
|
|
670
|
+
```
|
|
671
|
+
❌ Từ chối reconcile {sc_id}: row này đang {status}, không phải LEDGER_BEHIND_CODE.
|
|
672
|
+
--reconcile-code chỉ điền vào row TRỐNG mà code đã có tag. Row này có chuyện khác.
|
|
673
|
+
```
|
|
674
|
+
2. **Chỉ ghi 5 cột trên.** **Guard sau-ghi:** đọc lại TSV, diff với bản trước; có bất kỳ ô nào **khác** ngoài 5 cột đã định (kể cả `status`, `last_updated` của row không thuộc phạm vi) → **khôi phục file** và dừng.
|
|
675
|
+
3. **In chính xác từng file + từng row đã sửa**, kèm cột nào điền giá trị gì và **bằng chứng nào**:
|
|
676
|
+
```
|
|
677
|
+
📓 Đã ghi bù {n} row:
|
|
678
|
+
{UC-ID}-{platform}.tsv:{dòng} {sc_id}
|
|
679
|
+
implemented_by ← {ClassName.method} (từ {file}:{dòng})
|
|
680
|
+
gen_ver ← {spec_ver}
|
|
681
|
+
fe_phase ← {ui | integrated | —}
|
|
682
|
+
test_count ← {n} · test_classes ← {…} (từ @trace.verifies ở {file}) [hoặc: bỏ trống — không có @trace.verifies]
|
|
683
|
+
```
|
|
684
|
+
Ghi bù im lặng là ghi bù không kiểm chứng được.
|
|
685
|
+
|
|
686
|
+
**Không đụng** `dev_selftest`/`qc_status`/`qc_owner`/`qc_blocked_by`: luật G28 không áp vì **không có logic nào đổi** — code đã nằm đó từ trước, ta chỉ ghi lại sự thật vào sổ. Hạ tín hiệu nghiệm thu ở đây là trừng phạt một lượt dọn dẹp.
|
|
687
|
+
|
|
688
|
+
**Sau khi ghi, chạy tiếp Step 3 → Step 6 → Step 7 như thường** để `status` được tính lại và aggregate phản ánh số mới. In cảnh báo ở report:
|
|
689
|
+
```
|
|
690
|
+
ℓ Coverage sẽ NHẢY sau lượt này — code {cũ}% → {mới}%, test {cũ}% → {mới}%.
|
|
691
|
+
Đây KHÔNG phải việc mới làm được: là việc đã làm rồi mà sổ chưa ghi. Và {n} row
|
|
692
|
+
chuyển sang GAP là {n} chỗ thiếu test vừa lộ ra — phần "xấu đi" trên giấy chính
|
|
693
|
+
là phần trước đó đang bị che.
|
|
694
|
+
```
|
|
695
|
+
|
|
565
696
|
### Step 5c — BDD version drift check
|
|
566
697
|
|
|
567
698
|
*Đối xứng với Step 4 (PRD drift). Trước đây tầng BDD là tầng DUY NHẤT không có cờ drift — dù `/generate-code` vẫn ghi `@trace.bdd_version` vào code và JSON report vẫn lưu nó. Dữ liệu có, chỉ thiếu phép so.*
|
|
@@ -692,6 +823,18 @@ fe_integrated = rows where fe_phase == integrated # FE đã wire adapter th
|
|
|
692
823
|
# công việc CHƯA XONG dù status có thể đã là OK (có code + có test trên mock).
|
|
693
824
|
orphaned_count = rows where status == ORPHANED # code còn, scenario đã bị xoá khỏi .feature (Step 2b/Rule 0)
|
|
694
825
|
trace_orphan_count = số tag @trace.implements/@trace.verifies trỏ vào SC không tồn tại VÀ không có row TSV (Step 2b)
|
|
826
|
+
ledger_behind_code_count = số row có @trace.implements trong code mà cột implemented_by còn trống
|
|
827
|
+
(Step 2b câu B). 🟠 — "làm rồi mà không ghi sổ". Sạch bằng --reconcile-code.
|
|
828
|
+
# KHÔNG vào gate.blocking, và đây là quyết định có chủ ý — đừng "sửa":
|
|
829
|
+
# (1) gate.blocking nghĩa hẹp là CODE ĐANG HỎNG. Ở đây code hoàn toàn đúng
|
|
830
|
+
# và đang chạy; chỉ có sổ nói sai về nó. Cùng ranh giới mà R9(e) giữ.
|
|
831
|
+
# (2) Nợ tồn khi mới bật: mọi project đang chạy đều đã có sẵn hàng trăm row
|
|
832
|
+
# loại này (đo thật: 504 scenario / 910 row ở một project) ⇒ cờ chặn mới
|
|
833
|
+
# sẽ đỏ khắp nơi ở lần đầu ⇒ người ta tắt cổng ⇒ mất luôn 4 cờ 🔴 thật.
|
|
834
|
+
# (3) Nhưng nó vẫn PHẢI thấy được: in mỗi lần chạy + counter ở summary, và
|
|
835
|
+
# bản xác định của cùng phép kiểm là lint-trace T14 (cũng WARN).
|
|
836
|
+
# Team nào đã dọn sạch nợ tồn thì tự thêm counter này vào gate.blocking kèm
|
|
837
|
+
# `why` — self-check R13(e) canh việc đó.
|
|
695
838
|
prd_untracked_edit_count = số file PRD có nội dung đổi kể từ `sha_at_audit` mà `Version` KHÔNG đổi
|
|
696
839
|
(Step 3.9). 🔴 — có người sửa ngoài đường chính thức, nên MỌI phán đoán version
|
|
697
840
|
của Step 4/5 trên file đó đang dựa vào một nhãn không còn đúng.
|
|
@@ -797,6 +940,7 @@ Schema:
|
|
|
797
940
|
"fe_integrated": 0,
|
|
798
941
|
"orphaned_count": 0,
|
|
799
942
|
"trace_orphan_count": 0,
|
|
943
|
+
"ledger_behind_code_count": 0,
|
|
800
944
|
"prd_untracked_edit_count": 0,
|
|
801
945
|
"prd_drift_count": 0,
|
|
802
946
|
"prd_stale_ref_count": 0,
|
|
@@ -1007,6 +1151,16 @@ Schema:
|
|
|
1007
1151
|
"fix": "sửa sc_id cho đúng SC hiện có, HOẶC xoá code/test nếu không còn cần"
|
|
1008
1152
|
}
|
|
1009
1153
|
],
|
|
1154
|
+
"ledger_behind_code": [
|
|
1155
|
+
{
|
|
1156
|
+
"sc_id": "<SC-ID>",
|
|
1157
|
+
"platform": "web | app | system | webview | …",
|
|
1158
|
+
"files": ["<file code mang @trace.implements cho SC này>"],
|
|
1159
|
+
"has_verifies": false,
|
|
1160
|
+
"would_become": "OK | GAP",
|
|
1161
|
+
"fix": "/validate-traces --reconcile-code (điền implemented_by/gen_ver/fe_phase từ tag; test_count CHỈ khi có @trace.verifies; KHÔNG set status)"
|
|
1162
|
+
}
|
|
1163
|
+
],
|
|
1010
1164
|
"techdoc_drift": [
|
|
1011
1165
|
{
|
|
1012
1166
|
"uc_id": "<UC-ID>",
|
|
@@ -1242,6 +1396,23 @@ Trace orphan (tag trỏ vào SC không tồn tại, KHÔNG có row .tsv nào):
|
|
|
1242
1396
|
(Không lệnh nào khác bắt được cái này — row .tsv đã bị xoá bởi version cũ,
|
|
1243
1397
|
hoặc tag ghi sai id ngay từ đầu.)
|
|
1244
1398
|
|
|
1399
|
+
{khối dưới CHỈ in khi ledger_behind_code_count > 0 — else bỏ cả khối}
|
|
1400
|
+
🟠 LEDGER_BEHIND_CODE — làm rồi mà sổ chưa ghi ({n} scenario):
|
|
1401
|
+
{UC}-UC1-SC3 (web) code: {File.method} → sẽ thành OK
|
|
1402
|
+
{UC}-UC1-SC4 (web) code: {File.method} chưa có test → sẽ thành GAP
|
|
1403
|
+
… {n} scenario, gom theo PRD: {LESS-06} 76 · {LESS-09} 65 · …
|
|
1404
|
+
Code đã có tag @trace.implements, nhưng cột implemented_by còn trống ⇒ các row này
|
|
1405
|
+
đang hiện UNTRACKED. Dashboard đếm THIẾU, và /generate-code coi là "chưa làm" nên
|
|
1406
|
+
sẽ sinh lại thứ đã có.
|
|
1407
|
+
Nguyên nhân thường gặp: /generate-code dừng ở cổng build nên §Write Trace State
|
|
1408
|
+
chưa chạy (build fail 3 lần → "KHÔNG ghi trace" là đường thoát hợp lệ), rồi dev
|
|
1409
|
+
sửa tay cho build pass và commit mà không chạy lại lệnh.
|
|
1410
|
+
→ /validate-traces --reconcile-code (cả scope hiện tại)
|
|
1411
|
+
/validate-traces --reconcile-code --domain {d} (dọn từng domain cho dễ soi)
|
|
1412
|
+
⚠️ {n} trong số này CHƯA có @trace.verifies → chúng sẽ thành GAP, không phải OK.
|
|
1413
|
+
Đó là số ĐÚNG: chỗ thiếu test vừa lộ ra, không phải chỗ mới hỏng.
|
|
1414
|
+
🟠 KHÔNG chặn PR — code đang chạy đúng, chỉ sổ nói sai về nó.
|
|
1415
|
+
|
|
1245
1416
|
🔴 PRD_UNTRACKED_EDIT — nội dung PRD đổi mà nhãn Version KHÔNG đổi ({n} file):
|
|
1246
1417
|
specs/payment/create-invoice/PAY01-create-invoice.md Version 1.3 (không đổi từ lần audit)
|
|
1247
1418
|
Bằng chứng : git status — sửa CHƯA commit
|
|
@@ -1311,6 +1482,10 @@ Routing chưa chốt ({service_unrouted_count} scenario) — 🟠 KHÔNG chặn
|
|
|
1311
1482
|
và đóng dấu incorporated + archived/ — không phải làm tay bước nào).
|
|
1312
1483
|
|
|
1313
1484
|
Recommendations:
|
|
1485
|
+
- /validate-traces --reconcile-code cho LEDGER_BEHIND_CODE 🟠 ← CHẠY CÁI NÀY TRƯỚC
|
|
1486
|
+
↳ Nó chỉ ghi sổ theo tag đã có trong code, không sinh code. Chạy trước thì
|
|
1487
|
+
UNTRACKED/GAP bên dưới mới là số thật; chạy /generate-code trước sẽ sinh lại
|
|
1488
|
+
thứ đã tồn tại và có thể ghi đè code đang chạy.
|
|
1314
1489
|
- /generate-code {UC-ID} cho scenario DRIFT và UNTRACKED
|
|
1315
1490
|
- /dev-gen-test {UC-ID} cho GAP (thiếu test)
|
|
1316
1491
|
- /generate-bdd {prd-file} cho PRD_DRIFT 🟠 (changelog CÓ nêu UC này)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.1
|
|
3
|
+
updated: 2026-06-11
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Gap Analysis – <FEATURE>
|
|
8
|
+
|
|
9
|
+
> File ghi lại các **khoảng trống của tài liệu** mà `qa-analyst` phát hiện sau khi
|
|
10
|
+
> phân tích. Là đầu vào để hỏi dev/BA và cho `qa-planner`. Mỗi gap có ID `GAP-xx`
|
|
11
|
+
> để business rule (BR-xx), acceptance criteria (AC-xx) và test case trace ngược về.
|
|
12
|
+
|
|
13
|
+
| Trường | Giá trị |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Feature | `<FEATURE>` |
|
|
16
|
+
| Project / Service | `<project or service name / domain>` |
|
|
17
|
+
| Tài liệu nguồn | `<đường dẫn / link PRD / user story>` |
|
|
18
|
+
| Người phân tích | qa-analyst |
|
|
19
|
+
| Ngày phân tích | `<YYYY-MM-DD>` |
|
|
20
|
+
| Tổng số gap | `<N>` (Blocker: x · High: y · Medium: z · Low: w) |
|
|
21
|
+
| Trạng thái chung | 🔴 Blocked / 🟡 Cần làm rõ / 🟢 Đủ rõ để thiết kế TC |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Bảng Gap
|
|
26
|
+
|
|
27
|
+
| ID | Loại | Mô tả gap | Vị trí (mục/nguồn) | Ảnh hưởng (chức năng / BR / AC) | Mức độ | Người trả lời | Trạng thái | Câu trả lời |
|
|
28
|
+
|---|---|---|---|---|---|---|---|---|
|
|
29
|
+
| GAP-01 | MISSING | … | spec §x | chức năng A / BR-02 | 🔴 Blocker | Dev/BA | Open | — |
|
|
30
|
+
| GAP-02 | AMBIGUOUS | … | mockup màn hình Y | AC-03 | 🟠 High | BA | Open | — |
|
|
31
|
+
| GAP-03 | CONTRADICTORY | … | §2 vs §5 | BR-04 | 🟠 High | BA | Open | — |
|
|
32
|
+
| GAP-04 | ASSUMPTION | … (giả định AI tự đưa, cần xác nhận) | — | chức năng B | 🟡 Medium | Dev | Open | — |
|
|
33
|
+
|
|
34
|
+
### Loại gap
|
|
35
|
+
- **MISSING** – thông tin/chức năng/field/rule chưa được mô tả.
|
|
36
|
+
- **AMBIGUOUS** – mô tả mơ hồ, có ≥ 2 cách hiểu.
|
|
37
|
+
- **CONTRADICTORY** – các phần tài liệu mâu thuẫn nhau.
|
|
38
|
+
- **ASSUMPTION** – giả định do qa-analyst tự suy ra, cần dev/BA xác nhận.
|
|
39
|
+
- **OPEN QUESTION** – câu hỏi mở cần trả lời trước khi thiết kế/triển khai.
|
|
40
|
+
|
|
41
|
+
### Mức độ
|
|
42
|
+
🔴 Blocker (chặn thiết kế TC) · 🟠 High · 🟡 Medium · 🟢 Low
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Quy ước cập nhật
|
|
47
|
+
- `qa-analyst` tạo & điền gap khi phân tích; **không tự bịa câu trả lời** cho gap Blocker.
|
|
48
|
+
- Khi có phản hồi dev/BA: điền cột *Câu trả lời*, đổi *Trạng thái* → `Answered`.
|
|
49
|
+
- Còn gap 🔴 Blocker `Open` ⇒ **chưa** chuyển sang `qa-designer`; đẩy sang `qa-planner`
|
|
50
|
+
(skill `questions-for-dev`) để chốt câu hỏi.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## ⚠️ Checklist bắt buộc trước khi lưu file
|
|
55
|
+
|
|
56
|
+
Trước khi lưu `DOC_GAPS.md`, kiểm tra **từng hàng** trong bảng gap:
|
|
57
|
+
|
|
58
|
+
- [ ] **9 cột đủ** – đúng thứ tự: `ID | Loại | Mô tả gap | Vị trí (mục/nguồn) | Ảnh hưởng (chức năng / BR / AC) | Mức độ | Người trả lời | Trạng thái | Câu trả lời`
|
|
59
|
+
- [ ] **Cột Vị trí không rỗng** – phải có tham chiếu cụ thể đến mục trong tài liệu nguồn (vd `§3 UC4 BR25`, `Appendix B loại 7`, `§4.b Screen 3`). Đây là cột hay bị bỏ thiếu nhất → gây lệch toàn bộ cột sau.
|
|
60
|
+
- [ ] **Cột Ảnh hưởng = BR/AC references** – KHÔNG phải mức độ severity. Ví dụ đúng: `BR25, BR26 / AC-F01-33`. Nếu thấy "Blocker" / "High" ở đây → đang bị lệch cột.
|
|
61
|
+
- [ ] **Cột Mức độ có emoji** – bắt buộc dùng: `🔴 Blocker` / `🟠 High` / `🟡 Medium` / `🟢 Low`. Không được ghi text thuần.
|
|
62
|
+
- [ ] **Cột Người trả lời = vai trò** (PO / BA / Dev / Design / Content / DPO / QC Lead). Nếu thấy "Open" ở đây → đang bị lệch cột.
|
|
63
|
+
- [ ] **Cột Trạng thái = Open / Answered**. Nếu thấy "—" ở đây → đang bị lệch cột.
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
5
|
-
upstream_path: skills/qa-tc-analyst/acceptance-criteria.md
|
|
6
|
-
upstream_sha: 516f35cf78102d27aa5639bfb2818274399800c0
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
7
5
|
---
|
|
8
6
|
|
|
9
7
|
# Acceptance Criteria — Sinh tiêu chí chấp nhận
|
|
@@ -54,7 +52,7 @@ Mỗi AC gắn mã trace: chức năng + BR-xx để TC sau này map 1-1.
|
|
|
54
52
|
## Output
|
|
55
53
|
|
|
56
54
|
Ghi vào **mục Acceptance Criteria** của `{paths.qc_dir}/{UC-ID}/REQUIREMENT_ANALYSIS.md`
|
|
57
|
-
(KHÔNG tạo file riêng — qc-analyze chỉ trả 2 file: `REQUIREMENT_ANALYSIS.md` + `
|
|
55
|
+
(KHÔNG tạo file riêng — qc-analyze chỉ trả 2 file: `REQUIREMENT_ANALYSIS.md` + `DOC_GAPS.md`):
|
|
58
56
|
|
|
59
57
|
- Danh sách AC dạng Given/When/Then, có mã trace về chức năng, business rule (BR-xx)
|
|
60
58
|
và scenario chính thức `{UC-ID}-SC{N}` của `.feature`.
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
|
-
updated: 2026-
|
|
4
|
-
ported_from:
|
|
5
|
-
upstream_path: skills/qa-tc-analyst/business-rules.md
|
|
6
|
-
upstream_sha: 0d5f01257c30182d1c98835303640775d360a3da
|
|
3
|
+
updated: 2026-06-11
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
7
5
|
---
|
|
8
6
|
|
|
9
7
|
# Business Rules — Trích xuất luật nghiệp vụ
|
|
@@ -27,38 +25,6 @@ Trích xuất và liệt kê toàn bộ business rule, điều kiện và ràng
|
|
|
27
25
|
1. Đọc spec đã bóc tách (output của spec-breakdown) hoặc tài liệu gốc.
|
|
28
26
|
2. Quét tìm: điều kiện ("nếu… thì…"), ràng buộc field, giới hạn (min/max, rate limit),
|
|
29
27
|
quy tắc phân quyền, công thức tính, quy tắc trạng thái, default value.
|
|
30
|
-
3. **Checklist ràng buộc field — kiểm tra TẤT CẢ field (kể cả tuỳ chọn / optional):**
|
|
31
|
-
- [ ] `minlength` / `maxlength` — PRD có nêu không? Nếu không → GAP (MISSING)
|
|
32
|
-
- [ ] Ký tự được phép — chữ, số, tiếng Việt có dấu, ký tự đặc biệt, khoảng trắng?
|
|
33
|
-
- [ ] Trim khoảng trắng đầu/cuối — có hay không?
|
|
34
|
-
- [ ] Format đặc biệt — email, SĐT, ngày tháng, v.v.
|
|
35
|
-
> ⚠️ **Field tuỳ chọn (optional) vẫn phải kiểm tra đủ 4 mục trên.** "Không bắt buộc nhập" KHÔNG đồng nghĩa với "không có ràng buộc". Đây là nguồn gốc hay bị bỏ sót khi phân tích.
|
|
36
|
-
|
|
37
|
-
4. **Checklist đặc biệt — hay bị bỏ sót khi đọc BDD/PRD:**
|
|
38
|
-
|
|
39
|
-
**a. Routing table — đọc cả 2 chiều:**
|
|
40
|
-
- [ ] Với MỖI rule "nếu đủ điều kiện → bỏ qua / nếu thiếu → vào": đánh dấu cả 2 nhánh cần test
|
|
41
|
-
- [ ] Routing table N loại tài khoản × M màn → duyệt từng ô, không bỏ dòng nào
|
|
42
|
-
|
|
43
|
-
**b. Liệt kê hết variant:**
|
|
44
|
-
- [ ] Spec đề cập nhiều provider/platform/giá trị liệt kê (Google/Facebook, Lớp 1-6...)? → ghi từng variant ra
|
|
45
|
-
- [ ] Với mỗi variant: behavior hoặc content có khác nhau không? Nếu có → đánh dấu cần TC riêng
|
|
46
|
-
|
|
47
|
-
**c. Telemetry/event analytics:**
|
|
48
|
-
- [ ] Liệt kê TẤT CẢ event name được nhắc trong BDD/PRD cho UC này
|
|
49
|
-
- [ ] Với mỗi event: trigger khác nhau? → cần TC riêng
|
|
50
|
-
- [ ] Có field nhạy cảm (SĐT, PII) KHÔNG ĐƯỢC vào event? → cần TC verify âm riêng
|
|
51
|
-
|
|
52
|
-
**d. Privacy/security assertions âm:**
|
|
53
|
-
- [ ] Spec có nói "KHÔNG ghi", "KHÔNG hiển thị", "chỉ đọc", "KHÔNG vào event"? → ghi ra, cần TC riêng
|
|
54
|
-
- [ ] "Read-only + che X/hiện Y" → 2 TC riêng: (1) hiển thị đúng che/hiện, (2) không chỉnh sửa được
|
|
55
|
-
|
|
56
|
-
**e. Validation kế thừa từ UC/AC khác:**
|
|
57
|
-
- [ ] Spec có reference "chuẩn hoá theo ACx", "logic tương tự UCy", "validation như màn Z"? → đọc UC/AC đó
|
|
58
|
-
- [ ] Liệt kê TẤT CẢ scenario normalization của UC nguồn chưa có trong UC hiện tại
|
|
59
|
-
|
|
60
|
-
**f. AC có sub-cases:**
|
|
61
|
-
- [ ] Mỗi AC dạng "(1)...→...; (2)...→...; (3)...→..." → đếm số sub-cases, mỗi sub-case 1 TC
|
|
62
28
|
|
|
63
29
|
---
|
|
64
30
|
|
|
@@ -84,10 +50,10 @@ Với rule có nhiều điều kiện kết hợp → gợi ý dựng **Decision
|
|
|
84
50
|
## Output
|
|
85
51
|
|
|
86
52
|
Ghi vào **mục Business Rules** của `{paths.qc_dir}/{UC-ID}/REQUIREMENT_ANALYSIS.md`
|
|
87
|
-
(KHÔNG tạo file riêng — qc-analyze chỉ trả 2 file: `REQUIREMENT_ANALYSIS.md` + `
|
|
53
|
+
(KHÔNG tạo file riêng — qc-analyze chỉ trả 2 file: `REQUIREMENT_ANALYSIS.md` + `DOC_GAPS.md`):
|
|
88
54
|
|
|
89
55
|
- Bảng business rule có ID (BR-xx) để TC trace ngược về.
|
|
90
56
|
- Gợi ý các rule cần Decision Table / BVA khi sang qa-designer.
|
|
91
57
|
|
|
92
|
-
Rule MÂU THUẪN / KHÔNG RÕ → ghi vào `{paths.qc_dir}/{UC-ID}/
|
|
58
|
+
Rule MÂU THUẪN / KHÔNG RÕ → ghi vào `{paths.qc_dir}/{UC-ID}/DOC_GAPS.md`
|
|
93
59
|
(loại CONTRADICTORY / AMBIGUOUS, cột "Ảnh hưởng" trỏ BR-xx).
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
5
|
-
upstream_path: skills/qa-tc-analyst/data-flow.md
|
|
6
|
-
upstream_sha: fc0fc3d0f8010e3fb266c16b132eff1b23641a8f
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
7
5
|
---
|
|
8
6
|
|
|
9
7
|
# Data Flow — Phân tích luồng dữ liệu
|
|
@@ -55,7 +53,7 @@ Thể hiện luồng dạng bước tuần tự hoặc sơ đồ text:
|
|
|
55
53
|
## Output
|
|
56
54
|
|
|
57
55
|
Ghi vào **mục Data Flow** của `{paths.qc_dir}/{UC-ID}/REQUIREMENT_ANALYSIS.md`
|
|
58
|
-
(KHÔNG tạo file riêng — qc-analyze chỉ trả 2 file: `REQUIREMENT_ANALYSIS.md` + `
|
|
56
|
+
(KHÔNG tạo file riêng — qc-analyze chỉ trả 2 file: `REQUIREMENT_ANALYSIS.md` + `DOC_GAPS.md`):
|
|
59
57
|
|
|
60
58
|
- Sơ đồ/list luồng dữ liệu cho mỗi kịch bản chính.
|
|
61
59
|
- Danh sách integration point + state change + failure point.
|
|
@@ -63,4 +61,4 @@ Ghi vào **mục Data Flow** của `{paths.qc_dir}/{UC-ID}/REQUIREMENT_ANALYSIS.
|
|
|
63
61
|
- Dữ liệu/trạng thái cần chuẩn bị & cleanup → đầu vào fixture cho qa-runner.
|
|
64
62
|
|
|
65
63
|
Chặng nào luồng/hành vi chưa rõ (vd lỗi xử lý ra sao, retry, partial commit) →
|
|
66
|
-
ghi vào `{paths.qc_dir}/{UC-ID}/
|
|
64
|
+
ghi vào `{paths.qc_dir}/{UC-ID}/DOC_GAPS.md` (loại MISSING / OPEN QUESTION).
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
|
-
updated: 2026-
|
|
4
|
-
ported_from:
|
|
5
|
-
upstream_path: skills/qa-tc-analyst/spec-breakdown.md
|
|
6
|
-
upstream_sha: 4a5fb9334fef1fdc3ac5e899e0463c643af80dad
|
|
3
|
+
updated: 2026-06-11
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
7
5
|
---
|
|
8
6
|
|
|
9
7
|
# Spec Breakdown — Bóc tách yêu cầu
|
|
@@ -29,7 +27,7 @@ Bóc tách spec/PRD/user story thô thành mô tả yêu cầu có cấu trúc c
|
|
|
29
27
|
vào phân tích/BR/AC. Với file Confluence/HTML/MHTML: phát hiện qua thẻ `<s>`,
|
|
30
28
|
`<strike>`, `<del>` hoặc style `text-decoration: line-through`.
|
|
31
29
|
3. Xác định: feature name, actor/role, mục tiêu nghiệp vụ, phạm vi (in/out scope).
|
|
32
|
-
4. Đánh dấu phần MƠ HỒ / THIẾU → ghi vào `
|
|
30
|
+
4. Đánh dấu phần MƠ HỒ / THIẾU → ghi vào `DOC_GAPS.md` (gap GAP-xx).
|
|
33
31
|
|
|
34
32
|
---
|
|
35
33
|
|
|
@@ -39,7 +37,7 @@ Tách yêu cầu thành các khối:
|
|
|
39
37
|
|
|
40
38
|
A. TỔNG QUAN: mục tiêu, actor, giá trị nghiệp vụ.
|
|
41
39
|
B. CHỨC NĂNG: list từng chức năng (visible + ẩn + integration point).
|
|
42
|
-
C. INPUT/OUTPUT: mỗi chức năng có input gì, output gì, ràng buộc field.
|
|
40
|
+
C. INPUT/OUTPUT: mỗi chức năng có input gì, output gì, ràng buộc field.
|
|
43
41
|
D. TRẠNG THÁI & LUỒNG: các state, điều kiện chuyển, happy path + alternate flow.
|
|
44
42
|
E. PHỤ THUỘC: hệ thống/API/module liên quan.
|
|
45
43
|
F. GIẢ ĐỊNH & CÂU HỎI MỞ: điều suy ra được vs điều cần dev/BA xác nhận.
|
|
@@ -50,14 +48,14 @@ F. GIẢ ĐỊNH & CÂU HỎI MỞ: điều suy ra được vs điều cần dev
|
|
|
50
48
|
|
|
51
49
|
⚠️ `/qc-analyze` chỉ ghi **ĐÚNG 2 FILE** cho mỗi UC, đặt trong thư mục QC **lộ ra ngoài**
|
|
52
50
|
`{paths.qc_dir}/{UC-ID}/` (mặc định `docs/{UC-ID}/` — KHÔNG để trong `.agent/` ẩn):
|
|
53
|
-
`REQUIREMENT_ANALYSIS.md` + `
|
|
51
|
+
`REQUIREMENT_ANALYSIS.md` + `DOC_GAPS.md`. KHÔNG tách mỗi bước phân tích thành file riêng.
|
|
54
52
|
|
|
55
53
|
Phần spec-breakdown là **mục đầu tiên** của `REQUIREMENT_ANALYSIS.md`:
|
|
56
54
|
- Bảng chức năng + input/output/constraint
|
|
57
55
|
- Sơ đồ/list luồng chính & phụ
|
|
58
56
|
- Danh sách giả định và câu hỏi mở (đánh dấu rõ điều CHƯA chắc)
|
|
59
57
|
|
|
60
|
-
Đồng thời ghi mọi khoảng trống phát hiện vào `{paths.qc_dir}/{UC-ID}/
|
|
61
|
-
(theo `{paths.qc_skills_dir}/qa-analyst/
|
|
58
|
+
Đồng thời ghi mọi khoảng trống phát hiện vào `{paths.qc_dir}/{UC-ID}/DOC_GAPS.md`
|
|
59
|
+
(theo `{paths.qc_skills_dir}/qa-analyst/DOC_GAPS.template.md`), mỗi gap có ID `GAP-xx`.
|
|
62
60
|
|
|
63
61
|
Kết thúc bằng gợi ý: feature đã đủ rõ để chuyển sang `qa-planner` (phân tích rủi ro) chưa.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test Case — E2E Journey
|
|
@@ -18,7 +18,7 @@ Skill **tự chứa** để viết TC end-to-end: hành trình đầu→cuối x
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
20
|
## Format file TC (bắt buộc)
|
|
21
|
-
- Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](
|
|
21
|
+
- Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](DOC_GAPS.md)`.
|
|
22
22
|
- **Test Data** dạng list (tài khoản/role, dữ liệu lớp/buổi…) · **Steps** `[Action]`/`[Verify]` xuyên các màn ·
|
|
23
23
|
**Expected** 1 bullet = chuỗi verify point (tạo thành công, mã đúng, định tuyến đúng, đồng bộ đúng, hiển thị danh sách).
|
|
24
24
|
- ID journey `E2E-<FEATURE>-NN` · cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test Case — Functional API (không qua UI)
|
|
@@ -22,7 +22,7 @@ Chỉ cần load file này.
|
|
|
22
22
|
- 1 file/feature · mỗi TC **1 concept** · metadata **list** (không bảng/emoji): Title · Feature ·
|
|
23
23
|
Priority(P0/P1/P2) · Status(Draft) · Author(AI) · Tags · Trace · 🚫 Block(nếu có).
|
|
24
24
|
- **Trace:** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)`; không có BR → `⚠️ Chưa có Business Rule`.
|
|
25
|
-
- **🚫 Block:** TC phụ thuộc gap vẫn viết đủ + `[GAP-xx](
|
|
25
|
+
- **🚫 Block:** TC phụ thuộc gap vẫn viết đủ + `[GAP-xx](DOC_GAPS.md) — lý do`.
|
|
26
26
|
- **Test Data:** dạng **list** (request cụ thể: method/path/headers/body). **Steps:** `[Action]`/`[Verify]`.
|
|
27
27
|
**Expected:** 1 bullet nêu rõ **status code + field response cần chốt** (không ✅/❌).
|
|
28
28
|
- Cuối file: **Trace matrix** (BR↔TC, ⚠️ TC thiếu BR) + **bảng TC bị block** · bỏ nội dung gạch ngang.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test Case — Functional GUI Feature (đa màn hình)
|
|
@@ -22,7 +22,7 @@ Skill **tự chứa** để viết TC functional cho feature có luồng span
|
|
|
22
22
|
- 1 file/feature · mỗi TC **1 concept** · metadata **list** (không bảng/emoji): Title · Feature ·
|
|
23
23
|
Priority(P0/P1/P2) · Status(Draft) · Author(AI) · Tags · Trace · 🚫 Block(nếu có).
|
|
24
24
|
- **Trace:** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)`; không có BR → `⚠️ Chưa có Business Rule`.
|
|
25
|
-
- **🚫 Block:** TC phụ thuộc gap vẫn viết đủ + `[GAP-xx](
|
|
25
|
+
- **🚫 Block:** TC phụ thuộc gap vẫn viết đủ + `[GAP-xx](DOC_GAPS.md) — lý do`.
|
|
26
26
|
- **Test Data:** dạng **list** (không bảng). **Steps:** `[Action]`/`[Verify]`, không `*Expected:*`/bước. **Expected:** 1 bullet cụ thể.
|
|
27
27
|
- Cuối file: **Trace matrix** (BR↔TC, ⚠️ TC thiếu BR) + **bảng TC bị block** · không `#### Python Test Mapping` · bỏ nội dung gạch ngang.
|
|
28
28
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test Case — Functional GUI Screen (1 màn hình)
|
|
@@ -22,7 +22,7 @@ Skill **tự chứa** để viết TC functional cho 1 màn hình đơn lẻ (we
|
|
|
22
22
|
- 1 file/feature · mỗi TC **1 concept** · metadata **list** (mỗi trường 1 dòng, không bảng/emoji):
|
|
23
23
|
Title · Feature · Priority(P0/P1/P2) · Status(Draft) · Author(AI) · Tags · Trace · 🚫 Block(nếu có).
|
|
24
24
|
- **Trace:** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)`; TC không có BR → `⚠️ Chưa có Business Rule`.
|
|
25
|
-
- **🚫 Block:** TC phụ thuộc gap **vẫn viết đủ** + `[GAP-xx](
|
|
25
|
+
- **🚫 Block:** TC phụ thuộc gap **vẫn viết đủ** + `[GAP-xx](DOC_GAPS.md) — lý do`; chưa chạy tới khi gap Answered.
|
|
26
26
|
- **Test Data:** dạng **list** (`- **Trường:** giá trị`), không bảng.
|
|
27
27
|
- **Test Steps:** `**[Action]**` / `**[Verify]**`, KHÔNG `- *Expected:*` sau bước. **Expected:** 1 bullet cụ thể (không ✅/❌).
|
|
28
28
|
- Phân nhóm GUI/Functional · cuối file: **Trace matrix** (BR↔TC, ⚠️ TC thiếu BR) + **bảng TC bị block** · KHÔNG `#### Python Test Mapping` · bỏ nội dung gạch ngang.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test Case — Integration API
|
|
@@ -20,7 +20,7 @@ verify luồng dữ liệu & contract giữa các thành phần. Chỉ cần loa
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
22
|
## Format file TC (bắt buộc)
|
|
23
|
-
- Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](
|
|
23
|
+
- Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](DOC_GAPS.md)` (TC chặn vẫn viết đủ).
|
|
24
24
|
- **Test Data** dạng list · **Steps** `[Action]`/`[Verify]` · **Expected** 1 bullet nêu rõ chặng verify (response/bản ghi/event).
|
|
25
25
|
- Cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
|
|
26
26
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test Case — Integration DB
|
|
@@ -18,7 +18,7 @@ insert/update/soft-delete đúng giá trị, side-effect, toàn vẹn. Chỉ c
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
20
|
## Format file TC (bắt buộc)
|
|
21
|
-
- Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](
|
|
21
|
+
- Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](DOC_GAPS.md)`.
|
|
22
22
|
- **Test Data** dạng list (giá trị input) · **Steps** `[Action]`/`[Verify]` · **Expected** 1 bullet nêu rõ **bảng.cột = giá trị**.
|
|
23
23
|
- Cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
|
|
24
24
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
3
|
updated: 2026-06-11
|
|
4
|
-
ported_from:
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test Case — Integration GUI ↔ Backend
|
|
@@ -19,7 +19,7 @@ lỗi từ server, đồng bộ trạng thái hai chiều. Chỉ cần load file
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
21
|
## Format file TC (bắt buộc)
|
|
22
|
-
- Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](
|
|
22
|
+
- Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](DOC_GAPS.md)`.
|
|
23
23
|
- **Test Data** dạng list · **Steps** `[Action]`/`[Verify]` · **Expected** 1 bullet (API liên quan + biểu hiện UI kỳ vọng).
|
|
24
24
|
- Cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
|
|
25
25
|
|