Problem
Found while fixing #1615 (Shortcut Cleaner's "Delete Selected" wore SecondaryButton). That was not an
isolated slip, but the class is much narrower than a first sweep suggests, and worth writing down
precisely so nobody re-litigates it.
Two buttons perform an immediate, unrecoverable change while looking like an ordinary action:
| View |
Button |
Command |
What it does at click time |
Style |
| Audio Mixer |
Delete |
DeletePresetCommand |
rewrites the presets file on disk straight away; the code's own comment says "there is no undo" |
GhostButton |
| Environment Variables |
Delete |
DeleteVariableCommand |
removes the user or machine environment variable |
GhostButton |
Both already show a confirmation dialog, so the safety gate is present. What is missing is the visual
signal before the click: in both rows the delete button is the least conspicuous control.
Separately, danger is marked two different ways. Process Manager's per-row kill button is a
GhostButton with Foreground="{DynamicResource Danger}" — red text on a transparent button. It is the
only place in the app that marks danger this way; everywhere else uses DangerButton. It is not
unmarked, so this is a uniformity issue rather than a safety one, but it means a future reader has two
patterns to choose from for one meaning.
What is NOT wrong (checked, so it is not re-raised)
A label sweep flags 18 buttons; most are false positives, and I confirmed each against its command:
RemoveDirectory (Environment Variables), RemoveEntry (DNS & Hosts), RemoveItem (File Shredder)
and RemoveTarget (Ping) only mutate an in-memory collection. The change reaches the system through a
separate explicit Apply/Save. Staged edits are not destructive at click time, so GhostButton is
correct for all four.
Purge standby list (Standby Memory) drops a memory cache. No user data is involved; PrimaryButton
is right.
RemoveExclusion (Defender) increases protection.
Select common bloat (Debloater) only changes a selection.
Why there is no guard for this
I tried to make it mechanical and both candidate rules fail against the real code, so this needs human
judgement per button:
- By label — the regex that catches "Delete"/"Remove"/"Shred" also catches "Deselect All",
"Remove duplicates" and "Save current as preset". Precision is far too low to gate a build on.
- By confirmation dialog — appealing, since a command calling
DialogService.Instance.Confirm
looks like the app marking its own irreversible actions. It does not hold: of 25 buttons bound to a
confirming command, only 3 wear a destructive style, and the other 22 are mostly correct as they are.
SelectAll confirms because selecting everything is a big action, and ApplyChanges confirms because
it writes staged edits. Confirmation means "this is significant", not "this destroys something".
So this stays a review judgement rather than a CI check. Recording the two failed rules here so the next
person does not spend the same time rediscovering that they do not work.
Expected behavior
The two buttons above use DangerButton, matching Shortcut Cleaner, Debloater, Uninstaller, File
Shredder, Scheduled Maintenance, Edge/OneDrive and File Lock. Process Manager's kill button picks one
mechanism — most likely DangerButton sized down for a row, rather than a one-off red foreground.
Affected tab
Audio Mixer, Environment Variables, Process Manager.
Problem
Found while fixing #1615 (Shortcut Cleaner's "Delete Selected" wore
SecondaryButton). That was not anisolated slip, but the class is much narrower than a first sweep suggests, and worth writing down
precisely so nobody re-litigates it.
Two buttons perform an immediate, unrecoverable change while looking like an ordinary action:
DeletePresetCommandGhostButtonDeleteVariableCommandGhostButtonBoth already show a confirmation dialog, so the safety gate is present. What is missing is the visual
signal before the click: in both rows the delete button is the least conspicuous control.
Separately, danger is marked two different ways. Process Manager's per-row kill button is a
GhostButtonwithForeground="{DynamicResource Danger}"— red text on a transparent button. It is theonly place in the app that marks danger this way; everywhere else uses
DangerButton. It is notunmarked, so this is a uniformity issue rather than a safety one, but it means a future reader has two
patterns to choose from for one meaning.
What is NOT wrong (checked, so it is not re-raised)
A label sweep flags 18 buttons; most are false positives, and I confirmed each against its command:
RemoveDirectory(Environment Variables),RemoveEntry(DNS & Hosts),RemoveItem(File Shredder)and
RemoveTarget(Ping) only mutate an in-memory collection. The change reaches the system through aseparate explicit Apply/Save. Staged edits are not destructive at click time, so
GhostButtoniscorrect for all four.
Purge standby list(Standby Memory) drops a memory cache. No user data is involved;PrimaryButtonis right.
RemoveExclusion(Defender) increases protection.Select common bloat(Debloater) only changes a selection.Why there is no guard for this
I tried to make it mechanical and both candidate rules fail against the real code, so this needs human
judgement per button:
"Remove duplicates" and "Save current as preset". Precision is far too low to gate a build on.
DialogService.Instance.Confirmlooks like the app marking its own irreversible actions. It does not hold: of 25 buttons bound to a
confirming command, only 3 wear a destructive style, and the other 22 are mostly correct as they are.
SelectAllconfirms because selecting everything is a big action, andApplyChangesconfirms becauseit writes staged edits. Confirmation means "this is significant", not "this destroys something".
So this stays a review judgement rather than a CI check. Recording the two failed rules here so the next
person does not spend the same time rediscovering that they do not work.
Expected behavior
The two buttons above use
DangerButton, matching Shortcut Cleaner, Debloater, Uninstaller, FileShredder, Scheduled Maintenance, Edge/OneDrive and File Lock. Process Manager's kill button picks one
mechanism — most likely
DangerButtonsized down for a row, rather than a one-off red foreground.Affected tab
Audio Mixer, Environment Variables, Process Manager.