---
name: jira-task-discover
description: Discover requirements from a free-form natural-language topic. Searches the codebase, asks batched clarifying questions, then writes a structured requirements document with an issue-breakdown proposal. Use when user says "discover", "jira-task discover", "요구사항 분석", "디스커버리", "요구사항 문서", "주제 분석", or wants to turn a vague topic into a concrete requirements doc before creating Jira issues.
user-invocable: false
argument-hint: "<자연어 주제> [--lite] [--from <파일경로>]"
allowed-tools:
  - Read
  - Write
  - Bash
  - Glob
  - Grep
  - AskUserQuestion
---

# jira-task-discover: Requirements Discovery from a Topic

**Language Rule**: 프로젝트 CLAUDE.md의 Conventions 섹션 참고 (한국어 출력, Jira 코멘트 제목은 영어).

## Overview

`jira-task-discover`는 모호한 자연어 주제를 입력받아, 코드베이스 탐색과 사용자 질문을 거쳐 명시적인 요구사항 분석 문서를 만든다. 이 스킬의 산출물은 다음 단계인 `jira-task-create`(MAE-116에서 `--from-requirements` 추가)의 입력이 된다.

**입력 (3종):**
- 위치 인자: 자연어 주제 (필수). 예: `"사용자 알림 시스템"`
- `--lite`: 질문을 3건으로 줄이고, 출력 문서를 한 페이지 분량으로 축약
- `--from <파일경로>`: 기존 요구사항 문서를 import해서 베이스로 사용

**출력 (1종):**
- `docs/requirements/<TOPIC-SLUG>.requirements.md` — 요구사항 분석 문서 (말미에 이슈 분해 제안 섹션 포함)

**비목표 (Non-goals):**
- Jira 이슈/코멘트/첨부 생성 안 함 (로컬 문서 단계로 한정)
- `.jira-context.json` 읽기/쓰기 안 함 (`completedSteps` 갱신은 MAE-118의 책임)
- 인덱스 파일(`docs/requirements/INDEX.md` 등) 자동 관리 안 함
- `templates/requirements.template.md` 생성 안 함 (MAE-117의 책임). 부재 시 에러로 종료

## Input Model

```
$ARGUMENTS = <자연어 주제> [--lite] [--from <파일경로>]
```

**파싱 규칙:**
- 첫 번째 위치 인자(따옴표로 묶인 문자열 또는 플래그가 아닌 토큰의 연결)를 **자연어 주제**로 간주
- `--lite`: 인자 어디에 와도 됨. 값 없음 (boolean 플래그)
- `--from <파일경로>`: `--from` 다음 토큰을 파일경로로 사용. 절대/상대 경로 모두 허용
- 자연어 주제가 비어 있으면 Step 0에서 사용자에게 입력 요청
- `--lite`와 `--from`은 동시 사용 가능 (효과 합쳐짐: 질문 축소 + 기존 문서 import)

## Workflow

### Step 0: Parse Arguments

1. `$ARGUMENTS`를 토큰화한다.
2. `--lite` 토큰 존재 여부를 boolean `lite`에 저장.
3. `--from <path>` 패턴을 추출해 `fromPath`에 저장. `--from` 다음 토큰이 비었거나 다른 플래그면 에러.
4. 남은 토큰을 공백으로 합쳐 `topic`(자연어 주제)으로 사용.
5. `topic`이 비어 있으면:
   - `AskUserQuestion`으로 단답형 질문 1회: "어떤 주제로 요구사항을 만들까요? (한 문장으로 입력)"
   - 답변도 비어 있으면 종료 (에러 메시지 출력)
6. `fromPath`가 지정되었으면 파일 존재 검증:
   - 파일 부재: 에러 메시지 + 종료 (1회 안내, 자동 재시도 없음)
   - 파일이 1MB 초과: `AskUserQuestion`으로 진행 여부 confirm
   - 빈 파일: 경고 출력 후 default 모드로 fallback (자연어 주제만 사용)

### Step 1: Slug Generation & Confirm

1. `topic`을 영문 kebab-case 슬러그 1개로 변환한다.
   - 한글/비ASCII 주제: 의미를 영문으로 요약·번역 후 kebab-case화
   - 허용 문자: `[a-z0-9-]`만. 공백·특수문자·대문자는 제거 또는 변환
   - 길이 제한: 60자 이내로 절단
2. `docs/requirements/<slug>.requirements.md` 존재 여부 확인:
   - 존재하면 `<slug>-2`, `<slug>-3` ... 식으로 suffix 부여 (또는 사용자에게 overwrite 여부 confirm)
3. `AskUserQuestion`으로 슬러그 confirm 1회:
   - 옵션 A: "사용" (제안된 슬러그 그대로 진행)
   - 옵션 B: "수정" → 사용자가 직접 슬러그 입력 (단답형). 입력값도 `[a-z0-9-]`만 허용. 비어 있으면 옵션 A의 default를 강제 사용
4. 확정된 슬러그를 이후 Step에서 사용한다.

### Step 2: Codebase Context Collection

1. `topic`에서 키워드 3-5개를 추출한다.
   - 명사·기능 단어 우선. 한글 주제면 영문 대응어 포함
   - 예: "사용자 알림 시스템" → `["notification", "alert", "user", "push", "email"]`
2. 키워드별로 `Glob`/`Grep`을 사용해 관련 파일을 찾는다.
   - `Glob`: 파일명 매칭 (예: `**/*notification*`)
   - `Grep`: 본문 매칭 (대소문자 무시)
3. 결과를 합쳐 **상위 10개 파일**로 추리고, **파일당 최대 30줄**까지만 발췌한다.
4. **결과 메타 보존 형식**: 각 발췌는 `(file_path, line_range)` 튜플 형태로 보존한다. 이 메타는 Step 4 marker의 `code:` 부분에 그대로 인용된다.
   - line_range 표기: `<path>:<start>-<end>` (예: `src/notify.ts:45-60`). 단일 라인이면 `<path>:<line>` (예: `src/notify.ts:45`)
   - `Glob` 결과는 파일 단위이므로 line_range는 후속 `Grep` 매칭 줄 또는 발췌 범위를 사용
   - **민감 파일 제외**: `.env*`, `.claude/settings.local.json`, `node_modules/`, 자격증명·토큰을 포함한 파일은 발췌·메타에서 제외한다 (산출 문서가 Jira 첨부로 전송될 수 있음)
5. 결과가 0건이면 폴백: 레포 루트의 디렉터리 트리(depth 2)를 컨텍스트로 사용하고, 문서에 "관련 영역 자동 탐색 실패"로 기록.
6. `--from <path>`가 지정되었으면 해당 파일 내용을 함께 컨텍스트에 포함 (Step 4의 베이스 본문이 됨).

### Step 3: Batched Questions

`AskUserQuestion`을 **1회만** 호출해 다음 질문들을 한 묶음으로 배치한다.

**Default 모드 (4건):**

| # | 인덱스 | 카테고리 | 질문 |
|---|--------|---------|------|
| 1 | `Q1` | 이해관계자 | 이 기능의 주 사용자 또는 호출자는 누구입니까? |
| 2 | `Q2` | 성공 기준 | "끝났다"고 판단할 측정 가능한 기준은 무엇입니까? |
| 3 | `Q3` | 제약 | 반드시 지켜야 하는 기술/시간/비용 제약이 있습니까? |
| 4 | `Q4` | 비기능 요구사항 | 성능·보안·접근성·관측성 등에서 특별히 고려할 항목이 있습니까? |

**Q<N> 인덱스 부여 규칙:**
- 각 답변에는 위 표의 인덱스(`Q1`~`Q4`)를 그대로 부여한다. 이 인덱스는 Step 4 marker의 `source: Q<N>` 부분에 그대로 인용된다.
- `--lite` 모드: 4번(비기능 요구사항)이 생략되므로 인덱스는 `Q1`~`Q3`만 사용한다.
- `--from` 모드: 누락된 카테고리만 선별 질문하더라도 **원래 인덱스를 유지**한다 (예: NFR만 추가로 물으면 그 답변은 `Q4`. 1~3번이 import 본문에 이미 있으면 해당 답변은 `*(source: from)*` 또는 `*(source: from, Q<N>)*`).

**`--lite` 모드 (3건):** 위 표에서 4번(비기능 요구사항)을 제외하고 1~3번만 묻는다 (인덱스 `Q1`~`Q3`).

**`--from` 모드:** Step 2에서 import한 기존 문서를 분석해 누락된 카테고리만 선별 질문한다 (4건 중 일부만, 또는 전부 생략 가능). 인덱스 보존 규칙은 위 참조.

각 질문은 객관식 옵션 2-4개와 "Other → 자유 입력"을 함께 제공한다. 사용자가 모든 항목에 "Other → (빈)"으로 답하면 해당 항목은 문서에 `TBD`로 기록한다 (이때도 `Q<N>` 인덱스는 유지되어 Step 4 marker에 인용 가능).

### Step 3.5: Conflict Detection (--from mode only)

**필수**: `--from` 모드에서만 진입. `skills/jira-task-discover/refs/conflict-detection.md`를 Read하여 본문을 그대로 수행한다.

진입 조건: `--from` 플래그가 있고 import 파일이 비어있지 않으면 진입. 그 외 모든 모드는 통과(no-op).
격상 형식: `[CONFLICT] <카테고리>: import="<원본>" vs answer="<답변>" — 어느 쪽이 정확한지 결정 필요`
Step 4와의 협력: 격상된 `[CONFLICT]` 항목은 Step 4의 Open Questions에 자동 포함 (TBD 항목 뒤에 나열).

### Step 4: Generate Requirements Document

`docs/requirements/<slug>.requirements.md`를 생성한다.

**템플릿 선택:**
`templates/requirements.template.md`을 Read하여 베이스로 사용한다. 파일이 없으면 즉시 에러로 종료하고 "플러그인 자산 손상 — git restore templates/requirements.template.md"을 안내한다.

**문서에 채워야 할 내용:**
- Topic, Slug, Mode (default/lite/from), Generated At
- Stakeholders (Step 3 답변 1번)
- Goals & Success Criteria (Step 3 답변 2번)
- Constraints (Step 3 답변 3번을 **Technical / Schedule / Cost / Regulatory 4 sub-section**으로 분류. 답변에 명시되지 않은 카테고리는 `N/A — 해당 없음` 한 줄로 명시 — 누락 금지.)
- Non-functional Requirements (Step 3 답변 4번을 **6 카테고리 표**로 정리: 성능 / 가용성 / 보안 / 확장성 / 관측성 / 호환성. 각 항목은 값 또는 `N/A — <사유>`. `TBD`는 사용 금지 — 모르면 Open Questions로 격상. `--lite` 시 본 섹션 전체를 `N/A — lite mode` 한 줄로 대체.)
- Codebase Context (Step 2 결과: 파일 경로 + 발췌 요약)
- Functional Requirements (Step 3 답변과 codebase 컨텍스트로부터 LLM이 합성)
- **Goals ↔ FR 매핑** (Functional Requirements 합성 직후 도출. 표 형식 `| Goal | 만족하는 FR | 비고 |`. 모든 Goal에 최소 1개 FR 매핑이 원칙. 매핑되지 않는 Goal은 `[P1]`로 Open Questions에 격상. 매핑되지 않는 FR은 Out of Scope 후보 또는 Goal 누락 신호.)
- Edge Cases (`--lite` 시 생략)
- Out of Scope (`--lite` 시 생략)
- Open Questions (TBD로 표시된 항목 모음 + Step 3.5에서 격상된 `[CONFLICT]` 항목 + Goals↔FR 매핑 누락 항목 자동 포함. 순서: TBD 항목 먼저 → 매핑 누락 → conflict 항목)

`--from <path>`가 지정된 경우: `<path>` 본문을 베이스로 위 섹션을 보강·재구성한다 (덮어쓰기 X, 보강 O).

**`--lite` 모드 분량 규칙:** 각 섹션 최대 5줄. "Edge Cases"·"Out of Scope" 섹션은 생략. 한 페이지 분량 유지.

#### Trace Marker 자동 부여 규칙

**필수**: `skills/jira-task-discover/refs/trace-markers.md`를 Read하여 marker 형식·부여 대상·`synthesized` 가이드를 확인한다.

요약: 합성 4종(FR / Edge Cases / Out of Scope / Open Questions) 각 항목 끝에 출처 marker를 부여. 비대상(Stakeholders, Goals, Constraints, NFR, Codebase Context)에는 marker 불요.

**파일 쓰기 시점 — 중요:** Step 4의 합성 산출물은 **메모리상 객체로만 보관**한다. 실제 `docs/requirements/<slug>.requirements.md` 파일 쓰기는 **Step 4.5 confirm 통과 후**로 지연한다. 재합성 시 Step 2·Step 3 캐시는 재사용하고 Step 4 합성만 재실행한다.

### Step 4.5: Synthesis Confirm

**필수**: `skills/jira-task-discover/refs/synthesis-confirm.md`를 Read하여 본문을 그대로 수행한다.

Step 4 합성 산출물(FR / Edge Cases / Out of Scope / Open Questions)을 사용자에게 검증받는 단일 confirm gate이다.
분기: `proceed` → Step 5 진입 + 파일 쓰기. `revise` → 재합성(최대 3회). `cancel` → 메모리 폐기 후 정상 종료.

### Step 5: Issue Breakdown Section

**진입 조건:** Step 4.5 confirm을 통과(`proceed`)한 합성 결과를 입력으로 받아 본 단계를 실행한다. Step 4에서 생성한 문서의 **마지막 섹션**으로 다음 트리를 추가한다. **Jira 이슈를 만들지 않는다 — 문서에만 기록한다.**

```markdown
## Proposed Issue Breakdown

- **Epic**: <에픽 1줄 요약>
  - **Story 1**: <스토리 요약>
    - Sub-task 1.1: <서브태스크 요약>
    - Sub-task 1.2: <서브태스크 요약>
  - **Story 2**: <스토리 요약>
    - Sub-task 2.1: <서브태스크 요약>
```

규칙:
- 에픽 1개 + 스토리 N개 (보통 2-5) + 스토리당 서브태스크 1-5개
- 각 항목은 명사구 또는 동사구 한 줄 요약
- 우선순위·의존성 추정은 선택. 명시할 수 있으면 `(blocks: ...)` 등으로 표기
- 사용자가 다음 단계에서 `/jira-task create --from-requirements <경로>`로 이 트리를 그대로 Jira에 등록할 수 있도록 작성

### Step 6: Completion Summary

아래 형식으로 완료 요약을 출력한다 (다른 jira-task-* 스킬과 동일 패턴):

```
---
✅ **Discovery Complete** — <TOPIC>

- 요구사항 문서 생성: `docs/requirements/<slug>.requirements.md`
- 모드: default | lite | from | lite+from
- 코드베이스 컨텍스트: <발췌 파일 N개> (또는 "관련 영역 미발견")
- 이슈 분해 제안: 에픽 1 + 스토리 N + 서브태스크 M

**Progress**: **discover ✓** → create → init → start → plan → design → impl → test → review → merge → pr → done

**Next**: `/jira-task create --from-requirements docs/requirements/<slug>.requirements.md` — 이 분석서로 Jira 이슈를 등록합니다
---
```

`.jira-context.json`은 건드리지 않는다 (`completedSteps`에 `"discover"` 추가는 MAE-118의 책임).

## Error Handling

| 시나리오 | 처리 전략 |
|---------|----------|
| 자연어 주제 누락 | Step 0에서 `AskUserQuestion`으로 입력 요청. 답변도 비면 종료 |
| `--from` 파일 부재 | 경로와 함께 에러 메시지 출력 후 종료 (자동 재시도 없음) |
| `--from` 파일이 비어 있음 | 경고 출력 후 default 모드로 진행 (자연어 주제 기반) |
| `--from` 파일이 1MB 초과 | `AskUserQuestion`으로 진행 여부 confirm |
| 슬러그 confirm 거부 | 사용자가 직접 입력 1회 허용. 그것도 비면 default 슬러그 강제 사용 |
| 슬러그 중복 (같은 파일 존재) | `<slug>-2`, `<slug>-3` 자동 부여 또는 overwrite 여부 confirm |
| 키워드 추출 결과 0개 | repo root의 디렉터리 트리(depth 2)로 폴백, 컨텍스트 섹션에 "관련 영역 자동 탐색 실패" 명시 |
| Glob/Grep 결과 0건 | 컨텍스트 섹션에 "관련 영역 미발견" 기록 후 진행 (블로킹하지 않음) |
| 사용자가 모든 답변에 "Other → (빈)" 응답 | 해당 항목을 문서에 `TBD`로 기록하고 진행 |
| 탐색 결과가 컨텍스트 폭주 | 파일 10개·파일당 30줄 상한 강제. 초과 시 절단 |
| 템플릿 파일 부재 (`templates/requirements.template.md`) | 즉시 에러로 종료. "플러그인 자산 손상 — git restore templates/requirements.template.md" 안내 |
| `--lite`와 `--from` 동시 사용 | 두 효과 모두 적용 (질문 3건 또는 그 이하 + import 베이스) |
| 슬러그에 위험 문자 (`/`, `..`, 공백, 한글) | kebab-case 강제. 영문/숫자/하이픈만 허용. 변환 실패 시 사용자 직접 입력 요청 |
| Step 4.5에서 재합성 한도(`RESYNTHESIS_LIMIT=3`) 초과 | `revise` 옵션 제거 후 `proceed`/`cancel` 2분기로 강제 confirm. 사용자에게 "재합성 한도(3회)에 도달했습니다. 그대로 진행하거나 취소를 권장합니다." 안내 |
| Step 4.5 `cancel` 선택 | 메모리상 합성 산출물 폐기. 파일 시스템에는 아직 쓰지 않은 상태이므로 cleanup 불필요. 한국어 종료 메시지 1줄("요구사항 문서 생성을 취소했습니다.") 출력 후 정상 종료 |

## Non-goals

- Jira 이슈 생성/코멘트/첨부 — `discover`는 로컬 문서 단계로 한정. 이슈 등록은 `jira-task-create`(MAE-116)의 책임
- `.jira-context.json` 읽기/쓰기 — 본 스킬은 Jira 컨텍스트에 의존하지 않으며 갱신도 하지 않음
- `completedSteps`에 `"discover"` 추가 — MAE-118에서 처리
- `commands/jira-task.md`의 `discover` 액션 라우팅 — MAE-119에서 처리. 본 스킬은 직접 Skill 도구 호출로도 동작
- `templates/requirements.template.md` 파일 생성 — MAE-117의 책임
- 인덱스 파일 자동 관리 (`docs/requirements/INDEX.md` 등)
- 외부 API/네트워크 호출 (LLM 추론 외)
