@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/core/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).
|
|
@@ -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 |
|
|
@@ -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/core/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).
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
2
|
+
# SDD Framework — Trace Gate (GitHub Actions)
|
|
3
|
+
#
|
|
4
|
+
# COPY file này vào .github/workflows/ của project. Nó KHÔNG tự chạy từ
|
|
5
|
+
# .agent/templates/ — mọi thứ trong .agent/ là bản sinh ra, bị ghi đè mỗi lần
|
|
6
|
+
# /update-framework.
|
|
7
|
+
#
|
|
8
|
+
# VÌ SAO CẦN (GAPS-v3 G39): framework phát hiện được một lớp lỗi mà build xanh +
|
|
9
|
+
# test từng-UC xanh KHÔNG thấy — luồng ghép chạy vào hàm rỗng (SEAM_UNWIRED,
|
|
10
|
+
# STUB_UNRESOLVED), hoặc code trỏ vào scenario đã bị xoá (ORPHANED, TRACE_ORPHAN).
|
|
11
|
+
# Nhưng trước G39 việc phát hiện đó phụ thuộc vào có người TỰ NGUYỆN chạy
|
|
12
|
+
# /validate-traces trong Claude Code rồi đọc report bằng mắt. Cái gì không chặn
|
|
13
|
+
# thì sau sprint thứ ba không ai làm. Đây là chỗ nó chặn.
|
|
14
|
+
#
|
|
15
|
+
# GIỚI HẠN — đọc trước khi tin:
|
|
16
|
+
# Job này chứng minh "report khớp SỔ, và sổ không có cờ 🔴".
|
|
17
|
+
# Nó KHÔNG chứng minh "sổ khớp CODE" — việc đó cần quét tag trong source, đọc
|
|
18
|
+
# .feature, so version, tức cần /validate-traces (một lệnh LLM, không chạy được
|
|
19
|
+
# trong CI thường). Nên nó bắt ca phổ biến "quên chạy lại /validate-traces",
|
|
20
|
+
# nhưng KHÔNG bắt ca "sửa code mà không đụng sổ".
|
|
21
|
+
# Muốn bịt nốt: xem job `require-fresh-audit` ở cuối file.
|
|
22
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
23
|
+
|
|
24
|
+
name: Trace Gate
|
|
25
|
+
|
|
26
|
+
on:
|
|
27
|
+
pull_request:
|
|
28
|
+
push:
|
|
29
|
+
branches: [main, master, develop]
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
trace-gate:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
with:
|
|
37
|
+
# Cần lịch sử để job require-fresh-audit so được diff. Bỏ nếu không dùng job đó.
|
|
38
|
+
fetch-depth: 0
|
|
39
|
+
# Spec/trace nằm trong submodule (umbrella + spec_source)? Bỏ comment:
|
|
40
|
+
# submodules: recursive
|
|
41
|
+
|
|
42
|
+
- uses: actions/setup-node@v4
|
|
43
|
+
with:
|
|
44
|
+
node-version: '20'
|
|
45
|
+
|
|
46
|
+
# ── 1. Cấu trúc sổ ───────────────────────────────────────────────────────
|
|
47
|
+
# Sổ trace 24 cột do LLM ghi bằng tay. Một dấu tab thiếu dồn mọi ô sang trái
|
|
48
|
+
# và ô `status` nhận một ngày tháng — trước G38 không gì báo. Bước này chặn.
|
|
49
|
+
# Cũng bắt marker conflict git lọt vào sổ (T7) và sổ thiếu luật merge (T10).
|
|
50
|
+
- name: Lint sổ trace
|
|
51
|
+
run: npx -y @educa-corp/sdd-framework@latest --lint-trace
|
|
52
|
+
|
|
53
|
+
# ── 2. Cổng chặn PR ──────────────────────────────────────────────────────
|
|
54
|
+
# --gate-trace tự chạy lại lint ở tầng G1, nên bước 1 ở trên là để có log
|
|
55
|
+
# riêng dễ đọc khi đỏ. Muốn gọn thì bỏ bước 1 và chỉ giữ bước này.
|
|
56
|
+
- name: Trace gate (cờ 🔴 chặn PR)
|
|
57
|
+
run: npx -y @educa-corp/sdd-framework@latest --gate-trace
|
|
58
|
+
|
|
59
|
+
# ── 3. (tuỳ chọn) Đưa kết quả vào PR summary ─────────────────────────────
|
|
60
|
+
- name: Ghi kết quả vào job summary
|
|
61
|
+
if: always()
|
|
62
|
+
run: |
|
|
63
|
+
npx -y @educa-corp/sdd-framework@latest --gate-trace --json --warn-only \
|
|
64
|
+
> gate.json || true
|
|
65
|
+
{
|
|
66
|
+
echo '## Trace Gate'
|
|
67
|
+
echo '```json'
|
|
68
|
+
cat gate.json
|
|
69
|
+
echo '```'
|
|
70
|
+
} >> "$GITHUB_STEP_SUMMARY"
|
|
71
|
+
|
|
72
|
+
# ───────────────────────────────────────────────────────────────────────────
|
|
73
|
+
# Ép audit phải TƯƠI khi thứ report đang KHẲNG ĐỊNH bị đổi.
|
|
74
|
+
#
|
|
75
|
+
# Bịt cái lỗ mà trace-gate không bịt được: gate chứng minh "report khớp SỔ",
|
|
76
|
+
# không chứng minh "sổ khớp CODE" — việc đó cần /validate-traces, một lệnh LLM
|
|
77
|
+
# không chạy được ở đây. Nên job này dùng một PROXY: không verify được thì ĐÒI
|
|
78
|
+
# BẰNG CHỨNG có người vừa verify.
|
|
79
|
+
#
|
|
80
|
+
# ĐO BẰNG TAG, KHÔNG BẰNG `src/**`:
|
|
81
|
+
# Framework có luật boundary-only tagging — chỉ Controller/Handler/Middleware/
|
|
82
|
+
# Steps mang tag @trace; Entity/Repository/DTO/Interface/Base KHÔNG. Nên câu
|
|
83
|
+
# hỏi "PR có sửa src/ không?" chặn cả PR chỉ thêm một field vào DTO — một file
|
|
84
|
+
# không mang lời khẳng định trace nào. Cái gì báo oan thì bị tắt, rồi mất luôn
|
|
85
|
+
# phần thật sự cần chặn.
|
|
86
|
+
# Câu hỏi đúng: "PR có chạm dòng nào mang tag mà report đang khẳng định không?"
|
|
87
|
+
#
|
|
88
|
+
# sửa log trong Controller → cho qua (bản `src/**` cũ: chặn oan)
|
|
89
|
+
# thêm field vào DTO → cho qua (bản cũ: chặn oan)
|
|
90
|
+
# thêm method + @implements → CHẶN
|
|
91
|
+
# lấp một @trace.stub → CHẶN
|
|
92
|
+
#
|
|
93
|
+
# KHÔNG cần sửa gì theo layout project — tag là tag, ở đâu cũng vậy.
|
|
94
|
+
#
|
|
95
|
+
# BẢY TAG dưới đây là NGUỒN của đúng 4 cờ chặn PR. Chúng được khai trong
|
|
96
|
+
# bin/trace-schema.json → gate.audit_invalidating_tags, và self-check R10 fail
|
|
97
|
+
# build nếu file này không nhắc đủ — tag đổi tên mà đây không biết thì grep
|
|
98
|
+
# không khớp gì, job LUÔN XANH, và cổng mù trong im lặng.
|
|
99
|
+
#
|
|
100
|
+
# GIỚI HẠN ĐÃ BIẾT: đổi tên class (AuthService → AuthenticationService) không
|
|
101
|
+
# chạm dòng tag ⇒ job này bỏ lọt, dù cột implemented_by giờ trỏ vào tên không
|
|
102
|
+
# còn. Chấp nhận có chủ ý: ca đó ít gặp và KHÔNG im lặng (/validate-traces lần
|
|
103
|
+
# sau báo ngay), còn báo oan thì xảy ra mỗi ngày.
|
|
104
|
+
# Muốn chặt hơn (bắt cả rename, giá là chặn cả việc sửa log trong Controller):
|
|
105
|
+
# đổi bước dưới thành — lấy danh sách file đã đổi, rồi `grep -l` bảy tag đó
|
|
106
|
+
# TRÊN NỘI DUNG FILE thay vì trên diff.
|
|
107
|
+
# ───────────────────────────────────────────────────────────────────────────
|
|
108
|
+
require-fresh-audit:
|
|
109
|
+
if: github.event_name == 'pull_request'
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
steps:
|
|
112
|
+
- uses: actions/checkout@v4
|
|
113
|
+
with: { fetch-depth: 0 }
|
|
114
|
+
|
|
115
|
+
- name: Đổi thứ report khẳng định thì audit phải đổi theo
|
|
116
|
+
shell: bash
|
|
117
|
+
run: |
|
|
118
|
+
BASE="origin/${{ github.base_ref }}"
|
|
119
|
+
|
|
120
|
+
# 7 tag sinh ra 4 cờ chặn PR — khai ở bin/trace-schema.json,
|
|
121
|
+
# gate.audit_invalidating_tags (self-check R10 canh danh sách này khớp).
|
|
122
|
+
TAGS='@trace\.(implements|verifies|seam_port|seam_pending|stub|stub_owner|stub_for)'
|
|
123
|
+
|
|
124
|
+
# Chạm dòng mang tag = report có thể đã hết đúng. -U0 để chỉ lấy dòng thật đổi.
|
|
125
|
+
touched=$(git diff -U0 "$BASE"...HEAD | grep -E "^[+-].*${TAGS}" | head -5 || true)
|
|
126
|
+
audit=$(git diff --name-only "$BASE"...HEAD | grep -E 'trace-report\.json$' | head -1 || true)
|
|
127
|
+
|
|
128
|
+
if [ -n "$touched" ] && [ -z "$audit" ]; then
|
|
129
|
+
echo "::error::PR đổi tag trace nhưng không kèm trace-report.json được sinh lại."
|
|
130
|
+
echo ""
|
|
131
|
+
echo "Những dòng này đã đổi:"
|
|
132
|
+
echo "$touched" | sed 's/^/ /'
|
|
133
|
+
echo ""
|
|
134
|
+
echo "Trace gate chỉ chứng minh 'report khớp SỔ'. Tag vừa đổi mà chưa audit lại"
|
|
135
|
+
echo "thì mọi cờ 🔴 trong report nói về trạng thái TRƯỚC khi bạn sửa."
|
|
136
|
+
echo ""
|
|
137
|
+
echo "Chạy trong Claude Code: /validate-traces"
|
|
138
|
+
echo "Rồi commit: {trace_dir}/trace-report.json + *.tsv"
|
|
139
|
+
exit 1
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
if [ -n "$touched" ]; then
|
|
143
|
+
echo "✅ Tag trace có đổi, và audit đã được sinh lại cùng PR."
|
|
144
|
+
else
|
|
145
|
+
echo "✅ PR không chạm tag nào mà report đang khẳng định — audit vẫn còn đúng."
|
|
146
|
+
fi
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# @trace.revision: 1 ← field tĩnh; version theo dõi bằng @trace.bdd_version
|
|
5
5
|
# @trace.domain: <domain>
|
|
6
6
|
# @trace.platform: {active_platform — web | app | system} ← BẮT BUỘC mọi mode; phải khớp segment bdd/{platform}/ của path
|
|
7
|
-
# @trace.service: {active_service —
|
|
7
|
+
# @trace.service: {active_service — BẮT BUỘC mọi mode. "—" ở single-service/spec repo mode; "multi" nếu chưa chốt; "unresolved" nếu routing sai. Nguồn của cột TSV `service` — trace gộp không tách theo service nên đây là chỗ DUY NHẤT mang thông tin sở hữu}
|
|
8
8
|
# @trace.module: {active_module trong umbrella mode; "unknown" trong spec repo mode}
|
|
9
9
|
# @trace.status: draft
|
|
10
10
|
# @trace.author: AI-generated
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
# SDD Framework — git pre-push hook
|
|
4
|
+
#
|
|
5
|
+
# CÀI (từ gốc project):
|
|
6
|
+
# cp .agent/templates/hooks/pre-push .git/hooks/pre-push
|
|
7
|
+
# chmod +x .git/hooks/pre-push
|
|
8
|
+
#
|
|
9
|
+
# Trên Windows: Git for Windows chạy hook bằng sh nên file này dùng được như vậy.
|
|
10
|
+
#
|
|
11
|
+
# VÌ SAO CÓ HOOK NÀY khi đã có CI (GAPS-v3 G39/G40): nó chặn ở chỗ RẺ NHẤT.
|
|
12
|
+
# Cụ thể là T7 — marker conflict git (`<<<<<<< HEAD`) lọt vào sổ trace. Một khi
|
|
13
|
+
# thứ đó vào nhánh chung thì mọi người kéo về đều có sổ hỏng, và sổ trace là dữ
|
|
14
|
+
# liệu KHÔNG dựng lại được. Bắt trước lúc push tốn 2 giây; bắt ở CI thì đã muộn
|
|
15
|
+
# một vòng, bắt bằng mắt thì thường là ba tuần sau.
|
|
16
|
+
#
|
|
17
|
+
# CỐ Ý CHỈ LINT, KHÔNG GATE:
|
|
18
|
+
# --lint-trace = cấu trúc sổ. Nhanh, offline được sau lần đầu, và một lỗi ở đây
|
|
19
|
+
# LUÔN là lỗi thật (tab lệch, marker conflict, enum sai).
|
|
20
|
+
# --gate-trace = cờ 🔴. Cần trace-report.json còn tươi, mà giữa lúc làm việc thì
|
|
21
|
+
# nó thường chưa tươi — đỏ liên tục ⇒ người ta gõ --no-verify ⇒
|
|
22
|
+
# mất luôn cả phần lint. Cờ 🔴 để CI chặn.
|
|
23
|
+
#
|
|
24
|
+
# Bỏ qua một lần (dùng có ý thức, đừng thành phản xạ): git push --no-verify
|
|
25
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
# Không có node thì im lặng cho qua — hook không được làm người ta không push được
|
|
28
|
+
# vì lý do không liên quan tới việc họ đang làm.
|
|
29
|
+
command -v node >/dev/null 2>&1 || exit 0
|
|
30
|
+
|
|
31
|
+
# Không có sổ trace thì không có gì để kiểm (project chưa chạy /generate-bdd lần nào).
|
|
32
|
+
# Sửa đường dẫn nếu trace_dir của project khác (vd ../.trace, hay {spec_source}/.trace).
|
|
33
|
+
TRACE_DIR=".trace"
|
|
34
|
+
[ -d "$TRACE_DIR" ] || exit 0
|
|
35
|
+
|
|
36
|
+
echo "→ Lint sổ trace trước khi push ..."
|
|
37
|
+
|
|
38
|
+
if npx -y @educa-corp/sdd-framework@latest --lint-trace --trace "$TRACE_DIR"; then
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
cat <<'MSG'
|
|
43
|
+
|
|
44
|
+
──────────────────────────────────────────────────────────────────────
|
|
45
|
+
🔴 PUSH BỊ CHẶN — sổ trace hỏng cấu trúc.
|
|
46
|
+
|
|
47
|
+
Sổ trace là dữ liệu KHÔNG regenerate được. Đẩy một sổ hỏng lên nhánh
|
|
48
|
+
chung thì mọi người kéo về đều nhận bản hỏng.
|
|
49
|
+
|
|
50
|
+
Thường gặp nhất — marker conflict git chưa giải (T7):
|
|
51
|
+
1. Mở file lint vừa nêu, xoá 3 dòng <<<<<<< ======= >>>>>>>
|
|
52
|
+
2. GIỮ CẢ HAI BÊN, đừng chọn một bên (mất row là mất vĩnh viễn)
|
|
53
|
+
3. npx @educa-corp/sdd-framework --lint-trace # xác nhận sạch
|
|
54
|
+
4. /validate-traces trong Claude Code # reconcile row trùng
|
|
55
|
+
|
|
56
|
+
Playbook đầy đủ: docs/02-concepts/traceability.md
|
|
57
|
+
Bỏ qua một lần: git push --no-verify
|
|
58
|
+
──────────────────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
MSG
|
|
61
|
+
exit 1
|
|
@@ -77,12 +77,29 @@ AI *follow* các file này — để trống thì nó *đoán*:
|
|
|
77
77
|
|
|
78
78
|
| Lệnh | Việc | Ghi đè | KHÔNG đụng |
|
|
79
79
|
|------|------|--------|-----------|
|
|
80
|
-
| `/update-framework` | Sync bản npm mới | `.agent/commands\|steps\|hooks\|rules\|templates\|skills\|modules` | `CLAUDE.md`,
|
|
80
|
+
| `/update-framework` | Sync bản npm mới | `.agent/commands\|steps\|hooks\|rules\|templates\|skills\|modules` | `CLAUDE.md`, `.agent/project-context.yaml`, `.agent/project-lessons.md`, `.agent/review/`, `domain-knowledge/`, `.trace/`, `feedback/` |
|
|
81
81
|
| `/sync` (umbrella) | Pull + init submodule + nổi feedback + Living Docs | — | — |
|
|
82
82
|
|
|
83
83
|
Kiểm tra version mới nhất: `npm view @educa-corp/sdd-framework version`.
|
|
84
84
|
|
|
85
85
|
> **Quy tắc edit (critical):** `.tmpl` + `steps/` là source of truth. Sửa framework artifact phải sửa `.tmpl`/`steps` rồi `node bin/build.js`. Sửa thẳng `.agent/commands/*.md` sẽ **mất** khi rebuild/update.
|
|
86
|
+
>
|
|
87
|
+
> Từ v0.4.2, nâng cấp **cứu** file bạn đã sửa trong vùng ghi đè: bản cũ lưu ở `.agent/.overwritten-{version}-{date}/` và danh sách được in ra. Ranh giới vùng-sửa-được đầy đủ: `.agent/README.md`. Chi tiết cơ chế: [Configuration › Vùng nào bị ghi đè](../04-reference/configuration.md#vùng-nào-bị-ghi-đè-khi-update).
|
|
88
|
+
|
|
89
|
+
### Migration bố cục spec
|
|
90
|
+
|
|
91
|
+
Một số version đổi **bố cục** chứ không chỉ nội dung lệnh. `/update-framework` Step 5.5 tự quét và nhắc, hoặc chạy tay (đều **dry-run mặc định**, thêm `--apply` để thực thi):
|
|
92
|
+
|
|
93
|
+
| Lệnh | Khi nào cần |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `--migrate-bdd-platform` | Có `.feature` nằm **trực tiếp** dưới `bdd/` (bố cục phẳng trước v0.4.1) → chuyển sang `bdd/{platform}/`. Bố cục phẳng làm `web`/`system` cùng UC **va tên và ghi đè nhau**. |
|
|
96
|
+
| `--migrate-specs` | Còn `specs/prd/` hay `specs/bdd/` ở cấp gốc (bố cục artifact-type-first rất cũ) |
|
|
97
|
+
| `--rename-prd-files` | PRD còn tên cố định `prd.md` thay vì `{TICKET-ID}-{prd-slug}.md` |
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npx @educa-corp/sdd-framework --migrate-bdd-platform # xem plan
|
|
101
|
+
npx @educa-corp/sdd-framework --migrate-bdd-platform --apply # thực thi
|
|
102
|
+
```
|
|
86
103
|
|
|
87
104
|
---
|
|
88
105
|
|
|
@@ -26,8 +26,10 @@ Dùng AI tự do (mở chat, gõ prompt, copy-paste) → AI suy diễn theo tr
|
|
|
26
26
|
| Vấn đề | Cách giải |
|
|
27
27
|
|--------|-----------|
|
|
28
28
|
| AI viết lung tung, không bám requirement | Spec là **anchor cứng**; code link `@trace.source` về scenario |
|
|
29
|
-
| Sửa code → spec lệch → AI hiểu sai lần sau | **Spec là
|
|
30
|
-
| Sửa spec → không biết code nào cần regen | **Trace state `.tsv
|
|
29
|
+
| Sửa code → spec lệch → AI hiểu sai lần sau | **Spec là SSOT của "bản hiện tại"**; code mang version của "bản tôi được sinh theo" — **lệch nhau chính là tín hiệu drift** |
|
|
30
|
+
| Sửa spec → không biết code nào cần regen | **Trace state `.tsv`** một sổ / UC × platform → `OK`/`GAP`/`DRIFT`/`UNTRACKED`/`ORPHANED` |
|
|
31
|
+
| Xoá scenario → code mồ côi nằm im | **Quét ngược code → spec**; code trỏ vào SC không còn tồn tại bị gắn cờ 🔴, không tự hết |
|
|
32
|
+
| Build xanh nhưng ghép luồng chạy vào no-op | **Sổ seam/stub** — bắt lớp lỗi mà build + test từng-UC không thấy |
|
|
31
33
|
| PRD/BDD kém → code rác hàng loạt | **Quality gate** (`/review-context`) phải sạch critical + PO approve |
|
|
32
34
|
| Lỗi/định hướng sai lặp lại | **`/learn`** ghi lesson, nạp lại vào context |
|
|
33
35
|
| Đổi tech stack → viết lại workflow | **Module overlay** — skill đọc `stack-profile.yaml`, không hardcode |
|