외부 실증과 인증 화면 경계 보강

This commit is contained in:
Yun Chan 2026-08-12 15:01:21 +09:00
parent 68fd8f65a3
commit 64e1b2210d
7 changed files with 64 additions and 10 deletions

View file

@ -676,6 +676,7 @@
<p class="dg-note">197차 적용(2026-08-10): clean HEAD <code>4cd35488…</code>·tree <code>001a7c74…</code>의 6차 full run은 핵심 폐루프를 두 번째로 통과했고, 별도 returned-practice fixture도 초기 G4/G5 0을 증명했다. desktop G4/G5 2건은 GREEN이었지만 desktop이 만든 성공 상태를 mobile G4가 다시 읽을 때 테스트가 <code>반영 상태 다시 확인</code> 대신 최초 버튼을 찾아 5분 timeout, mobile G5는 serial 중단됐다. receipt <code>periodic-learner-e2e-20260810-012909.json</code>은 FAILED이며 public/NAS/active DB 접촉 0·exact cleanup GREEN이다. mobile 성공-state locator를 교정했고 실패 화면에서 추가로 확인한 강점·개선점·다음 문장·내담자 반응·워크시트 근거의 literal <code>[NAME]</code>/<code>[ORG]</code>도 저장/API는 유지한 채 표시층에서 자연어화했다. focused session-review desktop/mobile <b>2/2</b>·typecheck·live spec 4건 collection을 통과했지만 full runner는 재실행하지 않았다.</p>
<p class="dg-note">198차 적용(2026-08-10): clean HEAD <code>aa81af29…</code>·tree <code>3901d71c…</code>의 7차 full run이 499.8초에 첫 전체 <b>GREEN</b> receipt <code>periodic-learner-e2e-20260810-020117.json</code>·SHA-256 <code>bae963de…f32e1a</code>를 만들었다. 실제 브라우저 same-learner session 생성·SSE·review ready·G4/G5 <code>0→1→1</code>, 별도 zero-state returned-practice desktop/mobile <b>4/4</b>, route mock 0을 통과했다. public 8001·active DB 55432·engine 9099·NAS 접촉은 0이며 전용 container 4·volume 3·network 1·engine PID와 6578-6581 listener는 cleanup 뒤 모두 0이다. 기존 <code>vignette-e2e</code> hourly heartbeat는 중복 생성 없이 갱신해 최신 GREEN이 6시간 이상 오래됐거나 material milestone이 바뀐 때만 preflight 뒤 full runner를 최대 1회 실행하고, 실패 시 같은 heartbeat에서 재시도하지 않는다. G7 human pack evaluator·runner/checker와 후속 intake compiler 계약도 <b>103/103</b>으로 재검증했으며 물리 마이크는 열지 않았다.</p>
<p class="dg-note">199차 적용(2026-08-12): 실제 공개 학생 홈을 390×844·320×568에서 읽기 전용으로 확인해 부트 진단·console error·가로 overflow·literal PII placeholder는 0이고 핵심 학습 카드·탭·리뷰 CTA는 44px 이상임을 재확인했다. 반면 공통 톱바의 공간 전환 링크는 28px, 테마·로그아웃은 34px에 머물러 있던 P1을 발견했다. 소스는 720px 이하에서 워드마크 글자·사용자 칩을 접고 브랜드·공간 전환·테마·로그아웃 6개를 모두 44×44px로 고정했으며, 관리자 3역할 최악 조건 390/320 desktop/mobile <b>2/2</b>, 학생 자기주도 홈→회기→리뷰→재연습 desktop/mobile <b>6/6</b>, G1·G4·G5·G7 focused <b>50/50</b>, 대시보드 <b>10/10</b>, type/API contract와 SSOT checker를 통과했다. clean HEAD <code>9687f186…c48b</code>·tree <code>be2fc4d2…749d7</code>의 full disposable runner도 485.8초에 GREEN이었고 receipt <code>periodic-learner-e2e-20260812-143426.json</code>·SHA-256 <code>501d2d7f…c557</code>에서 same-learner SSE·review·G4/G5 <code>0→1→1</code>, returned desktop/mobile <b>4/4</b>, route mock 0, public·NAS·active DB 접촉 0과 container·volume·network·listener·temp 잔여 0을 확인했다. 공개 앱에는 아직 이 변경을 배포하지 않았으므로 실제 공개 톱바는 별도 승인 배포 전까지 기존 크기이며, G7은 명시 동의 물리 마이크·독립 human pack·canonical checker exit 0 전까지 external GATE다.</p>
<p class="dg-note">200차 적용(2026-08-12): actual NAS 로그인 320/390 읽기 전용 관측에서 조작면·boot·console은 정상이지만 비-overlay 세로 scrollbar 환경의 <code>100vw</code> 두 선언이 10px 가로 넘침을 만드는 P1을 확인했다. auth/login shell을 scrollbar를 제외한 컨테이너 기준 <code>100%</code>로 바꾸고 320px stable-scrollbar OAuth fixture를 고정했다. 인증 desktop/mobile <b>2/2</b>, 자기주도+G1·G4·G5·G7 <b>56/56</b>, 대시보드 <b>10/10</b>, G7 runner·checker·human/API 계약 <b>110/110</b>, type/API contract·Ruff·SSOT checker를 통과했다. 물리 soak standalone도 canonical 공통 3,000초를 보존하도록 production 기본·최소를 3,120초로 통일해 3,000초 요청을 장치 열거 전에 차단한다. 이 소스는 아직 공개/NAS에 배포하지 않았고 clean disposable 전체 폐루프 재검증 전이다.</p>
<div class="dg-principles" aria-label="디자인 생성 가드레일">
<div><b>래스터만 사용</b><span>이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.</span></div>
<div><b>기능 우선</b><span>메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.</span></div>
@ -1165,7 +1166,7 @@
<tr><td>Fresh compose smoke</td><td><code>docker compose -p vignette-packaging-smoke -f infra/docker-compose.yml up -d --build</code> + proxy <code>/api/health</code></td><td>Passed with dummy production-safe env: API healthy, DB healthy, web/proxy up, <code>http://localhost:18080/api/health</code> 200 with <code>db:true</code>, <code>engine:true</code>, <code>engine_mode:"claude_cli"</code>. Smoke volumes/network removed after run.</td></tr>
<tr><td>격리 NAS 프리뷰 · 회기 E2E 자동화</td><td><code>http://100.116.83.60:8088</code> / <code>vignette-e2e</code> 매시간 heartbeat / <a href="./ops/nas-preview-deployment-evidence-2026-08-07.md">배포 증거</a> / <a href="./ops/evidence/nas-preview-current-deploy-2026-08-07.json">기계 판독 증거</a></td><td>current clean source HEAD <code>61a41d1f…6af</code>·tree <code>87dec55d…3b77</code>의 archive <code>4d15d055…119d4d</code>를 전용 Compose 프로젝트·포트·네트워크·named volume에 승격했다. candidate 112/112와 실제 NAS-origin 112/112는 통과했지만 영수증은 실 API/DB 22건과 route fixture 90건을 분리한다. 자동화는 공개/NAS 화면과 health를 읽기 전용으로 매시간 보여준다. material milestone의 동일 학습자 SSE→review→G4/G5 actual 폐루프는 clean HEAD/tree·전용 engine/DB/API/Web·보호 포트 거부·sentinel·exact cleanup runner가 소유한다. 1~3차는 하네스, 4차는 reload ledger hydration 제품 결함, 5차는 fixture 공유, 6차는 mobile success-state locator를 fail-closed했다. 7차 clean <code>aa81af29…</code>는 same-learner SSE·review·G4/G5 <code>0→1→1</code>과 별도 returned desktop/mobile <code>4/4</code>, route mock 0, cleanup 0으로 첫 전체 GREEN을 만들었다. heartbeat는 최신 GREEN이 6시간 이상 오래됐거나 학생 runtime·회기 폐루프 material milestone이 바뀔 때만 full runner를 최대 1회 실행하고 실패 시 자동 재시도하지 않는다. G7 human intake·checker·template-only 변경은 G7 focused gate만 실행한다. release gate·NAS preflight·배포 SHA 변경 때만 프리뷰를 갱신한다. G7 외부 mic/provider/human 증거는 별도다.</td></tr>
<tr><td>G7 외부 증거 3-artifact 동시 시간창 오케스트레이터</td><td><code>scripts/run-g7-external-proof-window.py</code> · <a href="./ops/outcome-os-g7-external-proof-readiness-2026-08-07.md">준비 문서</a></td><td>soak·runtime·topology 세 캡처를 같은 host의 공통 3,000초 시간창으로 실행하고 checker까지 잇는다. 공개 배포·프로세스·source pin은 clean commit <code>a73bcd24…</code>와 fresh receipt <code>9f8d1941…</code>로 완료했다. Cloudflare가 Python 기본 User-Agent를 403으로 거부하는 경계도 브라우저 호환 header와 회귀 4/4로 고정했다. 30초 rehearsal은 세 leg 7 samples를 모두 통과했으며 마이크를 열지 않았다. <b>남은 선행 조건:</b> 사용자의 물리 장치 선택과 명시 동의, 독립 human voice-gain pack이다.</td></tr>
<tr><td>G7 external GATE · 최종 감사 정정</td><td><code>run-g7-external-proof-window.py</code><code>check-g7-external-proof.py</code></td><td><b>상태는 external GATE 유지.</b> runner 프로세스 exit는 canonical checker <code>exit 0</code>·<code>gate_closed=true</code>에 결속되고, browser Origin과 API transport host는 별도 allowlist로 검증된다. 세 artifact 교집합은 <code>≥3000s</code> + 120초 margin이고 Windows proof는 detached-clean HEAD/tree·tool SHA·<code>psutil==6.1.1</code>을 pin한다. clean-source 배포와 무마이크 rehearsal은 완료했다. 남은 것은 물리 마이크 3,120초, 동시 runtime/topology, 독립 human pack을 합친 4-artifact 실증뿐이다.</td></tr>
<tr><td>G7 external GATE · 최종 감사 정정</td><td><code>run-g7-external-proof-window.py</code><code>check-g7-external-proof.py</code></td><td><b>상태는 external GATE 유지.</b> runner 프로세스 exit는 canonical checker <code>exit 0</code>·<code>gate_closed=true</code>에 결속되고, browser Origin과 API transport host는 별도 allowlist로 검증된다. 세 artifact 교집합은 <code>≥3000s</code> + 120초 margin이고 Windows proof는 detached-clean HEAD/tree·tool SHA·<code>psutil==6.1.1</code>을 pin한다. 직접 물리 soak를 실행해도 production 기본·최소 3,120초를 강제하고 3,000초 요청은 장치를 열기 전에 차단한다. clean-source 배포와 무마이크 rehearsal은 완료했다. 남은 것은 물리 마이크 3,120초, 동시 runtime/topology, 독립 human pack을 합친 4-artifact 실증뿐이다.</td></tr>
<tr><td>G8 DONE · clean-head NAS 기준선</td><td><code>vignette-preview-20260807</code> · <code>run-outcome-os-release-agent.py</code></td><td><b>상태는 DONE.</b> active archive <code>4d15d055…119d4d</code>, source HEAD/tree <code>61a41d1f…6af</code>/<code>87dec55d…3b77</code>, API/Web <code>d5021950…e4b1</code>/<code>9796c092…4b36</code> exact running. candidate 112/112와 actual NAS-origin 112/112, health ok·db/engine true·auth 401·OpenAPI 126을 통과했다. fresh dump <code>36ec8748…24db8</code> 1,097,100 bytes, TOC 1,738 / TABLE DATA 129와 previous active <code>6030a677…c611</code>을 보존했다. release agent의 DB restore 비소유·image/Compose/active-state rollback 경계는 유지한다.</td></tr>
<tr><td>노트북 로컬 음성 스택 — faster-whisper STT + MeloTTS TTS</td><td><code>scripts/local-whisper-stt-server.py</code> · <code>scripts/start-local-whisper-stt.ps1</code> · <code>voice_stt_provider=local_whisper</code></td><td>2026-08-08 소유자 결정으로 음성 양쪽을 노트북 상주 로컬 모델로 정했다. TTS는 처음 Higgs로 잡았으나 연구/비상업 라이선스라 <code>config.py</code>가 운영에서 차단하고 있었고 그 가드를 푸는 건 법적 판단이라, 상업 사용이 허용된 <b>MeloTTS Korean(MIT)</b>으로 바꿔 가드 자체를 불필요하게 만들었다. Kokoro-82M은 Apache 2.0이지만 공식 <code>VOICES.md</code><b>한국어가 없어</b> 탈락했다. local Whisper는 현재 호스트의 cuDNN 부재를 반영해 <code>small/cpu-int8</code>를 운영 기본으로 고정했고, API health도 MeloTTS model을 실제 provider와 맞춰 보고한다. 합성 시드 8.72초에서 interim 9·final 5·word timestamp 12개, 한 글자 차이 전사를 확인했고 MeloTTS CPU RTF는 0.27~0.28, 합성음→local STT 왕복은 완전 일치했다. current 통합은 launcher/sidecar 80/80·G7 전체 166/166·API voice 71/71·API 전체 921·gateway 58을 통과했다. Higgs 운영 사용은 라이선스 가드가 남아 dev 전용이다.</td></tr>
<tr><td>비-secure origin 회기 리뷰 크래시 수정</td><td><code>apps/web/src/lib/uuid.ts</code> · <code>apps/web/src/lib/sha256.ts</code> · <code>apps/web/e2e/insecure-context-uuid.spec.ts</code></td><td>격리 NAS 프리뷰(평문 HTTP·비-localhost)에서 드러난 <code>crypto.randomUUID</code><code>crypto.subtle.digest</code> secure-context 의존을 portable fallback으로 교체했다. source-only UUID/SHA 회귀 12/12와 secure/insecure exact digest 회귀를 통과했고, 최종 archive <code>4d15d055…119d4d</code>의 actual NAS-origin 112/112로 배포 검증까지 닫았다.</td></tr>