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

# Review Follow-up Plan - REVIEW_REFACTOR

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

이 계획은 이전 코드리뷰 FAIL의 Required 항목만 해결한다. 구현 후 `CODE_REVIEW-cloud-G08.md`의 구현 에이전트 소유 섹션에 실제 변경 내용, 검증 명령, stdout/stderr를 채운 뒤 active 파일을 그대로 두고 리뷰를 요청한다. 사용자 결정, 사용자 소유 환경, scope 충돌로 막히면 review stub의 `사용자 리뷰 요청` 섹션을 채우고 중단한다. `complete.log` 작성, archive 이동, 최종 판정은 code-review 전용이다.

## 배경

`plan_cloud_G08_0.log` 구현은 다섯 언어에 receive coordinator를 추가했지만, 새 문서 계약과 달리 일부 언어가 inbound queue 포화 시 drop 또는 unbounded enqueue를 수행한다. 또한 정상 close에서 queued inbound item을 drain한다는 계약과 구현/테스트가 맞지 않는다. Go는 `inboundQueue` close와 concurrent send 사이에 panic 가능성이 있다.

## 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

## 범위 결정 근거

- wire format, proto schema, nonce/responseNonce 의미는 변경하지 않는다.
- direct response dispatch 정책은 이번 follow-up에서 되돌리지 않는다. 단, 문서와 구현이 response 예외를 일관되게 설명해야 한다.
- gateway worker 구현은 하지 않는다.
- 외부 dependency를 추가하지 않는다.
- 기존 active sibling `03+02_gateway_contract`는 수정하지 않는다.

## 구현 체크리스트

- [ ] Dart, Kotlin, Python, TypeScript inbound enqueue가 포화 시 메시지를 drop하거나 무제한 적재하지 않도록 backpressure 가능한 bounded queue 경계로 수정한다.
- [ ] 정상 close와 transport/error close를 구분해, 정상 close에서는 이미 enqueued 된 inbound item을 drain한 뒤 receive coordinator를 종료하도록 수정한다.
- [ ] Go `inboundQueue` close/send race를 제거해 close 중 concurrent `OnReceivedData`가 panic하지 않도록 수정한다.
- [ ] 각 언어 테스트에 queue full/backpressure와 정상 close queued item drain 검증을 추가하고, 기존 pending request cancel 테스트가 새 close 정책과 충돌하지 않게 조정한다.
- [ ] `PROTOCOL.md`와 `PORTING_GUIDE.md`의 receive ordering/backpressure/close 설명이 최종 구현과 정확히 일치하는지 갱신한다.
- [ ] 최종 검증으로 `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all`을 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REFACTOR-1] Backpressure And Close Contract Fix

#### 문제

- Dart `onReceivedData`는 `_inboundQueueLength >= _inboundQueueCapacity`일 때 packet을 버린다.
- Kotlin `onReceivedData`는 `trySend` 실패 결과를 무시한다.
- Python `on_received_data`는 `put_nowait` 실패 시 packet을 버린다.
- TypeScript inbound queue는 bound 없이 `push`한다.
- TypeScript/Python/Go 정상 close 경로는 queued inbound item을 dispatch하지 않고 폐기할 수 있다.
- Go는 `inboundQueue`를 close한 뒤 concurrent send가 발생하면 panic 가능성이 있다.

#### 해결 방법

각 언어에서 read loop가 포화된 inbound queue 앞에서 기다릴 수 있는 경계를 만든다. 기존 public `onReceivedData`가 sync API라면 transport read loop 내부에서 await/suspend/block 가능한 private enqueue API를 사용하고, 테스트용 sync wrapper는 유실 없는 방식으로 worker completion을 기다릴 수 있게 설계한다.

정상 close는 새 inbound 수락을 중단한 뒤 이미 큐에 들어간 item을 drain(dispatch 또는 명시된 drain 처리)하고 coordinator를 종료한다. transport read error, heartbeat timeout, 강제 shutdown처럼 error close인 경로는 문서대로 queued item을 discard할 수 있다. 두 경로의 이름과 호출 지점을 코드에서 구분한다.

Go는 `inboundQueue`를 close하지 않는 stop-signal 방식, 또는 send와 close를 같은 mutex로 보호하는 방식 중 하나를 선택해 closed channel send panic을 제거한다.

#### 수정 파일

- `dart/lib/src/communicator.dart`, 관련 Dart 수신 client/test
- `go/communicator.go`, 관련 Go 수신 client/test
- `kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt`, 관련 Kotlin 수신 client/test
- `python/proto_socket/communicator.py`, 관련 Python 수신 client/test
- `typescript/src/communicator.ts`, 관련 TypeScript 수신 client/test
- `PROTOCOL.md`
- `PORTING_GUIDE.md`

#### 중간 검증

```bash
cd dart && dart test
cd go && go test -count=1 ./...
cd kotlin && ./gradlew test
cd python && python3 -m pytest -q
cd typescript && npm run check && npm test
```

기대 결과: 모든 명령 exit code 0. 새 테스트는 queue full/backpressure와 정상 close drain이 기존 단순 FIFO 테스트와 별개로 실패할 수 있어야 한다.

## 최종 검증

```bash
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all
```

기대 결과: exit code 0, matrix 결과 파일의 최종 결과값 PASS.
