vignette/docs/ops/handoff-avatar-seoyeon-2026-06-27.md
Yun Chan 085460b5e0 대시보드 폴드아웃/드릴다운 정리 + 페르소나 역린·misconduct 반응 + 게이트웨이 격리·RAG 비차단 수정
SSOT 대시보드:
- 한신대 기술분석 PDF(19쪽) 정합성 분석 + 이번 세션 발견 섹션 추가
- 섹션 폴드아웃(접기)·상단 목차(드릴다운)·모두 펼치기/접기 — 내용 보존, 레이아웃만 정리

페르소나 반응 강화('저항·반응 조절' 핵심 차별):
- PersonaCard.triggers(역린) 필드 + CCD 핵심상처 파생 역린 블록
- L0에 무례·모욕·조롱 시 현실적 동맹 균열 반응 지침

버그·성능 수정(라이브/E2E로 포착):
- 게이트웨이 페르소나 격리: --append-system-prompt를 --system-prompt(교체)로 + --exclude-dynamic-system-prompt-sections (내담자 캐릭터 붕괴·개발맥락 누출 차단)
- RAG: 임베더 동기 로드(약 7-13초)를 _warm_rag_caches 백그라운드 warm으로(세션 생성 블로킹 회귀 수정)
- voice TTS RMS 데드힌트 제거, init_state OpennessParams 파라미터객체화
- 한국어 PII(날짜·금액·주소) 마스킹 보강
- 레이아웃 시각 게이트: 폼 컨트롤 값 스크롤 오탐 제외(7/7)

검증: 백엔드 84/84, E2E 42(데스크톱 27·모바일 11·아바타 4), 시각 게이트 7/7
2026-06-27 02:30:46 +09:00

57 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 서연(P1) 아바타 작업 핸드오프 — 2026-06-27
> 다른 세션에서 이어서 작업하기 위한 인계. imagegen(gpt-image-2)+BiRefNet+파츠 분리 리깅 파이프라인 전체를 여기서 참조.
> 상세 원칙은 `CLAUDE.md` §4.
---
## 0. 한 줄 요약
파이프라인·렌더러·dev 미리보기까지 **완성**됐으나, 서연 아트가 **잘못된 참조(Image #1=긴 머리)**로 만들어져, **진짜 목표 Image #2(짧은 갈색 보브, 정면)**로 **재생성**이 남았다.
---
## 1. ⚠️ 다음 세션이 가장 먼저 할 일 (핵심)
1. **목표 재확인**: 진짜 타겟은 **Image #2** = `D:\workspace\GLM\.claude-glm\image-cache\73cbbea0-5c27-4ced-91db-16d7a8df602f\2.png`
(단일 캐릭터, **짧은 갈색 보브**, 정면 — 현재 서연의 긴 머리와 다름. 사용자가 "잉??" 한 원인).
- 비전(analyze_image) 도구가 다중 패널/캐릭터를 자주 혼동했으므로, **재생성 전 사용자에게 Image #2 해석(짧은 보브, 의상 색 등)을 한 번 확인**할 것.
2. **Image #2를 `-i` 참조로 재생성**하면 gpt-image-2가 캐릭터를 그대로 따라함(텍스트 묘사 의존 X). 아트 디렉션은 2.png에 맡긴다.
## 2. 완료된 것 (재사용 가능)
- **이미지 생성**: `~/.codex/imagegen-headless/codex_imagegen.sh`(gpt-image-2, ChatGPT 구독). 검증 완료.
- **누끼**: `object-separation` 스킬(BiRefNet). 알파 정제(임계치 35/205)까지 확인.
- **파이프라인 스크립트**(`docs/avatar-art/seoyeon/`):
- `prompt-base.txt` — base 생성 프롬프트(Image #1 기준; Image #2 재생성 시 -i 참조로 대체 가능)
- `gen-variants.sh` — 표정 변주 7종(sad/tired/anxious/warm/startled/eyes-closed/speaking) 일괄 생성. base를 `-i`로.
- `cut-publish.sh` — BiRefNet 누끼 → 게시 일괄
- `publish.py` — 표준 캔버스(900×1125) 정규화 + 알파 정제. `python publish.py <컷아웃> <name>`
- `make-parts.py` — 특징 영역(UPPERFACE/EYELID/MOUTH) 크롭+페더 파츠. **영역 상수 튜너 블럭**(상단).
- **렌더러**: `apps/web/src/components/avatar/RasterBust.tsx`
- 파츠 분리: `base` + `upperface-<표정>`(눈썹+눈) + `eyelid-closed`(깜빡임, 1-blink) + `mouth-<표정>` + `mouth-open`(립싱크, RMS).
- 28표정→클러스터 매핑(`VARIANT_FOR_EXPRESSION`) 내장.
- **연결 배선**:
- `persona.ts`: `AvatarPersona.rasterArtSet?: string` 추가됨.
- `Session.tsx`: `PERSONA_AVATAR_LOOKS.P1 = { rasterArtSet: "seoyeon", expressionBias: "sad", ... }` + avatar 객체에 `rasterArtSet` 전달.
- `ClientAvatar.tsx`: `useRaster` 분기(rasterArtSet 있으면 `RasterBust`, 없으면 기존 SVG). `data-render-mode` 속성 추가.
- `App.tsx`: `/dev/avatar-preview` 라우트(인증 없음).
- **dev 미리보기**: `apps/web/src/pages/AvatarPreview.tsx`(서연 220px, speaking/sad·idle/sad·listening/warm·thinking/anxious).
- **스크린샷 도구**: `apps/web/scripts/avatar-shot.mjs` (`BASE_URL=http://localhost:<port> node ...`).
- **현재 에셋(Image #1=긴 머리 버전)**: `apps/web/public/avatar/seoyeon/{neutral,sad,tired,anxious,warm,startled,eyes-closed,speaking}.png` + `parts/`. → Image #2 재생성 시 덮어쓰기.
## 3. 남은 작업 (순서대로)
1. Image #2(2.png) 해석 사용자 확인 → ASCII 이름으로 복사: `cp "<2.png 경로>" docs/avatar-art/seoyeon/ref-image2.png`.
2. **base 재생성**(검증용 1장):
`codex_imagegen.sh --out base-v2.png --size 1024x1280 --quality high -i ref-image2.png "Use the supplied reference as the exact character. Same character, head-and-shoulders bust, perfectly front-facing, symmetrical, neutral calm expression, flat solid light gray #C9CDD2 background, no gradient/shadow/scenery, semi-realistic soft anime. No text/watermark/hands. Bangs above eyes."`
→ 결과(base-v2.png)를 사용자에게 보여주고 Image #2 일치 확인.
3. **변주 재생성**: `gen-variants.sh``BASE``base-v2.png`로 바꾸고 실행(동일 7종). → `cut-publish.sh``make-parts.py`.
4. **검증**: dev 서버(5173)의 `/dev/avatar-preview``avatar-shot.mjs`로 캡처 → 사용자 확인. 파츠 정렬이 틀리면 `make-parts.py` 영역 상수(UPPERFACE/EYELID/MOUTH) 튜닝 후 재생성.
5. **검증 게이트**(CLAUDE.md §2): `cd apps/web && npm run typecheck`. 레이아웃 변경 시 `e2e/session-layout.spec.ts`(8/8)+`e2e/layout-visual-gate.spec.ts`(7/7) — **web+api(+DB) 스택 필요**.
## 4. 환경 메모
- **dev 서버**: 5173 단일 인스턴스로 띄움(백그라운드). 끊기면 `cd apps/web && npm run dev -- --port 5173 --strictPort`. (5173/5174 중복 인스턴스가 "깨진 화면" 원인이었음 — 항상 5173 단일로.)
- codex CLI 0.142.2, auth_mode=chatgpt(구독). object-separation venv: `~/.venvs/object-separation` (CPU-only BiRefNet).
- 서연=P1은 API 시드(`apps/api/app/services/persona.py`). 웹엔 P1이 `PERSONA_AVATAR_LOOKS`에 있고 rasterArtSet="seoyeon".
## 5. 미해결/결정 필요
- Image #2 캐릭터의 **의상 색/추가 디테일** (비전 도구 불안정 → 사용자 확인 필요).
- 파츠 분리 리깅 vs 통째 변주 크로스페이드 — 사용자가 "파츠 분리"를 원했으므로 현행(파츠 분리) 유지하되, 결과가 어색하면 통째 변주 방식(`RasterBust` 이전 버전, git 히스토리 참조)으로 롤백 검토.
- 실제 Live2D Cubism(.moc3) 도입 여부는 소유자 결정(편집기 저작 필요).