<!-- task=m-high-performance-parallel-operations/06_gateway_real_path plan=0 tag=GATEWAY_REAL_PATH -->

# Plan - GATEWAY_REAL_PATH

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

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

## 배경

현재 TypeScript gateway benchmark는 `Communicator.onReceivedFrame`에 raw frame을 직접 주입하는 in-process 경로만 측정한다. 실제 TCP/WS read loop는 `PacketBase`를 직접 decode한 뒤 `enqueueInbound`로 넣기 때문에 gateway on/off 정책을 실제 transport 수신 경로에서 판단할 수 없다. 이 작업은 TypeScript TCP/WS 수신 경로가 gateway opt-in을 통과할 수 있게 하고, benchmark가 `gateway=off,on` 실제 transport rows를 기록하게 만든다.

## 사용자 리뷰 요청 흐름

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

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/high-performance-parallel-operations.md`
- Task ids:
  - `gateway-real-path`: TCP/WS 실제 수신 경로에서 gateway on/off baseline을 추가한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/milestones/high-performance-parallel-operations.md`
- `agent-test/local/rules.md`
- `agent-test/local/proto-socket-full-matrix.md`
- `agent-test/local/typescript-smoke.md`
- `typescript/bench/stress.ts`
- `typescript/src/communicator.ts`
- `typescript/src/inbound_gateway.ts`
- `typescript/src/node_inbound_gateway.ts`
- `typescript/src/base_client.ts`
- `typescript/src/tcp_client.ts`
- `typescript/src/tcp_server.ts`
- `typescript/src/node_ws_client.ts`
- `typescript/src/node_ws_server.ts`
- `typescript/test/communicator.test.ts`
- `typescript/test/tcp.test.ts`
- `typescript/test/ws.test.ts`
- `typescript/test/base_client.test.ts`
- `typescript/package.json`

### 테스트 환경 규칙

- test_env: `local`.
- `agent-test/local/rules.md`는 존재하며 읽었다.
- TypeScript 변경이므로 `agent-test/local/typescript-smoke.md`를 적용한다: `cd typescript && npm run check && npm test`.
- 실제 transport 수신 경로와 public protocol/API 동작에 영향을 주므로 `agent-test/local/proto-socket-full-matrix.md`도 적용한다: `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all`.
- gateway baseline 자체는 stress runner 계약을 사용한다. command는 repository script help와 기존 milestone context에 근거한 보조 검증으로 둔다.
- `<확인 필요>` 값은 없었다.

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

- 기존 `typescript/test/communicator.test.ts:531` 이후는 gateway reorder, fallback, decode error, Node worker ordering, stale result drop을 검증한다.
- 기존 `typescript/test/tcp.test.ts`와 `typescript/test/ws.test.ts`는 transport roundtrip을 검증하지만 gateway attach 상태의 TCP/WS 실제 수신 경로는 검증하지 않는다.
- 기존 `typescript/bench/stress.ts:768`의 gateway profile은 in-process frame-ingest만 측정한다. 실제 TCP/WS read loop gateway on/off row가 없다.

### 심볼 참조

- rename/remove 예정 symbol 없음.
- `onReceivedFrame` 사용처: `typescript/src/communicator.ts:219`, `typescript/bench/stress.ts:829`, `typescript/test/communicator.test.ts:553`, `typescript/test/communicator.test.ts:571`, `typescript/test/communicator.test.ts:598`, `typescript/test/communicator.test.ts:632`, `typescript/test/communicator.test.ts:657`.
- transport inline decode call site: `typescript/src/tcp_client.ts:84`, `typescript/src/node_ws_client.ts:315`.

### 분할 판단

- split policy를 plan 작성 전에 평가했다.
- shared task group: `agent-task/m-high-performance-parallel-operations/`.
- `06_gateway_real_path`: 실제 transport read loop와 benchmark baseline 변경. 독립 실행 가능.
- `07+06_gateway_cleanup`: gateway close/cancel/drain 계측. `06_gateway_real_path`에서 실제 transport gateway rows와 backlog 표현을 잡은 뒤 구현하도록 의존성을 둔다.
- 이 plan은 predecessor가 없는 독립 subtask다.

### 범위 결정 근거

- Dart/Go/Kotlin/Python transport 구현은 제외한다. 현재 gateway worker implementation은 TypeScript Node worker path에만 존재한다.
- wire format, proto schema, nonce 의미, request/response API는 변경하지 않는다.
- gateway default policy는 이미 roadmap의 `gateway-threshold`에서 default off로 선언했다. 이 plan은 default on 전환을 하지 않는다.
- browser Web Worker gateway는 제외한다. Node `worker_threads` 실제 TCP/WS baseline만 다룬다.

### 빌드 등급

- build lane: `cloud-G07`. 실제 transport ingest, worker gateway, benchmark runner, full matrix evidence가 얽힌 concurrency/terminal-benchmark 작업이다.
- review lane: `cloud-G07`. inline/gateway 경로의 parse-error, FIFO, close 동작을 코드와 결과 기록 양쪽에서 대조해야 한다.

## 구현 체크리스트

- [ ] [GATEWAY_REAL_PATH-1] TypeScript TCP/WS read loop가 raw `PacketBase` bytes를 `Communicator.onReceivedFrame`으로 전달하게 바꾸고, gateway off 상태에서 기존 inline 동작이 보존되는지 테스트한다.
- [ ] [GATEWAY_REAL_PATH-2] TypeScript stress gateway profile에 실제 `tcp`/`ws` transport rows를 추가하고, `gateway=off,on`별 throughput, p95/p99, memory, backlog를 기록한다.
- [ ] [GATEWAY_REAL_PATH-3] focused stress와 TypeScript tests, 전체 matrix를 실행해 `gateway-real-path` 완료 근거를 만든다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

1. `GATEWAY_REAL_PATH-1`에서 transport read loop를 `onReceivedFrame` 경유로 통일한다.
2. `GATEWAY_REAL_PATH-2`에서 benchmark rows를 추가한다.
3. `GATEWAY_REAL_PATH-3`에서 focused stress, TypeScript smoke, full matrix를 순서대로 실행한다.

## [GATEWAY_REAL_PATH-1] Transport Read Loop Gateway Path

### 문제

`Communicator`는 gateway opt-in raw frame entrypoint를 이미 제공한다(`typescript/src/communicator.ts:219`).

```ts
219  onReceivedFrame(raw: Uint8Array): void {
224    if (gateway !== null) {
225      this.frameSeq += 1;
226      gateway.submit({ seq: this.frameSeq, bytes: raw });
```

하지만 TCP/WS read loop는 raw frame을 넘기지 않고 직접 decode한다.

```ts
83      try {
84        const base = fromBinary(PacketBaseSchema, packetBytes);
85        await this.communicator.enqueueInbound(base.typeName, base.data, base.nonce, base.responseNonce);
```

```ts
313  private async onMessage(data: Uint8Array): Promise<void> {
314    try {
315      const base = fromBinary(PacketBaseSchema, data);
316      await this.communicator.enqueueInbound(base.typeName, base.data, base.nonce, base.responseNonce);
```

### 해결 방법

- `TcpClient`와 `NodeWsClient`에서 parse error handler를 `onDisconnected()`로 연결한다.
- TCP frame payload와 WS binary message를 `this.communicator.onReceivedFrame(...)`으로 전달한다.
- 기존 pause/resume 및 parseQueue 순서는 유지한다.
- `fromBinary(PacketBaseSchema, ...)` import가 transport 파일에서 더 이상 필요 없으면 제거한다.

예상 변경:

```ts
// constructor init 이후
this.communicator.setFrameErrorHandler(() => {
  void this.onDisconnected();
});

// TCP
this.communicator.onReceivedFrame(packetBytes);
void this.sendHeartbeat();

// WS
this.communicator.onReceivedFrame(data);
void this.sendHeartbeat();
```

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

- [ ] `typescript/src/tcp_client.ts`: inline decode를 `onReceivedFrame`으로 교체한다.
- [ ] `typescript/src/node_ws_client.ts`: inline decode를 `onReceivedFrame`으로 교체한다.
- [ ] `typescript/test/tcp.test.ts`: server/client 중 한쪽 이상에 `createNodeWorkerGateway`를 attach한 TCP request-response test를 추가한다.
- [ ] `typescript/test/ws.test.ts`: server/client 중 한쪽 이상에 `createNodeWorkerGateway`를 attach한 WS request-response test를 추가한다.

### 테스트 작성

- 작성한다. TCP/WS transport에서 실제 read loop가 gateway path를 타는지 기존 communicator unit test만으로는 검증되지 않는다.
- test 목표: gateway attach 상태에서도 send-push와 request-response가 PASS이고 기존 FIFO/nonce semantics가 유지된다.

### 중간 검증

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

예상 결과: exit code 0.

## [GATEWAY_REAL_PATH-2] Stress Gateway Transport Rows

### 문제

현재 gateway profile은 `frame-ingest`만 기록한다.

```ts
768  /**
769   * gateway on/off baseline. communicator의 `onReceivedFrame` opt-in 경로에 raw PacketBase frame을 흘려
773  async function profileGateway(mode: Mode): Promise<void> {
836      emitThroughputRow("gateway", `frames=${count}`, count, elapsed, stability, gatewayOn ? "on" : "off", memMb(), {
837        transport: TRANSPORT_FRAME_INGEST,
```

milestone의 `gateway-real-path` 검증은 실제 TCP/WS frame ingest의 gateway on/off row를 요구한다.

### 해결 방법

- `profileGateway`를 유지하되 `frame-ingest` rows 뒤에 `tcp`와 `ws` rows를 추가한다.
- transport rows는 동일 payload/count 기준으로 `gateway=off,on`을 모두 실행한다.
- gateway on은 client 또는 server의 `communicator.attachInboundGateway(createNodeWorkerGateway(...))`로 적용한다. 양방향을 동시에 켜면 효과 해석이 흐려지므로, 먼저 server inbound path를 기준으로 고정한다.
- row schema는 기존 `Row`를 유지한다. `gatewayBacklog`는 cleanup 계측 전까지 0 또는 현재 관측 가능한 값으로 두고, cleanup plan에서 정밀화한다.

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

- [ ] `typescript/bench/stress.ts`: gateway profile 설명을 실제 transport row 포함으로 갱신한다.
- [ ] `typescript/bench/stress.ts`: `runGatewayTransportBaseline(transport, mode, gatewayOn)` 헬퍼를 추가한다.
- [ ] `typescript/bench/stress.ts`: `profileGateway`가 `frame-ingest`, `tcp`, `ws` rows를 모두 출력하게 한다.
- [ ] `typescript/bench/stress.ts`: row의 `transport`가 `frame-ingest`, `tcp`, `ws`로 구분되고 `gateway`가 `off`/`on`으로 기록되는지 확인한다.

### 테스트 작성

- 별도 unit test보다 stress result contract로 검증한다. 이 변경은 benchmark harness 출력 축 추가이며, functional transport test는 `GATEWAY_REAL_PATH-1`에서 추가한다.

### 중간 검증

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

예상 결과: `overall_result: PASS`, `transport`에 `frame-ingest`, `tcp`, `ws` rows가 포함된다.

## [GATEWAY_REAL_PATH-3] Evidence Run

### 문제

Roadmap completion은 실제 결과 파일이 필요하다. focused quick만으로는 full baseline 근거가 약하다.

### 해결 방법

- TypeScript smoke를 먼저 실행한다.
- gateway focused full stress를 실행해 결과 파일을 만든다.
- 전체 matrix를 실행해 TypeScript transport 경로 변경이 cross-language 동작을 깨지 않았음을 확인한다.

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

- [ ] `agent-test/runs/`: stress runner가 새 결과 파일을 자동 생성한다.
- [ ] `CODE_REVIEW-cloud-G07.md`: 결과 파일 경로와 명령 출력을 기록한다.

### 테스트 작성

- 추가 테스트 파일 작성 없음. 검증 산출물을 남기는 단계다.

### 중간 검증

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

예상 결과: `overall_result: PASS`, required SKIP 0, stability violations 0.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `typescript/src/tcp_client.ts` | GATEWAY_REAL_PATH-1 |
| `typescript/src/node_ws_client.ts` | GATEWAY_REAL_PATH-1 |
| `typescript/test/tcp.test.ts` | GATEWAY_REAL_PATH-1 |
| `typescript/test/ws.test.ts` | GATEWAY_REAL_PATH-1 |
| `typescript/bench/stress.ts` | GATEWAY_REAL_PATH-2, GATEWAY_REAL_PATH-3 |
| `CODE_REVIEW-cloud-G07.md` | GATEWAY_REAL_PATH-3 |

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

- TCP/WS no-gateway path가 `onReceivedFrame` fallback으로 기존 behavior를 보존하는가.
- gateway attach path의 parse error가 disconnect semantics를 유지하는가.
- stress 결과에 `frame-ingest`, `tcp`, `ws` rows가 모두 있고 `gateway=off,on` 비교가 가능하다.
- full matrix가 TypeScript transport 변경 후에도 PASS다.

## 최종 검증

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

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

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

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

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