Communitygithub.com

genekogan/proof

T2+ 변경 사항에 필요한 증명 클립을 녹화합니다. 하나의 편집되지 않은, 실제 속도의 Playwright 비디오로, 로컬 페이크-마인드 세계에서 변경된 사용자 여정을 보여주며, 스크러브 바와 타임코드가 포함됩니다. 데스크톱과 (레이아웃이 변경된 경우) 모바일 버전을 녹화한 후, PR에 첨부하되 비디오를 저장소에 커밋하지 않습니다.

proof란 무엇인가요?

**proof**는 T2 이상의 변경 사항에 대해 사용자 여정을 하나의 연속된 실제 속도 비디오로 녹화하는 AI 에이전트 스킬입니다. 이 스킬은 검토자가 변경 사항을 실제 사용자가 보는 것처럼 정상 속도로 처음부터 끝까지 볼 수 있도록 합니다. 주로 로컬 '페이크-마인드' 세계에서 Playwright를 사용하여 데스크톱과 (레이아웃이 변경된 경우) 모바일 화면을 녹화하며, 편집, 속도 조절, 트리밍이 금지됩니다. 녹화된 클립은 저장소에 커밋되지 않고 GitHub 릴리스를 통해 PR에 첨부되며, 미리보기 GIF도 함께 제공됩니다. Cursor, Claude Code, Codex와 같은 AI 코딩 에이전트가 PR 생성 및 검토 과정에서 증거 자료를 자동으로 생성하고 첨부할 수 있도록 지원합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/genekogan/souls/tree/HEAD/.claude/skills/proof

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

미리보기

스킬 README에서

desktop.mp4

문서

proof — 변경된 여정의 편집되지 않은 클립

검토자는 사용자가 보는 것을 정상 속도로 처음부터 끝까지 볼 수 있어야 합니다. 클립이 증거이며, 스크린샷, 연락처 시트 또는 빨리 감기 녹화는 증거가 아닙니다.

티어에 필요한 사항의 출처: docs/process/PROOF-POLICY.yml (T0 없음; T1 집중 테스트 + 타입체크; T2는 변경된 여정의 클립 하나 추가, 데스크톱 및 레이아웃이 변경된 경우 모바일, 페이크-마인드 세계에서; T3/T4는 더 추가). 현재 diff의 티어는 node tools/proof/tier.mjs --base origin/main으로 확인합니다.

규칙

  • 편집되지 않음 및 실제 속도. 하나의 브라우저 컨텍스트, 한 번의 테이크. 절대 트리밍, 접합, 속도 증가 또는 감소하지 마십시오. 여정이 정책의 max_seconds보다 길면 변경 사항을 여전히 보여주는 더 짧은 여정을 녹화하되, 더 빠른 여정은 안 됩니다.
  • 테이크는 도착 시점에 시작 (기본값): 세계가 화면에 나타나고 도착 카드가 사라진 후에 녹화가 시작되므로, 클립은 로딩이 아닌 세계에서 시작됩니다. 그 이후로 정책이 요구하는 대로 하나의 편집되지 않은 실제 속도 테이크입니다. 로딩 또는 도착 자체가 변경 사항인 경우(도착 카드, 로딩 화면, 첫 페인트), 또는 여정이 세계 페이지가 아닌 경우(세계 목록, 로그인) --from-load를 전달합니다. 그러면 테이크가 페이지 생성 시점에 시작됩니다. 사이드카의 start (arrival 또는 load)는 어떤 것이 사용되었는지 나타내며, upload.mjs --proof는 이를 proof.json media[]에 복사합니다.
  • 낮 시간에. 로컬 세계 URL에서 레코더는 페이지가 열리기 전에 세계를 정오로 설정하고 시계를 일시 중지합니다 (--time-of-day 12, 기본값; 신 모드 라우트는 dev 소유자로). 개발 세계는 06:00에 부팅되며 실제 시간당 하루를 실행하므로, 40분 동안 켜져 있는 세계는 밤입니다. 설정하는 것은 세계의 신 기록에 하나의 world 항목이며, 이후 시계는 일시 중지된 상태로 유지됩니다. 다른 시간을 전달하거나, 시계, 조명 또는 신 기록 자체가 변경 사항인 경우 --time-of-day keep을 전달합니다. 사이드카의 worldTime은 설정된 값을 나타냅니다.
  • 실제 입력. 사용자가 하는 방식대로 page.mouse, page.keyboard, page.touchscreen 또는 로케이터 클릭으로 구동합니다. 카메라에서 이벤트를 발생시키기 위해 page.evaluate로 앱 내부를 호출하지 마십시오.
  • 페이크 마인드, 격리된 데이터. 로컬 세계만, BRAIN_MODE=fake, 새로운 데이터 디렉토리. 유지관리자가 요청하지 않는 한 프로덕션 세계에 대해 녹화하지 말고, 개인 브라우저 프로필에 로그인하여 녹화하지 마십시오.
  • 비디오(또는 프레임)를 저장소에 커밋하지 마십시오. .e2e/ (gitignored)에서 작업합니다.
  • 클립은 변경 사항을 보여주어야 합니다. 첨부하기 전에 시청하십시오(또는 최소한 프레임 추출, 아래 참조).

1. 페이크-마인드 세계 부팅

빌드된 웹 클라이언트 필요 (pnpm install --frozen-lockfile && pnpm build; 변경 사항에 대해 apps/web/dist/index.html이 존재하고 최신이면 건너뜁니다). 새 클론에서 빌드의 사전 빌드 검사는 웹 미디어가 준비될 때까지 실패합니다: node tools/assets/pull.mjs --only 'apps/web/**' (몇 개의 파일)로 충분합니다.

node tools/god-skill/dev-world.mjs proof 4710 --genesis worlds/templates/hello-hamlet.json --fresh --data .local/proof
# http://127.0.0.1:4710/w/proof?dev=1 출력 (pid N, 로그 .lane/proof.log); 서버는 분리된 상태로 계속 실행됩니다

홈페이지(세계 목록, 새 세계)는 단일 세계가 아닌 세계 런처가 제공합니다. 거기서 시작하는 여정의 경우, 런처(항상 페이크 마인드를 얻는 세계)를 실행하고 API를 통해 목록을 위한 세계를 만드십시오:

node tools/world-launcher/launcher.mjs --port 4720 --range 4721-4723 --data "$PWD/.local/proof-launcher" --eager 0 &
curl -s -X POST -H 'content-type: application/json' -H 'authorization: Bearer dev:proof' \
  -d '{"name":"Proof Garden","template":"hello-hamlet"}' http://127.0.0.1:4720/__sim/worlds
# http://127.0.0.1:4720/ 에 대해 녹화; pid로 런처 중지 (런처는 세계를 중지합니다)

변경된 표면을 포함하는 템플릿 선택 (worlds/templates/: hello-hamlet은 작고 빠름; eden-2026, mars-two 등은 더 큼). 사용 가능한 포트 사용; e2e/config.mjs는 다른 하네스를 위해 예약된 포트를 나열합니다. 완료되면 kill <pid>로 서버를 중지합니다.

앱 작동 확인: 로컬 스모크

녹화 전에, 또는 서버나 웹 앱을 변경하는 T1 변경의 전체 증명으로, 로컬 스모크를 실행합니다. 자체 격리된 런처(페이크 마인드, 개발 로그인, 실행 디렉토리 아래 데이터)를 사용 가능한 포트에서 부팅하고, 세계 목록과 하나의 세계를 열고, 사람이 그려지고 콘솔 오류 및 실패한 요청이 없는지 확인한 다음 시작한 것을 중지합니다:

node e2e/local-smoke.mjs --port 9950 --clip      # 새 클론에서는 --build 먼저; 사용 가능한 포트는 --port 생략
# → .local/e2e/<타임스탬프>/summary.json, shots/1-world-list.png 2-world.png 3-person.png, clip.mp4
node tools/proof/upload.mjs --pr $N .local/e2e/<타임스탬프>/summary.json .local/e2e/<타임스탬프>/shots/*.png

summary.json의 status: "pass"가 증거입니다. 해당 클립은 스모크 여정의 하나의 편집되지 않은 실제 속도 테이크입니다. 변경 사항의 클립이 아닙니다: T2 변경은 여전히 아래 자체 여정을 녹화합니다. 세부 사항: docs/testing/e2e.md#local-smoke.

2. 단계 작성

.claude/skills/proof/steps.example.mjs를 .e2e/proof/<slug>/steps.mjs에 복사하고 변경된 여정을 스크립팅합니다: 작업을 수행하고 결과를 보여줍니다. 기본 도착 시작으로 단계는 도착한 세계에서 시작합니다(arrived 마크는 0:00); --from-load를 사용하면 탐색 직후에 시작합니다. mark('label')은 사이드카에 챕터 시간을 스탬프하여 PR에서 "패널이 0:07에 열립니다"라고 말할 수 있도록 합니다. 변경 사항이 영향을 미치는 여정으로 유지하십시오.

3. 녹화

node .claude/skills/proof/record.mjs --url 'http://127.0.0.1:4710/w/proof?dev=1' \
  --steps .e2e/proof/<slug>/steps.mjs --out .e2e/proof/<slug>/desktop.mp4 --viewport desktop
# 레이아웃 또는 터치가 변경되었습니까? 또한:
node .claude/skills/proof/record.mjs --url '...' --steps .e2e/proof/<slug>/steps.mjs \
  --out .e2e/proof/<slug>/phone.mp4 --viewport phone
  • 브라우저: PLAYWRIGHT_BROWSERS_PATH 사용, 그렇지 않으면 /opt/pw-browsers (존재하는 경우). Chromium이 없는 경우: PLAYWRIGHT_BROWSERS_PATH="$PWD/.e2e/browsers" pnpm --filter mars-campus-viewer exec playwright install chromium.
  • Playwright는 플레이테스트 하네스와 동일한 방식으로 확인됩니다 (tools/playtest/lib/platform.mjs: 전역 playwright, 그렇지 않으면 mars/viewer의 @playwright/test). GPU 필요 없음; WebGL은 SwiftShader에서 실행됩니다.
  • --max-seconds는 정책의 max_seconds를 기본값으로 합니다. 종료 코드 3은 여정이 이를 초과했음을 의미합니다: 단축하십시오.
  • ffmpeg 사용: 하단에 진행 막대가 있고 hh:mm:ss / total 타임코드가 있는 mp4 (타임코드는 drawtext로 빌드된 ffmpeg 필요; 사이드카의 timecode는 존재 여부를 나타냄). ffmpeg 없음: 원시 .webm; PR에 그렇게 명시하십시오 (플레이어는 여전히 자체 스크러브 바를 표시).
  • 각 클립에는 <클립>.json 사이드카가 있습니다: url, viewport, duration, start, startedAt, 마크 (arrived 포함), worldTime, 콘솔 오류, 커밋 및 더티 플래그. page.screencast가 없는 Playwright는 --from-load 없이도 페이지 생성 시점부터 녹화합니다. 사이드카는 startFallback에서 이를 명시합니다.
  • 페이지는 테이크가 시작되기 전에 도착할 시간 --arrival-seconds (기본값 120)를 가집니다; 세계를 표시하지 않는 페이지는 --from-load 사용 힌트, 중단된 위치의 스틸 이미지 (<clip>.open-failed.png) 및 사이드카와 함께 실패합니다 (종료 코드 1). 사이드카의 콘솔 오류는 발견 사항입니다: 설명하거나 수정하십시오.

실행은 10분 포그라운드 제한보다 훨씬 짧습니다. 여러 클립을 한 번에 실행하려면 백그라운드에서 실행하십시오 (nohup setsid node ... > .e2e/proof/<slug>/rec.log 2>&1 &) 그리고 로그를 폴링하십시오.

4. 직접 확인

for t in 1 4 8; do ffmpeg -loglevel error -y -ss $t -i .e2e/proof/<slug>/desktop.mp4 -frames:v 1 .e2e/proof/<slug>/t$t.png; done

프레임을 확인하십시오 (PNG 읽기). 변경된 상태가 보여야 하고, 세계가 로드되어야 하며 (빈 캔버스나 로딩 캔버스가 아님), 프레임에 비공개 내용이 없어야 합니다. 변경 사항을 표시하지 않으면 단계를 수정하고 새 테이크를 녹화하십시오; 주장을 증명하지 않는 클립을 첨부하지 마십시오.

5. PR에 첨부 (커밋하지 않음)

게시 전에 모든 나가는 텍스트/JSON 페이로드를 node tools/proof/publication.mjs <페이로드 파일>로 확인하십시오. 미디어 픽셀, 오디오, 파일 이름 및 바이너리 메타데이터를 별도로 검사하십시오. 장치 경로, 호스트 이름, 장치/개인 IP, 로컬 URL 및 운영 식별자는 비공개 레코드에만 속합니다. 상대 경로와 중립 캡처 레이블을 사용하십시오. 업로더는 배치를 업로드하기 전에 감지된 텍스트 누출을 차단합니다. 이는 미디어 개인 정보를 인증할 수 없습니다.

node tools/proof/upload.mjs --pr $N --proof .e2e/journal/$ISSUE/proof.json .e2e/proof/$SLUG/desktop.mp4 .e2e/proof/$SLUG/phone.mp4
  • 기본 대상은 PR 자체의 프리릴리스 proofs-<n>입니다 (기본 브랜치의 태그, 첫 사용 시 생성됨); PR당 하나의 릴리스는 각각을 GitHub의 1000-에셋 제한 아래에 유지하며, 이전 공유 proofs 릴리스가 도달했습니다. --release <tag> (또는 SIM_PROOF_RELEASE)는 다른 릴리스를 지정합니다. 에셋 이름은 pr-<n>.<file>이며, 재테이크는 -2, -3을 얻으므로 실패한 것을 포함한 이전 테이크도 링크 가능합니다. SIM_PROOF_UPLOAD_URL (+ SIM_PROOF_UPLOAD_TOKEN)은 CDN과 같은 다른 엔드포인트로 전환합니다.
  • --proof를 사용하면 클립 및 이미지 링크가 proof.json media[]에 기록되고, 다른 파일(로그, JSON)은 files[]에 기록되며, proof.json이 마지막으로 업로드됩니다. 링크와 클립 링크를 PR의 Proof 섹션에 붙여넣으십시오. journal 스킬은 proof.json을 다룹니다.
  • 인라인 미리보기. GitHub는 릴리스 에셋을 다운로드로 제공하므로 mp4 링크는 PR에서 재생되지 않습니다. 각 비디오에 대해 upload.mjs는 ffmpeg로 작은 애니메이션 GIF를 만듭니다 (<clip>.preview.gif: 클립의 arrived 마크에서 6초 실제 속도, 또는 --from-load 테이크의 경우 0초; 최대 5 MB), 클립 옆에 업로드하고 media[].preview로 기록하며 [![desktop.mp4](...pr-412.desktop.preview.gif)](...pr-412.desktop.mp4)와 같은 줄을 출력합니다. 해당 줄을 붙여넣으십시오: 미리보기가 PR에서 재생되고 클릭하면 전체 클립이 열립니다. 변경 사항이 클립의 나중에 표시되는 경우 --preview-start <s> (및 --preview-seconds <s>)로 창을 선택하십시오. 미리보기는 포인터일 뿐, 증거가 아닙니다: 편집되지 않은 mp4가 증거입니다. 각 미리보기 전에 항상 명시적인 전체 해상도 편집되지 않은 비디오 링크를 넣고 실제 인코딩된 해상도와 지속 시간을 명시하십시오. 캡처 해상도를 유지하고, 접촉을 검토할 수 있도록 액션을 프레임화하십시오. 캡처를 업스케일하거나 축소된 GIF를 사용하여 동작 증명을 주장하지 마십시오.
  • 종료 코드 3: 업로드가 차단됨 (gh 없음, 로그인되지 않음, 권한 없음, 또는 네트워크 없음, 많은 클라우드 세션에서처럼). 사용자에게 어떤 클립이 대기 중이고 어디에 있는지 알리십시오. 각 클립의 지속 시간, 뷰포트, 정리된 사이드카 요약(마크, 콘솔 오류, 커밋) 및 저장소-상대적인 record.mjs 명령과 단계 파일이 포함된 PR 댓글을 게시하여 누구든 다시 녹화할 수 있도록 하십시오. PR 본문에서 증명을 "업로드 보류 중"으로 표시하십시오. 비디오를 base64로 붙여넣거나, 커밋하거나, 다른 브랜치로 푸시하지 마십시오.

gh pr는 클라우드 세션에서 작동하지 않을 수 있습니다. 다음으로 댓글을 달으십시오: gh api repos/$REPO/issues/$N/comments -F [email protected]/proof/$SLUG/comment.md.

클립 옆에 작성할 내용

클립당 한 줄: 어떤 여정, 어떤 세계 템플릿, 뷰포트, 지속 시간, 커밋, 변경 사항이 표시되는 순간 ("0:07 좌석이 강조 표시되고 영혼이 앉습니다"). 또한 콘솔 오류와 허용 가능한 이유를 포함하십시오.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

관련 스킬