fix(github): prefer shortest asset name as tiebreaker in auto-detection#9361
fix(github): prefer shortest asset name as tiebreaker in auto-detection#9361
Conversation
When a release publishes multiple binaries per platform (e.g. agent-sh/agnix ships agnix, agnix-lsp, and agnix-mcp), the platform-scoring rules tie and the picker would return whichever asset the GitHub API listed first — which varies per platform and produces inconsistent lockfile entries. Use shortest name as a tiebreaker, then lexicographic for full determinism. The canonical binary's name is almost always the shortest in this pattern. Fixes #9358 Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Greptile SummaryThis PR fixes non-deterministic asset selection in the GitHub backend by replacing a Confidence Score: 5/5Safe to merge — the logic is correct, tests are order-independent, and all existing tests continue to pass. The min_by comparator correctly inverts the score comparison (score_b.cmp(score_a)) to select the highest-scoring asset while adding deterministic tiebreakers. Both new tests exercise the exact failure modes described in the linked discussion and verify order-independence. No regressions in existing behavior. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["pick_best_asset(assets)"] --> B["score_all_assets(assets)"]
B --> C["into_iter()"]
C --> D["filter: score > 0"]
D --> E{"any candidates?"}
E -- No --> F["None"]
E -- Yes --> G["min_by comparator"]
G --> H["1. Highest score\n(score_b.cmp(score_a))"]
H --> I{"tie?"}
I -- No --> J["winner by score"]
I -- Yes --> K["2. Shortest name\n(name_a.len().cmp(&name_b.len()))"]
K --> L{"tie?"}
L -- No --> M["winner by length"]
L -- Yes --> N["3. Lexicographic\n(name_a.cmp(name_b))"]
N --> O["deterministic winner"]
J & M & O --> P["map: return asset String"]
Reviews (1): Last reviewed commit: "fix(github): prefer shortest asset name ..." | Re-trigger Greptile |
There was a problem hiding this comment.
Code Review
This pull request modifies the pick_best_asset method in src/backend/asset_matcher.rs to implement a tie-breaking mechanism for assets with identical scores. When scores are equal, the logic now prefers the asset with the shortest name, which typically represents the canonical binary. Additionally, new unit tests have been added to ensure correct behavior for tools like agnix and bun. There are no review comments to address, and I have no further feedback to provide.
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.20 x -- echo |
21.8 ± 0.6 | 20.6 | 23.8 | 1.00 |
mise x -- echo |
22.4 ± 2.2 | 21.0 | 66.9 | 1.03 ± 0.10 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.20 env |
21.3 ± 0.6 | 20.2 | 25.2 | 1.00 |
mise env |
22.2 ± 0.7 | 20.9 | 24.0 | 1.04 ± 0.05 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.20 hook-env |
22.5 ± 0.8 | 21.1 | 26.4 | 1.00 |
mise hook-env |
23.4 ± 0.8 | 21.8 | 25.8 | 1.04 ± 0.05 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.20 ls |
20.6 ± 0.7 | 19.3 | 22.8 | 1.00 |
mise ls |
21.2 ± 0.6 | 20.1 | 23.6 | 1.03 ± 0.05 |
xtasks/test/perf
| Command | mise-2026.4.20 | mise | Variance |
|---|---|---|---|
| install (cached) | 163ms | 166ms | -1% |
| ls (cached) | 79ms | 79ms | +0% |
| bin-paths (cached) | 84ms | 84ms | +0% |
| task-ls (cached) | 833ms | 817ms | +1% |
### 🚀 Features - **(registry)** add --security flag to include security info in JSON output by @jdx in [#9364](#9364) ### 🐛 Bug Fixes - **(config)** limit resolved backend opts to aliases by @risu729 in [#9315](#9315) - **(docs)** stack banner message and link on mobile by @jdx in [#9362](#9362) - **(github)** prefer shortest asset name as tiebreaker in auto-detection by @jdx in [#9361](#9361) - **(java)** newer zulu versions use a different directory structure by @roele in [#9365](#9365) - **(prune)** respect tracked lockfiles by @jdx in [#9373](#9373) - **(task)** skip tool install for missing naked tasks by @jdx in [#9374](#9374) - **(trust)** add untrust command by @jdx in [#9370](#9370) - fix - flux-operator-mcp aqua path by @monotek in [#9357](#9357) ### 📚 Documentation - update ruby compile msg by @fladson in [#9338](#9338) ### 📦️ Dependency Updates - update ubuntu docker tag to v26 by @renovate[bot] in [#9347](#9347) - update ghcr.io/jdx/mise:deb docker digest to 1af5a69 by @renovate[bot] in [#9352](#9352) - update taiki-e/install-action digest to 787505c by @renovate[bot] in [#9354](#9354) - update ghcr.io/jdx/mise:rpm docker digest to 7015ff3 by @renovate[bot] in [#9353](#9353) - update ghcr.io/jdx/mise:copr docker digest to da63a0f by @renovate[bot] in [#9351](#9351) - update ghcr.io/jdx/mise:alpine docker digest to 461700f by @renovate[bot] in [#9350](#9350) - bump communique 1.0.3 → 1.0.4 by @jdx in [#9378](#9378) ### 📦 Registry - remove openshift-install by @jdx in [#9372](#9372) - remove go-sdk by @jdx in [#9371](#9371) ### Chore - **(npm-publish)** use aube publish instead of npm publish by @jdx in [#9328](#9328) ### New Contributors - @fladson made their first contribution in [#9338](#9338)
Summary
agnix-*,agnix-lsp-*,agnix-mcp-*), the platform-scoring rules tie and the picker returned whichever asset GitHub's API listed first — varies per platform, producing inconsistent lockfile entries.bunthat shipbaseline/profilevariants alongside the canonical build.Fixes #9358
Test plan
asset_matchertests still pass (31/31)githubbackend tests still pass (24/24)Note
Medium Risk
Changes asset auto-selection ordering, which can alter which release artifact gets installed and what gets written to lockfiles across platforms. Risk is contained to tie cases but could still pick a different binary when multiple assets score equally.
Overview
Makes
AssetPicker::pick_best_assetdeterministic when multiple assets have the same platform score by adding tie-breakers: prefer higher score, then shortest filename, then lexicographic order.Adds unit tests covering multi-binary releases (e.g.
agnixvsagnix-lsp/agnix-mcp) and variant builds (e.g.bunbaseline/profile) to ensure the canonical, shortest-named asset is selected regardless of input ordering.Reviewed by Cursor Bugbot for commit dc373a9. Bugbot is set up for automated code reviews on this repo. Configure here.