2026-09-15 첫 휴먼테스트, NPC 대화 교체(gemma4), 구글 로그인·랜딩 페이지 구축
첫 휴먼테스트 — 실플레이 2판 관찰 (DB 이벤트 근거)
개선 배치 3/3 반영 후 첫 사람 플레이가 있었다. 게임 DB 읽기 전용 조회로 확인한 사실:
- 판 0468b70c (09:30~09:37) — 1회차 완주. 낮 발화 26건, 원숭이손 1회 제안(거절), 신의 질문 3회 전부 미사용, 밤 답안은 “채연이 아픈거 같아,” 11자 단문 → cause-1 confirmed(25.0), 나머지 셀 0으로 총점 8.8 · fail · death. 단서를 탭하지 않고 한 문장만 쓴 최소 답안의 하한 실측이다
- 판 806122f3 (13:15~13:19) — 낮 3비트·발화 26건까지 진행 후 밤 답안 없이 이탈
- 오늘 생성된 attempts는 121건이지만 실플레이는 위 2판뿐 — 나머지는
/play로드 시 즉시 세션을 만드는 구조와 UI 테스트가 만든 빈 판. 로드 즉시 세션 생성이 빈 판을 다량 적립한다는 것도 이번 조회로 확인된 관찰이다 - 이 판들에서 나온 NPC 문답(원래 플레이 8답변)이 아래 NPC 대화 개선의 출발 근거가 됐다
NPC 대화 개선 — 정책 npc-dialogue-2와 모델 교체 kanana → gemma4:12b
휴먼테스트에서 드러난 NPC 문답 품질 문제를 정책·측정·모델 세 축으로 손봤다. 정본은 model_evaluation.md 신규 섹션 “현재 NPC 평가 기준 — 2026-09-15”, 원문은 output/npc-dialogue-2026-09-15/(evaluation-report.md·final-summary.json).
- 정책 전환 —
npc-dialogue-2: 쉬운 말투·인물별 성격은 유지하되 질문 이해·자기 행동의 이유 설명·당일 기억을 요구. 이전 E6의 ‘왜=몰라’·3턴 망각·무조건 전언 수용은 더 이상 통과 조건이 아니다. 과거 E6 수치는 당시 기준의 기록으로 보존하고 새 정책의 근거로 재사용하지 않는다 - 새 평가 러너 —
backend/scripts/run_npc_dialogue_check.py. 실제 질문·허용 근거·출력·재생성·지연을 저장하고, 의미 품질을 단어 포함 검사나 같은 모델 자기평가로 통과시키지 않는다 - 측정(각 상황 1회) — Kanana 공통 21문답: 실패·재생성 0, 중간값 1.027초·p95 1.468초 / Gemma 합계 41문답: 실패·재생성 0, 중간값 2.599초·p95 3.053초(초기 목표 3초 소폭 초과). 은상의 전언 출처 구분(“준한테 들었어. 내가 직접 본 건 아니야”), 민석의 행동 근거 답변 등 실제 행동·출처 설명이 Kanana보다 정확해진 것을 근거로 로컬 NPC를
ollama:gemma4:12b· think off · temperature 0.3으로 교체. Core는 기존 유지 — 로컬 구성은 NPC·Core 둘 다 gemma4:12b가 됐다 - think=true 진단 3건은 생성 1024토큰 상한에서 전부 최종 답변 없이 종료(23.3~23.8초) — 추론 켜는 설정은 적용하지 않는다. 문맥 잘림 가설도 입력 토큰 동일 실측으로 기각
- 남은 한계를 명시 — 현재 있는 인물의 부재 추측 1건, “지금 다시 말해줘” 후속 4건 전부 “몰라”, 사라진 친구 이름에 현재 친구 나열 등 질문 관련성 문제 잔존. 최초 의미 품질 목표(중요 모순 0·현재 전언 이해·관련성 90%)에는 미달임을 그대로 기록 — 사람 블라인드 평가·새 참가자 5회차 실플레이는 미수행
- 부수 수정: 긴 기록 ID → 모델용 짧은 별칭(재생성 유발 해소), 정적 수첩 중복 제거(삭제된 기록 복구 현상 소멸). 신규 테스트 파일 6종(
test_npc_dialogue_contract·test_npc_context·test_npc_day_memory·test_npc_response_checks·test_age7_memory_window·test_scenario_knowledge) - 대화 규칙·저장 경계 재정의(api_contract·HANDOFF 갱신) — 사용자 지시로 장면당 캐릭터 1회 제한 복구(다른 캐릭터는 가능, 다음 장면에서 같은 캐릭터 재대화 가능, 하루 예산 8/7/6/5/4 유지). 발화별 UUID
request_id멱등 처리 — 재전송·동시 요청은 저장된 응답을 반환하고 예산을 중복 차감하지 않으며, 발화·예산·관찰·노트를 한 트랜잭션으로 저장. 모델 응답 실패는 대사로 위장하지 않고 503(상태 무변경, 같은 ID로 재시도). 새 루프에서 네 NPC 모두 당일 기억 초기화(신뢰 5%만 유지, 민석의 과거 루프 기억 예외 제거), 관리자 삭제는 지정 출처·연관 문답을 가리고 실제 재경험으로만 재학습.ambient는 서버 후보 선택식에서 조건 충족 시 시나리오 작성 대화로 교체. 기존 JSON 기억 필드 재사용이라 DB 마이그레이션 없음(단 구버전이 이미 잘라낸 진행 중 루프 기억은 복구 불가) - 기능 검증 — backend 460 passed(8.48초, 테스트 DB),
tsc --noEmit통과, 헤드리스 UI 4종(npc-followup·gameplay-clarity·connected-investigation·five-loop-flow) 통과, 모델 무호출 dry-run 40문답·구조 검사 294개 통과. 실DB 동시 요청 2건 → 모델 호출 1회·예산 차감 1회 확인, 저장 실패 롤백·관리자 삭제·루프 초기화 검증. 독립 코드 리뷰 지적 3건(발언 출처 의존성·조건부 기록 내용·한 글자 이름 처리) 수정 후 재검증. 백엔드 8500·프론트 3500 재기동,/health에서 NPC·Coreollama:gemma4:12b·/play200 확인. 검증 기록은docs/review-verification/2026-09-15-npc-dialogue/
구글 OAuth 로그인 — 백엔드~프론트 전 구간 구현
랜딩 페이지에 로그인 버튼을 놓기 위해 인증 전 구간을 헥사고날 규약대로 신설했다.
- 백엔드 신규 —
User엔티티, auth DTO, 포트 3종(OAuthClientPort·UserRepositoryPort·SessionTokenPort) +AuthUseCase/AuthInteractor, 어댑터 4종(GoogleOAuthClient·UserRepository·SessionTokenSigner(HMAC-SHA256)·auth_router),UserORM+ alembic 마이그레이션2026_09_15_1753-a8b1ba0fa71f_users_google_oauth적용(users 테이블 배포). CORS credentials 허용, 컴포지션 루트 배선 - 프론트 연동 — API 래퍼에 쿠키 세션용 credentials 추가, base URL을 localhost로 통일(쿠키 공유), 랜딩 로그인 버튼 → 백엔드 OAuth 시작 URL 연결, 세션 관리 API 계약 추가
- 라이브 검증 — 기동 중이던 서버가 8000 포트 구버전(신규 라우트 미탑재)이라 재기동 후 OAuth 리다이렉트·state 검증·세션 쿠키까지 실동작 확인. 기존 게임 엔드포인트 무영향 확인. 남은 것은 Google Console에 redirect URI 등록뿐
- 약관·개인정보처리방침 —
/terms·/privacy페이지 신설(다크 테마 통일),SiteFooter는 가운데 법적 문서 링크 +© BEYOND BAB · REMAKE DAY저작권 표기로 정리
랜딩 페이지 신설과 이미지 제작
/play 리다이렉트뿐이던 frontend/app/page.tsx를 실제 랜딩으로 만들었다.
- 이미지 후보 탐색 — 세계관 시각 규칙(얼굴·손·하늘·텍스트 금지, 주황=관리 권위 한정, 공포가 아닌 심리적 긴장) 안에서 소독(방역) 모티프를 표면 서사·세계관 진실·리메이크 구조를 한 번에 잇는 앵커로 채택. 제작 스펙
docs/REMAKE_DAY_이미지제작서_랜딩2종_v1.md(LP01 소독약 보관실 · LP02 방역 통제 표지판) 작성 후 codex로 변형 생성 — 헤드라인 자리를 비우는 센터 보이드 구도, 도로 통제 표지판·원경 로우앵글 등 피드백 반영 반복. codex 알파 채널은 전용 파라미터 없이 프롬프트로 지원됨을 확인하고 투명배경 타이틀 로고(risograph 어긋난 인쇄 효과)도 4종 생성 - 최종 결정 — 히어로는 LP02 대신
/play엔트리 이미지를 재사용(게임 진입과 랜딩의 시각 연속성). 생성물은output/imagegen/landing/에 보존 - 버튼 정리 — 로그인·시작 버튼을 동일 위계·컴팩트 사이즈로, 로고 확대, 카피 콤마 수정
음성·BGM 반입과 토글 스위치
- voice.md 개정(+136줄) — 대사 체계를 기본 14개 + 분기·안내·회고 16개 = 30개로 정리. 파일 등록과 장면 조건을 구분해, 화자의 실제 발화·결과 방송이 대본과 일치할 때만 재생한다(파일 소진을 위해 시나리오에 없는 내용을 만들지 않는다). 소등 방송 1개·현장 인물 대사 5개 추가 제작 완료, 다음 목표는 세 NPC 목소리 6개
- BGM·대사 연결 —
/play진입 시 기본 음량 25% 자동재생(차단 시 첫 입력에서 재시도), 장면·루프 간 재생 위치 유지. 대사 재생기는 방송→인물 순 재생, 대사 중 BGM 7% 덕킹 후 25% 복원, 다시 듣기·음성 끄기 독립 토글, 음원 실패가 진행을 막지 않는다 - 토글 스위치 — 음성·BGM 버튼을 우상단 토글 스위치 2개로 교체. 화면 밝기 적응 색은
mix-blend-difference가 요구 효과를 못 내 배경 휘도 감지 훅(backdrop luminance detection)으로 재구현, 밝은 화면(엔딩 등)에서 색 반전 확인. OFF 노브 수직 정렬·ON 투명 컷아웃 리그레션도 수정
배포 전략 확정 — 프론트 Vercel · 백엔드 t3.micro · 모델 홈서버
- 구도: 프론트 Vercel, 백엔드+Postgres AWS t3.micro, LLM 서빙은 홈서버 Ollama(백엔드가 프록시). 한국 단일 리전이라 Vercel의 지연 이점(도쿄 PoP ~30-40ms vs Cloudflare 서울 ~5-15ms)은 사실상 사라지지만, 프론트를 t3.micro에 올리면 Node 프로세스 ~100MB+와 렌더링 CPU가 백엔드·DB와 경합하므로 자원 보존을 근거로 Vercel 유지를 결정했다
- 프로덕션 이행 시 과제로 기록: 크로스 도메인 쿠키(
SameSite=None; Secure)와 백엔드 CORS에 실제 프론트 도메인 추가. 동일 도메인 자가 호스팅으로 가려면 동적 라우트(harness/[attemptId]등)에generateStaticParams가 필요해 정적 내보내기가 현재는 막혀 있다
마무리 — 커밋 상태와 이월
- 오늘 커밋 0건, 전부 미커밋 — 추적 파일 57개 +1,971/−487줄에 신규 파일 다수(auth 모듈 일체·
/terms·/privacy·토글/음성 컴포넌트·음성 mp3 30종·신규 테스트·검증 기록·이미지 제작서). HANDOFF.md를 2026-09-15 기준으로 갱신(+17/−3줄) - 이월(미완) — Google Console redirect URI 등록, NPC 의미 품질 목표(중요 모순 0·현재 전언 이해·관련성 90%) 미달분, 사람 블라인드 페르소나 평가·새 참가자 5회차 실플레이, 세 NPC 목소리 6개 제작. 다음 플레이 관찰 포인트: 장면당 1회 제한과 다음 장면 재개, 오늘 경험/지난 루프 구분, 현재 전언에 대한 반응, 네 인물이 서로 다른 것에 관심을 두는지