G0~G8 성과·동맹 측정 OS 작업 일괄 고정

8월 7일까지 워킹트리에만 남아 있던 미커밋 작업을 커밋한다. 여러 사본
폴더(worktree·clone)에 흩어져 있던 중간 스냅샷을 정리하기 전에 원본을
git 이력으로 고정하는 것이 목적이다.

- contracts/routes/services: measurement, outcome_trajectory, rupture_repair,
  deliberate_practice, calibration_transfer, supervision_research,
  multimodal_alliance, continuous_improvement 계열 신규 모듈과 테스트
- infra/db/init: 07~16 마이그레이션(측정 기반~calibration transfer 실행)
- apps/web: 세션 리뷰 카드·관리 화면·E2E 스펙 추가
- docs/ops: G0~G8 라이브 통합·배포·롤백 증거 문서와 evidence JSON/PNG
- scripts: smoke·ledger·릴리스 에이전트·NAS 프리뷰 운영 스크립트

engine.public 로그 .bak과 apps/web/test-results 산출물은 커밋에서 제외했다.
This commit is contained in:
Yun Chan 2026-08-08 01:30:53 +09:00
parent 93dd8f82d7
commit 16e791e044
390 changed files with 243188 additions and 499 deletions

View file

@ -0,0 +1,95 @@
# Outcome & Alliance OS 공개 배포 증거 — 2026-08-07
## 판정
G8 Continuous Improvement와 AOS-011 public/deploy proof는 실제 공개 API·정적 자산·인증 경계·watchdog에서 종료 조건을 통과했다. G7은 공개 WSS transport까지만 확인됐으며, 명시적 사용자 동의가 필요한 물리 마이크와 인증 회기의 50분 장시간 실측이 없어 종료하지 않는다.
## 배포 입력과 사전 게이트
- base commit: `76d0b9ae9bb11b62af86ccd9a55e798bbedc9e31`
- 최초 공개 승격에 사용한 release-only patch: SHA-256 `d9ac3c85c219640d14f74e705f766e6e1728464b0e32cc59e13acf8a45934d41`, 229 files, 3,350,569 bytes
- clean worktree: `D:\workspace\vignette-outcome-release-20260807`
- manifest 분류: dirty 257, Outcome 관련 235, mixed 4, 보존 제외 18, 미분류 0
- direct-runtime preflight: 필수 환경키 통과, `current_user=vignette`, non-owner app role
- 내부 ingestion token 6개: 독립 난수값을 운영 API 환경에 주입했으며 값은 로그·문서·프로세스 인자에 출력하지 않았다.
- 생성 API 타입은 clean worktree에서 공식 생성기로 다시 만들었고 선언된 SHA-256 `ba813bb5a16ab4a66e9e167213885ba66a334b1ddd8f945d462c2692d8077af3`과 일치했다. Windows checkout의 CRLF 차이는 공식 재생성 후 제거했다.
## clean release 검증
| 게이트 | 결과 |
|---|---|
| G0~G8 backend focused | 362 passed, 기존 경고 1건 |
| release/secret/G7 guard unit | 21 passed |
| Ruff | passed |
| TypeScript + API contract + production build | passed |
| 회기·학생 자기주도·G1/G4/G5/G7/G8 desktop/mobile | 126 passed, 의도적 mobile-only 제외 2 |
| layout visual gate | 15/15 passed |
| release manifest | dirty 전건 1회 분류, mixed fail-closed, patch SHA binding passed |
## 공개 API 증거
2026-08-07 03:07~03:13 KST에 production API 8001을 clean worktree의 `app.main:app`으로 교체했다.
- `https://api-vignette.chanpaca.net/health`: `status=ok`, `environment=prod`, `db=true`, `engine=true`, `engine_mode=claude_cli`
- 공개 OpenAPI: 69 paths에서 119 paths로 증가
- G1 `/sessions/{session_id}/alliance-pulses`: 존재
- G2 `/sessions/{session_id}/outcome-trajectory`: 존재
- G3 `/sessions/{session_id}/ruptures`: 존재
- G4 `/practice/learners/me`: 존재
- G5 `/calibration/learners/me`: 존재
- G6 `/supervision-research/supervision-view`: 존재
- G7 `/sessions/{session_id}/multimodal-alliance`: 존재
- G8 `/continuous-improvement`: 존재
- 인증 기준선 `GET /sessions`: 401
- G8 human route `GET /continuous-improvement`: 401이며 404가 아님
- Google OAuth `GET /auth/login?provider=google&next=/learn`: 302, Google location, state cookie 존재
## 공개 Web 증거
- Cloudflare Pages production deployment: `3d53dc4b-2cd5-4422-805c-7c6e8a95d1a2`
- immutable preview: `https://3d53dc4b.vignette-b1q.pages.dev`
- custom domain: `https://vignette.chanpaca.net`
- 두 주소 모두 200이며 entry asset은 `/assets/index-C3MqrpyJ.js`, `/assets/index-BbmNnVmr.css`
- Codex in-app browser에서 custom domain이 `/login`으로 렌더되고 Vignette 제품명과 학교 Google 로그인 CTA가 보이는 것을 확인했다.
## 운영 지속성
`VignettePublicRuntimeWatchdog`를 clean worktree의 `scripts/watch-public-runtime.ps1`과 5분 반복으로 재등록했다. 설치 직후 `Ready`, `LastTaskResult=0`이며 action·working directory 모두 `D:\workspace\vignette-outcome-release-20260807`을 가리킨다. 실제 재부팅 복구 smoke는 별도 B2 게이트로 유지한다.
## G7 voice hardening 재배포 — 04:31~04:38 KST
최초 공개 승격 기록은 위의 `d9ac3c...` 입력과 배포 증거로 보존한다. 후속 G7 voice hardening은
base commit은 유지한 채 release-only patch SHA-256
`3197805058e39a709897d3408f01f166f693791d400ea20e76d2e599d30002bc`
(235 files, 3,534,013 bytes)를 `D:\workspace\vignette-outcome-g7-release-20260807`에 적용해 배포했다.
배포 뒤 증거 문서와 dashboard를 포함해 다시 만드는 patch는 별도의 post-evidence 검증 산출물이며,
그 새 SHA를 이 시점의 실제 배포 입력으로 확대하지 않는다.
- clean backend 전체: `770 passed`, 기존 Starlette 경고 1건
- Web: API contract check, TypeScript typecheck, production build 통과
- production API 8001: PID `46732`, CWD `D:\workspace\vignette-outcome-g7-release-20260807\apps\api`
- local/public health: `environment=prod`, `db=true`, `engine=true`, `engine_mode=claude_cli`
- local/public voice health: STT `openai / gpt-4o-transcribe`, batch fallback available, TTS `openai / gpt-4o-mini-tts`
- 공개 OpenAPI 119 paths, 미인증 `GET /sessions` 401, Google OAuth 302 + state cookie
- 공개 `wss://api-vignette.chanpaca.net/voice/ws`: error `not authenticated` 뒤 close code `1008`
- Pages production deployment: `6d7e89d5-a98c-4118-a0a4-fde77e1cc7c8`
- immutable preview: `https://6d7e89d5.vignette-b1q.pages.dev`
- immutable/custom entry: `/assets/index-DZZoYvZq.js`, Session JS `/assets/Session-CHuKU2Sg.js`, Session CSS `/assets/Session-DPMJ7ZSw.css`
- 두 도메인에서 JS/CSS MIME 200과 Session 청크의 AI 생성 음성 고지 문구를 확인했다.
- 최근 production 5세대의 JS/CSS 의존 그래프를 병합해 이전 자산 103개를 보존한 뒤 새 파일 30개를 업로드했다.
- watchdog action·working directory를 새 clean worktree로 재등록하고 실행 직후 `Ready`, `LastTaskResult=0`을 확인했다.
- 검증용 API 8015는 PID·CWD를 대조한 뒤 종료했고 production 8001과 다른 로컬 런타임은 건드리지 않았다.
현재 운영에는 Deepgram 자격증명이 주입되지 않아 STT가 OpenAI batch provider를 선택한다. 따라서 이번
재배포는 Deepgram live interim/final, authenticated public `ready`, 물리 마이크 또는 50분 양방향 soak의
증거가 아니며 G7 상태를 `DONE`으로 바꾸지 않는다.
## G7의 남은 외부 게이트와 안전 사건
공개 TLS 1.3/WSS handshake와 비인증 `1008 not authenticated` 차단은 확인했지만 authenticated ready·양방향 50분 soak는 실행하지 않았다. 실행기는 `--confirm-physical-capture` 없이는 마이크 캡처 함수 전에 exit 3으로 차단하며 비밀값·session ID·축어록·응답·원음을 증거에 기록하지 않는다.
안전장치 추가 전 G533 물리 마이크가 명시적 사용자 동의 없이 3초씩 두 번 열렸다. 신호는 약 -90 dBFS로 사실상 무음이었고 원음·축어록은 보존하지 않았으며 즉시 추가 캡처를 중단했다. 이 실행은 G7 증거로 인정하지 않는다. 상세 감사 기록은 `ops/evidence/g7-external-voice-gate-audit-2026-08-07.json`이다.
## 최종 경계
이 증거로 G8과 AOS-011을 닫는다. AOS-012는 이 문서와 `dev_dashboard.html`, `TODO.md`, 현행 백로그를 동기화한 뒤 dashboard/release checker가 green일 때 닫는다. G7은 물리 마이크 사용에 대한 사용자의 명시적 동의와 인증된 공개 50분 실측 전까지 `BUILD`로 유지한다.