<!-- task=m-usb-install/02+01_adb_diagnostics plan=1 tag=REVIEW_API -->

# Plan - REVIEW_API

## 이 파일을 읽는 구현 에이전트에게

이 plan은 이전 리뷰 `code_review_local_G06_0.log`의 FAIL Required 항목만 좁게 해결한다. 구현이 끝나면 반드시 `CODE_REVIEW-local-G07.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 검증을 실행하고, active 파일은 그대로 둔 채 리뷰 준비를 보고한다. 최종 판정, log rename, `complete.log` 작성, task archive 이동은 code-review 전용이다. 사용자만 결정할 수 있는 외부 환경, secret, 범위 충돌로 막히면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 증거와 재개 조건을 남기고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다.

## 배경

ADB diagnostics model/service와 settings UI는 추가됐지만 실제 `AppSokApp` 진입 경로에서 `adbDiagnosticsLoader`가 전달되지 않아 사용자가 실행하는 앱에서는 진단 섹션이 표시되지 않는다. 또한 프로젝트 local 테스트 규칙상 완료 evidence는 remote Mac runner 기준이어야 하는데, 리뷰 중 remote `flutter test`가 shader asset cache 오류로 실패했다.

## 사용자 리뷰 요청 흐름

구현 중 차단 사유는 active `CODE_REVIEW-local-G07.md`의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 사용자 프롬프트는 금지이며, code-review가 요청 타당성과 `USER_REVIEW.md` 작성 여부를 판단한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/usable-mvp/milestones/usb-install.md`
- Task ids:
  - `adb-diagnostics`: ADB 실행 경로, bundled version, runtime hash, server port, fallback 여부를 진단 정보로 표시한다.
- Completion mode: check-on-pass

## 분석 결과

### 이전 리뷰

- Archived plan: `agent-task/m-usb-install/02+01_adb_diagnostics/plan_local_G06_0.log`
- Archived review: `agent-task/m-usb-install/02+01_adb_diagnostics/code_review_local_G06_0.log`
- Verdict: FAIL
- Required issues:
  - 실제 앱 경로 `AppSokApp`이 diagnostics loader를 연결하지 않아 settings diagnostics가 사용자에게 노출되지 않는다.
  - remote Mac runner 기준 `flutter test`가 `shaders/ink_sparkle.frag` runtime stages format 오류로 실패해 완료 evidence가 부족하다.

### 읽어야 할 파일

- `agent-ops/rules/project/domain/app-shell/rules.md`
- `agent-ops/rules/project/domain/artifact-flow/rules.md`
- `agent-ops/rules/project/domain/device-console/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/app-shell-smoke.md`
- `agent-test/local/artifact-flow-smoke.md`
- `agent-test/local/device-console-smoke.md`
- `lib/src/app.dart`
- `lib/src/features/app_shell.dart`
- `lib/src/features/settings/settings_page.dart`
- `lib/src/services/adb_service.dart`
- `test/widget_test.dart`
- `test/adb_service_test.dart`
- `pubspec.yaml`
- `pubspec.lock`

### 범위 결정 근거

- Include: production diagnostics loader wiring, test override, widget assertions for actual diagnostics values, remote verification evidence refresh.
- Exclude: new settings persistence, custom adb picker implementation, top status pill redesign, live device list, logcat console, macOS bundle copy changes.
- `pubspec.lock`는 `crypto` direct dependency classification 외의 unrelated drift가 없어야 한다.

### 빌드 등급

- `local-G07`: 이전 `local-G06`에서 명확한 production wiring 누락과 verification evidence 실패가 발견됐다. 수정 범위는 좁고 deterministic하므로 local lane을 유지하되 한 단계 올린다.

## 구현 체크리스트

- [ ] `AppSokApp` 실제 진입 경로에서 ADB diagnostics loader가 기본 연결되도록 하고 테스트 override를 유지한다.
- [ ] 설정 화면 진단 테스트가 `AppSokApp` 경로와 실제 source/path/version/hash/server port/fallback 표시값을 검증하도록 갱신한다.
- [ ] remote Mac runner에서 clean/pub get 후 `flutter analyze`와 `flutter test`를 재실행하고 실제 stdout/stderr를 기록한다.
- [ ] `flutter analyze`, `flutter test`, `flutter test test/adb_service_test.dart`, `flutter test test/widget_test.dart`를 현재 checkout에서도 재실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

`01_adb_bundle` predecessor는 `agent-task/archive/2026/06/m-usb-install/01_adb_bundle/complete.log`에서 PASS 완료가 확인된 상태다. 이 후속 plan은 predecessor를 다시 구현하지 않는다.

### [REVIEW_API-1] Wire Diagnostics Into Production App

#### 문제

- `lib/src/app.dart`는 `AppSokShell`을 생성하지만 `adbDiagnosticsLoader`를 전달하지 않는다.
- `lib/src/features/settings/settings_page.dart`는 loader가 null이면 diagnostics 섹션을 숨긴다.
- 현재 widget test는 직접 `AppSokShell(adbDiagnosticsLoader: ...)`를 생성하므로 실제 `AppSokApp` 경로 누락을 잡지 못한다.

#### 해결 방법

- `AppSokApp`에 테스트용 `adbDiagnosticsLoader` override를 추가한다.
- production 기본값은 `AdbService().collectDiagnostics`로 연결한다. 같은 `AdbService` 인스턴스를 재사용하면 충분하다.
- typedef가 feature 파일에만 있어 app layer에서 쓰기 어색하면 `AdbDiagnosticsLoader` typedef를 `lib/src/services/adb_service.dart`로 이동하고 기존 imports를 정리한다.
- `AppSokShell`의 optional loader injection은 테스트와 preview 유연성을 위해 유지한다.
- `test/widget_test.dart`에 `AppSokApp(adbDiagnosticsLoader: fake)`로 설정 화면에 진입해 `ADB 진단`, source, path, version first line, 12-char SHA-256 prefix, server port, fallback label을 실제 텍스트로 검증하는 테스트를 추가하거나 기존 diagnostics test를 이 경로로 바꾼다.
- `SettingsPage without diagnostics loader shows no diagnostics section` 테스트는 raw `AppSokShell`의 optional-injection 동작으로 남겨도 되지만, production 동작의 근거로 쓰지 않는다.

#### 수정 파일 및 체크리스트

- [ ] `lib/src/app.dart`: default diagnostics loader wiring과 test override 추가.
- [ ] `lib/src/features/app_shell.dart`: loader 전달이 production default와 충돌하지 않는지 확인.
- [ ] `lib/src/features/settings/settings_page.dart`: typedef 위치/import 정리 필요 시 반영.
- [ ] `lib/src/services/adb_service.dart`: typedef 이동이 필요하면 여기에 둔다.
- [ ] `test/widget_test.dart`: production app path diagnostics 표시값 검증 추가.

#### 테스트 작성

- `AppSokApp` 경로 테스트는 fake diagnostics loader를 사용해 실제 `adb` 실행 없이 안정적으로 검증한다.
- 최소 assertion:
  - `find.text('ADB 진단')`
  - `find.text('bundled')` 또는 fallback 케이스에서는 `find.text('system (fallback)')`
  - full path text
  - version first line
  - 12-char SHA-256 prefix
  - server port text

#### 중간 검증

```bash
flutter test test/widget_test.dart
```

Expected: widget tests pass without overflow exceptions.

### [REVIEW_API-2] Refresh Remote Verification Evidence

#### 문제

- Local preflight passed, but project local rules require remote Mac runner evidence for completion.
- Review rerun result:
  - `ssh toki@toki-labs.com 'zsh -lc '\''cd "$HOME/docker/services/code-server/data/volume/workspace/appsok" && flutter analyze'\'''` passed.
  - `ssh toki@toki-labs.com 'zsh -lc '\''cd "$HOME/docker/services/code-server/data/volume/workspace/appsok" && flutter test'\'''` failed in `SettingsPage renders ADB diagnostics from fake loader` with `Unsupported runtime stages format version. Expected 2, got 1.`

#### 해결 방법

- After source/test fixes, rerun remote verification from the remote checkout.
- Start with `flutter clean` and `flutter pub get` on the remote runner to clear stale shader/build artifacts.
- Then run remote `flutter analyze` and `flutter test`.
- Record exact stdout/stderr in `CODE_REVIEW-local-G07.md`. Do not summarize as "passed" without command output.
- If the same shader asset error persists after clean/pub get, capture the exact command/output and leave the implementation-owned `사용자 리뷰 요청` only if the blocker is genuinely remote environment-owned and not fixable by repository changes or deterministic reruns.

#### 수정 파일 및 체크리스트

- [ ] `CODE_REVIEW-local-G07.md`: remote command outputs recorded.
- [ ] Source/test files: only if remote failure reveals a repo-owned issue.

#### 중간 검증

```bash
ssh -o BatchMode=yes -o ConnectTimeout=8 toki@toki-labs.com 'zsh -lc '\''cd "$HOME/docker/services/code-server/data/volume/workspace/appsok" && flutter clean && flutter pub get && flutter analyze && flutter test'\'''
```

Expected: remote `flutter analyze` and `flutter test` pass.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `lib/src/app.dart` | REVIEW_API-1 |
| `lib/src/features/app_shell.dart` | REVIEW_API-1 |
| `lib/src/features/settings/settings_page.dart` | REVIEW_API-1 |
| `lib/src/services/adb_service.dart` | REVIEW_API-1, only if moving typedef |
| `test/widget_test.dart` | REVIEW_API-1 |
| `CODE_REVIEW-local-G07.md` | REVIEW_API-2 |
| `pubspec.lock` | keep only intentional dependency resolution |

## 최종 검증

```bash
flutter analyze
flutter test
flutter test test/adb_service_test.dart
flutter test test/widget_test.dart
ssh -o BatchMode=yes -o ConnectTimeout=8 toki@toki-labs.com 'zsh -lc '\''cd "$HOME/docker/services/code-server/data/volume/workspace/appsok" && flutter clean && flutter pub get && flutter analyze && flutter test'\'''
```

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-local-G07.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
