@educa-corp/sdd-framework 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/build.js +113 -19
- package/bin/gate-trace.js +464 -0
- package/bin/index.js +418 -146
- package/bin/lint-trace.js +602 -0
- package/bin/self-check.js +499 -6
- package/bin/trace-schema.json +1449 -692
- package/commands/debug.md +123 -510
- package/commands/debug.tmpl +3 -0
- package/commands/define-product.md +86 -509
- package/commands/dev-gen-test.md +120 -516
- package/commands/dev-run-test.md +120 -516
- package/commands/dev-smoke-test.md +86 -509
- package/commands/extend-prd.md +486 -0
- package/commands/extend-prd.tmpl +273 -0
- package/commands/fix-bug.md +152 -515
- package/commands/generate-architecture.md +94 -514
- package/commands/generate-architecture.tmpl +3 -0
- package/commands/generate-bdd.md +138 -519
- package/commands/generate-bdd.tmpl +18 -3
- package/commands/generate-code.md +156 -523
- package/commands/generate-code.tmpl +36 -7
- package/commands/generate-design-spec.md +86 -509
- package/commands/generate-prd.md +114 -509
- package/commands/generate-prd.tmpl +28 -0
- package/commands/generate-spec-manifest.md +86 -509
- package/commands/generate-tech-docs.md +86 -509
- package/commands/learn.md +172 -495
- package/commands/learn.tmpl +70 -3
- package/commands/map-testids.md +86 -509
- package/commands/propose-scenario.md +136 -508
- package/commands/propose-scenario.tmpl +52 -1
- package/commands/qc-analyze.md +86 -509
- package/commands/qc-design-test.md +87 -509
- package/commands/qc-design-test.tmpl +1 -0
- package/commands/qc-plan.md +86 -509
- package/commands/qc-report.md +86 -509
- package/commands/qc-review.md +86 -509
- package/commands/qc-run-test.md +133 -517
- package/commands/qc-run-test.tmpl +13 -1
- package/commands/refine-prd.md +99 -519
- package/commands/refine-prd.tmpl +3 -0
- package/commands/report-bug.md +86 -509
- package/commands/review-code.md +127 -513
- package/commands/review-code.tmpl +7 -3
- package/commands/review-context.md +96 -515
- package/commands/review-context.tmpl +6 -2
- package/commands/review-tech-docs.md +90 -510
- package/commands/review-tech-docs.tmpl +3 -0
- package/commands/setup-ai-first.md +166 -137
- package/commands/setup-ai-first.tmpl +72 -0
- package/commands/sync.md +86 -118
- package/commands/sync.tmpl +84 -16
- package/commands/update-framework.md +16 -102
- package/commands/update-framework.tmpl +14 -0
- package/commands/validate-traces.md +458 -531
- package/commands/validate-traces.tmpl +381 -31
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/README.md +20 -0
- package/core/commands/debug.md +123 -510
- package/core/commands/define-product.md +86 -509
- package/core/commands/dev-gen-test.md +120 -516
- package/core/commands/dev-run-test.md +120 -516
- package/core/commands/dev-smoke-test.md +86 -509
- package/core/commands/extend-prd.md +486 -0
- package/core/commands/fix-bug.md +152 -515
- package/core/commands/generate-architecture.md +94 -514
- package/core/commands/generate-bdd.md +138 -519
- package/core/commands/generate-code.md +156 -523
- package/core/commands/generate-design-spec.md +86 -509
- package/core/commands/generate-prd.md +114 -509
- package/core/commands/generate-spec-manifest.md +86 -509
- package/core/commands/generate-tech-docs.md +86 -509
- package/core/commands/learn.md +172 -495
- package/core/commands/map-testids.md +86 -509
- package/core/commands/propose-scenario.md +136 -508
- package/core/commands/qc-analyze.md +86 -509
- package/core/commands/qc-design-test.md +87 -509
- package/core/commands/qc-plan.md +86 -509
- package/core/commands/qc-report.md +86 -509
- package/core/commands/qc-review.md +86 -509
- package/core/commands/qc-run-test.md +133 -517
- package/core/commands/refine-prd.md +99 -519
- package/core/commands/report-bug.md +86 -509
- package/core/commands/review-code.md +127 -513
- package/core/commands/review-context.md +96 -515
- package/core/commands/review-tech-docs.md +90 -510
- package/core/commands/setup-ai-first.md +166 -137
- package/core/commands/sync.md +86 -118
- package/core/commands/update-framework.md +16 -102
- package/core/commands/validate-traces.md +458 -531
- package/core/hooks/data-guard.js +174 -83
- package/core/hooks/settings.json +2 -1
- package/core/rules/workflow.md +48 -4
- package/core/steps/capture-lesson.md +34 -1
- package/core/steps/context-loader.md +24 -3
- package/core/steps/gate.md +92 -35
- package/core/steps/report-footer.md +26 -2
- package/core/steps/trace-mirror.md +34 -7
- package/core/templates/README.md +24 -1
- package/core/templates/ci/trace-gate.yml +146 -0
- package/core/templates/feature.template +1 -1
- package/core/templates/hooks/pre-push +61 -0
- package/docs/01-getting-started/installation.md +18 -1
- package/docs/01-getting-started/what-is-sdd.md +4 -2
- package/docs/02-concepts/architecture.md +48 -5
- package/docs/02-concepts/pipeline-steps/02-specification.md +39 -3
- package/docs/02-concepts/pipeline-steps/04-bdd.md +24 -2
- package/docs/02-concepts/pipeline-steps/05-tech-docs.md +18 -1
- package/docs/02-concepts/pipeline-steps/06-code.md +35 -4
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +137 -12
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +59 -3
- package/docs/02-concepts/roles-and-hitl.md +1 -1
- package/docs/02-concepts/traceability.md +183 -117
- package/docs/03-guides/architect.md +63 -0
- package/docs/03-guides/developer.md +20 -4
- package/docs/03-guides/product-owner.md +72 -68
- package/docs/03-guides/tester-qa.md +81 -70
- package/docs/04-reference/commands.md +134 -105
- package/docs/04-reference/configuration.md +146 -94
- package/docs/04-reference/model-selection.md +32 -19
- package/docs/04-reference/trace-schema.md +26 -9
- package/docs/explain/02-generate-prd.md +80 -78
- package/docs/explain/02b-extend-prd.md +125 -0
- package/docs/explain/03-refine-prd.md +86 -86
- package/docs/explain/04-review-context.md +18 -1
- package/docs/explain/06-generate-bdd.md +23 -0
- package/docs/explain/08-review-tech-docs.md +20 -5
- package/docs/explain/10-review-code.md +36 -2
- package/docs/explain/19-qc-run-test.md +87 -67
- package/docs/explain/21-validate-traces.md +75 -68
- package/docs/explain/23-fix-bug.md +19 -3
- package/docs/explain/26-propose-scenario.md +70 -63
- package/docs/explain/27-learn.md +5 -3
- package/docs/explain/README.md +135 -134
- package/hooks/data-guard.js +174 -83
- package/hooks/settings.json +2 -1
- package/package.json +53 -50
- package/rules/workflow.md +48 -4
- package/steps/capture-lesson.md +34 -1
- package/steps/context-loader.md +24 -3
- package/steps/gate.md +92 -35
- package/steps/report-footer.md +26 -2
- package/steps/trace-mirror.md +34 -7
- package/templates/README.md +24 -1
- package/templates/ci/trace-gate.yml +146 -0
- package/templates/feature.template +1 -1
- package/templates/hooks/pre-push +61 -0
- package/scripts/init.sh +0 -49
- package/scripts/upgrade.sh +0 -94
package/package.json
CHANGED
|
@@ -1,50 +1,53 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@educa-corp/sdd-framework",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Spec Driven Development workflow framework for Claude Code",
|
|
5
|
-
"bin": {
|
|
6
|
-
"sdd-framework": "./bin/index.js"
|
|
7
|
-
},
|
|
8
|
-
"scripts": {
|
|
9
|
-
"build": "node bin/build.js && node bin/self-check.js",
|
|
10
|
-
"prepublishOnly": "node bin/build.js && node bin/self-check.js",
|
|
11
|
-
"pub": "npm publish --access=public",
|
|
12
|
-
"dev": "node bin/build.js && node bin/index.js --init",
|
|
13
|
-
"prepack": "node -e \"const fs=require('fs'); ['README.md','PUBLISHING.md','SETUP_GUIDE.md'].forEach(f=>{ if(fs.existsSync(f)) fs.renameSync(f,'__'+f); });\"",
|
|
14
|
-
"postpack": "node -e \"const fs=require('fs'); ['README.md','PUBLISHING.md','SETUP_GUIDE.md'].forEach(f=>{ if(fs.existsSync('__'+f)) fs.renameSync('__'+f,f); });\"",
|
|
15
|
-
"self-check": "node bin/self-check.js"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"bin/"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
},
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
}
|
|
50
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@educa-corp/sdd-framework",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Spec Driven Development workflow framework for Claude Code",
|
|
5
|
+
"bin": {
|
|
6
|
+
"sdd-framework": "./bin/index.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "node bin/build.js && node bin/self-check.js",
|
|
10
|
+
"prepublishOnly": "node bin/build.js && node bin/self-check.js",
|
|
11
|
+
"pub": "npm publish --access=public",
|
|
12
|
+
"dev": "node bin/build.js && node bin/index.js --init",
|
|
13
|
+
"prepack": "node -e \"const fs=require('fs'); ['README.md','PUBLISHING.md','SETUP_GUIDE.md'].forEach(f=>{ if(fs.existsSync(f)) fs.renameSync(f,'__'+f); });\"",
|
|
14
|
+
"postpack": "node -e \"const fs=require('fs'); ['README.md','PUBLISHING.md','SETUP_GUIDE.md'].forEach(f=>{ if(fs.existsSync('__'+f)) fs.renameSync('__'+f,f); });\"",
|
|
15
|
+
"self-check": "node bin/self-check.js",
|
|
16
|
+
"test": "node test/run.js",
|
|
17
|
+
"lint-trace": "node bin/lint-trace.js",
|
|
18
|
+
"gate-trace": "node bin/gate-trace.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"bin/",
|
|
22
|
+
"commands/",
|
|
23
|
+
"core/",
|
|
24
|
+
"hooks/",
|
|
25
|
+
"modules/",
|
|
26
|
+
"rules/",
|
|
27
|
+
"scripts/",
|
|
28
|
+
"skills/",
|
|
29
|
+
"steps/",
|
|
30
|
+
"templates/",
|
|
31
|
+
"docs/"
|
|
32
|
+
],
|
|
33
|
+
"keywords": [
|
|
34
|
+
"claude-code",
|
|
35
|
+
"spec-driven",
|
|
36
|
+
"ai-first",
|
|
37
|
+
"bdd",
|
|
38
|
+
"traceability",
|
|
39
|
+
"workflow"
|
|
40
|
+
],
|
|
41
|
+
"author": "duclm2 <duclm2@edupia.com.vn>",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/duclm2/sdd-framework"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=14"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
}
|
|
53
|
+
}
|
package/rules/workflow.md
CHANGED
|
@@ -7,10 +7,26 @@
|
|
|
7
7
|
|
|
8
8
|
## Checkpoints
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
Ba mức, định nghĩa đầy đủ ở `steps/gate.md` Bước 3a — **đây chỉ là bản tóm tắt, gate là nguồn**:
|
|
11
|
+
|
|
12
|
+
| Mức | Lệnh nào | `--yes` bỏ qua? |
|
|
13
|
+
|---|---|:---:|
|
|
14
|
+
| **Không chặn** | read-only (`/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs`) | — |
|
|
15
|
+
| **Chặn thường** | mọi lệnh sinh/sửa artifact | ✅ |
|
|
16
|
+
| **Chặn CỨNG** | ghi đè file đã có · `--resume` · migrate · prune | ❌ |
|
|
17
|
+
|
|
18
|
+
- CHECKPOINT phải nêu **target đã phân giải**, và **mọi cờ 🔴/⚠️ mà context-loader đã tính**
|
|
19
|
+
(`active_service = unresolved`, `Status ≠ FULL`, CLAUDE.md thiếu, target resolve bằng wildcard).
|
|
20
|
+
- **KHÔNG lặp lại** những gì `[CTX LOADED]` vừa in ngay phía trên. Sạch hết thì CHECKPOINT
|
|
21
|
+
chỉ hai dòng.
|
|
22
|
+
- `--yes` bỏ qua *chặn thường*, **không** bỏ qua *chặn cứng*, và **không** tắt việc in cờ.
|
|
23
|
+
|
|
24
|
+
> **Vì sao ba mức thay vì "always show" (G41):** bản cũ viết *"**Always** show a CHECKPOINT"*
|
|
25
|
+
> rồi ngay dòng sau lại cấp một ngoại lệ cho lệnh read-only — mà `gate.md` **không hề thực thi**
|
|
26
|
+
> ngoại lệ đó. Hai file cùng được nạp vào mọi lệnh và nói ngược nhau. Cộng thêm: cổng luôn in
|
|
27
|
+
> ra một bảng giống hệt nhau, 20 lần cho một feature, nên `Y` thành phản xạ và cổng hỏng **âm
|
|
28
|
+
> thầm** — vẫn hiện, vẫn được trả lời, chỉ là không ai đọc. Cổng chỉ ồn khi thật sự có chuyện
|
|
29
|
+
> thì mới được đọc.
|
|
14
30
|
|
|
15
31
|
## Scope Control
|
|
16
32
|
|
|
@@ -20,14 +36,42 @@
|
|
|
20
36
|
|
|
21
37
|
## Trace Contract
|
|
22
38
|
|
|
39
|
+
> **Phạm vi:** mục này áp cho **repo framework**. Ở project consumer, `.agent/` là mirror sinh
|
|
40
|
+
> ra và `bin/` không được cài — contract ở đó là **read-only**: thấy lệch thì **báo**, đừng tự
|
|
41
|
+
> sửa (xem `.agent/README.md`). Việc duy nhất chạy được ở project là **kiểm sổ trace**:
|
|
42
|
+
> `npx @educa-corp/sdd-framework --lint-trace`.
|
|
43
|
+
|
|
23
44
|
- Contract trace (field `@trace.*`, cột `.tsv`, path pattern, giá trị enum) có **một
|
|
24
45
|
nguồn-sự-thật máy đọc**: `bin/trace-schema.json`. Bản cho người đọc:
|
|
25
46
|
`docs/04-reference/trace-schema.md` — giữ hai file đồng bộ.
|
|
47
|
+
- **Canh contract ≠ canh dữ liệu.** `bin/self-check.js` đọc **file lệnh** và kiểm *"lệnh có gọi
|
|
48
|
+
đúng tên cột không"* — nó không bao giờ mở một `.tsv` thật. `bin/lint-trace.js` mở sổ thật.
|
|
49
|
+
Cần cả hai: sổ 24 cột được ghi **bằng tay**, hàng chục lần mỗi feature; một dấu tab thiếu ở
|
|
50
|
+
ô 17 dồn mọi ô sau đó sang trái, ô 21 `status` nhận một ngày tháng, và **không cờ nào bật**.
|
|
51
|
+
Thêm cột/vocabulary mới → khai binding cho `lint-trace` **ngay**; R8 fail build nếu quên.
|
|
26
52
|
- Đổi contract (thêm/bỏ/đổi nghĩa một field, path, hay giá trị enum) → **sửa
|
|
27
53
|
`bin/trace-schema.json` TRƯỚC**, rồi mới sửa lệnh. `npm run build` chạy
|
|
28
54
|
`bin/self-check.js` và **fail** nếu lệnh lệch schema.
|
|
29
55
|
- Field có consumer mà **không có producer** là lỗi chặn build — đó chính là hình dạng
|
|
30
56
|
của G1 (`@trace.sc_version`: 3 consumer, 0 producer, DRIFT chết mà không ai báo).
|
|
57
|
+
- **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`
|
|
58
|
+
thuộc `/dev-run-test` · `qc_status`/`qc_run_at` thuộc `/qc-run-test` · `test_count`/`test_classes`
|
|
59
|
+
thuộc `/dev-gen-test` — và **chỉ chủ được ghi giá trị KHẲNG ĐỊNH** (`pass`/`fail`/số lượng).
|
|
60
|
+
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á
|
|
61
|
+
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
|
|
62
|
+
tôn trọng quyền sở hữu.
|
|
63
|
+
*Tiền lệ đúng có sẵn: `/fix-bug` hạ `dev_selftest → not_run` với lý do "code vừa đổi nên tín
|
|
64
|
+
hiệu self-test cũ hết hiệu lực". Cùng lý do đó áp cho MỌI lệnh làm đổi spec hoặc code.*
|
|
65
|
+
**Ngoại lệ có chủ ý:** `qc_owner`/`qc_blocked_by` (con trỏ tới bug — spec đổi không làm bug biến
|
|
66
|
+
mất) và `test_count`/`test_classes` (test vẫn tồn tại trên đĩa; số lượng không sai, chỉ nội dung
|
|
67
|
+
cũ → **cảnh báo**, không hạ số, để tỷ lệ coverage không nhảy loạn).
|
|
68
|
+
- **Mỗi audit flag phải quan sát được ở CẢ BA tầng.** Mọi giá trị trong
|
|
69
|
+
`vocabularies.audit_flags` bắt buộc có đủ: **(1)** một counter `{flag_lowercase}_count`
|
|
70
|
+
trong Step 7 + `summary` của `trace-report.json` · **(2)** một mảng trong `issues` ·
|
|
71
|
+
**(3)** một khối trong report terminal. Thiếu tầng nào = cờ vô hình ở tầng đó.
|
|
72
|
+
`bin/self-check.js` R7 ép tầng (1) — **không có ngoại lệ**. Đây là hình dạng của G33:
|
|
73
|
+
7/10 cờ có counter, 3 cái không, nên dashboard (chỉ đọc `summary`) không tổng hợp
|
|
74
|
+
được — và bất đối xứng 7/10 là bẫy cho người viết dashboard: đọc `summary` rồi tưởng đủ.
|
|
31
75
|
|
|
32
76
|
## Code Generation
|
|
33
77
|
|
package/steps/capture-lesson.md
CHANGED
|
@@ -47,7 +47,7 @@ Nếu `lessons_path` chưa tồn tại, tạo file với header sau trước:
|
|
|
47
47
|
> Các lỗi AI KHÔNG được lặp lại trong dự án này. Được nạp bởi context-loader ở đầu
|
|
48
48
|
> mỗi lệnh và coi như ràng buộc cứng (cùng mức ưu tiên với coding standards trong CLAUDE.md).
|
|
49
49
|
> Thêm bằng /learn, hoặc chấp nhận prompt trong /review-code, /fix-bug, /debug.
|
|
50
|
-
> Commit file này để cả team dùng chung guardrail.
|
|
50
|
+
> Rà lại định kỳ bằng `/learn --review`. Commit file này để cả team dùng chung guardrail.
|
|
51
51
|
|
|
52
52
|
| Category | Áp dụng cho |
|
|
53
53
|
|----------|-----------|
|
|
@@ -58,6 +58,9 @@ Nếu `lessons_path` chưa tồn tại, tạo file với header sau trước:
|
|
|
58
58
|
| prd | output của /generate-prd, /refine-prd |
|
|
59
59
|
| general | mọi lệnh |
|
|
60
60
|
|
|
61
|
+
**Status:** `active` = đang là ràng buộc cứng · `retired` = đã hết đúng, GIỮ LẠI làm lịch sử
|
|
62
|
+
nhưng context-loader **không nạp nữa**. Lesson không ghi `Status` được coi là `active`.
|
|
63
|
+
|
|
61
64
|
---
|
|
62
65
|
```
|
|
63
66
|
|
|
@@ -65,6 +68,7 @@ Chèn lesson mới ngay dưới dấu phân cách `---` (**mới nhất lên đ
|
|
|
65
68
|
|
|
66
69
|
```markdown
|
|
67
70
|
### L-{NNN} — [{category}] {title}
|
|
71
|
+
- **Status**: active
|
|
68
72
|
- **Date**: {hôm nay YYYY-MM-DD}
|
|
69
73
|
- **Scope**: {scope}
|
|
70
74
|
- **Mistake**: {mistake}
|
|
@@ -73,6 +77,35 @@ Chèn lesson mới ngay dưới dấu phân cách `---` (**mới nhất lên đ
|
|
|
73
77
|
|
|
74
78
|
```
|
|
75
79
|
|
|
80
|
+
### Retire — đường ra của một lesson *(GAPS-v3 G46)*
|
|
81
|
+
|
|
82
|
+
Một lesson là **giả thuyết rằng AI sẽ lặp lại một lỗi**. Giả thuyết đó hết đúng khi code nó canh
|
|
83
|
+
không còn tồn tại, hoặc khi quy ước dự án đã đổi. Lúc đó nó phải bị **hạ xuống**, không được giữ.
|
|
84
|
+
|
|
85
|
+
Retire = đổi `Status` và ghi lý do — **KHÔNG xoá dòng**:
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
### L-003 — [code-gen] Dùng WebClient thay RestTemplate
|
|
89
|
+
- **Status**: retired
|
|
90
|
+
- **Retired**: 2027-03-15 — project đổi tầng HTTP, RestTemplate không còn trong repo
|
|
91
|
+
- **Date**: 2026-08-19
|
|
92
|
+
…giữ nguyên phần còn lại…
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Giữ lại vì nó là **lịch sử**: người sau đọc được *"vì sao dự án này từng có luật đó"*, thứ mà xoá
|
|
96
|
+
đi là mất vĩnh viễn.
|
|
97
|
+
|
|
98
|
+
> **Vì sao cần đường ra:** trước G46 file này **chỉ có đường vào**. Lesson được nạp làm *"ràng buộc
|
|
99
|
+
> cứng, cùng mức ưu tiên với CLAUDE.md"* — vĩnh viễn, kể cả khi code nó canh đã bị xoá. Không cờ
|
|
100
|
+
> nào nhắc, không lệnh nào gỡ; cách duy nhất là có người tự nhớ ra rồi xoá tay.
|
|
101
|
+
> Đây đúng lớp lỗi của **G28** (*"giữ một `pass` đã hết hiệu lực là báo cáo sai"*) và luật
|
|
102
|
+
> `rules/workflow.md` §Trace Contract — **"làm mất hiệu lực ≠ ghi đè"** — chỉ là ở hàng đợi này
|
|
103
|
+
> chưa ai áp luật đó.
|
|
104
|
+
>
|
|
105
|
+
> **Ba trong bốn lệnh ghi lesson là lệnh phản ứng khi có sự cố** (`/review-code`, `/fix-bug`,
|
|
106
|
+
> `/debug`), nên file phình nhanh nhất đúng lúc dự án đang trục trặc — và lesson sinh ra lúc đó
|
|
107
|
+
> hay gắn với một sự cố cụ thể hơn là một quy tắc bền.
|
|
108
|
+
|
|
76
109
|
## L5 — Xác nhận
|
|
77
110
|
|
|
78
111
|
In: `📝 Đã ghi lesson {id} → {lessons_path} ([{category}] {title})`
|
package/steps/context-loader.md
CHANGED
|
@@ -334,13 +334,33 @@ Phân giải path file lessons:
|
|
|
334
334
|
- Else mặc định `specs/domain-knowledge/lessons-learned.md`
|
|
335
335
|
- Ở chế độ umbrella/service (khi `service_root` được set), nếu `paths.lessons_file` chưa set, mặc định `{service_root}/.agent/project-lessons.md`
|
|
336
336
|
|
|
337
|
-
Nếu file tồn tại,
|
|
337
|
+
Nếu file tồn tại, **LỌC TRƯỚC KHI NẠP** — chỉ giữ lesson thoả **cả hai**:
|
|
338
|
+
|
|
339
|
+
1. **`Status: active`** (hoặc **không có** field `Status` → lesson cũ, coi là `active`)
|
|
340
|
+
2. **`category` khớp lệnh đang chạy**, hoặc `category: general`
|
|
341
|
+
|
|
342
|
+
Số còn lại mới nạp làm **GUARDRAIL ĐANG HOẠT ĐỘNG** cho phiên:
|
|
338
343
|
- Coi **Rule** của mỗi lesson là ràng buộc cứng — cùng mức ưu tiên với coding standards trong CLAUDE.md (Bước 3).
|
|
339
|
-
- Trước khi sinh hoặc sửa bất kỳ artifact nào (PRD, BDD, tech-doc, code, test), đối chiếu output với
|
|
344
|
+
- Trước khi sinh hoặc sửa bất kỳ artifact nào (PRD, BDD, tech-doc, code, test), đối chiếu output với lesson đã nạp có **`scope` khớp target** (domain / file glob).
|
|
340
345
|
- Nếu output sinh ra vi phạm một lesson → sửa **trước khi** trình bày, và ghi rõ lesson nào (`L-NNN`) đã được áp dụng.
|
|
341
346
|
|
|
347
|
+
Ghi lại **hai** con số cho recap Bước 7: `{n_active_for_this_command}` và `{n_total_active}`.
|
|
348
|
+
|
|
342
349
|
Nếu file không tồn tại → bỏ qua âm thầm (chưa có lesson nào được ghi nhận).
|
|
343
350
|
|
|
351
|
+
> **Vì sao lọc ở ĐÂY chứ không phải lúc dùng (GAPS-v3 G46):** bản cũ viết *"đọc và lưu **TẤT CẢ**
|
|
352
|
+
> lesson"* ở dòng trên, rồi *"đối chiếu với mọi lesson có `category` khớp"* ở dòng dưới. Bộ lọc
|
|
353
|
+
> **đã tồn tại** — chỉ là chạy **sau** khi đã nạp hết. Có 6 category, nên `/generate-prd` đang nạp
|
|
354
|
+
> cả đống lesson `code-gen` mà nó không bao giờ dùng tới. Chuyển bộ lọc lên trước là thay đổi thứ
|
|
355
|
+
> tự, không phải thêm logic.
|
|
356
|
+
>
|
|
357
|
+
> **Và vì sao chỉ nạp `active`:** trước G46 file lessons **chỉ có đường vào**. Một lesson viết năm
|
|
358
|
+
> ngoái cho code đã bị xoá vẫn được nạp làm ràng buộc cứng, mãi mãi. Cùng lớp lỗi với G28 — giữ
|
|
359
|
+
> một tín hiệu đã hết đúng. Đường ra: `/learn --review` (xem `capture-lesson.md` §Retire).
|
|
360
|
+
>
|
|
361
|
+
> ⚠️ **Không bao giờ tự bỏ lesson vì file quá dài.** Nạp thiếu một guardrail trong im lặng đúng là
|
|
362
|
+
> thứ framework này tồn tại để chống. Vượt ngưỡng thì **cảnh báo** ở recap, người quyết retire.
|
|
363
|
+
|
|
344
364
|
---
|
|
345
365
|
|
|
346
366
|
## Bước 7 — [RECAP] Working Memory Recap (chống lost-in-middle)
|
|
@@ -360,7 +380,8 @@ CLAUDE.md : {root + {service_root} | chỉ {service_root} | chỉ root | ⚠️
|
|
|
360
380
|
Ticket : {ticket_prefix}-
|
|
361
381
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
362
382
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
363
|
-
Lessons : {loaded —
|
|
383
|
+
Lessons : {loaded — {n} active cho lệnh này ({tổng} tổng) | chưa có}
|
|
384
|
+
{⚠️ CHỈ IN khi tổng ≥ 40: "{tổng} guardrail đang hoạt động — /learn --review để rà"}
|
|
364
385
|
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
365
386
|
Service : {active_service} ({active_service_module}) [← domain{/platform}{/prd_slug} nếu route qua by_prd_slug] | multi (map-theo-platform hoặc map-theo-prd_slug, chốt khi target đủ platform/prd_slug) | single-service
|
|
366
387
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
package/steps/gate.md
CHANGED
|
@@ -17,35 +17,31 @@ Trước tiên, kiểm tra xem `$ARGUMENTS` có phải là payload JSON từ m
|
|
|
17
17
|
- Đi thẳng tới phần logic riêng của lệnh.
|
|
18
18
|
3. Nếu `$ARGUMENTS` không phải JSON hoặc không có `_agent_mode` → tiếp tục sang Bước 1 (chế độ thường).
|
|
19
19
|
|
|
20
|
-
## Bước 0-B —
|
|
20
|
+
## Bước 0-B — Ghi nhận Model *(KHÔNG chặn)*
|
|
21
21
|
|
|
22
|
-
*Bỏ qua
|
|
22
|
+
*Bỏ qua nếu `_agent_mode: true` (sub-agent — orchestrator đã ghi nhận rồi).*
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
Ghi lại **model mà bạn — agent đang chạy lệnh này — thực sự đang dùng**, rồi mang nó vào
|
|
25
|
+
dòng `Model:` của report cuối (xem `report-footer`). Nếu bạn biết mình **không** phải một
|
|
26
|
+
model Opus, gắn thêm cảnh báo ngay ở dòng đó.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
**KHÔNG hỏi người dùng. KHÔNG chờ. KHÔNG dừng.**
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
Y — đúng → tiếp tục
|
|
42
|
-
S — bỏ qua kiểm tra (tôi chấp nhận rủi ro chất lượng thấp hơn với model hiện tại)
|
|
43
|
-
──────────────────────────────────────────────────────────────────
|
|
44
|
-
```
|
|
30
|
+
> **Vì sao bước này từng là prompt chặn, và vì sao bỏ (GAPS-v3 G41):** bản cũ hiện khối
|
|
31
|
+
> `⚙️ MODEL CHECK` rồi chờ `Y/S/N`. Ba vấn đề cùng chỉ một hướng:
|
|
32
|
+
> **(1)** nó hỏi người dùng thứ mà **agent đã biết chính xác**;
|
|
33
|
+
> **(2)** câu trả lời **không kiểm chứng được** — gõ `Y` xong vẫn đang chạy Haiku thì không
|
|
34
|
+
> gì phát hiện;
|
|
35
|
+
> **(3)** **cả `Y` lẫn `S` đều đi tiếp** — cách duy nhất để nó dừng là tự nguyện gõ `N`.
|
|
36
|
+
> Tức nó **không chặn được ai**, mà tốn một lần chặn ở **mọi** lệnh. Một feature đi hết
|
|
37
|
+
> pipeline dùng 20 lệnh; 30/32 lệnh chạy gate. Hai mươi lần bấm cho một tín hiệu tự-khai
|
|
38
|
+
> không kiểm chứng được — và chính cái giá đó làm mòn CHECKPOINT ở Bước 3, cổng có giá trị thật.
|
|
39
|
+
>
|
|
40
|
+
> Khai báo trong report **mạnh hơn** hỏi: đúng nguồn (agent, không phải người), và nằm
|
|
41
|
+
> **cạnh kết quả** để cân nhắc, thay vì nằm trước khi có kết quả để bấm cho xong.
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang một model Opus (`/model`) rồi chạy lại lệnh này."
|
|
43
|
+
**Vẫn khuyến nghị Opus:** phân tích spec, review kiến trúc và sinh code đòi hỏi suy luận sâu;
|
|
44
|
+
model nhỏ hơn dễ bỏ sót edge case và vi phạm kiến trúc. Đổi: `/model` → chọn Opus.
|
|
49
45
|
|
|
50
46
|
## Bước 1 — Xác định Target File
|
|
51
47
|
|
|
@@ -75,20 +71,81 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
|
|
|
75
71
|
|
|
76
72
|
## Bước 3 — CHECKPOINT
|
|
77
73
|
|
|
78
|
-
|
|
74
|
+
*Bỏ qua nếu `_agent_mode: true`.*
|
|
75
|
+
|
|
76
|
+
### 3a — Lệnh này có phải chặn không?
|
|
77
|
+
|
|
78
|
+
| Mức | Lệnh nào | `--yes` bỏ qua được? |
|
|
79
|
+
|---|---|:---:|
|
|
80
|
+
| **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
|
|
81
|
+
| **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
|
|
82
|
+
| **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
|
|
83
|
+
|
|
84
|
+
`--yes` trong `$ARGUMENTS` → bỏ qua CHECKPOINT mức *chặn thường*. (Bước 1 đã tách mọi token
|
|
85
|
+
`--` 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
|
|
86
|
+
headless: `claude -p "/generate-code UC1 --yes"`.
|
|
87
|
+
|
|
88
|
+
> **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: …*`
|
|
89
|
+
> 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
|
|
90
|
+
> **nghĩa là gì**.
|
|
91
|
+
> Nguồn máy đọc: `bin/trace-schema.json` → `gate.checkpoint_levels`; `self-check` **R11** fail
|
|
92
|
+
> build nếu nhãn trong file lệnh lệch với schema, hoặc nếu một lệnh `hard`/`none` thiếu nhãn.
|
|
93
|
+
> *(Lệnh không có dòng nào = mức **chặn thường**, mặc định.)*
|
|
94
|
+
|
|
95
|
+
> **Mức *không chặn* là thực thi đúng miễn trừ mà `rules/workflow.md` đã cấp từ trước** —
|
|
96
|
+
> trước G41 file đó viết *"read-only commands may skip CHECKPOINT"* còn gate thì luôn đòi.
|
|
97
|
+
> Hai file cùng được nạp vào mọi lệnh mà nói ngược nhau; agent theo cái nào là tuỳ lúc.
|
|
98
|
+
|
|
99
|
+
### 3b — In gì
|
|
100
|
+
|
|
101
|
+
**KHÔNG lặp lại những gì `[CTX LOADED]` vừa in.** Recap của context-loader (Bước 7) đã hiện
|
|
102
|
+
Stack · Platform · Layers · CLAUDE.md · Dict · Entities · Lessons · Service · Status ngay phía
|
|
103
|
+
trên. CHECKPOINT chỉ thêm **một** thông tin mới là `Target`.
|
|
104
|
+
|
|
105
|
+
**Mọi thứ sạch** — recap báo `Status: FULL`, không cờ nào bật → in đúng hai dòng:
|
|
79
106
|
|
|
80
107
|
```
|
|
81
|
-
CHECKPOINT
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Module : {module nếu có, else "not configured"}
|
|
87
|
-
Domains : {danh sách domain, ngăn cách bởi dấu phẩy}
|
|
108
|
+
CHECKPOINT — Target: {resolved file path}
|
|
109
|
+
Tiếp tục? (Y/N)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Có bất thường** → thêm một dòng cho **mỗi** trạng thái, nặng nhất lên đầu:
|
|
88
113
|
|
|
114
|
+
```
|
|
115
|
+
CHECKPOINT
|
|
116
|
+
🔴 Service : unresolved — {lý do context-loader đã ghi}
|
|
117
|
+
⚠️ CLAUDE.md: service overlay THIẾU — dùng root (code sinh ra có thể sai stack)
|
|
118
|
+
⚠️ Target : resolve bằng wildcard — {n} file khớp, chọn {file}
|
|
119
|
+
⚠️ Module : not configured — code sinh ra sẽ dùng default
|
|
120
|
+
Status : PARTIAL — thiếu: {danh sách}
|
|
121
|
+
Target : {resolved file path}
|
|
89
122
|
Tiếp tục? (Y/N)
|
|
90
123
|
```
|
|
91
124
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
125
|
+
### 3c — Cờ nào bật, cờ nào KHÔNG
|
|
126
|
+
|
|
127
|
+
Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader đã tính rồi** — không phát minh
|
|
128
|
+
điều kiện mới, chỉ mang thứ đang bị giấu lên chỗ người dùng phải quyết định:
|
|
129
|
+
|
|
130
|
+
| Bật cờ khi | Nguồn | Mức |
|
|
131
|
+
|---|---|:---:|
|
|
132
|
+
| `active_service = unresolved` | context-loader Bước 2b/2c/Fallback | 🔴 |
|
|
133
|
+
| `Status = MINIMAL` | recap Bước 7 | 🔴 |
|
|
134
|
+
| `Status = PARTIAL` | recap Bước 7 | ⚠️ |
|
|
135
|
+
| CLAUDE.md thiếu, hoặc service overlay thiếu | context-loader Bước 3 | ⚠️ |
|
|
136
|
+
| Target resolve qua wildcard, hoặc nhiều file khớp mà lệnh tự chọn | Bước 1 ở trên | ⚠️ |
|
|
137
|
+
| `module` không cấu hình | recap Bước 7 | ⚠️ |
|
|
138
|
+
|
|
139
|
+
**KHÔNG bật cờ cho:** `Lessons: chưa có` · `Dict: missing` · `Entities: missing`. Đó là
|
|
140
|
+
*"dự án chưa điền"*, không phải *"có gì đó sai"* — chúng ở lại trong recap.
|
|
141
|
+
|
|
142
|
+
> **Nguyên tắc một câu:** cờ dành cho thứ **framework không chắc chắn hoặc đã phải đoán**,
|
|
143
|
+
> không dành cho thứ **người dùng chưa làm**. Đẩy hết mọi thứ lên thì CHECKPOINT lại đầy như
|
|
144
|
+
> cũ, và ta quay về đúng chỗ xuất phát: một cổng luôn giống nhau thì bị lướt qua.
|
|
145
|
+
|
|
146
|
+
### 3d — Chờ trả lời
|
|
147
|
+
|
|
148
|
+
- "Y" → tiếp tục sang các bước riêng của lệnh.
|
|
149
|
+
- "N" → dừng, hỏi người dùng muốn thay đổi gì.
|
|
150
|
+
- Có `--yes` và mức *chặn thường* → coi như "Y", **nhưng vẫn IN khối CHECKPOINT** nếu có cờ
|
|
151
|
+
🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
|
package/steps/report-footer.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
Mọi report của lệnh phải kết thúc bằng section footer chuẩn này.
|
|
4
4
|
|
|
5
|
+
## Model *(bắt buộc, một dòng)*
|
|
6
|
+
|
|
7
|
+
In model mà **bạn — agent vừa chạy lệnh này — thực sự đang dùng** (ghi nhận ở Gate Bước 0-B):
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Model: {tên model đang chạy}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Nếu bạn biết mình **không** phải một model Opus, thêm cảnh báo ngay trên cùng dòng:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Model: {tên model} ⚠️ lệnh này khuyến nghị Opus — model nhỏ hơn dễ bỏ sót edge case,
|
|
17
|
+
phân tích spec thiếu sót, vi phạm kiến trúc. Cân nhắc chạy lại
|
|
18
|
+
với /model → Opus trước khi dùng kết quả này.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
> **Vì sao ở ĐÂY chứ không phải một prompt ở đầu lệnh (GAPS-v3 G41):** trước đây Gate hiện
|
|
22
|
+
> `⚙️ MODEL CHECK` rồi chờ `Y/S/N`. Nó **hỏi người dùng thứ agent đã biết**, câu trả lời
|
|
23
|
+
> **không kiểm chứng được**, và **cả `Y` lẫn `S` đều đi tiếp** — tức không chặn được ai, mà
|
|
24
|
+
> tốn một lần chặn ở mọi lệnh (20 lệnh cho một feature). Khai báo ở footer đúng nguồn hơn
|
|
25
|
+
> (agent tự khai, không phải người tự khai) và đúng chỗ hơn: nó nằm **cạnh kết quả** để
|
|
26
|
+
> người đọc cân nhắc có nên tin, thay vì nằm trước khi có kết quả để bấm cho xong.
|
|
27
|
+
|
|
5
28
|
## Status Badge
|
|
6
29
|
|
|
7
30
|
Chọn một theo kết quả:
|
|
@@ -34,7 +57,7 @@ Tìm lệnh hiện tại trong bảng phase dưới đây và đánh dấu **pha
|
|
|
34
57
|
| Phase | Commands |
|
|
35
58
|
|-------|----------|
|
|
36
59
|
| Discovery | `/define-product` |
|
|
37
|
-
| PRD | `/generate-prd` · `/refine-prd` · `/review-context` (PRD) |
|
|
60
|
+
| PRD | `/generate-prd` · `/extend-prd` · `/refine-prd` · `/review-context` (PRD) |
|
|
38
61
|
| Design Spec | `/generate-design-spec` |
|
|
39
62
|
| BDD | `/generate-bdd` · `/review-context` (BDD) |
|
|
40
63
|
| Tech Design | `/generate-tech-docs` · `/map-testids` · `/review-tech-docs` |
|
|
@@ -59,6 +82,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
59
82
|
| /setup-ai-first | `/define-product` để bắt đầu feature đầu tiên |
|
|
60
83
|
| /define-product | `/generate-prd {product-definition-file}` |
|
|
61
84
|
| /generate-prd | `/refine-prd {prd-file}` rồi `/review-context {prd-file}` |
|
|
85
|
+
| /extend-prd | `/refine-prd {prd-file}` (soi phần vừa thêm) rồi `/review-context {prd-file}` → PO duyệt → `/generate-bdd` **chỉ cho UC MỚI**; UC cũ dùng `/validate-traces --realign-prd-version {UC-ID}` |
|
|
62
86
|
| /refine-prd | Mở Review Board → cập nhật PRD → `/review-context {prd-file}` |
|
|
63
87
|
| /review-context (PRD) | Khi 0 critical → PO đặt `Status: approved`, rồi FE/App: `/generate-design-spec {prd-file}` (→ design sign-off → BDD); BE: `/generate-bdd {prd-file}`. Còn critical/NEEDS_FIX → sửa PRD (giữ draft) |
|
|
64
88
|
| /generate-design-spec | Designer review → xác nhận link Figma → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
@@ -84,7 +108,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
84
108
|
| /fix-bug | `/dev-run-test {UC-ID}` (dev_selftest vừa reset về not_run) → tạo PR; nếu fix một `{BUG-ID}` → QC chạy `/qc-run-test {UC-ID}` để verify + đóng bug |
|
|
85
109
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
86
110
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
87
|
-
| /propose-scenario |
|
|
111
|
+
| /propose-scenario | **Case A** (thiếu scenario cho AC có sẵn) → báo PO/Dev review trong `feedback/bdd-proposals/`; `/generate-bdd` tự chèn khi `Status: accepted`. **Case B** (requirement mới) → `feedback/prd-change-requests/` — PO phải đưa vào PRD trước, KHÔNG tự vào BDD được; `/validate-traces` nhắc lại kèm số ngày chờ chừng nào `Status: Open` |
|
|
88
112
|
| /learn | Tiếp tục làm việc — lesson áp dụng ở lệnh kế tiếp |
|
|
89
113
|
| /sync | `/validate-traces` để xem độ phủ đầy đủ; xử lý mọi `📥 tester feedback` được nêu |
|
|
90
114
|
| /update-framework | Review `git diff .agent/`, commit; `/sync` để đồng bộ nội dung dự án |
|
package/steps/trace-mirror.md
CHANGED
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
# Làm mới panel mirror của Living Docs *(local
|
|
1
|
+
# Làm mới panel mirror của Living Docs *(local)*
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
> **Hai vị trí, HAI TÊN KHÁC NHAU — đọc trước khi sửa gì ở đây.**
|
|
4
|
+
>
|
|
5
|
+
> | Đường dẫn | Vai trò | Git |
|
|
6
|
+
> |---|---|---|
|
|
7
|
+
> | `{paths.trace_dir}` (`.trace/` hoặc `{spec_source}/.trace/`) | **AUTHORITATIVE** — TSV + `trace-history.jsonl`. Không regenerate được. | **PHẢI commit** |
|
|
8
|
+
> | `./.trace-mirror/` ở gốc workspace hiện tại | **MIRROR** — bản sao tiện cho panel VS Code. Sinh lại được bất cứ lúc nào. | **Luôn gitignore** |
|
|
9
|
+
>
|
|
10
|
+
> Trước v0.4.3 cả hai đều tên `.trace`, nên một luật gitignore theo tên có thể **xoá sạch sổ gốc**
|
|
11
|
+
> khi dev mở thẳng spec repo làm workspace (lúc đó hai path bằng nhau). Hai tên khác nhau làm
|
|
12
|
+
> luật git đọc được bằng mắt và **không còn ca nhập nhằng nào**: `.trace-mirror/` không bao giờ
|
|
13
|
+
> commit, `.trace/` không bao giờ gitignore.
|
|
14
|
+
|
|
15
|
+
## Khi nào CÓ mirror
|
|
16
|
+
|
|
17
|
+
Mirror chỉ tồn tại khi **`{paths.trace_dir}` nằm NGOÀI workspace hiện tại** — panel đọc từ workspace đang mở nên cần một bản sao ở đây.
|
|
18
|
+
|
|
19
|
+
| Tình huống | `{paths.trace_dir}` | Có mirror? |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| Single-service | `./.trace` — **trong** workspace | ❌ Không. Panel đọc thẳng `.trace/trace-report.json`. Bỏ qua cả file này. |
|
|
22
|
+
| Dev mở thẳng **spec repo** | `./.trace` — **trong** workspace | ❌ Không. Như trên. |
|
|
23
|
+
| Umbrella + `spec_source`, dev đứng ở umbrella hoặc service submodule | `{spec_source}/.trace` — **ngoài** workspace | ✅ Có |
|
|
24
|
+
| Umbrella legacy (không `spec_source`) | `.trace` theo từng service | ✅ Có |
|
|
25
|
+
|
|
26
|
+
Quy tắc một dòng: **phân giải `panel_mirror = ./.trace-mirror` ở gốc workspace hiện tại; nếu `{paths.trace_dir}` đã nằm trong workspace này thì bỏ qua toàn bộ bước mirror.**
|
|
27
|
+
|
|
28
|
+
---
|
|
5
29
|
|
|
6
30
|
Sau khi cập nhật TSV authoritative tại `{paths.trace_dir}`:
|
|
7
31
|
|
|
@@ -9,11 +33,14 @@ Sau khi cập nhật TSV authoritative tại `{paths.trace_dir}`:
|
|
|
9
33
|
`{paths.trace_dir}` phân giải về `{spec_source}/.trace` — vị trí authoritative duy nhất.
|
|
10
34
|
Lệnh này chạy từ `service_root`, nên thao tác ghi là **liên-repo vào spec submodule**;
|
|
11
35
|
commit/push spec submodule cho lần cập nhật trace (giống như `feedback/`).
|
|
12
|
-
|
|
13
|
-
|
|
36
|
+
|
|
37
|
+
1. Phân giải `panel_mirror = ./.trace-mirror` tại **gốc workspace hiện tại**.
|
|
38
|
+
2. Nếu `{paths.trace_dir}` **không** nằm trong workspace hiện tại, copy mỗi
|
|
14
39
|
`{UC-ID}-{platform}.tsv` vừa cập nhật → `{panel_mirror}/{UC-ID}-{platform}.tsv` (tạo thư mục; ghi đè).
|
|
15
|
-
Không namespace theo service — chỉ có một bộ trace; service sở hữu được mang
|
|
16
|
-
|
|
40
|
+
Không namespace theo service — chỉ có một bộ trace; service sở hữu được mang ở
|
|
41
|
+
**cột `service` (cột 23)** của chính từng row, do `/generate-bdd` ghi từ `@trace.service`.
|
|
42
|
+
3. **KHÔNG copy `trace-history.jsonl`.** Nó là dữ liệu tích luỹ, không phải thứ sinh lại được —
|
|
43
|
+
nhân bản nó ra một thư mục gitignore là tạo hai lịch sử lệch nhau rồi mất bản thật.
|
|
17
44
|
|
|
18
45
|
**Legacy (không có `spec_source` — trace theo service):**
|
|
19
46
|
Copy mỗi `{UC-ID}-{platform}.tsv` vừa cập nhật → `{panel_mirror}/{service-name}/{UC-ID}-{platform}.tsv`
|
package/templates/README.md
CHANGED
|
@@ -17,7 +17,28 @@ commands/generate-bdd.md
|
|
|
17
17
|
|
|
18
18
|
Không lệnh nào đọc một path template lúc chạy. `paths.feature_template` / `paths.prd_template` từng tồn tại trong `project-context.yaml` nhưng chưa bao giờ có tác dụng — đã được gỡ bỏ (xem `GAPS.md` G9).
|
|
19
19
|
|
|
20
|
-
**Thêm nữa:** `.agent/` là vùng bị ghi đè. `/update-framework` chạy `npx … --init`, và `--init` copy `core/` → `.agent/` **vô điều kiện** (`bin/index.js` → `
|
|
20
|
+
**Thêm nữa:** `.agent/` là vùng bị ghi đè. `/update-framework` chạy `npx … --init`, và `--init` copy `core/` → `.agent/` **vô điều kiện** (`bin/index.js` → `installCore`). File duy nhất được giữ lại là `.agent/project-context.yaml`. Nên mọi chỉnh sửa ở `.agent/templates/` sẽ **biến mất** ở lần nâng cấp kế tiếp — từ v0.4.2 thì không còn im lặng: bản cũ được lưu vào `.agent/.overwritten-{version}-{date}/` và được liệt kê ra (`GAPS.md` G24). Nhưng vẫn phải áp lại bằng tay mỗi version, nên đây không phải chỗ để đặt thay đổi.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Ngoại lệ: `ci/` và `hooks/` — template để COPY RA, không phải để build
|
|
25
|
+
|
|
26
|
+
Hai thư mục này **không** giống phần còn lại của `templates/`. Chúng không được `{{include}}` vào lệnh nào, và **không** được đọc lúc chạy. Chúng là file **hoàn chỉnh, dùng ngay**, chờ một người copy ra khỏi `.agent/`:
|
|
27
|
+
|
|
28
|
+
| File | Copy tới | Làm gì |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `ci/trace-gate.yml` | `.github/workflows/` của project | Chặn PR khi trace có cờ 🔴 (`--gate-trace`) |
|
|
31
|
+
| `hooks/pre-push` | `.git/hooks/pre-push` (rồi `chmod +x`) | Chặn push khi sổ trace hỏng cấu trúc (`--lint-trace`) |
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# từ gốc project
|
|
35
|
+
mkdir -p .github/workflows && cp .agent/templates/ci/trace-gate.yml .github/workflows/
|
|
36
|
+
cp .agent/templates/hooks/pre-push .git/hooks/pre-push && chmod +x .git/hooks/pre-push
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Phải copy RA, không dùng tại chỗ** — vì đúng cái lý do cả file README này nói: `.agent/` bị ghi đè mỗi lần nâng cấp, và `.git/hooks/` thì git không bao giờ chạy từ chỗ khác. Copy ra rồi thì chúng là file của project: sửa tuỳ ý, nâng cấp framework không đụng tới.
|
|
40
|
+
|
|
41
|
+
Vì sao chúng tồn tại → `GAPS-v3.md` G39: framework phát hiện được một lớp lỗi mà build xanh + test xanh không thấy, nhưng trước đó việc phát hiện phụ thuộc vào có người tự nguyện chạy một lệnh chat. Hai file này là chỗ nó chặn bằng máy.
|
|
21
42
|
|
|
22
43
|
## Muốn đổi cấu trúc artifact sinh ra thì làm gì
|
|
23
44
|
|
|
@@ -43,5 +64,7 @@ Rồi phát hành version mới; project chạy `/update-framework` để nhận
|
|
|
43
64
|
| `product-definition.template.md` | `commands/define-product.tmpl` | product definition |
|
|
44
65
|
| `platform-guide.template.md` | (tham khảo) | — |
|
|
45
66
|
| `project-context.yaml` | **không** include — được copy thẳng làm file config khởi tạo | `.agent/project-context.yaml` |
|
|
67
|
+
| `ci/trace-gate.yml` | **không** include — người dùng copy ra | `.github/workflows/trace-gate.yml` |
|
|
68
|
+
| `hooks/pre-push` | **không** include — người dùng copy ra | `.git/hooks/pre-push` |
|
|
46
69
|
|
|
47
70
|
> Lưu ý `project-context.yaml` là ngoại lệ duy nhất: nó **được** copy ra làm file thật của project, và **được bảo vệ** khỏi ghi đè khi nâng cấp (chỉ tạo nếu chưa tồn tại).
|