diff --git a/docs/dev_dashboard.html b/docs/dev_dashboard.html index 52cc004..711e493 100644 --- a/docs/dev_dashboard.html +++ b/docs/dev_dashboard.html @@ -304,7 +304,7 @@

현재: G8·공개 앱·주기 실회기 전체 GREEN. 다음: G7 명시 동의 mic·human pack·checker exit 0.

운영 복구·watchdog·배포 상세 보기 -

G8 clean-head NAS-origin은 candidate 112/112·실제 origin 112/112로 DONE이다. 공개 API는 detached-clean b34623f3…·tree 32cc85c7…에서 OpenAPI 126, /admin/voice-runtime, local_whisper/small + melotts/melotts-korean, WS queue 4를 제공하며 fresh provenance receipt 9f8d1941…a21bf가 passed다. 공개 Web은 Pages entry index-BrpoQ5nP.js와 review chunk SessionReview-E03q-dGb.js에서 literal [NAME] 0·시간 만료·모바일 44px/자동 스크롤 보정을 노출한다. 주기 실회기 7차는 clean aa81af29…에서 same-learner SSE→review→G4/G5 0→1→1과 별도 zero-state returned desktop/mobile 4/4, 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다.

+

G8 clean-head NAS-origin은 candidate 112/112·실제 origin 112/112로 DONE이다. 공개 API는 detached-clean b34623f3…·tree 32cc85c7…에서 OpenAPI 126, /admin/voice-runtime, local_whisper/small + melotts/melotts-korean, WS queue 4를 제공하며 fresh provenance receipt 9f8d1941…a21bf가 passed다. 공개 Web은 Pages entry index-BrpoQ5nP.js와 review chunk SessionReview-E03q-dGb.js에서 literal [NAME] 0·시간 만료·모바일 44px/자동 스크롤 보정을 노출한다. 주기 실회기 7차는 clean aa81af29…에서 same-learner SSE→review→G4/G5 0→1→1과 별도 zero-state returned desktop/mobile 4/4, 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다.

2026-08-07 공개 DB는 recovered named volume으로 전환했고 원본 container·dump·volume을 보존했다. 2026-08-09 public DB incident 뒤 fresh custom dump f1fd569c…5f64를 만들고, 누락된 forward migration 14만 단일 트랜잭션으로 적용해 runtime schema 8/8을 복구했다. 공개 API·cloudflared는 clean release b34623f3…로 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는 9f8d1941…a21bf, 무마이크 rehearsal evidence는 voice 61af2e98…·runtime c6e8670e…·topology 89f1cb86…이며 UUID/email literal 0이다. G7은 배포가 아니라 실제 mic·동시 high-water·human evidence만 남은 external GATE다.

@@ -929,7 +929,7 @@
-
내부 구현·공개 선행조건 DONE

consent→단일 clock→독립 text/voice/fusion→철회·tombstone, streaming interim/final·word timestamp·provider event, HMAC word pseudonym, 열린 stream의 1초 동의 재검사·abort, 텍스트 보존·음성 재연결 UX를 연결했다. 운영 기본 provider는 노트북 상주 local_whisper/melotts이고 외부 Deepgram/OpenAI adapter는 fallback으로 보존한다. 격리 synthetic PCM soak는 59/59를 통과했다. Windows host topology는 detached-clean commit/tree·도구 SHA·psutil version과 PID/start/exe·command SHA/cwd·process/TCP high-water를 fail-closed로 수집하고, 3,120초 capture의 공통 3,000초를 canonical exit와 결속한다. 공개 API/cloudflared는 clean b34623f3…·tree 32cc85c7…로 fresh 승격돼 OpenAPI 126·/admin/voice-runtime·local_whisper/small·melotts/melotts-korean·WS queue 4를 제공한다. receipt 9f8d1941…a21bf가 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다.

외부 종료 GATE

30초 무마이크 rehearsal은 authenticated public WSS ready/ping/close1000, runtime 7 samples, Windows topology 7 samples를 모두 통과했고 physical_capture=false·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은 check-g7-human-voice-gain.py를 먼저 통과해야 하며 부적합하면 마이크를 열기 전에 exit 2다. 네 artifact가 scripts/check-g7-external-proof.py exit 0을 만들기 전에는 메인 상태를 DONE으로 바꾸지 않는다.

+
내부 구현·공개 선행조건 DONE

consent→단일 clock→독립 text/voice/fusion→철회·tombstone, streaming interim/final·word timestamp·provider event, HMAC word pseudonym, 열린 stream의 1초 동의 재검사·abort, 텍스트 보존·음성 재연결 UX를 연결했다. 운영 기본 provider는 노트북 상주 local_whisper/melotts이고 외부 Deepgram/OpenAI adapter는 fallback으로 보존한다. 격리 synthetic PCM soak는 59/59를 통과했다. Windows host topology는 detached-clean commit/tree·도구 SHA·psutil version과 PID/start/exe·command SHA/cwd·process/TCP high-water를 fail-closed로 수집하고, 3,120초 capture의 공통 3,000초를 canonical exit와 결속한다. 공개 API/cloudflared는 clean b34623f3…·tree 32cc85c7…로 fresh 승격돼 OpenAPI 126·/admin/voice-runtime·local_whisper/small·melotts/melotts-korean·WS queue 4를 제공한다. receipt 9f8d1941…a21bf가 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다.

외부 종료 GATE

30초 무마이크 rehearsal은 authenticated public WSS ready/ping/close1000, runtime 7 samples, Windows topology 7 samples를 모두 통과했고 physical_capture=false·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은 check-g7-human-voice-gain.py를 먼저 통과해야 하며 부적합하면 마이크를 열기 전에 exit 2다. 네 artifact가 scripts/check-g7-external-proof.py exit 0을 만들기 전에는 메인 상태를 DONE으로 바꾸지 않는다.

@@ -1162,7 +1162,7 @@ Docker image smokedocker build -f apps/api/Dockerfile . / docker run ... python -c "import app.main" / docker build -f apps/web/Dockerfile apps/webAPI/Web image build and API import smoke pass after packaging cleanup. Web build uses npm lockfile and ignores host node_modules; API image excludes local .env files. Deploy preflightpython scripts\check-deploy-preflight.py --skip-db --env-file infra\.env.example --allow-placeholder-secrets / DB mode with local DATABASE_URLPassed: exact-pinned API requirements, live coaching data/kb source pack, env template keys, and DB readiness (current_user=vignette). DB mode can additionally check app-role DSN with --require-app-role and now verifies session read-model columns including app.turns voice metadata columns(audio_ref/silence_ms/speech_rate/barge_in/provider_events) plus worksheet review columns. Fresh compose smokedocker compose -p vignette-packaging-smoke -f infra/docker-compose.yml up -d --build + proxy /api/healthPassed with dummy production-safe env: API healthy, DB healthy, web/proxy up, http://localhost:18080/api/health 200 with db:true, engine:true, engine_mode:"claude_cli". Smoke volumes/network removed after run. - 격리 NAS 프리뷰 · 회기 E2E 자동화http://100.116.83.60:8088 / vignette-e2e 매시간 heartbeat / 배포 증거 / 기계 판독 증거current clean source HEAD 61a41d1f…6af·tree 87dec55d…3b77의 archive 4d15d055…119d4d를 전용 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 aa81af29…는 same-learner SSE·review·G4/G5 0→1→1과 별도 returned desktop/mobile 4/4, route mock 0, cleanup 0으로 첫 전체 GREEN을 만들었다. heartbeat는 최신 GREEN이 6시간 이상 오래됐거나 material milestone이 바뀔 때만 full runner를 최대 1회 실행하고 실패 시 자동 재시도하지 않는다. release gate·NAS preflight·배포 SHA 변경 때만 프리뷰를 갱신한다. G7 외부 mic/provider/human 증거는 별도다. + 격리 NAS 프리뷰 · 회기 E2E 자동화http://100.116.83.60:8088 / vignette-e2e 매시간 heartbeat / 배포 증거 / 기계 판독 증거current clean source HEAD 61a41d1f…6af·tree 87dec55d…3b77의 archive 4d15d055…119d4d를 전용 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 aa81af29…는 same-learner SSE·review·G4/G5 0→1→1과 별도 returned desktop/mobile 4/4, 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 증거는 별도다. G7 외부 증거 3-artifact 동시 시간창 오케스트레이터scripts/run-g7-external-proof-window.py · 준비 문서soak·runtime·topology 세 캡처를 같은 host의 공통 3,000초 시간창으로 실행하고 checker까지 잇는다. 공개 배포·프로세스·source pin은 clean commit b34623f3…와 fresh receipt 9f8d1941…로 완료했다. Cloudflare가 Python 기본 User-Agent를 403으로 거부하는 경계도 브라우저 호환 header와 회귀 4/4로 고정했다. 30초 rehearsal은 세 leg 7 samples를 모두 통과했으며 마이크를 열지 않았다. 남은 선행 조건: 사용자의 물리 장치 선택과 명시 동의, 독립 human voice-gain pack이다. G7 external GATE · 최종 감사 정정run-g7-external-proof-window.pycheck-g7-external-proof.py상태는 external GATE 유지. runner 프로세스 exit는 canonical checker exit 0·gate_closed=true에 결속되고, browser Origin과 API transport host는 별도 allowlist로 검증된다. 세 artifact 교집합은 ≥3000s + 120초 margin이고 Windows proof는 detached-clean HEAD/tree·tool SHA·psutil==6.1.1을 pin한다. clean-source 배포와 무마이크 rehearsal은 완료했다. 남은 것은 물리 마이크 3,120초, 동시 runtime/topology, 독립 human pack을 합친 4-artifact 실증뿐이다. G8 DONE · clean-head NAS 기준선vignette-preview-20260807 · run-outcome-os-release-agent.py상태는 DONE. active archive 4d15d055…119d4d, source HEAD/tree 61a41d1f…6af/87dec55d…3b77, API/Web d5021950…e4b1/9796c092…4b36 exact running. candidate 112/112와 actual NAS-origin 112/112, health ok·db/engine true·auth 401·OpenAPI 126을 통과했다. fresh dump 36ec8748…24db8 1,097,100 bytes, TOC 1,738 / TABLE DATA 129와 previous active 6030a677…c611을 보존했다. release agent의 DB restore 비소유·image/Compose/active-state rollback 경계는 유지한다. diff --git a/docs/ops/outcome-os-g7-external-proof-readiness-2026-08-07.md b/docs/ops/outcome-os-g7-external-proof-readiness-2026-08-07.md index 18a487f..8c01566 100644 --- a/docs/ops/outcome-os-g7-external-proof-readiness-2026-08-07.md +++ b/docs/ops/outcome-os-g7-external-proof-readiness-2026-08-07.md @@ -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 diff --git a/scripts/prepare-g7-human-voice-gain-intake.py b/scripts/prepare-g7-human-voice-gain-intake.py index b6bee4b..3151dfc 100644 --- a/scripts/prepare-g7-human-voice-gain-intake.py +++ b/scripts/prepare-g7-human-voice-gain-intake.py @@ -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 --out \n" + "python -X utf8 -B scripts/check-g7-human-voice-gain.py --input \n" + "```\n", encoding="utf-8", newline="\n", ) diff --git a/scripts/test_prepare_g7_human_voice_gain_intake.py b/scripts/test_prepare_g7_human_voice_gain_intake.py index acada79..3df5804 100644 --- a/scripts/test_prepare_g7_human_voice_gain_intake.py +++ b/scripts/test_prepare_g7_human_voice_gain_intake.py @@ -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 --out ", + ): + self.assertIn(required_guidance, readme) report, pack = MODULE.compile_intake(target) self.assertIsNone(pack)