Updater/rebuild self-heal:
- Add a shared run_step wrapper used by both the update and rebuild
scripts. On the first failure matching a transient fetch/cache signature
(truncated tarball, corrupt NAR, hash mismatch, network timeout,
interrupted download), clear Nix's fetch caches and repair the store,
then retry once. Real config errors do not match and still fail loudly.
- The kernel-change boot fallback in the rebuild path is also wrapped.
- Fixes the reported 'cannot read file from tarball: Truncated tar archive
detected' failure, which a plain re-run cannot clear because Nix reuses
the corrupt cached archive.
Failed-update recovery / reporting:
- check_for_updates() now compares the running Hub version against the
branch VERSION, so a failed 'nix flake update' (lock advanced but no
generation staged) can no longer masquerade as 'up to date' and block
retries.
- /api/updates/check surfaces a persistent 'failed' state; /api/updates/run
never blocks a retry after a failure.
- Dashboard shows a red 'Update failed - click to retry' tile; the modal
offers a Retry Update button and stops offering a reboot on failure.