<!-- task=m-high-performance-parallel-operations/07+06_gateway_cleanup plan=1 tag=REVIEW_GATEWAY_CLEANUP -->

# Plan - REVIEW_GATEWAY_CLEANUP

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

`CODE_REVIEW-cloud-G06.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채우는 것이 구현의 필수 마지막 단계다. 구현 후 검증을 실행하고, 실제 stdout/stderr를 review stub에 기록한 뒤 active 파일을 유지한 채 리뷰 준비를 보고한다. 구현 중 사용자 결정, 사용자 소유 외부 환경, 또는 범위 충돌이 없이는 진행할 수 없으면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 증거를 남기고 중단한다. 명령 재실행이나 산출물 수집으로 해소 가능한 증거 공백은 사용자 리뷰 요청이 아니다.

## 배경

1차 리뷰는 TypeScript gateway cleanup 구현과 focused verification은 통과한다고 판단했다. 다만 계획의 diagnostics contract가 public export surface에서 완전히 노출되지 않았고, `sinkPending` close/drain 경로가 실제 양수 상태로 검증되지 않았다. 이 follow-up은 두 Required issue만 닫는다.

## 사용자 리뷰 요청 흐름

구현 중 blocker는 active `CODE_REVIEW-cloud-G06.md`의 `사용자 리뷰 요청` 섹션에 기록한다. code-review만 해당 요청을 검증하고 실제 `USER_REVIEW.md` 작성 여부를 결정한다.

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/high-performance-parallel-operations.md`
- Task ids:
  - `gateway-cleanup`: gateway worker close/cancel/drain 계측을 추가한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/code-review/SKILL.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-test/local/rules.md`
- `agent-test/local/typescript-smoke.md`
- `agent-test/local/proto-socket-full-matrix.md`
- `agent-roadmap/current.md`
- `agent-roadmap/milestones/high-performance-parallel-operations.md`
- `agent-task/archive/2026/06/m-high-performance-parallel-operations/06_gateway_real_path/complete.log`
- `agent-task/m-high-performance-parallel-operations/07+06_gateway_cleanup/plan_cloud_G06_0.log`
- `agent-task/m-high-performance-parallel-operations/07+06_gateway_cleanup/code_review_cloud_G06_0.log`
- `typescript/src/index.ts`
- `typescript/src/node.ts`
- `typescript/src/communicator.ts`
- `typescript/src/inbound_gateway.ts`
- `typescript/src/node_inbound_gateway.ts`
- `typescript/src/tcp_client.ts`
- `typescript/src/node_ws_client.ts`
- `typescript/src/tcp_server.ts`
- `typescript/src/node_ws_server.ts`
- `typescript/src/base_client.ts`
- `typescript/test/communicator.test.ts`
- `typescript/test/tcp.test.ts`
- `typescript/test/ws.test.ts`
- `typescript/bench/stress.ts`
- `typescript/package.json`
- `typescript/tsconfig.json`
- `agent-test/runs/20260603-082530-proto-socket-stress-quick.md`
- `agent-test/runs/20260603-082544-proto-socket-stress-quick.md`
- `agent-test/runs/20260603-082545-proto-socket-stress-quick.md`
- `agent-test/runs/20260603-082642-proto-socket-full-matrix.md`

### 테스트 환경 규칙

- test_env: `local`.
- `agent-test/local/rules.md`는 존재하며 읽었다.
- TypeScript 변경이므로 `agent-test/local/typescript-smoke.md`를 적용한다: `cd typescript && npm run check && npm test`.
- public TypeScript API surface에 닿으므로 type check를 반드시 포함한다.
- 1차 구현의 stress/full-matrix 결과 파일은 존재했고 PASS로 대조했다. 이 follow-up은 runtime behavior를 바꾸지 않는 export/test 보완이므로 focused stress quick만 재확인한다.
- `<확인 필요>` 값은 없었다.

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

- `InboundGatewayStats`는 `typescript/src/inbound_gateway.ts`에 정의됐지만 `typescript/src/communicator.ts` re-export에서 빠져 public barrel import coverage가 없다.
- `sinkPending`은 `typescript/src/inbound_gateway.ts`에서 증가/감소하지만, `typescript/test/communicator.test.ts`는 `sinkPending > 0` 상태를 만들지 않아 close 중 stale sink skip/decrement 경로를 검증하지 않는다.

### 심볼 참조

- rename/remove symbol 없음.
- `InboundGatewayStats`: `typescript/src/inbound_gateway.ts`, `typescript/src/node_inbound_gateway.ts`; public barrel은 `typescript/src/index.ts` -> `typescript/src/communicator.ts`, `typescript/src/node.ts` -> `typescript/src/communicator.ts`.
- `sinkPending`: `typescript/src/inbound_gateway.ts`; 기존 테스트 참조는 `typescript/test/communicator.test.ts`.

### 분할 판단

- split policy를 평가했다.
- shared task group: `agent-task/m-high-performance-parallel-operations/`.
- 현재 subtask: `07+06_gateway_cleanup`.
- predecessor `06_gateway_real_path`는 `agent-task/archive/2026/06/m-high-performance-parallel-operations/06_gateway_real_path/complete.log`로 충족됐다.
- follow-up은 같은 subtask 안의 review loop 보정이므로 새 split을 만들지 않는다.

### 범위 결정 근거

- TypeScript public re-export와 `WorkerGateway` cleanup regression test만 수정한다.
- `WorkerGateway`/Node worker gateway 구현, stress schema, TCP/WS read loop, Go/Kotlin 변경은 이번 follow-up에서 고치지 않는다.
- wire format, proto schema, gateway default policy는 변경하지 않는다.

### 빌드 등급

- build lane: `cloud-G06`. concurrency diagnostics contract의 review follow-up이고 기존 lane이 적절하다.
- review lane: `cloud-G06`. API surface와 close/drain test completeness를 확인해야 한다.

## 구현 체크리스트

- [ ] [REVIEW_GATEWAY_CLEANUP-1] `InboundGatewayStats`를 TypeScript public gateway export surface에서 import 가능하게 만든다.
- [ ] [REVIEW_GATEWAY_CLEANUP-2] `sinkPending > 0` 상태를 만드는 close/drain regression test를 추가한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## [REVIEW_GATEWAY_CLEANUP-1] Export Diagnostics Stats Type

### 문제

1차 리뷰 Required issue:

```text
typescript/src/communicator.ts:19-29 re-export 목록에 type InboundGatewayStats가 없다.
```

`typescript/src/index.ts`와 `typescript/src/node.ts`는 supported package surface를 `communicator.ts` re-export에 의존한다. 계획은 `InboundGatewayStats` type 추가를 요구했지만, 현재 사용자는 supported barrel에서 stats shape를 직접 import할 수 없다.

### 해결 방법

`typescript/src/communicator.ts`의 `./inbound_gateway.js` re-export 목록에 `type InboundGatewayStats`를 추가한다.

Before:

```ts
19 export {
20   decodePacketBaseEnvelope,
21   type DecodedEnvelope,
22   type DecodedFrame,
23   type FrameDecoder,
24   FrameReorderBuffer,
25   type InboundFrame,
26   type InboundGateway,
27   WorkerGateway,
28   type WorkerGatewayOptions,
29 } from "./inbound_gateway.js";
```

After:

```ts
export {
  decodePacketBaseEnvelope,
  type DecodedEnvelope,
  type DecodedFrame,
  type FrameDecoder,
  FrameReorderBuffer,
  type InboundFrame,
  type InboundGateway,
  type InboundGatewayStats,
  WorkerGateway,
  type WorkerGatewayOptions,
} from "./inbound_gateway.js";
```

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

- [ ] `typescript/src/communicator.ts`: `type InboundGatewayStats` re-export를 추가한다.

### 테스트 작성

- 별도 runtime test는 작성하지 않는다. `npm run check`가 public source import type surface를 검증한다.

### 중간 검증

```bash
cd typescript && npm run check
```

예상 결과: exit code 0.

## [REVIEW_GATEWAY_CLEANUP-2] Cover Sink Pending Close/Drain Path

### 문제

1차 리뷰 Required issue:

```text
typescript/test/communicator.test.ts:737-831 cleanup stats tests never make sinkPending positive.
typescript/src/inbound_gateway.ts:251 and :269 are not directly covered.
```

현재 테스트는 queued/reorder/worker pending을 검증하지만, `sinkPending`이 양수인 상태에서 close가 stale sink delivery를 막고 stats를 비우는지 검증하지 않는다.

### 해결 방법

`typescript/test/communicator.test.ts`의 `WorkerGateway cleanup stats` describe에 delayed sink test를 추가한다.

필수 시나리오:

- `WorkerGateway`에 즉시 decode되는 frame 2개를 제출한다.
- 첫 sink invocation을 unresolved promise로 막아 `stats().sinkPending > 0`을 관측한다.
- 그 상태에서 `gateway.close()`를 호출한다.
- close 직후 `sinkPending`, `queued`, `reorderPending`, `workerPending`이 0이고 `closed=true`인지 확인한다.
- blocked sink를 release한 뒤 두 번째 frame이 stale delivery로 호출되지 않았는지 확인한다.

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

- [ ] `typescript/test/communicator.test.ts`: `sinkPending` 양수 상태와 close 후 stale sink suppression을 검증하는 test를 추가한다.

### 테스트 작성

- 작성한다. concurrency cleanup counter regression이므로 필수다.

### 중간 검증

```bash
cd typescript && npm test
```

예상 결과: exit code 0, `WorkerGateway cleanup stats`에 신규 test가 포함된다.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `typescript/src/communicator.ts` | REVIEW_GATEWAY_CLEANUP-1 |
| `typescript/test/communicator.test.ts` | REVIEW_GATEWAY_CLEANUP-2 |
| `CODE_REVIEW-cloud-G06.md` | 구현 결과 기록 |

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

- `InboundGatewayStats`가 supported TypeScript barrel에서 import 가능한지 확인한다.
- 신규 test가 `sinkPending > 0`을 실제로 관측하는지 확인한다.
- close 후 두 번째 stale sink delivery가 발생하지 않는지 확인한다.
- 기존 gateway cleanup stress evidence가 깨지지 않는지 확인한다.

## 최종 검증

```bash
cd typescript && npm run check
```

```bash
cd typescript && npm test
```

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

모든 명령은 exit code 0이어야 한다. stress runner가 생성한 `agent-test/runs/*.md` 경로를 review stub에 기록한다.

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