proto-socket/agent-task/m-protocol-evolution-compatibility/02+01_legacy_alias/PLAN-cloud-G07.md
toki 6cdd0c3581 feat: protocol evolution compatibility implementation
- Add legacy alias support for backward compatibility
- Update ProtocolBuffer message definitions with new fields
- Implement fullname-based message routing
- Add alias fallback logic in all language clients (Dart, Go, Kotlin, Python, TypeScript)
- Update test suites for alias and fullname validation
- Add protocol sync verification tools
- Update documentation (PORTING_GUIDE, PROTOCOL, VERSIONING)
- Add agent task documentation for protocol evolution
2026-06-16 06:56:15 +09:00

10 KiB

Plan - ALIAS

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

이 plan은 full-name foundation 완료 후 legacy simple-name 수신 alias를 모든 지원 언어의 parser/listener/request/pending response 경로에 일관되게 적용한다. 구현 후 CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 내용으로 채운다. 사용자 결정이 필요한 blocker만 review stub의 사용자 리뷰 요청에 기록한다.

배경

마일스톤은 새 송신 기본값을 full proto name으로 바꾸되 기존 simple-name peer의 수신 호환성은 보존한다. 현재 Go/Kotlin/Python/TypeScript dispatch와 pending response 비교는 exact string lookup이므로 alias 규칙을 중앙화하지 않으면 parser만 통과하고 listener/request/response가 실패하는 부분 호환 상태가 된다.

사용자 리뷰 요청 흐름

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

Roadmap Targets

  • Milestone: agent-roadmap/milestones/protocol-evolution-compatibility.md
  • Task ids:
    • legacy-alias: parser lookup, listener/request handler routing, response type matching, pending expected type 비교에 동일 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/lib/src/communicator.dart, dart/test/communicator_test.dart
  • go/communicator.go, go/test/communicator_test.go
  • kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt, kotlin/src/test/kotlin/com/tokilabs/proto_socket/CommunicatorTest.kt
  • python/proto_socket/communicator.py, python/test/test_communicator.py
  • typescript/src/communicator.ts, typescript/test/communicator.test.ts
  • PROTOCOL.md, VERSIONING.md, PORTING_GUIDE.md

테스트 환경 규칙

test_env=local이다. 전체 protocol/API 호환성 변경이므로 최종 검증은 bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all이다. focused 중간 검증은 각 언어 unit test를 사용하되, 실행하지 못한 runtime은 명령과 차단 사유를 review stub에 기록한다.

테스트 커버리지 공백

  • Dart에는 package-qualified receive 테스트가 있으나 canonical alias collision 검사는 없다.
  • Go/Kotlin/Python/TypeScript는 simple alias receive, request handler alias, response alias, collision 초기화 실패 테스트가 부족하다.
  • parser alias만 추가하면 go/communicator.go:480-486, kotlin/.../Communicator.kt:421-427, python/.../communicator.py:519-524, typescript/src/communicator.ts:585-589의 pending expected type 비교가 계속 실패한다.

심볼 참조

  • 새 helper 후보: alias expansion/canonicalization helper per language.
  • 변경 call site: parser map initialization, AddListener/addListener, AddRequestListener/addRequestListener, dispatch lookup, _handle_response/handleResponse, parse.

분할 판단

분할 정책을 평가했다. 이 plan은 02+01_legacy_alias이며 predecessor 01_proto_fullname_foundationcomplete.log가 필요하다. 현재 작성 시점에는 predecessor가 missing이므로 구현 시작 전 agent-task/m-protocol-evolution-compatibility/01_proto_fullname_foundation/complete.log 또는 archive의 01_* complete.log를 확인해야 한다. 테스트 matrix 확장은 03+01,02_fullname_tests가 맡는다.

범위 결정 근거

이 plan은 alias 구현과 focused unit regression만 다룬다. Proto package/generated binding 수정은 predecessor 범위이며, cross-language scenario matrix 확장과 roadmap fullname-tests 완료는 후속 plan 범위다.

빌드 등급

cloud-G07: string identity가 parser, dispatch, pending correlation, public typed helpers를 관통하는 다중 언어 호환성 변경이다.

구현 체크리스트

  • 구현 시작 전 01_proto_fullname_foundation complete.log로 predecessor 완료를 확인한다.
  • 각 언어에 canonical full name과 legacy simple name을 같은 identity group으로 다루는 helper를 추가한다.
  • parser map 등록 시 full/simple alias를 모두 등록하고, simple alias가 서로 다른 full name으로 충돌하면 initialize 단계에서 실패시킨다.
  • listener/request handler 등록과 상호 배타 검사, inbound dispatch, pending response expected type 비교가 같은 alias 규칙을 사용하게 한다.
  • 각 언어 focused unit test로 simple legacy receive와 alias collision을 검증한다.
  • CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

[ALIAS-1] Alias Registry Helpers

문제: current lookup은 exact key 중심이다.

// go/communicator.go:497-503
parser := c.parserMap[typeName]
if parser == nil {
    return nil, fmt.Errorf("protobuf parser is not registered for type %s", typeName)
}

해결 방법: full name에서 마지막 segment를 simple alias로 계산하는 helper와 alias group lookup을 만든다. initialize에서 parserMap을 full/simple key로 normalize하되, 같은 simple alias가 다른 parser/full name으로 매핑되면 panic/error로 실패한다.

수정 파일 및 체크리스트:

  • go/communicator.go
  • kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt
  • python/proto_socket/communicator.py
  • typescript/src/communicator.ts
  • dart/lib/src/communicator.dart

테스트 작성: 각 언어 communicator unit에 collision test를 추가한다.

중간 검증:

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

[ALIAS-2] Routing And Pending Matching

문제: dispatch와 pending response expected type 비교가 exact string이면 legacy simple-name response가 실패한다.

// typescript/src/communicator.ts:580-589
if (typeName !== pending.expectedTypeName) {
  pending.reject(
    new Error(
      `response type mismatch for nonce ${responseNonce}: expected ${pending.expectedTypeName}, got ${typeName}`,
# python/proto_socket/communicator.py:375-376
req_handler = self._req_handlers.get(item.type_name)
listeners = list(self._handlers.get(item.type_name, []))

해결 방법: incoming wire type을 canonical group으로 resolve한 뒤 parser, handler, listener, pending expected type 비교에 같은 canonical value를 사용한다. Error message는 original wire value와 expected canonical value를 모두 포함한다.

수정 파일 및 체크리스트:

  • go/communicator.go
  • kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt
  • python/proto_socket/communicator.py
  • typescript/src/communicator.ts
  • dart/lib/src/communicator.dart

테스트 작성: request handler가 full name으로 등록되어도 incoming simple name을 처리하고, pending request expected full name이 incoming simple response를 수락하는 unit test를 추가한다.

중간 검증:

rg --sort path "typeName !=|expectedTypeName|expected_type_name|reqHandlers\\[|handlers\\[" go kotlin python typescript dart

[ALIAS-3] HeartBeat Alias Consistency

문제: HeartBeat parser/listener는 각 언어에서 별도 자동 등록되며 alias에서 빠지기 쉽다.

// dart/lib/src/protobuf_client.dart:52-55
parserMap.addAll({
  (HeartBeat).toString(): HeartBeat.fromBuffer,
});

해결 방법: HeartBeat도 proto_socket.HeartBeatHeartBeat alias를 같은 registry helper로 등록한다. 자동 heartbeat listener 등록도 canonical helper를 통해 등록한다.

수정 파일 및 체크리스트:

  • dart/lib/src/protobuf_client.dart
  • dart/lib/src/ws_protobuf_client_io.dart
  • dart/lib/src/ws_protobuf_client_web.dart
  • go/communicator.go
  • kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt
  • python/proto_socket/communicator.py
  • typescript/src/communicator.ts

테스트 작성: focused HeartBeat alias unit test는 있으면 추가하고, 없으면 전체 heartbeat tests가 canonical helper를 통해 통과하는지 기록한다.

중간 검증:

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

의존 관계 및 구현 순서

02+01_legacy_alias는 sibling 01_proto_fullname_foundation의 complete.log가 있어야 시작한다. active 후보는 agent-task/m-protocol-evolution-compatibility/01_proto_fullname_foundation/complete.log, archive 후보는 agent-task/archive/*/*/m-protocol-evolution-compatibility/01_*/complete.log다.

수정 파일 요약

파일 항목
dart/lib/src/communicator.dart, dart/lib/src/protobuf_client.dart, dart/lib/src/ws_protobuf_client_io.dart, dart/lib/src/ws_protobuf_client_web.dart ALIAS-1, ALIAS-2, ALIAS-3
go/communicator.go ALIAS-1, ALIAS-2, ALIAS-3
kotlin/src/main/kotlin/com/tokilabs/proto_socket/Communicator.kt ALIAS-1, ALIAS-2, ALIAS-3
python/proto_socket/communicator.py ALIAS-1, ALIAS-2, ALIAS-3
typescript/src/communicator.ts ALIAS-1, ALIAS-2, ALIAS-3
*/test/*communicator* ALIAS-1, ALIAS-2, ALIAS-3

최종 검증

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
bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all

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