<!-- task=m-change-aware-test-routing/05_user_entrypoint_runner_contract plan=0 tag=USER_ROUTE_RUN -->

# Code Review Reference - USER_ROUTE_RUN

> **[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-10
task=m-change-aware-test-routing/05_user_entrypoint_runner_contract, plan=0, tag=USER_ROUTE_RUN

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/change-aware-test-routing.md`
- Task ids:
  - `routing-skill`: 프로젝트 스킬 또는 기존 `run-proto-socket-test-matrix` 스킬에 "작업된 내용을 바탕으로 테스트" 요청 라우팅 절차를 추가한다.
  - `auto-test-shell`: `run_test_by_change.sh` 자동 라우팅 shell을 추가해 `테스트 해봐` 요청의 기본 실행 단위로 쓴다.
  - `speed-test-shell`: `run_speed_test.sh` 속도 전용 shell을 추가해 quick/daytime과 full/nightly 후보를 관리한다.
  - `stability-test-shell`: `run_stability_test.sh` 안정성 전용 shell을 추가해 quick stress와 nightly long-run 후보를 관리한다.
  - `test-profile-docs`: `agent-test/local/rules.md`와 관련 profile 문서에 4개 shell entrypoint와 주야간 분리 기준을 반영한다.
  - `result-report-contract`: 결과 보고에 선택 이유, 실행 명령, 결과 record, skipped/nightly-pending 항목을 남긴다.
- 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-change-aware-test-routing/05_user_entrypoint_runner_contract/`로 이동한다.
4. PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [USER_ROUTE_RUN-1] Auto route execution contract | [x] |
| [USER_ROUTE_RUN-2] Speed route wrapper | [x] |
| [USER_ROUTE_RUN-3] Stability route wrapper | [x] |
| [USER_ROUTE_RUN-4] Skill and local test docs | [x] |
| [USER_ROUTE_RUN-5] Route smoke and final verification | [x] |

## 구현 체크리스트

- [x] [USER_ROUTE_RUN-1] `run_test_by_change.sh`의 dry-run 계약을 보존하면서 non-dry-run auto route가 실행 계획, 실행 결과, record 경로를 남기게 한다.
- [x] [USER_ROUTE_RUN-2] `run_speed_test.sh`를 추가해 speed route dry-run 보고 후 낮 시간 quick 성능 실행과 nightly-pending full 후보 보고를 수행한다.
- [x] [USER_ROUTE_RUN-3] `run_stability_test.sh`를 추가해 stability route dry-run 보고 후 quick stability 실행과 hard gate/nightly-pending 후보 보고를 수행한다.
- [x] [USER_ROUTE_RUN-4] `run-proto-socket-test-matrix` skill과 `agent-test/local` profile 문서를 새 실행 wrapper 및 결과 보고 계약과 일치시킨다.
- [x] [USER_ROUTE_RUN-5] shell syntax, focused temp repo route smoke, deterministic `rg --sort path`로 검증하고 실제 stdout/stderr를 review stub에 남긴다.
- [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_cloud_G07_N.log`로 아카이브한다.
- [x] active `PLAN-*-G??.md`를 `plan_cloud_G07_M.log`로 아카이브한다.
- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [ ] PASS이면 `complete.log`에 `Roadmap Completion` 섹션과 대상 Task ids를 기록한다.
- [ ] PASS이면 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-change-aware-test-routing/05_user_entrypoint_runner_contract/`로 이동한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [x] FAIL이고 user-review gate가 트리거되지 않았으므로 다음 active `PLAN-cloud-G07.md`와 `CODE_REVIEW-cloud-G07.md`를 작성하고 `complete.log`를 작성하지 않는다.

## 계획 대비 변경 사항

- `run_speed_test.sh`의 분류 출력 파싱: 계획은 `run_test_by_change.sh --route speed --dry-run` 출력에서 추천 상태를 파싱하는 방식을 명시하지 않았다. stdout의 `| recommended | performance-quick |` 패턴을 `while IFS= read -r line; do case "$line" in ... esac; done` 으로 파싱했다. `run_stability_test.sh`도 같은 방식 적용.
- `run_test_by_change.sh` non-dry-run에서 `runner-docs-selfcheck`와 `docs-selfcheck` 모두 `bash -n <self>` 로 처리했다. 계획의 `runner-docs-selfcheck` 단일 항목을 `docs-selfcheck` alias도 같이 처리한 것이다. 동작 동일.

## 주요 설계 결정

- `run_test_by_change.sh`의 non-dry-run 실행 분기는 `main()` 함수 내 결과 출력 이후에 추가했다. `[ "$dry_run" -eq 1 ] && return`으로 dry-run 계약을 보존한다.
- anchor 실행(`functional-server-x5`, `functional-client-x5`, `functional-both-x5`)은 `anchor-runner-options` 범위이므로 `anchor-skipped`로 기록하고 실제 command를 실행하지 않는다.
- `run_speed_test.sh`와 `run_stability_test.sh`는 각각 classifier를 subshell로 호출해 출력을 캡처한 뒤 추천 상태를 파싱한다. classifier stdout/stderr를 합산하지 않고 stdout만 추천 파싱에 사용한다.
- nightly-pending 후보는 실행하지 않고 후보 command와 함께 `## nightly-pending 후보 (미실행, PASS 아님)` 섹션으로 기록한다.

## 사용자 리뷰 요청

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

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

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

- `--dry-run` 동작이 기존처럼 테스트를 실행하지 않는지 확인한다.
- non-dry-run wrapper가 실행한 항목과 skipped/nightly-pending 항목을 PASS로 섞지 않는지 확인한다.
- `run_speed_test.sh`와 `run_stability_test.sh`가 full/nightly 후보를 즉시 실행하지 않는지 확인한다.
- 결과 record에 선택 이유, 실행 명령, record path, skipped/nightly-pending 항목이 남는지 확인한다.

## 검증 결과

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

필수 규칙:
- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다.
- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다.
- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다.
- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다.

### USER_ROUTE_RUN-1~3 shell syntax
```text
$ bash -n agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_test_by_change.sh
exit:0

$ bash -n agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_speed_test.sh
exit:0

$ bash -n agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stability_test.sh
exit:0
```

### USER_ROUTE_RUN-4 deterministic contract search
```text
$ rg --sort path -n "run_test_by_change.sh|run_speed_test.sh|run_stability_test.sh|run_full_test.sh|nightly-pending|PASS 아님|결과 기록|hard gate" agent-ops/skills/project/run-proto-socket-test-matrix agent-test/local

agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:25:...run_test_by_change.sh --route <mode> --dry-run...run_full_test.sh --dry-run...
agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:199:- `nightly-pending`: 야간 별도 실행 후보. 실행하지 않은 것을 PASS로 보고하지 않음.
agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:204:...stability-quick을 추천하고 timeout, nonce/type mismatch, FIFO, pending leak, queue/gateway backlog를 hard gate로 본다.
agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:215:| `테스트 해봐` | `run_test_by_change.sh --route auto` | dry-run으로 후보 보고 → recommended 항목 실행 → 결과 record 경로 기록. skipped/nightly-pending은 실행 안 함 |
agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:216:| `속도 테스트 해봐` | `run_speed_test.sh` | ...nightly-pending full은 후보 command만 기록 |
agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:217:| `안정성 테스트 해봐` | `run_stability_test.sh` | ...stability-quick hard gate 실행. nightly-pending full은 후보 command만 기록 |
agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:225:### 결과 기록 계약
agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:228:- 실행하지 않은 skipped/nightly-pending 항목은 PASS로 보고하지 않는다.
agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md:229:- `nightly-pending` 후보는 `## nightly-pending 후보 (미실행, PASS 아님)` 섹션에 후보 command와 함께 기록한다.
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_full_test.sh:8:# run_test_by_change.sh --route full --dry-run...
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_full_test.sh:72:  printf '\n### Nightly pending (미실행, PASS 아님)\n\n'
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_speed_test.sh:8:# --dry-run: run_test_by_change.sh --route speed --dry-run 출력만 수행한다.
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_speed_test.sh:73:    '| nightly-pending | performance-full |'*)
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_speed_test.sh:90:  printf '- [nightly-pending] performance-full: 20:00 이후 야간 후보. 후보 command: ...run_performance.sh --full\n'
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_speed_test.sh:110:    printf '- 결과 기록: %s\n' "$rel"
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_speed_test.sh:114:# 5. nightly-pending 후보 요약 (미실행, PASS 아님)
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stability_test.sh:9:# non-dry-run: stability-quick recommended면 run_stress.sh --quick 실행(hard gate),
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stability_test.sh:88:  printf '- [실행 예정] stability-quick (hard gate): ...
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stability_test.sh:89:  printf '  hard gate: timeout / nonce mismatch / response type mismatch / FIFO violation / pending leak / queue/gateway backlog leak 모두 0\n'
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stability_test.sh:115:    printf '- 결과 기록: %s\n' "$rel"
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stability_test.sh:124:# 5. nightly-pending 후보 요약 (미실행, PASS 아님)
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_test_by_change.sh:29:  stability  stress/performance PASS record (stability hard gate 기준)
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_test_by_change.sh:777:      printf '\n#### nightly-pending (미실행, PASS 아님)\n\n'
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_test_by_change.sh:834:      printf '- 결과 기록: %s\n' "$rel_record"
agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_test_by_change.sh:839:    printf '\n### nightly-pending 후보 (미실행, PASS 아님)\n\n'
agent-test/local/proto-socket-full-matrix.md:53:- user-entrypoint (변경 기반 자동): `bash ...run_test_by_change.sh --route auto`
agent-test/local/proto-socket-full-matrix.md:56:- user-entrypoint (안정성): `bash ...run_stability_test.sh`
agent-test/local/proto-socket-performance-baseline.md:43:- user-entrypoint (속도 테스트): `bash ...run_speed_test.sh`
agent-test/local/proto-socket-performance-baseline.md:45:  - performance-quick recommended → `run_performance.sh --quick` 자동 실행. nightly-pending full은 후보 command만 기록 (PASS 아님)
agent-test/local/proto-socket-performance-baseline.md:56:- full route에서 `performance-full`이 `nightly-pending`이면 미실행 항목이며 PASS 아님으로 보고한다.
agent-test/local/proto-socket-performance-baseline.md:68:- stability hard gate: timeout, nonce mismatch, response type mismatch, per-connection FIFO violation, pending leak, queue/gateway backlog leak가 모두 0이어야 한다.
agent-test/local/rules.md:50:| `테스트 해봐` | `run_test_by_change.sh --route auto` | ...결과 record 경로 기록 |
agent-test/local/rules.md:51:| `속도 테스트 해봐` | `run_speed_test.sh` | ... |
agent-test/local/rules.md:52:| `안정성 테스트 해봐` | `run_stability_test.sh` | ... |
agent-test/local/rules.md:53:| `전체 테스트 해봐` | `run_full_test.sh` | ... |
agent-test/local/rules.md:55:### 결과 기록 계약
agent-test/local/rules.md:58:- 실행하지 않은 skipped/nightly-pending 항목은 PASS로 보고하지 않는다.
agent-test/local/rules.md:59:- `nightly-pending` 후보는 `## nightly-pending 후보 (미실행, PASS 아님)` 섹션에 후보 command와 함께 기록된다.
agent-test/local/rules.md:61:- stability-quick hard gate: timeout / nonce mismatch / response type mismatch / FIFO violation / pending leak / queue/gateway backlog leak가 모두 0이어야 PASS.
```

### USER_ROUTE_RUN-5 temp repo smoke
```text
$ tmp="$(mktemp ...)" && ... && printf 'package transport\n' > go/transport/stress_payload_1mb.go \
  && bash run_test_by_change.sh --route auto --dry-run \
  && bash run_speed_test.sh --dry-run \
  && bash run_stability_test.sh --dry-run

=== run_test_by_change.sh --route auto --dry-run ===
## 변경 기반 분류 결과

route: auto
last_pass_record: agent-test/runs/20260610-000000-proto-socket-stress-quick.md
last_pass_ref: 5b2ff62
fallback_reason: (없음)
changed_file_count: 4
detected_languages: go
detected_domains: other,transport
docs_only: no
untracked_included: yes

### 변경 파일 목록
| 파일 | 언어 | 도메인 |
|------|------|--------|
| agent-test/runs/20260610-000000-proto-socket-full-matrix.md |  | other |
| agent-test/runs/20260610-000000-proto-socket-performance-quick.md |  | other |
| agent-test/runs/20260610-000000-proto-socket-stress-quick.md |  | other |
| go/transport/stress_payload_1mb.go | go | transport |

### 라우팅 추천 결과
| 상태 | 테스트 후보 | 대상 | 근거 |
|---|---|---|---|
| recommended | functional-both-x5 | go | transport/codec/communicator/public API 변경은 수정 언어 기준 both x5 |
| recommended | functional-both-x5 | transport/queue | transport/queue 변경은 both x5로 확장 |
| recommended | stability-quick | queue, gateway, concurrency | transport/queue 변경은 timeout, nonce/type mismatch, FIFO, pending leak, backlog hard gate 점검 필요 |
| recommended | performance-quick | performance baseline | 성능 영향 가능 변경은 낮 시간 quick 참고값을 남기되 야간 baseline 근거로 쓰지 않음 |
| nightly-pending | performance-full | performance baseline | sustained/high parallel/1MB payload 지표는 20:00 이후 야간 full 후보. 후보 command: run_performance.sh --full |
| nightly-pending | stability-full | queue/gateway/transport | 장시간 leak/backlog 확인은 20:00 이후 야간 후보. 후보 command: run_stress.sh --full --profile sustained,parallel,payload |

=== run_speed_test.sh --dry-run ===
## Speed route 분류 결과

route: speed
last_pass_record: agent-test/runs/20260610-000000-proto-socket-performance-quick.md
last_pass_ref: 5b2ff62
...
### 라우팅 추천 결과
| recommended | performance-quick | performance baseline | 성능 영향 가능 변경... |
| nightly-pending | performance-full | performance baseline | ... |
| nightly-pending | stability-full | queue/gateway/transport | ... |

=== run_stability_test.sh --dry-run ===
## Stability route 분류 결과

route: stability
last_pass_record: agent-test/runs/20260610-000000-proto-socket-stress-quick.md
last_pass_ref: 5b2ff62
...
### 라우팅 추천 결과
| recommended | stability-quick | queue, gateway, concurrency | transport/queue 변경... |
| nightly-pending | stability-full | queue/gateway/transport | ... |
```

### 최종 검증
```text
$ git diff --check
exit:0
```

---

> **[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: Fail
  - code quality: Warn
  - plan deviation: Pass
  - verification trust: Fail
- 발견된 문제:
  - Required: `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_test_by_change.sh:828`, `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_speed_test.sh:85`, `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stability_test.sh:88` 등 새 non-dry-run 출력에서 `printf '- ...'` 형식 문자열을 사용한다. Bash `printf`는 선행 `-`를 option으로 해석하므로 실제 non-dry-run smoke에서 `printf: - : invalid option`이 반복되고, 실행 명령/선택 이유/exit code/결과 record 라인이 출력되지 않았다. 모든 dash-leading format은 `printf -- '- ...\n'` 또는 `printf '%s\n' '- ...'` 형태로 고치고, auto/speed/stability non-dry-run temp repo smoke로 `invalid option`이 없고 결과 record 라인이 남는지 검증해야 한다.
  - Required: `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_test_by_change.sh:725`는 `--dry-run`만 조기 반환하고 `--classify-only`는 반환하지 않는다. 사용법의 "`--classify-only` 분류 결과만 출력하고 종료" 계약과 달리 `bash .../run_test_by_change.sh --classify-only`가 `### 실행 계획`까지 출력했다. `classify_only=1`도 라우팅 추천/실행 분기 전에 종료하도록 복구하고, classify-only smoke를 검증에 추가해야 한다.
- 다음 단계:
  - FAIL follow-up: 위 Required 이슈를 고치는 다음 `PLAN-cloud-G07.md` / `CODE_REVIEW-cloud-G07.md`를 작성한다.
