<!-- task=ts_kotlin_wss_crosstest plan=0 tag=TEST -->

# Code Review Reference - TEST

## 개요

date=2026-04-27
task=ts_kotlin_wss_crosstest, plan=0, tag=TEST

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

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.

1. `CODE_REVIEW.md` → `code_review_N.log` (N = 기존 code_review_*.log 수)
2. `PLAN.md` → `plan_M.log` (M = 기존 plan_*.log 수)
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [TEST-1] typescript_kotlin.ts에 WSS 페이즈 추가 | [x] |

## 계획 대비 변경 사항

없음. 계획서의 지정 범위(`typescript/crosstest/typescript_kotlin.ts`) 안에서만 구현했다.

## 주요 설계 결정

- Kotlin 클라이언트가 이미 지원하는 `wss` 모드를 TypeScript 서버 오케스트레이터에 연결했다.
- WSS 서버는 기존 WS 서버 생성 패턴에 `serverTlsOptions()`를 5번째 인자로 전달하는 방식으로 구성했다.
- WSS 포트는 계획서에 명시된 `29816`을 사용했다.

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

- `typescript/crosstest/typescript_kotlin.ts` 29줄 다음에 `WSS_PORT = 29816` 상수가 추가됐는지 확인
- `main()`에서 `runTls()` 다음에 `sleep(150)` + `runWss()` 호출이 순서대로 있는지 확인
- `runWss()`, `runWssSendPush()`, `runWssRequests()` 세 함수가 모두 추가됐는지 확인
- `runWssSendPush()`에서 `serverTlsOptions()`를 `WsServer` 생성자 5번째 인자로 전달하는지 확인
- `runKotlinClient("wss", WSS_PORT, ...)` 호출 시 `CERT_PATH`가 인자로 전달되는지 확인
- `kotlin/crosstest/typescript_kotlin_client.kt`는 변경하지 않았는지 확인 (이미 wss 지원)

## 검증 결과

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

### TEST-1 중간 검증
```
$ cd typescript && npx tsc --noEmit
```

출력 없음. 종료 코드 0.

### 최종 검증
```
$ cd typescript && npx tsx crosstest/typescript_kotlin.ts
INFO typeName ts=TestData
Starting a Gradle Daemon, 1 busy and 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :extractIncludeProto UP-TO-DATE
> Task :extractProto UP-TO-DATE
> Task :generateProto UP-TO-DATE
> Task :compileKotlin UP-TO-DATE
> Task :compileJava
> Task :processResources UP-TO-DATE
> Task :classes
> Task :extractCrosstestProto UP-TO-DATE
> Task :extractIncludeCrosstestProto UP-TO-DATE
> Task :generateCrosstestProto NO-SOURCE
> Task :compileCrosstestKotlin UP-TO-DATE
> Task :compileCrosstestJava NO-SOURCE
> Task :processCrosstestResources NO-SOURCE
> Task :crosstestClasses UP-TO-DATE
SERVER_RECEIVED index=101 message=fire from kotlin client

> Task :run
INFO typeName kotlin=TestData
PASS scenario=1 detail=fire-and-forget sent
PASS scenario=2 detail=received push from typescript server

BUILD SUCCESSFUL in 7s
10 actionable tasks: 2 executed, 8 up-to-date
> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :extractIncludeProto UP-TO-DATE
> Task :extractProto UP-TO-DATE
> Task :generateProto UP-TO-DATE
> Task :compileKotlin UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :extractCrosstestProto UP-TO-DATE
> Task :extractIncludeCrosstestProto UP-TO-DATE
> Task :generateCrosstestProto NO-SOURCE
> Task :compileCrosstestKotlin UP-TO-DATE
> Task :compileCrosstestJava NO-SOURCE
> Task :processCrosstestResources NO-SOURCE
> Task :crosstestClasses UP-TO-DATE

> Task :run
INFO typeName kotlin=TestData
PASS scenario=3 detail=single request response matched
PASS scenario=4 detail=concurrent request responses matched

BUILD SUCCESSFUL in 1s
10 actionable tasks: 1 executed, 9 up-to-date
> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :extractIncludeProto UP-TO-DATE
> Task :extractProto UP-TO-DATE
> Task :generateProto UP-TO-DATE
> Task :compileKotlin UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :extractCrosstestProto UP-TO-DATE
> Task :extractIncludeCrosstestProto UP-TO-DATE
> Task :generateCrosstestProto NO-SOURCE
> Task :compileCrosstestKotlin UP-TO-DATE
> Task :compileCrosstestJava NO-SOURCE
> Task :processCrosstestResources NO-SOURCE
> Task :crosstestClasses UP-TO-DATE
SERVER_RECEIVED index=101 message=fire from kotlin client

> Task :run
INFO typeName kotlin=TestData
PASS scenario=1 detail=fire-and-forget sent
PASS scenario=2 detail=received push from typescript server

BUILD SUCCESSFUL in 1s
10 actionable tasks: 1 executed, 9 up-to-date
> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :extractIncludeProto UP-TO-DATE
> Task :extractProto UP-TO-DATE
> Task :generateProto UP-TO-DATE
> Task :compileKotlin UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :extractCrosstestProto UP-TO-DATE
> Task :extractIncludeCrosstestProto UP-TO-DATE
> Task :generateCrosstestProto NO-SOURCE
> Task :compileCrosstestKotlin UP-TO-DATE
> Task :compileCrosstestJava NO-SOURCE
> Task :processCrosstestResources NO-SOURCE
> Task :crosstestClasses UP-TO-DATE

> Task :run
INFO typeName kotlin=TestData
PASS scenario=3 detail=single request response matched
PASS scenario=4 detail=concurrent request responses matched

BUILD SUCCESSFUL in 1s
10 actionable tasks: 1 executed, 9 up-to-date
> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :extractIncludeProto UP-TO-DATE
> Task :extractProto UP-TO-DATE
> Task :generateProto UP-TO-DATE
> Task :compileKotlin UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :extractCrosstestProto UP-TO-DATE
> Task :extractIncludeCrosstestProto UP-TO-DATE
> Task :generateCrosstestProto NO-SOURCE
> Task :compileCrosstestKotlin UP-TO-DATE
> Task :compileCrosstestJava NO-SOURCE
> Task :processCrosstestResources NO-SOURCE
> Task :crosstestClasses UP-TO-DATE
SERVER_RECEIVED index=101 message=fire from kotlin client

> Task :run
INFO typeName kotlin=TestData
PASS scenario=1 detail=fire-and-forget sent
PASS scenario=2 detail=received push from typescript server

BUILD SUCCESSFUL in 1s
10 actionable tasks: 1 executed, 9 up-to-date
> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :extractIncludeProto UP-TO-DATE
> Task :extractProto UP-TO-DATE
> Task :generateProto UP-TO-DATE
> Task :compileKotlin UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :extractCrosstestProto UP-TO-DATE
> Task :extractIncludeCrosstestProto UP-TO-DATE
> Task :generateCrosstestProto NO-SOURCE
> Task :compileCrosstestKotlin UP-TO-DATE
> Task :compileCrosstestJava NO-SOURCE
> Task :processCrosstestResources NO-SOURCE
> Task :crosstestClasses UP-TO-DATE

> Task :run
INFO typeName kotlin=TestData
PASS scenario=3 detail=single request response matched
PASS scenario=4 detail=concurrent request responses matched

BUILD SUCCESSFUL in 1s
10 actionable tasks: 1 executed, 9 up-to-date
> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :extractIncludeProto UP-TO-DATE
> Task :extractProto UP-TO-DATE
> Task :generateProto UP-TO-DATE
> Task :compileKotlin UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :extractCrosstestProto UP-TO-DATE
> Task :extractIncludeCrosstestProto UP-TO-DATE
> Task :generateCrosstestProto NO-SOURCE
> Task :compileCrosstestKotlin UP-TO-DATE
> Task :compileCrosstestJava NO-SOURCE
> Task :processCrosstestResources NO-SOURCE
> Task :crosstestClasses UP-TO-DATE
SERVER_RECEIVED index=101 message=fire from kotlin client

> Task :run
INFO typeName kotlin=TestData
PASS scenario=1 detail=fire-and-forget sent
PASS scenario=2 detail=received push from typescript server

BUILD SUCCESSFUL in 1s
10 actionable tasks: 1 executed, 9 up-to-date
> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :extractIncludeProto UP-TO-DATE
> Task :extractProto UP-TO-DATE
> Task :generateProto UP-TO-DATE
> Task :compileKotlin UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :extractCrosstestProto UP-TO-DATE
> Task :extractIncludeCrosstestProto UP-TO-DATE
> Task :generateCrosstestProto NO-SOURCE
> Task :compileCrosstestKotlin UP-TO-DATE
> Task :compileCrosstestJava NO-SOURCE
> Task :processCrosstestResources NO-SOURCE
> Task :crosstestClasses UP-TO-DATE

> Task :run
INFO typeName kotlin=TestData
PASS scenario=3 detail=single request response matched
PASS scenario=4 detail=concurrent request responses matched

BUILD SUCCESSFUL in 1s
10 actionable tasks: 1 executed, 9 up-to-date
PASS all typescript-server/kotlin-client crosstests passed
```
