원래 active goal 의 완료 선언 조건 네 가지를 실행으로 대조했다. 조건 2(학생 폐루프 실 DB browser), 3(SSOT 일치), 4(G7 비합성)는 충족이고, 조건 1은 G7 외부 GATE 때문에 부분 충족이다. G8 자체는 종료됐다. 재검증: API 914, gateway 58, executor 28, probe 11, helper launcher 37, release agent 21, MeloTTS 16, local whisper 37, SSOT FAIL 0, dashboard E2E 10/10, web api-types/typecheck/build, ruff clean. G7 체커는 exit 1 을 유지해 합성으로 닫지 않았음을 증명한다.
305 lines
19 KiB
Markdown
305 lines
19 KiB
Markdown
# Vignette G0~G8 완료 핸드오프
|
|
|
|
> Updated: 2026-08-07 KST (G8 실제 rollback 종료 반영)
|
|
> Workspace: `D:\workspace\vignette`
|
|
> 이 문서는 다음 에이전트가 **G0~G8 아홉 목표 중 마지막으로 남은 G7 외부 게이트를 닫기 위한** 실행 기준이다.
|
|
|
|
## 0. 현재 상태 한 줄 요약
|
|
|
|
**G0~G6·G8은 internal DONE + 실제 runtime 증거로 종료됐다. 남은 것은 G7 외부 4-artifact 게이트 하나이며,
|
|
이건 코드로 풀 수 없고 사용자가 제공해야 하는 운영 자원·동의가 있어야 진행된다.**
|
|
|
|
| Goal | 판정 | 완료 증거 |
|
|
|---|---|---|
|
|
| G0 Measurement Foundation | DONE | provenance census 29/29, unknown/missing/orphan/null/total violations 0 |
|
|
| G1 Alliance Core | DONE | prompt 1.2 read-skew fix, prediction 24/24 ready, direction 9/9, error 0, recall 94.4%, precision 73.9% |
|
|
| G2 Outcome Trajectory | DONE | benchmark accuracy/early-warning recall 1.0, false alert 0, 실 DB 10 sessions/30 measurements |
|
|
| G3 Rupture & Repair | DONE | macro-F1 1.0, status 1.0, gaming 0, missed→partial→resolved 실 DB/API |
|
|
| G4 Deliberate Practice | DONE | completed-session observer, actual API/DB attempts, teacher correction, returned-practice browser 폐루프 |
|
|
| G5 Calibration & Transfer | DONE | actual transfer execution, independent/model-run/instrument/evidence provenance, DB/browser idempotency |
|
|
| G6 Supervision & Research | DONE | safety event metadata-only projection, safety priority 1 > deterioration 2, raw detail 0 |
|
|
| G7 Multimodal Alliance | **internal DONE · external GATE** | consent/withdrawal, synthetic soak 59/59, public unauth WSS 1008, focused 119 PASS |
|
|
| G8 Continuous Improvement | **DONE** | 격리 NAS 실제 image rollback 2회 + executed receipt 2건 (아래 §3) |
|
|
|
|
대시보드 status count는 **33 done / 2 doing / 0 planned**다.
|
|
|
|
### 완료 조건 판정 (2026-08-08 재검증)
|
|
|
|
원래 active goal의 완료 선언 조건 네 가지를 실행으로 대조한 결과다.
|
|
|
|
| # | 조건 | 판정 | 근거 |
|
|
|---|---|---|---|
|
|
| 1 | G0~G8 각각의 코드 계약과 실제 runtime 증거 | **부분 충족** | G0~G6·G8은 충족. **G7만 외부 GATE로 열려 있다** |
|
|
| 2 | 학생 홈→회기→리뷰→처방→재연습→전이 폐루프가 실제 API/DB/browser 통과 | **충족** | 일회용 클론에서 `returned-practice-db-closed-loop` desktop 2/2 + mobile 2/2, route mock 0 |
|
|
| 3 | current source 증거와 대시보드·TODO·backlog 일치 | **충족** | SSOT checker FAIL 0, unit 5/5, dashboard E2E 10/10, count 33/2/0이 카드와 일치 |
|
|
| 4 | G7을 가짜·합성 증거로 DONE 처리하지 않음 | **충족** | `check-g7-external-proof.py` exit 1 유지, G7 카드는 `GATE` |
|
|
|
|
재검증 수치: API **914 passed**, gateway **58**, executor **28**, probe **11**, helper launcher **37**,
|
|
release agent **21**, MeloTTS 사이드카 **16**, local whisper 사이드카 **37**, SSOT FAIL **0**,
|
|
dashboard E2E **10/10**, web api-types·typecheck·build 통과, ruff clean.
|
|
|
|
**따라서 `update_goal complete`를 호출하지 않는다.** 조건 1이 G7 때문에 미충족이고, 조건 4가 그것을
|
|
합성 증거로 메우는 것을 금지한다. G8 자체는 종료됐다(§3).
|
|
|
|
## 1. 작업 시작 전 반드시 읽을 파일
|
|
|
|
1. `AGENTS.md`
|
|
2. `docs/README.md`
|
|
3. `docs/HANDOFF.md` — 현재 문서
|
|
4. `docs/dev_dashboard.html` — 상태 SSOT
|
|
5. `docs/TODO.md` — 열린 작업 SSOT
|
|
6. `docs/ops/backlog-2026-06-26.md`
|
|
7. `docs/ops/outcome-os-g7-external-proof-readiness-2026-08-07.md` — **다음 작업의 핵심**
|
|
8. `docs/ops/nas-preview-g8-rollback-proof-runbook.md`
|
|
9. `docs/ops/nas-preview-deployment-evidence-2026-08-07.md`
|
|
10. `docs/ops/public-db-recovery-rehearsal-2026-08-07.md`
|
|
|
|
`docs/archive/`는 현재 상태 근거로 읽지 않는다.
|
|
|
|
## 2. 절대 보존 경계
|
|
|
|
- Windows 11 + PowerShell 환경이다. 실행 전 OS·셸·도구 경로를 다시 확인한다.
|
|
- 명령은 PowerShell 5.1 호환 문법을 기본으로 작성한다. NAS 원격 스크립트는 **UTF-8 base64 전달 방식**을 쓴다.
|
|
(`$()`가 PowerShell에서 먼저 확장되는 것을 막는다.)
|
|
- worktree는 큰 규모로 dirty하다. `git reset --hard`, `git checkout --`, 대규모 자동 포맷, 임의 삭제 금지.
|
|
- Git commit/stage/push는 사용자가 요청하기 전에는 하지 않는다.
|
|
- 공개 복구 DB, 원본 volume, pre-recovery container, dump, NAS named volume, 이전 API/Web 이미지를 삭제하지 않는다.
|
|
- **로컬 포트 8001(공개 API) · 5173(공개 Web) · 55432(공개 DB) · 9099/9100(엔진)은 공개 런타임이다.**
|
|
`scripts/dev-up.ps1`은 8000/5173 리스너를 정리하므로 공개 런타임이 떠 있는 동안 실행하지 않는다.
|
|
- 비밀값, 이메일, cookie, 사용자 UUID가 포함된 raw response, `.env` 내용은 로그·증거·채팅에 출력하지 않는다.
|
|
|
|
## 3. G8 — 종료됨 (2026-08-07 21:04~21:12 KST)
|
|
|
|
### Gate6 계약 정정 (성립 불가능했던 이전 계약을 코드로 교체)
|
|
|
|
감사 대상 current API 이미지 `sha256:52e0e816…8b2d`가 `com.docker.compose.project=vignette-preview-20260807`,
|
|
`service=api`, `version=2.20.1` **image label**을 갖고 있다. 따라서 "helper의 `com.docker.compose.*` key 0개"는
|
|
감사되지 않은 다른 이미지를 쓰지 않는 한 성립하지 않는다. 계약을 **key 부재 → 소속(membership)** 으로 바꿔
|
|
구현했다.
|
|
|
|
- 코드: `scripts/launch-nas-preview-g8-helpers.py`
|
|
- 테스트: `scripts/test_launch_nas_preview_g8_helpers.py` — **37/37**
|
|
- 계약: image 상속 label을 baseline으로 읽고 container의 모든 compose label이 baseline과 같거나 선언된 격리
|
|
override인지 검사 · 최종 project ≠ target · 최종 service ∉ {api,web,db,proxy} · argv에 target project/service
|
|
label 미주입(fake-runner) · exact container name/ID/`docker inspect` 증거 보존
|
|
- 런북: `docs/ops/nas-preview-g8-rollback-proof-runbook.md`
|
|
|
|
### 실제 실행 결과
|
|
|
|
| plan | receipt | 활성화된 API/Web 이미지 |
|
|
|---|---|---|
|
|
| `rollback-old` | `nas-g8-723eeef22eab05e63e3fafb0` | `79ec…4450` / `c530…2f28` |
|
|
| `restore-current` | `nas-g8-2738846cf2cf4fbe8ce0fc26` | `52e0…8b2d` / `6fdb…f215` |
|
|
|
|
- release gate·approval 각각 2회 멱등, lifecycle `executed`, artifact/approval/receipt binding, control-plane 분리 검증
|
|
- DB: `audit.ci_lifecycle_event` `rollback/executed` 2 · `audit.ci_human_approval_event` `authorize_rollback` 2 ·
|
|
`app.ci_release_gate` 2(전부 `pending_human_approval`, silent auto-promotion 0) · `ci_gate_artifact` 8
|
|
- HMAC journal 6 records, `previous_hash` 체인 전수 PASS, SHA256 `a5594feb…0690`
|
|
- 최종 상태: health 3/3, OpenAPI 126, auth 401, Web 200, helper 0, listener 0, 비밀 env 파기
|
|
- **계획 이탈:** Windows SSH 터널 `18018→8018`은 NAS sshd가 `administratively prohibited`로 direct-tcpip를 거부해
|
|
쓸 수 없었다. **sshd 설정은 바꾸지 않았고**, 같은 격리 계약의 NAS-side probe 컨테이너에서 loopback으로
|
|
실행해 control-plane(8018)/preview(8088) origin 분리는 그대로 유지했다. 다음 에이전트도 NAS에서
|
|
포트 포워딩을 기대하지 말 것.
|
|
- 기계 판독 증거: `docs/ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json`
|
|
|
|
## 4. 공개 서비스 복구 상태 — 이미 완료, 다시 망가뜨리지 말 것
|
|
|
|
공개 계정·회기 DB 복구는 2026-08-07 18:26 KST에 완료됐다.
|
|
|
|
- Public Web `https://vignette.chanpaca.net` · Public API `https://api-vignette.chanpaca.net` (origin `127.0.0.1:8001`)
|
|
- active DB container `vignette-dev-db`, volume `vignette_recovered_prod_20260807`, restart `unless-stopped`
|
|
- 복구 집계: users 84, sessions 30, turns 705, Google users 16, orphan sessions 0
|
|
- health `environment=prod`, `db=true`, `engine=true`, `engine_mode=claude_cli`, dev-login disabled, unauth `/auth/me` 401
|
|
- 공개 OpenAPI 119 paths · watchdog `VignettePublicRuntimeWatchdog` 5분 주기
|
|
|
|
보안상 과거 `auth_session`은 복원하지 않았다. 사용자는 Google 재로그인이 필요하다.
|
|
|
|
보존물: pre-recovery container `vignette-dev-db-pre-recovery-20260807-182642`,
|
|
pre-cutover dump `…20260807-091057Z.dump` SHA256 `6b84d5c8…af1f`,
|
|
recovered dump `…20260807-092630Z.dump` SHA256 `d7bcc396…68ed`,
|
|
post-cutover dump `…20260807-095511Z.dump` SHA256 `660695c8…65b88`.
|
|
|
|
공개 DB에는 current dirty source를 배포하지 않는다.
|
|
|
|
## 5. current source NAS 배포 — 완료
|
|
|
|
- URL `http://100.116.83.60:8088` · project `vignette-preview-20260807` · remote root `/volume1/docker/vignette-preview-20260807`
|
|
- active release SHA `6030a677af7e87cbfabc422b553d108d53414fd3c446548734a13b036d35c611`
|
|
- API `sha256:52e0e816…8b2d` / Web `sha256:6fdbb646…f215` (previous: `79ec731f…0450` / `c530213f…62f28`)
|
|
- DB volume `vignette-preview-20260807_pgdata` · pre-proof dump `vignette-preview-g8-preproof-20260807T110610Z.dump`
|
|
SHA256 `92ed4736…1570f`
|
|
- candidate browser E2E 108/108(634.578s), postdeploy SSE→DB review PASS
|
|
- **G8 rollback/restore 이후 재검증:** 실제 브라우저 SSE→DB review 재실행 PASS(35.0s)
|
|
|
|
배포 중 첫 108 gate가 103/5로 fail-closed된 이력(G5 fixture drift, StrictMode retry fixture, `shell.css` manifest 누락)은
|
|
지우지 않는다.
|
|
|
|
### ⚠ 배포된 SHA는 비-secure origin 결함을 갖고 있다 (수정은 소스에만 있음)
|
|
|
|
배포 후 NAS 프리뷰(`http://100.116.83.60:8088`, 평문 HTTP·비-localhost)에 전체 회기 스펙을 돌려보니 24건이
|
|
실패했고, 원인은 단 하나였다. 페이지 스냅샷의 실제 예외는 `crypto.randomUUID is not a function`이다.
|
|
이 API는 **secure context(HTTPS 또는 localhost)에서만** 노출되는데 제품 코드 18곳이 fallback 없이 직접
|
|
호출했고, `RuptureRepairCard.tsx`는 렌더 시점(`useRef`)에 호출해 회기 리뷰 라우트 전체가 error boundary로
|
|
떨어졌다. 릴리스 게이트의 108/108은 **localhost 후보 스택**(secure context)에서 돌았기 때문에 이 경로를
|
|
한 번도 밟지 않았다.
|
|
|
|
- 수정: `apps/web/src/lib/uuid.ts`의 `randomUuid()`로 통일. fallback도 `crypto.getRandomValues`를 우선
|
|
사용해 idempotency key의 예측 불가능성을 유지하고, Web Crypto가 아예 없을 때만 `Math.random`으로 내려간다.
|
|
- 회귀: `apps/web/e2e/insecure-context-uuid.spec.ts` **6/6** (직접 호출 0건 검사 포함), typecheck·build 통과.
|
|
- **아직 NAS에 배포하지 않았다.** 배포된 SHA `6030a677…c611`은 여전히 결함 빌드다. 다음 배포 때
|
|
release agent로 승격하고, 승격 뒤에는 NAS origin에서 회기 스펙을 다시 돌려 24건이 사라지는지 확인한다.
|
|
- 교훈: candidate gate를 localhost에서만 돌리면 secure-context 전용 API 결함을 못 잡는다. 배포 대상과
|
|
같은 scheme/host 형태에서 최소 한 번은 회기 리뷰 라우트를 열어봐야 한다.
|
|
|
|
## 6. **다음 에이전트의 유일한 남은 목표 — G7 외부 종료 Gate**
|
|
|
|
G7 내부 구현은 완료됐고 `scripts/check-g7-external-proof.py`는 현재 의도적으로 exit 1이다.
|
|
네 artifact를 **같은 public host, 겹치는 50분 시간창**으로 수집해야 한다.
|
|
|
|
```powershell
|
|
& $py -X utf8 -B scripts/check-g7-external-proof.py `
|
|
--voice-soak <soak.json> --runtime <runtime.json> `
|
|
--topology <topology.json> --human-voice-gain <pack.json>
|
|
```
|
|
|
|
1. `scripts/soak-public-voice-websocket.py` v4 — 운영 Deepgram/OpenAI TTS, authenticated public WSS,
|
|
**명시 동의 물리 마이크** 50분 양방향 `passed`. `--confirm-physical-capture` 없이는 장치 열거·캡처를 하지 않는다.
|
|
2. `scripts/capture-g7-runtime-evidence.py` — 같은 시간창의 관리자 endpoint worker/Uvicorn queue high-water.
|
|
3. `scripts/capture-g7-topology-evidence.py` — 같은 host·exact image의 50분 cgroup/proc/Docker/TCP high-water.
|
|
4. 독립 blind human voice-gain pack — 최소 30명 / 50회기 / 150 paired axis / blind evaluator 2인 /
|
|
ICC(A,1) ≥ 0.75 · κ ≥ 0.70 · gain ≥ 0.01 · participant-cluster bootstrap 10,000회 95% CI lower > 0.
|
|
|
|
준비 상세는 `docs/ops/outcome-os-g7-external-proof-readiness-2026-08-07.md`.
|
|
|
|
**사용자에게 받아야 하는 것 (코드로 대체 불가):**
|
|
|
|
- 운영 Deepgram key·quota 사용 권한
|
|
- authenticated learner/admin session 또는 안전한 `storageState` 생성 협조
|
|
- 물리 마이크 50분 실행에 대한 **명시적 동의**
|
|
- 실제 참가자·독립 평가자 운영 승인
|
|
|
|
합성 label이나 무동의 mic probe로 대체하지 않는다. `check-g7-external-proof.py` exit 0 전에는 G7 메인 상태를
|
|
DONE으로 바꾸지 않는다.
|
|
|
|
## 7. 학생 자기주도 학습 폐루프
|
|
|
|
```text
|
|
학습자 홈 추천 → 새 회기/사전 설정 → 실제 Session → 종료 리뷰 → G4 처방 또는 G5 전이 의도
|
|
→ 별도 재연습 회기 → completed-session observer → 실제 G4 attempt / G5 transfer execution
|
|
→ read-model reload → before/after·진행도·멱등 재확인
|
|
```
|
|
|
|
실제 DB-backed browser 증거: `apps/web/e2e/returned-practice-db-closed-loop.spec.ts` +
|
|
`apps/web/e2e/harness/prepare-returned-practice-db.py`, desktop 2/2 + mobile 2/2, route mock 0,
|
|
visible raw UUID 0, getUserMedia/enumerateDevices 0, horizontal overflow 0.
|
|
|
|
이 harness는 **disposable clone**(전용 DB container + 전용 API 포트 + 전용 vite 포트)에서만 실행한다.
|
|
공개 런타임 포트를 재사용하지 않는다. `--api-base-url`, `--database-url`, `--practice-internal-token`,
|
|
`--transfer-internal-token`이 필요하고 API health의 `db`·`engine`이 모두 true여야 한다.
|
|
|
|
2026-08-07 재실행 절차(그대로 재현 가능):
|
|
|
|
1. `docker run -d --name vignette-g8-e2e-db-<날짜> -p 127.0.0.1:55439:5432` + `infra/db/init` 마운트,
|
|
`POSTGRES_USER=vignette_owner` / `APP_DB_USER=vignette_app`. `app.ci_regression_dag_node`가 생기면 준비 완료.
|
|
2. 별도 엔진 게이트웨이를 **새 포트**(예: 9199)에 띄운다. 상주 게이트웨이의 claude 세션이 죽어 있으면
|
|
`engine=false`가 되므로 공개용 9099를 재사용하지 않는다.
|
|
3. uvicorn API를 8021에, vite를 5199에 띄우고 `ENGINE_URL`을 2번 게이트웨이로 지정한다.
|
|
4. harness 실행 → `E2E_RETURNED_PRACTICE_DB_CLOSED_LOOP=1` + `E2E_RETURNED_PRACTICE_FIXTURE`로 spec 실행.
|
|
5. 결과 기준: desktop 2/2 + mobile 2/2 = **4 passed**. 끝나면 컨테이너·프로세스를 모두 정리한다.
|
|
|
|
G4/G5 핵심 production bug 수정은 보존한다.
|
|
|
|
- G4 runtime SQL `digest(...)` → `app.digest(...)`
|
|
- G5 JSONB bind는 `json.dumps` string이 아니라 dict/list object 전달
|
|
- route는 nested Pydantic suite를 `body.model_dump()` dict로 깨지 않고 typed object로 전달
|
|
|
|
## 8. 최종 검증 명령과 현재 기준선
|
|
|
|
```powershell
|
|
$py = 'C:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe'
|
|
$ruff = 'C:\Users\encep\AppData\Local\hermes\hermes-agent\venv\Scripts\ruff.exe'
|
|
```
|
|
|
|
### Backend full — 기준 API **898 passed**, gateway **58 passed**
|
|
|
|
```powershell
|
|
Set-Location D:\workspace\vignette\apps\api
|
|
& $py -X utf8 -B -m pytest -p no:cacheprovider app -q
|
|
& $py -X utf8 -B -m pytest -p no:cacheprovider engine_gateway -q
|
|
```
|
|
|
|
### G8 executor/probe/helper/release governance — 기준 28 / 11 / 37 / 21
|
|
|
|
```powershell
|
|
Set-Location D:\workspace\vignette
|
|
& $py -X utf8 -B -m unittest scripts/test_serve_nas_preview_rollback_executor.py
|
|
& $py -X utf8 -B -m unittest scripts/test_probe_nas_preview_g8_rollback.py
|
|
& $py -X utf8 -B -m unittest scripts/test_launch_nas_preview_g8_helpers.py
|
|
& $py -X utf8 -B -m pytest -p no:cacheprovider scripts/test_outcome_os_release_agent.py -q
|
|
& $ruff check scripts/serve-nas-preview-rollback-executor.py scripts/test_serve_nas_preview_rollback_executor.py scripts/probe-nas-preview-g8-rollback.py scripts/test_probe_nas_preview_g8_rollback.py scripts/launch-nas-preview-g8-helpers.py scripts/test_launch_nas_preview_g8_helpers.py scripts/run-outcome-os-release-agent.py scripts/test_outcome_os_release_agent.py
|
|
```
|
|
|
|
### Web contract/type/build
|
|
|
|
```powershell
|
|
Set-Location D:\workspace\vignette\apps\web
|
|
npm run check:api-types
|
|
npm run typecheck
|
|
npm run build
|
|
```
|
|
|
|
### Dashboard SSOT + E2E — 기준 SSOT PASS(FAIL 0), unit 5/5, dashboard 10/10
|
|
|
|
```powershell
|
|
Set-Location D:\workspace\vignette
|
|
& $py -X utf8 -B scripts/check-dev-dashboard-ssot.py
|
|
& $py -X utf8 -B -m pytest -p no:cacheprovider scripts/test_dev_dashboard_ssot.py -q
|
|
|
|
Set-Location D:\workspace\vignette\apps\web
|
|
.\node_modules\.bin\playwright.cmd test e2e/dev-dashboard.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --reporter=line
|
|
```
|
|
|
|
status count를 바꾸면 `scripts/check-dev-dashboard-ssot.py`의 `EXPECTED_STATUS_COUNTS`와
|
|
`apps/web/e2e/dev-dashboard.spec.ts`의 `metrics.done`/`metrics.doing`을 **함께** 갱신한다.
|
|
|
|
### 격리 NAS 런타임 회기 E2E
|
|
|
|
```powershell
|
|
Set-Location D:\workspace\vignette\apps\web
|
|
$env:PLAYWRIGHT_BASE_URL='http://100.116.83.60:8088'
|
|
$env:PLAYWRIGHT_SKIP_WEB_SERVER='1'
|
|
node.exe .\node_modules\@playwright\test\cli.js test e2e/session-layout.spec.ts e2e/session-persistence.spec.ts `
|
|
e2e/self-directed-learning-loop.spec.ts e2e/alliance-pulse.spec.ts e2e/outcome-trajectory.spec.ts `
|
|
e2e/rupture-repair.spec.ts e2e/deliberate-practice.spec.ts e2e/calibration-transfer.spec.ts `
|
|
e2e/supervision-research.spec.ts e2e/multimodal-alliance.spec.ts e2e/continuous-improvement-admin.spec.ts `
|
|
--project=chromium-desktop --project=chromium-mobile --project=chromium-single-run --workers=1 --reporter=line
|
|
```
|
|
|
|
전체 Playwright inventory는 610 tests / 44 files다. 실행 환경/API/DB를 정확히 맞추지 않고 fixture failure를
|
|
제품 failure로 오인하지 않는다. 같은 blocker가 두 번 반복되면 전체 재시도 대신 원인·증거·수정 계획을 먼저 보고한다.
|
|
|
|
## 9. 핵심 변경 파일
|
|
|
|
- `scripts/launch-nas-preview-g8-helpers.py` · `scripts/test_launch_nas_preview_g8_helpers.py` (신규, Gate6 계약)
|
|
- `scripts/serve-nas-preview-rollback-executor.py` · `scripts/test_serve_nas_preview_rollback_executor.py`
|
|
- `scripts/probe-nas-preview-g8-rollback.py` · `scripts/test_probe_nas_preview_g8_rollback.py`
|
|
- `scripts/run-outcome-os-release-agent.py` · `scripts/test_outcome_os_release_agent.py`
|
|
- `scripts/check-dev-dashboard-ssot.py` · `scripts/test_dev_dashboard_ssot.py`
|
|
- `scripts/check-g7-external-proof.py` · `scripts/soak-public-voice-websocket.py` ·
|
|
`scripts/capture-g7-runtime-evidence.py` · `scripts/capture-g7-topology-evidence.py`
|
|
- `apps/web/src/lib/uuid.ts` · `apps/web/e2e/insecure-context-uuid.spec.ts` (신규, 비-secure origin 결함 수정)
|
|
- `apps/web/e2e/dev-dashboard.spec.ts` · `apps/web/e2e/returned-practice-db-closed-loop.spec.ts` ·
|
|
`apps/web/e2e/harness/prepare-returned-practice-db.py`
|
|
- `docs/dev_dashboard.html` · `docs/TODO.md` · `docs/README.md` · `docs/ops/backlog-2026-06-26.md`
|
|
- `docs/ops/nas-preview-g8-rollback-proof-runbook.md` ·
|
|
`docs/ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json` ·
|
|
`docs/ops/nas-preview-deployment-evidence-2026-08-07.md`
|
|
|
|
## 10. 최종 원칙
|
|
|
|
- source-only PASS를 runtime DONE으로 부르지 않는다.
|
|
- health만 보고 배포 완료라고 하지 않는다. auth, OpenAPI, assets, browser SSE→DB review를 함께 본다.
|
|
- synthetic control plane을 실제 NAS rollback으로 과장하지 않는다.
|
|
- G7 물리 마이크·사람 평가를 무동의/합성 데이터로 대체하지 않는다.
|
|
- current/previous images와 DB backup을 확인하기 전 destructive operation을 실행하지 않는다.
|
|
- 성공보다 정직한 fail-closed 증거가 우선이다.
|