From 80bcacc72302ebd660db4df1c536272284122727 Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Wed, 12 Aug 2026 18:20:53 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=B5=EA=B0=9C=20Web=20=ED=9B=84=EB=B3=B4?= =?UTF-8?q?=20=EC=82=AC=EC=A0=84=EA=B2=80=EC=A6=9D=20=EC=A6=9D=EA=B1=B0=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/HANDOFF.md | 8 ++ docs/TODO.md | 6 + docs/dev_dashboard.html | 1 + docs/ops/backlog-2026-06-26.md | 4 + .../public-web-preflight-2026-08-12.json | 116 ++++++++++++++++++ 5 files changed, 135 insertions(+) create mode 100644 docs/ops/evidence/public-web-preflight-2026-08-12.json diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 8f3fe32..dc2aeee 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -56,6 +56,14 @@ G8 배포 source 기준선은 branch `master`, HEAD `61a41d1f08239b5f9e99cfae42a `periodic-learner-e2e-20260812-171547.json`·SHA-256 `8c11a136…af8e3`이다. 487.3초에 동일 학습자 브라우저 회기 생성·SSE·review ready·G4/G5 `0→1→1`, 별도 returned desktop/mobile 4/4와 route mock 0을 통과했고 public/NAS/active DB 접촉 0, container·volume·network·listener·temp 잔여 0을 독립 재확인했다. +- 공개 Web 보정은 detached-clean `00f851a6…c229`·tree `9f78cd16…9486` 후보로 배포 직전까지 고정했다. + API generated type LF 계약, `npm ci --ignore-scripts`, API type contract, typecheck, 2회 byte-identical production + build와 상단 44px·로그인 무가로넘침·자기주도 폐루프 focused E2E 12/12를 통과했다. 새 primary CSS/JS는 + `index-Dzmt2kJS.css` SHA `da5e8535…fb9a`와 `index-BUoTLplD.js` SHA `08654d08…3c05`다. 현재 공개와 최근 + Pages 5개 origin의 지연 로드 자산 133개를 더해 최종 732파일로 만들었고 현행 공개 CSS/JS SHA도 exact + 보존했다. actual 공개는 health ok·db/engine true지만 구 Web이라 모바일 상단 6개 조작면이 44px 미만이고, + NAS는 health timeout·9100 listener 0·로그인 overflow 10px다. 공개/NAS 배포는 0이며 기계 판독 증거는 + `docs/ops/evidence/public-web-preflight-2026-08-12.json`이다. - 앞선 두 DB init 실패는 `core.autocrlf=true` detached checkout이 `99_app_role.sh`를 CRLF로 만든 것이었고, `.gitattributes`의 `*.sh text eol=lf` 뒤 새 worktree에서 tracked shell CRLF 0·해당 파일 CR 0과 실제 DB healthy를 확인해 닫았다. 공통 톱바의 브랜드·공간 전환·테마·로그아웃은 desktop/mobile 모두 44px이고, auth overflow와 diff --git a/docs/TODO.md b/docs/TODO.md index d95d396..3056540 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -38,6 +38,12 @@ 남은 범위는 예약 실행, 실패 알림, NAS/off-host 암호화 복제, 주기적 restore drill과 보존 정책이다. - [ ] **공개 Google OAuth 실제 `/turn` proof** — 로그인 계정으로 `storageState` 캡처 → `E2E_PUBLIC_AUTH=1` + `chromium-public-auth` 1회 통과. 실행 명령은 대시보드 "다음 실행 명령"/`HANDOFF.md`. (소유자 보류 중) +- [ ] **공개 Web 모바일 보정 Pages 배포** — detached-clean `00f851a6…c229`·tree `9f78cd16…9486` 후보는 + API type/typecheck, 2회 결정적 build, 상단 44px·로그인 무가로넘침·자기주도 폐루프 E2E 12/12와 현재/최근 + Pages 자산 133개 보존을 통과했다. actual 공개는 정상 서비스 중이지만 구 Web이라 모바일 상단 6개가 44px + 미만이고, NAS 로그인은 10px overflow다. 소유자 승인 뒤 Pages만 단일 owner로 배포하고 custom-domain 새 + asset SHA/MIME, 기존 asset 200, desktop/mobile 화면을 재검증한다. 공개 API/DB·Scheduled Task는 건드리지 않는다. + 증거: `ops/evidence/public-web-preflight-2026-08-12.json`. - [ ] **Compose 패키징용 `infra/.env` owner-secret** — 현재 운영 direct-runtime은 독립 G3~G8 token 주입, non-owner app-role preflight와 공개 health를 통과했다. Compose로 전환할 때만 `APP_DB_PASSWORD` 등 패키징 비밀과 prod-safe engine/voice flags를 별도 주입하고 compose profile preflight를 다시 통과한다. diff --git a/docs/dev_dashboard.html b/docs/dev_dashboard.html index f7053be..2908d8a 100644 --- a/docs/dev_dashboard.html +++ b/docs/dev_dashboard.html @@ -684,6 +684,7 @@

205차 진단·보강(2026-08-12): 진단과 로그인 폭 수정을 commit f97e7fad…·tree bdc83f24…의 새 detached-clean worktree에 고정해 periodic full runner를 한 번 실행했다. 전용 engine ready 뒤 disposable DB가 restart 127로 unhealthy가 돼 브라우저 전에 fail-closed했다. receipt periodic-learner-e2e-20260812-163742.json·SHA-256 ad403712…d840f의 cleanup 전 secret/PII-safe 로그가 99_app_role.sh#!/usr/bin/env bash\rNo such file or directory를 확정했다. Git blob은 LF지만 Windows core.autocrlf=true가 새 worktree를 CRLF로 만든 것이 원인이다. .gitattributes*.sh text eol=lf를 추가했다. public·NAS·active DB 접촉 0, container·volume·network·listener·temp 잔여 0이며, 같은 blocker가 두 번 반복돼 이번 heartbeat에서는 재실행하지 않는다. 다음 gate는 새 commit→새 detached checkout CR 0→preflight→single full run이다.

206차 검증(2026-08-12): LF 계약 commit f380cc46…·tree a6865ba9…를 새 detached-clean worktree에 checkout해 tracked shell CRLF 0, 99_app_role.sh CR 0, local desktop-linux/npipe·보호 포트 재사용 0 preflight를 확인했다. 단일 periodic full run은 500.0초에 GREEN이었다. receipt periodic-learner-e2e-20260812-164929.json·SHA-256 14124ff6…ab67에서 실제 동일 학습자 회기 생성·SSE·review ready·G4/G5 0→1→1, 별도 returned-practice desktop/mobile 4/4, route mock 0을 확인했다. public·NAS·active DB 접촉은 0이고 container·volume·network·2726-2729 listener·engine PID·temp 잔여도 0이다. current source의 주기 회기 gate는 GREEN으로 복귀했으며, 공개 톱바 44px와 NAS 로그인 폭 보정은 별도 승인 배포 전까지 source-only다.

207차 UX·실회기 검증(2026-08-12): actual 공개 desktop 상단바의 브랜드·공간 전환·테마·로그아웃이 28~34px인 것을 다시 확인해, 모바일에만 있던 44px 계약을 모든 viewport로 승격했다. source는 브랜드 최소높이, 공간 링크 최소높이, 테마·로그아웃 44×44px을 유지하며 1280/1024/390/320 역할 최악 조건 2/2, 자기주도·G1~G7 route-fixture 82/82, type/API contract·production build를 통과했다. clean b02bee26…·tree 8f677bba…의 single periodic full run도 487.3초에 GREEN이었다. receipt periodic-learner-e2e-20260812-171547.json·SHA-256 8c11a136…af8e3에서 same-learner SSE·review ready·G4/G5 0→1→1, returned desktop/mobile 4/4, route mock 0, public·NAS·active DB 접촉 0과 container·volume·network·3853-3856 listener·engine PID·temp 잔여 0을 확인했다. 이 상단바와 NAS 로그인 폭 보정은 별도 승인 배포 전까지 source-only이고, current NAS health timeout·9100 listener 0은 유지된다.

+

208차 공개 Web 후보 고정(2026-08-12): detached-clean 00f851a6…c229·tree 9f78cd16…9486에서 generated API type LF 계약, npm ci --ignore-scripts, API type contract, typecheck와 2회 byte-identical production build를 통과했다. 새 primary CSS index-Dzmt2kJS.css SHA da5e8535…fb9a, JS index-BUoTLplD.js SHA 08654d08…3c05를 고정했고, 상단 44px·로그인 무가로넘침·학생 자기주도 홈→회기→복기→재연습 focused E2E는 desktop/mobile 12/12다. actual 공개와 최근 Pages 5개 origin의 lazy asset 133개를 더해 최종 732파일로 만들고 현행 공개 CSS/JS SHA를 exact 보존했다. actual 공개는 health ok·db/engine true·OpenAPI 126·auth 401·local voice exact, console/boot/overflow/[NAME] literal 0이지만 구 Web 상단 6개 조작면은 44px 미만이다. NAS 로그인은 200·auth 401·OpenAPI 126이지만 health timeout·9100 listener 0·모바일 overflow 10px다. 공개/NAS/API/DB/task/마이크 mutation은 0이며, Pages 승격·NAS relay·G7 physical proof를 서로 다른 승인 게이트로 유지한다. 증거는 docs/ops/evidence/public-web-preflight-2026-08-12.json이다.

래스터만 사용이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.
기능 우선메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.
diff --git a/docs/ops/backlog-2026-06-26.md b/docs/ops/backlog-2026-06-26.md index 47cc4e6..89a9e54 100644 --- a/docs/ops/backlog-2026-06-26.md +++ b/docs/ops/backlog-2026-06-26.md @@ -116,6 +116,10 @@ ## B3. 소유자(윤찬) 결정 — 전건 확정(2026-06-30) +- [ ] **공개 Web 후보 Pages 승격 승인** — `00f851a6…c229`·tree `9f78cd16…9486`의 deterministic build와 + focused E2E 12/12, 현행/최근 Pages 자산 133개 보존은 완료됐다. 실제 공개와 NAS에는 아직 배포하지 않았다. + 승인 시 Pages Web만 승격하고 공개 API/DB·task·NAS runtime은 범위 밖으로 유지한다. + > 7건(평가설계 H1 κ/ICC·환각률, s2s 2차 PoC 채택, 페르소나 음성 모델·권리, fast-loop 외부 API 허용, > 재귀학습 fine-tuning 범위, 운영 보존기간·에스컬레이션, 추가 축어록 수급 20건/1개월)은 **전건 확정**됐다. > 결정 상세는 대시보드 "윤찬 결정 상세" 탭, ADR은 `docs/decisions/`(`voice-s2s-poc.md`, diff --git a/docs/ops/evidence/public-web-preflight-2026-08-12.json b/docs/ops/evidence/public-web-preflight-2026-08-12.json new file mode 100644 index 0000000..0d54923 --- /dev/null +++ b/docs/ops/evidence/public-web-preflight-2026-08-12.json @@ -0,0 +1,116 @@ +{ + "schema": "vignette.public-web-preflight.v1", + "captured_at": "2026-08-12T18:18:30+09:00", + "status": "preflight_passed_approval_required", + "deployment_executed": false, + "external_mutation": false, + "source": { + "branch": "detached HEAD", + "commit": "00f851a66fb680f650bf2077c72fcd563c27c229", + "tree": "9f78cd165b59e04986905e182b3e0cb89d9e9486", + "candidate_root": "D:\\workspace\\vignette-public-web-preflight-00f851a6", + "tracked_clean": true, + "api_generated_types_lf_pinned": true + }, + "candidate_gates": { + "npm_ci_ignore_scripts": "passed", + "api_type_contract": "passed", + "typecheck": "passed", + "production_build_runs": 2, + "production_build_deterministic": true, + "production_file_count_before_asset_preservation": 599, + "focused_playwright": { + "passed": 12, + "failed": 0, + "projects": [ + "chromium-desktop", + "chromium-mobile" + ], + "contracts": [ + "all-role topbar controls are at least 44px at 1280, 1024, 390, and 320 widths", + "login root has no horizontal overflow at narrow scrollbar viewports", + "secondary Google login action preserves its domain and redirect contract", + "learner self-directed home to session to review to repractice flow", + "transient boot diagnostic clears and actual empty boot remains fail-honest" + ], + "listener_15471_after": 0, + "temp_remaining": 0 + } + }, + "new_primary_assets": { + "css": { + "path": "assets/index-Dzmt2kJS.css", + "bytes": 29683, + "sha256": "da5e8535acd714fd85dfbd6d041f457a7a5d16eb15132b4889f2ff3f2867fb9a" + }, + "javascript": { + "path": "assets/index-BUoTLplD.js", + "bytes": 246182, + "sha256": "08654d08230358fdb607cc4d5116862b2e988787e7ea14fd5bcc73a87e1a3c05" + } + }, + "previous_asset_preservation": { + "origins_checked": 6, + "assets_added": 133, + "final_file_count": 732, + "download_temp_remaining": 0, + "current_public_assets": [ + { + "path": "assets/index-1zrRyPRd.css", + "sha256": "96954208bc09396ddcb30acc11f727658fa865957a9cf223e54e2fa06200ae61", + "preserved_exact": true + }, + { + "path": "assets/index-BrpoQ5nP.js", + "sha256": "b8e6b6679f6ad073f4a2ecfe81aa86769b09dcff7203ff393a8c3d9d854d623e", + "preserved_exact": true + } + ] + }, + "actual_runtime_read_only": { + "public": { + "health_status": "ok", + "db": true, + "engine": true, + "environment": "prod", + "auth_me_status": 401, + "openapi_paths": 126, + "voice": "local_whisper/small + melotts/melotts-korean", + "console_errors": 0, + "boot_diagnostic_overlays": 0, + "horizontal_overflow_px": 0, + "pii_placeholder_literals": 0, + "mobile_topbar_controls_under_44px": 6, + "candidate_not_deployed": true + }, + "nas_preview": { + "login_http_status": 200, + "auth_me_status": 401, + "openapi_paths": 126, + "health": "timeout", + "relay_9100_listener_count": 0, + "mobile_login_horizontal_overflow_px": 10, + "candidate_not_deployed": true + } + }, + "known_dependency_risk": { + "production_audit": { + "critical": 0, + "high": 0, + "moderate": 2 + }, + "package": "react-router-dom@6.30.4", + "advisory": "GHSA-jjmj-jmhj-qwj2", + "introduced_by_candidate": false, + "patched_v6_available": false, + "decision": "track a separate React Router 7 migration; do not apply an unreviewed major upgrade in this UI-only release" + }, + "approval_boundaries": { + "public_pages_deploy": "explicit owner approval required", + "nas_engine_relay": "explicit owner approval required", + "g7_physical_microphone": "device selection and explicit consent required", + "public_api_db_scheduled_tasks_touched": false, + "nas_containers_db_touched": false, + "physical_microphone_opened": false + } +}