2026-09-17 공개 운영 모델 확정(Sonnet 5·Haiku 4.5), 테스터7~11 휴먼테스트, 원숭이손 재설계
09-16 밤 작업에서 이어진 자정 이후 기록(00:00~00:30). 새벽(00:28~01:11)·오전~낮(09:43~12:39) 기록은 아래 “머지와 로컬 개발 복귀” 다음에 이어 적었다. 오후~밤(15:04~23:44) 미커밋 작업은 “테스터11” 다음에 적었다.
공개 운영 조합 확인 1판 (사용자 요청)
Core anthropic:claude-sonnet-5 + NPC anthropic:claude-haiku-4-5, 플레이어 gemma4:12b, 5회차 1판(305d77a6): 점수 11.7 → 11.7 → 16.0 → 24.8 → 29.8, 멸망 종결, 261.5초로 어제 돌린 판 중 가장 빨랐다. 크래시·폴백·서버 오류 0, NPC 발화 100건에서 메타 표현(유저·AI·게임 등) 0건. planner가 5회차에 beats 7개(상한 6)로 한 번 재생성했으나 복구 — 어제 Sonnet 판과 같은 구조화 출력 상한 문제다. 백엔드는 .env를 건드리지 않고 프로세스 환경변수로만 전환했다가 곧바로 로컬 설정으로 재기동.
기록 — 모델 선정·비용·전환 절차
docs/model_evaluation.md— A.19 §2에 조합 확인 판 추가, 판정 절에 “사용자 확정(2026-09-17)” 문구, 변경 이력 행. 빠져 있던 어댑터 스모크 표(세 모델 수정 전·후, temperature·effort 전송)와 selfplay 러너의 Secure 쿠키 처리 수정(33bebca)을 §5에 보강. gemma4 대조군 advisor 재생성 수 3 → 2 정정.metrics.yml1줄 추가(총 17줄)docs/HANDOFF.md맨 위 “공개 운영 모델 구성 — 확정” — 09-20에.env에 맞출 다섯 줄(키 자리·provider·모델), 재기동 확인, 확인용 1판, 콘솔 지출 한도, ollama 롤백, 운영 관찰 항목. 키 값은 문서에 쓰지 않았다docs/apiscenario.md맨 위 “최종 선정 — 2026-09-17 확정” — 선정·제외 이유 표, 판당 예상 비용을 두 판의 하네스 기록(호출 수·입출력 문자) × 단가로 재계산: 사람이 5회차까지 한 판(테스터62338ec9f+ 발화 분류기 보정) $0.68~0.97(950~1,360원), self-play 판 $0.54~0.78. 비용의 87~94%가 Core, 관리자 검사가 Core 입력의 56~68%. 완주 100/300/500판 $68~97 / $204~291 / $340~485(EC2면 $35~65 더함). Sonnet thinking 토큰·재생성·임베딩은 미포함(어댑터response.usage미기록). 임베딩은 Gemini 무료 키 그대로라 한도 확인이 운영 전환 전 과제
main 머지와 로컬 개발 복귀
- 머지 — 백엔드 590 passed ·
tsc클린 · 평가 러너 4종--help·NPC 러너 dry-run 정상 · 헤드리스 로그인 테스트 통과 · 추적 파일에 민감 문자열이 없음을 확인하고feat/coherence-chain12커밋을 main으로 fast-forward(6498e4f). 원격 push는 하지 않았다(원격 main09c3f23) - 키 삭제·로컬 복귀 — 사용자가
backend/.env의 Anthropic 키 값을 지웠다(줄은 빈 값으로 남음). 설정이 lru_cache라 백엔드를 재기동해 Coreollama:gemma4:12b·NPCollama:kanana1.5:8b-q4km(think off)로 확인, 헤드리스 로그인 통과, 로컬 1회차 self-play 크래시 0(8.8점, 66.9초)
새벽 — 배포 보안 점검 1건 (A등급, d3a54e5 01:04)
09-16 개발 로그인 리뷰에서 파킹해 둔 항목 하나를 배포 전에 닫았다. 배포 보안 점검 1건이고 세부는 공개 기록에 적지 않는다.
- 절차 — 커밋 기록상 sonnet 구현 → opus 리뷰 Critical 0 → 수정 1회, 593 passed(09-17 00시대 머지 때 590에서 +3). 이 일지 작성 시점에 재실행은 하지 않았다
- 문서 — 계약 문서·인계 문서·스펙·계획 문서, 이 일지의 09-16 이월 항목에 “09-17 수정 완료” 표기
새벽 — 공개 범위 정리와 데브로그 공개 게이트 (00:28~01:11)
저장소와 문서 사이트가 공개라서, 스포일러·운영 한도 같은 내용이 밖으로 나가지 않게 정리했다.
- 스포일러 식별자 중립화 (
08b593d01:04) — 테스트·검증 산출물 42파일 +95/−95. 결말이 드러나는 경로·DB명 표기와 목 응답의 결말 문장을 중립어로 바꿨다. 실제 DB 연결, 실제 결말 텍스트를 검증하는 코드, 원본 채점 로그는 그대로 뒀다 — 검증 의미가 바뀌면 안 되기 때문이다.frontend/tests/*.cjs7개가 여기에 포함된다 - 문서 공개 범위 (
cae8ca101:04) —apiscenario.md에서 한도로 역산한 최대 비용 문장을 지우고 “실제 한도 값은 배포.env에서 정하고 문서에 적지 않는다”로 바꿨다(한도 숫자가 공개되면 비용 공격 계산에 쓰일 수 있어서).HANDOFF.md운영 전환 절차에 과잉 사용 방지 허들 복원 확인 한 줄 추가 - 데브로그 스크립트 (
559ba6300:28,bd8b86d01:11) —scripts/jekyll-devlog.sh- 어제 섹션도 포스트로 다시 복사한다. 23:45 실행 뒤 자정 전후에 어제 섹션을 보완하는 일이 실제로 생겨서다(09-16 섹션이 그 예). 프롬프트의 metrics 경로
backend/metrics.yml→docs/metrics.yml정정 - 문서 사이트 포스트를 그대로 복사하지 않고
claude -p로 공개용 재작성: 결말 식별자 중립화, 보안·개발 계정·한도 세부 축약. 금지어가 1건이라도 남거나 재작성본이 원문의 절반 미만이면 포스트를 쓰지 않고 로그만 남긴다 - 재작성 호출은 빈 임시 폴더에서 훅 없이 실행한다 — 프로젝트 메모리·세션 훅 맥락이 공개 글에 섞여 들어가는 것을 막기 위해서다.
--posts-only DATE...로 지정 날짜만 재생성(+132/−21)
- 어제 섹션도 포스트로 다시 복사한다. 23:45 실행 뒤 자정 전후에 어제 섹션을 보완하는 일이 실제로 생겨서다(09-16 섹션이 그 예). 프롬프트의 metrics 경로
- 로컬
.env— 01:03 배포 준비로FRONTEND_BASE_URL을 운영 도메인으로 바꿨다(테스터9 F2 기록에서 확인). 이 값 때문에 세션 쿠키에Secure가 붙는다 — 아래 테스터9 F2 참고
오전 — 휴먼테스트 테스터7·8·9 (기록만, 코드 수정 없음)
세 명 모두 피드백은 기록 문서에 원문·해석·코드 위치로 남기고 조치는 전부 “미착수”다. 회차별 점수는 DB nights 읽기 전용 조회.
| 참가자 | 판(attempt) | 시각 | 결과 | 회차별 총점 | 피드백 | 문서 |
|---|---|---|---|---|---|---|
| 테스터7 | 61acc8ef (이벤트 606) | 10:08~10:56 | 5회차 clear | 33.5 → 40.8 → 66.9 → 66.9 → 94.2 | F1~F8 | 2026-09-16-tester7/tester7.md |
| 테스터8 | 7cf7484d (이벤트 595) | 09:43~10:22 | 5회차 doom(통과 0) | 0.0 → 14.6 → 29.2 → 29.2 → 47.9 | F1~F6 | 2026-09-17-test8/tester8.md |
| 테스터9 | e6290e17 | 11:43~15:00 | 5회차 clear(보조 플레이) | 55.4 → 64.2 → 55.4 → 55.4 → 85.4 | F1~F26 | 2026-09-17-tester9/tester9.md(미커밋) |
- 테스터7 — 09-16 10:33 후보
e7aa6a4f는 1회차 첫 장면에서 멈춘 판(이벤트 15건)이라 표본에서 뺐다. side_effect 셀은 테스터6과 같이 끝까지 0. 새 피드백: F3 NPC 선택 창 2×2 배열, F4 신의 개입 판정 「맞다」와 부연 「확신할 수 없다」 모순, F5 NPC 대화 맥락 단절, F6 「무슨 말을 들었나」 같은 내용 질문에 「맞다」가 붙음, F7 같은 시점 다음 그림 강조, F8 상황 이미지를 배경급으로 확대(적용 후보 4안, 협의 대기) - 테스터8 — 근거 탭 0개로 직접 쓴 답안만으로 채점됐고 cause·side_effect는 끝까지 0. F1 하루가 지날 때마다 화면이 아래로 밀림, F2 동기 파악 어려움, F3 3회차 아침 전까지 맥락 파악 어려움, F4 주제를 아는 개발자도 40%대(최종 47.9와 일치), F5 민석·은상에게 한 질문을 채연의 질문으로 인식, F6 규칙 해석 실패 시 다른 규칙으로 바꿔 제안
- 테스터9 프론트엔드/UI(10건) — F1 로그인 안내가 명령조 반말이고 “랜딩”이 개발 용어(
GuardScreen.tsx), F3 랜딩 버튼 등장(4.2s) 시 BGM 시작·우상단 토글, F4 플레이 안내·단서 기록 한 곳에, F5 채팅창 대신 비주얼노벨 대사창(줄 단위 앞·뒤 이동), F6 장면 그림은 처음에만 보여주고 단서 기록에 보관, F7 단서 기록 카드 → 한 줄 로그, F8 남은 대화 횟수를 HUD 게이지로(최대치9 - loop_n), F9 신의 개입 조언 모아 보기 또는 메모장, F12 대화 완료 인물 회색 처리, F13 장면 설명·규칙 결과·원숭이손 대가 문구가scene_execution.py의" ".join(narration)으로 한 문단에 합쳐짐(DB 이벤트 12225~12235 확인, 대가 문구 2회·대화 2회 차감) - 테스터9 백엔드/AI(3건)
- F2 개발 로그인 후에도 안내 화면 반복 —
backend.log에서 로그인 200 직후 세션 생성 요청 401이 2회. curl로는 로그인 200, 발급 쿠키를 직접 실으면 확인 요청도 200이라 세션은 유효하고 브라우저가 쿠키를 싣지 않은 상태. 원인 후보는 위.env변경으로 붙은Secure(http localhost의 Safari 거부) 또는127.0.0.1:3500/localhost:8500호스트 불일치. 설정 변경 없이 사용자 쪽에서 풀렸고 어떤 조치로 풀렸는지 모르므로 원인은 확정하지 않았다 - F10 「민석의 보고가 채연의 이송으로 이어졌는가?」에 「맞다」 + 본문 「알 수 없다」 — 이벤트 12194·12195 확인. 조언자(gemma4:12b)가 예/아니오 질문을
lookup으로 분류했고, 근거 2건의supported가 질문 명제가 아니라 “기록했다”는 하위 사실을 뒷받침했으며,intervention_interactor.py는lookup에서contradicted만unknown으로 낮춘다. 테스터7 F4·F6과 같은 계열 - F11 1회차 55.4(cause 75.0·motive 83.3) — Claude가 공개 관찰만으로 추천한 질문·추리문을 그대로 입력한 “보조 플레이” 표본이다. 처음엔 “채점이 관대하다”고 봤다가 재검토에서 정정했다: 한 문장이 여러 명제를 맞히는 현상은 테스터6 3회차(확정 8건/4문장)·테스터7 5회차(8건/5문장)에도 있고,
cited_chunks가 모든 명제에 같게 붙는 것은 후보 전체를 기록하는 설계(night_interactor._judge)다. 실제 버그는 motive-2의 매칭 문장 지목 오류 하나다. 1회차 점수 비교 테스터6 8.8 · 테스터7 33.5 · 테스터8 0.0 · 테스터9 55.4
- F2 개발 로그인 후에도 안내 화면 반복 —
- 난이도 판단 — 공통 피드백이 “개발자에게도 너무 어렵다”(테스터8 F3·F4)라서, 보조 플레이에서 통한 행동(본 것 기반 구체 질문, 같은 답만 하는 인물 건너뛰기, 대사와 방송 규칙 잇기, 인과로 잇는 추리문, 새 단서에 신의 질문)을 게임 안 안내·보조 장치로 옮기는 방향으로 정리했다. 채점 엄격도를 조이면 체감 난이도가 더 오르므로 엄격도와 난이도 보조는 목표 점수대를 정한 한 계획에서 함께 다루기로 했다. 채점기 점검은 A등급이라 별도 결정이 필요하다
낮 — 문서 사이트 칸반 자동 동기화와 자동 커밋·푸시 (071b500 12:39)
문서 사이트 칸반을 손으로 맞추지 않아도 두 저장소 진행 상황이 따라가게 했다. 3파일 +252/−1.
scripts/jekyll-kanban-sync.sh(194줄) — 개발 일지·인계 문서·커밋·파일 구성을 근거로 문서 사이트 칸반의 미완료 카드 status만 앞으로 올린다(todo → doing → review → done, 되돌리지 않음). YAML 파싱이 실패하면 전부 원복한다.--dry-run(판정만)·--no-publish(반영만, 커밋·푸시 안 함). crontab0 23 * * *등록 확인 — 23:45 데브로그보다 먼저 돈다scripts/beyondbob-publish.sh(49줄) — 자동화가 만든 파일만git commit --only로 문서 사이트 저장소에 커밋하고 푸시한다. 원격이 앞서면 rebase, 충돌하면 푸시를 멈추고 로컬 커밋만 남긴다. 작업 트리의 다른 수정이 섞이지 않게 하려고 경로 지정 커밋으로 제한했다jekyll-devlog.sh— 게이트를 통과해 새로 쓴 포스트를 위 헬퍼로 커밋·푸시(+10/−1). 문서 사이트 쪽 수정 범위도 “자동화 산출물만 자동 커밋·푸시, 세션 수동 수정은 요청 시에만”으로 바뀌었다- 문서 사이트 저장소에 실제로 올라간 칸반·프로필 커밋 내역은 이 일지를 쓰면서 조회 권한이 없어 확인하지 못했다
낮 — 휴먼테스트 테스터10 (기록만, 코드 수정 없음)
판 973b9869(Google 로그인, 맥북 Safari 1920x1080, 12:42~13:09 플레이): 1~4회차 모두 트럭 결말, 총점 8.8 → 8.8 → 0.0 → 0.0, 5회차 낮에서 피드백 완료. 테스터 요청으로 점수 원인과 정답(진실 명제)을 공개했으므로 5회차 이후는 정답을 모르는 표본이 아니다. 기록 docs/review-verification/2026-09-17-tester10/tester10.md(미커밋).
- 점수 원인 — 1회차는 7문장 중 “채연이는 열이 있다.” 하나만 cause-1(채연이 아프다)에 맞아 원인 25% × 0.35 = 8.8. 3회차에 정리 단계에서 답안을 고치며(
user_edited: true) 그 문장을 지워 ratchet이 적용되지 않고 0점. 4회차는 성격 묘사 4문장이라 불일치. 오답은 감점이 없고, 검진·이송 방송, “충식은 어제 이송됐다”, 트럭 옆면 표기 단서를 이미 봤지만 답안 문장으로 옮기지 못했다 - 피드백 5건 — F1 어떤 문장이 맞았는지 모르고 힌트가 없음(
ScoreScreen은 총점·칸별 3단계 문장만, 인정 문장은 결말에서만 공개). F2 정답 쪽으로 이끄는 흐름이 없는 불친절함(상위 원칙 — 신의 질문으로 “이 게임 목적이 뭐야?”를 물음). F3 규칙 직접 쓰기 제약(1회차 미리 보기 7회 중 5회 거부 — 대상 1명·행동 20개 글자 일치·부정어 3종만 인식, “서로”에 “그런 사람은 여기 없다”로 원인과 다른 문구, 대안이 전부 강제형) + 막힌 이유를 플레이어가 알아야 함. F4 원숭이손 대가·손상 단계(0→3)·결말 분기가 결말 회고에서만 드러나 짐작할 실마리가 없음. F5 신의 질문 5문항 전부 unknown — 테스터6~10 누적 36문항 중 29개(81%) - 정리 방향 — 테스터가 “확인 신호, 길을 좀 주는 게 있어야” 한다고 요약했다. 장르 비교(Obra Dinn 3개 묶음 확정, Golden Idol “2개 이하 오답”, Outer Wilds 함선 기록 표시)로 답답함의 원인이 장르가 아니라 확인 신호 부재임을 기록. 개선은 확인 신호(F1 인정 문장, F3 거부 원인, F5 쓸 만한 답)와 길잡이(목표를 원인·동기·정체로 안내, 빈 칸 방향 힌트, 신의 질문 다음 행동 제안 강조, 기믹 존재 암시) 두 축으로 묶었다
오후 — 휴먼테스트 테스터11 (기록만, 코드 수정 없음)
판 8523078a(개발 로그인, 로컬 localhost:3500, 14:11~14:31): 1회차 14.6점(동기 41.7만)·트럭 결말, 2회차 시작 직후 테스터가 소감 없이 그만둠 — 컨트롤러가 판을 판단. 기록 docs/review-verification/2026-09-17-tester11/tester11.md(미커밋).
- F1 개발 로그인 실패 — 로그인 200 직후 세션 생성 요청 401 ×2. 테스터9 F2가 다시 나타났다(
.env프론트 주소가 https라Secure; SameSite=Lax쿠키). “Chrome +http://localhost:3500” 안내 후 설정 변경 없이 해소 - 컨트롤러 관찰 6건 — O1 점수는 근거 기록을 그대로 옮긴 문장(준의 전언)이 motive-2로 인정받은 것이고, 제 말로 요약한 같은 내용은 오답(테스터9 F17 재발). O2 질문형 가설(“밥이문제인가;;;”)이 주장으로 채점됨. O3 신의 질문 2/2 unknown(둘 다
hit_cause_chain: true). O4 신의 힌트 “은상: 따라간다”가 규칙 선택지 3개에 없음(options()가 템플릿 앞 3개만, 리드rule_action미포함). O5manager_check기억 수정 4건 모두 ID 대신 설명문이라 적용 실패. O6 2회차 시작 직후 이탈(이유 미언급). 종합: 조사 구조는 작동했으나 단서→점수·다음 회차로 잇는 확인 신호·길잡이 부족이 1회차 이탈로 나타남. 신규 문제는 O4·O5, 나머지는 재발
오후~밤 — 작업 개요 (15:04~23:44, 전부 미커밋)
12:39 1ea9d81 뒤로 커밋은 없다. 아래는 미커밋 변경을 계획 문서, git diff, 파일 수정 시각으로 확인해 적었다. 시각은 파일의 마지막 수정 시각이라 작업을 시작한 시각이 아니다. 테스트 수치는 전부 계획 문서에 남은 기록이고, 이 일지를 쓰면서 다시 돌리지는 못했다(아래 “저장소·서버 상태” 참고).
| 묶음 | 등급 | 근거 문서 | 주요 파일 수정 시각 |
|---|---|---|---|
| 원숭이손 소원 4종 재설계 구현 | B | superpowers/plans/2026-09-16-f11-monkey-paw-wishes.md(재작성), 스펙 §3 개정 | 22:12~22:45 |
| 원숭이손 Q군 v2 삽화 6장 · 방송 MA13 녹음 | C | REMAKE_DAY_이미지제작서_원숭이손Q군_v2.md, output/imagegen/Q-v2-production.md, voice.md §10 | 22:26~22:37 |
| 판 주인 확인 (테스터9 F26) | A | superpowers/plans/2026-09-17-f26-attempt-ownership.md | 22:57~23:05 |
| 후속 보안 강화 (F26b) | A | superpowers/plans/2026-09-17-f26b-hardening.md | 23:16~23:21 |
| 휴먼테스트 피드백 반영 묶음 | F10은 B(기록상), 나머지는 기록 없음 | 계획 문서 없음 — diff와 테스트 docstring으로 확인 | 15:04, 22:00~22:01, 23:28~23:40 |
| 밤 기록은 참고 목록으로만 · 질문형 주장 안내 | A(채점 로직) | superpowers/plans/2026-09-17-night-evidence-reference.md | 23:41~23:44 |
밤 — 원숭이손 소원 4종 재설계 구현 (B등급)
스펙 2026-09-16-coherence-chain-design.md §3을 “방식 A(사실이지만 엉뚱한 곳을 가리킨다)”로 개정하고 계획을 처음부터 다시 쓴 뒤 Task 1~9를 마쳤다. 옛 소원 표(기획서 5.7의 검진 회피·은상 침묵·민석 방송 차단·준 잠들기)를 버린 이유는 두 가지다. 멸망 원인을 찾는 플레이어가 “검진이 채연을 보지 않는다” 같은 소원을 원할 까닭이 없어 유혹이 성립하지 않았고, 정보원을 없애는 소원은 부작용이 “세계가 바뀌었다”가 아니라 “게임이 막혔다”로 읽혔다. 기획서 파일은 고치지 않고 스펙에 이탈 사유를 적었다.
| # | 키 (겨냥 칸) | 소원 문장 (초안) | 얻는 사실 | 반대 사건 (같은 날 뒤 비트) |
|---|---|---|---|---|
| ① | chaeyeon-honest (motive) | 채연이 오늘은 밥을 왜 안 먹는지 솔직하게 말한다. | 채연 “밥에서 소독약 냄새가 나.” | 3비트 채연이 쟁반을 비움 → 5비트 담요 두른 사람 +1 |
| ② | checkup-record (cause) | 검진 담당자가 채연을 두고 무슨 말을 하는지 들린다. | 담당자가 소리 내어 “여기는 이상 없음.” | 6비트 소등 후 채연 자리 기침, 이상자 +1 |
| ③ | broadcast-room (motive) | 민석이 방송실에서 하는 말이 들린다. | 민석 “은상이 이상한 소리를 퍼뜨려요.” | 3비트 민석이 수첩을 덮어 두어 채연이 기록에서 빠짐 |
| ④ | band-meaning (identity) | 준이 손목띠 숫자의 뜻을 알아낸다. | 준 “침상에 같은 숫자가 있어. 자리 번호야.” | 5비트 은상이 “번호 순서대로 데려간대”로 부풀림, 소문 지수 +1 |
- 엔진 — 새 개념은 다섯 개로 묶었다:
PawWishDTO/PawRuleDTO, 신의 개입 후보에서 빠지는SceneActionDTO.paw_only, 실행 시 전략 표로 세계 상태를 바꾸는world_effect(flag_actor·rumor), 수락 즉시 장면, 부작용 관찰 문장 공개 조건. 수락하면 보이는 규칙 1개(monkey_paw)와 숨은 규칙 N개(paw_effect, 관찰 문장은 마지막 규칙에만)가 판 단위로 저장된다. 숨은 규칙은rule_rules.player_visible한 곳에서 걸러active_rules·규칙 충돌 표시에 나오지 않는다. 옛 발화 예산 대가(paw-cost)는 지워 어떤 경로에서도budget_left가 줄지 않는다. DB 마이그레이션은 없다(RuleOrm.source에paw_effect문자열) - 선택과 문구 — 어떤 소원을 낼지는 순수 함수
paw_rules.choose_wish(17줄)가 전날 밤 가장 높은 칸을 겨냥해 고르고, 관리자 모델은make_paw_reason으로 제안 문구 한 문장만 쓴다(실패하면 소원별default_reason). 2회 연속 거절이면 더 내지 않는다(PAW_DECLINE_LIMIT = 2). 1회차는 표의 첫 소원 고정이라 엔진은 소원 키 이름을 모른다 - 비트 배치 판단 — 원숭이손은 2비트에 제안되는데 같은 요청 안에서 2비트 장면이 먼저 실행되므로, 수락한 날 2비트 소원 장면은 그냥 두면 나오지 않는다. 그래서 소원 장면 비트가 현재 비트면 수락 응답에서 바로 실행한다. ③은 민석 “기록한다”(3비트)가 “방송실에 간다”(5비트)보다 앞이라, 5비트 방문을 소원 장면으로 쓰면 반대 사건이 앞서게 된다. 그래서 2비트에 따로 잠재 장면을 뒀다. ④는 은상의 평소 소문을 억제하면 억제 서술이 번호 소문과 모순되어 억제하지 않았다
- 구현 중 변경 — ② 장면을 “종이를 읽는다”에서 “담당자가 소리 내어 말한다”로 바꿨다. 인물은 글자를 읽지 못한다는 설정(테스터9 F24) 때문이고 스펙 §3 같은 줄도 고쳤다
- 프론트 —
DayScreen수락 응답의 서술·삽화·관찰을 현재 장면에 합침,PawRespondRes확장, 회고 라벨paw_effect= “원숭이손의 대가”, 플레이 안내의 “대화 횟수가 더 줄어들 수 있다”를 “받아들이면 남은 모든 날에 계속 걸린다”·”대가는 미리 알려 주지 않는다”로 교체(테스터9 F21), 제안 팝업에 “대가 없이 굴러오는 것은 없다.” 한 줄(테스터10 F4, 초안) - 규모 —
adapter.py+127,loop_interactor.py+105/−43,scene_execution.py+36/−16. 신규 테스트 5파일(test_paw_wishes.py353줄,test_paw_scene_execution.py83,test_scenario_paw.py70,test_scenario_dto_paw.py41,test_paw_rules.py40) - 검증(계획 문서 기록) — 기준선 604 passed / 1 failed(기존 한도 테스트 1건). 헤드리스
five-loop-flow→gameplay-clarity→npc-followup→scene-illustrations를 하나씩 실행.run_npc_dialogue_check.py --dry-run통과(가짜 Manager에make_paw_reason을 추가해야 했다, 출력 JSON 22:28 두 개). 임시 FakeLLM으로 5회차 사슬 확인: ①·② 제안, 3~5회차 반복, 부작용 주장 1 → 2건, 은상·채연 이상자 표시, 예산 불변. 이 결과를model_evaluation.md에 적을지는 정하지 않았고 오늘 그 파일은 00:17 이후 수정이 없다 - 남은 것 — 신의 질문 “채연이 밥에서 소독약 냄새가 난다고 했어?”는 ‘밥’ 주제 필터(F7
question_evidence) 때문에 아직 unknown이라test_spec_question_with_rice_word_is_supported를 strict xfail로 남겼다. 소원 문장·서술·대사·캡션은 전부 “초안 — 시나리오 확정 전”
밤 — 원숭이손 Q군 v2 삽화 6장과 트럭 방송 MA13 (C등급)
새 소원에 맞춰 그림 한 쌍(소원 장면 + 반대 사건 흔적)을 다시 맞췄다. v1의 Q03·Q04·Q06·clue-03은 캡션만 바꿔 재사용하고 Q05·Q07은 보관, 모자란 것만 새로 만들었다. 내장 image_gen, 후처리 없음.
| ID | 내용 | 규격 | 비고 |
|---|---|---|---|
| Q09 | 채연의 빈 쟁반 하나와 숟가락 | 1536×1024 (3:2) | 신규 |
| Q10 | 소등 후 앉아서 깊이 웅크린 채연 | 1536×1024 | 신규 |
| Q11 | 명판·손목띠의 같은 구멍 무늬(둘–간격–셋) | 1536×1024 | 신규. 첫 시도는 도구 안전 필터에 막혀 사물 중심 프롬프트로 재생성 |
| Q02 v2 | 별도 하단 침상에 앉은 담요 두른 등 둘 | 1536×1024 | 대체. 옛 그림의 쟁반 넷이 새 서술(셋)과 충돌. 첫 시도가 한 침상으로 보여 좌우로 분리 |
| Q08 v2 | 줄지은 침상 명판과 은상의 귓속말 | 1536×1024 | 대체. 옛 그림에 폐기된 수면 장면이 있고 명판이 없음 |
| P06 | 반쯤 열린 철문 너머 트럭 옆면 표기 | 941×1672 (약 9:16) | 밤 단서 |
- 검수 —
sharp로 6장 전체 디코딩, 목표 비율 대비 오차 0.2% 미만, 생성 원본과 SHA-256 일치. 시스템 Python에 Pillow가 없어 설치하지 않고 프로젝트의sharp로 검증했다. 기존 Q02·Q08 파일은 지우지 않고 v2로 따로 저장 - 등록 —
imageMap.ts에 Q02·Q03·Q04·Q06·Q08·Q09·Q10·Q11(+10줄, Q02·Q08은 ID를 유지하고 v2 파일로 연결). P06은 등록하지 않았다 - MA13 — “차량이 출발합니다. 문이 닫힐 때까지 자리에서 움직이지 마십시오.”
output/voice/MA13.mp3(107KB, 22:34) 녹음 완료, 게임에는 아직 연결하지 않음. 테스터9 F24(인물이 트럭 표기를 읽는 모순)에 대응해 글자를 읽을 수 있는 관리자가 트럭을 부르게 했고, 재생 시점을 4회차 밤에서 5회차 낮 끝으로 옮겼다. 상호 “○○” 표기는 쓰지 않는다. 인물 음성은 배제 결정이라 원숭이손 조건부 대사는 녹음하지 않는다(voice.md§10 +34줄) adapter.py의 4회차 트럭 결말 조각 자체는 이번 diff에서 바뀌지 않았다. 시나리오 최종 검수와 게임 화면 1초 식별 평가도 남았다
밤 — 판 주인 확인 (테스터9 F26, A등급)
테스터9 F26 공개 주의(“수정 전에는 세부를 공개 커밋·공개 포스트에 싣지 않는다”)에 따라, 이 절과 아래 F26b 절의 세부는 서버에 반영하기 전까지 공개 포스트에 싣지 않는다.
낮에는 테스터 플레이 중이라 기록만 했던 항목을 밤에 고쳤다. 목표는 판에 속한 모든 게임 API에서 “로그인 사용자 = 판 주인”을 확인하는 것이다. 소유 판정을 한 곳에 모으고, 판 하위 라우트 전부를 로그인 + 주인 확인 아래로 옮겼다. 최종 리뷰 반영으로 수정 1회. 테스트는 기준 634 passed / 1 failed / 1 xfailed에서 신규만 늘고 실패는 기존 1건(계획 기록, 정확한 수는 적혀 있지 않음), test_attempt_ownership.py 450줄. 넘긴 것은 F26b로.
밤 — 후속 보안 강화 (F26b, A등급)
위 공개 주의는 이 절에도 적용되므로 항목별 변경 세부는 적지 않는다. F26에서 넘긴 배포 보안 항목을 닫았다 — 공개 배포 설정에서의 인증 우회 차단, API 문서 라우트 비공개, 인스펙터 토큰 처리 강화 1건, 형식이 틀린 prior_attempt_id 500 → 422(판을 만들지 않음), 인증 필요 판정을 한 곳으로 모음.
- 공개 판정을 한 곳에 —
Settings.public_deploy는 세션 쿠키Secure와 같은 기준이다.main.deploy_profile()이LocalProfile/PublicProfile을 한 번 고르고, 프로파일이 문서 라우트와 기동 검사를 맡는다 - 테스트 환경 분리 —
tests/conftest.py가 운영 한도 설정을 코드 기본값으로 고정한다. 로컬.env에서 한도를 풀어 둔 탓에 계속 실패하던 한도 테스트가 이걸로 풀렸다 - 결과(계획 기록) — Task 5: 702 passed / 1 failed / 1 xfailed(기준 690 → +12),
npx tsc --noEmit통과. 리뷰 반영 뒤 747 passed / 0 failed / 1 xfailed(당시까지의 밤 작업 테스트 포함).frontend/tests/.playwright-out/guard/스크린샷 5장이 23:21에 갱신됐다(통과 여부 기록은 못 찾음) - 반영 안 함 — 프로파일 추상 부모, 인스펙터 후속 1건, 프록시 설정 확인(운영 전환 체크리스트),
run_core_selection.pyStage 4 러너 실행 환경 안내
오후~밤 — 휴먼테스트 피드백 반영 묶음 (계획 문서 없음)
각 테스터 기록 문서의 “조치” 줄은 테스터9 F10을 빼면 아직 “미착수”로 남아 있다. 아래 매핑은 diff와 테스트 docstring·주석에 적힌 피드백 번호로 확인했다.
| 피드백 | 변경 | 위치 · 테스트 |
|---|---|---|
| 테스터9 F10 (테스터7 F4·F6 계열) | settle_status: 본문이 확답을 피하면(알 수 없·가능성·모르겠 등 단서 8개) unknown. 무엇·누구 같은 의문사 질문은 contradicted → unknown, supported여도 “맞다.” 접두어를 붙이지 않음 | advisor_advice.py +24 (15:04) · 기록상 관련 44 passed, 전체 604 passed / 1 기존 실패 |
| 테스터8 F5 | NPC 프롬프트에 PLAYER_ASKER_NOTE: 말을 거는 상대는 명부 밖의 이름 모를 친구, “나”는 그 친구, 첫머리에 부른 이름은 상대 이름이 아님. 친구끼리 묻는 경로에는 붙이지 않음 | prompts.py·game_support.py · test_npc_asker_identity.py(3개), test_npc_dialogue_contract.py +45 |
| 테스터11 O5 | 관리자 점검 기억 목록에 인물별 짧은 id(m1…)를 줌. 삭제 대상은 짧은 참조 → 원래 ID(회차 접두어 뗀 형태 포함) → 6자 이상 원문 인용 순으로 해석하고, 후보가 둘 이상이면 적용하지 않음(오삭제 방지). 뜻풀이·요약은 거부 | npc_memory.py +37 · test_npc_day_memory.py +46 |
| 테스터11 O4 | 오늘 밤 조언이 권한 (대상, 행동)을 규칙 선택지 맨 앞에 둠. 관찰 근거가 없어도 “오늘 밤 조언이 권한 규칙이다.”로 냄. 이전 밤 리드·질문 리드는 순서를 바꾸지 않고, 이미 적용된 규칙은 다시 내지 않음 | intervention_interactor.py · test_usecase_intervention.py |
| 테스터10 F3 | 신규 rule_grammar.py(65줄): 행동 평서형에서 어간을 만들어 어미 기·는·지·게·고만 받고, 금지 표현은 닫힌 목록으로만 읽는다. LLM이 뜻을 풀지 않고 남는 글자가 있으면 거부. 거부 사유를 실제 원인별로 나눔(이름 여럿, ‘서로’·’모두’ 같은 집단 — 전에는 “그런 사람은 여기 없다”, 이름 없음, 행동 둘, 이중 부정, 목록 밖 행동은 쓸 수 있는 행동 5개 제시, 그 장면에서 확인 불가면 가능한 장면 안내). 금지를 원한 문장에는 강제형 대신 금지형 대안 | intervention_interactor.py +73/−32 · test_custom_rule_grammar.py 133줄 |
| 테스터9 F25 | 회고의 관찰 근거를 uuid 대신 “장면 3 · 준의 행동: …” 같은 라벨로, 3건 이상이면 접기 | 신규 lib/observationLabel.ts, Retrospective.tsx |
| 테스터9 F12 | 이 장면 대화를 마친 인물 카드를 흐림·흑백으로(선택은 막지 않음) | DayScreen.tsx |
| 테스터9 F22 | 버튼의 “…”를 “다음 장면 준비 중…” 등 문구와 aria-busy로 | DayScreen·GodScreen·ClearScreen·DoomEndScreen·ConfirmScreen |
| 테스터9 F1 | 가드 화면 문구를 존댓말로, “랜딩” → “처음 화면” | GuardScreen.tsx, guard.cjs 기대값 |
| 테스터8 F1 | 화면(phase)이 바뀌면 scrollTo(0, 0) — 긴 화면의 스크롤이 남아 다음 화면이 아래로 밀려 시작하던 문제 | play/page.tsx |
| 테스터9 F2 · 테스터11 F1 | 첫 플레이 안내에 “Chrome + http://localhost:3500”, Safari·127.0.0.1이면 Secure 쿠키 때문에 로그인 안내가 반복될 수 있다는 문장 | docs/first-play-guide.md |
플레이 안내 첫 문장도 “멸망하는 이유를 직접 쓴다”에서 “그 원인과 동기를 밝혀 쓴다”로 바뀌었다(피드백 번호 표기 없음).
밤 — 밤 기록은 참고 목록으로만, 질문형 주장 안내 (A등급, 휴먼테스트 순서표 3번)
근거는 테스터9 F17·F11 재정정(근거 원문 조각 “오후 검진을 시작합니다.”가 무관한 cause-5로 인정됐고, 조각이 빠지자 64.2 → 55.4)과 테스터11 O1(기록을 옮긴 문장은 점수, 제 말로 요약하면 오답)·O2(질문형 가설이 전부 불일치)다. 두 결정 모두 사용자가 B안을 골랐다.
| 구분 | 변경 전 | 변경 후 |
|---|---|---|
채점 후보(source_claims) | 직접 쓴 글 + 고른 노트 원문 | 직접 쓴 글만 |
| 답안 조건(화면) | 노트 1개 이상 또는 글 | 글이 있을 때만. 비면 “한 줄 이상 쓰면 정리할 수 있다.” |
| 서버 draft | 빈 글 + 노트 → 노트 원문이 주장 | 빈 글 → 주장 0개(거절하지 않음 — 셀프플레이 “침묵” 페르소나 호환) |
| 노트 패널 | “관찰 기록에서 근거 고르기 · 선택 N개” | “기록 보며 쓰기 · 표시 N개”, “기록은 참고용이다. 판정에는 위에 직접 쓴 글만 들어간다.” |
| 질문형 주장 | 표시 없음 | 확인 화면에 “질문이다. ‘~다’로 단정해 고쳐 쓴다. 다음 밤 글에도 고쳐 써야 이어진다.”(고치기를 쓴 뒤에는 “이대로 보내진다”) |
- 왜 노트를 뺐나 — 관찰 원문을 탭만 해도 주장이 되어, 추리 없이 많이 고를수록 점수가 오르는 역유인과 원문 조각이 무관한 명제에 붙는 오인정이 실제로 났다. 기획서 §7.2의 “유저가 쓴 것만 주장으로 쪼갠다”를 더 엄격히 따르는 방향이다. 기록 원문을 글에 직접 옮겨 적으면 플레이어가 쓴 문장이므로 막지 않는다. 노트 표시 상태 저장·다음 밤 복원은 참고 목록 표시용으로 남겼고 DB·이벤트 스키마는 그대로다
- ratchet — 코드는 그대로다. 이전 밤에 노트 조각으로 인정된 명제는 이번 글에 그 문장이 없으면 잠금이 풀린다. 조각은 플레이어가 쓴 문장이 아니어서 “문장을 안 바꾸면 판정이 나빠지지 않는다”는 취지 밖이라고 판단했다. 진행 중인 판은 반영 후 첫 밤에 조각 기여분만큼 점수가 내려갈 수 있고, 이미 저장된 draft는 다시 쓰지 않는다(한 밤 한정 과도기)
- 영향 추정(개발 DB, 상한) — 기록을 탭한 밤 113개 중 49개가 노트 원문 매칭으로 점수를 받았다. 새 규칙이면 통과선(50%)이 뒤집히는 밤 5개, 5회차 결말이 뒤집히는 판 1개. 과거 LLM 정리·셀프플레이 판이 섞여 상한으로 읽는다. 신이 “맞다”고 한 사실이 노트로 자동 주장되던 길이 사라져 체감 난이도는 오른다
- 질문형 판별을 백엔드에 둔 이유 — 프론트엔드에는 단위 테스트 도구가 없어(Playwright 스크립트뿐) 한국어 어미 오판 사례를 pytest 매개변수 표로 검증하는 편이 낫고, 주장을 쪼개는 층과 같은 곳에서 판정해야 화면이 받는
claims와 플래그가 어긋나지 않는다. 신규claim_rules.is_question_claim(85줄), draft·PATCH 응답에is_question: boolean[] - 리뷰 뒤 보수화 — 오표시보다 놓침을 택했다. 물음표는 문장 끝일 때만(인용 대사 속
"배고파?"는 평서),누군가·뭔가·언젠가·어딘가·무언가는 제외,ㄴ받침+지는 마지막 어절 3음절 이상일 때만(편지·먼지·반지·단지·왠지 제외). 테스트 표는 기존 36건에 오표시 12건·끝 물음표 변형 3건 추가(test_claim_rules.py69줄). 안내 문구는 해라체로 맞췄다 - 정리 — 기획서 v8.1 §7.2·§7.3을 “노트는 참고 목록이고 채점 후보가 아니다”로 고치고 패치 기록 한 줄 추가(+11). 운영 코드에서 안 쓰던
NoteRepository.by_ids와 테스트 가짜 제거.api_contract.md밤 draft·PATCH 절 갱신,demo_guide.md밤 흐름 문장 교체. 헤드리스connected-investigation.cjs기대값 갱신(+16/−3) - 남은 것 — 인용 대사 안에서 물음표 뒤에 공백이 오면(
채연이 "누구야? 왜?" 하고 물었다) 따옴표 안에서 문장이 갈려 질문으로 표시된다. 기획서 v8.1의 §7.2·7.3 밖(신의 질문 “탭 한 번으로 주장이 된다”, 답안 표 “노트 탭 + 자유 텍스트” 등)에 옛 서술이 남아 있다. “성실” 페르소나 셀프플레이는 노트 탭으로 점수를 받던 판이라 09-17 전후 수치가 이어지지 않는다 — 재측정 때 “09-17 이후 노트 비채점”을 표기한다
커밋·저장소 상태 (낮 작성 시점, 12:40 무렵)
- 오늘 커밋 13건 —
a815aff00:03 ~1ea9d8112:39. 00:03~00:26 5건(평가·비용 기록과 이 일지), 00:28~01:11 5건(데브로그·보안 점검·스포일러·공개 범위), 12:39 3건(071b500자동화,dcd677409-16 섹션에 프로덕션 도메인 연결 기록 +10줄,1ea9d81테스터7·8 기록 +179줄) - 원격 —
main·feat/coherence-chain·origin/main이 모두1ea9d81로 같다. 00시대 머지 때 “push 안 함(원격09c3f23)”이었던 상태는 이후 push로 해소됐다 - 미커밋 —
docs/review-verification/2026-09-17-tester9/(168줄, 테스터9 진행 중) 하나.git diff --stat·--cached --stat모두 비어 있음 - 확인하지 못한 것 — 백엔드 테스트 재실행,
localhost:8500/health·프론트 3500 응답, 문서 사이트 저장소 로그는 이 일지 작성 중 명령 승인이 나지 않아 보지 못했다.backend.log는 12:40까지 갱신되고 있었다
밤 — 저장소·서버 상태 (23:45 무렵 확인)
- 커밋 — 12:39 이후 0건. 추적 파일 68개 미커밋 +1,844/−960(이 일지 보완 전 기준): 백엔드 42파일 +1,110/−270, 프론트 17파일 +186/−70, 문서 9파일 +548/−620(F11 계획 재작성 703줄 변경이 가장 크다). 미추적 신규는 백엔드·프론트 코드·테스트 14파일 1,512줄, PNG 6장, 계획 문서 3개, 이미지제작서 Q군 v2, 테스터9·10·11 기록 폴더
- 서버 — 백엔드
uvicorn main:app --port 8500은 01:09에 뜬 프로세스 그대로라 15:04 이후 백엔드 변경은 하나도 반영되지 않았다(계획마다 “서버 재기동 금지”). 프론트next dev -p 3500(next-server v16.3.4)은 10:03에 떴고 dev 서버라 파일 변경이 바로 반영된다. 재기동 전까지 로컬 플레이는 화면과 서버가 어긋난다 — 예를 들어 밤 화면은 “기록은 판정에 안 들어간다”고 안내하지만 옛 백엔드는 표시한 기록 원문을 주장에 넣는다 - DB —
docker compose ps: 게임 DB 컨테이너(pgvector/pgvector:pg17) Up 2 days (healthy),127.0.0.1:5435 - 확인하지 못한 것 — 백엔드 전체 pytest 재실행과
localhost:8500/health요청은 이 일지를 쓰는 중 명령 승인이 나지 않아 실행하지 못했다.npx tsc --noEmit도 돌리지 않았다. 이 섹션의 밤 테스트 수치는 모두 계획 문서 기록이다. 일지를 쓰는 동안에도rule_grammar.py가 수정되고 있어(wants_suppress가 금지 표현이 정확히 하나일 때만 참) 밤 작업은 아직 끝나지 않았다 - 모델 평가 정본 —
docs/model_evaluation.md(00:17)·docs/metrics.yml(00:12) 이후 수정 없음. 오늘 평가 결론은 위 “기록 — 모델 선정·비용·전환 절차”에 적은 A.19 갱신이 전부다
이월
① 원격 push 여부(공개 저장소) — origin/main 1ea9d81로 해소 ② 09-20 운영 전환 때 .env 전환(HANDOFF.md 절차, 과잉 사용 방지 한도 복원 포함) ③ 임베딩 Gemini 무료 키 한도 확인 ④ planner beats 상한 강제(프롬프트 명시 또는 절단) ⑤ 어댑터 response.usage 기록으로 비용 실측 ⑥ Gemini 쿼터 리셋 후 80턴 재실행은 NPC 후보 제외로 불필요 ⑦ F11 원숭이손, 테스터7 F1·F2 — 밤: 원숭이손은 소원 4종 재설계로 Task 1~9 구현, 미커밋·서버 미반영, 문장은 시나리오 확정 전 ⑧ 배포 전 프록시 설정 확인(09-17 수정 완료) ⑨ 신의 질문 판정·본문 일관성(테스터7 F4·F6, 테스터9 F10) — 15:0x 코드 수정·테스트 완료(advisor_advice.py settle_status·is_hedged·is_wh_question, 관련 44 passed·전체 604 passed/1 기존 실패), 미커밋·서버 미반영(테스터 플레이 중이라 재시작 보류), 밤까지 미커밋·미반영 그대로 ⑩ 난이도 보조와 채점 엄격도 목표 점수대 결정(테스터8 F3·F4, 테스터9 F11 — 채점기는 A등급), motive-2 매칭 문장 지목 오류 ⑪ 낮 화면 재구성 묶음(테스터7 F2·F3·F7·F8, 테스터9 F4~F8·F12·F13) — 밤: F12만 반영 ⑫ NPC 화자 인식·대화 맥락(테스터8 F5, 테스터7 F5), 규칙 해석 실패 시 재입력 경로(테스터8 F6), 회차 전환 화면 밀림(테스터8 F1) — 밤: 테스터8 F5·F1 반영, F6은 테스터10 F3 작업으로 거부 사유·금지형 대안이 바뀜, 테스터7 F5는 그대로 ⑬ 로그인 안내 문구·랜딩 BGM(테스터9 F1·F3), 로컬 테스트 안내에 “Chrome + http://localhost:3500” 명시 검토(테스터9 F2) — 밤: F1 문구와 F2 안내(first-play-guide.md) 반영, F3 BGM은 그대로 ⑭ 테스터9 판 종료 후 attempt 확정·기록 커밋 — 판은 5회차 clear로 끝남, 커밋은 아직 ⑮ 서버 재기동·커밋 — 15:04 이후 백엔드 변경 전부 미반영, 진행 중인 플레이가 없을 때 반영(F26 기록) ⑯ 테스터8·9·10·11 기록 문서의 “조치: 미착수” 줄을 밤 반영분(테스터8 F1·F5, 테스터9 F1·F2·F12·F17·F21·F22·F25·F26, 테스터10 F3·F4, 테스터11 O1·O2·O4·O5)에 맞춰 갱신 ⑰ 시나리오 최종 확인 — 소원 문장·조건부 대사·Q군 캡션·MA13 대본·팝업 “대가 없이 굴러오는 것은 없다.” / P06·MA13 게임 연결 / 테스터9 F24 트럭 결말 조각 교체 ⑱ 원숭이손 ① 신의 질문 ‘밥’ 주제 필터(strict xfail 1건) ⑲ 노트 비채점 이후 셀프플레이 재측정(09-17 전후 불연속 표기), 원숭이손 러너 결과 model_evaluation.md 기록 여부 ⑳ 밤 기록 잔여 — 인용 대사 속 “? “ 오표시, 기획서 v8.1 §7.2·7.3 밖 노트 탭 서술, 밤 화면 2단 배치. 노트 비채점으로 오른 체감 난이도는 ⑩에 반영 ㉑ F26b에서 넘긴 것 — 인스펙터 후속 1건, run_core_selection.py Stage 4 러너 실행 환경 안내, 백엔드 전체 테스트·tsc 재확인(일지 작성 중 미실행)