3. 게이트 먼저
시작 상태
섹션 제목: “시작 상태”ls docs/plans/*-charcount.md && git status --short두 번째 명령은 아무것도 찍히지 않아야 합니다. 1단계에서 스캐폴딩과 스펙·기록표를, 2단계에서 계획을 각각 커밋해 두었기 때문입니다. 계획 파일이 없거나 트리가 깨끗하지 않으면 2. 계획을 파일로로 돌아갑니다.
이 단계에서 하는 것
섹션 제목: “이 단계에서 하는 것”의존성을 설치하고, 게이트 설정은 Prompt 2번 틀로 시킵니다. 게이트마다 일부러 어긋나게 해서 실패를 먼저 봅니다. 실패를 먼저 보는 이유는 Lint와 Build가 다룹니다.
따라하기
섹션 제목: “따라하기”- 템플릿 의존성과 게이트용 개발 의존성을 설치합니다.
npm installnpm install --save-dev vitest jsdom eslint @eslint/js typescript-eslint @playwright/testnpx playwright install chromium- worktree 디렉터리와 Playwright 산출물을 먼저 무시합니다. worktree는 7단계에서
필요합니다. Playwright는 실행마다
test-results/를 다시 쓰므로, 무시하지 않으면 뒤 단계의git add -A가 이 파일을 커밋하고 다음 시작 상태의 깨끗한 트리 요구를 흔듭니다. 첫 줄은 나의 기본 세팅의 것과 같습니다. Vite 템플릿의.gitignore가 이미 있으므로 덧붙입니다.
printf '\n.claude/worktrees/\ntest-results/\nplaywright-report/\n' >> .gitignoregit check-ignore -v .claude/worktrees/ test-results/두 경로 모두 .gitignore의 규칙과 함께 출력되어야 합니다.
- 게이트 설정 프롬프트(2번 틀):
lint, 단위 테스트, 빌드, e2e 네 가지 게이트를 설정해 주세요.
완료 기준: npm run lint, npm test, npm run build, npm run e2e 네 명령이 모두 exit 0."동작하게"로 쓰지 않습니다.범위: 포함 — eslint flat config(@eslint/js + typescript-eslint), vitest(environment jsdom, exclude에 **/.claude/worktrees/** 와 **/e2e/** 포함), playwright(testDir e2e, webServer로 npm run dev), package.json scripts, jsdom 환경과 HTTP 문서 응답을 확인하는 최소 smoke test 각 하나.제외 — 앱 기능 구현과 기능 테스트. smoke test는 유지하고 테스트가 없을 때 통과시키는 옵션은 쓰지 않습니다.구현 전에 만들 파일과 고칠 파일 목록을 먼저 보여 주세요.각 게이트를 설정한 뒤에는 일부러 어긋난 파일을 하나 만들어 그 게이트가 exit 0이 아닌값을 내는 것을 보여 주고, 그 파일을 지운 뒤 exit 0을 다시 보여 주세요.- 모델이 보여 준 실패와 복원 후 초록을 믿지 말고 직접 한 번 더 합니다. smoke test는 남긴 상태에서 다음 네 실패와 복원 후 성공을 확인합니다.
echo 'export const unused = 1; const dead = 2;' > src/dead.ts && npm run lint; echo "lint exit=$?"; rm src/dead.tsecho 'import { test, expect } from "vitest"; test("red", () => { expect(1).toBe(2); });' > src/red.test.ts && npm test; echo "test exit=$?"; rm src/red.test.tsecho 'const broken: number = "not a number"; export { broken };' > src/build-red.tsnpm run build; echo "build exit=$?"rm src/build-red.tsecho 'import { test, expect } from "@playwright/test"; test("red", async ({ page }) => { await page.goto("/"); await expect(page.locator("#nope")).toBeVisible({ timeout: 1000 }); });' > e2e/red.spec.tsnpm run e2e; echo "e2e exit=$?"rm e2e/red.spec.tsnpm run lint && npm test && npm run build && npm run e2e; echo "green exit=$?"네 실패 모두 exit 0이 아닌 값을 냅니다. 모델이 생성한 설정이 대략 다음 형태입니다. 프롬프트가 다른 형태를 내면 이 형태로 맞춰 봅니다.
/// <reference types="vitest/config" />import { defineConfig } from 'vite';
export default defineConfig({ test: { environment: 'jsdom', exclude: ['**/node_modules/**', '**/.claude/worktrees/**', '**/e2e/**'], },});import js from '@eslint/js';import tseslint from 'typescript-eslint';
export default tseslint.config( { ignores: ['dist/**', 'node_modules/**', '.claude/**', 'playwright-report/**', 'test-results/**'] }, js.configs.recommended, ...tseslint.configs.recommended,);import { defineConfig } from '@playwright/test';
export default defineConfig({ testDir: './e2e', use: { baseURL: 'http://localhost:5173', viewport: { width: 1280, height: 720 } }, webServer: { command: 'npm run dev', url: 'http://localhost:5173', reuseExistingServer: true },});"scripts": { "lint": "eslint .", "test": "vitest run", "e2e": "playwright test"}- 프로젝트
CLAUDE.md를 만듭니다. 검증 명령을 적어 두면 이후 세션이 “완료”라고 말하기 전에 무엇을 돌릴지 압니다. 이 규칙이 강제가 아니라 조언이라는 점은 CLAUDE.md 실전 가이드가 다룹니다. 6단계에서 그 규칙이 지켜지지 않는 경우를 겪습니다.
# charcount
- 변경을 마치면 npm run lint && npm test && npm run build 를 실행하고 출력을 보여준다- 화면 변경은 npm run e2e 도 실행한다- 글자 수 계산은 src/countChars.ts 의 순수 함수 하나에만 둔다- push는 사람이 한다. 커밋까지만 한다-
끝 비용과 컨텍스트 사용률을 읽어
docs/tutorial-log.md의 “3. 게이트” 행에 적습니다. 메모 열에는 “모델이 보여 준 실패를 직접 재현했는가”를 적습니다. -
네 게이트가 초록이면 기록표까지 함께 커밋하고 이후 리뷰의 기준점을 보존합니다.
git add -A가 기록표를 함께 담습니다.
git add -A && git commit -m "chore: 게이트 설정"git tag tutorial-gatesgit rev-parse tutorial-gates이 태그는 8단계 리뷰의 기준점입니다. 이후 단계에서 옮기지 않습니다. 태그가 이미 있다면 덮어쓰지 말고 올바른 3단계 완료 커밋을 가리키는지 확인합니다.
완료 확인
섹션 제목: “완료 확인”npm run lint && npm test && npm run build && npm run e2e; echo "green exit=$?"green exit=0이어야 합니다. 그리고 4번에서 본 네 실패는 exit 0이 아닌 값이었습니다.
계측 기록
섹션 제목: “계측 기록”값은 6번에서 이미 적었습니다. 시작 상태를 확인한 직후 시작 비용을, 커밋 직전에 끝 비용과
컨텍스트 사용률을 각각 적고 차액으로 읽습니다. 세션 수는 이 단계에서 연 세션 개수입니다.
기록표를 커밋한 뒤 /clear해 4단계를 새 세션으로 시작합니다.
어긋났을 때
섹션 제목: “어긋났을 때”새 게이트가 처음부터 초록이면 그 게이트가 아무것도 검사하지 않는지 의심합니다. 판정
기준은 검사는 통과하는데 실제로는 깨져 있을 때에
있습니다. npm test가 테스트 파일이 없다고 실패하면 smoke test 파일 경로와 vitest의 수집
설정을 확인합니다. .claude/ 전체를 무시하면 안 됩니다. 이유는
나의 기본 세팅에 있습니다.