#478

Stale checksum pins for rust and atuin — identical on the release commit and main, so --checksums-ref main cannot help (recurrence of #398; monitor flapping per #457)

Openpineridge-itopened 9d ago

Summary

Two checksums.yaml pins are stale against live upstream, so ACFS refuses to install lang.rust and tools.atuin with Security Error: Checksum mismatch. Contrary to the error text, main does not carry refreshed values — the entries are byte-identical on the release commit and on main, so neither --checksums-ref main nor waiting helps.

This is a recurrence of #398, which reported tools.atuin stale on v0.9.0 with different hashes. So the pin was refreshed after #398 and has gone stale again — the underlying cause is that these URLs are moving targets, not a one-off missed refresh.

Environment

ACFS version: 0.10.0
Release commit: ba924f17f4b00a6c4b57966570633e27c9422c69
main at test time: 405de32b3e8c22aadc90c8783d1694fdf48ddf92
OS: Omarchy 4.0.6 (ID=omarchy, ID_LIKE=arch)
Date observed: 2026-10-21

Observed mismatches

ERROR: Security Error: Checksum mismatch for rust
  Expected: 7d0ea0f8eba7fa1ebfe998091cd7ec4501e33ec5ca6b884eb4d894d7da5170af
  Actual:   9502b514362a21096210d498f143b8cdacda365d3dfcf45e8f5541e089ccafc0
  URL: https://sh.rustup.rs

ERROR: Security Error: Checksum mismatch for atuin
  Expected: e632c6d1dc71e75c9710caf5f645c11131f0d94c859ed6b4266444e11240abdb
  Actual:   69c7c0e057084ede4536de25f856c037f4649dcf8f29cc98a64ac52340320a99
  URL: https://github.com/atuinsh/atuin/releases/latest/download/atuin-installer.sh

main has the same stale values

Fetched checksums.yaml from both refs and compared — identical entries:

# identical at ba924f17… and at main (405de32b…)
atuin:
  url: "https://github.com/atuinsh/atuin/releases/latest/download/atuin-installer.sh"
  sha256: "e632c6d1dc71e75c9710caf5f645c11131f0d94c859ed6b4266444e11240abdb"
rust:
  url: "https://sh.rustup.rs"
  sha256: "7d0ea0f8eba7fa1ebfe998091cd7ec4501e33ec5ca6b884eb4d894d7da5170af"

The error text states:

End users: checksums.yaml is refreshed from upstream automatically, so a mismatch on a current ACFS means the PUBLISHED pin is stale

For these two entries that automatic refresh has not happened on main, so the only recourse the message offers (acfs hold) leaves the tools permanently uninstalled.

Likely reason the drift went unnoticed: #457

The checksum monitor has been flapping for the past week — all comments on #457 are automated alerts:

Timestamp (UTC)Event
2026-10-15 20:31recovered after 6 consecutive fail-closed runs
2026-10-15 23:16failed closed ×3 — "remote main and legacy mirror differ before observation"
2026-10-15 23:31recovered after 3 fail-closed runs
2026-10-16 10:01failed closed ×3 — "pinned base already contains generated drift"
2026-10-17 23:31failed closed ×3 — "remote main and legacy mirror differ"

Drift monitoring was therefore intermittently down across the window in which these two pins went stale, and the last recorded state is fail-closed. Fixing #457 is probably a prerequisite for these pins staying fresh.

Cascade

tools.ast_grep installs via ~/.cargo/bin/cargo install ast-grep --locked, so the lang.rust failure cascades into it:

ERROR: tools.ast_grep: install command failed: ~/.cargo/bin/cargo install ast-grep --locked

Root cause: unpinnable URLs

Both entries point at moving targets:

  • https://sh.rustup.rs — a live script that changes whenever rustup ships.
  • …/releases/latest/download/atuin-installer.sh — latest by definition.

Neither can be pinned durably, so both will drift again immediately after any refresh. #435 reports the same class of problem for AADC ("still builds unpinned main despite published installer and binaries").

Suggested fix

  1. Re-pin rust and atuin via ./scripts/lib/security.sh --update-checksums.
  2. Prefer immutable, versioned URLs over latest/download/ and sh.rustup.rs — e.g. pin a specific atuin release tag, and for rustup pin a versioned rustup-init artifact rather than the live bootstrap script. Where a distro package is a viable source (Arch ships atuin and rustup in extra), consider allowing that path to satisfy the module instead.
  3. Soften the end-user text: it currently promises an automatic refresh that did not occur here, and offers acfs hold as the only recourse. When main and the release commit carry the same stale hash, saying so explicitly would save users from trying --checksums-ref main.
  4. Surface stale pins in acfs doctor as a distinct state from "install failed", so users can tell an upstream pin problem from a local one.

Workaround used

Skipped the module and installed from Arch extra instead:

sudo pacman -S --needed atuin rustup
rustup default stable     # rust 1.99.1

Note this does not satisfy either module's installed_check — lang.rust tests test -x ~/.cargo/bin/cargo while Arch's rustup places proxies in /usr/bin, and tools.atuin requires ~/.atuin/bin/atuin plus an ACFS-generated wrapper marker. Reported separately in the Arch/Omarchy generated-modules issue.

Related

#398 (same class, v0.9.0, closed), #457 (monitor failing closed — likely why this drifted), #435 (unpinned main builds), #468 (checksums.yaml re-pin breaking bootstrap integrity).

Activity

2
Dicklesworthstone5d ago

I checked both pins on main against the live upstream files today.

  • rust (https://sh.rustup.rs): the checksum monitor refreshed this pin in 99fe9f79 on 2026-10-21, about half an hour after this report, to 9502b514…, the value you observed. Upstream still hashes to that value.
  • atuin: 99fe9f79 also refreshed this pin, to 69c7c0e0…, the value you observed. Atuin then released v18.24.2 on 2026-10-22, and releases/latest/download/atuin-installer.sh now hashes to 682117ad…. So main is stale for atuin again.

The monitor is not broken here; this deferral is deliberate. It publishes new hashes on its own only for installers hosted by this repository's owner. A change to a third-party installer waits until a maintainer has reviewed the new bytes and authorized that exact change. The monitor opened that request within minutes of the release: #480 (#481 is a duplicate with the same digest). The request also covers uv, whose installer changed upstream the same day.

I re-ran scripts/lib/security.sh --verify --json against main today. atuin and uv are the only mismatches, and their evidence still hashes to the digest in #480, so that authorization request is current.

Remaining operator step: review the v18.24.2 atuin-installer.sh and the current https://astral.sh/uv/install.sh. Then, on the monitor host, write authorize:d7643f38a766a806f15fb0fb97a17621adf8fcb25b0e911b66eb5f1501a9b4b9 into authorized-checksum-change in the monitor's state directory ($ACFS_MONITOR_STATE, default ~/.local/state/acfs-monitor). The file must be owner-only and must not be a symlink. The next monitor run, within 15 minutes, publishes both pins. Until then, --skip tools.atuin (or acfs hold) is the workaround.

You are right that latest/download/ URLs will keep drifting: every atuin release repeats this until someone authorizes it. Pinning a versioned release URL would replace that with manual version bumps, which is a maintainer decision and is not changed here.

I'm leaving this open until the atuin pin is published.

joyshmitz3d ago

Review of the v18.24.2 atuin-installer.sh bytes behind the pending authorization in #480 (digest d7643f38…), for the atuin half only.

Hash. releases/latest/download/atuin-installer.sh still hashes to 682117ada10ef0886fa4974f1afcf5fb396ce466c45acaffbf075eeb06f6dc25 today (2026-10-27). That matches releases/download/v18.24.2/atuin-installer.sh, and v18.24.1's installer hashes to the current pin 69c7c0e0…. main (5e344051) still carries 69c7c0e0….

Diff v18.24.1 → v18.24.2. Only the usual per-release cargo-dist changes. No logic differs:

  • APP_VERSION 18.24.1 → 18.24.2
  • releases/download/v18.24.1 → v18.24.2 in the three ARTIFACT_DOWNLOAD_URLS branches and the help text
  • the version field of the embedded install receipt (cargo-dist 0.31.0 in both)
  • the seven per-platform _checksum_value sha256 entries

Both files are 55965 bytes.

Embedded artifact hashes vs. the release. I compared these with the release's published .sha256 assets:

targetinstallerrelease .sha256
x86_64-unknown-linux-gnu005a4953f2fe96d4…005a4953f2fe96d4… ✓
aarch64-unknown-linux-gnu5ec6cc8bd3889b61…5ec6cc8bd3889b61… ✓

The release was published by github-actions[bot] on 2026-10-22T10:07:24Z with 36 assets.

Not covered. I did not find a .sha256 asset under the atuin-x86_64-unknown-linux-musl-static.tar.gz.sha256 name, so that target's embedded value (311cd1ba…) is unverified here. I also did not review the uv half of #480 (live https://astral.sh/uv/install.sh currently hashes to 1c6e7f02…, the same value #480 observed). The authorization should still get its own look at uv.

Context: we hit this on a 0.10.0 VPS, where acfs update reported Atuin (reinstall) as its only failure. We're holding atuin there (acfs hold atuin --expiry 2026-11-10) until the pin is published.