---
name: VSQA
description: EXECUTE // Survivors(project-VSLike)의 QA 실행 스킬 — TQA(봇 시뮬레이션·수치 검증)와 FQA(사람이 재미를 판정하는 루프)를 운영한다. 슬래시 명령 `/vsfqa`(FQA 세션) · `/vstqa`(TQA 배치) 로 직접 호출하거나, 사용자가 "FQA 세션", "TQA", "QA 돌려줘", "봇 배치", "밸런스 시뮬레이션", "시뮬 돌려줘", "회귀 배치", "판정시트", "재미 판정", "밸런스 검증/실측"을 요청할 때, 판정 피드백(⭕/❌/➖, "1번 재밌었음", "처형이 헐렁함" 같은 재미 평가)을 줄 때, 버전업 직후 "검증해줘"라고 할 때, FUN_CRITERIA/재미 기준을 언급할 때 반드시 사용한다. 밸런스 수치를 바꾼 뒤 효과 확인이 필요한 상황에도 트리거된다. 기획 토론·덱 정리(VSDebate)나 순수 기능 구현에는 쓰지 않는다.
---

# VSQA — TQA·FQA 운영 스킬

이 프로젝트의 QA 는 두 축이다. **어느 쪽 요청인지 먼저 판별**하고 해당 절차를 따른다.

| | TQA | FQA |
|---|---|---|
| 질문 | 스펙대로 도는가 · 수치가 범위인가 | **재밌는가** |
| 판정자 | 봇 (자동) | **사람 (사용자)** — Claude 는 절대 재미를 확정하지 않는다 |
| 산출물 | 배치 로그 + 진단 플래그 | 판정 시트 → 재미 기준 원장 갱신 → 밸런스 재조정 |

단일 소스 파일 (항상 이 경로 기준):
- 재미 기준 원장: `QA/FQA/FUN_CRITERIA.md` — **밸런스를 만지기 전 반드시 읽는다**
- 판정 시트(HTML): `QA/FQA/sessions/NNN_YYYY-MM-DD_주제/판정시트.html`
  — 템플릿: 이 스킬의 `assets/fqa-판정시트-template.html`
- TQA 리포트(HTML): `QA/TQA/bot/logs/YYYY-MM-DD_주제_리포트.html`
  — 템플릿: 이 스킬의 `assets/tqa-리포트-template.html`
- 봇 하네스: `QA/TQA/bot/qa_harness.html` (도구 상세: `QA/TQA/bot/README.md`)
- 로그: `QA/TQA/bot/logs/` (`YYYY-MM-DD_내용.json`)
- 게임 수치를 바꿀 때는 `WORKFLOW.md` 규칙(새 index_N·FALLBACK 동기·PATCH_LOG·커밋)을 그대로 따른다

**슬래시 명령**: `/vsfqa [메모]` = FQA 세션 시작(또는 판정 반영), `/vstqa [요청]` = TQA 배치.
정의 파일은 `.claude/commands/vsfqa.md` · `vstqa.md` — 둘 다 이 SKILL.md 를 따르라고 위임한다.
새로 추가된 커맨드는 클라이언트가 세션 시작 시 슬래시 목록을 캐싱하는 경우가 있어, 방금 만들었거나
수정한 직후에는 목록에 안 보일 수 있다(새 대화를 열면 반영됨) — 그래도 "FQA 세션 돌려줘" 같은
자연어는 이 스킬의 설명 매칭으로 즉시 트리거되니 슬래시가 안 보여도 동작은 동일하다.

**HTML 피드백 파이프라인 (핵심)**: TQA 리포트와 FQA 판정시트는 항상 위 템플릿 기반의 자기완결 HTML 로
만든다. 사용자는 브라우저에서 항목을 체크(⭕/❌/➖ 또는 조치 후보)하고 텍스트박스에 의견을 적은 뒤,
하단 버튼으로 **`/vsfqa …`·`/vstqa …` 프롬프트를 복사해 채팅에 붙여넣는다** — 그게 다음 턴의 입력이 된다.
템플릿 사용법: 파일을 복사한 뒤 **상단 "데이터 블록"(SESSION/ITEMS 또는 REPORT/SUMMARY/FLAGS/NOTES)만
교체**한다. CSS/JS 골격은 절대 건드리지 않는다(입력 자동저장·프롬프트 생성 로직이 거기 있다).

## 봇 배치 실행 방법 (TQA·FQA 공통)

1. 프리뷰 서버 `vslike`(포트 5607, 리포 루트) 를 preview_start 로 켠다.
2. 하네스 자동 모드 URL 로 이동시킨다:
   ```
   /QA/TQA/bot/qa_harness.html?auto=1&scenarios=<id,id>&speed=60&dur=900&runs=3&seed=1234
     [&build=index_N.html] [&override=<URL인코딩 JSON>]
   ```
   - 시나리오 id: `standard` `noexec` `greedy` `coward` `afk` `slashonly` `noslash` `pressure2x` `scythefocus`
     (기본 배치 = standard,noexec,greedy,afk,pressure2x × 3시드 · 정의는 `qa_scenarios.js`)
   - `build` 는 **항상 최신 index_N** 을 명시한다 — 하네스 기본값이 구버전일 수 있다.
   - 같은 시드+배속 = 같은 판 재현(회귀 비교의 근거). 기준 시드 1234 (runs=3 이면 1234/9153/17072).
3. 완료 폴링: `window.__QA.done===true` 를 preview_eval 로 확인 (짧게 여러 번 — 25초 초과 대기 금지).
   숨김 탭에선 봇이 풀스로틀로 돌므로 900초×21런도 수 분 내 끝난다.
4. 결과 추출: `window.__QA.results` 에서 요약만 뽑는다(샘플 전체 X — 크다). 진단 패널 텍스트는
   `document.getElementById('diag').innerText`.
5. 로그 저장: 요약 배열 + 진단을 `QA/TQA/bot/logs/YYYY-MM-DD_주제.json` 으로 Write (기존 로그의 `_meta`/legend 형식 유지).
6. 콘솔 에러 0건 확인.

주의: 봇은 주입식이라 **build/ 게임 파일을 절대 수정하지 않는다**. 승리 조건 미구현 → `capReached` = 생존으로 해석.
밸런스 실험은 ①공통 `override` 파라미터 ②시나리오별 `override` 필드 ③`spawnMult/eliteMult` 파라미터로 한다.
`groggy.duration`·`execution.*` 같은 미러 값도 봇이 알아서 재적용하므로 override 에 그냥 넣으면 된다.

## TQA 요청 처리 ("/vstqa" · "TQA 돌려줘" · "검증해줘" · 버전업 직후)

1. 목적 판별: **회귀**(버전업 후 이상 없나) / **계측**(현재 상태 측정) / **스윕**(특정 노브 실험).
2. 회귀면: 직전 로그와 같은 시드·시나리오로 돌리고, 시나리오별 생존/딜지분/처형 지표를 이전 로그와 표로 비교. 유의미한 변화(생존률 ±1런 이상, 딜지분 ±10%p 등)에 원인 가설을 붙인다.
3. 스윕이면: 한 번에 노브 1~2개만. 각 값당 3시드. 결과는 "노브 값 → 지표 변화 → 해석" 표로.
4. 진단 플래그(지배빌드·죽은무기·사망클러스터·밀도·적체)는 매 배치 반드시 보고에 포함한다.
5. **HTML 리포트 생성**: `assets/tqa-리포트-template.html` 을 복사해 `logs/YYYY-MM-DD_주제_리포트.html` 로 만들고
   REPORT/SUMMARY/FLAGS/NOTES 데이터 블록을 채운다. 진단 플래그·조치 후보는 `act:true` 로 넣어 사용자가
   체크+의견을 달 수 있게 한다. 채팅 보고에는 요약 표 + 리포트 링크를 담고, "리포트에서 체크 후
   복사 버튼으로 후속 요청을 보내면 된다"고 안내한다.
6. 로그(json) 저장 → WORKFLOW §6 에 따라 커밋.
7. 사용자가 `/vstqa 후속 요청 …` 을 붙여넣으면: 체크된 항목별 조치안을 제안하고 진행한다(밸런스 변경은 WORKFLOW 준수).

## FQA 세션 처리 ("/vsfqa" · "FQA 세션 돌려줘")

재미의 판정자는 항상 사람이다. Claude 의 역할은 ①판정하기 좋은 재료 만들기 ②판정을 기준으로 축적 ③기준에 맞게 조정 — 이 세 가지뿐이다.

1. **재학습**: `FUN_CRITERIA.md` 를 읽는다. `확정` 기준은 제약 조건, `제안` 기준은 이번 세션의 확인 대상.
2. **배치**: 위 방법으로 TQA 배치 실행. 이전 세션에서 튜닝했다면 A/B 비교(이전 값 vs 새 값)를 포함.
3. **판정 시트(HTML) 생성**: `sessions/` 에서 기존 최대 번호 +1 로 `NNN_YYYY-MM-DD_주제/판정시트.html` 을 만든다
   — `assets/fqa-판정시트-template.html` 을 복사해 SESSION/ITEMS/FREE_HINT 데이터 블록만 교체.
   판단 요소(ITEMS)는 **사람 언어**로 쓴다 — 수치를 그대로 나열하지 말고 "2분 러시 때 HP가 40%까지 밀렸다 —
   이 쫄림이 맞나?" 처럼 "느낌 질문"으로 바꾼다. 각 요소에 근거 수치(basis)·관련 기준 ID(crit)·실플레이
   확인 구간(guide)을 붙인다. 요소는 5~8개로 제한한다 — 사람이 한 세션에 판정할 수 있는 양이 그 정도다.
4. **안내 후 대기**: 사용자에게 시트 링크(더블클릭으로 열림) + 플레이 URL(`/build/index_N.html`)을 알려주고
   "시트에서 ⭕/❌/➖ 체크 + 메모 → 하단 [판정 프롬프트 복사] → 채팅에 붙여넣기" 흐름을 안내한 뒤 기다린다.
   여기서 멈춘다 — 판정 없이 다음 단계로 가지 않는다.
5. **판정 수신**: 사용자가 시트에서 복사한 `/vsfqa 세션 N 판정 …` 프롬프트를 붙여넣거나 채팅으로 말하면
   ("1번 ⭕, 3번 ❌ 처형이 헐렁함") 받은 판정을 세션 폴더에 `판정기록.md` 로 저장한다(원문 그대로 + 날짜).
   거친 메모도 그대로 받아 의도를 해석한다.
6. **기준 승격 (재학습의 핵심)**: 판정을 `FUN_CRITERIA.md` 에 반영한다 —
   - ⭕/❌ 가 기존 기준을 지지/반박하면 상태·목표 범위 갱신 (제안→확정, 범위 조정).
   - 새로운 불만/칭찬이면 새 F-번호로 추가하되, **사람 언어 → 봇 지표 번역**을 반드시 채운다
     (예: "쫄리는 맛이 없다" → 받은피해/분 + 빈사 횟수/런 목표 범위. 번역 불가능하면 '실플레이 판정' 항목으로 표기).
   - ➖ 는 다음 세션에 A/B 변형을 만들어 비교시킬 목록에 올린다.
   - 기준끼리 충돌하면(압박↑ vs 성장 쾌감↑) 문서의 "충돌 메모"에 적고 사용자에게 우선순위를 묻는다.
   - 판정 히스토리에 날짜와 요지를 한 줄 남긴다.
7. **재조정**: 확정 기준 미달 항목의 밸런스를 튜닝한다.
   - `gameBalance.json` 수치만으로 되면: WORKFLOW 규칙대로 JSON + 최신 인덱스의 FALLBACK_BALANCE 동기 갱신.
   - 코드 변경이 필요하면: WORKFLOW 규칙대로 **새 index_N+1** 을 만들어 작업 (구버전 무수정).
8. **검증 → 예고**: TQA 배치로 "기준 목표 범위에 들어왔는지" 수치 확인 후, 시트의 "다음 튜닝 예고"를 채우고
   다음 세션에서 뭘 다시 판정받을지 알려준다. 커밋(WORKFLOW §6).

## 판정 → 지표 번역 감각 (예시)

| 사람 언어 | 봇 지표 | 비고 |
|---|---|---|
| "쫄리는 맛이 없다" | 받은피해/분 · 빈사(HP<25%) 횟수/런 | 생존 런 기준으로 잡는다 |
| "처형이 잡일 같다" | 처형/분 상한 · 처형 간 평균 간격 | 빈도가 특별함을 죽인다 |
| "밀리다 역전하는 맛" | 분당 클리어율(DPS÷유입) <1 → ≥1.5 반전 시점 | 적체 구간은 지우지 말고 배치하는 것 |
| "이 무기 존재감이 없다" | 보유 런 평균 딜 지분 (<3% = 죽은 무기) | 진단 플래그와 동일 기준 |
| "손맛·연출·타격감" | **번역 불가** → 실플레이 판정 항목 | 억지로 수치화하지 않는다 |

번역의 원칙: 사용자의 말을 좁게 해석하지 말 것. "재미없다"의 원인 후보를 2~3개 세우고 각각을 지표로
검증해 어느 가설이 맞는지 데이터로 좁힌 뒤 튜닝한다.

## 보고 스타일

- 결과는 **표 + 진단 플래그 + 한 줄 해석**으로. 원시 수치 나열 금지.
- 판정 시트/로그/기준 원장은 항상 클릭 가능한 링크로 안내.
- 판정을 받은 뒤에는 "무엇을 어떻게 반영했는지"(기준 변화 → 수치 변화)를 짧게 되짚어 사용자가
  자기 판정이 어디에 쓰였는지 알게 한다 — 이게 루프를 계속 돌게 만드는 신뢰의 핵심이다.
