감정 관측 운영 검증과 문서 동기화

This commit is contained in:
Yun Chan 2026-09-23 05:03:35 +09:00
parent 29d5b6c50b
commit 2e4a6139f0
8 changed files with 209 additions and 8 deletions

View file

@ -25,7 +25,7 @@
| G7-EXTERNAL | 동의 기반 외부 음성 종료 게이트를 준비한다. | 장치 선택·명시 동의 후 3,120초 양방향 soak, 3,000초 공통 high-water, 독립 human voice-gain pack, canonical checker exit 0. |
| ANTHROPIC-001 | `claude_cli`와 Anthropic API live 동일성을 비교한다. | 기관 키를 게이트웨이 호스트에 승인 주입한 뒤 응답·계량·오류 표면화 비교. 키 주입 전에는 실행하지 않는다. |
| ADMIN-OPENROUTER-001 | 새 사용자 OAuth finish 성공을 관측한다. | API/web 복구·실제 PostgreSQL rollback·배포/보존 census·공개 관리자 UI를 수용했다. OpenRouter UI 상태는 미연결이고 health의 Jev `live_verified=false`는 live 검증이 아니며, 새 OAuth finish 성공 관측 전까지 진행 중이다. [운영 영수증](./ops/evidence/admin-openrouter-recovery-2026-09-22.json)을 따른다. |
| JEV-001 | 충분한 한국어 독립 평가와 전체 지연 반복 비교를 마친다. | 운영 API, 합성·인증 브라우저 3턴 runtime과 DB 감정 영속화는 수용했지만 품질 승격은 보류한다. 위 품질 게이트를 닫은 뒤 전체 사용자 흐름 완료 여부를 판단하며, 최신 probe·수용/반려 근거는 [Jev 결정문](./decisions/jev-client-affect.md)을 따른다. |
| JEV-001 | 충분한 한국어 독립 평가와 전체 지연 반복 비교를 마친다. | 운영 API, 합성·인증 브라우저 3턴 runtime과 DB 감정 영속화는 수용했지만 품질 승격은 보류한다. API legacy baseline 1191 passed·1 skipped·0 failed, gateway 82 passed는 구현 회귀 증거이며 품질·성능 우위 증거가 아니다. 위 품질 게이트를 닫은 뒤 전체 사용자 흐름 완료 여부를 판단하며, 최신 probe·수용/반려 근거는 [Jev 결정문](./decisions/jev-client-affect.md)을 따른다. |
| USER-LATENCY (JEV-001) | 실제 경로에서 text display·voice onset·완료 준비를 분리 측정한다. | 안전 검사를 유지한 최적화 뒤 반복 비교로 사용자 체감 지연을 평가한다. 현재 CUA 관측상한과 소수 audit은 속도 개선 증거가 아니다. |
| G6-PRODUCER-CONFLICT | 기존 submission id와 content hash를 읽기 전용으로 대조한다. | `SupervisionResearchConflictError`의 동일 id 재실행 idempotency 충돌을 해소하고 해당 테스트와 실제 cycle 성공을 확인한다. Jev·세션 경로와 분리된 기존 운영 충돌이며, 이번 배포 회귀로 단정하지 않는다. |
| VNET-001 | `vnet.18ka.net` 공개 전환의 외부 설정을 마친다. | DNS, Cloudflare zone 권한, Google redirect URI가 모두 준비된 뒤 live 검증. |
@ -55,6 +55,7 @@
| NODE-001 | Node gateway 전환 후보의 계약 범위를 정한다. | live endpoint conformance, `TurnEvaluationPayload` adapter, admin mapper의 작업 패킷과 회귀를 확정한다. |
| MIGRATION-001 | idempotent DB migration runner 도입 여부를 결정한다. | init SQL과 runner의 역할 경계, 인프라 영향, 소유자 승인을 확정한다. |
| OPS-001 | 운영 티켓 자동 분류·처리 후속을 설계한다. | 관리자 승인 뒤 이슈/PR/작업 스레드를 생성하는 범위와 audit 경계를 확정한다. |
| B1-LAYOUT-720-001 | 720px prestart `회기 시작` ancestor clipping의 원인을 분리한다. | baseline `d22cd988`과 현재 작업트리에서 같은 `left=25`, `right=695` clip이 재현됐다. 감정 관측 기능 원인으로 단정하지 않으며, 원인 확정 뒤 focused browser 재현·수정 검증으로 닫는다. 현재 전체 layout-visual-gate는 15개 중 1 passed·1 failed·13 not run이므로 전체 GREEN으로 쓰지 않는다. |
| E2E-001 | 전 기능 E2E 후속을 분류한다. | 이번 focused 범위에서 locator 18건을 교정하고 keyboard 1건을 해결했다. `npm run e2e` 전 기능 묶음에서 focused 범위 밖 케이스를 실행하고 실패별 재현·원인·수정 명령을 분류한다. 과거 sweep 실패를 오늘 재현 결함으로 단정하지 않으며, 실API/DB·장치 검증은 fixture 결과와 분리한다. |
| CUA-128 | 실제 배포 Computer Use 128 시나리오를 역할·승인 경계 안에서 재개한다. | 카탈로그 생성은 완료했으나 실배포 전체 검증은 미완료다. SHA `1306c524`에서 H09와 일반 학습자 로그인·교차 역할 차단·P4 추천·R09 잠금·R14 워크시트 보존을 재확인했지만, T18은 learner 브라우저만 있어 기존 RED를 종결하지 않았다. 순수 teacher·OFF 계정, 교수자 쓰기, 모바일과 독립 관찰자 공개 검증이 남아 있다. [실행 보고](./qa/production-computer-use-report-2026-09-09.md)를 따른다. |

View file

@ -86,3 +86,37 @@
### 2026-09-23 현재 runtime 재검증
[Runtime 재검증 영수증](../ops/evidence/jev-runtime-verification-2026-09-23.json)은 배포 컨테이너와 로컬의 Jev 관련 소스 4개 hash 일치, 과거 2회기의 9축 감정 상태와 OpenRouter audit 교집합, 그리고 독립 공유 adapter의 새 9축 호출(472ms)을 분리해 기록한다. 과거 audit은 새 호출이 아니며 독립 호출도 생성·DB·audit 저장을 검증하지 않는다. 구현·runtime 연결은 수용하되 한국어 품질·전체 지연·품질 승격 게이트는 계속 열린다.
## 관리자 감정 관측 콘솔 — 2026-09-23
`ADMIN-AFFECT-001`은 관리자 전용 읽기 화면 `/admin/emotions`로, 회기별 9축 상태와 완료된 내담자 턴의 Jev 전이 기록을 관측한다. 실제 사람의 감정 측정이나 진단이 아니며, 엔진·키·감정 정책을 조작하는 화면이 아니다. 기존 `/admin/ai`는 생성 응답 엔진 설정을 계속 소유하고, Jev는 서버의 provider·startup key 설정을 따른다. 두 화면은 메뉴와 안내에서 분리한다.
### trace 저장·격리 계약
- migration 23의 `app.client_affect_trace`는 `turn_id` 기본키와 `session_id`, `trace jsonb`, `created_at`을 보존하며 turn·session FK는 모두 cascade다. session/time index로 관리자 회기 목록과 역순 페이지를 조회한다. 기존 행을 역산하거나 변경하지 않는다.
- trace v1은 `schema_version=1`, 실제 provider/model·latency·token·cost, 상담 왕복 번호 `turn_seq`, 실제 전이와 같은 policy snapshot, 당시 코드 상태 context, 고정 순서의 9개 dimension을 저장한다. dimension은 `anxiety, sadness, anger, shame, guilt, loneliness, relief, hope, trust` 순서이고 각 항목의 `before/target/after/confidence/probabilities/decision`에서 결측은 0으로 바꾸지 않는다. 5개 확률은 강도 0~4 순서다.
- trace는 `TurnContext` 내부 필드다. 공개 `TurnResult`, stream `done`, `TurnRecord` JSON, `provider_events`와 학습자·교수자 DTO에는 넣지 않는다.
- Jev가 활성인 완료 내담자 턴만 client append와 같은 DB transaction에서 trace insert와 `state_after` upsert를 함께 실행한다. 실패하면 모두 rollback하며, 성공 뒤에만 process mirror를 갱신한다. legacy·위기·실패·취소 턴은 기존 동작을 유지하고 trace를 남기지 않는다.
- RLS는 관리자 SELECT만 허용한다. 서버 learner context의 INSERT는 연결된 client turn과 자기 session 일치가 전제이며 learner·teacher의 SELECT/UPDATE는 허용하지 않는다. 운영 스키마는 앱이 생성하지 않고 readiness 계약 실패를 명시 오류로 표면화한다.
### 관리자 API·표시 계약
- `GET /admin/affect/sessions?limit=1..100&offset>=0`은 최근 회기부터 `session_id/persona_code/started_at/ended/trace_count`만 반환한다. learner id·이름·메일은 반환하지 않으며 runtime의 `configured`는 연결 시험 성공을 뜻하지 않는다.
- `GET /admin/affect/sessions/{session_id}?limit=1..200&before_seq>0`은 현재 저장된 9축 상태, 연결된 내담자 turn의 `app.turns.seq` 기준 cursor 페이지와 `has_more`를 반환한다. trace의 상담 왕복 번호 `turn_seq`와 cursor 값은 같은 필드가 아니다. trace 없는 기존 회기도 조회할 수 있으며, 초기값을 합성하지 않는다. DB·스키마 오류는 503, 없는 회기는 404, 권한은 403, 잘못된 입력은 422다.
- 화면은 현재 상태 9축 막대, trace `turn_seq` gap을 끊어 보이는 9개 SVG 추이, 원자료 표, 선택 턴의 before→Jev target→after와 판단 확신도·5단계 분포·provenance를 제공한다. confidence는 정답 확률이 아니다. 자연어 판단 근거를 생성하거나 추정하지 않는다.
- 관계 행렬은 현재 불러온 trace의 `after-before`만 사용한다. 공통 유효 관측이 5개 이상이고 각 축 분산이 있을 때만 Pearson r을 표시하며, 그 밖에는 데이터 부족 또는 변화없음으로 표시한다. 이는 `상태 변화의 동행 · 인과관계 아님`이며 5개는 표시용 최소값일 뿐 통계적 유의성 기준이 아니다.
- 기존 앱 셸·Pretendard·의미 토큰·간격을 재사용한다. 데스크톱 추이는 3열, 모바일은 1열이고 320/390/1440px, dark/light, reduced-motion, keyboard, print를 검증 범위로 둔다. stale 요청은 AbortController 또는 요청 ID로 이전 회기 결과가 새 선택을 덮지 않게 한다.
### 현재 판정
backend trace/API와 실제 격리 PostgreSQL의 RLS·cascade·원자적 성공·rollback 검증은 수용했다. 실제 DB API 통합은 목록의 empty offset/total, JSONB trace decode, 상세 cursor·null·404를 확인했다. canonical artifact를 실제 재생성한 기술 검증은 6/6 통과, 외부 임상 승인은 0건이며 runtime package 8개 파일은 HEAD와 일치했다. migration 23의 운영 적용은 성공했고 RLS 2개 정책·grants·기존 행 0을 확인했다. `VIGNETTE_CLIENT_AFFECT_PROVIDER=legacy` baseline의 API 전체는 1191 passed·1 skipped·0 failed, gateway는 82 passed다.
웹 `generate:api-types`/`check:api-types`, typecheck, build, design SSOT와 focused 16개는 통과했다. 관리자 레이아웃 3개와 session-layout desktop/mobile 각 4개도 통과했고 실제 그래프·핵심 스크롤, dark/mobile/추이/관계 렌더 캡처와 API 운영 배포 증거를 수용했다. NAS web은 commit `29d5b6c5`, image `sha256:30cffa81e9c569a7ba93b7b90dd3b45459f79368d70675c83c041a9e4ec245b8`, entry `index-hrsPsc6h.js`, AdminAffect `AdminAffect-CXdULwAE.js`로 build와 컨테이너 교체 모두 exit 0이며 API·engine·DB 컨테이너는 유지됐다. 이에 `ADMIN-AFFECT-001`은 운영 수용 완료다. 실제 1턴 trace의 관계 표시는 데이터 부족이며, fixture의 5개 이상 관계 계산 검증과 혼동하지 않는다. 전체 `layout-visual-gate`는 15개 중 1 passed·1 failed·13 not run 상태이므로 전체 GREEN으로 주장하지 않는다. 720px prestart의 `회기 시작`은 ancestor clip(`left=25`, `right=695`)이 baseline `d22cd988`과 현재 작업트리에서 동일하게 재현되어 감정 관측 기능의 원인으로 단정하지 않는다.
### 운영 수용 기록 보강
[ADMIN-AFFECT 운영 영수증](../ops/evidence/admin-affect-runtime-2026-09-23.json)은 API commit `6ab40ff3`와 image SHA-256 prefix `2c437011`, migration 23의 RLS 2개 정책, API health `ok`·DB/engine 정상, Pages commit `29d5b6c5`의 공개 entry `index-m3-R1olx.js`·AdminAffect JS/CSS·기존 사용자 bundle `index-BA_Q0J7Y.js`의 200, health 200을 기록한다. 인증 CUA에서는 새 합성 회기 1왕복 뒤 관리자 화면의 trace 1개, 9축, 5단계 분포, 반영/보류와 policy/context, 실제 `openrouter`/`typesafe/jev-1.13-20260917` 응답의 492ms·input 2273·output 128·$0.000095466을 확인했다. 9개 SVG, ready 1, 진단 0, console error 0 및 회기 종료 뒤 2발화 리뷰 평가까지 확인했고, 새로고침 뒤에도 종료 회기 trace 1개·9축·5단계 분포를 복원했다. 사용자·합성 회기 식별자와 대화 원문은 기록하지 않는다.
운영 DB 읽기 전용 검증은 `BEGIN READ ONLY` 뒤 `ROLLBACK`으로 trace 1개, 연결 client turn FK 일치, trace shape와 9축 key, 실제 provider/model·492ms, 저장 current state와 trace `after` 일치, 회기 종료 상태를 확인했다. 쓰기나 원인 추정은 하지 않았다.
보존 census는 133개 테이블 중 131개 digest 일치, `app_user`·`auth_session` 행 수 동일과 digest 변경(로그인 활동은 있었으나 원인은 확정하지 않음), uploads 93개·52,973 bytes digest 일치, engine/DB 컨테이너 동일을 보인다. dark/mobile/추이/관계 캡처와 렌더 뒤 3.6/8.1초 관측 구간의 진단 0, NAS web 컨테이너 교체 exit 0을 수용했다. watchdog은 공통 root marker 누락으로 한 차례 반려한 뒤 보완해 고정 수용했으며, 영수증은 임시 scratch 원시로그와 CUA 관측을 root가 검토해 요약한다. fixture·API·실제 runtime 증거 경계를 구분한다.

View file

@ -303,7 +303,8 @@
<h1>지금 위치: <em>개선관리 원본 14개 재점검</em> — 2026-09-09 읽기 전용 확인에서 완료 13·검토 1(C-001)이다. REQ-009~011의 로컬 재검증은 수용했고, SHA `1306c524` 운영 배포 뒤 H09를 새 live 검증으로 PASS 확인했다. 2026-09-01·09-08 배포는 역사 증거이며, 9/9 배포가 기존 PASS 전체의 새 검증을 뜻하지는 않는다.</h1>
<p class="pulse-state"><b>실배포 CUA 128:</b> 카탈로그는 생성됐지만 전체 검증은 미완료다. H09(기록 검색·필터 복귀)는 SHA `1306c524`에서 PASS로 재확인했고 T18(감독·연구 drilldown)은 수정 배포 뒤에도 learner 브라우저만 있어 RED를 종결하지 않았다. 관리자와 일반 학습자 로그인에서 학습자의 `/admin`·`/teach`→`/learn` 차단, P4 추천·R09 잠금·R14 워크시트 보존을 확인했다. 순수 teacher·OFF 계정, 교수자 쓰기, 모바일과 독립 관찰자 공개 검증은 남아 있다.</p>
<p class="pulse-state"><b>2026-09-12 비넷 UX 감사:</b> <b>DONE · 로컬 시각 검수 수용</b>. 역할별 메뉴·모바일 라벨, 학습자 정보 위계와 긴 목록, 상담 시작 버튼 겹침, 교수·관리자 표의 넘침, 설정과 약관 배치를 수정했다. 전체 레이아웃 15 passed, 마지막 관리자 폭 보정 후 2 passed, 회기 8 passed, 접근성 44개(38+6) 통과와 직접 이미지 검수를 수용했다. 상세 판정·반려 기록·실제 API와 fixture 증거 경계는 <a href="./ops/ux-audit-2026-09-12.md">감사 기록</a>에 있다. 이후 SHA <code>e8b770e4d9023238bf210b412de75dcb98bfc08e</code>는 Forgejo master에 push했고, 17:55:31 KST 배포 시작 뒤 Pages 공개 배포와 NAS web 전용 교체를 18:06 KST까지 완료했다. API·engine·DB는 유지했다. 인증 내부 UI는 401 세션 만료로 미검증이므로 전체 운영 내부 화면 GREEN이나 전체 기능 출시 완료를 뜻하지 않으며 <a href="./ops/deployment-pipeline.md">배포 현황</a>을 따른다.</p>
<p class="pulse-state"><b>JEV-001 가상 내담자 감정 판단:</b> <b>운영 runtime 수용·품질 승격 검증 중</b>. API 1172 passed·1 skipped·0 failed, gateway 82 passed, web typecheck·build·API types 통과와 NAS 합성·인증 브라우저 3턴 runtime, 새로고침 6발화 복원·실제 6발화 review 요약·deep-loop 완료·DB 9축 감정 영속화를 수용했다. 공개 main JS와 health, <code>/sessions</code> CORS preflight는 200이고 Jev가 configured지만, 독립 한국어 품질 평가·성능 우위·정확도·사용자 체감 지연 개선·DONE 주장은 보류한다. 코드 기본값 <code>legacy</code>를 유지하며 SHA <code>969d9e2c3c94b4f3356defbf02bc863e1c8e30e1</code>와 API image를 적용했다. 배포 중 일시 502가 있어 무중단을 주장하지 않으며, 상세 수용/반려와 다음 게이트는 <a href="./decisions/jev-client-affect.md">Jev 결정문</a>을 따른다. 2026-09-23 <a href="./ops/evidence/jev-runtime-verification-2026-09-23.json">runtime 재검증 영수증</a>은 소스 4개 hash 일치·과거 DB/audit 교집합·독립 공유 adapter의 9축 호출을 수용하되, 한국어 품질·전체 지연·품질 승격을 증명하지 않는다.</p>
<p class="pulse-state"><b>JEV-001 가상 내담자 감정 판단:</b> <b>운영 runtime 수용·품질 승격 검증 중</b>. API legacy baseline 1191 passed·1 skipped·0 failed, gateway 82 passed, web typecheck·build·API types 통과와 NAS 합성·인증 브라우저 3턴 runtime, 새로고침 6발화 복원·실제 6발화 review 요약·deep-loop 완료·DB 9축 감정 영속화를 수용했다. 공개 main JS와 health, <code>/sessions</code> CORS preflight는 200이고 Jev가 configured지만, 독립 한국어 품질 평가·성능 우위·정확도·사용자 체감 지연 개선·DONE 주장은 보류한다. 코드 기본값 <code>legacy</code>를 유지하며 SHA <code>969d9e2c3c94b4f3356defbf02bc863e1c8e30e1</code>와 API image를 적용했다. 배포 중 일시 502가 있어 무중단을 주장하지 않으며, 상세 수용/반려와 다음 게이트는 <a href="./decisions/jev-client-affect.md">Jev 결정문</a>을 따른다. 2026-09-23 <a href="./ops/evidence/jev-runtime-verification-2026-09-23.json">runtime 재검증 영수증</a>은 소스 4개 hash 일치·과거 DB/audit 교집합·독립 공유 adapter의 9축 호출을 수용하되, 한국어 품질·전체 지연·품질 승격을 증명하지 않는다.</p>
<p class="pulse-state"><b>ADMIN-AFFECT-001 관리자 감정 관측:</b> <b>DONE · 운영 수용</b>. backend trace/API와 격리 PostgreSQL RLS·cascade·원자적 성공·rollback, canonical artifact 기술 6/6, migration 23 운영 적용(RLS 2개 정책·grants·기존 행 0), API commit <code>6ab40ff3</code> health, Pages commit <code>29d5b6c5</code>의 공개 index/AdminAffect JS/CSS·기존 사용자 bundle 200, web focused 16개, dark/mobile/추이/관계 캡처, 인증 CUA의 새로고침 뒤 종료 회기 trace 1개·9축·5단계 분포 복원과 리뷰 평가를 수용했다. NAS web은 image <code>sha256:30cffa81…ec245b8</code>, entry <code>index-hrsPsc6h.js</code>, AdminAffect <code>AdminAffect-CXdULwAE.js</code>로 build·컨테이너 교체 exit 0이며 API·engine·DB 컨테이너는 유지됐다. 실제 1턴 관계 표시는 데이터 부족이고 fixture 5개 이상 관계 계산 검증과 구분한다. watchdog은 공통 root marker 누락을 한 차례 반려한 뒤 보완해 고정 수용했다. 관리자 layout 3개와 session-layout desktop/mobile 각 4개는 통과했지만 전체 layout-visual-gate는 15개 중 1 passed·1 failed·13 not run이다. 720px prestart <code>회기 시작</code> ancestor clip은 baseline <code>d22cd988</code>과 현재 작업트리에서 같아 감정 관측 기능 원인으로 단정하지 않는다. <a href="./ops/evidence/admin-affect-runtime-2026-09-23.json">운영 영수증</a>을 따른다.</p>
<p class="pulse-state"><b>G6-PRODUCER-CONFLICT:</b> API 기동 중 기존 background 연구 producer의 <code>SupervisionResearchConflictError</code> 1건을 관측했다. Jev·세션 경로와 분리됐고 이번 배포 diff에 producer·store 변경이 없어 배포 회귀로 단정하지 않는다. 다음은 기존 submission id/content hash의 읽기 전용 대조, idempotency 충돌 해소, 해당 테스트와 실제 cycle 성공이다.</p>
<p class="pulse-state"><b>ADMIN-OPENROUTER-001:</b> <b>API/web 복구·배포 수용 · OAuth finish 대기</b>. 관리자 OpenRouter 복구의 SQL 수정은 실제 PostgreSQL 임시 테이블 rollback으로 확인했고 API 1173 passed·1 skipped·0 failed, 웹 정적 검증과 focused 선택 16개도 통과했다. NAS web·Pages 배포, public HTML/entry와 health 200, 이전 자산 174개 추가 보존·수집 실패 0, 공개 관리자 UI의 ready·복구 화면 없음·<code>gpt-5.6-terra</code> 유지를 수용했다. OpenRouter UI는 미연결이며 health의 Jev <code>live_verified=false</code>는 live 검증이 아니다. 남은 조건은 새 사용자 OAuth finish 성공 관측뿐이며, 전체 GREEN은 주장하지 않는다. 상세는 <a href="./ops/evidence/admin-openrouter-recovery-2026-09-22.json">운영 영수증</a>을 따른다.</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>
@ -1039,8 +1040,10 @@
<div class="task-row"><div><span class="task-status s-done">DONE</span></div><div><b>과거 Live2D demo 자산 제거</b><p>Mao/Haru 샘플, Pixi/Cubism 런타임, 공개 <code>/live2d/*</code> 캐시 잔여 접근을 차단했다.</p></div><div><b>산출물</b><p><code>apps/web/functions/live2d/[[path]].js</code>, SVG 도형 기반 파라미터 리그</p></div><div><b>검증</b><p>운영 <code>/live2d/mao/*</code>, Cubism core <code>404</code></p></div></div>
<div class="task-row"><div><span class="task-status s-done">DONE</span></div><div><b>프로세스 난립 정리</b><p>운영 확인용 프로세스와 로컬/Tailnet 검증용 dev 프로세스를 의도적으로 분리해 유지한다.</p></div><div><b>산출물</b><p>9099 engine, 8001 prod API, 8000/8010 dev API, 5173 web, cloudflared tunnel 1개</p></div><div><b>검증</b><p><code>Get-NetTCPConnection</code>에서 대상 포트별 listener 확인</p></div></div>
<div class="task-row"><div><span class="task-status s-plan">GATE</span></div><div><b>한신대 공문/데이터 거버넌스 게이트 정리</b><p>SSO 클레임, 추가 축어록 수급, 미성년 원본 활용동의, 개인정보 처리방침을 P1 진입 전 외부 의존성으로 명확히 둔다. 로컬 문서 골격은 준비됐지만 한신대/데이터 steward의 written evidence는 아직 필요하다.</p></div><div><b>산출물</b><p><code>docs/ops/hanshin-data-governance-gate.md</code>, 공문 질의 항목, 동의 범위 체크리스트, SSO claim mapping 표</p></div><div><b>검증</b><p>문서 artifact 작성 완료; IRB 게이트가 아니라 데이터/SSO 게이트로 외부 증거 필요 상태 유지</p></div></div>
<div class="task-row"><div><span class="task-status s-doing">JEV-001</span></div><div><b>Jev 감정 판단 실증과 기존 내담자 경로 반복 비교</b><p>수용: 신규 artifact 보존 갱신, app 1172 passed/1 skipped/0 failed, engine 82 passed, web typecheck/build/API types 통과, NAS API 배포·공개 JS/CORS preflight, 인증 브라우저 3왕복·6발화와 DB 9축 감정 영속화. 보류: 성능 우위·정확도·품질 승격과 사용자 체감 지연 개선.</p></div><div><b>산출물</b><p>runner/probe·배포 artifact는 <a href="./decisions/jev-client-affect.md">Jev 결정문</a>과 <a href="./ops/evidence/jev-production-deploy-2026-09-22.json">운영 증거</a>에서 관리한다.</p></div><div><b>검증</b><p>새로고침 뒤 6발화 복원, 종료 review의 실제 6발화 요약·deep-loop 완료와 DB 종료 상태를 확인했다. USER-LATENCY는 text display·voice onset·완료 준비의 실제 경로 분리 측정과 안전 검사 유지 최적화가 남는다. 일시 502 관측 때문에 무중단을 주장하지 않는다.</p></div></div>
<div class="task-row"><div><span class="task-status s-doing">JEV-001</span></div><div><b>Jev 감정 판단 실증과 기존 내담자 경로 반복 비교</b><p>수용: 신규 artifact 보존 갱신, API legacy baseline 1191 passed/1 skipped/0 failed, engine 82 passed, web typecheck/build/API types 통과, NAS API 배포·공개 JS/CORS preflight, 인증 브라우저 3왕복·6발화와 DB 9축 감정 영속화. 보류: 성능 우위·정확도·품질 승격과 사용자 체감 지연 개선.</p></div><div><b>산출물</b><p>runner/probe·배포 artifact는 <a href="./decisions/jev-client-affect.md">Jev 결정문</a>과 <a href="./ops/evidence/jev-production-deploy-2026-09-22.json">운영 증거</a>에서 관리한다.</p></div><div><b>검증</b><p>새로고침 뒤 6발화 복원, 종료 review의 실제 6발화 요약·deep-loop 완료와 DB 종료 상태를 확인했다. USER-LATENCY는 text display·voice onset·완료 준비의 실제 경로 분리 측정과 안전 검사 유지 최적화가 남는다. 일시 502 관측 때문에 무중단을 주장하지 않는다.</p></div></div>
<div class="task-row"><div><span class="task-status s-doing">ADMIN-OPENROUTER-001</span></div><div><b>관리자 OpenRouter 복구의 웹 검증과 새 OAuth 재시도</b><p>수용: <code>AmbiguousColumnError</code>의 기존 refresh column 참조와 <code>EXCLUDED.extra</code>의 text 캐스트 제거(JSONB 비교)를 수정했고, 실제 PostgreSQL rollback·API 교체·보존 census를 확인했다. 웹 focused 선택 16개와 정적 검증, NAS web·Pages 배포, public entry/health 200과 관리자 UI의 ready·복구 화면 없음은 수용했다. 진행 중: 새 사용자 OAuth finish 성공 관측.</p></div><div><b>산출물</b><p><a href="./ops/evidence/admin-openrouter-recovery-2026-09-22.json">운영 영수증</a></p></div><div><b>검증</b><p>API 1173 passed·1 skipped·0 failed, focused 16 passed, health <code>ok</code>·DB/engine true. API 교체 직후 census에서 133개 테이블 중 130개 동일이며 활동 메타데이터 3개는 변했다. OpenRouter UI 미연결과 Jev <code>live_verified=false</code>는 live 검증이 아니며, OAuth finish 성공은 아직 주장하지 않는다.</p></div></div>
<div class="task-row"><div><span class="task-status s-done">DONE</span></div><div><b>ADMIN-AFFECT-001 관리자 감정 관측 trace·그래프 운영 수용</b><p>수용: 완료 내담자 턴 trace의 공개 payload 비노출, API, 격리 PostgreSQL RLS·cascade, 성공·rollback 원자성, canonical artifact 기술 6/6, migration 23 운영 적용(RLS 2개 정책·grants·기존 행 0), API legacy baseline 1191 passed/1 skipped/0 failed와 gateway 82 passed, API 운영 health와 Pages 공개 index/AdminAffect JS/CSS·기존 사용자 bundle 200, 인증 CUA의 trace 1개·9축·5단계 분포와 새로고침 복원, NAS web build·컨테이너 교체 exit 0 및 API·engine·DB 컨테이너 유지.</p></div><div><b>산출물</b><p><a href="./decisions/jev-client-affect.md">Jev 결정문</a>, <a href="./ops/evidence/admin-affect-runtime-2026-09-23.json">운영 영수증</a>, <code>/admin/emotions</code>, <code>/admin/affect/sessions</code></p></div><div><b>검증 경계</b><p>web generate/check API types, typecheck, build, design SSOT와 focused 16개를 통과했고 dark/mobile/추이/관계 캡처 및 실제 리뷰 평가도 수용했다. 실제 1턴 관계 표시는 데이터 부족이며 fixture의 5개 이상 관계 계산 검증과 구분한다. watchdog은 한 차례 반려 뒤 root marker 보완으로 고정 수용했다. 전체 layout-visual-gate는 15개 중 1 passed·1 failed·13 not run이므로 전체 GREEN을 주장하지 않는다.</p></div></div>
<div class="task-row"><div><span class="tag info">B1-LAYOUT-720-001</span></div><div><b>720px prestart 시작 버튼 ancestor clipping</b><p>prestart <code>회기 시작</code>의 clip(<code>left=25</code>, <code>right=695</code>)이 baseline <code>d22cd988</code>과 현재 작업트리에서 동일하다. 감정 관측 기능 원인으로 단정하지 않고 cosmetic backlog로 추적한다.</p></div><div><b>다음 행동</b><p>원인을 분리한 뒤 focused browser 재현·수정 검증을 수행한다.</p></div><div><b>검증 경계</b><p>현재 전체 layout-visual-gate는 15개 중 1 passed·1 failed·13 not run이다. 관리자 3개와 session-layout desktop/mobile 각 4개 통과가 전체 gate 통과를 대체하지 않는다.</p></div></div>
<div class="task-row"><div><span class="task-status s-done">DONE</span></div><div><b>한신대 실사용 피드백 1차 개선팩</b><p>오류분석 자료를 컨텍스트 보존, 내담자 출력 품질, 리뷰 privacy/오류문구 UX, 교수자 설명 가능성으로 분해했고 1차 구현을 완료했다. P1은 role mapping + client-only history injection을 원자 패치로 닫았고, P2/P3/P4는 저장형 fallback 없이 빠른 UX 개선으로 배포 가능한 상태다.</p></div><div><b>산출물</b><p><code>gateway._split_messages(ai_role=client)</code>, <code>guardrail.sanitize_client_reply()</code> 품질 게이트, SSE full-response buffer, 리뷰 표시 자연어화, raw error mapper, 교수자 <code>AI 평가 범위</code> 패널, 계획/레드팀/대레드팀 문서</p></div><div><b>검증</b><p><code>engine_gateway/test_gateway_model.py app/test_orchestrator_masking.py app/test_client_reply_quality.py app/test_session_turn_persistence.py</code> 84 passed, <code>npm run typecheck</code>, <code>npm run check:api-types</code>, <code>session-review.spec.ts</code> focused 8 passed, <code>layout-visual-gate.spec.ts</code> 12 passed, <code>session-layout.spec.ts</code> 8 passed.</p></div></div>
</div>
<div class="source-note"><b>팀장 판정:</b> 로컬 회귀와 공개 prod-safe 게이트는 통과했다. 2026-06-29 수동 Cloudflare Pages production 배포가 현재 custom domain asset으로 확인됐고, 운영 반영 전 남은 핵심 증거는 공개 Google OAuth 실제 <code>/turn</code> smoke다. 런타임 mock/demo 자산은 운영 번들에서 제거하고 테스트 fixture만 남긴다.</div>
@ -1142,7 +1145,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-09-22 <code>check-dev-dashboard-ssot.py</code>의 실제 수집 기준 현재 수집은 <b>1235 tests / 70 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-22 <code>check-dev-dashboard-ssot.py</code>의 실제 수집 기준 현재 수집은 <b>1251 tests / 71 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>

View file

@ -137,6 +137,11 @@ DB readiness는 auth/admin 테이블뿐 아니라 세션 read-model 핵심 테
`TurnContext`/`TurnResult`/`StreamEvent` dataclass가 파이프라인을 관통한다. `EvalHook`/`LogHook`은
`Callable[[TurnContext, str], Awaitable[...]]` 타입으로 주입된다.
Jev가 남기는 `client_affect_trace`는 `TurnContext`의 관리자 관측 전용 내부 필드다. 공개 `TurnResult`,
SSE `done`, `TurnRecord` JSON, `provider_events`에는 포함하지 않는다. 성공한 내담자 append에서만
trace insert와 `state_after` upsert를 같은 DB transaction으로 묶고, 실패 시 rollback한다. legacy·위기·실패·취소
경로는 trace 없이 기존 상태 갱신 계약을 유지한다.
### 2.3 페르소나 메시지 빌더 — `app/services/persona.py` (L0~L6)
`build_turn_messages(card, state, learner_text_masked, ...)`가 한 턴의 `EngineMessage[]`를 조립한다.
@ -414,7 +419,8 @@ session lifecycle을 유지하며, future Node read API는 이 read-model contra
목표를 달성해도 시간 내에는 계속 진행한다(상태머신은 채점·표시용으로만 유지).
- `POST /sessions/{id}/turn` — 동기 경로. `prepare_turn` → `run_turn_generate` →
학습자 발화 turn(speaker=`counselor`, 원문 `text` + `text_masked`) + 내담자 응답 turn(speaker=`client`)
순차 append → 상태 갱신. `EngineError`는 503으로 변환.
순차 append → 상태 갱신. Jev trace가 있으면 내담자 append·trace·상태 upsert를 하나의 transaction으로
실행하고 성공 뒤에만 in-process mirror를 갱신한다. `EngineError`는 503으로 변환.
- `POST /sessions/{id}/stream` — SSE 경로(`run_turn_stream`). token/done/ping/error를 흘리고,
done 시점에 학습자 발화 + 누적 내담자 응답 + 상태를 먼저 영속화하고 즉시 완료한다. fast-loop 평가는
응답 경로 밖에서 같은 learner turn에 사후 저장한다. provider 연결이 깨끗한 EOF로 닫혀도 canonical
@ -540,6 +546,20 @@ session lifecycle을 유지하며, future Node read API는 이 read-model contra
- 공유 HTML과 API 도메인 `/robots.txt`는 `noindex`/`Disallow: /share/` 정책을 둔다. 공유 URL은 검색 색인용
공개 문서가 아니라 교수자 전달용 미리보기 카드다.
### 2.9.4 관리자 감정 관측 — `app/routes/admin.py` + `app/services/admin_affect.py`
관리자 전용 읽기 모델이다. `GET /admin/affect/sessions`는 최근 회기의 식별자·페르소나 코드·시작/종료·trace 수만
반환하며 learner id·이름·메일을 포함하지 않는다. `GET /admin/affect/sessions/{session_id}`는 연결된 내담자 turn의
`app.turns.seq`를 cursor로 쓰는 페이지와 저장된 현재 9축 상태를 돌려준다. trace의 상담 왕복 번호 `turn_seq`는
추이 축용 값으로 cursor와 다르다. 과거 trace가 없는 회기도 조회할 수 있지만 초기값이나 과거 전이를 합성하지 않는다. limit·offset·before_seq 검증은 422, 없는 회기는 404, 권한은 403,
DB 또는 schema 계약 오류는 503이다.
`app.client_affect_trace`는 migration 23의 turn/session FK cascade, `trace jsonb`, session/time index를 사용한다.
RLS는 관리자 SELECT만 허용하며, 서버 learner context의 INSERT도 연결된 client turn과 같은 session으로 제한한다.
learner·teacher의 SELECT/UPDATE는 허용하지 않고, 운영에서 앱이 누락 테이블을 만들지 않는다. trace v1은 실제
provider/model·latency·token·cost, 상담 왕복 번호 `turn_seq`, policy snapshot, 당시 코드 상태 context와 고정 순서 9축의
`before/target/after/confidence/probabilities/decision`만 보존한다. 이 값은 실제 사람의 감정 측정이나 진단이 아니다.
### 2.10 엔진 클라이언트 — `app/engine_client.py`
게이트웨이 HTTP 클라이언트(호출부만). 계약:
@ -736,6 +756,7 @@ React 19 + Vite. 라우팅은 `apps/web/src/App.tsx`(react-router-dom).
| `/teach/session/:sessionId/review` | SessionReview(교수자 읽기 전용 회기 검토) | teacher/admin |
| `/admin` | Admin(운영 홈) | admin |
| `/admin/ai` | AdminAi(AI 공급자·실시간 모델·추론 강도 드롭다운, 기간별 DB 비용·토큰·계량 커버리지, provider/model 원장, 평가 캐시 효율) | admin |
| `/admin/emotions` | AdminAffect(회기별 Jev 9축 상태·턴 trace·상태 변화 동행 관측) | admin |
| `/admin/users` | Admin(사용자 관리) | admin |
| `/admin/access` | Admin(접근 권한) | admin |
| `/admin/tickets` | Admin(운영 티켓 처리 큐: 접수, 필터, 카테고리 큐, 우선순위, 수동 상태 변경 감사) | admin |
@ -828,6 +849,9 @@ DB는 PostgreSQL 16 + pgvector(단일 SoR). 초기화 SQL은 `infra/db/init/`에
`visible_to TEXT[]`(기본 `{client,counselor,evaluator}`), salience/is_pinned/contradicts,
음성 paralinguistic(audio_ref/silence_ms/speech_rate/barge_in/provider_events; review는 제한된 taxonomy 칩만 파생). `turn_technique`/`turn_client_state`
다대다, `supervisor_comment`(rationale/critique + intent_deviation JSONB), `safety_events`.
- **내담자 감정 trace** `app.client_affect_trace` — 완료된 Jev 내담자 턴의 내부 전이 provenance. `turn_id` 기본키와
`session_id`는 `app.turns`/`app.sessions`를 cascade 참조하고, trace와 상태 upsert는 성공한 client append와 같은
transaction에 속한다. trace가 없는 과거·legacy·위기·실패·취소 턴은 추정값으로 채우지 않는다.
- **사례개념화 제출물** `app.case_worksheet` — 회기 리뷰의 축어록 기반 자동 초안을 학습자가 편집해 저장한 JSONB.
`session_id` 단위 upsert이며, `GET /review`에서 자동 초안보다 우선된다.
- **교수자 검토 상태** `app.session_review_status` — 교수자/관리자의 회기 검토 상태, 메모, 검토 시각을

View file

@ -20,7 +20,7 @@ Vignette 저장소의 모든 검증 수단(백엔드 단위 테스트, 웹 타
| API 타입 생성 체크 | `apps/web` | `npm run check:api-types` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | pass |
| 웹 타입체크 | `apps/web` | `npm run typecheck` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | pass |
| 웹 빌드 | `apps/web` | `npm run build` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | pass |
| Playwright E2E(전체) | `apps/web` | `npm run e2e` | **필요(+시드)** | **필요** | 자동기동 | 일부만 | **필요** | 현재 수집 1235 tests / 70 files · 현 작업트리 전체 GREEN 미검증 |
| Playwright E2E(전체) | `apps/web` | `npm run e2e` | **필요(+시드)** | **필요** | 자동기동 | 일부만 | **필요** | 현재 수집 1251 tests / 71 files · 현 작업트리 전체 GREEN 미검증 |
핵심 원칙: **단위 테스트(pytest)와 타입체크/빌드는 외부 서비스 없이 단독 실행된다.**
**E2E만 풀스택(DB+API+웹+브라우저)을 요구한다.** 아래 각 절에서 근거와 절차를 설명한다.
@ -326,7 +326,7 @@ VITE_API_BASE=http://127.0.0.1:8000 npm run e2e # 프록시 대신 API
### 3.6 실측 테스트 개수 (현재)
2026-09-22 `py -3.11 -X utf8 scripts/check-dev-dashboard-ssot.py`가 실행한 `npx playwright test --list` 실제 수집 기준 **현재 수집 1235 tests / 70 files**다
2026-09-22 `py -3.11 -X utf8 scripts/check-dev-dashboard-ssot.py`가 실행한 `npx playwright test --list` 실제 수집 기준 **현재 수집 1251 tests / 71 files**다
(유스케이스 16테마 `uc-*.spec.ts` 239 시나리오 포함).
이 숫자는 수집량이지 통과량이 아니다. 현 작업트리 전체 완주는 아직 증거가 없으며,
과거 전체 GREEN 기록과 이번 focused/release gate 결과를 구분해 적는다.

View file

@ -37,7 +37,7 @@ npx playwright test e2e/uc-session-conversation.spec.ts --grep '스트림 도중
| G7-EXTERNAL | 동의 기반 음성 외부 proof | 3,120초 soak, 3,000초 overlap high-water, 독립 human pack, checker exit 0 | 장치 선택·명시 동의 전 마이크를 열지 않음 |
| ANTHROPIC-001 | provider live 동일성 비교 | 승인 주입한 기관 키로 응답·계량·오류 표면화 비교 | credential 취급·주입은 소유자 경계 |
| ADMIN-OPENROUTER-001 | 새 사용자 OAuth finish 성공 관측 | API/web 복구·실제 PostgreSQL rollback·배포/보존 census·공개 관리자 UI를 수용 | OpenRouter UI는 미연결, health Jev `live_verified=false`는 live 검증이 아님. 상세는 [운영 영수증](./evidence/admin-openrouter-recovery-2026-09-22.json)을 따른다. |
| JEV-001 | 한국어 독립 평가와 전체 지연 반복 비교 | 운영 API·공개 JS·CORS preflight, 합성·인증 브라우저 3턴 runtime과 DB 감정 영속화를 수용했다. 감정·사실 품질과 지연을 평가한다. | 구현 수용·품질 승격 보류. 상세 수용/반려·최종 probe는 [Jev 결정문](../decisions/jev-client-affect.md)을 따른다. |
| JEV-001 | 한국어 독립 평가와 전체 지연 반복 비교 | 운영 API·공개 JS·CORS preflight, 합성·인증 브라우저 3턴 runtime과 DB 감정 영속화를 수용했다. API legacy baseline 1191 passed·1 skipped·0 failed와 gateway 82 passed는 구현 회귀 증거다. 감정·사실 품질과 지연을 평가한다. | 구현 수용·품질 승격 보류. 상세 수용/반려·최종 probe는 [Jev 결정문](../decisions/jev-client-affect.md)을 따른다. |
| USER-LATENCY (JEV-001) | text display·voice onset·완료 준비의 실제 경로 분리 측정 | 안전 검사를 유지한 최적화 뒤 반복 비교 | 소수 CUA 관측상한·audit은 사용자 체감 속도 개선 증거가 아님 |
| G6-PRODUCER-CONFLICT | 기존 submission id/content hash 읽기 전용 대조 | 동일 id 재실행 idempotency 충돌을 해소하고 해당 테스트와 실제 cycle 성공을 확인 | 기존 background producer 충돌 관측; Jev·세션 경로와 분리, 이번 배포 회귀로 단정하지 않음 |
| VNET-001 | vnet 공개 전환 | DNS·Cloudflare zone 권한·Google redirect URI와 live 검증 | 현재 NAS ingress를 넓히지 않음 |
@ -67,6 +67,7 @@ npx playwright test e2e/uc-session-conversation.spec.ts --grep '스트림 도중
| NODE-001 | Node gateway 전환 후보 | endpoint conformance, `TurnEvaluationPayload` adapter, admin mapper의 작업 패킷과 회귀 |
| MIGRATION-001 | idempotent DB migration runner | init SQL과 runner의 역할 경계·인프라 영향·소유자 승인 |
| OPS-001 | 운영 티켓 자동 분류 | 관리자 승인·audit 경계를 갖춘 구현 패킷 |
| B1-LAYOUT-720-001 | 720px prestart `회기 시작` ancestor clipping 원인 분리 | baseline `d22cd988`과 현재 작업트리에서 같은 `left=25`, `right=695` clip이 재현됐다. 감정 관측 기능 원인으로 단정하지 않는다. 원인 확정 뒤 focused browser 재현·수정 검증으로 닫는다. 전체 layout-visual-gate는 15개 중 1 passed·1 failed·13 not run이므로 전체 GREEN으로 쓰지 않는다. |
| E2E-001 | 전 기능 E2E 후속 분류 | focused 범위의 locator 18건 교정·keyboard 1건 해결 뒤 `npm run e2e`에서 범위 밖 케이스를 실행하고, 실패별 재현·원인·수정 명령을 분류한다. 과거 sweep 실패를 오늘 결함으로 단정하지 않으며 실API/DB·장치 검증은 fixture 결과와 분리한다. |
| CUA-128 | 실제 배포 Computer Use 재검증 | 128 시나리오 카탈로그 생성은 완료했지만 전체 실배포 검증은 미완료다. SHA `1306c524`에서 H09와 일반 학습자 로그인·교차 역할 차단·P4 추천·R09 잠금·R14 워크시트 보존을 재확인했지만, T18은 learner 브라우저만 있어 기존 RED를 종결하지 않았다. 순수 teacher·OFF 계정, 교수자 쓰기, 모바일과 독립 관찰자 공개 검증이 남아 있다. |

View file

@ -0,0 +1,133 @@
{
"schema_version": 1,
"recorded_on": "2026-09-23",
"scope": "ADMIN-AFFECT-001의 운영 API·migration, Pages 공개 경로, 인증 Computer Use 관측과 보존 census",
"source": {
"api_forgejo_commit": "6ab40ff3",
"api_image_sha256_prefix": "2c437011",
"pages_forgejo_commit": "29d5b6c5",
"pages_deployment_url": "https://7b588c67.vignette-b1q.pages.dev",
"public_entry_asset": "index-m3-R1olx.js"
},
"database_and_api": {
"migration_23_applied": true,
"rls_policy_count": 2,
"api_deployed": true,
"public_health": {
"status": "ok",
"db": true,
"engine": true
}
},
"pages_public_verification": {
"entry_asset_status": 200,
"health_status": 200,
"admin_affect_js_status": 200,
"admin_affect_css_status": 200,
"existing_user_bundle": {
"name": "index-BA_Q0J7Y.js",
"status": 200
}
},
"nas_web_build": {
"forgejo_commit": "29d5b6c5",
"exit_code": 0,
"image_sha256": "30cffa81e9c569a7ba93b7b90dd3b45459f79368d70675c83c041a9e4ec245b8",
"entry_asset": "index-hrsPsc6h.js",
"admin_affect_asset": "AdminAffect-CXdULwAE.js",
"container_replacement_exit_code": 0,
"container_replacement_receipt_pending": false,
"api_engine_db_containers_unchanged": true
},
"web_and_authenticated_runtime": {
"focused_e2e_passed": 16,
"watchdog": {
"observation_seconds_after_render": [
3.6,
8.1
],
"diagnostics_visible": 0,
"review": {
"initial_disposition": "rejected_once",
"issue": "공통 data-vignette-admin-root marker 누락",
"fixed_acceptance": true
}
},
"rendered_capture": {
"dark": true,
"mobile": true,
"trend": true,
"relationship": true
},
"authenticated_cua": {
"new_synthetic_session_round_trips": 1,
"admin_trace_count": 1,
"dimensions": 9,
"probability_bins": 5,
"decision_and_policy_context_visible": true,
"svg_count": 9,
"ready_visible": 1,
"diagnostics_visible": 0,
"console_errors": 0,
"reload_restored_ended_session_trace": true,
"trace_runtime": {
"provider": "openrouter",
"model": "typesafe/jev-1.13-20260917",
"latency_ms": 492,
"input_tokens": 2273,
"output_tokens": 128,
"cost_usd": 0.000095466
},
"session_closed_and_two_turn_review_evaluated": true
}
},
"read_only_database_verification": {
"method": "BEGIN READ ONLY / ROLLBACK",
"trace_count": 1,
"client_turn_fk_matching": true,
"trace_shape_valid": true,
"all_nine_dimension_keys_present": true,
"provider": "openrouter",
"model": "typesafe/jev-1.13-20260917",
"latency_ms": 492,
"persisted_current_state_matches_trace_after": true,
"session_status": "ended"
},
"preservation_census": {
"tables": {
"total": 133,
"matching_digests": 131
},
"activity_metadata": {
"app_user": {
"row_count_unchanged": true,
"digest_changed": true
},
"auth_session": {
"row_count_unchanged": true,
"digest_changed": true
},
"digest_change_cause": "로그인 활동이 있었으나 원인은 확정하지 않았다."
},
"uploads": {
"files": 93,
"bytes": 52973,
"digest_unchanged": true
},
"engine_db_containers_unchanged": true
},
"acceptance_state": {
"operational_api_and_migration_accepted": true,
"pages_public_verification_accepted": true,
"authenticated_runtime_observation_accepted": true,
"nas_web_build_succeeded": true,
"nas_web_container_replacement_completed": true,
"done_promotion": true
},
"evidence_boundary": "임시 scratch 원시로그와 CUA 관측을 root가 검토해 이 영수증에 요약했다. fixture, API, 실제 runtime 증거 경계를 구분하며 사용자·합성 회기 식별자, 대화 원문, 키와 인증 정보는 기록하지 않는다.",
"open_gates": [
"JEV-001 한국어 독립 품질·성능 우위·사용자 체감 지연 검증",
"ADMIN-OPENROUTER-001 새 사용자 OAuth finish 성공 관측",
"G6-PRODUCER-CONFLICT 기존 submission id/content hash 읽기 전용 대조와 cycle 성공"
]
}