From ab364a10c8bfab9ff18acb09bcc5232d1cc8dee0 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Wed, 7 Oct 2026 16:55:43 +0000 Subject: [PATCH] Build boxes: the engine gate (igneumd and igneum-miner fetched by build-remote must carry igneum-pow/src/ paths; a commit string alone does not prove the engine: the stub-engine 21d8f454 that rejected every block on the Devnet 3 hub, 7 Oct 2026); tools/ci/engine-check.sh with its self-test in the gate Co-Authored-By: Claude Fable 5.1 --- tools/build-remote.sh | 3 +++ tools/ci/engine-check.sh | 24 ++++++++++++++++++++++++ tools/ci/pre-push.sh | 1 + 3 files changed, 28 insertions(+) create mode 100755 tools/ci/engine-check.sh diff --git a/tools/build-remote.sh b/tools/build-remote.sh index ea8d27a4..365f4193 100755 --- a/tools/build-remote.sh +++ b/tools/build-remote.sh @@ -255,6 +255,9 @@ if [ "$FETCH" = 1 ] && [ -n "$ARTEFACTS" ]; then bs_log "artefact $dest: $(bs_size "$dest") bytes, sha256 $(bs_sha256 "$dest"), $(file -b "$dest" | cut -c1-60)" # the commit-string gate (rule of 6 October 2026): a node binary without its commit in its strings fails the run case "$BS_KIND:$(basename "$dest")" in node:igneumd) "$HERE/ci/commit-string-check.sh" "$dest" "$BS_SHA" || bs_die "commit-string gate failed for $a" ;; esac # only kaspad depends on kaspa-build-info + # the engine gate (7 Oct 2026, the Devnet 3 start): igneumd and igneum-miner must carry igneum-pow/src/ paths; a commit string + # alone does not prove the engine (a stub-engine 21d8f454 rejected every mined block on the fleet's hub) + case "$BS_KIND:$(basename "$dest")" in node:igneumd|node:igneum-miner) [ "${IGNEUM_ALLOW_STUB:-}" = 1 ] || "$HERE/ci/engine-check.sh" "$dest" || bs_die "engine gate failed for $a (IGNEUM_ALLOW_STUB=1 to fetch a stub-engine binary on purpose)" ;; esac # the glibc ceiling of anything that ships (main, 7 Oct 2026): a seed or a rig refuses a binary needing more than 2.36 if [ "$SHIP" = 1 ]; then "$HERE/ci/glibc-ceiling-check.sh" "$dest" "$GLIBC" || bs_die "glibc ceiling gate failed for $a"; fi done diff --git a/tools/ci/engine-check.sh b/tools/ci/engine-check.sh new file mode 100755 index 00000000..15340078 --- /dev/null +++ b/tools/ci/engine-check.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# The engine gate (7 October 2026, the Devnet 3 start): a 21d8f454 igneumd with its commit string twice but ZERO igneum-pow/src/ +# paths was placed in the artefact folder by a build outside the app tree; the fleet's hub ran it, the igneum-pow miner's blocks +# were every one rejected (Reject(BlockInvalid)), the go stopped. The commit-string gate cannot see this: the string comes from the +# fork's own git, the engine from the igneum-pow tree the build sat next to. So every igneumd and igneum-miner that +# tools/build-remote.sh fetches must carry igneum-pow source paths in its strings (rustc embeds the panic locations of the engine +# crate it compiled in: igneum-pow/src/...); none means the stub engine or a foreign igneum-pow, and the fetch refuses. +# +# tools/ci/engine-check.sh # exit 0 with the count, exit 1 "no igneum-pow/src/ path in " +# tools/ci/engine-check.sh --self-test # a fixture with the paths passes, one without fails +set -euo pipefail +if [ "${1:-}" = --self-test ]; then + t=$(mktemp -d); trap 'rm -rf "$t"' EXIT + printf 'binary junk\0/srv/builds/x/igneum-pow/src/lib.rs\0more junk\0igneum-pow/src/lottery.rs\0' > "$t/good" + printf 'binary junk\0/srv/builds/x/consensus/pow/src/stub.rs\0commit 21d8f454\0' > "$t/bad" + "$0" "$t/good" >/dev/null || { echo "engine-check self-test: a binary WITH igneum-pow paths was refused"; exit 1; } + if "$0" "$t/bad" >/dev/null 2>&1; then echo "engine-check self-test: a binary WITHOUT igneum-pow paths passed"; exit 1; fi + echo "engine-check self-test: a binary with igneum-pow/src/ paths passes, one without is refused"; exit 0 +fi +f="${1:-}"; [ -f "$f" ] || { echo "engine-check: no file '$f'" >&2; exit 2; } +n=$(LC_ALL=C grep -a -c 'igneum-pow/src/' "$f" || true) +if [ "${n:-0}" -gt 0 ]; then echo "engine-check: $(basename "$f") carries $n igneum-pow/src/ path line(s): the igneum-pow engine"; exit 0; fi +echo "engine-check: no igneum-pow/src/ path in $(basename "$f"): the stub engine or a foreign igneum-pow tree (the commit string alone does not prove the engine; 7 Oct 2026 Devnet 3)" >&2 +exit 1 diff --git a/tools/ci/pre-push.sh b/tools/ci/pre-push.sh index 5699d52c..152303a5 100755 --- a/tools/ci/pre-push.sh +++ b/tools/ci/pre-push.sh @@ -95,6 +95,7 @@ tree_checks() { run "pinned guest programs match their manifest" bash tools/ci/pinned-guests-check.sh run "root prover playbooks kill the GPU server and unlink its socket" bash tools/ci/prover-socket-check.sh run "commit-string gate self-test" bash tools/ci/commit-string-check.sh --self-test + run "engine gate self-test (igneumd and igneum-miner must carry igneum-pow/src/ paths)" bash tools/ci/engine-check.sh --self-test run "build server remote checkout self-test" bash infra/build-server/remote-run.sh --self-test run "a slot holder keeps its own line for the whole run (the watcher-trust rule)" bash infra/build-server/remote-run.sh --self-test-keeper run "the remote checkout resets the mirror's tree before the branch checkout (the stale-overlay class)" bash -c 'bash tools/ci/mirror-reset-check.sh --self-test && bash tools/ci/mirror-reset-check.sh'