공개 Web 후보 사전검증 증거 고정

This commit is contained in:
Yun Chan 2026-08-12 18:20:53 +09:00
parent 00f851a66f
commit 80bcacc723
5 changed files with 135 additions and 0 deletions

View file

@ -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와

View file

@ -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를 다시 통과한다.

View file

@ -684,6 +684,7 @@
<p class="dg-note">205차 진단·보강(2026-08-12): 진단과 로그인 폭 수정을 commit <code>f97e7fad…</code>·tree <code>bdc83f24…</code>의 새 detached-clean worktree에 고정해 periodic full runner를 한 번 실행했다. 전용 engine ready 뒤 disposable DB가 restart 127로 unhealthy가 돼 브라우저 전에 fail-closed했다. receipt <code>periodic-learner-e2e-20260812-163742.json</code>·SHA-256 <code>ad403712…d840f</code>의 cleanup 전 secret/PII-safe 로그가 <code>99_app_role.sh</code><code>#!/usr/bin/env bash\r</code><code>No such file or directory</code>를 확정했다. Git blob은 LF지만 Windows <code>core.autocrlf=true</code>가 새 worktree를 CRLF로 만든 것이 원인이다. <code>.gitattributes</code><code>*.sh text eol=lf</code>를 추가했다. public·NAS·active DB 접촉 0, container·volume·network·listener·temp 잔여 0이며, 같은 blocker가 두 번 반복돼 이번 heartbeat에서는 재실행하지 않는다. 다음 gate는 새 commit→새 detached checkout CR 0→preflight→single full run이다.</p>
<p class="dg-note">206차 검증(2026-08-12): LF 계약 commit <code>f380cc46…</code>·tree <code>a6865ba9…</code>를 새 detached-clean worktree에 checkout해 tracked shell CRLF 0, <code>99_app_role.sh</code> CR 0, local desktop-linux/npipe·보호 포트 재사용 0 preflight를 확인했다. 단일 periodic full run은 500.0초에 <b>GREEN</b>이었다. receipt <code>periodic-learner-e2e-20260812-164929.json</code>·SHA-256 <code>14124ff6…ab67</code>에서 실제 동일 학습자 회기 생성·SSE·review ready·G4/G5 <code>0→1→1</code>, 별도 returned-practice desktop/mobile <b>4/4</b>, 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다.</p>
<p class="dg-note">207차 UX·실회기 검증(2026-08-12): actual 공개 desktop 상단바의 브랜드·공간 전환·테마·로그아웃이 28~34px인 것을 다시 확인해, 모바일에만 있던 44px 계약을 모든 viewport로 승격했다. source는 브랜드 최소높이, 공간 링크 최소높이, 테마·로그아웃 44×44px을 유지하며 1280/1024/390/320 역할 최악 조건 <b>2/2</b>, 자기주도·G1~G7 route-fixture <b>82/82</b>, type/API contract·production build를 통과했다. clean <code>b02bee26…</code>·tree <code>8f677bba…</code>의 single periodic full run도 487.3초에 <b>GREEN</b>이었다. receipt <code>periodic-learner-e2e-20260812-171547.json</code>·SHA-256 <code>8c11a136…af8e3</code>에서 same-learner SSE·review ready·G4/G5 <code>0→1→1</code>, returned desktop/mobile <b>4/4</b>, 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은 유지된다.</p>
<p class="dg-note">208차 공개 Web 후보 고정(2026-08-12): detached-clean <code>00f851a6…c229</code>·tree <code>9f78cd16…9486</code>에서 generated API type LF 계약, <code>npm ci --ignore-scripts</code>, API type contract, typecheck와 2회 byte-identical production build를 통과했다. 새 primary CSS <code>index-Dzmt2kJS.css</code> SHA <code>da5e8535…fb9a</code>, JS <code>index-BUoTLplD.js</code> SHA <code>08654d08…3c05</code>를 고정했고, 상단 44px·로그인 무가로넘침·학생 자기주도 홈→회기→복기→재연습 focused E2E는 desktop/mobile <b>12/12</b>다. 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를 서로 다른 승인 게이트로 유지한다. 증거는 <code>docs/ops/evidence/public-web-preflight-2026-08-12.json</code>이다.</p>
<div class="dg-principles" aria-label="디자인 생성 가드레일">
<div><b>래스터만 사용</b><span>이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.</span></div>
<div><b>기능 우선</b><span>메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.</span></div>

View file

@ -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`,

View file

@ -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
}
}