diff --git a/docs/README.md b/docs/README.md index 9f11c5a..578e103 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,6 +9,7 @@ |---|---| | **[`dev_dashboard.html`](./dev_dashboard.html)** | **SSOT(단일 진실 공급원)** — 상태·검증 증거·결정·로드맵의 권위 기준 | | **[`TODO.md`](./TODO.md)** | **할 일(안된 것들) 통합** — 흩어진 열린 작업을 주제별로 모은 인덱스 | +| **[`ops/handoff-goal-production-2026-08-29.md`](./ops/handoff-goal-production-2026-08-29.md)** | **최신 정식 배포 핸드오프** — 워크북 9/2, public API 장애, 아바타 decode 감사, fail-closed 후보와 승인·E2E 게이트 | | [`../AGENTS.md`](../AGENTS.md) | 에이전트 작업 지침 원본(OS 선파악·증거 정직성·SSOT 동기화·이미지/아바타 파이프라인) | ## 🗺 원천문서·갭 로드맵 @@ -71,7 +72,7 @@ | [`guides/architecture.md`](./guides/architecture.md) | 시스템 아키텍처(엔진/오케스트레이터/저항/마스킹/음성/평가/데이터) | | [`guides/testing.md`](./guides/testing.md) | 테스트·검증(pytest, typecheck, Playwright E2E 게이트) | | [`DEPLOYMENT.md`](./DEPLOYMENT.md) | docker compose 배포·엔진 어댑터·환경변수·외부공개 운영 | -| [`HANDOFF.md`](./HANDOFF.md) | 최신 세션 인수인계 — 현재 상태·남은 외부 게이트·다음 우선순위 | +| [`HANDOFF.md`](./HANDOFF.md) | 일반 세션 인수인계 진입점 — 최신 정식 배포 상태는 위 2026-08-29 핸드오프 우선 | ## ⚙️ 운영 런북·게이트 트래커 (`ops/`) @@ -81,6 +82,12 @@ | [`ops/nas-preview-g8-rollback-proof-runbook.md`](./ops/nas-preview-g8-rollback-proof-runbook.md) | G8 실제 receipt-bound image rollback 런북 — Gate6 helper 격리 계약 정정(소속 기준), 실행 순서, 금지 사항, 실패 복구 | | [`ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json`](./ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json) | G8 실제 rollback/restore 기계 판독 증거 — helper 격리, 두 executed receipt, HMAC journal 체인, DB lifecycle 집계, 정리 상태 | | [`ops/evidence/google-account-data-recovery-2026-08-29.json`](./ops/evidence/google-account-data-recovery-2026-08-29.json) | Google identity alias 기반 관리자 데이터 복구의 백업·가드 트랜잭션·운영 DB·공개 런타임·Pages 승격 증거(실제 Gmail callback 미완료) | +| [`ops/evidence/google-account-live-browser-proof-2026-08-29.json`](./ops/evidence/google-account-live-browser-proof-2026-08-29.json) | 기존 실서비스 인증 세션의 `yunchan8804@gmail.com`·관리자 권한·온보딩 비전환·복구 데이터 가시성 및 현행 단일 Google CTA 검증 증거 | +| [`ops/evidence/workbook-runtime-sync-2026-08-29.json`](./ops/evidence/workbook-runtime-sync-2026-08-29.json) | 개선관리 완료본의 현행 API·Pages 증거 동기화, 전 시트 수식·시각 검증과 완료 8·검토 3 유지 기록 | +| [`ops/evidence/workbook-req001-completion-sync-2026-08-29.json`](./ops/evidence/workbook-req001-completion-sync-2026-08-29.json) | REQ-001 완료 승격 뒤 개선관리 완료본 6시트·11요구·38수식·수식 오류 0·완료 9/검토 2와 C-001 `pending-valid` 재생성 증거 | +| [`ops/evidence/avatar-decode-audit-2026-08-29.json`](./ops/evidence/avatar-decode-audit-2026-08-29.json) | 아바타 source union 93개·52,973 bytes·inventory SHA와 실제 decode 3 정상/90 실패, 현 DB 참조 2 정상/6 실패를 비식별 집계로 고정한 증거 | +| [`ops/evidence/avatar-image-resilience-recovery-2026-08-29.json`](./ops/evidence/avatar-image-resilience-recovery-2026-08-29.json) | 공개 아바타 404 원인·시점 복구·인증 브라우저 DOM과 공통 이미지 fallback 후보의 privacy-safe 증거 | +| [`ops/evidence/req008-reboot-preflight-2026-08-29.json`](./ops/evidence/req008-reboot-preflight-2026-08-29.json) | REQ-008 실제 재부팅 전 read-only task/runtime 사전점검 스냅샷 — 현재 public outage와 실제 reboot smoke가 이를 대체·완료하지 않음 | | [`ops/evidence/professor-summary-gap-deploy-2026-08-29.json`](./ops/evidence/professor-summary-gap-deploy-2026-08-29.json) | 교수자 검토 큐·요약 카드 12px 분리의 RED→GREEN·7폭/전체 시각 게이트·clean Pages 배포·실서비스 DOM 증거 | | [`ops/public-db-recovery-rehearsal-2026-08-07.md`](./ops/public-db-recovery-rehearsal-2026-08-07.md) | 공개 DB 데이터 교체 사고의 RLS/volume 포렌식, 이중 dump, 격리 복구·최신 migration/API 리허설과 승인형 cutover/rollback 게이트 | | [`ops/server-migration-runbook-draft.md`](./ops/server-migration-runbook-draft.md) | 서버 이관 런북 초안(자택→학교 정보처) — 이식성 이슈·DB dump/restore·엔진 모드 전환·검증 (초안) | diff --git a/docs/TODO.md b/docs/TODO.md index c76146a..92b0187 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -15,13 +15,16 @@ > 이 표는 워크북 ID와 현행 구현을 잇는 얇은 추적표다. 내부 기술 DONE의 focused 증거는 > `guides/testing.md`, 상세 계약은 SSOT `dev_dashboard.html`이 소유한다. C-001은 기술 사전검증과 외부 > 임상 승인을 분리한다. 검토 패킷과 fail-closed 판정기는 준비됐지만 외부 증거가 없으므로 계속 열린 항목이다. +> 완료본은 `outputs/01a04217-f73b-7303-b597-401fa7f5d290/Vignette_개선관리_완료.xlsx`, SHA-256 +> `c832547f30ae0664e54b302c8e9f62cc157f31022ad158d17803d8cac988d8bd`다. 집계는 **완료 9·검토 2·총 11**이며 +> 검토는 C-001 적격 외부 임상 검수와 REQ-008 실제 Windows 재부팅뿐이다. | ID | 상태 | 현행 경계 | |---|---|---| | C-001 | **OPEN · 외부 GATE** | v2 P1 합성 사례 6건·상태별 canonical 판정기와 109·수단 상세 차단·런타임/carry-over/output `ideation_stage <= 3`·4개 공식 source 기술 사전검증은 완료. 사례별 5필드 30개, 청소년 답변 6개, 검토자·소속·자격·검토일·결정 근거·서면 증거/해시·검토 버전/사례 해시를 포함한 승인 10필드가 있어야 닫는다. 현재 `review_complete=false`; F절/B4에서 추적한다. | | C-002 | **DONE · 내부 기술** | 첫 회기 라포 반영·한 초점 열린 질문 체크리스트, 근거 turn 연결, 이후 회기 not-applicable | | C-003 | **DONE · 내부 기술** | 종료 회기 4건 미만 insufficient, 이후 최다 페르소나 비중 0.75 이상 훈련 집중 주의; 임상·공정성 판정 아님 | -| REQ-001 | **READY · 실제 Gmail callback GATE** | provider가 이메일을 검증한 모든 Google 계정은 도메인·사전등록 없이 learner·approved로 즉시 로그인하며 Google 계정 선택기(`prompt=select_account`)를 유지하고 `hd`를 보내지 않는다. Pages production `ef48c0ae…` 승격 뒤 public custom domain은 단일 `Google 계정으로 로그인` CTA 1개·구 선택 버튼 0·dev login 0·console warning/error 0이고 공개 OAuth 시작 E2E 1/1을 통과했다. 실제 Gmail callback과 복구 계정의 관리자 진입·기존 21회기/64턴/평가 6건 확인 전에는 개선관리 상태를 `검토`로 유지한다. | +| REQ-001 | **DONE · 운영 수락** | provider가 검증한 모든 Google 계정은 도메인·사전등록 없이 learner·approved로 로그인한다. Pages `0c60261e…`의 단일 Google CTA·공개 Playwright 2건, 기존 Gmail 인증 세션의 로그인 이메일·관리자 진입·온보딩 비전환·복구 데이터 가시성을 확인했고 소유자가 수락했다. 현재 public API 장애는 별도 운영 복구 게이트이며 이미 닫힌 수락 증거를 지우지는 않는다. | | REQ-002 | **DONE · 내부 기술** | admin protocol draft→active→retired, 라이선스 C/D 외부 LLM 금지, evaluator-only RAG·rollback; migration 17 owner-run/readiness-only | | REQ-003 | **DONE · 내부 기술** | 페르소나 주호소가 JSON 키 순서나 surface 상태보다 우선 | | REQ-004 | **DONE · 내부 기술** | learner 현재 설정 AND 세션 snapshot. OFF는 AI 파생 API 403/UI 무요청·혼합 결과 redaction, 사용자 입력·privacy 보존; teacher/admin 유지 | @@ -30,27 +33,40 @@ | REQ-007 | **DONE · 내부 기술** | 회기 종료를 평가보다 먼저 영속화해 옛 평가 실패 뒤에도 새 회기 생성·턴 진행 가능 | | REQ-008 | **READY · 실제 재부팅 GATE** | 원본 응답 생성 실패는 기본 엔진+live-client readiness, 구조화 done 없는 SSE EOF의 `client_stream_incomplete` 복원과 공개 P20 실제 응답으로 닫았다. 후속 재부팅 복구는 전역 mutex·단계별 상한·프로세스 트리 종료·전체 다운 즉시복구와 PowerShell 5.1 timed `WaitForExit`의 process handle 선확보를 적용했다. 실제 PS5.1 계약 32 passed, detached-clean `44b7835c…`·tree `06133249…`, 5174 자동복구·HTTP 200, watchdog result 0/failcount 0까지 확인했지만 실제 Windows 재부팅 smoke 전에는 개선관리 상태를 `검토`로 유지한다. PC 비종속 상시 호스트 이전도 별도 운영 게이트다. | -현재 공개 API/engine/STT/TTS/cloudflared와 Pages production -`ef48c0ae-374e-41fc-b6fd-03f69b26e946`의 서비스 소스는 detached-clean `dba9b75a…`·tree `14cd4607…`다. 재부팅 복구용 -로그온·watchdog 작업도 같은 root·commit·tree·script SHA로 재등록했고, -60분 상한·`IgnoreNew`·복구 mutex·전체 다운 즉시복구·PowerShell 5.1 build 종료코드 판정을 고정했다. -watchdog의 명시 복구 실행 뒤 웹 5174 HTTP 200, `LastTaskResult=0`, failcount 0과 local/public -`status=ok·db=true·engine=true`를 확인했다. -새 학습자 라포 헤더와 단일 Google 로그인 번들은 custom domain에 공개됐다. 실제 Gmail callback과 Windows 재부팅 smoke는 별도 게이트다. +2026-08-29 최신 read-only 상태에서 정적 public Web과 Pages `0c60261e…`(source `5bf89ff…`)는 유지되지만, +local API 8001은 연결 거부, public API는 530이며 Docker daemon이 없어 DB/API는 **OUTAGE**다. task는 old +detached `dba9b75a…` runtime을 계속 가리킨다. 과거 `status=ok·db=true·engine=true`와 watchdog result 0은 이전 성공 +증거이지 현재 GREEN이 아니다. avatar fail-closed 코드와 upload receipt는 아직 후보이고 배포하지 않았다. --- ## A. 배포·공개 런타임 게이트 [환경] -> 출처: `ops/backlog-2026-06-26.md` B2 · 대시보드 운영 탭 · `ops/tailscale-vnet-runtime-2026-06-27.md` · `ops/public-runtime-watchdog.md` · `HANDOFF.md` +> 출처: `ops/backlog-2026-06-26.md` B2 · 대시보드 운영 탭 · `ops/tailscale-vnet-runtime-2026-06-27.md` · `ops/public-runtime-watchdog.md` · `ops/handoff-goal-production-2026-08-29.md` +- [ ] **public API/DB 복구와 avatar fail-closed 정식 승격** — 허용 source union은 93 objects·52,973 bytes, + inventory SHA-256 `9d703126f78d4fc8330408835d76a7d680276240dc578d6fc9ca420c2f25e6aa`다. 실제 decode는 정상 3·실패 90, + 현 DB 참조는 정상 2·실패 6·missing 0이다. 후보는 손상 bytes/DB reference를 private forensic으로 보존하고 + public static 응답을 404/fallback으로 막으며 decode-valid 객체만 immutable public cache에 제공한다. 신규 UUID 업로드도 + URL 기록·현재 참조·GET/HEAD에서 다시 full decode하고, 업로드 뒤 손상은 current invalid/health fallback에 포함한다. 전체 API/Web/ + PowerShell 회귀, 실제 브라우저 fallback, exact target/total/digest receipt, 후보 SHA와 사용자 배포 승인 전에는 Docker· + API/tunnel·task·DB avatar URL·stable upload root를 바꾸지 않는다. + 현재 Docker engine은 꺼져 있고 public watchdog이 활성이라 daemon 시작 즉시 기존 runtime 복구가 개입할 수 있다. 풀스택 E2E는 + watchdog 일시 중지·비활성화, 고유 DB/container/volume과 56432/58000/55173 포트, exact cleanup, Docker·watchdog 원상복구를 + 명시 승인받은 뒤 `layout-visual-gate` 15/15와 `session-layout` 8/8을 실행한다. +- [ ] **내장 브라우저 G8 사람 게이트 E2E** — 명시적 승인·보류(`keep_quarantine`)·반려(`reject`)와 사유 입력, + 증거 미충족 승인 차단은 typecheck와 route-fixture desktop/mobile **10/10**을 통과했다. 빠른 3.5초/느린 8초 응답에서도 + watchdog overlay 0을 확인했다. Codex 내장 브라우저의 격리 local stateful fixture에서도 8.5초 뒤 overlay 0·heading 정상, + content `keep_quarantine` 뒤 effect 0, 증거 없는 release 승인 disabled→`reject` 뒤 effect 0, 증거 4종 promote 승인 뒤 + lifecycle effect 정확히 1을 공동 확인했다. 로컬 사람 게이트는 GREEN이지만 실DB append-only 결정과 public proof는 + 아직 없으므로 current 운영 G8 전체를 GREEN으로 올리지 않는다. - [ ] **공개 DB 계정·회기 복구 안정화** — 2026-08-07 18:26 KST owner 승인으로 recovered named volume을 공개 `vignette-dev-db:55432`에 전환했다. cutover 기준 users 84/sessions 30/turns 705, Google 계정 16/소유 회기 30, orphan 0, health·engine·OAuth·watchdog가 정상이다. 전환 직전 container와 dump, 원본 volume을 보존한다. 남은 것은 사용자가 Google 재로그인한 뒤 본인 과거 회기가 보이는지 확인하는 일과 자동 백업 운영화다. 기존 인증 세션은 복사하지 않아 재로그인이 필요하다. 2026-08-09 Docker Desktop 중단과 18:02:55 KST Docker Desktop UI의 active DB 직접 stop으로 `db=false`가 - 재발했으나 동일 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 + 재발했으나 동일 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 전에 실패하도록 코드로 고정했다. 공개 API·cloudflared는 detached-clean `a73bcd24…`·tree `b02b3a1b…`로 fresh 승격했고 receipt `47388d58…9b08`가 passed다. local/public health는 `status=ok·db=true·engine=true`, 공개 OpenAPI 126, diff --git a/docs/dev_dashboard.html b/docs/dev_dashboard.html index 7a34176..4b1a60b 100644 --- a/docs/dev_dashboard.html +++ b/docs/dev_dashboard.html @@ -291,7 +291,7 @@
Vignette 커맨드센터팀장 리뷰 · dev status
내 차례 0 - 2026-08-28 KST + 2026-08-29 KST
@@ -300,11 +300,13 @@
project pulse -

지금 위치: G0~G6 · G8 증거 DONE. G7 external proof · C-001 · 재부팅 실증이 남았다.

-

현재: 공개 앱·API·DB와 current NAS 실회기는 GREEN이고 재부팅 복구 task 계약도 보강했다. 다음: 새 Pages 후보 명시 승인 → 실제 Windows 재부팅 자동복구 → G7 mic·human proof.

+

지금 위치: 공개 정적 Web은 유지, Public API·DB는 OUTAGE. 이미지 fail-closed 후보·E2E와 C-001·REQ-008 사람 게이트가 남았다.

+

현재: 배포된 API/task 기준선은 dba9b75a…, Pages는 0c60261e…(source 5bf89ff…)지만 Docker daemon 부재로 local 8001은 연결 거부, public API는 530이다. 아바타 decode fail-closed 변경은 후보 코드일 뿐 미배포라 운영 GREEN이 아니다. G8 차단·보류·반려·승인의 격리 local 내장 브라우저 proof는 GREEN이다. 다음: 전체 통합 GREEN과 G8 실DB/public proof를 확인한 뒤 push/Pages/runtime/task 전환 승인을 받고, 실제 재부팅은 별도 승인으로 실행한다.

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

2026-08-28 재부팅 복구 hardening: 로그온·5분 watchdog을 detached-clean 99779a6a…fbc8·tree 57da86aa…6b91에 재등록했다. 두 task는 ExecutionTimeLimit=PT1H·MultipleInstances=IgnoreNew이고 scheduler 이중 재시도는 제거했다. launcher는 exclusive mutex, API 180초·voice 90초·web build 600초 상한, timeout 시 parent+child process-tree 종료를 적용했고 watchdog은 cloudflared 누락 또는 API/web/voice-sidecar 전체 다운을 debounce 없이 즉시 복구한다. focused 회귀 50 passed, watchdog 18:10:57 KST·boot 18:14:27 KST 수동 실행 결과 0·failcount 0을 확인했다. 이것은 로그인 뒤 복구 증거이며 실제 Windows 재부팅 smoke와 PC 비종속 상시 호스트 이전은 여전히 별도 gate다.

+

2026-08-29 최신 read-only 상태: VignettePublicRuntime과 watchdog은 여전히 old dba9b75a… root를 가리키며, Docker Desktop Linux engine pipe가 없어 DB/API 복구에 실패한다. 정적 로그인 Web 200은 동적 API 정상 증거가 아니다. 운영 변경 승인 전에는 Docker 시작·API/tunnel 재시작·task 재등록·DB/avatar URL 수정·stable upload root cutover를 하지 않는다.

+

2026-08-29 아바타 무결성: 허용 source union은 93 objects · 52,973 bytes · SHA-256 9d703126…e6aa다. 실제 decode는 정상 3·실패 90, 현 DB 참조는 정상 2·실패 6·missing 0이다. 후보는 손상 bytes와 참조를 private forensic으로 보존하되 public serve는 404/fallback으로 막고, decode-valid 객체만 immutable public cache에 싣는다. 이 후보는 전체 API/Web/E2E·내장 브라우저·운영 배포 검증 전까지 GREEN이 아니다.

+

2026-08-29 재부팅 복구 hardening의 이전 성공 증거: Windows PowerShell 5.1의 timed WaitForExit()가 process handle 선확보 없이는 성공한 web build의 ExitCode를 null로 남겨 실패로 오판하는 경계를 수정했다. 실제 PS5.1 계약 32 passed, detached-clean 44b7835c…·tree 06133249…에 로그온·5분 watchdog을 같은 핀으로 재등록했다. 당시 watchdog 3회차 복구로 5174가 자동 기동해 HTTP 200을 반환했고 후속 실행은 LastTaskResult=0·failcount 0, local/public health status=ok·db=true·engine=true였다. 기존 ExecutionTimeLimit=PT1H·MultipleInstances=IgnoreNew·exclusive mutex·bounded wait·process-tree 종료·hard-down 즉시복구 계약도 유지한다. 이것은 로그인 뒤 과거 복구 증거이며 현재 장애나 실제 Windows 재부팅 smoke를 대신하지 않는다.

2026-08-27 Docker stale socket 인시던트·복구: 공개 로그인 화면은 유지됐지만 API가 db=false degraded 뒤 502가 됐다. 원인은 Docker Desktop 4.82.0 백엔드가 이전 비정상 종료에서 남은 0바이트 AF_UNIX reparse socket Docker\run\dockerInferencedocker-secrets-engine\engine.sock을 ERROR 1920으로 제거하지 못해 startup crash-loop한 결함이다. Docker 전체 종료 후 두 부모 IPC 디렉터리를 run.stale-20260827-232006·docker-secrets-engine.stale-20260827-232006으로 이동해 복구 가능하게 보존했고, container·image·volume 생성/삭제/교체 없이 기존 vignette-dev-dbvignette_recovered_prod_20260807만 시작했다. API는 detached-clean bf5f7352…0092·tree c39f917b…c88에서 routine API-only 복구했고 public health 3/3 status=ok·db=true·engine=true를 확인했다. 로그온·5분 watchdog도 같은 root/commit/tree와 exact boot/watchdog/start SHA에 재등록했으며 watchdog LastTaskResult=0·failcount 0이다. 실제 공개 로그인 브라우저는 console error/warning 0이다. authenticated public /turn은 2026-08-28 폐루프를 통과했고 실제 Windows 재부팅만 별도 gate다.

2026-08-18 엔진 readiness 장애·수정: 06:30~10:05 KST 공개 API가 engine=false로 약 3.5시간 degraded였다. 원인은 (1) reasoning_effort=high 콜드 프로브가 20초 타임아웃을 넘기면 실패가 성공과 같은 TTL(운영 1800초)로 캐시되는 게이트웨이 결함, (2) 공개 엔진 claude -p가 소유자 Claude 구독을 개발 에이전트 작업과 공유해 사용량 한도 소진 시 생성이 실패하는 운영 경계다. 워치독은 기본 /ready의 캐시 200만 보고 엔진을 healthy로 오판해 API만 재시작하는 루프에 빠졌다. 수정: 실패 전용 ENGINE_READY_FAILURE_TTL_SECONDS(기본 30초) 분리 + 프로브 타임아웃 20→45초, 회귀 4건 신설(게이트웨이 62/62·backend 986). detached-clean 4771b97c…c880·tree 286723de…c1fa로 API/게이트웨이/워치독·부트 task를 재승격·재등록했고 명시 실행 LastTaskResult=0, 공개 health ok·OpenAPI 126·local voice exact를 재확인했다. 1차 승격은 새 worktree에 apps/api/.env(gitignored 비밀값)가 없어 fail-closed로 실패했다 — 승격 절차에 env 이관 단계가 필요함을 기록한다(약 4분 다운타임).

2026-08-12 인시던트(NAS relay 복구 대기): 공개 API는 health ok·db/engine true·OpenAPI 126·auth 401과 local voice를 유지한다. NAS 프리뷰는 앞선 3/3 degraded·db=true·engine=false에서 15:24 KST local health 3회 타임아웃으로 악화됐고 정적 로그인 화면만 계속 보인다. NAS API의 고정 ENGINE_URL=http://192.168.0.223:9100 대상 listener가 사라졌으며 공개 엔진은 별도 loopback 127.0.0.1:9099에서 정상이다. G8 clean-head candidate 112/112·실제 origin 112/112와 rollback receipt는 완료 증거로 보존하지만, 현 NAS runtime은 relay를 source/secret/task에 결속해 복구하고 health 3/3·auth·OpenAPI·assets·실제 회기를 다시 통과할 때까지 DEGRADED다. 자동 재시작·포트 노출·배포는 실행하지 않았다. G7은 별도로 명시 동의 mic·동시 high-water·human evidence가 남는다.

@@ -318,9 +320,13 @@ Outcome clean E2E 126 · visual 15/15 Alliance G1 baseline 1.2 9/9 · 내부 DONE Tailnet 이전 확인 OK - Public API 126 paths · G1~G8 + Public API OUTAGE · 530/local refused + 이전 OpenAPI 증거 · Public API 126 paths · G1~G8 Direct-runtime preflight APP ROLE OK - critical 3 1차 완료·gate + Avatar decode 3 valid · 90 invalid + Workbook 완료 9 · 검토 2 + Human gate local 10/10 · IAB GREEN + Human gate 실DB/public pending Decision P0 조건부
@@ -344,7 +350,7 @@
🚧 GO를 막는 블로커 0
-
블로커Web production 승격

Cloudflare Pages production 배포 승인

필요: 준비된 99779a6a…fbc8 Web 후보를 Cloudflare Pages production에 업로드한다는 명시 승인.

왜 당신인가: 저장소 코드와 번들을 외부 배포 서비스로 전송하는 운영 변경이다.

승인 문구: Cloudflare Pages production 배포 승인
+
블로커Web/API/runtime 승격

통합 후보 정식 배포 승인

필요: 전체 API/Web/PowerShell 회귀와 내장 브라우저 E2E가 GREEN이고 exact commit SHA가 고정된 뒤, push·Cloudflare Pages·public API/tunnel·두 task·upload root cutover 범위를 한 번 더 확인한다.

왜 당신인가: 외부 배포와 이 PC 운영 런타임·예약 작업을 함께 바꾸는 운영 변경이다. 현재 public API 장애가 있어도 승인 전 mutation은 금지한다.

승인 전제: 후보 SHA·다운타임·보존 범위·rollback 영수증 제시
게이트Phase 3 파일럿 · 데이터

한신대 데이터/SSO 거버넌스

필요: SSO claim 스키마, 추가 축어록 수급, 미성년 원본 활용동의, 개인정보 처리방침에 대한 한신대/데이터 steward의 written evidence.

왜 당신인가: 기관 공문·협의 영역. 로컬 문서 골격은 준비됨(hanshin-data-governance-gate.md).

@@ -365,7 +371,7 @@
🤝 외부·임상팀 조율 0
-
조율위기게이트·평가·이론

임상팀 콘텐츠 (구훈정·어유경)

필요: C1 루브릭 항목·척도·가중치·anchor 예시·컷오프·검수 기준의 임상팀 확정본, CBT 이론별 단계 프롬프트 체인, 위기 스크립트·생명유지서약 문안, H2 평가 골든셋. 코드는 C1 schema/loader/validation scaffold까지만 준비됨.

왜 당신인가: doc3 R&R상 콘텐츠는 임상팀 산출물. 코드는 '편집 가능 구조'만 선제 구축 → 조율·수급 필요.

+
조율C-001·위기게이트·평가·이론

임상팀 콘텐츠·적격 외부 검수 (구훈정·어유경)

필요: C1 루브릭·CBT 체인·위기 문안·H2 골든셋의 임상팀 확정본과, C-001 실제 검수자의 이름·소속·자격·검토 시각, 사례별 판정·근거·수정 요구·재검토·서명 증거를 package/version/hash에 결속한다. 외부 입력 46칸은 현재 의도적으로 공란이다.

코드·내부 브라우저·운영 배포로 대신할 수 없다. 검수자 증거 없이 review_complete=true를 만들거나 워크북을 완료로 조작하지 않는다.

거버넌스계약·일정

스택 정합성·저작권 등재 (L1)

방향은 Node.js 교체 가능성 우선으로 정했다. 남은 일은 FastAPI 유지 사유, 계약 우선 전환 계획, 저작권 등재 문서 반영을 거버넌스 증거로 남기는 것이다.

권고: docs/decisions/backend-node-transition.md 기준으로 신청서/등재 문서의 스택 설명을 정합화한다.

@@ -694,11 +700,15 @@

211차 복구·재검증(2026-08-18 15:05 자동화): 엔진 구독 한도 리셋 직후 NAS 엔진 릴레이 실제 1회 시작이 4종 SHA pin 그대로 passed(영수증 receipt-actual-20260818.json, PID 65328, ready 실생 통과). NAS→릴레이 TCP가 막혀 있던 것은 Python311 인바운드 허용 규칙이 Public 프로필뿐인데 이더넷이 Private이라서였고, LAN 서브넷 한정 9100 허용 규칙 추가(소유자 UAC 승인) 뒤 NAS origin health 3/3 연속 status=ok·db·engine true, auth 401, OpenAPI 126을 실측 — 2026-08-12 이후 처음이다. current GREEN 표기는 actual-origin 실제 회기 turn→review smoke가 남아 보류. 같은 자동화의 직렬 게이트 재실행은 31 passed/14 failed/12 did-not-run로 실패: 파서 수정 후 첫 실행된 breakpoint 실측 스윕이 settings/learner 협폭 결함 91건을 보고했고(아침 실행에선 연쇄 중단으로 미실행), session-mvp·persistence·voice 실패군은 아침 동일 웹 코드 통과에 근거해 스택·데이터 드리프트가 의심된다 — 원인 조사로 이관, 가짜 증거 금지로 게이트 pending 유지. 증거는 docs/ops/evidence/nas-relay-recovery-2026-08-18.json·usecase-tdd-2026-08-18.json이다.

212차 핫픽스(2026-08-18 오후): 공개 POST /sessions/{id}/end 503(소유자 실사용 보고)의 원인은 회기 종료의 pinned_fact upsert가 learner 역할 연결로 실행된 것이었다. app.pinned_fact RLS는 learner에 INSERT(소유 케이스)만 허용하고 SELECT/UPDATE는 AI 컨텍스트·admin/instructor 전용이라 SELECT … FOR UPDATE + INSERT … ON CONFLICT DO UPDATE 조합이 충돌 후보 가시성에서 InsufficientPrivilegeError로 실패하고 fallback 차단이 503으로 노출됐다. 공개 DB 롤백 재현으로 단순 INSERT는 통과·ON CONFLICT 조합은 거부·ai_view=evaluator 컨텍스트는 전체 upsert 통과를 실증했고(bf5f7352), pinned_fact 저장만 같은 learner uid의 AI evaluator 뷰 연결로 분리했다. 검증: 관련 62 passed·app 924 passed, 공개 8001 승격 후 health ok. 엔진이 건강해 deep 평가가 처음 팩트를 반환한 순간 발화한 잠복 결함으로, 아침 degraded 구간엔 팩트가 비어 이 경로가 실행되지 않았다.

213차 복구·전환(2026-08-18 심야): 대청소 사건(node_modules·구 런타임 워크트리·Temp 소실)과 Docker Desktop 사망·whisper 9882 WinNAT 포트 예약·DHCP LAN IP 회수(223→224)가 연쇄 발생했다. 릴레이를 현행 루트 bf5f7352에 같은 4종 핀으로 재기동(r3 영수증)하고 192.168.0.224:9100으로 바인딩(방화벽 규칙 재발행), NAS는 실행 컨테이너 env 전량을 .env(0600)로 재구성해 ENGINE_URL 224 적용 후 api만 재생성했다. 클로드 예산 한도(Reached maximum budget $0.5)가 재발해 NAS ENGINE_MODE를 agy_cli(gemini)로 전환 — 공개는 소유자가 이미 관리자 UI로 agy 전환 완료. 결과: NAS origin health 3/3 status=ok·db·engine true, auth 401, OpenAPI 126, actual-origin 실회기 turn→review smoke 통과(agy 턴 2개→종료 200→리뷰 200) — 2026-08-12 이후 처음으로 201차 current GREEN 조건을 모두 충족했다. 회기 종료 503 핫픽스(bf5f7352)도 소유자 실세션 종료 성공으로 운영 검증. 권고: 공유기 DHCP 예약(호스트 MAC), Docker VM 클럭 동기화(호스트 대비 ~4일 선행 — DB 타임스탬프 오염), NAS 로컬 agy 이전. 증거는 docs/ops/evidence/nas-relay-recovery-2026-08-18.json이다.

-

214차 개선관리 워크북 동기화(2026-08-27): C-002·C-003과 REQ-001~008은 내부 기술 구현 DONE이다. 첫 회기 체크리스트와 종료 회기 기반 훈련 노출 지표를 추가했고, 외부 연구참여자 사전등록은 create에서 pending 고정 뒤 별도 PATCH 승인으로 분리했다. 프로토콜 레지스트리는 draft→active→retired, 라이선스 C/D의 외부 LLM 금지, evaluator-only RAG 색인·rollback을 강제하며 migration 17은 owner-run이고 startup은 readiness-only라 runtime DDL을 하지 않는다. 주호소는 surface보다 우선하고, 새 회기는 persona_id/version을 고정한다. 학습자 AI 피드백은 현재 계정 설정 AND 세션 snapshot일 때만 노출하며 OFF에서는 순수 파생 API 403·기존 share 404·혼합 응답 AI 필드 redaction·UI 파생 endpoint별 요청 0회를 적용한다. 축어록·저장 워크시트·outcome/calibration 입력·multimodal 동의/철회/삭제/raw audio/privacy 원장은 보존하고 alliance는 self-scores-only로 보여주며, privacy 삭제 조작면은 44px 이상·가로 overflow 0을 유지한다. teacher/admin 감독 뷰는 유지한다. 옛 회기 평가 실패는 degraded 리뷰로 남아도 새 회기를 막지 않는다. 헬스는 기본 엔진과 live-client를 함께 확인하고 구조화 done 없는 EOF는 client_stream_incomplete다. 상담자/내담자 이름은 prompt와 구조화 결과에서 [COUNSELOR]/[CLIENT]로 역할 마스킹한다. C-001은 내부 안전 사전검증만 완료했으며 임상 검토자 이름·소속 기관·검토일·서면 결정이 없어 외부 GATE로 계속 연다.

+

214차 개선관리 워크북 동기화(2026-08-27, 2026-08-29 최종 재생성): C-002·C-003과 REQ-001~007은 완료다. 기존 Gmail 인증 세션의 로그인 이메일·관리자 권한·온보딩 비전환·복구 데이터 가시성을 소유자가 수락해 REQ-001을 완료로 승격했다. REQ-008은 실제 내담자 응답과 복구 task 계약은 통과했지만 실제 Windows 재부팅 smoke가 남아 검토다. 완료본은 6시트·11요구·38수식·수식 오류 0, 완료 9·검토 2다. C-001은 내부 안전 사전검증만 완료했으며 적격 외부 검수자의 46개 입력과 서명 증거가 없어 pending-valid 외부 GATE로 유지한다. 외부 검수 입력을 만들거나 완료로 조작하지 않는다.

+

215차 적용(2026-08-28): 관리자 Provider·모델별 원장에서 gemini-3.7-flash-high 토큰은 있는데 비용이 미산정이던 원인을 최신 모델 누락과 단일 고정 rate card로 좁혀 수정했다. Gemini 3.6/3.7 Flash는 출시일과 2026-08-13~12-31 프로모션, 2027 표준 단가를 호출 시작일 기준으로 선택한다. 기존 0달러 행은 동일 계량 시그니처별로 묶어 요청 단위로 다시 가격화해 200K 입력 경계를 보존하고, 캐시 입력 수가 유실된 과거행은 확정값 대신 ≤$0.103489 · 참조 상한, 확정 산정/미산정 혼합은 $…+ · 일부 산정, 상한/미산정 혼합은 미산정 · 일부 상한으로 표시한다. 전체·일별·예산에 비용 확실성을 전파해 불확실한 평균·비중을 숨기고, migration 18의 client turn 기간 인덱스는 CREATE INDEX CONCURRENTLY로 트랜잭션 밖에서 적용해 턴 쓰기를 막지 않는다. 저장된 과거 양수 비용에는 현재 단가 라벨을 덧씌우지 않는다. 화면의 테스트 데이터는 정확한 (e2e, fake-client, input=1, output=1, cost=0) 조합만 원장·예산에서 제외하고 DB 행은 삭제하지 않았다. 검증: focused 105 passed/1 skipped, app+gateway 전체 1102 passed/1 skipped, 새 빈 PostgreSQL 온라인 마이그레이션+통합 1 passed, release agent 31 passed, API type generation/check·typecheck·build, 관리자 desktop/mobile 6 passed. 격리 DB는 자동 삭제했고 공개 배포는 하지 않았다.

216차 REQ-001 로그인 단순화(2026-08-29): 실제로 같은 startOAuth를 호출하던 학교용·다른 계정용 중복 버튼을 단일 Google 계정으로 로그인 CTA로 통합했다. 보조문구는 모든 Google 계정이며 Google authorize의 prompt=select_account는 남겨 공유 기기에서도 계정을 고를 수 있게 하고 특정 Workspace 도메인을 강제하는 hd는 보내지 않는다. Google이 검증한 이메일은 도메인·사전등록 제약 없이 즉시 승인되는 기존 서버 계약을 유지한다. 검증: auth API 41 passed, 직접 영향 desktop/mobile 32 passed, 인증 시각·경계폭 2 passed, 7폭 전체 레이아웃 15 passed, 세션 무회귀 8 passed, typecheck·lint·build 통과. 이 단일 CTA 번들은 아직 공개 미배포라 현재 공개 Pages의 기존 2버튼 DOM을 새 증거로 대체하지 않는다.

+

217차 REQ-008 복구 판정 교정(2026-08-29): Windows PowerShell 5.1에서 web build process handle을 먼저 열지 않고 timed WaitForExit()를 호출하면 정상 종료 뒤에도 ExitCode=$null로 남는 런타임 경계를 제거했다. handle 선확보→bounded wait→refresh→null/nonzero guard 순서를 실제 PS5.1 계약 32 passed로 고정하고, detached-clean 44b7835c…·tree 06133249…에 boot/watchdog을 같은 핀으로 재등록했다. watchdog 복구로 web 5174 HTTP 200, 후속 LastTaskResult=0·failcount 0, local/public health status=ok·db=true·engine=true를 확인했다. 개선관리 완료본 SHA 0a64d1bc…1177와 C-001 기술 증거 원장의 14개 artifact SHA도 14/14 일치시켰다. 실제 Windows 재부팅 smoke와 PC 비종속 상시 호스트 이전은 별도 gate다.

218차 Google 계정 데이터 복구·API 승격(2026-08-29): Gmail 로그인이 새 learner로 갈라져 정식 관리자 데이터가 사라져 보인 원인은 Google subject별 app_user가 둘로 생성된 것이었다. 이메일 자동병합 대신 owner-managed auth_identity_alias를 추가해 canonical 관리자에 Google subject 2개를 명시적으로 연결하고, 세션에는 실제 로그인 이메일을 별도 기록한다. 원본 백업 SHA c4725500…f2e9pg_restore --list로 확인한 뒤 복제 DB에서 복구 트랜잭션을 먼저 통과시켰다. Gmail 중복 계정의 상담 데이터는 0건이지만 설정 1행이 있어 첫 시도는 가드가 전부 rollback했고, 전체 FK 스캔 뒤 겹치는 설정값이 동일함을 확인해 source-only 알림 키만 canonical에 합치고 원본 설정 행은 보존했다. 활성 DB 결과는 canonical 21회기·64턴·평가 6건, 별칭 2·옛 Gmail 세션 0·감사로그 1·고아 0이며 사용자 1175·회기 469·평가 65를 유지한다. API+gateway 1111 passed/1 skipped, release agent 31 passed. detached-clean dba9b75a…·tree 14cd4607…에서 API/cloudflared fresh provenance를 발행하고 public health·DB·engine·voice·OpenAPI 129·auth 401을 확인했으며 boot/watchdog을 같은 핀으로 재등록해 LastTaskResult=0·failcount 0이다. 브라우저의 옛 Gmail 세션은 reload 후 /login으로 철회됐고, 실제 Gmail callback은 사용자 계정 선택 후 최종 확인한다.

219차 단일 Google 로그인 Pages 승격(2026-08-29): detached-clean dba9b75a…에서 typecheck·lint·cosmetic safety와 2회 byte-identical production build를 통과하고 최근 production 5개의 lazy asset 115개를 보존해 714파일을 Pages production ef48c0ae-374e-41fc-b6fd-03f69b26e946로 승격했다. custom domain은 새 entry index-B1rSWL_W.js SHA f8411694…b5bf, login chunk Login-DNNQ624T.js SHA f010f764…9c1d가 clean build와 일치하며, 단일 Google 계정으로 로그인 CTA 1개·구 계정 선택 버튼 0·dev login 0·console warning/error 0이다. 격리 Playwright의 공개 OAuth 시작 계약도 1 passed이고 이전 entry는 JavaScript MIME 200으로 보존된다. 배포별 preview origin은 같은 정적 자산을 받지만 서버 연결 진단을 표시하므로 runtime GREEN으로 기록하지 않는다. REQ-001은 실제 Gmail callback과 복구 계정의 관리자·21회기·64턴·평가 6건 확인 전까지 검토다.

+

220차 개선관리 완료본 현행 증거 동기화(2026-08-29): Vignette_개선관리_완료.xlsx의 상태·수식·서식은 유지하고 개발·기능 이슈!M5:M12임상·교육 이슈!M6:M7의 오래된 API/Pages 배포 근거만 현재 dba9b75a…·tree 14cd4607…·Pages ef48c0ae…로 갱신했다. artifact-tool import→values-only edit→export→reimport 뒤 6개 전 시트와 수정 집중 4개 렌더를 직접 확인했고 수식 오류 0, 완료 8·검토 3·총 11, 임상 checker pending_external_review·review_complete=false를 유지한다. 새 완료본 SHA는 aab6ef52…e26a다. 기존 C-001 사전검증 원장은 당시 14개 해시의 역사 증거로 보존하고, 현행 원장에서 기술 산출물 13/13 불변과 새 워크북 해시를 결합해 현재 패키지 14/14 연속성을 다시 확인했다. 실제 Gmail callback·Windows 재부팅 smoke·외부 임상 승인 없이 상태를 완료로 올리지 않았다. 기계 판독 증거는 docs/ops/evidence/workbook-runtime-sync-2026-08-29.json이다.

221차 교수자 콘솔 표면 간격 교정·공개 승격(2026-08-29): /teach의 검토 큐와 교수자 요약이 독립 Surface인데 부모 .pf-signal-stripgap:0 때문에 테두리·그림자가 맞붙던 원인을 --sp-3=12px로 교정했다. 수정 전 0px를 다시 주입해 새 회귀 검사가 RED가 되는 것을 확인하고 복원 뒤 focused 1 passed, 390~1440 7폭 교수자 gate 1 passed, 전체 layout visual 15 passed, session 무회귀 8 passed, typecheck·design SSOT·lint·build를 통과했다. tracked-clean 5bf89ff4…·tree 29f76aeb…에서 599파일 build 2회 byte-identical, 이전 자산 172개 보존 후 Pages production 0c60261e-cb37-482d-ba42-d91586194c48로 승격했다. 실서비스 1425×1272 DOM은 computed/실측 간격 12px·overflow 0·console warning/error 0이고 custom/preview의 Professor-BfR874KA.css SHA 63dbe2c7…7fff가 clean build와 일치한다. 증거는 docs/ops/evidence/professor-summary-gap-deploy-2026-08-29.json이다.

+

222차 REQ-001 완료·개선관리 재생성(2026-08-29): 기존 실서비스 인증 세션은 yunchan8804@gmail.com으로 설정·관리자 콘솔에 접근하고 온보딩으로 되돌아가지 않으며, 학습 이력 20건·리뷰 필요 6건을 표시했다. 소유자가 복구 데이터 가시성을 수락했고 최신 Pages 0c60261e…의 단일 Google CTA 1개·구 선택 버튼 0·dev login 0·무제한 도메인·공개 Playwright 2 passed를 함께 확인해 REQ-001을 완료로 승격했다. 개선관리 완료본은 artifact-tool 구조 추출로 6시트·11개 고유 요구·38수식·오류 0·완료 9/검토 2를 확인했다. C-001은 패키지 8/8·기술 사례 6/6·canonical checker 정상의 pending-valid이며 외부 입력 46칸은 공란으로 보존했다. 완료본 SHA는 c832547f…d8bd, sidecar SHA는 8c9618f0…a610이고 REQ-008 실제 Windows 재부팅 smoke와 C-001 외부 임상 승인만 검토로 남는다.

래스터만 사용이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.
기능 우선메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.
@@ -1109,7 +1119,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-28 현재 수집은 1138 tests / 62 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-29 현재 수집은 1158 tests / 64 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 완료. @@ -1119,11 +1129,11 @@ Outcome & Alliance OS G4/G5 callerpytest test_session_learning_producer.py test_deliberate_practice.py test_deliberate_practice_store.py test_calibration_transfer.py test_calibration_transfer_store.py / scripts/smoke-session-learning-producer.pyfocused 100 passed, 전체 API 855 passed. 실제 종료 회기·durable turn 2개·ready 평가에서 production caller가 G4 처방 원장 5종을 각 1개 생성하고 deterministic replay한다. G5는 prediction lock 전 observation 0, lock callback 뒤 failed 독립 관찰과 evaluator model-run 각 1개이며 replay 중복 0이다. learner/teacher projection이 일치하고 mastery/pass/assessment/transfer 자동 승격은 전부 0건이다. 합성 교육 fixture이며 임상·실제 숙달 주장이 아니다. 학생 자기주도 전체 루프 UInpx playwright test e2e/self-directed-learning-loop.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --reporter=dot / npx playwright test e2e/alliance-pulse.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=2 / npm run typecheck / 고정 캡처 직접 QA실제 src 홈 추천→목표 선택→텍스트/SSE 회기→종료·리뷰→G4 처방 키보드 CTA→새 회기 재연습 시작이 desktop/mobile 2/2, typecheck를 통과했다. 페이지 overflow 0, 홈 CTA 44px·4.5:1 이상 대비, typed launch intent와 replay 모드 보존, 내부 criterion/counterevidence/UUID 비노출을 확인했다. 390×844·320×568 활성 회기는 아바타/문구 겹침 0과 축어록/입력창 내부 포함을 통과했다. 320px 리뷰 1~5 척도는 다섯 선택지 44px 이상·내부/페이지 overflow 0이고 전체 desktop/mobile 8/8이다. 모든 미소유 API는 fixture 404이며 실제 로그인/API/DB 증거가 아니다. Contract SSOT aggregate DTOpy -3.11 -X utf8 -m pytest -p no:cacheprovider app/test_evaluation_persistence.py app/test_evaluator_model_routing.py app/test_teacher_dashboard.py app/test_rbac_idor.py app/test_session_turn_persistence.py -q / npm run check:api-types / npm run typecheck / npm run build50 backend passed; learner sessions, session review/worksheet, teacher dashboard, session start/detail DTOs use generated ApiSchema aliases with UI fallback. Stage responses are OpenAPI enum unions, including review phase key/label, reached phase, evaluation summary/trigger responses, and teacher session/growth stage. .github/workflows/api-contract.yml runs npm run check:api-types on API/Web contract changes. - 개선관리 C-002·C-003 / REQ-001~008pytest app/ -q / pytest engine_gateway/ -q / 항목별 focused pytest·DB/browser E2E / npm run check:api-types / npm run build내부 기술 DONE. 2026-08-28 최종 API 1002 passed, gateway 68 passed, Ruff·API type check·typecheck·lint·production build PASS. focused: C-002 3, C-003 11, REQ-001 auth 41 + callback access-log redaction 6 + OAuth UI desktop/mobile 4 + route-mock desktop/mobile 2 + 실제 관리자 DB/browser lifecycle 1, REQ-002·005 26(경고 1) + protocol 실제 DB lifecycle 1 + persona 실제 DB/browser lifecycle 1, REQ-003 34, REQ-004 직접 정책 85·관련 route/read-model 163·desktop/mobile 2, REQ-006 24, REQ-007 관련 163·live/session 50·DB E2E 1, REQ-008 health 1 passed. Google OIDC는 provider-verified 이메일을 도메인·사전등록 없이 learner·approved로 허용하고 suspended는 보존한다. 실제 관리자 E2E는 승인 전 403/대기→승인 후 동일 세션 200→피드백 OFF 영속 재조회→비활성화·세션 0을, persona E2E는 작성→승인→catalog→주호소→exact ID/version pin→controlled SSE→DB 2턴과 exact cleanup/설정 원복을 확인했다. 최종 레이아웃 재실행은 시각 게이트 15/15·포커스 106/106·세션 8/8, 실패·skip 0이며 격리 포트와 프로세스를 모두 종료했다. 전체 Playwright 현 작업트리 GREEN 수치로 환산하지 않는다. - 개선관리 C-001 외부 임상 승인scripts/check-clinical-crisis-review.py / run-clinical-crisis-technical-observations.py / data/clinical/p1-crisis-review-cases.json / docs/ops/clinical-crisis-protocol-review-2026-08-27.md내부 기술 READY · 외부 GATE 미완료. v2 P1 합성 사례 6건과 상태별 canonical fail-closed 판정기를 유지한다. 생성·스트림 실제 경로 6/6, 런타임 패키지 8개 HEAD·작업트리 SHA 일치, focused 90 passed·Ruff PASS를 확인했다. 개선관리 완료본은 6번째 C-001 외부검토 시트에서 사례별 5필드 30개·청소년 답변 6개·검토자 자격 포함 승인 10필드·서명 증거를 받고 canonical checker와 패키지 해시가 모두 맞을 때만 완료로 전파한다. 현재 gate는 pending-valid지만 외부 결정 0건·review_complete=false라 10 완료/1 검토/총 11을 유지한다. + 개선관리 C-002·C-003 / REQ-001~008pytest app/ -q / pytest engine_gateway/ -q / 항목별 focused pytest·DB/browser E2E / npm run check:api-types / npm run build완료 9 · 검토 2. C-002·C-003과 REQ-001~007은 요구·기술 증거가 완료됐다. 2026-08-29 API 1074 passed/1 skipped, gateway 68 passed, typecheck와 G8 focused desktop/mobile 10/10이 PASS다. 격리 local Codex 내장 브라우저는 8.5초 overlay 0·heading 정상, content 보류와 증거 없는 release 반려 effect 0, 증거 4종 promote 승인 lifecycle effect 1을 확인했다. 이는 local stateful fixture GREEN이며 실DB/public proof가 아니다. REQ-001은 기존 Gmail 인증 세션의 관리자 권한·온보딩 비전환·복구 이력 가시성을 확인하고 소유자가 수락했다. REQ-008은 공개 P20 실제 응답과 복구 계약을 확인했지만 실제 Windows 재부팅 smoke가 없어 검토다. C-001은 별도 외부 GATE다. 전체 Playwright 현 작업트리 GREEN 수치로 환산하지 않는다. + 개선관리 C-001 외부 임상 승인scripts/check-clinical-crisis-review.py / run-clinical-crisis-technical-observations.py / data/clinical/p1-crisis-review-cases.json / docs/ops/clinical-crisis-protocol-review-2026-08-27.md내부 기술 READY · 외부 GATE 미완료. v2 P1 합성 사례 6건과 상태별 canonical fail-closed 판정기를 유지한다. 생성·스트림 실제 경로 6/6, 런타임 패키지 8개 HEAD·작업트리 SHA 일치, focused 90 passed·Ruff PASS를 확인했다. 현행 개선관리 완료본 SHA는 c832547f…d8bd이며, 이전 C-001 기술 사전검증 원장의 0a64d1bc…1177과 8/3 동기화본 aab6ef52…e26a은 역사 스냅샷으로 보존한다. 후속 원장은 6시트·11요구·38수식·오류 0과 현재 package match를 기록한다. 6번째 C-001 외부검토 시트에서 사례별 5필드 30개·청소년 답변 6개·검토자 자격 포함 승인 10필드·서명 증거를 받고 canonical checker와 패키지 해시가 모두 맞을 때만 완료로 전파한다. 현재 gate는 pending-valid지만 외부 입력 46칸은 공란이고 review_complete=false다. REQ-001은 완료됐고 REQ-008 재부팅 실증과 C-001 외부 승인만 남아 9 완료/2 검토/총 11을 유지한다. SEO/GEO share cardspytest app/test_session_share.py app/test_session_turn_persistence.py -q / npm run generate:api-types / npm run typecheck21 passed; session share creates hashed-token public unfurl payload without raw transcript, revoked token returns 404, OpenAPI generated share DTOs, review screen share button typechecks. Static robots.txt/sitemap.xml/llms.txt added. - Backend pytest baselinepytest -q app2026-08-28 전체 실행 1002 passed. - X2 evaluator routing/cache/cost trendpython -X utf8 -m pytest -p no:cacheprovider app/test_llm_pricing.py app/test_admin_ops.py app/test_usage_report.py engine_gateway/test_provider_registry.py engine_gateway/test_gateway_model.py -q / API type generation/check / web typecheck/build / admin focused E2E·layout visual gate / authenticated public API smoke최신 backend 439 passed, gateway 45 passed, desktop/mobile E2E 2 passed, 7폭 focused visual gate 1 passed. Claude CLI SDK 비용 추정값과 Agy/Gemini·Codex·Claude API 공식 참조단가를 분리하고, 기존 0달러 행의 조회 시 보정·단가 미등록 모델의 미산정 표시·예산 합산·리포트 경고까지 고정했다. Claude 토큰은 전체 agent tree와 캐시 입력을 포함한다. 과거 0/0 Claude 442건은 로컬 JSONL의 실제 usage와 유일 일치한 169건만 백필했고, 273건은 token_unmetered_turns로 남겼다. 인증된 공개 관리자 화면은 확인 시점 30일 Claude 183건 중 계량 125·미계량 58건을 표시했다. + Backend pytest baselinepytest -q app2026-08-29 전체 실행 1074 passed / 1 skipped. + X2 evaluator routing/cache/cost trendpython -X utf8 -m pytest -p no:cacheprovider app/test_llm_pricing.py app/test_admin_ops.py app/test_admin_usage_postgres.py app/test_usage_report.py engine_gateway/test_provider_registry.py engine_gateway/test_gateway_model.py -q / 격리 PostgreSQL / API type generation/check / web typecheck/build / admin focused E2E2026-08-28 focused 105 passed/1 skipped, app+gateway 전체 1102 passed/1 skipped, 새 빈 PostgreSQL 온라인 마이그레이션+통합 1 passed, release agent 31 passed, desktop/mobile E2E 6 passed. Claude CLI SDK 비용 추정값과 호출 시점 Agy/Gemini·Codex·Claude API 공식 참조단가를 분리한다. Gemini 3.6/3.7 유효기간, 요청별 200K 구간, 과거 캐시 미보존 행의 reference_upper_bound, 확정 산정/미산정 partial, 상한/미산정 partial_upper_bound, 전체·일별·예산 certainty, 정확한 (e2e, fake-client, input=1, output=1, cost=0) 원장 제외와 리포트 경고를 고정했다. 동일 계량 시그니처 SQL 집계와 migration 18의 concurrent 기간 인덱스로 90일 원장의 raw-row fetch/sort를 제거하고 배포 중 turn 쓰기 잠금을 피한다. 과거 0/0 Claude 442건은 로컬 JSONL의 실제 usage와 유일 일치한 169건만 백필했고 273건은 token_unmetered_turns로 남겼다. 이번 변경은 로컬 검증만 했고 공개 런타임은 미배포다. H3 raw source isolationpython -B -m pytest -p no:cacheprovider app/test_persona_review.py app/test_live_coach_sources.py -q38 passed; persona source registration records raw hash-only artifacts separately from sanitized evaluator-only RAG chunks, and rag.index_document() rejects sensitivity=3/raw-marker chunks before DB access. H3 persona itemized authoring UInpm run typecheck / npm run build / npm run check:api-types / npx playwright test e2e/teacher.spec.ts --project=chromium-single-run --workers=1 / npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --workers=1 / npx playwright test e2e/session-layout.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1Typecheck/build/API type drift check passed; teacher PersonaStudio focused 8 passed including structured list payload and labeled prompt preview without raw JSON; visual gate 9 passed with the prompt tab opened; session-layout desktop/mobile 8 passed. H2 session review 3-column workbenchnpm run typecheck / npm run build / npx playwright test e2e/session-review.spec.ts --project=chromium-desktop --workers=1 / npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --workers=1Typecheck/build passed; 3 focused review E2E passed; 9 visual gates passed with dark-theme assertion. Filled learner review uses overview/flow, transcript, and evaluation rail as a 3-column desktop workbench with worksheet below; empty review remains 2 columns or less to avoid sparse gaps. @@ -1152,7 +1162,7 @@ OAuth/SAML admin landingC:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -X utf8 -m pytest -p no:cacheprovider app/test_auth_providers.py -q / public runtime restart36 passed; OAuth/SAML callback now normalizes generic saved next paths such as /learn and /teach to /admin for admin-entitled users while preserving deep links such as /learn/session/.... Live proof after commits 998acb44/6b6241f4 and latest boot-diagnostic deploy b67fd5d4: local/public /health returned prod, db=true, engine=true; custom domain now serves assets/index-R5KK7hZI.js/assets/index-DzdAkRsn.css plus boot diagnostic HTML; unauthenticated /personas remains 401. Session read-model DB readinesspython scripts\check-deploy-preflight.py --skip-db --env-file infra\.env.example --allow-placeholder-secrets / https://api-vignette.chanpaca.net/health2026-06-29 prod 503 원인은 운영 DB의 app.turns.provider_events 컬럼 누락이었다. 운영 DB hotfix 후 /teacher/dashboard code path는 source=database로 복구됐다. 현재 db.healthcheck(), runtime table readiness, deploy preflight DB mode는 app.turns 음성 메타 컬럼 5개(audio_ref, silence_ms, speech_rate, barge_in, provider_events), app.session_review_status worksheet 컬럼, app.safety_events 필수 컬럼을 함께 검증한다. 2026-06-30에는 Docker Desktop/DB 중단으로 public API 530/error code 1033이 재발했지만, Docker Desktop/DB 재기동 뒤 public health가 environment=prod, db=true, engine=true로 복구됐다. Admin usage persistencepython -m pytest app/test_admin_ops.py app/test_runtime_policy.py -q / authenticated local public-API smoke26 passed; /admin/usage returns 200 with source=database, durable=true. Cloudflare blocked raw Python public smoke with 1010, so app-level HTTP was verified against 127.0.0.1:8001 using the same prod process. - Admin AI operations subpagenpx playwright test e2e/admin.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --grep="shows detailed AI metering" / npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --workers=1 / public-admin-visual.spec.ts --grep="shows the live Codex and Agy model catalogs"/admin/ai는 7·30·90일 DB 원장, 비용·토큰·토큰 계량 커버리지·호출당 단가, 일별 비용, provider/model breakdown, evaluator cache를 표시하고 엔진 설정을 실제 저장한다. 비용은 SDK 추정·Provider 보고·참조단가·미산정을 구분한다. 토큰 입력은 비캐시·캐시 읽기·캐시 생성 합계이며, 실제 usage가 복구된 행은 토큰과 계량/전체 회 커버리지를, 복구 불가 0/0 행은 미계량을 표시한다. 최신 focused desktop/mobile 2 passed, 7폭 layout 1 passed, 실제 공개 관리자 브라우저 1 passed다. + Admin AI operations subpagenpx playwright test e2e/admin.spec.ts e2e/full-sweep-admin-ai.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --grep="shows detailed AI metering|shows partial AI cost|does not present a partial upper bound" / app/test_admin_usage_postgres.py/admin/ai는 7·30·90일 DB 원장, 비용·토큰·토큰 계량 커버리지·호출당 단가, 일별 비용, provider/model breakdown, evaluator cache를 표시하고 엔진 설정을 실제 저장한다. 비용은 SDK 추정·Provider 보고·참조단가·참조 상한·일부 산정·일부 상한·미산정을 구분한다. 과거 캐시 미보존 보정값은 ≤$…, 확정 산정/미산정 합계는 $…+, 상한/미산정 혼합은 미산정으로 표시한다. 전체·일별·예산의 불확실한 평균·비중은 숨기고 예산은 indeterminate를 표시한다. 2026-08-28 새 빈 PostgreSQL 마이그레이션+통합 1 passed와 desktop/mobile 6 passed를 확인했고 공개 관리자 브라우저는 이번 변경에서 재검증하지 않았다. Synthetic health samplerrecord_admin_health_sample(), record-admin-health-sample.py, install-health-sampler-task.ps1Backend focused 31 passed. Python compile/help passed; PowerShell parser + -PrintOnly passed. Local one-shot appended 5 service rows to app.admin_health_event: status ok, engine_mode claude_cli. This remains sample history, not an SLA claim. Health retention/rollupadmin_health_daily_rollup, maintain-admin-health-events.py, /admin/uptimeBackend focused 36 passed. Python compile/help passed. Local dry-run returned rollup_event_count=0, prunable_event_count=0. Uptime summary now combines raw samples with daily rollups when raw rows have been pruned; detailed events stay raw-only. Ticket duplicate linkingsupport_ticket.fingerprint, parent_ticket_id, /admin/ticketsBackend focused 38 passed. API types, web typecheck, and build passed. Admin tickets E2E 2 passed after restarting local API 8000 on the new code. Duplicate handling is deterministic hint + admin manual parent link/unlink only; no automatic merge, escalation, issue, PR, or thread creation. @@ -1206,10 +1216,10 @@ Public OAuth start/auth/config + /auth/login?provider=google2026-08-28 public auth config 200, Google configured true, allowed_email_domains=[], redirect URI https://api-vignette.chanpaca.net/auth/callback, dev-login disabled. 로그인 DOM은 모든 Google 계정을 명시하고 실제 Google 선택기에 yunchan@twentyoz.kryunchan8804@gmail.com이 함께 노출됐다. 기존 Google 계정 선택→callback→/admin 성공을 확인했다. 신규 Gmail 선택은 Vignette 계정 생성이므로 사용자 행동시점 확인 뒤 별도 실증한다. 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.ps12026-08-28 detached-clean 99779a6a…fbc8·tree 57da86aa…6b91에 로그온·watchdog 두 task를 재등록했다. action working directory/root/commit/tree/SHA pin, PT1H, IgnoreNew, scheduler retry 0은 PASS다. focused 회귀 50/50 뒤 watchdog 18:10:57 KST·boot 18:14:27 KST 수동 실행은 모두 LastTaskResult=0, failcount 0이었다. 실제 Windows 재부팅 자동복구 smoke는 별도 운영 gate다. - Public API healthhttp://127.0.0.1:8001/health / https://api-vignette.chanpaca.net/health2026-08-28 17:11:47 KST local/public 모두 status=ok·environment=prod·db=true·engine=true. voice는 local/public 모두 local_whisper small·melotts-korean·WS queue 4, web은 local/public 200과 동일 asset index-DJPgoeJy.js/index-CXOy3QyV.css를 반환했다. DB는 백업 vignette-dev-db-vignette-20260828-065331Z.dump를 검증하고 recovered named volume을 보존한 채 migration 17을 적용했다. - Public runtime current snapshothealth + provenance + Scheduled Tasks + Pages현재 동작 중인 API/engine/web/STT/TTS/cloudflared와 Cloudflare Pages production 1f1ddf18-9d5c-4d83-95a7-8cd71245e646은 clean source 2a396361…89c 계열이다. 다음 장애/로그온 복구 task만 99779a6a…fbc8에 pin했다. 새 학습자 헤더를 포함한 dist는 714파일·assets 164개로 빌드하고 최근 production 5세대를 보존했지만, Pages upload는 명시 승인이 없어 실행하지 않았다. - Public/local/Tailnet login recoveryhttps://vignette.chanpaca.net/login / https://api-vignette.chanpaca.net/health / https://alpaca-home.taile93291.ts.net/login2026-08-28 public web 200, public API health 200, auth config 200, Google login start와 callback 성공, P20 실제 회기·응답·종료·평가 폐루프 성공. Earlier Tailnet checks remain recorded separately; vnet DNS A records are still 0. + Public runtime scripts · source pinstart/watch/boot-public-runtime*.ps1 · install-public-runtime-task.ps1 · register-boot-task.ps12026-08-29 최신 read-only 확인에서 두 task는 old detached dba9b75a… runtime을 계속 가리킨다. Docker daemon 부재로 runtime task는 실패했고 watchdog도 DB/API를 복구하지 못한다. 새 total-size/decode receipt 후보는 미배포이며, 후보 통합 GREEN·사용자 승인 전 task 재등록이나 runtime 재시작을 하지 않는다. 실제 Windows 재부팅 자동복구 smoke도 별도 운영 gate다. + Public API healthhttp://127.0.0.1:8001/health / https://api-vignette.chanpaca.net/health2026-08-29 최신 상태는 OUTAGE다. local 8001은 연결 거부, public API는 530이며 Docker Desktop Linux engine pipe가 없다. 정적 public Web 200은 API·DB GREEN을 뜻하지 않는다. 2026-08-28의 status=ok·db=true·engine=true와 voice exact 값은 과거 성공 증거로만 보존한다. + Public runtime current snapshothealth + provenance + Scheduled Tasks + Pages배포된 동적 런타임/task 기준선은 clean commit dba9b75a…·tree 14cd4607…, Cloudflare Pages production은 0c60261e-cb37-482d-ba42-d91586194c48(source 5bf89ff4…)다. 현재 API/DB는 장애이고 fail-closed avatar 후보와 새 upload receipt는 아직 이 기준선에 승격되지 않았다. 후보와 deployed baseline을 분리하며, 승인 전 Docker/API/tunnel/task/DB/upload-root mutation을 하지 않는다. + Public/local/Tailnet login recoveryhttps://vignette.chanpaca.net/login / https://api-vignette.chanpaca.net/health / https://alpaca-home.taile93291.ts.net/login2026-08-28 Google callback→관리자·P20 실제 회기 폐루프는 유효한 과거 증거다. 2026-08-29에는 public API 530으로 신규 callback·관리자·G8 실DB E2E를 재검증할 수 없으므로 현재 운영 GREEN으로 재사용하지 않는다. public Web은 정적 로그인 화면만 200이다. 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 Learner growth headeruc-learner-home-dashboard.spec.ts --grep "성장 지표 라포 헤더"2026-08-28 chromium desktop/mobile 2 passed. 라포 문구 부모를 inset surface에서 plain div로 바꾸고 computed background transparent·border/radius/padding 0을 고정했다. typecheck·design SSOT·cosmetic filter safety도 통과했으며 Pages에는 아직 미배포다. @@ -1249,7 +1259,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.
-
환경·외부 승인 때문에 아직 못 닫는 항목(정직 표기): 새 학습자 헤더 Cloudflare Pages production upload 명시 승인 · 신규 Gmail 선택→Vignette 계정 생성은 사용자 행동시점 확인 필요 · C-001 사례별 판정·근거·수정 요구·재검토·검토일 30개, 청소년 답변 6개, 임상 검토자 이름·소속·자격·결정 근거를 포함한 승인 10필드와 서명 증거/해시·검토본 고정 · 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 파일럿 게이트. C-001 내부 검토 패킷·canonical 판정기·상한 수리와 pending-valid 검증, current source 공개 배포, generic Google callback, P20 실제 턴·종료·평가, local/public voice exact ready, authenticated WSS 무마이크 rehearsal은 완료했다. 운영 원칙상 가짜 증거로 DONE 표기하지 않는다.
+
환경·외부 승인 때문에 아직 못 닫는 항목(정직 표기): public API/DB 장애 복구와 avatar fail-closed 후보의 전체 회귀·배포·실브라우저 fallback · G8 관리자 사람 게이트의 승인형 실DB append-only 증거와 public proof(local stateful in-app browser는 GREEN) · C-001 사례별 판정·근거·수정 요구·재검토·검토일 30개, 청소년 답변 6개, 임상 검토자 이름·소속·자격·결정 근거를 포함한 승인 10필드와 서명 증거/해시·검토본 고정 · 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 파일럿 게이트. REQ-001은 Gmail 인증 세션·관리자·복구 데이터 수락으로 완료했다. C-001은 pending-valid 기술 사전검증뿐이며 외부 검수 입력을 조작하지 않는다. 운영 원칙상 가짜 증거로 DONE 표기하지 않는다.