개념
이 가이드에서는 OpenSpec의 핵심 아이디어와 이들이 어떻게 유기적으로 연결되는지 설명합니다. 실제 사용법에 대해서는 시작하기와 워크플로를 참고하세요.
철학
OpenSpec는 네 가지 원칙을 기반으로 구축되었습니다:
유연한 것, 경직된 것이 아닌 — 단계 게이트 없음, 의미 있는 작업에 집중
반복적인 것, 워터폴이 아닌 — 만들면서 배우고, 진행하면서 개선
간편한 것, 복잡한 것이 아닌 — 가벼운 설정, 최소한의 절차
브라운필드 우선 — 그린필드뿐 아니라 기존 코드베이스와도 작동이 원칙들이 중요한 이유
유연한 것, 경직된 것이 아닌. 전통적인 스펙 시스템은 작업을 단계로 고정시킵니다: 먼저 계획하고, 그다음 구현하고, 마지막으로 완료합니다. OpenSpec는 더 유연합니다 — 작업에 의미 있는 순서로 아티팩트를 자유롭게 생성할 수 있습니다.
반복적인 것, 워터폴이 아닌. 요구사항은 변합니다. 이해는 깊어집니다. 처음에는 좋은 접근법처럼 보였던 것이 코드베이스를 살펴본 후에는 성립하지 않을 수 있습니다. OpenSpec는 이러한 현실을 수용합니다.
간편한 것, 복잡한 것이 아닌. 일부 스펙 프레임워크는 광범위한 설정, 경직된 형식, 또는 무거운 프로세스를 요구합니다. OpenSpec는 방해가 되지 않습니다. 몇 초 만에 초기화하고, 즉시 작업을 시작하며, 필요할 때만 커스터마이징합니다.
브라운필드 우선. 대부분의 소프트웨어 작업은 처음부터 구축하는 것이 아니라 기존 시스템을 수정하는 것입니다. OpenSpec의 델타 기반 접근 방식은 새로운 시스템을 설명하는 것뿐 아니라 기존 동작에 대한 변경 사항을 지정하는 것도 쉽게 만들어 줍니다.
큰 그림
OpenSpec은 작업을 두 가지 주요 영역으로 구성합니다:
┌────────────────────────────────────────────────────────────────────┐
│ openspec/ │
│ │
│ ┌─────────────────────┐ ┌───────────────────────────────┐ │
│ │ specs/ │ │ changes/ │ │
│ │ │ │ │ │
│ │ 진실의 원천 │◄─────│ 제안된 수정사항 │ │
│ │ 시스템이 현재 │ 병합 │ 각 변경사항 = 하나의 폴더 │ │
│ │ 어떻게 동작하는지 │ │ 아티팩트 + 델타를 포함 │ │
│ │ │ │ │ │
│ └─────────────────────┘ └───────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────┘Specs는 진실의 원천(Source of Truth)입니다 — 시스템이 현재 어떻게 동작하는지를 설명합니다.
Changes는 제안된 수정사항입니다 — 병합할 준비가 될 때까지 별도의 폴더에 존재합니다.
이러한 분리가 핵심입니다. 여러 변경사항을 충돌 없이 병렬로 작업할 수 있습니다. 변경사항이 메인 스펙에 영향을 주기 전에 리뷰할 수 있습니다. 그리고 변경사항을 아카이브하면, 해당 델타가 진실의 원천에 깔끔하게 병합됩니다.
Specs
스펙은 구조화된 요구사항과 시나리오를 사용하여 시스템 동작을 설명합니다.
구조
openspec/specs/
├── auth/
│ └── spec.md # 인증 동작
├── payments/
│ └── spec.md # 결제 처리
├── notifications/
│ └── spec.md # 알림 시스템
└── ui/
└── spec.md # UI 동작 및 테마스펙은 도메인별로 구성하세요 — 시스템에 적합한 논리적 그룹입니다. 일반적인 패턴:
- 기능 영역별:
auth/,payments/,search/ - 컴포넌트별:
api/,frontend/,workers/ - 제한된 컨텍스트별:
ordering/,fulfillment/,inventory/
스펙 형식
스펙은 요구사항을 포함하며, 각 요구사항에는 시나리오가 있습니다:
# Auth Specification
## Purpose
애플리케이션의 인증 및 세션 관리.
## Requirements
### Requirement: User Authentication
시스템은 성공적인 로그인 시 JWT 토큰을 발급해야 한다(SHALL).
#### Scenario: Valid credentials
- GIVEN 유효한 자격 증명을 가진 사용자
- WHEN 사용자가 로그인 폼을 제출하면
- THEN JWT 토큰이 반환된다
- AND 사용자는 대시보드로 리디렉션된다
#### Scenario: Invalid credentials
- GIVEN 유효하지 않은 자격 증명
- WHEN 사용자가 로그인 폼을 제출하면
- THEN 오류 메시지가 표시된다
- AND 토큰이 발급되지 않는다
### Requirement: Session Expiration
시스템은 30분간 비활성 시 세션을 만료시켜야 한다(MUST).
#### Scenario: Idle timeout
- GIVEN 인증된 세션
- WHEN 30분 동안 활동이 없으면
- THEN 세션이 무효화된다
- AND 사용자는 재인증해야 한다주요 요소:
| 요소 | 목적 |
|---|---|
## Purpose | 이 스펙의 도메인에 대한 상위 수준 설명 |
### Requirement: | 시스템이 가져야 할 특정 동작 |
#### Scenario: | 요구사항의 구체적인 예시 |
| SHALL/MUST/SHOULD | 요구사항의 강도를 나타내는 RFC 2119 키워드 |
스펙을 이렇게 구조화하는 이유
요구사항은 "무엇(what)"입니다 — 구현을 명시하지 않고 시스템이 무엇을 해야 하는지를 명시합니다.
시나리오는 "언제(when)"입니다 — 검증 가능한 구체적인 예시를 제공합니다. 좋은 시나리오는:
- 테스트 가능합니다 (자동화된 테스트를 작성할 수 있음)
- 해피 패스와 엣지 케이스를 모두 다룹니다
- Given/When/Then과 같은 구조화된 형식을 사용합니다
RFC 2119 키워드 (SHALL, MUST, SHOULD, MAY)는 의도를 전달합니다:
- MUST/SHALL — 절대적 요구사항
- SHOULD — 권장 사항이지만 예외가 존재
- MAY — 선택 사항
스펙이 무엇인지 (그리고 무엇이 아닌지)
스펙은 동작 계약(behavior contract) 이며 구현 계획이 아닙니다.
좋은 스펙 내용:
- 사용자나 하위 시스템이 의존하는 관찰 가능한 동작
- 입력, 출력 및 오류 조건
- 외부 제약 사항 (보안, 개인 정보 보호, 신뢰성, 호환성)
- 테스트하거나 명시적으로 검증할 수 있는 시나리오
스펙에서 피해야 할 것:
- 내부 클래스/함수명
- 라이브러리나 프레임워크 선택
- 단계별 구현 세부 정보
- 상세한 실행 계획 (
design.md나tasks.md에 속함)
빠른 테스트:
- 외부에 보이는 동작을 변경하지 않고 구현을 변경할 수 있다면, 그것은 스펙에 포함되지 않아야 합니다.
가볍게 유지하기: 점진적 엄격함
OpenSpec은 관료주의를 피하는 것을 목표로 합니다. 변경사항을 검증 가능하게 만드는 가장 가벼운 수준을 사용하세요.
라이트 스펙 (기본값):
- 간결한 동작 우선 요구사항
- 명확한 범위와 비목표
- 몇 가지 구체적인 승인 확인 항목
전체 스펙 (더 높은 위험용):
- 교차 팀 또는 크로스 레포 변경
- API/계약 변경, 마이그레이션, 보안/개인 정보 보호 문제
- 모호함으로 인해 비용이 많이 드는 재작업이 발생할 가능성이 높은 변경
대부분의 변경사항은 라이트 모드로 유지해야 합니다.
인간 + 에이전트 협업
많은 팀에서 사람이 탐구하고 에이전트가 아티팩트를 초안합니다. 의도된 순환은 다음과 같습니다:
- 사람이 의도, 맥락, 제약 사항을 제공합니다.
- 에이전트가 이를 동작 우선 요구사항과 시나리오로 변환합니다.
- 에이전트는 구현 세부 사항을
spec.md가 아닌design.md와tasks.md에 보관합니다. - 검증을 통해 구현 전에 구조와 명확성을 확인합니다.
이렇게 하면 스펙이 사람이 읽기 쉽고 에이전트에게 일관성을 유지합니다.
Changes
변경사항은 시스템에 대한 제안된 수정으로, 이해하고 구현하는 데 필요한 모든 것을 하나의 폴더로 패키징한 것입니다.
변경사항 구조
openspec/changes/add-dark-mode/
├── proposal.md # 이유와 내용
├── design.md # 방법 (기술적 접근)
├── tasks.md # 구현 체크리스트
├── .openspec.yaml # 변경 메타데이터 (선택): schema, created, skip_specs, retire_capabilities
└── specs/ # 델타 스펙
└── ui/
└── spec.md # ui/spec.md에서 무엇이 변경되는지각 변경사항은 독립적입니다. 여기에는 다음이 포함됩니다:
- 아티팩트 — 의도, 설계, 작업을 캡처하는 문서
- 델타 스펙 — 추가, 수정 또는 제거되는 사항에 대한 사양
- 메타데이터 — 이 특정 변경사항에 대한 선택적 구성
변경사항이 폴더인 이유
변경사항을 폴더로 패키징하면 여러 장점이 있습니다:
모든 것이 함께. 제안, 설계, 작업, 스펙이 한 곳에 있습니다. 다른 위치를 찾을 필요가 없습니다.
병렬 작업. 여러 변경사항이 충돌 없이 동시에 존재할 수 있습니다.
add-dark-mode작업을 하는 동안fix-auth-bug도 진행할 수 있습니다.깔끔한 이력. 아카이브되면 변경사항은
changes/archive/로 이동하며 전체 컨텍스트가 보존됩니다. 무엇이 변경되었는지뿐만 아니라 이유도 나중에 확인할 수 있습니다.리뷰 친화적. 변경사항 폴더는 리뷰하기 쉽습니다 — 열어서 제안을 읽고, 설계를 확인하고, 스펙 델타를 보면 됩니다.
아티팩트
아티팩트는 변경사항 내에서 작업을 안내하는 문서입니다.
아티팩트 흐름
proposal ──────► specs ──────► design ──────► tasks ──────► implement
│ │ │ │
이유 무엇 방법 단계
+ 범위 변경사항 접근 방식 실행할아티팩트는 서로를 기반으로 합니다. 각 아티팩트는 다음 아티팩트에 대한 컨텍스트를 제공합니다.
아티팩트 유형
Proposal (proposal.md)
제안은 의도, 범위, 접근 방식을 높은 수준에서 캡처합니다.
# Proposal: Add Dark Mode
## Intent
사용자들은 야간 사용 시 눈의 피로를 줄이고
시스템 환경설정과 일치시키기 위해 다크 모드 옵션을 요청했습니다.
## Scope
포함 범위:
- 설정에서 테마 토글
- 시스템 환경설정 감지
- localStorage에 선호도 유지
제외 범위:
- 커스텀 컬러 테마 (향후 작업)
- 페이지별 테마 오버라이드
## Approach
CSS 커스텀 속성을 테마에 사용하고 React 컨텍스트로
상태 관리를 합니다. 첫 로드 시 시스템 환경설정을 감지하고
수동 오버라이드를 허용합니다.제안을 업데이트해야 하는 시점:
- 범위가 변경될 때 (좁아지거나 넓어질 때)
- 의도가 명확해질 때 (문제에 대한 이해가 향상될 때)
- 접근 방식이 근본적으로 전환될 때
Specs (specs/의 델타 스펙)
델타 스펙은 현재 스펙에 대해 무엇이 변경되는지 설명합니다. 아래의 델타 스펙을 참조하세요.
Design (design.md)
설계는 기술적 접근 방식과 아키텍처 결정을 캡처합니다.
# Design: Add Dark Mode
## Technical Approach
테마 상태는 prop drilling을 피하기 위해 React Context로 관리합니다.
CSS 커스텀 속성은 클래스를 토글하지 않고 런타임 전환을 가능하게 합니다.
## Architecture Decisions
### Decision: Context over Redux
테마 상태에 Redux 대신 React Context를 사용하는 이유:
- 간단한 이진 상태 (라이트/다크)
- 복잡한 상태 전이가 없음
- Redux 의존성 추가를 피함
### Decision: CSS Custom Properties
CSS-in-JS 대신 CSS 변수를 사용하는 이유:
- 기존 스타일시트와 함께 작동
- 런타임 오버헤드 없음
- 브라우저 네이티브 솔루션
## Data Flow
```
ThemeProvider (context)
│
▼
ThemeToggle ◄──► localStorage
│
▼
CSS Variables (:root에 적용됨)
```
## File Changes
- `src/contexts/ThemeContext.tsx` (신규)
- `src/components/ThemeToggle.tsx` (신규)
- `src/styles/globals.css` (수정)설계를 업데이트해야 하는 시점:
- 구현 결과 접근 방식이 작동하지 않음이 밝혀졌을 때
- 더 나은 솔루션이 발견되었을 때
- 의존성이나 제약 사항이 변경되었을 때
Tasks (tasks.md)
작업은 구현 체크리스트입니다 — 체크박스가 있는 구체적인 단계입니다.
# Tasks
## 1. Theme Infrastructure
- [ ] 1.1 ThemeContext 생성 (라이트/다크 상태)
- [ ] 1.2 색상에 대한 CSS 커스텀 속성 추가
- [ ] 1.3 localStorage 영속성 구현
- [ ] 1.4 시스템 환경설정 감지 추가
## 2. UI Components
- [ ] 2.1 ThemeToggle 컴포넌트 생성
- [ ] 2.2 설정 페이지에 토글 추가
- [ ] 2.3 헤더에 빠른 토글 포함하도록 업데이트
## 3. Styling
- [ ] 3.1 다크 테마 색상 팔레트 정의
- [ ] 3.2 CSS 변수를 사용하도록 컴포넌트 업데이트
- [ ] 3.3 접근성을 위한 대비 비율 테스트작업 모범 사례:
- 관련 작업을 제목 아래 그룹화
- 계층적 번호 매기기 사용 (1.1, 1.2 등)
- 한 세션에 완료할 수 있을 정도로 작게 유지
- 완료 시 작업 체크
델타 스펙
델타 스펙은 OpenSpec이 브라운필드 개발에서 작동하도록 하는 핵심 개념입니다. 전체 스펙을 다시 설명하는 대신 무엇이 변경되는지 설명합니다.
형식
# Delta for Auth
## ADDED Requirements
### Requirement: Two-Factor Authentication
시스템은 TOTP 기반 이중 인증을 지원해야 한다(MUST).
#### Scenario: 2FA enrollment
- GIVEN 2FA가 활성화되지 않은 사용자
- WHEN 사용자가 설정에서 2FA를 활성화하면
- THEN 인증기 앱 설정을 위한 QR 코드가 표시된다
- AND 활성화 전에 코드로 확인해야 한다
#### Scenario: 2FA login
- GIVEN 2FA가 활성화된 사용자
- WHEN 사용자가 유효한 자격 증명을 제출하면
- THEN OTP 챌린지가 표시된다
- AND 유효한 OTP 후에만 로그인이 완료된다
## MODIFIED Requirements
### Requirement: Session Expiration
시스템은 15분간 비활성 시 세션을 만료시켜야 한다(MUST).
(이전: 30분)
#### Scenario: Idle timeout
- GIVEN 인증된 세션
- WHEN 15분 동안 활동이 없으면
- THEN 세션이 무효화된다
## REMOVED Requirements
### Requirement: Remember Me
(2FA를 위해 폐기됨. 사용자는 각 세션마다 재인증해야 함.)델타 섹션
| 섹션 | 의미 | 아카이브 시 처리 |
|---|---|---|
## ADDED Requirements | 새로운 동작 | 메인 스펙에 추가됨 |
## MODIFIED Requirements | 변경된 동작 | 기존 요구사항을 대체함 |
## REMOVED Requirements | 폐기된 동작 | 변경사항이 retire_capabilities: true를 선언한 경우, 메인 스펙에서 삭제되며 마지막 요구사항 제거 시 해당 기능이 은퇴되고 스펙 파일이 삭제됩니다 |
## Purpose | 완전히 새로운 기능의 목적 | 생성되는 메인 스펙의 Purpose를 시드하며, 스펙이 이미 존재하는 경우 무시됩니다 |
전체 스펙 대신 델타를 사용하는 이유
명확성. 델타는 정확히 무엇이 변경되는지 보여줍니다. 전체 스펙을 읽으면 현재 버전과 정신적으로 차이를 비교해야 합니다.
충돌 방지. 서로 다른 요구사항을 수정하는 한 두 변경사항이 동일한 스펙 파일을 건드려도 충돌이 발생하지 않습니다.
리뷰 효율성. 리뷰어는 변경되지 않은 컨텍스트가 아닌 변경사항을 봅니다. 중요한 것에 집중할 수 있습니다.
브라운필드 적합성. 대부분의 작업은 기존 동작을 수정합니다. 델타는 수정 사항을 일급 시민으로 만듭니다.
Schemas
Schemas는 워크플로의 아티팩트 유형과 그 의존 관계를 정의합니다.
Schemas 작동 방식
# openspec/schemas/spec-driven/schema.yaml
name: spec-driven
artifacts:
- id: proposal
generates: proposal.md
requires: [] # No dependencies, can create first
- id: specs
generates: specs/**/*.md
requires: [proposal] # Needs proposal before creating
- id: design
generates: design.md
requires: [proposal] # Can create in parallel with specs
- id: tasks
generates: tasks.md
requires: [specs, design] # Needs both specs and design first아티팩트는 의존성 그래프를 형성합니다:
proposal
(root node)
│
┌─────────────┴─────────────┐
│ │
▼ ▼
specs design
(requires: (requires:
proposal) proposal)
│ │
└─────────────┬─────────────┘
│
▼
tasks
(requires:
specs, design)의존 관계는 활성화 조건이지, 게이트가 아닙니다. 어떤 것을 만들 수 있는지를 보여주지, 반드시 다음으로 만들어야 하는 것이 무엇인지를 강제하지 않습니다. 필요하지 않다면 design을 건너뛸 수 있습니다. specs를 design보다 먼저 만들거나 나중에 만들 수 있습니다 — 둘 다 proposal에만 의존합니다.
내장 Schemas
spec-driven (기본값)
스펙 기반 개발을 위한 표준 워크플로입니다:
proposal → specs → design → tasks → implement적합한 경우: 구현 전에 스펙에 합의하고 싶은 대부분의 기능 작업에 적합합니다.
사용자 정의 Schemas
팀 워크플로에 맞게 사용자 정의 schemas를 생성하세요:
# Create from scratch
openspec schema init research-first
# Or fork an existing one
openspec schema fork spec-driven research-first사용자 정의 schema 예시:
# openspec/schemas/research-first/schema.yaml
name: research-first
artifacts:
- id: research
generates: research.md
requires: [] # Do research first
- id: proposal
generates: proposal.md
requires: [research] # Proposal informed by research
- id: tasks
generates: tasks.md
requires: [proposal] # Skip specs/design, go straight to tasks사용자 정의 schemas 생성 및 사용에 대한 자세한 내용은 Customization을 참고하세요.
Archive
Archiving은 변경 사항을 완료하여 그 delta specs를 메인 specs에 병합하고, 변경 사항을 역사 기록으로 보존합니다.
Archive 시 발생하는 일
Before archive:
openspec/
├── specs/
│ └── auth/
│ └── spec.md ◄────────────────┐
└── changes/ │
└── add-2fa/ │
├── proposal.md │
├── design.md │ merge
├── tasks.md │
└── specs/ │
└── auth/ │
└── spec.md ─────────┘
After archive:
openspec/
├── specs/
│ └── auth/
│ └── spec.md # Now includes 2FA requirements
└── changes/
└── archive/
└── 2025-01-24-add-2fa/ # Preserved for history
├── proposal.md
├── design.md
├── tasks.md
└── specs/
└── auth/
└── spec.mdArchive 프로세스
Delta 병합. 각 delta spec 섹션(ADDED/MODIFIED/REMOVED)이 해당 메인 spec에 적용됩니다.
Archive로 이동. 변경 사항 폴더가 연대순 정렬을 위해 날짜 접두사가 붙은
changes/archive/로 이동합니다.컨텍스트 보존. 모든 아티팩트가 archive에 그대로 유지됩니다. 변경 사항이 왜 이루어졌는지 항상 되돌아볼 수 있습니다.
Archive가 중요한 이유
깔끔한 상태. 활성 변경 사항(changes/)에는 진행 중인 작업만 표시됩니다. 완료된 작업은 한쪽으로 치워집니다.
감사 추적. Archive는 모든 변경 사항의 전체 컨텍스트를 보존합니다 — 변경된 내용뿐 아니라, 왜 변경했는지 설명하는 proposal, 어떻게 변경했는지 설명하는 design, 수행된 작업을 보여주는 tasks까지 포함합니다.
Spec 진화. 변경 사항이 archive됨에 따라 specs가 유기적으로 성장합니다. 각 archive가 그 delta를 병합하여 시간이 지남에 따라 포괄적인 명세를 구축합니다.
전체 흐름
┌──────────────────────────────────────────────────────────────────────────────┐
│ OPENSPEC FLOW │
│ │
│ ┌────────────────┐ │
│ │ 1. START │ /opsx:propose (core) or /opsx:new (expanded) │
│ │ CHANGE │ │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 2. CREATE │ /opsx:ff or /opsx:continue (expanded workflow) │
│ │ ARTIFACTS │ Creates proposal → specs → design → tasks │
│ │ │ (based on schema dependencies) │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 3. IMPLEMENT │ /opsx:apply │
│ │ TASKS │ Work through tasks, checking them off │
│ │ │◄──── Update artifacts as you learn │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 4. VERIFY │ /opsx:verify (optional) │
│ │ WORK │ Check implementation matches specs │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ ┌──────────────────────────────────────────────┐ │
│ │ 5. ARCHIVE │────►│ Delta specs merge into main specs │ │
│ │ CHANGE │ │ Change folder moves to archive/ │ │
│ └────────────────┘ │ Specs are now the updated source of truth │ │
│ └──────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘선순환 사이클:
- Specs가 현재 동작을 설명합니다
- Changes가 수정 사항을 제안합니다 (delta로)
- Implementation이 변경 사항을 실제로 구현합니다
- Archive가 delta를 specs에 병합합니다
- Specs가 이제 새로운 동작을 설명합니다
- 다음 변경 사항이 업데이트된 specs를 기반으로 구축됩니다
용어집
| 용어 | 정의 |
|---|---|
| Artifact | 변경 사항 내 문서 (proposal, design, tasks 또는 delta specs) |
| Archive | 변경 사항을 완료하고 그 delta를 메인 specs에 병합하는 과정 |
| Change | 시스템에 대한 제안된 수정 사항, 아티팩트를 포함하는 폴더로 패키징됨 |
| Delta spec | 현재 specs에 대한 변경 사항(ADDED/MODIFIED/REMOVED)을 설명하는 스펙 |
| Domain | Specs의 논리적 그룹화 (예: auth/, payments/) |
| Requirement | 시스템이 반드시 가져야 하는 특정 동작 |
| Scenario | 요구 사항의 구체적 예시, 일반적으로 Given/When/Then 형식 |
| Schema | 아티팩트 유형과 그 의존 관계의 정의 |
| Spec | 시스템 동작을 설명하는 명세, 요구 사항과 시나리오를 포함 |
| Source of truth | 현재 합의된 동작을 포함하는 openspec/specs/ 디렉터리 |
다음 단계
- Getting Started - 실용적인 첫 단계
- Workflows - 일반적인 패턴과 각 패턴의 사용 시점
- Commands - 전체 명령어 참조
- Customization - 사용자 정의 schemas 생성 및 프로젝트 구성