# Sprint Contract — engine-bridge-v3 ## Goal `Recordingtest.EgPlugin.ReflectionEngineStateProvider`를 v2의 stub에서 진짜 reflection 기반 매핑으로 격상한다. SUT(EG-BIM Modeler)의 HmEG 엔진 내부 상태(카메라/선택/씬)를 in-process plugin에서 reflection으로 읽어 HTTP `/state` 응답에 실제 값을 채운다. 이 값이 골든파일 sidecar JSON으로 들어가 회귀 비교의 핵심 결정성 신호가 된다. ## Background - v1: 정적 분석으로 HmEG 어셈블리 멤버 후보 8000+ 카탈로그 (`docs/engine-catalog/hmeg-candidates.json`). - v2: MEF plugin masquerade + HttpListener + 8 + 3 tests. `ReflectionEngineStateProvider`는 stub만. - v3: stub을 실매핑으로 교체. SUT 환경에서 라이브 검증 필요. ## Definition of Done 각 항목은 객관적으로 검증 가능해야 한다. ### D1. AppManager 발견 - plugin이 SUT 프로세스 안에서 `AppManager`(또는 동등한 root) 인스턴스를 reflection으로 획득한다. - 실패 시 `NullEngineStateProvider`로 안전하게 폴백하고 stderr에 한 번만 경고 로그. ### D2. CameraSnapshot 실매핑 - `GetCamera()`가 활성 뷰포트의 카메라 eye/target/up/fov를 **non-default 값**으로 반환. - 검증: 라이브 SUT에서 카메라 이동 후 두 번 호출 → 적어도 한 필드가 달라짐. ### D3. SceneSnapshot 실매핑 - `GetScene()`가 현재 문서의 객체 수와 (열린 경우) 문서 경로를 반환. - 검증: Box 1개 생성 후 `ObjectCount >= 1`, 새 문서 만들면 0. ### D4. SelectedIds 실매핑 - `GetSelectedIds()`가 현재 선택된 객체의 ID 리스트를 반환 (HmEG 내부 ID 또는 GUID 문자열). - 검증: 객체 선택 → 비어있지 않은 리스트. ### D5. 결정성 + 정규화 - 응답 JSON은 normalizer가 처리 가능한 형태 (정렬된 키, 안정된 부동소수점 표현). normalizer 규칙은 기존 `mask_volatile_settings` / 부동소수점 epsilon으로 충분한지 확인하고 부족하면 신규 규칙 등록. ### D6. 단위 테스트 - `ReflectionEngineStateProvider`의 reflection 경로를 mockable한 `IAppManagerAccessor` 추상화 뒤로 격리. - Fake accessor로 각 D2/D3/D4를 단위 테스트화 (라이브 SUT 없이 CI 가능). - 최소 6 신규 테스트, 전체 suite green (현 94+ → 100+). ### D7. 라이브 검증 - 사용자 SUT 환경에서 plugin 로드 → `/state` GET 응답에 D2/D3/D4 실값 확인. - 결과는 `docs/history/2026-04-08_engine-bridge-v3.md` 에 캡처. ### D8. 문서 - `docs/contracts/engine-bridge-v3.evaluation.md` (Evaluator 산출물) - `docs/guides/engine-bridge-deploy.md` 업데이트 (v3 응답 스키마 변경분) ## Out of scope - HmEG 내부 데이터 변경/쓰기 (read-only) - viewport 픽셀 캡처 (별개 모듈) - 새 HTTP 엔드포인트 (기존 `/state` 라우트만 채움) ## Interfaces ```csharp // 새 추상화 (D6) public interface IAppManagerAccessor { object? GetAppManager(); object? GetActiveDocument(); object? GetActiveViewport(); } // 기존 IEngineStateProvider 시그니처 유지 — 구현만 교체 ``` ## Evaluation plan 1. Evaluator는 `/contract engine-bridge-v3.md` 를 읽고 D1~D8을 차례로 채점. 2. D2/D3/D4는 단위 테스트(D6)로 검증 가능 → CI에서 자동 grade. 3. D7은 사용자 라이브 결과 첨부로 grade (orchestrator가 캡처 전달). 4. fail 1회 → Generator 재작업. 누적 3회 → 자동 중단. ## Risks - HmEG 내부 타입 이름이 obfuscation/난독화 가능 → reflection by-name이 깨질 수 있음. 완화: `hmeg-candidates.json` 카탈로그를 dictionary로 lookup, fallback 체인 다중화. - AppManager singleton 접근 패턴이 SUT 버전마다 다를 수 있음. 완화: D1에서 여러 후보 시도. - 카메라 좌표계가 right-handed/left-handed/up-axis 다양 → 정규화 규칙 필요. ## Estimated complexity 중. 단위 테스트만으로는 D2/D3/D4의 실매핑이 옳은지 확인 불가 — 라이브 검증(D7)이 critical path. 1차 사이클은 발견(discovery)에 시간 쏠릴 가능성.