운영 배포 검증 근거를 반영

This commit is contained in:
Yun Chan 2026-08-28 17:17:34 +09:00
parent 2a39636163
commit dcb76a2373
4 changed files with 21 additions and 12 deletions

View file

@ -10,7 +10,7 @@
--- ---
## 개선관리 워크북 동기화 (2026-08-27) ## 개선관리 워크북 동기화 (2026-08-28)
> 이 표는 워크북 ID와 현행 구현을 잇는 얇은 추적표다. 내부 기술 DONE의 focused 증거는 > 이 표는 워크북 ID와 현행 구현을 잇는 얇은 추적표다. 내부 기술 DONE의 focused 증거는
> `guides/testing.md`, 상세 계약은 SSOT `dev_dashboard.html`이 소유한다. C-001은 기술 사전검증과 외부 > `guides/testing.md`, 상세 계약은 SSOT `dev_dashboard.html`이 소유한다. C-001은 기술 사전검증과 외부
@ -25,11 +25,15 @@
| REQ-002 | **DONE · 내부 기술** | admin protocol draft→active→retired, 라이선스 C/D 외부 LLM 금지, evaluator-only RAG·rollback; migration 17 owner-run/readiness-only | | REQ-002 | **DONE · 내부 기술** | admin protocol draft→active→retired, 라이선스 C/D 외부 LLM 금지, evaluator-only RAG·rollback; migration 17 owner-run/readiness-only |
| REQ-003 | **DONE · 내부 기술** | 페르소나 주호소가 JSON 키 순서나 surface 상태보다 우선 | | REQ-003 | **DONE · 내부 기술** | 페르소나 주호소가 JSON 키 순서나 surface 상태보다 우선 |
| REQ-004 | **DONE · 내부 기술** | learner 현재 설정 AND 세션 snapshot. OFF는 AI 파생 API 403/UI 무요청·혼합 결과 redaction, 사용자 입력·privacy 보존; teacher/admin 유지 | | REQ-004 | **DONE · 내부 기술** | learner 현재 설정 AND 세션 snapshot. OFF는 AI 파생 API 403/UI 무요청·혼합 결과 redaction, 사용자 입력·privacy 보존; teacher/admin 유지 |
| REQ-005 | **DONE · 내부 기술** | 새 회기는 승인 페르소나 `persona_id/version` 고정, 시작/상세 계약 노출, durable create 실패 503 | | REQ-005 | **DONE · 내부 기술·운영 실증** | 새 회기는 승인 페르소나 `persona_id/version` 고정. P20의 `suicide_ideation_stage=0.9 → int(0) → DB 1..5` 장애를 clamp로 제거했고, 공개 P20 회기 생성·실제 AI 응답·종료·평가를 확인 |
| REQ-006 | **DONE · 내부 기술** | prompt와 구조화 결과의 상담자/내담자 identity를 `[COUNSELOR]`/`[CLIENT]`로 역할 마스킹 | | REQ-006 | **DONE · 내부 기술** | prompt와 구조화 결과의 상담자/내담자 identity를 `[COUNSELOR]`/`[CLIENT]`로 역할 마스킹 |
| REQ-007 | **DONE · 내부 기술** | 회기 종료를 평가보다 먼저 영속화해 옛 평가 실패 뒤에도 새 회기 생성·턴 진행 가능 | | REQ-007 | **DONE · 내부 기술** | 회기 종료를 평가보다 먼저 영속화해 옛 평가 실패 뒤에도 새 회기 생성·턴 진행 가능 |
| REQ-008 | **DONE · 내부 기술** | 기본 엔진+live-client readiness, 구조화 done 없는 SSE EOF는 `client_stream_incomplete`로 실패 | | REQ-008 | **DONE · 내부 기술** | 기본 엔진+live-client readiness, 구조화 done 없는 SSE EOF는 `client_stream_incomplete`로 실패 |
운영 반영 기준은 clean commit `2a396361…89c`, Pages production
`1f1ddf18-9d5c-4d83-95a7-8cd71245e646`이다. API/engine/web/STT/TTS/cloudflared와 두 예약 작업은
같은 릴리스 루트에 고정했고 watchdog 8개 check, 공개 Google callback, P20 회기 폐루프를 통과했다.
--- ---
## A. 배포·공개 런타임 게이트 [환경] ## A. 배포·공개 런타임 게이트 [환경]

View file

@ -1197,14 +1197,14 @@
<tr><td>Admin manage-users</td><td><code>admin.spec.ts --grep manage real server-known users</code></td><td>route-mock desktop/mobile 2 passed에 더해 2026-08-27 실제 DB/browser 1 passed. pending 계정의 `/personas` 403·`/learn→/pending`, 승인 뒤 동일 세션 200, AI 피드백 OFF PATCH·GET 영속 재조회, 계정 비활성화·active session 0과 격리 포트 종료를 확인했다.</td></tr> <tr><td>Admin manage-users</td><td><code>admin.spec.ts --grep manage real server-known users</code></td><td>route-mock desktop/mobile 2 passed에 더해 2026-08-27 실제 DB/browser 1 passed. pending 계정의 `/personas` 403·`/learn→/pending`, 승인 뒤 동일 세션 200, AI 피드백 OFF PATCH·GET 영속 재조회, 계정 비활성화·active session 0과 격리 포트 종료를 확인했다.</td></tr>
<tr><td>Full E2E baseline</td><td><code>PLAYWRIGHT_PORT=5174 npm run e2e</code></td><td>2026-06-27/28 기준선 113 passed</td></tr> <tr><td>Full E2E baseline</td><td><code>PLAYWRIGHT_PORT=5174 npm run e2e</code></td><td>2026-06-27/28 기준선 113 passed</td></tr>
<tr><td>Public auth discovery</td><td><code>E2E_PUBLIC_AUTH=1 npx playwright test --list --project=chromium-public-auth</code></td><td>2 tests listed</td></tr> <tr><td>Public auth discovery</td><td><code>E2E_PUBLIC_AUTH=1 npx playwright test --list --project=chromium-public-auth</code></td><td>2 tests listed</td></tr>
<tr><td>Public pre-auth readiness</td><td><code>public-auth-turn.spec.ts --grep production-safe</code></td><td>production-safe smoke 1 passed. 인증된 public <code>/turn</code> proof는 아직 미완료이며 owner storageState가 필요하다.</td></tr> <tr><td>Public pre-auth readiness</td><td><code>public-auth-turn.spec.ts --grep production-safe</code> / authenticated in-app browser</td><td>production-safe smoke 1 passed. 2026-08-28 실제 공개 Google 세션으로 P20 회기 <code>03dddadd-adf3-4922-acbf-31002470da52</code>를 생성하고 자기점검 원장 잠금, 학습자 발화, 실제 AI 내담자 응답, 종료, 2발화 리뷰, AI 평가 완료, P20 1회 기록 영속과 다음 회기 버튼 재노출까지 확인했다.</td></tr>
<tr><td>Public OAuth start</td><td><code>/auth/config</code> + <code>/auth/login?provider=google</code></td><td>2026-06-30 복구 후 auth config 200, Google configured true, redirect URI <code>https://api-vignette.chanpaca.net/auth/callback</code>, dev-login disabled. Google login start는 GET 302와 <code>__Host-vignette_oauth_state</code> HttpOnly/Secure cookie를 반환한다. Authenticated public <code>/turn</code> proof는 owner storageState가 필요하다.</td></tr> <tr><td>Public OAuth start</td><td><code>/auth/config</code> + <code>/auth/login?provider=google</code></td><td>2026-08-28 public auth config 200, Google configured true, <code>allowed_email_domains=[]</code>, redirect URI <code>https://api-vignette.chanpaca.net/auth/callback</code>, dev-login disabled. 로그인 DOM은 모든 Google 계정을 명시하고 실제 Google 선택기에 <code>yunchan@twentyoz.kr</code><code>yunchan8804@gmail.com</code>이 함께 노출됐다. 기존 Google 계정 선택→callback→<code>/admin</code> 성공을 확인했다. 신규 Gmail 선택은 Vignette 계정 생성이므로 사용자 행동시점 확인 뒤 별도 실증한다.</td></tr>
<tr><td>Persona auth boundary</td><td><code>GET /personas</code></td><td>2026-06-30 복구 후 public unauth <code>/personas</code>는 401 <code>not authenticated</code>를 반환한다.</td></tr> <tr><td>Persona auth boundary</td><td><code>GET /personas</code></td><td>2026-06-30 복구 후 public unauth <code>/personas</code>는 401 <code>not authenticated</code>를 반환한다.</td></tr>
<tr><td>Public login</td><td><code>auth.spec.ts --grep public login</code></td><td>1 passed</td></tr> <tr><td>Public login</td><td><code>auth.spec.ts --grep public login</code></td><td>1 passed</td></tr>
<tr><td>Public runtime scripts · source pin</td><td><code>start/watch/boot-public-runtime*.ps1</code> · <code>install-public-runtime-task.ps1</code> · <code>register-boot-task.ps1</code></td><td>2026-08-27 detached-clean <code>bf5f7352…0092</code>·tree <code>c39f917b…c88</code>와 exact boot <code>4f368b2d…5197</code>·watchdog <code>6cd3c869…8242</code>·start <code>c8c837fd…6cf1</code> SHA에 로그온·watchdog 두 task를 재등록했다. action working directory/root/commit/tree/SHA pin은 PASS, watchdog은 <code>LastTaskResult=0</code>·Ready·failcount 0이다. 부트 task는 현재 healthy surface를 불필요하게 건드리지 않도록 RunNow하지 않았고, 실제 Windows 재부팅 후 자동복구 smoke만 별도 운영 gate로 남는다.</td></tr> <tr><td>Public runtime scripts · source pin</td><td><code>start/watch/boot-public-runtime*.ps1</code> · <code>install-public-runtime-task.ps1</code> · <code>register-boot-task.ps1</code></td><td>2026-08-28 detached-clean <code>2a396361…89c</code>·tree <code>c26bf816…fef</code>에 로그온·watchdog 두 task를 재등록했다. action working directory/root/commit/tree/SHA pin은 PASS다. watchdog 수동 실행은 Running→Ready, <code>LastTaskResult=0</code>·failcount 0이며 17:12:10 KST engine/API/voice/web/cloudflared/DB/public API 8개 check가 모두 healthy였다. Boot task는 Ready이며 이전 user-terminated 결과 <code>0x41306</code>은 이력으로 남는다. 실제 Windows 재부팅 자동복구 smoke는 별도 운영 gate다.</td></tr>
<tr><td>Public API health</td><td><code>http://127.0.0.1:8001/health</code> / <code>https://api-vignette.chanpaca.net/health</code></td><td>2026-08-27 복구 후 local은 <code>status=ok·db=true·engine=true</code>, public은 같은 응답을 연속 3/3 반환했다. 실제 공개 로그인 DOM·스크린샷도 정상이며 console error/warning은 0이다. DB container는 기존 recovered named volume을 그대로 유지한다.</td></tr> <tr><td>Public API health</td><td><code>http://127.0.0.1:8001/health</code> / <code>https://api-vignette.chanpaca.net/health</code></td><td>2026-08-28 17:11:47 KST local/public 모두 <code>status=ok·environment=prod·db=true·engine=true</code>. voice는 local/public 모두 <code>local_whisper small</code>·<code>melotts-korean</code>·WS queue 4, web은 local/public 200과 동일 asset <code>index-DJPgoeJy.js</code>/<code>index-CXOy3QyV.css</code>를 반환했다. DB는 백업 <code>vignette-dev-db-vignette-20260828-065331Z.dump</code>를 검증하고 recovered named volume을 보존한 채 migration 17을 적용했다.</td></tr>
<tr><td>Public runtime current snapshot</td><td><code>health + provenance + Scheduled Tasks</code></td><td>clean source <code>bf5f7352…0092</code>·tree <code>c39f917b…c88</code>에서 API-only 복구했고 web·engine·cloudflared는 살아 있던 프로세스를 유지했다. 기존 G7 fresh receipt와 무마이크 rehearsal은 역사 증거로 보존하며, 이번 routine 복구를 새 배포·G7 승격으로 오표기하지 않는다.</td></tr> <tr><td>Public runtime current snapshot</td><td><code>health + provenance + Scheduled Tasks + Pages</code></td><td>clean source <code>2a396361…89c</code>·tree <code>c26bf816…fef</code>로 API/engine/web/STT/TTS/cloudflared 전 프로세스를 정렬했다. old <code>bf5f7352</code> 참조 runtime은 0개다. Cloudflare Pages production <code>1f1ddf18-9d5c-4d83-95a7-8cd71245e646</code>은 source <code>2a39636</code>이며 current와 이전 5세대 entry/lazy JS·CSS를 custom/preview 양쪽에서 MIME·SHA 일치로 검증했다.</td></tr>
<tr><td>Public/local/Tailnet login recovery</td><td><code>https://vignette.chanpaca.net/login</code> / <code>https://api-vignette.chanpaca.net/health</code> / <code>https://alpaca-home.taile93291.ts.net/login</code></td><td>2026-06-30 public web login HEAD 200, public API health 200, auth config 200, Google login start 302. Earlier Tailnet checks remain recorded separately; vnet DNS A records are still 0.</td></tr> <tr><td>Public/local/Tailnet login recovery</td><td><code>https://vignette.chanpaca.net/login</code> / <code>https://api-vignette.chanpaca.net/health</code> / <code>https://alpaca-home.taile93291.ts.net/login</code></td><td>2026-08-28 public web 200, public API health 200, auth config 200, Google login start와 callback 성공, P20 실제 회기·응답·종료·평가 폐루프 성공. Earlier Tailnet checks remain recorded separately; vnet DNS A records are still 0.</td></tr>
<tr><td>Local 5175 login</td><td><code>PLAYWRIGHT_BASE_URL=http://127.0.0.1:5175 auth.spec.ts</code></td><td>desktop/mobile passed</td></tr> <tr><td>Local 5175 login</td><td><code>PLAYWRIGHT_BASE_URL=http://127.0.0.1:5175 auth.spec.ts</code></td><td>desktop/mobile passed</td></tr>
<tr><td>Learner/readiness E2E</td><td><code>learner.spec.ts + readiness.spec.ts desktop/mobile</code></td><td>14 passed</td></tr> <tr><td>Learner/readiness E2E</td><td><code>learner.spec.ts + readiness.spec.ts desktop/mobile</code></td><td>14 passed</td></tr>
<tr><td>Learner screenshots</td><td><code>learn-empty-desktop.png / learn-empty-mobile-compact.png</code></td><td>document overflow 0, empty history visible</td></tr> <tr><td>Learner screenshots</td><td><code>learn-empty-desktop.png / learn-empty-mobile-compact.png</code></td><td>document overflow 0, empty history visible</td></tr>
@ -1243,7 +1243,7 @@ $env:E2E_PUBLIC_STORAGE_STATE=".\node_modules\.tmp\public-auth.json"
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start-public-runtime.ps1</pre> powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start-public-runtime.ps1</pre>
</div> </div>
<div class="source-note"><b>닫은 항목(live 증거):</b> ① engine config 운영값(<code>claude_cli / 9099 / gateway-default</code>, durable, db). ② 상주 엔진풀 probe — 단일 session_id 2회 reused stream, TTFT 16674199ms, cost 누적 0.068→0.123. ③ 상주 엔진풀 RSS — gateway session 1개에서 <code>claude -p</code> child RSS 363.3MB, gateway RSS 16.2MB. ④ Postgres RLS/audit smoke 5 checks PASS. ⑤ turn cost telemetry — <code>app.turns</code> client_ai 13행에 provider/model/cost_usd 실적재(합 $1.22). ⑥ 레이아웃 시각 게이트 최신 9/9 + 2026-06-28 적대적 재검수 7/7 accept.</div> <div class="source-note"><b>닫은 항목(live 증거):</b> ① engine config 운영값(<code>claude_cli / 9099 / gateway-default</code>, durable, db). ② 상주 엔진풀 probe — 단일 session_id 2회 reused stream, TTFT 16674199ms, cost 누적 0.068→0.123. ③ 상주 엔진풀 RSS — gateway session 1개에서 <code>claude -p</code> child RSS 363.3MB, gateway RSS 16.2MB. ④ Postgres RLS/audit smoke 5 checks PASS. ⑤ turn cost telemetry — <code>app.turns</code> client_ai 13행에 provider/model/cost_usd 실적재(합 $1.22). ⑥ 레이아웃 시각 게이트 최신 9/9 + 2026-06-28 적대적 재검수 7/7 accept.</div>
<div class="source-note"><b>환경 제약으로 이 세션에서 못 닫는 항목(정직 표기):</b> 공개 Google OAuth 실제 <code>/turn</code>(OAuth start는 확인, 실제 계정 storageState 필요) · 실배포 <code>infra/.env</code> owner-secret fill-in · <code>vnet.18ka.net</code>/<code>api-vnet.18ka.net</code> DNS·OAuth redirect 등록 · 한신대 데이터/SSO 거버넌스 · G7 명시 동의 물리 마이크 3,120초와 공통 3,000초 운영 high-water, 독립 human voice-gain pack, canonical checker exit 0 · claude_cli↔Messages API 폴백 동일성 · 실제 Windows 재부팅 후 watchdog smoke · Phase 3 파일럿 게이트. current source 공개 배포, local voice exact ready, authenticated WSS 무마이크 rehearsal은 완료했다. 운영 원칙상 가짜 증거로 DONE 표기하지 않는다.</div> <div class="source-note"><b>환경·외부 승인 때문에 아직 못 닫는 항목(정직 표기):</b> 신규 Gmail 선택→Vignette 계정 생성은 사용자 행동시점 확인 필요 · C-001 외부 임상 검토자 이름·소속 기관·검토일·서면 결정 · <code>vnet.18ka.net</code>/<code>api-vnet.18ka.net</code> DNS·OAuth redirect 등록 · 한신대 데이터/SSO 거버넌스 · G7 명시 동의 물리 마이크 3,120초와 공통 3,000초 운영 high-water, 독립 human voice-gain pack, canonical checker exit 0 · claude_cli↔Messages API 폴백 동일성 · 실제 Windows 재부팅 후 watchdog smoke · Phase 3 파일럿 게이트. current source 공개 배포, generic Google callback, P20 실제 턴·종료·평가, local/public voice exact ready, authenticated WSS 무마이크 rehearsal은 완료했다. 운영 원칙상 가짜 증거로 DONE 표기하지 않는다.</div>
</div> </div>
<div class="tab-panel" id="panel-decisions" role="tabpanel" aria-labelledby="tab-decisions" hidden> <div class="tab-panel" id="panel-decisions" role="tabpanel" aria-labelledby="tab-decisions" hidden>
<div class="detail-head"><div><h3>윤찬 결정 상세 (전건 확정)</h3><p>람다가 단독으로 정하면 월권인 항목이었다. 2026-06-30 owner 결정으로 전건 확정됐고, 각 결정의 구현·실측은 후속 build/GATE로 남는다.</p></div><div class="mini-metrics"><span>결정 0개(전건 확정)</span><span>조건부 GO 사유</span></div></div> <div class="detail-head"><div><h3>윤찬 결정 상세 (전건 확정)</h3><p>람다가 단독으로 정하면 월권인 항목이었다. 2026-06-30 owner 결정으로 전건 확정됐고, 각 결정의 구현·실측은 후속 build/GATE로 남는다.</p></div><div class="mini-metrics"><span>결정 0개(전건 확정)</span><span>조건부 GO 사유</span></div></div>

View file

@ -96,6 +96,9 @@ python -m pytest engine_gateway/ --collect-only -q
| REQ-006 | `app/test_pii_masking_eval.py app/test_live_coach_sources.py app/test_client_reply_quality.py` | 24 passed — raw prompt와 구조화 결과의 counselor/client role masking | | REQ-006 | `app/test_pii_masking_eval.py app/test_live_coach_sources.py app/test_client_reply_quality.py` | 24 passed — raw prompt와 구조화 결과의 counselor/client role masking |
| REQ-007 | session persistence/evaluation 관련 API 9 files, live/session 묶음, 실제 DB persistence E2E | 163 + 50 pytest, DB E2E 1 passed — 실패한 옛 평가 뒤 새 회기 가능 | | REQ-007 | session persistence/evaluation 관련 API 9 files, live/session 묶음, 실제 DB persistence E2E | 163 + 50 pytest, DB E2E 1 passed — 실패한 옛 평가 뒤 새 회기 가능 |
| REQ-008 | `app/test_engine_health_contract.py`와 session stream 회귀 | health contract 1 passed; incomplete EOF는 live/session 50 묶음에 포함 | | REQ-008 | `app/test_engine_health_contract.py`와 session stream 회귀 | health contract 1 passed; incomplete EOF는 live/session 50 묶음에 포함 |
| REQ-001 공개 운영 | `https://vignette.chanpaca.net/login` + Google account chooser/callback | 로그인 DOM ‘모든 Google 계정’, `allowed_email_domains=[]`, twentyoz.kr/Gmail 동시 노출, 기존 Google 계정 callback→`/admin` 성공. 신규 Gmail 선택은 계정 생성 행동시점 확인 뒤 별도 실행 |
| REQ-005·007·008 공개 운영 | P20 회기 `03dddadd-adf3-4922-acbf-31002470da52` | 생성→자기점검 원장 잠금→실제 학습자/AI 내담자 2턴→종료→AI 평가 완료→P20 1회 기록 영속→다음 회기 버튼 재노출 |
| 운영 배포 | clean `2a396361…89c`, Pages `1f1ddf18-9d5c-4d83-95a7-8cd71245e646`, watchdog | local/public prod·db·engine·voice·web 정상, old-root runtime 0, watchdog 8 checks·LastTaskResult 0·failcount 0 |
로컬 Playwright는 기존 포트의 서버를 기본 재사용하지 않는다. 공개 preview나 다른 checkout의 stale bundle을 로컬 Playwright는 기존 포트의 서버를 기본 재사용하지 않는다. 공개 preview나 다른 checkout의 stale bundle을
현 작업트리 증거로 오인하지 않도록 충돌 시 fail-closed하며, 동일 dev server를 의도적으로 공유할 때만 현 작업트리 증거로 오인하지 않도록 충돌 시 fail-closed하며, 동일 dev server를 의도적으로 공유할 때만

View file

@ -12,9 +12,11 @@
> 섹션과 상세 근거 `docs/ops/source-docs-gap-analysis-2026-06-26.md`에서 추적한다. C1~C3/H·M 구조는 코드로 > 섹션과 상세 근거 `docs/ops/source-docs-gap-analysis-2026-06-26.md`에서 추적한다. C1~C3/H·M 구조는 코드로
> 선제 구축했고, 임상 문안·평가기준·골든셋 콘텐츠는 임상팀(구훈정·어유경) 외부 정의로 받는다. > 선제 구축했고, 임상 문안·평가기준·골든셋 콘텐츠는 임상팀(구훈정·어유경) 외부 정의로 받는다.
> >
> **개선관리 워크북(2026-08-27)** — C-002·C-003과 REQ-001~008은 내부 기술 구현 DONE이므로 열린 > **개선관리 워크북(2026-08-28)** — C-002·C-003과 REQ-001~008은 내부 기술 구현 DONE이며 clean
> 백로그에 중복하지 않는다. C-001은 자동 안전 게이트의 기술 사전검증만 완료됐고 임상 검토자 이름·소속 기관· > `2a396361…89c`/Pages `1f1ddf18…e646`, generic Google callback, 공개 P20 생성→응답→종료→평가 폐루프까지
> 검토일·서면 결정이 없어 B4 외부 GATE로 유지한다. 네 값이 모두 기록되기 전에는 완료로 닫지 않는다. > 운영 실증했으므로 열린 백로그에 중복하지 않는다. C-001은 자동 안전 게이트의 기술 사전검증만 완료됐고
> 임상 검토자 이름·소속 기관·검토일·서면 결정이 없어 B4 외부 GATE로 유지한다. 네 값이 모두 기록되기 전에는
> 완료로 닫지 않는다.
> >
> **Outcome & Alliance OS** — 2026-08-06 정식 전략 실행 트랙으로 승격했다. G0 Measurement Truth, G1 > **Outcome & Alliance OS** — 2026-08-06 정식 전략 실행 트랙으로 승격했다. G0 Measurement Truth, G1
> 현재 소스·실행 증거 재감사에서는 G0~G6과 G8이 DONE이다. G1 승격 prompt 1.2+read-skew/JSON 복구는 24/24 ready·방향 9/9·오류 0을 재확인했고, G0 census 29/29·위반 0, G4/G5 실제 API/DB/브라우저 폐루프, G6 safety metadata-only 최우선 runtime을 disposable clone에서 확인했다. G8은 실제 receipt-bound image rollback 2회(`nas-g8-723eeef2…`/`nas-g8-2738846c…`)에 더해 source HEAD `61a41d1f…6af`·tree `87dec55d…3b77`·archive `4d15d055…119d4d`의 candidate 112/112와 실제 NAS 평문 origin 112/112를 통과했다. 과거 `6030a677…c611`의 UUID 24건 실패와 후속 SHA 결함 rollback은 이력으로 보존하며 현재 완료 증거로 재사용하지 않는다. G7 Multimodal Alliance는 내부 구현 DONE과 외부 proof GATE를 분리한다. detached-clean public `a73bcd24…`·OpenAPI 126·`local_whisper`/`melotts` ready·authenticated WSS 무마이크 rehearsal까지 완료했고, 명시 동의 물리 마이크 3,120초·독립 라벨 voice-gain benchmark·동시 topology high-water를 추적한다. 외부 Deepgram/OpenAI adapter는 fallback으로 보존한다. G0~G8과 > 현재 소스·실행 증거 재감사에서는 G0~G6과 G8이 DONE이다. G1 승격 prompt 1.2+read-skew/JSON 복구는 24/24 ready·방향 9/9·오류 0을 재확인했고, G0 census 29/29·위반 0, G4/G5 실제 API/DB/브라우저 폐루프, G6 safety metadata-only 최우선 runtime을 disposable clone에서 확인했다. G8은 실제 receipt-bound image rollback 2회(`nas-g8-723eeef2…`/`nas-g8-2738846c…`)에 더해 source HEAD `61a41d1f…6af`·tree `87dec55d…3b77`·archive `4d15d055…119d4d`의 candidate 112/112와 실제 NAS 평문 origin 112/112를 통과했다. 과거 `6030a677…c611`의 UUID 24건 실패와 후속 SHA 결함 rollback은 이력으로 보존하며 현재 완료 증거로 재사용하지 않는다. G7 Multimodal Alliance는 내부 구현 DONE과 외부 proof GATE를 분리한다. detached-clean public `a73bcd24…`·OpenAPI 126·`local_whisper`/`melotts` ready·authenticated WSS 무마이크 rehearsal까지 완료했고, 명시 동의 물리 마이크 3,120초·독립 라벨 voice-gain benchmark·동시 topology high-water를 추적한다. 외부 Deepgram/OpenAI adapter는 fallback으로 보존한다. G0~G8과