v0.50.291 — "What's new?" link 404 fix
1 PR. Self-built + nesquena APPROVED with thorough behavioral harness. Closes #1579 (reported by @ai-ag2026).
What's fixed
The WebUI update banner's "What's new?" link was 404'ing whenever local HEAD diverged from upstream — unpushed work, dirty stage branches, fork checkouts, in-flight rebases, release-time merge commits. Reporter saw https://github.com/nesquena/hermes-webui/compare/c660c7f...86cb22e produce a 404 because c660c7f was an unpushed local commit.
Fix: replace git rev-parse --short HEAD with git merge-base HEAD <compare_ref> in api/updates.py:_check_repo. The merge-base is the most recent commit local and upstream share, and (since git fetch succeeded just before) is guaranteed to exist on the upstream GitHub repo.
| Scenario | Pre-fix | Post-fix |
|---|---|---|
| Pure-behind clone | URL with HEAD = upstream parent → resolves | merge-base == HEAD → URL unchanged ✅ backward-compat |
| 2 unpushed + 3 upstream (reporter's case) | URL with local HEAD → 404 | URL with merge-base → resolves ✅ |
Fork checkout pointing at upstream repo_url
| URL with fork's local SHA → 404 | URL with merge-base → resolves ✅ |
| Mid-rebase | URL → 404 | URL with merge-base → resolves ✅ |
| Shallow clone with no shared history | URL → 404 | merge-base fails → current_sha=None → JS link guard suppresses ✅
|
Also hardens static/ui.js:_showUpdateBanner to clear the link's href and display:none it on every banner render, so a stale link from a prior render can't survive a re-render where current_sha is null.
Tests
4111 → 4117 passing (+6 regression tests on tests/test_issue1579_whats_new_link_404.py). Tests use throwaway local+upstream git fixtures to verify the reporter's exact scenario, backward-compat for pure-behind clones, merge-base-failure fallback, JS reset invariant, JS guard shape, and end-to-end URL resolution.
Pre-release verification
- Independent reviewer (nesquena) APPROVED with full end-to-end behavioral harness.
- Cross-tool audit: webui-only, no agent surface.
- Security audit clean (no XSS/SSRF/injection — subprocess args passed as list, no shell).
- Race/state analysis:
_check_reposingle-threaded per request. - 8-scenario edge-case trace including stale-link reset.
- Browser API sanity: 11/11 endpoints verified.
- Live verification post-deploy:
curl /api/updates/checkreturns the merge-base SHA correctly.
Maintainer in-stage actions
- Rebased onto current master (REBASE-DEFAULT rule): PR was created against master at v0.50.289 timestamp, but v0.50.290 shipped between PR creation and this release. Resolved CHANGELOG conflict by promoting the PR's entry from v0.50.290 → v0.50.291 and bumping test count 4100 → 4117 to account for v0.50.290 baseline.
Thanks to @ai-ag2026 for the precise repro (the exact 404'ing URL was in the bug report).
Full changelog: https://github.com/nesquena/hermes-webui/blob/master/CHANGELOG.md