Merge master 5d7aa6451 into f0-sign-adversary under the master-landing lock

This commit is contained in:
igneum-labs 2026-10-09 07:22:27 +00:00
commit ad6d080e52
10 changed files with 202 additions and 29 deletions

File diff suppressed because one or more lines are too long

View file

@ -15511,8 +15511,8 @@
"run_status": "FAIL",
"master_status": "PROPOSED / NOT RUN",
"run_id": "canary-202-20261009-01",
"evidence_path": "tools/ci/canary/1176efb9.json; build-1:/srv/canary/1176efb9/mini/00-verdict.txt; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json",
"updated": "2026-10-09T03:47:40.335Z",
"evidence_path": "tools/ci/canary/1176efb9.json; build-1:/srv/canary/1176efb9/mini/00-verdict.txt; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json; build-1:/srv/canary/1176efb9/lp-4090-43/00-verdict.txt",
"updated": "2026-10-09T07:18:00.541Z",
"evidence_record": {
"requirement_id": "INT-07",
"decision": "FAIL",
@ -15520,7 +15520,7 @@
"cell": "canary:fresh-install",
"manifest_sha": "5d53a591",
"run_id": "canary-202-20261009-01",
"evidence": "tools/ci/canary/1176efb9.json; build-1:/srv/canary/1176efb9/mini/00-verdict.txt; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json",
"evidence": "tools/ci/canary/1176efb9.json; build-1:/srv/canary/1176efb9/mini/00-verdict.txt; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json; build-1:/srv/canary/1176efb9/lp-4090-43/00-verdict.txt",
"in_progress": false,
"coverage": "partial: V6-12's clean-install half (one published object installed fresh, synced, mined, proved and paid on one host per artefact); the cross-host agreement half (node, pool, CPU verifier, each GPU host across activation) is harness:same-work's",
"release_identity": {
@ -15533,8 +15533,8 @@
},
"claim_impact": "INT-07's clean-install half on kit 2 reads FAIL on the fleet canary (the walk bound at the fifth cut); the mac block PASS stands as the Mac entry's evidence; no fleet, hive or windows entry publishes until a record reads PASS on its own block",
"reviewer": "",
"at": "2026-10-09T03:47:40.335Z",
"note": "mac PASS, fleet FAIL at sync (the walk bound at the reference chain's fifth cut under fix 2), hive and windows pending | Kit 2 (tip 1176efb9, node 5d53a591): the mac block PASS under tools/ci/canary-check.sh (the project's macOS machine: synced from empty in 2,016 s, 18 blocks in five minutes at 12.65 MH/s, 0 refusals, shard n/a on Apple silicon, the tip inside ten of the age-adjusted feed, quit in 4 s); the fleet block FAIL at sync (lp-4090-11, 04:04 UK: a fresh 2.0.2 node walls at the reference chain's fifth cut under fix 2's walk bound, 'passed 7200 blocks (2 x epoch_blocks) without meeting a block this executor holds a record of'; the kit ran clean; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json); the hive block reads about 05:30 UK, the windows block on the relay lane's clock. No fleet, hive or windows entry publishes on this record; the Mac entry published on its PASS block at 02:20 UK. Kit 1's 94e4c6ba FAIL (the wedge) stands as that sha's record. The recorder's rule: a measured FAIL on one block is a FAIL on the case. Re-recorded 9 October 2026 04:3x UK with the hive block (lp-4090-43, FAIL at sync on the lost-proof loop) and the re-shaped fleet block (no sync.feed object).",
"at": "2026-10-09T07:18:00.541Z",
"note": "mac PASS (the Mac entry published on it 02:20 UK); fleet FAIL at sync (lp-4090-11, 04:04 UK: the walk bound at the reference chain's fifth cut under fix 2); hive FAIL (lp-4090-43: the lost-proof loop at the first class v5 cut, 'the proofs of 2 carried records are not held yet'); no windows block (the Windows order's default fired: no push without a proved shard). No fleet, hive or windows 2.0.2 entry publishes on this record. | Kit 2 (tip 1176efb9, node 5d53a591): the mac block PASS under tools/ci/canary-check.sh (the project's macOS machine: synced from empty in 2,016 s, 18 blocks in five minutes at 12.65 MH/s, 0 refusals, shard n/a on Apple silicon, the tip inside ten of the age-adjusted feed, quit in 4 s); the fleet block FAIL at sync (lp-4090-11, 04:04 UK: a fresh 2.0.2 node walls at the reference chain's fifth cut under fix 2's walk bound, 'passed 7200 blocks (2 x epoch_blocks) without meeting a block this executor holds a record of'; the kit ran clean; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json); the hive block reads about 05:30 UK, the windows block on the relay lane's clock. No fleet, hive or windows entry publishes on this record; the Mac entry published on its PASS block at 02:20 UK. Kit 1's 94e4c6ba FAIL (the wedge) stands as that sha's record. The recorder's rule: a measured FAIL on one block is a FAIL on the case. Re-recorded 9 October 2026 04:3x UK with the hive block (lp-4090-43, FAIL at sync on the lost-proof loop) and the re-shaped fleet block (no sync.feed object). Cell note brought up to the record's three blocks at 08:1x UK (the hive landing had re-recorded the batch note only).",
"network_label": "on an island, not a network"
},
"evidence_records": {
@ -15545,7 +15545,7 @@
"cell": "canary:fresh-install",
"manifest_sha": "5d53a591",
"run_id": "canary-202-20261009-01",
"evidence": "tools/ci/canary/1176efb9.json; build-1:/srv/canary/1176efb9/mini/00-verdict.txt; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json",
"evidence": "tools/ci/canary/1176efb9.json; build-1:/srv/canary/1176efb9/mini/00-verdict.txt; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json; build-1:/srv/canary/1176efb9/lp-4090-43/00-verdict.txt",
"in_progress": false,
"coverage": "partial: V6-12's clean-install half (one published object installed fresh, synced, mined, proved and paid on one host per artefact); the cross-host agreement half (node, pool, CPU verifier, each GPU host across activation) is harness:same-work's",
"release_identity": {
@ -15558,8 +15558,8 @@
},
"claim_impact": "INT-07's clean-install half on kit 2 reads FAIL on the fleet canary (the walk bound at the fifth cut); the mac block PASS stands as the Mac entry's evidence; no fleet, hive or windows entry publishes until a record reads PASS on its own block",
"reviewer": "",
"at": "2026-10-09T03:47:40.335Z",
"note": "mac PASS, fleet FAIL at sync (the walk bound at the reference chain's fifth cut under fix 2), hive and windows pending | Kit 2 (tip 1176efb9, node 5d53a591): the mac block PASS under tools/ci/canary-check.sh (the project's macOS machine: synced from empty in 2,016 s, 18 blocks in five minutes at 12.65 MH/s, 0 refusals, shard n/a on Apple silicon, the tip inside ten of the age-adjusted feed, quit in 4 s); the fleet block FAIL at sync (lp-4090-11, 04:04 UK: a fresh 2.0.2 node walls at the reference chain's fifth cut under fix 2's walk bound, 'passed 7200 blocks (2 x epoch_blocks) without meeting a block this executor holds a record of'; the kit ran clean; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json); the hive block reads about 05:30 UK, the windows block on the relay lane's clock. No fleet, hive or windows entry publishes on this record; the Mac entry published on its PASS block at 02:20 UK. Kit 1's 94e4c6ba FAIL (the wedge) stands as that sha's record. The recorder's rule: a measured FAIL on one block is a FAIL on the case. Re-recorded 9 October 2026 04:3x UK with the hive block (lp-4090-43, FAIL at sync on the lost-proof loop) and the re-shaped fleet block (no sync.feed object).",
"at": "2026-10-09T07:18:00.541Z",
"note": "mac PASS (the Mac entry published on it 02:20 UK); fleet FAIL at sync (lp-4090-11, 04:04 UK: the walk bound at the reference chain's fifth cut under fix 2); hive FAIL (lp-4090-43: the lost-proof loop at the first class v5 cut, 'the proofs of 2 carried records are not held yet'); no windows block (the Windows order's default fired: no push without a proved shard). No fleet, hive or windows 2.0.2 entry publishes on this record. | Kit 2 (tip 1176efb9, node 5d53a591): the mac block PASS under tools/ci/canary-check.sh (the project's macOS machine: synced from empty in 2,016 s, 18 blocks in five minutes at 12.65 MH/s, 0 refusals, shard n/a on Apple silicon, the tip inside ten of the age-adjusted feed, quit in 4 s); the fleet block FAIL at sync (lp-4090-11, 04:04 UK: a fresh 2.0.2 node walls at the reference chain's fifth cut under fix 2's walk bound, 'passed 7200 blocks (2 x epoch_blocks) without meeting a block this executor holds a record of'; the kit ran clean; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json); the hive block reads about 05:30 UK, the windows block on the relay lane's clock. No fleet, hive or windows entry publishes on this record; the Mac entry published on its PASS block at 02:20 UK. Kit 1's 94e4c6ba FAIL (the wedge) stands as that sha's record. The recorder's rule: a measured FAIL on one block is a FAIL on the case. Re-recorded 9 October 2026 04:3x UK with the hive block (lp-4090-43, FAIL at sync on the lost-proof loop) and the re-shaped fleet block (no sync.feed object). Cell note brought up to the record's three blocks at 08:1x UK (the hive landing had re-recorded the batch note only).",
"network_label": "on an island, not a network"
}
},

View file

@ -23,20 +23,24 @@ echo "$OVJSON" | python3 -c 'import json,sys; o=json.load(sys.stdin); assert isi
[ "$(strings "$BIN" | grep -c "$COMMIT")" -gt 0 ] || { echo "$BIN is not the $COMMIT node (a 0.3.5 node refuses an override file with fees_v1_activation_daa)"; exit 1; }
cp -p "$OV" "$OV.prev-$(date -u +%Y%m%dT%H%M%SZ)" 2>/dev/null || true
printf '%s\n' "$OVJSON" > "$OV"
# the pid is an igneumd process, never a shell whose command line carries the pattern's text (6 October 2026: pgrep -f matched the
# caller's own zsh -c "..." and the stop waited 11 minutes on it)
stop() { local p; p=$( { for c in $(pgrep -f "$1" || true); do if [ "$(ps -o comm= -p "$c" 2>/dev/null | xargs basename 2>/dev/null)" = igneumd ]; then echo "$c"; fi; done; true; } | head -1 ); if [ -n "$p" ]; then kill -INT "$p"; while kill -0 "$p" 2>/dev/null; do sleep 1; done; fi; } # the filter never fails the pipeline (17:43Z: a trailing caffeinate pid made the loop exit 1 and set -e ended the script before node 1)
# 8 October 2026 (the kill rule's fourth instance, the steward's check): a stop reads a PID FILE and nothing else; never a
# listing by pattern (pgrep -f matched the caller's own shell on 6 October and a pattern sweep killed a running miner tonight).
# Every node this script starts writes $appdir.pid (the nohup child's pid) and the stop takes that file; a node started before
# this script wrote pid files is not stopped here: its pid is written by the operator into the file first.
stop() { local f="$1.pid" p; [ -s "$f" ] || { echo "no pid file $f: nothing stopped (write the running node's pid there first)"; return 0; }; p=$(cat "$f"); if kill -0 "$p" 2>/dev/null; then kill -INT "$p"; while kill -0 "$p" 2>/dev/null; do sleep 1; done; fi; rm -f "$f"; }
lines() { sleep 10; grep -E "Calibrated v1 fees from the override file|Fees on igneum-devnet|Consensus params digest" "$1" | tail -3 || true; }
# the observer first
stop "igneumd --devnet.*observer-v4"
stop /tmp/igneum-devnet/observer-v4
reset_exec /tmp/igneum-devnet/observer-v4
nohup "$BIN" --devnet --nodnsseed --disable-upnp --appdir=/tmp/igneum-devnet/observer-v4 --rpclisten=127.0.0.1:26640 --rpclisten-json=127.0.0.1:28640 --listen=127.0.0.1:26641 \
--addpeer=127.0.0.1:26611 --addpeer=188.245.5.161:26611 --addpeer=192.168.68.67:26611 --override-params-file="$OV" $SNAPARG --nologfiles --yes >> /tmp/igneum-devnet/observer-v4.out 2>&1 &
echo $! > /tmp/igneum-devnet/observer-v4.pid
lines /tmp/igneum-devnet/observer-v4.out
# node 1, under caffeinate as it runs today
stop "igneumd --devnet.*appdir=/tmp/igneum-devnet/node1 "
stop /tmp/igneum-devnet/node1
reset_exec /tmp/igneum-devnet/node1
nohup caffeinate -dims "$BIN" --devnet --nodnsseed --disable-upnp --enable-unsynced-mining --appdir=/tmp/igneum-devnet/node1 --rpclisten=0.0.0.0:26610 --listen=0.0.0.0:26611 --evm-rpclisten=127.0.0.1:26791 \
--addpeer=188.245.5.161:26611 --addpeer=192.168.68.67:26611 --override-params-file="$OV" $SNAPARG --nologfiles --yes >> /tmp/igneum-devnet/node1.out 2>&1 &
echo $! > /tmp/igneum-devnet/node1.pid
lines /tmp/igneum-devnet/node1.out
echo "running now:"; ps -o pid=,lstart=,command= -p "$(pgrep -f '[i]gneumd --devnet' | tr '\n' ',' | sed 's/,$//')" | cut -c1-160
echo "running now (by the pid files):"; for n in observer-v4 node1; do p=$(cat /tmp/igneum-devnet/$n.pid 2>/dev/null); [ -n "$p" ] && ps -o pid=,lstart=,command= -p "$p" | cut -c1-160; done

View file

@ -188,3 +188,23 @@ Tested on the Mac, 4 October 2026: the unit tests (parse, bad jobs refused, sign
targeting, the once-only ledger, globs), the signer with the real key, the publisher against a scratch folder, the
reader against the live intake; the crate also compiles for `x86_64-pc-windows-gnu`. Not yet run on a PC: the
first job goes to PC 2 (`1ccfe586`) once 0.3.2 is installed there (`docs/plans/shard-test-pc2.md`).
## The dl split (9 October 2026)
dl.igneum.network is two Vercel projects. `igneum-dl` (the downloads folder, `~/.config/igneum/dlsite-dir`) carries the
manifests, signatures, checksums, the index and the pages, a few megabytes; its `.vercelignore` leaves every binary out
(`*.dmg`, `*.exe`, `*.zip`, `*.gz`, `**/moves/**`). `igneum-dl-bin` carries the binaries, from the store
`/srv/artefacts/dl-bin` on build-1, published only when a binary is new (`tools/dl/publish-bin.sh`; the three publishers
call it with `--if-needed` before their own deploy). Every served URL is unchanged: `igneum-dl`'s `vercel.json` rewrites
every binary path under `/dl/` to the bin project, and each `/public/<alias>` points at the bin project's file directly
(a rewrite's destination is never rewritten again). The binaries stay on disk in the downloads folder (the publishers
read them for sizes, hashes and the aliases); they are just not uploaded with it. Before the split the one 5.9 GB project
re-hashed every binary on every manifest publish (17 GB of deploys on the Mac in one night).
- `~/.config/igneum/dl-bin-host`: `user@host` of build-1 (the store and the publisher of the bin project; the Vercel
credential sits there in `~/.vercel-igneum`). `~/.config/igneum/dl-bin-base`: the bin project's production URL
(default `https://igneum-dl-bin.vercel.app`).
- Pid files: `<dlsite>/.publish-bin.pid` on the Mac, `/srv/artefacts/dl-bin/.deploy.pid` on the box; a second run refuses.
- A re-cut under the same file name (a different size) is copied again; a file removed from the folder stays in the
store and keeps answering (the URL rule; prune by hand on the box when a withdrawal must stop serving).

View file

@ -470,6 +470,7 @@ fi
if [ "$DEPLOY" = 1 ]; then
[ -n "$DLSITE" ] || { echo "--deploy needs the real downloads folder (no --dest)" >&2; exit 1; }
echo "deploying $DLSITE"
"$ROOT/tools/dl/publish-bin.sh" --if-needed || { echo "the bin publish failed; nothing deployed" >&2; exit 1; }
(cd "$DLSITE" && npx --yes vercel@latest --global-config "$HOME/.config/igneum/vercel" deploy --prod --yes 2>&1 | sed "s#$TOKEN#<token>#g"; exit "${PIPESTATUS[0]}") \
|| { echo "the deploy failed (the Vercel CLI's exit status above); nothing verified" >&2; exit 1; }
verify_live "$TRIES" || exit 1

View file

@ -318,6 +318,7 @@ fi
if [ "$DEPLOY" = 1 ]; then
[ -n "$DLSITE" ] || { echo "--deploy needs the real downloads folder (no --dest)" >&2; exit 1; }
"$ROOT/tools/dl/publish-bin.sh" --if-needed || { echo "the bin publish failed; nothing deployed" >&2; exit 1; }
echo "deploying $DLSITE"
(cd "$DLSITE" && npx --yes vercel@latest --global-config "$HOME/.config/igneum/vercel" deploy --prod --yes 2>&1 | sed "s#$TOKEN#<token>#g"; exit "${PIPESTATUS[0]}") \
|| { echo "the deploy failed (the Vercel CLI's exit status above); nothing verified" >&2; exit 1; }

View file

@ -163,12 +163,21 @@ print(json.dumps(aliases))
PY
)"
KEEP="$(python3 -c 'import json,sys; a=json.loads(sys.argv[1]); print(" ".join(v for v in a.values() if v))' "$ALIASES_JSON")"
log "aliases (vercel.json rewrites under /public/):"
python3 -c 'import json,sys; a=json.loads(sys.argv[1]); [print(" /public/%s -> %s" % (k, ("/dl/public/" + v) if v else "(no file yet; alias left out)")) for k,v in a.items()]' "$ALIASES_JSON" | scrub
VERCEL_JSON="$(python3 - "$ALIASES_JSON" <<'PY'
# the binaries live in the project igneum-dl-bin (tools/dl/publish-bin.sh, 9 October 2026); this project rewrites every
# binary path there and the aliases point there directly (a rewrite's destination is never rewritten again)
BIN_BASE="$( [ -f "$CFG/dl-bin-base" ] && tr -d '[:space:]' < "$CFG/dl-bin-base" || echo https://igneum-dl-bin.vercel.app)"
log "aliases (vercel.json rewrites under /public/, served from $BIN_BASE):"
python3 -c 'import json,sys; a=json.loads(sys.argv[1]); [print(" /public/%s -> %s" % (k, (sys.argv[2] + "/dl/public/" + v) if v else "(no file yet; alias left out)")) for k,v in a.items()]' "$ALIASES_JSON" "$BIN_BASE" | scrub
VERCEL_JSON="$(python3 - "$ALIASES_JSON" "$BIN_BASE" <<'PY'
import json, sys
a = json.loads(sys.argv[1])
rewrites = [{"source": "/public/" + k, "destination": "/dl/public/" + v} for k, v in a.items() if v]
a = json.loads(sys.argv[1]); bin_base = sys.argv[2].rstrip("/")
rewrites = [{"source": "/public/" + k, "destination": bin_base + "/dl/public/" + v} for k, v in a.items() if v]
# every binary under /dl/ (the same patterns as the .vercelignore of this project and publish-bin.sh); a file that is
# in this deployment is served from it first (the filesystem precedes rewrites), so a stray binary here still answers
rewrites += [
{"source": "/dl/:path(.*\\.(?:dmg|exe|zip|gz))", "destination": bin_base + "/dl/:path"},
{"source": "/dl/:path(.*/moves/.*)", "destination": bin_base + "/dl/:path"},
]
cfg = {
"cleanUrls": False,
"trailingSlash": False,
@ -230,6 +239,8 @@ if [ "$DRY" = 1 ]; then log "dry run: nothing written"; fi
if [ "$DEPLOY" = 1 ]; then
[ "$DRY" = 0 ] || { echo "--deploy and --dry-run together make no sense" >&2; exit 2; }
[ -z "$DEST" ] || { echo "--deploy needs the real downloads folder (no --dest)" >&2; exit 1; }
# the binaries first: a new file here is copied to build-1 and published from there before this small deploy rewrites to it
"$ROOT/tools/dl/publish-bin.sh" --if-needed || { echo "the bin publish failed; the manifests are not deployed" >&2; exit 1; }
log "deploying $DLSITE"
(cd "$DLSITE" && npx --yes vercel@latest --global-config "$CFG/vercel" deploy --prod --yes 2>&1 | scrub; exit "${PIPESTATUS[0]}") \
|| { echo "the deploy failed (the Vercel CLI's exit status above); nothing verified" >&2; exit 1; }

View file

@ -15,7 +15,7 @@
"profile_hashes": ""
},
"claim_impact": "INT-07's clean-install half on kit 2 reads FAIL on the fleet canary (the walk bound at the fifth cut); the mac block PASS stands as the Mac entry's evidence; no fleet, hive or windows entry publishes until a record reads PASS on its own block",
"note": "Kit 2 (tip 1176efb9, node 5d53a591): the mac block PASS under tools/ci/canary-check.sh (the project's macOS machine: synced from empty in 2,016 s, 18 blocks in five minutes at 12.65 MH/s, 0 refusals, shard n/a on Apple silicon, the tip inside ten of the age-adjusted feed, quit in 4 s); the fleet block FAIL at sync (lp-4090-11, 04:04 UK: a fresh 2.0.2 node walls at the reference chain's fifth cut under fix 2's walk bound, 'passed 7200 blocks (2 x epoch_blocks) without meeting a block this executor holds a record of'; the kit ran clean; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json); the hive block reads about 05:30 UK, the windows block on the relay lane's clock. No fleet, hive or windows entry publishes on this record; the Mac entry published on its PASS block at 02:20 UK. Kit 1's 94e4c6ba FAIL (the wedge) stands as that sha's record. The recorder's rule: a measured FAIL on one block is a FAIL on the case. Re-recorded 9 October 2026 04:3x UK with the hive block (lp-4090-43, FAIL at sync on the lost-proof loop) and the re-shaped fleet block (no sync.feed object).",
"note": "Kit 2 (tip 1176efb9, node 5d53a591): the mac block PASS under tools/ci/canary-check.sh (the project's macOS machine: synced from empty in 2,016 s, 18 blocks in five minutes at 12.65 MH/s, 0 refusals, shard n/a on Apple silicon, the tip inside ten of the age-adjusted feed, quit in 4 s); the fleet block FAIL at sync (lp-4090-11, 04:04 UK: a fresh 2.0.2 node walls at the reference chain's fifth cut under fix 2's walk bound, 'passed 7200 blocks (2 x epoch_blocks) without meeting a block this executor holds a record of'; the kit ran clean; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json); the hive block reads about 05:30 UK, the windows block on the relay lane's clock. No fleet, hive or windows entry publishes on this record; the Mac entry published on its PASS block at 02:20 UK. Kit 1's 94e4c6ba FAIL (the wedge) stands as that sha's record. The recorder's rule: a measured FAIL on one block is a FAIL on the case. Re-recorded 9 October 2026 04:3x UK with the hive block (lp-4090-43, FAIL at sync on the lost-proof loop) and the re-shaped fleet block (no sync.feed object). Cell note brought up to the record's three blocks at 08:1x UK (the hive landing had re-recorded the batch note only).",
"cells": [
{
"cell": "canary:fresh-install",
@ -24,9 +24,9 @@
],
"status": "FAIL",
"method": "team-reported",
"evidence": "tools/ci/canary/1176efb9.json; build-1:/srv/canary/1176efb9/mini/00-verdict.txt; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json",
"evidence": "tools/ci/canary/1176efb9.json; build-1:/srv/canary/1176efb9/mini/00-verdict.txt; build-1:/srv/canary/1176efb9/lp-4090-11/fleet-block.json; build-1:/srv/canary/1176efb9/lp-4090-43/00-verdict.txt",
"network_label": "on an island, not a network",
"note": "mac PASS, fleet FAIL at sync (the walk bound at the reference chain's fifth cut under fix 2), hive and windows pending"
"note": "mac PASS (the Mac entry published on it 02:20 UK); fleet FAIL at sync (lp-4090-11, 04:04 UK: the walk bound at the reference chain's fifth cut under fix 2); hive FAIL (lp-4090-43: the lost-proof loop at the first class v5 cut, 'the proofs of 2 carried records are not held yet'); no windows block (the Windows order's default fired: no push without a proved shard). No fleet, hive or windows 2.0.2 entry publishes on this record."
}
]
}

View file

@ -24,6 +24,15 @@
# only when it is anchored on the exact command line (`^/full/path` or `^command`), is the bracket form, a variable, -x on a
# binary name or -F on a pid file; a bare path, a log name or a word is red. The fix is a pid file or the anchored pattern.
#
# 6. (8 October 2026, 23:4x UK, the fourth instance: the V6-07 sub-lane's scratch socket sweep killed a running miner despite the
# pkill and killall shims, because the shims cover two commands and the class is ANY kill chosen by a pattern) `kill` fed by a
# pattern is flagged wherever it appears: `kill $(pgrep ...)`, `kill $(lsof -t ...)`, `kill $(ps ... | grep ...)`, `fuser -k`,
# `ss`/`netstat`/`lsof` pipelines ending in kill, `| xargs kill`, and a loop that kills pids it did not record
# (`for p in $(pgrep|lsof|ps|ss|netstat ...); do kill`). The allowed forms stay: a recorded pid variable (`kill "$PID"`, `kill $!`),
# the pid file (`kill "$(cat <pidfile>)"`, `kill "$(cut -d' ' -f1 <pidfile>)"`, `pkill -F`), `tools/fleet/fleet-bg.sh stop`, and the
# children of a recorded pid (`pgrep -P "$pid"`: an exact process tree, no pattern).
# The rule covers every tracked script and every job body (the playbooks under tools/fleet and tools/jobs included).
#
# tools/ci/kill-by-name-check.sh # exit 1 with file:line and the reason
# tools/ci/kill-by-name-check.sh --self-test # fires on each banned shape, passes each allowed one
set -euo pipefail
@ -68,10 +77,42 @@ check_line() { # <line> -> prints the reason, returns 1, when the line carrie
fi
if [[ "$code" =~ (^|[^A-Za-z0-9_])ps[[:space:]][^|]*\|[[:space:]]*grep[[:space:]]+(-[A-Za-z]+[[:space:]]+)*(\"[^\"]*\"|\'[^\']*\'|[^[:space:]|;\)]+) ]]; then
pat="${BASH_REMATCH[3]}"; pat="${pat#[\"\']}"; pat="${pat%[\"\']}"
[[ "$pat" == *'$'* ]] && return 0
[[ "$pat" =~ ^\[.\] ]] && return 0
[[ "$pat" == grep ]] && return 0 # `grep -v grep`
echo "ps | grep with a plain literal ($pat): it matches the grep itself; use the bracket form ([${pat:0:1}]${pat:1}) or pgrep -x"; return 1
if ! { [[ "$pat" == *'$'* ]] || [[ "$pat" =~ ^\[.\] ]] || [[ "$pat" == grep ]]; }; then # a variable, the bracket form, `grep -v grep` are fine; rule 6 still reads the line
echo "ps | grep with a plain literal ($pat): it matches the grep itself; use the bracket form ([${pat:0:1}]${pat:1}) or pgrep -x"; return 1
fi
fi
# rule 6: a kill chosen by a pattern (the socket-sweep class): the pids a kill takes come from a recorded variable or a pid file, never
# from pgrep, lsof, fuser, ss, netstat or a ps pipeline, and never through xargs or a loop over such a listing
if [[ "$code" =~ (^|[^A-Za-z0-9_./-])fuser[[:space:]]+(-[A-Za-z]*k|-[A-Za-z]+[[:space:]]+-[A-Za-z]*k) ]]; then
echo "fuser -k: a kill chosen by a socket or file pattern (rule 6, the socket-sweep class); record the pid you start and kill that pid, or use a pid file"; return 1
fi
local xargs_re='[|][[:space:]]*xargs[[:space:]]+(-[A-Za-z0-9]+[[:space:]]+)*kill([[:space:]]|$)'
if [[ "$code" =~ $xargs_re ]]; then
echo "| xargs kill: the pids come from a listing, not from a record (rule 6, the socket-sweep class); kill the pid you recorded or use a pid file"; return 1
fi
local tree_re='[$][(]pgrep[[:space:]]+-P[[:space:]]+("[$][A-Za-z0-9_{}!]+"|[$][A-Za-z0-9_{}!]+|[0-9]+)' # the parent pid is a variable (quoted or bare, $1 and $! included) or a number
local kill_re='(^|[^A-Za-z0-9_./-])kill[[:space:]]+(-[A-Za-z0-9]+[[:space:]]+)*[^[:space:]]*[$][(](pgrep|lsof|fuser|ss|netstat|ps)([[:space:]]|[)])'
local tool=""
if [[ "$code" =~ $kill_re ]]; then
tool="${BASH_REMATCH[3]}"
if ! { [[ "$tool" == pgrep ]] && [[ "$code" =~ $tree_re ]]; }; then
echo "kill \$($tool ...): a kill chosen by a pattern (rule 6, the socket-sweep class); the allowed forms are a recorded pid, \$(cat <pidfile>), \$(cut -d' ' -f1 <pidfile>), pkill -F, fleet-bg.sh stop, pgrep -P <recorded pid>"; return 1
fi
fi
local bt_re='(^|[^A-Za-z0-9_./-])kill[[:space:]]+(-[A-Za-z0-9]+[[:space:]]+)*[^[:space:]]*`(pgrep|lsof|fuser|ss|netstat|ps)[[:space:]]'
if [[ "$code" =~ $bt_re ]]; then
echo "kill \`${BASH_REMATCH[3]} ...\`: a kill chosen by a pattern (rule 6); kill a recorded pid or a pid file's"; return 1
fi
local loop_re='for[[:space:]]+[A-Za-z_][A-Za-z0-9_]*[[:space:]]+in[[:space:]]+[^;]*[$][(](pgrep|lsof|fuser|ss|netstat|ps)([[:space:]]|[)])[^;]*[;][[:space:]]*do[[:space:]].*kill'
if [[ "$code" =~ $loop_re ]]; then
tool="${BASH_REMATCH[1]}"
if ! { [[ "$tool" == pgrep ]] && [[ "$code" =~ $tree_re ]]; }; then # pgrep -P <recorded pid> walks that pid's own children: an exact tree, no pattern (allowed)
echo "a loop over \$($tool ...) that kills: the pids were listed, not recorded (rule 6, the socket-sweep class)"; return 1
fi
fi
local pipe_re='(^|[^A-Za-z0-9_./-])(pgrep|lsof|ss|netstat)[[:space:]][^|]*[|].*kill([[:space:]]|$)'
if [[ "$code" =~ $pipe_re ]] && [[ "$code" != *"xargs"* ]]; then
echo "a ${BASH_REMATCH[2]} pipeline ending in kill: a kill chosen by a pattern (rule 6, the socket-sweep class); record the pid or use a pid file"; return 1
fi
return 0
}
@ -85,6 +126,14 @@ if [ "${1:-}" = "--self-test" ]; then
'pkill -x node'
'pkill -f "[p]re-push.sh"'
'pgrep -f merge-to-master'
'kill $(pgrep -x igneum-miner)'
'kill -9 $(lsof -t -i :26611)'
'fuser -k 26611/tcp'
'lsof -t -i :26611 | xargs kill'
'ss -ltnp | grep 26611 | awk "{print $7}" | cut -d, -f2 | xargs kill -9'
'for p in $(pgrep -f "[i]gneum-worker"); do kill "$p"; done'
'pids=$(ps aux | grep "[w]orker" | awk "{print $2}"); kill $pids 2>/dev/null; kill $(pgrep -x worker)'
'kill `pgrep -x igneumd`'
'pkill -f "^igneum-gate:"'
'pkill cargo'
'pkill -f igneum-roll.log'
@ -108,6 +157,15 @@ if [ "${1:-}" = "--self-test" ]; then
'pkill -P "$keeper"'
'pkill -x igneumd'
'pgrep -f "[i]gneumd" >/dev/null'
'kill "$(cut -d'"'"' '"'"' -f1 "$PIDFILE")"'
'kill "$(cat /srv/canary/miner.pid)"'
'kill "$MINER_PID"; wait "$MINER_PID"'
'kill $! 2>/dev/null'
'bash tools/fleet/fleet-bg.sh stop miner-1'
'pkill -F /srv/run/miner.pid'
'for p in "${RECORDED[@]}"; do kill "$p"; done'
'for c in $(pgrep -P "$1" 2>/dev/null); do kill -TERM "$c"; done'
'kill $(pgrep -P $PID)'
"pkill -f '[n]ode tools/fleet/wave.mjs'"
'pgrep -x igneumd'
'pkill -x igneum-miner'
@ -127,7 +185,7 @@ if [ "${1:-}" = "--self-test" ]; then
)
for l in "${bad[@]}"; do if check_line "$l" >/dev/null; then echo "self-test failed: accepted: $l"; fails=1; fi; done
for l in "${good[@]}"; do if ! out="$(check_line "$l")"; then echo "self-test failed: rejected: $l ($out)"; fails=1; fi; done
[ "$fails" = 0 ] && echo "self-test passed: ${#bad[@]} banned shapes fail (a log or out file name under pkill/pgrep, a plain literal under -f, the second pkill on a line, ps | grep with a literal); ${#good[@]} allowed shapes pass (bracket form, -x, -F pidfile, kill \$(cat pidfile), a variable, a full path, comments)"
[ "$fails" = 0 ] && echo "self-test passed: ${#bad[@]} banned shapes fail (a kill fed by pgrep, lsof, fuser -k, an ss or netstat pipeline, xargs kill or a loop over a listing (rule 6); a log or out file name under pkill/pgrep, a plain literal under -f, the second pkill on a line, ps | grep with a literal); ${#good[@]} allowed shapes pass (bracket form, -x, -F pidfile, kill \$(cat pidfile), a variable, a full path, comments)"
exit $fails
fi
@ -137,6 +195,6 @@ fail=0; n=0
while IFS= read -r hit; do
f="${hit%%:*}"; rest="${hit#*:}"; ln="${rest%%:*}"; line="${rest#*:}"; n=$((n + 1))
if ! why="$(check_line "$line")"; then echo "kill-by-name: $f:$ln: $why"; fail=1; fi
done < <(git grep -nE '(^|[^A-Za-z0-9_./-])(pgrep|pkill)([[:space:]]|$)|(^|[^A-Za-z0-9_])ps[[:space:]][^|]*\|[[:space:]]*grep' -- '*.sh' '*.bash' '*.mjs' '*.js' '*.py' '*.ps1' '*.bat' ':!vendor/**' ':!**/node_modules/**' ':!tools/ci/kill-by-name-check.sh' || true)
[ "$fail" = 0 ] && echo "kill-by-name: $n pgrep/pkill/ps-grep lines, none kills or finds a process by a plain name or a file name"
done < <(git grep -nE '(^|[^A-Za-z0-9_./-])(pgrep|pkill|fuser)([[:space:]]|$)|(^|[^A-Za-z0-9_])ps[[:space:]][^|]*\|[[:space:]]*grep|(^|[^A-Za-z0-9_./-])kill([[:space:]]|$)|xargs[[:space:]]+(-[A-Za-z0-9]+[[:space:]]+)*kill' -- '*.sh' '*.bash' '*.mjs' '*.js' '*.py' '*.ps1' '*.bat' '*.yml' '*.yaml' '*.json' ':!vendor/**' ':!**/node_modules/**' ':!tools/ci/kill-by-name-check.sh' || true)
[ "$fail" = 0 ] && echo "kill-by-name: $n pgrep/pkill/ps-grep/kill lines, none kills or finds a process by a plain name, a file name or a pattern-chosen pid"
exit $fail

72
tools/dl/publish-bin.sh Executable file
View file

@ -0,0 +1,72 @@
#!/usr/bin/env bash
# The binaries of dl.igneum.network: copied to build-1 and published from there as the Vercel project igneum-dl-bin,
# only when a binary is new. dl.igneum.network itself (the project igneum-dl, deployed by the three publishers in
# packaging/ota/) carries only the manifests, signatures, checksums and pages, and rewrites every binary path to this
# project, so every served URL stays as it was (9 October 2026, the dl split: the one 5.9 GB project re-hashed every
# binary on every manifest publish, 17 GB of deploys on the Mac in one night).
#
# tools/dl/publish-bin.sh copy what is missing on build-1, deploy if anything was copied, verify
# tools/dl/publish-bin.sh --if-needed the same, silent and exit 0 when nothing is new (the publishers call this)
# tools/dl/publish-bin.sh --force deploy even when nothing is new (a vercel.json change on the box)
# tools/dl/publish-bin.sh --dry-run list the delta, copy and deploy nothing
#
# What counts as a binary: *.dmg, *.exe, *.zip, *.gz under dl/, and everything under a moves/ folder. Everything else
# stays in the small project (its .vercelignore lists the same patterns).
# Reads ~/.config/igneum/dlsite-dir (IGNEUM_DLSITE overrides), ~/.config/igneum/dl-bin-host (user@host of build-1, required),
# ~/.config/igneum/dl-bin-base (default https://igneum-dl-bin.vercel.app). Pid files: <dlsite>/.publish-bin.pid on
# the Mac, <store>/.deploy.pid on the box; a second run refuses (exit 75). Never kills anything.
set -euo pipefail
MODE=run; FORCE=0
for a in "$@"; do case "$a" in --if-needed) MODE=ifneeded ;; --force) FORCE=1 ;; --dry-run) MODE=dry ;; -h|--help) sed -n '2,19p' "$0"; exit 0 ;; *) echo "unknown flag $a" >&2; exit 2 ;; esac; done
CFG="$HOME/.config/igneum"
DLSITE="${IGNEUM_DLSITE:-}"; [ -n "$DLSITE" ] || { [ -f "$CFG/dlsite-dir" ] && DLSITE="$(tr -d '[:space:]' < "$CFG/dlsite-dir")"; } || true
[ -n "$DLSITE" ] && [ -d "$DLSITE/dl" ] || { echo "no downloads folder: ~/.config/igneum/dlsite-dir must hold dl/" >&2; exit 1; }
HOST="$( [ -f "$CFG/dl-bin-host" ] && tr -d '[:space:]' < "$CFG/dl-bin-host" || true)"
[ -n "$HOST" ] || { echo "no store host: ~/.config/igneum/dl-bin-host must hold user@host of build-1 (the box that publishes the bin project)" >&2; exit 1; }
BASE="$( [ -f "$CFG/dl-bin-base" ] && tr -d '[:space:]' < "$CFG/dl-bin-base" || echo https://igneum-dl-bin.vercel.app)"
STORE=/srv/artefacts/dl-bin
SSH=(ssh -o BatchMode=yes -o ConnectTimeout=15 "$HOST")
log() { echo "publish-bin: $*"; }
# the binaries here: "<size> <path>" lines, paths relative to the folder
# "<path> <size>" lines, paths relative to the folder, plain sort (comm compares whole lines)
local_list() { (cd "$DLSITE" && find dl -type f \( -name '*.dmg' -o -name '*.exe' -o -name '*.zip' -o -name '*.gz' -o -path '*/moves/*' \) -print0 | xargs -0 stat -f '%N %z' 2>/dev/null || (cd "$DLSITE" && find dl -type f \( -name '*.dmg' -o -name '*.exe' -o -name '*.zip' -o -name '*.gz' -o -path '*/moves/*' \) -printf '%p %s\n')) | LC_ALL=C sort; }
remote_list() { "${SSH[@]}" "cd $STORE 2>/dev/null && find dl -type f -not -name '._*' -printf '%p %s\n' | LC_ALL=C sort" || true; }
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
local_list > "$TMP/local"; remote_list > "$TMP/remote"
# missing on the box, or a different size there (a re-cut under the same name): copied again
LC_ALL=C comm -23 "$TMP/local" "$TMP/remote" | awk '{ print $1 }' > "$TMP/delta"
N=$(wc -l < "$TMP/delta" | tr -d ' ')
if [ "$N" = 0 ] && [ "$FORCE" = 0 ]; then [ "$MODE" = ifneeded ] || log "nothing new: $(wc -l < "$TMP/local" | tr -d ' ') binaries here, all on $HOST:$STORE"; exit 0; fi
log "$N binar$([ "$N" = 1 ] && echo y || echo ies) to publish:"; sed 's/^/ /' "$TMP/delta"
[ "$MODE" != dry ] || exit 0
PIDF="$DLSITE/.publish-bin.pid"
if [ -s "$PIDF" ] && kill -0 "$(cat "$PIDF")" 2>/dev/null; then echo "a bin publish is running (pid $(cat "$PIDF") in $PIDF); wait for it" >&2; exit 75; fi
echo $$ > "$PIDF"; trap 'rm -f "$PIDF"; rm -rf "$TMP"' EXIT
if [ "$N" != 0 ]; then
log "copying to $HOST:$STORE"
# COPYFILE_DISABLE: no AppleDouble ._ entries from the Mac (the HiveOS tar lesson); the store is swept of any before a deploy
COPYFILE_DISABLE=1 tar -cf - -C "$DLSITE" -T "$TMP/delta" | "${SSH[@]}" "tar -xf - -C $STORE"
fi
"${SSH[@]}" "find $STORE/dl -name '._*' -type f -delete" || true
log "deploying $STORE from $HOST at $(TZ=UTC date +%H:%M:%SZ)"
# the box's own pid file: one deploy at a time, never a kill
OUT="$("${SSH[@]}" "cd $STORE && if [ -s .deploy.pid ] && kill -0 \$(cat .deploy.pid) 2>/dev/null; then echo 'a bin deploy is running on the box (pid '\$(cat .deploy.pid)')'; exit 75; fi; echo \$\$ > .deploy.pid; trap 'rm -f .deploy.pid' EXIT; npx --yes vercel@latest --global-config ~/.vercel-igneum --scope igneum deploy --prod --yes 2>&1")" || { echo "$OUT" | tail -8 >&2; exit 1; }
URL=$(echo "$OUT" | grep -oE 'https://[a-z0-9.-]*vercel\.app' | tail -1); log "deployed $URL"
# verify: every binary in the delta (or, on --force, the current aliases' files) answers at the public base with its size
fails=0
while IFS= read -r p; do
[ -n "$p" ] || continue
want=$(awk -v p="$p" '$1 == p { print $2 }' "$TMP/local")
for t in 1 2 3 4 5 6 7 8 9 10 11 12; do
got=$(curl -sI "$BASE/$p" | tr -d '\r' | awk 'tolower($1) == "content-length:" { print $2 }' | tail -1)
[ "$got" = "$want" ] && break; sleep 5
done
if [ "$got" = "$want" ]; then log " ok $p ($want bytes)"; else log " FAIL $p: content-length ${got:-none}, want $want"; fails=$((fails + 1)); fi
done < "$TMP/delta"
[ "$fails" = 0 ] || { echo "publish-bin: $fails file(s) not served at $BASE" >&2; exit 1; }
log "done: $N published, served at $BASE ($(TZ=Europe/London date +%H:%M) UK)"