1탄 9장
1탄 9장
BUILD.md + 테스트 하네스 + E4 LogOnTable
드디어 코드를 만듭니다 — BUILD.md 생성 + TDD + 결정 과정 보존
📑 이 챕터에서 다룰 내용

새 8장에서 REVIEW.md READY: YES 판정을 받았습니다. 이제 드디어 코드를 만듭니다. 이 장에서 BUILD.md를 처음 만들고, 테스트 하네스를 설치하고, 첫 기능을 TDD로 구현하고, E4 LogOnTable 실황 보존의 첫 등장을 봅니다.

📚 사전 지식 체크🎯 이 장의 목적✅ 완료 후 결과물
새 8장 REVIEW.md READY: YES + git commit BUILD.md 생성 + 테스트 하네스 설치 + Phase 1 첫 기능 TDD 구현 + E4 LogOnTable 패턴 첫 적용 BUILD.md 파일 + 테스트 하네스 + Phase 1 첫 기능 + 첫 LogOnTable 트레이스

5파일 중 BUILD.md가 처음 만들어지는 단계입니다.

SPEC.md (새 5장)PLAN.md (새 6장)REVIEW.md (새 8장)BUILD.md ◀ 지금 여기CLAUDE.md (새 11장)
완성완성완성생성 중미완성
📘 이론적 배경 — 테스트 주도 개발 TDD (켄트 벡, 2003)

켄트 벡의 TDD 원칙: 코드보다 테스트를 먼저 작성합니다. 테스트가 통과하면 그것이 기능 완성의 증거예요.

테스트 하네스(테스트 코드를 자동 실행하고 결과를 보여주는 시스템)가 없으면 TDD를 실천할 수 없습니다. BUILD 첫날 테스트 하네스를 설치하는 이유: 나중에 설치하면 기존 코드에 테스트를 추가하는 것이 훨씬 어렵습니다.

💡 건물의 골조 공사

건물을 지을 때 외관 공사보다 골조(뼈대)를 먼저 세웁니다. 골조 없이 외관을 먼저 만들면 나중에 골조를 넣을 때 외관을 전부 뜯어내야 해요.

테스트 하네스는 코드의 골조입니다. BUILD 시작 전에 설치하면 자연스럽게 TDD로 개발하게 됩니다.

테스트 하네스는 BUILD 첫날 설치합니다. 기능을 하나라도 만들기 전에.

📘 표준 도구와의 매핑
도구매핑
GSD{N}-{M}-SUMMARY.md (작업별) + atomic commits
Spec-Kitimplementation logs
OpenSpecproposal 진행 추적
BMADDevon(Developer) dev journal
GSD STATE.md결정·차단·세션 간 메모리
9-1 BUILD.md 생성 — BUILD 시작의 신호 🔗

BUILD.md는 BUILD가 시작되는 순간 처음 만들어집니다. "지금 무엇을 만들고 있는가, 무엇이 완성됐는가, 다음에 무엇을 해야 하는가"를 항상 담고 있어야 합니다. /clear 후 새 세션에서 Claude가 이 파일을 읽으면 즉시 상황을 파악합니다.

💻 BUILD.md 생성 요청 (Claude Code)
/model claude-sonnet-4-6    # BUILD는 Sonnet으로 전환

REVIEW.md를 확인했어. READY: YES다. BUILD.md를 아래 형식으로
생성해줘:

## 현재 Phase: Phase 1.0
## 시작일: [오늘 날짜]
## 누적 시간: 0h
## 완성된 기능
- 없음 (시작)
## 현재 작업 중
- [PLAN.md Day 1 작업]
## 다음 단계
- [PLAN.md Day 2 작업]
## 현재 오류
- 없음
## LogOnTable 트레이스
- (E4 첫 등장 자리, Day 1부터 매일 채움)

마지막 "LogOnTable 트레이스" 섹션이 v1.0 대비 추가된 부분입니다. E4 등장 자리예요.

9-2 테스트 하네스 설치 — 기능 구현 전에 반드시 🔗

Expo (React Native) 프로젝트의 경우

💻 Jest + Testing Library 설치
# Jest + Testing Library 설치
npm install --save-dev jest @testing-library/react-native
npm install --save-dev @types/jest jest-expo

# package.json에 scripts 추가
# "test": "jest --watchAll",
# "test:ci": "jest"

# Claude Code에서 설정 요청
jest.config.js와 babel.config.js를 설정해줘. Expo 52 + TypeScript
환경에서 작동하도록 해줘.

Next.js 프로젝트의 경우

💻 Vitest + Playwright 설치
# Vitest + Testing Library 설치
npm install --save-dev vitest @testing-library/react @testing-library/user-event
npm install --save-dev @vitejs/plugin-react jsdom

# E2E 테스트 (Playwright)
npm init playwright@latest
# → tests/ 폴더 생성됨

# 설치 확인
npm test -- --run    # 테스트 실행. 아직 테스트 없음 → 오류 없이 실행돼야 함
💡 Claude Code에서 테스트 하네스 자동 설치

직접 설정하기 어려우면 Claude Code에게 맡기세요.

"이 프로젝트에 테스트 하네스를 설치해줘. Expo 52 + TypeScript 환경이야. 단위 테스트(Jest)와 E2E 테스트(Playwright) 둘 다 설치해줘. 설치 후 npm test가 오류 없이 실행되는지 확인해줘."

Claude가 설치부터 설정까지 전부 처리합니다.

9-3 기능 구현 — TDD 방식으로 🔗

테스트 하네스가 설치됐으면 이제 기능을 만듭니다. 테스트를 먼저 쓰고, 테스트를 통과하는 코드를 만듭니다. /tdd 명령을 사용하면 Claude Code가 자동으로 이 순서를 따릅니다.

💻 TDD 방식으로 로그인 기능 구현
/tdd    # TDD 모드 활성화

로그인 기능을 TDD 방식으로 만들어줘. 테스트를 먼저 작성하고
테스트가 통과하는 구현 코드를 만들어줘.

테스트 케이스:
  - 유효한 이메일+비밀번호로 로그인 성공
  - 잘못된 비밀번호로 로그인 실패 + 에러 메시지
  - 빈 이메일로 로그인 시도 + 에러 메시지

CLAUDE.md 규칙을 준수하고 다른 파일은 건드리지 마.
9-4 기능 완성 루틴 — BUILD.md 업데이트 🔗

기능 하나가 완성될 때마다 반드시 아래 루틴을 실행합니다.

순서해야 할 것
1npm test 실행 → 전체 테스트 통과 확인
2BUILD.md 업데이트 → 완성 기능 추가, 다음 단계 수정, LogOnTable 트레이스 1~3줄 추가
3CLAUDE.md "현재 완성된 것" 목록 업데이트
4git add . && git commit -m "[기능명] 완성"
5/clear 실행 → 새 세션 시작
6새 세션 첫 메시지: "5파일을 읽고 다음 기능을 시작해줘"
💻 기능 완성 루틴 — 실제 명령어
npm test    # 모든 테스트 통과 확인

# Claude Code에서:
BUILD.md를 업데이트해줘.
완성된 기능: [기능명]
다음 작업: [다음 기능명]
LogOnTable 트레이스: [오늘 결정한 핵심 1~3줄]

CLAUDE.md의 완성된 것 목록에 [기능명]을 추가해줘.

git add . && git commit -m "[기능명] 완성"
/clear

# 새 세션
SPEC.md, PLAN.md, REVIEW.md, BUILD.md, CLAUDE.md를 읽고
다음 기능을 시작해줘.
9-5 E4 LogOnTable 실황 보존 — 첫 등장 🔗

여기가 새 1장에서 정의한 E4의 첫 등장 자리입니다.

💡 E4의 정의

"왜 그 결정을 내렸는가"의 사용자-AI 대화 트레이스를 보존하는 패턴입니다.

단순 결정 결과(예: "jupjups 테이블 UNIQUE 제약 추가")가 아니라, 결정에 도달하는 과정(예: "통계 조작 가능성 발견 → 옵션 A/B/C 비교 → UNIQUE 채택"의 대화) 자체를 BUILD.md에 남기는 형식입니다.

9개 표준 도구의 자리: 모두 "산출물(artifact)" 중심입니다. GSD STATE.md도 "결정의 결과"만 남기고 "결정 과정"은 세션 종료 시 사라집니다.

BUILD.md의 LogOnTable 트레이스 형식

매일 5분에 끝나는 양식이 이미 있습니다(계획·실행·이슈·게이트·회고). 거기에 LogOnTable 트레이스 1~3줄을 추가합니다.

📘 BUILD.md Day 8 예시
## Day 8 (2026-MM-DD, 4h)

[계획]
- jupjups 테이블 + UNIQUE 제약 SQL 작성 (PLAN G2)
- 집계 트리거 함수 + 트리거 작성

[실행]
- 32줄 SQL 작성 + 적용 완료
- 트리거 동작 테스트 (jupjup 추가 → benefits 자동 갱신) 통과

[LogOnTable 트레이스]
> 결정: UNIQUE (user_id, benefit_id) 제약 추가 vs 트리거 안
  검증의 트레이드오프 비교. UNIQUE 채택 — 통계 조작 원천 차단.
> 근거: 외부 검증 (트리거 안에서 COUNT) 보다 DB 제약 (UNIQUE)
  이 더 견고. 사용자가 우회 시도 시 DB 레벨 차단.
> 부작용: 사용자가 "줍줍 취소"를 누르려면 DELETE 후 다시 INSERT.
  추후 UI에 명시.

[이슈]
- 없음

[회고 1줄]
- UNIQUE 제약은 SPEC §5의 "통계 조작 원천 차단"이 SQL 레벨로 박혔다.

3~5줄짜리 트레이스가 매일 BUILD.md에 누적됩니다. 33일(TSV) 또는 70일(줍줍) 후 BUILD.md에 약 100~200개의 트레이스가 모입니다.

두 사례 — LogOnTable이 작동하는 모습

📘 사례 1 — 줍줍 Day 17 (마이페이지 + FCM 연동)
[LogOnTable 트레이스]
> 결정: 마이페이지의 "내가 줍줍한 지원금 총액" 계산 — DB 집계 vs
  서버 캐시. DB 집계 채택 (트리거가 이미 jupjup 합계를 갱신).
> 근거: SPEC §4-4의 "바이럴 훅" 가치는 "실시간 정확성". 캐시는
  분 단위 지연 가능 → 사용자 "방금 한 거 안 보여요" 항의 위험.
> FCM 토큰 갱신 주기: 7일. 갱신 실패 시 user.fcm_token = NULL 처리.
📘 사례 2 — TSV Day 8 (SSOT 메커니즘 작성)
[LogOnTable 트레이스]
> 결정: lib/match_facts.ts의 MatchFacts 인터페이스 — stats
  필드 optional vs required. optional 채택.
> 근거: NBA·MLB 데이터 부족 시 LLM 환각 방지. SPEC §3-9의
  "입력에 없는 사실은 만들지 않는다".
> cache_control 위치: 페르소나 system prompt 끝에 추가.
  ANTHROPIC_API_BETA="prompt-caching-2024-07-31" 헤더 필수.
> 자동 일관성 테스트: tests/persona_consistency.test.ts 5개 케이스.
  실패 시 cron/publish.ts 정지.

왜 LogOnTable이 운영 매뉴얼의 본질인가

💡 6개월 후 동업자의 시나리오

6개월 후 비개발자 동업자가 줍줍 폴더를 받았다고 가정합니다. "jupjups 테이블 UNIQUE 제약은 왜 있는 거지?"라고 질문이 생겼습니다.

결과만 있는 경우 (표준 도구 패턴):

GSD STATE.md: "jupjups 테이블 + UNIQUE 제약 작성 완료"

동업자: "왜 UNIQUE을 박았는지 모르겠다. 트리거로도 가능했을 텐데..."

→ 결정의 근거가 없으니 동업자는 "이걸 빼도 되나" 같은 위험한 질문을 하게 됩니다.


LogOnTable이 있는 경우 (5파일+ 패턴):

BUILD.md Day 8 트레이스: "UNIQUE 제약 vs 트리거 안 검증 비교. UNIQUE 채택 — DB 제약이 외부 검증보다 견고. 사용자 우회 시도 시 DB 레벨 차단."

동업자: "아, 이래서 UNIQUE이구나. 트리거로도 가능했지만 DB 제약이 더 견고하다고 결정한 거네. 이걸 빼면 우회 가능."

→ 결정의 근거 + 대안 비교 + 부작용까지 모두 본문에 있습니다. 동업자가 즉시 작업 재개 가능해요.

이게 운영 매뉴얼의 본질입니다. "결정 결과"만 있는 건 "운영용"이고, "결정 과정"까지 있는 건 "운영용 + 학습용 + 인수인계용"입니다. 5파일+의 BUILD.md는 후자입니다.

책 본문 자체가 큰 LogOnTable

BUILD.md만이 아니라, 1탄·2탄·3탄 책 본문 자체가 큰 LogOnTable입니다. 이 책의 LogOnTable 사례 절들이 그 자리예요.

표준 도구의 매뉴얼이 "이 명령을 입력하세요"를 가르친다면, 5파일+의 본문은 "이런 대화로 이런 결정에 도달하세요"를 가르칩니다. 동업자가 책을 정독하면 "내가 따라할 수 있는 대화 패턴"이 손에 들립니다.

📌 새 9장 정리
  • 1️⃣ 핵심 한 줄: BUILD.md = 일자별 5분 양식 + LogOnTable 트레이스 1~3줄. 33~70일 누적됩니다.
  • 2️⃣ BUILD 시작 4단계:
    1. BUILD.md 생성 (Phase·시작일·누적 시간·LogOnTable 섹션)
    2. 테스트 하네스 설치 (Expo: Jest / Next.js: Vitest + Playwright)
    3. /tdd 모드 + 첫 기능 구현
    4. 기능 완성 루틴 (npm test → BUILD.md → CLAUDE.md → git → /clear)
  • 3️⃣ E4 LogOnTable 등장: BUILD.md 일자별 양식에 "LogOnTable 트레이스 1~3줄" 섹션 추가
  • 4️⃣ 트레이스 3요소: "왜 그 결정인가" + "대안 비교" + "부작용" 보존
  • 5️⃣ 두 사례: 줍줍 Day 17 (마이페이지 총액 — DB 집계 vs 캐시, DB 채택) / TSV Day 8 (SSOT stats 필드 — optional vs required, optional 채택)
  • 6️⃣ 운영 매뉴얼 가치: "결정 결과"만이 아니라 "결정 과정"까지. 6개월 후 동업자가 즉시 작업 재개 가능합니다.
  • 7️⃣ 표준 흡수 매핑: GSD SUMMARY.md + STATE.md / Spec-Kit implementation logs / BMAD Devon dev journal
🎉 첫 번째 기능 완성!

테스트가 통과했고, BUILD.md에 기록됐으며, LogOnTable 트레이스가 첫 줄을 받았고, git에 저장됐습니다.

6개월 후 누군가 이 폴더를 펼쳐도 "왜 이 결정이 내려졌는지"의 답이 본문에 있습니다.

다음 장에서 5파일+ 슬래시 명령 + 표준 도구 슬래시 명령 비교를 다룹니다.

📘
1탄 도우미
질문하기 OK
안녕하세요! BUILD.md와 LogOnTable 패턴에 대해 무엇이든 물어보세요. 👇