G8 실제 rollback 증명 종료와 비-secure origin 회기 리뷰 크래시 수정

G8 마지막 게이트인 receipt-bound 실제 image rollback을 격리 NAS
vignette-preview-20260807 에서 실행해 종료했다.

Gate6 계약 정정:
감사 대상 current API 이미지가 com.docker.compose.project/service/version
image label 을 갖고 있어 "helper 의 compose label 0개" 계약은 감사되지 않은
다른 이미지를 쓰지 않는 한 성립하지 않는다. 계약을 key 부재가 아니라
소속(membership) 으로 바꿔 launch-nas-preview-g8-helpers.py 에 구현했다.
image 상속 label 을 baseline 으로 읽고 container 의 모든 compose label 이
baseline 과 같거나 선언된 격리 override 인지 검사하며, 최종 project 는
target 이 아니고 service 는 api/web/db/proxy 가 아니어야 한다. docker run
argv 에 target label 을 주입하면 fake-runner 테스트가 먼저 깨진다 (37/37).

실행 결과:
- rollback-old  receipt nas-g8-723eeef22eab05e63e3fafb0 -> 79ec../c530..
- restore-current receipt nas-g8-2738846cf2cf4fbe8ce0fc26 -> 52e0../6fdb..
- release gate/approval 각 2회 멱등, audit.ci_lifecycle_event rollback/executed 2,
  audit.ci_human_approval_event authorize_rollback 2, silent auto-promotion 0
- HMAC journal 6-record 체인 검증, health 3/3, OpenAPI 126, auth 401, Web 200
- helper 0, listener 0, 비밀 env 파기. down/volume rm/prune 미실행, 공개 런타임 미접촉
- 계획했던 Windows SSH 터널은 NAS sshd 가 direct-tcpip 를 거부해 사용할 수 없어
  sshd 설정 변경 대신 같은 격리 계약의 NAS-side probe 컨테이너로 실행했다

비-secure origin 크래시 수정:
배포된 NAS 프리뷰(평문 HTTP, 비-localhost)에 회기 스펙을 돌려 24건 실패를 확인했고
원인은 하나였다. crypto.randomUUID 는 secure context 전용인데 제품 코드 18곳이
fallback 없이 호출했고 RuptureRepairCard 는 렌더 시점 호출이라 회기 리뷰 라우트
전체가 error boundary 로 떨어졌다. 릴리스 게이트 108/108 은 localhost 후보 스택에서만
돌아 이 경로를 밟은 적이 없다. src/lib/uuid.ts 의 randomUuid() 로 통일하고 fallback 도
crypto.getRandomValues 를 우선 사용해 idempotency key 의 예측 불가능성을 유지했다.
회귀는 insecure-context-uuid.spec.ts 6/6 으로 고정했다(직접 호출 0건 검사 포함).
이 수정은 아직 NAS 에 배포하지 않았다.

검증:
API 898, gateway 58, executor 28, probe 11, helper launcher 37, release agent 21,
ruff clean, web api-types/typecheck/build, SSOT FAIL 0, SSOT unit 5/5,
dashboard E2E 10/10, 학생 폐루프 실 DB 브라우저 4/4(일회용 클론),
crypto 수정 후 기존 스펙 회귀 70/70, 복원된 NAS 실제 브라우저 SSE->DB 리뷰 PASS.

부수 발견(열린 항목):
공개 API 가 engine=false 로 degraded 인데 워치독이 이를 감지하지 못한다. engine 판정이
게이트웨이 /health 의 ok 만 보고 claude readiness probe 를 돌리지 않기 때문이다.
같은 .env 와 같은 CLI 로 새 게이트웨이를 다른 포트에 띄우면 즉시 ready 이므로 상주
프로세스의 세션만 죽은 형태다. TODO A절과 대시보드에 기록했다.

이 커밋은 파일 단위로 담겼다. 위 파일들에는 이전 세션의 미커밋 G0~G8 작업이 함께
들어 있으며, hunk 를 쪼개면 대시보드/체커/TODO 정합성이 깨져 SSOT 체커가 실패한다.
This commit is contained in:
Yun Chan 2026-08-07 22:17:20 +09:00
parent 76d0b9ae9b
commit 93dd8f82d7
22 changed files with 10057 additions and 473 deletions

View file

@ -50,7 +50,7 @@
.pulse-main h1{margin-top:9px;}
.pulse-state{margin:13px 0 0;color:var(--ink-2);font-size:13.5px;max-width:640px;}
.pulse-state b{color:var(--ink);}
.phase-rail{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;margin-top:18px;}
.phase-rail{display:grid;grid-template-columns:repeat(6,1fr);gap:7px;margin-top:18px;}
.pr-seg{position:relative;}
.pr-bar{height:7px;border-radius:999px;background:var(--paper-3);overflow:hidden;}
.pr-fill{height:100%;border-radius:999px;background:linear-gradient(90deg,var(--accent),var(--accent-deep));}
@ -201,7 +201,7 @@
.fold>summary .fmeta{margin-left:auto;font:650 11px/1 var(--mono);color:var(--ink-3);}
.fold-inner{padding:6px 18px 20px;border-top:1px solid var(--hair);}
.grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;}
.roadmap{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:11px;margin-top:6px;}
.roadmap{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:11px;margin-top:6px;}
.phase-card{min-width:0;background:var(--paper);border:1px solid var(--hair);border-radius:12px;padding:14px;}
.phase-card.current{border-color:color-mix(in srgb,var(--accent) 42%,var(--hair));background:linear-gradient(180deg,var(--accent-tint),var(--surface) 58%);}
.phase-card.next{border-color:color-mix(in srgb,var(--warn) 35%,var(--hair));}
@ -272,7 +272,7 @@
<div class="brand"><span class="mark" aria-hidden="true"></span><span>Vignette 커맨드센터<small>팀장 리뷰 · dev status</small></span></div>
<div class="head-right">
<a class="owner-pill" href="#owner"><span class="d" aria-hidden="true"></span>내 차례 <b id="pill-owner">0</b></a>
<span class="stamp">2026-07-30 KST</span>
<span class="stamp">2026-08-07 KST</span>
</div>
</header>
@ -282,15 +282,16 @@
<div class="pulse-main">
<span class="eyebrow">project pulse</span>
<h1>지금 위치: <em>Phase 0 제품 데모는 public /turn proof가 핵심 블로커</em>.<br><em>Phase 1 MVP 코어 루프</em>는 로컬 DB-backed 실증 완료.</h1>
<p class="pulse-state">코어(저항·반응 조절, 상태머신, RAG, 이론모드, 가드레일, 평가 JSON Schema)는 <b>잘 정렬</b>됐고, 학습자 홈·교수자 리뷰·공개 웹 로그인·공개 API/Tailnet 기본 스모크도 통과했다. 2026-06-30 레드팀 중 public API Cloudflare 530/error code 1033을 발견했지만, Docker Desktop/DB 재기동 후 public health 200과 비인증 <code>/personas</code> 401로 복구를 확인했다. 단, 공개 Google OAuth 실제 <code>/turn</code>, vnet DNS/zone/OAuth redirect, 실배포 <code>infra/.env</code>, 기관 결정, 물리 마이크·public WSS 같은 게이트는 별도로 남아 있다. 이 판은 <b>검증된 내부 완료</b><b>외부 증거가 필요한 항목</b>을 분리해서 보여준다.</p>
<p class="pulse-state"><b>긴급 운영 상태:</b> 2026-08-07 18:26 KST 공개 DB를 복구 named volume으로 전환했다. public owner 집계 users 84·sessions 30·turns 705, Google 계정 16·소유 회기 30, orphan 0이며 health·engine·OAuth·로그인 화면·watchdog가 정상이다. 보안상 기존 auth session은 복사하지 않아 모든 사용자는 Google 재로그인이 필요하고, 전환 직전 container·dump와 원본 volume은 삭제하지 않았다. <b>개발 상태:</b> G0 provenance census 29/29·위반 0과 G6 safety metadata-only 우선 runtime은 disposable clone에서 통과했다. G4·G5 실제 API/DB/browser 폐루프와 current exact SHA <code>6030a677…c611</code>의 NAS 승격은 완료됐고 전체 browser E2E 108/108·postdeploy SSE→DB review·health 3/3·OpenAPI 126을 통과했다. G8은 격리 NAS에서 실제 image rollback 2회를 executed receipt(<code>nas-g8-723eeef2…</code>/<code>nas-g8-2738846c…</code>)로 실행해 DONE이며, G7은 Deepgram live·인증 WSS·명시 동의 물리 마이크 50분·독립 라벨 voice-gain과 resource high-water 전까지 외부 GATE다.</p>
<div class="phase-rail" id="phase-rail" aria-label="Phase 진행 추정"></div>
<div class="mstrip" aria-label="검증 지표">
<span class="mchip good">Full E2E 기준선 <b>158</b></span>
<span class="mchip good">Node conformance OK · gateway <b>29</b> · backend <b>400</b></span>
<span class="mchip good">Layout 시각게이트 <b>9/9</b> pass</span>
<span class="mchip warn">Full E2E 현재 수집 <b>604</b> · 전체 GREEN 대기</span>
<span class="mchip good">현재 전체 회귀 · gateway <b>58</b> · backend <b>898</b></span>
<span class="mchip good">Outcome clean E2E <b>126</b> · visual <b>15/15</b></span>
<span class="mchip good">Alliance G1 baseline 1.2 <b>9/9</b> · 내부 DONE</span>
<span class="mchip">Tailnet <b>이전 확인 OK</b></span>
<span class="mchip good">Public API <b>recovered OK</b></span>
<span class="mchip crit">배포지 secrets <b>BLOCK</b></span>
<span class="mchip good">Public API <b>119 paths · G1~G8</b></span>
<span class="mchip good">Direct-runtime preflight <b>APP ROLE OK</b></span>
<span class="mchip crit">critical 3 <b>1차 완료·gate</b></span>
<span class="mchip">Decision <b>P0 조건부</b></span>
</div>
@ -608,6 +609,31 @@
<p class="dg-note">155차 적용(2026-07-31): 세션 텍스트 입력이 AI 생성·TTS 종료까지 잠기고 답변 표시 뒤에도 evaluator가 끝날 때까지 다음 전송이 약 24초 묶이던 학습 UX를 실제 브라우저와 gateway/API 계량으로 분해했다. textarea는 회기 종료·일시정지에서만 잠기며 생성·음성 준비·재생 중에는 다음 질문 초안을 계속 작성·보존하고, 내담자 응답 저장 직후에는 음성 재생과 무관하게 다음 전송을 허용한다. 관리자 DB의 Agy/Gemini 설정은 evaluator/review에 유지하되 실시간 client 역할은 <code>VIGNETTE_LIVE_CLIENT_PROVIDER=claude_cli</code> 전용 lane으로 분리해 회기별 <code>claude -p</code> 프로세스를 재사용한다. stream learner/client turn과 결정론 상태를 먼저 durable 저장하고 SSE <code>done</code>을 보낸 뒤 fast-loop 평가는 백그라운드에서 같은 learner turn normalized row에 붙이며 평가 기반 코칭 충전도 한 번만 적용한다. Agy fallback도 <code>stream-json</code> delta를 실제 SSE token으로 전달한다. 로컬 음성은 <code>-UseHiggsVoice</code>로 설치된 <code>higgs-audio-v3-tts-4b</code>를 loopback 상주시켜 P1 실제 답변을 24kHz WAV로 합성하며 저장소의 무참조 synthetic seed만 reference로 허용하고 non-dev는 fail-closed한다. <b>실증</b>: 변경 전 full API 완료 24.17/24.57초, 변경 후 실제 UI 첫 응답·전송 해제 9.58초와 상주 연속 턴 6.96초, 생성 중 초안 enabled/보존, TTS 중 보내기 enabled. Higgs full API 362,924 bytes/7.56초 WAV, provider/model 헤더 확인. backend 432/432, gateway 44/44, typecheck·API types·build, session stream 1/1, voice skip/draft 1/1 통과. <b>배포·공개 실증</b>: commit <code>c7883434</code>를 origin/master에 push하고 Cloudflare Pages production <code>505155c4-01f3-4eac-ad59-c2d323a0bb51</code>로 게시했다. custom/preview 모두 <code>index-BU5JjRnR.js</code>를 JavaScript 200으로 서빙하고 최근 5개 배포의 의존 자산을 보존한다. 공개 API는 prod·db=true·engine=true, auth config Google configured/dev login disabled, 비인증 personas·voice speech 401, Google 시작 302다. 실제 공개 로그인 1280×720 렌더에서 버튼 2개 enabled, 브라우저 warning/error 0을 확인했다. 공개 음성은 라이선스 경계상 <code>openai / gpt-4o-mini-tts</code>를 유지한다.</p>
<p class="dg-note">156차 적용(2026-07-31): 활성 상담 세션이 전역 테마와 무관하게 <code>.sx-page--active</code>에서 다크 팔레트를 다시 정의해, 라이트 설정에서도 화면은 다크인데 공통 <code>Surface inset</code>인 AI 코치만 밝게 뜨는 혼합 테마 결함을 수정했다. 세션 전용 <code>--bg-surface</code>/<code>--text-*</code>/<code>--accent</code> 덮어쓰기를 제거하고 전역 <code>data-theme</code>·<code>tokens.css</code>·공통 <code>Surface</code>를 그대로 사용해 라이트는 종이·글래스, 다크는 차콜·세이지로 함께 전환한다. 우측 레일은 <b>AI 코치 → 현재 신호 → 음성·AI 응답 상태</b> 순으로 재배치하고 의미 없는 equalizer 막대와 중복 화면 모드 행을 제거했다. 700px 이하 높이에서는 발화 예시·보조 흐름을 먼저 접고 코치 판단과 근거/이력 액션을 보존하며, 기존 사각지대였던 881~1180px에서도 코칭 모드에 AI 코치 카드만 전폭으로 남긴다. <b>검증</b>: <code>npm run check:design-ssot</code>, typecheck, build 통과, 세션 전수 desktop/mobile <code>30 passed / 2 skipped</code>, session-layout <code>8/8</code>, 7폭 layout-visual-gate <code>15/15</code>, 라이트 1366×640 코치·1024×640 압축 코치 및 다크 1440/1024/390 캡처 직접 확인. 로컬 작업트리 기준이며 배포 전이다.</p>
<p class="dg-note">157차 적용(2026-07-31): 사용자 제공 1536×1024 활성 세션 시안을 실제 세션 화면에 반영했다. 데스크톱을 <b>좌측 단일 컨텍스트 레일 326px / 중앙 인물 무대+자막 / 우측 단일 라이브 코칭 레일 357px / 하단 116px 제어바</b>로 재구성하고, 상태 신호 모드에서도 AI 코치의 개입 시점·남은 기회·코칭 포인트를 미리 이해할 수 있게 했다. 제공된 수채화 잎 5장은 BEN2로 투명 분리한 뒤 600×800 이하 알파 WebP로 최적화해 합계 약 158KB로 줄였고, 좌우 캔버스와 아바타 뒤에 장식 계층으로 연결했다. 새 E2E는 1408px 상단/본문, 1468px 제어바, 326/357px 레일, WebP 응답과 computed background 연결을 1536×1024에서 고정한다. 1366×768 이하에서는 스테이지를 압축해 자막이 주 작업영역을 잃지 않게 했다. <b>검증</b>: <code>npm run check:design-ssot</code>, typecheck, build 통과, 세션 전수 desktop/mobile <code>32 passed / 2 skipped</code>, session-layout <code>8/8</code>, 7폭 layout-visual-gate <code>15/15</code>, 1536×1024 라이트 캡처 직접 확인. 앱 commit <code>12bdc594</code>를 Cloudflare Pages production에 배포하고 배포 증거 commit <code>32c0b97d</code>를 연동한 최종 production <code>f9b06388</code>까지 완료했다. 커스텀 도메인의 <code>index-CzevzoM7.js</code>, <code>Session-BWMFTqgE.js</code>, <code>Session-D7DZVnh0.css</code>, <code>leaf-1.webp</code>가 각각 올바른 JavaScript/CSS/WebP MIME으로 200을 반환했다. 공개 로그인 실렌더·브라우저 warning/error 0, API <code>prod/db/engine=true</code>, 비로그인 personas 401, Google OAuth 시작 302, watchdog 5항목 healthy도 확인했다.</p>
<p class="dg-note">158차 적용(2026-07-31): 관리자 <b>Provider·모델별 사용 원장</b>에서 Claude CLI만 비용이 잡히고 Agy/Gemini가 0달러로 보이던 원인을 수정했다. Claude CLI는 SDK가 반환한 호출별 비용 추정값을 우선하고, 비용이 없는 Agy/Gemini·Codex·Claude API는 버전 고정 공식 참조단가로 입력·캐시 입력·출력 토큰을 환산한다. 기존 DB에 비용 0으로 저장된 행도 <code>/admin/usage</code> 조회 시 보정하며, 공식 단가가 등록되지 않은 모델은 0달러 대신 <code>미산정</code>으로 표시한다. 응답과 리포트는 <code>recorded_cost_usd</code>, <code>estimated_cost_usd</code>, <code>cost_basis</code>, 단가 라벨·출처를 분리한다. 공개 DB-backed 30일 원장에서 <code>gemini-3.6-flash-high</code> 5호출·입력 35,703·출력 1,129가 <code>$0.062022</code>로 보정되고 총비용에도 합산되는 것을 인증 요청으로 확인했다. <b>검증</b>: backend/gateway focused <code>66 passed</code>, API type generation/check, typecheck, build, 관리자 desktop/mobile focused E2E <code>2 passed</code>, 7폭 focused layout visual gate <code>1 passed</code>. 공개 API 프로세스를 재시작하고 Cloudflare Pages production <code>11b3e11f</code>에 배포했으며, 커스텀 도메인의 <code>AdminAi-BfxMUlzj.js</code><code>AdminAi-XHkda_d4.css</code>가 올바른 MIME으로 200을 반환한다.</p>
<p class="dg-note">159차 적용(2026-07-31): Claude CLI result에 실제 <code>usage</code>/<code>modelUsage</code>가 있는데도 게이트웨이의 generate·SSE done 응답이 <code>tokens_in=0</code>, <code>tokens_out=0</code>을 하드코딩해 DB 원장에 0을 저장하던 근본 원인을 수정했다. <code>modelUsage</code>/<code>model_usage</code>가 있으면 메인 호출과 서브에이전트를 모델별로 합산하고, 없을 때 최상위 <code>usage</code>로 폴백한다. 입력 원장은 비캐시 입력 + cache read + cache creation 합계다. 과거 미수집 행은 토큰을 비용으로 역산하지 않고 <code>token_unmetered_turns</code>로 분리해 화면에 <code>미계량</code>으로 표시하며, Claude <code>total_cost_usd</code>는 청구 실비가 아니라 SDK 추정치이므로 <code>provider_estimate</code>/<code>SDK 추정</code>으로 바로잡았다. <b>검증</b>: backend 전체 <code>436 passed</code>, gateway 전체 <code>45 passed</code>, API type generation/check, typecheck, build, 관리자 desktop/mobile <code>2 passed</code>, 7폭 focused layout gate <code>1 passed</code>. 신규 live Opus generate는 입력 <code>31,918</code>·출력 <code>4</code>·비용 추정 <code>$0.124862</code>, Haiku SSE done은 입력 <code>30,450</code>·출력 <code>159</code>·비용 추정 <code>$0.061685</code>를 반환했다. 운영 DB 30일 원장의 과거 Claude <code>194</code>건은 <code>token_unmetered_turns=194</code>, <code>cost_basis=provider_estimate</code>로 확인했다. 공개 런타임을 새 gateway/API로 교체하고 Cloudflare Pages production <code>10c2bfc3</code>에 배포했다. 커스텀 도메인의 <code>index-BDlbUpT7.js</code>, <code>AdminAi-r9AkYKAl.js</code>, <code>AdminAi-D7JtoYC_.css</code>는 올바른 MIME으로 200이며, 실제 관리자 임시 세션의 공개 브라우저에서 <code>미계량</code>·<code>SDK 추정</code>·토큰 커버리지와 Codex/Agy catalog를 확인하고 세션·storage state를 즉시 폐기했다.</p>
<p class="dg-note">160차 적용(2026-07-31): 159차 이전 Claude 토큰 0/0 행을 비용에서 역산하지 않고 실제 로컬 Claude 실행 JSONL로 제한 백필했다. JSONL <code>3,908</code>개의 assistant usage record <code>3,848</code>개를 본문 출력 없이 읽고, 정규화 응답 SHA-256과 DB 생성 시각 창(-30초~+180초)이 모두 맞으며 후보가 정확히 1개인 경우만 허용했다. 운영 전체 Claude <code>442</code>건 중 <code>169</code>건을 실제 입력 <code>5,179,999</code>·출력 <code>46,910</code> 토큰으로 복구했고, 후보 없음 <code>273</code>건은 계속 <code>미계량</code>, 모호한 후보는 <code>0</code>건이다. apply는 <code>--expected-matches 169</code>와 행별 <code>UPDATE 1</code> 가드를 통과했으며 적용 후 dry-run의 추가 exact match는 <code>0</code>건이다. 확인 시점 30일 창은 Claude <code>183</code>건 중 계량 <code>125</code>·미계량 <code>58</code>건이었다. <b>검증</b>: backend 전체 <code>439 passed</code>, gateway 전체 <code>45 passed</code>, 공개 관리자 브라우저 <code>1 passed</code>에서 Claude 실제 토큰과 부분 계량 <code>125/183회</code>, 잔여 미계량 설명, 브라우저 오류 0을 확인하고 임시 인증 세션·storage state를 폐기했다. DB-only 백필이므로 추가 웹 배포 없이 공개 UI가 live API 결과를 즉시 반영한다.</p>
<p class="dg-note">161차 적용(2026-08-06): Outcome &amp; Alliance OS <b>G1 Alliance Core</b>를 증거 게이트로 닫았다. 수련생 자기평가를 먼저 append-only로 잠근 뒤 가상내담자와 독립 관찰자를 별도 모델 실행·세션으로 평가하며, 공개 전에는 외부 관점을 숨기고 terminal 상태에서만 3관점 × goal/task/bond 9개 축을 함께 보여준다. 교수자 재평정은 근거 장면·메모를 강제하고 이전 평정을 supersede하는 append-only 원장으로 남긴다. 학습자 리뷰는 축별 총점 없이 관점 차이·근거 장면·provenance를 데스크톱 표와 모바일 카드로 제공한다. <b>검증:</b> focused backend <code>40 passed</code>, 실 PostgreSQL RLS·상태전이·재시도 model-run·교수자 supersession smoke, Alliance Pulse desktop/mobile <code>6/6</code>와 기존 회기 리뷰 <code>12/12</code>. prompt <code>1.2.0</code> 합성 gold는 방향 정확도 <code>9/9</code>, 최종 실패 <code>0</code>, 근거 recall <code>88.9%</code>이며 실패한 첫 시도 2건도 provenance로 보존됐다. G2 종단 성과 궤적을 병렬 구현 중이다.</p>
<p class="dg-note">162차 적용(2026-08-06): Outcome &amp; Alliance OS <b>G2 Longitudinal Outcome Trajectory</b>를 증거 게이트로 닫고 G3를 BUILD로 승격했다. 교육용 합성 5회기 기대분포와 고통 부담·일상 기능·학습 참여 세 축을 총점 없이 추적하며, 누락은 무점수, safety는 별도 참조, 관계 합의·미해결 균열은 역할별 문장으로 분리한다. 학습자 리뷰에는 1~5회기 타임라인, 축별 상태·불확실성·근거·반대근거·다음 질문과 최신 회기 자기보고 체크인을 연결했다. <b>검증:</b> 4-case×5-session benchmark status 정확도 <code>1.0</code>, false alert·critical miss <code>0</code>; 실제 DB/API 한 case S1~S5·15개 관측, 동일 제출 멱등성, 변경 payload 409, 학습자 소유권·교수자 cohort·교차 cohort 차단, role-safe 관계 기억 통과. G2 desktop/mobile <code>12/12</code>, G1+기존 리뷰 <code>15/15</code>, G2/G3 통합 backend <code>90 passed</code>다.</p>
<p class="dg-note">163차 적용(2026-08-06): Outcome &amp; Alliance OS <b>G3 Rupture &amp; Repair Lab</b>을 증거 게이트로 닫고 G4를 BUILD로 승격했다. 9종 파열 상태머신·append-only 관측/재조정/안전참조 원장, 텍스트·SSE·음성 공통 durable-turn 감지, 후속 발화의 missed/partial/resolved reconciliation, 역할별 리뷰·교수자 supersession, 4~6턴 희소 Scenario Director와 prompt/SSE 내부 라벨 누출 차단을 연결했다. <b>검증:</b> 11-case benchmark 유형 macro-F1 <code>1.0</code>, 복구 상태 정확도 <code>1.0</code>, critical miss·judge gaming·암기문구 false resolution <code>0</code>; Scenario/G3 집중 <code>107 passed</code>, G0~G8 통합 계약 <code>251 passed</code>, 리뷰 desktop/mobile <code>50/50</code>. 실제 DB/API 회기에서 durable turn UUID 2개, 내부 토큰 write, 멱등 retry/변조 409, learner/cohort RLS, 교수자 append-only correction과 최종 <code>resolved</code>를 확인했다.</p>
<p class="dg-note">164차 적용(2026-08-06): Outcome &amp; Alliance OS <b>G4 Deliberate Practice Engine</b>을 증거 게이트로 닫고 G5를 BUILD로 승격했다. 평가 장면을 관찰 가능한 원자 행동과 replay·branch·constrained response·voice retry·difficulty ladder 5종 prescription으로 연결하고, competency graph의 약점·망각 위험에 따라 다음 연습을 고른다. 익숙한 장면 반복이나 자기 성공 주장만으로 mastery를 열지 않고 미지 사례 전이를 요구한다. <b>검증:</b> G4 core/store/API <code>54 passed</code>, G4 리뷰 desktop/mobile <code>8/8</code>, G1~G4+기존 리뷰 <code>58/58</code>. 실제 DB/API 회기에서 durable turn 근거 처방→학습자 시도→교수자 append-only correction, 안정 멱등 retry/변조 409, learner/cohort RLS, 보상 해킹 차단, 총점·XP 없음과 비임상 경계를 확인했다.</p>
<p class="dg-note">165차 적용(2026-08-06): Outcome &amp; Alliance OS <b>G5 Calibration Mirror &amp; Transfer</b>를 증거 게이트로 닫고 G6를 BUILD로 승격했다. 외부평가 전 prediction revision과 불가역 lock, 독립 runtime observation reveal, 역량별 calibration error·95% 구간·과신/과소신 처방, 네 변주 축 unseen transfer와 암기 문구 차단, 합성 subgroup drift를 역할 안전 원장/UI에 연결했다. <b>검증:</b> G5 core/store/API <code>41 passed</code>, 4-case expectation accuracy <code>1.0</code>, 보정 MAE <code>0.667→0.267</code>, unseen transfer 4/4, 암기 false verification 0, drift gap 0.667. 실제 DB/API revision→lock→reveal·멱등/변조 409·post-lock 422·RLS, G5 UI 4/4와 G1~G5 리뷰 <code>62/62</code>, typecheck/build를 통과했다.</p>
<p class="dg-note">166차 적용(2026-08-06): Outcome &amp; Alliance OS <b>G6 Supervision &amp; Research OS</b>를 증거 게이트로 닫고 G7을 BUILD로 승격했다. 위험·정체·미해결 관계 사건 attention queue와 3클릭 원장 drilldown, metadata-only 교수자/AI 불일치 dataset·audit, curriculum gap, model/prompt/instrument/subgroup drift, Phase 3 네 도메인 artifact provenance를 역할 안전 원장/UI에 연결했다. <b>검증:</b> G6 core/store/schema <code>28 passed</code>, 6-signal queue 순서 정확, raw transcript row 0, drift expected/actual 일치, manifest 네 도메인 전건. 실제 DB/API 멱등/409·AI-view·역할/cohort RLS·audit, version/subgroup/artifact hydrate 통과. G6 UI desktop/mobile <code>6/6</code>, typecheck/build를 통과했다.</p>
<p class="dg-note">167차 적용(2026-08-06→07): Outcome &amp; Alliance OS <b>G7 Multimodal Alliance</b>의 내부 제품 범위를 완성했다. 동의 preflight, 한 오디오 시계의 익명 STT word·silence/overlap/interruption/prosody, 독립 text/voice 측정과 calibrated no-gain fusion, 비임상 상호작용 신호 계약, 원음/metadata 역할 경계, 철회와 audio/derived tombstone을 실제 API/DB 원장에 연결했다. 회기 리뷰에는 시간축·독립 측정·보존 경계와 음성 재연습 CTA를 제공한다. <b>검증:</b> backend G0~G8 묶음 <code>393 passed</code>, 실제 API 멱등/변조409·RLS·융합 <code>[true,false,false]</code>·삭제, G7 desktop/mobile <code>8/8</code>, session review <code>24/24</code>, layout <code>15/15 + 8/8</code>, G1~G8 최종 UI 묶음 <code>84/84</code>. 물리 마이크·공개 WSS·50분 장시간 실증은 B2 외부 게이트로 남아 있다.</p>
<p class="dg-note">168차 적용(2026-08-06→07): Outcome &amp; Alliance OS <b>G8 Autonomous Content &amp; Continuous Improvement</b>의 내부 제품 범위를 완성했다. source→draft→독립 red-team→benchmark→human catalog gate, 모델·릴리스별 baseline/threshold/provenance/rollback 증거 rail, append-only 승인·monitor·rollback lifecycle, 운영 incident의 4-node 회귀 DAG를 관리자 릴리스 제어석과 실제 API/DB에 연결했다. 자동 게시 버튼은 없으며 human gate 전에는 효과가 없다. <b>검증:</b> G8 UI desktop/mobile <code>8/8</code>, 기존 admin <code>40/40</code>, 실제 API 멱등/변조409·401/403·4종 artifact·lifecycle 6·DAG 4/4, 금지 데이터 0. 현재 공개 OpenAPI에는 G7/G8 route가 각각 <code>0</code>개여서 실제 배포·public proof를 DONE으로 표시하지 않는다.</p>
<p class="dg-note">169차 적용(2026-08-07): G7/G8 외부 승격 전 로컬 릴리스 준비를 강화했다. 실제 loopback <code>/voice/ws</code> short soak는 8.015초 동안 연결 <code>83/83</code>·성공 발화 79·철회/재연결/overflow 복구를 통과했고 API/gateway 전체 <code>805 passed</code>지만, 물리 마이크·public WSS·실행된 50분 증거로 확대하지 않는다. G8 시각 QA는 승인 차단 이유를 상시 문구·<code>aria-describedby</code>·semantic form으로 고쳐 desktop/mobile <code>16/16</code>과 build를 통과했다. 배포 프리플라이트는 G3~G8 독립 32자 토큰과 G0~G8 migration sentinel을 fail-closed로 검사한다. 당시 199파일 release-only patch는 clean HEAD <code>git apply --check</code>를 통과했으나 후속 병렬 편집으로 manifest와 달라져 무효화했으며, 재분류·결정적 재빌드 전에는 배포에 사용할 수 없다. 공개 OpenAPI의 G7/G8 경로는 재확인 시점에도 각각 0개라 두 카드 상태는 BUILD로 유지한다.</p>
<p class="dg-note">170차 적용(2026-08-07): 병렬 개발 결과를 학생 자기주도 수련의 실제 실행 경로로 통합했다. G1은 회기 전 pre pulse를 fail-closed로, 첫 라운드 뒤 mid pulse를 비차단형으로 연결했고 desktop/mobile focused <code>2/2</code>와 시각 증거 4장을 보존했다. G4/G5 카드의 replay·branch·제약 응답·음성 재시도·난이도 사다리·미지 전이는 학습자 홈→사전 설정→실제 새 Session까지 typed launch intent를 유지하며 관련 UI <code>22/22</code>와 통합 묶음 <code>59/59</code>를 통과했다. 현행 API 기준 learner/session/layout 묶음은 <code>37/37</code>, API/gateway는 <code>767 + 45 passed</code>, typecheck/build/API 계약도 통과했다. dirty 250개는 Outcome 관련 228·혼합 4·보존 제외 18로 전건 분류했고, 혼합 문서 exact hunk와 clean-source API 타입 재생성으로 만든 223파일 release-only patch를 두 번 동일하게 조립해 clean HEAD와 canonical clean index 적용 검사를 통과했다. 바이너리 시각 증거 4장은 manifest에는 관련 증거로 등록하되 텍스트 patch와 분리했다. G7 물리 마이크·공개 WSS·50분 실측과 G8 실제 배포·public proof는 여전히 BUILD다.</p>
<p class="dg-note">171차 적용(2026-08-07): G8 agentic worker를 기본 비활성 opt-in scheduler로 연결했다. repo-approved 비식별 source는 immutable <code>app.ci_agentic_job</code>, <code>FOR UPDATE SKIP LOCKED</code> lease, retry 상태로 관리하며 source usage·classification·본문 hash·PII를 engine 전에 재검증한다. 실제 <code>claude_cli/claude-opus-4-8</code>에서 generator 1·독립 reviewer 2·variant generator 1·독립 judge 3, 총 7 calls를 실행해 dev PostgreSQL reviewer 2·variant 3·pass rate 1.0·<code>pending_human_approval</code>을 저장했다. 동일 UUID replay는 model call 0, human approval/catalog row는 0, clinical claim은 false다. engine timeout·answer leakage·red-team finding 실패도 pipeline 저장 0건으로 증명했다. 전체 API/gateway <code>858 passed</code>, Ruff·API type check·web typecheck·SSOT checker를 통과했다. 운영 drift trigger·사람 payload 검수 E2E·release-agent 폐루프 전까지 G8은 BUILD다.</p>
<p class="dg-note">171차 적용(2026-08-07): G7 voice code/internal 경계를 Deepgram streaming adapter와 운영 전환용 fail-closed 계약까지 확장했다. interim/final·word timestamp·provider event를 처리하고, word 원문 대신 deployment secret 기반 HMAC pseudonym만 저장한다. 열린 stream은 동의를 1초마다 재검사해 철회 시 abort하며, Session은 음성 단절 뒤 작성 중 텍스트와 텍스트 계속하기·키보드 재연결을 보존한다. WSS <code>ready</code>는 실제 STT/TTS provider/model을 반환하고 public runner v3의 mic-free preflight가 네 기대값을 exact match한다. full soak는 명시적 확인 전 장치를 열거하지 않는다. 운영 TTS는 OpenAI API <code>gpt-4o-mini-tts</code>로 고정하고 공식 앱 통합·출력 소유 근거와 회기 전·중 AI 생성 음성 고지를 반영했다. <b>검증:</b> voice/G7 backend <code>73 passed</code>, public runner <code>12 passed</code>, disclosure desktop/mobile E2E, SSOT checker green. 실제 Deepgram key·quota live, expected provider/model authenticated public ready, 명시 동의 물리 마이크와 50분 soak가 없어 G7은 계속 BUILD다.</p>
<p class="dg-note">172차 적용(2026-08-07): G7 voice hardening을 235파일 release-only patch <code>3197805058e3…2bc</code>로 clean worktree에서 재조립·검증한 뒤 공개 API 8001과 Cloudflare Pages production <code>6d7e89d5</code>에 재배포했다. API는 새 clean 경로에서 <code>prod/db/engine=true</code>, OpenAPI 119 paths, 인증 401·Google OAuth 302를 유지하고 <code>/voice/health</code>가 STT <code>openai/gpt-4o-transcribe</code>·TTS <code>openai/gpt-4o-mini-tts</code>를 반환한다. 공개 WSS 비인증 차단은 <code>1008</code>, custom/immutable web은 새 <code>index-DZZoYvZq.js</code>와 AI 생성 음성 고지 포함 Session 청크를 올바른 MIME으로 제공하며, watchdog도 새 clean 경로로 재등록해 <code>LastTaskResult=0</code>을 확인했다. 운영 Deepgram key가 없어 streaming provider는 아직 활성화하지 않았고 authenticated ready·명시 동의 물리 마이크·50분 soak도 미실행이므로 G7은 계속 BUILD다.</p>
<p class="dg-note">173차 적용(2026-08-07): G7 완료감사에서 내부 과대주장을 바로잡았다. benchmark는 calibration 점수 재진술 대신 synthetic gold target에 대한 text-only와 calibrated multimodal의 <code>1-MAE 0.9533→0.9673</code>, gain <code>+0.014</code>(최소 <code>0.01</code>)를 직접 계산하고 gold 변조 반례를 통과한다. consent mutation·timeline·measurement는 session 공통 PostgreSQL transaction lock으로 직렬화했으며 실제 개발 DB 동시 철회에서 미커밋 writer 대기, 커밋 뒤 저장 차단, timeline row <code>0</code>을 확인했다. route는 10MiB append 전 거부, transcript event queue <code>32</code>, Deepgram receive queue <code>16</code>을 사용하고 3초 loopback에서 연결 <code>61/61</code>·발화 <code>57</code>·overflow 복구·10MiB RSS probe를 통과했다. 다만 synthetic label은 독립 임상/파일럿 효과 증거가 아니고 단일 프로세스 probe는 실제 worker·Uvicorn·OS·Cloudflare high-water를 대체하지 않는다.</p>
<p class="dg-note">174차 적용(2026-08-07): 학생 자기주도 수련의 <b>홈 추천→목표 선택→텍스트/SSE 회기→종료·리뷰→G4 처방→새 회기 재연습</b>을 실제 <code>src</code> 제품 화면 하나의 상태 흐름으로 묶었다. desktop/mobile <code>2/2</code>, typecheck와 고정 캡처 9장 직접 QA를 통과했다. 홈 핵심 CTA는 44px·4.5:1 이상 대비로 보정했고, 390×844·320×568 활성 회기의 아바타/문구 겹침 0·축어록/입력창 카드 내부 포함을 고정했다. 리뷰→재연습의 내부 criterion/counterevidence/UUID/영문 이론키는 사용자용 한국어로 치환했다. 이 브라우저 증거는 미소유 <code>/api/**</code>를 404로 닫은 로그인 없는 route fixture이며 실제 DB 폐루프가 아니다. 실 PostgreSQL production caller 증거와 UI 소비 증거를 분리해 기록한다. 리뷰 1~5 척도는 320px에서 3+2로 재배치해 다섯 선택지 44px 이상·내부/페이지 overflow 0과 desktop/mobile <code>8/8</code>을 확인했다. 상세: <code>ops/outcome-os-self-directed-learning-loop-ui-evidence-2026-08-07.md</code>.</p>
<p class="dg-note">175차 적용(2026-08-07): <b>격리 NAS 프리뷰</b><code>http://100.116.83.60:8088</code>에 배포하고 실제 브라우저 회기와 review API의 저장 축어록 2턴을 확인했다. 전용 Compose 프로젝트·포트·네트워크·볼륨만 대상으로 배포했으며 기존 프로젝트 중단·재생성 명령은 실행하지 않았다. 매일 04:30 KST <b>Vignette 회기 E2E 정기 검증</b>(automation id <code>vignette-e2e</code>)을 ACTIVE로 구성했다. 새 기능이 material milestone이고 release-only patch 결정성·manifest·clean-index·NAS preflight가 모두 통과하며 배포 SHA가 달라질 때만 같은 격리 프리뷰를 승격한다. 실행 이력은 첫 스케줄 뒤 별도 증거로 남긴다. 증거: <a href="./ops/nas-preview-deployment-evidence-2026-08-07.md">배포 증거</a>, <a href="./ops/evidence/nas-preview-live-turn-2026-08-07.png">브라우저 증거</a>. 이 프리뷰와 자동화는 G7 종료 증거가 아니다. 물리 마이크 캡처는 미승인이고 Deepgram 운영 키가 없어 G7은 계속 <b>BUILD</b>다.</p>
<p class="dg-note">176차 적용(2026-08-07): G8의 세 내부 결손을 병렬 구현·독립 감사로 닫았다. G6 drift 원장의 canonical 임계값·subgroup 근거를 대조하는 default-off trigger는 실 DB incident 1·DAG 4·job 1, 멱등·동시성·approval/catalog 0을 통과했고 문자열만 믿던 fail-open을 RED로 수정했다. 기존 실제 Claude pending 후보는 새 모델 호출 0회로 격리 8011/5181 관리자 browser에서 catalog 0→1·approval 1, learner/teacher 403·replay 멱등·변조 409·민감 projection 비노출을 확인했다. 별도 실엔진 후보의 answer leakage는 422·저장 0으로 차단했다. release agent는 material+changed SHA·patch 2회 결정성·manifest/clean candidate·API/Web/회기 gate·NAS snapshot/semantic runtime/browser·rollback·exact-SHA SSOT handoff를 구현했고, 독립 감사에서 active-state drift·경로 탈출·secret archive·병렬 volume 충돌 네 결함을 수정했다. 전체 API/gateway <code>891 passed</code>, release governance <code>35/35</code>, 관리자·자기주도·회기 desktop/mobile <code>26/26</code>, API type·typecheck·build를 통과했다. 변경 SHA의 실제 격리 NAS 승격 전까지 G8은 <b>BUILD</b>다.</p>
<p class="dg-note">177차 적용(2026-08-07): G8 release-only SHA <code>e9b482ccba61…e99</code>를 격리 NAS <code>vignette-preview-20260807</code>에 실제 승격했다. Windows clean candidate의 <code>bash\r</code> DB init 실패, legacy env 경로 오판, 교체 직후 readiness 502를 각각 fail-closed RED로 재현하고 LF 정규화·snapshot env 추적/preflight·180초 bounded readiness로 수정했다. 선행 502 실행은 기존 이미지로 자동 rollback하고 health·OpenAPI 122·auth 401·이미지 ID를 재검증했다. 최종 실행은 API/Web 새 이미지, health ok·db/engine true, OpenAPI 123·auth 401·G0~G8, readiness 3회, 실제 postdeploy browser SSE→DB-backed review를 통과했으며 물리 마이크는 사용하지 않았다. release-agent <code>20/20</code>, final session E2E <code>559.812s</code>, browser review <code>26.921s</code>. exact SHA를 TODO·백로그·manifest와 동기화해 G8은 <b>DONE</b>이다. G7 외부 증거는 그대로 BUILD다.</p>
<p class="dg-note">178차 적용(2026-08-07): G7을 가짜 외부 증거로 닫을 수 없도록 제품 동의와 종료 checker를 연결했다. Session은 처리 목적·전송/전사·침묵/속도/끼어듦 파생·30일 보존·원음 미보존·철회/삭제·텍스트 대안을 설명하고, 서버 consent ledger 성공 전 <code>getUserMedia=0</code>·voice WebSocket <code>0</code>을 유지한다. 원장 지연·실패와 늦은 권한 응답도 capture를 남기지 않으며 Space를 제거하고 <code>Alt+M</code>을 안내한다. public runner v4는 turn별 interim ≥1·speech-final=1과 latency를, 관리자 runtime sampler는 worker/Uvicorn queue high-water를, Linux sampler는 exact image/container/cgroup/proc/Docker/TCP high-water를 기록한다. 별도 human contract는 synthetic/raw material을 거부하고 30명/50회기/150축·blind 2인·ICC/κ·10,000 cluster bootstrap을 재계산한다. 네 artifact는 같은 public host·겹치는 50분 시간창이어야 canonical checker를 통과한다. <b>검증:</b> API/G7 <code>92 passed</code>, evidence runner/checker·release gate <code>31 passed</code>, voice UI <code>2/2</code>, typecheck·API type·Ruff·py_compile. 실제 마이크·운영 Deepgram·실제 참가자는 사용하지 않아 G7은 계속 <b>BUILD</b>다.</p>
<p class="dg-note">179차 적용(2026-08-07): G7 내부 hardening release-only SHA <code>a8c27b0aadcb9dacea86c4be5e62e19277b9cc2678ebca51aa02998d2c2d1a0d</code>를 격리 NAS <code>vignette-preview-20260807</code>에 승격했다. 첫 release-agent 실행은 새 동의 모달을 따르지 않던 DB-backed mic fixture 1건을 23/24에서 fail-closed로 차단하고 원격을 변경하지 않았다. fixture를 마이크→동의 원장→synthetic capture 순서로 고친 뒤 focused <code>1/1</code>, clean candidate session E2E <code>24/24</code>, API 전체, API contract·typecheck·build를 통과했다. 최종 API/Web 이미지 <code>79ec…4450</code>/<code>c530…2f28</code>, health ok·db/engine true, OpenAPI 124·auth 401·G0~G8, readiness 3회, NAS browser SSE→DB review를 확인했다. 물리 마이크는 사용하지 않았고 G7 외부 four-artifact gate는 계속 <b>BUILD</b>다.</p>
<p class="dg-note">180차 적용(2026-08-07): current source release-only SHA <code>6030a677af7e…c611</code>를 격리 NAS <code>vignette-preview-20260807</code>에 승격했다. 최초 전체 gate는 108개 중 5개를 fixture drift 2종과 runtime-critical <code>shell.css</code> 분류 누락으로 차단해 원격을 바꾸지 않았고, G5→G4 무호출·StrictMode retry·learner 모바일 4열 packaging을 focused 6/6과 manifest 회귀로 고정했다. 최종 candidate browser E2E <code>108/108</code>, postdeploy 실제 SSE→DB review <code>32.437s</code>, health <code>3/3</code>, OpenAPI 126·auth 401·G0~G8 route를 통과했다. API/Web 이미지는 <code>52e0…8b2d</code>/<code>6fdb…f215</code>이며 named DB volume과 배포 전 dump를 보존했다. 이 승격은 current runtime 증거이고 G8 receipt-bound 실제 image rollback은 별도 GATE다.</p>
<p class="dg-note">181차 적용(2026-08-07): <b>G8의 마지막 게이트인 실제 receipt-bound image rollback을 격리 NAS에서 실행</b>해 DONE으로 승격했다. 먼저 성립 불가능한 Gate6 계약을 정정했다. 감사 대상 current API 이미지 자체가 <code>com.docker.compose.project=vignette-preview-20260807</code>·<code>service=api</code> image label을 갖고 있어 "helper의 compose label 0개"는 감사되지 않은 다른 이미지를 쓰지 않는 한 성립하지 않는다. 그래서 계약을 <b>key 부재가 아니라 소속</b>으로 바꿔 <code>scripts/launch-nas-preview-g8-helpers.py</code>에 고정했다. image 상속 label을 baseline으로 읽고, container의 모든 compose label이 baseline과 같거나 선언된 격리 override인지 검사하며, 최종 project는 <code>vignette-g8-helper-*</code>·service는 <code>g8-rollback-*</code>이어야 하고, <code>docker run</code> argv에 target project/service label을 주입하면 fake-runner 테스트가 먼저 깨진다(<code>37/37</code>). 실행은 executor <code>127.0.0.1:18149</code>(host network·read-only rootfs·cap-drop ALL·no-new-privileges·uid1028/gid100·group101)와 별도 lifecycle의 control-plane API <code>127.0.0.1:8018</code>로 구성했다. 계획했던 Windows SSH 터널은 NAS sshd가 <code>administratively prohibited</code>로 direct-tcpip를 거부해 사용할 수 없었고, sshd 설정을 바꾸는 대신 같은 격리 계약의 NAS-side probe 컨테이너에서 실행해 control-plane(8018)·preview(8088) origin 분리를 그대로 유지했다. 결과는 <code>rollback-old</code> receipt <code>nas-g8-723eeef2…</code>, <code>restore-current</code> receipt <code>nas-g8-2738846c…</code>로 실제 이미지가 <code>52e0/6fdb</code><code>79ec/c530</code><code>52e0/6fdb</code>로 왕복했고, release gate·approval 2회 멱등, DB <code>audit.ci_lifecycle_event</code> <code>rollback/executed</code> 2건과 receipt id 결속, silent auto-promotion 0, HMAC journal 6-record 체인 검증, health 3/3·OpenAPI 126·auth 401·Web 200, helper 0·listener 0 복귀와 비밀 env 파기를 확인했다. <code>down</code>·<code>volume rm</code>·<code>prune</code>은 실행하지 않았고 공개 런타임은 건드리지 않았다. G7은 Deepgram live·인증 WSS·명시 동의 물리 마이크 50분·독립 라벨 human pack이 남아 <b>외부 GATE</b>로 유지한다.</p>
<div class="dg-principles" aria-label="디자인 생성 가드레일">
<div><b>래스터만 사용</b><span>이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.</span></div>
<div><b>기능 우선</b><span>메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.</span></div>
@ -789,9 +815,13 @@
<div class="track-group">
<div class="tg-head"><h3>코드품질 · 로컬 개발 스택</h3><span class="tg-note">리팩토링 연구 + 1-커맨드 dev 스택 (2026-06-26~27). code-quality-research-2026-06-26.md · local-development.md</span></div>
<div class="scards">
<article class="scard" data-status="doing" data-cat="인프라·스택·RAG" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-doing">DB RECOVERY · PUBLIC LIVE</span><span class="scard-mid"><span class="scard-title">공개 계정·회기 복구와 무손실 전환</span><span class="scard-sum">복구 named volume을 공개 55432에 전환했다. 데이터·auth·watchdog는 정상이며 사용자 재로그인 후 과거 소유 회기 확인만 남았다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv k-good"><b>공개 전환</b><p>2026-08-07 18:26 KST owner 승인으로 <code>vignette_recovered_prod_20260807</code><code>vignette-dev-db:55432</code>에 연결했다. public owner 집계 users 84·sessions 30·turns 705, Google 계정 16·소유 회기 30, orphan 0이다. local/public health는 prod·DB true·engine true·claude_cli, OpenAPI 119, Google OAuth 302, 공개 로그인 화면 렌더와 watchdog check-only를 통과했다.</p></div><div class="kv"><b>보존·rollback</b><p>전환 직전 DB는 <code>vignette-dev-db-pre-recovery-20260807-182642</code>로 중지 보존했고 exact dump SHA는 <code>6b84d5c8…8af1f</code>다. 원본 volume, post-merge dump <code>d24eaa75…2e32</code>, 최종 recovered dump <code>d7bcc396…68ed</code>, 자동 rollback을 실증한 실패 후보 2개도 삭제하지 않았다.</p></div><div class="kv k-warn"><b>사용자 확인</b><p>보안상 기존 <code>auth_session</code>은 복사하지 않아 모두 Google 재로그인이 필요하다. 계정·회기 원장은 복구돼 있다. 실제 사용자가 재로그인한 뒤 과거 소유 회기 목록이 보이는지 확인할 때까지 이 카드는 안정화 중으로 유지한다. 상세: <code>ops/public-db-recovery-rehearsal-2026-08-07.md</code>.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="인프라·스택·RAG" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">DEV STACK</span><span class="scard-mid"><span class="scard-title">로컬 개발 스택 1-커맨드 기동 — <code>scripts/dev-up.ps1</code></span><span class="scard-sum">게이트웨이9099+API8000+웹5173+Docker DB 보장. 3포트 health OK + 실 AI 턴.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>현재</b><p>게이트웨이(9099 claude_cli)+API(8000, DB 미가용 시 in-memory degraded)+웹(5173)을 커맨드라인 기준 정리 후 결정론적 기동(<code>--reload</code> 워처 불안정 회피, uvicorn 있는 python 자동 해석). Docker가 사용 가능하면 <code>vignette-dev-db</code> healthcheck/pg_isready/role safety를 점검하고, compose <code>infra\.env</code> 필수값 누락도 경고한다. <code>-NoGateway</code>/<code>-NoWeb</code>는 해당 컴포넌트 정리도 건너뛰고, API 정리는 지정 <code>-ApiPort</code>만 대상으로 한다. dev-login + seed 페르소나. 로그 <code>.devlogs/</code>(gitignore). <b>검증</b>: 3포트 health OK + 실제 AI 턴 생성·회기리뷰 동작, API-only 재기동 후 8001/8010/5173/9099/20241 보존.</p></div><div class="kv k-warn"><b>비고</b><p>AI 턴은 로컬 claude CLI 사용(사용량 발생). 진입점 http://localhost:5173. <code>dev-down.ps1</code>은 기본적으로 DB 컨테이너를 보존하고, <code>-Db</code> 지정 시 함께 중지한다. 기존 <code>vignette-dev-db</code>는 accepting connections이나 healthcheck가 없고, <code>vignette_app</code>은 NOBYPASSRLS로 존재한다. 이번 패키징 smoke에서 fresh compose DB는 owner/app role 분리 상태로 API healthy까지 통과했고, 기존 dev DB의 운영 role 전환은 별도 owner migration 확인 후 진행한다. <b>주의(무DB 한정)</b>: DB 없이 degraded면 페르소나가 <code>source:seed_fallback·degraded:true</code>라 프론트 <code>isUsablePersona</code>가 막아 "회기 시작" 버튼이 비활성 → UI 세션 시작엔 실제 Postgres(<code>127.0.0.1:55432</code>)가 필요.</p></div></div>
<button class="scard-head" aria-expanded="false"><span class="chip c-done">DEV STACK · DB 보존 패치</span><span class="scard-mid"><span class="scard-title">로컬 개발 스택 1-커맨드 기동 — <code>scripts/dev-up.ps1</code></span><span class="scard-sum">정지 DB는 start 우선, 신규 PGDATA는 고정 named volume, 일반 dev-up의 DB 삭제 경로는 0.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>현재</b><p>게이트웨이(9099 claude_cli)+API(8000)+웹(5173)을 결정론적으로 기동한다. DB는 이름만 같은 새 container로 바꾸지 않는다. 기존 container가 stopped이면 <code>docker start</code>와 readiness를 먼저 수행하고, 그 외 비정상 상태·시작 실패·readiness timeout은 container/volume을 보존한 채 fail closed한다. 신규 DB만 <code>vignette-dev-db-pgdata</code> named volume을 사용하며 일반 경로에는 container rm·volume rm/prune·compose down -v가 없다.</p></div><div class="kv k-good"><b>검증</b><p><code>scripts/test_dev_up_db_safety.py</code> 5 passed, Ruff, Windows PowerShell 5.1 AST parser, diff check 통과. 실행 중인 DB container ID·생성 시각·PGDATA volume은 테스트 전후 동일했다.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="인프라·스택·RAG" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">VOICE 로컬 작동</span><span class="scard-mid"><span class="scard-title">음성 채팅 무음 해결 — provider + 브라우저 재생 경계 보강</span><span class="scard-sum">OPENAI_API_KEY 설정 확인, Web Audio unlock 재생, local live STT/TTS WS smoke 통과.</span></span><span class="caret" aria-hidden="true"></span></button>
@ -823,6 +853,49 @@
</article>
</div>
</div>
<!-- TRACK 4: OUTCOME & ALLIANCE OS -->
<div class="track-group" id="outcome-alliance-os">
<div class="tg-head"><h3>Outcome &amp; Alliance OS · 정식 승격 로드맵</h3><span class="tg-note">제약이 아닌 증거 게이트로 진행 · 사람 개발자 계획 없음 · 2026-08-06 승격</span></div>
<div class="scards">
<article class="scard" data-status="done" data-cat="Outcome OS·측정" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G0 DONE · INTERNAL</span><span class="scard-mid"><span class="scard-title">측정 진실 기반 — Measurement Truth Foundation</span><span class="scard-sum">G5 실제 수행 원장까지 포함한 current producer census 29/29와 provenance 위반 0을 고정했다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>구현</b><p><code>app.measurement_event</code>·<code>app.measurement_instrument</code>·<code>audit.model_run</code>과 6종 provenance, Python→JSON Schema→TypeScript 계약, 기존 rapport/alliance/fast/deep/Phase 3 adapter, 혼합층 집계 차단, 8개 deterministic benchmark 장면을 구축했다. <b>AOS-001~004 완료</b>.</p></div><div class="kv k-good"><b>종료 증거</b><p>post-merge dump disposable clone에 migrations 14/15/16을 각각 두 번 원자 재적용했다. current source census는 producer 29/29, unknown/missing table·null instrument/source/perspective·orphan instrument/model-run/evidence·호환성 위반 0이다. 기존 계약/schema·live append-only/RLS 증거도 유지한다. 상세: <code>ops/evidence/g0-provenance-census-scratch-post-g6-g8-20260807.json</code>, <code>ops/evidence/measurement-migration-rehearsal-2026-08-07.json</code>.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="Outcome OS·동맹" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G1 DONE · EXTERNAL ICC 분리</span><span class="scard-mid"><span class="scard-title">Alliance Core — goal/task/bond 다관점 측정</span><span class="scard-sum">승격 prompt 1.2는 24/24 ready·방향 9/9·오류 0으로 재검증했고 human-AI ICC는 외부 파일럿 품질 목표로 분리한다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>구현</b><p>회기 pulse, legacy alliance 격리, 자기평가 선잠금, 독립 모델 실행·재시도, 학습자 관점차 리뷰, 교수자 append-only 재평가를 구축했다. 실제 Session은 첫 발화 전 pre를 fail-closed로 잠그고 첫 왕복 뒤 흐름을 막지 않는 mid 30초 점검을 제공한다. <b>AOS-005~010 완료</b>.</p></div><div class="kv k-good"><b>종료 증거</b><p>focused backend 43 passed, live PostgreSQL reveal/RLS/audit/supersession smoke, desktop/mobile Alliance Pulse 6/6와 기존 회기 리뷰 12/12 통과. 동일 payload stable ID, 변경 payload 409, 타 학습자·교차 cohort 404와 pre/mid desktop·mobile 2/2·고정 캡처 4장을 추가 검증했다. 최신 source API/dev DB는 한 회기의 <code>pre(degraded/insufficient_transcript) → mid(ready) → post(ready)</code>를 실제 turn UUID·ended_at으로 닫고, awaiting 응답의 external-event read skew와 degraded terminal DB 제약을 교정했다. prompt 1.2.0 합성 gold 방향 정확도 9/9, 최종 실패 0, 근거 recall 88.9%. 상세: <code>ops/evidence/alliance-pulse-pre-mid-post-live-2026-08-07.json</code>, <code>ops/outcome-os-g1-g4-g5-g7-self-directed-integration-evidence-2026-08-07.md</code>.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="Outcome OS·종단" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G2 DONE · INTERNAL</span><span class="scard-mid"><span class="scard-title">Longitudinal Outcome Trajectory — 종단 성과 궤적</span><span class="scard-sum">5회기 예상 궤적·악화·관계 사건을 세 개 독립 축과 장면 근거로 조기에 추적한다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>구현</b><p>교육용 합성 5회기 arc, 세 축 outcome 원장·append-only revision, 누락·오류 무점수, safety 분리, early warning·다음 질문, 역할별 관계 기억, 학습자 체크인과 desktop/mobile 타임라인을 구축했다.</p></div><div class="kv k-good"><b>종료 증거</b><p>4-case×5-session benchmark status 정확도 1.0·false alert/critical miss 0. 기존 실제 DB/API on-track case의 S1~S5·관측 15개·멱등/409·RLS·role-safe 기억에 더해, production measurement producer→store→evaluator를 통과하는 실제 PostgreSQL 두 case·10회기·30개 측정으로 악화 <code>on_track→off_track→deteriorating</code>과 단발성 noise <code>on_track→watch→on_track</code>·alert 승격 0건을 검증했다. case별 revision 5개와 learner/teacher projection 일치, 합성·비임상 표시를 보존했다. G2 focused 40 passed, 전체 API 855 passed, G2 UI 12/12, G1+기존 리뷰 15/15. 상세: <code>ops/outcome-trajectory-live-integration-evidence-2026-08-06.md</code>, <code>ops/evidence/outcome-trajectory-alerts-live-2026-08-07.json</code>.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="Outcome OS·균열" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G3 DONE · INTERNAL</span><span class="scard-mid"><span class="scard-title">Rupture &amp; Repair Lab — 관계 균열과 복구</span><span class="scard-sum">균열을 자연스럽게 만들고 탐지·복구·재연습의 전 과정을 장면 단위로 검증한다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>구현</b><p>9종 rupture/repair 상태머신·append-only 원장, Scenario Director, 텍스트·SSE·음성 공통 finalizer 감지 경계, 회기 후 근거 장면·복구 분기, fast/deep reconciliation, 교수자 supersession을 구축했다.</p></div><div class="kv k-good"><b>종료 증거</b><p>11-case benchmark macro-F1 1.0·복구 상태 accuracy 1.0, critical miss·judge gaming·암기문구 false resolution 0. Scenario/G3 107 passed, 통합 계약 251 passed, 리뷰 desktop/mobile 50/50. 기존 수동 write API 계약과 별도로 실제 텍스트 <code>submit_turn</code>·공용 finalizer callback만 사용한 PostgreSQL smoke가 missed·partial·resolved 3 episode, 10개 append-only observation, 3개 reconciliation, learner/teacher projection, 세션 밖 evidence 참조 0건을 통과했다. SSE·음성 개별 transport 실 DB smoke는 이 증거 범위가 아니다. 상세: <code>ops/rupture-repair-live-integration-evidence-2026-08-06.md</code>, <code>ops/evidence/rupture-runtime-auto-live-2026-08-07.json</code>.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="Outcome OS·수련" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G4 DONE · INTERNAL</span><span class="scard-mid"><span class="scard-title">Deliberate Practice Engine — 의도적 수련 엔진</span><span class="scard-sum">실제 API/DB/엔진과 route-mock 0 브라우저에서 처방→후속 회기→observer 폐루프를 닫았다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>구현</b><p>원자적 practice prescription, 5개 연습 모드, competency graph·attempt evidence, 약점/망각 우선 선택, append-only PostgreSQL/API·RLS·내부 토큰, 학습자/교수자 리뷰 UI를 연결했다. ready 회기말 평가 저장 뒤 production <code>session_learning_producer</code>가 durable turn intent deviation을 실제 처방으로 변환한다. 학습자 CTA는 처방·원본 회기·성공 기준을 학습 홈→시작 전 브리핑→실제 새 세션 URL까지 보존한다.</p></div><div class="kv k-good"><b>종료 증거</b><p>실제 API/DB/엔진 smoke는 prescriptions 2·episodes 6·attempts 6·append-only correction 1·ready observer model-run 2를 통과했다. post-merge disposable clone의 실제 브라우저는 route mock 0으로 desktop 2/2·mobile 2/2, returned 카드 우선·G4 POST·read-model reload·before/after·멱등 retry를 확인했고 최종 episode/attempt/ready observer 각 1, 중복·UUID 노출·마이크 호출·overflow 0이다. 전체 API 현재 898 passed. 상세: <code>ops/evidence/scratch-browser-returned-practice-closed-loop-evidence-20260807.json</code>, <code>ops/outcome-os-g4-g5-production-caller-evidence-2026-08-07.md</code>.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="Outcome OS·보정" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G5 DONE · INTERNAL</span><span class="scard-mid"><span class="scard-title">Calibration Mirror &amp; Transfer — 자기보정과 전이</span><span class="scard-sum">학생 actual execution을 실제 API/DB/엔진과 브라우저에서 독립 observer·provenance까지 닫았다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>구현</b><p>prediction revision/lock/reveal, 독립 수행 관측, calibration error·95% interval·메타인지 처방, 미지 transfer suite·암기 차단·합성 drift 원장/API/RLS와 역할 안전 UI를 연결했다. production lock callback은 ready 평가와 같은 competency의 durable turn evidence가 있을 때만 failed 독립 관찰을 파생하며 pass·mastery·transfer는 자동 추론하지 않는다. 실패한 unseen trial과 자기보정 처방을 학습 홈과 실제 새 세션까지 보존한다.</p></div><div class="kv k-good"><b>종료 증거</b><p>실제 API/DB/엔진 smoke는 execution·model-inferred·independent observer·instrument v1·durable evidence·distinct model-run을 각각 1로 고정하고 멱등 및 오류 출처·미종료·타학습자·교차 cohort 차단을 통과했다. post-merge disposable clone 브라우저는 route mock 0으로 desktop/mobile 4/4, actual POST→read reload→before/after와 1→1 멱등 재확인을 통과했고 UUID 노출·마이크 호출·중복 원장 0이다. 4-case benchmark와 lock/reveal/RLS 계약도 유지한다. 상세: <code>ops/evidence/scratch-browser-returned-practice-closed-loop-evidence-20260807.json</code>, <code>ops/calibration-transfer-live-integration-evidence-2026-08-06.md</code>.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="Outcome OS·슈퍼비전" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G6 DONE · INTERNAL</span><span class="scard-mid"><span class="scard-title">Supervision &amp; Research OS — 교수자·연구 운영체계</span><span class="scard-sum">current safety event를 raw detail 없이 최우선 queue와 직접 원장 pointer로 실증했다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>구현</b><p>append-only attention queue·원장 pointer, metadata-only 교수자/AI 불일치 dataset·audit, cohort gap, version/subgroup drift, 4-domain Phase 3 manifest와 역할 안전 교수자·연구 UX를 연결했다. scheduled producer가 G0~G5 실제 원장에서 attention/gap을 파생하고 repo-approved synthetic version comparison을 별도 research 트랜잭션으로 실행한다.</p></div><div class="kv k-good"><b>종료 증거</b><p>기존 6-signal queue·3-click·네 도메인 manifest·실제 API/DB/RLS/audit·version/subgroup 증거에 더해 post-merge disposable clone의 current source에서 safety event와 deterioration 경쟁 신호를 실제 derive했다. 결과는 <code>safety_boundary(1) &gt; deterioration(2)</code>, direct pointer 각 1, source detail canary 1·G6 projection canary 0, raw transcript/임상 주장 0이고 replay가 멱등이다. 상세: <code>ops/evidence/g6-safety-priority-runtime-scratch-20260807.json</code>, <code>ops/outcome-os-g6-version-comparison-producer-evidence-2026-08-07.md</code>.</p></div></div>
</article>
<article class="scard" data-status="doing" data-cat="Outcome OS·음성" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-doing">G7 GATE · INTERNAL DONE · EXTERNAL PROOF</span><span class="scard-mid"><span class="scard-title">Multimodal Alliance — 음성·비언어 동맹 신호</span><span class="scard-sum">내부 안전·복구·용량 계약은 닫았고 실제 provider·동의 마이크·사람 평가 증거를 기다린다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv k-good"><b>내부 구현 DONE</b><p>consent→단일 clock→독립 text/voice/fusion→철회·tombstone, streaming interim/final·word timestamp·provider event, HMAC word pseudonym, 열린 stream의 1초 동의 재검사·abort, 텍스트 보존·음성 재연결 UX를 연결했다. 격리 synthetic PCM soak는 59/59 연결 종료·성공 발화 55·철회 차단 2·미동의 차단 1·overflow 거부/복구 1/1·10MiB 선초과 거부를 통과했고, G7 focused 119 passed·Ruff·compile을 통과했다. 공개 WSS preflight는 TLS 1.3/Cloudflare 연결과 비인증 1008 차단, 마이크 열거·캡처 0을 확인했다. 증거: <code>ops/evidence/g7-public-wss-preflight-current-20260807.json</code>.</p></div><div class="kv k-warn"><b>외부 종료 GATE</b><p>실제 Deepgram 운영 key·quota와 live interim/final, 기대값과 일치하는 authenticated public WSS ready, 실행 직전 명시 동의 물리 마이크 50분 양방향 soak, 같은 public host·겹치는 시간창의 worker/Uvicorn queue와 exact image·cgroup/proc/Docker/TCP high-water, 30명/50회기/150축 독립 라벨 held-out voice-gain이 필요하다. 네 artifact가 <code>scripts/check-g7-external-proof.py</code> exit 0을 만들기 전에는 메인 상태를 DONE으로 바꾸지 않는다. 현재 canonical checker exit 1은 이 외부 증거 부재를 정직하게 차단한 결과다.</p></div></div>
</article>
<article class="scard" data-status="done" data-cat="Outcome OS·에이전틱" data-owner="0">
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G8 DONE</span><span class="scard-mid"><span class="scard-title">Autonomous Content &amp; Continuous Improvement</span><span class="scard-sum">receipt-bound rollback executor가 격리 NAS에서 실제 image rollback과 restore를 두 번의 executed receipt로 실행했다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv"><b>agentic worker + 운영 환류 + human gate</b><p>승인 source의 실제 hash·PII를 engine 호출 전에 검사하고 structured generator 1개, 결과를 공유하지 않는 red-team 2개, variant generator와 variant별 독립 judge 3개 이상을 실행한다. 정답 누수·PII·unknown source claim·open finding·안전/보상 해킹·모델/structured 실패는 store 호출 전에 차단한다. repo-approved source는 기본 비활성 scheduler가 durable lease/retry job으로 관리한다. 실제 <code>claude_cli/claude-opus-4-8</code> 7 calls와 dev PostgreSQL reviewer 2·variant 3·pass rate 1.0을 거쳐 synthetic payload를 <code>pending_human_approval</code>로 저장했다. G6 canonical drift trigger는 metadata-only incident→DAG→job을 원자 enqueue하고, 실제 pending 후보의 관리자 검수는 catalog 0→1·approval 1과 역할 403·멱등/409·민감정보 비노출을 통과했다. 별도 누수 후보는 422·저장 0이다. 상세: <code>ops/outcome-os-g8-agentic-worker-evidence-2026-08-07.md</code>.</p></div><div class="kv k-good"><b>current NAS runtime</b><p>release-only SHA <code>6030a677…c611</code>를 전용 NAS Compose 프로젝트에 승격했다. API/Web 이미지 <code>52e0…8b2d</code>/<code>6fdb…f215</code>, health 3/3·db/engine true, OpenAPI 126·auth 401·G0~G8, browser E2E 108/108과 실제 SSE→DB-backed review를 확인했다. named DB volume과 predeploy dump를 보존했다.</p></div><div class="kv k-good"><b>실제 rollback receipt DONE</b><p>runtime+release_gate 전용 executor는 승인·idempotency·artifact·Compose/env/resolved-policy SHA와 exact API/Web image를 일회성 manifest에 결속하고 HMAC journal·crash recovery·previous-image 복구를 고정한다. 2026-08-07 격리 NAS에서 별도 loopback control-plane API(<code>127.0.0.1:8018</code>)와 별도 executor(<code>127.0.0.1:18149</code>)로 <b>실제 image rollback 2회</b>를 실행했다. <code>rollback-old</code>는 receipt <code>nas-g8-723eeef2…</code>로 previous 이미지 <code>79ec…4450</code>/<code>c530…2f28</code>를, <code>restore-current</code>는 receipt <code>nas-g8-2738846c…</code>로 current 이미지 <code>52e0…8b2d</code>/<code>6fdb…f215</code>를 활성화했다. release gate·approval 각각 2회 멱등, lifecycle <code>rollback/executed</code> 2건, 승인 <code>authorize_rollback</code> 2건, silent auto-promotion 0, HMAC journal 6-record 체인 검증, health 3/3·OpenAPI 126·auth 401·Web 200을 확인했다. helper는 image 상속 compose label을 baseline으로 두고 project/service를 격리 override하는 계약으로 검증했다(<code>launch-nas-preview-g8-helpers.py</code>, 37/37). 상세: <a href="./ops/nas-preview-g8-rollback-proof-runbook.md">런북</a> · <a href="./ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json">기계 판독 증거</a>.</p></div></div>
</article>
</div>
</div>
</section>
<!-- ░░ DEEP / FOLDED REFERENCE ░░ -->
@ -835,7 +908,7 @@
</div>
<details class="fold" id="fold-roadmap">
<summary><span class="fcaret" aria-hidden="true"></span>전체 개발 로드맵 (5단계)<span class="fmeta">MASTERPLAN + REVISIONS</span></summary>
<summary><span class="fcaret" aria-hidden="true"></span>전체 개발 로드맵 (기존 5단계 + Outcome OS)<span class="fmeta">MASTERPLAN + OUTCOME &amp; ALLIANCE OS</span></summary>
<div class="fold-inner">
<div class="roadmap">
<article class="phase-card current"><div class="phase-top"><span class="phase-id">Phase 0</span><span class="tag doing">closing</span></div><h3>기반 정렬 / 운영 안전장치</h3><p>인프라, 인증 경계, fail-closed, 공개 배포, 회귀 테스트 안정화.</p><ul class="phase-list"><li><b>상태:</b> 대부분 완료, 공개 <code>/turn</code> proof만 남음</li><li><b>검증:</b> build + backend 178 기준선 + Playwright 113 기준선, Node/backend focused 120</li><li><b>운영:</b> prod API 8001, engine 9099, tunnel 1개</li></ul></article>
@ -843,6 +916,7 @@
<article class="phase-card"><div class="phase-top"><span class="phase-id">Phase 2a</span><span class="tag info">planned</span></div><h3>3역할 / OAuth / 페르소나</h3><p>학습자, 교수자, 관리자 권한 분리와 페르소나 확장.</p><ul class="phase-list"><li><b>DoD:</b> 타인 session 직접 접근 403</li><li><b>범위:</b> OAuth BFF, RBAC, 교수 검수 루프</li><li><b>주의:</b> visible_to와 인간 권한은 별도 레이어</li></ul></article>
<article class="phase-card"><div class="phase-top"><span class="phase-id">Phase 2b</span><span class="tag info">planned</span></div><h3>음성 캐스케이드</h3><p>STT → 엔진 → TTS 왕복, WSS/터널 안정성, barge-in 로깅.</p><ul class="phase-list"><li><b>DoD:</b> 50분 WSS 끊김 실측</li><li><b>범위:</b> Deepgram STT, OpenAI TTS, voice preset</li><li><b>리스크:</b> 실시간 레이턴시는 실측 전 완료 표기 금지</li></ul></article>
<article class="phase-card"><div class="phase-top"><span class="phase-id">Phase 3</span><span class="tag info">planned</span></div><h3>교육용 파일럿 / 효과성</h3><p>수련생 파일럿, 사전사후 효과 측정, 재귀학습 데이터셋 산출.</p><ul class="phase-list"><li><b>DoD:</b> 20명 완주 + KPI 충족</li><li><b>측정:</b> SUS, 자기효능감, κ/ICC, 환각률</li><li><b>정정:</b> IRB 게이트가 아니라 데이터 활용동의/개인정보 게이트</li></ul></article>
<article class="phase-card next"><div class="phase-top"><span class="phase-id">Outcome OS</span><span class="tag doing">G7 external proof</span></div><h3>성과·동맹·수련 폐루프</h3><p>측정 → 이상 탐지 → 원인 가설 → 재연습 → 전이 검증 → 숙련도 갱신.</p><ul class="phase-list"><li><b>상태:</b> G0~G6 internal DONE · G8 실제 NAS rollback receipt DONE · G7 외부 voice/resource/human 대기</li><li><b>완료 DAG:</b> AOS-001~012</li><li><b>운영:</b> current source NAS SHA <code>6030a677…c611</code> 승격 완료 · G8 loopback control-plane rollback/restore receipt 2건 · G7 canonical four-artifact checker 준비</li></ul></article>
</div>
<div class="source-note">정정 기준: <code>MASTERPLAN</code> 원본의 IRB 신청/승인 게이트는 <code>MASTERPLAN_REVISIONS</code> 기준으로 제거한다. Phase 2는 2a(3역할/OAuth/페르소나)와 2b(음성 캐스케이드)로 분리하고, Phase 1 DoD에는 얇은 음성 왕복 1턴 PoC를 포함한다.</div>
</div>
@ -929,7 +1003,7 @@
<div class="task-row"><div><span class="task-status s-done">DONE</span></div><div><b>OpenAI TTS voice preset 추상화</b><p>P1/P2/P3 persona voice preset, invalid preset fallback, speed clamp, instructions payload 계약을 회귀화했고, <code>app.persona_voice_map</code>을 live <code>/voice/ws</code> TTS 선택에 연결했다. 명시 preset은 DB map보다 우선하고, OpenAI가 아닌 provider row는 기존 fallback으로 안전하게 흡수한다.</p></div><div><b>산출물</b><p><code>resolve_voice</code>, <code>resolve_voice_from_map</code>, <code>build_tts_payload</code>, <code>get_session_voice_map</code>, seed voice map row, dev runtime schema guard</p></div><div><b>검증</b><p><code>pytest app/test_runtime_policy.py app/test_persona_review.py app/test_voice_service.py app/test_voice_ws.py -q</code> 75 passed; full API 178 passed + gateway 11 passed.</p></div></div>
<div class="task-row"><div><span class="task-status s-done">POC DONE</span></div><div><b>P1 서연 무참조 synthetic voice 샘플</b><p>Higgs v3 로컬 런타임에서 실존 reference voice 없이 synthetic seed를 먼저 만들고, 그 seed만 재참조해 우울·피로·불안·라포·회복감 5개 변주를 생성했다. 개발용 <code>VIGNETTE_VOICE_POC_SAMPLE_TTS</code> 플래그로 <code>/voice/ws</code> P1 sample TTS provider에도 연결했다.</p></div><div><b>산출물</b><p><code>docs/archive/voice-art/bimec-persona-voice-poc-2026-06-27.md</code>, <code>docs/voice-art/p1-seoyeon-higgs-v3-20260627/manifest.json</code>, <code>apps/api/app/services/voice.py</code></p></div><div><b>검증</b><p>mp3/wav 6개(seed+5) 생성, 24kHz, 7.72~11.68초. live <code>/voice/ws</code> text_turn smoke: provider <code>p1-sample-poc</code>, binary 20 chunks/78,573 bytes. 샘플 provider는 TTS override만 담당하고 마이크/STT는 OpenAI 키가 필요하다. 프로덕션 탑재는 모델 라이선스·권리정책 결정 전 금지.</p></div></div>
<div class="task-row"><div><span class="task-status s-done">LOCAL DONE</span></div><div><b>barge-in / paralinguistic logging</b><p>음성 learner turn에 audio_ref, silence_ms, speech_rate, barge_in을 nullable 메타로 저장하고, 회기 리뷰에서 침묵·발화 속도·끼어듦·음성 입력 비언어 칩으로 표시한다. 2차로 <code>provider_events</code> JSONB 보존 슬롯을 추가해 control/STT provider 이벤트를 allowlist·size limit 후 저장하고, 3차로 내부 taxonomy <code>event_type</code>/<code>category</code>를 붙인다. 4차로 인증된 회기 리뷰에는 한숨·울음·웃음·호흡·운율·배경소음 같은 정규화 이벤트만 label/detail 칩으로 제한 노출한다. 실제 Session 마이크 UI는 browser voice activity/trailing silence 메타를 <code>audio_end</code>에 싣고, readiness는 음성 메타 5개 컬럼 전체를 확인한다. raw transcript/text/provider/source/raw type은 응답에서 제외하고, 공개 공유 카드는 축어록과 provider raw를 계속 싣지 않는다.</p></div><div><b>산출물</b><p><code>app.turns.provider_events</code>, <code>TurnRecord.provider_events</code>, voice route 이벤트 sanitizing/taxonomy, <code>ReviewNonverbalEvent</code>, <code>SessionReview</code> 칩 UI, browser voice metadata capture, voice metadata readiness guard</p></div><div><b>검증</b><p><code>python -X utf8 -m pytest -p no:cacheprovider app/test_runtime_policy.py app/test_session_turn_persistence.py app/test_voice_ws.py app/test_voice_service.py -q</code> 77 passed; provider_events DB insert placeholder/args, WS raw key drop, STT+control event merge, internal taxonomy, client turn 미혼입, review 파생 칩 raw provider 미노출, 침묵 칩 중복 방지, 5-column readiness 검증. <code>PLAYWRIGHT_PORT=5197 npx playwright test e2e/voice-success.spec.ts --project=chromium-single-run --workers=1</code> 2 passed, <code>PLAYWRIGHT_PORT=5199 npx playwright test e2e/session-persistence.spec.ts --project=chromium-single-run --workers=1</code> 5 passed, <code>npm run typecheck</code>.</p></div></div>
<div class="task-row"><div><span class="task-status s-plan">GATE</span></div><div><b>공개·실기기 음성 장시간 실측</b><p>남은 범위는 실제 Deepgram interim/final WSS, 물리 마이크, 공개 WSS, 50분 양방향 장시간 실측, provider 기반 한숨·울음 감지다. 로컬 OpenAI STT/TTS smoke와 synthetic mic E2E는 이 실측을 대체하지 않는다.</p></div><div><b>산출물</b><p>public WSS smoke log, physical mic capture log, 50분 soak evidence, provider paralinguistic event sample</p></div><div><b>검증</b><p>실제 공개/실기기 환경에서만 완료 가능. 현재는 B2 음성 캐스케이드 live gate로 추적한다.</p></div></div>
<div class="task-row"><div><span class="task-status s-plan">GATE</span></div><div><b>공개·실기기 음성 장시간 실측</b><p>Deepgram adapter, HMAC word pseudonym, 1초 동의 재검사, 공통 consent transaction lock, bounded queue/10MiB cap, recovery UX와 provider/model ready 계약은 내부 완료다. 남은 범위는 실제 Deepgram key·quota live, 기대 provider/model authenticated public WSS, 명시 동의 물리 마이크, 50분 양방향 soak, 독립 라벨 voice-gain benchmark, 실제 운영 topology resource high-water와 provider 기반 한숨·울음 표본이다. mic-free preflight와 synthetic E2E/label은 이를 대체하지 않는다.</p></div><div><b>산출물</b><p>expected provider/model public WSS ready log, Deepgram interim/final 표본, explicit-consent physical mic capture log, 50분 soak evidence, independently labeled voice-gain report, worker/proxy resource high-water, provider paralinguistic event sample</p></div><div><b>검증</b><p>실제 공개/실기기/외부 provider 환경에서만 완료 가능. 현재는 B2 음성 캐스케이드 live gate로 추적한다.</p></div></div>
<div class="task-row"><div><span class="task-status s-done">DECIDED</span></div><div><b>s2s 2차 PoC 판단</b><p>소유자 결정(2026-06-30): s2s 2차 PoC 유지. 캐스케이드 1차를 운영 기준으로 두고 <code>voice-s2s-poc.md</code> 비교 PoC를 계속 연다. 최종 채택/폐기는 비교 리포트 이후 재판단한다. 채택 여부 자체는 확정됐고, 비교 PoC 구현·실측이 후속 build로 남는다.</p></div><div><b>산출물</b><p><code>docs/decisions/voice-s2s-poc.md</code></p></div><div><b>검증</b><p>transcript, safety, audit, latency, failure, privacy 기준 명시. 실제 비교 실측은 후속.</p></div></div>
</div>
</div>
@ -970,13 +1044,19 @@
<tbody>
<tr><td>Web typecheck</td><td><code>npm run typecheck</code></td><td>Passed</td></tr>
<tr><td>Design SSOT / auth visual</td><td><code>npm run check:design-ssot</code> / <code>npx playwright test e2e/auth-visual.spec.ts --project=chromium-single-run --reporter=line</code> / <code>npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --reporter=line</code></td><td>SSOT checker passed; login/onboarding light-dark desktop-mobile 1 passed; 14 core screens × 7 widths visual gate 14 passed.</td></tr>
<tr><td>Full Playwright E2E baseline</td><td><code>npm run e2e:parallel</code> / <code>npm run e2e:single-run</code> / <code>npm run e2e:list</code></td><td>현재 수집 기준 215 tests / 20 files. fixture desktop/mobile 166/166 passed(2.5분), DB/engine/provider 직렬 49/49 passed(23.2분), 합계 215/215 passed.</td></tr>
<tr><td>Full Playwright E2E baseline</td><td><code>npm run e2e:parallel</code> / <code>npm run e2e:single-run</code> / <code>npm run e2e:list</code></td><td>2026-08-07 현재 수집은 <b>610 tests / 44 files</b>다. 현 작업트리의 610개 전체 GREEN은 아직 검증 전이며, 2026-07-15의 fixture desktop/mobile 166/166 + DB/engine/provider 직렬 49/49 = 215/215는 과거 기준선으로만 보존한다.</td></tr>
<tr><td>Refactor governance P1~P8</td><td><code>ruff check app</code> / <code>pytest -q app</code> / <code>pytest -q engine_gateway</code> / <code>npm run typecheck</code> / <code>npm run check:api-types</code> / <code>npm run check:design-ssot</code> / <code>npm run check:dead-code</code> / <code>npm run check:duplication</code> / <code>npm run build</code> / <code>npm audit --audit-level=high</code> / full Playwright</td><td>Backend 400 passed, gateway 29 passed, web gates/build/audit passed, vulnerabilities 0, production duplication 1 clone/15 lines/0.03%, Playwright 215/215 passed. 상세 근거는 <code>ops/refactor-governance-2026-07-15.md</code>.</td></tr>
<tr><td>API typegen SSOT</td><td><code>npm run check:api-types</code></td><td>Passed; FastAPI OpenAPI → <code>src/lib/api.gen.ts</code> stale check</td></tr>
<tr><td>Outcome &amp; Alliance OS G0</td><td><code>py -3.11 -X utf8 -m pytest -p no:cacheprovider apps/api/app/test_measurement_contract.py apps/api/app/test_runtime_schema_ssot.py -q</code> / <code>scripts/check-measurement-ledger.sql</code> / measurement·API contract checks / web typecheck / DB-backed <code>session-persistence</code> focused E2E 3종</td><td>G0 contract/schema 11 passed, 기존 backend 100 passed, auth 39 passed. Python→JSON Schema→TypeScript→PostgreSQL enum·필수필드 계약이 일치하고 8개 deterministic benchmark가 검증됐다. Live PostgreSQL에서 learner/client/evaluator 가시 행 1/1/2, 교차 누수 0, append-only guard 2를 확인했다. 학습자 턴→교수자 대시보드, 워크시트 검수, 종료 deep 평가→durable 리뷰 E2E는 각각 1 passed. G0/AOS-001~004 완료.</td></tr>
<tr><td>Outcome &amp; Alliance OS G1</td><td><code>pytest test_alliance_measurement.py test_alliance_calibration.py test_measurement_routes.py test_runtime_schema_ssot.py test_measurement_contract.py</code> / <code>scripts/smoke-alliance-pulse-api.py</code> / <code>alliance-pulse.spec.ts</code> / <code>session-review.spec.ts</code> / prompt 1.2 calibration compare</td><td>backend 40 passed, live DB에서 202→awaiting_agents→ready·공개 전 외부 관점 비노출·3관점×3축·교수자 재평정 supersession·attempt별 model-run provenance를 확인했다. desktop/mobile Alliance Pulse 6/6와 기존 회기 리뷰 12/12 통과. 합성 gold 방향 9/9, 최종 실패 0, 근거 recall 88.9%. G1/AOS-005~010 완료.</td></tr>
<tr><td>Outcome &amp; Alliance OS G2</td><td><code>pytest test_outcome_trajectory.py test_outcome_trajectory_schema.py test_outcome_trajectory_store.py</code> / <code>scripts/smoke-outcome-trajectory-api.py</code> / <code>scripts/smoke-outcome-trajectory-alerts.py</code> / <code>outcome-trajectory.spec.ts</code></td><td>focused 40 passed. 기존 실제 DB/API on-track 5회기·멱등/409·RLS에 더해 합성 교육 fixture 두 개가 production measurement producer→store→evaluator를 통과했다. 실제 10회기·30개 측정·case별 5 revision에서 악화는 S3 off_track·S4~S5 deteriorating, 단발성 noise는 S3 watch 뒤 회복해 alert 승격 0건이었다. 최신 observation 30개가 원본 측정 30개를 모두 참조하고 learner/teacher projection이 일치한다. 결과 JSON은 source score를 담지 않으며 임상 주장을 금지한다.</td></tr>
<tr><td>Outcome &amp; Alliance OS G3</td><td><code>pytest test_rupture_scenario_director.py test_rupture_runtime.py test_rupture_repair.py test_rupture_repair_store.py</code> / <code>scripts/smoke-rupture-repair-api.py</code> / <code>scripts/smoke-rupture-runtime-auto.py</code> / <code>rupture-repair.spec.ts</code> / G1~G3 review regression</td><td>benchmark macro-F1 1.0·상태 accuracy 1.0·critical miss/judge gaming/암기 false resolution 0. 최신 G3 focused 70 passed; 누적 Scenario/G3 107 passed, G0~G8 계약 251 passed, desktop/mobile review 50/50. 수동 write API는 durable UUID·인증·멱등·409·RLS·교수자 correction을 검증했고, 별도 자동 runtime smoke는 실제 텍스트 learner turn/finalizer callback으로 3 episode·10 observations·3 reconciliations, missed/partial/resolved, learner/teacher projection, evidence 참조 무결성을 PostgreSQL에서 검증했다.</td></tr>
<tr><td>Outcome &amp; Alliance OS G4/G5 caller</td><td><code>pytest test_session_learning_producer.py test_deliberate_practice.py test_deliberate_practice_store.py test_calibration_transfer.py test_calibration_transfer_store.py</code> / <code>scripts/smoke-session-learning-producer.py</code></td><td>focused 100 passed, 전체 API 855 passed. 실제 종료 회기·durable turn 2개·ready 평가에서 production caller가 G4 처방 원장 5종을 각 1개 생성하고 deterministic replay한다. G5는 prediction lock 전 observation 0, lock callback 뒤 failed 독립 관찰과 evaluator model-run 각 1개이며 replay 중복 0이다. learner/teacher projection이 일치하고 mastery/pass/assessment/transfer 자동 승격은 전부 0건이다. 합성 교육 fixture이며 임상·실제 숙달 주장이 아니다.</td></tr>
<tr><td>학생 자기주도 전체 루프 UI</td><td><code>npx playwright test e2e/self-directed-learning-loop.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --reporter=dot</code> / <code>npx playwright test e2e/alliance-pulse.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=2</code> / <code>npm run typecheck</code> / 고정 캡처 직접 QA</td><td>실제 <code>src</code> 홈 추천→목표 선택→텍스트/SSE 회기→종료·리뷰→G4 처방 키보드 CTA→새 회기 재연습 시작이 desktop/mobile 2/2, typecheck를 통과했다. 페이지 overflow 0, 홈 CTA 44px·4.5:1 이상 대비, typed launch intent와 replay 모드 보존, 내부 criterion/counterevidence/UUID 비노출을 확인했다. 390×844·320×568 활성 회기는 아바타/문구 겹침 0과 축어록/입력창 내부 포함을 통과했다. 320px 리뷰 1~5 척도는 다섯 선택지 44px 이상·내부/페이지 overflow 0이고 전체 desktop/mobile 8/8이다. 모든 미소유 API는 fixture 404이며 실제 로그인/API/DB 증거가 아니다.</td></tr>
<tr><td>Contract SSOT aggregate DTO</td><td><code>py -3.11 -X utf8 -m pytest -p no:cacheprovider app/test_evaluation_persistence.py app/test_evaluator_model_routing.py app/test_teacher_dashboard.py app/test_rbac_idor.py app/test_session_turn_persistence.py -q</code> / <code>npm run check:api-types</code> / <code>npm run typecheck</code> / <code>npm run build</code></td><td>50 backend passed; learner sessions, session review/worksheet, teacher dashboard, session start/detail DTOs use generated <code>ApiSchema</code> aliases with UI fallback. Stage responses are OpenAPI enum unions, including review phase key/label, reached phase, evaluation summary/trigger responses, and teacher session/growth stage. <code>.github/workflows/api-contract.yml</code> runs <code>npm run check:api-types</code> on API/Web contract changes.</td></tr>
<tr><td>SEO/GEO share cards</td><td><code>pytest app/test_session_share.py app/test_session_turn_persistence.py -q</code> / <code>npm run generate:api-types</code> / <code>npm run typecheck</code></td><td>21 passed; session share creates hashed-token public unfurl payload without raw transcript, revoked token returns 404, OpenAPI generated share DTOs, review screen share button typechecks. Static <code>robots.txt</code>/<code>sitemap.xml</code>/<code>llms.txt</code> added.</td></tr>
<tr><td>Backend pytest baseline</td><td><code>pytest -q app</code></td><td>2026-07-15 전체 실행 400 passed. 외부 Starlette 의존성의 <code>python_multipart</code> PendingDeprecationWarning 1건만 존재한다.</td></tr>
<tr><td>X2 evaluator routing/cache/cost trend</td><td><code>python -B -m pytest -p no:cacheprovider app/test_usage_report.py app/test_evaluator_model_routing.py app/test_runtime_policy.py app/test_admin_ops.py -q</code> / <code>scripts/report-ai-usage.py</code> sample CLI / prior web gates</td><td>42 backend passed + CLI sample OK; fast/deep evaluator model override, semantic cache hit/miss, admin usage budget/fail-closed, cache hit-rate observability, daily cost trend, and provider/model cost report schema covered. Prior API typecheck/build/admin E2E evidence remains valid because the API response shape was not changed.</td></tr>
<tr><td>Backend pytest baseline</td><td><code>pytest -q app</code></td><td>2026-07-31 전체 실행 439 passed. 외부 Starlette 의존성의 <code>python_multipart</code> PendingDeprecationWarning 1건만 존재한다.</td></tr>
<tr><td>X2 evaluator routing/cache/cost trend</td><td><code>python -X utf8 -m pytest -p no:cacheprovider app/test_llm_pricing.py app/test_admin_ops.py app/test_usage_report.py engine_gateway/test_provider_registry.py engine_gateway/test_gateway_model.py -q</code> / API type generation/check / web typecheck/build / admin focused E2E·layout visual gate / authenticated public API smoke</td><td>최신 backend 439 passed, gateway 45 passed, desktop/mobile E2E 2 passed, 7폭 focused visual gate 1 passed. Claude CLI SDK 비용 추정값과 Agy/Gemini·Codex·Claude API 공식 참조단가를 분리하고, 기존 0달러 행의 조회 시 보정·단가 미등록 모델의 <code>미산정</code> 표시·예산 합산·리포트 경고까지 고정했다. Claude 토큰은 전체 agent tree와 캐시 입력을 포함한다. 과거 0/0 Claude 442건은 로컬 JSONL의 실제 usage와 유일 일치한 169건만 백필했고, 273건은 <code>token_unmetered_turns</code>로 남겼다. 인증된 공개 관리자 화면은 확인 시점 30일 Claude 183건 중 계량 125·미계량 58건을 표시했다.</td></tr>
<tr><td>H3 raw source isolation</td><td><code>python -B -m pytest -p no:cacheprovider app/test_persona_review.py app/test_live_coach_sources.py -q</code></td><td>38 passed; persona source registration records raw hash-only artifacts separately from sanitized evaluator-only RAG chunks, and <code>rag.index_document()</code> rejects <code>sensitivity=3</code>/raw-marker chunks before DB access.</td></tr>
<tr><td>H3 persona itemized authoring UI</td><td><code>npm run typecheck</code> / <code>npm run build</code> / <code>npm run check:api-types</code> / <code>npx playwright test e2e/teacher.spec.ts --project=chromium-single-run --workers=1</code> / <code>npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --workers=1</code> / <code>npx playwright test e2e/session-layout.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1</code></td><td>Typecheck/build/API type drift check passed; teacher PersonaStudio focused 8 passed including structured list payload and labeled prompt preview without raw JSON; visual gate 9 passed with the prompt tab opened; session-layout desktop/mobile 8 passed.</td></tr>
<tr><td>H2 session review 3-column workbench</td><td><code>npm run typecheck</code> / <code>npm run build</code> / <code>npx playwright test e2e/session-review.spec.ts --project=chromium-desktop --workers=1</code> / <code>npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --workers=1</code></td><td>Typecheck/build passed; 3 focused review E2E passed; 9 visual gates passed with dark-theme assertion. Filled learner review uses overview/flow, transcript, and evaluation rail as a 3-column desktop workbench with worksheet below; empty review remains 2 columns or less to avoid sparse gaps.</td></tr>
@ -1005,7 +1085,7 @@
<tr><td>OAuth/SAML admin landing</td><td><code>C:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -X utf8 -m pytest -p no:cacheprovider app/test_auth_providers.py -q</code> / public runtime restart</td><td>36 passed; OAuth/SAML callback now normalizes generic saved <code>next</code> paths such as <code>/learn</code> and <code>/teach</code> to <code>/admin</code> for admin-entitled users while preserving deep links such as <code>/learn/session/...</code>. Live proof after commits <code>998acb44</code>/<code>6b6241f4</code> and latest boot-diagnostic deploy <code>b67fd5d4</code>: local/public <code>/health</code> returned <code>prod</code>, <code>db=true</code>, <code>engine=true</code>; custom domain now serves <code>assets/index-R5KK7hZI.js</code>/<code>assets/index-DzdAkRsn.css</code> plus boot diagnostic HTML; unauthenticated <code>/personas</code> remains <code>401</code>.</td></tr>
<tr><td>Session read-model DB readiness</td><td><code>python scripts\check-deploy-preflight.py --skip-db --env-file infra\.env.example --allow-placeholder-secrets</code> / <code>https://api-vignette.chanpaca.net/health</code></td><td>2026-06-29 prod 503 원인은 운영 DB의 <code>app.turns.provider_events</code> 컬럼 누락이었다. 운영 DB hotfix 후 <code>/teacher/dashboard</code> code path는 <code>source=database</code>로 복구됐다. 현재 <code>db.healthcheck()</code>, runtime table readiness, deploy preflight DB mode는 <code>app.turns</code> 음성 메타 컬럼 5개(<code>audio_ref</code>, <code>silence_ms</code>, <code>speech_rate</code>, <code>barge_in</code>, <code>provider_events</code>), <code>app.session_review_status</code> worksheet 컬럼, <code>app.safety_events</code> 필수 컬럼을 함께 검증한다. 2026-06-30에는 Docker Desktop/DB 중단으로 public API 530/error code 1033이 재발했지만, Docker Desktop/DB 재기동 뒤 public health가 <code>environment=prod</code>, <code>db=true</code>, <code>engine=true</code>로 복구됐다.</td></tr>
<tr><td>Admin usage persistence</td><td><code>python -m pytest app/test_admin_ops.py app/test_runtime_policy.py -q</code> / authenticated local public-API smoke</td><td>26 passed; <code>/admin/usage</code> returns 200 with <code>source=database</code>, <code>durable=true</code>. Cloudflare blocked raw Python public smoke with 1010, so app-level HTTP was verified against <code>127.0.0.1:8001</code> using the same prod process.</td></tr>
<tr><td>Admin AI operations subpage</td><td><code>npx playwright test e2e/admin.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --grep="admin route guards"</code> / <code>npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --workers=1</code> / <code>npx playwright test e2e/session-layout.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1</code></td><td><code>/admin/ai</code>를 관리자 좌측 메뉴의 독립 작업면으로 추가했다. 7·30·90일 <code>/admin/usage</code> 재조회, DB 원장/영속성, 비용·토큰·계량 커버리지·호출당 단가, 일별 비용, provider/model별 원장, evaluator cache 상세를 표시하고, 기존 <code>GET/PATCH /admin/engine-config</code>로 엔진 방식·연결 주소·기본 모델을 실제 저장한다. 예산은 서버 <code>ADMIN_USAGE_BUDGET_USD</code> 소유임을 그대로 노출한다. 관리자 route guard desktop/mobile 14 passed, 전체 레이아웃 시각 게이트 13 passed(신규 화면 7폭 캡처 포함), session-layout 8 passed.</td></tr>
<tr><td>Admin AI operations subpage</td><td><code>npx playwright test e2e/admin.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --grep="shows detailed AI metering"</code> / <code>npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --workers=1</code> / <code>public-admin-visual.spec.ts --grep="shows the live Codex and Agy model catalogs"</code></td><td><code>/admin/ai</code>는 7·30·90일 DB 원장, 비용·토큰·토큰 계량 커버리지·호출당 단가, 일별 비용, provider/model breakdown, evaluator cache를 표시하고 엔진 설정을 실제 저장한다. 비용은 <code>SDK 추정</code>·<code>Provider 보고</code>·<code>참조단가</code>·<code>미산정</code>을 구분한다. 토큰 입력은 비캐시·캐시 읽기·캐시 생성 합계이며, 실제 usage가 복구된 행은 토큰과 <code>계량/전체 회</code> 커버리지를, 복구 불가 0/0 행은 <code>미계량</code>을 표시한다. 최신 focused desktop/mobile 2 passed, 7폭 layout 1 passed, 실제 공개 관리자 브라우저 1 passed다.</td></tr>
<tr><td>Synthetic health sampler</td><td><code>record_admin_health_sample()</code>, <code>record-admin-health-sample.py</code>, <code>install-health-sampler-task.ps1</code></td><td>Backend focused 31 passed. Python compile/help passed; PowerShell parser + <code>-PrintOnly</code> passed. Local one-shot appended 5 service rows to <code>app.admin_health_event</code>: status ok, engine_mode claude_cli. This remains sample history, not an SLA claim.</td></tr>
<tr><td>Health retention/rollup</td><td><code>admin_health_daily_rollup</code>, <code>maintain-admin-health-events.py</code>, <code>/admin/uptime</code></td><td>Backend focused 36 passed. Python compile/help passed. Local dry-run returned <code>rollup_event_count=0</code>, <code>prunable_event_count=0</code>. Uptime summary now combines raw samples with daily rollups when raw rows have been pruned; detailed events stay raw-only.</td></tr>
<tr><td>Ticket duplicate linking</td><td><code>support_ticket.fingerprint</code>, <code>parent_ticket_id</code>, <code>/admin/tickets</code></td><td>Backend focused 38 passed. API types, web typecheck, and build passed. Admin tickets E2E 2 passed after restarting local API 8000 on the new code. Duplicate handling is deterministic hint + admin manual parent link/unlink only; no automatic merge, escalation, issue, PR, or thread creation.</td></tr>
@ -1025,6 +1105,7 @@
<tr><td>Crisis safety gate UI</td><td><code>PLAYWRIGHT_PORT=5193 npx playwright test e2e/session-mvp.spec.ts --project=chromium-single-run --workers=1</code> / <code>PLAYWRIGHT_PORT=5259 npx playwright test e2e/session-mvp.spec.ts --project=chromium-desktop --workers=1 --grep "voice conversation stop"</code></td><td>mock SSE <code>safety</code> + <code>done.conversation_stopped</code>와 mock voice <code>reply.conversation_stopped</code>에서 안전 자원 109와 입력 disabled가 유지되고, 빈 client reply를 <code>내담자 응답 없음</code>으로 덮지 않으며 live-coach를 호출하지 않는지 검증한다. 음성 위기 경로는 TTS 종료 이벤트 없이도 socket close를 확인한다.</td></tr>
<tr><td>Persona/session review UI E2E</td><td><code>PLAYWRIGHT_PORT=5215 npx playwright test e2e/teacher.spec.ts --project=chromium-single-run --workers=1</code></td><td>9 passed mixed suite; real server-row rendering과 route-fixture UI 흐름을 함께 포함한다. 교수자가 pending persona를 승인하고, pending/recent review detail로 진입하며, 별도 student analysis 메뉴·학습자 검색·행 펼침·full learner timeline drilldown을 검증한다.</td></tr>
<tr><td>Voice UI synthetic E2E</td><td><code>npx playwright test e2e/voice-success.spec.ts --project=chromium-single-run</code> / <code>PLAYWRIGHT_PORT=5248 npx playwright test e2e/session-mvp.spec.ts --project=chromium-single-run --workers=1 --grep "pending voice transcript"</code></td><td>voice-success 2 passed + pending transcript failure UI 1 passed; direct WS cascade, Session 텍스트 턴의 persisted reply <code>/voice/speech</code>→OpenAI speech→Web Audio 재생, Session mic button path with synthetic browser audio/Web Audio playback, and final transcript followed by persistence failure becoming a visible <code>저장 실패</code> turn instead of a silent successful transcript</td></tr>
<tr><td>G7 explicit consent · external proof</td><td><code>pytest app/test_g7_voice_gain_evidence.py app/test_voice_runtime.py ...</code> / <code>pytest scripts/test_g7_external_proof.py scripts/test_g7_runtime_evidence.py scripts/test_g7_topology_evidence.py scripts/test_g7_external_voice_soak.py</code> / <code>voice-success.spec.ts</code></td><td>API/G7 92 passed, evidence runner/checker·release gate 31 passed, voice UI 2/2. 서버 30일·원음 미보존 consent ledger 성공 전 getUserMedia/voice WS 0회, public v4 interim/final latency, worker/Uvicorn·Linux topology high-water와 independent human-held-out gate를 fail-closed로 고정했다. exact SHA <code>a8c27b0a…1a0d</code> NAS 승격과 clean candidate session E2E 24/24도 통과했다. 실제 마이크·Deepgram·human evidence는 미실행이라 G7 BUILD.</td></tr>
<tr><td>Voice s2s decision memo</td><td><code>docs/decisions/voice-s2s-poc.md</code></td><td>criteria recorded; keep/drop decision remains owner DECIDE</td></tr>
<tr><td>Hanshin data/SSO gate</td><td><code>docs/ops/hanshin-data-governance-gate.md</code></td><td>artifact created; written external evidence still required</td></tr>
<tr><td>Hanshin feedback 1차 improvement pack</td><td><code>docs/ops/hanshin-feedback-improvement-plan-2026-07-03.md</code> / <code>docs/redteam/hanshin-feedback-plan-redteam-2026-07-03.md</code> / <code>docs/redteam/hanshin-feedback-plan-counter-redteam-2026-07-03.md</code> / backend+web implementation</td><td>1차 implemented: P1 role mapping + client-only history injection, P2 quality retry/no-save gate + SSE full-response buffer, P3 review display humanization/raw error mapper/fast-deep labels/client feedback label, P4 supervisor scope panel. Verification: backend focused 84 passed, web typecheck and API type check passed, session-review focused 8 passed, layout visual gate 12 passed, session-layout 8 passed. Remaining follow-ups are stored fallback metadata, lower-latency partial stream policy, fast/deep reconciliation, resident namespace/prompt caching, and clinical rubric/CBT wording gates.</td></tr>
@ -1040,6 +1121,10 @@
<tr><td>Docker image smoke</td><td><code>docker build -f apps/api/Dockerfile .</code> / <code>docker run ... python -c "import app.main"</code> / <code>docker build -f apps/web/Dockerfile apps/web</code></td><td>API/Web image build and API import smoke pass after packaging cleanup. Web build uses npm lockfile and ignores host <code>node_modules</code>; API image excludes local <code>.env</code> files.</td></tr>
<tr><td>Deploy preflight</td><td><code>python scripts\check-deploy-preflight.py --skip-db --env-file infra\.env.example --allow-placeholder-secrets</code> / DB mode with local <code>DATABASE_URL</code></td><td>Passed: exact-pinned API requirements, live coaching <code>data/kb</code> source pack, env template keys, and DB readiness (<code>current_user=vignette</code>). DB mode can additionally check app-role DSN with <code>--require-app-role</code> and now verifies session read-model columns including <code>app.turns</code> voice metadata columns(<code>audio_ref</code>/<code>silence_ms</code>/<code>speech_rate</code>/<code>barge_in</code>/<code>provider_events</code>) plus worksheet review columns.</td></tr>
<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> 매일 04:30 KST / <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 SHA <code>6030a677…c611</code>을 전용 Compose 프로젝트·포트·네트워크·named volume에 승격했다. browser E2E 108/108, health 3/3, OpenAPI 126·auth 401·G0~G8, postdeploy SSE→DB review를 통과했고 predeploy dump와 이전 exact images를 보존했다. 자동화는 ACTIVE이며 material milestone+release gate+배포 SHA 변경 때만 프리뷰를 갱신한다. G7 외부 mic/provider/human 증거는 별도다.</td></tr>
<tr><td>비-secure origin 회기 리뷰 크래시 수정</td><td><code>apps/web/src/lib/uuid.ts</code> · <code>apps/web/e2e/insecure-context-uuid.spec.ts</code></td><td>격리 NAS 프리뷰(평문 HTTP·비-localhost)에서 회기 리뷰 라우트가 <code>crypto.randomUUID is not a function</code>으로 error boundary에 잡혔다. 이 API는 secure context 전용인데 제품 코드 18곳이 fallback 없이 호출했고 <code>RuptureRepairCard</code>는 렌더 시점 호출이라 화면 전체가 죽었다. 릴리스 게이트는 localhost 후보 스택에서만 돌아 미검출. <code>randomUuid()</code>로 통일하고 fallback도 <code>getRandomValues</code> 우선으로 예측 불가능성을 유지했다. 회귀 <code>6/6</code>(직접 호출 0건 검사 포함), typecheck·build 통과. <b>NAS 프리뷰에는 아직 미배포</b>이며 배포된 SHA <code>6030a677…c611</code>은 여전히 결함 빌드다.</td></tr>
<tr><td>공개 워치독 engine readiness 사각지대(해결)</td><td><code>scripts/watch-public-runtime.ps1</code> · <code>scripts/start-public-runtime.ps1</code> · <code>apps/api/engine_gateway/gateway.py</code></td><td>2026-08-07 22:0x KST 소유자 승인으로 9099를 재기동해 복구했다. 재기동 직후 <code>/ready?force=true</code> 200 <code>ok:true·detail:OK</code>, API 8001과 공개 <code>api-vignette.chanpaca.net</code> 모두 <code>status:ok·engine:true·engine_detail:OK</code>다. 원인은 16:06부터 상주한 9099 프로세스 하나였다(CLI·코드·cwd는 정상 — 동일 인자 직접 실행과 <code>EngineSession</code> 재현이 <code>"OK"</code>를 반환). 재발 방지 3건: (1) 워치독·기동 스크립트의 engine 판정을 <code>/health</code>(프로세스 liveness)에서 <code>/ready</code>(실제 생성)로 바꾸고 API 판정에 <code>engine</code>을 추가, shared secret 인스턴스용 토큰 헤더와 503 본문 로깅 포함. (2) 게이트웨이가 자식 <code>claude -p</code>의 stderr를 상시 드레인해(PIPE 미독 시 자식 블록도 차단) 실패 detail에 <code>exit</code>·stderr를 붙인다 — 실증: <code>empty engine response (error: unknown option '--vignette-nonexistent-flag-xyz')</code>. (3) 기동 시 게이트웨이 로그 회전, <code>Stop-UvicornByPort</code><code>Name -like python*</code> 추가(호출자 자기 자신 종료 방지). 검증: <code>pytest engine_gateway</code> 58/58, 워치독 <code>-CheckOnly</code> healthy 5/5, 장애 재현(9299·<code>CLAUDE_BIN</code> 부재)에서 <code>/health</code><code>ok:true</code>로 통과하고 <code>/ready</code>는 503으로 검출되어 워치독이 <code>unhealthy (1/3)</code> + 503 본문을 남겼다. <b>NAS용 9100(06:27 상주)은 실사용 세션 7개가 있어 미접촉</b>이라 게이트웨이 stderr 개선은 다음 재기동 때 반영된다.</td></tr>
<tr><td>G8 실제 receipt-bound image rollback</td><td><code>scripts/launch-nas-preview-g8-helpers.py</code> / <code>scripts/serve-nas-preview-rollback-executor.py</code> / <code>scripts/probe-nas-preview-g8-rollback.py</code> / <a href="./ops/nas-preview-g8-rollback-proof-runbook.md">런북</a> / <a href="./ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json">기계 판독 증거</a></td><td>격리 NAS에서 별도 executor(18149)·control-plane(8018) helper로 실제 image rollback 2회를 실행했다. receipt <code>nas-g8-723eeef2…</code>로 previous <code>79ec…4450</code>/<code>c530…2f28</code>, receipt <code>nas-g8-2738846c…</code>로 current <code>52e0…8b2d</code>/<code>6fdb…f215</code>를 활성화했다. release gate·approval 각각 2회 멱등, <code>audit.ci_lifecycle_event</code> rollback/executed 2건과 receipt id 결속, silent auto-promotion 0, HMAC journal 6-record 체인 검증, health 3/3·OpenAPI 126·auth 401·Web 200, helper 0·listener 0 복귀. helper 격리 계약은 image 상속 label baseline 대비 검증이며 fake-runner 37/37로 고정했다. <code>down</code>/<code>volume rm</code>/<code>prune</code> 미실행, 공개 런타임 미접촉.</td></tr>
<tr><td>Actual deployment env</td><td><code>infra/.env</code> owner-secret fill-in</td><td>Remaining external step: deployment target must provide real <code>APP_DB_PASSWORD</code>, OAuth client id/secret, <code>OPENAI_API_KEY</code>, <code>SESSION_SECRET</code>, and production-safe engine/voice flags. Current local stray values such as <code>ENGINE_MODE=claude_cli</code> and prod sample TTS must not be copied.</td></tr>
<tr><td>Focused E2E</td><td><code>admin + db-persistence + voice-success</code></td><td>Latest admin spec: 8 passed on chromium desktop, including all-workspace admin navigation, health dashboard, real server-known users, operation tickets, mobile controls, and tablet form containment.</td></tr>
<tr><td>Dev dashboard redteam</td><td><code>scripts/test_dev_dashboard_ssot.py</code> / <code>e2e/dev-dashboard.spec.ts</code></td><td>Unit: SSOT checker 4 tests OK + current dashboard check PASS. E2E: local file, <code>127.0.0.1</code>, <code>localhost</code> 외부형 origin, 필터 오순서/빠른 재시도/키보드, details/tabs 접기, hash anchor, 링크·이미지 무결성, desktop/mobile overflow를 검증해 chromium desktop/mobile 10 passed.</td></tr>
@ -1073,7 +1158,7 @@
<tr><td>Engine gateway probe (live)</td><td><code>scripts/probe-engine-gateway.py --base-url http://127.0.0.1:9099 --reuse-runs 2</code></td><td>claude_p / opus-4-8; 단일 session_id 2회 reused stream; TTFT 16674199ms; cost 누적 0.068→0.123(turns 1→2)</td></tr>
<tr><td>Engine gateway RSS (live)</td><td><code>docs/ops/engine-rss-smoke-2026-06-28.md</code></td><td>gateway session 1개, <code>health.sessions=1</code>; gateway PID 51592 RSS 16.2MB; resident <code>claude -p</code> child PID 51688 RSS 363.3MB / Private 628.8MB after one turn; plugin bun children RSS 178.6MB.</td></tr>
<tr><td>Postgres RLS/audit smoke (live)</td><td><code>VIGNETTE_RLS_AUDIT_DSN=…vignette_app… check-postgres-rls-audit.py --write-fixtures</code></td><td>5 checks PASS: preflight, learner 세션/턴 격리, teacher cohort 스코프, visible_to evaluator-only 숨김, teacher/admin read audit insert (NOBYPASSRLS app role, fixtures 자동 정리)</td></tr>
<tr><td>Turn cost telemetry (live DB)</td><td><code>SELECT … FROM app.turns WHERE actor_kind='client_ai'</code></td><td>13 client_ai turns 적재: llm_provider=claude_cli, model=gateway-default, cost_usd 실값(합 $1.22, 평균 $0.094), visible_to 배열. 토큰은 CLI 게이트웨이 특성상 0, cost는 산출</td></tr>
<tr><td>Turn cost/token telemetry (live DB)</td><td><code>SELECT … FROM app.turns WHERE actor_kind='client_ai'</code> / live gateway generate·SSE / <code>scripts/backfill-claude-token-usage.py</code></td><td>Claude CLI의 <code>total_cost_usd</code>는 청구 실비가 아닌 SDK 비용 추정값으로 저장한다. 신규 gateway generate·SSE는 <code>modelUsage</code> 전체 agent tree의 비캐시·cache read/create 입력과 출력을 전달한다. 수정 전 전체 0/0 Claude 442건 중 로컬 JSONL의 정규화 응답 SHA-256·시각이 유일하게 일치한 169건만 실제 입력 5,179,999·출력 46,910 토큰으로 복구했다. 불일치 273건은 비용 역산 없이 <code>token_unmetered_turns</code>로 남겼다.</td></tr>
<tr><td>Cosmetic polish re-verify</td><td><code>5 polish agents → typecheck + gate + layout E2E re-run</code></td><td>typecheck OK; current gate 9 passed; layout focused E2E 54 passed; session-layout 8/8; regression 0</td></tr>
<tr><td>Dashboard layout alignment</td><td><code>npm run typecheck</code> / <code>npm run build</code> / <code>layout-visual-gate</code> / <code>session-layout</code> / <code>session-review</code> / <code>learner+teacher+admin E2E</code></td><td>current rerun: typecheck/build passed; layout gate 9 passed; session-layout+session-review chromium-desktop 6 passed. 이전 정렬 라운드: session-layout desktop/mobile 8 passed; learner+teacher+admin chromium-desktop 17 passed. 대표 캡처는 <code>docs/archive/ops/layout-research-2026-06-28/final-gate-*.png</code>.</td></tr>
<tr><td>Learner session archive</td><td><code>python -B -m pytest app/ -q</code> / <code>python -B -m pytest engine_gateway/ -q</code> / <code>npm run check:api-types</code> / <code>npm run typecheck</code> / <code>npm run build</code> / <code>npx playwright test e2e/learner.spec.ts --project=chromium-desktop --workers=1</code></td><td>Archive 당시 178 backend passed + 11 gateway passed; 최신 gateway contract gate는 27 passed. OpenAPI generated archive DTOs are current; learner history can archive/restore an ended session and keeps archived sessions out of the review queue while preserving records.</td></tr>
@ -1091,7 +1176,7 @@ $env:E2E_PUBLIC_STORAGE_STATE=".\node_modules\.tmp\public-auth.json"
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start-public-runtime.ps1</pre>
</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는 2026-06-30 재확인 완료, 실제 계정 storageState 필요) · 실배포 <code>infra/.env</code> owner-secret fill-in(<code>APP_DB_PASSWORD</code>, <code>OAUTH_GOOGLE_CLIENT_ID</code>, <code>OAUTH_GOOGLE_CLIENT_SECRET</code>, <code>OPENAI_API_KEY</code>, <code>SESSION_SECRET</code>) · <code>vnet.18ka.net</code>/<code>api-vnet.18ka.net</code> 공개 런타임(DNS A record 0, Cloudflare 18ka.net zone 권한 불일치, Google OAuth redirect URI 등록 필요) · 한신대 데이터/SSO 거버넌스(owner/기관 written evidence 필요) · 음성 실제 Deepgram interim/final WSS·물리 마이크·공개 WSS·50분 양방향 장시간 실측 · claude_cli↔Messages API 폴백 동일성 · 실제 Windows 재부팅 후 watchdog smoke · Phase 3 파일럿 게이트. owner 결정 7건은 2026-06-30 전건 확정됨. 운영 원칙상 가짜 증거로 DONE 표기하지 않는다. 전체 추적: <code>docs/ops/backlog-2026-06-26.md</code>(B1 구현 후속 · B2 환경제약 · B3 소유자결정 · B4 거버넌스).</div>
<div class="source-note"><b>환경 제약으로 이 세션에서 못 닫는 항목(정직 표기):</b> 공개 Google OAuth 실제 <code>/turn</code>(OAuth start는 2026-06-30 재확인 완료, 실제 계정 storageState 필요) · 실배포 <code>infra/.env</code> owner-secret fill-in(<code>APP_DB_PASSWORD</code>, <code>OAUTH_GOOGLE_CLIENT_ID</code>, <code>OAUTH_GOOGLE_CLIENT_SECRET</code>, <code>OPENAI_API_KEY</code>, <code>SESSION_SECRET</code>) · <code>vnet.18ka.net</code>/<code>api-vnet.18ka.net</code> 공개 런타임(DNS A record 0, Cloudflare 18ka.net zone 권한 불일치, Google OAuth redirect URI 등록 필요) · 한신대 데이터/SSO 거버넌스(owner/기관 written evidence 필요) · G7 실제 Deepgram 운영 key·quota live interim/final, 기대 provider/model authenticated public WSS ready, 명시 동의 물리 마이크와 50분 양방향 soak · claude_cli↔Messages API 폴백 동일성 · 실제 Windows 재부팅 후 watchdog smoke · Phase 3 파일럿 게이트. owner 결정 7건은 2026-06-30 전건 확정됨. 운영 원칙상 가짜 증거로 DONE 표기하지 않는다. 전체 추적: <code>docs/ops/backlog-2026-06-26.md</code>(B1 구현 후속 · B2 환경제약 · B3 소유자결정 · B4 거버넌스).</div>
</div>
<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>
@ -1238,7 +1323,8 @@ powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start-public-runtime
{id:"P1",name:"MVP 코어루프",pct:78,cls:""},
{id:"P2a",name:"권한·페르소나",pct:74,cls:""},
{id:"P2b",name:"음성 캐스케이드",pct:40,cls:""},
{id:"P3",name:"파일럿·효과",pct:6,cls:"idle"}
{id:"P3",name:"파일럿·효과",pct:6,cls:"idle"},
{id:"AOS",name:"성과·동맹 OS",pct:22,cls:"cur"}
];
var rail=$("phase-rail");
if(rail){