SDD là lớp contract giữa ý định và code.
CafeKit biến feature idea thành requirements có nguồn, design contracts, task packets, verification evidence, và machine state đã sync trước khi implementation được phép chạy.
CafeKit keeps the assistant moving through persistent contracts instead of relying on chat memory.
Evidence
Gather codebase and external evidence before requirements or design are finalized.
Contract
Lock behavior, constraints, canonical contracts, traceability, and out-of-scope boundaries.
Task packets
Split work into self-contained packets with related files, criteria, dependencies, and evidence.
Readiness
Deterministic validation must pass before ready_for_implementation can be true.
Develop
Implement one unblocked task after task-aware inspection of real entrypoints and blast radius.
Proof
Run exact evidence commands, prove reachability, and reject scope drift or hidden placeholders.
Sync
Update task_registry and task markdown only after proof, or audit drift before continuing.
SDD trong CafeKit là gì#
Specification-driven development trong CafeKit không phải nghi thức viết tài liệu dài. Nó là hệ thống kiểm soát cho AI coding.
Assistant chỉ nên code khi công việc đã có contract bền vững:
- vấn đề nào nằm trong scope
- điều gì nằm ngoài scope
- requirement nào phải satisfy
- design contract nào không được âm thầm đổi
- task packet nào đang active
- command và runtime proof nào chứng minh task done
- state file nào phải sync sau khi có proof
Điểm mấu chốt: chat memory mềm, spec thì cứng. Chat có thể quên, tóm tắt sai, hoặc tự hợp lý hóa. specs/<feature>/ là source of truth để assistant kế tiếp, reviewer, hoặc teammate đọc lại mà không cần tin vào context hội thoại cũ.
Luồng một dòng#
/hapo:specs
-> validate spec artifacts
-> /hapo:develop one task packet
-> /hapo:test + /hapo:code-review
-> /hapo:sync after proof
Đây là delivery loop chính của SDD. Request còn mơ hồ, architecture còn tranh luận, acceptance criteria chưa rõ, hoặc thay đổi chạm nhiều subsystem thì dùng /hapo:brainstorm như bước pre-spec tùy chọn trước khi loop này bắt đầu.
Artifact contract#
CafeKit lưu spec theo cấu trúc:
specs/<feature>/
├── spec.json
├── requirements.md
├── research.md
├── design.md
├── tasks/
│ ├── task-R0-01-<foundation>.md
│ ├── task-R1-01-<feature-step>.md
│ └── task-R2-01-<feature-step>.md
└── reports/
└── red-team-report.md
Artifact legacy bị cấm:
init.jsonspec-state.jsonhydration.md
Task hydration có thể xảy ra trong UI của assistant, nhưng task files vẫn là source of truth. Hydration không được ghi thành markdown artifact.
Flow theo từng phase#
1. Phân tích intent#
/hapo:specs <feature-description> trước tiên quyết định request đã đủ sẵn sàng để viết spec chưa.
Nó nên route sang /hapo:brainstorm khi output còn mơ hồ, architecture còn nhiều lựa chọn, scope boundary chưa rõ, acceptance criteria thiếu, hoặc work trải qua nhiều subsystem độc lập.
Với thay đổi rất nhỏ một file, CafeKit có thể cảnh báo rằng spec đầy đủ không cần thiết. SDD nên nghiêm cho feature work có rủi ro, không biến mọi typo thành ceremony.
2. Scan spec đang tồn tại và dependency#
Trước khi tạo artifact mới, CafeKit scan specs/ để tìm spec chưa xong và scope overlap.
Mục tiêu là tránh hai spec cùng đụng một file, contract, migration, command, hoặc runtime surface. Nếu có dependency, quan hệ đó nên được ghi trong spec.json để thứ tự implementation rõ ràng.
3. Đánh giá complexity và khóa scope#
CafeKit đánh giá request qua intent, giả thuyết implementation, gap size, risk, và blast radius.
Output là scope_lock:
| Scope lock field | Ý nghĩa |
|---|---|
source | Request gốc hoặc approved design summary. |
in_scope | Behavior spec được phép deliver. |
out_of_scope | Behavior assistant không được tự thêm. |
expansion_policy | Thường là requires-user-approval. |
Sau khi scope đã chốt, assistant không được âm thầm mở rộng, thu hẹp, hoặc diễn giải lại. Nếu cần đổi scope, phải update spec trước, không xử lý lén trong implementation.
4. Tạo spec.json#
spec.json là machine-readable state file. Nó theo dõi status, current phase, approvals, scope, design context, task files, task registry, timestamps, và readiness.
Field quan trọng:
| Field | Vì sao quan trọng |
|---|---|
status | Canonical values gồm in_progress, blocked, done, archived. Spec mới không nên emit legacy in-progress. |
current_phase | Cho biết spec đang ở init, requirements, design, tasks, develop, test, hoặc review. |
scope_lock | Chặn hidden scope change trong specs và implementation. |
task_files | Phải khớp chính xác file thật dưới tasks/. |
task_registry | Machine state cho từng task file. |
ready_for_implementation | Hard gate; chỉ true khi approvals, registry sync, validation, và task readiness đều pass. |
5. Viết evidence trước requirements cuối cùng#
Với spec không trivial, research.md phải tồn tại trước khi finalize requirements, design, hoặc tasks.
Evidence có thể là:
- targeted codebase scout findings
- official/current external docs
- constraint từ package/runtime files
- skip rationale rõ ràng cho docs-only hoặc work cô lập
Evidence Summary nên ghi:
- codebase scout result
- external research result hoặc skip rationale
- selected decision
- rejected alternatives
- remaining gaps
- downstream task/test implications
Mục tiêu là không viết requirements bằng trí nhớ khi repo hoặc upstream docs có thể trả lời.
6. Viết requirements#
requirements.md biến intent thành behavior testable. Requirement nên dùng numeric IDs và acceptance criteria đủ rõ để verify.
Requirement tốt cần:
- singular
- unambiguous
- testable
- map được sang task
- nêu rõ non-functional needs như security, performance, reliability, accessibility, migration, rollback
Nếu một requirement không verify được, nó chưa sẵn sàng để thành implementation work.
7. Viết design contracts#
design.md giải thích feature sẽ được build thế nào. Nó không chỉ nói "implement feature"; nó phải khóa các quyết định mà implementation sau này phải giữ.
Với auth, session, transport, persistence, schemas, generated artifacts, commands, package exports, hoặc runtime-sensitive work, design phải có canonical contracts và invariants. Đây là những rule /hapo:develop không được âm thầm thay thế.
| Contract type | Cần nêu rõ |
|---|---|
| Runtime entrypoint | route, command, worker, provider, hook, API boundary, UI mount. |
| Persistence | schema, migration, datastore, deletion/retention policy. |
| Transport | request/response shape, event contract, queue topic, CLI args. |
| Integration | output từ task trước phải được import, mount, register, invoke thế nào. |
| Testing | unit, integration, E2E, visual, accessibility, smoke, security, performance proof. |
8. Chia thành task packets#
CafeKit không đưa cho /hapo:develop một feature mơ hồ. Nó đưa task packets.
Task file dùng naming:
tasks/task-R{N}-{SEQ}-<slug>.md
R0 dành cho shared foundation. R1+ là feature clusters. Sequence phải có hai chữ số.
Mỗi task phải tự đủ context:
| Task section | Vai trò |
|---|---|
Context | Vì sao task tồn tại và target outcome là gì. |
Constraints | MUST, SHOULD, MUST NOT, scope guardrails. |
Steps | Checklist implementation đủ chi tiết để làm. |
Requirements | Requirement IDs và acceptance criteria được cover. |
Related Files | Path chính xác khi biết; nếu chưa biết thì scout trước khi finalize. |
Completion Criteria | Check quan sát được để chứng minh complete. |
Evidence | Command, artifact proof, runtime proof, negative-path proof, reachability proof. |
Risk Assessment | Risk, severity, mitigation. |
Task vague là invalid. Junior developer hoặc AI coding agent phải có thể làm task mà không đoán.
9. Build task_registry#
spec.json.task_registry được keyed bằng task file path.
Status values:
pendingin_progressblockeddone
Mỗi registry entry cần:
idtitlestatusdependenciesblockerstarted_atcompleted_atlast_updated_at
done là illegal nếu thiếu verification evidence mới. Nếu thiếu proof, task giữ pending, in_progress, hoặc blocked.
10. Validate readiness#
Trước implementation, chạy:
node .claude/scripts/validate-spec-output.cjs specs/<feature>
Validator kiểm tra artifact shape, forbidden files, task path naming, required task sections, requirement coverage, task file inventory, task_registry, và readiness consistency.
scope_lock is an object and scope expansion requires explicit approval.
research.md has an Evidence Summary or a justified skip rationale.
spec.json task_files exactly matches the tasks/ directory.
task_registry has one complete entry for every task file.
Completion Criteria and Evidence are specific enough to execute.
node .claude/scripts/validate-spec-output.cjs specs/<feature> exits cleanly.
ready_for_implementation = true chỉ hợp lệ khi spec structurally valid, approvals xong, task files và registry khớp disk, validation requirements thỏa, và tasks có evidence expectations executable.
/hapo:develop dùng spec thế nào#
/hapo:develop không phải "bắt đầu code từ toàn bộ ý tưởng". Nó là task executor.
Hai mode:
| Mode | Command | Behavior |
|---|---|---|
| Specific-task mode | /hapo:develop <feature> <task-file> | Load đúng một task packet, implement, verify, sync, rồi dừng. |
| Full-spec mode | /hapo:develop <feature> | Build queue từ task_registry, chọn next pending unblocked task, chạy full loop, rồi đọc lại state. |
Trước khi code, develop phải extract:
- objective và constraints
- related files
- completion criteria
- evidence commands
- requirement IDs
- named technologies và runtime choices
- design contracts và invariants
- prior task outputs cần consume
Sau đó nó scout entrypoint và caller thật. Runtime-facing code chưa done nếu chỉ là orphan file. Nó phải được import, mount, register, invoke, hoặc reachable từ runtime boundary thật.
Quality gate sau implementation#
Một task chỉ complete khi bốn lớp proof đều pass:
| Layer | Điều phải đúng |
|---|---|
| Automated verification | Compile/typecheck/build và exact task evidence commands pass. |
| Spec compliance | Scoped requirements và design contracts đã implement, không thiếu, không dư. |
| Code review | Không có blocking correctness, security, architecture, hoặc regression findings. |
| Task evidence | Runtime/artifact proof, reachability, negative paths khớp Evidence section. |
NO_TESTS không phải pass. Command exit 0 nhưng zero tests cũng không phải pass. Build success đơn lẻ không đủ proof cho user-facing hoặc runtime-facing work.
Routine SDD thực tế#
/hapo:specs <approved idea>
node .claude/scripts/validate-spec-output.cjs specs/<feature>
/hapo:develop <feature> <task-file>
/hapo:test <feature>
/hapo:code-review --pending
/hapo:sync <feature> <task-file> done
Dùng /hapo:brainstorm <idea> trước routine này chỉ khi idea chưa đủ rõ để viết specs.
Với spec lớn, ưu tiên mỗi session một task. Diff nhỏ giúp evidence, review, và rollback dễ hơn.
Khi nào nên dùng SDD#
Dùng full SDD path khi work đổi product behavior, chạm nhiều file, đi qua runtime boundary, update auth/data/schema/package contracts, ảnh hưởng user, cần review evidence, hoặc sẽ handoff giữa người/assistant/session.
Skip hoặc rút gọn khi change thật sự trivial: typo, copy edit cô lập, config một dòng, hoặc emergency fix thuộc /hapo:hotfix.
Ý tưởng cốt lõi#
CafeKit SDD là forcing function:
- intent thành scope
- scope thành requirements
- requirements thành design contracts
- design thành task packets
- task packets thành verified code
- verified code thành synchronized state
Đó là trọng tâm của CafeKit. Assistant không thành công vì code nhanh. Assistant thành công khi code khớp approved spec, reachable trong hệ thống thật, có evidence, pass review, và để lại state chính xác cho lần chạy tiếp theo.