Vignette 커맨드센터팀장 리뷰 · dev status
내 차례 0 2026-06-27 KST
project pulse

지금 위치: Phase 0 마감 직전 → Phase 1 진입 대기.
위기게이트 109교수자 성장 UI는 1차 구현 완료.

코어(저항·반응 조절, 상태머신, RAG, 이론모드, 가드레일, 평가 JSON Schema)는 잘 정렬됐고 회귀도 녹색이다. 막힌 건 두 종류 — 내가 실증/결정해야 풀리는 외부 의존(아래 "내 차례")과, 남은 원천문서·콘텐츠·운영 갭이다. 이 판은 그 둘을 분리해서 보여준다.

Full Playwright 72 통과 Backend pytest 122 통과 Layout 시각게이트 7/7 accept Pages prod 12da49f3 Public API prod OK 원천문서 갭 critical 3 Decision P0 조건부

당신 차례 — 이걸 풀어주면 진행이 열린다

람다가 단독으로 못 정하거나(월권), 실제 계정·하드웨어·외부 합의가 필요한 항목. 각 카드는 무엇을 막는지 · 무엇이 필요한지 · 왜 당신인지를 담았다. 팀장이 우선순위를 골라 하나씩 풀어주면 된다.

🚧 GO를 막는 블로커 0
블로커Phase 0 마감 · P1 진입

공개 Google OAuth 실제 /turn 증명

필요: 로그인 가능한 계정으로 storageState 캡처 → public-auth-turn E2E 1회 통과.

왜 당신인가: 실제 Google 계정 인터랙티브 로그인이라 자동화 불가. (owner 지시로 현재 보류 상태)

증거: public-auth.json + public /turn 성공 로그
게이트Phase 3 파일럿 · 데이터

한신대 데이터/SSO 거버넌스

필요: SSO claim 스키마, 추가 축어록 수급, 미성년 원본 활용동의, 개인정보 처리방침에 대한 한신대/데이터 steward의 written evidence.

왜 당신인가: 기관 공문·협의 영역. 로컬 문서 골격은 준비됨(hanshin-data-governance-gate.md).

🧭 소유자 결정 (DECIDE) 0
결정아키텍처·일정

백엔드 언어 (Python 유지 vs Node/Spring)

PDF는 Node.js 우선(팀 보유기술·5개월 일정)/Spring 대안. 현재 Python/FastAPI — 재작성은 일정·인력 리스크.

영향: 팀 역량·유지보수 vs 재작성 비용. 람다 단독 결정 금지.

결정Phase 3 측정

평가설계 (H1: 실험/통제군·3척도·κ/ICC)

doc4가 20명 실험/통제군·단회기 50분·3척도 pre-post를 명시. κ/ICC·환각률 목표는 doc4 미명시 — 확정 필요.

영향: 평가 타당도, Phase 3 측정력. 평가설계는 소유자 결정.

결정음성 아키텍처

s2s 2차 PoC 채택 여부

캐스케이드 1차는 확정. voice-s2s-poc.md 기준표로 비교 후 유지/폐기.

캐스케이드만 / s2s 2차 PoC 유지

결정페르소나 음성

서비스용 음성 모델·권리 정책

Higgs급 무참조 synthetic P1 샘플은 생성 완료, dev-only sample TTS provider 연결 완료. 실존 인물/성우 ref 사용 금지 확정. 서비스 배포 전 상업 라이선스·동의 ref·대체 provider 중 결정 필요.

Higgs 라이선스 / 동의 ref / 대체 TTS

결정데이터주권·레이턴시

fast-loop 외부 API 허용 여부

로컬 상주 분류기 기본 + 외부 Haiku/Solar 폴백 허용 여부.

로컬 전용 / 외부 폴백 허용

결정동의서·데이터셋

재귀학습 fine-tuning 범위

1차 few-shot 자동갱신만 vs fine-tuning 포함.

few-shot only / fine-tuning 포함

결정안전 정책

자유연습 기본값

수정안: 기본 ON + 피드백 권장 배지 + 교수자 토글.

기본 ON / 교수자 승인 후 ON

🤝 외부·임상팀 조율 0
조율위기게이트·평가·이론

임상팀 콘텐츠 (구훈정·어유경)

필요: C1 워크시트 항목·루브릭, CBT 이론별 단계 프롬프트 체인, 위기 스크립트·생명유지서약 문안, H2 평가 골든셋.

왜 당신인가: doc3 R&R상 콘텐츠는 임상팀 산출물. 코드는 '편집 가능 구조'만 선제 구축 → 조율·수급 필요.

수급평가 타당도·다양성

추가 축어록 수급 규모/일정

n=1 시드 한계 해소를 위한 추가 사례 수급 규모·일정 확정.

영향: 평가 타당도, 페르소나 다양성, Phase 3 측정력.

거버넌스계약·일정

스택 정합성·저작권 등재 (L1)

doc4 신청서 스택(Spring/Node·TimescaleDB) vs 실제 FastAPI/Python 불일치. 20주 단기일정·9월 저작권 등재 압박.

권고: 스택 정합 또는 변경사유 거버넌스 기록.

진행 현황

아래 "상태 보드"의 작업 카드에서 자동 집계. 완료/진행/계획 비율과 트랙별 완료도. (Phase 진행률은 단계별 증거 기반 추정치 — 정밀 수치 아님)

상태 분포

추적 작업 0건 기준

완료 0 진행 0 계획·블로커 0

트랙별 완료도

카테고리별 완료 카드 / 전체 카드

관계도 — 무엇이 무엇을 막는가

왼쪽 내 차례(clay) 노드를 풀면 가운데 게이트/작업이 열리고, 오른쪽 납품·마일스톤으로 이어진다. 화살표를 따라가면 "내가 지금 풀어야 임계경로가 뚫리는 것"이 보인다.

내 차례 (OWNER) 게이트 · 작업 납품 · 마일스톤 OAuth /turn 증명 백엔드 언어 결정 임상팀 콘텐츠 평가설계 (H1) 한신대 거버넌스 Phase 0 마감 Phase 1 MVP 위기게이트 1091차 구현 · 검증 교수자 성장 UI1차 구현 · 검증 평가 KPI (H1) Phase 1 GO 납품 필수조건법적 생존선 Phase 3 파일럿
내 차례 — 윤찬이 풀어야 열림 납품 필수 — 미구현 임계작업 게이트·마일스톤 ··· 점선 = 약한/아키텍처 의존

디자인 시안 지침 — 기능 추출 기반 이미지 생성

2026-06-27 기준 주요 페이지 기능을 추출해 PC·태블릿·모바일 반응형 시안 7장과 온화한 이미지 요소 보드 2장을 만들었다. 결과물은 전부 PNG 래스터 이미지이며, 구현 확정안이 아니라 레이아웃·톤·이미지 요소 판단 기준이다.

프롬프트 문서

적용 원칙: 생성 이미지 안의 문구는 참고하지 말고 실제 카피는 코드/기획서 기준으로 다시 쓴다. 세션 아바타는 기존 서연/P1 아바타 핸드오프와 `rasterArtSet` 지침을 우선한다. 교수·관리자 내비게이션은 현재 `AppShell`·`Sidebar` 구조를 유지하고, 배경 일러스트·패턴은 빈 상태·히어로·세션 주변 질감에 소량만 쓴다.

1차 적용(2026-06-27): 온화한 이미지 요소 보드는 구현 참고용으로만 두고, 앱 배경에는 전용 래스터 텍스처 `apps/web/public/design-elements/clinical-paper-ambient.png`를 연결했다. 보드·타일셋·누끼 시트 형태 이미지는 직접 UI 배경으로 쓰지 않는다.

2차 적용(2026-06-27): 생성된 관리자/설정/리뷰 시안 기준으로 admin 역할의 상단바·사이드바를 어두운 운영 콘솔 크롬으로 전환했고, 관리자 사용자 관리 행을 조밀한 운영 테이블 밀도로 낮췄다. 회기 리뷰는 헤더·인사이트 카드·피드백 스테이지에 따뜻한 래스터 질감과 낮은 채도 틴트를 적용했다.

3차 적용(2026-06-27): 상담 세션 시작/진행 화면을 시안 기준의 어두운 상담 스테이지로 재정렬했다. 시작 전 화면은 내담자 무대·브리핑·진행 초점 3영역으로 유지하고, 진행 중 화면은 어두운 캔버스 위에 중앙 스테이지와 자막/컨트롤을 배치한다.

4차 적용(2026-06-27): 교수 콘솔은 시안의 triage 콘솔 구조에 맞춰 KPI를 전폭 6칸으로 재배치하고, 종료 회기 검토 큐와 최근 회기 기록을 첫 화면 2열 핵심 영역으로 올렸다. 성장 추적·페르소나 저작·검수 보조 큐는 하단 보조 업무로 낮췄고, 교수자 사이드바는 좁은 teal rail로 전환했다.

5차 적용(2026-06-27): 회기 리뷰는 시안의 좌·중·우 작업대 구조에 맞춰 요약/액션 레일, 감정·흐름 중앙 영역, 우측 인사이트 패널로 재배치했다. 모바일에서는 트랜스크립트를 워크시트보다 먼저 노출하고, 사례개념화 워크시트는 제한 높이의 보조 패널로 낮춰 긴 문서처럼 보이지 않게 했다.

6차 적용(2026-06-27): 설정 화면은 글로벌 셸을 숨기고 설정 전용 좌측 레일을 주 내비로 승격했다. 계정, AI 운영, 테마, 음성, 알림 카드를 시안의 차분한 설정 워크스페이스 흐름에 맞춰 단일 컬럼으로 재배치했고, 모바일은 상단 고정 섹션 탭으로 모든 항목이 잘리지 않게 정리했다.

7차 적용(2026-06-27): 로그인 화면은 별도 생성한 래스터 상담실 배경(login-counseling-room.png)을 왼쪽 브랜드 패널에 적용해 시안의 실제 상담실 분위기를 반영했다. 학습자 홈은 모바일 grid 행 계산 때문에 생기던 리스트-상세 간 큰 공백을 제거하고, 회기 준비 보드가 한 흐름으로 이어지게 정리했다.

래스터만 사용이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.
기능 우선메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.
온화하지만 임상적종이 질감, 낮은 채도, 차분한 빛은 허용하되 상담 훈련 도구의 신뢰감을 먼저 세운다.
반응형 세트각 핵심 화면은 한 장 안에 PC·태블릿·모바일을 함께 배치해 전환 규칙을 비교한다.
화면추출한 핵심 기능디자인 의도
로그인/진입Google OAuth, 허용 도메인 안내, 로컬 역할 선택, 교육용 비치료 고지신뢰·보안이 먼저 보이는 조용한 진입 화면
학습자 홈내담자 선택, 주호소·난도·접근·음성 정보, 새 회기 시작, 기존 회기 이어가기오늘 시작할 연습이 명확한 상담 연습 작업대
상담 세션회기 단계, 내담자 컨텍스트, 아바타, 음성 오브, 실시간 자막, 텍스트 폴백, 안전 점검화면 중심은 내담자, 피드백은 조용한 신호
회기 리뷰요약, 감정 밸런스, 회기 흐름, 축어록, 기법 태그, 개선점, 오디오/PDF점수 폭격이 아니라 근거 기반 회고
교수 콘솔리뷰 대기 큐, 코호트 현황, 페르소나 검수, 종료 회기 목록awareness보다 triage에 가까운 교수자 작업대
관리자 콘솔서비스 상태, 엔진·DB·음성·리뷰 리소스, 사용자 등록·수정·비활성화시스템 건강성과 권한 관리가 한눈에 보이는 운영 화면
설정계정, 관리자 AI 운영 설정, 테마, 음성 프리셋, 속도, 알림역할별 설정만 보이는 조용한 환경 관리
이미지 요소종이 질감, 상담실 책상, 노트, 식물, 부드러운 빛, 패턴, 아바타 분위기UI 뒤에서만 느껴지는 따뜻함과 반구상 내담자 톤

상태 보드

현재 추적 중인 작업을 카드로. 요약만 노출되고, 상세 근거·검증 로그는 카드를 펼쳐야 보인다. 필터로 "내 차례"·블로커만 추려 볼 수 있다.

필터

한신대 PDF 정합성 · 이번 세션 발견

원천 기술분석 PDF(트웬티온스×한신대, 19쪽) 전수 정독 대조 (2026-06-27)
현재

PDF가 차별 기술로 꼽은 '저항·반응 조절'(AI가 너무 착하지 않게, 실제 환자처럼)·상태머신(라포→탐색→개입→정리)·RAG(자료검색)·이론모드(인간중심/CBT)·답변과 분리된 가드레일·SSE 스트리밍·React19·피드백 JSON Schema 강제(벤더중립)가 이미 구현·정렬됨. Stanford RCT(피드백 없는 연습=역효과)도 H2 턴평가로 충족 방향.

권고

이 코어를 '교육용(비의료)' 포지션으로 유지. 평가는 교수자 검토용 보조지표로 표기.

현재

라이브 테스트에서 수련생이 내담자를 "수동적 패배자"라 비난·조롱("웃음이 나오십니까")해도 민재가 공손히 흡수 → 훈련 가치 훼손. 수정: ① L0에 무례·모욕·조롱·인신공격 시 현실적 동맹 균열(위축·방어·따지기·종결의향) 지침 ② PersonaCard.triggers(역린) 필드 + CCD 핵심상처 파생 역린 블록(상담자가 핵심상처를 조롱·확정·강요·평가절하 시 가장 강한 반응). PDF '저항·반응 조절' 핵심 차별 강화. 무회귀 77/77.

잔여

P1~P3 명시 triggers는 임상팀 정밀 저작(현재 CCD 파생 기본값으로 작동). 라이브 재현 검증.

현재

PDF(9·16·18쪽): 자해·자살 감지 시 대화 중단 + 자살예방상담 109 안내 + 지도교수 자동 알림, 안전은 LLM 밖 별도 CrisisGate. 구현: CRISIS_HOTLINE_NUMBER=109, TurnResponse.crisis_resource/conversation_stopped, REST·SSE·voice 경로의 엔진 호출 전 중단, app.safety_events detail 적재, 교수자 대시보드 안전 알림 큐.

검증

pytest app/test_session_turn_persistence.py app/test_voice_ws.py -q 20 passed, 안전 이벤트 DB insert payload 테스트 포함. pytest app/test_teacher_dashboard.py app/test_session_turn_persistence.py app/test_voice_ws.py -q 21 passed.

잔여

비밀보장 예외고지·생명유지서약 등 임상 문안, 실시간 push/메일 알림, 지역 자원 확장, 운영 정책 문구는 소유자·임상팀 확정 필요. 현재 교수자 알림은 safety_events 기반 대시보드 큐다.

현재

TeacherDashboardResponse.learner_growth를 추가해 턴별 fast-loop 평가의 appropriateness, rapport_signal, 기법 태그를 학습자별로 집계한다. 교수 콘솔은 학습자별 성장 카드, 회기별 막대 추이, 평균 라포, 변화폭, 최근 회기 점검 포인트를 표시한다. 평가가 없는 회기는 "평가 부족"으로 남겨 가짜 곡선을 만들지 않는다.

검증

pytest app/test_teacher_dashboard.py app/test_session_turn_persistence.py app/test_voice_ws.py -q 21 passed, pytest app/ -q 119 passed, npm run check:api-types, npm run typecheck passed.

잔여

자기효능감·기술숙련도·수련만족도 사전사후(H1)와 교수자 코멘트/검수 워크플로 확장은 별도 평가설계·임상팀 문항 확정이 필요하다.

현재

① PDF: 고성능(Claude·GPT=내담자발화·실시간평가)/저비용 한국어(Solar=단순응답·사후요약) 2단계 + 캐싱 90%절감. 현재 client AI는 claude_cli 기본 라우팅, fast/deep evaluator는 EVALUATOR_FAST_MODEL/EVALUATOR_DEEP_MODEL 설정 시 모델 override를 gateway에 전달한다. 벤더중립 인터페이스와 L0~L2 cache hint/session reuse는 있음. ② PDF는 Node.js 우선(팀 보유기술·5개월 일정)/Spring 대안. 현재 Python/FastAPI — 재작성은 일정·인력 리스크.

권고

2-tier는 evaluator 모델 override 이후 client AI/요약 모델 정책과 semantic cache로 점진 도입. 백엔드 언어는 소유자 결정(팀 역량·유지보수 vs 재작성 비용).

현재

페르소나 격리(캐릭터 붕괴 버그)·RAG 비차단(세션생성 블로킹 회귀)·역린/misconduct·init_state 파라미터객체·데드코드(LogHook·tier·RMS)·OAuth state 복구·X1 dataset export dry-run — 백엔드 122 + E2E 42(데스크27·모바일11·아바타4) + 시각게이트 7/7 통과. 스택 라이브(web·api·gateway·voice·RAG).

다음

남은 원천문서 갭과 임상 콘텐츠 적재를 순서대로 닫는다.

원천문서 갭 분석

산학협력 원천문서 5종 정독 + 코드 교차조사 (2026-06-26). 근거: source-docs-gap-analysis-2026-06-26.md · critical 3 / high 4 / medium+ 6
현재

doc1/4/5가 1급 산출물로 요구하는 워크시트 축(탐색 11항목·호소 5영역·인지삼제·1/2차 감정·보호/방해 4사분면·생물심리사회 목표)을 SessionReviewResponse.caseWorksheet로 노출한다. 서버는 저장된 축어록만 근거로 규칙 기반 초안을 만들고, 프론트 리뷰 화면은 근거 턴으로 점프 가능한 read-only 워크시트 카드를 표시한다.

검증

pytest app/test_session_turn_persistence.py -q 15 passed, pytest app/ -q 119 passed, npm run check:api-types, npm run typecheck, session-review.spec.ts 1 passed.

잔여

편집·DB 저장형 워크시트, 임상팀 루브릭, AI 추출/채점, 교수자 검수 플로우는 후속이다. 현재 초안은 숨은 추론이나 임상 점수 없이 축어록 근거가 있는 항목만 채운다.

현재

prepare_turn→state_machine.evolve에 crisis.risk_level을 ideation_observed로 전달(위기 관측 상태머신 반영). escalate=True 시 REST·SSE·voice가 엔진 호출 전 중단하고 app.safety_events에 109 resource와 conversation_stopped를 적재한다. 교수자 대시보드는 이 레코드를 안전 알림 큐로 표시한다. 안전 이벤트 insert payload는 test_record_safety_event_writes_teacher_alert_payload로 회귀화했다.

잔여(임상팀)

비밀보장 예외고지·단계적 탐색·생명유지서약 스크립트 콘텐츠 + 실시간 교수자 push/메일 + 위기탐색 누락 회기리뷰 감점.

현재

TurnContext+prepare_turn에 theory_mode, sessions/voice가 sess.theory_mode 전달, evaluator._theory_mode가 세션 이론(학습자 선택) 우선. build_turn_messagesTHEORY_MODE_GUIDANCE를 통해 인간중심·CBT·통합 이론 프레이밍을 엔진 메시지에 넣는다. 프론트 Session.tsx 'humanistic' 하드코딩 제거→persona.theory_target 기준(CBT 페르소나는 cbt). 회귀: test_prepare_turn_threads_theory_mode_into_engine_messages 포함 focused 20 passed.

잔여(임상팀)

CBT 이론별 단계 프롬프트 체인 콘텐츠 + 이론부합 채점 루브릭 + 프론트 이론 선택 UI(현재 persona 설계 이론 자동).

현재

doc4가 20명 실험/통제군·단회기 50분·3척도 pre-post를 못박았으나 코드 0건. Phase3 KPI도 report shape만, 계산 코드 0줄. (κ/ICC·환각률은 doc4 미명시 — 평가설계 문서 확정 필요.)

권고

3척도 pre-post 폼·실험/통제군 배정·자동누적 대시보드·추이 시각화·검정 계산 코드. 평가설계는 소유자 결정.

현재

텍스트 /turn·/stream·음성 경로에서 fast-loop 턴 평가를 TurnRecord.evaluation에만 남기지 않고 app.feedback_scores, app.turn_technique, app.turn_client_state, app.supervisor_comment, app.alternative_utterance로 정규화 적재 후 리뷰 조회에서 hydrate한다. 원시 평가 테이블은 evaluator/admin RLS로 제한하고 서버가 evaluator 컨텍스트로 적재한다. app.turns insert도 RETURNING id 확인으로 0-row silent success를 차단. 검증: pytest app/test_evaluation_persistence.py -q 6 passed, pytest app/test_session_turn_persistence.py app/test_evaluation_persistence.py -q 21 passed, pytest app/ 119 passed + pytest engine_gateway/ 7 passed.

잔여

더 큰 finalize_turn/SessionRepository 경계 · few-shot 골든셋 기본 OFF · 회기리뷰 2열 UI(축어록 타임라인+비언어) 프론트 강화 · 원천 축어록 골든셋 적재(임상팀).

현재

POST/GET/PUT /personas/drafts를 추가해 teacher/admin이 페르소나 카드를 draft로 생성·조회·편집하고 review 상태로 올릴 수 있다. 교수 콘솔에는 JSON 초안 패널과 검수 큐의 편집 불러오기를 연결했다. 승인된 카드만 학습자 catalog에 노출되는 기존 경계는 유지.

검증

pytest app/test_persona_review.py -q 19 passed, pytest app/ -q 119 passed, npm run check:api-types, npm run typecheck, npm run build passed.

잔여

P4~P7 실제 임상 콘텐츠 적재, JSON 대신 항목형 저작 UI, 루브릭·이론 콘텐츠 외부화는 후속. 임상팀이 제공하지 않은 페르소나 내용을 임의 생성하지 않는다.

현재

정규식 폴백에 한국어 고위험 패턴 추가: 구체 날짜(2001.4.18→[DATE])·금액(1200원→[MONEY])·행정구역 주소(서울시 강남구 역삼동→[ADDR]). 상담 생성(generate/stream)·fast/deep 평가의 외부 LLM 호출 직후 audit.llm_call_log에 provider/model/token/cost/inference_geo/latency만 적재한다. prompt/completion 본문은 저장하지 않는다. 로컬 dev-login 실제 /turn smoke에서 audit.llm_call_log가 8→11로 3행 증가했다. 이번 패스에서 app_user.consent_at 기반 learner 전용 동의 수락/철회 API와 회기 시작·voice dev persona 시작 하드게이트를 추가했고, 세션 시작 전 프론트 동의 UI와 E2E seed를 연결했다. 검증: 동의/세션/음성 회귀 64 passed, 전체 API 125 passed, npm run check:api-types, npm run typecheck, npm run build.

잔여

이름/기관명은 NER 필요(Presidio ko 모델·spaCy ko, 무거움 — TODO 명시). 미성년/guardian 및 법무 검토가 필요한 서명 동의서·개인정보 고지 evidence는 외부 게이트다. 공개 Google OAuth 실제 /turn proof는 별도 운영 게이트.

현재

M1: voice learner turn의 audio_ref, silence_ms, speech_rate, barge_in을 리뷰 API nonverbal 이벤트로 파생하고, 회기 리뷰 축어록에 침묵·발화 속도·끼어듦·음성 입력 칩으로 표시한다. 한숨·울음 감지와 live 마이크/STT/TTS 실측은 아직 별도다. M2: case_profile을 learner-persona 안정 case로 upsert하고, session_no를 트랜잭션 안에서 원자 증가시키며, 시작/턴/voice 경로가 직전 session_summary 기반 seed recall을 사용한다. episodic embedding writer와 case_digest/pinned_fact 실적재는 후속. M3: Google/SAML/dev-login이 AUTH_EMAIL_COHORT_MAP/AUTH_DOMAIN_COHORT_MAP 및 SAML cohort claim을 cohort_ids로 전달하고, DB app_user.external_id는 provider subject(google:/saml:/dev:) 기반으로 저장한다.

권고

M1 한숨·울음/억양 등 provider 이벤트 보존, M2 session_summary digest/pinned_fact 압축·embedding writer·case_profile trajectory 갱신, M3 운영 SAML 서명검증·기관 claim schema/test tenant·deprovisioning audit는 외부 IdP 협의 후 진행.

현재

X1: scripts/export-recursive-dataset.pyapp.services.dataset_export로 masked-text JSONL dry-run, PII scan, κ/ICC 계산, approved export 게이트를 구현했다. 기본은 technical_dry_run이고 ds.* write는 --write-dataset 명시 시에만 수행한다. X2: app.turns의 provider/model/tokens/cost를 최근 7일 기준으로 집계하는 GET /admin/usage를 추가했고, 운영 콘솔 /admin에 누적 비용·입출력 토큰·계량 커버리지·provider/model breakdown과 ADMIN_USAGE_BUDGET_USD 기반 예산 경고(ok/warn/exceeded)를 표시한다. EVALUATOR_FAST_MODEL/EVALUATOR_DEEP_MODEL 설정 시 fast/deep 평가 호출만 해당 모델 override로 gateway에 전달하고, 비워두면 기존 default 라우팅을 유지한다. DB 미가용 dev에서는 runtime store로 fallback하지만 prod에서는 fail-closed한다. L1: doc4 신청서 스택(Spring Boot 3/Node.js·TimescaleDB) vs 실제 FastAPI/Python 불일치, 20주 단기일정·9월 저작권 등재 압박.

권고

X1 approved export·골든셋 승격은 steward/legal 승인, reviewer disposition, IAA 게이트(κ≥0.6/ICC≥0.75) 이후만 진행한다. X2 후속은 semantic cache·장기 비용 추이/한도 정책·운영 모델별 비용 검증, L1은 스택 정합 또는 변경사유 거버넌스 기록.

즉시 착수 가능(내부 코드, 외부 합의 불요)

  • C1/C2/C3/H2/H3은 1차 구조 완료. 후속은 저장형 워크시트, 임상 스크립트, CBT 체인, 2열 리뷰 UI, P4~P7 콘텐츠 적재처럼 데이터·정책·UI 고도화 영역이다.
  • H4(부분): 한국어 정규식 마스킹, metadata-only LLM call audit 경로, 로컬 live row proof, learner 동의 수락/철회/회기 시작 하드게이트 골격은 완료. 남은 내부 후보는 이름/기관 NER이고, guardian/legal 서명 동의 evidence는 외부 게이트다. X1 dry-run export 1차와 X2 비용 관측·예산 경고/evaluator 모델 override 1차는 완료, X2 semantic cache는 후속. M1/M2/M3 1차는 완료, provider 기반 한숨·울음 감지와 case_digest/pinned_fact 실적재, 운영 SAML 서명검증은 후속.

소유자 결정 / 외부(임상팀·기관) 의존

  • 임상팀 산출물: C1 워크시트 항목·루브릭, C3 CBT 콘텐츠·체인, C2 위기 스크립트·서약 문안, H2 골든셋 코딩.
  • 소유자 평가설계: H1 실험/통제군·3척도 문항·50분 흐름, κ/ICC·환각률 목표(doc4 미명시).
  • 기관(한신 IT): M3 SSO IdP·test tenant·claim 스키마·인증서, 거버넌스 증거.
  • 거버넌스: L1 스택 정합성 방향·저작권 등재 문서화·IP 협의.

판독 한계 (정직성)

  • 핵심 축어록 2단 표는 PDF 시각 판독이 1차 근거(txt 일부 누락), OCR 잔재 존재.
  • doc4 κ/ICC·환각률은 신청서 본문 미명시 — 계약 확정 지표로 단정 금지.
  • '현재상태'는 grep/코드 사실 기반. C1~C3·H2·H3은 직접 재확인(✓), 그 외는 착수 전 코드 1차 재확인 권고.

코드품질 · 로컬 개발 스택

리팩토링 연구 + 1-커맨드 dev 스택 (2026-06-26~27). code-quality-research-2026-06-26.md · local-development.md
현재

게이트웨이(9099 claude_cli)+API(8000, DB 미가용 시 in-memory degraded)+웹(5173)을 커맨드라인 기준 정리 후 결정론적 기동(--reload 워처 불안정 회피, uvicorn 있는 python 자동 해석). Docker가 사용 가능하면 vignette-dev-db healthcheck/pg_isready/role safety를 점검하고, compose infra\.env 필수값 누락도 경고한다. -NoGateway/-NoWeb는 해당 컴포넌트 정리도 건너뛰고, API 정리는 지정 -ApiPort만 대상으로 한다. dev-login + seed 페르소나. 로그 .devlogs/(gitignore). 검증: 3포트 health OK + 실제 AI 턴 생성·회기리뷰 동작, API-only 재기동 후 8001/8010/5173/9099/20241 보존.

비고

AI 턴은 로컬 claude CLI 사용(사용량 발생). 진입점 http://localhost:5173. dev-down.ps1은 기본적으로 DB 컨테이너를 보존하고, -Db 지정 시 함께 중지한다. 기존 vignette-dev-db는 accepting connections이나 healthcheck가 없고, vignette_app은 NOBYPASSRLS로 존재하지만 현재 API startup DDL은 owner 권한이 필요해 런타임 app-role 분리는 후속이다. 주의(무DB 한정): DB 없이 degraded면 페르소나가 source:seed_fallback·degraded:true라 프론트 isUsablePersona가 막아 "회기 시작" 버튼이 비활성 → UI 세션 시작엔 실제 Postgres(127.0.0.1:55432)가 필요.

현재

직접 WS 재현으로 근본원인 규명: 키 없으면 백엔드가 degraded+1011 즉시 close → 마이크 깜빡·녹음 미도달. STT(gpt-4o-transcribe)·TTS(gpt-4o-mini-tts) 모두 OpenAI. 실 OPENAI_API_KEY를 apps/api/.env(gitignore)에 설정 → /voice/health available:true(degraded-close 사라짐). 백로그 B2 음성 캐스케이드가 로컬에서 실작동.

부수 수정

① 미설정 시 마이크 버튼 사전 비활성+명확 안내 ② TTS 지문 제거: (고개 끄덕)·(한숨)·[침묵] 등 무대지시를 음성으로 안 읽음(speakable_text, 자막엔 유지) ③ 아바타 애니메이션: 텍스트 턴 speaking 시 입 정지(0) 버그 수정 + thinking 표현 보강. typecheck+voice테스트 PASS.

증상

라이브 회기에서 내담자(민재)가 "저는 Claude Code인데… Vignette 코드베이스… git status…"로 캐릭터를 깨고 개발 맥락 노출. 원인: ENGINE_MODE=claude_cli가 로컬 claude(=Claude Code)를 호출하는데 게이트웨이가 페르소나를 --append-system-prompt로 코딩 어시스턴트 정체성에 덧붙이고, cwd=repo라 CLAUDE.md·git status·env가 시스템프롬프트에 포함됨.

수정·검증

engine_gateway/gateway.py: --append-system-prompt--system-prompt(페르소나만 교체 주입) + --exclude-dynamic-system-prompt-sections(cwd/env/git/메모리 섹션 제거). 라이브: 깨던 입력 그대로 → 민재 완벽 인캐릭터, 누출 0. 게이트웨이 7/7 + 전체 API 119 passed.

현재

app/turn_runtime.py를 추가해 load_owned_session, record_completed_turn, append_completed_turn, update_session_state, record_safety_event를 공통화했다. routes/sessions.py의 submit/stream과 routes/voice.py가 같은 저장·위기 이벤트 경로를 사용하고, stream fast-loop 평가 누락도 닫았다. voice 경로도 세션 recall cache를 사용한다. 검증: 관련 회귀 45 passed, 전체 API 119 passed, gateway 7 passed.

잔여

더 큰 finalize_turn/SessionRepository 경계, 장기적으로는 세션 저장소 인터페이스 SSOT화가 남아 있다.

현재

apps/api/scripts/export-openapi.pyapps/web/scripts/generate-api-types.mjs로 FastAPI OpenAPI를 apps/web/src/lib/api.gen.ts에 생성한다. npm run check:api-types가 재생성 누락을 잡고, TurnResponse/SessionEndResponse는 생성 타입 alias를 사용한다. 기존 누락 필드 crisis_kind, end_state, crisis_resource, safety_alerts, learner_growth, PersonaDraftPayload는 생성 타입에 포함된다. 검증: npm run check:api-types, npm run typecheck, pytest app/ 119 passed, pytest engine_gateway/ 7 passed.

잔여

나머지 수기 미러 타입(PersonaSummary, review/admin/teacher/user DTO 등)을 생성 타입 alias로 점진 전환하고, 실제 CI 워크플로에 npm run check:api-types를 연결해야 한다.

현재

LogHook/log_hook(caller 0) 타입·파라미터·분기·export 제거 · 게이트웨이/엔진클라 tier dead-contract 제거(write-only, gateway는 model만 사용). 잔여(RMS 힌트·P4~P7·Live2D 고아 자산·파라미터객체 init_state/prepare_turn/upsert)는 docs/ops/refactor-rag-patches-2026-06-26.{md,json}에 스테이징(단계 적용).

참고

일괄 적용 대신 라이브 스택 보호 위해 그룹별 적용+pytest 검증.

현재

임베더 BGE-M3 검증+버전핀(1.4.0 dtype버그→1.2.11/transformers 4.44.2). embed_query를 asyncio.to_thread로 offload. 턴 파이프라인 배선: retrieve_persona_memory→episodic recall, search_kb→kb_behavior_cues. KB seed 3청크 적재. rag.py latent 버그 3건 수정. GraphRAG는 2차 보류.

성능 회귀 수정

최초 RAG 배선이 회기 시작/턴에 임베더 로드(~7-13s)를 동기 awaitPOST /sessions가 막힘 → session-layout E2E 4건 타임아웃. 수정: 회상·KB 회수를 _warm_rag_caches 백그라운드 task로 옮기고 턴은 캐시만 읽음(비차단). 이번 동의 게이트 E2E 재검증 중 여러 세션 warm task가 BGE-M3를 동시에 지연 로드해 API health/dev-login timeout이 반복된 문제는 embedder load/encode RLock과 warm semaphore 1개로 안정화했다. 재검증: session-layout 4/4 + 핵심 E2E 27/27·11/11·아바타 4/4, 최신 layout/session 조합 11/11 통과.

시각 게이트

admin 1280 input "text-clipped-x" 1건은 폼 input 값 스크롤(설계상 정상) 오탐 — form 컨트롤을 text-clip 판정에서 제외 → 게이트 7/7(실 결함 검사 유지).

심층 상세 · 검증 로그

로드맵 단계표, 단계별 상세 작업·검증 명령 표, 이번 세션 내러티브. 기본 접힘 — 필요할 때만 펼쳐서 본다.

전체 개발 로드맵 (5단계)MASTERPLAN + REVISIONS
Phase 0closing

기반 정렬 / 운영 안전장치

인프라, 인증 경계, fail-closed, 공개 배포, 회귀 테스트 안정화.

  • 상태: 대부분 완료, 공개 /turn proof만 남음
  • 검증: build + backend 84 + Playwright 72
  • 운영: prod API 8001, engine 9099, tunnel 1개
Phase 1next

MVP 코어 루프

1 페르소나 상담, 실제 턴 저장, 회기말 피드백, 저항 엔진 검증.

  • DoD: 로그인 → P1 상담 완주 → 피드백 수신
  • 추가: 음성 왕복 1턴 PoC 포함
  • 증거: cost/turn DB 적재 + openness 곡선 대조
Phase 2aplanned

3역할 / OAuth / 페르소나

학습자, 교수자, 관리자 권한 분리와 페르소나 확장.

  • DoD: 타인 session 직접 접근 403
  • 범위: OAuth BFF, RBAC, 교수 검수 루프
  • 주의: visible_to와 인간 권한은 별도 레이어
Phase 2bplanned

음성 캐스케이드

STT → 엔진 → TTS 왕복, WSS/터널 안정성, barge-in 로깅.

  • DoD: 50분 WSS 끊김 실측
  • 범위: Deepgram STT, OpenAI TTS, voice preset
  • 리스크: 실시간 레이턴시는 실측 전 완료 표기 금지
Phase 3planned

교육용 파일럿 / 효과성

수련생 파일럿, 사전사후 효과 측정, 재귀학습 데이터셋 산출.

  • DoD: 20명 완주 + KPI 충족
  • 측정: SUS, 자기효능감, κ/ICC, 환각률
  • 정정: IRB 게이트가 아니라 데이터 활용동의/개인정보 게이트
정정 기준: MASTERPLAN 원본의 IRB 신청/승인 게이트는 MASTERPLAN_REVISIONS 기준으로 제거한다. Phase 2는 2a(3역할/OAuth/페르소나)와 2b(음성 캐스케이드)로 분리하고, Phase 1 DoD에는 얇은 음성 왕복 1턴 PoC를 포함한다.
단계별 상세 작업 · 검증 명령 표P0~결정 / 검증 50+행

Phase 0 마감 상세

지금 단계는 구현을 더 벌리는 단계가 아니라, 운영 증거를 닫고 P1 진입 조건을 고정하는 단계다.

상태: 조건부우선순위: P0블로커: public /turn
BLOCK
공개 Google OAuth 실제 /turn proof 확보

로그인 가능한 계정으로 storageState를 저장한 뒤 public-auth-turn E2E를 실행한다.

산출물

apps/web/node_modules/.tmp/public-auth.json, public /turn 성공 로그

검증

E2E_PUBLIC_AUTH=1 + chromium-public-auth 1회 통과

DONE
engine config 운영값 재확인

GET /admin/engine-config로 운영값을 직접 확인했다. engine_mode=claude_cli, engine_url=http://127.0.0.1:9099, model=gateway-default, durable=true, source=database로 의도값과 일치한다.

산출물

config API 응답(durable, db source)

검증

claude_cli / http://127.0.0.1:9099 / gateway-default 의도값 대조 완료

DONE
과거 Live2D demo 자산 제거

Mao/Haru 샘플, Pixi/Cubism 런타임, 공개 /live2d/* 캐시 잔여 접근을 차단했다.

산출물

apps/web/functions/live2d/[[path]].js, P1 PSB raster avatar + SVG fallback

검증

운영 /live2d/mao/*, Cubism core 404

DONE
프로세스 난립 정리

운영 확인용 프로세스와 로컬/Tailnet 검증용 dev 프로세스를 의도적으로 분리해 유지한다.

산출물

9099 engine, 8001 prod API, 8000/8010 dev API, 5173 web, cloudflared tunnel 1개

검증

Get-NetTCPConnection에서 대상 포트별 listener 확인

GATE
한신대 공문/데이터 거버넌스 게이트 정리

SSO 클레임, 추가 축어록 수급, 미성년 원본 활용동의, 개인정보 처리방침을 P1 진입 전 외부 의존성으로 명확히 둔다. 로컬 문서 골격은 준비됐지만 한신대/데이터 steward의 written evidence는 아직 필요하다.

산출물

docs/ops/hanshin-data-governance-gate.md, 공문 질의 항목, 동의 범위 체크리스트, SSO claim mapping 표

검증

문서 artifact 작성 완료; IRB 게이트가 아니라 데이터/SSO 게이트로 외부 증거 필요 상태 유지

팀장 판정: 로컬 회귀와 공개 prod-safe 게이트는 통과했다. Cloudflare Pages production 12da49f3이 commit 0ec266a dist로 배포됐고, 운영 반영 전 남은 핵심 증거는 공개 Google OAuth 실제 /turn smoke다. 런타임 mock/demo 자산은 운영 번들에서 제거하고 테스트 fixture만 남긴다.

Phase 0 완료 상세 목록

이전 "완료" 카드 내용을 탭 안에서 항목별로 보존한다.

DONE
DB persona 기반 테스트

session-persistence, teacher, voice/api/personas에서 실제 DB persona를 가져온다.

산출물

seed persona 직접 결합 제거, 실제 persona catalog 기반 E2E

검증

persona 관련 E2E가 DB-backed persona로 통과

DONE
비개발 런타임 보호

prod/staging에서 dev login, seed fallback, OAuth 누락, 기본 secret, localhost CORS를 거부한다.

산출물

fail-closed runtime config validation

검증

backend runtime policy unittest 통과

DONE
compose OAuth 주입

ENVIRONMENT, Google OAuth vars, CORS_ORIGINS, OPENAI_BASE_URL을 API 컨테이너에 명시했다.

산출물

compose 환경 주입 정리

검증

docker compose -f infra\docker-compose.yml --env-file infra\.env.example config --quiet 더미 필수 env 세트로 통과

DONE
admin 모바일 overflow 수정

긴 readiness detail을 안정화했고, 사용자 변경은 DB 저장소가 durable할 때만 허용한다.

산출물

admin responsive layout, durable store gate, AI health copy

검증

admin manage-users desktop/mobile 2 passed

DONE
global engine config 테스트 분리

db-persistence는 전역 engine config를 바꾸므로 @single-run으로 분리했다.

산출물

Playwright single-run tagging

검증

전체 Playwright 72 passed

DONE
handoff와 문서 갱신

docs/HANDOFF.md, docs/dev_dashboard.html, apps/web/e2e/README.md를 최신 상태로 맞췄다.

산출물

handoff, dashboard, E2E README

검증

최신 커밋 기준 상태/검증/운영 포트 일치

DONE
공개 API prod 전환

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

DONE
공개 런타임 재기동 스크립트

scripts/start-public-runtime.ps1scripts/stop-public-runtime.ps1로 API 8001과 cloudflared를 재현 가능하게 만들었다.

산출물

public runtime start/stop scripts

검증

engine 9099 + API 8001 + cloudflared only

DONE
persona catalog 인증화

/personas는 이제 비로그인 401이다. 로컬과 공개 API 모두 직접 확인했고 E2E 회귀를 추가했다.

산출물

authenticated persona catalog boundary

검증

local/public unauth GET /personas 401

DONE
public API base fallback 보강

public 웹에서 /api/auth/config가 SPA HTML로 떨어지지 않도록 public API origin fallback을 추가했다.

산출물

public API origin fallback

검증

public login screen E2E 1 passed

DONE
학습자 홈 0회 기록 상태

학습자 홈은 fake 기록 없이 실제 서버 세션 0개를 기존 회기 빈 상태와 0 카운트로 표시한다.

산출물

empty history UX, zero count, no fake stats

검증

learner screenshots: document overflow 0, empty history visible

DONE
로컬 5175 로그인 재기동 검증

127.0.0.1:5175 web, 8000 API, 9099 engine을 재기동하고 dev-login 서버 세션과 /learn redirect를 확인했다.

산출물

local dev-login flow proof

검증

desktop/mobile auth flow passed

DONE
active session dense viewport 보정

375px급 active session에서 stage 내부가 1px 넘게 잘리던 문제를 avatar/padding 조정으로 제거했다.

산출물

session layout responsive adjustment

검증

session-layout desktop/mobile 8 passed

DONE
텍스트 턴 SSE 전환

POST /sessions/{id}/stream token 이벤트로만 내담자 자막을 쌓고, HTTP 거절과 SSE error 모두 실패 턴을 transcript와 저장소에 남기지 않는다.

산출물

real SSE stream turn path, failed turn discard

검증

session layout/turn E2E passed

DONE
음성 실패 턴 미저장

음성 회기도 엔진 응답 생성 성공 후에만 learner/client turn을 저장한다. 실패한 transcript는 pending 상태에서 제거한다.

산출물

voice failure persistence guard

검증

voice + voice-success + session-layout 15 passed

DONE
비영구 상태 문구 정리

admin health와 voice degraded reason은 내부 fallback/seed 표현 대신 비영구 런타임 상태를 사용자용 문구로 표시한다.

산출물

operator-facing copy cleanup

검증

settings/admin focused E2E 통과

DONE
직접 URL persona 차단

/learn/session/:code로 직접 들어와도 DB 원본 persona가 아니면 회기 시작을 막는다.

산출물

route guard, degraded/seed fallback regression

검증

unavailable persona code E2E 통과

DONE
demo Live2D 자산 제거

Mao/Haru 샘플과 Pixi/Cubism 런타임을 공개 배포물에서 제거했다. 세션 화면은 P1 PSB raster avatar와 SVG fallback을 렌더링한다.

산출물

P1 PSB raster avatar, SVG fallback, legacy /live2d/* 404 function

검증

Mao/Haru/Cubism core routes 404, no Live2D/Pixi chunks

이번 세션 내러티브 (원문 보존)team lead review

이번 세션은 seed persona 결합 제거, 비개발 fail-closed 설정, compose OAuth 주입, admin 모바일 overflow 수정, persona 인증 경계 보강, 전체 Playwright 재통과, 공개 API prod 전환까지 완료했다. 이번 이어받기에서는 내담자 AI 생성 턴의 provider/model/token/cost 텔레메트리를 /turn, SSE stream, 음성 생성 경로에서 DB app.turns까지 적재하도록 연결했고, gateway stream done/error 계약을 구조화했으며, P1 상담 시작→텍스트 stream→종료→리뷰 피드백 UI E2E와 저항 엔진 정량 회귀 테스트를 추가했다. 이어서 PII 마스킹 게이트 우회 차단, RBAC/IDOR·감사 insert 경로, 음성 paralinguistic 메타 저장, 공개 런타임 watchdog 스크립트와 runbook을 보강했다. 추가로 상주 engine session reuse, SAML provider 스캐폴드, visible_to 런타임 필터, EOT/TTS payload 계약까지 회귀화했다. 백엔드 회귀 테스트는 84개로 재검증했고, 페르소나 승인/반려 API와 교수 콘솔 검수 UI proof를 추가했다. Postgres RLS/audit live smoke checker와 s2s 2차 PoC 판단 메모도 준비했지만, live DB 실행과 s2s 채택 결정은 별도 증거가 필요하다. 이후 로컬 5175 런타임 재기동, admin 사용자 관리 E2E 안정화, 학습자 홈 0회 기록 UX, active session 실제 SSE 스트림 전환, 텍스트/음성 실패 턴 미저장, 직접 URL persona 우회 차단, Live2D demo 자산 제거, AI 운영 fail-closed 보강까지 전체 Playwright로 확인했다. 2026-06-26 15:18 KST 기준 공개 API 터널을 복구한 뒤 전체 Playwright 72개가 desktop/mobile/single-run 모두 통과했다. Cloudflare Pages production 배포 2a58ca49도 완료했고, 커스텀 도메인이 새 asset을 서빙하는 것을 확인했다. 과거 Mao/Haru Live2D demo 자산은 repo와 번들에서 제거했고, /live2d/* 운영 경로는 404로 차단했다. 현재 런타임은 prod API 8001, dev API 8000/8010, web 5173, engine gateway 9099, cloudflared tunnel 1개를 의도적으로 유지한다. 이번 라운드에서는 레이아웃 작업을 서브에이전트 전담으로 분리해 세션, 학습자 홈/리뷰, 관리자/교수자, 설정 화면을 overflow 수리 수준이 아니라 실제 작업 화면 재설계 수준으로 갱신했다. 통합 레이아웃 E2E는 desktop/mobile 54개를 최종 통과했고, 자세한 인수인계는 docs/ops/layout-redesign-handoff-2026-06-26.md에 남겼다. 이번 이어받기에서는 핸드오프가 남긴 "실기기 시각 수용"을 엄격한 자동 게이트로 닫았다. 7개 권장 너비(390/720/861/900/1024/1280/1440)에서 7개 재설계 화면의 가로 overflow 0·컨트롤 클립 0을 강제하는 layout-visual-gate.spec.ts(7 passed, 49장 스크린샷)를 만들고, 화면별 1에이전트 병렬 시각 리뷰 → 6개 병렬 수정 에이전트 → 화면별 적대적 재검수까지 돌려 7/7 accept(critical/major 0, 회귀 0)를 확정했다. 학습자홈 1280 3열 가운데 컬럼 붕괴(critical)와 교수 'API 404' raw 배너를 포함한 결함을 모두 해소했고, 레이아웃 항목을 DONE으로 닫았다. 이번 로그인 복구 라운드에서는 dev/Tailnet OAuth direct start까지 local_oauth_unavailable로 막고, public OAuth state를 HttpOnly 쿠키에 묶인 서명 토큰으로 바꿔 API 재시작 후 콜백이 invalid_state로 실패하지 않게 했으며, callback 실패 reason/status 진단 로그와 화면 메시지 분기를 추가했다. 추가로 Google provider error를 access_denied/provider_error로 분리하고 로그인 화면에 reason code를 노출했다. 이어서 C1 사례개념화 워크시트 1차 구조를 리뷰 API와 화면에 붙여 축어록 근거 기반 read-only 초안을 제공한다. 공개 Google OAuth 실제 /turn 증명만 storageState 캡처 후 남아 있다.