7. 병렬 작업
시작 상태
섹션 제목: “시작 상태”git status --short && git check-ignore -v .claude/worktrees/echo '{"tool_name":"Bash","tool_input":{"command":"git push origin main"}}' | sh hooks/block-push.sh; echo "exit=$?"6단계 커밋 이후여야 합니다. 첫 줄은 아무것도 찍히지 않아야 하고, 두 번째 줄에 무시 규칙이
나와야 하며, 마지막 줄은 exit=2여야 합니다. 무시 규칙이 비어 있으면
3. 게이트 먼저로 돌아가 .gitignore에 .claude/worktrees/를
추가합니다. exit=2가 아니면 6. 규칙을 강제로로 돌아갑니다.
터미널에서 claude agents에 들어가고 나올 수 있어야 합니다. 안 되면
준비: 활용 팁의 에이전트 뷰 절을 확인합니다.
이 단계에서 하는 것
섹션 제목: “이 단계에서 하는 것”공백 제외 옵션과 남은 글자 수 표시는 서로 무관한 기능입니다. 이 둘을 worktree 두 개에서 동시에 만듭니다. 하나는 포그라운드 세션이 맡고 하나는 백그라운드 세션이 맡습니다. 진행은 준비: 활용 팁에서 사용해 본 에이전트 뷰에서 지켜봅니다. worktree를 열기 전에 누가 언제 무엇으로 머지하는지부터 정합니다. worktree를 언제 열고 어떻게 정리하는지의 판단은 Worktrees가 다룹니다.
따라하기
섹션 제목: “따라하기”- 분기하기 전에 main에서 이번 기능의 계약을 스펙에 추가합니다. 프롬프트로 시킵니다.
<날짜>는 실제 스펙 파일 이름으로 바꿉니다.
docs/specs/<날짜>-charcount.md 에 "공백 제외 옵션" 절을 추가해 주세요.옵션 off(기본)는 공백과 줄바꿈을 포함해 셉니다. on이면 정규식 /\s/gu 로 공백 문자를 제거한 뒤같은 글자 단위 정의로 셉니다. 스펙 파일만 수정하고 코드는 건드리지 마세요.1단계에서 공백 제외를 기본으로 골랐다면 지금 스펙과 테스트를 공백 포함 기본으로 맞춥니다. 게이트를 통과시킨 뒤 커밋하고, 이 시점의 커밋 해시를 적어 두어 A와 B가 같은 커밋에서 시작하게 합니다.
npm run lint && npm test && npm run buildgit add docs/specs && git commit -m "docs: 공백 옵션 계약"git rev-parse HEAD머지 방법도 지금 정합니다. 이 튜토리얼은 “각 worktree에서 커밋까지 하고, 머지는
main에서 사람이 git merge로 한다”를 씁니다. squash나 PR 같은 다른 방법도 가능하지만,
worktree를 열기 전에 하나를 고릅니다.
- 기능 A를 포그라운드 세션에 맡깁니다.
새 worktree를 만들어 그 안에서 작업해 주세요.src/countChars.ts 와 src/countChars.test.ts 만 변경해 주세요.countChars(text: string, options?: { excludeWhitespace?: boolean }): number 로 확장합니다.excludeWhitespace 기본값은 false이며 기존 스펙의 세기 정의를 보존합니다.true이면 정규식 /\s/gu로 공백 문자를 제거한 뒤 같은 글자 정의로 셉니다. 테스트를 먼저 써 주세요.UI, CSS, main.ts, package.json과 lockfile은 수정하지 마세요. npm ci로 의존성을 설치하세요.완료 기준: npm run lint && npm test && npm run build 가 exit 0.끝나면 커밋하고, worktree는 유지한 채로(keep) 빠져나와 주세요. 머지는 제가 합니다.- 기능 B는 백그라운드 세션에 맡깁니다. 별도 터미널을 열어 같은 charcount 디렉터리로 이동한 뒤 실행합니다.
claude --bg "새 worktree를 만들고 npm ci로 설치해 주세요. src/remaining.ts와 src/remaining.test.ts만 만드세요. remainingChars(count: number, limit = 140): number는 limit - count를 반환하며 음수도 유지합니다. 139/140/141 입력의 결과 1/0/-1을 테스트 먼저 확인하세요. UI, CSS, main.ts, countChars, package.json과 lockfile은 수정하지 마세요. 완료 기준: npm run lint && npm test && npm run build 가 exit 0. 커밋 후 worktree를 유지한 채로 빠져나와 주세요."claude agentsA가 실행 중일 때 별도 터미널에서 B를 시작합니다. 두 세션 모두 1번에서 적어 둔 같은
커밋에서 출발해야 합니다. 에이전트 뷰에서 B의 진행을 지켜보다가 질문이 오면
attach해서 답합니다. 쓰는 환경에 --bg가 없으면 두 번째 포그라운드 터미널을 열어
같은 B 프롬프트를 그대로 실행합니다.
- 머지 전 기준선을 남깁니다.
npm test 2>&1 | tail -3git worktree list테스트 개수를 적어 둡니다. git worktree list 출력에서 A와 B 각각의 브랜치 이름도
함께 확인합니다. A와 B 세션을 닫기 전에 각 세션의 끝 비용과 컨텍스트 사용률을 읽어
둡니다. 세션을 닫은 뒤에는 그 값을 다시 읽을 수 없습니다.
- 머지합니다.
git merge <A 브랜치> && git merge --no-edit <B 브랜치>npm run lint && npm test && npm run buildnpm test 2>&1 | tail -3두 번째 머지는 fast-forward가 아니어서 머지 커밋이 생깁니다. --no-edit은 메시지
편집기를 열지 않고 기본 메시지로 커밋합니다. 테스트 개수가 A와 B가 각각 추가한
만큼만 늘었는지 봅니다. 그보다 많이 늘었다면
worktree 안에 남아 있던 테스트 사본이 함께 수집되고 있다는 뜻입니다. 3단계에서 등록한
vitest exclude를 확인합니다. 원인은
병렬 작업이 막힐 때가 다룹니다.
- UI 통합은 main에서 한 세션이 맡습니다.
머지된 countChars와 remainingChars를 main에서 연결해 주세요.공백 제외 체크박스와 data-testid="remaining" 요소를 추가하고 count 요소는 보존하세요.체크박스와 textarea의 변경마다 countChars(text, { excludeWhitespace: checkbox.checked })를한 번 계산해 count와 remainingChars(count) 표시 양쪽에 사용하세요.remaining이 음수일 때만 초과 색을 적용하세요. 함수의 계산을 UI에서 재구현하지 마세요.139/140/141자에서 두 표시가 139/1, 140/0, 141/-1인지 확인하세요."가 나\n" 입력은 옵션 on이면 2/138, off이면 4/136인지 E2E로 확인하세요.색 상태는 140자와 141자의 경계에서 확인하세요.npm run lint && npm test && npm run build && npm run e2e 출력을 보여 주세요.분기 전에 정한 옵션 계약과 UI 결과가 일치하는지 확인합니다. 커밋 직전에 main 세션의
끝 비용과 컨텍스트 사용률을 읽습니다. 4번에서 읽어 둔 A·B 값과 함께
docs/tutorial-log.md의 “7. 병렬” 행에 세션별로 한 행씩 적습니다. 그다음 통합 코드와
기록표를 함께 커밋합니다.
git add src index.html e2e docs/specs docs/tutorial-log.mdgit commit -m "feat: 공백 옵션과 남은 글자 표시 통합"- worktree를 정리합니다. A와 B 세션은 worktree를 유지한 채 빠져나왔으므로 디렉터리와
브랜치가 남아 있습니다. main에서 git 명령으로 지웁니다. 디렉터리와 브랜치 이름은 4번의
git worktree list출력에서 읽습니다. A와 B 각각에 대해 실행합니다.
git worktree remove .claude/worktrees/<A 디렉터리>git branch -d <A 브랜치>git worktree remove .claude/worktrees/<B 디렉터리>git branch -d <B 브랜치>git worktree listmain 하나만 남아야 합니다. git worktree remove가 잠겨 있다고 거부하면 세션이 아직
그 worktree를 쓰고 있다는 뜻입니다. 세션을 먼저 끝내고 다시 실행합니다.
완료 확인
섹션 제목: “완료 확인”npm run lint && npm test && npm run build && npm run e2e; echo "green exit=$?"git worktree listgrep -n 'data-testid="remaining"' index.html src/*.tsgreen exit=0이고, git worktree list에 main만 남고, data-testid="remaining"이 한 곳에
있어야 합니다. 옵션 on/off와 제한 경계를 조합한 케이스들이 4번과 6번에서 이미 통과했어야
합니다.
계측 기록
섹션 제목: “계측 기록”값은 4번과 6번에서 이미 적었습니다. “7. 병렬” 행은 main·A·B 세션별로 한 행씩입니다. 시작 상태를 확인한 직후 시작 비용을, 커밋 직전에 끝 비용과 컨텍스트 사용률을 각각 적고 차액으로 읽습니다. 세션 수는 이 단계에서 연 세션 개수입니다. 재시작한 세션이 있으면 행을 추가하고, 세 세션으로 고정해서 세지 않습니다. A 세션이 6번 통합까지 그대로 이어갔다면 A 행의 끝 값이 main 행의 시작 값입니다. 에이전트 뷰에서 B 세션의 컨텍스트 사용률을 읽을 수 있으면 메모 열에 적습니다.
어긋났을 때
섹션 제목: “어긋났을 때”- 백그라운드 세션이 첫 편집을 거부하면 처음부터 worktree 안에서 시작하지 않았다는 뜻입니다. 병렬 작업이 막힐 때를 확인합니다.
- 머지 후 테스트 개수가 예상보다 많으면 같은 페이지의 “테스트 러너가 worktree 안의 테스트도 함께 수집합니다”를 확인합니다.
- main이 항상 dirty로 보이면
.gitignore에.claude/worktrees/가 있는지 확인합니다. Worktrees가 이 함정을 다룹니다.