G7 평가 입력 안내 보강

This commit is contained in:
Yun Chan 2026-08-10 02:55:21 +09:00
parent 3067b72526
commit 190ae70d4d
4 changed files with 52 additions and 7 deletions

View file

@ -304,7 +304,7 @@
<p class="pulse-state"><b>현재:</b> G8·공개 앱·주기 실회기 전체 GREEN. <b>다음:</b> 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>b34623f3…</code>·tree <code>32cc85c7…</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>9f8d1941…a21bf</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시간 이상 오래됐거나 material milestone이 바뀔 때만 full runner를 최대 1회 실행한다. 마이크를 열지 않은 G7 rehearsal은 인증 WSS·runtime·Windows topology 세 leg 7-sample로 통과했다. 다음 외부 gate는 실제 mic·동시 high-water·human evidence다.</p>
<p class="pulse-state">G8 clean-head NAS-origin은 candidate 112/112·실제 origin 112/112로 DONE이다. 공개 API는 detached-clean <code>b34623f3…</code>·tree <code>32cc85c7…</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>9f8d1941…a21bf</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">2026-08-07 공개 DB는 recovered named volume으로 전환했고 원본 container·dump·volume을 보존했다. 2026-08-09 public DB incident 뒤 fresh custom dump <code>f1fd569c…5f64</code>를 만들고, 누락된 forward migration 14만 단일 트랜잭션으로 적용해 runtime schema 8/8을 복구했다. 공개 API·cloudflared는 clean release <code>b34623f3…</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>9f8d1941…a21bf</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>
@ -929,7 +929,7 @@
</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">clean 공개 runtime·인증 WSS 무마이크 rehearsal까지 닫았고, 동의 마이크·사람 평가 증거를 기다린다.</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를 연결했다. 운영 기본 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>b34623f3…</code>·tree <code>32cc85c7…</code>로 fresh 승격돼 OpenAPI 126·<code>/admin/voice-runtime</code>·<code>local_whisper/small</code>·<code>melotts/melotts-korean</code>·WS queue 4를 제공한다. receipt <code>9f8d1941…a21bf</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을 며 관련 계약은 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>
<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>b34623f3…</code>·tree <code>32cc85c7…</code>로 fresh 승격돼 OpenAPI 126·<code>/admin/voice-runtime</code>·<code>local_whisper/small</code>·<code>melotts/melotts-korean</code>·WS queue 4를 제공한다. receipt <code>9f8d1941…a21bf</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>
@ -1162,7 +1162,7 @@
<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시간 이상 오래됐거나 material milestone이 바뀔 때만 full runner를 최대 1회 실행하고 실패 시 자동 재시도하지 않는다. 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건을 분리한다. 자동화는 공개/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>b34623f3…</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한다. 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>

View file

@ -84,6 +84,8 @@ runtime/topology interval 기본값은 child collector 상한과 같은 60초이
artifact SHA와 비식별 participant/labeler/observation 수치를 채운 뒤 `--compile`하면 ICC·categorical κ와 production
floor·gain·CI를 행에서 다시 계산한다. 모든 gate가 통과한 경우에만 기존 파일을 덮어쓰지 않고 최종 pack을 원자 생성한다.
이름·이메일·원음·축어록·자유서술 열은 받지 않으며 콘솔에도 입력 경로·키·라벨·잘못된 셀 값을 출력하지 않는다.
생성된 `README.md`는 사전등록 시각, key/split 규칙, status-score 조합, label taxonomy, production floor와 실제 compile/check
순서를 한 파일에서 설명하므로 독립 평가팀이 Python 소스를 읽지 않고도 입력을 준비할 수 있다.
```powershell
& $py -X utf8 -B scripts/prepare-g7-human-voice-gain-intake.py --create-template <intake-dir>

View file

@ -524,10 +524,42 @@ def create_template(directory: Path) -> None:
csv.writer(handle, lineterminator="\n").writerow(fields)
(directory / README_NAME).write_text(
"# G7 human voice-gain intake\n\n"
"이 디렉터리는 빈 입력 틀이지 증거가 아니다. `manifest.json`의 모든 provenance를 "
"실제 외부 연구 산출물 SHA-256으로 채우고 `template_only`를 `false`로 바꿔라. "
"CSV에는 비식별 키와 수치만 넣고 이름, 이메일, 원음, 축어록, 자유서술을 넣지 마라. "
"각 held-out 회기는 goal/task/bond 3축과 동일한 blind labeler panel을 가져야 한다.\n",
"## 이 폴더의 상태\n\n"
"이 디렉터리는 빈 입력 틀이지 증거가 아니다. 이름, 이메일, 원음, 축어록, "
"자유서술을 넣지 마라. 최종 pack도 임상 효과를 주장할 수 없다.\n\n"
"## 작성 순서\n\n"
"1. held-out 라벨을 열기 전에 protocol, consent, split, labeling, analysis plan을 "
"사전등록하고 각 산출물의 SHA-256을 고정한다.\n"
"2. `manifest.json`의 provenance, 두 모델 identity, reliability report를 실제 값으로 "
"채우고 `template_only`를 `false`로 바꾼다. `registered_at`은 "
"`held_out_labels_opened_at`보다 빨라야 한다.\n"
"3. 아래 CSV 계약에 맞춰 비식별 키와 수치만 입력한다.\n"
"4. compile 명령으로 production gate를 다시 계산한다. 성공한 경우에만 최종 pack이 "
"원자적으로 생성된다.\n"
"5. standalone checker로 최종 pack을 한 번 더 검증한 뒤 G7 runner에 전달한다.\n\n"
"## CSV 계약\n\n"
"- `participants.csv`: `split`은 `calibration` 또는 `held_out`이다. key는 각각 "
"`calibration-` 또는 `held-`로 시작하고 consent receipt SHA-256은 참가자마다 고유해야 한다.\n"
"- `labelers.csv`: 최소 2명의 독립 평가자를 선언한다. 세 blind/independent 열은 모두 "
"소문자 `true`여야 하고 attestation SHA-256을 넣는다.\n"
"- `observations.csv`: `axis`는 `goal`, `task`, `bond` 중 하나다. 각 held-out 회기는 "
"세 축을 모두 가져야 하며 모든 행에 동일한 blind labeler panel을 사용한다.\n"
"- prediction `status`는 `observed`, `missing`, `error` 중 하나다. `observed`일 때만 "
"0 이상 1 이하 score를 쓰고, `missing` 또는 `error`면 score 셀을 비운다.\n"
"- `label_score`는 0 이상 1 이하이고 `label_category`는 labeling protocol에 "
"사전 정의한 동일 taxonomy의 ASCII token을 사용한다.\n\n"
"## Production gate\n\n"
"최소 calibration 참가자 1명, held-out 참가자 30명, 완전 paired held-out 회기 50개, "
"paired 축 150개, blind labeler 2명이 필요하다. compiler는 ICC(A,1) 0.75 이상, "
"categorical kappa 0.70 이상, paired gain 0.01 이상, participant-cluster bootstrap "
"10,000회의 95% CI lower가 0보다 큰지 행에서 다시 계산한다. 한 조건이라도 결측이면 "
"양 조건을 최대오류로 처리해 gain 부풀림을 막는다.\n\n"
"## 실행\n\n"
"```powershell\n"
"python -X utf8 -B scripts/prepare-g7-human-voice-gain-intake.py "
"--compile <intake-dir> --out <pack.json>\n"
"python -X utf8 -B scripts/check-g7-human-voice-gain.py --input <pack.json>\n"
"```\n",
encoding="utf-8",
newline="\n",
)

View file

@ -151,6 +151,17 @@ class G7HumanVoiceGainIntakeTests(unittest.TestCase):
)
self.assertIs(True, manifest["template_only"])
self.assertFalse(json.loads(output.getvalue())["template_is_evidence"])
readme = (target / MODULE.README_NAME).read_text(encoding="utf-8")
for required_guidance in (
"## 작성 순서",
"`registered_at`은 `held_out_labels_opened_at`보다 빨라야 한다",
"`observed`, `missing`, `error`",
"ICC(A,1) 0.75 이상",
"categorical kappa 0.70 이상",
"bootstrap 10,000회",
"--compile <intake-dir> --out <pack.json>",
):
self.assertIn(required_guidance, readme)
report, pack = MODULE.compile_intake(target)
self.assertIsNone(pack)