moai-adk 0.5.2__py3-none-any.whl → 0.5.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/__init__.py +1 -1
- moai_adk/cli/commands/backup.py +25 -1
- moai_adk/cli/commands/doctor.py +30 -4
- moai_adk/cli/commands/init.py +23 -2
- moai_adk/cli/commands/status.py +32 -2
- moai_adk/cli/commands/update.py +47 -8
- moai_adk/core/project/initializer.py +13 -11
- moai_adk/core/project/phase_executor.py +9 -4
- moai_adk/core/template/processor.py +60 -1
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +8 -0
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +18 -0
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +18 -0
- moai_adk/templates/.claude/agents/alfred/git-manager.md +38 -2
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +18 -0
- moai_adk/templates/.claude/agents/alfred/project-manager.md +6 -0
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +6 -0
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +8 -0
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +17 -0
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +7 -1
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +18 -0
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +6 -0
- moai_adk/templates/.claude/commands/alfred/0-project.md +5 -1
- moai_adk/templates/.claude/commands/alfred/1-plan.md +5 -1
- moai_adk/templates/.claude/commands/alfred/2-run.md +6 -2
- moai_adk/templates/.claude/commands/alfred/3-sync.md +28 -7
- moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +5 -1
- moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md +5 -1
- moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md +5 -1
- moai_adk/templates/.claude/output-styles/alfred/study-with-alfred.md +5 -1
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/SKILL.md +30 -273
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/examples.md +487 -129
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/reference.md +603 -70
- moai_adk/templates/.claude/skills/moai-cc-agents/SKILL.md +22 -2
- moai_adk/templates/.claude/skills/moai-cc-claude-md/SKILL.md +22 -2
- moai_adk/templates/.claude/skills/moai-cc-commands/SKILL.md +22 -2
- moai_adk/templates/.claude/skills/moai-cc-hooks/SKILL.md +22 -2
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/SKILL.md +22 -2
- moai_adk/templates/.claude/skills/moai-cc-memory/SKILL.md +22 -2
- moai_adk/templates/.claude/skills/moai-cc-settings/SKILL.md +22 -2
- moai_adk/templates/.claude/skills/moai-cc-skills/SKILL.md +25 -5
- moai_adk/templates/.claude/skills/moai-essentials-debug/SKILL.md +152 -547
- moai_adk/templates/.claude/skills/moai-essentials-debug/examples.md +835 -878
- moai_adk/templates/.claude/skills/moai-essentials-debug/reference.md +665 -1151
- moai_adk/templates/.claude/skills/moai-skill-factory/SKILL.md +138 -427
- moai_adk/templates/.claude/skills/moai-spec-authoring/README.md +61 -53
- moai_adk/templates/.claude/skills/moai-spec-authoring/SKILL.md +99 -1181
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples.md +541 -0
- moai_adk/templates/.claude/skills/moai-spec-authoring/reference.md +622 -0
- moai_adk/templates/.moai/config.json +5 -5
- moai_adk/templates/.moai/memory/CLAUDE-AGENTS-GUIDE.md +208 -0
- moai_adk/templates/.moai/memory/CLAUDE-PRACTICES.md +369 -0
- moai_adk/templates/.moai/memory/CLAUDE-RULES.md +539 -0
- moai_adk/templates/.moai/memory/{development-guide.md → DEVELOPMENT-GUIDE.md} +3 -3
- moai_adk/templates/.moai/memory/SKILLS-DESCRIPTION-POLICY.md +218 -0
- moai_adk/templates/.moai/memory/config-schema.md +444 -0
- moai_adk/templates/CLAUDE.md +142 -702
- {moai_adk-0.5.2.dist-info → moai_adk-0.5.6.dist-info}/METADATA +294 -336
- {moai_adk-0.5.2.dist-info → moai_adk-0.5.6.dist-info}/RECORD +63 -56
- /moai_adk/templates/.moai/memory/{gitflow-protection-policy.md → GITFLOW-PROTECTION-POLICY.md} +0 -0
- /moai_adk/templates/.moai/memory/{spec-metadata.md → SPEC-METADATA.md} +0 -0
- {moai_adk-0.5.2.dist-info → moai_adk-0.5.6.dist-info}/WHEEL +0 -0
- {moai_adk-0.5.2.dist-info → moai_adk-0.5.6.dist-info}/entry_points.txt +0 -0
- {moai_adk-0.5.2.dist-info → moai_adk-0.5.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,622 @@
|
|
|
1
|
+
# SPEC Authoring Reference
|
|
2
|
+
|
|
3
|
+
## 메타데이터 완전 레퍼런스
|
|
4
|
+
|
|
5
|
+
### 7개 필수 필드
|
|
6
|
+
|
|
7
|
+
#### 1. `id` – 고유 SPEC 식별자
|
|
8
|
+
|
|
9
|
+
**형식**: `<DOMAIN>-<NUMBER>`
|
|
10
|
+
|
|
11
|
+
**규칙**:
|
|
12
|
+
- 할당 후 불변
|
|
13
|
+
- 대문자 도메인 사용 (예: `AUTH`, `PAYMENT`, `CONFIG`)
|
|
14
|
+
- 세 자리 숫자 (001–999)
|
|
15
|
+
- 중복 확인: `rg "@SPEC:AUTH-001" -n .moai/specs/`
|
|
16
|
+
|
|
17
|
+
**예시**:
|
|
18
|
+
- `AUTH-001` (인증 기능)
|
|
19
|
+
- `INSTALLER-SEC-001` (설치 프로그램 보안)
|
|
20
|
+
- `TRUST-001` (TRUST 원칙)
|
|
21
|
+
- `CONFIG-001` (설정 스키마)
|
|
22
|
+
|
|
23
|
+
**디렉토리 구조**:
|
|
24
|
+
```
|
|
25
|
+
.moai/specs/SPEC-AUTH-001/
|
|
26
|
+
├── spec.md # 메인 SPEC 문서
|
|
27
|
+
├── diagrams/ # 선택: 아키텍처 다이어그램
|
|
28
|
+
└── examples/ # 선택: 코드 예제
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### 2. `version` – 시맨틱 버전
|
|
32
|
+
|
|
33
|
+
**형식**: `MAJOR.MINOR.PATCH`
|
|
34
|
+
|
|
35
|
+
**생애주기**:
|
|
36
|
+
|
|
37
|
+
| Version | Status | Description | Trigger |
|
|
38
|
+
|---------|--------|-------------|---------|
|
|
39
|
+
| `0.0.1` | draft | 초안 | SPEC 생성 |
|
|
40
|
+
| `0.0.x` | draft | 초안 개선 | 콘텐츠 편집 |
|
|
41
|
+
| `0.1.0` | completed | 구현 완료 | TDD 후 `/alfred:3-sync` |
|
|
42
|
+
| `0.1.x` | completed | 버그 수정, 문서 업데이트 | 구현 후 패치 |
|
|
43
|
+
| `0.x.0` | completed | 기능 추가 | 마이너 개선 |
|
|
44
|
+
| `1.0.0` | completed | 프로덕션 안정 | 이해관계자 승인 |
|
|
45
|
+
|
|
46
|
+
**버전 업데이트 예시**:
|
|
47
|
+
```markdown
|
|
48
|
+
## HISTORY
|
|
49
|
+
|
|
50
|
+
### v0.2.0 (2025-11-15)
|
|
51
|
+
- **ADDED**: 다중 인증 지원
|
|
52
|
+
- **CHANGED**: 토큰 만료 시간 30분으로 연장
|
|
53
|
+
- **AUTHOR**: @YourHandle
|
|
54
|
+
|
|
55
|
+
### v0.1.0 (2025-10-30)
|
|
56
|
+
- **COMPLETED**: TDD 구현 완료
|
|
57
|
+
- **EVIDENCE**: Commits 4c66076, 34e1bd9
|
|
58
|
+
- **TEST COVERAGE**: 89.13%
|
|
59
|
+
|
|
60
|
+
### v0.0.2 (2025-10-25)
|
|
61
|
+
- **REFINED**: 비밀번호 재설정 플로우 요구사항 추가
|
|
62
|
+
- **AUTHOR**: @YourHandle
|
|
63
|
+
|
|
64
|
+
### v0.0.1 (2025-10-23)
|
|
65
|
+
- **INITIAL**: JWT 인증 SPEC 초안 생성
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### 3. `status` – 진행 상태
|
|
69
|
+
|
|
70
|
+
**값**: `draft` | `active` | `completed` | `deprecated`
|
|
71
|
+
|
|
72
|
+
**생애주기 흐름**:
|
|
73
|
+
```
|
|
74
|
+
draft → active → completed → [deprecated]
|
|
75
|
+
↓ ↓ ↓
|
|
76
|
+
/alfred:1-plan /alfred:2-run /alfred:3-sync
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**전환**:
|
|
80
|
+
- `draft`: 작성 중 (v0.0.x)
|
|
81
|
+
- `active`: 구현 진행 중 (v0.0.x → v0.1.0)
|
|
82
|
+
- `completed`: 구현 완료 (v0.1.0+)
|
|
83
|
+
- `deprecated`: 폐기 예정
|
|
84
|
+
|
|
85
|
+
#### 4. `created` – 생성일
|
|
86
|
+
|
|
87
|
+
**형식**: `YYYY-MM-DD`
|
|
88
|
+
|
|
89
|
+
**규칙**:
|
|
90
|
+
- 한 번 설정, 변경 없음
|
|
91
|
+
- ISO 8601 날짜 형식
|
|
92
|
+
- 첫 초안 날짜
|
|
93
|
+
|
|
94
|
+
**예시**: `created: 2025-10-23`
|
|
95
|
+
|
|
96
|
+
#### 5. `updated` – 최종 수정일
|
|
97
|
+
|
|
98
|
+
**형식**: `YYYY-MM-DD`
|
|
99
|
+
|
|
100
|
+
**규칙**:
|
|
101
|
+
- 모든 콘텐츠 변경 시 업데이트
|
|
102
|
+
- 초기에는 `created`와 동일
|
|
103
|
+
- 최신 편집 날짜 반영
|
|
104
|
+
|
|
105
|
+
**업데이트 패턴**:
|
|
106
|
+
```yaml
|
|
107
|
+
created: 2025-10-23 # 변경 없음
|
|
108
|
+
updated: 2025-10-25 # 편집 시 변경
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### 6. `author` – 주 작성자
|
|
112
|
+
|
|
113
|
+
**형식**: `@{GitHubHandle}`
|
|
114
|
+
|
|
115
|
+
**규칙**:
|
|
116
|
+
- 단일 값 (배열 아님)
|
|
117
|
+
- `@` 접두사 필수
|
|
118
|
+
- 대소문자 구분 (예: `@Goos`, `@goos` 아님)
|
|
119
|
+
- 추가 기여자는 HISTORY 섹션에 기록
|
|
120
|
+
|
|
121
|
+
**예시**:
|
|
122
|
+
```yaml
|
|
123
|
+
# 올바름
|
|
124
|
+
author: @Goos
|
|
125
|
+
|
|
126
|
+
# 잘못됨
|
|
127
|
+
author: goos # @ 누락
|
|
128
|
+
authors: [@Goos] # 배열 불가
|
|
129
|
+
author: @goos # 대소문자 오류
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### 7. `priority` – 작업 우선순위
|
|
133
|
+
|
|
134
|
+
**값**: `critical` | `high` | `medium` | `low`
|
|
135
|
+
|
|
136
|
+
**가이드라인**:
|
|
137
|
+
|
|
138
|
+
| Priority | Description | Examples |
|
|
139
|
+
|----------|-------------|----------|
|
|
140
|
+
| `critical` | 프로덕션 차단, 보안 취약점 | 보안 패치, 치명적 버그 |
|
|
141
|
+
| `high` | 주요 기능, 핵심 기능 | 인증, 결제 시스템 |
|
|
142
|
+
| `medium` | 개선, 향상 | UI 폴리시, 성능 최적화 |
|
|
143
|
+
| `low` | 있으면 좋음, 문서화 | README 업데이트, 마이너 리팩토링 |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### 9개 선택 필드
|
|
148
|
+
|
|
149
|
+
#### 8. `category` – 변경 유형
|
|
150
|
+
|
|
151
|
+
**값**: `feature` | `bugfix` | `refactor` | `security` | `docs` | `perf`
|
|
152
|
+
|
|
153
|
+
**용도**:
|
|
154
|
+
```yaml
|
|
155
|
+
category: feature # 새 기능
|
|
156
|
+
category: bugfix # 결함 해결
|
|
157
|
+
category: refactor # 코드 구조 개선
|
|
158
|
+
category: security # 보안 강화
|
|
159
|
+
category: docs # 문서 업데이트
|
|
160
|
+
category: perf # 성능 최적화
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### 9. `labels` – 분류 태그
|
|
164
|
+
|
|
165
|
+
**형식**: 문자열 배열
|
|
166
|
+
|
|
167
|
+
**목적**: 검색, 필터링, 그룹화
|
|
168
|
+
|
|
169
|
+
**모범 사례**:
|
|
170
|
+
- 소문자, kebab-case 사용
|
|
171
|
+
- SPEC당 2-5개 레이블
|
|
172
|
+
- `category`와 중복 방지
|
|
173
|
+
|
|
174
|
+
**예시**:
|
|
175
|
+
```yaml
|
|
176
|
+
labels:
|
|
177
|
+
- authentication
|
|
178
|
+
- jwt
|
|
179
|
+
- security
|
|
180
|
+
|
|
181
|
+
labels:
|
|
182
|
+
- performance
|
|
183
|
+
- optimization
|
|
184
|
+
- caching
|
|
185
|
+
|
|
186
|
+
labels:
|
|
187
|
+
- installer
|
|
188
|
+
- template
|
|
189
|
+
- cross-platform
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### 10-13. 관계 필드 (의존성 그래프)
|
|
193
|
+
|
|
194
|
+
##### `depends_on` – 필수 SPEC
|
|
195
|
+
|
|
196
|
+
**의미**: 먼저 완료되어야 하는 SPEC
|
|
197
|
+
|
|
198
|
+
**예시**:
|
|
199
|
+
```yaml
|
|
200
|
+
depends_on:
|
|
201
|
+
- USER-001 # 사용자 모델 SPEC
|
|
202
|
+
- TOKEN-001 # 토큰 생성 SPEC
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**사용 사례**: 실행 순서, 병렬화 결정
|
|
206
|
+
|
|
207
|
+
##### `blocks` – 차단된 SPEC
|
|
208
|
+
|
|
209
|
+
**의미**: 이 SPEC이 해결될 때까지 진행할 수 없는 SPEC
|
|
210
|
+
|
|
211
|
+
**예시**:
|
|
212
|
+
```yaml
|
|
213
|
+
blocks:
|
|
214
|
+
- AUTH-002 # OAuth 통합은 기본 인증을 기다림
|
|
215
|
+
- PAYMENT-001 # 결제는 인증 필요
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
##### `related_specs` – 관련 SPEC
|
|
219
|
+
|
|
220
|
+
**의미**: 직접 의존성 없는 관련 항목
|
|
221
|
+
|
|
222
|
+
**예시**:
|
|
223
|
+
```yaml
|
|
224
|
+
related_specs:
|
|
225
|
+
- SESSION-001 # 세션 관리 (관련되지만 독립적)
|
|
226
|
+
- AUDIT-001 # 감사 로깅 (횡단 관심사)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
##### `related_issue` – 연결된 GitHub 이슈
|
|
230
|
+
|
|
231
|
+
**형식**: 전체 GitHub 이슈 URL
|
|
232
|
+
|
|
233
|
+
**예시**:
|
|
234
|
+
```yaml
|
|
235
|
+
related_issue: "https://github.com/modu-ai/moai-adk/issues/42"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### 14-15. 범위 필드 (영향 분석)
|
|
239
|
+
|
|
240
|
+
##### `scope.packages` – 영향받는 패키지
|
|
241
|
+
|
|
242
|
+
**목적**: 어떤 패키지/모듈이 영향받는지 추적
|
|
243
|
+
|
|
244
|
+
**예시**:
|
|
245
|
+
```yaml
|
|
246
|
+
scope:
|
|
247
|
+
packages:
|
|
248
|
+
- src/core/auth
|
|
249
|
+
- src/core/token
|
|
250
|
+
- src/api/routes/auth
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
##### `scope.files` – 주요 파일
|
|
254
|
+
|
|
255
|
+
**목적**: 주요 구현 파일 참조
|
|
256
|
+
|
|
257
|
+
**예시**:
|
|
258
|
+
```yaml
|
|
259
|
+
scope:
|
|
260
|
+
files:
|
|
261
|
+
- auth-service.ts
|
|
262
|
+
- token-manager.ts
|
|
263
|
+
- auth.routes.ts
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## EARS 요구사항 문법
|
|
269
|
+
|
|
270
|
+
### 5가지 EARS 패턴
|
|
271
|
+
|
|
272
|
+
EARS (Easy Approach to Requirements Syntax)는 친숙한 키워드를 사용하여 체계적이고 테스트 가능한 요구사항을 제공합니다.
|
|
273
|
+
|
|
274
|
+
#### 패턴 1: Ubiquitous Requirements
|
|
275
|
+
|
|
276
|
+
**템플릿**: `시스템은 [능력]해야 한다.`
|
|
277
|
+
|
|
278
|
+
**목적**: 항상 활성화된 기본 기능
|
|
279
|
+
|
|
280
|
+
**특성**:
|
|
281
|
+
- 전제 조건 없음
|
|
282
|
+
- 항상 적용 가능
|
|
283
|
+
- 핵심 기능 정의
|
|
284
|
+
|
|
285
|
+
**예시**:
|
|
286
|
+
```markdown
|
|
287
|
+
**UR-001**: 시스템은 사용자 인증을 제공해야 한다.
|
|
288
|
+
|
|
289
|
+
**UR-002**: 시스템은 HTTPS 연결을 지원해야 한다.
|
|
290
|
+
|
|
291
|
+
**UR-003**: 시스템은 사용자 인증 정보를 안전하게 저장해야 한다.
|
|
292
|
+
|
|
293
|
+
**UR-004**: 모바일 앱의 크기는 50 MB 미만이어야 한다.
|
|
294
|
+
|
|
295
|
+
**UR-005**: API 응답 시간은 요청의 95%에 대해 200ms를 초과하지 않아야 한다.
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**모범 사례**:
|
|
299
|
+
- ✅ 능동태 사용
|
|
300
|
+
- ✅ 요구사항당 단일 책임
|
|
301
|
+
- ✅ 측정 가능한 결과
|
|
302
|
+
- ❌ 모호한 용어 피하기 ("사용자 친화적", "빠른")
|
|
303
|
+
|
|
304
|
+
#### 패턴 2: Event-driven Requirements
|
|
305
|
+
|
|
306
|
+
**템플릿**: `WHEN [트리거], 시스템은 [응답]해야 한다.`
|
|
307
|
+
|
|
308
|
+
**목적**: 특정 이벤트에 의해 트리거되는 동작 정의
|
|
309
|
+
|
|
310
|
+
**특성**:
|
|
311
|
+
- 개별 이벤트에 의해 트리거
|
|
312
|
+
- 일회성 응답
|
|
313
|
+
- 원인-결과 관계
|
|
314
|
+
|
|
315
|
+
**예시**:
|
|
316
|
+
```markdown
|
|
317
|
+
**ER-001**: WHEN 사용자가 유효한 인증 정보를 제출하면, 시스템은 JWT 토큰을 발급해야 한다.
|
|
318
|
+
|
|
319
|
+
**ER-002**: WHEN 토큰이 만료되면, 시스템은 HTTP 401 Unauthorized를 반환해야 한다.
|
|
320
|
+
|
|
321
|
+
**ER-003**: WHEN 사용자가 "비밀번호 찾기"를 클릭하면, 시스템은 비밀번호 재설정 이메일을 보내야 한다.
|
|
322
|
+
|
|
323
|
+
**ER-004**: WHEN 데이터베이스 연결이 실패하면, 시스템은 지수 백오프로 3번 재시도해야 한다.
|
|
324
|
+
|
|
325
|
+
**ER-005**: WHEN 파일 업로드가 10 MB를 초과하면, 시스템은 에러 메시지와 함께 업로드를 거부해야 한다.
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**고급 패턴** (사후 조건 포함):
|
|
329
|
+
```markdown
|
|
330
|
+
**ER-006**: WHEN 결제 거래가 완료되면, 시스템은 확인 이메일을 보낸 다음 주문 상태를 "paid"로 업데이트해야 한다.
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**모범 사례**:
|
|
334
|
+
- ✅ 요구사항당 단일 트리거
|
|
335
|
+
- ✅ 구체적이고 테스트 가능한 응답
|
|
336
|
+
- ✅ 에러 조건 포함
|
|
337
|
+
- ❌ 여러 WHEN 연결하지 않기
|
|
338
|
+
|
|
339
|
+
#### 패턴 3: State-driven Requirements
|
|
340
|
+
|
|
341
|
+
**템플릿**: `WHILE [상태], 시스템은 [동작]해야 한다.`
|
|
342
|
+
|
|
343
|
+
**목적**: 상태 중 지속적인 동작
|
|
344
|
+
|
|
345
|
+
**특성**:
|
|
346
|
+
- 상태가 지속되는 동안 활성
|
|
347
|
+
- 지속적인 모니터링
|
|
348
|
+
- 상태 의존적 동작
|
|
349
|
+
|
|
350
|
+
**예시**:
|
|
351
|
+
```markdown
|
|
352
|
+
**SR-001**: WHILE 사용자가 인증된 상태이면, 시스템은 보호된 라우트에 대한 접근을 허용해야 한다.
|
|
353
|
+
|
|
354
|
+
**SR-002**: WHILE 토큰이 유효하면, 시스템은 토큰 클레임에서 사용자 ID를 추출해야 한다.
|
|
355
|
+
|
|
356
|
+
**SR-003**: WHILE 시스템이 유지보수 모드이면, 시스템은 HTTP 503 Service Unavailable을 반환해야 한다.
|
|
357
|
+
|
|
358
|
+
**SR-004**: WHILE 배터리 잔량이 20% 미만이면, 모바일 앱은 백그라운드 동기화 빈도를 줄여야 한다.
|
|
359
|
+
|
|
360
|
+
**SR-005**: WHILE 파일 업로드가 진행 중이면, UI는 진행 표시줄을 표시해야 한다.
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**모범 사례**:
|
|
364
|
+
- ✅ 상태 경계 명확히 정의
|
|
365
|
+
- ✅ 상태 진입/종료 조건 명시
|
|
366
|
+
- ✅ 상태 전환 테스트
|
|
367
|
+
- ❌ 겹치는 상태 피하기
|
|
368
|
+
|
|
369
|
+
#### 패턴 4: Optional Features
|
|
370
|
+
|
|
371
|
+
**템플릿**: `WHERE [기능], 시스템은 [동작]할 수 있다.`
|
|
372
|
+
|
|
373
|
+
**목적**: 기능 플래그 기반 조건부 기능
|
|
374
|
+
|
|
375
|
+
**특성**:
|
|
376
|
+
- 기능이 존재하는 경우에만 적용
|
|
377
|
+
- 구성 의존적
|
|
378
|
+
- 제품 변형 지원
|
|
379
|
+
|
|
380
|
+
**예시**:
|
|
381
|
+
```markdown
|
|
382
|
+
**OF-001**: WHERE 다중 인증이 활성화된 경우, 시스템은 OTP 검증을 요구할 수 있다.
|
|
383
|
+
|
|
384
|
+
**OF-002**: WHERE 세션 로깅이 활성화된 경우, 시스템은 로그인 타임스탬프를 기록할 수 있다.
|
|
385
|
+
|
|
386
|
+
**OF-003**: WHERE 프리미엄 구독이 활성화된 경우, 시스템은 무제한 API 호출을 허용할 수 있다.
|
|
387
|
+
|
|
388
|
+
**OF-004**: WHERE 다크 모드가 선택된 경우, UI는 어두운 색 구성표로 렌더링할 수 있다.
|
|
389
|
+
|
|
390
|
+
**OF-005**: WHERE 분석 동의가 부여된 경우, 시스템은 사용자 동작을 추적할 수 있다.
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**모범 사례**:
|
|
394
|
+
- ✅ "할 수 있다(can)" 사용 (허용), "해야 한다(shall)" 아님 (필수)
|
|
395
|
+
- ✅ 기능 플래그 조건 명확히 정의
|
|
396
|
+
- ✅ 기능 없을 때 기본 동작 명시
|
|
397
|
+
- ❌ 핵심 기능을 선택 사항으로 만들지 않기
|
|
398
|
+
|
|
399
|
+
#### 패턴 5: Constraints
|
|
400
|
+
|
|
401
|
+
**템플릿**: `IF [조건], THEN 시스템은 [제약]해야 한다.`
|
|
402
|
+
|
|
403
|
+
**목적**: 품질 속성 및 비즈니스 규칙 강제
|
|
404
|
+
|
|
405
|
+
**특성**:
|
|
406
|
+
- 조건부 강제
|
|
407
|
+
- 품질 게이트
|
|
408
|
+
- 비즈니스 규칙 검증
|
|
409
|
+
|
|
410
|
+
**예시**:
|
|
411
|
+
```markdown
|
|
412
|
+
**C-001**: IF 토큰이 만료되었다면, THEN 시스템은 접근을 거부하고 HTTP 401을 반환해야 한다.
|
|
413
|
+
|
|
414
|
+
**C-002**: IF 10분 이내에 5번 이상 로그인 실패가 발생하면, THEN 시스템은 임시로 계정을 잠가야 한다.
|
|
415
|
+
|
|
416
|
+
**C-003**: 액세스 토큰은 15분 수명을 초과하지 않아야 한다.
|
|
417
|
+
|
|
418
|
+
**C-004**: IF 비밀번호가 8자 미만이면, THEN 시스템은 등록을 거부해야 한다.
|
|
419
|
+
|
|
420
|
+
**C-005**: IF API 속도 제한이 초과되면, THEN 시스템은 HTTP 429 Too Many Requests를 반환해야 한다.
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
**단순화된 제약** (조건 없음):
|
|
424
|
+
```markdown
|
|
425
|
+
**C-006**: 시스템은 평문 비밀번호를 저장하지 않아야 한다.
|
|
426
|
+
|
|
427
|
+
**C-007**: /health 및 /login을 제외한 모든 API 엔드포인트는 인증을 요구해야 한다.
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**모범 사례**:
|
|
431
|
+
- ✅ 엄격한 제약에는 SHALL, 부드러운 권장사항에는 SHOULD 사용
|
|
432
|
+
- ✅ 제한 정량화 (시간, 크기, 횟수)
|
|
433
|
+
- ✅ 강제 메커니즘 명시
|
|
434
|
+
- ❌ 모호한 제약 피하기
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## EARS 패턴 선택 가이드
|
|
439
|
+
|
|
440
|
+
| 패턴 | 키워드 | 사용 시기 | 예시 컨텍스트 |
|
|
441
|
+
|---------|---------|----------|-----------------|
|
|
442
|
+
| **Ubiquitous** | shall | 핵심 기능, 항상 활성 | "시스템은 로그인을 제공해야 한다" |
|
|
443
|
+
| **Event-driven** | WHEN | 개별 이벤트에 대한 응답 | "WHEN 로그인 실패 시, 에러 표시" |
|
|
444
|
+
| **State-driven** | WHILE | 상태 중 지속적 동작 | "WHILE 로그인 상태, 접근 허용" |
|
|
445
|
+
| **Optional** | WHERE | 기능 플래그 또는 구성 | "WHERE 프리미엄이면, 기능 해제" |
|
|
446
|
+
| **Constraints** | IF-THEN | 품질 게이트, 비즈니스 규칙 | "IF 만료되었다면, 거부" |
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## HISTORY 섹션 형식
|
|
451
|
+
|
|
452
|
+
HISTORY 섹션은 모든 SPEC 버전과 변경 사항을 문서화합니다.
|
|
453
|
+
|
|
454
|
+
### 구조
|
|
455
|
+
|
|
456
|
+
```markdown
|
|
457
|
+
## HISTORY
|
|
458
|
+
|
|
459
|
+
### v{MAJOR}.{MINOR}.{PATCH} ({YYYY-MM-DD})
|
|
460
|
+
- **{CHANGE_TYPE}**: {설명}
|
|
461
|
+
- **AUTHOR**: {GitHub 핸들}
|
|
462
|
+
- **{추가 컨텍스트}**: {세부사항}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### 변경 유형
|
|
466
|
+
|
|
467
|
+
| Type | Description | Example |
|
|
468
|
+
|------|-------------|---------|
|
|
469
|
+
| **INITIAL** | 첫 초안 | `v0.0.1: INITIAL 초안 생성` |
|
|
470
|
+
| **REFINED** | 초안 중 콘텐츠 업데이트 | `v0.0.2: REFINED 검토 기반 요구사항` |
|
|
471
|
+
| **COMPLETED** | 구현 완료 | `v0.1.0: COMPLETED TDD 구현` |
|
|
472
|
+
| **ADDED** | 새 요구사항/기능 | `v0.2.0: ADDED 다중 인증` |
|
|
473
|
+
| **CHANGED** | 수정된 요구사항 | `v0.2.0: CHANGED 토큰 만료 15분→30분` |
|
|
474
|
+
| **FIXED** | 구현 후 버그 수정 | `v0.1.1: FIXED 토큰 갱신 로직` |
|
|
475
|
+
| **DEPRECATED** | 폐기 예정 표시 | `v1.5.0: DEPRECATED 레거시 인증 엔드포인트` |
|
|
476
|
+
|
|
477
|
+
### 완전한 HISTORY 예시
|
|
478
|
+
|
|
479
|
+
```markdown
|
|
480
|
+
## HISTORY
|
|
481
|
+
|
|
482
|
+
### v0.2.0 (2025-11-15)
|
|
483
|
+
- **ADDED**: OTP를 통한 다중 인증 지원
|
|
484
|
+
- **CHANGED**: 사용자 피드백 기반으로 토큰 만료 30분으로 연장
|
|
485
|
+
- **AUTHOR**: @Goos
|
|
486
|
+
- **REVIEWER**: @SecurityTeam
|
|
487
|
+
- **RATIONALE**: 보안 태세를 유지하면서 UX 개선
|
|
488
|
+
|
|
489
|
+
### v0.1.1 (2025-11-01)
|
|
490
|
+
- **FIXED**: 토큰 갱신 경쟁 조건
|
|
491
|
+
- **EVIDENCE**: Commit 3f9a2b7
|
|
492
|
+
- **AUTHOR**: @Goos
|
|
493
|
+
|
|
494
|
+
### v0.1.0 (2025-10-30)
|
|
495
|
+
- **COMPLETED**: TDD 구현 완료
|
|
496
|
+
- **AUTHOR**: @Goos
|
|
497
|
+
- **EVIDENCE**: Commits 4c66076, 34e1bd9, 1dec08f
|
|
498
|
+
- **TEST COVERAGE**: 89.13% (목표: 85%)
|
|
499
|
+
- **QUALITY METRICS**:
|
|
500
|
+
- Test Pass Rate: 100% (42/42 tests)
|
|
501
|
+
- Linting: ruff ✅
|
|
502
|
+
- Type Checking: mypy ✅
|
|
503
|
+
- **TAG CHAIN**:
|
|
504
|
+
- @SPEC:AUTH-001: 1 occurrence
|
|
505
|
+
- @TEST:AUTH-001: 8 occurrences
|
|
506
|
+
- @CODE:AUTH-001: 12 occurrences
|
|
507
|
+
|
|
508
|
+
### v0.0.2 (2025-10-25)
|
|
509
|
+
- **REFINED**: 비밀번호 재설정 플로우 요구사항 추가
|
|
510
|
+
- **REFINED**: 토큰 수명 제약 명확화
|
|
511
|
+
- **AUTHOR**: @Goos
|
|
512
|
+
|
|
513
|
+
### v0.0.1 (2025-10-23)
|
|
514
|
+
- **INITIAL**: JWT 인증 SPEC 초안 생성
|
|
515
|
+
- **AUTHOR**: @Goos
|
|
516
|
+
- **SCOPE**: 사용자 인증, 토큰 생성, 토큰 검증
|
|
517
|
+
- **CONTEXT**: 2025년 4분기 제품 로드맵 요구사항
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## TAG 통합
|
|
523
|
+
|
|
524
|
+
### TAG 블록 형식
|
|
525
|
+
|
|
526
|
+
모든 SPEC 문서는 타이틀 다음에 TAG 블록으로 시작합니다:
|
|
527
|
+
|
|
528
|
+
```markdown
|
|
529
|
+
# @SPEC:AUTH-001: JWT Authentication System
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### TAG 체인 참조
|
|
533
|
+
|
|
534
|
+
SPEC에서 관련 TAG 연결:
|
|
535
|
+
|
|
536
|
+
```markdown
|
|
537
|
+
## Traceability (@TAG Chain)
|
|
538
|
+
|
|
539
|
+
### TAG 체인 구조
|
|
540
|
+
```
|
|
541
|
+
@SPEC:AUTH-001 (이 문서)
|
|
542
|
+
↓
|
|
543
|
+
@TEST:AUTH-001 (tests/auth/service.test.ts)
|
|
544
|
+
↓
|
|
545
|
+
@CODE:AUTH-001 (src/auth/service.ts, src/auth/token-manager.ts)
|
|
546
|
+
↓
|
|
547
|
+
@DOC:AUTH-001 (docs/api/authentication.md)
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### 검증 명령어
|
|
551
|
+
```bash
|
|
552
|
+
# SPEC TAG 검증
|
|
553
|
+
rg '@SPEC:AUTH-001' -n .moai/specs/
|
|
554
|
+
|
|
555
|
+
# 중복 ID 확인
|
|
556
|
+
rg '@SPEC:AUTH' -n .moai/specs/
|
|
557
|
+
rg 'AUTH-001' -n
|
|
558
|
+
|
|
559
|
+
# 전체 TAG 체인 스캔
|
|
560
|
+
rg '@(SPEC|TEST|CODE|DOC):AUTH-001' -n
|
|
561
|
+
```
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
---
|
|
565
|
+
|
|
566
|
+
## 검증 명령어
|
|
567
|
+
|
|
568
|
+
### 빠른 검증 스크립트
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
#!/usr/bin/env bash
|
|
572
|
+
# validate-spec.sh - SPEC 검증 헬퍼
|
|
573
|
+
|
|
574
|
+
SPEC_DIR="$1"
|
|
575
|
+
|
|
576
|
+
echo "SPEC 검증 중: $SPEC_DIR"
|
|
577
|
+
|
|
578
|
+
# 필수 필드 확인
|
|
579
|
+
echo -n "필수 필드... "
|
|
580
|
+
rg "^(id|version|status|created|updated|author|priority):" "$SPEC_DIR/spec.md" | wc -l | grep -q "7" && echo "✅" || echo "❌"
|
|
581
|
+
|
|
582
|
+
# 작성자 형식 확인
|
|
583
|
+
echo -n "작성자 형식... "
|
|
584
|
+
rg "^author: @[A-Z]" "$SPEC_DIR/spec.md" > /dev/null && echo "✅" || echo "❌"
|
|
585
|
+
|
|
586
|
+
# 버전 형식 확인
|
|
587
|
+
echo -n "버전 형식... "
|
|
588
|
+
rg "^version: 0\.\d+\.\d+" "$SPEC_DIR/spec.md" > /dev/null && echo "✅" || echo "❌"
|
|
589
|
+
|
|
590
|
+
# HISTORY 섹션 확인
|
|
591
|
+
echo -n "HISTORY 섹션... "
|
|
592
|
+
rg "^## HISTORY" "$SPEC_DIR/spec.md" > /dev/null && echo "✅" || echo "❌"
|
|
593
|
+
|
|
594
|
+
# TAG 블록 확인
|
|
595
|
+
echo -n "TAG 블록... "
|
|
596
|
+
rg "^# @SPEC:" "$SPEC_DIR/spec.md" > /dev/null && echo "✅" || echo "❌"
|
|
597
|
+
|
|
598
|
+
# 중복 ID 확인
|
|
599
|
+
SPEC_ID=$(basename "$SPEC_DIR" | sed 's/SPEC-//')
|
|
600
|
+
DUPLICATE_COUNT=$(rg "@SPEC:$SPEC_ID" -n .moai/specs/ | wc -l)
|
|
601
|
+
echo -n "중복 ID 확인... "
|
|
602
|
+
[ "$DUPLICATE_COUNT" -eq 1 ] && echo "✅" || echo "❌ (found $DUPLICATE_COUNT occurrences)"
|
|
603
|
+
|
|
604
|
+
echo "검증 완료!"
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### 사용법
|
|
608
|
+
|
|
609
|
+
```bash
|
|
610
|
+
# 단일 SPEC 검증
|
|
611
|
+
./validate-spec.sh .moai/specs/SPEC-AUTH-001
|
|
612
|
+
|
|
613
|
+
# 모든 SPEC 검증
|
|
614
|
+
for spec in .moai/specs/SPEC-*/; do
|
|
615
|
+
./validate-spec.sh "$spec"
|
|
616
|
+
done
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
**Last Updated**: 2025-10-27
|
|
622
|
+
**Version**: 1.1.0
|
|
@@ -56,13 +56,13 @@
|
|
|
56
56
|
"current_stage": "initialized"
|
|
57
57
|
},
|
|
58
58
|
"project": {
|
|
59
|
-
"
|
|
59
|
+
"name": "{{PROJECT_NAME}}",
|
|
60
60
|
"description": "{{PROJECT_DESCRIPTION}}",
|
|
61
|
-
"initialized": true,
|
|
62
|
-
"locale": "en",
|
|
63
61
|
"mode": "{{PROJECT_MODE}}",
|
|
64
|
-
"
|
|
65
|
-
"
|
|
62
|
+
"locale": "{{CONVERSATION_LANGUAGE}}",
|
|
63
|
+
"language": "{{CODEBASE_LANGUAGE}}",
|
|
64
|
+
"created_at": "{{CREATION_TIMESTAMP}}",
|
|
65
|
+
"initialized": true,
|
|
66
66
|
"optimized": false
|
|
67
67
|
},
|
|
68
68
|
"tags": {
|