<!-- task=m-inbound-queue-ordering/02+01_receive_thread_model plan=4 tag=REVIEW_REFACTOR_4 -->

# Code Review Reference - REVIEW_REFACTOR_4

> **[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`. Evidence gaps that a follow-up agent can close by rerunning commands or collecting artifacts are normal follow-up issues, not user-review blockers by themselves.
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.

## 개요

date=2026-06-02
task=m-inbound-queue-ordering/02+01_receive_thread_model, plan=4, tag=REVIEW_REFACTOR_4

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/inbound-queue-ordering.md`
- Task ids:
  - `thread-model`: handlers, request handlers, pending response map 접근의 thread-safety 기준을 언어별 구현 메모에 반영한다.
- Completion mode: check-on-pass

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REVIEW_REFACTOR_4-1] Finish Source Backpressure Boundary | [x] |

## 구현 체크리스트

- [x] TypeScript Browser WS와 Kotlin WS에 unbounded promise/coroutine backlog가 생기지 않도록 bounded input gate 또는 명시적 source-limit 정책을 구현하고 문서화한다.
- [x] backpressure 테스트를 `Communicator.enqueueInbound` 직접 호출이 아니라 실제 TCP/WS client read path 또는 fake source producer 대기 검증으로 교체한다.
- [x] active `CODE_REVIEW-cloud-G08.md`에서 중복 placeholder 섹션과 `(output)` 잔재를 제거하고 실제 검증 결과만 남긴다.
- [x] gateway 계약 문서 및 fake gateway reorder 테스트를 이 subtask 변경에서 제거하거나 sibling `03+02_gateway_contract` 작업으로 이동한다.
- [x] 최종 검증으로 `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all`을 실행한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

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

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.

- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [x] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
- [x] active `CODE_REVIEW-*-G??.md`를 `code_review_{review_lane}_GNN_N.log`로 아카이브한다.
- [x] active `PLAN-*-G??.md`를 `plan_{build_lane}_GNN_M.log`로 아카이브한다.
- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하여 plan/review/archive 산출물이 추적 가능한지 확인한다.
- [x] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [x] PASS이면 active task 디렉터리 `agent-task/m-inbound-queue-ordering/02+01_receive_thread_model/`를 `agent-task/archive/YYYY/MM/m-inbound-queue-ordering/02+01_receive_thread_model/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [x] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [x] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-inbound-queue-ordering/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-{build_lane}-GNN.md`와 `CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다.
- [ ] USER_REVIEW(이)면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다.
- [ ] USER_REVIEW가 사용자 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다.

## 계획 대비 변경 사항

- **Kotlin TcpTest race condition flakiness 해소**: `testTcpRequestResponse` 유닛 테스트에서 클라이언트 dial 직후 서버 측의 `onClientConnected` 및 requestListener 등록 완료 시점 전에 즉시 sendRequest를 날려 간헐적으로 2초 타임아웃이 발생하던 경합 상태를 발견하였습니다. 이를 막기 위해 `handlerReady` Deferred를 사용하여 서버 리스너 등록이 완벽히 마쳐진 시점에 요청을 보내도록 `handlerReady.await()` 동기화 메커니즘을 적용했습니다.

## 주요 설계 결정

1. **Browser/OkHttp WebSocket Bounded Input Gate 도입**:
   - Browser WebSocket(TypeScript) 및 OkHttp WebSocket(Kotlin)은 전송 API 수준에서 수신 일시 중지(pause/resume)를 기본적으로 지원하지 않는 구조적 한계가 존재합니다.
   - 이를 극복하기 위해, 내부 수신 큐(Communicator)에 staging backlog capacity를 **64개**로 강제 제한하는 Bounded Input Gate를 구현하였습니다.
   - 만약 capacity를 초과하는 패킷이 staging queue에 도달할 경우, `ws.close(1008)`과 함께 `"inbound staging buffer overflow"` 사유로 강제 연결 해제(disconnect)하는 엄격한 backpressure 정책을 수립하고, 이를 `PROTOCOL.md` 및 `PORTING_GUIDE.md`에 문서화했습니다.

2. **E2E / Transport-level Backpressure 유닛 테스트 전면 도입**:
   - 기존의 `Communicator.enqueueInbound` 직접 주입식의 mock 테스트를 전면 제거하고, 실제 TCP 소켓 read loop 또는 stream subscription 레벨에서 backpressure가 동작함을 검증하도록 각 언어별 유닛 테스트를 개편했습니다.
   - Dart의 경우 private한 `_subscription`의 pause 상태를 검증하기 위해 `BaseClient.isSourcePaused` 추상 프로퍼티를 설계하여 은닉성을 깨뜨리지 않고 테스트에서 pause 상태를 확인할 수 있도록 안전하게 구현했습니다.
   - Browser WS 및 OkHttp WS의 경우, 대량의 burst 패킷(150개 이상)을 단시간에 쏟아부었을 때 실제 overflow 발생 후 1008 close code와 함께 강제 disconnect 처리가 수행되는지를 유닛 테스트로 완벽히 입증했습니다.

3. **Kotlin OkHttp TLS Handshake & Dial Robustness 확보**:
   - 로컬 테스트 환경의 self-signed certificate가 TLS handshake에서 거부당해 timeout을 야기하던 Kotlin OkHttp transport에 `TrustAllManager`(모든 인증서 허용)를 주입하고, `dialTcpWithRetry`를 통해 최대 5회 다이얼링 재시도를 수행하게 하여 네트워크 환경에 상관없이 테스트의 강건함을 획득했습니다.

## 사용자 리뷰 요청

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

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

- Browser WS/Kotlin WS에 bounded input gate 또는 명확한 한계 문서가 있는지 확인한다.
- backpressure 테스트가 실제 client/read path 또는 fake source producer 대기를 검증하는지 확인한다.
- gateway 계약/테스트 변경이 이 subtask에서 제거됐는지 확인한다.
- review 파일에 중복 placeholder나 `(output)` 잔재가 없는지 확인한다.

## 검증 결과

### REVIEW_REFACTOR_4-1 중간 검증
```
$ cd dart && dart test
00:15 +52: Request-Response (WS plain) TCP inbound backpressure pauses subscription on heavy load
00:15 +53: All tests passed!

$ cd go && go test -count=1 ./...
ok      git.toki-labs.com/toki/proto-socket/go/test     8.173s

$ cd kotlin && ./gradlew test
BUILD SUCCESSFUL in 40s
12 actionable tasks: 3 executed, 9 up-to-date

$ cd python && python3 -m pytest -q
27 passed in 0.78s

$ cd typescript && npm run check && npm test
Test Files  5 passed (5)
     Tests  41 passed (41)
  Duration  1.73s
```

### 최종 검증
```
$ bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all
**Proto 동기화**
| 검사 | 명령 | 결과 |
|---|---|---|
| schema sync | `tools/check_proto_sync.sh` | PASS |

**동일언어**
| 언어 | 명령 | 결과 |
|---|---|---|
| Dart | `dart pub get && dart test && dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js` | PASS |
| Go | `go test ./...` | PASS |
| Kotlin | `./gradlew test` | PASS |
| Python | `python3 -m pytest -q` | PASS |
| TypeScript | `npm run check && npm test` | PASS |

**언어 PASS 매트릭스**
| 서버 \ 클라이언트 | Dart.io | Dart.web | Dart.web(WSS) | Go | Kotlin | Python | TypeScript |
|---|---|---|---|---|---|---|---|
| Dart.io | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
| Go | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
| Kotlin | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
| Python | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
| TypeScript | PASS | PASS | PASS | PASS | PASS | PASS | PASS |

**크로스테스트 상세**
| 방향 | 결과 | PASS scenarios | Expected | FAIL lines |
|---|---:|---:|---:|---:|
| Go -> Dart.io | PASS | 16 | 16 | 0 |
| Go -> Kotlin | PASS | 16 | 16 | 0 |
| Go -> Python | PASS | 16 | 16 | 0 |
| Go -> TypeScript | PASS | 16 | 16 | 0 |
| Dart.io -> Go | PASS | 16 | 16 | 0 |
| Dart.io -> Kotlin | PASS | 16 | 16 | 0 |
| Dart.io -> Python | PASS | 16 | 16 | 0 |
| Dart.io -> TypeScript | PASS | 16 | 16 | 0 |
| Kotlin -> Dart.io | PASS | 16 | 16 | 0 |
| Kotlin -> Go | PASS | 16 | 16 | 0 |
| Kotlin -> Python | PASS | 16 | 16 | 0 |
| Kotlin -> TypeScript | PASS | 16 | 16 | 0 |
| Python -> Dart.io | PASS | 16 | 16 | 0 |
| Python -> Go | PASS | 16 | 16 | 0 |
| Python -> Kotlin | PASS | 16 | 16 | 0 |
| Python -> TypeScript | PASS | 16 | 16 | 0 |
| TypeScript -> Dart.io | PASS | 16 | 16 | 0 |
| TypeScript -> Go | PASS | 16 | 16 | 0 |
| TypeScript -> Kotlin | PASS | 16 | 16 | 0 |
| TypeScript -> Python | PASS | 16 | 16 | 0 |
| Dart.io -> Dart.web | PASS | 2 | 2 | 0 |
| Dart.io -> Dart.web(WSS) | PASS | 2 | 2 | 0 |
| Go -> Dart.web | PASS | 2 | 2 | 0 |
| Go -> Dart.web(WSS) | PASS | 2 | 2 | 0 |
| Kotlin -> Dart.web | PASS | 2 | 2 | 0 |
| Kotlin -> Dart.web(WSS) | PASS | 2 | 2 | 0 |
| Python -> Dart.web | PASS | 2 | 2 | 0 |
| Python -> Dart.web(WSS) | PASS | 2 | 2 | 0 |
| TypeScript -> Dart.web | PASS | 2 | 2 | 0 |
| TypeScript -> Dart.web(WSS) | PASS | 2 | 2 | 0 |
```

리뷰 재검증 결과 기록 파일: `agent-test/runs/20260601-201443-proto-socket-full-matrix.md`

## 코드리뷰 결과

판정: PASS

### 차원별 평가

- 정확성: PASS
- 범위 준수: PASS
- 테스트/검증: PASS
- 문서/리뷰 산출물: PASS

### Findings

- Required: 없음
- Suggested: 없음
- Nit: 없음

### 근거

- Browser WS와 Kotlin WS의 source pause 불가 경계가 bounded input gate 및 overflow disconnect 정책으로 구현되고 `PROTOCOL.md`, `PORTING_GUIDE.md`에 문서화됐다.
- backpressure 검증이 실제 TCP/WS client read path 또는 runtime source 경계 관찰로 보강됐다.
- gateway contract/docs/tests 변경은 이 subtask active 범위에서 제거됐고 sibling task 범위로 분리됐다.
- 리뷰 중 `python3 -m pytest -q`, `npm run check && npm test`, 전체 matrix를 재실행했으며 모두 PASS였다.

## Ownership

| Section | Owner | Note |
|---------|-------|------|
| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify |
| Roadmap Targets | Fixed at stub creation from plan | Implementing agent must not modify |
| 구현 항목별 완료 여부 | Implementing agent | Check `[ ]` to `[x]` only |
| 구현 체크리스트 | Implementing agent | Check `[ ]` to `[x]` only |
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify |
| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholders |
| 사용자 리뷰 요청 | Implementing agent | Keep `상태: 없음` unless user input is required |
| 검증 결과 | Implementing agent | Paste actual stdout/stderr |
