# Outcome & Alliance OS G7/G8 UI/UX 시각 QA - 실행일: 2026-08-07 - 대상: G7 `MultimodalAllianceCard`, G8 `ContinuousImprovementCockpit` - 디자인 방향: 규제 민감형 상담 수련 제품의 차분한 임상 워크벤치 - 기준 밀도: `DESIGN_VARIANCE=5`, `MOTION=3`, `DENSITY=6` - 판정: 고심각도 시각·접근성 결함 없음. G8 승인 요건 노출/키보드 제출 결함 1건을 좁게 수정했고, G7은 터치 타깃·키보드 포커스 수치 회귀를 추가했다. ## 1. QA 기준 기존 Pretendard, Vignette CSS 토큰, light/dark theme을 유지했다. 마케팅식 성과 과장은 넣지 않고 다음 순서로 판정했다. 1. 접근성: 의미 구조, 라벨, 키보드 포커스, 최소 타깃, 동적 상태 설명 2. 증거 노출: 측정 출처·불확실성·반대근거·승인 전제의 가시성 3. 되돌릴 수 있는 제어: 동의 철회·삭제 범위·rollback 증거·human gate 4. 역할 경계: 학습자 원음 제어와 교수자 metadata-only, 관리자 전용 승격 제어 5. 반응형: 페이지 전체 가로 overflow 없음, 내부 시간축만 명시적으로 수평 스크롤 6. motion/theme: dark theme와 `prefers-reduced-motion`에서 정보 손실 없음 접근성·상호작용 감사에는 최신 [Web Interface Guidelines](https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md)의 semantic control, visible focus, form label/name, reduced motion, overflow 규칙을 사용했다. ## 2. 실제 렌더 매트릭스 | 표면 | 데스크톱 | 모바일 | theme/motion | 결과 | |---|---:|---:|---|---| | G7 학습자 회기 리뷰 | Chromium 1440×900 | Pixel 5 | light 및 별도 dark + reduced-motion 흐름 | 통과 | | G7 교수자 회기 리뷰 | Chromium 1440×900 | Pixel 5 | 역할별 API route mock | 통과 | | G8 관리자 지속 개선 | Chromium 1440×900 | Pixel 5 | dark + reduced-motion | 통과 | | G8 empty/degraded/RBAC | Chromium 1440×900 | Pixel 5 | fail-closed read model | 통과 | Playwright 산출물 이름은 다음과 같다. 각 파일은 desktop/mobile 프로젝트별 결과 폴더 아래 생성된다. - G7: `g7-multimodal-alliance-desktop.png` - G8 승인 전: `g8-continuous-improvement-before-approval.png` - G8 승인 후: `g8-continuous-improvement-cockpit.png` ## 3. G7 판독 ### 통과한 점 - 정보 위계가 `단일 오디오 시계 → 이벤트 inspector → goal/task/bond 독립 측정 → 개인정보 원장 → 음성 재연습` 순서로 명확하다. - 텍스트와 음성을 먼저 독립 측정하고 no-gain이면 텍스트 단독으로 유지한다. 값, 불확실성, 출처, 반대근거가 같은 축 안에 있어 합산 총점처럼 보이지 않는다. - 익명 자막은 원문 대신 화자·순서·시간 토큰으로 표시되고, 교수자 뷰는 원본 음성 API를 호출하지 않는다. - 동의, 철회, 원본 음성/파생 특징 삭제 범위를 별도 확인으로 나눠 되돌릴 수 있는 제어 경계가 분명하다. - 모바일에서는 720px 시간 캔버스를 내부 viewport에 격리한다. 페이지 전체 overflow는 없고 viewport가 키보드 포커스를 받는다. - 시간폭을 보존하는 이벤트 버튼은 desktop/mobile 모두 실제 24×24px 이상이다. 이벤트의 짧은 시각 라벨은 `aria-label`과 선택 후 inspector의 전체 설명으로 보완된다. - playhead만 `left` transition을 사용하며 reduced-motion에서는 transition이 제거된다. ### 변경 - `apps/web/e2e/multimodal-alliance.spec.ts`: 이벤트 최소 타깃 24×24px와 오디오 시계 viewport 키보드 포커스를 수치 회귀로 추가했다. - 제품 소스/CSS는 수정하지 않았다. 시간축 이벤트의 최소 너비를 임의로 늘리면 시간 길이 인코딩과 인접 이벤트 간격을 왜곡하므로 현재 24px 하한을 유지했다. ## 4. G8 판독 ### 통과한 점 - hero는 “승격보다 근거를 먼저 본다”는 운영 원칙을 한 문장으로 고정하고, 입력·승격·효과·데이터 경계를 바로 아래 strip에서 다시 확인하게 한다. - source → independent red-team → coverage drift → human catalog gate가 실제 순서이므로 01~04 구조가 장식이 아니라 프로세스 의미를 갖는다. - 모델/릴리스 카드는 baseline·threshold·provenance·rollback 4종 증거를 같은 위치에 노출하며, 누락 증거는 승인 전에 차단된다. - incident DAG와 append-only lifecycle이 하단 운영 원장으로 분리돼 승격 후보와 사후 회귀 증명을 혼동하지 않는다. - desktop 2열 gate와 mobile 1열 gate 전환, 4열 pipeline/DAG의 단계적 2열·1열 전환에서 페이지 가로 overflow가 없다. - dark theme의 경계·본문·상태 대비가 유지되고 reduced-motion에서는 loading spinner animation이 제거된다. - `vgops-*` 관리자 shell과 별도 `cic-*` feature namespace를 사용하며 production build의 cosmetic-filter safety gate를 통과했다. ### 발견·수정한 결함 `apps/web/src/pages/admin/ContinuousImprovementCockpit.tsx`의 비활성 승인 버튼은 차단 이유를 `title`에만 두고 있었다. 비활성 버튼은 키보드 포커스를 받지 않고 모바일에는 hover가 없어 “데이터 경계 위반”, “증거 4종 누락”, “승인 사유 필요” 중 무엇이 막는지 확인하기 어려웠다. 승인 입력도 일반 `div`라 Enter 제출 의미가 없었다. 수정 내용: - 승인 영역을 실제 `
`으로 바꾸고 Enter 제출도 기존 `boundarySafe && complete && reason` gate를 통과할 때만 실행한다. - 입력에 의미 있는 `name`, 예시형 placeholder, `aria-describedby`를 추가했다. - 차단/준비 상태를 항상 보이는 문구로 렌더하고 입력과 버튼이 같은 설명을 참조한다. - 비활성 버튼의 접근 불가능한 `title` 의존을 제거했다. - 상태 색은 기존 `--text-muted`, `--text-accent`, `--crit-text`만 사용했다. 회귀 테스트는 다음을 고정한다. - rollback 증거가 빠진 릴리스 게이트: `필수 증거 4종이 모두 있어야 기록 가능` - 사유가 빈 모델 게이트: `승인 사유를 먼저 입력해야 함` - 4종 증거 + 사유 충족: `증거 4종과 승인 사유가 준비됨` - 입력에서 Enter 제출 후 append-only 승인/effect 원장 생성 ## 5. 검증 증거 작업 디렉터리: `D:\workspace\vignette\apps\web` ```text npm run typecheck PASS npx playwright test e2e/multimodal-alliance.spec.ts e2e/continuous-improvement-admin.spec.ts \ --project=chromium-desktop --project=chromium-mobile --workers=2 16 passed npx playwright test e2e/continuous-improvement-admin.spec.ts \ --grep "renders the generated-content" \ --project=chromium-desktop --project=chromium-mobile --workers=2 2 passed npm run build PASS · cosmetic-filter safety PASS · Vite production build PASS ``` ## 6. 범위 경계 - `docs/dev_dashboard.html`의 G7/G8 상태와 근거를 읽어 제품/외부 gate를 구분했지만 상태는 변경하지 않았다. - `docs/TODO.md`와 backlog 상태를 변경하지 않았다. - 공개 배포, public route proof, 물리 마이크, public WSS, 50분 장시간 회귀는 이번 로컬 시각 QA의 증거로 대체하지 않는다. - deploy, git stage, commit은 수행하지 않았다.