[ contents ]
이해하기

개념

이 가이드는 rasen의 핵심 아이디어와 그들이 어떻게 함께 맞춰지는지 설명합니다. 실제 사용 방법은 시작하기워크플로우를 참조하세요.

철학

Rasen은 네 가지 원칙을 중심으로 구축되었습니다:

유연함은 경직되지 않음     — 단계 게이트가 없음, 의미 있는 작업 수행
반복적이며 폭포수가 아님 — 구축하면서 배움, 진행하면서 정제
쉬움은 복잡하지 않음      — 가벼운 설정, 최소한의 의례
기존 코드베이스 우선      — 새로운 것뿐만 아니라 기존 코드베이스도 지원

이 원칙이 중요한 이유

유연함은 경직되지 않음. 전통적인 스펙 시스템은 단계에 잠금니다: 먼저 기획하고, 구현하고, 완료됩니다. Rasen은 더 유연합니다 — 작업에 의미 있는 순서대로 산출물을 생성할 수 있습니다.

반복적이며 폭포수가 아님. 요구사항은 변합니다. 이해가 깊어집니다. 처음에 좋은 접근 방식처럼 보였던 것이 코드베이스를 본 후에는 유지되지 않을 수 있습니다. Rasen은 이 현실을 포용합니다.

쉬움은 복잡하지 않음. 일부 스펙 프레임워크는 광범위한 설정, 엄격한 형식, 무거운 프로세스를 요구합니다. Rasen은 방해하지 않습니다. 초 단위로 초기화하고, 즉시 작업 시작, 필요할 때만 커스터마이징합니다.

기존 코드베이스 우선. 대부분의 소프트웨어 작업은 처음부터 구축하는 것이 아닙니다 — 기존 시스템을 수정하는 것입니다. Rasen의 증량 기반 접근 방식은 단순히 새로운 시스템을 설명하지 않고, 기존 동작에 대한 변경을 쉽게 지정합니다.

큰 그림

Rasen은 작업을 두 가지 주요 영역으로 정리합니다:

┌────────────────────────────────────────────────────────────────────┐
│                               rasen/                               │
│                                                                    │
│   ┌─────────────────────┐      ┌───────────────────────────────┐   │
│   │       specs/        │      │         changes/              │   │
│   │                     │      │                               │   │
│   │  신뢰할 수 있는     │◄─────│  제안된 변경                   │   │
│   │  단일 소스          │ merge│  각 변경 = 하나의 폴더         │   │
│   │  시스템이 현재      │      │  산출물 + 증량 포함           │   │
│   │  어떻게 작동하는지  │      │                               │   │
│   │                     │      │                               │   │
│   └─────────────────────┘      └───────────────────────────────┘   │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

스펙은 신뢰할 수 있는 단일 소스입니다 — 시스템이 현재 어떻게 동작하는지 설명합니다.

변경은 제안된 수정입니다 — 병합할 준비가 될 때까지 별도의 폴더에 있습니다.

이 분리가 핵심입니다. 충돌 없이 여러 변경을 병렬로 작업할 수 있습니다. 변경이 메인 스펙에 영향을 주기 전에 검토할 수 있습니다. 그리고 변경을 보관할 때, 증량이 신뢰할 수 있는 단일 소스에 깔끔하게 병합됩니다.

스펙

스펙은 구조화된 요구사항과 시나리오를 사용하여 시스템의 동작을 설명합니다.

구조

rasen/specs/
├── auth/
│   └── spec.md           # 인증 동작
├── payments/
│   └── spec.md           # 결제 처리
├── notifications/
│   └── spec.md           # 알림 시스템
└── ui/
    └── spec.md           # UI 동작 및 테마

스펙을 도메인별로 정리합니다 — 시스템에 의미 있는 논리적 그룹화. 일반적인 패턴:

  • 기능 영역별: auth/, payments/, search/
  • 컴포넌트별: api/, frontend/, workers/
  • 경계된 컨텍스트별: ordering/, fulfillment/, inventory/

스펙 형식

스펙에는 요구사항이 포함되고, 각 요구사항에는 시나리오가 있습니다:

# 인증 스펙

## 목적
애플리케이션을 위한 인증 및 세션 관리.

## 요구사항

### 요구사항: 사용자 인증
시스템은 성공한 로그인 시 JWT 토큰을 발급해야 합니다(SHALL).

#### 시나리오: 유효한 자격증명
- GIVEN 유효한 자격증명을 가진 사용자
- WHEN 사용자가 로그인 양식을 제출
- THEN JWT 토큰이 반환됨
- AND 사용자가 대시보드로 리다이렉트됨

#### 시나리오: 유효하지 않은 자격증명
- GIVEN 유효하지 않은 자격증명
- WHEN 사용자가 로그인 양식을 제출
- THEN 오류 메시지가 표시됨
- AND 토큰이 발급되지 않음

### 요구사항: 세션 만료
시스템은 30분의 비활성 후 세션을 만료해야 합니다(MUST).

#### 시나리오: 유휴 시간 초과
- GIVEN 인증된 세션
- WHEN 30분이 활동 없이 경과
- THEN 세션이 무효화됨
- AND 사용자가 다시 인증해야 함

주요 요소:

요소 목적
## 목적 이 스펙의 도메인에 대한 고수준 설명
### 요구사항: 시스템이 가져야 할 특정 동작
#### 시나리오: 요구사항의 구체적인 예
SHALL/MUST/SHOULD 요구사항 강도를 나타내는 RFC 2119 키워드

스펙을 이렇게 구조화하는 이유

요구사항은 "무엇"입니다 — 구현을 지정하지 않고 시스템이 무엇을 해야 하는지 명시합니다.

시나리오는 "언제"입니다 — 검증 가능한 구체적인 예를 제공합니다. 좋은 시나리오:

  • 테스트 가능함 (자동화된 테스트를 작성할 수 있음)
  • 긍정 경로와 엣지 케이스 모두를 다룸
  • Given/When/Then 또는 유사한 구조화된 형식을 사용

RFC 2119 키워드 (SHALL, MUST, SHOULD, MAY) 의도를 전달합니다:

  • MUST/SHALL — 절대 요구사항
  • SHOULD — 권장, 하지만 예외 존재
  • MAY — 선택사항

스펙이 무엇인지 (그리고 아닌지)

스펙은 동작 계약, 구현 계획이 아닙니다.

좋은 스펙 내용:

  • 사용자 또는 다운스트림 시스템이 신뢰하는 관찰 가능한 동작
  • 입력, 출력 및 오류 조건
  • 외부 제약사항 (보안, 개인정보보호, 신뢰성, 호환성)
  • 테스트 또는 명시적으로 검증할 수 있는 시나리오

스펙에서 피해야 할 사항:

  • 내부 클래스/함수 이름
  • 라이브러리 또는 프레임워크 선택
  • 단계별 구현 세부사항
  • 상세한 실행 계획 (이것들은 design.md 또는 tasks.md에 속함)

빠른 테스트:

  • 구현이 외부적으로 보이는 동작을 변경하지 않고 변경될 수 있다면, 아마 스펙에 속하지 않습니다.

가벼움 유지: 점진적 엄격함

Rasen은 관료주의를 피하는 것을 목표로 합니다. 변경을 여전히 검증 가능하게 하는 가장 가벼운 수준을 사용합니다.

가벼운 스펙 (기본):

  • 짧은 동작 우선 요구사항
  • 명확한 범위 및 비목표
  • 몇 가지 구체적인 수용 기준

전체 스펙 (더 높은 위험성의 경우):

  • 크로스팀 또는 크로스 리포 변경
  • API/계약 변경, 마이그레이션, 보안/개인정보보호 관심사
  • 모호함이 값비싼 재작업을 야기할 가능성이 있는 변경

대부분의 변경은 가벼운 모드에 남아 있어야 합니다.

인간 + 에이전트 협업

많은 팀에서 인간이 탐색하고 에이전트가 산출물을 초안합니다. 의도된 루프는:

  1. 인간이 의도, 컨텍스트 및 제약사항을 제공합니다.
  2. 에이전트는 이를 동작 우선 요구사항 및 시나리오로 변환합니다.
  3. 에이전트는 spec.md가 아닌 design.mdtasks.md에 구현 세부사항을 유지합니다.
  4. 검증은 구현 전 구조와 명확성을 확인합니다.

이것은 스펙을 인간이 읽기 쉽게 하고 에이전트가 일관되도록 합니다.

변경

변경은 시스템에 대한 제안된 수정이며, 이를 이해하고 구현하기 위해 필요한 모든 것이 있는 폴더로 패키징됩니다.

변경 구조

rasen/changes/add-dark-mode/
├── proposal.md           # 이유와 무엇
├── design.md             # 방법 (기술적 접근)
├── tasks.md              # 구현 체크리스트
├── .openspec.yaml        # 변경 메타데이터 (선택사항)
└── specs/                # 증량 스펙
    └── ui/
        └── spec.md       # ui/spec.md에서 변경되는 것

각 변경은 자체 포함됩니다. 다음을 포함합니다:

  • 산출물 — 의도, 설계 및 작업을 캡처하는 문서
  • 증량 스펙 — 추가, 수정 또는 제거되는 것에 대한 스펙
  • 메타데이터 — 이 특정 변경에 대한 선택적 설정

변경이 폴더인 이유

변경을 폴더로 패키징하는 것은 여러 이점을 가집니다:

  1. 모든 것이 함께. 제안서, 설계, 작업 및 스펙은 한 곳에 있습니다. 다른 위치를 찾아다닐 필요가 없습니다.

  2. 병렬 작업. 여러 변경이 동시에 존재하여 충돌하지 않습니다. add-dark-mode를 작업하면서 fix-auth-bug도 진행 중일 수 있습니다.

  3. 깔끔한 기록. 보관될 때, 변경은 전체 컨텍스트가 보존되어 changes/archive/로 이동합니다. 무엇이 변경되었을 뿐만 아니라 왜 변경되었는지 이해할 수 있습니다.

  4. 검토하기 좋음. 변경 폴더는 검토하기 쉽습니다 — 열고, 제안서를 읽고, 설계를 확인하고, 스펙 증량을 봅니다.

산출물

산출물은 작업을 안내하는 변경 내 문서입니다.

산출물 흐름

제안서 ──────► 스펙 ──────► 설계 ──────► 작업 ──────► 구현
    │           │           │           │
   왜        무엇         어떻게      단계
  + 범위      변경        접근       취할

산출물은 서로 기반합니다. 각 산출물은 다음에 대한 컨텍스트를 제공합니다.

산출물 타입

제안서 (proposal.md)

제안서는 높은 수준에서 의도, 범위접근 방식을 캡처합니다.

# 제안서: 다크 모드 추가

## 의도
사용자가 밤 시간 사용 중 눈 피로를 줄이고 시스템 환경설정과 일치시키기 위해 다크 모드 옵션을 요청했습니다.

## 범위
포함:
- 설정의 테마 토글
- 시스템 환경설정 감지
- localStorage에서 환경설정 유지

제외:
- 커스텀 색상 테마 (향후 작업)
- 페이지별 테마 재정의

## 접근 방식
테마 관리를 위해 CSS 커스텀 속성과 React Context를 사용합니다.
첫 로드에서 시스템 환경설정을 감지하고, 수동 재정의를 허용합니다.

제안서를 언제 업데이트할 것인가:

  • 범위 변경 (축소 또는 확대)
  • 의도 명확화 (문제에 대한 이해 개선)
  • 접근 방식이 근본적으로 변경

스펙 (증량 스펙 specs/)

증량 스펙은 현재 스펙에 비해 변경되는 것을 설명합니다. 아래 증량 스펙을 참조하세요.

설계 (design.md)

설계는 기술적 접근 방식아키텍처 결정을 캡처합니다.

# 설계: 다크 모드 추가

## 기술적 접근 방식
테마 상태는 프롭 드릴을 피하기 위해 React Context를 통해 관리됩니다.
CSS 커스텀 속성은 클래스 토글링 없이 런타임 전환을 가능하게 합니다.

## 아키텍처 결정

### 결정: Context over Redux
테마 상태에 React Context를 사용하는 이유:
- 간단한 이진 상태 (light/dark)
- 복잡한 상태 전환 없음
- Redux 종속성 추가 방지

### 결정: CSS 커스텀 속성
CSS-in-JS 대신 CSS 변수를 사용하는 이유:
- 기존 스타일시트와 호환
- 런타임 오버헤드 없음
- 브라우저 기본 솔루션

## 데이터 흐름
```
ThemeProvider (context)
       │
       ▼
ThemeToggle ◄──► localStorage
       │
       ▼
CSS Variables (applied to :root)
```

## 파일 변경
- `src/contexts/ThemeContext.tsx` (새로움)
- `src/components/ThemeToggle.tsx` (새로움)
- `src/styles/globals.css` (수정됨)

설계를 언제 업데이트할 것인가:

  • 구현에서 접근 방식이 작동하지 않음을 알 수 있음
  • 더 나은 솔루션 발견
  • 종속성 또는 제약사항이 변경

작업 (tasks.md)

작업은 구현 체크리스트 — 체크박스가 있는 구체적인 단계입니다.

# 작업

## 1. 테마 인프라
- [ ] 1.1 light/dark 상태로 ThemeContext 생성
- [ ] 1.2 색상을 위한 CSS 커스텀 속성 추가
- [ ] 1.3 localStorage 지속성 구현
- [ ] 1.4 시스템 환경설정 감지 추가

## 2. UI 컴포넌트
- [ ] 2.1 ThemeToggle 컴포넌트 생성
- [ ] 2.2 설정 페이지에 토글 추가
- [ ] 2.3 빠른 토글을 포함하도록 Header 업데이트

## 3. 스타일링
- [ ] 3.1 다크 테마 색상 팔레트 정의
- [ ] 3.2 CSS 변수를 사용하도록 컴포넌트 업데이트
- [ ] 3.3 접근성을 위한 명암비 테스트

작업 모범 사례:

  • 관련 작업을 제목 아래에 그룹화
  • 계층적 번호 매기기 사용 (1.1, 1.2 등)
  • 한 세션에서 완료할 수 있을 만큼 작업을 작게 유지
  • 완료하면서 작업을 체크오프

증량 스펙

증량 스펙은 rasen이 기존 코드베이스 개발에 적용되도록 만드는 핵심 개념입니다. 전체 스펙을 다시 명시하지 않고 변경되는 것을 설명합니다.

형식

# 인증을 위한 증량

## ADDED 요구사항

### 요구사항: 2단계 인증
시스템은 TOTP 기반 2단계 인증을 지원해야 합니다(MUST).

#### 시나리오: 2FA 등록
- GIVEN 2FA가 활성화되지 않은 사용자
- WHEN 사용자가 설정에서 2FA 활성화
- THEN 인증 앱 설정을 위한 QR 코드가 표시됨
- AND 사용자가 활성화 전 코드로 확인해야 함

#### 시나리오: 2FA 로그인
- GIVEN 2FA가 활성화된 사용자
- WHEN 사용자가 유효한 자격증명 제출
- THEN OTP 챌린지가 제시됨
- AND 유효한 OTP 후에만 로그인 완료

## MODIFIED 요구사항

### 요구사항: 세션 만료
시스템은 15분의 비활성 후 세션을 만료해야 합니다(MUST).
(이전: 30분)

#### 시나리오: 유휴 시간 초과
- GIVEN 인증된 세션
- WHEN 15분이 활동 없이 경과
- THEN 세션이 무효화됨

## REMOVED 요구사항

### 요구사항: 기억하기
(2FA 대신 사용 중단됨. 사용자는 각 세션마다 다시 인증해야 함)

증량 섹션

섹션 의미 보관 시 발생하는 것
## ADDED 요구사항 새로운 동작 메인 스펙에 추가됨
## MODIFIED 요구사항 변경된 동작 기존 요구사항 대체
## REMOVED 요구사항 사용되지 않는 동작 메인 스펙에서 삭제됨

전체 스펙 대신 증량을 사용하는 이유

명확함. 증량은 정확히 무엇이 변경되는지 보여줍니다. 전체 스펙을 읽으면 현재 버전에 대해 정신적으로 diff해야 합니다.

충돌 회피. 두 변경이 동일한 스펙 파일을 만져도 다른 요구사항을 수정하는 한 충돌하지 않습니다.

검토 효율성. 리뷰어는 변경되지 않은 컨텍스트가 아닌 변경을 봅니다. 중요한 것에 집중합니다.

기존 코드베이스 적합성. 대부분의 작업은 기존 동작을 수정합니다. 증량은 수정을 우선적으로 만들고, 사후 생각이 아닙니다.

스키마

스키마는 워크플로우의 산출물 타입과 그들의 의존성을 정의합니다.

스키마 작동 방식

# rasen/schemas/spec-driven/schema.yaml
name: spec-driven
artifacts:
  - id: proposal
    generates: proposal.md
    requires: []              # 의존성 없음, 먼저 생성 가능

  - id: specs
    generates: specs/**/*.md
    requires: [proposal]      # 생성 전 제안서 필요

  - id: design
    generates: design.md
    requires: [proposal]      # 스펙과 병렬로 생성 가능

  - id: tasks
    generates: tasks.md
    requires: [specs, design] # 먼저 스펙과 설계 필요

산출물은 의존성 그래프를 형성합니다:

                    제안서
                   (루트 노드)
                       │
         ┌─────────────┴─────────────┐
         │                           │
         ▼                           ▼
      스펙                       설계
   (requires:                  (requires:
    제안서)                    제안서)
         │                           │
         └─────────────┬─────────────┘
                       │
                       ▼
                    작업
                (requires:
                스펙, 설계)

의존성은 인에이블러이며, 게이트가 아닙니다. 생성 가능한 것을 보여주며, 다음에 반드시 생성해야 할 것을 보여주지 않습니다. 필요하지 않으면 설계를 건너뛸 수 있습니다. 스펙을 설계 전후에 생성할 수 있습니다 — 둘 다 제안서에만 의존합니다.

내장 스키마

spec-driven (기본)

규격 기반 개발을 위한 표준 워크플로우:

제안서 → 스펙 → 설계 → 작업 → 구현

최적 대상: 구현 전 스펙에 동의하려는 대부분의 기능 작업.

커스텀 스키마

팀의 워크플로우를 위해 커스텀 스키마를 생성합니다:

# 처음부터 생성
rasen schema init research-first

# 또는 기존 것을 포크
rasen schema fork spec-driven research-first

커스텀 스키마 예:

# rasen/schemas/research-first/schema.yaml
name: research-first
artifacts:
  - id: research
    generates: research.md
    requires: []           # 먼저 조사 실시

  - id: proposal
    generates: proposal.md
    requires: [research]   # 조사에 의해 결정된 제안서

  - id: tasks
    generates: tasks.md
    requires: [proposal]   # 스펙/설계 건너뛰고, 작업으로 바로

커스터마이징에서 커스텀 스키마 생성 및 사용에 대한 전체 세부사항을 참조하세요.

보관

보관은 증량 스펙을 메인 스펙에 병합하고 변경을 역사를 위해 보존하여 변경을 완료합니다.

보관 시 발생하는 것

보관 전:

rasen/
├── specs/
│   └── auth/
│       └── spec.md ◄────────────────┐
└── changes/                         │
    └── add-2fa/                     │
        ├── proposal.md              │
        ├── design.md                │ merge
        ├── tasks.md                 │
        └── specs/                   │
            └── auth/                │
                └── spec.md ─────────┘


보관 후:

rasen/
├── specs/
│   └── auth/
│       └── spec.md        # 이제 2FA 요구사항 포함
└── changes/
    └── archive/
        └── 2025-01-24-add-2fa/    # 역사를 위해 보존됨
            ├── proposal.md
            ├── design.md
            ├── tasks.md
            └── specs/
                └── auth/
                    └── spec.md

보관 프로세스

  1. 증량 병합. 각 증량 스펙 섹션 (ADDED/MODIFIED/REMOVED)이 해당 메인 스펙에 적용됩니다.

  2. 보관으로 이동. 변경 폴더는 시간 순서 정렬을 위해 날짜 접두사와 함께 changes/archive/로 이동합니다.

  3. 컨텍스트 보존. 모든 산출물은 보관에서 그대로 유지됩니다. 변경이 이루어진 이유뿐만 아니라 무엇이 변경되었는지 이해하기 위해 항상 돌아볼 수 있습니다.

보관이 중요한 이유

깨끗한 상태. 활성 변경(changes/)은 진행 중인 작업만 표시합니다. 완료된 작업은 치워집니다.

감사 추적. 보관은 모든 변경의 전체 컨텍스트를 보존합니다 — 변경된 내용뿐만 아니라 왜 변경되었는지 설명하는 제안서, 방법을 설명하는 설계, 수행된 작업을 보여주는 작업.

스펙 진화. 스펙은 변경이 보관되면서 유기적으로 성장합니다. 각 보관은 증량을 병합하여 시간이 지남에 따라 포괄적인 스펙을 구축합니다.

모두 함께 맞춰지는 방식

┌──────────────────────────────────────────────────────────────────────────────┐
│                                  RASEN 흐름                                  │
│                                                                              │
│   ┌────────────────┐                                                         │
│   │  1. 시작       │  /rasen:propose (core) 또는 /rasen:new (expanded)           │
│   │     변경       │                                                         │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  2. 생성       │  /rasen:ff 또는 /rasen:continue (expanded 워크플로우)       │
│   │     산출물     │  제안서 → 스펙 → 설계 → 작업 생성                       │
│   │                │  (스키마 의존성 기반)                                 │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  3. 구현       │  /rasen:apply                                            │
│   │     작업       │  작업을 진행하면서 체크오프                              │
│   │                │◄──── 배우면서 산출물 업데이트                           │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  4. 검증       │  /rasen:verify (선택사항)                                │
│   │     작업       │  구현이 스펙과 일치하는지 확인                          │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐     ┌──────────────────────────────────────────────┐    │
│   │  5. 보관       │────►│  증량 스펙이 메인 스펙에 병합됨           │    │
│   │     변경       │     │  변경 폴더가 archive/로 이동됨             │    │
│   └────────────────┘     │  스펙이 이제 업데이트된 신뢰할 수 있는     │    │
│                          │  단일 소스입니다                           │    │
│                          └──────────────────────────────────────────────┘    │
│                                                                              │
└──────────────────────────────────────────────────────────────────────────────┘

선순환:

  1. 스펙은 현재 동작을 설명
  2. 변경은 수정을 제안 (증량으로)
  3. 구현이 변경을 실제로 만듦
  4. 보관이 증량을 스펙에 병합
  5. 스펙이 이제 새로운 동작을 설명
  6. 다음 변경이 업데이트된 스펙에 기반함

용어집

용어 정의
산출물 변경 내 문서 (제안서, 설계, 작업 또는 증량 스펙)
보관 변경을 완료하고 증량을 메인 스펙에 병합하는 프로세스
변경 폴더로 패키징된 시스템에 대한 제안된 수정 및 산출물
증량 스펙 현재 스펙에 비해 변경사항을 설명하는 스펙 (ADDED/MODIFIED/REMOVED)
도메인 스펙에 대한 논리적 그룹화 (예: auth/, payments/)
요구사항 시스템이 가져야 할 특정 동작
시나리오 Given/When/Then 형식의 요구사항의 구체적인 예
스키마 산출물 타입과 그들의 의존성의 정의
스펙 요구사항과 시나리오를 포함하는 시스템 동작을 설명하는 스펙
신뢰할 수 있는 단일 소스 rasen/specs/ 디렉터리, 현재 동의된 동작을 포함

다음 단계