OpenSpec-practise

OpenSpec Practical Guide

1. Introduction

OpenSpec is a Spec-centric engineering methodology and toolchain designed to improve the determinism and verifiability of complex systems throughout the full cycle from design to delivery, through unified structured documents and automated workflows. This guide uses a complete small e-commerce website case study to demonstrate the full process — from architecture design, system design, and module design, to interface design, unit testing, integration testing (covering interface-layer acceptance), and performance testing — in order to facilitate adoption in real-world projects.

Further Reading: For a deep retrospective on the AI collaboration workflow for this case (prompt design and interaction records) and cross-language replication validation in Python, see OpenSpec Practical Guide: Deep Retrospective on AI-Assisted Software Engineering.

CLI Reference Manual: For the complete command reference for the OpenSpec CLI (init, validate, archive, etc.), see OpenSpec User Manual.

Training Materials: This project includes companion presentation slides OpenSpec User Manual, suitable for team training and technical sharing.


2. Methodology and Core OpenSpec Concepts

OpenSpec is not merely a document format — it is an engineering practice of Spec-Driven Development. It advocates “spec as the source of truth”, ensuring that code and tests always remain consistent with the design, solving the persistent problem in traditional development where “documentation lags behind the code”.

2.1 Core Philosophy

Terminology Note: In this document “spec” and “Spec” are used interchangeably, both referring to the document structure defined by OpenSpec; “specification” and “spec” may also be used interchangeably without distinction.

OpenSpec’s design follows four core principles:

2.2 Directory Structure and Single Source of Truth

OpenSpec divides project state into two core areas, ensuring separation between “current state” and “the change process”:

When a change is developed and archived, its Delta Spec is merged into the main Spec, forming the new source of truth.

2.3 Workflow and CLI Tools

OpenSpec provides two primary workflow modes: CLI and Slash Commands (AI collaboration).

2.3.1 Command-Line Tool (CLI)

The CLI (openspec) is suited for management operations by human developers:

2.3.2 AI Collaboration Commands (Slash Commands)

OpenSpec 1.0+ introduced the OPSX workflow, implementing a dynamic command system — AI no longer receives static instructions but actively queries the CLI to understand the current project state and document dependencies.

In supported AI editors (such as Cursor, Claude Code, Qoder, Windsurf, Junie, Lingma IDE, ForgeCode, and 20+ other tools), it is recommended to drive development using Slash Commands:

Default Core Configuration:

Command Purpose
/opsx:propose <description> Create a change and generate all planning documents in one step (proposal/design/specs/tasks)
/opsx:explore Enter exploration mode — think through problems and investigate the codebase without writing code
/opsx:apply Implement tasks according to tasks.md, dynamically reading the current change context
/opsx:archive Complete and archive the current change, prompt whether to sync Delta Spec to the main spec

Extended Workflow Commands (enabled via openspec config profile)

Command Purpose
/opsx:new Initialize the change directory structure only (no documents created)
/opsx:continue Create the next document in dependency order (step-by-step mode)
/opsx:ff Fast-forward to generate all planning documents at once
/opsx:verify Verify that the implementation is consistent with the spec
/opsx:sync Merge Delta Spec into the main spec (without archiving)
/opsx:bulk-archive Bulk-archive multiple completed changes
/opsx:onboard 15-minute full-process guided walkthrough

The key difference between the OPSX workflow and the old version is: actions, not phases. You can edit any document at any time — there is no phase locking.

2.4 Validation and Observability


3. Iteration Process Overview

OpenSpec’s iteration process is centered on “spec-first”, but does not mandate a cumbersome approval process.

3.1 Goals and Scope (Proposal)

Before any code begins, first use proposal.md to define Why and What.

3.2 Spec Initialization

Use the CLI to quickly initialize the project structure (if you are using the examples/ecommerce-mini source code directly, this step is already complete and can be skipped):

openspec init --tools none

If you are using the companion source code, run the following command to confirm that the spec documents are complete and valid:

openspec validate v1-mvp

Create a new changeset (e.g., v1-mvp) under openspec/changes/, containing the following files:

3.2.1 proposal.md (Macro Intent)

This is the starting point of the project, clearly defining “why we are doing this” and “what the criteria for success are”.

# Proposal: Ecommerce Mini MVP

## Why

### Background

This project originated from in-depth community discussions about AI-assisted programming, and requires a complete hands-on case to demonstrate the specific application of OpenSpec specifications in AI-assisted programming.

### Problem Statement

A standardized way is needed to ensure that humans and AI reach consensus on requirements while keeping code and documentation in sync.

### Alternatives Considered

1. **Write code directly**: Fast but lacks documentation support.
2. **Traditional requirements documents**: Separated from code, easily becomes outdated.
3. **OpenSpec spec-driven**: Define the spec first, then write the code, maintaining consistency ✓ This approach was chosen.

## What Changes

### New Resources Added

- **Domain Models**: Core entities such as Product, User, Cart, Order.
- **API Interfaces**: RESTful interfaces for products, cart, orders, payments, etc.

### New Capabilities

- Product list query and listing.
- Cart management (add, remove).
- Order checkout and inventory deduction.

## Capabilities

### New Capabilities

- `catalog-management`: Product list query, product listing, and inventory deduction management
- `cart-management`: Cart item addition, removal, and quantity limits
- `order-management`: Order creation, order query, and total price calculation
- `payment`: Order payment and status transitions
- `domain-model`: Core business entity definitions
- `error-handling`: Unified error response format and standard error code system

### Modified Capabilities

(None — this is a brand-new MVP project)

## Impact

- **Affected Code**: `ecommerce-mini/src/` (Node.js), `ecommerce-mini-python/src/` (Python)
- **New APIs**: 8 REST endpoints (GET /api/products, POST /api/products, POST /api/cart/items, DELETE /api/cart/items/:id, POST /api/orders, GET /api/orders/:id, POST /api/payments/:orderId, GET /metrics)
- **Dependencies**: Node.js has zero npm dependencies; Python depends on FastAPI + Pydantic

## Scope

### In Scope

- Product list query and listing.
- Cart management (add, remove).
- Order checkout and inventory deduction.
- Payment simulation.
- In-memory storage and file persistence.

### Out of Scope

- Complex search and recommendations.
- Real payment gateway integration.
- Admin management interface.

## Goals (SLO)

- **Latency**: Core interface p99 < 100ms.
- **Concurrency**: Support 50 RPS.
- **Quality**: Core logic test coverage > 80%.

3.2.2 Other Core Files

3.3 Architecture and System Design

Based on the Proposal, determine the following in design.md:

3.4 Spec-Driven Implementation

This is the core of OpenSpec — code is a mapping of the spec.

3.5 Validation and Measurement

# Validate the change spec
openspec validate v1-mvp

# Successful validation output
Change 'v1-mvp' is valid

Note: The validate command checks Proposal section completeness, directory structure, Delta Header format, and Scenario coverage. For detailed validation rules and troubleshooting, see OpenSpec User Manual - 6. Validation and Common Errors.

3.6 Archiving and Knowledge Consolidation

When v1-mvp development is complete and has passed acceptance, run /opsx:archive (recommended) or the CLI command openspec archive. This merges the Specs from the changeset into the main spec directory (openspec/specs/), making them the latest source of truth for the system.


4. Case Background: Small E-Commerce Website

4.1 Core Domains and Contexts

This case builds a micro e-commerce system called ecommerce-mini, containing five core contexts:

4.2 Simplifying Assumptions

To focus on the OpenSpec process, the following engineering trade-offs were made:

4.3 Non-Functional Goals


5. Architecture Design

5.1 Layered Architecture

This project uses a classic four-layer architecture to ensure separation of concerns:

Layer Directory (src/) Responsibilities Dependency Direction
Interface Layer http/ Handle HTTP requests, parameter parsing, authentication, response formatting -> Application
Application Layer services/ Use case orchestration, e.g., “place order” involves deducting stock, clearing cart -> Domain, Repo
Domain Layer domain/ Pure business entities (types.js) and logic, no external dependencies None
Infrastructure repo/, persist/ Data persistence implementation (Memory/File) Implementation Detail

5.2 Boundaries and Dependency Rules

5.3 Data Flow Overview

Using the “place order” scenario as an example:

  1. User initiates a POST /api/orders request.
  2. HTTP Layer parses the Token and verifies user identity.
  3. Order Service receives the request:
    • Calls Cart Service to retrieve the current cart items.
    • Calls Catalog Service to deduct inventory (transaction consistency boundary).
    • Calculates the total price and generates the order entity.
  4. Order Repo saves the order data.
  5. HTTP Layer returns 201 Created with the order details.

6. System Design

6.1 Interface Protocol

Standard RESTful JSON style is used.

6.2 Data Models

In OpenSpec, we first define the models in changes/v1-mvp/specs/domain-model/spec.md. Spec files must use the Delta Header + Requirement + Scenario format:

Spec Definition (changes/v1-mvp/specs/domain-model/spec.md):

# Domain Model Specification

## Overview

Core business entity definitions, with no dependency on any external framework.

## ADDED Requirements

### Requirement: Product Entity Definition

The system SHALL define a product entity containing a unique identifier, name, price, and stock.

**Priority**: P0 (Critical)

**Rationale**: Products are the core entity of an e-commerce system and the foundation of all transactions.

#### Scenario: Create a Valid Product

Given a new product needs to be created
When product information is provided: { id, name, priceCents, stock }
Then the product entity is created successfully
And the id format is prod_xxxx
And priceCents >= 0
And stock >= 0

---

### Requirement: Non-negative Stock Validation

Stock MUST NOT become negative after deduction.

**Priority**: P0 (Critical)

**Rationale**: Negative stock leads to overselling and affects business accuracy.

#### Scenario: Deduct Stock When Insufficient

Given a product has a stock of 5
When an attempt is made to deduct 6 units of stock
Then an OUT_OF_STOCK error is thrown
And the stock remains unchanged

Code Implementation (src/domain/types.js / JSDoc):

Since this project uses plain JS, we implement the Spec mapping via JSDoc:

/**
 * @typedef {Object} Product
 * @property {string} id
 * @property {string} name
 * @property {number} priceCents
 * @property {number} stock
 */

6.3 Error Handling

Unified error response structure for easy front-end processing:

{
  "code": "OUT_OF_STOCK",
  "message": "Product [prod_123] is out of stock"
}

7. Module Detailed Design

7.1 Catalog (Product Domain)

7.2 Cart (Cart Domain)

7.3 Order (Order Domain)


8. Interface Design

A key advantage of OpenSpec is using Markdown to write highly readable spec documents while maintaining structure. In v1.2.0, specs are organized by Capability, one folder per capability. The following are real excerpts from openspec/changes/v1-mvp/specs/catalog-management/spec.md and openspec/changes/v1-mvp/specs/order-management/spec.md:

# Catalog Management Specification

## Overview

Product catalog management capability, covering product queries, listing, and inventory management.

## ADDED Requirements

### Requirement: Product List Query

The system SHALL provide a product list query interface that returns all available products.

**Priority**: P0 (Critical)

**Rationale**: Product browsing is the core entry function of an e-commerce system; users must be able to view purchasable products.

#### Scenario: Get All Products

Given product data exists in the system
When the user requests GET /api/products
Then a status code of 200 is returned
And a product array Product[] is returned
# Order Management Specification

## Overview

Order management capability, covering order creation, query, and total price calculation.

## ADDED Requirements

### Requirement: Order Creation

The system SHALL support settling a user's shopping cart to create an order, handling inventory deduction and cart clearing in the process.

**Priority**: P0 (Critical)

**Rationale**: Order creation is the core transaction process, involving coordination of multiple modules (Cart -> Catalog -> Order).

#### Scenario: Successfully Create an Order

Given the user has items in their shopping cart
And the product inventory is sufficient
When a POST /api/orders request is sent with { userId }
Then a status code of 201 is returned
And the newly created Order is returned
And the order status is PENDING_PAYMENT
And the shopping cart is cleared
And the inventory is deducted

#### Scenario: Insufficient Inventory When Creating an Order

Given the user has items in their shopping cart
And the product inventory is insufficient
When a POST /api/orders request is sent with { userId }
Then a status code of 409 is returned
And the error code OUT_OF_STOCK is returned

Note:

9. Spec-Driven Implementation

This is the core of OpenSpec — code is a mapping of the spec. When writing code, developers (or AI) should always have the Spec file open as a reference.

9.1 Traceability Matrix

Establish a Spec ↔ Code ↔ Test mapping to ensure every Spec item has code coverage:

Spec Definition (Requirements) Code Implementation Verification Method
POST /api/orders src/http/server.js (Route Handler) Integration Test
Response 409: Stock insufficient catch (e) { if (e.message === 'OUT_OF_STOCK') ... } Unit Test (Error Case)
Order.totalCents (Model) src/domain/types.js (Interface) JSDoc / Code Review
p99 < 100ms (SLO) performance.spec.js (Performance Test) CI Pipeline

Practical Tip: Reference the corresponding Spec section in code comments, e.g., // Corresponds to Spec: POST /api/orders.

9.2 Directory Structure Mapping

OpenSpec-practise/
├── docs/                            <-- Documentation directory
│   ├── openspec-user-manual.md          <-- OpenSpec User Manual
│   ├── openspec-practical-guide.md  <-- Practical Guide (this document)
│   └── openspec-ai-workflow-analysis.md  <-- AI Collaboration Workflow Analysis
├── examples/
│   ├── openspec/                    <-- OpenSpec spec directory
│   │   ├── config.yaml              <-- Project configuration (tech stack, rules, etc.)
│   │   ├── specs/                   <-- Main spec (source of truth after archiving)
│   │   │   ├── catalog-management/spec.md
│   │   │   ├── cart-management/spec.md
│   │   │   ├── order-management/spec.md
│   │   │   ├── payment/spec.md
│   │   │   ├── domain-model/spec.md
│   │   │   └── error-handling/spec.md
│   │   └── changes/v1-mvp/          <-- MVP change spec
│   │       ├── .openspec.yaml       <-- Change metadata
│   │       ├── proposal.md          <-- Corresponding proposal document
│   │       ├── design.md            <-- Corresponding design document
│   │       ├── tasks.md             <-- Corresponding task list
│   │       └── specs/               <-- Delta specs (organized by capability)
│   │           ├── catalog-management/spec.md  <-- Catalog management spec
│   │           ├── cart-management/spec.md     <-- Cart management spec
│   │           ├── order-management/spec.md    <-- Order management spec
│   │           ├── payment/spec.md             <-- Payment spec
│   │           ├── domain-model/spec.md        <-- Domain model spec
│   │           └── error-handling/spec.md      <-- Error handling spec
│   ├── ecommerce-mini/              <-- Node.js Implementation
│   │   └── src/
│   │       ├── domain/types.js      <-- Corresponds to Data Models in the Spec
│   │       ├── services/            <-- Corresponds to Business Rules in the Spec
│   │       ├── http/server.js       <-- Corresponds to API Definitions in the Spec
│   │       └── persist/             <-- Corresponds to Storage Strategy in the Design
│   └── ecommerce-mini-python/       <-- Python Implementation

9.3 Code Implementation Example

Controller Layer (src/http/server.js):

// Corresponds to Spec: POST /api/orders
if (pathname === "/api/orders" && req.method === "POST") {
  const body = await readJson(req);
  try {
    // Orchestrate business logic (Orchestration)
    // 1. Check cart (Rule: Cart Not Empty)
    // 2. Check inventory (Rule: Stock Check)
    // 3. Create order
    const order = orderService.createOrder(body.userId);
    return sendJson(res, 201, order);
  } catch (e) {
    if (e.message === "CART_EMPTY")
      return sendError(res, "CART_EMPTY", "Cart is empty", 400);
    if (e.message === "OUT_OF_STOCK")
      return sendError(res, "OUT_OF_STOCK", "Insufficient stock", 409);
    throw e;
  }
}

10. Validation and Evaluation: Ensuring Implementation Conforms to Spec

After writing code, how can you effectively evaluate consistency between the implementation and the Spec? This section introduces the validation methods and tools recommended by OpenSpec.

10.1 Traceability Matrix

The traceability matrix was already presented in 9.1 Traceability Matrix. It is recommended to maintain it concurrently during the code-writing phase, ensuring every Spec item has a corresponding code implementation and test verification.

10.2 From Scenario to Test Case

OpenSpec’s Gherkin-format scenarios are naturally suited for conversion into test cases:

Scenario in the Spec (specs/order-management/spec.md):

#### Scenario: Successfully Create an Order

Given the user has items in their shopping cart
And the product inventory is sufficient
When a POST /api/orders request is sent with { userId }
Then a status code of 201 is returned
And the newly created Order is returned
And the shopping cart is cleared
And the inventory is deducted

Corresponding Integration Test (__tests__/integration.spec.js):

The following example assumes the test environment service is running at http://localhost:3000 (the base variable points to that address).

it('complete shopping flow', async () => {
  // 1. List product → Given product inventory is sufficient
  const res1 = await fetch(`${base}/api/products`, {...})
  assert.strictEqual(res1.status, 201)

  // 2. Add to cart → Given user has items in their shopping cart
  const res2 = await fetch(`${base}/api/cart/items`, {...})
  assert.strictEqual(res2.status, 200)

  // 3. Place order → When POST /api/orders is sent
  const res3 = await fetch(`${base}/api/orders`, {...})
  assert.strictEqual(res3.status, 201)  // Then status code 201 is returned
  const order = await res3.json()
  assert.strictEqual(order.totalCents, 1000)  // Then the newly created order is returned
  assert.strictEqual(order.status, 'PENDING_PAYMENT')
})

10.3 Relationship with TDD

OpenSpec does not replace TDD — it works in concert with TDD:

Traditional TDD: Requirements → Write tests → Write code → Refactor
OpenSpec + TDD: Requirements → Write Spec → Validate Spec → Write tests (based on Scenarios) → Write code → Refactor

Key Differences:

Encountering format errors? See OpenSpec User Manual - 6. Validation and Common Errors for troubleshooting.

10.4 Code Review Checklist

When reviewing a PR, check for consistency between implementation and Spec:


11. Test Design: Verifying the Spec

Tests are not an afterthought — they are the executable version of the spec.

11.1 Unit Tests (src/domain/logic.spec.js)

Targeting pure function logic, such as amount calculation and state machine transitions.

import { test } from "node:test";
import assert from "node:assert";
import { calculateTotal } from "./logic.js";

test("calculateTotal sums up item prices", () => {
  const items = [
    { priceCents: 100, quantity: 2 },
    { priceCents: 50, quantity: 1 },
  ];
  const total = calculateTotal(items);
  assert.strictEqual(total, 250);
});

11.2 Integration Tests (__tests__/integration.spec.js)

Simulates real user paths, verifying inter-module collaboration.

11.3 Performance Baseline (performance.spec.js)

Defines and validates SLOs.


12. Example Code Operations Manual

12.1 Preparing the Environment

This project has no package.json dependencies (aside from development tools), which not only showcases native capabilities but also lowers the barrier to running the project.

12.2 Running the Development Server

The development version uses in-memory storage; data is reset on restart.

# Start the server
node examples/ecommerce-mini/src/http/server.js

# Run the test suite in another terminal
node --test examples/ecommerce-mini/__tests__/

12.3 Running the Production Server

The production version has file persistence, authentication, and idempotency checking enabled.

# Start the production server (Port 3002)
node examples/ecommerce-mini/src/http/server.prod.js

13. Production-Grade Extension Practices

To demonstrate how OpenSpec handles complexity, three advanced features are introduced in server.prod.js.

13.1 Persistent Storage (src/persist/fileStore.js)

Spec Change: The system needs to retain user data even after a restart.

Implementation:

13.2 Authentication and Security

Spec Change: All non-public interfaces must carry a Bearer Token.

Implementation:

13.3 Idempotency

Spec Change: For duplicate payment requests for the same order, the system should return the same result without charging again.

Implementation:

13.4 Observability

Spec Change: The system needs to expose a /metrics endpoint for monitoring collection.

Implementation:


14. Conclusion

Through the ecommerce-mini case, we have demonstrated how OpenSpec spans the full lifecycle from “Proposal” to “Production”.

We hope this practical guide helps you better apply the OpenSpec methodology in real-world projects.