NAS 엔진 장애 상태 반영

This commit is contained in:
Yun Chan 2026-08-12 15:21:04 +09:00
parent a134a1ac71
commit b5f44fe1cb

View file

@ -300,11 +300,11 @@
<section class="pulse">
<div class="pulse-main">
<span class="eyebrow">project pulse</span>
<h1>지금 위치: <em>G0~G6 · G8 DONE</em>. <em>G7 external proof</em>를 닫는 중.</h1>
<p class="pulse-state"><b>현재:</b> G8·공개 앱·주기 실회기 전체 GREEN. <b>다음:</b> G7 명시 동의 mic·human pack·checker exit 0.</p>
<h1>지금 위치: <em>G0~G6 · G8 증거 DONE</em>. <em>NAS 엔진 복구 · G7 external proof</em>가 남았다.</h1>
<p class="pulse-state"><b>현재:</b> 공개 앱·주기 실회기는 GREEN이지만 NAS 프리뷰는 DB 정상·engine 불능으로 DEGRADED다. <b>다음:</b> 승인된 source-pinned engine relay 복구와 NAS-origin 재검증, 이후 G7 명시 동의 mic·human pack·checker exit 0.</p>
<details class="pulse-details">
<summary>운영 복구·watchdog·배포 상세 보기</summary>
<p class="pulse-state">G8 clean-head NAS-origin은 candidate 112/112·실제 origin 112/112로 DONE이다. 공개 API는 detached-clean <code>a73bcd24…</code>·tree <code>b02b3a1b…</code>에서 OpenAPI 126, <code>/admin/voice-runtime</code>, <code>local_whisper/small</code> + <code>melotts/melotts-korean</code>, WS queue 4를 제공하며 fresh provenance receipt <code>47388d58…9b08</code>가 passed다. 공개 Web은 Pages entry <code>index-BrpoQ5nP.js</code>와 review chunk <code>SessionReview-E03q-dGb.js</code>에서 literal <code>[NAME]</code> 0·시간 만료·모바일 44px/자동 스크롤 보정을 노출한다. 주기 실회기 7차는 clean <code>aa81af29…</code>에서 same-learner SSE→review→G4/G5 <code>0→1→1</code>과 별도 zero-state returned desktop/mobile <code>4/4</code>, route mock 0, exact cleanup 0을 모두 통과했다. hourly heartbeat는 최신 GREEN이 6시간 이상 오래됐거나 학생 runtime·회기 폐루프 material milestone이 바뀔 때만 full runner를 최대 1회 실행한다. G7 human intake·checker·template-only 변경은 G7 focused gate만 실행해 학생 실DB runner와 증거를 섞지 않는다. 마이크를 열지 않은 G7 rehearsal은 인증 WSS·runtime·Windows topology 세 leg 7-sample로 통과했다. 다음 외부 gate는 실제 mic·동시 high-water·human evidence다.</p>
<p class="pulse-state"><b>2026-08-12 현재 인시던트:</b> 공개 API는 health ok·db/engine true·OpenAPI 126·auth 401과 local voice를 유지한다. 반면 NAS 프리뷰 health는 3/3 <code>degraded·db=true·engine=false</code>이고 API 컨테이너가 unhealthy다. NAS API의 고정 <code>ENGINE_URL=http://192.168.0.223:9100</code> 대상 listener가 사라졌으며 공개 엔진은 별도 loopback <code>127.0.0.1:9099</code>에서 정상이다. G8 clean-head candidate 112/112·실제 origin 112/112와 rollback receipt는 완료 증거로 보존하지만, 현 NAS runtime은 relay를 source/secret/task에 결속해 복구하고 health 3/3·auth·OpenAPI·assets·실제 회기를 다시 통과할 때까지 DEGRADED다. 자동 재시작·포트 노출·배포는 실행하지 않았다. G7은 별도로 명시 동의 mic·동시 high-water·human evidence가 남는다.</p>
<p class="pulse-state">2026-08-07 공개 DB는 recovered named volume으로 전환했고 원본 container·dump·volume을 보존했다. 2026-08-12에는 휴면 Gradle daemon의 <code>8001</code> 점유·cloudflared/voice sidecar 중단과 PowerShell 5.1 native stderr 조기 종료 결함을 복구했다. DB mutation 전에 fresh custom dump <code>9cbda31e…0ce5</code>(7,532,625 bytes·TOC 1,492)를 고정했다. 공개 API·cloudflared는 detached-clean <code>a73bcd24…</code>·tree <code>b02b3a1b…</code>로 fresh 교체했고 public health 3/3·db/engine true·OpenAPI 126·local voice exact를 통과했다. 로그온·5분 watchdog 두 task도 같은 root/commit/tree/script SHA에 pin해 명시 실행 결과 0을 확인했다. 공개 runtime receipt는 <code>47388d58…9b08</code>, 무마이크 rehearsal evidence는 voice <code>61af2e98…</code>·runtime <code>c6e8670e…</code>·topology <code>89f1cb86…</code>이며 UUID/email literal 0이다. G7은 배포가 아니라 실제 mic·동시 high-water·human evidence만 남은 external GATE다.</p>
</details>
<div class="phase-rail" id="phase-rail" aria-label="Phase 진행 추정"></div>
@ -677,6 +677,7 @@
<p class="dg-note">198차 적용(2026-08-10): clean HEAD <code>aa81af29…</code>·tree <code>3901d71c…</code>의 7차 full run이 499.8초에 첫 전체 <b>GREEN</b> receipt <code>periodic-learner-e2e-20260810-020117.json</code>·SHA-256 <code>bae963de…f32e1a</code>를 만들었다. 실제 브라우저 same-learner session 생성·SSE·review ready·G4/G5 <code>0→1→1</code>, 별도 zero-state returned-practice desktop/mobile <b>4/4</b>, route mock 0을 통과했다. public 8001·active DB 55432·engine 9099·NAS 접촉은 0이며 전용 container 4·volume 3·network 1·engine PID와 6578-6581 listener는 cleanup 뒤 모두 0이다. 기존 <code>vignette-e2e</code> hourly heartbeat는 중복 생성 없이 갱신해 최신 GREEN이 6시간 이상 오래됐거나 material milestone이 바뀐 때만 preflight 뒤 full runner를 최대 1회 실행하고, 실패 시 같은 heartbeat에서 재시도하지 않는다. G7 human pack evaluator·runner/checker와 후속 intake compiler 계약도 <b>103/103</b>으로 재검증했으며 물리 마이크는 열지 않았다.</p>
<p class="dg-note">199차 적용(2026-08-12): 실제 공개 학생 홈을 390×844·320×568에서 읽기 전용으로 확인해 부트 진단·console error·가로 overflow·literal PII placeholder는 0이고 핵심 학습 카드·탭·리뷰 CTA는 44px 이상임을 재확인했다. 반면 공통 톱바의 공간 전환 링크는 28px, 테마·로그아웃은 34px에 머물러 있던 P1을 발견했다. 소스는 720px 이하에서 워드마크 글자·사용자 칩을 접고 브랜드·공간 전환·테마·로그아웃 6개를 모두 44×44px로 고정했으며, 관리자 3역할 최악 조건 390/320 desktop/mobile <b>2/2</b>, 학생 자기주도 홈→회기→리뷰→재연습 desktop/mobile <b>6/6</b>, G1·G4·G5·G7 focused <b>50/50</b>, 대시보드 <b>10/10</b>, type/API contract와 SSOT checker를 통과했다. clean HEAD <code>9687f186…c48b</code>·tree <code>be2fc4d2…749d7</code>의 full disposable runner도 485.8초에 GREEN이었고 receipt <code>periodic-learner-e2e-20260812-143426.json</code>·SHA-256 <code>501d2d7f…c557</code>에서 same-learner SSE·review·G4/G5 <code>0→1→1</code>, returned desktop/mobile <b>4/4</b>, route mock 0, public·NAS·active DB 접촉 0과 container·volume·network·listener·temp 잔여 0을 확인했다. 공개 앱에는 아직 이 변경을 배포하지 않았으므로 실제 공개 톱바는 별도 승인 배포 전까지 기존 크기이며, G7은 명시 동의 물리 마이크·독립 human pack·canonical checker exit 0 전까지 external GATE다.</p>
<p class="dg-note">200차 적용(2026-08-12): actual NAS 로그인 320/390 읽기 전용 관측에서 조작면·boot·console은 정상이지만 비-overlay 세로 scrollbar 환경의 <code>100vw</code> 두 선언이 10px 가로 넘침을 만드는 P1을 확인했다. auth/login shell을 scrollbar를 제외한 컨테이너 기준 <code>100%</code>로 바꾸고 320px stable-scrollbar OAuth fixture를 고정했다. 인증 desktop/mobile <b>2/2</b>, 자기주도+G1·G4·G5·G7 <b>56/56</b>, 대시보드 <b>10/10</b>, G7 runner·checker·human/API 계약 <b>110/110</b>, type/API contract·Ruff·SSOT checker를 통과했다. 물리 soak standalone도 canonical 공통 3,000초를 보존하도록 production 기본·최소를 3,120초로 통일해 3,000초 요청을 장치 열거 전에 차단한다. clean HEAD <code>64e1b221…a4e</code>·tree <code>2c687bac…30bf</code>의 full disposable runner는 489.6초에 GREEN이었고 receipt <code>periodic-learner-e2e-20260812-150209.json</code>·SHA-256 <code>a7b2f758…8071</code>에서 same-learner SSE·review·G4/G5 <code>0→1→1</code>, returned desktop/mobile <b>4/4</b>, route mock 0, public·NAS·active DB 접촉 0과 container·volume·network·listener·temp 잔여 0을 확인했다. 이 소스는 아직 공개/NAS에 배포하지 않았다.</p>
<p class="dg-note">201차 관측(2026-08-12): 읽기 전용 현재-state 대조에서 공개 앱은 health ok·db/engine true·OpenAPI 126·auth 401과 <code>local_whisper/small</code>·<code>melotts/melotts-korean</code>을 유지했지만, NAS 프리뷰는 3회 연속 <code>status=degraded·db=true·engine=false</code>였다. NAS의 DB·Web·proxy는 running이고 API는 restart 0인 채 unhealthy였다. 원인은 API의 고정 <code>ENGINE_URL=http://192.168.0.223:9100</code> 대상 listener 부재로 좁혔다. 현재 공개 엔진은 별도 loopback <code>127.0.0.1:9099</code>에만 있어 공개 서비스는 영향받지 않는다. 과거 G8 clean-head NAS-origin 112/112와 실제 rollback receipt는 완료 증거로 보존하되, 현 NAS runtime은 <b>DEGRADED · REVALIDATION</b>으로 표시한다. 별도 승인 전에는 LAN 포트 노출·Scheduled Task 생성·컨테이너 재시작·배포를 하지 않는다. source-pinned·secret-bound relay를 복구한 뒤 health 3/3·auth 401·OpenAPI 126·assets·실제 NAS-origin 회기 smoke를 다시 통과해야 current GREEN으로 돌아간다.</p>
<div class="dg-principles" aria-label="디자인 생성 가드레일">
<div><b>래스터만 사용</b><span>이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.</span></div>
<div><b>기능 우선</b><span>메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.</span></div>
@ -934,8 +935,8 @@
<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를 연결했다. 운영 기본 provider는 노트북 상주 <code>local_whisper</code>/<code>melotts</code>이고 외부 Deepgram/OpenAI adapter는 fallback으로 보존한다. 격리 synthetic PCM soak는 59/59를 통과했다. Windows host topology는 detached-clean commit/tree·도구 SHA·<code>psutil</code> version과 PID/start/exe·command SHA/cwd·process/TCP high-water를 fail-closed로 수집하고, 3,120초 capture의 공통 3,000초를 canonical exit와 결속한다. 공개 API/cloudflared는 clean <code>a73bcd24…</code>·tree <code>b02b3a1b…</code>로 fresh 승격돼 OpenAPI 126·<code>/admin/voice-runtime</code>·<code>local_whisper/small</code>·<code>melotts/melotts-korean</code>·WS queue 4를 제공한다. receipt <code>47388d58…9b08</code>가 passed이고 두 source-pinned task도 result 0이다. human pack은 category·κ·preregistration·paired completeness·결측 ITT를 캡처 전에 검증한다. 새 intake compiler는 non-evidence 빈 틀에서 시작해 비식별 CSV의 production floor·ICC·κ·gain·CI를 재계산하고 모두 통과한 경우에만 pack을 쓴다. 생성된 README가 key/split·status-score·taxonomy·실행 순서를 설명하며 관련 계약은 103/103·runtime sampler 4/4다.</p></div><div class="kv k-warn"><b>외부 종료 GATE</b><p>30초 무마이크 rehearsal은 authenticated public WSS ready/ping/close1000, runtime 7 samples, Windows topology 7 samples를 모두 통과했고 <code>physical_capture=false</code>·UUID/email literal 0이다. 남은 것은 사용자가 선택한 장치와 실행 직전 명시 동의를 받은 물리 마이크 3,120초 양방향 soak, 같은 public host·공통 3,000초 시간창의 worker/Uvicorn queue와 process/TCP high-water, 최소 31명·held-out 50회기·150축·blind evaluator 2인의 실제 독립 human voice-gain pack이다. 작성 도구만 준비됐고 사람 데이터는 아직 없다. pack은 <code>check-g7-human-voice-gain.py</code>를 먼저 통과해야 하며 부적합하면 마이크를 열기 전에 exit 2다. 네 artifact가 <code>scripts/check-g7-external-proof.py</code> exit 0을 만들기 전에는 메인 상태를 DONE으로 바꾸지 않는다.</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 · CLEAN-HEAD NAS VERIFIED</span><span class="scard-mid"><span class="scard-title">Autonomous Content &amp; Continuous Improvement</span><span class="scard-sum">agentic worker·human gate·실제 rollback과 current clean source의 NAS-origin 112/112를 모두 닫았다.</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>clean-head NAS-origin 종료 증거</b><p>source HEAD <code>61a41d1f…6af</code>·tree <code>87dec55d…3b77</code>·2회 동일 archive <code>4d15d055…119d4d</code>를 active release에 결속했다. candidate session E2E <b>112/112</b>와 실제 평문 NAS-origin browser review <b>112/112</b>(11 specs, desktop/mobile/single-run)가 GREEN이며 API/Web <code>d5021950…e4b1</code>/<code>9796c092…4b36</code>, health ok·db/engine true, auth 401, OpenAPI 126을 확인했다. fresh dump <code>36ec8748…24db8</code>(1,097,100 bytes, TOC 1,738 / TABLE DATA 129)와 previous <code>6030a677…c611</code>을 보존했다.</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 체인 검증을 확인했다. 상세: <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>
<button class="scard-head" aria-expanded="false"><span class="chip c-done">G8 DONE · EVIDENCE VERIFIED · RUNTIME DEGRADED</span><span class="scard-mid"><span class="scard-title">Autonomous Content &amp; Continuous Improvement</span><span class="scard-sum">agentic worker·human gate·실제 rollback·NAS-origin 112/112 증거는 닫혔고, 현재 NAS engine relay는 재검증이 필요하다.</span></span><span class="caret" aria-hidden="true"></span></button>
<div class="scard-body"><div class="kv k-warn"><b>현재 NAS runtime 인시던트</b><p>2026-08-12 NAS health는 3/3 <code>degraded·db=true·engine=false</code>이며 API 컨테이너가 unhealthy다. 고정 <code>ENGINE_URL=http://192.168.0.223:9100</code> 대상 listener가 없고 공개 엔진은 별도 loopback 9099에서 정상이다. 과거 배포·rollback 증거를 무효화하지는 않지만, 승인된 relay 복구와 actual-origin 회기 재검증 전에는 current runtime GREEN으로 표시하지 않는다.</p></div><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>clean-head NAS-origin 종료 증거</b><p>source HEAD <code>61a41d1f…6af</code>·tree <code>87dec55d…3b77</code>·2회 동일 archive <code>4d15d055…119d4d</code>를 active release에 결속했다. candidate session E2E <b>112/112</b>와 실제 평문 NAS-origin browser review <b>112/112</b>(11 specs, desktop/mobile/single-run)가 GREEN이며 API/Web <code>d5021950…e4b1</code>/<code>9796c092…4b36</code>, 당시 health ok·db/engine true, auth 401, OpenAPI 126을 확인했다. fresh dump <code>36ec8748…24db8</code>(1,097,100 bytes, TOC 1,738 / TABLE DATA 129)와 previous <code>6030a677…c611</code>을 보존했다.</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 체인 검증을 확인했다. 상세: <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>
@ -959,7 +960,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> local_whisper STT + MeloTTS 기본, Deepgram/OpenAI fallback</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</span></div><h3>성과·동맹·수련 폐루프</h3><p>측정 → 이상 탐지 → 원인 가설 → 재연습 → 전이 검증 → 숙련도 갱신.</p><ul class="phase-list"><li><b>상태:</b> G0~G6 internal DONE · G8 clean-head NAS-origin DONE · G7 외부 voice/resource/human 대기</li><li><b>완료 DAG:</b> AOS-001~012</li><li><b>운영:</b> NAS archive <code>4d15d055…119d4d</code> · candidate/NAS-origin 112/112 · G7 canonical four-artifact checker exit 0 필요</li></ul></article>
<article class="phase-card next"><div class="phase-top"><span class="phase-id">Outcome OS</span><span class="tag doing">NAS DEGRADED · G7 external</span></div><h3>성과·동맹·수련 폐루프</h3><p>측정 → 이상 탐지 → 원인 가설 → 재연습 → 전이 검증 → 숙련도 갱신.</p><ul class="phase-list"><li><b>상태:</b> G0~G6 internal DONE · G8 배포/rollback 증거 DONE · 현 NAS engine relay 재검증 · G7 외부 voice/resource/human 대기</li><li><b>완료 DAG:</b> AOS-001~012</li><li><b>운영:</b> NAS archive <code>4d15d055…119d4d</code> · 역사 candidate/NAS-origin 112/112 · current health degraded/db true/engine false · G7 canonical four-artifact checker exit 0 필요</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>
@ -1164,10 +1165,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> 매시간 heartbeat / <a href="./ops/nas-preview-deployment-evidence-2026-08-07.md">배포 증거</a> / <a href="./ops/evidence/nas-preview-current-deploy-2026-08-07.json">기계 판독 증거</a></td><td>current clean source HEAD <code>61a41d1f…6af</code>·tree <code>87dec55d…3b77</code>의 archive <code>4d15d055…119d4d</code>를 전용 Compose 프로젝트·포트·네트워크·named volume에 승격했다. candidate 112/112와 실제 NAS-origin 112/112는 통과했지만 영수증은 실 API/DB 22건과 route fixture 90건을 분리한다. 자동화는 공개/NAS 화면과 health를 읽기 전용으로 매시간 보여준다. material milestone의 동일 학습자 SSE→review→G4/G5 actual 폐루프는 clean HEAD/tree·전용 engine/DB/API/Web·보호 포트 거부·sentinel·exact cleanup runner가 소유한다. 1~3차는 하네스, 4차는 reload ledger hydration 제품 결함, 5차는 fixture 공유, 6차는 mobile success-state locator를 fail-closed했다. 7차 clean <code>aa81af29…</code>는 same-learner SSE·review·G4/G5 <code>0→1→1</code>과 별도 returned desktop/mobile <code>4/4</code>, route mock 0, cleanup 0으로 첫 전체 GREEN을 만들었다. heartbeat는 최신 GREEN이 6시간 이상 오래됐거나 학생 runtime·회기 폐루프 material milestone이 바뀔 때만 full runner를 최대 1회 실행하고 실패 시 자동 재시도하지 않는다. G7 human intake·checker·template-only 변경은 G7 focused gate만 실행한다. release gate·NAS preflight·배포 SHA 변경 때만 프리뷰를 갱신한다. G7 외부 mic/provider/human 증거는 별도다.</td></tr>
<tr><td>격리 NAS 프리뷰 · 회기 E2E 자동화</td><td><code>http://100.116.83.60:8088</code> / <code>vignette-e2e</code> 매시간 heartbeat / <a href="./ops/nas-preview-deployment-evidence-2026-08-07.md">배포 증거</a> / <a href="./ops/evidence/nas-preview-current-deploy-2026-08-07.json">기계 판독 증거</a></td><td>current clean source HEAD <code>61a41d1f…6af</code>·tree <code>87dec55d…3b77</code>의 archive <code>4d15d055…119d4d</code>를 전용 Compose 프로젝트·포트·네트워크·named volume에 승격했다. candidate 112/112와 실제 NAS-origin 112/112는 당시 통과했지만 영수증은 실 API/DB 22건과 route fixture 90건을 분리한다. <b>2026-08-12 현재는 health 3/3 degraded·db true·engine false</b>이며, 고정 LAN engine relay listener 부재로 current runtime 재검증이 필요하다. 자동화는 공개/NAS 화면과 health를 읽기 전용으로 매시간 보여준다. material milestone의 동일 학습자 SSE→review→G4/G5 actual 폐루프는 clean HEAD/tree·전용 engine/DB/API/Web·보호 포트 거부·sentinel·exact cleanup runner가 소유한다. 1~3차는 하네스, 4차는 reload ledger hydration 제품 결함, 5차는 fixture 공유, 6차는 mobile success-state locator를 fail-closed했다. 7차 clean <code>aa81af29…</code>는 same-learner SSE·review·G4/G5 <code>0→1→1</code>과 별도 returned desktop/mobile <code>4/4</code>, route mock 0, cleanup 0으로 첫 전체 GREEN을 만들었다. heartbeat는 최신 GREEN이 6시간 이상 오래됐거나 학생 runtime·회기 폐루프 material milestone이 바뀔 때만 full runner를 최대 1회 실행하고 실패 시 자동 재시도하지 않는다. G7 human intake·checker·template-only 변경은 G7 focused gate만 실행한다. release gate·NAS preflight·배포 SHA 변경 때만 프리뷰를 갱신한다. G7 외부 mic/provider/human 증거는 별도다.</td></tr>
<tr><td>G7 외부 증거 3-artifact 동시 시간창 오케스트레이터</td><td><code>scripts/run-g7-external-proof-window.py</code> · <a href="./ops/outcome-os-g7-external-proof-readiness-2026-08-07.md">준비 문서</a></td><td>soak·runtime·topology 세 캡처를 같은 host의 공통 3,000초 시간창으로 실행하고 checker까지 잇는다. 공개 배포·프로세스·source pin은 clean commit <code>a73bcd24…</code>와 fresh receipt <code>9f8d1941…</code>로 완료했다. Cloudflare가 Python 기본 User-Agent를 403으로 거부하는 경계도 브라우저 호환 header와 회귀 4/4로 고정했다. 30초 rehearsal은 세 leg 7 samples를 모두 통과했으며 마이크를 열지 않았다. <b>남은 선행 조건:</b> 사용자의 물리 장치 선택과 명시 동의, 독립 human voice-gain pack이다.</td></tr>
<tr><td>G7 external GATE · 최종 감사 정정</td><td><code>run-g7-external-proof-window.py</code><code>check-g7-external-proof.py</code></td><td><b>상태는 external GATE 유지.</b> runner 프로세스 exit는 canonical checker <code>exit 0</code>·<code>gate_closed=true</code>에 결속되고, browser Origin과 API transport host는 별도 allowlist로 검증된다. 세 artifact 교집합은 <code>≥3000s</code> + 120초 margin이고 Windows proof는 detached-clean HEAD/tree·tool SHA·<code>psutil==6.1.1</code>을 pin한다. 직접 물리 soak를 실행해도 production 기본·최소 3,120초를 강제하고 3,000초 요청은 장치를 열기 전에 차단한다. clean-source 배포와 무마이크 rehearsal은 완료했다. 남은 것은 물리 마이크 3,120초, 동시 runtime/topology, 독립 human pack을 합친 4-artifact 실증뿐이다.</td></tr>
<tr><td>G8 DONE · clean-head NAS 기준선</td><td><code>vignette-preview-20260807</code> · <code>run-outcome-os-release-agent.py</code></td><td><b>상태는 DONE.</b> active archive <code>4d15d055…119d4d</code>, source HEAD/tree <code>61a41d1f…6af</code>/<code>87dec55d…3b77</code>, API/Web <code>d5021950…e4b1</code>/<code>9796c092…4b36</code> exact running. candidate 112/112와 actual NAS-origin 112/112, health ok·db/engine true·auth 401·OpenAPI 126을 통과했다. fresh dump <code>36ec8748…24db8</code> 1,097,100 bytes, TOC 1,738 / TABLE DATA 129와 previous active <code>6030a677…c611</code>을 보존했다. release agent의 DB restore 비소유·image/Compose/active-state rollback 경계는 유지한다.</td></tr>
<tr><td>G8 증거 DONE · current NAS DEGRADED</td><td><code>vignette-preview-20260807</code> · <code>run-outcome-os-release-agent.py</code></td><td><b>배포·rollback 증거는 DONE, 현재 runtime은 재검증 중.</b> active archive <code>4d15d055…119d4d</code>, source HEAD/tree <code>61a41d1f…6af</code>/<code>87dec55d…3b77</code>, API/Web <code>d5021950…e4b1</code>/<code>9796c092…4b36</code> 기준선은 보존한다. candidate 112/112와 actual NAS-origin 112/112, 당시 health ok·db/engine true·auth 401·OpenAPI 126을 통과했다. 2026-08-12 현재는 engine relay listener 부재로 health degraded·db true·engine false다. fresh dump <code>36ec8748…24db8</code> 1,097,100 bytes, TOC 1,738 / TABLE DATA 129와 previous active <code>6030a677…c611</code>을 보존했다. release agent의 DB restore 비소유·image/Compose/active-state rollback 경계는 유지한다.</td></tr>
<tr><td>노트북 로컬 음성 스택 — faster-whisper STT + MeloTTS TTS</td><td><code>scripts/local-whisper-stt-server.py</code> · <code>scripts/start-local-whisper-stt.ps1</code> · <code>voice_stt_provider=local_whisper</code></td><td>2026-08-08 소유자 결정으로 음성 양쪽을 노트북 상주 로컬 모델로 정했다. TTS는 처음 Higgs로 잡았으나 연구/비상업 라이선스라 <code>config.py</code>가 운영에서 차단하고 있었고 그 가드를 푸는 건 법적 판단이라, 상업 사용이 허용된 <b>MeloTTS Korean(MIT)</b>으로 바꿔 가드 자체를 불필요하게 만들었다. Kokoro-82M은 Apache 2.0이지만 공식 <code>VOICES.md</code><b>한국어가 없어</b> 탈락했다. local Whisper는 현재 호스트의 cuDNN 부재를 반영해 <code>small/cpu-int8</code>를 운영 기본으로 고정했고, API health도 MeloTTS model을 실제 provider와 맞춰 보고한다. 합성 시드 8.72초에서 interim 9·final 5·word timestamp 12개, 한 글자 차이 전사를 확인했고 MeloTTS CPU RTF는 0.27~0.28, 합성음→local STT 왕복은 완전 일치했다. current 통합은 launcher/sidecar 80/80·G7 전체 166/166·API voice 71/71·API 전체 921·gateway 58을 통과했다. Higgs 운영 사용은 라이선스 가드가 남아 dev 전용이다.</td></tr>
<tr><td>비-secure origin 회기 리뷰 크래시 수정</td><td><code>apps/web/src/lib/uuid.ts</code> · <code>apps/web/src/lib/sha256.ts</code> · <code>apps/web/e2e/insecure-context-uuid.spec.ts</code></td><td>격리 NAS 프리뷰(평문 HTTP·비-localhost)에서 드러난 <code>crypto.randomUUID</code><code>crypto.subtle.digest</code> secure-context 의존을 portable fallback으로 교체했다. source-only UUID/SHA 회귀 12/12와 secure/insecure exact digest 회귀를 통과했고, 최종 archive <code>4d15d055…119d4d</code>의 actual NAS-origin 112/112로 배포 검증까지 닫았다.</td></tr>
<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>