---
name: write-story
description: >
  Use this skill when the user says "write story", "create story", "new story",
  "스토리 작성", "스토리 만들어", "스토리 써줘", or wants to create user stories.
  Collaboratively writes XP-style user stories with acceptance criteria
  and registers them to TrackerBoot via MCP.
---

# Write Story

## Invocation

```
/write-story <project-id>
```

- **`project-id`** — TrackerBoot 프로젝트 ID **(필수)**

`project-id` 없이 호출되면 Step 0에서 즉시 중단한다.

---

## Step 0: 사전 조건 확인

스킬 실행 전 반드시 다음을 확인한다.

### 프로젝트 ID 확인 (필수)

호출 시 `project-id`가 제공되었는지 확인한다.

**제공되지 않았으면 즉시 중단:**

```
❌ TrackerBoot 프로젝트 ID가 필요합니다.

프로젝트 ID 없이 실행하면 권한이 있는 임의의 프로젝트에 스토리가 등록될 수 있습니다.

사용법: /write-story <project-id>
예시:   /write-story 12345678
```

STOP.

**제공되었으면:** `project-id`를 세션 전체에서 사용할 값으로 저장한다.

## Step 1: 시나리오 수집

사전 조건이 모두 통과되면, 사용자에게 시나리오를 요청한다.

```
구상하고 계신 사용자 시나리오를 설명해주세요.

누가 어떤 상황에서 무엇을 하려는지 자유롭게 서술해주시면 됩니다.
가능하면 이 기능을 사용하는 페르소나도 함께 알려주세요.
하나의 시나리오를 작은 스토리들로 나눠드리겠습니다.

예시:
  "쇼핑몰에서 사용자가 상품을 장바구니에 담고, 결제 수단을 선택한 뒤,
   주문을 완료하고 확인 이메일을 받는 전체 흐름"
```

PAUSE.

시나리오를 받은 뒤 `As`에 사용할 페르소나 표현이 없거나 모호하면 바로 다음 질문으로 확인한다.

```
이 시나리오의 주요 페르소나는 누구인가요?

예시:
  - 처음 구매하는 신규 고객
  - 여러 팀을 관리하는 프로젝트 매니저
  - 영업 담당자 Alex
```

PAUSE. 페르소나를 확인한 뒤 Step 2로 진행한다.

---

## Step 2: 스토리 분리

수집한 시나리오를 분석하여 **INVEST 원칙**에 따라 독립적인 스토리들로 나눈다.

### 분리 기준

분리 상세 규칙은 `references/story-splitting-guide.md` 참조.

스토리의 `As` 항목은 반드시 명시적인 페르소나 표현을 사용한다.
- 시나리오에 페르소나가 드러나면 그 표현을 사용한다.
- 시나리오에 페르소나가 없거나 모호하면 Step 1의 추가 질문으로 먼저 확인한다.
- 확인되지 않은 상태에서 임의의 페르소나를 만들어 진행하지 않는다.

각 스토리가 다음을 만족하는지 검토한다:
- **Independent**: 다른 스토리에 의존하지 않고 독립적으로 전달 가능한가?
- **Valuable**: 기술적 수평 분할이 아닌 사용자에게 실질적인 가치를 전달하는가?
- **Small**: 하나의 이터레이션 안에서 완료할 수 있을 만큼 작은가?
- **Testable**: 인수 기준을 작성할 수 있는가?

### UI 인터랙션 흐름 시나리오일 때

시나리오가 화면 구성, 버튼, 입력 폼 등 UI 조작 흐름을 포함하면 **UI 인터랙션 흐름별 분리 패턴**을 적용한다.

다음 유형별로 스토리를 나눈다:
1. **진입점 노출** — 기능을 시작할 수 있는 버튼/아이콘이 화면에 보인다
2. **화면 전환** — 버튼을 누르면 새 화면/윈도우가 열린다
3. **폼 구성 확인** — 열린 화면에서 필요한 입력 필드와 버튼이 보인다
4. **데이터 저장** — 입력 후 저장하면 결과가 특정 화면에 반영된다
5. **취소/복귀** — 취소하거나 이전 버튼으로 되돌아간다
6. **기존 데이터 노출** — 수정 진입 시 기존 값이 채워져 있다
7. **삭제 확인** — 삭제 전 확인 메시지가 표시된다

> "버튼 하나 추가"가 너무 작아 보여도, UI 인터랙션 흐름 단위에서는 유효한 스토리다.

### 분리 결과 표시 형식

```
## 📋 스토리 분리 결과

시나리오를 [N]개의 스토리로 나눴습니다.

---

**[1] [스토리 제목]**

### Why

**As** [페르소나]
**I want** [기능]
**So that** [가치]

> 분리 이유: [왜 이 단위로 나눴는지]

**[2] [스토리 제목]**

### Why

**As** [페르소나]
**I want** [기능]
**So that** [가치]

> 분리 이유: [왜 이 단위로 나눴는지]

...

---
이 분리가 적절한가요?
→ "ok" — 인수 기준 작성으로 진행
→ "split [번호]" — 더 잘게 나누기
→ "merge [번호] [번호]" — 합치기
→ "edit [번호]" — 수정
```

PAUSE. 변경 사항 반영 후 재표시. "ok" 를 받으면 진행.

---

## Step 3: 인수 기준 작성

확정된 모든 스토리에 대해 AC를 한 번에 작성한 뒤, 전체를 함께 검토한다.

### AC 작성 순서

각 스토리마다 다음 순서로 작성한다:

1. **해피 패스** — 정상적인 주요 흐름 먼저
2. **엣지 케이스** — 경계값, 예외 흐름
3. **오류 케이스** — 잘못된 입력, 시스템 오류

### UI 스토리 AC 작성 시 규칙

- **GIVEN**: 항상 화면 이름을 명시한다 (예: "메인 화면이 열려 있을 때")
- **THEN**: 화면의 어느 위치에서 무엇이 보이는지 명시한다 (예: "오른쪽 상단에 + 버튼이 보인다")
- 상세 규칙은 `ac-writing-guide.md`의 "UI 스토리 AC 작성 패턴" 참조

### 영속성 AC

데이터를 **생성·수정·삭제**하는 스토리에는 반드시 영속성 AC를 마지막에 추가한다.
별도 "영속성 스토리"를 만들지 않는다.
패턴은 `ac-writing-guide.md`의 "영속성 AC 패턴" 참조

### 전체 AC 표시 형식

모든 스토리의 AC를 하나의 블록으로 표시한다.

```markdown
## 📋 인수 기준 초안 (전체 [N]개 스토리)

---

### [1] [스토리 제목]

```gherkin
Scenario: [시나리오 이름]
    Given [사전 조건]
    When  [사용자 행동]
    Then  [기대되는 결과]

Scenario: [시나리오 이름]
    Given [사전 조건]
    When  [사용자 행동]
    Then  [기대되는 결과]
```

---

### [2] [스토리 제목]

```gherkin
Scenario: [시나리오 이름]
    Given [사전 조건]
    When  [사용자 행동]
    Then  [기대되는 결과]
```

...
```

표시 후:

```
인수 기준을 검토해주세요.
→ "add [스토리번호] [내용]" — AC 추가
→ "remove [스토리번호 AC번호]" — AC 제거
→ "edit [스토리번호 AC번호]" — AC 수정
→ "done" — 완료, 레이블 선택으로 진행
```

PAUSE. 변경 사항 반영 후 재표시. "done" 을 받으면 Step 4로 진행한다.

AC 작성 상세 규칙은 `references/ac-writing-guide.md` 참조.

---

## Step 4: 레이블 선택

### 4-1. 레이블 추천

전체 스토리 내용을 분석하여 공통 레이블과 개별 레이블을 추천한다.
스토리 번호는 `S1`, `S2` 형식으로 표기하고, 연속된 범위는 `S1~S4` 형식으로 묶어 표시한다.

```
스토리 내용을 분석한 추천 레이블입니다.

공통 레이블 추천:
  - [레이블명]   ([적용 이유 — 기능 도메인 설명])
  - [레이블명]

개별 레이블 추천:
  - S[번호]~S[번호] : [레이블명]
  - S[번호]~S[번호] : [레이블명]
  - S[번호] : [레이블명]

적용할 레이블을 선택해주세요.
→ "ok" / "done" — 추천 그대로 확정
→ 추가/제거하고 싶으면 알려주세요
```

PAUSE. 변경 사항 반영 후 재표시. "ok" / "done" 을 받으면 레이블을 확정하고 4-2로 진행한다.

### 4-2. 관련 스토리 조회 및 문맥 반영

레이블이 확정되면, TrackerBoot MCP로 동일 프로젝트 내 동일 레이블의 기존 스토리를 조회한다.

```
tracker-boot-mcp-tb_search_stories (projectId + labels filter)
```

조회 시 반드시 Step 0에서 저장한 `project-id`를 함께 전달한다.

**관련 스토리가 없으면:** 조용히 진행한다.

**관련 스토리가 있으면:** 다음 순서로 분석한다.

#### 1) 기존 스토리 목록 표시

```
📋 기존 관련 스토리 (레이블: "[레이블]", 총 [N]개)
- [스토리 ID] [스토리 제목]
- [스토리 ID] [스토리 제목]
...

기존 스토리를 바탕으로 문맥을 분석합니다...
```

#### 2) 문맥 분석

기존 스토리들에서 다음 항목을 추출한다:

- **페르소나 표현** — "As" 뒤에 쓰인 페르소나 명칭 (기존과 일치시킴)
- **동사/행동 표현** — "I want to" 뒤에 쓰인 동사 패턴 (기존 용어 우선)
- **화면·UI 용어** — 기존 스토리에서 사용한 화면 이름, 버튼 명칭
- **AC 형식** — GIVEN/WHEN/THEN 작성 스타일 및 상세 수준
- **중복 스코프** — 새 스토리와 동일하거나 겹치는 기능

#### 3) 변경이 필요한 경우 개발자에게 알림

분석 결과 새 스토리 조정이 필요하면 변경 사항을 표시하고 확인을 받는다:

```
🔍 기존 스토리 문맥 분석 결과

[변경 필요 항목이 있는 경우]

**조정 사항:**
- [스토리 N] "[기존 표현]" → "[기존 스토리 문맥에 맞춘 표현]"
  이유: [기존 스토리에서 사용한 용어/패턴과 일치시키기 위해]
- ...

[중복 스코프가 있는 경우]

**중복 검토:**
- [스토리 N]이 기존 스토리 [[스토리 ID] [제목]]과 스코프가 겹칩니다.
  → 제거 또는 스코프 조정이 필요합니다.

조정을 적용할까요?
→ "ok" — 전체 적용
→ "skip" — 조정 없이 진행
→ 특정 항목만 적용하려면 알려주세요
```

PAUSE. "ok" 를 받으면 스토리와 AC에 조정 사항을 반영하고 Step 5로 진행한다.

**변경이 필요하지 않은 경우:** 조용히 Step 5로 진행한다.

---

## Step 5: 최종 확인

완성된 전체 스토리 목록을 표시하고 최종 승인을 받는다.

```markdown
## ✅ 최종 스토리 Preview ([N]개)

---

### [1] [스토리 제목]

### Why

**As** [페르소나]
**I want** [기능]
**So that** [가치]

### Acceptance Criteria

```gherkin
Scenario: [시나리오 이름]
    Given [조건]
    When  [행동]
    Then  [결과]
```

**레이블:** [레이블1], [레이블2]

---

### [2] [스토리 제목]
...

---

TrackerBoot에 [N]개 스토리를 등록할까요?
→ "register" — 전체 등록
→ "register [번호]" — 해당 스토리만 등록
→ "edit [번호] [섹션]" — 수정 (title / description / ac / labels)
→ "cancel" — 취소
```

PAUSE.

---

## Step 6: TrackerBoot 등록

개발자가 확인하면 TrackerBoot MCP로 스토리를 **역순(마지막 스토리부터)**으로 등록한다.

> TrackerBoot는 새로 등록된 스토리를 목록 상단에 추가하므로, 원하는 순서대로 화면에 표시되려면 **마지막 스토리(S[N])부터 첫 번째 스토리(S1) 순서**로 등록해야 한다.

### MCP 도구

```
tracker-boot-mcp-tb_create_story   — 스토리 생성 (Why + AC + Notes 모두 description에 포함)
```

### 등록 절차

스토리마다 **1단계(스토리 생성)**만 실행한다. **S[N] → S[N-1] → ... → S[1] 순서로 진행한다.**

**1단계 — 스토리 생성:**

AC는 task가 아닌 `description`의 `### Acceptance Criteria` 섹션에 gherkin 형식으로 포함한다.
라벨은 MCP가 지원하지 않으므로 `description`의 `**Notes:**` 섹션에 ul 형식으로 포함한다.
추후 MCP 서버가 라벨 생성을 지원하면 `labels` 파라미터를 함께 전달한다.

```json
{
  "projectId": "[Step 0에서 저장한 project-id]",
  "title": "[스토리 제목]",
  "storyType": "Feature",
  "description": "### Why\n\n**As** [페르소나]\n**I want** [기능]\n**So that** [가치]\n\n### Acceptance Criteria\n\n```gherkin\nScenario: [시나리오 이름]\n    Given [사전 조건]\n    When  [사용자 행동]\n    Then  [기대되는 결과]\n\nScenario: [시나리오 이름]\n    Given [사전 조건]\n    When  [사용자 행동]\n    Then  [기대되는 결과]\n```\n\n**Notes:**\n\n- [레이블1]\n- [레이블2]"
}
```

### 등록 진행 표시

역순으로 진행하되, 진행 카운터는 원래 순서(S1=1번)로 표시한다:

```
⏳ [N/N] 등록 중... [마지막 스토리 제목]
✅ [N/N] [마지막 스토리 제목] — 완료 (ID: [스토리 ID])
⏳ [N-1/N] 등록 중... [N-1번째 스토리 제목]
✅ [N-1/N] [N-1번째 스토리 제목] — 완료 (ID: [스토리 ID])
...
⏳ [1/N] 등록 중... [첫 번째 스토리 제목]
✅ [1/N] [첫 번째 스토리 제목] — 완료 (ID: [스토리 ID])
```

### 전체 등록 완료

```
✅ 전체 [N]개 스토리 등록 완료

등록된 스토리:
  - #[스토리 ID] [스토리 제목]
  - #[스토리 ID] [스토리 제목]
  ...

→ 각 스토리에 대해 후속 구현 계획이나 개발 워크플로우를 이어갈 수 있습니다.
```

### 등록 실패

특정 스토리 등록에 실패하면:

```
❌ [N번 스토리] 등록 실패: [오류 메시지]

→ "retry" — 다시 시도
→ "skip" — 이 스토리 건너뛰고 다음으로
→ "copy" — 해당 스토리 내용을 Markdown 형식으로 출력
→ "cancel" — 전체 등록 중단
```

---

## 참조 파일

| 파일 | 사용 시점 |
|------|---------|
| `references/story-splitting-guide.md` | Step 2 스토리 분리 시 |
| `references/story-format-guide.md` | Step 2 스토리 초안 형식 |
| `references/ac-writing-guide.md` | Step 3 AC 작성 시 |
