fix: stop raising findings no repair can clear - #50
Merged
Merged
Conversation
`save_scan_state` wrote to `%APPDATA%\WinMedic\last_scan.json` from any `App`, including the dozens the suite builds. Ticking a checkbox in a test therefore overwrote the scan the developer's own WinMedic had left behind β which is exactly what `SystemActions` exists to prevent for the browser, the UAC prompt and restore points. Persistence now sits behind the same seam: off by default, switched on by the desktop front end through `enable_real_system_actions`. That surfaced an integration test which assumed `App::new` starts with no issues. It restores the last scan, so on a machine that has actually run WinMedic `issues[0]` was a real finding rather than the one the test was about; it now clears the list first, the way the window tests already do. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nothing in the findings list could be ticked. The row was an `egui::Frame` whose response was handed a click sense afterwards, and a `Frame` registers its response *after* everything drawn inside it β so the row's click target sat on top of its own checkbox and swallowed every click meant for it. The boxes were drawn, they just could not be reached. The row is now a `Ui` with `UiBuilder::sense`, which registers itself before its contents and leaves the checkbox on top. Labels sense clicks for text selection and would have taken the row's place at the front, so selectable labels are off inside a row: a finding's title is a list entry, not prose. Ticking a box also moves the detail pane to that finding, the way `space` already did. The severity marks are drawn geometry rather than text: an octagon for critical, a rounded triangle for warning, a disc for info. egui's bundled fonts have no warning sign in them, so a written mark would have reached some machines as an empty box β the same reason the navigation icons are painted. They replace the `[!] CRITICAL` text badges in the list, the detail pane, the filter chips and the dashboard cards, and each carries its name for a screen reader. `Severity::badge` keeps the written form for the report file, which is now its only caller. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three findings came back unchanged after a scan, a repair and a reboot. Each one measured something its own repair could not touch. `wu_reboot_pending` tested whether the CBS `RebootPending` key exists. Windows creates it while servicing and files the outstanding work underneath; the restart consumes that work and empties the key, but leaves the key itself behind β permanently. On the machine this was found on it has sat there empty (0 subkeys, 0 values) while `Auto Update\RebootRequired` was absent, so WinMedic reported a restart that no restart could clear. The key now counts only while it still holds entries, and the two signals a boot really does clear β `Auto Update\RebootRequired` and `PendingFileRenameOperations` β are read alongside it. `pending_reboot_reason` takes the three as data so the verdict is testable without a registry to write into. `sys_clean_winsxs` was raised on DISM's own "cleanup recommended" verdict. That verdict also weighs backups and disabled features, which only `/ResetBase` reclaims and which WinMedic deliberately never touches; `StartComponentCleanup`, the one repair offered, removes superseded packages and nothing else. With 4.43 GB of backups and zero reclaimable packages the flag stayed "Yes" however often the repair ran, DISM answered "completed successfully" every time, and the audit log recorded a cleaned store. The finding now needs a reclaimable package to exist, the repair reads the store back before it claims anything, and both DISM calls pass `/English`: the output arrives in the console code page, so `from_utf8_lossy` had already cost the parser the store size and cache lines on a German machine. `sys_clean_setup_logs` reported "13.2 MB, 2 files" that were `CBS.log`, held open by TrustedInstaller since the log was created a month earlier, and `dism.log` β written by this module's own `AnalyzeComponentStore` call 34 seconds before the same scan measured it. Both the measurement and the sweep now ask Windows for `DELETE` access first, which is exactly the question `remove_file` asks later and, with a fully permissive share mode, blocks nobody. What is counted is what can be removed; a rotated `CbsPersist_*.log` still is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three findings survived their own repair: scan, repair, reboot, scan again β and there they were, unchanged. Each measured something the repair it offered could not touch.
Diagnosed against a real machine's
last_scan.json, audit log and registry rather than from first principles.wu_reboot_pendingβ a key the restart leaves behindThe check tested whether
Component Based Servicing\RebootPendingexists. Windows creates it while servicing and files the outstanding work underneath it; the restart consumes that work and empties the key, but leaves the key itself in place β permanently. On the machine this was found on it had been sitting there empty (0 subkeys, 0 values) whileAuto Update\RebootRequiredwas absent: a restart that no restart could clear.The CBS key now counts only while it still holds entries, and the two signals a boot really does clear are read alongside it β
Auto Update\RebootRequiredandPendingFileRenameOperations.pending_reboot_reasontakes the three signals as data, so the verdict is testable without a registry to write into.sys_clean_winsxsβ a repair that could not move the numberThe finding was raised on DISM's own "cleanup recommended" verdict. That verdict also weighs backups and disabled features, which only
/ResetBasereclaims and which WinMedic deliberately never touches.StartComponentCleanupβ the one repair offered here β removes superseded packages and nothing else. With 4.43 GB of backups and zero reclaimable packages the flag stayedYeshowever often the repair ran, DISM answered "completed successfully" every time, and the audit log recorded a cleaned store./English. The output arrives in the console code page, sofrom_utf8_lossyhad already cost the parser the store-size and cache lines on a German machine β visible in the finding's details as a missing "Explorer size"sys_clean_setup_logsβ the scan finding its own log"13.2 MB, 2 files" were
CBS.log, held open by TrustedInstaller since the log was created a month earlier, anddism.logβ written by this module's ownAnalyzeComponentStorecall 34 seconds before the same scan measured it.Both the measurement and the sweep now ask Windows for
DELETEaccess first. That is exactly the questionremove_fileasks later, and with a fully permissive share mode the probe blocks nobody. What is counted is what can be removed; a rotatedCbsPersist_*.logstill is.Checks
cargo fmt,cargo clippy --all-targets -D warningsand the full suite pass: 361 unit + 266 integration tests, 8 of them new for these three cases β an empty CBS key, a CBS key still holding work, a recommendation with nothing reclaimable, a cleanup that reclaimed nothing, and a log held open withFILE_SHARE_NONEthat is neither counted nor reported as a failed deletion.π€ Generated with Claude Code