diff --git a/tools/ci/README.md b/tools/ci/README.md
index 4557b253a..e065a13f2 100644
--- a/tools/ci/README.md
+++ b/tools/ci/README.md
@@ -11,6 +11,7 @@
| gh's active account is the stored Igneum entry (`gh-account-check.sh`, in Igneum's own gh directory `~/.config/gh-igneum` through `gh-env.sh`, never the founder's) | A push or a landing from this Mac while Igneum's gh directory names any other account as active, or none (the refusal names the one step: the founder or main stores the Igneum token there with `GH_CONFIG_DIR=~/.config/gh-igneum gh auth login --with-token`; no lane does); skipped with a line while `github-suspended` stands. RULE: no lane switches gh accounts on this Mac, ever; the second owner's login belongs to other projects and must never touch Igneum; the stored entry's name is in ~/.config/igneum/gh-user, never in the repository. | 7 October 2026, 21:41 UK: a lane switched gh to the other login during the suspension; nobody could say which |
| F02 (Review B): the proof-rule test bypass cannot reach a release build (`proof-rule-bypass-check.sh`; a cell of the node matrix) | An env read of IGNEUM_TEST_SKIP_PROOF_RULE with no cfg(test) or cfg(feature) guard in the 12 lines above, or under a feature in the crate's default features; a release igneumd carrying the bypass string. Red on every node sha until the proving lane's change (the read under a non-default feature or cfg(test)) lands | 8 Oct 2026 |
+| the guest input format moves with the pinned guests (`guest-format-check.sh`; the diff rule in `merge-to-master.sh`, the tree rule in the gate) | A proving host whose GUEST_INPUT_FORMAT moved while the pinned guests stayed (8 October 2026, the V6-07 sub-lane: a master-built host failed every proof against the 5 October pair) |
| the test map merges structurally at a landing (`test-map-merge.py`) and the harness page regenerates from the merged map (`merge-to-master.sh`) | Nothing by itself: two lanes adding cells collided as text and the regenerated page lost rule 26's race; the merge now keeps master's cells plus the branch's, minus what the branch removed and master left, and regenerates the page | 8 Oct 2026 |
| a push that lost the ref race retries without re-running the hook (`merge-to-master.sh` `push_race`, 12 tries) | Nothing by itself: under one landing a minute a 70-second hook per try never won master's compare-and-swap (Review B's landing lost three in a row); once the hook has passed on the first try and the rejection is a ref race, later tries push --no-verify (both parents gated) | 8 Oct 2026 |
| the kit ISA check (`kit-isa-check.sh`; in the gate as a self-test, in `merge-to-master.sh` over any executable a landing adds under packaging/kits or bin, and in the shipper's cut gate over the kit) | Any binary whose disassembly carries a zmm register, an EVEX opmask or an EVEX-only mnemonic (AVX-512): a fleet binary comes only from the cross-build kit at the x86-64-v3 baseline, never from a box's native gate build (79 fleet hosts died on one, 8 Oct 2026) | 8 Oct 2026 |
diff --git a/tools/ci/checks.txt b/tools/ci/checks.txt
index 055e68453..6c8e7f0ab 100644
--- a/tools/ci/checks.txt
+++ b/tools/ci/checks.txt
@@ -80,6 +80,7 @@ the registry's evidence rules: a PASS names evidence that exists, a touched evid
the kit ISA check: a distribution kit's binaries carry no AVX-512 encoding (the x86-64-v3 baseline; self-test with a fake objdump)
F02 (Review B): the proof-rule test bypass cannot reach a release build: an env read with no cfg guard or under a default feature is red; a release binary carrying the bypass string is red (self-test)
the test map merges structurally at a landing: master's cells plus the branch's, minus what the branch removed and master left (self-test)
+the guest input format moves with the pinned guests: the elf manifest's guest_input_format equals the source constant where the field exists, a format bump without a guest change is refused at the merge (self-test, then the tree)
the REV suite is generated from Review B's findings and dispatch and matches them (self-test, then the tree)
the public ledger (docs/ledger-public.md) is what docs/fud-ledger.md generates: one row per item, no commit ids, times or team names (self-test first)
the ledger page reads both entry heading forms (M1 and AP-F8-1) so no in-house pass row is dropped from /ledger (known-failed first)
diff --git a/tools/ci/guest-format-check.sh b/tools/ci/guest-format-check.sh
new file mode 100755
index 000000000..fcc5a6df4
--- /dev/null
+++ b/tools/ci/guest-format-check.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+# The guest input format moves with the pinned guests (the V6-07 sub-lane's fault, 8 October 2026, 22:0x UK: master's proving host
+# wrote GUEST_INPUT_FORMAT 3 while the pinned guests were the 5 October pair, so a master-built host failed every proof).
+#
+# tools/ci/guest-format-check.sh
the landing rule: a diff that changes the GUEST_INPUT_FORMAT constant in
+# proving/igneum-prove/core/src/shard.rs without changing a file under
+# proving/igneum-prove/elf/ is red (the guests must be repinned with the format)
+# tools/ci/guest-format-check.sh --tree [] the tree rule: proving/igneum-prove/elf/manifest.json's guest_input_format, when
+# the field exists, equals the source constant; a manifest without the field is a
+# named line (a pre-provenance pin; igneum-prove-pin writes the field since 7d38077d); a
+# mismatch with a source_commit names the commit the kit's prover builds from (not red)
+# tools/ci/guest-format-check.sh --self-test
+set -euo pipefail
+HERE="$(cd "$(dirname "$0")" && pwd -P)"; ME="$HERE/$(basename "$0")"
+SRC="proving/igneum-prove/core/src/shard.rs"; ELF_DIR="proving/igneum-prove/elf"; MANIFEST="$ELF_DIR/manifest.json"
+
+src_format() { # -> the constant's value, or empty
+ sed -n 's/^pub const GUEST_INPUT_FORMAT: u32 = \([0-9][0-9]*\);.*/\1/p' "$1" | head -1
+}
+diff_rule() { #
+ local base="$1" head="$2" b h touched
+ b=$(git show "$base:$SRC" 2>/dev/null | src_format /dev/stdin || true)
+ h=$(git show "$head:$SRC" 2>/dev/null | src_format /dev/stdin || true)
+ [ -n "$h" ] || { echo "guest-format: no GUEST_INPUT_FORMAT constant at $head (nothing to check)"; return 0; }
+ if [ "$b" = "$h" ]; then echo "guest-format: the guest input format is unchanged ($h)"; return 0; fi
+ touched=$(git diff --name-only "$base" "$head" -- "$ELF_DIR/" | grep -c . || true)
+ if [ "${touched:-0}" -gt 0 ]; then echo "guest-format: the format moves ${b:-none} to $h with $touched file(s) under $ELF_DIR/ (the guests repinned with it)"; return 0; fi
+ echo "guest-format: REFUSED: GUEST_INPUT_FORMAT moves ${b:-none} to $h in $SRC with no change under $ELF_DIR/ (the pinned guests would refuse every input; repin the guests with the format and land both together)"
+ return 1
+}
+tree_rule() { # []
+ local root="${1:-.}" s m
+ [ -f "$root/$SRC" ] || { echo "guest-format: no $SRC in this tree (nothing to check)"; return 0; }
+ s=$(src_format "$root/$SRC"); [ -n "$s" ] || { echo "guest-format: no GUEST_INPUT_FORMAT constant in $SRC (nothing to check)"; return 0; }
+ [ -f "$root/$MANIFEST" ] || { echo "guest-format: REFUSED: no $MANIFEST beside a source format $s"; return 1; }
+ m=$(python3 -c 'import json,sys; d=json.load(open(sys.argv[1])); v=d.get("guest_input_format"); print("" if v is None else v)' "$root/$MANIFEST" 2>/dev/null || true)
+ sc=$(python3 -c 'import json,sys; d=json.load(open(sys.argv[1])); print(d.get("source_commit") or "")' "$root/$MANIFEST" 2>/dev/null || true)
+ if [ -z "$m" ]; then echo "guest-format: the pinned guests' manifest names no guest_input_format (a pre-provenance pin); the source format is $s; unverified until the guests are repinned with the field"; return 0; fi
+ if [ "$m" = "$s" ]; then echo "guest-format: the pinned guests and the source agree on guest input format $s"; return 0; fi
+ # a mismatch with provenance: the kit's prover is built from the manifest's source_commit (its format is the guests'), never this
+ # tree's tip, until the pin moves (the coordinator's shape, 8 October 2026 22:1x UK); without provenance nothing says which host
+ # the guests take and the tree is red
+ if [ -n "$sc" ]; then echo "guest-format: the pinned guests read guest input format $m from source_commit ${sc:0:12}; this tree's constant is $s, so the kit's prover builds from ${sc:0:12}, never this tip, until the guests are repinned"; return 0; fi
+ echo "guest-format: REFUSED: the pinned guests read guest input format $m, the source constant is $s, and the manifest names no source_commit (a host built from this tree fails every proof; repin the guests with provenance or move the constant back)"
+ return 1
+}
+if [ "${1:-}" = --self-test ]; then
+ d=$(mktemp -d); trap 'rm -rf "$d"' EXIT; fails=0
+ ( cd "$d" && git init -q -b master . && mkdir -p "$(dirname "$SRC")" "$ELF_DIR" && printf 'pub const GUEST_INPUT_FORMAT: u32 = 2;\n' > "$SRC" && printf 'elf' > "$ELF_DIR/a.elf" && printf '{"format":"v1"}\n' > "$MANIFEST" && git add -A && git -c user.name=t -c user.email=t@t commit -q -m base && git tag base
+ git checkout -q -b bump && printf 'pub const GUEST_INPUT_FORMAT: u32 = 3;\n' > "$SRC" && git -c user.name=t -c user.email=t@t commit -qam bump && git tag bump-alone
+ git checkout -q -b both base && printf 'pub const GUEST_INPUT_FORMAT: u32 = 3;\n' > "$SRC" && printf 'elf3' > "$ELF_DIR/a.elf" && printf '{"format":"v1","guest_input_format":3}\n' > "$MANIFEST" && git -c user.name=t -c user.email=t@t commit -qam both && git tag bump-with-guests
+ git checkout -q -b other base && printf 'x' > other.txt && git add -A && git -c user.name=t -c user.email=t@t commit -q -m other && git tag no-bump
+ git checkout -q -b off base && printf 'pub const GUEST_INPUT_FORMAT: u32 = 3;\n' > "$SRC" && printf '{"format":"v1","guest_input_format":2}\n' > "$MANIFEST" && git -c user.name=t -c user.email=t@t commit -qam off && git tag off
+ git checkout -q -b prov base && printf 'pub const GUEST_INPUT_FORMAT: u32 = 3;\n' > "$SRC" && printf '{"format":"v1","guest_input_format":1,"source_commit":"15bb6cdd4aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}\n' > "$MANIFEST" && git -c user.name=t -c user.email=t@t commit -qam prov && git tag prov ) >/dev/null 2>&1 || { echo "self-test failed: the fixture did not build"; exit 1; }
+ out=$( cd "$d" && bash "$ME" base bump-alone 2>&1 ) && { echo "self-test failed: a format bump with no guest change passed"; fails=1; }; case "$out" in *"no change under"*) ;; *) echo "self-test failed: the bump was not named: $out"; fails=1 ;; esac
+ ( cd "$d" && bash "$ME" base bump-with-guests >/dev/null 2>&1 ) || { echo "self-test failed: a format bump with repinned guests was refused: $( cd "$d" && bash "$ME" base bump-with-guests 2>&1 )"; fails=1; }
+ ( cd "$d" && bash "$ME" base no-bump >/dev/null 2>&1 ) || { echo "self-test failed: a diff without a format change was refused"; fails=1; }
+ ( cd "$d" && git checkout -q both && bash "$ME" --tree . >/dev/null 2>&1 ) || { echo "self-test failed: an agreeing manifest was refused: $( cd "$d" && bash "$ME" --tree . 2>&1 )"; fails=1; }
+ out=$( cd "$d" && git checkout -q off && bash "$ME" --tree . 2>&1 ) && { echo "self-test failed: a manifest format off the source passed"; fails=1; }; case "$out" in *"read guest input format 2, the source constant is 3"*) ;; *) echo "self-test failed: the mismatch was not named: $out"; fails=1 ;; esac
+ out=$( cd "$d" && git checkout -q prov && bash "$ME" --tree . 2>&1 ) || { echo "self-test failed: a mismatch with provenance (the kit's prover from source_commit) was refused: $out"; fails=1; }; case "$out" in *"builds from 15bb6cdd4aaa"*) ;; *) echo "self-test failed: the provenance line was not named: $out"; fails=1 ;; esac
+ out=$( cd "$d" && git checkout -q base && bash "$ME" --tree . 2>&1 ) || { echo "self-test failed: a pre-provenance manifest (no field) was refused: $out"; fails=1; }; case "$out" in *"names no guest_input_format"*) ;; *) echo "self-test failed: the unverified pin was not named: $out"; fails=1 ;; esac
+ [ "$fails" = 0 ] && echo "self-test passed: a GUEST_INPUT_FORMAT bump without a change under the elf directory is refused and named, with repinned guests it passes, a diff without the bump passes; in the tree an agreeing manifest passes, a manifest whose guest_input_format is off the source with no provenance is refused and named, one with a source_commit names the host's commit, a pin without the field is a named line"
+ exit $fails
+fi
+if [ "${1:-}" = --tree ]; then tree_rule "${2:-.}"; exit $?; fi
+[ $# -eq 2 ] || { echo "usage: $0 | --tree [] | --self-test" >&2; exit 2; }
+diff_rule "$1" "$2"
diff --git a/tools/ci/merge-to-master.sh b/tools/ci/merge-to-master.sh
index 08d8faa24..f5d2c905b 100755
--- a/tools/ci/merge-to-master.sh
+++ b/tools/ci/merge-to-master.sh
@@ -384,6 +384,9 @@ if [ -n "$KITBINS" ]; then bash tools/ci/kit-isa-check.sh $KITBINS || { echo "me
RULE26_SKIP_PATHS="$RULE26_SKIP_PATHS" bash tools/ci/rule26-no-revert.sh "$BASE" "$SHA" "$REMOTE/master" || { echo "merge-to-master: REFUSED by rule 26 (above)" >&2; exit 1; }
# the registry's evidence rules (8 October 2026, 18:4x UK): a PASS carries existing evidence, a touched evidence file moves with its
# row, stale evidence never reads PASS, a run_status needs the approval (GOV-02, GOV-04, GOV-08)
+# the guest input format moves with the pinned guests (the V6-07 sub-lane's fault, 8 October 2026 22:0x UK): a landing that changes
+# GUEST_INPUT_FORMAT without a change under proving/igneum-prove/elf/ is refused
+bash tools/ci/guest-format-check.sh "$BASE" "$SHA" || { echo "merge-to-master: REFUSED: the guest input format moved without the guests (above)" >&2; exit 1; }
[ -n "$BATCHES" ] || bash tools/ci/registry-evidence-check.sh "$BASE" "$SHA" || { echo "merge-to-master: REFUSED by the registry's evidence rules (above)" >&2; exit 1; } # with batches the rules run on the merged result below
for i in $(seq 1 "$TRIES"); do
git fetch -q "$REMOTE" master; TIP=$(git rev-parse "$REMOTE/master")
diff --git a/tools/ci/pre-push.sh b/tools/ci/pre-push.sh
index 88b019638..a1c1bc721 100755
--- a/tools/ci/pre-push.sh
+++ b/tools/ci/pre-push.sh
@@ -179,6 +179,7 @@ tree_checks() {
run "the kit ISA check: a distribution kit's binaries carry no AVX-512 encoding (the x86-64-v3 baseline; self-test with a fake objdump)" bash tools/ci/kit-isa-check.sh --self-test
run "F02 (Review B): the proof-rule test bypass cannot reach a release build: an env read with no cfg guard or under a default feature is red; a release binary carrying the bypass string is red (self-test)" bash tools/ci/proof-rule-bypass-check.sh --self-test
run "the test map merges structurally at a landing: master's cells plus the branch's, minus what the branch removed and master left (self-test)" python3 tools/ci/test-map-merge.py --self-test
+ run "the guest input format moves with the pinned guests: the elf manifest's guest_input_format equals the source constant where the field exists, a format bump without a guest change is refused at the merge (self-test, then the tree)" bash -c 'bash tools/ci/guest-format-check.sh --self-test >/dev/null && bash tools/ci/guest-format-check.sh --tree .'
run "the REV suite is generated from Review B's findings and dispatch and matches them (self-test, then the tree)" bash tools/ci/review-suite-check.sh
run "the public ledger (docs/ledger-public.md) is what docs/fud-ledger.md generates: one row per item, no commit ids, times or team names (self-test first)" bash -c 'node tools/ledger/export-public.mjs --self-test && node tools/ledger/export-public.mjs --check'
run "the ledger page reads both entry heading forms (M1 and AP-F8-1) so no in-house pass row is dropped from /ledger (known-failed first)" node tools/ledger-page.mjs --self-test