5 pha · 1 triết lý · Không còn đoán mò
Chương 5 đã cho bạn ngôn ngữ — EARS Notation, 8 thành phần, Risk Matrix. Chương này cho bạn động cơ — một quy trình làm việc hoàn chỉnh biến spec thành production code thông qua năm pha được thiết kế kỹ lưỡng.
Tỷ lệ 40/60 lý thuyết–thực hành có chủ đích: bạn sẽ thực sự chạy workflow, không chỉ đọc về nó. Ba công cụ cụ thể được giới thiệu theo thứ tự tăng dần về tính linh hoạt — không có "cách tốt nhất", chỉ có "cách phù hợp nhất" với đội nhóm và dự án của bạn.
Khi AI generate code sai → không sửa code trực tiếp → tìm điểm trong Spec chưa rõ ràng → sửa Spec → re-generate.
Code là artifact tạm thời. Spec mới là nguồn sự thật lâu dài.
Context Discovery → Spec → Plan → Tasks → Implementation → Validation
Workflow thực tế với 5 Slash Commands — 5 Touchpoints trong GitHub Issues & PRs
Open Agentic IDE — đọc file, chạy terminal, multi-model, MCP integration
Xây dựng workflow riêng với Markdown thuần — tự do tuyệt đối, không toolkit
Lab A: CRUD đơn giản (45 phút) · Lab B: Import Business Logic phức tạp (60 phút)
Rubric chấm điểm, bài học từ hai Labs, tổng kết chương
Pipeline tuyến tính với các điểm kiểm tra rõ ràng. Mỗi pha có đầu vào, đầu ra, người chịu trách nhiệm, và Definition of Done cụ thể. Không được phép chuyển sang pha tiếp theo khi pha hiện tại chưa hoàn thành.
◄─────── "Fix the Spec, not the Code" ───────►
Khi validation thất bại → quay về Spec, không sửa code trực tiếp
| Pha | Tên | Actor | Input | Output | Definition of Done |
|---|---|---|---|---|---|
| 0 | Context Discovery | Human | User stories, domain knowledge | Context document | Team hiểu domain & constraints |
| 1 | Specification | Human | Context doc, user stories | SPEC.md (APPROVED) | AI review passed, spec locked |
| 2 | Planning | AI | SPEC.md | PLAN.md | Human approved arch + risks |
| 3 | Task Decomp. | AI | PLAN.md | TASKS.md | Tasks atomic & independent |
| 4 | Implementation | AI | TASKS.md + SPEC.md | Source code + tests | All tests green |
| 5 | Validation | Both | Code + SPEC.md | Validation report | Code ↔ Spec 100% match |
Đây là pha thường bị bỏ qua nhất vì nó không tạo ra file code nào. Nhưng đây chính là nguyên nhân số một khiến dự án AI-assisted thất bại: team đã viết spec và nhờ AI implement mà không thực sự hiểu domain. AI implement đúng spec nhưng spec lại sai về mặt business.
Vấn đề thực sự là gì? User đang bị đau ở đâu?
Tránh solution thinking ở bước này. Chỉ mô tả pain.
Các thuật ngữ domain-specific mà AI cần biết.
Các quy tắc nghiệp vụ bất thành văn.
Ai được lợi? Ai chịu ảnh hưởng? Ai có quyền quyết định?
Tech, Business, Time — ràng buộc cứng.
Mỗi assumption là một rủi ro nếu sai.
Open Questions cần clarify với stakeholder trước khi viết spec.
Đây là pha con người làm chủ hoàn toàn. Dựa trên Context Document từ Pha 0, bạn viết SPEC.md theo đúng cấu trúc 8 thành phần và EARS Notation đã học ở Chương 5. Sau khi viết xong draft, mới đưa AI vào để review — không sớm hơn.
Pha 2 là lần đầu tiên AI tham gia chủ động với vai trò kiến trúc sư. AI đọc SPEC.md và tạo ra PLAN.md — một tài liệu mô tả cách tiếp cận kỹ thuật, các component cần tạo, dependency giữa chúng, và risk assessment. Con người review và approve trước khi đi tiếp.
"Design trước, code sau" luôn cho kết quả tốt hơn. AI có xu hướng bắt đầu code ngay khi được đưa spec — giống như nhà thầu xây móng trước khi có bản vẽ.
PLAN.md buộc AI phải "nghĩ" trước khi "làm".
| Component | Trách nhiệm | File |
|---|---|---|
| ReviewRouter | HTTP endpoints, validation | src/reviews/router.py |
| ReviewService | Business logic từ SPEC §3 | src/reviews/service.py |
| ReviewRepository | DB CRUD + aggregate query | src/reviews/repository.py |
| BlacklistService | Filter inappropriate content | src/shared/blacklist.py |
| AggregateUpdateJob | Background rating recalculation | src/jobs/aggregate_update.py |
POST /reviews → ReviewRouter (validate input)
→ ReviewService.create_review()
→ OrderRepository.verify_purchase() [check buyer đã mua]
→ ReviewRepository.find_by_order() [check duplicate]
→ BlacklistService.scan() [check content]
→ ReviewRepository.create() [persist]
→ Response 201 Created
(async) → AggregateUpdateJob.enqueue()
| Rủi ro | Khả năng | Impact | Mitigation |
|---|---|---|---|
| Race condition: double submit | High | High | DB unique constraint |
| Aggregate lag > 5 min | Med | Med | Redis cache + job queue |
| Blacklist false positives | Med | Low | Whitelist + user appeal |
"Questions for Human" là vàng.
Đây là nơi AI cho bạn biết những chỗ spec còn mơ hồ. Nếu AI không có câu hỏi nào, hoặc spec của bạn rất tốt, hoặc AI đang assume — hãy hỏi lại: "Bạn đã assume điều gì?" Mỗi assumption ẩn là một bug tiềm ẩn cho nó.
Nếu AI không đặt câu hỏi sau khi đọc PLAN.md — hãy chủ động hỏi nó: "Bạn đã assume điều gì trong quá trình tạo plan này?"
Từ PLAN.md, AI tạo TASKS.md — danh sách các task cụ thể, có thể implement độc lập, với acceptance criteria rõ ràng cho từng task. Đây là bước chuyển từ "what to build" sang "how to build it step by step".
| ID | Task | Est | Deps | Spec Refs | Done When |
|---|---|---|---|---|---|
| T001 | Tạo DB migration reviews table | 1h | — | §5 Data | Migration runs, rollback OK |
| T002 | Implement BlacklistService | 2h | — | §3 Unwanted | 10 test cases pass |
| T003 | Implement ReviewRepository | 3h | T001 | §5 Data | CRUD ops + aggregate query OK |
| T004 | Implement ReviewService | 4h | T002,T003 | §3 Func. | All business rules enforced |
| T005 | Implement ReviewRouter | 2h | T004 | §3 Func. | All endpoints return correct HTTP |
| T006 | Implement AggregateUpdateJob | 3h | T003 | §4 Non-func | Rating updates within 5 min |
| T007 | Integration tests | 2h | T005,T006 | §7 Accept. | All AC checklist items pass |
| T008 | API documentation | 1h | T005 | — | OpenAPI spec generated |
Đây là pha AI làm việc nhiều nhất — nhưng không phải theo nghĩa "chat và nhận code". AI implement từng task trong TASKS.md, theo đúng thứ tự dependency, với SPEC.md và PLAN.md luôn trong context. Không có task nào được implement mà không có spec refs rõ ràng.
AI generate: if rating not in range(1, 5):
Dev sửa tay: if rating not in range(1, 6):
→ Code diverge khỏi spec, không ai biết tại sao
Test fails → Check SPEC §3: "rating 1–5 (integer)"
Spec rõ nhưng AI dùng range() sai
Update prompt → Re-generate → Correct
Pha cuối cùng là formal verification: đọc code và spec song song, xác nhận mọi requirement đều được implement đúng. Đây không phải code review thông thường — đây là compliance check.
| Spec Section | Requirement (tóm tắt) | Code File/Line | Test Name | Status |
|---|---|---|---|---|
| §3 WHEN submit | Validate rating 1–5 | service.py:L45 | test_rating_boundary_valid | Pass |
| §3 WHEN submit | Validate comment 10–500 | service.py:L52 | test_comment_length_boundaries | Pass |
| §3 Unwanted buyer | Reject non-buyer review | service.py:L61 | test_non_buyer_rejected | Pass |
| §3 Unwanted dup | Reject duplicate review | service.py:L72 | test_duplicate_review_rejected | Pass |
| §8 Out of Scope | NO moderation queue | (verify absent) | test_no_moderation_endpoint | Pass |
Cho đoạn hội thoại sau — xác định mỗi message thuộc pha nào và tại sao developer này đang làm sai:
→ Pha nào bị skip? Sai lầm cụ thể là gì? SDD đúng trông như thế nào?
Viết SPEC.md ngắn (Detailed level) cho tính năng "Password Reset". Sau đó đưa cho Cline với prompt Pha 2 để generate PLAN.md.
Review output của AI: risks nào nó tìm được? Questions nào nó đặt ra? Bạn đồng ý với architectural approach không?
Workflow thực tế với Slash Commands — đưa SDD pipeline trực tiếp vào GitHub Issues và Pull Requests. 5 Slash Commands, 5 Touchpoints, mỗi lần chuyển pha đều có human-in-the-loop.
GitHub Spec Kit là tập hợp workflows, templates, và GitHub Actions được thiết kế để đưa SDD pipeline trực tiếp vào GitHub Issues và Pull Requests. Thay vì quản lý SPEC.md, PLAN.md, TASKS.md thủ công, Spec Kit cung cấp các slash commands — những điểm chạm (touchpoints) chuẩn hóa giữa người và AI.
Mỗi slash command là một "handoff point" — nơi con người chuyển giao quyền kiểm soát cho AI một cách có chủ đích, với context được chuẩn bị sẵn. Không có gì xảy ra mà không có ý chí của người dùng.
| Command | Pha | Actor kích hoạt | AI làm gì |
|---|---|---|---|
| /speckit.constitution | Setup | Tech lead, once | Tạo AGENTS.md từ project description + tech stack |
| /speckit.specify | Pha 1 | Developer / PM | Review spec draft, tìm gaps, tạo SPEC.md version cuối |
| /speckit.plan | Pha 2 | Developer | Đọc SPEC.md, tạo PLAN.md với arch + risks + questions |
| /speckit.tasks | Pha 3 | Developer (sau approve) | Đọc PLAN.md, tạo TASKS.md với atomic tasks và deps |
| /speckit.implement | Pha 4 | Developer (per task) | Implement task cụ thể + tests, tạo PR |
Command quan trọng nhất. Gọi khi đã có draft spec (hoặc chỉ có user story). AI sẽ:
Trigger sau khi SPEC.md đã được approve. AI sẽ:
Sau khi plan được approve → dev có thể chạy /speckit.tasks
Trigger sau khi PLAN.md approved. AI sẽ:
Trigger trong task sub-issue. AI sẽ:
PR description: Task ID · Spec refs · Test coverage · Out of Scope verified
Open Agentic IDE — đối cực của Spec Kit. Chạy ngay trong VSCode, đọc file, chạy terminal, gọi MCP servers, thực thi kế hoạch multi-step mà không cần copy-paste từng đoạn code.
| Tiêu chí | Cline (Roo Code) | GitHub Copilot Chat | Cursor AI | Kiro IDE |
|---|---|---|---|---|
| Open source | MIT License | Proprietary | Proprietary | AWS-controlled |
| Agentic (multi-step) | Native | Limited | Composer | Native |
| Multi-model support | Anthropic/OpenAI/Ollama | Copilot only | Multiple | AWS Bedrock |
| MCP integration | Full | None | Partial | Limited |
| File system access | Full read/write | Read only | Full | Full |
| Terminal execution | With approval | No | Yes | Yes |
| Cost model | Pay-per-token (API) | Subscription | Subscription | AWS pricing |
| Vendor lock-in | Lowest | GitHub/MS | Medium | AWS |
Điểm khác biệt lớn nhất của Cline so với AI chatbot thông thường là khả năng thực thi — không chỉ suggest. Ví dụ: giao Cline implement Task T004 với full autonomy.
| Task trong SDD | Model khuyến nghị | Lý do | Approx cost |
|---|---|---|---|
| Pha 0: Context Discovery | Claude Sonnet | Cần reasoning, domain understanding | $0.003/1k tokens |
| Pha 1: Spec review + gaps | Claude Sonnet | Logic analysis, contradiction detect | $0.003/1k tokens |
| Pha 2: Planning (PLAN.md) | Claude Sonnet | Architecture decisions cần depth | $0.003/1k tokens |
| Pha 3: Task decomp. | Claude Haiku | Structured breakdown, không cần depth | $0.00025/1k tokens |
| Pha 4: Boilerplate code | Claude Haiku / GPT4o-mini | Simple patterns, CRUD generation | $0.00015/1k tokens |
| Pha 4: Business logic | Claude Sonnet | Complex logic cần reasoning | $0.003/1k tokens |
| Pha 5: Validation | Claude Sonnet | Careful comparison cần accuracy | $0.003/1k tokens |
| Offline / confidential | Llama 3 via Ollama | Data không ra ngoài machine | Free (local GPU) |
Kết nối Cline với MCP servers tạo ra workflow agentic thực sự: AI không chỉ generate code — nó đọc Jira để biết requirement, đọc GitHub để biết existing code, viết code, chạy tests, và tạo PR. Tất cả mà không cần bạn switch tab.
Bạn nói với Cline:
"Đọc Jira ticket PROJ-123, implement theo spec, tạo PR và link vào ticket."
Cline sẽ tự động orchestrate toàn bộ: fetch ticket → read spec → implement → test → create PR → update Jira.
Không có MCP → Cline chỉ là AI code editor thông minh. Với MCP → Cline thực hiện multi-step workflow hoàn chỉnh. Đây chính là tầm nhìn của SDD: con người design ý định, AI thực thi toàn bộ.
Xây dựng workflow riêng không cần toolkit — chỉ với Markdown files, git, và bất kỳ AI chat nào. Bản chất SDD không phụ thuộc vào công cụ, mà phụ thuộc vào nguyên lý.
Quy ước thư mục .sdd/ đặt tất cả spec artifacts trong một nơi, tách biệt với source code nhưng nằm cùng repo. Dấu chấm đầu tên tránh nhầm lẫn với source code, đồng thời truyền tín hiệu rõ ràng: đây là metadata của dự án.
Mỗi khi bắt đầu AI session mới, bạn không chat tự nhiên — bạn trình bày contract và yêu cầu AI "ký" (acknowledge) trước khi làm việc. Điều này áp dụng cho mọi AI: ChatGPT, Claude, Gemini, hay bất kỳ model nào.
| Artifact | Naming | Location | Ví dụ |
|---|---|---|---|
| Feature spec | feature-{name}/SPEC.md | .sdd/specs/ | feature-cart/SPEC.md |
| Bugfix spec | fix-{issue-id}/SPEC.md | .sdd/specs/ | fix-gh-234/SPEC.md |
| Plan | PLAN.md (trong folder) | .sdd/specs/{name}/ | feature-cart/PLAN.md |
| Tasks | TASKS.md (trong folder) | .sdd/specs/{name}/ | feature-cart/TASKS.md |
| AI review | {name}-review-{date}.md | .sdd/reviews/ | cart-review-2025-01-20.md |
| Git tag | spec/{name}/v{semver} | git tag | spec/cart/v1.0.0 |
| Git commit | spec({name}): {action} | commit msg | spec(cart): approve v1.0.0 |
| Branch | spec/{name}-draft | git branch | spec/cart-draft |
Bài thực hành trung tâm của chương — chạy toàn bộ SDD pipeline cho hai tính năng với độ phức tạp khác nhau. Lab B là "bài test thực sự".
Feature: Quản lý Categories cho blog. Simple CRUD, không có business logic phức tạp. Mục đích: làm quen với SDD pipeline trong môi trường "an toàn" trước khi tackle Lab B.
Đây là bài test thực sự. Tính năng Import Data có đủ độ phức tạp để bộc lộ tất cả những gì có thể sai nếu Planning và Task Decomposition bị bỏ qua: format validation, error logging, partial success, rollback strategy. Những vấn đề này không hiện ra khi nhìn vào user story — chỉ hiện ra khi bạn spec kỹ.
Admin có thể upload file CSV để import hàng loạt sản phẩm. Requirements: upload CSV, parse và import vào database, báo cáo số lượng thành công/thất bại, xử lý lỗi định dạng.
← Đây là tất cả. Phần tiếp theo: bạn phải tự phát hiện tất cả những gì còn thiếu qua SDD process.
Danh sách câu hỏi bạn phải trả lời trước khi viết spec. Chúng không xuất hiện trong user story — bạn phải tự phát hiện:
| Câu hỏi | Nếu không hỏi → Bug |
|---|---|
| "CSV format cụ thể thế nào? Header row có không?" | AI đoán format → import sai toàn bộ |
| "Nếu 1 row lỗi trong 1000 rows — rollback hay skip?" | Hành vi undefined → inconsistent data |
| "Duplicate product (same SKU) → update hay error?" | Silent data override hoặc false rejection |
| "File size limit?" | Memory exhaustion khi upload 500MB CSV |
| "Log ở đâu? Admin xem được không? Trong bao lâu?" | Log mất sau restart, không debug được |
| "Import async hay sync? Timeout?" | 30s timeout khi import 50,000 rows |
| "Validation per-row hay per-field?" | Row 1 lỗi field 2 → message không rõ |
| Vấn đề thiết kế | Lab A (CRUD) | Lab B (Import) |
|---|---|---|
| Async processing | Không cần | Bắt buộc — background job queue |
| Transaction strategy | Per-request transaction | Per-row, không global rollback |
| Error storage | Không cần | import_errors table + downloadable |
| Concurrency control | Không cần | Semaphore/lock cho 3-job limit |
| File storage | Không cần | Temp storage + cleanup job |
| Progress tracking | Không cần | Real-time counters + polling |
| Testing complexity | Unit tests đủ | Integration + end-to-end bắt buộc |
| ID | Task | Est | Dependencies |
|---|---|---|---|
| T001 | DB migration: import_jobs table | 1h | — |
| T002 | DB migration: import_errors table | 1h | T001 |
| T003 | FileValidationService (size, ext) | 2h | — |
| T004 | CSVParserService (header + rows) | 3h | T003 |
| T005 | RowValidatorService (per-field) | 3h | — |
| T006 | ImportJobRepository | 2h | T001,T002 |
| T007 | ImportWorker (async background) — critical path | 4h | T004,T005,T006 |
| T008 | ConcurrencyGuard (3-job limit) | 2h | T006 |
| T009 | ImportRouter (upload + status) | 2h | T007,T008 |
| T010 | ErrorExportEndpoint (CSV download) | 2h | T006 |
| T011 | Integration tests | 4h | T009,T010 |
| T012 | Admin email alert (all-fail case) | 2h | T007 |
| Tiêu chí | Lab A (CRUD) | Lab B (Import) | Điểm |
|---|---|---|---|
| SPEC đủ 8 thành phần | 8/8 sections | 8/8 sections | 20đ |
| EARS notation | ≥5 SHALL statements | ≥12 SHALL statements | 20đ |
| Out of Scope rõ ràng | ≥3 items | ≥5 items | 10đ |
| PLAN.md có risks | ≥2 risks | ≥5 risks | 10đ |
| Tasks atomic (≤4h) | All tasks ≤4h | All tasks ≤4h | 15đ |
| Code có EARS tags | ≥80% rules tagged | ≥80% rules tagged | 10đ |
| Tests cover AC | 100% AC covered | 100% AC covered | 15đ |
Task Decomposition không phải overhead — nó là quality gate. Khi ai đó implement tất cả trong 1 task (không decompose) → context overflow, AI forget spec details → thiếu partial success logic → lỗi production.
| Cách tiếp cận | Phù hợp với | Điểm mạnh | Điểm yếu |
|---|---|---|---|
| GitHub Spec Kit | Team dùng GitHub, muốn cấu trúc | Traceability tốt, audit trail hoàn hảo | Cần setup, learning curve |
| Cline (Roo Code) | Developer muốn speed + autonomy | Agentic, multi-model, MCP integration | Cần giám sát, có thể overrun |
| DIY Markdown | Team nhỏ, linh hoạt, bất kỳ AI | Không vendor lock, đơn giản, tự do | Tự kỷ luật cao hơn cần thiết |
Test-Driven Specification
Given-When-Then (BDD) notation · AI generate test suite trước khi viết code (TDS) ·
Contract testing cho API · Mutation testing với AI-generated test cases.
5 pha · Fix the Spec · Human-in-the-loop ở mọi điểm quan trọng