The node pin moves to 4c6b129d (release-0.3.14-node), which is what the live payload inputs carry, so windows-ci's payload-inputs step is green again (red since 630b537 on master's 0.3.13 pin against the 0.3.14 inputs).
Conflicts: infra/fast-time/override-60x.json keeps master's side (the fresh-rule field was already there at u64::MAX; the release line would be a duplicate key); tools/ci/playbook-quit-check.sh keeps master's rule 2 and pre-rule list with the release side's Ember allow entry and the 0.3.15 expiry check.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Main's decision of 6 October 2026. CLAUDE.md 'Running agents on this Mac': every Linux and Windows cargo build and every
Linux test suite goes to igneum-build-1 through tools/build-remote.sh and tools/cross-remote.sh; the PCs keep GPU and
Windows-runtime jobs; the Mac keeps macOS binaries, the DMG and Metal tests under the lock. -Wl,--no-insert-timestamp in
cross-remote.sh, proto-cuda/windows-node/cross-build.sh and jobbuild.rs (two box builds byte-identical, verified).
The empty-commit class: tools/ci/commit-string-check.sh (self-test in ci.yml, shown firing on a Mac worktree build and
passing on a box build) runs on every igneumd from the three build scripts; push-build-inputs.sh adds node.commit_full,
the PC job writes a minimal node/.git from it at extract and cleans kaspa-build-info on a new commit (4 jobbuild tests
pass, run on the box); cross-build.sh refuses a worktree and cleans on a new commit. Plan: second worktree's clean build
1 min 18 s with sccache 604 hits of 993.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The console-window class (Josh, 5 October 2026: "Windows Command Processor" windows on PC 1 whenever a remote job runs).
Measured on PC 1 (ae432dc7, Windows 11 Pro 26200, default terminal "Let Windows decide" = Windows Terminal 1.24) with
tools/windows/console-watch.ps1 (job run-20261005-182528): no child a job script starts from the app's headless
console opens a window (powershell, cmd, query, curl, nvidia-smi, wsl --status, a distro, interop cmd and powershell,
powershell -WindowStyle Hidden: 0 windows each); Start-Process in a new console opens a Terminal window (the known-failed
case: 2 windows), the same with -WindowStyle Hidden opens none (the known-finished case). The elevated path
(Start-Process -Verb RunAs -WindowStyle Hidden through the AppInfo service) is the one road left; its watcher
(console-watch-elevated.ps1, job run-20261005-184610) was cancelled at the UAC prompt.
- platform.rs: elevated_ps_line + elevated_command build the one PowerShell line every elevated launch uses (the NVIDIA
power cap, the sweep helper, the clock sync, an elevated remote job), -WindowStyle Hidden by construction; unit
tests on the line, the quoting and the Command.
- jobrun.rs: the elevated job path uses it; the relaunch helper's Start-Process carries the reason it has no
-WindowStyle Hidden (igneum-app.exe is a windows-subsystem program).
- tools/ci/windows-spawn-check.mjs (+ ci.yml): fails when a Command::new in app/igneum-app/src is not quieted,
a creation_flags is not CREATE_NO_WINDOW alone, a Start-Process the Rust code writes lacks -WindowStyle Hidden or
-NoNewWindow, or host.cpp spawns without CREATE_NO_WINDOW / SW_HIDE; self-test on known-good and known-bad samples.
- tools/windows/console-watch.ps1, console-watch-bg.ps1, console-watch-elevated.ps1: the watchers (run jobs).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Source: the scratch engine's own log in collect ember-c35-collect-1 (06:59Z): 22:31:02Z '0.3.10 is available: downloading',
22:31:05Z 'update: starting the installer first ... ota-apply.ps1', and the installed app's 'quit:' at 22:31:06Z.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
PC 1, 22:31 UTC: the installed engine's quit hung 24 minutes in the jobs runner's abort, waiting for EOF on the script's
stdout pipe whose write end the second engine and its miners had inherited (Process.Start with redirection inherits
every inheritable handle), while the orphaned miners mined on against the relaunched app.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The app's install clears the jobs folder on a PC, so a run job whose kit was fetched by an earlier fetch job finds
nothing after an update and fails in seconds (5 October 2026, 21:49Z, the AMD kit; bench-log 39f02ff). Rule: a run
playbook that reaches a path under the jobs folder other than its own tests the kit is there before its first use,
and the fetch is republished under a new id after any app update.
tools/ci/kit-path-check.sh reads every *.ps1 under relay/playbooks/ and tools/. A kit root is a path derived from
the jobs folder (`$jobs = Split-Path $env:IGNEUM_JOB_DIR` then `Join-Path $jobs '<fetch id>'`, the race-5090.ps1
shape) or one carrying a literal `jobs\` (the amd-card-test.ps1 shape); every path built from it belongs to that kit.
A presence check (Test-Path, [IO.File]::Exists, [IO.Directory]::Exists, Get-Item or Get-ChildItem with -ErrorAction)
on the root or anything under it covers the whole kit. A use before that line fails with "kit path used before a
presence check: republish the fetch after any app update", as does a literal jobs\ path in a command with no check.
The job's own folder ($env:IGNEUM_JOB_DIR) is not a kit path.
Fixtures: kit-path-ok.ps1 (both shapes, checked; a sibling pack file covered by the worker's check) and
kit-path-unchecked.ps1 (the worker run before its check, a literal never checked); --self-test asserts the lines.
Wired into ci.yml after the bash-body step, and into publish-jobs.sh add --kind run beside the other two checks;
test-publish-jobs.sh gains the refusal (34 passed, 0 failed). The current tree: race-5090.ps1 is the one playbook
with a kit, checked before use. README-ship.md: the rule.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A PC job is published from a worktree by packaging/ota/publish-jobs.sh and never passes CI before it runs; tonight
the root-socket fault came back from a job on a branch without the check. `add --kind run` now runs, on the script
being published and before anything is signed: tools/ci/bash-body-check.sh for a PowerShell script (every inline
bash body parses; a body it cannot read fails, never skips), `bash -n` for a .sh script, and
tools/ci/prover-socket-check.sh for both (a root prover run kills sp1-gpu-server and unlinks its socket). A failure
refuses the publish with the check's output; a missing check file refuses too. Kinds without a script (fetch,
collect, restart, update-now, shard-benchmark, build) are untouched.
tools/ci/prover-socket-check.sh is copied from proving-v1 (c2544be; master lacks it) with two additions: file
arguments check those files only (the publisher's call), and an allow list for packaging/ota/test-publish-jobs.sh,
which carries a known-bad root prover script on purpose. Its ci.yml step is left to proving-v1 to avoid a duplicate.
packaging/ota/test-publish-jobs.sh: four refusals (a lost quote in a PowerShell bash body, an unreadable body, a
.sh with a lost quote, a root prover script without the cleanup) and the envelope unchanged after a refusal.
32 passed, 0 failed on this Mac with the main checkout's signer. packaging/README-ship.md: the publish-time gate.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Twice on 5 October 2026 a PowerShell job script carried a bash body inside a string, a quote was lost on the way
through PowerShell, and bash refused the body: pc1-cpu-prove.ps1 (first version) reported exit 0 having done
nothing, the 0.3.10 installer job failed in 4 s. tools/amd-prove/check-job-bash.sh covered only its own here-string.
tools/ci/bash-body-check.sh reads every *.ps1 under relay/playbooks/ and tools/, finds each bash body however it is
handed over (bash -c "...", bash -lc '...', bash -c $var, a + concatenation in parentheses, the Start-Process argument
list, a here-string written to a file that is later run with bash), unescapes it the way PowerShell would (backtick
escapes and "" in double-quoted strings, '' in single-quoted strings, here-strings verbatim; $var left as-is, a $(...)
subexpression replaced by ${PS_SUBEXPR}), and runs bash -n on it. One line per body with the file line of the error.
A body it sees but cannot read is "unextractable body" and fails too: a skip would be a hole in the class check.
bash 3.2 compatible; python3 for the extractor.
--self-test runs three fixtures under tools/ci/fixtures/: the correct shapes (8 bodies, must pass), the lost quotes
(the awk apostrophe, a dropped closing quote in a literal and in a variable; must fail with the line), and three
unreadable bodies (must fail). Wired into ci.yml next to the copied-sources check, self-test first. The current tree:
7 inline bodies in 3 playbooks, all parse. packaging/README-ship.md: the job-script rule (body to a file, bash <file>).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Fed by /api/explorer from the observer's tables. Latest blocks (hash, number, DAA, blue score, miner, txs, proof
records, time); a block's header, parents, children, mergeset, coinbase outputs, EVM transactions, shards, checkpoint
and certificate; an address's blocks, what they earned, vote keys and balance (eth_getBalance when EXPLORER_EVM_RPC is
set). Same tokens as live.html. vercel.json rewrites /block/:id and /address/:addr; the footer links the explorer; the
link checker skips template literals and resolves /api/<name> to its function. node tools/site-serve.mjs previews the
site with the functions in-process.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The numbers profitability sites and pool software read (WhatToMine's form: explorer or pool with an API, the halving
schedule, a source for total coins). Reward and supply from the emission rule at the node's DAA score; the halving table
(33 rows), the 30-day ramp and the observer's coinbase check. Cached 10 s, CORS open. FIELDS in each handler is the
contract; public-stats.test.mjs checks it from a fixture, tools/ci/public-api-check.mjs checks a deployment.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
docs/security/keys.md: every key the project depends on (the folder, the gh
keyring, the Vercel env of three projects, the GitHub secrets) with where it
lives, what it unlocks, the blast radius lost and leaked, who rotates it and
the rotation status, written from the files and the scripts that read them.
No value, no private fingerprint. Section 4: the second OTA signing key kept
offline, the app change (a key list plus revocation in the manifest), 0.3.9
as the carrier, and the emergency path if the one key leaks today (a manifest
signed with a new key is useless to 0.3.x apps; the mitigation in order).
tools/keys/backup.sh: ~/Desktop/igneum-keys-<date>.dmg, AES-256, hdiutil's
own prompt (never argv, history or a file), the folder minus build-slots,
dlsite-dir and pytools/, plus a README; attached read-only, every file
compared by sha256, listed, detached. --dry-run lists. restore.sh: --check
compares the image against the live folder without printing values, --to
copies back with 0600/0644 and 0700. test-backup.sh: the end-to-end test on a
scratch folder with a throwaway passphrase, 8 steps, passed.
tools/ci/no-secrets-check.sh, in ci.yml: no tracked file named like a key of
~/.config/igneum, no 64-hex value assigned to a token/key/secret name outside
tests and the allowlist (the OTA public key, the published Hardhat and Anvil
accounts); a --self-test fires on a known-bad tree first. 776 files, 0 hits.
Also: ~/.config/igneum, vercel/ and txgen/ are 0700 now (were 0755).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Footer partial: imprint line with the registered address and the mailbox; Report a flaw mails hello@igneum.network with the spec issues as the second route. Litepaper: Who are you names the entity that ships the software, the team is pseudonymous with no team page, the ledger and the benchmark source are public with the repository at the public testnet, the last paragraph gives the mailbox and the address. Miner: the dev fee goes to Igneum Labs LTD. Evidence (md and page): repository private until the public testnet. Trademark FILING.md: applicant Igneum Labs LTD at the DIFC address. Identity check: the ledger and fixes file join the export list; the forbidden list notes that the registered address is allowed. Site rebuilt (bench page and journey picked up the txgen log entry).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
On 5 October 2026 the Mac's host (shard program id 0x0559759b...) rejected every
proof from PC 2's host (0x05db1aca...). Both were built from the same guest
sources: host/build.rs compiled the guests on each machine and the ELF depends
on where it is built (cargo's -C metadata for a path crate includes the checkout
path; a worktree on the same Mac gave a third id, 0x0dfade07...). The node's
verifier also spent 114 s to 138 s per proof in the prover client and both key
setups before a 0.1 s to 0.4 s verify.
- elf/: both guest ELFs, their verifying keys and manifest.json (sha256, ids);
host/src/pinned.rs embeds and checks them at every start; the prove modes
refuse when SP1's setup does not derive the manifest's id
- --mode verify: LightProver with the pinned key, no prover client, no key
setup; prints the proof's own program id next to ours ("IS NOT OURS")
- --mode id; igneum-prove-pin and pin-guests.sh to re-pin; build.rs builds a
guest only under IGNEUM_BUILD_GUESTS=1
- tools/ci/pinned-guests-check.sh: elf/ must match its manifest, no script
builds a guest outside pin-guests.sh; make-package.sh and build-dmg.sh print
the pinned ids
- unit tests on the pinned set; bench-log entry with the three ids, the cause
and the timing: 127.0 s wall per verify before, 1.8 s to 2.4 s after
- rollout order in proving/README.md: every prover and verifier moves together
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- docs/analysis/base-fee-floor.md: the base-fee floors (100 gwei per gas, 10,000 gwei per pgas), B_p 120,000 and
S_p 30,000 pgas, the calibrated v1 pgas table (intrinsic 300, modexp 10 + 1 per 10 bytes) from the measured 44
cycles per EVM gas and 9 cycles per pgas, with the arithmetic and a stated price assumption; spec 05 section 5.10.
The parameters are implemented on the node fork branch testnet-params (vendor, not in this repository).
- docs/testnet/README.md: igneum-testnet-1 (chain id 4462, ports 268xx, frozen genesis 2026-10-05T00:00:00Z with
its message and hash, mainnet finality window, every switch from genesis, no override file) and the reset policy.
Every value proposed, for the morning sign-off.
- docs/plans/history-rewrite.md: G14, the exact git-filter-repo pass, the dry run on a throwaway mirror clone (0
identity hits, 0 secrets, every stamp +0000, 312 commits), what breaks and the order for the morning.
- G13: app/igneum-app/src/inputs.rs and igneum-ota-sign sign-inputs / verify-inputs; push-inputs.sh signs
payload-inputs.json with the OTA key and pins the node commit (packaging/windows/node-source.pin);
windows.yml verifies the signature with the embedded key, the zip, every file and the pin before building and
uploads the verified record; fetch-ci-artifacts.sh signs the update manifest only with --sign-manifest <run-id>
after re-verifying that run's inputs. test-inputs-signing.sh (16 cases) and tools/ci/check-workflow-shell.mjs.
- site: testnet terms on the download section, wallet.html (wallet_addEthereumChain, chain ids 4462/4463, IGN, 18
decimals), the litepaper's app paragraph (MetaMask and the coming Igneum Wallet, no hardware wallet) and the
miner fee sentence (no protocol fee; optional 1% in the miner software, off with one flag). node site/build.mjs
and the link check pass.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
windows.yml: parse job (every .ps1 through the Windows PowerShell 5.1 parser with a negative fixture, PSScriptAnalyzer
as warnings, parenthesis check of every .bat/.cmd with a negative fixture), build job (engine on the MSVC target,
window host through BUILD-APP.bat as it is, payload through make-payload.sh in Git Bash, installer through
build-installer.ps1, smoke run of both exes, launcher DRY_RUN, three artifacts for 90 days).
push-inputs.sh publishes payload-inputs.zip (node, miner, workers, NVRTC DLLs) to the downloads host from the Mac;
fetch-ci-artifacts.sh pulls the green run's installer and payload back into the downloads folder.
Host: --version and --help, version.h shared with host.rc. Launcher: DRY_RUN=1 prints the plan and starts nothing.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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>