<!-- task=tls_crosstest plan=0 tag=TLS_CROSSTEST -->

# TLS 크로스테스트 전 언어 확장

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

각 항목의 체크리스트를 완료 표시하고, 중간 검증 명령을 실행한 뒤 출력을 CODE_REVIEW.md `검증 결과` 섹션에 붙여 넣는다. 최종 검증까지 완료 후 CODE_REVIEW.md 각 항목을 `[x]`로 체크한다. **의존 관계 및 구현 순서** 섹션을 반드시 지킨다.

## 배경

`dart_go`·`go_dart` 두 조합에만 TLS TCP + WSS 크로스테스트가 존재한다. Python·TypeScript·Kotlin에 TLS 구현이 추가됨에 따라 나머지 18개 쌍에도 TLS 검증이 가능해졌다. 이번 작업으로 서버·클라이언트 양쪽 모두 TLS를 지원하는 모든 조합에 TLS 크로스테스트 phase를 추가한다.

**기준 파일:** `dart/crosstest/dart_go.dart` (orchestrator), `go/crosstest/dart_go_client/main.go` (client)

**인증서 경로 규칙:** 각 언어의 `test/certs/server.crt` + `server.key` 를 사용한다 (모두 `dart/test/certs/` 원본의 사본). orchestrator는 자신의 언어 경로로 서버 cert를 로드하고 `--cert=<path>` 로 클라이언트에 전달한다.

---

## 포트 배정표

| orchestrator | TCP | WS | TLS TCP (신규) | WSS (신규) |
|---|---|---|---|---|
| dart_kotlin | 29590 | 29592 | **29594** | **29596** |
| dart_python | 29694 | 29696 | **29698** | **29700** |
| dart_typescript | 29790 | 29792 | **29794** | **29796** |
| go_kotlin | 29290 | 29292 | **29294** | **29296** |
| go_python | 29390 | 29392 | **29394** | **29396** |
| go_typescript | 29490 | 29492 | **29494** | **29496** |
| kotlin_dart | 29490 | 29492 | **29494** | **29496** |
| kotlin_go | 29390 | 29392 | **29394** | **29396** |
| kotlin_python | 29394 | 29396 | **29398** | **29400** |
| kotlin_typescript | 29794 | 29796 | **29798** | **29800** |
| python_dart | 29494 | 29496 | **29498** | **29500** |
| python_go | 29490 | 29492 | **29494** | **29496** |
| python_kotlin | 29498 | 29500 | **29502** | **29504** |
| python_typescript | 29798 | 29800 | **29802** | **29804** |
| typescript_dart | 29802 | 29804 | **29806** | **29808** |
| typescript_go | 29806 | 29808 | **29810** | **29812** |
| typescript_kotlin | 29810 | 29812 | **29814** | — |
| typescript_python | 29814 | 29816 | **29818** | **29820** |

---

## [TLS_CROSSTEST-1] Dart 클라이언트 파일 — TLS 모드 추가

### 문제

`dart/crosstest/kotlin_dart_client.dart`, `dart/crosstest/python_dart_client.dart`, `dart/crosstest/typescript_dart_client.dart` 3개 파일이 `--mode=tls/wss`, `--cert` 인수를 처리하지 않는다.

### 해결 방법

`dart/crosstest/go_dart_client.dart` 패턴을 참조한다. 각 파일에서:

1. `args`에서 `--cert` 인수 파싱 추가
2. `_connectWithRetry` 또는 동등 함수의 `switch (mode)` 블록에 `'tls'`·`'wss'` 케이스 추가:
   ```dart
   case 'tls':
     final ctx = SecurityContext()..setTrustedCertificates(certPath!);
     final socket = await ProtobufClient.connectSecure(_host, port, context: ctx);
     return _ClientHandle(/* TCP client */, () async => /* close */);
   case 'wss':
     final ctx = SecurityContext()..setTrustedCertificates(certPath!);
     final ws = await WsProtobufClient.connectSecure(_host, port, context: ctx);
     return _ClientHandle(/* WS client */, () async => /* close */);
   ```
3. 각 파일에서 push 메시지 검증 문자열이 맞는지 확인:
   - `kotlin_dart_client`: `'push from kotlin server'`
   - `python_dart_client`: `'push from python server'`
   - `typescript_dart_client`: `'push from typescript server'`

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

- `dart/crosstest/kotlin_dart_client.dart`
  - [x] `--cert` 파라미터 파싱 추가
  - [x] `'tls'`·`'wss'` 모드 케이스 추가
- `dart/crosstest/python_dart_client.dart`
  - [x] `--cert` 파라미터 파싱 추가
  - [x] `'tls'`·`'wss'` 모드 케이스 추가
- `dart/crosstest/typescript_dart_client.dart`
  - [x] `--cert` 파라미터 파싱 추가
  - [x] `'tls'`·`'wss'` 모드 케이스 추가

### 테스트 작성

단독 실행 테스트 없음. TLS_CROSSTEST-8~10의 orchestrator 검증으로 확인.

### 중간 검증

```
$ cd dart && dart analyze crosstest/kotlin_dart_client.dart crosstest/python_dart_client.dart crosstest/typescript_dart_client.dart
No issues found!
```

---

## [TLS_CROSSTEST-2] Go 클라이언트 파일 — TLS 모드 추가

### 문제

`go/crosstest/kotlin_go_client/main.go`, `go/crosstest/python_go_client/main.go`, `go/crosstest/typescript_go_client/main.go` 3개 파일이 `--mode=tls/wss`, `--cert` 를 처리하지 않는다.

### 해결 방법

`go/crosstest/dart_go_client/main.go` 패턴을 참조한다. 각 파일에서:

1. `flag.String("cert", "", ...)` 플래그 추가
2. `dial()` 함수의 `switch mode` 블록에 `"tls"`·`"wss"` 케이스 추가:
   ```go
   case "tls":
     tlsCfg, err := buildClientTLS(*cert)
     client, err = toki.DialTcpTLS(ctx, host, port, tlsCfg, 0, 0, parserMap())
   case "wss":
     tlsCfg, err := buildClientTLS(*cert)
     client, err = toki.DialWssWithHeartbeat(ctx, host, port, wsPath, tlsCfg, 0, 0, parserMap())
   ```
3. `buildClientTLS(certFile string)` 헬퍼를 `dart_go_client/main.go`에서 복사 추가
4. 각 파일 push 메시지 검증 문자열 확인:
   - `kotlin_go_client`: `"push from kotlin server"`
   - `python_go_client`: `"push from python server"`
   - `typescript_go_client`: `"push from typescript server"`

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

- `go/crosstest/kotlin_go_client/main.go`
  - [x] `--cert` 플래그 추가
  - [x] `"tls"`·`"wss"` 케이스 및 `buildClientTLS` 헬퍼 추가
- `go/crosstest/python_go_client/main.go`
  - [x] 동일
- `go/crosstest/typescript_go_client/main.go`
  - [x] 동일

### 테스트 작성

없음. TLS_CROSSTEST-7~9의 orchestrator 검증으로 확인.

### 중간 검증

```
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
  go build ./crosstest/kotlin_go_client ./crosstest/python_go_client ./crosstest/typescript_go_client
(exit 0)
```

---

## [TLS_CROSSTEST-3] Kotlin 클라이언트 파일 — TLS 모드 추가

### 문제

`kotlin/crosstest/dart_kotlin_client.kt`, `go_kotlin_client/Main.kt`, `python_kotlin_client.kt`, `typescript_kotlin_client.kt` 4개 파일이 `--mode=tls/wss`, `--cert` 를 처리하지 않는다.

### 해결 방법

각 파일에서:

1. `argValue(args, "cert")` 파싱 추가
2. `connectWithRetry(mode, port, cert)` 시그니처에 `cert: String?` 추가
3. `when (mode)` 블록에 `"tls"`·`"wss"` 케이스 추가:
   ```kotlin
   "tls" -> {
     val sslCtx = buildClientSslContext(cert ?: error("--cert required for tls"))
     DialTcpTls(HOST, port, sslCtx, 0, 0, parserMap)
   }
   "wss" -> {
     val sslCtx = buildClientSslContext(cert ?: error("--cert required for wss"))
     dialWss(HOST, port, WS_PATH, sslCtx, 0, 0, parserMap)
   }
   ```
4. `buildClientSslContext(certPath: String): SSLContext` 헬퍼 추가 — PEM cert를 `TrustStore`에 로드 (구현은 `tls_support` 과제에서 도입한 TestHelpers.kt 패턴 참조):
   ```kotlin
   fun buildClientSslContext(certPath: String): SSLContext {
       val certFactory = java.security.cert.CertificateFactory.getInstance("X.509")
       val cert = java.io.File(certPath).inputStream().use {
           certFactory.generateCertificate(it) as java.security.cert.X509Certificate
       }
       val ts = java.security.KeyStore.getInstance("PKCS12")
       ts.load(null, null)
       ts.setCertificateEntry("toki", cert)
       val tmf = javax.net.ssl.TrustManagerFactory.getInstance(
           javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm()
       )
       tmf.init(ts)
       val ctx = javax.net.ssl.SSLContext.getInstance("TLS")
       ctx.init(null, tmf.trustManagers, null)
       return ctx
   }
   ```
5. 각 파일 push 메시지 검증 문자열 확인 (`'push from dart/go/python/typescript server'`).

**참고:** `go_kotlin_client`는 Gradle 서브프로젝트 (`kotlin/crosstest/go_kotlin_client/`). 나머지 세 파일은 독립 `.kt` 파일.

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

- `kotlin/crosstest/dart_kotlin_client.kt`
  - [x] `--cert` 파싱, `"tls"`·`"wss"` 케이스, `buildClientSslContext` 추가
- `kotlin/crosstest/go_kotlin_client/src/main/kotlin/com/tokilabs/toki_socket/crosstest/Main.kt`
  - [x] 동일
- `kotlin/crosstest/python_kotlin_client.kt`
  - [x] 동일
- `kotlin/crosstest/typescript_kotlin_client.kt`
  - [x] 동일

### 테스트 작성

없음. TLS_CROSSTEST-6~10의 orchestrator 검증으로 확인.

### 중간 검증

```
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
  ./gradlew compileCrosstestKotlin
BUILD SUCCESSFUL
```

---

## [TLS_CROSSTEST-4] Python 클라이언트 파일 — TLS 모드 추가

### 문제

`python/crosstest/dart_python_client.py`, `go_python_client.py`, `kotlin_python_client.py`, `typescript_python_client.py` 4개 파일이 TLS 모드를 처리하지 않는다.

### 해결 방법

각 파일에서:

1. `argparse`에 `--cert` 인수 추가 (`default=None`)
2. `choices=["tcp", "ws"]` → `["tcp", "ws", "tls", "wss"]` 변경
3. `dial()` 함수에 `"tls"`·`"wss"` 케이스 추가:
   ```python
   elif mode == "tls":
       ssl_ctx = ssl.create_default_context(cafile=cert)
       ssl_ctx.check_hostname = False
       return await connect_tcp_tls(HOST, port, ssl_ctx, 0, 0, parser_map())
   elif mode == "wss":
       ssl_ctx = ssl.create_default_context(cafile=cert)
       ssl_ctx.check_hostname = False
       return await connect_wss(HOST, port, WS_PATH, ssl_ctx, 0, 0, parser_map())
   ```
4. `import ssl`, `connect_tcp_tls`, `connect_wss` import 추가

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

- `python/crosstest/dart_python_client.py`
  - [x] `import ssl`, `connect_tcp_tls`, `connect_wss` 추가
  - [x] `--cert` argparse 인수 추가, choices 확장
  - [x] `"tls"`·`"wss"` 분기 추가
- `python/crosstest/go_python_client.py`
  - [x] 동일
- `python/crosstest/kotlin_python_client.py`
  - [x] 동일
- `python/crosstest/typescript_python_client.py`
  - [x] 동일

### 중간 검증

```
$ python3 -m py_compile python/crosstest/dart_python_client.py \
  python/crosstest/go_python_client.py \
  python/crosstest/kotlin_python_client.py \
  python/crosstest/typescript_python_client.py
(exit 0)
```

---

## [TLS_CROSSTEST-5] TypeScript 클라이언트 파일 — TLS 모드 추가

### 문제

`typescript/crosstest/dart_typescript_client.ts`, `go_typescript_client.ts`, `kotlin_typescript_client.ts`, `python_typescript_client.ts` 4개 파일이 TLS 모드를 처리하지 않는다.

### 해결 방법

각 파일에서:

1. `parseArgs()` 내 `mode` 타입을 `"tcp" | "ws" | "tls" | "wss"` 로 확장
2. `--cert` 인수 파싱 추가
3. `dialWithRetry` / `dial()` 에 `cert?: string` 파라미터 추가
4. `dial()` switch 에 `"tls"`·`"wss"` 케이스 추가:
   ```typescript
   case "tls": {
     const ca = fs.readFileSync(cert!);
     return connectTcpTls(HOST, port, { ca }, 0, 0, parserMap());
   }
   case "wss": {
     const ca = fs.readFileSync(cert!);
     return connectWss(HOST, port, WS_PATH, { ca }, 0, 0, parserMap());
   }
   ```
5. `import * as fs from "node:fs"`, `connectTcpTls`, `connectWss` import 추가

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

- `typescript/crosstest/dart_typescript_client.ts`
  - [x] `fs`, `connectTcpTls`, `connectWss` import 추가
  - [x] `--cert` 파싱, mode 타입 확장, `dial()` 케이스 추가
- `typescript/crosstest/go_typescript_client.ts`
  - [x] 동일
- `typescript/crosstest/kotlin_typescript_client.ts`
  - [x] 동일
- `typescript/crosstest/python_typescript_client.ts`
  - [x] 동일

### 중간 검증

```
$ cd typescript && npx tsc --noEmit
(exit 0)
```

---

## [TLS_CROSSTEST-6] Dart orchestrator 3개 — TLS phase 추가

### 문제

`dart/crosstest/dart_kotlin.dart`, `dart/crosstest/dart_python.dart`, `dart/crosstest/dart_typescript.dart` 에 TLS phase가 없다.

### 해결 방법

`dart/crosstest/dart_go.dart` 패턴을 참조한다. 각 파일에서:

1. TLS/WSS 포트 상수 추가:
   - `dart_kotlin`: `_tlsTcpPort = 29594`, `_wssPort = 29596`
   - `dart_python`: `_tlsTcpPort = 29698`, `_wssPort = 29700`
   - `dart_typescript`: `_tlsTcpPort = 29794`, `_wssPort = 29796`
2. `_DartTlsTcpServer`, `_DartWssServer` 클래스 추가 (dart_go.dart 와 동일 구조)
3. `_runTls()` 메서드 추가 — TLS TCP send-push, TLS TCP requests, WSS send-push, WSS requests 4개 phase
4. `main()`에서 `await _runTls()` 호출 추가
5. 각 파일의 클라이언트 실행 헬퍼에서 `--cert=<path>` 전달:
   - `dart_kotlin`: Kotlin 클라이언트 `./gradlew run` 호출 시 `-PappArgs="['--mode=tls','--port=29594','--cert=...']"` 형식
   - `dart_python`: Python subprocess 호출 시 `--mode tls --port 29698 --cert <path>` 추가
   - `dart_typescript`: `node --import tsx` 호출 시 `--mode=tls --port=29794 --cert=<path>` 추가
6. 인증서 경로: `dart/test/certs/server.crt`, `dart/test/certs/server.key` (이미 각 파일의 repo root에서 계산 가능)

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

- `dart/crosstest/dart_kotlin.dart`
  - [x] TLS/WSS 포트 상수 추가 (29594, 29596)
  - [x] `_DartTlsTcpServer`, `_DartWssServer` 클래스 추가
  - [x] `_runTls()` 메서드 추가 (4 phase)
  - [x] `main()`에서 `_runTls()` 호출 추가
  - [x] Kotlin 클라이언트 호출에 TLS 인수 전달
- `dart/crosstest/dart_python.dart`
  - [x] 동일 (포트 29698, 29700)
- `dart/crosstest/dart_typescript.dart`
  - [x] 동일 (포트 29794, 29796)

### 중간 검증

```
$ cd dart && dart analyze crosstest/dart_kotlin.dart crosstest/dart_python.dart crosstest/dart_typescript.dart
No issues found!

$ cd dart && dart run crosstest/dart_python.dart
PASS all dart-server/python-client crosstests passed

$ cd dart && dart run crosstest/dart_typescript.dart
PASS all dart-server/typescript-client crosstests passed

$ cd dart && dart run crosstest/dart_kotlin.dart
PASS all dart-server/kotlin-client crosstests passed
```

---

## [TLS_CROSSTEST-7] Go orchestrator 3개 — TLS phase 추가

### 문제

`go/crosstest/go_kotlin.go`, `go/crosstest/go_python.go`, `go/crosstest/go_typescript.go` 에 TLS phase가 없다.

### 해결 방법

`go/crosstest/go_dart.go` 패턴 참조. 각 파일에서:

1. TLS/WSS 포트 상수 추가:
   - `go_kotlin`: `goKotlinTLSPort = 29294`, `goKotlinWSSPort = 29296`
   - `go_python`: `goPythonTLSPort = 29394`, `goPythonWSSPort = 29396`
   - `go_typescript`: `goTypescriptTLSPort = 29494`, `goTypescriptWSSPort = 29496`
2. `crypto/tls` import 추가 (미존재 시)
3. `loadServerTLS(certFile, keyFile)` 헬퍼 추가 (go_dart.go 에서 복사)
4. `runTLSTCPSendPush`, `runTLSTCPRequests`, `runWSSendPushSecure`, `runWSSRequestsSecure` 추가
5. `run()` 에서 TLS phase 호출 추가
6. 인증서: `go_dart.go`와 동일하게 `dartDir`의 `test/certs/` 에서 로드

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

- `go/crosstest/go_kotlin.go`
  - [x] TLS 포트 상수 (29294, 29296), `loadServerTLS`, TLS phase 함수 4개 추가
  - [x] `run()`에서 호출 추가
- `go/crosstest/go_python.go`
  - [x] 동일 (포트 29394, 29396)
- `go/crosstest/go_typescript.go`
  - [x] 동일 (포트 29494, 29496)

### 중간 검증

```
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
  go run ./crosstest/go_python.go
PASS all go-server/python-client crosstests passed

$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
  go run ./crosstest/go_typescript.go
PASS all go-server/typescript-client crosstests passed

$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
  go run ./crosstest/go_kotlin.go
PASS all go-server/kotlin-client crosstests passed
```

---

## [TLS_CROSSTEST-8] Kotlin orchestrator 4개 — TLS TCP phase 추가

### 문제

`kotlin_dart.kt`, `kotlin_go.kt`, `kotlin_python.kt`, `kotlin_typescript.kt` 에 TLS phase가 없다. Kotlin `WsServer` TLS는 이번 TLS_CROSSTEST 범위에서 사용하지 않으므로 TLS TCP 2개 phase만 추가한다.

### 해결 방법

각 파일에서:

1. TLS TCP 포트 상수 추가:
   - `kotlin_dart`: TLS TCP `29494`
   - `kotlin_go`: TLS TCP `29394`
   - `kotlin_python`: TLS TCP `29398`
   - `kotlin_typescript`: TLS TCP `29798`
2. 인증서 로딩: `kotlin/src/test/resources/server.crt` + `server.key` 경로를 repo root 기준으로 계산
3. `runTlsTcp(sslContext, certPath)` 함수 추가 — send-push, requests 2 phase
4. Kotlin `WsServer`는 TLS를 지원하지 않으므로 WSS phase는 추가하지 않는다.
5. TLS TCP 서버는 `TcpServer(..., sslContext = serverCtx)` 생성자 사용
6. main 또는 run 함수에서 `runTlsTcp()` 호출 추가

Kotlin 서버 로딩 패턴 (`tls_support` 과제에서 도입한 `createTestSslContexts` 참조):
```kotlin
val repoRoot = File(object {}.javaClass.classLoader.getResource("server.crt")!!.toURI())
    .parentFile.parentFile.parentFile.parentFile.parentFile // navigate to repo root
val certPath = "$repoRoot/kotlin/src/test/resources/server.crt"
val keyPath  = "$repoRoot/kotlin/src/test/resources/server.key"
val serverCtx = createServerSslContext(certPath, keyPath)
```

또는 orchestrator에서 `System.getenv("REPO_ROOT")` 환경변수를 활용하거나, 스크립트 경로로부터 repo root를 계산한다.

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

- `kotlin/crosstest/kotlin_dart.kt`
  - [x] TLS TCP 포트 상수 (29494)
  - [x] 인증서 경로 계산 로직 추가 (`kotlinDir()`)
  - [x] `runTlsTcp()` 함수 추가 (send-push, requests)
  - [x] main에서 `runTlsTcp()` 호출 추가
  - [x] WSS phase 제외 (Kotlin `WsServer` TLS 미지원)
- `kotlin/crosstest/kotlin_go.kt`
  - [x] 동일 (TLS TCP 포트 29394, WSS 제외)
- `kotlin/crosstest/kotlin_python.kt`
  - [x] 동일 (TLS TCP 포트 29398, WSS 제외)
- `kotlin/crosstest/kotlin_typescript.kt`
  - [x] 동일 (TLS TCP 포트 29798, WSS 제외)

### 중간 검증

```
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
  ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinDartKt
PASS all kotlin-server/dart-client crosstests passed

$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
  ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinGoKt
PASS all kotlin-server/go-client crosstests passed
```

---

## [TLS_CROSSTEST-9] Python orchestrator 4개 — TLS phase 추가

### 문제

`python/crosstest/python_dart.py`, `python_go.py`, `python_kotlin.py`, `python_typescript.py` 에 TLS phase가 없다.

### 해결 방법

각 파일에서:

1. TLS/WSS 포트 상수 추가:
   - `python_dart`: `TLS_TCP_PORT = 29498`, `WSS_PORT = 29500`
   - `python_go`: `TLS_TCP_PORT = 29494`, `WSS_PORT = 29496`
   - `python_kotlin`: `TLS_TCP_PORT = 29502`, `WSS_PORT = 29504`
   - `python_typescript`: `TLS_TCP_PORT = 29802`, `WSS_PORT = 29804`
2. `import ssl` 추가
3. `_make_server_ssl_context()` 헬퍼 추가 (python/test/test_tcp.py 패턴 재사용):
   ```python
   def _make_server_ssl_context() -> ssl.SSLContext:
       ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
       ctx.load_cert_chain(CERT_PATH, KEY_PATH)
       return ctx
   ```
4. `CERT_PATH`, `KEY_PATH` 상수: 각 파일 기준 repo root에서 계산
5. `run_tls()` 코루틴 추가 — TLS TCP send-push, TLS TCP requests, WSS send-push, WSS requests
6. `main()` 또는 `run()` 에서 `await run_tls()` 호출 추가
7. `--cert` 로 클라이언트 subprocess에 인증서 경로 전달

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

- `python/crosstest/python_dart.py`
  - [x] TLS/WSS 포트 상수 (29498, 29500), cert 경로, `run_tls()` 추가
- `python/crosstest/python_go.py`
  - [x] 동일 (29494, 29496)
- `python/crosstest/python_kotlin.py`
  - [x] 동일 (29502, 29504)
- `python/crosstest/python_typescript.py`
  - [x] 동일 (29802, 29804)

### 중간 검증

```
$ python3 -m py_compile python/crosstest/python_dart.py python/crosstest/python_go.py \
  python/crosstest/python_kotlin.py python/crosstest/python_typescript.py
(exit 0)

$ cd python && python3 -m crosstest.python_go
PASS all python-server/go-client crosstests passed

$ cd python && python3 -m crosstest.python_typescript
PASS all python-server/typescript-client crosstests passed
```

---

## [TLS_CROSSTEST-10] TypeScript orchestrator 4개 — TLS phase 추가

### 문제

`typescript/crosstest/typescript_dart.ts`, `typescript_go.ts`, `typescript_kotlin.ts`, `typescript_python.ts` 에 TLS phase가 없다.

### 해결 방법

각 파일에서:

1. TLS/WSS 포트 상수 추가:
   - `typescript_dart`: `TLS_TCP_PORT = 29806`, `WSS_PORT = 29808`
   - `typescript_go`: `TLS_TCP_PORT = 29810`, `WSS_PORT = 29812`
   - `typescript_kotlin`: `TLS_TCP_PORT = 29814` (WSS 없음)
   - `typescript_python`: `TLS_TCP_PORT = 29818`, `WSS_PORT = 29820`
2. `import * as fs from "node:fs"` 추가
3. `CERT_PATH`, `KEY_PATH`: `path.resolve(__dirname, "../../typescript/test/certs/server.crt")` 등 repo root 기준 계산
4. `runTls()` 함수 추가 — TLS TCP send-push, TLS TCP requests, (WSS send-push, WSS requests)
   - `typescript_kotlin`: WS 미지원이므로 TLS TCP 2 phase만
5. main 에서 `await runTls()` 호출 추가
6. `TcpServer` 생성 시 `tlsOptions: { cert, key }` 전달
7. `WsServer` 생성 시 `tlsOptions: { cert, key }` 전달 (typescript_kotlin 제외)
8. 클라이언트 subprocess에 `--mode=tls`, `--cert=CERT_PATH` 전달

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

- `typescript/crosstest/typescript_dart.ts`
  - [x] TLS/WSS 포트 상수 (29806, 29808), cert 경로, `runTls()` 추가
- `typescript/crosstest/typescript_go.ts`
  - [x] 동일 (29810, 29812)
- `typescript/crosstest/typescript_kotlin.ts`
  - [x] TLS 포트 상수 (29814), `runTls()` — TLS TCP 2 phase만
- `typescript/crosstest/typescript_python.ts`
  - [x] 동일 (29818, 29820)

### 중간 검증

```
$ cd typescript && npx tsc --noEmit
(exit 0)

$ cd typescript && node --import tsx crosstest/typescript_go.ts
PASS all typescript-server/go-client crosstests passed

$ cd typescript && node --import tsx crosstest/typescript_python.ts
PASS all typescript-server/python-client crosstests passed
```

---

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `dart/crosstest/kotlin_dart_client.dart` | TLS_CROSSTEST-1 |
| `dart/crosstest/python_dart_client.dart` | TLS_CROSSTEST-1 |
| `dart/crosstest/typescript_dart_client.dart` | TLS_CROSSTEST-1 |
| `go/crosstest/kotlin_go_client/main.go` | TLS_CROSSTEST-2 |
| `go/crosstest/python_go_client/main.go` | TLS_CROSSTEST-2 |
| `go/crosstest/typescript_go_client/main.go` | TLS_CROSSTEST-2 |
| `kotlin/crosstest/dart_kotlin_client.kt` | TLS_CROSSTEST-3 |
| `kotlin/crosstest/go_kotlin_client/src/main/kotlin/com/tokilabs/toki_socket/crosstest/Main.kt` | TLS_CROSSTEST-3 |
| `kotlin/crosstest/python_kotlin_client.kt` | TLS_CROSSTEST-3 |
| `kotlin/crosstest/typescript_kotlin_client.kt` | TLS_CROSSTEST-3 |
| `python/crosstest/dart_python_client.py` | TLS_CROSSTEST-4 |
| `python/crosstest/go_python_client.py` | TLS_CROSSTEST-4 |
| `python/crosstest/kotlin_python_client.py` | TLS_CROSSTEST-4 |
| `python/crosstest/typescript_python_client.py` | TLS_CROSSTEST-4 |
| `typescript/crosstest/dart_typescript_client.ts` | TLS_CROSSTEST-5 |
| `typescript/crosstest/go_typescript_client.ts` | TLS_CROSSTEST-5 |
| `typescript/crosstest/kotlin_typescript_client.ts` | TLS_CROSSTEST-5 |
| `typescript/crosstest/python_typescript_client.ts` | TLS_CROSSTEST-5 |
| `dart/crosstest/dart_kotlin.dart` | TLS_CROSSTEST-6 |
| `dart/crosstest/dart_python.dart` | TLS_CROSSTEST-6 |
| `dart/crosstest/dart_typescript.dart` | TLS_CROSSTEST-6 |
| `go/crosstest/go_kotlin.go` | TLS_CROSSTEST-7 |
| `go/crosstest/go_python.go` | TLS_CROSSTEST-7 |
| `go/crosstest/go_typescript.go` | TLS_CROSSTEST-7 |
| `kotlin/crosstest/kotlin_dart.kt` | TLS_CROSSTEST-8 |
| `kotlin/crosstest/kotlin_go.kt` | TLS_CROSSTEST-8 |
| `kotlin/crosstest/kotlin_python.kt` | TLS_CROSSTEST-8 |
| `kotlin/crosstest/kotlin_typescript.kt` | TLS_CROSSTEST-8 |
| `python/crosstest/python_dart.py` | TLS_CROSSTEST-9 |
| `python/crosstest/python_go.py` | TLS_CROSSTEST-9 |
| `python/crosstest/python_kotlin.py` | TLS_CROSSTEST-9 |
| `python/crosstest/python_typescript.py` | TLS_CROSSTEST-9 |
| `typescript/crosstest/typescript_dart.ts` | TLS_CROSSTEST-10 |
| `typescript/crosstest/typescript_go.ts` | TLS_CROSSTEST-10 |
| `typescript/crosstest/typescript_kotlin.ts` | TLS_CROSSTEST-10 |
| `typescript/crosstest/typescript_python.ts` | TLS_CROSSTEST-10 |

## 의존 관계 및 구현 순서

**1단계 (클라이언트 파일 — 병렬 가능):**
TLS_CROSSTEST-1, TLS_CROSSTEST-2, TLS_CROSSTEST-3, TLS_CROSSTEST-4, TLS_CROSSTEST-5

**2단계 (orchestrator 파일 — 각 클라이언트 완료 후):**
- TLS_CROSSTEST-6 → TLS_CROSSTEST-1(Dart client), TLS_CROSSTEST-3(Kotlin), TLS_CROSSTEST-4(Python), TLS_CROSSTEST-5(TypeScript) 완료 후
- TLS_CROSSTEST-7 → TLS_CROSSTEST-2(Go), TLS_CROSSTEST-3(Kotlin), TLS_CROSSTEST-4(Python), TLS_CROSSTEST-5(TypeScript) 완료 후
- TLS_CROSSTEST-8 → TLS_CROSSTEST-1(Dart), TLS_CROSSTEST-2(Go), TLS_CROSSTEST-4(Python), TLS_CROSSTEST-5(TypeScript) 완료 후
- TLS_CROSSTEST-9 → TLS_CROSSTEST-1(Dart), TLS_CROSSTEST-2(Go), TLS_CROSSTEST-3(Kotlin), TLS_CROSSTEST-5(TypeScript) 완료 후
- TLS_CROSSTEST-10 → TLS_CROSSTEST-1(Dart), TLS_CROSSTEST-2(Go), TLS_CROSSTEST-3(Kotlin), TLS_CROSSTEST-4(Python) 완료 후

## 최종 검증

```
$ cd dart && dart run crosstest/dart_kotlin.dart
PASS all dart-server/kotlin-client crosstests passed

$ cd dart && dart run crosstest/dart_python.dart
PASS all dart-server/python-client crosstests passed

$ cd dart && dart run crosstest/dart_typescript.dart
PASS all dart-server/typescript-client crosstests passed

$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
  go run ./crosstest/go_kotlin.go && go run ./crosstest/go_python.go && go run ./crosstest/go_typescript.go
PASS all go-server/kotlin-client crosstests passed
PASS all go-server/python-client crosstests passed
PASS all go-server/typescript-client crosstests passed

$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
  ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinDartKt && \
  ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinGoKt && \
  ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinPythonKt && \
  ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinTypescriptKt
(모두 PASS)

$ cd python && python3 -m crosstest.python_dart && python3 -m crosstest.python_go && \
  python3 -m crosstest.python_kotlin && python3 -m crosstest.python_typescript
(모두 PASS)

$ cd typescript && node --import tsx crosstest/typescript_dart.ts && \
  node --import tsx crosstest/typescript_go.ts && \
  node --import tsx crosstest/typescript_kotlin.ts && \
  node --import tsx crosstest/typescript_python.ts
(모두 PASS)
```
