<!-- task=m-protocol-evolution-compatibility/03+01,02_fullname_tests plan=0 tag=TEST -->

# Plan - TEST

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

이 plan은 identity 에픽의 검증 완성 작업이다. foundation과 alias 구현이 완료된 뒤 full name 송수신, simple legacy 수신, request/response alias 호환, alias 충돌 감지를 동일 언어와 크로스 언어 테스트에 고정한다. 구현 후 review stub의 구현 에이전트 소유 섹션을 반드시 채운다.

## 배경

full-name identity 전환은 단위 테스트만으로는 부족하다. 지원 언어 모두가 같은 wire `typeName`을 보내고, legacy simple-name을 수신 호환으로 유지하며, cross-language matrix에서 같은 시나리오를 통과해야 roadmap task를 완료할 수 있다.

## 사용자 리뷰 요청 흐름

구현 중 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 사용자 질문은 금지이며, code-review가 `USER_REVIEW.md` 작성 여부를 판단한다.

## Roadmap Targets

- Milestone: `agent-roadmap/milestones/protocol-evolution-compatibility.md`
- Task ids:
  - `fullname-tests`: full name 송수신, simple name legacy 수신, request/response alias 호환, alias 충돌 감지 동일 언어 및 크로스 언어 테스트
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-test/local/rules.md`
- `agent-test/local/proto-socket-full-matrix.md`
- `agent-roadmap/milestones/protocol-evolution-compatibility.md`
- `dart/test/communicator_test.dart`, `dart/crosstest/dart_go.dart`, `dart/crosstest/dart_kotlin.dart`, `dart/crosstest/dart_python.dart`, `dart/crosstest/dart_typescript.dart`, `dart/crosstest/dart_web.dart`
- `go/test/communicator_test.go`, `go/test/test_helpers_test.go`, `go/crosstest/*.go`
- `kotlin/src/test/kotlin/com/tokilabs/proto_socket/CommunicatorTest.kt`, `kotlin/src/test/kotlin/com/tokilabs/proto_socket/TestHelpers.kt`, `kotlin/crosstest/*.kt`
- `python/test/test_communicator.py`, `python/test/test_tcp.py`, `python/crosstest/*.py`
- `typescript/test/communicator.test.ts`, `typescript/test/base_client.test.ts`, `typescript/test/tcp.test.ts`, `typescript/crosstest/*.ts`
- `tools/check_proto_sync.sh`, `tools/generate_proto.sh`

### 테스트 환경 규칙

`test_env=local`이다. `proto-socket-full-matrix` profile을 읽었고, 필수 최종 검증은 `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all`이다. 결과 record는 `agent-test/runs/YYYYMMDD-HHMMSS-proto-socket-full-matrix.md`에 남아야 하며, Dart.web/WSS client coverage가 포함되어야 한다. 실행하지 않은 항목은 PASS로 기록하지 않는다.

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

- Dart의 package-qualified receive unit은 `example.TestData` 중심이라 canonical `proto_socket.TestData`와 simple legacy 충돌을 모두 덮지 않는다.
- Go/Kotlin/Python/TypeScript unit에는 alias collision 감지 테스트가 없다.
- Cross-language runners는 send-push/request-response 성공은 보지만 full-name wire value와 simple legacy receive를 명시 검증하지 않는다.

### 심볼 참조

테스트에서 참조하는 identity symbols: `TypeNameOf`, `typeNameOf`, `type_name_of`, `TestDataSchema.typeName`, `HeartBeatSchema.typeName`, Dart `qualifiedMessageName`. rename/remove 없음.

### 분할 판단

분할 정책을 평가했다. 이 plan은 `03+01,02_fullname_tests`이며 predecessor `01_proto_fullname_foundation`과 `02+01_legacy_alias`의 complete.log가 필요하다. 현재 작성 시점에는 둘 다 missing이다. 구현 전 active 또는 archive complete.log로 두 predecessor를 확인해야 한다.

### 범위 결정 근거

이 plan은 검증 추가와 필요한 test helper 정리만 한다. Production alias/typeName 구현 변경은 predecessor 범위이며, evolution 에픽 테스트는 다루지 않는다.

### 빌드 등급

`cloud-G07`: 전체 local matrix와 browser/WSS coverage, 다중 언어 test runner 변경을 검토해야 한다.

## 구현 체크리스트

- [ ] 구현 시작 전 `01_proto_fullname_foundation`과 `02+01_legacy_alias` complete.log를 확인한다.
- [ ] Dart/Go/Kotlin/Python/TypeScript 동일 언어 test에 canonical full-name 송신과 simple legacy 수신을 추가한다.
- [ ] 각 언어 test에 request/response alias 호환과 alias collision 초기화 실패를 추가한다.
- [ ] crosstest runner가 full-name wire value를 로깅/검증하고, legacy simple receive smoke를 각 server-capable 언어에 추가한다.
- [ ] full matrix를 실행하고 record path와 PASS/FAIL matrix를 review stub에 붙인다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [TEST-1] Same-Language Identity Tests

문제: simple/full/collision behavior가 언어별 unit에 균일하게 없다.

```dart
// dart/test/communicator_test.dart:200-211
test('sendRequest accepts package-qualified response typeName', () async {
  final communicator = _FakeCommunicator(packageQualifiedParser: true);
...
  communicator.onReceivedData(
    'example.TestData',
```

해결 방법: 각 언어 unit에 canonical `proto_socket.TestData` 송신 assertion, simple `TestData` legacy receive, request/response alias, collision failure를 추가한다. Dart의 `example.TestData` 테스트는 canonical package와 collision case로 갱신한다.

수정 파일 및 체크리스트:

- [ ] `dart/test/communicator_test.dart`
- [ ] `go/test/communicator_test.go`
- [ ] `kotlin/src/test/kotlin/com/tokilabs/proto_socket/CommunicatorTest.kt`
- [ ] `python/test/test_communicator.py`
- [ ] `typescript/test/communicator.test.ts`

테스트 작성: 필수. 각 behavior별 assertion을 명시한다.

중간 검증:

```bash
dart test test/communicator_test.dart
go test ./...
cd kotlin && ./gradlew test
cd python && python3 -m pytest -q
cd typescript && npm run check && npm test
```

### [TEST-2] Cross-Language Wire Identity Coverage

문제: crosstest는 성공 여부만 보고 full-name wire value를 contract로 고정하지 않는다.

```go
// go/crosstest/go_dart.go:41-49
toki.TypeNameOf(&packets.TestData{}): func(b []byte) (proto.Message, error) {
...
fmt.Printf("INFO typeName go=%s\n", toki.TypeNameOf(&packets.TestData{}))
```

해결 방법: 각 runner가 `INFO typeName <lang>=proto_socket.TestData`를 출력하거나 assert하고, server/client receive path가 full name으로 동작함을 확인한다. runner output parser가 INFO line을 무시하지 않는다면 expected value를 검증하게 한다.

수정 파일 및 체크리스트:

- [ ] `dart/crosstest/*.dart`
- [ ] `go/crosstest/*.go`
- [ ] `kotlin/crosstest/*.kt`
- [ ] `python/crosstest/*.py`
- [ ] `typescript/crosstest/*.ts`
- [ ] `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/*` only if matrix parsing must record identity lines

테스트 작성: 필수. Matrix runner 변경 시 runner selfcheck/focused matrix를 실행한다.

중간 검증:

```bash
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_test_by_change.sh --route auto --dry-run
```

### [TEST-3] Full Matrix Evidence

문제: roadmap `fullname-tests`의 검증 문구는 전체 matrix PASS를 요구한다.

해결 방법: full matrix를 한 번 실행하고 record path, Proto sync, 동일언어, 언어 PASS 매트릭스, Dart.web/WSS rows를 review stub에 붙인다. 실패하면 실패 행과 재현 명령을 기록하고 자동으로 고칠 수 있는 범위면 고친다.

수정 파일 및 체크리스트:

- [ ] `agent-test/runs/<generated>-proto-socket-full-matrix.md` 생성 여부 확인
- [ ] `CODE_REVIEW-cloud-G07.md` 검증 결과 섹션에 record path와 핵심 표 요약 붙이기

테스트 작성: 새 test 추가가 아니라 검증 evidence 수집이다.

중간 검증:

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

## 의존 관계 및 구현 순서

`03+01,02_fullname_tests`는 sibling `01_proto_fullname_foundation`과 `02+01_legacy_alias`의 complete.log가 있어야 시작한다. active 후보는 `agent-task/m-protocol-evolution-compatibility/01_proto_fullname_foundation/complete.log`와 `agent-task/m-protocol-evolution-compatibility/02+01_legacy_alias/complete.log`이며, archive 후보는 같은 task group 아래 `01_*`, `02+*` complete.log다.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `dart/test/communicator_test.dart`, `go/test/communicator_test.go`, `kotlin/src/test/kotlin/com/tokilabs/proto_socket/CommunicatorTest.kt`, `python/test/test_communicator.py`, `typescript/test/communicator.test.ts` | TEST-1 |
| `dart/crosstest/*`, `go/crosstest/*`, `kotlin/crosstest/*`, `python/crosstest/*`, `typescript/crosstest/*` | TEST-2 |
| `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/*` | TEST-2, only if parser/reporting changes are required |
| `agent-test/runs/*proto-socket-full-matrix.md` | TEST-3 evidence output |

## 최종 검증

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

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