@educa-corp/sdd-framework 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/build.js +230 -0
- package/bin/index.js +609 -0
- package/commands/debug.md +835 -0
- package/commands/debug.tmpl +257 -0
- package/commands/define-product.md +746 -0
- package/commands/define-product.tmpl +191 -0
- package/commands/dev-gen-test.md +1015 -0
- package/commands/dev-gen-test.tmpl +490 -0
- package/commands/dev-run-test.md +749 -0
- package/commands/dev-run-test.tmpl +224 -0
- package/commands/dev-smoke-test.md +716 -0
- package/commands/dev-smoke-test.tmpl +217 -0
- package/commands/fix-bug.md +749 -0
- package/commands/fix-bug.tmpl +171 -0
- package/commands/generate-bdd.md +1144 -0
- package/commands/generate-bdd.tmpl +499 -0
- package/commands/generate-code.md +1038 -0
- package/commands/generate-code.tmpl +513 -0
- package/commands/generate-design-spec.md +1079 -0
- package/commands/generate-design-spec.tmpl +524 -0
- package/commands/generate-prd.md +945 -0
- package/commands/generate-prd.tmpl +166 -0
- package/commands/generate-spec-manifest.md +663 -0
- package/commands/generate-spec-manifest.tmpl +164 -0
- package/commands/generate-tech-docs.md +1249 -0
- package/commands/generate-tech-docs.tmpl +252 -0
- package/commands/learn.md +641 -0
- package/commands/learn.tmpl +63 -0
- package/commands/map-testids.md +580 -0
- package/commands/map-testids.tmpl +81 -0
- package/commands/propose-scenario.md +632 -0
- package/commands/propose-scenario.tmpl +133 -0
- package/commands/qc-analyze.md +611 -0
- package/commands/qc-analyze.tmpl +112 -0
- package/commands/qc-design-test.md +567 -0
- package/commands/qc-design-test.tmpl +68 -0
- package/commands/qc-plan.md +548 -0
- package/commands/qc-plan.tmpl +49 -0
- package/commands/qc-report.md +559 -0
- package/commands/qc-report.tmpl +60 -0
- package/commands/qc-review.md +552 -0
- package/commands/qc-review.tmpl +53 -0
- package/commands/qc-run-test.md +609 -0
- package/commands/qc-run-test.tmpl +84 -0
- package/commands/refine-prd.md +992 -0
- package/commands/refine-prd.tmpl +278 -0
- package/commands/report-bug.md +647 -0
- package/commands/report-bug.tmpl +148 -0
- package/commands/review-code.md +682 -0
- package/commands/review-code.tmpl +104 -0
- package/commands/review-context.md +1202 -0
- package/commands/review-context.tmpl +488 -0
- package/commands/review-tech-docs.md +871 -0
- package/commands/review-tech-docs.tmpl +372 -0
- package/commands/setup-ai-first.md +546 -0
- package/commands/setup-ai-first.tmpl +358 -0
- package/commands/sync.md +451 -0
- package/commands/sync.tmpl +351 -0
- package/commands/update-framework.md +251 -0
- package/commands/update-framework.tmpl +151 -0
- package/commands/validate-traces.md +928 -0
- package/commands/validate-traces.tmpl +429 -0
- package/core/FRAMEWORK_VERSION +1 -0
- package/core/commands/debug.md +835 -0
- package/core/commands/define-product.md +746 -0
- package/core/commands/dev-gen-test.md +1015 -0
- package/core/commands/dev-run-test.md +749 -0
- package/core/commands/dev-smoke-test.md +716 -0
- package/core/commands/fix-bug.md +749 -0
- package/core/commands/generate-bdd.md +1144 -0
- package/core/commands/generate-code.md +1038 -0
- package/core/commands/generate-design-spec.md +1079 -0
- package/core/commands/generate-prd.md +945 -0
- package/core/commands/generate-spec-manifest.md +663 -0
- package/core/commands/generate-tech-docs.md +1249 -0
- package/core/commands/learn.md +641 -0
- package/core/commands/map-testids.md +580 -0
- package/core/commands/propose-scenario.md +632 -0
- package/core/commands/qc-analyze.md +611 -0
- package/core/commands/qc-design-test.md +567 -0
- package/core/commands/qc-plan.md +548 -0
- package/core/commands/qc-report.md +559 -0
- package/core/commands/qc-review.md +552 -0
- package/core/commands/qc-run-test.md +609 -0
- package/core/commands/refine-prd.md +992 -0
- package/core/commands/report-bug.md +647 -0
- package/core/commands/review-code.md +682 -0
- package/core/commands/review-context.md +1202 -0
- package/core/commands/review-tech-docs.md +871 -0
- package/core/commands/setup-ai-first.md +546 -0
- package/core/commands/sync.md +451 -0
- package/core/commands/update-framework.md +251 -0
- package/core/commands/validate-traces.md +928 -0
- package/core/hooks/data-guard.js +141 -0
- package/core/hooks/settings.json +18 -0
- package/core/modules/android-compose/module.yaml +13 -0
- package/core/modules/android-compose/stack-profile.yaml +57 -0
- package/core/modules/angular/architecture-snippets/component-patterns.md +187 -0
- package/core/modules/angular/module.yaml +6 -0
- package/core/modules/angular/stack-profile.yaml +38 -0
- package/core/modules/context-engineering/architecture-snippets/context-design.md +119 -0
- package/core/modules/context-engineering/module.yaml +9 -0
- package/core/modules/context-engineering/stack-profile.yaml +61 -0
- package/core/modules/dotnet/architecture-snippets/clean-arch.md +160 -0
- package/core/modules/dotnet/module.yaml +6 -0
- package/core/modules/dotnet/stack-profile.yaml +50 -0
- package/core/modules/flutter/module.yaml +14 -0
- package/core/modules/flutter/stack-profile.yaml +59 -0
- package/core/modules/golang/architecture-snippets/domain-layout.md +283 -0
- package/core/modules/golang/module.yaml +6 -0
- package/core/modules/golang/stack-profile.yaml +40 -0
- package/core/modules/ios-swiftui/module.yaml +13 -0
- package/core/modules/ios-swiftui/stack-profile.yaml +55 -0
- package/core/modules/java-spring/architecture-snippets/layered-arch.md +201 -0
- package/core/modules/java-spring/module.yaml +15 -0
- package/core/modules/java-spring/stack-profile.yaml +28 -0
- package/core/modules/nextjs/architecture-snippets/app-router-patterns.md +269 -0
- package/core/modules/nextjs/module.yaml +14 -0
- package/core/modules/nextjs/stack-profile.yaml +74 -0
- package/core/modules/nuxt/module.yaml +14 -0
- package/core/modules/nuxt/stack-profile.yaml +58 -0
- package/core/modules/php-laravel/architecture-snippets/service-repository.md +302 -0
- package/core/modules/php-laravel/module.yaml +15 -0
- package/core/modules/php-laravel/stack-profile.yaml +56 -0
- package/core/modules/qc-playwright/stack-profile.yaml +66 -0
- package/core/modules/react/architecture-snippets/hooks-query-patterns.md +254 -0
- package/core/modules/react/module.yaml +14 -0
- package/core/modules/react/stack-profile.yaml +63 -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/rules/data-protection.md +80 -0
- package/core/rules/workflow.md +44 -0
- package/core/skills/code/SKILL.md +19 -0
- package/core/skills/debug/SKILL.md +19 -0
- package/core/skills/design-spec/SKILL.md +11 -0
- package/core/skills/discovery/SKILL.md +14 -0
- package/core/skills/prd/SKILL.md +19 -0
- package/core/skills/qc/qa-analyst/DOC_GAPS.template.md +63 -0
- package/core/skills/qc/qa-analyst/acceptance-criteria.md +60 -0
- package/core/skills/qc/qa-analyst/business-rules.md +59 -0
- package/core/skills/qc/qa-analyst/data-flow.md +64 -0
- package/core/skills/qc/qa-analyst/spec-breakdown.md +61 -0
- package/core/skills/qc/qa-designer/e2e/journey.md +41 -0
- package/core/skills/qc/qa-designer/exploratory/charter.md +68 -0
- package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +43 -0
- package/core/skills/qc/qa-designer/functional/api.md +45 -0
- package/core/skills/qc/qa-designer/functional/gui-feature.md +46 -0
- package/core/skills/qc/qa-designer/functional/gui-screen.md +52 -0
- package/core/skills/qc/qa-designer/integration/api.md +42 -0
- package/core/skills/qc/qa-designer/integration/db.md +39 -0
- package/core/skills/qc/qa-designer/integration/gui.md +40 -0
- package/core/skills/qc/qa-designer/integration/kafka.md +40 -0
- package/core/skills/qc/qa-designer/non-functional.md +40 -0
- package/core/skills/qc/qa-planner/test-plan.md +120 -0
- package/core/skills/qc/qa-reviewer/script/e2e.md +87 -0
- package/core/skills/qc/qa-reviewer/script/exploratory.md +45 -0
- package/core/skills/qc/qa-reviewer/script/functional.md +101 -0
- package/core/skills/qc/qa-reviewer/script/integration.md +91 -0
- package/core/skills/qc/qa-reviewer/script/non-functional.md +126 -0
- package/core/skills/qc/qa-reviewer/test-case/e2e.md +73 -0
- package/core/skills/qc/qa-reviewer/test-case/exploratory.md +43 -0
- package/core/skills/qc/qa-reviewer/test-case/functional.md +76 -0
- package/core/skills/qc/qa-reviewer/test-case/integration.md +69 -0
- package/core/skills/qc/qa-reviewer/test-case/non-functional.md +73 -0
- package/core/skills/qc/qa-runner/e2e.md +49 -0
- package/core/skills/qc/qa-runner/exploratory/session.md +36 -0
- package/core/skills/qc/qa-runner/functional/api.md +35 -0
- package/core/skills/qc/qa-runner/functional/gui-feature.md +51 -0
- package/core/skills/qc/qa-runner/functional/gui-screen.md +55 -0
- package/core/skills/qc/qa-runner/integration.md +47 -0
- package/core/skills/qc/qa-runner/non-functional.md +49 -0
- package/core/skills/qc/qa-runner/report/report.md +37 -0
- package/core/skills/setup-ai-first/SKILL.md +11 -0
- package/core/skills/spec/SKILL.md +19 -0
- package/core/skills/test/SKILL.md +18 -0
- package/core/steps/business-language.md +56 -0
- package/core/steps/capture-lesson.md +79 -0
- package/core/steps/context-loader.md +311 -0
- package/core/steps/gate.md +88 -0
- package/core/steps/report-footer.md +100 -0
- package/core/steps/review-fanout.md +159 -0
- package/core/steps/spawn-agent.md +129 -0
- package/core/steps/trace-mirror.md +26 -0
- package/core/templates/architecture.template.md +113 -0
- package/core/templates/design-spec.template.md +217 -0
- package/core/templates/feature.template +120 -0
- package/core/templates/platform-guide.template.md +145 -0
- package/core/templates/prd.template.md +224 -0
- package/core/templates/product-definition.template.md +188 -0
- package/core/templates/project-context.yaml +161 -0
- package/core/templates/tech-design.template.md +498 -0
- package/docs/01-getting-started/README.md +19 -0
- package/docs/01-getting-started/core-concepts.md +102 -0
- package/docs/01-getting-started/installation.md +156 -0
- package/docs/01-getting-started/quickstart.md +86 -0
- package/docs/02-guides/README.md +26 -0
- package/docs/02-guides/bdd-input-checklist.md +68 -0
- package/docs/02-guides/developer/README.md +49 -0
- package/docs/02-guides/developer/bdd-and-trace.md +126 -0
- package/docs/02-guides/developer/commands.md +76 -0
- package/docs/02-guides/developer/pr-checklist.md +16 -0
- package/docs/02-guides/developer/scenarios.md +460 -0
- package/docs/02-guides/developer/workflow.md +121 -0
- package/docs/02-guides/prd-input-checklist.md +94 -0
- package/docs/02-guides/product-owner/README.md +81 -0
- package/docs/02-guides/product-owner/commands.md +30 -0
- package/docs/02-guides/product-owner/handoff-checklist.md +42 -0
- package/docs/02-guides/product-owner/prd-writing-rules.md +45 -0
- package/docs/02-guides/product-owner/scenarios.md +438 -0
- package/docs/02-guides/tech-docs-input-checklist.md +109 -0
- package/docs/02-guides/tester/README.md +75 -0
- package/docs/02-guides/tester/bug-reporting.md +117 -0
- package/docs/02-guides/tester/qc-automation.md +165 -0
- package/docs/02-guides/tester/reading-specs.md +79 -0
- package/docs/02-guides/tester/scenarios.md +186 -0
- package/docs/02-guides/tester/spec-manifest.md +130 -0
- package/docs/02-guides/tester/test-checklist.md +31 -0
- package/docs/02-guides/tester/workflow.md +77 -0
- package/docs/03-concepts/README.md +20 -0
- package/docs/03-concepts/architecture.md +248 -0
- package/docs/03-concepts/mechanisms-explained.md +124 -0
- package/docs/03-concepts/pipeline.md +278 -0
- package/docs/03-concepts/traceability.md +152 -0
- package/docs/04-operations/README.md +33 -0
- package/docs/04-operations/bug-flow.md +364 -0
- package/docs/04-operations/publishing.md +154 -0
- package/docs/04-operations/sync-and-update.md +522 -0
- package/docs/05-reference/README.md +34 -0
- package/docs/05-reference/command-cheatsheet.md +147 -0
- package/docs/05-reference/commands.md +234 -0
- package/docs/05-reference/model-selection.md +74 -0
- package/docs/05-reference/modules.md +110 -0
- package/docs/05-reference/trace-schema.md +154 -0
- package/docs/06-commands/README.md +75 -0
- package/docs/06-commands/explain-debug.md +32 -0
- package/docs/06-commands/explain-define-product.md +43 -0
- package/docs/06-commands/explain-dev-gen-test.md +28 -0
- package/docs/06-commands/explain-dev-run-test.md +24 -0
- package/docs/06-commands/explain-dev-smoke-test.md +25 -0
- package/docs/06-commands/explain-fix-bug.md +28 -0
- package/docs/06-commands/explain-generate-bdd.md +45 -0
- package/docs/06-commands/explain-generate-code.md +53 -0
- package/docs/06-commands/explain-generate-design-spec.md +54 -0
- package/docs/06-commands/explain-generate-prd.md +45 -0
- package/docs/06-commands/explain-generate-spec-manifest.md +20 -0
- package/docs/06-commands/explain-generate-tech-docs.md +56 -0
- package/docs/06-commands/explain-learn.md +21 -0
- package/docs/06-commands/explain-map-testids.md +28 -0
- package/docs/06-commands/explain-propose-scenario.md +24 -0
- package/docs/06-commands/explain-qc-analyze.md +22 -0
- package/docs/06-commands/explain-qc-design-test.md +20 -0
- package/docs/06-commands/explain-qc-plan.md +21 -0
- package/docs/06-commands/explain-qc-report.md +23 -0
- package/docs/06-commands/explain-qc-review.md +24 -0
- package/docs/06-commands/explain-qc-run-test.md +27 -0
- package/docs/06-commands/explain-refine-prd.md +51 -0
- package/docs/06-commands/explain-report-bug.md +24 -0
- package/docs/06-commands/explain-review-code.md +45 -0
- package/docs/06-commands/explain-review-context.md +68 -0
- package/docs/06-commands/explain-review-tech-docs.md +45 -0
- package/docs/06-commands/explain-setup-ai-first.md +25 -0
- package/docs/06-commands/explain-sync.md +24 -0
- package/docs/06-commands/explain-update-framework.md +22 -0
- package/docs/06-commands/explain-validate-traces.md +25 -0
- package/docs/README.md +53 -0
- package/docs/t-sample.md +826 -0
- package/hooks/data-guard.js +141 -0
- package/hooks/settings.json +18 -0
- package/modules/android-compose/module.yaml +13 -0
- package/modules/android-compose/stack-profile.yaml +57 -0
- package/modules/angular/architecture-snippets/component-patterns.md +187 -0
- package/modules/angular/module.yaml +6 -0
- package/modules/angular/stack-profile.yaml +38 -0
- package/modules/context-engineering/architecture-snippets/context-design.md +119 -0
- package/modules/context-engineering/module.yaml +9 -0
- package/modules/context-engineering/stack-profile.yaml +61 -0
- package/modules/dotnet/architecture-snippets/clean-arch.md +160 -0
- package/modules/dotnet/module.yaml +6 -0
- package/modules/dotnet/stack-profile.yaml +50 -0
- package/modules/flutter/module.yaml +14 -0
- package/modules/flutter/stack-profile.yaml +59 -0
- package/modules/golang/architecture-snippets/domain-layout.md +283 -0
- package/modules/golang/module.yaml +6 -0
- package/modules/golang/stack-profile.yaml +40 -0
- package/modules/ios-swiftui/module.yaml +13 -0
- package/modules/ios-swiftui/stack-profile.yaml +55 -0
- package/modules/java-spring/architecture-snippets/layered-arch.md +201 -0
- package/modules/java-spring/module.yaml +15 -0
- package/modules/java-spring/stack-profile.yaml +28 -0
- package/modules/nextjs/architecture-snippets/app-router-patterns.md +269 -0
- package/modules/nextjs/module.yaml +14 -0
- package/modules/nextjs/stack-profile.yaml +74 -0
- package/modules/nuxt/module.yaml +14 -0
- package/modules/nuxt/stack-profile.yaml +58 -0
- package/modules/php-laravel/architecture-snippets/service-repository.md +302 -0
- package/modules/php-laravel/module.yaml +15 -0
- package/modules/php-laravel/stack-profile.yaml +56 -0
- package/modules/qc-playwright/stack-profile.yaml +66 -0
- package/modules/react/architecture-snippets/hooks-query-patterns.md +254 -0
- package/modules/react/module.yaml +14 -0
- package/modules/react/stack-profile.yaml +63 -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 +49 -0
- package/readme.txt +1 -0
- package/rules/data-protection.md +80 -0
- package/rules/workflow.md +44 -0
- package/scripts/init.sh +49 -0
- package/scripts/migrate-specs.js +258 -0
- package/scripts/rename-prd-files.js +174 -0
- package/scripts/upgrade.sh +94 -0
- package/skills/code/SKILL.md +19 -0
- package/skills/code/SKILL.tmpl +19 -0
- package/skills/debug/SKILL.md +19 -0
- package/skills/debug/SKILL.tmpl +19 -0
- package/skills/design-spec/SKILL.md +11 -0
- package/skills/design-spec/SKILL.tmpl +11 -0
- package/skills/discovery/SKILL.md +14 -0
- package/skills/discovery/SKILL.tmpl +14 -0
- package/skills/prd/SKILL.md +19 -0
- package/skills/prd/SKILL.tmpl +19 -0
- package/skills/qc/qa-analyst/DOC_GAPS.template.md +63 -0
- package/skills/qc/qa-analyst/acceptance-criteria.md +60 -0
- package/skills/qc/qa-analyst/business-rules.md +59 -0
- package/skills/qc/qa-analyst/data-flow.md +64 -0
- package/skills/qc/qa-analyst/spec-breakdown.md +61 -0
- package/skills/qc/qa-designer/e2e/journey.md +41 -0
- package/skills/qc/qa-designer/exploratory/charter.md +68 -0
- package/skills/qc/qa-designer/exploratory/explore-to-functional.md +43 -0
- package/skills/qc/qa-designer/functional/api.md +45 -0
- package/skills/qc/qa-designer/functional/gui-feature.md +46 -0
- package/skills/qc/qa-designer/functional/gui-screen.md +52 -0
- package/skills/qc/qa-designer/integration/api.md +42 -0
- package/skills/qc/qa-designer/integration/db.md +39 -0
- package/skills/qc/qa-designer/integration/gui.md +40 -0
- package/skills/qc/qa-designer/integration/kafka.md +40 -0
- package/skills/qc/qa-designer/non-functional.md +40 -0
- package/skills/qc/qa-planner/test-plan.md +120 -0
- package/skills/qc/qa-reviewer/script/e2e.md +87 -0
- package/skills/qc/qa-reviewer/script/exploratory.md +45 -0
- package/skills/qc/qa-reviewer/script/functional.md +101 -0
- package/skills/qc/qa-reviewer/script/integration.md +91 -0
- package/skills/qc/qa-reviewer/script/non-functional.md +126 -0
- package/skills/qc/qa-reviewer/test-case/e2e.md +73 -0
- package/skills/qc/qa-reviewer/test-case/exploratory.md +43 -0
- package/skills/qc/qa-reviewer/test-case/functional.md +76 -0
- package/skills/qc/qa-reviewer/test-case/integration.md +69 -0
- package/skills/qc/qa-reviewer/test-case/non-functional.md +73 -0
- package/skills/qc/qa-runner/e2e.md +49 -0
- package/skills/qc/qa-runner/exploratory/session.md +36 -0
- package/skills/qc/qa-runner/functional/api.md +35 -0
- package/skills/qc/qa-runner/functional/gui-feature.md +51 -0
- package/skills/qc/qa-runner/functional/gui-screen.md +55 -0
- package/skills/qc/qa-runner/integration.md +47 -0
- package/skills/qc/qa-runner/non-functional.md +49 -0
- package/skills/qc/qa-runner/report/report.md +37 -0
- package/skills/setup-ai-first/SKILL.md +11 -0
- package/skills/setup-ai-first/SKILL.tmpl +11 -0
- package/skills/spec/SKILL.md +19 -0
- package/skills/spec/SKILL.tmpl +19 -0
- package/skills/test/SKILL.md +18 -0
- package/skills/test/SKILL.tmpl +18 -0
- package/steps/business-language.md +56 -0
- package/steps/capture-lesson.md +79 -0
- package/steps/context-loader.md +311 -0
- package/steps/gate.md +88 -0
- package/steps/report-footer.md +100 -0
- package/steps/review-fanout.md +159 -0
- package/steps/spawn-agent.md +129 -0
- package/steps/trace-mirror.md +26 -0
- package/templates/architecture.template.md +113 -0
- package/templates/design-spec.template.md +217 -0
- package/templates/feature.template +120 -0
- package/templates/platform-guide.template.md +145 -0
- package/templates/prd.template.md +224 -0
- package/templates/product-definition.template.md +188 -0
- package/templates/project-context.yaml +161 -0
- package/templates/tech-design.template.md +498 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Review Fan-Out toàn diện + Hội tụ về độ đầy đủ
|
|
2
|
+
|
|
3
|
+
**Vì sao có cái này:** Một lượt review đơn không bao giờ liệt kê hết mọi vấn đề cùng lúc — model
|
|
4
|
+
dừng ở mức "đủ" findings, nên mỗi vòng review sau lại lòi ra vấn đề *mới*
|
|
5
|
+
(đập chuột chũi). Quy trình này ép review **hội tụ trong một lần chạy lệnh**:
|
|
6
|
+
fan out song song theo các chiều review, rồi lặp một critic độ-đầy-đủ cho tới khi một
|
|
7
|
+
vòng không sinh thêm gì mới, *trước khi* ghi file findings.
|
|
8
|
+
|
|
9
|
+
Lệnh gọi cung cấp hai thứ bắt buộc + hai tuỳ chọn:
|
|
10
|
+
- **DIMENSIONS** — danh sách các chiều review để fan out
|
|
11
|
+
(`/refine-prd` → 3 lăng kính; `/review-context` → các P-check hoặc B-check).
|
|
12
|
+
- **FINDINGS SCHEMA** — dạng YAML mà mỗi finding phải theo (định nghĩa trong lệnh).
|
|
13
|
+
- **GRANULARITY** *(tuỳ chọn, mặc định `auto`)* — `auto`: chọn độ mịn fan-out theo bảng ngưỡng kích thước ở Phase 1 (hành vi cũ). `per-uc`: **LUÔN** fan-out theo từng UC, **bỏ qua ngưỡng** — dùng cho review cần độ đầy đủ cao (`/refine-prd` truyền cái này để lần đầu đã quét sâu). Lệnh không truyền → `auto` → hành vi không đổi.
|
|
14
|
+
- **CHANGED_SCOPE** *(tuỳ chọn)* — danh sách UC/section đã thay đổi (review **delta**). Nếu được truyền, Phase 1 chỉ fan-out trên các phạm vi này + PRD-global; Phase 2 critic vẫn quét **toàn doc** làm lưới an toàn. Không truyền → quét toàn bộ như thường.
|
|
15
|
+
|
|
16
|
+
> **Bỏ qua ở chế độ sub-agent:** Nếu Gate Bước 0 đã set `_agent_mode: true`, toàn bộ
|
|
17
|
+
> quy trình này bị **bỏ qua** — orchestrator đã chạy sẵn một dimension/UC cho mỗi
|
|
18
|
+
> sub-agent. Chạy các check của lệnh trực tiếp trên section đã giới hạn và trả về findings.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Phase 1 — Quét dimension song song
|
|
23
|
+
|
|
24
|
+
**Bao nhiêu sub-agent:** *số lượng* agent không phải là đòn bẩy độ đầy đủ — bề rộng được
|
|
25
|
+
cố định bởi taxonomy DIMENSION (thêm agent vào cùng một dimension chỉ tìm lại cùng vấn đề),
|
|
26
|
+
còn *độ sâu* thuộc về vòng lặp critic ở Phase 2.
|
|
27
|
+
|
|
28
|
+
**Nếu `GRANULARITY = per-uc`:** **bỏ qua bảng ngưỡng dưới đây**, luôn dùng độ mịn **DIMENSION × phạm vi UC** (kể cả PRD nhỏ) — đảm bảo quét sâu, không bỏ sót ngay lần đầu. (Cái giá: nhiều agent hơn cho PRD nhỏ — chấp nhận để lần đầu đầy đủ.)
|
|
29
|
+
|
|
30
|
+
**Nếu `GRANULARITY = auto`** (mặc định): chọn **độ mịn fan-out** theo kích thước target, tái dùng ngưỡng của `steps/spawn-agent.md`:
|
|
31
|
+
|
|
32
|
+
| Kích thước target | Độ mịn | Số agent |
|
|
33
|
+
|-------------|-------------|-------------|
|
|
34
|
+
| ≤ 3 UC **và** ≤ 300 dòng | một agent cho mỗi DIMENSION trên cả file | = số dimension |
|
|
35
|
+
| > 3 UC **hoặc** > 300 dòng | một agent cho mỗi **DIMENSION × phạm vi UC** (các UC + một phạm vi PRD-global), gom batch để vừa giới hạn agent | `dimensions × (UCs + 1)`, có cap (xem dưới) |
|
|
36
|
+
|
|
37
|
+
Độ mịn lớn hơn giữ context của mỗi sub-agent nhỏ và quét nó vét cạn trên một
|
|
38
|
+
UC duy nhất — chính là điều ngăn bỏ sót trên các PRD lớn.
|
|
39
|
+
|
|
40
|
+
> **Các section global (không thuộc UC) — bắt buộc ở chế độ `DIMENSION × UC`.** Mỗi agent per-UC chỉ
|
|
41
|
+
> thấy một UC, nên các section toàn-PRD không thuộc UC nào (scope, success metric,
|
|
42
|
+
> problem statement, terminology, glossary, changelog) sẽ không được quét. Khi nào
|
|
43
|
+
> fan out theo UC, cũng phải thêm một phạm vi **"PRD-global"** (các section không thuộc UC, finding nhận
|
|
44
|
+
> `uc_id: ""`) bên cạnh danh sách UC. Nên số agent tự nhiên là `dimensions × (UCs + 1)`.
|
|
45
|
+
> (Không cần ở chế độ whole-file — ở đó mỗi agent đã thấy các section global rồi.)
|
|
46
|
+
|
|
47
|
+
### Agent cap — gom batch các UC khi fan-out quá rộng
|
|
48
|
+
|
|
49
|
+
`dimensions × (UCs + 1)` có thể bùng nổ trên PRD lớn (vd 6 check × (8 UC + 1) = 54
|
|
50
|
+
agent). Giới hạn mỗi wave ở **`AGENT_CAP = 12`** agent và gom batch các phạm vi UC cho vừa:
|
|
51
|
+
|
|
52
|
+
1. Dựng danh sách phạm vi = `[UC1, UC2, …, UCn, PRD-global]` (độ dài `UCs + 1`).
|
|
53
|
+
- **Nếu `CHANGED_SCOPE` được truyền (review delta):** danh sách phạm vi = `[các UC trong CHANGED_SCOPE] + [PRD-global]` (chỉ các UC đã đổi + global), KHÔNG phải tất cả UC. Số agent tụt theo đó.
|
|
54
|
+
2. Tính số-phạm-vi-mỗi-bucket: `groups = max(1, floor(AGENT_CAP / dimensions))`.
|
|
55
|
+
- Nếu `groups ≥ UCs + 1` → không cần batch, chạy một agent cho mỗi `DIMENSION × scope`.
|
|
56
|
+
- Else chia danh sách phạm vi thành `groups` bucket liền kề kích thước xấp xỉ bằng nhau
|
|
57
|
+
(giữ `PRD-global` ở bucket riêng nếu vừa; nếu không thì gắn vào bucket cuối).
|
|
58
|
+
Mỗi agent khi đó xử lý **một DIMENSION trên một bucket UC**.
|
|
59
|
+
3. Kích thước wave kết quả = `dimensions × groups ≤ AGENT_CAP`.
|
|
60
|
+
|
|
61
|
+
Một agent đã batch review nhiều UC cùng lúc — vẫn giới hạn chặt hơn nhiều so với cả
|
|
62
|
+
file, nên độ phủ vẫn cao. `AGENT_CAP` là núm chỉnh duy nhất; tăng nếu host cho phép
|
|
63
|
+
concurrency nhiều hơn, giảm để tiết kiệm token. Chế độ whole-file (≤ 3 UC) không bao giờ chạm cap.
|
|
64
|
+
|
|
65
|
+
Spawn các sub-agent đã chọn bằng Agent tool (gửi trong một message duy nhất để chúng
|
|
66
|
+
chạy đồng thời). Mỗi sub-agent nhận một **context window mới** và quét phạm vi của nó
|
|
67
|
+
chỉ qua **một** dimension duy nhất — độ phủ sâu hơn một session phải tung hứng mọi
|
|
68
|
+
dimension cùng lúc (tránh lost-in-the-middle).
|
|
69
|
+
|
|
70
|
+
Template prompt cho sub-agent (điền vào các ngoặc):
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
You are a {DIMENSION_NAME} reviewer. Read the full target file at {target_file}.
|
|
74
|
+
Scope: review ONLY through the {DIMENSION_NAME} lens/check — {DIMENSION_DESCRIPTION}.
|
|
75
|
+
Be exhaustive: scan every section, every UC, every AC/BR/scenario. Do not stop early.
|
|
76
|
+
Project context (terminology, entities, architecture):
|
|
77
|
+
{slim_context — banned terms, canonical entities, layer order, domains}
|
|
78
|
+
|
|
79
|
+
Return a JSON array of findings, each:
|
|
80
|
+
{ "dimension": "{DIMENSION_NAME}", "severity": "critical|major|minor",
|
|
81
|
+
"section": "...", "uc_id": "...", "quote": "<verbatim ≤120 chars>",
|
|
82
|
+
"finding": "...", "suggestion": "...", "auto_fixable": true|false }
|
|
83
|
+
Return [] if this dimension is clean. Return ONLY the JSON array.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Gom mảng findings của mọi sub-agent vào một danh sách hợp nhất `ALL_FINDINGS`.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Phase 2 — Vòng lặp hội tụ critic độ-đầy-đủ
|
|
91
|
+
|
|
92
|
+
Đây là bước chống đập-chuột-chũi. Lặp cho tới khi **hai vòng liên tiếp thêm 0 finding
|
|
93
|
+
mới**, hoặc tới cap cứng **3 vòng**, cái nào đến trước:
|
|
94
|
+
|
|
95
|
+
> **Lưu ý delta:** kể cả khi `CHANGED_SCOPE` giới hạn Phase 1 vào các UC đã đổi, completeness-critic ở Phase 2 **vẫn đọc TOÀN bộ doc** — đây là lưới an toàn bắt các vấn đề mà một fix ở UC đã đổi có thể làm lộ ra ở chỗ khác.
|
|
96
|
+
|
|
97
|
+
1. Spawn một sub-agent **completeness-critic** bằng Agent tool. Cho nó:
|
|
98
|
+
- toàn bộ target file (`{target_file}`),
|
|
99
|
+
- danh sách findings đã ghi nhận dưới dạng **slim JSON** — chỉ 3 fields cốt lõi
|
|
100
|
+
đủ để critic nhận ra trùng lặp (không cần `quote`, `suggestion`, `auto_fixable`, `severity`):
|
|
101
|
+
```json
|
|
102
|
+
[
|
|
103
|
+
{ "uc_id": "...", "section": "...", "finding": "..." },
|
|
104
|
+
...
|
|
105
|
+
]
|
|
106
|
+
```
|
|
107
|
+
Nếu `ALL_FINDINGS` vượt 60 items, rút gọn `finding` xuống còn 80 ký tự đầu mỗi item.
|
|
108
|
+
- cùng slim context (banned terms, canonical entities, layer order, domains).
|
|
109
|
+
Prompt nó:
|
|
110
|
+
```
|
|
111
|
+
Here is a document and a list of issues already found. Read the WHOLE document.
|
|
112
|
+
List ONLY real, additional issues NOT already in the list — gaps, ambiguities,
|
|
113
|
+
contradictions, missing edge/negative paths, coverage holes, terminology drift,
|
|
114
|
+
structural omissions, and any issue that a fix to an existing finding would expose.
|
|
115
|
+
ALSO flag ROLE-BOUNDARY / altitude violations (you are NOT limited to adding detail):
|
|
116
|
+
content sitting in the WRONG section — detailed mechanism (retry counts, timeouts, flag
|
|
117
|
+
names/owners, error branches) written INSIDE an acceptance criterion or a scope line
|
|
118
|
+
instead of the Business Rule/Logic section; an AC that merely restates its referenced BR
|
|
119
|
+
(same content, converged); a term definition crammed into In/Out Scope. For these, the
|
|
120
|
+
suggestion must be to MOVE the detail to its proper section (AC keeps only the observable
|
|
121
|
+
outcome + BR ref) — NOT to delete it, and NOT to add more detail.
|
|
122
|
+
Do NOT repeat anything already listed. Return the same finding JSON shape, or [] if
|
|
123
|
+
nothing new.
|
|
124
|
+
```
|
|
125
|
+
2. Thêm bất kỳ finding thực sự mới (chưa có trong `ALL_FINDINGS`) vào danh sách.
|
|
126
|
+
3. Nếu vòng này trả 0 finding mới → tăng bộ đếm dry-round; ngược lại reset về 0.
|
|
127
|
+
4. Dừng khi bộ đếm dry-round đạt 2, hoặc sau tổng cộng 3 vòng.
|
|
128
|
+
|
|
129
|
+
Ghi lại `convergence_rounds` (số vòng critic đã chạy) cho report.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Phase 3 — Dedup, giải quyết xung đột, merge
|
|
134
|
+
|
|
135
|
+
Các sub-agent chạy **mù với nhau** (độc lập = độ phủ đa dạng). Chúng không bao giờ
|
|
136
|
+
trao đổi hay điều hoà giữa chúng — mọi xử lý trùng/xung đột diễn ra **ở đây trong
|
|
137
|
+
orchestrator**, nơi thấy toàn bộ tập findings.
|
|
138
|
+
|
|
139
|
+
1. **Khử trùng lặp** `ALL_FINDINGS`: hai finding là trùng nếu cùng nhắm tới cùng
|
|
140
|
+
`section` + `uc_id` và mô tả cùng một vấn đề gốc. Giữ cái có `suggestion`
|
|
141
|
+
phong phú hơn; nếu khác nhau về severity, giữ severity **cao hơn**.
|
|
142
|
+
2. **Giải quyết xung đột** — nhóm các finding còn lại theo `section` + `uc_id` và kiểm tra
|
|
143
|
+
mâu thuẫn (hai finding có `suggestion` không thể cùng áp dụng, hoặc đề xuất sửa ngược nhau cho cùng một chỗ):
|
|
144
|
+
- Nếu hai đề xuất có thể **merge** thành một bản sửa mạch lạc → merge thành một finding duy nhất.
|
|
145
|
+
- Nếu chúng **loại trừ lẫn nhau** → phát ra **một** finding nêu cả hai phương án
|
|
146
|
+
và set `auto_fixable: false` với `status: "needs_discussion"` (PRD) /
|
|
147
|
+
`status: "pending"` (review) để con người chọn — không bao giờ âm thầm bỏ một bên.
|
|
148
|
+
- Nếu một finding bị **vô hiệu** bởi finding khác (vd một finding cấu trúc nói một section
|
|
149
|
+
bị thiếu, nhưng một finding khác trích dẫn nội dung từ chính section đó) → bỏ cái không hợp lệ.
|
|
150
|
+
3. **Sắp xếp** theo severity (critical → major → minor), rồi theo thứ tự `section` trong file.
|
|
151
|
+
4. **Gán ID ổn định** `F001, F002, …` theo thứ tự đã sắp đó.
|
|
152
|
+
5. Map `dimension` của mỗi finding vào field schema của lệnh
|
|
153
|
+
(`lens` cho `/refine-prd`; `check_id` cho `/review-context`).
|
|
154
|
+
6. Ghi **một** file findings duy nhất theo FINDINGS SCHEMA mà lệnh định nghĩa.
|
|
155
|
+
|
|
156
|
+
Trong report cuối của lệnh, thêm một dòng:
|
|
157
|
+
```
|
|
158
|
+
Convergence: {convergence_rounds} vòng critic — file findings đã đầy đủ; chạy lại sẽ lòi ra 0 vấn đề mới.
|
|
159
|
+
```
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Pattern điều phối Sub-Agent
|
|
2
|
+
|
|
3
|
+
Dùng bởi các lệnh nặng khi target vượt ngưỡng phức tạp.
|
|
4
|
+
Session chính trở thành một **orchestrator nhẹ** — chỉ điều phối.
|
|
5
|
+
Mỗi đơn vị công việc chạy trong sub-agent riêng với context window mới.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Ngưỡng phức tạp
|
|
10
|
+
|
|
11
|
+
| Tín hiệu | Ngưỡng | Hành động |
|
|
12
|
+
|--------|-----------|--------|
|
|
13
|
+
| Số UC trong PRD | > 3 UC | spawn 1 agent cho mỗi UC |
|
|
14
|
+
| Độ dài PRD | > 300 dòng | spawn agent bất kể số UC |
|
|
15
|
+
|
|
16
|
+
Nếu vượt **một trong hai** ngưỡng → chuyển sang chế độ orchestration.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Các bước của Orchestrator (session chính)
|
|
21
|
+
|
|
22
|
+
### Bước A — Dựng context gọn
|
|
23
|
+
|
|
24
|
+
Chỉ trích xuất những gì sub-agent cần — KHÔNG truyền nguyên CLAUDE.md hay nguyên business-dictionary:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"project_name": "{project.name}",
|
|
29
|
+
"tech_stack": {
|
|
30
|
+
"language": "{tech_stack.language}",
|
|
31
|
+
"framework": "{tech_stack.framework}",
|
|
32
|
+
"build_tool": "{tech_stack.build_tool}",
|
|
33
|
+
"test_framework": "{tech_stack.test_framework}",
|
|
34
|
+
"database": "{tech_stack.database}",
|
|
35
|
+
"module": "{tech_stack.module}"
|
|
36
|
+
},
|
|
37
|
+
"conventions": {
|
|
38
|
+
"build_command": "{conventions.build_command}",
|
|
39
|
+
"commit_format": "{conventions.commit_format}"
|
|
40
|
+
},
|
|
41
|
+
"paths": {
|
|
42
|
+
"specs_dir": "{paths.specs_dir}",
|
|
43
|
+
"trace_dir": "{paths.trace_dir}",
|
|
44
|
+
"tech_docs_dir": "{paths.tech_docs_dir}"
|
|
45
|
+
},
|
|
46
|
+
"architecture_summary": "<3-5 gạch đầu dòng: thứ tự layer + quy tắc chính>",
|
|
47
|
+
"domains": ["{domain1}", "{domain2}"],
|
|
48
|
+
"banned_terms": ["{term1}", "{term2}"]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Bước B — Trích danh sách UC
|
|
53
|
+
|
|
54
|
+
Quét PRD target tìm các heading `#### {TICKET-ID}-UC{N}:`.
|
|
55
|
+
Dựng list: `[ { uc_id, uc_name, line_start, line_end } ]`
|
|
56
|
+
|
|
57
|
+
### Bước C — Công bố kế hoạch
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Phát hiện độ phức tạp cao — {N} UC / {L} dòng trong {prd_file}
|
|
61
|
+
Đang spawn {N} sub-agent (1 cho mỗi UC)...
|
|
62
|
+
Agent 1 → {TICKET-ID}-UC1: {tên UC}
|
|
63
|
+
Agent 2 → {TICKET-ID}-UC2: {tên UC}
|
|
64
|
+
...
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Bước D — Spawn một sub-agent cho mỗi UC
|
|
68
|
+
|
|
69
|
+
Dựng payload và gọi Agent tool cho từng UC:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"_agent_mode": true,
|
|
74
|
+
"command": "generate-bdd",
|
|
75
|
+
"uc_id": "{TICKET-ID}-UC{N}",
|
|
76
|
+
"target_file": "{đường dẫn tuyệt đối tới PRD hoặc feature file}",
|
|
77
|
+
"uc_section": { "line_start": {N}, "line_end": {N} },
|
|
78
|
+
"context": { "<context gọn từ Bước A>" },
|
|
79
|
+
"active_platform": "{web|app|system — platform orchestrator đã chọn ở Platform Selection}",
|
|
80
|
+
"design_coverage": { "<Screen States + AC-UI behavioral orchestrator đã trích ở 'Design Spec — Gate & Load' (B1); rỗng nếu BE / không có design-spec>" }
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> **Truyền state orchestrator đã phân giải (quan trọng):** orchestrator (session chính) đã chạy các Guard + chọn platform + nạp design-spec MỘT LẦN *trước* khi spawn. Phải kèm `active_platform` và `design_coverage` vào payload để sub-agent áp đúng (đặc biệt phủ Screen States + AC-UI cho FE/App). KHÔNG kèm → sub-agent sinh BDD thiếu phần design (PRD lớn mất B1).
|
|
85
|
+
|
|
86
|
+
> **Phạm vi lệnh**: Chỉ `/generate-bdd` khởi động chế độ orchestration. `/generate-code` và `/dev-gen-test` có thể chạy như sub-agent (chúng tôn trọng `_agent_mode: true` từ Gate Bước 0), nhưng không spawn thêm sub-agent — phạm vi của chúng vốn đã là một UC duy nhất.
|
|
87
|
+
|
|
88
|
+
Serialize JSON này và truyền làm `$ARGUMENTS` khi gọi lệnh sub-agent.
|
|
89
|
+
|
|
90
|
+
### Bước E — Thu thập và merge kết quả
|
|
91
|
+
|
|
92
|
+
Mỗi sub-agent trả về:
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"uc_id": "{TICKET-ID}-UC{N}",
|
|
96
|
+
"files_created": ["path/to/file1", "path/to/file2"],
|
|
97
|
+
"status": "success | error",
|
|
98
|
+
"errors": []
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Merge vào một report duy nhất (theo định dạng report-footer.md).
|
|
103
|
+
Nếu có sub-agent lỗi → liệt kê rõ ràng và đề xuất chạy lại riêng UC đó.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Điểm vào của Sub-Agent (các lệnh được gọi)
|
|
108
|
+
|
|
109
|
+
Khi `gate.md Bước 0` phát hiện `_agent_mode: true`:
|
|
110
|
+
|
|
111
|
+
1. Parse toàn bộ payload từ `$ARGUMENTS`
|
|
112
|
+
2. **Bỏ qua context-loader.md** — dùng trực tiếp `payload.context`
|
|
113
|
+
3. **Chỉ giới hạn ở `payload.uc_id`** — không xử lý các UC khác trong file
|
|
114
|
+
4. Chỉ đọc section PRD giữa `payload.uc_section.line_start` và `line_end`
|
|
115
|
+
5. **Dùng state orchestrator đã phân giải:** `active_platform` = `payload.active_platform`; `design_coverage` = `payload.design_coverage`. **KHÔNG chạy lại** các Guard (PRD approved / Design-Spec) hay tự nạp lại design-spec / hỏi platform — orchestrator đã làm một lần ở session chính.
|
|
116
|
+
6. Thực thi logic thường của lệnh cho riêng UC này (dùng `design_coverage` từ payload để phủ Screen States + AC-UI)
|
|
117
|
+
7. Trả về JSON kết quả có cấu trúc (định dạng Bước E ở trên)
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Tiết kiệm Context Window
|
|
122
|
+
|
|
123
|
+
| Chế độ | Nạp gì mỗi session |
|
|
124
|
+
|------|------------------------|
|
|
125
|
+
| Single session (≤ 3 UC) | Full context + full PRD + tất cả UC |
|
|
126
|
+
| Orchestrator | Context gọn + chỉ các heading UC |
|
|
127
|
+
| Mỗi sub-agent | Context gọn + **chỉ 1 section UC** |
|
|
128
|
+
|
|
129
|
+
PRD càng lớn, mức tiết kiệm trên mỗi sub-agent càng nhiều.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Làm mới panel mirror của Living Docs *(local, chế độ umbrella)*
|
|
2
|
+
|
|
3
|
+
*Bỏ qua hoàn toàn ở chế độ single-service (không có `services` và không có `setup.spec_source`) — ở đó
|
|
4
|
+
`.trace/` của chính repo CHÍNH LÀ vị trí panel, nên không có gì để mirror.*
|
|
5
|
+
|
|
6
|
+
Sau khi cập nhật TSV authoritative tại `{paths.trace_dir}`:
|
|
7
|
+
|
|
8
|
+
**Khi `setup.spec_source` được đặt (trace gộp — trường hợp phổ biến):**
|
|
9
|
+
`{paths.trace_dir}` phân giải về `{spec_source}/.trace` — vị trí authoritative duy nhất.
|
|
10
|
+
Lệnh này chạy từ `service_root`, nên thao tác ghi là **liên-repo vào spec submodule**;
|
|
11
|
+
commit/push spec submodule cho lần cập nhật trace (giống như `feedback/`).
|
|
12
|
+
1. Phân giải `panel_mirror = ./.trace` tại **gốc workspace hiện tại**.
|
|
13
|
+
2. Nếu `panel_mirror` phân giải ra path khác với `{paths.trace_dir}`, copy mỗi
|
|
14
|
+
`{UC-ID}-{platform}.tsv` vừa cập nhật → `{panel_mirror}/{UC-ID}-{platform}.tsv` (tạo thư mục; ghi đè).
|
|
15
|
+
Không namespace theo service — chỉ có một bộ trace; service sở hữu được mang trong
|
|
16
|
+
`@trace.service` của từng row.
|
|
17
|
+
|
|
18
|
+
**Legacy (không có `spec_source` — trace theo service):**
|
|
19
|
+
Copy mỗi `{UC-ID}-{platform}.tsv` vừa cập nhật → `{panel_mirror}/{service-name}/{UC-ID}-{platform}.tsv`
|
|
20
|
+
(namespace theo `active_service`).
|
|
21
|
+
|
|
22
|
+
Cách này giữ panel Living Docs của workspace đang mở luôn mới **giữa các lần sync** — nó chỉ là
|
|
23
|
+
một **mirror tiện lợi cục bộ**. File `trace-report.json` đã merge (canonical, trong
|
|
24
|
+
`{spec_source}/.living-docs/`) được build lại bởi `/sync` hoặc `/validate-traces`. Với các lệnh
|
|
25
|
+
được orchestrate, làm việc này một lần trong orchestrator sau khi tất cả sub-agent trả về — không phải
|
|
26
|
+
bên trong từng sub-agent.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# §1. Project Overview
|
|
2
|
+
|
|
3
|
+
Project : {{PROJECT_NAME}}
|
|
4
|
+
Language : {{LANGUAGE}} # vd: Java 17 / TypeScript / C# / Go
|
|
5
|
+
Framework : {{FRAMEWORK}} # vd: Spring Boot 3.2 / Angular 17 / .NET 8
|
|
6
|
+
Build : {{BUILD_COMMAND}} # vd: mvn clean install -DskipTests / dotnet build / ng build
|
|
7
|
+
Test : {{TEST_COMMAND}} # vd: mvn test / dotnet test / ng test
|
|
8
|
+
Domains : {{COMMA_SEPARATED_DOMAINS}}
|
|
9
|
+
|
|
10
|
+
# §2. Architecture
|
|
11
|
+
|
|
12
|
+
style: "{{ARCH_STYLE}}" # vd: Layered / Clean / Hexagonal / Component-based
|
|
13
|
+
|
|
14
|
+
layers: "{{LAYER_STACK}}"
|
|
15
|
+
# Ví dụ:
|
|
16
|
+
# Java/Spring: Controller → Facade → Service → Repository
|
|
17
|
+
# .NET Clean: Presentation → Application → Domain → Infrastructure
|
|
18
|
+
# Angular: Component → Service → HTTP Client → Backend API
|
|
19
|
+
# Go: Handler → UseCase → Repository → Domain
|
|
20
|
+
|
|
21
|
+
rules:
|
|
22
|
+
- "{{ARCH_RULE_1}}" # vd: Controller không được chứa business logic
|
|
23
|
+
- "{{ARCH_RULE_2}}" # vd: Service sở hữu ranh giới transaction
|
|
24
|
+
- "{{ARCH_RULE_3}}" # vd: Repository không được gọi service
|
|
25
|
+
|
|
26
|
+
# Chiều phụ thuộc giữa các layer (layer trong không được phụ thuộc layer ngoài):
|
|
27
|
+
# {{OUTER_LAYER}} → {{MIDDLE_LAYER}} → {{INNER_LAYER}}
|
|
28
|
+
|
|
29
|
+
# §3. Coding Standards
|
|
30
|
+
|
|
31
|
+
naming:
|
|
32
|
+
classes: "{{CLASS_NAMING}}" # vd: PascalCase / PascalCase+Suffix
|
|
33
|
+
methods: "{{METHOD_NAMING}}" # vd: camelCase / PascalCase
|
|
34
|
+
packages: "{{PACKAGE_NAMING}}" # vd: lowercase / lowercase.snake_case
|
|
35
|
+
files: "{{FILE_NAMING}}" # vd: PascalCase.java / kebab-case.ts
|
|
36
|
+
|
|
37
|
+
patterns:
|
|
38
|
+
response_wrapper: "{{RESPONSE_WRAPPER}}" # vd: ApiResponse<T> / Result<T> / IActionResult
|
|
39
|
+
mapping: "{{MAPPING_LIBRARY}}" # vd: MapStruct / AutoMapper / manual
|
|
40
|
+
exception_base: "{{BASE_EXCEPTION}}" # vd: ResourceNotFoundException / DomainException
|
|
41
|
+
|
|
42
|
+
forbidden:
|
|
43
|
+
- "Magic number — dùng hằng số có tên"
|
|
44
|
+
- "Lệnh debug print trong code production"
|
|
45
|
+
- "{{PROJECT_SPECIFIC_FORBIDDEN_PATTERN}}"
|
|
46
|
+
|
|
47
|
+
# §4. API Conventions
|
|
48
|
+
|
|
49
|
+
versioning: "{{API_VERSIONING}}" # vd: tiền tố /v1/ / theo header / query param
|
|
50
|
+
auth: "{{AUTH_MECHANISM}}" # vd: JWT Bearer / OAuth2 / API Key
|
|
51
|
+
|
|
52
|
+
http_status:
|
|
53
|
+
get_list: 200 # danh sách phân trang hoặc đầy đủ
|
|
54
|
+
get_single: 200
|
|
55
|
+
create: 201
|
|
56
|
+
update: 200
|
|
57
|
+
delete: 204
|
|
58
|
+
bad_request: 400
|
|
59
|
+
unauthorized: 401
|
|
60
|
+
forbidden: 403
|
|
61
|
+
not_found: 404
|
|
62
|
+
server_error: 500
|
|
63
|
+
|
|
64
|
+
error_response_format: |
|
|
65
|
+
{
|
|
66
|
+
"code": "ERROR_CODE",
|
|
67
|
+
"message": "Human readable message",
|
|
68
|
+
"details": {} // optional field-level errors
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# §5. Error Handling
|
|
72
|
+
|
|
73
|
+
not_found_exception: "{{NOT_FOUND_EXCEPTION_CLASS}}" # vd: ResourceNotFoundException
|
|
74
|
+
validation_exception: "{{VALIDATION_EXCEPTION_CLASS}}" # vd: ValidationException
|
|
75
|
+
domain_exception: "{{DOMAIN_EXCEPTION_CLASS}}" # vd: DomainException / BusinessRuleViolationException
|
|
76
|
+
|
|
77
|
+
global_handler: "{{GLOBAL_EXCEPTION_HANDLER}}" # vd: @ControllerAdvice / ExceptionHandlerMiddleware
|
|
78
|
+
|
|
79
|
+
rules:
|
|
80
|
+
- "Không bao giờ nuốt exception âm thầm"
|
|
81
|
+
- "Log ở mức error kèm full stack trace cho lỗi 5xx"
|
|
82
|
+
- "{{PROJECT_SPECIFIC_ERROR_RULE}}"
|
|
83
|
+
|
|
84
|
+
# §6. Testing Standards
|
|
85
|
+
|
|
86
|
+
unit_test_framework: "{{UNIT_TEST_FW}}" # vd: JUnit 5 + Mockito / xUnit + Moq / Jest
|
|
87
|
+
integration_test_framework: "{{IT_TEST_FW}}" # vd: Spring Boot Test / WebApplicationFactory
|
|
88
|
+
|
|
89
|
+
coverage_targets:
|
|
90
|
+
unit: "{{UNIT_COVERAGE_PCT}}%" # vd: 80%
|
|
91
|
+
integration: "{{IT_COVERAGE_PCT}}%" # vd: phủ các flow chính
|
|
92
|
+
|
|
93
|
+
naming_pattern: "{{TEST_METHOD_NAMING}}" # vd: methodName_whenCondition_shouldExpectation
|
|
94
|
+
|
|
95
|
+
rules:
|
|
96
|
+
- "Unit test chỉ mock các dependency trực tiếp"
|
|
97
|
+
- "Integration test phủ happy path + các luồng lỗi chính"
|
|
98
|
+
- "Mọi scenario trong .feature phải có test tương ứng"
|
|
99
|
+
|
|
100
|
+
# §7. Git Conventions
|
|
101
|
+
|
|
102
|
+
branch_feature: "feature/{{TICKET_PREFIX}}-{N}-{slug}"
|
|
103
|
+
branch_fix: "fix/{{TICKET_PREFIX}}-{N}-{slug}"
|
|
104
|
+
branch_chore: "chore/{slug}"
|
|
105
|
+
|
|
106
|
+
commit_feature: "feat({{TICKET_PREFIX}}-{N}): {description}"
|
|
107
|
+
commit_fix: "fix({{TICKET_PREFIX}}-{N}): {description}"
|
|
108
|
+
commit_chore: "chore: {description}"
|
|
109
|
+
commit_docs: "docs: {description}"
|
|
110
|
+
|
|
111
|
+
pr_title: "{{TICKET_PREFIX}}-{N}: {feature name}"
|
|
112
|
+
pr_requires_review: true
|
|
113
|
+
pr_branch_protection: "{{BASE_BRANCH}}" # vd: main / develop
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# {TICKET-ID} {Feature Name} — Design Spec [{Platform}]
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
Template này được sử dụng bởi /generate-design-spec.
|
|
5
|
+
Platform = web | app | app-ios | app-android
|
|
6
|
+
|
|
7
|
+
PLATFORM SECTIONS:
|
|
8
|
+
- Section 3A + 4A: chỉ dành cho web (react/nextjs/vue/angular). Xóa C khi dùng cho web.
|
|
9
|
+
- Section 3C + 4B: chỉ dành cho app (flutter/react-native/ios/android). Xóa A+B khi dùng cho app.
|
|
10
|
+
|
|
11
|
+
COMPONENT MAPPING (bắt buộc):
|
|
12
|
+
- Mọi component trong Component Inventory PHẢI được map với figma-components/{module}.md
|
|
13
|
+
- ✅ Matched → dùng Code Component và Import Path từ catalog
|
|
14
|
+
- ⚠️ TODO → đánh dấu [TODO — chưa implement]
|
|
15
|
+
- ❌ Chưa có → đánh dấu [NEW — cần confirm với designer]
|
|
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
|
+
|
|
24
|
+
SCREEN STATES (bắt buộc mỗi màn):
|
|
25
|
+
- Tối thiểu: default, loading, error
|
|
26
|
+
- Thêm "empty" nếu màn có thể hiển thị trạng thái không có dữ liệu
|
|
27
|
+
- Thêm "success" nếu action tạo ra trạng thái xác nhận riêng biệt
|
|
28
|
+
-->
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Metadata
|
|
33
|
+
|
|
34
|
+
| Field | Value |
|
|
35
|
+
|--------------------|---------------------------------------------------------------|
|
|
36
|
+
| **Spec ID** | {TICKET-ID}-DS-{platform} |
|
|
37
|
+
| **Version** | 1.0 |
|
|
38
|
+
| **Status** | draft / approved |
|
|
39
|
+
| **Platform** | {web \| app \| app-ios \| app-android} |
|
|
40
|
+
| **Module** | {active_module} |
|
|
41
|
+
| **Service** | {active_service} |
|
|
42
|
+
| **Domain** | {domain} |
|
|
43
|
+
| **Business PRD** | [{TICKET-ID}](./{TICKET-ID}-slug.md) |
|
|
44
|
+
| **Figma** | {link file feature} ({linked}/{N} frame đã link) |
|
|
45
|
+
| **Author** | {tên PO hoặc "AI-assisted"} |
|
|
46
|
+
| **Created** | {YYYY-MM-DD} |
|
|
47
|
+
| **Updated** | {YYYY-MM-DD} |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
# 1. Danh mục màn hình (Screen Inventory)
|
|
52
|
+
|
|
53
|
+
| # | Tên màn hình | Điểm vào | Figma Frame (link node-level) | Ghi chú |
|
|
54
|
+
|---|-------------|-------------|-------------------------------|-------|
|
|
55
|
+
| 1 | {Màn hình 1} | {người dùng đến từ đâu} | [Frame]({node-level url}) | |
|
|
56
|
+
| 2 | {Màn hình 2} | {điểm vào} | ❌ Missing — thêm link node-id | |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
# 2. Đặc tả màn hình (Screen Specs)
|
|
61
|
+
|
|
62
|
+
## Màn hình 1: {Tên màn hình}
|
|
63
|
+
|
|
64
|
+
**Figma**: [{Tên frame}]({figma_frame_url})
|
|
65
|
+
|
|
66
|
+
### Layout
|
|
67
|
+
|
|
68
|
+
{Grid / max-width / padding / spacing — tham chiếu design token nếu áp dụng được}
|
|
69
|
+
|
|
70
|
+
### Component Inventory
|
|
71
|
+
|
|
72
|
+
| Component (Figma) | Code Component | Import Path | States | Ghi chú |
|
|
73
|
+
|------------------------|----------------|------------------------|---------------------------------|---------|
|
|
74
|
+
| {Figma/Button/Primary} | Button | @/components/ui/Button | default, loading, disabled | |
|
|
75
|
+
| {Figma/Input/Text} | TextInput | @/components/ui/Input | default, focus, error, disabled | |
|
|
76
|
+
|
|
77
|
+
### Screen States
|
|
78
|
+
|
|
79
|
+
| State | Trigger | Hành vi UI |
|
|
80
|
+
|-----------|----------------------------------|----------------------------------------------------------|
|
|
81
|
+
| default | Màn đã load, có dữ liệu | {Mô tả toàn bộ giao diện đã render} |
|
|
82
|
+
| loading | API đang gọi | {Vị trí và kiểu skeleton / spinner} |
|
|
83
|
+
| error | API thất bại / lỗi validation | {Toast / lỗi inline / màn lỗi + CTA khôi phục} |
|
|
84
|
+
| empty | Không có dữ liệu trả về | {Illustration + CTA — vd: "Chưa có mục nào. Thêm mới →"} |
|
|
85
|
+
| success | Action hoàn tất (nếu có) | {Toast xác nhận / điều hướng / thay đổi giao diện} |
|
|
86
|
+
|
|
87
|
+
### Actions & Navigation
|
|
88
|
+
|
|
89
|
+
| Action | Trigger | Kết quả |
|
|
90
|
+
|-----------------|---------------------------|---------------------------------------------------|
|
|
91
|
+
| {Tên action} | Tap/click {phần tử} | Điều hướng tới {Màn hình N} / Mở {Tên modal} |
|
|
92
|
+
| {Back/Cancel} | Cử chỉ back / nút | Quay lại {màn trước} mà không lưu |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
<!-- Lặp lại ## Màn hình N cho mỗi màn bổ sung -->
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
# 3. Pattern tương tác (Interaction Patterns)
|
|
101
|
+
|
|
102
|
+
<!-- === CHỈ WEB — xóa section này cho app === -->
|
|
103
|
+
|
|
104
|
+
## A. Hành vi Responsive *(web)*
|
|
105
|
+
|
|
106
|
+
| Breakpoint | Width | Thay đổi layout |
|
|
107
|
+
|------------|------------|---------------------------------------------|
|
|
108
|
+
| Mobile | < 768px | {1 cột, bottom nav, CTA full-width} |
|
|
109
|
+
| Tablet | 768–1279px | {grid 2 cột, sidebar thu gọn} |
|
|
110
|
+
| Desktop | ≥ 1280px | {layout đầy đủ, max-width 1440px} |
|
|
111
|
+
|
|
112
|
+
## B. Hover / Focus / Keyboard *(web)*
|
|
113
|
+
|
|
114
|
+
| Phần tử | Hover | Focus | Keyboard |
|
|
115
|
+
|----------------|-------------------------------|---------------------------------|---------------|
|
|
116
|
+
| Primary button | Background → {color.hover} | Outline 2px {color.focus} | Enter / Space |
|
|
117
|
+
| Text input | Border → {color.border.hover} | Border → {color.primary} | Tab to focus |
|
|
118
|
+
|
|
119
|
+
<!-- === CHỈ APP — xóa section A+B cho app === -->
|
|
120
|
+
|
|
121
|
+
## C. Cử chỉ & Điều hướng *(app)*
|
|
122
|
+
|
|
123
|
+
| Cử chỉ | Màn / Phần tử | Hành vi |
|
|
124
|
+
|----------------------|---------------------|---------------------------------------------|
|
|
125
|
+
| Cử chỉ back | Mọi màn | {Quay lại / hiện dialog "Discard changes?"} |
|
|
126
|
+
| Pull-to-refresh | {Tên màn} | Refresh dữ liệu, spinner ở trên cùng |
|
|
127
|
+
| Swipe trái trên row | {List item} | Hiện action {Delete / Archive} |
|
|
128
|
+
|
|
129
|
+
### Navigation Stack *(app)*
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
{vd: BottomTab(Home) → ListPage → DetailPage → EditPage}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Platform Conventions *(app)*
|
|
136
|
+
|
|
137
|
+
| Khía cạnh | iOS | Android |
|
|
138
|
+
|------------------|-------------------------------------------|-------------------------------------|
|
|
139
|
+
| Navigation bar | Nút back trên-trái, title canh giữa | Mũi tên Up, title canh trái |
|
|
140
|
+
| Bottom sheet | UISheetPresentation, hiện grabber | BottomSheet, drag handle |
|
|
141
|
+
| Dialog | Action canh phải | Action canh trái |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
# 4. Cân nhắc theo Platform (Platform Considerations)
|
|
146
|
+
|
|
147
|
+
<!-- === CHỈ WEB === -->
|
|
148
|
+
|
|
149
|
+
## A. Accessibility *(web)*
|
|
150
|
+
|
|
151
|
+
- [ ] Mọi phần tử tương tác đều tới được bằng phím Tab — không có keyboard trap
|
|
152
|
+
- [ ] Focus trap bên trong modal
|
|
153
|
+
- [ ] Nút chỉ có icon phải có `aria-label`
|
|
154
|
+
- [ ] Nội dung động thông báo qua `aria-live`
|
|
155
|
+
- [ ] Tương phản WCAG AA: text ≥ 4.5:1, text lớn ≥ 3:1
|
|
156
|
+
- [ ] Input form có label hiển thị (không chỉ dùng placeholder)
|
|
157
|
+
|
|
158
|
+
<!-- === CHỈ APP === -->
|
|
159
|
+
|
|
160
|
+
## B. Thiết bị & OS *(app)*
|
|
161
|
+
|
|
162
|
+
- [ ] Áp dụng safe area insets (trên + dưới) ở mọi màn
|
|
163
|
+
- [ ] Touch target tối thiểu: 44×44pt (iOS) / 48×48dp (Android)
|
|
164
|
+
- [ ] Đã test trên 375pt (iPhone SE) và 360dp (Android nhỏ)
|
|
165
|
+
- [ ] Deep link: `{scheme}://{host}/{path}` → {tên màn}
|
|
166
|
+
- [ ] Permission: {Camera / Location / Notification} — nội dung lý do TBD
|
|
167
|
+
- [ ] Offline: {tên màn} hiện dữ liệu cache + banner; {action} bị disable kèm tooltip
|
|
168
|
+
- [ ] Đã test dark mode — không có màu hardcode
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
# 5. AC-UI — Tiêu chí chấp nhận về Design
|
|
173
|
+
|
|
174
|
+
> Được **PO + Designer** review và sign off trước khi sinh BDD.
|
|
175
|
+
> Bổ sung cho AC mức nghiệp vụ trong [Business PRD](./{TICKET-ID}-slug.md).
|
|
176
|
+
|
|
177
|
+
| ID | Tiêu chí chấp nhận | Verified by |
|
|
178
|
+
|--------|--------------------------------------------------------------------------|-----------------|
|
|
179
|
+
| AC-UI1 | Mọi màn khớp với frame Figma đã duyệt trong dung sai design-system | Designer |
|
|
180
|
+
| AC-UI2 | Trạng thái loading xuất hiện trong vòng 200ms kể từ khi gọi API | QA |
|
|
181
|
+
| AC-UI3 | Mọi thông báo lỗi đều hiển thị, rõ ràng, và kèm CTA khôi phục | PO |
|
|
182
|
+
| AC-UI4 | Empty state có illustration và call-to-action | PO + Designer |
|
|
183
|
+
| AC-UI5 | {Tiêu chí riêng theo platform} | QA |
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
# Appendix
|
|
188
|
+
|
|
189
|
+
## Tóm tắt Figma
|
|
190
|
+
|
|
191
|
+
| Màn hình | Figma Frame (node-level) | Trạng thái Link / Fetch |
|
|
192
|
+
|------------|--------------------------|--------------------------------|
|
|
193
|
+
| {Màn hình 1} | [Link]({node-level url}) | ✅ Đã link & fetch |
|
|
194
|
+
| {Màn hình 2} | — | ❌ Missing — không có link node-id |
|
|
195
|
+
|
|
196
|
+
## Design Token đã tham chiếu
|
|
197
|
+
|
|
198
|
+
| Token | Value | Dùng ở |
|
|
199
|
+
|-------------------|----------|----------------------------|
|
|
200
|
+
| `color.primary` | {#hex} | Button, link |
|
|
201
|
+
| `spacing.md` | {16px} | Khoảng cách dọc tiêu chuẩn |
|
|
202
|
+
|
|
203
|
+
## Tài liệu tham khảo
|
|
204
|
+
|
|
205
|
+
- [{TICKET-ID}](./{TICKET-ID}-slug.md) — Business PRD
|
|
206
|
+
|
|
207
|
+
## Giả định AI
|
|
208
|
+
|
|
209
|
+
- {Giả định — [AI DRAFT]}
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Changelog
|
|
214
|
+
|
|
215
|
+
| Version | Date | Changes |
|
|
216
|
+
|---------|--------------|-----------------|
|
|
217
|
+
| 1.0 | {YYYY-MM-DD} | Initial version |
|