<!-- task=m-inbound-queue-ordering/06_kotlin_gateway plan=1 tag=REVIEW_API -->

# Kotlin Gateway Wiring 후속 구현 계획

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

이 계획은 직전 리뷰 FAIL의 Required 이슈만 해결한다. 구현 후 `CODE_REVIEW-cloud-G08.md`의 구현 에이전트 소유 섹션에 실제 변경 내용과 검증 stdout/stderr를 채운 뒤 active 파일을 그대로 두고 리뷰를 요청한다. 최종 판정과 archive는 code-review 전용이다.

## 배경

직전 구현은 `CoroutineWorkerGateway`와 reorder 테스트를 추가했지만, 실제 Kotlin TCP/WS read loop는 여전히 raw frame을 inline decode한 뒤 `Communicator.enqueueInbound`로 직접 넘긴다. 따라서 gateway worker pool이 production ingress path에 적용되지 않았다.

## 사용자 리뷰 요청 흐름

구현 중 user-only blocker가 있으면 active review stub의 `사용자 리뷰 요청` 섹션을 채운다.

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/inbound-queue-ordering.md`
- Task ids:
  - `kotlin-gateway`: Kotlin coroutine worker gateway 후보를 적용한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-task/m-inbound-queue-ordering/06_kotlin_gateway/plan_cloud_G08_0.log`
- `agent-task/m-inbound-queue-ordering/06_kotlin_gateway/code_review_cloud_G08_0.log`
- `kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt`
- `kotlin/src/main/kotlin/com/tokilabs/proto_socket/TcpClient.kt`
- `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt`
- `kotlin/src/test/kotlin/com/tokilabs/proto_socket/CommunicatorTest.kt`
- `go/communicator.go`
- `go/tcp_client.go`
- `go/ws_client.go`

### 실패 원인

- Kotlin `Communicator`에 raw frame ingress API와 gateway attach/enable API가 없다.
- `TcpClient`와 `WsClient`가 gateway를 거칠 수 있는 `onReceivedFrame` equivalent 대신 `PacketBase.parseFrom`을 직접 호출한다.
- 테스트가 gateway를 수동 생성하고 sink에서 `enqueueInbound`를 직접 호출해 실제 read loop wiring gap을 잡지 못한다.

### 범위 결정 근거

- 기존 worker gateway 구현을 유지하고, communicator/transport wiring과 그 wiring을 증명하는 테스트만 추가한다.
- proto schema, 다른 언어 구현, OkHttp staging 정책은 변경하지 않는다.

### 빌드 등급

- build/review: `cloud-G08`. 이유: coroutine gateway lifecycle, transport parse-error semantics, TCP/WS ingress API contract를 함께 다룬다.

## 구현 체크리스트

- [ ] `Communicator`에 내부 frame seq, gateway attach/enable API, raw `onReceivedFrame` ingress, gateway decode error handler를 추가한다.
- [ ] `Communicator.close()`/`shutdown()`에서 attached gateway lifecycle을 정리하고, gateway가 coordinator state를 소유하지 않게 유지한다.
- [ ] `TcpClient` read loop가 raw packet bytes를 `Communicator.onReceivedFrame`으로 전달하고 inline/gateway parse error 모두 기존 disconnect semantics를 보존한다.
- [ ] `WsClient.receiveBytes`가 raw websocket bytes를 `Communicator.onReceivedFrame`으로 전달하고 inline/gateway parse error 모두 기존 disconnect semantics를 보존한다.
- [ ] Kotlin tests에 read loop가 attached gateway를 우회하지 않는 검증과 gateway parse-error path 검증을 추가한다.
- [ ] 중간 검증으로 `cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle ./gradlew test --tests com.tokilabs.proto_socket.CommunicatorTest --rerun-tasks`를 실행한다.
- [ ] 최종 검증으로 `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all`을 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_API-1] Kotlin gateway wiring

#### 문제

- `CoroutineWorkerGateway`가 실제 ingress path에서 사용되지 않아 `kotlin-gateway` Task 완료 조건을 충족하지 못한다.

#### 해결 방법

- Go 선행 구현과 같은 구조로 `Communicator`에 gateway attach/enable과 raw frame ingress를 추가한다.
- `TcpClient`/`WsClient`는 raw frame을 직접 decode하지 말고 communicator raw ingress에 넘긴다.
- gateway sink는 decoded frame을 `enqueueInbound` 또는 기존 coordinator path로만 전달한다.

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

- [ ] `kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt`
- [ ] `kotlin/src/main/kotlin/com/tokilabs/proto_socket/TcpClient.kt`
- [ ] `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt`
- [ ] `kotlin/src/test/kotlin/com/tokilabs/proto_socket/CommunicatorTest.kt`

#### 테스트 작성

- attached counting gateway가 raw frame submit을 기록하고, read loop/receiveBytes가 inline decode로 우회하면 실패하게 만든다.
- gateway decode error가 caller-owned error/disconnect handler로 전달되는지 확인한다.
- production `CoroutineWorkerGateway` attached path에서도 out-of-order completion 후 communicator listener dispatch 순서가 입력 순서인지 확인한다.

#### 중간 검증

```bash
cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle ./gradlew test --tests com.tokilabs.proto_socket.CommunicatorTest --rerun-tasks
```

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt` | REVIEW_API-1 |
| `kotlin/src/main/kotlin/com/tokilabs/proto_socket/TcpClient.kt` | REVIEW_API-1 |
| `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt` | REVIEW_API-1 |
| `kotlin/src/test/kotlin/com/tokilabs/proto_socket/CommunicatorTest.kt` | REVIEW_API-1 |

## 최종 검증

```bash
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all
```

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