---
name: minos
description: QA 시나리오 기반 Playwright 테스트 자동 생성 + fix-until-pass 루프 (미노스). qa-writer → 코드 생성 → 실행 → 수정 반복. /minos로 실행.
triggers:
  - "minos"
  - "미노스"
  - "qpassenger"
  - "큐패신저"
  - "qa-until-pass"
  - "QA 통과할 때까지"
  - "테스트 통과까지"
  - "playwright test until pass"
auto_apply: false
---

# Minos (미노스)

> **미노스(Minos)**: 그리스 신화의 저승 심판자. 죽은 자의 영혼을 심판해 합격/불합격을 가립니다.
> 코드를 심판대에 세워 모든 테스트가 통과할 때까지 fix 루프를 반복하는 이 스킬의 본성과 일치합니다.

QA 시나리오를 Playwright 테스트 코드로 변환하고, 모든 테스트가 통과할 때까지 자동으로 수정을 반복합니다.

## Quick Start

```
/minos                           # 자동 감지 (qa-scenarios.md 또는 docs/qa/)
/minos @qa-scenarios.md          # 특정 QA 문서 지정
/minos --api-only                # API 테스트만
/minos --ui-only                 # UI 테스트만
```

**공식 호출명:** `/minos` (별칭: `미노스`, 레거시: `/qpassenger`, `큐패신저`)

## 워크플로우 (7단계)

```
Step 1: 시나리오 수집
  ↓
Step 2: Playwright 코드 생성
  ↓
Step 3: 서버 준비 (자동 감지 + 실행)
  ↓
Step 4: 테스트 실행
  ↓
Step 5: 브라우저 탐색 QA (탐색 스크립트 생성·실행 → 이슈 회수)
  ↓
Step 6: Healer Loop (실패 → 수정 → 재실행, max 5회)
  ↓
Step 7: 결과 보고 + 서버 정리
```

---

## Step 1: 시나리오 수집

QA 시나리오를 수집합니다. 우선순위 순으로 탐색:

1. `$ARGUMENTS`로 전달된 QA 문서 경로
2. `qa-scenarios.md` (zephermine 산출물)
3. `docs/qa/*.md` (qa-writer 산출물)
4. 위 모두 없으면 → qa-writer 패턴으로 현장 생성

### 시나리오 파싱 규칙

QA 문서에서 테스트 케이스 테이블을 추출합니다:

```markdown
<!-- 이 형식을 인식 -->
| TC-ID | 시나리오 | 입력 | 기대 결과 | 우선순위 |
|-------|---------|------|----------|---------|
| TC-001 | 로그인 성공 | valid@email.com / Pass123! | 대시보드 이동 | P0 |
| TC-002 | 로그인 실패 | invalid@email.com / wrong | 에러 메시지 | P0 |
```

### 보충 시나리오 소스

`qa-scenarios.md`의 테스트 케이스가 부족하면 추가 소스를 참조합니다:

1. `operation-scenarios.md` (운영 시나리오) — qa-scenarios의 근거 문서. 메뉴별/업무별 흐름에서 누락된 테스트 케이스를 보충
2. `api-spec.md` — API 엔드포인트 중 qa-scenarios에 없는 것을 추가

### 시나리오 없을 때 현장 생성

qa-scenarios.md가 전혀 없으면 미노스가 직접 시나리오를 생성합니다:

**1단계: 프로젝트 분석 (자동)**

```bash
# 라우트/API 엔드포인트 탐색
grep -rn "router\.\|@Get\|@Post\|@app\.\|app\.get\|app\.post" --include="*.{ts,tsx,js,py,java}" src/ app/ 2>/dev/null | head -30

# 페이지/컴포넌트 탐색
find src -name "*.tsx" -path "*/pages/*" -o -name "*.tsx" -path "*/app/*" 2>/dev/null
```

**2단계: 시나리오 생성 (CRUD + 엣지 케이스)**

| 입력 소스 | 생성 전략 |
|-----------|----------|
| `operation-scenarios.md` 있음 | 업무 흐름 기반 TC 작성 (우선) |
| `api-spec.md` 있음 | API 엔드포인트별 정상/에러 케이스 |
| 둘 다 없음 | 코드 분석으로 라우트/페이지 자동 감지 → TC 생성 |

**3단계: TC 테이블 작성**

각 기능에 대해 아래 형식으로 테스트 케이스를 작성합니다:

```markdown
| TC-ID | 시나리오 | 유형 | 입력 | 기대 결과 | 우선순위 | 전제조건 |
|-------|---------|------|------|----------|---------|---------|
| TC-001 | 정상 로그인 | 정상 | valid@test.com / Pass123! | 대시보드 이동 | P0 | 회원 가입 완료 |
| TC-002 | 잘못된 비밀번호 | 에러 | valid@test.com / wrong | "비밀번호 오류" 표시 | P0 | - |
| TC-003 | 빈 이메일 제출 | 엣지 | (빈값) / Pass123! | "이메일 필수" 검증 | P1 | - |
```

**TC 유형별 필수 포함:**

| 유형 | 최소 케이스 | 예시 |
|------|-----------|------|
| 정상 (Happy path) | 기능당 1~2개 | 로그인 성공, 주문 완료 |
| 에러 (Error) | 기능당 2~3개 | 잘못된 입력, 권한 없음, 404 |
| 엣지 (Edge) | 주요 기능당 1~2개 | 빈값, 특수문자, 최대길이, 동시 요청 |
| 회귀 (Regression) | 변경 영역당 1개 | 기존 기능이 깨지지 않았는지 |

**4단계: 저장**

생성된 시나리오를 `qa-scenarios.md`로 저장 → Step 2로 진행

### 도메인사전 컨텍스트 로드

Step 1 끝에 `docs/domain-dictionary.md` 존재 여부를 확인하고, 있으면 메모리에 로드하여 Step 2~6 전체에서 참조합니다.

**용도:**
- 시나리오 텍스트의 도메인 용어를 사전 한글 표기와 일치시킴 (예: 사전 `Cart=장바구니`인데 시나리오에 "쇼핑백"이면 정정)
- Step 2 코드 생성 시 `describe`/`it` 블록에 사전 영문 식별자 사용
- 사전 위반 발견 시 Step 6 Healer Loop의 수정 후보로 분류

사전이 없으면 이 컨텍스트 단계 건너뜀.

---

## Step 2: Playwright 코드 생성

시나리오 → Playwright TypeScript 테스트 코드로 변환합니다.

> 상세 변환 규칙: [references/playwright-codegen.md](references/playwright-codegen.md)

### 프로젝트 감지

```
# 테스트 프레임워크 자동 감지
playwright.config.ts 존재 → Playwright 설정 재사용
package.json "playwright" → 버전 확인
없으면 → npx playwright install 안내
```

파일 구조: `tests/e2e/{feature}.spec.ts` + `tests/api/{feature}-api.spec.ts` (기능 단위 분리)

### 코드 생성 원칙

- 각 기능별 `describe` 블록, TC-ID 주석 포함
- Role-based selector 우선, 하드코딩 URL 금지, `beforeEach`로 상태 초기화
- **도메인사전 준수** (사전 있을 때): `describe('Cart')`, `it('adds item to 장바구니')` 같이 영문 식별자(클래스/함수명) + 한글 표기(테스트 설명/UI 라벨 매칭) 모두 사전 따름. 사전 금지 표현(예: `basket`)은 코드/주석에 절대 사용 금지

---

## Step 3: 서버 준비 (자동 감지 + 실행)

테스트 전에 앱 서버를 자동으로 준비합니다. 사용자 개입 없이 진행합니다.

감지 순서: docker-compose.yml → Dev Server → Django → 사용자 안내

> 네이티브 `/run`과의 관계: /run은 단발 실행·확인용이고, 이 Step은 테스트 수명주기에 묶인 서버 준비
> (포트 정리·헬스체크·종료)라 자체 절차가 기본입니다. 자체 감지가 모두 실패하면 /run의 실행 패턴을 참고.

환경별 서버 실행, 포트 정리, 헬스체크 상세: See [server-setup.md](references/server-setup.md)

---

## Step 4: 테스트 실행

### Worker 수 제한 (CPU 보호)

**기본값: CPU 논리코어의 50%** (`--workers=50%`)
사용자가 `--workers` 옵션으로 오버라이드 가능합니다.

```bash
# 기본 실행 (CPU 50% 제한)
npx playwright test --reporter=list --workers=50%

# 사용자가 --workers 지정 시 해당 값 사용
npx playwright test --reporter=list --workers=3      # 고정 3개
npx playwright test --reporter=list --workers=25%    # CPU 25%
npx playwright test --reporter=list --workers=1      # 직렬 (디버깅)

# headed 모드 (디버깅 필요 시)
npx playwright test --headed --workers=50%

# 특정 파일만
npx playwright test tests/e2e/auth.spec.ts --workers=50%
```

### 사전 조건 확인

테스트 실행 전 머신 상태(CPU 코어, workers 수, 예상 RAM)를 감지하여 사용자에게 보여줍니다.

CPU 감지 명령어 및 출력 형식: See [server-setup.md](references/server-setup.md)

추가 사전 조건: 서버 실행(Step 3 완료), DB 시드, `.env.test`, Playwright 브라우저 설치

---

## Step 5: 브라우저 탐색 QA (코드화 방식)

자동화 테스트(Step 4) 이후, **탐색용 Playwright 스크립트를 생성·실행**하여 실제 브라우저에서
탐색적 QA를 수행합니다. 자동화 테스트가 잡지 못하는 콘솔 에러, 네트워크 실패, 레이아웃 깨짐을 발견합니다.

> 상세 프로토콜: [references/browser-explorer.md](references/browser-explorer.md)

### 설계 원칙 (gstack browser 차용)

Step 2에서 이미 Playwright 코드를 생성하므로, 탐색 QA도 동일하게 **코드화**하여 일관성과 효율을 확보합니다.

| 원칙 | 의미 | 효과 |
|------|------|------|
| 코드화 | 페이지 순회·수집을 단일 Playwright 스크립트로 생성·실행 | Healer 반복 시 재탐색 비용 0 (스크립트 재실행) |
| 토큰 효율 | 수집 결과를 `report.json`으로 덤프, 컨텍스트엔 이슈만 적재 | 페이지 수에 무관하게 컨텍스트 안정 |
| MCP 비의존 | Playwright 이벤트 리스너로 console/network/error를 한 번에 수집 | Playwright MCP 설치 불필요 |

### 실행 조건

- **Playwright만 설치되어 있으면 기본 실행** (MCP 불필요)
- `--no-explore` 옵션으로 스킵 가능
- `--explore-only` 옵션으로 Step 2~4를 건너뛰고 이 단계만 실행 가능
- `--explore-mcp` 옵션으로 기존 Playwright MCP 방식 fallback (페이지마다 도구 직접 호출)

### 체크 항목

| 체크 | 수집 방법 (Playwright 이벤트) | 감지 대상 |
|------|------------------------------|----------|
| JS 에러 | `page.on('pageerror')` | `Uncaught TypeError`, unhandled rejection |
| 콘솔 에러 | `page.on('console')` (type=error) | React warnings, deprecated API |
| 네트워크 실패 | `page.on('response')` (status>=400) | 4xx/5xx, CORS, 404 리소스 |
| 구조 검증 | `page.accessibility.snapshot()` | 빈 페이지, 접근성 누락 |
| 시각적 확인 | `page.screenshot({fullPage})` | 레이아웃 깨짐, overflow, 빈 화면 |
| 인터랙션 | 생성된 `interact.spec.ts` (Phase 4) | 버튼 미반응, 폼 제출 실패 |

### 실행 흐름

```
1. 라우트 수집 (소스/qa-scenarios에서)
2. 탐색 스크립트 생성 → tests/explore/explore.spec.ts
   (ROUTES 순회 + console/pageerror/response 리스너 + screenshot + snapshot 덤프)
3. npx playwright test tests/explore/explore.spec.ts 실행
4. test-results/explorer/report.json 생성
5. jq/grep으로 이슈 항목만 추출 (전체를 컨텍스트에 올리지 않음)
6. (선택) snapshot.json 읽고 interact.spec.ts 생성·실행 (액티브 인터랙션)
```

### 발견 이슈 처리

- **P0/P1 코드 수정 가능** (JS 에러, API 실패) → Healer Loop(Step 6)에 전달
- **수동 확인 필요** (레이아웃, UX) → 결과 보고서(Step 7)에만 기록

---

## Step 6: Healer Loop

테스트 실패(Step 4) + 브라우저 탐색 QA 발견 이슈(Step 5)를 자동으로 분석하고 수정을 반복합니다.

> 상세 프로토콜: [references/healer-loop.md](references/healer-loop.md)

### 루프 구조

```
max_retries = 5
retry = 0

WHILE (실패한 테스트 존재) AND (retry < max_retries):
  1. 실패 로그 분석 (에러 메시지, 스택 트레이스)
  2. 원인 분류 → 수정 대상 결정
  3. 수정 적용 (Edit 도구)
  4. 재실행 (실패한 테스트만)
  5. retry++

IF retry >= max_retries:
  남은 실패 → test.fixme() 표시 + 사용자 보고
```

### 원인 분류 체계

| 원인 | 수정 대상 | 예시 |
|------|----------|------|
| 셀렉터 변경 | 테스트 코드 | `button[name]` → `getByRole('button')` |
| API 응답 불일치 | 구현 코드 | 404 → 엔드포인트 경로 오류 |
| 타이밍 이슈 | 테스트 코드 | `waitForResponse`, `waitForSelector` 추가 |
| 비즈니스 로직 버그 | 구현 코드 | 유효성 검증 누락 |
| 테스트 데이터 문제 | 테스트 코드 | fixture/seed 데이터 수정 |
| 콘솔 JS 에러 | 구현 코드 | `TypeError`, `Unhandled Rejection` (Step 5 발견) |
| 404 리소스 | 구현 코드 | 이미지/폰트/API 경로 오류 (Step 5 발견) |
| 인프라 문제 | 사용자 안내 | DB 연결, 포트 충돌 |

### 수정 원칙

- **테스트 코드 수정 우선**: 구현이 정확하면 테스트를 맞춤
- **구현 코드 수정은 신중하게**: 명백한 버그만 수정
- **수정 범위 최소화**: 실패한 부분만 정확히 수정
- **인프라 문제는 수정하지 않음**: 사용자에게 보고

---

## Step 7: 결과 보고 + 서버 정리

### 결과 보고서 생성

요약·수정 이력·미통과 항목·브라우저 탐색 발견 이슈 4섹션으로 구성합니다.
보고서 마크다운 템플릿 및 QA 문서 업데이트 형식: See [result-report.md](references/result-report.md)

### 판정 기준 (qa-engineer 기준 적용)

| Grade | 조건 | 판정 |
|-------|------|------|
| **PASS** | 자동 테스트 + 탐색 QA 전체 통과 | 배포 가능 |
| **CONDITIONAL** | P0/P1 통과, P2/P3 일부 fixme 또는 탐색 QA 경고만 | 조건부 진행 |
| **FAIL** | P0 또는 P1 실패 존재 (자동 테스트 또는 탐색 QA) | 수정 필수 |

### QA 문서 업데이트

원본 시나리오 문서에 `✅ / ⚠️ fixme` 결과를 반영합니다.

---

## 옵션

| 옵션 | 설명 | 기본값 |
|------|------|--------|
| `--workers N` | Playwright worker 수 (숫자 또는 퍼센트) | 50% |
| `--api-only` | API 테스트만 생성/실행 | false |
| `--ui-only` | UI E2E 테스트만 생성/실행 | false |
| `--max-retries N` | Healer 최대 반복 횟수 | 5 |
| `--headed` | 브라우저 화면 표시 | false |
| `--skip-generate` | 기존 테스트 코드 사용 (Step 2 건너뜀) | false |
| `--no-explore` | 브라우저 탐색 QA 스킵 (Step 5 건너뜀) | false |
| `--explore-only` | 브라우저 탐색 QA만 실행 (Step 2~4 건너뜀) | false |
| `--explore-mcp` | 탐색 QA를 Playwright MCP 방식으로 실행 (코드화 대신 fallback) | false |
| `--no-explore-active` | 액티브 인터랙션 탐색(Phase 4) 스킵, 패시브 수집만 | false |
| `--fix-code` | 구현 코드 수정도 허용 | true |
| `--fix-test-only` | 테스트 코드만 수정 (구현 코드 수정 금지) | false |

---

## 연관 에이전트/스킬

| 리소스 | 역할 | 연결 |
|--------|------|------|
| qa-writer (에이전트) | 테스트 시나리오 작성 | Step 1 입력 |
| qa-engineer (에이전트) | 품질 판정 기준 | Step 7 판정 |
| zephermine (스킬) | qa-scenarios.md + operation-scenarios.md 생성 | Step 1 입력 |

---

### 서버 정리

테스트 완료 후 Step 3에서 실행한 서버를 정리합니다.

서버 정리 명령어 상세: See [server-setup.md](references/server-setup.md)

---

## 주의사항

- Playwright 미설치 시 `npx playwright install` 필요
- 브라우저 탐색 QA(Step 5)는 탐색 스크립트를 생성·실행하므로 Playwright만 있으면 동작 (MCP 불필요). `--explore-mcp`로 MCP 방식 fallback 가능
- 탐색 결과(`report.json`)는 전체를 컨텍스트에 올리지 말고 jq/grep으로 이슈 항목만 추출 (토큰 절약)
- Healer가 구현 코드를 수정하므로, 커밋되지 않은 변경사항이 있으면 주의
- 외부 의존성(메일, 결제 등) 테스트는 mock 대체 권장

---

## 다음 단계 안내

QA가 완료되면 사용자에게 다음 단계를 안내합니다:

```
✅ Minos 완료! (결과: {PASS/CONDITIONAL/FAIL})

👉 다음 단계 (선택):
  /docker-deploy       → Docker 배포 환경 생성
  /review              → 코드 리뷰 (아직 안 했다면)
  /write-api-docs      → API 문서 생성
  /commit              → 변경사항 커밋
  /wrap-up             → 세션 요약 + MEMORY.md 업데이트

📎 참고: docs/workflow-guide.md
```
