The repo is two things at once — bench-the-project and bench-the-
distribution — and install/update conflated them by cloning the repo
and subtracting what should not have come along. Invert it: one
curated artifact, correct by construction.
- manager/core/release-manifest: the whole shipping list in one place
(copy/tree/once/keep/seed classes). update.sh's hardcoded top-level
file list, promoted.
- release.sh: builds bench.tar.gz from the manifest (contents at the
tarball root, stable asset name — the tokenless latest-release URL
depends on both), stamps the source repo into the shipped update.sh,
refuses on dirty tree or existing tag, tags v<VERSION> and publishes
via gh release create. Never ships in the artifact.
- update.sh: downloads the latest release (BENCH_REF pins a tag) via
gh with an anonymous curl fallback; refuses when the asset's VERSION
disagrees with its tag; replaces manager/core/ wholesale plus the
artifact manifest's `copy` files; touches nothing else. No release
published -> says so and changes nothing; no silent git fallback.
- tests: the tarball equals exactly the manifest (no cards, no local/
content beyond the generated starter, no state/tests/.claude), the
artifact installs pristine and boots the board, and update.sh's
replace/survive/refuse paths run hermetically against PATH-stubbed
gh and curl.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>