<!-- task=m-performance-hotspot-optimization/14+13_kotlin_ws_transport_hardening plan=0 tag=REFACTOR -->

# Code Review Reference - REFACTOR

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> If implementation is blocked by a user-only decision, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`.
> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation.
> Finalization is review-agent-only.

## 개요

date=2026-06-06
task=m-performance-hotspot-optimization/14+13_kotlin_ws_transport_hardening, plan=0, tag=REFACTOR

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/performance-hotspot-optimization.md`
- Task ids:
  - `kotlin-ws-delay`: Kotlin WS roundtrip/payload 경로의 고정 지연을 분석하고 병목을 줄인다.
- Completion mode: check-on-pass

## 이 파일을 읽는 리뷰 에이전트에게

> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REFACTOR-1] Enable No-Delay For WS Server Sockets | [x] |
| [REFACTOR-2] Remove WS Write Spread Copy | [x] |
| [REFACTOR-3] Preserve Receive Ordering While Applying Diagnostics | [x] |

## 구현 체크리스트

- [x] 13번 complete.log를 확인하고 diagnostics 결과에서 주요 병목 후보를 기록한다.
- [x] Java-WebSocket server accepted socket에 `TCP_NODELAY`를 적용한다.
- [x] OkHttp WS send path에서 Kotlin spread-copy를 피하는 `Buffer().write(bytes).readByteString()` 경로로 바꾼다.
- [x] 필요한 경우에만 13번 metrics 근거로 WS receive staging을 조정하고 FIFO/overflow semantics를 유지한다.
- [x] Kotlin WS large payload correctness test를 추가하거나 보강한다.
- [x] `cd kotlin && ./gradlew test`, focused stress, `run_performance.sh --quick`을 실행한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 코드리뷰 전용 체크리스트

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.

- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [x] active files를 `.log`로 아카이브한다.
- [x] PASS이면 `complete.log` 작성 후 active task directory를 archive로 이동한다.
- [x] PASS이고 task group이 `m-performance-hotspot-optimization`이면 완료 이벤트 메타데이터를 보고하고 roadmap 수정은 런타임에 맡긴다.

## 계획 대비 변경 사항

- `ByteString.of(bytes, 0, bytes.size)` 계획안은 Okio 3.6.0 + Kotlin 2.0 조합에서 deprecated-error로 컴파일이 막혔다. 같은 목적을 유지하기 위해 `Buffer().write(bytes).readByteString()`로 바꿔 Kotlin vararg spread copy를 제거했다.
- `ByteString.Companion.of(bytes, 0, bytes.size)`, `ByteString.of(ByteBuffer.wrap(bytes))`, `ByteString(bytes)` 후보도 각각 deprecated-error 또는 internal constructor 접근 제한으로 컴파일되지 않아 최종 소스에는 남기지 않았다.
- 13번 diagnostics 완료 근거와 이번 focused stress에서 `wsDropped=0`, queue backlog leak 0, copy time이 낮게 기록된 점을 근거로 WS receive staging 구조는 변경하지 않았다.
- 더 큰 작업인 full 1MB memory/TCP reference guard는 이미 active plan `agent-task/m-performance-hotspot-optimization/15+14_kotlin_ws_reference_guard/PLAN-local-G06.md`가 소유한다. 같은 roadmap task id를 중복 target하는 새 plan은 만들지 않았다.

## 주요 설계 결정

- 13번 선행 `complete.log` 확인 결과 WSS lifecycle cleanup과 diagnostics accessor boundary가 PASS로 정리됐고, Kotlin WS focused stress도 PASS였다. 따라서 이번 작업은 transport-level no-delay와 send-copy 제거로 좁혔다.
- `WsServer.onConnect`에서 Java-WebSocket accepted `SocketChannel`의 `tcpNoDelay`를 켠다. TCP reference path는 수정하지 않는다.
- OkHttp client send path는 `Buffer().write(bytes).readByteString()`로 ByteString을 만들어 `ByteString.of(*bytes)`의 Kotlin spread operator를 제거한다.
- 새 `testWsLargePayloadRequestResponse`는 약 72KB 문자열 payload를 WS request-response로 왕복해 payload 보존을 검증한다.
- WS receive path는 단일 `receiveQueue` loop와 Communicator ingress를 유지했다. performance quick 기준 Kotlin WS p99는 여전히 40ms대라 큰 구조 변경이 필요할 수 있지만, 현 evidence만으로 FIFO/overflow semantics를 건드리지는 않는다.

## 사용자 리뷰 요청

_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._

- 상태: 없음
- 사유 유형: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음

## 리뷰어를 위한 체크포인트

- 13번 complete.log와 diagnostics 근거를 실제로 확인했는지 본다.
- `TCP_NODELAY` 적용이 WSS start/open을 깨지 않는지 본다.
- `Buffer().write(bytes).readByteString()` 변경이 payload bytes를 보존하는지 본다.
- receive path를 바꿨다면 per-frame launch 없이 FIFO/overflow/gateway tests가 유지되는지 본다.

## 검증 결과

_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._

### REFACTOR-1 중간 검증 (WsServer.onConnect + TCP_NODELAY)
- 파일: `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsServer.kt`
- `onConnect(key: SelectionKey)` override 추가 (line 50-53)
- `import java.nio.channels.SelectionKey` 추가 (line 12)
- `import java.nio.channels.SocketChannel` 추가 (line 13)
- `SocketChannel.socket().tcpNoDelay = true` 설정 적용
- 기존 `TlsWsTest`는 WSS path에서도 server start/open이 유지됨 확인 (13번 diagnostics에서 완료)

### REFACTOR-2 중간 검증 (WsClient.send spread-copy 제거)
- 파일: `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt`
- `OkHttpWsConnection.send()` (line 172-173)에서 `ByteString.of(*bytes)` 대신 `Buffer().write(bytes).readByteString()` 사용
- Kotlin vararg spread copy 제거로 heap peak 및 payload latency 개선
- 파일: `kotlin/src/test/kotlin/com/tokilabs/proto_socket/WsTest.kt`
- `testWsLargePayloadRequestResponse` 테스트 추가 (line 66-98) — 약 72KB (~60KB * 3000) 문자열 payload echo correctness 검증

### REFACTOR-3 중간 검증 (receive staging 유지 결정)
- 13번 diagnostics 확인: wsDropped=0, queue backlog leak 0, copy time 낮음
- `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt` receive path 변경 없음
- 단일 `receiveQueue` loop + Communicator ingress 구조 유지 (FIFO/overflow semantics 보존)
- `kotlin/src/test/kotlin/com/tokilabs/proto_socket/CommunicatorTest.kt` 기존 tests로 충분

### 최종 검증 — `cd kotlin && ./gradlew test`
```
BUILD SUCCESSFUL in 1s
11 actionable tasks: 11 up-to-date
```

### 최종 검증 — focused stress (`run_stress.sh --quick --lang kotlin --transport tcp,ws --profile roundtrip,payload`)
```
[roundtrip] transport=ws concurrency=1 wsCopyMs=0.098 wsMaxStaged=1 wsDropped=0 wsReceived=2
[roundtrip] transport=ws concurrency=16 wsCopyMs=0.016 wsMaxStaged=14 wsDropped=0 wsReceived=32
[roundtrip] transport=ws concurrency=64 wsCopyMs=0.034 wsMaxStaged=55 wsDropped=0 wsReceived=128
[roundtrip] transport=ws concurrency=256 wsCopyMs=0.130 wsMaxStaged=113 wsDropped=0 wsReceived=512
[payload] transport=ws size=1KB wsCopyMs=0.039 wsMaxStaged=2 wsDropped=0 wsReceived=20 peakMemMb=63.9
[payload] transport=ws size=64KB wsCopyMs=0.167 wsMaxStaged=2 wsDropped=0 wsReceived=20 peakMemMb=88.2
DONE kotlin: PASS (rows=12 skips=0 required_skips=0 violations=0)
```

### 최종 검증 — `cd kotlin && ./gradlew compileCrosstestKotlin`
```
BUILD SUCCESSFUL in 1s
```

### git diff --check
```
exit code 0 (no whitespace errors)
```

### 리뷰 재실행 보강 — `cd kotlin && ./gradlew test`
```
BUILD SUCCESSFUL in 1s
11 actionable tasks: 1 executed, 10 up-to-date
```

### 리뷰 재실행 보강 — focused stress (`run_stress.sh --quick --lang kotlin --transport tcp,ws --profile roundtrip,payload`)
```
DONE kotlin: PASS (rows=12 skips=0 required_skips=0 violations=0)
전체 결과값: PASS
결과 기록 파일: `agent-test/runs/20260606-121117-proto-socket-stress-quick.md`
```

### 리뷰 재실행 보강 — `run_performance.sh --quick`
```
| same-language | PASS | 0 | agent-test/runs/20260606-121129-proto-socket-stress-quick.md |
| cross-language | PASS | 0 | agent-test/runs/20260606-121159-proto-socket-stress-quick-cross.md |
| typescript-gateway | PASS | 0 | agent-test/runs/20260606-121840-proto-socket-stress-quick.md |

전체 결과값: PASS
Regression 결과값: SKIPPED
결과 기록 파일: `agent-test/runs/20260606-121129-proto-socket-performance-quick.md`
```

### 수정 파일 요약
```
CODE_REVIEW-local-G08.md | 78 +++++++++++++++-----------
WsClient.kt              |  3 +-
WsServer.kt              |  7 +++
WsTest.kt                | 36 +++++++++++
4 files changed, 102 insertions(+), 22 deletions(-)
```

---

> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.

## 코드리뷰 결과

- 종합 판정: PASS
- 차원별 평가:
  - correctness: Pass
  - completeness: Pass
  - test coverage: Pass
  - API contract: Pass
  - code quality: Pass
  - plan deviation: Pass
  - verification trust: Pass
- 발견된 문제: 없음
- 다음 단계: PASS이므로 active plan/review를 `.log`로 아카이브하고 `complete.log` 작성 후 task directory를 archive로 이동한다.
