| name | verify-report |
| description | PR/구현 검증을 PM·비개발자도 이해할 수 있는 캡처 중심 HTML 리포트로 만든다. Jira/Notion/Slack/와이어프레임/PR test plan 같은 기획 근거를 사용자-facing 동작과 매핑하고, 핵심 UI 흐름은 스크린샷/GIF를 primary evidence로 증명한다. 로직/API/DB/code diff 검증은 하단 기술 보조 검증으로 정리한다. 기본은 로컬 확인용이며 업로드/PR 업데이트는 명시 요청 시에만 한다. |
| argument-hint | [base-url] [--upload] [--update] [--ask-before] [--no-workers] |
Verify Report
구현이 기획 의도대로 동작한다는 사실을 PM·비개발자도 캡처/GIF만 보고 이해할 수 있게 HTML 리포트로 만든다. 리포트의 중심은 개발 과정 로그가 아니라 “기획 근거 → 사용자-facing 성공 기준 → 실제 화면 증거”의 매핑이다. 화면 변화는 PNG/GIF 캡처를 primary evidence로 삼고, 로직/API/DB/code diff 검증은 하단 기술 보조 검증으로 분리한다.
원칙
- PM-facing이 기본값: 리포트는 개발자 디버깅 로그가 아니라 PM·기획자·디자이너가 구현 핵심과 동작을 빠르게 이해하는 공유 문서다. 내부 셋업/삽질보다 사용자-facing 결과를 먼저 보여준다.
- 기획 근거와 구현 동작을 매핑: Jira, Notion, Slack, 와이어프레임, PR test plan, frame 성공 기준이 있으면 각 요구를 실제 화면 동작/상태와 연결한다. 출처가 없는 코드 리스크는 별도 기술 보조 검증으로 내린다.
- Frame은 requirement source, report는 evidence adjudicator: TFT Frame의 Requirement Matrix/Domain Work Map/verify focus는 중요한 입력 source지만 최종 판정표를 그대로 복사하는 SSOT가 아니다.
/verify-report는 Frame 항목을 reuse/revise/add/drop/blocked로 재판정하고, 최신 사용자 지시·구현 diff·데이터/권한 현실성·캡처 가능성으로 evidence 계약을 확정한다.
- 과거 교정은 intent로 재해석: 이전 실패 회고나 사용자 교정은 중요한 제약이지만, 기능의 primary action을 덮어쓰는 literal 요구가 아니다. 먼저 교정이 막으려던 실패(intent)를 추출하고, 현재 데이터/권한/side effect상 literal 실행이 비현실적이면 같은 intent를 보존하는 현실적인 equivalent path를 제안하거나 선택한다. blocked는 교정 intent까지 보존할 대체 경로가 없을 때만 쓴다.
- 캡처 중심 리포트: UI 기능의 primary evidence는 focused screenshot/GIF다. code diff, API 응답, DB 조회, unit test는 PM-facing 화면 증거를 보조하거나 비가시 정책을 설명하는 하단 근거로 둔다.
- UI 캡처 번들은 공통 기본값: 모든 정적 UI 화면 검증은
contextual focused crop을 primary evidence로 두고, 같은 route/action/viewport의 full viewport screenshot을 supporting evidence로 함께 둔다. crop은 너무 좁게 잘라 label·컨테이너·주변 맥락을 잃지 않게 하고, 검증 포인트를 알아볼 만큼 주변 UI를 포함한다. user-facing Web UI는 desktop과 mobile viewport를 둘 다 기본 검증하고, 단일 플랫폼/admin desktop-only처럼 해당하지 않으면 생략 사유를 detail/Coverage Gap에 남긴다.
- Coverage 먼저, 캡처는 그 다음: 리포트 시작 전에 요구사항으로 검증 축을 정의한다. 캡처가 있어도 해당 축을 닫지 못하면 PASS가 아니다.
- Oracle surface 먼저 정의: 각 claim이 참/거짓으로 판정되는 전체 표면을 먼저 적는다. 표면은 “첫 화면에 보이는 일부”가 아니라 사용자가 판단해야 하는 전체 subject/action/state range다. 예: 전체 리스트, 전체 carousel/page set, 모든 option state, before/after 동일 interaction path, role별 허용/차단 경계, 저장 후 downstream 표시까지. Evidence가 이 판정 표면 전체를 같은 조작 경로로 덮지 못하면 PASS가 아니라 Coverage Gap이다.
- Surface fan-out은 report 책임: 반복 카드·썸네일·badge·tag·list item UI 변경은 사용자가 별도로 말하지 않아도
/verify-report가 consumer surface matrix를 만든다. 단일 공통 컴포넌트 캡처만으로 닫지 말고, 각 surface를 capture/technical evidence/exclusion or gap으로 분류한다. Preflight가 있으면 재사용하되, 없으면 diff/frame/user request/project overlay preset에서 자체 도출한다.
- Motion-first evidence: 이동/전환/클릭/열림/닫힘/스무스함/끊김 없음처럼 시간 흐름이 claim이면 정적 PNG만으로 PASS 처리하지 않는다. GIF/짧은 영상이 primary evidence이고, 대표 final-state PNG/crop은 supporting evidence로 함께 둔다. GIF는 판독 가능한 품질이어야 하며, 기본 생성 경로는
skills/verify-report/scripts/make-motion-gif.mjs helper다. helper 기본값은 원본 해상도 유지(--width source), 12fps, 8초 trim, palettegen/paletteuse + sierra2_4a dithering이다. 저용량을 이유로 390px/8fps/no-palette처럼 텍스트와 색상이 깨지는 설정을 primary evidence에 쓰지 않는다.
- Setup noise 격리: 로그인, 빌드, Metro/dev-server, pod/env/codegen, dependency bootstrap처럼 검증 전 준비 과정은 리포트의 PASS item에 넣지 않는다. setup 자체가 검증 대상이거나, 검증을 막은 blocked/coverage gap일 때만 짧게 남긴다.
- 실패 리포트 export 금지: 구현 완료 검증 목적의 PM-facing report는
fail 항목이 있으면 정적 HTML로 export하지 않는다. 실패를 발견하면 report 생성을 멈추고 구현 수정 → 재검증으로 돌아간다. 실패 재현/분석 리포트가 목적일 때만 reportPurpose: "failure-analysis" 또는 allowFailingReport: true를 명시한다.
- 미검증 명시: 자동화로 확인하지 못한 항목은 PASS로 쓰지 않고
미검증/blocked/Coverage Gap에 남긴다.
- 렌더링 claim은 실제 렌더로 닫는다: 구조도, TUI, WebView, Markdown/HTML preview, SVG/이미지 생성처럼 “보인다”가 성공 기준인 작업은 source text, Mermaid codeblock, raw inline SVG, HTML 파일 생성만으로 PASS가 아니다. 실제 artifact를 열어 렌더링된 결과를 확인하고, 가능하면 캡처를 evidence로 남긴다.
- 짧고 초점 있는 primary evidence: 리포트 본문 핵심 증거는 검증 claim을 직접 닫는 artifact여야 한다. 정적 UI는 viewport/섹션/element crop, flow UI는 GIF/짧은 영상이 primary다. 세로로 긴 full-page 캡처는 필요할 때만 보조 증거로 남기고 토글/appendix/link 뒤에 둔다.
role: "primary"인 이미지/GIF는 renderer가 full-width로 보여주므로, 한 항목의 핵심 before/after 합성 이미지나 단일 핵심 crop에는 반드시 primary role을 붙인다.
- 텍스트 합성 캡처는 glyph 확인: 메시지 본문·알림톡·TUI처럼 실제 텍스트를 이미지로 렌더링할 때는 대상 언어 glyph가 있는 폰트(예: 한글은 Apple SD Gothic Neo/AppleGothic/Noto Sans CJK)를 사용한다.
□/tofu box가 보이면 인코딩 문제가 아니라 폰트 fallback 실패일 가능성이 높으므로 리포트 확정 전에 재렌더링한다.
- Raw evidence에도 의도를 붙인다: 모든 evidence에는 가능한 한
purpose, inspectFor, expected, observed, role, relatedItem을 붙여 “왜 수집했는지 / 무엇을 봐야 하는지”가 report와 /archive의 캡처/미디어 탭에서도 보이게 한다. Raw 파일의 의도는 별도 섹션으로 분리하지 말고 해당 raw 토글 내부 상단에 함께 보여 시선이 흩어지지 않게 한다.
- Item detail은 읽히는 설명이어야 한다:
detail에는 긴 한 문단을 넣지 말고 조건/관찰/제약을 문장 단위나 줄바꿈 bullet로 나눈다. renderer는 긴 detail을 자동 bullet card로 정리하고 backtick inline code와 URL link를 강조하지만, agent도 “왜 직접 캡처하지 못했는지 / 무엇으로 대체 검증했는지 / 남은 gap은 무엇인지”가 눈에 들어오게 작성한다.
- 판정은 엄격하게, 레이아웃은 기본값으로: PASS/미검증/coverage gap과 evidence metadata는 strict하게 지키되, 섹션 순서·카드 수·표현 방식은 케이스에 맞게 renderer default가 흡수한다. 에이전트는 양식 채우기보다 기준을 증거로 닫는 데 집중한다.
- Renderer design default: report UI는 generative-ui식 디자인 절제를 참고하되, 사용자에게 읽고 싶을 만큼 강한 verdict/coverage hierarchy를 제공한다. 검증 report는 심심한 문서가 아니라 판단 artifact이므로 상단 verdict, PASS/GAP 색상, 핵심 증거 카드의 리듬을 살린다. 새 dependency를 붙여 AI가 매번 HTML을 생성하게 하지 않고, deterministic renderer가 일관된 구조를 만든다.
- Before/After 비교는 판단해서 포함: 기존 UI/동작이 기준점으로 의미 있는 변경은 작업 전(before)과 작업 후(after)를 같은 축/viewport/role로 캡처하고, 차이를 설명한다. 신규 화면처럼 baseline이 없거나 부작용 위험이 큰 경우는 생략 사유를 남긴다.
- 업로드 opt-in: 기본
/verify-report는 로컬 리포트 확인까지만 한다. project artifact storage 업로드와 PR 본문 갱신은 --upload 또는 사용자의 명시적 업로드 액션이 있을 때만 한다.
- Case worker fan-out 기본: main agent가 coverage 계획·환경·허용 액션을 정의하고, 여러 검증 축은 case worker subagent가 계획된 캡처/로그/명령 실행과 1차 검증을 병렬 수행한다.
--no-workers가 있거나 단일·자명한 항목이면 main이 직접 실행한다.
- Main final adjudicator: subagent는 계획된 evidence를 만들고 의견을 반환할 뿐이다. 최종
pass/fail/unverified 판정, 계획 밖 추가 캡처/재캡처 승인, 사용자 질문, verify_report_live 업데이트는 main만 한다.
- 프리뷰 강제: HTML 생성 후 Glimpse WebView로 먼저 보여주고, 사용자가 확인한 뒤 다음 행동을 정한다.
Preflight 선택
검증 축은 필요하지만 데이터/계정/preview/before 기준이 불명확하거나, 작은 hotfix에 full report가 과할 수 있으면 먼저 /verify-report-preflight를 사용한다. 단, preflight는 선택적 확인 단계다. 사용자가 preflight를 생략해도 /verify-report는 이 스킬의 coverage/fan-out 규칙을 자체 적용해야 한다.
light: focused screenshot/log/test 1~2개 또는 /verify-report --no-workers로 닫는다.
standard/full: coverage plan을 확정한 뒤 이 스킬의 live report 흐름으로 들어간다.
blocked: 캡처를 시작하지 말고 필요한 URL/role/data/side-effect 승인만 사용자에게 요청한다.
Preflight는 PASS 증거가 아니며, 최종 판정은 여전히 이 스킬의 evidence/coverage gate 또는 /verify 결과로 닫는다.
모드 (default: confirm-only)
| 모드 | 설명 | 트리거 |
|---|
| confirm (default) | 로컬 캡처/검증 증거 수집 + HTML 프리뷰만. 업로드 X | 기본 |
| upload | confirm + project artifact storage 업로드 + PR 본문 갱신 | --upload 인자 또는 사용자가 명시 요청 |
| update | 기존 리포트에 신규 검증 항목 append/update/replace | --update 인자 또는 “추가/교체/기존 리포트에 반영” 키워드 감지 |
| ask-before | 항목별 검증 실행 전 사전 확인 | --ask-before 인자 또는 사용자가 요구 |
Escape hatch:
--no-workers: case worker subagent fan-out을 끄고 main agent가 모든 항목의 플로우 실행과 판정을 직접 수행한다. report live/update/finish 절차는 동일하다.
실행 단계 개요
| Step | 설명 | confirm | upload | update |
|---|
| 1 | 성공 기준 수집 + 캡처/증거 유형 분류 | ✓ | ✓ | ✓ (신규만) |
| 2 | 검증 환경 확인 | ✓ | ✓ | ✓ |
| 3 | 로그인/권한 Credential 확보 | ✓ | ✓ | ✓ |
| 4 | 검증 계획 수립 → 유저 확인 | ✓ | ✓ | ✓ |
| 4-B | (ask-before 모드만) 항목별 사전 확인 | opt | opt | opt |
| 5 | verify_report_live 시작 → case worker plan/brief 작성 → 필요 시 공유 증거 수집 | ✓ | ✓ | ✓ |
| 5-B | case worker subagent fan-out으로 계획된 캡처/로그/명령 실행 + 1차 검증 (--no-workers면 skip) | ✓ | ✓ | ✓ |
| 6 | main 결과 adjudication → live preview 갱신 → 정적 HTML export → 유저 리뷰 | ✓ | ✓ | ✓ (병합) |
| 7 | project artifact storage 업로드 | | ✓ | ✓ |
| 8 | context.md + PR 본문 업데이트 | | ✓ | ✓ |
| 9 | 후속 단계 AskUserQuestion | ✓ | ✓ | ✓ |
상세 참조:
Step 1: 기획 근거 수집 + 성공 기준 매핑 + 캡처/증거 유형 분류
소스 우선순위:
- 사용자가 이번 검증에서 직접 지정한 기준 — “이 화면을 보여줘”, “기획대로 동작하는지 증명해줘” 같은 최신 지시
- 기획 근거 — Jira, Notion, Slack, 와이어프레임, 디자인 시안, 요구사항 문서
- PR test plan —
gh pr view body의 ## Test plan
- Verify 체크리스트 —
.context/work/{workspace}/context.md의 ## Verifications
- Frame 성공 기준 —
.pi/frame.json 또는 frame transcript의 success criteria
- 구현 코드 분석 — 기획 근거가 비어 있는 리스크를 보완하는 보조 입력
- 정책축 스캔 / 백엔드 레이어 맵 — 비가시 정책·레이어 책임은 하단 기술 보조 검증 후보로 승격
Frame/TFT plan이 있으면 먼저 Frame handoff adjudication 을 작성한다. Frame 항목을 그대로 복사하거나 무시하지 말고, 각 requirement/verify item에 아래 판정을 붙인다.
| 판정 | 의미 | 처리 |
|---|
reuse | Frame 항목의 claim/subject/evidence가 현재 검증에도 그대로 맞음 | Requirement ID를 유지해 V/T item으로 승격 |
revise | intent는 맞지만 subject/action/evidence가 현재 현실과 다름 | Requirement ID와 변경 사유를 남기고 equivalent path로 수정 |
add | 최신 사용자 지시, 구현 diff, 데이터/권한 확인에서 새 축 발견 | 새 V/T item으로 추가하고 출처를 명시 |
drop | 현재 scope 밖, 중복, 더 이상 유효하지 않음 | report에서 제외하되 이유를 남김 |
blocked | 대체 경로도 없어 검증 불가 | Coverage Gap/blocked item으로 남김 |
수집 직후 먼저 핵심 사용자 행동(primary action) 을 고정한다. 이 기능이 create, update, read/display, delete, permission denial, event emission 중 무엇으로 성공하는지 분리한다. 과거 교정이 있으면 문장을 literal과 intent로 나눈다. 예를 들어 “같은 기존 항목으로 비교”가 권한 정책상 불가능한데 기능의 핵심이 “새 항목 생성 시 선택값 저장/표시”라면, literal 기존 항목 수정에 매이지 말고 “user-facing에 노출되는 생성 가능한 subject로 새 항목을 만들어 선택값별 표시를 확인”하는 equivalent path로 재구성한다.
수집 직후 각 요구를 PM-facing 검증 계약으로 바꾼다.
| 필드 | 의미 |
|---|
| 근거 출처 | Jira/Notion/Slack/와이어프레임/PR test plan/frame/사용자 지시 |
| Frame handoff 판정 | Frame 항목이면 reuse/revise/add/drop/blocked 중 무엇인지와 이유 |
| PM-readable claim | 비개발자가 이해할 수 있는 성공 문장 |
| 핵심 사용자 행동 | create/update/read-display/permission/event 중 기능을 실제로 닫는 primary verb |
| 사용자/관리자 시나리오 | 어떤 role이 어떤 화면에서 무엇을 조작하는지 |
| 대상 subject | 같은 row/id/order/review/user 등 상태 전환을 증명할 기준 subject |
| 화면 oracle | 무엇이 보이면 기획대로 구현된 것인지 |
| oracle surface | 그 oracle을 판정하려면 전체 어디까지 봐야 하는지. 첫 viewport/첫 row/대표 1건인지, 전체 list/page/carousel/option/role/state/downstream까지인지 명시 |
| primary visual evidence | screenshot/GIF/crop 중 무엇으로 보여줄지 |
| 하단 기술 보조 검증 | API/DB/code/test가 필요한 경우만 기록 |
| 제외할 noise | 로그인 실패, bootstrap, selector 삽질 등 report에서 숨길 준비 과정 |
과거 교정/실패 회고가 현재 기능의 primary action과 충돌하면, 아래 순서로 처리한다.
- 교정 literal과 intent를 분리한다. (
기존 row만 써라 vs 서로 다른 조건의 데이터를 섞지 마라)
- literal 실행 가능성을 확인한다. 권한 정책, user-facing 노출 여부, side effect 위험을 본다.
- literal이 비현실적이면 core feature path에서 intent를 보존하는 equivalent subject/action을 찾는다.
- equivalent path가 있으면 그 경로를 검증 계약에 명시하고 진행한다. 없을 때만 blocked/unverified로 내린다.
그 다음 각 항목마다 oracle surface gate를 먼저 통과시킨다. Claim이 참/거짓으로 판정되는 전체 표면이 무엇인지 적고, evidence가 그 전체 표면을 같은 subject/role/viewport/action path로 덮는지 확인한다. “첫 화면에 3개 보임”, “대표 row 하나만 보임”, “after만 캡처함”, “다른 subject로 비교함”은 claim 전체를 닫지 못하면 supporting evidence일 뿐 PASS 근거가 아니다.
Oracle surface 예시:
| Claim 유형 | oracle surface |
|---|
| 리스트/캐러셀/페이지네이션 중복·정렬·누락 | 전체 item range와 순서. before/after가 있으면 같은 interaction path로 처음부터 끝까지 비교 |
| filter/search/result count | 입력 조건, empty/data/overflow 상태, 전체 result boundary 또는 sampling 기준 |
| option/default/selection | no data, existing data, refresh/stale, 저장 후 재조회 상태 |
| create/update action | 입력 → 저장 → reload/read → downstream user-facing 표시까지 |
| permission/role | 허용 role success path + 차단 role denial path + 잘못된 role을 blocker로 오인하지 않았는지 |
| responsive/layout | mobile/boundary/desktop의 문제 표면 전체. 한 viewport crop만으로 responsive claim PASS 금지 |
| event/network | trigger path, non-trigger path, payload/count, 중복 발화 여부 |
그 다음 각 항목을 검증 축(coverage axis) 으로 쪼개고, 축마다 화면 캡처로 검증할지, 하단 보조 근거로 검증할지 분류한다. 반복 카드·썸네일·badge·tag 정책은 여기서 consumer surface fan-out matrix를 반드시 만든다. 각 surface는 실제 route/subject를 찾고, 못 찾으면 PASS 대신 exclusion 또는 Coverage Gap으로 남긴다.
필수 coverage 도출 규칙:
| 변경 감지 | 기본 검증 축 |
|---|
| 정적 UI 화면 검증 | contextual focused crop primary + same-route full viewport supporting + desktop/mobile 적용 여부 |
| responsive class/layout 변경 | mobile(예: 390px) + breakpoint boundary(예: 480/500/640px) + desktop(예: 1320~1440px) |
| nav/sidebar/menu 변경 | expanded + collapsed + 영향받는 role/account |
| typography/logo/token 변경 | screenshot + DOM class/token + computed font-size/line-height |
| table/card/overflow 변경 | empty state + data state + overflow/scroll state |
| 반복 카드/썸네일/badge/tag/list item 변경 | consumer surface matrix + 각 surface의 actual route subject + focused crop primary + full viewport supporting + mobile 별도 viewport + exclusion/gap 사유 |
| option/default selection 변경 | no data + data exists + stale/refresh selection 유지 |
| create/update/read 등 primary action이 있는 기능 | primary action happy path + downstream user-facing 표시/저장 확인 + 필요한 regression path |
| 기존 UI/동작을 바꾸는 수정 | 같은 route/action/viewport/role의 before + after 비교 |
| 정책축 스캔이 있는 작업 | channel_matrix의 각 채널 + time_basis/default_fallback/application_cardinality/data_migration/api_cache_identity 축 |
| 백엔드 레이어 맵이 있는 작업 | entry_point/application_flow/domain_rule/data_access/cache_batching/persistence/consumer 책임 축 |
| rendered artifact / diagram / Studio UI 변경 | UI_CAPTURE 또는 artifact preview capture. source text/HTML 생성만으로 PASS 금지 |
더 자세한 프리셋은 references/coverage-and-capture-quality.md를 따른다.
| 분류 | 설명 | 리포트 증거 |
|---|
| UI_CAPTURE | 화면에 보이는 상태/플로우 | PNG/GIF + 짧은 설명 |
| NETWORK | GA/픽셀/API 요청 발화/미발화 | request/response 로그, matched count, 필터 조건 |
| CONSOLE | 콘솔 출력/런타임 상태 | console log/error 캡처 |
| CODE_DIFF | 코드 구조 자체가 근거 | 하단 기술 보조 검증의 관련 diff/파일/라인 요약 |
| BE | API/권한/DB만 영향 | 하단 기술 보조 검증의 API 응답, SQL 결과, 로그 또는 CODE_DIFF |
| SKIP | 이번 리포트에서 제외 | 제외 사유 |
정책축 스캔이 있는 작업은 “보이는 화면”만 캡처하지 말고, 각 채널이 올바른 기준 시간을 쓰는지와 DEFAULT/다중 적용 규칙이 실제 결과에 반영되는지를 항목으로 분리한다. 화면 증거가 없는 축은 BE/API/SQL/log/code diff 증거로 닫고, 닫지 못하면 Coverage Gap으로 남긴다.
백엔드 레이어 맵이 있는 작업은 사용자-facing 결과뿐 아니라 “책임이 올바른 레이어에 있는가”도 CODE_DIFF/BE 증거로 닫는다. 예를 들어 resolver는 연결만 하는지, repo는 조회 조건만 소유하는지, VO는 계산/불변식을 소유하는지, loader key에 기준 값이 들어가는지를 항목화한다.
분류 결과를 사용자에게 보여주고 확인한다. 이 계획은 개발자용 테스트 목록이 아니라 PM-facing 리포트의 목차여야 한다.
다음 기획 근거 → 구현 동작 → 캡처 증거 매핑으로 리포트를 만들겠습니다. 수정할 게 있나요?
| # | Frame handoff | 근거 출처 | PM-readable 성공 기준 | 시나리오/subject | primary evidence | 하단 보조 검증 |
|---|---------------|-----------|-------------------------|------------------|------------------|----------------|
| V1 | reuse R1 | Jira COM-123 | 관리자가 새 옵션을 켜면 사용자 화면에 새 CTA가 보인다 | admin 설정 → user detail / item=123 | before/after focused crop | API 응답 JSON |
| V2 | 와이어프레임 | 모바일에서 카드가 한 줄로 겹치지 않는다 | anonymous / 390×844 | mobile crop | 없음 |
| V3 | PR test plan | 클릭 플로우가 끊기지 않고 상세로 이동한다 | member / click CTA | GIF primary + final PNG | console error 0 |
| T1 | 코드 리스크 | 권한 없는 mutation은 차단된다 | unauthorized role | 없음 | API 403 response |
Step 2: 검증 환경 확인
which agent-browser
which ffmpeg
대상 URL: $ARGUMENTS > Preview URL (PR 감지) > dev/staging URL > 로컬 서버 순으로 자동 감지 후 AskUserQuestion으로 확인한다. 환경 차이가 검증 결과에 영향을 주는 경우(NODE_ENV vs 배포 환경 등)는 리포트에 명시한다.
프로젝트별 preview URL, 계정 alias, 업로드 대상 저장소 규칙이 있으면 private/project overlay skill을 추가로 로드한다.
Before/After가 필요한 항목은 before 기준도 함께 정한다.
- 우선순위: 사용자 제공 before URL/capture > PR base preview/develop/production > base branch local 실행 > 기존 report/archive capture
- before와 after는 가능한 한 같은 route, query, data fixture, viewport, role, action으로 맞춘다.
- before 재현이 과도하게 비싸거나 데이터/결제/외부 side effect 위험이 있으면 캡처하지 말고
before 생략 사유를 Coverage Gap 또는 detail에 남긴다.
Step 3: 로그인/권한 Credential 확보
검증 항목에서 필요한 역할을 판별해 역할별 AskUserQuestion으로 확보한다. 추가 계정을 거부하면 해당 항목은 SKIP 또는 부분 검증으로 표시한다.
Step 4: 검증 계획 수립
| 캡처/증거 유형 | 형태 |
|---|
| UI 단일 상태 | contextual focused crop primary + full viewport supporting. user-facing Web이면 desktop/mobile viewport를 둘 다 기본 캡처하고, 예외는 사유를 남긴다. |
| UI 다단계 플로우 / 스무스함 / 이동 | 고화질 GIF 또는 짧은 영상 primary + 대표 final-state contextual crop + full viewport supporting. 기본 GIF 생성은 make-motion-gif.mjs helper를 사용하고, 원본 해상도 유지 + 12fps + palette 최적화를 기본값으로 한다. |
| NETWORK | JSON/표 + 필요 시 화면 PNG |
| CONSOLE | 로그 excerpt + 필요 시 화면 PNG |
| CODE_DIFF | 파일/라인/diff 요약 |
| BE/API | 응답 JSON/상태코드/쿼리 결과 |
각 항목에는 리포트에서 확인 가능한 메타데이터를 포함한다.
- URL / 환경: local, PR Preview, dev, production 등
- viewport:
390×844, 1440×900 등
- account/role: admin, partner, anonymous 등
- commit/branch 또는 PR 번호
- 실행 액션: reload, click, scroll, filter 조건 등
파일 경로: .context/work/{workspace}/captures/ 안에 저장한다.
⚠️ /tmp/는 사용 금지 — 휘발되고 /archive/Glimpse 프리뷰 탐색 대상이 아니다.
파일명: kebab-case {항목번호}-{설명}.{png|gif|json|txt}
UI 캡처 계획은 primary/supporting과 before/after 여부를 분리한다.
| 역할 | 권장 형태 | 리포트 표시 |
|---|
| primary before | 변경 전 기준 상태의 viewport/section/element crop | after와 같은 항목에 나란히 표시 |
| primary after | 변경 후 검증 상태의 viewport/section/element crop | before와 같은 항목에 나란히 표시 |
| primary combined | before/after를 한 이미지 안에 합성한 핵심 비교 crop | role: "primary"로 full-width 단일 카드 표시 |
| supporting context | full-page, 긴 스크롤 캡처, raw debug screenshot | 토글/details/appendix/link 뒤에 표시 |
Before/After는 다음 조건이면 포함한다.
- 기존 UI/동작의 개선·회귀 방지가 핵심인 변경
- 사용자가 “기존 대비”, “전/후”, “깨짐/복구”, “regression”을 언급한 변경
- responsive/nav/typography처럼 전 상태와 비교할 때 의도가 더 분명해지는 변경
다음 조건이면 생략 가능하지만 사유를 남긴다.
- 완전히 신규 화면/기능이라 의미 있는 before가 없음
- before 환경을 띄우는 비용이 검증 가치보다 큼
- 결제/알림/외부 API처럼 before 재현이 side effect를 만들 수 있음
- 동일 데이터/권한 상태를 맞출 수 없어 비교가 오히려 오해를 부름
세로 1600px 이상 또는 viewport 높이의 2배 이상인 이미지는 primary evidence로 쓰지 말고 crop을 추가한다. verify_report_live HTML은 긴 이미지를 자동으로 접힌 토글에 넣지만, 검증 품질상 primary crop을 별도로 남겨야 한다.
AskUserQuestion으로 계획 확인.
Step 4-B: (옵션) 사전 항목별 확인
--ask-before 모드 또는 사용자가 “사전 확인하자” 요청한 경우, 각 항목 시작 전마다 확인한다.
[V1] dev 스팟상세 GA 이벤트 미발화 — NETWORK + PNG
URL: https://example.local/path
액션: reload → 7초 대기 → scroll → performance resource에서 이벤트명 필터
진행할까요?
옵션: 진행 / 건너뛰기 / 다른 액션으로
Step 5: verify_report_live 시작 → case worker plan/brief 작성
references/capture-commands.md와 references/case-worker-fanout.md를 따른다.
캡처 계획이 확정되면 먼저 live report를 시작한다. 이때 Glimpse가 열리고, 이후 항목별 진행 상태가 SSE로 실시간 갱신된다.
{
"action": "start",
"title": "Verify Report — {ticket-or-branch}",
"ticket": "{ticket}",
"summary": "이번 리포트에서 검증할 성공 기준 요약",
"items": [
{ "id": "V1", "title": "신규 버튼 노출", "type": "UI_CAPTURE", "status": "pending" },
{ "id": "V2", "title": "GA 이벤트 미발화", "type": "NETWORK", "status": "pending" }
]
}
각 항목은 main 또는 worker가 실행을 시작할 때 running으로 갱신한다. main이 명백히 판단할 수 있는 skip/blocked/fail은 바로 기록할 수 있지만, 여러 축 검증의 pass는 Step 5-B case worker 결과를 main이 adjudication하거나 --no-workers 직접 실행 후 Step 6에서 확정한다.
{
"action": "update",
"runId": "{runId}",
"item": {
"id": "V1",
"title": "신규 버튼 노출",
"type": "UI_CAPTURE",
"status": "pass",
"detail": "Preview 환경에서 버튼 노출 확인",
"evidence": [{
"label": "After — mobile 390px",
"kind": "image",
"path": ".context/work/{workspace}/captures/v1-button.png",
"role": "primary",
"relatedItem": "V1",
"purpose": "모바일에서 신규 버튼이 fold 위에 노출되는지 확인",
"inspectFor": ["버튼 위치", "기존 sticky CTA와 겹침 없음"],
"expected": "버튼이 보이고 CTA와 겹치지 않는다",
"observed": "버튼이 title 아래에 보이며 overlap 없음"
}]
}
}
- UI 캡처 증거: primary crop PNG/GIF를 먼저 남기고, full-page는 필요 시 supporting으로 남긴다.
- Before/After 증거: label을
Before — ..., After — ...로 시작하고, detail에 “무엇이 달라져야 하는지 / 달라지면 안 되는지”를 설명한다.
- Raw evidence intent:
purpose에는 수집 이유, inspectFor에는 리뷰어가 봐야 할 포인트, expected에는 닫아야 할 기준, observed에는 실제 관찰, role에는 primary/supporting/raw, relatedItem에는 V1 같은 검증 항목 id를 넣는다. verify_report_live finish는 이 metadata를 captures/evidence-intent.json sidecar로 남겨 /archive raw media preview에서도 재사용한다. 정적 report에서는 JSON/TXT/network/console/diff 같은 raw evidence를 각 검증 item 안의 기본 접힘 토글로 렌더하고, 토글 내부 상단에 intent block을 먼저 보여준 뒤 raw 원문을 둔다. Raw evidence card는 가로 grid에 끼워 반쪽 너비가 되지 않게 full-width 세로 배치한다.
- NETWORK 증거: 필터 조건, matched count, matched request 목록을 JSON/TXT로 남긴다.
- CONSOLE 증거: 콘솔 error/warn/log excerpt를 남긴다.
- CODE_DIFF 증거: 관련 파일/라인과 diff summary를 남긴다.
PASS 처리 조건:
- 성공 기준의 모든 필수 coverage axis가 증거로 닫혔을 때만
pass.
- oracle surface 전체가 같은 subject/role/viewport/action path로 덮였을 때만
pass.
- flow/motion claim은 GIF/짧은 영상 primary evidence가 있어야
pass로 닫는다. 대표 final-state PNG/crop은 supporting으로 함께 둔다.
- 전체 range/list/page/carousel/option/role/downstream 판정이 필요한 claim을 첫 viewport, 첫 row, 대표 1건, final-state 1장만으로 닫지 않는다.
- before/after가 필요한 항목은 after만 캡처하고 PASS로 닫지 않는다. before 생략이 정당하면 detail에 사유를 명시한다.
- 캡처가 있어도 축이 빠졌으면
unverified 또는 별도 Coverage Gap 항목으로 남긴다.
- 자동화/권한/외부 환경 때문에 못 본 항목은
blocked로 남기고 차단 사유를 적는다.
캡처/증거는 “무엇을 실행했는지”와 “결과가 무엇인지”를 재현 가능하게 남긴다. 예: reload + scroll, targetEvents, matchedResourceCount.
Fan-out을 사용할 경우, 실행 전에 .context/work/{workspace}/captures/verify-workers/에 최소 세 가지를 작성한다.
plan.json: 검증 항목, 필수 coverage axis, 기대 결과, 환경(URL/viewport/role), worker별 허용 액션, output path
evidence-index.md: main이 이미 가진 공유 증거와 worker가 만들어야 할 planned evidence 목차. 각 evidence마다 왜/봐야 할 것/기대/관찰/역할/관련 기준을 적는다.
briefs/{itemId}.md: subagent가 읽을 case별 작업 지시. 허용/금지 액션과 result JSON path를 명시
큰 이미지/영상은 복사하지 말고 기존 .context/work/{workspace}/captures/ 경로를 참조한다. Worker가 새로 만드는 evidence도 이 capture root 아래에 저장하게 한다.
Step 5-B: case worker fan-out (기본, --no-workers면 skip)
references/case-worker-fanout.md를 따른다.
기본적으로 main은 case별 worker subagent를 병렬 실행해 planned capture/log/test/API-read와 1차 검증을 맡긴다. 단, 다음 경우에는 fan-out을 생략하고 main이 직접 실행·판정한다.
- 사용자가
--no-workers를 지정함
- 검증 항목이 1개이고 실행 플로우가 짧고 자명함
- subagent 도구가 현재 환경에서 사용할 수 없음
- 계정/session/evidence를 별도 subagent session으로 넘기면 안 됨
- 결제/알림/외부 write처럼 worker가 실수하면 side effect가 생기는 플로우
Subagent 규칙:
- brief에 적힌 URL/viewport/role/action/output path 안에서 planned evidence를 직접 만든다.
- 계획 밖 새 캡처/재캡처, 다른 계정/다른 route/다른 viewport 추가, DB/API write,
verify_report_live update는 하지 않는다.
- 사용자에게 직접 질문하지 않는다. 계획된 evidence가 부족하거나 새 캡처가 필요하다고 판단하면
UNVERIFIED와 main_action_required를 반환한다.
- 출력은 result JSON 파일과 함께
PASS / FAIL / UNVERIFIED, 생성/사용한 evidence path 목록이어야 한다.
메인 규칙:
- subagent 결과를 그대로 믿지 않는다. result JSON과 evidence path가 존재하고 criteria를 실제로 닫는지 확인한 뒤 최종 판정한다.
UNVERIFIED는 main으로 escalation된 작업이다. main이 추가 증거 수집, brief 수정 후 재위임, 기준 재해석, 사용자 질문, Coverage Gap 기록 중 하나로 처리한다.
- 추가 증거가 필요하면 main이 직접 처리하거나, 계획을 명시적으로 갱신한 뒤 해당 case만 다시 worker에 맡긴다.
Subagent launch가 필요한 경우, 현재 Pi subagent 규칙에 따라 먼저 subagent help를 확인하고, subagent batch launch 후에는 status/detail polling을 하지 말고 완료 follow-up을 기다린다.
Step 6: main 결과 adjudication → live preview 갱신 → 정적 HTML export → 유저 리뷰
모든 case worker 결과를 main이 adjudication한 뒤 verify_report_live action=update로 각 항목의 최종 상태와 evidence를 반영한다. 구현 완료 검증 목적이면 fail 항목이 하나라도 있는 상태에서 verify_report_live action=finish를 호출해 정적 HTML을 export하지 않는다. 먼저 구현 수정 → 재배포/재실행 → 재검증으로 돌아간다. 실패 재현/분석 자체가 사용자 요청인 경우에만 reportPurpose: "failure-analysis" 또는 allowFailingReport: true를 명시해 실패 리포트 export를 허용한다.
finish 전에 결과를 네 그룹으로 분리한다. 상단은 PM-facing 캡처 검증이고, 로직/API/DB/code diff는 하단 기술 보조 검증으로 내린다. verify_report_live finish는 구현 검증 report에 fail 항목이 있으면 export를 차단하고, 허용 가능한 경우에는 report lint도 실행해 motion claim의 GIF 누락, GIF+PNG pairing 누락, setup noise PASS item, primary tall image, evidence metadata 누락을 Report Lint 섹션과 tool details에 경고로 남긴다. 경고는 PASS를 자동으로 뒤집지는 않지만, motion claim의 GIF 누락처럼 PM-facing 이해를 깨는 항목은 Coverage Gap 후보로 보고 보완하거나 unverified 처리한다.
Verified — PM-facing behavior
- 기획 근거와 매핑된 사용자-facing 동작이 캡처/GIF로 닫힌 항목
Coverage gaps / Unverified
- 필요한 축이 빠진 항목
- 캡처는 있지만 검증 기준을 닫지 못한 항목
- case worker가 `UNVERIFIED`로 올렸고 main이 추가 증거/질문/보완 없이 닫지 못한 항목
Technical support checks
- API/DB/code diff/unit test처럼 화면 증거를 보조하는 하단 근거
- 비가시 정책 자체가 요구사항인 경우의 BE/NETWORK/CODE_DIFF 근거
Blocked / Known unrelated failures
- 권한/외부 환경/기존 실패로 막힌 항목
- setup noise는 검증을 실제로 막은 경우에만 여기에 짧게 기록
{
"action": "finish",
"runId": "{runId}",
"finalSummary": "PASS/SKIP/미검증 및 주의사항 요약"
}
재오픈/수동 오픈:
/archive .context/work/{workspace}/captures/report.html
/archive 목록에서 선택
/archive --browser .context/work/{workspace}/captures/report.html 브라우저 fallback
액션 처리:
- 로컬 프리뷰 확인만 한 경우: confirm 모드 완료. 업로드하지 않는다.
- 사용자가 업로드를 명시한 경우: Step 7(upload)로 진행한다.
- 보완이 필요한 경우: 필요한 항목을 재검증하거나 update 모드로 보완한다.
- live/Glimpse 실행 실패: 정적 HTML export 후 시스템 브라우저 fallback을 안내하고 업로드하지 않는다.
update 모드: 기존 run이 있으면 같은 runId에 항목을 append/update한다. 없으면 새 start 후 기존 report.html 내용을 참고해 필요한 항목만 보완한다.
Step 7: project artifact storage 업로드 (upload 모드만)
references/upload-scripts.md를 따른다.
기본 confirm 모드에서는 이 단계를 스킵한다. 사용자가 /verify-report --upload를 명시하거나 리포트 확인 후 업로드를 직접 요청한 경우에만 진행한다.
Step 8: context.md + PR 본문 업데이트 (upload 모드만)
references/report-templates.md를 따른다.
context.md ## Report에는 검증 기준 커밋, 증거 링크, PASS/SKIP/미검증을 기록한다.
- PR 본문
## 스크린샷 / 영상에는 업로드된 HTML 리포트와 핵심 증거만 요약한다.
- confirm 모드에서는 PR/context를 수정하지 않는다.
Step 9: 후속 단계
{
"questions": [{
"question": "검증 리포트 생성 완료. 다음 단계를 선택해주세요.",
"options": [
"/create-pr — PR 생성 (upload된 리포트가 있으면 포함)",
"/reflect — 학습 캡처",
"/verify-report --upload — project artifact storage 업로드",
"/verify-report --update — 추가 검증 항목 처리",
"일단 멈춤"
]
}]
}
자주 마주치는 케이스
| 케이스 | 해결 |
|---|
| 기획 근거가 있는 UI 검증 | 근거 출처 → PM-readable 성공 기준 → 실제 화면 캡처/GIF를 같은 item에 매핑한다. |
| 화면 변화가 있는 검증 | PNG/GIF 캡처를 primary evidence로 남긴다. code/test/DB는 하단 보조 근거다. |
| 이동/전환/클릭/열림/닫힘/스무스함 검증 | GIF/짧은 영상을 primary로 두고, 대표 PNG/crop을 supporting으로 함께 둔다. 최종 PNG만으로 PASS 처리하지 않는다. |
| responsive/layout 변경 | mobile + breakpoint boundary + desktop 축을 모두 계획하고, 누락 시 Coverage Gap으로 남긴다. |
| 기존 대비 변경이 중요한 UI | before + after를 같은 viewport/role/action으로 캡처하고 차이를 설명한다. |
| 긴 full-page 캡처 | primary evidence로 쓰지 않는다. crop/section 이미지를 본문에 두고 full-page는 토글/appendix/link로 둔다. |
| 화면 변화가 없는 검증 | UI 캡처로 억지 증명하지 말고 NETWORK/CONSOLE/CODE_DIFF 증거로 남기되, PM-facing 섹션이 아니라 하단 기술 보조 검증으로 둔다. |
| GA/픽셀 미발화 검증 | targetEvents, 필터 조건, matched count, matched requests를 JSON으로 저장한다. |
| 사용자가 “BE는 빼” | BE/CODE_DIFF 항목을 SKIP 표시하고 사유를 남긴다. |
| 사용자가 “추가로 X도 확인” | update 모드로 기존 리포트에 항목 append. |
| 사용자가 “그 리포트에 교체/업데이트” | 새 리포트를 만들지 말고 기존 captures/report.html의 같은 item을 update/replace한다. archive copy는 자동으로 생겨도 workspace report는 같은 검증 artifact로 유지한다. |
| 로그인/빌드/env/부트스트랩 삽질이 있었음 | 핵심 검증 target이 아니면 report item에서 제외한다. 필요한 경우 내부 setup note나 blocked 사유에만 짧게 남긴다. |
구현 검증 중 fail 항목 발생 | 정적 report export로 마무리하지 않는다. 구현 수정 → 재검증으로 돌아가고, 실패 재현/분석 목적일 때만 명시적으로 failure report를 허용한다. |
subagent가 UNVERIFIED 반환 | main이 추가 evidence 수집/brief 수정 후 재위임/사용자 질문/Coverage Gap 중 하나로 처리한다. subagent가 계획 밖 새 캡처·질문을 하지 않는다. |
| 사용자가 “업로드는 나중에” | confirm 모드로 종료하고 /verify-report --upload 안내. |
| Glimpse 창이 안 뜸/닫힘 | 업로드하지 않고 /archive --browser report.html 또는 open report.html fallback 안내. |