Problem
This repo's dominant recurring defect is view-model surface that is implemented, unit-tested, and reachable by nothing: no XAML binds it and no code reads it. The compiler cannot see it and view-model tests cannot see it, because the test exercises the property the same way the missing binding would have.
Six current instances, each verified by grepping the generated property name and its backing field across *.cs and *.xaml:
| Property |
State |
Consequence |
ContextMenuViewModel.ActivePresetId |
maintained at 4 sites, read at 0 |
the Menu Style buttons cannot show which preset is active |
SpeedTestViewModel.SpeedStatus |
declared, never assigned, never read |
dead declaration; the literal string SpeedStatus appears exactly once in the whole app |
DiskAnalyzerViewModel.TotalFolders |
assigned from a full recursive Entries.Sum(e => e.FolderCount) on every scan, read at 0 |
a recursive sum computed per scan and discarded |
DiskAnalyzerViewModel.CurrentFolder |
assigned and cleared on the scan path, read at 0 |
redundant: the next line puts the same value into StatusMessage, which is bound |
AboutViewModel.LatestNotes |
assigned from the release body on every update check, read at 0 |
the release notes are fetched and never shown |
AboutViewModel.ReleaseNote.Url |
populated for all 10 history entries, read at 0 |
the release-history cards are not clickable |
SystemHealthViewModel.DriveTarget.FreeGB |
populated per chkdsk drive, read at 0 |
free space is computed but absent from the type's own Display string, which is the only thing the view shows |
(Seven rows; ReleaseNote.Url and DriveTarget.FreeGB are plain properties rather than [ObservableProperty], same shape.)
Why the existing guard misses them
ArchitectureTests has a guard for exactly this class, and its file scope is Models/. Every instance above lives in ViewModels/ — where the defect actually recurs. Same weakness as the hardcoded ["TuneUpService.cs", "DeepCleanupService.cs"] list that let a third temp sweeper hide in a view-model for months (#2094): a guard that names its own scope can only ever catch what it was already looking at.
Expected behavior
The guard covers ViewModels/ too, and each instance is then resolved one of two ways:
- delete the ones that are genuinely redundant (
SpeedStatus, CurrentFolder, TotalFolders — refactor:, no behaviour change)
- bind the ones whose absence is a missing capability the user should have: the active Menu Style preset, clickable release-history entries, free space on the chkdsk drive picker, and the release notes on About. Those need a mockup first per the design workflow.
Splitting them that way is deliberate: widening the guard before resolving the hits would make it red on merge.
Evidence
Reference counts above are from grep -rnE "\b(Prop|_field)\b" --include=*.cs --include=*.xaml, excluding obj/. Note that [ObservableProperty] makes the generated name absent from the source entirely, so a grep for the property name returning only the field declaration is itself the proof it is never used.
Affected tabs
Context Menu, Speed Test, Disk Analyzer, About, System Health
Problem
This repo's dominant recurring defect is view-model surface that is implemented, unit-tested, and reachable by nothing: no XAML binds it and no code reads it. The compiler cannot see it and view-model tests cannot see it, because the test exercises the property the same way the missing binding would have.
Six current instances, each verified by grepping the generated property name and its backing field across
*.csand*.xaml:ContextMenuViewModel.ActivePresetIdSpeedTestViewModel.SpeedStatusSpeedStatusappears exactly once in the whole appDiskAnalyzerViewModel.TotalFoldersEntries.Sum(e => e.FolderCount)on every scan, read at 0DiskAnalyzerViewModel.CurrentFolderStatusMessage, which is boundAboutViewModel.LatestNotesAboutViewModel.ReleaseNote.UrlSystemHealthViewModel.DriveTarget.FreeGBDisplaystring, which is the only thing the view shows(Seven rows;
ReleaseNote.UrlandDriveTarget.FreeGBare plain properties rather than[ObservableProperty], same shape.)Why the existing guard misses them
ArchitectureTestshas a guard for exactly this class, and its file scope isModels/. Every instance above lives inViewModels/— where the defect actually recurs. Same weakness as the hardcoded["TuneUpService.cs", "DeepCleanupService.cs"]list that let a third temp sweeper hide in a view-model for months (#2094): a guard that names its own scope can only ever catch what it was already looking at.Expected behavior
The guard covers
ViewModels/too, and each instance is then resolved one of two ways:SpeedStatus,CurrentFolder,TotalFolders—refactor:, no behaviour change)Splitting them that way is deliberate: widening the guard before resolving the hits would make it red on merge.
Evidence
Reference counts above are from
grep -rnE "\b(Prop|_field)\b" --include=*.cs --include=*.xaml, excludingobj/. Note that[ObservableProperty]makes the generated name absent from the source entirely, so a grep for the property name returning only the field declaration is itself the proof it is never used.Affected tabs
Context Menu, Speed Test, Disk Analyzer, About, System Health