회기 집계와 기록 복귀 및 감독 근거 링크 수정
Some checks failed
API contract / OpenAPI type drift (push) Failing after 4m46s

This commit is contained in:
Yun Chan 2026-09-09 14:41:54 +09:00
parent aa951c6c4a
commit 1306c524c1
20 changed files with 4631 additions and 60 deletions

View file

@ -291,7 +291,7 @@
<div class="brand"><span class="mark" aria-hidden="true"></span><span>Vignette 커맨드센터<small>팀장 리뷰 · dev status</small></span></div>
<div class="head-right">
<a class="owner-pill" href="#owner"><span class="d" aria-hidden="true"></span>내 차례 <b id="pill-owner">0</b></a>
<span class="stamp">2026-09-01 KST</span>
<span class="stamp">2026-09-09 KST</span>
</div>
</header>
@ -300,9 +300,10 @@
<section class="pulse">
<div class="pulse-main">
<span class="eyebrow">project pulse</span>
<h1>지금 위치: <em>NAS <code>vignette-prod</code> 정식 배포 완료 기록(SHA <code>dce85620</code>)</em> — 2026-09-01 당시 배포·실계정 회기 검증·데이터 보존 증거를 남겼다. 신규 REQ-009~011 접수와 C-001·REQ-008 외부 게이트가 남았다.</h1>
<h1>지금 위치: <em>개선관리 원본 14개 재점검</em> — 2026-09-09 읽기 전용 확인에서 완료 13·검토 1(C-001)이다. REQ-009~011의 로컬 재검증은 수용했고, REQ-010 추가 수정은 미배포다. 2026-09-01·09-08 배포는 당시 증거이며 오늘의 새 live 검증이 아니다.</h1>
<p class="pulse-state"><b>실배포 CUA 128:</b> 카탈로그는 생성됐지만 전체 검증은 미완료다. 실제 배포에서는 H09(기록 검색·필터 복귀)와 T18(감독·연구 drilldown)이 RED로 남아 있다. 두 항목은 각각 local 16 passed와 API 12 passed·local 교수자 15 passed로 수정 검증했으나, 배포 재검증이 열려 있다. 관리자와 일반 학습자 로그인에서 학습자의 `/admin`·`/teach`→`/learn` 차단, P4 추천 일치와 허용된 관리자 P16 1개·학습자 P4 1개 회기 종료를 확인했다. 순수 teacher·OFF 계정, 교수자 쓰기, 모바일과 독립 관찰자 공개 검증은 남아 있다.</p>
<p class="pulse-state"><b>2026-08-31 배포 파이프라인 재정립(역사 기록):</b> git 관리·배포는 <code>git.chanpaca.net</code>(Forgejo) 중심으로 이관했고, <code>github.com</code>(origin)은 private 백업/미러로 유지한다. 배포 대상은 NAS Production(<code>docker-compose.nas.yml</code>, <code>vignette-prod</code>)이며 이 PC는 개발용이다. Cloudflare tunnel은 NAS ingress의 현재 경로이므로 대체 ingress 검증 전에는 제거하지 않는다. 문서 <a href="./ops/deployment-pipeline.md">deployment-pipeline.md</a>.</p>
<p class="pulse-state"><b>최근 확인된 배포 증거(2026-09-01 당시):</b> Forgejo master <code>dce85620</code>를 NAS에서 직접 clone·빌드해 <code>vignette-prod</code> api/engine/web을 교체했고, Cloudflare Pages production도 새 빌드(<code>index-BFKGXJQi.js</code>, 이전 세대 자산 보존)로 배포했다. 사전 dump <code>cab6826b…</code>(11.0MB·TOC 1783)·env 백업·구 이미지 보존으로 롤백 경로를 고정했다. 중복 활성 회기 14쌍 30행은 최신 유지 정책으로 종료(영수증 보존·삭제 0)하고 마이그레이션 20/21/22를 온라인 적용했다. 이 과정에서 mig22의 <code>name[]=text[]</code> 캐스트 결함과 master의 게이트웨이 openai provider 누락 회귀를 발견해 즉시 교정했다(테스트 71 passed). 배포 당시 public health <code>ok·db/engine true</code>, OpenAPI 200, <code>/auth/me</code> 401, dev-login 404, 데이터 집계 전후 동일(app_user 1380/sessions 618/turns 1743)을 확인했다. 증거: <a href="./ops/evidence/nas-prod-deploy-2026-09-01.json">nas-prod-deploy-2026-09-01.json</a>. <b>headful 실계정 폐루프도 당시 완료:</b> NAS env의 OAuth secret 오류(<code>invalid_client</code>)를 교정한 뒤 소유자 실계정 로그인→기존 회기 20건 표시(데이터 보존)→새 사례 회기 생성(mig22 실증)→실턴 SSE·AI 응답→종료→리뷰 생성까지 GREEN(sessions 619·turns 1745·case_profile 566). 일일 검증형 DB 백업 sidecar 첫 덤프도 11.2MB로 성공했다. <b>다음:</b> 신규 REQ-009~011 재현, C-001 외부 임상 검수, NAS 재부팅 자동복구 smoke, 백업 실패 알림·off-host 복제.</p>
<p class="pulse-state"><b>최근 확인된 배포 증거(2026-09-01 당시):</b> Forgejo master <code>dce85620</code>를 NAS에서 직접 clone·빌드해 <code>vignette-prod</code> api/engine/web을 교체했고, Cloudflare Pages production도 새 빌드(<code>index-BFKGXJQi.js</code>, 이전 세대 자산 보존)로 배포했다. 사전 dump <code>cab6826b…</code>(11.0MB·TOC 1783)·env 백업·구 이미지 보존으로 롤백 경로를 고정했다. 중복 활성 회기 14쌍 30행은 최신 유지 정책으로 종료(영수증 보존·삭제 0)하고 마이그레이션 20/21/22를 온라인 적용했다. 이 과정에서 mig22의 <code>name[]=text[]</code> 캐스트 결함과 master의 게이트웨이 openai provider 누락 회귀를 발견해 즉시 교정했다(테스트 71 passed). 배포 당시 public health <code>ok·db/engine true</code>, OpenAPI 200, <code>/auth/me</code> 401, dev-login 404, 데이터 집계 전후 동일(app_user 1380/sessions 618/turns 1743)을 확인했다. 증거: <a href="./ops/evidence/nas-prod-deploy-2026-09-01.json">nas-prod-deploy-2026-09-01.json</a>. <b>headful 실계정 폐루프도 당시 완료:</b> NAS env의 OAuth secret 오류(<code>invalid_client</code>)를 교정한 뒤 소유자 실계정 로그인→기존 회기 20건 표시(데이터 보존)→새 사례 회기 생성(mig22 실증)→실턴 SSE·AI 응답→종료→리뷰 생성까지 GREEN(sessions 619·turns 1745·case_profile 566). 일일 검증형 DB 백업 sidecar 첫 덤프도 11.2MB로 성공했다. <b>남은 운영·외부 게이트:</b> C-001 외부 임상 검수, NAS 재부팅 자동복구 smoke, 백업 실패 알림·off-host 복제.</p>
<details class="pulse-details">
<summary>운영 복구·watchdog·배포 상세 보기</summary>
<p class="pulse-state"><b>2026-08-31 사례 연속성 후보:</b> source candidate에는 같은 NPC의 <code>완전히 새로 시작</code>(빈 새 case)과 <code>이어서 진행</code>(선택 case의 압축 기억)을 분리했고, 사례별 누적 회기·상담자 가시 턴·누적 시간을 시작 전 표시하며 기억은 lazy foldout으로 숨겼다. migration 22는 legacy case unique만 해제하고 migration 21의 단일 활성 회기 제약을 유지한다. 이는 source/test 후보 상태이며 NAS DB 적용·배포·실제 production 브라우저 GREEN은 아직 하지 않았다.</p>
@ -327,7 +328,7 @@
<span class="mchip">이전 OpenAPI 증거 · Public API <b>126 paths · G1~G8</b></span>
<span class="mchip good">Direct-runtime preflight <b>APP ROLE OK</b></span>
<span class="mchip crit">Avatar decode <b>3 valid · 90 invalid</b></span>
<span class="mchip">Workbook <b>완료 9 · 검토 2</b></span>
<span class="mchip">Workbook 최신 원본 <b>완료 13 · 검토 1</b></span>
<span class="mchip good">Human gate local <b>10/10 · IAB GREEN</b></span>
<span class="mchip">Human gate <b>실DB/public pending</b></span>
<span class="mchip">Decision <b>P0 조건부</b></span>
@ -342,13 +343,13 @@
</section>
<section class="block source-note" aria-labelledby="product-issues-title">
<h2 id="product-issues-title">제품 이슈 접수 현황 (2026-09-07)</h2>
<p><b>지표 범위:</b> 이 표는 개선관리 워크북의 14개 항목을 로컬 추적용으로 분리한 것이다. 상단의 모듈 카드 <code>33 done / 2 doing</code>과 같은 지표가 아니다. 외부 원본은 <a href="https://docs.google.com/spreadsheets/d/1MNRDfXoIQJbLzIcSRdHnQHREWELbKqV4/edit?gid=351278076#gid=351278076">개선관리 워크북</a>이며 2026-09-07 수집 SHA-256 <code>625281e72067ae2aea402f2fe932b4f593b7905c35f8a9740cf346c7f077c812</code>다. 로컬 집계는 완료 9·기존 gate 2·신규 3이다. 원본의 기존 대기 표기와 로컬 DONE은 동기화 대기 상태이며 원본을 수정하지 않는다.</p>
<h2 id="product-issues-title">제품 이슈 원본 재점검 (2026-09-09)</h2>
<p><b>지표 범위:</b> 이 표는 <a href="https://docs.google.com/spreadsheets/d/1MNRDfXoIQJbLzIcSRdHnQHREWELbKqV4/edit?pli=1&amp;gid=1294900115#gid=1294900115">개선관리 워크북</a> 14개 항목의 최신 원본과 로컬 재검증을 분리한다. 다운로드 원본 SHA-256은 <code>f64bbc859354e8bfdd62bb3393cffd841ca3a0d865983967a149aea7cf569773</code>, 원본은 완료 13·검토 1(C-001)이며 REQ-008~011도 완료다. API 전체 1108 passed/기존 skip 1, route fixture browser 44 passed/0 failed/0 skipped를 수용했다. 이는 local proof이며 REQ-010 추가 수정은 미배포, 새 public live 검증은 하지 않았다.</p>
<div class="dg-table-wrap"><table class="dg-table"><thead><tr><th>ID</th><th>로컬 상태</th><th>원본 상태</th><th>로컬 조치 및 검증 결과</th><th>검증 증거</th></tr></thead><tbody>
<tr><td>REQ-009</td><td>DONE · E2E 검증완료</td><td>중요 · 대기</td><td>상담 중 엔진 스트림 끊김/오류 시 입력 복원, 부분 턴 미적재 보호, 인라인 재시도/닫기 버튼 및 음성 상태 복원 구현 완료.</td><td>단위·Playwright 통과 및 실서버 헤드풀 브라우저 검증. <a href="./ops/evidence/headful-02-session-multi-turn.png">headful-02-session-multi-turn.png</a></td></tr>
<tr><td>REQ-010</td><td>DONE · E2E 검증완료</td><td>중요 · 상태 공란</td><td>하드 딜리트 없이 0턴 무턴 세션은 완료 회기 집계에서 안전하게 제외하고, 실제 발화가 진행된 회기만 완료 카운트에 반영되도록 집계 프로젝션 교정.</td><td>헤드풀 브라우저 2턴 완료 시 카운트 증가(+1) 및 0턴 즉시 종료 시 카운트 불변(유지) 검증. <a href="./ops/evidence/headful-05-learner-home-after-completed.png">headful-05</a>, <a href="./ops/evidence/headful-06-learner-home-zero-turn-verified.png">headful-06</a></td></tr>
<tr><td>REQ-011</td><td>DONE · E2E 검증완료</td><td>일반 · 상태 공란</td><td>OAS G5 자기예측 시 legacy instrument ID 정규화 및 scoped block ID 일치화로 HTTP 422 위반 오류 해소. 1차 예측 기록 및 잠금 성공.</td><td>헤드풀 브라우저 리뷰 피드백 탭에서 1차 예측 저장 및 잠금 완료. <a href="./ops/evidence/headful-04-review-calibration-locked.png">headful-04-review-calibration-locked.png</a></td></tr>
<tr><td>SRC-001</td><td>DONE · 로컬 동기화완료</td><td>원본 워크북 정합성</td><td>개선관리 워크북 replica의 수식 오류(<code>#REF!</code>) 수정 및 개발 상태 집계 범위(15행까지 포함) 보정 완료.</td><td>수식 수정본 엑셀 생성: <code>outputs/01a04217-f73b-7303-b597-401fa7f5d290/Vignette_개선관리_완료.xlsx</code></td></tr>
<tr><td>REQ-009</td><td>원본 완료 · 기존 구현 재검증 수용</td><td>완료</td><td>입력 복원·부분 턴 미저장·재시도/닫기·음성 상태 복원을 local browser로 재검증했다.</td><td>route fixture browser 44 passed/0 failed/0 skipped. 이번 재검증은 새 public live 검증·새 배포가 아니다.</td></tr>
<tr><td>REQ-010</td><td>원본 완료 · 추가 수정 로컬 검증 수용</td><td>완료</td><td>0턴/client-only 회기를 첫 완료·반복·경험 배지 집계에서 기존 완료 조건과 같게 제외했다.</td><td>API 1108 passed/기존 skip 1, route fixture browser 44 passed/0 failed/0 skipped. 추가 수정 미배포.</td></tr>
<tr><td>REQ-011</td><td>원본 완료 · 기존 구현 재검증 수용</td><td>완료</td><td>자기예측 저장·잠금의 기존 해결을 local browser로 재검증했다.</td><td>route fixture browser 44 passed/0 failed/0 skipped. 이번 재검증은 새 public live 검증·새 배포가 아니다.</td></tr>
<tr><td>SRC-001</td><td>역사 replica 수식 보정</td><td>해당 없음</td><td>과거 replica의 <code>#REF!</code>·15행 집계 범위 보정은 보존하며 최신 원본에서 그 오류는 미재현이다.</td><td>과거 수정본: <code>outputs/01a04217-f73b-7303-b597-401fa7f5d290/Vignette_개선관리_완료.xlsx</code></td></tr>
</tbody></table></div>
</section>
@ -1135,7 +1136,7 @@
<tbody>
<tr><td>Web typecheck</td><td><code>npm run typecheck</code></td><td>Passed</td></tr>
<tr><td>Design SSOT / auth visual</td><td><code>npm run check:design-ssot</code> / <code>npx playwright test e2e/auth-visual.spec.ts --project=chromium-single-run --reporter=line</code> / <code>npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --reporter=line</code></td><td>SSOT checker passed; login/onboarding light-dark desktop-mobile 1 passed; 14 core screens × 7 widths visual gate 14 passed.</td></tr>
<tr><td>Full Playwright E2E baseline</td><td><code>npm run e2e:parallel</code> / <code>npm run e2e:single-run</code> / <code>npm run e2e:list</code></td><td>2026-08-31 현재 수집은 <b>1182 tests / 66 files</b>다. 이 숫자는 수집량이며 현 작업트리 전체 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는 범위가 다른 역사 기준선으로 보존한다.</td></tr>
<tr><td>Full Playwright E2E baseline</td><td><code>npm run e2e:parallel</code> / <code>npm run e2e:single-run</code> / <code>npm run e2e:list</code></td><td>2026-09-09 현재 수집은 <b>1188 tests / 66 files</b>다. 이 숫자는 수집량이며 현 작업트리 전체 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는 범위가 다른 역사 기준선으로 보존한다.</td></tr>
<tr><td>Refactor governance P1~P8</td><td><code>ruff check app</code> / <code>pytest -q app</code> / <code>pytest -q engine_gateway</code> / <code>npm run typecheck</code> / <code>npm run check:api-types</code> / <code>npm run check:design-ssot</code> / <code>npm run check:dead-code</code> / <code>npm run check:duplication</code> / <code>npm run build</code> / <code>npm audit --audit-level=high</code> / full Playwright</td><td>Backend 400 passed, gateway 29 passed, web gates/build/audit passed, vulnerabilities 0, production duplication 1 clone/15 lines/0.03%, Playwright 215/215 passed. 상세 근거는 <code>archive/project-cleanup-2026-09-07/refactor-governance-2026-07-15.md</code>.</td></tr>
<tr><td>API typegen SSOT</td><td><code>npm run check:api-types</code></td><td>Passed; FastAPI OpenAPI → <code>src/lib/api.gen.ts</code> stale check</td></tr>
<tr><td>Outcome &amp; Alliance OS G0</td><td><code>py -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</code> / <code>scripts/check-measurement-ledger.sql</code> / measurement·API contract checks / web typecheck / DB-backed <code>session-persistence</code> focused E2E 3종</td><td>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 완료.</td></tr>