<!-- task=m-logcat-console/02+01_console_stream plan=1 tag=REVIEW_LOGCAT_STREAM -->

# REVIEW_LOGCAT_STREAM 후속 계획

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

`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채우는 것은 필수입니다. 구현 후 검증을 실행하고 실제 내용과 출력을 기록한 뒤 active 파일을 그대로 두고 리뷰 준비를 보고하세요. 최종 판정, log rename, `complete.log`, archive 이동은 code-review-skill 전용입니다. 구현이 사용자 결정, 사용자 소유 외부 환경, 범위 충돌로 막히면 review stub의 `사용자 리뷰 요청` 섹션에 근거를 기록하고 중단하세요. 직접 질문, 채팅 선택지, `request_user_input`, `USER_REVIEW.md` 작성, archive, `complete.log` 작성은 금지입니다. 후속 에이전트가 재실행이나 산출물 수집으로 닫을 수 있는 증거 공백은 사용자 리뷰 요청이 아닙니다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/usable-mvp/milestones/logcat-console.md`
- Task ids:
  - `stream`: 선택 device의 `adb logcat` stream을 시작하고 화면에 append한다.
  - `lifecycle`: 화면 이탈 또는 device 변경 시 logcat process를 정리한다.
- Completion mode: check-on-pass

## 리뷰 요약

`code_review_local_G06_0.log` 판정은 FAIL입니다. 선택된 device 식별자 표시가 빠졌고, `startLogcat`이 늦게 완료되는 경계에서 stale session이 현재 콘솔에 붙을 수 있습니다.

## 범위 결정 근거

- `filter`, `auto-scroll`, export/clipboard, clear/pause 실제 동작은 이번 후속 범위에서 제외한다.
- 로드맵 문서는 수정하지 않는다. PASS completion event 이후 런타임이 처리한다.
- 실패 원인이 명확하고 widget test로 재현 가능하므로 follow-up route는 `local-G07`로 둔다.

## 구현 체크리스트

- [ ] `ConsolePage`가 선택 device label/serial을 표시하고 logcat 진입 test가 이를 검증한다.
- [ ] `ConsolePage` logcat start lifecycle에 stale async session guard를 추가한다.
- [ ] delayed starter/device change widget test로 stale session stop과 현재 session 유지 동작을 검증한다.
- [ ] `flutter test test/widget_test.dart test/console_page_test.dart`를 실행한다.
- [ ] `flutter analyze`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## REVIEW_LOGCAT_STREAM-1 Selected Device Identity

### 문제

`ConsolePage`는 선택된 `AdbDevice`를 stream 시작에만 사용하고 화면에는 표시하지 않습니다. 이전 계획의 LOGCAT_STREAM-1 테스트 기대값은 ready device logcat 진입 후 선택 device serial 또는 display name이 console에 보이는 것이었지만, 현재 test는 `콘솔` title만 확인합니다.

### 해결 방법

콘솔 상단 controls 근처에 선택 device display name과 serial을 표시합니다. `device == null`인 sample/preview 상태에서는 기존 sample console UI가 어색하지 않도록 표시를 생략하거나 "device 미선택" 상태를 명확히 둡니다.

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

- [ ] `lib/src/features/console/console_page.dart`: `widget.device` 기반 selected device label/serial UI 추가.
- [ ] `test/widget_test.dart`: `ready device logcat button opens console for that device`가 console 이동 후 device label 또는 serial을 검증하도록 보강.

### 테스트 작성

- 기존 `ready device logcat button opens console for that device` test를 보강한다.
- assertion: logcat 버튼 tap 후 `device-ready-logcat` 또는 `Pixel 8`이 console 화면에 표시된다.

### 중간 검증

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

## REVIEW_LOGCAT_STREAM-2 Async Session Race

### 문제

`ConsolePage._startSession`은 `await starter(serial: device.serial)` 이후 `mounted`만 확인하고 `_session`과 `_subscription`을 갱신합니다. 그 사이 widget이 다른 device/starter로 갱신되면 오래된 session이 현재 화면에 붙거나 새 session이 leak될 수 있습니다.

### 해결 방법

session generation/token 또는 capture한 serial/starter 대조를 추가합니다. `await starter` 이후 현재 widget 상태와 다르면 반환된 stale session을 즉시 `stop()`하고 화면 상태를 변경하지 않습니다. catch path도 현재 generation일 때만 error/loading 상태를 반영합니다. `_stopSession`은 기존 session/subscription을 정리하면서 pending start를 무효화해야 합니다.

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

- [ ] `lib/src/features/console/console_page.dart`: stale async session guard 추가.
- [ ] `test/console_page_test.dart`: delayed starter로 device 변경 중 첫 session이 늦게 반환되는 케이스 추가.

### 테스트 작성

- `ConsolePage`를 device A로 렌더링하고 starter completer A를 보류한다.
- 같은 widget tree에서 device B로 갱신한 뒤 starter completer B를 완료한다.
- 이후 completer A를 완료했을 때 A session은 `stop()`되고, B session line만 화면에 append되는지 확인한다.

### 중간 검증

```bash
flutter test test/console_page_test.dart
```

## 최종 검증

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

검증 출력은 `CODE_REVIEW-local-G07.md`의 `검증 결과`에 실제 stdout/stderr로 기록한다.
