fix(backend): respect permissive minimum release age#10310
Conversation
📝 WalkthroughWalkthroughAdds a Backend hook returning rich VersionInfo for the absolute latest stable release (created_at and prerelease), implements it for GitHub/Forgejo, updates latest resolution to prefer that metadata for cutoff validation, and treats a zero-duration minimum_release_age as disabling the cutoff. ChangesLatest Stable Version Metadata and Cutoff Resolution
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 29bfe3f. Configure here.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/backend/mod.rs`:
- Around line 1284-1296: latest_version_unfiltered currently only calls
latest_stable_version, but the new metadata hook latest_stable_version_info must
be consulted first so backends like github.rs that implement only the metadata
variant return the true canonical "absolute latest"; update
latest_version_unfiltered to call self.latest_stable_version_info(config).await,
use the returned Option<VersionInfo> (when Some) as the fast-path latest result,
and only fall back to calling self.latest_stable_version(config).await or the
cached-list resolution if the metadata hook returns None or an error, preserving
existing error handling and return types.
- Around line 1583-1610: The code unconditionally calls
list_remote_versions_with_info_with_refresh(...) even when latest.created_at is
present; change the logic in the branch handling Some(latest) so you first check
latest.created_at (and compute info = latest.created_at.as_ref().map(|_|
&latest)) and only call list_remote_versions_with_info_with_refresh and set
fallback_refresh = false if info is None (i.e., created_at missing) or the
created_at case doesn't satisfy
latest_stable_candidate_allowed_by_before_date(&version, info, before); keep
using latest_stable_candidate_allowed_by_before_date(&version, info, before) for
the final decision and ensure fallback_refresh is adjusted only when the remote
list is actually fetched.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 210da34d-f397-4807-9ff6-be94f0b17d1a
📒 Files selected for processing (3)
src/backend/github.rssrc/backend/mod.rssrc/install_before.rs
Greptile SummaryThis PR fixes two independent
Confidence Score: 5/5Safe to merge — both bug fixes are narrow and well-tested, backward compatibility is maintained for all existing backends, and the new trait method defaults to a no-op. Both changes (zero-duration short-circuit and fast-path metadata injection) are isolated to their respective code paths, covered by dedicated regression tests, and do not alter behavior for the common No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "fix(backend): use metadata fast path for..." | Re-trigger Greptile |
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.2 x -- echo |
21.0 ± 2.8 | 17.6 | 34.3 | 1.06 ± 0.16 |
mise x -- echo |
19.8 ± 1.3 | 18.0 | 38.9 | 1.00 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.2 env |
19.2 ± 1.1 | 17.3 | 26.0 | 1.00 |
mise env |
21.5 ± 1.0 | 18.4 | 26.1 | 1.12 ± 0.08 |
env measured 12% slower, but the relative uncertainty overlaps the 10% threshold. |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.2 hook-env |
25.4 ± 4.7 | 19.4 | 36.8 | 1.11 ± 0.22 |
mise hook-env |
22.8 ± 1.3 | 20.1 | 30.2 | 1.00 |
✅ Performance improvement for hook-env is 11% |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.2 ls |
18.4 ± 1.2 | 15.9 | 24.0 | 1.00 |
mise ls |
19.4 ± 1.5 | 15.9 | 25.0 | 1.06 ± 0.11 |
xtasks/test/perf
| Command | mise-2026.6.2 | mise | Variance |
|---|---|---|---|
| install (cached) | 155ms | 157ms | -1% |
| ls (cached) | 71ms | 69ms | +2% |
| bin-paths (cached) | 80ms | 80ms | +0% |
| task-ls (cached) | 145ms | 148ms | -2% |

Summary
Fixes
minimum_release_agehandling when resolvinglatestthrough backend fast paths.minimum_release_age = "0s"as disabling the cutoff, matching the documented behavior.created_atmetadata from the release endpoint.0scutoff disabling.Root Cause
latest_stable_version()returned only a version string. Whenminimum_release_agewas active, mise checked that version against the cached full version metadata. If the canonical latest release had not yet appeared in the cached metadata list, mise treated it like an unverified/too-new release and fell back to an older cached version, producing warnings such asignored by minimum_release_ageeven for permissive cutoffs.Separately,
"0s"was parsed as a timestamp at process start instead ofNone, so it still enabled the metadata filtering path despite the docs saying it disables the delay.Validation
cargo test latest_version_testscargo test install_before::tests::test_zero_minimum_release_age_disables_cutoffcargo fmt --all -- --checkRefs #10303 (comment)
Note
Medium Risk
Changes core latest-version resolution and release-age filtering used across installs; behavior is narrowed with tests but affects many backends' latest queries.
Overview
Fixes
minimum_release_agesolatestresolution through backend fast paths behaves as documented.0sdisables the cutoff:install_beforenow treats zero-durationminimum_release_age(e.g."0s") as no release-age filter instead of a timestamp at process start.Rich fast-path metadata: A new
latest_stable_version_infohook returnsVersionInfo(includingcreated_at) from canonical upstream “latest” endpoints. GitHub/Forgejo populate it from/releases/latest.latest_version/latest_version_unfilteredprefer this hook, then fall back to the string-only fast path.Stale cache + age filtering: When a cutoff is active, release-age checks use fast-path metadata when present, so the canonical latest can pass even if it is missing from a stale cached version list.
latest_stable_candidate_allowed_by_before_dateaccepts fast-path candidates when the cutoff is in the future and metadata is missing or lacks a date (permissive case).Regression tests cover stale metadata, unfiltered latest, permissive future cutoffs, and
0sdisabling.Reviewed by Cursor Bugbot for commit 39f9e63. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
Improvements
Tests