Implement engine-bridge PoC v1 (#9)

- Add Recordingtest.EngineBridge library (IEngineSnapshot, HmEgSnapshot
  skeleton, MetadataLoader, CandidateFinder, CatalogWriter).
- Add Recordingtest.EngineBridge.Probe console exe that dumps
  hmeg-types.json and hmeg-candidates.json to docs/engine-catalog.
- Add Recordingtest.EngineBridge.Tests (xUnit, 6 tests).
- Add probe design doc with plugin-masquerade recommendation.
- Static analysis only; SUT is never executed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-07 15:48:58 +09:00
parent 13dc4109d8
commit 2a4f1d3fa4
16 changed files with 127677 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
# 2026-04-07 이슈 #9 — engine-bridge PoC v1 (Generator)
- **이슈**: kimminsung/recordingtest#9
- **소요 시간**: ~25분
- **Context 사용량**: ~55k tokens
- **역할**: Generator (Sprint Contract `docs/contracts/engine-bridge.md` 기준 구현)
## 범위
Sprint Contract `engine-bridge` PoC v1의 DoD 항목만 구현. 스코프 이탈 없음.
실제 런타임 attach / 값 캡처는 v2로 연기(계약 Out of scope).
## 산출물
### 라이브러리 `src/Recordingtest.EngineBridge/`
- `IEngineSnapshot.cs``IEngineSnapshot` 인터페이스 + `CameraState`/`SceneSummary` 레코드
- `HmEgSnapshot.cs` — skeleton (NotImplementedException), 리플렉션 앵커 상수
- `HmEgAssemblyHint="HmEG"`, `EditorManagerTypeHint="HmEGAppManager"`, etc.
- `MetadataLoader.cs``MetadataLoadContext` + `PathAssemblyResolver` (SUT root + runtime dir)
- `CandidateFinder.cs` — 4 카테고리 (select/camera/scene/render) 키워드 매칭
- `CatalogWriter.cs` — 결정적 정렬된 JSON 출력 (WriteIndented + LF normalize + trailing newline)
### Probe `src/Recordingtest.EngineBridge.Probe/`
- `Program.cs``--sut`/`--out` 인자, 기본값 `EG-BIM Modeler` / `docs/engine-catalog`
- SUT 폴더 없음 → exit 2
- 카탈로그 2개 작성 + 요약 출력
### 테스트 `tests/Recordingtest.EngineBridge.Tests/` (xUnit, 6개)
1. `MetadataLoader_LoadsHmegAssembly_WithoutExecution`
2. `CandidateFinder_FindsSelectionRelatedTypes`
3. `CatalogSerializer_OutputsSorted_Idempotent`
4. `HmEgSnapshot_DefaultInstance_ThrowsNotImplemented`
5. `CandidateCategories_AllFourPresent`
6. `HmEgSnapshot_Constants_MatchCatalog` (bonus)
SUT 탐지는 `AppContext.BaseDirectory`에서 위로 걸어 `EG-BIM Modeler/HmEG.dll`을 찾는다.
### 설계 문서 `docs/engine-bridge-probe-design.md`
- 5가지 옵션 비교 (ALC side-load / CLR profiler / 관리 인젝터 / **MEF plugin masquerade** / AutomationPeer)
- render-complete 신호 레이턴시 표
- 권고: **plugin masquerade** (PoC v2), CLR profiler는 fallback
### 카탈로그 `docs/engine-catalog/`
- `hmeg-types.json`, `hmeg-candidates.json`
### 솔루션
- `recordingtest.sln`에 3개 프로젝트 추가 (`dotnet sln add`)
## 실행 결과
- `dotnet build recordingtest.sln` → 경고 0, 오류 0
- 13 어셈블리 로드 (HmEG 2285 / EditorCore 416 / HmGeometry.V2 1669 / ...)
- 후보: camera=4226, render=3602, scene=3081, select=726
- 2회 실행 → `docs/engine-catalog` diff 없음 (결정성 확인)
- `dotnet test tests/Recordingtest.EngineBridge.Tests` → 6/6 통과
## 제약 준수
- SUT 실행 없음 (MetadataLoadContext 전용, 메타데이터만)
- `EG-BIM Modeler/`에 쓰기 없음
- `PROGRESS.md`/`PLAN.md` 미수정 (Generator는 Evaluator pass 전까지 손대지 않음)
- `TreatWarningsAsErrors` 유지, nullable 활성화
- 추가 런타임 의존성: `System.Reflection.MetadataLoadContext` 8.0.0 + `System.Text.Json` 8.0.5 만
## 남은 것 (Evaluator 몫)
- `docs/contracts/engine-bridge.evaluation.md` 작성
- pass 확정 후 `PROGRESS.md`/`PLAN.md` 갱신은 호출자가 수행