<!-- task=m-socket-session-loop/01_client_socket_layer plan=1 tag=REVIEW_API -->

# Plan - REVIEW_API

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

`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채우는 것이 필수 마지막 단계다. 구현 후 검증을 실행하고 실제 출력, 계획 대비 변경, 설계 결정을 review stub에 기록한 뒤 active 파일을 유지하고 리뷰 준비를 보고한다. 사용자 결정, 외부 환경 준비, 범위 충돌 없이는 안전하게 진행할 수 없으면 review stub의 `사용자 리뷰 요청`에 정확한 증거를 남기고 중단한다. `USER_REVIEW.md`, archive, `complete.log` 작성은 code-review 전용이다.

## 배경

첫 리뷰는 `FAIL`이다. Flutter wrapper 자체 테스트는 통과했지만, 구현이 `../proto-socket/dart` generated packet binding을 손으로 수정했고 `apps/client` root `dependency_overrides`로 proto_socket의 `protobuf` 제약을 우회했다. Socket Session Loop의 client layer는 이후 UI/state 작업의 기반이므로, proto_socket Dart package 자체가 protobuf runtime 계약과 generated output을 일관되게 소유해야 한다.

## 사용자 리뷰 요청 흐름

구현 중 차단 조건은 active `CODE_REVIEW-*-G??.md`의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 그 내용을 검증해 실제 `USER_REVIEW.md` 작성 여부를 결정한다.

## 분석 결과

### 읽은 파일

- `agent-task/m-socket-session-loop/01_client_socket_layer/code_review_cloud_G06_0.log`
- `agent-task/m-socket-session-loop/01_client_socket_layer/plan_cloud_G06_0.log`
- `apps/client/pubspec.yaml`
- `apps/client/pubspec.lock`
- `apps/client/lib/src/integrations/socket/alt_socket_client.dart`
- `apps/client/lib/src/integrations/socket/socket_endpoint.dart`
- `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- `../proto-socket/dart/pubspec.yaml`
- `../proto-socket/dart/pubspec.lock`
- `../proto-socket/dart/lib/src/packets/message_common.pb.dart`
- `../proto-socket/tools/generate_proto.sh`

### 실패 근거

- `../proto-socket/dart/lib/src/packets/message_common.pb.dart`는 generated file인데 `createRepeated()`가 손으로 `UnsupportedError('obsolete')`를 던지도록 변경되었다.
- `apps/client/pubspec.yaml`의 `dependency_overrides`가 `protobuf ^6.0.0`을 강제하지만, path dependency인 `../proto-socket/dart/pubspec.yaml`은 여전히 `protobuf: ^3.1.0`을 선언한다.
- 기존 review log의 dependency 설명은 `protoc_plugin` downgrade를 말하지만 실제 manifest/lockfile은 `25.0.0`이다.

### 빌드 등급

- build: `cloud-G06`, review: `cloud-G06`.
- protocol/generated binding과 Flutter dependency graph를 함께 정리하지만 terminal-agent workflow는 아니므로 cloud-G06을 유지한다.

## 구현 체크리스트

- [ ] `../proto-socket/dart`의 protobuf runtime 계약을 package 차원에서 정리하고 `apps/client/pubspec.yaml`의 root `dependency_overrides` 의존을 제거하거나 명확히 정당화한다. 검증: `cd ../proto-socket/dart && dart pub get`, `cd apps/client && flutter pub get`.
- [ ] `../proto-socket/dart/lib/src/packets/message_common.pb.dart`의 손수정 `UnsupportedError('obsolete')` diff를 제거하고 canonical proto 기준 Dart binding을 재생성한다. 검증: `cd ../proto-socket && protoc --proto_path=proto --dart_out=dart/lib/src/packets message_common.proto`, `cd ../proto-socket && tools/check_proto_sync.sh`.
- [ ] 후속 구현 기록을 실제 manifest/lockfile/diff와 일치하게 작성하고 wrapper 파일을 format-clean 상태로 만든다. 검증: `cd apps/client && dart format --output=none --set-exit-if-changed lib/src/integrations/socket test/integrations/socket`.
- [ ] 최종 검증으로 `cd ../proto-socket/dart && dart analyze`, `cd ../proto-socket/dart && dart test`, `cd ../proto-socket/dart && dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js`, `cd apps/client && flutter test`, `cd apps/client && flutter analyze --no-fatal-infos`, `cd apps/client && flutter build web`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_API-1] Fix protobuf runtime contract

문제: `apps/client/pubspec.yaml` root override가 `protobuf ^6.0.0`을 강제하지만 `../proto-socket/dart/pubspec.yaml`은 `protobuf: ^3.1.0`으로 남아 있다. 이 상태는 ALT app에서만 dependency solver를 우회하고, proto_socket package 자체 테스트/lockfile은 다른 protobuf major를 사용할 수 있다.

해결 방법:

- `../proto-socket/dart/pubspec.yaml`의 `protobuf` constraint를 실제 지원 버전과 맞춘다. 현재 ALT generated contracts가 protobuf 6 API를 요구하므로 proto_socket Dart package도 protobuf 6 compatible로 정리하는 방향을 우선한다.
- `../proto-socket/dart/pubspec.lock`을 `dart pub get`으로 갱신한다.
- `apps/client/pubspec.yaml`의 `dependency_overrides`는 package constraint가 정상 해소되면 제거한다. 부득이하게 남겨야 하면 이유와 제거 조건을 review stub에 기록한다.
- `apps/client/pubspec.lock`을 `flutter pub get`으로 갱신한다.

수정 파일 및 체크리스트:

- [ ] `../proto-socket/dart/pubspec.yaml`
- [ ] `../proto-socket/dart/pubspec.lock`
- [ ] `apps/client/pubspec.yaml`
- [ ] `apps/client/pubspec.lock`

테스트 작성: 별도 테스트보다 dependency resolution 검증이 핵심이다.

중간 검증:

```bash
cd ../proto-socket/dart && dart pub get
cd apps/client && flutter pub get
```

기대 결과: proto_socket package와 ALT client가 같은 protobuf major 계약으로 clean resolution된다.

### [REVIEW_API-2] Regenerate proto_socket Dart packets

문제: generated packet file을 손으로 고쳐 `createRepeated()`가 런타임 예외를 던지게 만들었다. 이는 generated output 수정 금지와 proto_socket canonical proto/generation 흐름을 어긴다.

해결 방법:

- `../proto-socket/dart/lib/src/packets/message_common.pb.dart`의 수동 `UnsupportedError('obsolete')` 변경을 없앤다.
- protobuf 6 compatible `protoc-gen-dart`로 `../proto-socket/proto/message_common.proto`에서 Dart binding을 재생성한다.
- `protoc-gen-dart`가 없으면 `dart pub global activate protoc_plugin 25.0.0`로 준비한다. 네트워크/권한 문제로 준비할 수 없으면 review stub의 `사용자 리뷰 요청`에 command output과 재개 조건을 기록한다.
- schema 자체는 바꾸지 않는다. Go/Kotlin/Python/TypeScript packet schema 변경은 이 follow-up 범위가 아니다.

수정 파일 및 체크리스트:

- [ ] `../proto-socket/dart/lib/src/packets/message_common.pb.dart`
- [ ] 필요한 경우 proto_socket Dart generated sidecar files

테스트 작성: 새 테스트는 필수 아님. 대신 generated API와 web import compile을 검증한다.

중간 검증:

```bash
cd ../proto-socket && protoc --proto_path=proto --dart_out=dart/lib/src/packets message_common.proto
cd ../proto-socket && tools/check_proto_sync.sh
```

기대 결과: generated file에 `PbList()` obsolete hand edit가 남지 않고, proto schema sync가 깨지지 않는다.

### [REVIEW_API-3] Restore verification trust and formatting

문제: 기존 review log는 `protoc_plugin` downgrade를 설명했지만 실제 manifest/lockfile은 `25.0.0`이다. 또한 wrapper/test 파일은 `dart format --output=none --set-exit-if-changed`에서 변경 대상으로 보고되었다.

해결 방법:

- 실제 dependency resolution 결과를 manifest/lockfile 기준으로 review stub에 기록한다.
- `apps/client/lib/src/integrations/socket/`와 `apps/client/test/integrations/socket/`를 `dart format` 기준에 맞춘다.
- 최종 검증 출력은 cached output이 아니라 실제 재실행 stdout/stderr를 붙인다.

수정 파일 및 체크리스트:

- [ ] `apps/client/lib/src/integrations/socket/alt_socket_client.dart`
- [ ] `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- [ ] `CODE_REVIEW-cloud-G06.md`

테스트 작성: 형식/기록 신뢰도 복구 작업이라 새 테스트는 필수 아님.

중간 검증:

```bash
cd apps/client && dart format lib/src/integrations/socket test/integrations/socket
cd apps/client && dart format --output=none --set-exit-if-changed lib/src/integrations/socket test/integrations/socket
```

기대 결과: format check가 exit 0으로 끝나고, review stub의 설명이 실제 diff와 충돌하지 않는다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `../proto-socket/dart/pubspec.yaml` | REVIEW_API-1 |
| `../proto-socket/dart/pubspec.lock` | REVIEW_API-1 |
| `apps/client/pubspec.yaml` | REVIEW_API-1 |
| `apps/client/pubspec.lock` | REVIEW_API-1 |
| `../proto-socket/dart/lib/src/packets/message_common.pb.dart` | REVIEW_API-2 |
| `apps/client/lib/src/integrations/socket/alt_socket_client.dart` | REVIEW_API-3 |
| `apps/client/test/integrations/socket/alt_socket_client_test.dart` | REVIEW_API-3 |
| `agent-task/m-socket-session-loop/01_client_socket_layer/CODE_REVIEW-cloud-G06.md` | REVIEW_API-3 |

## 최종 검증

```bash
cd ../proto-socket/dart && dart analyze
cd ../proto-socket/dart && dart test
cd ../proto-socket/dart && dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js
cd apps/client && flutter test
cd apps/client && flutter analyze --no-fatal-infos
cd apps/client && flutter build web
```

기대 결과: proto_socket Dart package와 ALT client가 모두 통과한다. cached output은 허용하지 말고 명령을 실제 재실행한다.

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