<!-- task=m-api-centered-proto-socket-rail/03+01_client_api_wrappers plan=1 tag=REVIEW_CLIENT -->
# PLAN-cloud-G07: Client API Wrapper Review Follow-up

## 이 파일을 읽는 구현 에이전트에게
이 계획은 이전 리뷰의 Required 항목만 닫는다. 코드 변경 후 반드시 active `CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 실제 검증 stdout/stderr로 채우고, active 파일을 그대로 둔 채 리뷰를 요청한다. finalization, log rename, `complete.log`, archive 이동은 code-review 전용이다. 사용자 결정, 사용자 소유 외부 환경, 또는 범위 충돌이 없으면 `USER_REVIEW.md`를 직접 만들지 말고 review stub의 `사용자 리뷰 요청`만 증거와 함께 채운다.

## 배경
첫 리뷰에서 wrapper 구현 자체는 기존 `sendRequest<Req, Res>` API socket 패턴을 따르는 것으로 보였지만, 계획이 요구한 error-path coverage와 검증 증거가 부족했다. 후속 작업은 새 public wrapper surface의 boundary test를 보강하고, 허용된 원격 검증 환경의 실제 출력으로 review evidence를 복구한다.

## 사용자 리뷰 요청 흐름
implementation-time blocker는 active `CODE_REVIEW-cloud-G07.md`의 `사용자 리뷰 요청` 섹션에 기록한다. 검증 출력 누락처럼 후속 에이전트가 재실행 또는 산출물 수집으로 해소할 수 있는 공백만으로는 사용자 리뷰 요청을 만들지 않는다.

## 분석 결과

### 읽은 파일
- `agent-task/m-api-centered-proto-socket-rail/03+01_client_api_wrappers/plan_cloud_G07_0.log`
- `agent-task/m-api-centered-proto-socket-rail/03+01_client_api_wrappers/code_review_cloud_G07_0.log`
- `apps/client/lib/src/integrations/socket/alt_socket_client.dart`
- `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- `apps/client/lib/src/contracts/alt_contracts.dart`
- `apps/client/test/contracts/alt_contracts_test.dart`
- `apps/client/lib/src/integrations/socket/socket_endpoint.dart`
- `apps/client/lib/src/integrations/socket/socket_connection_controller.dart`
- `apps/client/integration_test/socket_runtime_smoke_test.dart`
- `apps/client/test_runtime/socket_web_runtime_smoke_test.dart`
- `packages/contracts/proto/alt/v1/backtest.proto`
- `packages/contracts/proto/alt/v1/market.proto`
- `../proto-socket/dart/lib/src/communicator.dart`
- `apps/client/pubspec.yaml`
- `agent-test/local/rules.md`
- `agent-test/local/client-smoke.md`

### 테스트 커버리지 공백
- `startBacktest`, `listInstruments`, `listBars` success round-trip은 `apps/client/test/integrations/socket/alt_socket_client_test.dart`에 추가되어 있다.
- 이전 계획의 error-path propagation 요구는 아직 테스트되지 않았다.
- 전체 `cd apps/client && flutter test`와 socket runtime smoke의 실제 stdout/stderr가 없다.

### 심볼 참조
- renamed/removed symbol: none.
- 새 호출 surface: `AltSocketClient.startBacktest`, `AltSocketClient.listInstruments`, `AltSocketClient.listBars`.

### 분할 판단
split decision policy를 재평가했다. 이 follow-up은 같은 client wrapper test/evidence 표면만 닫는 보완 작업이며, API/worker sibling 작업과 독립적으로 리뷰 가능하므로 기존 split subtask `03+01_client_api_wrappers` 안의 단일 follow-up plan으로 유지한다.

### 범위 결정 근거
- `services/api/**`, `services/worker/**`, protobuf schema source, generated Dart outputs는 수정하지 않는다.
- API의 실제 worker-backed 응답 구현은 sibling task 범위다.
- 이 작업은 client wrapper tests와 review evidence 복구만 다룬다.

### 빌드 등급
- Build lane: `cloud-G07`
- Review lane: `cloud-G07`
- 근거: 이전 리뷰가 verification trust Fail을 기록했고, 허용된 원격 검증 환경의 stdout/stderr 수집과 runtime smoke 판단이 필요하다.

## 구현 체크리스트
- [ ] [REVIEW_CLIENT-1] `AltSocketClient` 신규 wrapper 3종의 error-path boundary test를 추가한다.
- [ ] [REVIEW_CLIENT-2] 허용된 원격 검증 환경에서 계획 검증 명령을 실행하고 실제 stdout/stderr를 `CODE_REVIEW-cloud-G07.md`에 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_CLIENT-1] Error-path boundary coverage
문제:
`plan_cloud_G07_0.log:69`는 error path가 기존 wrapper와 같은 방식으로 전파되는지 확인하라고 했지만, `apps/client/test/integrations/socket/alt_socket_client_test.dart:331` 이후의 신규 테스트는 success round-trip만 검증한다.

해결 방법:
`apps/client/test/integrations/socket/alt_socket_client_test.dart`에 새 wrapper error propagation test를 추가한다. `sendRequest`의 typed response mismatch 경로를 사용하면 fake socket만으로 결정적으로 검증할 수 있다.

Before:
```dart
test('startBacktest command request-response loop', () async {
  ...
});
```

After approach:
```dart
test('new API wrappers propagate response type mismatch errors', () async {
  Future<void> expectTypeMismatch<Res>(Future<Res> future) async {
    await Future<void>.delayed(Duration.zero);
    final sentPacket = PacketBase.fromBuffer(fakeWs.sentBytes.last);
    final wrongResponse = HelloResponse()..serverName = 'wrong-type';
    fakeWs.feedFromServer((PacketBase()
          ..typeName = HelloResponse.getDefault().info_.qualifiedMessageName
          ..nonce = 300
          ..responseNonce = sentPacket.nonce
          ..data = wrongResponse.writeToBuffer())
        .writeToBuffer());
    await expectLater(future, throwsA(isA<StateError>()));
  }

  await expectTypeMismatch(client.startBacktest(StartBacktestRequest()));
  await expectTypeMismatch(client.listInstruments(ListInstrumentsRequest()));
  await expectTypeMismatch(client.listBars(ListBarsRequest()));
});
```

수정 파일 및 체크리스트:
- `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- [ ] 새 테스트가 세 신규 wrapper 모두에서 wrong response type을 주입한다.
- [ ] assertion은 `StateError` 전파를 확인한다.
- [ ] fake transport 외 runtime endpoint를 추가하지 않는다.

테스트 작성:
- 작성: `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- 테스트명: `new API wrappers propagate response type mismatch errors`
- assertion goal: response type mismatch가 wrapper에서 삼켜지지 않고 `sendRequest` error로 전파된다.

중간 검증:
- 허용된 원격 검증 환경에서 `cd apps/client && flutter test test/integrations/socket/alt_socket_client_test.dart`
- 기대 결과: exit code 0, 실제 stdout/stderr를 review stub에 붙인다.

### [REVIEW_CLIENT-2] Verification evidence recovery
문제:
`code_review_cloud_G07_0.log:44`와 `code_review_cloud_G07_0.log:47`에 기록된 것처럼 이전 review evidence는 실제 stdout/stderr가 없고, 원 계획의 전체 Flutter test 및 socket runtime smoke 검증을 충족하지 못했다.

해결 방법:
로컬 테스트는 `agent-test/local/rules.md`상 금지되어 있으므로 이 로컬 세션에서 실행하지 않는다. 허용된 원격 검증 환경에서 아래 명령을 실행하고, active `CODE_REVIEW-cloud-G07.md`의 `검증 결과`에 명령, exit code, stdout/stderr를 원문으로 기록한다. 원격 runtime smoke를 실행할 수 없으면 실행한 명령, 실제 출력, 미실행 사유, 재개 조건을 `사용자 리뷰 요청` 또는 `검증 결과`에 구분해 기록한다.

수정 파일 및 체크리스트:
- `agent-task/m-api-centered-proto-socket-rail/03+01_client_api_wrappers/CODE_REVIEW-cloud-G07.md`
- [ ] `구현 체크리스트` 항목을 실제 완료 상태로 체크한다.
- [ ] `계획 대비 변경 사항`, `주요 설계 결정`, `검증 결과`를 placeholder 없이 채운다.
- [ ] 검증 명령별 실제 stdout/stderr를 기록한다.

테스트 작성:
- 코드 테스트 추가 없음. REVIEW_CLIENT-1의 테스트 보강 후 원격 검증 명령을 실행한다.

중간 검증:
- 허용된 원격 검증 환경에서 `cd apps/client && flutter test`
- 허용된 원격 검증 환경에서 `cd apps/client && flutter analyze`
- 허용된 원격 검증 환경에서 `cd apps/client && dart run test -p chrome test_runtime/socket_web_runtime_smoke_test.dart --timeout 30s`
- 가능한 원격 device/smoke 환경에서 `cd apps/client && flutter test integration_test/socket_runtime_smoke_test.dart`
- 기대 결과: 실행 가능한 명령은 exit code 0, 실행 불가 명령은 실제 차단 근거와 재개 조건 기록.

## 수정 파일 요약
| 파일 | 항목 |
|------|------|
| `apps/client/test/integrations/socket/alt_socket_client_test.dart` | REVIEW_CLIENT-1 |
| `agent-task/m-api-centered-proto-socket-rail/03+01_client_api_wrappers/CODE_REVIEW-cloud-G07.md` | REVIEW_CLIENT-2 |

## 최종 검증
- 허용된 원격 검증 환경에서 `cd apps/client && flutter test`
- 허용된 원격 검증 환경에서 `cd apps/client && flutter analyze`
- 허용된 원격 검증 환경에서 `cd apps/client && dart run test -p chrome test_runtime/socket_web_runtime_smoke_test.dart --timeout 30s`
- 가능한 원격 device/smoke 환경에서 `cd apps/client && flutter test integration_test/socket_runtime_smoke_test.dart`
모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
