@educa-corp/sdd-framework 0.2.1 → 0.2.4
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/index.js +59 -29
- package/commands/debug.md +21 -8
- package/commands/define-product.md +21 -8
- package/commands/dev-gen-test.md +21 -8
- package/commands/dev-run-test.md +21 -8
- package/commands/dev-smoke-test.md +21 -8
- package/commands/fix-bug.md +21 -8
- package/commands/generate-bdd.md +24 -10
- package/commands/generate-bdd.tmpl +3 -2
- package/commands/generate-code.md +21 -8
- package/commands/generate-design-spec.md +21 -8
- package/commands/generate-prd.md +21 -8
- package/commands/generate-spec-manifest.md +21 -8
- package/commands/generate-tech-docs.md +21 -8
- package/commands/learn.md +21 -8
- package/commands/map-testids.md +21 -8
- package/commands/propose-scenario.md +21 -8
- package/commands/qc-analyze.md +21 -8
- package/commands/qc-design-test.md +21 -8
- package/commands/qc-plan.md +21 -8
- package/commands/qc-report.md +21 -8
- package/commands/qc-review.md +21 -8
- package/commands/qc-run-test.md +21 -8
- package/commands/refine-prd.md +21 -8
- package/commands/report-bug.md +21 -8
- package/commands/review-code.md +21 -8
- package/commands/review-context.md +21 -8
- package/commands/review-tech-docs.md +21 -8
- package/commands/setup-ai-first.md +14 -7
- package/commands/setup-ai-first.tmpl +14 -7
- package/commands/validate-traces.md +21 -8
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/debug.md +21 -8
- package/core/commands/define-product.md +21 -8
- package/core/commands/dev-gen-test.md +21 -8
- package/core/commands/dev-run-test.md +21 -8
- package/core/commands/dev-smoke-test.md +21 -8
- package/core/commands/fix-bug.md +21 -8
- package/core/commands/generate-bdd.md +24 -10
- package/core/commands/generate-code.md +21 -8
- package/core/commands/generate-design-spec.md +21 -8
- package/core/commands/generate-prd.md +21 -8
- package/core/commands/generate-spec-manifest.md +21 -8
- package/core/commands/generate-tech-docs.md +21 -8
- package/core/commands/learn.md +21 -8
- package/core/commands/map-testids.md +21 -8
- package/core/commands/propose-scenario.md +21 -8
- package/core/commands/qc-analyze.md +21 -8
- package/core/commands/qc-design-test.md +21 -8
- package/core/commands/qc-plan.md +21 -8
- package/core/commands/qc-report.md +21 -8
- package/core/commands/qc-review.md +21 -8
- package/core/commands/qc-run-test.md +21 -8
- package/core/commands/refine-prd.md +21 -8
- package/core/commands/report-bug.md +21 -8
- package/core/commands/review-code.md +21 -8
- package/core/commands/review-context.md +21 -8
- package/core/commands/review-tech-docs.md +21 -8
- package/core/commands/setup-ai-first.md +14 -7
- package/core/commands/validate-traces.md +21 -8
- package/core/steps/context-loader.md +21 -8
- package/core/templates/project-context.yaml +23 -10
- package/package.json +1 -1
- package/steps/context-loader.md +21 -8
- package/templates/project-context.yaml +23 -10
|
@@ -177,16 +177,28 @@ Nếu có section `services`:
|
|
|
177
177
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
178
178
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
179
179
|
|
|
180
|
-
**
|
|
181
|
-
-
|
|
182
|
-
-
|
|
180
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
181
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
182
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
183
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
184
|
+
|
|
185
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
186
|
+
|
|
187
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
183
188
|
- Lưu `active_service` = `services.{domain}.path`
|
|
184
189
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
185
190
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
186
191
|
|
|
187
|
-
**
|
|
188
|
-
-
|
|
189
|
-
-
|
|
192
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
193
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
194
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
195
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
196
|
+
|
|
197
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
198
|
+
|
|
199
|
+
**3. Fallback**:
|
|
200
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
201
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
190
202
|
|
|
191
203
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
192
204
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -206,7 +218,7 @@ Nếu có section `services`:
|
|
|
206
218
|
|
|
207
219
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
208
220
|
|
|
209
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
221
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
210
222
|
|
|
211
223
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
212
224
|
|
|
@@ -382,7 +394,8 @@ Ticket : {ticket_prefix}-
|
|
|
382
394
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
383
395
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
384
396
|
Lessons : {loaded — N guardrails | chưa có}
|
|
385
|
-
|
|
397
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
398
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
386
399
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
387
400
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
388
401
|
```
|
|
@@ -599,14 +612,15 @@ Từ vựng step của System BDD (luôn dùng — bất kể từ vựng FE/App
|
|
|
599
612
|
*Bỏ qua section này nếu đang chạy spec repo mode.*
|
|
600
613
|
|
|
601
614
|
Routing service là **domain-keyed** và **context-loader (Bước 1.5) đã phân giải sẵn** từ `@trace.domain`/Domain của PRD — KHÔNG re-resolve ở đây, chỉ dùng lại các biến đã set:
|
|
602
|
-
- `active_service` =
|
|
603
|
-
- `active_module` = module của service (`services.{domain}.module`, đã override `tech_stack.module` ở Bước 1.5) — dùng cho từ vựng bên dưới.
|
|
615
|
+
- `active_service` = path submodule đã phân giải (dạng phẳng), hoặc `"multi"` (dạng map-theo-platform ở cấp PRD — chưa chốt 1 platform), hoặc `"unresolved"` nếu domain không khớp entry nào, hoặc bỏ trống ở single-service.
|
|
616
|
+
- `active_module` = module của service (`services.{domain}.module`, đã override `tech_stack.module` ở Bước 1.5) — dùng cho từ vựng bên dưới. Với `"multi"`, lấy module theo từng platform từ `service_candidates` khi sinh `bdd/{platform}/`.
|
|
604
617
|
|
|
605
618
|
Chỉ cần kiểm tra trạng thái đã phân giải:
|
|
606
619
|
|
|
607
620
|
| Trạng thái (từ context-loader) | Hành động |
|
|
608
621
|
|---|---|
|
|
609
622
|
| `active_service` đã phân giải thành path service | Tiếp tục với `active_module` đã set. |
|
|
623
|
+
| `active_service = "multi"` (domain map-theo-platform, target PRD chưa gắn 1 platform) | Tiếp tục — BDD là artifact liên team, platform-split. Sinh `bdd/{platform}/` cho các platform có trong `service_candidates`; từ vựng lấy theo `service_candidates.{platform}.module`. KHÔNG cần chốt 1 service. |
|
|
610
624
|
| `active_service = "unresolved"` (có section `services` nhưng domain PRD không khớp entry nào) | **DỪNG**, báo: "Domain `{domain}` của PRD không khớp service nào trong `services:` của project-context.yaml — bổ sung mapping rồi chạy lại." (Không đoán/hỏi tay — domain là khoá định danh, lệch là lỗi cấu hình cần sửa ở SoT.) |
|
|
611
625
|
| Single-service (không có section `services`) | `active_module = tech_stack.module` (đã set ở Bước 6.5). Tiếp tục. |
|
|
612
626
|
|
|
@@ -179,16 +179,28 @@ Nếu có section `services`:
|
|
|
179
179
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
180
180
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
181
181
|
|
|
182
|
-
**
|
|
183
|
-
-
|
|
184
|
-
-
|
|
182
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
183
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
184
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
185
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
186
|
+
|
|
187
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
188
|
+
|
|
189
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
185
190
|
- Lưu `active_service` = `services.{domain}.path`
|
|
186
191
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
187
192
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
188
193
|
|
|
189
|
-
**
|
|
190
|
-
-
|
|
191
|
-
-
|
|
194
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
195
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
196
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
197
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
198
|
+
|
|
199
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
200
|
+
|
|
201
|
+
**3. Fallback**:
|
|
202
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
203
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
192
204
|
|
|
193
205
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
194
206
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -208,7 +220,7 @@ Nếu có section `services`:
|
|
|
208
220
|
|
|
209
221
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
210
222
|
|
|
211
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
223
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
212
224
|
|
|
213
225
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
214
226
|
|
|
@@ -384,7 +396,8 @@ Ticket : {ticket_prefix}-
|
|
|
384
396
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
385
397
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
386
398
|
Lessons : {loaded — N guardrails | chưa có}
|
|
387
|
-
|
|
399
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
400
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
388
401
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
389
402
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
390
403
|
```
|
|
@@ -179,16 +179,28 @@ Nếu có section `services`:
|
|
|
179
179
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
180
180
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
181
181
|
|
|
182
|
-
**
|
|
183
|
-
-
|
|
184
|
-
-
|
|
182
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
183
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
184
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
185
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
186
|
+
|
|
187
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
188
|
+
|
|
189
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
185
190
|
- Lưu `active_service` = `services.{domain}.path`
|
|
186
191
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
187
192
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
188
193
|
|
|
189
|
-
**
|
|
190
|
-
-
|
|
191
|
-
-
|
|
194
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
195
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
196
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
197
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
198
|
+
|
|
199
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
200
|
+
|
|
201
|
+
**3. Fallback**:
|
|
202
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
203
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
192
204
|
|
|
193
205
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
194
206
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -208,7 +220,7 @@ Nếu có section `services`:
|
|
|
208
220
|
|
|
209
221
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
210
222
|
|
|
211
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
223
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
212
224
|
|
|
213
225
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
214
226
|
|
|
@@ -384,7 +396,8 @@ Ticket : {ticket_prefix}-
|
|
|
384
396
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
385
397
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
386
398
|
Lessons : {loaded — N guardrails | chưa có}
|
|
387
|
-
|
|
399
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
400
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
388
401
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
389
402
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
390
403
|
```
|
|
@@ -179,16 +179,28 @@ Nếu có section `services`:
|
|
|
179
179
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
180
180
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
181
181
|
|
|
182
|
-
**
|
|
183
|
-
-
|
|
184
|
-
-
|
|
182
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
183
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
184
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
185
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
186
|
+
|
|
187
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
188
|
+
|
|
189
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
185
190
|
- Lưu `active_service` = `services.{domain}.path`
|
|
186
191
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
187
192
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
188
193
|
|
|
189
|
-
**
|
|
190
|
-
-
|
|
191
|
-
-
|
|
194
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
195
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
196
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
197
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
198
|
+
|
|
199
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
200
|
+
|
|
201
|
+
**3. Fallback**:
|
|
202
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
203
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
192
204
|
|
|
193
205
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
194
206
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -208,7 +220,7 @@ Nếu có section `services`:
|
|
|
208
220
|
|
|
209
221
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
210
222
|
|
|
211
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
223
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
212
224
|
|
|
213
225
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
214
226
|
|
|
@@ -384,7 +396,8 @@ Ticket : {ticket_prefix}-
|
|
|
384
396
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
385
397
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
386
398
|
Lessons : {loaded — N guardrails | chưa có}
|
|
387
|
-
|
|
399
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
400
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
388
401
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
389
402
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
390
403
|
```
|
|
@@ -184,16 +184,28 @@ Nếu có section `services`:
|
|
|
184
184
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
185
185
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
186
186
|
|
|
187
|
-
**
|
|
188
|
-
-
|
|
189
|
-
-
|
|
187
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
188
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
189
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
190
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
191
|
+
|
|
192
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
193
|
+
|
|
194
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
190
195
|
- Lưu `active_service` = `services.{domain}.path`
|
|
191
196
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
192
197
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
193
198
|
|
|
194
|
-
**
|
|
195
|
-
-
|
|
196
|
-
-
|
|
199
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
200
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
201
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
202
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
203
|
+
|
|
204
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
205
|
+
|
|
206
|
+
**3. Fallback**:
|
|
207
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
208
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
197
209
|
|
|
198
210
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
199
211
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -213,7 +225,7 @@ Nếu có section `services`:
|
|
|
213
225
|
|
|
214
226
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
215
227
|
|
|
216
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
228
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
217
229
|
|
|
218
230
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
219
231
|
|
|
@@ -389,7 +401,8 @@ Ticket : {ticket_prefix}-
|
|
|
389
401
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
390
402
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
391
403
|
Lessons : {loaded — N guardrails | chưa có}
|
|
392
|
-
|
|
404
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
405
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
393
406
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
394
407
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
395
408
|
```
|
|
@@ -191,16 +191,28 @@ Nếu có section `services`:
|
|
|
191
191
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
192
192
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
193
193
|
|
|
194
|
-
**
|
|
195
|
-
-
|
|
196
|
-
-
|
|
194
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
195
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
196
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
197
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
198
|
+
|
|
199
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
200
|
+
|
|
201
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
197
202
|
- Lưu `active_service` = `services.{domain}.path`
|
|
198
203
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
199
204
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
200
205
|
|
|
201
|
-
**
|
|
202
|
-
-
|
|
203
|
-
-
|
|
206
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
207
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
208
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
209
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
210
|
+
|
|
211
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
212
|
+
|
|
213
|
+
**3. Fallback**:
|
|
214
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
215
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
204
216
|
|
|
205
217
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
206
218
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -220,7 +232,7 @@ Nếu có section `services`:
|
|
|
220
232
|
|
|
221
233
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
222
234
|
|
|
223
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
235
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
224
236
|
|
|
225
237
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
226
238
|
|
|
@@ -396,7 +408,8 @@ Ticket : {ticket_prefix}-
|
|
|
396
408
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
397
409
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
398
410
|
Lessons : {loaded — N guardrails | chưa có}
|
|
399
|
-
|
|
411
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
412
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
400
413
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
401
414
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
402
415
|
```
|
package/core/commands/learn.md
CHANGED
|
@@ -188,16 +188,28 @@ Nếu có section `services`:
|
|
|
188
188
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
189
189
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
190
190
|
|
|
191
|
-
**
|
|
192
|
-
-
|
|
193
|
-
-
|
|
191
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
192
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
193
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
194
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
195
|
+
|
|
196
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
197
|
+
|
|
198
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
194
199
|
- Lưu `active_service` = `services.{domain}.path`
|
|
195
200
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
196
201
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
197
202
|
|
|
198
|
-
**
|
|
199
|
-
-
|
|
200
|
-
-
|
|
203
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
204
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
205
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
206
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
207
|
+
|
|
208
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
209
|
+
|
|
210
|
+
**3. Fallback**:
|
|
211
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
212
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
201
213
|
|
|
202
214
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
203
215
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -217,7 +229,7 @@ Nếu có section `services`:
|
|
|
217
229
|
|
|
218
230
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
219
231
|
|
|
220
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
232
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
221
233
|
|
|
222
234
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
223
235
|
|
|
@@ -393,7 +405,8 @@ Ticket : {ticket_prefix}-
|
|
|
393
405
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
394
406
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
395
407
|
Lessons : {loaded — N guardrails | chưa có}
|
|
396
|
-
|
|
408
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
409
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
397
410
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
398
411
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
399
412
|
```
|
|
@@ -189,16 +189,28 @@ Nếu có section `services`:
|
|
|
189
189
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
190
190
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
191
191
|
|
|
192
|
-
**
|
|
193
|
-
-
|
|
194
|
-
-
|
|
192
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
193
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
194
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
195
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
196
|
+
|
|
197
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
198
|
+
|
|
199
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
195
200
|
- Lưu `active_service` = `services.{domain}.path`
|
|
196
201
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
197
202
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
198
203
|
|
|
199
|
-
**
|
|
200
|
-
-
|
|
201
|
-
-
|
|
204
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
205
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
206
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
207
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
208
|
+
|
|
209
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
210
|
+
|
|
211
|
+
**3. Fallback**:
|
|
212
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
213
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
202
214
|
|
|
203
215
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
204
216
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -218,7 +230,7 @@ Nếu có section `services`:
|
|
|
218
230
|
|
|
219
231
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
220
232
|
|
|
221
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
233
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
222
234
|
|
|
223
235
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
224
236
|
|
|
@@ -394,7 +406,8 @@ Ticket : {ticket_prefix}-
|
|
|
394
406
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
395
407
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
396
408
|
Lessons : {loaded — N guardrails | chưa có}
|
|
397
|
-
|
|
409
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
410
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
398
411
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
399
412
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
400
413
|
```
|
|
@@ -189,16 +189,28 @@ Nếu có section `services`:
|
|
|
189
189
|
*(vd: `specs/user/create-account/USR01-create-account.md` **và** `specs/user/create-account/bdd/system/UC1.feature` đều → domain = `user`, prd_slug = `create-account`)*
|
|
190
190
|
- Nếu `$ARGUMENTS` chứa một path, trích xuất segment domain sau `specs_dir`
|
|
191
191
|
|
|
192
|
-
**
|
|
193
|
-
-
|
|
194
|
-
-
|
|
192
|
+
**1b. Phát hiện active platform** (chỉ cần khi service ở dạng map-theo-platform — bước 2b):
|
|
193
|
+
- Đọc `@trace.platform` từ header của target `.feature` (`system` | `web` | `app`) — Gate đã resolve target trước bước này.
|
|
194
|
+
- Nếu target không mang `@trace.platform` (vd target là PRD `.md`), thử suy từ segment `bdd/{platform}/` trong path target.
|
|
195
|
+
- Nếu vẫn không xác định được → `active_platform = null`.
|
|
196
|
+
|
|
197
|
+
**2. Route tới service** — nếu active domain khớp một key trong `services`. Giá trị `services.{domain}` có **hai dạng**; nhận dạng bằng việc có `path` trực tiếp hay không:
|
|
198
|
+
|
|
199
|
+
**2a. Dạng phẳng** — `services.{domain}` có **trực tiếp** `path`/`module` (một domain ↔ một service, mọi platform về cùng submodule). Route như cũ:
|
|
195
200
|
- Lưu `active_service` = `services.{domain}.path`
|
|
196
201
|
- Lưu `active_service_module` = `services.{domain}.module`
|
|
197
202
|
- Nếu service có `module` riêng → dùng nó làm `active_module` (override `tech_stack.module`)
|
|
198
203
|
|
|
199
|
-
**
|
|
200
|
-
-
|
|
201
|
-
-
|
|
204
|
+
**2b. Dạng map-theo-platform** — `services.{domain}` **KHÔNG** có `path` trực tiếp mà chứa các sub-key platform (`system` / `web` / `app`), mỗi cái là `{ path, module }` (một business-domain trải trên nhiều platform/submodule). Route theo `active_platform` (bước 1b):
|
|
205
|
+
- Nếu `active_platform` khớp một sub-key → `entry = services.{domain}.{active_platform}`; lưu `active_service = entry.path`, `active_service_module = entry.module` (→ `active_module`, override `tech_stack.module`).
|
|
206
|
+
- Nếu `active_platform = null` (chưa xác định platform, vd đang thao tác cấp PRD) → **KHÔNG** chốt một service; đặt `active_service = multi` và lưu `service_candidates = services.{domain}` (toàn map platform→{path,module}). Lệnh cần một service cụ thể (`/generate-code`, `/dev-*`, `/fix-bug`) luôn chạy trên target `.feature` có platform nên sẽ resolve được ở lần chạy đó; lệnh cấp PRD (`/generate-prd`, `/refine-prd`) không cần service cụ thể.
|
|
207
|
+
- Nếu `active_platform` xác định nhưng không có sub-key tương ứng → `active_service = unresolved` (xem Fallback) với lý do "domain `{domain}` chưa cấu hình platform `{active_platform}`".
|
|
208
|
+
|
|
209
|
+
*(Cả 2a/2b: override `paths.specs_dir`/`paths.tech_docs_dir` per-service CHỈ khi `setup.spec_source` KHÔNG được đặt. Khi `spec_source` ĐƯỢC đặt, MỌI BDD/tech-doc là artifact liên team → để bước 4 route sang spec repo; KHÔNG pin per-service ở đây.)*
|
|
210
|
+
|
|
211
|
+
**3. Fallback**:
|
|
212
|
+
- Không phát hiện được domain, hoặc domain không khớp key nào trong `services` → giữ path mặc định từ Bước 1, đặt `active_service = unresolved`.
|
|
213
|
+
- Domain khớp một map-theo-platform (2b) nhưng `active_platform` xác định mà thiếu sub-key tương ứng → `active_service = unresolved`, ghi lý do rõ để lệnh DỪNG báo lỗi cấu hình (không tự đoán platform).
|
|
202
214
|
|
|
203
215
|
**4. Tự động override theo spec source** — nếu `setup.spec_source` được đặt VÀ path tương ứng chưa được set tường minh trong `paths:`:
|
|
204
216
|
- Override `paths.specs_dir` → `{spec_source}/specs` — **luôn khi `spec_source` được đặt.** Mọi spec artifact (PRD, BDD, tech-docs, design-spec) nằm dưới gốc spec thống nhất trong spec repo dùng chung theo bố cục feature-package: `{spec_source}/specs/{domain}/{prd-slug}/`. Mọi umbrella (FE/App/BE) đều đọc từ đây. *(`specs/` theo service chỉ khi không có `spec_source`.)*
|
|
@@ -218,7 +230,7 @@ Nếu có section `services`:
|
|
|
218
230
|
|
|
219
231
|
## Bước 1.6 — [SERVICE CONVENTIONS] Nạp convention riêng của service (chế độ umbrella)
|
|
220
232
|
|
|
221
|
-
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc context ở chế độ single-service.*
|
|
233
|
+
*Bỏ qua hoàn toàn bước này nếu `active_service` là `"unresolved"` hoặc `"multi"` (chưa chốt một service — dạng map-theo-platform ở cấp PRD) hoặc context ở chế độ single-service.*
|
|
222
234
|
|
|
223
235
|
Khi `active_service` đã được phân giải thành một path thật ở Bước 1.5 (vd: `user-service/`):
|
|
224
236
|
|
|
@@ -394,7 +406,8 @@ Ticket : {ticket_prefix}-
|
|
|
394
406
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
395
407
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
396
408
|
Lessons : {loaded — N guardrails | chưa có}
|
|
397
|
-
|
|
409
|
+
Platform : {active_platform: system | web | app | — nếu chưa xác định}
|
|
410
|
+
Service : {active_service} ({active_service_module}) | multi (map-theo-platform, chốt khi target có platform) | single-service
|
|
398
411
|
Svc Root : {service_root} — đã nạp conventions + trace_dir từ config service | —
|
|
399
412
|
Status : {FULL | PARTIAL — thiếu: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
400
413
|
```
|