spec-driven
อาร์ติแฟกต์ของเวิร์กโฟลว์เริ่มต้น: ลำดับ รูปแบบ และโฟลเดอร์การเปลี่ยนแปลงที่สร้างขึ้น
spec-driven เป็นสคีมาเริ่มต้นที่มีมาในตัวของ OpenSpec schema.yaml กำหนดฟิลด์ที่สคีมานี้ตั้งค่าไว้
อาร์ติแฟกต์
เวิร์กโฟลว์จะร่างอาร์ติแฟกต์สี่รายการ:
| อาร์ติแฟกต์ | ไฟล์ | วัตถุประสงค์ |
|---|---|---|
proposal | proposal.md | เหตุผลที่จำเป็นต้องมีการเปลี่ยนแปลง |
specs | specs/<capability-path>/spec.md, หนึ่งรายการต่อความสามารถ | พฤติกรรมใดที่เปลี่ยนแปลง |
design | design.md | วิธีการสร้าง |
tasks | tasks.md | รายการตรวจสอบการนำไปใช้งาน |
ลำดับการจัดทำ
┌─ specs ──┐
proposal ────┤ ├── tasks ── apply
└─ design ─┘Proposal ต้องจัดทำเป็นอันดับแรก Specs และ design สามารถจัดทำตามลำดับใดก็ได้ แต่ tasks ต้องมีทั้ง specs และ design จึงจะดำเนินการต่อได้ การนำไปใช้งาน (apply) จะเริ่มต้นเมื่อ tasks.md พร้อมแล้ว
ชิ้นงาน 2 รายการที่สามารถข้ามไปได้อันได้:
design: เมื่อเงื่อนไข ทั้งของ design ไม่ได้ส่งผลกับคุณ จะดำเนินการข้ามไป โดยจะจัดทำtasksไว้ก่อนตามปกติspecs: ตั้งค่าskip_specs: trueใน.openspec.yamlของการเปลี่ยนแปลงนั้น
ตัวอย่างโฟลเดอร์การเปลี่ยนแปลง
การเปลี่ยนแปลงชื่อ add-user-auth โดยจะจัดทำชิ้นงานทั้งหมด:
openspec/changes/add-user-auth/
├── .openspec.yaml change metadata, written when the change is created
├── proposal.md
├── specs/
│ └── user-auth/
│ └── spec.md one delta spec per capability
├── design.md
└── tasks.mdproposal.md
กำหนดให้เหตุผลว่าทำไมการเปลี่ยนแปลงนี้จำเป็นต้องมี
โครงสร้าง
แม่แบบที่เอเจนต์รับในการจัดทำรูปแบบผลลัพธ์ (templates/proposal.md):
# Proposal
## Why
<!-- Explain the motivation for this change. What problem does this solve? Why now? -->
## What Changes
<!-- Describe what will change. Be specific about new capabilities, modifications, or removals. -->
## Capabilities
### New Capabilities
<!-- Capabilities being introduced. Name each capability for a cohesive system
behavior that can own related requirements as the system evolves. Do not name
implementation tasks or proposal sections. Avoid broad catch-all names. Use
kebab-case for path segments you introduce (e.g., user-auth or identity/user-auth)
that follow the project's existing spec organization. Each creates
specs/<capability-path>/spec.md. -->
- `<capability-path>`: <brief description of what this capability covers>
### Modified Capabilities
<!-- Existing capabilities whose REQUIREMENTS are changing (not just implementation).
Only list here if spec-level behavior changes. Each needs a delta spec file.
Use the exact existing path under openspec/specs/. Leave empty if no requirement
changes. A change with no capabilities at all (pure refactor, tooling, docs)
must set `skip_specs: true` in its .openspec.yaml - openspec validate rejects
a zero-delta change without that marker. Do not invent a requirement just to
satisfy validation. -->
- `<existing-capability-path>`: <what requirement is changing>
## Impact
<!-- Affected code, APIs, dependencies, systems -->คำแนะนำ
คำแนะนำที่ส่งต่อให้กับเอเจนต์เมื่อจัดทำชิ้นงานนี้ (จาก schema.yaml):
สร้างเอกสาร proposal ที่ให้เหตุผลว่าทำไมการเปลี่ยนแปลงนี้จำเป็นต้องมี
ส่วนต่าง ๆ:
- **Why**: ประโยค 1-2 ที่อธิบายปัญหาหรือโอกาส การเปลี่ยนแปลงนี้แก้ปัญหาอะไร ทำไมต้องตอนนี้
- **What Changes**: รายการสิ่งที่เปลี่ยนแปลง สิ่งใหม่ การปรับปรุง หรือการกำจัด และต้องชัดเจน การเปลี่ยนแปลงที่กระทบให้ระบุ **BREAKING**
- **Capabilities**: ระบุ spec ที่จะสร้างหรือแก้ไข:
- **New Capabilities**: รายการความสามารถใหม่แต่ละรายการจะสร้างเป็น `specs/<capability-path>/spec.md` ใหม่ ระบุแต่ละความสามารถโดยพฤติกรรมที่คงความมั่นคงของระบบไม่ใช่การทำงานที่แก้ไขในครั้ง เช่น `user-auth` ไม่ใช่ `add-login-endpoint` กำหนดขอบเขตที่สอดคล้องกันเพื่อให้สามารถจัดการข้อกำหนดที่เกี่ยวข้องได้เมื่อระบบพัฒนาต่อไป หลีกเลี่ยงคำกว้าง ๆ ใช้ kebab-case สำหรับ path segment ใหม่ เช่น `user-auth` หรือ `identity/user-auth` ตามโครงสร้าง spec ที่มีอยู่ของโปรเจกต์
- **Modified Capabilities**: รายการความสามารถที่มีอยู่โดย REQUIREMENTS มีการเปลี่ยนแปลง ระบุเฉพาะเมื่อพฤติกรรมระดับ spec เปลี่ยน (ไม่ใช่รายละเอียดของ implementation) ต้องมี delta spec file ใช้ path ที่มีอยู่จาก `openspec/specs/` หากไม่มี requirement ที่เปลี่ยนแปลงให้ค่าว่าง
- **Impact**: โค้ด API dependency หรือระบบที่เกี่ยวข้อง
สำคัญ: ส่วน Capabilities เป็นตัวกำหนดข้อผูกพัน
ระหว่างช่วง proposal และ specs ก่อนระบุควรตรวจสอบ
spec ที่มีอยู่ของโปรเจกต์ด้วย:
รัน `openspec list --specs` เป็นรายการความสามารถของโปรเจกต์ แล้ว
ใช้ `openspec show "<spec-id>" --type spec --json --no-scenarios` เมื่อต้องการ
รายละเอียดของความสามารถและข้อความ requirements โดยไม่ต้องโหลด
file spec ทั้งหมดขึ้น context เพิ่ม `--store "<id>"` ทั้งสองคำสั่งได้
เฉพาะที่ลงทะเบียน standalone store และคง `--type
spec` ไว้ เพราะการให้ชื่อเหมือนกันจะสร้าง error ว่าเป็นรายการกำกวม
`openspec list` โดยไม่มี `--specs` เป็นรายการการเปลี่ยนแปลงที่ดำเนินการ
ไม่ใช้ spec - ไม่เคยแสดงรายการที่มีอยู่ของโปรเจกต์
ใช้ path ที่แน่นอนของความสามารถที่มีอยู่แทนการตั้งชื่อใหม่
การอ่านแบบกรองเป็นการสรุปภาพรวม ก่อนกำหนดว่าการเปลี่ยนแปลง
มีหรือไม่ควรแก้ไข spec แต่ละอันที่ที่เกี่ยวข้องต้องอ่าน
เต็ม ๆ มี scenario ด้วย `openspec show "<spec-id>" --type spec` (เช่นเดิม
ใช้ `--store`)
ความสามารถที่ระบุทุก ๆ รายการต้องมี spec file
การเปลี่ยนแปลงแต่ละรายการต้องระบุความสามารถอย่างน้อยหนึ่งรายการ
(ใหม่หรือแก้ไข) หรือปฏิเสธ spec โดยตรง: `openspec validate` จะปฏิเสธ
การเปลี่ยนแปลงที่ delta เป็นศูนย์ถ้า `.openspec.yaml` ไม่ได้
ตั้งค่า `skip_specs: true` ตั้งค่า `skip_specs: true` เท่านั้นเมื่อ
ไม่มีพฤติกรรมระดับ spec (refactor, tooling, docs) - spec อธิบาย
พฤติกรรม ดังนั้นถ้าพฤติกรรมไม่เปลี่ยน spec ก็ไม่ควรเปลี่ยน
อย่าสร้าง requirement ขึ้นมาเฉพาะเพื่อผ่าน validation
ให้กระชับ (1-2 หน้า) เน้นที่ "ทำไม" ไม่ "อย่างไร" -
รายละเอียด implementation อยู่ใน design.md
นี่คือพื้นฐาน - specs, design และ tasks ทั้งหมดสร้างจากจุดนี้Delta specs (spec.md)
ระบุพฤติกรรมที่เปลี่ยนแปลง มี delta spec หนึ่งตัวต่อแต่ละความสามารถที่ proposal ระบุ
แต่ละ delta spec อยู่ใน spec.md ภายในโฟลเดอร์ความความสามารถของมัน openspec validate และ openspec archive จะปฏิเสธ delta section ที่เขียนในไฟล์อื่นภายใต้ specs/ เช่น specs/user-auth.md เพราะ archive ไม่จะ merge
โครงสร้าง
แม่แบบที่เอเจนต์รับในการจัดทำรูปแบบผลลัพธ์ (templates/spec.md):
# Spec Delta
## Purpose
<!-- New capabilities only: one or two sentences (50+ characters) on what this capability is for. Delete this section for an existing capability. -->
## ADDED Requirements
### Requirement: <!-- requirement name -->
<!-- requirement text -->
#### Scenario: <!-- scenario name -->
- **WHEN** <!-- condition -->
- **THEN** <!-- expected outcome -->คำแนะนำ
คำแนะนำที่ส่งต่อให้กับเอเจนต์เมื่อจัดทำชิ้นงานนี้ (จาก schema.yaml):
สร้าง spec file ที่ระบุสิ่งที่ระบบต้องทำได้
Spec เป็น contract ของพฤติกรรม ไม่ใช่แผนการดำเนินงาน
เนื้อหาที่ควรอยู่ใน spec:
- พฤติกรรมของระบบที่ผู้ใช้หรือระบบอื่น ๆ พึ่งพามา
- อินพุต เอาต์พุต และเงื่อนไขของความผิดพลาด
- ข้อจำกัดภายนอก (ความปลอดภัย ความเชื่อมั่น เสถียรภาพ ความเข้ากันได้)
- Scenarios ที่สามารถทดสอบหรือตรวจสอบได้
สิ่งที่ควรหลีกเลี่ยงใน spec:
- ชื่อ class/function ภายใน
- การเลือก Library หรือ framework
- รายละเอียดการดำเนินงานทีละขั้นตอน
- แผนการดำเนินการเชิงลึก (อยู่ design.md หรือ tasks.md)
ทดสอบง่าย ๆ: ถ้าการดำเนินงานสามารถเปลี่ยนแปลงได้โดยไม่ต้องเปลี่ยน
พฤติกรรมภายนอกที่เห็นได้ก็ไม่น่าจะอยู่ใน spec
สร้าง spec file หนึ่งตัวต่อแต่ละความสามารถที่ระบุในส่วนของ Capabilities ของ proposal
`<capability-path>` เป็น spec directory เทียบกับ `specs/` (เช่น
`user-auth` หรือ `identity/user-auth`) ให้คง path ไว้เต็ม ๆ:
- New capabilities: ใช้ path ที่แม่นยำจาก proposal ใน `specs/<capability-path>/spec.md` segment ใหม่ต้องเป็น kebab-case ตามโครงสร้างที่มีอยู่ของโปรเจกต์ ไม่เพิ่มชั้นของพื้นที่ถ้าโปรเจกต์เป็น flat layout
- Modified capabilities: ใช้ path ที่มีอยู่จาก `openspec/specs/<capability-path>/` เมื่อสร้าง delta ใน `specs/<capability-path>/spec.md` รัน `openspec list --specs` เพื่อยืนยัน path ก่อนเขียน เพิ่ม `--store "<id>"` เฉพาะที่ standalone store - path ที่พิมพ์ผิดหรือตั้งขึ้นใหม่อ้างถึงความสามารถที่ไม่มีอยู่จริงไม่ใช่เป้าหมายจริง ไม่เปลี่ยนตำแหน่งหรือตั้งชื่อความสามารถ
เขียน spec file ทีละตัว ให้ผู้ใช้เห็นความคืบหน้าและ
ถ้าถูกหยุดกลางทางการ run จะยังรักษาไฟล์ที่เขียนไว้แล้ว
- ก่อนเขียนอะไร ให้เทียบความสามารถที่ระบุใน
proposal กับไฟล์ `specs/<capability-path>/spec.md` ที่มีอยู่
เริ่มจากความสามารถแรกที่ยังไม่มีไฟล์ ไม่เขียนทับ
ไฟล์ที่มีอยู่เว้นแต่ผู้ใช้ขอ
- ก่อนแต่ละไฟล์ ระบุความสามารถที่เขียนในหนึ่งบรรทัด
- ทันทีที่ร่างเสร็จให้เขียนไฟล์ ไม่วางแผนทุกไฟล์
ก่อนเริ่มไฟล์แรก
- หยุดเมื่อทุกความสามารถที่ระบุใน proposal มีไฟล์แล้ว
ต้องมีอย่างน้อยหนึ่ง spec file เว้นแต่ `.openspec.yaml`
ของ change นั้นตั้ง `skip_specs: true` (ไม่มีพฤติกรรมระดับ spec) - `openspec validate`
จะปฏิเสธการเปลี่ยนแปลง delta เป็นศูนย์ถ้าไม่มีค่า
ถ้าไม่ระบุความสามารถใน proposal และ `skip_specs`
ไม่ได้ตั้ง กลับไปตรวจทาน proposal ก่อน
การดำเนินการ delta (ใช้ ## header):
- **ADDED Requirements**: New capabilities
- **MODIFIED Requirements**: พฤติกรรมที่เปลี่ยน - ต้องระบุเนื้อหา
- **REMOVED Requirements**: Features ที่เลิกใช้ - ต้องระบุ **Reason** และ **Migration**
- **RENAMED Requirements**: เปลี่ยนชื่อ - ใช้รูปแบบ FROM:/TO:
ข้อกำหนดรูปแบบ:
- แต่ละ requirement: `### Requirement: <name>` ตามด้วยคำอธิบาย
- ใช้ SHALL/MUST สำหรับข้อกำหนด (หลีกเลี่ยง should/may)
- แต่ละ scenario: `#### Scenario: <name>` ตามรูปแบบ WHEN/THEN
- **สำคัญ**: Scenario ต้องใช้ # 4 ตัว (`####`) พอดี ใช้ 3 ตัวหรือ bullets จะทำให้ล้มเหลวแบบเงียบ ๆ
- Requirement ทุกตัวต้องมีอย่างน้อยหนึ่ง scenario
- Scenario ทุกตัวต้องมีขั้นตอน WHEN/GIVEN (ตัวกระตุ้น) และขั้นตอน THEN (ผลลัพธ์) ถ้ามีเฉพาะ AND line หรือข้อความธรรมดาจะนับเป็น scenario แต่ `openspec validate` จะแจ้ง
ให้ตรวจสอบ: การตรวจสอบปกติผ่านได้ แต่ `openspec validate --strict` จะไม่ผ่าน
- ให่คำอธิบายแต่ละ requirement (ข้อความระหว่าง `### Requirement:` และ
scenario แรก) ไม่เกิน 500 ตัวอักษร `openspec validate`
จะแจ้งหากเกินนี้ ADDED requirement และใน main spec
ถ้าเกินค่านี้: การตรวจสอบปกติผ่านได้ แต่ `openspec validate --strict`
จะล้มเหลว เมื่อเขียน requirement ใหม่ ให้ระบุพฤติกรรมหนึ่งต่อ
requirement: ย้ายตัวอย่างและ edge cases ไปที่ scenarios และแยก
requirement ที่มีหลายพฤติกรรมเป็น block `### Requirement:`
แต่ละตัว พร้อม scenario ของตัวเอง ใน MODIFIED
ให้คง requirement block เดิมไว้อย่างสมบูรณ์ ห้ามแยก ตัด หรือ
เขียนใหม่จนเกินความสั้น หากต้องการแยก requirement เดิม
ที่มากเกินไปเฉพาะเมื่อผู้ใช้ขอในการเปลี่ยนแปลงที่มีจุดประสงค์นั้น
ใน MODIFIED คง header และทุก scenario
ตัดคำอธิบายเหลือพฤติกรรมเดียวโดยไม่เปลี่ยนความหมาย
แล้วเพิ่มพฤติกรรมที่ตัดออกเป็น ADDED requirement
แยกแต่ละตัวพร้อม scenarios
เฉพาะ new capabilities: ส่วนแรก
ของ delta spec คือ `## Purpose`
หนึ่งถึงสองประโยค (50+ ตัวอักษร หรือ `openspec validate --strict`
จะแจ้งว่าเป็นสั้นเกินไป) อธิบายความสามารถนี้ใช้ทำอะไร
เมื่อ archive จะนำไปใช้กับ main spec ที่สร้าง; ถ้าไม่มีจะค้าง
`TBD ... Update Purpose after archive` ให้คุณเติมเอง
อย่าเพิ่ม `## Purpose` ให้กับ delta ของความสามารถที่มีอยู่ -
spec นั้นมีแล้วและ delta ของมันจะถูกละเลย
หากต้องการเปลี่ยน Purpose ของความสามารถที่มีอยู่
รวมถึง `TBD` ที่เหลือ
แก้ `<planningHome.root>/openspec/specs/<capability-path>/spec.md`
โดยตรง `planningHome.root` จากคำตอบของ
`openspec instructions ... --json` ใช้เสมอแทน
path เทียบกับ repo: มันจะชี้ไปที่
store ถ้า change อยู่ใน store -
ไม่ว่าจะมาจาก `--store`, เชิงของโปรเจกต์, หรือ default
ของ store - ไม่เช่นนั้นจะชี้ไปที่ repo ปัจจุบัน ไม่ต้องระบุ
กรณีใด ๆ; field นี้ระบุไว้แล้ว
ขั้นตอนการดำเนินการ MODIFIED requirements:
1. หา requirement เดิมใน `<planningHome.root>/openspec/specs/<capability-path>/spec.md` (store-aware root เดิม)
2. คัดลอก requirement block ทั้งหมด (จาก `### Requirement:` ถึง
scenarios ทั้งหมด)
3. วางภายใต้ `## MODIFIED Requirements` และแก้ไขให้แสดงพฤติกรรมใหม่
4. ตรวจสอบว่า header ตรงกัน (ไม่สนใจ whitespace)
จุดพลาดที่พบบ่อย: ใช้ MODIFIED กับเนื้อหารายการทำให้รายละเอียด
หายไปตอน archive
หากเพิ่ม concern ใหม่โดยไม่เปลี่ยนพฤติกรรมที่มีอยู่ ให้ใช้ ADDED แทน
ตัวอย่าง (New capabilities ส่วนแรกจึงเป็น `## Purpose`):
```
# Spec Delta
## วัตถุประสงค์
อนุญาตให้ผู้ใช้ส่งออกข้อมูลของตนออกจากผลิตภัณฑ์ในรูปแบบที่พกพาได้
## ข้อกำหนดที่เพิ่มเข้ามา (ADDED)
### ข้อกำหนด: ผู้ใช้สามารถส่งออกข้อมูลได้
ระบบจะต้องอนุญาตให้ผู้ใช้ส่งออกข้อมูลของตนในรูปแบบ CSV
#### สถานการณ์: การส่งออกสำเร็จ
- **เมื่อ** ผู้ใช้คลิกปุ่ม "Export" (ส่งออก)
- **แล้ว** ระบบจะดาวน์โหลดไฟล์ CSV ที่มีข้อมูลของผู้ใช้ทั้งหมด
## ข้อกำหนดที่ถูกนำออก (REMOVED)
### ข้อกำหนด: การส่งออกแบบเดิม (Legacy export)
**เหตุผล**: ถูกแทนที่ด้วยระบบการส่งออกใหม่
**การย้ายข้อมูล**: ใช้จุดปลาย (endpoint) การส่งออกใหม่ที่ `/api/v2/export`
```
สเปคควรทดสอบได้ - แต่ละสถานการณ์เป็นกรณีทดสอบที่เป็นไปได้design.md
อธิบายวิธีการเปลี่ยนแปลงนี้ให้ดำเนินการอย่างไร เขียนขึ้นเฉพาะเมื่อการเปลี่ยนแปลงนั้นต้องการเอกสารออกแบบเท่านั้น
โครงสร้าง
เทมเพลตที่เอเจนต์ได้รับในรูปแบบเอาต์พุต (templates/design.md):
# Design
## Context
<!-- Current state and constraints that shape the approach. See proposal.md for motivation - don't restate it -->
## Goals / Non-Goals
**Goals:**
<!-- What this design aims to achieve -->
**Non-Goals:**
<!-- What is explicitly out of scope -->
## Decisions
<!-- Key design decisions with rationale and alternatives considered -->
## Risks / Trade-offs
<!-- Known risks and trade-offs -->คำแนะนำ
คำแนะนำที่ส่งไปยังเอเจนต์เมื่อมันร่างเอกสารนี้ (จาก schema.yaml):
Create the design document that explains HOW to implement the change.
When to include design.md (create only if any apply):
- Cross-cutting change (multiple services/modules) or new architectural pattern
- New external dependency or significant data model changes
- Security, performance, or migration complexity
- Ambiguity that benefits from technical decisions before coding
Sections:
- **Context**: Only the current state and constraints needed to explain the approach. Reference the proposal for motivation instead of restating it (e.g., "See proposal.md - Why").
- **Goals / Non-Goals**: What this design achieves and explicitly excludes. Don't restate the proposal's scope - add only design-level boundaries.
- **Decisions**: Key technical choices with rationale (why X over Y?). Include alternatives considered for each decision.
- **Risks / Trade-offs**: Known limitations, things that could go wrong. Format: [Risk] → Mitigation
- **Migration Plan**: Steps to deploy, rollback strategy (if applicable)
- **Open Questions**: Unknowns that can safely be answered later without
changing the specs, the approach, or the task breakdown. Omit if none.
Open questions are for genuinely deferrable unknowns, not decisions you
skipped. If a question would change the specs, the chosen approach, or
the task breakdown, resolve it now - ask the user instead of guessing.
Focus on architecture and approach, not line-by-line implementation.
The proposal covers why and what; design covers how. Reference the
proposal for motivation and, once written, the specs for requirements -
if a section would only restate them, point to them instead.
Good design docs explain the "why" behind technical decisions.tasks.md
แบ่งการทำงานด้านการพัฒนาออกเป็นงานที่สามารถตรวจสอบได้ apply จะติดตามความคืบหน้าในส่วนนี้
โครงสร้าง
เทมเพลตที่เอเจนต์ได้รับในรูปแบบเอาต์พุต (templates/tasks.md):
# Tasks
## 1. <!-- Task Group Name -->
- [ ] 1.1 <!-- Task description -->
- [ ] 1.2 <!-- Task description -->
## 2. <!-- Task Group Name -->
- [ ] 2.1 <!-- Task description -->
- [ ] 2.2 <!-- Task description -->คำแนะนำ
คำแนะนำที่ส่งไปยังเอเจนต์เมื่อมันร่างเอกสารนี้ (จาก schema.yaml):
Create the task list that breaks down the implementation work.
Before writing tasks, check design.md for Open Questions. If any of them
would change what gets built, resolve them with the user first - do not
bake an unstated assumption into the task list.
**IMPORTANT: Follow the template below for tracked tasks.** The apply phase parses
checkbox format to track progress. A box holding only `x` counts as done,
upper or lower case and with any spacing, so `- [ x]` is done too. Every
other marker, including `- [~]`, `- [-]` and an empty `- []`, reads as
unfinished. A line with no checkbox is not tracked at all.
Guidelines:
- Group related tracked tasks under ## numbered headings
- Each tracked task MUST be a checkbox: `- [ ] X.Y Task description`
- Tasks should be small enough to complete in one session
- Order tasks by dependency (what must be done first?)
- Track implementation and verification work that can be completed before
archive. If the requested workflow includes archive or work that requires
this change to be archived, preserve those steps as plain bullets in an
optional `## Workflow follow-up` section at the end of tasks.md. These
bullets are reference information outside tracked task progress.
- Each task MUST state how to verify completion (a test, command,
observable behavior, or delivered artifact). Put the verification in
that task's checkbox description. Use a separate verification task only
when it checks broader integration or system behavior that spans
multiple implementation tasks.
- Each task group MUST land the tests and documentation its own work
calls for. Do NOT collect testing or documentation into a final group -
when a late group first exercises work from an early one, the failures
cascade back through every group in between and force rework. A group
whose work calls for neither, such as scaffolding or dependency setup,
carries neither. A final group is for integration checks only, not for
the tests and docs an earlier group owed.
Example:
```
# Tasks
## 1. Setup
- [ ] 1.1 Create new module structure and verify expected files are present
- [ ] 1.2 Add dependencies to package.json and verify package installation succeeds
## 2. Core Implementation
- [ ] 2.1 Implement data export function and verify the export test passes
- [ ] 2.2 Add CSV formatting utilities and verify unit tests cover quoting and delimiters
- [ ] 2.3 Document the export API in docs/export.md and verify the documented command runs as written
```
When applicable, append workflow follow-up as plain bullets, for example:
```
## Workflow follow-up
- Archive the change after the project's review requirements are satisfied.
- Verify the archived result.
```
Reference specs for what needs to be built, design for how to build it.Apply
ขั้นตอนการส่งต่อจากการวางแผนไปสู่การพัฒนาจริง Apply เป็นเฟสที่ทำงานผ่าน tasks.md ไม่ใช่เอกสาร (artifact)
- เริ่มต้น: เมื่อ
tasks.mdมีอยู่และระบุอย่างน้อยหนึ่งงาน - ติดตาม: กล่องกาเครื่องหมาย (checkboxes) ใน
tasks.mdการทำเครื่องหมายถูกเป็นบันทึกความคืบหน้า - สิ้นสุด: เมื่อกล่องกาเครื่องหมายทุกช่องถูกทำเครื่องหมายครบ OpenSpec จะแนะนำให้ทำการเก็บถาวร (archive) การเปลี่ยนแปลงนั้น
การตั้งค่า
การตั้งค่าของ apply (จาก schema.yaml):
apply:
requires: [tasks]
tracks: tasks.md
# instruction: shown belowคำแนะนำ
คำแนะนำที่ส่งไปยังเอเจนต์เมื่อเริ่มการพัฒนา (จาก schema.yaml):
Read context files, work through pending tasks, mark complete as you go.
Pause if you hit blockers or need clarification.schema.yaml
schema.yaml แบบสมบูรณ์ โดยตัดเนื้อหาคำแนะนำออก แต่ละส่วนแสดงอย่างเต็มรูปแบบในหัวข้อที่เกี่ยวข้องด้านบน
name: spec-driven
version: 1
description: Default OpenSpec workflow - proposal → specs → design → tasks
artifacts:
- id: proposal
generates: proposal.md
description: Initial proposal document outlining the change
template: proposal.md
# instruction: shown in full under proposal.md above
requires: []
- id: specs
generates: "specs/**/*.md"
description: Detailed specifications for the change
template: spec.md
# instruction: shown in full under Delta specs above
requires:
- proposal
- id: design
generates: design.md
description: Technical design document with implementation details
template: design.md
# instruction: shown in full under design.md above
requires:
- proposal
- id: tasks
generates: tasks.md
description: Implementation checklist with trackable tasks
template: tasks.md
# instruction: shown in full under tasks.md above
requires:
- specs
- design
apply:
requires: [tasks]
tracks: tasks.md
# instruction: shown in full under Apply above