Vòng đời spec
Specification-driven development

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.

Spec-driven development loop

CafeKit keeps the assistant moving through persistent contracts instead of relying on chat memory.

01
/hapo:specs

Evidence

Gather codebase and external evidence before requirements or design are finalized.

02
requirements + design

Contract

Lock behavior, constraints, canonical contracts, traceability, and out-of-scope boundaries.

03
tasks/task-R*.md

Task packets

Split work into self-contained packets with related files, criteria, dependencies, and evidence.

04
validate-spec-output.cjs

Readiness

Deterministic validation must pass before ready_for_implementation can be true.

05
/hapo:develop

Develop

Implement one unblocked task after task-aware inspection of real entrypoints and blast radius.

06
/hapo:test + /hapo:code-review

Proof

Run exact evidence commands, prove reachability, and reject scope drift or hidden placeholders.

07
/hapo:sync

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
Owns
Must contain
spec.json
Machine state
status, current_phase, scope_lock, approvals, task_files, task_registry, readiness flags
requirements.md
Behavior contract
numeric requirement IDs, EARS-style acceptance criteria, constraints, NFRs
research.md
Evidence record
codebase scout, external research or skip rationale, decision, rejected alternatives
design.md
Implementation contract
architecture, canonical contracts, invariants, traceability, risk, test strategy
tasks/task-R*.md
Execution packets
context, constraints, related files, dependencies, steps, completion criteria, evidence
reports/
Review trail
optional research, validation, red-team, and review reports for high-risk specs

Artifact legacy bị cấm:

  • init.json
  • spec-state.json
  • hydration.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
sourceRequest gốc hoặc approved design summary.
in_scopeBehavior spec được phép deliver.
out_of_scopeBehavior assistant không được tự thêm.
expansion_policyThườ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:

FieldVì sao quan trọng
statusCanonical values gồm in_progress, blocked, done, archived. Spec mới không nên emit legacy in-progress.
current_phaseCho biết spec đang ở init, requirements, design, tasks, develop, test, hoặc review.
scope_lockChặn hidden scope change trong specs và implementation.
task_filesPhải khớp chính xác file thật dưới tasks/.
task_registryMachine state cho từng task file.
ready_for_implementationHard 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 typeCần nêu rõ
Runtime entrypointroute, command, worker, provider, hook, API boundary, UI mount.
Persistenceschema, migration, datastore, deletion/retention policy.
Transportrequest/response shape, event contract, queue topic, CLI args.
Integrationoutput từ task trước phải được import, mount, register, invoke thế nào.
Testingunit, 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 sectionVai trò
ContextVì sao task tồn tại và target outcome là gì.
ConstraintsMUST, SHOULD, MUST NOT, scope guardrails.
StepsChecklist implementation đủ chi tiết để làm.
RequirementsRequirement IDs và acceptance criteria được cover.
Related FilesPath chính xác khi biết; nếu chưa biết thì scout trước khi finalize.
Completion CriteriaCheck quan sát được để chứng minh complete.
EvidenceCommand, artifact proof, runtime proof, negative-path proof, reachability proof.
Risk AssessmentRisk, 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:

  • pending
  • in_progress
  • blocked
  • done

Mỗi registry entry cần:

  • id
  • title
  • status
  • dependencies
  • blocker
  • started_at
  • completed_at
  • last_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 is locked

scope_lock is an object and scope expansion requires explicit approval.

Evidence exists

research.md has an Evidence Summary or a justified skip rationale.

Tasks are real files

spec.json task_files exactly matches the tasks/ directory.

Registry is synced

task_registry has one complete entry for every task file.

Every task proves done

Completion Criteria and Evidence are specific enough to execute.

Validator passes

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:

ModeCommandBehavior
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 verificationCompile/typecheck/build và exact task evidence commands pass.
Spec complianceScoped requirements và design contracts đã implement, không thiếu, không dư.
Code reviewKhông có blocking correctness, security, architecture, hoặc regression findings.
Task evidenceRuntime/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.