igneum/tools/ci/identity-check.sh
igneum-labs 70bed1065a CI on every push: igneum-pow tests, census build, simulator quick modes, site build + link check, identity grep
GitHub Actions workflow (.github/workflows/ci.yml) on push and pull_request with three jobs on the free runners:
igneum-pow `cargo test --release` and the igneum-census build; the two Python simulators' --quick modes under a
120-second timeout; the site build, an internal link check of site/*.html (tools/ci/link-check.mjs) and a gh-free
identity grep of the public export list (tools/ci/identity-check.sh over tools/ci/forbidden-strings.txt: machine
names, LAN and overlay addresses, home paths, local time zones, the log-intake key pattern; never a key or a name).
The node fork is too big for CI today and the workflow says so.

sim/finality_v2.py --quick is now a genuine smoke run (one day or hour per scenario, one partition and one eclipse
setting): 149 s at nice 19 on a loaded Mac, was 745 s. sim/difficulty/sim.py gains --quick (up50 and warmup-hard,
kaspa and igneum controllers, 36 s). One bench-log time-zone label reworded so the identity grep passes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 09:57:34 +00:00

63 lines
4.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# Identity grep of the public export list, gh-free, for CI (tools/ci/forbidden-strings.txt).
#
# Copies the paths that igneum-public/tools/sync.sh publishes into a temporary directory, applies the same generic
# scrub that sync.sh applies (model names for machines, <lan-ip> for LAN addresses, ~ for home paths, UTC stamps),
# then greps the result with the committed pattern list. A hit means a change would reach the public mirror with
# a machine name, a LAN address, a home path or the log-intake key pattern that the generic scrub does not catch.
# The private rules of the mirror (sync.local.sed, identity.local) are not here; they run at export time.
#
# tools/ci/identity-check.sh # exit 1 on any hit, with file:line
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
REPO="$(cd "$HERE/../.." && pwd)"
PATTERNS="$HERE/forbidden-strings.txt"
# The export list of igneum-public/tools/sync.sh (keep in step with it).
DIRS=(docs/spec docs/analysis sim igneum-pow igneum-census tools/harness proto-cuda/packs docs/benchmarks tools/finality-attacks tools/exec-attacks)
FILES=(docs/provenance.md docs/bench-log.md docs/evidence.md proto-cuda/README.md proto-cuda/CHECKLIST.md proto-cuda/host.cu proto-cuda/build.sh
proto-cuda/build.bat proto-cuda/.gitignore proto-cuda/emu/emu.sh proto-cuda/emu/shim.cpp proto-cuda/emu/cuda_runtime.h proto-metal/README.md
proto-metal/MEMHARD.md proto-metal/TESTS.md proto-metal/main.swift proto-opencl/README.md proto-opencl/WAVEFRONT.md proto-opencl/host.c
proto-opencl/build.sh proto-opencl/build.bat proto-opencl/.gitignore proto-opencl/emu/emu.sh proto-opencl/emu/emu_main.cpp proto-opencl/emu/emu_opencl.h)
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
for d in "${DIRS[@]}"; do [ -d "$REPO/$d" ] && { mkdir -p "$TMP/$(dirname "$d")"; cp -R "$REPO/$d" "$TMP/$d"; }; done
for f in "${FILES[@]}"; do [ -f "$REPO/$f" ] && { mkdir -p "$TMP/$(dirname "$f")"; cp "$REPO/$f" "$TMP/$f"; }; done
# prune what sync.sh prunes
find "$TMP" \( -name target -o -name __pycache__ -o -name out -o -name 'build-*' -o -name node_modules -o -name results -o -name runs \) -prune -exec rm -rf {} + 2>/dev/null || true
find "$TMP" \( -name .DS_Store -o -name '*.pyc' \) -type f -delete
# the generic scrub of sync.sh step 3 (its public half; the rules are public text, not secrets)
TEXT_FILES="$(find "$TMP" -type f \( -name '*.md' -o -name '*.rs' -o -name '*.py' -o -name '*.mjs' -o -name '*.sh' -o -name '*.bat' \
-o -name '*.c' -o -name '*.cu' -o -name '*.cl' -o -name '*.h' -o -name '*.cpp' -o -name '*.swift' -o -name '*.metal' -o -name '*.json' \
-o -name '*.csv' -o -name '*.toml' -o -name '*.txt' \) -print)"
while IFS= read -r f; do
[ -n "$f" ] || continue
perl -pi -e '
s/the PC node at 192\.168\.[0-9.]+/the RTX 5090 node on the LAN/g;
s/\bthe PC node\b/the RTX 5090 node/g;
s/\bWindows PC\b/an RTX 5090 on Windows/g;
s/\bthe PC\x27s\b/the RTX 5090 machine\x27s/g;
s/\bthe PC\b/the RTX 5090 machine/g;
s/\bPC (joins|start|period)\b/RTX 5090 $1/g;
s/192\.168\.[0-9]+\.[0-9]+/<lan-ip>/g;
s/DESKTOP-[A-Z0-9]{7}/<pc-hostname>/g;
s/~\/Desktop\//`/g; s/``/`/g;
s/~\/\.cargo\/bin\/cargo/cargo/g;
s/\/Users\/[A-Za-z0-9_.-]+/~/g;
s/C:\\Users\\[A-Za-z0-9_.-]+/%USERPROFILE%/g;
s/(\d{1,2}:\d{2}(?::\d{2})? UTC) = \d{1,2}:\d{2} B[S]T/$1/g;
s/(\d{1,2}):(\d{2})(:\d{2})? to (\d{1,2}):(\d{2})(:\d{2})? B[S]T/sprintf("%02d:%s%s to %02d:%s%s UTC",($1+23)%24,$2,$3\/\/"",($4+23)%24,$5,$6\/\/"")/ge;
s/(\d{1,2}):(\d{2})(:\d{2})? B[S]T/sprintf("%02d:%s%s UTC",($1+23)%24,$2,$3\/\/"")/ge;
' "$f"
done <<< "$TEXT_FILES"
perl -pi -e 's/\(Mac side only;/(Apple M5 Max side only;/g; s/\bthe Mac\x27s\b/the Apple M5 Max\x27s/g; s/\bthe Mac\b/the Apple M5 Max/g;' "$TMP/docs/bench-log.md" 2>/dev/null || true
PAT="$(grep -vE '^\s*(#|$)' "$PATTERNS")"
HITS="$(grep -rEn -f <(printf '%s\n' "$PAT") "$TMP" || true)"
if [ -n "$HITS" ]; then
echo "identity grep: HITS in the public export list (after the generic scrub):"
printf '%s\n' "$HITS" | sed "s#^$TMP/##" | cut -c1-200
exit 1
fi
echo "identity grep: 0 hits over $(printf '%s\n' "$TEXT_FILES" | grep -c .) files"