From c9af680ddd6c066eb4bf210e62c4efb6b3d703c1 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Wed, 7 Oct 2026 20:37:40 +0000 Subject: [PATCH] class v5 kits: the box-side body moved out of the inline command string into tools/class-v5/kits-on-box.sh, run by path from the mirror checkout (main's inline-rm rule of 21:33 BST: no rm, find -delete or truncation inside a bash -c string); kits-remote.sh now only syncs the sources and calls it Co-Authored-By: Claude Fable 5.1 --- tools/class-v5/kits-on-box.sh | 86 ++++++++++++++++++++++++++++++++++ tools/class-v5/kits-remote.sh | 87 +++-------------------------------- 2 files changed, 93 insertions(+), 80 deletions(-) create mode 100755 tools/class-v5/kits-on-box.sh diff --git a/tools/class-v5/kits-on-box.sh b/tools/class-v5/kits-on-box.sh new file mode 100755 index 00000000..5a74d083 --- /dev/null +++ b/tools/class-v5/kits-on-box.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +# The class v5 kit build as it runs ON igneum-build-1 (called by tools/class-v5/kits-remote.sh through the build-server +# library's remote runner, from the worktree's mirror checkout, so this file travels with the commit). A script file by +# path, never an inline string: main's rule of 7 October 2026, 21:33 BST (no rm, find -delete or truncation inside a +# `bash -c` string; tools/ci/inline-rm-check.sh). What it does, in order: the pack loader test with the class v5 cases, +# the Linux and Windows builds of the two one-click workers, the CPU emulation's --check on the class v5 pack, then the +# kit zip at /srv/artefacts/packs/packs-ca3-v5-.zip with SHA256SUMS. Logs land in /srv/builds/_log/v5-class/kits-. +# bash tools/class-v5/kits-on-box.sh (cwd = the worktree root on the box) +set -u +STAMP="${1:?stamp}"; SKIP_EMU="${2:-0}" +ZIP="/srv/artefacts/packs/packs-ca3-v5-$STAMP.zip" +LOGDIR="/srv/builds/_log/v5-class/kits-$STAMP" +T=$(mktemp -d /tmp/v5-kits.XXXXXX); S=$T/stage; mkdir -p "$S/bin/linux" "$S/bin/windows" "$S/src" "$S/packs" "$S/tools" "$LOGDIR" +rc=0 +step() { echo "STEP $1 $(date -u +%H:%M:%SZ)"; } +fail() { echo "FAIL $1"; rc=1; } +finish() { cp "$T"/*.log "$LOGDIR"/ 2>/dev/null; echo "LOGS $LOGDIR"; rm -rf "$T"; } +V5=proto-cuda/packs-ca3-v5/v5-dn3-epoch0 +step packfile-test +cc -std=c99 -Wall -Wextra -Wno-unused-function -O1 -o "$T/packfile-test" proto-cuda/nvrtc/emu/packfile-test.c && "$T/packfile-test" proto-cuda/packs/igneum-devnet-v4-epoch0 "$V5" > "$T/packfile-test.log" 2>&1 || fail "packfile-test ($(tail -1 "$T/packfile-test.log"))" +grep -E '^(FAIL| v5 pack)' "$T/packfile-test.log"; grep -c '^ok' "$T/packfile-test.log" | sed 's/^/packfile-test ok lines /' +step linux-opencl-worker +gcc -std=c99 -O2 -Wall -Wextra -Wno-stringop-truncation -Wno-format-truncation -DIGNEUM_CL_DYNAMIC -DCL_TARGET_OPENCL_VERSION=120 -I proto-cuda/packs/igneum-devnet-v4-epoch0 -DIGNEUM_KERNEL_PATH='"kernel_bound.cl"' -o "$S/bin/linux/igneum-worker-opencl" proto-opencl/host.c -ldl -lpthread 2> "$T/cl-linux.log" || { fail "linux opencl worker"; head -20 "$T/cl-linux.log"; } +step linux-cuda-worker +g++ -std=c++17 -O2 -Wall -Wextra -I proto-cuda/nvrtc -I /usr/local/cuda/include -o "$S/bin/linux/igneum-worker-cuda" proto-cuda/nvrtc/worker.cpp -ldl -lpthread 2> "$T/cuda-linux.log" || { fail "linux cuda worker"; head -20 "$T/cuda-linux.log"; } +step windows-cuda-worker +x86_64-w64-mingw32-g++ -std=c++17 -O2 -Wall -Wextra -static -I proto-cuda/nvrtc -I /usr/local/cuda/include -o "$S/bin/windows/igneum-worker-cuda.exe" proto-cuda/nvrtc/worker.cpp 2> "$T/cuda-win.log" && x86_64-w64-mingw32-strip "$S/bin/windows/igneum-worker-cuda.exe" || { fail "windows cuda worker"; head -20 "$T/cuda-win.log"; } +step windows-opencl-worker +# the Khronos CL headers alone (never -I /usr/include: that puts glibc's stdint.h ahead of mingw's) +mkdir -p "$T/inc" && cp -r /usr/include/CL "$T/inc/" +x86_64-w64-mingw32-gcc -std=c99 -O2 -Wall -Wextra -Wno-stringop-truncation -Wno-format-truncation -static -DIGNEUM_CL_DYNAMIC -DCL_TARGET_OPENCL_VERSION=120 -I "$T/inc" -I proto-cuda/packs/igneum-devnet-v4-epoch0 -DIGNEUM_KERNEL_PATH='"kernel_bound.cl"' -o "$S/bin/windows/igneum-worker-opencl.exe" proto-opencl/host.c 2> "$T/cl-win.log" && x86_64-w64-mingw32-strip "$S/bin/windows/igneum-worker-opencl.exe" || { fail "windows opencl worker"; head -20 "$T/cl-win.log"; } +if [ "$SKIP_EMU" = 0 ]; then + step emu-check-v5 + # the CPU emulation (proto-cuda/nvrtc/emu/test.sh's build) with pack A = the class v5 pack and pack B = the v4 control + E=$T/emu; mkdir -p "$E" + emu_kernel() { { echo '#include '; echo '#include '; echo "namespace $2 {"; sed -E 's/([A-Za-z_0-9]+)<<<([^,]+), ([^>]+)>>>\(/emu_launch(\1, \2, \3, /' "$1/$3.cu"; echo "}"; } > "$E/$3_$2.cpp"; g++ -std=c++17 -O2 -w -I proto-cuda/emu -I "$1" -c "$E/$3_$2.cpp" -o "$E/$3_$2.o"; } + emu_kernel "$V5" emu_pack_a kernel && emu_kernel "$V5" emu_pack_a kernel_bound && emu_kernel proto-cuda/packs-ca3-v5/v4-genesis emu_pack_b kernel && emu_kernel proto-cuda/packs-ca3-v5/v4-genesis emu_pack_b kernel_bound \ + && g++ -std=c++17 -O2 -Wall -Wextra -DIGNEUM_EMU -I proto-cuda/nvrtc -I /usr/local/cuda/include -c proto-cuda/nvrtc/worker.cpp -o "$E/worker.o" \ + && g++ -std=c++17 -O2 -Wall -Wextra -DIGNEUM_EMU -DIGNEUM_EMU_TWO_PACKS -I proto-cuda/nvrtc -I proto-cuda/emu -I /usr/local/cuda/include -c proto-cuda/nvrtc/emu/emu_backend.cpp -o "$E/emu_backend.o" \ + && g++ -std=c++17 -O2 -w -I proto-cuda/emu -c proto-cuda/emu/shim.cpp -o "$E/shim.o" \ + && g++ -o "$E/igneum-worker-cuda-emu" "$E"/*.o -pthread 2> "$T/emu-build.log" || { fail "emu build"; head -30 "$T/emu-build.log"; } + if [ -x "$E/igneum-worker-cuda-emu" ]; then + ( IGNEUM_EMU_PACK="$PWD/$V5" IGNEUM_EMU_PACK2="$PWD/proto-cuda/packs-ca3-v5/v4-genesis" timeout 1500 nice -n 10 "$E/igneum-worker-cuda-emu" --check --pack "$V5" > "$T/emu-check.log" 2>&1 ) || fail "emu --check on the class v5 pack (rc $?)" + grep -E '^check PASS|self-test|FAIL|error' "$T/emu-check.log" | cut -c1-400 + fi +fi +if [ "$rc" != 0 ]; then echo "KIT not written: a step failed (rc $rc)"; finish; exit 1; fi +step stage +for p in v4-genesis v5-genesis v5-dn3-epoch0; do mkdir -p "$S/packs/$p"; cp proto-cuda/packs-ca3-v5/$p/* "$S/packs/$p/"; done +cp proto-cuda/nvrtc/worker.cpp proto-cuda/nvrtc/packfile.h proto-cuda/nvrtc/cuda_api.h proto-opencl/host.c proto-opencl/cl_dynamic.h proto-newpow/class-v5/bench.cu proto-newpow/class-v5/run.sh proto-metal/packbench.swift "$S/src/" +cp tools/class-v5/fleet-cuda-v5-bench.sh tools/class-v5/pc1-amd-v5-bench.ps1 "$S/tools/" +cat > "$S/README.txt" <<'R' +packs-ca3-v5: the class v5 kit (Igneum, 7 October 2026; docs/design/class-v5-stored-state.md) +packs/v5-dn3-epoch0 the first class v5 pack: Devnet 3 epoch 0, program id e5a4ac5978462156, 11 state leaves (leaves.bin, 704 B) under + state root 7e37a9fb19b154d32daf5bf30a50d339a75029fbc9eec9ea20e95439dba5a311, cache FNV-1a 64 7334fa46e5d972eb + expected fingerprint of the 2^24 outputs at base nonce 0: 82b19cbde8557ea5 (Metal, M5 Max, 18:07:09Z) on every platform +packs/v5-genesis the string-seed class v5 pack over the devnet's 93 leaves; packs/v4-genesis the class v4 control (sub-version 3) +bin/linux igneum-worker-cuda (NVRTC, libcuda + libnvrtc.so.12 at run time), igneum-worker-opencl (libOpenCL.so.1 at run time) +bin/windows igneum-worker-cuda.exe (nvcuda.dll + nvrtc64 at run time), igneum-worker-opencl.exe (OpenCL.dll at run time) +Every worker reads a class v5 pack's leaves.bin, checks it against the pack's IGNEUM_STATE_LEAVES_FNV64, uploads it for igneum_build and +frees it after the build; a pack without its leaves builds nothing. Self-test: cache head, last line and FNV; dataset head, last word and +64 samples; 96 vector lanes. Bench: igneum-worker-cuda --bench --pack packs/v5-dn3-epoch0 --batch-log2 24 (fleet-cuda-v5-bench.sh); +igneum-worker-opencl --bench-pack --pack packs/v5-dn3-epoch0 --batch-log2 24 --device (pc1-amd-v5-bench.ps1); src/bench.cu with nvcc. +Intel: not measured tonight (7 October 2026); no Arc B580 sits on PC 1 or PC 2 and the only Arc path needs a driver click, which no PC job +may raise; the card's holder and a click-free driver path are owed. The OpenCL worker takes the Intel device by index the same way. +R +( cd "$S" && find . -type f ! -name SHA256SUMS | sort | xargs sha256sum > SHA256SUMS ) +mkdir -p /srv/artefacts/packs +python3 - "$S" "$ZIP" <<'PY' +import os, sys, zipfile +stage, out = sys.argv[1], sys.argv[2] +with zipfile.ZipFile(out, 'w', zipfile.ZIP_DEFLATED) as z: + for dp, dn, fn in os.walk(stage): + dn.sort() + for f in sorted(fn): + p = os.path.join(dp, f); rel = os.path.relpath(p, stage) + zi = zipfile.ZipInfo(rel, date_time=(2026, 10, 7, 0, 0, 0)); zi.compress_type = zipfile.ZIP_DEFLATED + zi.external_attr = (0o755 if rel.startswith('bin/') or rel.endswith('.sh') else 0o644) << 16 + with open(p, 'rb') as fh: z.writestr(zi, fh.read()) +PY +sha256sum "$ZIP" | cut -c1-64 > "$ZIP.sha256" +echo "KIT $ZIP bytes $(stat -c %s "$ZIP") files $(python3 -c "import zipfile,sys; print(len(zipfile.ZipFile(sys.argv[1]).namelist()))" "$ZIP")" +echo "KIT sha256 $(cat "$ZIP.sha256")" +for b in "$S"/bin/linux/* "$S"/bin/windows/*; do echo "BIN $(basename "$(dirname "$b")")/$(basename "$b") $(stat -c %s "$b") bytes sha256 $(sha256sum "$b" | cut -c1-64)"; done +finish +exit 0 diff --git a/tools/class-v5/kits-remote.sh b/tools/class-v5/kits-remote.sh index 1bd365c5..15c43d55 100755 --- a/tools/class-v5/kits-remote.sh +++ b/tools/class-v5/kits-remote.sh @@ -12,7 +12,10 @@ # IGNEUM_AGENT=v5-kits tools/class-v5/kits-remote.sh [--box 1] [--skip-emu] # # Takes one of the box's build slots through infra/build-server/remote-run.sh (bs_remote_run), box 1 by default (the -# build-server lane's word of 7 October 2026, 19:4x BST: the kit builds on build-1 explicitly). +# build-server lane's word of 7 October 2026, 19:4x BST: the kit builds on build-1 explicitly). The work itself is +# tools/class-v5/kits-on-box.sh, a script file run by path on the box (the inline-rm rule of 21:33 BST); when the +# build-server lane's lease tool is in place, the same file goes through `/srv/builds/_bin/lease pool -- bash +# tools/class-v5/kits-on-box.sh ...` with the label "v5 kit". set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BS_TOOL=class-v5-kits @@ -31,85 +34,9 @@ ZIP="/srv/artefacts/packs/packs-ca3-v5-$STAMP.zip" bs_toolchain_check bs_sync_sources bs_log "sources at $WT (commit $BS_SHA on $BS_BRANCH); building the class v5 kits on box $BOX" -read -r -d '' CMD < \$T/packfile-test.log 2>&1 || fail "packfile-test (\$(tail -1 \$T/packfile-test.log))" -grep -E '^(FAIL| v5 pack)' \$T/packfile-test.log; grep -c '^ok' \$T/packfile-test.log | sed 's/^/packfile-test ok lines /' -step linux-opencl-worker -gcc -std=c99 -O2 -Wall -Wextra -Wno-stringop-truncation -Wno-format-truncation -DIGNEUM_CL_DYNAMIC -DCL_TARGET_OPENCL_VERSION=120 -I proto-cuda/packs/igneum-devnet-v4-epoch0 -DIGNEUM_KERNEL_PATH='"kernel_bound.cl"' -o \$S/bin/linux/igneum-worker-opencl proto-opencl/host.c -ldl -lpthread 2> \$T/cl-linux.log || { fail "linux opencl worker"; head -20 \$T/cl-linux.log; } -step linux-cuda-worker -g++ -std=c++17 -O2 -Wall -Wextra -I proto-cuda/nvrtc -I /usr/local/cuda/include -o \$S/bin/linux/igneum-worker-cuda proto-cuda/nvrtc/worker.cpp -ldl -lpthread 2> \$T/cuda-linux.log || { fail "linux cuda worker"; head -20 \$T/cuda-linux.log; } -step windows-cuda-worker -x86_64-w64-mingw32-g++ -std=c++17 -O2 -Wall -Wextra -static -I proto-cuda/nvrtc -I /usr/local/cuda/include -o \$S/bin/windows/igneum-worker-cuda.exe proto-cuda/nvrtc/worker.cpp 2> \$T/cuda-win.log && x86_64-w64-mingw32-strip \$S/bin/windows/igneum-worker-cuda.exe || { fail "windows cuda worker"; head -20 \$T/cuda-win.log; } -step windows-opencl-worker -# the Khronos CL headers alone (never -I /usr/include: that puts glibc's stdint.h ahead of mingw's) -mkdir -p \$T/inc && cp -r /usr/include/CL \$T/inc/ -x86_64-w64-mingw32-gcc -std=c99 -O2 -Wall -Wextra -Wno-stringop-truncation -Wno-format-truncation -static -DIGNEUM_CL_DYNAMIC -DCL_TARGET_OPENCL_VERSION=120 -I \$T/inc -I proto-cuda/packs/igneum-devnet-v4-epoch0 -DIGNEUM_KERNEL_PATH='"kernel_bound.cl"' -o \$S/bin/windows/igneum-worker-opencl.exe proto-opencl/host.c 2> \$T/cl-win.log && x86_64-w64-mingw32-strip \$S/bin/windows/igneum-worker-opencl.exe || { fail "windows opencl worker"; head -20 \$T/cl-win.log; } -if [ $SKIP_EMU = 0 ]; then - step emu-check-v5 - # the CPU emulation (proto-cuda/nvrtc/emu/test.sh's build) with pack A = the class v5 pack and pack B = the v4 control - E=\$T/emu; mkdir -p \$E - emu_kernel() { { echo '#include '; echo '#include '; echo "namespace \$2 {"; sed -E 's/([A-Za-z_0-9]+)<<<([^,]+), ([^>]+)>>>\\(/emu_launch(\\1, \\2, \\3, /' "\$1/\$3.cu"; echo "}"; } > "\$E/\$3_\$2.cpp"; g++ -std=c++17 -O2 -w -I proto-cuda/emu -I "\$1" -c "\$E/\$3_\$2.cpp" -o "\$E/\$3_\$2.o"; } - emu_kernel \$V5 emu_pack_a kernel && emu_kernel \$V5 emu_pack_a kernel_bound && emu_kernel proto-cuda/packs-ca3-v5/v4-genesis emu_pack_b kernel && emu_kernel proto-cuda/packs-ca3-v5/v4-genesis emu_pack_b kernel_bound \\ - && g++ -std=c++17 -O2 -Wall -Wextra -DIGNEUM_EMU -I proto-cuda/nvrtc -I /usr/local/cuda/include -c proto-cuda/nvrtc/worker.cpp -o \$E/worker.o \\ - && g++ -std=c++17 -O2 -Wall -Wextra -DIGNEUM_EMU -DIGNEUM_EMU_TWO_PACKS -I proto-cuda/nvrtc -I proto-cuda/emu -I /usr/local/cuda/include -c proto-cuda/nvrtc/emu/emu_backend.cpp -o \$E/emu_backend.o \\ - && g++ -std=c++17 -O2 -w -I proto-cuda/emu -c proto-cuda/emu/shim.cpp -o \$E/shim.o \\ - && g++ -o \$E/igneum-worker-cuda-emu \$E/*.o -pthread 2> \$T/emu-build.log || { fail "emu build"; head -30 \$T/emu-build.log; } - if [ -x \$E/igneum-worker-cuda-emu ]; then - ( IGNEUM_EMU_PACK=\$PWD/\$V5 IGNEUM_EMU_PACK2=\$PWD/proto-cuda/packs-ca3-v5/v4-genesis timeout 1500 nice -n 10 \$E/igneum-worker-cuda-emu --check --pack \$V5 > \$T/emu-check.log 2>&1 ) || fail "emu --check on the class v5 pack (rc \$?)" - grep -E '^check PASS|self-test|FAIL|error' \$T/emu-check.log | cut -c1-400 - fi -fi -if [ \$rc != 0 ]; then echo "KIT not written: a step failed (rc \$rc)"; mkdir -p /srv/builds/_log/v5-class/kits-$STAMP && cp \$T/*.log /srv/builds/_log/v5-class/kits-$STAMP/; echo "LOGS /srv/builds/_log/v5-class/kits-$STAMP"; rm -rf \$T; exit 1; fi -step stage -for p in v4-genesis v5-genesis v5-dn3-epoch0; do mkdir -p \$S/packs/\$p; cp proto-cuda/packs-ca3-v5/\$p/* \$S/packs/\$p/; done -cp proto-cuda/nvrtc/worker.cpp proto-cuda/nvrtc/packfile.h proto-cuda/nvrtc/cuda_api.h proto-opencl/host.c proto-opencl/cl_dynamic.h proto-newpow/class-v5/bench.cu proto-newpow/class-v5/run.sh proto-metal/packbench.swift \$S/src/ -cp tools/class-v5/fleet-cuda-v5-bench.sh tools/class-v5/pc1-amd-v5-bench.ps1 \$S/tools/ -cat > \$S/README.txt <<'R' -packs-ca3-v5: the class v5 kit (Igneum, 7 October 2026; docs/design/class-v5-stored-state.md) -packs/v5-dn3-epoch0 the first class v5 pack: Devnet 3 epoch 0, program id e5a4ac5978462156, 11 state leaves (leaves.bin, 704 B) under - state root 7e37a9fb19b154d32daf5bf30a50d339a75029fbc9eec9ea20e95439dba5a311, cache FNV-1a 64 7334fa46e5d972eb - expected fingerprint of the 2^24 outputs at base nonce 0: 82b19cbde8557ea5 (Metal, M5 Max, 18:07:09Z) on every platform -packs/v5-genesis the string-seed class v5 pack over the devnet's 93 leaves; packs/v4-genesis the class v4 control (sub-version 3) -bin/linux igneum-worker-cuda (NVRTC, libcuda + libnvrtc.so.12 at run time), igneum-worker-opencl (libOpenCL.so.1 at run time) -bin/windows igneum-worker-cuda.exe (nvcuda.dll + nvrtc64 at run time), igneum-worker-opencl.exe (OpenCL.dll at run time) -Every worker reads a class v5 pack's leaves.bin, checks it against the pack's IGNEUM_STATE_LEAVES_FNV64, uploads it for igneum_build and -frees it after the build; a pack without its leaves builds nothing. Self-test: cache head, last line and FNV; dataset head, last word and -64 samples; 96 vector lanes. Bench: igneum-worker-cuda --bench --pack packs/v5-dn3-epoch0 --batch-log2 24 (fleet-cuda-v5-bench.sh); -igneum-worker-opencl --bench-pack --pack packs/v5-dn3-epoch0 --batch-log2 24 --device (pc1-amd-v5-bench.ps1); src/bench.cu with nvcc. -Intel: not measured tonight (7 October 2026); no Arc B580 sits on PC 1 or PC 2 and the only Arc path needs a driver click, which no PC job -may raise; the card's holder and a click-free driver path are owed. The OpenCL worker takes the Intel device by index the same way. -R -( cd \$S && find . -type f ! -name SHA256SUMS | sort | xargs sha256sum > SHA256SUMS ) -mkdir -p /srv/artefacts/packs -python3 - "\$S" '$ZIP' <<'PY' -import os, sys, zipfile -stage, out = sys.argv[1], sys.argv[2] -with zipfile.ZipFile(out, 'w', zipfile.ZIP_DEFLATED) as z: - for dp, dn, fn in os.walk(stage): - dn.sort() - for f in sorted(fn): - p = os.path.join(dp, f); rel = os.path.relpath(p, stage) - zi = zipfile.ZipInfo(rel, date_time=(2026, 10, 7, 0, 0, 0)); zi.compress_type = zipfile.ZIP_DEFLATED - zi.external_attr = (0o755 if rel.startswith('bin/') or rel.endswith('.sh') else 0o644) << 16 - with open(p, 'rb') as fh: z.writestr(zi, fh.read()) -PY -sha256sum '$ZIP' | cut -c1-64 > '$ZIP.sha256' -echo "KIT $ZIP bytes \$(stat -c %s '$ZIP') files \$(python3 -c "import zipfile,sys; print(len(zipfile.ZipFile(sys.argv[1]).namelist()))" '$ZIP')" -echo "KIT sha256 \$(cat '$ZIP.sha256')" -for b in \$S/bin/linux/* \$S/bin/windows/*; do echo "BIN \$(basename \$(dirname \$b))/\$(basename \$b) \$(stat -c %s \$b) bytes sha256 \$(sha256sum \$b | cut -c1-64)"; done -cp \$T/*.log /srv/builds/_log/v5-class/kits-$STAMP/ 2>/dev/null || { mkdir -p /srv/builds/_log/v5-class/kits-$STAMP && cp \$T/*.log /srv/builds/_log/v5-class/kits-$STAMP/; } -echo "LOGS /srv/builds/_log/v5-class/kits-$STAMP" -rm -rf \$T -( exit \$rc ) -EOF2 +# the body runs from a script FILE at the worktree's mirror checkout (tools/class-v5/kits-on-box.sh, carried by the commit), never +# an inline string: main's rule of 7 October 2026, 21:33 BST (no rm, find -delete or truncation inside a bash -c string) +CMD="cd '$WT' && bash tools/class-v5/kits-on-box.sh '$STAMP' '$SKIP_EMU'" set +e BR_KIND=build BR_COMMAND="class v5 kits (packfile-test, emu --check v5, Linux and Windows workers, kit zip)" BR_TARGET="x86_64-linux+windows" BR_ARTEFACTS="" \ bs_remote_run "$WT" "$BS_WT class-v5 kits" "$CMD" 2>&1 | tee "/tmp/v5-kits-$STAMP.log" | grep -E '^(STEP|FAIL|KIT|BIN|LOGS|check PASS|self-test|packfile-test|emu:| v5|build-remote: RESULT)'