Merge master 5d7aa6451 into f0-sign-adversary under the master-landing lock
This commit is contained in:
commit
ad6d080e52
10 changed files with 202 additions and 29 deletions
File diff suppressed because one or more lines are too long
|
|
@ -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"
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
72
tools/dl/publish-bin.sh
Executable 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)"
|
||||
Loading…
Reference in a new issue