G8 실제 rollback 증명 종료와 비-secure origin 회기 리뷰 크래시 수정
G8 마지막 게이트인 receipt-bound 실제 image rollback을 격리 NAS vignette-preview-20260807 에서 실행해 종료했다. Gate6 계약 정정: 감사 대상 current API 이미지가 com.docker.compose.project/service/version image label 을 갖고 있어 "helper 의 compose label 0개" 계약은 감사되지 않은 다른 이미지를 쓰지 않는 한 성립하지 않는다. 계약을 key 부재가 아니라 소속(membership) 으로 바꿔 launch-nas-preview-g8-helpers.py 에 구현했다. image 상속 label 을 baseline 으로 읽고 container 의 모든 compose label 이 baseline 과 같거나 선언된 격리 override 인지 검사하며, 최종 project 는 target 이 아니고 service 는 api/web/db/proxy 가 아니어야 한다. docker run argv 에 target label 을 주입하면 fake-runner 테스트가 먼저 깨진다 (37/37). 실행 결과: - rollback-old receipt nas-g8-723eeef22eab05e63e3fafb0 -> 79ec../c530.. - restore-current receipt nas-g8-2738846cf2cf4fbe8ce0fc26 -> 52e0../6fdb.. - release gate/approval 각 2회 멱등, audit.ci_lifecycle_event rollback/executed 2, audit.ci_human_approval_event authorize_rollback 2, silent auto-promotion 0 - HMAC journal 6-record 체인 검증, health 3/3, OpenAPI 126, auth 401, Web 200 - helper 0, listener 0, 비밀 env 파기. down/volume rm/prune 미실행, 공개 런타임 미접촉 - 계획했던 Windows SSH 터널은 NAS sshd 가 direct-tcpip 를 거부해 사용할 수 없어 sshd 설정 변경 대신 같은 격리 계약의 NAS-side probe 컨테이너로 실행했다 비-secure origin 크래시 수정: 배포된 NAS 프리뷰(평문 HTTP, 비-localhost)에 회기 스펙을 돌려 24건 실패를 확인했고 원인은 하나였다. crypto.randomUUID 는 secure context 전용인데 제품 코드 18곳이 fallback 없이 호출했고 RuptureRepairCard 는 렌더 시점 호출이라 회기 리뷰 라우트 전체가 error boundary 로 떨어졌다. 릴리스 게이트 108/108 은 localhost 후보 스택에서만 돌아 이 경로를 밟은 적이 없다. src/lib/uuid.ts 의 randomUuid() 로 통일하고 fallback 도 crypto.getRandomValues 를 우선 사용해 idempotency key 의 예측 불가능성을 유지했다. 회귀는 insecure-context-uuid.spec.ts 6/6 으로 고정했다(직접 호출 0건 검사 포함). 이 수정은 아직 NAS 에 배포하지 않았다. 검증: API 898, gateway 58, executor 28, probe 11, helper launcher 37, release agent 21, ruff clean, web api-types/typecheck/build, SSOT FAIL 0, SSOT unit 5/5, dashboard E2E 10/10, 학생 폐루프 실 DB 브라우저 4/4(일회용 클론), crypto 수정 후 기존 스펙 회귀 70/70, 복원된 NAS 실제 브라우저 SSE->DB 리뷰 PASS. 부수 발견(열린 항목): 공개 API 가 engine=false 로 degraded 인데 워치독이 이를 감지하지 못한다. engine 판정이 게이트웨이 /health 의 ok 만 보고 claude readiness probe 를 돌리지 않기 때문이다. 같은 .env 와 같은 CLI 로 새 게이트웨이를 다른 포트에 띄우면 즉시 ready 이므로 상주 프로세스의 세션만 죽은 형태다. TODO A절과 대시보드에 기록했다. 이 커밋은 파일 단위로 담겼다. 위 파일들에는 이전 세션의 미커밋 G0~G8 작업이 함께 들어 있으며, hunk 를 쪼개면 대시보드/체커/TODO 정합성이 깨져 SSOT 체커가 실패한다.
This commit is contained in:
parent
76d0b9ae9b
commit
93dd8f82d7
22 changed files with 10057 additions and 473 deletions
|
|
@ -15,12 +15,12 @@ Vignette 저장소의 모든 검증 수단(백엔드 단위 테스트, 웹 타
|
|||
|
||||
| 검증 | 작업 디렉터리 | 명령 | DB | API(8000) | 웹(5173) | 엔진GW(9099) | 브라우저 | 현재 통과 |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| 백엔드 단위 테스트 | `apps/api` | `python -m pytest app/ -q` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | 2026-07-30 전체 실행 432 passed |
|
||||
| 엔진 게이트웨이 테스트 | `apps/api` | `python -m pytest engine_gateway/ -q` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | 2026-07-30 전체 실행 44 passed |
|
||||
| 백엔드 단위 테스트 | `apps/api` | `python -m pytest app/ -q` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | 2026-07-31 전체 실행 439 passed |
|
||||
| 엔진 게이트웨이 테스트 | `apps/api` | `python -m pytest engine_gateway/ -q` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | 2026-07-31 전체 실행 45 passed |
|
||||
| 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` | **필요(+시드)** | **필요** | 자동기동 | 일부만 | **필요** | 215 tests / 20 files |
|
||||
| Playwright E2E(전체) | `apps/web` | `npm run e2e` | **필요(+시드)** | **필요** | 자동기동 | 일부만 | **필요** | 현재 수집 610 tests / 44 files · 현 작업트리 전체 GREEN 미검증 |
|
||||
|
||||
핵심 원칙: **단위 테스트(pytest)와 타입체크/빌드는 외부 서비스 없이 단독 실행된다.**
|
||||
**E2E만 풀스택(DB+API+웹+브라우저)을 요구한다.** 아래 각 절에서 근거와 절차를 설명한다.
|
||||
|
|
@ -42,15 +42,15 @@ Vignette 저장소의 모든 검증 수단(백엔드 단위 테스트, 웹 타
|
|||
|
||||
```sh
|
||||
# apps/api
|
||||
python -m pytest app/ -q # 앱 단위 테스트: 2026-07-30 전체 실행 432 passed
|
||||
python -m pytest engine_gateway/ -q # 게이트웨이 단위 테스트: 2026-07-30 전체 실행 44 passed
|
||||
python -m pytest app/ -q # 앱 단위 테스트: 2026-07-31 전체 실행 439 passed
|
||||
python -m pytest engine_gateway/ -q # 게이트웨이 단위 테스트: 2026-07-31 전체 실행 45 passed
|
||||
```
|
||||
|
||||
수집만 빠르게 확인하려면:
|
||||
|
||||
```sh
|
||||
python -m pytest app/ --collect-only -q # 현재: "432 tests collected" (2026-07-30)
|
||||
python -m pytest engine_gateway/ --collect-only -q # 현재: "44 tests collected" (2026-07-30)
|
||||
python -m pytest app/ --collect-only -q # 현재: "436 tests collected" (2026-07-31)
|
||||
python -m pytest engine_gateway/ --collect-only -q # 현재: "45 tests collected" (2026-07-31)
|
||||
```
|
||||
|
||||
> 참고: 실행 중 `PendingDeprecationWarning: Please use 'import python_multipart'`
|
||||
|
|
@ -271,10 +271,160 @@ VITE_API_BASE=http://127.0.0.1:8000 npm run e2e # 프록시 대신 API
|
|||
|
||||
### 3.6 실측 테스트 개수 (현재)
|
||||
|
||||
`npx playwright test --list` 기준 **총 215 tests / 20 files**.
|
||||
2026-08-07 `npx playwright test --list` 기준 **현재 수집 610 tests / 44 files**다.
|
||||
이 숫자는 수집량이지 통과량이 아니다. 현 작업트리 전체 604개 완주는 아직 증거가 없으며,
|
||||
과거 전체 GREEN 기록과 이번 focused/release gate 결과를 구분해 적는다.
|
||||
|
||||
- **병렬 시나리오**: 166 tests (desktop 83 + mobile 83)
|
||||
- **`@single-run` 직렬 시나리오**: 49 tests (DB 영속화·세션 MVP·음성 성공경로·인증 시각 테마·회기말 평가 저장·교수자 명시 재평가 저장·교수자 턴 재평가 저장·교수자 UI 평가 재시도·교수자 사용자별 분석·source pack sync·이론모드 저장·동의 철회 후 voice 차단·브라우저 stream PII 마스킹·음성 transcript 저장 실패 UI 표면화 등)
|
||||
- 2026-08-06 Outcome & Alliance OS G0 검증: `test_measurement_contract.py` + runtime schema SSOT **11 passed**,
|
||||
기존 세션·평가·메모리·RBAC backend **100 passed**, auth cohort 계약 **39 passed**, Python 생성 계약
|
||||
`--check`와 TypeScript measurement/API 계약·typecheck 통과. `scripts/check-measurement-ledger.sql`을 실제
|
||||
PostgreSQL owner 연결에서 실행해 learner/client/evaluator 가시 행이 각각 1/1/2, 교차 view 누수 0,
|
||||
append-only UPDATE/DELETE guard 2건임을 확인했다. DB-backed `session-persistence`의 학습자 턴→교수자
|
||||
대시보드, 워크시트 저장→수정요청 검수, 종료 deep 평가→durable 교수자 리뷰 focused E2E는 각각
|
||||
**1/1 passed**. 명시 cohort가 없는 새 DB에서도 이 증거가 재현되도록 dev-login E2E 요청만 공통
|
||||
`e2e-hanshin` cohort를 고정하며 생산 OAuth/SAML·관리 사용자 cohort는 우선 보존한다.
|
||||
- 2026-08-06 Outcome & Alliance OS G1 검증: alliance service/calibration/routes/runtime/contract focused
|
||||
backend **40 passed**. `scripts/smoke-alliance-pulse-api.py`는 실제 DB/API/엔진에서 `202 → awaiting_agents →
|
||||
ready`, 공개 전 외부 관점 비노출, terminal 3관점×3축 9개, 동일 cohort 교수자 조회, 교수자 재평정 2회의
|
||||
append-only supersession, 시도별 model-run provenance를 단언한다. `e2e/alliance-pulse.spec.ts`는 데스크톱·
|
||||
모바일 **6/6**, 기존 `session-review.spec.ts`는 같은 두 프로젝트 **12/12**를 통과했다. prompt `1.2.0`
|
||||
합성 gold 비교는 방향 정확도 **9/9**, 최종 실패 **0**, 근거 recall **88.9%**이며 첫 시도 실패 2건의
|
||||
오류·재시도 provenance도 보존했다. 비교 산출물은
|
||||
`ops/alliance-calibration-report-prompt-1.2.0-2026-08-06.md`다.
|
||||
- 2026-08-07 G1 실제 회기 checkpoint 보강: 최신 source API와 dev PostgreSQL에서 첫 발화 전 pre는
|
||||
`degraded/insufficient_transcript`로 fail-closed, 첫 실제 왕복의 durable turn UUID 2개를 쓰는 mid와
|
||||
DB 종료 뒤 post는 `ready`로 통과했다. 같은 응답 안의 `awaiting_agents`/external-event read skew를
|
||||
차단하고 degraded terminal/audit DB 제약을 교정했다. post는 최초 202, 동일 payload 안정 replay,
|
||||
변경 payload 409, RLS/cohort와 교수자 3축 supersession을 재확인했다. focused G1 **43 passed**와 Ruff 통과,
|
||||
기계 판독 결과는 `ops/evidence/alliance-pulse-pre-mid-post-live-2026-08-07.json`이다.
|
||||
- 2026-08-06 Outcome & Alliance OS G2 검증: contract/store/schema와 G3 통합 focused backend **90 passed**,
|
||||
durable review UUID 회귀 **37 passed**. `scripts/smoke-outcome-trajectory-api.py`는 실제 DB/API/엔진에서 한
|
||||
case의 S1~S5 연속성, 15개 독립 축, total score 부재, 동일 제출 measurement ID 멱등성, 변경 payload 409,
|
||||
같은 cohort 교수자 조회, 다른 학습자·교차 cohort 차단, 역할별 관계 메모리, 합성·비임상 고지를 단언했다.
|
||||
`e2e/outcome-trajectory.spec.ts` desktop/mobile은 체크인 포함 **12/12**, G1 Alliance Pulse와 기존 Session
|
||||
Review 회귀는 **15/15**를 통과했다. 상세 metadata는
|
||||
`ops/outcome-trajectory-live-integration-evidence-2026-08-06.md`가 소유한다.
|
||||
- 2026-08-07 G2 악화/false-alert 실 DB 보강: `scripts/smoke-outcome-trajectory-alerts.py`는 합성 교육용
|
||||
두 case의 실제 10회기와 production observation producer가 쓴 30개 `measurement_event`를 evaluator가
|
||||
소비하는지 확인한다. 악화 case는 S3 `off_track`·S4~S5 `deteriorating`, 단발성 noise control은
|
||||
S3 `watch` 뒤 S4~S5 `on_track`이며 alert 승격 0건이다. case별 revision 5개·supersession 4개와 최신
|
||||
observation 30개→measurement 30개 provenance, learner/teacher projection 일치, 합성·비임상 표시를
|
||||
단언하고 결과 JSON에는 source score를 기록하지 않는다. G2 focused **40 passed**, Ruff·`py_compile`·실 DB
|
||||
smoke 통과. 동시 G8 변경 수렴 뒤 전체 API도 **855 passed**를 통과했다.
|
||||
- 2026-08-06 Outcome & Alliance OS G3 검증: 11-case/9-type 합성 benchmark의 rupture type macro-F1
|
||||
**1.0**, repair status accuracy **1.0**, critical miss·judge gaming·memorized phrase false resolution **0**.
|
||||
Scenario Director와 runtime/store/session focused **107 passed**, G0~G8 계약·store·runtime 묶음 **251 passed**.
|
||||
실제 DB/API 회기 smoke는 durable turn UUID 2개, 독립 내부 토큰 write, 동일 payload 멱등 ID, 변경 payload
|
||||
409, learner/cohort RLS, 교수자 append-only correction과 최종 resolved를 확인했다. G1~G3 및 기존 리뷰
|
||||
desktop/mobile 회귀는 **50/50 passed**. 상세는
|
||||
`ops/rupture-repair-live-integration-evidence-2026-08-06.md`가 소유한다.
|
||||
- 2026-08-07 G3 자동 runtime 보강: `scripts/smoke-rupture-runtime-auto.py`는 외부 client/evaluator만
|
||||
결정론 seam으로 교체하고 실제 `sessions.submit_turn`·공용 `finalize_completed_turn` hook을 호출한다.
|
||||
rupture 저장 endpoint를 호출하지 않은 채 로컬 PostgreSQL에 missed/partial/resolved 3 episode,
|
||||
observation **10개**, reconciliation **3개**, structured learner evaluation **5개**, 세션 밖 evidence 참조
|
||||
**0건**, 세션별 fast/deep model-run **2개**를 단언하며 learner/teacher read projection도 검증한다.
|
||||
focused G3 runtime/store/core/scenario는 **70 passed**다. 재현 JSON은
|
||||
`ops/evidence/rupture-runtime-auto-live-2026-08-07.json`이다. 이 실 DB 실행은 텍스트 learner-turn
|
||||
transport를 증명하며 SSE·음성 개별 transport live smoke까지 증명했다고 확장하지 않는다.
|
||||
- 2026-08-06 Outcome & Alliance OS G4 검증: deliberate-practice core/store/API focused **54 passed**,
|
||||
5개 연습 모드와 약점·망각 우선 선택, 익숙한 성공/자기 성공 주장만으로 mastery를 열지 않는 전이
|
||||
게이트를 고정했다. 실제 DB/API 회기 smoke는 durable turn UUID 2개를 prescription/attempt evidence로
|
||||
사용하고 내부 토큰 처방 write, 동일 제출 안정 ID, 변경 payload 409, learner/cohort RLS, 교수자 append-only
|
||||
correction, 총점·XP 없음, `clinical_claim_allowed=false`를 확인했다. G4 desktop/mobile은 **8/8**,
|
||||
G1~G4와 기존 회기 리뷰 통합 회귀는 **58/58 passed**. 상세는
|
||||
`ops/deliberate-practice-live-integration-evidence-2026-08-06.md`가 소유한다.
|
||||
- 2026-08-06 Outcome & Alliance OS G5 검증: calibration-transfer core/store/API focused **41 passed**,
|
||||
4-case benchmark expectation accuracy **1.0**, 잠금 뒤 오염 거부 **1**, 반복 보정 MAE **0.667→0.267**,
|
||||
unseen varied transfer 4/4, 암기 문구 false verification **0**, 합성 subgroup drift gap **0.667**을 확인했다.
|
||||
실제 DB/API smoke는 durable turn prediction revision→불가역 lock→독립 runtime observation reveal,
|
||||
동일 제출 안정 ID·변경 payload 409, post-lock revision 422, learner/supervisor projection과 교차 역할/cohort
|
||||
차단을 검증했다. G5 learner/teacher desktop/mobile **4/4**, G1~G5+기존 리뷰 **62/62**, typecheck·build
|
||||
통과. 상세는 `ops/calibration-transfer-live-integration-evidence-2026-08-06.md`가 소유한다.
|
||||
- 2026-08-07 G4/G5 production caller 실 DB 검증: `scripts/smoke-session-learning-producer.py`는 실제 종료
|
||||
회기·durable turn UUID 2개·ready session evaluation을 만들고 `session_learning_producer`만으로 G4/G5
|
||||
파생 원장을 생성한다. 잠금 전 G4 submission/card/prescription/snapshot/decision 각 1개와 G5 observation
|
||||
0개, prediction lock callback 뒤 failed 독립 observation·turn/session provenance model-run 각 1개를
|
||||
확인했다. 재실행은 G4 deterministic submission/card replay이며 G5·model-run 중복 0이다. episode/attempt,
|
||||
mastery/pass, calibration assessment, transfer suite/trial/assessment는 모두 0이다. learner/teacher projection
|
||||
일치와 `clinical_claim_allowed=false`도 단언한다. focused **100 passed**, 전체 API **855 passed**, Ruff·
|
||||
`py_compile`·실 PostgreSQL smoke 통과. 상세는
|
||||
`ops/outcome-os-g4-g5-production-caller-evidence-2026-08-07.md`가 소유한다.
|
||||
- 2026-08-07 학생 자기주도 전체 루프 UI 검증: `self-directed-learning-loop.spec.ts`는 실제 `src` 화면에서
|
||||
학습 홈 추천→목표 선택→텍스트/SSE 회기→종료·리뷰→G4 처방 CTA→새 회기 사전 설정·시작을 하나의
|
||||
상태 흐름으로 묶고 desktop/mobile **2/2**를 통과했다. 미소유 `/api/**`는 전부 fixture 404이고
|
||||
`auth/me`·세션·리뷰·practice read model도 route fixture이므로 실제 로그인/API/DB 증거가 아니다.
|
||||
390×844·320×568 활성 회기를 포함한 9장 시각 QA, 내부 criterion/counterevidence/UUID 비노출,
|
||||
홈 CTA 44px·4.5:1 대비와 source API/DB 증거의 분리 기준은
|
||||
`ops/outcome-os-self-directed-learning-loop-ui-evidence-2026-08-07.md`가 소유한다.
|
||||
- 2026-08-06 Outcome & Alliance OS G6 검증: supervision/research core/store/API/runtime-schema focused
|
||||
**28 passed**, 6-signal attention queue 순서 정확, item별 drilldown 1/상한 3, metadata-only calibration
|
||||
dataset raw transcript row 0, version drift `drift_flagged`, Phase 3 네 도메인 manifest를 고정했다. 실제
|
||||
DB/API smoke는 두 개의 durable practice attempt UUID를 원장 pointer로 사용해 내부 토큰, 동일 제출 안정 ID,
|
||||
변경 payload 409, supervisor/research AI-view 분리, teacher/learner/cross-cohort RLS, teacher audit를 검증했다.
|
||||
role-safe research read model은 model/prompt/instrument version, subgroup metrics, artifact provenance를 hydrate한다.
|
||||
G6 desktop/mobile **6/6**, typecheck·build 통과. 상세는
|
||||
`ops/supervision-research-live-integration-evidence-2026-08-06.md`가 소유한다.
|
||||
- 2026-08-07 G6 scheduled producer 보강: G0~G5 원장 기반 파생과 repo-approved synthetic version evaluator
|
||||
focused **37 passed**. 실제 dev DB에서 6 cohort cycle 실패 0, measurement anchor 12개, baseline/candidate
|
||||
batch 2·drift report 1·subgroup 2, replay 중복 0, evaluator/prompt/instrument provenance hydrate를 확인했다.
|
||||
원문 transcript와 임상 주장은 0이다. 상세는 `ops/outcome-os-g6-ledger-producer-evidence-2026-08-07.md`와
|
||||
`ops/outcome-os-g6-version-comparison-producer-evidence-2026-08-07.md`가 소유한다.
|
||||
- 2026-08-06→07 Outcome & Alliance OS G7 검증: 동의→단일 오디오 시계→독립 text/voice/fusion→철회·
|
||||
tombstone의 실제 HTTP/DB 경계와 역할 안전 UI를 통과했다. 공개 배포 뒤 G7 API route, TLS 1.3 WSS
|
||||
handshake와 비인증 1008 차단을 확인했다. Deepgram streaming adapter/interim/final/word timestamp,
|
||||
HMAC word pseudonym, 1초 동의 재검사, 음성 recovery UX와 `ready` provider/model 계약은 code/internal 완료다.
|
||||
public preflight는 마이크 없이 authenticated ready/ping과 기대 STT/TTS provider/model 네 값만 검사한다.
|
||||
실제 Deepgram key·quota live, 명시 동의 물리 마이크, authenticated public ready, 실행된 50분 soak와 운영 TTS
|
||||
상업 이용권 증거는 외부 게이트이며 synthetic/preflight 증거로 대체하지 않는다.
|
||||
- 2026-08-06→07 Outcome & Alliance OS G8 검증: source→독립 red-team→benchmark→human gate,
|
||||
baseline/threshold/provenance/rollback 4종 증거, lifecycle과 incident DAG를 실제 API/DB에서 통과했다.
|
||||
clean release backend **362 passed**, 회기·Outcome desktop/mobile **126 passed / 2 skipped**, layout visual
|
||||
gate **15/15**, typecheck·API contract·build를 통과한 뒤 API 8001과 Cloudflare Pages production에 배포했다.
|
||||
공개 OpenAPI **119 paths**에서 G1~G8 route, prod/db/engine health, auth 401, Google OAuth 302+state cookie,
|
||||
custom-domain 새 asset과 브라우저 로그인 렌더를 확인했다. 상세는
|
||||
`ops/outcome-os-public-deployment-evidence-2026-08-07.md`가 소유한다.
|
||||
- 2026-08-07 Outcome & Alliance OS 배포 프리플라이트: Compose profile과 별도로 `direct-runtime` profile을
|
||||
추가했다. `scripts/provision-outcome-os-runtime-secrets.py`는 G3~G8 토큰 6개만 원자적으로 생성·회전하고
|
||||
값을 출력하지 않는다. 운영 `apps/api/.env`에서 필수키와 `DATABASE_URL`, `current_user=vignette` non-owner
|
||||
app-role 검사를 통과했다. 상세는 `ops/outcome-os-deploy-preflight-evidence-2026-08-07.md`가 소유한다.
|
||||
- 2026-08-07 G7 로컬 `/voice/ws` short soak: loopback Uvicorn의 실제 FastAPI WebSocket transport에서
|
||||
8.015초·83/83 연결, 성공 발화 79, 정상/인증 거부/provider degraded close, 같은 socket 철회와 재연결
|
||||
차단, 4KiB 실행 한정 overflow 뒤 복구를 확인했다. 관련 42 tests와 API/gateway 전체 **805 passed**.
|
||||
외부 provider·실DB·물리 마이크·public WSS는 사용하지 않았고 50분 옵션은 제공만 했으므로 B2는 유지한다.
|
||||
상세는 `ops/outcome-os-g7-wss-soak-evidence-2026-08-07.md`가 소유한다.
|
||||
- 2026-08-07 G7 후속 hardening: voice service/WS/G7 store·API focused **73 passed**, public runner **12 passed**.
|
||||
`scripts/soak-public-voice-websocket.py --preflight-only`는 auth cookie·소유 회기와 아래 네 기대값을 필수로 받고
|
||||
WSS ready/ping까지만 수행한다. 마이크 장치 열거·캡처가 없으므로 물리 음성 증거로 판정하지 않는다.
|
||||
|
||||
```powershell
|
||||
C:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -X utf8 `
|
||||
scripts\soak-public-voice-websocket.py --preflight-only `
|
||||
--expected-stt-provider deepgram --expected-stt-model nova-3 `
|
||||
--expected-tts-provider <승인된-provider> --expected-tts-model <승인된-model>
|
||||
```
|
||||
|
||||
50분 full soak는 같은 기대값에 `--duration-seconds 3000`, `--microphone-device <명시-장치>`,
|
||||
`--confirm-physical-capture`를 추가하고 사용자가 실행 직전에 물리 캡처에 명시 동의한 경우에만 실행한다.
|
||||
- 2026-08-07 G7 external-proof readiness: Session 첫 음성 사용은 서버 30일·원음 미보존 consent ledger가
|
||||
성공하기 전 `getUserMedia`와 voice WebSocket을 시작하지 않는다. controlled provider와 synthetic stream을
|
||||
사용한 `voice-success.spec.ts` single-run **2/2**에서 원장 지연 중 둘 다 0회, 성공 뒤 각각 정확히 1회,
|
||||
지연 권한 뒤 pause 시 track stop·WS 0을 확인했다. API voice/G7 focused **92 passed**, external evidence
|
||||
runner/checker와 release gate contract **31 passed**, typecheck·API type
|
||||
contract·Ruff·py_compile을 통과했다. `soak-public-voice-websocket.py` v4, `/admin/voice-runtime`,
|
||||
`capture-g7-runtime-evidence.py`, `capture-g7-topology-evidence.py`, independent human-held-out evaluator를
|
||||
`check-g7-external-proof.py`가 같은 public host·겹치는 50분 시간창으로 묶는다. 실제 마이크·운영 Deepgram·
|
||||
실제 참가자 evidence는 없으므로 G7은 BUILD다. 상세는
|
||||
`ops/outcome-os-g7-external-proof-readiness-2026-08-07.md`가 소유한다.
|
||||
- 2026-08-07 G7/G8 시각 QA: 데스크톱·Pixel 5에서 focused **16/16**, typecheck·build·cosmetic-filter를
|
||||
통과했다. G8 승인 차단 이유를 `title` 의존에서 상시 문구·`aria-describedby`·semantic form/Enter 제출로
|
||||
바꾸고, G7 이벤트 최소 24×24px와 시간축 키보드 포커스를 수치 회귀로 고정했다. 상세는
|
||||
`ops/outcome-os-g7-g8-visual-qa-2026-08-07.md`가 소유한다.
|
||||
- 2026-08-07 G0~G8 release-only assembly: dirty **257파일**을 related 235/mixed 4/excluded 18로 전건
|
||||
분류했다. `api.gen.ts`는 clean HEAD + related API 소스에서 공식 재생성하고 Windows checkout에서도 선언
|
||||
해시를 다시 확인했다. 최초 공개 승격 patch는 229 files, SHA-256 `d9ac3c85...34d41`로 두 번 동일하게
|
||||
조립돼 clean HEAD/canonical index 적용 검사를 통과했다. 최종 SSOT 반영 뒤 다시 결정적 조립·검사한다.
|
||||
- 2026-07-15 전체 검증: `npm run e2e:parallel` **166/166 passed**(2.5분), `npm run e2e:single-run` **49/49 passed**(23.2분). 합계 **215/215 passed**. AI 튜터 DB 영속화는 정상 provider 응답이 2분을 넘을 수 있어 해당 테스트만 같은 실엔진 묶음의 장시간 기준인 240초를 사용한다.
|
||||
- `e2e/voice-success.spec.ts`는 직접 `/voice/ws` 캐스케이드, Session 텍스트 턴의
|
||||
`POST /voice/speech`, Session 마이크 UI를 함께 검증한다. 브라우저 `<audio>.play()`가 차단된 조건에서도
|
||||
|
|
@ -322,6 +472,9 @@ VITE_API_BASE=http://127.0.0.1:8000 npm run e2e # 프록시 대신 API
|
|||
- 2026-07-01 focused 검증: `npx playwright test e2e/admin.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --grep "approved admin without onboarding"` **2 passed**. 승인된 `role=admin` 사용자의 세션에 `admin_access=false`, `onboarding_completed_at=null`이 남아도 `/admin`이 `/onboarding`으로 우회하지 않고 관리 콘솔의 `/admin/*` API를 호출하는지 fixture로 고정한다.
|
||||
- 2026-07-15 보태니컬 글래스 UI·SSOT 검증: `npm run check:design-ssot` + `npm run typecheck` + `npm run build` 통과, `npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --reporter=line` 시각 게이트 **15/15**, `npx playwright test e2e/auth-visual.spec.ts --project=chromium-single-run --reporter=line` **1/1**, `npx playwright test e2e/session-layout.spec.ts e2e/learner.spec.ts e2e/session-review.spec.ts --project=chromium-desktop --project=chromium-mobile` **46/46**, 로그인→온보딩 focused desktop/mobile **2/2**. 공통 AppShell GNB, Theme store, Surface variant의 소유권과 전 폭 대시보드/리뷰 탭, 로그인·온보딩 라이트/다크 390/1280px, 고해상도 보태니컬 자산을 함께 고정한다. 라이트 테마도 패널당 복수 굴절 그라데이션, backdrop blur, 헤어라인, 그림자를 computed style로 단언하며 모바일 셸이 보태니컬 배경을 제거하지 않는지 검사한다. 관리자 사용자 표는 semantic table, 정렬 헤더, 1440px 최소 폭과 표 전용 가로 스크롤을 desktop/mobile에서 검증한다.
|
||||
- 2026-07-31 활성 세션 보태니컬 워크스페이스 검증: `full-sweep-session.spec.ts`의 1536×1024 계약이 좌 326px·우 357px 레일, 1408px 상단/본문, 1468px 하단 제어바, 좌우/스테이지 보태니컬 WebP 연결과 라이트 테마를 실측한다. 세션 전수 desktop/mobile **32 passed / 2 skipped**, `session-layout` **8/8**, 7폭 `layout-visual-gate` **15/15**, `check:design-ssot`·typecheck·build를 통과했다. 1366×768 이하는 스테이지보다 자막이 작아지지 않게 별도 압축 계약을 적용한다.
|
||||
- 2026-07-31 관리자 Provider·모델별 비용 원장 검증: `python -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` **66 passed**. Claude CLI SDK 비용 추정값과 Agy/Gemini·Codex·Claude API 공식 참조단가 추정을 분리하고, 기존 DB의 0달러 Agy 행을 조회 시 재산정하며, 단가 미등록 모델은 `미산정`으로 남기는 계약을 고정했다. `npm run generate:api-types`·`check:api-types`·typecheck·build를 통과했고, 관리자 AI desktop/mobile focused E2E **2 passed**와 7폭 focused layout visual gate **1 passed**에서 Gemini 원장 `$0.06`·`참조단가` 표시와 레이아웃 containment를 확인했다. 공개 API 프로세스를 재시작하고 Cloudflare Pages production `11b3e11f`에 배포했다. 인증된 공개 `/admin/usage?window_days=30`은 `source=database`, `durable=true`, `gemini-3.6-flash-high` 5호출·입력 35,703·출력 1,129·참조단가 `$0.062022`를 반환했고, 검증용 인증 세션은 즉시 삭제했다. 커스텀 도메인의 `AdminAi-BfxMUlzj.js`와 `AdminAi-XHkda_d4.css`는 올바른 JavaScript/CSS MIME으로 200을 반환한다.
|
||||
- 2026-07-31 Claude CLI 토큰 원장 focused 검증: result `modelUsage`의 전체 agent tree를 합산하고 최상위 `usage` 폴백, cache read/create 입력 포함, generate·SSE done 전파를 회귀화했다. 전체 backend **436 passed**, gateway **45 passed**, API type generation/check·typecheck·build, 관리자 AI desktop/mobile **2 passed**. 신규 live Opus generate는 입력 **31,918**·출력 **4**·비용 추정 `$0.124862`, Haiku SSE done은 입력 **30,450**·출력 **159**·비용 추정 `$0.061685`를 반환했다. 운영 DB 30일 원장의 과거 Claude 행은 역산하지 않고 `tokens=미계량`, `token_unmetered_turns=194`, `cost_basis=provider_estimate`로 분리됨을 임시 인증 세션으로 확인하고 세션을 즉시 폐기했다.
|
||||
- 2026-07-31 Claude CLI 과거 토큰 백필 검증: 로컬 Claude JSONL **3,908개**의 assistant usage record **3,848개**를 읽되 본문을 출력하지 않고, 정규화 응답 SHA-256과 DB 생성 시각 창(-30초~+180초)이 모두 일치하며 후보가 정확히 1개인 턴만 복구했다. 운영 DB의 과거 0/0 Claude 턴 **442건** 중 **169건**을 실제 입력 **5,179,999**·출력 **46,910** 토큰으로 갱신했고, 불일치 **273건**은 계속 `미계량`, 모호한 후보는 **0건**이었다. apply는 `--expected-matches 169` 가드와 행별 `UPDATE 1` 확인을 통과했고, 적용 후 dry-run 재실행에서 추가 exact match **0건**을 확인했다. 전체 backend **439 passed**, gateway **45 passed**이며, 공개 관리자 브라우저 **1 passed**에서 Claude 행의 실제 토큰과 부분 계량 `125/183회` 표시를 확인하고 임시 세션을 폐기했다.
|
||||
|
||||
레이아웃·시각 회귀 게이트(핵심 합격선):
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue