# 2026-04-07 이슈 #4 — Normalizer Iteration 2 (Generator)
## 요약
Evaluator가 fail 처리한 두 항목(DoD #6 sidecar 로그, DoD #7 suspected-field 커버리지)을 수정.
## 변경 사항
- `src/Recordingtest.Normalizer/Normalizer.cs`
- `Normalize(string input, string profileName, string? sidecarPath = null)` 오버로드 추가.
- `sidecarPath`가 디렉터리면 `
/normalization.log`, 아니면 해당 경로에 작성.
- 포맷: `{RuleId}\tcount={Count}` 라인을 RuleId 사전순 정렬, 마지막 `total=` 라인.
- `src/Recordingtest.Normalizer/Rules.cs`
- `mask_volatile_settings` 규칙 추가. catalog에 등재된 휘발성 boolean/scalar 필드 (GridSnap, IsSidePanelVisible, GridColor.* 등)의 값을 ``로 마스킹.
- `src/Recordingtest.Normalizer/profiles/default.yaml`
- `mask_volatile_settings` 규칙을 sort_json_keys 직전에 추가.
- `tests/Recordingtest.Normalizer.Tests/RuleTests.cs`
- sidecar 파일/디렉터리 두 케이스 테스트 추가.
- default 적용 규칙 수 5 → 6 갱신, `mask_volatile_settings` 포함 검증.
- `tests/Recordingtest.Normalizer.Tests/CoverageTests.cs`
- `|| true` 단락 제거. 명시적 `Dictionary` 필드→규칙 매핑 도입.
- 매핑된 규칙이 default 프로파일에 실제로 존재하는지 검증.
- 매핑 없는 필드는 explicit 메시지로 fail.
## 매핑 (suspectedNondeterministicFields → 규칙)
- `AutoSaveFilePath`, `AutoSave_RecentFileName` → `normalize_paths`
- `CanOverrideWireColorWithFace`, `IsSidePanelVisible`, `OverrideFaceColor`, `Solar_IsLocalTime`, `VisibleGrid`, `GridSnap`, `MidpointOsnap`, `GridSpacing` → `mask_volatile_settings`
- `GridColor.{ALPHA,BLUE,GREEN,RED}`, `MajorGridColor.{ALPHA,BLUE,GREEN,RED}` → `mask_volatile_settings`
## 결과
- `dotnet build recordingtest.sln`: 경고 0, 오류 0
- `dotnet test tests/Recordingtest.Normalizer.Tests`: 10/10 pass (기존 8 + sidecar 2)
- 강화된 coverage 테스트가 명시적 매핑으로 실제 통과함 (단락 없음).
- sidecar 파일 작성 verified (파일 존재 + 라인 포맷 + 정렬 + total 합계).
## 소요 시간
약 15분
## Context 사용량
약 35k tokens
## 관련 이슈
#4