# 변경 기반 테스트 라우팅 정형화

## 목표

사용자가 "테스트 해봐"처럼 테스트 범위를 직접 지정하지 않아도, 마지막 통과 테스트 지점과 현재 변경 내용을 분석해 기능 테스트, 속도 테스트, 안정성 테스트 중 필요한 검증을 자동으로 고른다. 명시 요청은 "속도 테스트 해봐", "안정성 테스트 해봐", "전체 테스트 해봐" 세 라우팅으로 분리하고, 언어별 변경은 수정 언어 중심 x5 또는 양방향 x5를 기본 기준점으로 삼으며, 장시간/대용량 측정은 야간 window로 분리한다.

## 단계

안정화와 유지

## 상태

[완료]

## 구현 잠금

- 상태: 해제
- 결정 필요: 없음

## 범위

- 마지막 PASS 테스트 record와 현재 변경 파일을 기반으로 테스트 범위를 추론한다.
- 테스트 종류를 `functional`, `performance`, `stability` 세 축으로 정형화한다.
- 사용자-facing 라우팅은 `테스트 해봐`, `속도 테스트 해봐`, `안정성 테스트 해봐`, `전체 테스트 해봐` 4개로 정형화한다.
- 언어별 변경은 Dart, Go, Kotlin, Python, TypeScript 중 수정 언어를 anchor로 잡아 server x5, client x5, 또는 both x5로 라우팅한다.
- x5의 self 방향은 cross pair가 아니라 해당 언어 same-language/unit 또는 same-language transport row로 채운다.
- Dart.web/Dart.web(WSS)는 server-capable 5개 언어 x5에는 넣지 않고, full functional matrix 또는 Dart.web/browser 관련 변경에서 필수 client coverage로 유지한다.
- proto/schema, codec, framing, communicator, transport, queue/gateway, benchmark/test runner 변경은 더 넓은 검증 범위로 승격한다.
- 속도와 안정성 테스트는 quick/daytime과 full/nightly 기준을 분리한다.
- 정기 full test는 매 변경 gate와 별도 성격으로 둔다.
- 각 라우팅은 `run_test_by_change.sh`, `run_speed_test.sh`, `run_stability_test.sh`, `run_full_test.sh` shell entrypoint로 관리하고, shell 내부에서 기존 `run_matrix.sh`, `run_performance.sh`, `run_stress.sh`를 조합한다.

## 기능

### Epic: [change-classifier] 변경 내용 분류

테스트 요청 시 현재 diff가 어떤 검증 범위를 요구하는지 판단한다.

- [x] [last-pass-point] `agent-test/runs/`의 요청 라우팅과 맞는 최신 PASS record와 git ref를 기준으로 마지막 테스트 지점을 찾는다. 검증: PASS record가 없을 때는 현재 diff 기준 보수 라우팅으로 fallback한다.
- [x] [diff-source] 마지막 PASS ref, 현재 HEAD, uncommitted 변경을 합쳐 실제 테스트 대상 diff를 만든다. 검증: commit된 변경과 작업트리 변경이 동시에 있어도 누락하지 않는다.
- [x] [path-domain-map] 변경 파일을 언어 구현, proto/schema, transport, communicator, queue/gateway, performance harness, test docs, docs-only로 분류한다. 검증: 각 분류가 선택한 테스트 kind와 scope에 반영된다.
- [x] [risk-escalation] codec/framing/proto/communicator 변경은 수정 언어 범위를 넘어 full 또는 wider functional gate 후보로 승격한다. 검증: protocol-relevant 변경이 smoke test만으로 끝나지 않는다.

### Epic: [functional-routing] 기능 테스트 라우팅

일반 수정 후 항상 실행할 최소 기능 기준점을 정한다.

- [x] [anchor-language-x5] 언어 구현 변경은 수정 언어 중심 server x5 또는 client x5를 선택한다. 검증: server-only/client-only 변경은 해당 방향 x5를 실행 후보로 만든다.
- [x] [anchor-language-both-x5] transport, codec, communicator, public API 변경은 수정 언어 기준 양방향 x5를 선택한다. 검증: 같은 언어 self 방향은 same-language 검증으로 채우고 중복 방향은 결과에서 한 번만 센다.
- [x] [dart-web-coverage] Dart.web/Dart.web(WSS)는 full functional matrix와 browser client 관련 변경에서 필수 coverage로 유지한다. 검증: full functional route가 기존 Dart.web/WSS client 열을 누락하지 않는다.
- [x] [full-functional-periodic] 정기 full 또는 넓은 protocol 변경은 functional full 5x5와 Dart.web/WSS client coverage를 선택한다. 검증: 전체 cross matrix가 매 변경 기본값이 아니라 정기/고위험 변경용으로 분리된다.

### Epic: [performance-stability-routing] 속도/안정성 라우팅

성능과 안정성은 목적을 분리하되, 측정 row에는 stability hard gate를 같이 남긴다.

- [x] [daytime-performance-quick] 성능 영향 가능 변경은 낮 시간 quick performance를 선택한다. 검증: quick 결과는 변경 후 속도 참고값이며 야간 baseline으로 기록하지 않는다.
- [x] [daytime-stability-quick] queue, gateway, concurrency, transport 변경은 낮 시간 quick stability/stress를 선택한다. 검증: timeout, nonce mismatch, type mismatch, FIFO violation, pending leak, queue/gateway backlog가 hard gate로 남는다.
- [x] [nightly-heavy-routing] sustained, high parallel, 1MB payload, 장시간 leak 확인은 20:00 이후 full/nightly 후보로 분리한다. 검증: 낮 시간 full 장시간 측정은 baseline 완료 근거로 쓰이지 않는다.
- [x] [periodic-full-routing] 정기 full test는 functional full 5x5와 performance/stability nightly full을 구분해 실행 후보를 만든다. 검증: 정기 full이 매 수정 gate와 분리된다.

### Epic: [user-entrypoints] 사용자 요청 4분류

사용자가 길게 지정하지 않아도 요청 문장으로 테스트 의도를 안정적으로 고른다.

- [x] [auto-test-route] `테스트 해봐`는 마지막 PASS 지점과 현재 diff를 분석해 functional/performance/stability 중 필요한 범위를 자동 선택한다. 검증: 변경 내용 분석 결과와 선택한 테스트 범위를 실행 전에 보고한다.
- [x] [speed-test-route] `속도 테스트 해봐`는 performance 중심으로 라우팅하고, 낮 시간 quick과 야간 full 후보를 분리한다. 검증: 장시간/1MB/full이 20:00 이전에 baseline으로 처리되지 않는다.
- [x] [stability-test-route] `안정성 테스트 해봐`는 timeout, nonce/type mismatch, FIFO, pending leak, queue/gateway backlog 중심으로 라우팅한다. 검증: 성능 수치가 좋아도 hard gate 위반 row는 PASS가 아니다.
- [x] [full-test-route] `전체 테스트 해봐`는 functional full 5x5를 기본으로 실행하고, performance/stability full은 시간대에 따라 즉시 실행 또는 nightly pending으로 분리한다. 검증: 실행하지 않은 야간 full 항목을 PASS로 보고하지 않는다.

### Epic: [skill-and-runner-contract] 스킬과 runner 계약

스킬이 선택한 라우팅을 실제 명령으로 연결한다.

- [x] [routing-skill] 프로젝트 스킬 또는 기존 `run-proto-socket-test-matrix` 스킬에 "작업된 내용을 바탕으로 테스트" 요청 라우팅 절차를 추가한다. 검증: 사용자가 언어와 테스트 종류를 지정하지 않아도 변경 분석 결과와 선택한 검증 범위를 먼저 보고한다.
- [x] [auto-test-shell] `run_test_by_change.sh` 자동 라우팅 shell을 추가해 `테스트 해봐` 요청의 기본 실행 단위로 쓴다. 검증: 마지막 PASS 지점, 변경 분류, 선택된 하위 command가 결과 기록에 남는다.
- [x] [speed-test-shell] `run_speed_test.sh` 속도 전용 shell을 추가해 quick/daytime과 full/nightly 후보를 관리한다. 검증: 성능 관련 변경에서 기존 `run_performance.sh`/`run_stress.sh`를 직접 외우지 않아도 실행된다.
- [x] [stability-test-shell] `run_stability_test.sh` 안정성 전용 shell을 추가해 quick stress와 nightly long-run 후보를 관리한다. 검증: stability hard gate 요약이 별도 결과로 남는다.
- [x] [full-test-shell] `run_full_test.sh` 전체 테스트 shell을 추가해 functional full과 nightly heavy 후보를 분리한다. 검증: 기존 `run_matrix.sh --all`과 performance/stability full이 한 결과 계약 안에서 구분된다.
- [x] [anchor-runner-options] 필요한 경우 각 shell 또는 기존 runner에 `--anchor <lang>`와 `--direction server|client|both` 또는 동등한 개별 명령 조합을 추가한다. 검증: 수정 언어 중심 x5를 full 5x5 없이 실행할 수 있다.
- [x] [test-profile-docs] `agent-test/local/rules.md`와 관련 profile 문서에 4개 shell entrypoint와 주야간 분리 기준을 반영한다. 검증: 테스트 문서만 읽어도 네 라우팅의 명령과 판정 기준을 알 수 있다.
- [x] [result-report-contract] 결과 보고에 선택 이유, 실행 명령, 결과 record, skipped/nightly-pending 항목을 남긴다. 검증: 실행하지 않은 야간 full을 PASS로 오인하지 않는다.

## 완료 리뷰

- 상태: 승인됨
- 요청일: 2026-06-10
- 완료 근거:
  - `run_matrix.sh --cross --anchor <lang> --direction server|client|both`가 추가되어 언어 anchor x5를 full 5x5 없이 실행할 수 있다.
  - `run_test_by_change.sh`가 언어별 `functional-server-x5`, `functional-client-x5`, `functional-both-x5` 추천을 anchor matrix 실행으로 연결한다.
  - focused 검증 `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --cross --anchor go --direction server` PASS, 결과 기록 `agent-test/runs/20260610-104319-proto-socket-anchor-go-server-matrix.md`.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 2026-06-10 사용자 요청으로 완료 승인 후 archive 이동.

## 범위 제외

- 이번 마일스톤은 실제 성능 최적화를 수행하지 않는다.
- 모든 변경마다 full 5x5 또는 full performance를 강제하지 않는다.
- shell entrypoint는 기존 runner를 대체하는 대형 rewrite가 아니라, 사용자 요청 라우팅과 결과 계약을 고정하는 얇은 wrapper로 둔다.
- "기능 테스트 해봐"는 별도 사용자-facing 라우팅으로 확장하지 않고, `테스트 해봐`의 변경 기반 functional gate 또는 `전체 테스트 해봐`의 full functional gate로 처리한다.
- 야간 record 없이 장시간/대용량 baseline을 확정하지 않는다.
- C#/Swift 포팅, package registry release, 외부 CI/CD runner 연결은 포함하지 않는다.

## 작업 컨텍스트

- 관련 경로: `agent-ops/skills/project/run-proto-socket-test-matrix/SKILL.md`, `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh`, `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_performance.sh`, `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh`, `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/`, `agent-test/local/rules.md`, `agent-test/local/proto-socket-full-matrix.md`, `agent-test/local/proto-socket-performance-baseline.md`, `agent-test/runs/`
- 선행 작업: 없음
- 후속 작업: `야간 대용량 패킷 성능 기준선`, `대용량 WS/병렬 전송 후속 최적화`
- 표준선: 기본 사용자 요청은 "변경 내용 기반 자동 라우팅"으로 처리하고, 사용자가 명시적으로 범위를 지정하면 그 범위를 우선한다.
- agent-task 동기화:
  - 완료: `agent-task/archive/2026/06/m-change-aware-test-routing/01_change_classifier_core/complete.log` -> `last-pass-point`, `diff-source`, `path-domain-map`
  - 완료: `agent-task/archive/2026/06/m-change-aware-test-routing/02+01_risk_routing_rules/complete.log` -> `risk-escalation`
  - 완료: `agent-task/archive/2026/06/m-change-aware-test-routing/01_dart_web_coverage/complete.log` -> `dart-web-coverage`
  - 완료: `agent-task/archive/2026/06/m-change-aware-test-routing/02_full_functional_periodic/complete.log` -> `full-functional-periodic`
  - 완료(직접 처리): `functional-routing` anchor 보강 -> `anchor-language-x5`, `anchor-language-both-x5`; 검증=`bash -n .../run_test_by_change.sh`, focused dry-run server/client/transport, public-api unit smoke
  - 완료(직접 처리): `performance-stability-routing` daytime quick 보강 -> `daytime-performance-quick`, `daytime-stability-quick`; 검증=`bash -n .../run_test_by_change.sh`, focused temp repo route smoke(auto/speed/stability/full), `rg --sort path ...`
  - 계획 작성: `agent-task/m-change-aware-test-routing/03_nightly_periodic_contract/PLAN-cloud-G07.md` -> `nightly-heavy-routing`, `periodic-full-routing`
  - 완료: `agent-task/archive/2026/06/m-change-aware-test-routing/04_user_entrypoints_full_route/complete.log` -> `full-test-route`
  - 완료(직접 처리): `user-entrypoints` auto/speed/stability dry-run 정책 보강 -> `auto-test-route`, `speed-test-route`, `stability-test-route`; 검증=`bash -n .../run_test_by_change.sh`, focused temp repo route smoke(auto/speed/stability), `rg --sort path ...`
  - 계획 작성: `agent-task/m-change-aware-test-routing/05_user_entrypoint_runner_contract/PLAN-cloud-G07.md` -> `routing-skill`, `auto-test-shell`, `speed-test-shell`, `stability-test-shell`, `test-profile-docs`, `result-report-contract`
  - 완료(직접 처리): `skill-and-runner-contract` user-entrypoint runner 계약 동기화 -> `routing-skill`, `auto-test-shell`, `speed-test-shell`, `stability-test-shell`, `test-profile-docs`, `result-report-contract`; 검증=`bash -n .../run_test_by_change.sh .../run_speed_test.sh .../run_stability_test.sh .../run_full_test.sh`, `run_test_by_change.sh --route auto --dry-run`, `run_speed_test.sh --dry-run`, `run_stability_test.sh --dry-run`, `run_full_test.sh --dry-run`
  - 완료(직접 처리): `skill-and-runner-contract` anchor x5 실행 연결 -> `anchor-runner-options`; 검증=`bash -n .../run_matrix.sh .../run_test_by_change.sh .../run_speed_test.sh .../run_stability_test.sh .../run_full_test.sh`, invalid anchor/mode guard, direction-without-anchor guard, `run_matrix.sh --cross --anchor go --direction server` PASS (`agent-test/runs/20260610-104319-proto-socket-anchor-go-server-matrix.md`)
