IRB 게이트가 아니라 데이터/SSO 게이트로 문서 전수 정합
팀장 판정
--
-
- 로컬 회귀와 공개 prod-safe 게이트는 통과했다. -
- Cloudflare Pages production `0fe8f3cc`이 `543d48c` 소스로 배포됐다. -
- 운영 반영 전 남은 핵심 증거는 공개 Google OAuth 실제 `/turn` smoke다. -
- 런타임 mock/demo 자산은 운영 번들에서 제거하고, 테스트 fixture만 남긴다. -
Phase 0 완료 상세 목록
+이전 “완료” 카드 내용을 탭 안에서 항목별로 보존한다.
+`session-persistence`, `teacher`, `voice`는 `/api/personas`에서 실제 DB persona를 가져온다.
seed persona 직접 결합 제거, 실제 persona catalog 기반 E2E
persona 관련 E2E가 DB-backed persona로 통과
제품/UX 완료
--
-
- 학습자 홈 0회 기록 상태는 fake 기록 없이 실제 서버 세션 0개로 표시한다. -
- active session은 실제 SSE token 이벤트로 자막을 쌓는다. -
- 텍스트/음성 실패 턴은 transcript와 저장소에 남기지 않는다. -
- 375px급 active session viewport overflow를 보정했다. -
- 직접 URL persona 우회는 DB 원본 persona가 아니면 차단한다. -
- 세션 화면은 SVG persona avatar만 렌더링한다. -
prod/staging에서 dev login, seed fallback, OAuth 누락, 기본 secret, localhost CORS를 거부한다.
fail-closed runtime config validation
backend runtime policy unittest 통과
운영/테스트 완료
--
-
- seed persona 결합을 제거하고 DB persona 기반 E2E로 전환했다. -
- 비개발 런타임은 dev login, seed fallback, 기본 secret, localhost CORS를 fail-closed 한다. -
- compose OAuth/CORS/OpenAI base 설정을 API 컨테이너에 명시했다. -
- persona catalog는 비로그인 401로 인증 경계를 가진다. -
- admin 모바일 overflow, AI 운영 상태 문구, global engine config 테스트 격리를 정리했다. -
- handoff, E2E README, 이 대시보드를 최신 상태로 맞췄다. -
`ENVIRONMENT`, Google OAuth vars, `CORS_ORIGINS`, `OPENAI_BASE_URL`을 API 컨테이너에 명시했다.
compose 환경 주입 정리
`docker compose --env-file .env.example config --quiet` 통과
긴 readiness detail을 안정화했고, 사용자 변경은 DB 저장소가 durable할 때만 허용한다.
admin responsive layout, durable store gate, AI health copy
admin manage-users desktop/mobile 2 passed
`db-persistence`는 전역 engine config를 바꾸므로 `@single-run`으로 분리했다.
Playwright single-run tagging
전체 Playwright 72 passed
`docs/HANDOFF.md`, `docs/dev_dashboard.html`, `apps/web/e2e/README.md`를 최신 상태로 맞췄다.
handoff, dashboard, E2E README
최신 커밋 기준 상태/검증/운영 포트 일치
`cloudflared` ingress를 `127.0.0.1:8001` prod API로 돌렸고 public readiness gate가 통과했다.
prod API 8001, tunnel config
`https://api-vignette.chanpaca.net/health` prod/db/engine OK
`scripts/start-public-runtime.ps1`와 `scripts/stop-public-runtime.ps1`로 API 8001과 cloudflared를 재현 가능하게 만들었다.
public runtime start/stop scripts
engine 9099 + API 8001 + cloudflared only
`/personas`는 이제 비로그인 401이다. 로컬과 공개 API 모두 직접 확인했고 E2E 회귀를 추가했다.
authenticated persona catalog boundary
local/public unauth `GET /personas` 401
public 웹에서 `/api/auth/config`가 SPA HTML로 떨어지지 않도록 public API origin fallback을 추가했다.
public API origin fallback
public login screen E2E 1 passed
학습자 홈은 fake 기록 없이 실제 서버 세션 0개를 `기존 회기` 빈 상태와 0 카운트로 표시한다.
empty history UX, zero count, no fake stats
learner screenshots: document overflow 0, empty history visible
`127.0.0.1:5175` web, `8000` API, `9099` engine을 재기동하고 dev-login 서버 세션과 `/learn` redirect를 확인했다.
local dev-login flow proof
desktop/mobile auth flow passed
375px급 active session에서 stage 내부가 1px 넘게 잘리던 문제를 avatar/padding 조정으로 제거했다.
session layout responsive adjustment
session-layout desktop/mobile 8 passed
`POST /sessions/{id}/stream` token 이벤트로만 내담자 자막을 쌓고, HTTP 거절과 SSE error 모두 실패 턴을 transcript와 저장소에 남기지 않는다.
real SSE stream turn path, failed turn discard
session layout/turn E2E passed
음성 회기도 엔진 응답 생성 성공 후에만 learner/client turn을 저장한다. 실패한 transcript는 pending 상태에서 제거한다.
voice failure persistence guard
voice + voice-success + session-layout 15 passed
admin health와 voice degraded reason은 내부 fallback/seed 표현 대신 비영구 런타임 상태를 사용자용 문구로 표시한다.
operator-facing copy cleanup
settings/admin focused E2E 통과
`/learn/session/:code`로 직접 들어와도 DB 원본 persona가 아니면 회기 시작을 막는다.
route guard, degraded/seed fallback regression
unavailable persona code E2E 통과
Mao/Haru 샘플과 Pixi/Cubism 런타임을 공개 배포물에서 제거했다. 세션 화면은 SVG persona avatar만 렌더링한다.
SVG-only avatar, legacy `/live2d/*` 404 function
Mao/Haru/Cubism core routes 404, no Live2D/Pixi chunks
재기동 후 public health와 `/turn` smoke 재확인
검증 실행 결과
--
-
- Web typecheck: `npm run typecheck` passed. -
- Backend unittest: `app.test_runtime_policy`, `app.test_session_turn_persistence`, `engine_gateway.test_gateway_model` 20 OK. -
- Python compile: `python -m compileall app engine_gateway` passed. -
- Web build: `npm run build` passed. -
- Full E2E: `PLAYWRIGHT_HOST=127.0.0.1 npx playwright test` 72 passed. -
- Latest focused E2E: learner + session-layout + settings + admin 37 passed. -
공개 운영 증거
--
-
- Pages deploy: `0fe8f3cc`, source `543d48c`, branch `main`. -
- Custom domain assets: `index-D1Z5DH5J.js`, `index-BA9-xxfn.css`. -
- Public readiness: `public-auth-turn.spec.ts --grep production-safe` 1 passed. -
- Public login: `auth.spec.ts --grep public login` 1 passed. -
- Legacy Live2D routes: Mao/Haru/Cubism core 404. -
- Persona auth boundary: local/public unauth `GET /personas` 401. -
다음 실행 명령
--
-
- `npx playwright codegen https://vignette.chanpaca.net/login --save-storage=.\node_modules\.tmp\public-auth.json` -
- `$env:E2E_PUBLIC_AUTH="1"` -
- `$env:E2E_PUBLIC_STORAGE_STATE=".\node_modules\.tmp\public-auth.json"` -
- `.\node_modules\.bin\playwright.cmd test e2e/public-auth-turn.spec.ts --project=chromium-public-auth` -
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start-public-runtime.ps1` -
검증 실행 상세 표
+요약하지 않고 실행 범위, 명령, 결과를 행 단위로 남긴다.
+| 범위 | 명령 / 확인 대상 | 결과 |
|---|---|---|
| Web typecheck | npm run typecheck | Passed |
| Backend unittest | python -m unittest app.test_runtime_policy app.test_session_turn_persistence engine_gateway.test_gateway_model | 20 tests OK |
| Python compile | python -m compileall app engine_gateway | Passed |
| Web build | npm run build | Passed |
| Pages production deploy | wrangler pages deploy dist --project-name vignette --branch main | `0fe8f3cc`, source `543d48c` |
| Custom domain assets | https://vignette.chanpaca.net/ | `index-D1Z5DH5J.js`, `index-BA9-xxfn.css` |
| Legacy Live2D routes | /live2d/mao/* / /live2d/haru/* / /live2d/live2dcubismcore.min.js | 404 |
| Compose | docker compose --env-file .env.example config --quiet | Passed with dummy required env |
| Focused E2E | admin + db-persistence + voice-success | 10 passed |
| Admin manage-users | admin.spec.ts --grep manage real server-known users | desktop/mobile 2 passed |
| Full E2E | PLAYWRIGHT_HOST=127.0.0.1 npx playwright test | 72 passed |
| Public auth discovery | E2E_PUBLIC_AUTH=1 npx playwright test --list --project=chromium-public-auth | 2 tests listed |
| Public readiness | public-auth-turn.spec.ts --grep production-safe | 1 passed |
| Persona auth boundary | GET /personas | verified local/public unauth 401 |
| Public login | auth.spec.ts --grep public login | 1 passed |
| Public runtime script | scripts\start-public-runtime.ps1 | engine 9099 + API 8001 + cloudflared only |
| Public API health | https://api-vignette.chanpaca.net/health | prod, db true, engine true |
| Local 5175 login | PLAYWRIGHT_BASE_URL=http://127.0.0.1:5175 auth.spec.ts | desktop/mobile passed |
| Learner/readiness E2E | learner.spec.ts + readiness.spec.ts desktop/mobile | 14 passed |
| Learner screenshots | learn-empty-desktop.png / learn-empty-mobile-compact.png | document overflow 0, empty history visible |
| Session layout/turn | session-layout.spec.ts desktop/mobile | 8 passed |
| Voice/session focused | voice + voice-success + session-layout | 15 passed |
| Latest focused E2E | learner + session-layout + settings + admin | 37 passed |
다음 실행 명령
+남은 public OAuth `/turn` proof 확보용 명령이다.
+cd D:\workspace\vignette\apps\web +npx playwright codegen https://vignette.chanpaca.net/login --save-storage=.\node_modules\.tmp\public-auth.json + +$env:E2E_PUBLIC_AUTH="1" +$env:E2E_PUBLIC_STORAGE_STATE=".\node_modules\.tmp\public-auth.json" +.\node_modules\.bin\playwright.cmd test e2e/public-auth-turn.spec.ts --project=chromium-public-auth+
cd D:\workspace\vignette +powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start-public-runtime.ps1