Skip to content

fix: an added-then-deleted env variable in one session is now actually removed#1414

Merged
laurentiu021 merged 2 commits into
mainfrom
fix/env-added-var-delete
Jul 10, 2026
Merged

fix: an added-then-deleted env variable in one session is now actually removed#1414
laurentiu021 merged 2 commits into
mainfrom
fix/env-added-var-delete

Conversation

@laurentiu021

Copy link
Copy Markdown
Owner

Summary

Fixes ultra-audit finding P2 #48.

EnvironmentVariablesViewModel.ApplyChanges keeps two parallel bookkeeping maps:

  • _baseline (Key → value) — drives RecomputePending / the pending-change count.
  • _originals (Key → (scope, name)) — the sole source for DeletedEntries() and the actual registry deletion.

The delete loop removed the variable from both maps, but the add/edit loop updated only _baseline — a freshly-added variable was never recorded in _originals, and ApplyChanges never re-runs Load().

Concrete failure (single session, no Refresh):

  1. Add a new variable C → Apply. SetVariable writes it to the registry, _baseline gets C, _originals does not.
  2. Delete C in the grid → Apply. RecomputePending (reads _baseline) counts C as a pending deletion → UI shows "1 pending change", but DeletedEntries (reads _originals) is empty → DeleteVariable(C) is never called. Status says "Applied 0 changes", PendingChangeCount stays stuck at 1, and C remains orphaned in the registry. (A manual Refresh self-heals by reloading _originals.)

Fix

The apply loop now writes _originals[Key(v)] = (v.Scope, v.Name) alongside _baseline[Key(v)] = v.Value on a successful SetVariable, keeping the two maps in lock-step (the exact invariant the existing code comment claims).

Testing note

No unit test added: EnvironmentVariableService is a sealed concrete class with no interface seam, and its SetVariable/DeleteVariable/ReadAll hit the real HKCU/HKLM Environment hive — exercising ApplyChanges end-to-end would mutate the live user registry, which the no-system-deps unit-test rule forbids. The fix is a symmetric one-line bookkeeping sync verifiable by inspection; a proper test is gated on introducing IEnvironmentVariableService (tracked by the broader arch-seam findings).

Checks

  • All 3 projects build 0 warnings / 0 errors
  • Leak scan on diff: clean

…y removed

ApplyChanges keeps two parallel maps: _baseline (drives the pending-change count)
and _originals (the sole source for DeletedEntries()/registry deletion). The delete
loop removed from both, but the add/edit loop updated only _baseline — so a
freshly-added variable was never recorded in _originals. Deleting that variable
later in the same session then showed '1 pending change' (RecomputePending reads
_baseline) yet DeletedEntries (reads _originals) skipped it, so it was never removed
from the registry and PendingChangeCount stuck at 1. A manual Refresh self-healed by
reloading _originals. The apply loop now writes _originals[Key(v)] alongside
_baseline[Key(v)] on a successful SetVariable, keeping the maps in lock-step.

Fixes ultra-audit finding P2 #48.

No unit test added: EnvironmentVariableService is a sealed concrete class with no
interface seam and its SetVariable/DeleteVariable/ReadAll hit the real HKCU/HKLM
Environment hive, so exercising ApplyChanges end-to-end would mutate the live user
registry (forbidden by the no-system-deps unit-test rule). The fix is a symmetric
one-line bookkeeping sync verifiable by inspection; a proper test is gated on the
IEnvironmentVariableService seam tracked by the broader arch-seam findings.
@laurentiu021 laurentiu021 merged commit d9fcb6b into main Jul 10, 2026
4 checks passed
@laurentiu021 laurentiu021 deleted the fix/env-added-var-delete branch July 10, 2026 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant