# Changelog

## Score

- CAI 45 → 45 (+0.1)
- Rubric changed (rubric-2026.09.9 → rubric-2026.09.18) — scores are not directly comparable.

## Lenses

- Code Health 87 → 88 (+0.8)
- Architecture 99 → 87 (-12.0)
- Maturity 58 → 58 (+0.4)
- Readiness 76 → 78 (+1.6)
- Security 15 → 15 (+0.0)
- Accessibility 80 → 80 (+0.0)
- Performance 100 (new)

## Resolved (12)

- DistributableToolchain::get_component_suggestion (cognitive 17) (src/toolchain/distributable.rs)
- Documentation: no project overview (README.md)
- Duplicated block (6 lines × 2) (src/cli/self_update/unix.rs)
- Duplicated block (8 lines × 2) (src/toolchain/names.rs)
- FileTooLong: self_update/windows.rs (src/cli/self_update/windows.rs)
- FixmeComment (src/cli/self_update/unix.rs)
- Further sole-owners (lower concentration)
- Hotspot: src/cli/self_update/windows.rs (src/cli/self_update/windows.rs)
- Hotspot: src/dist/component/package.rs (src/dist/component/package.rs)
- Hotspot: src/test.rs (src/test.rs)
- Off-boarding risk: anonymized user #1
- TodoComment (src/toolchain/distributable.rs)

## New (10)

- Documentation: no installation or build instructions (ci/actions-templates/README.md)
- Duplicate file writing operations. `utils.write_file` and `raw.write_file` perform the same core operation (writing string content to a file path). The presence of both suggests a lack of abstraction or a split between 'high-level' and 'low-level' utilities that isn't clearly justified by distinct signatures (e.g., one doesn't take a mode/encoding parameter that the other lacks).
- Duplicated block (15–16 lines × 2) (src/toolchain/distributable.rs)
- Duplicated block (8 lines × 2) (src/toolchain/names.rs)
- Inconsistent naming and scope for file system removal. `utils` exposes `remove_file` but `raw` exposes `remove_dir`. There is no `raw.remove_file` or `utils.remove_dir` shown, creating an asymmetry. Furthermore, `utils.remove_file` takes an unused `name` argument, while `raw.remove_dir` does not. This suggests `utils` is a wrapper that might be incomplete or inconsistently implemented compared to `raw`.
- Inconsistent return types for existence checks. `path_exists` returns a boolean, while `is_file` also returns a boolean. However, other operations in `raw` (like `open_dir_following_links`) return `Result`. While not a direct name collision, the inconsistency in error handling (bool vs Result) for similar 'check' operations is a design flaw. More critically, `raw` lacks a `file_exists` or `dir_exists` specific check, relying on `path_exists` + type check, whereas `is_file` is specific. This is a minor API design inconsistency rather than a direct duplicate, but combined with the `remove` asymmetry, it lowers consistency.
- Inverted test pyramid
- Naming inconsistency in test assertion helpers. `expect` is a generic name that implies checking the result of a command, but it doesn't specify what is being expected (stdout? stderr? exit code?). `expect_with_env` is also vague. The `Assert` type has specific methods like `is_ok`, `with_stdout`, etc. The factory methods on `Config` should likely be named more descriptively, e.g., `run_command` or `execute`, returning an `Assert` builder, rather than `expect_*` which conflates execution with assertion.
- Projects may be oversized for their cohesion
- rustup::cli::self_update::stage::cleanup_at (cognitive 16) (src/cli/self_update/stage.rs)

## Changes since last survey

- 91 commits — 75 feature/other, 16 fixes

## By area

- src/cli — 39 commits
- src/install.rs — 12 commits
- (root) — 7 commits
- src/dist — 6 commits
- tests/suite — 6 commits
- .github/workflows — 4 commits
- ci/actions-templates — 4 commits
- src/errors.rs — 3 commits
- src/toolchain — 3 commits
- doc/user-guide — 2 commits
- ci/run.bash — 1 commit
- src/anchors.rs — 1 commit
- src/config.rs — 1 commit
- src/download — 1 commit
- src/process.rs — 1 commit

## Notable commits

- fix: fix(cli): log empty toolchain message with info
- fix: fix(dist): add `DistError::HostTupleUnsupported` to nightly backtracking flow
- fix: fix(dist): refine message of `DistError::HostTupleUnsupported`
- fix: fix(error): exclude `source` in `RustupError`'s `Display` impl
- fix: fix(installer): format shell command as code block
- fix: fix(rustup-init/sh): dont let an external `local` pass for the builtin
- fix: fix(rustup-mode): make "remove last target" warning more robust
- fix: fix(self-update): fix detection logic for `xonsh`
- fix: fix(self-update): move the updater under RUSTUP_HOME and mark its outcome
- fix: fix(self-update): publish the rustup binary atomically
- fix: fix(self-update): record DisplayVersion from the replacer on Windows
- fix: fix(self-update): remove abandoned pending binaries once stale
- fix: fix(self-update): remove abandoned updaters only once stale
- fix: fix(self-update): serialize self-updates with a lock
- fix: fix(uninstall): reuse resolved cargo home during cleanup
- fix: fix(windows): attempt GC cleanup after uninstall errors
- change: Upgrade faster-hex to 1
- change: Upgrade opentelemetry etc to 0.33
- change: chore(anchor): bump static roots
- change: chore(deps): lock file maintenance
- …and 71 more
