From 833e33f83d305ed5f053acb7abd5c68143ec9b90 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Wed, 30 Sep 2026 11:22:31 +0100 Subject: [PATCH 1/5] fix(setup): install just from a checksum-verified release, not curl|bash Both just.systems/install.sh | bash fallbacks are replaced with install_just_verified: a pinned just 1.58.0 release binary per platform, fetched over TLS1.2+ into mktemp and sha256-checked before install (ported from hyperpolymath/standards setup.sh 3079bc12; macOS shasum fallback added). Unknown platforms fail rather than guess a target. Verified locally: real download installs just 1.58.0; a tampered digest is rejected; sh -n + shellcheck clean; hypatia scan reports no shell_download_then_run in setup.sh. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QFphKkDVB9pUDSCD4bkz65 --- build/setup.sh | 63 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/build/setup.sh b/build/setup.sh index c04d6ea..ec65c6f 100755 --- a/build/setup.sh +++ b/build/setup.sh @@ -127,6 +127,61 @@ detect_platform() { esac } +# ── Verified just install ── +# Replaces `curl https://just.systems/install.sh | bash`: piping a remote script +# into a shell runs whatever the server returns, with no chance to check it. +# A pinned RELEASE BINARY is fetched instead and its digest checked before use +# (ported from hyperpolymath/standards setup.sh, 3079bc12). Digests computed +# 2026-08-07; casey/just publishes none, so this is trust-on-first-use — any +# later substitution fails loudly. An unrecognised platform returns failure +# rather than fetching a plausible-looking binary for the wrong target. +JUST_VERSION="1.58.0" + +just_target() { + case "$(uname -s 2>/dev/null):$(uname -m 2>/dev/null)" in + Linux:x86_64|Linux:amd64) echo "x86_64-unknown-linux-musl" ;; + Linux:aarch64|Linux:arm64) echo "aarch64-unknown-linux-musl" ;; + Darwin:x86_64) echo "x86_64-apple-darwin" ;; + Darwin:arm64|Darwin:aarch64) echo "aarch64-apple-darwin" ;; + *) echo "" ;; + esac +} + +just_sha256() { + case "$1" in + x86_64-unknown-linux-musl) echo "4a5cc2f53e6f0f8c59092a6cc38291eb729d46a7dd95d3ae582008881b84931d" ;; + aarch64-unknown-linux-musl) echo "748237128c4c40cbdabc65e841d05ceba13cc23a91eaba395495894c1d9764df" ;; + x86_64-apple-darwin) echo "9a09cfef66aaa79da58203970103a0684307716caaabd3e9844cacc4dc0f4023" ;; + aarch64-apple-darwin) echo "50ae3e996c974a0bf32ea7d10f495070df33f1b43e0616b2769e3d4821ed8f48" ;; + *) echo "" ;; + esac +} + +# sha256sum is GNU; macOS ships shasum instead. +sha256_of() { + if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d" " -f1 + else shasum -a 256 "$1" | cut -d" " -f1 + fi +} + +install_just_verified() { + jv_target="$(just_target)" + [ -z "$jv_target" ] && { fail "just: no verified build for $(uname -s)/$(uname -m); use your package manager"; return 1; } + jv_want="$(just_sha256 "$jv_target")" + jv_tmp="$(mktemp -d)" + jv_url="https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-${jv_target}.tar.gz" + curl -fsSL --proto '=https' --tlsv1.2 -o "$jv_tmp/just.tar.gz" "$jv_url" || { rm -rf "$jv_tmp"; return 1; } + jv_got="$(sha256_of "$jv_tmp/just.tar.gz")" + if [ "$jv_got" != "$jv_want" ]; then + fail "just: CHECKSUM MISMATCH for $jv_url (expected $jv_want, got $jv_got)" + rm -rf "$jv_tmp" + return 1 + fi + tar -xzf "$jv_tmp/just.tar.gz" -C "$jv_tmp" just + sudo install -m 0755 "$jv_tmp/just" /usr/local/bin/just + rm -rf "$jv_tmp" +} + # ── Install just ── install_just() { if command -v just >/dev/null 2>&1; then @@ -139,8 +194,8 @@ install_just() { case "$PKG_MGR" in dnf) sudo dnf install -y just ;; apt) sudo apt-get install -y just 2>/dev/null || { - # just not in older apt repos — use installer - curl -fsSL https://just.systems/install.sh | bash -s -- --to /usr/local/bin + # just not in older apt repos — use the verified release binary + install_just_verified } ;; pacman) sudo pacman -S --noconfirm just ;; apk) sudo apk add just ;; @@ -150,8 +205,8 @@ install_just() { rpm-ostree) sudo rpm-ostree install just ;; guix) guix install just ;; *) - info "Using just installer script..." - curl -fsSL https://just.systems/install.sh | bash -s -- --to /usr/local/bin + info "Installing verified just release..." + install_just_verified ;; esac From 32c3d7193041cbd47ec0c513a4059930233d1452 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Wed, 30 Sep 2026 11:23:26 +0100 Subject: [PATCH 2/5] docs(setup): stop advertising curl|sh in the usage comment The advertised rsr-template-repo URL no longer exists (setup.sh was removed there in 162b02a), and the pattern is the one this script now refuses to use for just. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QFphKkDVB9pUDSCD4bkz65 --- build/setup.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/setup.sh b/build/setup.sh index ec65c6f..4a3e0b5 100755 --- a/build/setup.sh +++ b/build/setup.sh @@ -6,9 +6,7 @@ # Then hands off to `just setup` for project-specific configuration. # # Usage: -# curl -fsSL https://raw.githubusercontent.com/hyperpolymath/rsr-template-repo/main/setup.sh | sh -# # or after cloning: -# ./setup.sh +# ./build/setup.sh # after cloning — read it first; never pipe a fetched script into a shell # # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) From 7815dc764c8a512027ddf871349f7d8a63fa235e Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Wed, 30 Sep 2026 11:26:41 +0100 Subject: [PATCH 3/5] Update build/setup.sh Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> --- build/setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build/setup.sh b/build/setup.sh index 4a3e0b5..2e61ee6 100755 --- a/build/setup.sh +++ b/build/setup.sh @@ -176,6 +176,7 @@ install_just_verified() { return 1 fi tar -xzf "$jv_tmp/just.tar.gz" -C "$jv_tmp" just + sudo install -d -m 0755 /usr/local/bin || { rm -rf "$jv_tmp"; return 1; } sudo install -m 0755 "$jv_tmp/just" /usr/local/bin/just rm -rf "$jv_tmp" } From 0e25fc8e79e89f13fe1cd44964ae15bf549afd34 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Wed, 30 Sep 2026 11:28:05 +0100 Subject: [PATCH 4/5] fix(ci): skip instant-sync dispatch cleanly when FARM_DISPATCH_TOKEN is absent secrets is not available in step if:, so the token is mapped to job env and both steps gate on it (the standards instant-sync.yml pattern). Without the PAT the dispatch falls back to GITHUB_TOKEN and 401s. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QFphKkDVB9pUDSCD4bkz65 --- .github/workflows/instant-sync.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index 40e1706..94f9afc 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -15,8 +15,14 @@ jobs: dispatch: runs-on: ubuntu-latest timeout-minutes: 15 + # `secrets` is not available in step `if:`; job-level env is. Without the + # PAT the dispatch falls back to GITHUB_TOKEN and fails 401 cross-repo, so + # skip cleanly where FARM_DISPATCH_TOKEN has not been propagated. + env: + FARM_DISPATCH_TOKEN: ${{ secrets.FARM_DISPATCH_TOKEN }} steps: - name: Trigger Propagation + if: ${{ env.FARM_DISPATCH_TOKEN != '' }} uses: peter-evans/repository-dispatch@v4.0.1 with: token: ${{ secrets.FARM_DISPATCH_TOKEN }} @@ -30,6 +36,7 @@ jobs: "forges": "" } - name: Confirm + if: ${{ env.FARM_DISPATCH_TOKEN != '' }} env: REPO_NAME: ${{ github.event.repository.name }} run: echo "::notice::Propagation triggered for ${REPO_NAME}" From 64c0a7d30115c7c470c157e9434cbe22da0176c2 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 10:37:12 +0000 Subject: [PATCH 5/5] docs(setup): document just installation helpers and failure behavior --- build/setup.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/build/setup.sh b/build/setup.sh index 2e61ee6..d87920c 100755 --- a/build/setup.sh +++ b/build/setup.sh @@ -135,6 +135,8 @@ detect_platform() { # rather than fetching a plausible-looking binary for the wrong target. JUST_VERSION="1.58.0" +# Print the release target for the current Linux or macOS architecture. +# Unrecognised platforms print an empty line with a successful exit status. just_target() { case "$(uname -s 2>/dev/null):$(uname -m 2>/dev/null)" in Linux:x86_64|Linux:amd64) echo "x86_64-unknown-linux-musl" ;; @@ -145,6 +147,8 @@ just_target() { esac } +# Print the pinned release archive SHA-256 for the target in $1. +# Unrecognised targets print an empty line with a successful exit status. just_sha256() { case "$1" in x86_64-unknown-linux-musl) echo "4a5cc2f53e6f0f8c59092a6cc38291eb729d46a7dd95d3ae582008881b84931d" ;; @@ -155,13 +159,21 @@ just_sha256() { esac } +# Print the SHA-256 of the file at $1 to standard output. # sha256sum is GNU; macOS ships shasum instead. +# A hashing failure can produce no output yet return success via cut. sha256_of() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d" " -f1 else shasum -a 256 "$1" | cut -d" " -f1 fi } +# Download and checksum-verify JUST_VERSION for this platform, then use sudo +# to install it as /usr/local/bin/just with mode 0755, replacing any existing file. +# Return 1 for an unsupported platform, download failure, checksum mismatch or +# failure to create /usr/local/bin. Temporary files are removed on these handled +# failures and after installation. If execution reaches cleanup, return its status; +# in the conditional call from main, extraction or copy failures can be masked. install_just_verified() { jv_target="$(just_target)" [ -z "$jv_target" ] && { fail "just: no verified build for $(uname -s)/$(uname -m); use your package manager"; return 1; } @@ -182,6 +194,10 @@ install_just_verified() { } # ── Install just ── +# Keep an existing just command, or install using the detected PKG_MGR. +# Use the verified release if apt fails or PKG_MGR has no supported install branch. +# Return 1 if just is still unavailable on PATH; the final availability check +# determines success in main's conditional call even if an installer failed. install_just() { if command -v just >/dev/null 2>&1; then ok "just already installed: $(just --version 2>/dev/null | head -1)"