vignette/docs/TODO.md
Yun Chan 2624d49984 설치형 로컬 TTS를 MeloTTS 한국어(MIT)로 채택하고 엔드포인트로 연결
Higgs Audio v3 는 연구/비상업 라이선스라 config.py 가 environment != dev 에서
차단하고 있었다. 그 가드를 푸는 건 법적 판단이라 코드로 결정할 수 없어서,
상업 사용이 허용된 설치형을 다시 찾아 MeloTTS Korean 으로 바꿨다. 결과적으로
가드를 건드릴 필요 자체가 사라졌다 — Higgs 가드는 그대로 두고 provider 만
melotts 로 두면 운영에서도 동작한다.

검토 결과:
- MeloTTS   MIT       한국어 지원  -> 채택. CPU 실시간, 사전학습 다화자
- Kokoro-82M Apache2.0 한국어 없음  -> 탈락. 공식 VOICES.md 언어 목록에 부재
- Piper      GPL                   -> 탈락
- XTTS-v2 / Fish Speech 비상업      -> 탈락. Higgs 와 같은 문제

사전학습 다화자 모델이라 실존 인물 reference 를 쓰지 않는다. Higgs 경로가
P1 프리셋 한정이던 이유가 없으므로 모든 페르소나 프리셋에 적용된다.

구현:
- scripts/melotts-server.py  loopback HTTP 사이드카(/health, POST /tts -> WAV)
- voice_tts_provider=melotts 경로와 VIGNETTE_MELOTTS_TTS_* 설정
- scripts/start-melotts.ps1  런처(설치 순서 안내 포함)

실측:
- CPU 정상 상태 RTF 0.27~0.28(실시간 3.6배). 첫 실행 13.25 는 모델 다운로드
- POST /tts 200, WAV 350,566 bytes, 3.61s, 헤더 provider/model/license
- 빈 텍스트 422, 미지 경로 404 로 fail-closed
- 왕복 검증: MeloTTS 합성음을 로컬 faster-whisper 가 완전 일치 전사
  "그렇게 느끼셨군요. 조금 더 이야기해 주실 수 있을까요?" (word timestamp 8개)

설치 함정 3가지를 decisions/local-voice-stack.md 에 남겼다.
librosa 0.9.1 의 pkg_resources(setuptools<81), MeloTTS 가 언어와 무관하게
임포트하는 일본어 unidic 사전, Windows 한국어 g2p 의 eunjeon.

G7 게이트의 TTS 허용목록에 melotts 를 추가했다. 선언/실제 불일치 차단과
배치 STT 배제는 그대로다.

검증: API 914 passed, 사이드카 melotts 16/16 + whisper 37/37, SSOT FAIL 0, ruff clean.
2026-08-08 09:29:57 +09:00

468 lines
47 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Vignette 할 일 (안된 것들) — 통합 TODO
> **한 곳에서 보는 "남은 작업" 인덱스.** 여러 문서에 흩어져 있던 열린 작업을 주제별로 모았다.
> **권위 기준은 SSOT `dev_dashboard.html`**, 열린 게이트 추적은 `ops/backlog-2026-06-26.md`(얇은 현행본)다.
> 이 파일은 그 둘을 **집계·링크**하는 뷰이며, 상태가 어긋나면 대시보드를 기준으로 맞춘다.
> 완료된 작업 기록은 `archive/`(냉동 보관)에 있고 평상시 읽지 않는다.
>
> 태그: **[환경]** 이 워크스테이션에서 증거 생산 불가 · **[외부]** 기관/소유자 서면·결정 필요 ·
> **[구현]** 코드로 진행 가능 · **[임상]** 임상팀(구훈정·어유경) 외부 콘텐츠 소유.
---
## A. 배포·공개 런타임 게이트 [환경]
> 출처: `ops/backlog-2026-06-26.md` B2 · 대시보드 운영 탭 · `ops/tailscale-vnet-runtime-2026-06-27.md` · `ops/public-runtime-watchdog.md` · `HANDOFF.md`
- [ ] **공개 DB 계정·회기 복구 안정화** — 2026-08-07 18:26 KST owner 승인으로 recovered named volume을
공개 `vignette-dev-db:55432`에 전환했다. public 기준 users 84/sessions 30/turns 705,
Google 계정 16/소유 회기 30, orphan 0, health·engine·OAuth·watchdog가 정상이다. 전환 직전 container와
dump, 원본 volume을 보존한다. 남은 것은 사용자가 Google 재로그인한 뒤 본인 과거 회기가 보이는지
확인하는 일과 자동 백업 운영화다. 기존 인증 세션은 복사하지 않아 재로그인이 필요하다.
상세: `ops/public-db-recovery-rehearsal-2026-08-07.md`.
- [ ] **자동 DB 백업·정기 복원 리허설**`scripts/backup-vignette-db.ps1`의 custom dump→TOC 검증→
SHA manifest 원자 게시와 현재 public-target 일회용 복원(129 tables/9,646 rows/orphan 0)을 통과했다.
남은 범위는 예약 실행, 실패 알림, NAS/off-host 암호화 복제, 주기적 restore drill과 보존 정책이다.
- [ ] **공개 Google OAuth 실제 `/turn` proof** — 로그인 계정으로 `storageState` 캡처 → `E2E_PUBLIC_AUTH=1` +
`chromium-public-auth` 1회 통과. 실행 명령은 대시보드 "다음 실행 명령"/`HANDOFF.md`. (소유자 보류 중)
- [ ] **Compose 패키징용 `infra/.env` owner-secret** — 현재 운영 direct-runtime은 독립 G3~G8 token 주입,
non-owner app-role preflight와 공개 health를 통과했다. Compose로 전환할 때만 `APP_DB_PASSWORD` 등 패키징
비밀과 prod-safe engine/voice flags를 별도 주입하고 compose profile preflight를 다시 통과한다.
- [ ] **`vnet.18ka.net`/`api-vnet.18ka.net` 공개 live** — DNS A record 등록, cloudflared의 `18ka.net` zone 권한,
Google redirect URI `https://api-vnet.18ka.net/auth/callback` 등록. (현재 prod API 8001은 health OK)
- [x] **비-secure origin에서 회기 리뷰 크래시 수정** — 2026-08-07 격리 NAS 프리뷰
`http://100.116.83.60:8088`(평문 HTTP·비-localhost)에서 회기 리뷰 라우트가
`crypto.randomUUID is not a function`으로 error boundary에 잡혔다. `crypto.randomUUID`는 secure
context에서만 노출되는데 제품 코드 18곳이 fallback 없이 직접 호출했고, 특히
`RuptureRepairCard.tsx`는 렌더 시점(`useRef`)에 호출해 화면 전체가 죽었다. 릴리스 게이트는
localhost 후보 스택(secure context)에서만 돌아 이 경로를 밟은 적이 없다. `src/lib/uuid.ts`
`randomUuid()`로 통일했고 fallback도 `crypto.getRandomValues`를 우선 사용해 idempotency key의
예측 불가능성을 유지한다. 회귀는 `e2e/insecure-context-uuid.spec.ts` 6/6으로 고정했다(직접 호출
0건 검사 포함). **주의: 이 수정은 아직 NAS 프리뷰에 배포되지 않았다** — 배포된 SHA
`6030a677…c611`은 여전히 결함이 있는 빌드다.
- [x] **워치독 engine readiness 사각지대** — 2026-08-07 22:0x KST 소유자 승인으로 9099 재기동과
판정 기준 교정을 모두 마쳤다. 복구 실측: 9099 `/ready?force=true` 200 `ok:true, detail:OK`,
API 8001과 공개 `api-vignette.chanpaca.net` 모두 `status:ok, engine:true, engine_detail:OK`.
원인은 16:06부터 상주하던 9099 **프로세스 하나**였다. 같은 인자로 `claude -p`를 직접 실행하고
`EngineSession`을 그대로 재현하면 양쪽 다 `"OK"`를 반환해 CLI·코드·cwd는 무관함을 확인했다
(별도 포트 9199 실험과 동일 결론).
재발 방지 3건:
(1) `scripts/watch-public-runtime.ps1`·`scripts/start-public-runtime.ps1`의 engine 판정을
`/health`(프로세스 liveness) → `/ready`(실제 생성)로 바꾸고, API 판정에 `engine`을 추가했다.
shared secret 인스턴스를 401로 오판하지 않도록 `X-Vignette-Engine-Token` 헤더를 붙이고,
503 응답 **본문**을 로그 detail에 남긴다.
(2) `engine_gateway/gateway.py`가 자식 `claude -p`의 stderr를 상시 드레인해(PIPE를 아무도 읽지
않으면 자식이 블록되는 문제도 함께 차단) 실패 detail에 `exit`·stderr를 붙인다. 실증:
`empty engine response (error: unknown option '--vignette-nonexistent-flag-xyz')`.
`str()`이 비는 `TimeoutError` 등에는 타입명을 최소 보장한다.
(3) 기동 시 게이트웨이 로그 회전, `Stop-UvicornByPort``Name -like python*` 조건 추가
(명령 문자열만 매칭해 호출자 자신을 죽이는 사고 방지).
검증: `pytest engine_gateway` 58/58, 워치독 `-CheckOnly` healthy 5/5, 장애 재현(9299를
`CLAUDE_BIN` 부재로 기동)에서 `/health``ok:true`로 통과하고 `/ready`는 503으로 검출되어
워치독이 `unhealthy (1/3)` + 503 본문을 남겼다.
남은 것: NAS용 9100은 실사용 세션 7개가 있어 미접촉이라 (2)는 다음 재기동 때 반영된다.
- [ ] **재부팅 후 watchdog smoke** — 실제 Windows 재부팅 후 엔진/API/터널 자동 복구 + public `/turn` 실측.
DNS 개통 후 `api-vnet.18ka.net``-AdditionalPublicHealthUrls`로 명시 추가.
- [x] **노트북 로컬 음성 스택 STT 구현** — 2026-08-08 소유자 결정으로 음성 양쪽을 노트북 상주
로컬 모델로 쓴다(STT faster-whisper, TTS는 아래 항목대로 MeloTTS). 이전에는 코드에 로컬 STT 경로가 아예 없었고
(`voice_stt_provider``openai|deepgram` 둘뿐), interim/final 스트리밍 구현도 Deepgram 전용이었다.
`scripts/local-whisper-stt-server.py` 사이드카(Higgs와 같은 loopback 상주 방식)와
`voice_stt_provider=local_whisper` 경로를 추가했다. 오디오는 호스트를 벗어나지 않고 외부 STT 키가
필요 없다. 실측: 저장소 합성 시드 음성 8.72초로 interim 9 · final 5 · word timestamp 12개 전부 present,
전사는 원문과 한 글자(`안녕하세요``안녕하세여`) 차이였다. 회귀 `scripts/test_local_whisper_stt_server.py`
37/37, `apps/api/app/test_voice_service.py` 로컬 provider 케이스 포함 API 전체 908 passed.
**발견 1:** 이 노트북은 CUDA 장치는 보이지만 cuDNN(`cudnn_ops64_9.dll`)이 없어 GPU 추론이 **네이티브
크래시**로 죽는다. 같은 프로세스 try/except로는 못 잡아서 디바이스 확인을 버릴 수 있는 자식 프로세스
(`--self-check`)로 분리하고 `auto`에서 CPU로 폴백하게 했다. cuDNN 9를 설치하면 GPU(float16)로 훨씬
빨라지며 `large-v3`도 실시간권에 들어온다 — 설치는 소유자 판단 사항이라 하지 않았다.
**발견 2:** G7 종료 체커가 `expected_stt_provider == "deepgram"`을 하드코딩하고 있었다. 이는 결정
기록이 아니라 벤더 한 줄이었으므로, 운영하기로 한 provider 허용목록으로 바꿨다
(`ALLOWED_STT_PROVIDERS`/`ALLOWED_TTS_PROVIDERS`). 선언/실제 불일치 차단은 그대로 유지한다.
- [x] **노트북 로컬 음성 스택 TTS 구현 (MeloTTS)** — Higgs는 연구/비상업 라이선스라 `config.py`
운영에서 차단하고 있었고, 그 가드를 푸는 건 법적 판단이라 코드로 결정할 수 없었다. 그래서 상업 사용이
허용된 설치형을 다시 찾아 **MeloTTS Korean(MIT)** 으로 바꿨다. 가드를 건드릴 필요가 사라졌다.
`scripts/melotts-server.py` loopback 사이드카 + `voice_tts_provider=melotts` 경로를 추가했고,
사전학습 다화자 모델이라 Higgs처럼 P1 프리셋 한정이 아니라 모든 페르소나에 적용된다.
**실측:** CPU 정상 상태 RTF 0.27~0.28(실시간의 3.6배), `POST /tts` 200·WAV 350,566 bytes·3.61s,
빈 텍스트 422·미지 경로 404. **왕복 검증**으로 MeloTTS 합성음을 faster-whisper가 완전 일치 전사했다.
회귀 사이드카 16/16, API 전체 914 passed, ruff clean.
**검토 후 탈락:** Kokoro-82M은 Apache 2.0이지만 공식 `VOICES.md`**한국어가 없다**(검색 요약이
지원한다고 했으나 오답). Piper는 GPL, XTTS-v2·Fish Speech는 비상업이라 Higgs와 같은 문제다.
설치 함정 3가지는 `decisions/local-voice-stack.md`에 남겼다(setuptools<81, unidic download, eunjeon).
근거: [`decisions/local-voice-stack.md`](./decisions/local-voice-stack.md).
- [ ] **음성 캐스케이드 live** Deepgram streaming adapter와 interim/final·word timestamp, bounded event queue,
운영 10MiB 사전 거부와 실제 PostgreSQL 동시 철회 직렬화는 코드/내부 회귀까지 완료했다. 종료에는 운영
key·quota를 사용한 live interim/final, 기대 provider/model과 일치하는 authenticated public WSS ready,
명시 동의 물리 마이크, 50분 양방향 장시간 실측과 실제 worker/proxy의 RSS·queue high-water가 모두 필요하다.
> **완료된 격리 검증 경로:** NAS 프리뷰 `http://100.116.83.60:8088`을 전용 Compose 프로젝트·포트·네트워크·볼륨에 배포하고 실제 브라우저 회기와 review API 저장 축어록을 확인했다. current source exact SHA `6030a677af7e87cbfabc422b553d108d53414fd3c446548734a13b036d35c611`은 전체 browser E2E 108/108, postdeploy SSE→DB review, health 3/3, OpenAPI 126·auth 401·G0~G8 route를 통과했다. 기존 프로젝트를 대상으로 한 중단·재생성 명령은 실행하지 않았다. 매일 04:30 KST `Vignette 회기 E2E 정기 검증`(automation id `vignette-e2e`)은 ACTIVE다. 새 기능이 material milestone이고 release-only patch 결정성·manifest checker·canonical clean-index·NAS preflight를 통과하며 배포 SHA가 달라질 때만 같은 격리 프리뷰를 갱신한다. 첫 스케줄 실행 이력은 아직 증거에 포함하지 않았다. 증거: [배포 증거](./ops/nas-preview-deployment-evidence-2026-08-07.md), [current 기계 판독 증거](./ops/evidence/nas-preview-current-deploy-2026-08-07.json), [브라우저 증거](./ops/evidence/nas-preview-live-turn-2026-08-07.png). 이는 G8 실제 receipt-bound rollback이나 미승인 물리 마이크·부재한 Deepgram 운영 키를 대체하지 않는다.
- [ ] **claude_cli ↔ Anthropic API live 동일성** provider 라우팅·모델 탐색·설정 저장 경로는 구현 완료. 남은 게이트는 연구팀/기관 `ANTHROPIC_API_KEY` 게이트웨이 호스트에 주입한 같은 프롬프트의 live 응답·계량·오류 표면화를 비교하는 것이다.
## B. 외부 거버넌스 [외부]
> 출처: 백로그 B4 · `ops/hanshin-data-governance-gate.md` · `ops/source-docs-gap-analysis-2026-06-26.md` · `MASTERPLAN.md`
- [ ] **한신대 데이터/SSO 거버넌스 서면 증거** 공식 문의서 발송·서면 응답 수령, 동의범위 매트릭스, SSO claim map,
privacy review, 미성년 원본 활용동의, 개인정보 처리방침. 로컬 골격은 `ops/hanshin-data-governance-gate.md`.
- [ ] **L1 스택 정합성·저작권 등재 문서 반영** 신청서/등재 문서에 FastAPI 유지 사유 + 계약 우선 Node 전환 계획 반영.
결정 기록: `decisions/backend-node-transition.md`.
## C. Phase 3 교육용 파일럿 [외부] + [구현 scaffold 완료]
> 출처: 백로그 Phase3 · `phase3/*` · 대시보드 P3 탭. 문서·checker·exporter scaffold는 준비됨.
- [ ] **20명 파일럿 운영** roster, consent 법무승인(G-P3-02), session completion evidence 수집.
- [ ] **효과성/KPI 측정** SUS·자기효능감·κ0.70/ICC0.75·환각률3%. 3척도 pre/post 실측 `kpi_report.json`.
- [ ] **재귀학습 데이터셋 approved 산출** `approved_for_recursive_learning_seed`(consent/PII/IAA/legal 승인) + 승인 export 실행.
- [ ] **개인정보/동의 감사 서명** `phase3/privacy-consent-audit.md` 서명 완료, withdrawal_log 종결.
## D. 소유자 결정 완료(2026-06-30) → 구현 후속 [구현]
> 출처: 대시보드 "윤찬 결정 상세" 탭 · `decisions/` · 백로그 B3. 결정 자체는 전건 확정, 아래는 후속 build.
- [ ] **s2s 2차 비교 PoC 구현·실측** `decisions/voice-s2s-poc.md` 기준표(전사·안전·감사·지연) 20턴 비교 리포트 최종 채택/폐기.
- [ ] **fast-loop 외부 폴백 구현** 로컬 상주 분류기 우선 + Haiku/Solar 폴백, 전송 가드(데이터주권·로그·동의관측.
- [x] **운영 TTS provider 선정·통합** 운영 경로는 OpenAI API `gpt-4o-mini-tts` 고정했다. OpenAI
Services Agreement의 고객 애플리케이션·최종 사용자 통합권과 출력 소유 조항을 근거로 기록하고, 공식 TTS
가이드가 요구하는 AI 생성 음성·사람 음성 아님 고지를 회기 시작 전과 진행 UI에 상시 노출한다. 로컬
Higgs와 sample provider는 무참조 synthetic seed를 쓰는 개발 전용 경로로 계속 분리한다.
- [ ] **재귀학습 fine-tuning 파이프라인** 동의/데이터셋 게이트 충족 . few-shot 자동갱신은 선행 가능.
- [ ] **헬스 retention 적용·검증** raw 90일 / rollup 365일. escalation/그룹 자동화는 미도입 고정.
- [x] **한신대 실사용 피드백 1차 개선팩** `ops/hanshin-feedback-improvement-plan-2026-07-03.md`,
`redteam/hanshin-feedback-plan-redteam-2026-07-03.md`, `redteam/hanshin-feedback-plan-counter-redteam-2026-07-03.md`
기준 P0~P4 1차 완료. 완료 범위: role mapping + client-only stateless history injection, review UI 표시 자연어화,
raw error display mapper, fast/deep 라벨, 명백한 출력 결함 차단, SSE full-response buffer, 교수자 설명 패널.
검증 수치는 SSOT 대시보드만 소유한다. partial stream, client 전용 resident session, fast-loop 사후 저장은
구현 완료했다. 남은 후속은 저장형 fallback/synthetic 계약, fast/deep reconciliation,
임상팀 루브릭/CBT/약물·평가 문구 확정.
## D-2. 전수 E2E 순회 소유자 결정 — **전건 결정 완료(2026-07-27)** → 구현 후속 [구현]
> 출처: `ops/e2e-full-sweep-2026-07-27.md` 발견 결함 로그 · `ops/backlog-2026-06-26.md` B3-신규.
> 결함 12건은 RED→GREEN으로 수정 완료(대시보드 143차). 소유자 결정 7건은 질문 도구로 전건 확정.
- [x] **설정 아바타 변경 UI 구현** REDGREEN 완료(full-sweep-settings 4/4, 무회귀 44/44)
- [x] **동의 철회 전체 흐름 구현** 설정 동의 섹션+철회 2단계 확인+재동의, API round-trip GREEN
- [x] **신규 학습자 기초 우선 추천 구현** `starterPersona()` 난도 오름차순, 무회귀 42/42
- [x] **학생 분석 테이블 가상화 구현** @tanstack/react-virtual, 300행 REDGREEN, 무회귀 40/40+게이트 4/4
- [x] **저작 모드 좌측 레일 마크업 정리** 레일 JSX·CSS 삭제, dead-code 게이트 통과
- [x] dev-login 재로그인 자동 재승인 결정: 현행 유지(코드 변경 없음, 종결)
- [x] **감정 밸런스 타임라인 차트 구현** deep `turn_valence`+결정론 파생 폴백, 백엔드 421/421, 라이브 5pt 실측
> 전체 검증 수치·상세는 SSOT 대시보드 144차 노트와 `ops/e2e-full-sweep-2026-07-27.md`가 소유한다.
## E. 코드 품질·리팩터 로드맵 [구현] (비게이트 — 여유 시)
> 출처: `ops/code-quality-research-2026-06-26.md` · `decisions/backend-node-transition.md` next candidates.
> **2026-07-02 실측**: 로드맵 상당수는 이미 해결(turn_runtime·tier 제거·eval_hook 주입 등). 아래는 코드 재확인 기준 현행 상태.
- [x] **Stage enum SSOT 통합** `taxonomy.Stage` 라벨 단일 정의(SoT), `services.state_machine` re-export(중복 `class Stage` 제거). **검증: 단일 enum 정체성 확인, 백엔드 pytest 352 passed, 수집 379 import 무결. (2026-07-02)**
- [x] **store `recent_turns`/`masked_turns` Type-2 중복 제거** `recent_turns = masked_turns()[-k:]` 위임으로 단일 소유. **검증: 백엔드 352 passed. (2026-07-02)**
- [x] **화자 한글 라벨 4× 중복 → `taxonomy.speaker_ko_label` 단일 헬퍼** evaluator/live_coach/memory 프롬프트의 `'상담자'/'내담자'` 삼항 통합. **검증: 헬퍼 단위 + 백엔드 352 passed. (2026-07-02)**
- [x] ~~턴 파이프라인 dedup~~ `turn_runtime.py` `load_owned_session`/`record_completed_turn` 이미 추출됨.
- [x] ~~`_iso` 중복 통합~~ teacher/sessions `_iso` 중복 해소됨(현재 `_iso_text`/`_iso_dt` 별개 목적 함수).
- [x] ~~tier dead-contract 제거~~ · ~~voice 경로 eval_hook 미주입~~ gateway tier 제거 + voice eval_hook 주입 완료.
- [x] **Speaker/Role 계약 레벨 — 검토 결과 조치 불요** DB actor 매핑은 1곳(`session_persistence.py`, 중복 아님), `Role` appdb는 이미 단일 dict(`DB_ROLE_BY_APP`/`APP_ROLE_BY_DB`), 엔진 `AIRole` 이미 단일 `Literal`. 실제 중복이던 표시 라벨은 위에서 통합됨 별도 추상화 불요. (2026-07-02 실측)
- [x] **`_list_sessions` N+1 제거(1차: state/turns)** 세션별 `session_state`/`turns` fetch 루프(1+2N) `= ANY($ids)` 배치 3쿼리 + Python 그룹핑. **검증: 실 DB 동등성 50세션/109턴 불일치 0, 왕복 101→3, 백엔드 352 passed(회귀 테스트 mock 시퀀스 갱신). (2026-07-02)**
- [x] **`_list_sessions` N+1 제거(2차: 턴평가 하이드레이션)** 상세 뷰에서 세션별 evaluator 연결+평가 로드 루프 세션 turn_refs 배치(`_hydrate_sessions_turn_evaluations`, 연결 1회). 싱글 헬퍼는 플러럴 위임으로 행위 보존(`_load_turn_evaluations` 이미 `turn_id = ANY` 배치). **검증: 백엔드 352 passed. (2026-07-02)**
- **E2E 검증( 스택)**: dev API(8000, 코드 반영)++DB에서 `chromium-single-run` **2 passed** "위기교수자 대시보드", "학습자 리뷰+교수자 대시보드"(`list_all_sessions` include_turn_evaluation=True로 1·2차 N+1 경로 모두 브라우저 end-to-end). (2026-07-02)
- [ ] fast-loop `eval_hook` **사용 정책 제품 결정** (현재 주입은 ; 켤지/끌지 확정은 소유자).
- [ ] Node 게이트웨이 구현 시: 라이브 엔드포인트 conformance, `TurnEvaluationPayload` 어댑터 추출, `admin.py` 매퍼 정리.
- [ ] init SQL과 별도의 idempotent DB migration runner 도입 (인프라 추가 소유자 결정 권장).
## F. 임상팀 콘텐츠 [임상] (외부 소유)
> 출처: `ops/source-docs-gap-analysis-2026-06-26.md` · 백로그 B0. 코드 구조는 선제 구축, 문안·기준은 외부 정의.
- [ ] **태깅 축어록 4종 후속 게이트** `ops/tagged-data-utilization-2026-07-15.md` §3 소유:
golden set P8~P11, 다회기 스키마 격상, gestalt/dbt 이론모드 신설(소유자 결정), P1~P7 보강,
사례개념화 루브릭 draft, P8~P11 초안 검수·승인(특히 P9 자해 페르소나는 안전장치 실측 선행).
- [ ] C1 사례개념화 **확정 루브릭 콘텐츠** + AI 추출/채점 calibration (현재 scaffold_only).
- [ ] CBT 체인·이론부합 루브릭.
- [ ] 위기개입 프로토콜 임상 문안.
- [ ] 평가 골든셋 콘텐츠.
## G. 운영 후속 [구현] (비차단)
> 출처: 백로그 B1
- [ ] **운영 티켓 자동 분류·처리** Claude Recipe headless 자동 수정 후보, 관리자 승인 이슈 등록·PR/작업 스레드 생성,
처리 결과 audit trail 확장. 자동 수정은 운영자 승인 전까지 실행하지 않는다.
## H. 2026-07-13 한신대 회의 결정 구현 [구현] (파일럿 게이트 — 7월 내)
> 출처: `ops/hanshin-meeting-actions-2026-07-13.md` (요구사항 상세·완료기준은 그 문서가 소유).
> 데드라인: **7월 내 배포 → 7월 말~8월 초 파일럿(대학원생 ~20명)**. 9~10월 연구팀 점진 이관.
- [x] **P1. 회기 종료 시간 기반 전환** 구현 완료(2026-07-14). 60분 시간 기반(`SESSION_DURATION_MINUTES`) +
10분 알람 + 시간 만료 정리 유도 다이얼로그 + 유예(+10분) 서버 409 거부 + 시작 목표 1~4개
선택(`goal_stages` 계약, DDL·런타임 가드 포함 회의 권장 2개 수준, 소유자 지시 2026-07-15로 4개까지 허용).
목표 달성해도 시간 계속 진행. 상태머신은 채점·표시용 유지.
**검증**: 백엔드 pytest 393 pass, 1분 회기 실측(알람만료 다이얼로그409), session-layout 8/8, layout-visual-gate 12/12.
- [x] **P2. 회기 계획·달성도 게이지** 구현 완료(2026-07-14). 설계 1p `ops/session-progress-gauge-design-2026-07-14.md`.
단계별 누적 게이지(rapport_credit 파생, 회기 ×0.7 이월로 누적) + 상세 수치(방어/개방도/라포 누적+이번 회기 증가분)
세션 화면·상세 응답·스트림 done·대시보드 페르소나 카드(rapport_percent) 노출. 계획서·프로토콜 첨부는 기존
`/personas/sources`(+신규 엑셀 업로드) 흡수. **검증**: 2회기 carry 실측(65%→46% 시작 = ×0.7 정확).
- [~] **P3. 파일럿 인프라 대비** 부하 검증 완료: `scripts/load-test-sessions.py`, 20 동시 세션 생성 20/20 성공
(p95 125ms, RAG warm 병목 없음), 5 동시 실턴은 p50 55s로 **claude_cli 상주 풀이 병목** 파일럿
`ENGINE_MODE=claude_api` 전환 권고. 이관 절차 초안 `ops/server-migration-runbook-draft.md`, 파일럿 사용 지침
`ops/pilot-usage-guide-draft.md`. **남은 것**: 실제 서버 이관(연구팀·정보처 협의) 외부 대기.
- [x] **P4. 데이터 업로드 흐름 검증** 자유 양식 엑셀 업로드 경로가 없어서 신규 구축(2026-07-14):
`POST /personas/sources/upload`(xlsx/xlsm/csv 텍스트 결정론 변환 `services/tabular_ingest.py` 기존 마스킹·
hash-only 증거·sanitized chunk 경로 재사용, 원본 바이트 미저장) + PersonaStudio 파일 첨부 xlsx 지원.
**검증**: 파란 라벨 샘플 실업로드(NAME 마스킹·chunk 색인·임베딩 OK, raw hash-only 확인), 방어 테스트 9종
(.xls 거부·cp949 폴백·손상/ 파일) pass.
- [~] **P5. 협업 체계** 비개발자용 가이드 `guides/collaboration-for-researchers.md` 작성 완료(문구 수정 프로세스 포함).
**남은 것**: 저장소 초대(소유자 직접 실행).
- **외부 대기(구현 착수 금지)**: '실패(게임오버)' 정의 / 검수 표준화 항목 / AI 평가 노출 정책 / 페르소나 추가 제작 전부 연구팀 , 수신 반영.
## I. Outcome & Alliance OS — 정식 승격 로드맵 [에이전틱 구현]
> **2026-08-06 정식 승격.** 상세 계약·품질 목표·의존성은
> `ops/vignette-outcome-alliance-os-agentic-plan-2026-08-06.md`, 상태는 SSOT 대시보드의
> `Outcome & Alliance OS` G0~G8 계획 카드가 소유한다. 아래 작업은 사람 개발자 스프린트가 아니라
> 에이전트가 RED → 구현 → 통합 → 적대 검증 → runtime proof → SSOT 동기화로 닫는 증거 DAG다.
### I-0. G0 Measurement Truth Foundation
- [x] `app.measurement_event`, `app.measurement_instrument`, `audit.model_run` 계약과 provenance enum 구축.
- [x] 기존 `rapport_credit`, `alliance_level`, fast/deep 평가, Phase 3 KPI의 source map과 adapter 구축.
- [x] `simulated_state`·`model_inferred`·`agent_reported`·`learner_reported`·`human_rated`·
`observed_runtime` 층을 섞는 read model 실패 테스트 구축.
- [x] goal mismatch, task mismatch, empathic miss, withdrawal, confrontation, successful/failed repair를 포함한
benchmark pack 구축.
- [x] **G0 종료 GATE 재검증** post-merge dump의 disposable clone에 migrations 14/15/16을 각각
원자 재적용하고 current source census 29/29 producers, unknown/missing/null/orphan/호환성 위반 0을 확인했다.
증거: `ops/evidence/g0-provenance-census-scratch-post-g6-g8-20260807.json`.
### I-1. G1 Alliance Core
- [x] goal/task/bond의 내담자·관찰자·수련생 3관점 측정과 회기 ·· pulse 구현.
- [x] 현재 `alliance_level` legacy simulation signal로 격리하고 alliance read model 구축.
- [x] 학습자 리뷰의 관점 차이·근거 장면 UI 구현.
- [x] 교수자 재평가를 append-only measurement로 구현.
- [x] **G1 종료 GATE** 관점 독립 실행·저장, 축별 비가림 UI, 골든 장면 분류·근거 span,
평가 실패의 정상 점수 폴백 0건. **증거:** G1 focused backend 43 passed, PostgreSQL RLS/append-only/reveal
실원장 smoke, desktop/mobile Alliance Pulse 6/6 기존 회기 리뷰 12/12, prompt `1.2.0` 합성 gold 방향
정확도 9/9·최종 실패 0·근거 recall 88.9%. 실제 Session 진입 pre pulse를 fail-closed로 잠그고 라운드
mid pulse를 비차단형으로 연결했으며, stable ID 재시도·변조 409·교차 회기 404를 통과했다. desktop/mobile
pre·mid focused E2E 2/2와 시각 증거 4장을 보존했다. 추가 source API/dev DB 실증은 회기의
`pre(degraded/insufficient_transcript) → mid(ready) → post(ready)` 실제 turn UUID·ended_at과 함께 닫고,
동일 응답 안의 awaiting/external-event read skew와 degraded terminal DB 제약을 교정했다. 증거:
`ops/evidence/alliance-pulse-pre-mid-post-live-2026-08-07.json`. 현재 승격 기준 prompt 1.2+read-skew fix+
보수적 trailing-comma JSON 복구의 전체 재보정은 24/24 ready, 기대 방향 9/9, 오류·재시도 0,
evidence recall 94.4precision 73.9% 기록했다. human-AI ICC는 내부 구현 종료가 아니라 Phase 3 외부 품질 목표다.
### I-2. G2 Longitudinal Outcome Trajectory
- [x] 최소 5회기 사례 arc와 예상 성과 궤적 분포 구현.
- [x] safety event와 outcome deterioration의 별도 계약·표시 구현.
- [x] 초기 1~5회기 off-track 탐지와 다음 확인 질문 구현.
- [x] case memory에 관계 사건·합의·미해결 균열을 role-safe하게 추가.
- [x] **G2 종료 GATE** 5회기 기억·목표·관계 연속성, 악화 benchmark 조기경보 목표,
false alert·uncertainty 병기, 합성 궤적의 임상 결과 오표시 0건. **증거:** 4-case×5-session
benchmark status 정확도 1.0·false alert 0·critical miss 0, 실제 DB/API 5회기 연속 case와 15개 독립 ,
멱등 재시도·변조 409·학습자/코호트 RLS·role-safe 관계 기억 통과, desktop/mobile 체크인·궤적 12/12와
G1/기존 리뷰 15/15 회귀 통과. 추가 실제 PostgreSQL producerstoreevaluator smoke는 합성 교육용
악화 case의 `on_track→off_track→deteriorating` 단발성 noise control의
`on_track→watch→on_track`·false alert 승격 0건을 실제 10회기·30 measurement·case별 5 revision으로
검증했고 learner/teacher 최신 projection이 일치했다. 원점수는 증거 JSON에 복제하지 않았고 임상 주장은 금지한다.
### I-3. G3 Rupture & Repair Lab
- [x] rupture/repair 상태머신과 이벤트 원장 구현.
- [x] Scenario Director의 자연스러운 균열 주입 구현.
- [x] 실시간 감지, 회기 장면 재생, 복구 분기 비교 구현.
- [x] 후속 발화에서 복구된 fast-loop 경고의 deep-loop reconciliation 구현.
- [x] **G3 종료 GATE** 유형별 탐지·복구 benchmark, missed/partial/resolved E2E, 순응 유도 judge
gaming 0건, 문장 암기 전략의 변형 사례 실패 검증. **증거:** 11-case macro-F1 1.0·복구 상태
accuracy 1.0, critical miss/judge gaming/암기 false resolution 0, Scenario/G3 107 passed,
G0~G8 계약 251 passed, desktop/mobile 리뷰 50/50, 실제 API/DB durable-turn·멱등·RLS·교수자
append-only correction·최종 resolved 검증. 기존 수동 write smoke의 missedpartialresolved와 별도로,
실제 `submit_turn`/공용 finalizer callback만 사용한 자동 runtime PostgreSQL smoke에서 3 episode·10 observation·
3 reconciliation, 상태, learner/teacher read projection, 세션 evidence 참조 0건을 재현했다.
### I-4. G4 Deliberate Practice Engine
- [x] 평가 장면을 원자적 practice prescription으로 변환.
- [x] replay, branch, constrained response, voice retry, difficulty ladder 구현.
- [x] competency graph와 attempt evidence 저장.
- [x] 약한 역량과 망각 위험에 따른 다음 연습 자동 선택.
- [x] **G4 종료 GATE 재검증** 모든 코칭 카드의 실행 가능한 재연습 연결, 전후 비교·근거 저장,
미지 사례 mastery 금지, 점수 보상 해킹 benchmark 통과. **증거:** G4 core/store/API 54 passed,
실제 API/DB durable-turn 처방학습자 시도교수자 append-only correction, 멱등 retry/변조 409,
learner/cohort RLS, reward-claim `practicing`·`mastery_allowed=false`, G4 UI 8/8 G1~G4 리뷰 58/58.
replay/branch/constrained response/voice retry/difficulty ladder 카드 CTA가 학습자 사전 설정실제 Session으로
이어지고 launch intent가 URL과 화면에 유지되는 desktop/mobile 22/22 통합 59/59를 통과했다. 추가 실제
PostgreSQL production caller smoke는 ready 평가·durable turn 2개에서 G4 submission/card/prescription/snapshot/
decision 1개를 자동 생성하고 재실행 같은 deterministic submission/card replay, episode·attempt·mastery·
transfer 승격 0건을 확인했다. 실제 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, G4 POST·read-model reload·before/after·멱등 retry를 확인했고
최종 episode/attempt/ready observer 1, UUID 노출·마이크 호출·overflow·중복 0이다.
증거: `ops/evidence/scratch-browser-returned-practice-closed-loop-evidence-20260807.json`.
- [x] **학생 자기주도 전체 루프 UI 계약** 실제 `src` 학습 추천P1·목표 선택텍스트/SSE 회기
종료·리뷰G4 공감적 반영 처방키보드 CTA 회기 사전 설정·시작까지 desktop/mobile **2/2**,
typecheck와 고정 캡처 9장 시각 QA를 통과했다. CTA는 40px44px 4.5:1 이상 대비로 보정했고,
390×844·320×568 활성 회기의 아바타/문구 겹침 0·축어록/입력창 카드 내부 포함과 리뷰재연습의
내부 criterion/counterevidence/UUID/영문 이론키 비노출을 고정했다. 리뷰 1~5 척도는 320px에서
3+2 반응형 배열로 전환해 다섯 선택지 44px 이상·내부/페이지 overflow 0을 desktop/mobile 8/8로 고정했다. 검증은 모든
미소유 `/api/**` 404로 닫은 로그인 없는 route fixture이며 실제 API/DB 폐루프라고 주장하지 않는다.
상세: `docs/ops/outcome-os-self-directed-learning-loop-ui-evidence-2026-08-07.md`.
### I-5. G5 Calibration Mirror & Transfer
- [x] 외부평가 공개 자기평가 잠금 흐름 구현.
- [x] 역량별 calibration error와 신뢰도 구간 계산.
- [x] 과신·과소신 맞춤 메타인지 연습 자동 처방.
- [x] 인구통계·관계스타일·난이도를 바꾼 transfer suite 구현.
- [x] **G5 종료 GATE 재검증** 자기평가 오염 방지·수정 이력, 반복 연습의 calibration error 감소,
사례 역량 유지, subgroup 평가 드리프트 리포트. **증거:** 4-case expectation accuracy 1.0,
lock 오염 거부 1, calibration MAE 0.6670.267, unseen 4/4 전이, 암기 false verification 0,
합성 subgroup drift 0.667 탐지. 실제 API/DB durable-turn revisionlock독립 reveal·멱등/409·RLS,
G5 UI 4/4, G1~G5+기존 리뷰 62/62, typecheck/build 통과. transfer CTA는
`novelty=unseen_transfer`·suite·trial을 학습자 사전 설정실제 Session까지 보존하며 desktop/mobile
2/2와 실제 세션 통합 2/2를 통과했다. 추가 production caller DB smoke는 prediction lock observation
0건, lock callback `failed`·`model_inferred`·`independent_observer` 관찰과 turn/session provenance
model-run 1개를 확인했다. 재실행 중복 0, passed·assessment·transfer suite/trial/승격 0이며
learner/teacher projection이 일치한다. 학생 후속 종료 회기에서 actual-execution POST·422 대기·503 재시도·
성공 reload·멱등 재확인 UI와 내부 UUID 비노출은 desktop/mobile 16/16으로 연결했다. 실제 API/DB/엔진
smoke는 execution·model-inferred·independent observer·instrument/evidence/model-run provenance 1과
멱등·오류 출처·미종료·타학습자·교차 cohort 차단을 통과했다. 같은 post-merge disposable clone 브라우저는
desktop/mobile 4/4로 G5 POSTreloadbefore/after와 11 멱등 재확인을 통과했고 UUID 노출·마이크 호출·
중복 원장 0이다. 합성 교육 fixture이고 임상·실제 숙달 주장은 금지한다.
### I-6. G6 Supervision & Research OS
- [x] attention queue와 learner drilldown을 측정 원장 기반으로 재구축.
- [x] 교수자 정정·AI 불일치를 calibration dataset으로 연결.
- [x] cohort curriculum gap, model drift, instrument version 비교 구현.
- [x] Phase 3 evidence manifest에 alliance/rupture/transfer/calibration 추가.
- [x] **G6 종료 GATE 재검증** 위험·정체·미해결 관계 사건 3클릭 이내, 모든 집계의 원장 drilldown,
모델·척도 버전별 재현 리포트, public/teacher/learner 경계·감사 로그 검증. **증거:** 6-signal
queue 순서 정확·drilldown 1/상한3, metadata-only dataset raw transcript 0, version drift 탐지,
Phase3 도메인 전건. 실제 API/DB 멱등/409·AI-view·역할/cohort RLS·audit, version/subgroup/artifact
provenance hydrate 통과. 추가 scheduled producer는 G0~G5 실제 원장에서 attention/gap을 파생하고,
repo-approved synthetic baseline/candidate와 실제 measurement anchor 12개를 자동 비교해 batch 2·report 1·
subgroup 2를 저장했다. replay 중복 0, periodic 6 cohort 성공, drift/provenance hydrate, transcript 0·비임상
경계를 확인했다. G6 focused 37 passed, G6 UI desktop/mobile 6/6, typecheck/build 통과. 최신
safety-event metadata-only 우선 producer는 post-merge disposable clone의 current source에서 derive 201,
`safety_boundary(1) > deterioration(2)`, direct pointer 1, source detail canary 1·G6 projection canary 0,
raw transcript/임상 주장 0을 통과했다. NAS 승격은 배포 증거이지 internal 종료 조건과 분리한다. 상세:
`ops/outcome-os-g6-ledger-producer-evidence-2026-08-07.md`,
`ops/outcome-os-g6-version-comparison-producer-evidence-2026-08-07.md`,
`ops/evidence/g6-safety-priority-runtime-scratch-20260807.json`.
### I-7. G7 Multimodal Alliance
- [x] STT word timestamp, silence, overlap, interruption, prosody feature event 통합.
- [x] 텍스트·음성 평가 독립 산출 calibrated fusion 구현.
- [x] 장면별 오디오 재생과 음성 재연습 구현.
- [x] 비언어 특징의 과도한 임상 추론 차단 계약·테스트 구현.
- [x] Deepgram streaming STT adapter, interim/final·word timestamp·provider event 계약과 OpenAI batch fallback 구현.
- [x] 저장 word token을 deployment `SESSION_SECRET` 기반 HMAC-SHA256 pseudonym으로 전환하고 원문 미보존을 고정.
- [x] 열린 streaming 동의를 1초마다 재검사해 철회 provider 전송·후속 저장을 중단하는 fail-closed 계약 구현.
- [x] 음성 단절/실패 작성 텍스트를 보존하고 텍스트 계속하기·키보드 가능한 음성 재연결 recovery UX 구현.
- [x] 운영 TTS를 OpenAI API `gpt-4o-mini-tts` 고정하고 공식 Services Agreement의 통합·출력 소유 근거와
최종 사용자 AI 생성 음성 고지를 제품·증거 계약에 반영.
- [x] authenticated WSS `ready` STT/TTS provider·model을 노출하고, 마이크 열거·캡처 없는 public preflight가
기대값과의 정확 일치를 검사하도록 구현. full soak만 명시적 `--confirm-physical-capture` 장치를 연다.
- [x] synthetic gold target에 대해 text-only와 calibrated multimodal 출력을 직접 비교하는 1-MAE benchmark를
구현하고 `0.9533→0.9673`, 실측 gain `+0.014`(최소 `0.01`) gold 변조 반례를 통과했다.
- [x] consent mutation·timeline·measurement를 session 공통 PostgreSQL transaction lock으로 직렬화하고 실제
개발 DB 동시 철회에서 미커밋 writer 대기, 철회 커밋 저장 차단, timeline row `0` 확인했다.
- [x] 10MiB audio buffer를 append 전에 거부하고 streaming event queue `32`, Deepgram receive queue `16`
고정했다. 단일 프로세스 cap probe는 10MiB high-water·초과 거부·clear RSS 기준선 복귀를 확인했다.
- [x] 음성 사용은 처리 목적·전송/전사·파생 신호·30일 보존·원음 미보존·철회/삭제·텍스트 대안을 설명하고,
서버 동의 원장 성공 `getUserMedia` voice WebSocket을 모두 0회로 유지한다. 원장 실패와 지연 권한 응답도
마이크 track/소켓을 남기지 않으며 숨은 Space 대신 안내 가능한 `Alt+M` 사용한다.
- [x] process-local metadata-only `/admin/voice-runtime` Uvicorn `--ws-max-queue 4` 추가해 worker RSS/CPU/FD,
WebSocket·provider session·audio buffer·event queue·overflow/fallback/error high-water를 관측 가능하게 만들었다.
- [x] public WSS evidence v4의 turn별 interim/speech-final/latency 계약, 같은 worker를 고정하는 runtime sampler,
exact image/container/cgroup/proc/Docker/TCP topology sampler, 독립 blind human-held-out voice-gain 계약과
artifact를 같은 public host·동시 시간창으로 묶는 `check-g7-external-proof.py` 구현했다.
- [x] G7 내부 hardening exact SHA `a8c27b0aadcb9dacea86c4be5e62e19277b9cc2678ebca51aa02998d2c2d1a0d`
격리 NAS에 승격했다. clean candidate session E2E 24/24, OpenAPI 124, auth 401, G0~G8와 실제 NAS
browser SSEDB review를 통과했고 물리 마이크는 사용하지 않았다.
- [ ] **G7 종료 GATE** 오디오·자막·측정 이벤트 시간 정렬, 물리 마이크·공개 WSS 장시간 E2E,
텍스트 단독 대비 음성 이득 benchmark, 음성 보존·삭제·동의 정책 검증. **내부 완료:** 실제 API/DB
동의단일 시계독립 측정/융합철회·삭제, actual-Postgres 동시 철회, synthetic gold gain benchmark,
bounded queue/10MiB cap RSS probe, Deepgram adapter, HMAC word pseudonym, 1초 동의 재검사, 선행 동의 원장,
recovery UX, mic-free expected-provider/model preflight와 외부 증거용 artifact checker를 확인했다. 최신
격리 synthetic PCM soak는 59/59 연결 종료·성공 발화 55·철회 차단 2·미동의 차단 1·overflow 거부/복구 1/1,
focused 119 passed를 통과했다. 공개 G7 route는 TLS 1.3 handshake·비인증 1008·Cloudflare edge와 마이크
열거/캡처 0을 확인했다. 증거: `ops/evidence/g7-public-wss-preflight-current-20260807.json`.
**남음:** 실제 Deepgram 운영 key·quota와 live interim/final, 기대값과 일치하는 authenticated public WSS ready,
사용자의 명시 동의를 받은 물리 마이크, 실행된 50분 양방향 soak, 독립 라벨 held-out/pilot의 실제 음성 이득,
실제 worker·Uvicorn·OS·Cloudflare edge를 같은 50분 시간창으로 묶은 RSS/CPU/queue high-water.
preflight·synthetic·옵션 제공만으로 종료하지 않는다.
### I-8. G8 Autonomous Content & Continuous Improvement
- [x] source pack 기반 사례·균열·연습·benchmark 초안 자동 생성.
- [x] 안전·정체성·난이도·정답 누수·문화적 편향 독립 적대 검토.
- [x] 승인된 콘텐츠만 catalog 승격하고 provenance 보존.
- [x] metadata-only 운영 incident를 승인 source로 변환해 adversarial benchmark pipeline을 실행.
- [x] repo-approved synthetic source를 durable lease/retry job으로 등록하고 API lifespan에서 opt-in 주기 실행.
- [x] 운영 측정의 약한 benchmark·drift를 주기적으로 탐색해 incidentadversarial 경로를 자동 기동.
- [x] 실제 Claude pending payload를 사람 검수하고 승인된 projection만 catalog에 01로 소비하는
관리자 browser/API/DB E2E. learner/teacher 403·replay 멱등·변조 409·민감 payload 비노출.
- [x] release agent의 결정적 patch·manifest·clean candidate·API/Web/회기 gate, 격리 NAS 승격,
semantic runtime/browser proof, 이미지 rollback, exact-SHA SSOT handoff를 fail-closed로 구현·독립 감사.
- [x] release agent로 변경 SHA `e9b482ccba616a610c1f4862366d44aabae20ee8c82d8ef7f2cf16069f2d6e99`
실제 격리 NAS에 승격하고 postdeploy browser·DB review·rollback snapshot·exact-SHA SSOT handoff를 남겼다.
- [x] **G8 종료 GATE 재검증** sourcedraftred-teambenchmarkcatalog 재현, 정답 누수·PII·무근거
임상 주장 0건, 모델 교체 자동 calibration/rollback, 운영 오류의 재현 테스트·backlog DAG 자동 환류.
**현재 코드 증거:** caller가 완성 JSON을 넣는 기존 경계와 별도로 source hash·PII fail-closedstructured
generator서로 결과를 공유하지 않는 red-team 2개variant generator독립 judge 3개 이상durable
`draft_payload`·`pending_human_approval` 저장 worker/API를 추가했다. 모델/structured output 실패, PII,
answer leakage, 무근거 claim, reward hacking은 store 호출 차단하고 같은 submission은 model call 0으로
재생한다. repo-approved source의 durable lease/retry scheduler를 lifespan에 opt-in 연결했고 실제
`claude_cli/claude-opus-4-8` 7 callsdev PostgreSQL reviewer 2·variant 3·pass rate 1.0
`pending_human_approval` 동일 UUID 0-call replay를 확인했다. full API/gateway 858 passed,
Ruff·OpenAPI type check·web typecheck 통과. G6 canonical 임계값·subgroup 원장을 재검증하는 default-off
drift trigger는 DB incident 1·DAG 4·job 1·approval/catalog 0과 동시성·멱등을 통과했다. 기존 실제
Claude pending payload는 모델 호출 0회로 관리자 browser에서 catalog 01·approval 1, 역할 403·
replay 멱등·변조 409를 통과했다. release agent는 독립 감사 4건 수정 14/14와 전체 API 891 passed를
통과했다. exact SHA의 NAS runtime은 health·OpenAPI 123·auth 401·G0~G8와 browser SSEDB review를
통과했고 transient 502 rollback/recovery와 최종 readiness 3회째 성공을 기록했다. 상세:
`ops/outcome-os-g8-agentic-worker-evidence-2026-08-07.md`. 현재 소스의 HTTP control-plane executor는
artifact SHA·idempotency key·receipt/evidence가 일치할 때만 `executed` 허용하고 미구성은 `requested`,
호출/receipt 실패는 `failed` 남긴다.
**2026-08-07 종료:** 격리 NAS `vignette-preview-20260807`에서 실제 receipt-bound image rollback을
실행했다. 별도 executor helper(`127.0.0.1:18149`, host network·read-only rootfs·cap-drop ALL·
no-new-privileges·uid1028/gid100·group101) 별도 lifecycle의 control-plane API(`127.0.0.1:8018`,
producer disabled, preview DB `172.22.0.2` `vignette_app` role) 띄우고, `rollback-old` plan은 receipt
`nas-g8-723eeef22eab05e63e3fafb0`으로 previous 이미지 `79ec…4450`/`c530…2f28`, `restore-current` plan은
receipt `nas-g8-2738846cf2cf4fbe8ce0fc26`으로 current 이미지 `52e0…8b2d`/`6fdb…f215` 활성화했다.
release gate·approval 각각 2회 멱등, `audit.ci_lifecycle_event` `rollback/executed` 2건과 receipt id 결속,
`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 격리는 image가
상속하는 `com.docker.compose.*` label을 baseline으로 두고 project/service만 격리 override하는 계약으로
검증했다(`scripts/launch-nas-preview-g8-helpers.py`, fake-runner 37/37). 계획했던 Windows SSH 터널은 NAS
sshd가 `administratively prohibited` 거부해 sshd 설정 변경 대신 같은 격리 계약의 NAS-side probe
컨테이너로 실행했고 control-plane/preview origin 분리는 유지했다. `down`/`volume rm`/`prune` 미실행,
공개 런타임 미접촉, 비밀 env 파기, helper 0·listener 0 복귀. 상세:
[런북](./ops/nas-preview-g8-rollback-proof-runbook.md) ·
[기계 판독 증거](./ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json).
- [x] current source exact SHA `6030a677…c611` 격리 NAS에 승격했다. release-only patch 3회 결정성,
전체 browser E2E 108/108, postdeploy SSEDB review 32.437s, health 3/3, OpenAPI 126·auth 401·G0~G8
route, named DB volume 보존을 확인했다. 이는 runtime promotion 증거이며 실제 rollback receipt와 구분한다.
### I-DAG. 첫 에이전트 실행팩 AOS-001~012
- [x] **AOS-001** 기존 지표 provenance inventory 선행 없음. 종료: 모든 현재 점수의 source map.
- [x] **AOS-002** `measurement_event` ADR/schema/DDL 선행 AOS-001. 종료: contract + rollback + RLS tests.
- [x] **AOS-003** benchmark case schema와 8개 장면 선행 AOS-001. 종료: deterministic fixtures.
- [x] **AOS-004** legacy rapport/alliance adapter 선행 AOS-002. 종료: 기존 데이터 무손실 read model.
- [x] **AOS-005** goal/task/bond 3관점 structured schema 선행 AOS-002/003. 종료: gold contract tests.
- [x] **AOS-006** session measurement API 선행 AOS-005. 종료: API/DB idempotency E2E.
- [x] **AOS-007** 학습자 self-assessment lock 선행 AOS-002. 종료: reveal-order E2E.
- [x] **AOS-008** Alliance Pulse 리뷰 UI 선행 AOS-006/007. 종료: desktop/mobile visual proof.
- [x] **AOS-009** 교수자 measurement drilldown 선행 AOS-006. 종료: role/RLS/audit E2E.
- [x] **AOS-010** measurement drift/calibration job 선행 AOS-003/005. 종료: version comparison report.
- [x] **AOS-011** public/deploy proof manifest 공개 API 119 paths, G1~G8 route, Pages asset, auth/OAuth proof.
- [x] **AOS-012** SSOT/TODO 동기화 dashboard/TODO/backlog/release manifest 동기화와 checker green.
---
## 지금 임계경로 (한 줄)
납품(공개 데모) 핵심 블로커는 **A(공개 `/turn` proof + 배포 secrets)**. 다음이 **B(한신대 거버넌스)**
**C(Phase 3 파일럿)** C는 2026-07-13 회의로 **7월 말~8월 초 파일럿 일정 확정**, 전제로 **H의 P1(회기 종료 시간 기반)**
구현 게이트다. **I(Outcome & Alliance OS) 현재 감사 기준 G0~G6이 internal DONE이다.
G8은 receipt-bound 실제 NAS rollback proof가 남았다. G7은 내부 구현 DONE과 외부 proof GATE를 분리하며,
Deepgram live·auth public WSS·명시 동의 mic·
50분 soak·독립 라벨 benchmark·운영 resource high-water가 남았다.** D~G는
품질·확장 작업으로 게이트가 아니다. 상세 상태·검증 증거는 SSOT 대시보드가 소유한다.