Lays down the Generic / HmEG-aware / App-specific separation that lets us
target other HmEG-hosting WPF applications later, and lands the v3 engine
state provider on top of it.
Architecture rule (CLAUDE.md §8.1, new): every module belongs to exactly one
of three tiers — Generic / HmEG-aware / App-specific (e.g. EgBim). Dependency
direction is strictly App-specific → HmEG-aware → Generic. Generic must not
reference HmEG.dll; HmEG-aware must not reference any per-app assembly.
This commit is the first incremental step:
+ src/Recordingtest.Bridge.Abstractions/ (Generic, new csproj)
IEngineStateProvider, CameraSnapshot, SceneSnapshot,
NullEngineStateProvider — extracted from EgPlugin so the generic core
owns the contract. Zero SUT references.
+ src/Hmeg/Recordingtest.Hmeg.Bridge/ (HmEG-aware, new csproj)
HmegDirectStateProvider — IEngineStateProvider implemented against
the HmEG public API (Space, HmEGViewport, ISelectable, ModelBase.Uid).
Decoupled from any specific host app via Func<Space?>/Func<HmEGViewport?>
lambdas; the EgBim plugin host supplies them. Reusable for any other
WPF application that hosts HmEG.
Selection traversal walks Space.Children and collects ModelBase.Uid
for nodes whose ISelectable.IsSelected is true. We deliberately type
nodes as object + late-bound Uid lookup to avoid pulling MemoryPack
into the dependency graph.
+ tests/Hmeg/Recordingtest.Hmeg.Bridge.Tests/
5 unit tests covering null lambdas, throwing lambdas, document path
provider, and constructor null arg validation.
+ src/Recordingtest.EgPlugin/ChainedEngineStateProvider.cs
Wraps two providers; falls back from Hmeg.Direct to the existing
Reflection accessor when the primary returns empty/default. Lets us
land the new wire-up before the EgBim adapter Q1~Q7 lookups are
filled in. 7 new tests.
+ src/Recordingtest.EgPlugin/IAppManagerAccessor.cs
Reflection accessor abstraction (preserved as the v3 fallback). Looks
up Editor.AppManager.AppManager via well-known Instance/Current
property names. Unit-testable through a fake.
~ src/Recordingtest.EgPlugin/IEngineStateProvider.cs
Type definitions removed (now in Bridge.Abstractions); only the
reflection-based provider remains. ReflectionEngineStateProvider
delegates everything to IAppManagerAccessor.
~ src/Recordingtest.EgPlugin/HmEgBridgePlugin.cs
BuildProvider() picks ChainedEngineStateProvider(Hmeg.Direct,
Reflection). The HmEG-aware lambdas are stubs (return null) until the
next step wires the EgBim adapter; the chain falls through to the
reflection path so behaviour matches v2 for now.
+ docs/contracts/engine-bridge-v3.md — Sprint Contract
+ docs/contracts/generic-sut-split.md — Sprint Contract for the
remaining mass-rename / folder move (step 2, deferred).
+ docs/hmeg-api-survey.md — Read-only survey of the HmEG
public API (Space, ModelBase, HmEGViewport, IHmCamera, IPlugin) used
to design HmegDirectStateProvider. Open Q1~Q7 listed.
Tests: 94 → 115 passing, 0 failing. The new HmEG-aware test project copies
HmEG.dll next to its output (Private=true) since it runs out-of-process.
Step 2 (deferred to next session): mass-rename
src/Recordingtest.EgPlugin → src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost + .Adapter
src/Recordingtest.EngineBridge → src/Hmeg/Recordingtest.Hmeg.Catalog
src/Recordingtest.EngineBridge.Client → split (Generic + Hmeg)
plus Recordingtest.Architecture.Tests to enforce the §8.1 dependency rule.
Ref: #10 follow-up, #14 follow-up.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.4 KiB
7.4 KiB
PROGRESS.md — recordingtest
에이전트 간 공유 메모리. 세션 시작 시 PLAN.md와 함께 반드시 읽을 것. 작업 상태만 기록한다. 결정의 근거는
docs/history/, 전략은CLAUDE.md/ 메모리 참조.
저장소: https://gitea.hmac.kr/kimminsung/recordingtest
SUT: EG-BIM Modeler/ (git 제외, 로컬 동봉)
현재 이슈: #2 컨텍스트 엔지니어링 & AI 개발환경 셋업
Done
| 날짜 | 항목 | 산출물 |
|---|---|---|
| 2026-04-07 | 히스토리 훅 설정 | docs/history/2026-04-07_히스토리-훅-설정.md |
| 2026-04-07 | 이슈 #2 리서치 & 에이전트 분해 | 메모리 project_recordingtest_plan.md |
| 2026-04-07 | 구현 고려사항 정리 (8개 카테고리) | 히스토리 |
| 2026-04-07 | Golden-file 회귀 전략 채택 | 메모리 project_recordingtest_strategy.md |
| 2026-04-07 | CLAUDE.md 초안 + §0 협업 규칙 | CLAUDE.md |
| 2026-04-07 | SUT(EG-BIM Modeler) 정적 분석 | 메모리 project_sut_egbim_modeler.md |
| 2026-04-07 | .claude/ agents·commands·skills·hooks 셋업 |
.claude/ |
| 2026-04-07 | Harness design 채택 (Planner/Generator/Evaluator) | CLAUDE.md §0.1, .claude/agents/planner.md, evaluator.md |
| 2026-04-07 | SUT 폴더 .gitignore |
.gitignore |
| 2026-04-07 | 초기 Sprint Contracts 5건 작성 | docs/contracts/*.md |
| 2026-04-07 | SUT 카탈로그 v0 (정적) | docs/sut-catalog/catalog.md, plugins.md |
| 2026-04-07 | 솔루션 스캐폴드(sut-prober PoC 타깃) | recordingtest.sln, src/Recordingtest.SutProber/ |
| 2026-04-07 | sut-prober PoC 구현 (Generator) | src/Recordingtest.SutProber/, docs/sut-catalog/{plugins,json-configs,assemblies}.json |
| 2026-04-07 | sut-prober PoC Evaluator pass (#3) | docs/contracts/sut-prober.evaluation.md |
| 2026-04-07 | diff-reporter PoC + Evaluator pass (#5) | src/Recordingtest.DiffReporter*/, docs/contracts/diff-reporter.evaluation.md |
| 2026-04-07 | normalizer PoC + Evaluator pass v2 (#4) — sidecar log, explicit coverage mapping, 6 rules | src/Recordingtest.Normalizer/, docs/contracts/normalizer.evaluation.md |
| 2026-04-07 | player PoC + Evaluator pass (#7) — 6 tests, no fixed sleeps, fake host | src/Recordingtest.Player/, docs/contracts/player.evaluation.md |
| 2026-04-07 | recorder PoC + Evaluator pass v2 (#6) — drag state machine, focus events, ts/raw_coord | src/Recordingtest.Recorder/, docs/contracts/recorder.evaluation.md |
| 2026-04-07 | test-runner PoC + Evaluator pass (#8) — 5-module E2E 파이프라인, 6 tests, DI | src/Recordingtest.Runner/, docs/contracts/test-runner.evaluation.md |
| 2026-04-07 | engine-bridge PoC v1 + Evaluator pass (#9) — 정적 분석, HmEG 내부 후보 8000+, API 초안 | src/Recordingtest.EngineBridge*/, docs/engine-catalog/, docs/engine-bridge-probe-design.md |
| 2026-04-07 | engine-bridge v2 + Evaluator pass (#10) — MEF plugin masquerade, HttpListener, HmEgHttpSnapshot, 11 tests | src/Recordingtest.EgPlugin/, src/Recordingtest.EngineBridge.Client/, docs/guides/engine-bridge-deploy.md |
| 2026-04-07 | 라이브 SUT smoke test 가이드 작성 | docs/guides/smoke-test.md |
| 2026-04-07 | Smoke test 1회차 — integration gap 4개 발견 (recorder target null, VK 코드, player enum, null guard) | scenarios/box-create.yaml |
| 2026-04-07 | Smoke gap fix + Evaluator pass (#11) — STAThread, KeyTranslator, 60 tests, regression trap 검증 | commit 139fbbc |
| 2026-04-07 | Smoke test 1회차 — recorder PID attach + UIA target 정상 (box-v4), player 재생 부분 실패 | docs/history/2026-04-07_smoke-1회차-결과.md, scenarios/box-v4*.yaml |
| 2026-04-07 | Smoke 2차 gap fix + Evaluator pass (#12) — full-path resolver, type target inheritance, window filter, UTF-8 BOM-less, 71 tests | commit 8784fec |
| 2026-04-07 | sut-prober snake_case + scaffolding review 1회차 | commit 0f0324e |
| 2026-04-07 | normalizer follow-ups + Evaluator pass — float epsilon 구성화 + JSON-path 마스크 스코핑, 77 tests | commit eeee3c2 |
| 2026-04-08 | Smoke test 2회차 — 첫 E2E 성공 🎉 Box geometry 생성 확인 | docs/history/2026-04-08_smoke-2회차-첫-e2e-성공.md, scenarios/box-v5*.yaml |
| 2026-04-08 | 이슈 #13 Gap E/F/G fix — HotkeyParseTests + FocusEventFilter + WindowPointResolver, 94 tests | docs/history/2026-04-08_이슈13-smoke3-fix-generator.md |
| 2026-04-08 | 이슈 #14 Raw 시나리오 E2E 성공 🎉 수동 cleanup 없이 box-v6.yaml 재생으로 Box 생성 | player: null-target fallback + foreground switch + leading alt+tab strip + timing preservation, 24 player tests |
| 2026-04-09 | engine-bridge v3 D1/D6 scaffold (reflection accessor + 9 tests, EgPlugin) | IAppManagerAccessor, ReflectionEngineStateProvider, 14 EgPlugin tests |
| 2026-04-09 | HmEG 소스 survey + docs/hmeg-api-survey.md |
Q1~Q7 식별, HmegDirectStateProvider 설계 근거 |
| 2026-04-09 | 3-tier 분리 1단계 (incremental) — Recordingtest.Bridge.Abstractions (Generic) + Recordingtest.Hmeg.Bridge (HmEG-aware) 신설, HmegDirectStateProvider + ChainedEngineStateProvider wire-up, 115 tests |
CLAUDE.md §8.1 + commit pending |
In progress
- 3-tier 분리 (incremental, 1단계 완료, 2단계 대기)
- 1단계 ✅: 새 계층 모듈 신설 (
Recordingtest.Bridge.Abstractions,Recordingtest.Hmeg.Bridge, 테스트), 인터페이스 추출, EgPlugin이 HmEG-aware provider chain 사용. 115 tests green. commit pending. - 2단계 ⏳: 기존
Recordingtest.EgPlugin→src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost+.Adapter폴더/네임스페이스 이동,Recordingtest.EngineBridge→src/Hmeg/Recordingtest.Hmeg.Catalog,Recordingtest.EngineBridge.Client분할, ArchitectureTests. 다음 세션 작업.
- 1단계 ✅: 새 계층 모듈 신설 (
- engine-bridge v3 라이브 검증 — 1단계 wire-up 완료 후 EgBim adapter에서 Space/Viewport 람다 실 매핑 (Q1~Q7 답 필요). 사용자 환경에서
curl /scene /camera /selection.
Follow-ups
sut-prober JSON naming snake_case— commit0f0324enormalizer: mask_volatile_settings JSON-path 스코핑— commiteeee3c2normalizer: float epsilon 구성화— commiteeee3c2- diff-reporter: 실제
diff-triager에이전트 통합 테스트. non-blocking. - recorder/player: 라이브 SUT 수동 smoke test — 60 FPS / 10회 중 9회 reliability DoD는 샌드박스 unit test 불가, 실제 환경에서 검증 필요.
- player:
wait_forUIA 이벤트 매핑 강화 (현재 host passthrough). - player:
UiaPlayerHostuia_path resolver가 마지막@AutomationId만 사용 — 전체 ancestor chain 지원 필요. - recorder: IME 조합 키 처리 (contract risks).
player: foreground settle 안정화— 능동 대기(GetForegroundWindowpolling 2s + 100ms settle)로 전환, 1차 재생 성공 확인- [~] recorder Gap I-1 — UIA
Automation.FocusedElement폴링 PoC 시도(commit pending). 결과: SUT의 CommandBox 등 AutomationPeer 미부착 컨트롤은 UIA 외부에서 본질적으로 못 봄. deferred — generic WPF DLL injection 또는 SUT-side AutomationPeer 부착 PoC가 필요. 현재는 Player fallback(null target → OS 키 입력 / raw_coord 클릭)이 공식 전략.
Blocked
(없음)
Recent regression runs
(러너 미구현 — /regress 사용 불가)
Scaffolding review
- 마지막 감사: 2026-04-07 (초기 셋업)
- 다음 감사 권장: PoC 3개 완료 후