docs(auth): 인증 종료 요구사항과 검증 결과를 기록한다

This commit is contained in:
Yu Sung
2026-10-14 00:33:59 +09:00
parent 228e7d0be5
commit d50a8a9b15
3 changed files with 302 additions and 4 deletions
@@ -4,9 +4,9 @@
- PRD: `docs/20261012_본인인증_후_콘텐츠_보기_설정/prd.md`
- API 기준: PRD §11, 별도 `api-contract.md` 없음
- 상태: **코드 구현·빌드 검증 완료 / 실제 인증 통합 QA 대기**
- 상태: **Phase 7·R1 구현·로컬 기능/시각 검증 완료 / 실제 인증 통합 QA는 기존 대기 유지**
- 현재 브랜치: `main`, worktree 사용 안 함
- 현재 Phase: Phase 3 실제 인증 통합 QA 대기
- 현재 Phase: Phase 7·R1 로컬 검증 완료. Phase 3 실제 인증 통합 QA는 별도 대기.
- 구현 허가: **2026-10-12 사용자 “승인” 확인. 현재 브랜치에서 승인된 구현·검증을 진행한다.**
## 목표
@@ -383,3 +383,144 @@
- 독립 기능/시각 검토 모두 **APPROVE(P6 한정)**. 리뷰 `reviews/phase6-fixed-backdrop-panel-motion.md`. 전체 앱 빌드에도 변경 파일 오류/경고가 없었다. 기존 unrelated 빌드 경고는 유지한다.
- QA 앱2개 및 runner2개 제거, 작업 소유 simulator 종료, recorder 종료를 확인했다. booted 기기 및 QA/build/recordVideo 프로세스 없음. 시스템 글자크기 large/ReduceMotion0 복원 증거를 보존했다.
- 한계: 실제 실행 OS는 iOS26이며 minimum16.6 compile만 확인했다. 실제 toast/7개 실계정 인증/실서버 통합은 이전 미검증 범위다. VM·API·개발 mock·caller는 이번 단계에서 수정하지 않았다. 커밋/푸시/worktree 생성 없음.
## Phase 7: 인증 중 설정 패널 종료와 용어 정리
**상태:** 2026-10-14 구현·로컬 검증 완료. 실제 VoiceOver 제스처·실서버 검증은 미실행으로 구분하며 이전 대기/실패 기록은 이력으로 보존한다.
**Phase 결과:** 최초 설정 또는 저장 실패 후 X에서 종료 여부를 선택하고, 종료 시 인증 대기 상태를 폐기하며 정상 저장 흐름은 유지한다.
**선행조건:** PRD Phase 7 요구사항과 이 계획에 대한 명시적 구현 승인. 현재는 문서 외 변경 금지.
**범위:** PRD `AUTH-012`~`AUTH-017`. 일반 설정·다른 인증 안내·API·mock·프로젝트 설정·공용 팝업 변경은 제외한다.
### Task 7.1: 안전한 종료와 V2 팝업 연결
**Goal `P7-T1`:** 일곱 진입점의 공용 패널에서 종료 확인을 제공하고, 종료 후 추가 제출이나 오래된 성공 action 실행을 막는다.
- 시작 조건: Phase 7 구현 승인. 완료 증거: 실제 VM 기반 RED/GREEN 검사와 공용 UI·caller 연결. 최종 native UI QA와 두 앱 빌드는 후속 `P7-QA`가 담당한다.
- Modify: `SodaLive/Sources/V2/Component/Modal/AuthContentSettingsSheet.swift` — X·고정 헤더·팝업 표시 상태와 full-screen host overlay, preview 연결.
- Modify: `SodaLive/Sources/MyPage/MyPageViewModel.swift` — 제출 중이 아니고 패널이 열려 있을 때 기존 `clearPendingAuthVerification()`을 사용하는 취소 메서드. 실패 toast도 해제해 뒤 화면에 남지 않게 한다.
- Modify: `SodaLive/Sources/I18n/I18n.swift` — 기존 인증 전용 ON/OFF 설명 수정, 종료 제목·본문·confirm·cancel 문자열 추가. shared 토글 제목·저장 CTA는 유지한다.
- Modify: `SodaLive/Sources/Main/Home/HomeView.swift`, `SodaLive/Sources/Home/HomeTabView.swift`, `SodaLive/Sources/Chat/ChatTabView.swift`, `SodaLive/Sources/Live/Now/All/LiveNowAllView.swift`, `SodaLive/Sources/V2/Main/MainView.swift`, `SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift` — 종료 callback에서 각 caller의 `pendingAction`만 해제한다. 다른 UI·문구·라우팅은 바꾸지 않는다.
- Read: `SodaLive/Sources/V2/Component/Modal/SodaV2ActionModal.swift`, `SodaLive/Sources/MyPage/MyPageView.swift`, 독립 `Settings/Content/ContentSettingsView.swift`. My Page는 대기 action이 없어 기존 modifier 호출을 유지한다.
- Create/Test: `work/tests/check-auth-content-settings-exit.sh`, `work/tests/AuthContentSettingsExitCheck.swift` — 실제 VM·모델과 격리 의존성으로 검사한다. production dependency injection 리팩터링이나 XCTest target 추가는 하지 않는다.
**Interfaces:**
- VM: `cancelAuthContentSettings() -> Void`. 기존 main-thread 관례와 제출 중/패널 표시 guard를 지키며 영수증·대기 요청·성공 closure를 정리한다. 서버 요청·UserDefaults 변경·재시작은 하지 않는다.
- Panel: 필수 `onClose: () -> Void` 추가. X는 팝업만 연다.
- Modifier: `authContentSettings(viewModel:onCancel:)`에 기본값 `{}`인 취소 closure를 추가한다. 여섯 callback caller는 `{ pendingAction = nil }`을 전달한다.
- Confirm: guard 재확인 → 팝업 닫기 → VM 취소 → caller 취소 1회. Continue/dim은 팝업 상태만 해제한다. 패널 닫힘/host 종료 시 팝업 상태를 초기화한다.
- 소비 컴포넌트: 변경 없는 `SodaV2ActionModal`과 PRD 확정 문구. 전체 host 위에 올리고 뒤 패널 입력·접근성을 차단한다.
- 보존 계약: 0.25초 패널 퇴장, Reduce Motion, host `onDismiss`의 기존 제출 호출. 종료 시 기존 guard로 제출 0회, 저장 시 닫힘 완료 후 제출 1회.
- [x] **RED:** 실제 VM 검사로 최초 종료·POST 실패 후 종료·fresh receipt 재진입·이전 성공 closure 미실행·제출 중 취소 무시를 고정한다. 종료의 추가 POST/GET·저장·성공·재시작은 모두 0회로 assert한다.
- [x] **RED 확인:** `bash work/tests/check-auth-content-settings-exit.sh`에서 취소 메서드 부재 또는 요구 동작 실패를 기록한다. 이미 통과하는 serializer를 일부러 실패시키지 않는다.
- [x] **GREEN:** 위 최소 VM·패널·번역·여섯 caller 연결을 구현한다. `xmark` 16pt medium, 44×44pt hit 영역, 중앙 제목과 동일한 좌우 영역, VoiceOver 레이블을 적용한다. 헤더·CTA는 고정하고 본문만 overflow scroll한다.
- [x] **GREEN 확인:** 같은 검사 exit 0. 실패 transport/HTTP/envelope/decode별 취소, 중복 종료, 새 ON/ALL 시작, 제출 시작 후 취소 무시와 정상 저장 1회 계약을 확인한다.
- [x] **REFACTOR:** 이번 변경의 중복만 정리하고 focused 검사와 아래 직접 영향 회귀를 재실행한다. 무관한 UI·shared modal·API 수정은 하지 않는다.
**TDD 예외:** SwiftUI overlay·VoiceOver·모션은 현행 앱 테스트 번들에서 자동 재현할 수 없다. 현재 실제 패널/modifier/V2 팝업 소스를 사용하는 임시 native QA host로 X·dialog·host-dismiss를 실행하고 screenshot 및 요청/callback 카운터를 기록한다. 이전 임시 QA 경로가 남아 있다고 가정하지 않는다.
### Task 7.2: 기능·접근성·빌드 Gate
**Goal `P7-QA`:** 종료와 기존 저장의 차이를 실제 실행 증거로 검증한다.
- 시작 조건: `P7-T1` 구현·focused 검사 완료. 완료 증거: 아래 자동·native 검증과 기록. 미실행 검증은 완료로 표시하지 않는다.
- Confirm/Test: Task 7.1 대상 파일, 기존 `work/scripts/check-auth-content-settings.swift`, `work/tests/check-auth-verification-mock.sh`, 현재 simulator destination과 두 앱 스킴.
- TDD 예외: 검증 전용 Task다. 실제 실행 결과와 캡처·카운터를 대체 증거로 사용한다.
- [x] 최초 및 POST 실패 후 X → 계속하기/바깥 탭은 draft·대기 action 보존, 종료하기는 패널 닫힘·대기 상태 폐기·추가 전송 0회. 본문의 명시적 줄바꿈을 캡처한다.
- [ ] 일곱 caller에서 종료 후 action A가 실행되지 않고 새 인증 action B만 정상 성공 후 1회 실행된다. 실패 toast 잔류, 빠른 연속 X/종료, dialog 뒤 저장 터치, 정상 저장/실패 재표시를 검사한다.
- [ ] 작은 iPhone·가로·최대 글자·VoiceOver·Reduce Motion에서 제목/X/CTA 접근과 dialog 입력 차단을 확인한다. 고정 backdrop과 패널 단독 퇴장을 대조한다.
- [x] focused·기존 auth mock·serializer 검사와 두 Debug 앱 빌드를 exit 0으로 확인한다. 변경 Swift diagnostics 도구가 없으면 실제 compiler/build 결과로 대체하고 한계를 기록한다.
- [x] 이 문서와 PRD에 결과를 누적한다. 구현 후 필요한 리뷰는 같은 디렉터리의 `reviews/phase7-auth-settings-exit.md`에 기존 리뷰 샘플을 따라 남긴다. 기존 실서버 `P3-QA`는 별도 [blocked] 유지.
**실행 명령 (승인 후):**
```bash
bash work/tests/check-auth-content-settings-exit.sh
bash work/tests/check-auth-verification-mock.sh
swiftc SodaLive/Sources/MyPage/Auth/AuthVerifyRequest.swift SodaLive/Sources/Settings/Content/ContentType.swift work/scripts/check-auth-content-settings.swift -o "$QA_DIR/check-auth-content-settings"
"$QA_DIR/check-auth-content-settings"
xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug -destination 'generic/platform=iOS Simulator' -derivedDataPath "$QA_DIR/SodaLive-build" CODE_SIGNING_ALLOWED=NO -quiet build
xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -destination 'generic/platform=iOS Simulator' -derivedDataPath "$QA_DIR/SodaLive-dev-build" CODE_SIGNING_ALLOWED=NO -quiet build
```
- `$QA_DIR`은 승인 후 존재를 확인한 임시 작업 폴더다. native QA destination은 당시 설치된 simulator에서 확인하고 과거 UUID·아키텍처를 고정하지 않는다. 두 앱 빌드는 순차 실행한다.
- 전체 unrelated 회귀는 이번 범위에서 제외한다. 실제 VM·공용 패널·여섯 caller·auth mock·serializer의 직접 영향 회귀를 검사하며 추가 전체 회귀가 필요한 근거가 생기면 기록한다.
- 서버에 이미 도달했을 수 있는 실패 POST rollback은 검사나 보장 범위가 아니다. 승인된 실서버 QA 환경 없이 실제 인증·회원 상태를 변경하지 않는다.
### 승인과 완료 조건
- [x] Phase 7 PRD/계획의 명시적 구현 승인을 받는다. 2026-10-13 사용자 “구현 승인”.
- [x] `P7-T1`과 `P7-QA`의 로컬 실행 증거를 확보한다. 미실행 VoiceOver 제스처·7개 실서버 진입 및 실제 toast 검증은 완료 주장에 포함하지 않는다.
순서: **계획 승인 대기 → `P7-T1` → `P7-QA`**. 커밋·푸시는 별도 요청 없이는 하지 않는다.
### `P7-PLAN` 문서 작성 — 2026-10-13
- 완료: 사용자 확정 범위·V2 재사용·두 문장 사이 줄바꿈을 PRD와 이 계획에 반영했다. 새 작업 문서나 앱 코드는 만들지 않았다.
- 근거: 샘플/정책, 실제 패널·VM·V2 modal·caller·I18n·일반 설정·기존 auth 검사 스크립트 대조와 읽기 전용 계획 검토. shared 제목은 그대로 사용하며 인증 전용 설명만 수정하도록 범위를 한정했다.
- 검증: `git diff --check` exit 0, `git diff --stat`에서 기존 문서 두 개만 변경됨을 확인했다. 추가 섹션을 다시 읽어 확정 문구·줄바꿈·승인 gate·일반 설정 제외와 대조했다. 기능 테스트·빌드·native 실행·서버 요청은 계획 단계라 실행하지 않았다.
- 남은 항목: **Phase 7 구현 승인**. 이전 Phase의 승인·완료 기록은 보존하며 이번 구현 승인으로 재사용하지 않는다.
### `P7-T1` 구현 시작 — 2026-10-13
- 사용자 “구현 승인” 확인. 승인된 인터페이스로 VM/실제 소스 회귀 검사와 UI/caller 작업을 분리하며 수정 파일이 겹치지 않게 한다.
- 현재 작업 디렉터리를 유지한다. 기존 두 계획 문서 변경은 보존한다. 신규 worktree·외부 의존성·앱 테스트 타깃은 추가하지 않는다.
- 시나리오: 최초/POST 실패 후 종료, 계속하기·dim 값 보존, 새 인증 재진입, 기존 저장·모션 유지, native 접근성·줄바꿈, 두 앱 빌드 및 기존 회귀 검사.
### `P7-T1` 구현 및 자동 검증 — 2026-10-13
- 구현 완료: VM에 guarded cancel 13줄 추가, 공용 패널의 X·고정 헤더·V2 modal overlay·취소 callback, 여섯 caller의 `pendingAction` 정리와 인증 전용 다국어 문구를 반영했다. 공용 modal·일반 설정·API·프로젝트 파일은 변경하지 않았다.
- RED: 구현 담당자가 실제 VM 컴파일에서 `has no member 'cancelAuthContentSettings'` exit 1을 확인했다. GREEN: coordinator가 새 검사 스크립트를 직접 실행해 exit 0을 확인했다. 실제 VM·DTO·UserDefaults extension/native Combine이며 저장소·AppState·메모리 저장소는 doubles다.
- 실제 검사: 최초 MyPage/callback 종료, transport/HTTP/envelope/decode/missing-data/invalid-DTO 6종 실패 뒤 종료·새 인증, 이전 closure 해제·미실행, 새로운 callback 동기화 후 1회, 제출 중 취소 무시, MyPage 저장·재시작, main dispatch 및 무관한 notice subscription 보존 모두 PASS.
- 기존 전체 `for test in work/tests/check-*.sh; do bash "$test" || exit $?; done`를 변경 전·후 직접 실행해 exit 0을 확인했다. 사용자 ulw의 전체 suite 요구에 따라 계획의 focused 기본 범위보다 검증만 확대했으며 생산 수정은 늘리지 않았다. 기존 실제 serializer 4조합도 exit 0.
- 두 앱 Debug simulator 빌드 exit 0. 명령은 기존 workspace와 각 scheme, `-destination 'generic/platform=iOS Simulator'`, cached derivedData(`SodaLive-dev-commit-build`/`SodaLive-commit-build`), `-disableAutomaticPackageResolution CODE_SIGNING_ALLOWED=NO ONLY_ACTIVE_ARCH=YES ARCHS=x86_64 -quiet build`다. 현재 호스트는 x86_64/Xcode26.0이다.
- 로그: `/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/auth-exit-dev-build-final.log`, `auth-exit-standard-build.log`. 최초 dev 빌드는 120초 tool timeout으로 중단됐으며 잔류 프로세스 없음 확인 후 600초 한도로 재실행해 통과했다. 기존 중복 Compile Sources·Pods 의존성·LiveRoom 미사용 변수·Crashlytics dSYM 경고는 범위 밖이라 수정하지 않았다.
- `lsp_diagnostics` 도구 미제공. 실제 compiler/typecheck/link 성공과 Swift parse로 대체하며 LSP 통과로 표현하지 않는다. `git diff --check` exit 0, coordinator의 수정 파일 읽기·연결 대조 완료.
- 남은 검증: 현재 production UI를 직접 참조하는 `auth-exit-qa` native 실행, 독립 기능/시각 검토, QA 자원 정리. 실제 계정·실서버는 변경하지 않았다.
### `P7-QA` native 실행 및 최종 gate 보류 — 2026-10-13
- 핵심 기능 PASS: native dark 10개·light 4개·375pt SE3 narrow 3개·가로 최대 글자 1개·Reduce Motion 2개 및 추가 반복 종료 1개가 기능 assertion을 통과했다. X44pt, continue/dim draft 보존, 최초/실패 후 종료, fresh ON/ALL, normal save host-dismiss 순서, 뒤 패널 hit 차단을 실제 SwiftUI 컴포넌트에서 실행했다.
- 접근성은 공개 UIKit API로 실제 host 노드를 순회해 팝업 title/body/두 버튼만 노출됨을 확인했다. 실제 VoiceOver swipe/focus 세션은 실행하지 않았으며 노드 검사를 그 증거로 대체하지 않는다.
- coordinator 재실행: `AuthExitQA`의 `-only-testing:AuthExitQAUI/AuthExitUITests/testKoreanFemaleContinueDimAndExit`를 직접 실행해 1 test/0 failures/exit 0. `ParentCore01.xcresult`, `parent-core-01.log`에 `cancelled=1;onCancel=1;dismissed=1;post=0;success=0;restart=0;pending=false;receipt=false;save=false`를 확인했다. 팝업과 패널 모두 사라지고 원래 QA host가 남았다.
- 증거 부모: `/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/auth-exit-qa`. `EVIDENCE.md`에 명령/한계, `capture-inventory.json`에 PNG74개와 tree/hash, 각 run에 xcresult·source-before/after를 보존했다. 같은 production13개 hash 유지. regular ko ON/OFF baseline diff는 0.54%/0.64%, similarity99이나 시각 성공 판정은 아니다.
- **시각 FAIL `REV-P7-001`:** 가로 + 최대 Dynamic Type에서 변경 없는 shared modal이 경고 본문과 버튼명을 생략한다. `phase7-landscape-02/modal-upright.png`를 coordinator도 직접 열어 확인했다. 기능 test는 전체 accessibility label을 읽어 통과하므로 시각 gate와 분리한다. 정상 크기 한국어 팝업은 두 문장 줄바꿈이 온전히 표시된다.
- Oracle 코드·VM 검토는 **APPROVE(해당 범위 한정)**, 코드 수정 요구 없음. native 시각 FAIL과 실제 VoiceOver/일반 모션 정량 검증 미완료 때문에 전체 Phase7 gate는 완료하지 않는다. 일본어 modal의 단어 중간 줄바꿈은 추가 시각 검토 사항이다.
- QA harness 보정: XCTest `.exists`는 VoiceOver 노드 의미와 달라 공개 UIKit 노드 검사로 교체했고 hit/disabled 검사를 유지했다. 44pt의 1e-6 부동소수점 오차만 허용했다. Reduce Motion 설정 복원 오류는 YES/NO 변환 후 원값 검증으로 정리했으며 해당 영상은 일반 모션 증거로 사용하지 않는다. production 수정/검사 약화 없음.
- 정리: worker의 `teardown-receipt.json`에 앱/runner6건 삭제·설정/portrait 복원·두 소유 기기 Shutdown·recorder 종료 증거가 있다. coordinator 핵심 재실행으로 재설치한 앱/runner2개도 uninstall exit0 후 소유17Pro shutdown exit0으로 정리했다. 증거 파일은 보존한다.
- 최종 상태: **[blocked] 공용 팝업의 큰 글자 대응 수정 범위 승인 필요.** 현재 구현은 보존하며 커밋/푸시하지 않았다.
### Task P7-R1: 종료 팝업의 큰 글자 경고·동작명 보존 (완료)
**Goal `P7-R1`:** 가로·최대 글자에서도 경고 두 문장과 ‘계속하기’·‘종료하기’를 생략 없이 읽고 조작할 수 있다.
- Review: `reviews/phase7-auth-settings-exit.md`, `REV-P7-001`.
- 시작 조건: 사용자 범위 확대 승인. 기존 공용 modal 무변경 제약 때문에 승인 전 production 수정 금지.
- Files: 승인 시 `SodaLive/Sources/V2/Component/Modal/SodaV2ActionModal.swift`의 필요한 최소 레이아웃과 실제 사용 caller들 확인. 별도 새 팝업이나 글자 크기 강제 축소로 우회하지 않는다.
- [x] RED: 현재 actual modal의 가로 + 최대 글자에서 경고·버튼 ellipsis를 native 캡처로 재현했다.
- [x] 수정 범위 승인 후 PRD 제약과 Task를 확정한다. 사용자 “최소한 수정”: 공용 modal 한 파일의 크기·줄바꿈·필요한 overflow만 보정하고 기존 기본 디자인·동작·문구를 유지한다.
- [x] 최소 레이아웃 수정으로 두 경고 문장·버튼명 전체 표시 및 조작을 검증한다.
- [x] 해당 UI QA와 공용 컴포넌트 영향 회귀(실제 copy의 단일/두 버튼 fixture·caller 정적 연결), 두 앱 빌드·집중 독립 시각 gate를 통과시킨다. 모든 caller 실계정 화면을 실행한 것은 아니다.
- [x] 실제 결과·QA 자원 정리를 본 문서와 리뷰에 누적한다.
### `P7-R1` 승인 후 재개
- 기존 native RED 캡처를 재사용하며 새 QA 프로젝트를 만들지 않는다. 가로 최대 글자·세로 최대 글자·기본 크기·기존 공용 팝업 한/두 버튼의 영향을 중심으로 검증한다.
- 회귀 원인은 shared modal의 고정 폭/제목 높이와 확대 글자의 공간 부족이다. 글자 강제 축소, 신규 팝업·설정·API·추상화 추가는 하지 않는다.
- 검증: 기존 `auth-exit-qa`의 해당 native 시나리오와 실제 screenshot, 기존 종료 회귀 script/전체 shell suite, 두 앱 cached build. 실제 VoiceOver 조작·실서버 검증과 접근성 노드 검사 범위는 구분한다.
### `P7-R1` 수정 및 최종 로컬 검증 — 2026-10-14
- 공용 `SodaV2ActionModal.swift`만 +46/-22줄로 보정했다. 기본340pt 자연 높이·간격·색상·button2→button1 순서/단일 primary/callback 보존. 접근성 크기에서 가용 폭을 사용하고 제목/본문/버튼은 세로 압축하지 않으며 넘치는 글만 스크롤한다. 글자 축소·새 API·의존성 없음.
- RED는 기존 실제 가로 최대 글자 ellipsis 캡처다. GREEN은 `auth-exit-qa/R1-EVIDENCE.md`: 가로최대1, 375pt세로최대2, 기본ko/quick/ja3, 단일/두 버튼fixture1 모두 PASS. fixture의 상태바 dim 탭 좌표 실패는 scratch 좌표만 보정해 callback primary1/secondary1/dim1로 통과했다. production 변경은 한 번이었다.
- coordinator가 `PHASE7_READY=1 bash run_phase7.sh r1-landscape r1-parent-landscape-01`을 직접 실행해 1 test/0failures/46.864초/exit0을 확인했다. 실제 최대 글자 가로에서 전체 경고가 스크롤로 보이고, 고정된 두 버튼명·종료 동작이 통과했다. 종료 후 cancel1/onCancel1/hostDismiss1/post0/success0/restart0.
- 현재 소스 read와 최대 글자 가로/세로 PNG 직접 확인 완료. 기본 한국어 popup의 이전/수정 후 `visual-qa.mjs image-diff`는 1206×2622 일치, 2336 pixels/0.0007 diffRatio, similarity100, alpha정상이며 hotspot은 상단 시계 영역이다. 기본 popup 배치가 보존됐다.
- 최신 전체 `work/tests/check-*.sh` exit0. 최신 두 Debug simulator workspace build exit0: tmp/opencode의 `auth-exit-r1-dev-build.log`, `auth-exit-r1-standard-build.log`. 이전과 같은 cached derivedData·x86_64·signingNO 옵션. Swift parse/diff check exit0. LSP 도구는 여전히 제공되지 않아 실제 compiler로 대체했다.
- 독립 최종 기능 Oracle **APPROVE**, 독립 시각 reviewer **PASS**. 시각 reviewer는 최신 핵심 캡처11장과 수정 전2장을 직접 비교했고, 중복 프레임27장 전체 또는 모든 실계정 화면을 검사했다는 주장은 하지 않았다. 확정 차단 발견사항 없음. 기존 일본어 `必/要` 줄바꿈은 의미를 숨기지 않는 경미 사항으로 미수정.
- worker `r1-teardown-receipt.json`에 두 기기 설정/portrait복구와 앱/runner4건 삭제·shutdown 증거가 있다. coordinator 재실행 후 light/large/ReduceMotion0을 직접 확인하고 재설치 앱/runner2개 uninstall,17Pro shutdown exit0. 기록과 PNG는 보존한다.
- 남은 한계: live VoiceOver 제스처, 실제 toast lifecycle, 7개 실계정/실서버 통합과 모든 공용 popup 사용 화면 runtime은 미실행이다. 관련 원래 체크박스는 완료로 위장하지 않는다. 완료 범위는 요청 기능 구현·현재 소스의 로컬 기능/시각/빌드 gate다.