A different dcode entry point is winning on PATH than the one we upgraded.
Returned by detect_shadowed_dcode after a successful upgrade so the TUI can
warn the user that re-launching will pick up the wrong binary. The most
common cause is a pre-uv install (e.g. a leftover from a previous
pipx/pip-based install) earlier on PATH than the uv tool shims.
A frozen dataclass rather than a NamedTuple (unlike the sibling
DependencyChange) so __post_init__ can enforce the conflict invariant
the type's name promises: an instance only exists when there genuinely is
a shadow. The producer already guarantees this, so the check is defensive
against future direct construction, not a runtime gate on the hot path.