v0.2.3 — fail-closed freshness hold (Casks, taps, lib*) + single-package upgrade
Security + UX release. The --min-age freshness hold now covers Casks, tap formulae, and lib* formulae, and fails closed when it can't verify a release age — plus single-package upgrades and live progress during the dependency scan.
Fixed
- Freshness hold now covers Casks, tap formulae, and
lib*formulae — and fails closed (#62). The age check only resolved release dates fromhomebrew-coreatFormula/<first-letter>/<name>.rb, so three classes of package came back "age unknown" and silently skipped the--min-agehold: Casks (which live inhomebrew-cask), tap formulae (their own tap repo), andlib*formulae (libgit2,libheif,libusb, … — homebrew-core shards these underFormula/lib/, notFormula/l/). Lookups are now routed to the correct repo and path per package type, and a release age that genuinely cannot be verified is now held rather than allowed through. The same routing + fail-closed policy applies to the transitive-dependency age check in bothsafe-upgradeandsafe-install. The CVE-aware bypass (skip the hold when the installed version has known CVEs) is unchanged, so security patches are never withheld.
Added
- Single-package upgrades (#61):
brew safe-upgrade <name> [<name> …]restricts the run to the named outdated package(s) instead of everythingbrew outdatedreports. Matches the full name or its basename; a named package that isn't outdated is reported, not silently ignored. --allow-unknown-ageonsafe-upgradeandsafe-install— the explicit opt-out to permit packages whose release age can't be verified (default: such packages are held).- Dependency-scan progress (#60): the transitive-dependency scan now prints
[i/N] checking <dep> <version>…before each dependency's network checks, so a large scan shows live progress instead of a silent wait.
Upgrade
- Homebrew tap:
brew update && brew upgrade safe-upgrade - Script install: re-run
install.sh
Thanks to @aleksandrs-ledovskis for the detailed report in #62.