vignette/docs/ops/outcome-os-g7-g8-visual-qa-2026-08-07.md
Yun Chan 16e791e044 G0~G8 성과·동맹 측정 OS 작업 일괄 고정
8월 7일까지 워킹트리에만 남아 있던 미커밋 작업을 커밋한다. 여러 사본
폴더(worktree·clone)에 흩어져 있던 중간 스냅샷을 정리하기 전에 원본을
git 이력으로 고정하는 것이 목적이다.

- contracts/routes/services: measurement, outcome_trajectory, rupture_repair,
  deliberate_practice, calibration_transfer, supervision_research,
  multimodal_alliance, continuous_improvement 계열 신규 모듈과 테스트
- infra/db/init: 07~16 마이그레이션(측정 기반~calibration transfer 실행)
- apps/web: 세션 리뷰 카드·관리 화면·E2E 스펙 추가
- docs/ops: G0~G8 라이브 통합·배포·롤백 증거 문서와 evidence JSON/PNG
- scripts: smoke·ledger·릴리스 에이전트·NAS 프리뷰 운영 스크립트

engine.public 로그 .bak과 apps/web/test-results 산출물은 커밋에서 제외했다.
2026-08-08 01:30:53 +09:00

112 lines
7.2 KiB
Markdown
Raw Permalink 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.

# 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 제출 의미가 없었다.
수정 내용:
- 승인 영역을 실제 `<form>`으로 바꾸고 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은 수행하지 않았다.