Kilo Code: Mastering Spec-Driven Development (SDD)

Kilo Code: Mastering Spec-Driven Development (SDD)

In our previous post, we explored Codebase Indexing and how Kilo Code builds a semantic map of your repository. Now, it’s time to use that power effectively.

Kilo Code Deep Dive Series

This comprehensive series covers Kilo Code (kiro.dev) - the AI-first agentic development platform:

✓ 12 parts complete!

Spec-driven development workflow diagram Spec-Driven Development ensures AI-generated code aligns with your requirements

Most developers fall into the trap of “vibe coding”—throwing prompts at an AI and hoping for the best. While fast, this leads to technical debt and “context rot.” Kilo Code solves this through Spec-Driven Development (SDD) using OpenSpec as its underlying framework.

The Problem with Vibe Coding

Vibe coding is the AI equivalent of coding without a plan:

Developer: "Add user authentication"
AI: *generates some code*
Developer: "Hmm, not quite. Also add password reset."
AI: *generates more code*
Developer: "Wait, now the login is broken. Fix it."
AI: *patches things*
Developer: "Oh, and we need OAuth too..."
AI: *adds OAuth, breaks something else*

Result: Spaghetti code, inconsistent patterns, hidden bugs

Common Vibe Coding Anti-Patterns

Anti-Pattern Description Consequence
Incremental Drift Requirements change mid-stream Inconsistent architecture
Context Amnesia AI forgets earlier decisions Contradictory implementations
Patchwork Code Fixes layered on fixes Technical debt accumulation
Missing Tests Focus on features, not quality Unreliable code
No Documentation No spec means no docs Knowledge loss

What is Spec-Driven Development?

Spec-Driven Development (SDD) flips the workflow:

Traditional AI Coding (Vibe):
Prompt → Code → Hope → Debug → More Code → ???

Spec-Driven Development (OpenSpec):
Requirements → Spec → Proposal → Tasks → Code → Verify → Archive → Done

The SDD Workflow with OpenSpec

┌─────────────────────────────────────────────────────────────┐
│              SPEC-DRIVEN WORKFLOW (OpenSpec)├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. INITIALIZATION                                          │
│     openspec init                                           │
│     └─→ Creates openspec/ directory structure               │
│                                                             │
│  2. PROPOSAL                                                │
│     /openspec:proposal or /openspec-proposal.md            │
│     └─→ Creates proposal.md, design.md, tasks.md            │
│                                                             │
│  3. APPLY                                                   │
│     /openspec:apply <change-id>                             │
│     └─→ AI implements tasks from tasks.md                   │
│                                                             │
│  4. ARCHIVE                                                 │
│     /openspec:archive <change-id> --yes                     │
│     └─→ Merges spec deltas, cleans workspace                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

OpenSpec Folder Structure

When you initialize OpenSpec, it creates this structure:

project-root/
├── openspec/
│   ├── AGENTS.md              # AI agent instructions
│   ├── project.md             # Project context & tech stack
│   ├── specs/                 # Source of truth (current specs)
│   │   ├── auth-login/
│   │   │   └── spec.md
│   │   └── payment/
│   │       └── spec.md
│   └── changes/               # Active changes
│       ├── add-user-auth/     # Change folders
│       │   ├── proposal.md
│       │   ├── design.md
│       │   ├── tasks.md
│       │   └── specs/         # Spec deltas
│       └── archive/           # Completed changes
│           └── 2026-03-30-add-user-auth/
├── .kilocode/
│   └── workflows/             # Kilo Code workflow definitions
└── .cursor/
    ├── skills/
    └── commands/

Key differences from the article’s earlier references:

  • Specs live in openspec/specs/<module-name>/spec.md
  • Tasks are in openspec/changes/<change-id>/tasks.md (not a global tasks folder)
  • Changes are proposed in openspec/changes/<change-id>/
  • Kilo Code uses .kilocode/workflows/ for workflow definitions

Step 1: Initialize OpenSpec

Before starting spec-driven development, initialize OpenSpec in your project:

# Install OpenSpec globally
npm install -g @fission-ai/openspec@latest

# Verify installation
openspec --version

# Initialize in your project (interactive)
openspec init

# Or initialize with specific tools (non-interactive)
openspec init --tools claude,cursor,kilocode

This creates the openspec/ directory structure and configures AI tool integrations.


Step 2: Gathering Requirements

Before writing any spec, you need clear requirements. Kilo Code can help extract and clarify requirements through conversation.

Starting the Conversation

User: "I want to add a feature to our e-commerce app"

Kilo Code (Spec Mode):
I'll help you define the requirements. Let's start with some questions:

1. What specific feature do you want to add?
   - Product reviews?
   - Wishlist functionality?
   - Recommendation engine?
   - Something else?

2. Who are the primary users of this feature?
   - Customers?
   - Admins?
   - Both?

3. What are the must-have capabilities?
   - Create, read, update, delete?
   - Moderation workflow?
   - Integration with other systems?

4. Any technical constraints?
   - Must use existing database?
   - Performance requirements?
   - Security considerations?

Requirements Template

Kilo Code can generate a structured requirements document:

# Feature Requirements: Product Reviews

## 1. Overview
Allow customers to leave reviews and ratings for products they've purchased.

## 2. User Stories

### As a Customer
- I want to leave a review for products I've purchased
- I want to rate products on a 1-5 star scale
- I want to see other customers' reviews before buying
- I want to mark reviews as helpful or not helpful

### As an Admin
- I want to moderate reviews before they're published
- I want to remove inappropriate reviews
- I want to respond to customer reviews
- I want to see review analytics

## 3. Functional Requirements

| ID | Requirement | Priority |
|----|-------------|----------|
| FR-1 | Users can submit reviews with text and rating | Must Have |
| FR-2 | Reviews require purchase verification | Must Have |
| FR-3 | Admins can approve/reject reviews | Must Have |
| FR-4 | Users can edit their own reviews within 24h | Should Have |
| FR-5 | Support image attachments in reviews | Could Have |
| FR-6 | Implement review helpfulness voting | Could Have |

## 4. Non-Functional Requirements

| ID | Requirement | Target |
|----|-------------|--------|
| NFR-1 | Review submission latency | < 500ms |
| NFR-2 | Review display latency | < 200ms |
| NFR-3 | Support 10,000 reviews per product | Scale |
| NFR-4 | Prevent spam and abuse | Security |

## 5. Constraints
- Must use existing PostgreSQL database
- Must integrate with current user authentication
- Must comply with GDPR (data deletion)

Step 3: Creating the Proposal

Once requirements are clear, use Kilo Code’s Proposal Mode to create a detailed change proposal.

Generate the Proposal

In Kilo Code (VSCode), use the slash command:

/openspec:proposal

Or use the alternative prompt file approach:

/openspec-proposal.md

This creates a new change folder with the proposal documents:

openspec/changes/add-product-reviews/
├── proposal.md          # Feature overview & requirements
├── design.md            # Technical architecture
├── tasks.md             # Implementation tasks
└── specs/               # Spec deltas
    └── product-reviews/
        └── spec.md      # New spec (delta: ADDED)

The AI will generate comprehensive documentation:

proposal.md - Feature overview and requirements:

# Proposal: Product Reviews System

## 1. Overview
Allow customers to leave reviews and ratings for products they've purchased.

## 2. User Stories

### As a Customer
- I want to leave a review for products I've purchased
- I want to rate products on a 1-5 star scale
- I want to see other customers' reviews before buying

### As an Admin
- I want to moderate reviews before they're published
- I want to remove inappropriate reviews
- I want to see review analytics

## 3. Functional Requirements

| ID | Requirement | Priority |
|----|-------------|----------|
| FR-1 | Users can submit reviews with text and rating | Must Have |
| FR-2 | Reviews require purchase verification | Must Have |
| FR-3 | Admins can approve/reject reviews | Must Have |
| FR-4 | Users can edit their own reviews within 24h | Should Have |

## 4. Non-Functional Requirements

| ID | Requirement | Target |
|----|-------------|--------|
| NFR-1 | Review submission latency | < 500ms |
| NFR-2 | Review display latency | < 200ms |
| NFR-3 | Support 10,000 reviews per product | Scale |

design.md - Technical architecture:

# Design: Product Reviews System

## 1. System Architecture

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Frontend  │────▶│  API Layer  │────▶│   Review    │
│   (React)   │     │  (Express)  │     │   Service   │
└─────────────┘     └─────────────┘     └─────────────┘
                                       ┌─────────────┐
                                       │  PostgreSQL │
                                       │  Database   │
                                       └─────────────┘

2. Database Schema

-- Reviews table
CREATE TABLE reviews (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id),
    product_id UUID NOT NULL REFERENCES products(id),
    rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
    title VARCHAR(200),
    content TEXT NOT NULL,
    status VARCHAR(20) DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    CONSTRAINT unique_user_product_review UNIQUE (user_id, product_id)
);

-- Review helpfulness votes
CREATE TABLE review_votes (
    review_id UUID REFERENCES reviews(id),
    user_id UUID REFERENCES users(id),
    helpful BOOLEAN NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    PRIMARY KEY (review_id, user_id)
);

-- Indexes for performance
CREATE INDEX idx_reviews_product ON reviews(product_id, status);
CREATE INDEX idx_reviews_user ON reviews(user_id);
CREATE INDEX idx_reviews_created ON reviews(created_at DESC);

3. API Endpoints

Method Endpoint Description Auth
POST /api/reviews Create review User
GET /api/products/:id/reviews Get product reviews Public
GET /api/reviews/:id Get single review Public
PUT /api/reviews/:id Update review User
DELETE /api/reviews/:id Delete review User/Admin
POST /api/reviews/:id/vote Vote on review User
PATCH /api/reviews/:id/status Moderate review Admin

4. Request/Response Examples

Create Review:

POST /api/reviews
{
  "productId": "uuid-here",
  "rating": 5,
  "title": "Great product!",
  "content": "I love this product. Highly recommended."
}

Response: 201 Created
{
  "id": "review-uuid",
  "status": "pending",
  "message": "Review submitted for moderation"
}

5. Validation Rules

const reviewSchema = {
  productId: { type: 'uuid', required: true },
  rating: { type: 'integer', min: 1, max: 5, required: true },
  title: { type: 'string', max: 200, optional: true },
  content: { type: 'string', min: 10, max: 5000, required: true }
};

6. Security Considerations

  1. Purchase Verification: Only allow reviews from verified purchasers
  2. Rate Limiting: Max 3 reviews per user per hour
  3. Content Moderation: Profanity filter and spam detection
  4. XSS Prevention: Sanitize all user input
  5. SQL Injection: Use parameterized queries

7. Testing Strategy

  • Unit tests for service layer (90% coverage)
  • Integration tests for API endpoints
  • E2E tests for critical user flows
  • Load testing for 1000 concurrent users

Shall I proceed with creating the implementation tasks?


---

## Step 4: Task Breakdown

The proposal is approved. Now Kilo Code breaks it into implementable tasks in `tasks.md`.

### Generate Task List

Use the OpenSpec CLI to validate the proposal:

```bash
# Validate the proposal
openspec validate add-product-reviews

# View the generated tasks
openspec show add-product-reviews --type tasks

The tasks are stored in openspec/changes/add-product-reviews/tasks.md:

# Tasks: Product Reviews

## Implementation Plan

### Phase 1: Foundation (Day 1-2)

**Task 1.1: Database Migration**
- [ ] Create migration file for reviews table
- [ ] Create migration file for review_votes table
- [ ] Add indexes for performance
- [ ] Write migration tests
- Acceptance: Migration runs successfully, tables created correctly

**Task 1.2: Review Model**
- [ ] Create Review model/ORM class
- [ ] Add validation logic
- [ ] Add instance methods (calculateHelpfulness, etc.)
- [ ] Add static methods (findByProduct, findByUser)
- Acceptance: Model passes all unit tests

**Task 1.3: Review Service Layer**
- [ ] Create review service class
- [ ] Implement createReview() with purchase verification
- [ ] Implement getReviews() with pagination
- [ ] Implement updateReview() with time window check
- [ ] Implement deleteReview() with cascade handling
- Acceptance: Service layer has 90% test coverage

### Phase 2: API Implementation (Day 3-4)

**Task 2.1: Review Routes**
- [ ] Create Express routes for all endpoints
- [ ] Add authentication middleware
- [ ] Add request validation
- [ ] Add error handling
- Acceptance: All routes return correct status codes

**Task 2.2: Response Formatting**
- [ ] Create response transformers
- [ ] Add pagination metadata
- [ ] Add HATEOAS links
- Acceptance: Consistent API response format

**Task 2.3: Admin Endpoints**
- [ ] Create moderation endpoints
- [ ] Add admin authorization
- [ ] Implement bulk operations
- Acceptance: Admins can moderate reviews

### Phase 3: Frontend Integration (Day 5-6)

**Task 3.1: Review Components**
- [ ] Create ReviewList component
- [ ] Create ReviewCard component
- [ ] Create ReviewForm component
- [ ] Create StarRating component
- Acceptance: Components render correctly

**Task 3.2: State Management**
- [ ] Create review slice (Redux/Zustand)
- [ ] Add async thunks for API calls
- [ ] Add loading and error states
- Acceptance: State updates correctly

**Task 3.3: Product Page Integration**
- [ ] Add reviews section to product page
- [ ] Add review submission form
- [ ] Add review filtering and sorting
- Acceptance: Full user flow works end-to-end

### Phase 4: Testing & Polish (Day 7)

**Task 4.1: Comprehensive Testing**
- [ ] Run full test suite
- [ ] Fix any failing tests
- [ ] Add integration tests
- [ ] Perform load testing
- Acceptance: All tests pass, p95 latency < 500ms

**Task 4.2: Documentation**
- [ ] Update API documentation
- [ ] Add component documentation
- [ ] Write user guide
- Acceptance: Docs are complete and accurate

**Task 4.3: Code Review & Cleanup**
- [ ] Address code review feedback
- [ ] Remove debug code
- [ ] Optimize queries
- Acceptance: Code approved for merge

---

Total Estimated Time: 7 days
Critical Path: Database  Model  Service  API  Frontend

Step 5: Implementation

With tasks defined, use Kilo Code’s Apply Mode to implement each task systematically.

Apply Tasks

In Kilo Code, use the slash command to start implementation:

/openspec:apply add-product-reviews

Or use the OpenSpec CLI to get instructions for the AI agent:

# Get enriched instructions for applying tasks
openspec instructions apply --change add-product-reviews

Kilo Code will read tasks.md and implement each task systematically:

File: migrations/20260330-create-reviews-table.js

'use strict';

module.exports = {
  async up(queryInterface, Sequelize) {
    // Create reviews table
    await queryInterface.createTable('reviews', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.literal('gen_random_uuid()'),
        primaryKey: true
      },
      user_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'users',
          key: 'id'
        },
        onDelete: 'CASCADE'
      },
      product_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'products',
          key: 'id'
        },
        onDelete: 'CASCADE'
      },
      rating: {
        type: Sequelize.INTEGER,
        allowNull: false,
        validate: {
          min: 1,
          max: 5
        }
      },
      title: {
        type: Sequelize.STRING(200),
        allowNull: true
      },
      content: {
        type: Sequelize.TEXT,
        allowNull: false
      },
      status: {
        type: Sequelize.STRING(20),
        defaultValue: 'pending',
        validate: {
          isIn: [['pending', 'approved', 'rejected']]
        }
      },
      created_at: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
      },
      updated_at: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
      }
    });

    // Add unique constraint
    await queryInterface.addConstraint('reviews', {
      fields: ['user_id', 'product_id'],
      type: 'unique',
      name: 'unique_user_product_review'
    });

    // Create review_votes table
    await queryInterface.createTable('review_votes', {
      review_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'reviews',
          key: 'id'
        },
        onDelete: 'CASCADE'
      },
      user_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'users',
          key: 'id'
        },
        onDelete: 'CASCADE'
      },
      helpful: {
        type: Sequelize.BOOLEAN,
        allowNull: false
      },
      created_at: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
      }
    });

    // Add primary key constraint for review_votes
    await queryInterface.addConstraint('review_votes', {
      fields: ['review_id', 'user_id'],
      type: 'primary key',
      name: 'review_votes_pkey'
    });

    // Create indexes for performance
    await queryInterface.addIndex('reviews', ['product_id', 'status'], {
      name: 'idx_reviews_product'
    });

    await queryInterface.addIndex('reviews', ['user_id'], {
      name: 'idx_reviews_user'
    });

    await queryInterface.addIndex('reviews', ['created_at'], {
      order: ['DESC'],
      name: 'idx_reviews_created'
    });
  },

  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('review_votes');
    await queryInterface.dropTable('reviews');
  }
};

Test File: tests/migrations/20260330-create-reviews-table.test.js

const { sequelize } = require('../../src/config/database');
const { QueryInterface } = require('sequelize');

describe('Migration: Create Reviews Tables', () => {
  it('should create reviews table with correct structure', async () => {
    const table = await queryInterface.describeTable('reviews');
    
    expect(table.id).toBeDefined();
    expect(table.user_id).toBeDefined();
    expect(table.product_id).toBeDefined();
    expect(table.rating).toBeDefined();
    expect(table.status.defaultValue).toBe('pending');
  });

  it('should create review_votes table', async () => {
    const table = await queryInterface.describeTable('review_votes');
    
    expect(table.review_id).toBeDefined();
    expect(table.user_id).toBeDefined();
    expect(table.helpful).toBeDefined();
  });

  it('should have required indexes', async () => {
    const indexes = await queryInterface.showIndex('reviews');
    
    const indexNames = indexes.map(idx => idx.name);
    expect(indexNames).toContain('idx_reviews_product');
    expect(indexNames).toContain('idx_reviews_user');
    expect(indexNames).toContain('idx_reviews_created');
  });
});

Verification

Running migration:

$ npm run db:migrate

== 20260330-create-reviews-table: migrating =======
== 20260330-create-reviews-table: migrated (0.042s)

✓ Reviews table created
✓ Review votes table created
✓ Indexes created

Ready to proceed to Task 1.2: Review Model?


---

## Step 6: Verification

Each task is verified against its acceptance criteria before moving on.

### Check Status

Use OpenSpec CLI to check the status of your change:

```bash
# Check completion status
openspec status add-product-reviews

# Validate the change
openspec validate add-product-reviews

Automated Verification

$ npm test -- Review.test.js

  Review Model
    ✓ should create valid review instance (12ms)
    ✓ should validate rating between 1-5 (8ms)
    ✓ should reject invalid status values (5ms)
    ✓ should prevent duplicate user-product reviews (15ms)
    ✓ should calculate helpfulness percentage (7ms)
    ✓ should sanitize content on save (6ms)

  6 passing (53ms)
  Coverage: 94%

Running Integration Tests

$ npm test:integration -- reviews

  Review Integration
    ✓ should create review via service (45ms)
    ✓ should fetch reviews by product (32ms)
    ✓ should update review within time window (28ms)
    ✓ should reject update after 24h (22ms)
    ✓ should delete review and cascade votes (38ms)

  5 passing (165ms)

Static Analysis

$ npm run lint:reviews

✓ No ESLint errors
✓ No TypeScript errors
✓ Security scan: No issues

Acceptance Criteria Check

Criteria Status
Model passes all unit tests ✓ Pass
Model has validation logic ✓ Pass
Instance methods implemented ✓ Pass
Static methods implemented ✓ Pass
90% test coverage ✓ Pass (94%)

Result: Task 1.2 VERIFIED ✓

Proceeding to Task 1.3: Review Service Layer?


---

## Step 6: Documentation

The final step is generating documentation based on the implemented spec.

### Auto-Generate Documentation

`````markdown
User: "Generate documentation for the reviews feature"

Kilo Code (Code Mode):
I'll generate comprehensive documentation based on the implementation.

## API Documentation: Reviews

### Overview
The Reviews API allows customers to submit and view product reviews, 
and admins to moderate them.

### Authentication
- User endpoints require valid JWT token
- Admin endpoints require admin role

### Endpoints

#### POST /api/reviews
Create a new product review.

**Request:**
```json
{
  "productId": "550e8400-e29b-41d4-a716-446655440000",
  "rating": 5,
  "title": "Excellent quality",
  "content": "This product exceeded my expectations..."
}
```

**Response (201 Created):**
```json
{
  "id": "660e8400-e29b-41d4-a716-446655440001",
  "productId": "550e8400-e29b-41d4-a716-446655440000",
  "userId": "770e8400-e29b-41d4-a716-446655440002",
  "rating": 5,
  "title": "Excellent quality",
  "content": "This product exceeded my expectations...",
  "status": "pending",
  "createdAt": "2026-03-30T14:30:00Z",
  "helpfulness": {
    "helpful": 0,
    "notHelpful": 0,
    "percentage": 0
  }
}
```

**Errors:**
| Code | Message | Cause |
|------|---------|-------|
| 400 | Invalid rating | Rating not between 1-5 |
| 400 | Content too short | Content less than 10 chars |
| 401 | Unauthorized | Missing/invalid token |
| 404 | Product not found | Invalid product ID |
| 409 | Duplicate review | User already reviewed this product |

### Rate Limits
- 3 reviews per user per hour
- 100 API requests per minute

[More documentation continues...]
```

---

## Step 7: Archive the Change

Once all tasks are complete and verified, archive the change:

```bash
# Archive the change (merges spec deltas, cleans workspace)
openspec archive add-product-reviews --yes

# Or use the slash command in Kilo Code
/openspec:archive add-product-reviews --yes
```

This will:
1. Merge spec deltas from `openspec/changes/add-product-reviews/specs/` into `openspec/specs/`
2. Move the change folder to `openspec/changes/archive/YYYY-MM-DD-add-product-reviews/`
3. Update `openspec/specs/product-reviews/spec.md` as the new source of truth

---

## SDD vs. Vibe Coding: A Comparison

| Aspect | Vibe Coding | Spec-Driven Development |
|--------|-------------|------------------------|
| **Planning** | None or minimal | Detailed upfront planning |
| **Requirements** | Discovered during coding | Defined before coding |
| **Architecture** | Emergent (often inconsistent) | Designed intentionally |
| **Testing** | Afterthought | Built into acceptance criteria |
| **Documentation** | Missing or outdated | Generated from spec |
| **Technical Debt** | Accumulates quickly | Minimized by design |
| **Time to Start** | Immediate | Delayed (planning phase) |
| **Time to Complete** | Unpredictable | Estimated and tracked |
| **Code Quality** | Variable | Consistent |
| **Maintainability** | Poor | Good |
| **Best For** | Prototypes, experiments | Production features |

---

## When to Use SDD

### Use Spec-Driven Development When:

- **Building production features** that need to be maintainable
- **Working in teams** where consistency matters
- **Complex requirements** that need careful planning
- **Regulated industries** requiring documentation
- **Long-term projects** where technical debt matters

### Vibe Coding is Acceptable For:

- **Quick prototypes** to validate ideas
- **Personal projects** with no maintenance needs
- **Learning exercises** where speed matters more than quality
- **One-off scripts** that won't be reused
- **Exploratory coding** to understand a problem

---

## OpenSpec File Templates

### Proposal Template (`openspec/changes/<change-id>/proposal.md`)

```markdown
# Proposal: [Feature Name]

## 1. Overview
[Brief description of what we're building]

## 2. User Stories
- As a [user type], I want to [action] so that [benefit]

## 3. Functional Requirements

| ID | Requirement | Priority |
|----|-------------|----------|
| FR-1 | [Requirement] | Must Have |

## 4. Non-Functional Requirements

| ID | Requirement | Target |
|----|-------------|--------|
| NFR-1 | [Performance/Security/Scale] | [Metric] |

## 5. Constraints
- [Technical constraints, dependencies, etc.]
```

### Design Template (`openspec/changes/<change-id>/design.md`)

```markdown
# Design: [Feature Name]

## 1. System Architecture
[Diagrams and component relationships]

## 2. Data Model
[Database schema, data structures]

## 3. API Design
[Endpoints, request/response formats]

## 4. Security Considerations
[Authentication, authorization, data protection]

## 5. Testing Strategy
[Test coverage requirements, testing approach]
```

### Tasks Template (`openspec/changes/<change-id>/tasks.md`)

```markdown
# Tasks: [Feature Name]

## Implementation Plan

### Phase 1: [Phase Name]

**Task 1.1: [Task Name]**
- [ ] [Subtask 1]
- [ ] [Subtask 2]
- Acceptance: [Clear acceptance criteria]

**Task 1.2: [Task Name]**
- [ ] [Subtask 1]
- Acceptance: [Clear acceptance criteria]
```

### Spec Template (`openspec/specs/<module-name>/spec.md`)

```markdown
# Specification: [Module Name]

## 1. Overview
[Current state of the module]

## 2. Business Logic
[Rules and constraints]

## 3. Data Model
[Current schema]

## 4. API Reference
[Current endpoints]

## 5. Security
[Current security measures]
```

---

## Best Practices

### 1. Keep Specs Living Documents

Update specs as requirements evolve. Each spec in `openspec/specs/<module>/spec.md` should have a changelog:

```markdown
## Changelog

| Date | Version | Author | Changes |
|------|---------|--------|---------|
| 2026-03-30 | 1.0 | Team | Initial spec |
| 2026-04-02 | 1.1 | Team | Added image attachments |
```

### 2. One Spec Per Module

Organize specs by functional module:

```text
openspec/specs/
├── auth-login/
│   └── spec.md
├── product-reviews/
│   └── spec.md
├── payment/
│   └── spec.md
└── user-management/
    └── spec.md
```

### 3. Use Change Folders for Active Work

Each feature/fix gets its own change folder:

```text
openspec/changes/
├── add-product-reviews/     # Active change
│   ├── proposal.md
│   ├── design.md
│   ├── tasks.md
│   └── specs/
└── archive/
    └── 2026-03-30-add-oauth/  # Completed
```

### 4. Define Clear Acceptance Criteria

Vague criteria lead to incomplete work:

```bash
Bad:  "The feature should work correctly"

Good: "User can submit review with 10-5000 characters,
       1-5 star rating, and optional title.
       Duplicate reviews are rejected with 409 status."
```

### 5. Validate Before Apply

Always validate your proposal before starting implementation:

```bash
# Validate proposal structure
openspec validate add-product-reviews

# Check status
openspec status add-product-reviews
```

### 6. Archive Completed Changes

Don't leave change folders lying around:

```bash
# Archive when all tasks are complete
openspec archive add-product-reviews --yes
```

This merges spec deltas and keeps your workspace clean.

---

## What's Next?

Now that you've mastered Spec-Driven Development, you're ready to learn about **Steering and Custom Agents**. In the next post, we'll explore how to customize Kilo Code's behavior for your team's specific needs.

**Coming up:** [Kilo Code Series #7: Steering and Custom Agents](/ai/kilo-code-series-07-steering/)

In the next post, we'll cover:
- Creating steering rules with Markdown
- Building custom agents for specific tasks
- Team-specific configuration patterns
- Best practices for agent steering

---

## Quick Reference

### OpenSpec CLI Commands

```bash
# Install OpenSpec
npm install -g @fission-ai/openspec@latest

# Initialize in project
openspec init --tools claude,cursor,kilocode

# Validate a proposal
openspec validate add-product-reviews

# Check status
openspec status add-product-reviews

# Show change details
openspec show add-product-reviews

# List all changes and specs
openspec list --changes
openspec list --specs

# Archive completed change
openspec archive add-product-reviews --yes

# Get instructions for AI agents
openspec instructions apply --change add-product-reviews
```

### Kilo Code Slash Commands

```
/openspec:proposal          # Create proposal (proposal.md, design.md, tasks.md)
/openspec:apply <change>    # Implement tasks from a change
/openspec:archive <change>  # Archive completed change
/openspec-proposal.md       # Alternative proposal trigger
```

### Folder Structure

```text
project-root/
├── openspec/
│   ├── AGENTS.md              # AI agent instructions
│   ├── project.md             # Project context
│   ├── specs/                 # Source of truth
│   │   ├── auth-login/
│   │   │   └── spec.md
│   │   └── product-reviews/
│   │       └── spec.md
│   └── changes/               # Active changes
│       ├── add-product-reviews/
│       │   ├── proposal.md
│       │   ├── design.md
│       │   ├── tasks.md
│       │   └── specs/
│       └── archive/
├── .kilocode/
│   └── workflows/             # Kilo Code workflows
└── .cursor/
    ├── skills/
    └── commands/
```

### Workflow Summary

```bash
1. Initialize:  openspec init
2. Proposal:    /openspec:proposal
3. Validate:    openspec validate <change>
4. Apply:       /openspec:apply <change>
5. Verify:      openspec status <change>
6. Archive:     openspec archive <change> --yes
```