<!-- task=m-performance-hotspot-optimization/16_perf_regression plan=1 tag=REVIEW_TEST -->

# Code Review Reference - REVIEW_TEST

> **[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.
> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation; record the needed decision in `사용자 리뷰 요청` and stop for code-review.
> 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-07
task=m-performance-hotspot-optimization/16_perf_regression, plan=1, tag=REVIEW_TEST

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/performance-hotspot-optimization.md`
- Task ids:
  - `perf-regression`: 개선 후 `run_performance.sh --full --baseline <baseline>`을 실행해 throughput 20% 이상 하락 또는 p99 25% 이상 악화 WARN 후보를 확인한다.
- Completion mode: check-on-pass

## 이 파일을 읽는 리뷰 에이전트에게

> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.

각 항목의 구현을 실제 결과 파일과 대조하고, `검증 결과` 섹션의 출력이 결과 파일과 일치하는지 확인하세요.
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.

1. 판정을 append한다.
2. `CODE_REVIEW-cloud-G07.md` -> `code_review_cloud_G07_N.log`, `PLAN-cloud-G07.md` -> `plan_cloud_G07_M.log`로 아카이브한다.
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-performance-hotspot-optimization/16_perf_regression/`으로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다. `USER_REVIEW.md`가 사용자 결정으로 완료/PASS 해소되면 code-review가 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log` 작성 후 archive 이동한다.
4. PASS이고 task group이 `m-performance-hotspot-optimization`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REVIEW_TEST-1] Full Performance Regression Evidence Recovery | [x] (evidence 회수 완료. 단 측정 결과 자체는 overall_result=FAIL / regression_result=WARN — 아래 검증 결과·주요 설계 결정 참조) |

## 구현 체크리스트

- [x] baseline 파일 `agent-test/runs/20260605-025842-proto-socket-performance-full.md` 존재와 현재 git ref/status를 확인한다. (존재 확인, ref=85b86fc, 소스 무변경)
- [x] full performance regression 비교 명령을 실행하고 결과 파일 경로, 전체 결과값, regression 결과값, compared/warning rows를 기록한다. (record `agent-test/runs/20260606-200122-proto-socket-performance-full.md`, overall=FAIL, regression=WARN, compared 336 / missing 0 / warning 83)
- [x] WARN row가 있으면 row key, throughput/p99 변화, hard gate 위반 여부, watchlist/후속 처리 판단을 기록한다. (검증 결과·주요 설계 결정에 분류)
- [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하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [ ] PASS이면 active task 디렉터리 `agent-task/{task_name}/`를 `agent-task/archive/YYYY/MM/{task_name}/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/{task_group}/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [x] 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로 이동한다.

## 계획 대비 변경 사항

- 고정 검증 명령(최종 검증 `run_performance.sh --full --baseline ...`)은 그대로 1회 실행했다. 대체하지 않았다.
- 추가로 **focused 재측정 2건**을 보조 검증으로 실행했다. 근거: `agent-test/local/proto-socket-performance-baseline.md`의 "특정 병목만 좁혀 볼 때는 `run_stress.sh ... --profile <profile>`을 직접 실행할 수 있다"(보조 검증). 목적은 overall=FAIL을 만든 2개 hard-gate row가 transient host 노이즈인지 본질 회귀인지 분리하는 것. 검증 명령 계약을 바꾼 것이 아니라 분류 evidence를 보강한 것이다.
  - `run_stress.sh --full --lang dart --transport ws --profile burst` → record `agent-test/runs/20260607-021802-proto-socket-stress-full.md`
  - `run_stress.sh --full --lang typescript --transport tcp --profile parallel` → record `agent-test/runs/20260607-021929-proto-socket-stress-full.md`
- 소스/harness/threshold/baseline/결과 기록 형식은 변경하지 않았다. 회귀 후보를 발견했지만 새 최적화 구현은 이 plan 범위 밖이라 수정하지 않았다.

## 주요 설계 결정

측정 결과 **overall_result=FAIL, regression_result=WARN (compared 336 / missing 0 / warning 83)**. 따라서 `perf-regression` Task를 깨끗한 PASS로 닫을 수 없다. WARN/FAIL row를 성격별로 분리했다.

1. **본질 회귀 후보 (Dart WS burst dispatch) — 후속 필요**
   - `burst / Dart / ws`가 count에 비례해 붕괴: 1000→45.3% drop, 10000→96.6% drop, 100000→98.9% drop. count=100000은 hard-gate FAIL(Timeout=1, PendLeak=1).
   - **재측정 2/2 재현**: dart ws burst 100000 → "dispatch timeout", 100000건 중 56060건만 수신(약 44% 유실), violations=2. host load jitter는 이렇게 큰 유실을 반복 재현하지 않으므로 transient로 보지 않는다.
   - baseline(06-05, ref c3bbd70)에서는 dart ws burst 100000 = 147175 rps / violations=0 PASS였다. baseline 이후 Dart isolate 대용량 payload 최적화 커밋(`a0c2acc`, 06-06)이 WS burst dispatch 경로에 영향을 줬을 가능성이 높다. → **후속: Dart WS burst dispatch 경로 회귀 조사/수정** (이 plan 범위 밖).

2. **host-load 민감 FAIL (TypeScript parallel tcp clients=1024) — idle 재확인 필요**
   - 본 run Timeout=96 (511904건 중 0.019%), 재측정 Timeout=56. 0으로 떨어지지 않음. 측정 내내 host load average 5.9–8.4.
   - 직전 baseline 흐름(메모리 기록)에서는 같은 row가 72→0으로 깨끗이 transient 확정됐다. 이번엔 host 부하가 높아 0으로 안 내려가나, 최고부하(1024 client) 지점에 국한되고 환경 의존이 크다. → **후속: idle host에서 재측정해 환경성 확정**.

3. **환경성 host-contention WARN (83건 중 다수) — watchlist**
   - 원인 분해: p99-악화만 21건, throughput-drop만 9건, 둘다 53건. transport ws 53 / tcp 29.
   - **go(코드 무변경)도 13건 WARN**(p99악화 8, throughput drop 1, 둘다 4)이고 cross-language는 양방향(A→B와 B→A) 모두 WARN이다. 코드가 안 바뀐 축까지 광범위하게 WARN이므로, baseline(차분한 host)보다 높았던 이번 run의 host 부하가 지배적 원인이다.
   - 프로젝트 표준상 절대 throughput/latency는 host 의존값이며 서로 다른 부하 상태의 결과를 고정 합격선으로 비교하지 않는다(`proto-socket-performance-baseline.md` 판정 기준). 단, Dart ws WARN 11건 중 burst 계열은 1번 회귀 후보와 같은 경로이므로 일괄 watchlist로 묶지 않고 1번으로 분리했다.

4. **의도된 INCOMPLETE 신호 (해석 보조)**: kotlin same-language = INCOMPLETE(required_skips=3, violations=0) — TCP parallel clients>=128 deferred(`parallelDeadlockBottleneck`)로, 설계상 의도된 deferral이며 새 위반이 아니다.

결론: 이 검증은 의도대로 동작해 **재현되는 Dart WS burst dispatch 회귀를 잡아냈다.** evidence는 모두 회수했고, perf-regression은 회귀 후속(1번 수정 + 2번 idle 재확인) 없이는 PASS로 닫히지 않는다. 후속 라우팅(follow-up plan vs 수용 결정)은 code-review가 판단한다.

## 사용자 리뷰 요청

_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._

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

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

- 결과 파일의 `overall_result`, `regression_result`, compared rows, warning rows가 review 기록과 일치하는지 확인한다.
- WARN row가 있으면 모든 row가 원인/후속 처리와 함께 분류됐는지 확인한다.
- stability hard gate 위반을 성능 WARN과 혼동하지 않았는지 확인한다.

## 검증 결과

_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._

필수 규칙:
- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다.
- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다.
- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다.
- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다.
- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다.

### REVIEW_TEST-1 중간 검증
```
$ test -f agent-test/runs/20260605-025842-proto-socket-performance-full.md && git rev-parse --short HEAD && git status --short && uptime
85b86fc
 M agent-roadmap/milestones/performance-hotspot-optimization.md
 D agent-task/m-performance-hotspot-optimization/15+14_kotlin_ws_reference_guard/CODE_REVIEW-local-G06.md
 D agent-task/m-performance-hotspot-optimization/15+14_kotlin_ws_reference_guard/PLAN-local-G06.md
?? .tmp/
?? agent-task/archive/2026/06/m-performance-hotspot-optimization/15+14_kotlin_ws_reference_guard/
?? agent-task/m-performance-hotspot-optimization/16_perf_regression/
?? agent-task/m-performance-hotspot-optimization/17+16_compat_matrix/
 08:26:11 up 15 days, 22:06,  0 user,  load average: 5.92, 6.45, 8.37
```
- baseline 파일 존재 확인됨. git ref `85b86fc` (코드 변경 없음 — 미커밋 변경은 milestone 문서/이전 task archive 이동뿐, 소스 무변경).

### 최종 검증
완료 시각 2026-06-07T02:16Z. ref=85b86fc. 결과 record: `agent-test/runs/20260606-200122-proto-socket-performance-full.md` (frontmatter: `overall_result: FAIL`, `regression_result: WARN`).
```
$ bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_performance.sh --full --baseline agent-test/runs/20260605-025842-proto-socket-performance-full.md --throughput-drop-pct 20 --p99-worse-pct 25

=== performance 측정 결과 ===
| 구성 | 결과 | exit code | 결과 기록 | 로그 |
|---|---|---:|---|---|
| same-language | FAIL | 1 | agent-test/runs/20260606-200122-proto-socket-stress-full.md | /tmp/proto-socket-performance.ks3K2C/same-language.log |
| cross-language | PASS | 0 | agent-test/runs/20260607-020848-proto-socket-stress-full-cross.md | /tmp/proto-socket-performance.ks3K2C/cross-language.log |
| typescript-gateway | PASS | 0 | agent-test/runs/20260607-021541-proto-socket-stress-full.md | /tmp/proto-socket-performance.ks3K2C/typescript-gateway.log |

전체 결과값: FAIL
Regression 결과값: WARN
결과 기록 파일: `agent-test/runs/20260606-200122-proto-socket-performance-full.md`
```

Regression 비교 요약 (record `## Regression 비교`):
```
- baseline: `agent-test/runs/20260605-025842-proto-socket-performance-full.md`
- compared rows: 336
- missing baseline rows: 0
- warning rows: 83
```

hard-gate 위반 (overall=FAIL 원인) — 측정 결과 표에서 결과=FAIL row 2건:
```
| burst | count=100000 | Dart | ws | 7 | 1 | 100000 | 1654.2 | 0 | 0 | 0 | Timeout=1 | ... | PendLeak=1 | ... | FAIL |
| parallel | clients=1024 | TypeScript | tcp | 7 | 1024 | 511904 | 22489.0 | 59.388 | 101.063 | 119.367 | Timeout=96 | ... | FAIL |
```

WARN row 원인 분해 (83건): throughput-drop만 9 / p99-worse만 21 / 둘다 53. transport ws 53 / tcp 29. profile cross 28, parallel 15, roundtrip 11, payload 11, sustained 10, gateway 4, burst 4. 코드 무변경 go도 13건 WARN(환경성 근거). Dart ws WARN 11건 중 burst 계열(10000: 96.6% drop, 100000: 98.9% drop)은 본질 회귀 후보로 분리(주요 설계 결정 1번).

### 보조 검증 — focused 재측정 (hard-gate FAIL 분류용)
```
$ bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh --full --lang dart --transport ws --profile burst
[burst] transport=ws count=1000 received=1000 violations=0
[burst] transport=ws count=10000 received=10000 violations=0
[burst] count=100000 dispatch timeout received=55996
[burst] transport=ws count=100000 received=56060 violations=2
DONE dart: FAIL (rows=3 skips=0 required_skips=0 violations=2)
전체 결과값: FAIL
결과 기록 파일: `agent-test/runs/20260607-021802-proto-socket-stress-full.md`
```
→ Dart ws burst 100000 **재현**(2/2): 100000건 중 56060건만 수신(약 44% 유실). transient 아님 = 본질 회귀 후보.

```
$ bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh --full --lang typescript --transport tcp --profile parallel
[parallel] transport=tcp clients=16 done violations=0
[parallel] transport=tcp clients=128 done violations=0
[parallel] transport=tcp clients=512 done violations=0
[parallel] transport=tcp clients=1024 done violations=56
DONE typescript: FAIL (rows=4 skips=0 required_skips=0 violations=56)
전체 결과값: FAIL
결과 기록 파일: `agent-test/runs/20260607-021929-proto-socket-stress-full.md`
```
→ TS tcp parallel 1024 Timeout 96→56, 0으로 안 떨어짐(host load 5.9–8.4). 최고부하 지점 국한 + 환경 의존 → idle host 재확인 필요.

---

> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.

## 코드리뷰 결과

- 종합 판정: FAIL
- 차원별 평가:
  - correctness: Fail
  - completeness: Fail
  - test coverage: Fail
  - API contract: Pass
  - code quality: Pass
  - plan deviation: Pass
  - verification trust: Pass
- 발견된 문제:
  - Required: `agent-task/m-performance-hotspot-optimization/16_perf_regression/code_review_cloud_G07_1.log:147`-`:177`의 full performance baseline 비교가 `overall_result=FAIL`, `regression_result=WARN`, hard-gate FAIL 2건을 기록했습니다. 특히 `agent-test/runs/20260607-021802-proto-socket-stress-full.md`의 Dart WS burst focused rerun도 `burst / count=100000 / Dart / ws`에서 `Timeout=1`, `PendLeak=1`, `received=56060/100000`을 재현합니다. `dart/lib/src/ws_protobuf_client_io.dart:60`-`:69`와 `dart/lib/src/ws_protobuf_client_web.dart:85`-`:110`의 `_isDispatching` reentrant return은 async dispatch 중 도착한 WS frame을 버릴 수 있으므로, follow-up에서 WS 수신을 drop-free 직렬 큐/버퍼로 바꾸고 Dart WS burst 100k가 stability violation 0 PASS임을 증명해야 합니다.
  - Required: `agent-task/m-performance-hotspot-optimization/16_perf_regression/code_review_cloud_G07_1.log:192`-`:202`의 TypeScript TCP parallel focused rerun도 `clients=1024`에서 timeout 56건을 남겼습니다. 구현 에이전트는 host-load 민감 후보로 분류했지만, 현재 evidence만으로는 full performance hard gate를 닫을 수 없습니다. follow-up에서 같은 host가 낮은 load인 상태에서 focused rerun과 최종 full baseline 비교를 다시 기록해 환경성 PASS를 증명하거나, 재현되면 별도 TypeScript 회귀로 남겨야 합니다.
- 다음 단계: FAIL follow-up plan/review를 작성한다.
