Staging rule: publish-jobs.sh --deploy ships a jobs-only change (refuses when anything else differs from the live folder); restart-seed.sh refuses a binary whose GLIBC need exceeds the seed's; the CLAUDE.md rule
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
10112d1df7
commit
60e78a56ba
2 changed files with 36 additions and 0 deletions
|
|
@ -13,6 +13,15 @@ SRC="${IGNEUMD_LINUX:-/Users/joshm/Projects/igneum/infra/cross/out-039/igneumd}"
|
|||
WANT="${IGNEUMD_LINUX_SHA256:-7e26e374586ad8ba539e371c6cbbd74f0f77aee1e2e97cd25f0182fcbda458a5}"
|
||||
echo "$OVJSON" | python3 -c 'import json,sys; o=json.load(sys.stdin); assert isinstance(o, dict) and "fees_v1_activation_daa" in o; print("override:", json.dumps(o, sort_keys=True))'
|
||||
test "$(shasum -a 256 "$SRC" | cut -c1-64)" = "$WANT" || { echo "$SRC is not the 2b6d23ef Linux node ($WANT)"; exit 1; }
|
||||
# the seed is Debian 12 (glibc 2.36): a binary built on igneum-build-1 (Ubuntu 24.04, glibc 2.39) does not start there
|
||||
# ("version GLIBC_2.38 not found", a restart loop; 6 October 2026, 21:43Z, three minutes down). The zigbuild from
|
||||
# infra/cross/build-linux.sh (glibc 2.36 target) is the seed's binary. Refused here before anything is copied.
|
||||
NEED="$(strings "$SRC" | grep -oE 'GLIBC_2\.[0-9]+' | sort -t. -k2 -n | tail -1 | sed 's/GLIBC_//')"
|
||||
HOST_GLIBC="$(ssh -i "$HOME/.ssh/igneum_ed25519" -o ConnectTimeout=8 root@188.245.5.161 'ldd --version 2>/dev/null | head -1 | grep -oE "[0-9]+\.[0-9]+$"' 2>/dev/null || echo 2.36)"
|
||||
if [ -n "$NEED" ] && [ "$(printf '%s\n%s\n' "$NEED" "$HOST_GLIBC" | sort -t. -k1,1n -k2,2n | tail -1)" != "$HOST_GLIBC" ]; then
|
||||
echo "$SRC needs GLIBC $NEED but the seed has $HOST_GLIBC: build it with infra/cross/build-linux.sh (zigbuild, glibc 2.36) and pass that one"; exit 1
|
||||
fi
|
||||
echo "binary needs GLIBC $NEED, the seed has $HOST_GLIBC"
|
||||
SSH="ssh -i $HOME/.ssh/igneum_ed25519 -o ConnectTimeout=20 root@188.245.5.161"
|
||||
# 6 October 2026 (the exec recovery after the 15:44Z reorg): IGNEUMD_EXEC_SNAPSHOT_FILE=<local file> copies that exec snapshot to the
|
||||
# seed (/root/v4/exec-snapshot.bin) and adds --igneum-exec-snapshot=<path>,0x<sha256> to EXTRA_ARGS in seed-v4.env (replacing an
|
||||
|
|
|
|||
|
|
@ -404,6 +404,33 @@ if [ -n "$NEXT_FOLDER" ]; then
|
|||
cp "$JOBS" "$JOBS.sig" "$SIGNED" "$NEXT_FOLDER/" && echo "jobs file, signature and envelope mirrored to the next folder"
|
||||
fi
|
||||
|
||||
# --deploy ships the JOBS FILE ONLY (6 October 2026, 22:0x UK rule): the downloads folder is shared disk state and a deploy
|
||||
# ships all of it, so a manifest or a package staged there by another lane went live with the next job publish (the Mac and
|
||||
# PC 1 took earlier 0.3.15 builds that way). Before deploying, every file in the live token folder and dl/public/ apart from
|
||||
# the jobs file and its signature must equal what is live (size and sha256 against the served copy); anything else differing
|
||||
# refuses the deploy and names the files. The release's own deploy goes through packaging/ota/publish-manifest.sh --deploy or
|
||||
# tools/ship-app.mjs, never through here. IGNEUM_JOBS_DEPLOY_ALL=1 overrides, knowingly, for a full-folder deploy.
|
||||
jobs_only_check() {
|
||||
[ "${IGNEUM_JOBS_DEPLOY_ALL:-0}" = 1 ] && { echo "IGNEUM_JOBS_DEPLOY_ALL=1: deploying the whole folder" >&2; return 0; }
|
||||
local base="https://dl.igneum.network" bad=0 f n live_size local_size local_sha live_sha
|
||||
for f in "$DEST"/* "$DLSITE"/dl/public/*; do
|
||||
[ -f "$f" ] || continue
|
||||
n="$(basename "$f")"
|
||||
case "$n" in igneum-jobs.json|igneum-jobs.signed.json|igneum-jobs.json.sig) continue ;; esac
|
||||
local rel; rel="${f#"$DLSITE"}"
|
||||
local_size="$(stat -f %z "$f" 2>/dev/null || stat -c %s "$f")"
|
||||
live_size="$(curl -sI -m 10 -H 'Cache-Control: no-cache' "$base$rel?x=$RANDOM" | awk 'tolower($1)=="content-length:"{print $2}' | tr -d '\r' | tail -1)"
|
||||
if [ -z "$live_size" ]; then echo " not live yet: $rel (a new file; the release step deploys it)" >&2; bad=1; continue; fi
|
||||
if [ "$live_size" != "$local_size" ]; then echo " differs from the live copy: $rel (local $local_size B, live $live_size B)" >&2; bad=1; continue; fi
|
||||
case "$n" in *.json|*.sig|*.sha256) # small: compare the bytes
|
||||
local_sha="$(shasum -a 256 "$f" | cut -c1-64)"; live_sha="$(curl -s -m 15 -H 'Cache-Control: no-cache' "$base$rel?x=$RANDOM" | shasum -a 256 | cut -c1-64)"
|
||||
[ "$local_sha" = "$live_sha" ] || { echo " differs from the live copy: $rel (content)" >&2; bad=1; } ;;
|
||||
esac
|
||||
done
|
||||
if [ "$bad" = 1 ]; then echo "publish-jobs: the folder holds changes besides the jobs file (above); a job publish never deploys them. Deploy the release through publish-manifest.sh --deploy or ship-app.mjs, or stage elsewhere. Not deployed." >&2; return 1; fi
|
||||
return 0
|
||||
}
|
||||
if [ "$DEPLOY" = 1 ] && ! jobs_only_check; then DEPLOY=0; echo "the jobs file is written and signed locally; the deploy was refused" >&2; exit 1; fi
|
||||
if [ "$DEPLOY" = 1 ]; then
|
||||
[ -n "$DLSITE" ] || { echo "--deploy needs the real downloads folder (no --dest)" >&2; exit 1; }
|
||||
echo "deploying $DLSITE"
|
||||
|
|
|
|||
Loading…
Reference in a new issue