# P2 회기 계획·달성도 게이지 설계 (1p) > 2026-07-13 한신대 회의 P2 결정의 구현 설계. 소유자 확인용 1페이지. > 원칙: 게이지는 **백엔드 결정론 상태머신 수치에서 파생**하며, LLM이 만들지 않는다. > CCD·정답 라벨·ideation 등 내담자 내부 설정은 계속 비노출(M6). 게이지는 "훈련 진행 신호"만 보여준다. ## 1. 무엇을 보여주나 | 표면 | 내용 | |---|---| | 세션 화면(좌측 트랙) | 단계별 누적 게이지 4개 — "라포 100 중 65" 식. 이번 회기 목표 단계에 목표 배지(P1 구현됨) | | 세션 화면(관찰 패널) | **상세 수치**: 유효 개방도(%), 방어(저항) 수준(%), 라포 누적(%) + 이번 회기 증가분(+N%p) | | 학습자 홈(페르소나 카드) | 페르소나별 라포 누적 게이지 — 회기가 이어질수록 차오르는 학습 신호 | **학습 신호 설계 의도(회의 합의)**: 초심 상담자는 라포를 1회기에 못 만드는 게 정상이다. 게이지가 회기를 건너 누적되는 모습 자체가 "여러 회기에 걸쳐 쌓는 것"임을 가르친다. ## 2. 게이지 공식 (결정론) 상태머신(`state_machine.py`)의 기존 수치만 사용한다. 새 상태 없음. - 단계 전이 조건은 `turns_in_stage >= STAGE_MIN_TURNS[stage]` AND `rapport_credit >= STAGE_ADVANCE_RAPPORT[stage]`. - **단계 게이지**(stage s): - 지나온 단계: `100` - 미래 단계: `0` - 현재 단계: `min(99, rapport_credit / STAGE_ADVANCE_RAPPORT[s] × 99)` — 라포 누적이 게이지의 본질. (두 게이트를 모두 충족해 전이 대기 상태면 99에서 대기, 전이 순간 100) - `정리`(CLOSE)는 진입 자체가 100 (전이 임계 없음) - **누적성**: `rapport_credit`은 회기 종료 시 ×0.7로 이월(`init_state(carry)`, 기존 구현)되므로 다음 회기 게이지는 0이 아니라 이월분에서 시작한다 → "누적 게이지"가 자동 성립. - **이번 회기 증가분**: `rapport_credit − prev_rapport_credit`(세션 생성 시 저장된 이월 기준값, 기존 컬럼). - **방어(저항) 수준**: `resistance`(0~1)를 %로. 학습자 표기는 "방어 신호(저항)" — 학술 용어화. - **유효 개방도**: `effective_openness`(이미 학습자 노출 중인 값)를 %로. ## 3. 계약 변경 - `session_read_model.py`에 `SessionProgress` DTO 신설: `stages[] {stage, percent, achieved, is_goal}` + `rapport_percent, rapport_delta_percent, resistance_percent, openness_percent`. - 파생 함수는 순수함수 `build_session_progress(state, prev_rapport_credit, goal_stages)` — 상태머신 상수를 단일 원천으로 읽는다. - 노출 지점: `SessionDetailResponse.progress`(새로고침 복원), `TurnResponse.progress` + 스트림 `done` payload(턴마다 갱신), 대시보드 `persona_progress[].rapport_percent`(홈 카드). - **비노출 유지**: ideation_stage, CCD, 정답 라벨, raw resistance 원값 명칭("저항 엔진" 등 내부 용어). ## 4. 비(非)작업 (회의 결정 준수) - 별도 "치료 계획 탭" 없음 — 계획서·프로토콜은 페르소나 RAG 첨부(`/personas/sources`, 기존 경로)로 흡수. - 회기 간 망각 기능 없음. - 페르소나 수치의 전 회기 공유는 기존 carry-over(라포 ×0.7, resistance drift)가 이미 소유 — 변경 없음.