From f15a777402de1aa0f03b284b30f6b2555ded77a6 Mon Sep 17 00:00:00 2001 From: toki Date: Thu, 18 Jun 2026 07:20:09 +0900 Subject: [PATCH] fix(iop-client): remove short-name parser keys, use canonical full-name only - Remove 'ClientHelloRequest' and 'ClientHelloResponse' short-name keys from clientParserMap - Update parser_map_test.dart to verify full-name key presence and short-name key absence - All 27 Flutter tests pass, no whitespace errors --- .../CODE_REVIEW-local-G04.md | 85 ++++++++++++++----- apps/client/lib/iop_wire/parser_map.dart | 2 - .../client/test/iop_wire/parser_map_test.dart | 15 ++-- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/agent-task/proto-socket-iop-parser-alias/CODE_REVIEW-local-G04.md b/agent-task/proto-socket-iop-parser-alias/CODE_REVIEW-local-G04.md index 2c829a3..3c986a1 100644 --- a/agent-task/proto-socket-iop-parser-alias/CODE_REVIEW-local-G04.md +++ b/agent-task/proto-socket-iop-parser-alias/CODE_REVIEW-local-G04.md @@ -28,18 +28,18 @@ | 항목 | 완료 여부 | |------|---------| -| [IOP_PARSER_ALIAS-1] IOP client parser map canonical key 정리 | [ ] | -| [IOP_PARSER_ALIAS-2] parser map test expectation 갱신 | [ ] | -| [IOP_PARSER_ALIAS-3] IOP client 생성 경로 회귀 검증 | [ ] | +| [IOP_PARSER_ALIAS-1] IOP client parser map canonical key 정리 | [x] | +| [IOP_PARSER_ALIAS-2] parser map test expectation 갱신 | [x] | +| [IOP_PARSER_ALIAS-3] IOP client 생성 경로 회귀 검증 | [x] | ## 구현 체크리스트 -- [ ] `apps/client/lib/iop_wire/parser_map.dart`에서 `ClientHelloRequest`, `ClientHelloResponse` short-name key를 제거하고 `iop.ClientHelloRequest`, `iop.ClientHelloResponse` full-name key만 남긴다. -- [ ] `apps/client/test/iop_wire/parser_map_test.dart`가 full-name key 존재와 short-name key 부재를 검증하도록 갱신한다. -- [ ] parser 동작 검증도 full-name key를 통해 수행한다. -- [ ] `ClientWireClient` 생성 및 bootstrap 경로가 duplicate alias error 없이 통과하는지 targeted Flutter test로 확인한다. -- [ ] `apps/client` 전체 Flutter test 또는 실행 불가 사유를 `CODE_REVIEW-local-G04.md`에 기록한다. -- [ ] `CODE_REVIEW-local-G04.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. +- [x] `apps/client/lib/iop_wire/parser_map.dart`에서 `ClientHelloRequest`, `ClientHelloResponse` short-name key를 제거하고 `iop.ClientHelloRequest`, `iop.ClientHelloResponse` full-name key만 남긴다. +- [x] `apps/client/test/iop_wire/parser_map_test.dart`가 full-name key 존재와 short-name key 부재를 검증하도록 갱신한다. +- [x] parser 동작 검증도 full-name key를 통해 수행한다. +- [x] `ClientWireClient` 생성 및 bootstrap 경로가 duplicate alias error 없이 통과하는지 targeted Flutter test로 확인한다. +- [x] `apps/client` 전체 Flutter test 또는 실행 불가 사유를 `CODE_REVIEW-local-G04.md`에 기록한다. +- [x] `CODE_REVIEW-local-G04.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. ## 코드리뷰 전용 체크리스트 @@ -59,11 +59,15 @@ ## 계획 대비 변경 사항 -_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ +_계획에 따라 정확하게 구현했다. 추가 변경 사항 없음._ + +- `apps/client/lib/iop_wire/parser_map.dart`: short-name key 2개(`ClientHelloRequest`, `ClientHelloResponse`) 제거 +- `apps/client/test/iop_wire/parser_map_test.dart`: full-name key 존재/short-name key 부재 검증으로 테스트 기대값 변경 ## 주요 설계 결정 -_구현 에이전트가 주요 설계 결정 사항을 기록한다._ +- proto-socket core는 변경하지 않고, IOP consumer side의 explicit short-name parser entry만 canonical full-name 등록 방식으로 맞췄다. +- short-name 수신 호환은 proto-socket 내부 canonicalize 경로가 담당하므로, IOP parser map에서는 full-name key만 유지한다. ## 사용자 리뷰 요청 @@ -99,32 +103,75 @@ _구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 ### IOP_PARSER_ALIAS-1 중간 검증 ```bash -$ cd apps/client && flutter test test/iop_wire/client_wire_client_test.dart -(output) +$ cd /config/workspace/iop/apps/client && flutter test test/iop_wire/client_wire_client_test.dart +00:00 +0: loading /config/workspace/iop/apps/client/test/iop_wire/client_wire_client_test.dart +00:00 +0: ClientWireClient hello request mapping +00:00 +1: All tests passed! ``` ### IOP_PARSER_ALIAS-2 중간 검증 ```bash -$ cd apps/client && flutter test test/iop_wire/parser_map_test.dart -(output) +$ cd /config/workspace/iop/apps/client && flutter test test/iop_wire/parser_map_test.dart +00:00 +0: loading /config/workspace/iop/apps/client/test/iop_wire/parser_map_test.dart +00:00 +0: Parser map should contain ClientHelloRequest and ClientHelloResponse with canonical full-name keys +00:00 +1: All tests passed! ``` ### IOP_PARSER_ALIAS-3 targeted regression ```bash -$ cd apps/client && flutter test test/iop_wire/parser_map_test.dart test/iop_wire/client_wire_client_test.dart test/client_bootstrap_test.dart -(output) +$ cd /config/workspace/iop/apps/client && flutter test test/iop_wire/parser_map_test.dart test/iop_wire/client_wire_client_test.dart test/client_bootstrap_test.dart +00:00 +0: loading /config/workspace/iop/apps/client/test/iop_wire/parser_map_test.dart +00:00 +0: /config/workspace/iop/apps/client/test/iop_wire/parser_map_test.dart: Parser map should contain ClientHelloRequest and ClientHelloResponse with canonical full-name keys +00:00 +1: /config/workspace/iop/apps/client/test/iop_wire/client_wire_client_test.dart: ClientWireClient hello request mapping +00:00 +2: /config/workspace/iop/apps/client/test/client_bootstrap_test.dart: runIopClient can skip external integrations +00:01 +3: All tests passed! ``` ### 최종 검증 ```bash -$ cd apps/client && flutter test +$ cd /config/workspace/iop/apps/client && flutter test +00:00 +0: loading /config/workspace/iop/apps/client/test/client_bootstrap_test.dart +00:00 +0: runIopClient can skip external integrations +00:00 +1: runIopClient can skip external integrations +00:00 +2: runIopClient can skip external integrations +00:00 +3: runIopClient can skip external integrations +00:00 +4: runIopClient can skip external integrations +00:00 +5: runIopClient can skip external integrations +00:00 +6: runIopClient can skip external integrations +00:00 +7: runIopClient can skip external integrations +00:00 +8: runIopClient can skip external integrations +00:00 +9: Client App basic rendering and success handshake test +00:00 +10: Client App basic rendering and success handshake test +00:00 +10: auto-login failure does not block initialize +[MattermostHost] Mattermost auto-login failed: Bad state: credentials missing +00:00 +11: Client App basic rendering and success handshake test +00:00 +12: Client App basic rendering and success handshake test +00:00 +13: Client App basic rendering and success handshake test +00:01 +14: Client App basic rendering and success handshake test +00:01 +15: Client App basic rendering and success handshake test +00:01 +16: Client App basic rendering and success handshake test +00:01 +17: Client App connection error state test +00:01 +18: Client App opens IOP agent panel from the left rail +00:01 +19: Client App opens Edges panel and displays Edge details +00:02 +20: Client App opens Nodes panel and displays active Nodes and configurations +00:02 +21: Client App opens Execution/Logs panel and displays lifecycle events +00:02 +22: Client App refresh behavior when selected edge disappears +00:02 +23: Client App opens Operations & Domain Agents panel and verifies agents, operations history, and command triggering +00:02 +24: Client App handles unsupported or error command responses and shows error banner +00:03 +25: Client App gates agent.status and agent.command without required inputs +00:03 +26: Client App mobile screen layout verification for layout and overflow +00:03 +27: All tests passed! + $ git diff --check -(output) +(no output - no whitespace errors) ``` +- 검증 결과 요약: 전체 Flutter test 27개 모두 통과, git whitespace error 없음 +- 원격 runner 동기화 없이 local quick check만 수행: 원격 runner 동기화 없이 local Flutter test만 실행했다.proto-socket core 변경 없이 IOP client parser map만 변경했으므로 local 검증만으로 충분하다. + --- > **[IMPLEMENTING AGENT - BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** diff --git a/apps/client/lib/iop_wire/parser_map.dart b/apps/client/lib/iop_wire/parser_map.dart index 3bea912..9ecaddb 100644 --- a/apps/client/lib/iop_wire/parser_map.dart +++ b/apps/client/lib/iop_wire/parser_map.dart @@ -4,6 +4,4 @@ import '../gen/proto/iop/control.pb.dart'; final Map)> clientParserMap = { 'iop.ClientHelloRequest': ClientHelloRequest.fromBuffer, 'iop.ClientHelloResponse': ClientHelloResponse.fromBuffer, - 'ClientHelloRequest': ClientHelloRequest.fromBuffer, - 'ClientHelloResponse': ClientHelloResponse.fromBuffer, }; diff --git a/apps/client/test/iop_wire/parser_map_test.dart b/apps/client/test/iop_wire/parser_map_test.dart index 7315847..f05455a 100644 --- a/apps/client/test/iop_wire/parser_map_test.dart +++ b/apps/client/test/iop_wire/parser_map_test.dart @@ -4,20 +4,23 @@ import 'package:iop_client/gen/proto/iop/control.pb.dart'; void main() { test( - 'Parser map should contain ClientHelloRequest and ClientHelloResponse', + 'Parser map should contain ClientHelloRequest and ClientHelloResponse with canonical full-name keys', () { + // Canonical full-name keys must be present expect(clientParserMap.containsKey('iop.ClientHelloRequest'), isTrue); expect(clientParserMap.containsKey('iop.ClientHelloResponse'), isTrue); - expect(clientParserMap.containsKey('ClientHelloRequest'), isTrue); - expect(clientParserMap.containsKey('ClientHelloResponse'), isTrue); - // Verify parser works + // Short-name keys must NOT be present (proto-socket handles alias internally) + expect(clientParserMap.containsKey('ClientHelloRequest'), isFalse); + expect(clientParserMap.containsKey('ClientHelloResponse'), isFalse); + + // Verify parser works via canonical full-name keys final req = ClientHelloRequest() ..clientId = 'test-client' ..clientVersion = '1.0.0'; final reqBytes = req.writeToBuffer(); - final parserReq = clientParserMap['ClientHelloRequest']; + final parserReq = clientParserMap['iop.ClientHelloRequest']; expect(parserReq, isNotNull); final parsedReq = parserReq!(reqBytes) as ClientHelloRequest; expect(parsedReq.clientId, equals('test-client')); @@ -29,7 +32,7 @@ void main() { ..message = 'welcome'; final resBytes = res.writeToBuffer(); - final parserRes = clientParserMap['ClientHelloResponse']; + final parserRes = clientParserMap['iop.ClientHelloResponse']; expect(parserRes, isNotNull); final parsedRes = parserRes!(resBytes) as ClientHelloResponse; expect(parsedRes.ready, isTrue);