@anhth2/spec-driven-dev-plugin 0.9.1 → 0.10.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/ARCHITECTURE.md +20 -9
- package/bin/index.js +1 -2
- package/commands/debug.md +13 -12
- package/commands/define-product.md +12 -11
- package/commands/{generate-tests.md → dev-gen-test.md} +48 -15
- package/commands/{generate-tests.tmpl → dev-gen-test.tmpl} +18 -4
- package/{core/commands/run-tests.md → commands/dev-run-test.md} +62 -13
- package/commands/{run-tests.tmpl → dev-run-test.tmpl} +32 -2
- package/{core/commands/smoke-test.md → commands/dev-smoke-test.md} +17 -16
- package/commands/{smoke-test.tmpl → dev-smoke-test.tmpl} +5 -5
- package/commands/fix-bug.md +13 -12
- package/commands/generate-bdd.md +39 -13
- package/commands/generate-bdd.tmpl +9 -2
- package/commands/generate-code.md +86 -15
- package/commands/generate-code.tmpl +56 -4
- package/commands/generate-design-spec.md +105 -39
- package/commands/generate-design-spec.tmpl +93 -28
- package/commands/generate-prd.md +12 -11
- package/commands/generate-spec-manifest.md +12 -11
- package/commands/generate-tech-docs.md +63 -22
- package/commands/generate-tech-docs.tmpl +51 -11
- package/commands/learn.md +13 -12
- package/commands/propose-scenario.md +13 -12
- package/commands/propose-scenario.tmpl +1 -1
- package/commands/refine-prd.md +166 -16
- package/commands/refine-prd.tmpl +16 -5
- package/commands/report-bug.md +12 -11
- package/commands/review-code.md +14 -13
- package/commands/review-code.tmpl +1 -1
- package/commands/review-context.md +161 -12
- package/commands/review-context.tmpl +11 -1
- package/commands/review-tech-docs.md +13 -11
- package/commands/review-tech-docs.tmpl +1 -0
- package/commands/setup-ai-first.md +7 -7
- package/commands/sync.md +23 -20
- package/commands/sync.tmpl +16 -13
- package/commands/update-framework.md +7 -7
- package/commands/validate-traces.md +57 -37
- package/commands/validate-traces.tmpl +45 -26
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/debug.md +13 -12
- package/core/commands/define-product.md +12 -11
- package/core/commands/{generate-tests.md → dev-gen-test.md} +48 -15
- package/{commands/run-tests.md → core/commands/dev-run-test.md} +62 -13
- package/{commands/smoke-test.md → core/commands/dev-smoke-test.md} +17 -16
- package/core/commands/fix-bug.md +13 -12
- package/core/commands/generate-bdd.md +39 -13
- package/core/commands/generate-code.md +86 -15
- package/core/commands/generate-design-spec.md +105 -39
- package/core/commands/generate-prd.md +12 -11
- package/core/commands/generate-spec-manifest.md +12 -11
- package/core/commands/generate-tech-docs.md +63 -22
- package/core/commands/learn.md +13 -12
- package/core/commands/propose-scenario.md +13 -12
- package/core/commands/refine-prd.md +166 -16
- package/core/commands/report-bug.md +12 -11
- package/core/commands/review-code.md +14 -13
- package/core/commands/review-context.md +161 -12
- package/core/commands/review-tech-docs.md +13 -11
- package/core/commands/setup-ai-first.md +7 -7
- package/core/commands/sync.md +23 -20
- package/core/commands/update-framework.md +7 -7
- package/core/commands/validate-traces.md +57 -37
- package/core/modules/android-compose/module.yaml +13 -0
- package/core/modules/android-compose/stack-profile.yaml +57 -0
- package/core/modules/flutter/module.yaml +14 -0
- package/core/modules/flutter/stack-profile.yaml +59 -0
- package/core/modules/ios-swiftui/module.yaml +13 -0
- package/core/modules/ios-swiftui/stack-profile.yaml +55 -0
- package/core/modules/nuxt/module.yaml +14 -0
- package/core/modules/nuxt/stack-profile.yaml +58 -0
- package/core/modules/react-native/module.yaml +14 -0
- package/core/modules/react-native/stack-profile.yaml +56 -0
- package/core/modules/vue/module.yaml +14 -0
- package/core/modules/vue/stack-profile.yaml +65 -0
- package/core/skills/code/SKILL.md +19 -18
- package/core/skills/debug/SKILL.md +27 -26
- package/core/skills/design-spec/SKILL.md +12 -11
- package/core/skills/discovery/SKILL.md +12 -11
- package/core/skills/prd/SKILL.md +14 -14
- package/core/skills/setup-ai-first/SKILL.md +7 -7
- package/core/skills/spec/SKILL.md +14 -14
- package/core/skills/test/SKILL.md +40 -38
- package/core/steps/capture-lesson.md +1 -1
- package/core/steps/context-loader.md +5 -4
- package/core/steps/report-footer.md +7 -7
- package/core/steps/review-fanout.md +138 -0
- package/core/steps/spawn-agent.md +1 -1
- package/core/steps/trace-mirror.md +18 -0
- package/core/templates/design-spec.template.md +16 -8
- package/core/templates/product-definition.template.md +3 -3
- package/core/templates/project-context.yaml +4 -1
- package/modules/android-compose/module.yaml +13 -0
- package/modules/android-compose/stack-profile.yaml +57 -0
- package/modules/flutter/module.yaml +14 -0
- package/modules/flutter/stack-profile.yaml +59 -0
- package/modules/ios-swiftui/module.yaml +13 -0
- package/modules/ios-swiftui/stack-profile.yaml +55 -0
- package/modules/nuxt/module.yaml +14 -0
- package/modules/nuxt/stack-profile.yaml +58 -0
- package/modules/react-native/module.yaml +14 -0
- package/modules/react-native/stack-profile.yaml +56 -0
- package/modules/vue/module.yaml +14 -0
- package/modules/vue/stack-profile.yaml +65 -0
- package/package.json +1 -1
- package/skills/code/SKILL.md +19 -18
- package/skills/debug/SKILL.md +27 -26
- package/skills/debug/SKILL.tmpl +1 -1
- package/skills/design-spec/SKILL.md +12 -11
- package/skills/discovery/SKILL.md +12 -11
- package/skills/prd/SKILL.md +14 -14
- package/skills/setup-ai-first/SKILL.md +7 -7
- package/skills/spec/SKILL.md +14 -14
- package/skills/test/SKILL.md +40 -38
- package/skills/test/SKILL.tmpl +9 -9
- package/steps/capture-lesson.md +1 -1
- package/steps/context-loader.md +5 -4
- package/steps/report-footer.md +7 -7
- package/steps/review-fanout.md +138 -0
- package/steps/spawn-agent.md +1 -1
- package/steps/trace-mirror.md +18 -0
- package/templates/design-spec.template.md +16 -8
- package/templates/product-definition.template.md +3 -3
- package/templates/project-context.yaml +4 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Generates unit and integration tests from BDD specs, runs the test suite and reports results, or smoke-tests live API endpoints on a running service. Trigger when: "/
|
|
2
|
+
description: Generates unit and integration tests from BDD specs, runs the test suite and reports results, or dev-smoke-tests live API endpoints on a running service. Trigger when: "/dev-gen-test", "/dev-run-test", "/dev-smoke-test", "tạo test", "viết test", "chạy test", "generate tests", "run tests", "test kết quả", "smoke test", "test API", "kiểm tra endpoint đang chạy".
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Test Skills — Generate, Run & Smoke Test
|
|
6
6
|
|
|
7
|
-
This skill handles three commands: `/
|
|
7
|
+
This skill handles three commands: `/dev-gen-test`, `/dev-run-test`, and `/dev-smoke-test`.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
## /
|
|
11
|
+
## /dev-gen-test — Generate Unit & Integration Tests
|
|
12
12
|
|
|
13
13
|
### Gate
|
|
14
14
|
|
|
@@ -212,7 +212,7 @@ src/test/{language}/{package}/
|
|
|
212
212
|
### Output
|
|
213
213
|
|
|
214
214
|
```
|
|
215
|
-
/
|
|
215
|
+
/dev-gen-test Complete — {UC-ID}:
|
|
216
216
|
✅ service/{Service}Test.{ext} ({M} tests)
|
|
217
217
|
✅ facade/{Facade}Test.{ext} ({M} tests)
|
|
218
218
|
✅ controller/{Controller}Test.{ext} ({M} tests)
|
|
@@ -256,13 +256,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
256
256
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
257
257
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
258
258
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
259
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
260
|
-
| /
|
|
261
|
-
| /run-
|
|
262
|
-
| /run-
|
|
263
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
264
|
-
| /smoke-test | Create PR and link to ticket |
|
|
265
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
259
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
260
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
261
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
262
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
263
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
264
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
265
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
266
266
|
| /fix-bug | Create PR and link to ticket |
|
|
267
267
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
268
268
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
@@ -282,7 +282,7 @@ Next : {suggested command with example arguments}
|
|
|
282
282
|
|
|
283
283
|
---
|
|
284
284
|
|
|
285
|
-
## /run-
|
|
285
|
+
## /dev-run-test — Run Tests & Report Results
|
|
286
286
|
|
|
287
287
|
### Gate
|
|
288
288
|
|
|
@@ -362,7 +362,7 @@ If `services` section is present:
|
|
|
362
362
|
|
|
363
363
|
**2. Route to service** — if active domain matches a key in `services`:
|
|
364
364
|
- Override `paths.specs_dir` → `services.{domain}.specs_dir`
|
|
365
|
-
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
|
|
365
|
+
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir` — **only if `setup.spec_source` is NOT set.** When `spec_source` IS set, the tech-design (API contract) is a cross-team artifact and must live in the shared spec repo (handled in step 4), so leave `tech_docs_dir` for step 4 to route — do NOT pin it per-service here.
|
|
366
366
|
- Store `active_service` = `services.{domain}.path`
|
|
367
367
|
- Store `active_service_module` = `services.{domain}.module`
|
|
368
368
|
- If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
|
|
@@ -374,13 +374,14 @@ If `services` section is present:
|
|
|
374
374
|
**4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
|
|
375
375
|
- Override `paths.prd_dir` → `{spec_source}/specs/prd`
|
|
376
376
|
- Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
|
|
377
|
+
- Override `paths.tech_docs_dir` → `{spec_source}/specs/tech-docs` — **always when `spec_source` is set** (step 2 no longer pins tech-docs per-service in this case). The tech-design IS the cross-team API contract: BE authors it here, and FE/App read it from the same spec submodule at `/generate-code --phase=integration`. *(Per-service tech-docs only happen when there is no `spec_source` — a pure multi-service BE repo with no shared spec module.)*
|
|
377
378
|
- Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
|
|
378
379
|
- Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
|
|
379
380
|
- Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
|
|
380
381
|
- Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
|
|
381
382
|
- Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
|
|
382
383
|
|
|
383
|
-
> **Why under `spec_source`:**
|
|
384
|
+
> **Why under `spec_source`:** PRD, design-spec, domain knowledge, the **API contract (tech-docs)**, and tester feedback are all **cross-team artifacts** — they must live in the **shared spec repo** so every umbrella (FE/App/BE) reads the same source via `/sync`. Tech-docs specifically: BE authors the tech-design (API contract), commits + pushes it into the spec submodule (2-layer commit), and FE/App pull it on their next `/sync` to wire the real API in `/generate-code --phase=integration`. In single-service mode (no `spec_source`), these default under the repo root — still shared, same repo.
|
|
384
385
|
|
|
385
386
|
---
|
|
386
387
|
|
|
@@ -404,7 +405,7 @@ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-
|
|
|
404
405
|
| `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
|
|
405
406
|
|
|
406
407
|
**3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
|
|
407
|
-
- Shell commands (`/run-
|
|
408
|
+
- Shell commands (`/dev-run-test`, `/dev-gen-test`) run **from within** `service_root`
|
|
408
409
|
- File write operations (test files, trace TSVs) use paths **relative to** `service_root`
|
|
409
410
|
|
|
410
411
|
**4. If service config not found** — keep umbrella defaults, still set `service_root = {active_service}` (path anchor is always needed even without a config override).
|
|
@@ -497,7 +498,7 @@ active_module = tech_stack.module (e.g. "java-spring", "react", "flutter")
|
|
|
497
498
|
|
|
498
499
|
If `tech_stack.module` is blank or not recognized → set `platform_type = "unknown"` and flag as ⚠️ in the Step 7 recap.
|
|
499
500
|
|
|
500
|
-
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (
|
|
501
|
+
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (dev-gen-test, debug, fix-bug, dev-smoke-test).
|
|
501
502
|
|
|
502
503
|
---
|
|
503
504
|
|
|
@@ -602,7 +603,7 @@ Read stack trace and analyze:
|
|
|
602
603
|
### Output
|
|
603
604
|
|
|
604
605
|
```
|
|
605
|
-
/run-
|
|
606
|
+
/dev-run-test Report — {service}
|
|
606
607
|
Run at: {datetime}
|
|
607
608
|
|
|
608
609
|
## Summary
|
|
@@ -656,13 +657,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
656
657
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
657
658
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
658
659
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
659
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
660
|
-
| /
|
|
661
|
-
| /run-
|
|
662
|
-
| /run-
|
|
663
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
664
|
-
| /smoke-test | Create PR and link to ticket |
|
|
665
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
660
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
661
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
662
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
663
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
664
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
665
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
666
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
666
667
|
| /fix-bug | Create PR and link to ticket |
|
|
667
668
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
668
669
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
@@ -682,10 +683,10 @@ Next : {suggested command with example arguments}
|
|
|
682
683
|
|
|
683
684
|
---
|
|
684
685
|
|
|
685
|
-
## /smoke-test — Test Live API Endpoints
|
|
686
|
+
## /dev-smoke-test — Test Live API Endpoints
|
|
686
687
|
|
|
687
688
|
Use when the service is **already running** to verify endpoints work correctly.
|
|
688
|
-
Different from `/run-
|
|
689
|
+
Different from `/dev-run-test` (which runs unit/integration tests without a live server).
|
|
689
690
|
|
|
690
691
|
### Phase 1 — Find Service URL
|
|
691
692
|
|
|
@@ -765,7 +766,7 @@ If `services` section is present:
|
|
|
765
766
|
|
|
766
767
|
**2. Route to service** — if active domain matches a key in `services`:
|
|
767
768
|
- Override `paths.specs_dir` → `services.{domain}.specs_dir`
|
|
768
|
-
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
|
|
769
|
+
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir` — **only if `setup.spec_source` is NOT set.** When `spec_source` IS set, the tech-design (API contract) is a cross-team artifact and must live in the shared spec repo (handled in step 4), so leave `tech_docs_dir` for step 4 to route — do NOT pin it per-service here.
|
|
769
770
|
- Store `active_service` = `services.{domain}.path`
|
|
770
771
|
- Store `active_service_module` = `services.{domain}.module`
|
|
771
772
|
- If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
|
|
@@ -777,13 +778,14 @@ If `services` section is present:
|
|
|
777
778
|
**4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
|
|
778
779
|
- Override `paths.prd_dir` → `{spec_source}/specs/prd`
|
|
779
780
|
- Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
|
|
781
|
+
- Override `paths.tech_docs_dir` → `{spec_source}/specs/tech-docs` — **always when `spec_source` is set** (step 2 no longer pins tech-docs per-service in this case). The tech-design IS the cross-team API contract: BE authors it here, and FE/App read it from the same spec submodule at `/generate-code --phase=integration`. *(Per-service tech-docs only happen when there is no `spec_source` — a pure multi-service BE repo with no shared spec module.)*
|
|
780
782
|
- Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
|
|
781
783
|
- Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
|
|
782
784
|
- Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
|
|
783
785
|
- Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
|
|
784
786
|
- Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
|
|
785
787
|
|
|
786
|
-
> **Why under `spec_source`:**
|
|
788
|
+
> **Why under `spec_source`:** PRD, design-spec, domain knowledge, the **API contract (tech-docs)**, and tester feedback are all **cross-team artifacts** — they must live in the **shared spec repo** so every umbrella (FE/App/BE) reads the same source via `/sync`. Tech-docs specifically: BE authors the tech-design (API contract), commits + pushes it into the spec submodule (2-layer commit), and FE/App pull it on their next `/sync` to wire the real API in `/generate-code --phase=integration`. In single-service mode (no `spec_source`), these default under the repo root — still shared, same repo.
|
|
787
789
|
|
|
788
790
|
---
|
|
789
791
|
|
|
@@ -807,7 +809,7 @@ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-
|
|
|
807
809
|
| `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
|
|
808
810
|
|
|
809
811
|
**3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
|
|
810
|
-
- Shell commands (`/run-
|
|
812
|
+
- Shell commands (`/dev-run-test`, `/dev-gen-test`) run **from within** `service_root`
|
|
811
813
|
- File write operations (test files, trace TSVs) use paths **relative to** `service_root`
|
|
812
814
|
|
|
813
815
|
**4. If service config not found** — keep umbrella defaults, still set `service_root = {active_service}` (path anchor is always needed even without a config override).
|
|
@@ -900,7 +902,7 @@ active_module = tech_stack.module (e.g. "java-spring", "react", "flutter")
|
|
|
900
902
|
|
|
901
903
|
If `tech_stack.module` is blank or not recognized → set `platform_type = "unknown"` and flag as ⚠️ in the Step 7 recap.
|
|
902
904
|
|
|
903
|
-
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (
|
|
905
|
+
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (dev-gen-test, debug, fix-bug, dev-smoke-test).
|
|
904
906
|
|
|
905
907
|
---
|
|
906
908
|
|
|
@@ -1022,7 +1024,7 @@ tail -n 100 {LOG_FILE_PATH}
|
|
|
1022
1024
|
### Output
|
|
1023
1025
|
|
|
1024
1026
|
```
|
|
1025
|
-
/smoke-test Report — {UC-ID}
|
|
1027
|
+
/dev-smoke-test Report — {UC-ID}
|
|
1026
1028
|
Tested at: {datetime}
|
|
1027
1029
|
Base URL: http://localhost:{port}
|
|
1028
1030
|
|
|
@@ -1074,13 +1076,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
1074
1076
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
1075
1077
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
1076
1078
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
1077
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
1078
|
-
| /
|
|
1079
|
-
| /run-
|
|
1080
|
-
| /run-
|
|
1081
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
1082
|
-
| /smoke-test | Create PR and link to ticket |
|
|
1083
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
1079
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
1080
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
1081
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
1082
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
1083
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
1084
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
1085
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
1084
1086
|
| /fix-bug | Create PR and link to ticket |
|
|
1085
1087
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
1086
1088
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
@@ -54,7 +54,7 @@ If `lessons_path` does not exist, create it with this header first:
|
|
|
54
54
|
| code-gen | /generate-code output |
|
|
55
55
|
| bdd | /generate-bdd output |
|
|
56
56
|
| tech-docs | /generate-tech-docs output |
|
|
57
|
-
| tests | /
|
|
57
|
+
| tests | /dev-gen-test output |
|
|
58
58
|
| prd | /generate-prd, /refine-prd output |
|
|
59
59
|
| general | every command |
|
|
60
60
|
|
|
@@ -74,7 +74,7 @@ If `services` section is present:
|
|
|
74
74
|
|
|
75
75
|
**2. Route to service** — if active domain matches a key in `services`:
|
|
76
76
|
- Override `paths.specs_dir` → `services.{domain}.specs_dir`
|
|
77
|
-
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
|
|
77
|
+
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir` — **only if `setup.spec_source` is NOT set.** When `spec_source` IS set, the tech-design (API contract) is a cross-team artifact and must live in the shared spec repo (handled in step 4), so leave `tech_docs_dir` for step 4 to route — do NOT pin it per-service here.
|
|
78
78
|
- Store `active_service` = `services.{domain}.path`
|
|
79
79
|
- Store `active_service_module` = `services.{domain}.module`
|
|
80
80
|
- If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
|
|
@@ -86,13 +86,14 @@ If `services` section is present:
|
|
|
86
86
|
**4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
|
|
87
87
|
- Override `paths.prd_dir` → `{spec_source}/specs/prd`
|
|
88
88
|
- Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
|
|
89
|
+
- Override `paths.tech_docs_dir` → `{spec_source}/specs/tech-docs` — **always when `spec_source` is set** (step 2 no longer pins tech-docs per-service in this case). The tech-design IS the cross-team API contract: BE authors it here, and FE/App read it from the same spec submodule at `/generate-code --phase=integration`. *(Per-service tech-docs only happen when there is no `spec_source` — a pure multi-service BE repo with no shared spec module.)*
|
|
89
90
|
- Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
|
|
90
91
|
- Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
|
|
91
92
|
- Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
|
|
92
93
|
- Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
|
|
93
94
|
- Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
|
|
94
95
|
|
|
95
|
-
> **Why under `spec_source`:**
|
|
96
|
+
> **Why under `spec_source`:** PRD, design-spec, domain knowledge, the **API contract (tech-docs)**, and tester feedback are all **cross-team artifacts** — they must live in the **shared spec repo** so every umbrella (FE/App/BE) reads the same source via `/sync`. Tech-docs specifically: BE authors the tech-design (API contract), commits + pushes it into the spec submodule (2-layer commit), and FE/App pull it on their next `/sync` to wire the real API in `/generate-code --phase=integration`. In single-service mode (no `spec_source`), these default under the repo root — still shared, same repo.
|
|
96
97
|
|
|
97
98
|
---
|
|
98
99
|
|
|
@@ -116,7 +117,7 @@ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-
|
|
|
116
117
|
| `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
|
|
117
118
|
|
|
118
119
|
**3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
|
|
119
|
-
- Shell commands (`/run-
|
|
120
|
+
- Shell commands (`/dev-run-test`, `/dev-gen-test`) run **from within** `service_root`
|
|
120
121
|
- File write operations (test files, trace TSVs) use paths **relative to** `service_root`
|
|
121
122
|
|
|
122
123
|
**4. If service config not found** — keep umbrella defaults, still set `service_root = {active_service}` (path anchor is always needed even without a config override).
|
|
@@ -209,7 +210,7 @@ active_module = tech_stack.module (e.g. "java-spring", "react", "flutter")
|
|
|
209
210
|
|
|
210
211
|
If `tech_stack.module` is blank or not recognized → set `platform_type = "unknown"` and flag as ⚠️ in the Step 7 recap.
|
|
211
212
|
|
|
212
|
-
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (
|
|
213
|
+
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (dev-gen-test, debug, fix-bug, dev-smoke-test).
|
|
213
214
|
|
|
214
215
|
---
|
|
215
216
|
|
|
@@ -36,13 +36,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
36
36
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
37
37
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
38
38
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
39
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
40
|
-
| /
|
|
41
|
-
| /run-
|
|
42
|
-
| /run-
|
|
43
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
44
|
-
| /smoke-test | Create PR and link to ticket |
|
|
45
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
39
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
40
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
41
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
42
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
43
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
44
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
45
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
46
46
|
| /fix-bug | Create PR and link to ticket |
|
|
47
47
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
48
48
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Exhaustive Review Fan-Out + Completeness Convergence
|
|
2
|
+
|
|
3
|
+
**Why this exists:** A single-pass review never lists every issue at once — the model
|
|
4
|
+
stops at "enough" findings, so each later review round surfaces *new* problems
|
|
5
|
+
(whack-a-mole). This procedure forces the review to **converge in one command run**:
|
|
6
|
+
fan out across review dimensions in parallel, then loop a completeness critic until a
|
|
7
|
+
round produces nothing new, *before* writing the findings file.
|
|
8
|
+
|
|
9
|
+
The calling command supplies two things:
|
|
10
|
+
- **DIMENSIONS** — the list of review dimensions to fan out over
|
|
11
|
+
(`/refine-prd` → the 4 lenses; `/review-context` → the P-checks or B-checks).
|
|
12
|
+
- **FINDINGS SCHEMA** — the YAML shape each finding must follow (defined in the command).
|
|
13
|
+
|
|
14
|
+
> **Sub-agent mode bypass:** If Gate Step 0 set `_agent_mode: true`, this whole
|
|
15
|
+
> procedure is **skipped** — the orchestrator is already running one dimension/UC per
|
|
16
|
+
> sub-agent. Run the command's checks directly on the scoped section and return findings.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Phase 1 — Parallel dimension scan
|
|
21
|
+
|
|
22
|
+
**How many sub-agents:** the agent *count* is not the completeness lever — breadth is
|
|
23
|
+
fixed by the DIMENSION taxonomy (adding agents to the same dimension just re-finds the
|
|
24
|
+
same issues), and *depth* is owned by the Phase 2 critic loop. Pick the **fan-out
|
|
25
|
+
granularity** by target size, reusing the `steps/spawn-agent.md` thresholds:
|
|
26
|
+
|
|
27
|
+
| Target size | Granularity | Agent count |
|
|
28
|
+
|-------------|-------------|-------------|
|
|
29
|
+
| ≤ 3 UCs **and** ≤ 300 lines | one agent per DIMENSION over the whole file | = number of dimensions |
|
|
30
|
+
| > 3 UCs **or** > 300 lines | one agent per **DIMENSION × UC-scope** (UCs + a PRD-global scope), batched to fit the agent cap | `dimensions × (UCs + 1)`, capped (see below) |
|
|
31
|
+
|
|
32
|
+
The larger granularity keeps each sub-agent's context small and its scan exhaustive on a
|
|
33
|
+
single UC — which is what prevents misses on big PRDs.
|
|
34
|
+
|
|
35
|
+
> **Global (non-UC) sections — required in `DIMENSION × UC` mode.** Per-UC agents only
|
|
36
|
+
> see one UC each, so PRD-wide sections that belong to no UC (scope, success metrics,
|
|
37
|
+
> problem statement, terminology, glossary, changelog) would go unscanned. Whenever you
|
|
38
|
+
> fan out per UC, also include a **"PRD-global"** scope (the non-UC sections, findings get
|
|
39
|
+
> `uc_id: ""`) alongside the UC list. So the natural agent count is `dimensions × (UCs + 1)`.
|
|
40
|
+
> (Not needed in the whole-file mode — there each agent already sees the global sections.)
|
|
41
|
+
|
|
42
|
+
### Agent cap — batch UCs when the fan-out gets too wide
|
|
43
|
+
|
|
44
|
+
`dimensions × (UCs + 1)` can explode on large PRDs (e.g. 6 checks × (8 UCs + 1) = 54
|
|
45
|
+
agents). Cap the wave at **`AGENT_CAP = 12`** agents and batch UC scopes to fit:
|
|
46
|
+
|
|
47
|
+
1. Build the scope list = `[UC1, UC2, …, UCn, PRD-global]` (length `UCs + 1`).
|
|
48
|
+
2. Compute scopes-per-agent-bucket: `groups = max(1, floor(AGENT_CAP / dimensions))`.
|
|
49
|
+
- If `groups ≥ UCs + 1` → no batching needed, run one agent per `DIMENSION × scope`.
|
|
50
|
+
- Else split the scope list into `groups` contiguous buckets of roughly equal size
|
|
51
|
+
(keep `PRD-global` in its own bucket if it fits; otherwise append it to the last
|
|
52
|
+
bucket). Each agent then handles **one DIMENSION over one bucket of UCs**.
|
|
53
|
+
3. Resulting wave size = `dimensions × groups ≤ AGENT_CAP`.
|
|
54
|
+
|
|
55
|
+
A batched agent reviews several UCs at once — still scoped far tighter than the whole
|
|
56
|
+
file, so coverage stays high. `AGENT_CAP` is the only knob; raise it if the host allows
|
|
57
|
+
more concurrency, lower it to save tokens. Whole-file mode (≤ 3 UCs) never hits the cap.
|
|
58
|
+
|
|
59
|
+
Spawn the chosen sub-agents using the Agent tool (send them in a single message so they
|
|
60
|
+
run concurrently). Each sub-agent gets a **fresh context window** and scans its scope
|
|
61
|
+
through its **one** dimension only — deeper coverage than one session juggling every
|
|
62
|
+
dimension at once (avoids lost-in-the-middle).
|
|
63
|
+
|
|
64
|
+
Sub-agent prompt template (fill the braces):
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
You are a {DIMENSION_NAME} reviewer. Read the full target file at {target_file}.
|
|
68
|
+
Scope: review ONLY through the {DIMENSION_NAME} lens/check — {DIMENSION_DESCRIPTION}.
|
|
69
|
+
Be exhaustive: scan every section, every UC, every AC/BR/scenario. Do not stop early.
|
|
70
|
+
Project context (terminology, entities, architecture):
|
|
71
|
+
{slim_context — banned terms, canonical entities, layer order, domains}
|
|
72
|
+
|
|
73
|
+
Return a JSON array of findings, each:
|
|
74
|
+
{ "dimension": "{DIMENSION_NAME}", "severity": "critical|major|minor",
|
|
75
|
+
"section": "...", "uc_id": "...", "quote": "<verbatim ≤120 chars>",
|
|
76
|
+
"finding": "...", "suggestion": "...", "auto_fixable": true|false }
|
|
77
|
+
Return [] if this dimension is clean. Return ONLY the JSON array.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Collect every sub-agent's array into one consolidated list `ALL_FINDINGS`.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Phase 2 — Completeness-critic convergence loop
|
|
85
|
+
|
|
86
|
+
This is the anti-whack-a-mole step. Repeat until **two consecutive rounds add zero new
|
|
87
|
+
findings**, or a hard cap of **3 rounds**, whichever comes first:
|
|
88
|
+
|
|
89
|
+
1. Spawn one **completeness-critic** sub-agent with the Agent tool. Give it:
|
|
90
|
+
- the full target file (`{target_file}`),
|
|
91
|
+
- the current `ALL_FINDINGS` list (so it knows what is already captured),
|
|
92
|
+
- the same slim context.
|
|
93
|
+
Prompt it:
|
|
94
|
+
```
|
|
95
|
+
Here is a document and a list of issues already found. Read the WHOLE document.
|
|
96
|
+
List ONLY real, additional issues NOT already in the list — gaps, ambiguities,
|
|
97
|
+
contradictions, missing edge/negative paths, coverage holes, terminology drift,
|
|
98
|
+
structural omissions, and any issue that a fix to an existing finding would expose.
|
|
99
|
+
Do NOT repeat anything already listed. Return the same finding JSON shape, or [] if
|
|
100
|
+
nothing new.
|
|
101
|
+
```
|
|
102
|
+
2. Append any genuinely new findings (not already in `ALL_FINDINGS`) to the list.
|
|
103
|
+
3. If this round returned 0 new → increment the dry-round counter; else reset it to 0.
|
|
104
|
+
4. Stop when dry-round counter reaches 2, or after 3 rounds total.
|
|
105
|
+
|
|
106
|
+
Record `convergence_rounds` (how many critic rounds ran) for the report.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Phase 3 — Dedup, resolve conflicts, merge
|
|
111
|
+
|
|
112
|
+
Sub-agents run **blind to each other** (independence = diverse coverage). They never
|
|
113
|
+
talk or reconcile among themselves — all duplicate/conflict resolution happens **here in
|
|
114
|
+
the orchestrator**, where the full set is visible.
|
|
115
|
+
|
|
116
|
+
1. **Deduplicate** `ALL_FINDINGS`: two findings are duplicates if they target the same
|
|
117
|
+
`section` + `uc_id` and describe the same underlying issue. Keep the one with the
|
|
118
|
+
richer `suggestion`; if they differ on severity, keep the **higher** severity.
|
|
119
|
+
2. **Resolve conflicts** — group remaining findings by `section` + `uc_id` and check for
|
|
120
|
+
contradictions (two findings whose `suggestion`s cannot both be applied, or that
|
|
121
|
+
propose opposite fixes for the same spot):
|
|
122
|
+
- If the two suggestions can be **merged** into one coherent fix → merge them into a
|
|
123
|
+
single finding.
|
|
124
|
+
- If they are **mutually exclusive** → emit **one** finding that states both options
|
|
125
|
+
and set `auto_fixable: false` with `status: "needs_discussion"` (PRD) /
|
|
126
|
+
`status: "pending"` (review) so a human picks — never silently drop one side.
|
|
127
|
+
- If a finding is **invalidated** by another (e.g. a structural finding says a section
|
|
128
|
+
is missing, but another quotes content from it) → drop the invalid one.
|
|
129
|
+
3. **Sort** by severity (critical → major → minor), then by `section` order in the file.
|
|
130
|
+
4. **Assign stable IDs** `F001, F002, …` in that sorted order.
|
|
131
|
+
5. Map each finding's `dimension` into the command's schema field
|
|
132
|
+
(`lens` for `/refine-prd`; `check_id` for `/review-context`).
|
|
133
|
+
6. Write the **single** findings file in the FINDINGS SCHEMA the command defines.
|
|
134
|
+
|
|
135
|
+
In the command's final report, add one line:
|
|
136
|
+
```
|
|
137
|
+
Convergence: {convergence_rounds} critic round(s) — findings file is complete; re-running should surface 0 new issues.
|
|
138
|
+
```
|
|
@@ -80,7 +80,7 @@ Build payload and invoke Agent tool for each UC:
|
|
|
80
80
|
}
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
> **Command scope**: Only `/generate-bdd` initiates orchestration mode. `/generate-code` and `/
|
|
83
|
+
> **Command scope**: Only `/generate-bdd` initiates orchestration mode. `/generate-code` and `/dev-gen-test` can run as sub-agents (they respect `_agent_mode: true` from Gate Step 0), but they do not spawn further sub-agents — their scope is already a single UC.
|
|
84
84
|
|
|
85
85
|
Serialize this JSON and pass as `$ARGUMENTS` when invoking the sub-agent command.
|
|
86
86
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Refresh Living Docs panel mirror *(local, umbrella mode)*
|
|
2
|
+
|
|
3
|
+
*Skip entirely in single-service mode (no `services` and no `setup.spec_source`) — there
|
|
4
|
+
the service `.trace/` IS the panel location, so nothing to mirror.*
|
|
5
|
+
|
|
6
|
+
After updating the authoritative service TSV(s) at `{paths.trace_dir}`:
|
|
7
|
+
|
|
8
|
+
1. Resolve `panel_mirror = ./.trace` at the **current workspace root** (where this command runs).
|
|
9
|
+
2. If `panel_mirror` resolves to a different path than `{paths.trace_dir}`, copy each
|
|
10
|
+
just-updated `{UC-ID}.tsv` → `{panel_mirror}/{service-name}/{UC-ID}.tsv`
|
|
11
|
+
(create the dir; overwrite). Use `active_service` for `{service-name}`.
|
|
12
|
+
|
|
13
|
+
This keeps the open workspace's Living Docs panel current **between syncs** — it is a
|
|
14
|
+
**local convenience mirror only**. The *canonical* report in the spec module
|
|
15
|
+
(`{spec_source}/.living-docs/`) and the merged `trace-report.json` are rebuilt by
|
|
16
|
+
`/sync` or `/validate-traces` (those need every service's data, so a single per-UC
|
|
17
|
+
command cannot produce them). For orchestrated commands, do this once in the orchestrator
|
|
18
|
+
after all sub-agents return — not inside each sub-agent.
|
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
- ⚠️ TODO → đánh dấu [TODO — chưa implement]
|
|
15
15
|
- ❌ Chưa có → đánh dấu [NEW — cần confirm với designer]
|
|
16
16
|
|
|
17
|
+
FIGMA LINKS (bắt buộc mỗi màn):
|
|
18
|
+
- Mỗi screen PHẢI có link Figma node-level (URL chứa ?node-id=...) — lấy bằng
|
|
19
|
+
right-click frame → "Copy link to selection". Đây là link AI đọc được qua Figma MCP.
|
|
20
|
+
- Link file trần (không có node-id) KHÔNG hợp lệ — AI không định vị được frame.
|
|
21
|
+
- Screen chưa có design → đánh dấu ❌ Missing; spec giữ Status "draft", chặn sign-off
|
|
22
|
+
và /generate-bdd cho tới khi đủ link.
|
|
23
|
+
|
|
17
24
|
SCREEN STATES (bắt buộc mỗi màn):
|
|
18
25
|
- Tối thiểu: default, loading, error
|
|
19
26
|
- Thêm "empty" nếu màn có thể hiển thị trạng thái không có dữ liệu
|
|
@@ -34,7 +41,7 @@
|
|
|
34
41
|
| **Service** | {active_service} |
|
|
35
42
|
| **Domain** | {domain} |
|
|
36
43
|
| **Business PRD** | [{TICKET-ID}](./{TICKET-ID}-slug.md) |
|
|
37
|
-
| **Figma** | {
|
|
44
|
+
| **Figma** | {feature file link} ({linked}/{N} frames linked) |
|
|
38
45
|
| **Author** | {PO name or "AI-assisted"} |
|
|
39
46
|
| **Created** | {YYYY-MM-DD} |
|
|
40
47
|
| **Updated** | {YYYY-MM-DD} |
|
|
@@ -43,10 +50,10 @@
|
|
|
43
50
|
|
|
44
51
|
# 1. Screen Inventory
|
|
45
52
|
|
|
46
|
-
| # | Screen Name | Entry Point | Figma Frame | Notes |
|
|
47
|
-
|
|
48
|
-
| 1 | {Screen 1} | {how user arrives} | [Frame]({
|
|
49
|
-
| 2 | {Screen 2} | {entry point} |
|
|
53
|
+
| # | Screen Name | Entry Point | Figma Frame (node-level link) | Notes |
|
|
54
|
+
|---|-------------|-------------|-------------------------------|-------|
|
|
55
|
+
| 1 | {Screen 1} | {how user arrives} | [Frame]({node-level url}) | |
|
|
56
|
+
| 2 | {Screen 2} | {entry point} | ❌ Missing — add node-id link | |
|
|
50
57
|
|
|
51
58
|
---
|
|
52
59
|
|
|
@@ -181,9 +188,10 @@
|
|
|
181
188
|
|
|
182
189
|
## Figma Summary
|
|
183
190
|
|
|
184
|
-
| Screen | Figma Frame
|
|
185
|
-
|
|
186
|
-
| {Screen 1} | [Link]({url})
|
|
191
|
+
| Screen | Figma Frame (node-level) | Link / Fetch Status |
|
|
192
|
+
|------------|--------------------------|--------------------------------|
|
|
193
|
+
| {Screen 1} | [Link]({node-level url}) | ✅ Linked & fetched |
|
|
194
|
+
| {Screen 2} | — | ❌ Missing — no node-id link |
|
|
187
195
|
|
|
188
196
|
## Design Tokens Referenced
|
|
189
197
|
|
|
@@ -50,7 +50,9 @@ paths:
|
|
|
50
50
|
# .agent/project-context.yaml to ".agent/project-lessons.md" (resolved per service_root).
|
|
51
51
|
lessons_file: "specs/domain-knowledge/lessons-learned.md"
|
|
52
52
|
|
|
53
|
-
# Tech Docs
|
|
53
|
+
# Tech Docs (BE-authored API contract).
|
|
54
|
+
# In umbrella mode with spec_source set, context-loader auto-routes this to
|
|
55
|
+
# {spec_source}/specs/tech-docs so FE/App read the contract via the spec submodule.
|
|
54
56
|
tech_docs_dir: "tech-docs"
|
|
55
57
|
|
|
56
58
|
# Design Specs (FE/App platforms only — web, app)
|
|
@@ -94,6 +96,7 @@ domains:
|
|
|
94
96
|
# When spec_source is set, context-loader auto-derives:
|
|
95
97
|
# prd_dir → {spec_source}/specs/prd
|
|
96
98
|
# design_spec_dir → {spec_source}/specs/design-spec
|
|
99
|
+
# tech_docs_dir → {spec_source}/specs/tech-docs # shared API contract (per-service tech_docs_dir below wins in multi-service)
|
|
97
100
|
# domain_knowledge_dir → {spec_source}/specs/domain-knowledge
|
|
98
101
|
# (You can still override these manually in paths: section below.)
|
|
99
102
|
#
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
name: "Android (Jetpack Compose)"
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
description: "Native Android development with Jetpack Compose + Kotlin"
|
|
4
|
+
language: "Kotlin"
|
|
5
|
+
framework: "Jetpack Compose"
|
|
6
|
+
stack_type: "mobile"
|
|
7
|
+
default_layer_order:
|
|
8
|
+
- Domain models
|
|
9
|
+
- Repository (data layer)
|
|
10
|
+
- UseCase (domain logic)
|
|
11
|
+
- ViewModel (StateFlow<UiState>)
|
|
12
|
+
- Composable screens (presentation)
|
|
13
|
+
test_framework: "JUnit5 + MockK + Turbine"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
build:
|
|
2
|
+
compile: "./gradlew assembleRelease"
|
|
3
|
+
test: "./gradlew test"
|
|
4
|
+
run: "./gradlew installDebug / Open in Android Studio → Run"
|
|
5
|
+
lint: "./gradlew lint"
|
|
6
|
+
|
|
7
|
+
architecture:
|
|
8
|
+
style: "MVVM + Clean Architecture (Composable → ViewModel → UseCase → Repository)"
|
|
9
|
+
key_rules:
|
|
10
|
+
- "Composables are pure UI functions — no business logic, no direct suspend calls"
|
|
11
|
+
- "ViewModels expose StateFlow<UiState>; Composables collect via collectAsStateWithLifecycle()"
|
|
12
|
+
- "UseCases are single-responsibility classes injected into ViewModels"
|
|
13
|
+
- "Repositories are interfaces; implementations live in the data layer"
|
|
14
|
+
- "Dependency injection via Hilt"
|
|
15
|
+
- "Never launch coroutines from a Composable directly — use LaunchedEffect or ViewModel"
|
|
16
|
+
folder_structure: |
|
|
17
|
+
src/main/java/{package}/
|
|
18
|
+
├── core/
|
|
19
|
+
│ ├── network/ ← Retrofit instance, interceptors
|
|
20
|
+
│ ├── theme/ ← MaterialTheme, Color, Type, Shape
|
|
21
|
+
│ └── utils/
|
|
22
|
+
├── shared/
|
|
23
|
+
│ └── components/ ← reusable Composables (AppButton, AppTextField...)
|
|
24
|
+
├── features/
|
|
25
|
+
│ └── {domain}/
|
|
26
|
+
│ ├── ui/ ← Composable screens + components
|
|
27
|
+
│ ├── viewmodel/ ← ViewModel + UiState
|
|
28
|
+
│ ├── domain/ ← UseCases, domain models
|
|
29
|
+
│ └── data/ ← Repository impl, data sources
|
|
30
|
+
|
|
31
|
+
coding_standards:
|
|
32
|
+
naming:
|
|
33
|
+
composables: "PascalCase (e.g., OrderListScreen, CreateOrderForm)"
|
|
34
|
+
viewmodels: "PascalCase + ViewModel suffix (e.g., OrderListViewModel)"
|
|
35
|
+
usecases: "PascalCase + UseCase suffix (e.g., CreateOrderUseCase)"
|
|
36
|
+
files:
|
|
37
|
+
screen: "{Feature}Screen.kt"
|
|
38
|
+
viewmodel: "{Feature}ViewModel.kt"
|
|
39
|
+
usecase: "{Feature}UseCase.kt"
|
|
40
|
+
patterns:
|
|
41
|
+
state_management: "StateFlow<UiState> in ViewModel"
|
|
42
|
+
navigation: "Jetpack Navigation Compose"
|
|
43
|
+
networking: "Retrofit + OkHttp"
|
|
44
|
+
serialization: "Kotlinx Serialization or Gson"
|
|
45
|
+
di: "Hilt"
|
|
46
|
+
async: "Kotlin Coroutines + Flow"
|
|
47
|
+
|
|
48
|
+
testing:
|
|
49
|
+
unit: "JUnit5 + MockK + Turbine (Flow testing)"
|
|
50
|
+
ui: "Compose UI Test (composeTestRule)"
|
|
51
|
+
patterns:
|
|
52
|
+
- "Test ViewModel with fake repositories and TestCoroutineDispatcher"
|
|
53
|
+
- "UI tests use semantics matchers — set Modifier.testTag() on Composables"
|
|
54
|
+
|
|
55
|
+
trace_tags:
|
|
56
|
+
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
57
|
+
source: "// @trace.source=specs/bdd/{domain}/{UC-ID}.feature"
|