Cascade only ever accounted for the first requested package still
found in the resolution: it computed one cascade round, re-resolved
once, then unconditionally broke out of the loop. A second requested
removal still pulled in by a different, unrelated dependent was never
re-checked against the new resolution - it silently shipped anyway,
with no error and no cascade. Fixed by looping to a fixed point:
re-scan every requested name against the latest resolution until none
of them remain.
That loop surfaced a second, independent bug it happened to newly
reach: the "all roots removed via cascade" branch called
resolution.deinit() and then returned without reassigning resolution,
so the function's outer defer resolution.deinit() fired again on
the same freed value - a double-free. This bug predates this change;
it just needed a second cascade round to ever be reached, and there
were no existing tests for uninstall --cascade at all. Fixed by only
deiniting-then-reassigning when there are roots left to re-resolve.
Added a regression test with two packages independently required by
different dependents; confirmed it reproduces both bugs independently
before landing the fix for either.