G7 증명과 G8 clean-head 승격 준비

This commit is contained in:
Yun Chan 2026-08-09 18:22:03 +09:00
parent 94c681d450
commit 5221f79e3f
52 changed files with 6876 additions and 506 deletions

View file

@ -2,7 +2,7 @@
## 판정
G7은 계속 **BUILD**다. 이번 변경은 물리 마이크나 운영 Deepgram을 사용한 실증이 아니라,
G7은 **내부 구현 DONE · external GATE**다. 이번 변경은 물리 마이크나 운영 provider를 사용한 실증이 아니라,
외부 증거가 들어왔을 때 synthetic·preflight·짧은 probe로 잘못 닫히지 않도록 종료 게이트를
실행 가능한 네 artifact 계약으로 만든 것이다.
@ -23,9 +23,10 @@ G7은 계속 **BUILD**다. 이번 변경은 물리 마이크나 운영 Deepgram
- Linux topology sampler는 exact Compose project/service, container ID, image digest, init PID,
start/restart, cgroup path를 매 sample 전후 재검증한다. cgroup v2, `/proc`, parsed Docker stats,
endpoint를 폐기한 host TCP queue/retransmit의 50분 high-water를 만들 수 있다.
- 누적 high-water를 이번 실행의 부하로 오인하지 않도록 API worker와 대상 container는 증거 시작
120초 이내에 새로 시작된 동일 인스턴스여야 한다. checker가 시작 시각, PID/container ID와
네 artifact의 겹치는 시간창을 함께 묶어 이 조건을 fail-closed로 검증한다.
- 누적 high-water를 이번 실행의 부하로 오인하지 않도록 Linux Compose API/container는 증거 시작
120초 이내의 동일 인스턴스여야 한다. Windows host mode는 detached-clean commit/tree, runner/collector/checker
SHA, `psutil==6.1.1`, 새 API/cloudflared PID/start/exe·command SHA/실제 cwd를 매 sample 전후 검증한다.
checker는 voice/runtime/topology 세 artifact의 **공통 시간창이 3,000초 이상**인지 재계산한다.
- 독립 human-labeled held-out voice-gain 계약은 raw audio·transcript·synthetic pack을 거부하고,
사전등록·동의·participant split·model artifact·blind independent labeler provenance를 요구한다.
production gate는 30명/50회기/150 paired axis, ICC(A,1) 0.75, 선택적 κ 0.70, gain 0.01,
@ -37,8 +38,9 @@ G7은 계속 **BUILD**다. 이번 변경은 물리 마이크나 운영 Deepgram
## 검증
- API voice/G7 focused: `92 passed`.
- external evidence runners/checkers와 release gate contract: `31 passed`; Ruff와 `py_compile` 통과.
- API 전체 `921 passed`, gateway `58 passed`, API voice 통합 `71 passed`.
- runner/checker/topology `86 passed`, public launcher/sidecar `80 passed`, G7 통합 `166 passed`;
Ruff·`py_compile`·PowerShell 5.1 parser·`git diff --check` 통과.
- Web typecheck와 API type contract 통과.
- `voice-success.spec.ts` chromium single-run `2/2` 통과. 동의 원장 응답을 의도적으로 지연한
동안 `getUserMedia=0`, voice WebSocket `0`을 확인했고, 성공 뒤 각각 정확히 1회였다.
@ -51,7 +53,8 @@ G7은 계속 **BUILD**다. 이번 변경은 물리 마이크나 운영 Deepgram
## 실제 종료 때 필요한 네 artifact
1. `soak-public-voice-websocket.py` v4의 운영 Deepgram/OpenAI TTS·authenticated public WSS·
1. `soak-public-voice-websocket.py` v4의 운영 기본값 `local_whisper`/`melotts`와 정확히 일치하는 ready metadata,
authenticated public WSS·
명시 동의 물리 마이크 50분 양방향 `passed` evidence.
2. 같은 시간창에 `capture-g7-runtime-evidence.py`로 얻은 관리자 endpoint worker/Uvicorn queue
high-water evidence.
@ -65,7 +68,7 @@ DONE으로 표시하지 않는다.
## 실행 오케스트레이터 (2026-08-08 추가)
앞의 1~3번은 **같은 public host의 겹치는 시간창**이어야 하는데, 지금까지는 운영자가 세 명령을 따로
앞의 1~3번은 **같은 public transport host의 공통 3,000초 시간창**이어야 하는데, 지금까지는 운영자가 세 명령을 따로
띄우고 시계를 손으로 맞춰야 했다. 50분짜리 실행에서 한 번 어긋나면 처음부터 다시 해야 한다.
`scripts/run-g7-external-proof-window.py`가 세 캡처를 **동시에** 시작하고, 전부 끝나면 human pack을
더해 checker까지 그대로 돌린다.
@ -74,22 +77,30 @@ DONE으로 표시하지 않는다.
# 실제 실행 (물리 마이크 50분 + 사람 pack 필요)
& $py -X utf8 -B scripts/run-g7-external-proof-window.py `
--wss-url wss://api-vignette.chanpaca.net/voice/ws `
--origin https://api-vignette.chanpaca.net `
--origin https://vignette.chanpaca.net `
--admin-runtime-url https://api-vignette.chanpaca.net/admin/voice-runtime `
--compose-project <project> --api-container <c> --api-image-digest sha256:... `
--caddy-container <c> --caddy-image-digest sha256:... `
--topology-mode windows-host --repo-root <detached-clean-root> `
--git-sha <commit> --git-tree-sha <tree> `
--runner-script-sha256 <sha> --collector-script-sha256 <sha> `
--checker-script-sha256 <sha> --psutil-version 6.1.1 `
--api-pid <pid> --api-executable-name python.exe --api-executable-sha256 <sha> `
--api-cwd <root\apps\api> --api-listen-port 8001 `
--cloudflared-pid <pid> --cloudflared-executable-name cloudflared.exe `
--cloudflared-executable-sha256 <sha> --cloudflared-cwd <root> `
--microphone-device "<장치명>" --confirm-physical-capture `
--duration-seconds 3120 `
--human-voice-gain <pack.json> --out-dir <증거디렉터리>
```
게이트를 **약화시키지 않는다.** CLI로 실증한 fail-closed 경계 네 가지:
게이트를 **약화시키지 않는다.** CLI로 실증한 주요 fail-closed 경계:
| 시도 | 결과 |
|---|---|
| 동의·장치 없이 운영 실행 | `physical_microphone_consent_required`, exit 2 |
| human pack 없이 운영 실행 | `human_voice_gain_pack_required`, exit 2 |
| 50분 미만 시간창 | `production_window_too_short`, exit 2 |
| 세 캡처의 host 불일치 | `hosts_must_match:[...]`, exit 2 |
| 3,120초 미만 시간창 | `production_window_too_short`, exit 2 |
| transport host/scheme 불일치 | `hosts_must_match` 또는 scheme 오류, exit 2 |
| 허용되지 않은 browser Origin | query/원문을 반사하지 않는 Origin 오류, exit 2 |
`--rehearse`는 마이크·사람 없이 **배관만** 확인하는 모드다. soak을 `--preflight-only`로 돌려 장치를
열지 않고, 인자·경로·산출 파일까지 실제로 검증한다. 보고서의 `gate_closed`는 rehearse에서 **항상
@ -122,5 +133,6 @@ has /admin/voice-runtime → False
2. `--rehearse`로 배관을 확인한다.
3. 동의 하 물리 마이크 50분 + human pack으로 실제 실행한다.
기대 provider 기본값은 2026-08-08 결정에 맞춰 `local_whisper` / `melotts`
(근거: `../decisions/local-voice-stack.md`). 회귀는 `scripts/test_run_g7_external_proof_window.py` 20/20.
기대 provider 기본값은 2026-08-08 결정에 맞춰 `local_whisper/small` / `melotts/melotts-korean`이다
(근거: `../decisions/local-voice-stack.md`). runner 회귀는 37/37, G7 통합은 166/166이다. production exit 0은
`checker_returncode == 0 && gate_closed is true`에 결속되며 rehearse는 성공해도 gate를 닫지 않는다.