<!-- task=m-performance-hotspot-optimization/11+10_dart_isolate_transport_path plan=0 tag=REFACTOR -->

# Plan - REFACTOR

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

이 plan은 `10_dart_isolate_gateway_contract` 완료 후 구현한다. active/archived `10_*` sibling의 `complete.log`가 없으면 구현을 시작하지 말고 review stub에 blocker로 기록한다. 구현 완료는 `CODE_REVIEW-cloud-G08.md` 작성까지다.

## 배경

현재 gateway는 `Communicator.attachInboundGateway` 보호 메서드로 테스트에서만 붙는다. Milestone은 사용자/운영 on-off 옵션 없이 제품 내부 단일 수신 경로에서 FIFO, nonce matching, close cleanup, web fallback을 유지하라고 요구한다. contract hardening 이후 TCP/WS transport가 raw frame을 `onReceivedFrame`으로 넘겨 gateway path를 실제 성능 row에 반영해야 한다.

## 사용자 리뷰 요청 흐름

선행 `10` complete.log 부재, user-only 환경 blocker, 범위 충돌은 review stub의 `사용자 리뷰 요청`에 기록한다. 직접 사용자에게 묻지 않는다.

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/performance-hotspot-optimization.md`
- Task ids:
  - `dart-isolate-real-path`: 실제 TCP/WS transport 수신 경로 hardening 연결
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- 공통/로드맵/plan/test 규칙 파일 일체
- `agent-roadmap/milestones/performance-hotspot-optimization.md`
- `agent-test/local/dart-smoke.md`
- `agent-test/local/proto-socket-performance-baseline.md`
- `dart/lib/src/protobuf_client.dart`
- `dart/lib/src/ws_protobuf_client_io.dart`
- `dart/lib/src/ws_protobuf_client_web.dart`
- `dart/lib/src/communicator.dart`
- `dart/lib/src/inbound_gateway.dart`
- `dart/lib/src/inbound_gateway_io.dart`
- `dart/lib/src/inbound_gateway_web.dart`
- `dart/lib/proto_socket.dart`
- `dart/test/socket_test.dart`
- `dart/test/communicator_test.dart`
- `dart/bench/stress.dart`

### 테스트 환경 규칙

`test_env=local`. Dart 변경은 `dart-smoke` 필수 검증을 따른다. 실제 성능 row 반영을 확인해야 하므로 focused `run_stress.sh --quick --lang dart --transport tcp,ws --profile roundtrip,payload`와 `run_performance.sh --quick`을 실행한다.

### 테스트 커버리지 공백

- TCP path: `socket_test.dart`는 fragmented frame/1MB/request-response를 커버한다. gateway가 실제 path에 붙었는지 관찰하는 테스트는 없다.
- WS IO path: same-language WS tests는 있으나 gateway path 여부를 관찰하지 않는다.
- Web fallback: compile test는 있으나 browser runtime gateway fallback stress는 full matrix에서만 확인된다.

### 심볼 참조

변경 후보: `Communicator.attachInboundGateway`(`dart/lib/src/communicator.dart:234-249`), `onReceivedFrame`(`:262-273`), TCP inline decode(`dart/lib/src/protobuf_client.dart:104-110`), WS IO inline decode(`dart/lib/src/ws_protobuf_client_io.dart:66-71`), WS web inline decode는 `dart/lib/src/ws_protobuf_client_web.dart` 동일 구조.

### 분할 판단

subtask dir `11+10_dart_isolate_transport_path`는 predecessor `10`에 의존한다. 현재 active sibling `agent-task/m-performance-hotspot-optimization/10_dart_isolate_gateway_contract/`에는 `complete.log`가 없으므로 의존성은 미충족이다. 구현은 `10` PASS 후 진행한다. 이 plan은 transport path 연결만 다루며 large payload transfer는 `12+10,11`로 분리한다.

### 범위 결정 근거

Public API 옵션은 추가하지 않는다. gateway on/off 사용자 설정, protocol schema, 다른 언어 구현은 제외한다. `dart-app-core` manager import는 하지 않는다.

### 빌드 등급

`cloud-G08`. 실제 transport 수신 경로, web conditional export, FIFO/nonce/close cleanup 회귀가 얽힌 concurrency 변경이다.

## 의존 관계 및 구현 순서

1. `10_dart_isolate_gateway_contract`의 `complete.log`를 확인한다.
2. TCP path를 `onReceivedFrame`으로 전환한다.
3. WS IO/web path를 같은 contract로 전환한다.
4. focused stress와 Dart smoke를 실행한다.

## 구현 체크리스트

- [ ] predecessor `10_dart_isolate_gateway_contract` complete.log 존재를 확인한다.
- [ ] `ProtobufClient`가 decoded inline path 대신 hardened gateway-backed `onReceivedFrame`을 사용하게 한다.
- [ ] `WsProtobufClient` IO/web이 같은 receive coordinator path를 사용하고 web은 `SyncInboundGateway` fallback을 유지한다.
- [ ] 내부 단일 수신 경로로 동작하며 public on/off 옵션을 추가하지 않는다.
- [ ] TCP/WS FIFO, nonce matching, close cleanup regression tests와 focused stress 결과를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REFACTOR-1] TCP transport receive path

문제: TCP `_parsing()`은 frame extraction 후 `PacketBase.fromBuffer`를 직접 호출한다(`dart/lib/src/protobuf_client.dart:104-110`). gateway는 성능 row에 반영되지 않는다.

해결 방법:

```dart
// Before
final common = PacketBase.fromBuffer(packetBytes);
await onReceivedData(common.typeName, common.data,
    incomingNonce: common.nonce, responseNonce: common.responseNonce);
```

```dart
// After sketch
await onReceivedFrame(packetBytes);
```

constructor에서 내부 gateway를 attach하되 async readiness/drop은 `10` contract에 맡긴다.

수정 파일 및 체크리스트:
- [ ] `dart/lib/src/protobuf_client.dart`
- [ ] `dart/test/socket_test.dart`

테스트 작성: existing TCP fragmented/1MB/request-response tests를 유지하고, gateway path를 관찰 가능한 internal test seam이 있으면 추가한다.

중간 검증:

```bash
cd dart && dart test test/socket_test.dart -r expanded
```

### [REFACTOR-2] WS IO/web receive path

문제: WS IO `_dispatch`도 inline decode를 수행한다(`dart/lib/src/ws_protobuf_client_io.dart:66-71`). web path도 같은 구조라 gateway fallback이 제품 경로에 없다.

해결 방법: IO는 `IsolateInboundGateway`, web은 conditional export의 `SyncInboundGateway` 기반 `IsolateInboundGateway`를 attach한다. `_dispatch`는 bytes normalization 후 `await onReceivedFrame(bytes)`만 수행한다.

수정 파일 및 체크리스트:
- [ ] `dart/lib/src/ws_protobuf_client_io.dart`
- [ ] `dart/lib/src/ws_protobuf_client_web.dart`
- [ ] `dart/test/socket_test.dart`

테스트 작성: existing WS request-response/close/broadcast tests로 회귀 확인한다. Browser runtime은 full matrix에서 확인한다.

중간 검증:

```bash
cd dart && dart test test/socket_test.dart -r expanded
```

### [REFACTOR-3] Performance row inclusion

문제: milestone 완료 조건은 제품 내부 단일 수신 경로가 성능 row에 반영되는 것이다. 단위 테스트만으로는 부족하다.

해결 방법: focused `roundtrip,payload` stress를 TCP/WS 모두 실행하고 결과 파일에 Dart rows가 PASS/stability 0인지 기록한다.

수정 파일 및 체크리스트:
- [ ] 코드 변경 없음. 검증 산출물 수집.

테스트 작성: skip.

중간 검증:

```bash
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh --quick --lang dart --transport tcp,ws --profile roundtrip,payload
```

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `dart/lib/src/protobuf_client.dart` | REFACTOR-1 |
| `dart/lib/src/ws_protobuf_client_io.dart` | REFACTOR-2 |
| `dart/lib/src/ws_protobuf_client_web.dart` | REFACTOR-2 |
| `dart/test/socket_test.dart` | REFACTOR-1, REFACTOR-2 |

## 최종 검증

```bash
cd dart && dart test test/socket_test.dart test/communicator_test.dart -r expanded
cd dart && dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh --quick --lang dart --transport tcp,ws --profile roundtrip,payload
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_performance.sh --quick
```

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