<!-- task=m-large-payload-followup-optimization/04_ws_fixed_latency plan=0 tag=PERF -->

# WS Fixed Latency Path Plan

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

이 plan의 구현 완료 조건에는 대응 `CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션 작성이 포함된다. 구현 후 검증 명령을 실행하고 실제 출력, 계획 대비 변경, 주요 설계 결정을 채운 뒤 active 파일을 그대로 둔 채 리뷰 준비를 보고한다. 사용자만 결정할 수 있는 범위 변경, 외부 환경/secret/서비스 준비, 또는 구현을 안전하게 계속할 수 없는 충돌이 있으면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 근거를 기록하고 중단한다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 재실행으로 닫을 수 있는 검증 증거 공백은 사용자 리뷰 요청이 아니다.

## 배경

현 마일스톤의 `[ws-fixed-latency-path]`는 WS 계열 roundtrip에서 약 40ms 고정 latency가 반복되는 경로를 common/worker/gateway보다 더 아래 transport까지 분해해야 한다. 최근 TypeScript gateway transport row는 gateway off/on 모두 p50 약 41ms였고, worker_threads row는 p99가 200ms 이상으로 별도 tail을 보였다. 단일 코드 변경으로 단정하기 어렵기 때문에 계측과 낮은 위험의 transport 설정 보강을 한 plan에 묶는다.

## 사용자 리뷰 요청 흐름

구현 중 사용자 결정이 필요한 경우 active `CODE_REVIEW-cloud-G07.md`의 `사용자 리뷰 요청` 섹션에 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 형식으로 기록한다. 구현 에이전트는 직접 사용자 프롬프트를 만들지 않으며, code-review가 해당 요청을 검증하고 실제 `USER_REVIEW.md` 작성 여부를 판단한다.

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/large-payload-followup-optimization.md`
- Task ids:
  - `ws-fixed-latency-path`: WS 계열 fixed latency가 지속되면 common/worker/gateway 경로 분석
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/project/domain/kotlin/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-roadmap/current.md`
- `agent-roadmap/milestones/large-payload-followup-optimization.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-test/local/rules.md`
- `agent-test/local/proto-socket-performance-baseline.md`
- `agent-test/runs/20260613-141506-proto-socket-performance-full.md`
- `agent-test/runs/20260613-202744-proto-socket-stress-full.md`
- `typescript/src/tcp_client.ts`
- `typescript/src/node_ws_client.ts`
- `typescript/src/node_ws_server.ts`
- `typescript/src/inbound_gateway.ts`
- `typescript/src/node_inbound_gateway.ts`
- `typescript/bench/stress.ts`
- `typescript/test/tcp.test.ts`
- `typescript/test/ws.test.ts`
- `typescript/test/communicator.test.ts`
- `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt`
- `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsServer.kt`
- `kotlin/src/test/kotlin/com/tokilabs/proto_socket/WsTest.kt`
- `kotlin/src/test/kotlin/com/tokilabs/proto_socket/TestHelpers.kt`
- `kotlin/crosstest/stress.kt`

### 테스트 환경 규칙

- `test_env=local`; performance baseline profile을 읽었다.
- fixed latency는 절대 latency hard gate가 아니라 분석 task이므로 quick/full stress row와 gateway transport row를 증거로 삼는다.
- layout 확인: TypeScript/Kotlin manifests, `run_stress.sh`, `run_performance.sh`, `npm`, `kotlin/gradlew`, `bash` 존재 확인.

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

- 기존 unit tests는 correctness 중심이고 socket `noDelay`나 phase별 latency를 검증하지 않는다.
- `typescript/bench/stress.ts` gateway profile은 gateway off/on/worker_threads를 비교하지만 transport write, frame parse, handler, response write phase를 분리하지 않는다.
- Kotlin WS metrics는 copy/staging counters가 있으나 stress output의 fixed latency 원인 분해에는 충분하지 않다.

### 심볼 참조

- renamed/removed symbol: none.

### 분할 판단

- shared task group: `agent-task/m-large-payload-followup-optimization/`.
- sibling split은 `01_typescript_ws_1mb`, `02_typescript_tcp_tail`, `03_kotlin_tcp_parallel`, `04_ws_fixed_latency`, `05_dart_large_packet_guard`이며 모두 독립이다.
- 이 작업은 cross-domain WS/TCP latency 진단이므로 별도 cloud plan으로 분리했다. 다른 sibling의 성능 수치를 바꾸더라도 dependency로 묶지 않는다.

### 범위 결정 근거

- 프로토콜 schema, payload 1MB 최적화, Kotlin TCP required skip은 제외한다.
- 고정 latency를 환경별 절대 threshold로 fail 처리하지 않는다. 이 plan의 목표는 원인 분해와 낮은 위험 완화다.

### 빌드 등급

- `cloud-G07`: 여러 런타임과 terminal benchmark evidence가 필요하고 고정 40ms latency는 환경/transport 상호작용 가능성이 높다.

## 구현 체크리스트

- [ ] [PERF-1] TypeScript/Kotlin WS/TCP socket 경로의 low-latency 설정과 phase 계측을 추가해 gateway off/on과 transport latency를 분리한다.
- [ ] [PERF-2] fixed latency 재현 stress를 실행하고 개선 여부와 남은 병목 후보를 review stub에 수치로 기록한다.
- [ ] TypeScript gateway/WS roundtrip 및 Kotlin WS quick stress를 실행해 correctness와 stability hard gate가 유지되는지 확인한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [PERF-1] low-latency 설정 및 phase 계측

문제: TypeScript `TcpClient`와 custom `NodeWebSocket` 경로에는 명시적 `setNoDelay(true)`가 보이지 않는다(`typescript/src/tcp_client.ts:15-23`, `typescript/src/node_ws_client.ts:166-185`). Kotlin server WS는 `tcpNoDelay`를 켜지만(`kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsServer.kt:50-52`), OkHttp client socket은 별도 설정이 없다.

해결 방법:

```ts
// before: typescript/src/node_ws_client.ts:166
constructor(private readonly socket: NodeSocket, ...)
```

```ts
// after: shape
constructor(private readonly socket: NodeSocket, ...) {
  this.socket.setNoDelay?.(true);
  ...
}
```

```kotlin
// before: kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt:250
val builder = OkHttpClient.Builder()
```

```kotlin
// after: shape
val builder = OkHttpClient.Builder()
    .socketFactory(NoDelaySocketFactory)
```

- TypeScript TCP/WS sockets에 no-delay를 명시한다.
- Kotlin OkHttp WS client에 plain socket no-delay 설정을 추가한다. TLS 경로는 SSL socket factory와 충돌하지 않게 별도 검토한다.
- stress/gateway output에는 phase를 늘리기보다 stderr diagnostic으로 `transport=tcp/ws`, gateway mode, p50/p99 key row를 추적 가능하게 한다.

수정 파일 및 체크리스트:

- [ ] `typescript/src/tcp_client.ts`: socket low-latency 설정 추가.
- [ ] `typescript/src/node_ws_client.ts`: custom WS socket low-latency 설정 추가.
- [ ] `typescript/src/node_ws_server.ts`: upgrade socket low-latency 설정 확인/추가.
- [ ] `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt`: OkHttp plain WS socket no-delay 설정 추가.
- [ ] `kotlin/src/test/kotlin/com/tokilabs/proto_socket/WsTest.kt`: WS correctness 회귀 유지.

테스트 작성: unit에서 OS socket option을 직접 assert하기 어렵다. 대신 연결/roundtrip/close 회귀 테스트를 실행하고, 필요 시 TypeScript에서는 fake socket으로 `setNoDelay(true)` 호출 여부를 테스트한다.

중간 검증:

```bash
cd typescript && npm test -- test/tcp.test.ts test/ws.test.ts
cd kotlin && ./gradlew --offline test --tests com.tokilabs.proto_socket.WsTest
```

예상 결과: exit 0, TCP/WS correctness PASS.

### [PERF-2] fixed latency row 수집

문제: `agent-test/runs/20260613-202744-proto-socket-stress-full.md`의 TypeScript gateway transport row는 gateway off/on 모두 p50 약 41ms로 gateway 여부와 무관한 fixed latency를 보인다. 개선 여부는 같은 profile row 재실행으로만 판단 가능하다.

해결 방법:

```ts
// before: typescript/bench/stress.ts gateway/roundtrip rows only record aggregate p50/p99
```

```ts
// after: keep ROW schema stable; add deterministic stderr diagnostics or review extraction
```

- ROW schema는 기존 performance parser와 호환되게 유지한다.
- review stub에 다음 rows를 붙인다: TypeScript `roundtrip/ws concurrency=1`, `gateway transport/ws gateway=off`, `gateway transport/ws gateway=on`, Kotlin `roundtrip/ws concurrency=1`.
- 수치가 개선되지 않으면 남은 병목 후보를 `계획 대비 변경 사항`이 아니라 `주요 설계 결정`에 기록한다.

수정 파일 및 체크리스트:

- [ ] `typescript/bench/stress.ts`: 필요 시 deterministic diagnostic log 추가.
- [ ] `kotlin/crosstest/stress.kt`: 필요 시 Kotlin WS row 식별 log 추가.

테스트 작성: 별도 unit test 없음. 성능 row가 검증이다.

중간 검증:

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

예상 결과: 두 명령 모두 target rows PASS. TypeScript gateway off/on p50/p99와 Kotlin WS roundtrip row가 review stub에 기록된다.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `typescript/src/tcp_client.ts` | PERF-1 |
| `typescript/src/node_ws_client.ts` | PERF-1 |
| `typescript/src/node_ws_server.ts` | PERF-1 |
| `typescript/bench/stress.ts` | PERF-2 |
| `kotlin/src/main/kotlin/com/tokilabs/proto_socket/WsClient.kt` | PERF-1 |
| `kotlin/src/test/kotlin/com/tokilabs/proto_socket/WsTest.kt` | PERF-1 |
| `kotlin/crosstest/stress.kt` | PERF-2 |

## 최종 검증

```bash
cd typescript && npm run check
cd typescript && npm test -- test/tcp.test.ts test/ws.test.ts
cd kotlin && ./gradlew --offline test --tests com.tokilabs.proto_socket.WsTest
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh --quick --lang typescript,kotlin --transport ws --profile roundtrip
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh --quick --lang typescript --transport ws --profile gateway
```

예상 결과: unit/check 명령 exit 0. stress rows는 target rows PASS, stability counter 0. fixed latency가 남으면 남은 후보와 row 수치를 review stub에 명시한다.

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