From 83590e9ef79086c545ab16e59abaeda54d4599d4 Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Sun, 9 Aug 2026 22:56:05 +0900 Subject: [PATCH] =?UTF-8?q?G7=20=EA=B3=B5=EA=B0=9C=20=EC=A6=9D=EA=B1=B0?= =?UTF-8?q?=EC=99=80=20SSOT=20=EB=8F=99=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/e2e/dev-dashboard.spec.ts | 3 +- docs/HANDOFF.md | 154 ++++++++++++---------------- docs/TODO.md | 37 +++---- docs/dev_dashboard.html | 30 +++--- docs/guides/testing.md | 15 ++- docs/ops/backlog-2026-06-26.md | 35 +++---- scripts/check-dev-dashboard-ssot.py | 4 +- 7 files changed, 130 insertions(+), 148 deletions(-) diff --git a/apps/web/e2e/dev-dashboard.spec.ts b/apps/web/e2e/dev-dashboard.spec.ts index e58186b..a39dc4b 100644 --- a/apps/web/e2e/dev-dashboard.spec.ts +++ b/apps/web/e2e/dev-dashboard.spec.ts @@ -342,7 +342,8 @@ test.describe("dev dashboard static command center", () => { await expect(pulseDetails).toHaveJSProperty("open", false); await pulseDetails.locator("summary").click(); await expect(pulseDetails).toHaveJSProperty("open", true); - await expect(pulseDetails).toContainText("detached clean release와 exact Git commit/tree"); + await expect(pulseDetails).toContainText("b34623f3"); + await expect(pulseDetails).toContainText("실제 mic·동시 high-water·human evidence"); await pulseDetails.locator("summary").click(); await expect(pulseDetails).toHaveJSProperty("open", false); diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 0e30e8a..704ce66 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -8,9 +8,11 @@ **G0~G6의 내부 구현·증거와 G8 clean-head NAS-origin runtime은 종료됐다. G8은 source HEAD `61a41d1f…6af`·tree `87dec55d…3b77`·archive `4d15d055…119d4d`로 candidate 112/112와 actual NAS-origin -112/112를 모두 통과했다. 앞선 fail-closed·verified rollback 이력과 previous `6030a677…c611`은 보존했다. G7 공개 런처의 -local sidecar lifecycle·provider/model readiness·Uvicorn queue, fresh PID/source provenance, 3,120초 runner와 -3,000초 공통 시간창·canonical exit 계약은 소스에서 완료됐지만, current source 공개 배포와 외부 4-artifact 게이트는 남아 있다.** +112/112를 모두 통과했다. 앞선 fail-closed·verified rollback 이력과 previous `6030a677…c611`은 보존했다. G7 공개 런타임은 +detached-clean `b34623f3…`·tree `32cc85c7…`로 fresh 승격했고 OpenAPI 126, local Whisper/MeloTTS, Uvicorn queue 4, +API/cloudflared provenance receipt와 source-pinned Scheduled Task result 0을 확인했다. 인증 WSS·runtime·Windows topology의 +30초 무마이크 rehearsal도 통과했다. 남은 것은 명시 동의 물리 마이크 3,120초·공통 3,000초 high-water, +독립 human pack과 canonical checker exit 0이다.** | Goal | 판정 | 완료 증거 | |---|---|---| @@ -21,7 +23,7 @@ local sidecar lifecycle·provider/model readiness·Uvicorn queue, fresh PID/sour | G4 Deliberate Practice | DONE | completed-session observer, actual API/DB attempts, teacher correction, returned-practice browser 폐루프 | | G5 Calibration & Transfer | DONE | actual transfer execution, independent/model-run/instrument/evidence provenance, DB/browser idempotency | | G6 Supervision & Research | DONE | safety event metadata-only projection, safety priority 1 > deterioration 2, raw detail 0 | -| G7 Multimodal Alliance | **internal DONE · external GATE** | consent/withdrawal, synthetic soak 59/59, G7 runner/checker/topology 86/86, launcher/sidecar 80/80, API voice 71/71 | +| G7 Multimodal Alliance | **internal DONE · external GATE** | consent/withdrawal, synthetic soak 59/59, public `b34623f3…`·OpenAPI 126·local voice, no-mic rehearsal 3 legs × 7 samples | | G8 Continuous Improvement | **DONE · CLEAN-HEAD NAS VERIFIED** | 실제 image rollback 2회 + executed receipt 2건, source/archive 결속, candidate 112/112, actual NAS-origin 112/112 | 대시보드 status count는 **33 done / 2 doing / 0 planned**다. @@ -35,33 +37,26 @@ G8 배포 source 기준선은 branch `master`, HEAD `61a41d1f08239b5f9e99cfae42a - G8 clean-head execute는 격리 NAS preview만 변경했고 공개 API/DB·물리 마이크는 건드리지 않았다. source HEAD/tree와 archive 2회 결정성, fresh dump, exact images, candidate/actual-origin 결과를 모두 결속했다. -- G8 종료 뒤 공개 Web에 commit `7cece90e…`의 PII 표시 토큰 핫픽스를 Pages production deployment - `721e82b8…`로 승격했다. 공개 API/DB는 재시작하지 않았고, 실제 사용자 회기에서 literal `[NAME]` 0과 - `되는 건지 잘 모르겠는데요` 표시를 브라우저로 확인했다. API full 921/921, Web typecheck/build, - session full-sweep desktop/mobile 34 passed·2 intentional skip이 GREEN이다. +- G8 종료 뒤 공개 Web은 Pages production deployment `7bd59055…`로 갱신했다. 실제 사용자 회기에서 literal + `[NAME]` 0, `시간 만료`, 모바일 44px·자동 스크롤 보정을 브라우저로 확인했다. 공개 API는 아래 G7 clean + promotion에서 별도로 fresh 승격했다. - active goal은 계속 `active`다. 목표는 “문서 작성”이 아니라 **G0~G8 아홉 목표를 실제 runtime과 E2E로 모두 닫는 것**이다. G8은 종료됐고 G7 canonical checker exit 0이 없으면 `goal complete`를 호출하지 않는다. - 마지막 완료 작업은 G8 source HEAD `61a41d1f…6af`·tree `87dec55d…3b77`·archive `4d15d055…119d4d`의 candidate 112/112와 actual NAS-origin 112/112다. API/Web `d5021950…e4b1`/`9796c092…4b36`, health ok·db/engine true·auth 401·OpenAPI 126, fresh dump `36ec8748…24db8`을 확인했다. - G7 Windows topology mode, 3,000초 공통 시간창, canonical checker-bound exit와 공개 런처의 local - Whisper/MeloTTS lifecycle·exact readiness·Uvicorn queue·fresh API/cloudflared provenance 계약은 코드와 회귀가 - 끝났지만 public launcher 실행과 capture는 수행하지 않았다. - 현재 public API가 Git metadata가 없는 냉동 release 디렉터리에서 실행되므로 provenance gate가 의도적으로 - 닫혀 있다. 이 검증을 약화해서 통과시키면 안 된다. -- **public task source-pin P0:** watchdog·로그온 boot는 이제 detached clean release만 허용하고 Git - commit/tree와 watchdog|boot/start script SHA를 health·Docker·process mutation 전에 검증한다. hidden VBS도 - shared source를 직접 실행하지 않고 구조적으로 pin된 task만 trigger한다. 회귀는 provenance 11개를 포함한 - watchdog/start/cutover combined 22/22, PowerShell 5.1 parser·WSH syntax PASS다. 그러나 **실제 두 Scheduled Task action은 - 아직 shared worktree를 가리키며 pin 인자가 없다.** 5분 watchdog은 pin 부재로 반복 실행마다 - `LastTaskResult=1`이고, 새 필수 pin 인자 부재 때문에 운영 프로세스를 건드리기 전에 의도대로 fail-closed했다. - 18:02:55 KST에는 Docker Desktop UI가 active DB container에 직접 stop을 보내 public `db=false`가 재발했다. - 같은 container ID와 recovered named volume만 18:05 KST 재시작했고, 공개 local/public health는 다시 - `status=ok, db=true, engine=true`다. clean commit 뒤 두 task를 동일한 detached stable - release root로 재등록하고 action pin·watchdog result 0·로그온/reboot smoke를 확인하기 전에는 public runtime - 자동복구를 DONE으로 부르지 않는다. -- 다음 mutation 대상은 G7 public runtime이다. G8 NAS는 새 material milestone이 생기기 전까지 읽기 전용 기준선으로 - 두고, public/DB mutation owner는 한 명만 둔다. + Whisper/MeloTTS lifecycle·exact readiness·Uvicorn queue·fresh API/cloudflared provenance 계약은 코드와 공개 runtime에서 + 확인했다. detached-clean `b34623f3…`·tree `32cc85c7…`의 receipt `9f8d1941…a21bf`가 passed이고, + OpenAPI 126·`/admin/voice-runtime`·`local_whisper/small`·`melotts/melotts-korean`·queue 4가 공개 경로와 일치한다. +- **public task source-pin P0 완료:** watchdog·로그온 boot는 detached clean release의 commit/tree와 + watchdog|boot/start script SHA를 mutation 전에 검증한다. 두 Scheduled Task를 같은 `b34623f3…` stable root에 + 재등록하고 명시 실행해 `LastTaskResult=0`·Ready와 working directory pin을 확인했다. 실제 Windows 재부팅 뒤 + 자동복구 smoke는 별도 운영 게이트로 남는다. +- 인증 WSS ready/ping/close 1000, runtime 7 samples, Windows topology 7 samples의 30초 무마이크 rehearsal을 통과했다. + voice/runtime/topology evidence에는 UUID/email literal이 없고 `physical_capture=false`다. 다음 mutation은 사용자가 + 정확한 장치를 선택하고 명시 동의한 뒤의 3,120초 마이크 캡처다. G8 NAS는 새 material milestone이 생기기 전까지 + 읽기 전용 기준선으로 둔다. ### 완료 조건 판정 (2026-08-09 재검증) @@ -75,8 +70,7 @@ G8 배포 source 기준선은 branch `master`, HEAD `61a41d1f08239b5f9e99cfae42a | 4 | G7을 가짜·합성 증거로 DONE 처리하지 않음 | **충족** | `check-g7-external-proof.py` exit 1 유지, G7 카드는 `GATE` | 재검증 수치: API **921 passed**, gateway **58**, executor **28**, probe **11**, helper launcher **37**, -release agent **30**, G7 runner/checker/topology 묶음 **86**, G7 public launcher/sidecar **80**, G7 통합 **166**, -API voice 통합 **71**, +release agent **30**, current G7 six-suite **87/87**, runtime sampler **4/4**, API voice 통합 **71**, MeloTTS 사이드카 **16**, local whisper 사이드카 **38**, SSOT FAIL **0**, dashboard E2E **10/10**, web api-types·typecheck·build 통과, ruff clean. @@ -102,7 +96,7 @@ live health 테스트는 React StrictMode 중복 조회의 첫 응답을 고정 | G4 | 모든 코칭 카드의 실행 재연습, 전후 근거 저장, unseen 전이 전 mastery 금지 | 실제 API/DB attempt·observer·teacher correction, browser route mock 0 | disposable DB에서 returned-practice desktop/mobile 4/4와 멱등 재확인 | | G5 | 자기평가 잠금, calibration 감소, unseen transfer 유지, subgroup drift | actual transfer execution과 independent/model-run/instrument/evidence provenance | G4와 같은 disposable DB에서 actual POST·read reload·1→1 멱등 재확인 | | G6 | 3-click queue, 원장 drilldown, 버전 재현, 역할/RLS/audit | safety metadata-only, safety priority 1 > deterioration 2, raw detail 0 | current HEAD producer/store/API와 supervisor UI 회귀 재실행 | -| G7 | 시간 정렬, **물리 마이크+공개 WSS 장시간 E2E**, text-only 대비 음성 이득, 동의/삭제 정책 | 내부 계약·synthetic soak만 완료. canonical checker는 의도적으로 exit 1 | current 공개 배포→인증 WSS→명시 동의 mic 50분→동시 runtime/topology→독립 human pack→checker exit 0 | +| G7 | 시간 정렬, **물리 마이크+공개 WSS 장시간 E2E**, text-only 대비 음성 이득, 동의/삭제 정책 | 내부 계약·공개 clean runtime·인증 WSS 무마이크 rehearsal 완료. canonical checker는 의도적으로 미실행/미종료 | 장치 선택·명시 동의→mic 3,120초→동시 runtime/topology→독립 human pack→checker exit 0 | | G8 | source→draft→red-team→benchmark→catalog 재현, 누수/PII/무근거 0, 자동 calibration+rollback, incident→test/backlog 환류 | agentic worker·human gate·실제 rollback/restore receipt 2건, clean-head candidate/NAS-origin 112/112 | **종료.** 새 material milestone 전까지 NAS 기준선 보존 | ## 1. 작업 시작 전 반드시 읽을 파일 @@ -192,24 +186,25 @@ UI가 active DB container에 직접 stop을 보내 같은 증상이 재발했다 - 2026-08-09 18:05 KST 재기동 후 owner read-only 집계: users 356, sessions 193, turns 726, Google users 16, Google-owned sessions 31. 조회는 `BEGIN READ ONLY` 뒤 `ROLLBACK`했고 PII를 출력하지 않았다. - health `environment=prod`, `db=true`, `engine=true`, `engine_mode=claude_cli`, dev-login disabled, unauth `/auth/me` 401 -- **2026-08-09 18:05 KST recovery snapshot:** local/public health는 `status=ok, db=true, engine=true`, Google OAuth - start는 302→`accounts.google.com`, 공개 OpenAPI는 119 paths다. `/voice/health`는 아직 OpenAI STT/TTS이고 - local Whisper 9882·MeloTTS 9883 listener는 0이다. -- DB 컨테이너는 `vignette_recovered_prod_20260807` named volume과 `unless-stopped`를 유지하고 local/public - health는 `status=ok, db=true, engine=true`다. 다만 watchdog·로그온 task action은 아직 shared worktree이며 - stable root/commit/tree pin 인자가 없다. 새 source-pin 코드가 5분 watchdog을 mutation 전에 차단해 반복 실행이 - `LastTaskResult=1`이다. clean commit의 detached release root로 두 task를 재등록하기 전까지 자동복구가 - 의도적으로 비활성인 상태다. +- **2026-08-09 G7 promotion snapshot:** local/public health는 `status=ok, db=true, engine=true`, Google OAuth + start는 302→`accounts.google.com`, 공개 OpenAPI는 126 paths이고 `/admin/voice-runtime`이 존재한다. + `/voice/health`는 `local_whisper/small`·`melotts/melotts-korean`·WS queue 4를 보고한다. +- DB 컨테이너는 `vignette_recovered_prod_20260807` named volume과 `unless-stopped`를 유지한다. API/cloudflared는 + detached-clean `b34623f3…`·tree `32cc85c7…`에서 실행되고 receipt `9f8d1941…a21bf`가 passed다. + watchdog·로그온 task도 같은 stable root/commit/tree/script SHA에 pin해 명시 실행 결과 0·Ready를 확인했다. + 실제 Windows 재부팅 뒤 자동복구 smoke만 남아 있다. 보안상 과거 `auth_session`은 복원하지 않았다. 사용자는 Google 재로그인이 필요하다. -보존물: pre-recovery container `vignette-dev-db-pre-recovery-20260807-182642`과 원본/recovery Docker volumes. +보존물: pre-recovery container `vignette-dev-db-pre-recovery-20260807-182642`과 원본/recovery Docker volumes, +그리고 2026-08-09 fresh custom dump +`D:\workspace\vignette-backups\vignette-dev-db-vignette-20260809-122235Z.dump` +(SHA256 `f1fd569c…5f64`, 7,458,327 bytes)다. 과거 증거에는 pre-cutover dump `…20260807-091057Z.dump` SHA256 `6b84d5c8…af1f`, recovered dump `…20260807-092630Z.dump` SHA256 `d7bcc396…68ed`, post-cutover dump `…20260807-095511Z.dump` SHA256 -`660695c8…65b88`이 기록돼 있으나, **인계 시점 로컬에는 `D:\workspace\vignette-backups` 디렉터리가 없고 -`D:\workspace\vignette-recovery`에도 이 dump들이 보이지 않는다.** 삭제로 단정하지 말고 off-host/NAS/다른 경로를 -확인하기 전 restore·cleanup을 금지한다. NAS의 pre-proof/pre-clean-head dump는 §5 기준으로 실제 존재와 hash를 -재확인했다. +`660695c8…65b88`이 기록돼 있다. 이 세 과거 dump의 현재 위치는 별도로 재확인하지 않았으므로 삭제로 단정하지 말고 +off-host/NAS/다른 경로를 확인하기 전 restore·cleanup을 금지한다. NAS의 pre-proof/pre-clean-head dump는 §5 기준으로 +실제 존재와 hash를 재확인했다. 공개 DB에는 current dirty source를 배포하지 않는다. @@ -431,45 +426,37 @@ hash를 갖춘 복원 절차로만 수행한다. 이미지 rollback 성공을 DB G7 내부 소스 계약은 완료됐고 `scripts/check-g7-external-proof.py`는 현재 의도적으로 exit 1이다. 네 artifact를 **같은 public host, 겹치는 50분 시간창**으로 수집해야 한다. -먼저 닫아야 할 운영·코드 선행조건이 있다. +운영·코드 선행조건과 무마이크 rehearsal은 닫혔다. -- 공개 API는 여전히 119 paths 구버전이며 `/admin/voice-runtime`이 없고(404), `/voice/health`는 - `openai/gpt-4o-transcribe` + `openai/gpt-4o-mini-tts`다. -- local Whisper 9882와 MeloTTS 9883 listener는 아직 공개 호스트에 떠 있지 않다. 다만 current source의 - `start-public-runtime.ps1`는 두 sidecar를 API보다 먼저 시작하고 `local_whisper/small/cpu-int8`, - `melotts/melotts-korean` exact provider/model·WS/HTTP readiness를 fail-closed로 확인하며, 기존 비정상 리스너를 - 임의 종료·재사용하지 않는다. Uvicorn도 `--ws websockets --ws-max-queue 4`로 고정했다. source 검증은 - launcher/sidecar 80/80, API voice 71/71, PowerShell parse·Ruff·compile·diff-check PASS지만 공개 실행은 0회다. +- 공개 API는 detached-clean `b34623f3…`·tree `32cc85c7…`에서 OpenAPI 126과 + `/admin/voice-runtime`을 제공한다. `/voice/health`는 `local_whisper/small` + + `melotts/melotts-korean`, Uvicorn WS queue 4를 정확히 보고하고 receipt `9f8d1941…a21bf`가 passed다. +- local Whisper 9882와 MeloTTS 9883은 API보다 먼저 exact readiness를 통과했고, 런처는 기존 비정상 리스너를 + 임의 종료·재사용하지 않는다. public health는 promotion과 rehearsal 뒤에도 `status=ok·db=true·engine=true`다. - **외부 실행 전 코드 P0 3건은 완료:** (1) production 프로세스 exit 0은 canonical checker `returncode == 0 && gate_closed == true`에 결속한다. (2) 실제 브라우저 Origin `https://vignette.chanpaca.net`은 exact HTTPS allowlist로, API/WSS/admin/topology `api-vignette.chanpaca.net`은 별도 transport host와 `wss`/`https` scheme으로 검증한다. (3) 실제 capture 기본·최소를 3,120초로 올리고 sampler를 ceil+terminal sample로 계산하며, checker가 voice/runtime/topology 공통 교집합 - **3,000초 이상**을 강제한다. focused runner 37/37과 통합 G7 166/166을 통과했다. + **3,000초 이상**을 강제한다. current six-suite 87/87과 runtime sampler 4/4를 통과했다. - 현재 공개 topology는 Windows host Uvicorn + cloudflared다. 명시적 `windows_host` topology mode는 구현 완료됐다. API/cloudflared의 PID·start time·executable name/SHA256·command-line SHA256·Git SHA·cwd를 pin하고, 각 sample 전후 identity와 Git HEAD drift를 검사한다. RSS/peak RSS/CPU/handles/threads, process TCP/established/listener, API listen-port owner/conflict와 host TCP high-water도 수집한다. 기존 `linux_compose`의 api+caddy·fresh-container 규칙은 그대로 유지한다. -- Windows topology focused 검증은 G7 runner/checker/topology 86/86, Ruff, `py_compile`, `git diff --check`를 통과했고 실제 - read-only adapter가 API 8001 owner=1/conflict=0, cloudflared established TCP>0를 읽었다. raw command line이나 - endpoint는 저장하지 않았다. -- **남은 provenance blocker는 배포/실증:** 현재 API cwd는 - `D:\workspace\vignette-outcome-g7-release-20260807\apps\api`이고 그 release 디렉터리에는 `.git`이 없다. 소스의 - `-RequireFreshPublicProvenance` 모드는 detached-clean commit/tree와 Python/cloudflared/config SHA를 mutation 전에 - 검증하고, legacy API와 exact-config cloudflared를 bounded stop한 뒤 pinned release cwd에서 새 PID로 교체한다. - PID/start/exe SHA/command SHA/실제 cwd를 재검증한 safe receipt에는 raw command line·config 내용을 남기지 않는다. - topology artifact도 같은 commit/tree, runner/collector/checker SHA와 `psutil==6.1.1`을 매 sample 전후 결속한다. - 이 코드는 atomic receipt contract 18/18을 포함한 G7 통합 166/166으로 GREEN이지만 **현재 public에는 아직 실행하지 않았다.** - clean commit 전 legacy cwd/Git pin을 약화하거나 기존 PID를 증거로 재사용하지 않는다. -- watchdog·로그온 boot의 detached-clean source pin 코드는 완료됐지만 실제 task action은 아직 legacy shared - source다. clean commit 뒤 `docs/ops/public-runtime-watchdog.md` 순서대로 같은 stable release root에 두 task를 - 재등록하고 commit/tree/script hash marker와 `LastTaskResult=0`을 확인한다. 그 전에는 current - `LastTaskResult=1`을 실패가 아니라 안전 차단으로 유지하고, 단일 mutation owner가 public 배포 시간창을 소유한다. +- Windows topology는 API/cloudflared의 PID·start·exe SHA·command SHA·cwd와 detached-clean commit/tree, + runner/collector/checker SHA, `psutil==6.1.1`을 결속한다. 30초 rehearsal에서 API listener owner/conflict와 + cloudflared TCP, RSS/CPU/handles/threads를 7회 수집했고 raw command line·endpoint·UUID·email은 저장하지 않았다. +- watchdog·로그온 boot 두 task도 같은 `b34623f3…` stable root에 재등록했다. commit/tree/script hash marker, + working directory, `LastTaskResult=0`·Ready를 확인했다. 실제 Windows 재부팅 뒤 복구 smoke는 아직 남아 있다. - 운영 Python에 `psutil`이 없으면 collector는 `command_unavailable:psutil`로 fail-closed한다. current `apps/api/requirements.txt`와 명시적 Python 3.11 모두 `psutil==6.1.1`로 고정됐다. - 현재 운영 STT 모델은 이 호스트에서 실측된 CPU int8 `small`로 고정한다. cuDNN 9가 설치되고 별도 성능·정확도 gate를 통과하기 전까지 launcher·API runtime metadata·50분 runner/checker expected model을 모두 `small`로 유지한다. +- 무마이크 rehearsal 산출물은 + `D:\workspace\vignette-runtime-evidence\g7-rehearsal-b34623f3db05-20260809T134105Z`에 있다. + voice `61af2e98…009c`, runtime `c6e8670e…4454`, topology `89f1cb86…a251`이며 세 leg 모두 passed, + `physical_capture=false`다. ```powershell & $py -X utf8 -B scripts/check-g7-external-proof.py ` @@ -503,8 +490,7 @@ $env:PYTHONPATH='D:\workspace\vignette\apps\api' **사용자에게 받아야 하는 것 (코드로 대체 불가):** -- authenticated learner/admin session 또는 안전한 `storageState` 생성 협조 -- 물리 마이크 50분 실행에 대한 **명시적 동의** +- 물리 장치 선택과 3,120초 실행에 대한 **명시적 동의** - 실제 참가자·독립 평가자 운영 승인 합성 label이나 무동의 mic probe로 대체하지 않는다. `check-g7-external-proof.py` exit 0 전에는 G7 메인 상태를 @@ -687,7 +673,7 @@ node.exe .\node_modules\@playwright\test\cli.js test e2e/session-layout.spec.ts --project=chromium-desktop --project=chromium-mobile --project=chromium-single-run --workers=1 --reporter=line ``` -전체 Playwright inventory는 622 tests / 44 files다. 실행 환경/API/DB를 정확히 맞추지 않고 fixture failure를 +전체 Playwright inventory는 626 tests / 44 files다. 실행 환경/API/DB를 정확히 맞추지 않고 fixture failure를 제품 failure로 오인하지 않는다. 같은 blocker가 두 번 반복되면 전체 재시도 대신 원인·증거·수정 계획을 먼저 보고한다. ## 9. 핵심 변경 파일 @@ -731,8 +717,8 @@ node.exe .\node_modules\@playwright\test\cli.js test e2e/session-layout.spec.ts 대체 불가능한 동의·인증 세션·실제 참가자/평가자 승인만 요청한다. 동시 작업은 최대 세 하위 lane으로 나누되, NAS/public/DB mutation owner는 항상 한 에이전트만 둔다. -1. **G7 proof lane:** current public route/config 감사, local provider readiness, `--rehearse`, 네 artifact 수집 준비. - 실제 마이크는 사용자 명시 동의 전 0회, public mutation은 단일 owner에게 인계. +1. **G7 proof lane:** 완료된 clean public runtime과 무마이크 rehearsal을 기준선으로 보존하고, 장치 선택·명시 동의 뒤 + 3,120초 mic/runtime/topology 동시 캡처와 human pack·canonical checker를 닫는다. 2. **G8/NAS monitor lane:** 완료된 archive·images·health·자동화 drift를 읽기 전용으로 감시. 새 material milestone 전 mutation 0. 3. **E2E/SSOT lane:** local fixture, disposable DB browser, visual/accessibility, dashboard/TODO/backlog 정합을 읽기 전용으로 감사. @@ -751,22 +737,18 @@ API/Web `d5021950…e4b1`/`9796c092…4b36`, candidate 112/112, actual NAS-origi milestone 전에는 NAS를 mutation하지 마. 현재 공유 worktree의 후속 dirty 변경은 이 배포 source와 분리해서 다뤄. 최종 목표는 G0~G8 아홉 목표를 코드-only가 아니라 실제 runtime 증거로 모두 닫는 것이다. G0~G6과 G8은 DONE이다. -G7은 내부 구현만 DONE이다. current source 공개 배포, -local_whisper/melotts ready, authenticated public WSS, 사용자의 명시 동의를 받은 물리 마이크 50분 soak, -같은 시간창의 runtime/topology high-water, 독립 human voice-gain pack까지 모아 canonical checker exit 0을 만들어야 한다. +G7은 내부 구현과 clean public runtime·local_whisper/melotts ready·authenticated public WSS 무마이크 rehearsal까지 완료했다. +이제 사용자가 고른 장치와 명시 동의를 받은 물리 마이크 3,120초 soak, 같은 시간창의 runtime/topology high-water, +독립 human voice-gain pack을 모아 canonical checker exit 0을 만들어야 한다. G7 runner exit의 checker exit 0/gate_closed 결속, browser Origin과 API/WSS host 분리, 3,120초 capture와 3,000초 공통 overlap, detached-clean HEAD/tree, runner/collector/checker SHA와 exact psutil pin은 소스에서 완료됐다. -API/cloudflared는 legacy PID를 재사용하지 말고 `-RequireFreshPublicProvenance`로 pinned release cwd에서 강제 -재시작해 새 PID/start/exe/command SHA/cwd safe receipt를 결속해. -G7 runner/checker/topology는 86/86, public launcher/sidecar 계약은 80/80, 통합은 166/166, API voice 통합은 71/71로 구현됐지만 -현재 public API의 Git 없는 냉동 release cwd는 provenance gate를 -통과하지 못한다. current committed repo 기반 launcher/runtime으로 정렬하거나 동등하게 강한 provenance를 구현하고, -cwd/Git pin이나 기존 Linux Compose gate를 약화하지 마. 합성 증거로 G7을 DONE 처리하지 마. -public task source-pin 코드는 구현됐다. watchdog·로그온 boot는 detached clean release와 exact Git commit/tree, -watchdog|boot/start script SHA가 없으면 mutation 전에 실패한다. 하지만 실제 두 Scheduled Task action은 아직 shared -worktree와 legacy 인자를 가리키며, 5분 watchdog은 최신 실행에서 pin 인자 부재로 `LastTaskResult=1`이다. public은 -현재 health ok지만 자동복구는 의도적으로 fail-closed다. clean commit 뒤 동일 stable release root로 두 task를 -재등록하고 action pin·watchdog result 0·로그온/reboot smoke를 증명한 뒤에만 runtime DONE으로 바꿔. +API/cloudflared는 detached-clean `b34623f3…`·tree `32cc85c7…`에서 새 PID로 교체됐고 safe receipt +`9f8d1941…a21bf`가 passed다. 공개 OpenAPI 126·`/admin/voice-runtime`·local provider/model·queue 4와 +public health db/engine true를 확인했다. 30초 rehearsal은 인증 WSS·runtime·Windows topology 세 leg 7 samples를 +모두 통과했고 `physical_capture=false`·UUID/email 0이다. 이 증거를 물리 마이크나 사람 평가로 과장하지 마. +watchdog·로그온 boot도 같은 stable root와 exact Git commit/tree/script SHA에 재등록했고 두 task의 명시 실행 결과가 +0·Ready다. 실제 Windows 재부팅 뒤 자동복구 smoke는 별도 운영 게이트로 남는다. cwd/Git pin이나 기존 Linux Compose +gate를 약화하지 말고 합성 증거로 G7을 DONE 처리하지 마. 학생 자기주도 폐루프는 홈 추천→회기→리뷰→G4 처방/G5 전이→별도 재연습→completed-session observer→ actual attempt/execution→read-model reload→before/after·멱등까지 desktop/mobile 실제 DB/browser로 검증해. @@ -775,8 +757,8 @@ NAS-origin E2E, visual/accessibility, auth/OpenAPI/assets/SSE→DB review를 포 독립 작업은 서브에이전트로 병렬화하되 NAS/public/DB mutation은 단일 owner만 수행해. 공개 DB 복구 volume과 pre-recovery container/dumps, NAS named volume과 previous images는 삭제하지 마. 비밀/PII/raw UUID를 증거에 남기지 마. -과거 로컬 recovery dump 경로는 인계 시점에 보이지 않으므로 삭제로 단정하거나 그 파일을 전제로 복원하지 말고, -off-host/NAS 보관 위치와 새 backup 목적지를 먼저 확인해. +과거 로컬 recovery dump는 현재 위치를 별도로 확인하기 전 삭제로 단정하거나 그 파일을 전제로 복원하지 마. +2026-08-09 fresh public dump `vignette-dev-db-vignette-20260809-122235Z.dump` SHA `f1fd569c…5f64`도 보존해. source-only PASS나 health-only를 DONE으로 부르지 말고, 대시보드·TODO·backlog·HANDOFF를 마지막 증거와 함께 동기화해. 모든 게이트가 실제로 닫히기 전에는 goal complete를 선언하지 마. ``` diff --git a/docs/TODO.md b/docs/TODO.md index b7acd53..d2fe043 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -22,10 +22,11 @@ 재발했으나 동일 recovered container/volume만 재기동했고, 현재 owner read-only 집계는 users 356/sessions 193/ turns 726, Google users 16/Google-owned sessions 31이며 public db/engine true다. watchdog·로그온 boot는 detached clean release의 Git commit/tree와 watchdog|boot/start SHA가 없으면 mutation 전에 실패하도록 코드로 고정했다. - 실제 두 Scheduled Task action은 아직 shared worktree라 watchdog 반복 실행은 의도적으로 - `LastTaskResult=1`이다. 18:05 KST 복구 뒤 local/public health는 `status=ok·db=true·engine=true`, 공개 OpenAPI는 - 119 paths지만 `/voice/health`는 OpenAI STT/TTS이고 local voice sidecar listener 9882/9883은 0이다. - clean commit 뒤 동일 stable release root로 두 task를 재등록하기 전까지 자동복구는 DONE이 아니다. + 공개 API·cloudflared는 detached-clean `b34623f3…`·tree `32cc85c7…`로 fresh 승격했고 receipt + `9f8d1941…a21bf`가 passed다. local/public health는 `status=ok·db=true·engine=true`, 공개 OpenAPI 126, + `/admin/voice-runtime`, `local_whisper/small` + `melotts/melotts-korean`, queue 4를 확인했다. 로그온·watchdog + 두 task도 같은 root/commit/tree/script SHA에 재등록해 명시 실행 `LastTaskResult=0`을 확인했다. + 남은 자동복구 gate는 실제 Windows 재부팅 smoke와 정기 DB 백업 운영화다. 상세: `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)을 통과했다. @@ -109,26 +110,18 @@ (2) **독립 blind human voice-gain pack** — held-out 30명 외 calibration split 참가자 포함 총 최소 31명 / held-out 50회기 / 150 paired axis / 독립 평가자 2인 / ICC(A,1) ≥ 0.75 · κ ≥ 0.70 · gain ≥ 0.01 · participant-cluster bootstrap 10,000회 95% CI lower > 0. - **선행 조건(2026-08-08 발견):** 공개 런타임은 119 paths 구버전이라 `/admin/voice-runtime`이 - 배포돼 있지 않다. 마이크와 사람을 다 준비해도 오늘 실행하면 50분을 버리고 artifact 2에서 실패한다. - current source를 공개에 먼저 승격해야 한다(비-secure origin `crypto.randomUUID` 수정도 함께 나간다). - 오케스트레이터가 시작 전에 `admin_voice_runtime_not_deployed`로 막는다 — 실측 exit 2. - 이 판정은 미인증 HTTP 상태가 아니라 OpenAPI `paths`로 한다. Cloudflare가 자동화 클라이언트에 - 모든 경로를 403(error 1010)으로 주기 때문에 상태 코드로는 배포 누락을 알 수 없다. - 2026-08-09 재감사에서 공개 `/voice/health`는 여전히 OpenAI STT/TTS이고 local Whisper 9882·MeloTTS - 9883 listener가 없음을 확인했다. current source에는 sidecar-before-API lifecycle, exact - `local_whisper/small/cpu-int8`·`melotts/melotts-korean` readiness, provider env와 Uvicorn - `--ws websockets --ws-max-queue 4`를 fail-closed로 연결했다(launcher/sidecar 80/80, API voice 71/71). - Windows host topology mode도 PID/start/exe·command SHA/cwd와 process/TCP high-water를 검증한다. - 하지만 이 source를 공개에 배포한 적은 없고, 현재 API의 Git 없는 냉동 release cwd는 provenance gate를 통과하지 - 못한다. current committed repo 기반으로 공개 runtime을 정렬한 뒤에만 50분 창을 연다. + **공개 선행 조건 완료(2026-08-09):** detached-clean `b34623f3…`·tree `32cc85c7…`에서 OpenAPI 126, + `/admin/voice-runtime`, exact local voice provider/model과 queue 4를 제공한다. fresh launcher receipt + `9f8d1941…a21bf`가 passed이고 두 Scheduled Task도 동일 source에 pin돼 result 0이다. Cloudflare의 Python + 기본 User-Agent 403 경계는 runtime sampler의 browser-compatible header와 회귀 4/4로 고정했다. **외부 실행 전 코드 P0 완료:** runner 종료 코드는 canonical checker `exit 0`/`gate_closed=true`에 결속됐고, 브라우저 Origin(`vignette.chanpaca.net`)은 API/WSS/admin/topology host(`api-vignette.chanpaca.net`)와 분리된 HTTPS allowlist로 검증한다. 실제 capture는 최소 3,120초·ceil+terminal sample이고 voice/runtime/topology 공통 overlap `≥3000s`를 checker가 강제한다. Windows artifact는 detached-clean HEAD/tree, runner/collector/checker SHA, exact `psutil==6.1.1`을 매 sample 전후 pin한다. fresh launcher는 legacy API와 exact-config cloudflared를 bounded 교체하고 새 PID/start/exe/command SHA/실제 cwd의 raw command-line 없는 receipt를 만든다. G7 runner/checker/topology - 86/86, launcher/sidecar 80/80, 통합 166/166을 통과했다. 실제 공개 실행 전 `--rehearse`로 배관을 먼저 검증한다. + 87/87과 runtime sampler 4/4를 통과했다. `--rehearse`는 인증 WSS ready/ping/close 1000, + runtime 7 samples, Windows topology 7 samples를 모두 통과했고 마이크 capture false·UUID/email literal 0이다. fail-closed 경계(동의 없음·pack 없음·3,120초 미만·host/Origin/scheme 불일치)는 CLI로 실증했다. 상세: `ops/outcome-os-g7-external-proof-readiness-2026-08-07.md`. @@ -435,8 +428,8 @@ 격리 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`. - **남음:** current source의 공개 배포와 `local_whisper`/`melotts` ready metadata 일치, authenticated public WSS ready, - 사용자의 명시 동의를 받은 물리 마이크, 실행된 50분 양방향 soak, 독립 라벨 held-out/pilot의 실제 음성 이득, + **남음:** 사용자가 장치를 선택하고 명시 동의한 물리 마이크 3,120초, 공통 3,000초 양방향 soak와 동시 + runtime/topology high-water, 독립 라벨 held-out/pilot의 실제 음성 이득, 실제 worker·Uvicorn·OS·Cloudflare edge를 같은 50분 시간창으로 묶은 RSS/CPU/queue high-water. preflight·synthetic·옵션 제공만으로 종료하지 않는다. @@ -523,7 +516,7 @@ - [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-011** public/deploy proof manifest — 공개 API 126 paths, G1~G8 route, Pages asset, auth/OAuth proof. - [x] **AOS-012** SSOT/TODO 동기화 — dashboard/TODO/backlog/release manifest 동기화와 checker green. --- @@ -533,5 +526,5 @@ **C(Phase 3 파일럿)** — C는 2026-07-13 회의로 **7월 말~8월 초 파일럿 일정 확정**, 그 전제로 **H의 P1(회기 종료 시간 기반)**이 새 구현 게이트다. **I(Outcome & Alliance OS)는 현재 감사 기준 G0~G6과 G8이 DONE이다. G8은 receipt-bound 실제 rollback과 current clean source NAS-origin 112/112를 완료했다. G7은 내부 구현 DONE과 외부 proof GATE를 분리하며, -current source 공개 배포·`local_whisper`/`melotts` ready·auth public WSS·명시 동의 mic·50분 soak·독립 라벨 benchmark·운영 resource high-water가 남았다.** D~G는 +current source 공개 배포·local voice ready·authenticated WSS 무마이크 rehearsal은 완료했고, 명시 동의 mic 3,120초·동시 resource high-water·독립 라벨 benchmark·checker exit 0이 남았다.** D~G는 품질·확장 작업으로 게이트가 아니다. 상세 상태·검증 증거는 SSOT 대시보드가 소유한다. diff --git a/docs/dev_dashboard.html b/docs/dev_dashboard.html index 56d6b1b..3f862a1 100644 --- a/docs/dev_dashboard.html +++ b/docs/dev_dashboard.html @@ -291,10 +291,10 @@
project pulse

지금 위치: G0~G6 · G8 DONE.
G7 external proof를 닫는 중.

-

현재: G8 clean-head는 source HEAD 61a41d1f…·tree 87dec55d…·2회 결정적 archive 4d15d055…119d4d로 격리 NAS에 승격됐다. candidate 112/112와 실제 NAS 평문 origin browser review 112/112가 모두 GREEN이고 health·db·engine, auth 401, OpenAPI 126도 통과했다. 공개 Web은 7cece90e의 PII 표시 토큰 핫픽스를 Pages production 721e82b8에 승격했고, 실제 사용자 회기에서 literal [NAME] 0·보정 문장 노출을 확인했다. 다음: G7 current source 공개 배포 → 인증 WSS → 명시 동의 물리 마이크·운영 high-water·독립 사람 증거 순서로 진행한다.

+

현재: 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 7bd59055에서 literal [NAME] 0·시간 만료·모바일 44px/자동 스크롤 보정을 실제 회기에 노출한다. 마이크를 열지 않은 G7 rehearsal도 인증 WSS·runtime·Windows topology 세 leg 7-sample로 통과했다. 다음: 사용자의 장치 선택·명시 동의 → 물리 마이크 3,120초·공통 3,000초 high-water → 독립 human pack → canonical checker exit 0 순서다.

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

2026-08-07 18:26 KST 공개 DB를 vignette_recovered_prod_20260807 named volume으로 전환했고 원본 container·dump·volume은 삭제하지 않았다. 기존 auth session은 복사하지 않아 사용자는 Google 재로그인이 필요하다. 2026-08-09 18:02:55 KST Docker Desktop UI가 active DB container에 직접 stop을 보내 public db=false가 재발했지만 같은 container ID와 recovered volume만 18:05 KST 재시작했다. 재기동 뒤 owner read-only 집계는 users 356·sessions 193·turns 726, Google users 16·Google-owned sessions 31이고 public health는 다시 status=ok·db=true·engine=true다. public task source pin 코드는 완료됐다. watchdog·로그온 boot는 detached clean release와 exact Git commit/tree·watchdog|boot/start SHA가 없으면 health·Docker·process mutation 전에 실패하고 hidden VBS도 pinned task만 trigger한다(provenance 11개 포함 combined 22/22, PS5.1·WSH PASS). 다만 실제 두 Scheduled Task action은 아직 shared worktree라 watchdog은 필수 pin 인자 부재로 LastTaskResult=1이며 자동복구가 의도적으로 fail-closed다. clean commit 뒤 두 task를 동일 stable release root로 재등록하고 action pin·result 0·로그온/reboot smoke를 확인해야 한다. G8 NAS는 archive 4d15d055…119d4d, API/Web d5021950…e4b1/9796c092…4b36으로 current clean source 승격과 actual-origin 112/112를 완료했다. 이전 6030a677…c611과 이미지는 복구 기준으로 보존했다. G7 source는 runner/checker/topology 86/86, launcher/sidecar 80/80, 통합 166/166, API voice 71/71이지만 public은 아직 OpenAI provider·Git 없는 냉동 release라 external GATE다.

+

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다.

@@ -303,7 +303,7 @@ Outcome clean E2E 126 · visual 15/15 Alliance G1 baseline 1.2 9/9 · 내부 DONE Tailnet 이전 확인 OK - Public API 119 paths · G1~G8 + Public API 126 paths · G1~G8 Direct-runtime preflight APP ROLE OK critical 3 1차 완료·gate Decision P0 조건부 @@ -651,7 +651,7 @@

183차 적용(2026-08-08): 182차 뒤 소유자 스크린샷에서 시간 만료 상태의 게이트 화면이 여전히 깨져 있어 네 개의 별개 결함을 계측으로 특정하고 닫았다. (1) .sx-timebar는 세션이 다크 stage 팔레트를 강제하던 시절의 잔재로, 배경이 어디에도 정의된 적 없는 --bg-panel의 하드코딩 다크 폴백으로 칠해지는데 글자만 테마 토큰을 따라가 라이트에서 제목 1.13:1·설명 1.76:1이었다. 의미색 토큰(--warn-*/--crit-*)으로 되돌려 13.88:1·6.94:1(다크 13.86·9.30)로 올렸다. (2) 같은 이유로 .sx-end-dialog__panel이 어두운 gradient 위 어두운 글자라 제목 2.68:1·본문 1.14:1로 사실상 보이지 않았다. 불투명 --bg-app 표면으로 바꿔 15.79:1·5.19:1(다크 15.18·6.52)이 됐다. (3) 보태니컬 장식 위로 본문을 올리는 .sx-page--active > *{position:relative}가 같은 특이도(0,1,0)로 뒤에 있어 종료 모달의 position:fixed를 덮어썼다. 오버레이가 화면을 덮는 대신 그리드 한 칸(1532×32px)으로 눌려 들어갔다. :not(.sx-end-dialog)로 제외해 fixed 1600×900 뷰포트 전체를 회복했다. (4) 게이트 행 정의 .sx-page--active.sx-alliance-gated(0,2,0)가 :has() 두 개짜리 규칙(0,3,0)보다 특이도가 낮아 시간 만료 바가 뜨는 순간 밀려났다. 숨긴 축어록·컨트롤바의 빈 트랙이 남아 화면 절반이 비었다(80px 59px 628px 0px 116px 5행). 게이트 규칙에도 같은 :has()를 붙여 3행(80px 59px 693px)으로 정정했다. 무회귀: typecheck 통과, session-layout+alliance-pulse+layout-visual-gate 31/31(182차에서 실패했던 settings도 통과), 시간만료 종료 다이얼로그 E2E 2/2, pre/mid 잠금 E2E 2/2, full-sweep-session+self-directed-learning-loop 30 pass. 남은 음성 4건(voice skip·Space mic)은 변경분 stash 후 baseline에서도 동일 실패라 이 변경과 무관한 기존 회귀다.

184차 적용(2026-08-08): 182·183차 변경이 로컬 워크트리에만 있어 소유자가 보던 공개 사이트에는 반영될 수 없던 상태를 배포로 닫았다. 소유자 스크린샷의 3 AXES는 이미 소스에서 사라진 문자열이었고, 접속 주소가 https://vignette.chanpaca.net이라 커밋 전 변경이 보일 수 없는 것이 원인이었다. 커밋 f0c2240f로 고정한 뒤 npm run build(Session 청크 Session-DnhnKvTy.js·Session-Xn1JLv-d.css), scripts\preserve-pages-assets.ps1로 직전 5개 production 배포의 지연 로드 자산 104개를 보존하고(진행 중 세션의 lazy chunk 404 방지), wrangler pages deploy dist --project-name vignette --branch main --commit-hash f0c2240f로 배포했다(deployment a12c195c, 신규 업로드 37 / 기존 666). 커스텀 도메인 검증은 index-BTkJUPLZ.js 200, Session JS/CSS 모두 올바른 MIME 200이며 신규 마커(축 선택함·is-gate·:not(.sx-end-dialog)) 각 1건, 구버전 마커(3 AXES·--bg-panel·척도 text-overflow) 전부 0건이다. 첫 조회에서 edge가 이전 index를 준 건 배포 직후 타이밍이었고 재조회에서 신규 index로 확정됐다. 공개 API·런타임은 건드리지 않았다.

185차 적용(2026-08-09): 177·181차의 G8 DONE 판정은 rollback receipt gate 완료로 범위를 정정했다. 108/108은 localhost candidate 결과였고 같은 NAS 평문 origin에서는 secure-context 전용 crypto.randomUUID 예외로 회기 E2E 24건이 실패했다. 소스는 randomUuid()로 통일해 insecure-origin 6/6·API type·typecheck·build를 통과했지만 NAS에는 아직 미배포다. 따라서 G8 카드는 BUILD · RECEIPT DONE · RUNTIME REVALIDATION으로 되돌리고, clean-head release mode 구현→수정 배포→실제 NAS-origin 전체 회기 E2E GREEN까지를 남긴다. G7은 운영 기본 local_whisper/melotts의 current 공개 배포·인증 WSS·명시 동의 mic 50분·동시 runtime/topology·독립 human pack 전까지 외부 GATE다.

-

186차 적용(2026-08-09): 공개 DB listener 소실 사고는 Docker Desktop 중단으로 좁혀졌고 recovered named volume을 보존한 기존 컨테이너만 재기동해 복구했다. public/local health는 db·engine true, current owner 집계는 users 171·sessions 93·turns 726이다. 당시 워치독 action의 삭제된 옛 workspace 드리프트를 shared current workspace·5분 주기로 교정하고 즉시 실행 0을 확인했다. 이 임시 조치는 후속 source-pin에서 안전하지 않은 입력으로 판정됐고, 현재 task는 detached-clean pin 인자 부재로 mutation 전에 fail-closed한다. G8 clean-head release mode는 tracked-dirty 차단·HEAD/tree/archive 2회 결정성·archive-only candidate·patch 무회귀·evidence binding과 commit 전 NAS-origin 11-spec rollback gate를 unit 30/30으로 고정했고, 새 NAS preview predeploy dump 72698232…5d41c(1,015,222 bytes·TOC 1,752)를 보존했다. G7 재감사에서는 공개 OpenAPI 119·/admin/voice-runtime 부재, OpenAI voice provider, local sidecar listener 0, Windows host topology와 Compose-only collector 불일치를 확인했으므로 사람 증거 전에 launcher·topology 선행 구현이 필요하다.

+

186차 적용(2026-08-09): 공개 DB listener 소실 사고는 Docker Desktop 중단으로 좁혀졌고 recovered named volume을 보존한 기존 컨테이너만 재기동해 복구했다. public/local health는 db·engine true, 당시 owner 집계는 users 171·sessions 93·turns 726이었다. 당시 워치독 action의 삭제된 옛 workspace 드리프트를 shared current workspace·5분 주기로 교정하고 즉시 실행 0을 확인했다. 이 임시 조치는 후속 source-pin에서 안전하지 않은 입력으로 판정됐고, 그 시점 task는 detached-clean pin 인자 부재로 mutation 전에 fail-closed했다. G8 clean-head release mode는 tracked-dirty 차단·HEAD/tree/archive 2회 결정성·archive-only candidate·patch 무회귀·evidence binding과 commit 전 NAS-origin 11-spec rollback gate를 unit 30/30으로 고정했고, 새 NAS preview predeploy dump 72698232…5d41c(1,015,222 bytes·TOC 1,752)를 보존했다. 같은 시점 G7 재감사에서는 공개 OpenAPI 119·/admin/voice-runtime 부재, OpenAI voice provider, local sidecar listener 0, Windows host topology와 Compose-only collector 불일치를 확인해 launcher·topology 선행 구현이 필요하다고 판정했다. 이 역사 스냅샷의 blocker는 후속 clean public 승격으로 해소됐다.

187차 적용(2026-08-09): G8 clean-head dry-run은 active 6030a677…c611→desired archive 6b1b15bd…a3f7를 mutation 0으로 결속했다. execute 1은 archive CRLF/API type byte-check에서, execute 2는 API·types·build 통과 뒤 session E2E 109 passed / 5 failed에서 모두 승격 전에 fail-closed되어 NAS active/image/DB는 바뀌지 않았다. source-only UUID 4건은 production 번들에서 /src/lib/uuid.ts import가 불가능한 gate 배치 오류라 별도 Vite gate 6/6으로 분리했다. 남은 실제 제품 blocker는 timezone 없는 started_at을 KST 브라우저가 약 9시간 경과로 오인해 시간종료 모달이 정상 코칭 이력을 가리는 문제다. backend UTC offset/Z 계약과 focused disposable DB/browser 회귀를 닫고 새 clean commit을 만든 뒤에만 NAS 배포를 재개한다.

188차 적용(2026-08-09): 회기 시간 P0를 우회 없이 수정했다. browser-facing started_at/ended_at과 learner/teacher dashboard timestamp는 UTC +00:00을 반환하고, 리뷰의 달력 날짜는 서버 locale 대신 KST(+09:00)를 사용한다. backend 관련 65 passed, 후속 voice 계약을 포함한 API 전체 921 passed, Ruff·compile·web typecheck를 통과했다. 고유 Compose DB/API/Web/engine과 Asia/Seoul browser에서 코칭 이력 focused 1/1은 active/null·UTC suffix·10분 미만 경과·timebar/dialog 0·reload 후 coach mark 실제 클릭과 source-pack dialog를 확인했다. 종료 뒤 container·volume·listener 0이다. 이제 새 clean commit 결속과 NAS-origin 전체 E2E가 남았다.

189차 적용(2026-08-09): G7 외부 실행 전 P0를 소스에서 닫았다. production runner exit 0은 canonical checker 0·gate_closed=true에 결속하고, browser Origin allowlist를 API/WSS/admin/topology transport host·scheme과 분리했다. capture는 최소 3,120초·ceil+terminal sample이며 checker는 voice/runtime/topology 공통 교집합 3,000초를 강제한다. Windows 증거는 detached-clean commit/tree, runner/collector/checker SHA, psutil==6.1.1을 매 sample 전후 검증한다. fresh public launcher는 mutation 전에 source·Python·cloudflared·config SHA를 고정하고, legacy API와 exact-config cloudflared를 bounded 교체해 새 PID/start/exe·command SHA/실제 cwd의 raw command-line 없는 receipt를 남긴다. receipt destination은 runtime mutation 전에 create/flush/atomic-replace 권한을 검사하고 기존 receipt를 보존한 채 원자 게시한다. 검증: G7 runner/checker/topology 86/86, launcher/sidecar 80/80, 통합 166/166, API 921, gateway 58, Web api-types·typecheck·build, 자기주도 desktop/mobile 6/6, Ruff·compile·PS5.1 parser·diff-check PASS. 실제 public 실행·마이크·사람 평가는 하지 않았으므로 G7은 external GATE다.

@@ -841,7 +841,7 @@
-
공개 전환

2026-08-07 18:26 KST owner 승인으로 vignette_recovered_prod_20260807vignette-dev-db:55432에 연결했다. cutover 집계 users 84·sessions 30·turns 705, Google 계정 16·소유 회기 30, orphan 0이다. 2026-08-09 Docker Desktop 중단 후 동일 컨테이너만 재기동했으며 현재 users 171·sessions 93·turns 726, local/public health prod·DB true·engine true·claude_cli, OpenAPI 119, Google OAuth 302다. source-pin 코드는 완료됐지만 실제 watchdog·로그온 task action은 shared worktree라 최신 watchdog은 pin 인자 부재로 mutation 전에 exit 1이다. clean commit의 detached stable release root로 두 task를 재등록하기 전까지 자동복구는 의도적으로 fail-closed다.

보존·rollback

전환 직전 DB는 vignette-dev-db-pre-recovery-20260807-182642로 중지 보존했고 exact dump SHA는 6b84d5c8…8af1f다. 원본 volume, post-merge dump d24eaa75…2e32, 최종 recovered dump d7bcc396…68ed, 자동 rollback을 실증한 실패 후보 2개도 삭제하지 않았다.

사용자 확인

보안상 기존 auth_session은 복사하지 않아 모두 Google 재로그인이 필요하다. 계정·회기 원장은 복구돼 있다. 실제 사용자가 재로그인한 뒤 과거 소유 회기 목록이 보이는지 확인할 때까지 이 카드는 안정화 중으로 유지한다. 상세: ops/public-db-recovery-rehearsal-2026-08-07.md.

+
공개 전환

2026-08-07 18:26 KST owner 승인으로 vignette_recovered_prod_20260807vignette-dev-db:55432에 연결했다. cutover 집계 users 84·sessions 30·turns 705, Google 계정 16·소유 회기 30, orphan 0이다. 2026-08-09 Docker Desktop 중단 후 동일 컨테이너만 재기동했고, fresh dump f1fd569c…5f64를 보존한 뒤 누락 migration 14만 단일 트랜잭션으로 적용했다. 현재 local/public health는 prod·DB true·engine true·claude_cli, OpenAPI 126, Google OAuth 302다. API/cloudflared와 watchdog·로그온 task는 detached-clean b34623f3…·tree 32cc85c7…와 exact script SHA에 pin했고 두 task 명시 실행 결과 0·Ready를 확인했다. 실제 Windows 재부팅 smoke만 남아 있다.

보존·rollback

전환 직전 DB는 vignette-dev-db-pre-recovery-20260807-182642로 중지 보존했고 exact dump SHA는 6b84d5c8…8af1f다. 원본 volume, post-merge dump d24eaa75…2e32, 최종 recovered dump d7bcc396…68ed, 2026-08-09 fresh dump f1fd569c…5f64, 자동 rollback을 실증한 실패 후보 2개도 삭제하지 않았다.

사용자 확인

보안상 기존 auth_session은 복사하지 않아 모두 Google 재로그인이 필요하다. 계정·회기 원장은 복구돼 있다. 실제 사용자가 재로그인한 뒤 과거 소유 회기 목록이 보이는지 확인할 때까지 이 카드는 안정화 중으로 유지한다. 상세: ops/public-db-recovery-rehearsal-2026-08-07.md.

@@ -911,8 +911,8 @@
구현

append-only attention queue·원장 pointer, metadata-only 교수자/AI 불일치 dataset·audit, cohort gap, version/subgroup drift, 4-domain Phase 3 manifest와 역할 안전 교수자·연구 UX를 연결했다. scheduled producer가 G0~G5 실제 원장에서 attention/gap을 파생하고 repo-approved synthetic version comparison을 별도 research 트랜잭션으로 실행한다.

종료 증거

기존 6-signal queue·3-click·네 도메인 manifest·실제 API/DB/RLS/audit·version/subgroup 증거에 더해 post-merge disposable clone의 current source에서 safety event와 deterioration 경쟁 신호를 실제 derive했다. 결과는 safety_boundary(1) > deterioration(2), direct pointer 각 1, source detail canary 1·G6 projection canary 0, raw transcript/임상 주장 0이고 replay가 멱등이다. 상세: ops/evidence/g6-safety-priority-runtime-scratch-20260807.json, ops/outcome-os-g6-version-comparison-producer-evidence-2026-08-07.md.

- -
내부 구현 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 연결 종료·성공 발화 55·철회 차단 2·미동의 차단 1·overflow 거부/복구 1/1·10MiB 선초과 거부를 통과했다. 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와 결속한다. current source의 public launcher도 sidecar-before-API lifecycle, local_whisper/small/cpu-int8·melotts/melotts-korean exact readiness, provider env, Uvicorn --ws websockets --ws-max-queue 4, fresh API/cloudflared provenance receipt를 연결했다. runner/checker/topology 86/86·launcher/sidecar 80/80·통합 166/166·API voice 71/71을 통과했다.

외부 종료 GATE

새 launcher는 아직 public에 실행하지 않았다. 현재 public API는 Git metadata가 없는 냉동 release cwd와 OpenAI voice provider로 실행돼 새 Windows provenance gate를 통과하지 못한다. 검증된 clean commit 기반 runtime으로 정렬하고 /admin/voice-runtime과 local provider/model ready를 실제 공개 경로에서 확인한 뒤 authenticated public WSS, 실행 직전 명시 동의 물리 마이크 50분 양방향 soak, 같은 public host·공통 3,000초 시간창의 worker/Uvicorn queue와 process/TCP high-water, 30명/50회기/150축 독립 라벨 held-out voice-gain을 수집해야 한다. 네 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이다. current six-suite 87/87·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이다. 네 artifact가 scripts/check-g7-external-proof.py exit 0을 만들기 전에는 메인 상태를 DONE으로 바꾸지 않는다.

@@ -1068,7 +1068,7 @@ Web typechecknpm run typecheckPassed Design SSOT / auth visualnpm run check:design-ssot / npx playwright test e2e/auth-visual.spec.ts --project=chromium-single-run --reporter=line / npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --reporter=lineSSOT checker passed; login/onboarding light-dark desktop-mobile 1 passed; 14 core screens × 7 widths visual gate 14 passed. - Full Playwright E2E baselinenpm run e2e:parallel / npm run e2e:single-run / npm run e2e:list2026-08-09 현재 수집은 622 tests / 44 files다. 이 숫자는 수집량이며 현 작업트리 전체 GREEN과 동일하지 않다. G8 clean-head release gate는 candidate 112/112와 실제 NAS-origin 112/112를 통과했다. 이전 단일 120/120과 2026-07-15의 fixture desktop/mobile 166/166 + DB/engine/provider 직렬 49/49 = 215/215는 범위가 다른 역사 기준선으로 보존한다. + Full Playwright E2E baselinenpm run e2e:parallel / npm run e2e:single-run / npm run e2e:list2026-08-09 현재 수집은 626 tests / 44 files다. 이 숫자는 수집량이며 현 작업트리 전체 GREEN과 동일하지 않다. G8 clean-head release gate는 candidate 112/112와 실제 NAS-origin 112/112를 통과했다. 이전 단일 120/120과 2026-07-15의 fixture desktop/mobile 166/166 + DB/engine/provider 직렬 49/49 = 215/215는 범위가 다른 역사 기준선으로 보존한다. Refactor governance P1~P8ruff check app / pytest -q app / pytest -q engine_gateway / npm run typecheck / npm run check:api-types / npm run check:design-ssot / npm run check:dead-code / npm run check:duplication / npm run build / npm audit --audit-level=high / full PlaywrightBackend 400 passed, gateway 29 passed, web gates/build/audit passed, vulnerabilities 0, production duplication 1 clone/15 lines/0.03%, Playwright 215/215 passed. 상세 근거는 ops/refactor-governance-2026-07-15.md. API typegen SSOTnpm run check:api-typesPassed; FastAPI OpenAPI → src/lib/api.gen.ts stale check Outcome & Alliance OS G0py -3.11 -X utf8 -m pytest -p no:cacheprovider apps/api/app/test_measurement_contract.py apps/api/app/test_runtime_schema_ssot.py -q / scripts/check-measurement-ledger.sql / measurement·API contract checks / web typecheck / DB-backed session-persistence focused E2E 3종G0 contract/schema 11 passed, 기존 backend 100 passed, auth 39 passed. Python→JSON Schema→TypeScript→PostgreSQL enum·필수필드 계약이 일치하고 8개 deterministic benchmark가 검증됐다. Live PostgreSQL에서 learner/client/evaluator 가시 행 1/1/2, 교차 누수 0, append-only guard 2를 확인했다. 학습자 턴→교수자 대시보드, 워크시트 검수, 종료 deep 평가→durable 리뷰 E2E는 각각 1 passed. G0/AOS-001~004 완료. @@ -1129,7 +1129,7 @@ Crisis safety gate UIPLAYWRIGHT_PORT=5193 npx playwright test e2e/session-mvp.spec.ts --project=chromium-single-run --workers=1 / PLAYWRIGHT_PORT=5259 npx playwright test e2e/session-mvp.spec.ts --project=chromium-desktop --workers=1 --grep "voice conversation stop"mock SSE safety + done.conversation_stopped와 mock voice reply.conversation_stopped에서 안전 자원 109와 입력 disabled가 유지되고, 빈 client reply를 내담자 응답 없음으로 덮지 않으며 live-coach를 호출하지 않는지 검증한다. 음성 위기 경로는 TTS 종료 이벤트 없이도 socket close를 확인한다. Persona/session review UI E2EPLAYWRIGHT_PORT=5215 npx playwright test e2e/teacher.spec.ts --project=chromium-single-run --workers=19 passed mixed suite; real server-row rendering과 route-fixture UI 흐름을 함께 포함한다. 교수자가 pending persona를 승인하고, pending/recent review detail로 진입하며, 별도 student analysis 메뉴·학습자 검색·행 펼침·full learner timeline drilldown을 검증한다. Voice UI synthetic E2Enpx playwright test e2e/voice-success.spec.ts --project=chromium-single-run / PLAYWRIGHT_PORT=5248 npx playwright test e2e/session-mvp.spec.ts --project=chromium-single-run --workers=1 --grep "pending voice transcript"voice-success 2 passed + pending transcript failure UI 1 passed; direct WS cascade, Session 텍스트 턴의 persisted reply /voice/speech→OpenAI speech→Web Audio 재생, Session mic button path with synthetic browser audio/Web Audio playback, and final transcript followed by persistence failure becoming a visible 저장 실패 turn instead of a silent successful transcript - G7 explicit consent · external proofpytest app/test_g7_voice_gain_evidence.py app/test_voice_runtime.py ... / python -m unittest scripts/test_g7_external_proof.py scripts/test_g7_topology_evidence.py ... / voice-success.spec.ts내부 voice/G7 계약과 consent ledger, 동의 전 getUserMedia/voice WS 0회, public v4 interim/final latency, worker/Uvicorn 및 Linux/Windows topology, independent human-held-out gate를 fail-closed로 고정했다. runner/checker/topology는 86/86, public launcher/sidecar는 80/80, G7 통합은 166/166, API voice 통합은 71/71·Ruff·compile을 통과했다. 현재 public API는 Git 없는 냉동 release cwd라 provenance gate를 통과하지 못하고 local_whisper/melotts sidecar도 미기동이다. 실제 명시 동의 마이크·50분·동시 runtime/topology·human evidence가 없어 G7 external GATE다. + G7 explicit consent · external proofpytest app/test_g7_voice_gain_evidence.py app/test_voice_runtime.py ... / python -m unittest scripts/test_g7_external_proof.py scripts/test_g7_topology_evidence.py ... / voice-success.spec.ts내부 voice/G7 계약과 consent ledger, 동의 전 getUserMedia/voice WS 0회, public v4 interim/final latency, worker/Uvicorn 및 Linux/Windows topology, independent human-held-out gate를 fail-closed로 고정했다. 공개 runtime은 clean source b34623f3…에서 OpenAPI 126·local voice exact·queue 4·task result 0을 제공한다. 마이크 없는 rehearsal은 인증 WSS ready/ping/close1000, runtime 7 samples, topology 7 samples를 모두 통과했고 물리 capture false·UUID/email 0을 유지했다. 실제 명시 동의 마이크 3,120초·공통 3,000초 동시 runtime/topology·독립 human evidence가 없어 G7 external GATE다. Voice s2s decision memodocs/decisions/voice-s2s-poc.mdcriteria recorded; keep/drop decision remains owner DECIDE Hanshin data/SSO gatedocs/ops/hanshin-data-governance-gate.mdartifact created; written external evidence still required Hanshin feedback 1차 improvement packdocs/ops/hanshin-feedback-improvement-plan-2026-07-03.md / docs/redteam/hanshin-feedback-plan-redteam-2026-07-03.md / docs/redteam/hanshin-feedback-plan-counter-redteam-2026-07-03.md / backend+web implementation1차 implemented: P1 role mapping + client-only history injection, P2 quality retry/no-save gate + SSE full-response buffer, P3 review display humanization/raw error mapper/fast-deep labels/client feedback label, P4 supervisor scope panel. Verification: backend focused 84 passed, web typecheck and API type check passed, session-review focused 8 passed, layout visual gate 12 passed, session-layout 8 passed. Remaining follow-ups are stored fallback metadata, lower-latency partial stream policy, fast/deep reconciliation, resident namespace/prompt caching, and clinical rubric/CBT wording gates. @@ -1146,8 +1146,8 @@ 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 매일 04:30 KST / 배포 증거 / 기계 판독 증거current clean source HEAD 61a41d1f…6af·tree 87dec55d…3b77의 archive 4d15d055…119d4d를 전용 Compose 프로젝트·포트·네트워크·named volume에 승격했다. candidate session E2E 112/112와 실제 NAS 평문 origin browser review 112/112, health ok·db/engine true, OpenAPI 126·auth 401을 통과했고 fresh dump와 이전 active/images를 보존했다. 자동화는 ACTIVE이며 material milestone+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까지 잇는다. CLI는 동의·장치 없음, human pack 없음, 3,120초 미만, host 불일치를 전부 fail-closed하며 --rehearse는 마이크를 열지 않는다. 기존 Linux Compose gate를 보존한 채 Windows host Uvicorn+cloudflared topology mode를 추가해 detached-clean source/tool SHA와 PID/start/exe·command SHA/cwd·process/TCP high-water를 검증했고 runner/checker/topology 86/86을 통과했다. current source launcher도 local sidecar/provider/queue와 fresh PID provenance를 fail-closed로 연결했지만 아직 공개에 실행하지 않았다. 남은 선행 조건: 공개 런타임은 119 paths 구버전이고 /admin/voice-runtime이 없으며 /voice/health는 OpenAI STT/TTS, local sidecar 9882/9883은 내려가 있다. API는 Git 없는 냉동 release cwd라 provenance gate도 닫혀 있다. clean committed source runtime으로 정렬한 뒤에만 물리 마이크 50분독립 human voice-gain pack을 수집한다. - G7 external GATE · 최종 감사 정정run-g7-external-proof-window.pycheck-g7-external-proof.py상태는 external GATE 유지. 물리 마이크 전 코드 P0 3건은 완료됐다. runner 프로세스 exit는 canonical checker exit 0·gate_closed=true에 결속되고, browser Origin vignette.chanpaca.net은 API/WSS/admin/topology host api-vignette.chanpaca.net과 분리된 HTTPS allowlist로 검증되며, 세 artifact 교집합은 ≥3000s + 120초 sampler margin으로 강제된다. Windows proof는 detached-clean HEAD/tree·runner/collector/checker script SHA·exact psutil==6.1.1을 pin한다. 공개 창에서는 legacy PID를 재사용하지 않고 API/cloudflared를 pinned executable/config와 stable release cwd에서 강제 재시작해 safe provenance receipt를 결속한다. 남은 것은 clean-source 실제 배포와 4-artifact 실증이다. + 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 경계는 유지한다. 노트북 로컬 음성 스택 — faster-whisper STT + MeloTTS TTSscripts/local-whisper-stt-server.py · scripts/start-local-whisper-stt.ps1 · voice_stt_provider=local_whisper2026-08-08 소유자 결정으로 음성 양쪽을 노트북 상주 로컬 모델로 정했다. TTS는 처음 Higgs로 잡았으나 연구/비상업 라이선스라 config.py가 운영에서 차단하고 있었고 그 가드를 푸는 건 법적 판단이라, 상업 사용이 허용된 MeloTTS Korean(MIT)으로 바꿔 가드 자체를 불필요하게 만들었다. Kokoro-82M은 Apache 2.0이지만 공식 VOICES.md한국어가 없어 탈락했다. local Whisper는 현재 호스트의 cuDNN 부재를 반영해 small/cpu-int8를 운영 기본으로 고정했고, API health도 MeloTTS model을 실제 provider와 맞춰 보고한다. 합성 시드 8.72초에서 interim 9·final 5·word timestamp 12개, 한 글자 차이 전사를 확인했고 MeloTTS CPU RTF는 0.27~0.28, 합성음→local STT 왕복은 완전 일치했다. current 통합은 launcher/sidecar 80/80·G7 전체 166/166·API voice 71/71·API 전체 921·gateway 58을 통과했다. Higgs 운영 사용은 라이선스 가드가 남아 dev 전용이다. 비-secure origin 회기 리뷰 크래시 수정apps/web/src/lib/uuid.ts · apps/web/src/lib/sha256.ts · apps/web/e2e/insecure-context-uuid.spec.ts격리 NAS 프리뷰(평문 HTTP·비-localhost)에서 드러난 crypto.randomUUIDcrypto.subtle.digest secure-context 의존을 portable fallback으로 교체했다. source-only UUID/SHA 회귀 12/12와 secure/insecure exact digest 회귀를 통과했고, 최종 archive 4d15d055…119d4d의 actual NAS-origin 112/112로 배포 검증까지 닫았다. @@ -1163,9 +1163,9 @@ Public OAuth start/auth/config + /auth/login?provider=google2026-06-30 복구 후 auth config 200, Google configured true, redirect URI https://api-vignette.chanpaca.net/auth/callback, dev-login disabled. Google login start는 GET 302와 __Host-vignette_oauth_state HttpOnly/Secure cookie를 반환한다. Authenticated public /turn proof는 owner storageState가 필요하다. Persona auth boundaryGET /personas2026-06-30 복구 후 public unauth /personas는 401 not authenticated를 반환한다. Public loginauth.spec.ts --grep public login1 passed - Public runtime scripts · source pinstart/watch/boot-public-runtime*.ps1 · install-public-runtime-task.ps1 · register-boot-task.ps1PowerShell 5.1 parser 오류 0. detached-clean stable source, Git commit/tree, watchdog|boot/start script SHA를 runtime 검사·mutation 전에 검증하며 hidden VBS는 구조적으로 pin된 task만 trigger한다. 회귀는 provenance 11개를 포함한 combined 22/22·WSH syntax PASS. 실제 task migration은 아직 미완료: watchdog과 로그온 task action이 shared worktree/legacy 인자를 가리켜 최신 5분 watchdog은 mutation 전에 exit하고 LastTaskResult=1이다. 사용자 승인 clean commit 뒤 동일 stable release root로 두 task를 재등록하고 action pin·result 0·로그온/reboot smoke를 확인해야 한다. - Public API healthhttp://127.0.0.1:8001/health / https://api-vignette.chanpaca.net/health2026-08-09 핸드오프 read-only 확인에서 local/public 모두 status=ok, db=true, engine=true다. DB container는 recovered named volume과 unless-stopped를 유지한다. 이는 source-pin task migration이나 G7 current-source 배포 완료 증거가 아니다. - Public runtime 17:54 read-only snapshothealth + OpenAPI + voice + listeners + Scheduled Taskslocal/public health status=ok·db=true·engine=true, 공개 OpenAPI 119 paths, /admin/voice-runtime 없음, /voice/health openai/gpt-4o-transcribe + openai/gpt-4o-mini-tts, local Whisper 9882·MeloTTS 9883 listener 0. watchdog·로그온 task action은 여전히 legacy shared worktree이고 17:54 KST watchdog LastTaskResult=1이다. 이는 필수 pin 인자 부재로 mutation 전 fail-closed한 값이며 G7 current-source 배포 완료가 아니다. + Public runtime scripts · source pinstart/watch/boot-public-runtime*.ps1 · install-public-runtime-task.ps1 · register-boot-task.ps1detached-clean b34623f3…·tree 32cc85c7…와 exact script SHA에 로그온·watchdog 두 task를 재등록했다. 두 task를 명시 실행해 LastTaskResult=0·Ready를 확인했고 working directory도 같은 stable root다. 실제 Windows 재부팅 후 자동복구 smoke만 별도 운영 gate로 남는다. + Public API healthhttp://127.0.0.1:8001/health / https://api-vignette.chanpaca.net/healthlocal/public 모두 status=ok, db=true, engine=true다. 공개 OpenAPI 126과 /admin/voice-runtime, local Whisper/MeloTTS exact provider/model, queue 4를 확인했다. DB container는 recovered named volume과 unless-stopped를 유지한다. + Public runtime current snapshothealth + OpenAPI + voice + provenance + Scheduled Tasksclean source b34623f3…·tree 32cc85c7…, receipt 9f8d1941…a21bf passed. API/cloudflared는 같은 release root에서 실행되고 두 task result 0이다. 무마이크 rehearsal은 voice/runtime/topology를 모두 통과했으며 public health는 실행 뒤에도 ok·db/engine true다. Public/local/Tailnet login recoveryhttps://vignette.chanpaca.net/login / https://api-vignette.chanpaca.net/health / https://alpaca-home.taile93291.ts.net/login2026-06-30 public web login HEAD 200, public API health 200, auth config 200, Google login start 302. Earlier Tailnet checks remain recorded separately; vnet DNS A records are still 0. Local 5175 loginPLAYWRIGHT_BASE_URL=http://127.0.0.1:5175 auth.spec.tsdesktop/mobile passed Learner/readiness E2Elearner.spec.ts + readiness.spec.ts desktop/mobile14 passed @@ -1205,7 +1205,7 @@ $env:E2E_PUBLIC_STORAGE_STATE=".\node_modules\.tmp\public-auth.json" powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start-public-runtime.ps1
닫은 항목(live 증거): ① engine config 운영값(claude_cli / 9099 / gateway-default, durable, db). ② 상주 엔진풀 probe — 단일 session_id 2회 reused stream, TTFT 1667–4199ms, cost 누적 0.068→0.123. ③ 상주 엔진풀 RSS — gateway session 1개에서 claude -p child RSS 363.3MB, gateway RSS 16.2MB. ④ Postgres RLS/audit smoke 5 checks PASS. ⑤ turn cost telemetry — app.turns client_ai 13행에 provider/model/cost_usd 실적재(합 $1.22). ⑥ 레이아웃 시각 게이트 최신 9/9 + 2026-06-28 적대적 재검수 7/7 accept.
-
환경 제약으로 이 세션에서 못 닫는 항목(정직 표기): 공개 Google OAuth 실제 /turn(OAuth start는 2026-06-30 재확인 완료, 실제 계정 storageState 필요) · 실배포 infra/.env owner-secret fill-in(APP_DB_PASSWORD, OAUTH_GOOGLE_CLIENT_ID, OAUTH_GOOGLE_CLIENT_SECRET, OPENAI_API_KEY, SESSION_SECRET) · vnet.18ka.net/api-vnet.18ka.net 공개 런타임(DNS A record 0, Cloudflare 18ka.net zone 권한 불일치, Google OAuth redirect URI 등록 필요) · 한신대 데이터/SSO 거버넌스(owner/기관 written evidence 필요) · G7 current source 공개 배포, local_whisper/melotts provider/model ready 일치, authenticated public WSS, 명시 동의 물리 마이크와 50분 양방향 soak, 독립 human voice-gain pack · claude_cli↔Messages API 폴백 동일성 · 실제 Windows 재부팅 후 watchdog smoke · Phase 3 파일럿 게이트. owner 결정 7건은 2026-06-30 전건 확정됨. 운영 원칙상 가짜 증거로 DONE 표기하지 않는다. 전체 추적: docs/ops/backlog-2026-06-26.md(B1 구현 후속 · B2 환경제약 · B3 소유자결정 · B4 거버넌스).
+
환경 제약으로 이 세션에서 못 닫는 항목(정직 표기): 공개 Google OAuth 실제 /turn(OAuth start는 확인, 실제 계정 storageState 필요) · 실배포 infra/.env owner-secret fill-in · vnet.18ka.net/api-vnet.18ka.net DNS·OAuth redirect 등록 · 한신대 데이터/SSO 거버넌스 · G7 명시 동의 물리 마이크 3,120초와 공통 3,000초 운영 high-water, 독립 human voice-gain pack, canonical checker exit 0 · claude_cli↔Messages API 폴백 동일성 · 실제 Windows 재부팅 후 watchdog smoke · Phase 3 파일럿 게이트. current source 공개 배포, local voice exact ready, authenticated WSS 무마이크 rehearsal은 완료했다. 운영 원칙상 가짜 증거로 DONE 표기하지 않는다.