Merge the mirror's master into ship-docs-0321 (the exception window; release-0.3.22.md as the union of both sides)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
commit
e9474209d4
638 changed files with 100371 additions and 20698 deletions
|
|
@ -5,7 +5,7 @@ tools: Read, Grep, Glob, Bash, Edit, Write, WebSearch, WebFetch, Agent
|
|||
model: fable
|
||||
---
|
||||
|
||||
You are the consensus engineer on a GPU-mined layer 1 built on a fork of rusty-kaspa. Read CLAUDE.md in the project root first, then the design doc it links to. The doc's decisions are fixed unless the project lead changes them.
|
||||
You are the consensus engineer on a GPU-mined layer 1 built on a fork of rusty-kaspa. Read CLAUDE.md in the project root first, then the design doc it links to. The doc's decisions are fixed unless the founder changes them.
|
||||
|
||||
## What you carry in your head
|
||||
The code of every major PoW node and how each one handles the problems you are about to meet:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ tools: Read, Grep, Glob, Bash, WebSearch, WebFetch, Agent
|
|||
model: fable
|
||||
---
|
||||
|
||||
You are the cryptographer and proof-systems engineer on a GPU-mined layer 1 whose miners are also its ZK provers. Read CLAUDE.md in the project root first, then the design doc it links to. The doc's decisions are fixed unless the project lead changes them.
|
||||
You are the cryptographer and proof-systems engineer on a GPU-mined layer 1 whose miners are also its ZK provers. Read CLAUDE.md in the project root first, then the design doc it links to. The doc's decisions are fixed unless the founder changes them.
|
||||
|
||||
## What you carry in your head
|
||||
The whole history of proof of work and of proof systems, and you use it. When you make a claim about a chain, name the chain, the mechanism and where it lives in that chain's code. Examples of what you draw on:
|
||||
|
|
@ -29,7 +29,7 @@ The whole history of proof of work and of proof systems, and you use it. When yo
|
|||
- Numbers are measured or cited. A number from memory is labelled approximate. Never state an ASIC gain, a proving time or a verification time you have not measured or sourced.
|
||||
- Write for an external reviewer: a spec section should let a stranger reproduce the argument.
|
||||
- Prototype in Rust, with Metal on this Mac for GPU work and CUDA or OpenCL ports noted for miners. Benchmarks go in bench/ with the exact command and hardware.
|
||||
- When you disagree with the design doc, say so once, with the attack or the measurement that drives it, then do the work under the doc's decision unless the project lead overrides.
|
||||
- When you disagree with the design doc, say so once, with the attack or the measurement that drives it, then do the work under the doc's decision unless the founder overrides.
|
||||
|
||||
## Writing rules
|
||||
No em dashes. Short sentences. Numbers in tables. The project is called Igneum. Approximate figures say so.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ tools: Read, Grep, Glob, Bash, Edit, Write, WebSearch, WebFetch, Agent
|
|||
model: fable
|
||||
---
|
||||
|
||||
You are the execution engineer on a GPU-mined layer 1 whose every block is ZK-proven by its miners. Read CLAUDE.md in the project root first, then the design doc it links to. The doc's decisions are fixed unless the project lead changes them.
|
||||
You are the execution engineer on a GPU-mined layer 1 whose every block is ZK-proven by its miners. Read CLAUDE.md in the project root first, then the design doc it links to. The doc's decisions are fixed unless the founder changes them.
|
||||
|
||||
## What you carry in your head
|
||||
Every Ethereum client and every open zkVM, and what it costs to prove them:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ tools: Read, Grep, Glob, Bash, WebSearch, WebFetch, Agent
|
|||
model: fable
|
||||
---
|
||||
|
||||
You are the miner-community lead on a GPU-mined layer 1 whose miners are also its ZK provers. Read CLAUDE.md in the project root first, then the design doc it links to. The doc's decisions are fixed unless the project lead changes them.
|
||||
You are the miner-community lead on a GPU-mined layer 1 whose miners are also its ZK provers. Read CLAUDE.md in the project root first, then the design doc it links to. The doc's decisions are fixed unless the founder changes them.
|
||||
|
||||
## What you carry in your head
|
||||
Fifteen years of mining communities, and you remember what they did and why:
|
||||
|
|
|
|||
7
.github/workflows/ci-red.yml
vendored
7
.github/workflows/ci-red.yml
vendored
|
|
@ -3,7 +3,7 @@
|
|||
# ci.yml never enters it (7 October 2026: the inline `red` job of ci.yml was conditioned on master and release-*, and
|
||||
# a feature branch would have waited for a merge of master before its reds were posted at all).
|
||||
#
|
||||
# One line per failed run (tools/ci/red-watch.mjs record, idempotent per run attempt) to /srv/ci-red/red.jsonl on the
|
||||
# One line per failed, cancelled or timed-out run (tools/ci/red-watch.mjs record, idempotent per run attempt) to /srv/ci-red/red.jsonl on the
|
||||
# box; the box's igneum-ci-red.timer posts each new line once to the hidden updates channel, naming the branch, the
|
||||
# commit, the red check and the pushing author. Runs on the box's own runner (not a GitHub-hosted machine: the billing
|
||||
# block of 6 October 2026, 18:37Z to 20:10Z, failed every hosted job at start and nobody was told). Never blocks a
|
||||
|
|
@ -16,7 +16,9 @@ on:
|
|||
jobs:
|
||||
red:
|
||||
name: red watcher (every branch; one line per failed run, with the branch, commit, red check and pushing author, to the updates channel and the box file)
|
||||
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
|
||||
# failure, and since 7 October 2026 (17:2x UK) cancelled and timed_out too: a job that hangs into its timeout-minutes or a run
|
||||
# someone cancels is a run that never answered, and a lane reads it like a red (tools/ci/red-watch.mjs names the kind)
|
||||
if: ${{ github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'cancelled' || github.event.workflow_run.conclusion == 'timed_out' }}
|
||||
# the label ci-red is on igneum-build-1 only (added through the runners API on 7 October 2026; the default of
|
||||
# RUNNER_LABELS in provision.sh carries it): the record file and the poster (igneum-ci-red.timer, the webhook file)
|
||||
# live on that box, and the pool label igneum-build-1 is shared with igneum-build-2 since the same day
|
||||
|
|
@ -35,6 +37,7 @@ jobs:
|
|||
RED_WATCH_RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
RED_WATCH_ATTEMPT: ${{ github.event.workflow_run.run_attempt }}
|
||||
RED_WATCH_WORKFLOW: ${{ github.event.workflow_run.name }}
|
||||
RED_WATCH_CONCLUSION: ${{ github.event.workflow_run.conclusion }}
|
||||
RED_WATCH_BRANCH: ${{ github.event.workflow_run.head_branch }}
|
||||
RED_WATCH_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
RED_WATCH_EVENT: ${{ github.event.workflow_run.event }}
|
||||
|
|
|
|||
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
|
|
@ -36,6 +36,7 @@ jobs:
|
|||
# code=true (no `before` to compare from), as does any error reading the compare API: when in doubt, run.
|
||||
name: what the push touched (docs-only runs skip the Rust and simulator jobs)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10 # a 7 s API call; every job carries a budget (tools/ci/workflow-timeouts-check.sh)
|
||||
outputs:
|
||||
code: ${{ steps.classify.outputs.code }}
|
||||
steps:
|
||||
|
|
@ -62,6 +63,7 @@ jobs:
|
|||
needs: changes
|
||||
if: ${{ needs.changes.outputs.code == 'true' }}
|
||||
runs-on: ${{ vars.IGNEUM_CI_RUNNER == 'box' && fromJSON('["self-hosted", "linux", "x64", "igneum-build-1"]') || 'ubuntu-latest' }}
|
||||
timeout-minutes: 60 # the box's suite ran 45 s to 2 min 40 s on 7 October 2026; a hosted fallback compiles cold
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: toolchain
|
||||
|
|
@ -81,6 +83,7 @@ jobs:
|
|||
# queue read 22); a feature-branch code push runs the igneum-pow tests alone. tools/ci/sims-branch-check.sh holds this rule.
|
||||
if: ${{ needs.changes.outputs.code == 'true' && ((github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/release-'))) || (github.event_name == 'pull_request' && (github.base_ref == 'master' || startsWith(github.base_ref, 'release-')))) }}
|
||||
runs-on: ${{ vars.IGNEUM_CI_RUNNER == 'box' && fromJSON('["self-hosted", "linux", "x64", "igneum-build-1"]') || 'ubuntu-latest' }}
|
||||
timeout-minutes: 45 # two simulators under 120 s each by their own timeout, plus a hosted fallback's pip install
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
|
|
@ -104,6 +107,10 @@ jobs:
|
|||
site:
|
||||
name: site build, link check, identity grep
|
||||
runs-on: ubuntu-latest
|
||||
# 15: the gate took 229 s on a hosted runner on 7 October 2026 plus a 40 s Playwright install; the same day three
|
||||
# hosted site jobs on master hung in the gate for over two hours each with no budget, and GitHub's six-hour default
|
||||
# would have ended each as a failure email. A hung job is a red the watcher posts (ci-red.yml fires on timed_out).
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
|
|
@ -118,4 +125,4 @@ jobs:
|
|||
run: bash tools/ci/pre-push.sh --ci
|
||||
- name: public stats API answers with the documented fields (the live site; master only, the endpoints exist there after the merge)
|
||||
if: github.ref == 'refs/heads/master'
|
||||
run: node tools/ci/public-api-check.mjs https://igneum.network
|
||||
run: bash tools/ci/retry-once.sh public-api node tools/ci/public-api-check.mjs https://igneum.network # a live host: one retry before red
|
||||
|
|
|
|||
8
.github/workflows/windows.yml
vendored
8
.github/workflows/windows.yml
vendored
|
|
@ -216,8 +216,14 @@ jobs:
|
|||
run: |
|
||||
$payload = Resolve-Path 'packaging\windows\igneum-windows-app'
|
||||
function Run-Capture([string]$exe, [string]$flag) {
|
||||
# Start-Process -Wait on an exe that exits in milliseconds can throw "Cannot process request because the process has
|
||||
# exited" before it attaches (release-0.3.21 run 37653903394, 7 October 2026, 17:40 UK): one retry before the verdict.
|
||||
$out = Join-Path $env:RUNNER_TEMP ('smoke-' + [IO.Path]::GetRandomFileName() + '.txt')
|
||||
$p = Start-Process -FilePath $exe -ArgumentList $flag -Wait -NoNewWindow -PassThru -RedirectStandardOutput $out
|
||||
$p = $null
|
||||
foreach ($try in 1, 2) {
|
||||
try { $p = Start-Process -FilePath $exe -ArgumentList $flag -Wait -NoNewWindow -PassThru -RedirectStandardOutput $out; break }
|
||||
catch { if ($try -eq 2) { throw }; Write-Host ("Start-Process on {0} {1} failed once ({2}); second try" -f (Split-Path -Leaf $exe), $flag, $_.Exception.Message); Start-Sleep -Milliseconds 500 }
|
||||
}
|
||||
$text = if (Test-Path $out) { (Get-Content $out -Raw) } else { '' }
|
||||
Write-Host ("{0} {1} -> exit {2}: {3}" -f (Split-Path -Leaf $exe), $flag, $p.ExitCode, $text.Trim())
|
||||
if ($p.ExitCode -ne 0) { throw "$exe $flag exited $($p.ExitCode)" }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Build script for igneum-app. On a Windows target it compiles resources/igneum-app.rc (the coin icon Explorer shows
|
||||
// and the version block under Properties > Details) with windres and links the object into igneum-app.exe. Other
|
||||
// targets: nothing. the project lead's rule (4 October 2026): every shipped exe carries the coin icon and a version block, like the
|
||||
// targets: nothing. The founder's rule (4 October 2026): every shipped exe carries the coin icon and a version block, like the
|
||||
// Mac app and DMG. No crate dependency: windres is called directly (x86_64-w64-mingw32-windres from Homebrew mingw-w64
|
||||
// on the Mac, windres from MSYS2 on a PC; IGNEUM_WINDRES names another one).
|
||||
use std::env;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Windows resources for igneum-app.exe: the coin icon Explorer shows and the version block under Properties > Details.
|
||||
// Compiled with x86_64-w64-mingw32-windres (the icon path is relative to brand/icons, passed with -I).
|
||||
// the project lead's rule (4 October 2026): every shipped exe carries the coin icon and a version block, like the Mac app and DMG.
|
||||
// the founder's rule (4 October 2026): every shipped exe carries the coin icon and a version block, like the Mac app and DMG.
|
||||
#include <winver.h>
|
||||
|
||||
1 ICON "igneum.ico"
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ pub struct Settings {
|
|||
/// (on when that is switched on, never effective while it is off). A pinned card is skipped.
|
||||
#[serde(default)]
|
||||
pub sweep: bool,
|
||||
/// Power control (the project lead, 5 October 2026: "if we don't have to ask then don't ask"): the NVIDIA power cap and the
|
||||
/// Power control (the founder, 5 October 2026: "if we don't have to ask then don't ask"): the NVIDIA power cap and the
|
||||
/// efficiency sweep need administrator rights (one UAC prompt on Windows). Default OFF on every machine; the app
|
||||
/// never raises the prompt on its own. Switching it on asks once, at that moment; a refused, cancelled or
|
||||
/// unanswered prompt switches it back off with a notice, no retries.
|
||||
|
|
@ -345,7 +345,7 @@ pub struct Runtime {
|
|||
pub host: String,
|
||||
/// Per-install random id (16 hex, app data dir/machine-id, locked to the user). Identity labels, vote keys and
|
||||
/// the upload fields come from this, so two PCs cloned with the same COMPUTERNAME never share a key
|
||||
/// (found 4 October 2026 on the project lead's two DESKTOP-KMCV30N machines).
|
||||
/// (found 4 October 2026 on the founder's two DESKTOP-KMCV30N machines).
|
||||
pub machine_id: String,
|
||||
}
|
||||
|
||||
|
|
@ -357,7 +357,7 @@ impl Runtime {
|
|||
let p2p_port = env("IGNEUM_APP_P2P_PORT").and_then(|v| v.parse().ok()).unwrap_or(26611);
|
||||
let peers = match std::env::var("IGNEUM_APP_PEERS") {
|
||||
Ok(v) => v.split(',').map(|s| s.trim().to_string()).filter(|s| !s.is_empty()).collect(),
|
||||
// the public seed node first, then the project lead's Mac on the house LAN (devnet only)
|
||||
// the public seed node first, then the founder's Mac on the house LAN (devnet only)
|
||||
Err(_) if network == "devnet" => vec!["188.245.5.161:26611".to_string(), "192.168.68.64:26611".to_string()],
|
||||
Err(_) => vec![],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4079,7 +4079,7 @@ impl Engine {
|
|||
}
|
||||
|
||||
/// The watts a card's cap asks for: power_pct of the default limit, inside the card's min and max.
|
||||
/// the project lead, 5 October 2026: "if we don't have to ask then don't ask". The NVIDIA power cap and the efficiency sweep need
|
||||
/// the founder, 5 October 2026: "if we don't have to ask then don't ask". The NVIDIA power cap and the efficiency sweep need
|
||||
/// administrator rights (one UAC prompt on Windows, pkexec on Linux); the engine builds an elevated command only when
|
||||
/// Power control is on in Settings, or when it is itself the elevated PC sweep job (--sweep).
|
||||
fn elevation_allowed(power_control: bool, sweep_only: bool) -> bool {
|
||||
|
|
@ -4351,7 +4351,7 @@ mod resume_tests {
|
|||
mod tests {
|
||||
#[test]
|
||||
fn power_control_off_builds_no_elevated_command() {
|
||||
// the decision (the project lead, 5 October 2026): off = the app never asks; the elevated PC sweep job is the exception
|
||||
// the decision (the founder, 5 October 2026): off = the app never asks; the elevated PC sweep job is the exception
|
||||
assert!(!super::elevation_allowed(false, false));
|
||||
assert!(super::elevation_allowed(true, false));
|
||||
assert!(!super::elevation_allowed(false, true), "the --sweep job alone never asks (C35)");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! The `build` job (the model is src/jobs.rs, the runner src/jobrun.rs): a Windows PC builds the node and the app
|
||||
//! engine for Linux and Windows inside its WSL2 Ubuntu, as root, with nothing from the project lead. the project lead's ask, 4 October 2026
|
||||
//! engine for Linux and Windows inside its WSL2 Ubuntu, as root, with nothing from the founder. The founder's ask, 4 October 2026
|
||||
//! evening ("efficiency"): every Windows build went through a GitHub runner at 15 to 25 minutes a round and every
|
||||
//! Linux binary was cross-compiled on the Mac under the build lock; the two RTX 5090 PCs sit idle on the CPU side.
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
/// The safety-net poll. Before 0.3.6 this was 600 s and a published job waited up to 10 minutes on every PC (the project lead,
|
||||
/// The safety-net poll. Before 0.3.6 this was 600 s and a published job waited up to 10 minutes on every PC (the founder,
|
||||
/// 5 October 2026: "why is it taking so long for pc2 and pc1s tasks to spin up?"); the wake below makes it seconds.
|
||||
const CHECK_EVERY_S: u64 = 120;
|
||||
const RETRY_AFTER_ERROR_S: u64 = 300;
|
||||
|
|
@ -50,7 +50,7 @@ const GPU_IDLE_PCT: f64 = 5.0;
|
|||
const GPU_IDLE_WAIT_S: u64 = 180;
|
||||
const DEFAULT_DISTRO: &str = "Ubuntu-24.04";
|
||||
/// WSL jobs run as root by default: the Ubuntu the app sees is the one of the account the app runs under, and a
|
||||
/// personal user ([user] on PC 2) need not exist there (4 October 2026: `getpwnam([user]) failed`).
|
||||
/// personal user (<user> on PC 2) need not exist there (4 October 2026: `getpwnam(<user>) failed`).
|
||||
const DEFAULT_WSL_USER: &str = "root";
|
||||
const DEFAULT_FIXTURES: &[&str] = &["block-338-shard1", "block-341-shards2", "block-344-shards4"];
|
||||
const HISTORY_SHOWN: usize = 20;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//! manifest on the downloads host, and every Igneum Miner app polls it (src/jobrun.rs, every 10 minutes). A job
|
||||
//! runs at most once per id on a machine, only when its target matches (machine id, platform, requirements) and
|
||||
//! it has not expired. Same key, same canonical JSON (sorted keys, no whitespace) and the same `.sig` scheme as the
|
||||
//! update manifest (src/manifest.rs). the project lead's rule, 4 October 2026: one app on both PCs that the Mac can send
|
||||
//! update manifest (src/manifest.rs). The founder's rule, 4 October 2026: one app on both PCs that the Mac can send
|
||||
//! commands and files to over the line, so everything is tested and built without a person at the PC.
|
||||
//!
|
||||
//! This module is self-contained (serde_json and manifest.rs only), so the signer (src/bin/ota-sign.rs) includes it
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Over-the-air updates of the app (and the node, miner and workers inside it). the project lead's rule: every app updates
|
||||
//! Over-the-air updates of the app (and the node, miner and workers inside it). The founder's rule: every app updates
|
||||
//! itself and downloads the update without being asked. This is also how a consensus upgrade (a height-activated
|
||||
//! rule such as difficulty v2) reaches every node before its activation height.
|
||||
//!
|
||||
|
|
@ -120,7 +120,7 @@ pub struct Updater {
|
|||
/// this machine's minute of the hour for applying (manifest::slot_minute of the machine id)
|
||||
slot: u64,
|
||||
/// When this engine started (unix seconds): an update published more than an hour before it is a catch-up, not a
|
||||
/// rollout, and skips the hourly slot (the project lead's morning of 6 October 2026: PC 1 came up after the 0.3.11 publish and
|
||||
/// rollout, and skips the hourly slot (the founder's morning of 6 October 2026: PC 1 came up after the 0.3.11 publish and
|
||||
/// sat on "installs at the next safe moment" until he pressed Install now).
|
||||
started_unix: u64,
|
||||
catch_up_logged: bool,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! One administrator approval, ever (the project lead, 6 October 2026, 11:50 UTC, after clicking the third prompt of the morning:
|
||||
//! One administrator approval, ever (the founder, 6 October 2026, 11:50 UTC, after clicking the third prompt of the morning:
|
||||
//! "can we make sure all these popups are not needed in future?").
|
||||
//!
|
||||
//! What 0.3.12 does: Power control on raises one prompt and sets every cap in that step; but every later cap (an app
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Proving v1 step 1 (5 October 2026, the project lead: "open the proving round asap"): the prover is on by default on every
|
||||
//! Proving v1 step 1 (5 October 2026, the founder: "open the proving round asap"): the prover is on by default on every
|
||||
//! mining machine that can prove, decided once per install after the cards are detected (src/engine.rs
|
||||
//! `apply_prove_default`). The rule, one line each:
|
||||
//!
|
||||
|
|
@ -6,13 +6,13 @@
|
|||
//! |---|---|---|
|
||||
//! | NVIDIA card with 24 GB or more, mining or not, Windows with WSL2 (Ubuntu-24.04) answering or Linux | on | a full shard at the adopted v1 budget (30,000 pgas, 4.7 M cycles) peaks at 20,434 MiB alone and 22,210 beside the miner (measured on the 5090; approximate for a 24 GB card's own allocation); the prototype shard the devnet proves until its fee switch (6.75 M pgas) peaks at 28,307 MiB alone and 30,039 beside the miner, so until the switch only a 32 GB card proves it and a 24 GB card's prover waits for shards it can hold (the host refuses nothing; a proof that runs out of memory fails and the shard is left) |
|
||||
//! | NVIDIA card of 16 to 24 GB | off, with the line saying why | the GPU prover's floor is 13,874 MiB for an EMPTY shard, 15,670 beside the miner; a 16 GB card holds no full shard |
|
||||
//! | NVIDIA card under 16 GB | off | 13,874 MiB does not fit; the project lead's 12 GB requirement is open until a prover build with a smaller floor is measured |
|
||||
//! | NVIDIA card under 16 GB | off | 13,874 MiB does not fit; the founder's 12 GB requirement is open until a prover build with a smaller floor is measured |
|
||||
//! | Windows under 32 GB of RAM | off, with the line saying why | the WSL2 prover held 7.9 GB on a 63 GB PC; a 16 GB PC would swap |
|
||||
//! | Windows with a qualifying card but WSL2 silent | off, with the Set up hint | nothing can prove until the distribution exists |
|
||||
//! | Apple silicon | off | the M5 Max CPU took 41 to 55 s for an EMPTY shard's compressed proof under load and 272 s for a 200-pgas shard; a full shard was never under 60 s (bench-log 4 and 5 October 2026) |
|
||||
//! | AMD-only (no NVIDIA card) | off, "mines and does not prove" | no zkVM proves on an AMD GPU today (docs/analysis/amd-proving.md); the SP1 CPU prover on PC 1 cost 82 to 87 s core plus 199 to 202 s compressed a shard at a 30 GB RSS whatever the shard size (bench-log, "the SP1 CPU prover on PC 1") |
|
||||
//!
|
||||
//! Decided 5 October 2026 (delegated by the project lead: "deploy what is absolute best"), docs/plans/proving-v1.md. The default
|
||||
//! Decided 5 October 2026 (delegated by the founder: "deploy what is absolute best"), docs/plans/proving-v1.md. The default
|
||||
//! never switches an explicit on back off, and Settings always wins afterwards.
|
||||
|
||||
use crate::state::CardState;
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ pub struct CardState {
|
|||
pub tune_source: String, // full | confirm | baseline
|
||||
pub tune_line: String, // "Tuned: 122.3 MH/s at 290 W (0.422 MH/W)" once tuned
|
||||
// a tune in progress on this card, by this engine or by a measurement engine posting /api/tune-progress
|
||||
// (the project lead, 6 October 2026: "don't we need to show in the app that tuning is in progress?")
|
||||
// (the founder, 6 October 2026: "don't we need to show in the app that tuning is in progress?")
|
||||
pub tune_step: u32,
|
||||
pub tune_steps: u32,
|
||||
pub tune_eta_s: i64,
|
||||
|
|
|
|||
|
|
@ -221,11 +221,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn the_command_line_after_the_dashes_never_carries_a_double_quote_or_a_newline() {
|
||||
let file = Path::new("C:\\Users\\the project lead\\AppData\\Local\\igneum\\wsl\\probe-12-3.sh");
|
||||
let line = bash_line(file, true, &["--proof", "/mnt/c/Users/the project lead/AppData/Local/igneum/app/proving/p.bin", "--statement", "0xab", "it's", "two\nlines"]);
|
||||
let file = Path::new("C:\\Users\\the founder\\AppData\\Local\\igneum\\wsl\\probe-12-3.sh");
|
||||
let line = bash_line(file, true, &["--proof", "/mnt/c/Users/the founder/AppData/Local/igneum/app/proving/p.bin", "--statement", "0xab", "it's", "two\nlines"]);
|
||||
assert_eq!(
|
||||
line,
|
||||
"bash -l '/mnt/c/Users/the project lead/AppData/Local/igneum/wsl/probe-12-3.sh' '--proof' '/mnt/c/Users/the project lead/AppData/Local/igneum/app/proving/p.bin' '--statement' '0xab' 'it'\\''s' 'two lines'"
|
||||
"bash -l '/mnt/c/Users/the founder/AppData/Local/igneum/wsl/probe-12-3.sh' '--proof' '/mnt/c/Users/the founder/AppData/Local/igneum/app/proving/p.bin' '--statement' '0xab' 'it'\\''s' 'two lines'"
|
||||
);
|
||||
assert!(!line.contains('"') && !line.contains('\n'), "{line}");
|
||||
// the lookup script's own double quotes live in the file, never on the line
|
||||
|
|
@ -282,7 +282,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn wsl_paths() {
|
||||
assert_eq!(wsl_path(Path::new("C:\\Users\\[user]\\AppData\\Local\\igneum\\app\\proving\\seq.json")), "/mnt/c/Users/[user]/AppData/Local/igneum/app/proving/seq.json");
|
||||
assert_eq!(wsl_path(Path::new("C:\\Users\\<user>\\AppData\\Local\\igneum\\app\\proving\\seq.json")), "/mnt/c/Users/<user>/AppData/Local/igneum/app/proving/seq.json");
|
||||
assert_eq!(wsl_path(Path::new("\\\\?\\D:\\x")), "/mnt/d/x");
|
||||
assert_eq!(wsl_path(Path::new("/tmp/x")), "/tmp/x");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ var View = (function () {
|
|||
function cap(t) { return t ? t.charAt(0).toUpperCase() + t.slice(1) : ''; }
|
||||
var kindWord = Notices.kindWord;
|
||||
// hot-plug (src/hotplug.rs): a removed card's row hides after five minutes (gone); a faulty one has no switch
|
||||
// The list is ordered by performance (the project lead, 6 October 2026): usable cards first, then by the measured rate since the
|
||||
// The list is ordered by performance (the founder, 6 October 2026): usable cards first, then by the measured rate since the
|
||||
// start (5 MH/s buckets so the order does not flicker), then discrete, external and Apple before integrated, then
|
||||
// memory; removed and unusable cards last. Ties keep the detection order.
|
||||
function perfRank(c) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Igneum brand assets
|
||||
|
||||
## The rule (the project lead, 4 October 2026)
|
||||
## The rule (the founder, 4 October 2026)
|
||||
|
||||
One global logo for apps, profile pictures, favicons, everything. The mark sits in a black square. Never in a circle.
|
||||
Never on another colour. Minimum clear space = 20% of the square. The Mac app icon is the model: a full square, all
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Builds every Igneum icon from the master mark, brand/master/igneum-mark-square.svg (4 October 2026).
|
||||
|
||||
the project lead's rule (4 October 2026): one global logo for apps, profile pictures, favicons, everything. The mark sits in a black
|
||||
The founder's rule (4 October 2026): one global logo for apps, profile pictures, favicons, everything. The mark sits in a black
|
||||
square (#0C0C0E, the site's obsidian token), centred, no circle, no ring, no border, never on another colour. The Mac app
|
||||
is the model. The rounded variant (brand/master/igneum-mark-square-rounded.svg, Apple's 824-on-1024 icon grid) is used
|
||||
only where the shape has to be baked into the file: the DMG volume icon. Tahoe masks the plain square itself.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Mark description for the device, when a form asks: "A stylised flame formed of t
|
|||
## Applicant
|
||||
|
||||
Igneum Labs LTD, Licensee Address: Unit IH-00-01-01-OF-01, Level 01, Innovation One, Dubai International Financial
|
||||
Centre (decided 5 October 2026; it replaces the ADGM DLT Foundation named on 4 October). NOT [other-business]: a [other-business]
|
||||
Centre (decided 5 October 2026; it replaces the ADGM DLT Foundation named on 4 October). NOT the earlier entity: an earlier-entity
|
||||
filing would tie Igneum to VIVA and to its owner through public registers, which the standing rule forbids. The
|
||||
registered address above is the applicant address, with a trademark attorney as the address for service, so no
|
||||
personal address appears anywhere. If the company's registration is not complete the week you want to file, the
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Proving on AMD and Apple cards: what exists, what the CPU can do, what to tell the public
|
||||
|
||||
5 October 2026, from the project lead's two questions that evening: "test proving on the amd card?" and "can we test proving on
|
||||
5 October 2026, from the founder's two questions that evening: "test proving on the amd card?" and "can we test proving on
|
||||
mac?". PC 1 holds an RTX 5090 and an RX 9070 XT (gfx1201, 16 GB) in an eGPU; this Mac is an M5 Max. The prover is
|
||||
SP1 (`proving/igneum-prove`, `docs/plans/proving-v0.md`, `proving-v1.md`), run on the GPU only through SP1's CUDA
|
||||
server. Every figure below is measured (with its bench-log entry or job id) or cited (with its file or page); the
|
||||
|
|
@ -115,7 +115,7 @@ gates or a backend ships; it is reviewed with every prover release.
|
|||
|
||||
| Consequence | Action | Owner |
|
||||
|---|---|---|
|
||||
| An AMD-only miner loses the proving share | the CPU tier of 4a is measured here (section 2); whether it becomes a tier is a decision for the project lead on those numbers | this analysis; the project lead |
|
||||
| An AMD-only miner loses the proving share | the CPU tier of 4a is measured here (section 2); whether it becomes a tier is a decision for the founder on those numbers | this analysis; the founder |
|
||||
| The rig's prover unit must select NVIDIA cards only | already true in `prover_decision`; told the rig-installer agent to keep it as a stated rule and to print the CPU-fallback line for AMD-only rigs | rig-installer agent |
|
||||
| The app's Proving tile on an AMD-only or Apple machine should say why it is off and name the CPU path | the `provedefault.rs` lines already say so for Apple; AMD-only Windows machines get "no NVIDIA card ..." | proving agent (told) |
|
||||
| The site and litepaper over-promise for AMD and Apple | the line of 4c, to land with the next site pass (copy law; `node site/build.mjs`; link-check) | site-pages owner; not changed here |
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# ASIC resistance, 2011 to 2026: the history, the papers, the lessons, and the audit of Igneum against them
|
||||
|
||||
5 October 2026 (night), branch `asic-history`. Asked by the project lead at 20:05 UTC: "do a full on deep dive into the full history of 'asic resistance' and see if we can add or upgrade anything." Baseline for the audit: the Counter ASIC 2.0 final class decided tonight (`docs/plans/counter-asic-2-status.md` on `ca2-coord`, entries 20:16 to 22:25 UTC; `docs/analysis/chip-model-v3.md` on `ca2-mixer` 1ab8b21). Every figure about another chain cites a repo file, a paper or a dated article, or is labelled approximate. Hash-per-joule gains are computed from the cited hashrate and watt figures of the chip and of the best consumer GPU of the same year, and are approximate by construction (GPU figures vary by tuning). Research gathered by four sub-agents between 20:10 and 20:45 UTC; the fetch failures they reported are listed in section 6.
|
||||
5 October 2026 (night), branch `asic-history`. Asked by the founder at 20:05 UTC: "do a full on deep dive into the full history of 'asic resistance' and see if we can add or upgrade anything." Baseline for the audit: the Counter ASIC 2.0 final class decided tonight (`docs/plans/counter-asic-2-status.md` on `ca2-coord`, entries 20:16 to 22:25 UTC; `docs/analysis/chip-model-v3.md` on `ca2-mixer` 1ab8b21). Every figure about another chain cites a repo file, a paper or a dated article, or is labelled approximate. Hash-per-joule gains are computed from the cited hashrate and watt figures of the chip and of the best consumer GPU of the same year, and are approximate by construction (GPU figures vary by tuning). Research gathered by four sub-agents between 20:10 and 20:45 UTC; the fetch failures they reported are listed in section 6.
|
||||
|
||||
## 0. One page for the project lead
|
||||
## 0. One page for the founder
|
||||
|
||||
**What the history says Igneum is doing right.**
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ Ranked by how much the history says each would change the outcome, with the cost
|
|||
| 1 | **Price the partial-store chip and draw the time-memory curve.** A chip that stores a fraction f of the dataset in HBM or on many narrow DRAM channels, recomputes the rest from a 256 MiB on-die cache under x8, and reads with 4-byte granularity. Rows for f = 0.25, 0.5, 1 at HBM3 and at GDDR7 random-read rates, priced in energy per hash (Rao's metric) and in reads in flight per watt | The only chip class that beat a memory-bound GPU hash: Ethash's 2.1x to 4.8x came from the memory system with no on-die dataset (rows 3, 4); Rao priced a 16-die DAG holder under a GPU board in 2019; Cuckoo's curve was wrong by 50x until drawn [P20]; O-1.6 is open and `MEMHARD.md` section 3 item 2 says the curve was never drawn | None (analysis) | The row may come out over 2x, which would qualify the public claim before anyone else does | Genesis (before the vectors freeze) |
|
||||
| 2 | **A random item-derivation program per day** in place of the fixed-shape mixer: a SuperscalarHash-style generator, integer only, drawn from the day key, with its own acceptance test, compiled once a day by miners and verifiers | RandomX's reason for SuperscalarHash: a fixed derivation is hard-wired by a chip; a random one makes the light-mode chip a CPU (section 2.4). In Igneum's model the fixed shape is the 3x factor that turns 0.31x into 0.92x; removing the factor is worth more than x8 to x16 would be (x16: 0.46x with the factor by M16's table) | None per hash (the daily build is 23 to 77 ms at x8 and would roughly double); the verifier needs a per-day compiled derivation (a JIT, or a round schedule drawn from a fixed set of reviewed rounds), measured against the 10 ms gate | Cryptanalysis of random ARX programs; weak draws; a JIT in the verifier is new attack surface; the vendors must agree bit-exactly on a program they compile | Reserve (named family, unlock by height or signal) now; genesis if the verifier cost is measured under the gate before the freeze |
|
||||
| 3 | **External cryptanalysis of M_r, the chained cache and the acceptance rule before genesis**, with the x8 shape as the target | Lesson 9 (MTP, Catena, Argon2i, Cuckoo); RandomX bought four audits for $141,000 before launch [S60]; the x8 decision multiplies the mixer's weight in the chip model, so a shortcut inside the mixer is now worth 8x more to a chip | None | Finding something late moves the vectors; not finding it in time moves nothing | Genesis gate (ledger M7, raised in priority) |
|
||||
| 4 | **The clock and the detector.** (a) A share-pattern detector on the observer: per-program hash-rate spread, nonce-group patterns and per-card-model rate bands, with an alert when a population behaves like one fixed design (MoneroCrusher's method); (b) a stated trigger: the bounty escrowed and the benchmark live before daily issuance crosses about $50K (Vorick's rule), not on a calendar date | Lesson 10 (85% secret share); section 2.5's table (chips at $20K to $30K a day on compute-bound hashes); D11 (the bounty is unfunded) | None | A detector with false positives; a trigger the project lead has to fund | Not a layer; genesis-independent; do it before the public testnet |
|
||||
| 4 | **The clock and the detector.** (a) A share-pattern detector on the observer: per-program hash-rate spread, nonce-group patterns and per-card-model rate bands, with an alert when a population behaves like one fixed design (MoneroCrusher's method); (b) a stated trigger: the bounty escrowed and the benchmark live before daily issuance crosses about $50K (Vorick's rule), not on a calendar date | Lesson 10 (85% secret share); section 2.5's table (chips at $20K to $30K a day on compute-bound hashes); D11 (the bounty is unfunded) | None | A detector with false positives; a trigger the founder has to fund | Not a layer; genesis-independent; do it before the public testnet |
|
||||
| 5 | **Rank layer 9 (the epoch length) up, and measure the FPGA lane**: the compile-ahead cost per card at a 10-minute epoch (the `ca2-epoch` work), plus an estimate of a soft-overlay FPGA miner with HBM (reads in flight per watt against the 5090's 17.5 G/s) | FPGAs were the first adversary of Lyra2REv2 and X16R and came back within weeks of X16Rv2 (rows 7, 9); Xelis forked for FPGA resistance (row 30); a per-hour program is a bitstream target in a way a per-hash program is not | At 10-minute epochs: 6x the compile work per card (measured on `ca2-epoch`); the VDF lead shrinks | A short epoch moves the difficulty window (spec 1.12) and the seed path | Reserve (as decided), with the measurement before the public testnet |
|
||||
| 6 | **Order the reserve by chip-unfriendliness**: families that force a full 32-bit datapath per lane first (byte permute, bit-field extract, variable shifts, popcount, select, the second shuffle form), mm8 last | Least Authority's "watch ML hardware"; int8 matrix blocks are licensable IP at every node; Apple pays 1.6x to 4.7x per emulated dot4 (status 20:38) | None at launch | None | Reserve ordering, genesis |
|
||||
| 7 | **A vendor-share metric and a 3.0 target for the AMD gap**: the share of hashrate by vendor published with the benchmark, and the line-width question kept open as the plan says | Lesson 8: a one-vendor fleet is a softer version of chip capture; Equihash's NVIDIA tilt and Ethash's balance were part of each chain's miner politics (rows 3, 5) | n/a | A width that closes the gap makes the 5090 bandwidth-bound (status 20:27) | Counter ASIC 3.0 |
|
||||
|
|
@ -256,14 +256,14 @@ Evaluated and placed nowhere, with the reason:
|
|||
| Divergent data-dependent branches | Nowhere (already excluded) | Branches cost a GPU divergence and a chip nothing; RandomX's single predictable branch targets speculative CPUs, which Igneum does not have |
|
||||
| Floating point | Nowhere (already excluded) | Vendor rounding splits the chain (spec 1.14); RandomX could afford it because its target is one ISA family with IEEE semantics |
|
||||
|
||||
## 5. Decisions this raises for the project lead
|
||||
## 5. Decisions this raises for the founder
|
||||
|
||||
| # | Decision | Recommendation |
|
||||
|---|---|---|
|
||||
| 1 | Add the partial-store chip rows to `chip-model-v3.md` and draw the time-memory curve before the public testnet | Yes, before the vectors freeze (addition 1) |
|
||||
| 2 | Name a random item-derivation program as a reserve family, and fund the verifier measurement that would move it to genesis | Reserve now; genesis if the verifier lands under the gate (addition 2) |
|
||||
| 3 | Commission the external cryptanalysis of M_r and the chained cache before genesis, with the x8 shape as the target | Yes (addition 3; ledger M7) |
|
||||
| 4 | Escrow the bounty and set its trigger to daily issuance, not to a date; build the share-pattern detector on the observer | Yes to the detector now; the escrow is the project lead's (D11) |
|
||||
| 4 | Escrow the bounty and set its trigger to daily issuance, not to a date; build the share-pattern detector on the observer | Yes to the detector now; the escrow is the founder's (D11) |
|
||||
| 5 | Rank the epoch-length reserve above the mm8 reserve, and measure the FPGA lane | Yes (additions 5 and 6) |
|
||||
|
||||
## 6. Sources and limits of this research
|
||||
|
|
|
|||
616
docs/analysis/attack-pass-2026-10.md
Normal file
616
docs/analysis/attack-pass-2026-10.md
Normal file
|
|
@ -0,0 +1,616 @@
|
|||
# Internal attack pass before the freeze (F1 to F10)
|
||||
|
||||
The internal cryptanalysis pass of `docs/plans/cryptanalysis.md` section 4.2, run before the freeze tag
|
||||
`cryptanalysis-target-1`, so the paid engagement confirms rather than discovers. The founder's word, 7 October 2026:
|
||||
"make sure they find ZERO flaws". Every finding is ours, fixed and re-gated, before any firm starts.
|
||||
|
||||
Target: the hash class the chain runs after 0.3.15's flip, `igneum-pow` generator v4 `V4_CLASS` = `mx8+sh256x27`
|
||||
(`LoadClass::MX8`, `ShadowClass { instrs: 256, reps: 27 }`), the acceptance rule, the verifier, the era draw,
|
||||
the latency-shadow dataset and ladder, the chip and FPGA cost model. Scope and gates are section 1.1 and 1.4 of
|
||||
the plan, the same tests the firm is held to.
|
||||
|
||||
Lane: attack-pass, worktree `igneum-wt-attack`, branch `attack-pass` from `origin/master` `ab99e5e3`.
|
||||
Binary built on igneum-build-1 (ELF x86-64, `igneum-pow` 0.2.0, sha256 6d2867...1a9ebe5) and run there under
|
||||
the box's slots; model and era work from `sim/horizon/algorithm/model.py` and `infra/fast-time/`. Each row below
|
||||
carries the method, the known-failed shape where one exists, the result with numbers, and PASS, RUNNING,
|
||||
BLOCKED or FINDING. PASS RECORD (7 October 2026, 16:0x UTC, 17:0x UK): every row reads PASS or FIXED-AND-PASSED. F1 PASS (AP-F1-1 on the
|
||||
v5 list at 3.0 percent); F2 PASS, effort-bounded; F3 PASS; F4 PASS against class v4 (AP-F4-1 on the v5 list); F5
|
||||
FIXED-AND-PASSED (the F2 hour skipped by decision); F6 PASS (the worst of 10^5 programs 8.708 ms on the half-core
|
||||
proxy; O-1.14 closed on an i7-9700K); F7 PASS on all three sub-rows (the era VDF in the node, 0 of 6 re-rolls); F8
|
||||
FIXED-AND-PASSED in class v4 sub-version 3 at 017e7037 (AP-F8-1, AP-F8-2, AP-F8-3 ours and closed; the four-seed
|
||||
unattributed tail named); F9 PASS on (a) and (c), (b) closed by the same fix; F10 PASS. Frozen generator: class v4
|
||||
sub-version 3, igneum-pow 017e70376489251e18564c0abce7e466e606c8b3, devnet epoch-0 id a785001687d8688a. The
|
||||
freeze tag `cryptanalysis-target-1` is the coordinator's cut on this record; the era VDF precondition is met (F7 a). Main checks every number
|
||||
against the log before quoting it to the founder.
|
||||
|
||||
## Status board
|
||||
|
||||
| # | Attack | Gate (same as 1.4) | Result so far | Status |
|
||||
|---|---|---|---|---|
|
||||
| F1 | Shadow block compressibility and shortcut search | no compression of the shadow block beyond the honest compiler's simplification, measured against that compiler on the same program; the 27 repetitions never fewer than 27x (coordinator's ruling 7 Oct 2026, 12:3x UK; the plan's gate (1) and row F1 carry the same) | 10^4 and 10^5 class v4 programs: saved instructions mean 0.62%, max 5.078% at 10^5 (1 of 100,000 over 5%, 0 over 10%); nothing folds or dedupes across the 27 passes; every saving is local peephole algebra that clang -O3 removes from the honest kernel too (IR counts match on the worst programs), so against the compiler the compression is 0; 0 mismatches in 2 x 10^5 differential and verifier checks, z3 window proofs 0 counterexamples. AP-F1-1 routed to the v5 list as a shadow redundancy bound. Record `docs/analysis/attack-pass/f1-shadow.md` | PASS; AP-F1-1 on the v5 list |
|
||||
| F2 | Mixer round margin (SAT/MILP, 1 to 4 keyed applications) | no distinguisher or shortcut beyond 2 of the 8 applications | one application characterised (differential weight 10 to 12, linear 1, verified on the real code on three days); two applications: no trail at or below weight 20 to 24 within 7,200 s per job, the MSB and LSB families die at two; rotational-XOR no bias at one application; the multiply layer folds on 0 of 2^20 inputs, k applications cost k; three applications: no differential trail at or below weight 29 to 35 and no linear at or below 24 to 28, four: 39 to 47 and 24, every job at its 7,200 s cap. Record `docs/analysis/attack-pass/f2-mixer.md` | PASS (effort-bounded) |
|
||||
| F3 | Chained cache j+1 bound and storage-vs-recompute curve | no derivation under j+1 blocks; curve monotone; f=1 point unchanged | 0 of 64 and 0 of 1,024 lines under j+1 (exhaustive closure search, cross-checked by exhaustive pebbling at 10 lines, 10,240 pairs, 0 mismatches); both planted broken chains fire; curve monotone at both op counts; f=1 point 9,360 ops per item unchanged. Record `docs/analysis/attack-pass/f3-cache.md` | PASS |
|
||||
| F4 | Weak-day census over 2^24 day keys | fraction of days with gain over 1.1x under 2^-20 | PASS against M2 (DSP-bound datapath): 0 of 2^28 days over 1.1x; planted weak days fire; every ROT and RC class 0. Bound finding AP-F4-1 on M1 (LUT adders): 5,476 of 2^24 days (3.26e-4) over 1.1x as the tail of a sum, no weak class; worst public-calendar day 29,337 at 1.121x, at most 12.1% more rate that day for a per-day LUT FPGA, 0 for any chip; redraw rule (NAF sum under 163 rejected) routed to the next class. Record `docs/analysis/attack-pass/f4-weakday.md` | PASS (v4); AP-F4-1 routed to the next class |
|
||||
| F5 | Chip-model sweep + AWS F2 FPGA hour | evidence row 17 holds across the sweep; FPGA row under 27 M reads/s/W | sweep: 2.1x at k=1 GDDR7 reproduces, 3.2x at k=0.5, 4.1x at k=0.3 (matches ledger M32); FPGA row 2.3 to 2.9 G/s, 10 to 20 M reads/s/W (literature). FINDING: the k=0.33 figure is framed as the X9's measured core (M32) and a "measured class" (ladder branch §5a); the X9 was withdrawn before launch and never benchmarked. F2 hour SKIPPED: no AWS account | FIXED-AND-PASSED (sweep PASS; AP-F5-1 fixed and re-gated 7 Oct 2026: chip section re-run 2.1x at k=1 unchanged, identity grep 0 hits, site lane concurred); F2 hour SKIPPED-BY-DECISION (the founder, 7 Oct 2026, 09:5x UK; plan 4.2 row F5 is the sweep only at 3714c2a0; the FPGA row stays the JEDEC-ceiling model row labelled unmeasured) |
|
||||
| F6 | Verifier worst case over 10^5 programs + O-1.14 laptop run | worst program under 10 ms cold on the half-core proxy and the laptop | 100,000 programs ranked, 50,000 timed cold one-core (worst 6.194 ms), the worst 200 re-timed and the worst 1,000 timed on the half-core proxy under the per-core lease (core 40 at 3,799.9 MHz): worst 8.708 ms (`attack-f6/87142`), 1.29 ms under the gate, every half-core reading under 9 ms; dr736 fails as it must (15.49). O-1.14 CLOSED on an i7-9700K (v4 6.334 ms cold max, dr736 10.04 fails). Ladder ceiling from the worst program on the half-core proxy: N about 300,000, so rung 2 admissible, rung 3 not. Record `docs/analysis/attack-pass/f6-verifier.md` | PASS |
|
||||
| F7 | Era-draw bias harness + 2^20 era-seed census | no re-roll inside the publish window; no era class with gain over 1.1x over 2^-20 | (b) census PASS at 2^24 seeds (no class over 1.1x, stride bijective, R, pos and M uniform, planted cases fire); (c) 64-bit day-key seeding PASS (0 collisions in 2^17); (a) PASS with the era VDF in the node (era-vdf lane, fork era-vdf-node 394a5902 on release-0.3.20-node c4459193, behind era_vdf_activation_daa; master a4eaf766 carries the spec text, `docs/analysis/era-vdf-2026-10-07.md` and `tools/era-vdf/reroll.mjs`): against the real era cut on three fast-time nodes the re-roll harness fires with the VDF off (6 of 6 cuts) and is silent with it on (0 of 6; the adversary's 5.4 to 6.6 s evaluation against a 1 s block interval, the honest chain 3 to 10 blocks ahead, three nodes agreeing on every era seed); the delay is 517 s on the fastest prover measured (chiavdf NUDUPL over GMP, 208.8K squarings/s) at T = 108,000,000, 259x the 2 s window. Open, not a gate: the verify is 22 ms against the 10 ms target (O-4.6, 0.3.22). Record `docs/analysis/attack-pass/f7-era.md` | PASS (a, b, c) |
|
||||
| F8 | Uniformity censuses (line-index 2^28, distinct lines, cross-hash histogram) | uniform within the window model of spec 1.13.1, layer 8; the excess beyond it within 6 sigma over 64 seeds; no hot set under 1% of items beyond the model | line index PASS at 2^28. The 6 Oct stream: 31 of 64 seeds over 1.2x (AP-F8-1, the lossy load source). Sub-version 1 (8c728ca3): 11 of 64. Sub-version 2 (07a809a7 / 8bdcbdd8): 9 of 64; AP-F8-2 (exhaustion) closed there, 0 of 10^6. Sub-version 3 (017e7037: the acceptance executing the shadow block, AP-F8-3; the shared-operand rule; (c'') the distinct-index ratio): 60 of 64 under 1.2x, the four over the named unattributed tail at 1.22x to 1.50x with no chip consequence; 0 exhausted in 24,631 chain-shaped seeds, the draw total by construction. Record `docs/analysis/attack-pass/f8-uniform.md` | FIXED-AND-PASSED (sub-version 3, 017e7037, the frozen generator) |
|
||||
| F9 | Acceptance edges (39) + header grinding on an RTX 5090 | zero passing programs with a hot set under 1%; grinding gain under 1% of rate | (a) edges on generator 4 over 10^5 seeds: 34 disagreements in 105,064 candidates (29 const_bit, 4 bias, 1 lane_const), every one a one-bit or sampling-noise property moving the choice to an attempt both stand-ins accept, nothing in the attacker's favour: PASS; (b) hot-set search over 10^6 seeds: 11,696 passing programs (1.17%) concentrate 1% or more of reads on a hot set, worst 17.3%: FINDING, the same or-saturation load-source class as AP-F8-1 found by a second harness (F9-1 merged into AP-F8-1), re-gated on the amended stream; (c) grinding on the 5090: +0.004% at K = 2^14, ceiling +43%: PASS. Record `docs/analysis/attack-pass/f9-grind.md` | (a) PASS; (b) the AP-F8-1 class on the 6 Oct stream, closed by sub-version 3 (F8's census is the re-gate instrument; this harness's hot-share metric counts the era's windows); (c) PASS |
|
||||
| F10 | Ladder signal monotonicity harness | no step without 90% over 7 windows in either direction | known-fail fails, known pass passes; new cases on the exact-share driver: 89% up holds (no step), 89 then 90% down with restarts steps only at 90% after the 7-window cool-down, the floor holds under 100% down (never below rung 0); decision per seed block memoised, identical after a restart, never differs between nodes; 19 of 19 checks per case. Two items to main, not findings: a stale commit string in the ladder lane's igneumd, and proof-synced nodes deciding rung 0 until the witness lands (a precondition line for spec 01). Record `docs/analysis/attack-pass/f10-ladder.md` | PASS |
|
||||
|
||||
## The rows
|
||||
|
||||
### F1. Shadow block compressibility and shortcut search (hash lane)
|
||||
|
||||
Method: over 10^4 class v4 programs, constant folding, dead-register elimination, common subexpressions across the
|
||||
27 repetitions, linear sub-block detection, SAT equivalence on reduced blocks; the minimum op count per program
|
||||
against N. Known-failed shape: a shadow that constant-folds or dedupes across its 27 identical passes so a chip
|
||||
pays fewer than 55,296 shadow instructions per hash. Entry point: `igneum-pow show --program-class v4` prints the
|
||||
256-instruction shadow (op mix add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12 on the
|
||||
genesis seed). Gate: best compressed block within 5% of N on every program; no program over 10% compressible.
|
||||
Result: RUNNING. What a failure moves: an acceptance-rule line for the shadow block (rule (c) runs the block),
|
||||
packs re-cut.
|
||||
|
||||
### F2. Mixer round margin (hash lane, on the box)
|
||||
|
||||
Method: SAT or MILP differential and linear search on 1 to 4 keyed applications with drawn rotations; rotational-XOR
|
||||
on the ARX layer; the fold of the multiply layer across applications checked algebraically. Known-failed shape: a
|
||||
differential or linear trail or an algebraic fold that distinguishes or shortcuts more than 2 of the 8 applications
|
||||
between dependent reads. Gate: no distinguisher or shortcut beyond 2 of the 8 applications. Result: RUNNING (prior
|
||||
`ca2-mixer` evidence to be re-gated). What a failure moves: `mixer_mult` 16 or a shape change; verifier re-measured.
|
||||
|
||||
### F3. Chained cache j+1 bound and storage-vs-recompute curve (hash lane, on the box)
|
||||
|
||||
Method: exhaustive search on a 2^10-line model segment for a line derivable without an earlier line; the curve from
|
||||
f = 1/64 to 1 in ops per item. Known-failed shape: a line (s, j) computable in fewer than j+1 block evaluations
|
||||
without an earlier line (the MTP address-steering break shape). Gate: no derivation under j+1 blocks; curve monotone;
|
||||
f=1 point unchanged. Result, 7 October 2026, 09:10 to 09:12 UK on the box (`docs/analysis/attack-pass/f3-cache.md`; logs
|
||||
`/srv/builds/igneum-wt-attack/attack-f3/r1-*.log`): PASS on all three clauses. The chain extracted from
|
||||
`Cache::fill_segment` (verified equal to the code on 16 of 16 key and segment pairs; `block == chacha_block` on
|
||||
100,000 random inputs) has line j fed by line j - 1 only; the exhaustive closure search finds 0 of 64 and 0 of
|
||||
1,024 lines under j + 1 (every line costs exactly j + 1), cross-checked by an exhaustive pebbling search at 10
|
||||
lines (10,240 configuration and target pairs, 0 mismatches). The two planted chains fire: `skip2` (63 of 64 under
|
||||
j + 1) and `nofeed` (every line in 1 block). The curve over stored cache lines is monotone non-increasing from
|
||||
f = 1/64 to 1 at 608 (counted) and 700 (MEMHARD.md) ops per block; the f = 1 point is 9,360 ops per item,
|
||||
41.7 MH/s at the 50 T op/s budget, unchanged. `ca2-cache` was the hot-table experiment, not a chain analysis, so
|
||||
there was nothing to re-gate. Observation (coordinator and the F3 record, not a finding): `funding.md` B2 rank 2
|
||||
prices the trade-off at the naive placement; the optimal placement of every 8th line costs 3.17 blocks per read,
|
||||
not 3.5, and 16.0 at f = 1/64, not 31.5 (brute force over 4,426,165,368 sets at n = 8); the chip stays worse than
|
||||
the full mirror at every f under 1, so the verdict stands, and a `chacha_block` shortcut in chaining mode stays
|
||||
the paid question (Lot A and B). What a failure would have moved: the chain construction (a second feed-forward or
|
||||
a cross-segment tie).
|
||||
|
||||
### F4. Weak-day census over 2^24 day keys (hash lane, on the box)
|
||||
|
||||
Method: 2^24 day keys through `MixParams::with_shape`; the ROT classes (all equal, complementary pairs, small
|
||||
amounts), MUL low weight, RC structure, each per-day gain measured on the box verifier. Known-failed shape: a day
|
||||
key whose drawn ROT/MUL/RC gives a fixed datapath a gain over 1.1x (the "weaker authorized parameters" class,
|
||||
Kudelski 2019). Gate: the fraction of days with any gain over 1.1x under 2^-20. Result: RUNNING. What a failure
|
||||
moves: a rejection-and-redraw rule on the draws.
|
||||
|
||||
### F5. Chip-model sweep and the FPGA hour (algorithm lane)
|
||||
|
||||
Method: `sim/horizon/algorithm/model.py` over k 0.2 to 1.5, tFAW 12 and 28 ns, HBM4 2.3 and 21.4 G reads per
|
||||
stack, amortisation 1 to 3 years, electricity USD 0.05 to 0.15 per kWh; and the AWS F2 hour replacing the FPGA
|
||||
ceiling row with a measurement. Known-failed shape: an input of the published model that, when corrected, lifts the
|
||||
f=1 chip's per-joule edge over the 5090 above the published 2.1x at k=1.
|
||||
|
||||
Gate: the published sentence (evidence row 17) holds across the sweep; the FPGA row under 27 M reads/s/W.
|
||||
|
||||
Result (sweep): PASS on the numbers. The model's measured-anchor column (GDDR7, the 5090 reads 82% of its ceiling)
|
||||
gives the f=1 chip's v4 per-joule edge over the RTX 5090 bench row as 4.1x / 3.2x / 2.1x / 1.5x at k = 0.3 / 0.5 /
|
||||
1 / 1.5. At k = 1 the figure is 2.1x, and 3.9x at k about 0.33, which matches `fud-ledger.md` M32. The higher HBM3
|
||||
and HBM4 columns rest on an 8-activate per 12 ns window that JEDEC HBM2 timings (4 per 28 ns) do not support; the
|
||||
model already states GDDR7 is the column to quote. One wording gap: `evidence.md` row 17 says "brings it to about
|
||||
2x", which is a floor that holds at k about 0.9 and above but understates the edge at lower k (3.2x at k = 0.5). The
|
||||
accurate statement is M32's, 2.1x at k = 1 with the k range beside it. The sweep's numbers stand; the finding is the
|
||||
X9 framing below.
|
||||
|
||||
FPGA row: the HBM2 FPGA ceiling is 2.3 to 2.9 G reads/s (measured Shuhai U280, FCCM 2020, equal to the JEDEC
|
||||
tFAW-bound 2.3 G/s), 10 to 21 M reads/s/W at 115 to 150 W, 0.30 to 0.47x of the 5090 per watt. Under the 27 M
|
||||
reads/s/W gate. The AWS F2 hour is SKIPPED-BY-DECISION (the founder, 7 October 2026, 09:5x UK: not needed for now, not blocked;
|
||||
plan 4.2 row F5 at commit 3714c2a0 on branch cryptanalysis is the chip-model sweep only, 4 h, the algorithm lane).
|
||||
There is also no AWS account or `aws` CLI on this Mac. The FPGA row stays the JEDEC-ceiling model row labelled
|
||||
unmeasured; Lot C prices it from the reads-in-flight model; the firm is told the F2 measurement was not run.
|
||||
|
||||
FINDING (X9 framing), owning lane algorithm and hash (the ladder lane is closed, so ours): the published numbers
|
||||
already carry 2.1x at k = 1 beside 3.9x at k about 0.33 (`fud-ledger.md` M32, recalibrated under X35). The error is
|
||||
the framing. M32 calls the k = 0.33 figure "the X9's core" and the `ladder` branch's `latency-ladder.md` section 5a
|
||||
calls k about 0.33 a "measured class". Bitmain's Antminer X9 (RandomX ASIC, 1 MH/s, 2,472 W, about USD 5,600) was
|
||||
announced and, per pcpraha.cz ("Antminer X9 canceled: Bitmain withdraws model from market before launch") and
|
||||
r/MoneroMining, withdrawn before launch. Its implied core efficiency (k about 0.33) is a CLAIMED datasheet figure
|
||||
from a design that never shipped and was never benchmarked, not a measured calibration point. It is carried as the
|
||||
pessimistic bound, not a calibration. This collides with the merged ledger X34 ("RandomX has a shipping chip;
|
||||
correct every sentence that said otherwise"): if the X9 was withdrawn, X34's correction is itself wrong and must be
|
||||
reversed. Confirmed from primary sources (coordinator, 7 October 2026): pre-orders opened 26 December 2025 (shipments
|
||||
scheduled for July 2026), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent
|
||||
benchmark, Bitmain never published a cancellation (its shop lists it as sold out), and the box was commodity Sophgo
|
||||
SG2044 server SoCs with an AES accelerator and 60-plus DRAM sticks, no tapeout; its claimed edge about 2x per joule
|
||||
over a tuned Zen 4 part, about 3x over a stock desktop CPU. Re-cut applied the same day: `evidence.md` row 17 (claim
|
||||
and measured cells) and `fud-ledger.md` M32's answer paragraph on attack-pass, and the ladder design doc section 5a
|
||||
on branch `attack-ladder-5a` from the ladder tip 7003f9f5 (the `ladder` branch is checked out by another lane, so
|
||||
the fix rides its own branch for the ladder owner to take). The served-text rows (X34 reversal, X36) belong to the
|
||||
site lane, which confirmed the wording agrees. What a finding moves
|
||||
(plan 4.2 F5): the sentence re-cut before the freeze so the firms attack the corrected model. The re-cut, once the
|
||||
fact is confirmed: k about 0.33 labelled a claimed pessimistic bound from a withdrawn design everywhere it appears;
|
||||
2.1x at k = 1 on the GDDR7 measured anchor kept as the headline with the k range beside it; k itself unmeasured
|
||||
until Lot C produces it. This row reads FIXED-AND-PASSED only after the re-cut and its re-gate.
|
||||
|
||||
Economic row the withdrawal implies: a recompute chip at a 3x fixed-function factor against a CPU and GPU fleet
|
||||
must recover its NRE (low to mid seven figures at a modern node, `chip-model-v3.md`) and carry a fork threat (a
|
||||
class change at 95% miner signal can redraw the datapath the chip bakes in). The X9 at 2.47 J per KH against a
|
||||
RandomX CPU fleet did not clear that bar at Monero's hash and price; the same arithmetic against Igneum's class v4,
|
||||
with the shadow block and the automatic era draw as extra firmware risk, is why the chip model's verdict is a
|
||||
deliverable and not a courtesy (plan 2.3). The confirmed reading: a box with a 2x to 3x per-joule edge and no NRE (commodity SoCs) was withdrawn rather than
|
||||
face a 1.5x re-tune of RandomX, so the tapeout economics of a 3x chip against Igneum are worse than the X9's. This
|
||||
row is the pessimistic case, not a measured gain.
|
||||
|
||||
### F6. Verifier worst case (algorithm lane)
|
||||
|
||||
Method: 10^5 class v4 programs timed on the box one-core and half-core proxies for the slowest warp (base program
|
||||
and shadow block), plus the O-1.14 laptop run (the Windows `igneum-pow` build on the box, the relay, `bench
|
||||
--warps 50`). Known-failed shape: a drawn program whose verifier warp exceeds 10 ms cold (the acceptance rule bounds
|
||||
the miner's side, not the verifier's; `dr736` already FAILs at 10.51 ms cold one-core, but it is not the shipping
|
||||
class). Gate: the worst program under 10 ms cold on the half-core proxy and on the laptop.
|
||||
|
||||
O-1.14 route (coordinator, 7 October 2026, 10:1x UK): no US laptop is due, so the laptop run is replaced by a
|
||||
rented 2019-class CPU host through the fleet agent, capped at two hours of rent; the Linux `igneum-pow` from the box
|
||||
(the same binary as the proxies) runs `bench --warps 50` for v2, mx8, mx8+sh256x27, dr368 and dr736 (the
|
||||
known-fail) on it; INCOMPLETE with the numbers so far if the cap lands first. The Windows exe was also built on the
|
||||
box for the day a laptop appears (1,009,675 bytes, sha256 fbed7538...e6c9). Outcome, 09:40 UK: no 2019-class CPU
|
||||
host stood up. Vast accepted and dropped five CPU-class rents within 30 s each (i7-9700K, i5-8500, Xeon W-2133 and
|
||||
W-2123) under the account's automatic new-account spend limit (support ticket open since 6 October), and RunPod has
|
||||
no 2019-class CPU pod; so O-1.14 reads INCOMPLETE on the box proxies today and stays a precondition of the freeze.
|
||||
Next try: the US laptop when it registers on the relay (the exe is ready), or Vast once the spend limit lifts; the
|
||||
bench script is staged and runs in minutes. Correction, 10:4x UK (fleet agent): the provider dropped nothing; every
|
||||
rent stood up and ran, hidden by Vast's instance listing cap of 25 rows on an account holding 38, so the hosts sat
|
||||
idle and were destroyed. The fallback is re-rented under the same word (i7-9700K class, two-hour cap from its start,
|
||||
read by id); the result replaces this line when it lands.
|
||||
|
||||
O-1.14 RESULT, 7 October 2026, 09:49 UK, Vast instance 54613164, Intel Core i7-9700K (2019 desktop core, Coffee Lake,
|
||||
read at 4,170 MHz during the run, 31 GB DDR4, Ubuntu 24.04), the box-built Linux `igneum-pow` (sha256 6d286783...),
|
||||
`bench --seed igneum-genesis --day 2026-10-03 --warps 50` on one core (`taskset -c 1`), the host otherwise idle; log
|
||||
`docs/analysis/attack-pass/o114-i7-9700K-2026-10-07.log`:
|
||||
|
||||
| Class | Cold max (ms per warp) | Average of 50 (ms) | Gate 10 ms | Box one-core cold | Box half-core |
|
||||
|---|---|---|---|---|---|
|
||||
| v2 | 1.582 | 1.280 | pass | 1.30 | n/a |
|
||||
| mx8 (class v3) | 5.394 | 5.267 | pass | 4.67 | 7.56 |
|
||||
| mx8+sh256x27 (class v4, the target) | 6.334 | 6.006 | pass, 3.7 ms of headroom | 5.06 | 8.23 |
|
||||
| dr368 | 5.540 | 5.426 | pass | 5.32 | 8.16 |
|
||||
| dr736 (the known-fail) | 10.290 | 10.042 | FAIL, as it must | 10.51 | 15.49 |
|
||||
|
||||
Cache fill 276 ms on the 9700K core (box 361 ms, M5 Max 175 to 181 ms). The 2019 desktop core sits between the box's
|
||||
two proxies as the arithmetic predicted (1.2x the box one-core cold on v4, 0.77x the half-core); the known-fail
|
||||
fires on it. A 2019 laptop core at 3.5 GHz reads about 15 to 20 percent slower than this desktop part (approximate,
|
||||
clock ratio), so about 7.0 to 7.6 ms on v4, still under 10 ms. Consequences: a 2019-class node verifying class v4
|
||||
spends 0.6 percent of one core at 1 bps and 6 percent at 10 bps; a header flood needs about 160 invalid headers a
|
||||
second to saturate one such core; a pool verifies about 160 shares a second per core; IBD of 108,000 headers is
|
||||
about 11 minutes of one core. The implied ladder ceiling on this core: the shadow costs 0.74 ms per 55,296
|
||||
instructions (v4 minus mx8), so the 4.0 ms of headroom buys about 300,000 more shadow instructions, N about 650,000
|
||||
counted ops at the 1.83 convention (approximate), against 370,000 on the half-core proxy and 1,060,000 on the
|
||||
2.5x rule; the half-core proxy stays the standing pessimistic rule and the ladder's ceiling should be taken from
|
||||
it, not from this desktop part. O-1.14 is CLOSED on a real 2019-class core for the genesis program; the F6 row
|
||||
still owes the 10^5-program worst case before it reads PASS.
|
||||
|
||||
Result (average, verified on the box): class v4 `mx8+sh256x27` runs 4.90 to 5.06 ms per warp cold on one EPYC
|
||||
9454P core (nice 19, taskset), 8.23 ms on the half-core proxy (both SMT siblings busy). Under 10 ms. Status
|
||||
RUNNING: the 10^5-program worst-case search and the O-1.14 laptop relay run are owed before the row reads PASS.
|
||||
What a failure moves: an acceptance-rule bound on verifier cost; the ladder's ceiling set from the measured core.
|
||||
|
||||
### F7. Era-draw bias harness and census (node lane harness, hash lane census)
|
||||
|
||||
Method: the fast-time 3-node network (`infra/fast-time/`) with an adversary withholding or publishing the last blue
|
||||
block before C_era(n) to re-roll the draw; a census of 2^20 era seeds for stride, ROT and weight-perturbation
|
||||
classes with gain over 1.1x; the 64-bit seeding of the day-key stream against the spec's intent. Known-failed shape:
|
||||
a re-roll of the era draw inside the 2 s publish window, or an era class (stride bijection, all-equal ROT, low-weight
|
||||
M) with a chip gain. Gate: no re-roll inside the publish window; no era class with gain over 1.1x at a fraction over
|
||||
2^-20; the draw's input set as the spec states it.
|
||||
|
||||
Result (full record `docs/analysis/attack-pass/f7-era.md`; harness `tools/attack/f7-era/`). Census: 2^20 and 2^24 era
|
||||
seeds through `generator::era_draw` over `V3_ALLOWED` (the chain's path), classified; the planted known-fail/known-pass
|
||||
of the classifier fired and the sound draw raised nothing. No era class with gain over 1.1x at any fraction (the richest
|
||||
is M = 1 at 1.0034x, absent in 2^24; every class over 2^-20 is 1.0000x to 1.0007x); the stride is a bijection on every
|
||||
sample (0 even M), R and pos and the M bits uniform; the op-weight corners (15 to 31 of 75) are 1.0x against the GPU, 0
|
||||
memory effect. The 64-bit day-key seeding is the spec's intent (spec 1.8.4); 2^16 days are all distinct, birthday 2^-33.
|
||||
Harness: the 3-node fast-time network (`reroll.mjs`, ports 29800+, suffix 980) with an adversary holding the last block
|
||||
before the cut; known-pass (`--vdf-ms 0`) fires at 1 of 6 cuts (seed = adversary block), known-fail (`--vdf-ms 5000`)
|
||||
is silent at 0 of 6, both SOUND. The node has no era VDF yet (`seed_below` is a plain block hash, era-layout.md section
|
||||
8), so the harness cannot show the real 2 s-window gate; the era draw's grinding resistance rests on the 1-hour VDF of
|
||||
spec 4.4 (re-roll needs a 1,800x evaluator, spec 4.6 gives 300x; forge needs 20 days of 100% hash). Verdict: census PASS,
|
||||
64-bit seeding PASS, harness INCOMPLETE with the written argument. Logs on igneum-build-1
|
||||
`/srv/builds/igneum-wt-attack/attack-f7/census-2p24.log`, `census-2p20.log`, `reroll-knownpass.log`, `reroll-knownfail.log`.
|
||||
What a failure moves: the draw procedure or the C_era cut rule; a redraw rule for the era stream.
|
||||
|
||||
Sub-row (a) CLOSED, 7 October 2026, 15:1x UK (the era-VDF lane, launched by the coordinator on this row's INCOMPLETE):
|
||||
the era VDF is in the node (fork `era-vdf-node` 394a5902 on `release-0.3.20-node` c4459193, behind
|
||||
`era_vdf_activation_daa`, never on any network until the founder sets it per network; repo master a4eaf766 carries the spec
|
||||
text, the record `docs/analysis/era-vdf-2026-10-07.md` and the harness `tools/era-vdf/reroll.mjs`, which attacks the
|
||||
era cut directly now that the node takes `pow_era_blocks` and `pow_era_lead` from the override file). Against the
|
||||
REAL era cut (era 120 DAA, lead 20 on the fast-time file, three nodes on igneum-build-2) the harness fires with the
|
||||
VDF off (6 of 6 cuts: the adversary's block is the cut block and its hash the seed, known the instant it is built) and
|
||||
is silent with it on (0 of 6 across six cuts: the adversary's 5.4 to 6.6 s evaluation with the node's own code against
|
||||
a 1 s block interval, the honest chain 3 to 10 blocks ahead when it published, three nodes agreeing on every era seed,
|
||||
the record ready at every era start). SOUND both ways. The production delay: 517 s on the fastest prover measured
|
||||
(chiavdf NUDUPL over GMP, 208.8K squarings/s on the same core) at T = 108,000,000 squarings, 259x the 2 s window.
|
||||
Freeze sentence (the era-VDF lane's, carried to the plan's owner): "The era seed E_n is the output of a one-hour
|
||||
verifiable delay (class-group Wesolowski, 1,024-bit prime discriminant, T 108,000,000, scheme byte 0 with the
|
||||
hash-chain fallback as byte 1) over the blue blocks of the day ending at the era's cut block; the attack pass's F7
|
||||
re-roll harness fires against the stand-in and is silent against the delay, so the era draw procedure and the C_era
|
||||
cut rule are frozen with the VDF in the node, behind era_vdf_activation_daa, never until set per network." Open, not
|
||||
a gate of F7: the verify is 22 ms with the group held, against the 10 ms target (once per 180 days per importing
|
||||
node; O-4.6's reducer or GMP behind a feature, 0.3.22). Logs `/srv/builds/igneum-wt-era-vdf/ev-harness-out/
|
||||
reroll-vdf-{on,off}-5.json` on build-2. F7: PASS on all three sub-rows.
|
||||
|
||||
### F8. Uniformity censuses (hash lane, on the box)
|
||||
|
||||
Method: the line-index distribution over 2^28 derivations; distinct lines per hash and per warp on 10^6 nonces of
|
||||
three programs; the cross-hash item histogram of one epoch. Gate: the largest bucket within 6 sigma of uniform; no
|
||||
hot set under 1% of items. Result: RUNNING. What a failure moves: the mask or the fold; packs re-cut.
|
||||
|
||||
### F9. Acceptance edges and header grinding (hash lane; one PC 2 job)
|
||||
|
||||
Method: the 39 edge disagreements reproduced and bounded; a search over 10^6 seeds for programs that pass rule (c)
|
||||
with a hot set under 1%; the header-grinding search cost against its DRAM-locality gain measured on PC 2's RTX 5090
|
||||
(one job through `tools/build-job.mjs`). Known-failed shape: a seed grind that steers a program to a hot cache set
|
||||
for DRAM locality, or an edge where the closed-form stand-in disagrees with the live verifier in the attacker's
|
||||
favour. Gate: zero passing programs with a hot set under 1%; the grinding gain under 1% of rate at any search cost.
|
||||
|
||||
Result: the `accept` path reproduces per-seed verdicts (genesis seed: 1 candidate ACCEPTED, bias max 54, 0
|
||||
saturated). The header-grinding cost-versus-gain measurement needs a 5090. Status BLOCKED on the go decision: use
|
||||
PC 2's 5090 through a relay run job only if PC 2 is online and mining is unaffected, else a rented pod under the
|
||||
standing fleet budget. What a failure moves: the closed-form stand-in replaced by the live verdict at the edges; a
|
||||
locality term in rule (c).
|
||||
|
||||
### F10. Ladder signal monotonicity (node lane)
|
||||
|
||||
Method: the fast-time harness with a weight that steps the ladder down and never up, and an 89% signal; the step
|
||||
rule's monotonicity and its memoisation per seed block. Known-failed shape: a chip owner stepping the ladder down
|
||||
(cheaper N) without the 90% threshold, or a step registered under 90%. Gate: no step without 90% over 7 windows in
|
||||
either direction; a step down needs the same. Result: RUNNING. What a failure moves: the step rule's text in spec 01
|
||||
before the ladder is frozen.
|
||||
|
||||
## Lane (d): the families re-run on class v5 (7 October 2026, evening; the coordinator's word on the founder's order)
|
||||
|
||||
Object: igneum-pow on branch `class-v5` at e4f1f275 (the frozen sub-version 3 017e7037 merged; the v5 chain draw is
|
||||
the amended v4's instruction for instruction, generator 5, every item keyed by the window's state through the leaf
|
||||
XOR before the first mixer; `V5_CLASS` = `mx8+sh256x27+state`), against the first v5 pack
|
||||
`proto-cuda/packs-ca3-v5/v5-dn3-epoch0` (Devnet 3's genesis 4020cb43... as epoch and era seed, day 20,733, program id
|
||||
e5a4ac5978462156, reproduced by the e4f1f275 build on box 2: the pairing). The four harnesses carried onto the
|
||||
class-v5 tree in worktree `igneum-wt-attack-v5` (branch `attack-v5`), each with `--class v5` and, where the dataset
|
||||
enters, `--state <IGSD1>` attaching the leaves through `with_leaves` as the CLI does; F8's traced derivation carries
|
||||
the leaf XOR and validates bit for bit against `derive_items_leaves` and `Epoch::hash_warp` (p1 on the dn3 state at
|
||||
4,096 nonces: 0 mismatches over 16,777,216 items and 64 warps; the flipped-state file mismatches: the known-fail).
|
||||
Both boxes at nice 10 beside the release builds; the binaries run from copies in each run's scratch directory (AP-H2).
|
||||
GitHub answered 403 (account suspended) from 17:2x UK, so this section lands on the box mirror (`build`, master and
|
||||
attack-pass) by the coordinator's exception rule; nothing touches GitHub.
|
||||
|
||||
| Family | Class v5 run | Result | Verdict |
|
||||
|---|---|---|---|
|
||||
| F4 weak-day census | 2^24 chain days from 20,729 under `Shape::for_class(&V5_CLASS)`, box 1, 18:5x to 19:1x UTC | byte-identical to the class v4 census: M2 (DSP-bound) 0 of 2^24 days over 1.1x; M1 (LUT adders) 5,476 days, 3.264e-4, the same bounded tail, worst day 4,819,563 at cost 197 against the median 231; planted weak days fire (mul1all M2 unbounded, mulnaf 1.333x). The day-key draw depends on the mixer shape alone and v5 adds only the state flag, so identity is the expected and the measured result | PASS (v4's reading; AP-F4-1 stays the next-class item) |
|
||||
| F8 hot-set gate | 64 seeds at 2^24, chain path, v5 with the dn3 state, box 2 (64 threads), from 18:47 UTC | pending | pending |
|
||||
| F9 exhaustion count | 10^5 chain-shaped seeds on the v5 chain path with the dn3 state, box 1, ten parallel chunks (the chain draw costs about 2.2 s per candidate through (c''), so 10^6 is about fifty hours) | pending | pending |
|
||||
| F1 shadow redundancy | 10^5 class v5 programs through the string-seed path, box 1 | pending | pending |
|
||||
|
||||
## Operating hazards found by the pass
|
||||
|
||||
AP-H1 (box scratch cleaned by builds; found by F3, 7 October 2026, 10:0x UK). `infra/build-server/remote-run.sh`
|
||||
line 71 runs `git clean -qfd -e target -e 'target-*' ...` on `/srv/builds/<worktree>` before every remote build, so
|
||||
an untracked box scratch directory of one row (a venv, a log dir, a crate's `tools/attack/*/target`) is deleted by
|
||||
the next build from any row. F3 protected its own directory through the box mirror's `.git/info/exclude`; the lane
|
||||
then added `attack-*/`, `target-attack-*/`, `tools/attack/` and `.build-remote.log` to that file at 10:1x UK, after
|
||||
which `git clean -fdn` on the mirror lists nothing (the clean has no `-x`, so the exclude file applies). The class
|
||||
check is owed to the build-server lane: the clean line should spare a lane's declared scratch prefix (`-e 'attack-*'`
|
||||
style, or read a per-worktree exclude list), and a CI check should fail a remote-run.sh whose clean line lacks it.
|
||||
OPEN until that check lands (CLAUDE.md: a rule row closes only with its check).
|
||||
|
||||
AP-H2 (this lane's own, 7 October 2026, 13:3x and 14:5x UK, twice). Two census runs launched from the same crate's
|
||||
`target/release` binary path on the box mirror: a rebuild of the crate at a new commit replaces the binary under a
|
||||
run still in progress, and every chunk the run launches after that executes the new commit's code with the old run's
|
||||
label (the 07a809a7 control's later chunks ran 8bdcbdd8; the ddacfbd3 class check's later chunks ran 017e7037). Both
|
||||
runs were caught by their attempt histograms (attempts 32 and 35 under a cap of 32) and their contaminated chunks
|
||||
discarded. Fix in the lane's launcher: `run-census-chain.sh` copies the binary into the run's own scratch directory
|
||||
before the first chunk and runs from the copy, so a rebuild cannot reach a run in progress; a run's record names the
|
||||
sha256 of the copy. Class check owed: the same rule for every lane's long run (the box's build runner could refuse to
|
||||
replace a binary that a running process has open, or stamp the commit into the run's log at every chunk).
|
||||
|
||||
## Ledger rows
|
||||
|
||||
AP-F1-1 (hash lane; ruling asked). At 10^5 class v4 programs one program (`attack-f1/37341`) compresses by 5.078
|
||||
percent (13 of 256 shadow instructions per pass), 0.078 points over the gate's first clause, on 1 of 100,000; every
|
||||
other program is within 5 percent and none over 10. The saving is the same local shape as on every program (a
|
||||
register written twice from one source with no write between), nothing crosses a pass, and clang -O3 removes the
|
||||
same instructions from the honest kernel (IR counts match the harness on the worst programs), so a chip gains nothing
|
||||
relative to a card: no shortcut. The gate as written counts honest-compiler simplification as compressibility. Two
|
||||
ways to close: re-word gate (1) and row F1 to "compressible beyond the honest compiler's own simplification" (the
|
||||
firms then attack chip-relative compression, which is the question), or a shadow-draw redundancy bound in the next
|
||||
class (reject a shadow with over 12 peephole-removable instructions per pass, rejection about 1e-5; class v4 is on
|
||||
the live vote). Ruling (coordinator, 7 October 2026, 12:3x UK): both. Gate (1) and row F1 re-worded to "no
|
||||
compression of the shadow block beyond the honest compiler's simplification, measured against that compiler on the
|
||||
same program" (sent to the cryptanalysis lane for the plan and the firms' brief), under which the 5.078 percent
|
||||
letter miss at honest-compiler parity is a PASS; and a shadow redundancy bound on the v5 generator's list beside
|
||||
AP-F4-1 and AP-F8-1 (the generator refuses a shadow block whose honest-compiler simplification exceeds a stated
|
||||
fraction; the v5 lane sets the fraction from F1's census), gated by F1's harness on 64 seeds of the v5 stream.
|
||||
The fraction is 3.0 percent (v5 lane, class-v5 45e29cb0; 384 of 100,000 draws redrawn in its census, 3.8e-3, against
|
||||
F1's histogram where the 3.0 to 5.5 percent bins hold 397 of 100,000); the plan's 1.1 sentence carries the number.
|
||||
Status: F1 PASS; AP-F1-1 FIXED-AND-PASSED against v5 once the bound is in the v5 generator and F1's census passes.
|
||||
|
||||
|
||||
AP-F5-1 (algorithm and hash lane, ours; the ladder lane is closed). The k about 0.33 chip-efficiency figure is
|
||||
framed as a measured calibration ("the X9's core", `fud-ledger.md` M32 L172; "measured class", `ladder` branch
|
||||
`docs/design/latency-ladder.md` section 5a). The Antminer X9 was withdrawn before launch and never benchmarked, so
|
||||
k about 0.33 is a claimed datasheet bound, not a measurement. This also puts the merged ledger X34 ("RandomX has a
|
||||
shipping chip") in question. Fix owed, held until the coordinator's research agent confirms the withdrawal and the
|
||||
no-benchmark fact: relabel k about 0.33 as a claimed pessimistic bound from a withdrawn design in `evidence.md` row
|
||||
17, `fud-ledger.md` M32 and the `ladder` branch; reverse X34 if the withdrawal is confirmed; keep 2.1x at k = 1 on
|
||||
the GDDR7 measured anchor as the headline with the k range beside it. Re-gate after the re-cut. Status: FIXED on the docs rows (evidence 17, M32, ladder 5a on branch attack-ladder-5a d3cb17b6; attack-pass
|
||||
rebased on master a3678789 after X36); FIXED-AND-PASSED once the site lane's X34/X36 served rows are confirmed in
|
||||
one voice (no objection received) and the sweep is re-run against the re-cut sentence (the numbers are unchanged, so
|
||||
the re-gate is the identity check and one `model.py --section chip` run against the new wording). Re-gate done 7 October 2026, 09:5x UK: the 5090
|
||||
bench row still reads 5.7x / 4.1x / 3.2x / 2.1x / 1.5x (v3; v4 at k = 0.3 / 0.5 / 1 / 1.5), identity grep 0 hits
|
||||
over 290 export files, the site lane confirmed the served text agrees. AP-F5-1: FIXED-AND-PASSED.
|
||||
|
||||
AP-F8-1 (hash lane; the generator fix is the Counter ASIC lane's on the v4 seam, routed 7 October 2026, 10:3x UK).
|
||||
The class v4 item read map is not uniform. F8 phase D, one program, 2^26 nonces: the top 0.1 percent of items take
|
||||
0.520 percent of reads against 0.115 percent for the uniform control (4.05x); the top 1 percent take 2.49 percent
|
||||
(1.37x); one item (0xca5b92) takes 78,479 reads, 153x the mean; read site 15 feeds 6.37 percent of its reads into
|
||||
that 0.1 percent in all 8 iterations; the excess grows with N as a real skew does. Sized: a chip caching the hot
|
||||
0.1 percent in SRAM serves about 0.5 percent of reads from cache, so the shortcut is under one percent of rate today;
|
||||
an auditor flags a non-uniform read map in a design that claims uniform random reads, and site 15's index derivation
|
||||
is the cause to name. Fix asked: per-site index whitening or a rejected class above a bound. Re-gate: the top
|
||||
0.1 percent within 1.2x of the control over 2^26 nonces on every one of 64 seeds, with F8's harness against the
|
||||
Counter ASIC lane's branch. Phase E (the 64-program census) decides whether it is one program or the class.
|
||||
Framing from the Counter ASIC lane (the generator's owner, 7 October 2026, 10:5x UK): class v4's item map is not
|
||||
designed to be uniform per program. Layer 8 (spec 01 section 1.13.1) gives each load site k_off = below(3), so a
|
||||
site reads the whole dataset, a half or a quarter under the era's stride and interleave; a quarter-window site
|
||||
concentrates 4x on its quarter by design, which is the 4.05x at the top 0.1 percent, and the windows exist so a
|
||||
chip's SRAM mirror must hold the whole dataset every hour (the Counter ASIC 2.0 windows-union census). The right
|
||||
control is therefore the window model from the program's own 16 draws, reported beside the uniform control (what an
|
||||
auditor sees first); the number that must be explained is the single item 0xca5b92 at 153x the mean (window
|
||||
coincidence under the era mapping with a stated tail, or a low-entropy index source at site 15, which would be a
|
||||
fault). The lane reproduces with F8's harness on branch `ca3-v4-uniform`, waits for phase E, re-prices the chip
|
||||
consequence (a 0.1 percent hot-set cache, about 1.7 MB of SRAM, serving 0.5 percent of reads: under one percent of
|
||||
rate) and changes the generator only on a fault beyond the model, since v4 is on the live devnet's vote. F8 was
|
||||
re-briefed to carry both controls and the per-site table. Raised to the coordinator: plan 1.4 gate (4) and row F8
|
||||
say "within 6 sigma of uniform"; if the design is windowed, the gate text must say "uniform within the window model
|
||||
of spec 1.13.1" before the freeze tag, or every reviewer files the windows as a finding on day one.
|
||||
Coordinator's ruling (7 October 2026, 11:0x UK), accepted: the right null is the window model derived from the
|
||||
program's own draws; F8 is re-gated against it, and the finding stays open only for the excess beyond the window
|
||||
model (the 153x item, or a low-entropy source at site 15 if the 64-seed census shows one). No generator change to
|
||||
class v4 is allowed: it is on the live devnet's vote, and a class change before the flip splits the chain. If the
|
||||
census shows a real fault it goes to the coordinator priced; otherwise the record carries the documented null and
|
||||
the hot-set bound (a 0.1 percent cache, about 1.7 MB of SRAM, under one percent of rate) goes into the next class.
|
||||
Gate wording settled (coordinator, 11:2x UK): plan 1.4 gate (4) and row F8 now read "uniform within the window
|
||||
model of spec 1.13.1, layer 8; the excess beyond it within 6 sigma over 64 seeds", carried into the plan's scope
|
||||
text by the cryptanalysis lane so the firms are briefed on the windows before they start.
|
||||
Mechanism (hash lane, branch `ca3-v4-uniform` 095f84a7, `docs/analysis/ca3-v4-uniform.md`, harness
|
||||
`tools/ca3-v4-uniform`, 7 October 2026, 12:3x UK): the windows-union null (a Poisson mixture at 416 / 288 / 736 / 608
|
||||
reads per item by quarter from the program's 16 draws) moves the top 0.1 percent from 0.115 to 0.160 percent, 1.39x,
|
||||
not 4.05x; every per-site row of F8's attribution except site 15 is the window model. The rest is the LOAD SOURCE:
|
||||
site 15 is the load at 63 reading r6, whose last writer is `or` at 61 (r6 = r6 | r4), so the source is all-ones with
|
||||
probability about (3/4)^32 per read; under the era map x = 0xffffffff is item 0xca5b92, the hottest item exactly, and
|
||||
the next seven hottest are the seven one-zero-bit sources whose zero survives the window mask (7 of 7); the measured
|
||||
count fixes the bias at p = 0.7585 per bit. The class: a load whose source's last writer is lossy (or: 0.30 percent
|
||||
of a site's reads on 0.1 percent of values; mul, trailing zeros: 1.07; mulhi: 0.79; an or of an or: about 4.5).
|
||||
Static census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (48.5 percent or, 4.9
|
||||
percent an or chain, 73 percent mul, 64 percent mulhi); predicted S_0.1 median 0.45, 90th 0.88, 99th 5.3, max 9.8
|
||||
percent; p1 / p2 / p3 predicted 0.58 / 0.32 / 4.72 against measured 0.52 / 0.27 / 4.60. The fault sits in the
|
||||
acceptance rule's blind spot: part (a) takes any write as fresh, part (c) counts saturation on final values only.
|
||||
Consequence: the 1.2x-against-window gate fails 96.6 percent of today's programs, so it is withdrawn as a v4 gate and
|
||||
becomes the v5 generator item's gate (draw a load's source from registers whose last writer injects; a dynamic check
|
||||
counting saturated load sources), with F8's phase E as its test. Chip side: the top 0.1 percent of items is 1.07 MB
|
||||
of SRAM (0.53 mm^2, about USD 0.25) serving 0.52 percent of p1's reads and 4.6 percent of p3's, at most 1.005x and
|
||||
1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor is one site repeating its item in all 8 iterations,
|
||||
6.25 percent of reads, 1.067x. That 1.067x is the v4 hot-set bound the record carries. No generator change to v4;
|
||||
the hash lane takes the two flip options priced to main.
|
||||
Ruling (the founder, 7 October 2026, 15:2x UK): option A, the class v4 amendment ships in 0.3.20, the feature node (0.3.19 is the app-only cut on the unchanged 0.3.17 node pin; corrected by the coordinator) (a load's source drawn
|
||||
only from registers whose last writer injects or is a rotate, the v5 rule applied now; a new program stream and
|
||||
seven re-exported packs on branch `ca3-v4-amend`, the hash lane), with limited testing. This lane's part is the proof
|
||||
of the fix: F8's hot-set census at 2^24 nonces on each of 64 seeds of the amended stream, on the box's CPU path as
|
||||
phase D ran, gate: the top 0.1 percent of items within 1.2x of the window model derived from each program's own 16
|
||||
window draws, one number per seed; reported to the hash lane, main and the Counter ASIC lane. The amended stream has
|
||||
no lossy-sourced load by construction, so a seed over 1.2x there is a finding against the model's own tail, not the
|
||||
fault, and the record says which.
|
||||
Second harness (F9 sub-row b, 10^6 seeds, 12:5x UK): the same class from the other side, the per-site address trace:
|
||||
11,696 of 1,000,000 passing programs concentrate 1 percent or more of their reads on a hot set (worst 17.3 percent,
|
||||
seed 842871, an `or`-written load source all-ones in 36 percent of evaluations), so F9-1 merges into AP-F8-1 and
|
||||
F9's harness is the second re-gate of the amendment, run on the amended stream beside F8's 64-seed census.
|
||||
Re-gate interim (7 October 2026, 13:2x to 13:5x UK, box 2): F8's 64-seed census at 2^24 nonces against the amended
|
||||
stream (igneum-pow 8c728ca3, sub-version 1; pairing verified, the harness draws the devnet epoch-0 program as
|
||||
1a4230699a6b9c60) at 30 of 64 seeds shows nine over 1.2x of the window model (p31 29.27x, p11 5.45x, p19 3.32x, p6
|
||||
3.11x, p23 2.04x, p4 1.57x, p10 1.50x, p26 1.30x, p25 1.28x), p6's hottest item predicted from "site 13, r0,
|
||||
all-ones, last writer a load at 12": a load-after-load chain (a hot address yields a fixed dataset word, which is the
|
||||
next load's address), which the source rule admits because a load injects. Rule-level reading, checkable in code:
|
||||
generator.rs line 1326 sets `entropy_kept[dst]` true for a rotate whatever it rotated, so an or-saturated register
|
||||
rotated once is an admitted source and the rotate preserves the saturation. RETRACTION: F9's hot-set census run on
|
||||
box 2 against the 8c728ca3 build (10^6 seeds, 1,871 flagged, worst 9.66 percent) was not a re-gate: the F9 harness
|
||||
draws through `candidate_class` with its own era class, not through `chain_program` where the rule lives, and the
|
||||
amended and the old binary print the identical program for seed igneum-f9/518927; those numbers describe the old
|
||||
stream under a changed evaluation and are withdrawn; the harness is being given a `chain_program` draw mode so it can
|
||||
serve as the second re-gate. The hash lane confirmed the reading (14:0x UK): the amendment's rule is keyed on the
|
||||
era-composed class, so a draw with no era (F9's path) is the old stream, and on the chain path the residual is real:
|
||||
p6's load at 12 had a saturated source itself, read one constant word and left a constant in r0, which the rule
|
||||
counts as injecting; a rotate keeps 0xffffffff, so or-then-rotate-then-load passes too. Both are saturation delivered
|
||||
through a writer that preserves it. Fix shape put to the owner of sub-version 2 (the Counter ASIC lane): dataflow
|
||||
freshness instead of a one-writer look-back (fresh at the start; a load keeps dst fresh only if its source was fresh;
|
||||
add, sub, xor, mad, shfl fresh if either operand was; rotl, rotr only if the operand was; or, mul, mulhi never; a
|
||||
load's source drawn only from fresh registers), with the dynamic (c') check on load sources as the backstop; a stream
|
||||
change, so sub-version 2 with new packs, ids and fingerprints.
|
||||
RE-GATE VERDICT on sub-version 1 (7 October 2026, census ended 12:55:55 UTC, 13:55 UK; box 2; igneum-pow 8c728ca3
|
||||
paired with release-0.3.20-node 8097d600, pairing id 1a4230699a6b9c60 verified; 64 seeds p2 to p65 at 2^24 nonces,
|
||||
chain path, window-model control; log `/srv/builds/igneum-wt-attack-regate/attack-f8-regate/log/`): FAIL the pass
|
||||
line. 53 of 64 seeds under 1.2x of the window model (0.9915x to 1.16x, no predicted source); 11 over:
|
||||
|
||||
| Seed | Over the window model | Over flat | Hottest item, reads of 2^31 | Predicted source |
|
||||
|---|---|---|---|---|
|
||||
| p31 | 29.27x | 31.99x | 0x74e2b8, 5,365,527 | site 4, r4, all-ones, last writer rotl at 3 |
|
||||
| p11 | 5.45x | 6.00x | 0x0eec66, 31,486 | site 1, r7, all-ones, last writer or at 63 (the previous iteration) |
|
||||
| p45 | 4.55x | 6.37x | 0x400000, 5,644 | site 1, r4, zero, last writer mulhi at 59 |
|
||||
| p19 | 3.32x | 3.93x | 0x400000, 28,114 | site 37, r5, zero, last writer load at 32 |
|
||||
| p6 | 3.11x | | 0x3bf40d, 13,792 | site 13, r0, all-ones, last writer load at 12 |
|
||||
| p23 | 2.04x | 2.85x | 0x09dd36, 13,848 | site 16, r7, all-ones, last writer load at 14 |
|
||||
| p4 | 1.57x | 2.11x | 353 reads | none (window tail) |
|
||||
| p34 | 1.51x | 1.87x | 0x400000, 1,547 | site 23, r6, zero, last writer rotr at 12 |
|
||||
| p10 | 1.50x | 1.65x | 353 reads | none (window tail) |
|
||||
| p26 | 1.30x | 1.54x | 0x000000, 7,637 | site 10, r1, zero, last writer rotl at 2 |
|
||||
| p25 | 1.28x | 1.65x | 363 reads | none (window tail) |
|
||||
|
||||
Three residual classes, each a constant (all-ones or zero) delivered to a load through a writer the rule admits:
|
||||
(1) saturation or zero preserved through rotl, rotr, load or mad; (2) zero made by mulhi; (3) the iteration
|
||||
boundary, where the rule's writer state starts fresh at instruction 0 so an or at 63 feeds a load at 1. The
|
||||
sub-version 2 rule (dataflow freshness per register, computed as a fixpoint over the loop, with the dynamic count
|
||||
of saturated load sources per site as the backstop; the hash lane builds it on `ca3-v4-amend`) closes all eleven as
|
||||
far as the sources show. Rate side on sub-version 1: still one item at one site, under 1 percent of rate to a chip
|
||||
caching it, so the 0.3.20 ship is safe on rate; the auditor's flag is what sub-version 2 removes. F9's hot-set
|
||||
harness is retired from the re-gate: its hot-share metric counts the era's designed half and quarter windows as hot
|
||||
buckets (its chain-path run on sub-version 1 flagged 83,162 of 10^6, and its worst seed 826184 has no concentrated
|
||||
source at all, top address counts 18 to 59 of 2,048); F8's census, with the flat control beside the window one, is
|
||||
the single re-gate instrument.
|
||||
Sub-version 2 (07a809a7, the stream identical at 8bdcbdd8 for every seed accepting within 32), the same 64 seeds at
|
||||
2^24, 13:10 to 14:2x UTC: at 39 of 64 seeds, 8 over 1.2x of the window model, worst p23 4.82x. Three are the window
|
||||
model's tail (p4 1.22x, p8 1.38x, p10 1.50x, no predicted source); five are constants the freshness rule cannot see
|
||||
because it tracks lineage, not value: p23 (0x000000, 41,727 reads, zero from xor of a register with itself at
|
||||
instruction 0), p34 1.25x (sub of a register with itself), p15 2.57x (zero through rotl at 0), p18 2.50x and p19
|
||||
3.32x (a load whose address is constant delivers one word to the next load; p19 is byte for byte the sub-version 1
|
||||
program). (c') cannot catch them: 164 of 16,384 per site is about fifty times coarser than the gate (p23's item is
|
||||
0.002 percent of all reads and still 4.8x at the top 0.1 percent). Fix shape sent to the hash lane: forbid
|
||||
self-operands for xor, sub and mad in the draw; a dynamic per-site bound on the most repeated source value (any
|
||||
value) set from the gate; a load's dst fresh only if its source passes it. Rate side unchanged (one item at one
|
||||
site, nothing to a chip); the auditor's uniformity test is what fails.
|
||||
Localised (14:1x to 14:3x UTC): p23's band is ONE site, site 7 = instruction 38 `load src=r6`, in every iteration
|
||||
including iteration 0 (9.5 percent of that position's reads on the top 0.1 percent of items in each of the eight;
|
||||
16,846 hot items at about 900 reads each, 55x the mean; about 15 bits of index entropy), so it is made inside the
|
||||
iteration from the init-word path. The hash lane read the history: 25 `mulhi r6 = hi(r6 * r3)` (dense near zero),
|
||||
31 `or r6 |= r4`, 35 `xor r6 ^= r4`: or then xor with the SAME operand is `r6 & ~r4`, an AND mask keeping about a
|
||||
quarter of the bits of a small value, which the lineage rule counted as injecting because it cannot see the operand
|
||||
cancel; reproduced in the acceptance's own execution once the shadow runs (AP-F8-3): site 7 reads 874,953 distinct
|
||||
word indices over 2^20 evaluations against about 1,046,500 for the other fifteen sites (0.84 of uniform, 2.2 s) and
|
||||
0.55 at 2^24 (35 s). Neither dataset- nor nonce-dependent: a rule reaches it. Sub-version 3's second commit: per
|
||||
site, the distinct word-index count over the sample as a RATIO to the uniform expectation for that site's window,
|
||||
rejected below a threshold set from the clean seeds' spread (expected near 0.95 at 2^20; this lane supplies the
|
||||
spread from the 53 clean sub-version 1 seeds' by-site entropy); the structural alternative (an abstract value class
|
||||
tracking "r6 holds r4's bits") catches this idiom and nothing it does not know. Predictor rule for the record: a
|
||||
load whose source's last two writers share an operand (or/xor, or/sub, xor/or) over a mulhi output.
|
||||
RE-GATE VERDICT on sub-version 2 (final, the last seed at [2026-10-07T14:20:06Z]; 64 seeds at 2^24, chain path, window-model
|
||||
control, box 2; stream 07a809a7 / 8bdcbdd8, pairing id a788661687db4bb3): FAIL. 55 of 64 under 1.2x (0.9915x to
|
||||
1.144x), 9 over:
|
||||
|
||||
| Seed | Over the window model | Hot site (site, instruction) | Share of that site's reads on the top 0.1 percent | Bucket entropy of uniform | Predicted source |
|
||||
|---|---|---|---|---|---|
|
||||
| p23 | 4.82x | 7, 38 | 9.43 percent | 0.974 | or then xor with the same operand over a mulhi (the hash lane's reading) |
|
||||
| p19 | 3.32x | 15, 62 | 6.64 percent | 0.964 | zero through a load (unchanged from sub-version 1) |
|
||||
| p15 | 2.57x | 2, 12 | 4.49 percent | 0.982 | zero through rotl at 0 |
|
||||
| p18 | 2.50x | 6, 30 | 5.55 percent | 0.937 | all-ones through a load |
|
||||
| p56 | 2.01x | 2, 10 | 3.34 percent | 0.994 | unattributed (new over sub-version 1) |
|
||||
| p10 | 1.50x | 8, 28 | 2.04 percent | 0.979 | unattributed (identical to sub-version 1) |
|
||||
| p8 | 1.38x | 14, 51 | 1.42 percent | 0.980 | unattributed |
|
||||
| p34 | 1.25x | 1, 13 | 1.35 percent | 0.997 | one-bit value through sub |
|
||||
| p4 | 1.22x | 1, 8 | 1.45 percent | 0.981 | unattributed (1.57x on sub-version 1) |
|
||||
|
||||
Every failing seed is one low-entropy load site. Clean-seed spread of the per-site bucket entropy (848 site rows of
|
||||
sub-version 1's 53 clean seeds): min 0.9865, p1 0.9961, p5 0.9999, so bucket entropy separates only the strong four;
|
||||
the hash lane's distinct-index ratio at 2^20 (p23 at 0.84) is about six times more sensitive and sets its own
|
||||
threshold from the clean seeds. Verdict lines sent to the Counter ASIC lane, the hash lane, main and the
|
||||
cryptanalysis lane; byte 5 for 0.3.21 stands on this evidence.
|
||||
Sub-version 3 (hash lane): first commit ddacfbd3 (14:20Z; the acceptance executes the shadow block, pinned to
|
||||
verify.rs by an agreement test; class check by this lane: of 598,678 chain-shaped seeds 11,990, 2.0 percent, accept
|
||||
at a different attempt, 0 exhausted, max attempt 32); second commit 017e7037 (the shared-operand rule, or-then-xor,
|
||||
or-then-sub, xor-then-or on one operand is a mask, in the source rule and (a'); and (c''), every load site's distinct
|
||||
word indices over 2^20 evaluations with the shadow executed against the uniform expectation on its window at or above
|
||||
0.98, the last test of the chosen candidate). The threshold's evidence (hash lane, 2^20): the 55 clean seeds' minimum
|
||||
site ratio 0.9960, p1 0.9990, median 1.0000; the strong five p23 0.8361, p18 0.9274, p19 0.9335, p15 0.9432, p56
|
||||
0.9654; floor 0.98 sits 0.015 from each side. At 2^24 the weak four (p34 0.9181, p4 0.9614, p8 0.9630, p10 0.9612)
|
||||
share their value with two clean seeds (p44 0.9612, p52 0.9613), so the 2^24 stage is not taken and p4, p8, p10 and
|
||||
p34 stay the open tail, unattributed. The ratio refuses about 4 percent of candidates that pass every other test
|
||||
(4,099-program census at 017e7037: mean attempts 2.086 against 1.998, max 17, 0 lossy-sourced load sites of 65,584,
|
||||
0 exhaustions; suite 103 of 103; devnet epoch-0 at attempt 1, id a785001687d8688a, pairing verified by this lane).
|
||||
RE-GATE VERDICT on sub-version 3 (017e70376489251e18564c0abce7e466e606c8b3; pairing id a785001687d8688a verified;
|
||||
64 seeds p2 to p65 at 2^24, chain path, window-model control, box 2, 14:51 to 16:00:20 UTC, 7 October 2026): PASS.
|
||||
60 of 64 under 1.2x (0.9915x to 1.144x); the four over are the named open tail, unattributed and chased: p10
|
||||
1.5036x (identical on sub-versions 1, 2 and 3; hottest item 0x4004da, 362 reads), p8 1.3776x (0x837de4, 420), p34
|
||||
1.2505x (0x800010, 541, the one-bit value through sub at 5), p4 1.2167x (0x4000e7, 355); their hottest items carry
|
||||
355 to 541 reads of 2^31 (one to two per 2^22 items above the mean), no chip consequence, and the ratio rule reads
|
||||
them at 0.9927 to 0.9963 at 2^20, inside the clean spread. Every strong seed of sub-versions 1 and 2 is under the
|
||||
line (p23 4.82x to under 1.2x, p19, p15, p18, p56 likewise). Exhaustion: 0 in 10^6 chain-shaped seeds at 8bdcbdd8
|
||||
(the 256 cap and the deterministic last resort unchanged since) and 0 in 24,631 at 017e7037 (20,532 of this lane's,
|
||||
max attempt 29, plus the hash lane's 4,099, max 17), the draw total by construction; the 10^6 on 017e7037 continues
|
||||
on box 2 as a strengthening line (the chain draw now costs about 2.2 s per candidate through (c''), so about two
|
||||
days) and is not a condition. Node consequence, not a gate: about 2 attempts at 2.2 s each per epoch per node, 4 to
|
||||
5 s at one epoch an hour. Log `/srv/builds/igneum-wt-attack-regate/attack-f8-sv3b/log/regate-sv3b-64x2e24.log`.
|
||||
Status: FIXED-AND-PASSED. AP-F8-1 (the lossy load source), AP-F8-2 (the attempt exhaustion) and AP-F8-3 (the
|
||||
shadow-less acceptance) are closed in class v4 sub-version 3 at 017e7037, the frozen generator; sub-versions 1
|
||||
(11 of 64) and 2 (9 of 64) stand in the record as the two failed re-gates.
|
||||
|
||||
AP-F4-1 (hash lane; the next-class rule is the Counter ASIC lane's seam, routed 7 October 2026, 11:4x UK). A bound
|
||||
on the day-key draw, not a weak class: on the M1 metric (every multiply in LUT adders, adders per mixer application
|
||||
against the census median 231) 5,476 of 2^24 days (3.26e-4) and 87,426 of 2^28 (3.26e-4) gain over 1.1x, the tail
|
||||
of a sum the exact convolution predicts to 0.6 percent; on M2 (DSP-bound) 0 days in 2^28, which is the metric the
|
||||
weak-class gate reads against (LUT multiplies are 72 percent of M1's cost and the slower design). Worst day in 2^24:
|
||||
chain day 4,819,563 (NAF sum 149, cost 197, 1.173x); worst in the public calendar: chain day 29,337 (23.6 years in,
|
||||
NAF sum 158, cost 206, 1.121x, M2 1.000x), reproduced through `igneum-pow export` (memhard.h equal to the harness).
|
||||
Priced: at most 12.1 percent more rate on that day for a per-day LUT-recompute FPGA (reads and shadow untouched),
|
||||
0 for a stored-dataset FPGA or any chip, 12 days a century at or over 1.1x (0.004 percent of a century's hashes),
|
||||
one place-and-route a day under USD 3 compiled ahead on the public calendar. Remedy for the next class, class v4
|
||||
untouched: reject a MUL block with NAF sum under 163 (M1 cost under 211) and redraw from the next stream values,
|
||||
plus NAF weight at least 4 per word and at least 4 distinct ROT amounts; rejection 6.1e-4 per day; first calendar
|
||||
redraw day 22,633; no pack changes. Landed (Counter ASIC lane, 7 October 2026, 11:5x UK): the rule is on the class v5 lane's bound list
|
||||
(`docs/design/class-v5-stored-state.md` section 11) with F4's harness as its gate, re-gated by this lane against the
|
||||
v5 branch once its `accept.rs` carries it. The brief's rank 3 (funding.md B2, the untested all-equal ROT draw of
|
||||
MEMHARD.md) now reads "a bounded tail, measured", with the F4 record as the source.
|
||||
Status: F4 PASS against v4; AP-F4-1 FIXED-AND-PASSED against v5 once the lane's accept.rs carries the rule and the
|
||||
census passes against it.
|
||||
|
||||
AP-F8-2 (hash lane; found 7 October 2026, 14:3x UK, on class v4 sub-version 2 at 07a809a7). A chain-shaped epoch
|
||||
seed can exhaust all 32 draw attempts under the new rule (a') and the generator treats exhaustion as a consensus fault
|
||||
(panic, generator.rs line 1438): seed `igneum-f9/331672` through `Epoch::chain_program` with an era, "32 consecutive
|
||||
candidates rejected, last: (a') load at 16 reads r6, not fresh by dataflow in the loop's steady state". One in the
|
||||
first 331,672 chain-shaped seeds (300,000 drew clean), so a rate of order 10^-6 to 10^-5 per epoch seed; the 10^6-seed
|
||||
measurement with the attempts distribution runs on box 2 (F9's chain path, the panic caught and counted). Meaning:
|
||||
an exhausted epoch seed is an epoch no node can draw a program for, a liveness halt, and the seeds are VDF outputs
|
||||
nobody can steer around it; at one epoch an hour the bracketed rate is one halt per 11 to 40 years, which the firms
|
||||
would compute from the rule as written. Sub-version 1: 0 exhausted in 10^6 chain-shaped seeds. Cause: the draw's
|
||||
no-eligible fallback picks a register the (a') fixpoint then rejects, and when it fires on several loads of one
|
||||
candidate the attempts compound. Fix (the hash lane's call): the draw enforces the freshness fixpoint itself so (a')
|
||||
never fires, or MAX_ATTEMPTS is sized to the measured rejection rate with the exhaustion probability in the spec.
|
||||
Repair (hash lane, `ca3-v4-amend` 8bdcbdd8, 13:31 UTC; main's ruling: the draw must be total and no consensus path
|
||||
may panic): the attempt cap of the class v4 shape is 256 (MAX_ATTEMPTS_V4; v2 and v3 keep 32), after which the seed
|
||||
takes a deterministic last-resort program (the attempt-256 candidate with every or, mul and mulhi rewritten to xor,
|
||||
accepted as drawn); the stream is unchanged for every seed that accepts within the bound. Measured at 8bdcbdd8
|
||||
through the chain path (F9's census, box 2): 0 exhausted and 0 panics in 650,000 chain-shaped seeds (the 10^6 to
|
||||
follow), max attempt 35, no seed at the last resort, seeds past attempt 31 about 3.2e-6 (5 in 1.55 million draws,
|
||||
inside the (2/3)^32 = 2.3e-6 estimate), per-attempt rejection 0.67 (attempt histogram 232,235 / 155,322 / 103,509 /
|
||||
68,858 / ...), mean about 2 attempts per seed; seed 331672 accepts at attempt 32. The 07a809a7 control's clean
|
||||
evidence is one exhaustion in 331,672 seeds (3e-6); its later chunks were contaminated by the 8bdcbdd8 rebuild on
|
||||
the same binary path and are not used.
|
||||
Final (14:03:53 UTC, 10^6 chain-shaped seeds at 8bdcbdd8 through F9's chain path): 0 exhausted, 0 panics, 4 seeds
|
||||
past attempt 31 (three at 32, one at 35; 4e-6, inside the (2/3)^32 estimate), max attempt 35, no seed at the last
|
||||
resort; attempt histogram 331,529 / 222,065 / 147,864 / 98,600 / 66,397 / 44,105 / ... / 1 at 31 / 3 at 32 / 1 at 35,
|
||||
a per-attempt rejection of 0.67 and a mean of 2.0 attempts per seed. The second run (meant as the 07a809a7 control)
|
||||
ran the same binary after the rebuild on the shared path and reproduces these figures exactly; the clean 07a809a7
|
||||
evidence is the first run's 331,672 seeds with one exhaustion.
|
||||
Status: FIXED-AND-PASSED on the exhaustion half (AP-F8-2) at 8bdcbdd8; the hot-set gate on the same commit is the
|
||||
open half of sub-version 2 (AP-F8-1).
|
||||
|
||||
AP-F8-3 (hash lane, found by it while preparing sub-version 3's dynamic bounds, 7 October 2026, 14:1x UTC; the root
|
||||
of AP-F8-1's residual classes). `accept.rs` never runs the latency-shadow block: `run_unit` executes the 64 base
|
||||
instructions per iteration and nothing after instruction 63, while `verify.rs` and every kernel run the shadow 27
|
||||
times at the end of each iteration. So the acceptance rule has judged every class v4 program (the 6 October stream,
|
||||
sub-versions 1 and 2) on a shadow-less execution, and the forced equalities and constants of p23, p15, p18 and p19
|
||||
are made by the shadow block's lossy pairs (an or pair on two registers, a mulhi zero, a rotate of either), which the
|
||||
acceptance never executed; the base-program writers named by the predictor ("xor at 0", "load at 12") were
|
||||
innocent, the shadow before them was not. Checked by the hash lane: p23 at attempt 4 passes an 8-repeat bound at
|
||||
16,384 evaluations and a 2^19.5 distinct-index floor at 2^20 in the acceptance's own run, because there its registers
|
||||
are uniform. Consequences: every acceptance-based number in this pass shares the blind spot (F9 sub-row (a) compared
|
||||
two stand-ins of the same shadow-less rule, consistent with each other and both incomplete; F8's "acc addr" and
|
||||
"acc sat" columns likewise), which is why the harness-side censuses, which run the real hash, found what the rule
|
||||
could not. Fix (sub-version 3, the hash lane): `run_unit` executes the shadow block as the hash does (reps times
|
||||
with the iteration's sel), then the per-site bounds (B: 8 repeats over the 16,384; A: the 2^19.5 distinct-index floor
|
||||
over 2^20 on the chosen candidate), the lineage rule, the 256 cap and the last resort unchanged; the known-failed
|
||||
test (p23, p15, p18 through the dynamic check with the shadow executed) runs on box 2 before the string comes. This
|
||||
lane re-gates sub-version 3 with the 64-seed census and the chain-path exhaustion count; the class check owed with
|
||||
the fix: a test that the acceptance's execution and the verifier's agree on the register state at the end of every
|
||||
iteration for one program, so the two paths can never diverge again.
|
||||
Status: FINDING-OPEN; closes with sub-version 3's re-gate.
|
||||
|
||||
Any further finding is logged here and in `docs/fud-ledger.md` with its owning lane (hash and algorithm: fixed in
|
||||
`igneum-pow` behind a test and re-gated; node: the node lane, relay agent) before the row is marked FIXED-AND-PASSED.
|
||||
278
docs/analysis/attack-pass/f1-shadow.md
Normal file
278
docs/analysis/attack-pass/f1-shadow.md
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
# Attack pass F1: shadow block compressibility and shortcut search
|
||||
|
||||
Row F1 of `docs/plans/cryptanalysis.md` section 4.2, fed into `docs/analysis/attack-pass-2026-10.md`.
|
||||
Run 7 October 2026, 09:15 to 11:1x UK, by the attack-pass F1 sub-agent on igneum-build-1. Times to humans UK;
|
||||
log lines UTC. Every number below cites its log under `/srv/builds/igneum-wt-attack/target-attack-f1/` on the
|
||||
box (copies of the summaries, firings and explains in `tools/attack/f1-shadow/results/`).
|
||||
|
||||
## 0. One line
|
||||
|
||||
PASS on substance at 10^4 and 10^5 programs, with one letter-of-gate miss at 10^5 (AP-F1-1): the best compressed
|
||||
shadow block is 6,912 to 6,588 instructions per iteration on the worst of 10^4 (4.69 percent, seed
|
||||
`attack-f1/8556`) and 6,912 to 6,561 on the worst of 10^5 (5.078 percent, seed `attack-f1/37341`, the only program
|
||||
over 5 percent in 100,000), mean 0.62 percent, none over 10 percent; nothing folds or dedupes across the 27 passes (the saving per pass is the same in every pass, 12 x 27
|
||||
= 324); the whole saving is local peephole algebra (a register xored, added or rotated twice with the same source
|
||||
and no write between) that clang -O3 removes from the same block too, so the honest GPU's compiled kernel already
|
||||
pays the reduced count and a chip gains nothing relative. Verified: 0 mismatches in 10^4 + 10^5 differential tests
|
||||
and 10^4 + 10^5 verifier cross-checks, [[Z3]] z3 window proofs with 0 counterexamples.
|
||||
|
||||
## 1. Target
|
||||
|
||||
| Item | Value | Source |
|
||||
|---|---|---|
|
||||
| Commit under attack | `924288d1` (branch `attack-pass`; the box builds ran at the branch's later heads `11b375a0` and `b2a411d1`, which differ only in other rows' files) | `git log` |
|
||||
| Program class | `--program-class v4`, generator 4, `V4_CLASS` = `mx8+sh256x27` | `igneum-pow/src/generator.rs` lines 802 to 807 |
|
||||
| Shadow block | `ShadowClass { instrs: 256, reps: 27 }`: 256 ALU instructions drawn from the program stream after the 64 base instructions, run 27 times after instruction 63 of every iteration with the iteration's `sel` | `generator.rs` lines 355 to 376 and 1257 to 1290; `verify.rs` lines 383 to 388 |
|
||||
| Shadow instructions per hash | 8 x 256 x 27 = 55,296 | `ShadowClass::instrs_per_hash` |
|
||||
| Shadow op families and weights (of 75) | add 12, xor 10, mul 8, mad 8, shfl 8, rotl 7, sub 6, mulhi 6, rotr 6, or 4 | `NONLOAD_WEIGHTS`, `generator.rs` line 1099 |
|
||||
| Op semantics | every op is read-modify-write on `dst`: add `dst + src + select(sel bit, imm2, imm)`, sub, mul, mulhi, xor, or, rotl by an immediate, rotr by `src & 31`, mad `src x src2 + dst`, shfl `dst ^= src[lane ^ mask]` | `verify.rs` `step`, lines 403 to 486 |
|
||||
| State the block runs on | the 8 lane registers as instruction 63 left them (the iteration's 16 loads XORed in); `sel` = r0 at the iteration's start; pass k's output is pass k + 1's input; all 8 registers feed the fold | `verify.rs` lines 379 to 395 |
|
||||
|
||||
Seeds: the string seeds `attack-f1/<i>`, each through `generate_from_seed_bytes_program_class(seed, seed.as_bytes(),
|
||||
ProgramClass::V4, None)` (the acceptance rule's redraw included). Attempts over the 10^4: 9,497 at attempt 0, 472 at
|
||||
1, 30 at 2, 1 at 3 (`results/f1-attempts.txt`), the 5.0 percent rejection rate of spec 1.4.6.
|
||||
|
||||
## 2. What N counts (decided here, both reported)
|
||||
|
||||
| Unit | Per iteration | Per hash | Where it is used |
|
||||
|---|---|---|---|
|
||||
| A: shadow instructions | 6,912 | 55,296 | the row's known-failed shape ("fewer than 55,296 shadow instructions per hash"); `shadow_instrs_per_hash`; the kernel text |
|
||||
| B: counted ops, the 1.83 convention (add 5, rotr 2, shfl 2, the rest 1; 137 / 75 per instruction) | about 12,630 at the weights (13,338 on seed 0) | about 101,000 (the ladder's 102,100 rung is this plus the base program's 930) | the ladder rungs, the 5090's 11 pJ per counted op, `E = memory + N x 11 pJ x k` (`latency-shadow-2026-10-06.md` section 6, `algorithm.md` 5.3) |
|
||||
| C: chip datapath ops | about 6,270 (6,129 on seed 0) | about 50,100 | this file only: fixed rotates are wiring (0), the add's per-iteration constant hoisted out of the 27 passes |
|
||||
|
||||
Decision: the gate is applied in unit A. (1) The row's own failed shape is written in instructions. (2) Unit B's
|
||||
extra 0.83 op per instruction is the add's select logic (shift, and, select: 3 of its 5 counted ops) and the
|
||||
rotate's funnel shift, the honest GPU's cost of the same instruction, not work a compressor removes. (3) The chip
|
||||
model's `k` floor is derived per instruction (`algorithm.md` 5.3: 0.221 pJ per op at the weights add 32, mul 22,
|
||||
rot 13, shfl 8 of 75), so unit B's gap is already inside `k`. Unit B rides along as the naive tally; unit C is
|
||||
reported for the chip question. The same percentage applies to unit B on every program (the saved instructions'
|
||||
counted ops scale with the mix), so the gate reads the same in both units.
|
||||
|
||||
Unit note for the algorithm lane (AP-F1-1, below): the `k = 0.3` floor divides a per-instruction energy by a
|
||||
per-counted-op energy.
|
||||
|
||||
## 3. Method
|
||||
|
||||
The 27 passes are unrolled symbolically over the 8 registers at the iteration's start (symbolic inputs) and `sel`
|
||||
(symbolic per-iteration constants). Every register value after every instruction is a hash-consed node in a normal
|
||||
form that captures the algebra a chip could exploit:
|
||||
|
||||
| Normal form | Captures | Instructions |
|
||||
|---|---|---|
|
||||
| `Sum { (node, coeff) }` mod 2^32, constants folded | additive chains, add-then-sub cancellation, constant folding across adds, `2a` as one term | add, sub, mad |
|
||||
| `Xor { (base, rot, lane-mask) }` over GF(2) | linear sub-blocks: xor chains, fixed rotates distributed over xor, shuffle masks composed by xor, cancellation of equal atoms, rotl-of-rotl merged | xor, rotl, shfl |
|
||||
| `Or { nodes }` | idempotence and reassociation | or |
|
||||
| `RotrVar { x, s, k }` | variable rotates by the same amount register composed into one | rotr |
|
||||
| `Mul { a, b }` with `Lo` and `Hi` views | one 64-bit product per operand pair shared by mul, mulhi and mad | mul, mulhi, mad |
|
||||
|
||||
A node equal to an existing node costs nothing (identity, cancellation, idempotence, any dedupe across the 27
|
||||
passes). Every other needed node is realised the cheaper of two ways: from its normal form (option a: its atoms and
|
||||
the ops between them, rotated and permuted atoms materialised once and shared) or by its original instruction
|
||||
applied to its predecessor (option b: one instruction, as the kernel runs it). The realised count therefore never
|
||||
exceeds the naive count and takes every local shortcut the rules know; a greedy choice is iterated to a fixpoint and
|
||||
compared with the all-(b) baseline. Reachability runs backwards from the 8 output registers of pass 27, so a value
|
||||
written and never read is not counted. The count is the best realisation these rules find, not a proven minimum
|
||||
(the structural reason it is close to the minimum is section 6: every op reads its own `dst`, so there is no dead
|
||||
code, and every saving is a local identity a compiler also finds).
|
||||
|
||||
Soundness, three ways: (1) every program's normal-form DAG is evaluated concretely on random 32-lane states and
|
||||
compared with the block run instruction by instruction with the verifier's `step` semantics; (2) with the base
|
||||
program emptied, the crate's own `hash_warp` (the verifier) runs the same block for 8 iterations on the real init
|
||||
words and its 32 hashes are compared with the DAG's; (3) z3 proves window equivalence (the straight-line window
|
||||
against the DAG's normal forms, 32 lanes when a shuffle is present) from the harness's JSON export.
|
||||
|
||||
Known-failed shape: a shadow that constant-folds or dedupes across its 27 identical passes so a chip pays fewer than
|
||||
55,296 shadow instructions per hash.
|
||||
|
||||
## 4. Harness
|
||||
|
||||
| Item | Path |
|
||||
|---|---|
|
||||
| Crate | `tools/attack/f1-shadow/` (`Cargo.toml` with `igneum-pow = { path = "../../../igneum-pow" }` and an empty `[workspace]`) |
|
||||
| Source | `tools/attack/f1-shadow/src/main.rs`: `census`, `one`, `plant`, `explain`, `windows`, `emit-c` |
|
||||
| z3 proof script | `tools/attack/f1-shadow/z3check.py` |
|
||||
| Results copied to the tree | `tools/attack/f1-shadow/results/` (summaries, firings, top 50, explains, proxy table) |
|
||||
| Build line (from the crate directory on the Mac) | `IGNEUM_AGENT=attack-f1 bash /Users/joshm/Projects/igneum/tools/build-remote.sh --artefacts "target/release/attack-f1" --out <scratchpad>/attack-f1 -- build --release` (four builds: 09:16, 09:28, 09:37 and 10:30 UK; the last binary sha256 `2585308d...1964`) |
|
||||
| Binary on the box | `/srv/builds/igneum-wt-attack/tools/attack/f1-shadow/target/release/attack-f1`, copied to `/srv/builds/igneum-wt-attack/target-attack-f1/bin/attack-f1` |
|
||||
| Run lines (box, from `target-attack-f1/`) | `bin/census.sh` (10^4, `flock -s` on the measure file, `nice -n 10 taskset -c 0-5,48-53`, 12 threads, 98.5 s); `bin/census100k.sh` (10^5, one chunk under 30 min); `bin/z3sample.sh` (windows of 16 at stride 8 over two passes, lock held per seed); `./bin/attack-f1 plant --seed attack-f1/0`; `./bin/attack-f1 explain --seed attack-f1/8556` |
|
||||
| Box logs | `logs/plant-3.log`, `logs/census-2.log` (10^4, corrected harness), `logs/census100k-1.log`, `logs/z3sample-2.log`, `logs/z3-smoke-0.log`, `logs/z3-whole-0-r1.log`; outputs `out/census2/`, `out/census100k/`, `out/z3/`, `out/explain2-*.txt`, `out/pass-*.c` and `.ll` |
|
||||
| Box scratch | `/srv/builds/igneum-wt-attack/target-attack-f1/` (logs, out, bin, the z3 venv). Named `target-attack-f1` and not `attack-f1` because `remote-run.sh` line 71 runs `git clean -fd -e target -e 'target-*'` before every sibling build (hazard AP-H1 in the pass record); the first `attack-f1/` scratch directory was deleted by a sibling build within minutes of its creation |
|
||||
| z3 | 5.1.0 in `target-attack-f1/venv` (pip bootstrapped from `bootstrap.pypa.io/get-pip.py`; the box's python has no `ensurepip`) |
|
||||
|
||||
A harness defect found and fixed during the pass (logged for the trust story): the first 10^4 census (`logs/census-1.log`,
|
||||
10:31 UK) read max 5.86 percent on seed `attack-f1/8948` and 2 programs over 5 percent. The `explain` listing showed
|
||||
rotated-atom nodes (interned after their consumer during realisation, so carrying a higher id) marked needed but
|
||||
skipped by the descending sweep, so their cost was dropped. Fixed in build 4 (a work stack processes a child with a
|
||||
higher id as soon as it is needed); seed 8948 then reads 1.17 percent (253 of 256 per pass) and the census below is
|
||||
the corrected one. The firings were rerun on the fixed binary.
|
||||
|
||||
## 5. Why nothing is invariant across the 27 passes (read from the code)
|
||||
|
||||
Pass k + 1 reads the 8 registers pass k wrote, and pass 1 reads the registers instruction 63 left (which carry the
|
||||
iteration's 16 loaded words). The only per-iteration invariant inside the block is the add's immediate select
|
||||
(`sel` is fixed for the iteration), a 32-bit lane constant per add instruction: a chip computes it once per iteration
|
||||
instead of 27 times, the unit-B-to-unit-C gap of section 2 and not a reduction in instructions. Every op reads its
|
||||
own `dst`, so no instruction's result is dead: the next write of that register reads it, and the fold reads all 8 at
|
||||
the end. A pair of registers can only become equal through `or` (`or r1, r2; or r2, r1` leaves both as `r1 | r2`),
|
||||
after which `sub r1, r2` is a constant; the harness folds that case (a constant node costs nothing) and it did not
|
||||
arise in 10^4 programs (`consts` per program = the add instructions' selects only). Measured, not assumed: the
|
||||
per-pass saving on the worst program is 12 instructions and the 27-pass saving is 324 = 12 x 27 (`one --reps 1`
|
||||
against `one --reps 27`, `logs/plant-3.log` and section 7), so no dedupe crosses a pass boundary.
|
||||
|
||||
## 6. Firings (`logs/plant-3.log`, corrected binary, 10:31 UK)
|
||||
|
||||
| Case | Block | Instructions saved | Differential test | Verifier cross-check | Expected | Fired as expected |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Known pass | the real block of seed `attack-f1/0` | 0.014 percent (1 of 6,912) | ok (64 states) | ok (32 hashes) | about 0 to 2 percent | yes |
|
||||
| Known fail | the same block with slots 0 to 64 overwritten by 10 xor pairs, 5 rotl triples, 5 add/sub pairs, 5 or pairs, 5 shfl pairs (50 of 256 removable) | 19.94 percent | ok | ok | about 19.5 percent plus the block's own | yes |
|
||||
| Must not fire | the same patterns with the source register rotated between the two halves (no pair cancels) | 0.78 percent | ok | ok | about the block's own | yes |
|
||||
| Information | the same patterns with a read of `dst` between the halves | 11.73 percent | ok | | the second half restores a value a chip still holds, a real zero-op shortcut | noted |
|
||||
| Soundness | the real block with the rotl composition rule deliberately wrong (`rot + n + 1`) | | MISMATCH | | MISMATCH | yes |
|
||||
| Dead code | the real block with its last instruction replaced by `rotl r7`, one pass, fold over 7 registers against 8 | cost 254 against 255; unneeded derived nodes 5 against 4 | ok | | one instruction dead only when r7 is not folded | yes |
|
||||
|
||||
The dead-code firing shows the reachability pass works; in the real class it never fires because every op reads its
|
||||
own `dst` (section 5).
|
||||
|
||||
## 7. Census
|
||||
|
||||
### 7.1 10^4 programs (`logs/census-2.log`, `out/census2/census.csv`, 10:31 to 10:33 UK, 98.5 s on 12 threads)
|
||||
|
||||
| Quantity | Value |
|
||||
|---|---|
|
||||
| Programs | 10,000 (`attack-f1/0` to `attack-f1/9999`) |
|
||||
| Naive per iteration | 6,912 instructions (55,296 per hash); counted ops 13,338 on seed 0 (about 12,630 at the weights); chip view 6,129 on seed 0 |
|
||||
| Instructions saved, min / mean / max | 0.000 / 0.627 / 4.688 percent |
|
||||
| Worst program | `attack-f1/8556` (attempt 1): 6,912 to 6,588 per iteration, 55,296 to 52,704 per hash |
|
||||
| Programs over 5 percent / over 10 percent | 0 / 0 |
|
||||
| Chip-view ops saved beyond free rotates and hoisted constants, mean / max | 0.524 / 4.348 percent |
|
||||
| Differential mismatches | 0 of 10,000 (8 random 32-lane states each) |
|
||||
| Verifier mismatches (`hash_warp` on the block, 8 iterations, 32 hashes) | 0 of 10,000 |
|
||||
| Rewrites over all programs and passes | identity 327,111; xor-cancel 307,665; sum-cancel 1,086,616; or-idem 31,245; rotl-merge 442,292; rotr-merge 31,862; product-shared 232,157 (events, most of them cost-neutral: a merged rotate whose intermediate is still read, a shared product inside a fused mad) |
|
||||
| Histogram of instructions saved, 0.5 percent bins from 0 | 5,445; 2,119; 1,198; 993; 147; 58; 28; 8; 2; 2; 0; 0 (the last bin is 5.5 percent and over) |
|
||||
|
||||
Top of the tail (`results/f1-top50-corrected.csv`): 8556 and 4259 at 4.69 percent (12 of 256 per pass), 1206 at
|
||||
4.30, 3491 at 4.28, 6812 at 3.92, 8087 at 3.91, 7292 at 3.89, then 3.52 and under.
|
||||
|
||||
### 7.2 10^5 programs (`logs/census100k-1.log`, `out/census100k/census.csv`)
|
||||
|
||||
| Quantity | Value |
|
||||
|---|---|
|
||||
| Programs | 100,000 (`attack-f1/0` to `attack-f1/99999`), 12 threads, 1,073.7 s, finished 10:51 UK |
|
||||
| Instructions saved, min / mean / max | 0.000 / 0.617 / 5.078 percent |
|
||||
| Worst program | `attack-f1/37341` (attempt 0): 6,912 to 6,561 per iteration (13 of 256 per pass), 55,296 to 52,488 per hash |
|
||||
| Programs over 5 percent / over 10 percent | 1 / 0 |
|
||||
| Next worst | 71442 at 4.70, then 95060, 8556, 77816 at 4.69 |
|
||||
| Chip-view ops saved beyond free rotates and hoisted constants, mean / max | 0.513 / 5.079 percent |
|
||||
| Differential mismatches | 0 of 100,000 (4 random states each) |
|
||||
| Verifier mismatches | 0 of 100,000 |
|
||||
| Histogram of instructions saved, 0.5 percent bins from 0 | 55,595; 20,442; 11,790; 9,729; 1,447; 613; 256; 103; 17; 7; 1; 0 |
|
||||
|
||||
The harness's own gate line at 10^5 reads FAIL by the letter (one program over 5 percent by 0.078 points); the
|
||||
substance of section 7.3 and 7.4 holds for it as for the others: the 13 instructions are the same local shape
|
||||
(a register written twice from the same source with no write between), nothing crosses a pass, and the compiler
|
||||
removes the same instructions from the honest kernel. Recorded as AP-F1-1 in the pass record for a ruling on the
|
||||
gate's wording versus a shadow-draw redundancy bound in the next class (class v4 is on the live vote).
|
||||
|
||||
### 7.3 What the saving is (`out/explain2-8556.txt`, `results/explain2-8556.txt`)
|
||||
|
||||
The 12 instructions per pass on the worst program, listed by the harness, are all of one shape: a register
|
||||
written twice with the same source and nothing written between, so the second write undoes or merges with the first.
|
||||
Lines 53 and 57 `xor r4, r0` twice (r4 and r0 untouched between: the second restores r4 to the node it held, cost
|
||||
0); lines 64 and 67 `xor r6, r4` twice; lines 130 and 132 `xor r5, r0` twice; lines 189 and 191 `xor r0, r2` twice;
|
||||
lines 137 and 139 an add and a sub whose terms cancel; lines 88 and 241 a rotl absorbed into the next rotate of the
|
||||
same register; line 1 an add whose sum is realised directly from its atoms. Nothing spans a pass boundary and
|
||||
nothing involves the constants.
|
||||
|
||||
### 7.4 A production compiler finds the same shortcuts (`out/pass-*.c`, `out/pass-*-O3.ll`)
|
||||
|
||||
`emit-c` writes one pass as scalar C (shfl as a pure external function so the compiler may cancel a repeated
|
||||
shuffle but cannot see through it); clang 18 `-O3 -emit-llvm` on the box, counting the IR's `xor i32`, `sub i32`
|
||||
and `or i32` against the block's xor-plus-shfl, sub and or counts:
|
||||
|
||||
| Seed | Harness per pass | Block xor+shfl | IR xor | Block sub | IR sub | Block or | IR or |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 8556 (worst) | 256 to 244 | 73 | 65 | 21 | 20 | 10 | 10 |
|
||||
| 4259 | 256 to 244 | 69 | 59 | 16 | 16 | 13 | 12 |
|
||||
| 1206 | 256 to 245 | 69 | 61 | 29 | 27 | 16 | 15 |
|
||||
| 8948 | 256 to 253 | 58 | 55 | 18 | 16 | 10 | 10 |
|
||||
| 2 | 256 to 256 | 56 | 56 | 23 | 22 | 17 | 17 |
|
||||
| 8 | 256 to 256 | 65 | 65 | 16 | 15 | 10 | 10 |
|
||||
| 16 | 256 to 256 | 66 | 66 | 11 | 11 | 9 | 9 |
|
||||
|
||||
On the three programs the harness calls incompressible the compiler keeps every xor; on the worst it drops 8 of
|
||||
73. (The IR add count is not comparable: the add's select lowers to two adds plus a select.) The miner kernels are
|
||||
compiled per epoch by NVRTC, Metal and the OpenCL driver, all LLVM-based with the same instcombine peepholes, so the
|
||||
honest card already runs the reduced block; the 5090's 11 pJ per counted op and every ladder rung were measured on
|
||||
such compiled kernels.
|
||||
|
||||
## 8. z3 window proofs (`logs/z3sample-2.log`, `out/z3/win-*.log`)
|
||||
|
||||
Windows of 16 instructions at stride 8 over two passes (63 windows per program, the pass boundary included), the
|
||||
straight-line window against the DAG's normal forms on all 32 lanes when a shuffle is present, 60 s per window.
|
||||
|
||||
[[Z3]]
|
||||
|
||||
A window reads `unknown` when z3 does not finish inside the timeout (bit-blasted chains of 32-bit multiplies); it is
|
||||
not a counterexample and those windows are covered by the differential tests. One whole pass (256 instructions, 32
|
||||
lanes, 367 nodes) did not finish in 786 s (`logs/z3-whole-0-r1.log`), so windows are the proof unit. The smoke run
|
||||
on seed 0 (31 single-pass windows) proved every window in under 0.1 s each (`logs/z3-smoke-0.log`).
|
||||
|
||||
## 9. Gate and verdict
|
||||
|
||||
Gate (row F1, the same as 1.4 test 1): the best compressed block within 5 percent of N on every program; no program
|
||||
over 10 percent compressible; the 27 repetitions not evaluable in fewer than 27x the single-pass cost.
|
||||
|
||||
| Test | Result | Log |
|
||||
|---|---|---|
|
||||
| Every program within 5 percent of N (unit A, 10^4) | yes: worst 4.69 percent | `logs/census-2.log` |
|
||||
| No program over 10 percent | yes: 0 | `logs/census-2.log` |
|
||||
| 27 passes in fewer than 27x one pass | no: the saving per pass is identical in every pass (12 x 27 = 324 on the worst) | `logs/plant-3.log`, section 5 |
|
||||
| Dead registers across the passes | none (every op reads `dst`; reachability pass verified by its firing) | section 6 |
|
||||
| Constant folding across the passes | the add's select only (a per-iteration constant, hoistable by anyone; unit C) | section 2 |
|
||||
| Common subexpressions across the passes | none (no node of pass k equals a node of pass k + 1; every identity is inside a pass) | section 7.3 |
|
||||
| Linear sub-blocks | xor, rotl and shfl chains in GF(2) normal form: the only collapses are the local pairs above | section 3 |
|
||||
| Harness trusted | known pass and known fail fired, must-not-fire held, soundness firing fired | section 6 |
|
||||
| 10^5 programs | [[100K-GATE]] | `logs/census100k-1.log` |
|
||||
|
||||
Verdict: PASS. Reservations, stated: (1) the worst of 10^4 sits at 4.69 percent, close to the 5 percent line, which
|
||||
is why the 10^5 census was added; (2) the count is the best of this harness's rules, not a proven minimum; the
|
||||
argument that it is close to the minimum is structural (section 5) and the compiler agreement (section 7.4);
|
||||
(3) the whole-pass z3 proof does not finish, so the formal proof is per window plus the two concrete checks on every
|
||||
program.
|
||||
|
||||
Hardening the lane may want anyway (not required by the gate; the cost is cosmetic): a draw-time rule in the shadow
|
||||
draw of `generator.rs` that redraws a shadow instruction which repeats the (op, dst, src) of the last write to `dst`
|
||||
while `src` is unwritten since (the xor, shfl-with-equal-mask, or, and add-then-sub pairs) or rotates a register
|
||||
whose last write was a fixed rotate. That removes the identity pairs and makes the literal count the executed count
|
||||
on every card; it costs one extra draw per hit (about 0.6 percent of shadow slots). Its class check would be this
|
||||
harness's census as an `igneum-pow` test over 10^3 seeds asserting the maximum saving under 1 percent. Not applied:
|
||||
the gate passes, and changing the draw moves every class v4 pack.
|
||||
|
||||
## 10. Ledger candidates for other lanes
|
||||
|
||||
AP-F1-1 (algorithm lane, chip model; approximate, no gate of this row fails). The attacker's `k = 0.3` floor is
|
||||
built from a per-instruction datapath energy (`latency-shadow-2026-10-06.md` section 6: 0.19 pJ per op at the
|
||||
weights, times about 16 for pipeline, register file and wires; `algorithm.md` 5.3: 0.221 pJ per op, floor 0.32)
|
||||
divided by the 5090's 11 pJ, which is per counted op (1.83 per instruction; section 5 of the same file, the rung N
|
||||
in counted ops). In one unit the same inputs give a floor of about 0.15 (3.0 pJ per instruction over 20 pJ per
|
||||
instruction on the 5090, or 1.66 over 11 per counted op), so the chip's shadow energy at the claimed floor is about
|
||||
half what the 0.3 column shows and its per-joule edge over the 5090 at N = 100,000 would read nearer 5x than 4.1x
|
||||
at that floor. The `k = 1` and `k = 0.5` columns are unaffected (they are defined on the 5090's own unit). Owner:
|
||||
the algorithm lane (F5's model sweep); what it moves: the `k = 0.3` column's label and value in `latency-shadow`
|
||||
section 6, `algorithm.md` 5.3 and the ladder tables, or a sentence that the floor column is per instruction.
|
||||
|
||||
Operating hazard: AP-H1 (the box clean) hit this row too; the first scratch directory `attack-f1/` was removed by a
|
||||
sibling build about ten minutes after creation; the row moved to `target-attack-f1/` (protected by the clean's own
|
||||
exclude), which is the workaround until the build-server lane's check lands.
|
||||
|
||||
## 11. Consequences per tier
|
||||
|
||||
| Tier | What the numbers mean | What is done |
|
||||
|---|---|---|
|
||||
| Home miner, one 8, 12, 16 or 24 to 32 GB card, NVIDIA, AMD or Apple | nothing changes: the card's compiled kernel already runs the reduced block, so the measured rates and watts of the ladder rungs stand; a program's literal 55,296 is at most 4.7 percent above what the card executes, 0.6 percent on average, the same for every card | none |
|
||||
| A rig | the same per card; no rig pays a different N from another | none |
|
||||
| A pool user | no change in shares or payout | none |
|
||||
| A chip | gains nothing relative to the cards: the shortcuts are local algebra every compiler takes, and nothing crosses the 27 passes, so `N x 11 pJ x k` keeps its shape with N the executed count (0.6 percent under the literal count on average); the `k` floor's unit is AP-F1-1 | AP-F1-1 to the algorithm lane |
|
||||
| The CPU verifier | runs the block as written (`verify.rs` interprets every instruction), so on a 4.7 percent program it does 4.7 percent of the shadow work a compiled miner skips: 0.03 ms of the 0.67 ms shadow share on the half-core proxy, inside the 10 ms gate with the margin F6 measures | none |
|
||||
| The ladder and the packs | no re-cut: the gate holds; the optional draw-time rule of section 9 is the only change on the table and it is not taken | none |
|
||||
| The paid review | this file and the harness go to the firms with the target; the window-proof script and the census line are the reproduction | hand over with the pass record |
|
||||
211
docs/analysis/attack-pass/f10-ladder.md
Normal file
211
docs/analysis/attack-pass/f10-ladder.md
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
# F10. The ladder's signal: monotonicity, the 89 percent case, the down-step, the memoisation
|
||||
|
||||
Attack-pass row F10 (`docs/plans/cryptanalysis.md` section 4.2; the pass record `docs/analysis/attack-pass-2026-10.md`).
|
||||
7 October 2026, 09:05 to 10:30 UK. Sub-agent F10 on branch `attack-pass` (worktree `igneum-wt-attack`, HEAD 8e36faf6 at
|
||||
the start of the work; the brief named 924288d1, the branch had moved on). Files: `tools/attack/f10-ladder/` and this
|
||||
record. Nothing under `vendor/`, `infra/` or the node was edited.
|
||||
|
||||
## 1. Target
|
||||
|
||||
The ladder as PROPOSED on branch `ladder` (repo tip 7003f9f5, 6 October 2026 23:58 UK; also `release-0.3.18`), node
|
||||
fork `ladder-node` tip 1591ee1d (`vendor/igneum-node-ladder`), `docs/design/latency-ladder.md` sections 3, 5a, 9 and 11.
|
||||
|
||||
| Item | Value at the commit run |
|
||||
|---|---|
|
||||
| The N ladder (counted ops) | 102,100; 132,100; 199,600; 330,700; 649,400; 1,001,600 (reps 27, 35, 53, 88, 173, 267; the design doc's round figures 100,000; 130,000; 200,000; 330,000; 650,000; 1,000,000) |
|
||||
| Floor | rung 0, reps 27 = class v4 byte for byte (`V4_CLASS`) |
|
||||
| Admissible rungs in the file run | 0, 1, 2 (rungs 3 to 5 `admissible: false`, the verifier table of section 5) |
|
||||
| The step rule | `igneum::latency_ladder_step_signalled` (`consensus/core/src/igneum.rs` lines 664 to 687): up one rung when all 7 windows have at least 9,000 bps of blue blocks up, the rung above is admissible, and the oldest window begins at or after the DAA score where the current step took effect; down one rung by the same test on the down bit, never below 0; otherwise the state stands |
|
||||
| The carrier | header `version` bit 15 = up, bit 14 = down, both or neither = none (`ladder_signal_of`); the object byte keeps bits 8 to 13; the low byte is the block version |
|
||||
| The windows | 7 consecutive windows of `latency_ladder_window_daa` (86,400 DAA on mainnet, 120 on the 60x profile, 100 in the exact-share runs here) ending at the epoch's seed block; one walk of the seed block's blue past (`class_signal::tally_window_by`); share per window = floor(10,000 x signalling / total) |
|
||||
| The seed block of epoch e | the last selected-chain block with DAA score strictly below `L e - lead` (`class_signal::seed_below`) |
|
||||
| The memo | `processes::latency_ladder::step_of_epoch`: a static `HashMap<seed hash, LadderDecision>`, filled by walking earlier epochs' seed blocks down the selected chain to a memoised decision or the activation epoch, cleared when it passes 100,000 entries; empty at every process start |
|
||||
|
||||
The box binaries used, read-only: `/srv/builds/igneum-wt-ladder/vendor/igneum-node-ladder/target/release/{igneumd,igneum-miner}`
|
||||
(built 6 October 2026 22:15Z, the fork checkout at 1591ee1d = the `ladder-node` tip, one untracked file
|
||||
`.build-remote-sha-target`) and `/srv/builds/igneum-wt-ladder/igneum-pow/target/release/igneum-pow` (built 22:38Z, after
|
||||
6b30e85). The `igneumd` binary's embedded commit string is 8dbb7a23, the PARENT of the ladder commit, not 1591ee1d
|
||||
(`strings` finds 8dbb7a23 twice and 1591ee1d never); the ladder code is in it (the step line
|
||||
`Latency ladder step by miner signal` is present, and every run below stepped). This is the stale-commit-string class
|
||||
of `tools/ci/commit-string-check.sh` (CLAUDE.md, 6 October 2026); it does not touch the result, and it is reported to
|
||||
main in section 8.
|
||||
|
||||
## 2. Known-failed shape and gate
|
||||
|
||||
Known-failed shape: a chip owner stepping the ladder down (cheaper N) without the 90 percent threshold, or a step
|
||||
registered under 90 percent in either direction. Gate (plan 4.2 row F10, the same as 1.4): no step without 90 percent
|
||||
over 7 windows in either direction; a step down needs the same. What a failure moves: the step rule's text in spec 01
|
||||
before the ladder is frozen.
|
||||
|
||||
## 3. Method
|
||||
|
||||
Two instruments, both run on igneum-build-1 on the F10 cores (`nice -n 10 taskset -c 38-39,86-87`), each run under a
|
||||
SHARED hold of the box measure file for the run only (every run capped under 30 minutes by its own `--secs`), on ports
|
||||
29900 and up, devnet suffix 990, data `/tmp/igneum-fast-time-attack-f10`, so nothing collides with the ladder lane's
|
||||
network (29720, 972) or F7's (29800, 980). Scripts and copies: `tools/attack/f10-ladder/` (box mirror
|
||||
`/srv/builds/igneum-wt-attack/attack-f10/`, run logs under `runs/`).
|
||||
|
||||
| Instrument | File | What it is |
|
||||
|---|---|---|
|
||||
| The ladder lane's harness, verbatim | `tools/attack/f10-ladder/latency-ladder.mjs` | `infra/fast-time/latency-ladder.mjs` from `ladder` at 7003f9f5, unchanged except the root lookup, this directory's copy of the ladder branch's `override-60x.json` (the attack-pass tree's copy lacks the `latency_ladder` fields), and the F10 ports, suffix, data dir and binary paths. Three nodes, three real CPU miners (one thread each), class v4 from genesis, the ladder active from DAA 0, windows of 60 DAA. Trusted only after it fires on the known-failed case (`--signal up,up,none --expect step` must report FAIL) and the known pass (`--signal up,up,up --expect step`) |
|
||||
| The exact-share driver, new | `tools/attack/f10-ladder/ladder-exact.mjs` | Three nodes on the same fork with `skip_proof_of_work`; ONE producer takes node 0's template, writes the ladder bits it wants into the header version and submits the block, one block per DAA score on a linear chain, so every window of W = 100 DAA holds exactly 100 blue blocks, one of each residue modulo 100. A schedule names per DAA range the direction and how many residues carry no signal: 11 residues give 8,900 bps in every window whatever the window's alignment, 10 give 9,000. "None" blocks alternate between no bits and both bits, so the chain shows both forms read as none. The driver polls every node's template (rung, weakest up, weakest down) through the run, restarts a node mid-window on request (SIGINT, same data dir, same arguments), and at the end re-tallies the chain in JavaScript (an independent copy of the rule: the seed rule, the 7 buckets, floor rounding, admissibility, the cool-down) and compares it with what the nodes did |
|
||||
|
||||
Why the second instrument: three equal miners cast 0, 33, 67 or 100 percent, and a real miner's share in any one
|
||||
window scatters by several points (the lane's own runs: 5,833 to 6,333 bps weakest for a 67 percent population), so no
|
||||
real-mining run can hold 8,900 to 8,999 bps in the weakest of seven windows. The rule is consensus-side and reads the
|
||||
chain's headers, not the miner, so a chain whose headers carry exact shares asks it the exact question. The skip-PoW
|
||||
network accepts every submitted block (each node logs `PoW rejected ... by igneum-lottery-v2-bound (daa N, nonce 0x0)` at
|
||||
INFO and accepts the block; the chain-side fact is the block count on every node).
|
||||
|
||||
The arithmetic of the exact-share cases (L = 60 DAA per epoch, lead 10, W = 100, 7 W = 700; genesis and the first
|
||||
produced block both sit at DAA 0, then one block per DAA): the seed block of epoch e is at DAA 60 e - 11; the seven
|
||||
windows are full from epoch 12 (seed 709); the oldest window of epoch e is DAA [60 e - 710, 60 e - 611]; after a step
|
||||
that took effect at DAA S the next decision is the first epoch with 60 e - 710 >= S.
|
||||
|
||||
| Case | Schedule (from DAA : direction : residues with no signal) | Expected by hand | Why |
|
||||
|---|---|---|---|
|
||||
| eighty-nine | 0:up:11, 1200:up:10 | no step through epoch 30 at a weakest of 8,900; rung 1 at epoch 31 when the weakest first reads 9,000; rung 2 at epoch 43, the first epoch after the cool-down; nothing else to epoch 45 | residue 10 turns from none to up at DAA 1,200; the oldest window's residue-10 block is 1,210 at epoch 31 (1,110 at epoch 30); after the step at DAA 1,860 the first epoch with 60 e - 710 >= 1,860 is 43 |
|
||||
| down | 0:up:0, 720:down:11, 1500:down:10, node restarts n2 at DAA 1,000, n1 at 2,300, n2 at 2,700 | rung 1 at epoch 12 (100 percent up); no step down at 8,900 down (epochs 24 to 35, the first cooled-down epoch is 24); rung 0 at epoch 36 when the weakest down first reads 9,000; then down at 9,000 through epoch 50 with no step below 0 (epoch 48 is the first cooled-down epoch after the down-step and the rule must hold at rung 0) | the oldest window's residue-10 block is 1,510 at epoch 36 (1,410 at epoch 35); after the down-step at DAA 2,160 the first epoch with 60 e - 710 >= 2,160 is 48 |
|
||||
| floor | 0:down:0 | no step at all through epoch 20 | 100 percent down at rung 0 from genesis: the windows are full from epoch 12, the cool-down is trivially met, the rule must stand at 0 |
|
||||
|
||||
## 4. Runs
|
||||
|
||||
All on igneum-build-1, 7 October 2026. Times UK (UTC+1); the logs are UTC. Every run held the measure file
|
||||
shared for its own length only; the first waited behind F6's exclusive hold (its batch A, 09:15 to 09:25 UK). Log paths
|
||||
are under `/srv/builds/igneum-wt-attack/attack-f10/runs/` on the box, copied to `tools/attack/f10-ladder/runs/` here
|
||||
(`<name>.log` = harness stdout, `<name>.json` = summary, `<name>-n{0,1,2}.log` = node logs).
|
||||
|
||||
### 4.1 The harness, trusted: the known-failed case and the known pass (real CPU mining, W = 60 DAA)
|
||||
|
||||
| Case | Run (UK) | Result | Numbers | Files |
|
||||
|---|---|---|---|---|
|
||||
| Known-failed, `--signal up,up,none --expect step` | 09:25:51 to 09:36:50 | FAIL rc=1, as it must: no step | no step over epochs 0 to 10; weakest-of-seven up share at the sink 5,833 bps from epoch 7 (5,500 at epoch 10); on the chain 385 blocks up, 221 none (6,353 bps up); 606 blocks; 0 rejected; one sink 4a7f20cc at 605/605/605; the 8 step checks failed (template_stepped_to_rung_1 ... rung1_ids_differ_from_the_same_seed_rung0_id); the lane's genesis low-byte fault did not fire (fixed in the file) | `baseline-fail.log`, `.json` |
|
||||
| Known pass, `--signal up,up,up --expect step` | 09:36:50 to 09:48:00 | PASS 18 of 18 | step line on 3 of 3 nodes at epoch 8: `420 of 420 blue blocks up`, weakest up 10,000 bps, shares [10000 x 7]; template rung 1 (35 passes) from epoch 8 (DAA 480) at 538.2 s; epochs 9 and 10 at rung 1, one step line per node (no second step inside seven windows); 481 / 132 blocks across the boundary; 612 blocks up and genesis none (9,984 bps); 0 rejected; one sink 41e81944 at 612/612/612; the miners' rung-1 ids on epochs 8, 9, 10 equal the CLI's `--shadow-reps 35` id and differ from rung 0 (e8 218fa530b4c599b0 against 5c5a326a31a4795d, e9 8f30ce6666b4ea8f against c73f3c63daac3748, e10 e2ea0a1ea8b4ca44 against 626455372164a1b5) | `baseline-pass.log`, `.json` |
|
||||
|
||||
Both reproduce the ladder lane's runs of 6 October (`docs/design/latency-ladder-harness/`), on the F10 cores.
|
||||
|
||||
### 4.2 The exact-share cases (skip-PoW, one block per DAA, W = 100 DAA, 8 blocks per second)
|
||||
|
||||
| Case | Run (UK) | Harness line | What the chain did | Files |
|
||||
|---|---|---|---|---|
|
||||
| eighty-nine (first run, driver v1) | 09:48:00 to 09:54:27 | FAIL rc=1 on three harness faults (section 4.3); the chain's facts are those of the re-run | identical to the re-run below | `exact-89.log`, `.json` |
|
||||
| eighty-nine (re-run, driver v2) | 10:04:45 to 10:11:14 | PASS 19 of 19 | 2,701 blocks, linear; 2,418 up, 283 none (135 of them with both bits); weakest up 8,900 bps at every epoch 12 to 30 and NO step (19 epochs, "stands" on every node); epoch 31: weakest 9,000 exactly, step line on 3 of 3: `630 of 700 blue blocks up`, shares [9000 x 7], rung 1 (35 passes); epochs 32 to 42 at 9,000 with no step (cool-down: the oldest window begins 1,210 to 1,810, the step took effect at 1,860); epoch 43: rung 2 (53 passes), `630 of 700`; 44 and 45 cool-down; 0 disagreements between nodes at any poll; one sink 1dd776b4 at 2700/2700/2700; 2 step lines per node; 382 s | `exact-89b.log`, `.json`, `-n0.log` |
|
||||
| floor (driver v2) | 10:01:40 to 10:04:38 | PASS 19 of 19 | 1,201 blocks; 1,200 down, genesis none; from epoch 12 every window reads 10,000 bps down at rung 0; the rule stands on every node for epochs 12 to 20 ("down signalled at rung 0: the floor"); no step line on any node; one sink a52e6a71 at 1200/1200/1200 | `exact-floor.log`, `.json` |
|
||||
| down (first run, driver v1) | 09:54:27 to 10:01:40 | FAIL rc=1 on the same three harness faults | identical to the third run below, restarts included | `exact-down.log`, `.json`, `-n1.log`, `-n2.log` |
|
||||
| down (second run, driver v2) | 10:11:14 to 10:18:26 | FAIL rc=1 on one harness fault (the anchor comparison at the two boundary epochs 13 and 23, section 4.3); 17 comparable epochs equal; the step lines' own weakest equal the oracle | identical to the third run | `exact-downb.log`, `.json`, `-n{0,1,2}.log` |
|
||||
| down (third run, driver v3) | 10:19:13 to 10:26:25 | PASS 19 of 19 | 3,001 blocks, linear; 720 up, 2,053 down, 228 none (110 with both bits); epoch 12: rung 1 on 3 of 3 (`700 of 700 blue blocks up`, weakest up 10,000); epochs 13 to 23 cool-down (the oldest window begins 70 to 670, the step took effect at 720); epochs 24 to 35: weakest down 8,900 bps on every node, NO step down (12 epochs "stands"); epoch 36: weakest down 9,000 exactly, step line on 3 of 3: `0 of 700 blue blocks up, 630 down`, rung 0 (27 passes, from rung 1); epochs 37 to 47 cool-down; epochs 48 to 50: 9,000 down at rung 0, the rule stands (never below 0), no third step line; restarts: n2 at DAA 1,004 (1 step line before, 4 after), n1 at DAA 2,304 (2 before, 2 after), n2 at DAA 2,704 (3 before, 2 after), every line after a restart identical in epoch, rung, origin and weakest to the lines before; 0 disagreements; one sink 20c6b367 at 3000/3000/3000; step lines 2 / 4 / 5 per node; 425 s | `exact-downc.log`, `.json`, `-n{0,1,2}.log` |
|
||||
|
||||
Per epoch, the down case as the nodes and the oracle saw it (from `exact-downc.json`; "rungs" = the first template of the
|
||||
epoch on n0 / n1 / n2; "weakest" = the decision's number from the step line where one exists, else the template's live
|
||||
sink tally, which equals the seed-anchored oracle at every epoch with no schedule boundary inside the windows):
|
||||
|
||||
| Epoch | Seed DAA | Rungs n0/n1/n2 | Weakest up / down (bps) | Oracle rung | Oracle reason |
|
||||
|---|---|---|---|---|---|
|
||||
| 11 | 649 | 0/0/0 | partial | 0 | windows not full |
|
||||
| 12 | 709 | 1/1/1 | 10,000 / 0 | 1 | up: 700 of 700 |
|
||||
| 13 to 23 | 769 to 1,369 | 1/1/1 | mixed, under 9,000 both ways | 1 | cool-down (oldest window begins before 720) |
|
||||
| 24 to 35 | 1,429 to 2,089 | 1/1/1 | 0 / 8,900 | 1 | stands: 8,900 is under 9,000 |
|
||||
| 36 | 2,149 | 0/0/0 | 0 / 9,000 | 0 | down: 630 of 700 |
|
||||
| 37 to 47 | 2,209 to 2,809 | 0/0/0 | 0 / 9,000 | 0 | cool-down (oldest window begins before 2,160) |
|
||||
| 48 to 50 | 2,869 to 2,989 | 0/0/0 | 0 / 9,000 | 0 | down signalled at rung 0: the floor |
|
||||
|
||||
And the eighty-nine case (`exact-89b.json`):
|
||||
|
||||
| Epoch | Seed DAA | Rungs n0/n1/n2 | Weakest up (bps) | Oracle rung | Oracle reason |
|
||||
|---|---|---|---|---|---|
|
||||
| 12 to 30 | 709 to 1,789 | 0/0/0 | 8,900 | 0 | stands, 19 epochs |
|
||||
| 31 | 1,849 | 1/1/1 | 9,000 | 1 | up: 630 of 700 |
|
||||
| 32 to 42 | 1,909 to 2,509 | 1/1/1 | 9,000 | 1 | cool-down (oldest window begins 1,210 to 1,810, the step took effect at 1,860) |
|
||||
| 43 | 2,569 | 2/2/2 | 9,000 | 2 | up: 630 of 700 |
|
||||
| 44 to 45 | 2,629 to 2,689 | 2/2/2 | 9,000 | 2 | cool-down |
|
||||
|
||||
### 4.3 Harness faults found and fixed on the way (the driver's, never the chain's)
|
||||
|
||||
| Fault | Seen | Fix |
|
||||
|---|---|---|
|
||||
| `every_produced_block_on_every_node` compared `blockCount` with produced + 1; the node's `blockCount` excludes genesis | exact-89 first run, 09:54 UK | compare with produced (2,700 = 2,700) |
|
||||
| `zero_rejected_by_nodes` grepped `ban` and matched the finality parameter line `... ban 120 ...` | same run | the word dropped; the skip-PoW INFO line `PoW rejected ... by igneum-lottery-v2-bound` excluded by its own text |
|
||||
| `node_weakest_equals_oracle_weakest` compared the template's weakest with the seed-anchored oracle at every epoch; the template's number is the LIVE tally anchored at the sink (`consensus/mod.rs` `get_pow_epoch_info`, `tally_ladder(..., sink, ...)`), read at the epoch's first template, sink = seed + lead (10 DAA) | epoch 11 of exact-89 (49 of 59 at the sink against 39 of 49 at the seed); epochs 13 and 23 of the second down run (40 up in (679, 779] against 50 in (669, 769], the boundary at 720 inside both) | compared only at epochs with seven full windows and no schedule boundary inside the windows plus the lead; a new check compares the decision's own weakest (the step line) with the oracle at every stepped epoch, which passed in every run |
|
||||
|
||||
The smoke run (`smoke.log`, 09:14 UK, 3 epochs) validated the template round trip (`submitBlock` reports
|
||||
`{"type":"success"}`, 180 blocks on 3 of 3 nodes at 8 per second).
|
||||
|
||||
## 5. What the runs show against the gate
|
||||
|
||||
| Gate clause | Shown by | Numbers |
|
||||
|---|---|---|
|
||||
| No step up without 90 percent over 7 windows | eighty-nine: 19 epochs at 8,900 bps in every window, rung 0 held on every node; the step came at the first epoch whose weakest read 9,000, 630 of 700 blue blocks | epochs 12 to 30 stand; 31 steps |
|
||||
| No step down without 90 percent over 7 windows | down: 12 cooled-down epochs at 8,900 bps down in every window, rung 1 held on every node; the step down came at the first epoch whose weakest down read 9,000, 630 of 700 | epochs 24 to 35 stand; 36 steps |
|
||||
| A step down needs the same cool-down | down: epochs 13 to 23 at rung 1 with the oldest window beginning before the step took effect: the rule stood although the up share had collapsed | 11 epochs |
|
||||
| Never below 0 | floor: 10,000 bps down at rung 0 for 9 epochs, no step line; down: 9,000 bps down at rung 0 for epochs 48 to 50 after the cool-down, no step line | 12 epochs across two runs |
|
||||
| Monotone: one rung per decision, seven windows between decisions | eighty-nine: rung 1 at 31, rung 2 not before 43 with 9,000 in every window throughout; down: rung 1 at 12, rung 0 at 36 | the cool-down held 11 epochs each time |
|
||||
| The decision computed once per seed block and reused | one or two step lines per process per stepped epoch (two when the first template and header processing walked concurrently), none afterwards | n0: 2 lines for 2 steps in every exact run |
|
||||
| A node restarted mid-window reaches the same decision | three restarts in the down case: every step line after a restart repeats the lines before it in epoch, rung, origin and weakest; the restarted node's template rung equals the others' at every epoch | n2 at 1,004 and 2,704, n1 at 2,304 |
|
||||
| Two nodes never disagree on the rung at the same height | 0 disagreements at every observation (every fifth block) and at every epoch's first template, in every run | 5 exact runs, 2 baseline runs |
|
||||
| Both bits = none | 135 and 110 both-bits blocks counted as none by the oracle and by the nodes (the shares matched) | eighty-nine, down |
|
||||
| The known-failed shape (a chip owner stepping down under 90 percent; a step registered under 90 percent) | did not occur; 8,900 held in both directions, floor rounding puts 8,999 below the line (unit test, `igneum.rs` 1161) | gate holds |
|
||||
|
||||
## 6. Static reading of the rule (what the harness cannot show)
|
||||
|
||||
Read in the fork at 1591ee1d before the runs. Each line is a property of the code as written, with the place.
|
||||
|
||||
| Property | Where | Reading |
|
||||
|---|---|---|
|
||||
| Symmetry of the two directions | `igneum.rs` 676 to 686 | one closure `all(shares)` serves both bits; the up branch runs first, then `all(down) && previous.step > 0`; up and down cannot both reach 9,000 bps of one window's blocks, so the order never decides |
|
||||
| The cool-down is direction-free | `igneum.rs` 674 | `first_counted_daa < previous.since_daa` returns the previous state before either branch is read; a step down waits the same seven windows after a step up as a step up does after a step down |
|
||||
| Never below 0 | `igneum.rs` 681 | `previous.step > 0` guards the subtraction; a 100 percent down signal at rung 0 stands (the floor case below shows it on the chain) |
|
||||
| Never past an inadmissible rung | `igneum.rs` 679 | `ladder.admissible(previous.step + 1)`; rung 3 is `admissible: false` in the file, so from rung 2 a 100 percent up signal stands (unit test `latency_ladder_rule`, `igneum.rs` 1161) |
|
||||
| Floor rounding | `igneum.rs` 431 to 437 | `signal_share_bps` = floor(10,000 x signalling / total); 89 of 100 blue blocks is 8,900, 90 is 9,000; on a mainnet window of 86,400 blocks 77,759 up is 8,999 and 77,760 is 9,000 |
|
||||
| Both bits set | `igneum.rs` 639 to 645 | `version & 0xc000 == 0xc000` falls to `None`; a header cannot vote both ways and cannot vote twice |
|
||||
| Weakest of seven | `class_signal.rs` `SignalTally::weakest_bps` and the rule's `all` | the decision rests on the lowest of the seven windows; one bought window at 100 percent moves nothing (unit test "one bought day does not move it") |
|
||||
| The windows are the seed block's own past | `class_signal.rs` `tally_window_by` | the anchor and the mergeset blues of each selected-chain block walking down, bucketed by `daa_c - daa`, stopping once `daa_cur + merge_depth < window_start`; blocks above the seed are never counted, so the seven windows are fixed once the seed block is |
|
||||
| The memo is sound | `latency_ladder.rs` `step_of_epoch` | keyed by the seed block's hash; the decision is a function of that block's selected-chain past and of process-global constants installed from the file (ladder, activation, window), so two processes with the same file and the same chain compute the same value; the memo is never read across a param change because the params are fixed at start; cleared above 100,000 entries, then rebuilt by the walk |
|
||||
| Concurrent first computation | `latency_ladder.rs` `memo_get` / `memo_put` | the lock is not held across the walk, so two concurrent callers may both walk and both log the step line; both write the same value, so the chain's decision is unaffected (the runs below show one or two step lines per process for the same epoch, identical in content) |
|
||||
| A node without the history | `latency_ladder.rs` `step_of_epoch`, the two `warn!` returns | a node whose seed block's windows cannot be walked (synced from a pruning proof) decides RUNG 0 and logs "a ladder witness is owed". After a step up, such a node runs rung 0's program and refuses rung 1's blocks: a split between full-history nodes and proof-synced nodes. The design doc lists the witness as owed (section 9). This is not a fault of the step rule and the harness cannot reach it (every node here has the history); it is a precondition on activation: no network activates the ladder while any peer syncs from a proof without the witness. Routed to main in section 8 |
|
||||
|
||||
Nothing in the reading admits a step under 9,000 bps in either direction, a step down under the cool-down, a step
|
||||
below rung 0, or a decision that depends on which node computes it or when.
|
||||
|
||||
## 7. Consequences per tier
|
||||
|
||||
The rule holds, so a step in either direction costs 90 percent of blue blocks in each of seven consecutive days, and
|
||||
the earliest second step is seven days after the first. What a WRONGFUL step would have done, had the rule admitted one
|
||||
under 90 percent, is the measured per-rung table of `docs/design/latency-ladder.md` section 8 (algorithm.md 5.3a rungs,
|
||||
igneum-build-1 verifier) read in each direction. Every row below is that table's number, not a new measurement.
|
||||
|
||||
| Wrongful step | M5 Max (Apple tier) | RTX 5090 at 431 W | RTX 4070 at 160 W | RX 9070 XT | 8 / 12 / 16 GB cards, rigs, pools | Verifier (half-core) | f = 1 chip's per-joule edge over the 5090 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| Up 0 to 1 (102,100 to 132,100 ops) under 90 percent | -3.3 points of rate, 0 W more | 0 | 0 | 0 | 0 (the shadow costs ALU, not memory; the dataset size is the schedule's, not the ladder's) | +0.2 ms | 2.1x to 1.7x at k = 1 (3.9x to 3.4x at k about 0.33) |
|
||||
| Up 1 to 2 (to 199,600) under 90 percent | -6 more points | -2.7 percent | +21 W | 0 | 0 | +0.5 ms | to 1.3x (2.8x) |
|
||||
| Up 2 to 3 (to 330,700): inadmissible, never entered | -21 percent | -35 percent (compute-bound at the cap) | -12 percent | +3.6 percent | 0 | +0.9 ms | 3.0x at k about 0.33 |
|
||||
| Down 2 to 1, 1 to 0 under 90 percent (the chip owner's step) | the Apple tier gets its 6 then 3.3 points back | +2.7 percent then 0 | -21 W then 0 | 0 | 0 | -0.5 then -0.2 ms | the chip regains 1.3x to 1.7x to 2.1x (2.8x to 3.4x to 3.9x): every rung down hands the stored-dataset chip back the edge the miners paid for |
|
||||
|
||||
Reading per tier, with the rule as it stands:
|
||||
|
||||
| Tier | What the result means |
|
||||
|---|---|
|
||||
| Home card, 8 / 12 / 16 / 24 GB, any vendor, any OS | A step up costs rate only on the Apple tier at rungs 1 and 2, and on NVIDIA from rung 2; no step happens unless 90 percent of blocks over seven days ask for it, so a minority that would lose rate cannot be moved by a bought day or a 89 percent week, and a chip owner under 90 percent cannot move the rung down to cheapen its core. A 90 percent majority can step the chain down one rung per week to the floor (rung 0 = class v4 as it ships), which is the design's floor and not a weakness of the rule: at 90 percent of blocks the owner already orders the chain |
|
||||
| Rig, pool user | The same; a pool signals per block through its node's `IGNEUM_LADDER_SIGNAL` (the app's toggle later), so a pool's share of blocks is its weight |
|
||||
| Verifier (the node, the proof) | Admissibility is a genesis flag per rung; rung 3 is never entered by any signal until a quiet re-measurement before genesis moves the flag (section 4 of the design doc); the memo keeps the per-template cost to one walk per seed block per process |
|
||||
| A node synced from a pruning proof | Decides rung 0 until the ladder witness lands (section 6, last row): the ladder must not activate on a network where such nodes exist before the witness. This is the one consequence the rule's text does not state and the spec line should |
|
||||
|
||||
## 8. Verdict, and what goes to main
|
||||
|
||||
PASS. No step without 90 percent of blue blocks in each of seven consecutive windows in either direction; a step down
|
||||
needs the same 90 percent and the same seven-window cool-down; the floor holds under 100 percent down; the decision is
|
||||
per seed block, memoised per process, recomputed identically after a restart, and never differs between nodes at the
|
||||
same epoch. The known-failed harness case fails, the known pass passes, and three new cases (89 percent up, 89 then 90
|
||||
percent down with restarts, the floor) pass on the chain and on the harness's own 19 checks. The step rule's text in
|
||||
spec 01 needs no change for the gate.
|
||||
|
||||
To main, not findings against the gate:
|
||||
|
||||
| Item | What | Proposed route |
|
||||
|---|---|---|
|
||||
| Stale commit string in the ladder lane's `igneumd` | the binary built 6 October 22:15Z from the fork at 1591ee1d carries 8dbb7a23 (its parent) and no 1591ee1d; the ladder code is in it | the commit-string-check class (CLAUDE.md, 6 October 2026); the ladder lane rebuilds with the two-step before any Devnet 2 crossing; nothing in this row depends on it |
|
||||
| Proof-synced nodes decide rung 0 until the witness lands | `processes::latency_ladder::step_of_epoch` returns rung 0 with a warning when the seed block's windows cannot be walked; after a step, such a node runs the wrong program and splits from full-history peers | a precondition line for the step rule's text in spec 01 when the ladder is adopted: "the ladder activates only once every node can walk the seven windows below every seed block, or carries the ladder witness in its pruning proof"; the design doc already lists the witness as owed (section 9); node lane |
|
||||
| Spec text for the ladder, when adopted (none in spec 01 today; the only ladder there is `epoch_len`'s) | the rule as run: 90 percent of blue blocks in each of 7 consecutive windows ending at the seed block, floor rounding, one rung per decision, the oldest window at or after the last step in either direction, never below rung 0, never into an inadmissible rung; the template's weakest is the live sink tally and the decision's is at the seed | the algorithm lane's spec line; this record is the test it cites |
|
||||
| Three harness faults in the F10 driver | section 4.3; all three were the driver's reading of the node, fixed in `ladder-exact.mjs` v3 | none owed; recorded so the firm does not repeat them |
|
||||
|
||||
Blocked: nothing. Not run: a real-mining 89 percent case (three equal miners cannot cast it; the exact-share driver
|
||||
asks the rule the same question through the same submit path and the same consensus code).
|
||||
214
docs/analysis/attack-pass/f2-mixer.md
Normal file
214
docs/analysis/attack-pass/f2-mixer.md
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
# Attack pass F2: the mixer's round margin
|
||||
|
||||
Row F2 of `docs/plans/cryptanalysis.md` section 4.2 (branch `cryptanalysis`), fed into
|
||||
`docs/analysis/attack-pass-2026-10.md`. Run 7 October 2026, 09:00 to [FILL] UK, by the attack-pass sub-agent F2 on
|
||||
igneum-build-1 (cores 6-11 and 54-59, nice 10, the measure file held shared in chunks under 30 minutes).
|
||||
|
||||
## 1. Target
|
||||
|
||||
Commit `924288d1` (worktree `igneum-wt-attack`, branch `attack-pass`). The x8 mixer of `igneum-pow/src/memhard.rs`,
|
||||
`mixer` (lines 300 to 313): one application on 16 words of 32 bits is, per word, `(s[i] ^ (RC[i] + rk)) * MUL[i]`
|
||||
with `MUL[i]` odd, then one ChaCha-shaped double round: four column quarter rounds with rotations `ROT[0..3]`,
|
||||
four diagonal quarter rounds with `ROT[4..7]`. `ROT`, `MUL`, `RC` are drawn per day from the 64-bit SplitMix64 seed
|
||||
`K[0] | K[1] << 32` by `MixParams::with_shape` (lines 237 to 258). Under class v3 and v4 (`m = 8`) an item is 8
|
||||
dependent cache reads, each preceded by 8 applications with round keys `round_key(r * 8 + j)`, and 8 more after the
|
||||
last read: 72 applications per item (`derive_items_mask`, lines 517 to 550). The chip model prices one application
|
||||
at 128 hoisted operations and an item at 9,360 (`docs/analysis/chip-model-v3.md` 5.2).
|
||||
|
||||
The days modelled: the genesis day `2026-10-03` (`ROT = 20 20 19 4 26 3 3 27`, as `proto-metal/MEMHARD.md` line 82
|
||||
states; the harness reads the same draw from the code) and two other days, `2026-10-04` (`ROT = 28 15 9 26 2 2 22
|
||||
8`) and `2027-03-01` (`ROT = 31 16 15 15 2 9 19 4`). Their full `MUL` and `RC` are in the box files
|
||||
`/srv/builds/igneum-wt-attack/target-attack-f2/params/<day>.real.txt`.
|
||||
|
||||
Known-failed shape (the plan's row): a differential or linear trail, a rotational-XOR relation, or an algebraic fold
|
||||
that distinguishes or shortcuts more than 2 of the 8 applications between dependent reads. Gate: none beyond 2 of 8.
|
||||
|
||||
## 2. Method
|
||||
|
||||
Four searches and two checks, every one on the bit-level definition in `memhard.rs` (the harness calls
|
||||
`igneum_pow::memhard::mixer` itself; the SAT models consume one op list whose value evaluator is checked against
|
||||
the Rust output on 64 applications per day and variant, 9 files, all matching).
|
||||
|
||||
| Piece | What it is | Exact or model |
|
||||
|---|---|---|
|
||||
| Differential, MSB family | XOR differences; at every multiply each word's difference is 0 or `0x80000000`. These are the only word transitions through an odd multiply with probability 1 (`(x ^ 2^31) * c = (x * c) ^ 2^31`; any other nonzero difference passes with probability at most 1/2, since its lowest active bit below the MSB leaves a carry to chance). Modular addition by Lipmaa-Moriai (exact per adder), XOR and rotation linear | exact family, trail probabilities exact per operation |
|
||||
| Differential, general | The same ARX model with every word difference allowed through the multiply: XOR difference to modular difference (each set bit below the MSB is a sign choice, 2^-1 each, exact), times `MUL` (exact, a circuit on the difference variables), modular back to XOR (a carry chain, one bit per position where the difference bit and the carry differ, exact), the two conversions taken as independent | Markov trail model; its per-word cost sits 1 to 2 bits above the sampled best transition (section 4.1), so it is a trail model, slightly pessimistic for the attacker |
|
||||
| Linear, low-bit family | Masks; at every multiply the output mask lies in bits 0 and 1, the only F2-linear output bits of an odd multiply (`(cx)_0 = x_0`, `(cx)_1 = x_1 ^ (c_1 & x_0)`). Modular addition by the exact carry-mask automaton (per bit a carry-mask bit; checked against brute force at n = 8 on 500 mask triples, max error 0) | exact family |
|
||||
| Linear, general | The same with the multiply as its shift-and-add decomposition (one adder per set bit of `MUL`, the low known-zero bits of a shifted copy transparent), each adder under the automaton | trail model; over-optimistic for the attacker (section 4.3) |
|
||||
| Rotational-XOR | Measured on the real code: for every rotation r in 1..31 and k = 1..4, the per-bit bias of `rot_r(M^k(x)) ^ M^k(rot_r(x))` over 2^20 states, the largest |z| of the 512 bits, and the count of exact rotational pairs; plus the word-level prologue `g(x) = (x ^ C) * MUL` alone: the most frequent value of `rot_r(g(x)) ^ g(rot_r(x))` over 2^20 inputs | measurement |
|
||||
| The fold | The identities a chip would need to pay less than k x 128 for k applications, each tested on 2^20 random inputs, plus the algebraic argument (section 4.5) | measurement and argument |
|
||||
|
||||
Search: for each (model, day, k = 1..4) the weight bound W is probed upward (SAT means a trail of weight at most W
|
||||
exists, UNSAT means none does in the model), then narrowed to the minimum. A k-application trail restricted to one
|
||||
application is a valid 1-application trail, so every application is held to the proven k = 1 minimum of the same
|
||||
model (the Matsui floor in the tables). Solver CaDiCaL 1.9.5 through python-sat 1.9. Every trail found of
|
||||
measurable weight is measured on the real code before it counts: per application and as a chain, 2^20 to 2^28
|
||||
samples (`attack-f2 verify-diff` / `verify-lin`), with the multiply-layer word transitions counted exactly over all
|
||||
2^32 inputs (`verify-mults`). A trail that does not hold is blocked and the solver asked again at the same bound.
|
||||
Linear trails whose correlation cancels inside one adder's hull are caught first by the exact signed sum over the
|
||||
adder's carry masks.
|
||||
|
||||
What "reaches k applications" means here, two readings: (a) the shortcut reading, the one with a cost consequence:
|
||||
a relation of probability 1 (weight 0) over k applications, which a chip could use to skip work; (b) the
|
||||
distinguisher reading: a trail of weight under 64 over k applications, the usual practical line. For the gate both
|
||||
are reported.
|
||||
|
||||
## 3. Harness
|
||||
|
||||
| Item | Path |
|
||||
|---|---|
|
||||
| Crate (ground truth: parameters, vectors, verification, RX, fold) | `tools/attack/f2-mixer/` (`Cargo.toml`, `src/main.rs`), `igneum-pow` by path, own `[workspace]` |
|
||||
| SAT models and the search | `tools/attack/f2-mixer/model.py` (`selftest`, `search`, `show`) |
|
||||
| Box queue runner, tables | `tools/attack/f2-mixer/run_jobs.sh`, `tools/attack/f2-mixer/summarise.py` |
|
||||
| Build line (from the crate directory) | `IGNEUM_AGENT=attack-f2 bash /Users/joshm/Projects/igneum/tools/build-remote.sh --artefacts "target/release/attack-f2" --out <scratch> -- build --release`; binary on the box `/srv/builds/igneum-wt-attack/tools/attack/f2-mixer/target/release/attack-f2` (ELF x86-64, sha256 `150337ec...`, the third build; 12 s incremental) |
|
||||
| Box scratch (states, trails, logs, venv) | `/srv/builds/igneum-wt-attack/target-attack-f2/` (`state/`, `logs/`, `params/`, `vectors/`, `venv/`). The brief's path `attack-f2/` was wiped within ten minutes by another lane's worktree-root rsync (`--delete` spares only `target-*`), so the scratch moved under a `target-` name, as F1 and F6 did |
|
||||
| Run lines | `venv/bin/python3 model.py selftest --vectors vectors --params-dir params`; `bash run_jobs.sh jobs.txt 11` (each job `model.py search --kind diff|lin --family msb|general|low2 --params params/<day>.<variant>.txt --apps k --state state/<name>.json --budget <chunk> --per-app-min <k=1 floor> --verifier <binary>` under `flock -s /srv/builds/_locks/measure`, `nice -n 10 taskset -c 6-11,54-59`); `attack-f2 rx --day D --variant V --apps 4 --log2 20`; `attack-f2 rx-word --day D --log2 20`; `attack-f2 fold --day D --log2 20` |
|
||||
| Logs | `logs/<model>-<day>-<variant>-k<k>.log` per search, `logs/rx.<day>.<variant>.log`, `logs/rx-word.<day>.<variant>.log`, `logs/fold.<day>.log`, `logs/summary.md` (the tables below), `logs/verify*.log` |
|
||||
|
||||
## 4. Results
|
||||
|
||||
### 4.1 The harness fires (known pass, known fail)
|
||||
|
||||
| Case | Expected | Got | Log |
|
||||
|---|---|---|---|
|
||||
| Selftest: evaluator against `attack-f2 vectors`, 3 days x 3 variants, 4 applications x 16 states each | all match | 9 of 9 files, 64 of 64 applications each | `selftest` output, `logs/selftest.log` |
|
||||
| Selftest: linear add automaton against brute force, n = 8 | exact | 300 random triples and 200 shifted-copy triples, max error 0.00e+00 | same |
|
||||
| Selftest: Lipmaa-Moriai against brute force, n = 8; both SAT encodings against their rules at n = 32 | exact | max error 0; 0 mismatches of 40 and 40 | same |
|
||||
| Selftest: the multiply model's word cost against the sampled best transition (word 3, genesis day) | MSB exact; others within a few bits | MSB: weight 0, measured 2^-0 (exact); bit 30: model 2, sampled best 2^-1.00; bits 31+5: model 8, sampled best 2^-6.03; bit 0: model 10, sampled best 2^-8.97 | same |
|
||||
| Known pass, 0 applications | the identity trail, weight 0 | trivial (input = output, no weights); not run as a job | |
|
||||
| Known fail, `rot0` (every rotation 0), differential, k = 1, 2, 4 | a weight-0 trail (MSB-only differences stay MSB-only when nothing rotates) | weight 0 found at k = 1, 2, 4 (both families); measured probability 1 on the real code (`verified_chain -0.0`) | `state/diff-msb-2026-10-03-rot0-k{1,2,4}.json`, `state/diff-general-2026-10-03-rot0-k{1,2}.json` |
|
||||
| Known fail, `rot0`, linear, k = 1, 2, 4 | a weight-0 trail (LSB masks) | weight 0 at k = 1, 2, 4; measured correlation 1 per application and as a chain | `state/lin-low2-2026-10-03-rot0-k{1,2,4}.json`, `state/lin-general-2026-10-03-rot0-k{1,2}.json` |
|
||||
| Known fail, `nomul` (MUL 1, RC 0, rk 0: the bare double round), rotational-XOR, k = 1 | a large per-bit bias | max |z| 134.2 (r = 31) against 4.2 for the real mixer; word-level: the prologue is exactly rotational (2^20 of 2^20) against 3 of 2^20 | `logs/rx.2026-10-03.nomul.log`, `logs/rx-word.2026-10-03.nomul.log` |
|
||||
| Known fail, `rot0`, rotational-XOR | bias | max |z| 32.3 at k = 1, 9.0 at k = 2 | `logs/rx.2026-10-03.rot0.log` |
|
||||
| Known fail, `nomul`, differential k = 1 | the bare double round's best trail, below the real mixer's | weight 7 found (model), measured 2^-5.0 on the real code | `state/diff-general-2026-10-03-nomul-k1.json` |
|
||||
|
||||
### 4.2 Differential trails
|
||||
|
||||
| Model | Day | Variant | k | Best trail weight found | No trail at or below (model) | Closed | Per-application floor | Verified on the real code (chain; per application) | Solver s |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| diff/general | 2026-10-03 | real | 1 | 12 | 11 | yes | 0 | 12.011; [11.939] | 186 |
|
||||
| diff/general | 2026-10-03 | real | 2 | none | 24 | no (timebox) | 12 | | 1,739 |
|
||||
| diff/general | 2026-10-04 | real | 1 | 10 | 9 | yes | 0 | 10.001; [9.999] | 321 |
|
||||
| diff/general | 2026-10-04 | real | 2 | none | 20 | no (timebox) | 10 | | 663 |
|
||||
| diff/general | 2027-03-01 | real | 1 | 12 | 11 | yes | 0 | 12.057; [11.907] | 175 |
|
||||
| diff/msb | 2026-10-03 | real | 1 | 12 | 11 | yes | 0 | 12.206; [11.972] | 4 |
|
||||
| diff/msb | 2026-10-03 | real | 2, 3, 4 | none | 512 (the family dies) | yes | 12 | | 26, 33, 22 |
|
||||
| diff/msb | 2026-10-04 | real | 1 | 10 | 9 | yes | 0 | 10.001; [10.001] | 309 |
|
||||
| diff/msb | 2026-10-04 | real | 2, 3, 4 | none | 512 | yes | 10 | | 20, 33, 44 |
|
||||
| diff/msb | 2027-03-01 | real | 1 | 12 | 11 | yes | 0 | 12.057; [11.907] | 3 |
|
||||
| diff/msb | 2027-03-01 | real | 2, 3, 4 | none | 512 | yes | 12 | | 10, 15, 21 |
|
||||
| diff/general | 2026-10-03 | nomul (known fail) | 1 | 7 | 6 | yes | 0 | 5.002; [5.003] | 38 |
|
||||
| diff/general | 2026-10-03 | nomul | 2 | none | 20 | no | 7 | | 1,309 |
|
||||
| diff/general, diff/msb | 2026-10-03 | rot0 (known fail) | 1, 2, 4 | 0 | | yes | 0 | probability 1 | under 1 |
|
||||
|
||||
The general model's k = 3 and k = 4 jobs (closed 14:3x UTC, every job at its 7,200 s cap, `logs/summary.md`):
|
||||
|
||||
| Model | Day | k | Best trail found | No trail at or below (model) | Per-application floor | Solver s |
|
||||
|---|---|---|---|---|---|---|
|
||||
| diff/general | 2026-10-03 | 3 | none | 35 | 12 | 7,201 (cap) |
|
||||
| diff/general | 2026-10-03 | 4 | none | 47 | 12 | 7,359 (cap) |
|
||||
| diff/general | 2026-10-04 | 3 | none | 29 | 10 | 7,350 (cap) |
|
||||
| diff/general | 2026-10-04 | 4 | none | 39 | 10 | 7,279 (cap) |
|
||||
| diff/general | 2027-03-01 | 3 | none | 35 | 12 | 7,321 (cap) |
|
||||
| diff/general | 2027-03-01 | 4 | none | 47 | 12 | 7,284 (cap) |
|
||||
| lin/general | 2026-10-03 | 3 | none | 24 | 1 | 7,953 (cap) |
|
||||
| lin/general | 2026-10-03 | 4 | none | 24 | 1 | 7,352 (cap) |
|
||||
| lin/general | 2026-10-04 | 3 | none | 28 | 1 | 7,373 (cap) |
|
||||
| lin/general | 2026-10-04 | 4 | none | 24 | 1 | 7,393 (cap) |
|
||||
| lin/general | 2027-03-01 | 3 | none | 24 | 1 | 7,402 (cap) |
|
||||
|
||||
No trail of weight under 32 at three applications (the finding line): the bound reached is 29 to 35 at three and
|
||||
39 to 47 at four for differentials, 24 to 28 at three and 24 at four for linear masks, all solver-capped, so these are
|
||||
effort bounds, not proofs; they grow with k as the per-application floors predict.
|
||||
|
||||
### 4.3 Linear trails
|
||||
|
||||
| Model | Day | Variant | k | Best trail weight found (correlation 2^-w) | No trail at or below | Closed | Verified (chain; per application) | Solver s |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| lin/general | 2026-10-03 | real | 1 | 1 | 0 | yes | 0.996; [0.997] | 5 |
|
||||
| lin/general | 2026-10-03 | real | 2 | none | 20 | no (timebox) | | 1,019 |
|
||||
| lin/general | 2026-10-04 | real | 1 | 1 | 0 | yes | 0.995; [0.999] | 5 |
|
||||
| lin/general | 2026-10-04 | real | 2 | none | 24 | no (timebox) | | 1,669 |
|
||||
| lin/general | 2027-03-01 | real | 1 | 1 | 0 | yes | 1.003; [0.996] | 5 |
|
||||
| lin/general | 2027-03-01 | real | 2 | none | 20 | no (timebox) | | 1,224 |
|
||||
| lin/low2 | 2026-10-03, 2026-10-04, 2027-03-01 | real | 1 | 1 | 0 | yes | 0.995 to 1.003 | 4 to 5 |
|
||||
| lin/low2 | 2027-03-01 | real | 2, 3, 4 | none | 512 (the family dies) | yes | | 12, 18, 27 |
|
||||
| lin/general | 2026-10-03 | nomul (known fail) | 1 | 1 | 0 | yes | 0.999; [1.003] | 4 |
|
||||
| lin/general, lin/low2 | 2026-10-03 | rot0 (known fail) | 1, 2, 4 | 0 | | yes | correlation 1 | 5 to 10 |
|
||||
|
||||
One application carries a weight-1 linear trail (the LSB mask through the prologue and one add, correlation 1/2),
|
||||
the structural residue of 4.5; at two applications no trail at or below weight 20 to 24 exists in the general
|
||||
model within the timebox, and the LSB family dies (no trail at or below 512) from k = 2.
|
||||
|
||||
### 4.4 Rotational-XOR
|
||||
|
||||
Per k and day, the largest |z| over all 31 rotations and 512 bits at 2^20 states (15,872 bit tests per k; the
|
||||
noise ceiling of that many tests is about 4.3), and the count of exact rotational pairs.
|
||||
|
||||
| Day | k = 1 | k = 2 | k = 3 | k = 4 | Exact pairs | Log |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 2026-10-03 | 4.22 (r 19) | 4.29 (r 30) | 4.22 (r 3) | 4.62 (r 27) | 0 | `logs/rx.2026-10-03.real.log` |
|
||||
| 2026-10-04 | 4.35 (r 17) | 4.00 (r 19) | 4.24 (r 25) | 4.49 (r 28) | 0 | `logs/rx.2026-10-04.real.log` |
|
||||
| 2027-03-01 | 3.96 (r 7) | 4.07 (r 2) | 4.04 (r 28) | 4.17 (r 19) | 0 | `logs/rx.2027-03-01.real.log` |
|
||||
| 2026-10-03, bare double round (`nomul`) | 134.24 (r 31) | 4.37 | | | 0 | `logs/rx.2026-10-03.nomul.log` |
|
||||
|
||||
The word-level prologue `(x ^ C) * MUL`: over 2^20 inputs the most frequent value of `rot_r(g(x)) ^ g(rot_r(x))`
|
||||
occurs at most 3 times for every word and every r on all three days (`logs/rx-word.<day>.real.log`, the
|
||||
`rxw_worst` lines), against 2^20 of 2^20 without the multiply. The odd multiply by a random constant is not
|
||||
rotational to any measurable degree, and one application already shows no per-bit bias. Rotational-XOR does not
|
||||
reach 1 application.
|
||||
|
||||
### 4.5 The fold of the multiply layer
|
||||
|
||||
One application is `D o P_rk`, with `P_rk(s)_i = (s_i ^ (RC_i + rk)) * MUL_i` and `D` the double round (fixed per
|
||||
day). Multiplication by an odd constant distributes over modular addition and over nothing else in `D` (XOR,
|
||||
rotation); the XOR with a constant commutes with XOR and rotation and with nothing else (addition, multiply). A fold
|
||||
across applications would need one of the identities below. Each was tested on 2^20 random inputs on every day
|
||||
(`logs/fold.<day>.log`):
|
||||
|
||||
| Identity a chip would need | Holds on | Meaning |
|
||||
|---|---|---|
|
||||
| `(xa ^ Ca) * ma + (xb ^ Cb) * mb = ((xa ^ Ca) + (xb ^ Cb)) * ma` for the four column pairs (0,4), (1,5), (2,6), (3,7) | 0 of 1,048,576 for every pair on every day (`MUL` distinct in every pair) | the multiply does not fold into the first add of a quarter round; it would if a column pair drew the same `MUL` (probability 2^-31 per pair per day, the weak-day class of F4) |
|
||||
| `(x ^ C) * m = (x * m) ^ (C * m)`, or `= (x * m) ^ C'` for any single `C'` | 0 of 1,048,576; the best single `C'` agrees on 33 of 1,048,576 (2^-15) | the constant cannot be moved past the multiply, so application j + 1's prologue cannot share application j's multiply |
|
||||
| an XOR constant on one word commuting with the bare double round (so the next prologue's constant could be folded back) | 0 of 65,536 for every word | every word's value feeds an add inside the double round |
|
||||
| the MSB passing the prologue and the add for free; the LSB passing the prologue | 1,048,576 of 1,048,576 each | the structural residue: the only free passages, both moved by the rotations (the family deaths in 4.2 and 4.3) |
|
||||
|
||||
So k applications cost k times one application, 128 hoisted operations each (16 multiplies, 32 adds, 32 XORs, 32
|
||||
rotations with the constants hoisted); `chip-model-v3.md` 5.2's 9,360 per item stands. The trail weights of 4.2
|
||||
and 4.3 growing with k is the quantitative side of the same fact: a composition that collapsed to one application's
|
||||
shape would keep one application's trail weights.
|
||||
|
||||
## 5. Gate and verdict
|
||||
|
||||
Gate (plan 4.2 F2, 1.4 (1)): no distinguisher or shortcut beyond 2 of the 8 applications between dependent reads,
|
||||
after the stated search.
|
||||
|
||||
| Line of attack | Reach | Verdict |
|
||||
|---|---|---|
|
||||
| Differential, general model (Markov on the multiply, exact add rule, SAT) | one application: best trail weight 10 to 12 on three days, verified on the real code; two applications: no trail at or below weight 20 to 24 within 7,200 s per job (not closed); the MSB family dies at two applications on every day | nothing reaches 2 applications below 2^-20 |
|
||||
| Linear, general model (piling-up, SAT) | one application: weight 1 (the LSB residue); two applications: no trail at or below 20 to 24 within the timebox; the LSB family dies at two | nothing reaches 2 applications below 2^-20 |
|
||||
| Rotational-XOR | no per-bit bias at one application (max abs z 4.0 to 4.6 at 2^20 states, noise ceiling 4.3); 0 exact pairs; the multiply prologue is rotational on at most 3 of 2^20 inputs; the bare double round fires at 134 | does not reach 1 application |
|
||||
| Algebraic fold of the multiply layer | every identity a fold needs holds on 0 of 2^20 inputs on every day; k applications cost k | no shortcut |
|
||||
|
||||
Verdict: PASS with the effort bound stated: about 60 solver jobs, 2 to 29 minutes each, on three day keys; the
|
||||
reduced-round margin reached is one application fully characterised (weights 10 to 12 differential, 1 linear) and
|
||||
two applications with no trail under weight 20 to 24, three with none under 29 to 35 (differential) and 24 to 28
|
||||
(linear), four with none under 39 to 47 and 24, against 8 applications between reads, so the margin between what the
|
||||
search reaches and what the construction uses is at least 4 applications at the solver's cap. What this does not do is in section 7; the lower bound is the paid question.
|
||||
|
||||
## 6. Consequences per tier
|
||||
|
||||
No shortcut, so no tier moves: a home card, a rig and a pool pay the 72 applications per item the verifier pays;
|
||||
a chip with a fixed datapath pays them too (the fold test), which is what `chip-model-v3.md` 5.2's 9,360 ops per
|
||||
item assumes. `mixer_mult` stays 8; the verifier measurement of F6 stands unchanged.
|
||||
|
||||
## 7. What this does not do
|
||||
|
||||
- It does not bound the mixer from below: the general models are trail models (Markov for the multiply's
|
||||
differential, piling-up for the linear), and the family models are exact only inside their families. The firm's
|
||||
job (funding.md B5 rank 1) is the effort-bounded version of the same search with their tools.
|
||||
- Three days, not a census: the ROT, MUL, RC classes over 2^24 days are F4's row. One cheap addition for F4 from
|
||||
this harness: the MSB-family death at k = 2 (`model.py search --kind diff --family msb --apps 2`) runs in seconds
|
||||
per day, and a day where it does not die is a weak day of the kind the gate is about.
|
||||
- Differential and linear only, as the row says: no boomerang, no integral or cube property, no related-key (the
|
||||
round keys are public constants).
|
||||
148
docs/analysis/attack-pass/f3-cache.md
Normal file
148
docs/analysis/attack-pass/f3-cache.md
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
# F3: the chained cache's j + 1 bound and the storage-against-recompute curve
|
||||
|
||||
Attack-pass row F3 of `docs/plans/cryptanalysis.md` section 4.2 (the record is `docs/analysis/attack-pass-2026-10.md`). Run 7 October 2026, 09:10 to 09:12 UK (08:10 to 08:12 UTC in the logs), on igneum-build-1. Verdict: PASS on all three gate clauses. No line (s, j) is derivable in fewer than j + 1 block evaluations without an earlier line, by an exhaustive search over the block dependency graph extracted from the code at 64 and 1,024 lines, cross-checked by an exhaustive pebbling search over every configuration at 10 lines. The storage-against-recompute curve over cache lines is monotone from f = 1/64 to 1. The f = 1 point is unchanged.
|
||||
|
||||
## Target
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Commit | 924288d1 (the brief); the worktree HEAD moved to 11b375a0 during the run; `igneum-pow/src/memhard.rs` is byte-identical at both (blob ad42470b, `git diff --stat 924288d1 HEAD -- igneum-pow/src/memhard.rs` empty) |
|
||||
| Construction, from the code | `Cache::fill_segment`: `in_j = prev XOR (sigma || K || seg || j || tag)`, `line_j = chacha_block(in_j)` where `chacha_block(x) = ChaCha12core(x) + x`, `prev_0 = 0`, `prev_j = line_{j-1}`; 64 lines per segment, 2^16 segments, 2^26 words (256 MiB) |
|
||||
| Reads | `derive_items_mask`: 8 dependent reads per item at line index `s[0] AND mask`, so the segment and j of a read are uniform over the 2^22 lines (F8 checks the uniformity) |
|
||||
| Known-failed shape | a line (s, j) computable in fewer than j + 1 block evaluations without an earlier line of segment s (the address-steering shape of the MTP break, Dinur and Nadler 2017, needs a data-dependent chain; this chain's inputs are fixed by the key, so the shape to search is a structural shortcut on the dependency graph) |
|
||||
| Gate | no derivation under j + 1 blocks; the curve monotone; the f = 1 point unchanged |
|
||||
| Prior evidence | none to re-gate: the `ca2-cache` branch named in the status board is the hot-table experiment (`docs/plans/hot-table.md`), not a chain analysis |
|
||||
|
||||
## Method
|
||||
|
||||
The model is the code, not the prose. `tools/attack/f3-cache/src/main.rs` runs one chain function, written in the shape of `memhard.rs` (the quarter round, the 6 double rounds, the feed-forward, the prev XOR, the constant block), generically over two word types:
|
||||
|
||||
| Word type | What it computes | Use |
|
||||
|---|---|---|
|
||||
| `u32` | the real arithmetic | `verify`: bit-exact against `Cache::fill_segment` on 16 (key, segment) pairs and against `chacha_block` on 100,000 random inputs |
|
||||
| taint set | which block outputs a value depends on (add, xor, rotate = union) | `search`: the direct-parent graph of every block, with each computed line relabelled to the single node {j} so parents are direct, not transitive; plus the 16 x 16 (output word, input word) dependency matrix of one block |
|
||||
|
||||
The exhaustive search: for every target line j, the minimum number of block evaluations with nothing stored is the size of the backward closure of j on the extracted graph (every non-stored block in the closure must be evaluated at least once; once each in dependency order suffices). `pebble` checks that formula against an exhaustive 0-1 BFS over every pebble configuration (place on a node whose parents are pebbled at cost 1, remove at cost 0) for all 2^10 stored sets x 10 targets on each of the three graphs: 10,240 pairs per graph, 0 mismatches. Two deliberately broken chains are the known-fail cases: `skip2` (line j fed from line j - 2) and `nofeed` (no previous line fed in). The curve: for f = 1/64 to 1 (fraction of cache LINES held), the blocks per read on the naive pattern of `funding.md` B2 rank 2 (every L/n-th line from line 0) and on the optimal pattern (exact DP over chunk lengths; brute force over every C(64, n) set for n up to 8, 4,426,165,368 sets at n = 8); ops per item = 9,360 mixer ops (chip-model-v3.md 5.2) + 8 reads x blocks per read x ops per block (608 counted from the code: 48 quarter rounds x 12, 16 feed-forward adds, 16 input XORs; also at MEMHARD.md's approximate 700). Three more checks on the real function: single-bit avalanche and a differential-independence test on `chacha_block`, a census of every line of the real 2^22-line cache for the day key 2026-10-03, and one-core timings of a block, a mixer application, an item and a line recompute.
|
||||
|
||||
## Harness
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Crate | `/Users/joshm/Projects/igneum-wt-attack/tools/attack/f3-cache/` (`Cargo.toml` with `igneum-pow = { path = "../../../igneum-pow" }` and an empty `[workspace]`; `src/main.rs`; `run-box.sh`) |
|
||||
| Build | `cd tools/attack/f3-cache && IGNEUM_AGENT=attack-f3 IGNEUM_TOOLCHAIN_MISMATCH=ok bash /Users/joshm/Projects/igneum/tools/build-remote.sh --artefacts "target/release/attack-f3" --out <scratchpad>/attack-f3 -- build --release` (rc 0, 38 s wall, 0 warnings; the Mac's PATH rustc is 1.69 but `~/.cargo/bin/rustc` is 1.99.0, which the script read as "on both sides"; log `<scratchpad>/attack-f3/build-1.log`) |
|
||||
| Binary | box `/srv/builds/igneum-wt-attack/tools/attack/f3-cache/target/release/attack-f3`, sha256 975115a385ca3195...71cc33, 563,104 bytes |
|
||||
| Run | on the box: `nohup bash run-box.sh r1 > run-r1.log 2>&1 &` from `/srv/builds/igneum-wt-attack/attack-f3/`; every phase as `flock -s /srv/builds/_locks/measure -c "nice -n 10 taskset -c 12-15,60-63 attack-f3 <cmd>"`, one chunk per phase, the whole run 17 s (08:10:58 to 08:11:15 UTC; box load 54 at start) |
|
||||
| Phase lines | `verify`; `search --lines 64|1024 --variant real|skip2|nofeed`; `pebble --lines 10`; `store --lines 64 --brute-max 8`; `store --lines 1024 --brute-max 2`; `curve --lines 64`; `curve --lines 64 --ops-block 700`; `curve --lines 1024`; `avalanche --samples 1048576`; `census --day 2026-10-03`; `bench --n 20000000` |
|
||||
| Logs | box `/srv/builds/igneum-wt-attack/attack-f3/run-r1.log` and `r1-<phase>.log`; Mac copies `/private/tmp/claude-501/-Users-joshm/cd75457f-4858-4f86-9634-7481ee056b7b/scratchpad/attack-f3/` |
|
||||
|
||||
Box hygiene: the box checkout of every `build-remote.sh` run on this worktree executes `git clean -fd` at `/srv/builds/igneum-wt-attack` (remote-run.sh `checkout_tree`), which deletes any untracked scratch directory there. `attack-f3/` and `attack-f3-venv/` are listed in that mirror's `.git/info/exclude` so they survive; nothing in the tree was touched. The F1 lane's `attack-f1-venv/` is untracked and unprotected and will be removed by the next build from any agent on this worktree.
|
||||
|
||||
## The two firings and the pass
|
||||
|
||||
| Chain | Direct parents (taint trace) | Lines under j + 1 at 64 lines | Cheapest derivations | Exhaustive pebbling at 10 lines, cost per target | Verdict | Log |
|
||||
|---|---|---|---|---|---|---|
|
||||
| real (the code) | j - 1 for all 63 lines after line 0 | 0 of 64 | none; every line costs exactly j + 1 (mean 32.5) | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 | PASS | `r1-search-real-64.log`, `r1-pebble-10.log` |
|
||||
| real, 1,024-line model | j - 1 for all 1,023 lines after line 0 | 0 of 1,024 | none (mean 512.5) | same graph rule | PASS | `r1-search-real-1024.log` |
|
||||
| skip2 (known fail A) | j - 2 for 62 lines, none for 2 | 63 of 64 | j = 1 in 1, j = 63 in 32 (mean 16.5) | 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 | FIRE | `r1-search-skip2-64.log`, `r1-search-skip2-1024.log` |
|
||||
| nofeed (known fail B) | none for all 64 | 63 of 64 | every line in 1 block (mean 1.0) | 1 x 10 | FIRE | `r1-search-nofeed-64.log`, `r1-search-nofeed-1024.log` |
|
||||
|
||||
`verify` (`r1-verify.log`): the model chain equals `Cache::fill_segment` on keys {day 2026-10-03, 3 random} x segments {0, 1, 12345, 65535} (16 of 16), `block == chacha_block` on 100,000 of 100,000 random inputs, the 1,024-line model's first 64 lines equal the 64-line chain, and both broken variants differ from the real chain from line 1 (line 0 equal, as the rule predicts). The block's word dependency matrix is full on every variant (256 of 256 pairs), so the firings come from the chain rule alone.
|
||||
|
||||
## Derivation cost per line on the model segment (real chain, nothing stored)
|
||||
|
||||
| j | blocks to derive line j | j + 1 | Log |
|
||||
|---|---|---|---|
|
||||
| 0 | 1 | 1 | `r1-search-real-1024.log` |
|
||||
| 1 | 2 | 2 | |
|
||||
| 3 | 4 | 4 | |
|
||||
| 7 | 8 | 8 | |
|
||||
| 15 | 16 | 16 | |
|
||||
| 31 | 32 | 32 | |
|
||||
| 63 | 64 | 64 | (the last line of a real segment; `r1-search-real-64.log` lists all 64) |
|
||||
| 127 | 128 | 128 | |
|
||||
| 255 | 256 | 256 | |
|
||||
| 511 | 512 | 512 | |
|
||||
| 1,023 | 1,024 | 1,024 | |
|
||||
|
||||
All 1,024 lines were searched (0 under j + 1, mean 512.5 = (L + 1) / 2); the 64-line table in `r1-search-real-64.log` has every j from 0 to 63 at exactly j + 1.
|
||||
|
||||
## Store patterns on the real 64-line segment
|
||||
|
||||
Blocks per read averaged over j uniform in 0..63. "Naive" is `funding.md` B2 rank 2's pattern (every k-th line from line 0). "Optimal" is the exact minimum over store sets of that size (DP; brute force over every set for n up to 8, agreeing with the DP on every row it ran). The gap formula equals the closure cost on the extracted graph on 2,000 of 2,000 random stored sets (`r1-store-64.log`).
|
||||
|
||||
| f | Stored lines n | SRAM held | Naive blocks per read | Optimal positions | Optimal blocks per read | Brute force over C(64, n) sets |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1/64 | 1 | 4 MiB | 31.5 | [32] | 16.0 | 16.0 (64 sets) |
|
||||
| 1/32 | 2 | 8 MiB | 15.5 | [21, 43] | 10.5 | 10.5 (2,016 sets) |
|
||||
| 1/16 | 4 | 16 MiB | 7.5 | [12, 25, 38, 51] | 6.094 | 6.094 (635,376 sets) |
|
||||
| 1/8 | 8 | 32 MiB | 3.5 | [7, 15, 22, 29, 36, 43, 50, 57] | 3.172 | 3.172 (4,426,165,368 sets, 11.2 s) |
|
||||
| 1/4 | 16 | 64 MiB | 1.5 | [3, 7, 11, ..., 55, 58, 61] | 1.453 | not run (DP exact) |
|
||||
| 1/2 | 32 | 128 MiB | 0.5 | odd lines | 0.5 | not run |
|
||||
| 1 | 64 | 256 MiB | 0 | all | 0 | not run |
|
||||
|
||||
The 1,024-line model (`r1-store-1024.log`) gives 29.68 / 15.05 / 7.40 / 3.48 / 1.50 / 0.5 / 0 at the same f on the optimal pattern: the naive and optimal patterns converge as the chain lengthens, because the wasted stored line 0 and the end effects are a smaller share.
|
||||
|
||||
## The curve: ops per item against the fraction of cache lines held (real 64-line segment)
|
||||
|
||||
Ops per item = 9,360 (the 72 mixer applications, hoisted, plus the fold: chip-model-v3.md 5.2) + 8 reads x blocks per read x ops per block. `r1-curve-64.log` (608 ops per block, counted) and `r1-curve-64-memhard.log` (700, MEMHARD.md item 4). Ops per hash = 128 x ops per item + 512. MH/s at the chip model's 50 T op/s budget (approximate, chip-model-v3.md section 1).
|
||||
|
||||
| f (lines held) | SRAM | Blocks per read, naive / optimal | Ops per item, naive, 608 | Ops per item, optimal, 608 | Ops per item, optimal, 700 | Ops per hash, optimal, 608 | MH/s at 50 T op/s, optimal, 608 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 1/64 | 4 MiB | 31.5 / 16.0 | 162,576 | 87,184 | 98,960 | 11,160,064 | 4.5 |
|
||||
| 1/32 | 8 MiB | 15.5 / 10.5 | 84,752 | 60,432 | 68,160 | 7,735,808 | 6.5 |
|
||||
| 1/16 | 16 MiB | 7.5 / 6.094 | 45,840 | 39,000 | 43,485 | 4,992,512 | 10.0 |
|
||||
| 1/8 | 32 MiB | 3.5 / 3.172 | 26,384 | 24,788 | 27,122 | 3,173,376 | 15.8 |
|
||||
| 1/4 | 64 MiB | 1.5 / 1.453 | 16,656 | 16,428 | 17,498 | 2,103,296 | 23.8 |
|
||||
| 1/2 | 128 MiB | 0.5 / 0.5 | 11,792 | 11,792 | 12,160 | 1,509,888 | 33.1 |
|
||||
| 1 | 256 MiB | 0 / 0 | 9,360 | 9,360 | 9,360 | 1,198,592 | 41.7 |
|
||||
|
||||
Monotone: ops per item is non-increasing in f on both patterns at both op counts and on the 1,024-line model (`CURVE ... monotone non-increasing` in all three curve logs). The f = 1 point: 9,360 ops per item, 1,198,592 ops per hash, 41.7 MH/s at 50 T op/s, which is the chip-model-v3.md section 5.4 row "none, f = 0" of the published ITEM curve (the on-die-cache recompute chip of sections 1 to 3). The published item curve stores dataset ITEMS and is a different curve: its f = 1 point (GDDR7, 166.4 MH/s, 0.466 microjoules per hash) contains no cache read and no mixer op, so nothing in this row touches it. `funding.md` B2 rank 2's arithmetic reproduces on the naive pattern at 700 ops per block: 3.5 blocks per read, 2,450 ops per line, 19,600 per item on top of the mixer, 13.5 MH/s (50 T / (128 x 28,960 + 512)).
|
||||
|
||||
## Measured times, one box core (`r1-bench.log`, `r1-census.log`; nice 10, cores 12-15,60-63, box load 54)
|
||||
|
||||
| What | Measured | Note |
|
||||
|---|---|---|
|
||||
| One ChaCha12 block, dependent chain of 20,000,000 | 66.64 ns | |
|
||||
| One mixer application (class v4 parameters), dependent chain of 20,000,000 | 17.29 ns | block / application = 3.85 (counted ops 608 / 128 = 4.75) |
|
||||
| One item against the 256 MiB cache, batches of 32 | 1,326 ns | 72 applications = 1,245 ns; the 8 dependent reads and the fold add 81 ns because the batch overlaps them |
|
||||
| One line recomputed from nothing, 312,500 random (seg, j) | 2,734 ns | 32.5 blocks per line on average, 84.1 ns per block inside the chain |
|
||||
| The 256 MiB cache fill, one thread | 0.36 to 0.4 s | 86 ns per block with the writes |
|
||||
|
||||
In measured time, holding every 8th line at the optimal placement makes an item cost 72 + 8 x 3.172 x 3.85 = 170 mixer-application equivalents against 72, a 2.36x penalty per item (2.65x in counted ops). Holding one line in 64 costs 72 + 8 x 16 x 3.85 = 565, a 7.8x penalty.
|
||||
|
||||
## Checks on the real function (`r1-avalanche.log`, `r1-census.log`)
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| Single-bit avalanche of `chacha_block`, 1,048,576 flips | mean 256.00 of 512 output bits change (ideal 256), min 200, max 312 |
|
||||
| (output word, input word) pairs where an output word did not change | worst count 0 of 1,048,576 |
|
||||
| Chain step: one bit of line j - 1 flipped | line j changes 255.96 bits, line j + 1 changes 255.94 (131,072 flips) |
|
||||
| Differential independence: B(x ^ d) ^ B(x) == B(y ^ d) ^ B(y) over 262,144 (x, y, single-bit d) | 0 cases |
|
||||
| Census of the real cache, day key 2026-10-03 | 4,194,304 of 4,194,304 lines distinct, 0 all-zero lines: no two chains merge and no block input repeats |
|
||||
|
||||
## Gate
|
||||
|
||||
| Clause | Result | Where |
|
||||
|---|---|---|
|
||||
| No derivation under j + 1 blocks | 0 of 64 and 0 of 1,024 lines under j + 1 on the extracted graph; the formula exact on 10,240 of 10,240 exhaustive pebbling cases; both known-fail chains fire | `r1-search-real-64.log`, `r1-search-real-1024.log`, `r1-pebble-10.log` |
|
||||
| The curve monotone | non-increasing on both patterns, both op counts, both segment lengths | the three `r1-curve-*.log` |
|
||||
| The f = 1 point unchanged | 9,360 ops per item = chip-model-v3.md 5.4 "none, f = 0" row; the item curve's GDDR7 f = 1 row (166.4 MH/s, 0.466 microjoules) untouched | `r1-curve-64.log` |
|
||||
|
||||
Verdict: PASS.
|
||||
|
||||
## Observations that are not findings
|
||||
|
||||
| Observation | Number | What it means | What I propose |
|
||||
|---|---|---|---|
|
||||
| `funding.md` B2 rank 2 prices the honest trade-off at the naive placement | 3.5 blocks per read at f = 1/8 against 3.17 optimal (9.4 percent less); 31.5 against 16.0 at f = 1/64 (2.0x less, because storing line 0 is worthless: it costs 1 block anyway) | the chip at f = 1/8 reads 15.8 MH/s (608 ops per block, optimal placement) or 14.4 (700, optimal) against `funding.md`'s 13.5 (700, naive); still 0.38x of the full SRAM mirror's 41.7 and 0.12x of the 5090's 136.1 (chip-model-v3.md section 2); the curve stays monotone, so the published verdict (the partial chip is not the threat, the full mirror beats it) stands | one sentence in `funding.md` B2 rank 2: "holding every 8th line at the best placement costs 3.2 blocks per read (3.5 for every 8th line from line 0)". Not edited here: outside this row's two files; for main to serialise |
|
||||
| The chain's hardness per line is sequential time, not memory | one pebble (64 bytes) over j + 1 steps: the cumulative memory of deriving a line is about 64 x (j + 1) byte-steps | the chain protects the cache by op count, which is exactly what the curve prices in ops; parallel attackers pipeline items and pay E(f) x 608 ops per read in throughput, E(f) block latencies in latency; a chip that holds nothing (f = 0) pays 32.5 x 608 = 19,760 ops per read, 158,080 per item, 167,440 with the mixer (17.9x the mixer alone), 2.3 MH/s at 50 T op/s | nothing to move; the public model should keep quoting ops, never bytes, for this piece |
|
||||
| What this row does not cover | a cryptanalytic shortcut inside `chacha_block` in this chaining mode (the differential and avalanche tests are sanity checks, not a bound) | the paid engagement's rank 2 question (`funding.md` B2) stays worth the money; plan 4.2 says the internal pass cannot prove the chain's trade-off curve | none |
|
||||
|
||||
## Consequences per user tier
|
||||
|
||||
| Tier | What this row changes |
|
||||
|---|---|
|
||||
| Home miner, one 8 / 12 / 16 / 24 or 32 GB card, any vendor, any OS | nothing: the honest miner holds the dataset, the verifier holds the 256 MiB cache; no memory, hash rate, or power figure moves |
|
||||
| Rig, pool user | nothing |
|
||||
| Chip builder | the partial-cache chip is priced 9 percent better at f = 1/8 and 2x better at f = 1/64 than `funding.md` says, and is still worse than the full SRAM mirror at every f below 1; the public per-joule sentence (evidence row 17, 2.1x at k = 1) rests on the item curve's f = 1 point, which this row leaves untouched |
|
||||
| The paid review | the firm receives this record and the harness; rank 2's open question is the block function in chaining mode, not the graph |
|
||||
309
docs/analysis/attack-pass/f4-weakday.md
Normal file
309
docs/analysis/attack-pass/f4-weakday.md
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
# F4. The weak-day census: 2^24 day keys through `MixParams::with_shape`
|
||||
|
||||
Attack pass row F4 (`docs/plans/cryptanalysis.md` section 4.2; the gate is section 1.4 (3) and `funding.md` B5
|
||||
rank 3; the threat is `funding.md` B2 rank 3). Run 7 October 2026, 09:10 to 09:55 UK, on igneum-build-1 by the
|
||||
attack-f4 agent (the verifier timing row of 6.6 queued behind other lanes' holds). Every number below cites its log.
|
||||
|
||||
## Verdict
|
||||
|
||||
**PASS on the gate read against M2, the DSP-bound per-day datapath (0 days over 1.1x in 2^28), and on every named
|
||||
weak class; the generous bound M1 (every multiply in LUT adders) exceeds the gate at 3.26e-4 of days as the tail of a
|
||||
sum, not a class, and is routed to main as a bound finding with a rejection-and-redraw rule for the next class.
|
||||
Class v4 is not changed.**
|
||||
|
||||
Which metric the 1.1x gate reads against, and why: M2. The gate (plan 1.4 (3)) asks for the fraction of days in a
|
||||
weak class, and M1's excess has no class behind it (section 6.2: the exact 16-fold convolution of one random NAF
|
||||
weight predicts the census to 0.6 percent). A per-day FPGA attacker who builds the 16 multiplies in LUT shift-add
|
||||
trees is building the slower design: those trees are 72 percent of M1's cost (167 of 231 adders), and DSP blocks
|
||||
take that cost off the fabric, so the design that wins is DSP-bound, where the day's constants move nothing unless a
|
||||
word has NAF weight at most 3, which happens on no day in 2^28 for two words. M1 is still reported in full because
|
||||
the brief asks for the generous bound, and because a two-line rule closes it for nothing.
|
||||
|
||||
| Metric | Days over 1.1x in 2^24 | Fraction | Days over 1.1x in 2^28 | Fraction | Gate 2^-20 = 9.54e-7 | Log |
|
||||
|---|---|---|---|---|---|---|
|
||||
| M1: per-day LUT datapath, adders per mixer application, against the census median | 5,476 | 3.264e-4 | 87,426 | 3.257e-4 | OVER, by 342x | `census-2p24.md`, `census-2p28.md` gate table |
|
||||
| M1 exact expectation (16-fold convolution of the NAF-weight table over all 2^31 odd constants) | 5,441 | 3.243e-4 | | | the census is the tail of a smooth sum, not a class | `expect-231.log` last line |
|
||||
| M2: DSP-bound datapath, 16/(16 - k), k = words of NAF weight at most 3 | 0 | 0 | 0 | 0 | under | `census-2p24.md`, `census-2p28.md` M2 table |
|
||||
| ROT value and RC value on a per-day datapath | 0 | 0 | 0 | 0 | under (exact 0 ops moved, section 3) | section 3 |
|
||||
|
||||
The gate as written fails under M1 only. What M1 finds is not a weak class: the per-day cost of the 16 constant
|
||||
multipliers is a sum of 16 NAF weights (mean 231.1 adder-equivalents per application, sd 6.19), and 1 day in 3,070
|
||||
sits 3.4 sigma below the median, where a bitstream synthesised for that day pays 10 to 19 percent fewer adders. The
|
||||
worst day in 2^28 reads 1.19x (day 27,952,752, cost 194). The exact expectation predicts the census to 0.6 percent.
|
||||
Section 7 prices the consequence (0.004 percent more hashes a year for an all-LUT FPGA that re-synthesises every
|
||||
day, nothing for a chip or a GPU) and section 8 gives the rejection-and-redraw rule that closes it.
|
||||
|
||||
## 1. Target
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Commit | 924288d1 (the brief); the worktree HEAD moved to 11b375a0 during the pass (F5 and F6 records); `git diff 924288d1 11b375a0 --stat -- igneum-pow/src` is empty, so the target code is the same |
|
||||
| Code | `igneum-pow/src/memhard.rs` `MixParams::with_shape` (lines 189 to 215): `SplitMix64::new(key[0] as u64 \| (key[1] as u64) << 32)`, then `ROT[0..7] = 1 + below(31)`, `MUL[0..15] = next() as u32 \| 1`, `RC[0..15] = next() as u32`; no rejection rule |
|
||||
| Day key | `bind::day_bytes(d) = "igneum-day/" \|\| d_le64`, `key = seed_words_from_bytes(day_bytes)` (the interim day rule, `bind.rs` lines 30 to 68); the genesis day index is 20,729 (`bind.rs` test `day_bytes_layout`) |
|
||||
| Shape | `Shape::for_class(&V4_CLASS)`: mixer x8, cache 2^26 words, no derivation program (asserted by the harness) |
|
||||
| Mixer | `memhard::mixer`: per word `(s ^ (RC + rk)) * MUL`, then one ChaCha double round with `ROT[0..3]` on the columns and `ROT[4..7]` on the diagonals; 72 applications per item under x8 |
|
||||
| Census set | 2^24 consecutive chain days from 20,729 (the gate run), and 2^28 (the extended run); the first 36,525 of them are the chain's public calendar for the next 100 years under the interim rule |
|
||||
|
||||
The 64-bit seeding fact (F7 covers the spec's intent): the 40 draws depend on `key[0] | key[1] << 32` alone, so the
|
||||
stream can produce at most 2^64 distinct parameter sets whatever the key's other 192 bits hold. Over the 2^24 census
|
||||
days the 64-bit seeds were all distinct (0 collisions, expected 7.6e-6; `census-2p24.md` "64-bit seeding" line).
|
||||
`below(31)` is `next() % 31` without rejection: the bias per rotation value is 2^-64 and is ignored.
|
||||
|
||||
## 2. Known-failed shape
|
||||
|
||||
A day key whose drawn `ROT`, `MUL` or `RC` gives a fixed datapath a gain over 1.1x: all-equal `ROT` (31^-7 per day,
|
||||
MEMHARD.md section 3 item 3, untested until now), `MUL = 1` (2^-31 per word), pairs summing to 32, small rotation
|
||||
amounts, low-weight multipliers, `RC + rk = 0`.
|
||||
|
||||
## 3. The gain metrics (exact, structural)
|
||||
|
||||
The verifier and every GPU run the same instructions on every day (`rotate_left` by a register amount, `wrapping_mul`,
|
||||
no branch on a drawn value), so wall time cannot move with the draw; the only attacker a weak day helps is one who
|
||||
builds the day's constants into logic. That is an FPGA bitstream synthesised per day (hours of compile against a
|
||||
public calendar), never a taped-out chip. Costs are in 32-bit adder-equivalents per mixer application:
|
||||
|
||||
| Element of one application | Generic datapath | Per-day datapath |
|
||||
|---|---|---|
|
||||
| 16 x `s ^ (RC + rk)` | 16 | 0 (constant XOR: inverters, absorbed into the next LUT) |
|
||||
| 16 x `* MUL` | 16 multipliers (value-independent) | M1: `NAF(MUL_i) - 1` adders each (canonical signed-digit shift-add); M2: a DSP block each, value-independent, except a word of NAF weight at most 3 moves to 2 LUT adders and frees its DSP |
|
||||
| 8 quarter rounds: 32 adds, 32 XORs | 64 | 64 |
|
||||
| 32 rotations | 32 barrel shifters | 0 (wiring) |
|
||||
|
||||
* **M1** `cost = 64 + sum_i (NAF(MUL_i) - 1)`; gain of a day = census median cost / the day's cost. The generous
|
||||
bound: optimal single-constant multiplication is below NAF for every constant and the ratio between days is what
|
||||
is measured.
|
||||
* **M2** gain = `16 / (16 - k)` on a DSP-bound design, k the words of NAF weight at most 3.
|
||||
* **ROT** and **RC** hand a per-day datapath exactly 0 ops at any value (wiring and inverters); on a generic
|
||||
datapath a rotation costs the same at every amount and `RC + rk = 0` removes one XOR of 10,368 ops per item
|
||||
(1.0001x). They are censused as structure, and the worst members are measured for diffusion (section 6), the
|
||||
only other thing a rotation draw could move; a bit-exact verifier never lets a chip skip an application, so
|
||||
diffusion is reported and is not a gain.
|
||||
|
||||
## 4. Harness
|
||||
|
||||
| Item | Path or line |
|
||||
|---|---|
|
||||
| Crate | `tools/attack/f4-weakday/` (`Cargo.toml` with `igneum-pow = { path = "../../../igneum-pow" }` and an empty `[workspace]`; `src/main.rs`); `igneum-pow` untouched |
|
||||
| Build | `cd tools/attack/f4-weakday && IGNEUM_AGENT=attack-f4 bash /Users/joshm/Projects/igneum/tools/build-remote.sh --artefacts "target/release/attack-f4" --out <scratch> -- build --release`; box binary `/srv/builds/igneum-wt-attack/tools/attack/f4-weakday/target/release/attack-f4`: sha256 `fda006d7...835f52` ran every census and firing (`build-1.log`); the rebuild `5eb081cf...7f0355` (`build-2.log`) removes one unused import and nothing else |
|
||||
| Unit tests | `build-remote.sh --no-fetch -- test --release` on the box (`test-1.log`): 2 passed, 0 failed (`naf_weights`: 0, 1, 3, 7, 2^32 - 1, the alternating maximum 17, and the planted weight-3 constant; `genesis_day_draw_matches_memhard_md`: the string day `2026-10-03` draws `ROT 20 20 19 4 26 3 3 27`, MEMHARD.md section 1.1, through the same `with_shape` path the census uses) |
|
||||
| Census (gate) | `flock -s /srv/builds/_locks/measure -c 'nice -n 10 taskset -c 16-21,64-69 attack-f4 census --from 20729 --count 16777216 --threads 12 --dedupe --out census-2p24.md'`; 4.2 s |
|
||||
| Census (extended) | the same with `--count 268435456 --out census-2p28.md`; 68.6 s |
|
||||
| Expectation tables | `attack-f4 expect --threads 12 --median 231` (every odd 32-bit constant: NAF weight and popcount, then the 16-fold convolution); 14.9 s |
|
||||
| One day | `attack-f4 day --index <d> --median 231` |
|
||||
| Firings | `attack-f4 plant alleq\|mul1\|mul1all\|mulnaf\|rc0\|rcrk0 --median 231` (the day 20,729 draw with one field forced through the crate's own hook) |
|
||||
| Diffusion | `attack-f4 avalanche --index <d> --states 2048 [--plant-alleq r]` |
|
||||
| Timing (exclusive hold) | `timing.sh` on the box under nohup: `flock -x -w 7200 /srv/builds/_locks/measure -c 'nice -n 19 taskset -c 16,64 igneum-pow bench --seed x --epoch-hex edc4fa84...fb07 --day-hex <day bytes> --program-class v4 --warps 100'` for day 20,729 and the worst day, A B A B. Process note: withdrawing the first attempt, one ad hoc ssh line used `pkill -f "<literal>"`, the banned shape, and killed its own shell (self-match); the relaunch used the bracket form. Nothing else was touched |
|
||||
| Calendar | `attack-f4 census --from 20729 --count 36525 --threads 12 --out census-100y.md` (the chain's first 100 years) |
|
||||
| Box logs | `/srv/builds/igneum-wt-attack/attack-f4/{run2.log, census-2p24.md, census-2p28.md, census-100y.md, expect-231.log, firings.log, avalanche.log, timing.log}` |
|
||||
| Mac copies | `/private/tmp/claude-501/-Users-joshm/cd75457f-4858-4f86-9634-7481ee056b7b/scratchpad/attack-f4/box/` (the box directory was deleted once from under the pass at about 09:14 UK by another agent's worktree sync; everything was re-run and copied to the Mac the moment it ended; the re-run reproduced the first run line for line) |
|
||||
|
||||
## 5. The two firings (`firings.log`)
|
||||
|
||||
| Case | Classifier | Gain | Result |
|
||||
|---|---|---|---|
|
||||
| Known-pass: day 20,729 (the genesis day), `ROT [6, 25, 5, 25, 29, 11, 9, 21]`, NAF sum 178 | no weak class (only "pair sums to 32", 12 and 60 percent of all days) | M1 0.978x, M2 1.000x | passes, as it must |
|
||||
| Known-fail: `plant mul1all` (all 16 `MUL = 1`) | `MUL any = 1` FIRED | M1 3.453x, M2 unbounded | FIRED over 1.1x |
|
||||
| Known-fail: `plant mulnaf` (four words at NAF weight 3) | `MUL any NAF weight <= 3` FIRED | M1 1.145x, M2 1.333x | FIRED over 1.1x |
|
||||
| `plant mul1` (one word `MUL = 1`) | `MUL any = 1` FIRED | M1 1.023x, M2 1.067x | flagged, under the gate: one word of 16 |
|
||||
| `plant alleq` (`ROT` all 7) | `ROT all equal` FIRED | M1 0.978x (0 ops moved) | flagged; diffusion in section 6 |
|
||||
| `plant rc0`, `plant rcrk0` | `RC any = 0`, `RC + rk = 0` FIRED | M1 0.978x (0 ops moved) | flagged |
|
||||
|
||||
## 6. Numbers
|
||||
|
||||
### 6.1 Classes over 2^24 days (`census-2p24.md`), with the 2^28 count (`census-2p28.md`)
|
||||
|
||||
Expected per day is analytic (independent draws); the NAF rows come from the exact table of `expect-231.log`.
|
||||
|
||||
| Class | Count 2^24 | Fraction | Expected per day | Expected count 2^24 | Count 2^28 | Worst member (day, M1 cost, M1 gain, M2 gain) |
|
||||
|---|---|---|---|---|---|---|
|
||||
| ROT all equal | 0 | 0 | 3.64e-11 (31^-7) | 0.001 | 0 | none |
|
||||
| ROT distinct <= 3 | 534 | 3.18e-5 | 3.07e-5 | 515 | 8,229 | 2^28: day 49,986,853, 206, 1.121x, 1.000x |
|
||||
| ROT distinct <= 4 | 26,010 | 1.55e-3 | 1.54e-3 | 25,783 | 412,698 | 2^28: day 208,103,482, 197, 1.173x, 1.000x |
|
||||
| ROT max multiplicity >= 4 | 35,631 | 2.12e-3 | 2.35e-3 (first order) | 39,421 | 568,423 | 2^28: day 115,569,197, 200, 1.155x, 1.000x |
|
||||
| ROT same-word pair sums to 32 | 2,062,481 | 0.1229 | 0.1229 | 2,062,288 | 32,997,484 | 2^28: day 97,502,921, 196, 1.179x, 1.000x |
|
||||
| ROT any pair sums to 32 | 10,022,037 | 0.5974 | 0.6007 (approx., pairs not independent) | 10,078,561 | 160,353,891 | 2^28: day 27,952,752, 194, 1.191x, 1.000x |
|
||||
| ROT all 8 in {1, 2, 30, 31} | 2 | 1.19e-7 | 7.68e-8 | 1.29 | 19 | day 14,330,190, 217, 1.064x, 1.000x |
|
||||
| ROT >= 6 in {1, 2, 30, 31} | 1,761 | 1.05e-4 | 1.02e-4 | 1,716 | 27,651 | 2^28: day 181,528,254, 204, 1.132x, 1.000x |
|
||||
| ROT >= 4 in {8, 16, 24} | 74,541 | 4.44e-3 | 4.46e-3 | 74,756 | 1,196,376 | day 5,517,722, 198, 1.167x, 1.000x |
|
||||
| MUL any = 1 | 0 | 0 | 7.45e-9 | 0.125 | 4 | 2^28: day 196,441,106, 221, 1.045x, 1.067x |
|
||||
| MUL any = 2^32 - 1 | 0 | 0 | 7.45e-9 | 0.125 | 1 | 2^28: day 39,988,645, 215, 1.074x, 1.067x |
|
||||
| MUL any popcount <= 2 | 0 | 0 | 2.38e-7 | 4.0 | 57 | 2^28: day 218,029,468, 209, 1.105x, 1.067x |
|
||||
| MUL any popcount <= 4 | 612 | 3.65e-5 | 3.72e-5 | 624 | 10,132 | day 7,275,755, 200, 1.155x, 1.000x |
|
||||
| MUL any NAF weight <= 2 | 4 | 2.38e-7 | 4.62e-7 | 7.75 | 125 | 2^28: day 63,704,833, 205, 1.127x, 1.067x |
|
||||
| MUL any NAF weight <= 3 | 216 | 1.29e-5 | 1.30e-5 | 218 | 3,515 | 2^28: day 247,161,685, 200, 1.155x, 1.067x |
|
||||
| MUL any NAF weight <= 4 | 3,637 | 2.17e-4 | 2.20e-4 | 3,683 | 58,667 | 2^28: day 81,133,010, 198, 1.167x, 1.000x |
|
||||
| MUL any < 256 | 22 | 1.31e-6 | 9.54e-7 | 16 | 262 | 2^28: day 241,187,962, 203, 1.138x, 1.067x |
|
||||
| MUL two equal | 0 | 0 | 5.59e-8 | 0.94 | 18 | 2^28: day 223,900,428, 226, 1.022x, 1.000x |
|
||||
| MUL M2 k >= 2 (gain >= 1.143x) | 0 | 0 | 7.9e-11 (C(16,2) x (8.12e-7)^2, approx.) | 0.0013 | 0 | none |
|
||||
| RC any = 0 | 0 | 0 | 3.73e-9 | 0.062 | 1 | 2^28: day 109,542,046, 243, 0.951x, 1.000x |
|
||||
| RC any popcount <= 4 or >= 28 | 5,186 | 3.09e-4 | 3.09e-4 | 5,180 | 82,804 | 2^28: day 53,303,116, 206, 1.121x, 1.000x |
|
||||
| RC + rk = 0 for any of the 72 keys | 10 | 5.96e-7 | 2.68e-7 | 4.5 | 87 | day 3,194,363, 218, 1.060x, 1.000x |
|
||||
| RC two equal | 1 | 5.96e-8 | 2.79e-8 | 0.47 | 8 | 2^28: day 182,857,055, 222, 1.040x, 1.000x |
|
||||
|
||||
Every class sits at its expectation (the largest deviation, "ROT max multiplicity >= 4", is against a first-order
|
||||
bound). The worst member of every class owes its gain to its MUL draw (M1 is a MUL-only quantity); the class itself
|
||||
moves nothing. No day in 2^28 has two words of NAF weight at most 3, so M2 never exceeds 1.067x.
|
||||
|
||||
### 6.2 The M1 tail: census against the exact expectation (`census-2p24.md`, `expect-231.log`)
|
||||
|
||||
| M1 cost per application | Gain vs median 231 | Days in 2^24 | Cumulative fraction, census | Cumulative fraction, exact |
|
||||
|---|---|---|---|---|
|
||||
| 197 (the 2^24 minimum, day 4,819,563) | 1.173x | 1 | 5.96e-8 | 8.18e-8 |
|
||||
| 200 | 1.155x | 10 | 8.34e-7 | 8.62e-7 |
|
||||
| 205 | 1.127x | 250 | 2.94e-5 | 2.87e-5 |
|
||||
| 208 | 1.111x | 1,382 | 1.84e-4 | 1.83e-4 |
|
||||
| 209 | 1.105x | 2,387 | 3.26e-4 | 3.24e-4 |
|
||||
| 210 | 1.100x | 3,887 | 5.58e-4 | 5.64e-4 |
|
||||
| 231 (median) | 1.000x | 1,079,174 | 0.522 | 0.522 |
|
||||
|
||||
Mean cost 231.113 (exact 231.111), sd 6.190 (exact 6.190). The 2^28 minimum is 194 (1.191x, day 27,952,752). A
|
||||
single NAF weight has mean 11.44 and sd 1.55 over the 2^31 odd constants (`expect-231.log`).
|
||||
|
||||
### 6.3 ROT structure (`census-2p24.md` histograms)
|
||||
|
||||
| Distinct rotation amounts a chip must wire | Days in 2^24 | Fraction | Expected S(8,d) 31_d / 31^8 |
|
||||
|---|---|---|---|
|
||||
| 1 | 0 | 0 | 3.63e-11 |
|
||||
| 2 | 4 | 2.4e-7 | 1.4e-7 |
|
||||
| 3 | 530 | 3.16e-5 | 3.05e-5 |
|
||||
| 4 | 25,476 | 1.52e-3 | 1.51e-3 |
|
||||
| 5 | 421,405 | 0.0251 | 0.0251 |
|
||||
| 6 | 2,773,843 | 0.1653 | 0.1653 |
|
||||
| 7 | 7,302,781 | 0.4353 | 0.4351 |
|
||||
| 8 | 6,253,177 | 0.3727 | 0.3729 |
|
||||
|
||||
Small amounts {1, 2, 30, 31} and byte-aligned amounts {8, 16, 24} follow Binomial(8, 4/31) and Binomial(8, 3/31) to
|
||||
within 3 percent in every bin.
|
||||
|
||||
### 6.4 Diffusion of the worst members (`avalanche.log`: 2,048 states x 512 input bits, mean and minimum per-output-bit flip probability)
|
||||
|
||||
| Day | Why | ROT | After 1 application, mean / min | After 2, mean / min |
|
||||
|---|---|---|---|---|
|
||||
| 20,729 | genesis, same-word pair 11 + 21 = 32 | 6 25 5 25 29 11 9 21 | 0.461 / 0.383 | 0.500 / 0.498 |
|
||||
| 4,819,563 | M1 worst in 2^24 | 26 18 8 30 24 24 6 9 | 0.467 / 0.426 | 0.500 / 0.499 |
|
||||
| 27,952,752 | M1 worst in 2^28 | 11 26 11 7 6 20 20 3 | 0.460 / 0.392 | 0.500 / 0.498 |
|
||||
| 11,482,247 | 3 distinct amounts, multiplicity 5 | 12 19 19 4 19 12 19 19 | 0.453 / 0.374 | 0.500 / 0.499 |
|
||||
| 14,330,190 | all 8 amounts in {1, 2, 30, 31} | 1 1 2 31 1 31 1 31 | 0.331 / 0.196 | 0.4995 / 0.497 |
|
||||
| 332,924 | NAF weight 3 word, three amounts of 1 | 1 23 1 1 12 11 16 18 | 0.458 / 0.370 | 0.500 / 0.498 |
|
||||
| 196,441,106 | `MUL = 1` word (2^28) | 30 24 23 5 11 28 12 9 | 0.461 / 0.364 | 0.500 / 0.499 |
|
||||
| 109,542,046 | `RC = 0` word (2^28) | 28 5 4 31 25 28 12 4 | 0.459 / 0.348 | 0.500 / 0.499 |
|
||||
| planted all 1 | the worst all-equal draw | 1 x 8 | 0.345 / 0.216 | 0.500 / 0.499 |
|
||||
| planted all 16 | half-word swaps | 16 x 8 | 0.387 / 0.312 | 0.500 / 0.499 |
|
||||
| planted all 7 | | 7 x 8 | 0.464 / 0.400 | 0.500 / 0.498 |
|
||||
|
||||
The slowest draw that can exist (all rotations by 1, probability 31^-8 per day) reaches full avalanche after 2 of the
|
||||
8 applications between cache reads; the worst real day in 2^28 (all amounts in {1, 2, 30, 31}) the same. No draw
|
||||
gives an attacker a shorter dependency between reads than the round margin F2 measures.
|
||||
|
||||
### 6.5 The chain's first 100 years (`census-100y.md`: days 20,729 to 57,253 under the interim day rule)
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Days over 1.1x under M1 | 6 of 36,525 (1.64e-4; the 2^24 rate predicts 12) |
|
||||
| First such day | 22,633 (genesis + 1,904 days, about 5.2 years in), cost 208, 1.111x |
|
||||
| Worst day | 29,337 (genesis + 8,608 days, about 23.6 years in), cost 206, 1.121x |
|
||||
| Days at exactly 1.100x (cost 210) | 6 more: 25,605; 28,102; 31,573; 33,710; 42,573; 54,884 |
|
||||
| M2 k >= 2 | 0 |
|
||||
| Genesis day 20,729 | cost 226, 0.978x; the next four devnet days (20,730 to 20,733) read 0.987x, 1.036x, 0.947x, 0.979x |
|
||||
| Rotation structure | 1 day with 2 distinct amounts (57,146, genesis + 36,417, cost 225, 1.027x), 46 with 4, none with 3 or fewer otherwise; no day with a `MUL` of NAF weight under 4 |
|
||||
|
||||
### 6.6 Verifier time (exclusive hold, `timing.log`)
|
||||
|
||||
A confirmation row only: the verifier's code path is value-independent, so the exact metric is the op count above
|
||||
and a wall-time difference between days can only be noise. Queued on the box at 09:47 UK (`timing.sh`, nohup, an
|
||||
exclusive `flock -x -w 7200` behind the shared holds of F1, F2, F8, F9, F10 and F7 and the queued exclusive hold of
|
||||
F6; the first attempt, queued 09:14 UK, was attached to a Mac ssh session and was withdrawn in favour of the nohup
|
||||
job). Cores 16 and 64, nice 19, `--warps 100`, day 20,729 against day 4,819,563 (the 2^24 M1 worst), A B A B.
|
||||
|
||||
| Day | Cold warp 0 (ms) | Average per warp, 100 warps (ms) |
|
||||
|---|---|---|
|
||||
| 20,729 (genesis) | pending (`timing.log`) | pending |
|
||||
| 4,819,563 (M1 worst, 1.173x) | pending (`timing.log`) | pending |
|
||||
|
||||
The verdict does not rest on this row.
|
||||
|
||||
### 6.7 The worst days in full (`worst-days.log`, `export-29337.log`)
|
||||
|
||||
The worst day in adders per application against the census median, in each set. M1 is the sum of the 16 NAF weights
|
||||
less 16 plus 64. Every one is an ordinary draw whose 16 weights happen to sum low; none has a word under NAF weight 7.
|
||||
|
||||
| Set | Chain day | Years after genesis | ROT | MUL words (hex) | NAF weights | M1 cost | Gain vs median 231 | M2 |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| The public calendar, first 36,525 days (what an auditor runs) | 29,337 | 23.6 | 24 12 18 11 14 26 29 21 | 3fe4d03b 227c2043 06011627 40c10137 00234d99 063071d9 91e5abb7 035240b1 f40bfe47 809251b9 1ce999ef 940b381d da13a021 f75f8ba7 3f59bca7 01310e05 | 9 8 9 8 10 10 12 10 9 10 12 11 10 11 11 8 (sum 158) | 206 | 1.121x | 1.000x |
|
||||
| 2^24 (the gate census) | 4,819,563 | 13,139 | 26 18 8 30 24 24 6 9 | a0653c83 a09de525 810085fb 6a00eba1 bf8205ff bba82079 f27da4c3 2cb80223 6001efcf 1c2814f7 ae9d09d7 ffedd7b7 943dde01 39ff47e1 0513a83f c028eef9 | 11 11 7 10 7 10 12 10 7 9 13 8 8 8 9 9 (sum 149) | 197 | 1.173x | 1.000x |
|
||||
| 2^28 (extended) | 27,952,752 | 76,481 | 11 26 11 7 6 20 20 3 | f15eb273 227a08f1 20f822e1 6d477779 8d9b3aff 03040503 27fff521 bfd9ce7d 7708000d 5d60ba11 2d40005b f07e10d7 1deefdb1 4881e821 01e1fc71 3ee7c39b | 13 9 8 11 11 7 7 11 7 11 9 9 8 8 7 10 (sum 146) | 194 | 1.191x | 1.000x |
|
||||
|
||||
Reproduction, through the harness: `attack-f4 day --index 29337 --median 231` (and 4819563, 27952752). Through
|
||||
`igneum-pow` itself, with the day bytes `"igneum-day/" || d_le64` as hex (day 29,337 = 0x7299):
|
||||
`igneum-pow export --seed x --epoch-hex edc4fa844da9dc98d37e965176f6558a31560e40502ab3ae5491b21aaaabfb07 --day-hex 69676e65756d2d6461792f9972000000000000 --program-class v4 --out <dir>`
|
||||
writes the day's constants into the pack's `memhard.h` as `IGNEUM_MIX_ROT_INIT` and `IGNEUM_MIX_MUL_INIT`; run on the
|
||||
box at 09:52 UK (`export-29337.log`, OVERALL PASS, cache FNV-1a 64 `1979492fb76b52ce`), the pack's 8 rotations and
|
||||
16 multipliers equal the harness's word for word. The day-hex strings of the other two days are in section 6.2's
|
||||
source list (`census-2p24.md` and `census-2p28.md`, "The 16 lowest-cost days"): `...2f6b8a490000000000` and
|
||||
`...2f7086aa0100000000`.
|
||||
|
||||
## 7. Gate line and consequences
|
||||
|
||||
Gate (plan 1.4 (3)): the fraction of days with any gain over 1.1x under 2^-20.
|
||||
|
||||
| Model | Fraction over 1.1x | Gate | What the number means per tier |
|
||||
|---|---|---|---|
|
||||
| M1 (per-day LUT bitstream) | 3.26e-4 (1 day in 3,070; 2^24 and 2^28 agree; exact expectation 3.24e-4) | FAIL by 342x | An FPGA farm that re-synthesises its bitstream every day gains 10 to 19 percent on those days: 3.26e-4 x about 0.12 = 4e-5 of a year's hashes, 0.004 percent. The FPGA lane is already behind every GPU tier on reads per watt (F5: 10 to 20 M reads/s/W against the gate's 27 M), so no home miner (8, 12, 16, 24 or 32 GB), rig or pool on any vendor or OS sees a competitor appear, and no day's difficulty moves by a measurable amount |
|
||||
| M2 (DSP-bound FPGA) | 0 in 2^28 | PASS | nothing moves for any tier |
|
||||
| Chip (programmable constants, the chip-model-v3 recompute chip) | 0 by construction | PASS | nothing moves; a taped-out chip cannot specialise per day |
|
||||
| GPU and the CPU verifier | 0 by construction | PASS | every tier pays the same ops on every day |
|
||||
|
||||
What the worst day buys, priced for the per-day LUT datapath (the M1 attacker) on the worst calendar day, 29,337:
|
||||
|
||||
| Item | Value | Source |
|
||||
|---|---|---|
|
||||
| Fewer adders per mixer application that day | 231 to 206, 10.8 percent fewer | section 6.7 |
|
||||
| Item derivations per unit of fabric that day | 1.121x (M1 gain) | section 6.7 |
|
||||
| Hash rate of a recompute FPGA (items derived per hash, the `chip-model-v3` ops-per-hash attacker) that day | up to 12.1 percent above its ordinary day, an upper bound: the 128 dependent cache reads per hash and the shadow block are untouched by the draw, so the whole-hash gain is below the mixer's | `chip-model-v3.md` section 1 (ops per hash = 128 x 72 x 130); section 3 |
|
||||
| Hash rate of the stored-dataset (f = 1) FPGA or chip that day | 0 (it derives no items per hash; the mixer is paid once in the daily build) | `funding.md` B2 rank 2 |
|
||||
| Days a century at or over 1.1x | 12 (6 over, 6 at exactly 1.100x) | section 6.5 |
|
||||
| Share of a century's hashes the M1 attacker gains | 12 / 36,525 x about 0.11 = 3.6e-5, 0.004 percent | arithmetic on the rows above |
|
||||
| What one bitstream a day costs | one place-and-route of a large part: 42 to 160 minutes on a mid-size part (PRflow, FPT 2019, cited in spec 01 section 1.13), hours on a large one; on a rented 96-thread box (Hetzner AX162 class, about USD 0.35 per hour, approximate) under USD 3 per bitstream (approximate), and it compiles any time ahead because the calendar is public | spec 01 section 1.13; price approximate |
|
||||
|
||||
So the bitstream is cheap and the gain is 0.004 percent of a century for the slower of the two FPGA designs: nothing
|
||||
a home miner on any card, a rig or a pool on any vendor or OS can see, and nothing that moves a day's difficulty.
|
||||
|
||||
What is being done about the M1 line: class v4 is not changed (it is the object on the live devnet's vote). The
|
||||
rejection-and-redraw rule of section 8 is proposed to main for the next class, unless main reads the census as a
|
||||
fault beyond the metric (this row does not: every class sits at its expectation and the worst day is an ordinary
|
||||
draw). The rule costs one redraw on 5.6e-4 of days, changes no existing vector (day 20,729 has NAF sum 178; the first
|
||||
day the rule would redraw is 22,633, about 5.2 years after genesis, section 6.5), and makes the M1 gate pass by
|
||||
construction. `igneum-pow` is untouched by this row.
|
||||
|
||||
## 8. Proposed fix for the next class: a rejection-and-redraw rule on the MUL draw (for main's decision)
|
||||
|
||||
Shape, like the program acceptance rule 1.4.6 and `DeriveProgram::check`: draw the 16 `MUL`, test, and on rejection
|
||||
continue the same stream with 16 fresh draws (so every later draw keeps its position only within an accepted block;
|
||||
`RC` is drawn after the accepted `MUL` block). Tests, in order:
|
||||
|
||||
| Rule | Threshold | Rejection probability per candidate | What it closes |
|
||||
|---|---|---|---|
|
||||
| Sum of NAF weights of the 16 `MUL` at least 163 (M1 cost at least 211, gain at most 1.095x against the median 231) | `sum_i NAF(MUL_i) >= 163` | 5.64e-4 (`expect-231.log` cumulative at cost 210) | the M1 tail: no day over 1.1x by construction |
|
||||
| Every `MUL` of NAF weight at least 4 | `NAF(MUL_i) >= 4` | 1.30e-5 per day | `MUL = 1`, `2^32 - 1`, `2^a +- 1`, `2^a +- 2^b +- 1`: the M2 words (hygiene; M2 already passes) |
|
||||
| `ROT`: at least 4 distinct amounts (the `DISTINCT_ROTS_FLOOR` idea of `derive.rs`) | `distinct >= 4` | 3.07e-5 per day | the degenerate rotation draws (hygiene; 0 ops moved, diffusion fine at 2 applications) |
|
||||
|
||||
Total rejection about 6.1e-4 per day: one redraw every 4.5 years of chain time; `MAX_ATTEMPTS`-style exhaustion is
|
||||
impossible in practice (64 rejections in a row at 6e-4 each). Class check to land with it: a unit test in `memhard.rs`
|
||||
that plants a low-sum draw (stream seed chosen so the first MUL block fails) and asserts the redraw, plus this
|
||||
harness re-run over 2^24 showing 0 days over 1.1x under M1 after the rule. The reproduction line for the finding
|
||||
without the rule: `attack-f4 day --index 4819563 --median 231` (cost 197, 1.173x) and
|
||||
`attack-f4 day --index 27952752 --median 231` (cost 194, 1.191x).
|
||||
|
||||
Consensus consequence: the rule changes the day-key-to-constants map on rejected days only, so it must land before the
|
||||
freeze tag. In the chain's first 100 years the sum rule redraws 12 days (6 under 1.1x and 6 at exactly 1.100x,
|
||||
section 6.5), the first of them 22,633, about 5.2 years after genesis; no pack cut for the devnet, the testnet or the
|
||||
first five years of mainnet changes. The per-word rule redraws no day in the first 100 years (no word of NAF weight
|
||||
under 4 in `census-100y.md`); the `ROT` rule redraws one, day 57,146 (2 distinct amounts, 99.7 years in).
|
||||
|
||||
## 9. What this row did not do
|
||||
|
||||
* It did not time the verifier per day beyond the confirmation row of 6.6: the verifier's code path is
|
||||
value-independent (no branch on a drawn value), so op counts are the exact metric.
|
||||
* It did not search optimal single-constant multiplication costs (not computable at 2^28 scale); NAF is the standard
|
||||
canonical bound and the ratio between days is what the gate asks.
|
||||
* It did not census the era draw (F7) or the spec's intent for the 64-bit seeding (F7); the fact is stated in section 1.
|
||||
229
docs/analysis/attack-pass/f6-verifier.md
Normal file
229
docs/analysis/attack-pass/f6-verifier.md
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
# F6: the verifier's worst case over 10^5 class v4 programs
|
||||
|
||||
Attack-pass row F6 (`docs/plans/cryptanalysis.md` 4.2; the record `docs/analysis/attack-pass-2026-10.md`), the box search.
|
||||
The O-1.14 laptop relay run is not in this record (main runs it separately). Written 7 October 2026.
|
||||
|
||||
## Target
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Commit | `924288d1` on branch `attack-pass` (`igneum-pow` is byte-identical at the worktree HEAD `8e36faf6`: `git diff --stat 924288d1..HEAD -- igneum-pow` is empty) |
|
||||
| Class | `--program-class v4`: generator 4 on `V4_CLASS` = `mx8+sh256x27` (`LoadClass::MX8` plus `ShadowClass { instrs: 256, reps: 27 }`), no era bytes (the same draw `igneum-pow bench --program-class v4 --seed S` makes) |
|
||||
| Dataset | day `2026-10-03`, `Shape::for_class_day(V4_CLASS, 0)`: cache 2^26 words (256 MiB), mixer x8, dataset 2^28 words, memory-hard |
|
||||
| Work per hash | 64 base instructions x 8 iterations (16 loads) plus 256 shadow instructions x 27 passes x 8 iterations = 55,296 shadow instructions, 101,192 counted ops at the 1.83 convention |
|
||||
| Gate | 10 ms per 32-lane warp, cold, on the half-core proxy (plan 1.4 item 6; spec 01 section 1.9 and 1.11; `algorithm.md` 3.3 and 5.5) |
|
||||
| Programs | 10^5 deterministic string seeds `attack-f6/0` to `attack-f6/99999` through the class v4 chain draw with its acceptance rule (5.22 percent needed a second or third attempt, max attempt 3) |
|
||||
|
||||
The era draw is not in the search: `generator.rs` draws the shadow block from `NONLOAD_WEIGHTS` with no era perturbation
|
||||
(no `perturb` path exists in the code at this commit), and the era parameters change only the load addressing, not the op
|
||||
counts. Every drawn program has exactly 48 non-load base instructions and 256 shadow instructions, so the verifier's cost
|
||||
differs between programs only through the family mix (the per-family cost on the CPU) and the data.
|
||||
|
||||
## Known-failed shape
|
||||
|
||||
A drawn program whose verifier warp exceeds 10 ms cold on the half-core proxy. The acceptance rule (spec 1.4.6) bounds the
|
||||
miner's side (distinctness, bias, saturation); nothing bounds the verifier's cost per program, and the half-core headroom
|
||||
of the average program is 1.8 ms (`algorithm.md` 5.5), so a family mix that costs the CPU interpreter more than the average
|
||||
could cross the gate.
|
||||
|
||||
## Harness
|
||||
|
||||
`tools/attack/f6-verifier/` (its own cargo crate, `igneum-pow` as a path dependency, the same release profile as the CLI:
|
||||
opt-level 3, LTO, one codegen unit). It builds the day's dataset ONCE (`DatasetSource::new_shape`, 0.58 s on the box) and
|
||||
swaps programs under it: `Epoch { program, dataset }` is only the pair, and `verify::hash_warp(&program, base, &dataset)`
|
||||
takes both, so one dataset serves every program. The naive path (`igneum-pow bench` per seed) refills the cache every
|
||||
time (370 ms) and would take 10 hours per core.
|
||||
|
||||
| Command | What it does |
|
||||
|---|---|
|
||||
| `attack-f6 scan --program-class v4 --count N --start S --threads T --cold-reps R --flush swap --out F` | program i = seed `attack-f6/<S+i>`; one CSV line per program: generation time, R timed warps (each after a flush), their min, the op counts by family for the base and the shadow block |
|
||||
| `attack-f6 time (--program-class v4 \| --class dr736) --seeds-file F --cold-reps R --steady W --flush sweep` | the deep re-time: R cold warps (each after a 256 MiB write sweep, what the cache fill does before `bench`'s "single cold run"), max, median, min, a steady average of W warps, and `GATE 10 ms PASS/FAIL` on the max |
|
||||
| `attack-f6 micro --program-class v4` | the genesis program with its shadow block rewritten to one family at a time against the same program with no shadow: the per-family cost of a shadow instruction (ranking weights only) |
|
||||
| `attack-f6 load --program-class v4 --seconds 0` | hashes class v4 warps on the calling core until killed: the SMT sibling's load for the half-core proxy, the same class the 3.3 proxy ran on both siblings |
|
||||
| `rank.py --scan ... --weights ... --column ... --top 50 --out-prefix P` | the proxy ranking (sum over families of weight x (8 x base count + 216 x shadow count)), the distribution (min, median, p99, p99.9, max with the seed), the worst-N lists, a no-intercept regression of time on the family counts |
|
||||
|
||||
Build line (from the crate directory):
|
||||
`IGNEUM_AGENT=attack-f6 bash /Users/joshm/Projects/igneum/tools/build-remote.sh --artefacts "target/release/attack-f6" --out <scratch> -- build --release`
|
||||
(build 08:04 to 08:06 UTC, rustc 1.99.0, binary sha256 `89c35674...17f3f9`, on the box at
|
||||
`/srv/builds/igneum-wt-attack/tools/attack/f6-verifier/target/release/attack-f6`).
|
||||
|
||||
Box scratch: `/srv/builds/igneum-wt-attack/target-attack-f6/` (not the `attack-f6/` the brief named: that path is an
|
||||
untracked directory in the worktree mirror and `build-remote.sh`'s checkout step runs `git clean -fd` on the mirror
|
||||
before every build of this worktree by any agent, which removed it once at 08:04 UTC; `target-*` is on the clean's keep
|
||||
list, so this name survives). Logs there: `phase1.log`, `scan-0.csv`, `scan-50000.csv` (phase 1), `phase2a.log`,
|
||||
`clock-2a.log`, `full-0.csv`, `phase2b.log`, `clock-2b.log`, `full-50000.csv`, `phase2c.log`, `clock-2c.log` (phase 2),
|
||||
`smoke.log` (the functional check). Copies on the Mac under the session scratchpad `attack-f6/`.
|
||||
|
||||
Run lines:
|
||||
|
||||
| Phase | Hold | Cores | Line |
|
||||
|---|---|---|---|
|
||||
| 1, pre-screen (counts and a coarse time, no timing claim) | `flock -s` per 50,000-program chunk (2.6 min each) | `nice -n 10 taskset -c 42-47,90-95`, 12 threads | `attack-f6 scan --program-class v4 --count 50000 --start {0,50000} --threads 12 --cold-reps 2 --flush swap` |
|
||||
| 2A, firings, micro, full pass first half | `flock -x` | `nice -n 19 taskset -c 40`; half-core: core 88 running `attack-f6 load` | `phase2a.sh` |
|
||||
| 2B, full pass second half, worst 50 by proxy and worst 50 by coarse time re-timed on both proxies | `flock -x` | same | `phase2b.sh` |
|
||||
| 2C, worst 1,000 by the full one-core pass on the half-core; worst 10 deep re-timed on both proxies | `flock -x` | same | `phase2c.sh` |
|
||||
|
||||
The clock of cores 40 and 88 (`scaling_cur_freq`) and the load average were read every 5 s during every exclusive hold
|
||||
(`clock-2*.log`).
|
||||
|
||||
## The two firings (batch A, exclusive hold taken 08:15:20 UTC, core 40 at 3,799.9 MHz throughout, `clock-2a.log`)
|
||||
|
||||
`attack-f6 time ... --cold-reps 5 --steady 20 --flush sweep`, the gate applied to the max of the 5 cold warps
|
||||
(`phase2a.log`). Lane-0 vectors equal the known ones (dr736 `e23d389f3eea0c83`, the Mac's).
|
||||
|
||||
| Case | Proxy | Cold max / median / min (ms) | Steady, avg of 20 | Known value (`algorithm.md` 3.3) | Verdict |
|
||||
|---|---|---|---|---|---|
|
||||
| known-fail, `--class dr736`, genesis seed | one core | 10.284 / 9.982 / 9.952 | 9.562 | 10.51 cold, 9.76 steady | FAIL (fired) |
|
||||
| known-fail, `--class dr736`, genesis seed | half-core | 14.135 / 13.795 / 13.400 | 13.225 | 15.49 | FAIL (fired) |
|
||||
| known-pass, `--program-class v4`, genesis seed | one core | 5.156 / 5.140 / 5.135 | 4.909 | 5.06 cold, 4.90 steady | PASS (fired) |
|
||||
| known-pass, `--program-class v4`, genesis seed | half-core | 8.624 / 8.510 / 8.389 | 8.268 | 8.23 | PASS (fired) |
|
||||
|
||||
The harness reads the known-fail class over the gate and the known-pass class under it on both proxies, within 2 percent
|
||||
of the 3.3 one-core numbers and within 9 percent on the half-core (the earlier half-core run loaded the sibling with
|
||||
`igneum-pow bench` of the same class; this one hashes class v4 warps on it continuously).
|
||||
|
||||
## What one program can move (batch A, `micro`, core 40 solo)
|
||||
|
||||
The genesis class v4 program with no shadow block: 4.511 ms steady; with its drawn shadow: 4.920 ms. So the whole 55,296-
|
||||
instruction shadow block costs 0.41 ms per warp on this core (7.4 us per 1,000 shadow instructions; `model.py` carries
|
||||
7.0) and the base program with its 128 loads and 4,096 item derivations costs the other 4.5 ms. The verifier's cost is
|
||||
92 percent dataset derivation (the x8 mixer, 8 dependent cache reads per item), which no drawn program changes: every
|
||||
class v4 program has 16 loads and the acceptance rule's distinctness test keeps the items per warp near 4,096. The family
|
||||
mix of the shadow can move at most a fraction of 0.41 ms. The per-family rewrite (the 256 shadow instructions all one
|
||||
family) reads add 4.798, sub 4.703, xor 4.683, rotl 4.818, mad 4.805, shfl 5.042, rotr 5.160 ms per warp; the mul,
|
||||
mulhi and or rows (0.97, 1.55, 1.13 ms) are degenerate (the registers collapse to 0 or all-ones, every lane then loads
|
||||
the same item and the memory side vanishes) and are not ALU costs. Batch A's micro line printed its per-1,000 column
|
||||
1,000x too small (ns per instruction); fixed in the source, the numbers above are the ms-per-warp column, which is right.
|
||||
|
||||
## Full one-core pass A (batch A, 50,000 programs, core 40 solo, one cold warp each after a program swap, `full-0.csv`)
|
||||
|
||||
617 s for 50,000 programs (12.3 ms each, 2.5 ms of it generation and acceptance). The per-family regression on the
|
||||
50,000 timings (no intercept) gives 86 to 98 us per 1,000 executed instructions by family, R^2 0.001: the family mix
|
||||
explains none of the program-to-program variation. Those regression weights (add 89.1, sub 87.7, mul 90.6, mulhi 98.4,
|
||||
xor 89.6, or 86.0, rotl 89.4, rotr 86.3, mad 91.2, shfl 95.6) are the proxy weights used for the worst-50-by-proxy list.
|
||||
|
||||
| Pass A | n | min | median | p99 | p99.9 | max |
|
||||
|---|---|---|---|---|---|---|
|
||||
| all rows | 50,000 | 4.610 (`attack-f6/1278`) | 4.950 | 6.753 | 7.834 | 10.710 (`attack-f6/26705`) |
|
||||
| rows outside the three disturbed blocks | 44,000 | 4.610 | 4.948 | 5.606 | 5.662 | 6.194 (`attack-f6/48484`) |
|
||||
|
||||
The rows over 6 ms sit in three 2,000-program blocks (26,000 to 27,999: 337 rows; 36,000 to 37,999: 300; 38,000 to
|
||||
39,999: 294) and nowhere else (0 in each of the other 22 blocks); the neighbours of the 10.71 ms seed, unrelated programs,
|
||||
all read 7.6 to 8.5 ms. `clock-2a.log` shows core 88 (the idle sibling of a solo run) at 3.8 GHz for stretches in those
|
||||
minutes (08:21:25, 08:21:45, 08:22:05 to 08:22:25 UTC) and core 40 dipping to 3.68 GHz at 08:21:00: a foreign process
|
||||
(the box's hands run outside the measure lock) sat on the sibling, which is the half-core condition, and those rows read
|
||||
half-core numbers. They are not program properties and not numbers; the three blocks are re-scanned in batch B, and from
|
||||
batch B on a per-second sampler logs every process whose last CPU was 40 or 88 (`clock-2b.log`, `clock-2c.log`) so a
|
||||
disturbed row can be named.
|
||||
|
||||
## Batches B and C: queued, starved of the exclusive hold (state at 09:46 UTC)
|
||||
|
||||
Batch B (the second 50,000 of the full one-core pass, the re-scan of the three disturbed blocks, the worst 50 by proxy
|
||||
and the worst 50 by phase-1 coarse time re-timed 10 cold reps each on both proxies) was queued with `flock -x -w 7200`
|
||||
at 08:33:56 UTC and had not taken the file by 09:46 UTC. Linux `flock` gives a pending exclusive waiter no priority over
|
||||
new shared takers; eight lanes re-take the file in chunks (17 to 38 shared holders at every reading, F2 spawning many
|
||||
short ones, one F9 hold 33 minutes old at 09:06, over the 30-minute cap), so the file is never free. Left on the box:
|
||||
`run2b-retry.sh` re-queues batch B up to four more times (2 h each); `run2c-auto.sh` waits for `BATCH B DONE`, builds the
|
||||
batch C lists on the box (`mklists.py`: the worst 1,000 and worst 10 by the full one-core pass, pass A's three disturbed
|
||||
blocks replaced by their re-scan) and queues batch C (the worst 1,000 on the half-core at 2 cold reps each, the worst 10
|
||||
at 20 cold reps on both proxies). A marker sits beside the lock (`/srv/builds/_locks/measure.wanted-by-attack-f6`). When
|
||||
they land, `timeparse.py --log phase2b.log --clock clock-2b.log` (and `2c`) prints the per-seed tables with the sampler's
|
||||
foreign-process column, and this record is completed.
|
||||
|
||||
## Numbers so far, the gate, the verdict
|
||||
|
||||
| Quantity | Value | Where |
|
||||
|---|---|---|
|
||||
| Programs drawn and counted (phase 1) | 100,000 | `scan-0.csv`, `scan-50000.csv` |
|
||||
| Programs timed cold on core 40 alone (one-core proxy) | 50,000 (44,000 clean, 6,000 in disturbed blocks awaiting the re-scan) | `full-0.csv` |
|
||||
| One-core cold, clean rows: min / median / p99 / p99.9 / max | 4.610 / 4.948 / 5.606 / 5.662 / 6.194 ms (`attack-f6/48484`), single warps, not yet re-timed | `full-0.csv` |
|
||||
| Genesis class v4, half-core, max of 5 cold | 8.624 ms | `phase2a.log` |
|
||||
| Half-core over one-core, genesis class v4 | 1.67x (8.624 / 5.156) | `phase2a.log` |
|
||||
| Programs timed on the half-core proxy | 1 (the genesis seed) | `phase2a.log` |
|
||||
| Core 40 clock during every exclusive timing | 3,799.9 MHz (dips to 3,680 MHz only in the disturbed minutes) | `clock-2a.log` |
|
||||
|
||||
Gate line: the worst program under 10 ms cold on the half-core proxy. Not yet measured: no drawn program other than the
|
||||
genesis seed has a half-core number, and the one-core worst (6.194 ms, a single warp with no sampler running) has not been
|
||||
re-timed. Carried to the half-core at the genesis ratio it would read 6.19 x 1.67 = 10.3 ms, over the gate; carried at the
|
||||
additive half-core cost of the genesis program (8.624 - 5.156 = 3.47 ms) it would read 9.66 ms, under it by 0.34 ms. The
|
||||
2.5x bracket of `algorithm.md` 5.5 is between. Whether `attack-f6/48484` (and the other clean rows over 5.6 ms: 1 in 100
|
||||
of the pass) is a program property or a short disturbance is what batch C's 20-rep re-time with the sampler decides;
|
||||
the record says FINDING if its half-core cold max reads 10 ms or more.
|
||||
|
||||
Verdict: INCOMPLETE. 100,000 programs drawn and ranked, 50,000 timed on the one-core proxy, 0 of the worst re-timed on
|
||||
the half-core proxy; the two firings fired; the box search's second half and the half-core re-times are queued and
|
||||
starved of the exclusive hold.
|
||||
|
||||
## The ladder ceiling implied so far
|
||||
|
||||
`algorithm.md` 5.5 and `model.py --section ladder` set the ceiling from the half-core headroom at 12.1 us per 1,000 shadow
|
||||
instructions, N = 101,192 + instructions x 1.83.
|
||||
|
||||
| Worst program on the half-core | Headroom to 10 ms | Shadow instructions it buys | Ceiling N (counted ops) |
|
||||
|---|---|---|---|
|
||||
| 8.23 ms (3.3's average, the published figure) | 1.77 ms | 146,000 | about 370,000 |
|
||||
| 8.62 ms (genesis seed, this run's max of 5) | 1.38 ms | 114,000 | about 310,000 |
|
||||
| 9.66 ms (48484 if the additive carry holds) | 0.34 ms | 28,000 | about 152,000 |
|
||||
| 10.3 ms (48484 if the 1.67x carry holds) | none | 0 | below today's 101,192: the floor rung 100,000 is the ceiling |
|
||||
|
||||
The proposed genesis ladder {100,000; 130,000; 200,000; 330,000; 650,000; 1,000,000} already exceeds the 310,000 ceiling
|
||||
at its fourth rung on the genesis program alone; on the worst program the ceiling could be the floor. This is the
|
||||
ladder's own open question (plan 1.1, "ceiling set by the verifier"), and the number that sets it is the half-core
|
||||
worst case still queued.
|
||||
|
||||
## Consequences per user tier (at the numbers measured so far; the model's table of 5.5 at 10 ms beside them)
|
||||
|
||||
| | At 8.62 ms (genesis, half-core max) | At 9.66 ms (worst, additive carry, unverified) | At 10.3 ms (worst, 1.67x carry, unverified) | Model at 10 ms |
|
||||
|---|---|---|---|---|
|
||||
| A node on a 2019-class laptop core at 1 bps | 0.9 percent of one core | 1.0 | 1.0 | 1 |
|
||||
| At 10 bps (the Devnet 2 experiment) | 8.6 percent of one core | 9.7 | 10.3 | 10 |
|
||||
| IBD over the 108,000-header pruning window, one core | 15.5 min | 17.4 | 18.5 | 18 |
|
||||
| Header flood: invalid headers per second that saturate one core | 116 | 104 | 97 | 100 |
|
||||
| A pool core verifying shares, shares per second per core | 116 | 104 | 97 | 100 |
|
||||
|
||||
What each tier does with it: a home miner (8, 12, 16, 24 or 32 GB card, any vendor, any OS) runs a node that spends about
|
||||
1 percent of one CPU core on the hash at 1 bps whatever the drawn program, and 9 to 10 percent at 10 bps; the card is not
|
||||
involved. A rig is the same per node. A pool verifying shares at 100 per second per core needs one core per 100 shares
|
||||
per second at the worst program, 116 at the average: a pool that sized its share verification at the average loses 14
|
||||
percent of its per-core headroom on the worst program, so pools size at 97 shares per second per core (the 10 ms figure)
|
||||
and never at the average. A node under header flood holds at about 100 invalid headers per second per core on any
|
||||
program, the M15 figure. The 2019-class core itself is still the half-core proxy until the O-1.14 laptop run lands
|
||||
(main's lane).
|
||||
|
||||
What this lane does about it: completes batches B and C when the hold comes (automatic, on the box); if the worst
|
||||
program reads 10 ms or more on the half-core proxy, the finding goes to main with the seed, the reproduction line
|
||||
`igneum-pow bench --program-class v4 --seed <seed> --day 2026-10-03 --warps 50` on core 40 and the half-core, and the
|
||||
proposed fix: an acceptance-rule bound on verifier cost (a per-program cost model over the family counts checked at
|
||||
draw time, a redraw when it exceeds the bound, exactly as rule (c) redraws on bias) and the ladder's ceiling set from
|
||||
the measured worst, not the average; `igneum-pow` is not edited by this lane.
|
||||
|
||||
## Batches B and C landed (7 October 2026, 13:5x UTC, cores 40 and 88 under the per-core lease)
|
||||
|
||||
The measure file was retired at 13:3x UTC and replaced by per-core leases; cores 40 and 88 were leased to this row
|
||||
(`/srv/builds/_bin/lease cores 40,88 --owner attack-pass`), so the batches ran with nothing else on those cores while
|
||||
builds continued on the rest of the box. Core 40's clock (`clock-2b.log`, `clock-2c.log`): median 3,799.9 MHz in both
|
||||
batches, 954 of 958 and 57 of 63 samples at 3.7 GHz or more, the 1.5 GHz readings between runs.
|
||||
|
||||
| Batch | What | Programs | Reps | Worst program | Half-core cold max | Log |
|
||||
|---|---|---|---|---|---|---|
|
||||
| B | the second 50,000 of the one-core pass, then the worst 50 by proxy and the worst 50 by coarse time re-timed cold on both proxies | 200 re-timed | 10 | `attack-f6/87142` | 8.708 ms | `phase2b.log`, done 13:52:11Z |
|
||||
| C | the worst 1,000 by the full one-core pass on the half-core, then the worst 10 at 20 cold reps on both proxies | 1,000 + 10 | 2, then 20 | `attack-f6/88521` (8.629), `attack-f6/15781` (8.414) | 8.629 ms | `phase2c.log`, done 13:57:45Z |
|
||||
|
||||
The one-core worst of the full pass (`attack-f6/48484`, 6.194 ms single warp) does not reach the half-core top ten:
|
||||
its one-core reading was a short disturbance, as the batch C re-scan shows. Every program timed on the half-core
|
||||
proxy reads under 9 ms.
|
||||
|
||||
## Gate line and verdict
|
||||
|
||||
Gate: the worst program under 10 ms cold on the half-core proxy (and on a 2019-class core: O-1.14, the i7-9700K row,
|
||||
class v4 6.334 ms cold max). Result: the worst of 100,000 class v4 programs on the half-core proxy is 8.708 ms,
|
||||
1.29 ms under the gate; the genesis program reads 8.624 on the same proxy, so the worst drawn program costs 1 percent
|
||||
more than the genesis one and the distribution is tight (one-core clean rows 4.610 to 6.194 ms, p99 5.606).
|
||||
Verdict: PASS. The two firings fired (dr736 FAIL at 15.49 ms half-core; class v4 genesis PASS at 8.62). Consequences
|
||||
per tier: a 2019-class node verifying the worst class v4 program spends 0.9 percent of one core at 1 bps and 9 percent
|
||||
at 10 bps on the pessimistic proxy; a header flood needs about 115 invalid headers a second to saturate one such
|
||||
core; a pool verifies about 115 shares a second per core; IBD of 108,000 headers is about 16 minutes of one core.
|
||||
Implied ladder ceiling on the half-core proxy from the worst program: 10 - 8.708 = 1.29 ms of headroom buys about
|
||||
106,000 shadow instructions, N about 300,000 counted ops at the 1.83 convention (approximate), against 370,000
|
||||
from the genesis program's headroom; the ladder's ceiling should be read from the worst program, not the genesis
|
||||
one, so rung 2 (199,600) stays admissible and rung 3 (330,700) does not on this proxy.
|
||||
165
docs/analysis/attack-pass/f7-era.md
Normal file
165
docs/analysis/attack-pass/f7-era.md
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# F7: the era-draw bias harness and the era-seed census
|
||||
|
||||
Attack-pass row F7 (`docs/plans/cryptanalysis.md` 4.2; the record `docs/analysis/attack-pass-2026-10.md`), both halves:
|
||||
the fast-time re-roll harness (node lane) and the 2^20 era-seed census plus the 64-bit day-key check (hash lane).
|
||||
Written 7 October 2026. Every number cites its log path on igneum-build-1.
|
||||
|
||||
## Target
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Commit | `924288d1` on branch `attack-pass` (`igneum-pow` is byte-identical at worktree HEAD `11b375a0`: `git diff --stat 924288d1..HEAD -- igneum-pow docs/spec infra/fast-time` is empty) |
|
||||
| Spec | `docs/spec/01-lottery-hash.md` 1.13.1 (era seed and draw), 1.8.4 (the day-key mixer stream); `docs/spec/04-seeds-and-vdf.md` 4.4 (era seed pipeline) and 4.6 (T from a reference core); `docs/plans/era-layout.md` sections 1 and 8 (branch `ca2-era`); `docs/analysis/horizon/algorithm.md` 5.4 |
|
||||
| Draw code | `igneum_pow::generator::era_draw` over `V3_ALLOWED = [1]` (the chain's path): the width draw (consumed, pinned at 4 bytes), the odd stride multiplier `M`, the rotation `R` in 1..31, the four interleave positions `pos` by partial Fisher-Yates |
|
||||
| Day-key code | `igneum_pow::memhard::MixParams::with_shape`: `SplitMix64::new(K[0] \| (K[1] << 32))` draws ROT[0..7], MUL[0..15], RC[0..15]; `K = seed_words_from_bytes("igneum-day/" \|\| day_le64)` (node fork `consensus/pow/src/igneum.rs`, `bind::day_bytes`) |
|
||||
| Node draw input (today) | `consensus/src/consensus/mod.rs` `seed_below`: `E_n` is the hash of the last selected-chain block below `15,552,000 n - 7,200` (era 0: genesis). The 1-hour VDF of spec 4.4 and the certified checkpoint it reads do NOT exist in the node (era-layout.md section 8, `proto-vdf` is a prototype) |
|
||||
|
||||
## Sub-row verdicts
|
||||
|
||||
| Sub-row | Verdict | Gate (plan 4.2 F7) |
|
||||
|---|---|---|
|
||||
| (a) re-roll harness | INCOMPLETE, with the written argument | no re-roll inside the publish window |
|
||||
| (b) 2^20 era-seed census | PASS | no era class with gain over 1.1x at a fraction over 2^-20 |
|
||||
| (c) 64-bit day-key seeding | PASS, within spec intent (one observation recorded) | the draw's input set as the spec states it |
|
||||
|
||||
## (a) The re-roll harness (node lane)
|
||||
|
||||
`tools/attack/f7-era/reroll.mjs`: a 3-node fast-time network (`infra/fast-time/override-60x.json` with
|
||||
`skip_proof_of_work`, the `class-v4-signal.mjs` shape), own ports 29800 and up, own devnet suffix 980, own data dir
|
||||
`/tmp/igneum-fast-time-attack-f7`. The node binary is the ladder fork `vendor/igneum-node-ladder` at `1591ee1d`
|
||||
(`igneumd 2.1.0`, already built on the box; read-only). Two honest virtual miners share 1 block/s on nodes 0 and 1; the
|
||||
adversary on node 2 holds a block `A` built on the tip at DAA score `S - 1` (the seed block sits there), optionally waits
|
||||
a stub VDF of `--vdf-ms`, then publishes `A` to try to make its own block the epoch's seed block (the last selected-chain
|
||||
block below the cut `S`). A re-roll succeeds when the epoch's reported seed becomes `hash(A)`.
|
||||
|
||||
The era cut `15,552,000 n - 7,200` is 180 days of DAA score away on every profile (`POW_ERA_BLOCKS` is a chain constant,
|
||||
not an override field), so the harness attacks the EPOCH cut (`60 e - 10` at 60x), which runs the identical `seed_below`
|
||||
derivation at a reachable score, one cut per minute. The harness's own era draw (JS) is checked byte-for-byte against the
|
||||
Rust census at start: seed `b62532bc...` draws `M 558c0543 R 4 pos [0,1,2,3]` on both (log line "draw self-check ... OK").
|
||||
|
||||
Firings (both runs 6 cuts, box cores 36-37,84-85 under the shared measure lock):
|
||||
|
||||
| Run | `--vdf-ms` | Re-rolls to A | Gate | Harness | Log |
|
||||
|---|---|---|---|---|---|
|
||||
| known-pass | 0 (no delay, the stand-in) | 1 of 6 (epoch 11, seed = A) | FAIL | SOUND (fires) | `/srv/builds/igneum-wt-attack/attack-f7/reroll-knownpass.log` |
|
||||
| known-fail | 5,000 (a delay past one block interval) | 0 of 6 | PASS | SOUND (silent) | `/srv/builds/igneum-wt-attack/attack-f7/reroll-knownfail.log` |
|
||||
|
||||
Both runs: 6 of 6 adversary blocks accepted, all three sinks agree, no reorg of the honest chain. The harness fires on the
|
||||
known-pass and is silent on the known-fail, so it is trusted.
|
||||
|
||||
Written argument (the plan allows one for the VDF's assumptions; the VDF's own delay soundness belongs to the finality
|
||||
review row of `funding.md`). The re-roll is possible ONLY when the adversary can evaluate the draw of a candidate input
|
||||
inside the block publish window. Today the node has no VDF: `E_n` is a plain block hash, so the input of any candidate
|
||||
block is known the instant the block is built, and the harness shows the last-block-before-the-cut is grindable with one
|
||||
block of hash (1 of 6 cuts steered in fast time, `--vdf-ms 0`). With any delay past one honest block interval the
|
||||
re-roll is gone (`--vdf-ms 5000`: 0 of 6). The design closes this with the 1-hour class-group VDF of spec 4.4: re-rolling
|
||||
by withholding needs the 3,600 s VDF evaluated inside the 2 s window, a 1,800x evaluator, and spec 4.6's margin table
|
||||
gives 300x as the horizon (`algorithm.md` 5.4; `sim/horizon/algorithm/model.py --section era`). The forge route needs
|
||||
2/3 of the 30-day weight, 20 days of 100 percent hash (CLAUDE.md headline). The sub-row is INCOMPLETE because the harness
|
||||
cannot demonstrate the real gate: the VDF and the certified checkpoint it reads are not in the node yet (era-layout.md
|
||||
section 8 states this). What the harness DOES establish: the C_era cut rule with no delay is grindable, so the era draw's
|
||||
soundness rests entirely on the VDF landing before the draw procedure is frozen, and the delay-soundness measurement is
|
||||
owed to the finality lane.
|
||||
|
||||
## (b) The 2^20 era-seed census (hash lane)
|
||||
|
||||
`tools/attack/f7-era/` (a cargo crate with `igneum-pow` as a path dependency and an empty `[workspace]`; ELF built on the
|
||||
box, sha256 `a87818d8...`). `attack-f7 census` runs `era_draw` over `V3_ALLOWED` on `2^n` seeds and classifies each draw;
|
||||
`attack-f7 all` runs the plant known-fail case, the census, the spec-stream op-weight census and the day-key check.
|
||||
|
||||
Known-fail / known-pass of the classifier (planted parameters through a test hook in this crate; log
|
||||
`/srv/builds/igneum-wt-attack/attack-f7/census-2p20.log`): every planted weak draw fires its flag (M = 1, M = 2^32-1,
|
||||
M = 2^16+1, a naf-2 multiplier, an even M, R = 0, R = 32, pos linear, pos contiguous, pos not ascending) and a sound draw
|
||||
(igneum-era-test/0) raises nothing. "Plant verdict: every planted case fired and the sound draw did not."
|
||||
|
||||
Census results (2^24 = 16,777,216 draws, the stronger run; `census-2p24.log`; the 2^20 run agrees, `census-2p20.log`):
|
||||
|
||||
| Class | Count (2^24) | Fraction | Expected (uniform) | Chip gain |
|
||||
|---|---|---|---|---|
|
||||
| M even (bijection failure) | 0 | 0 | 0 | finding if present: none |
|
||||
| R out of 1..31 | 0 | 0 | 0 | finding if present: none |
|
||||
| pos invalid (not 4 ascending) | 0 | 0 | 0 | finding if present: none |
|
||||
| M = 1 (identity stride) | 0 | 0 | 4.66e-10 | 1.0034x |
|
||||
| M = 2^32 - 1 | 0 | 0 | 4.66e-10 | 1.0030x |
|
||||
| popcount(M) <= 2 | 1 | 5.96e-8 (2^-24) | 1.49e-8 | 1.0030x |
|
||||
| popcount(M) <= 4 | 43 | 2.56e-6 (2^-18.6) | 2.33e-6 | 1.0022x |
|
||||
| popcount(M) <= 6 | 1,626 | 9.69e-5 | 9.61e-5 | 1.0014x |
|
||||
| popcount(M) <= 8 | 27,749 | 1.65e-3 | 1.66e-3 | 1.0007x |
|
||||
| naf(M) <= 2 | 1 | 5.96e-8 | - | 1.0030x |
|
||||
| naf(M) <= 3 | 18 | 1.07e-6 | - | 1.0026x |
|
||||
| M = 2^k + 1 | 1 | 5.96e-8 | 1.44e-8 | 1.0030x |
|
||||
| pos linear [0,1,2,3] | 9,257 | 5.52e-4 | 5.50e-4 | 1.0000x |
|
||||
| pos contiguous | 120,054 | 7.16e-3 | 7.14e-3 | 1.0000x |
|
||||
| pos in the low byte | 645,856 | 3.85e-2 | 3.85e-2 | 1.0000x |
|
||||
|
||||
The gain metric is the datapath energy a chip saves per hash against the base weights, over the hash's datapath energy
|
||||
(19.5 nJ at 100,000 ops x 0.195 pJ, the N5 floor of `algorithm.md` 5.4 / `model.py --section era`). The stride multiply is
|
||||
one of three address operations, run 128 times per hash (16 loads x 8 iterations); a low-weight `M` replaces the multiplier
|
||||
with a few shift-adds, worth at most 128 x 0.52 pJ = 67 pJ, so M = 1 is the richest corner at 1.0034x. The rotation is a
|
||||
wire mux and the interleave an address-line permute, 0 pJ on the modelled chip. No drawn parameter touches the memory
|
||||
bound, the item derivation, the load count or N.
|
||||
|
||||
Gate: no class with gain over 1.1x at a fraction over 2^-20. The richest gain in the whole classifier is 1.0034x (M = 1),
|
||||
and M = 1 did not occur in 2^24 draws (expected 4.66e-10). Every class at a fraction over 2^-20 has gain 1.0000x to
|
||||
1.0007x. PASS on both counts.
|
||||
|
||||
Uniformity of the draw (2^24): stride rotation R over 1..31 chi-square 38.5 on 30 dof (max bucket deviation 2.07 sigma,
|
||||
R = 0 or 32 seen 0 times); interleave pos 1,820 of 1,820 four-subsets seen, chi-square 1,775.7 on 1,819 dof (max deviation
|
||||
3.63 sigma, 0 draws with a non-4-subset); M bit 0 always set (odd by construction), bits 1..31 each set in 0.500 of draws
|
||||
(worst bit 1.81 sigma); the stride bijection never failed (0 even M). The era stream's own 64-bit seed (words 0 and 1) was
|
||||
distinct on all 2^24 draws.
|
||||
|
||||
Op-weight corners (spec 1.13.1 first stream, implemented in `attack-f7 spec` from the spec text because `igneum-pow` does
|
||||
not draw the op-weight perturbation at this commit; 2^20 draws, `census-2p20.log`): the ten non-load weights each
|
||||
perturbed by -2..+2 and renormalised to 75 move the multiply share (mul+mad+mulhi, base 22 of 75) between 15 and 31. The
|
||||
richest corner for a chip is 15/75 (0.152 pJ per op, -22 percent of the base datapath), seen once in 2^20; 16/75 at
|
||||
3.22e-3. The GPU's energy moves the same way (its IMAD is the chain's own op), so the chip-against-GPU gain of every
|
||||
weight corner is 1.0x, with 0 memory effect. Renormalised sums were 75 on every draw (0 failures). Fold rotations: a triple
|
||||
all equal 2.13e-3, both triples all equal 1.91e-6, all six equal 0; uniform over 1..31, rotation 0 never drawn; a wire
|
||||
mux, 1.0x.
|
||||
|
||||
## (c) The 64-bit seeding of the day-key stream (hash lane)
|
||||
|
||||
`attack-f7 days` over days 0..131,072 (`census-2p20.log`). The day key `K` is `seed_words_from_bytes("igneum-day/" ||
|
||||
day_le64)`: a calendar function, no chain state. All 256 bits of `K` enter the cache fill (spec 1.8.3, `K[0..7]` in every
|
||||
block input), so the dataset depends on the full key; the mixer-constant stream (ROT, MUL, RC) is seeded from `K[0] |
|
||||
(K[1] << 32)`, 64 bits, which is the spec's stated intent (spec 1.8.4).
|
||||
|
||||
| Quantity | Value |
|
||||
|---|---|
|
||||
| Days the chain can have | about 65,745 in 180 years at 1 block/s (2^16.0) |
|
||||
| Distinct 256-bit keys K over 2^17 days | 131,072 (all) |
|
||||
| Distinct 64-bit stream seeds over 2^17 days | 131,072 (0 duplicates) |
|
||||
| Distinct (ROT, MUL, RC) tuples over 2^17 days | 131,072 |
|
||||
| Birthday bound on a 64-bit collision among 2^16 days | 2^(32 - 65) = 2^-33 |
|
||||
|
||||
The spec intends 64 bits for the mixer-constant draw, and the truncation is not a reduction of the draw space the firm
|
||||
would flag: at most 2^16 days are ever drawn, each a distinct calendar day with a distinct 64-bit seed (0 collisions in
|
||||
2^17), so no two days share a mixer. One observation, within spec intent and recorded for the written argument of
|
||||
`funding.md` B5 rank 6: the mixer-constant stream has 64 bits of seed entropy, so at most 2^64 distinct daily mixers are
|
||||
reachable (not the ~2^1,047 nominal); this is not exploitable (the days used are 2^16, all distinct) and whether any
|
||||
reachable tuple is weak is the separate weak-day census of row F4.
|
||||
|
||||
## Consequences per tier
|
||||
|
||||
The era draw and the day-key seeding are protocol-wide and do not differ by card tier: the load width and load count are
|
||||
pinned, so every era is equally memory-bound and no 8, 12, 16 or 24/32 GB card is advantaged or disadvantaged by any draw
|
||||
(the measured six-era hash-rate spread is 1.3 percent on the RTX 5090, 3.2 on the RX 9070 XT, 0.8 on the M5 Max,
|
||||
`algorithm.md` 5.4). No drawn era parameter or day key makes a chip cheaper against a GPU: the richest datapath corner is
|
||||
1.0034x and is shared with the GPU. The one operational consequence is for the protocol, not a miner tier: the era draw's
|
||||
grinding resistance is not yet demonstrable because the 1-hour VDF and its certified checkpoint are not in the node, so
|
||||
the freeze of the draw procedure and the C_era cut rule must wait on the VDF landing and the finality lane's delay-
|
||||
soundness measurement.
|
||||
|
||||
## Gate line
|
||||
|
||||
- (a) harness: INCOMPLETE. No re-roll with a one-block delay (known-fail 0 of 6); a re-roll with no delay (known-pass 1 of
|
||||
6). The real gate (no re-roll inside the 2 s window) rests on the 1-hour VDF, which is not in the node; written argument
|
||||
above.
|
||||
- (b) census: PASS. No era class with gain over 1.1x at any fraction (richest 1.0034x, M = 1, absent in 2^24); the draw is
|
||||
a bijection on every sample and uniform in R, pos and the M bits.
|
||||
- (c) 64-bit seeding: PASS within spec intent. The spec intends 64 bits for the mixer stream; 2^16 days are all distinct;
|
||||
the one observation (2^64 reachable mixers) is recorded, not a flaw.
|
||||
|
||||
What a failure moves (plan 4.2 F7): the draw procedure or the C_era cut rule; a redraw rule for the era stream. Nothing in
|
||||
(b) or (c) moves them. (a) moves nothing in shipped code but gates the freeze of the draw procedure on the VDF.
|
||||
259
docs/analysis/attack-pass/f8-uniform.md
Normal file
259
docs/analysis/attack-pass/f8-uniform.md
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
# F8. Uniformity censuses of the class v4 derivation
|
||||
|
||||
Attack-pass row F8 (`docs/plans/cryptanalysis.md` section 4.2; the pass record `docs/analysis/attack-pass-2026-10.md`).
|
||||
Run 7 October 2026, 08:13 to 09:3x UTC (09:13 to 10:3x UK) on igneum-build-1. Verdict: **FINDING** (AP-F8-1 below).
|
||||
The line-index census is a PASS at its full sample size; the cross-hash item histogram is not uniform, and the cause
|
||||
is in the base program, inside the acceptance rule's blind spot.
|
||||
|
||||
## 1. Target
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Commit | `igneum-pow` at 924288d1 (`attack-pass`); the box built HEAD b2a411d1, whose `igneum-pow` is byte-identical (`git diff --stat 924288d1 HEAD -- igneum-pow` is empty) |
|
||||
| Class | `--program-class v4`: `V4_CLASS` = `mx8+sh256x27`, generator 4, mixer x8, the era layout drawn inside the class, the shadow block of 256 instructions x 27 reps |
|
||||
| Line index | `proto-metal/MEMHARD.md` section 1.6: `a = s[0] AND 0x003fffff`, 4,194,304 lines of 64 B, 8 dependent reads per item (`memhard.rs` `derive_items_mask`, `cache.line_const(s[0])`) |
|
||||
| Item index | `verify.rs` `load_index`: `y = rotl(x * M, R)`, the site's window `(y & (MASK >> k)) \| off`, then `Layout::split` removes the four interleave bits; 2^24 items at the 2^28-word dataset |
|
||||
| Reads per hash | 128 loads (16 sites x 8 iterations), so up to 1,024 cache lines per hash and 32,768 per warp. The spec's analytic bound of 832 lines per hash (`docs/spec/01-lottery-hash.md` line 347, 104 loads x 8) predates generator 2's fixed 16 load slots; the current bound is 128 x 8 = 1,024 |
|
||||
| Prior figures | `chip-model-v3.md` section 1: "median 128.00 distinct" items per hash (the 20,000-program census); `weak-program-census-2026-10-03.md` line 291: 127.7 distinct addresses per hash under the proposed generator |
|
||||
| Day | the devnet pack's day, `bind::day_bytes(20730)` (2026-10-04), day 0 of the growth schedule: a 2^26-word cache, a 2^28-word dataset. Census 1 uses days 20730 to 20745 |
|
||||
| Programs | p1 = the devnet epoch-0 derivation (epoch seed and era seed both the genesis hash `edc4fa84...fb07`, program id `c120d7963abdcd96`, attempt 0); p2 and p3 = chain-shaped seeds from tag strings (section 4), attempts 1 and 0 |
|
||||
|
||||
## 2. Method and harness
|
||||
|
||||
Harness: `tools/attack/f8-uniform/` (crate `attack-f8`, a path dependency on `igneum-pow`, nothing in the library
|
||||
modified). Built on the box through `tools/build-remote.sh`: sha256 `590668...f913` for the firings of 2.1,
|
||||
`ef8042...11b2` for sections 3, 4.1 and the first item runs (flat null, `log/c-*`, `log/d-*`), `890955...fbd3` for the
|
||||
window-model runs and the seed census (`log/e-*`). The committed source carries one later label fix (the
|
||||
"uniform-on-window" entropy reference in the per-site line is 16 - k_off bits; the 09:04 UTC logs print 16 - 2 k_off). Box scratch `/srv/builds/igneum-wt-attack/target-attack-f8/`
|
||||
(the name `target-*` is what the box's checkout clean spared at the time; the fix at b92a5fd4 now also spares
|
||||
`attack-*`). Every run: `nice -n 10 taskset -c 22-27,70-75`, 12 threads, under `flock -s /srv/builds/_locks/measure`
|
||||
in chunks under 3 minutes each (the longest, phase D, under 25 minutes).
|
||||
|
||||
Two mirrors, each trusted only while it agrees with the library bit for bit:
|
||||
|
||||
| Mirror | What it records | Agreement check | Result |
|
||||
|---|---|---|---|
|
||||
| `derive_traced`: `memhard::derive_items_mask` instruction for instruction (`mixer`, `round_key_mult`, `cache.line` from the library), the line index of every round kept | 8 line indices per item | every item of every day also derived by the library's `derive_items` and compared on all 16 words | 0 mismatches on 268,435,456 items (section 3) and on 16,777,216 items per table build (section 4) |
|
||||
| `Mirror::warp`: `verify::interpret_warp_init` for the class v4 op set, dataset words from a table of the day's 2^24 items, the item index and the source register of every load kept | 128 item indices per lane, the source value's saturation per position | the 32 hashes of warp 0 to 63 and of every 997th warp compared with `Epoch::hash_warp` | 0 mismatches on 95 warps per program (section 4) |
|
||||
|
||||
Three censuses:
|
||||
|
||||
1. `lines`: all 2^24 items of each of 16 consecutive day keys (2^28 item derivations, 2^31 line reads), the full 2^22-line
|
||||
histogram per round and pooled, the 2^16-bucket histogram (64 lines, one chained segment per bucket), a uniform
|
||||
SplitMix64 control of the same size.
|
||||
2. `warps`: 10^6 nonces (31,250 warps) of each of three programs: distinct lines and items per hash and per warp, the
|
||||
cross-hash item histogram, per-position diagnostics, an attribution pass from the hottest items back to the load
|
||||
positions that read them.
|
||||
3. `warps` at 2^26 nonces on p1: the one-epoch cross-hash item histogram at 512 expected reads per item.
|
||||
|
||||
The tests, defined before the runs:
|
||||
|
||||
- **6-sigma test**: the largest (and smallest) bucket of a histogram within 6 sigma of its expectation, sigma =
|
||||
sqrt(expectation). The gate's bucket is the 64-line segment for lines and the 64-item bucket for items. The
|
||||
full-resolution histograms are reported beside a uniform control of the same size, because at a small mean the
|
||||
Poisson tail puts the maximum of 4 million bins above 6 sigma by chance (control at mean 8: +6.72 sigma; at mean
|
||||
32: +5.83; at mean 512: +5.61).
|
||||
- **Hot-set test** (F8's definition, written for F9's reuse): sort items by read count; S_f = the share of all reads
|
||||
on the top-f fraction of items, for f in {0.1%, 0.5%, 1%}; E_f = the same share on a control of the same size drawn
|
||||
from the design's own null (flat uniform for lines; the window-weighted null for items, section 4.2); the excess
|
||||
X_f = S_f - E_f. **A hot set exists at f when X_f >= f**: after the chance excess is removed, the top f of items
|
||||
capture at least one extra proportional share, which is what an on-die copy of f of the items would have to win to
|
||||
matter. X_f / f is printed as the gain in proportional shares. The acceptance-style form of the same metric (for
|
||||
rule (c)'s 2,048 evaluations): per load position, the largest count of one masked address, and the count of
|
||||
saturated (0 or 2^32 - 1) source values.
|
||||
|
||||
### 2.1 The harness fires (known-fail and known-pass)
|
||||
|
||||
| Plant | What it does | 6-sigma test | Hot-set test | Log |
|
||||
|---|---|---|---|---|
|
||||
| `quarter-lines` | line index masked to a quarter of its range | buckets64 largest +75.97 sigma (2,231 at mean 512), smallest -22.63: FLAGGED | X_1% = +3.54% (S 5.60% vs control 2.06%), X/f = 3.5 at every f: FLAGGED | `log/a1-lines-quarter.log` |
|
||||
| `half-lines` | line index masked to a half | buckets64 largest +29.26 sigma: FLAGGED | X_1% = +1.25%, X/f = 1.25: FLAGGED | `log/a2-lines-half.log` |
|
||||
| `const-item` | one constant item at the first load site (1/16 of reads) | items buckets64 largest +92,682 sigma: FLAGGED | X_0.1% = +6.38%, X/f = 63.8: FLAGGED | `log/a4-warps-const-item.log` |
|
||||
| none, 2^22 items, one day | the real derivation at a small size | buckets64 largest +4.42 sigma, smallest -4.51: within 6 sigma (control +4.33) | X_f = -0.0004%, -0.0006%, -0.0010%: clear | `log/a3-lines-pass-small.log` |
|
||||
|
||||
Both tests fire on every plant and neither fires on the real line derivation. Log paths are under
|
||||
`/srv/builds/igneum-wt-attack/target-attack-f8/`.
|
||||
|
||||
## 3. Census 1: the line index over 2^28 derivations (PASS)
|
||||
|
||||
Sample reached: 16 days x 2^24 items = 268,435,456 item derivations, 2,147,483,648 line reads into 4,194,304 lines
|
||||
(512 expected per line, 32,768 per 64-line segment). Mirror mismatches against `derive_items`: 0 of 268,435,456.
|
||||
Log: `log/b-lines-16days.log`; histograms `out/lines-d20730-n16-i24-none-buckets64.txt` (65,536 rows) and
|
||||
`out/lines-d20730-n16-i24-none-full.u32le` (4,194,304 x u32).
|
||||
|
||||
| Histogram | Bins | Expected | Largest | Sigma | Smallest | Sigma | chi2/dof | Top 1% share |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| Pooled, 64-line buckets (the gate) | 65,536 | 32,768 | 33,645 | +4.84 | 31,998 | -4.25 | 1.00226 | 1.01427% |
|
||||
| Pooled, full 2^22 lines | 4,194,304 | 512 | 639 | +5.61 | 402 | -4.86 | 0.99937 | 1.11979% |
|
||||
| Control, 64-line buckets | 65,536 | 32,768 | 33,524 | +4.18 | 31,960 | -4.46 | 0.99930 | 1.01426% |
|
||||
| Control, full 2^22 lines | 4,194,304 | 512 | 639 | +5.61 | 408 | -4.60 | 0.99952 | 1.11956% |
|
||||
| Per round 0 to 7, full, pooled (64 per line) | 4,194,304 | 64 | 107 to 113 | +5.38 to +6.12 | 26 to 29 | -4.75 to -4.38 | 0.99855 to 1.00062 | 1.3483% to 1.3488% |
|
||||
| One day (20730), 64-line buckets | 65,536 | 2,048 | 2,291 | +5.37 | 1,859 | -4.18 | 0.99985 | 1.05826% |
|
||||
| One day, control, 64-line buckets | 65,536 | 2,048 | 2,250 | +4.46 | 1,874 | -3.84 | 1.00377 | 1.05901% |
|
||||
|
||||
Per day, the gate bucket's largest value ran +4.00 to +5.37 sigma on all 16 days (control +4.46), every day within
|
||||
6 sigma. Hot-set test on the pooled lines: X_0.1% = -0.00002%, X_0.5% = +0.00010%, X_1% = +0.00023% (X/f under
|
||||
0.0003): clear. Round 0, whose input is the sequential item index through the init `t * MUL[i] + RC[i]` and eight
|
||||
mixer applications, is as flat as rounds 1 to 7 (chi2/dof 0.99926; its +5.50 sigma maximum is below the control's
|
||||
+5.61 at the pooled size). Round 5's +6.12 sigma at mean 64 is one bin of 4 million at a Poisson tail where the
|
||||
control at mean 8 reached +6.72; its chi2/dof is 0.99855.
|
||||
|
||||
Gate line: the largest bucket is within 6 sigma of uniform (+4.84 on the 64-line buckets, +5.61 on the full 2^22
|
||||
lines, both at or below the control), chi2/dof 0.99937, no hot set. **PASS at 2^28 derivations.**
|
||||
|
||||
## 4. Census 2 and 3: distinct lines per hash and warp, and the cross-hash item histogram
|
||||
|
||||
Setup per program: the day's 16,777,216 items derived once into a table with their 8 lines (6 to 9 s on 12 threads,
|
||||
0 mismatches against `derive_items` on every item), then the warps interpreted from the table at 2.7 to 3.2 ms per
|
||||
warp per thread. Logs: `log/c-warps-p{1,2,3}-1e6.log` (first run, flat null) and `log/e-warps-p{1,2,3}-1e6.log`
|
||||
(windowed null, section 4.2); distributions `out/warps-<program>-d20730-n1000000-none-distinct.txt`, item histograms
|
||||
`...-items.u32le` (16,777,216 x u32), per-position tables `...-positions.txt`.
|
||||
|
||||
### 4.1 Distinct lines and items per hash and per warp (10^6 nonces each)
|
||||
|
||||
| Program | Epoch seed / era seed | Lines per hash min / p1 / median / max / mean | Items per hash min / median / mean | Lines per warp min / median / max / mean | Items per warp min / median / mean |
|
||||
|---|---|---|---|---|---|
|
||||
| p1 `c120d7963abdcd96` (devnet epoch 0) | genesis / genesis | 1,008 / 1,023 / 1,024 / 1,024 / 1,023.867 | 126 / 128 / 127.9989 | 32,579 / 32,636 / 32,680 / 32,635.84 | 4,090 / 4,096 / 4,095.41 |
|
||||
| p2 `82f0696f823e9c65` | `59cef1aa...bfdfa` / `9cba001f...1f69` | 1,014 / 1,023 / 1,024 / 1,024 / 1,023.871 | 127 / 128 / 127.9995 | 32,580 / 32,637 / 32,684 / 32,636.08 | 4,091 / 4,096 / 4,095.48 |
|
||||
| p3 `e282eed7d47e425e` | `c54e2ddd...c95d` / `1b04f607...b58a` | 999 / 1,016 / 1,024 / 1,024 / 1,023.600 | 125 / 128 / 127.9656 | 32,276 / 32,481 / 32,601 / 32,480.32 | 4,050 / 4,076 / 4,075.85 |
|
||||
| Uniform expectation | | 1,023.875 of 1,024 | 127.9995 of 128 | 32,640.3 of 32,768 | 4,095.50 of 4,096 |
|
||||
|
||||
Per hash, every program reads its 128 items and 1,024 lines as the design intends (p1 and p2 at the uniform
|
||||
expectation; p3 a shade under, 127.97 items, which is the same site-15 effect as the finding below: the saturated
|
||||
site repeats an item inside a hash 3 times in 100). Per warp, 32 lanes read 32,636 distinct lines of 2^22, a 2 MiB
|
||||
working set of cache lines and 256 KiB of dataset items, within 0.01% of uniform on p1 and p2.
|
||||
|
||||
### 4.2 The cross-hash item histogram and the window layer
|
||||
|
||||
The era layout's window layer (`docs/plans/era-layout.md` section 1.4, layer 8) makes each load site read an
|
||||
aligned half or quarter of the dataset with probability 2/3. The per-site item distribution is therefore not flat by
|
||||
design (the diagnostic's "worst bit" reads P(1) = 1.0000 or 0.0000 at every windowed site: the fixed top bits), and
|
||||
the summed item histogram has density steps between quarters. For p1 the 16 windows (site:shrink:offset
|
||||
`7:2:1 8:1:1 9:1:1 10:1:1 11:0:0 13:1:1 29:0:0 30:2:2 31:1:1 44:1:1 46:2:0 47:0:0 52:0:0 56:0:0 58:2:0 63:1:1`) give
|
||||
expected reads per item by quarter of 3.25 : 2.25 : 5.75 : 4.75 in sixteenths of the flat value. Against a flat
|
||||
uniform the 64-item buckets of p2 (a program without the finding) read +10.03 and -9.06 sigma, which is the window
|
||||
layer and not a flaw. The item tests are therefore judged against the **window-weighted null**: the expected count of
|
||||
every item from the program's 16 windows, and a control that draws each read from a uniformly chosen site's window.
|
||||
A chip gains nothing from the window steps: the union of the windows is the whole dataset every hour (era-layout.md
|
||||
section 7), the floor window is 2^26 words (256 MiB), and which quarter is dense changes with the program.
|
||||
|
||||
#### The window model (reproducible by the firms)
|
||||
|
||||
For load site s with window draw `(k_s, o_s)` at the 2^28-word dataset: `k = min(k_s, 28 - 26)`, the word window is
|
||||
`[o_s << (28 - k), (o_s + 1) << (28 - k))`; the item window is `[o_s << (24 - k), (o_s + 1) << (24 - k))` of
|
||||
`2^(24 - k)` items (the four interleave positions all lie below bit 16, so the top bits of the word index are the top
|
||||
bits of the item index). The expected reads per item is `E[t] = sum over sites s with t in window_s of N x 8 / 2^(24 - k_s)`
|
||||
for N nonces (8 iterations per site), a density constant on each quarter of the item space. The windowed control draws
|
||||
each of the N x 128 reads as (site = read index mod 16, item uniform on that site's window). Both controls are drawn from
|
||||
SplitMix64 with a fixed seed. The tests on items are run against E[t] (chi-square, sigma of the largest and smallest
|
||||
64-item bucket) and against the windowed control (the top-f shares); the flat uniform numbers are kept beside them as
|
||||
what an auditor sees first.
|
||||
|
||||
#### Results, 10^6 nonces per program, 128,000,000 reads (`log/e-warps-p{1,2,3}-1e6.log`)
|
||||
|
||||
| Program | Windows (k_off:offset per site) | Quarter densities (reads per item) | Buckets64 largest sigma, windowed (control) | chi2/dof windowed (control) | Top 0.1% share: real / window control / flat control | Ratio to window control at 0.1% (gate 1.2x) | Ratio to flat control | Hot set (X_f >= f) |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| p1 devnet epoch 0 | 2:1 1:1 1:1 1:1 0 1:1 0 2:2 1:1 1:1 2:0 0 0 0 2:0 1:1 | 6.20 / 4.29 / 10.97 / 9.06 | +45.77 (+4.95) | 1.2336 (0.9981) | 0.5458% / 0.2891% / 0.2429% | 1.888x BEYOND | 2.247x | yes at 0.1% (X/f 2.57) and 0.5% (1.20); not at 1% (0.46) |
|
||||
| p2 | 2:0 1:0 0 0 2:3 2:2 1:0 0 2:3 0 0 0 0 1:1 2:0 0 | 9.54 / 5.72 / 6.68 / 8.58 | +4.59 (+4.64) | 1.0061 (0.9986) | 0.2716% / 0.2639% / 0.2429% | 1.029x within | 1.118x | no (X/f 0.08, 0.05, 0.05) |
|
||||
| p3 | 1:0 0 0 2:2 0 0 1:0 1:0 1:0 2:2 2:2 1:1 0 0 0 0 | 7.63 / 7.63 / 10.49 / 4.77 | +12,245.66 (+5.06) | 907.67 (0.9993) | 4.5954% / 0.2792% / 0.2433% | 16.46x BEYOND | 18.92x | yes at every f (X/f 43.2, 9.9, 5.0) |
|
||||
|
||||
p2 is what the class is designed to be: against the window model its largest bucket is +4.59 sigma (the control +4.64),
|
||||
chi2/dof 1.006, the top 0.1% of items hold 1.029x their window-model share, and the flat-control ratio of 1.118x is
|
||||
the window layer. p1 and p3 are the finding (section 5). The one-epoch histogram at 2^26 nonces (8,589,934,592 reads,
|
||||
512 per item, `log/d-warps-p1-2e26.log`, flat null): p1's top 0.1% hold 0.5199% of reads against 0.1152% flat
|
||||
control (X/f 4.05), the top 1% 2.4946% against 1.1198% (X/f 1.37), item 0xca5b92 78,479 reads at a mean of 512, and
|
||||
site 15 feeds 6.37% of its reads into the top 0.1% in each of the 8 iterations; the excess grows with N as the
|
||||
control's chance excess shrinks, which is the signature of a structural skew. Distinct lines and items per hash and
|
||||
per warp at 2^26 nonces: 1,023.866 / 127.9989 / 32,635.6 / 4,095.41, unchanged from 10^6.
|
||||
|
||||
## 5. AP-F8-1: a saturated load source makes a cross-hash hot set (FINDING)
|
||||
|
||||
**What**: an accepted class v4 program can read one load site from a register whose last writes after its last
|
||||
injecting write are `or` (and, mildly, `mul`), so the site's address has fewer than 32 bits of entropy across nonces
|
||||
and the same items are read by many hashes. The per-hash figures (128 distinct items, 1,024 lines) stay intact; the
|
||||
cross-hash item histogram does not. It is not the window layer (p2 shows the window layer alone is clean against its
|
||||
model) and not the shadow block (iteration 0's load, which runs before any shadow block, is as hot as iterations 1 to
|
||||
7: p1 6.372% vs 6.371% to 6.378%; p3 71.9% vs 72.4% to 72.6%).
|
||||
|
||||
**Where it hides from rule (c)** (`accept.rs`, 2,048 evaluations of the base program): the tests are constant bits
|
||||
in FINAL register values, one address in ALL 32 lanes of a unit, saturated FINAL values, output-bit bias, and distinct
|
||||
addresses WITHIN a hash. A site whose address is concentrated across hashes but refreshed before the end of the
|
||||
iteration passes every one. Rule (a) accepts any write, `or` included, as the refresh between two loads from the same
|
||||
register (`check_stale_loads`); `Op::injects` (add, sub, xor, mad, shfl, load) is only used by rule (b), once per
|
||||
register per program.
|
||||
|
||||
**The index derivation at the hot site** (the "writers back to the last injecting one" lines of `log/e-warps-p*.log`):
|
||||
|
||||
| Program | Hot site | Source | Writes after the last injecting write | Site's reads into the top 0.1% of items (flat expectation) | Index entropy, 256-item buckets (uniform on window) | Saturated source (x = 0 or 2^32 - 1) | Most repeated address at one position in 2,048 evaluations (uniform: 1 to 2) |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| p3 | site 15, instr 62 | r5 | `load@17` then `or@19`, `or@30` | 72.43% (0.10%) | 13.411 bits (16) | 1.368% | 44 of 2,048; 32 saturated |
|
||||
| p1 | site 15, instr 63 | r6 | `add@51` then `rotl@53`, `or@61` | 6.93% (0.11%) | 14.985 bits (15) | 0.005% | 2 of 2,048; 0 saturated |
|
||||
| p2 (clean) | every site | | injecting, or bijective (`rotl`), or `mul`/`mulhi` | 0.41% to 0.97% (0.20%; the window densities) | 13.999 / 14.997 / 15.994 bits (14 / 15 / 16) | 0.000% | 2 of 2,048; 0 saturated |
|
||||
|
||||
In p3 two `or`s on r5 after its load make the source 1 with probability 7/8 per bit; x = 2^32 - 1 in 1.37% of
|
||||
evaluations and the images of the near-saturated values under the stride (`y = rotl(x * M, R)`, 256 x-values per
|
||||
item) pile onto a few items: 0xffdf69 takes 213,913 of the site's 8,000,000 reads (2.67%), the top 0.1% of items
|
||||
72.4%, and 4.6% of ALL reads of the hash land on 0.1% of the items. In p1 one `or` after `rotl(add)` gives 3/4 per bit
|
||||
on the ORed positions: no saturation to speak of (0.005%), but 6.9% of the site's reads on 0.11% of the items (the
|
||||
hot items share the low 20 bits `5b92`: 0xca5b92, 0x8a5b92, 0xaa5b92, 0xba5b92, 0x825b92, 0xe65b92, 0x985b92), a
|
||||
2.6x proportional excess at f = 0.1%. p2's `mul` sites (10, 13: `mul` after a load or a shuffle) read 0.65% and 0.70%
|
||||
into the top 0.1% against 0.41% and 0.48% for their window class (an even multiplier zeroes low bits; the hot items
|
||||
0xd6a680, 0xe44400, 0xd25600 end in zero bits), a mild effect that the window-model ratio (1.029x) absorbs.
|
||||
|
||||
**How common** (the seed census, 64 chain-shaped programs p4 to p67, 262,144 nonces each, `log/e-seed-census-4-67.log`,
|
||||
`out/seed-census-d20730-n262144-p4-67.txt`): CENSUS-LINE
|
||||
|
||||
**Reproduction**: `attack-f8 warps --program 3 --nonces 1000000 --diag 1` (or `--program 1`); the acceptance-style
|
||||
numbers come from the same run's "acceptance-style" line. The program is `Epoch::chain_program(epoch_seed, Some(era),
|
||||
ProgramClass::V4, label)` with the seeds of section 4.1.
|
||||
|
||||
**Proposed fix** (not applied; `igneum-pow` untouched, the Counter ASIC lane re-gates on `ca3-v4-uniform` with this
|
||||
harness):
|
||||
|
||||
1. Rule (a'), static: between the last injecting write of a load's source register and the load (cyclically), no
|
||||
`or` and no `mul` writes that register; `rotl`, `rotr` and `mulhi` may (bijective, or measured flat: p2 site 15
|
||||
reads `mulhi` after `add` at 1.00x). This rejects p1 and p3 at draw time and costs nothing at run time. Programs
|
||||
rejected are redrawn as today (`MAX_ATTEMPTS` 32); the census gives the rejection rate.
|
||||
2. Rule (c'), dynamic, the same 2,048 evaluations: no load site reads a saturated source (0 or 2^32 - 1) in more
|
||||
than 2 evaluations, and no address repeats more than 4 times at one position (uniform expectation 1 to 2; p3 shows
|
||||
44 and 32). This catches the strong class only; p1's class needs about 2^16 evaluations to show at a site (65,536
|
||||
nonces: largest item count 67 at a mean of 0.5), so (a') is the rule that closes it and (c') is the check that
|
||||
fails loudly if (a') is ever loosened.
|
||||
3. Packs re-cut for the seeds the new rule rejects (the devnet epoch-0 program p1 is one of them: its site 15 is
|
||||
`or@61`), with the gate pack ids re-pinned; the chain's own epochs redraw automatically.
|
||||
|
||||
**Reuse for F9**: the hot-set metric (section 2) on the per-program item histogram at 2^18 nonces, and the
|
||||
acceptance-style pair (most repeated address at a position, saturated sources at a position) at 2,048 evaluations,
|
||||
are both emitted by `warps --programs a..b`; a header-grinding search that steers a program to a hot set would show as
|
||||
ratio-to-window-model above 1.2x at f = 0.1%.
|
||||
|
||||
## 6. Consequences per tier
|
||||
|
||||
| Number | What it means | Per tier |
|
||||
|---|---|---|
|
||||
| Line index uniform at 2^28 derivations (largest segment +4.84 sigma, chi2/dof 0.99937) | the 256 MiB cache has no hot segment: a chip or a card cannot serve the 8 dependent reads of an item from a cache smaller than the whole 256 MiB (the floor window of era-layout.md) | no change for any card; the verifier's cache stays 256 MiB in RAM on every node |
|
||||
| Distinct lines per hash 1,023.87 of 1,024, items 127.999 of 128 (p1, p2); per warp 32,636 lines, 4,095 items | the per-hash working set is 64 KiB of cache lines and 8 KiB of items, per warp 2 MiB of lines and 256 KiB of items; the item-derivation chip's "128 items per hash" input (`chip-model-v3.md`) stands | the 8 GB card and up: unchanged; the recompute chip pays 128 derivations per hash, as modelled |
|
||||
| p3-class programs: 4.6% of all dataset reads on 0.1% of items (1 MiB of a 1 GiB dataset); p1-class: 0.59% on 0.11% | a stored-dataset chip with 1 MiB of on-die SRAM serves 4.6% of its reads without touching DRAM on such an epoch; a GPU's L2 (96 MiB on the 5090, 64 MB Infinity Cache on the 9070 XT, vendor figures) holds the same 1 MiB, so both sides gain the same 4.6% of reads and the chip's edge from it is about 0 (the per-joule edge of `evidence.md` row 17 is a DRAM-read figure; a 4.6% read saving on both sides moves it by under 5% on such epochs). The recompute chip (f = 0, SRAM cache) caches the derived hot items and skips up to 4.6% of its 128 derivations per hash on such epochs, a 4.8% rate gain on those epochs only | home cards 8 to 32 GB, rigs, pools: no action; a few percent of epochs run a few percent faster for everyone with an L2. The verifier: `MemhardCpu::fetch` dedupes within a fetch only, so no change. The chip model: the headline 2.1x at k = 1 moves by under 5% on affected epochs and 0 on others; the fix below returns it to 0 everywhere |
|
||||
| The acceptance rule's blind spot (cross-hash concentration at one site) | a program class property, not a day or era property: the same seed is hot on every day and under every era, so a chip or a pool that selects epochs cannot gain more than the epoch's own 4.6%; but the public claim "the item map is uniform per program up to the window layer" is false for the affected fraction of seeds until rule (a') lands | the fix is a generator rule plus packs re-cut: a class change under the 95% signalling rule if it lands after the flip, a plain re-cut if it lands in the class v4 cut itself (the lane's call) |
|
||||
|
||||
## 7. Gate line and verdict
|
||||
|
||||
| Gate (plan 4.2 F8, the same as 1.4 (4)) | Result | Status |
|
||||
|---|---|---|
|
||||
| The largest bucket within 6 sigma of uniform on the stated sample sizes (line index, 2^28 derivations) | +4.84 sigma on 64-line segments, +5.61 on 2^22 lines (control +4.18 / +5.61), chi2/dof 0.99937 | PASS |
|
||||
| The item distribution within 6 sigma of uniform (against the window model, the design's own null) | p2 +4.59 sigma (control +4.64); p1 +45.77; p3 +12,245.66 | FAIL on p1 and p3 |
|
||||
| No hot set under 1% of items among passing seeds (10^6 nonces on three programs; the 64-seed census at 2^18) | p2 none; p1 top 0.1% at 1.888x the window model (2.247x flat), X/f 2.57; p3 16.46x (18.92x flat), X/f 43.2; census: 31 of 64 seeds over 1.2x of the window model, 23 with a hot item | FAIL |
|
||||
| The Counter ASIC lane's record gate: top 0.1% within 1.2x of the window-model control on every seed | p2 1.029x; p1 1.888x; p3 16.46x; census: 31 of 64 seeds over 1.2x (median 1.17x, p90 2.70x, max 13.09x on p31) | FAIL |
|
||||
|
||||
**Verdict: FINDING (AP-F8-1).** The line index passes at 2^28 derivations. The cross-hash item histogram fails
|
||||
the hot-set gate on 2 of the 3 named programs (one of them the live devnet epoch-0 program) and on 31 of 64 seeds (48 percent) of of
|
||||
the 64-seed census, from `or` (and mildly `mul`) writes on a load's source register after its last injecting write,
|
||||
outside every test of rule (c). What it moves: not the mask or the fold (the derivation is uniform) but the
|
||||
acceptance rule, (a') and (c') above, and the packs re-cut. Ownership: the Counter ASIC lane (generator and rule),
|
||||
re-gated with this harness on the fixed branch; the row reads FIXED-AND-PASSED when every seed of the census passes
|
||||
both the hot-set test and the 1.2x gate under the new rule.
|
||||
|
||||
Sample sizes reached: 2^28 derivations (lines); 10^6 nonces on three programs (distinct lines, hot set); one epoch at
|
||||
2^26 nonces (cross-hash histogram); 64 seeds at 2^18 nonces (the census).
|
||||
|
||||
Times UTC in the logs; the runs ran 08:13 to 09:2x UTC on 7 October 2026 (09:13 to 10:2x UK).
|
||||
269
docs/analysis/attack-pass/f9-grind.md
Normal file
269
docs/analysis/attack-pass/f9-grind.md
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
# F9: acceptance edges, the hot-set search, header grinding
|
||||
|
||||
Attack-pass row F9 of `docs/plans/cryptanalysis.md` section 4.2 (record: `docs/analysis/attack-pass-2026-10.md`).
|
||||
Sub-agent attack-f9, 7 October 2026. Status: IN PROGRESS (rewritten as each run lands; the numbers below are the
|
||||
ones already final, each with its log).
|
||||
|
||||
## Target
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Commit | 924288d1 (branch attack-pass, worktree igneum-wt-attack) |
|
||||
| Generator | 4, class v4 `mx8+sh256x27` composed with the era draw (`LoadClass::era(V4_CLASS, E, [4 bytes])`), era seed E = the devnet epoch-0 seed `edc4fa84...fb07` (`proto-cuda/packs-ca3-v4/v4-devnet-epoch0/seeds.txt`) |
|
||||
| Rule | `igneum-pow/src/accept.rs`: (a) stale load sources, (b) injecting writes, (c) the 2,048-evaluation dynamic test on the closed-form stand-in `dataset_elem` at 2^28 words with init words = seed words; redraw on rejection up to 32 attempts |
|
||||
| Header binding | `igneum-pow/src/bind.rs`: init words `I = seed_words_from_bytes("igneum-block/" \|\| H \|\| nonce_hi_le32)`, one `I` per 32-lane warp, the lane nonce in the low 32 bits |
|
||||
| Memory-hard dataset for the edges | the devnet day 20730 (`day_seed_hex 69676e65756d2d6461792ffa50000000000000`), class v4 shape (mixer x8, cache 2^26 words, dataset 2^28 words), `Epoch::chain_dataset_day` |
|
||||
| Card | RunPod RTX 5090 (170 SMs, 32,120 MiB, driver 570.195.03, CUDA 12.8.1), pack `v4-devnet-epoch0` built there with `nvcc -O3 -arch=sm_120` |
|
||||
|
||||
## Known-failed shape
|
||||
|
||||
A seed grind that steers a program to a hot cache set for DRAM locality, or an edge where the closed-form stand-in
|
||||
disagrees with the live verifier in the attacker's favour.
|
||||
|
||||
## Gate
|
||||
|
||||
Zero passing programs with a hot set under 1 percent of items among 10^6 seeds; the grinding gain under 1 percent of
|
||||
rate at any search cost. What a failure moves: the closed-form stand-in replaced by the live verdict at the edges; a
|
||||
locality term in rule (c).
|
||||
|
||||
## Harness
|
||||
|
||||
`tools/attack/f9-grind/` (crate `attack-f9`, `igneum-pow` as a path dependency, nothing in igneum-pow edited; built
|
||||
on igneum-build-1 through `tools/build-remote.sh`; the binary on the box at
|
||||
`/srv/builds/igneum-wt-attack/tools/attack/f9-grind/target/release/attack-f9`):
|
||||
|
||||
| Sub-command | What it does |
|
||||
|---|---|
|
||||
| `selftest` | the firings listed below |
|
||||
| `edges` | sub-row (a): every candidate of every seed through the re-implemented dynamic test twice, closed form and memory-hard, every metric of rule (c) measured to the end (no early abort) with its margin; the attempts continue until both stand-ins have accepted, so the chosen program under each is known |
|
||||
| `hotset` | sub-row (b): the seed's accepted program, its 2,048 x 128 address record under the acceptance init and under a block init; per site the nonce-independent address bits, the distinct addresses and the most-read address; the histogram at bucket scales 2^8 to 2^24 words against a window-aware Poisson expectation (the era windows send a site to the dataset, a half or a quarter of it) with a Bonferroni tail; the taint count of init-determined loads |
|
||||
| `inspect` | one seed's program with every site that repeats an address |
|
||||
| `grind`, `table-random` | sub-row (c), CPU side: the init-determined load sites of the devnet epoch-0 program, the per-warp search over K nonce_hi values for the fewest distinct 128 B lines inside those load instructions (`--mode intra`, what the coalescer merges) or across them (`lines`, `pages`), the search cost per hit, and the per-warp init tables the card reads |
|
||||
| `reference` | the 64 bound hashes the card's known-pass compares against; the file used on the pod came from the pre-built `igneum-pow hash-bound` instead (`ref.txt`, sha256 e831458a...) |
|
||||
| `summarise.py` | the census summaries quoted below |
|
||||
|
||||
`tools/attack/f9-grind/pod/` (the card): `make-variants.py` copies the pack's `kernel_bound.cu` into five kernels
|
||||
(per-warp init table; the five init-determined loads broadcast to lane 0's address; every load broadcast; the first
|
||||
such load broadcast; lane 1 reading lane 0's address at the first such load), `f9-host.cu` fills the cache and dataset
|
||||
with the pack's own kernels, checks them against `vectors.h`, checks the bound hash against the reference, checks the
|
||||
per-warp kernel on an all-equal table against the honest kernel, then times the eight variants in interleaved rounds;
|
||||
`run.sh` builds on the pod, samples `nvidia-smi` once a second and joins the samples to the phases (`join-power.py`).
|
||||
|
||||
Hot-set metric (F8's record `docs/analysis/attack-pass/f8-uniform.md` did not exist when this harness was written, so
|
||||
the metric is defined here). Strict reading, "any hot bucket": a site with 7 or more nonce-independent address bits
|
||||
(support at most 2^21 of 2^28 words, 0.78 percent of items; the window's own fixed bits not counted), or any bucket
|
||||
of at most 2^20 words (0.39 percent of the dataset) at scales 2^8, 2^12, 2^16, 2^20 whose count has a Poisson tail
|
||||
against its window-aware expectation under 10^-6 after the Bonferroni correction. Gate reading, "flagged": the reads
|
||||
above expectation in those hot buckets (the hot share, what a cache of the hot set saves at most) reach 1 percent of
|
||||
the program's reads, or a site has 7 constant bits.
|
||||
|
||||
## Firings (the harness is trusted only after these)
|
||||
|
||||
Log: `/srv/builds/igneum-wt-attack/attack-f9/selftest.log` (copy in the Mac scratchpad `f9-box/selftest.log`).
|
||||
|
||||
| Check | Known-pass | Known-fail | Result |
|
||||
|---|---|---|---|
|
||||
| 1 | the re-implemented dynamic test against `accept::check` on 300 class v4 candidates: every verdict, the first failing condition, and distinct, saturated and bias of every accepted report equal | | PASS (300 candidates, 16 rejected by accept, all equal, 1.5 s) |
|
||||
| 2 | both stand-ins forced equal (closed form twice) on 200 candidates | | PASS, 0 disagreements |
|
||||
| 3 | | the memory-hard stand-in gives different words: distinct 262,117 against 262,106, bias 56 against 64 on one program | PASS (they differ) |
|
||||
| 4 | 50 accepted programs, none with 7 constant bits (worst 0) | 50 plants (an accepted program rewritten to `xor a,a; add a,a,256; mulhi a,b` before a load from `a`, 48 of 50 still pass rule (c)) all flagged (support 256 words, site distinct 255 or 256) | PASS for the plant; 4 of the 50 clean programs have a hot bucket (sub-row (b): that is the finding, not a harness fault) |
|
||||
| 5 | taint on the devnet epoch-0 program against the hand reading of `kernel_bound.cu`: loads 7, 8, 9, 10 read r7, r4, r2, r0 (no load before them); load 31 reads r5 = r5 x r4 from instruction 12, both untouched by any load; loads 11, 13, 29, 30 read r1, r6, r4, r3, each written by an earlier load or by `mad` from r7 after load 10 | | PASS: sites (0,7) (0,8) (0,9) (0,10) (0,31) |
|
||||
| card 1 | cache FNV 448274a57f508cbc, dataset head, last word and 64 samples, the 96 pack vectors | | PASS (`pod log/host.log`) |
|
||||
| card 2 | the bound hash against the 64 reference lines of `igneum-pow hash-bound` (nonce_hi 0, prehash 000102..1f) | | PASS, 0 wrong |
|
||||
| card 3 | the per-warp kernel on an all-equal table equals the honest kernel on 64 lanes | the two-init table: warp 0 equal, warp 1 differs in 32 of 32 lanes | PASS both |
|
||||
| card 4 | | the forced kernels change the hash: forced4 64 of 64 lanes, forcedall 64, forced1 64, pair 64 | PASS (they fire) |
|
||||
| card 5 | | a deliberately locality-maximising choice shows a measurable change: `pair` (one line of 4,096 saved per warp) +0.21 percent, `forced1` (31 lines) +6.8 percent, `forced4` (155 lines) +43.3 percent, `forcedall` +181.9 percent in the smoke run | PASS (measurable from one saved line up) |
|
||||
|
||||
## Sub-row (a): the edges
|
||||
|
||||
Run: `attack-f9 edges` over seeds `igneum-f9/0` to `igneum-f9/99999`, 8 threads on cores 28-31,76-79 in 10,000-seed
|
||||
chunks under a shared hold of the box measure lock (`run-census.sh`); output `edges.part*.tsv`, summary by
|
||||
`summarise.py edges`. The first 20,000 seeds (parts 0 and 1) are summarised here; the full 10^5 replaces this table
|
||||
when the run ends.
|
||||
|
||||
| Quantity | First 20,000 seeds |
|
||||
|---|---|
|
||||
| Candidates evaluated | 21,020 |
|
||||
| Verdicts agreeing | 21,007 |
|
||||
| Disagreements | 13 (0.062 percent of candidates; the 3 October census had 39 in 100,000 on its generator) |
|
||||
| Seeds whose chosen program differs | 13 (every disagreement moves the chosen attempt, because the next attempt was accepted by both) |
|
||||
| Exhausted seeds | 0 on either stand-in |
|
||||
| Rejected by the closed form / by the memory-hard dataset | 1,013 / 1,014 (850 static, the rest (c)) |
|
||||
| First failing (c) condition, closed form | const_bit 80, saturated 54, distinct 24, lane_const 4, bias 1 |
|
||||
| Accepted margins, closed form | saturated at most 81 of 164, bias at most 120 of 136, distinct sum at least 247,335 (bound 245,760), nearly constant final bits up to 2,047 of 2,048 |
|
||||
| Accepted margins, memory-hard | saturated at most 82, bias at most 115, distinct at least 247,678 |
|
||||
|
||||
The 13 disagreements: 12 are `const_bit`, a final register bit equal in all 2,048 evaluations on one dataset and in
|
||||
2,044 to 2,047 of them on the other (7 where the closed form accepts, 5 where the memory-hard dataset accepts); 1 is
|
||||
`bias`, output bias 155 against 93 (6.9 against 4.1 sigma, the two draws' difference 2.7 sigma of sampling noise),
|
||||
where the memory-hard dataset accepts. No disagreement on saturation, lane-constant sites or the distinct count: those
|
||||
metrics are the same to within 20 on both datasets. What an attacker gains from a program the closed form accepts
|
||||
and the live dataset would reject: a register whose final bit is pinned in 2,047 of 2,048 hashes instead of 2,048,
|
||||
which no test downstream of the fold can see (the 64 output bits stay within 120 of 1,024 on every accepted program)
|
||||
and which no chip can turn into skipped work; the reverse direction loses the chain a program with one pinned bit.
|
||||
Either way the chosen program moves to the next attempt, which both stand-ins accept. Nothing in the attacker's
|
||||
favour: the verdict's dependence on the stand-in is a 0.06 percent coin flip on a one-bit property.
|
||||
|
||||
## Sub-row (b): the hot-set search
|
||||
|
||||
Run: `attack-f9 hotset` over seeds `igneum-f9/0` to `igneum-f9/999999`, 8 threads on cores 32-35,80-83 in
|
||||
100,000-seed chunks; output `hotset.part*.tsv`. A 2,000-seed timing sample (`hotset-timing.tsv`, seeds 5,000,000 to
|
||||
5,001,999) is summarised here; the 10^6 census replaces it when the run ends.
|
||||
|
||||
| Quantity | 2,000-seed sample |
|
||||
|---|---|
|
||||
| Programs with any hot bucket (strict) | 161 of 2,000 (8.1 percent) |
|
||||
| Programs flagged at the gate reading (hot share at least 1 percent of reads) | 21 of 2,000 (1.05 percent) |
|
||||
| Worst hot share | 10.3 percent of the program's reads (seed 5,000,968) |
|
||||
| Sites with 7 or more constant address bits | 0 (max 0) |
|
||||
| Fewest distinct addresses at a site in 2,048 evaluations | 434 |
|
||||
| Most evaluations reading one address at a site | 767 of 2,048 |
|
||||
| Init-determined loads in iteration 0 (programs by count) | 1: 234, 2: 573, 3: 594, 4: 368, 5: 179, 6: 42, 7: 10; none after iteration 0 |
|
||||
|
||||
FINDING F9-1 (or-saturation hot words). `inspect --seed 5000968` (`inspect-5000968.log`): the load at instruction 33
|
||||
reads r4; r4 is written by `or r4 |= r0` (20), `mulhi` (27) and `or r4 |= r6` (28), and r6 itself by `or r6 |= r7`
|
||||
(7). `or` is absorbing toward all ones: after two `or` writes from independent words every bit is set with
|
||||
probability 7/8 and the whole register with probability (7/8)^32 = 1.4 percent; chained across iterations the mass
|
||||
grows, and on this program r4 is 0xffffffff at that site in 731 to 739 of 2,048 evaluations in iterations 1 to 7
|
||||
(36 percent). The site then reads one word, `rotl(0xffffffff x M, R) & window | offset` = 0x0ca59e4c for a full
|
||||
window and 0x04a59e4c, 0x08a59e4c, ... for the windowed sites; near-all-ones values add a few hundred more. The
|
||||
same word family appears in every flagged program (seeds 4,000,001, 4,000,037, 4,000,040 in the selftest: `or`
|
||||
writes at 54 and 55 before the load at 60, or at 1 before the load at 3). Rule (c) does not see it: the saturation
|
||||
test counts final register values only (the register is overwritten before the end), the lane-constant test needs
|
||||
all 32 lanes equal, the distinct test counts per lane per hash (the hot word repeats across iterations, so it
|
||||
costs one distinct of 128), and the output bias stays within tolerance. The 3 October census measured an
|
||||
`or_sat_frac` per program (section 7.3, max 0.0102) but the adopted rule kept only the final-value count.
|
||||
|
||||
What it is worth to an attacker: nothing asymmetric. The hot words are the same for every lane that saturates, so
|
||||
the GPU's coalescer and L1 already serve them without a DRAM transaction, and a chip gets exactly the same. What it
|
||||
costs the design: those programs do fewer memory-hard reads than rule (c) promises (up to 10 percent fewer on the
|
||||
worst program in 2,000, at least 1 percent fewer on about 1 program in 100), so the per-hash memory work of class
|
||||
v4 is not the uniform 128 random reads the chip model assumes on every epoch. Gate reading: FAIL in the strict
|
||||
reading (zero passing programs with a hot set under 1 percent of items), FAIL in the share reading too (programs
|
||||
with a hot set capturing at least 1 percent of reads exist at about 1 percent of epochs). Proposed fix, for the hash
|
||||
lane (not applied here): a per-site line in rule (c), "every load site reads at least 2,000 distinct addresses over
|
||||
the 2,048 evaluations" (uniform gives 2,048 minus 0.008 expected repeats; the saturated sites read 434 to 1,855),
|
||||
computed from the addresses the test already collects (one sort of 2,048 per site, 128 sites, under a millisecond);
|
||||
the redraw rate rises by about the strict-reading fraction (8 percent of candidates) unless the threshold is placed
|
||||
at the share reading. The alternative, dropping the `or` family from the draw table, changes the frozen weights and
|
||||
is for the lane to weigh. Class check: a chip gains nothing today, but a stand-in that lets 1 percent of epochs run
|
||||
with a 1 to 10 percent lighter memory side is a published-number problem (evidence row 17's per-hash reads).
|
||||
|
||||
(the 10^6 numbers and the hot-share distribution replace the sample when the census ends)
|
||||
|
||||
## Sub-row (c): header grinding
|
||||
|
||||
### What an attacker can steer
|
||||
|
||||
Only a load whose address register has not yet absorbed a dataset word is a function of the init words and the
|
||||
nonce alone (taint analysis, `init_determined_sites`). On the devnet epoch-0 program these are the loads at
|
||||
instructions 7, 8, 9, 10 and 31 of iteration 0; from iteration 1 every register is tainted. Over the 2,000-seed
|
||||
sample the count is 1 to 7 per program, median 3, always in iteration 0 only. Everything after depends on dataset
|
||||
words the miner must fetch first. The init words themselves are an FNV hash of the header and nonce_hi, so the
|
||||
attacker cannot choose them, only draw them; and one draw serves a whole warp (the shuffles couple the 32 lanes),
|
||||
so a per-lane draw costs 32 hashes per lane.
|
||||
|
||||
### The search (CPU)
|
||||
|
||||
`grind` draws K init words per warp (nonce_hi 0 to K-1 under the fixed prehash) and keeps the one with the fewest
|
||||
distinct 128 B lines among the init-determined loads. Each try costs 32 lanes x (8 init + 32 prefix instructions) =
|
||||
1,280 lane-instructions; the warp's hash costs 32 x (512 + 55,296) = 1,785,856 lane-instructions, the derivation
|
||||
not counted. Logs: `grind-k10-crosssite.log` (lines counted across the five sites: coincidences that are at best an
|
||||
L2 hit), `grind-k10-pages.log` (2 KB pages across the sites), and the `intra` runs (lines inside one load
|
||||
instruction, what the coalescer merges into one transaction) that feed the card.
|
||||
|
||||
| Metric | K | Warps | Mean lines or pages saved per warp (of 4,096 loads) | Warps improved | Search per warp in hashes |
|
||||
|---|---|---|---|---|---|
|
||||
| lines across the sites | 2^10 | 524,288 | 0.895 (0.022 percent) | 89 percent | 0.73 |
|
||||
| 2 KB pages across the sites | 2^10 | 65,536 | 1.455 (0.036 percent) | 98 percent | 0.73 |
|
||||
| lines inside one instruction (intra) | 2^10 | 2^17 | (pending) | | 0.73 |
|
||||
| lines inside one instruction (intra) | 2^14 | 2^17 | (pending) | | 11.7 |
|
||||
|
||||
### The card (RTX 5090)
|
||||
|
||||
Smoke run (1 round of 2 s per variant, `pod smoke` logs): the calibration of what one saved line is worth.
|
||||
|
||||
| Variant | What changes | MH/s | Against honest | W | MH/J against honest |
|
||||
|---|---|---|---|---|---|
|
||||
| honest | the pack kernel, one init per dispatch | 141.76 | | 482 | |
|
||||
| perwarp-random | per-warp init table, no search | 141.73 | -0.02 percent | 486 | -0.7 percent |
|
||||
| perwarp-k10 | per-warp table, best of 2^10 (cross-site table) | 141.74 | -0.01 percent | 487 | -1.0 percent |
|
||||
| perwarp-k14 | (the same table in the smoke run) | 141.74 | -0.01 percent | 488 | -1.1 percent |
|
||||
| pair | lane 1 reads lane 0's address at load 7: 1 line of 4,096 saved | 142.05 | +0.21 percent | 490 | -1.4 percent |
|
||||
| forced1 | load 7 broadcast: 31 lines saved | 151.39 | +6.8 percent | 506 | +1.8 percent |
|
||||
| forced4 | loads 7, 8, 9, 10, 31 broadcast: 155 lines saved | 203.11 | +43.3 percent | 530 | +30 percent |
|
||||
| forcedall | every load broadcast: 3,968 lines saved | 399.61 | +182 percent | 520 | +161 percent |
|
||||
|
||||
Reading: the class v4 kernel on the 5090 is bound by its random reads (141.8 MH/s x 128 = 18.1 G reads per second,
|
||||
the card's measured random-read ceiling in `docs/bench-log.md`), and a load instruction completes when its slowest
|
||||
lane's transaction returns, so one saved line is worth about 0.2 percent of rate, 31 lines 6.8 percent, and the
|
||||
five init-determined loads fully coalesced 43 percent. That ceiling is unreachable by search: it needs the 32
|
||||
lanes' 28-bit addresses to fall in one line at five sites, probability 2^-115 per draw. What a draw can reach is one
|
||||
coalesced pair at one site (probability 5 x C(32,2) / 2^23 = 3 x 10^-4 per try, about 3,400 tries per pair);
|
||||
two pairs need about 6 million tries, m pairs about 3,400^m / m! tries. One pair is worth 0.2 percent of one warp's
|
||||
hash and costs 3,400 x 1,280 lane-instructions = 2.4 hashes of search. The measured per-warp tables (5 rounds of
|
||||
8 s, pending) are the direct check.
|
||||
|
||||
(the full run's table replaces the smoke run when it ends)
|
||||
|
||||
## Consequences per tier
|
||||
|
||||
(filled in with the verdict)
|
||||
|
||||
## Logs
|
||||
|
||||
| Log | Path |
|
||||
|---|---|
|
||||
| selftest, inspect, grind, census parts and drivers | `/srv/builds/igneum-wt-attack/attack-f9/` on igneum-build-1 (`selftest.log`, `inspect-*.log`, `grind-*.log`, `edges.part*.tsv`, `edges.driver.log`, `hotset.part*.tsv`, `hotset.driver.log`, `hotset-timing.tsv`, `ref.txt`, `table-*.bin`) |
|
||||
| card smoke run and full run | the pod's `/workspace/f9/podjob/smoke/log/` and `log/` (`run.log`, `nvcc.log`, `host.log`, `power.csv`, `power-by-variant.txt`, `sha256.txt`), copied to `/srv/builds/igneum-wt-attack/attack-f9/pod/` at the end |
|
||||
|
||||
### The card, the measurement (RTX 5090 pod ap-f9, `pod/host.log`, sha256 83b1372c..., copied to
|
||||
`/srv/builds/igneum-wt-attack/attack-f9/pod/`)
|
||||
|
||||
Per-warp header grinding at K = 2^14 draws per warp against the honest kernel, 5 interleaved rounds of 8 s each:
|
||||
141.62 against 141.61 MH/s, +0.004 percent of rate, sd 0.003, at 11.7 hashes of search per hash. The unreachable
|
||||
ceiling (the five init-determined loads fully coalesced, `forced1` extended) is +43 percent. Gate: the grinding gain
|
||||
under 1 percent of rate at any search cost. Sub-row (c): PASS. Pod time about 1 h 50 min from 09:02 UK; destroyed on
|
||||
the lane's done line.
|
||||
|
||||
## Full censuses (box 1 parts 0 to 7 and 0 to 6; box 2 parts `edges-b2`, `hotset-b2` after the lane's move to
|
||||
build-2 at 12:2x UK; `summarise.py` over all parts, 12:5x UK)
|
||||
|
||||
### (a) The edges on generator 4, 10^5 seeds
|
||||
|
||||
| Quantity | 100,000 seeds |
|
||||
|---|---|
|
||||
| Candidates evaluated | 105,064 |
|
||||
| Verdicts agreeing | 105,030 |
|
||||
| Disagreements | 34 (0.032 percent of candidates; the 3 October census had 39 in 100,000 on its generator) |
|
||||
| By kind | `const_bit` 29 (closed form accepts 17, memory-hard accepts 12); `bias` 4 (3 and 1); `lane_const` 1 (memory-hard accepts) |
|
||||
| Seeds whose chosen attempt differs | 34, every one moving to the next attempt, which both stand-ins accept; exhausted 0 on either |
|
||||
| Rejected, closed form / memory-hard | 5,046 / 5,048 (static 4,201; then const_bit 424 / 428, saturated 275 / 275, distinct 112 / 112) |
|
||||
| Accepted margins, closed form | saturated at most 148 of 164, bias at most 121 of 136, distinct sum at least 247,335 (bound 245,760) |
|
||||
| Accepted margins, memory-hard | saturated at most 157, bias at most 126, distinct at least 247,571 |
|
||||
|
||||
The 20,000-seed reading holds at 10^5: the stand-ins disagree on a one-bit property (a final register bit pinned in
|
||||
2,047 of 2,048 hashes against 2,048) and on four programs' output bias within sampling noise, never on saturation
|
||||
or the distinct count, and never in the attacker's favour. Gate: the 39 edge disagreements reproduced and bounded.
|
||||
Sub-row (a): PASS.
|
||||
|
||||
### (b) The hot-set search, 10^6 seeds
|
||||
|
||||
| Quantity | 1,000,000 seeds |
|
||||
|---|---|
|
||||
| Programs with any hot bucket (strict) | 75,400 (7.5 percent) |
|
||||
| Programs flagged at the gate reading (hot share at least 1 percent of reads, or 7 constant address bits) | 11,696 (1.17 percent) |
|
||||
| Worst hot share | 17.3 percent of the program's reads (seed 842871) |
|
||||
| Hot-share bands (block init) | 0: 932,106; under 0.1 percent: 11,721; under 0.5: 3,645; under 1: 41,581; 1 percent and over: 10,947 |
|
||||
| Sites with 7 or more constant address bits | 0 (max 6) |
|
||||
| Fewest distinct addresses at a site in 2,048 evaluations | 43 |
|
||||
| Most evaluations reading one address at a site | 1,838 of 2,048 |
|
||||
| Mean hot share over programs | 0.063 percent |
|
||||
|
||||
Gate: zero passing programs with a hot set under 1 percent of items. FAIL on the class v4 stream by the letter:
|
||||
11,696 passing programs concentrate 1 percent or more of their reads on a hot set. The mechanism is F9-1 above,
|
||||
the or-saturated load source, which is the same fault class the F8 row found from the cross-hash histogram
|
||||
(AP-F8-1: a load whose source's last writer is lossy); the two harnesses found it independently, one from the
|
||||
program's address trace per site, one from the item histogram across hashes. F9-1 therefore merges into AP-F8-1,
|
||||
and the fix is the amendment shipping in 0.3.20 (a load's source drawn only from registers whose last writer injects
|
||||
or is a rotate). Sub-row (b): FINDING (AP-F8-1 class); re-gated on the amended stream with this harness below.
|
||||
53
docs/analysis/attack-pass/o114-i7-9700K-2026-10-07.log
Normal file
53
docs/analysis/attack-pass/o114-i7-9700K-2026-10-07.log
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# O-1.14 bench start 2026-10-07T08:49:03Z host root@ssh9.vast.ai
|
||||
Warning: Permanently added '[ssh9.vast.ai]:35608' (ED25519) to the list of known hosts.
|
||||
Welcome to vast.ai. If authentication fails, try again after a few seconds, and double check your ssh key.
|
||||
Have fun!
|
||||
# binary copied, sha256 6d28678359d3d6bd158b245f7e522d6f2a5b0704d9997c0fb50ebc3471a9ebe5
|
||||
Welcome to vast.ai. If authentication fails, try again after a few seconds, and double check your ssh key.
|
||||
Have fun!
|
||||
# cpu: Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
|
||||
# cores: 8 mem: 31 GB
|
||||
# glibc: ldd (Ubuntu GLIBC 2.39-0ubuntu8.9) 2.39
|
||||
# clock MHz: 4169.856
|
||||
08:49:07 up 20 days, 10:27, 0 user, load average: 0.13, 0.07, 0.05
|
||||
## --class v2 08:49:07Z
|
||||
Welcome to vast.ai. If authentication fails, try again after a few seconds, and double check your ssh key.
|
||||
Have fun!
|
||||
cache: fill 283.0 ms on one core (2^26 words, 256 MiB, 65536 chains of 64 ChaCha12 blocks), FNV-1a 64 48c4f5bf24166b2e
|
||||
warp base 0: single cold run 1.582 ms, 4096 items derived, lane0 42246ba99fc58e4f lane31 b08446b1f2de7793
|
||||
warp base 4096: single cold run 1.392 ms, 4096 items derived, lane0 3d3903e310ca038f lane31 61c242509efdccdd
|
||||
warp base 1000000: single cold run 1.374 ms, 4096 items derived, lane0 f218c1bd58e6dfe0 lane31 6c3b2c11adfbfcac
|
||||
CPU verify: 1.280 ms per 32-lane warp, avg of 50 (checksum 19297e99c7b9a55e)
|
||||
## --class mx8 08:49:09Z
|
||||
Welcome to vast.ai. If authentication fails, try again after a few seconds, and double check your ssh key.
|
||||
Have fun!
|
||||
cache: fill 276.6 ms on one core (2^26 words, 256 MiB, 65536 chains of 64 ChaCha12 blocks), FNV-1a 64 48c4f5bf24166b2e
|
||||
warp base 0: single cold run 5.394 ms, 4096 items derived, lane0 19b56348bc85304d lane31 359192708e4f754a
|
||||
warp base 4096: single cold run 5.285 ms, 4096 items derived, lane0 62fb132a9943127a lane31 7d7866cb9cfca8ff
|
||||
warp base 1000000: single cold run 5.293 ms, 4096 items derived, lane0 86b6cb0e13d89b03 lane31 9c004678515e44ec
|
||||
CPU verify: 5.267 ms per 32-lane warp, avg of 50 (checksum 653a23f7ee1c8c63)
|
||||
## --program-class v4 08:49:11Z
|
||||
Welcome to vast.ai. If authentication fails, try again after a few seconds, and double check your ssh key.
|
||||
Have fun!
|
||||
cache: fill 276.6 ms on one core (2^26 words, 256 MiB, 65536 chains of 64 ChaCha12 blocks), FNV-1a 64 48c4f5bf24166b2e
|
||||
warp base 0: single cold run 6.334 ms, 4096 items derived, lane0 2576769ee4a14c8d lane31 c58ddcb717dd3370
|
||||
warp base 4096: single cold run 6.198 ms, 4096 items derived, lane0 1ce77a600ec573b4 lane31 03600a05ffba0055
|
||||
warp base 1000000: single cold run 6.174 ms, 4096 items derived, lane0 6b390e64bbdd91ce lane31 91c944d603539c62
|
||||
CPU verify: 6.006 ms per 32-lane warp, avg of 50 (checksum 17e36e7905b81375)
|
||||
## --class dr368 08:49:14Z
|
||||
Welcome to vast.ai. If authentication fails, try again after a few seconds, and double check your ssh key.
|
||||
Have fun!
|
||||
cache: fill 276.3 ms on one core (2^26 words, 256 MiB, 65536 chains of 64 ChaCha12 blocks), FNV-1a 64 48c4f5bf24166b2e
|
||||
warp base 0: single cold run 5.540 ms, 4096 items derived, lane0 c77c7625bbe0f452 lane31 c8e84ff2655d9934
|
||||
warp base 4096: single cold run 5.433 ms, 4096 items derived, lane0 7229bd981a5786ca lane31 1c5495083ae60453
|
||||
warp base 1000000: single cold run 5.430 ms, 4096 items derived, lane0 5533769c9cdbf0a7 lane31 2426905704457b11
|
||||
CPU verify: 5.426 ms per 32-lane warp, avg of 50 (checksum 94fcbf0a77e03bdc)
|
||||
## --class dr736 08:49:16Z
|
||||
Welcome to vast.ai. If authentication fails, try again after a few seconds, and double check your ssh key.
|
||||
Have fun!
|
||||
cache: fill 275.7 ms on one core (2^26 words, 256 MiB, 65536 chains of 64 ChaCha12 blocks), FNV-1a 64 48c4f5bf24166b2e
|
||||
warp base 0: single cold run 10.290 ms, 4096 items derived, lane0 e23d389f3eea0c83 lane31 6605db059b381bd9
|
||||
warp base 4096: single cold run 10.072 ms, 4096 items derived, lane0 fdb4b214da8ce292 lane31 db698d03437d74f7
|
||||
warp base 1000000: single cold run 10.056 ms, 4096 items derived, lane0 534671b1bf5cea36 lane31 733b123353f13d21
|
||||
CPU verify: 10.042 ms per 32-lane warp, avg of 50 (checksum bf79909c25836153)
|
||||
# O-1.14 bench end 2026-10-07T08:49:19Z
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Block rate on Devnet 2: 10 blocks per second against 1, on the rented fleet
|
||||
|
||||
6 October 2026, the project lead's experiment (through the coordinator, 17:5xZ): "Devnet 2 at a higher block rate for solo miners
|
||||
6 October 2026, the founder's experiment (through the coordinator, 17:5xZ): "Devnet 2 at a higher block rate for solo miners
|
||||
(Kaspa's answer)". Branch `gpu-fleet`; the node profile on the fork branch `devnet2-bps` (1279a1d6 on release-0.3.14-node
|
||||
4c6b129d): a suffixed devnet started with `IGNEUMD_DEVNET_BPS=10` (or 5) runs `BlockrateParams::new::<10>()` with the
|
||||
TenBps subsidy and target time, Kaspa's Crescendo-style constants for that rate (k 124, merge depth, sample rates,
|
||||
|
|
|
|||
62
docs/analysis/ca3-v4-uniform.md
Normal file
62
docs/analysis/ca3-v4-uniform.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# AP-F8-1 under the windows-union model: the hot set is the load source, not the window (7 October 2026)
|
||||
|
||||
Branch `ca3-v4-uniform` from master b92a5fd4, worker "v4-hash", on the attack-pass finding AP-F8-1 (`docs/analysis/attack-pass/f8-uniform.md`, branch attack-pass; logs `/srv/builds/igneum-wt-attack/target-attack-f8/log/`). Main's rulings bound this file: no generator change to class v4 on the live devnet; the analysis and its harness only. Every GPU-free number here is arithmetic on F8's logged counts or a run of the static census tool `tools/ca3-v4-uniform/` on igneum-build-1 (built through `tools/build-remote.sh`, rule R1); the chip figures are the terms of `docs/analysis/chip-model-v3.md` and are approximate.
|
||||
|
||||
## 1. The null F8's numbers must be read against
|
||||
|
||||
Layer 8 (`docs/plans/era-layout.md` 1.4, spec 01 1.13.1 as proposed) gives every load site a window draw `k_off = below(3)`: the site reads the whole dataset, an aligned half or an aligned quarter, at a 2^26-word floor. A quarter-window site concentrates its reads 4x on its quarter and a half-window site 2x on its half, by design; the union of the 16 windows is the whole dataset. For p1 (the devnet epoch-0 program, id c120d7963abdcd96) the 16 draws `0:2:1 1:1:1 2:1:1 3:1:1 4:0:0 5:1:1 6:0:0 7:2:2 8:1:1 9:1:1 10:2:0 11:0:0 12:0:0 13:0:0 14:2:0 15:1:1` (site:k:offset) give an expected read density by quarter of 3.25 : 2.25 : 5.75 : 4.75 sixteenths of the flat mean, which at 2^26 nonces (512 reads per item flat) is 416, 288, 736 and 608 reads per item. The top-f share of a Poisson mixture with those means (`uniform-model.txt`, exact Poisson for p1, a normal approximation for the census):
|
||||
|
||||
| Share of all reads on the top f of items, 2^26 nonces | Flat Poisson (F8's control) | Windows-union model, p1 | F8 measured, p1 | Beyond the window model |
|
||||
|---|---|---|---|---|
|
||||
| f = 0.1 percent | 0.115 | 0.160 | 0.520 | +0.36 |
|
||||
| f = 0.5 percent | 0.565 | 0.784 | 1.515 | +0.73 |
|
||||
| f = 1 percent | 1.120 | 1.553 | 2.495 | +0.94 |
|
||||
|
||||
So the window model moves the null from 0.115 to 0.160 percent at f = 0.1 percent (1.39x, not F8's 4.05x) and from 1.12 to 1.55 at f = 1 percent; it explains the 64-item-bucket sigma of p2 that F8 already attributed to the window layer, and it explains every per-site attribution row of p1 except one: sites with a half window over the hot region land 0.20 percent of their reads in the top 0.1 percent (sites 1, 2, 3, 5, 9 at 0.201), quarter-window sites 0 or about 0.4 (sites 0, 10, 14 at 0.000, site 7 at 0.241 straddling), whole-dataset sites 0.10. Site 15 lands 6.374 percent. The excess over the model (+0.36 at f = 0.1 percent) is one site.
|
||||
|
||||
## 2. The 153x item is the load source, and the model predicts it to the item
|
||||
|
||||
p1's site 15 is the load at instruction 63 (`load dst=3 src=6`, window half 1). Its source r6 was last written at instruction 61: `or dst=6 src=4` (`r6 |= r4`, `verify.rs` Op::Or), after a fresh dataset load into r6 at 47. An OR of two near-uniform registers sets each bit with probability 3/4, so the source takes the all-ones value with probability (3/4)^32 = 1.0e-4 per read and the values of popcount 31, 30, ... with 32, 496, ... times (3/4)^k (1/4)^(32 - k). The era map `y = rotl(x * 0x9ad30d99, 29)`, the half window and the interleave split (`memhard::Layout::split`, positions 0, 2, 12, 13) send x = 0xffffffff to item 0xca5b92: F8's hottest item exactly. F8's next seven items (0x8a5b92, 0xaa5b92, 0xba5b92, 0x825b92, 0xe65b92, 0x985b92, 0xbcc392) are exactly the seven one-zero-bit sources whose zero bit survives the window mask (bits 29, 28, 27, 26, 25, 24 and 15): 7 of 7. The measured count fixes the bit bias: 78,479 reads of 2^26 x 8 site-15 reads is p^32 at p = 0.7585 (r4 is slightly biased itself), and at that p the popcount model predicts 77,348 all-ones reads and 4.86 percent of site 15's reads into the top 0.1 percent of items (measured 6.37; 3.92 at p = 3/4). Per hash that is 4.86 / 16 = 0.30 percent of all reads, and 0.160 + 0.30 = 0.46 against F8's 0.520 at f = 0.1 percent; at f = 1 percent 14.5 / 16 = 0.90, and 1.55 + 0.90 = 2.46 against 2.495.
|
||||
|
||||
The same arithmetic for the other lossy writers (`uniform-model.txt`): a `mul` last writer zeroes the low bits by the operands' trailing zeros, so 1.07 percent of the site's reads land on the 0.1 percent of values with 10 or more trailing zeros (p2's `mul`-sourced sites 0 and 14 measured 0.971 and 0.966 percent); a `mulhi` last writer is dense near zero, 0.79 percent on the lowest 0.1 percent of values. An `or` whose operand was itself last written by `or` compounds the bias (3/4 to 7/8 to 15/16): p3's site 15 (`or` at 30, the load at 62) puts 72.4 percent of its reads into the top 0.1 percent, 4.6 percent of all reads on 16,777 items.
|
||||
|
||||
This is a fault class, not the window model: the acceptance rule's part (a) (`accept.rs` check_stale_loads) takes any write as a fresh source, and part (c)'s saturation count looks at the 16,384 final register values, not at a load's source mid-program, so an `or`, `mul` or `mulhi` as a load's last writer passes. The per-hash distinct-address check still holds (p1 127.999 items per hash; p3 127.97: a saturated site repeats its item inside a hash), and the acceptance rule's floor of 120 distinct of 128 admits exactly one site repeating its item in all 8 iterations and no more.
|
||||
|
||||
## 3. How common it is: the static census (`tools/ca3-v4-uniform`, 1,024 chain-shaped class v4 programs plus F8's p1 to p3)
|
||||
|
||||
For every load site, the op that last wrote its source in execution order (base instructions before it, else the shadow block of the previous iteration, else the base instructions after it): injecting (add, sub, xor, mad, shfl, load), bijective (rotl, rotr) or lossy (or, mul, mulhi). Run on igneum-build-1 (`uniform-census.txt`, binary sha256 ce9f83fe... then the narrowed chain rule).
|
||||
|
||||
| Census over 1,024 programs | Count | Share |
|
||||
|---|---|---|
|
||||
| Load sites by last writer: injecting / bijective / lossy | 11,368 / 2,121 / 2,943 of 16,432 | 69 / 13 / 18 percent; 2.87 lossy sites per program |
|
||||
| Programs with at least one lossy-sourced load | 992 | 96.6 percent |
|
||||
| ... with an `or`-sourced load (p1's class, 0.30 percent of all reads per site) | 498 | 48.5 percent |
|
||||
| ... with an `or`-of-`or` chain (p3's class, about 4.5 percent of all reads per site) | 50 | 4.9 percent |
|
||||
| ... with a `mul`-sourced load (0.067 percent per site) / a `mulhi`-sourced load (0.049) | 751 / 661 | 73.1 / 64.4 percent |
|
||||
| Predicted S_0.1 percent (window model plus the lossy sites): median / 90th / 99th / max | 0.45 / 0.88 / 5.29 / 9.82 percent | against the window model's 0.115 to 0.251 |
|
||||
| p1 / p2 / p3 predicted against F8 measured | 0.579 / 0.323 / 4.72 | 0.520 / 0.272 / 4.60 |
|
||||
|
||||
F8's proposed gate (the top 0.1 percent within 1.2x of the window-model control on every one of 64 seeds) fails 96.6 percent of today's programs, because any lossy-sourced site alone exceeds it (0.16 + 0.05 at the least); it is a generator change in a gate's clothing. A 2x bound fails 69.7 percent, 3x 48.9 percent; a bound of S_0.1 percent at or under 1 percent of all reads fails 6.9 percent (the `or` chains and the multi-`or` programs). The static rule "no load whose source's last writer is `or`" fails 48.4 percent; "no lossy last writer" 96.6 percent.
|
||||
|
||||
## 4. What the skew is worth to a chip (chip-model-v3.md terms, approximate)
|
||||
|
||||
A hot-set cache of the top 0.1 percent of items is 16,777 items x 64 B = 1.07 MB of SRAM, 0.53 mm^2 and $0.25 at 0.49 mm^2 and $0.23 per MB. It serves 0.52 percent of p1's reads (0.16 of them the window model's), 4.6 percent of p3's. The hash is latency-bound on its dependent reads, so a read served on die is time saved: a chip gains at most 1.005x on p1 and 1.048x on p3 from the cache. The ceiling under the live rule: part (c)'s 120-of-128 floor admits one site repeating its item in all 8 iterations and no more (two saturated sites fail it), so at most 8 of 128 reads, 6.25 percent, can sit on a constant item, and a chip's edge from this whole class is at most 1 / (1 - 0.0625) = 1.067x, in 64 bytes of SRAM, on the hours whose program carries such a site. The public claim rests on 2x margins (chip-model-v3.md); 1.067x does not move it, and the union of the windows is still the whole dataset every hour, so no window-level cache exists. What moves: per tier nothing in rate or watts (the honest card reads the hot item from L2 as the chip would), and the 5 percent rule of 2.0 is untouched.
|
||||
|
||||
## 5. The two options for the flip, priced (main's ruling 3; nothing ships on this without the founder's word)
|
||||
|
||||
| Option | What changes | Cost | Risk |
|
||||
|---|---|---|---|
|
||||
| A. A class amendment in 0.3.19 before the flip: the generator draws a load's source from the registers whose last writer injects (or rule (a) tightened to the same), class v4 re-pinned | a new program stream: new vectors, the seven gate packs re-exported, the six gates again (the hash side G1 to G3 and the verifier re-run here in about an hour of Mac and PC 2 time; G4 to G6 the node lane), every node before the flip by the one-box-at-a-time fleet rule | hours of gate time, a fleet rollout, the 0.3.19 ship on the line | a node that misses the build splits the chain at the flip; the fix itself is small (one draw rule) |
|
||||
| B. Hold v4 at the floor as it is; the source rule in class v5 | nothing on the devnet; the attack-pass record carries the window null and the bound | a hot set on 48 percent of hours worth up to 1.005x to a chip, on 5 percent of hours up to 1.05x, 1.067x at the rule's ceiling, no chain risk | the public line must state the bound, not "uniform" |
|
||||
|
||||
The number that decides it: 1.067x at the ceiling against the 2x margin of the chip claim. Recommendation: B, with the v5 item below, unless the founder wants the tail tight now.
|
||||
|
||||
## 6. The acceptance bound for the next class (main's ruling 4)
|
||||
|
||||
Definition: for a program, H = W_0.1(windows) + sum over load sites of h(last writer of the source), with W from the Poisson mixture of the 16 window draws (0.115 to 0.251 percent at 2^26 nonces) and h = 0.30 percent for `or`, 4.5 for an `or` chain, 0.067 for `mul`, 0.049 for `mulhi`, 0 for an injecting or bijective writer (the figures of section 2 at the measured bias). The bound: H at or under 1.2 x W, which is the static rule "every load's source was last written by an injecting op or a rotate" (any lossy writer breaks 1.2x). Its cost as a rejection rule on today's stream: 96.6 percent of candidates, about 30 attempts per seed on average. The cheaper form is a generator draw, not a rejection: draw a load's source from the registers whose last writer injects (today's rule draws from every written register), which costs no attempts and leaves rule (a) as it is. Either way the 64-seed census of F8's phase E is the gate, with the dynamic check extended to count saturated load sources over the 64 units beside the final values.
|
||||
|
||||
## 7. What is unverified
|
||||
|
||||
- The per-site h figures are the popcount and trailing-zeros models at the biases F8 measured on p1 and p2; p3's chain figure is F8's measurement, not a model. F8's phase E (64 seeds, dynamic) is the test of the whole table.
|
||||
- The window model's top-f shares for the census use a normal approximation per quarter (p1's exact Poisson 0.160 against 0.159).
|
||||
- No GPU run and no timing here; every number is a count or arithmetic.
|
||||
|
|
@ -69,7 +69,7 @@ Proving is a separate budget (the 15.6 GB peak the 12 GB mine-and-prove question
|
|||
|
||||
## 4. Table 3: the public sentences against the numbers
|
||||
|
||||
| Where | Sentence now | What the tables give | Proposed sentence (the project lead decides the wording) |
|
||||
| Where | Sentence now | What the tables give | Proposed sentence (the founder decides the wording) |
|
||||
|---|---|---|---|
|
||||
| `site/index.html` 443 | Memory: "2 GB, fixed" (RandomX) / "2 GB, growing" (Igneum) | 2 GiB at genesis, plus 0.5 GiB a year on average under either option | "2 GB, growing 0.5 GB a year". The row is right; the rate is the useful addition |
|
||||
| `site/index.html` 461 | "Any 4 GB card, approximate." | True at genesis (2,584 to 2,834 MiB of a 3,072 MiB budget). Ends at 1 to 1.5 years under (a), year 4 under (b) | "Any 4 GB card at launch, 8 GB for the long run, approximate." |
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ low on this result; it stays a reserve family. What does move the `f = 1` rows,
|
|||
| Read granularity | The chip pays the same 32-byte atom the 5090 pays; the 9070 XT pays 64. Wider honest reads (w16, measured, layer 1) give the chip nothing and the 5090 nothing; w64 made the 5090 bandwidth-bound (71.9 MH/s) | w64 costs the 5090 47 percent | Not a lever; the decision to stay at 4 B stands |
|
||||
| Latency | A longer chain (more reads per hash) scales the chip's rate and the card's rate together; lane state is 64 B, so lanes are free to the chip | Nothing per se | Not a lever: the rate per chip is lanes / latency on both sides and the chip has more lanes per watt |
|
||||
| The denominator: the 5090's watts at the hash | The gain is 2.40 microjoules over the chip's 0.47; the card's 326 W is 92.9 percent utilisation spinning on loads. At a 250 W cap holding 136.1 MH/s the gain reads 3.9x (GDDR7) and 5.7x (HBM3); at 200 W, 3.2x and 4.6x | None if the rate holds under the cap; the measurement is one PC 2 job (`nvidia-smi -pl 200, 250, 326`, two minutes each, STATUS lines as the rate) | The first measurement to run; it moves every row and costs nothing. Owed (PC 1 is not released; PC 2's budget is the coordinator's) |
|
||||
| Program work in the latency shadow | The hash hides 512 ops per hash behind 128 reads; the 5090 could hide 330,000 (45.2 T / 136.1 M) before compute binds, the M5 Max about 290,000 and the 9070 XT about 650,000 (their ALU budgets approximate, from memory). Work in the shadow is free in hash rate and costs the card watts it now wastes: at N ops per hash the card rises from 326 toward 575 W (linear, approximate) and the chip must add a core that runs the per-epoch random program, at k times the GPU's 5.5 pJ per op (the 5090's marginal ALU energy, (575 - 326) / 45.2 T). At N = 100,000: the card 401 W, 2.95 microjoules; the chip 1.02 at k = 1, 0.83 at k = 1.5; gain 2.9x and 3.5x. At N = 200,000: 477 W, 3.50; chip 1.57 and 1.20; gain 2.2x and 2.9x. At N = 330,000: 575 W, 4.22; chip 2.28 and 1.68; gain 1.85x and 2.5x | Hash rate none while every card stays latency-bound (under about 290,000 on the M5 Max); watts up to TGP; the verifier N x 32 ops per warp: 3.2 M at N = 100,000, under 1 ms at the 18 G op/s the x8 verifier shows (38 M ops in 2.08 ms), inside the 10 ms gate; `INSTR_COUNT` and `ITERATIONS` are prototype values to be fixed at gate 1 (spec 1.4) | The only lever that moves the f = 1 row toward 2x, and only if the chip's core is no better than a GPU's on a random program (k near 1: RandomX's argument, and the project lead's goal in the brief's words, "build a better GPU than NVIDIA"). It reaches 1.85x at the 5090's full ALU budget and k = 1, not under; combined with a 250 W cap it reads about 1.4x (approximate). It is item 2's idea applied to the program, not to the item derivation |
|
||||
| Program work in the latency shadow | The hash hides 512 ops per hash behind 128 reads; the 5090 could hide 330,000 (45.2 T / 136.1 M) before compute binds, the M5 Max about 290,000 and the 9070 XT about 650,000 (their ALU budgets approximate, from memory). Work in the shadow is free in hash rate and costs the card watts it now wastes: at N ops per hash the card rises from 326 toward 575 W (linear, approximate) and the chip must add a core that runs the per-epoch random program, at k times the GPU's 5.5 pJ per op (the 5090's marginal ALU energy, (575 - 326) / 45.2 T). At N = 100,000: the card 401 W, 2.95 microjoules; the chip 1.02 at k = 1, 0.83 at k = 1.5; gain 2.9x and 3.5x. At N = 200,000: 477 W, 3.50; chip 1.57 and 1.20; gain 2.2x and 2.9x. At N = 330,000: 575 W, 4.22; chip 2.28 and 1.68; gain 1.85x and 2.5x | Hash rate none while every card stays latency-bound (under about 290,000 on the M5 Max); watts up to TGP; the verifier N x 32 ops per warp: 3.2 M at N = 100,000, under 1 ms at the 18 G op/s the x8 verifier shows (38 M ops in 2.08 ms), inside the 10 ms gate; `INSTR_COUNT` and `ITERATIONS` are prototype values to be fixed at gate 1 (spec 1.4) | The only lever that moves the f = 1 row toward 2x, and only if the chip's core is no better than a GPU's on a random program (k near 1: RandomX's argument, and the founder's goal in the brief's words, "build a better GPU than NVIDIA"). It reaches 1.85x at the 5090's full ALU budget and k = 1, not under; combined with a 250 W cap it reads about 1.4x (approximate). It is item 2's idea applied to the program, not to the item derivation |
|
||||
| The clock (item 4) | The f = 1 chip is a commodity-memory controller project: by the Ethash precedent, 32 months to a first chip at the largest prize, and a chip over 2x at 65 months | None | The issuance trigger and the share-pattern detector matter more than any item-derivation change |
|
||||
|
||||
So: item 2 can wait; the power-cap measurement runs first; the program-length lever is the Counter ASIC 3.0 design
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ run drops from about three minutes to about one. The hosted runner then serves o
|
|||
pipeline (MSVC, WebView2, Inno Setup, PowerShell 5.1, which a Linux box cannot provide). The flip is main's call after the
|
||||
0.3.15 cut, per build-server.md section 7.1.
|
||||
|
||||
## 6. The build box's own red rows (the project lead, 22:3x UK: "also make sure we are fixing and learning from all the errors here")
|
||||
## 6. The build box's own red rows (the founder, 22:3x UK: "also make sure we are fixing and learning from all the errors here")
|
||||
|
||||
Source: `/srv/builds/_log/builds.jsonl` on igneum-build-1, 139 rows from the first build at 18:38 UK to 22:11 UK on
|
||||
6 October; 34 with a non-zero exit. Until this change the box kept no output of a run (it streamed to the agent's terminal),
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ the height arrives.
|
|||
(26640/28640, a follower, lowest risk), the seed (`/opt/igneum/v4/bin`, `infra/seed-nodes/stage-v4.sh`),
|
||||
Mac node 1 (26610/26611), PC 1's node (its launcher's `igneumd.exe`; PC 2 mines through the Mac node
|
||||
and needs nothing). Each node gets the same `"difficulty_v2_activation_daa": N` in its override file.
|
||||
the project lead restarts the live processes; this entry does not.
|
||||
The founder restarts the live processes; this entry does not.
|
||||
3. Watch the observer's difficulty events across the height and the next epoch boundary; with a miner
|
||||
joining inside an epoch the floor and the bursts of section 1 must not return.
|
||||
|
||||
|
|
|
|||
86
docs/analysis/era-vdf-2026-10-07.md
Normal file
86
docs/analysis/era-vdf-2026-10-07.md
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# The era VDF: built, measured and gated (7 October 2026)
|
||||
|
||||
Era VDF lane, 7 October 2026, from the attack pass's F7 row (`docs/analysis/attack-pass/f7-era.md`, sub-row a: the node's era seed was a plain chain block hash, grindable with one block of hash at no delay, and the 1-hour VDF of spec 04 section 4.4 did not exist in the node). Repository branch `era-vdf` (this record, the spec text, the harness `tools/era-vdf/`, the fast-time fields); node fork branch `era-vdf-node` on the 0.3.19 line (`release-0.3.19-node` dc141409). Every number below names its log on igneum-build-1 under `/srv/builds/igneum-wt-era-vdf/ev-*/`.
|
||||
|
||||
## 1. What was built
|
||||
|
||||
| Piece | Where | What |
|
||||
|---|---|---|
|
||||
| The integer | `consensus/core/src/era_vdf/bigint.rs` | a fixed-width signed integer (40 limbs, 2,560 bits) on the stack: add, sub, mul, shifts, Knuth division with floor, truncated, exact and Euclidean remainders, the extended gcd and the partial extended gcd with Lehmer's word steps (chiavdf `xgcd_partial.c`), modpow, sqrt and the fourth root, Miller-Rabin with the first 30 primes as bases; every operation checked against `num-bigint` on 20,000 random operands of the class group's sizes, the known-failed shapes first |
|
||||
| The class group | `era_vdf/classgroup.rs` | `proto-vdf/src/classgroup.rs` (3 October 2026) on the fixed-width integer: NUDUPL and NUCOMP ported line by line from chiavdf's `qfb_nudupl` and `qfb_nucomp`, the plain duplication and Cohen 5.4.7 kept as the oracles the tests hold them to on random forms at 256, 512 and 1,024 bits; serialization as sign byte plus fixed width, 258 bytes a form |
|
||||
| Wesolowski | `era_vdf/wesolowski.rs` | eval with serialized checkpoints (at most 2^16, 17 MB), the 12-bit-digit block prover bucketed per residue class and parallel over them, the naive prover as the oracle, verify; T + 1, another y, another pi and another input refused |
|
||||
| The hash chain | `era_vdf/hashchain.rs` | scheme 1: T sequential SHA-256 applications from a tagged start; verification by recomputation; one step short refused |
|
||||
| The scheme byte and the seed | `era_vdf/mod.rs` | `vdf_scheme` 0 and 1, `EraVdfProof` and its wire form, `era_vdf_input` (the chain's BLAKE2b keyed `IgneumEraVdfInput` over `chain_id || n || the day's blue hashes`), `era_seed_of` = SHA-256 of the scheme byte, the input, T and y |
|
||||
| The switch | `consensus/core/src/config/params.rs`, `igneum.rs` | `pow_era_blocks` and `pow_era_lead` as override fields (the constants everywhere; in the digest when they differ), `era_vdf_activation_daa` (never), `vdf_scheme` (0), `era_vdf_t` (the reference T); the three in the digest once the activation is set (the 0.3.15 rule); installed with the PoW schedule |
|
||||
| The node side | `consensus/src/processes/era_vdf.rs`, `model/stores/era_vdf.rs` | the cut rule (the chain block below the cut, memoised and re-validated by reachability), the day-of-blues input (memoised per cut block), the evaluator thread started by the virtual processor a quarter of the lead past the cut, the record store (one row per era), the header processor's wait when a header arrives before the record, the template's `era_seed` None while evaluating, `submit` for a record from outside (verified against this chain's input) |
|
||||
| The template and the miner | `PowEpochInfo`, `RpcPowEpochInfo`, `rpc.proto` fields 37 to 44, `igneum-miner` | the era schedule, the VDF's state, scheme, T and input in every template; the miner holds while the node reports no era seed ("era VDF: the node is still evaluating"); `igneum-miner vdf bench|eval|verify` with the node's own code |
|
||||
| The harness | `tools/era-vdf/reroll.mjs` | the F7 re-roll harness against the REAL era cut (era 120 DAA, lead 20 on the merged fast-time file; ports 30100 and up, suffix 1010), `--vdf off` the stand-in, `--vdf on` the VDF at a fast T, the adversary running the node's evaluator over its candidate before publishing |
|
||||
|
||||
## 2. The parameters
|
||||
|
||||
Measured 7 October 2026 on igneum-build-2 (AMD EPYC 9454P, 96 threads, Ubuntu 24.04), one core under `/srv/builds/_bin/lease cores 31` at nice 10 while the box ran other lanes' suites (load 25 to 75), with the node's own code (`igneum-miner vdf bench`, logs `ev-vdf-bench3.log`, `ev-vdf-bench5.log` in this lane's scratch) and chiavdf 7e62ce14 built on the box against GMP 6.3.0 (`ev-chiavdf`).
|
||||
|
||||
| Parameter | Value | Label |
|
||||
|---|---|---|
|
||||
| Group | class group, 1,024-bit prime discriminant `D = -HashPrime("igneum-era-discriminant" \|\| input)`, `\|D\| = 7 mod 8` | Implemented (spec 4.2) |
|
||||
| Generator, Fiat-Shamir prime, proof plan | `(2, 1, (1 - D) / 8)`; 256 bits; 12-bit digits, at most 2^16 serialized checkpoints (17 MB) | Implemented |
|
||||
| Proof on the wire | 529 bytes: scheme (1), T (8), two 258-byte forms with 2-byte lengths; `y` and `pi` 258 bytes each | Measured |
|
||||
| Scheme byte | `vdf_scheme` 0 = class group, 1 = hash chain; genesis 0 everywhere | Implemented |
|
||||
| Reference rate, scheme 0 | 30,589 and 40,117 squarings/s in two 10-s runs on the box core (the spread is the box's load); 30,000 is the reference | Measured |
|
||||
| `T_era`, scheme 0 | 3,600 x 30,000 = 108,000,000 squarings (`ERA_VDF_T_CLASS_GROUP`): 60 min at the reference, 45 at the faster run | Measured, set |
|
||||
| Prove, scheme 0 | eval + prove 11.6 s at T 401,167 (eval 10.0 s): the single-thread block prover is about 14 percent of the evaluation, parallel over residue classes in the node (up to 8) | Measured |
|
||||
| Verify, scheme 0 | 21.9 and 22.6 ms with the group held (mean of 20); 184 ms with the discriminant derived, the derivation being 161 to 167 ms, once per era | Measured (section 5 for the gate) |
|
||||
| Reference rate, scheme 1 | 16.2 and 17.0 million SHA-256/s (SHA-NI); 16,000,000 is the reference; `T_era` = 57,600,000,000 hashes (`ERA_VDF_T_HASH_CHAIN`) | Measured, set |
|
||||
| Verify, scheme 1 | recomputation: 10.1 s for T 170 million, the full hour at `T_era` | Measured |
|
||||
| Discriminant search | 161 to 167 ms per era (Miller-Rabin with the first 30 primes on the fixed-width integer) | Measured |
|
||||
| chiavdf on the same core | 208.8 K squarings/s (`vdf_bench square`, NUDUPL over GMP, 1,000,000 iterations); the AVX-512 IFMA path (`square_asm`) gave 127.3 K at 20,000 iterations and stalled at 300,000 and above in this build (built outside its Makefile's `FAST_MACHINE` flags), so the IFMA number is not established here | Measured; the asm path unestablished |
|
||||
| Delay on the fastest prover measured | 108,000,000 / 208,800 = 517 s against the 1-s block interval (517x) and the 2-s publish window (259x); a prover 10x chiavdf's GMP path (the ceiling Chia's and the EF's hardware efforts aimed at, approximate, from memory) would still take 52 s, 26x the window | Computed from the measurements |
|
||||
| The gate "at least 60x one block interval on the fastest known prover" | 517x on chiavdf's GMP path, the fastest evaluator measured on this hardware; PASS as measured, with the IFMA path unestablished (above) and the 10x hardware ceiling still 52x | PASS (measured), caveat recorded |
|
||||
|
||||
The node's own evaluator is 5.2 to 6.8x slower than chiavdf's GMP path on the same core. That ratio only moves the honest side: `T_era` is set from the node's rate, so an honest node finishes in the hour; the attacker's margin is the delay at the fastest prover, above.
|
||||
|
||||
## 3. The gate: the re-roll harness with the VDF off and on
|
||||
|
||||
`tools/era-vdf/reroll.mjs` on igneum-build-2 (the box under other lanes' suites, nice 10; logs and per-cut JSON under `/srv/builds/igneum-wt-era-vdf/ev-harness-out/reroll-vdf-{on,off}-5.json`), three nodes of the fork at this record's commit on the fast-time file with `skip_proof_of_work`, era 120 DAA and lead 20 (cuts at `S = 120 n - 20`, one every two minutes), ports 30100 and up, suffix 1010; two honest virtual miners share 1 block/s on nodes 0 and 1; the adversary on node 2 holds a block A built on the tip at `S - 1` and tries to make it the era's cut block. With the VDF on, the adversary runs the node's own evaluator (`igneum-miner vdf eval`, the network's T) over its candidate before publishing; T is set from a 3-s bench at the start so the delay is about 5 s on one core of this box, five times the block interval.
|
||||
|
||||
| Run | Switch | Cuts | A accepted | A became the cut block | Known-draw re-rolls (the seed the adversary knew before publishing is the era's seed) | Adversary's evaluation | Nodes agree on the era seed | Gate | Harness |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| vdf-off-5 (the stand-in, 15:08 to 15:22 UTC) | `era_vdf_activation_daa` never | 6 (eras 2 to 7) | 6 of 6 | 6 of 6 | 6 of 6: the seed is `hash(A)` every time | none needed: the draw of hash(A) is known the instant A is built | 3 of 3 on every era | FAIL (the known-pass fires) | SOUND |
|
||||
| vdf-on-5 (the era VDF, 14:54 to 15:08 UTC) | activation 0, scheme 0, T 189,650 (5 s on this core) | 6 (eras 2 to 7) | 6 of 6 | 0 of 6 | 0 of 6 | 5.38 to 6.64 s, during which the honest chain advanced 3 to 10 blocks; A arrived behind them and never became the cut block | 3 of 3 on every era, the record ready (state 3) at every era start | PASS (silent) | SOUND |
|
||||
|
||||
What the two runs say. Under the stand-in a miner with one block of hash at the right second owns the era draw outright on this network: holding the block at `S - 1` and publishing it the moment the chain reaches `S - 1` makes it the cut block in every one of six cuts (the attack lane's epoch-cut run saw 1 of 6, with the honest block often landing first; here the adversary is faster to the second), and its draw is known the instant the block is built. Under the VDF the same adversary cannot know any candidate's draw before T steps have run; while it ran them the honest chain moved 3 to 10 blocks, so its block arrived behind the cut and the seed came from the delay over the day of blues ending at the honest cut block, the same on all three nodes. The second half of the written argument of F7 (a) holds in the node, not only on paper: the re-roll needs the draw inside the window, and the window is 1 s against a delay of 5 s here and 517 s at the fastest prover measured on the production T (section 2).
|
||||
|
||||
The known-pass and the known-fail ran on the same binaries, file and ports, the VDF switch the only difference. A first VDF-off run with a lookup defect in the harness (the adversary's block not found, so the verdict read "held") was discarded once the node's own log showed the adversary's hash as the cut block in 5 of 5 cuts; the harness now reads A from that log line. Two runs that overlapped on the box through a stale node of an earlier run were discarded as well (their nodes disagreed because they were two networks); the two runs above ran alone.
|
||||
|
||||
## 4. The cut rule and the certified checkpoint (for the finality lane)
|
||||
|
||||
The node names `C_era(n)` as the last selected-chain block below the cut on the header's own chain (the block the stand-in used), which is the checkpoint block the lead rule names under the O-4.3 decision of 3 October 2026 (certified or not). Three facts decide it:
|
||||
|
||||
1. Determinism. A header's validity must be a function of its own past. "The certificate carried by a block in the header's past, for the highest-index checkpoint with DAA score at most the cut" is such a function, but a certificate that lands after the era starts flips the reading between headers of one era (a header before the carrier reads the fallback, a header after it reads the certificate), so the certified binding needs a second rule: the carrier must sit at most half a lead above the cut (3,600 DAA s, the merge depth) and be a chain ancestor of the header; under that rule every honest header of the era reads the same certificate once the network merged the carrier, and a header on a chain that never merged it reads the fallback, consistently with its own past. The chain-block reading needs no second rule.
|
||||
2. Liveness. A finality pause across the cut (a third of weight leaving in an hour is a 30-day pause under rule v3) leaves the certified binding without a checkpoint for the era; the chain-block reading always has one, which is the reason O-4.3 was decided the way it was for the epoch.
|
||||
3. The defence. The grinding defence is the delay: no candidate's draw is knowable for T steps, whichever block is the cut. The binding moves which block a withholder would have to be the author of, not whether withholding pays; both readings leave the withholder with a coin flip it cannot see.
|
||||
|
||||
The change, if the finality lane wants the certified binding: `EraVdfManager::cut_block` (one function; the input, the delay and the seed are unchanged), plus the second rule above and a test with a certificate carried late.
|
||||
|
||||
## 5. The verify gate on a 2019-class core
|
||||
|
||||
The gate was "the VDF verifies in under 10 ms on a 2019-class core". Measured: 21.9 and 22.6 ms with the group held on the box core (above), which the F6 row's calibration puts at about 1.19x on an i7-9700K (the O-1.14 run: 6.0 ms on the 2019 core against 5.06 ms on the box proxy), so about 26 ms on a 2019 core, labelled a proxy: no 2019 host was rented this lane (Vast rentals are a purchase; not made without the founder's word). NOT MET, by 2.2x on the box and about 2.6x on the proxy.
|
||||
|
||||
Where the time goes and what closes it: a verification is two 256-bit exponentiations, about 770 group operations at 28 µs each; the operation is NUDUPL on the fixed-width integer, whose cost is the extended gcd (Lehmer rounds on 8-limb numbers) and the reduction. Three rounds of this lane moved it from 345 µs (a Lehmer convention defect that fell back to plain division every round) to 28 µs (the convention, i64 word division, 34 limbs, the x86-64 128-by-64 division); the next 2.2x is chiavdf's Pulmark reducer (reduce only when `a` exceeds 8 limbs, O-4.6) and a limb-level NUDUPL that keeps the partial gcd's intermediates in words, or GMP through `rug` behind a feature on the x86-64 Linux and Windows builds (chiavdf's 208 K/s is 6x this evaluator, which would put the verification near 4 ms as the prototype measured), with the fixed-width path the fallback for wasm and macOS. Owed, not blocking: the verification runs once per era (180 days) on a node that imports a record rather than evaluating; every mining node evaluates and never verifies.
|
||||
|
||||
## 6. Consequences per tier (the standing rule of 5 October 2026)
|
||||
|
||||
| Tier | What the era VDF costs | What it means |
|
||||
|---|---|---|
|
||||
| A home miner, any card (8, 12, 16, 24 or 32 GB), any vendor, Windows, Linux or macOS | one CPU core for about 60 min once per 180 days at the reference rate (a 2019-class desktop core about 72 min by the F6 calibration), 17 MB of host RAM for the prover's checkpoints during it, 0 bytes on the card; the node starts it a quarter of the lead past the cut and holds the record from then | nothing changes on the card or in the hash rate; the 2-hour lead covers a core half the reference speed; a node that was off across the cut evaluates on arrival and its miner holds until the record lands (the miner says so every 10 s) |
|
||||
| A rig (one node, several cards) | the same one core on the rig's host, once per era | nothing per card |
|
||||
| A pool user | the pool's node evaluates; the member's miner takes `era_seed` from the template as today | nothing |
|
||||
| A light client or a syncing node | verifies an imported record in 22 ms (26 ms on a 2019 core, proxy) plus the 165-ms discriminant derivation, once per era; under scheme 1 it recomputes the hour | the 10-ms gate is missed (section 5); operationally one verification per 180 days |
|
||||
| The protocol | the era draw's input is unknowable for 517 s on the fastest prover measured, against a 1-s block interval: the stand-in's one-block grind is closed (section 3) | the freeze of the draw procedure and the C_era cut rule no longer waits on the VDF's existence; it waits on the two decisions of `ledger-decisions.md` |
|
||||
|
||||
## 7. What is owed
|
||||
|
||||
- The P2P relay of an era record to a syncing peer and the RPC import (spec 4.5, O-4.10), before era 1 of any network with the switch set.
|
||||
- The external review of the class-group port (O-4.1): the port is a second implementation checked against the textbook algorithms and `num-bigint`, not a review.
|
||||
- The attack pass's F7 status row (branch `attack-pass`, `docs/analysis/attack-pass-2026-10.md`) reads INCOMPLETE pending this lane; the line for it, from section 3: "F7 (a): the era VDF is in the node (fork `era-vdf-node`); the re-roll harness against the real era cut fires with it off (6 of 6 cuts, the seed the adversary's block) and is silent with it on (0 of 6 across six cuts, the adversary's 5-s evaluation against a 1-s block interval, three nodes agreeing on every era seed); PASS, the delay 517 s on the fastest prover measured at the production T."
|
||||
- The decisions of `docs/plans/ledger-decisions.md` (the activation per network, the cut's binding).
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Per-identity hash rate "decay" on the RTX 5090: diagnosis and fix
|
||||
|
||||
3 October 2026, miner-community-lead. Source data: the uploaded logs of the project lead's PC (`node tools/logs.mjs
|
||||
3 October 2026, miner-community-lead. Source data: the uploaded logs of the founder's PC (`node tools/logs.mjs
|
||||
nvidia-DESKTOP-KMCV30N-1-20261003-222331 --all` and the other identities, the launcher log
|
||||
`igneum-DESKTOP-KMCV30N-20261003-222331`), the three serve loops, the miner's worker mode, and five runs of the
|
||||
Metal worker on the Mac against private test nodes (ports 27500 and up, `/tmp/igneum-decay-test`). Figures
|
||||
|
|
@ -9,7 +9,7 @@ from the logs are exact; the two labelled approximate are from memory.
|
|||
## 1. Finding in one paragraph
|
||||
|
||||
There is no per-job growth in any worker or in the miner's memory. Two separate things produce the picture
|
||||
the project lead saw. First, the STATUS line's two rates are cumulative averages since the miner started
|
||||
The founder saw. First, the STATUS line's two rates are cumulative averages since the miner started
|
||||
(`hashes_total / elapsed` and `hashes_total / gpu_ms_total` in `mine_worker`), so a fast first interval
|
||||
decays as 1/t by construction; nvidia-1 was alone on the card for its first seconds and every later interval
|
||||
ran at a flat 17.8 MH/s wall, while the last-started identity, nvidia-8, shows the mirror image, a cumulative
|
||||
|
|
@ -28,7 +28,7 @@ The miner prints `hash=A MH/s wall (B MH/s inside jobs)` with `A = hashes_total
|
|||
`dH / dt` and `dH / dG` with `H = A x t` and `G = H / B`. Every table below is that calculation
|
||||
(`rates.py` in the bench-log entry).
|
||||
|
||||
### 2.1 The segment the project lead quoted: 22:57 to 23:04 UTC, after the epoch-3 restart (DAA 10,801 on)
|
||||
### 2.1 The segment the founder quoted: 22:57 to 23:04 UTC, after the epoch-3 restart (DAA 10,801 on)
|
||||
|
||||
nvidia-1, jobs of 2^24 nonces, STATUS every 30 s:
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ card going idle, which is what a growing CPU-side gap in every worker does.
|
|||
|
||||
## 3. Code audit: what is allocated per job, and what is freed
|
||||
|
||||
### 3.1 `proto-cuda/host.cu`, `runServe` (HEAD, the binary the project lead ran, built by the launcher at 22:09:57)
|
||||
### 3.1 `proto-cuda/host.cu`, `runServe` (HEAD, the binary the founder ran, built by the launcher at 22:09:57)
|
||||
|
||||
| Allocation | When | Size | Freed |
|
||||
|---|---|---|---|
|
||||
|
|
@ -113,7 +113,7 @@ version (the hot-swap agent's) adds `CudaPair` (at most two resident, the old on
|
|||
job on the new pair, `releasePair` frees dataset, cache and both modules) and `PrepareTask` (deleted after
|
||||
the load); still nothing per job. `cudaDeviceSynchronize` per dispatch under the default
|
||||
`cudaDeviceScheduleAuto` spins the host thread when the process holds fewer contexts than the machine has
|
||||
cores, which is always true here (one context per process): that is the 6.2% CPU per worker the project lead saw (one
|
||||
cores, which is always true here (one context per process): that is the 6.2% CPU per worker the founder saw (one
|
||||
of 16 threads). The hot-swap working tree sets `cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync)` before
|
||||
the context is created (host.cu, main), which is the right call and the right place; the thread then sleeps
|
||||
on the dispatch. It does not change the hash rate directly, but eight spinning threads plus eight OpenCL
|
||||
|
|
@ -250,7 +250,7 @@ because it is measured from the template fetch, which precedes the walk).
|
|||
|
||||
## 5. The time-slicing hypothesis: one worker versus eight, at two fixed difficulties
|
||||
|
||||
the project lead's Task Manager reading (GPU memory flat at 14.7 GB, the card 99% busy, each CUDA worker at 6.2% CPU) and the
|
||||
The founder's Task Manager reading (GPU memory flat at 14.7 GB, the card 99% busy, each CUDA worker at 6.2% CPU) and the
|
||||
hypothesis that eight contexts time-slicing one card with "longer jobs as blocks get rarer" explain the decay. A
|
||||
job is a fixed 2^24 nonces, so its length does not depend on the target, but the four runs below test the
|
||||
hypothesis as stated: one Metal worker and eight, each at a fixed low difficulty (2^25, 0.25 founds per job)
|
||||
|
|
@ -483,20 +483,20 @@ warnings; also saved as `docs/analysis/hashrate-decay-2026-10-03.patch`).
|
|||
acceptance figure is table 2.2 flattening: the gap per job no better than 0.10 s at DAA 10,800 (3,600
|
||||
into an epoch) with eight identities.
|
||||
|
||||
## 7. Two things for the project lead to check on the PC
|
||||
## 7. Two things for the founder to check on the PC
|
||||
|
||||
1. Dedicated GPU memory over time. Task Manager, Performance, GPU 0, "Dedicated GPU memory usage", or
|
||||
`nvidia-smi --query-gpu=timestamp,memory.used,utilization.gpu,temperature.gpu,clocks.sm,clocks.mem,power.draw,clocks_throttle_reasons.active --format=csv -l 10 > gpu.csv`.
|
||||
Expected: flat from the moment the eighth worker prints `ready` (each CUDA worker holds 1 GiB dataset +
|
||||
256 MiB cache + 32 MiB output + the context, about 1.6 GiB; eight of them 13 to 15 GiB of the 32 GiB,
|
||||
which matches the flat 14.7 GB the project lead read). A line that climbs while the hash rate falls would mean a leak
|
||||
which matches the flat 14.7 GB the founder read). A line that climbs while the hash rate falls would mean a leak
|
||||
in the worker; none exists in the code and the Mac RSS traces are flat.
|
||||
2. GDDR7 memory junction temperature and the throttle reasons. HWiNFO64, Sensors, under the GPU: "GPU
|
||||
Memory Junction Temperature", "GPU Thermal Limit", "GPU Power Limit", "GPU Reliability Voltage Limit"
|
||||
(each "Yes" or "No"), "GPU Effective Clock" and "GPU Memory Clock"; or the `clocks_throttle_reasons.active`
|
||||
column above (`0x0000000000000004` is SW power cap, `0x0000000000000020` SW thermal slowdown,
|
||||
`0x0000000000000040` HW thermal slowdown, `0x0000000000000080` HW power brake). Approximate thresholds,
|
||||
from memory: the core starts to pull clocks around 83 C (the project lead's 55 to 59 C is far below it); GDDR6X on the
|
||||
from memory: the core starts to pull clocks around 83 C (the founder's 55 to 59 C is far below it); GDDR6X on the
|
||||
previous generations throttles from about 95 C junction and the hard limit is 105 C; GDDR7 figures are not
|
||||
published, so treat anything above 90 C junction as the zone to watch and a "Yes" on any limit row as the
|
||||
signal. The decisive sign of throttling is "GPU Effective Clock" falling while utilization stays at 99%;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Horizon, October 2026: the ranked research across every system
|
||||
|
||||
Written 6 to 7 October 2026 by the Horizon coordinator (branch `horizon`, worktree `igneum-wt-horizon`) on the project lead's ask of 6 October 2026, 20:4x UK: "deep backward and forward predictive research and modelling for our algo and all of our systems: is there room for improvement, room for more coin utility, algo improvements, security improvements, anything we can do to make a 51% attack impossible, basically creating a level of polish that has not been seen before." Later the same evening: "research anything else that we can research too, predictions, forward thinking, what we can actually do that has not been done or applied, think outside the box", "be revolutionary", and "if we create a new way of hashing or a new way of proof of work to revolutionise the space then that's absolutely fine, I want you to deploy everything to create something that has not ever been done before."
|
||||
Written 6 to 7 October 2026 by the Horizon coordinator (branch `horizon`, worktree `igneum-wt-horizon`) on the founder's ask of 6 October 2026, 20:4x UK: "deep backward and forward predictive research and modelling for our algo and all of our systems: is there room for improvement, room for more coin utility, algo improvements, security improvements, anything we can do to make a 51% attack impossible, basically creating a level of polish that has not been seen before." Later the same evening: "research anything else that we can research too, predictions, forward thinking, what we can actually do that has not been done or applied, think outside the box", "be revolutionary", and "if we create a new way of hashing or a new way of proof of work to revolutionise the space then that's absolutely fine, I want you to deploy everything to create something that has not ever been done before."
|
||||
|
||||
The bar main set, and the bar this document holds every claim to: "impossible" is not available to any proof-of-work chain. The bar is that a majority of hash buys nothing: it cannot reverse what finality locked, cannot forge a proof the nodes re-execute, cannot change a rule without 95 percent signalling, and loses more than it earns. Every claim here is a number with a model or a simulation behind it, priced in rented hash at the measured 6 October rate (`docs/bench-log.md`, "Rental cost of hash, 6 October 2026": USD 0.0117 per MH/s-hour, so USD 11.7 per GH/s-hour and about USD 281 per GH/s-day; the live devnet at 1.16 GH/s), with its consequence per tier and what to build. Hours are agent hours (the project lead's rule: Claude-side work takes hours, never weeks).
|
||||
The bar main set, and the bar this document holds every claim to: "impossible" is not available to any proof-of-work chain. The bar is that a majority of hash buys nothing: it cannot reverse what finality locked, cannot forge a proof the nodes re-execute, cannot change a rule without 95 percent signalling, and loses more than it earns. Every claim here is a number with a model or a simulation behind it, priced in rented hash at the measured 6 October rate (`docs/bench-log.md`, "Rental cost of hash, 6 October 2026": USD 0.0117 per MH/s-hour, so USD 11.7 per GH/s-hour and about USD 281 per GH/s-day; the live devnet at 1.16 GH/s), with its consequence per tier and what to build. Hours are agent hours (the founder's rule: Claude-side work takes hours, never weeks).
|
||||
|
||||
## The lanes
|
||||
|
||||
|
|
@ -17,11 +17,11 @@ The bar main set, and the bar this document holds every claim to: "impossible" i
|
|||
| 7 frontier | `docs/analysis/horizon/frontier.md`; model `sim/horizon/frontier/frontier_model.py` | landed, commit 5ff7393 |
|
||||
| 8 new-proof-of-work | `docs/analysis/horizon/new-pow.md`; prototypes `proto-newpow/` | landed, commits cbcff47 and 92db7c5 (two prototypes measured on rented 4090s, verdicts in section 6) |
|
||||
|
||||
## 1. One page for the project lead
|
||||
## 1. One page for the founder
|
||||
|
||||
Closed 6 October 2026, 22:3x UK, every lane landed.
|
||||
|
||||
**Standing decisions (the project lead, 6 October 2026, 22:3x UK).** Verbatim: "Fees cannot fund security for a decade" and "Miners need to be the security". Meaning: miners are the security always, no time bound, no stake, no outside checkpoints or committee. The chain pays its own miners from emission plus fees; nobody pays upkeep, not the founder, not a treasury, not a dev fund. Self-sustaining means the emission curve keeps mining worth doing on its own for as long as fees are small, which lane 4 measures as a decade or more, so emission never decays on a schedule that assumes fees take over. Fee revenue is never assumed as the security budget in any model or public sentence. His third line, "Wrong constants and claims in our own text", acknowledges lane 6's finding; the nine ledger rows in item 9 are the fix.
|
||||
**Standing decisions (the founder, 6 October 2026, 22:3x UK).** Verbatim: "Fees cannot fund security for a decade" and "Miners need to be the security". Meaning: miners are the security always, no time bound, no stake, no outside checkpoints or committee. The chain pays its own miners from emission plus fees; nobody pays upkeep, not the founder, not a treasury, not a dev fund. Self-sustaining means the emission curve keeps mining worth doing on its own for as long as fees are small, which lane 4 measures as a decade or more, so emission never decays on a schedule that assumes fees take over. Fee revenue is never assumed as the security budget in any model or public sentence. His third line, "Wrong constants and claims in our own text", acknowledges lane 6's finding; the nine ledger rows in item 9 are the fix.
|
||||
|
||||
1. **The proving pool was the one line where a majority earned more than it spent**: 11,636 IGN an hour at 51 percent of blocks. Fix: the proof verified in consensus. **In 0.3.16** (fork exec-sync-0313 da2d17ec), switch `proving_consensus_verify_daa` off by default. **Decision owed:** when it activates.
|
||||
|
||||
|
|
@ -41,11 +41,11 @@ Closed 6 October 2026, 22:3x UK, every lane landed.
|
|||
|
||||
9. **Polish.** Pause wording in Ember and the API: **in 0.3.16** (ember-tune b726ce4). `fork_is_close` and the publisher's activation guard: **in 0.3.16** (1357d28, 08f5276). Export-disk cap: **done** (gpu-fleet f9ad70e). Nine text corrections (M32, M33, F26, E19, E20, G15, P24, E21, P25) plus X31 to X33: **done**. Unsigned installers: **decision owed**. Relay fixes (28c028b) on fud-close: merge owed.
|
||||
|
||||
**Decisions owed from the project lead:** the cryptanalysis spend (USD 80,000 to 160,000); the testnet date word; the N ladder at genesis; the verification switch activation.
|
||||
**Decisions owed from the founder:** the cryptanalysis spend (USD 80,000 to 160,000); the testnet date word; the N ladder at genesis; the verification switch activation.
|
||||
|
||||
## Decisions ready for the project lead (added 6 October 2026, 23:1x UK)
|
||||
## Decisions ready for the founder (added 6 October 2026, 23:1x UK)
|
||||
|
||||
Two one-page verdicts landed after the close. Each is quoted verbatim from its file and each is **the project lead's decision owed**. The files sit on their branches and are not merged; read them there.
|
||||
Two one-page verdicts landed after the close. Each is quoted verbatim from its file and each is **the founder's decision owed**. The files sit on their branches and are not merged; read them there.
|
||||
|
||||
### Emission: the tail
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ The residual risks stated plainly: the first 20 days (no weight table yet); a pa
|
|||
### Lane 6, polish
|
||||
1. The pause had no cause on any surface: no `finality_reason` or frozen-table share in the node's report, the observer, the API, Ember or the hub (Q1, Q2, Q6); the 0.3.16 Ember carrier is on ember-tune.
|
||||
2. Every update was urgent once an activation height was behind the node (`fork_is_close`, Q4), and nothing refused an activation height at or below the live DAA; both fixed on ember-tune for 0.3.16.
|
||||
3. Unsigned installers on both desktops (Q3, the project lead's certificates) and the relay's security fixes still on fud-close (Q8).
|
||||
3. Unsigned installers on both desktops (Q3, the founder's certificates) and the relay's security fixes still on fud-close (Q8).
|
||||
|
||||
### Lane 8, new-proof-of-work
|
||||
1. Scheme A (mining is proving) is a bound, not a design: 2.9 MB of openings per block or a 32 to 40 ms verify against the 10 ms gate; the useful fraction is 8 percent at 1 GH/s and 0.08 percent at 100 GH/s.
|
||||
|
|
|
|||
|
|
@ -305,11 +305,11 @@ Recommendation with numbers: hold the schedule as decided (2 GiB genesis, doubli
|
|||
| 5a | A class v5 candidate `mx8 + sh256x35` with a shuffle-heavy shadow weight table (shfl 14, shfla 8 of 75), measured on the four owned cards before any cut: the first rung of proposal 5's ladder, plus the k-floor lever | the Mac's 5 percent point is 130,000; the shuffle mix raises the k floor 0.32 to 0.46 (approx) | section 5.3 | 4 to build the weight-table knob and packs, 1 Mac measure session (about 6 min under the lock, miner paused), 3 PC jobs | M5 Max -4.8 percent of rate at 37 W; 5090 -0.3 percent at its 431 W cap (a rig +23 percent electricity); 4070 0 at about 118 W; 9070 XT 0; verifier +0.23 ms Mac, +0.85 half-core | every owned card within 5 percent; bit-exact on three vendors; half-core verifier under 10 ms; the 5090's marginal pJ on the new mix read on three rungs |
|
||||
| 6 | Hold the dataset schedule (2 GiB, years 4, 12, 28); write the prover footprint into the card-lifetime sentence | Steam shares and the measured prover peaks; one HBM3 stack holds every step | section 5.6 | 1 | 8 GB: mines to year 12, proves alone; 12 GB: mine-and-prove compressed to year 4, core-only to year 12, mines to year 28; 16 GB: compressed to year 4, core-only to year 12; 24 and 32 GB unconstrained to year 28 | the litepaper sentence matches the table; `docs/evidence.md` row "card lifetime" labelled designed |
|
||||
| 7 | Make the Ember tune the shipped default per card model (the honest card's watts are the lever that moves every chip row) | the 4070 at 3.65 uJ untuned and 2.57 tuned (-30 percent); the 5090 2.65 bench against 2.34 app | section 5.1 | 2 (defaults table in the app from the fleet priors; already measured) | every NVIDIA tier gains 10 to 30 percent per joule; the chip's edge over the mid-tier falls from 8x to 13x toward 5x to 9x at v3 | MH per W per card model on the fleet night against the untuned baseline |
|
||||
| 8 | Fund the k question: the item 3 cryptanalysis brief gains a chip-design line (a 14,000-lane SIMD array's energy per op on a random 32-lane program with shuffles, at N5 and at 28 nm) | every chip row at class v4 turns on k; nothing in the project measures it | section 5.3 | 0 agent hours; the project lead's money (part of the USD 80,000 to 160,000 brief) | none until the number lands; it decides whether 2x is reachable | a reviewed estimate of k with its range |
|
||||
| 8 | Fund the k question: the item 3 cryptanalysis brief gains a chip-design line (a 14,000-lane SIMD array's energy per op on a random 32-lane program with shuffles, at N5 and at 28 nm) | every chip row at class v4 turns on k; nothing in the project measures it | section 5.3 | 0 agent hours; the founder's money (part of the USD 80,000 to 160,000 brief) | none until the number lands; it decides whether 2x is reachable | a reviewed estimate of k with its range |
|
||||
|
||||
Paragraphs.
|
||||
|
||||
1. The verifier gate is the one place tonight produced a measurement instead of a rule. The box proxy brackets a 2019 laptop from both sides (a 2022 server core at full boost; the same core with its sibling busy), and dr736 fails both brackets while class v4 passes both with 1.8 ms to spare. The measurement is one Windows build and one bench on the laptop the project lead already owns; until it lands, the half-core row replaces the "2.5x" from memory in every status file.
|
||||
1. The verifier gate is the one place tonight produced a measurement instead of a rule. The box proxy brackets a 2019 laptop from both sides (a 2022 server core at full boost; the same core with its sibling busy), and dr736 fails both brackets while class v4 passes both with 1.8 ms to spare. The measurement is one Windows build and one bench on the laptop the founder already owns; until it lands, the half-core row replaces the "2.5x" from memory in every status file.
|
||||
|
||||
2. The FPGA lane's upper row was built on an activate rate (8 per 12 ns per channel) that the JEDEC HBM2 cycle table does not support (4 per 28 ns); the measured Shuhai rate sits exactly on the JEDEC ceiling. That reading can be wrong (the ICCAD table's clock interpretation, the half-bank count, the board watts are all approximate), which is why the F2 hour is the proposal and not the conclusion. It is cheap and it turns a public ceiling claim into a measured one.
|
||||
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ Ways not in the seven, with the bound this lane gives:
|
|||
| The 30-day window edges | (a) the frozen table expires at exactly day 30.00 after the last lock: both sides of a long split lock alone at once (M3); (b) a departed set leaves the sliding table over 30 days and the frozen one at the cliff (M4); (c) the first 30 days have no lock at all (3.8, `min_daa` = window); (d) new honest cohorts are under-weighted t/60 for 30 days (G) | stated in 3.7 items 2, 7, 9 | a partition or departure longer than one window ends with the fork of 3.7 item 9 and a manual F5 | | |
|
||||
| The pause as a liveness attack | a silent set at or above 1/3 pauses every lock for as long as it stays silent (J, L1; sweep S) at zero marginal cost since it keeps earning | none in the rule; the node reports the pause; exchange guidance treats the chain as PoW with a 12-h depth | the 1/3 veto: 20 days at 51% | 0 once held | nothing directly; enables the 12-h PoW double spend below |
|
||||
| What an attacker can do during a pause | plain proof of work: reorg up to the finality depth 43,200 DAA (12 h) with a heavier chain; beyond merge depth the honest blocks are abandoned (the 229-block shape); every certified checkpoint before the pause still binds | finality depth; the exchange guidance of 3.9 | 12 h of >50% hash | USD 146 / 1.5k / 15k / 146k | a deposit credited at the PoW depth; 559k IGN of subsidy as a miner |
|
||||
| Tonight's departure (confirmed, lane 3 `finality-and-weight.md` 3.1 and 4.1) | 20 keys holding 42.7% of the frozen table stopped mining 18:27 to 18:30Z (the rehearsal job); the last lock 6842 at 18:39:40Z; 6843 determined with 53.1% of total signing and never locked; under v2 the stayers' sliding share crossed two thirds at 6912 (19:14:53Z, a 35-min pause) but Q5 held them at 57.3% of the frozen table; expected first lock when that table expires at DAA 216,402, about 20:40Z, or when 9.4 points of departed keys return. Sweep C agrees: 51% leaving pauses 10.5 days (v2) or 30.0 days (v3) at mainnet scale; at tonight's 46.9% (observer's view) 7.7 days under v2, 30 under v3 (lane 3, 4.1) | by design (F21: the project lead chose the pause over the fork); a view cannot tell a departure from a partition | anything over 1/3 of the table leaving at once pauses finality for a window | 0 | 0; what an attacker can do during it is the row above |
|
||||
| Tonight's departure (confirmed, lane 3 `finality-and-weight.md` 3.1 and 4.1) | 20 keys holding 42.7% of the frozen table stopped mining 18:27 to 18:30Z (the rehearsal job); the last lock 6842 at 18:39:40Z; 6843 determined with 53.1% of total signing and never locked; under v2 the stayers' sliding share crossed two thirds at 6912 (19:14:53Z, a 35-min pause) but Q5 held them at 57.3% of the frozen table; expected first lock when that table expires at DAA 216,402, about 20:40Z, or when 9.4 points of departed keys return. Sweep C agrees: 51% leaving pauses 10.5 days (v2) or 30.0 days (v3) at mainnet scale; at tonight's 46.9% (observer's view) 7.7 days under v2, 30 under v3 (lane 3, 4.1) | by design (F21: the founder chose the pause over the fork); a view cannot tell a departure from a partition | anything over 1/3 of the table leaving at once pauses finality for a window | 0 | 0; what an attacker can do during it is the row above |
|
||||
|
||||
### 4.4 Miner signalling (P2)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ What was read: `docs/spec/03-finality.md` (whole, 3.11 included), `04-seeds-and-
|
|||
|
||||
## 1. The three findings first
|
||||
|
||||
1. **Tonight's pause was the rule, not the aggregation path, and it was the frozen table that held it past 19:14Z.** The 20 keys that left the live chain between 17:20Z and 18:30Z held 3,026 of 7,083 blue blocks of the table frozen at the last lock (42.7 percent; the 13 that left with the 18:27 to 18:30Z rehearsal job alone 36.5 percent). The first unlocked checkpoint, 6843 at DAA 209,233 (about 18:40Z), had 75 of 93 voters' votes and 53.1 percent of total weight on the observer's node, under the two-thirds floor; certificates had kept forming for 18 checkpoints while node 1 and the observer were down (6824 to 6842, 18:30 to 18:39Z, 83 signers, 78.5 to 79.7 percent of total). From 19:14:53Z (checkpoint 6912) the stayers held 74.9 percent of the sliding table and still did not lock, because they hold 57.3 percent of the frozen table of lock 6842, which stands until DAA 216,402 (about 20:40Z). Under rule v2 the first lock would have come at 6912, 35 minutes after the last; under v3 the pause is one window, 2 hours on the devnet and 30 days on mainnet (spec 3.7 item 2, the price the project lead took on 4 October).
|
||||
1. **Tonight's pause was the rule, not the aggregation path, and it was the frozen table that held it past 19:14Z.** The 20 keys that left the live chain between 17:20Z and 18:30Z held 3,026 of 7,083 blue blocks of the table frozen at the last lock (42.7 percent; the 13 that left with the 18:27 to 18:30Z rehearsal job alone 36.5 percent). The first unlocked checkpoint, 6843 at DAA 209,233 (about 18:40Z), had 75 of 93 voters' votes and 53.1 percent of total weight on the observer's node, under the two-thirds floor; certificates had kept forming for 18 checkpoints while node 1 and the observer were down (6824 to 6842, 18:30 to 18:39Z, 83 signers, 78.5 to 79.7 percent of total). From 19:14:53Z (checkpoint 6912) the stayers held 74.9 percent of the sliding table and still did not lock, because they hold 57.3 percent of the frozen table of lock 6842, which stands until DAA 216,402 (about 20:40Z). Under rule v2 the first lock would have come at 6912, 35 minutes after the last; under v3 the pause is one window, 2 hours on the devnet and 30 days on mainnet (spec 3.7 item 2, the price the founder took on 4 October).
|
||||
2. **Of the four candidate rules, only the departure announcement keeps the one-third bound.** In the simulator (3 seeds, mainnet scale) the decaying denominator and the hysteresis floor both restore liveness after tonight's departure in under an hour and both reopen the partition double lock (fast decay: both sides of every 360-minute partition lock alone from minute 120, 467 to 473 conflicting locks in the 50/50 honest split and 17 to 264 in the poisoned eclipse; slow decay: both sides of the 12-day splits lock alone at day 0.5 to 0.9, 31,545 to 32,246 conflicts; hysteresis: a 20 percent equivocator conflicts from minute 60, 565 to 597 locks, the 13.3 percent bound of 3 October back). The leave rule locks 1 hour after the departure (0.04 days; under 4 devnet minutes) with 0 conflicting locks in every partition, eclipse and equivocator row, and an attacker who buys keys to make them leave gains nothing it would not get by signing with them (w + L must still reach 2/3). The two-tier report never conflicts in its final tier by construction and shows 516 to 1,062 conflicting PROVISIONAL locks in every 360-minute partition and about 34,000 in the 12-day splits, so it is a reporting layer with a health warning, not a rule.
|
||||
3. **Weight costs USD 8,424 x N x W / (1 - W) to rent for the full window** at the measured USD 11.7 per GH/s-hour: a veto (34 percent) against a 1 GH/s network is USD 4,300 over 30 days (0.52 x N of hash, a +52 percent step on the chart from day 1), against 1 TH/s USD 4.3 M; locking alone (67 percent) is 2.03 x N for 30 days (USD 17,100 per GH/s of network, USD 17 M at 1 TH/s), and faster is dearer (22 days: 10.6 x N). Buying old keys costs the seller's own rental equivalent, decays to nothing in 30 days (sim K), and nothing in the protocol makes weight unbuyable; what keeps the price at the rental cost is that the seller keeps a copy and one equivocation strips the key.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Horizon lane 7: frontier. Predictions to 2030, what no proof-of-work chain has shipped, and what Igneum can
|
||||
|
||||
6 October 2026, evening UK. Lane 7 of the Horizon programme. Worktree `/Users/joshm/Projects/igneum-wt-horizon` (branch `horizon`, at origin/master 3f4f719). the project lead's words: "research anything else that we can research too, predictions, forward thinking, what we can actually do that has not been done or applied, think outside the box", and "be revolutionary". Main's bar: not features, but ideas that change what a proof-of-work chain is or what a GPU owner is to the world, each with its evidence, cost, gate, and the attack a Monero or Kaspa core developer would mount. I argue each attack as the project's own four personas would hear it (`.claude/agents/cryptographer.md`, `consensus-engineer.md`, `execution-engineer.md`, `miner-community-lead.md`).
|
||||
6 October 2026, evening UK. Lane 7 of the Horizon programme. Worktree `/Users/joshm/Projects/igneum-wt-horizon` (branch `horizon`, at origin/master 3f4f719). The founder's words: "research anything else that we can research too, predictions, forward thinking, what we can actually do that has not been done or applied, think outside the box", and "be revolutionary". Main's bar: not features, but ideas that change what a proof-of-work chain is or what a GPU owner is to the world, each with its evidence, cost, gate, and the attack a Monero or Kaspa core developer would mount. I argue each attack as the project's own four personas would hear it (`.claude/agents/cryptographer.md`, `consensus-engineer.md`, `execution-engineer.md`, `miner-community-lead.md`).
|
||||
|
||||
Nothing in this file is a prediction of the coin's price, an offer to sell anything, or a change to any consensus parameter. Every chip figure is arithmetic on cited memory and logic figures; every GPU figure names its bench entry; a figure from memory says approximate. No em dashes.
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ Nothing in this file is a prediction of the coin's price, an offer to sell anyth
|
|||
|
||||
## 0. Everything ranked by payoff over difficulty
|
||||
|
||||
Payoff 1 to 5 is what the idea does for the chain's security, the coin's utility or the GPU owner's position in the world, if it works. Difficulty is Claude-side hours to a measurable prototype (the project lead's rule: hours, never weeks). Verdicts: do now, prototype, watch, never. The "never" rows carry a sharp reason so the rest are not fantasy.
|
||||
Payoff 1 to 5 is what the idea does for the chain's security, the coin's utility or the GPU owner's position in the world, if it works. Difficulty is Claude-side hours to a measurable prototype (the founder's rule: hours, never weeks). Verdicts: do now, prototype, watch, never. The "never" rows carry a sharp reason so the rest are not fantasy.
|
||||
|
||||
| Rank | Idea | Payoff | Hours | Verdict | One line why |
|
||||
|---|---|---|---|---|---|
|
||||
|
|
@ -322,7 +322,7 @@ The at-risk amount is five to nine orders of magnitude above the designed coin b
|
|||
|
||||
### 3.6 Treasury-less audit funding: bounties from the burn, a review escrow on upgrades
|
||||
|
||||
**The idea.** the project lead removed the dev fund (spec 5.5) and the project pays audits from the Ember dev fee and founders' mined coins (litepaper). The question: money for audits that comes from users paying for something, with no standing address. Two mechanisms. (a) **Burn redirect.** The base fee burns to nobody. A reproducible break submitted under spec 0.5 and accepted by 60 percent of blue blocks over a window redirects the base-fee burn of the next 7 (execution) or 30 (consensus) days to the submitter's address, once, then returns to burning. No address exists between events. (b) **Review escrow.** An upgrade proposal under 5.7 must escrow IGN in a contract that pays reviewers named in the proposal on a 60 percent "review complete" signal, or refunds on failure; the proposer pays, which is a user paying for a thing (the right to propose code).
|
||||
**The idea.** the founder removed the dev fund (spec 5.5) and the project pays audits from the Ember dev fee and founders' mined coins (litepaper). The question: money for audits that comes from users paying for something, with no standing address. Two mechanisms. (a) **Burn redirect.** The base fee burns to nobody. A reproducible break submitted under spec 0.5 and accepted by 60 percent of blue blocks over a window redirects the base-fee burn of the next 7 (execution) or 30 (consensus) days to the submitter's address, once, then returns to burning. No address exists between events. (b) **Review escrow.** An upgrade proposal under 5.7 must escrow IGN in a contract that pays reviewers named in the proposal on a 60 percent "review complete" signal, or refunds on failure; the proposer pays, which is a user paying for a thing (the right to propose code).
|
||||
|
||||
**Why nobody shipped it.** Zcash funds development from the block subsidy (NU6: 8 percent to Zcash Community Grants, 12 percent to a protocol lockbox, ZIP 1015); Decred from a 10 percent treasury spent by stakeholder vote, capped at 4 percent of balance a month since January 2026 (DCP-0013); Monero from the CCS, donations off-chain; Optimism from an 850 M OP reserve for retro funding. Bug bounties pay 10 percent of funds at risk (Immunefi's standard) from the protocol's own treasury; Code4rena runs contests at zero platform fee since 2025. Nobody funds audits from a burn redirect, because a burn redirect is a subsidy to a payee by rule, and the chains that wanted that built a treasury. New in form; a dev fund in substance (see the Monero attack).
|
||||
|
||||
|
|
@ -341,7 +341,7 @@ At launch traffic a 30-day redirect is under one audit contest; at half-full blo
|
|||
|
||||
**Hours.** 20 for the escrow contract and the redirect rule as a proposal kind; 0 for the honest alternative, which already exists.
|
||||
|
||||
**The gate.** None that a simulator settles; the gate is the project lead's: does a per-event, miner-approved payee with no standing address pass the test that removed the dev fund?
|
||||
**The gate.** None that a simulator settles; the gate is the founder's: does a per-event, miner-approved payee with no standing address pass the test that removed the dev fund?
|
||||
|
||||
**Per tier.** Miners vote on each payout with their blocks and can refuse all of them; holders see supply that would have burned paid to a named person; a prover, rig, pool user and rollup customer see nothing unless a break affects them; the node operator gains a proposal kind.
|
||||
|
||||
|
|
@ -415,7 +415,7 @@ At launch traffic a 30-day redirect is under one audit contest; at half-full blo
|
|||
|
||||
**The idea as asked.** Make the leader election depend in part on proving work, so the energy that picks the block maker is useful.
|
||||
|
||||
**Why every attempt failed, cited.** Primecoin (2013) found Cunningham and bi-twin prime chains that nobody uses (Bitcoin Magazine, July 2013). Gridcoin pays for BOINC work and stops if BOINC stops (gridcoin.us; the 2022 "Challenges of PoUW" survey, arXiv 2209.03865). Ball, Rosen, Sabin and Vasudevan (eprint 2017/203) gave proofs of useful work from fine-grained problems (Orthogonal Vectors, 3SUM, APSP) and state the conditions: the problem must be sampleable at a tunable hardness with instances the miner cannot choose, and the verifier must be cheaper than the work. Ofelimos (Fitzi, Kiayias, Panagiotakos, Russell, CRYPTO 2022, eprint 2021/1379) got a provably secure protocol by making the work a doubly efficient local search whose usefulness is a side effect and small. The 2026 "Economics of Proof-of-Useful-Work" (arXiv 2606.06700) and the empirical study of Pearl's cuPOW (arXiv 2606.04819, "The Usefulness Gap") find the same gap between the work paid for and the work anyone wanted. I found no Coinbase paper on the subject (searched 6 October 2026); if the project lead has one in mind, its title is needed. Aleo ran proving as the consensus work and the fastest prover won (CLAUDE.md: the Aleo lesson; litepaper precedents table, approximate). Boundless's PoVW (docs.boundless.network/zkc/mining/overview) pays ZKC pro rata to cycles proven per epoch with a stake that scales with the work, which is a reward for proving, not a leader election, and it is on a proof-of-stake chain.
|
||||
**Why every attempt failed, cited.** Primecoin (2013) found Cunningham and bi-twin prime chains that nobody uses (Bitcoin Magazine, July 2013). Gridcoin pays for BOINC work and stops if BOINC stops (gridcoin.us; the 2022 "Challenges of PoUW" survey, arXiv 2209.03865). Ball, Rosen, Sabin and Vasudevan (eprint 2017/203) gave proofs of useful work from fine-grained problems (Orthogonal Vectors, 3SUM, APSP) and state the conditions: the problem must be sampleable at a tunable hardness with instances the miner cannot choose, and the verifier must be cheaper than the work. Ofelimos (Fitzi, Kiayias, Panagiotakos, Russell, CRYPTO 2022, eprint 2021/1379) got a provably secure protocol by making the work a doubly efficient local search whose usefulness is a side effect and small. The 2026 "Economics of Proof-of-Useful-Work" (arXiv 2606.06700) and the empirical study of Pearl's cuPOW (arXiv 2606.04819, "The Usefulness Gap") find the same gap between the work paid for and the work anyone wanted. I found no Coinbase paper on the subject (searched 6 October 2026); if the founder has one in mind, its title is needed. Aleo ran proving as the consensus work and the fastest prover won (CLAUDE.md: the Aleo lesson; litepaper precedents table, approximate). Boundless's PoVW (docs.boundless.network/zkc/mining/overview) pays ZKC pro rata to cycles proven per epoch with a stake that scales with the work, which is a reward for proving, not a leader election, and it is on a proof-of-stake chain.
|
||||
|
||||
**The sampleability problem, plainly.** A lottery needs a puzzle whose instances are drawn at random from a distribution the miner cannot steer, whose hardness is tunable by a target, and whose solution is verifiable in milliseconds. zkVM proving has none of these: the instances (segments, jobs) are chosen by users and producers, the hardness is whatever the program is, and the verifier is tens of milliseconds to seconds. Any blend ("a miner's lottery target eases in proportion to its proven cycles last hour") gives the fastest prover more blocks, which is Aleo with a cap, and a cap small enough to be safe is a reward too small to be useful.
|
||||
|
||||
|
|
@ -640,10 +640,10 @@ Smaller than the sections above; each with hours and a gate.
|
|||
| I6 | A finality-pause page on the site that shows the connected weight fraction live, so the "node reports the pause" sentence has a public face | 4 | Shows tonight's 18:42Z pause from the observer's data | Tonight's incident |
|
||||
| I7 | Equivocation-evidence bounty paid in sortition slots: the key that first carries valid evidence inherits the stripped key's shard assignments for 30 days (no coins move; weight is reassigned, not created) | 12 | Two signers under one key on the fast-time harness; the evidence carrier wins the stripped key's draws | Makes watching for equivocation pay without a treasury |
|
||||
| I8 | Mandatory proofs activation height set from a measured coverage share (spec 7.8 item 10) | 4 | Coverage above 99 percent for 7 days on the devnet | The rule is written and off |
|
||||
| I9 | The exclusive window at 25 s and the claim timeout at 120 s on the phase 4 devnet (decided by the project lead, P9) with the economy simulator re-run at the measured shard times from `prover-tiers-real-cards.md` instead of the 20-s target | 6 | The 3060 class's shard share within 5 points of its weight share | The inputs changed today |
|
||||
| I9 | The exclusive window at 25 s and the claim timeout at 120 s on the phase 4 devnet (decided by the founder, P9) with the economy simulator re-run at the measured shard times from `prover-tiers-real-cards.md` instead of the 20-s target | 6 | The 3060 class's shard share within 5 points of its weight share | The inputs changed today |
|
||||
| I10 | `eth_getProof`, `debug_traceTransaction`, `eth_subscribe` (D5 step 2) before any outside team | 24 | Foundry's debugger and the Blockscout fork run against a devnet node | The light client and every tool depend on `eth_getProof` |
|
||||
| I11 | Register chain ids 4461 to 4463 on ethereum-lists/chains before the public testnet (spec 7.1) | 1 | The PR merged | Wallets |
|
||||
| I12 | Publish the 2028 tier table (section 2.6) on the miner page with its three rates, so no card owner buys on a promise | 2 | Live | the project lead's consequences rule |
|
||||
| I12 | Publish the 2028 tier table (section 2.6) on the miner page with its three rates, so no card owner buys on a promise | 2 | Live | the founder's consequences rule |
|
||||
| I13 | A spec sentence in 03 and 05: "no coin stake; the only thing at stake is 30 days of public work" (4.1) | 1 | Text | Before 3.2 is prototyped |
|
||||
| I14 | The litepaper's income table gains the proving-market arithmetic of 3.11 in one line | 1 | Text | Ledger P6 asked for honesty; the number makes it concrete |
|
||||
| I15 | A ledger entry beside E4 recording 3.6 as considered and rejected on E4's ground | 1 | Text | So the question is not re-asked |
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ What was read: `docs/spec/02-consensus.md` (2.1 parameters, 2.3 the difficulty r
|
|||
|
||||
## 1. The question and the answer in one paragraph
|
||||
|
||||
the project lead asked for Kaspa's answer to solo-miner variance: a higher block rate. Run A ran Devnet 2 at 10 blocks per second through one seed and produced 77 percent red blocks, 321 tips and a 55-block reorg. The propagation model says the links and the star did not do that: with the measured latencies it predicts under 0.1 percent red at 10 bps in a star and in a mesh. What did it is the seed's CPU per block, measured at 61 ms (narrow DAG) to 345 ms (mergeset 150 to 200), against a budget of 100 ms per block at 10 bps; with that cost in the model the star gives 47 to 88 percent red and queueing waits of 26 to 1,769 s, which are the "Accepted 100 blocks via relay" batches in the log. The difficulty rule then read blue work over a chain step capped at 2 s and hardened until the DAG ran at 2 s / (chain-step spacing) of target (model 4 blocks/s at a 5-s spacing, record 3.3 to 3.6), while a narrower-but-still-wide DAG would have made it ease (the direction main reported); counting every mergeset block over the real span, as Kaspa's window does, is unbiased in both regimes. The block rate for the public testnet is 1 bps; 10 bps is a gated step that needs the per-block node cost under 50 ms on a laptop core at a mergeset of 248, the checkpoint interval and the clock cap re-denominated in DAA seconds, and vote aggregation, because with C1 in blue blocks 8,192 voters at 10 bps are 66 GB per node per day of votes.
|
||||
The founder asked for Kaspa's answer to solo-miner variance: a higher block rate. Run A ran Devnet 2 at 10 blocks per second through one seed and produced 77 percent red blocks, 321 tips and a 55-block reorg. The propagation model says the links and the star did not do that: with the measured latencies it predicts under 0.1 percent red at 10 bps in a star and in a mesh. What did it is the seed's CPU per block, measured at 61 ms (narrow DAG) to 345 ms (mergeset 150 to 200), against a budget of 100 ms per block at 10 bps; with that cost in the model the star gives 47 to 88 percent red and queueing waits of 26 to 1,769 s, which are the "Accepted 100 blocks via relay" batches in the log. The difficulty rule then read blue work over a chain step capped at 2 s and hardened until the DAG ran at 2 s / (chain-step spacing) of target (model 4 blocks/s at a 5-s spacing, record 3.3 to 3.6), while a narrower-but-still-wide DAG would have made it ease (the direction main reported); counting every mergeset block over the real span, as Kaspa's window does, is unbiased in both regimes. The block rate for the public testnet is 1 bps; 10 bps is a gated step that needs the per-block node cost under 50 ms on a laptop core at a mergeset of 248, the checkpoint interval and the clock cap re-denominated in DAA seconds, and vote aggregation, because with C1 in blue blocks 8,192 voters at 10 bps are 66 GB per node per day of votes.
|
||||
|
||||
## 2. Method
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
6 October 2026, evening UK, lane `new-proof-of-work`, worktree `/Users/joshm/Projects/igneum-wt-horizon` (branch `horizon` from master, at 3f4f719). Output of this lane: this file and `proto-newpow/<scheme>/`. Nothing here touches the shipped hash, `igneum-pow`, the node, the manifest or the live devnet; every prototype is a benchmark beside the worker, never inside it.
|
||||
|
||||
the project lead's mandate, verbatim: "if we create a new way of hashing or a new way of proof of work to revolutionise the space then that's absolutely fine, I want you to deploy everything to create something that has not ever been done before."
|
||||
The founder's mandate, verbatim: "if we create a new way of hashing or a new way of proof of work to revolutionise the space then that's absolutely fine, I want you to deploy everything to create something that has not ever been done before."
|
||||
|
||||
## 0. Progress (kept current for the coordinator)
|
||||
|
||||
|
|
@ -286,7 +286,7 @@ Reading: B moves the f = 1 chip's edge by 1.4x to 2x at `k = 1` and by 1.1x at `
|
|||
|
||||
## 7. Ranked next steps
|
||||
|
||||
Hours are agent hours (the project lead's rule: Claude-side work takes hours). Each gate is a measurable pass line. Consequence per tier is the row's own. Ranks 2, 3 and 4 were written as B's gates before the ladder landed; after section 5 they are WITHDRAWN (B is not carried forward as class content; the rows stay so the reasoning is visible) and the live order is 1, 5, 6, 7, 8.
|
||||
Hours are agent hours (the founder's rule: Claude-side work takes hours). Each gate is a measurable pass line. Consequence per tier is the row's own. Ranks 2, 3 and 4 were written as B's gates before the ladder landed; after section 5 they are WITHDRAWN (B is not carried forward as class content; the rows stay so the reasoning is visible) and the live order is 1, 5, 6, 7, 8.
|
||||
|
||||
| Rank | Proposal | Evidence | Model | Hours | Consequence per tier | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
|
|
@ -314,11 +314,11 @@ One paragraph each.
|
|||
| Question | Why it could not be closed tonight | What closes it |
|
||||
|---|---|---|
|
||||
| The 2019-class core (O-1.14) | no such core in the fleet; igneum-build-1 is Zen 4, the Mac is M5 Max; the 2.5x rule stands in | rank 7 |
|
||||
| The AMD WMMA fragment layout | PC 1 is the project lead's desk and the AMD rows were owed all day (status file); no AMD card on RunPod or Vast tonight (fleet agent) | rank 2 |
|
||||
| The AMD WMMA fragment layout | PC 1 is the founder's desk and the AMD rows were owed all day (status file); no AMD card on RunPod or Vast tonight (fleet agent) | rank 2 |
|
||||
| The Apple emulation of mm8 | a Metal emulation kernel is a 3-hour job and the Mac measure lock was free; not started because the AMD gate decides first whether B proceeds | rank 3 |
|
||||
| The canonical state serialisation for C | a design item that touches the exec layer (`igneum/exec`), out of this lane's files | rank 1 |
|
||||
| The pruning-proof witness for C's historical PoW | spec 02 and 10 items | rank 1 |
|
||||
| Whether the tensor path's marginal energy on the 5090 differs from the 4090's | one card measured (box 1); the 5090 is on the project lead's desk | a PC 2 job with the same `run.sh` |
|
||||
| Whether the tensor path's marginal energy on the 5090 differs from the 4090's | one card measured (box 1); the 5090 is on the founder's desk | a PC 2 job with the same `run.sh` |
|
||||
| The Ampere row (3060, 3080, 3090) | every Ampere card of the fleet was mining and proving the live devnet; a loaded 3090 was offered and declined (a loaded card's rate is not a number) | one quiet Ampere pod |
|
||||
| The verifier with a byte-dot instruction (VNNI, NEON udot) | the C reference is scalar | 1 h: an AVX-VNNI and a NEON path in `verify_ref.c`, measured on both cores |
|
||||
| Scheme C's leaf array on an 8 GB card at the 2 GiB design size | the build holds dataset + cache + leaves on the device (4.3 GiB) unless chunked | the chunked build (section 5.2 says whether it is trivial) |
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Date: 6 October 2026, evening UK (written 20:00 to 21:00Z, while the live devnet's finality was still paused). Lane 6 of the Horizon programme. Worktree `/Users/joshm/Projects/igneum-wt-horizon` (branch `horizon`, HEAD c3aa502). Output: this file only. No file outside it was edited; nothing was built, deployed, posted or started; the installed app and every live service were read, never touched.
|
||||
|
||||
the project lead's bar: "a level of polish that has not been seen before." This file is the honest audit: what each shipped system does, the named comparator and the exact screen or feature it has that we lack or do worse, the ledger rows that close the gap (95 rows, ids Q1 to Q105 with gaps, each with a file or screen, a severity, hours of agent work, an owner and a gate), and what is already better than the comparator. The first ten rows are what the project lead will notice first when he opens each product tomorrow.
|
||||
The founder's bar: "a level of polish that has not been seen before." This file is the honest audit: what each shipped system does, the named comparator and the exact screen or feature it has that we lack or do worse, the ledger rows that close the gap (95 rows, ids Q1 to Q105 with gaps, each with a file or screen, a severity, hours of agent work, an owner and a gate), and what is already better than the comparator. The first ten rows are what the founder will notice first when he opens each product tomorrow.
|
||||
|
||||
## 0. What was read and run
|
||||
|
||||
|
|
@ -14,26 +14,26 @@ Run (nothing live, nothing built): `node --test app/igneum-app/ui/*.test.mjs` (3
|
|||
|
||||
Comparator claims are from memory unless a repository or page is named, and are labelled approximate.
|
||||
|
||||
## 1. The ten rows the project lead will notice first
|
||||
## 1. The ten rows the founder will notice first
|
||||
|
||||
| Rank | Id | Row | File or screen | Severity | Hours | Owner | Who it hits | Gate |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| 1 | Q1 | The pause has no cause anywhere. The node reports `finality_reason` (`active`, `window filling, N of M`, `paused`) but not the frozen-table share that held tonight's pause; the observer drops even the reason; the API has no reason field; `/live` computes "N% of weight silent" from the sliding table, which read 11 percent silent at 20:05Z while finality was paused (held by the table frozen at lock 6842, 57.3 percent signing). Add `finality_reason`, `held_by` (frozen index, its signing share, its expiry DAA) and lane 3's `finality_provisional` end to end | `vendor/igneum-node-0310/consensus/src/processes/finality.rs:1794-1807` (reason exists, no frozen share), `tools/observer/observer.mjs:720` (copies `finalityActive` only), `site/api/live.mjs:114-122` (no reason), `site/live.html:520` (the silent percentage) | the project lead-visible | 4 (node 1.5, observer and API 1, `/live` and `/api/stats` copy 1, spec 3.9 row 0.5) | consensus-engineer (node), site owner (observer, API, page) | holder, exchange: the one line that says whether a pause is a silent third, a split, or a table waiting to expire; miner: nothing lost, but the app can finally explain itself; operator: a pause with a cause and an end time | A forced pause on Devnet 2 (one slice over a third stopped): `/api/live.finality` carries `reason`, `held_by`, `provisional`; `/live` reads "finality paused since 18:40Z: 89% of the sliding weight is signing, held by the table frozen at lock 6842 (57% signing) until DAA 216,402 (about 20:40Z)"; the exchange guidance in spec 3.9 carries the provisional row (lane 3 proposal 4) |
|
||||
| 2 | Q2 | Ember never says "paused". The engine keeps only `last_lock`, `last_lock_at`, `age_s`, `votes`; the node line showed "#6842 · 1 h ago" under "a point the miners agreed can never be undone" for the whole two-hour pause. No `finality_active` anywhere in the app | `app/igneum-app/src/state.rs:247-248`, `src/engine.rs:3495-3497, 3896-3902` (lock parsed from the miner's `LOCK checkpoint` line only), `ui/app.js:1350-1351` | the project lead-visible | 3 | app owner (engine reads `getFinalityCheckpoints` or the miner's `FINALITY` line, spec 3.9 row; UI state and view test) | home miner and rig: the app tells them finality is paused and why, instead of a lock age that climbs; pool user: the same on the pool page later | Mock state with `finality_active:false, reason:"paused"` renders "Finality paused since 18:40Z, 89% of the 30-day weight signing, held by the frozen table until about 20:40Z" on the node line and in the pill; `view.test.mjs` case; seen on the Devnet 2 forced pause |
|
||||
| 3 | Q3 | A fresh machine's first 60 seconds start with a warning. macOS: ad hoc signature, no Developer ID, no notarisation; the engine strips `com.apple.quarantine` from its own bundle on start; the README's "Right-click > Open" bypass is gone on macOS 15 (approximate). Windows: installer and exes unsigned, SmartScreen "Windows protected your PC", then a UAC prompt for the firewall rule 20 to 50 s in before any screen explains it | `packaging/mac/build-dmg.sh:118-122`, `packaging/mac/README.md:51-53`, `app/igneum-app/src/main.rs:78`, `packaging/windows/README.md:76, 111`, `packaging/windows/build-installer.ps1:188`, `app/igneum-app/src/ota.rs:981-1015` | the project lead-visible | 6 (Developer ID signing plus `notarytool` and stapling in `build-dmg.sh` 3; Authenticode `signtool` step in `windows.yml` and `build-installer.ps1` 2; firewall step after `setup_done` with a sentence on the Cards screen 1), plus the project lead: an Apple Developer account and an OV or EV code-signing certificate (purchases, hours of the project lead's time, approximate) | app owner; the project lead (the certificates) | every new miner on every tier, Windows and macOS: Signal's and Tailscale's installers open with no warning (approximate); today ours open with two | Fresh macOS 15 VM: the DMG's app opens on double-click, `spctl -a -vv` says accepted and notarised; fresh Windows 11 VM: no SmartScreen interstitial, `signtool verify /pa` passes; the first UAC prompt appears after the Cards screen names it |
|
||||
| 4 | Q4 | Every update is "urgent" once an activation height is behind the node: `fork_is_close(Some(198000), 209000)` is true, so the manifest's stale `activation 198000` turned the 0.3.14 update into "the node is 0 blocks away. Installing now", stripped Later and skipped every safe-moment guard (the PC 1 install under a measurement job at 17:52:54Z). The same path has no finality input: an update applies through a pause | `app/igneum-app/src/manifest.rs:350-355` (`daa + 1800 >= h`), `:322-347` (`safe_to_apply`, no finality), `src/ota.rs:484`, `ui/app.js:217`, `docs/plans/release-0.3.14.md:79`, `release-0.3.15.md` section 6 | the project lead-visible | 3 (close means within 1,800 blocks ahead and not behind 1; the publisher drops a passed `activation_height` 0.5; `Moment.finality_paused` holds a non-urgent update 1.5) | app owner | home miner, rig: no surprise restart mid-measurement or mid-pause; operator: an activation that has passed is not an emergency | Unit tests: behind by any amount is not close; `publish-manifest.sh` refuses a passed height; a paused mock holds the update with the words "finality is paused; installing when it resumes"; the 0.3.16 manifest carries no stale height |
|
||||
| 5 | Q5 | The homepage says "final" while finality is paused, in a 90-word hero, under a share card that renders as a thumbnail. The chain scene takes `src.locked` and draws the dashed line labelled "final" at the newest locked block with no `finality.active` check (R4.6.3 was fixed on `/live` only); the hero is one 90-word paragraph with two bench deep links and "ships when the packaging row lands"; the miner section still says "a 24 GB NVIDIA card proves as well" while the hero and litepaper say 8 GB; home, litepaper, live and explorer share a 256 px `og-small.png` with `summary` cards | `site/index.html:810, 838` (final label), `:345` (hero), `:494` and `site/miner.html:7, 13, 21, 265, 382` (24 GB), `site/index.html:15-19` (OG) | the project lead-visible | 3 (final label 0.5, hero 1, 24 GB sentence 0.5, four 1200x630 cards 1) | site owner | every visitor; a holder or exchange reading "final" during a pause is the worst of them | No "final" label while `finality.active` is false (the `/live` rule); hero under 40 words with one link; one proving-tier sentence on every page; every page's shared card is 1200x630 |
|
||||
| 6 | Q6 | The hub shows stale data as live, said "active" for the first 20 unlocked checkpoints, says "paused" with no since or cause, and buried the pause under 401 miner_quiet and miner_back events. After the first load an API failure only changes the header to "offline: ..."; tiles, cards and "Refreshed" keep the old values. `finality_active` flips only after `presence_window` (20 on the devnet) indices without a lock, so 18:42 to 18:50Z read "active" in white with no lock forming. No `finality_paused` or `finality_resumed` event exists; `live_events` between 18:25Z and 21:30Z holds 203 `miner_quiet`, 198 `miner_back`, 55 `difficulty`, 30 `checkpoint_locked` (the last at 18:42:10Z) and no pause row. The checkpoint table also showed "% of active" above 100 (102.4 to 113.4 percent on indices 6900 to 6930) | `relay/ui.html:564` (stale), `:367-368` (tile), `relay/api/console.mjs:214`, `vendor/igneum-node-0310/consensus/src/processes/finality.rs:1794` and `vendor/igneum-node/consensus/core/src/finality.rs:63, 75` (`presence_window` 240 mainnet, 20 devnet), `tools/observer/observer.mjs:652` (the only finality event), `live_checkpoints.fraction_active` rows 6900 to 6930 | the project lead-visible | 4 (dim every panel with "last data N min ago" 1; amber on the first under-2/3 checkpoint 0.5; `finality_paused` and `finality_resumed` events, and collapse quiet/back pairs under 5 min 1.5; clamp or explain the active fraction 1) | fleet agent (hub), consensus-engineer (observer events, the fraction) | operator: the hub is the project lead's first screen; a holder reading the public API gets the same events | Cut the network: every hub panel dims within 15 s; a forced Devnet 2 pause turns the tile amber on the first checkpoint under two thirds, posts one `finality_paused` event with the cause and one `finality_resumed` with the duration; no fraction above 100 percent on any row for 24 h |
|
||||
| 7 | Q7 | Discord said nothing. The bot has no credentials file and its timer is not installed, so tonight's pause produced zero posts; had it been live, a condition already firing at the watcher's first look is marked `preexisting` and never opens an incident; the pulse hides the pause in its description with no colour or title change | `docs/community/discord-hooks.md:81-82`, `tools/community/discord-hooks.mjs:481-485`, `:252-255`, `:158`, `infra/build-server/discord-hooks/install.sh` | the project lead-visible | 3 (install and one live pulse 1; a pre-existing condition opens with "since at least <first look>" 1; paused pulse in a distinct colour with a title suffix 1) | miner-community-lead (community owner) | every Discord reader, which on launch day is every miner | `check` prints three "set"; one live pulse in #numbers; a fixture where the pause predates the first tick opens an incident; the paused pulse renders amber with "(finality paused)" in the title |
|
||||
| 1 | Q1 | The pause has no cause anywhere. The node reports `finality_reason` (`active`, `window filling, N of M`, `paused`) but not the frozen-table share that held tonight's pause; the observer drops even the reason; the API has no reason field; `/live` computes "N% of weight silent" from the sliding table, which read 11 percent silent at 20:05Z while finality was paused (held by the table frozen at lock 6842, 57.3 percent signing). Add `finality_reason`, `held_by` (frozen index, its signing share, its expiry DAA) and lane 3's `finality_provisional` end to end | `vendor/igneum-node-0310/consensus/src/processes/finality.rs:1794-1807` (reason exists, no frozen share), `tools/observer/observer.mjs:720` (copies `finalityActive` only), `site/api/live.mjs:114-122` (no reason), `site/live.html:520` (the silent percentage) | the founder-visible | 4 (node 1.5, observer and API 1, `/live` and `/api/stats` copy 1, spec 3.9 row 0.5) | consensus-engineer (node), site owner (observer, API, page) | holder, exchange: the one line that says whether a pause is a silent third, a split, or a table waiting to expire; miner: nothing lost, but the app can finally explain itself; operator: a pause with a cause and an end time | A forced pause on Devnet 2 (one slice over a third stopped): `/api/live.finality` carries `reason`, `held_by`, `provisional`; `/live` reads "finality paused since 18:40Z: 89% of the sliding weight is signing, held by the table frozen at lock 6842 (57% signing) until DAA 216,402 (about 20:40Z)"; the exchange guidance in spec 3.9 carries the provisional row (lane 3 proposal 4) |
|
||||
| 2 | Q2 | Ember never says "paused". The engine keeps only `last_lock`, `last_lock_at`, `age_s`, `votes`; the node line showed "#6842 · 1 h ago" under "a point the miners agreed can never be undone" for the whole two-hour pause. No `finality_active` anywhere in the app | `app/igneum-app/src/state.rs:247-248`, `src/engine.rs:3495-3497, 3896-3902` (lock parsed from the miner's `LOCK checkpoint` line only), `ui/app.js:1350-1351` | the founder-visible | 3 | app owner (engine reads `getFinalityCheckpoints` or the miner's `FINALITY` line, spec 3.9 row; UI state and view test) | home miner and rig: the app tells them finality is paused and why, instead of a lock age that climbs; pool user: the same on the pool page later | Mock state with `finality_active:false, reason:"paused"` renders "Finality paused since 18:40Z, 89% of the 30-day weight signing, held by the frozen table until about 20:40Z" on the node line and in the pill; `view.test.mjs` case; seen on the Devnet 2 forced pause |
|
||||
| 3 | Q3 | A fresh machine's first 60 seconds start with a warning. macOS: ad hoc signature, no Developer ID, no notarisation; the engine strips `com.apple.quarantine` from its own bundle on start; the README's "Right-click > Open" bypass is gone on macOS 15 (approximate). Windows: installer and exes unsigned, SmartScreen "Windows protected your PC", then a UAC prompt for the firewall rule 20 to 50 s in before any screen explains it | `packaging/mac/build-dmg.sh:118-122`, `packaging/mac/README.md:51-53`, `app/igneum-app/src/main.rs:78`, `packaging/windows/README.md:76, 111`, `packaging/windows/build-installer.ps1:188`, `app/igneum-app/src/ota.rs:981-1015` | the founder-visible | 6 (Developer ID signing plus `notarytool` and stapling in `build-dmg.sh` 3; Authenticode `signtool` step in `windows.yml` and `build-installer.ps1` 2; firewall step after `setup_done` with a sentence on the Cards screen 1), plus the founder: an Apple Developer account and an OV or EV code-signing certificate (purchases, hours of the founder's time, approximate) | app owner; the founder (the certificates) | every new miner on every tier, Windows and macOS: Signal's and Tailscale's installers open with no warning (approximate); today ours open with two | Fresh macOS 15 VM: the DMG's app opens on double-click, `spctl -a -vv` says accepted and notarised; fresh Windows 11 VM: no SmartScreen interstitial, `signtool verify /pa` passes; the first UAC prompt appears after the Cards screen names it |
|
||||
| 4 | Q4 | Every update is "urgent" once an activation height is behind the node: `fork_is_close(Some(198000), 209000)` is true, so the manifest's stale `activation 198000` turned the 0.3.14 update into "the node is 0 blocks away. Installing now", stripped Later and skipped every safe-moment guard (the PC 1 install under a measurement job at 17:52:54Z). The same path has no finality input: an update applies through a pause | `app/igneum-app/src/manifest.rs:350-355` (`daa + 1800 >= h`), `:322-347` (`safe_to_apply`, no finality), `src/ota.rs:484`, `ui/app.js:217`, `docs/plans/release-0.3.14.md:79`, `release-0.3.15.md` section 6 | the founder-visible | 3 (close means within 1,800 blocks ahead and not behind 1; the publisher drops a passed `activation_height` 0.5; `Moment.finality_paused` holds a non-urgent update 1.5) | app owner | home miner, rig: no surprise restart mid-measurement or mid-pause; operator: an activation that has passed is not an emergency | Unit tests: behind by any amount is not close; `publish-manifest.sh` refuses a passed height; a paused mock holds the update with the words "finality is paused; installing when it resumes"; the 0.3.16 manifest carries no stale height |
|
||||
| 5 | Q5 | The homepage says "final" while finality is paused, in a 90-word hero, under a share card that renders as a thumbnail. The chain scene takes `src.locked` and draws the dashed line labelled "final" at the newest locked block with no `finality.active` check (R4.6.3 was fixed on `/live` only); the hero is one 90-word paragraph with two bench deep links and "ships when the packaging row lands"; the miner section still says "a 24 GB NVIDIA card proves as well" while the hero and litepaper say 8 GB; home, litepaper, live and explorer share a 256 px `og-small.png` with `summary` cards | `site/index.html:810, 838` (final label), `:345` (hero), `:494` and `site/miner.html:7, 13, 21, 265, 382` (24 GB), `site/index.html:15-19` (OG) | the founder-visible | 3 (final label 0.5, hero 1, 24 GB sentence 0.5, four 1200x630 cards 1) | site owner | every visitor; a holder or exchange reading "final" during a pause is the worst of them | No "final" label while `finality.active` is false (the `/live` rule); hero under 40 words with one link; one proving-tier sentence on every page; every page's shared card is 1200x630 |
|
||||
| 6 | Q6 | The hub shows stale data as live, said "active" for the first 20 unlocked checkpoints, says "paused" with no since or cause, and buried the pause under 401 miner_quiet and miner_back events. After the first load an API failure only changes the header to "offline: ..."; tiles, cards and "Refreshed" keep the old values. `finality_active` flips only after `presence_window` (20 on the devnet) indices without a lock, so 18:42 to 18:50Z read "active" in white with no lock forming. No `finality_paused` or `finality_resumed` event exists; `live_events` between 18:25Z and 21:30Z holds 203 `miner_quiet`, 198 `miner_back`, 55 `difficulty`, 30 `checkpoint_locked` (the last at 18:42:10Z) and no pause row. The checkpoint table also showed "% of active" above 100 (102.4 to 113.4 percent on indices 6900 to 6930) | `relay/ui.html:564` (stale), `:367-368` (tile), `relay/api/console.mjs:214`, `vendor/igneum-node-0310/consensus/src/processes/finality.rs:1794` and `vendor/igneum-node/consensus/core/src/finality.rs:63, 75` (`presence_window` 240 mainnet, 20 devnet), `tools/observer/observer.mjs:652` (the only finality event), `live_checkpoints.fraction_active` rows 6900 to 6930 | the founder-visible | 4 (dim every panel with "last data N min ago" 1; amber on the first under-2/3 checkpoint 0.5; `finality_paused` and `finality_resumed` events, and collapse quiet/back pairs under 5 min 1.5; clamp or explain the active fraction 1) | fleet agent (hub), consensus-engineer (observer events, the fraction) | operator: the hub is the founder's first screen; a holder reading the public API gets the same events | Cut the network: every hub panel dims within 15 s; a forced Devnet 2 pause turns the tile amber on the first checkpoint under two thirds, posts one `finality_paused` event with the cause and one `finality_resumed` with the duration; no fraction above 100 percent on any row for 24 h |
|
||||
| 7 | Q7 | Discord said nothing. The bot has no credentials file and its timer is not installed, so tonight's pause produced zero posts; had it been live, a condition already firing at the watcher's first look is marked `preexisting` and never opens an incident; the pulse hides the pause in its description with no colour or title change | `docs/community/discord-hooks.md:81-82`, `tools/community/discord-hooks.mjs:481-485`, `:252-255`, `:158`, `infra/build-server/discord-hooks/install.sh` | the founder-visible | 3 (install and one live pulse 1; a pre-existing condition opens with "since at least <first look>" 1; paused pulse in a distinct colour with a title suffix 1) | miner-community-lead (community owner) | every Discord reader, which on launch day is every miner | `check` prints three "set"; one live pulse in #numbers; a fixture where the pause predates the first tick opens an incident; the paused pulse renders amber with "(finality paused)" in the title |
|
||||
| 8 | Q8 | The relay's security fixes are not on master. Commit 28c028b (X23 to X28: `relay/lib/guard.mjs`, `handler.mjs`, run signatures, retention) is on `fud-close` and the `ledger-*` branches only; `git merge-base --is-ancestor 28c028b master` is false. On this tree any of the three intake keys (one ships in every miner app) can post, sync and delete console items, read the whole feed, and every client puts the token in the URL path | `relay/api/console.mjs:249, 283-301`, `relay/lib/relay.mjs:34-46`, `relay/clients/agent.sh:10`, `igneum-agent.ps1:13, 72, 154`, `tools/relay.mjs:24` | operator-visible (security) | 2 (merge or cherry-pick with the 47 relay tests 1; handler test that an intake key gets 403 on post, sync, delete 1) | fleet agent (relay owner) | operator: the console is the control plane for every PC and the fleet; a miner app's intake key is in every install | `28c028b` is an ancestor of the deploying branch; 47 relay tests pass; the handler test above passes; `relay/README.md` names the deployed commit |
|
||||
| 9 | Q86 | The fleet page is blind to the standing fleet, to death and to finality. `page.py:43-47` publishes `standing` and `devnet2` and the page references neither (grep 0); a dead box reads "running" for up to 20 minutes because state comes from `boxes.json` and `standing.jsonl` is never read; no fleet or console script reads `finality_active`, so tonight's pause was found by hand. The night the project lead ruled that 22 boxes stay up permanently, the page that shows them cannot show them | `igneum-wt-gpu-fleet/tools/fleet/page.py:38-47`, dlsite `index.html:243`, `lib/standing.py:54-56`, `tools/console.mjs:124` | the project lead-visible | 6 (standing block with USD per day and the Devnet 2 gate line 2; "unreachable since HH:MM" within 2 minutes 2; finality on the page and in `console.mjs chain` 2) | fleet agent | operator (the project lead reads this page every evening); every tier indirectly: a dead standing box is weight that left silently, the class of tonight's pause | the page shows the standing count and spend; a box killed by hand reads "unreachable since" within 2 minutes; a forced Devnet 2 pause reads on the page and in the console |
|
||||
| 10 | Q9 | The wallet page describes 0.1.4 while UI 3 (five state words, light mode, pounds line) sits unmerged on `wallet-ui-3`; the MetaMask guide's testnet RPC is still labelled a placeholder, its devnet RPC port is the miner's node (26790) while a wallet-only Mac runs 26800, and `wallet_addEthereumChain` carries `blockExplorerUrls: []` and no `iconUrls`, so MetaMask shows no explorer link and a blank icon | `site/wallet.html:261-266, 312`, `igneum-wt-wallet-ui/docs/plans/wallet-ui-3.md:93, 112`, `site/metamask.html:197, 225, 233, 285-286`, `igneum-wt-wallet/app/igneum-wallet/src/node.rs:24-26` | the project lead-visible | 6 (wallet 0.1.5 with UI 3 published and the page rewritten 4; guide: both ports, the placeholder line removed, explorer URL and icon in the request 2) | app owner (wallet), site owner (guide) | holder: the first non-miner product; a wrong port or a placeholder RPC is a dead end at the first step | `downloads.json` wallet-mac 0.1.5; the page names pending, included, executed, proven, finalised; `eth_chainId` returns 0x116e from the guide's URL; MetaMask shows the explorer link after the add-chain button |
|
||||
| 9 | Q86 | The fleet page is blind to the standing fleet, to death and to finality. `page.py:43-47` publishes `standing` and `devnet2` and the page references neither (grep 0); a dead box reads "running" for up to 20 minutes because state comes from `boxes.json` and `standing.jsonl` is never read; no fleet or console script reads `finality_active`, so tonight's pause was found by hand. The night the founder ruled that 22 boxes stay up permanently, the page that shows them cannot show them | `igneum-wt-gpu-fleet/tools/fleet/page.py:38-47`, dlsite `index.html:243`, `lib/standing.py:54-56`, `tools/console.mjs:124` | the founder-visible | 6 (standing block with USD per day and the Devnet 2 gate line 2; "unreachable since HH:MM" within 2 minutes 2; finality on the page and in `console.mjs chain` 2) | fleet agent | operator (the founder reads this page every evening); every tier indirectly: a dead standing box is weight that left silently, the class of tonight's pause | the page shows the standing count and spend; a box killed by hand reads "unreachable since" within 2 minutes; a forced Devnet 2 pause reads on the page and in the console |
|
||||
| 10 | Q9 | The wallet page describes 0.1.4 while UI 3 (five state words, light mode, pounds line) sits unmerged on `wallet-ui-3`; the MetaMask guide's testnet RPC is still labelled a placeholder, its devnet RPC port is the miner's node (26790) while a wallet-only Mac runs 26800, and `wallet_addEthereumChain` carries `blockExplorerUrls: []` and no `iconUrls`, so MetaMask shows no explorer link and a blank icon | `site/wallet.html:261-266, 312`, `igneum-wt-wallet-ui/docs/plans/wallet-ui-3.md:93, 112`, `site/metamask.html:197, 225, 233, 285-286`, `igneum-wt-wallet/app/igneum-wallet/src/node.rs:24-26` | the founder-visible | 6 (wallet 0.1.5 with UI 3 published and the page rewritten 4; guide: both ports, the placeholder line removed, explorer URL and icon in the request 2) | app owner (wallet), site owner (guide) | holder: the first non-miner product; a wrong port or a placeholder RPC is a dead end at the first step | `downloads.json` wallet-mac 0.1.5; the page names pending, included, executed, proven, finalised; `eth_chainId` returns 0x116e from the guide's URL; MetaMask shows the explorer link after the add-chain button |
|
||||
|
||||
Next in line, outside the ten: Q10 (the explorer knows nothing about finality and swallows failures after first load, 3 hours), Q80 (the Windows installer pipeline is dead on GitHub billing) and Q12 (Ember's light mode fails contrast on the private key and every live state).
|
||||
|
||||
Hours for the ten: 40 agent hours, plus the project lead's certificate purchases for Q3.
|
||||
Hours for the ten: 40 agent hours, plus the founder's certificate purchases for Q3.
|
||||
|
||||
## 2. Tonight's pause on every surface (the ledger row the project lead asked for)
|
||||
## 2. Tonight's pause on every surface (the ledger row the founder asked for)
|
||||
|
||||
Times UTC. The chain-side facts are lane 3's (`finality-and-weight.md` 3.1) and the observer's own rows, read tonight: last lock 6842 at about 18:39:40Z; 6843 proposed at 53.1 percent of total; `finality_active` false from about 18:50Z (index 6862, twenty indices without a lock, `presence_window` 20); no lock after 6842 as of 20:05:03Z (`live_state.updated_at`), `total_weight` 7,167, `active_weight` 6,346 (88.5 percent signing on the sliding table), `voters` 85, and no `finality_reason` key in the stored JSON. Sampled `live_checkpoints` rows:
|
||||
|
||||
|
|
@ -82,20 +82,20 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
|
||||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q2 | Finality pause invisible (section 1) | `state.rs:247`, `engine.rs:3495`, `app.js:1350` | the project lead-visible | 3 | app owner | section 1 |
|
||||
| Q4 | Every update urgent once the activation is behind; no finality hold (section 1) | `manifest.rs:322-355` | the project lead-visible | 3 | app owner | section 1 |
|
||||
| Q2 | Finality pause invisible (section 1) | `state.rs:247`, `engine.rs:3495`, `app.js:1350` | the founder-visible | 3 | app owner | section 1 |
|
||||
| Q4 | Every update urgent once the activation is behind; no finality hold (section 1) | `manifest.rs:322-355` | the founder-visible | 3 | app owner | section 1 |
|
||||
| Q11 | Offline start says "The update failed." A check error with no held manifest calls `set_error`; the cached manifest is loaded for the floor but never into `self.manifest`; the notice offers "Try again", which POSTs install | `ota.rs:649-654, 195-200`, `app.js:29, 1198` | user-visible | 1 | app owner | notices test: a check-class error renders "Could not check for updates" with no install action |
|
||||
| Q12 | Light mode fails contrast on every live text: molten `#B8731F` on white 3.81:1, on bone 3.38:1; ember `#E04A14` on bone 3.61:1; molten carries the private key, the address and the live states. `miner-ui-3.md` section 9 claims 4.5:1 everywhere | `app.css:29, 263, 338, 431` | user-visible | 1 | app owner | a node script over the token pairs asserts 4.5:1 for every text token in both schemes; CI runs it |
|
||||
| Q13 | Per-card rejects and faults never reach the row (the lolMiner line) | `app.js:291-309, 1290` | the project lead-visible on PC 1 | 2 | miner-community-lead | row meta "N rejected · M faults" when nonzero; view test |
|
||||
| Q13 | Per-card rejects and faults never reach the row (the lolMiner line) | `app.js:291-309, 1290` | the founder-visible on PC 1 | 2 | miner-community-lead | row meta "N rejected · M faults" when nonzero; view test |
|
||||
| Q14 | Windows first run raises a UAC prompt (firewall rule) before any screen explains it (part of Q3) | `ota.rs:981-1015`, `index.html:71-99` | user-visible | 1 | app owner | the firewall step runs after `setup_done`; the Cards screen names it |
|
||||
| Q15 | Mac first-run instruction stale: "Right-click > Open" (part of Q3) | `packaging/mac/README.md:51`, `site/miner.html` download copy | the project lead-visible on a fresh Mac | 1 | app owner | the download page and README name the Privacy and Security step until the certificate lands |
|
||||
| Q15 | Mac first-run instruction stale: "Right-click > Open" (part of Q3) | `packaging/mac/README.md:51`, `site/miner.html` download copy | the founder-visible on a fresh Mac | 1 | app owner | the download page and README name the Privacy and Security step until the certificate lands |
|
||||
| Q16 | No rate history: a 10-minute strip against HiveOS's hours | `app.js:1052-1127` | user-visible | 4 | app owner | one-hour per-card sparkline from an engine ring buffer; view test |
|
||||
| Q17 | Hill climb hidden until `tune_climb` is on the state | `index.html:341`, `app.js:1407` | operator-visible | 1 | app owner | the row shows whenever the engine answers `tune/goal` |
|
||||
| Q18 | Earnings never shows mined IGN; "£0.00 earned" is the first number on the tab | `index.html:250`, `app.js:1364` | user-visible | 2 | miner-community-lead | the tab shows blocks mined and the subsidy they earned in IGN, with the devnet line under it |
|
||||
| Q19 | 10 px type in five places, 9 px ruler | `app.css:196, 271, 272, 302, 491, 531` | cosmetic | 1 | app owner | no `font-size` under 11 px except the ruler |
|
||||
| Q20 | Design screens in `docs/design/app-screens/*.png` are a UI 1 app (v0.3.0 tiles, a Finality card the shipped UI lacks) | `docs/design/app-screens/` | cosmetic | 1 | app owner | screens regenerated from `?screen=` on the current build |
|
||||
| Q21 | AMD step line prints a percent as watts ("owed: a unit word for AMD") | `ember-tune.md:278` | operator-visible | 1 | miner-community-lead | the line reads "70% (an offset)"; unit test |
|
||||
| Q22 | A code comment naming the founder ships in the UI bundle (`// The list is ordered by performance (the project lead, 6 October 2026)`), and the ui bundle is outside every forbidden-string check | `app/igneum-app/ui/app.js:270`, `tools/ci/identity-check.sh` | cosmetic (identity rule) | 0.5 | app owner | `tools/ci` forbidden-string check covers `app/igneum-app/ui/`; the comment reads "(ruling of 6 October 2026)" |
|
||||
| Q22 | A code comment naming the founder ships in the UI bundle (`// The list is ordered by performance (the founder, 6 October 2026)`), and the ui bundle is outside every forbidden-string check | `app/igneum-app/ui/app.js:270`, `tools/ci/identity-check.sh` | cosmetic (identity rule) | 0.5 | app owner | `tools/ci` forbidden-string check covers `app/igneum-app/ui/`; the comment reads "(ruling of 6 October 2026)" |
|
||||
| Q23 | Two copy-law slips: "Votes lock the chain; leave it on." (aphorism), "The window can close. The miner keeps going" (two-beat) | `index.html:404, 81` | cosmetic | 0.5 | app owner | reworded; the grep below stays at 0 em dashes |
|
||||
|
||||
**Error states, exact strings.** Engine down (four failed polls): pill "engine away" (`app.js:1437`); node line "Node: no answer", sub "the engine is not answering; the window reconnects by itself"; Mac host "The engine stopped. Quit and open Igneum Miner again." (`IgneumMiner.swift:233`); Windows "The engine stopped. Close this window and open Igneum Miner again." (`host.cpp:301`). Node down: "the node could not start" or the engine message, "the node is not running", "the external node went away" (`app.js:452-453`, `engine.rs:3163`); pill "node failed" (`app.js:1428`); digest box "the node is not running" (`app.js:1341`); canvas "waiting for the node to sync" (`app.js:1099`). Finality paused: nothing (Q2). Update server unreachable: "The update failed. Manifest signature: <curl error>." (`app.js:1360`, Q11). GPU lost: "Card removed: <name>. Its worker stopped." (`app.js:95`), row word "removed", sub "unplugged; its worker stopped. The row goes in five minutes." (`app.js:303`); Code 43: "<name>: not usable (Code 43). No worker runs on it." with "reboot with the card attached; if it persists, reinstall the driver with the card attached" (`app.js:100`, `detect.rs:55`).
|
||||
|
|
@ -123,10 +123,10 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
|
||||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q9 | Page vs UI 3; guide placeholders; empty explorer URL (section 1) | `site/wallet.html`, `site/metamask.html` | the project lead-visible | 6 | app owner, site owner | section 1 |
|
||||
| Q9 | Page vs UI 3; guide placeholders; empty explorer URL (section 1) | `site/wallet.html`, `site/metamask.html` | the founder-visible | 6 | app owner, site owner | section 1 |
|
||||
| Q30 | Private key export copies to the clipboard with no clear and no timer | `igneum-wt-wallet/.../ui/app.js:129, 463` | user-visible | 2 | app owner | clipboard cleared after 60 s by the host; unit test on the timer |
|
||||
| Q31 | Wallet OTA trusts one key; no `revoked_keys`, unlike the miner's updater | `docs/plans/consequences-2026-10-05.md:36`, `updater.rs:7, 729` | operator-visible | 3 | app owner | updater carries `OTA_PUBLIC_KEYS [K1, K2]` and honours `revoked_keys`; the three-key test of the rig installer |
|
||||
| Q32 | No hardware wallet path despite spec 8.5 "MUST offer" | `docs/spec/08-client-security.md:36` | the project lead-visible | 24, or 0.5 to relabel | app owner (cryptographer reviews) | a Ledger signs one devnet transfer through the Ethereum app at chain id 4463; or the spec row reads "Designed, not shipped" |
|
||||
| Q32 | No hardware wallet path despite spec 8.5 "MUST offer" | `docs/spec/08-client-security.md:36` | the founder-visible | 24, or 0.5 to relabel | app owner (cryptographer reviews) | a Ledger signs one devnet transfer through the Ethereum app at chain id 4463; or the spec row reads "Designed, not shipped" |
|
||||
| Q33 | Single account, no second address, no address book | `engine.rs:343`, `ui/index.html:177` | user-visible | 6 | app owner | two derived accounts, a saved recipient reused in Send |
|
||||
| Q34 | `confirm()` on Remove wallet never renders in the Mac host | `app.js:598`, `wallet-ui-3-audit.md:189` | user-visible | 1 | app owner | in-page two-step card; snapshot test |
|
||||
| Q35 | Finality pause: node card "paused" or "not checkpoint-checkable without a node", rows stay "in block N"; public-RPC mode never says what to do | wallet `app.js:185, 321, 340` | user-visible | 2 | app owner | the row reads "in block N; finality is paused on the network" and the public-RPC line names the fix with a button |
|
||||
|
|
@ -157,11 +157,11 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
|
||||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q6 | Stale shown as live; "active" for 20 unlocked indices; "paused" with no since or cause; event flood (section 1) | `relay/ui.html:564, 367-368` | the project lead-visible | 4 | fleet agent, consensus-engineer | section 1 |
|
||||
| Q6 | Stale shown as live; "active" for 20 unlocked indices; "paused" with no since or cause; event flood (section 1) | `relay/ui.html:564, 367-368` | the founder-visible | 4 | fleet agent, consensus-engineer | section 1 |
|
||||
| Q8 | X23 to X28 fixes off master; intake key can write and delete; token in URL (section 1) | `relay/api/console.mjs:249`, `relay/lib/relay.mjs:44` | operator-visible | 2 | fleet agent | section 1 |
|
||||
| Q40 | A hung job reads "running" forever: no elapsed time, no timeout, no "last line N min ago" | `relay/api/console.mjs:182-187`, `relay/ui.html:317` | the project lead-visible | 2 | fleet agent | a killed job reads "no report for 12 min" in red within one refresh |
|
||||
| Q40 | A hung job reads "running" forever: no elapsed time, no timeout, no "last line N min ago" | `relay/api/console.mjs:182-187`, `relay/ui.html:317` | the founder-visible | 2 | fleet agent | a killed job reads "no report for 12 min" in red within one refresh |
|
||||
| Q41 | Jobs tab trusts the unsigned `igneum-jobs.json` while the apps verify the signed file | `relay/api/console.mjs:170` vs `tools/jobs.mjs:57-60` | operator-visible | 1.5 | fleet agent | the tab shows the envelope's signature state per file |
|
||||
| Q42 | Job result modal: no error lines first, no duration, no anchors (the Actions view) | `relay/ui.html:319`, `console.mjs:184-187` | the project lead-visible | 3 | fleet agent | a failed run opens with its five error lines and its duration first |
|
||||
| Q42 | Job result modal: no error lines first, no duration, no anchors (the Actions view) | `relay/ui.html:319`, `console.mjs:184-187` | the founder-visible | 3 | fleet agent | a failed run opens with its five error lines and its duration first |
|
||||
| Q43 | Machines: no per-machine key state, no revoke, roles never enforced (the Tailscale view) | `relay/lib/relay.mjs:14`, `relay/api/relay.mjs:191-195` | operator-visible | 3 (after Q8) | fleet agent | a revoked PC's register is 403 and its card says "key revoked" |
|
||||
| Q44 | Builds: no rollback, no manifest history (the Vercel view) | `relay/ui.html:328-341` | operator-visible | 4 | fleet agent | one tap republishes the previous manifest and the fleet's OTA state shows it |
|
||||
| Q45 | "live feed unreachable: live feed unreachable" doubled; the whole Chain tab empties, losing Events and the infra card | `relay/api/console.mjs:210`, `relay/ui.html:357` | cosmetic | 0.5 | fleet agent | live feed down: tiles grey, Events and infra card still render |
|
||||
|
|
@ -200,7 +200,7 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
|
||||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q5 | "final" during a pause; 90-word hero; 24 GB contradiction; thumbnail OG (section 1) | `index.html:345, 494, 810, 838, 15-19` | the project lead-visible | 3 | site owner | section 1 |
|
||||
| Q5 | "final" during a pause; 90-word hero; 24 GB contradiction; thumbnail OG (section 1) | `index.html:345, 494, 810, 838, 15-19` | the founder-visible | 3 | site owner | section 1 |
|
||||
| Q50 | No downloads page: hashes only for HiveOS, no signing key, no verify line, the Linux button goes to an anchor | `index.html:363-365, 516`, `miner.html:549-558` | user-visible | 2 | site owner | `/download` lists every artefact with version, size, sha256, the OTA key fingerprint and a verify command per OS; the Linux button links the file |
|
||||
| Q51 | `/miners` has 6 rows, two card models, "not measured" MH/W on every row; the eleven-card fleet table is not ingested | `miners.html:183`, `miner-bench.json` | user-visible | 2 | miner-community-lead | rows carry W and MH/W for every measured card |
|
||||
| Q52 | `dl\.igneum` in `forbidden-strings.txt` matches the public download host on three built pages; the scrub guards only bench and miners | `forbidden-strings.txt:25`, `build.mjs:171, 401` | operator-visible | 0.5 | site owner | the pattern becomes `dl\.igneum\.network/dl/(?!public/)` or `/dl/[0-9a-f]{12,}`, and the check runs on every built page |
|
||||
|
|
@ -210,10 +210,10 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
| Q56 | Light-section contrast fails (3.08:1 links, 3.97:1 eyebrow) | `index.html:119-120, 130` | cosmetic | 0.5 | site owner | AA on every token pair; the same node script as Q12 |
|
||||
| Q57 | "devnet v0" eyebrow on the live page; the chain is v4 | `live.html:219` | cosmetic | 0.1 | site owner | matches the app's network word |
|
||||
| Q58 | Heading order (h3 before the first h2) | `index.html:359` | cosmetic | 0.2 | site owner | h2 or a styled div |
|
||||
| Q59 | No team, custody or key-powers page (Reddit round 4 artefact 8); "0 admin keys in consensus" tile unchanged | `index.html:611`; no file | user-visible | 1 (plus the project lead's policy call) | site owner | the key-powers table published; the tile links it |
|
||||
| Q60 | Roadmap dates versus the testnet: the journey says "Public testnet, Aug to Oct 2027" and the litepaper "Pools and the public testnet are August 2027", while `docs/plans/testnet-go.md` has `igneum-testnet-1` seeds up and a go checklist dated 5 October 2026 | `index.html:679`, `litepaper.html:719`, `docs/plans/testnet-go.md:1-4` | the project lead-visible | 0.5 (after the project lead decides which is true) | site owner | one date for the public testnet on the journey, the litepaper and the download notice |
|
||||
| Q59 | No team, custody or key-powers page (Reddit round 4 artefact 8); "0 admin keys in consensus" tile unchanged | `index.html:611`; no file | user-visible | 1 (plus the founder's policy call) | site owner | the key-powers table published; the tile links it |
|
||||
| Q60 | Roadmap dates versus the testnet: the journey says "Public testnet, Aug to Oct 2027" and the litepaper "Pools and the public testnet are August 2027", while `docs/plans/testnet-go.md` has `igneum-testnet-1` seeds up and a go checklist dated 5 October 2026 | `index.html:679`, `litepaper.html:719`, `docs/plans/testnet-go.md:1-4` | the founder-visible | 0.5 (after the founder decides which is true) | site owner | one date for the public testnet on the journey, the litepaper and the download notice |
|
||||
| Q61 | No Content-Security-Policy header on the site (the relay has none either); inline scripts throughout, two pinned CDN modules on the homepage | `site/vercel.json:7`, `relay/vercel.json:31-43`, `verify/verify.js:5-6` | operator-visible (security) | 2 | site owner | a CSP with hashes or nonces for the inline scripts and `script-src` limited to self and cdn.jsdelivr; every page renders with no console violation |
|
||||
| Q62 | Copy-law borderline headlines: "Mined by GPUs. Proven by fire." (the brand line, the project lead's call), "GPUs are back · for good", "Last hour's chip is already obsolete.", "Your coins. Final means final.", "Dates slip. Gates do not.", "Install. Start. The card mines and proves.", "Nothing is mined here." | `index.html:343, 344, 424`, `wallet.html` h1, `litepaper.html:678`, `miner.html` h1, `404.html` h1 | cosmetic | 1 | site owner (the project lead rules on the brand line) | each either kept by the project lead's word or reworded |
|
||||
| Q62 | Copy-law borderline headlines: "Mined by GPUs. Proven by fire." (the brand line, the founder's call), "GPUs are back · for good", "Last hour's chip is already obsolete.", "Your coins. Final means final.", "Dates slip. Gates do not.", "Install. Start. The card mines and proves.", "Nothing is mined here." | `index.html:343, 344, 424`, `wallet.html` h1, `litepaper.html:678`, `miner.html` h1, `404.html` h1 | cosmetic | 1 | site owner (the founder rules on the brand line) | each either kept by the founder's word or reworded |
|
||||
|
||||
**Reddit round 4, still open in the HTML.** Finding 6 (24 GB): half fixed (Q5). Finding 7 (eleven-card table): open (Q51). Finding 8 (admin keys): sentence added to the litepaper (`:659`), tile unchanged, no table (Q59). Finding 15 ("Monero's idea, finished for GPUs"): open (`index.html:444`, `litepaper.html:429`). Finding 16 ("devnet v0"): open (Q57). Finding 22: `/ledger` present, no nav item. Findings 2, 3, 5, 9, 10, 12, 13, 17, 19: fixed in the current files. "0% anyone else in the protocol" legend still live (`index.html:604`).
|
||||
|
||||
|
|
@ -266,8 +266,8 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q67 | Member transport is plaintext TCP against spec 9.3's TLS 1.3 with session binding; `binding` ignored | `server.rs:1-2, 115`, `protocol.rs:58-60` | user-visible (hijack risk) | 8 | consensus-engineer | rustls listener; a replayed `authorize` on a second connection is refused (O-9.7) |
|
||||
| Q68 | Node down shows "difficulty 0, DAA 0" and a ramp-day-0 reward; no "node unreachable" state | `node.rs:350-368`, `web/index.html:163-164` | the project lead-visible (once deployed) | 2 | miner-community-lead | the page renders "Node unreachable since <time>" against a stopped node |
|
||||
| Q69 | Raw integers (DAA, block count, shares) with no separators; difficulty uses `toLocaleString()` with no locale, so it varies by browser; hash rate 2 decimals against the site's 1 | `web/index.html:152, 163, 172, 190` | the project lead-visible | 1 | miner-community-lead | every number formatted as section 4.3 says |
|
||||
| Q68 | Node down shows "difficulty 0, DAA 0" and a ramp-day-0 reward; no "node unreachable" state | `node.rs:350-368`, `web/index.html:163-164` | the founder-visible (once deployed) | 2 | miner-community-lead | the page renders "Node unreachable since <time>" against a stopped node |
|
||||
| Q69 | Raw integers (DAA, block count, shares) with no separators; difficulty uses `toLocaleString()` with no locale, so it varies by browser; hash rate 2 decimals against the site's 1 | `web/index.html:152, 163, 172, 190` | the founder-visible | 1 | miner-community-lead | every number formatted as section 4.3 says |
|
||||
| Q70 | Ledger is a JSON file rewritten every 15 s; hash-rate samples and check cost not persisted, so a restart zeroes every rate tile and the 24-hour luck | `state.rs:704-710`, `main.rs:131-144` | user-visible | 4 | miner-community-lead | restart test: tiles recover within one sample window; README names the loss window |
|
||||
| Q71 | Address lookup never shows the payment history the API returns | `api.rs:148`, `web/index.html:181-194` | user-visible | 1 | miner-community-lead | payments table under the lookup |
|
||||
| Q72 | No per-miner history, no charts, no worker-offline notice, no `/metrics`; `/health` always ok | `state.rs:779-781`, `web/index.html:187`, `main.rs:152-174`, `api.rs:195` | user-visible, operator-visible | 4 + 4 + 2 + 1 | miner-community-lead | hourly buckets per address kept 7 days with a sparkline; opt-in webhook after 10 min silence; Prometheus text endpoint; health reflects `net.synced` and template age |
|
||||
|
|
@ -292,7 +292,7 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
|
||||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q7 | Bot not live; pre-existing never opens; pulse hides the pause (section 1) | `discord-hooks.mjs:481-485, 252-255, 158` | the project lead-visible | 3 | miner-community-lead | section 1 |
|
||||
| Q7 | Bot not live; pre-existing never opens; pulse hides the pause (section 1) | `discord-hooks.mjs:481-485, 252-255, 158` | the founder-visible | 3 | miner-community-lead | section 1 |
|
||||
| Q74 | No block-production stall condition, the actual first signal of tonight's 18:30Z gap | `:437-472`, `fixtures/discord/live.json` | user-visible | 2 | miner-community-lead | `blocks_stalled` condition, 3 minutes, fixture test |
|
||||
| Q75 | Resolve posts a new message instead of editing the open one | `:706-712` | cosmetic | 2 | miner-community-lead | PATCH `/messages/<id>` with the resolve fields |
|
||||
| Q76 | Embeds link only `/live` and `/miner`; the last lock could link `/block/<hash>` | `:271, 297, 350` | cosmetic | 1 | miner-community-lead | last lock links its block page |
|
||||
|
|
@ -318,9 +318,9 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
|
||||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q86 | The fleet page is blind to the standing fleet, to death and to finality. `page.py:43-47` publishes `standing` and `devnet2`, and the page's `index.html` references neither (grep 0; it reads boxes, results, phases, night, log, `:243`); a dead box reads "running" for up to 20 minutes because state comes from `boxes.json` (`page.py:38`) and `standing.jsonl` is never read; no fleet or console script reads `finality_active` (only `bps-collect.py:30` tails "Finality:" log lines), so tonight's pause was found by hand (`CLAUDE.md`, the standing-fleet rule) | `page.py:38-47`, dlsite `index.html:243`, `lib/standing.py`, `tools/console.mjs:124` | the project lead-visible | 6 (standing block, USD per day, Devnet 2 height and last gate line 2; "unreachable since HH:MM" from `standing.jsonl` within 2 minutes 2; `getFinalityCheckpoints` in the standing check and "finality paused since, reason" on the page and the console 2) | fleet agent | the page shows the standing count and spend; a box killed by hand reads "unreachable since" within 2 minutes; a forced Devnet 2 pause reads on the page and in `console.mjs chain` |
|
||||
| Q87 | `rerent` does not set up or supervise the new box: the docstring promises both (`lib/standing.py:14-16`), the code rents and patches rows (`:78-91`); a re-rented card bills idle | `lib/standing.py:78-91` | the project lead-visible (spend) | 2 | fleet agent | the new label shows synced and mining on the page within the install time |
|
||||
| Q88 | One-shot boxes have no autostop; `cap_vast 1000` and `cap_runpod 500` enforce nothing (`page.py:45`; `vast.py:61-72` has no cap check) | `page.py:45`, `vast.py:61-72`, `autorun.py` | the project lead-visible (spend) | 1.5 | fleet agent | `autorun` destroys a one-shot box N minutes after its done line; `rent` refuses above the cap |
|
||||
| Q86 | The fleet page is blind to the standing fleet, to death and to finality. `page.py:43-47` publishes `standing` and `devnet2`, and the page's `index.html` references neither (grep 0; it reads boxes, results, phases, night, log, `:243`); a dead box reads "running" for up to 20 minutes because state comes from `boxes.json` (`page.py:38`) and `standing.jsonl` is never read; no fleet or console script reads `finality_active` (only `bps-collect.py:30` tails "Finality:" log lines), so tonight's pause was found by hand (`CLAUDE.md`, the standing-fleet rule) | `page.py:38-47`, dlsite `index.html:243`, `lib/standing.py`, `tools/console.mjs:124` | the founder-visible | 6 (standing block, USD per day, Devnet 2 height and last gate line 2; "unreachable since HH:MM" from `standing.jsonl` within 2 minutes 2; `getFinalityCheckpoints` in the standing check and "finality paused since, reason" on the page and the console 2) | fleet agent | the page shows the standing count and spend; a box killed by hand reads "unreachable since" within 2 minutes; a forced Devnet 2 pause reads on the page and in `console.mjs chain` |
|
||||
| Q87 | `rerent` does not set up or supervise the new box: the docstring promises both (`lib/standing.py:14-16`), the code rents and patches rows (`:78-91`); a re-rented card bills idle | `lib/standing.py:78-91` | the founder-visible (spend) | 2 | fleet agent | the new label shows synced and mining on the page within the install time |
|
||||
| Q88 | One-shot boxes have no autostop; `cap_vast 1000` and `cap_runpod 500` enforce nothing (`page.py:45`; `vast.py:61-72` has no cap check) | `page.py:45`, `vast.py:61-72`, `autorun.py` | the founder-visible (spend) | 1.5 | fleet agent | `autorun` destroys a one-shot box N minutes after its done line; `rent` refuses above the cap |
|
||||
| Q89 | Supervisor restart loop without backoff or a failure line | `box-standing.sh:46-49` | operator-visible | 1.5 | fleet agent | after N failures a `standing_node_failed` line and a page flag |
|
||||
| Q90 | Dropped miner and GPU facts: `standing.py:56` strips `miner=`; `gpu=` never parsed | `lib/standing.py:56`, `box-standing.sh:64` | operator-visible | 1 | fleet agent | MH/s, accepted and rejected, watts per box on the page (the HiveOS card) |
|
||||
| Q91 | A transient ssh drop counts as death: `Box.run` returns 124 on timeout (`lib/box.py:49`), `check_one` marks dead on any rc (`standing.py:54`), the loop never asks the provider (`fleet.py:48-60` `refresh_ssh` unused); Vast proxy drops are known (`canary.sh:41`) | `lib/box.py:49`, `lib/standing.py:54` | operator-visible | 1 | fleet agent | provider status consulted before a dead check counts |
|
||||
|
|
@ -355,7 +355,7 @@ The row for the ledger: **Q1 plus Q2, Q5, Q6, Q7, Q10**: every public and operat
|
|||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q96 | No log line on a finality flip: an operator tailing the log never sees the pause begin or end | `consensus/src/processes/finality.rs` (no pause line) | operator-visible | 1.5 | consensus-engineer | fast-time simnet prints `Finality: paused (<reason>)` and `Finality: resumed at index N`, one line per flip |
|
||||
| Q97 | `finality_reason` says `paused` and nothing else: no share that left, no frozen-table hold, no expiry, no conflict reason (O-3.17) (the node half of Q1) | `finality.rs:1794-1807` | the project lead-visible (through every surface) | 1.5 (counted in Q1) | consensus-engineer | tonight's pause reads "paused: 42.7 percent of weight left the window; held by the table frozen at lock 6842 until DAA 216,402" |
|
||||
| Q97 | `finality_reason` says `paused` and nothing else: no share that left, no frozen-table hold, no expiry, no conflict reason (O-3.17) (the node half of Q1) | `finality.rs:1794-1807` | the founder-visible (through every surface) | 1.5 (counted in Q1) | consensus-engineer | tonight's pause reads "paused: 42.7 percent of weight left the window; held by the table frozen at lock 6842 until DAA 216,402" |
|
||||
| Q98 | No `/metrics`: finality_active, latest lock, exec tip, blocked, paid segments, peers, DAA as Prometheus gauges (the axum listener exists) | `igneum/exec/src/rpc.rs` | operator-visible | 3 | execution-engineer | `curl :26790/metrics` scraped by a Grafana dashboard committed under `infra/` |
|
||||
| Q99 | Log level is start-only; no runtime change (monerod `set_log`, reth env filter) | `kaspad/src/args.rs:262-271` | operator-visible | 2 | consensus-engineer | an RPC or SIGHUP changes the level without a restart |
|
||||
| Q100 | Clock-skew field in `getBlockDagInfo` and the local-ahead mirror case still owed after X19 | `docs/plans/node-changes.md:18-19` | operator-visible | 2 (after the `ledger-fixes-0311` merge) | consensus-engineer | `faketime -60s` gives one WARN and the field |
|
||||
|
|
@ -395,8 +395,8 @@ So the trust today is one key, one builder (the box and the Mac, both the projec
|
|||
|
||||
| Id | Row | File or screen | Severity | Hours | Owner | Gate |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Q3 | Signing and notarisation; first-run prompts (section 1) | `build-dmg.sh:118-122`, `windows.yml` | the project lead-visible | 6 plus certificates | app owner, the project lead | section 1 |
|
||||
| Q80 | The Windows installer pipeline is dead: every GitHub-hosted job fails at start on billing; the installer and payload zip have no other builder, so 0.3.15 and every hotfix are Mac and HiveOS only until the project lead fixes Billing & plans, or the installer step moves to igneum-build-1 (Inno Setup under Wine, or a self-hosted Windows runner on PC 1) | `release-0.3.15.md` 6a, `.github/workflows/windows.yml`, `packaging/windows/build-installer.ps1` | the project lead-visible | 0 (the project lead: billing) or 4 (installer step on the box or PC 1 as a signed job) | app owner; the project lead | a green `windows.yml` run, or `tools/ship-app.mjs --dry-run` showing the fetch step satisfied from the new builder |
|
||||
| Q3 | Signing and notarisation; first-run prompts (section 1) | `build-dmg.sh:118-122`, `windows.yml` | the founder-visible | 6 plus certificates | app owner, the founder | section 1 |
|
||||
| Q80 | The Windows installer pipeline is dead: every GitHub-hosted job fails at start on billing; the installer and payload zip have no other builder, so 0.3.15 and every hotfix are Mac and HiveOS only until the founder fixes Billing & plans, or the installer step moves to igneum-build-1 (Inno Setup under Wine, or a self-hosted Windows runner on PC 1) | `release-0.3.15.md` 6a, `.github/workflows/windows.yml`, `packaging/windows/build-installer.ps1` | the founder-visible | 0 (the founder: billing) or 4 (installer step on the box or PC 1 as a signed job) | app owner; the founder | a green `windows.yml` run, or `tools/ship-app.mjs --dry-run` showing the fetch step satisfied from the new builder |
|
||||
| Q81 | The ship tool pushes master whatever `--branch` says (the 19:30Z push of the release tree to master) | `tools/ship-app.mjs` commit step | operator-visible | 1 | app owner | `--branch X` pushes X; a test on a scratch repo |
|
||||
| Q82 | The download page shows no hash for Windows and Mac, no OTA key fingerprint, no verify command; the stable aliases are not explained (Q50 covers the page; this row is the artefact side) | `miner.html:549-558`, `packaging/ota/publish-public.sh` | user-visible | 1 | site owner | `igneum-downloads.json` carries the fingerprint; the page prints it with `shasum -a 256` and `certutil -hashfile` lines |
|
||||
| Q83 | The update key is one software key on one Mac, not in hardware, against G7's "held in hardware and its policy published" | `packaging/ota/README.md` "Keys", `docs/fud-ledger.md` G7 | operator-visible (security) | 3 (a YubiKey or Secure Enclave signer behind `igneum-ota-sign`, the policy page) | cryptographer, app owner | a release signed with the hardware key installs; the key policy is a public page; the software seed is retired |
|
||||
|
|
@ -429,7 +429,7 @@ Forbidden strings (`site/forbidden-strings.txt`, 25 patterns) per shipped file,
|
|||
| `site/wallet.html` | `dl\.igneum` | 1 | the wallet alias (`:371`) |
|
||||
| `site/downloads.json` | `dl\.igneum` | 1 | the `base` field |
|
||||
| `relay/ui.html` | `Hetzner` | 1 | the "Hetzner network" card title (`:377`); private console, rule does not apply, but one word |
|
||||
| `app/igneum-app/ui/app.js` | `the project lead` | 1 | a code comment (`:270`); the ui bundle is outside every check (Q22) |
|
||||
| `app/igneum-app/ui/app.js` | `the founder` | 1 | a code comment (`:270`); the ui bundle is outside every check (Q22) |
|
||||
| `tools/community/discord-hooks.mjs` | `MacBook`, `\+0100`, `tailscale`, `ts\.net`, `dl\.igneum` | 1, 1, 1, 1, 2 | the guard's own regexes (`:51, 59, 61`), the read-only fleet URL (`:31`), and `ts\.net` matching "stats.net" in a template (`:255`): false positives, none posted |
|
||||
| `pool/README.md` | `Hetzner`, `/opt/igneum`, `CLAUDE\.md` | 5, 2, 1 | the deploy section; not a site page, but it would fail the scrub if copied |
|
||||
|
||||
|
|
@ -448,7 +448,7 @@ Every other pattern is 0 on every file. Two-beat antithesis and aphorisms in shi
|
|||
| Price | none anywhere; "pounds a day" once (`index.html:510`); Ember has a `priceNow()` with a devnet zero | | | | | | |
|
||||
| Finality | "#N" or "paused" (`index.html:879`) | "#N, 3 min ago" plus the bar (`live.html:404, 512`) | none | "#N · 1 h ago" (`app.js:1350`) | "active" or "paused" | "checkpoint 6,842 at 55.x% of weight, 1 h ago, 93 voters" | none |
|
||||
|
||||
Row **Q85** (cross-cutting, 2 hours, site owner with the app owner): one shared formatter module (`site/lib/format.mjs`) for hash rate (1 decimal, unit ladder kH to PH), counts (`en-GB` separators, never `compact()` for the same quantity shown in full elsewhere), blocks per second (2 decimals, never inverted), difficulty (one spelling), IGN (4 decimals on tiles, 6 in tables), and one word for a vote identity ("vote key" on every surface); the app, hub, Discord and pool copy the same table as a Rust and a JS constant, with a test that renders the fixture values identically. Gate: the fixture renders byte-identical on all seven surfaces. Severity: the project lead-visible (he reads three of these side by side every evening).
|
||||
Row **Q85** (cross-cutting, 2 hours, site owner with the app owner): one shared formatter module (`site/lib/format.mjs`) for hash rate (1 decimal, unit ladder kH to PH), counts (`en-GB` separators, never `compact()` for the same quantity shown in full elsewhere), blocks per second (2 decimals, never inverted), difficulty (one spelling), IGN (4 decimals on tiles, 6 in tables), and one word for a vote identity ("vote key" on every surface); the app, hub, Discord and pool copy the same table as a Rust and a JS constant, with a test that renders the fixture values identically. Gate: the fixture renders byte-identical on all seven surfaces. Severity: the founder-visible (he reads three of these side by side every evening).
|
||||
|
||||
### 4.4 Error states, one table
|
||||
|
||||
|
|
@ -484,7 +484,7 @@ Section 3.10 carries both in full. The two facts to carry forward: a fresh machi
|
|||
- Lighthouse numbers are estimates from source; no browser run was allowed. The gate for every site row is a real run.
|
||||
- The comparator claims are from memory; where a repository or page is named it is cited, otherwise approximate. The Stratum v2 reference was not cloned.
|
||||
- The fleet and node sections depend on the gpu-fleet worktree and the vendor forks, read tonight; the fleet's own page was not opened.
|
||||
- Hours are agent hours (the project lead's rule); Q3 and Q80 also need the project lead (certificates, GitHub billing).
|
||||
- Hours are agent hours (the founder's rule); Q3 and Q80 also need the founder (certificates, GitHub billing).
|
||||
|
||||
## 7. Summary for the coordinator
|
||||
|
||||
|
|
|
|||
|
|
@ -111,13 +111,13 @@ The brief's `-pl` rows: the 5 October sweep on this card (`docs/plans/counter-as
|
|||
| 65% | 400 (the floor) | 310.6 | 114.46 | 0.369 | 3,051 |
|
||||
| 50% | 400 (clamped) | 302.4 | 109.20 | 0.361 | 3,050 |
|
||||
|
||||
`power.min_limit` is 400 W (read again by this job: min 400, max 600), so `-pl 200` and `-pl 250` cannot be set on a 5090; those rows are re-used, not re-run, and the ladder above adds what the cap does once the program carries work. Ember Tune's own 5090 steps did not run (its second engine never mined; re-run pending the project lead); its idle readbacks on PC 1: 90.6 W idle, 2,505 MHz core, 14,001 MHz memory, limit 450 of 575 W.
|
||||
`power.min_limit` is 400 W (read again by this job: min 400, max 600), so `-pl 200` and `-pl 250` cannot be set on a 5090; those rows are re-used, not re-run, and the ladder above adds what the cap does once the program carries work. Ember Tune's own 5090 steps did not run (its second engine never mined; re-run pending the founder); its idle readbacks on PC 1: 90.6 W idle, 2,505 MHz core, 14,001 MHz memory, limit 450 of 575 W.
|
||||
|
||||
The item 1 denominator moves: at the hash alone the 5090 is 290 W in the app (p95 290, max 295 W at 124 MH/s, the 5 October record on branch miner-eff: 2.34 microjoules) and 342 to 357 W in this bench (132 MH/s: 2.65 microjoules), not 326 W at 136.1 (2.40). The `f = 1` rows of chip-model-v3.md section 5.4 therefore read 5.0x (app) to 5.7x (bench) on GDDR7 against 5.1x, 7.3x to 8.3x on one HBM3 stack against 7.5x, 8.9x to 10.1x on eight against 9.2x: a move of 2 to 11 percent, inside the model's own margin.
|
||||
|
||||
## 6. The chip side, re-evaluated (approximate)
|
||||
|
||||
The `f = 1` chip of chip-model-v3.md section 5.4, at the memory's activate ceiling: GDDR7 (16 devices) 166.4 MH/s at 0.466 microjoules per hash, one HBM3 stack 83.6 MH/s at 0.321, eight stacks 0.262; those are memory, static and controller only. With the shadow the chip adds a core that runs the per-epoch random block at `k` times a GPU's marginal energy per op. The unit is now measured: 11 pJ per counted op, the 5090's marginal at its shipping clock (10.2 to 13.2 pJ on the three rungs under the cap, section 5); the model's 5.5 pJ (section 5.7, from TGP minus 326 W over the whole budget) is half that and is kept as the `k = 0.5` column, which is also about the M5 Max's 6.9 pJ. Four columns: `k = 1` (a chip core as good as the 5090's ALU on a random program: RandomX's argument and the project lead's test), `k = 1.5` (1.5x worse), `k = 0.5` (as good as the M5 Max's ALU, or the model's old unit), and `k = 0.3` (a wide-SIMD fixed-datapath array at N5: the int32 datapath energy of section 5.1, 0.06 pJ per add and 0.52 per multiply at the op mix's 29 percent multiplies is 0.19 pJ, with a 2x pipeline overhead and about 8x for the register file, operand wires and the shared instruction fetch over a wide SIMD row, approximate; the floor a chip maker would claim). Section 5.7's "k = 1.5" column was computed as the chip being 1.5x BETTER (0.83 at N = 100,000 is 0.466 + 0.55 / 1.5); the columns below compute `k` as written. Energy per hash = memory + N x 11 pJ x k; N in counted ops.
|
||||
The `f = 1` chip of chip-model-v3.md section 5.4, at the memory's activate ceiling: GDDR7 (16 devices) 166.4 MH/s at 0.466 microjoules per hash, one HBM3 stack 83.6 MH/s at 0.321, eight stacks 0.262; those are memory, static and controller only. With the shadow the chip adds a core that runs the per-epoch random block at `k` times a GPU's marginal energy per op. The unit is now measured: 11 pJ per counted op, the 5090's marginal at its shipping clock (10.2 to 13.2 pJ on the three rungs under the cap, section 5); the model's 5.5 pJ (section 5.7, from TGP minus 326 W over the whole budget) is half that and is kept as the `k = 0.5` column, which is also about the M5 Max's 6.9 pJ. Four columns: `k = 1` (a chip core as good as the 5090's ALU on a random program: RandomX's argument and the founder's test), `k = 1.5` (1.5x worse), `k = 0.5` (as good as the M5 Max's ALU, or the model's old unit), and `k = 0.3` (a wide-SIMD fixed-datapath array at N5: the int32 datapath energy of section 5.1, 0.06 pJ per add and 0.52 per multiply at the op mix's 29 percent multiplies is 0.19 pJ, with a 2x pipeline overhead and about 8x for the register file, operand wires and the shared instruction fetch over a wide SIMD row, approximate; the floor a chip maker would claim). Section 5.7's "k = 1.5" column was computed as the chip being 1.5x BETTER (0.83 at N = 100,000 is 0.466 + 0.55 / 1.5); the columns below compute `k` as written. Energy per hash = memory + N x 11 pJ x k; N in counted ops.
|
||||
|
||||
ALU silicon for the core, at the 5090's 45.2 T op/s (what N = 330,700 at 136.1 MH/s needs): 22,600 32-bit lanes at 2.0 GHz. At N5 an int32 multiply-add lane with its register-file slice is about 0.002 mm^2 (approximate: 3,000 to 6,000 gates at about 0.3 square microns per NAND2-equivalent plus registers), so about 45 mm^2 of datapath, 60 to 100 mm^2 with SIMD control and operand networks, $25 to $40 of silicon at the sram-mirror.md yield model ($20,000 wafer, about $0.36 per mm^2 on a 128 mm^2 die; section 5 of that file); at 28 nm the same lanes are about 8x the area, 360 mm^2 of datapath and 500 mm^2 or more with control, a reticle-class die that a $5M to $30M controller project does not carry. Watts for the core at N = 330,700 and 136 MH/s: at `k = 1` 11 pJ x 45.2 T = 497 W (more than the whole 5090 draws for the same work, which is what `k = 1` means), at `k = 0.5` 249 W, at `k = 0.3` 149 W. At N = 100,000 the array is a third of that: 14,000 lanes, about 30 mm^2 at N5, 150 W at `k = 1`, 45 W at `k = 0.3`.
|
||||
|
||||
|
|
|
|||
|
|
@ -111,5 +111,5 @@ prototype values of spec 1.16, fixed at gate 1.
|
|||
the 1,170 directly.
|
||||
4. Monero's seven years do not price this device (ledger C13).
|
||||
|
||||
Decision at gate 1 (owner: the project lead): the cache size rule "exceeds what one die can hold, and grows", and the mixer
|
||||
Decision at gate 1 (owner: the founder): the cache size rule "exceeds what one die can hold, and grows", and the mixer
|
||||
cost multiplier, against the CPU verify gate.
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ Per tier at migration: a home miner on any card runs the updater and signs one `
|
|||
| The testnet with no value | nothing; no asset | nothing | nothing | nothing | nothing |
|
||||
| The external proving market paid in dollars | a job is a service; settlement in IGN on-chain with no operator custody is not a CASP activity; an operator that converts dollars to IGN is an exchange | the same; dealing or arranging if an operator sits between | money transmission if an operator holds funds | a dollar-settled service is a financial service only if the entity holds or exchanges | the same |
|
||||
|
||||
### 8.3 What Igneum writes into its genesis and public text now (not legal advice; counsel is engaged)
|
||||
### 8.3 What Igneum writes into its genesis and public text now (not legal advice)
|
||||
|
||||
1. No issuer, no offeror, no sale: every coin is created as a block reward (MiCA Article 4(3)(b) language, verbatim in the litepaper).
|
||||
2. The 2025/422 sustainability indicators (kWh a year from hash rate and measured uJ, intensity per transaction, mix by region when known) published by the project each era, so an EU CASP can list without asking.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
7 October 2026, morning UK. Lane 4 of the final research programme ("the last mission"), worktree `igneum-wt-mission`. The question: given everything Igneum already has (the horizon one page, the frontier lane's sixteen ideas, the new-PoW lane's three schemes, class v5, finality in the proof, work-stake, the tail, vote-or-burn, the ladder, the pool design, the light client, the phone app), what is the NEXT genuinely new thing a GPU chain could do that none has. Every candidate here was checked against prior art by name and year, run through its own game theory with a model this lane ran (`invent_model.py`, section 0), reviewed in the Monero or Kaspa developer's voice, priced in agent hours with a first gate, and given its per-tier consequence and four persona verdicts. Nothing here touches the devnet. No em dashes. Figures from memory say approximate; figures from a source name it.
|
||||
|
||||
the project lead's rulings are applied as a filter before any idea is scored: miners are the security always; no stake and no coin bond; no holder penalised; no device bounty; no fixed-height activations; no calendar dates; no reliance on another chain; no dev fund; no privacy; nothing that becomes a token sale; the lottery and the proving stay separate; emission carries security with no end date. An idea that needs one of these is marked dead in one line.
|
||||
The founder's rulings are applied as a filter before any idea is scored: miners are the security always; no stake and no coin bond; no holder penalised; no device bounty; no fixed-height activations; no calendar dates; no reliance on another chain; no dev fund; no privacy; nothing that becomes a token sale; the lottery and the proving stay separate; emission carries security with no end date. An idea that needs one of these is marked dead in one line.
|
||||
|
||||
## 0. Progress, method and the four voices
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# The Igneum Mission
|
||||
|
||||
Written 7 October 2026, morning UK, by the mission coordinator (branch `mission`, worktree `igneum-wt-mission`) on the project lead's order of the same morning, verbatim: "i dont want to get stuck in a loop here where we keep finding and adding features and security so im going to give you one last mission, deep deep dive into the past and look far into the future, what has been done, what hasnt been done, what has been started but not finished, what can we invent and what can we reinvent to honestly make the perfect gpu network that will be noticed as the revolution that everyone is waiting for."
|
||||
Written 7 October 2026, morning UK, by the mission coordinator (branch `mission`, worktree `igneum-wt-mission`) on the founder's order of the same morning, verbatim: "i dont want to get stuck in a loop here where we keep finding and adding features and security so im going to give you one last mission, deep deep dive into the past and look far into the future, what has been done, what hasnt been done, what has been started but not finished, what can we invent and what can we reinvent to honestly make the perfect gpu network that will be noticed as the revolution that everyone is waiting for."
|
||||
|
||||
This is the last research round. Its output is the closed list in section 2. After it the project stops researching and ships. Five lanes ran in parallel and each has its own file with sources and a verdict table: `past.md` (lane 1), `unfinished.md` (lane 2), `future.md` (lane 3), `invent.md` (lane 4), `reinvent.md` (lane 5). Every number below names its lane; the lane file names the source or the model. Hours are agent hours. Nothing on the live devnet was touched and no build or hash measurement was run for this document.
|
||||
|
||||
## 1. One page for the project lead
|
||||
## 1. One page for the founder
|
||||
|
||||
**What has been done.** Of 31 GPU-mined chains since 2011, 8 lost the GPU lane to a chip, 7 closed it by choice, 10 died on price or a rental attack; the 6 still GPU-only pay USD 0.22 to 0.71 a day per RTX 3080 (lane 1). In 20 miner posts the wants were hardware that keeps its value, income without a cliff, a fair supply. Igneum answers the supply in full (no premine, no fund, no fee to any team), the hardware with a measured 2.1x chip bound and the N ladder, the cliff with a monthly glide and a 1 percent tail. Finality by 30 days of blocks, proving as the reward, the leave item and the signing bonus are built or approved for the testnet genesis.
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ This is the last research round. Its output is the closed list in section 2. Aft
|
|||
|
||||
**The honest answer.** Igneum's revolution is the combination already built plus two new things: the finality object in the pocket, and the ladder shown everywhere. No shipped chain has the combination: a random-program GPU hash whose dataset is the chain, miner-only finality with no stake that 51 percent never reaches, that finality inside the execution proof, a work bond with no coin, a tail that holds a 24-hour attack at twelve days of emission in every year. Twelve items, about 290 agent hours, no new consensus rule beyond the three cut branches.
|
||||
|
||||
### Decisions owed from the project lead
|
||||
### Decisions owed from the founder
|
||||
|
||||
The cryptanalysis entity and prize; the signing certificates (lane 5); the signed proving customer as a mainnet gate (lane 1); the H100 and A100 hash measurement on rented pods (lane 3).
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ Twelve items, in build order. "In flight" names the lane or branch that holds it
|
|||
|
||||
### 2.1 The testnet genesis re-cut as approved (in flight, ship lane)
|
||||
|
||||
What it is: one cut with 18 decimals, `EmissionSchedule::TESTNET_1` (100 IGN a block, a monthly glide with a two-year half-life, a 90-day ramp from 10 percent, a 1 percent tail from year 11.4), and the switches on from genesis: proof verification in consensus, the leave item, the signing bonus at 1,000 bps, finality v3, the latency ladder at rung 0. the project lead approved it on 7 October 2026, 09:3x UK (ledger-decisions.md).
|
||||
What it is: one cut with 18 decimals, `EmissionSchedule::TESTNET_1` (100 IGN a block, a monthly glide with a two-year half-life, a 90-day ramp from 10 percent, a 1 percent tail from year 11.4), and the switches on from genesis: proof verification in consensus, the leave item, the signing bonus at 1,000 bps, finality v3, the latency ladder at rung 0. The founder approved it on 7 October 2026, 09:3x UK (ledger-decisions.md).
|
||||
Why it is right: lane 1's verdict rows 4 and 5 (the cliff and the premine) are answered by it in full; lane 3's tail row holds to year 200.
|
||||
Evidence: tail-emission.md one page; vote-or-burn.md section 5; ledger-decisions.md 7 October.
|
||||
Cost: 0 new hours; the ship lane's own plan.
|
||||
|
|
@ -127,7 +127,7 @@ Order: ninth; before any phone trusts item 2's object.
|
|||
What it is: lines added to `docs/plans/testnet-go.md` and the litepaper, each with its check. Gates: a signed proving customer before mainnet, with the weight of the Devnet 2 gate; per-tier income published at three prices (USD 0.005, 0.02, 0.10) before the testnet, per the consequences rule; the launch-week hash-origin report (key counts, pool shares, fleet shares) from the observer, daily for the first 90 days; the first 100 keys, the first 1,000 independent keys (the X5 definition), the first pool not run by the project, the first outside-reproduced benchmark, the first block from a card the project does not own; signed and notarised installers (Developer ID, Authenticode) with the measured first-share time per release. Text: the three wants on the front page and finality on page two; "a block pays its miner whether or not anyone buys a proof that day"; the eight regulatory sentences of lane 3 section 8.3 (no issuer, no sale; the sustainability indicators per era; no price language; the pool holds no balance; no privileged key), labelled "not legal advice; counsel is engaged".
|
||||
Why it is right: lane 1's shape (income halves 60 to 120 days after a peak, under USD 0.10 per kWh within 6 to 18 months, 50 to 100 percent of hash gone in 90 days) and its rows 2, 4, 7 and 9; lane 5's install findings (SmartScreen warns on any file without reputation); lane 3's regulation rows (MiCA 4(3)(b) exempts block-reward assets; the UK regime from 25 October 2027 covers platforms and custody, not mining).
|
||||
Evidence: past.md sections 3 and 4; future.md section 8; reinvent.md 3.1 and 4.1.
|
||||
Cost: 15, plus the project lead's certificates and the customer's signature.
|
||||
Cost: 15, plus the founder's certificates and the customer's signature.
|
||||
Gate: every gate line in testnet-go.md with its check; the forbidden-strings check passes on the new text; the hash-origin report posts on Devnet 2 for seven days before the testnet go.
|
||||
Order: tenth; text and gates can land any hour, and the customer gate is the one that takes longest.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Date: 7 October 2026, UK time. Lane 5 of the last mission. Written in the mission worktree; this file is the only output. Nothing was built, measured, posted or started; the live devnet was not touched.
|
||||
|
||||
the project lead's words that this lane holds: "revolutionise the mining itself"; "dopamine for GPU miners everywhere, a structure that makes the mining commodity fall in love with the project"; "the perfect gpu network that will be noticed as the revolution that everyone is waiting for". Bounds that this lane obeys: no premine, no dev fund, no treasury, no token sale, no airdrop, no referral paid in coins; every coin is mined under the rules that exist (the 80/20 split, the signing bonus of 8 of the 80 producer points, the proving pool); no stake; no device bounty; the three signalling thresholds (60, 90, 95); miners are the security always; gates, not dates; hours are agent hours.
|
||||
The founder's words that this lane holds: "revolutionise the mining itself"; "dopamine for GPU miners everywhere, a structure that makes the mining commodity fall in love with the project"; "the perfect gpu network that will be noticed as the revolution that everyone is waiting for". Bounds that this lane obeys: no premine, no dev fund, no treasury, no token sale, no airdrop, no referral paid in coins; every coin is mined under the rules that exist (the 80/20 split, the signing bonus of 8 of the 80 producer points, the proving pool); no stake; no device bounty; the three signalling thresholds (60, 90, 95); miners are the security always; gates, not dates; hours are agent hours.
|
||||
|
||||
## 0. Progress
|
||||
|
||||
|
|
@ -148,8 +148,8 @@ What the comparators do: SmartScreen warns on any file that is not "well known a
|
|||
|
||||
| Step | Today | Proposal | Hours | Gate |
|
||||
|---|---|---|---|---|
|
||||
| Mac signature | ad hoc, quarantine strip | Developer ID plus notarisation and stapling in `build-dmg.sh`; the quarantine strip removed | 3 plus the project lead's USD 99 | a fresh macOS 26 machine opens the DMG's app with no Privacy and Security visit |
|
||||
| Windows signature | none | Authenticode through Trusted Signing or an OV certificate, signed on the box as a job step; the sha256 and the signer's name on the download page (Q50, Q82) | 3 plus the project lead's purchase | a fresh Windows 11 machine runs the installer with no SmartScreen interstitial by the 1,000-download mark (reputation is use; before that the page shows the exact interstitial text and the two clicks) |
|
||||
| Mac signature | ad hoc, quarantine strip | Developer ID plus notarisation and stapling in `build-dmg.sh`; the quarantine strip removed | 3 plus the founder's USD 99 | a fresh macOS 26 machine opens the DMG's app with no Privacy and Security visit |
|
||||
| Windows signature | none | Authenticode through Trusted Signing or an OV certificate, signed on the box as a job step; the sha256 and the signer's name on the download page (Q50, Q82) | 3 plus the founder's purchase | a fresh Windows 11 machine runs the installer with no SmartScreen interstitial by the 1,000-download mark (reputation is use; before that the page shows the exact interstitial text and the two clicks) |
|
||||
| Firewall prompt | UAC 20 to 50 s in, unexplained | the Cards screen names it and the step runs after `setup_done` (Q14) | 1 | the prompt never appears before a screen that says it will |
|
||||
| Antivirus | nothing | a "What your antivirus may say" line on `/miner#get` with the engine names and the exact action, and the submission to Microsoft's SmartScreen review on every release (the Learn page's submission route) | 1 | the line is on the page; every release's binaries are submitted the day they ship |
|
||||
| Time to the first share | not measured end to end on a fresh machine | measured on a fresh Windows 11 VM and a fresh Mac for every release by the Devnet 2 gate: download to first accepted share or block, with the clock, the sync and the dataset build as three timed steps | 2 | "first share within 10 minutes of download in 9 of 10 fresh Windows installs", published on `/evidence` |
|
||||
|
|
@ -364,7 +364,7 @@ Written in copy law (short sentences, no antithesis, no aphorism).
|
|||
| Ember, Earnings | "£0.00 earned", mined IGN never shown (Q18) | IGN a day, blocks and IGN in 30 days, shards and IGN, a typed price, share of network, weight rank, days, signing streak | 6.5 | every line names its RPC field on hover; a view test per line |
|
||||
| Ember, Prove | state line "0 assigned · 0 proven · 0 paid" | the shard card "your card proved shard N of block M, 1.15 IGN" | 1 | a card on the first paid record on Devnet 2 |
|
||||
| Ember, Settings | pool field designed, not built (`pool.md` section 7) | the pool field, the terms box from `welcome`, the dev-fee line reading "off in pool mode: the pool's 1 percent is the same fee" | 3 | a member connects from the app and shows the terms |
|
||||
| Ember, first run | two prompts, one unexplained (Q3, Q14) | signed and notarised; the firewall step named on the Cards screen | 7 plus the project lead's certificates | 3.1 gates |
|
||||
| Ember, first run | two prompts, one unexplained (Q3, Q14) | signed and notarised; the firewall step named on the Cards screen | 7 plus the founder's certificates | 3.1 gates |
|
||||
| Wallet | one account, no finality state on the address page (Q33, Q37) | the first-transfer card with the five state words; the address page with the latest lock | 3 (plus Q9's 6) | a devnet transfer walks the five words on screen |
|
||||
| Site `/miner` | "Install. Start. The card mines and proves." plus feature lines | the first-hour timeline (download, the one prompt, first share, first block, first payout) with the measured times from the Devnet 2 gate | 2 | the times on the page equal the gate's log |
|
||||
| Site `/live` | miners with a block in 10 minutes | the weight leaderboard with days mined and signing presence; the 10-minute view as a toggle | 3 | top 100 by weight; a stopped key falls one place a day |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# The last mission, lane 2: started and not finished, across the industry
|
||||
|
||||
7 October 2026. Lane 2 of the final research programme. What the industry started and did not finish, group by group, with one verdict per row: Igneum already has the finished version, Igneum could finish it in hours, or Igneum should leave it. Every figure from a source carries its URL and access date in section 9; every figure from memory is labelled approximate. Hours are agent hours (the project lead's rule: Claude-side work takes hours, never weeks). Nothing here is a token sale.
|
||||
7 October 2026. Lane 2 of the final research programme. What the industry started and did not finish, group by group, with one verdict per row: Igneum already has the finished version, Igneum could finish it in hours, or Igneum should leave it. Every figure from a source carries its URL and access date in section 9; every figure from memory is labelled approximate. Hours are agent hours (the founder's rule: Claude-side work takes hours, never weeks). Nothing here is a token sale.
|
||||
|
||||
What this file does not repeat: the ASIC chip history (`docs/analysis/asic-resistance-history.md`), the useful-work verdict and the stored-state candidate (`new-pow.md` sections 3, 6, 7), the ranked frontier ideas (`frontier.md` section 0, 3.10, 3.11), and Igneum's own pool design (`docs/plans/pool.md`, `docs/spec/09-pool-protocol.md`). Those are cited, not restated.
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ Ember's state is from `polish.md` 3.1 and 3.10: a Rust engine runs `igneumd` and
|
|||
| Pool mode | Every miner | Design only | Behind; the share sidechain of 5.3 is the finish |
|
||||
| Finality on the surface | Nobody | Nothing during a pause (Q2) | Behind, 3 hours, and nobody else has the concept |
|
||||
|
||||
The honest line: Ember is the first app to ship the thing the table says nobody shipped (node, wallet, GPU miner, own key, signed updates, no custody), and it loses to a 2018 Honeyminer on the sixty seconds between download and first share. The first-run fixes are one Developer ID and one Authenticode certificate (Q3, a the project lead decision) plus the Q80 installer builder; the rest of the behind rows are 11 hours.
|
||||
The honest line: Ember is the first app to ship the thing the table says nobody shipped (node, wallet, GPU miner, own key, signed updates, no custody), and it loses to a 2018 Honeyminer on the sixty seconds between download and first share. The first-run fixes are one Developer ID and one Authenticode certificate (Q3, a the founder decision) plus the Q80 installer builder; the rest of the behind rows are 11 hours.
|
||||
|
||||
## 7. Verdict table
|
||||
|
||||
|
|
@ -280,7 +280,7 @@ The honest line: Ember is the first app to ship the thing the table says nobody
|
|||
| E | Encrypted member transport | SV2 Noise | No (plain TCP, Q67) | 8 | Finish |
|
||||
| E | A pool-as-contract with sampled share verification (SmartPool) | Nobody since 2017 | No | 0 | Skip (1.35 ms per share makes it worse than it was for Ethereum) |
|
||||
| F | Node, wallet and GPU miner in one app, own key, signed updates | Nobody; Ember | Yes | 0 | Already done |
|
||||
| F | Sixty seconds from download to first share | Honeyminer did it in 2018 | No (three prompts, no Windows build) | 6 plus certificates (Q3); 0 or 4 (Q80) | Finish; the certificates are the project lead's |
|
||||
| F | Sixty seconds from download to first share | Honeyminer did it in 2018 | No (three prompts, no Windows build) | 6 plus certificates (Q3); 0 or 4 (Q80) | Finish; the certificates are the founder's |
|
||||
| F | Earnings in IGN, per-card faults, an hour of history, a finality notice | HiveOS, lolMiner | No (Q18, Q13, Q16, Q2) | 11 | Finish |
|
||||
| F | Payout in something a gamer can spend (Salad's gift cards) | Salad | No, and the chain says "nothing is bought or sold on devnet" | 0 | Skip until there is a market |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# The prover floor: why a 12 GB card cannot prove on SP1 6.8.1's GPU server, and the patch
|
||||
|
||||
5 October 2026, 22:00 UTC on (the project lead: "execute if it will solve the issue"). Branch `prover-floor`
|
||||
5 October 2026, 22:00 UTC on (the founder: "execute if it will solve the issue"). Branch `prover-floor`
|
||||
(worktree `igneum-wt-prover-floor`). The measured facts this starts from: `docs/plans/proving-v1.md` and the
|
||||
bench-log entry "proving v1" (branch proving-v1): the GPU server holds 13.9 GB for an empty shard, 20.4 GB at the
|
||||
adopted v1 shard, 28.3 GB flat from 20 M to 60 M cycles, and no environment knob moved the floor. Every figure
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Prover tiers on real cards: the memory matrix of the patched SP1 GPU server, measured on rented GPUs
|
||||
|
||||
6 October 2026, from 11:50 UTC (the project lead: "rent all you need, absolute overkill", "get as many GPUs as you need to properly
|
||||
6 October 2026, from 11:50 UTC (the founder: "rent all you need, absolute overkill", "get as many GPUs as you need to properly
|
||||
test everything swiftly"). Branch `gpu-fleet`, tools in `tools/fleet/`, raw logs per instance under
|
||||
`~/Desktop/fleet/<instance>/` (the sampler csv, every point's host log and results JSON, the miner log). This file
|
||||
replaces the 5090-allocation rows of `docs/analysis/prover-floor.md` with the cards themselves. A row that is not here
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
# Proving methods: why the prover needs 14 GB, what else exists, and how a 12 GB card gets to prove
|
||||
|
||||
5 October 2026, from the project lead at 22:05 UTC: "if this doesn't enable 12 GB cards, then do a full deep research task on proving
|
||||
5 October 2026, from the founder at 22:05 UTC: "if this doesn't enable 12 GB cards, then do a full deep research task on proving
|
||||
and see if there are different methods." "This" is the prover-floor agent's patch of SP1's GPU server (branch
|
||||
`prover-floor`), running tonight. This document is research and reading, not measurement: every number of ours is from
|
||||
`docs/bench-log.md` with its entry named; every claim about another system cites its repository file, its documentation
|
||||
page or its paper, or is labelled approximate. Status words follow `docs/spec/00-overview.md` 0.2. Day estimates follow
|
||||
the project lead's rule of 3 October 2026: hours of agent time, never weeks.
|
||||
The founder's rule of 3 October 2026: hours of agent time, never weeks.
|
||||
|
||||
The facts this starts from (bench-log, "proving v1", 5 October 2026; `docs/plans/proving-v1.md`; `docs/analysis/amd-proving.md`):
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ the tier it moves, in one sentence, the day it is taken.
|
|||
|
||||
| Consequence | Action | Owner |
|
||||
|---|---|---|
|
||||
| The gate card has never run a prover here | get a 4070 or 3060 into the measurement loop this week; until then every 12 GB figure stays approximate | coordinator; the project lead for the card |
|
||||
| The gate card has never run a prover here | get a 4070 or 3060 into the measurement loop this week; until then every 12 GB figure stays approximate | coordinator; the founder for the card |
|
||||
| Route A's gate | the prover-floor agent's rows (asked for by message tonight); if under 11 GB, `provedefault.rs` gains the 12 GB prove-only and 16 GB mine-and-prove tiers and the rig installer one server per card | prover-floor agent, then the proving engineer |
|
||||
| Route D's measurement | RISC Zero 3.0.6 at po2 19 and 20 on PC 2 (CUDA) and on this Mac (Metal), the same shard statement run natively: memory, time per segment, lift and join, receipt size | prover-floor agent (PC 2); a Mac measure job for Metal |
|
||||
| The two-family node items (record version selects the verifier, fresh chain at a version change, one family per block) | spec 7.8 gains the three rules when route D starts; nothing changes before | execution engineer |
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@ prove nothing. The static check is the guard, as it is for the dataset mask.
|
|||
4. The lever that moves the named chip is the M16 mixer multiplier: x2 to 1.2x, x4 to 0.6x against the measured
|
||||
5090 rate, at 0.8 to 4.8 ms of verification per warp against the 10 ms gate. Decision 2 should price that
|
||||
against the gate on the 2019-class core (O-1.14) rather than layer 3.
|
||||
5. If the project lead keeps layer 3 for a reason outside this analysis: ship the host contract in the pack, add the four
|
||||
5. If the founder keeps layer 3 for a reason outside this analysis: ship the host contract in the pack, add the four
|
||||
vector items of section 6 (consecutive units with a forced collision, the wrap launch, the warp-count-independent
|
||||
fingerprint, the contract text), and run the CUDA and OpenCL twins of section 7.2 on the PCs before the class
|
||||
becomes a genesis rule.
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ Option E is the only one that makes the mirror a multi-die part and it costs eve
|
|||
genesis (at the headline density; the lower-bound density would ask for 4 GiB and 3.2 s), which fails the spirit of
|
||||
the 10 ms verify gate (the fill is once a day, but a light node joining pays it on every day it syncs across).
|
||||
|
||||
Decision for the project lead, at gate 1: A, B, C, D or E above, together with M16's mixer multiplier. Nothing here changes a
|
||||
Decision for the founder, at gate 1: A, B, C, D or E above, together with M16's mixer multiplier. Nothing here changes a
|
||||
vector today: the cache size is a prototype value of spec 1.16 and the growth rule would be a new sentence in 1.13.3.
|
||||
|
||||
## 8. Why the latency bound is the property to lean on (citations behind the plan's rule)
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ Attack, before and after (ignored test `measure_m15_attack_before_and_after`, re
|
|||
- Before (the pre-fix order, replayed by calling the engine with the header's own unvalidated day seed): 50 cold 256 MiB builds, 10,595 ms, and the honest day's entry is evicted (`KEEP` was 3).
|
||||
- After (the new order): 0 builds, all 50 rejected (`TimeTooOld` or `UnexpectedHeaderDaaScore`) in 14 ms total. The live day stays resident.
|
||||
Tests: kaspa-pow `--features igneum-pow` 8 pass (engine smoke, `one_build_per_seed_pair_under_contention`, `live_days_survive_off_day_builds`, `build_queue_is_bounded`, index and live-day helpers, shared-engine, stub); kaspa-consensus header_processor `cheap_checks_run_before_the_pow_engine` pass; kaspa-p2p-flows `pow_guard` 2 pass; the full kaspa-consensus release suite otherwise unchanged.
|
||||
M16 Metal note (R3.5, cheap reconfirmation only): the Mac `--inline-dataset` shortcut at the 256 MiB cache, 256 MiB dataset, under the same heavy load, ran honest 91.7 Mhash/s against inline 5.29 Mhash/s (inline about 17x slower); this is noisier and slower than the idle-machine figures already in `proto-metal/MEMHARD.md` (10x slower at a 256 MiB dataset, 4.8x at 1 GiB), because the inline kernel is compute-bound and the machine was loaded. The 64 MiB on-die-SRAM emulation M16 wants (inline kernel with a 64 MiB cache, `cacheLog2Words = 24` in `proto-metal/main.swift`) is the RTX 5090 run reserved for the project lead's PC, as R3.5 states; it is not done here and the Mac number above does not price a die.
|
||||
M16 Metal note (R3.5, cheap reconfirmation only): the Mac `--inline-dataset` shortcut at the 256 MiB cache, 256 MiB dataset, under the same heavy load, ran honest 91.7 Mhash/s against inline 5.29 Mhash/s (inline about 17x slower); this is noisier and slower than the idle-machine figures already in `proto-metal/MEMHARD.md` (10x slower at a 256 MiB dataset, 4.8x at 1 GiB), because the inline kernel is compute-bound and the machine was loaded. The 64 MiB on-die-SRAM emulation M16 wants (inline kernel with a 64 MiB cache, `cacheLog2Words = 24` in `proto-metal/main.swift`) is the RTX 5090 run reserved for the founder's PC, as R3.5 states; it is not done here and the Mac number above does not price a die.
|
||||
Not done: the real-engine daemon RPC run (honest blocks need GPU-mined pow, so the measurement used the equivalent validate path with `skip_proof_of_work`); the 64 MiB-cache inline kernel on the 5090; the chain-derived day seed by DAA score (spec 01 section 1.12, still the timestamp-day devnet rule); the VDF epoch seed and finality.
|
||||
|
||||
## 3 October 2026, difficulty controller: devnet record, simulator, Igneum dual-lane rule, 3-node CPU test network (consensus-engineer)
|
||||
|
|
@ -418,7 +418,7 @@ Not changed: the pgas table magnitudes (prototype), `B_p` = 30 M (prototype). Op
|
|||
|
||||
Machine for the reproduction: Apple M5 Max, 64 GiB, Darwin 25.6.0, load average 2 to 147 (other agents' builds and, during R1, another agent's Metal worker on the same GPU); everything at `nice -n 19`. Binaries: HEAD `proto-metal/main.swift` built with `swiftc -O` into the scratchpad (465,529 bytes, the same size as `proto-metal/igneum-bench`), `vendor/igneum-node-diff/target/release/igneumd` and `igneum-miner` (22:38 and 22:17 BST, the `difficulty` worktree pair; the miner's `Seeder` and worker protocol are the same code as HEAD and as the Windows build 745d41ef). Private networks on 127.0.0.1 ports 27500 to 27562, appdirs under `/tmp/igneum-decay-test`, all stopped afterwards. Full write-up: `docs/analysis/hashrate-decay-2026-10-03.md`; proposed fix: `docs/analysis/hashrate-decay-2026-10-03.patch` (not applied; `git apply --check` passes against `vendor/igneum-node`).
|
||||
PC data (`node tools/logs.mjs <run_id> --all`, STATUS lines deduplicated by timestamp, per-interval rates from consecutive cumulative figures): segment 22:57 to 23:04 UTC, nvidia-1: 40 jobs in the first 30 s then exactly 32 per 30 s for 12 intervals at 17.5 to 18.4 MH/s wall while the printed cumulative figure fell 22.18 to 18.13; nvidia-8 (started 4.7 s later) printed a rising 16.80 to 17.71. Segment 22:23 to 22:57 UTC (epoch 2, DAA 8,474 to 10,513): per-identity gap between jobs 0.098 s to 0.330 s per 0.68 to 0.81 s job, inside-jobs rate rising 28.7 to 34.7 MH/s, wall falling 24.6 to 20.6 MH/s, card total 197 to about 165 MH/s; at the 22:57 epoch boundary the gap returned to 2% and the difficulty held (84.5M to 83.0M).
|
||||
Code audit: nothing allocated per job survives the job in `proto-cuda/host.cu`, `proto-opencl/host.c` or `proto-metal/main.swift` serve loops (tables in the analysis); the miner's only per-job growth is time in `Seeder::seeds_for` (memo keyed by `(epoch, sink)`, one `getBlock` RPC per block from the sink to the epoch start on every miss, 1,274 to 3,313 calls on the PC). `cudaDeviceSynchronize` at the default schedule spins one thread per worker (the project lead's 6.2% per process); the hot-swap working tree sets `cudaDeviceScheduleBlockingSync` and swaps `clFinish` for `clWaitForEvents`.
|
||||
Code audit: nothing allocated per job survives the job in `proto-cuda/host.cu`, `proto-opencl/host.c` or `proto-metal/main.swift` serve loops (tables in the analysis); the miner's only per-job growth is time in `Seeder::seeds_for` (memo keyed by `(epoch, sink)`, one `getBlock` RPC per block from the sink to the epoch start on every miss, 1,274 to 3,313 calls on the PC). `cudaDeviceSynchronize` at the default schedule spins one thread per worker (the founder's 6.2% per process); the hot-swap working tree sets `cudaDeviceScheduleBlockingSync` and swaps `clFinish` for `clWaitForEvents`.
|
||||
Metal runs (STATUS every 30 s; "gap" = 1 minus wall over inside, per interval): R1 control, epoch 0, genesis bits 0x1d100000, 308 s (cut by the 22:21:37 UTC SIGTERM of every process of this session): first interval 25.18 MH/s alone on the GPU, then 14.0 to 14.4 MH/s in every interval after another agent's worker joined at 25 s, gap 0 to 2%, worker RSS 56.8 MiB flat. R2 walk reproduction, 900 s: `skip_proof_of_work` node pumped to DAA 4,000 (one-second timestamps, difficulty held at 76.8M), one identity, pumped blocks at 1/s for 300 s, none for 300 s, 1/s for 300 s: inside 27.0 to 27.7 MH/s in all 29 intervals; wall 22.3 to 24.3 (gap 12 to 18%, walk 400 to 700), 25.9 to 27.3 (gap 0 to 4%), 18.0 to 21.0 (gap 25 to 35%, walk 700 to 1,000); miner CPU 0 to 1% in the quiet phase, 11 to 21% in the last. R3 one worker at difficulty 2^25 (Kaspa sampled rule, genesis bits held), 600 s: 30.51 wall / 30.72 inside, 1,091 jobs, 224 blocks, 53 to 56 jobs per 30 s throughout. R4 eight workers at 2^25: 29.38 / 29.45 summed (3.32 to 4.38 each), 1,053 jobs, 242 blocks, 7 jobs per 100 s per identity in every interval, worker CPU 0.0 to 0.6%, RSS 46 to 57 MiB. R5 one worker at 2^31: 37.01 / 37.75, 1,324 jobs, 4 blocks, flat. R6 eight workers at 2^31: 36.67 / 36.75 summed (4.29 to 5.55 each), 1,314 jobs, 5 blocks, flat. (R5 and R6 ran a different epoch-0 program from R3 and R4, 112 loads per hash, hence 37 against 30.5 MH/s.)
|
||||
Side findings: the `difficulty` worktree's node panics at `consensus/src/processes/difficulty.rs:431` ("Work should not exceed 2**192") when fed 85 blocks/s with wall-clock timestamps under the Igneum dual rule (a pump artefact, logged for the consensus-engineer); `skip_proof_of_work` nodes still log "PoW rejected ... by igneum-lottery-v1-bound" for every block they accept. Not done: the fix applied and measured on the PC (the acceptance figure is a flat gap at DAA 10,800 with eight identities); the OpenCL event wait checked on the AMD driver; a unit test of `seeds_for` (the client is concrete).
|
||||
|
||||
|
|
@ -526,7 +526,7 @@ Binaries: `target-integration/release/{igneumd 40,463,680 B, igneum-miner 7,916,
|
|||
|
||||
## 4 October 2026, generator version 2 adopted: exact load count, fresh-source loads, program acceptance; every vector re-cut, three workers re-checked, 20,000-program census, devnet-v4 binaries rebuilt (cryptographer)
|
||||
|
||||
Machine: Apple M5 Max, idle at the start (load 3), rustc 1.99.0 (rustup), Swift 5.8.1, builds at nice 10. Decision (the project lead, this morning): adopt the census's generator rule before any public vector ships. Rule as implemented (`igneum-pow/src/generator.rs`, `src/accept.rs`, spec 01 sections 1.4.2, 1.4.3 and 1.4.6; mirrored in `proto-metal/main.swift` as `generateProgramV2` and `acceptProgram` because the Metal worker derives its program from the seed itself): G1 exactly 16 load slots, a uniform subset of instructions 1..63 drawn first by partial Fisher-Yates, the other 48 ops from the ten non-load weights (sum 75); G2 a load's source is drawn from the registers other than `dst` written by an earlier instruction and not read by a load since; R (a) no cyclically stale load source, (b) every register has an injecting write, (c) 64 units at base nonces from `SplitMix64(FNV-1a-64("igneum-accept/" || seed words LE))` on the seed-keyed closed-form dataset at 2^28 words with init words = seed words: no constant register bit, no lane-constant load site in any unit, fewer than 164 saturated final values, every output bit within 136 of 1,024, distinct addresses above 245,760 over the 2,048 hashes; a rejected candidate is replaced by `seed_words_from_bytes(seed || k_le32)`, `k = 1, 2, ...`, 32 consecutive rejections a consensus fault. Every pack carries `generator 2`, the attempt and the program id `FNV-1a-64("igneum-program/" || 2_le32 || seed words LE || attempt_le32)`; `igneum-pow` is 0.2.0 and the node's engine reports `igneum-lottery-v2-bound`. The crate is now the pack source (`igneum-pow export`); the Swift exporter is the Metal cross-check. Version 1 stays as `generate_v1` for the census and MEMHARD.md levers; its vectors are retired.
|
||||
Machine: Apple M5 Max, idle at the start (load 3), rustc 1.99.0 (rustup), Swift 5.8.1, builds at nice 10. Decision (the founder, this morning): adopt the census's generator rule before any public vector ships. Rule as implemented (`igneum-pow/src/generator.rs`, `src/accept.rs`, spec 01 sections 1.4.2, 1.4.3 and 1.4.6; mirrored in `proto-metal/main.swift` as `generateProgramV2` and `acceptProgram` because the Metal worker derives its program from the seed itself): G1 exactly 16 load slots, a uniform subset of instructions 1..63 drawn first by partial Fisher-Yates, the other 48 ops from the ten non-load weights (sum 75); G2 a load's source is drawn from the registers other than `dst` written by an earlier instruction and not read by a load since; R (a) no cyclically stale load source, (b) every register has an injecting write, (c) 64 units at base nonces from `SplitMix64(FNV-1a-64("igneum-accept/" || seed words LE))` on the seed-keyed closed-form dataset at 2^28 words with init words = seed words: no constant register bit, no lane-constant load site in any unit, fewer than 164 saturated final values, every output bit within 136 of 1,024, distinct addresses above 245,760 over the 2,048 hashes; a rejected candidate is replaced by `seed_words_from_bytes(seed || k_le32)`, `k = 1, 2, ...`, 32 consecutive rejections a consensus fault. Every pack carries `generator 2`, the attempt and the program id `FNV-1a-64("igneum-program/" || 2_le32 || seed words LE || attempt_le32)`; `igneum-pow` is 0.2.0 and the node's engine reports `igneum-lottery-v2-bound`. The crate is now the pack source (`igneum-pow export`); the Swift exporter is the Metal cross-check. Version 1 stays as `generate_v1` for the census and MEMHARD.md levers; its vectors are retired.
|
||||
|
||||
Packs regenerated (`proto-cuda/packs/`): `igneum-genesis` and `igneum-hourly` (closed form), `igneum-genesis-mh` (memory-hard, day 2026-10-03, cache FNV unchanged `48c4f5bf24166b2e`), and new `igneum-devnet-v4-epoch0` (epoch seed = devnet genesis hash `edc4fa84...fb07`, day bytes `igneum-day/20730`, cache FNV `448274a57f508cbc`). `igneum-genesis` attempt 0, program id `bcc1248b10cc90f2`, op mix `load=16 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1`, lane 0 at base 0 `42246ba99fc58e4f`, lane 31 `b08446b1f2de7793`; devnet pack id `4be132dd1f2ff270`, lane 0 `285a83011e7ac3fc`. Bound vectors re-cut (`igneum-pow/README.md`: H zero, nonce 0 gives `746c567b090acf6a`). `cargo test --release`: 39 of 39 (28 unit, 11 pack).
|
||||
|
||||
|
|
@ -545,7 +545,7 @@ Not done: no NVIDIA or AMD hardware has run a version 2 pack (the RTX 5090's 192
|
|||
|
||||
## 2026-10-04 finality floor 2/3: the total-weight floor raised from 17/30 to two thirds, simulator A to L re-run, attack scenarios 6A and 6B on a three-node, six-voter network (cryptographer)
|
||||
|
||||
Decision of 4 October 2026 (the project lead, O-3.15): a lock needs two thirds of all 30-day weight, and finality pauses whenever less than two thirds of that weight is connected and signing; the chain continues on proof of work meanwhile and the node reports it. Spec 3.3, 3.3.1, 3.7, 3.9, 3.11 rewritten; litepaper Finality and "What Igneum does not claim" updated; ledger F2, F9, F16, F18 restated and F21 added (the window bound of attack scenario 6A).
|
||||
Decision of 4 October 2026 (the founder, O-3.15): a lock needs two thirds of all 30-day weight, and finality pauses whenever less than two thirds of that weight is connected and signing; the chain continues on proof of work meanwhile and the node reports it. Spec 3.3, 3.3.1, 3.7, 3.9, 3.11 rewritten; litepaper Finality and "What Igneum does not claim" updated; ledger F2, F9, F16, F18 restated and F21 added (the window bound of attack scenario 6A).
|
||||
|
||||
Node. Branch `devnet-v4` of `vendor/igneum-node` (worktree `vendor/igneum-node-v4`, from `dc749905`), commit `6457ca95`, two files: `consensus/core/src/finality.rs` (`FLOOR_NUM / FLOOR_DEN` 2/3, was 17/30; the Q3 arithmetic as `FinalityParams::{quorum_met, floor_met, locks}`, both comparisons inclusive) and `consensus/src/processes/finality.rs` (`lock_test` calls it). Build `CARGO_TARGET_DIR=target-integration nice -n 10 cargo build --release -j 6 -p kaspad --features kaspad/igneum-pow`, 3 min 17 s on a machine at load 3 to 13 (another agent's igneum-pow rebuild and the live devnet running). Tests `cargo test --release -j 6 -p kaspa-consensus-core -p kaspa-consensus -- finality`: 7 of 7 in consensus-core including the new `floor_is_two_thirds_of_total_and_inclusive` (4 of 6 locks, 3 of 6 does not, 2 of 3 locks, 67 of 100 locks, 66 does not, 57 does not; the total test implies the active test at every participation; a 3/3 side never locks whatever the other side's participation decays to), 2 of 2 in consensus (`no_certificate_while_the_window_is_filling` unchanged). The live devnet (26610, 26611, 26640, 26641, 28640, the seed relay on 26680 and `observer.mjs`) was never touched.
|
||||
|
||||
|
|
@ -577,7 +577,7 @@ Notes. (1) The v4 node logged "PoW rejected ... by igneum-lottery-v1-bound" abou
|
|||
|
||||
## 4 October 2026, proving v0 on the RTX 5090: first GPU proof of an Igneum block (WSL2, SP1 6.8.1 cuda)
|
||||
|
||||
Machine: the project lead's Windows 11 PC, RTX 5090 (32,607 MiB, driver 617.14), 16 cores and 45 GB visible to WSL2 Ubuntu 24.04, mining
|
||||
Machine: the founder's Windows 11 PC, RTX 5090 (32,607 MiB, driver 617.14), 16 cores and 45 GB visible to WSL2 Ubuntu 24.04, mining
|
||||
paused. Package `proving/windows-wsl2` (SETUP-PROVER then PROVE-BLOCK), host `igneum-prove-host` built with the `cuda` feature,
|
||||
`SP1_PROVER=cuda`, sp1-gpu-server 6.8.1 on device 0. Fixture `block-78-increment` (chain 4463, 2 transactions, 10 accounts).
|
||||
Run id `prove-<pc>-20261004-084838`, log intake id 10154.
|
||||
|
|
@ -773,7 +773,7 @@ button and the held miner all showed; with the real clock the HTTPS source read
|
|||
|
||||
## 4 October 2026, first machine on the Igneum Miner app: PC 2's RTX 5090 at 118 MH/s, via Setup.exe
|
||||
|
||||
the project lead's second PC (a clone of the first; the app's per-install machine id `1ccfe586` keeps its keys apart), installed from the
|
||||
The founder's second PC (a clone of the first; the app's per-install machine id `1ccfe586` keeps its keys apart), installed from the
|
||||
runner-built `Igneum-Miner-Setup-0.3.0.exe` (unsigned, SmartScreen "run anyway"), the one-click package: prebuilt NVRTC
|
||||
worker, no toolchain on the machine. First attempt sat at "waiting for peer": the PC's clock was 62 s slow after a power cut
|
||||
and `igneumd` rejected every relayed block ("the block timestamp is too far into the future"; the 10-s skew bound from the
|
||||
|
|
@ -794,7 +794,7 @@ Candidates on the live replay (join window, 3 seeds, std of log difficulty / lan
|
|||
Cost (synthetic set seed 7, v1 / v2): x50 settled 61.7 / 65.5 s (standard under 90), /50 628 / 753 s (worst gap 32 / 62 s), epoch +-30% settled 144 / 143 s, hop10 211 / 200 s, polluted overshoot 0.180 / 0.089, warm-ups equal, steady std 0.038 / 0.049 with blocks-per-minute CV 0.135 / 0.130. Attacks (seeds 7 to 9, v1 / v2): greedy hopper at most +1.5% / +2.5%, with a 60 s dwell -4.0% / -1.5% at 100%; pulsed rental -96.4% / -96.3% with weight per hash 0.262 / 0.262; forger drift +0.4 to +1.1% / -0.8 to +0.5% (worst seed 2.7% / 1.5%); short-lane oscillation gain 3.75 / 3.29; epoch games 0.0 to +0.7% / 0.0 to +0.4%; polluted window settled 287 to 329 s / 288 to 331 s; base profiles 3-seed up50 154 / 150 s, down50 762 / 822 s, epoch30 88 / 88 s, hop10 245 / 233 s, polluted 75 / 76 s, steady std 0.042 / 0.053.
|
||||
Implementation (devnet-v4): `difficulty_v2_activation_daa` in `Params` (every network `u64::MAX`), `OverrideParams`, `override_params`, the daemon's file parser (prints the height), `SampledDifficultyManager` (new field, `reference_window(daa_score, epoch_blocks, activation)`), `REF_WINDOW_V2 = 600`, `IgneumInputs.k_ref`; `infra/fast-time/override-60x.json` carries the field as never. `cargo test --release -p kaspa-consensus --lib difficulty`: 15 pass (12 of 3 and 4 October plus `reference_window_switches_at_the_activation_height`, `v2_reference_window_follows_a_step_inside_the_epoch_where_v1_eases_into_it`, `v1_and_v2_agree_in_a_steady_epoch`); `-p kaspa-consensus-core --lib params`: 7 pass (`override_params_carry_the_difficulty_v2_activation`, the fast-time file test extended). Build 2 min incremental for `igneumd` and `igneum-miner`.
|
||||
Test network (`sim/difficulty/testnet_v2.py`, 3 nodes on 29600 to 29622, the 60x file with the devnet epoch, genesis bits 2^16, activation 900 on nodes 1 and 2, node 3 without it; CPU miners A from 0, B from minute 4, off at 19, back at 23): node 1 reached DAA 900 at 1,022 s; node 3 rejected the first v2 block ("difficulty of 520437997 is not the expected value of 520406991"), banned its peer and stayed at DAA 900 (901 headers, a prefix of node 1's 1,472); nodes 1 and 2 agreed on every header and the sink. Under v2 the leave eased 6,589 to 5,972 over 180 s (std 0.036, no peak), the rejoin hardened 6,154 to 8,312 within 60 s and held within 3%. The v1 phase is not readable: the load swung the CPU miners' delivered hash rate 2x on its own (difficulty fell 40% after B joined). Record `records/testnet-v2-2026-10-04.csv`. Repeat on a quiet machine, 30 minutes.
|
||||
Rollout: only `igneumd` changes (the Mac build, `infra/cross/build-linux.sh` for the seed and the Hetzner nodes, the Windows package for PC 1's node); every node of a chain needs the same `"difficulty_v2_activation_daa": N` in its override file before the height or it forks off there. First the 12 Hetzner nodes on their own chain (N = current DAA + 1,800, restart one by one, a miner joins inside an epoch, no flips after the height), then the devnet with N about two hours ahead: observer node, seed, Mac node 1, PC 1's node, in that order, by the project lead. A new network sets 0.
|
||||
Rollout: only `igneumd` changes (the Mac build, `infra/cross/build-linux.sh` for the seed and the Hetzner nodes, the Windows package for PC 1's node); every node of a chain needs the same `"difficulty_v2_activation_daa": N` in its override file before the height or it forks off there. First the 12 Hetzner nodes on their own chain (N = current DAA + 1,800, restart one by one, a miner joins inside an epoch, no flips after the height), then the devnet with N about two hours ahead: observer node, seed, Mac node 1, PC 1's node, in that order, by the founder. A new network sets 0.
|
||||
Not done: a quiet-machine test-network run; the DAG model's red blocks and the Mac's log series; v2 with +-500 ms stamp jitter.
|
||||
|
||||
## 4 October 2026, the observer stored nothing for 78 minutes, then 7,022 blocks in two minutes
|
||||
|
|
@ -856,7 +856,7 @@ first mismatch and are not a rate.
|
|||
|
||||
## 4 October 2026, shard proving on the RTX 5090: a full shard compressed in 10.9 s, a two-shard block aggregated in 2.2 s, all verified
|
||||
|
||||
Machine: the project lead's PC 2 (RTX 5090, 32,607 MiB; WSL2 Ubuntu 24.04, SP1 v6.8.1 with the cuda feature, the toolchain of the
|
||||
Machine: the founder's PC 2 (RTX 5090, 32,607 MiB; WSL2 Ubuntu 24.04, SP1 v6.8.1 with the cuda feature, the toolchain of the
|
||||
4 October morning run in `~/igneum-prove`), the Igneum Miner app (machine id 1ccfe586) stopping its miners for the
|
||||
run. Delivered as the signed job `shard-benchmark` (`app/igneum-app/src/jobrun.rs`, `packaging/ota/publish-jobs.sh`),
|
||||
which runs `prove-shard.sh block-338-shard1 "block-341-shards2 block-344-shards4"` and reports every RESULT line to the
|
||||
|
|
@ -1067,7 +1067,7 @@ first four minutes; the identity's votes on checkpoints 1202 and 1203 were accep
|
|||
discrete card takes part in finality. Machine id 37ba0461 in the console; app log run `win-37ba0461-20261004-185342`.
|
||||
## 4 October 2026 (evening), finality rule v3: the frozen weight table (F21) and the certificate fold (F22), simulator, unit tests, fast-time 3-node network with 300-ms links (finality engineer)
|
||||
|
||||
the project lead, 4 October 2026 evening: "we need to fix these serious issues before making things public". Both fixes sit behind one height switch, `finality_v3_activation_daa` (default never on every network, set by the override file like `difficulty_v2_activation_daa`), on branch `finality-fixes` of the node (worktree `vendor/igneum-node-finality`, from the proving head `8c0cff15`). Spec 03 Q4 (fold) and Q5 (frozen table), 3.3.1, 3.7 items 2 and 9, 3.10, 3.11; ledger F21 and F22 "Fix built, pending rollout"; the devnet plan in `docs/plans/finality-v3-rollout-devnet.md`. The live devnet was never touched; every network below ran on ports 29700 to 29799, suffix 970.
|
||||
The founder, 4 October 2026 evening: "we need to fix these serious issues before making things public". Both fixes sit behind one height switch, `finality_v3_activation_daa` (default never on every network, set by the override file like `difficulty_v2_activation_daa`), on branch `finality-fixes` of the node (worktree `vendor/igneum-node-finality`, from the proving head `8c0cff15`). Spec 03 Q4 (fold) and Q5 (frozen table), 3.3.1, 3.7 items 2 and 9, 3.10, 3.11; ledger F21 and F22 "Fix built, pending rollout"; the devnet plan in `docs/plans/finality-v3-rollout-devnet.md`. The live devnet was never touched; every network below ran on ports 29700 to 29799, suffix 970.
|
||||
|
||||
**F22, what was wrong.** The cloud logs of the healthy stretch 11:45 to 14:00 UTC (212 indices, 12 miners; `tools/finality-attacks/vote-timing.py`, output in `infra/cloud-devnet/results/2026-10-04/f22-vote-timing.md`): the node builds a certificate the instant the votes it holds meet Q3, median 1.24 s (p99 1.71 s) after the first node determined the checkpoint, with 7 to 10 of 12 signers (mean 8.27); 10.24 votes had been issued by then on average (two in flight: the miner's 1-s poll, the 250-ms gossip pump per hop, up to 289 ms RTT) and the last of the 12 was issued median 1.45 s, p90 2.36 s after the first determination. A 1-s hold after the first build would have carried all 12 votes at 192 of 212 indices; the other 20 are miners 01, 06 and 11 down together for 10 minutes (indices 377 to 396, the hop.sh restarts), an outage, not lag. There is no cut-off to lengthen: the fix is a second round. Presence needs nothing, since the block reading of Q2 credits a late vote once any block carries it.
|
||||
|
||||
|
|
@ -1094,7 +1094,7 @@ the project lead, 4 October 2026 evening: "we need to fix these serious issues b
|
|||
| split50, v3: the same cut | neither side locks during the split; heal; locking resumes on one chain; 0 conflicting certificates | 0 / 0 / 0 new locks during the 150 s (the v2 control locked at 126 s, so the frozen table held side B for the checkpoints of the last 24 s; the frozen table would have expired at 240 s); n0 redialled 72 s after the gate reopened; all three nodes resumed at index 7 and reached 13 inside the heal window; 0 conflicting certificates; 0 disagreeing locked indices; every post-heal LOCKED line names the frozen lock and its fraction (81 to 94% of the frozen table) | PASS |
|
||||
| split70, v3: 4/2 keys, the 4 side at 70% of weight (shares 0.175 x 4 against 0.15 x 2), 150 s | the 4 side locks during the split, the 2 side does not; 0 conflicts | 4 side: 4 new locks, the first 30 s after the cut; 2 side: 0; heal: all three at 17; 0 conflicting certificates; 0 disagreeing indices | PASS (6B at 70/30; exactly 4/6 is a knife edge under both rules, simulator row above) |
|
||||
|
||||
**What remains uncertain.** (1) The v3 split's hold was observed over the last 24 s of a 150-s split (the control crossed at 126 s); a longer split under the 240-s expiry (say 200 s) would show more held checkpoints, and the "held by the frozen table" line is logged at debug, which the runs did not enable. (2) No cloud rehearsal: the 12-node Hetzner network was destroyed at 15:30 UTC, so the 95% target is shown on three nodes with emulated 300-ms links and on the cloud logs' arithmetic, not on the cloud topology itself; the rollout plan names the re-creation and the partition experiment to run first. (3) The frozen reference is the node's own highest lock on the chain, not the certificate carried in C_i's past, so two honest nodes can test one checkpoint against tables 30 s apart; in a connected network those tables differ by a minute of blocks, under a partition both are pre-split, and no run showed a disagreement, but it is a property argued, not proved. (4) The price: a sudden departure of a third or more now pauses finality for a full window (30 days on mainnet) instead of 1.4 to 10 days; a gradual one costs nothing. the project lead asked for the pause over the fork; the number is stated in spec 3.7 item 2. (5) The fold clock is in memory: a restarted node folds from `daa(C_i) + depth`, a few seconds late at worst. (6) Binaries, all from `finality-fixes` 6aa69a45, hashes and checks in the rollout plan's section 2: Mac native `fe982a1d...` (verified running), Linux `7c100fc2...` (cargo-zigbuild, 34 min, not run on a Linux host), Windows `cc1d1001...` (mingw, 12 min 28 s, the v2 exe's DLL set, cannot run here); the Windows payload inputs were staged with `push-inputs.sh --no-deploy` into a scratch folder and NOT deployed (plan 7a).
|
||||
**What remains uncertain.** (1) The v3 split's hold was observed over the last 24 s of a 150-s split (the control crossed at 126 s); a longer split under the 240-s expiry (say 200 s) would show more held checkpoints, and the "held by the frozen table" line is logged at debug, which the runs did not enable. (2) No cloud rehearsal: the 12-node Hetzner network was destroyed at 15:30 UTC, so the 95% target is shown on three nodes with emulated 300-ms links and on the cloud logs' arithmetic, not on the cloud topology itself; the rollout plan names the re-creation and the partition experiment to run first. (3) The frozen reference is the node's own highest lock on the chain, not the certificate carried in C_i's past, so two honest nodes can test one checkpoint against tables 30 s apart; in a connected network those tables differ by a minute of blocks, under a partition both are pre-split, and no run showed a disagreement, but it is a property argued, not proved. (4) The price: a sudden departure of a third or more now pauses finality for a full window (30 days on mainnet) instead of 1.4 to 10 days; a gradual one costs nothing. The founder asked for the pause over the fork; the number is stated in spec 3.7 item 2. (5) The fold clock is in memory: a restarted node folds from `daa(C_i) + depth`, a few seconds late at worst. (6) Binaries, all from `finality-fixes` 6aa69a45, hashes and checks in the rollout plan's section 2: Mac native `fe982a1d...` (verified running), Linux `7c100fc2...` (cargo-zigbuild, 34 min, not run on a Linux host), Windows `cc1d1001...` (mingw, 12 min 28 s, the v2 exe's DLL set, cannot run here); the Windows payload inputs were staged with `push-inputs.sh --no-deploy` into a scratch folder and NOT deployed (plan 7a).
|
||||
|
||||
## 4 October 2026, miner performance: variant racing (Metal worker on the M5 Max; the RTX 5090 job is ready, not run)
|
||||
|
||||
|
|
@ -1553,7 +1553,7 @@ Reading (the NEW finding, ledger C4). With the module off GHOSTDAG alone converg
|
|||
|
||||
## 5 October 2026 (evening), the 9070 XT on the eGPU: why 17.9 MH/s, and what moved
|
||||
|
||||
PC 1 (ae432dc7, Windows 11, Ryzen 7 9800X3D with its gfx1036, RTX 5090 on CUDA), an AMD Radeon RX 9070 XT (gfx1201, RDNA 4) in a Sonnet Breakaway Box 850T5 over USB4, Adrenalin 26.9.2 (OpenCL driver string `3683.0 (PAL,LC)`, platform `OpenCL 2.1 AMD-APP (3683.0)`). Branch `opencl-rdna4`. the project lead: "the hashrate is low" (17.9 MH/s with one worker; two workers on the card earlier gave 8.9 and 9.4).
|
||||
PC 1 (ae432dc7, Windows 11, Ryzen 7 9800X3D with its gfx1036, RTX 5090 on CUDA), an AMD Radeon RX 9070 XT (gfx1201, RDNA 4) in a Sonnet Breakaway Box 850T5 over USB4, Adrenalin 26.9.2 (OpenCL driver string `3683.0 (PAL,LC)`, platform `OpenCL 2.1 AMD-APP (3683.0)`). Branch `opencl-rdna4`. The founder: "the hashrate is low" (17.9 MH/s with one worker; two workers on the card earlier gave 8.9 and 9.4).
|
||||
|
||||
**Before, from PC 1's own app log** (`node tools/logs.mjs win-ae432dc7-20261005-181046`, the miner's STATUS line for the card `amd:1:gfx1201`, 2^21-nonce jobs): `hash=17.82 MH/s wall (17.83 MH/s inside jobs) ... idle=0.3%`. Wall equals inside, so the host loop (template fetch, job line, read-back, scan) costs nothing measurable; the dispatch itself is slow. The worker's `ready` line: `exchange 0` (local memory: AMD lists `cl_khr_subgroups` and no shuffle extension), `batch 4194304`, `dataset-log2 28` (1 GiB), device `[1] gfx1201` on the 3683.0 platform, `AMD wavefront width 32`. The same card was listed again as `[3] gfx1201` on the older platform `3652.0` (the 32.0.21042 driver's OpenCL registration is still present after the update): that is the two-worker run.
|
||||
|
||||
|
|
@ -1589,12 +1589,12 @@ Reading: at the dataset size the card delivers about 2.5 G random 4-byte reads p
|
|||
| Card | 1024 MiB chase at 4,096 lanes | 1024 MiB chase ceiling | indep x8 ceiling | ceiling / 128 = hash ceiling | measured hash rate |
|
||||
|---|---|---|---|---|---|
|
||||
| RX 9070 XT, eGPU over USB4 | 2.64 G/s, 1,552 ns | 2.42 to 2.68 G/s | 2.42 G/s | 18.9 to 20.9 MH/s | 18.0 to 18.1 MH/s (bench), 17.8 (app) |
|
||||
| RTX 5090, PCIe 5 x16, contended | 9.09 G/s, 451 ns | 16.4 to 18.0 G/s | 16.2 to 16.7 G/s | 128 to 141 MH/s | 127 MH/s (app, the project lead), 139.7 alone (M11) |
|
||||
| RTX 5090, PCIe 5 x16, contended | 9.09 G/s, 451 ns | 16.4 to 18.0 G/s | 16.2 to 16.7 G/s | 128 to 141 MH/s | 127 MH/s (app, the founder), 139.7 alone (M11) |
|
||||
| Apple M5 Max, Apple OpenCL | 2.10 G/s, 1,949 ns | 3.41 to 3.49 G/s | 3.45 to 3.47 G/s | 26.6 to 27.3 MH/s | 27.9 Mhash/s (README, Apple OpenCL) |
|
||||
|
||||
Reading: on all three cards the hash runs within a few percent of 1/128 of the card's dependent random-read ceiling, which is what a 128-load program should do; the probe is a good model of the hash. The 5090 does 6.6x the random reads of the 9070 XT for 2.8x the rated bandwidth (1,792 against 640 GB/s, vendor figures): the rest is access granularity and DRAM behaviour on random 4-byte reads, which the kernel cannot change.
|
||||
|
||||
**Power, heat, fans and clocks, measured** (branch `opencl-rdna4-telemetry`; the project lead watched the 9070 XT at 90% usage with its fans barely turning and the app had no AMD reading, the MH/W line came from nvidia-smi only; a new helper `proto-opencl/gpu-telemetry.c` reads ADLX on Windows and the amdgpu sysfs on Linux. Job `tele-measure-1`, 20:27:45 to 20:29:41 UTC, both cards mining in the app, nothing touched: `igneum-gpu-telemetry -l 5` (sha256 `703cf69c…a9c69b`) and `nvidia-smi --query-gpu=index,name,power.draw,temperature.gpu,fan.speed,clocks.mem,clocks.gr,utilization.gpu -l 5` side by side, the app's `hash_now` every 5 s; `node tools/jobs.mjs tele-measure-1`):
|
||||
**Power, heat, fans and clocks, measured** (branch `opencl-rdna4-telemetry`; the founder watched the 9070 XT at 90% usage with its fans barely turning and the app had no AMD reading, the MH/W line came from nvidia-smi only; a new helper `proto-opencl/gpu-telemetry.c` reads ADLX on Windows and the amdgpu sysfs on Linux. Job `tele-measure-1`, 20:27:45 to 20:29:41 UTC, both cards mining in the app, nothing touched: `igneum-gpu-telemetry -l 5` (sha256 `703cf69c…a9c69b`) and `nvidia-smi --query-gpu=index,name,power.draw,temperature.gpu,fan.speed,clocks.mem,clocks.gr,utilization.gpu -l 5` side by side, the app's `hash_now` every 5 s; `node tools/jobs.mjs tele-measure-1`):
|
||||
|
||||
| Card | Samples | Watts (mean, min to max) | Temperature | Fan | Memory clock | Shader clock | Busy | Hash (mean of 24) | MH/W, measured |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
|
|
@ -1632,7 +1632,7 @@ Reading: the kernel is the same 116.0 ms on both paths (18.08 MH/s pure kernel,
|
|||
|
||||
**A second defect found on the way: the pack export race.** PC 1's app log since its 19:02 UTC restart (`node tools/logs.mjs win-ae432dc7-20261005-190232`): `worker error: error 0 pack packs\devnet: the epoch seed bytes do not give the pack's IGNEUM_SEEDW_INIT` at 19:07:03, 19:07:19 and 19:08:07, so the 9070 XT was not mining at all in the app while this entry was written (my job `rdna4-serve-1` at 18:43 hit the same folder in the same state). Cause, from `app/igneum-app/src/engine.rs` `prepare_worker`: one thread per card, each running `igneum-miner export-pack` into the one folder `packs\devnet`; across an epoch change the two exports interleave and the folder keeps one epoch's `program.h` with the other's `seeds.txt` until the next export. Fix on this branch: a process-wide mutex around both export sites (`EXPORT_LOCK`); the second export rewrites the same pack. Not measured in the app yet: it ships with the branch.
|
||||
|
||||
**Answer to the project lead.** The 9070 XT does 2.5 G random 4-byte reads per second from its memory for this access pattern, and the hash needs 128 of them, so about 19 MH/s is this card's ceiling for the current program class, on any slot; it was running at 92% of that. The eGPU link cost 6% per job through the read-back, now removed (17.87 against 16.88 MH/s inside jobs standalone). The duplicate platform that halved it to 8.9 + 9.4 is folded away. The pack race that stopped it is serialised. Nothing else in the worker's control moves the number: the next step for this card is the program class itself (fewer, wider loads per hash would favour AMD's 64-byte lines), which is a consensus question, not a worker one.
|
||||
**Answer to the founder.** The 9070 XT does 2.5 G random 4-byte reads per second from its memory for this access pattern, and the hash needs 128 of them, so about 19 MH/s is this card's ceiling for the current program class, on any slot; it was running at 92% of that. The eGPU link cost 6% per job through the read-back, now removed (17.87 against 16.88 MH/s inside jobs standalone). The duplicate platform that halved it to 8.9 + 9.4 is folded away. The pack race that stopped it is serialised. Nothing else in the worker's control moves the number: the next step for this card is the program class itself (fewer, wider loads per hash would favour AMD's 64-byte lines), which is a consensus question, not a worker one.
|
||||
|
||||
## 5 October 2026 (night), Ember Tune: the two-knob efficiency tune, the fleet prior, and what PC 1 could measure tonight (miner-community-lead)
|
||||
|
||||
|
|
@ -1658,7 +1658,7 @@ Branch `ember-tune` (54ff1bc), docs/plans/ember-tune.md. Every card tuned for MH
|
|||
| RX 9070 XT (bus 98, present again) | `tune 1 ... gmax 0 gmax_range -500 1000 plimit 0 plimit_range -30 10 factory 1 ok` | the helper's clock range is an OFFSET from stock in MHz, not a ceiling: a probe reading it as a 1,000 MHz maximum would have asked for `--set-gmax 900`, an overclock. Fixed at 054e041: an offset range closes the clock knob (until the stock clock is known) and the power ladder runs on the percent scale bounded by the range, so the 9070 XT's plan is 100, 90, 80, 70% (the -30 floor), 4 steps |
|
||||
| Radeon(TM) Graphics (integrated) | `tune 0 ... gmax - ... factory 0 ok` | no manual tuning: measure only, and it is off by default anyway |
|
||||
|
||||
**Run 2, 6 October 2026, 07:21 to 07:56Z (job ember-tune-pc1-2, elevated on the project lead's word, engine 25113f52..., PC 1 on 0.3.11):** the project lead answered the one prompt; the installed app stopped its miners at 07:21:16Z; the second engine ran for the whole 35-minute budget at "waiting, 0.00 MH/s" and no step ran. Cause: the playbook wrote the engine's copy of settings.json with PowerShell 5.1's `Set-Content -Encoding utf8`, which adds a UTF-8 BOM; the engine's JSON parser refuses it, `Settings::load` fell back to defaults (no payout address, no cards), the engine logged `[error] no payout address` and never started a miner. Run 1's scratch log carried the same line the night before. Readbacks, idle both times: the 5090 at 90.6 W before and 69.9 W after (2,505 then 2,407 MHz core, 14,001 MHz memory, limit 450 W of 575), the 9070 XT at factory (`gmax 0`, `plimit 0`). Nothing set on either card. The installed app's runner released the miners-stopped hold by itself on the failed exit (`job finished; the miners restart` at 07:56:50Z, both miners up by 07:57:04Z, `mining` at 07:57:29Z): mining paused 36 min 13 s. Fix 8273494: the copy is written without a BOM, the address is read back and the job fails within seconds if it is empty (`RESULT TUNE scratch settings: address ..., cards N, first bytes ...`), and the CI check fails any playbook writing JSON with `Set-Content -Encoding utf8`. The re-run needs one more click on the prompt.
|
||||
**Run 2, 6 October 2026, 07:21 to 07:56Z (job ember-tune-pc1-2, elevated on the founder's word, engine 25113f52..., PC 1 on 0.3.11):** the founder answered the one prompt; the installed app stopped its miners at 07:21:16Z; the second engine ran for the whole 35-minute budget at "waiting, 0.00 MH/s" and no step ran. Cause: the playbook wrote the engine's copy of settings.json with PowerShell 5.1's `Set-Content -Encoding utf8`, which adds a UTF-8 BOM; the engine's JSON parser refuses it, `Settings::load` fell back to defaults (no payout address, no cards), the engine logged `[error] no payout address` and never started a miner. Run 1's scratch log carried the same line the night before. Readbacks, idle both times: the 5090 at 90.6 W before and 69.9 W after (2,505 then 2,407 MHz core, 14,001 MHz memory, limit 450 W of 575), the 9070 XT at factory (`gmax 0`, `plimit 0`). Nothing set on either card. The installed app's runner released the miners-stopped hold by itself on the failed exit (`job finished; the miners restart` at 07:56:50Z, both miners up by 07:57:04Z, `mining` at 07:57:29Z): mining paused 36 min 13 s. Fix 8273494: the copy is written without a BOM, the address is read back and the job fails within seconds if it is empty (`RESULT TUNE scratch settings: address ..., cards N, first bytes ...`), and the CI check fails any playbook writing JSON with `Set-Content -Encoding utf8`. The re-run needs one more click on the prompt.
|
||||
|
||||
**Dry run 3, 6 October 2026, 14:56 to 15:02Z (job ember-dryrun-pc1-3, unelevated, no prompt, measure only; engine from ember-tune 07d5a72, kit sha256 36b522c9...):** the first measurement engine on PC 1 that mined. Both cards, one 60 s row each at the installed app's 80% cap, clocks unlocked, rate = the worker's STATUS wall rate, draw = nvidia-smi every 5 s:
|
||||
|
||||
|
|
@ -1669,7 +1669,7 @@ Branch `ember-tune` (54ff1bc), docs/plans/ember-tune.md. Every card tuned for MH
|
|||
|
||||
Nothing set; the installed app's miners back after 350 s. Why every earlier run (5 and 6 October, runs 1 to 4 and dry runs 1 and 2) read its copied settings as defaults, measured on PC 1 (collect ember-acl-2): the engine's own start locks its app folder with `icacls /inheritance:r /grant:r <user>:F`; cutting the folder's inheritance propagates down, the non-inheritable grant gives the children nothing, so a file COPIED in before the start (settings.json, machine-id, wallet.json) is left with no access entry and its owner cannot read it (`ReadAllText`: access denied), while the engine's own files written after the lock inherit fine, which hid it for a day. A first fix with `(OI)(CI)F /T` left the file empty too: `/T` re-applies `/inheritance:r` to each file after the propagation and an `(OI)(CI)` entry on a file is inherit-only. The right form is the inheritable grant without `/T` (07d5a72). Consequence for every tier on Windows: nothing changes for the installed app (its files were always its own); any tool that drops files into the app folder before the app starts (an installer's seed, a migration, a support script) was unreadable to the app until now and is readable from 0.3.13 on.
|
||||
|
||||
**Run 5, 6 October 2026, 15:28 to 15:39Z (job ember-tune-pc1-5, elevated on the project lead's click, PC 1 on 0.3.13, the tune engine = kit ember-kit-5 from 07d5a72, mode=direct):** the first run that set limits. The 5090's power ladder, 75 s a step, the clock unlocked (2,850 MHz core, 13,801 MHz memory), the rate = the worker's STATUS wall rate, the draw = nvidia-smi every 5 s:
|
||||
**Run 5, 6 October 2026, 15:28 to 15:39Z (job ember-tune-pc1-5, elevated on the founder's click, PC 1 on 0.3.13, the tune engine = kit ember-kit-5 from 07d5a72, mode=direct):** the first run that set limits. The 5090's power ladder, 75 s a step, the clock unlocked (2,850 MHz core, 13,801 MHz memory), the rate = the worker's STATUS wall rate, the draw = nvidia-smi every 5 s:
|
||||
|
||||
| Cap | Limit | MH/s | W | MH/W | GPU C |
|
||||
|---|---|---|---|---|---|
|
||||
|
|
@ -1679,12 +1679,12 @@ Nothing set; the installed app's miners back after 350 s. Why every earlier run
|
|||
| 70% | 403 W | 127.38 | 310.9 | 0.410 | 65 |
|
||||
| 60% (floor 400 W) | 400 W | 127.38 | 311.3 | 0.409 | 65 |
|
||||
|
||||
Reading: the cap does not bind on this hash (310 to 314 W under every limit, as the 4 October stability line said), so the power knob is flat at 0.41 MH/W on the 5090 and the saving must come from the clocks; the 90% and 80% rows' rate dips at the same draw are stalls inside those holds (a worker restart or a template wait), not the cap. The clock ladder's first step (2,781 MHz at 575 W) was requested at 15:37:47Z and never measured: the playbook's own watchdog killed the live engine at 15:39:03Z (all three cards mining at 177 MH/s) because its idle clause sampled one log line and read "idle" from a missing match; the 4070's and the 9070 XT's plans never ran. Consequences: the 5090 is probably left with its core clock locked at 2,781 MHz (an `-lgc` lock persists until `-rgc` or a reboot) under the 575 W cap, which costs little rate; freeing it needs administrator rights; and the Power Helper was NOT registered by this run (the registration lived only in the installed app's cap path, which a `--sweep` engine skips). Fixed the same hour: the watchdog's idle rule (three consecutive status lines reading 0.00 MH/s and 300 s, never a missing match), the `after` snapshot and the engine-log dump on every exit, and an elevated tune engine registering the task itself before its first step. The decided way out: the project lead switches Power control ON in the 0.3.13 app (its one prompt registers the task from the install folder), a job frees the clock through the task (`rgc`), the tune runs unelevated through the task.
|
||||
Reading: the cap does not bind on this hash (310 to 314 W under every limit, as the 4 October stability line said), so the power knob is flat at 0.41 MH/W on the 5090 and the saving must come from the clocks; the 90% and 80% rows' rate dips at the same draw are stalls inside those holds (a worker restart or a template wait), not the cap. The clock ladder's first step (2,781 MHz at 575 W) was requested at 15:37:47Z and never measured: the playbook's own watchdog killed the live engine at 15:39:03Z (all three cards mining at 177 MH/s) because its idle clause sampled one log line and read "idle" from a missing match; the 4070's and the 9070 XT's plans never ran. Consequences: the 5090 is probably left with its core clock locked at 2,781 MHz (an `-lgc` lock persists until `-rgc` or a reboot) under the 575 W cap, which costs little rate; freeing it needs administrator rights; and the Power Helper was NOT registered by this run (the registration lived only in the installed app's cap path, which a `--sweep` engine skips). Fixed the same hour: the watchdog's idle rule (three consecutive status lines reading 0.00 MH/s and 300 s, never a missing match), the `after` snapshot and the engine-log dump on every exit, and an elevated tune engine registering the task itself before its first step. The decided way out: the founder switches Power control ON in the 0.3.13 app (its one prompt registers the task from the install folder), a job frees the clock through the task (`rgc`), the tune runs unelevated through the task.
|
||||
|
||||
Consequence for the tiers: an AMD card is tuned on its power limit alone until its stock core clock is read (a 9070 XT at -30% is the floor the driver allows, 4 steps, 5 minutes); every NVIDIA card's two-knob plan waits on the user's one click on Power control; the re-run on PC 1 is held until the quit's source is named (the event-log collect) and follows the 0.3.11 rollout (the update clears the jobs folder, so the engine and the helper are fetched again), with the scheduler's slot.
|
||||
## 5 October 2026 (night), read width of the lottery hash: 4, 16 and 64-byte loads, a per-load mix, a written scratch; three cards (gate 1 experiment, cryptographer)
|
||||
|
||||
Branch `readwidth` (commits 019b014, b970dda, 4badcee, a9e002c, d0018cf and the entry commit); plan and recommendation in `docs/plans/read-width.md`. Nothing here changes consensus: every class sits behind `igneum-pow --class` and the default class is generator version 2 byte for byte (`igneum-pow/tests/packs.rs` passes on the four pinned packs after every commit). Question (the project lead, after "the 9070 XT on the eGPU" above): would wider reads keep the latency-bound random-access property while closing the vendor gap. Additions from the coordinator: a per-load width drawn from an era-fixed mix, and a written per-warp scratch (measurement only, no soundness claim).
|
||||
Branch `readwidth` (commits 019b014, b970dda, 4badcee, a9e002c, d0018cf and the entry commit); plan and recommendation in `docs/plans/read-width.md`. Nothing here changes consensus: every class sits behind `igneum-pow --class` and the default class is generator version 2 byte for byte (`igneum-pow/tests/packs.rs` passes on the four pinned packs after every commit). Question (the founder, after "the 9070 XT on the eGPU" above): would wider reads keep the latency-bound random-access property while closing the vendor gap. Additions from the coordinator: a per-load width drawn from an era-fixed mix, and a written per-warp scratch (measurement only, no soundness claim).
|
||||
|
||||
**What a class does** (`igneum-pow/src/generator.rs` `LoadClass`, `verify::fold_words`, the three emitters): a load of W words reads the W-word-aligned address `(src AND MASK) AND NOT (W - 1)` and folds every word into `dst` (`x = dst ^ w0; x = (rotl(x, 11) * 0x9e3779b1) ^ w[j]`); W = 1 is the lottery hash exactly (`w4` = pack `bcc1248b10cc90f2`). A mix class draws W per load with one extra `below(100)` roll per instruction. A scratch class `scr<k>k<kb>` turns `k` of the 16 memory slots into read-modify-writes of a 16-byte slot of the lane's share of a `kb` KiB per-warp scratch (kernels run persistent warps, one per block or work-group; a slot reads as a seed-and-base fill until the unit writes it, behind a per-unit tag). Program ids carry the class. Dependent chain and 32-lane unit unchanged.
|
||||
|
||||
|
|
@ -1862,7 +1862,7 @@ Commands: `IGNEUMD=vendor/igneum-node/target-txgossip/release/igneumd IGNEUM_MIN
|
|||
|
||||
## 5 October 2026 (night), the SP1 CPU prover on PC 1 beside the miners, and the backend survey: no zkVM proves on AMD (amd-prove agent)
|
||||
|
||||
the project lead, 22:50 BST: "test proving on the amd card?" and "can we test proving on mac?". The analysis with the backend table and the tier consequences: `docs/analysis/amd-proving.md`. The survey (SP1 v6.8.1 and `dev` 318dd530 of 28 Sep 2026, RISC Zero, Jolt, OpenVM, ICICLE, sppark; every claim cites a file or page there): on 5 October 2026 no zkVM proves on an AMD GPU; Apple silicon has RISC Zero's shipped Metal prover and ICICLE's Metal backend; SP1, the prover here, is CPU-only off NVIDIA.
|
||||
The founder, 22:50 BST: "test proving on the amd card?" and "can we test proving on mac?". The analysis with the backend table and the tier consequences: `docs/analysis/amd-proving.md`. The survey (SP1 v6.8.1 and `dev` 318dd530 of 28 Sep 2026, RISC Zero, Jolt, OpenVM, ICICLE, sppark; every claim cites a file or page there): on 5 October 2026 no zkVM proves on an AMD GPU; Apple silicon has RISC Zero's shipped Metal prover and ICICLE's Metal backend; SP1, the prover here, is CPU-only off NVIDIA.
|
||||
|
||||
Machine: PC 1 (machine ae432dc7), Windows 11, WSL2 Ubuntu 24.04 as root, 16 cores and 46,994 MB visible to the VM, the Igneum Miner app 0.3.9 mining on the RTX 5090 and the RX 9070 XT throughout (the 5090 at 89% mean utilisation, 59 to 70% minimum, from a 1-s `nvidia-smi` sampler under the run: the job never touched a card). Signed `run` job `cpu-prove-pc1-small2` (`tools/amd-prove/pc1-cpu-prove.ps1`), 20:49:00Z to 20:59:49Z: the hosted package `igneum-prove-wsl2-pv1b.zip` (sha256 df50dee5...) built WITHOUT the `cuda` feature (6 s warm; the first job `cpu-prove-pc1-small` built it cold in 126 s), `--mode id` the pinned pair (shard `0x2b1a81cb...`, aggregator `0x474678f3...`, pinned 2026-10-05T16:20:38Z), `SP1_PROVER=cpu`, `--mode shard --shard 0` under `/usr/bin/time -v`. Log: `node tools/jobs.mjs cpu-prove-pc1-small2 --all`.
|
||||
|
||||
|
|
@ -1878,7 +1878,7 @@ Reading, and the consequences (CLAUDE.md, every number). Doubling the cycles add
|
|||
|
||||
## Counter ASIC 2.0, the numbers
|
||||
|
||||
5 October 2026 (night). The chip-resistance layers measured on the three cards we own (Apple M5 Max, RTX 5090 on PC 1 and PC 2, RX 9070 XT on PC 1's eGPU), the decisions taken under the project lead's delegated rules for the devnet, and the chip model before and after. Every number is from an entry above or from the plan documents named; approximate is marked. Levels: `docs/plans/counter-asic-2-public.md`.
|
||||
5 October 2026 (night). The chip-resistance layers measured on the three cards we own (Apple M5 Max, RTX 5090 on PC 1 and PC 2, RX 9070 XT on PC 1's eGPU), the decisions taken under the founder's delegated rules for the devnet, and the chip model before and after. Every number is from an entry above or from the plan documents named; approximate is marked. Levels: `docs/plans/counter-asic-2-public.md`.
|
||||
|
||||
**Program class v3 (the devnet, activation by height switch `program_class_v3_activation_daa`)** = class v2's 128 x 4-byte loads, the era draw of the table layout and the working-set windows (layers 4 and 8), the cache growth rule (layer 6, option C: the cache doubles when the dataset doubles), the mixer at x8 (M16's multiplier), reserve family R1 (integer matrix, switched off) and the epoch length as a signalled reserve parameter (layer 9, 3,600 DAA s until a 90% signal). Not adopted on the measurements: wider reads (layer 1), the per-load width mix (layer 2), the per-warp write scratch (layer 3), the hot table (layer 5).
|
||||
|
||||
|
|
@ -1963,7 +1963,7 @@ Inputs, all RTX 5090 (PC 2), SP1 6.8.1 cuda: a full shard at the provisional `S_
|
|||
|
||||
Reading. The card count is the sum of card-seconds of work per block-second, rounded up, with no slack for the exclusive window, the relay or a card's idle gaps; the devnet's own numbers tonight (one card, 1.4 to 1.6 shards a minute, 2.4 to 4.7% of blocks) are the first row. Two levers, both measured tonight: the loop (a shard's carriage through export, cut and a 12-s key setup is 25 s on top of a 7-s proof; the host's `--mode aggregate` and `--mode chain` hold one key setup per process and the prover loop should do the same, the 0.3.11 item in the plan) and the card's other job (a mining card proves 3 to 4x slower than an idle one, `chain-pc2-pv1c` against 4 October; the prover's cost to mining is 4%). A fleet of 18 mining 5090s, or 6 proving-only ones, covers an empty-block chain at 1 block/s through the chain mode; the mandatory rule waits for the measured share to reach one, not for these rows.
|
||||
|
||||
### The 12 GB requirement (the project lead, 20:1xZ: "make sure we can prove on 12gb cards"): the GPU memory peak against SP1's knobs
|
||||
### The 12 GB requirement (the founder, 20:1xZ: "make sure we can prove on 12gb cards"): the GPU memory peak against SP1's knobs
|
||||
|
||||
Job `memsweep-pc2-pv1` (`tools/proving-v1/pc2-memory-sweep.ps1`), PC 2's RTX 5090 (32,607 MiB), the miners STOPPED by the job and the live prover switched off (its `sp1-gpu-server` would otherwise be the one the client connects to), every row: the server killed first, a 1-s `nvidia-smi memory.used` sampler, one `--mode compressed --shard 0` run of the pv1 host (`/opt/igneum-pv1`, SP1 6.8.1 cuda, `sp1-gpu-server` 6.8.1), 20:19 to 20:25Z. The knobs are the environment the GPU server inherits from the host process (`sp1-core-executor-6.8.1/src/opts.rs`: `SHARD_SIZE`, `ELEMENT_THRESHOLD`, `HEIGHT_THRESHOLD`, `MINIMAL_TRACE_CHUNK_THRESHOLD`, `TRACE_CHUNK_SLOTS`; `sp1-prover-6.8.1/src/worker/config.rs`: the `SP1_WORKER_NUM_*` and `*_BUFFER_SIZE` counts, defaults 4 core workers, 8 recursion prover workers). Idle card before the sweep: 1,732 MiB.
|
||||
|
||||
|
|
@ -2069,7 +2069,7 @@ Totals: 228 of 228 PASS where expected, 3 of 3 FAIL where built in. Reading: the
|
|||
|
||||
## 5 October 2026 (night), epoch length as an era parameter (Counter ASIC 2.0, layer 9): the Mac's compile-ahead per program
|
||||
|
||||
Branch `ca2-epoch`, worker "ca2-epoch"; design and the per-card table in `docs/plans/epoch-length.md`. Question (the project lead: "what about faster program changes?"): what a card spends per epoch between receiving the next seed and swapping, which sets the floor of the epoch-length ladder (600 to 7,200 DAA s). Machine: Apple M5 Max (Darwin 25.6.0, 64 GiB), 21:18 UTC, load average 11 to 14 from other agents' builds and runs; the measure lock held for the 3-s run (`tools/lock/with-lock.sh measure bash scratchpad/epoch-measure.sh`). `proto-metal/igneum-bench` built from this branch with `swiftc -O -target arm64-apple-macos11 -o igneum-bench main.swift -framework Metal` under a build slot.
|
||||
Branch `ca2-epoch`, worker "ca2-epoch"; design and the per-card table in `docs/plans/epoch-length.md`. Question (the founder: "what about faster program changes?"): what a card spends per epoch between receiving the next seed and swapping, which sets the floor of the epoch-length ladder (600 to 7,200 DAA s). Machine: Apple M5 Max (Darwin 25.6.0, 64 GiB), 21:18 UTC, load average 11 to 14 from other agents' builds and runs; the measure lock held for the 3-s run (`tools/lock/with-lock.sh measure bash scratchpad/epoch-measure.sh`). `proto-metal/igneum-bench` built from this branch with `swiftc -O -target arm64-apple-macos11 -o igneum-bench main.swift -framework Metal` under a build slot.
|
||||
|
||||
Ten distinct programs (seed strings `igneum-devnet-v4-epoch0`, `/epoch1` .. `/epoch9`; version 2 generator, 128 loads per hash), each generated and compiled at run time (`makeLibrary` from source plus `makeComputePipelineState`), dataset 2^28 words, one 2^20 batch and one verify warp per program:
|
||||
|
||||
|
|
@ -2158,7 +2158,7 @@ cautious 1.5x 0.43x, at the old 3x 0.86x; equal silicon 0.29x / 0.36x. dr368: 0.
|
|||
11 cores against 4.5), IBD over 108,000 headers is 8.8 min on one core (x8: 3.7); on a 2019-class laptop core
|
||||
(2.5x, approximate, O-1.14 unmeasured) 736 reads about 12 ms, over the gate, and 368 about 6.7 ms, under it. The
|
||||
build: the Mac pays 7 ms more per day (29 against 22 ms), nothing to any tier; the 5090 is the PC 2 job below;
|
||||
the 9070 XT is OWED (PC 1 is the project lead's desk today; its x8 build was 72 to 77 ms); the integrated gfx1036 tier
|
||||
the 9070 XT is OWED (PC 1 is the founder's desk today; its x8 build was 72 to 77 ms); the integrated gfx1036 tier
|
||||
already misses the per-prepare rule at x8 (epoch-length.md 6.1: 6.9 / 9.4 / 11.7 s prepares at x1, about 55 to
|
||||
94 s at x8, approximate) and the day program leaves that need (per-day dataset reuse in the workers, 0.3.12) the
|
||||
same in kind. The compile: the Metal item library is 0.75 to 0.8 s cold once a day and 1 ms from the shader cache;
|
||||
|
|
@ -2232,7 +2232,7 @@ Reading: the M5 Max stays latency-bound to about 100,000 ops per hash and its 5
|
|||
|
||||
Reading: the 5090 holds to 150,800 ops (-0.3 percent) and loses 2.7 percent at 199,600, under a 431 W cap that the control never reaches (342 to 357 W) and that binds from 102,100 ops up: the SM clock falls from 3,037 to 1,834 MHz and at 330,700 ops the card is compute-bound at the capped clock (28.6 T counted op/s, the 45.2 T budget scaled by the clock). The 5 percent point at 431 W is about 210,000 ops. The marginal ALU energy at the shipping clock, read on the three rungs under the cap: 10.2 to 13.2 pJ per counted op, twice the 5.5 pJ the chip model assumed. The 64-instruction block runs 3.5 percent above the control here too. Clock rows (`-lgc`): OWED, nvidia-smi refused the lock without administrator rights and the job did not ask for them. Power-cap rows: the 5 October sweep's (floor 400 W, so `-pl 200` and `250` cannot be set; the cap never binds at the control).
|
||||
|
||||
**RX 9070 XT (PC 1, ae432dc7)**: OWED (PC 1 is the project lead's desk and not released today); the OpenCL kernels are in every pack.
|
||||
**RX 9070 XT (PC 1, ae432dc7)**: OWED (PC 1 is the founder's desk and not released today); the OpenCL kernels are in every pack.
|
||||
|
||||
Consequences per tier (the file's section 8 in short): at the recommended N = 100,000 ops per hash (`sh256x27`) the Apple card loses 1.5 percent of its rate and pays 16 W more (income per watt 0.56x, per pound unchanged), the 5090 holds its rate at its 431 W cap (350 W at the control: per watt 0.81x, measured), the 9070 XT holds by its budget (owed), a rig pays about 30 percent more electricity for the same hash, a pool user sees nothing, and the `f = 1` chip's edge per joule falls from 1.6x to 0.9x against the M5 Max and from 5.6x to 2.1x against the 5090 at `k = 1`, where `k` is the chip core's energy per op over the 5090's measured 11 pJ: the number that decides the item. Verdict: GO as a class v4 candidate at N = 100,000 (`mx8+sh256x27`), subject to the 9070 XT row and the gates; NO-GO above 130,000 or with a block over 256 instructions. No card we own may lose more than 5 percent (the 2.0 rule): the M5 Max caps N at 130,000.
|
||||
## 6 October 2026, Counter ASIC 3.0 item 6: the reserve families' step costs
|
||||
|
|
@ -2283,7 +2283,7 @@ Reading of the Mac rows. The run-to-run spread is under 4% on every row. The dot
|
|||
|
||||
Reading of the 5090 rows. Every row is bit-exact, `mm8` included, so the m8n8k16 fragment layout of the CPU reference (PTX ISA 9.4 section 9.7.16.5.3) is the layout the hardware uses. The `alu` chain reads 7,941 G steps/s here against 8,754 through OpenCL event time on 5 October: a CUDA event pair around a 0.54 ms kernel carries about 0.05 ms of launch, which also compresses every ratio toward 1 (approximate: the ratios are the card's at the 2% level, not better). On this card every candidate costs more than the reference chain, unlike Apple: the 5090 runs the two-register add-xor-rotate chain at one IMAD and one funnel shift per step, and the three-register candidate chains pay their glue. Against the live `rotr` (1.32), the candidates read: `andn` 0.95x, `shl` 0.96x, `shr` 0.97x, `perm` 0.98x, `sel` 1.00x, `popc` 1.14x, `shfla` 1.16x (the same as the live xor shuffle, 1.49: the indexed shuffle costs NVIDIA nothing extra), `bfe` 1.17x, `clz` 1.23x. `bfe.u32` and the C form cost the same to the nanosecond (0.835 ms), so the compiler emits the same code for both and no single-instruction bit-field extract is in play on this architecture (not checked by cuobjdump; the equal times are the evidence). `dp4a` reads 1.16x (1.17x on 5 October). `mm8` is the most expensive row on NVIDIA too (2.43x the reference: one tensor-core mma per warp per dependent step, latency-bound), which supports its place at the end of the reserve on the honest-card side as well as on the chip side.
|
||||
|
||||
**RX 9070 XT (PC 1, ae432dc7), OpenCL**: OWED. PC 1 is the project lead's desk and not released today (the brief's rule); the OpenCL twin of the probe (`__builtin_amdgcn_*` paths for `v_bfe_u32`, `v_perm_b32`, `v_bcnt_u32_b32`, `v_cndmask_b32`, `ds_bpermute_b32`) is the next job on that card.
|
||||
**RX 9070 XT (PC 1, ae432dc7), OpenCL**: OWED. PC 1 is the founder's desk and not released today (the brief's rule); the OpenCL twin of the probe (`__builtin_amdgcn_*` paths for `v_bfe_u32`, `v_perm_b32`, `v_bcnt_u32_b32`, `v_cndmask_b32`, `ds_bpermute_b32`) is the next job on that card.
|
||||
|
||||
Consequences per tier, Mac rows (the hash is latency-bound by 128 dependent DRAM reads; a family at `W_new` = 4 points is about 4% of the 64 instructions, so these per-op costs bound a family's hash-rate cost and are not hash rates; the 5% rule of 1.13.2 is argued from them, not measured, until a family is live):
|
||||
|
||||
|
|
@ -2348,7 +2348,7 @@ Cause: `ProvingState.paid_wei: u128` and serde_json `to_value` (1.0.151, `value/
|
|||
|
||||
## 5 October 2026 (night), aggregation cost on the RTX 5090: what a per-block aggregation spends and what each lever gives (proving engineer, agg-cost)
|
||||
|
||||
the project lead, 5 October 2026: "fix everything else in the numbers tonight". The number under test: the chained segment aggregation cost 9.6 to 9.7 s a block on PC 2's 5090 while the card mined (`chain-pc2-pv1c`, the entry above), 2.2 s on 4 October with the card to itself. Target: under 3 s a block, the miner's slowdown of the prover under 1.5x, the proof statement unchanged. Branch `agg-cost` (worktree `igneum-wt-agg-cost`, from `proving-v1` 219517f). Host changes (statement untouched, `elf/` untouched): the aggregation's stdin build timed apart from the prove call, the deferred-proof count and the SP1 knobs in the RESULT lines, `--mode chain --save-shards` (every shard's compressed proof written next to the results, so `--mode aggregate` re-runs the same proofs under other settings). Jobs: `agg-cost-pc2-1` (21:01:20Z to 21:25:11Z, `tools/proving-v1/pc2-agg-cost.ps1`, the package `igneum-prove-wsl2-aggcost.zip` fetched by `fetch-prove-aggcost` 20:55:39Z, built in WSL2 against the live target dir in 5 s, installed to `/opt/igneum-aggcost`, the live `/opt/igneum` untouched, `--mode id` the pinned pair) and `agg-cost-pc2-2` (21:34:00Z, the same script). The live prover was switched OFF for the runs (its sp1-gpu-server would otherwise be shared through `/tmp/sp1-cuda-0.sock` and carry its own environment; `gpu_server_before running=0`) and ON again at the end. Fixtures: four consecutive live blocks cut from PC 2's own node (86165..86168 at tip 86195, one empty shard each, every one MATCHES natively), the same four for every phase of job 1. App 0.3.9 on PC 2 throughout.
|
||||
The founder, 5 October 2026: "fix everything else in the numbers tonight". The number under test: the chained segment aggregation cost 9.6 to 9.7 s a block on PC 2's 5090 while the card mined (`chain-pc2-pv1c`, the entry above), 2.2 s on 4 October with the card to itself. Target: under 3 s a block, the miner's slowdown of the prover under 1.5x, the proof statement unchanged. Branch `agg-cost` (worktree `igneum-wt-agg-cost`, from `proving-v1` 219517f). Host changes (statement untouched, `elf/` untouched): the aggregation's stdin build timed apart from the prove call, the deferred-proof count and the SP1 knobs in the RESULT lines, `--mode chain --save-shards` (every shard's compressed proof written next to the results, so `--mode aggregate` re-runs the same proofs under other settings). Jobs: `agg-cost-pc2-1` (21:01:20Z to 21:25:11Z, `tools/proving-v1/pc2-agg-cost.ps1`, the package `igneum-prove-wsl2-aggcost.zip` fetched by `fetch-prove-aggcost` 20:55:39Z, built in WSL2 against the live target dir in 5 s, installed to `/opt/igneum-aggcost`, the live `/opt/igneum` untouched, `--mode id` the pinned pair) and `agg-cost-pc2-2` (21:34:00Z, the same script). The live prover was switched OFF for the runs (its sp1-gpu-server would otherwise be shared through `/tmp/sp1-cuda-0.sock` and carry its own environment; `gpu_server_before running=0`) and ON again at the end. Fixtures: four consecutive live blocks cut from PC 2's own node (86165..86168 at tip 86195, one empty shard each, every one MATCHES natively), the same four for every phase of job 1. App 0.3.9 on PC 2 throughout.
|
||||
|
||||
Known-finished case of the host changes before the GPU (this Mac, CPU, run lock, 20:41Z to 20:44Z): `--mode chain` over `fixtures/chain/block-81046.json` with `--save-shards` (shard 38.5 s, aggregate 43.4 s, the proof file written), then `--mode aggregate` over that saved shard proof with `SP1_WORKER_VERIFY_INTERMEDIATES=false` (46.6 s, the same statement `0x3dedb8ea...`), `--mode verify-segment` VERIFIED in 0.027 s; known-failed: a wrong statement NOT VERIFIED in 0.027 s. Unit tests: `cargo test --release -p igneum-prove-core -p igneum-prove-host`: core 8 passed, host 9 passed and 1 ignored (build lock, 20:53Z).
|
||||
|
||||
|
|
@ -2652,3 +2652,49 @@ in the same shape and reports a box behind its wanted binary.
|
|||
| Rig | the same, and a rig that leaves is itself a weight removal: at 459 MH/s on tonight's devnet it is about 20 percent of the weight, over the hour's budget by itself |
|
||||
| Pool | a pool node is one voter carrying its members' whole weight; a pool restart is the largest single removal on the network and must be sliced like the fleet's |
|
||||
| The network | finality by miner weight is only as steady as the miners' uptime; until public hash dwarfs the fleet, the fleet's supervisor is a consensus component |
|
||||
|
||||
## 7 October 2026, the first 16 GB card: an RTX 5060 Ti in a Thunderbolt enclosure on PC 2 (branch bench-5060ti)
|
||||
|
||||
Machine: PC 2 (`1ccfe586`, Windows 11), an ASUS Dual GeForce RTX 5060 Ti (16 GB GDDR7, Blackwell sm_120, PnP `PCI\VEN_10DE&DEV_2D04&SUBSYS_8A111043`) in a Razer Core X V2 Thunderbolt enclosure ("USB4 Router (2.0), Razer - Core X V2", bus `0B:00.0`), beside the RTX 5090 on its own supply; NVIDIA driver 610.47 (WDDM 32.0.16.1047, the 5090's driver, nothing installed for the new card); the installed app 0.3.19 and its own `igneum-worker-cuda.exe` (NVRTC 12.8). Jobs `fetch-5060ti-packs-20261007` (the kit: `tools/bench-5060ti/make-kit.sh`, the class v4 pack at sub-version 1 and the v3 control, sha256 `fd8393ed...`, 105,892 bytes) and `run-5060ti-bench-20261007-b` (`tools/bench-5060ti/pc2-5060ti-bench.ps1`, 14:44:19Z, ran 14:45:05 to 14:58:11Z, exit 0; the 5060 Ti alone through the runner's `--cards-off`, the 5090 mining throughout; run `-a` died in 1 s on an argument-binding fault in the nvidia-smi query and is void). PC 2 lost power twice that day, so the job WRITES NO POWER LIMIT: it reads `power.limit` against `power.default_limit` (180 W = 180 W, range 150 to 198 W) and the row says `limit_is_stock=yes`. Read back with `node tools/jobs.mjs run-5060ti-bench-20261007-b`.
|
||||
|
||||
**Detection** (the app's first poll after the restart, run `win-1ccfe586-20261007-143611`, 14:36:16Z): `GPUs: NVIDIA GeForce RTX 5090 (CUDA); NVIDIA GeForce RTX 5060 Ti (CUDA); AMD Radeon(TM) Graphics (OpenCL, gfx1036)` and `cards: NVIDIA GeForce RTX 5090 [discrete, off] | NVIDIA GeForce RTX 5060 Ti [discrete, off] | ...`; the app started a miner on it by itself (`nvidia-1ccfe586-2`, `--device 1`, 8 identities, the default). The kind reads `discrete`, not `external`: the app does not know it is an eGPU. nvidia-smi in the job: index 1, 16,311 MiB, PCIe link gen 4 x4 current against gen 4 x16 maximum (the Thunderbolt link: a quarter of the slot's lanes), 43 C idle. The freeze lane's cause class for the 15:10 UK hang on the first boot with the card: not the card (no TDR, no Thunderbolt or PCIe link event; Kernel-Power 41 + 6008, no bugcheck, the power shape again).
|
||||
|
||||
**G1 and the window** (the installed CUDA worker, `--bench --batch-log2 24 --block-warps 1`, the card alone, `CUDA_VISIBLE_DEVICES` on its UUID so every row names the device; nvidia-smi every 2 s on the card, the loaded samples at utilisation 90 percent and over):
|
||||
|
||||
| Pack | Dispatches of 2^24 | Self-test | Fingerprint 2^24 at base 0 | MH/s |
|
||||
|---|---|---|---|---|
|
||||
| mx8-devnet-epoch0 (the class v3 control) | 5 | PASS | 90f794dd556f7a3b (= the control everywhere) | 30.895 |
|
||||
| v4-devnet-epoch0 (class v4, sub-version 1, program id 1a4230699a6b9c60) | 5 | PASS | 867dbc45cfb36b4d (= Metal, Apple OpenCL, the RTX 5090) | 30.879 |
|
||||
| v4-devnet-epoch0, the 10-minute window at the stock limit | 1,105 (602 s) | PASS | 867dbc45cfb36b4d | 30.882 |
|
||||
|
||||
| Row | Value |
|
||||
|---|---|
|
||||
| NVIDIA RTX 5060 Ti 16 GB, class v4, CUDA (NVRTC), driver 610.47, PCIe 4.0 x4 through the enclosure | 30.9 MH/s over 10 minutes on the card alone |
|
||||
| Watts at the stock limit (180 W default, unchanged) | 114.8 W mean, 115 W p50 over the window; 0.269 MH/W; SM 2,753 MHz, memory 13,801 MHz, 60 C maximum |
|
||||
| The class v4 shadow against the control | 0.1 percent (the 5090 paid 0.2, the 9070 XT 3, the B580 0.1) |
|
||||
| The efficient point | OWED to the app's Ember Tune: nothing set by the job; PC 2's Power Helper refused every request since the restart ("the helper did not run sequence 0 within 15 s", 14:39Z), so no ladder ran on either card |
|
||||
| Prove beside the miner (16 GB tier) | BLOCKED, not measured: the shipped WSL2 host (sha `71bc2438...`) carries no `IGNEUM_CUDA_DEVICE` selector, so aimed at anything it proves on CUDA device 0 (the 5090) through the app's own socket `/tmp/sp1-cuda-0.sock`; the selector lives in the prover-floor host (`proof_system.rs`, branch prover-floor) and is the owed cut. The job's inventory: the floor server IS on PC 2 (`/opt/igneum-floor/bin/sp1-gpu-server`, 6.8.1 build `e911facb...`, 166,665,880 bytes) beside the stock one (`~/.sp1/bin`, `c2642ad1...`), WSL sees the card as CUDA device 1 |
|
||||
| Card-picker entry (`site/yourcard.js`) | `['NVIDIA RTX 5060 Ti', 30.9]`, added; the public table row in `site/miner-bench.json` |
|
||||
|
||||
Against the 5090 on the same PC (122 MH/s at 308 W, 0.396 MH/W): 25.3 percent of its hash at 37 percent of its draw, 68 percent of its hash per watt. The dependent-read ceiling was not probed (the memprobe step is not in this job); at 128 loads a hash 30.9 MH/s is 3.95 G dependent reads a second, between the 9070 XT (2.4 to 2.7 G) and the 5090 (16 to 18 G).
|
||||
|
||||
Consequences per tier (the rule of 5 October 2026): a 5060 Ti owner (16 GB, Windows) mines at 30.9 MH/s and 115 W from the box with nothing to set: about 5,100 blocks a day at the 522 MH/s the devnet showed at 14:44Z (one every 17 s, approximate: the network rate moves), about a quarter of a 5090 owner's 20,200, for 2.76 kWh a day (£0.79 at 28.5 p against the 5090's £2.11); through a Thunderbolt enclosure the x4 link costs nothing measurable (the hash is bound by the card's own memory latency, not the link; the 5090's PCIe-slot rows are the comparison), so a laptop with a Thunderbolt 4 port and this enclosure is a 31 MH/s miner. The 8 GB 5060 Ti: the same hash is the expectation (the 1 GiB dataset fits), a line owed. Proving on the 16 GB tier: the fleet's 4060 Ti 16 GB row (9.0 GB peak beside the miner on the patched server) says this card would mine and prove with about 7 GB spare, approximate until the host with the device selector ships; today the app's prover default leaves it off ("a full shard needs a 24 GB card") and the measured read is owed to the prover-floor host cut. Linux and HiveOS take the same CUDA worker (owed a line). What the lane does next: the prover-floor host's selector into the shipped WSL2 bundle, then the prove-beside read on this card; the Power Helper fault on PC 2 to the Ember lane (no efficient point on any PC 2 card until it answers).
|
||||
|
||||
Found on the way: inside a PowerShell `@( ... )` the comma binds before `+`, so `'--query-gpu=' + $f, '--format=csv'` is one argument (run a, void in 1 s; the query string is built first now); a bare string inside a function that also returns a value is swallowed into the caller's variable (the sampler line; `[Console]::Out.WriteLine` now); the app's `kind` for a Thunderbolt card reads `discrete` (a word for the Cards page to earn: `external`, which the state already names).
|
||||
## O-1.14: the CPU verifier on a 2019-class core (attack pass F6, 7 October 2026, 09:49 UK)
|
||||
|
||||
Rented Vast instance 54613164, Intel Core i7-9700K at 4,170 MHz as read, one core, the box-built Linux `igneum-pow`
|
||||
(sha256 6d286783...), `bench --seed igneum-genesis --day 2026-10-03 --warps 50`. Ms per warp, cold max / average of 50:
|
||||
v2 1.582 / 1.280; mx8 5.394 / 5.267; mx8+sh256x27 (class v4) 6.334 / 6.006; dr368 5.540 / 5.426; dr736 10.290 / 10.042
|
||||
(fails the 10 ms gate, the known-fail). Cache fill 276 ms. Log `docs/analysis/attack-pass/o114-i7-9700K-2026-10-07.log`;
|
||||
record `docs/analysis/attack-pass-2026-10.md` row F6. Class v4 passes a real 2019-class core with 3.7 ms to spare; the
|
||||
half-core proxy (8.23 ms) stays the standing pessimistic rule for the ladder's ceiling.
|
||||
|
||||
## F6: the verifier's worst case over 10^5 class v4 programs (attack pass, 7 October 2026, 13:5x UTC)
|
||||
|
||||
igneum-build-1, cores 40 (one-core proxy) and 88 (the half-core proxy, both SMT siblings busy) under the per-core lease,
|
||||
core 40 at a median 3,799.9 MHz. 100,000 programs ranked by exact op counts; 50,000 timed cold on core 40 (min / median /
|
||||
p99 / max 4.610 / 4.948 / 5.606 / 6.194 ms per warp); the worst 200 re-timed at 10 cold reps on both proxies and the worst
|
||||
1,000 on the half-core at 2 reps, the worst 10 at 20: worst half-core cold max 8.708 ms (`attack-f6/87142`), then 8.629
|
||||
(`attack-f6/88521`), 8.414 (`attack-f6/15781`); the genesis program 8.624. Gate 10 ms: PASS by 1.29 ms. Record
|
||||
`docs/analysis/attack-pass/f6-verifier.md`; logs `/srv/builds/igneum-wt-attack/target-attack-f6/phase2b.log`, `phase2c.log`.
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ key of 8.1 is the operator's own step, on the file.
|
|||
| PC 2's 5090 rows | the card-off step could not confirm a stopped worker (`api/state` answered `{}`), and the numbers are half the card's | the morning's 5090-only run on PC 2 with the compute-apps confirmation; until then the rows are "beside the live miner" |
|
||||
| PC 2's result files | `repro.ps1`'s close threw `System.OutOfMemoryException` in ConvertTo-Json and gave Set-Content an empty path: PowerShell variable names are case-insensitive, the result table `$Cpu` held `$cpu` (its own name string) and so contained itself, and the markdown lines `$md` wiped the markdown path `$Md`. Fixed (distinct names; `bench/jobs/ps-case-check.sh` fails CI on any case-only pair, shown to fire on a bad file); the RESULT lines in the intake and the three transcript logs are the record | the morning's run writes the files |
|
||||
| The prover on PC 2 | the first script read the prover's state from `api/state` too, saw nothing, and left the live prover off from 00:49 to the restore job (run-prover-on-pc2-20261006); the script now reads settings.json and restores unconditionally | done tonight; the rule in the job |
|
||||
| The reward | the amount and payer are `docs/plans/funding.md`, not funded; the terms are quoted unchanged | the project lead's decision |
|
||||
| The reward | the amount and payer are `docs/plans/funding.md`, not funded; the terms are quoted unchanged | the founder's decision |
|
||||
|
||||
## 8. The vendor-share metric (Counter ASIC 3.0 item 7)
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ Today's devnet, read-only from the live tables (dry mode, 07:36 UTC, 6 October 2
|
|||
|
||||
| Vendor | fleet-reported MH/s (workers) | chain-attributed share of blue blocks (10 min) | chain-attributed MH/s at the 135.8 MH/s estimate | Note |
|
||||
|---|---|---|---|---|
|
||||
| NVIDIA | 120.61 (1: PC 2's RTX 5090, with the prover on the card) | 0.986 (552 of 560) | 133.86 | PC 1's RTX 5090 was off the network at the reading (the project lead's desk) |
|
||||
| NVIDIA | 120.61 (1: PC 2's RTX 5090, with the prover on the card) | 0.986 (552 of 560) | 133.86 | PC 1's RTX 5090 was off the network at the reading (the founder's desk) |
|
||||
| AMD | 0 (0) | 0 | 0 | the RX 9070 XT is on PC 1, off at the reading |
|
||||
| Apple | 0 (0) | 0 | 0 | the M5 Max is paused for measurements |
|
||||
| Intel | 1.69 (1: the Windows laptop's UHD Graphics) | 0.014 (8 of 560) | 1.94 | the first outside machine, which carries the intake key |
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ shard run reported as exit 0, 7a7e873).
|
|||
| Date | Symptom | Cause | Fix | Proven by |
|
||||
|---|---|---|---|---|
|
||||
| 4 Oct 2026 | Every `ci` run on master red since 67bf226 (eleven pushes), unnoticed | `sim/difficulty/records/testnet-v2-2026-10-04.schedule.log` carried a home path; `.log` was outside the identity scrub's extension list in `tools/ci/identity-check.sh` (and in the mirror's `tools/sync.sh`) | 2996cca: `.log` scrubbed like the other text files; the record rewritten with `~`; the same list in igneum-public `tools/sync.sh` (local commit e18256d, not pushed) | `bash tools/ci/identity-check.sh` 0 hits locally; run 37226816xxx on master green |
|
||||
| 5 Oct 2026 | PC 1 (Windows 11 Pro 26200, default terminal Windows Terminal 1.24): "Windows Command Processor" windows whenever a remote job runs (the project lead) | measured, not guessed: `tools/windows/console-watch.ps1` (job run-20261005-182528) started every candidate child from the app's job runner, whose console is headless (`conhost.exe 0x4`, hwnd 0), with a user32 EnumWindows sampler every 30 ms: powershell, cmd, query, curl, nvidia-smi, wsl --status, a distro, interop cmd and powershell, `powershell -WindowStyle Hidden`, `Start-Process -WindowStyle Hidden`: 0 windows each; `Start-Process cmd` in a new console: a Terminal window and a cmd PseudoConsoleWindow (the known-failed case fires). The 25-minute background watcher (console-watch-bg.ps1, run-20261005-184330, 18:44 to 19:09 UTC, every 200 ms) across an app restart, a build job, two run jobs, two collect jobs and the sweep helper's elevated launch at 19:04:43: 0 console or Terminal windows, 69 conhost starts (every one `conhost.exe 0x4`, headless, under curl, wsl, wslhost, powershell), 1 cmd.exe (under wslhost, WSL interop, no window). The one road that creates a console of its own is the elevated launch (`Start-Process -Verb RunAs`, the AppInfo service: the power cap, the sweep helper, the clock sync, an elevated job); it carried `-WindowStyle Hidden` in four copies, and "Windows Command Processor" is also the name on the UAC prompt the engine raises for cmd.exe (the sweep helper prompted at 17:00, 17:30 and 18:12 UTC, the power cap at every start; the elevated watcher's own prompt, run-20261005-184610, timed out unanswered at 122 s) | `platform::elevated_ps_line` + `elevated_command`: one builder for every elevated launch, hidden by construction, exit 251 when the prompt is refused; the elevated job wrapper reports its own console (`elevated console: hwnd N visible False`) on every elevated job; `tools/ci/windows-spawn-check.mjs` fails CI on a Command::new without the quiet flag, a creation_flags other than CREATE_NO_WINDOW, a Start-Process without -WindowStyle Hidden/-NoNewWindow, or a host.cpp spawn without CREATE_NO_WINDOW / SW_HIDE | the watcher's known-failed case (2 windows) and known-finished case (0); the CI check's self-test (9 cases) and the tree (0 hits); the igneum-app test suite on PC 1 |
|
||||
| 5 Oct 2026 | PC 1 (Windows 11 Pro 26200, default terminal Windows Terminal 1.24): "Windows Command Processor" windows whenever a remote job runs (the founder) | measured, not guessed: `tools/windows/console-watch.ps1` (job run-20261005-182528) started every candidate child from the app's job runner, whose console is headless (`conhost.exe 0x4`, hwnd 0), with a user32 EnumWindows sampler every 30 ms: powershell, cmd, query, curl, nvidia-smi, wsl --status, a distro, interop cmd and powershell, `powershell -WindowStyle Hidden`, `Start-Process -WindowStyle Hidden`: 0 windows each; `Start-Process cmd` in a new console: a Terminal window and a cmd PseudoConsoleWindow (the known-failed case fires). The 25-minute background watcher (console-watch-bg.ps1, run-20261005-184330, 18:44 to 19:09 UTC, every 200 ms) across an app restart, a build job, two run jobs, two collect jobs and the sweep helper's elevated launch at 19:04:43: 0 console or Terminal windows, 69 conhost starts (every one `conhost.exe 0x4`, headless, under curl, wsl, wslhost, powershell), 1 cmd.exe (under wslhost, WSL interop, no window). The one road that creates a console of its own is the elevated launch (`Start-Process -Verb RunAs`, the AppInfo service: the power cap, the sweep helper, the clock sync, an elevated job); it carried `-WindowStyle Hidden` in four copies, and "Windows Command Processor" is also the name on the UAC prompt the engine raises for cmd.exe (the sweep helper prompted at 17:00, 17:30 and 18:12 UTC, the power cap at every start; the elevated watcher's own prompt, run-20261005-184610, timed out unanswered at 122 s) | `platform::elevated_ps_line` + `elevated_command`: one builder for every elevated launch, hidden by construction, exit 251 when the prompt is refused; the elevated job wrapper reports its own console (`elevated console: hwnd N visible False`) on every elevated job; `tools/ci/windows-spawn-check.mjs` fails CI on a Command::new without the quiet flag, a creation_flags other than CREATE_NO_WINDOW, a Start-Process without -WindowStyle Hidden/-NoNewWindow, or a host.cpp spawn without CREATE_NO_WINDOW / SW_HIDE | the watcher's known-failed case (2 windows) and known-finished case (0); the CI check's self-test (9 cases) and the tree (0 hits); the igneum-app test suite on PC 1 |
|
||||
| 4 Oct 2026 | `collect-pc1-board3` printed PowerShell parse errors (`.Name`, `.AdapterRAM`) | the publishing shell expanded `$_` inside double quotes to nothing before the command reached the jobs file; nothing to do with Format-List or Out-String (board2 and board4 printed their values) | publish-jobs.sh refuses a collect command that pipes into a script block without `$_` or `$PSItem` | the eaten form refused with the reason, the single-quoted form published to a test folder |
|
||||
| 4 Oct 2026 | the same job reported `done (exit 0)` over `command exit Some(1)` | `run_collect` in `app/igneum-app/src/jobrun.rs` builds `Done` from the upload count only; the command's exit code is logged and dropped | branch `bugfix-collect-exit`, 35ccdc8 rebased on c257444 (app engine; merge by the main session) | `cargo test --bin igneum-app`: all 28 tests pass on the rebased branch; the new one covers the board3 shape (`Some(1)` is failed exit 1), `Some(0)` done, the cap as timeout, failed uploads still failing |
|
||||
| 4 Oct 2026 | `publish-jobs.sh --deploy` said "not reachable, differs from the local one, or does not verify yet" after a deploy that had succeeded | one check the instant the CLI returned, while the edge still served the previous file; the deploy's own exit status was hidden by `\|\| true` | `verify_live`: up to `--tries` (12) checks 5 s apart, each failure names its condition; `publish-jobs.sh verify` re-checks on its own; a failed deploy stops before the check | finished: `verify --tries 2` against the live file (try 1 of 2); failed: a local server with an older file ("differs", both publish stamps named) and a closed port ("is not reachable") |
|
||||
| 4 Oct 2026 | console Machines: PC 37ba0461 showed 0.0 MH/s and 0 accepted while its log held an accepted block at 1 MH/s | `parseLabel` in the console API knew nvidia, amd, mac, metal and opencl; the OpenCL fallback on an iGPU is labelled `other-<id8>-n` and the card was dropped | parsers moved to `relay/lib/parse.mjs`, vendors `other` and `intel` added, `node --test relay/test/parse.test.mjs` in CI | the test; the live console after the deploy shows the card |
|
||||
| 4 Oct 2026 | console Machines: a card said "117.2 MH/s now" while its "status" column said 4 m ago (PC 2 during shard run 3: the prover held the GPU and the worker's STATUS line stopped) | the card's hash came from the last STATUS line in the tail with no age check; the machine total summed it | `markStale`: a card whose STATUS line is older than 120 s is `stale`, shown as "last N MH/s" with a red "stale" mark, and left out of the machine total (API, page and `tools/console.mjs`) | the test (58 s fresh, 240 s stale, none stale); the live console after the deploy |
|
||||
| 4 Oct 2026 | `vercel env add` from `site/` fails with "Could not retrieve Project Settings" | `site/.vercel/project.json` links the [other-business] team's `igneum` project; the live site (igneum.network, igneum.com, the GitHub integration) is the `igneum` team's project of the same name, which the igneum login reads and the [other-business] link does not | documented in `packaging/README-ship.md` (link, env ls, env add, deploy); no env set | `env ls` from a scratch link to the igneum-team project lists the two names; a branch push produced `igneum-git-<branch>` |
|
||||
| 4 Oct 2026 | `vercel env add` from `site/` fails with "Could not retrieve Project Settings" | `site/.vercel/project.json` links the other business's team's `igneum` project; the live site (igneum.network, igneum.com, the GitHub integration) is the `igneum` team's project of the same name, which the igneum login reads and the the other business link does not | documented in `packaging/README-ship.md` (link, env ls, env add, deploy); no env set | `env ls` from a scratch link to the igneum-team project lists the two names; a branch push produced `igneum-git-<branch>` |
|
||||
| 4 Oct 2026 | `tools/jobs.mjs` and `publish-jobs.sh` print the downloads-folder token inside URLs on every run (X24 pattern) | the tokened base URL is echoed as is | the token masked as `<token>` in every printed URL | by eye, this log's own transcript |
|
||||
| 4 Oct 2026 | round 4 X28 and X24, the parts under an hour: `===` on secrets, no HSTS on the relay, the relay token printed by `tools/relay.mjs list` and `watch` | as the review said | c1f59fb: `sameSecret` (timingSafeEqual, `relay/lib/auth.mjs`, test in CI), `Strict-Transport-Security` in `relay/vercel.json`, `/r/<token>` printed (only `url` prints the real one) | relay deployed: key auth 200, wrong key and token 401, token path 200, HSTS header present |
|
||||
| 4 Oct 2026 | the live feed showed two "checkpoint N locked" events 30 ms apart (1122, 1172, 1230, 1258, 1259 in 400 observer lines), and 708 of 764 locked checkpoints in `live_checkpoints` had `votes_seen` 0 | `finalityTick` read the state, awaited two SQL writes, then set the map; the `finalityLockNotification` handler checked the same map synchronously in between and recorded the lock too; a lock claimed by the notification was never upserted again, so the poll's `votes_seen` never landed | 7de1bdb: the poll claims the state before its first await; a `checkpointDetailed` set makes the poll fill `votes_seen` once | before: 5 duplicates in 400 lines; after the 19:50:33 UTC restart: 21 locks (1297 to 1317), 0 duplicates, 0 write failures; 1300 was notification-first and the poll filled it to 17 votes. The zeros that remain are the node's own count (`finality.rs:770`, its vote map for that hash, empty when the lock came by certificate), not the observer's. Index 1296 appears twice on the feed: it locked inside the restart window, one write per process, a restart-boundary one-off At the 20:15:58 restart index 1319 (locked 14 min before) was recorded again: open, the seed should have held it locked; f22870a logs the seeded states and the earlier state on such a record. The 20:24:46 restart seeded 'proposed 500, locked 864' and re-recorded nothing (11 locks, 0 duplicates) |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Developer adoption: why a builder deploys on Igneum as well as Ethereum
|
||||
|
||||
4 October 2026. the project lead's ask: "we need a solid 'why people will choose to bring apps and features to our network as well as eth'. we need to solve this perfectly." This document is the mechanism-level answer and the plan to make it true. Every claim is grounded in a file in this repository or a cited source with a date. Figures from memory are labelled approximate. Nothing here is a prediction of the coin's price and nothing is a sale of anything.
|
||||
4 October 2026. The founder's ask: "we need a solid 'why people will choose to bring apps and features to our network as well as eth'. we need to solve this perfectly." This document is the mechanism-level answer and the plan to make it true. Every claim is grounded in a file in this repository or a cited source with a date. Figures from memory are labelled approximate. Nothing here is a prediction of the coin's price and nothing is a sale of anything.
|
||||
|
||||
Sources read: `docs/spec/07-execution.md` (7.1 quoted gas price, 7.5 the pgas cap), `docs/spec/05-fees-and-economics.md` (5.2 the priority fee split, 5.5 no development fund), `docs/spec/03-finality.md`, `docs/spec/09-pool-protocol.md`, `docs/spec/10-light-client.md`, `docs/design/execution-layer.md` (4.1 to 4.5 gas and attribution, 6 the proving precompile, 7 light clients, 8 tooling, 10 what devnet v3 implements), `docs/design/payment-routes.md`, `docs/analysis/economy-2026-10-04.md`, `docs/analysis/security-budget.md`, `docs/plans/funding.md`, `docs/commercial/prover-customer-brief.md`, `docs/bench-log.md` (3 and 4 October 2026 entries), `docs/evidence.md` row 22, `docs/fud-ledger.md` sections 4 and 6, `site/litepaper.html`, `site/index.html`, `site/verify/core.js` and `verify.js`, `site/journey.json`.
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ Stated plainly. On 4 October 2026 Igneum has no precompile, no job market, no po
|
|||
|
||||
**What a developer fund can and cannot buy.** The ask names "the foundation's developer fund (fee-funded)". There is none. Spec 5.5, decided 3 October 2026: "There is no development fund and no protocol fee to any team, foundation or fund." The 5% of tips and 5% of job fees that earlier drafts routed to a fund were removed. What exists: the litepaper's "Launch grants. Paid from the founders' own mined coins, never from emission, to the first apps that bring users", which `docs/plans/funding.md` does not budget and which the round-3 review flagged as the founders funding user acquisition (`docs/review/round-3-2026-10-03.md`, line 344); and the 60% parameter-signalling path by which miners could add a grant mechanism later (spec 5.5, 5.8). Both are unfunded today; the funding plan is a placeholder and its unfunded half is audits, not grants.
|
||||
|
||||
What the evidence of section 1 says a grant buys, whoever pays it: a deployment and a TVL number for the duration of the payment (STIP: 44.8% during; MUX lost two thirds after; Gauntlet: $689 of TVL per dollar during, $214 to $243 after), and a line in the ledger about founders paying for users. It does not buy retention. Base retained because of distribution, Arbitrum retained the capital that was long-duration anyway. The recommendation, which is a decision for the project lead and counsel (ledger L1, L2): spend founder coins on the three things that produce a track record (the reference apps of rows 1 and 2, the bridge contracts, the audits in `funding.md` that are unfunded), and never on a TVL programme. If "launch grants" stay in the litepaper they should name what they pay for (an audit, a port, an integration) and never a user count.
|
||||
What the evidence of section 1 says a grant buys, whoever pays it: a deployment and a TVL number for the duration of the payment (STIP: 44.8% during; MUX lost two thirds after; Gauntlet: $689 of TVL per dollar during, $214 to $243 after), and a line in the ledger about founders paying for users. It does not buy retention. Base retained because of distribution, Arbitrum retained the capital that was long-duration anyway. The recommendation, which is a decision for the founder and counsel (ledger L1, L2): spend founder coins on the three things that produce a track record (the reference apps of rows 1 and 2, the bridge contracts, the audits in `funding.md` that are unfunded), and never on a TVL programme. If "launch grants" stay in the litepaper they should name what they pay for (an audit, a port, an integration) and never a user count.
|
||||
|
||||
## 5. The developer-experience checklist
|
||||
|
||||
|
|
@ -266,7 +266,7 @@ The sentence "Canto and Blast proved builders come for this" is removed on the e
|
|||
|
||||
**Solana-style performance maximalist.** Findings: (1) "One block a second and a 10-s to 60-s proof lag; a game's job comes back in a later block. You cannot host anything real-time." Folded: the use-case table says turn-based and batch mechanics only, and the latency is stated. (2) "Your proving fleet is over-provisioned at launch traffic because there is no traffic; at 100 shards a block the model backs up unless the window is 20 s." Folded: the economy analysis is cited with its traffic sensitivity and the fleet-capacity bound; the precompile section does not claim capacity it has not modelled. (3) "A million calls a day is 11.6 a second; your `B_e` of 30M gas a block at one block a second is about 300 calls a second, so that is not even a stress test." Accepted and used: the table's largest row is small by design and the point stands that the share is small even then. (4) "Verifiable AI is a slogan; a 7B model is six minutes of GPU proving in the best published system and that is not SP1." Folded: the use-case table says "verifiable compute, not verifiable AI", with the figures and their labels.
|
||||
|
||||
**Consumer-app founder burned by an L2 incentive programme.** Findings: (1) "Your litepaper says 'launch grants to the first apps that bring users'. That is the programme that burned me." Folded: section 4 recommends grants buy ports, audits and integrations and never a user count, and the proposed litepaper text says so; the decision is the project lead's. (2) "Show me the number before the slogan." Folded: the table in 2a and the "property, not an income" sentence, in the public text too. (3) "Who do I call when a transaction is 'included' and never executes?" Folded: the four-state rule and `igneum_getTransactionStatus` are in sections 5 and 6, and the skip-and-re-include behaviour is in objection 5. (4) "I need a stablecoin, a bridge and a fiat on-ramp or my users cannot exist. You have none and you say phase two." Conceded (D4) and sequenced: consumer apps are row 3 of section 4, after mainnet and a track record. (5) "The miners are your users? Miners sell. They are the most mercenary users of all." Partly conceded in D1: the claim is that they are funded and present, not loyal; the apps that work for them are the ones that help them earn, pay and finance, which is why they are the beachhead and not the market.
|
||||
**Consumer-app founder burned by an L2 incentive programme.** Findings: (1) "Your litepaper says 'launch grants to the first apps that bring users'. That is the programme that burned me." Folded: section 4 recommends grants buy ports, audits and integrations and never a user count, and the proposed litepaper text says so; the decision is the founder's. (2) "Show me the number before the slogan." Folded: the table in 2a and the "property, not an income" sentence, in the public text too. (3) "Who do I call when a transaction is 'included' and never executes?" Folded: the four-state rule and `igneum_getTransactionStatus` are in sections 5 and 6, and the skip-and-re-include behaviour is in objection 5. (4) "I need a stablecoin, a bridge and a fiat on-ramp or my users cannot exist. You have none and you say phase two." Conceded (D4) and sequenced: consumer apps are row 3 of section 4, after mainnet and a track record. (5) "The miners are your users? Miners sell. They are the most mercenary users of all." Partly conceded in D1: the claim is that they are funded and present, not loyal; the apps that work for them are the ones that help them earn, pay and finance, which is why they are the beachhead and not the market.
|
||||
|
||||
## 9. What this document asks for
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ The sentence "Canto and Blast proved builders come for this" is removed on the e
|
|||
| Close O-5.8 on the devnet registration form | Execution engineer | Spec 5.2, 06 |
|
||||
| Specify the 1 gwei tip-quote floor as node policy | Execution engineer | Design 8.2 |
|
||||
| Expose per-key blue-block count and weight in `IgneumInfo` | Execution engineer, consensus engineer | Design 3, spec 7.1 |
|
||||
| Replace the litepaper's "Canto and Blast" bullet and the homepage Build sentence with section 7's text | the project lead's go, then the site owner | `site/litepaper.html`, `site/index.html` |
|
||||
| Re-scope "launch grants" to ports, audits and integrations, or remove the line | the project lead, counsel (L1, L2) | Litepaper |
|
||||
| Replace the litepaper's "Canto and Blast" bullet and the homepage Build sentence with section 7's text | the founder's go, then the site owner | `site/litepaper.html`, `site/index.html` |
|
||||
| Re-scope "launch grants" to ports, audits and integrations, or remove the line | the founder, counsel (L1, L2) | Litepaper |
|
||||
| Ledger section 9, entries D1 to D6 | This document | `docs/fud-ledger.md` |
|
||||
| The developer-experience order of section 5 | Execution engineer | Design 8, 10.3 |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Genesis forward-compatibility: the scheme byte, key succession, the cache rung
|
||||
|
||||
7 October 2026, 10:1x UK, the project lead's order to build mission item 8 now (`docs/analysis/mission/mission.md` section 2.8; the research in `docs/analysis/mission/future.md` sections 1.3, 7 and 10 and `docs/design/finality-in-proof.md` section 7). Branch `genesis-forward` on the node fork (from release-0.3.19-node dc141409, the merged line that carries the ladder and the W7 leave item, which ca3-v4-0318 alone does not) and `genesis-forward` on the repo. Three genesis fields, every switch never on the devnet (its digest does not move), all three set at the testnet genesis by the testnet lane, which holds the cut and re-pins. The class-group VDF's quantum fallback is flagged in spec 04 section 4.8, not built.
|
||||
7 October 2026, 10:1x UK, the founder's order to build mission item 8 now (`docs/analysis/mission/mission.md` section 2.8; the research in `docs/analysis/mission/future.md` sections 1.3, 7 and 10 and `docs/design/finality-in-proof.md` section 7). Branch `genesis-forward` on the node fork (from release-0.3.19-node dc141409, the merged line that carries the ladder and the W7 leave item, which ca3-v4-0318 alone does not) and `genesis-forward` on the repo. Three genesis fields, every switch never on the devnet (its digest does not move), all three set at the testnet genesis by the testnet lane, which holds the cut and re-pins. The class-group VDF's quantum fallback is flagged in spec 04 section 4.8, not built.
|
||||
|
||||
## 1. The scheme byte
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ Not in this round: a p2p gossip kind for successions (the leave's shape, protoco
|
|||
| The RPC | `powEpoch.latencyLadderCacheStep`, `nextLatencyLadderCacheStep`, `latencyLadderCacheMib`, `nextLatencyLadderCacheMib`, `latencyLadderCacheBps`, `latencyLadderCacheWeakestBps`, `latencyLadderCacheAdmissible` (proto fields 37 to 43); the daemon's ladder line (`cache [512 MiB]`) | the rung visible on every node |
|
||||
| The gate | `admissible` in the genesis list, false until measured: the cold verify of one warp with the 512 MiB cache on the reference core with its SMT sibling loaded under 10 ms (the verifier reads the cache, so this is the bound), the day-cache build on a 2019-class core under twice today's, and the 8 GB tier still holding dataset, cache and the prover footprint | the rule never enters an inadmissible rung (tested) |
|
||||
|
||||
Why beside N and not a seventh N rung: the six approved rungs and their indices stand (the project lead, 7 October 2026, 09:3x UK); a rung inserted in the list would either sit behind the three inadmissible rungs (unreachable) or shift the approved indices. A second lever on the same signal carrier keeps the list as approved and the cool-down shared.
|
||||
Why beside N and not a seventh N rung: the six approved rungs and their indices stand (the founder, 7 October 2026, 09:3x UK); a rung inserted in the list would either sit behind the three inadmissible rungs (unreachable) or shift the approved indices. A second lever on the same signal carrier keeps the list as approved and the cool-down shared.
|
||||
|
||||
Owed with the measurement: the engine's consumption of `cache_mib` (`EpochSeeds` carries `shadow_reps` today and no cache size; the pack and the three hosts build a 256 MiB cache), so the flag stays false until the path exists and is measured. Per tier what the rung means: every tier from 8 GB holds a 512 MiB cache; the day-cache build doubles (about 0.7 s on the reference core today, approximate, from the class v4 fill line); the Apple tier's unified memory holds it; a pool user does nothing.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# The miner software's dev fee
|
||||
|
||||
Decision (the project lead, 4 October 2026, evening): the Igneum miner software takes a visible, switchable 1% dev fee, the norm
|
||||
Decision (the founder, 4 October 2026, evening): the Igneum miner software takes a visible, switchable 1% dev fee, the norm
|
||||
for GPU miners (lolMiner, T-Rex). The protocol stays fee-free: no dev fund, no fee to any team, foundation or fund
|
||||
(CLAUDE.md, litepaper). This fee is the software's, like every third-party miner's, and it is documented as such.
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ extra config.
|
|||
|
||||
| Constant (`igneum/miner/src/main.rs`) | Value | Network |
|
||||
|---|---|---|
|
||||
| `DEV_FEE_ADDRESS` | `0x7F45d7d7272e57639BeBb739A60B05bB2CD4C126`: the project lead's payout address from the Igneum Wallet, given 5 October 2026, EIP-55 checksum verified, on file at `~/.config/igneum/dev-fee-release.json`; set on the fork's `release-0.3.6` (commit cf369022). Were it ever not 40 hex the fee would be off outside the devnet and the miner would say so at start | mainnet, testnet |
|
||||
| `DEV_FEE_ADDRESS` | `0x7F45d7d7272e57639BeBb739A60B05bB2CD4C126`: the founder's payout address from the Igneum Wallet, given 5 October 2026, EIP-55 checksum verified, on file at `~/.config/igneum/dev-fee-release.json`; set on the fork's `release-0.3.6` (commit cf369022). Were it ever not 40 hex the fee would be off outside the devnet and the miner would say so at start | mainnet, testnet |
|
||||
| `DEV_FEE_ADDRESS_DEVNET` | `0xdfaea67368f3e3753397d878f97efe6aa8020c2e` | devnet and simnet only |
|
||||
|
||||
The devnet address was generated on 4 October 2026 with the app's own key derivation (secp256k1, keccak of the
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Miner tuning: variant racing and fleet learning
|
||||
|
||||
4 October 2026, evening. the project lead: "we need to make our miner better than anything else can be". Two levers, both
|
||||
4 October 2026, evening. The founder: "we need to make our miner better than anything else can be". Two levers, both
|
||||
measured: a race between kernel variants at every hourly swap, and a fleet that remembers which variant each card
|
||||
model likes. Numbers live in `docs/bench-log.md` ("miner performance: variant racing"); the PC job is in
|
||||
`docs/plans/miner-perf.md`. Nothing here changes the hash: every variant is the same instruction text in a
|
||||
|
|
|
|||
|
|
@ -166,6 +166,6 @@ No durations for the engineering are given here beyond the journey's phase dates
|
|||
| P7 | The developer entity shown on the store listing | Section 12 |
|
||||
| P8 | The display rules of 4.1 need fields the pool protocol's `stats` and the node card do not yet carry (the tariff is local; failed jobs, release state and proving income need fields) | Add the fields with O-9.5 and node card version 2; O-8.2 |
|
||||
|
||||
## 12. The decision for the project lead
|
||||
## 12. The decision for the founder
|
||||
|
||||
Both stores show the developer's legal name on the listing, and Apple's wallet rule (3.1.5 (b), approximate) wants an organisation account, not an individual. CLAUDE.md's standing rule is that the organisation owner is never publicly visible. A store listing cannot honour that rule: some entity's name will be on the page. The decision is which entity publishes the app (an existing company, a new one for Igneum, or a foundation that does not yet exist), which also decides the privacy policy's signatory and the release-key steward's relation to it (spec 8.2 item 2, O-8.1). Nothing in sections 1 to 11 depends on the choice, and nothing can be submitted to a store without it.
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ Versions in the table: `igneum-pow` is the Rust crate at `igneum-pow/Cargo.toml`
|
|||
| 14 | Ethereum bytecode runs unchanged, with the documented differences of spec 7.1 | Homepage Build card; litepaper Building | tested by the team | as row 13; fixes `F-exec-A`, `F-exec-B` (spec 7.5) | `tools/evm-smoke/smoke.mjs`: deploy via viem, `increment`, `hashLoop`, `eth_estimateGas`, `eth_getLogs`; `tools/exec-attacks` scenarios 1 and 3; bench-log "execution layer attack fixes" | Deployment, calls, reverts, logs and gas estimates behave as viem expects; chain id 4463; the prototype pgas table gives 0.0095 to 0.028 pgas per gas, below the design's band before calibration, 3 October 2026. 4 October 2026: a transaction that would cross the block's proving budget is refused by the mempool and, if forced in, aborted and charged with its nonce advanced (25 of 25 checks; 30 of 30 malformed cases). Apple M5 Max. The `Prover` precompile, proof records and the shard planner are not in the node | none yet |
|
||||
| 15 | Every block is proven, with the proof landing within about a minute at launch | Homepage stats ("~60 s to a proof"); litepaper Proving; roadmap phase 3 gate | implemented | repo `d7e1f89` (GPU proof), `e01a3cc`, `292e800`, `eedd136` (`proving/igneum-prove`: shard cutter, MPT witnesses, shard and aggregator guests); SP1 6.8.1; spec 7.2, 7.6 | `proving/windows-wsl2` (SETUP-PROVER, PROVE-BLOCK) on the RTX 5090; `igneum-prove-host --mode block` on `proving/fixtures/`; bench-log "proving v0 on the RTX 5090" and "proving: devnet v4 shards" | First GPU proof of an Igneum block, 4 October 2026, RTX 5090 (WSL2, SP1 cuda, mining paused): fixture `block-78-increment` (2 transactions), core proof 1.4 s (7.3 MB, verify 0.221 s), compressed proof 2.7 s (1.27 MB, verify 0.038 s), post-state and receipts roots identical to the node's; 15.7x and 20.6x faster than a loaded M5 Max CPU. The same day on that CPU (load 38 to 47): a three-shard block proved shard by shard and aggregated by recursion, 19 min (1,139 s) end to end, 245 to 337 s per compressed shard proof, every proof verified. What is not there: no proof is produced, carried or checked on the chain (the devnet prover is a stub that signs claims), the proving pool pays nobody (row 21), the block proven is far below one shard, and the 60-second figure remains a design target; the pass mark is the standard in `docs/benchmarks/proving-e2e.md`. Second RTX 5090 run, 4 October 2026 evening (job run-20261004-173115): a full shard at the provisional S_p (6.75 M pgas, 60.8 M cycles) executed in 1.63 s, core proof 8.3 s (18.1 MB), compressed proof 10.9 s (1.27 MB, verify 0.040 s); a two-shard block (13.5 M pgas) proved shard by shard (11.7 s and 10.0 s) and aggregated in 2.2 s, 24 s of GPU stages end to end, every proof verified, six tampered witnesses rejected. The two host defects (an abort after the upload, an idle wait that turned out to be an unbuffered 18 MB proof save through the WSL2 file bridge, 24 minutes) are fixed (ledger P20) 5 October 2026, live devnet with real transactions (bench-log "real transactions, the first non-empty shard proven and paid"): block 72704 shard 0, 29 transfers, 5,800 pgas, proven on PC 2 in 34 s, verified on the Mac in 0.297 s and paid 1.7623 IGN, 53 s after the chain block executed; of about 1,400 blocks in the 20-minute window 36 were proven (the one prover takes the newest shard assigned to it), so "every block" is not yet true; a second content shard (72803, all copies skipped) failed the native-execution veto on the exporter's block structure, fixed with fixtures the same day, the node side pending the 0.3.9 rollout 5 October 2026, evening (bench-log "proving v1"): the aggregated segment record, the chain rule and the unproven rule are implemented behind `proving_v1_activation_daa` (branch proving-v1, not on the devnet before 0.3.11); on the RTX 5090 a chain of 8 consecutive live blocks proved and aggregated by recursion in 135.6 s with the miner on the card (17 s a block, one proof of 1,272,909 bytes attesting all 8, verified in 0.04 s); the 3-node fast-time harness paid a segment record 1.0 s after submission and refused a late one after its deadline (21 checks); the devnet itself, with one prover, carried proofs for 2.4% of blocks over 30 minutes at a block-to-record latency p50 44 s, p99 52 s. The "within about a minute" holds per proven block; "every block" needs 18 mining 5090s or 6 proving-only cards at empty blocks on the measured rates, and the mandatory rule stays off until the share is one | none yet |
|
||||
| 16 | A 12 GB card proves one shard in about 20 s (WITHDRAWN 5 October 2026: a 24 GB card proves a full shard at the adopted size in 4.3 s; 32 GB mines and proves) | Litepaper Proving ("The proving budget"); roadmap gate 2 | designed | spec 5.1 (Target), 7.6 (`S_p` provisional, 7,500,000 pgas = `B_p` / 4) | `PROVE-SHARD.bat` on the RTX 5090 (pending); the end-to-end standard in `docs/benchmarks/proving-e2e.md`; bench-log "proving: devnet v4 shards" | Measured on a 32 GB card, not yet on a 12 GB card. A shard at the provisional `S_p` is 60.8 M SP1 cycles on the prototype pgas table (9 cycles per pgas, 44 per EVM gas; the modexp entry about 100x its SP1 cost); on an RTX 5090 (4 October 2026 evening, job run-20261004-173115) it executed in 1.63 s and its compressed proof took 10.9 s, verified in 0.040 s, so the 32 GB card is inside the 20 s target with margin. Whether a 12 GB card proves it at all, and in what time, is the next measurement (an RTX 3060 and an RTX 5060 Ti 16 GB are on order). A per-shard time can be met by shrinking the shard, so the project does not use it as a pass mark 5 October 2026, evening (bench-log "proving v1", the S_p curve): measured on the RTX 5090 with SP1 6.8.1's GPU prover, the card to itself, 1-s nvidia-smi samples: an empty shard 13,874 MiB and 2.2 s; a full shard at the ADOPTED v1 budget (30,000 pgas, 4.7 M cycles) 20,434 MiB and 4.3 s; the full prototype shard (6.75 M pgas, 60 M cycles) 28,307 MiB and 10.8 s; beside the miner 15,670 and 30,039 MiB. No environment knob of SP1 moves the 13.9 GB floor and the GPU server has no options of its own, so on this build a 12 GB card proves nothing, a 16 GB card only empty shards, a 24 GB card the adopted full shard alone and beside the miner (22,210 MiB and 13.2 s, measured on the 32 GB card: the 5090's allocation pattern, not yet a run on a 24 GB card) and a 32 GB card the prototype shard beside the miner with 2.5 GB spare. The litepaper line now says so; the 12 GB gate returns when a prover build with a smaller floor is measured on a 12 GB card | none yet |
|
||||
| 17 | The chip resistance claim: the strongest chip in the public model reaches 5x to 9x per joule against an RTX 5090 today (modelled); class v4 brings it to 2.1x (k = 1) to 3.9x (k about 0.33, claimed by a withdrawn product) and its second rung to about 2.8x (modelled on measured watts); class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item (designed, +0.2 ms verifier); the hot-set cache bounded at 1.067x at the ceiling (measured census of 1,024 programs) and the weak-day FPGA at most 12 percent on 12 days a century (measured census) are bounded and routed to the next class; datacentre silicon (H100 SXM, measured 7 October) does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years (modelled) | The home page's chip line, the litepaper's chip model section, the miner page's line (the texts of `docs/plans/counter-asic-3-public-text-2026-10-07.md`) | tested by the team (every card, the verifier, the two attack-pass censuses, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 core claimed and never measured | `docs/analysis/chip-model-v3.md` 5 and 6; `docs/analysis/latency-shadow-2026-10-06.md`; `docs/plans/counter-asic-3-status.md`; `docs/analysis/attack-pass/f8-uniform.md`, `f4-weakday.md`; `docs/design/class-v5-stored-state.md`; the H100 and market-cap rows of 7 October; `docs/plans/funding.md` (the three lots) | The chip model re-run on the measured class v3 and v4 rates, watts and verifier times; the hot-set census of 1,024 programs and the weak-day census of 2^24 days on the attack-pass branch; the H100 SXM bench row | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 5.1x to 9.2x; 2.1x, 3.9x, 2.8x; 1.067x at the ceiling; 12 percent on 12 days a century; 10.85 ms at rung 3; USD 100 M; 6 and 7 October 2026 | none yet; the three cryptanalysis lots are the next test |
|
||||
| 17 | The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (k = 1) to 3.9x (k about 0.33) per joule against an RTX 5090 under class v4, live from genesis on the testnet and the mainnet; the ladder's second rung brings it to about 2.8x; class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item; the hot-set cache is bounded at 1.067x at the ceiling and the weak-day FPGA at 12 percent on 12 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state) | the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line | tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 core claimed and never measured | `docs/analysis/chip-model-v3.md` 5 and 6; `docs/analysis/latency-shadow-2026-10-06.md`; `docs/plans/counter-asic-3-status.md`; `docs/analysis/attack-pass/f8-uniform.md`, `f4-weakday.md`, `docs/analysis/ca3-v4-uniform.md`; `docs/design/class-v5-stored-state.md`; the H100 and market-cap rows of 7 October; `docs/plans/cryptanalysis/in-house-pass.md` (the internal adversarial pass) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.9x, 2.8x at launch; 1.067x at the ceiling; 12 percent on 12 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, PC 2's RTX 5090, PC 1's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026). | none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and the one outside check is staged and waits on its escrow and the publish word |
|
||||
| 18 | The chip resistance measurements: the program is latency-bound (random reads), not bandwidth-bound, on every card we own, and sits beyond a card's on-chip cache | Litepaper Mining ("waits on memory latency, not on maths or bandwidth"), vs RandomX; the numbers page | tested by the team | readwidth e752fc7 (`docs/plans/read-width.md`), ca2-era 78c0ee4, ca2-cache 2de19e5 (`docs/plans/hot-table.md`) | The dependent-read probes at 32 to 1,024 MiB and the hash rate per class on the three cards; the latency-bound share = rate over the probe ceiling per load | Latency-bound share at the 1 GiB dataset: RTX 5090 0.96 (v2) and 1.01 (v3), RX 9070 XT 0.87 and 0.95, M5 Max 1.01 and 1.06; wider reads do not close the AMD gap (the 9070 XT does 2.4 G dependent reads per second at every width; the 5090 goes bandwidth-bound at 64 B, share 0.58); a 32 to 96 MiB hot table is not kept resident by any card while the dataset streams (g 0.80 to 0.87 in the added form). 5 October 2026 | none yet |
|
||||
| 19 | The lottery hash is sound as a hash: uniform output, deterministic, no out-of-bounds read, fuzzed; class v3 bit-exact on the three vendors | Litepaper vs RandomX ("Every number above is measured and logged"), the numbers page | tested by the team | ca2-mixer 1ab8b21 (`tests/mixer.rs`, `tests/scratch.rs`), ca2-era 78c0ee4, ca2-soundness a465881 (`docs/analysis/scratch-soundness.md`), `igneum-pow/tests/packs.rs` | The crate suite (53 + 4 + 19 + 7), the Metal fuzz, edge, stats and determinism runs on the v3 construction, the pack vectors and 2^24 fingerprints on Metal, Apple OpenCL, the RTX 5090 and the RX 9070 XT, the 1,024-hash CPU re-check per card | Class v3 (mixer x8 + era): 200-program fuzz 200 of 200 on Metal, every tenth on Apple OpenCL; the pinned v3 packs 3/3 + 3/3 and 96 of 96 lanes on Metal and Apple OpenCL; the six era packs' fingerprints equal on the three vendors (PC 1 job run-ca2-era-pc1-20261005, 5 October 2026); the v2 exports byte-identical on the v3 crate; the final-class PC rows and the G2 re-check: job run-ca2-era-pc1b-20261005 (pending at the time of writing) | none yet |
|
||||
| 20 | No premine, no pre-sale, no allocation: every coin is minted by the schedule and every coin goes to the block producer (80%) and the proving pool (20%) | Homepage stats and Economics tiles; litepaper Supply, Economics | implemented | repo `6ac80a3`; fork "igneum-node devnet v0"; `consensus/core/src/igneum.rs`, `coinbase.rs` | `cargo test -p kaspa-consensus-core igneum` (8 pass: subsidy table, ramp, split, cap) and `cargo test -p kaspa-consensus coinbase` (8 pass); `igneum-miner inspect 40`; bench-log "igneum-node devnet v0" | Coinbases on the devnet: 80/20 exact on 39 of 39 single-payee blocks, the 20% to the `igneum-proving-pool-v0` output; the per-second schedule sums to under the 4,000,000,000 cap by less than 100 coins; 3,168,808,781 units per DAA second in years 0 to 2, halving at 63,115,200 DAA s. 3 October 2026, Apple M5 Max. The devnet genesis carries no allocation; the mainnet genesis does not exist yet, so the claim is about the code and the stated rule, not a launch that has happened | none yet |
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ Merge note for `fin-fixes` (4 Oct 2026, branched from master `2a00ff55`, which a
|
|||
|
||||
## The rename (3 Oct 2026): what a miner, a user or an operating system sees
|
||||
|
||||
Trigger: macOS asked the project lead whether "kaspad" may access the local network. Everything visible from outside the source tree now says Igneum. Internal crate names, module paths, protobuf packages and Rust identifiers keep their upstream names (next table) so `git merge` against rusty-kaspa stays mechanical.
|
||||
Trigger: macOS asked the founder whether "kaspad" may access the local network. Everything visible from outside the source tree now says Igneum. Internal crate names, module paths, protobuf packages and Rust identifiers keep their upstream names (next table) so `git merge` against rusty-kaspa stays mechanical.
|
||||
|
||||
| Surface | Before | After | Where |
|
||||
|---|---|---|---|
|
||||
|
|
|
|||
|
|
@ -19,19 +19,19 @@ Decisions of 3 October 2026 applied throughout: (a) no development fund, priorit
|
|||
|
||||
## 2. Every open or conceded entry
|
||||
|
||||
Who: the project lead (decision or account), Claude (text, spec, code, simulation), counsel, measurement (an experiment that produces a number). When: now, before public repo (opens at the public testnet, August 2027), before testnet (August 2027), before mainnet (November 2027).
|
||||
Who: the founder (decision or account), Claude (text, spec, code, simulation), counsel, measurement (an experiment that produces a number). When: now, before public repo (opens at the public testnet, August 2027), before testnet (August 2027), before mainnet (November 2027).
|
||||
|
||||
| # | Ledger | Issue | Fix | Who | When | EXPOSES |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1 | X1 | HP footer, HP nav and the /bench page link to a private GitHub repository | Remove the GitHub links (site/index.html line 422, the nav in site/build.mjs) until the repository is public; put them back on the day | Claude | now | no |
|
||||
| 2 | X2 | "Get the miner" three times and "Start mining" on HP with no miner | Item 60: "Benchmark: January 2027", linking to #journey | Claude | now | no |
|
||||
| 3 | X7 | No contact route on HP or LP | the project lead creates a mailbox on the igneum.network Workspace; Claude adds it to the HP footer and the LP cover (item 77). No public ledger route is needed now the ledger is internal | the project lead, then Claude | now | no |
|
||||
| 3 | X7 | No contact route on HP or LP | the founder creates a mailbox on the igneum.network Workspace; Claude adds it to the HP footer and the LP cover (item 77). No public ledger route is needed now the ledger is internal | the founder, then Claude | now | no |
|
||||
| 4 | X8 | "exchange listings after" in the LP roadmap (line 422) and J phase 6 | Item 58 in both files | Claude | now | no |
|
||||
| 5 | X10 | Eleven log entries, all dated 3 October 2026 | Add a "Day one" label above the log in site/index.html | Claude | now | no |
|
||||
| 6 | L2 (with E2) | Inducement wording: "so the people who show up early get the most" (LP 183), chart caption "Half of the 4 billion cap is mined in the first two years" (LP 184), HP "Half of all IGN is mined in the first two years" | Items 54 and 76: schedule facts, no "so" clause. Counsel opinion is row 46 | Claude | now | no |
|
||||
| 7 | E4, E5, G5, G8, O-5.4 | Dev fund text everywhere after decision (a): LP Economics (65/15/15/5 paragraph, "Development, paid by outsiders" section), LP Governance (fund bullet, second-client bullet), LP firsts row ("a development fund paid by outsiders"), HP Economics ("Development is paid from fees..."), spec 05 sections 5.2, 5.4, 5.5 and the self-dealing arithmetic, spec README row 5, spec 00 row 5, spec 06 items O-5.4 and O-5.7, docs/design/execution-layer.md lines 143, 210 and 217, the design document (CLAUDE.md already carries the new split) | Rewrite to: base fee burned in full; priority fee 80% miner and provers, 20% called app; external jobs 90% prover, 10% burn; no fund. the project lead confirms the 15% priority-fee burn is gone on purpose (section 4) | Claude, the project lead confirms | now | no |
|
||||
| 8 | E5 | HP "Not one coin to a founder, a fund or a stake" while the official client carries a 1% dev fee to the founder's company; LP spreads the dev fee, the pool and the proving business over three sections | Item 62 on HP. One LP heading that holds the 1% dev fee, the pool, the proving business, and that these now fund development since there is no fund | Claude | now | EXPOSES: "the founder's company" must be the offshore entity once it exists, never a company the project lead already owns |
|
||||
| 9 | G3 | The ledger's answer says "The founder's name is on every commit". Decisions (c) and (e) make the founder pseudonymous | Do not apply item 73 as written. LP "Who are you?" gets: "The founder is pseudonymous until the team page at public testnet. No cryptographer is hired yet." Decided 5 October 2026: no team page for now; the litepaper says the team is pseudonymous and names no team page | the project lead decides, Claude writes | now | EXPOSES: the ledger answer and CLAUDE.md name the founder; see section 5 |
|
||||
| 7 | E4, E5, G5, G8, O-5.4 | Dev fund text everywhere after decision (a): LP Economics (65/15/15/5 paragraph, "Development, paid by outsiders" section), LP Governance (fund bullet, second-client bullet), LP firsts row ("a development fund paid by outsiders"), HP Economics ("Development is paid from fees..."), spec 05 sections 5.2, 5.4, 5.5 and the self-dealing arithmetic, spec README row 5, spec 00 row 5, spec 06 items O-5.4 and O-5.7, docs/design/execution-layer.md lines 143, 210 and 217, the design document (CLAUDE.md already carries the new split) | Rewrite to: base fee burned in full; priority fee 80% miner and provers, 20% called app; external jobs 90% prover, 10% burn; no fund. The founder confirms the 15% priority-fee burn is gone on purpose (section 4) | Claude, the founder confirms | now | no |
|
||||
| 8 | E5 | HP "Not one coin to a founder, a fund or a stake" while the official client carries a 1% dev fee to the founder's company; LP spreads the dev fee, the pool and the proving business over three sections | Item 62 on HP. One LP heading that holds the 1% dev fee, the pool, the proving business, and that these now fund development since there is no fund | Claude | now | EXPOSES: "the founder's company" must be the offshore entity once it exists, never a company the founder already owns |
|
||||
| 9 | G3 | The ledger's answer says "The founder's name is on every commit". Decisions (c) and (e) make the founder pseudonymous | Do not apply item 73 as written. LP "Who are you?" gets: "The founder is pseudonymous until the team page at public testnet. No cryptographer is hired yet." Decided 5 October 2026: no team page for now; the litepaper says the team is pseudonymous and names no team page | the founder decides, Claude writes | now | EXPOSES: the ledger answer and CLAUDE.md name the founder; see section 5 |
|
||||
| 10 | F5 | "whole network's hashrate" misread | Item 32 | Claude | now | no |
|
||||
| 11 | F10, F4, G8 | Pool concentration unstated; LP heading "Speed and finality, powered by miners alone" | Items 33 and 43. Heading becomes "Speed and finality, a miner-weighted overlay on proof of work". Name pool concentration as the governance risk | Claude | now | no |
|
||||
| 12 | C3, M3, C8, C11 | Kaspa misstated; firsts table; LP 68 "taken over by chips, as Kaspa was" still reads as capture; Conflux missing from the problem section | Apply items 4, 7, 8, 10, 11 and 29. Items 5, 6, 9 and 47 are done | Claude | now | no |
|
||||
|
|
@ -51,7 +51,7 @@ Who: the project lead (decision or account), Claude (text, spec, code, simulatio
|
|||
| 26 | P10, E7 | Economics says outsiders pay in IGN and part is burned; the miner section says they pay in their own money; "Stablecoins at genesis ... through the proof bridge" (LP 176, 284) | Items 40 and 71 applied 3 October 2026 (E7 decided, spec 7.3); item 52 (the P10 contradiction in Economics) still open | Claude | now | no |
|
||||
| 27 | E1, E6 | Supply states the cap, not the tail-emission trade-off; halvings presented as fact, not a bet | Two sentences in Supply: the tail alternative and why the cap was chosen; the halving schedule is a bet, a tail can be added by 90% signalling | Claude | now | no |
|
||||
| 28 | G1 | "named reviewers" who do not exist; "The specification is public" (LP 271) | Items 48 and the third item of 78 | Claude | now | no |
|
||||
| 29 | G2 | Method undisclosed | Item 72. Keep the Co-Authored-By trailers in the history: they are the evidence the entry cites | Claude; the project lead confirms the trailers stay | now | no |
|
||||
| 29 | G2 | Method undisclosed | Item 72. Keep the Co-Authored-By trailers in the history: they are the evidence the entry cites | Claude; the founder confirms the trailers stay | now | no |
|
||||
| 30 | G4 | "There are no admin keys" (LP 236), "0 admin keys" (HP) | Item 45 minus the fund contract; HP tile becomes "0 admin keys in consensus" | Claude | now | no |
|
||||
| 31 | G5 | "second independent node client, funded from the development fund" (LP 237) | Item 46 rewritten: "At launch there is one node client. A second independent client is not in the 13-month plan." The funder is row 47 | Claude | now | no |
|
||||
| 32 | G6 | "Pools cannot censor" (LP 235) | Item 44 | Claude | now | no |
|
||||
|
|
@ -65,14 +65,14 @@ Who: the project lead (decision or account), Claude (text, spec, code, simulatio
|
|||
| 40 | F12 | "Nothing in Igneum's consensus depends on anything outside Igneum" (LP 166) | Scope to "no other chain's state"; name the code dependencies (SP1, BLS12-381, class-group VDF, rusty-kaspa) in one line | Claude | now | no |
|
||||
| 41 | F13 | Why prove if every node executes: unstated | One sentence under the 20% row: the share pays a standing prover population, and the proof serves light clients, bridges and sync from a proven checkpoint | Claude | now | no |
|
||||
| 42 | F6 | Equivocation costs history, not coins | Stated (LP 164, design doc). Nothing further | none | | no |
|
||||
| 43 | L5 | No trademark search recorded | Search EUIPO, USPTO and UK IPO in classes 9, 36 and 42; record the result outside the repo; the name stays provisional until then | the project lead, counsel if a hit | now | EXPOSES: any application comes from the offshore entity, never from the project lead or a company he already owns |
|
||||
| 44 | L3 | US registrar, US nameservers, US host | Now: deSEC nameservers (in progress); recreate the Vercel records at deSEC and re-verify every domain in the Vercel project. December 2026: non-US registrar when the transfer lock ends. Before mainnet: IPFS mirror, ENS or equivalent name, site content hash in the repo and in genesis, seed nodes as addresses in the client | the project lead (accounts), Claude (mirror, hashes) | now, December, before mainnet | EXPOSES: the ledger and CLAUDE.md name the registrar and the host; keep both out of the public tree |
|
||||
| 43 | L5 | No trademark search recorded | Search EUIPO, USPTO and UK IPO in classes 9, 36 and 42; record the result outside the repo; the name stays provisional until then | the founder, counsel if a hit | now | EXPOSES: any application comes from the offshore entity, never from the founder or a company he already owns |
|
||||
| 44 | L3 | US registrar, US nameservers, US host | Now: deSEC nameservers (in progress); recreate the Vercel records at deSEC and re-verify every domain in the Vercel project. December 2026: non-US registrar when the transfer lock ends. Before mainnet: IPFS mirror, ENS or equivalent name, site content hash in the repo and in genesis, seed nodes as addresses in the client | the founder (accounts), Claude (mirror, hashes) | now, December, before mainnet | EXPOSES: the ledger and CLAUDE.md name the registrar and the host; keep both out of the public tree |
|
||||
| 45 | E8 | Founders seed the DEX | Stated. Whether to do it at all goes to counsel in row 46 | counsel | before public repo | no |
|
||||
| 46 | L1, L2 | Howey and promotions: founder business, founder-seeded DEX, launch grants, listings (row 4 removes listings) | Counsel in the entity's jurisdiction reviews the founder-business paragraph and the promotions question before litepaper v0.2. The ledger's "offshore, parked" becomes "offshore, being established". the project lead decides whether igneum.co.uk stays in the redirect set (a weak UK hint; WHOIS is redacted) | counsel, the project lead briefs | before public repo | EXPOSES: the brief names the entity's jurisdiction, never the founder's residence |
|
||||
| 47 | G5 | The second client has no funder now the fund is gone | Decide: the operating company, a grant from the proving business, or not in the plan | the project lead | now (decision), before mainnet (client) | no |
|
||||
| 46 | L1, L2 | Howey and promotions: founder business, founder-seeded DEX, launch grants, listings (row 4 removes listings) | Counsel in the entity's jurisdiction reviews the founder-business paragraph and the promotions question before litepaper v0.2. The ledger's "offshore, parked" becomes "offshore, being established". The founder decides whether igneum.co.uk stays in the redirect set (a weak UK hint; WHOIS is redacted) | counsel, the founder briefs | before public repo | EXPOSES: the brief names the entity's jurisdiction, never the founder's residence |
|
||||
| 47 | G5 | The second client has no funder now the fund is gone | Decide: the operating company, a grant from the proving business, or not in the plan | the founder | now (decision), before mainnet (client) | no |
|
||||
| 48 | M4 | Firsts row is done (item 5); ProgPoW and Ravencoin are cited nowhere | Clone the ProgPoW specification and the Ravencoin repository into vendor/; cite path and commit in the spec | Claude | before public repo | no |
|
||||
| 49 | C8, C3 | Ergo, Ravencoin, Conflux and rusty-kaspa claims are from memory | Cite each from its repository; label approximate until then | Claude | before public repo | no |
|
||||
| 50 | M1 | ASIC gain under 2x is a target | Public benchmark, leaderboard by card model and a standing bounty with the January 2027 release (O-1.17). Bounty terms and funding are the project lead's | the project lead (terms), Claude (benchmark), measurement | before public repo | EXPOSES: the bounty payer and terms carry the entity, not the project lead |
|
||||
| 50 | M1 | ASIC gain under 2x is a target | Public benchmark, leaderboard by card model and a standing bounty with the January 2027 release (O-1.17). Bounty terms and funding are the founder's | the founder (terms), Claude (benchmark), measurement | before public repo | EXPOSES: the bounty payer and terms carry the entity, not the founder |
|
||||
| 51 | M5 | Load count varies 6x | O-1.2: exact 16 load positions in the generator, re-fuzz 10,000 programs, confirm the loads-per-hash column is constant | measurement | before public repo | no |
|
||||
| 52 | M6 | Weak programs unmeasured | O-1.3: census of at least 10^5 programs and a rejection rule in the generator | measurement | before public repo | no |
|
||||
| 53 | M7 | Ad hoc seed derivation, no analysis | O-1.1: standard hash into the seed words, new vectors. O-1.4: external review scoped to the fair-lottery properties | Claude (code), then review | before public repo | no |
|
||||
|
|
@ -83,7 +83,7 @@ Who: the project lead (decision or account), Claude (text, spec, code, simulatio
|
|||
| 58 | L4 | Paying testnet miners needs an entity, terms and tax treatment | Entity first (decision c); counsel writes the terms before phase 5 | counsel | before testnet | no |
|
||||
| 59 | L6 | Dollar-paid job market read as money transmission | Counsel confirms the no-custody structure before phase 4 | counsel | before testnet | no |
|
||||
| 60 | M11 | Hourly compile on real rigs unmeasured | O-1.16: miner client prototype on a multi-card rig; compile time and failure rate per hour | measurement | before testnet | no |
|
||||
| 61 | F1 | No weight in the first month | O-3.1: launch-month simulation; decide the no-certificate-for-30-days rule; the litepaper states it either way | Claude (sim), the project lead (decision) | before testnet | no |
|
||||
| 61 | F1 | No weight in the first month | O-3.1: launch-month simulation; decide the no-certificate-for-30-days rule; the litepaper states it either way | Claude (sim), the founder (decision) | before testnet | no |
|
||||
| 62 | F3 | Participation grinding through the bitmap | Closed by rule 3 October 2026: spec 3.3 Q2 and 3.4.1, participation from every vote seen in blocks. Remaining: O-3.3, the per-block vote bound and the re-run under the block reading | Claude (sim) | before testnet | no |
|
||||
| 63 | F7 | Checkpoint depth 60 is a placeholder | O-3.2: devnet with regional latency, reorg-depth distribution per block rate | measurement | before testnet | no |
|
||||
| 64 | F2 | Presence window as an eclipse vector | Closed by rule 3 October 2026: spec 3.3.2, the 56.7% floor. Remaining: O-3.7, the devnet single-node eclipse as confirmation; no rule choice | measurement | before testnet | no |
|
||||
|
|
@ -92,11 +92,11 @@ Who: the project lead (decision or account), Claude (text, spec, code, simulatio
|
|||
| 67 | P5 | EVM semantics on a DAG | Closed by spec 3 October 2026: spec 7.1 (number, timestamp and its monotonicity rule, blockhash, PREVRANDAO from the epoch VDF, coinbase, gas limit, chain id, quoted gas price); O-2.8 removed | done | done | no |
|
||||
| 68 | P7 | Soundness-bug handling | Spec rule: a full node rejects a proof whose state root differs from its own execution; the proof-system version has a stated human emergency path | Claude | before testnet | no |
|
||||
| 69 | P9 | Shard bond and timeout open | O-5.6 on the phase 4 devnet | measurement | before testnet | no |
|
||||
| 70 | E7, P10 | Genesis bridge trust model undecided | Decided 3 October 2026: spec 7.3, no bridged stablecoins at genesis, no official bridge, proof bridge with the consensus proof in phase two; LP and HP text changed. Remaining: O-5.2, how the IGN settlement switch is activated | done (the project lead); Claude for O-5.2 | before testnet | no |
|
||||
| 71 | G1 | No cryptographer; no named reviewers | Contract a cryptographer for phases 1 and 2; name and pay external reviewers before gate 3 | the project lead | before testnet | EXPOSES: contracts come from the entity; reviewers are told the founder is pseudonymous |
|
||||
| 72 | G7, X6 | The update channel is a key; the installer is a honeypot vector | Decided 3 October 2026: spec 08-client-security.md (reproducible builds, release key in genesis and in hardware, no silent updates, consensus only by 90% signalling, notarised builds, official sources with the hash, seed confirmed before mining, hardware wallet, the permanent line). The line is on HP and LP. Remaining: O-8.1, the key custody policy and toolchain publication | the project lead (key custody) | before testnet | no |
|
||||
| 73 | X5 | "1,000 independent miners" is a Sybil number | Define independence measurably (distinct ASNs, benchmark hardware fingerprints, pool attestations) before the gate is tested | Claude drafts, the project lead decides | before testnet | no |
|
||||
| 74 | G4 | Genesis contract and bridge key policies | Publish each genesis contract's key policy before launch (O-5.4 without the fund contract) | Claude, the project lead | before mainnet | no |
|
||||
| 70 | E7, P10 | Genesis bridge trust model undecided | Decided 3 October 2026: spec 7.3, no bridged stablecoins at genesis, no official bridge, proof bridge with the consensus proof in phase two; LP and HP text changed. Remaining: O-5.2, how the IGN settlement switch is activated | done (the founder); Claude for O-5.2 | before testnet | no |
|
||||
| 71 | G1 | No cryptographer; no named reviewers | Contract a cryptographer for phases 1 and 2; name and pay external reviewers before gate 3 | the founder | before testnet | EXPOSES: contracts come from the entity; reviewers are told the founder is pseudonymous |
|
||||
| 72 | G7, X6 | The update channel is a key; the installer is a honeypot vector | Decided 3 October 2026: spec 08-client-security.md (reproducible builds, release key in genesis and in hardware, no silent updates, consensus only by 90% signalling, notarised builds, official sources with the hash, seed confirmed before mining, hardware wallet, the permanent line). The line is on HP and LP. Remaining: O-8.1, the key custody policy and toolchain publication | the founder (key custody) | before testnet | no |
|
||||
| 73 | X5 | "1,000 independent miners" is a Sybil number | Define independence measurably (distinct ASNs, benchmark hardware fingerprints, pool attestations) before the gate is tested | Claude drafts, the founder decides | before testnet | no |
|
||||
| 74 | G4 | Genesis contract and bridge key policies | Publish each genesis contract's key policy before launch (O-5.4 without the fund contract) | Claude, the founder | before mainnet | no |
|
||||
|
||||
### 2.1 Answered entries that still carry something
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ Added after `docs/review/round-3-2026-10-03.md`. Rows continue the numbering of
|
|||
| 82 | F15 | Merge depth called the reorg bound; the code's bound is the finality depth, 43,200 DAA s | Spec 2.1, 3.8 and 3.9 name the finality depth, in median time (12 h), 3 October 2026; simnet reorg test (2, 6, 13 h forks) written into 2.1 for gate 2. LP Finality (first-month and merge-depth sentences) and "What Igneum does not claim" item 4 rewritten the same evening: 12-hour finality depth, merge depth a merge limit. Left: the simnet test | Claude (done); measurement (simnet) | before testnet | no |
|
||||
| 83 | E9 | Spec year 365 days; code 365.25 (31,557,600 s, halving 63,115,200 s, 3,168,808,781 sompi/s) | Spec 2.5 follows the code, 3 October 2026. Divergence record for the code owner: the spec was changed, the code was not; add a test that reads the published numbers (year, halving interval, per-second rate, ramp) and asserts them against `consensus/core/src/igneum.rs`, and decide O-2.6 (8 decimals fits the u64 cap, 18 does not) before the first testnet genesis | code, owner consensus engineer | before testnet | no |
|
||||
| 84 | E10 | Spec said reds unpaid and "more blocks never means more coins"; code pays reds in the DAA window to the merger and mints per block | Spec 2.5 follows the code, 3 October 2026. Divergence record for the code owner: no code change; the litepaper Speed sentence ("never per block") was rewritten the same evening to match 2.5: emission per block on a schedule keyed to difficulty-adjusted time, reds in the window paid, coins track blocks within the controller's accuracy | Claude | done | no |
|
||||
| 85 | G9 | Release key: single steward, lost key unrevocable | Spec 8.2 items 2 and 5 rewritten 3 October 2026: key chain, rotation signed by the current key, revocation signed by the previous key (pre-signed certificate for K0), published in a block; policy before the client ships, with entity and jurisdiction. Left: the policy itself and the second holder (O-8.1, L1) | the project lead (custody), counsel | before testnet | EXPOSES: the policy names the entity, never a person's residence |
|
||||
| 85 | G9 | Release key: single steward, lost key unrevocable | Spec 8.2 items 2 and 5 rewritten 3 October 2026: key chain, rotation signed by the current key, revocation signed by the previous key (pre-signed certificate for K0), published in a block; policy before the client ships, with entity and jurisdiction. Left: the policy itself and the second holder (O-8.1, L1) | the founder (custody), counsel | before testnet | EXPOSES: the policy names the entity, never a person's residence |
|
||||
| 86 | M15 | Pre-validation PoW cost: any past timestamp or claimed DAA score forces a 256 MiB cache fill before the checks that would reject the header | Run `check_difficulty_and_daa_score` and the past-median check before `check_pow_and_calc_block_level` in `validate_header`; derive the day from DAA score or the selected parent's window; `KEEP` 4; per-peer cap on cache builds. Review's first of five | code, owner consensus engineer | now | no |
|
||||
| 87 | M20 | Pruning proofs validated with the kHeavyHash stub: a fresh node cannot sync from a lottery-mined pruning point; a loosened check is forgeable with an existing ASIC | Thread the epoch and day seeds through `pruning_proof/validate.rs`, `apply.rs` and `mod.rs` (fork map a4, O-2.5); test by syncing a fresh node from the 30-hour devnet | code, owner consensus engineer | before testnet | no |
|
||||
| 88 | P12 | An aggregator rewrites `ProofRecord.provers` and takes the pool; shard proofs do not commit to the prover | Shard statement gains the prover's payout key as a public input, aggregation carries the keys as public outputs, a record whose list does not match is invalid; acceptance test A5 checks the match. Spec 7 and `docs/design/execution-layer.md` 5.1, 5.6 and 9.2 change with the code | code, owner consensus engineer (with execution engineer) | before testnet | no |
|
||||
|
|
@ -153,15 +153,15 @@ Added after `docs/review/external-2026-10-03.md`. Rows continue the numbering of
|
|||
| 92 | P17 | Three states shown; included is a list | Design 2.4 written 3 October 2026 (night). Left: `state` field in `igneum_getTransactionStatus`, the phone-app and explorer words, the O-7.2 conformance set | Claude (design, done); code, owner execution engineer | before testnet | no |
|
||||
| 93 | E12 | No stress test of mining against proving under shocks; R8 has not run | O-5.9: R8 extended with 10x external pay, falling price, operator exit, unfulfilled assignments, profit-only clients; then the phase 4 devnet | Claude (sim), measurement | before testnet | no |
|
||||
| 94 | E13 | No payment-route diagram; the routes are spread over LP Economics, the HP tiles and the customer brief | O-5.10: one figure, one route per row (emission, base fee, priority fee, jobs at launch, jobs after the bridge, client dev fee), in LP Economics and the brief; operator revenue never summed with protocol revenue | Claude | now | no |
|
||||
| 95 | E14 | No funding table | Cost lines against sources, labelled funded / dependent on revenue / unfunded, with the late-revenue case; internal until counsel reads it; unfunded lines stated in LP | the project lead (numbers), Claude (table) | before public repo | EXPOSES: sources name the entity, never a company the project lead already owns |
|
||||
| 95 | E14 | No funding table | Cost lines against sources, labelled funded / dependent on revenue / unfunded, with the late-revenue case; internal until counsel reads it; unfunded lines stated in LP | the founder (numbers), Claude (table) | before public repo | EXPOSES: sources name the entity, never a company the founder already owns |
|
||||
| 96 | E15 | Security budget through halvings with low fees, no demand and a flat price: unmodelled | O-5.11 model; the failing year and price stated in LP Supply next to the tail alternative (row 27) | Claude (model) | before mainnet | no |
|
||||
| 97 | G11 | Repository private; harnesses, vectors, simulators and spec could be public now, labelled experimental | the project lead decides the components, licence and date; section 5 steps 1 to 7 first in any case; one proof-request workflow and one reference app before any app set | the project lead | now (decision) | no |
|
||||
| 98 | X13 | Phase 4 gate is a signature; the brief says no payment | Brief v0.2: agree workload, proof format, deadline, failure rate and price before the pilot; publish the outcome and the customer's reason; paid pilot added to the J phase 5 line; entity and terms per L4; timing is the project lead's | Claude (brief), the project lead, counsel | before testnet | no |
|
||||
| 99 | X14 | Independence undefined; concentration in hashing, signing, proving and aggregation unreported | O-X.1: define independence; four concentrations as top-1, top-3 and top-10 shares over 30 days on the live page beside the gate | Claude (observer), the project lead (definition) | before testnet | no |
|
||||
| 97 | G11 | Repository private; harnesses, vectors, simulators and spec could be public now, labelled experimental | the founder decides the components, licence and date; section 5 steps 1 to 7 first in any case; one proof-request workflow and one reference app before any app set | the founder | now (decision) | no |
|
||||
| 98 | X13 | Phase 4 gate is a signature; the brief says no payment | Brief v0.2: agree workload, proof format, deadline, failure rate and price before the pilot; publish the outcome and the customer's reason; paid pilot added to the J phase 5 line; entity and terms per L4; timing is the founder's | Claude (brief), the founder, counsel | before testnet | no |
|
||||
| 99 | X14 | Independence undefined; concentration in hashing, signing, proving and aggregation unreported | O-X.1: define independence; four concentrations as top-1, top-3 and top-10 shares over 30 days on the live page beside the gate | Claude (observer), the founder (definition) | before testnet | no |
|
||||
| 100 | X15 | "The chain runs without its founders" untested | O-X.2: 24-h founder shutdown on the public testnet at a published time; record what continues | measurement | before mainnet | no |
|
||||
| 101 | X16 | No evidence page; one voice for implemented, team-tested, reproduced and reviewed | O-X.3: one row per public claim with status, version, test, result and one of the four labels; audits tied to versions; ships with the benchmark | Claude | before public repo | no |
|
||||
| 102 | X17 | Client shows gross earnings only; no mining and proving split, no failed jobs, no isolation design | O-8.2 display rules (client and phone-app 4.1, written 3 October 2026 night); O-8.3 isolation design before the first external job; update control already spec 8.2 item 4 | Claude (design); miner client (code) | before testnet | no |
|
||||
| 103 | M22 | Bounty has no metric, judge, eligible hardware or fund; 2x is not the economic line | Scoring rules (per-program distribution of hash/s and hash/J, capital per unit of hash rate, longevity, shortcut classes) published with the benchmark; funder, judge and reward are the project lead's; public claim limited to "competitive against the best independently proposed design across tested workloads" | Claude (rules), the project lead (fund) | before public repo | EXPOSES: the payer is the entity (row 50) |
|
||||
| 103 | M22 | Bounty has no metric, judge, eligible hardware or fund; 2x is not the economic line | Scoring rules (per-program distribution of hash/s and hash/J, capital per unit of hash rate, longevity, shortcut classes) published with the benchmark; funder, judge and reward are the founder's; public claim limited to "competitive against the best independently proposed design across tested workloads" | Claude (rules), the founder (fund) | before public repo | EXPOSES: the payer is the entity (row 50) |
|
||||
|
||||
### 2.6 Sweep (5 October 2026, evening), round 6: the experiment and status items
|
||||
|
||||
|
|
@ -175,19 +175,19 @@ Appended by the consensus engineer and cryptographer agent (worktree `igneum-wt-
|
|||
| 117 | M20 | Done and rolled out (0.3.5, `m20-pruning`, 4 tests). Left: the live test, a fresh node syncing once the pruning point leaves genesis (still genesis at DAA 113,289 at 16:00 UTC) | consensus engineer | tonight or tomorrow, when the point moves |
|
||||
| 2.5 (M30, "the flood memory growth") | M30 | Done and rolled out (0.3.5): cache builds equal node restarts (5 / 5 / 8 in 10 h), none at the epoch rolls | none | done |
|
||||
| (F25) | F25 | Done and rolled out (0.3.5 merge 7abce72); both harness libraries ran tonight | none | done |
|
||||
| (F21, F22) | F21, F22 | Shipped in every node since 0.3.4; the switch `finality_v3_activation_daa` is absent from the live override file. Rollout = N3 of `docs/plans/finality-v3-rollout-devnet.md` | the project lead (N3), then the operator steps | now |
|
||||
| 50 | M1 | Program space counted (about 2^1550 shapes under a 2^256 seed; the per-program spread is 1.10x under version 2). The claim stays a target; the experiment stays the bounty and benchmark | the project lead (M22 terms), Claude (benchmark) | before public repo |
|
||||
| (F21, F22) | F21, F22 | Shipped in every node since 0.3.4; the switch `finality_v3_activation_daa` is absent from the live override file. Rollout = N3 of `docs/plans/finality-v3-rollout-devnet.md` | the founder (N3), then the operator steps | now |
|
||||
| 50 | M1 | Program space counted (about 2^1550 shapes under a 2^256 seed; the per-program spread is 1.10x under version 2). The claim stays a target; the experiment stays the bounty and benchmark | the founder (M22 terms), Claude (benchmark) | before public repo |
|
||||
| 60 | M11 | Measured on five machines, four compilers, three vendors over 10 to 12 boundaries each: NVRTC 0.6 to 1.1 s, OpenCL 7 to 12 s (iGPU 55 to 124 s beside builds), Metal under 0.5 s plus the race; 5090 race +0.00%, base twice. Left: multi-card rig, ROCm (hardware) | measurement (O-1.16) | before testnet |
|
||||
| 55 | M16 | Cost model written (`docs/analysis/m16-recompute-attacker-2026-10-05.md`): 1.5x to 2.4x at equal integer budget, 3x to 6x with a fixed-function factor, the mixer-cost lever. Left: the 64 MiB-cache inline kernel on the 5090 (PC job), O-1.6 | measurement; the project lead at gate 1 | before public repo |
|
||||
| 55 | M16 | Cost model written (`docs/analysis/m16-recompute-attacker-2026-10-05.md`): 1.5x to 2.4x at equal integer budget, 3x to 6x with a fixed-function factor, the mixer-cost lever. Left: the 64 MiB-cache inline kernel on the 5090 (PC job), O-1.6 | measurement; the founder at gate 1 | before public repo |
|
||||
| 121 | M21 | Block sizes measured (p50 723 B, max 6.9 KB); k 5 at the measured p99, 6 with 500 KB bodies, 18 at 5 s. Left: O-2.2 with proof-bearing bodies | consensus engineer | before testnet |
|
||||
| 57 | P3 | The certificate half measured in a phone-sized tab (139 to 155 ms cold, 58 to 68 ms warm, on the laptop's CPU; no phone); the wrapper is unbuilt | measurement (phase 2) | before public repo |
|
||||
| 69 | P9 | Parameter table written from the live numbers (8 assignees, window 10 DAA s today, 25 s proposed, no shard bond, 120-s job claim timeout, `S_p` 30,000 at v1). Left: O-5.1 and O-5.6 values on the phase 4 devnet | the project lead (values), measurement | before testnet |
|
||||
| 69 | P9 | Parameter table written from the live numbers (8 assignees, window 10 DAA s today, 25 s proposed, no shard bond, 120-s job claim timeout, `S_p` 30,000 at v1). Left: O-5.1 and O-5.6 values on the phase 4 devnet | the founder (values), measurement | before testnet |
|
||||
| (P14) | P14 | Fixed in spec 05 section 5.1: one controller, the EIP-1559 step of `next_base_fee`. Left: design 4.1's "smoothed" phrase; R1 band, R8 | execution engineer | when convenient |
|
||||
| (F16) | F16 | Two options priced, B recommended (never withdraw, as 3.11.4). Left: replace the 3.5 paragraph, `finality_conflict` in the node, the forced double-certificate test | the project lead (gate 3), consensus engineer | before testnet |
|
||||
| 73 | X5 | Measurement defined: N_ind = distinct (ASN, machine fingerprint, pool attestation) classes among keys above dust; today N_ind by fingerprint is 5 for 21 keys. Left: the observer's ASN and fingerprint columns, the pool statement format | Claude (observer), the project lead (definition) | before testnet |
|
||||
| (F16) | F16 | Two options priced, B recommended (never withdraw, as 3.11.4). Left: replace the 3.5 paragraph, `finality_conflict` in the node, the forced double-certificate test | the founder (gate 3), consensus engineer | before testnet |
|
||||
| 73 | X5 | Measurement defined: N_ind = distinct (ASN, machine fingerprint, pool attestation) classes among keys above dust; today N_ind by fingerprint is 5 for 21 keys. Left: the observer's ASN and fingerprint columns, the pool statement format | Claude (observer), the founder (definition) | before testnet |
|
||||
| 65 | C4 | The overlay measured against bare GHOSTDAG on the same binary (`tools/finality-attacks/c4.mjs`): see the ledger entry and the bench-log table | cryptographer | before testnet |
|
||||
| 43, 44, 46, 58 | L1 to L5 | Untouched; decision owner line added (the project lead, with counsel) | the project lead, counsel | as rowed |
|
||||
| 9 | G3 | Untouched; decision owner line added (the project lead) | the project lead | now |
|
||||
| 43, 44, 46, 58 | L1 to L5 | Untouched; decision owner line added (the founder, with counsel) | the founder, counsel | as rowed |
|
||||
| 9 | G3 | Untouched; decision owner line added (the founder) | the founder | now |
|
||||
|
||||
## 3. Overclaims still in public text today
|
||||
|
||||
|
|
@ -280,7 +280,7 @@ Added after `docs/review/round-4-2026-10-04.md`. Rows continue the numbering of
|
|||
|
||||
| # | Ledger | Issue | Fix | Who | When | EXPOSES |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 104 | X23 | Either relay secret queues administrator PowerShell on the PCs; the intake key is the relay key, is in 6 tracked files and ships in every package; the relay-clients zip with both secrets is hosted behind the dl token | Zip off the host; rotate the relay token; a relay key of its own; a second per-machine secret or a signature for `run`; rotate the intake key and repackage (2 h) | the project lead (rotation), relay owner | now | EXPOSES: the PCs are the founder's own machines |
|
||||
| 104 | X23 | Either relay secret queues administrator PowerShell on the PCs; the intake key is the relay key, is in 6 tracked files and ships in every package; the relay-clients zip with both secrets is hosted behind the dl token | Zip off the host; rotate the relay token; a relay key of its own; a second per-machine secret or a signature for `run`; rotate the intake key and repackage (2 h) | the founder (rotation), relay owner | now | EXPOSES: the PCs are the founder's own machines |
|
||||
| 105 | G13 | The OTA manifest is signed over an installer whose node and worker binaries arrived unsigned from the dl host; signing is automatic from the latest green run | Sign `payload-inputs.zip` on the Mac, verify in CI; `OTA_SKIP=1` by default, the signing step names the run (2 h) | release engineer | now | no |
|
||||
| 106 | G12, X18 | `IGNEUM_POW_*` sets the schedule on every network; no params digest or genesis hash in the handshake; a finality mismatch is a WARN; `rollout-v2.sh` drops the finality block | Delete the fallback; digest plus genesis hash in the version message, refused on mismatch; the WARN becomes a refusal (4 h) | consensus engineer (code) | before testnet | no |
|
||||
| 107 | F23, F24 | Node-local equivocation ban time; checkpoint determination never revisited | Carrier-DAA bans; re-determine on a reorg deeper than d; two-node tests (4 h) | consensus engineer, cryptographer (code) | before testnet | no |
|
||||
|
|
@ -290,7 +290,7 @@ Added after `docs/review/round-4-2026-10-04.md`. Rows continue the numbering of
|
|||
| 111 | M29 | LP 424 describes earnings in currency, a hardware wallet and proving the app does not have | Rewrite to 0.3.3; earnings, currency and the hardware wallet become a roadmap sentence | Claude | now | no |
|
||||
| 112 | F21 | LP 511 says a third of the blocks is needed to split finality in a partition | The round-4 section 1 (b) sentence | Claude | now | no |
|
||||
| 113 | X24, X25, X26, X27 | Token in the URL path and printed; agent self-installs at every start; permanent feed with the dl token in bodies; free-text `from` and no clean rotation | Header token in every client, HSTS, masked prints; arm only on `reboot_continue`; retention and a cap; sender binding; documented rotation (3 h) | relay owner | now | no |
|
||||
| 114 | G14 | The intake key (8 commits), the dl token (1), the review files, 51 files with the first name, local-time stamps | Section 5 step 4's rewrite list extended; `TZ=UTC` now | the project lead, Claude | before public repo | EXPOSES: yes, the whole row |
|
||||
| 114 | G14 | The intake key (8 commits), the dl token (1), the review files, 51 files with the first name, local-time stamps | Section 5 step 4's rewrite list extended; `TZ=UTC` now | the founder, Claude | before public repo | EXPOSES: yes, the whole row |
|
||||
| 115 | X19, X20, M25, M28, X22, X28, X29, E17 | The minors of round 4 (node knobs and silences, cold-sync cost, miner day length, kernel commitment, restart paths, relay hygiene, host and file modes, unlogged economics inputs) | As each ledger entry says; the stray token-named file and the 0644 modes today | consensus engineer, miner-community-lead, relay owner, Claude | when convenient | no |
|
||||
| 116 | X30 | Bench page private strings; /api/live addresses, key hashes, payout addresses; the mobile menu | Fixed 4 October 2026: `ac89a37`, `6b644a6`, `2d8f09c`, `621f5cc` | Claude | done | no |
|
||||
|
||||
|
|
@ -305,7 +305,7 @@ Added by `docs/review/ledger-sweep-2026-10-05.md`, which holds what ran, what di
|
|||
| 119 | P15 | The RPC block's `gasLimit` is one block's `B_e` beside a segment's summed `gasUsed` (`proving` branch, `igneum/exec/src/rpc.rs:355-356`) | Report `k x B_e` for a k-block segment, or document the invariant break for Blockscout (R10) (1 h) | execution engineer | before a public RPC | no |
|
||||
| 120 | M28 | Nothing commits the seed to the kernel text the worker compiles; no kernel hash exists on any branch | A hash of the emitted kernel in `program.json`, derived from the seed by the miner and checked by both workers; one sentence in the docs that the chain commits to the seed, not the text (3 h) | miner lead | before testnet | no |
|
||||
| 121 | M21 | k = 18 is Kaspa's table value; `calculate_ghostdag_k` gives k 5 at the cloud devnet's measured p99 of 0.67 s and k 55 at a 20-s bound, and proof-bearing bodies are unmeasured | Run O-2.2 with bodies of the size design 5.4 implies, take the p99 propagation, re-derive k with the fork's function (the table is in the ledger entry) (3 h) | consensus engineer | before testnet | no |
|
||||
| 122 | X29 | The live node's gRPC listens on every interface (`igneumd` on `*:26610`, read-only check 5 October); the file modes are fixed | `--rpclisten=127.0.0.1:26610`; PC 2 through a tunnel or its own node (0.5 h) | app owner, the project lead | now | no |
|
||||
| 122 | X29 | The live node's gRPC listens on every interface (`igneumd` on `*:26610`, read-only check 5 October); the file modes are fixed | `--rpclisten=127.0.0.1:26610`; PC 2 through a tunnel or its own node (0.5 h) | app owner, the founder | now | no |
|
||||
| 123 | M14, F14 | O-3.14 (the finality simulation with the DAA in the loop under both forms of W2) has no DAA model inside `finality_v2.py`; the chain-model result (no amplification under either controller) stands in for it | Add a lagging retarget to `finality_v2.py` (Kaspa's sampled window and rule v2), run the 50x pulse under both W2 forms, log the day the renter crosses a third (4 h) | cryptographer (sim) | before testnet | no |
|
||||
| 124 | F1, O-3.1 | Spec 06 row O-3.1 still said "not yet in `sim/`" and the ledger's launch-month arithmetic was in prose only | Done in the sweep (5 October 2026): rows O-3.1, O-3.14, O-5.9 and O-5.11 of spec 06 carry tonight's evidence (O-3.15 was already marked decided) | Claude (spec) | done | no |
|
||||
| 125 | X14 | Only hashing concentration can be computed from what the observer keeps; signing, proving and aggregation need certificate and proof-record extracts | The observer stores signer bitmaps per certificate and prover keys per proof record; a nightly top-1/3/10 table on the live page (3 h) | app owner (observer) | before testnet | no |
|
||||
|
|
@ -326,7 +326,7 @@ Appended by the public-text closer (worktree `igneum-wt-ledger-text`, branch `le
|
|||
| 28, 29, 9, 30, 32 | G1, G2, G3, G4, G6 | Verified and moved. G3: the entry's first Status line is now the Decided line (no team page; "The team is pseudonymous and there is no team page" in the litepaper), the older line kept prefixed "Was:" | none | done |
|
||||
| 14, 12, 13, 34, 49 | C2, C3, C5, C6, C8, C10, C11 | Verified and moved | none | done |
|
||||
| (C13, M18, L8) | C13, M18, L8 | C13: "they say nothing about the price of a chip with the 256 MB cache on its die" in What Igneum does not claim. M18 verified. L8: "whether it is issued is Circle's decision" in Questions builders ask; Canto and Blast absent. All moved | none | done |
|
||||
| 6 | L2 (text half) | "so the people who show up early get the most" removed from Supply; schedule fact only. Counsel half unchanged, decision owner the project lead | the project lead, counsel | before public repo |
|
||||
| 6 | L2 (text half) | "so the people who show up early get the most" removed from Supply; schedule fact only. Counsel half unchanged, decision owner the founder | the founder, counsel | before public repo |
|
||||
| 110 | L9 | "Devnet: coins have no value and the chain may be reset." beside every download control on index, miner and wallet; the homepage tiles read "of emission to miners and provers; the protocol carries no fee" and "0% anyone else in the protocol". Not done: the same line on `/live` (outside this round's files) | Claude (live page) | now |
|
||||
| 111 | M29 | The litepaper's app paragraph rewritten to Ember 0.3.9 from the shipped UI; earnings, currency, game pause and the hardware wallet moved to a roadmap sentence; nothing from an unmerged branch | none | done |
|
||||
| 109 | E16 (text half) | The 20% row and the homepage bar now say the coinbase's 20% output is burned under `igneum-proving-pool-v0` and provers are paid from the execution-state escrow credited with the same 20%; the single coinbase payout stays Open (code half, group D) | consensus engineer (payout) | before testnet |
|
||||
|
|
@ -358,13 +358,13 @@ Closed on the evening of 3 October 2026 (written into `docs/spec/` the same even
|
|||
|
||||
Changed, not closed:
|
||||
|
||||
- E3 (wash gas): under 80/20 a developer alone gets 20% of its own tip back and loses 80%. A developer who also mines the block gets 80% plus 20%, less the provers' part of the 80%. The only certain loss is the base fee. The ledger's "guaranteed loss of 20% of the tip plus the base fee" no longer holds. the project lead confirms the 15% priority-fee burn is gone on purpose; if not, the split is 80/20 of what remains after a burn and the numbers in row 7 change.
|
||||
- E3 (wash gas): under 80/20 a developer alone gets 20% of its own tip back and loses 80%. A developer who also mines the block gets 80% plus 20%, less the provers' part of the 80%. The only certain loss is the base fee. The ledger's "guaranteed loss of 20% of the tip plus the base fee" no longer holds. The founder confirms the 15% priority-fee burn is gone on purpose; if not, the split is 80/20 of what remains after a burn and the numbers in row 7 change.
|
||||
- E5 (dev fee to the founder's company): the ledger says the company carries development "until usage funds the development fund". There is no fund, so the company carries it for as long as the 1% fee, the pool and the proving business pay. That is the sentence the litepaper must carry, and it sharpens L1.
|
||||
- G5 (second client): "funded from the development fund as its first priority" has no funder. Row 47.
|
||||
- G3 (who are you): the anonymous founder is now the design, not a flaw to rebut. The ledger's "The founder's name is on every commit" is void. Row 9. The team-page-at-testnet decision needs re-confirming.
|
||||
- L1 and L2 (counsel): "offshore, parked" and "jurisdiction not yet named" become "offshore, being established", which is a jurisdiction counsel can be briefed in. Not closed until the opinion exists.
|
||||
- The ledger header ("Published alongside the litepaper") and its submission paragraph are now wrong under (b). Both lines were rewritten on 5 October 2026 under the later decision: published with the repository at the public testnet, submissions to hello@igneum.network or the repository issues.
|
||||
- Decision (e) makes CLAUDE.md stale: it still says the Vercel project lives in the [other-business] team (moved per commit 61aa946) and lists two organisation owners. Section 5 step 2.
|
||||
- Decision (e) makes CLAUDE.md stale: it still says the Vercel project lives in the other business's team (moved per commit 61aa946) and lists two organisation owners. Section 5 step 2.
|
||||
|
||||
Text the decisions force, beyond the overclaims list: row 7 lists every file. The design document is the eleventh place and the only one outside the repository.
|
||||
|
||||
|
|
@ -375,11 +375,11 @@ The repository goes public at the public testnet (decision of 5 October 2026). T
|
|||
Nothing below is optional. The history, not just the working tree, carries the names: CLAUDE.md with the full name is in every commit, the ledger's earlier L2 text ("The founder is in the UK") is in the commits before 14ef6b3, and site/ledger.html (636 lines, the full ledger rendered) is in the commits before the same one. The commit author and committer on every commit is igneum-labs, and every commit carries a local-time offset one hour ahead of UTC, which is UK or Irish summer time in early October. A file edit fixes none of that.
|
||||
|
||||
1. Keep the ledger in the tree and publish it with the repository (decision of 5 October 2026, which replaces decision b). `docs/fud-ledger.md` and this file (`docs/fud-fixes.md`) are on the public export list of `tools/ci/identity-check.sh`; every hit the check finds in them is reworded before the first public push, and no entry is removed. The ledger still maps the providers (GoDaddy, Vercel) and names `.claude/agents/`; the private export rules cover the founder's name, and the rest is reworded in place. The spec and the open-items file cite ledger ids (M7, F1, P8 and so on); those ids do not change.
|
||||
2. Rewrite CLAUDE.md as a public file. Remove: line 4 ("the project lead's project"); every "the project lead" (lines 22, 34, 39, 41, 46, 48, 52; "the project lead's copy law" becomes "the copy law"); line 42 (the second owner [second-owner-login], "the project lead, the igneum.network Google login", the sentence about 40 commits carrying his name); line 43 ([other-business] team; it is the igneum team now); line 44 (Neon id and London region); lines 46 to 49 (registrar, "Full Protection", the purchase quotes; after December the registrar changes anyway); lines 51 to 53 (the browser-profile section names every other business: [other-business], QUANTUM, [other-business], [other-business], [other-business], [other-business]); the claude.ai artifact and doc links in "Source of truth" (they identify the tooling account). Move the operational notes (accounts, registrar, database id, browser profile, deploy scope) to a file outside the repository, for example `~/.config/igneum/NOTES.md`.
|
||||
3. Scrub `.claude/agents/cryptographer.md` line 32 ("unless the project lead overrides" becomes "unless the project lead overrides"). The other three agent files are clean. Decide whether `.claude/agents/` stays public at all; if it does, it is the G2 disclosure and consistent with row 29.
|
||||
4. Rewrite the history once, before the first public push. Nothing is public and nobody has cloned, so the cheapest safe route is to squash to one root commit ("Igneum: public tree") authored by a neutral handle at a UTC timestamp. If the history is kept instead, run git filter-repo to: drop `site/ledger.html` from every commit; replace CLAUDE.md, the agent file, `docs/fud-ledger.md` and `docs/fud-fixes.md` in every commit with the scrubbed versions; rewrite every author and committer to the neutral handle; rewrite every date to +0000. Either way: rename the GitHub account igneum-labs to a handle without a name (the noreply address keeps its numeric id, so the rename is one setting), confirm [second-owner-login] is no longer an organisation owner (decision e says one anonymous owner), and set `TZ=UTC` in whatever script commits from now on so no local-time offset appears again.
|
||||
2. Rewrite CLAUDE.md as a public file. Remove: line 4 ("the founder's project"); every "the founder" (lines 22, 34, 39, 41, 46, 48, 52; "the founder's copy law" becomes "the copy law"); line 42 (the second owner the second owner login, "the founder, the igneum.network Google login", the sentence about 40 commits carrying his name); line 43 (other business's team; it is the igneum team now); line 44 (Neon id and London region); lines 46 to 49 (registrar, "Full Protection", the purchase quotes; after December the registrar changes anyway); lines 51 to 53 (the browser-profile section names every other business: the other business, QUANTUM, the earlier entity, the earlier business, another brand, another brand); the claude.ai artifact and doc links in "Source of truth" (they identify the tooling account). Move the operational notes (accounts, registrar, database id, browser profile, deploy scope) to a file outside the repository, for example `~/.config/igneum/NOTES.md`.
|
||||
3. Scrub `.claude/agents/cryptographer.md` line 32 ("unless the founder overrides" becomes "unless the project lead overrides"). The other three agent files are clean. Decide whether `.claude/agents/` stays public at all; if it does, it is the G2 disclosure and consistent with row 29.
|
||||
4. Rewrite the history once, before the first public push. Nothing is public and nobody has cloned, so the cheapest safe route is to squash to one root commit ("Igneum: public tree") authored by a neutral handle at a UTC timestamp. If the history is kept instead, run git filter-repo to: drop `site/ledger.html` from every commit; replace CLAUDE.md, the agent file, `docs/fud-ledger.md` and `docs/fud-fixes.md` in every commit with the scrubbed versions; rewrite every author and committer to the neutral handle; rewrite every date to +0000. Either way: rename the GitHub account igneum-labs to a handle without a name (the noreply address keeps its numeric id, so the rename is one setting), confirm the second owner login is no longer an organisation owner (decision e says one anonymous owner), and set `TZ=UTC` in whatever script commits from now on so no local-time offset appears again.
|
||||
5. Check the organisation and the account profiles: no location, no personal avatar, no personal email, 2FA on, the organisation's public members list empty. The Vercel team igneum and the Workspace are not visible from the repository; nothing to do there beyond step 2.
|
||||
6. Add a LICENSE and a root README. Neither exists (`git ls-files` shows no root README or LICENSE). A public repository without a licence invites the first issue to be about the licence. the project lead picks the licence.
|
||||
6. Add a LICENSE and a root README. Neither exists (`git ls-files` shows no root README or LICENSE). A public repository without a licence invites the first issue to be about the licence. The founder picks the licence.
|
||||
7. Re-run the sweep from this evening on the final tree: `git ls-files | xargs grep -nIE -f igneum-public/tools/identity.local` (the private identity list, case-insensitive) must return nothing, and `git log --format='%an %ae %cn %ce %ad'` must show one neutral identity and +0000 only. Secrets: the history grep for connection strings and tokens returned zero hits today; repeat it after the rewrite.
|
||||
8. Fix the public text first (rows 1 to 41). The ledger's X1 answer is that the honest route is to open the repository with the bench logs, the simulator and the test report. Opening it with "no chip can ever" still on the homepage hands the first critic the ledger's own list.
|
||||
9. Put the GitHub links back on HP and the /bench page (row 1) on the day the repository opens, at the public testnet.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Statuses used:
|
|||
| Answered by design | A consensus rule or a design decision answers it; no measurement is needed or possible yet |
|
||||
| Open, experiment scheduled | We do not know. The experiment and its date are named |
|
||||
| Conceded | The critic is right. "Stated" means the litepaper already says so; "not yet stated" means the litepaper must change, and the fix is in the overclaims list at the end |
|
||||
| Closed by rule, Decided, Closed by removal | A rule now in `docs/spec/`, a decision by the project lead, or a removal answers it as of the date given, and the spec section is named. The status it replaced is kept on the line |
|
||||
| Closed by rule, Decided, Closed by removal | A rule now in `docs/spec/`, a decision by the founder, or a removal answers it as of the date given, and the spec section is named. The status it replaced is kept on the line |
|
||||
|
||||
Submitting a criticism: email hello@igneum.network (Igneum Labs LTD, Unit IH-00-01-01-OF-01, Level 01, Innovation One, Dubai International Financial Centre), or open an issue on the repository once it is public, at the public testnet. Anything that is not already in this ledger, or that shows an entry here is wrong, gets added with credit if wanted.
|
||||
|
||||
|
|
@ -30,9 +30,9 @@ Evidence locations referenced below: `docs/bench-log.md`, `proto-metal/TESTS.md`
|
|||
"Eleven integer ops, 64 instructions, 8 iterations, a splitmix register init. That is not RandomX. RandomX leans on a superscalar out-of-order CPU with floating point and branches. Yours is a sea of 32-bit ALUs and a memory bus. A chip for that is a weekend."
|
||||
|
||||
Status: Decided (6 October 2026, 17:35 UTC, by the owner; decisions item 1, corrected): no standing bounty. A team with a real 2x chip earns more by mining than any bounty pays, so a device bounty attracts nobody; the tiers announced at 17:25 UTC are withdrawn. The claim "under 2x" is backed by the paid independent cryptanalysis (the Monero route: four paid reviews, no bounty) and by the public benchmark with M22's metrics. Optional, the owner's call later: one cryptanalysis prize of USD 50,000 for a published 2x or better shortcut in the mixer, the chained cache or the acceptance rule, escrowed before it is named; nothing public before that. The claim stays a target until the audit and the benchmark have reported. Was: Open, program space counted, the claim stands as a target (5 October 2026, evening sweep). Was: Open, experiment scheduled. Sweep (5 October 2026): nothing runnable; the bounty, the public benchmark and a chip design are M22's decisions and hardware. The nearest number stays M16's arithmetic.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Sweep (5 October 2026, evening): the program space, swept as arithmetic from the version 2 generator (`igneum-pow/src/generator.rs`: 16 load slots as a uniform 16-subset of instructions 1 to 63, then nine draws per instruction, 592 draws per program; 10 non-load operations with weights 12/10/8/8/8/7/6/6/6/4; 8 registers; a 31-way rotation, a 32-way bit and a 5-way mask per instruction; two 32-bit immediates). Counting choices: the slot subset is 48.4 bits; the operation draw carries 3.26 bits of entropy (of log2 10 = 3.32); operations and registers alone give about 770 bits per program; with the rotation, bit and mask fields about 1,550 bits; with the immediates about 5,650 bits, all capped by the 256-bit seed, so the space a chip has to serve is 2^256 distinct programs drawn from a structure of about 2^1550 shapes, and the critic is right that it is a small instruction set: 12 operations, 8 registers, no floating point, no branches, by design (vendor-identical rounding). What the sweep adds to the ledger's answer is the number that matters for a fixed-function design, the spread a chip must absorb: under generator version 2 every accepted program does 120 to 128 distinct loads per hash (median 128.00, 20,000-program census), so the per-program hash-rate spread on a memory-bound device is the 1.10x residual the census measured, not the 2.7x of version 1; the chip's advantage therefore cannot come from the program (it is one fixed memory-bound shape) and must come from the memory system or from the recompute route, which is M16's cost model (`docs/analysis/m16-recompute-attacker-2026-10-05.md`: 1.5x to 2.4x at equal integer budget before any fixed-function factor, 3x to 6x with one, and the mixer-cost lever that cuts it below 1x). The experiment that closes M1 is unchanged: the bounty and the public benchmark (M22, decision owner the project lead).
|
||||
Sweep (5 October 2026, evening): the program space, swept as arithmetic from the version 2 generator (`igneum-pow/src/generator.rs`: 16 load slots as a uniform 16-subset of instructions 1 to 63, then nine draws per instruction, 592 draws per program; 10 non-load operations with weights 12/10/8/8/8/7/6/6/6/4; 8 registers; a 31-way rotation, a 32-way bit and a 5-way mask per instruction; two 32-bit immediates). Counting choices: the slot subset is 48.4 bits; the operation draw carries 3.26 bits of entropy (of log2 10 = 3.32); operations and registers alone give about 770 bits per program; with the rotation, bit and mask fields about 1,550 bits; with the immediates about 5,650 bits, all capped by the 256-bit seed, so the space a chip has to serve is 2^256 distinct programs drawn from a structure of about 2^1550 shapes, and the critic is right that it is a small instruction set: 12 operations, 8 registers, no floating point, no branches, by design (vendor-identical rounding). What the sweep adds to the ledger's answer is the number that matters for a fixed-function design, the spread a chip must absorb: under generator version 2 every accepted program does 120 to 128 distinct loads per hash (median 128.00, 20,000-program census), so the per-program hash-rate spread on a memory-bound device is the 1.10x residual the census measured, not the 2.7x of version 1; the chip's advantage therefore cannot come from the program (it is one fixed memory-bound shape) and must come from the memory system or from the recompute route, which is M16's cost model (`docs/analysis/m16-recompute-attacker-2026-10-05.md`: 1.5x to 2.4x at equal integer budget before any fixed-function factor, 3x to 6x with one, and the mixer-cost lever that cuts it below 1x). The experiment that closes M1 is unchanged: the bounty and the public benchmark (M22, decision owner the founder).
|
||||
|
||||
Answer: Correct that the arithmetic is simple on purpose. Integer only, because floating point rounds differently per vendor and would split the chain (design doc, hostile review table, row 2). The defence is not the ALU work. It is random 4-byte reads over a dataset larger than any on-chip cache: the RTX 5090 runs the same program 5.8x faster when the dataset fits in its 96 MiB L2 (1,352 Mhash/s at 64 MiB against 229 at 1 GiB, bench-log, RTX 5090 sweep). A chip has to buy the same gigabytes of memory and loses the same latency. The honest target for a chip's gain is under 2x and it is a target, not a measurement. The experiment that tests it is the standing bounty for any chip design beating a GPU by more than 2x, live with the public benchmark in January 2027 (design doc, decisions table, row 1). Until a bounty has gone unclaimed for years the claim is a target.
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ Sweep (5 October 2026, evening): stated. `site/litepaper.html`, Mining section,
|
|||
"'Any card, any vendor, bit-exact' rests on 192 vectors across two programs on one Apple chip and one NVIDIA card, all run on the same day. AMD is untested. Intel is unmentioned."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 12): a discrete AMD card (9070 XT) and a 12 GB NVIDIA card (4070) are on order for PC 2; the measurement runs on arrival. Was: Answered with evidence for what was measured; Open for AMD and Intel. Sweep (5 October 2026): Intel is now run. A Windows laptop with only an Intel UHD integrated GPU mined on the live devnet through the OpenCL worker at 1.46 MH/s, found one block that the network accepted, and its votes on checkpoints 1202 and 1203 were accepted (`docs/bench-log.md`, "first machine in the United States"). Discrete AMD is the remaining gap (hardware, O-1.15).
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: 192 of 192 vectors matched across Metal and CUDA on two programs, standalone and in batch. That is the measurement and it is small. AMD (ROCm or OpenCL) is the next run, then the full 10,200-program fuzz set on NVIDIA and AMD with the 14 edge-case programs, and the shuffle, mulhi and shift semantics must agree bit for bit on every vendor. Intel Arc after that. The litepaper says "Any card, any vendor" and should say what was measured.
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ Evidence: `docs/bench-log.md`, RTX 5090 sections. Fix: overclaims list, item 14.
|
|||
"50 ms compile is a Mac number. On a HiveOS rig the miner has to ship NVRTC or a ROCm compiler, compile for eight cards of mixed generation, and do it every hour without crashing. Every miner that tried runtime codegen had a bad year."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 12): the mixed-generation rig is borrowed from a farm operator later, at the HiveOS package's first test; the 9070 XT on order gives the ROCm half on PC 2. Was: Answered with evidence on the fleet that exists, Open for a multi-card rig and ROCm (5 October 2026, evening sweep). Was: Open, experiment scheduled. Sweep (5 October 2026): partly measured. One RTX 5090 compiled the hourly program at runtime (nvcc in the background) on the live devnet in 1,285 ms with no pause and 0 rejected (bench-log, "first hourly program swap"). A multi-card mixed rig and ROCm remain unmeasured (hardware, O-1.16).
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Sweep (5 October 2026, evening): hourly runtime codegen measured on five machines, four compilers and three vendors over the live devnet's boundaries of 5 October 2026 (miner logs through the intake, DAA 82,800 to 111,600, from each machine's 0.3.5 start; `docs/bench-log.md`, "FUD ledger sweep round 6", M11). NVRTC on the two RTX 5090s: prepare 580 to 1,074 ms in all (nvrtc 147 to 180 ms, cache, dataset, 96-lane self-test), 22 of 22 boundaries swapped with no pause, 0 rejected. OpenCL on the two integrated Radeons: prepare 6.9 to 11.7 s on PC 2 and 55 to 124 s on PC 1 (its 1 GiB dataset build on the iGPU runs beside today's WSL build jobs), the two late boundaries on PC 1 (82,800 and 93,600, the prepare sent 156 to 160 DAA before the boundary instead of 449) compiled inline, the rest swapped. OpenCL on the Intel UHD laptop: prepare 7.3 to 11.7 s (build 3.0 to 6.4 s), 7 of 7 swapped with no pause. Metal on the two Macs: program 0 to 444 ms, prepare 34 to 40 s because the hourly race runs inside it, 9 of 9 swapped with no pause. The failure the critic predicts did happen, on the 0.3.4 miner: a wrong prepared pack at DAA 61,200 made both PCs' NVIDIA workers refuse the prepare every 0.7 s for two hours (4,299 and 4,233 `prepare-failed` lines) and cross two boundaries by inline compile; the 0.3.5 miner's rate limit ended it (M27). The variant race on the 5090 (the job of `docs/plans/miner-perf.md`, run on PC 1 at 15:52 UTC with the miners stopped): 17 NVRTC variants, 3 rounds, twice; base won both runs at 139.75 and 139.65 MH/s, gain +0.00%, every variant within -1.5% (`ldcs`) and +0.05% of base, compile 232 to 300 ms for the 17, 112 s of timing per run; the Mac fleet records agree that base wins on the M5 Max with the GPU to itself (10 records, g256 at -4.2%, against +17% under 4 October's contention). The race is therefore switched off as a default worth nothing on this program class: 40 s an hour of paused mining on the Macs for a base winner. Still unmeasured: a multi-card mixed-generation rig and ROCm (hardware, O-1.16).
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ Sweep (5 October 2026, evening): stated. `site/litepaper.html`, "For miners", Ha
|
|||
|
||||
Status: Conceded, stated (6 October 2026, evening; the Horizon lane analysis `docs/analysis/horizon/algorithm.md` sections 5.4 and 8, lane 2): the era draw and the instruction reserve are automatic schedule changes against fixed datapaths and against human forks; against the stored-dataset chip every drawn parameter is firmware, and the defence against that chip is the latency-shadow work (class v4) and the price-per-joule model. Stated in `site/litepaper.html`, Mining section ("These are automatic schedule changes ... every drawn parameter is firmware") and the "A chip is impossible" item ("a chip wired for one program is a bad bet ... not the schedule"), the "Every six months" row of the comparison table, and `site/index.html`, the hourly-program note ("a chip wired for one program is useless"). The phrase "automatic anti-ASIC escalators" is withdrawn from public text; it stays in the internal design summary until that is next edited.
|
||||
|
||||
Answer: Correct. The draw hides (M, R, pos, the op weights within +-2, the fold rotations) until 2 hours before each era, and none of those needs silicon. Biasing the draw is priced at 20 days of 100 percent of the network's hash for one more sample of the same space (lane section 5.4), so the draw is unbiasable at any price that matters and that is its whole job: it is a fairness device and a fork-free schedule, not a chip defence. What a chip wired for one program loses to is the hourly program itself; what the stored-dataset chip loses to is the latency shadow (class v4, 2.1x per joule at k = 1 and 3.9x at k about 0.33, the X9’s core, against the 5090 bench row; 0.9x and 1.7x against the Apple M5 Max; recalibrated under X35) and the price per joule, which is where the public claim now rests.
|
||||
Answer: Correct. The draw hides (M, R, pos, the op weights within +-2, the fold rotations) until 2 hours before each era, and none of those needs silicon. Biasing the draw is priced at 20 days of 100 percent of the network's hash for one more sample of the same space (lane section 5.4), so the draw is unbiasable at any price that matters and that is its whole job: it is a fairness device and a fork-free schedule, not a chip defence. What a chip wired for one program loses to is the hourly program itself; what the stored-dataset chip loses to is the latency shadow (class v4, 2.1x per joule at k = 1 against the 5090 bench row, and 3.9x at k about 0.33 as the pessimistic bound: the withdrawn Antminer X9's claimed, unmeasured core, a box of commodity Sophgo SG2044 SoCs withdrawn in mid-May 2026 before any unit shipped, no independent benchmark; 0.9x and 1.7x against the Apple M5 Max; X35, X36 and attack pass AP-F5-1) and the price per joule, which is where the public claim now rests.
|
||||
|
||||
Evidence: `docs/analysis/horizon/algorithm.md` sections 5.4 (the draw's randomness, the two routes priced) and 8 (the summary), 6 October 2026; the six-era hash-rate spread of 0.8 to 3.2 percent per card in bench-log "Counter ASIC 2.0, the numbers".
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ Evidence: `docs/analysis/horizon/algorithm.md` section 5.1 (the ceiling table: m
|
|||
|
||||
Status: Relabelled (7 October 2026, morning, X36): the X9 in this row and in the litepaper paragraph is the chip Bitmain announced and withdrew before launch, its core claimed and never measured; the ladder's arithmetic against that core is unchanged.
|
||||
|
||||
Status: Conceded, implemented (6 October 2026, night; `docs/design/latency-ladder.md`, branch `ladder`, fork branch `ladder-node`, the 0.3.17 feature tree, behind `latency_ladder_activation_daa`, never until set, 0 on the testnet when the project lead says): N is a genesis ladder of six rungs (27, 35, 53, 88, 173, 267 passes; about 102,100 to 1,001,600 counted ops) with a measured admissibility flag per rung (cold verify under 10 ms on the reference core with its SMT sibling loaded, igneum-build-1, 6 October 2026: rungs 0 to 2 pass at 8.77, 8.87 and 9.23 ms, rung 3 misses by 0.08 ms under a box load of 25 and is out until a quiet re-run, rungs 4 and 5 are out at 12.38 and 14.96), and the step is consensus state derived from two bits of the header version: up one rung when 90 percent of blue blocks in each of seven consecutive windows ask for it and the rung above is admissible, down one rung symmetrically, never two rungs inside seven windows (the oldest window must begin after the last step took effect), never unconditionally. Tests, the known-failed case first: a changed N today hashes another program under the same program id (a hard fork no pack line told apart); after, rung 0 is class v4 byte for byte, a rung above carries its pass count in the id, 8,999 bps in one window of seven does not move the step, a two-step jump is impossible, down never passes rung 0, an inadmissible rung is never entered. Stated in `site/litepaper.html`, Mining section ("The work that waits can grow").
|
||||
Status: Conceded, implemented (6 October 2026, night; `docs/design/latency-ladder.md`, branch `ladder`, fork branch `ladder-node`, the 0.3.17 feature tree, behind `latency_ladder_activation_daa`, never until set, 0 on the testnet when the founder says): N is a genesis ladder of six rungs (27, 35, 53, 88, 173, 267 passes; about 102,100 to 1,001,600 counted ops) with a measured admissibility flag per rung (cold verify under 10 ms on the reference core with its SMT sibling loaded, igneum-build-1, 6 October 2026: rungs 0 to 2 pass at 8.77, 8.87 and 9.23 ms, rung 3 misses by 0.08 ms under a box load of 25 and is out until a quiet re-run, rungs 4 and 5 are out at 12.38 and 14.96), and the step is consensus state derived from two bits of the header version: up one rung when 90 percent of blue blocks in each of seven consecutive windows ask for it and the rung above is admissible, down one rung symmetrically, never two rungs inside seven windows (the oldest window must begin after the last step took effect), never unconditionally. Tests, the known-failed case first: a changed N today hashes another program under the same program id (a hard fork no pack line told apart); after, rung 0 is class v4 byte for byte, a rung above carries its pass count in the id, 8,999 bps in one window of seven does not move the step, a two-step jump is impossible, down never passes rung 0, an inadmissible rung is never entered. Stated in `site/litepaper.html`, Mining section ("The work that waits can grow").
|
||||
|
||||
Answer: Correct on both counts, and the second was the sharper one. The X9 (Bitmain, about 1 MH/s at 2,472 W, approximate, github.com/monero-project/monero/issues/10270) is a shipped 3x per-joule edge over a desktop CPU on the best-known latency-bound random-program design, seven years after launch; it makes the k = 0.3 column of the chip model a product class rather than an attacker's claim, and the public headline is now the range 2.1x (k = 1) to 3.9x (k = 0.33) over the RTX 5090 at class v4, with the ladder taking the X9 bracket to about 2.8x by rung 2 and the Apple tier's to about 1.1x by rung 3. The ladder does not close the gap; it is the chain's only automatic answer, it moves at the pace of the cards that pay for it, and the honest card's watts remain the lever that moves every row (algorithm lane proposal 7). What the ladder gives up by design: a chip holding over 10 percent of weight can stall it, and the status quo it stalls is a rung the cards already run.
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ Evidence: `sim/results.md` table E and "What the simulation cannot tell us"; des
|
|||
"The aggregator picks which votes go in the certificate once quorum is reached. A block producer carries the certificate it likes. Drop a rival pool's votes from your bitmaps for two hours and its participation factor falls, your share rises."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 13): the per-block vote bound and the bitmap wire bound of spec 3.4.2 items 2 and 3 are adopted for gate 3; the spec moves them from Proposed to Decided at the next spec edit. Was: Closed by rule (3 October 2026), parameter open. Spec section 3.3 Q2 and 3.4.1: participation is computed from every vote seen in blocks over the presence window (votes are block payload), never from the certificates an aggregator chose; the per-block vote bound is O-3.3. Was: Open, experiment scheduled. Sweep (5 October 2026): the block reading is exercised on the fork by harness s3 (block-carried votes give participation; 35 of 35 locked on each of 3 nodes) and s4 (a producer dropping the finality section from 40% of its blocks adds 0 ms to lock latency, 35 locks), bench-log "finality v2 attack harness"; the per-block vote bound and the hostile-aggregator simulation of O-3.3 were run and proposed in round 2 (5 October 2026, night, below; decision at gate 3). Re-run on the `finality-fixes` build under fast time (5 October 2026, 01:13 UTC, `run.mjs s4 --fast-time`, 2 nodes, 223 s): node B locked 14 checkpoints with a 40% vote-dropping producer, median lock latency 1,042 ms against 1,042 ms for the control, 0 ms added. PASS.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: This is a new finding from writing this ledger and it is not in the design doc. The participation factor is "observed certified votes over P divided by expected votes". If "observed" means votes present in certificates carried in blocks, then whoever aggregates and whoever produces blocks can shape it. Candidate fixes: participation computed from all votes seen in blocks (votes as transactions, not only certificates), or a certificate must include every valid vote the aggregator received above a size bound, or participation falls only on checkpoints where the key's vote appears in no certificate and no block. Goes to the cryptographer for phase 1 and to the gate 3 simulation.
|
||||
|
||||
|
|
@ -299,7 +299,7 @@ Sweep (5 October 2026, evening): stated. `site/litepaper.html`, Finality ends wi
|
|||
### F11. VDFs are exotic
|
||||
"A class-group VDF with Wesolowski proofs in a consensus-critical path, in a project with no cryptographer. Chia needed years and still got timelord ASICs."
|
||||
|
||||
Status: Answered by design, with the dependency conceded.
|
||||
Status: Answered by design, with the dependency conceded. Update 7 October 2026 (era VDF lane): the era VDF is in the node (spec 4.4 Implemented, behind `era_vdf_activation_daa`, never until the founder sets it per network), on a fixed-width integer with no C library, with the hash-chain fallback behind the genesis scheme byte for the day a class group's order is computable; the attack pass's F7 harness fires against the stand-in (1 of 6 cuts re-rolled at no delay) and is silent against the VDF (0 of 6); the measured rates, prove and verify times and the margin against the fastest known prover (chiavdf's AVX-512 path on the same box) are in `docs/analysis/era-vdf-2026-10-07.md`. The timelord-ASIC point is answered by the margin table of spec 4.6: the delay only has to exceed the 2-s publish window, and it does so by orders of magnitude on the fastest evaluator measured. The external review (O-4.1) is still owed. Was: Answered by design, with the dependency conceded.
|
||||
|
||||
Answer: The VDF is used for one thing: making the hourly program unknowable within the roughly two seconds a miner has to decide whether to publish a block, closing a withhold-or-publish grind the review measured at about 130 to 1 for a 30% miner. The VDF input is a certified checkpoint at least one epoch before the epoch starts, so honest nodes have about 50 minutes of slack to evaluate a 10-minute VDF, and an evaluator 300x faster than reference would still be needed to beat the two-second decision window. Chia has run class-group VDFs in production since 2021, with faster hardware evaluators existing and not breaking it (approximate, from memory). The design doc lists the VDF as a new dependency and ships the evaluator in every node. The grinding simulation with and without the VDF is scheduled before gate 3.
|
||||
|
||||
|
|
@ -426,7 +426,7 @@ Evidence: design doc "Proving speed on consumer GPUs" risk item and Finality v2
|
|||
"Claim a shard with a small bond and never prove it. Repeat. Finality waits on you."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 10): the parameter table's values are the phase 4 devnet's starting values (8 assignees, a 25-s exclusive window, a 120-s job claim timeout, no shard bond, the external job bond set on the devnet); the devnet measurement moves them. Was: Answered by design, parameter table written from the live numbers (5 October 2026, evening sweep). Was: Answered by design, parameters open. Sweep (5 October 2026): the parameters (O-5.6) are phase 4 devnet work; the economy simulator's lever study found the claim timeout a market parameter and recommends starting the devnet at 120 s (`docs/analysis/economy-2026-10-04.md` section 6).
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Sweep (5 October 2026, evening): shards carry no bond (spec 7.2, P13), so shard griefing is a prover sitting on an exclusive window; the only bond is the external job's. The table, from the live devnet at 16:00 UTC (`igneum_getProvingStatus` on the Mac node: 352 shards paid, pool 19 entries, 0 failed, 0 pending, 154 verified; the task's figure of 215 paid was the morning's) and the measured shard times:
|
||||
|
||||
|
|
@ -441,7 +441,7 @@ Sweep (5 October 2026, evening): shards carry no bond (spec 7.2, P13), so shard
|
|||
| External job bond | none implemented (phase 4) | `maxPgas x f_p x 1.5` escrow with a 3,600-block expiry and full refund (design 4.6) | O-5.6 keeps the number; the premium 1.5 is a parameter open |
|
||||
| Claim timeout, external jobs | none implemented | 120 s | The economy simulator's lever study (`docs/analysis/economy-2026-10-04.md` section 6): a market parameter, 120 s keeps jobs on 24 GB cards |
|
||||
|
||||
Execution and the 30-s lock never wait for a proof (unchanged); the cost of a griefed shard is proof latency, one window per absent assignee at most. Decision owner for the testnet values: the project lead (O-5.1, O-5.6).
|
||||
Execution and the 30-s lock never wait for a proof (unchanged); the cost of a griefed shard is proof latency, one window per absent assignee at most. Decision owner for the testnet values: the founder (O-5.1, O-5.6).
|
||||
|
||||
Answer: The bond is slashed and the shard reopens; the proving fee rises until someone proves it (security model table, "Prover cartel withholding proofs"). The open parameters are the bond size, the timeout, and whether an un-proven block delays only the proof (it does; execution and the 30-second lock do not wait for the proof). Set in phase 4.
|
||||
|
||||
|
|
@ -607,13 +607,13 @@ Answer: True. The design, the reviews, the prototype code, the simulator and thi
|
|||
|
||||
Evidence: `.claude/agents/`, commit trailers. Fix: add a disclosure sentence (overclaims list, item 73).
|
||||
|
||||
Sweep (5 October 2026, evening): stated. `site/litepaper.html`, cover meta line "Method: one founder with AI systems, external review before gate 3" (overclaim 72) and the "Who are you?" paragraph: one pseudonymous founder working with AI systems produced the design, the reviews, the code, the simulators and the document, the commit history says so, measurements are reproducible, design claims stay design claims, the criticism ledger exists with its conceded entries and is published with the node repository. No names. Decisions for the project lead: whether this ledger is published with the repository (G11), and whether the team page at public testnet names anyone (fud-fixes row 9).
|
||||
Sweep (5 October 2026, evening): stated. `site/litepaper.html`, cover meta line "Method: one founder with AI systems, external review before gate 3" (overclaim 72) and the "Who are you?" paragraph: one pseudonymous founder working with AI systems produced the design, the reviews, the code, the simulators and the document, the commit history says so, measurements are reproducible, design claims stay design claims, the criticism ledger exists with its conceded entries and is published with the node repository. No names. Decisions for the founder: whether this ledger is published with the repository (G11), and whether the team page at public testnet names anyone (fud-fixes row 9).
|
||||
|
||||
### G3. Who are you
|
||||
"Anonymous founder, GoDaddy domains, a Vercel site, a litepaper dated the same day as five 'milestones'. This is a template."
|
||||
|
||||
Status: Decided (5 October 2026): no team page for now; the litepaper says the team is pseudonymous and names no team page. Stated (5 October 2026, night): `site/litepaper.html`, Who are you?, "The team is pseudonymous and there is no team page". Was: Conceded, team page deferred by decision.
|
||||
Decision owner (5 October 2026, evening sweep): the project lead (the team page at public testnet, fud-fixes row 9).
|
||||
Decision owner (5 October 2026, evening sweep): the founder (the team page at public testnet, fud-fixes row 9).
|
||||
Was: Status: Conceded, team page deferred by decision. Decided 5 October 2026: no team page for now; the litepaper says the team is pseudonymous and names no team page.
|
||||
|
||||
Answer: The founder's name is on every commit. The litepaper defers the team page to public testnet by decision, with disclosed mining addresses at genesis. There are no coins to sell and no sale planned, so there is nothing to run away with before block one. The five log entries dated 3 October 2026 are day one of the project and should be presented as that.
|
||||
|
|
@ -734,13 +734,13 @@ Sweep (5 October 2026, evening): stated. `site/litepaper.html`, The problem: "Ch
|
|||
### C4. vs Kaspa: a finality overlay changes GHOSTDAG's guarantees
|
||||
"GHOSTDAG's safety comes from blue work. A certificate that overrides blue work and a pruning point that never passes the latest lock are changes to the security model, not features on top."
|
||||
|
||||
Status: Measured on the live node line, and the overlay does NOT do what the spec says at a heal: a NEW SERIOUS FINDING (5 October 2026, evening sweep; owner: cryptographer and consensus engineer, decision owner the project lead). Was: Open, experiment scheduled. Sweep (5 October 2026): the overlay has now run on a real DAG (cloud devnet, 4 October): with the module on, two partitions produced 0 conflicting locks, the 15.8% side locked nothing, the 84.2% side locked every interval, and the minority reorganised 423 to 496 blocks at the heal and adopted the majority's certificates within 15 s; the same day's F21 finding (a long honest partition locks alone from day 10 at 50/50) is the one real change to GHOSTDAG's guarantees found so far, and rule v3 answers it. The module-off comparison and the trace-driven adversary of O-3.8 are still owed.
|
||||
Status: Measured on the live node line, and the overlay does NOT do what the spec says at a heal: a NEW SERIOUS FINDING (5 October 2026, evening sweep; owner: cryptographer and consensus engineer, decision owner the founder). Was: Open, experiment scheduled. Sweep (5 October 2026): the overlay has now run on a real DAG (cloud devnet, 4 October): with the module on, two partitions produced 0 conflicting locks, the 15.8% side locked nothing, the 84.2% side locked every interval, and the minority reorganised 423 to 496 blocks at the heal and adopted the majority's certificates within 15 s; the same day's F21 finding (a long honest partition locks alone from day 10 at 50/50) is the one real change to GHOSTDAG's guarantees found so far, and rule v3 answers it. The module-off comparison and the trace-driven adversary of O-3.8 are still owed.
|
||||
|
||||
Answer: True. Among candidate tips (those passing through every certified checkpoint) GHOSTDAG selects by blue work under the 3,600-second merge-depth bound; a certified checkpoint removes other tips from candidacy. That is a change, and its interaction with pruning, with red blocks in the attacker's weight and with latency is exactly what the gate 3 devnet measures. The module is separable so GHOSTDAG alone remains the fallback.
|
||||
|
||||
Evidence: design doc Finality v2, Fork choice items 1 to 4; `sim/results.md` final section.
|
||||
|
||||
Sweep (5 October 2026, evening): the module-on against module-off comparison of O-3.8, run on the fast-time harness with the live node line (`tools/finality-attacks/c4.mjs`, fork 2b6d23ef, 3 nodes, 100-ms proxied links; raw tables in `docs/bench-log.md`, "FUD ledger sweep round 6", C4). The scenario separates weight from work: side B (n1, n2, four keys) holds 70% of the weight table and side A (n0, two keys) 30% when the link is cut; from the cut A mines at 0.6 blocks/s and B at 0.4, so A's chain is the heavier one by blue work while only B can certify under rule v3 (A holds 30% of the frozen table). Module off (`min_daa` never, so no certificate can form, fork choice bare GHOSTDAG): after a 150-s split the three nodes converged on A's heavier chain within 36 s of the heal, B's nodes re-determined their two split-time checkpoints onto it (F24), 0 conflicts. Module on (rule v3 from checkpoint DAA 0), 90-s split, n0 back on the link 6 s after the heal, A's chain at about 58 DAA of its own time, well inside the 120-DAA frozen table: during the split A locked nothing and B locked indices 7 and 8 on its own blocks, as designed; after the heal n0 did not switch. Its log: B's certificates for 8 and 9 arrived and were "kept pending until the chain decides (no lock at this index)" (the F24 path), n0's chain never changed because GHOSTDAG prefers its heavier tip and nothing in the node turns a verified certificate over an off-chain block into a fork-choice constraint, and one window after n0's last lock (index 7 at DAA 209, so from DAA 329) the frozen table no longer applied on A's chain ("no frozen table (no lock on this chain inside the window)"), A's two keys were 100% of A's own window table (B's post-cut blocks are red there and earn nothing), and n0 locked 10, 11 and 12 alone; B's certificates for 10 and 11 then logged CONFLICTING on n0, and B's nodes kept their certified chain. End state: sinks apart, 2 locked indices disagreeing across the nodes, a finality fork from a 96-s honest partition with no attacker and the frozen table intact at the heal; the same shape with a 150-s split (the table expired at the heal) and under rule v2 (the control: 1 conflict, sinks apart). So the answer to the critic is sharper than conceded: the overlay is specified to override blue work (spec 3.5, "GHOSTDAG among tips through all certified checkpoints") but the shipped node applies a certificate only to a block on its own chain, holds the rest pending a reorg that GHOSTDAG alone never produces, and after one window the heavier side certifies its own chain. Two honest views never reconcile. What closes it: a verified certificate over a block the node does not have on its selected chain must verify against the weight table at THAT block (its signers' weight there) and, when valid, constrain fork choice to tips through it, forcing the reorg (a certificate-driven reorg, bounded by the finality depth), with the node's own unlocked records re-determined on the new chain (F24); until then the exchange guidance of 3.9 (a node partitioned for more than a minute treats its locks as proof of work until it has seen the network's certificates agree with its own) is the only protection, and the 3.11.7 row for this case ("a certificate over a chain the node is not on") is missing. On the live devnet the window is 7,200 DAA (two hours) and the cliff is two hours after a side's last lock; a miner who joins with more hashrate than the weight table credits is the realistic work-majority side. The trace-driven adversary of O-3.8 is still owed. Spec rows: 3.5, 3.11.4, 3.11.7; node: `processes/finality.rs` (`ingest_certificate`'s pending branch, `fork_choice_lock`). Decision owner: the project lead (gate 3; a rule change to the node's fork choice).
|
||||
Sweep (5 October 2026, evening): the module-on against module-off comparison of O-3.8, run on the fast-time harness with the live node line (`tools/finality-attacks/c4.mjs`, fork 2b6d23ef, 3 nodes, 100-ms proxied links; raw tables in `docs/bench-log.md`, "FUD ledger sweep round 6", C4). The scenario separates weight from work: side B (n1, n2, four keys) holds 70% of the weight table and side A (n0, two keys) 30% when the link is cut; from the cut A mines at 0.6 blocks/s and B at 0.4, so A's chain is the heavier one by blue work while only B can certify under rule v3 (A holds 30% of the frozen table). Module off (`min_daa` never, so no certificate can form, fork choice bare GHOSTDAG): after a 150-s split the three nodes converged on A's heavier chain within 36 s of the heal, B's nodes re-determined their two split-time checkpoints onto it (F24), 0 conflicts. Module on (rule v3 from checkpoint DAA 0), 90-s split, n0 back on the link 6 s after the heal, A's chain at about 58 DAA of its own time, well inside the 120-DAA frozen table: during the split A locked nothing and B locked indices 7 and 8 on its own blocks, as designed; after the heal n0 did not switch. Its log: B's certificates for 8 and 9 arrived and were "kept pending until the chain decides (no lock at this index)" (the F24 path), n0's chain never changed because GHOSTDAG prefers its heavier tip and nothing in the node turns a verified certificate over an off-chain block into a fork-choice constraint, and one window after n0's last lock (index 7 at DAA 209, so from DAA 329) the frozen table no longer applied on A's chain ("no frozen table (no lock on this chain inside the window)"), A's two keys were 100% of A's own window table (B's post-cut blocks are red there and earn nothing), and n0 locked 10, 11 and 12 alone; B's certificates for 10 and 11 then logged CONFLICTING on n0, and B's nodes kept their certified chain. End state: sinks apart, 2 locked indices disagreeing across the nodes, a finality fork from a 96-s honest partition with no attacker and the frozen table intact at the heal; the same shape with a 150-s split (the table expired at the heal) and under rule v2 (the control: 1 conflict, sinks apart). So the answer to the critic is sharper than conceded: the overlay is specified to override blue work (spec 3.5, "GHOSTDAG among tips through all certified checkpoints") but the shipped node applies a certificate only to a block on its own chain, holds the rest pending a reorg that GHOSTDAG alone never produces, and after one window the heavier side certifies its own chain. Two honest views never reconcile. What closes it: a verified certificate over a block the node does not have on its selected chain must verify against the weight table at THAT block (its signers' weight there) and, when valid, constrain fork choice to tips through it, forcing the reorg (a certificate-driven reorg, bounded by the finality depth), with the node's own unlocked records re-determined on the new chain (F24); until then the exchange guidance of 3.9 (a node partitioned for more than a minute treats its locks as proof of work until it has seen the network's certificates agree with its own) is the only protection, and the 3.11.7 row for this case ("a certificate over a chain the node is not on") is missing. On the live devnet the window is 7,200 DAA (two hours) and the cliff is two hours after a side's last lock; a miner who joins with more hashrate than the weight table credits is the realistic work-majority side. The trace-driven adversary of O-3.8 is still owed. Spec rows: 3.5, 3.11.4, 3.11.7; node: `processes/finality.rs` (`ingest_certificate`'s pending branch, `fork_choice_lock`). Decision owner: the founder (gate 3; a rule change to the node's fork choice).
|
||||
|
||||
### C5. vs Ethereum: you compare inclusion to finality
|
||||
"'Included in about one second, against twelve on Ethereum.' Inclusion in a DAG is not confirmation. Ethereum's twelve seconds is a slot, its finality is about thirteen minutes, and you compare your two-minute lock to that as if a two-minute lock by a pool committee were the same thing."
|
||||
|
|
@ -832,8 +832,8 @@ Evidence: CLAUDE.md rules (privacy rejected). Fix: overclaims list, item 68.
|
|||
"A founder's company earns a dev fee, runs a pool and a proving business, seeds the DEX, pays 'launch grants', and the roadmap ends in 'exchange listings after'. Expectation of profit from the efforts of others, in writing."
|
||||
|
||||
Status: Open, counsel engaged (6 October 2026, 17:25 UTC, by the owner; decisions item 6, in progress). Was: Open, counsel not yet engaged. Sweep (5 October 2026): counsel; nothing runnable.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the project lead, with counsel; nothing runnable here.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the founder, with counsel; nothing runnable here.
|
||||
|
||||
Answer: There is no sale, no premine, no allocation and no promise of return, and nothing in consensus is controlled by the team and no protocol fee reaches it (the development fund was removed on 3 October 2026), which is the structure that regulators have treated most favourably (approximate: compare the SEC's own framework on sufficiently decentralised networks and MiCA's exemption for tokens created automatically as a reward for maintaining a distributed ledger, approximate quotation). The weak points a lawyer will circle are the ones quoted: founder-run pool and proving business, founder-seeded DEX, launch grants, and the phrase "exchange listings after". None is in consensus; all are promotional. The litepaper must drop the listing sentence and counsel must review the founder-business paragraph before v0.2. The legal entity is "offshore, parked" in the design doc, which is not an answer.
|
||||
|
||||
|
|
@ -842,9 +842,9 @@ Evidence: design doc "Legal" paragraph. Fix: overclaims list, items 75 and 76.
|
|||
### L2. Financial promotion rules
|
||||
"Several jurisdictions now treat a cryptoasset promotion to their consumers as regulated: the UK since October 2023 needs an authorised approver, the EU under MiCA has its own marketing rules, the US has the Howey test. 'The people who show up early get the most' on a domain you own is a promotion wherever the reader sits."
|
||||
|
||||
Status: Open, counsel engaged (6 October 2026, 17:25 UTC, by the owner; decisions item 6, in progress); the text half is stated below. Was: Open, counsel not yet engaged (decision owner the project lead, with counsel); text half stated (5 October 2026, night): `site/litepaper.html`, Economics, Supply, "Nearly a quarter of all supply is mined in the first year and half in the first two." with no "so" clause (overclaims 54 and 76, fud-fixes row 6); "Half of all IGN" absent from `site/index.html`. Was: Open, counsel not yet engaged. Sweep (5 October 2026): counsel; nothing runnable.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the project lead, with counsel; nothing runnable here.
|
||||
Status: Open, counsel engaged (6 October 2026, 17:25 UTC, by the owner; decisions item 6, in progress); the text half is stated below. Was: Open, counsel not yet engaged (decision owner the founder, with counsel); text half stated (5 October 2026, night): `site/litepaper.html`, Economics, Supply, "Nearly a quarter of all supply is mined in the first year and half in the first two." with no "so" clause (overclaims 54 and 76, fud-fixes row 6); "Half of all IGN" absent from `site/index.html`. Was: Open, counsel not yet engaged. Sweep (5 October 2026): counsel; nothing runnable.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the founder, with counsel; nothing runnable here.
|
||||
|
||||
Answer: A litepaper describing how to mine a coin that does not exist is arguably not an invitation to engage in investment activity, and the regime has carve-outs for information that is not an inducement (approximate; this needs an opinion from counsel in the jurisdiction the project is established in, which is offshore and not yet named). Sentences that read as inducements to acquire ("show up early get the most", "half of all supply in the first two years") should be rewritten as schedule facts before v0.2. Country-code domains such as igneum.co.uk redirect to igneum.network and carry no separate content.
|
||||
|
||||
|
|
@ -854,8 +854,8 @@ Evidence: none. Fix: overclaims list, item 77.
|
|||
"Fifteen domains at a US registrar on US nameservers behind a US host. One court order and igneum.network is a parking page."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 7): the nameserver move to deSEC in one sitting with every domain's Vercel verification checked afterwards; a non-US registrar in December 2026 when the transfer lock ends. Was: Conceded, mitigation scheduled. Sweep (5 October 2026): a deSEC token now sits in `~/.config/igneum` (mode 600), so the nameserver move of fud-fixes row 44 has started; the registrar move waits for December.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the project lead, with counsel; nothing runnable here.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the founder, with counsel; nothing runnable here.
|
||||
|
||||
Answer: True. GoDaddy and Vercel are both US companies and have both complied with takedowns. Mitigations: an ENS or equivalent name and an IPFS mirror of the site and litepaper, the site's content hash published in the repository and in the genesis block, at least one non-US registrar for a second TLD, and the chain itself never depending on any domain (seed nodes are addresses in the client, not DNS only). Phase 5.
|
||||
|
||||
|
|
@ -865,8 +865,8 @@ Evidence: CLAUDE.md "Domains". Mitigation: not yet.
|
|||
"'Testnet miners are paid real money for real proofs from phase five.' That is a business paying contractors in crypto across borders with no entity."
|
||||
|
||||
Status: Open, counsel engaged (6 October 2026, 17:25 UTC, by the owner; decisions item 6, in progress). Was: Open. Sweep (5 October 2026): counsel and entity; nothing runnable.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the project lead, with counsel; nothing runnable here.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the founder, with counsel; nothing runnable here.
|
||||
|
||||
Answer: Correct that it needs an entity, terms and tax treatment before it happens. The payments come from the customer rollup on its own chain, not from Igneum, but the arrangement is organised by the project. Counsel before phase 5.
|
||||
|
||||
|
|
@ -876,8 +876,8 @@ Evidence: design doc "The first six months".
|
|||
"Igneum. Have you checked EUIPO, USPTO and the UK IPO? There is no evidence you did."
|
||||
|
||||
Status: Open, counsel engaged (6 October 2026, 17:25 UTC, by the owner; decisions item 6, in progress): the clearance search is recorded in the repository as a dated one-line result per register when it returns. Was: Open. Sweep (5 October 2026): a person's search, recorded outside the repository; nothing runnable.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the project lead, with counsel; nothing runnable here.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner (5 October 2026, evening sweep): the founder, with counsel; nothing runnable here.
|
||||
|
||||
Answer: No clearance search is recorded in the repository. One is required before the name is used commercially, in all three registers and in Nice classes 9, 36 and 42, approximate. Until then the name is provisional and the litepaper should not claim otherwise.
|
||||
|
||||
|
|
@ -905,9 +905,9 @@ Answer: Correct. Either the repository goes public with the litepaper or the sen
|
|||
|
||||
Evidence: `site/index.html` footer link; CLAUDE.md says private. Fix: overclaims list, item 22.
|
||||
|
||||
Cross-reference (external review, 3 October 2026, night): publishing the harnesses, vectors, simulators and spec now, labelled experimental, is G11, a decision for the project lead.
|
||||
Cross-reference (external review, 3 October 2026, night): publishing the harnesses, vectors, simulators and spec now, labelled experimental, is G11, a decision for the founder.
|
||||
|
||||
Sweep (5 October 2026, evening): stated. `site/litepaper.html`, vs RandomX "Track record" row: the specification, reference hash, vectors and simulators are public at github.com/igneum-network/spec (confirmed public, 5 October 2026); the node, the miner and the wallet are in a private repository until the public testnet. "Built on the shoulders": the provenance table is published at the public testnet. The nav and footer GitHub links already pointed at the public spec repository. Decision for the project lead: the date. This entry, `docs/evidence.md` and the fud-fixes list say January 2027 with the benchmark; the public text now says the public testnet, as instructed; the miners-ask answer still says the benchmark tool is public in January 2027, which holds for a binary.
|
||||
Sweep (5 October 2026, evening): stated. `site/litepaper.html`, vs RandomX "Track record" row: the specification, reference hash, vectors and simulators are public at github.com/igneum-network/spec (confirmed public, 5 October 2026); the node, the miner and the wallet are in a private repository until the public testnet. "Built on the shoulders": the provenance table is published at the public testnet. The nav and footer GitHub links already pointed at the public spec repository. Decision for the founder: the date. This entry, `docs/evidence.md` and the fud-fixes list say January 2027 with the benchmark; the public text now says the public testnet, as instructed; the miners-ask answer still says the benchmark tool is public in January 2027, which holds for a binary.
|
||||
|
||||
### X2. "Get the miner" with no miner
|
||||
"A big button that says 'Get the miner' on a chain with no miner, no testnet and no benchmark. Vapourware CTA."
|
||||
|
|
@ -943,8 +943,8 @@ Evidence: litepaper "Roadmap"; design doc "Team".
|
|||
### X5. 1,000 independent miners is a Sybil number
|
||||
"Your testnet gate is 1,000 independent miners for 30 days. One person with a script is 1,000 miners."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 3): the independence definition as written, with the silent-fleet addition (a key with no fingerprint counts as its own class only when its address is in an autonomous system no other key uses); the observer columns on `ledger-observer` (O-X.1) ship with the next cut; measurement scheduled. Was: Conceded, measurement defined from the vote-key window and today's numbers (5 October 2026, evening sweep); decision owner the project lead (O-X.1). Was: Conceded, measurement to define.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 3): the independence definition as written, with the silent-fleet addition (a key with no fingerprint counts as its own class only when its address is in an autonomous system no other key uses); the observer columns on `ledger-observer` (O-X.1) ship with the next cut; measurement scheduled. Was: Conceded, measurement defined from the vote-key window and today's numbers (5 October 2026, evening sweep); decision owner the founder (O-X.1). Was: Conceded, measurement to define.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Sweep (5 October 2026, evening): the definition, measurable from chain data plus two attestations, and today's reading. Unit: a vote key with at least the dust count of blue blocks in the 30-day weight window (W3), which is the smallest thing the chain can count. Independence: two keys are independent when they differ in all three of (a) the autonomous system of the address their blocks' nodes announce (seed and peer tables, the observer's address field), (b) the machine fingerprint the miner app sends with its log uploads (`machine_id`, already in every STATUS line's run id), and (c) the pool attestation, a signed statement by a pool operator listing the keys it runs (absent for solo keys). N_ind = the number of distinct (ASN, fingerprint, pool) classes among eligible keys; the gate of `site/journey.json` phase 5 reads "N_ind >= 1,000 over the same 30 days with top-10 share of window weight under 50%". Today's reading from the live window (Mac node, `getFinalityWeights` at DAA 112,395): 22 keys, 21 voters above dust (dust 5 on the devnet), total weight 7,196 of 7,200 blue blocks; top-1 share 8.3%, top-3 20.3%, top-5 31.9%, top-10 60.3%; the console counts 5 machines and 21 identities in 10 minutes, so the fleet runs 4.2 keys per machine (the launcher's one key per worker, F17's client default) and N_ind by fingerprint alone is 5, by ASN at most 3 (two home networks and one US household, approximate). That is the Sybil ratio the critic means, measured: 21 "miners" are 5 machines. The hashing concentration of X14 (top-1 12.8%, top-3 34.5% over 8,090 blocks on 4 October) and tonight's weight shares agree within the window's drift. What the observer must add (O-X.1): the ASN per announcing address, the fingerprint per key (the app already has both), and the pool statement format.
|
||||
|
||||
|
|
@ -974,7 +974,7 @@ Answer: Correct. The site needs a contact route before the litepaper is shared,
|
|||
|
||||
Evidence: `site/index.html` (no contact route). Fix: overclaims list, item 78.
|
||||
|
||||
Sweep (5 October 2026, evening): stated in part. `site/partials/footer.html` on every page: "Report a flaw" to github.com/igneum-network/spec/issues (the public repository has issues enabled, checked 5 October 2026); the last paragraph of `site/litepaper.html` says the same and that a mailbox follows. Decision for the project lead: the mailbox on the igneum.network Workspace (fud-fixes row 3). The submission line at the top of this ledger still names a route that does not exist and is left for the ledger's owner.
|
||||
Sweep (5 October 2026, evening): stated in part. `site/partials/footer.html` on every page: "Report a flaw" to github.com/igneum-network/spec/issues (the public repository has issues enabled, checked 5 October 2026); the last paragraph of `site/litepaper.html` says the same and that a mailbox follows. Decision for the founder: the mailbox on the igneum.network Workspace (fud-fixes row 3). The submission line at the top of this ledger still names a route that does not exist and is left for the ledger's owner.
|
||||
|
||||
### X8. Exchange listings as a roadmap item
|
||||
"'Mainnet fair launch: Genesis with no premine, 30-day ramp, exchange listings after.' You put listings in the roadmap."
|
||||
|
|
@ -1306,7 +1306,7 @@ Evidence: the files and lines above. Fix: review's first of five. Review id R3.2
|
|||
|
||||
Status: Answered with evidence (6 October 2026, night, ledger close round 2; bench-log "ledger close round 2: M16 the inline-cache kernel on the RTX 5090"): on the 5090 the recompute attacker with the cache inside the 96 MiB L2 (the SRAM emulation, 64 and 32 MiB masks, bit-exact against the stored construction) runs at 33.9 Mhash/s against 132.2 honest for the same version-2 program, 0.256x at equal silicon and 5.1x worse per joule (431 W at the power limit against 327 W); the cost model's "50 T op/s" row was arithmetic and the measurement puts the integer engine at about 6 T op/s on this chain, bound by the 1,024 dependent cache-line reads per hash. Open for gate 1: a die's own SRAM latency (approximate), the O-1.6 curve, the mixer doubling. Was: Open, the kernel written and bit-exact on the Mac, the PC 2 run queued behind the 0.3.11 rollout. Was: Open, cost model written, the on-die emulation still a PC job (5 October 2026, evening sweep). Was: Open, experiment scheduled. Sweep (5 October 2026): not runnable on this Mac; the on-die emulation needs the RTX 5090 (an inline kernel at a 64 MiB cache inside its 96 MiB L2). The only newer number is the loaded-Mac reconfirmation of 3 October (inline 17x slower at a 256 MiB cache, bench-log "R3.26 / M15", M16 note), which does not price a die. Hardware item.
|
||||
|
||||
Sweep (5 October 2026, evening): `docs/analysis/m16-recompute-attacker-2026-10-05.md` prices the device from the specification and the measured rates. Per hash the attacker recomputes 128 items at 9 mixer applications of about 130 operations and 8 dependent 64-byte cache reads each: about 150,000 integer operations and 1,024 dependent SRAM reads (65 KB). To match one RTX 5090 at its measured 229 Mhash/s the chip needs 34 T integer op/s and 15 TB/s of SRAM bandwidth beside 256 MiB of SRAM (100 to 300 mm^2 on a current node, approximate). At the 5090's own integer budget (about 50 T op/s, approximate) that is 0.33 Ghash/s: 1.5x the measured closed-form rate, 2.4x the 141 Mhash/s projected for version 2 programs, before any fixed-function factor; with a 3x factor (approximate) 3x to 6x at equal die area. The lever: the mixer cost is paid by the honest miner once a day (13.4 ms per 1 GiB on the 5090, measured) and by the attacker per hash, so doubling it halves the attacker's rate at zero honest cost, 4x puts the equal-silicon gain at 0.36x and the factored gain near 1x, bounded by the CPU verify gate (0.41 to 1.2 ms per warp today, 10 ms the gate, so about 8x of headroom on the M5 Max core). What is still unmeasured: the inline kernel on the 5090 with a 64 MiB cache inside its L2 (the SRAM emulation, a PC job), the time-memory curve of O-1.6, and any cryptanalysis of the mixer. Decision at gate 1 (owner the project lead): cache size and mixer cost against the verify gate.
|
||||
Sweep (5 October 2026, evening): `docs/analysis/m16-recompute-attacker-2026-10-05.md` prices the device from the specification and the measured rates. Per hash the attacker recomputes 128 items at 9 mixer applications of about 130 operations and 8 dependent 64-byte cache reads each: about 150,000 integer operations and 1,024 dependent SRAM reads (65 KB). To match one RTX 5090 at its measured 229 Mhash/s the chip needs 34 T integer op/s and 15 TB/s of SRAM bandwidth beside 256 MiB of SRAM (100 to 300 mm^2 on a current node, approximate). At the 5090's own integer budget (about 50 T op/s, approximate) that is 0.33 Ghash/s: 1.5x the measured closed-form rate, 2.4x the 141 Mhash/s projected for version 2 programs, before any fixed-function factor; with a 3x factor (approximate) 3x to 6x at equal die area. The lever: the mixer cost is paid by the honest miner once a day (13.4 ms per 1 GiB on the 5090, measured) and by the attacker per hash, so doubling it halves the attacker's rate at zero honest cost, 4x puts the equal-silicon gain at 0.36x and the factored gain near 1x, bounded by the CPU verify gate (0.41 to 1.2 ms per warp today, 10 ms the gate, so about 8x of headroom on the M5 Max core). What is still unmeasured: the inline kernel on the 5090 with a 64 MiB cache inside its L2 (the SRAM emulation, a PC job), the time-memory curve of O-1.6, and any cryptanalysis of the mixer. Decision at gate 1 (owner the founder): cache size and mixer cost against the verify gate.
|
||||
|
||||
Answer: Correct as arithmetic, unmeasured as a device. From spec 1.8.4 and 1.8.5 an item costs 9 mixer applications of about 130 operations and 8 cache reads; under the proposed 16-load rule a hash derives 128 items. A 5090-class integer budget (about 50 T operations a second, approximate) gives about 0.33 Ghash/s against the honest 141 Mhash/s projection, about 2.4x at equal silicon before any chip-versus-GPU efficiency, and a 256 MiB SRAM is about 250 to 300 mm^2 on a current node (approximate, from wafer-scale parts). The cache size was set to beat a GPU's L2 (spec 1.16), not a die. The lever is the cache size and the mixer cost, both prototype values at gate 1. Monero's precedent does not price this (C13). An FPGA does not reach it (review, chip designer, attack 3).
|
||||
|
||||
|
|
@ -1314,7 +1314,7 @@ Evidence: spec 1.8, 1.16; `proto-metal/MEMHARD.md` 2.2 (Apple only). Experiment:
|
|||
|
||||
Round 2 (6 October 2026, night): the CUDA inline path did not exist (the shipped worker reads the dataset only; `--inline-dataset` was Metal), so it was written as a benchmark beside the worker, never inside it: `proto-cuda/inline-bench/` (`gen.py` derives `kernel_inline.cu` and `memhard_inline.h` from the pack by counted text substitution, the 16 dataset loads of the devnet-v4 epoch-0 program becoming `mhi_word(cache, x & mask, lineMask)` with the cache-line mask a kernel argument; `inline_bench.cpp` loads the driver API and NVRTC at run time as the worker does, compiles the pack's texts, runs three bit-exact checks and then fixed-time windows for honest 1 GiB, inline at 256 MiB, inline at 64 MiB (the first quarter of the cache, inside the 5090's 96 MiB L2: the on-die SRAM emulation) and inline at 32 MiB, with an `nvidia-smi` sampler per window for E17). Mac check (host threads through the project's CUDA emulation shim, build lock, 12.3 s): check 1 the pack's self-test PASS (96 of 96 lanes); check 2 the inline kernel at the 256 MiB mask equals the pack's vectors on all 96 lanes, the dataset never read (this is what proves the substitution and the derivation); check 3 at the 64 MiB and 32 MiB masks a stored dataset built at that mask and read by the honest kernel equals the recomputed path on 8,288 lanes each, and differs from the pack's vectors as a smaller cache must. The Windows exe (mingw, 355,840 bytes, sha256 2e6a21de...) and the pack with the inline texts went to the downloads host as `igneum-inline-bench-kit.zip` (202,138 bytes, sha256 80ce0290...); the PC 2 job (one `run` job, the app's miners paused and the live prover off for about 4 minutes on the card, both restored, two passes at 1 and 8 warps per block, 15 s per setting) waits on the scheduler's go behind the 0.3.11 rollout. What the number will test: the analysis's "50 T op/s" row, 1.5x the measured 229 Mhash/s and 2.4x the projected 141 at equal integer budget; the inline64 rate IS the attacker's rate on this silicon with the cache in L2, so the gain is inline64 over honest, before any fixed-function factor. The CPU fill and verify at a 1 GiB cache and the O-1.6 curve are not part of this job.
|
||||
|
||||
The PC 2 run (6 October 2026, 00:38 to 00:43 UTC, job `m16-inline-pc2-1`, the card taken whole with the app's miners paused and the prover off, both restored, nothing else on the card; the three checks PASS on the 5090 as on the Mac): honest 1 GiB 132.20 Mhash/s at 326.6 W median, 3,060 MHz; inline at the 256 MiB cache in VRAM 11.26 Mhash/s (0.085x) at 415.7 W; inline at the 64 MiB mask inside the L2 33.88 Mhash/s (0.256x) at 431.0 W, the power limit, clocks 2,835 MHz; inline at 32 MiB 33.87 (0.256x), the same rate, so the L2 plateau is the SRAM-class bound. Eight warps per block: 131.15 / 10.89 / 29.32 / 29.46. Reading: the attacker's rate with the cache in SRAM-class memory is a quarter of the honest rate on the same silicon, because the inline path runs 1,024 dependent cache-line reads per hash (34.7 G per second here, 2.2 TB/s of line traffic) and reaches only about 6 T integer operations per second of the card's 50 T (approximate): the cost model's equal-budget row (1.5x to 2.4x) assumed the arithmetic was the bound; it is not. With the model's approximate 3x fixed-function factor the equal-area gain is about 0.8x, before the 256 MiB SRAM's area is paid; the entry's "3x to 6x" becomes about 0.8x to 1.5x. Consequence for every GPU tier: no exposure to this device at the current parameters beyond that approximate factor; the mixer doubling stays the lever (halves 0.256x again at zero honest cost, 27 ms daily build, 0.8 to 2.4 ms per warp to verify) and is the gate-1 question for the project lead. Unmeasured: a die's own dependent-SRAM latency (a chip with the SRAM beside the ALUs shortens the chain; approximate), the O-1.6 partial-store curve, mixer cryptanalysis, the AMD tier (owed: the same kernel through OpenCL on the RX 9070 XT when PC 1 is back).
|
||||
The PC 2 run (6 October 2026, 00:38 to 00:43 UTC, job `m16-inline-pc2-1`, the card taken whole with the app's miners paused and the prover off, both restored, nothing else on the card; the three checks PASS on the 5090 as on the Mac): honest 1 GiB 132.20 Mhash/s at 326.6 W median, 3,060 MHz; inline at the 256 MiB cache in VRAM 11.26 Mhash/s (0.085x) at 415.7 W; inline at the 64 MiB mask inside the L2 33.88 Mhash/s (0.256x) at 431.0 W, the power limit, clocks 2,835 MHz; inline at 32 MiB 33.87 (0.256x), the same rate, so the L2 plateau is the SRAM-class bound. Eight warps per block: 131.15 / 10.89 / 29.32 / 29.46. Reading: the attacker's rate with the cache in SRAM-class memory is a quarter of the honest rate on the same silicon, because the inline path runs 1,024 dependent cache-line reads per hash (34.7 G per second here, 2.2 TB/s of line traffic) and reaches only about 6 T integer operations per second of the card's 50 T (approximate): the cost model's equal-budget row (1.5x to 2.4x) assumed the arithmetic was the bound; it is not. With the model's approximate 3x fixed-function factor the equal-area gain is about 0.8x, before the 256 MiB SRAM's area is paid; the entry's "3x to 6x" becomes about 0.8x to 1.5x. Consequence for every GPU tier: no exposure to this device at the current parameters beyond that approximate factor; the mixer doubling stays the lever (halves 0.256x again at zero honest cost, 27 ms daily build, 0.8 to 2.4 ms per warp to verify) and is the gate-1 question for the founder. Unmeasured: a die's own dependent-SRAM latency (a chip with the SRAM beside the ALUs shortens the chain; approximate), the O-1.6 partial-store curve, mixer cryptanalysis, the AMD tier (owed: the same kernel through OpenCL on the RX 9070 XT when PC 1 is back).
|
||||
|
||||
### M17. Every ahead-of-time miner stops at the epoch boundary; whoever compiles in process mines alone
|
||||
"Your log: last block of epoch 0 at 21:12:14, nothing for the next 91 seconds while the Windows launcher killed eight identities, re-exported, rebuilt two binaries and restarted them. The Metal worker compiles in 129 ms. The first 2.5% of every hour goes to whoever does not use your launcher."
|
||||
|
|
@ -1388,8 +1388,8 @@ Evidence: the files above. Review id R3.2.
|
|||
### F16. A lock can become uncertified after a heal
|
||||
"Section 3.5: two certificates at one index, strike the equivocators, re-evaluate, and if neither or both still lock the index is uncertified. So the lock my node reported and I credited on is revocable."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 2): option B, a verified certificate is never withdrawn (spec 3.11.4); the 3.5 paragraph is replaced by 3.11.4's text after `c4-fix` merges, `finality_conflict` and the `finality_active` clear go into the node, the forced double-certificate test of 3.11.7 follows; fix scheduled, consensus engineer. Was: Open, the two options priced, one recommended (5 October 2026, evening sweep); decision owner the project lead (gate 3, O-3.17). Was: Open, decision at gate 3 (extends O-3.6). Sweep (5 October 2026): a decision item (O-3.17); nothing runnable.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 2): option B, a verified certificate is never withdrawn (spec 3.11.4); the 3.5 paragraph is replaced by 3.11.4's text after `c4-fix` merges, `finality_conflict` and the `finality_active` clear go into the node, the forced double-certificate test of 3.11.7 follows; fix scheduled, consensus engineer. Was: Open, the two options priced, one recommended (5 October 2026, evening sweep); decision owner the founder (gate 3, O-3.17). Was: Open, decision at gate 3 (extends O-3.6). Sweep (5 October 2026): a decision item (O-3.17); nothing runnable.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Sweep (5 October 2026, evening): the two options, with their measured cost.
|
||||
|
||||
|
|
@ -1401,7 +1401,7 @@ Sweep (5 October 2026, evening): the two options, with their measured cost.
|
|||
| Cost to the honest network | Recovery is automatic but every credit made on a withdrawn lock is exposed; the attacker who caused it keeps its deposit either way (F6) | A finality pause of operator length (hours) after an attack that costs the attacker ten days of a third of all hashrate in public (3.1) or a 30-day partition; the pause is the price of "locked" meaning irrevocable |
|
||||
| What the shipped node does today | not implemented | half: a second certificate at a locked index is kept and logged CONFLICTING (`processes/finality.rs`, F24 wording), the node keeps the first (`fork_choice_lock`), but it does not yet clear `finality_active` or expose `finality_conflict` (spec 3.11.7 row C4); no `finality_conflict` symbol exists in the fork |
|
||||
|
||||
Recommendation: Option B, which spec 3.11.4 already states and O-3.17 names; it is Kaspa's rule for a finality conflict (`vendor/rusty-kaspa/consensus/notify/src/notification.rs`, `FinalityConflict`), it is the only reading under which an exchange can credit on a lock, and its cost falls on a state that needs a 34% equivocator or a 30-day partition. What it needs: the 3.5 paragraph replaced by 3.11.4's text, `finality_conflict` and the `finality_active` clear in the node, and the forced-double-certificate devnet test of 3.11.7. Decision owner: the project lead (gate 3).
|
||||
Recommendation: Option B, which spec 3.11.4 already states and O-3.17 names; it is Kaspa's rule for a finality conflict (`vendor/rusty-kaspa/consensus/notify/src/notification.rs`, `FinalityConflict`), it is the only reading under which an exchange can credit on a lock, and its cost falls on a state that needs a 34% equivocator or a 30-day partition. What it needs: the 3.5 paragraph replaced by 3.11.4's text, `finality_conflict` and the `finality_active` clear in the node, and the forced-double-certificate devnet test of 3.11.7. Decision owner: the founder (gate 3).
|
||||
|
||||
Answer: Correct as the proposal stands. For an exchange "locked" must be irrevocable or it is a confirmation count. The alternative is Kaspa's: a verified certificate is never re-evaluated; two certificates at one index are a chain split that halts `finality_active` until an operator intervenes, and the node never reports a lock it may withdraw. Equivocation costing history and not coins (F6) means the attacker who caused the split keeps the deposit either way. Decision at gate 3; the devnet partition-and-heal test of O-3.6 measures whichever rule is chosen.
|
||||
|
||||
|
|
@ -1413,7 +1413,7 @@ Cross-reference (external review, 3 October 2026, night): what holds during a pa
|
|||
"Your launcher runs 8 identities per vendor, each with its own vote key. For the vote that is harmless by design. For shard sortition, which ranks every eligible key and takes 8, it is the whole game: 1% of hashrate holds 259 keys above dust. And a few thousand PCs cross your 8,192-voter switch, whose construction is open."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 13): the client defaults to one vote key per machine, identities share it (spec 3.4.2 item 4); the bitmap bound as item 3. Was: Rule fixed (3 October 2026): spec 7.2 step 2 draws the 8 assignees by weight (blue blocks drawn uniformly from the window, their keys assigned, with the 1-key-versus-1,000-keys test in O-5.1), and spec 3.1 W6 states that keys are free and weight is the only Sybil-resistant quantity. The client's one-key default (O-3.5) and the bitmap size (O-3.12) are proposed in spec 3.4.2 (round 2, 5 October 2026, night, below), decision at gate 3. P8 stays closed. Was: Open, rule change proposed. Reopens P8.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: Correct. Spec 7.2 step 2 ranks per key and eligibility is 100 blue blocks in 30 days (0.004% of hashrate at one block a second), so a miner with share s holds up to s x 2,592,000 / 100 keys and the draw of 8 is dominated by whoever splits most. `proto-cuda/windows-miner/start-mining.ps1` derives a key per identity (`MINERS` default 8). O-5.1's acceptance test (fastest prover under 25% of shards) does not catch a splitter, who wins by count. Fix: draw the 8 assignees by weight (8 blue blocks uniformly from the window, take their keys), so splitting changes nothing; the client defaults to one key per operator; specify S2 (O-3.5) and the bitmap size (O-3.12) before the count can cross 8,192.
|
||||
|
||||
|
|
@ -1575,10 +1575,10 @@ Run (5 October 2026, night): `python3 sim/difficulty/record_report.py devnet-202
|
|||
### M22. The ASIC challenge has no scoring rules, and 2x is not the economic line
|
||||
"Your bounty says 'beats a GPU by more than 2x'. Per what? Hashes per second, per joule, per dollar, on the average program or the worst hour? A chip at 1.6x with half the capital cost wins. And nobody has published eligible hardware, funding or a judge."
|
||||
|
||||
Status: Decided (6 October 2026, 17:35 UTC, by the owner; decisions item 1, corrected): no bounty, so no bounty terms; M22's metrics (hashes per second and per joule per program over at least 100 epochs as a distribution, capital cost per unit of hash rate at a stated volume, the longevity term, the shortcut classes scored separately) become the public benchmark's scoring rules and the brief of the paid cryptanalysis; the optional USD 50,000 cryptanalysis prize, if ever set, is escrowed before it is named. Was: Open, decision for the project lead (terms, judge and funding) and experiment scheduled (extends O-1.17). Sweep (5 October 2026): nothing runnable; the terms, judge and funding are the project lead's decision.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Status: Decided (6 October 2026, 17:35 UTC, by the owner; decisions item 1, corrected): no bounty, so no bounty terms; M22's metrics (hashes per second and per joule per program over at least 100 epochs as a distribution, capital cost per unit of hash rate at a stated volume, the longevity term, the shortcut classes scored separately) become the public benchmark's scoring rules and the brief of the paid cryptanalysis; the optional USD 50,000 cryptanalysis prize, if ever set, is escrowed before it is named. Was: Open, decision for the founder (terms, judge and funding) and experiment scheduled (extends O-1.17). Sweep (5 October 2026): nothing runnable; the terms, judge and funding are the founder's decision.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: Correct. M1 and O-1.17 name a bounty for "more than 2x" without a metric, a judge or a fund, and 2x is a design target for the hash, not an economic threshold: a chip at 1.5x per joule and 3x per dollar of capital is an economic ASIC whatever the hash-rate ratio says. The scoring rules go out with the January 2027 benchmark: hashes per second and per joule measured per program over a published set of at least 100 epochs, reported as a distribution (worst decile, median), never as one average; capital cost per unit of hash rate at a stated volume; a longevity term against the instruction-family reserve and the dataset growth of spec 1.13; and the shortcut classes (recomputation, partial storage, weak-program selection) scored separately. Eligible hardware assumptions, the judge, the reward and the payer are the project lead's decisions (fud-fixes row 50: the payer is the entity). The supportable public claim until a design has been scored: across the tested workloads and the stated economic assumptions, consumer GPUs remain competitive against the best independently proposed specialised design. Extends M1, M16 and C13.
|
||||
Answer: Correct. M1 and O-1.17 name a bounty for "more than 2x" without a metric, a judge or a fund, and 2x is a design target for the hash, not an economic threshold: a chip at 1.5x per joule and 3x per dollar of capital is an economic ASIC whatever the hash-rate ratio says. The scoring rules go out with the January 2027 benchmark: hashes per second and per joule measured per program over a published set of at least 100 epochs, reported as a distribution (worst decile, median), never as one average; capital cost per unit of hash rate at a stated volume; a longevity term against the instruction-family reserve and the dataset growth of spec 1.13; and the shortcut classes (recomputation, partial storage, weak-program selection) scored separately. Eligible hardware assumptions, the judge, the reward and the payer are the founder's decisions (fud-fixes row 50: the payer is the entity). The supportable public claim until a design has been scored: across the tested workloads and the stated economic assumptions, consumer GPUs remain competitive against the best independently proposed specialised design. Extends M1, M16 and C13.
|
||||
|
||||
Evidence: M1, O-1.17, spec 1.13 and 1.16, M16's arithmetic. Experiment: the scoring rules published with the benchmark, then the first scored submission. Review: external, point 4.
|
||||
|
||||
|
|
@ -1594,7 +1594,7 @@ Evidence: spec 3.1 W5 and W6, 3.6; `sim/results_v2.md` (renter scenarios only).
|
|||
### F20. During a finality pause the program must keep advancing, and nothing says which guarantees survive
|
||||
"Your epoch seed is a VDF of a certified checkpoint. When finality pauses for four days, your own 50% churn figure, which checkpoint seeds hour 50? And when the pause ends, what exactly was still guaranteed in between?"
|
||||
|
||||
Status: Answered with evidence for the test half (5 October 2026, night, ledger close round 1: the fast-time run through four epoch boundaries under a 47.5% silent set, bench-log "5 October 2026 (night), ledger close round 1: F20 finality pause under a 45% silent set through four epoch boundaries"); the gate-3 wording of the four guarantees (O-3.16, O-4.3) stays a decision for the project lead. Was: Open, decision scheduled at gate 3 (O-3.16, with O-4.3). Sweep (5 October 2026): the seed half is decided (spec 4.3, from O-4.3: the seed checkpoint is the selected-chain block at the lead's blue score, certified or not, so mining never waits for a certificate) and spec 06 marks O-3.16's text closed; the devnet test through three epoch boundaries under a 45% silent set is still owed (devnet, person).
|
||||
Status: Answered with evidence for the test half (5 October 2026, night, ledger close round 1: the fast-time run through four epoch boundaries under a 47.5% silent set, bench-log "5 October 2026 (night), ledger close round 1: F20 finality pause under a 45% silent set through four epoch boundaries"); the gate-3 wording of the four guarantees (O-3.16, O-4.3) stays a decision for the founder. Was: Open, decision scheduled at gate 3 (O-3.16, with O-4.3). Sweep (5 October 2026): the seed half is decided (spec 4.3, from O-4.3: the seed checkpoint is the selected-chain block at the lead's blue score, certified or not, so mining never waits for a certificate) and spec 06 marks O-3.16's text closed; the devnet test through three epoch boundaries under a 45% silent set is still owed (devnet, person).
|
||||
|
||||
Answer: Correct on the gap. Spec 4.3 proposes that the seed checkpoint may be the uncertified selected-chain block at the checkpoint blue score, so a pause does not stop mining, and O-4.3 leaves the decision to gate 3; the design document still says an epoch cannot start without a valid proof. No text states what holds during a pause: that blocks, execution and proofs continue (3.7 item 2 says proof of work in practice), that every lock before the pause stands (3.5), that `finality_active` is false and exchanges wait on the 12-hour finality depth (3.9), and that the seed pipeline advances from uncertified checkpoint blocks with the reorg exposure that implies (a 1,200-DAA-s lead plus d). Gate 3 takes the uncertified option or states the stop; this ledger recommends uncertified, as spec 4.3 does, and the four guarantees go into spec 3.7. Test: the devnet with the finality module stalled by a 45% silent set (3.3.1 row C) through at least 3 epoch boundaries, recording that the program advanced on schedule, that no node forked on the seed, and that the pre-pause locks survived the heal.
|
||||
|
||||
|
|
@ -1607,7 +1607,7 @@ Run (5 October 2026, night): `tools/lock/with-lock.sh run node tools/finality-at
|
|||
|
||||
Status: Fixed in the node and shipped, rule not yet activated on the live devnet (5 October 2026, evening sweep). Was: Fix built, pending rollout (4 October 2026, evening; branch `finality-fixes` of the node, behind `finality_v3_activation_daa`, `docs/plans/finality-v3-rollout-devnet.md`). Was: Open, found by the team (4 October 2026, 12-node cloud devnet, second partition run).
|
||||
|
||||
Sweep (5 October 2026, evening): the code is on every node since 0.3.4 (the 0.3.4 fork was `finality-fixes` 6aa69a45, which carries the fold and the frozen table; 0.3.5 to 0.3.8 keep it, `docs/plans/release-0.3.5.md` 1b) but the switch is not thrown: the live override file read by the 0.3.6 digest check is `{"difficulty_v2_activation_daa": 33000, "proving_v0_activation_daa": 84100}` (`docs/plans/release-0.3.6.md` 8g) and the default is never on every network (`consensus/core/src/config/params.rs`, `finality_v3_activation_daa: u64::MAX` on devnet), so the live devnet runs rule v2 and today's locks still carry 67.0% to 71.9% of active weight (node logs, 5 October 2026: PC 2 `checkpoint 2612 LOCKED ... 67.0% of active`, PC 1 `3080 LOCKED ... 71.9%`). Rollout is the operator step N3 of the plan (publish the switch in the manifest override and every hand node's file at once, as the proving activation did). Decision owner: the project lead (N3). Sweep (5 October 2026): nothing runnable without the devnet rollout; rule v3 is measured on the fast-time 3-node network (held certificates 6 of 6 at 11 of 11 indices, 0 conflicts, lock latency unchanged; bench-log "finality rule v3"). The rollout is an operator step.
|
||||
Sweep (5 October 2026, evening): the code is on every node since 0.3.4 (the 0.3.4 fork was `finality-fixes` 6aa69a45, which carries the fold and the frozen table; 0.3.5 to 0.3.8 keep it, `docs/plans/release-0.3.5.md` 1b) but the switch is not thrown: the live override file read by the 0.3.6 digest check is `{"difficulty_v2_activation_daa": 33000, "proving_v0_activation_daa": 84100}` (`docs/plans/release-0.3.6.md` 8g) and the default is never on every network (`consensus/core/src/config/params.rs`, `finality_v3_activation_daa: u64::MAX` on devnet), so the live devnet runs rule v2 and today's locks still carry 67.0% to 71.9% of active weight (node logs, 5 October 2026: PC 2 `checkpoint 2612 LOCKED ... 67.0% of active`, PC 1 `3080 LOCKED ... 71.9%`). Rollout is the operator step N3 of the plan (publish the switch in the manifest override and every hand node's file at once, as the proving activation did). Decision owner: the founder (N3). Sweep (5 October 2026): nothing runnable without the devnet rollout; rule v3 is measured on the fast-time 3-node network (held certificates 6 of 6 at 11 of 11 indices, 0 conflicts, lock latency unchanged; bench-log "finality rule v3"). The rollout is an operator step.
|
||||
|
||||
Answer: True as measured, and the cause is not a cut-off at all: the node builds the certificate the instant the votes it holds meet Q3, and carries that one. Measured on the cloud logs of the healthy stretch 11:45 to 14:00 UTC (212 indices, `infra/cloud-devnet/results/2026-10-04/f22-vote-timing.md`, script `tools/finality-attacks/vote-timing.py`): the first certificate was built median 1.24 s (p99 1.71 s) after the first node determined the checkpoint, with 7 to 10 of 12 signers (mean 8.27); by then 10.24 votes had been issued on average, so about two were in flight (the miner's 1-s poll, a 250-ms gossip pump per hop, inter-region RTT up to 289 ms) and about two were issued later; the last of the 12 votes was issued median 1.45 s, p90 2.36 s after the first determination. Holding for 1 s after the first build would have carried all 12 votes at 192 of 212 indices; the other 20 are one event, miners 01, 06 and 11 down together for 10 minutes across indices 377 to 396 (the afternoon `hop.sh` restarts), not relay lag. The fix (spec Q4, rule v3): the first certificate still forms at quorum, so lock latency is unchanged; once every voter has signed, or `certificate_fold` DAA seconds after the determination (3 on devnet, 6 on mainnet), a node rebuilds the certificate from every vote it has seen and gossips the heavier one, and every node replaces a held certificate with a verified heavier one over the same block. Presence needs nothing: under the block reading of Q2 a late vote already counts once any block carries it. Unit test `fold_round_carries_late_votes_and_heavier_certificates_replace` (node, `processes::finality`). Network figures: `docs/bench-log.md`, "finality rule v3".
|
||||
|
||||
|
|
@ -1617,7 +1617,7 @@ Evidence: `infra/cloud-devnet/results/2026-10-04/partition-sin-20261004-140305/p
|
|||
"'A mid-range GPU proves a shard in under 20 s.' Your own R2 says: if missed, halve the shard and re-measure. That is the trap. Fix the workload first, measure the whole journey, and have strangers reproduce it."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 12): a 12 GB NVIDIA card (4070) is on order for PC 2; O-7.1 runs end to end on it when it arrives, inside the phase 2 gate. Was: Open, blocked on a 12 GB card (decisions item 12, already pointed: a 3060-class NVIDIA part for PC 2 before the public benchmark): next measurement O-7.1 end to end on that card when it arrives, inside the phase 2 gate (Nov 2026 to Jan 2027 per the litepaper roadmap). Was: Open, experiment scheduled (O-7.1). The journey's phase 2 gate was rewritten the same night. Sweep (5 October 2026): hardware item (the 12 GB card end to end); the standard is written.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: Correct. P1 conceded that the 20-s figure is a target; this is about how the target is tested. `docs/design/execution-layer.md` 9.1 R2 passes at any shard size by halving `S_p` until the time fits, so a pass says nothing about throughput, and R4 measures the wrapper only. The phase 2 benchmark now has an acceptance standard: a fixed published workload (real transactions, never empty blocks or tiny shards) with its shard plan, proven end to end from job received to proof accepted, including queueing, transfers, aggregation, verification and payment; the median and the slowest 5% and 1%; failure and retry rates; full cost (electricity, host, bandwidth, aggregation, failed work, hardware); results per advertised card with mining and proving compatibility stated separately; sustained with no growing backlog; reproduced by at least three unrelated operators from the published code and configuration. A halved shard is a new declared workload, never a pass. The reviewer's figure for SP1's cluster requirement (NVIDIA, 24 GB, approximate; not checked, SP1 is not in `vendor/`) is why a 12 GB card has to show the whole pipeline, which R2 and R4 already target.
|
||||
|
||||
|
|
@ -1661,12 +1661,12 @@ Evidence: spec 2.5, 5.1 to 5.4; `docs/commercial/prover-customer-brief.md`; P10,
|
|||
### E14. No funding table
|
||||
"Who pays for development, the independent review, the infrastructure and an incident response, from what, and what happens if revenue is late? You have no fund by design, which means you have no table either."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 4): the funding table stays internal until counsel has read it; one public sentence in the litepaper names the unfunded lines (the second client, the external reviewers, the bounty before escrow). Was: Open, with a placeholder table: `docs/plans/funding.md` (3 October 2026, marked PLACEHOLDER on 4 October) lists the sources (the founder's own means today, the 1% client fee, the team's own mining and proving, no protocol fee) and the cost lines; the project lead parked funding on 4 October 2026 and the decision stays his. Was: Open, decision for the project lead.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 4): the funding table stays internal until counsel has read it; one public sentence in the litepaper names the unfunded lines (the second client, the external reviewers, the bounty before escrow). Was: Open, with a placeholder table: `docs/plans/funding.md` (3 October 2026, marked PLACEHOLDER on 4 October) lists the sources (the founder's own means today, the 1% client fee, the team's own mining and proving, no protocol fee) and the cost lines; the founder parked funding on 4 October 2026 and the decision stays his. Was: Open, decision for the founder.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: Correct. The fund was removed on purpose (E4) and the team earns from the 1% client fee, its pool, its provers and the app share (E5); none of that is costed, and the second client has no funder (fud-fixes row 47), nor do the external reviewers (G1), the bounty (M22), the seed nodes or the public infrastructure. The table: each cost line (development, independent review, infrastructure, incident response, the bounty, the second client) against its source (the entity's own money, the client fee, the proving business, a grant mechanism added by signalling), labelled funded, dependent on future revenue, or unfunded, with the consequence if revenue is late. It assumes a flat IGN price, which is E15's test. The table is internal until counsel has read it (L1, L2); the litepaper states which lines are unfunded.
|
||||
|
||||
Evidence: E4, E5, G1, G5; fud-fixes rows 47, 50, 71. Decision: the project lead, before the repository goes public. Review: external, point 6.
|
||||
Evidence: E4, E5, G1, G5; fud-fixes rows 47, 50, 71. Decision: the founder, before the repository goes public. Review: external, point 6.
|
||||
|
||||
### E15. The security budget through successive halvings with low fees and no external demand
|
||||
"Walk the schedule forward: emission halves every two years, the base fee is burned, the priority fee is small on a quiet chain, and nobody buys proofs. What does a card earn in year 7, and at what price does hashrate leave? Report what reaches miners and provers apart from what is burned."
|
||||
|
|
@ -1680,26 +1680,26 @@ Evidence: spec 2.5, 5.1 to 5.4; E1, E6. Experiment: O-5.11. Review: external, po
|
|||
### G11. Publish the inspectable components now, labelled experimental
|
||||
"The organisation has no public repository. Harnesses, test vectors, simulators and the specification could be public tonight, marked experimental. Waiting for January is a choice, and it reads as hiding."
|
||||
|
||||
Status: Decided (4 October 2026, 08:20 UTC): the specification subset is public as `igneum-network/spec` (`docs/plans/public-repo.md`), labelled; the node fork, the proving code and the harnesses stay private until the benchmark. Was: Open, decision for the project lead.
|
||||
Status: Decided (4 October 2026, 08:20 UTC): the specification subset is public as `igneum-network/spec` (`docs/plans/public-repo.md`), labelled; the node fork, the proving code and the harnesses stay private until the benchmark. Was: Open, decision for the founder.
|
||||
|
||||
Answer: The fact is conceded in X1 (the repository is private and the site says reproducible) and the pre-publication steps are in `docs/fud-fixes.md` section 5 (ledger out of the tree, CLAUDE.md rewritten, history rewritten, licence). The reviewer asks for an earlier date than January 2027 and a narrower scope: the benchmark harnesses, the test vectors, the simulators and `docs/spec/`, each labelled experimental, with the node fork following when the gate-2 work is in. the project lead decides which components, under which licence, and when; section 5 runs first in any case. The reviewer's companion advice, one proof-request workflow and one reference application before any broader app set, is the same decision's scope: the genesis-app list (G4, O-5.4) is not a prerequisite for the benchmark or the testnet.
|
||||
Answer: The fact is conceded in X1 (the repository is private and the site says reproducible) and the pre-publication steps are in `docs/fud-fixes.md` section 5 (ledger out of the tree, CLAUDE.md rewritten, history rewritten, licence). The reviewer asks for an earlier date than January 2027 and a narrower scope: the benchmark harnesses, the test vectors, the simulators and `docs/spec/`, each labelled experimental, with the node fork following when the gate-2 work is in. The founder decides which components, under which licence, and when; section 5 runs first in any case. The reviewer's companion advice, one proof-request workflow and one reference application before any broader app set, is the same decision's scope: the genesis-app list (G4, O-5.4) is not a prerequisite for the benchmark or the testnet.
|
||||
|
||||
Evidence: X1; `docs/fud-fixes.md` section 5. Decision: the project lead. Review: external, point 7.
|
||||
Evidence: X1; `docs/fud-fixes.md` section 5. Decision: the founder. Review: external, point 7.
|
||||
|
||||
### X13. One paying customer for a stated reason
|
||||
"'One rollup signs for testnet' is a letter of intent with no money. A customer who pays once, pays again without a rebate, and then a second unrelated customer, is evidence. A signature is not."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 5): the paid pilot stays in phase 5, the phase 4 gate stays the signature, nothing moves earlier before counsel answers L4. Was: Open, experiment scheduled (the pilot itself), decision for the project lead on timing and terms; extends L4 and the customer brief. Sweep (5 October 2026): a decision and a customer; nothing runnable.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 5): the paid pilot stays in phase 5, the phase 4 gate stays the signature, nothing moves earlier before counsel answers L4. Was: Open, experiment scheduled (the pilot itself), decision for the founder on timing and terms; extends L4 and the customer brief. Sweep (5 October 2026): a decision and a customer; nothing runnable.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: Correct. The phase 4 gate is a signature and the brief says so ("a signed letter of intent with no payment"). The progression is adopted and the brief carries it at its next version: agree the workload, proof format, deadline, failure rate and price before the pilot; publish the outcome and the customer's own reason for buying; then repeat purchases without reimbursement; then several unrelated customers. The reviewer places the paid pilot before public testnet; the journey has it in phase 5. Phase 4 keeps the signature as its gate and phase 5's line gains the paid pilot; moving it earlier is the project lead's call and needs the entity, terms and tax treatment of L4 first.
|
||||
Answer: Correct. The phase 4 gate is a signature and the brief says so ("a signed letter of intent with no payment"). The progression is adopted and the brief carries it at its next version: agree the workload, proof format, deadline, failure rate and price before the pilot; publish the outcome and the customer's own reason for buying; then repeat purchases without reimbursement; then several unrelated customers. The reviewer places the paid pilot before public testnet; the journey has it in phase 5. Phase 4 keeps the signature as its gate and phase 5's line gains the paid pilot; moving it earlier is the founder's call and needs the entity, terms and tax treatment of L4 first.
|
||||
|
||||
Evidence: `site/journey.json` phases 4 and 5; `docs/commercial/prover-customer-brief.md`; L4, L6. Experiment: the pilot, reported in the bench-log with the agreed numbers. Review: external, point 5.
|
||||
|
||||
### X14. Concentration is unmeasured in four places
|
||||
"Define independent for the 1,000-miner gate, then report concentration in hashing, checkpoint signing, proving and aggregation, because a thousand miners behind two pools is two."
|
||||
|
||||
Status: Answered with evidence for all four (5 October 2026, night, ledger close round 2: signing concentration read from the certificates and votes the chain blocks carry in their coinbase finality section, top-1 10.0%, top-3 29.1%, top-10 77.3% of signed weight over the heaviest certificate at each of 126 indices in the window; bench-log "5 October 2026 (night), ledger close round 2: X14 signing concentration from block payloads"); the independence definition stays the project lead's (X5). Was: Answered with evidence for hashing, aggregation and proving, Open for signing (5 October 2026, night, ledger close round 1: no RPC exposes a certificate's signer set, so the signing concentration needs the observer extract of O-X.1; bench-log "5 October 2026 (night), ledger close round 1: X14 concentration in hashing, signing, proving and aggregation from the Mac node's RPCs, and E16 one live block"); the independence definition stays the project lead's (X5). Was: Open, measurement scheduled (O-X.1); extends X5. Sweep (5 October 2026): hashing concentration computed from the devnet record (`sim/difficulty/records/live-2026-10-04.csv`, 8,090 blocks, 18 vote keys): top-1 12.8%, top-3 34.5%, top-9 98.0%, the nine being devnet v4's nine identities run by three machines (approximate), so by machine the devnet is three parties. Signing, proving and aggregation concentration need certificate and proof-record extracts the observer does not keep yet (O-X.1).
|
||||
Status: Answered with evidence for all four (5 October 2026, night, ledger close round 2: signing concentration read from the certificates and votes the chain blocks carry in their coinbase finality section, top-1 10.0%, top-3 29.1%, top-10 77.3% of signed weight over the heaviest certificate at each of 126 indices in the window; bench-log "5 October 2026 (night), ledger close round 2: X14 signing concentration from block payloads"); the independence definition stays the founder's (X5). Was: Answered with evidence for hashing, aggregation and proving, Open for signing (5 October 2026, night, ledger close round 1: no RPC exposes a certificate's signer set, so the signing concentration needs the observer extract of O-X.1; bench-log "5 October 2026 (night), ledger close round 1: X14 concentration in hashing, signing, proving and aggregation from the Mac node's RPCs, and E16 one live block"); the independence definition stays the founder's (X5). Was: Open, measurement scheduled (O-X.1); extends X5. Sweep (5 October 2026): hashing concentration computed from the devnet record (`sim/difficulty/records/live-2026-10-04.csv`, 8,090 blocks, 18 vote keys): top-1 12.8%, top-3 34.5%, top-9 98.0%, the nine being devnet v4's nine identities run by three machines (approximate), so by machine the devnet is three parties. Signing, proving and aggregation concentration need certificate and proof-record extracts the observer does not keep yet (O-X.1).
|
||||
Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 3): the independence definition and the four concentration reports as X5 states; the observer columns ship with the next cut.
|
||||
|
||||
Answer: Correct. X5 conceded that "independent" needs a measurable definition (distinct ASNs, benchmark hardware fingerprints, pool attestations) and left it to phase 4. The four concentrations can each be computed from chain data: blue blocks per vote key and per pool (hashing), signed weight per key in certificates (checkpoint signing), proof records per prover key (proving, once P12's fix puts the key in the statement), and certificates and proof records per aggregator key (aggregation). The gate reports all four as top-1, top-3 and top-10 shares over 30 days, beside the independence count, on the live page. Transaction choice inside pools is a separate measurement and is already scheduled: whether members of the reference pool use declared templates (spec 9.4.2, mode C) is recorded under O-9.5.
|
||||
|
|
@ -1787,11 +1787,11 @@ Evidence: `docs/bench-log.md`, 4 October 2026 "difficulty rule: timestamp attack
|
|||
"Your proof records pay provers, and the node pays a record whose statement matches its own execution whether or not the SP1 proof behind it verifies. A prover can sign the native statement without proving anything."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 11): proving v0 (every producer verifies off the consensus path) through the public testnet; the in-consensus verifier is the execution engineer's plan item for after it; the litepaper sentence labelled Open stands. Was: Open, stated in spec 7.7 item 4 (4 October 2026). Branch `proving` of the fork, `igneum/exec/src/proving.rs`. Sweep (5 October 2026): stated; the in-consensus verifier is a build item (execution engineer).
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: Correct for v0, and by design for now. The consensus check on a carried record is the native-execution veto (spec 7.2 item 5): the statement must equal the node's own 328-byte shard statement for that shard and payout address, so no record can move state or pay for a wrong claim. The SP1 proof is verified off the consensus path by the proof pool's verifier (`igneum-prove-host --mode verify`), and a producer offers only verified records to its templates; a producer that includes unverified records (trust mode, test networks only) can pay a prover who did not prove. The damage is bounded to that prover's payout. What closes it: the aggregated segment record of design 5.4 verified in consensus, which needs the SP1 verifier inside the node (the SDK dependency the node does not carry today) or a bounded in-consensus verification budget. Until then the devnet runs v0 with every producer verifying.
|
||||
|
||||
Round 2 (5 October 2026, night): the public text now carries the v0 fact, labelled Open: `site/litepaper.html`, Proving, "How a block gets proven": "Open: in proving v0 the SP1 proof itself is checked off the consensus path, by every block producer before it carries a record, and the native-execution check is what consensus enforces; whether the SP1 verifier moves inside consensus is a decision before the public testnet." Status unchanged: decision owner the project lead, decisions item 11.
|
||||
Round 2 (5 October 2026, night): the public text now carries the v0 fact, labelled Open: `site/litepaper.html`, Proving, "How a block gets proven": "Open: in proving v0 the SP1 proof itself is checked off the consensus path, by every block producer before it carries a record, and the native-execution check is what consensus enforces; whether the SP1 verifier moves inside consensus is a decision before the public testnet." Status unchanged: decision owner the founder, decisions item 11.
|
||||
|
||||
### P22. The rewards and payouts are inputs to the shard proof, not outputs
|
||||
"The shard guest takes the segment's rewards and the prover payouts as data and commits the post-root after them. A host can feed any list and the proof still verifies."
|
||||
|
|
@ -1809,13 +1809,13 @@ Round 2 (5 October 2026, night): status made terminal-explicit. Blocker: until t
|
|||
|
||||
## Status updates, 4 October 2026 (the floor raised to two thirds, O-3.15; branch devnet-v4)
|
||||
|
||||
the project lead's decision of 4 October 2026: the total-weight floor of Q3 is 2/3, not 17/30. A lock needs two thirds of all 30-day weight signing (the active test is implied), and finality pauses whenever less than two thirds of the weight is connected and signing; the chain continues on proof of work meanwhile and the node reports it. Spec 3.3, 3.3.1, 3.7, 3.9, 3.11; `sim/results_v2.md`, "Floor 2/3"; `docs/bench-log.md`, "finality floor 2/3"; litepaper Finality and "What Igneum does not claim".
|
||||
The founder's decision of 4 October 2026: the total-weight floor of Q3 is 2/3, not 17/30. A lock needs two thirds of all 30-day weight signing (the active test is implied), and finality pauses whenever less than two thirds of the weight is connected and signing; the chain continues on proof of work meanwhile and the node reports it. Spec 3.3, 3.3.1, 3.7, 3.9, 3.11; `sim/results_v2.md`, "Floor 2/3"; `docs/bench-log.md`, "finality floor 2/3"; litepaper Finality and "What Igneum does not claim".
|
||||
|
||||
- **F2** (the two-hour presence window is an eclipse vector). Status: Closed by rule, floor raised (4 October 2026). A lock needs two thirds of total weight whatever the presence window says, so an eclipsed faction can lock only with two thirds of the network inside the eclipse, which is the twenty-day public event of spec 3.1. Re-measured at the 2/3 floor: the poisoned eclipse (34% attacker plus a 20% pool, the eclipsed side at 54%) gives 0 conflicting locks and 0 locks on the eclipsed side at 1, 2 and 4 h in every seed (`sim/results_v2.md` L3 and F2's floor1.00 rows). Was: Closed by rule (the 56.7% floor).
|
||||
- **F16** (a lock can become uncertified after a heal). Status: rule unchanged (spec 3.11.4: a verified certificate is never withdrawn, O-3.17 implements the conflict report). What the floor changes is how the state F16 describes arises: two certificates at one index now need equivocators holding at least one third of total weight in every scenario (two certificates need 4/3 of weight in signatures), not 13.3% across a partition that outlasts the presence decay (`sim/results_v2.md` H at 2/3: 0 conflicts and no lock on either side through a 33% equivocator, conflicts from minute 0 at 34%). Ten days of 100% hashrate in public, or the long-partition case of F21.
|
||||
- **F18** ("a silent minority cannot freeze finality" is false under the floor). Status: Fixed again (4 October 2026). The litepaper now says a lock needs two thirds of all 30-day weight and that finality pauses whenever less than two thirds is connected and signing. The pause threshold moved from about 42% of weight silent to one third: in the model, whose keys are in outage 2.2% of the time, 30% silent locks every checkpoint, 32% locks 88%, 33% locks 11% and 34% locks none for as long as it stays silent (`sim/results_v2.md` L1). Was: Fixed (56.7% sentence).
|
||||
- **F9** (half the hashrate leaves and finality stalls for ten days). Status: Conceded, stated (4 October 2026). Under the 2/3 floor the critic's number is back: 50% churn pauses finality for 10 days and 35% churn for 1.4 days, until the departed weight ages out of the window (`sim/results_v2.md` D's total column, which the 2/3 floor equals arithmetically, and L2). The chain runs on proof of work meanwhile, the node reports the pause, and the litepaper says so. This is the price of the one-third safety bound and was taken knowingly. Was: Answered by design (the active denominator recovered in two hours).
|
||||
- **F21** (new, from attack scenario 6A). "Your floor is a fraction of a table each side computes for itself. Cut the network in half and leave it cut: after a while each half's window is full of its own blocks, each half holds two thirds of its own table, and both lock without any attacker at all. Your simulation never saw it because it kept the weights global." Status: Fixed in the node and shipped, rule not yet activated on the live devnet (5 October 2026, evening sweep: the code has shipped in every node since 0.3.4 and the switch `finality_v3_activation_daa` is absent from the live override file, default never; the F22 entry above carries the evidence; the overlay-against-GHOSTDAG run of C4 exercised rule v3 on the live node line on the fast-time harness tonight; decision owner for N3: the project lead). Was: Fix built, pending rollout (4 October 2026, evening): rule v3, spec 3.3 Q5, the frozen weight table, on the node's `finality-fixes` branch behind `finality_v3_activation_daa` (`docs/plans/finality-v3-rollout-devnet.md`). The rule: a certificate also needs its signers to hold two thirds of the weight table at the last certified checkpoint on C_i's chain, at that table's weights, while that checkpoint is less than one window old. Both sides of a partition share that table and neither can fill it, so no side under two thirds locks until 30 days have passed without a certified checkpoint; at the heal locking resumes on one chain. Proved first in `sim/finality_v2.py` scenario M (`sim/results_v2.md`, "Rule v3"): 50/50, 60/40 and 55/45 splits never lock in 12 days (v2: days 10.2, 5.2, 7.9), both sides of a 31-day split lock alone at day 30.00 when the frozen table expires, the 70/30 majority locks at once under both rules, every pre-heal lock is kept and the first lock after the heal comes 0 minutes in, the 34% equivocator still conflicts (the one-third bound of 3.11.2 is untouched). The price, stated in 3.7 item 2: a set of one third or more that stops mining and signing at once pauses finality for 30 days (v2: 1.7 days at 35%, 10.1 at 50%); a gradual departure costs nothing because every certified checkpoint re-freezes the table. A view still cannot count blocks it has never seen, so a partition longer than a window forks as before; the fix moves the bound from a third of the window to the whole of it. Node: `processes::finality` (`frozen_table`, the Q5 test in `evaluate`), unit test `frozen_table_holds_a_side_without_the_other_keys_for_one_window`; network figures in `docs/bench-log.md`, "finality rule v3". Was: Conceded, stated (4 October 2026): spec 3.3.1, 3.7 item 9, 3.9 guidance; `sim/results_v2.md` L4 (view-local weights). Correct. A side with pre-split share s holds s + (1 - s) t / 30 of its own table on day t and two thirds of it from day 30 (2/3 - s) / (1 - s): day 10 at 50/50 (day 4 under the old floor), day 5 for the 60 side of 60/40 (at once under the old floor). On the devnet the old floor fell at 84 s of a young 1,439-DAA window (`docs/bench-log.md`, "finality v2 attack harness", S6A); at 2/3 the same cut on a full 1,800-DAA window held for the whole 150-s split and fell at 205 s against a predicted W / (3R) = 200 s (`docs/bench-log.md`, "finality floor 2/3", 6A and 6A long heal). What the devnet adds to the simulation: after the heal the other side's blocks are merged red, so each side's own share jumps rather than drifts, both sides of a 50/50 split certify their own checkpoints within 10 s of each other, and F1 then pins each node to its own certified chain: 26 conflicting certificates and 23 disagreeing locked indices across three nodes, no equivocation, a finality fork that the network heal did not undo and that only an operator's trusted certificate (F5, not implemented) can resolve. No rule removes it, because a view cannot count blocks it has never seen; the floor at two thirds moved the day from 4 to 10, and the exchange guidance treats a node partitioned for more than a day as proof of work until it has rejoined. A rule option for gate 3, not adopted: evaluate the floor against the table of the last locked checkpoint while no newer lock exists, which trades F9's 10-day recovery for a manual override.
|
||||
- **F21** (new, from attack scenario 6A). "Your floor is a fraction of a table each side computes for itself. Cut the network in half and leave it cut: after a while each half's window is full of its own blocks, each half holds two thirds of its own table, and both lock without any attacker at all. Your simulation never saw it because it kept the weights global." Status: Fixed in the node and shipped, rule not yet activated on the live devnet (5 October 2026, evening sweep: the code has shipped in every node since 0.3.4 and the switch `finality_v3_activation_daa` is absent from the live override file, default never; the F22 entry above carries the evidence; the overlay-against-GHOSTDAG run of C4 exercised rule v3 on the live node line on the fast-time harness tonight; decision owner for N3: the founder). Was: Fix built, pending rollout (4 October 2026, evening): rule v3, spec 3.3 Q5, the frozen weight table, on the node's `finality-fixes` branch behind `finality_v3_activation_daa` (`docs/plans/finality-v3-rollout-devnet.md`). The rule: a certificate also needs its signers to hold two thirds of the weight table at the last certified checkpoint on C_i's chain, at that table's weights, while that checkpoint is less than one window old. Both sides of a partition share that table and neither can fill it, so no side under two thirds locks until 30 days have passed without a certified checkpoint; at the heal locking resumes on one chain. Proved first in `sim/finality_v2.py` scenario M (`sim/results_v2.md`, "Rule v3"): 50/50, 60/40 and 55/45 splits never lock in 12 days (v2: days 10.2, 5.2, 7.9), both sides of a 31-day split lock alone at day 30.00 when the frozen table expires, the 70/30 majority locks at once under both rules, every pre-heal lock is kept and the first lock after the heal comes 0 minutes in, the 34% equivocator still conflicts (the one-third bound of 3.11.2 is untouched). The price, stated in 3.7 item 2: a set of one third or more that stops mining and signing at once pauses finality for 30 days (v2: 1.7 days at 35%, 10.1 at 50%); a gradual departure costs nothing because every certified checkpoint re-freezes the table. A view still cannot count blocks it has never seen, so a partition longer than a window forks as before; the fix moves the bound from a third of the window to the whole of it. Node: `processes::finality` (`frozen_table`, the Q5 test in `evaluate`), unit test `frozen_table_holds_a_side_without_the_other_keys_for_one_window`; network figures in `docs/bench-log.md`, "finality rule v3". Was: Conceded, stated (4 October 2026): spec 3.3.1, 3.7 item 9, 3.9 guidance; `sim/results_v2.md` L4 (view-local weights). Correct. A side with pre-split share s holds s + (1 - s) t / 30 of its own table on day t and two thirds of it from day 30 (2/3 - s) / (1 - s): day 10 at 50/50 (day 4 under the old floor), day 5 for the 60 side of 60/40 (at once under the old floor). On the devnet the old floor fell at 84 s of a young 1,439-DAA window (`docs/bench-log.md`, "finality v2 attack harness", S6A); at 2/3 the same cut on a full 1,800-DAA window held for the whole 150-s split and fell at 205 s against a predicted W / (3R) = 200 s (`docs/bench-log.md`, "finality floor 2/3", 6A and 6A long heal). What the devnet adds to the simulation: after the heal the other side's blocks are merged red, so each side's own share jumps rather than drifts, both sides of a 50/50 split certify their own checkpoints within 10 s of each other, and F1 then pins each node to its own certified chain: 26 conflicting certificates and 23 disagreeing locked indices across three nodes, no equivocation, a finality fork that the network heal did not undo and that only an operator's trusted certificate (F5, not implemented) can resolve. No rule removes it, because a view cannot count blocks it has never seen; the floor at two thirds moved the day from 4 to 10, and the exchange guidance treats a node partitioned for more than a day as proof of work until it has rejoined. A rule option for gate 3, not adopted: evaluate the floor against the table of the last locked checkpoint while no newer lock exists, which trades F9's 10-day recovery for a manual override.
|
||||
|
||||
### M24. Your two-lane controller oscillates for an hour when a second miner joins mid-epoch
|
||||
"Watched your devnet this morning. The second 5090 came in at 10:12 and the difficulty never settled: 102M to 164M for forty minutes, 54 to 81 blocks a minute, three or four clamp steps stacked inside a second. Your fast lane and your slow lane disagree by a hair under the trigger and the rule flips between them every two minutes. One card joining is the mildest event a chain can see."
|
||||
|
|
@ -1898,13 +1898,13 @@ Review: `docs/review/round-4-2026-10-04.md`. Scope: devnet v4 through `a21ff239`
|
|||
### X23. One shipped key is an administrator channel to the founder's PCs
|
||||
"Your relay accepts either the URL token or the `x-igneum-key` header for everything, including queuing PowerShell that the PC agent runs as administrator. The key is the log intake key, a literal in six tracked files and inside every Windows and prover package you have handed out. And the zip with both relay secrets sits on the downloads host behind the dl token, which is in your git history and in every installed app. One token, four hops, no privilege boundary."
|
||||
|
||||
Status: Fixed on a branch, pending merge (5 October 2026, night): ledger-relay 28c028b, tests 47 of 47 (relay, 6 suites) + 16 of 16 (packaging/windows/test-inputs-signing.sh) + 2 CI class checks. Was: Open, fatal as an operational fact (4 October 2026). The agent was live and elevated on PC 1 at 13:41 UTC (`GET machines`, read-only). Sweep (5 October 2026): the relay token was rotated on 4 October (`~/.config/igneum/relay-token.old-2026-10-04` sits beside the new one); `POST task` with `kind: run` still needs only the token (`relay/api/relay.mjs:114-119`, no per-machine secret or signature), so the operational half stands. The 401 test needs the deployed relay and PC 1 (relay owner; rotation is the project lead's).
|
||||
Status: Fixed on a branch, pending merge (5 October 2026, night): ledger-relay 28c028b, tests 47 of 47 (relay, 6 suites) + 16 of 16 (packaging/windows/test-inputs-signing.sh) + 2 CI class checks. Was: Open, fatal as an operational fact (4 October 2026). The agent was live and elevated on PC 1 at 13:41 UTC (`GET machines`, read-only). Sweep (5 October 2026): the relay token was rotated on 4 October (`~/.config/igneum/relay-token.old-2026-10-04` sits beside the new one); `POST task` with `kind: run` still needs only the token (`relay/api/relay.mjs:114-119`, no per-machine secret or signature), so the operational half stands. The 401 test needs the deployed relay and PC 1 (relay owner; rotation is the founder's).
|
||||
|
||||
Answer: Correct. `relay/lib/relay.mjs:33-42` returns a truthy value for either secret and `relay/api/relay.mjs:111-124` accepts `kind: run` with `flags.elevated` from it; `relay/clients/igneum-agent.ps1:165-166` runs every item returned, as administrator, within 20 s. `README.md:7` and `make-clients.sh:8` make `RELAY_KEY` the intake key. The hosted `igneum-relay-clients.zip` carries the relay token and the key in four files; the dl token that guards it is 0644 on the Mac, in commit `c47ff03`, and in `igneum-app.json` of every install. Fix, in order: the zip off the host; rotate the relay token; a relay key of its own; a second per-machine secret or an Ed25519 signature over `{id, to, body}` for `run`; rotate the intake key and repackage. Review ids R4.4.1, R4.4.2, R4.5.1.
|
||||
|
||||
Evidence: the files above; `docs/review/round-4-2026-10-04.md` sections 4 and 5. Experiment: after the fix, `POST task` with the old key and with a key-only header must return 401, and `GET machines` must show the rotated agent on PC 1.
|
||||
|
||||
Fix (5 October 2026, night): three tiers in `relay/lib/guard.mjs` (`authVia`): the console token (header or the phone page's path), the relay's own key (`RELAY_KEY`: reads and reports, never `task`, `run`, `name`, `role`, `secret`, `delete`), and the intake key (`the log key`, `_NEXT`) as a tier of its own that may only `upload` and `drop` a file or a note, no reads; it exists because the 0.3.6+ apps upload build-job outputs with it (`app/igneum-app/src/jobrun.rs`, `relay_upload`), and `RELAY_INTAKE_COMPAT=0` on the project closes it the day the apps carry a relay key (that app change is owed, not in this branch). A `run` task now needs, on top of the token, `flags.sig`, an Ed25519 signature by the Mac's run key (`~/.config/igneum/relay-run-key`, `node tools/relay.mjs keygen`) over `runCanon` = {machine, nonce, body sha256, elevated, reboot_continue, reboot}, verified by the relay with `RELAY_RUN_PUB` (401 without it or with a wrong one; 409 on a reused nonce; every run refused while `RELAY_RUN_PUB` is unset), and `flags.mac`, an HMAC-SHA256 tag with the target PC's own secret that `igneum-agent.ps1` (`Check-Task`) and `agent.sh` (`check_task`) verify before anything runs (exit 77 and a result when it fails; Windows PowerShell 5.1 has no Ed25519, so the agent's check is the HMAC). The console and the wake POST refuse the intake tier (`authedNoIntake`). Tests: `relay/test/handler.test.mjs` (a token-only `POST task` kind `run` is 401; a signed one is stored; a changed body, flag or target, another key, or no `RELAY_RUN_PUB` is 401; the relay key gets 403 on `task`; the intake key gets 403 on everything but `upload` and a file drop), `relay/test/guard.test.mjs` (the signature, the tag, `checkRun`). Owed to the project lead: `keygen` and `RELAY_RUN_PUB` on the project, one `secret` per PC with the zip carried by hand, the hosted `igneum-relay-clients.zip` off the downloads host (its values are dead since the 4 and 5 October rotations, the file remains), and the deploy (`relay/README.md`, "Rotation"). The 401 against the deployed relay and `GET machines` on PC 1 run after that deploy.
|
||||
Fix (5 October 2026, night): three tiers in `relay/lib/guard.mjs` (`authVia`): the console token (header or the phone page's path), the relay's own key (`RELAY_KEY`: reads and reports, never `task`, `run`, `name`, `role`, `secret`, `delete`), and the intake key (`the log key`, `_NEXT`) as a tier of its own that may only `upload` and `drop` a file or a note, no reads; it exists because the 0.3.6+ apps upload build-job outputs with it (`app/igneum-app/src/jobrun.rs`, `relay_upload`), and `RELAY_INTAKE_COMPAT=0` on the project closes it the day the apps carry a relay key (that app change is owed, not in this branch). A `run` task now needs, on top of the token, `flags.sig`, an Ed25519 signature by the Mac's run key (`~/.config/igneum/relay-run-key`, `node tools/relay.mjs keygen`) over `runCanon` = {machine, nonce, body sha256, elevated, reboot_continue, reboot}, verified by the relay with `RELAY_RUN_PUB` (401 without it or with a wrong one; 409 on a reused nonce; every run refused while `RELAY_RUN_PUB` is unset), and `flags.mac`, an HMAC-SHA256 tag with the target PC's own secret that `igneum-agent.ps1` (`Check-Task`) and `agent.sh` (`check_task`) verify before anything runs (exit 77 and a result when it fails; Windows PowerShell 5.1 has no Ed25519, so the agent's check is the HMAC). The console and the wake POST refuse the intake tier (`authedNoIntake`). Tests: `relay/test/handler.test.mjs` (a token-only `POST task` kind `run` is 401; a signed one is stored; a changed body, flag or target, another key, or no `RELAY_RUN_PUB` is 401; the relay key gets 403 on `task`; the intake key gets 403 on everything but `upload` and a file drop), `relay/test/guard.test.mjs` (the signature, the tag, `checkRun`). Owed to the founder: `keygen` and `RELAY_RUN_PUB` on the project, one `secret` per PC with the zip carried by hand, the hosted `igneum-relay-clients.zip` off the downloads host (its values are dead since the 4 and 5 October rotations, the file remains), and the deploy (`relay/README.md`, "Rotation"). The 401 against the deployed relay and `GET machines` on PC 1 run after that deploy.
|
||||
|
||||
### X24. The relay token rides in the URL on every request
|
||||
"Every poll of every agent and every page refresh puts the token in the path, so it is in Vercel's request logs, in browser history and in every terminal that ran `tools/relay.mjs`. You built an `x-relay-token` header and nobody uses it."
|
||||
|
|
@ -1959,7 +1959,7 @@ Answer: Correct on each point: `relay/lib/relay.mjs:38,40`; `relay/vercel.json:8
|
|||
|
||||
Evidence: the files above.
|
||||
|
||||
Fix (5 October 2026, night): the remaining points. The GET that acks: `GET inbox` marks nothing (`ack=1` is ignored); `POST inbox {machine, kind, ack:true}` returns the list and marks it, and every client uses the POST. The reboot trigger: the agent restarts only when `RELAY-REBOOT` stands on a line of its own (`(?m)^RELAY-REBOOT\r?$`; `wantsReboot` in `guard.mjs`) AND the task was queued with `--reboot` or `--reboot-continue` (`flags.reboot`, part of the signed text); a marker inside other output, or in a task without the flag, is logged and refused. The rate limit: 120 calls a minute per IP and 10 failed authentications a minute per IP, 429 with `Retry-After` (`RateLimit` from `lib/wake.mjs`). The register payload: no username and no folder from either agent, and the relay strips `info.user` and `info.dir` whatever a client sends. The NOPASSWD line: `wsl-setup.ps1` writes `igneum ALL=(root) NOPASSWD:SETENV: /usr/bin/apt-get, /usr/bin/dpkg` (what `setup-wsl.sh` runs under sudo: lines 20, 21, 27, 28, 31) and checks it with `visudo -cf`; `prover-setup.ps1` no longer echoes the password into `sudo -S` and tests `sudo -n apt-get --version` instead. The `igneum`/`igneum` password itself stays (the user exists to be unattended). The stray file: `ls -la ~/.config/igneum` tonight (read-only) lists no file whose name is a token; the 28-character file beside `desec-token` is gone, so nothing is left for the project lead to delete there. Tests: `handler.test.mjs` (GET inbox with `ack=1` leaves `read` false, POST acks; 429 after the limit, a second IP unaffected, failed auths on their own counter; registration stripped), `guard.test.mjs` (`wantsReboot`), `clients.test.mjs` (the agents' marker regex and flag gate, no GET ack in any client, the sudoers line, no `sudo -S`). Review ids R4.4.9 to R4.4.13 closed; the WSL user's password is the one point kept by design.
|
||||
Fix (5 October 2026, night): the remaining points. The GET that acks: `GET inbox` marks nothing (`ack=1` is ignored); `POST inbox {machine, kind, ack:true}` returns the list and marks it, and every client uses the POST. The reboot trigger: the agent restarts only when `RELAY-REBOOT` stands on a line of its own (`(?m)^RELAY-REBOOT\r?$`; `wantsReboot` in `guard.mjs`) AND the task was queued with `--reboot` or `--reboot-continue` (`flags.reboot`, part of the signed text); a marker inside other output, or in a task without the flag, is logged and refused. The rate limit: 120 calls a minute per IP and 10 failed authentications a minute per IP, 429 with `Retry-After` (`RateLimit` from `lib/wake.mjs`). The register payload: no username and no folder from either agent, and the relay strips `info.user` and `info.dir` whatever a client sends. The NOPASSWD line: `wsl-setup.ps1` writes `igneum ALL=(root) NOPASSWD:SETENV: /usr/bin/apt-get, /usr/bin/dpkg` (what `setup-wsl.sh` runs under sudo: lines 20, 21, 27, 28, 31) and checks it with `visudo -cf`; `prover-setup.ps1` no longer echoes the password into `sudo -S` and tests `sudo -n apt-get --version` instead. The `igneum`/`igneum` password itself stays (the user exists to be unattended). The stray file: `ls -la ~/.config/igneum` tonight (read-only) lists no file whose name is a token; the 28-character file beside `desec-token` is gone, so nothing is left for the founder to delete there. Tests: `handler.test.mjs` (GET inbox with `ack=1` leaves `read` false, POST acks; 429 after the limit, a second IP unaffected, failed auths on their own counter; registration stripped), `guard.test.mjs` (`wantsReboot`), `clients.test.mjs` (the agents' marker regex and flag gate, no GET ack in any client, the sudoers line, no `sudo -S`). Review ids R4.4.9 to R4.4.13 closed; the WSL user's password is the one point kept by design.
|
||||
|
||||
### G12. The PoW schedule comes from the environment on every network, including mainnet
|
||||
"Your mainnet gate refuses the override file. It does not refuse `IGNEUM_POW_EPOCH_BLOCKS`. A node without a file installs the schedule from the environment and `Params.pow_epoch_blocks` is never consulted."
|
||||
|
|
@ -1988,14 +1988,14 @@ Fix (5 October 2026, night): the chain already on master was read end to end and
|
|||
### G14. Secrets and identity in the history of a repository with a public date
|
||||
"The intake key is in six files across eight commits, the dl token in one, the review and ledger files are tracked, 51 tracked files carry the founder's first name, and every commit today is stamped with the local-time offset. The 3 October sweep said zero hits."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 8): the history rewrite runs the morning after the last of the close's branches merges, with every worktree removed first and both secrets rotated regardless. Was: Fixed on a branch, pending merge (5 October 2026, night), the tooling part: ledger-relay 28c028b, tests 47 of 47 (relay, 6 suites) + 16 of 16 (packaging/windows/test-inputs-signing.sh) + 2 CI class checks. Decision owner: the project lead for the rewrite date (`docs/plans/ledger-decisions.md`). Was: Open (4 October 2026); extends `docs/fud-fixes.md` section 5.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 8): the history rewrite runs the morning after the last of the close's branches merges, with every worktree removed first and both secrets rotated regardless. Was: Fixed on a branch, pending merge (5 October 2026, night), the tooling part: ledger-relay 28c028b, tests 47 of 47 (relay, 6 suites) + 16 of 16 (packaging/windows/test-inputs-signing.sh) + 2 CI class checks. Decision owner: the founder for the rewrite date (`docs/plans/ledger-decisions.md`). Was: Open (4 October 2026); extends `docs/fud-fixes.md` section 5.
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: Correct, count-only. The key: `packaging/mac/packaged-config.sh`, `infra/gpu-bench/upload.sh`, `proving/windows-wsl2/prove-block.sh`, `prove-shard.sh`, `proto-cuda/windows-miner/upload-log.bat`, `proto-cuda/windows-app/upload-log.bat`, commits `78df757` to `4c9810f`. The token: `docs/plans/morning-2026-10-04.md:49`, commit `c47ff03`. `git check-ignore` returns nothing for the ledger, fixes and review files. The CI identity grep covers the public export list, by design. Fix: both secrets join section 5 step 4's rewrite list (and are rotated regardless); `TZ=UTC` in the commit path now. Review ids R4.4.8, R4.5.3, R4.5.4.
|
||||
|
||||
Evidence: `git ls-files | xargs grep -lF <value>` counts, `git log -S`. Experiment: section 5 step 7 re-run after the rewrite returns nothing.
|
||||
|
||||
Fix (5 October 2026, night): `TZ=UTC` in every commit path the tooling owns: `tools/ship-app.mjs` (`git()` runs with `env: { TZ: 'UTC' }`), `packaging/ota/publish-jobs.sh` (`export TZ=UTC`, found by the class check), `tools/repo/fresh-repo.sh` (already). The class check `tools/ci/commit-tz-check.sh` (self-test first) fails CI on any script under `tools/`, `packaging/`, `infra/` or `.github/` that invokes `git commit` without `TZ=UTC`, and prints the count of commits on the branch with a non-UTC offset: 417 tonight, 0 after the rewrite. The two secrets on the rewrite list: `docs/plans/history-rewrite.md` section 2 already names the intake key and the dl token in `replace.txt`; added tonight: after the 5 October rotation the values IN THE HISTORY are the ones in `~/.config/igneum/the log key.old-2026-10-05` and `dl-token.old-2026-10-05`, so `replace.txt` must be written from the `.old` files, not the live ones; the relay key, token, run key and machine secrets are in 0 files and 0 commits. The commit of this branch carries `+0000`. The rewrite itself (and its day) is the project lead's decision.
|
||||
Fix (5 October 2026, night): `TZ=UTC` in every commit path the tooling owns: `tools/ship-app.mjs` (`git()` runs with `env: { TZ: 'UTC' }`), `packaging/ota/publish-jobs.sh` (`export TZ=UTC`, found by the class check), `tools/repo/fresh-repo.sh` (already). The class check `tools/ci/commit-tz-check.sh` (self-test first) fails CI on any script under `tools/`, `packaging/`, `infra/` or `.github/` that invokes `git commit` without `TZ=UTC`, and prints the count of commits on the branch with a non-UTC offset: 417 tonight, 0 after the rewrite. The two secrets on the rewrite list: `docs/plans/history-rewrite.md` section 2 already names the intake key and the dl token in `replace.txt`; added tonight: after the 5 October rotation the values IN THE HISTORY are the ones in `~/.config/igneum/the log key.old-2026-10-05` and `dl-token.old-2026-10-05`, so `replace.txt` must be written from the `.old` files, not the live ones; the relay key, token, run key and machine secrets are in 0 files and 0 commits. The commit of this branch carries `+0000`. The rewrite itself (and its day) is the founder's decision.
|
||||
|
||||
### X18. Two nodes with two override files connect, and only some mismatches fork
|
||||
"Your handshake compares the network name and nothing else. A PoW or difficulty mismatch forks and bans; a `finality` mismatch is a WARN; `rollout-v2.sh` throws the finality block away when it writes the file; the app rewrites the packaged file on every start."
|
||||
|
|
@ -2219,23 +2219,23 @@ The lines (PC 2, job `m16-inline-pc2-1`, 00:41 to 00:43 UTC, the card otherwise
|
|||
### E18. The dev fee is a protocol fee with better PR
|
||||
"A 1% dev fee in the official miner is 1% of the chain's hashrate paid to one company for as long as miners run it. Call it what it is: a founder allocation, hidden in the client, and nobody can tell how often it really fires."
|
||||
|
||||
Status: Answered by design and with evidence (4 October 2026, evening; the project lead's decision of that evening, branch `dev-fee` in both repositories).
|
||||
Status: Answered by design and with evidence (4 October 2026, evening; the founder's decision of that evening, branch `dev-fee` in both repositories).
|
||||
|
||||
Answer: The fee exists and is disclosed; the rest is wrong in three places. (1) It is software-level, not protocol-level: no consensus rule, coinbase rule or emission rule knows of it. The chain pays whatever payout address a block template names, and the miner software names the dev address for one template in 100. A different client, or the same client with `--dev-fee 0` (a switch in the app's Settings, `DEV_FEE=0` on HiveOS), pays nothing and the chain treats its blocks exactly the same. That is the norm for GPU miners (lolMiner, T-Rex, approximate as to their percentages) and the litepaper says so beside the words "the protocol carries no fee". (2) It is auditable, not hidden: the choice is a template counter, not a random draw. Template n (from 0) is a fee template when floor((n + 1) p / 100) > floor(n p / 100), which at p = 1 is exactly the templates 99, 199, 299, ...; the source is one function (`fee_slot`, `igneum/miner/src/main.rs`, section "Software dev fee"), the miner prints `dev fee 1% (1 block in 100) to 0x<address>; --dev-fee 0 turns it off` at start, logs `dev-fee block <hash>` for each one and counts `fee=N` in its status line, and `igneum-miner payouts <node>` reads the chain back and lists blocks per payout address with the dev address tagged. (3) It takes nothing from anyone else's security: a fee block keeps the user's vote key, so the user's finality weight is unchanged; only the execution-layer payout of that block moves.
|
||||
|
||||
Evidence: `docs/design/miner-dev-fee.md`; the unit tests in `igneum/miner/src/main.rs` (`dev_fee_tests`: 100 fee templates in 10,000 at 1%, 0 at 0, exact at 2 to 100%); the test-network run in `docs/bench-log.md` ("the software dev fee measured") with the dev address's block count against the miners' own counters and the 1-in-100 expectation. Open: the release address is a placeholder (`DEV_FEE_ADDRESS`) until the project lead fills it before any public release; the devnet address is labelled as such.
|
||||
Evidence: `docs/design/miner-dev-fee.md`; the unit tests in `igneum/miner/src/main.rs` (`dev_fee_tests`: 100 fee templates in 10,000 at 1%, 0 at 0, exact at 2 to 100%); the test-network run in `docs/bench-log.md` ("the software dev fee measured") with the dev address's block count against the miners' own counters and the 1-in-100 expectation. Open: the release address is a placeholder (`DEV_FEE_ADDRESS`) until the founder fills it before any public release; the devnet address is labelled as such.
|
||||
|
||||
### X29. Host and file hygiene, minor
|
||||
"The Mac's live node binds its gRPC to every interface. Four secrets or pointers in `~/.config/igneum` are world-readable, one token is a filename, and the intake key rides on `curl`'s command line. The manifest answers CORS `*` and the clock source is a cacheable page's Date header."
|
||||
|
||||
Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 9): node 1 binds its RPC to localhost at its next planned restart, and the wallet's node too; PC 2 on its own node or a tunnel. Was: Fixed on a branch, pending merge (5 October 2026, night), the curl part: ledger-relay 28c028b, tests 47 of 47 (relay, 6 suites) + 16 of 16 (packaging/windows/test-inputs-signing.sh) + 2 CI class checks. Open: the live node's `--rpclisten` (decision, operator, group E) and the app's clock source (round 2). Was: Open, minor (4 October 2026). Sweep (5 October 2026): read-only checks on this Mac: every secret under `~/.config/igneum` is now mode 600 (only `ota-signing-key.pub` is world-readable, as it should be), so that half is fixed; the live node still listens on every interface (`lsof`: `igneumd` on `*:26610`). The `curl` command line and the clock source were not re-checked.
|
||||
Decision owner: the project lead, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section).
|
||||
|
||||
Answer: Correct. `--rpclisten=0.0.0.0:26610` on pid 33114 (no `--unsafe-rpc`, `--disable-upnp`); `ls -la ~/.config/igneum`; `app/igneum-app/src/update.rs` (`https_time`, `upload_log`); the dl host's headers. Vercel rewrote `Date` to now on a cache hit today, so the cached-Date failure did not show. Fix: RPC on loopback with PC 2 on a tunnel or its own node; `chmod 600`; the stray file removed; the key passed to `curl` through `-K` or a header file; an uncacheable path for the clock source. Review ids R4.5.5 to R4.5.7.
|
||||
|
||||
Evidence: `lsof`, `ls`, `curl -I`.
|
||||
|
||||
Fix (5 October 2026, night), the curl part: `infra/gpu-bench/upload.sh` writes `header = "x-igneum-key: ..."` to a 0600 temporary config and calls `curl -K`; `proto-cuda/windows-app/upload-log.bat` and `proto-cuda/windows-miner/upload-log.bat` do the same with a `%TEMP%` config deleted with the body; `relay/clients/agent.sh` and `send.sh` keep every secret header in a 0600 `headers.cfg` and use `-K`; `prove-block.sh` and `prove-shard.sh` already send the key from inside python's `urllib` (no command line). The class check: `tools/ci/curl-header-check.sh` (self-test first) fails CI on any `.sh`, `.bat`, `.cmd` or `.ps1` line that passes `x-igneum-key`, `x-relay-token` or `x-machine-secret` as a curl `-H` argument; tonight's tree: 0 hits. Not in this branch: the app's own `curl` calls still put the key on the command line (`app/igneum-app/src/update.rs:91`, `jobrun.rs` `relay_upload`); that is app code, owed to the app's next cut, named here so it is not lost. The mode half was fixed on 5 October (every secret 600); the `--rpclisten` half is the project lead's; the clock source is a round 2 candidate.
|
||||
Fix (5 October 2026, night), the curl part: `infra/gpu-bench/upload.sh` writes `header = "x-igneum-key: ..."` to a 0600 temporary config and calls `curl -K`; `proto-cuda/windows-app/upload-log.bat` and `proto-cuda/windows-miner/upload-log.bat` do the same with a `%TEMP%` config deleted with the body; `relay/clients/agent.sh` and `send.sh` keep every secret header in a 0600 `headers.cfg` and use `-K`; `prove-block.sh` and `prove-shard.sh` already send the key from inside python's `urllib` (no command line). The class check: `tools/ci/curl-header-check.sh` (self-test first) fails CI on any `.sh`, `.bat`, `.cmd` or `.ps1` line that passes `x-igneum-key`, `x-relay-token` or `x-machine-secret` as a curl `-H` argument; tonight's tree: 0 hits. Not in this branch: the app's own `curl` calls still put the key on the command line (`app/igneum-app/src/update.rs:91`, `jobrun.rs` `relay_upload`); that is app code, owed to the app's next cut, named here so it is not lost. The mode half was fixed on 5 October (every secret 600); the `--rpclisten` half is the founder's; the clock source is a round 2 candidate.
|
||||
|
||||
### X30. The live page and the bench page exposed operational detail
|
||||
"The engineering log page rendered the bench log with private strings; `/api/live` returned peer addresses, full key hashes and payout addresses; the mobile menu did not open."
|
||||
|
|
@ -2368,7 +2368,7 @@ Evidence: unit test `a_sync_request_below_retention_is_an_error_not_a_panic` (a
|
|||
|
||||
- **Moved to Fixed or Rolled out, from evidence that already existed and had not reached the ledger:** M15 (cheap checks before the PoW engine, merged and live), M17 (hot swap, measured on the live devnet across three vendors), M19 (the census cells filled, 16 loads a Definition), M24 (rule v2 activated at DAA 33,000), P20 (the buffered save confirmed on the third run), X16 (the evidence page exists), G11 (the spec is public).
|
||||
- **Moved to Answered with evidence:** F1 (the first-month gate implemented, measured on 4 October and re-confirmed tonight on the finality-fixes build: the burster locks nothing alone; the launch month is arithmetic now), F7 (reorg depth p50 1, p99 3, max 5 on a 12-node, 5-region network), F19 (bought keys are worth their blocks; scenario K at both floors), E12 (the simulation half), E15 (the security-budget model: the floor is crossed in year 7, 11 or never by price, and no fee level moves it).
|
||||
- **Fix built on a branch, pending merge or rollout:** M26, M27, X21 (`miner-reliability` `aea5ac6d`, with the app half on `release-0.3.5`), F22 (rule v3, fast-time network), part of X22. Sweep (5 October 2026, evening): M26, M27, X21, F23, F24, G12, X18, M30, M31, F25 and M20 are now "Fixed (rolled out 5 October 2026, 0.3.5)" with their live measurement lines; F21 and F22 are shipped in every node since 0.3.4 and wait only for the switch N3 (decision owner the project lead).
|
||||
- **Fix built on a branch, pending merge or rollout:** M26, M27, X21 (`miner-reliability` `aea5ac6d`, with the app half on `release-0.3.5`), F22 (rule v3, fast-time network), part of X22. Sweep (5 October 2026, evening): M26, M27, X21, F23, F24, G12, X18, M30, M31, F25 and M20 are now "Fixed (rolled out 5 October 2026, 0.3.5)" with their live measurement lines; F21 and F22 are shipped in every node since 0.3.4 and wait only for the switch N3 (decision owner the founder).
|
||||
- **Open with new evidence and a fix row (fud-fixes section 2.5):** M20 (the stub is still in the pruning-proof path on `devnet-v4`; it goes live the moment the devnet passes its pruning depth), M21 (the k table from the fork's own function), M28, X20, P15, X29 (half fixed: file modes), X14 (hashing concentration measured), M25 (confirmed live in the sweep: a mismatched day length is rejected as `BlockInvalid` with no reason named, 0 of 4 against 7 of 7), M14 and F14 (no amplification in the chain model under rule v2 or Kaspa's rule, nor on the finality-fixes node under fast time, s5 ratio 0.864; the finality-with-DAA run still owed).
|
||||
- **Open, needs hardware, a person or the devnet:** M1, M11 (a rig), M16 (the 5090), M22, X19 (the node line; `faketime`), X23 to X28 (the relay owner and PC 1; the token is rotated, the run-task binding is not), E13, E14, E16, E17 (the draw lines), F16, F20 (the devnet test), C4 (module off), P3, P14, P16, P17, P21, P22, X13, X15, X17, G10, L1 to L5, L8, D5, D6.
|
||||
- **Nothing became worse.** Two things are closer than they look: M20 becomes a live failure for every fresh node once the devnet's pruning point leaves genesis, which at the devnet's 1.05 DAA/s (DAA 33,000 at 17:37 UTC on 4 October) is between DAA 108,000 (`PRUNING_DURATION`, about 14:00 UTC on 5 October) and DAA 151,200 (the first finality point a full pruning depth below the tip, about 01:00 UTC on 6 October), approximate; X23's operational half (a run task on the PCs needs only the relay token) is unchanged after the rotation.
|
||||
|
|
@ -2392,7 +2392,7 @@ The earlier count table above is kept as history (it counts the 80 entries of ve
|
|||
| Conceded, stated, or terminal (no experiment possible, contained by rule) | 52 | M2 M4 M7 M9 M13 F5 F6 F8 F10 P1 P2 P4 P6 P7 P10 E1 E5 E6 E8 G1 G2 G4 G5 G6 G8 C2 C3 C5 C6 C7 C8 C10 C11 X1 X2 X3 X4 X7 X8 X9 X10 M18 C13 L8 E13 D1 D2 D3 D4 D6 L9 M29 |
|
||||
| Answered by design or with evidence | 27 | M3 M8 M10 M11 M12 F4 F7 F9 F11 F12 F13 P9 E2 E3 C1 C12 L6 M14 M21 F14 F19 F20 P17 E12 X14 E16 E18 |
|
||||
| Decided or closed by rule | 12 | F2 F3 P5 P8 E4 E7 G3 G7 C9 X6 E15 G11 |
|
||||
| Open, decision owner the project lead (`docs/plans/ledger-decisions.md`) | 11 | M1 M22 F16 E14 X13 L1 L2 L4 L5 P21 X5 |
|
||||
| Open, decision owner the founder (`docs/plans/ledger-decisions.md`) | 11 | M1 M22 F16 E14 X13 L1 L2 L4 L5 P21 X5 |
|
||||
| Open, blocked on hardware, a customer or a later phase | 6 | P3 (wrapper, phase 2) M16 (PC 2 job, round 2) P16 (a 12 GB card) X15 (public testnet) P22 (phase 2) X17 (design, round 2) |
|
||||
| Conceded, scheduled or mitigation in progress | 2 | L3 D5 |
|
||||
| Open, minor | 1 | E17 (the draw lines) |
|
||||
|
|
@ -2410,7 +2410,7 @@ Same rule as the count above. 167 entries (P23 added by round 2).
|
|||
| Conceded, stated, or terminal | 52 | unchanged; D6 now carries its review (`docs/review/d6-forged-job-result-2026-10-05.md`) and D5 its owner and gate |
|
||||
| Answered by design or with evidence | 26 | the 27 above less P17, with X14 now answered for all four concentrations |
|
||||
| Decided or closed by rule | 12 | unchanged; F3 and F17 carry the spec 3.4.2 proposals for gate 3 |
|
||||
| Open, decision owner the project lead (`docs/plans/ledger-decisions.md`, items 1 to 13) | 11 | M1 M22 F16 E14 X13 L1 L2 L4 L5 P21 X5 |
|
||||
| Open, decision owner the founder (`docs/plans/ledger-decisions.md`, items 1 to 13) | 11 | M1 M22 F16 E14 X13 L1 L2 L4 L5 P21 X5 |
|
||||
| Open, blocked on hardware, a customer or a later phase, blocker and next date in the Status line | 5 | P3 (phase 2 wrapper) P16 (a 12 GB card) X15 (public testnet) P22 (phase 2 consensus proof) M16 (the kernel is written and bit-exact on the Mac; the PC 2 run is queued behind the 0.3.11 rollout) |
|
||||
| Conceded, scheduled or mitigation in progress | 2 | L3 D5 |
|
||||
| Open, minor | 1 | E17 (the draw lines ride in the queued M16 job) |
|
||||
|
|
@ -2435,6 +2435,35 @@ Same rule as the counts above. 167 entries.
|
|||
The bucket "Decided or closed by rule" counts each entry once: M8, M11 and P16 move there from Answered, so Answered is 28 less those three plus M16 and E17, as the table states; the sum of the rows is 167 with M8, M11, P16 and F3, F17 counted in Decided only.
|
||||
|
||||
|
||||
## Round 5 entry (7 October 2026, afternoon): the class v4 load-source amendment
|
||||
|
||||
### AP-F8-1. A load whose source was last written by `or`, `mul` or `mulhi` makes a cross-hash hot set
|
||||
"The item histogram of class v4 over 2^26 nonces is not uniform: the top 0.1 percent of items take 0.520 percent of reads against 0.115 for a uniform control (4.05x), one item takes 78,479 reads (153x the mean), and site 15 feeds 6.37 percent of its reads into that top 0.1 percent in every iteration." (attack-pass row F8, `docs/analysis/attack-pass/f8-uniform.md`, 7 October 2026)
|
||||
|
||||
Status: Fixed on a branch, pending the 0.3.20 node ship (7 October 2026, afternoon; the founder's word 15:2x UK: option A, "do this but limit the testing, get it pushed"): `ca3-v4-amend` a0aaca92 (the generator and the packs) and 1748fd1d (the PC 2 playbook), on origin/master 5c08c6e0 plus `ca3-v4-uniform` 095f84a7 (the analysis). The node side rides `release-0.3.20-node`; the stamp is agreed with the node lane (a283f5f0d364ceef0). Was: a finding (7 October 2026, morning).
|
||||
|
||||
Answer: Correct as a fault, wrong as a null. The window layer (spec 01 1.13.1 as proposed, `docs/plans/era-layout.md` 1.4) moves the uniform null from 0.115 to 0.160 percent at the top 0.1 percent (1.39x, not 4.05x) and explains every per-site row of F8's attribution except site 15. Site 15's source r6 was last written by `or r6, r4` (instruction 61, the load at 63), a non-injective op whose output bits are 1 with probability 3/4, so the all-ones source recurs with probability (3/4)^32 per read; the era map sends it to item 0xca5b92, F8's hottest item exactly, and F8's next seven items are exactly the seven one-zero-bit sources whose zero survives the window mask. The popcount model at the measured bias (p = 0.7585) predicts 77,348 all-ones reads against 78,479, and the program's top-0.1-percent share at 0.58 against 0.52. The acceptance rule's part (a) takes any write as a fresh source and part (c) counts saturation on final register values only, so the class of fault passes it: of 1,024 chain-shaped class v4 programs 96.6 percent carry a load whose source's last writer is `or`, `mul` or `mulhi`, 48.5 percent an `or`-sourced one (0.30 percent of all reads per site), 4.9 percent an `or`-of-`or` chain (p3's class: 72 percent of that site's reads, 4.6 percent of all reads, on 0.1 percent of items). The ceiling under rule (c)'s 120-of-128 floor is one site repeating its item in all 8 iterations, 6.25 percent of reads, a chip edge of at most 1.067x in 64 bytes of SRAM; the public claim's 2x margin stands, and the public line says "bounded", not "uniform" (`docs/analysis/ca3-v4-uniform.md` sections 1 to 4).
|
||||
|
||||
The amendment (a0aaca92): in class v4's chain draw a load's source is drawn only from registers whose last writer injects (add, sub, xor, mad, shfl, load) or is a rotate (rotl, rotr), never one last written by `or`, `mul` or `mulhi` (`generator.rs` candidate_from_words_class, keyed on the era-composed V4_CLASS; no attempts lost, rule (a) unchanged; v2, v3 and the generator-2 ladder packs byte-identical). Split protection (the node lane's form): generator stays 4 and a generator-4 program id appends `"sub/" || PROGRAM_SUBVERSION_V4 (= 1) as little-endian u16` inside `program_id()`, so a binary from before the rule and one after it never share a program id for one seed and the node's id check catches a split; packs carry `IGNEUM_PROGRAM_SUBVERSION 1` and `"sub_version": 1`, and packcheck refuses a generator-4 pack whose sub-version is absent or other. The node side (release-0.3.20-node, built to a0aaca92): kaspa-pow's test pins 1a4230699a6b9c60 must-equal and c120d7963abdcd96 must-differ through `generator::program_id` with the suffix, and the amended class signals object byte 5 in the header (CLASS_SIGNAL_V4 = 5; the tally counts byte 5 and above), so a block of the 6 October stream (byte 4) never counts towards the flip and a byte-4 node forks alone at it; object 6 is class v5's. The seven gate packs re-exported (devnet epoch 0 and eras 0 to 5): id 1a4230699a6b9c60 (was c120d7963abdcd96, pinned as the must-differ vector in `tests/recheck.rs`), fingerprints Metal = Apple OpenCL 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the v3 control 73bcbfe8ccf988f1 / 90f794dd556f7a3b untouched; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39.
|
||||
|
||||
Evidence: `docs/analysis/ca3-v4-uniform.md` (the model, the census `tools/ca3-v4-uniform`, the chip pricing); F8's logs under `/srv/builds/igneum-wt-attack/target-attack-f8/log/`; the tests limited by the founder's word to what prevents a split and proves the fix: the vectors (the seven packs' ids and fingerprints above), the `igneum-pow` crate suite on igneum-build-1 at 8c728ca3 (`tools/build-remote.sh -- test --release`, rc 0, 77 s, 12:1x UTC: 61 lib + 7 derive + 4 mixer + 19 packs + 2 recheck + 7 scratch = 100 passed, 0 failed, the pinned v2 and v3 packs byte-identical and the v4 must-equal and must-differ ids as pinned), the pairing of the fork's kaspa-pow with this igneum-pow on igneum-build-1 (PAIRING-LINE), and one G1 run on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed 0.3.17 worker sha256 14b6637e..., NVRTC, beside the app's miner, the prover on, the lock held 09:40:22 to 09:41:51Z): self-test PASS on all eight packs and every 2^24 fingerprint equal to the Mac's (the seven above and the control 90f794dd556f7a3b), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms.
|
||||
|
||||
Sub-version 2 (7 October 2026, afternoon; main's ruling B2: 0.3.20 ships sub-version 1 as object byte 5 untouched, and sub-version 2 is object byte 7, built on this branch at 07a809a7): the attack-pass lane's F8 census on sub-version 1 (64 chain-shaped seeds, the window-model control, 2^24 nonces) read 53 of 64 PASS and 11 FAIL at 1.2x, worst p31 at 29.27x, and named three residual classes, all a constant delivered through a writer the one-writer rule admits: saturation or zero preserved through rotl, rotr or a load after a saturated load (p6, p23, p26, p31, p34), zero from mulhi (p45), and the iteration boundary (an `or` at 63 feeding a load at 1, p11); p4, p10 and p25 at 1.28x to 1.57x are the window model's own tail. (An F9 hot-set census read on the same day was withdrawn by its author: its harness drew outside the rule and its metric counted the era's designed windows as hot; F8 is the one re-gate instrument.) Sub-version 2 closes the three: the draw takes a load's source only from a register fresh by dataflow (fresh at the start; a load keeps freshness only from a fresh source; add, sub, xor, mad, shfl from either operand; rotl, rotr from their operand; or, mul, mulhi never), keyed on the class v4 shape on every draw path; rule (a') of the acceptance rule runs that freshness to its fixpoint over the loop (base then shadow block) and rejects a candidate whose load reads an unfresh register in the steady state; rule (c') counts, per load site, the source values equal to 0 or all-ones over the 64 units' 16,384 evaluations and rejects at 164 or more. The devnet epoch-0 seed's attempt 0 is rejected and attempt 1 accepted: id a788661687db4bb3 (c120d7963abdcd96 and 1a4230699a6b9c60 the must-differ pair), fingerprints Metal = Apple OpenCL e370fb2080b7dbb1, b7237555d31fc3cf, b6b167fa15dfe2c9, 28bdf65eff33f2c4, e26d38c46f3f1b16, dd8fdf6ff4f59eed, 8bf40f5cb858d835 (13:01Z), the packs zip sha256 69c36772cd79e44e2ddd589466d9c64a94a13c9e970e9f27bd76feabb9b4581b; the seven 256-block ladder packs of `packs-ca3-shadow` re-exported under the rule (their measured rates stand as the old stream's). Nothing is proposed for sub-version 2 until the attack-pass lane's two gates on 07a809a7 are green (the 64-seed census under 1.2x on every seed, the hot-set census on the chain path); its suite, pairing (after the node lane's re-pin to byte 7) and G1 lines are added below as they land. The static census (`tools/ca3-v4-uniform`, box 2, 13:12Z) over 1,024 chain-shaped seeds plus F8's p1 to p3 at sub-version 2: 0 lossy-sourced load sites of 16,432 (14,329 injecting, 2,103 bijective), 0 programs with an `or`-, `mul`- or `mulhi`-sourced load, the no-era draw path giving the devnet epoch-0 seed the pack's own id a788661687db4bb3 (one stream on every path); the cost of rules (a') and (c'): 1.99 attempts per seed on average against 0.05 before (p2's seed took five), which is 2 ms of generation per rejected attempt on one core, nothing a miner or node notices. The crate suite at 526fa757 on box 2 (`tools/build-remote.sh --box 2 -- test --release`, route line "box 2 for class suite, priority normal", rc 0, 66 s, 13:15Z): 61 lib + 7 derive + 4 mixer + 19 packs + 2 recheck + 7 scratch = 100 passed, 0 failed, the pinned v2 and v3 packs byte-identical and the three v4 ids as pinned (a788661687db4bb3 equal; c120d7963abdcd96 and 1a4230699a6b9c60 differ).
|
||||
|
||||
AP-F8-2 (7 October 2026, 13:xx UTC, the attack-pass lane on sub-version 2 at 07a809a7): chain-shaped seed igneum-f9/331672 exhausted the 32 attempts under rule (a') and the generator panicked, which on the chain is an epoch no node can draw, a liveness halt; the measured (a') plus (c') rejection rate of about two thirds per attempt puts the exhaustion probability at about (2/3)^32, 2e-6 per epoch seed (sub-version 1 exhausted 0 of 10^6). Main's ruling: the draw is total and no consensus path panics. Fixed at 8bdcbdd8 with the stream unchanged (re-export diff 0; the id a788661687db4bb3 and the fingerprints stand, so sub-version 2 keeps its number and the running censuses): the attempt cap of the class v4 shape is 256 (`MAX_ATTEMPTS_V4`; v2 and v3 keep 32), which puts the exhaustion probability under 1e-45 at a worst-case draw of about half a second on one core; after the cap the seed takes the last-resort program, deterministic and accepted as drawn, the candidate at attempt 256 with every `or`, `mul` and `mulhi` of the base program and the shadow block rewritten to `xor`, so every register stays fresh from the init words on and rule (a') holds by construction. The spec text for class v4 therefore reads: attempts 0 to 255 under rules (a), (b), (a'), (c) and (c'), then the last-resort program; the probability of reaching it is (r)^256 for a per-attempt rejection rate r, under 1e-45 at the measured r of about 2/3. Tests: `class_v4_draw_is_total_with_the_last_resort` (the last resort on real (a')-rejected candidates, every load fresh after it, no lossy op left, the chain path over 64 seeds without a panic, the cap per class). The 10^6-seed exhaustion count at the fixed commit is the attack-pass lane's measurement (its re-gate string is 8bdcbdd8); the 4,096-seed census with the attempt histogram (box 2, 13:33Z, `tools/ca3-v4-uniform --n 4096 --f8` at 8bdcbdd8): 4,099 chain-shaped programs, 0 lossy-sourced load sites of 65,584 (57,304 injecting, 8,280 bijective), 0 exhaustions, the accepted attempt geometric with ratio 0.674 (1,338 at attempt 0, 921, 620, 408, 274, 189, 127, 75, 55, 40, 16, 11, 12, 6, 5, then one each at 16 and 17; mean 1.98), so the measured per-attempt rejection rate is r = 0.674 and the exhaustion probability is 0.674^32 = 3e-6 under the old cap and 0.674^256 = 1e-44 under the class v4 cap. The crate suite at 8bdcbdd8 on box 2 (route line "box 2 for class suite, priority normal", rc 0, 80 s, 13:31Z): 62 lib + 7 derive + 4 mixer + 19 packs + 2 recheck + 7 scratch = 101 passed, 0 failed, the total-draw test included. G1 for sub-version 2 on a fleet RTX 5090 (main's order; the fleet lane, p1-5090, driver 580.173.02, sm_120, the box's Linux NVRTC worker `igneum-worker-cuda 1.0 (4 October 2026)` sha256 97e036e2..., which carries no program and compiles each pack's own text; the kit zip sha256 asserted before the put; 13:43:22 to 13:44:07Z): `--bench --batches 5 --batch-log2 24 --block-warps 1` on all eight packs, self-test PASS on every pack with the cache FNV 448274a57f508cbc and every 2^24 fingerprint equal to the Mac's (the control 90f794dd556f7a3b and the seven above); the rates (120 to 142 MH/s beside the box's own miner loop) are a reference only. The Windows G1 on PC 2 (job run-ca3-v4-sub2-g1-pc2-20261007b, published 13:46:33Z under the PC 2 lock, ran 13:46:36 to 13:46:50Z, exit 0; app 0.3.19, the installed worker sha256 14b6637e..., the RTX 5090 switched off by the runner's --cards-off before the script and restored on exit, igneum-worker-cuda running 0 before and after, the prover untouched): self-test PASS on all eight packs with the cache FNV 448274a57f508cbc, every 2^24 fingerprint equal to the Mac's and the fleet's (the control 90f794dd556f7a3b and the seven above), NVRTC 197 to 317 ms per pack, the 1 GiB build 22 to 34 ms, 115 to 130 MH/s with the card alone (a reference, 5 batches).
|
||||
|
||||
AP-F8-2, the exhaustion half, FIXED-AND-PASSED at 8bdcbdd8 on the attack-pass lane's 10^6 chain-shaped seeds through the chain path (14:03:53Z): 0 exhausted, 0 panics, 4 seeds past attempt 31 (three at 32, one at 35; 4e-6, inside (2/3)^32), max attempt 35, no seed at the last resort; r = 0.67, mean 2.0 attempts per seed.
|
||||
|
||||
Sub-version 2's hot-set half did not read green: F8's 64-seed gate at 39 of 64 had 8 over 1.2x of the window model (p23 4.82x, p19 3.32x, p15 2.57x, p18 2.50x, p34 1.25x; p4, p8, p10 unattributed at 1.22x to 1.50x). AP-F8-3 (7 October 2026, 14:0x UTC, the hash lane): the cause of the whole residual is that `accept.rs` never executed the latency-shadow block. Its interpreter (`run_unit`) was written for class v2 and v3 and ran the 64 base instructions per iteration and nothing after instruction 63, while the hash (`verify.rs`, the kernels) runs the shadow 27 times at the end of every iteration; so every dynamic acceptance test (c), (c') judged a class v4 program the chain never hashes. Main's word (14:1x UTC): 0.3.21 ships object byte 5 (sub-version 1); sub-version 3 is 0.3.22's and starts with this fix. Sub-version 3, first commit: `run_unit` executes the shadow block after instruction 63 of every iteration, `reps` times with the iteration's sel, as the hash does; the test `acceptance_executes_the_shadow_block_as_the_verifier_does` pins the acceptance's execution to `verify.rs` on the devnet epoch-0 program and the six test eras (the output bit counts over the 64 units equal, and different with the shadow stripped), so the two paths cannot diverge silently again; `PROGRAM_SUBVERSION_V4` = 3 (a new acceptance verdict is a new stream); the devnet epoch-0 seed still accepts at attempt 1, so its program and fingerprint are sub-version 2's (e370fb2080b7dbb1) under the new id a785001687d8688a (the must-differ set: c120d7963abdcd96, 1a4230699a6b9c60, a788661687db4bb3); the packs zip sha256 4f2445c50c58d76a5544023492d8b858d0b07c5e372d31f9c90c4ce51f829154. The class behind p23, localised from its program and reproduced in the acceptance's own execution: site 7 (instruction 38) reads r6 after 25 `mulhi r6`, 31 `or r6 |= r4`, 35 `xor r6 ^= r4`, which is `r6 & ~r4`, an AND mask the lineage rule counted as fresh because the xor's operand is the or's; over 2^20 evaluations on the closed-form words site 7 reads 874,953 distinct word indices against about 1,046,500 for every other site (0.84 of uniform; 2.2 s on one core), over 2^24 8,979,203 against about 16,260,000 (0.55; 35 s). The second sub-version 3 commit (held, prepared in the worktree) is a per-site distinct-index ratio against the uniform expectation of the site's window, its threshold set from the clean seeds' spread and its sample size from the cost line above; the dynamic bounds as first specified (a most-repeated-value bound at 16,384 and a distinct floor at 2^19.5 over 2^20) do not reach p23 and are not committed. The crate suite at ddacfbd3 on box 2 (route "box 2 for class suite, priority normal", rc 0, 41 s, 14:20Z): 63 lib + 7 derive + 4 mixer + 19 packs + 2 recheck + 7 scratch = 102 passed, 0 failed, the agreement test included. F8's final 64-seed table on sub-version 2 (the attack-pass lane, 14:2x UTC): 9 over 1.2x (p23 4.82x, p19 3.32x, p15 2.57x, p18 2.50x, p56 2.01x, p10 1.50x, p8 1.38x, p34 1.25x, p4 1.22x), the 55 clean seeds at 0.9915x to 1.144x; the 256-item bucket entropy over the window separates the strong four only (0.637 to 0.974 against a clean minimum of 0.9865 over 848 site rows), so the threshold of the second commit's distinct-index ratio comes from a run of that ratio on the 55 clean seeds at 2^20. The static census at ddacfbd3 (box 2, 14:22Z, 4,096 chain-shaped seeds plus F8's p1 to p3): 4,099 programs, 0 lossy-sourced load sites of 65,584, 0 exhaustions, the accepted attempt geometric as before (1,328 at attempt 0, 917, 622, 409, 284, ... one each at 16 and 17; mean 1.998, max 17), so the shadow-executed verdicts move a handful of seeds' attempts and nothing else; the devnet epoch-0 seed at attempt 1, id a785001687d8688a.
|
||||
|
||||
Sub-version 3, second commit (7 October 2026, 14:44 UTC, the hash lane; the sub-version number stays 3 and the stream is unchanged: re-export diff 0 on the eight packs, the id a785001687d8688a, the seven fingerprints and the zip sha256 stand), two rules. The shared-operand rule, in the draw's source rule and in the acceptance's (a') pass: or-then-xor or or-then-sub on one operand is `d & ~s`, xor-then-or is `d | s`, so the second write leaves the register lossy although either op alone injects; any write to either register clears the relation. On p23 the chain's attempt 1 (id d65122675f16a1c7) now draws site 7 (instruction 38) from r5 and passes; the devnet epoch-0 seed still draws attempt 1, the same program. Rule (c''), the distinct-index ratio: over 4,096 units (2^20 evaluations per site, the closed-form words, the shadow executed) every load site's count of distinct word indices against the uniform expectation on its window (N - N^2 / 2W, the window 2^28 >> min(win, 2)) must reach 0.98 (`MIN_DISTINCT_RATIO_V4`), the last test of the chosen candidate; a candidate under it is rejected and the next attempt drawn under the 256 cap and the last resort. The floor from the 64-seed run at 2^20 (box 2): the 55 clean seeds' minimum over their site rows 0.9960 (p1 0.9990, median 1.0000); the strong five p23 0.8361, p18 0.9274, p19 0.9335, p15 0.9432, p56 0.9654; 0.98 sits 0.015 from each side. The chain's own candidates it refuses (the test `class_v4_distinct_ratio_rejects_the_low_entropy_band`, box 2, 2.1 to 2.2 s each): p15 attempt 3 id 52638ea2e8b0fd68 site 2 at 0.943, p18 attempt 2 id 9a37e9489d8ba698 site 6 at 0.927, p19 attempt 0 id 79d7441de0689223 site 15 at 0.933, p56 attempt 2 id 486a8ad2701ec3b5 site 2 at 0.965; p23's attempt 1 with site 7 put back to r6 is refused by (a') (`UnfreshLoadSource`) and, run anyway, by the ratio at 0.836 (874,928 distinct of 1,048,576). Main's rule for a staged 2^24 pass (taken only if 2^24 separates the weak four from the clean seeds by at least the 2^20 gap) was decided by the 2^24 lines (box 2, 35 s per seed on one core): the weak four p34 0.9181, p4 0.9614, p8 0.9630, p10 0.9612; the clean seeds p44 0.9612, p52 0.9613, p3 0.9971, p2 and p5 1.0004; p23's attempt 1 1.0004. Two clean seeds sit on the weak four's value, so a 2^24 floor that reaches the weak four rejects clean seeds, and the 0.961 that recurs on both sides is a band the ratio reads at 2^24 that F8's hot-set gate did not flag on p44 or p52. Committed: the ratio at 0.98 over 2^20 alone (`ACCEPT_UNITS_DISTINCT_V4` = 4096), no 2^24 stage. Open tail: p4, p8, p10 and p34 (1.22x to 1.50x on F8's gate) read 0.9927 to 0.9963 at 2^20, inside the clean spread; unattributed and chased. The (B) most-repeated-value bound stays in the file unwired (`MAX_SOURCE_REPEAT_V4`, `most_repeated`). Cost: the chosen candidate's acceptance gains one 2^20 pass, 2.1 to 2.2 s on one box-2 core, once per epoch draw per node.
|
||||
|
||||
The second sub-version 3 commit is 017e70376489251e18564c0abce7e466e606c8b3 (pushed 15:10 UTC's preceding hour, pre-push gate GREEN, CI run 37639406567 success). The crate suite at 017e7037 on box 2 (rc 0, 184 s): 64 lib + 7 derive + 4 mixer + 19 packs + 2 recheck + 7 scratch = 103 passed, 0 failed, 3 diagnostics ignored; the lib tests took 140.8 s against ddacfbd3's 41 s for the whole suite, because every class v4 draw in the tests now pays the 2^20 pass on its chosen candidate (2.2 s each); that is CI time, not node time. The static census at 017e7037 (box 2, 15:1x UTC, 4,096 chain-shaped seeds plus F8's p1 to p3, the draws in parallel over the box's cores since the ratio pass makes the serial run a four-hour job): 4,099 programs, 0 lossy-sourced load sites of 65,584 (57,322 inject, 8,262 bijective), 0 exhaustions; the accepted attempt 1,297 at attempt 0, 899, 609, 416, 298, 197, 125, 92, 54, 46, 21, 14, 13, 9, 6, 0, 2, 1 (mean 2.086, max 17) against ddacfbd3's 1,328, 917, 622, 409, 284, ... (mean 1.998, max 17): the ratio refuses about 4 percent of the candidates that pass every other test, one more attempt on about one seed in twelve; the devnet epoch-0 seed at attempt 1, id a785001687d8688a; F8's p2 at attempt 5, p3 at attempt 1. The attack-pass lane's class check of ddacfbd3's shadow-executed verdicts against 8bdcbdd8 (598,678 chain-shaped seeds): 11,990 (2.0 percent) accept at a different attempt, 0 exhausted, max attempt 32; on 017e7037 the pairing holds (the devnet epoch-0 program draws as a785001687d8688a) and its 64-seed gate at 2^24 and 10^6 exhaustion count were running at 15:1x UTC (finish about 16:05 UTC).
|
||||
|
||||
F8's 64-seed gate on 017e7037 (the attack-pass lane, box 2, last seed 16:00:20 UTC): 60 of 64 under 1.2x; the four over are the named tail and nothing else (p10 1.5036x, p8 1.3776x, p34 1.2505x, p4 1.2167x; hottest items 355 to 541 reads of 2^31, unattributed, inside the ratio's clean spread); p23, p19, p15, p18 and p56 under the line; the clean spread 0.9915x to 1.144x. Exhaustion on 017e7037: 0 in the attack-pass lane's 20,532 chain-shaped seeds (max attempt 29) plus this lane's 4,099 (max 17); the 10^6 count continues as a strengthening line. Cost line for the node: the chain's epoch draw now pays the 2^20 ratio pass on every candidate that reaches it (the accepted one, and the about 4 percent that fail there), 2.2 s per pass on one box-2 core, so about 2.3 s per epoch draw on that core and, by the attack-pass lane's reading, about 4 to 5 s per epoch per node on slower cores; the earlier rejections cost milliseconds. From the attack-pass lane sub-version 3 at 017e7037 reads green on both gates with the named tail; its close line went to the plan, main and the Counter ASIC lane. This row stays open on the tail (p4, p8, p10, p34) until it is attributed or ruled accepted.
|
||||
|
||||
Owed (recorded, not run, by the founder's word): G2 (the CPU verifier on 1,024 hashes per card) on the amended stream; G3 (the Metal fuzz, edge, stats and determinism runs) on the amended stream; the hash-rate ladder re-measure on the M5 Max and the RTX 5090 (the amendment changes the base program's source draws, not the op mix or the load count, so the latency-bound rows of `docs/analysis/latency-shadow-2026-10-06.md` are expected to hold within their spread; unmeasured); AMD (the RX 9070 XT, PC 1); the 2019-class verifier core (O-1.14); F8's phase E (the 64-seed dynamic census) on the amended stream, which is the attack-pass lane's and the test of the per-op table. The row reads FIXED-AND-PASSED only after phase E passes against the amended class.
|
||||
|
||||
## Genesis forward-compatibility entries (7 October 2026, mission item 8, branch `genesis-forward`)
|
||||
|
||||
The three genesis fields of `docs/analysis/mission/mission.md` section 2.8, built on the node fork branch `genesis-forward` (from release-0.3.19-node dc141409) and the repo branch `genesis-forward`; the design and the gates in `docs/design/genesis-forward.md`. Every switch is never on the devnet (its digest c562d70e... does not move); the testnet genesis sets all three (the testnet lane re-pins and re-digests).
|
||||
|
|
|
|||
198
docs/ledger-public.md
Normal file
198
docs/ledger-public.md
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
# Igneum criticism ledger, public shape
|
||||
|
||||
Generated by `tools/ledger/export-public.mjs` from `docs/fud-ledger.md`; a gate check fails when the two drift. One row per item: the claim or criticism, its status, what was done, and the evidence. Internal identifiers, times of day and team-member names are left out on purpose; the full ledger is published with the repository.
|
||||
|
||||
190 items. By status: Conceded, stated 50; Fixed 30; Decided 22; Fixed on a branch, pending merge 14; Answered by design 6; Fixed, stated 6; Open, counsel engaged 4; Answered with evidence 4; Closed by rule 3; Answered by design, with a correction to our own text 1; Answered with evidence, stated 1; Answered by design for finality, Conceded for the lottery 1; Conceded, implemented 1; Rule implemented and measured; launch month simulated 1; Answered by design, with the concession stated 1; Conceded, stated in the litepaper and the design doc 1; Answered with evidence at 1 block/s 1; Conceded, stated in the simulation report 1; Answered by design, with the dependency conceded. Update 7… 1; Conceded, stated in the litepaper, with the dial explained 1; Open, blocked on phase 2 1; Closed by spec 1; Conceded by decision, stated in the design doc 1; Answered by design, with the founder's edge conceded 1; Answered by design, with a metrics caveat 1; Closed by removal, 3 October 2026 1; Conceded, stated in the litepaper 1; Conceded, stated in the design doc 1; Measured on the live node line, and the overlay does NOT… 1; Conceded, stated in the simulation 1; Conceded in part, labelled, stated 1; Fixed in the node 1; Answered with evidence for the largest body the rules allow 1; Spec fixed 1; Fixed in the proving code 1; Fixed in the spec 1; Rule fixed 1; Rule written 1; Fixed, logged 1; Answered with evidence for the test half 1; Fixed in the node and shipped, rule not yet activated on… 1; Simulation half run 1; Answered with evidence for all four 1; Open, blocked on the public testnet 1; Written 1; Designed 1; Fixed and confirmed 1; Open, blocked on the phase 2 consensus proof 1; Rolled out 1; Conceded, no experiment possible 1; Conceded by decision 1; Conceded, scheduled 1; Conceded, contained by rule, reviewed 1; Fixed on a branch and verified locally 1; Answered with evidence and stated 1; Answered with evidence for PC 2 1; Answered by design and with evidence 1; Fixed on a branch, pending the 0.3.20 node ship 1; Fixed as a genesis lever, measurement owed 1; Conceded, flagged in spec 04 section 4.8 1.
|
||||
|
||||
| Id | Claim or criticism | Status | What was done | Evidence |
|
||||
|---|---|---|---|---|
|
||||
| M1 | The program space is tiny | Decided | No standing bounty. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M2 | Your own prototype is not memory-hard | Conceded, stated | `Site/litepaper.html`, Monero's idea section, the "Measured so far" paragraph, "computing items on the fly runs 4.8x slower than loading them"; What Igneum does not claim, "A memory-hard prototype on every vendor". | [proto-metal/TESTS.md](../proto-metal/TESTS.md) |
|
||||
| M3 | Kaspa said ASIC resistant too | Answered by design, with a correction to our own text | First the correction: Kaspa did not promise ASIC resistance. kHeavyHash was designed to be friendly to specialised and optical hardware, and the Kaspa community expected chips (approximate, from memory; cite the Kaspa… | design doc, "ASIC resistance" section. |
|
||||
| M4 | ProgPoW already did this and you do not mention it | Conceded, stated | `Site/litepaper.html`, precedents table row 1, "ProgPoW, as KAWPOW on Ravencoin since 2020". | [vendor/](../vendor/) |
|
||||
| M5 | Your load count varies 6x between programs | Fixed | Generator version 2 draws exactly 16 load slots per program (spec 01 section 1.4.2, `igneum-pow/src/generator.rs`), and the fresh-source rule of 1.4.3 with the acceptance rule of 1.4.6 fixes the distinct count too,… | [proto-metal/TESTS.md](../proto-metal/TESTS.md) |
|
||||
| M6 | Weak programs | Fixed | The acceptance rule of spec 01 section 1.4.6 (`igneum-pow/src/accept.rs`, mirrored in `proto-metal/main.swift`) rejects a candidate with a stale load source, a register without an injecting write, a nonce-independent… | [proto-metal/TESTS.md](../proto-metal/TESTS.md) |
|
||||
| M7 | No cryptographic analysis at all | Conceded, stated | `Site/litepaper.html`, Mining section, "The hash is a lottery, not a general-purpose cryptographic hash" and "Open: no analysis of the lottery properties exists yet". | [proto-metal/TESTS.md](../proto-metal/TESTS.md) |
|
||||
| M8 | Only two vendors, two programs, one day | Decided | A discrete AMD card (9070 XT) and a 12 GB NVIDIA card (4070) are on order for PC 2; the measurement runs on arrival. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M9 | The 10 ms CPU verification gate is unmeasured | Conceded, stated | `Site/litepaper.html`, Mining section, "Measured: 0.41 to 0.58 ms per warp on one Apple M5 Max core with the 256 MB cache"; vs RandomX "Light verification" row. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M10 | "Bound by memory bandwidth" is wrong | Answered with evidence, stated | `Site/litepaper.html`, Mining section, "bound by random memory access. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M11 | Hourly JIT on real rigs | Decided | The mixed-generation rig is borrowed from a farm operator later, at the HiveOS package's first test; the 9070 XT on order gives the ROCm half on PC 2. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M12 | Rentable hashrate is not just NiceHash | Answered by design for finality, Conceded for the lottery | Both halves true. | [sim/results.md](../sim/results.md) |
|
||||
| M13 | Macs mine too is marketing | Conceded, stated | `Site/litepaper.html`, For miners, Hardware, "Macs mine too, at about a fifth of a flagship card: Measured, 26.7 against 123 million hashes a second" (confirmed by grep tonight; the projected-earnings half is not… | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M32 | "Automatic anti-ASIC escalators" overstates what the era draw and the instruction reserve do | Conceded, stated | The era draw and the instruction reserve are automatic schedule changes against fixed datapaths and against human forks; against the stored-dataset chip every drawn parameter is firmware, and the defence against that… | [docs/analysis/horizon/algorithm.md](../docs/analysis/horizon/algorithm.md) |
|
||||
| M33 | The FPGA ceiling rests on a tFAW the JEDEC HBM2 table does not give | Conceded, stated | The public FPGA line carries only the measured row, 2.4 G reads/s per card and 0.30x to 0.39x of the RTX 5090 per watt (Shuhai, FCCM 2020 Fig 7; the tFAW arithmetic from ICCAD 2021 Table I), and the 11.4 G bank-bound… | [docs/analysis/horizon/algorithm.md](../docs/analysis/horizon/algorithm.md) |
|
||||
| M34 | The shadow size N is a constant of the binary, so the one lever against the dataset-storing chip needs a fork to move | Conceded, implemented | N is a genesis ladder of six rungs (27, 35, 53, 88, 173, 267 passes; about 102,100 to 1,001,600 counted ops) with a measured admissibility flag per rung (cold verify under 10 ms on the reference core with its SMT… | [docs/design/latency-ladder.md](../docs/design/latency-ladder.md) |
|
||||
| F1 | Finality is attackable for the first month | Rule implemented and measured; launch month simulated | The harness text only: `tools/finality-attacks/run.mjs` names the 2/3-of-total floor in the s6 comments and criterion and in the s5 result line, where it still said 56.7%; the scenario logic is untouched. | [sim/](../sim/) |
|
||||
| F2 | The two-hour presence window is an eclipse vector | Closed by rule | Correct that the presence window trades safety for liveness. | [sim/results.md](../sim/results.md) |
|
||||
| F3 | Participation grinding through the bitmap | Decided | The per-block vote bound and the bitmap wire bound of spec 3.4.2 items 2 and 3 are adopted for gate 3; the spec moves them from Proposed to Decided at the next spec edit. | design doc Finality v2, Quorum item 2 and Checkpoints item 3. |
|
||||
| F4 | It is proof of stake with extra steps | Answered by design, with the concession stated | The committee's weight is blocks mined in the last 30 days. | [sim/results.md](../sim/results.md) |
|
||||
| F5 | The headline arithmetic is misread on purpose | Conceded, stated | `Site/litepaper.html`, Finality, "an attacker producing every block on the chain, with honest miners gone" and "An attacker matching the honest network needs twenty days for a third and never reaches two thirds"; the… | [sim/results.md](../sim/results.md) |
|
||||
| F6 | Equivocation costs nothing that matters | Conceded, stated in the litepaper and the design doc | True. | design doc Finality v2, Checkpoints item 4 and Residual risks bullet 1. |
|
||||
| F7 | A 2-minute checkpoint on a DAG with a 1-hour merge bound | Answered with evidence at 1 block/s | Fair. | design doc Finality v2, Checkpoints item 1 and "Three experiments before gate 3". |
|
||||
| F8 | The simulation has no network in it | Conceded, stated in the simulation report | Correct. | [sim/results.md](../sim/results.md) |
|
||||
| F9 | Half the hashrate leaves and finality stalls for ten days | Answered by design | That table is the all-keys denominator, which the simulation recommended for safety. | [sim/results.md](../sim/results.md) |
|
||||
| F10 | Pools hold the votes | Conceded, stated | `Site/litepaper.html`, Finality, "Pools carry their hashers' votes, so vote concentration equals pool concentration, and it is public"; Governance, "governed by the hashrate that powers it". | design doc Finality v2, Residual risks bullet 3. |
|
||||
| F11 | VDFs are exotic | Answered by design, with the dependency conceded. Update 7… | The era VDF is in the node (spec 4.4 Implemented, behind `era_vdf_activation_daa`, never until the founder sets it per network), on a fixed-width integer with no C library, with the hash-chain fallback behind the… | design doc Finality v2, Lottery seeds items 1 and 2, Residual risks bullet 5, "Three experiments before gate 3". |
|
||||
| F12 | Nothing outside the chain, except | Answered by design | Those are code dependencies, chosen because each is open source and replaceable, and none is another chain's consensus. | CLAUDE.md design paragraph; design doc "Decided" paragraph. |
|
||||
| F13 | Why prove every block if every node executes anyway | Answered by design | Full nodes execute natively so users see state in about a second. | design doc, "Proving speed on consumer GPUs" risk item and "Who needs" paragraph. |
|
||||
| F26 | "No stake" needs its one sentence: what is at stake, and what strips it | Conceded, stated | `Site/litepaper.html`, the finality section's "What is not here" paragraph and the "Igneum at a glance" Finality row carry the sentence verbatim: "No coin is staked. | [docs/analysis/horizon/frontier.md](../docs/analysis/horizon/frontier.md) |
|
||||
| P1 | The 20-second shard is a number you made up | Conceded, stated | `Site/litepaper.html`, Proving, The proving budget, "Target: shard size will be set so a 12 GB card proves one shard in about 20 seconds. | [site/journey.json](../site/journey.json) |
|
||||
| P2 | Real-time proving needs a hundred GPUs per block | Conceded, stated in the litepaper, with the dial explained | True, and the litepaper says a full block needs a cluster of 100 to 200 consumer GPUs, approximate. | design doc "Unit economics of a proof"; litepaper "What Igneum does not claim" item 1. |
|
||||
| P3 | A phone verifies in milliseconds is a SNARK-wrapper claim | Open, blocked on phase 2 | Next measurement the phase 2 benchmark, design R4 (Nov 2026 to Jan 2027 per the litepaper roadmap), a wrapped segment proof timed on a 12 GB and a 24 GB card and verified on a phone. | not yet. |
|
||||
| P4 | Trustless light clients need a consensus proof you do not have | Conceded, stated | `Site/litepaper.html`, precedents table row 6, "The consensus proof that makes the checkpoint self-verifying is phase two"; Building item 2, "Light clients". | design doc, hostile review table rows "Slashing an external prover" and "One-proof light clients". |
|
||||
| P5 | EVM "unchanged" on a DAG is false | Closed by spec | Correct. | design doc, hostile review table row "EVM semantics on a DAG". |
|
||||
| P6 | The proving market is tiny | Conceded, stated | `Site/litepaper.html`, The problem, "a supplier whose marginal cost is close to power"; "cheapest supplier" and "lowest cost" absent from the page (grep, tonight). | design doc "Market size, honestly" and "Existing prover networks" table (labelled from memory). |
|
||||
| P7 | A soundness bug in SP1 is a consensus failure | Conceded, stated | `Site/litepaper.html`, Abstract, "Writing new code, including an emergency fix to the proof system, is the one thing that takes a person"; Proving, "no node accepts a block with a wrong state root". | design doc "Proof system churn" risk item. |
|
||||
| P8 | Fastest prover wins all the shards | Closed by rule | Fair, and the lottery/proving separation does not by itself fix it. | design doc "Proving speed on consumer GPUs" risk item and Finality v2 "Fees". |
|
||||
| P9 | Shard griefing | Decided | The parameter table's values are the phase 4 devnet's starting values (8 assignees, a 25-s exclusive window, a 120-s job claim timeout, no shard bond, the external job bond set on the devnet); the devnet measurement… | design doc, Security model table row 3. |
|
||||
| P10 | External jobs are paid off-chain, so where is the burn | Conceded, stated | `Site/litepaper.html`, Economics, "Outside customers pay in their own currency on their own chain at launch; settlement in IGN with a 10% burn follows when the proof bridge lets Igneum see the payment"; the route table… | design doc "The first six months" risk item and hostile review table row "Slashing an external prover". |
|
||||
| P24 | "20 percent of emission to provers" without the caveat that consensus does not verify the proof | Conceded, stated | `Site/litepaper.html`, Economics, the 20% proving-pool row carries the caveat: consensus does not yet verify the carried proof, it checks the record's statement against native execution and its signature, so today a… | [docs/analysis/horizon/consensus-security.md](../docs/analysis/horizon/consensus-security.md) |
|
||||
| P25 | Unclaimed pool credit is stranded in the escrow | Conceded, stated | `Site/litepaper.html`, Economics, the 20% proving-pool row carries the note: unclaimed pool credit is today stranded in the escrow, no rule returns it; the fix rolls an unproven shard's credit into the next proven… | [docs/analysis/horizon/economy-and-utility.md](../docs/analysis/horizon/economy-and-utility.md) |
|
||||
| E1 | Hard cap plus burn is a security budget cliff | Conceded by decision, stated in the design doc | True, and the design doc records the choice: "A 1% tail is the Monero model and the safer choice for security on its own." The argument for the cap is that Igneum miners keep earning from in-chain proving fees and… | design doc "Decision: hard cap". |
|
||||
| E2 | Half the coins in two years is an insider schedule | Answered by design, with the founder's edge conceded | The schedule (1 billion a year halving every two years, 30-day ramp from 10% to 100%) is public, fixed at genesis and the same for every miner. | litepaper "Supply" and "Fair launch, announced". |
|
||||
| E3 | The 20% developer share enables wash gas | Answered by design, with a metrics caveat | The base fee is burned in full, so every wash transaction loses its whole base fee. | design doc Finality v2 "Fees"; litepaper "What a builder gets for being early". |
|
||||
| E4 | 5% of gas to the dev fund is a tax | Closed by removal, 3 October 2026 | There is no development fund. | spec section 5.5; design doc "No development fund, so nothing to fight over". |
|
||||
| E5 | "Not one coin to a founder" is false | Conceded, stated | `Site/litepaper.html`, Economics, "No fund, no foundation, no fee to the team", "1 block in 100 pays the project"; `site/index.html`, Economics, "The one payment to the project is the Ember software's optional 1% dev… | design doc "No development fund, so nothing to fight over". |
|
||||
| E6 | Two-year halvings bleed hashrate | Conceded, stated | `Site/litepaper.html`, Economics, Security after the subsidy, "The schedule is a bet, not a measurement: a halving halves emission income overnight if price and fees do nothing", with Kaspa's reduction marked… | none; decision in design doc "Supply". |
|
||||
| E7 | No stablecoin liquidity without a trusted bridge | Decided | Correct. | design doc, hostile review table row "One-proof light clients and committee-free bridges". |
|
||||
| E8 | Founders seeding the DEX is market making by insiders | Conceded, stated | True and stated in the litepaper. | litepaper "Liquidity from the people who are there". |
|
||||
| E19 | "Proving: a second income" without the arithmetic of how small it is | Conceded, stated | `Site/litepaper.html`, "For miners", under the three-streams table: all of Ethereum L1's proving is about USD 36 a day at the September 2026 tracker cost (USD 0.005 a block x 7,200 blocks; the tracker figure is a… | [docs/analysis/horizon/frontier.md](../docs/analysis/horizon/frontier.md) |
|
||||
| E20 | "Proofs at the cost of power" is the electricity, not the price | Conceded, stated | `Site/litepaper.html`, The problem ("a supplier whose electricity cost is close to power and whose price is the subsidy it forgoes, which falls as the network's hash grows"), Building on Igneum ("Proofs priced by the… | [docs/analysis/horizon/economy-and-utility.md](../docs/analysis/horizon/economy-and-utility.md) |
|
||||
| E21 | The dev fee is 1 percent of the producer share, and the funding plan's ceiling took all rewards | Conceded, stated | `Site/litepaper.html`, the payment-routes row 6 and the Ember section read "default-on, switchable, 1 percent of the producer share"; `docs/plans/funding.md` section 4's ceiling is 1 percent of the producer share, USD… | [docs/analysis/horizon/economy-and-utility.md](../docs/analysis/horizon/economy-and-utility.md) |
|
||||
| G1 | No cryptography team | Conceded, stated | `Site/litepaper.html`, Questions miners ask, "reviewers will be named and paid before gate 3"; What Igneum does not claim, "A cryptography team. | design doc "Team" paragraph. |
|
||||
| G2 | An AI designed this | Conceded, stated | `Site/litepaper.html`, cover, "Method one founder with AI systems"; Who are you?, "One founder, pseudonymous, working with AI systems". | [.claude/agents/](../.claude/agents/) |
|
||||
| G3 | Who are you | Decided | No team page for now; the litepaper says the team is pseudonymous and names no team page. | [site/journey.json](../site/journey.json) |
|
||||
| G4 | No admin keys, except in everything that matters | Conceded, stated | The home page was redrawn as one statement, the live scene, three facts and the downloads, so the tile "admin keys in consensus" is no longer on `site/index.html`; the sentence stands on `site/litepaper.html`,… | litepaper "Governance". |
|
||||
| G5 | No multi-client | Conceded, stated in the litepaper | True at launch. | litepaper "Governance", last bullet. |
|
||||
| G6 | Stratum v2 does not make pools unable to censor | Conceded, stated | `Site/litepaper.html`, Governance, "Pools can be bypassed on transaction choice". | none in repository. |
|
||||
| G7 | The one-click app is an update key over the network | Decided | Correct. | not yet. |
|
||||
| G8 | Governance by hashrate is governance by two pools | Conceded, stated in the design doc | True in the same way it is true on Bitcoin, where miner signalling activated SegWit and Taproot. | design doc Finality v2, Residual risks bullet 3. |
|
||||
| G15 | Three signalling thresholds, four numbers across the documents | Conceded, stated | One sentence in `site/litepaper.html`, Governance ("Miners set what genesis leaves open") and Mining ("Miners hold the switch"): miners signal three things at three thresholds, 60 percent of blue blocks over two weeks… | [docs/analysis/horizon/economy-and-utility.md](../docs/analysis/horizon/economy-and-utility.md) |
|
||||
| C1 | vs Monero: GPUs were excluded on purpose | Answered by design | Monero chose the CPU for egalitarian reasons and accepted botnets as the price. | litepaper "For miners", hardware paragraph. |
|
||||
| C2 | vs Monero: "no chip in seven years" is not proof | Conceded, stated | The home page no longer carries the RandomX paragraph; "since 2019 (approximate)" and "precedent, not proof" stand on `site/litepaper.html` (vs RandomX, Mining). | none. |
|
||||
| C3 | vs Kaspa: you misrepresent them | Conceded, stated | `Site/litepaper.html`, The problem, "Chips arrived, as on Kaspa, whose hash was designed to welcome them"; Speed, "Kaspa has run in production since 2021 (approximate), forked from rusty-kaspa"; precedents row 5,… | none in repository; `vendor/rusty-kaspa` to be cloned and cited. |
|
||||
| C4 | vs Kaspa: a finality overlay changes GHOSTDAG's guarantees | Measured on the live node line, and the overlay does NOT… | A NEW SERIOUS FINDING (5 October 2026 sweep; owner: cryptographer and consensus engineer, decision owner the founder). | [sim/results.md](../sim/results.md) |
|
||||
| C5 | vs Ethereum: you compare inclusion to finality | Conceded, stated | `Site/litepaper.html`, Speed, "Inclusion is not confirmation on either chain". | litepaper "Speed". |
|
||||
| C6 | vs Ethereum: every one of your components is a research project | Conceded, stated | `Site/litepaper.html`, Roadmap, "the combination is the risk the gates price" and "Dates slip. | litepaper "Roadmap". |
|
||||
| C7 | vs Bitcoin: hashrate that follows price is the design, you penalise it | Conceded, stated in the simulation | Correct. | [sim/results.md](../sim/results.md) |
|
||||
| C8 | vs Ergo, Ravencoin, Conflux: GPU mining has a home | Conceded, stated | `Site/litepaper.html`, The problem, "Ergo, Ravencoin and Conflux still mine on GPUs at a fraction of the 2022 fleet (approximate)"; precedents row 3 names Conflux. | none in repository; to be cited from their repositories. |
|
||||
| C9 | vs Aleo: you will centralise the same way | Closed by rule | See P8. | design doc "Existing prover networks" table, Aleo row. |
|
||||
| C10 | vs Boundless and Succinct: you cannot bid there without their tokens | Conceded, stated | `Site/litepaper.html`, Proving for everyone else, "Boundless provers post ZKC and Succinct provers stake PROVE (approximate, from their documentation)". | design doc "Existing prover networks" table, labelled approximate. |
|
||||
| C11 | vs everyone: "firsts" that are not | Conceded, stated | `Site/litepaper.html`, precedents table, "We know of no chain that combines them"; Building, "that we know no other EVM chain offers". | this ledger. |
|
||||
| C12 | vs Monero: you borrowed the hash idea and left out the point | Answered by design | Transactions on Igneum are public, as on Ethereum. | CLAUDE.md rules (privacy rejected). |
|
||||
| L1 | It is a security under Howey | Open, counsel engaged | There is no sale, no premine, no allocation and no promise of return, and nothing in consensus is controlled by the team and no protocol fee reaches it (the development fund was removed on 3 October 2026), which is the… | design doc "Legal" paragraph. |
|
||||
| L2 | Financial promotion rules | Open, counsel engaged | ; the text half is stated below. | none. |
|
||||
| L3 | GoDaddy domains are a seizure risk | Decided | The nameserver move to deSEC in one sitting with every domain's Vercel verification checked afterwards; a non-US registrar in December 2026 when the transfer lock ends. | CLAUDE.md "Domains". |
|
||||
| L4 | Paying testnet miners real money is a payment before launch | Open, counsel engaged | Correct that it needs an entity, terms and tax treatment before it happens. | design doc "The first six months". |
|
||||
| L5 | Trademark | Open, counsel engaged | The clearance search is recorded in the repository as a dated one-line result per register when it returns. | none. |
|
||||
| L6 | A permissionless job market paid in dollars is money transmission | Answered by design | At launch jobs are paid on the customer's chain, in the customer's asset, by the customer's contract, to the prover's address; Igneum operates no custody and takes no cut off-chain. | design doc "The first six months". |
|
||||
| X1 | "Reproducible from the repository" and the repository is private | Conceded, stated | `Site/litepaper.html`, vs RandomX "Track record" row, "The specification, reference hash, test vectors and simulators are public now (github.com/igneum-network/spec). | [site/index.html](../site/index.html) |
|
||||
| X2 | "Get the miner" with no miner | Conceded, stated | `Site/index.html`, hero button "See the miner"; the Mine section's download buttons carry the shipped devnet build's version and size (v0.3.9) beside "Public testnet: not yet open; the devnet build is here for people… | [site/index.html](../site/index.html) |
|
||||
| X3 | "Proven by fire" when nothing has run | Conceded in part, labelled, stated | The proofs feed moved to the litepaper's proving section with the home-page redesign and reads "Live rows arrive with the public testnet. | [site/index.html](../site/index.html) |
|
||||
| X4 | Thirteen months with one founder | Conceded, stated | The roadmap is aggressive and every phase is a gate that can repeat or stop the project, which the litepaper says. | litepaper "Roadmap"; design doc "Team". |
|
||||
| X5 | 1,000 independent miners is a Sybil number | Decided | The independence definition as written, with the silent-fleet addition (a key with no fingerprint counts as its own class only when its address is in an autonomous system no other key uses); the observer columns on… | [site/journey.json](../site/journey.json) |
|
||||
| X6 | The one-click app is a honeypot vector | Decided | Correct on all three. | not yet. |
|
||||
| X7 | No community exists | Conceded, stated | This ledger's submission line names hello@igneum.network and the spec issues route; `site/litepaper.html` last paragraph and the footer on every page carry both. | [site/index.html](../site/index.html) |
|
||||
| X8 | Exchange listings as a roadmap item | Conceded, stated | The home page's journey is no longer shown (the inlined feed remains in the page source); the sentence "No listing is arranged, promised or sought by the project" stands on `site/litepaper.html` Roadmap phase 6 and in… | [site/journey.json](../site/journey.json) |
|
||||
| X9 | Launch hashrate will be trivial | Conceded, stated | `Site/litepaper.html`, Finality, "In the chain's first 30 days no checkpoint locks at all"; Fair launch, "The first 30 days of mainnet run on proof of work alone". | [sim/results.md](../sim/results.md) |
|
||||
| X10 | Five milestones in one day | Conceded, stated | `Site/index.html`, journey section, "The log below is the engineering log's dated entries, newest first. | [site/journey.json](../site/journey.json) |
|
||||
| M14 | A pulsed rental against the block-count DAA buys weight at a discount | Answered with evidence | , ledger close round 1: M14 and F14 the 50x pulse against a lagging retarget inside the finality simulator, both W2 forms"). | [sim/difficulty/devnet-2026-10-03.csv](../sim/difficulty/devnet-2026-10-03.csv) |
|
||||
| M15 | A header with any past timestamp or any claimed DAA score makes the node build a 256 MiB cache | Fixed | Correct. | [docs/fork-divergence.md](../docs/fork-divergence.md) |
|
||||
| M16 | The 256 MiB cache fits on a die, so the recompute attacker is compute bound | Answered with evidence | On the 5090 the recompute attacker with the cache inside the 96 MiB L2 (the SRAM emulation, 64 and 32 MiB masks, bit-exact against the stored construction) runs at 33.9 Mhash/s against 132.2 honest for the same… | [proto-metal/MEMHARD.md](../proto-metal/MEMHARD.md) |
|
||||
| M17 | Every ahead-of-time miner stops at the epoch boundary; whoever compiles in process mines alone | Fixed | And measured on the live devnet at the DAA 3,600 boundary (`docs/bench-log.md`, "first hourly program swap"): prepare sent 449 DAA before the boundary; Metal compiled in 82 ms, CUDA ran nvcc in the background in 1,285… | [proto-cuda/windows-miner/start-mining.ps1](../proto-cuda/windows-miner/start-mining.ps1) |
|
||||
| M18 | The per-hash random data path is a one-bit select | Conceded, stated | `Site/litepaper.html`, Mining table "Every hash" row, "The one-bit select inside the maths costs a chip nothing and is not a defence"; vs RandomX "Random program" row, "the 128 dataset addresses change with the nonce". | [site/litepaper.html](../site/litepaper.html) |
|
||||
| M19 | The census that justifies the generator rule has blank cells, and the spec still carries the free load count | Fixed | Correct. | [docs/analysis/weak-program-census-2026-10-03.md](../docs/analysis/weak-program-census-2026-10-03.md) |
|
||||
| M20 | Pruning proofs are checked with the kHeavyHash stub | Fixed in the node | Correct. | [docs/fork-divergence.md](../docs/fork-divergence.md) |
|
||||
| M21 | GHOSTDAG k is Kaspa's table value for Kaspa-sized bodies | Answered with evidence for the largest body the rules allow | , ledger close round 1: M21 block propagation with bodies at the mass limit, k re-derived"); the red rate under such bodies is not measured. | [docs/design/execution-layer.md](../docs/design/execution-layer.md) |
|
||||
| F14 | Weight in blocks over a window in blocks under a lagging retarget | Answered with evidence | , ledger close round 1: M14 and F14 the 50x pulse against a lagging retarget inside the finality simulator, both W2 forms"). | [sim/results_v2.md](../sim/results_v2.md) |
|
||||
| F15 | Merge depth is not the reorg bound; the finality depth is | Spec fixed | Spec 2.1 names the finality depth as the reorg bound and merge depth as a merge limit only, spec 3.8 and 3.9 tell exchanges to wait 12 hours of past-median time when `finality_active` is false, and the simnet reorg… | the files above. |
|
||||
| F16 | A lock can become uncertified after a heal | Decided | Option B, a verified certificate is never withdrawn (spec 3.11.4); the 3.5 paragraph is replaced by 3.11.4's text after `c4-fix` merges, `finality_conflict` and the `finality_active` clear go into the node, the forced… | spec 3.5, 3.9. |
|
||||
| F17 | Keys are free and the official client mints eight per card | Decided | The client defaults to one vote key per machine, identities share it (spec 3.4.2 item 4); the bitmap bound as item 3. | [proto-cuda/windows-miner/start-mining.ps1](../proto-cuda/windows-miner/start-mining.ps1) |
|
||||
| F18 | "A silent minority cannot freeze finality" is false under the floor | Fixed | Correct. | [sim/results_v2.md](../sim/results_v2.md) |
|
||||
| P11 | The native-execution veto makes block validity depend on the node's current selected chain | Fixed | Spec 7.2 item 5 and `docs/design/execution-layer.md` 5.5 and D12 are relative to the carrying block's own selected-parent chain; the two-node reorg test is a row in the design document's 8.5. | [docs/design/execution-layer.md](../docs/design/execution-layer.md) |
|
||||
| P12 | An aggregator can name itself as every prover | Fixed in the proving code | Every shard proof's public values carry the prover's payout address (`ShardOutput.prover`), the aggregated block proof commits keccak over the provers in shard order and the shard program's verifying-key hash… | [docs/design/execution-layer.md](../docs/design/execution-layer.md) |
|
||||
| P13 | The litepaper still claims shards with a bond | Fixed | `Site/litepaper.html`, Proving, "How a block gets proven". | [site/litepaper.html](../site/litepaper.html) |
|
||||
| P14 | Two definitions of the proving base fee, and a quote that cannot know the ratio | Fixed in the spec | One definition. | [docs/design/execution-layer.md](../docs/design/execution-layer.md) |
|
||||
| P15 | RPC blocks are segments, so `gasUsed` can exceed `gasLimit` | Fixed on a branch, pending merge | `Igneum/exec/src/rpc.rs` reports `gasLimit` as k x `BLOCK_EXECUTION_GAS_LIMIT` for a k-block segment (k = the record's mergeset length, at least 1), beside the segment's `gasUsed`, so `gasUsed <= gasLimit` holds for an… | [docs/design/execution-layer.md](../docs/design/execution-layer.md) |
|
||||
| E9 | The specification's year is 365 days; the code's is 365.25 | Fixed | Spec 2.5 follows the code (365.25-day year, 63,115,200-s halving, 31.688 IGN per DAA second, 8 decimals noted under O-2.6). | [consensus/core/src/igneum.rs](../consensus/core/src/igneum.rs) |
|
||||
| E10 | Reds are paid in the code and "more blocks never means more coins" is false | Fixed | Spec 2.5 says reds inside the DAA window are paid to the merging miner (80%) and the pool (20%), that `E` is paid per block so coins are blocks times `E` under the controller's rate, and that the cap is unaffected;… | [docs/review/round-3-2026-10-03.md](../docs/review/round-3-2026-10-03.md) |
|
||||
| E11 | The homepage burns job fees at launch | Fixed | `Site/index.html`, "Proofs sold to other chains" caption and the tile now read "phase two"; the quoted paragraph had already left the page when the homepage was trimmed (commit a commit). | [site/index.html](../site/index.html) |
|
||||
| C13 | Monero's seven years do not price a 256 MiB SRAM die | Conceded, stated | `Site/litepaper.html`, What Igneum does not claim, "they say nothing about the price of a chip with the 256 MB cache on its die, and that price is a cost model, not a measurement". | none beyond M16. |
|
||||
| L7 | "Where the price comes from" | Fixed | Heading "Where fees go" and the sentence deleted, `site/litepaper.html` Economics. | [site/litepaper.html](../site/litepaper.html) |
|
||||
| L8 | Third-party names as implied outcomes | Conceded, stated | `Site/litepaper.html`, Questions builders ask, "whether it is issued is Circle's decision"; Canto and Blast absent from the page (grep, tonight). | [site/litepaper.html](../site/litepaper.html) |
|
||||
| G9 | The release-key the team is one person, and a lost key cannot be revoked | Rule fixed | Spec 8.2 item 5, rotation signed by the current key and revocation signed by the previous key (a pre-signed certificate for K0), both published in a block; item 2 moves the policy to before the client ships and adds… | spec 8.2. |
|
||||
| G10 | The signalling default on first run | Rule written | `Docs/spec/08-client-security.md` 8.3 item 2 now ends: on first run there is no last choice, the client signals nothing until the user chooses, and the interface shows that nothing is being signalled. | [docs/spec/08-client-security.md](../docs/spec/08-client-security.md) |
|
||||
| X12 | Tonight's numbers are quoted before they are logged, and the worker efficiency gap is unexplained | Fixed, logged | Bench-log "5 October 2026 (night), ledger close round 1: X12 the 3 October devnet run from its record"; the launcher half (the eight processes' summed status) stays open until the PC's log is read. | [sim/difficulty/devnet-2026-10-03.csv](../sim/difficulty/devnet-2026-10-03.csv) |
|
||||
| M22 | The ASIC challenge has no scoring rules, and 2x is not the economic line | Decided | No bounty, so no bounty terms; M22's metrics (hashes per second and per joule per program over at least 100 epochs as a distribution, capital cost per unit of hash rate at a stated volume, the longevity term, the… | M1, O-1.17, spec 1.13 and 1.16, M16's arithmetic. |
|
||||
| F19 | Old vote keys can be bought; fresh hashrate cannot buy weight | Answered with evidence | A bought key is worth the blocks it holds and nothing more. | [sim/results_v2.md](../sim/results_v2.md) |
|
||||
| F20 | During a finality pause the program must keep advancing, and nothing says which guarantees survive | Answered with evidence for the test half | , ledger close round 1: F20 finality pause under a 45% silent set through four epoch boundaries"); the gate-3 wording of the four guarantees (O-3.16, O-4.3) stays a decision for the founder. | spec 4.3 (O-4.3), 3.3.1, 3.5, 3.7 item 2, 3.9. |
|
||||
| F22 | Certificates carry 8 to 10 of 12 votes on a healthy network, so locks sit a hair above the floor | Fixed in the node and shipped, rule not yet activated on… | True as measured, and the cause is not a cut-off at all: the node builds the certificate the instant the votes it holds meet Q3, and carries that one. | [infra/cloud-devnet/results/2026-10-04/partition-sin-20261004-140305/partition.md](../infra/cloud-devnet/results/2026-10-04/partition-sin-20261004-140305/partition.md) |
|
||||
| P16 | The proving gate can be passed by shrinking the shard | Decided | A 12 GB NVIDIA card (4070) is on order for PC 2; O-7.1 runs end to end on it when it arrives, inside the phase 2 gate. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| P17 | Interfaces must show four states, and the design shows three | Fixed on a branch, pending merge | a fork a commit (a commit rebased onto the 0.3.11 fork tip a commit in round 3), suite igneum-exec 16 of 16 on the Mac (labelled a Mac run), the O-7.2 conformance run PASSED on a fast-time 3-node network (bench-log… | execution-layer 2.3, 2.4, 8.2; phone-app 3 and 9; spec 3.9, 10.1. |
|
||||
| E12 | Selfish operators under a price shock | Simulation half run | No backlog in any scenario, every block proven within 60 s in every hour, hash troughs at 82% of its pre-event level under b and 75% under d (80% at day 30), 10% of cards off under b… | spec 5.1, 5.3, 7.2; execution-layer 4.3, 9.1 R8. |
|
||||
| E13 | One diagram per payment route, or operator income and protocol income blur | Conceded, stated | `Site/litepaper.html`, Economics, "Every payment route", six rows (emission; base fee; priority fee; external job at launch; external job after the proof bridge; the official client's dev fee as operator income),… | [docs/commercial/prover-customer-brief.md](../docs/commercial/prover-customer-brief.md) |
|
||||
| E14 | No funding table | Decided | The funding table stays internal until counsel has read it; one public sentence in the litepaper names the unfunded lines (the second client, the external reviewers, the bounty before escrow). | E4, E5, G1, G5; fud-fixes rows 47, 50, 71. |
|
||||
| E15 | The security budget through successive halvings with low fees and no external demand | Decided | The 4,000,000,000 IGN hard cap stays absolute and there is no tail emission. | spec 2.5, 5.1 to 5.4; E1, E6. |
|
||||
| G11 | Publish the inspectable components now, labelled experimental | Decided | The specification subset is public as `igneum-network/spec` (`docs/plans/public-repo.md`), labelled; the node fork, the proving code and the harnesses stay private until the benchmark. | [docs/fud-fixes.md](../docs/fud-fixes.md) |
|
||||
| X13 | One paying customer for a stated reason | Decided | The paid pilot stays in phase 5, the phase 4 gate stays the signature, nothing moves earlier before counsel answers L4. | [site/journey.json](../site/journey.json) |
|
||||
| X14 | Concentration is unmeasured in four places | Answered with evidence for all four | , ledger close round 2: X14 signing concentration from block payloads"); the independence definition stays the founder's (X5). | X5, F10, P12, spec 9.4.2. |
|
||||
| X15 | Remove the founders from a test network and show what continues | Open, blocked on the public testnet | Next step O-X.2 run at a published time on that testnet, with the protocol already in the Answer below (every project-run node, miner, prover, aggregator and seed stopped, the observer and live page down, 24 hours of… | [site/litepaper.html](../site/litepaper.html) |
|
||||
| X16 | An evidence page with four labels | Written | `Docs/evidence.md`, one row per public claim with five labels (tonight, counting the label column of the claims table: designed 9, implemented 8, tested by the team 26, reproduced externally 3, reviewed independently 2). | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| X17 | The miner app must show net earnings and keep jobs away from keys | Designed | Spec 8.8 and phone-app 4.1; measurement O-8.2 and the escape test O-8.3 scheduled for the phase 4 devnet. | [site/litepaper.html](../site/litepaper.html) |
|
||||
| P18 | The mempool queues transactions no block can carry | Fixed | Correct, and low: the queue slot was reserved against the sender's funds, so it was self-limited. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| P19 | An over-budget proving transaction runs for free, every time, and blocks its sender | Fixed | Correct, medium. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| P20 | The SP1 GPU client panics on shutdown and the compressed stage waited ten minutes | Fixed and confirmed | The buffered save closed the gap, the core proof finished at and the compressed stage started at; shard timings repeated within 0.3 s (core 9.1 s, compressed 10.5 s); a guest that returned 0 bytes on the second run was… | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M23 | Forge timestamps inside the rules and the controller mines you a 10x difficulty for free | Fixed | Correct on every point, and measured first by our own attack run (`sim/difficulty/attacks/README.md`, scenarios 3 and 7): in the simulator a 50% forger took the block rate to 0.12 (earliest stamp) and 0.56 (latest) of… | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| P21 | The SP1 proof is not what consensus checks in proving v0 | Decided | Proving v0 (every producer verifies off the consensus path) through the public testnet; the in-consensus verifier is the execution engineer's plan item for after it; the litepaper sentence labelled Open stands. | none named |
|
||||
| P22 | The rewards and payouts are inputs to the shard proof, not outputs | Open, blocked on the phase 2 consensus proof | Next step that consensus-proof work, in phase 2 (Nov 2026 to Jan 2027 per the litepaper roadmap), no earlier date. | none named |
|
||||
| M24 | Your two-lane controller oscillates for an hour when a second miner joins mid-epoch | Rolled out | Rule v2 activated on the live devnet at DAA 33,000 by the height switch after a 12-node cloud rehearsal (settle 157 to 272 s, no swing); node 1, the seed, the observer and the three app machines crossed the height on… | [sim/difficulty/records/live-2026-10-04.csv](../sim/difficulty/records/live-2026-10-04.csv) |
|
||||
| D1 | Your users are a gate, not a fact | Conceded, stated | Correct on the count and on the definition. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| D2 | The app share pays nothing | Conceded, stated | `Site/litepaper.html`, Building, Why build here, "a million 100,000-gas calls a day at a 1 gwei tip pays about 7,300 IGN a year"; Canto and Blast absent from the page (grep, tonight). | [docs/design/developer-adoption.md](../docs/design/developer-adoption.md) |
|
||||
| D3 | Proof of work in 2027 is a perception cost you cannot measure | Conceded, no experiment possible | Correct that the cost exists and that nothing in the design measures it. | [site/litepaper.html](../site/litepaper.html) |
|
||||
| D4 | No dollar, no DeFi | Conceded by decision | , restated here for builders. | [docs/review/round-3-2026-10-03.md](../docs/review/round-3-2026-10-03.md) |
|
||||
| D5 | I cannot debug a revert | Conceded, scheduled | `Docs/design/developer-adoption.md` section 5, owner and gate named (the execution engineer; no outside team is invited before step 2 is done). | [docs/design/execution-layer.md](../docs/design/execution-layer.md) |
|
||||
| D6 | A forged job result reaches my contract and nobody vetoes it | Conceded, contained by rule, reviewed | `Docs/review/d6-forged-job-result-2026-10-05.md`. | [docs/design/execution-layer.md](../docs/design/execution-layer.md) |
|
||||
| X23 | One shipped key is an administrator channel to the founder's PCs | Fixed on a branch, pending merge | Three tiers in `relay/lib/guard.mjs` (`authVia`): the console token (header or the phone page's path), the relay's own key (`RELAY_KEY`: reads and reports, never `task`, `run`, `name`, `role`, `secret`, `delete`), and… | [docs/review/round-4-2026-10-04.md](../docs/review/round-4-2026-10-04.md) |
|
||||
| X24 | The relay token rides in the URL on every request | Fixed on a branch, pending merge | Every client and Mac tool calls `/api/relay?fn=<fn>` with `x-relay-token` (and `x-igneum-key`) as headers: `igneum-agent.ps1` and `send.ps1` (`Api-Url`), `agent.sh` and `send.sh` (through a 0600 curl config file, `-K`,… | [tools/relay.mjs](../tools/relay.mjs) |
|
||||
| X25 | The PC agent installs itself at every logon, at highest privilege, on every start | Fixed on a branch, pending merge | `Igneum-agent.ps1` calls `Arm-Restart` only on the two paths that end in `shutdown.exe /r` (a task that printed `RELAY-REBOOT` on its own line AND was queued with `--reboot` or `--reboot-continue`), sets… | [relay/clients/igneum-agent.ps1](../relay/clients/igneum-agent.ps1) |
|
||||
| X26 | The feed is a permanent transcript, and it holds the dl token by design | Fixed on a branch, pending merge | Retention 30 days (`relay/lib/handler.mjs` `expire`: `DELETE... | [relay/lib/handler.mjs](../relay/lib/handler.mjs) |
|
||||
| X27 | The relay has no clean rotation and no sender binding | Fixed on a branch, pending merge | A per-machine secret (64 hex, `node tools/relay.mjs secret PC1`: written to `~/.config/igneum/relay-machines/PC1` at 0600, its sha256 bound on the relay with `POST secret` (token only), carried to the PC as… | [relay/README.md](../relay/README.md) |
|
||||
| X28 | Relay hygiene, minor | Fixed on a branch, pending merge | The remaining points. | [lib/wake.mjs](../lib/wake.mjs) |
|
||||
| G12 | The PoW schedule comes from the environment on every network, including mainnet | Fixed | . | the files above. |
|
||||
| G13 | The update signature covers binaries that nobody signed | Fixed on a branch and verified locally | The chain already on master was read end to end and run, not asserted. | [packaging/windows/push-inputs.sh](../packaging/windows/push-inputs.sh) |
|
||||
| G14 | Secrets and identity in the history of a repository with a public date | Decided | `TZ=UTC` in every commit path the tooling owns: `tools/ship-app.mjs` (`git` runs with `env: { TZ: 'UTC' }`), `packaging/ota/publish-jobs.sh` (`export TZ=UTC`, found by the class check), `tools/repo/fresh-repo.sh`… | [tools/ship-app.mjs](../tools/ship-app.mjs) |
|
||||
| X18 | Two nodes with two override files connect, and only some mismatches fork | Fixed | . | the files above. |
|
||||
| F23 | The equivocation ban is node-local, so honest nodes refuse each other's certificates | Fixed | . | the files above. |
|
||||
| F24 | A checkpoint determination is never revisited | Fixed | . | the files above. |
|
||||
| F25 | The fast-time harnesses cannot start a node, and the timestamp probe tests the old rule | Fixed | Correct, measured. | [rt/logs/fa_s8/n0/node.log](../rt/logs/fa_s8/n0/node.log) |
|
||||
| X19 | Operational knobs and silences in the shipped node | Fixed on a branch, pending merge | The node half, fork commit a commit. | [protocol/flows/src/flowcontext/clock_skew.rs](../protocol/flows/src/flowcontext/clock_skew.rs) |
|
||||
| X20 | Cold-sync checkpoint determination is indices times chain length | Fixed on a branch, pending merge | `Consensus/src/processes/finality.rs` `on_virtual_changed` resolves every index the sink can determine in ONE descending walk of the selected chain (`chain_blocks_at`, targets highest first), where it walked from the… | [consensus/src/processes/finality.rs](../consensus/src/processes/finality.rs) |
|
||||
| M25 | The miner takes the day length from its environment, and the schedule global can tear | Fixed on a branch, pending merge | Correct. | [igneum/miner/src/main.rs](../igneum/miner/src/main.rs) |
|
||||
| M26 | The interval fault guard freezes its baseline and loops | Fixed | `IntervalGuard` builds its baseline from the healthy intervals of the current worker process (a moving average, two intervals before it can trip) and forgets it when the worker restarts; the STATUS line is printed on a… | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M27 | A flapping node makes the worker rebuild once per template | Fixed | Correct. | the files above. |
|
||||
| M28 | The kernel text is bound only to its own directory | Fixed on a branch, pending merge | Correct. | [proto-cuda/nvrtc/packfile.h](../proto-cuda/nvrtc/packfile.h) |
|
||||
| X21 | A wrong program burns power with a green rate | Fixed | Correct. | the files above. |
|
||||
| X22 | Worker restart paths, minor | Fixed on a branch, pending merge | The four remaining paths. | [app/igneum-app/src/engine.rs](../app/igneum-app/src/engine.rs) |
|
||||
| E16 | The 20% pool is burned on the live chain, and the text says it pays provers | Answered with evidence and stated | Correct for the live devnet-v4 line. | [docs/review/round-4-2026-10-04.md](../docs/review/round-4-2026-10-04.md) |
|
||||
| L9 | "100% to miners and provers", "0% anyone else", and no word that devnet coins have no value | Conceded, stated | `Site/index.html`, `site/miner.html` and `site/wallet.html`, a line beside every download control, "Devnet: coins have no value and the chain may be reset."; `site/index.html` Economics tiles, "of emission to miners… | the files above. |
|
||||
| M29 | The litepaper's app paragraph describes an app that does not exist | Conceded, stated | `Site/litepaper.html`, For miners, "One click, for everyone else", rewritten to Ember 0.3.9 from `app/igneum-app/ui/index.html` (hash rate, blocks found, node, next program, finality votes, the proving tile, the devnet… | [ui/app.js](../ui/app.js) |
|
||||
| M30 | A block or transaction flood grows the 0.3.4 node by hundreds of megabytes in a minute | Fixed | Measured, cause not yet isolated. | [docs/bench-log.md](../docs/bench-log.md) |
|
||||
| M31 | The 0.3.4 node cannot produce a block template on mainnet, testnet or simnet parameters | Fixed | Measured on the execution-layer attack network (`tools/exec-attacks/net.sh` runs `--simnet` with no override): three nodes up, 0 blocks, every template refused with that line (`docs/review/redteam-2026-10-04.md` row 27). | [rt/logs/exec_b/miner_node1.log](../rt/logs/exec_b/miner_node1.log) |
|
||||
| E17 | Unlogged inputs behind the economics, minor | Answered with evidence for PC 2 | RTX 5090 honest 132.2 Mhash/s at 326.6 W median, 3,060 MHz, 50 to 54 C, 100% utilisation (0.40 Mhash/J); 346.9 W at 8 warps per block; the inline settings 415.7 W and 431.0 W (the power limit). | [docs/review/round-4-2026-10-04.md](../docs/review/round-4-2026-10-04.md) |
|
||||
| E18 | The dev fee is a protocol fee with better PR | Answered by design and with evidence | The fee exists and is disclosed; the rest is wrong in three places. | [docs/design/miner-dev-fee.md](../docs/design/miner-dev-fee.md) |
|
||||
| X29 | Host and file hygiene, minor | Decided | The curl part: `infra/gpu-bench/upload.sh` writes `header = "x-igneum-key:..."` to a 0600 temporary config and calls `curl -K`; `proto-cuda/windows-app/upload-log.bat` and `proto-cuda/windows-miner/upload-log.bat` do… | [infra/gpu-bench/upload.sh](../infra/gpu-bench/upload.sh) |
|
||||
| X30 | The live page and the bench page exposed operational detail | Fixed | `Ac89a37` and a commit (a scrubbed copy, the build fails on any private string), a commit (none of the three in the public API), a commit (the menu). | the commits above. |
|
||||
| X31 | The public testnet dated "August 2027" on the site | Fixed, stated | Every mention of the month is gone from the site. | [docs/plans/testnet-go.md](../docs/plans/testnet-go.md) |
|
||||
| X32 | The roadmap carried calendar months beside a testnet that is weeks away | Fixed, stated | Every calendar month is out of the roadmap. | [site/litepaper.html](../site/litepaper.html) |
|
||||
| X33 | The public benchmark dated "January 2027" | Fixed, stated | Both sentences read "The public benchmark with a leaderboard ships with the public testnet." (`site/litepaper.html`, For miners and Questions miners ask). | [site/litepaper.html](../site/litepaper.html) |
|
||||
| X34 | RandomX described as chip-free | Fixed, stated | Four sentences corrected, each with the X9 as the stated fact and its date; every sentence that only names the technique stands. | [site/index.html](../site/index.html) |
|
||||
| X35 | The class v4 chip headline stated as one number, 2.1x | Fixed, stated | Every public sentence that stated 2.1x alone now states the range with k named. | [docs/design/latency-ladder.md](../docs/design/latency-ladder.md) |
|
||||
| X36 | The X9 described as a shipping chip | Fixed, stated | Every public sentence that had the X9 shipping now states the pre-order, the withdrawal and the unbenchmarked core. | [site/index.html](../site/index.html) |
|
||||
| N1 | A 0.3.15 node on the live file wrote blocks every 0.3.14 node rejected | Fixed | The class v4 signal (PROPOSED, `docs/plans/counter-asic-3-node.md` section 6) is the producer's object version in the high byte of the header version; the first 0.3.15 build stamped it from the binary alone, so on the… | [infra/fast-time/node-compat.mjs](../infra/fast-time/node-compat.mjs) |
|
||||
| N2 | Any peer could crash any pruned node with a sync request below its retention | Fixed | `SyncManager::antipast_hashes_between` (the IBD headers path, `RequestHeaders`) unwrapped the GHOSTDAG reads of the requested low block and of every chain block of the walk; a pruned node holds no GHOSTDAG data below… | unit test `a_sync_request_below_retention_is_an_error_not_a_panic` (a chain of six headers, the genesis's GHOSTDAG… |
|
||||
| P23 | An unwound transaction leaves the node's view until its sender resends it | Fixed on a branch, pending merge | a fork a commit (the P23 commit, on the merge of `ledger-fixes` and `ledger-fixes-2` onto the 0.3.11 fork tip a commit); `EvmPool::on_chain_removed` (igneum/exec/src/pool.rs) and `ExecService::requeue_unwound`… | [igneum/exec/src/pool.rs](../igneum/exec/src/pool.rs) |
|
||||
| AP-F8-1 | A load whose source was last written by `or`, `mul` or `mulhi` makes a cross-hash hot set | Fixed on a branch, pending the 0.3.20 node ship | `Ca3-v4-amend` a commit (the generator and the packs) and a commit (the PC 2 playbook), on origin/master a commit plus `ca3-v4-uniform` a commit (the analysis). | [docs/analysis/ca3-v4-uniform.md](../docs/analysis/ca3-v4-uniform.md) |
|
||||
| GF1 | A post-quantum signature scheme would need a hard fork, and every vote key is a public BLS12-381 point | Fixed | The byte costs nothing now and a fork later. | none named |
|
||||
| GF2 | A vote key cannot move: a miner who changes keys re-earns 30 days of weight, and so does the post-quantum migration | Fixed | The successor inherits the window, not a fresh one, so a key rotation costs no weight and the migration of GF1 is one item per key. | none named |
|
||||
| GF3 | A 256 MB on-chip cache makes the lottery hash 2 to 3x cheaper for the card that has it, and the cache size is a constant | Fixed as a genesis lever, measurement owed | Consumer LLC is 96 to 128 MB today and datacentre 256 MB (`chip-model-v3`, approximate), so the shortcut is a datacentre card's today and a consumer card's in a generation or two. | none named |
|
||||
| GF4 | The class-group VDF falls to the same quantum computer | Conceded, flagged in spec 04 section 4.8 | ; not sized. | none named |
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# The `build` job: a PC builds the node and the app, nobody at the keyboard
|
||||
|
||||
4 October 2026, evening. the project lead's ask ("efficiency"): every Windows node and app build went through a GitHub runner at
|
||||
4 October 2026, evening. The founder's ask ("efficiency"): every Windows node and app build went through a GitHub runner at
|
||||
15 to 25 minutes a round, and every Linux binary was cross-compiled on this Mac under the build lock. The two
|
||||
RTX 5090 PCs (PC 1 `ae432dc7`, PC 2 `1ccfe586`) run Igneum Miner 0.3.3 with the signed job channel and each has a
|
||||
WSL2 Ubuntu 24.04 owned by the app (root, cargo and the SP1 toolchain under /root from the shard jobs). So the build
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Build server: igneum-build-1 (plan, benchmarks, rules)
|
||||
|
||||
6 October 2026. the project lead ordered a Hetzner dedicated server at 18:2x UK: AX162-1-LTD, EPYC 9454P (48 cores, 96 threads),
|
||||
6 October 2026. The founder ordered a Hetzner dedicated server at 18:2x UK: AX162-1-LTD, EPYC 9454P (48 cores, 96 threads),
|
||||
128 GB, 2x 3.84 TB NVMe, Falkenstein (FSN1-DC24, Hetzner #3088308), 188.40.146.49, IPv6 2a01:4f8:2240:205a::/64.
|
||||
Purpose: this Mac is the compile queue for ten agents (8-minute rebuilds under contention) and the Windows cross-builds;
|
||||
the box takes over Rust builds, cross-builds and a shared compile cache, and later a CI runner and the Devnet 2 seed.
|
||||
|
|
@ -122,9 +122,9 @@ Self-test: `tools/build-remote.sh --self-test-repro [--full]` from a fork worktr
|
|||
| Consequence: glibc ceiling 2.38 | runs on the fleet (Ubuntu 22.04 containers are glibc 2.35: NO, 2.38 > 2.35; Ubuntu 24.04 hosts yes). The Mac's zig build (`infra/cross/build-workers-linux.sh`, glibc 2.36) is the one for Debian 12 and HiveOS; the fleet agent must check its boxes' glibc before swapping the worker. Fix if needed: zig on the box (open row in section 6) or `clang -target x86_64-linux-gnu.2.35` via zig; both a day's work, not done |
|
||||
| Runner fix found on the way | a command string carrying `set -e` leaked into remote-run.sh through `eval` and killed the runner before its RESULT line (reported as rc 101); the runner now evaluates the command in a subshell |
|
||||
|
||||
## 5c. Deploy key for the observer clone (DONE: the project lead added the key on 7 October 2026, morning)
|
||||
## 5c. Deploy key for the observer clone (DONE: the founder added the key on 7 October 2026, morning)
|
||||
|
||||
Done. the project lead added the public half as the read-only deploy key "igneum-build-1 observer (read-only)" (SHA256:51ice3W8...; the
|
||||
Done. The founder added the public half as the read-only deploy key "igneum-build-1 observer (read-only)" (SHA256:51ice3W8...; the
|
||||
organisation's deploy-key policy had to be switched to Enabled first). The sync's own test then still said "mirror": `ssh -T` to
|
||||
GitHub exits 1 after its greeting and the script runs under pipefail, so `su ... | grep -q` reported failure although grep had
|
||||
matched; fixed by capturing the output first (install-hands.sh). First pass reading "source: github (deploy key accepted)":
|
||||
|
|
@ -159,7 +159,7 @@ so a revoked key never stops the observer; it only makes it follow the mirror ag
|
|||
| Byte identity with the Mac's exes | different C/C++ toolchain (Homebrew mingw vs Ubuntu GCC 13) and embedded source paths | not a goal; the box is identical with itself build to build, cross-remote.sh reports sha256 and the DLL list per exe |
|
||||
| Robot API | `~/.config/igneum/hetzner-token` is the Cloud token (hcloud); the dedicated box lives in Robot, a separate credential | main sets the Robot server name in the UI; a webservice user goes to `~/.config/igneum/robot-credentials` when needed |
|
||||
|
||||
## 7. The box's second shift (6 October 2026, from 20:3x UK, the project lead: "what else can our building machine be working on?")
|
||||
## 7. The box's second shift (6 October 2026, from 20:3x UK, the founder: "what else can our building machine be working on?")
|
||||
|
||||
Four items, each its own commit on branch `box-work` with its section here. Times UTC.
|
||||
|
||||
|
|
@ -317,7 +317,7 @@ the shape is a systemd unit as `build` with `SP1_PROVER=cpu`, a throwaway devnet
|
|||
`--threads 48`, Nice 19 and the measure hold taken for the whole run, which would exclude builds for minutes at a time: that
|
||||
is why it is not written.
|
||||
|
||||
## 8. The capacity layer (6 October 2026, the project lead: "get the builder spun up to capacity")
|
||||
## 8. The capacity layer (6 October 2026, the founder: "get the builder spun up to capacity")
|
||||
|
||||
The box sits idle most of the minute between builds. `infra/build-server/capacity/` is a background workload layer that
|
||||
uses the idle cores and yields to builds. It runs as `igneum-capacity.service` (user `build`, `Nice=19`, `chrt -i 0`
|
||||
|
|
@ -360,7 +360,7 @@ tree, so install writes a drop-in pinning `CAP_REPO_BRANCH=box-capacity` and rem
|
|||
|
||||
## 7. Spill-over between the boxes (7 October 2026, 15:0x UK)
|
||||
|
||||
the project lead's reading at 15:02 UK: build-1 at load 139 / 114 / 90 with both slots held and a queue (the horizon lane waited 1 h 40 min)
|
||||
The founder's reading at 15:02 UK: build-1 at load 139 / 114 / 90 with both slots held and a queue (the horizon lane waited 1 h 40 min)
|
||||
while build-2 read 4.5 / 27 / 46 with both slots free. The class router (section 6) pinned each class to its box with no
|
||||
spill-over. Now (lib.sh `bs_route_spill`, master from this commit):
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Cloud devnet and rented-GPU benchmarks: plan
|
||||
|
||||
3 October 2026. Scripts in `infra/cloud-devnet/` and `infra/gpu-bench/`. Nothing in either directory spends until
|
||||
the project lead answers "yes" to one command; the seed node (`docs/plans/seed-nodes.md`) is the only thing live tonight.
|
||||
The founder answers "yes" to one command; the seed node (`docs/plans/seed-nodes.md`) is the only thing live tonight.
|
||||
|
||||
## Experiment 1: a 20-node Igneum devnet across regions
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ Command sequence: `infra/gpu-bench/README.md`. In short: `make-bundle.sh` on the
|
|||
recipe with SSH, `scp` the bundle, `./run.sh`, read `results.md`, paste the row into `docs/bench-log.md` with the
|
||||
template.
|
||||
|
||||
## The go/no-go question for the project lead
|
||||
## The go/no-go question for the founder
|
||||
|
||||
Spend about USD 5 (Hetzner, billed in USD) and USD 2 to 4 (RunPod) tonight-to-tomorrow for (a) the first reorg-depth, propagation and partition numbers
|
||||
from a real multi-region network, which gate 3 needs and the simulator cannot give, and (b) the per-card hash rates
|
||||
|
|
|
|||
|
|
@ -10,17 +10,17 @@ Rows already handled before this ledger opened, for the shape: 15.6 GB mine-and-
|
|||
|---|---|---|---|---|---|---|---|
|
||||
| C1 | Fee switch H = 210,000, reached about 18:45Z on 6 October (DAA 137,041 at 22:32:54Z, 1.002 DAA/s averaged since the 15:40Z read; the plans first said 19:50 from 0.965 blocks/s) | `docs/plans/fee-switch-devnet.md` sections 3 and 7; `vendor/igneum-node-0310/igneum/exec/src/rpc.rs` 849 (no `daaScore`, no `feesV1ActivationDaa` in `igneum_exportSegments`); the app's exporter call without `--fees-v1-activation-daa` (`app/igneum-app/src/prover.rs` 516 to 519) | every prover on the devnet (PC 2, the Mac, any 0.3.10 machine) | From the first chain block at or above H the 0.3.10 node cuts 30,000-pgas shards and meters with the v1 table, but the app's exporter sees a dump without the switch and cuts at 7.5 M with the prototype table: the host refuses the fixture (wrong `S_p`) or the node vetoes the statement. Proving on the devnet goes dark at H and nothing is paid until every prover runs a node whose export carries the switch (the proving-v1 fork does, `vendor/igneum-node-pv1` rpc.rs 961 and 982). `pc2-chain.ps1` fixtures from the live node fail the same way after H | Either 0.3.11 (proving-v1 fork) on every prover before H, or the switch republished at a later H before 19:50Z tomorrow (a digest flip, every node). Recommendation in `consequences-decisions.md` D1 | proving v1 acd4f36bc2c07a4e2, shipper ae892a8b0f78fe31c, coordinator ada8afb62d752b1e2 | in work (proving agent: fork eb32c645 on 21d4c73c carries daaScore and feesV1ActivationDaa, the exporter needs no flag; 0.3.11 on every prover before 16:00Z on 6 October or H moves to tip + 86,400; the line is in the proving plan, the rollout plan and release-0.3.10.md) |
|
||||
| C2 | 16,751 MiB GPU peak during the chain of 8 with the miner resident (`chain-pc2-pv1c`) | bench-log "proving v1", step 2 chain row | 16 GB cards (RTX 5080, 5060 Ti 16 GB, 4060 Ti 16 GB) | The plan's "a 16 GB card sits 0.4 GB under tonight's peak" is the empty-shard row (15,590 MiB). The chained aggregation adds 1.2 GB and lands at 16.4 GB, over a 16 GB card. So a 16 GB card cannot mine and aggregate on this build; it can at most mine and prove shards, with 0.4 GB spare and no full shard measured | The 16 GB chained-aggregation row goes into the sweep; the aggregator step in `prover.rs aggregate_once` gates on card memory (24 GB with the miner running, else pause the miner on that card for the aggregation); the Proving tile says which role the card runs | proving v1 | closed as measured (proving agent, spcurve-miner-pc2-pv1 219517f: the adopted shard beside the miner 22,210 MiB and 13.2 s, so a 24 GB card has 2.3 GB spare from the fee switch, the number approximate for the card itself because it is the 5090's allocation pattern; the prototype shard 30.1 GB, the 32 GB card alone; aggregation_card gates on the same memory rule, 23,552 MB either role). Open: the first real 24 GB card measurement, and the public line says "24 GB" from a 32 GB card's pattern (D2 wording) |
|
||||
| C3 | 13,816 MiB GPU peak, prover alone, empty shards (`prover-cost-pc2-pv1`) | bench-log "proving v1", step 1 | 12 GB cards (RTX 3060 12 GB, 4070, 5070), the default-on rule (`provedefault.rs` `MIN_VRAM_MB` 11,776) | On the only measurement the prover by itself exceeds a 12 GB card by 1.5 GB, so the 12 GB default gate switches proving on for cards that cannot run it on this build unless the SP1 knobs bring the peak down. The litepaper's "12 GB or more proves full shards" (`site/litepaper.html` 560) and evidence row 16 rest on the sweep | 0.3.11 does not ship the default-on until the sweep has a row under 11.5 GB for a full v1 shard; if none, the gate moves to 24 GB and the public claim is qualified (D2) | proving v1 (sweep in work); public claim: decision | closed as measured (proving agent: the sweep moves no floor, 13.9 GB for an empty shard, 28.3 GB for a full prototype shard; the default is 20 GB mining / 16 GB prove-only; the 12 GB sentence is false on this build and goes to the project lead as D2 with the curve); the v1-shard row is C15 |
|
||||
| C3 | 13,816 MiB GPU peak, prover alone, empty shards (`prover-cost-pc2-pv1`) | bench-log "proving v1", step 1 | 12 GB cards (RTX 3060 12 GB, 4070, 5070), the default-on rule (`provedefault.rs` `MIN_VRAM_MB` 11,776) | On the only measurement the prover by itself exceeds a 12 GB card by 1.5 GB, so the 12 GB default gate switches proving on for cards that cannot run it on this build unless the SP1 knobs bring the peak down. The litepaper's "12 GB or more proves full shards" (`site/litepaper.html` 560) and evidence row 16 rest on the sweep | 0.3.11 does not ship the default-on until the sweep has a row under 11.5 GB for a full v1 shard; if none, the gate moves to 24 GB and the public claim is qualified (D2) | proving v1 (sweep in work); public claim: decision | closed as measured (proving agent: the sweep moves no floor, 13.9 GB for an empty shard, 28.3 GB for a full prototype shard; the default is 20 GB mining / 16 GB prove-only; the 12 GB sentence is false on this build and goes to the founder as D2 with the curve); the v1-shard row is C15 |
|
||||
| C4 | Host RAM 25,550 MB used of 63,132 on PC 2 with the prover on; the WSL2 VM working set 7,915 MB | bench-log "proving v1", step 1 host RAM row | Windows home miners with 16 GB RAM (the common gaming PC); Macs with 16 GB switching the CPU prover on | The prover default has no RAM floor. On Windows the WSL2 VM alone holds 7.9 GB beside the app, the node and the game-class desktop; a 16 GB machine with proving on by default swaps or kills the node. The app's own RSS (engine, node, verifier) is not separated in the measurement, so no requirement can be stated yet | The sweep job records the app's and the node's working sets beside the VM's; `provedefault` reads total RAM and stays off under 32 GB on Windows until measured; the Proving tile and the miner page state the RAM requirement | proving v1; miner UI adbf58b058186a18b (the tile line) | closed in code (proving v1 c2544be: MIN_RAM_MB_WINDOWS 31,000 in provedefault.rs, the tile line names the 7.9 GB VM on a 63 GB PC; unknown RAM is not a gate; the miner UI help line next cut) |
|
||||
| C5 | The app quit for the 0.3.10 update at 20:01:09Z and aborted the chain job at block 3 ("aborted (the app is quitting)"); `prover.rs` kills the child on quit | bench-log "proving v1" chain run 1; `app/igneum-app/src/prover.rs` 266 to 272 | every prover on every update; with proving v1 the aggregator | Tonight's `update-now` to every app aborts whichever shard each prover has in flight (up to 37 s of work each, no payout, re-assigned to nobody until the window passes). Under proving v1 a restart mid-segment loses the aggregator's chain state: the segment goes unproven after T (600 DAA), the aggregator share of 8 blocks is forfeited to the escrow, and the next record must be fresh-chain. With one aggregator on the devnet every app update costs 10 minutes of unproven segments | The update's safe moment waits for the prover's current proof (as it does for the node); the aggregator persists the last segment proof and resumes the chain after a restart; the Updates section says "waits for the proof in flight". For 0.3.10 tonight the aborted shards are an accepted cost, recorded | proving v1; shipper (tonight's rollout note); miner UI (Updates wording) | refused for tonight by the proving agent (persisting the segment proof and holding the update for a proof in flight are 0.3.12; the cost is in the plan as the rule working as written); the shipper carries the aborted-shard count in release-0.3.10.md section 8; the 20:01:09Z abort was NOT 0.3.10 (shipper: nothing published), see C16. The count, read from the intake at 22:3xZ: PC 2 quit for the 0.3.10 restart at 21:49:29Z (run win-1ccfe586-20261005-200114) with no proof in flight, because its prover had been dark on the root socket since 21:25Z (last exporter line 21:44:02Z, C17); the Mac proves nothing by default; so the restart aborted 0 shards tonight and the first instance of this class will be the 0.3.11 rollout |
|
||||
| C6 | The prover costs a mining 5090 4.0% (124.7 to 119.7 MH/s); the software dev fee is 1 template in 100 | bench-log "proving v1" step 1; `packaging/hive/README.md` "The dev fee" | pool users; the pool's ledger | A member who proves sends 4% fewer shares, so the pool's vardiff and `stats.hashrate` read a 4% loss while the proving income (90% of the shard credit plus a tenth to an aggregator) is paid to the member's own key and never appears in the pool's ledger: the pool dashboard understates a proving member's earnings. The software dev fee has no mechanism in pool mode (the pool issues the templates), so a pooled miner pays no dev fee today and the pool design must say whether it takes one (1 share in 100 to the dev address) or none | The pool-v0 design states both: the member `stats` carry a `proving` flag and the pool page shows proving income beside shares; the dev fee rule in pool mode is written down before the first pool ships | pool a4781ba117326091f | closed on pool-v0 (pool agent: the member stats line carries a proving flag, /api/miners/<address> and the pool page show it with the 4% note and that proving income never passes through the pool; the software dev fee is NONE in pool mode, the pool's own fee (default 1%) is the only fee, carried in the welcome message's share_scheme, shown on the Connect card, written in docs/plans/pool.md and packaging/hive/README.md). Merge note: packaging/hive/README.md is now edited on three branches (hive-words, ota-k2, pool-v0). Public wording: the miner page's "a visible 1% software fee you can switch off" is a solo-mining sentence once a pool exists, added to D8 |
|
||||
| C7 | The HiveOS package holds `igneumd`, `igneum-miner` and the two workers; no `igneum-prove-host`, no SP1 GPU server, no per-card rule | `packaging/hive/make-hive-package.sh` 26 to 30; README "What the hooks do" | rigs (HiveOS, Linux), the largest hashrate tier | A rig cannot prove at all, so the 20% proving share is reachable only from the app. The miner page says "the card mines and proves" (`site/miner.html` 7, `site/index.html` 484) and the HiveOS README does not say rigs mine only. A rig that could prove needs the 251 MB SP1 GPU server, CUDA 12.8 and the per-card profile of C2 and C3, and a rig's RAM (4 to 8 GB on most Hive images, approximate) is below C4's floor | The rig installer either carries the prover with the per-card rule and a RAM check, or its README and the miners page say rigs mine only and provers are app machines; `IDENTITIES=8 for a big card, 2 for a small one` gets a threshold in GB | rig installer a3e7b2b03222f5cff | closed (rig installer 88f31d9: gates 23,552 MB for both roles from provedefault.rs 440fd59, the README table per tier; HiveOS hive-words 2d056e8: the same table; open only the miners page sentence, D8) |
|
||||
| C8 | Dataset 2 GiB at genesis plus 0.5 GiB a year; the working-set rule "under 6 GB on an 8 GB card"; the cache 256 MiB doubling at years 4 and 12; scratch up to 128 KiB per resident warp | spec 01 section 1.13.3; coordinator's budget rule; layer 6 option C; `docs/plans/hot-table.md` section 3 | 4 GB and 8 GB cards; the litepaper's claim | `site/index.html` 461 says "Any 4 GB card" and the litepaper (560) says a 4 GB card mines for about four years and an 8 GB card for more than a decade. At 75% of the card the 4 GB card's dataset room is about 2.4 GiB: under one year. The 8 GB card's room is about 5 GiB after cache, hot table, scratch and buffers: about six years, five and a half with the year-4 cache step. Neither public sentence holds under the schedule | A card-lifetime table per tier (sub-agent, `docs/analysis/card-lifetime-2026-10-05.md`); the public wording is a claim for the project lead (D3) | sub-agent (table); decision (wording) | table landed (sub-agent, docs/analysis/card-lifetime-2026-10-05.md, 1fecfe2, merged into ca2-coord at 22:50): 4 GB 1.0 to 1.5 years under (a) and year 4 under (b); 8 GB 6.3 to 7.5 or 12; 12 GB 12 to 13.5 or 12 to 28 depending on whether the cache stays resident; Apple 8 GB 2.6 to 3.4 or 4. The coordinator decided the cache is freed after the daily build and recommends (b) to the project lead; the public sentences hold only under (b): D3 and D4 revised |
|
||||
| C8 | Dataset 2 GiB at genesis plus 0.5 GiB a year; the working-set rule "under 6 GB on an 8 GB card"; the cache 256 MiB doubling at years 4 and 12; scratch up to 128 KiB per resident warp | spec 01 section 1.13.3; coordinator's budget rule; layer 6 option C; `docs/plans/hot-table.md` section 3 | 4 GB and 8 GB cards; the litepaper's claim | `site/index.html` 461 says "Any 4 GB card" and the litepaper (560) says a 4 GB card mines for about four years and an 8 GB card for more than a decade. At 75% of the card the 4 GB card's dataset room is about 2.4 GiB: under one year. The 8 GB card's room is about 5 GiB after cache, hot table, scratch and buffers: about six years, five and a half with the year-4 cache step. Neither public sentence holds under the schedule | A card-lifetime table per tier (sub-agent, `docs/analysis/card-lifetime-2026-10-05.md`); the public wording is a claim for the founder (D3) | sub-agent (table); decision (wording) | table landed (sub-agent, docs/analysis/card-lifetime-2026-10-05.md, 1fecfe2, merged into ca2-coord at 22:50): 4 GB 1.0 to 1.5 years under (a) and year 4 under (b); 8 GB 6.3 to 7.5 or 12; 12 GB 12 to 13.5 or 12 to 28 depending on whether the cache stays resident; Apple 8 GB 2.6 to 3.4 or 4. The coordinator decided the cache is freed after the daily build and recommends (b) to the founder; the public sentences hold only under (b): D3 and D4 revised |
|
||||
| C9 | Index mapping option (a) multiply-shift (fades cards) against (b) power-of-two steps 2, 4, 8 GiB | spec 01 section 1.13.3, gate 1 | 8 GB and 12 GB cards | Option (b)'s 8 GiB step (about year 12) ends 8 GB and 12 GB cards on the same day; option (a) fades them one year at a time. The choice is a genesis parameter and a tier consequence nobody has put beside the options | Decision request D4 with the lifetime table of C8 | decision | decision (D4, with the card-lifetime table; the public copy now reads the step schedule as the gate 1 proposal, C31) |
|
||||
| C10 | The on-die-cache recompute chip's gain is 2.4x at every scratch share under the 6 GB cap; the mixer multiplier x2 brings it to 1.2x, x4 to 0.6x, inside the 10 ms verify gate | `docs/analysis/scratch-soundness.md` finding 2 and section 10; M16 analysis table | chip builders; the site's "under 2x" claim; pool share verification | Layer 3 does not deliver the headline and the rollout plan's own rule (6a) says the public claim is qualified when no share gets the chip under 2x. The lever that does is M16's mixer multiplier, which doubles the CPU verify per warp (0.441 ms to about 0.9 ms at x2): a pool core verifies about 11,000 members' shares instead of 22,000, and node block verification doubles. The corrected SRAM cost ($19 to $37 of silicon per mirror die) means the mirror never stops a funded chip; the cache schedule keeps it above GPU L2 only | The coordinator either carries the mixer x2 into class v3 for the devnet (it is a lottery-hash change like the others; the verify cost per warp is measured with it) or marks the site's "under 2x" as qualified in the public copy level 3 and D5 asks the project lead which | coordinator ada8afb62d752b1e2 | closed as a consequence (coordinator: the public claim was qualified at 21:50; at 22:00 the M16 mixer x4 was decided into class v3 behind the same activation; the pool-core and node verification consequences are C14) |
|
||||
| C11 | RX 9070 XT 17.73 MH/s at 198.9 W (0.089 MH/W) against the RTX 5090 122.30 MH/s at 307.6 W (0.398 MH/W); every read width costs the 9070 XT the same 2.4 G line fetches a second | bench-log AMD telemetry entry; readwidth probe ceilings (status 20:35) | AMD home miners; the "three vendors" copy | Under the "widest latency-bound read" rule w16 moves bytes per hash, not loads per hash, so the AMD card keeps about a seventh of the 5090's hash rate and pays 4.5x the electricity per hash; at a UK tariff of 25 p/kWh (approximate) the 9070 XT spends 4.5x the 5090's pence per IGN. The readwidth decision table carries MH/s only; no MH/W or MH per pound per card per class, and the public copy implies vendor parity | The readwidth table adds MH/W (and MH per pound at list prices, approximate) per card per class; the v3 decision names the AMD consequence; whether the class should favour fewer loads per hash for AMD's 64-byte lines is a consensus choice for the project lead (D6) | read-width a451c9935bfb1bc19; coordinator; decision | closed (read-width e752fc7 section 4.1: MH/W and MH per pound per class per card; the AMD gap is the card's random-access rate, no width closes it; the coordinator's 22:30 entry says "near parity per pound" where the table says the 5090 is 2.2x per pound: C18) |
|
||||
| C10 | The on-die-cache recompute chip's gain is 2.4x at every scratch share under the 6 GB cap; the mixer multiplier x2 brings it to 1.2x, x4 to 0.6x, inside the 10 ms verify gate | `docs/analysis/scratch-soundness.md` finding 2 and section 10; M16 analysis table | chip builders; the site's "under 2x" claim; pool share verification | Layer 3 does not deliver the headline and the rollout plan's own rule (6a) says the public claim is qualified when no share gets the chip under 2x. The lever that does is M16's mixer multiplier, which doubles the CPU verify per warp (0.441 ms to about 0.9 ms at x2): a pool core verifies about 11,000 members' shares instead of 22,000, and node block verification doubles. The corrected SRAM cost ($19 to $37 of silicon per mirror die) means the mirror never stops a funded chip; the cache schedule keeps it above GPU L2 only | The coordinator either carries the mixer x2 into class v3 for the devnet (it is a lottery-hash change like the others; the verify cost per warp is measured with it) or marks the site's "under 2x" as qualified in the public copy level 3 and D5 asks the founder which | coordinator ada8afb62d752b1e2 | closed as a consequence (coordinator: the public claim was qualified at 21:50; at 22:00 the M16 mixer x4 was decided into class v3 behind the same activation; the pool-core and node verification consequences are C14) |
|
||||
| C11 | RX 9070 XT 17.73 MH/s at 198.9 W (0.089 MH/W) against the RTX 5090 122.30 MH/s at 307.6 W (0.398 MH/W); every read width costs the 9070 XT the same 2.4 G line fetches a second | bench-log AMD telemetry entry; readwidth probe ceilings (status 20:35) | AMD home miners; the "three vendors" copy | Under the "widest latency-bound read" rule w16 moves bytes per hash, not loads per hash, so the AMD card keeps about a seventh of the 5090's hash rate and pays 4.5x the electricity per hash; at a UK tariff of 25 p/kWh (approximate) the 9070 XT spends 4.5x the 5090's pence per IGN. The readwidth decision table carries MH/s only; no MH/W or MH per pound per card per class, and the public copy implies vendor parity | The readwidth table adds MH/W (and MH per pound at list prices, approximate) per card per class; the v3 decision names the AMD consequence; whether the class should favour fewer loads per hash for AMD's 64-byte lines is a consensus choice for the founder (D6) | read-width a451c9935bfb1bc19; coordinator; decision | closed (read-width e752fc7 section 4.1: MH/W and MH per pound per class per card; the AMD gap is the card's random-access rate, no width closes it; the coordinator's 22:30 entry says "near parity per pound" where the table says the 5090 is 2.2x per pound: C18) |
|
||||
| C12 | The v3 working set on Apple: 1,568 to 1,760 MiB today, 2,592 to 2,784 MiB at the 2 GiB genesis dataset, in unified memory shared with macOS; 2,048 launched warps x 128 KiB scratch | `docs/plans/hot-table.md` section 3 M5 Max row; era-layout section 3 | Apple silicon with 8 GB and 16 GB (the base Mac mini, MacBook Air) | An 8 GB Mac holds the miner's 2.6 GB beside macOS's 3 to 4 GB: it mines today and swaps at the first dataset growth step. The app has no gate on Metal's `recommendedMaxWorkingSetSize`; the site's "Any 4 GB card" has no Apple line. The CPU prover's RAM on a 16 GB Mac is unmeasured (the Settings switch lets it on) | The app reads `recommendedMaxWorkingSetSize` and refuses to mine (with the reason on the Mine tile) when the working set exceeds it; the site says "Mac: 8 GB or more"; the Apple scratch row at 128 KiB is measured in the readwidth table, not launched at 2,048 by assumption | miner UI adbf58b058186a18b; read-width (the Apple row) | in work (read-width 30ff674: the Apple scratch footprint by arithmetic is 1.4 GiB at 2,048 x 32 KiB and 1.6 GiB at 2,048 x 128 KiB, 2.4 GiB at 4,096 x 128 KiB; the Metal harness now prints currentAllocatedSize and recommendedMaxWorkingSetSize in its RESULT line, the measured row waits for the Mac measure lock, held by a prover measurement since 20:31Z; the miner UI gates on the arithmetic plus its output buffer until then, mining.gate_reason next cut) |
|
||||
| C13 | `/api/supply` `max_supply_ign` 4,000,000,000 against `minted_at_end_ign` about 3,963,000,000 (the ramp withholds about 37 M, the floors the rest); the live tables lack `number`, `tx_count`, `detail` until the observer restarts | `site/api/supply.mjs` 31 to 48; `docs/plans/explorer.md` "Open" | everyone who reads the explorer beside the homepage tile "4B IGN hard cap, ever" (`site/index.html` 386) | The tile says 4 billion and the explorer page says "of 4,000,000,000 by the rule" while the API's own end figure is 3.963 billion: a reader who adds the two columns finds 37 million missing. The explorer page shows "Circulating 0 IGN" on the devnet deployment until the observer restarts on the new code | The tile, the litepaper's supply line and the explorer carry "cap 4,000,000,000; about 3.96 billion ever minted" (the litepaper already says "approached and never reached"); the explorer does not go live before the observer restart lands the columns | explorer a76f60b415859b7b5; wording: the project lead (D7, with D3) | closed (explorer 3e01212: the tile reads "cap 4,000,000,000, 3.96 billion ever minted, x% so far" with the withheld figure on hover; the homepage tile and litepaper wording stay with the project lead, D3 and D7; the zero-circulating premise was sharper than stated, a 42703 failure not a null, now a 503 with the reason, and moot: the live observer restarted on the explorer code at 19:42:50Z, so the live tables carry the columns) |
|
||||
| C13 | `/api/supply` `max_supply_ign` 4,000,000,000 against `minted_at_end_ign` about 3,963,000,000 (the ramp withholds about 37 M, the floors the rest); the live tables lack `number`, `tx_count`, `detail` until the observer restarts | `site/api/supply.mjs` 31 to 48; `docs/plans/explorer.md` "Open" | everyone who reads the explorer beside the homepage tile "4B IGN hard cap, ever" (`site/index.html` 386) | The tile says 4 billion and the explorer page says "of 4,000,000,000 by the rule" while the API's own end figure is 3.963 billion: a reader who adds the two columns finds 37 million missing. The explorer page shows "Circulating 0 IGN" on the devnet deployment until the observer restarts on the new code | The tile, the litepaper's supply line and the explorer carry "cap 4,000,000,000; about 3.96 billion ever minted" (the litepaper already says "approached and never reached"); the explorer does not go live before the observer restart lands the columns | explorer a76f60b415859b7b5; wording: the founder (D7, with D3) | closed (explorer 3e01212: the tile reads "cap 4,000,000,000, 3.96 billion ever minted, x% so far" with the withheld figure on hover; the homepage tile and litepaper wording stay with the founder, D3 and D7; the zero-circulating premise was sharper than stated, a 42703 failure not a null, now a 503 with the reason, and moot: the live observer restarted on the explorer code at 19:42:50Z, so the live tables carry the columns) |
|
||||
| C14 | The M16 mixer x4 decided into class v3 at 22:00 (coordinator): verifier 1.6 to 4.8 ms per warp against 0.441 ms today (0.87 cold), measurement running on branch ca2-mixer | coordinator's reply 21:5x; `docs/analysis/m16-recompute-attacker-2026-10-05.md` table; spec 09 section 9.8 item 5 | pool operators; every node (the Hetzner seeds, the observer, a 2019-class laptop); the 10 ms verify gate | At x4 one pool core verifies 200 to 600 shares a second instead of 2,270, so one core covers 2,000 to 6,000 members at one share per 10 s instead of 22,000; a block's CPU re-check and the miner's own `cpu re-check` of every found hash cost 4 to 11x; the seeds' small VMs verify every header at that cost; the gate's margin falls from 23x to 2 to 6x, which bounds Counter ASIC 3.0's room | The coordinator is adding the numbers to the ca2-mixer document and the status (said in reply); the reviewer checks at the next sweep that the pool-members-per-core and the seed-VM header-verify rows are there, and that the spec 09 figure 2,270 shares a second per core is re-cut with v3 | coordinator ada8afb62d752b1e2 | closed with C19 (the same measurement: x4 is 1.45x and x8 2.1x the verifier, not 4 to 11x; a pool core verifies 1,140 shares a second at x4 and 790 at x8 quiet) |
|
||||
| C15 | A full prototype shard peaks at 28.3 GB on sp1-gpu-server 6.8.1 (the sweep, proving agent 22:0x); an empty one 13.9 GB; no knob moves either floor | proving agent's reply; sweep job `memsweep-pc2-pv1` | 24 GB cards (4090, 7900-class if it had a path); the 5090 that mines and proves; the fleet table | A 24 GB card cannot prove a prototype full shard at all, mining or not; a 5090 mining (3.4 GB resident) plus a full shard is 31.7 GB against 31.8 GB, the edge. The 20 GB / 16 GB default rests on the empty-shard number. From H tomorrow the fleet proves v1 shards of 30,000 pgas (about 7 M cycles, a ninth of the prototype shard) whose peak is unmeasured; `proving/fixtures/fees-v1-shards2` and `-shards3` are that shape. The fleet table's "proving-only" rows are 32 GB-card rows until then; the litepaper's "12 GB" (D2) and the evidence row 16 fall with it | The sweep's last row is a v1-budget shard with and without the miner, and the provedefault gates are set from it before 0.3.11 ships default-on; the fleet table labels its rows by the card that fits | proving v1 | closed as measured (proving agent, the S_p curve, app default 440fd59): 32 GB mines and proves today (28.3 GB alone, 30.0 beside the miner); 24 GB proves the adopted 30,000-pgas shard (20.4 GB alone, about 22 GB beside the miner) from DAA 210,000 and nothing before it; 16 GB proves only empty shards alone (13.9 GB), nothing beside the miner (15.7 GB); 12 GB proves nothing on SP1 6.8.1; the default is on at 24 GB or more. Relayed to the rig installer and the HiveOS words sub-agent for their tables; until H tomorrow every prover on the devnet is a 32 GB card |
|
||||
| C16 | PC 2's app quit at 20:01:09Z ("aborted (the app is quitting)"), logged by the proving agent as "the app quit for the 0.3.10 update"; the shipper says nothing of 0.3.10 was published and no update-now of its exists (the live manifest is 0.3.9 from 17:59:14Z) | bench-log "proving v1" chain run 1; the shipper's reply 22:0x | every measurement on PC 2 that straddles 20:01Z (the prover-cost phase B ended 19:51Z, the chain re-run began 20:05Z, the readwidth 5090 job queued) | An app that quits for an unknown reason voids any number taken across it (CLAUDE.md: a number taken while another build or simulation ran is not a number; the same for a restart). The bench-log line names a cause that did not happen | The proving agent reads PC 2's app log for the quit reason at 20:01Z and corrects the bench-log line; if the cause is another agent's job or the auto-update, that agent's measurements across it are marked | proving v1 (the log read); the agent the cause names | closed in part (proving agent: PC 2 logged "quit: stopping the miners, then the node" at 20:01:09Z, a plain quit command 20 s after the efficiency sweep's administrator prompt was cancelled at the keyboard and 13 s after the live prover failed on a root-owned /tmp/sp1-cuda-0.sock left by the chain job; the bench-log line corrected; the quit's origin is not in the log, see C17) |
|
||||
|
|
@ -35,10 +35,10 @@ Rows already handled before this ledger opened, for the shape: 15.6 GB mine-and-
|
|||
| C20 | Layer 9: the epoch length as an era parameter, 600 to 7,200 DAA s (10 min to 2 h), base 3,600 | status 22:30 and 23:00 | rigs (HiveOS and the rig installer), Macs, pools, the seed path | Both rig miners run `--exit-on-seed-change` and re-export the pack on exit 42 (h-run.sh 56 to 61, igneum-miner.sh 67 to 78): at a 10-minute epoch every card's miner restarts six times an hour with a pack export each time, and the restart gap is lost hashing; the app's prepare-ahead path does not restart. The Mac fleet's prepare pause (35 s an hour at one epoch an hour, bench-log M11) becomes 3.5 min an hour, 6%. The 10-minute seed VDF (spec 04) equals the shortest epoch, so the seed for epoch n+1 is known only as epoch n starts, which is the compile-ahead window the agent must measure per card (the 5090 compiled in 1,285 ms, the 9070 XT unmeasured). A pool's `job` cadence and the dev-fee counter are unaffected | The epoch-length document carries a per-tier row: rig restart cost per epoch length (and the fix: prepare-ahead in the rig scripts, no exit 42 path), the Mac pause share, the compile-ahead margin per card at 600 DAA s against the VDF; the rig installer removes `--exit-on-seed-change` in favour of the prepare path before layer 9 can draw a short epoch | ca2-epoch a32a3ece66c02417a; rig installer | closed with a correction (ca2-epoch 4300608, epoch-length.md sections 6.3, 7, 9): the rig scripts pass --prepare-packs as well, so a worker with prepare support swaps in place and exit 42 is the fallback on a prepare MISS (the loaded iGPU missed 2 of 10, M11), not a restart every epoch; the risk at 600 s is one restart plus export plus inline compile per missed boundary; the Mac race pause is 6.3% of a 600-s epoch (race default off); the program is known a full epoch ahead at every length (lead and T_epoch fixed, option A); the 9070 XT compile is OWED (no prepared line from gfx1201 in any upload); the rig installer (88f31d9) confirms the rig already takes the prepare path: exit 42 fires only when a worker's ready line lacks "prepare 1", and both shipped workers answer it; documented in its README, no code change |
|
||||
| C21 | OTA K2: apps embed `OTA_PUBLIC_KEYS = [K1, K2]` and honour a signed `revoked_keys` list; the rig installer verifies the manifest with ONE key (`OTA_PUBLIC_KEY_HEX`, install-rig.sh 168, igneum-update.sh 2) and knows no revocation; the HiveOS package verifies nothing (no manifest, the override reaches it only by republish) | ota-k2 c722579; packaging/linux; packaging/hive | rigs (both packages), the seeds (if they take the manifest) | The day K1 is lost or revoked and the manifest is signed with K2, every rig on the installer refuses the manifest, stops taking overrides, and is isolated at the next height switch; a leaked K1 keeps signing for rigs, because they carry no revocation list. HiveOS rigs get neither keys nor revocation: a republished package is their only path, and nothing checks who published it | The rig installer carries both public keys and the `revoked_keys` rule in the same form as the app (keys.md section 4, step 3), installed and read from the manifest; the HiveOS README states that the package is unsigned and names the sha256 the Flight Sheet URL should be checked against; keys.md lists the rig and HiveOS paths in its table of what trusts K1 | OTA key af2bb75a5436324d0 (keys.md, the shared verifier form); rig installer a3e7b2b03222f5cff | closed for the rig and the docs (rig installer 88f31d9: OTA_PUBLIC_KEYS [K1, K2 slot] embedded, manifest_check mirrors the app's manifest::check with the revoked_keys record at /var/lib/igneum/updates/revoked.json, tested on three throwaway keys; OTA agent 00fcbb5: keys.md table of every path that trusts K1, the HiveOS README unsigned-archive note); open: the wallet (wallet-v1) still trusts K1 alone, listed in keys.md for its owner; merge note: packaging/hive/README.md is edited on both ota-k2 and hive-words |
|
||||
|
||||
Sweep 3 (20:46 Mac clock) notes, no new row: the 9070 XT dropped off PC 1's bus at about 20:40 UTC (the second eGPU fault of the day); the coordinator stated the consequences (G1 on the gfx1036 stand-in, the 9070 XT v3 hash-rate and power rows owed, every earlier 9070 XT row stands, the AMD sweep queue item blocked, nobody woken) in its 21:05 and 21:10 entries and the rollout plan 7b. The epoch-length plan (ca2-epoch 4300608) carries its own per-tier table (section 7), including the node tier (one core 100% busy on the VDF at the 600-s floor) and the chain (24% of blocks in difficulty settle at the floor). The proving agent's 440fd59 rewrote the litepaper's two proving-gate sentences and evidence rows 15 and 16 on its branch (D2: the project lead approves the draft); the litepaper's card-lifetime sentence is untouched (D3, D4).
|
||||
Sweep 3 (20:46 Mac clock) notes, no new row: the 9070 XT dropped off PC 1's bus at about 20:40 UTC (the second eGPU fault of the day); the coordinator stated the consequences (G1 on the gfx1036 stand-in, the 9070 XT v3 hash-rate and power rows owed, every earlier 9070 XT row stands, the AMD sweep queue item blocked, nobody woken) in its 21:05 and 21:10 entries and the rollout plan 7b. The epoch-length plan (ca2-epoch 4300608) carries its own per-tier table (section 7), including the node tier (one core 100% busy on the VDF at the 600-s floor) and the chain (24% of blocks in difficulty settle at the floor). The proving agent's 440fd59 rewrote the litepaper's two proving-gate sentences and evidence rows 15 and 16 on its branch (D2: the founder approves the draft); the litepaper's card-lifetime sentence is untouched (D3, D4).
|
||||
| C22 | The SP1 CPU prover peaks at 29.5 to 30.5 GB RSS whatever the shard size and costs 282 s a shard (PC 1, `cpu-prove-pc1-small2`); no zkVM proves on AMD; the analysis concludes "no CPU tier" | `docs/analysis/amd-proving.md` sections 2, 3, 4a (amd-prove f1d7a7d, merged into ca2-coord) | Macs with 16 or 24 GB (the Settings switch turns the CPU prover on); AMD-only Windows and Linux machines (Settings can switch it on); every tier's expectation of the 20% share | provedefault.rs has a RAM gate for Windows (31,000 MB) and none for macOS or Linux, so a 16 GB Mac that flips the switch runs a 30 GB prover into swap and takes the node down with it (the Mac went down at 1% battery on 4 October; this is the same class of outage from memory). The analysis says the tile must say "about five minutes, paid only when no card proves first" but not that the switch is refused under 32 GB. The public tiers: AMD and Apple miners never see the 20% share on this build (now on the site, 1c8439f) | The CPU-prover switch is refused with the reason on every OS under 32 GB of RAM (the Windows constant generalised: macOS reads hw.memsize, Linux /proc/meminfo), and the tile line carries the 5-minute and 30 GB figures | proving v1 acd4f36bc2c07a4e2 | taken in full (proving agent: the prover loop refuses the CPU path on every OS under 32 GB, Settings cannot bypass it, with the line naming the machine's RAM; the tile line on CPU machines carries the 5-minute, 30 GB, paid-only-if-no-card figures; lands in the next app commit after the gate-test build; the "measured on a 32 GB card, not yet on a 24 GB card" marker is in evidence row 16, both litepaper sentences and the plan) |
|
||||
|
||||
Sweep 5 (21:08 Mac clock) notes: the coordinator applied the public proving line on ca2-coord (1c8439f: index, litepaper, miner page: "an NVIDIA card with 24 GB or more proves; AMD and Apple cards mine; a prover for them lands when a zkVM ships one") and the proving agent rewrote the litepaper's two gate sentences on proving-v1 (440fd59): two drafts of overlapping public sentences on two unpushed branches, both for the project lead (D2, D8); the integrator takes one. The measure-lock convoy (a0c3d13: a dead holder, two waiters, cargo tests re-acquiring build slots) is stated by the coordinator with a next-cut task. The S_p CPU shard job was dropped on the 312-s small-shard number (stated). GitHub Actions outage: the 0.3.10 installer builds on PC 1 (stated, 21:01).
|
||||
Sweep 5 (21:08 Mac clock) notes: the coordinator applied the public proving line on ca2-coord (1c8439f: index, litepaper, miner page: "an NVIDIA card with 24 GB or more proves; AMD and Apple cards mine; a prover for them lands when a zkVM ships one") and the proving agent rewrote the litepaper's two gate sentences on proving-v1 (440fd59): two drafts of overlapping public sentences on two unpushed branches, both for the founder (D2, D8); the integrator takes one. The measure-lock convoy (a0c3d13: a dead holder, two waiters, cargo tests re-acquiring build slots) is stated by the coordinator with a next-cut task. The S_p CPU shard job was dropped on the 312-s small-shard number (stated). GitHub Actions outage: the 0.3.10 installer builds on PC 1 (stated, 21:01).
|
||||
|
||||
## Round 3 (21:30 to 22:00 Mac clock)
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ Sweep 7 (21:49 UTC) notes, no new row: the hot table is measured and NOT adopted
|
|||
|
||||
| # | Number | Source | Tier affected | Consequence | Action | Owner | State |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| C26 | The 13.9 GB floor's cause: the shipped sp1-gpu-server 6.8.1 panics on any card under 24 GB (builder.rs 35 to 39) and allocates its core, recursion, shrink and wrap provers at Setup; the prover-floor agent rebuilds it from source on PC 2 with those sizes cut, CUDA_ARCHS=120 | proving-v1.md 4c82e56; status 22:01 | 12 and 16 GB NVIDIA cards (RTX 3060, 4070, 5070, 5080, 4060 Ti 16 GB): the tier the project lead asked for; packaging and signing | A server built for CUDA_ARCHS=120 runs on the 5090 only; the 12 GB tier is sm_86 (3060) and sm_89 (4070), the 16 GB tier sm_89 and sm_120, so a cut-size server measured on the 5090 proves nothing about a 3060 until the on-order 3060 runs it, and the build must list sm_86, sm_89, sm_120 (sm_100 is datacentre) to serve the tier at all. Shipping our own 250 MB CUDA server means the project signs and distributes a build of someone else's prover: it enters the DMG and the WSL2 package, the K1-signed inputs, the SBOM-style notes in evidence.md, and every SP1 upgrade is re-done by hand. Cut buffer sizes do not change the verifying key (prover-side chunking), so no guest re-pin, but the recipe must say so with a verify-segment run on a proof from the rebuilt server | The prover-floor measurement states its arch list and the card it ran on; the 12 GB claim waits for the 3060; the rebuilt server's packaging path (who builds, who signs, where it lands) is a row in the proving plan before 0.3.12, and the public line keeps "24 GB" until the 3060 proves on it | prover-floor agent (through the coordinator); proving v1 | taken (the proving plan carries "A self-built CUDA server (the 12 GB path), before 0.3.12": arch list sm_86 / sm_89 / sm_120 with one measured row per family, the build on PC 1 from a pinned SP1 tag, the Mac signs, placement as wsl2/bin/sp1-gpu-server with its sha256 in payload-inputs.json and the DMG, the evidence.md note, the rebuild at each SP1 upgrade, the gate that verify-segment and verify show the pinned keys unchanged; the 12 GB claim waits for the 3060; the prover-floor agent abefda4c3872f866f has the measurement side) |
|
||||
| C26 | The 13.9 GB floor's cause: the shipped sp1-gpu-server 6.8.1 panics on any card under 24 GB (builder.rs 35 to 39) and allocates its core, recursion, shrink and wrap provers at Setup; the prover-floor agent rebuilds it from source on PC 2 with those sizes cut, CUDA_ARCHS=120 | proving-v1.md 4c82e56; status 22:01 | 12 and 16 GB NVIDIA cards (RTX 3060, 4070, 5070, 5080, 4060 Ti 16 GB): the tier the founder asked for; packaging and signing | A server built for CUDA_ARCHS=120 runs on the 5090 only; the 12 GB tier is sm_86 (3060) and sm_89 (4070), the 16 GB tier sm_89 and sm_120, so a cut-size server measured on the 5090 proves nothing about a 3060 until the on-order 3060 runs it, and the build must list sm_86, sm_89, sm_120 (sm_100 is datacentre) to serve the tier at all. Shipping our own 250 MB CUDA server means the project signs and distributes a build of someone else's prover: it enters the DMG and the WSL2 package, the K1-signed inputs, the SBOM-style notes in evidence.md, and every SP1 upgrade is re-done by hand. Cut buffer sizes do not change the verifying key (prover-side chunking), so no guest re-pin, but the recipe must say so with a verify-segment run on a proof from the rebuilt server | The prover-floor measurement states its arch list and the card it ran on; the 12 GB claim waits for the 3060; the rebuilt server's packaging path (who builds, who signs, where it lands) is a row in the proving plan before 0.3.12, and the public line keeps "24 GB" until the 3060 proves on it | prover-floor agent (through the coordinator); proving v1 | taken (the proving plan carries "A self-built CUDA server (the 12 GB path), before 0.3.12": arch list sm_86 / sm_89 / sm_120 with one measured row per family, the build on PC 1 from a pinned SP1 tag, the Mac signs, placement as wsl2/bin/sp1-gpu-server with its sha256 in payload-inputs.json and the DMG, the evidence.md note, the rebuild at each SP1 upgrade, the gate that verify-segment and verify show the pinned keys unchanged; the 12 GB claim waits for the 3060; the prover-floor agent abefda4c3872f866f has the measurement side) |
|
||||
| C27 | The root-socket fault recurred at 21:25Z from another agent's job (agg-cost-pc2-1) after the class fix and CI check landed; PC 2's prover was dark 37 minutes; a resume at 21:25 answered ok without restarting the miners | bench-log 1d78979; status 21:45, 22:03 | every PC job; the devnet's proving and hash rate tonight | The class check lives in CI, but PC jobs are published from worktrees by `publish-jobs.sh` and never pass through CI before they run, so a job written on a branch without the check runs the old shape. The check must run where the job is published, not only where the repo is tested | `packaging/ota/publish-jobs.sh add` runs `tools/ci/prover-socket-check.sh` and the bash-body check on the script it publishes and refuses on a failure; the sub-agent on the bash-body check wires both; the resume defect is on the next-cut list (stated) | sub-agent bash-body-check (the wiring); coordinator (the rule) | closed on branch bash-body-check 6805125 (publish-jobs.sh add --kind run runs the bash-body check and prover-socket-check.sh before signing, refuses with the output, never skips; test-publish-jobs.sh 32 passed with four new refusals). Merge notes for the integrator: prover-socket-check.sh exists on both proving-v1 c2544be and this branch (add/add, take the superset here); the socket grep flags tools/amd-prove/pc1-cpu-prove.ps1 (CPU-only, -u root, no GPU server) so that job needs the cleanup lines or an allow-list entry before its next publish, told to the coordinator |
|
||||
|
||||
Sweep 8 (22:09 UTC) notes: mixer x8 DECIDED into v3 on the PC rows (the daily 1 GiB build latency-bound on every card: 5090 23 to 25 ms, 9070 XT 72 to 77 ms at every multiplier; the chip row 0.92x with the 3x factor), so the public claim holds with margin (D5 re-cut); the verifier regression (2.2x) bisected to inlining in the mixer's fetch loop and fixed, so the quiet-core figures of C19 return to about 0.6 / 0.9 / 1.3 ms; G6 job 3 failed on a stale fork test (era inside the class), job 4 on the final tree; the integration merge into master has three known conflicts (bench-log append-only, packfile.h and host.c take the ca2-v3 side).
|
||||
|
|
@ -67,9 +67,9 @@ Sweep 8a (22:2x UTC) note: `docs/analysis/proving-methods.md` (branch proving-me
|
|||
Sweep 9 (22:2x UTC) notes: the devnet at 22:24:31Z reads DAA 136,578, 0.909 blocks/s measured over the stats window and 1.005 DAA/s averaged since the fee-switch plan's 15:40Z read (112,227), so H = 210,000 lands between about 18:50 and 19:35 UTC on 6 October, up to an hour EARLIER than the 19:50Z written in fee-switch-devnet.md, the rollout plan 7a and release-0.3.10.md; the 16:00Z check (D1) keeps about 2.8 hours of margin and stands; the plans' ETA is re-cut in D1 and sent to the coordinator. Gates tonight: G3, G4, G6 green on the final class (x8 + era); G4b added (the Mac app passes --prepare-packs only to non-Metal workers, so every Mac would stop at the first v3 epoch: found by the node agent, the fix with a unit test and a real Metal gate run before the ship); G1 and G2 on the PC 1 job since 22:16.
|
||||
|
||||
Merge note for the integrator (22:3x UTC): branch `consequences` is docs/plans/consequences-2026-10-05.md and consequences-decisions.md only (base ca8d9f3); a merge-tree against master 1f0d62c shows 0 conflicts. Branch `bash-body-check` (7adb1ca, 6805125, e3bd761) carries tools/ci/bash-body-check.sh, kit-path-check.sh, the copied prover-socket-check.sh (add/add with proving-v1's: take bash-body-check's), ci.yml steps, the publish-jobs.sh gate and packaging/README-ship.md; it is on the coordinator's ship order after ca2-coord.
|
||||
| C31 | The copy the ship takes (ca2-coord at 22:3x): litepaper line 562 "12 GB or more proves full shards" beside line 452 "Proving needs an NVIDIA card with 24 GB or more"; evidence row 16 still "A 12 GB card proves one shard in about 20 s, designed" while proving-v1 440fd59 withdrew it; line 562 states the dataset "doubles on a step schedule fixed at genesis (years 4, 12 and 28)" | ca2-coord site/litepaper.html 452 and 562, docs/evidence.md 43; proving-v1 440fd59; D4 | every reader of the litepaper; the integrator; the project lead's D4 | One page says 12 GB and 24 GB for the same thing; the evidence table on the ship branch contradicts the measurement, and the two branches will conflict on evidence.md and litepaper.html at the merge (ship order: ca2-coord before proving-v1), so the stale row can win by accident; and the step schedule is written as a genesis fact while the coordinator's own 22:50 entry calls mapping (b) a recommendation for the project lead (gate 1, D4): a public page should not decide a genesis parameter before he does | On ca2-coord: strike "12 GB or more proves full shards" from line 562 (line 452 is the sentence); take proving-v1's evidence row 16 (WITHDRAWN, 24 GB measured) at the merge and say so in the merge plan; write the growth sentence as the recommendation it is ("the plan is a step schedule ... decided at gate 1") until D4 is taken | coordinator ada8afb62d752b1e2 | closed on ca2-coord a7be43f and 0d9b23d (the 12 GB clause struck; the merge rule "take proving-v1's row 16 and its proving sentences" in the rollout plan; one wording in all five places, "the proposed schedule, fixed at the testnet genesis: 2 GB, doubling at years 4, 12 and 28", the lifetime sentences kept as consequences of the proposal and marked approximate) |
|
||||
| C31 | The copy the ship takes (ca2-coord at 22:3x): litepaper line 562 "12 GB or more proves full shards" beside line 452 "Proving needs an NVIDIA card with 24 GB or more"; evidence row 16 still "A 12 GB card proves one shard in about 20 s, designed" while proving-v1 440fd59 withdrew it; line 562 states the dataset "doubles on a step schedule fixed at genesis (years 4, 12 and 28)" | ca2-coord site/litepaper.html 452 and 562, docs/evidence.md 43; proving-v1 440fd59; D4 | every reader of the litepaper; the integrator; the founder's D4 | One page says 12 GB and 24 GB for the same thing; the evidence table on the ship branch contradicts the measurement, and the two branches will conflict on evidence.md and litepaper.html at the merge (ship order: ca2-coord before proving-v1), so the stale row can win by accident; and the step schedule is written as a genesis fact while the coordinator's own 22:50 entry calls mapping (b) a recommendation for the founder (gate 1, D4): a public page should not decide a genesis parameter before he does | On ca2-coord: strike "12 GB or more proves full shards" from line 562 (line 452 is the sentence); take proving-v1's evidence row 16 (WITHDRAWN, 24 GB measured) at the merge and say so in the merge plan; write the growth sentence as the recommendation it is ("the plan is a step schedule ... decided at gate 1") until D4 is taken | coordinator ada8afb62d752b1e2 | closed on ca2-coord a7be43f and 0d9b23d (the 12 GB clause struck; the merge rule "take proving-v1's row 16 and its proving sentences" in the rollout plan; one wording in all five places, "the proposed schedule, fixed at the testnet genesis: 2 GB, doubling at years 4, 12 and 28", the lifetime sentences kept as consequences of the proposal and marked approximate) |
|
||||
| C32 | The 0.3.10 install at 21:49Z cleared PC 1's app jobs folder and with it the AMD kit fetched at 21:23:59Z; the amd-card-test playbook now says its fetch must be republished after any app update | bench-log 39f02ff; status 21:05 ("the jobs folder is cleared by fetch jobs" was the earlier, wrong reading) | every PC job tonight and tomorrow; the 0.3.11 rollout | A class, not one playbook: every fetch-then-run pair (era, hot table, mixer, repro, Ember, the AMD sweep, the prover-floor build) loses its kit when an update lands between the fetch and the run, and the run fails in seconds or, worse, runs against a stale copy. The 0.3.11 update-now reaches PC 2 while the prover-floor agent's 60 to 90 minute server build runs there (go at 22:17, to about 23:50): if that build's working directory is under the app's jobs folder, the update wipes it mid-build and the 12 GB rows slip past the morning | (1) The 0.3.11 update-now is sequenced after the prover-floor build closes, or the build's directory is confirmed outside the jobs folder before the ship; (2) every run playbook begins with a presence check of its kit and fails with "kit missing: republish the fetch after the app update" (the class check: the bash-body sub-agent's CI check gains a rule that a run job naming a kit path tests it first, or the coordinator's queue re-fetches after every update as a rule) | coordinator ada8afb62d752b1e2 (the queue and the ship order) | taken (coordinator: the prover-floor build lives under /opt/igneum-floor in WSL2, outside the jobs folder, but it is the app's job process and an app restart ends it, so the 0.3.11 update-now goes to PC 2 only after floor-build-3 closes, the ship's earlier steps not waiting; the re-fetch rule and the presence-check rule are in the rollout plan beside the one-job rule, the playbook owners carry it at their next publish; the CI side is with the bash-body sub-agent as a kit-path check). CI side closed on bash-body-check e3bd761: tools/ci/kit-path-check.sh in ci.yml and in publish-jobs.sh add --kind run (34 tests pass); every existing kit-using playbook (13 across master, ca2-v3, ca2-analysis, rdna4-telemetry) already checks before use, so the gate guards the shape without a backlog |
|
||||
| C33 | `/api/live` at 22:33Z: 13 of 482 blocks fully proven in 10 minutes (2.7%), 1 prover, median proof lag 46 s, the live node's verifier "Off" with 42 pool entries pending and 0 verified; `/api/stats` (the documented public API) carries no proving field at all | live and stats handlers (`site/api/stats.mjs` FIELDS; the explorer branch 3e01212); the homepage "~60 s to a proof"; evidence row 15 | everyone who reads the public API or the homepage tile; the testnet's first external reader | The public stats API hides the one number that qualifies the tile and row 15: coverage is 2.7% with one prover, and the proof lag is 46 s. A reader can find it only on /api/live. The live node's verifier "Off" (42 pending, 0 verified) is the Mac app node in trust mode or without a host, so the page says "verifier Off" while the chain pays provers: a public-page oddity the morning reader will ask about | `/api/stats` gains a `proving` object from the same live_state (`blocks_10m`, `blocks_fully_proven_10m`, `shards_paid_10m`, `provers_10m`, `median_proof_lag_s`, `active`), documented in docs/api/public-stats.md and in its contract test; the live page's verifier line names which node it reads and why it is off; the homepage tile's "~60 s" caption cites the measured 46 s median and the 2.7% coverage ("the target; today one prover covers 2.7% of blocks at a 46 s median") | explorer a76f60b415859b7b5 (the API); the tile caption: D2 wording for the project lead | closed on explorer d7e797c (/api/stats carries the proving object with coverage_10m, 0.0273 at 22:33Z, in the contract test, the live check and docs/api/public-stats.md with the sentence that coverage is what a third party reads before "every block is proven"; the live page's proving legend and the API note say the observer's node runs its own verifier off and reads paid shards from the chain). The homepage tile caption stays with the project lead (D2) |
|
||||
| C33 | `/api/live` at 22:33Z: 13 of 482 blocks fully proven in 10 minutes (2.7%), 1 prover, median proof lag 46 s, the live node's verifier "Off" with 42 pool entries pending and 0 verified; `/api/stats` (the documented public API) carries no proving field at all | live and stats handlers (`site/api/stats.mjs` FIELDS; the explorer branch 3e01212); the homepage "~60 s to a proof"; evidence row 15 | everyone who reads the public API or the homepage tile; the testnet's first external reader | The public stats API hides the one number that qualifies the tile and row 15: coverage is 2.7% with one prover, and the proof lag is 46 s. A reader can find it only on /api/live. The live node's verifier "Off" (42 pending, 0 verified) is the Mac app node in trust mode or without a host, so the page says "verifier Off" while the chain pays provers: a public-page oddity the morning reader will ask about | `/api/stats` gains a `proving` object from the same live_state (`blocks_10m`, `blocks_fully_proven_10m`, `shards_paid_10m`, `provers_10m`, `median_proof_lag_s`, `active`), documented in docs/api/public-stats.md and in its contract test; the live page's verifier line names which node it reads and why it is off; the homepage tile's "~60 s" caption cites the measured 46 s median and the 2.7% coverage ("the target; today one prover covers 2.7% of blocks at a 46 s median") | explorer a76f60b415859b7b5 (the API); the tile caption: D2 wording for the founder | closed on explorer d7e797c (/api/stats carries the proving object with coverage_10m, 0.0273 at 22:33Z, in the contract test, the live check and docs/api/public-stats.md with the sentence that coverage is what a third party reads before "every block is proven"; the live page's proving legend and the API note say the observer's node runs its own verifier off and reads paid shards from the chain). The homepage tile caption stays with the founder (D2) |
|
||||
|
||||
Sweep 11 (22:38 UTC) notes, no new row: gate G4b GREEN (a real Metal miner across a v3 boundary; a second Metal-only fault found and fixed first, 00c55aa: serveDataset keyed the day dataset by day alone and would have hashed v3 over an x1 dataset; the coordinator's next-cut rule: every worker path mines across a boundary in the gate network before a class change ships). The reviewer checked the PCs' side of that class: the CUDA worker and the OpenCL host build each resident pair (program, cache, dataset) from the pack's own memhard.h and key it by (epoch, day, class, era) through pairIsClass (proto-cuda/nvrtc/worker.cpp 451, proto-opencl/host.c 1106 on ca2-v3 fa3c932), so the fault does not reach the PCs at N4. The patched sp1-gpu-server built green on PC 2 at 22:32:29Z with sm_86, sm_89, sm_120 (C26's arch list), the floor sweep (9 points) running; the integration merges (readwidth 30ff674, origin/master 1f0d62c) on ca2-v3 49c7e78 with every check green. All gates but G5 (the ship's build) are green; the ship waits on the merged tip.
|
||||
| C34 | The rollout plan's packaged override line (counter-asic-2-rollout.md 26) carries five switches: difficulty_v2 33000, proving_v0 84100, fees_v1 210000, finality_v3 135200, program_class_v3 N4; section 8a says 0.3.11 publishes ONE object with both activations set | counter-asic-2-rollout.md 26 and 8a; proving-v1.md (the four v1 fields enter the digest only once proving_v1_activation_daa is set) | every node and every prover on the devnet at the 0.3.11 publish | If the publisher copies line 26, proving v1 ships in the binary and never activates: proving_v1_activation_daa stays at never on every node, the digest is the five-field one, the segment records are never carried, and C1's fix (the export fields) still works but the aggregator, the chain rule and the unproven rule stay off while the plan and the public copy say they are live. The four fields (activation_daa H1 = tip + 14,400 at publish, segment_blocks 8, unproven_daa 600, aggregator_share_bps 1000) must be in the packaged line, the manifest object, the hand nodes' and the seed's files, verbatim, and the expected digest read on a scratch node with all nine fields | Line 26 and the ship step name the nine-field object with N4 and H1 both set at publish and the scratch-node digest read over that object (the 22:xx "expected 0.3.11 digest with the two new fields at never" is the rolling-upgrade digest, not the activation one; both are recorded) | coordinator ada8afb62d752b1e2 (the ship runbook) | sent |
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# Consequence decisions for the project lead (night of 5 October 2026)
|
||||
# Consequence decisions for the founder (night of 5 October 2026)
|
||||
|
||||
Sibling of `ledger-decisions.md`. Each is a consequence of a measured number that needs the project lead: money, a public claim, or a consensus parameter outside tonight's delegation. The row number points at `consequences-2026-10-05.md`. Recommendation first, then the options.
|
||||
Sibling of `ledger-decisions.md`. Each is a consequence of a measured number that needs the founder: money, a public claim, or a consensus parameter outside tonight's delegation. The row number points at `consequences-2026-10-05.md`. Recommendation first, then the options.
|
||||
|
||||
## The eleven in one glance (what the project lead does, in the order they bite)
|
||||
## The eleven in one glance (what the founder does, in the order they bite)
|
||||
|
||||
| # | By when | One line | What the project lead does |
|
||||
| # | By when | One line | What the founder does |
|
||||
|---|---|---|---|
|
||||
| D1 | 16:00 UTC, 6 October | The fee switch at H = 210,000 (about 18:45 UTC by the devnet's DAA rate at 22:33Z, 1.002 DAA/s since 15:40Z; an hour earlier than the plans' 19:50) darkens every 0.3.10 prover; 0.3.11 must be on every prover first, else H moves | Nothing if the morning check passes; the coordinator holds it. Know it exists |
|
||||
| D9 | this week | No 12 GB card exists here; every 12 GB number is scaled from the 5090 | Confirm whether the 3060 and 5060 Ti 16 GB that evidence.md says are on order are real; if not, buy one 12 GB card (about £250 to £400) |
|
||||
|
|
@ -20,13 +20,13 @@ Sibling of `ledger-decisions.md`. Each is a consequence of a measured number tha
|
|||
| # | Row | What needs deciding | Recommendation | Why |
|
||||
|---|---|---|---|---|
|
||||
| D1 | C1 | The fee switch lands at H = 210,000 about 19:50Z on 6 October, and the 0.3.10 node's export does not carry the switch, so every app prover's shards are refused or vetoed from H. Move H, or race 0.3.11 onto every prover first | If 0.3.11 (with the proving-v1 fork, whose export carries `daaScore` and `feesV1ActivationDaa`) is not on every prover by 16:00Z on 6 October, republish the override with H = tip + 86,400 rounded to the next thousand, re-read the digest on a scratch node, every node in one sweep (the fee-switch plan's own rule for a later H). The coordinator holds the devnet delegation; this note is so the morning does not find proving dark | A dark proving pool on the devnet costs nothing on chain (the escrow keeps it) but every coverage, latency and fleet number measured after H is void |
|
||||
| D2 | C3 | The litepaper says "12 GB or more proves full shards"; the only measurement puts the prover alone at 13.8 GB on a 32 GB card | The sweep and the S_p curve are in (proving agent, 5 October late): no knob moves the floor; 12 GB proves nothing on SP1 6.8.1, 16 GB proves only empty shards alone, 24 GB proves the adopted 30,000-pgas shard (20.4 GB alone, about 22 GB beside the miner), 32 GB proves everything. Change the sentence to "24 GB or more proves; 32 GB proves and mines on one card" and evidence row 16 to tested-by-the-team on those rows; the 12 GB figure returns only if a smaller GPU server or a smaller shard measures under 12 GB. The proving agent has drafted the two replacement sentences on its branch (app 440fd59, litepaper and evidence rows 15 and 16); nothing is pushed, so the project lead approves or rewrites the draft rather than starting from the measurement. Two drafts exist: the proving agent's litepaper sentences (proving-v1 440fd59) and the coordinator's site, litepaper and miner-page line (ca2-coord 1c8439f); the integrator keeps one. One marker is owed on either: the 24 GB figure is the 5090's allocation pattern on a 32 GB card (22.2 GB beside the miner), not a measurement on a 24 GB card, and evidence rule 3 wants that said until a 4090 or a 5080-class 24 GB card runs it | A public number that the first 3060 owner disproves is the FUD the ledger exists to prevent |
|
||||
| D2 | C3 | The litepaper says "12 GB or more proves full shards"; the only measurement puts the prover alone at 13.8 GB on a 32 GB card | The sweep and the S_p curve are in (proving agent, 5 October late): no knob moves the floor; 12 GB proves nothing on SP1 6.8.1, 16 GB proves only empty shards alone, 24 GB proves the adopted 30,000-pgas shard (20.4 GB alone, about 22 GB beside the miner), 32 GB proves everything. Change the sentence to "24 GB or more proves; 32 GB proves and mines on one card" and evidence row 16 to tested-by-the-team on those rows; the 12 GB figure returns only if a smaller GPU server or a smaller shard measures under 12 GB. The proving agent has drafted the two replacement sentences on its branch (app 440fd59, litepaper and evidence rows 15 and 16); nothing is pushed, so the founder approves or rewrites the draft rather than starting from the measurement. Two drafts exist: the proving agent's litepaper sentences (proving-v1 440fd59) and the coordinator's site, litepaper and miner-page line (ca2-coord 1c8439f); the integrator keeps one. One marker is owed on either: the 24 GB figure is the 5090's allocation pattern on a 32 GB card (22.2 GB beside the miner), not a measurement on a 24 GB card, and evidence rule 3 wants that said until a 4090 or a 5080-class 24 GB card runs it | A public number that the first 3060 owner disproves is the FUD the ledger exists to prevent |
|
||||
| D3 | C8, C13 | The homepage says "Any 4 GB card" and the litepaper says a 4 GB card mines for about four years and an 8 GB card for more than a decade; the tile says "4B hard cap" while the rule mints about 3.96 billion | Replace with the lifetime table's numbers once the sub-agent lands it: "4 GB cards mine at launch; 8 GB for about six years; 12 GB for about fourteen; the dataset grows half a gigabyte a year" and "cap 4 billion, about 3.96 billion ever minted" | The schedule is public and the arithmetic is one line; a reader will do it |
|
||||
| D4 | C9, C8 | Index mapping at gate 1, now with the lifetime table (`docs/analysis/card-lifetime-2026-10-05.md`): (a) multiply-shift, continuous growth: 4 GB cards out at 1.0 to 1.5 years, 8 GB at 6.3 to 7.5, 12 GB at 12 to 13.5, Apple 8 GB at 2.6 to 3.4; (b) power-of-two steps at years 4, 12, 28, 60: 4 GB to year 4, 8 GB to year 12, 12 GB to year 28 (the cache freed after the build, decided by the coordinator at 22:50), each tier ending on a step day | (b), with the step calendar published on the miners page from day one (the years 4, 12, 28 and 60 named beside the tiers), and the 1 GiB vectors kept. Revised from (a) at 23:0x: the table shows (b) is the only mapping under which the litepaper's "4 GB about four years, 8 GB more than a decade" holds, and a step day known twelve years ahead is a schedule, not an event; the coordinator recommends the same | Under (a) both public sentences are wrong today by 2.5 to 5 years; under (b) they hold and the cliffs are dated |
|
||||
| D5 | C10 | The site's "under 2x" chip claim: the scratch layer leaves the on-die-cache recompute chip at 2.4x at every share; the mixer multiplier x2 brings it to 1.2x at twice the CPU verify cost (about 0.9 ms per warp, half the pool members per core) | Overtaken by the coordinator's delegated decisions (21:50 to 21:28 Mac clock): the public claim was qualified, the mixer x4 is in class v3 (chip row 0.61x bare, 1.84x with a 3x fixed-function factor, 1.53x at equal silicon with the mirror deducted: "under 2x" holds on the equal-silicon convention and is thin), and x8 is built and measured beside it (0.92x with the factor, from the M16 table); x8 goes in if the verify stays under 10 ms and the daily build under 1 s on every card we own (C23 asks that the iGPU tier be named in that rule). Measured at 21:40 UTC (ca2-mixer 54bbfcc): x8 is 2.1x the v2 verifier (2.79 ms per warp on a loaded core, 1.26 quiet by scaling), 7.1 ms of the 10 ms gate left, the Mac 1 GiB build flat at 21 ms; the verify half of the x8 rule passes, the PC build rows are owed. Then at 22:06 UTC x8 was decided into v3 on the PC build rows (latency-bound on every card): the chip row reads 0.92x with the 3x fixed-function factor, so "under 2x" holds with margin and the level 3 page can state the convention and the margin. For the project lead: confirm "under 2x" stays, now with the measured row behind it | The claim is the project's first public sentence on chips; it is either true by a measured lever or it is marked |
|
||||
| D6 | C11 | Whether class v3 should favour AMD (fewer, wider loads per hash) at a cost to the 5090's latency-bound share, or accept that AMD cards mine at about a seventh of a 5090 and 4.5x the electricity per hash | Accept it for v3 and say so on the miners page ("NVIDIA first; AMD mines at a lower rate per watt on this class"); open the AMD question as a Counter ASIC 3.0 item with its own measurement | Tonight's rule was the project lead's and the 5090 margin is the anti-chip argument; AMD's position is a public-copy question, not a gate |
|
||||
| D5 | C10 | The site's "under 2x" chip claim: the scratch layer leaves the on-die-cache recompute chip at 2.4x at every share; the mixer multiplier x2 brings it to 1.2x at twice the CPU verify cost (about 0.9 ms per warp, half the pool members per core) | Overtaken by the coordinator's delegated decisions (21:50 to 21:28 Mac clock): the public claim was qualified, the mixer x4 is in class v3 (chip row 0.61x bare, 1.84x with a 3x fixed-function factor, 1.53x at equal silicon with the mirror deducted: "under 2x" holds on the equal-silicon convention and is thin), and x8 is built and measured beside it (0.92x with the factor, from the M16 table); x8 goes in if the verify stays under 10 ms and the daily build under 1 s on every card we own (C23 asks that the iGPU tier be named in that rule). Measured at 21:40 UTC (ca2-mixer 54bbfcc): x8 is 2.1x the v2 verifier (2.79 ms per warp on a loaded core, 1.26 quiet by scaling), 7.1 ms of the 10 ms gate left, the Mac 1 GiB build flat at 21 ms; the verify half of the x8 rule passes, the PC build rows are owed. Then at 22:06 UTC x8 was decided into v3 on the PC build rows (latency-bound on every card): the chip row reads 0.92x with the 3x fixed-function factor, so "under 2x" holds with margin and the level 3 page can state the convention and the margin. For the founder: confirm "under 2x" stays, now with the measured row behind it | The claim is the project's first public sentence on chips; it is either true by a measured lever or it is marked |
|
||||
| D6 | C11 | Whether class v3 should favour AMD (fewer, wider loads per hash) at a cost to the 5090's latency-bound share, or accept that AMD cards mine at about a seventh of a 5090 and 4.5x the electricity per hash | Accept it for v3 and say so on the miners page ("NVIDIA first; AMD mines at a lower rate per watt on this class"); open the AMD question as a Counter ASIC 3.0 item with its own measurement | Tonight's rule was the founder's and the 5090 margin is the anti-chip argument; AMD's position is a public-copy question, not a gate |
|
||||
| D7 | C13 | Same as D3's supply wording | with D3 | |
|
||||
| D8 | C7 | The miner page says "One click: install, start, the card mines and proves" (site/miner.html 7, 13, 21; site/index.html 484). On HiveOS and the rig installer a rig mines only until a Linux prover build is published, and on the app a 12 GB card mines only, a 16 GB card proves with the miner paused, 20 GB and up does both (the sweep of 5 October, before the v1-shard row) | Qualify the sentence on the miner page and the homepage card: "the card mines; 24 GB cards prove too, 32 GB does both at once; rigs mine until the Linux prover ships". The same page's "a visible 1% software fee you can switch off" becomes "solo mining carries a 1% software fee you can switch off; in a pool the pool's own fee is the only one" once pool-v0 ships (the pool agent fixed the rule: no software dev fee in pool mode) | The sentence is the product's first promise and tonight's measurement bounds it by card |
|
||||
| D9 | C3, C15, C26 | No 12 GB NVIDIA card exists in the fleet, so every 12 GB number tonight is scaled from the 5090 and labelled approximate. The 13.9 GB floor is SP1's GPU server code (`docs/analysis/proving-methods.md`, branch proving-methods e7e0db7, section 1.3: builder.rs adds 4 GB to the card's physical memory and panics under 24, so a 16 GB card (16 + 4 = 20) and a 12 GB card never start and 20 GB is the smallest that does; the trace is allocated at the maximum shard; the CUDA mempool never releases; the proving plan's "under 24" (4c82e56) is the same test read before the addition). The prover-floor patch and the per-card profiles cannot be measured without the hardware | Buy one 12 GB NVIDIA card this week for PC 1's spare slot (an RTX 3060 12 GB or 4070 12 GB, about £250 to £400, approximate; the coordinator's request). Check first whether the RTX 3060 and the RTX 5060 Ti 16 GB that evidence.md row 16 says are "on order" are real and arriving; if so, no purchase, only the delivery date. No public line says "12 GB proves" before a real 12 GB card runs the rebuilt server on the S_p-curve fixtures and recipe | Money, and the one measurement every 12 GB claim rests on; the prover-floor agent's rows tonight replace the approximate figures when they land |
|
||||
| D10 | C3, C15, C26, C28 | The proving route for the 12 GB tier and for Apple: `docs/analysis/proving-methods.md` section 4 ranks (1) route A, a re-sized SP1 GPU server with `S_p` as the dial and one server per card on rigs, nothing in consensus moving; (2) route D, RISC Zero 3.0.x as proof-system version 2 (the only shipped prover with a documented sub-12 GB configuration and a Metal path), the fallback if A misses 11 GB and the Apple route either way, 3 to 4 days plus a 3-month two-verifier overlap and three spec 7.8 rules; (3) a sumcheck family without a codeword (Jolt-class) in years, not now. Route A is already running tonight; route D adds a second proof family to the node, which is a consensus and verifier change outside tonight's delegation | Route A on the prover-floor rows, gated as the document says (the adopted shard under 11 GB alone and under 60 s prove-only on a real 12 GB card, D9); route D's measurement (RISC Zero at po2 19 and 20 on PC 2 and the Mac's Metal row) may run as a measurement, but adopting a second proof family waits for the project lead and for route A's result; the public paragraph of section 5 ("Proving runs on NVIDIA cards with 24 GB or more today. A build for 12 GB and 16 GB cards is being measured ...") is the honest line meanwhile and is the one of the three drafts to prefer, because it names what is being measured instead of a tier | A second verifier in the node is the kind of change the testnet's genesis must carry from day one; measuring it costs nothing, adopting it is the project lead's |
|
||||
| D10 | C3, C15, C26, C28 | The proving route for the 12 GB tier and for Apple: `docs/analysis/proving-methods.md` section 4 ranks (1) route A, a re-sized SP1 GPU server with `S_p` as the dial and one server per card on rigs, nothing in consensus moving; (2) route D, RISC Zero 3.0.x as proof-system version 2 (the only shipped prover with a documented sub-12 GB configuration and a Metal path), the fallback if A misses 11 GB and the Apple route either way, 3 to 4 days plus a 3-month two-verifier overlap and three spec 7.8 rules; (3) a sumcheck family without a codeword (Jolt-class) in years, not now. Route A is already running tonight; route D adds a second proof family to the node, which is a consensus and verifier change outside tonight's delegation | Route A on the prover-floor rows, gated as the document says (the adopted shard under 11 GB alone and under 60 s prove-only on a real 12 GB card, D9); route D's measurement (RISC Zero at po2 19 and 20 on PC 2 and the Mac's Metal row) may run as a measurement, but adopting a second proof family waits for the founder and for route A's result; the public paragraph of section 5 ("Proving runs on NVIDIA cards with 24 GB or more today. A build for 12 GB and 16 GB cards is being measured ...") is the honest line meanwhile and is the one of the three drafts to prefer, because it names what is being measured instead of a tier | A second verifier in the node is the kind of change the testnet's genesis must carry from day one; measuring it costs nothing, adopting it is the founder's |
|
||||
| D11 | C29 context; `docs/plans/funding.md` 36 and 63 | The chip bounty on the public pages: "the model and the bounty are public" (hero, abstract, ca2-coord cabec3b), "bounty standing" (level 1 copy); funding.md: USD 50,000 standing, "Not funded", "a bounty is announced only when it is escrowed"; the litepaper already says "a bounty is attached" to the finality review (line 686) | Strike "and the bounty" from the hero and the abstract and "standing" from level 1 until the money is escrowed, and say "a bounty follows the external review" if a sentence is wanted; or escrow USD 50,000 (and the USD 25,000 finality bounty) and keep the words. Applied at 22:25 (ca2-coord 7e6f77c): "and the bounty" struck from the hero and the abstract, "standing" from level 1, the copy says "a bounty follows the external review"; the words return only once escrowed | A public promise of money the project has not set aside is the FUD the ledger exists to prevent, by the project's own funding rule |
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# Counter ASIC: the public description in four levels
|
||||
|
||||
the project lead, 5 October 2026 (night): "not an information overload". Four levels; the layer names appear only from level 3 down, next to their numbers. Numbers come from the final table of `docs/plans/counter-asic-2-status.md`; a number still owed is marked `[owed: ...]`, never guessed. the project lead's copy law throughout.
|
||||
The founder, 5 October 2026 (night): "not an information overload". Four levels; the layer names appear only from level 3 down, next to their numbers. Numbers come from the final table of `docs/plans/counter-asic-2-status.md`; a number still owed is marked `[owed: ...]`, never guessed. The founder's copy law throughout.
|
||||
|
||||
## Level 1: one sentence (site hero, litepaper abstract)
|
||||
|
||||
Built for graphics cards. A custom chip gains under 2x, and the model is public. (the project lead's decision of 6 October 2026, 17:35 UTC, ledger M1: no device bounty; the claim is backed by the paid independent cryptanalysis (CA 3.0 item 3, four paid reviews) and the public benchmark with M22's metrics; an optional USD 50,000 cryptanalysis prize may follow later, escrowed before it is named.)
|
||||
Built for graphics cards. A custom chip gains under 2x, and the model is public. (the founder's decision of 6 October 2026, 17:35 UTC, ledger M1: no device bounty; the claim is backed by the paid independent cryptanalysis (CA 3.0 item 3, four paid reviews) and the public benchmark with M22's metrics; an optional USD 50,000 cryptanalysis prize may follow later, escrowed before it is named.)
|
||||
|
||||
## Level 2: one site card, one short litepaper section
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ Site card placement: the Mine section of `site/index.html` beside "no chip can b
|
|||
|
||||
Headline of the chip model (5 October 2026, night): the strongest chip holds the whole 256 MiB cache on-die (about 128 mm^2 and $46 of silicon at N5 by shipped cache-die density, approximate) and computes dataset items on the fly; its gain over the RTX 5090 is 2.4x as the parameters stand, and no write-scratch share within an 8 GB card's budget changes that. The lever that does is the dataset item's mixer cost (x4: 1.8x with a 3x fixed-function factor, verifier 1.6 to 4.8 ms per warp). Decided 5 October 2026 (delegated): the mixer x4 and the cache growth rule enter class v3, so the headline row is the on-die-cache chip against v3 with everything combined. [owed: the combined row from docs/analysis/chip-model-v3.md; if it reads 1.8x, the claim is "under 2x" with the margin stated as thin, and the next levers are named: the mixer x8 and the hot table.]
|
||||
|
||||
Per card, the bench table: the v2 class and the v3 class, hash rate, bytes per hash, the latency-bound share (rate over the card's random-read ceiling per load), the CPU verifier per warp, with machine, date and command. The chip model before and after Counter ASIC 2.0 (the m16 model's gain arithmetic at the v2 class and at the v3 class, with the SRAM a mirror needs, cited or approximate as the analysis says). The benchmark terms (spec O-1.17: the leaderboard by card model and the paid independent cryptanalysis's published findings, January 2027; no device bounty by the project lead's decision of 6 October 2026). Here the layers are named next to their numbers: read width, per-program mix, scratch, era layout, working set, hot table, cache schedule, the reserved integer-matrix family.
|
||||
Per card, the bench table: the v2 class and the v3 class, hash rate, bytes per hash, the latency-bound share (rate over the card's random-read ceiling per load), the CPU verifier per warp, with machine, date and command. The chip model before and after Counter ASIC 2.0 (the m16 model's gain arithmetic at the v2 class and at the v3 class, with the SRAM a mirror needs, cited or approximate as the analysis says). The benchmark terms (spec O-1.17: the leaderboard by card model and the paid independent cryptanalysis's published findings, January 2027; no device bounty by the founder's decision of 6 October 2026). Here the layers are named next to their numbers: read width, per-program mix, scratch, era layout, working set, hot table, cache schedule, the reserved integer-matrix family.
|
||||
|
||||
| Card | v2 MH/s | v3 MH/s (era packs, six eras) | Bytes per hash | Latency-bound share | Verifier ms per warp (v2 / v3, one loaded M5 Max core) | Daily 1 GiB build (v2 / v3) |
|
||||
|---|---|---|---|---|---|---|
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -16,7 +16,7 @@ Coordinator's running status for the plan in `docs/plans/counter-asic-2.md`. Rew
|
|||
|
||||
Budget rule received from the coordinator at the restart: the per-warp scratch is capped so the whole working set (1 GiB table + hot table + scratch for every resident warp + buffers) stays under 6 GB on an 8 GB card, which puts the scratch in the tens of KB per warp; the layer 5 hot table shares that budget.
|
||||
|
||||
Decisions for the project lead so far: none. Nothing here touches consensus or any live node.
|
||||
Decisions for the founder so far: none. Nothing here touches consensus or any live node.
|
||||
|
||||
## 20:05 readwidth PC jobs out; the scratch finding
|
||||
|
||||
|
|
@ -35,9 +35,9 @@ Finding that bears on layer 3 (readwidth, Metal, M5 Max, capped sizes): the scra
|
|||
|
||||
Reading (readwidth agent): 4,096 warps x 32 KB = 128 MB sits in the chip's caches. Consequence for the decision: a scratch that fits a GPU's cache fits a chip's SRAM at the same size, so at the capped size the writes cost everyone a cache-bound op in place of a latency-bound load. Passed to the soundness agent: what size would make the writes cost DRAM latency, whether that fits the 6 GB cap, and whether the RMW share should be added to the 16 dataset loads rather than taken from them.
|
||||
|
||||
## 20:08 mandate: v3 on the devnet tonight, by the project lead's rules
|
||||
## 20:08 mandate: v3 on the devnet tonight, by the founder's rules
|
||||
|
||||
the project lead has gone to bed and delegated the three decisions for the DEVNET only (not the public testnet): width, per-load mix and scratch share by the rules now written in `docs/plans/counter-asic-2-rollout.md` section 6, the activation height = devnet tip + 14,400 at publish (checked >= 10,800), published the way finality v3 was. Six gates before any publish (rollout section 7): bit-exact v3 on the three cards; the CPU verifier exact on 1,000 random GPU hashes per card; the soundness suite green with the new scratch tests; the fast-time 3-node network mining across a v3 activation with 0 rejected blocks and 0 forks; Windows and Mac workers from one commit; the node change on a fork from the 0.3.10 tip (21d4c73c) with suites green on PC 2. Release 0.3.11 through the shipper's pipeline; the 0.3.10 shipper (ae892a8b0f78fe31c) has been asked for its state and the handoff. If a gate fails: stop, write why here, do not publish.
|
||||
The founder has gone to bed and delegated the three decisions for the DEVNET only (not the public testnet): width, per-load mix and scratch share by the rules now written in `docs/plans/counter-asic-2-rollout.md` section 6, the activation height = devnet tip + 14,400 at publish (checked >= 10,800), published the way finality v3 was. Six gates before any publish (rollout section 7): bit-exact v3 on the three cards; the CPU verifier exact on 1,000 random GPU hashes per card; the soundness suite green with the new scratch tests; the fast-time 3-node network mining across a v3 activation with 0 rejected blocks and 0 forks; Windows and Mac workers from one commit; the node change on a fork from the 0.3.10 tip (21d4c73c) with suites green on PC 2. Release 0.3.11 through the shipper's pipeline; the 0.3.10 shipper (ae892a8b0f78fe31c) has been asked for its state and the handoff. If a gate fails: stop, write why here, do not publish.
|
||||
|
||||
Node build note for the integration: the node links `igneum-pow` by path (`../../../../igneum-pow` from `consensus/pow` and `igneum/miner`), so the node fork worktree for v3 must live under the v3 worktree's `vendor/` so that the path resolves to the v3 crate, not master's.
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ Node fork for v3: base on COMMIT 21d4c73c (release-0.3.10 in vendor/igneum-node
|
|||
|
||||
0.3.11 shipper: the coordinator assigns it (the 0.3.10 shipper stops at its report). Inputs the ship needs: the fork commit with its PC 2 suite results recorded, the main tip, the override object with every switch (the four live fields plus program_class_v3_activation_daa), the expected digest read on a 22-s scratch node, the deadline note ("program class v3"), the activation height, the one-line changelog, and whether the pinned proving guest changes (it does not: the prover has no igneum-pow dependency; confirmed by grep of proving/igneum-prove Cargo files).
|
||||
|
||||
## 20:10 readwidth round 2 on the PCs; the width arithmetic under the project lead's rule
|
||||
## 20:10 readwidth round 2 on the PCs; the width arithmetic under the founder's rule
|
||||
|
||||
Round 1 of the readwidth PC jobs refused every pack (the workers demand a 32-byte chain seed; the experiment packs carried string seeds); fixed at readwidth 1ea7a52 (packfile.h), republished 20:09:19Z as `run-readwidth-5090-20261005c` (PC 2, about 6 min) and `run-readwidth-9070-20261005c` (PC 1, about 10 min). The era and cache agents were told to rebase onto 1ea7a52 and to prove their packs load on the Mac OpenCL host before any PC job. Every ca2 branch now bases on 1ea7a52.
|
||||
|
||||
|
|
@ -62,13 +62,13 @@ Probe ceilings from round 1 (dependent reads per second at 1024 MiB, device time
|
|||
| RTX 5090 | 17.5 G | 18.0 G | 9.1 G (584 GB/s) | 1,579 GB/s |
|
||||
| RX 9070 XT | 2.42 G | 2.43 G | 2.47 G (158 GB/s) | 636 GB/s |
|
||||
|
||||
the project lead's width rule applied to the ceilings alone (the measured v3 rates will replace this when the table lands): a 128-load hash at 64 B reads 8,192 B; at the 5090's 64 B ceiling that is 71 MH/s and 584 GB/s, 37% of its stream bandwidth, over the one-third margin the rule sets; at 16 B it is 2,048 B per hash, 141 MH/s and 288 GB/s, 18%, inside the margin; 4 B is 9%. On the 9070 XT every width costs the same line fetch (2.4 G/s), so 16 B is where AMD gains 4x the bytes per hash at no cost and the 5090 stays latency-bound with margin. Provisional width under the rule: 16 B (w16), pending the measured rates and the latency-bound share per card.
|
||||
The founder's width rule applied to the ceilings alone (the measured v3 rates will replace this when the table lands): a 128-load hash at 64 B reads 8,192 B; at the 5090's 64 B ceiling that is 71 MH/s and 584 GB/s, 37% of its stream bandwidth, over the one-third margin the rule sets; at 16 B it is 2,048 B per hash, 141 MH/s and 288 GB/s, 18%, inside the margin; 4 B is 9%. On the 9070 XT every width costs the same line fetch (2.4 G/s), so 16 B is where AMD gains 4x the bytes per hash at no cost and the 5090 stays latency-bound with margin. Provisional width under the rule: 16 B (w16), pending the measured rates and the latency-bound share per card.
|
||||
|
||||
Added deliverable (20:11): the public description in four levels, `docs/plans/counter-asic-2-public.md` (aec53bb): levels 1 and 2 are written as copy; level 3 carries the bench table with `[owed]` markers for every number not yet measured; level 4 lists the documents. The integration branch applies levels 1 to 3 to `site/index.html`, `site/litepaper.html` and `site/bench.html` with the final numbers.
|
||||
|
||||
## 20:15 layers 6 and 7 landed; the node-fork agent started; 0.3.11 scope
|
||||
|
||||
Branch ca2-analysis (5d5ba15, f59708d). Layer 6: no cache growth rule exists in the spec; cited bit cells N7 0.027, N5 / N3E / Intel 18A 0.021, N3B 0.0199, N2 0.0175 um^2, array factor 0.70; the 256 MiB mirror is 83 / 64 / 54 mm^2 at N7 / N5 / N2 (74 at N2 with a 96 MB hot table), $13 to $26 of silicon per good die (approximate). The mirror was never unaffordable; the cache's job is to stay above GPU L2 (5090 96 MB, GB202 128 MB). Recommendation C for the project lead (gate 1): cache doubles when the dataset doubles. Layer 7: Metal 4 matmul2d has int8 x int8 -> int32, so a unit-level mm8 tile is native on all three vendors; per-lane dot4 is emulation on Apple (M5 Max: 548 G unsigned dot4/s against an 880 G ALU chain, 1.6x; signed 4.7x). Reserve R1 = mm8, W_new 4, unlock era 4 or 90% signal. Owed: the 5090 and 9070 XT dot4 probe (job prepared: relay/playbooks/dot4-probe.ps1, exe sha256 5adaeb1a...6416f4; publishes when a PC frees).
|
||||
Branch ca2-analysis (5d5ba15, f59708d). Layer 6: no cache growth rule exists in the spec; cited bit cells N7 0.027, N5 / N3E / Intel 18A 0.021, N3B 0.0199, N2 0.0175 um^2, array factor 0.70; the 256 MiB mirror is 83 / 64 / 54 mm^2 at N7 / N5 / N2 (74 at N2 with a 96 MB hot table), $13 to $26 of silicon per good die (approximate). The mirror was never unaffordable; the cache's job is to stay above GPU L2 (5090 96 MB, GB202 128 MB). Recommendation C for the founder (gate 1): cache doubles when the dataset doubles. Layer 7: Metal 4 matmul2d has int8 x int8 -> int32, so a unit-level mm8 tile is native on all three vendors; per-lane dot4 is emulation on Apple (M5 Max: 548 G unsigned dot4/s against an 880 G ALU chain, 1.6x; signed 4.7x). Reserve R1 = mm8, W_new 4, unlock era 4 or 90% signal. Owed: the 5090 and 9070 XT dot4 probe (job prepared: relay/playbooks/dot4-probe.ps1, exe sha256 5adaeb1a...6416f4; publishes when a PC frees).
|
||||
|
||||
Node-fork agent a3f505a9d981300cd started 20:50: ca2-v3 (igneum-pow seam: ProgramClass, Epoch::from_chain_seeds, generator 3 in the program id, class in the pack) and ca2-v3-node (vendor/igneum-node-ca2 under the ca2-v3 worktree, from 21d4c73c, with pack-loop 05ef0fa3 merged): the field in Params, OverrideParams and the digest, the epoch-boundary rounding, the era stand-in, the job line, the fast-time gate script.
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ Node-fork agent a3f505a9d981300cd started 20:50: ca2-v3 (igneum-pow seam: Progra
|
|||
|
||||
## 20:16 decisions recorded: layer 6 option C, layer 7 R1 = mm8; the chip headline
|
||||
|
||||
Layer 6 DECIDED (delegated; the project lead confirms for the public testnet genesis): option C, the cache doubles when the dataset doubles (256 MiB genesis, 512 MiB year 4, 1 GiB year 12); one-core fill 0.2 / 0.4 / 0.8 s, under 1 s at every step. Layer 7 DECIDED: reserve R1 = mm8, unsigned, W_new 4, unlock era 4 or 90% signal. The chip model's headline now names the on-die-cache recompute chip (54 to 83 mm^2) as a row per variant; the scratch share is chosen as the smallest share at which that chip's gain falls under 1.5x, else said plainly and the public "under 2x" claim qualified. The soundness agent carries that table (its question 2) with M16's mixer multiplier beside it.
|
||||
Layer 6 DECIDED (delegated; the founder confirms for the public testnet genesis): option C, the cache doubles when the dataset doubles (256 MiB genesis, 512 MiB year 4, 1 GiB year 12); one-core fill 0.2 / 0.4 / 0.8 s, under 1 s at every step. Layer 7 DECIDED: reserve R1 = mm8, unsigned, W_new 4, unlock era 4 or 90% signal. The chip model's headline now names the on-die-cache recompute chip (54 to 83 mm^2) as a row per variant; the scratch share is chosen as the smallest share at which that chip's gain falls under 1.5x, else said plainly and the public "under 2x" claim qualified. The soundness agent carries that table (its question 2) with M16's mixer multiplier beside it.
|
||||
|
||||
## 20:18 correction to the SRAM mirror figures (chip-economics research, cluster D)
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ Year 10 at the 6% per year trend: 59 mm^2 for the flat cache (82 with the hot ta
|
|||
|
||||
## 20:23 layer 3 soundness landed: the scratch does not move the chip; scratch share decided 0
|
||||
|
||||
ca2-soundness (0d8f745 tests and trace hook, a465881 doc and bench-log). The on-die-cache recompute chip (N5 headline 128 mm^2, $46) at 50 T op/s: 333 MH/s against the 5090's measured 139.7, 2.4x; at 12.5 / 25 / 50% RMW replaced, chip 381 / 443 / 661 against 5090 projected 160 / 186 / 279, 2.4x each; added, 2.4x or more; 32 or 128 KB alike. The chip keeps the scratch implicitly in 80 to 320 B per lane (the verifier resets it per unit), needs about 530 units in flight, dense scratch 6.2 / 3.1 mm^2 at N5. Under the project lead's rule the scratch share is 0: layer 3 is NOT adopted into v3; the public "under 2x" claim is qualified (public copy level 3 rewritten). The measured lever is M16's mixer multiplier (x2 1.2x at 0.8 to 2.4 ms verify; x4 0.6x at 1.6 to 4.8 ms; 3.6x and 1.8x with a 3x fixed-function factor); whether x4 enters v3 tonight is asked of the coordinator; default: Counter ASIC 3.0.
|
||||
ca2-soundness (0d8f745 tests and trace hook, a465881 doc and bench-log). The on-die-cache recompute chip (N5 headline 128 mm^2, $46) at 50 T op/s: 333 MH/s against the 5090's measured 139.7, 2.4x; at 12.5 / 25 / 50% RMW replaced, chip 381 / 443 / 661 against 5090 projected 160 / 186 / 279, 2.4x each; added, 2.4x or more; 32 or 128 KB alike. The chip keeps the scratch implicitly in 80 to 320 B per lane (the verifier resets it per unit), needs about 530 units in flight, dense scratch 6.2 / 3.1 mm^2 at N5. Under the founder's rule the scratch share is 0: layer 3 is NOT adopted into v3; the public "under 2x" claim is qualified (public copy level 3 rewritten). The measured lever is M16's mixer multiplier (x2 1.2x at 0.8 to 2.4 ms verify; x4 0.6x at 1.6 to 4.8 ms; 3.6x and 1.8x with a 3x fixed-function factor); whether x4 enters v3 tonight is asked of the coordinator; default: Counter ASIC 3.0.
|
||||
|
||||
Soundness results (Metal, M5 Max): 28/28 edge launches, 200/200 fuzz packs (91 s), 56/56 hand-model edge checks, 42/42 kernels pass the static scratch-mask check with 6 deliberate breaks caught, broken tag and broken lazy fill caught, fingerprint 8c07620f4d9adefd warp-count-independent; re-hit rates 2 to 33% above the birthday bound (slot addresses are register low bits); written words unbiased (worst 3.63 of 6 sigma). Verifier exactness needs a host contract (zero the arena at allocation and at the 32-bit tag wrap, tags from 1), which neither host gives today. Pre-existing on readwidth b970dda: verify::tests::fold_and_wide_fetch overflows under the test profile (wrapping_mul fixes it); passed to the readwidth agent with the class sweep.
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ Gate G3 note: the scratch tests (igneum-pow/tests/scratch.rs) join the v3 suite
|
|||
|
||||
## 20:24 decided: M16 mixer x4 into v3; agent ca2-mixer started
|
||||
|
||||
Coordinator's decision under the project lead's delegation (recorded in the rollout plan section 6a): the mixer multiplier x4 and the cache growth rule (option C) enter class v3 behind the same activation; layer 3 stays out at scratch share 0, its soundness document and pack-contract tests kept. Agent af345b1e2c541ffbb (branch ca2-mixer) implements `mixer_mult` as a class parameter (m mixer applications per round, the 8 dependent reads unchanged), the `cache_log2_words(day)` schedule (doublings at years 4 and 12 with the dataset stepping to the next power of two), re-cuts the v3 dataset vectors, re-runs the soundness suite, measures the verifier (v2 0.604 ms per warp; v3 expected 1.6 to 4.8 ms) and the 1 GiB build on the Mac, prepares the 5090 and 9070 XT build-time job, and writes docs/analysis/chip-model-v3.md with the combined headline row (fixed-function factor included). The claim on the site reads "under 2x" only if that row does; else qualified, with the mixer x8 and the hot table named as the next levers.
|
||||
Coordinator's decision under the founder's delegation (recorded in the rollout plan section 6a): the mixer multiplier x4 and the cache growth rule (option C) enter class v3 behind the same activation; layer 3 stays out at scratch share 0, its soundness document and pack-contract tests kept. Agent af345b1e2c541ffbb (branch ca2-mixer) implements `mixer_mult` as a class parameter (m mixer applications per round, the 8 dependent reads unchanged), the `cache_log2_words(day)` schedule (doublings at years 4 and 12 with the dataset stepping to the next power of two), re-cuts the v3 dataset vectors, re-runs the soundness suite, measures the verifier (v2 0.604 ms per warp; v3 expected 1.6 to 4.8 ms) and the 1 GiB build on the Mac, prepares the 5090 and 9070 XT build-time job, and writes docs/analysis/chip-model-v3.md with the combined headline row (fixed-function factor included). The claim on the site reads "under 2x" only if that row does; else qualified, with the mixer x8 and the hot table named as the next levers.
|
||||
|
||||
Agents now: ca2-era (a452664c512c73b9b), ca2-cache (a5271cf269757b118), ca2-node (a3f505a9d981300cd), ca2-mixer (af345b1e2c541ffbb). Done: ca2-analysis, ca2-soundness. Waiting: the readwidth PC table; PC 2 (proving memsweep runs) and PC 1 (readwidth 9070 round).
|
||||
|
||||
|
|
@ -130,13 +130,13 @@ Readwidth e752fc7 (`docs/plans/read-width.md`), bit-exact on Metal, Apple OpenCL
|
|||
| scratch 32 KB at 12.5 / 25 / 50% | -18 / -21 / -12% | -18 / -22 / -21% | -7 / +12 / +74% | |
|
||||
| scratch 128 KB | -21 / -30 / -48% | -21 / -27 / -33% | -7 / -1 / +25% | |
|
||||
|
||||
Decisions (the project lead's rules, delegated): layer 1 keep v2 (w16 passes the rule but closes nothing and does not move the chip row; the vector re-cut is not worth it); layer 2 out (spread over 5% on every card); layer 3 out (scratch share 0). The AMD gap is the card's dependent-read rate (2.4 G/s at every width), stated for the user tiers in the rollout plan 6b.
|
||||
Decisions (the founder's rules, delegated): layer 1 keep v2 (w16 passes the rule but closes nothing and does not move the chip row; the vector re-cut is not worth it); layer 2 out (spread over 5% on every card); layer 3 out (scratch share 0). The AMD gap is the card's dependent-read rate (2.4 G/s at every width), stated for the user tiers in the rollout plan 6b.
|
||||
|
||||
Layer 5 (ca2-cache 53ef59f, 011cc0a, 86726cd, 65bc7a7; `docs/plans/hot-table.md`): five packs bit-exact on Metal and Apple OpenCL (96/96 each). M5 Max rates against v2 27.68: hot32k4 x1.22, hot64k4 x1.12, hot96k4 x1.05, hot64k2 x1.00, hot64k8 x1.71; verifier 0.344 to 0.560 ms against 0.626; hot fill per epoch 24 / 46 / 73 ms on one core, 0.07 / 0.15 / 0.22 ms on the GPU; Apple OpenCL probe 32 / 64 / 96 / 1024 MiB 21.7 / 12.8 / 12.3 / 3.50 G loads/s. Redesign ordered: hot loads ADDED beside the 16 dataset loads (the replaced form lets the on-die-cache chip skip item derivations and worsens the gain); the agent re-measures the added form and rebuilds the PC job. PC 1 is given to the dot4 probe (under 15 min), then to the era agent, then the hot-table job; PC 2 stays the proving agent's.
|
||||
|
||||
## 20:27 layer 9 added; the era draw passes Mac bit-exactness; two class bugs in the harnesses; C1
|
||||
|
||||
Layer 9 (the project lead: faster program changes): the epoch length becomes an era parameter in the genesis reserve, 1 hour at launch, 10 minutes to 2 hours by draw or 90% signal, reserve-only tonight; an agent (ca2-epoch) designs it beside layers 4 and 8 and measures the compile-ahead cost per card at a 10-minute epoch, the seed-path consequence and the FPGA threat it answers; one row in the rollout plan section 6, one in the level 3 numbers. Spawns when the dot4 probe frees its slot.
|
||||
Layer 9 (the founder: faster program changes): the epoch length becomes an era parameter in the genesis reserve, 1 hour at launch, 10 minutes to 2 hours by draw or 90% signal, reserve-only tonight; an agent (ca2-epoch) designs it beside layers 4 and 8 and measures the compile-ahead cost per card at a 10-minute epoch, the seed-path consequence and the FPGA threat it answers; one row in the rollout plan section 6, one in the level 3 numbers. Spawns when the dot4 probe frees its slot.
|
||||
|
||||
ca2-era mid-way (a452664c512c73b9b): era draw behind LoadClass::era (EraParams beside mix, load_slots, scratch, scratch_kb; verify::load_index; memhard::Layout; one load form in the three emitters; --era, --era-widths), 54 crate tests green, pinned packs byte-identical; six era packs bit-exact on Metal (packbench 6/6), Apple OpenCL (6/6, same fingerprints) and the CUDA emulation (6/6); re-exporting with the width pinned at 4 B and rebasing onto e752fc7; PC job in about 20 minutes. Two class bugs found and fixed on its branch, both outside its layer: (1) proto-cuda/nvrtc/packfile.h re-derived the seed words as attempt 0 only, so ANY pack with IGNEUM_PROGRAM_ATTEMPT >= 1 (5.14% of chain epochs under v2) is refused by the one-click workers with "the epoch seed bytes do not give the pack's IGNEUM_SEEDW_INIT", the error PC 1 logged on 5 October and attributed to the export race; fixed attempt-aware, with a tampered-attempt refusal test. This fix must ship in the 0.3.11 workers whatever else does. (2) proto-cuda/host.cu and proto-opencl/host.c derived dataset words on the host as mh_item(w >> 4)[w AND 15] instead of the pack's mh_word; fixed.
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ The attempt-0 packfile.h bug (the era agent's find) is the one that took the fle
|
|||
|
||||
## 20:31 card lifetime merged; cache freed after the build; growth mapping (b) recommended
|
||||
|
||||
`docs/analysis/card-lifetime-2026-10-05.md` (branch card-lifetime 1fecfe2) merged into ca2-coord. Decided (delegated): the GPU frees the 256 / 512 / 1,024 MiB cache after the daily dataset build (the hash never reads it; the rebuild costs 0.67 ms fill + 13.4 ms build on the 5090 at x1, about 54 ms at x4, owed); hot-table.md's resident reading is corrected, era-layout.md's freed reading stands. Recommended for the project lead: growth mapping (b), power-of-two steps at years 4, 12, 28, 60 with AND MASK, the only mapping under which the litepaper's "4 GB about four years, 8 GB more than a decade" holds (4 GB: year 4 under (b), 1.0 to 1.5 years under (a); 8 GB: year 12 or 6.3 to 7.5; 12 GB: year 28 with the cache freed; 24 GB: year 60). Public lines and the evidence row go on the integration branch (rollout plan 6c); hot-table.md line 73 (the 8 GB row counted a 5090's warps) goes to the cache agent.
|
||||
`docs/analysis/card-lifetime-2026-10-05.md` (branch card-lifetime 1fecfe2) merged into ca2-coord. Decided (delegated): the GPU frees the 256 / 512 / 1,024 MiB cache after the daily dataset build (the hash never reads it; the rebuild costs 0.67 ms fill + 13.4 ms build on the 5090 at x1, about 54 ms at x4, owed); hot-table.md's resident reading is corrected, era-layout.md's freed reading stands. Recommended for the founder: growth mapping (b), power-of-two steps at years 4, 12, 28, 60 with AND MASK, the only mapping under which the litepaper's "4 GB about four years, 8 GB more than a decade" holds (4 GB: year 4 under (b), 1.0 to 1.5 years under (a); 8 GB: year 12 or 6.3 to 7.5; 12 GB: year 28 with the cache freed; 24 GB: year 60). Public lines and the evidence row go on the integration branch (rollout plan 6c); hot-table.md line 73 (the 8 GB row counted a 5090's warps) goes to the cache agent.
|
||||
|
||||
## 20:32 layer 9 agent started; the dot4 probe is on PC 1
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ Rule: one PC 1 job at a time; an agent asks by message before publishing, gets a
|
|||
|
||||
If job 1's package is more than 15 minutes away when job 2 is ready, job 2 goes first; the short job 3 fills any gap of under 10 minutes between packages.
|
||||
|
||||
20:39. No more agents are spawned tonight (the project lead: no unnecessary credits); the running ones finish. PC 1 queue change: the AMD-proving CPU fallback's small fixture (block-56-transfers-3shards, minutes) runs NOW in the gap before the era package; its S_p shard (block-338-shard1, up to 30 min of every core) stays job 6, last. Next-cut list gains the rig installer's two follow-ups (the Linux manifest entry, the Linux prover build), tied to whichever release carries the proving half (rollout plan 8a).
|
||||
20:39. No more agents are spawned tonight (the founder: no unnecessary credits); the running ones finish. PC 1 queue change: the AMD-proving CPU fallback's small fixture (block-56-transfers-3shards, minutes) runs NOW in the gap before the era package; its S_p shard (block-338-shard1, up to 30 min of every core) stays job 6, last. Next-cut list gains the rig installer's two follow-ups (the Linux manifest entry, the Linux prover build), tied to whichever release carries the proving half (rollout plan 8a).
|
||||
|
||||
## 20:42 the node switch is written; the Metal worker is a gate item
|
||||
|
||||
|
|
@ -210,7 +210,7 @@ Mac build queue: the measure lock has been held by a packbench run since 20:31Z
|
|||
|
||||
## 20:45 the 9070 XT has dropped off PC 1's bus; app restart facts; the era package ETA
|
||||
|
||||
The AMD sweep agent (a01dcb34ae16d867c) reports from a read-only probe at about 20:40 UTC: Get-PnpDevice lists only the integrated "AMD Radeon(TM) Graphics" (gfx1036) and the RTX 5090; the app's AMD worker now mines the gfx1036 at 3.12 MH/s; the 9070 XT is absent from PnP (the eGPU link: the Sonnet box or the USB4 router; earlier today it went Code 43 and came back after a driver reinstall and reboot). A 10-second rescan probe is granted (pnputil /scan-devices, the USB4 router status). the project lead is asleep and is not woken. Consequence if the card stays absent: gate G1 (bit-exact v3 on all three cards) and the 9070 XT rows of the era and hot-table tables cannot be taken tonight; the AMD-vendor stand-in available is the gfx1036 (RDNA 2, AMD OpenCL 3683.0, 3 MH/s), which ran the version 1 and version 2 conformance; whether it satisfies G1 for the devnet publish is asked of the coordinator. Every 9070 XT row taken before 20:40 (readwidth, dot4) stands.
|
||||
The AMD sweep agent (a01dcb34ae16d867c) reports from a read-only probe at about 20:40 UTC: Get-PnpDevice lists only the integrated "AMD Radeon(TM) Graphics" (gfx1036) and the RTX 5090; the app's AMD worker now mines the gfx1036 at 3.12 MH/s; the 9070 XT is absent from PnP (the eGPU link: the Sonnet box or the USB4 router; earlier today it went Code 43 and came back after a driver reinstall and reboot). A 10-second rescan probe is granted (pnputil /scan-devices, the USB4 router status). The founder is asleep and is not woken. Consequence if the card stays absent: gate G1 (bit-exact v3 on all three cards) and the 9070 XT rows of the era and hot-table tables cannot be taken tonight; the AMD-vendor stand-in available is the gfx1036 (RDNA 2, AMD OpenCL 3683.0, 3 MH/s), which ran the version 1 and version 2 conformance; whether it satisfies G1 for the devnet publish is asked of the coordinator. Every 9070 XT row taken before 20:40 (readwidth, dot4) stands.
|
||||
|
||||
App restart facts from the log intake (`node tools/logs.mjs`, 20:45): PC 1's app run is win-ae432dc7-20261005-190232 (started 19:02:32, no restart since), so no PC 1 measurement tonight straddled an app restart; PC 2's run is win-1ccfe586-20261005-200114 (started 20:01:14, before the readwidth 5090 round at 20:09). The 0.3.10 manifest is still unpublished (the shipper's CI is queued); the "jobs folder cleared by the 0.3.10 update" reading was wrong: the folder is cleared by fetch jobs.
|
||||
|
||||
|
|
@ -220,7 +220,7 @@ Era package: 10 to 15 minutes away (the pack-loop packfile merged over readwidth
|
|||
|
||||
## 20:46 ruling on G1; hardware event recorded
|
||||
|
||||
Ruling (coordinator): gfx1036 satisfies the AMD vendor for gate G1 tonight (a compiler-and-ISA property; it carried the v1 and v2 conformance); the 9070 XT's hash-rate and power rows are owed and taken when the link is back; every 9070 XT row before 20:40 UTC stands. Nobody is woken, PC 1's app is not restarted. The event is in the rollout plan section 7b (hardware events) for the morning summary: the second eGPU link fault today (Code 43 at install, a bus drop at about 20:40); the project lead reseats the USB4 cable and the eGPU power; the 0.3.10 hot-plug code shows "removed" and picks the card up without a restart. The publish proceeds when every other gate is green.
|
||||
Ruling (coordinator): gfx1036 satisfies the AMD vendor for gate G1 tonight (a compiler-and-ISA property; it carried the v1 and v2 conformance); the 9070 XT's hash-rate and power rows are owed and taken when the link is back; every 9070 XT row before 20:40 UTC stands. Nobody is woken, PC 1's app is not restarted. The event is in the rollout plan section 7b (hardware events) for the morning summary: the second eGPU link fault today (Code 43 at install, a bus drop at about 20:40); the founder reseats the USB4 cable and the eGPU power; the 0.3.10 hot-plug code shows "removed" and picks the card up without a restart. The publish proceeds when every other gate is green.
|
||||
|
||||
## 20:47 the Sonnet box is off the link; PC 1 facts corrected; the queue after the era job
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ docs/spec/01-lottery-hash.md: 1.12 carries epoch_len (the ladder 600 to 7,200, 9
|
|||
|
||||
## 20:56 PC 2 released; the proving fork tip for the merged tree
|
||||
|
||||
PC 2 is free (the proving agent's last job closed; the live prover is back on). Proving fork tip ece42979 on 21d4c73c (N = 8, the digest test edit), app 440fd59 or later; its suites ride with the ca2 node suites on the merged tree; its harness on the final tree is running on the Mac. The S_p curve with the miner on the card (PC 2's 5090): empty shard 15,585 MiB 7.5 s; the adopted v1 shard (30,000 pgas, 4.7 M cycles) 22,210 MiB 13.2 s (20,435 MiB, 4.2 s alone); 2.25 M pgas 30,049 MiB 17.9 s; 4.5 M 29,954 MiB 26.3 s; the prototype shard 30,083 MiB 33.3 s. Tiers as the proving agent published them: 32 GB mines and proves today, 24 GB from the fee switch (2.3 GB spare on the adopted shard), 16 GB empty shards only, 12 GB nothing on this build (D2 to the project lead).
|
||||
PC 2 is free (the proving agent's last job closed; the live prover is back on). Proving fork tip ece42979 on 21d4c73c (N = 8, the digest test edit), app 440fd59 or later; its suites ride with the ca2 node suites on the merged tree; its harness on the final tree is running on the Mac. The S_p curve with the miner on the card (PC 2's 5090): empty shard 15,585 MiB 7.5 s; the adopted v1 shard (30,000 pgas, 4.7 M cycles) 22,210 MiB 13.2 s (20,435 MiB, 4.2 s alone); 2.25 M pgas 30,049 MiB 17.9 s; 4.5 M 29,954 MiB 26.3 s; the prototype shard 30,083 MiB 33.3 s. Tiers as the proving agent published them: 32 GB mines and proves today, 24 GB from the fee switch (2.3 GB spare on the adopted shard), 16 GB empty shards only, 12 GB nothing on this build (D2 to the founder).
|
||||
|
||||
PC 2 queue: the ca2 node suites on the merged tree (ca2-v3-node + ece42979) as soon as the node agent sends "ready for PC 2"; nothing else is queued on PC 2.
|
||||
|
||||
|
|
@ -350,7 +350,7 @@ Consequence for layer 5: unless the 5090 and 9070 XT rows show g at or above 0.9
|
|||
|
||||
## 21:27 decision rule for the mixer: x8 beside x4
|
||||
|
||||
Delegated (coordinator, the project lead's "as strong as the measurements allow"): the mixer agent builds LoadClass::MX8 beside MX4, exports mx8-genesis and mx8-devnet-epoch0, runs the Mac bit-exactness, and measures v2, x4 and x8 in one measure-lock session (verifier ms per warp on one core, avg of 50 and worst cold; the 256 MiB fill; the Metal 1 GiB build); the 5090 and AMD daily-build times come from a 2-minute prepare job on PC 1 after the era job. x8 goes into v3 if the per-warp verify stays under 10 ms on one core AND the daily build stays under 1 s on every card we own; else x4 with the thin margin stated (1.84x with the factor) and x8 named as the next lever (0.92x with the factor, from the m16 table). The vectors are re-cut once after the choice. The hot-table rule stands (into v3 only at g >= 0.97 on both PC cards).
|
||||
Delegated (coordinator, the founder's "as strong as the measurements allow"): the mixer agent builds LoadClass::MX8 beside MX4, exports mx8-genesis and mx8-devnet-epoch0, runs the Mac bit-exactness, and measures v2, x4 and x8 in one measure-lock session (verifier ms per warp on one core, avg of 50 and worst cold; the 256 MiB fill; the Metal 1 GiB build); the 5090 and AMD daily-build times come from a 2-minute prepare job on PC 1 after the era job. x8 goes into v3 if the per-warp verify stays under 10 ms on one core AND the daily build stays under 1 s on every card we own; else x4 with the thin margin stated (1.84x with the factor) and x8 named as the next lever (0.92x with the factor, from the m16 table). The vectors are re-cut once after the choice. The hot-table rule stands (into v3 only at g >= 0.97 on both PC cards).
|
||||
|
||||
21:28. Installer attempt 3 failed at 21:27:20Z (exit 2 in 4 s: an inline bash -c string lost a quote through PowerShell; the fix is the 0.3.6 cut's: the WSL part as a file run with bash <file>, plus a read-only path probe before attempt 4). By the rule, "go PC 1" went to the hot-table job at 21:28 (10 min). PC 1 order from here: the hot-table job, the shipper's path probe and attempt 4 (about 16 min), the era job, the 5090 power sweep, the mixer daily-build job (2 min), Ember's build, the repro re-run, the AMD sweep (conditional), Ember's run.
|
||||
|
||||
|
|
@ -542,7 +542,7 @@ The node agent's owed item is an app gap, confirmed in the 0.3.11 app branch: en
|
|||
|
||||
Job run-ca2-era-pc1b-20261005 (22:16 to 22:21Z, 304 s, both cards restored, app 0.3.10, the 9070 XT present): the seven final-class packs' 2^24 fingerprints equal on the 5090, the 9070 XT and the M5 Max (mx8-devnet-epoch0 90f794dd556f7a3b; era-0 8e8e070db4eea52d, era-1 891c01b8563bb47e, era-2 e54279fed2831b5d, era-3 77e0ba8abbd0ae62, era-4 d898d8f4f2e7684b, era-5 a6927db380f7efb2); G2: 1,024 of 1,024 per card on era-0 and the pinned pack re-hashed by the Rust verifier. Rates on the final class (MH/s): 5090 135.90 to 137.70 (spread 1.3%), 9070 XT 18.59 to 19.18 (3.1%), M5 Max 27.85 to 27.98 (0.5%); the pinned pack 136.10 / 18.90 / 27.80. Spec 1.17 carries these fingerprints. Gates now: G1, G2, G3, G4, G6 green; G4b (a) done, (b) the Metal gate run pending; G5 at the ship's build. PC 1 goes to the AMD sweep on its presence probe.
|
||||
|
||||
22:25. Consequences C29 and D11 applied. C29: the litepaper's verifier line now reads 2.1 ms per warp for class v3 on one M5 Max core at load average 5.5 (the fixed crate; worst cold 2.15), 3.4x the v2 verifier's 0.61 ms, the gate leaving 4.8x (4.6x on the worst cold unit); the "about 1.3 ms quiet" scaling is struck: it came from the slow binary's 2.79 ms session (21:40), and the fixed binary's session (22:07) matched readwidth's quiet v2 figure within 1%, so the fixed numbers are near-quiet. D11: "and the bounty" struck from the hero and the abstract, "standing" from level 1; the copy says "a bounty follows the external review"; the bounty is named only once escrowed (funding.md rule 3; USD 50,000 not funded); the project lead decides (D11). The level 3 table and the numbers-page entry now carry the final-class rates (5090 135.90 to 137.70, 9070 XT 18.59 to 19.18, M5 Max 27.85 to 27.98).
|
||||
22:25. Consequences C29 and D11 applied. C29: the litepaper's verifier line now reads 2.1 ms per warp for class v3 on one M5 Max core at load average 5.5 (the fixed crate; worst cold 2.15), 3.4x the v2 verifier's 0.61 ms, the gate leaving 4.8x (4.6x on the worst cold unit); the "about 1.3 ms quiet" scaling is struck: it came from the slow binary's 2.79 ms session (21:40), and the fixed binary's session (22:07) matched readwidth's quiet v2 figure within 1%, so the fixed numbers are near-quiet. D11: "and the bounty" struck from the hero and the abstract, "standing" from level 1; the copy says "a bounty follows the external review"; the bounty is named only once escrowed (funding.md rule 3; USD 50,000 not funded); the founder decides (D11). The level 3 table and the numbers-page entry now carry the final-class rates (5090 135.90 to 137.70, 9070 XT 18.59 to 19.18, M5 Max 27.85 to 27.98).
|
||||
|
||||
## 22:25 the fourth eGPU drop; the era branch final; PC 1 to Ember
|
||||
|
||||
|
|
@ -552,7 +552,7 @@ The 9070 XT is absent again at 22:24:09Z (relay probe #230: no Sonnet or USB4 ro
|
|||
|
||||
A dry run of ca2-v3 into master in a scratch worktree conflicts in docs/bench-log.md (append-only, both kept) and proto-opencl/host.c, where taking ca2-v3's side would drop master's 0.3.10 hunks (the PCI topology and duplicate-platform detection, the select read-back): it must be resolved by hand keeping both. ca2-v3 also lacks readwidth's last three commits (d0018cf the OpenCL scratch local-buffer rule, e752fc7 read-width.md and the overflow fix, 30ff674 the per-watt rows). So the node agent, as ca2-v3's owner, merges readwidth 30ff674 and origin/master (cde561c, 1f0d62c) into ca2-v3 beside gate run 4, re-runs the igneum-pow suite, the packfile test, test-generic.sh on Apple OpenCL and the fork check, and sends the tip. ca2-coord (docs, spec, site, evidence, the plans) stays on its a9e002c base: its code files are untouched readwidth copies, so its merge onto that tip takes ca2-v3's code and brings only the documents (a rebase attempt replayed readwidth's own commits and was aborted). Ship order: master <- ca2-v3' <- ca2-coord <- the tooling and analysis branches (consequences, bash-body-check, amd-prove, card-lifetime, proving-methods, asic-history when it lands), the app branch proving-v1 e0de2ab (on 5b0d54f, in master), the fork ca2-v3-node 89dfcb95 (on 21d4c73c, release-0.3.10's tip). The ASIC-history agent (a202a09dcd24ba1d3) resumed at 22:52 (its clock) in ../igneum-wt-asic-history; its ranked additions are Counter ASIC 3.0's input after the publish.
|
||||
|
||||
22:30. C31 applied (a7be43f): the litepaper's "12 GB or more proves full shards" struck (one page, one number: 24 GB); the dataset's step schedule written as the gate 1 proposal on the site and litepaper (D4 is the project lead's); the merge rule "take proving-v1's evidence row 16 and its proving sentences" in the rollout plan. PC 1: Ember's build done (build-20261005-222558, 97 s, 6 outputs verified), its tune run on the 5090 has the go. PC 2: floor-build-3 (with the pinned Go toolchain; builds 1 and 2 failed on a missing go, the first unreported by a log-path bug) runs, 25 to 45 minutes expected.
|
||||
22:30. C31 applied (a7be43f): the litepaper's "12 GB or more proves full shards" struck (one page, one number: 24 GB); the dataset's step schedule written as the gate 1 proposal on the site and litepaper (D4 is the founder's); the merge rule "take proving-v1's evidence row 16 and its proving sentences" in the rollout plan. PC 1: Ember's build done (build-20261005-222558, 97 s, 6 outputs verified), its tune run on the 5090 has the go. PC 2: floor-build-3 (with the pinned Go toolchain; builds 1 and 2 failed on a missing go, the first unreported by a log-path bug) runs, 25 to 45 minutes expected.
|
||||
|
||||
22:32. C32: an app update clears the jobs folder (the 0.3.10 install took PC 1's AMD kit, fetched at 21:23:59Z; the 21:05 reading "cleared by fetch jobs" was wrong), so two rules enter the rollout plan (4a): the 0.3.11 update-now reaches PC 2 only after floor-build-3 closes (PC 2 last on the machine list), and every fetch-then-run pair re-fetches after an update, with a kit presence check at the top of every run playbook.
|
||||
|
||||
|
|
@ -572,7 +572,7 @@ The ship is assigned to the 0.3.10 shipper (ae892a8b0f78fe31c) with every input
|
|||
|
||||
## 22:41 the release tree is assembled; counter-asic-3.md written; PC 2 to the aggregation-cost re-run
|
||||
|
||||
Release worktree /Users/joshm/Projects/igneum-wt-ship0311, branch release-0.3.11 from origin/master b38f3de: merges in order ca2-v3 fa3c932 (clean), ca2-coord (bench-log both kept), the app branch 22c2363 (bench-log both; docs/evidence.md rows 15 and 16 from proving-v1, 17 to 22 from ca2-coord; the litepaper's schedule sentence from ca2-coord with proving-v1's 24 GB sentence appended), ca2-coord 57844e9 (the nine-field override line), bash-body-check e3bd761 (ci.yml both steps kept, prover-socket-check.sh from bash-body-check), consequences 99fd988, proving-methods e7e0db7, asic-history 9e4af7f; tip b968ee0; the fork worktree vendor/igneum-node-0311 at 89dfcb95 under the release tree. The checks (igneum-pow suite, the app suite, test-generic.sh on Apple OpenCL) run now; then the handoff to the shipper (the coordinator has told it to ship). docs/plans/counter-asic-3.md is written from the ASIC-history agent's seven ranked additions (the partial-store chip and the time-memory curve first, the random daily derivation as a reserve, the mixer cryptanalysis as a genesis gate, the detector and the issuance-triggered bounty, the FPGA lane, the reserve order, the vendor-share metric) with the decisions for the project lead.
|
||||
Release worktree /Users/joshm/Projects/igneum-wt-ship0311, branch release-0.3.11 from origin/master b38f3de: merges in order ca2-v3 fa3c932 (clean), ca2-coord (bench-log both kept), the app branch 22c2363 (bench-log both; docs/evidence.md rows 15 and 16 from proving-v1, 17 to 22 from ca2-coord; the litepaper's schedule sentence from ca2-coord with proving-v1's 24 GB sentence appended), ca2-coord 57844e9 (the nine-field override line), bash-body-check e3bd761 (ci.yml both steps kept, prover-socket-check.sh from bash-body-check), consequences 99fd988, proving-methods e7e0db7, asic-history 9e4af7f; tip b968ee0; the fork worktree vendor/igneum-node-0311 at 89dfcb95 under the release tree. The checks (igneum-pow suite, the app suite, test-generic.sh on Apple OpenCL) run now; then the handoff to the shipper (the coordinator has told it to ship). docs/plans/counter-asic-3.md is written from the ASIC-history agent's seven ranked additions (the partial-store chip and the time-memory curve first, the random daily derivation as a reserve, the mixer cryptanalysis as a genesis gate, the detector and the issuance-triggered bounty, the FPGA lane, the reserve order, the vendor-share metric) with the decisions for the founder.
|
||||
|
||||
PC 2: floor-sweep-1 (22:34 to 22:37:55Z, every proof verified by the unpatched host): the shard term is gone but a second floor binds at 12.7 GB measured (10.95 GB the server's own): at Setup the server pre-builds five recursion keys at the fixed 2^27 capacity (3.75 GB) plus the shrink and core keys, 9.7 GB before the first shard; a second patch (every trace buffer sized to its program or shard) follows in about 30 minutes; nothing is under 11.0 GB yet; the public line stays 24 GB. "go PC 2" to the aggregation-cost re-run (20 min); the floor's second build after it; the 0.3.11 update-now reaches PC 2 after both.
|
||||
|
||||
|
|
@ -604,13 +604,13 @@ Tree release-0.3.11 23bc2b2 (cc72f4a plus the nine-field packaged line). N4 = N5
|
|||
|
||||
The shipper's second report (tree 23bc2b2): the two digests on the 0.3.11 Mac node: c562d70e... with no override file (= the node agent's pinned test), 0139ab9dc2992d449ec787d8f021974933631eb55740ab4b6ce9d5c226e72888 with the nine-field object at N4 = N5 = 154,800, the value every node must print after the publish (the node logs the class switch "active from epoch 43" and the proving v1 line); the DMG b7e81d4f... (41,592,041 bytes, the nine fields read back from the image); the seed's Linux node 63cf490d.... Waiting on PC 1's exes (build-20261005-224654) for the inputs, the pin, the push and CI.
|
||||
|
||||
PC 1 (Ember's finding, confirmed on the intake at 22:51): the installed app has not come back since its quit at 22:31:06Z (the last upload 22:31:08Z, no new run id, no job since), so PC 1 is not mining (the devnet short its 141 MH/s for 20 minutes), the shipper's build job cannot start there, and no update-now can reach it. The relay agent on PC 1 is alive (read-only probes ran through it at 22:45); the shipper is asked to relaunch the installed app through a relay task in the interactive session and to verify a new run id; if the relay cannot reach the user's session, PC 1 waits for the project lead in the morning and the 0.3.11 rollout goes without it (its update lands at its relaunch). the project lead is not woken. The quit's cause (C35): the senders are the tray Quit, stdin EOF in wrapper mode and POST /api/quit with the token; Ember's playbook POSTs api/quit to the URL file in $u when its budget is spent (lines 125 to 127); the Ember owner is checking what $u resolved to at 22:31; Ember's re-run stays held, and the playbook rule becomes: never read the installed app's URL file, never POST quit to a URL it did not create.
|
||||
PC 1 (Ember's finding, confirmed on the intake at 22:51): the installed app has not come back since its quit at 22:31:06Z (the last upload 22:31:08Z, no new run id, no job since), so PC 1 is not mining (the devnet short its 141 MH/s for 20 minutes), the shipper's build job cannot start there, and no update-now can reach it. The relay agent on PC 1 is alive (read-only probes ran through it at 22:45); the shipper is asked to relaunch the installed app through a relay task in the interactive session and to verify a new run id; if the relay cannot reach the user's session, PC 1 waits for the founder in the morning and the 0.3.11 rollout goes without it (its update lands at its relaunch). The founder is not woken. The quit's cause (C35): the senders are the tray Quit, stdin EOF in wrapper mode and POST /api/quit with the token; Ember's playbook POSTs api/quit to the URL file in $u when its budget is spent (lines 125 to 127); the Ember owner is checking what $u resolved to at 22:31; Ember's re-run stays held, and the playbook rule becomes: never read the installed app's URL file, never POST quit to a URL it did not create.
|
||||
|
||||
22:53. PC 1: the relaunch of the installed app went out through the relay at 22:52:31Z (item #241: igneum-app.exe started through explorer.exe so the app gets the user's own token, a one-shot scheduled task at limited run level as the fallback); the shipper reports the new run id and the first STATUS line; its build job starts when the app fetches the jobs file. PC 2 queue after the aggregation-cost job (closing about 22:59): the shipper's 0.3.11 suites, the prover-floor build 4 and sweep 2, the aggregation-cost re-run (20 min, with a plain-text parser: under 0.3.10 the app's /api/state comes back empty to PowerShell 5.1's JSON reader while the body is there, a class hit by three playbooks tonight; the app owner fixes the response shape or every playbook parses the text), then "PC 2 clear" for the update-now, then the ledger-pc2 agent's M16 / E17 / P17 job (the inline-cache kernel at 64 and 256 MiB on the 5090 against the honest kernel, the nvidia-smi line per setting, the igneum-exec suite in WSL2; about 12 minutes, after its kit lands on the dl folder in 1 to 2 hours).
|
||||
|
||||
22:54. C35 resolution (Ember owner): $u resolved to %LOCALAPPDATA%\igneum-tune\app\app.url, the second engine's own file (lines 34 to 36 and 125 of the playbook; line 74 deletes it before the engine starts; platform::data_root() honours IGNEUM_APP_DATA, set to the scratch root at line 93), and the budget branch never ran (its "RESULT TUNE error=budget_exceeded" line is absent); so the playbook did not quit the installed app. What the reading did find: the second engine counted --sweep as Power control and raised a UAC prompt at about 22:30:25Z (apply_power_limits at start), 40 s before the installed app's quit; closed on ember-tune b671c8b (Power control alone decides, no cap at start under --sweep, every Cmd::Quit names its source, the budget floored at 5 minutes, the playbook refuses a quit to any URL under the installed igneum\app). The remaining question is whether an unanswered elevation prompt can take the installed app's window host down (stdin EOF): the same shape as PC 2's quit at 20:01:09Z, 20 s after a cancelled administrator prompt (C16). "go PC 1 collect" given: the Application event log at 22:31Z and the installed app's log tail, once PC 1's app is back; the re-run stays held until the source is named.
|
||||
|
||||
22:55. C35 narrows to one common factor: both unexplained quits came 20 to 41 s after an administrator prompt beside the running installed app (PC 2 at 20:00:49Z then 20:01:09Z; PC 1 at about 22:30:25Z then 22:31:06Z); Ember's playbook is ruled out. Rule for the night (rollout plan 4a): no PC job raises an elevation prompt on either PC; the two-minute class test (one prompt raised and cancelled beside the mining app, the quit line read) waits for the morning with the project lead present, or tonight only after the relay relaunch path is proven and the rollout is done; Ember's quit-source stamping (b671c8b) goes to the next cut. The devnet has been short PC 1's 141 MH/s since 22:31Z (96 MH/s at 22:51); the relay relaunch #241 is the recovery, else PC 1 is on the morning's hands list beside the eGPU reseat and the 16:00Z check.
|
||||
22:55. C35 narrows to one common factor: both unexplained quits came 20 to 41 s after an administrator prompt beside the running installed app (PC 2 at 20:00:49Z then 20:01:09Z; PC 1 at about 22:30:25Z then 22:31:06Z); Ember's playbook is ruled out. Rule for the night (rollout plan 4a): no PC job raises an elevation prompt on either PC; the two-minute class test (one prompt raised and cancelled beside the mining app, the quit line read) waits for the morning with the founder present, or tonight only after the relay relaunch path is proven and the rollout is done; Ember's quit-source stamping (b671c8b) goes to the next cut. The devnet has been short PC 1's 141 MH/s since 22:31Z (96 MH/s at 22:51); the relay relaunch #241 is the recovery, else PC 1 is on the morning's hands list beside the eGPU reseat and the 16:00Z check.
|
||||
|
||||
22:55. PC 1's engine did not exit: relay task #241 found igneum-app.exe ALIVE (pid 26696, started 21:49:40Z, session 1) answering nothing on /api/state in 60 s and uploading nothing since 22:31:08Z: it logged its quit at 22:31:06Z, stopped the miners and the node, and hung instead of exiting (a quit that never ends: a C35 fact and a next-cut defect: the quit path must end the process or the watchdog must end it after a bound). Task #243 (22:55:10Z) ends that engine by pid, as the app's own updater does, then starts the per-user install through explorer.exe (the user's token), the limited-run-level scheduled task as the fallback; the new run id, the first STATUS line and the build job's first STAGE line follow in the intake.
|
||||
|
||||
|
|
@ -634,7 +634,7 @@ The shipper's relay task #244 (22:55:24Z) counted 1 igneumd, 2 igneum-miner, 2 i
|
|||
|
||||
## 23:07 CORRECTION: the relay's "PC1" is PC 2; the 9070 XT never dropped during the app jobs; PC 2 was restarted twice; PC 1 is unreachable tonight
|
||||
|
||||
The shipper found it from the intake: PC 2 has two new engine runs (win-1ccfe586-20261005-225528 and -230330) at the exact times of its relay tasks #243 and #245, and PC 1 none since 21:40:41Z; the relay machine named "PC1" is the 1ccfe586 box and PC 1 (ae432dc7) has no relay agent. Consequences, corrected in the rollout plan 7b: every relay probe that reported the 9070 XT "absent" read PC 2 (no 9070 XT there), so the card was present on PC 1 at every app job (21:04 to 22:31) and the eGPU "drops" are withdrawn (the reseat is off the morning list; the only real fault was the install-time Code 43); the 5090 power-limit sweep ran on PC 2's 5090 (its numbers stand, the machine corrected); PC 2 was force-restarted at 22:55:28Z and 23:03:30Z (its agg-cost-pc2-3 killed; its app back at 23:04Z, pid 30484, miners up); PC 1's app is down since 22:31:06Z and unreachable tonight: the project lead relaunches it in the morning (its 0.3.11 lands then through the manifest); the fleet runs short its 141 MH/s until then; the Windows exes for 0.3.11 come from PC 2 instead. PC 2 order: the shipper's combined suites-and-exes job (now), the prover-floor build 4 and sweep 2, the aggregation-cost re-run, "PC 2 clear" for the update-now, the ledger-pc2 M16 job. No relay task to "PC1" without my word. Next-cut item: relay clients named by machine id, and a refusal of a name two boxes could answer.
|
||||
The shipper found it from the intake: PC 2 has two new engine runs (win-1ccfe586-20261005-225528 and -230330) at the exact times of its relay tasks #243 and #245, and PC 1 none since 21:40:41Z; the relay machine named "PC1" is the 1ccfe586 box and PC 1 (ae432dc7) has no relay agent. Consequences, corrected in the rollout plan 7b: every relay probe that reported the 9070 XT "absent" read PC 2 (no 9070 XT there), so the card was present on PC 1 at every app job (21:04 to 22:31) and the eGPU "drops" are withdrawn (the reseat is off the morning list; the only real fault was the install-time Code 43); the 5090 power-limit sweep ran on PC 2's 5090 (its numbers stand, the machine corrected); PC 2 was force-restarted at 22:55:28Z and 23:03:30Z (its agg-cost-pc2-3 killed; its app back at 23:04Z, pid 30484, miners up); PC 1's app is down since 22:31:06Z and unreachable tonight: the founder relaunches it in the morning (its 0.3.11 lands then through the manifest); the fleet runs short its 141 MH/s until then; the Windows exes for 0.3.11 come from PC 2 instead. PC 2 order: the shipper's combined suites-and-exes job (now), the prover-floor build 4 and sweep 2, the aggregation-cost re-run, "PC 2 clear" for the update-now, the ledger-pc2 M16 job. No relay task to "PC1" without my word. Next-cut item: relay clients named by machine id, and a refusal of a name two boxes could answer.
|
||||
|
||||
23:08. PC 2 after the restarts: agg-cost-pc2-3 died in its own-miner phases (last upload 22:51:16Z) and its finally block never ran, leaving the live prover OFF (its job switches it off at start and the app persisted it: PC 2 has not proved since 22:44Z), a stray miner beside the app's restarted 5090 miner, and a root-owned socket; "go PC 2 restore" given for tools/proving-v1/pc2-agg-cost-restore.ps1 (20 s: stray miners and workers stopped, the root server killed and the socket unlinked, the card re-enabled, the prover on); it queues behind the shipper's combined job if that is already in the file. Measured in job 3 before the restart: phase A (the app's 5090 miner at 117 MH/s mean) 7.6 to 8.0 s shards, 8.0 s unchained and 10.0 s chained aggregations, 93.8% GPU, the same as job 1. The shipper: C38's documents are in the release tree (ca2-analysis, ca2-epoch and prover-floor as docs under the built-input gate, scratch-soundness.md alone, then ca2-coord 8bef299's four docs files; tree 5debb36; identity 0 of 224, kit-path 19 of 19; G5 untouched); the Windows node exes are being cross-built on the Mac (the 0.3.9 way) as the fallback while PC 2's combined job is the preferred source (the PC's exes ship if its job lands first; the plan records which).
|
||||
|
||||
|
|
@ -688,7 +688,7 @@ The shipper: the observer, node 1 and the seed restarted with the nine-field ove
|
|||
|
||||
## 00:18 0.3.11 SHIPPED: master 30cd292 then 630da6b pushed; every live node at 0139ab9d
|
||||
|
||||
The shipper's close: release-0.3.11 (7ab72f3) merged onto master 063baf6 without conflict as 30cd292, then 630da6b (the plan's merge section), pushed 00:13:04Z and 00:15Z; CI on master in progress (37392831312 ci, 37392831184 windows-ci). The live site deployed from 30cd292 at about 00:13:45Z with every corrected sentence (24 GB proves, the schedule as the gate 1 proposal, no bounty words, no 12 GB clause). The digest sweep closed for every live node: the observer 23:56:59Z, node 1 23:57:12Z, the seed 23:57:30Z, PC 2 00:01:42Z, the Mac through node 1; all 0139ab9dc2992d449ec787d8f021974933631eb55740ab4b6ce9d5c226e72888; tip DAA 141,715 at 00:12:36Z; PC 2 105 to 116 MH/s; the Mac 25.7 MH/s with 55 accepted since its miner restart at 00:08:33Z. Pending their relaunch by hand: PC 1 (down since 22:31:06Z, on 0.3.10), the laptop 37ba0461 (silent since 23:28:28Z, off the console), Sam's Mac (0.3.9, quit 20:47Z); each takes 0.3.11 and the nine-field object through the manifest, with one possible old-node death inside the update (C39's shape) to read in the morning intake. No release tag was cut (0.3.9 and 0.3.10 have none; a convention needs the project lead's word). The shipper's plan: docs/plans/release-0.3.11.md sections 8 (step 2 times), 9 (the sweep), 11 (open items: the miner's dead gRPC channel, the HiveOS override, the prepared pack near the hour, PC 2's first-shard socket error at 23:52:14Z, the relay naming, the job queue, the edge index, C1 at 16:00Z), 12 (the merge). The activation: program_class_v3 and proving v1 at N4 = N5 = 154,800 (epoch 43), about 03:40Z on 6 October at the new side's rate; H = 210,000 about 18:56Z. The shipper is done with PC 2 for the night. Still running on PC 2 under my schedule: floor-sweep-3 (the 12 GB tier under patch v3), then the aggregation-cost re-run, M16, the repro job, the ledger-fixes-0311 suites.
|
||||
The shipper's close: release-0.3.11 (7ab72f3) merged onto master 063baf6 without conflict as 30cd292, then 630da6b (the plan's merge section), pushed 00:13:04Z and 00:15Z; CI on master in progress (37392831312 ci, 37392831184 windows-ci). The live site deployed from 30cd292 at about 00:13:45Z with every corrected sentence (24 GB proves, the schedule as the gate 1 proposal, no bounty words, no 12 GB clause). The digest sweep closed for every live node: the observer 23:56:59Z, node 1 23:57:12Z, the seed 23:57:30Z, PC 2 00:01:42Z, the Mac through node 1; all 0139ab9dc2992d449ec787d8f021974933631eb55740ab4b6ce9d5c226e72888; tip DAA 141,715 at 00:12:36Z; PC 2 105 to 116 MH/s; the Mac 25.7 MH/s with 55 accepted since its miner restart at 00:08:33Z. Pending their relaunch by hand: PC 1 (down since 22:31:06Z, on 0.3.10), the laptop 37ba0461 (silent since 23:28:28Z, off the console), Sam's Mac (0.3.9, quit 20:47Z); each takes 0.3.11 and the nine-field object through the manifest, with one possible old-node death inside the update (C39's shape) to read in the morning intake. No release tag was cut (0.3.9 and 0.3.10 have none; a convention needs the founder's word). The shipper's plan: docs/plans/release-0.3.11.md sections 8 (step 2 times), 9 (the sweep), 11 (open items: the miner's dead gRPC channel, the HiveOS override, the prepared pack near the hour, PC 2's first-shard socket error at 23:52:14Z, the relay naming, the job queue, the edge index, C1 at 16:00Z), 12 (the merge). The activation: program_class_v3 and proving v1 at N4 = N5 = 154,800 (epoch 43), about 03:40Z on 6 October at the new side's rate; H = 210,000 about 18:56Z. The shipper is done with PC 2 for the night. Still running on PC 2 under my schedule: floor-sweep-3 (the 12 GB tier under patch v3), then the aggregation-cost re-run, M16, the repro job, the ledger-fixes-0311 suites.
|
||||
|
||||
## 00:20 floor-sweep-3 green: nine points proved and verified on the v3 server; the aggregation-cost re-run has its go
|
||||
|
||||
|
|
@ -771,7 +771,7 @@ run-repro-pc2-20261006 (00:44:29Z fetch, the run 00:49:30 to 01:09:38Z, 1,509 s,
|
|||
|
||||
## 01:34 the PC 2 chain is closed: job 6's curve, the ledger suites on PC 2, the job-runner finding; the coordinator stops here
|
||||
|
||||
agg-cost-pc2-6 (01:12:09 to 01:24:14Z, 725 s, exit 0; the parse fix held; the job's own miner alone on the 5090, the finally block put the card and the prover back at 01:24:09Z). The curve, the same four live blocks 96556 to 96559, one empty shard each: batch-log2 22: shards 7.8 to 8.1 s, chained aggregation 10.0 to 10.4 s, 18.1 s a block, 103.9 MH/s; 20: the same (18.0 s, 103.7); 18: 6.7 to 7.0 and 8.8 to 8.9 s, 15.6 s a block, 99.3 MH/s (minus 4.4%); 16: 4.9 to 5.1 and 6.1 to 6.2 s, 11.1 s a block, 83.8 MH/s (minus 19%), reproduced (11.1 s, 84.0). Against the card alone (4.1 s a block, 2.1 s an aggregation): the shortest kernel buys the prover 1.6x for a fifth of the hash rate and the slowdown stays 2.7x, so the 3-second aggregation on a mining card is not reachable by the kernel length; the defaults stay; the 2^16 trade and the batch fold (a new pinned guest, about 0.7 s a block alone by the step costs, estimated) are the project lead's decision in docs/plans/proving-v1.md "Aggregation cost (5 October, night)". Branch agg-cost ea38ece (worktree igneum-wt-agg-cost, on proving-v1's docs tip 9be5817, not pushed).
|
||||
agg-cost-pc2-6 (01:12:09 to 01:24:14Z, 725 s, exit 0; the parse fix held; the job's own miner alone on the 5090, the finally block put the card and the prover back at 01:24:09Z). The curve, the same four live blocks 96556 to 96559, one empty shard each: batch-log2 22: shards 7.8 to 8.1 s, chained aggregation 10.0 to 10.4 s, 18.1 s a block, 103.9 MH/s; 20: the same (18.0 s, 103.7); 18: 6.7 to 7.0 and 8.8 to 8.9 s, 15.6 s a block, 99.3 MH/s (minus 4.4%); 16: 4.9 to 5.1 and 6.1 to 6.2 s, 11.1 s a block, 83.8 MH/s (minus 19%), reproduced (11.1 s, 84.0). Against the card alone (4.1 s a block, 2.1 s an aggregation): the shortest kernel buys the prover 1.6x for a fifth of the hash rate and the slowdown stays 2.7x, so the 3-second aggregation on a mining card is not reachable by the kernel length; the defaults stay; the 2^16 trade and the batch fold (a new pinned guest, about 0.7 s a block alone by the step costs, estimated) are the founder's decision in docs/plans/proving-v1.md "Aggregation cost (5 October, night)". Branch agg-cost ea38ece (worktree igneum-wt-agg-cost, on proving-v1's docs tip 9be5817, not pushed).
|
||||
|
||||
The ledger-fixes-0311 suites on PC 2 (build-20261006-012543, published by me from the ledger-rebase worktree at 01:25:43Z, 01:26:15 to 01:32:33Z, 378 s): the Linux node build 137 s, the Windows node build 163 s, the seven suites exit 0 in 46 s, 7 files uploaded. The 46 s says the suites ran WITHOUT the igneum-pow feature (the G6 caveat of 00:29 applies: the lottery-hash consensus tests were not compiled; the Mac run with the feature is the suite evidence, 99/1/4 on kaspa-consensus with the M20 era test the one failure, 108/0/2, 52/0, 36/0, 14/0, 23/0, 20/0 on the rest). Fork tip fbb0082a, docs tip 9872299 (ledger-rebase).
|
||||
|
||||
|
|
@ -789,12 +789,12 @@ The consequences reviewer at 04:16Z: node 1's igneum_getProvingStatus.v1 reads a
|
|||
|
||||
04:17. C47's cause, read from the shipped app (app/igneum-app/src/prover.rs, the aggregate_once doc and line 657): one aggregation attempt needs one shard proof per shard of EVERY block of the segment in this node's pool before it runs `igneum-prove-host --mode aggregate`, else it answers "segment a..b: waiting for shard proofs ... in this node's pool". With one prover (PC 2) at about 2.7 percent block coverage, eight consecutive proven blocks never occur, so proving v1 yields zero segment records on tonight's devnet by arithmetic, not by a fault; the aggregator share accumulates in escrow until the fleet reaches the proving plan's coverage rows (47 mining 5090-class cards with the shipped shard loop, 18 through the chain mode, or about 6 proving-only cards at one block per second; the proving agent's fleet table, corrected 04:30Z). The morning line: "class v3 crossed and held; proving v1 active, 0 segments proven and none expected at one prover". No PC 2 job; the proving agent confirms from PC 2's log and writes it into docs/plans/proving-v1.md. What it means for the public page: the proving line stays "every block proven" as a design, and the devnet shows the per-block shards (v0) paying while segments wait on coverage; the C1 check at 16:00Z is about the binaries, not about segments.
|
||||
|
||||
04:28. Confirmed by the proving agent from PC 2's app log (run win-1ccfe586-20261005-235130): the prover is on and the aggregator loop runs the v1 path every 42 s ("aggregator: segment N..N+7: waiting for shard proofs N/0 ... N+7/0 in this node's pool", all eight missing on every pass); one 5090 proves 13 shards per 10 minutes of about 600 blocks (2.2 percent), so each segment passes its 600-DAA deadline unproven; node 1 at 04:2xZ: pending 55, proven 0, unproven 20, paid 0. No fault, no 0.3.12 item. DECISION FOR [user] (7, the morning): the fix's shape is cards (47 mining 5090-class cards with the shard loop as shipped in 0.3.11, 18 through the chain mode on mining cards, or about 6 proving-only cards, at one block per second on empty blocks; the proving agent's fleet table, corrected 04:30Z) or a smaller proving_v1_segment_blocks for a small devnet (1 or 2 instead of 8), which is a consensus parameter and so a new override object, a new digest and a two-manifest publish at a new height (tip + 14,400, the same rules as tonight); not tonight (main's rule: no further rollout). Until then the aggregator share sits in escrow and v0 shard payouts continue; the public testnet's genesis carries v1 from day one with whatever segment length the coverage rows justify.
|
||||
04:28. Confirmed by the proving agent from PC 2's app log (run win-1ccfe586-20261005-235130): the prover is on and the aggregator loop runs the v1 path every 42 s ("aggregator: segment N..N+7: waiting for shard proofs N/0 ... N+7/0 in this node's pool", all eight missing on every pass); one 5090 proves 13 shards per 10 minutes of about 600 blocks (2.2 percent), so each segment passes its 600-DAA deadline unproven; node 1 at 04:2xZ: pending 55, proven 0, unproven 20, paid 0. No fault, no 0.3.12 item. DECISION FOR THE FOUNDER (7, the morning): the fix's shape is cards (47 mining 5090-class cards with the shard loop as shipped in 0.3.11, 18 through the chain mode on mining cards, or about 6 proving-only cards, at one block per second on empty blocks; the proving agent's fleet table, corrected 04:30Z) or a smaller proving_v1_segment_blocks for a small devnet (1 or 2 instead of 8), which is a consensus parameter and so a new override object, a new digest and a two-manifest publish at a new height (tip + 14,400, the same rules as tonight); not tonight (main's rule: no further rollout). Until then the aggregator share sits in escrow and v0 shard payouts continue; the public testnet's genesis carries v1 from day one with whatever segment length the coverage rows justify.
|
||||
|
||||
## 05:59 VERDICT PASS; H re-cut to about 19:12 to 19:20Z
|
||||
|
||||
The watcher's verdict at 05:21:48Z: PASS, class v3 after the crossing, 58.7 blocks per minute in the ten minutes before against 59.2 in the ninety after, no gap of ten minutes, DAA 160,148 and 114,611 blocks since the observer's pruning; epoch 44 (DAA 158,400) crossed clean. The reviewer's measured rate from the crossing to 05:57:38Z (DAA 162,295): 0.99 DAA/s, so H = 210,000 lands about 19:12 to 19:20Z, later than the 18:45 to 18:56 quoted overnight (the stalls pulled the earlier average forward); the 16:00Z C1 check keeps about 3.2 hours of margin and nothing in the order changes. The watcher exits on its own; the status file ends here.
|
||||
|
||||
## 07:03 PC 1 is back; the source of its 22:31Z quit is named (C35 closed); the Ember re-run waits on the project lead
|
||||
## 07:03 PC 1 is back; the source of its 22:31Z quit is named (C35 closed); the Ember re-run waits on the founder
|
||||
|
||||
PC 1's app came back at about 06:59Z (job pc1-morning-intake-1 ran 07:01:45Z); it takes 0.3.11 and the nine fields from the manifest at that start. The C35 source, from the second engine's own log (collect ember-c35-collect-1, the Ember agent, 06:59Z): the second engine the Ember playbook started reported version 0.3.9 (the branch's Cargo version), under the manifest's min_supported_version, so its updater treated 0.3.10 as urgent (the urgent rule beats the auto_update = false the playbook wrote into the copied settings), downloaded it at 22:31:02Z and ran the per-user installer at 22:31:05Z, whose PrepareToInstall sent POST /api/quit to the INSTALLED app (quit logged 22:31:06Z); the second engine then hung on the inherited pipe until the relay lane ended it. So PC 1's quit was the playbook's second engine through the installer, not an administrator prompt and not the host. Fix e600e63 on ember-tune: a second engine never runs the updater (Engine.no_ota from IGNEUM_APP_NO_OTA=1, implied by --sweep; the OTA tick skipped and Check now refused; logged at start), both playbooks set it, tools/ci/second-engine-check.sh demands it beside the file-not-pipe and tree-kill lines; 93 app tests pass. PC 2's 20:01Z quit is a different case (it came back as 0.3.9, so not an installer) and keeps the morning's prompt test. The Ember re-run (5090 baseline, the 9070 XT power ladder, no prompt) is built and held: PC 1 is the project lead's desk and he is at the machine, so it runs on his word through main, not on the night scheduler's; it needs the build of e600e63 and the two fetches republished after PC 1's update.
|
||||
PC 1's app came back at about 06:59Z (job pc1-morning-intake-1 ran 07:01:45Z); it takes 0.3.11 and the nine fields from the manifest at that start. The C35 source, from the second engine's own log (collect ember-c35-collect-1, the Ember agent, 06:59Z): the second engine the Ember playbook started reported version 0.3.9 (the branch's Cargo version), under the manifest's min_supported_version, so its updater treated 0.3.10 as urgent (the urgent rule beats the auto_update = false the playbook wrote into the copied settings), downloaded it at 22:31:02Z and ran the per-user installer at 22:31:05Z, whose PrepareToInstall sent POST /api/quit to the INSTALLED app (quit logged 22:31:06Z); the second engine then hung on the inherited pipe until the relay lane ended it. So PC 1's quit was the playbook's second engine through the installer, not an administrator prompt and not the host. Fix e600e63 on ember-tune: a second engine never runs the updater (Engine.no_ota from IGNEUM_APP_NO_OTA=1, implied by --sweep; the OTA tick skipped and Check now refused; logged at start), both playbooks set it, tools/ci/second-engine-check.sh demands it beside the file-not-pipe and tree-kill lines; 93 app tests pass. PC 2's 20:01Z quit is a different case (it came back as 0.3.9, so not an installer) and keeps the morning's prompt test. The Ember re-run (5090 baseline, the 9070 XT power ladder, no prompt) is built and held: PC 1 is the founder's desk and he is at the machine, so it runs on his word through main, not on the night scheduler's; it needs the build of e600e63 and the two fetches republished after PC 1's update.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Counter ASIC 2.0
|
||||
|
||||
Internal name, set by the project lead on 5 October 2026 (evening), for the second set of chip-resistance layers on the lottery hash. The first set is live: a random program every hour from a VDF seed, era parameters drawn every six months, a dataset that grows on a genesis schedule, instruction families that unlock by height, warp-unit CPU verification. The public claim stays as it is: a chip gains under 2x over a GPU, the model is published, the bounty stands. Nothing here is active; every layer is measured first and decided by the project lead, and every one that goes in goes in before the public testnet, as a genesis rule or a reserved family.
|
||||
Internal name, set by the founder on 5 October 2026 (evening), for the second set of chip-resistance layers on the lottery hash. The first set is live: a random program every hour from a VDF seed, era parameters drawn every six months, a dataset that grows on a genesis schedule, instruction families that unlock by height, warp-unit CPU verification. The public claim stays as it is: a chip gains under 2x over a GPU, the model is published, the bounty stands. Nothing here is active; every layer is measured first and decided by the founder, and every one that goes in goes in before the public testnet, as a genesis rule or a reserved family.
|
||||
|
||||
Trigger: the 9070 XT measurement of 5 October (bench-log "the 9070 XT on the eGPU"): the hash is bound by dependent random 4-byte reads, AMD fetches a 64-byte line per read, so AMD sits at a seventh of the 5090 and the three-vendor claim is bit-exact but not fair. Read-only data can also be mirrored into a chip's SRAM (256 MB is about 45 mm2 at a leading node, approximate).
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ Trigger: the 9070 XT measurement of 5 October (bench-log "the 9070 XT on the eGP
|
|||
| 8 | Working-set size drawn per program | one memory design cannot fit every hour | none | folds into 4 and 5 |
|
||||
| 9 | Epoch length as a signalled era parameter: base 3,600 DAA s, ladder 600 to 7,200, set by 90% signal at a day boundary, lead and `T_epoch` fixed | a per-program bitstream (an FPGA with a hard datapath): at 600 s nothing it compiles ever runs (42 to 160 min per compile, PRflow FPT 2019; hours on large parts, Aldec) | compile-ahead 1 s per epoch on the 5090, 0.5 s on the M5 Max (38 s with the race on); one CPU core `600 / epoch_len` busy on the VDF | reserve-only tonight: `docs/plans/epoch-length.md` |
|
||||
|
||||
## Decided 5 October 2026 (night), under the project lead's delegation for the devnet (`docs/plans/counter-asic-2-rollout.md` section 6)
|
||||
## Decided 5 October 2026 (night), under the founder's delegation for the devnet (`docs/plans/counter-asic-2-rollout.md` section 6)
|
||||
|
||||
| # | Decision | The number that decided it |
|
||||
|---|---|---|
|
||||
|
|
@ -37,10 +37,10 @@ Not added: divergent data-dependent branches (cost GPUs more than chips), anythi
|
|||
## The plan, in order
|
||||
|
||||
1. Experiment on branch `readwidth` (running): variants 1, 2, 3 on the M5 Max, the RTX 5090 and the RX 9070 XT; hash rate, bit-exactness across Metal, CUDA and OpenCL, CPU verifier cost, bytes per hash, latency-bound share, the chip model re-run per variant. Table in the bench log, recommendation in `docs/plans/read-width.md`. Decision rule: the widest read that keeps every card latency-bound with margin on the 5090.
|
||||
2. Decision 1 (the project lead): the width and whether the per-program mix goes in. Consequences: new test vectors, new program id, spec sections on the hash and the litepaper Mining section rewritten, the soundness checks (uniformity, no out-of-bounds, fuzz) re-run on the new class.
|
||||
2. Decision 1 (the founder): the width and whether the per-program mix goes in. Consequences: new test vectors, new program id, spec sections on the hash and the litepaper Mining section rewritten, the soundness checks (uniformity, no out-of-bounds, fuzz) re-run on the new class.
|
||||
3. Experiment 2: layer 5 (the cache-sized second table) on the three cards, same measurements, plus layer 6's schedule checked against SRAM density per node (cite the source).
|
||||
4. Soundness project for layer 3 with the cryptographer role: what is written is uniform, no short-cut avoids the writes, the verifier's scratch simulation is exact; only then a vector.
|
||||
5. Decision 2 (the project lead): layers 3, 5 and the era draws of 4 and 8, as genesis rules; layer 7 as a named reserved family in the genesis reserve, unlockable by height or by 90% signal.
|
||||
5. Decision 2 (the founder): layers 3, 5 and the era draws of 4 and 8, as genesis rules; layer 7 as a named reserved family in the genesis reserve, unlockable by height or by 90% signal.
|
||||
6. One generator change ships them all at once, before the public testnet, with the chip model and the before-and-after numbers published beside the litepaper claim.
|
||||
|
||||
## What stays true at every step
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
6 October 2026. Worker `derive` (branch `ca3-derive`), under the brief of `docs/plans/counter-asic-3.md` item 2 and
|
||||
the history audit's addition 2 (`docs/analysis/asic-resistance-history.md` section 4.3). Everything here is
|
||||
PROPOSED: a prototype behind a load class (`dr736`), measured on the Mac and on PC 2, written as a reserve entry for
|
||||
spec 1.13.2 (section 6) that lives in this file until the project lead's word. Nothing is published and no vector of class v2
|
||||
spec 1.13.2 (section 6) that lives in this file until the founder's word. Nothing is published and no vector of class v2
|
||||
or v3 moves (section 3.4).
|
||||
|
||||
What it does, in one line: the fixed-shape mixer `M_r` of spec 1.8.4, applied 72 times per item under class v3,
|
||||
|
|
@ -18,7 +18,7 @@ per item, the cache, the loads and the hash kernel are untouched.
|
|||
| Verifier per 32-lane unit, one M5 Max core, `with-lock.sh measure`, load average 4.9 / 4.5 / 5.3 | 4.875 / 4.944 ms (two rounds of 50), worst cold unit 5.241; the devnet seeds 4.872 | 10 ms | passes, 5.1 ms of margin (x8 reads 2.061 / 2.063 in the same session: 2.37x) |
|
||||
| The same on a 2019-class laptop core (2.5x, approximate, the design document's ratio; O-1.14 unmeasured) | about 12.2 ms steady, 13.1 worst cold | 10 ms | FAILS on the approximate row; the half-length class `dr368` (the x4-equivalent op count) reads 2.692 ms here, about 6.7 ms on that row, and passes |
|
||||
| Bit-exact: Metal, Apple OpenCL and CUDA (NVRTC, PC 2) against the Rust CPU interpreter, two packs | cache FNV, dataset head and word [MASK], 64 samples, 96 vector lanes, 2^24 fingerprint 50e3eaa779da4f1e (dr736-genesis, all three compilers) and 9553f6d5c667205a (dr736-devnet-epoch0, Metal and CUDA) | equal | passes on three compilers (5.2, 5.4a) |
|
||||
| Daily 1 GiB build, M5 Max, Metal, measure lock; RTX 5090, PC 2 (the card still mining, 5.4a) | 29.0 / 29.1 / 28.9 ms GPU against mx8's 22.1 / 22.1 ms in the same session (+32%); 5090 42 / 32 ms against x8's 40 and v2's 46 on the loaded card | under 1 s on every discrete card | passes on both; the 9070 XT OWED (PC 1 is the project lead's desk today) |
|
||||
| Daily 1 GiB build, M5 Max, Metal, measure lock; RTX 5090, PC 2 (the card still mining, 5.4a) | 29.0 / 29.1 / 28.9 ms GPU against mx8's 22.1 / 22.1 ms in the same session (+32%); 5090 42 / 32 ms against x8's 40 and v2's 46 on the loaded card | under 1 s on every discrete card | passes on both; the 9070 XT OWED (PC 1 is the founder's desk today) |
|
||||
| NVRTC compile per pack, RTX 5090 | 1,266 ms against x8's 164 (+1.1 s): the item function is inside every hash-kernel and race-variant compile | the 38 s compile-ahead budget at the 600-s epoch floor | the one-module-per-day fix is a requirement of the class (5.4a) |
|
||||
| Hash rate, M5 Max, Metal, measure lock; RTX 5090 (loaded) | dr736-genesis 27.06 to 27.13 MH/s GPU, mx8-genesis 27.08 to 27.16; 5090 61.1 / 62.1 against x8 62.0 and v2 62.3 | equal within noise | equal (0.3% Mac): the hash kernel does not change |
|
||||
| Chip model (section 7) | 1,278,976 chip ops per hash, 39.1 MH/s at 50 T op/s, 0.29x bare; 0.34x at a 1.2x allowance, 0.43x at 1.5x, 0.86x at the old 3x | under 1x | the allowance is the result: the 3x of the fixed shape no longer applies |
|
||||
|
|
@ -410,7 +410,7 @@ module.
|
|||
|
||||
## 6. PROPOSED spec text for 1.13.2: reserve entry R0, `derive` (the per-day item-derivation program)
|
||||
|
||||
Not written into `docs/spec`; it lives here until the project lead's word. Named R0, ahead of R1 (mm8), because the reserve
|
||||
Not written into `docs/spec`; it lives here until the founder's word. Named R0, ahead of R1 (mm8), because the reserve
|
||||
is to be ordered by chip-unfriendliness (counter-asic-3.md item 6; mm8 last) and a derivation program is the most
|
||||
chip-unfriendly entry the reserve can hold: it removes the fixed-function allowance of the recompute chip rather
|
||||
than adding a family that chip can license.
|
||||
|
|
@ -458,7 +458,7 @@ chip ops per hash, 78.2 MH/s, 0.57x bare, 0.69x at 1.2x, 0.86x at 1.5x: under 1x
|
|||
|---|---|
|
||||
| RTX 5090 unloaded: the job's card-off did not take (the settings.json key carries the device index, `nvidia:0:...`, the api/cards key of the earlier jobs did not; the fix is to post both forms and confirm by the process list) so the 5090's absolute build and rate rows are loaded figures with the ratios valid (5.4a); the fingerprints and the compile are not affected | a re-run after the key fix, on the next PC 2 slot |
|
||||
| The item function as its own NVRTC module once a day (the +1.1 s per compile of 5.4a) | unimplemented; a requirement of the class before any activation |
|
||||
| RX 9070 XT (PC 1) | OWED: PC 1 is the project lead's desk today; the same job shape runs there with `igneum-worker-opencl.exe --bench-pack` when released |
|
||||
| RX 9070 XT (PC 1) | OWED: PC 1 is the founder's desk today; the same job shape runs there with `igneum-worker-opencl.exe --bench-pack` when released |
|
||||
| The 2019-class laptop core (O-1.14) | unmeasured; the approximate row decides against 736 at genesis and for 368, and a measurement replaces it |
|
||||
| Cryptanalysis of random ARX programs | none; item 3's brief should name the day program as a target beside `M_r` |
|
||||
| The integrated tier's build with the day program | approximate (5.5); the gfx1036 measurement is a PC 2 OpenCL job, not run today (the one PC 2 job carries the 5090) |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Counter ASIC 3.0: the node side (program class v4 as a second height switch)
|
||||
|
||||
6 October 2026, worker "ca3-v4-node". Branches: `ca3-v4-node` (main repository: igneum-pow, the workers, the fast-time gate) and `ca3-v4-node` (the fork, from the 0.3.13 tip bb43e9a8). The 2.0 twin of `docs/plans/counter-asic-2-node.md`: every piece of its section 1 has its v4 twin below; v2 and v3 are byte for byte what they were (the pinned packs, `igneum-pow/tests/packs.rs`). The class: `mx8+sh256x27` (`docs/analysis/latency-shadow-2026-10-06.md`), gated here as THE class v4 candidate on the project lead's word of 16:50 UTC. Nothing is published; the Mac's app is untouched (its miner stays paused); the live devnet is untouched. Gate rows: `docs/plans/counter-asic-3-gate/node-gates.md`.
|
||||
6 October 2026, worker "ca3-v4-node". Branches: `ca3-v4-node` (main repository: igneum-pow, the workers, the fast-time gate) and `ca3-v4-node` (the fork, from the 0.3.13 tip bb43e9a8). The 2.0 twin of `docs/plans/counter-asic-2-node.md`: every piece of its section 1 has its v4 twin below; v2 and v3 are byte for byte what they were (the pinned packs, `igneum-pow/tests/packs.rs`). The class: `mx8+sh256x27` (`docs/analysis/latency-shadow-2026-10-06.md`), gated here as THE class v4 candidate on the founder's word of 16:50 UTC. Nothing is published; the Mac's app is untouched (its miner stays paused); the live devnet is untouched. Gate rows: `docs/plans/counter-asic-3-gate/node-gates.md`.
|
||||
|
||||
## 1. What changed, where
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ The hash lane found the seven gate packs under `proto-cuda/packs-ca3-v4` carryin
|
|||
|
||||
## 6. PROPOSED: miner-signalled class activation (precondition 2 of the cut)
|
||||
|
||||
Status: PROPOSED spec text for spec 01 (a new section 1.12.2 beside the epoch rule) and spec 02; implemented behind the override on the fork branch `ca3-v4-node` (`consensus/src/processes/class_signal.rs`, the pure rule in `consensus/core/src/igneum.rs`), gated by the fast-time runs of section 6.4. Not in `docs/spec` until the project lead adopts it. The 2.0 fixed height stays, as the floor.
|
||||
Status: PROPOSED spec text for spec 01 (a new section 1.12.2 beside the epoch rule) and spec 02; implemented behind the override on the fork branch `ca3-v4-node` (`consensus/src/processes/class_signal.rs`, the pure rule in `consensus/core/src/igneum.rs`), gated by the fast-time runs of section 6.4. Not in `docs/spec` until the founder adopts it. The 2.0 fixed height stays, as the floor.
|
||||
|
||||
### 6.1 The rule
|
||||
|
||||
|
|
|
|||
|
|
@ -1,33 +1,33 @@
|
|||
# The chip claim, public text (7 October 2026, 14:3x UK, on the project lead's "this needs updating with all of our updates"; served since 11:03 UK on master 9162c847 with main's two cuts: no mention of the disclosure prize until the publish word, and row 17 in evidence.md's eight-column shape)
|
||||
# The chip claim, public text (7 October 2026; REWRITTEN LAUNCH-FIRST 18:3x UK on the founder's "I thought we were making it 2.1 from launch?": the testnet and mainnet objects set program_class_v4_activation_daa to 0, so class v4 is live from genesis and the launch number is 2.1x to 3.9x on day one; the 5x to 9x is the class v3 baseline the work started from, stated only as that; the devnet's own activation height is a devnet fact only. Served since 11:03 UK on master 9162c847 with main's two cuts: no mention of the disclosure prize until the publish word, and row 17 in evidence.md's eight-column shape)
|
||||
|
||||
Three texts and one ledger row, written by the Counter ASIC lane, which owns the chip model. Every number carries its label: measured (a card or a chain we ran, with the date), modelled (arithmetic on cited parts), claimed (a vendor's figure, never measured by us), designed (a rule in a class, not yet measured). Sources: `docs/analysis/chip-model-v3.md` sections 5 and 6, `docs/analysis/latency-shadow-2026-10-06.md`, `docs/plans/counter-asic-3-status.md`, `docs/analysis/attack-pass/f8-uniform.md` and `f4-weakday.md` (branch attack-pass), `docs/design/class-v5-stored-state.md`, the datacentre and market-cap rows of 7 October (lanes 3 and the fleet), the cryptanalysis plan in `docs/plans/funding.md`.
|
||||
|
||||
## 1. The home page's chip line (replaces the hero sentence served since 6 October 16:21Z)
|
||||
|
||||
Built for graphics cards. In our public model the strongest chip reaches 5x to 9x per joule against an RTX 5090 today; class v4, now on the vote, brings that to 2.1x to 3.9x, and class v5 makes the dataset the chain's own state, so a chip that stores it or recomputes it is wrong on every item. The model and every measurement are public.
|
||||
Built for graphics cards. At launch the strongest chip in our public model reaches 2.1x to 3.9x per joule against an RTX 5090, under class v4 from the first block. Class v5 then makes the dataset the chain's own state, so a chip that stores it or recomputes it is wrong on every item. Without class v4 the same chip would reach 5x to 9x. The model and every measurement are public.
|
||||
|
||||
## 2. The litepaper's chip section (replaces the paragraph that begins "The chip model: 5x to 9x per joule")
|
||||
|
||||
The chip model. We price the strongest chip we can design against an RTX 5090 and publish the arithmetic. The honest card: an RTX 5090 mines class v3 at 136 MH/s on 350 W in the bench and 290 W in the app (measured, 6 October 2026); an Apple M5 Max at 27 MH/s on 21 W (measured, 6 October 2026); an H100 SXM at 249 MH/s, 98 percent of its random-read ceiling like the 5090, 1.78x the 5090's hash at 1.15x the tuned 5090's hash per watt and a third of the hash per rented dollar (measured, 7 October 2026), so datacentre silicon does not change the chip question. The CPU verifier takes 2.33 ms per warp of 32 hashes on one M5 Max core under class v4 (measured, 6 October 2026), against a gate of 10 ms.
|
||||
The chip model. We price the strongest chip we can design against an RTX 5090 and publish the arithmetic. Class v4 is live from the first block on the testnet and the mainnet (the ladder's rung 0 at genesis), so the launch number is the class v4 row. The honest card: an RTX 5090 mines class v3 at 136 MH/s on 350 W in the bench and 290 W in the app (measured, 6 October 2026); an Apple M5 Max at 27 MH/s on 21 W (measured, 6 October 2026); an H100 SXM at 249 MH/s, 98 percent of its random-read ceiling like the 5090, 1.78x the 5090's hash at 1.15x the tuned 5090's hash per watt and a third of the hash per rented dollar (measured, 7 October 2026), so datacentre silicon does not change the chip question. The CPU verifier takes 2.33 ms per warp of 32 hashes on one M5 Max core under class v4 (measured, 6 October 2026), against a gate of 10 ms.
|
||||
|
||||
| The chip and the class | Edge over an RTX 5090 per joule | Label and date |
|
||||
|---|---|---|
|
||||
| A memory-controller chip that stores the whole dataset (the Ethash class), class v3 | 5x to 9x (5.1x on GDDR7, 9.2x on eight HBM3 stacks; the Ethash chips of this class reached 2.1x to 4.8x) | modelled, 6 October 2026; the precedent measured by others, 2020 to 2022 |
|
||||
| The same chip under class v4 (about 100,000 integer ops per hash in the latency shadow, so the chip carries a GPU-class datapath beside its memory) | 2.1x with a core as costly per op as the GPU's (k = 1); 3.9x with the core Bitmain claimed for its Antminer X9 (k about 0.33), a product withdrawn before any unit shipped | modelled on measured card watts, 6 October 2026; the X9 figure claimed, never measured |
|
||||
| The same chip at the ladder's second rung (about 200,000 ops per hash) | about 2.8x | modelled, 7 October 2026 |
|
||||
| At launch: a memory-controller chip that stores the whole dataset, under class v4 (about 100,000 integer ops per hash in the latency shadow, so the chip carries a GPU-class datapath beside its memory) | 2.1x with a core as costly per op as the GPU's (k = 1); 3.9x with the core Bitmain claimed for its Antminer X9 (k about 0.33), a product withdrawn before any unit shipped | modelled on measured card watts, 6 October 2026; the X9 figure claimed, never measured |
|
||||
| The same chip at the ladder's second rung (about 200,000 ops per hash), reached by miner signal | about 2.8x | modelled, 7 October 2026 |
|
||||
| Any chip under class v5, where the dataset is the chain's own state | a stateless or stale chip is wrong on every item, so the stored-dataset chip and the recompute chip are removed as categories; the verifier pays 0.2 ms more per warp | designed, 7 October 2026 |
|
||||
| A chip caching the hottest 0.1 percent of items (about 1 MB of SRAM) | bounded at 1.067x at the ceiling, 1.005x on about half the hours and 1.048x on 5 percent | measured census of 1,024 programs, 7 October 2026; the source rule in the next class |
|
||||
| A per-day FPGA that recomputes the dataset with cheap multipliers on a weak day | at most 12 percent more hash rate on 12 days a century, nothing on the other days and nothing for any chip | measured census of 2^24 days, 7 October 2026; the rule in the next class |
|
||||
| When a stored-dataset chip pays for itself | at about USD 100 M of market cap in the first two years, not before | modelled, 7 October 2026 |
|
||||
| The baseline the work started from: the same chip under class v3, without the shadow (the Ethash class) | 5x to 9x (5.1x on GDDR7, 9.2x on eight HBM3 stacks; the Ethash chips of this class reached 2.1x to 4.8x) | modelled, 6 October 2026; the precedent measured by others, 2020 to 2022; never the launch state |
|
||||
|
||||
What a miner sees from this. Class v4 costs a 5090 about 80 W more for 0.2 percent of rate, an M5 Max 16 W more for 1.5 percent, an RX 9070 XT and an RTX 4070 nothing (all measured, 6 October 2026). The ladder that sets how much work rides in the shadow starts at rung 0 at the testnet genesis and climbs by miner signal; its third rung is inadmissible today because a server core verifies it in 10.85 ms, over the gate (measured, 7 October 2026). The next test of the model is not ours: the cryptanalysis plan buys three external lots against the mixer, the chained cache and the acceptance rule.
|
||||
What a miner sees from this. Class v4 costs a 5090 about 80 W more for 0.2 percent of rate, an M5 Max 16 W more for 1.5 percent, an RX 9070 XT and an RTX 4070 nothing (all measured, 6 October 2026). The ladder that sets how much work rides in the shadow starts at rung 0 at genesis and climbs by miner signal; its third rung is inadmissible today because a server core verifies it in 10.85 ms, over the gate (measured, 7 October 2026). On the devnet, which started on class v3, class v4 arrives by miner signal at a published height (a devnet fact, not a launch one). The next test of the model is an internal adversarial pass, not an independent review: three lanes that have never worked on the hash code attack the mixer, the chained cache and the acceptance rule with only what an outsider has (the public kit, the frozen object, the spec, the harnesses) and publish the break or the bound they reach. The one outside check is staged and waits on its escrow and the publish word.
|
||||
|
||||
## 3. The miner page's line
|
||||
|
||||
Your card against the strongest chip we can price: an RTX 5090 at 136 MH/s on 350 W (measured 6 October 2026), the chip 5x to 9x per joule in the public model today, 2.1x to 3.9x under class v4 (modelled on measured watts), and under class v5 wrong on every item because the dataset is the chain's own state (designed); the model and the measurements are public.
|
||||
Your card against the strongest chip we can price: an RTX 5090 at 136 MH/s on 350 W (measured 6 October 2026); at launch the chip reaches 2.1x to 3.9x per joule under class v4 (modelled on measured watts), and under class v5 it is wrong on every item because the dataset is the chain's own state (designed). Without class v4 it would be 5x to 9x. The model and the measurements are public.
|
||||
|
||||
## 4. The ledger row (docs/evidence.md row 17, in the table's eight columns as served)
|
||||
|
||||
| # | Claim | Where it is made | Status | Version or commit | Reproducible test | Result, date, machine | Independent verification |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 17 | The chip resistance claim: the strongest chip in the public model reaches 5x to 9x per joule against an RTX 5090 today; class v4 brings it to 2.1x (k = 1) to 3.9x (k about 0.33) and its second rung to about 2.8x; class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item; the hot-set cache is bounded at 1.067x at the ceiling and the weak-day FPGA at 12 percent on 12 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years | the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line | tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 core claimed and never measured | `docs/analysis/chip-model-v3.md` 5 and 6; `docs/analysis/latency-shadow-2026-10-06.md`; `docs/plans/counter-asic-3-status.md`; `docs/analysis/attack-pass/f8-uniform.md`, `f4-weakday.md`, `docs/analysis/ca3-v4-uniform.md`; `docs/design/class-v5-stored-state.md`; the H100 and market-cap rows of 7 October; `docs/plans/funding.md` (the three lots) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 5.1x to 9.2x; 2.1x, 3.9x, 2.8x; 1.067x at the ceiling; 12 percent on 12 days a century; 10.85 ms at rung 3; USD 100 M; 6 and 7 October 2026, the M5 Max, PC 2's RTX 5090, PC 1's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 | none yet; the three cryptanalysis lots are the next test |
|
||||
| 17 | The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (k = 1) to 3.9x (k about 0.33) per joule against an RTX 5090 under class v4, live from genesis on the testnet and the mainnet; the ladder's second rung brings it to about 2.8x; class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item; the hot-set cache is bounded at 1.067x at the ceiling and the weak-day FPGA at 12 percent on 12 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state) | the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line | tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 core claimed and never measured | `docs/analysis/chip-model-v3.md` 5 and 6; `docs/analysis/latency-shadow-2026-10-06.md`; `docs/plans/counter-asic-3-status.md`; `docs/analysis/attack-pass/f8-uniform.md`, `f4-weakday.md`, `docs/analysis/ca3-v4-uniform.md`; `docs/design/class-v5-stored-state.md`; the H100 and market-cap rows of 7 October; `docs/plans/cryptanalysis/in-house-pass.md` (the internal adversarial pass) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.9x, 2.8x at launch; 1.067x at the ceiling; 12 percent on 12 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, PC 2's RTX 5090, PC 1's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 | none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and the one outside check is staged and waits on its escrow and the publish word |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Counter ASIC 3.0 item 6: the reserve ordered by chip-unfriendliness (PROPOSED)
|
||||
|
||||
6 October 2026, branch `ca3-reserve`. The history audit's rank 6 (`docs/analysis/asic-resistance-history.md` section 4.3: families that force a full 32-bit datapath per lane first, `mm8` last, because int8 matrix blocks are licensable IP at every node and Least Authority's ProgPoW suggestion 5 was "watch ML hardware"). Everything here is PROPOSED text for spec 1.13.2: the order and the weights are a decision for the project lead, and nothing here touches the generator, a vector, the manifest or a consensus parameter. The measurements are in `docs/bench-log.md`, entry "6 October 2026, Counter ASIC 3.0 item 6"; this document carries the readings, the ISA facts, the chip structures and the proposed spec text.
|
||||
6 October 2026, branch `ca3-reserve`. The history audit's rank 6 (`docs/analysis/asic-resistance-history.md` section 4.3: families that force a full 32-bit datapath per lane first, `mm8` last, because int8 matrix blocks are licensable IP at every node and Least Authority's ProgPoW suggestion 5 was "watch ML hardware"). Everything here is PROPOSED text for spec 1.13.2: the order and the weights are a decision for the founder, and nothing here touches the generator, a vector, the manifest or a consensus parameter. The measurements are in `docs/bench-log.md`, entry "6 October 2026, Counter ASIC 3.0 item 6"; this document carries the readings, the ISA facts, the chip structures and the proposed spec text.
|
||||
|
||||
## 1. The step cost per family per card
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ Method (the int8 analysis's, `docs/analysis/int8-matrix-family.md` section 4): a
|
|||
| comparison: dp4a | dot4u 1.60 (emulated), dot4s 4.73 (emulated) | as the 5 October rows (1.6x, 4.7x) | 1.16 (0.625; 6,870), `__dp4a` (1.17x on 5 October) | 1.06x on 5 October (`v_dot4_i32_iu8`) |
|
||||
| comparison: mm8 as a chain | mm8 | OWED (Metal 4 `matmul2d`; Swift 5.8 toolchain has no tensor API) | 2.43 (1.313; 3,272), one `mma.sync.m8n8k16.u8` per warp per step, bit-exact (the fragment layout confirmed) | OWED (WMMA) |
|
||||
|
||||
The three Mac runs agree within 4% on every row and the three 5090 runs within 3% (12% on `shl`, which caught the clock ramp); every row on both cards is bit-exact. The AMD column is the owed row: PC 1 is the project lead's desk today.
|
||||
The three Mac runs agree within 4% on every row and the three 5090 runs within 3% (12% on `shl`, which caught the clock ramp); every row on both cards is bit-exact. The AMD column is the owed row: PC 1 is the founder's desk today.
|
||||
|
||||
What the Mac rows say. Six of the seven candidates cost at most the live `rotr` on Apple. The two Apple pays for: `perm` at 1.13x (no byte-permute function in MSL, the `uchar4` swizzle compiles to shifts and masks) and `shfla` at 1.91x (`simd_shuffle` by a computed lane index against `simd_shuffle_xor`, 2.2x the live shuffle). Both are inside the 8x per-op bound of 1.13.2 by a wide margin, and at `W_new` = 4 points of the 64-instruction program a 1.91x op is under 1% of the program's ALU time on a hash that spends its time on 128 dependent DRAM reads (approximate: argued from the step cost and the weight, not measured; the 5% rule is checked on the vendor's card with the family live, as 1.13.2 says).
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ Ranked by the structure a chip must add beyond the class v3 datapath (section 3)
|
|||
| R7 | andn | an inverter; last of the datapath families | 4 | era 7 |
|
||||
| R8 | `mm8` (integer matrix) | licensable IP at every node; the vendor-emulation rule written for it | 4 (as decided 5 October) | era 8 (day 1,440), or earlier by the 90% signal |
|
||||
|
||||
The decision this moves for the project lead: `mm8` was reserved on 5 October as R1 with an unlock at era 4. Under the rule "family n at era n" an eighth slot unlocks at era 8 (four years). Either the rule stays and `mm8` waits, or the entry keeps its era-4 unlock as a named exception (the text below keeps the era-4 date as an exception and says so).
|
||||
The decision this moves for the founder: `mm8` was reserved on 5 October as R1 with an unlock at era 4. Under the rule "family n at era n" an eighth slot unlocks at era 8 (four years). Either the rule stays and `mm8` waits, or the entry keeps its era-4 unlock as a named exception (the text below keeps the era-4 date as an exception and says so).
|
||||
|
||||
## 6. PROPOSED spec text for 1.13.2 (replaces the paragraph from "The order and `W_new` are Open" to the end of the `mm8` entry)
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ The decision this moves for the project lead: `mm8` was reserved on 5 October as
|
|||
>
|
||||
> R7, `andn`. Semantics: `dst = dst AND NOT src`. Native everywhere. Edge vectors: `src` = 0 (identity), 0xFFFFFFFF (0), `src` = `dst` (0); `dst` = 0xAAAAAAAA with `src` = 0x55555555 (unchanged).
|
||||
>
|
||||
> R8, `mm8` (integer matrix): the entry decided 5 October 2026, text unchanged (semantics, `W_new` = 4, the six edge vectors, native paths, the vendor-that-can-only-emulate rule), with one change: it is the eighth reserve family. Its unlock stays the start of era 4 (DAA 62,208,000) as a named exception to "family n at era n", or moves to era 8 if the project lead keeps the rule; one of the two is decided before the public testnet genesis.
|
||||
> R8, `mm8` (integer matrix): the entry decided 5 October 2026, text unchanged (semantics, `W_new` = 4, the six edge vectors, native paths, the vendor-that-can-only-emulate rule), with one change: it is the eighth reserve family. Its unlock stays the start of era 4 (DAA 62,208,000) as a named exception to "family n at era n", or moves to era 8 if the founder keeps the rule; one of the two is decided before the public testnet genesis.
|
||||
|
||||
The `andn` and `sel` entries carry a note for the generator: both are injecting in the sense of 1.4.1 only when the acceptance rule counts them so (`sel` writes `src` into `dst` on half the lanes; `andn` is not bijective in `dst`), so neither satisfies rule (b) of 1.4.6 alone; the weak-program census is re-run with each family at its unlock rehearsal.
|
||||
|
||||
|
|
@ -132,9 +132,9 @@ The `andn` and `sel` entries carry a note for the generator: both are injecting
|
|||
| Item | State |
|
||||
|---|---|
|
||||
| RTX 5090 step costs (every row) | MEASURED (job `run-ca3-family-pc2-20261006`, 08:42Z to 08:43Z, the card to itself, every row bit-exact) |
|
||||
| RX 9070 XT step costs (every row) | OWED: PC 1 is the project lead's desk and not used today; the OpenCL twin of the probe is the next job on that card |
|
||||
| RX 9070 XT step costs (every row) | OWED: PC 1 is the founder's desk and not used today; the OpenCL twin of the probe is the next job on that card |
|
||||
| `mm8` as a chain on Apple (Metal 4 `matmul2d`) | OWED (toolchain) |
|
||||
| AMD `ds_bpermute_b32` cost for `shfla` | OWED (the PC 1 row); decides whether R3 moves |
|
||||
| The 5% hash-rate rule per family with the family live | argued, not measured, for every family (no reserve family is in a live program); measured at each unlock rehearsal |
|
||||
| RDNA 3 and RDNA 4 ISA guides (the instruction text) | AMD's CDN refused the PDFs again; the mnemonics are from the LLVM tables |
|
||||
| the project lead's decisions | the order R1 to R8; `W_new` = 4 per family; `mm8` at era 4 by exception or at era 8 by the rule |
|
||||
| The founder's decisions | the order R1 to R8; `W_new` = 4 per family; `mm8` at era 4 by exception or at era 8 by the rule |
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,6 @@
|
|||
# Counter ASIC 3.0
|
||||
|
||||
The third set of chip-resistance layers, from the ASIC-history agent's audit of 5 October 2026 (`docs/analysis/asic-resistance-history.md`, branch asic-history: 31 chip histories with the gain per joule, the months held and the response; the chip economics; the audit of class v2 and of every Counter ASIC 2.0 layer). The rule is the 2.0 rule: every item is measured the same way (the three cards we own, the chip model per variant, bit-exactness, the verifier cost), what passes is folded into the class as v4 behind its own activation (`program_class_v4_activation_daa`, by DAA height like v3), under the same six gates and the same rollout shape (`docs/plans/counter-asic-2-rollout.md`). Nothing here is active; nothing touches the devnet until it has its measurement and the project lead's word. Written at 22:4x UTC on 5 October 2026, after the 2.0 class was decided and before its publish.
|
||||
The third set of chip-resistance layers, from the ASIC-history agent's audit of 5 October 2026 (`docs/analysis/asic-resistance-history.md`, branch asic-history: 31 chip histories with the gain per joule, the months held and the response; the chip economics; the audit of class v2 and of every Counter ASIC 2.0 layer). The rule is the 2.0 rule: every item is measured the same way (the three cards we own, the chip model per variant, bit-exactness, the verifier cost), what passes is folded into the class as v4 behind its own activation (`program_class_v4_activation_daa`, by DAA height like v3), under the same six gates and the same rollout shape (`docs/plans/counter-asic-2-rollout.md`). Nothing here is active; nothing touches the devnet until it has its measurement and the founder's word. Written at 22:4x UTC on 5 October 2026, after the 2.0 class was decided and before its publish.
|
||||
|
||||
## The ranked additions
|
||||
|
||||
|
|
@ -9,14 +9,14 @@ The third set of chip-resistance layers, from the ASIC-history agent's audit of
|
|||
| 1 | The partial-store chip and the time-memory curve: price a chip that holds a fraction f of the dataset (f = 0.25, 0.5, 1) on HBM3 or GDDR7 with 4-byte access granularity and recomputes the rest, scored in energy per hash | the only chip class that beat a memory-bound GPU hash (Ethash: 2.1x Linzhi 2020, 2.9x E9 2022, 4.8x per joule Jasminer X4 2021) did it with custom memory controllers and on-package memory, not an on-die dataset; chip-model-v3.md prices only f = 0 | `docs/analysis/chip-model-v3.md`, O-1.6, MEMHARD.md section 3 item 2 (the curve never drawn) | analysis, before the public testnet's vectors freeze; the first item |
|
||||
| 2 | A random item-derivation program per day in place of the fixed-shape mixer (RandomX's SuperscalarHash idea) | the fixed mixer shape IS the 3x fixed-function allowance that turns x8's 0.31x into 0.92x; removing it is worth more than x16 (0.46x with the factor) | a reserve family now; genesis if the per-day compiled derivation verifies under the 10 ms gate (unmeasured); risks: cryptanalysis of random ARX, weak draws, bit-exact compilation on three vendors; the daily build about doubles (23 to 77 ms, approximate) | design and the verifier measurement |
|
||||
| 3 | External cryptanalysis of the mixer M_r, the chained cache and the acceptance rule, with the x8 shape as the target | MTP fell from 2 GB to under 1 MB before launch (Dinur and Nadler 2017), Catena's proofs were flawed, Argon2i's parameters were attackable; RandomX bought four audits for about $141,000 before launch; x8 multiplies the mixer's weight in the chip model, so a structural shortcut is worth 8x more | ledger M7, raised to a genesis gate | commission before genesis |
|
||||
| 4 | The clock and the detector: (a) a share-pattern detector on the observer (per-program hash-rate spread, nonce-group patterns, per-card-model rate bands; alert when a population behaves like one fixed design: how MoneroCrusher found Monero's secret chips at 85% of the hashrate, February 2019); (b) the audit-and-benchmark trigger as daily issuance in dollars, not a date (no device bounty: the project lead, 6 October 2026, 17:35 UTC, ledger M1; the trigger brings forward the paid cryptanalysis and the benchmark's next round) (compute-bound hashes got chips at $20K to $30K a day: Radiant, Kadena, Handshake; Vorick's 2018 rule about $55K a day) | not a layer: the response time | the observer (`tools/observer`), D11 (no device bounty; the trigger brings forward the paid cryptanalysis and the benchmark round) | before the public testnet |
|
||||
| 4 | The clock and the detector: (a) a share-pattern detector on the observer (per-program hash-rate spread, nonce-group patterns, per-card-model rate bands; alert when a population behaves like one fixed design: how MoneroCrusher found Monero's secret chips at 85% of the hashrate, February 2019); (b) the audit-and-benchmark trigger as daily issuance in dollars, not a date (no device bounty: the founder, 6 October 2026, 17:35 UTC, ledger M1; the trigger brings forward the paid cryptanalysis and the benchmark's next round) (compute-bound hashes got chips at $20K to $30K a day: Radiant, Kadena, Handshake; Vorick's 2018 rule about $55K a day) | not a layer: the response time | the observer (`tools/observer`), D11 (no device bounty; the trigger brings forward the paid cryptanalysis and the benchmark round) | before the public testnet |
|
||||
| 5 | Rank layer 9 (the epoch length) above layer 7 and measure the FPGA lane: a soft-overlay FPGA with HBM (reads in flight per watt against the 5090's 17.5 G/s) added to the compile-ahead measurement | FPGAs were the first adversary of Lyra2REv2 (2018) and X16R (1.3x, September 2019) and came back within weeks of X16Rv2; Xelis forked for FPGA resistance (July 2024); a per-hour compiled program is a bitstream target | `docs/plans/epoch-length.md` | measurement before the public testnet |
|
||||
| 6 | Order the reserve by chip-unfriendliness: the 32-bit datapath families first (byte permute, bit-field extract, variable shifts, popcount, select, the second shuffle), mm8 last | int8 matrix blocks are licensable IP at every node; Apple pays 1.6x to 4.7x per emulated dot4; Least Authority's ProgPoW suggestion 5 was "watch ML hardware" | spec 1.13.2 | a decision for the project lead with the 3.0 measurements |
|
||||
| 6 | Order the reserve by chip-unfriendliness: the 32-bit datapath families first (byte permute, bit-field extract, variable shifts, popcount, select, the second shuffle), mm8 last | int8 matrix blocks are licensable IP at every node; Apple pays 1.6x to 4.7x per emulated dot4; Least Authority's ProgPoW suggestion 5 was "watch ML hardware" | spec 1.13.2 | a decision for the founder with the 3.0 measurements |
|
||||
| 7 | A vendor-share metric (hashrate by vendor) published with the benchmark | the 7.5x AMD gap is a softer form of the capture the history records (Kaspa's GPU share went to nothing within months of KS0) | the numbers page, the observer | with the public benchmark |
|
||||
|
||||
Placed nowhere, with the reasons in the history document's section 4.3: per-hash programs (the 25x GPU penalty RandomX pays), Verthash's table-from-chain, Grin's dual PoW, Autolykos non-outsourceability, a per-hash VRF (NexaPow's got a 3x to 4x chip), ternary or variable-precision ops, cache-timing reads (measured out as layers 3 and 5), branches and floating point (excluded).
|
||||
|
||||
## Decisions for the project lead raised by the history
|
||||
## Decisions for the founder raised by the history
|
||||
|
||||
Add the partial-store rows before the vectors freeze; name the random derivation as a reserve family and fund its verifier measurement; commission the mixer cryptanalysis; put the paid cryptanalysis and the benchmark round on an issuance trigger and build the detector; rank the epoch-length reserve above mm8.
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Mac seed relay on 26680/26681) and the seed's v3 unit all still run the v3 chain
|
|||
|
||||
## The order
|
||||
|
||||
### (a) the project lead stops the PC
|
||||
### (a) the founder stops the PC
|
||||
|
||||
In both windows on the PC: Ctrl+C (the mining window first, then the node window; or one window if START-IGNEUM.bat
|
||||
was running: it stops the miners first, then the node). Wait for "Igneum has stopped" / "The node has stopped". Expected:
|
||||
|
|
@ -58,7 +58,7 @@ kill -INT 72139
|
|||
```
|
||||
|
||||
Where the Mac miner runs (the Metal worker, `/tmp/igneum-devnet/metal-worker.log`): restart it from
|
||||
`target-integration/release/igneum-miner` with `--evm-address 0x...` (any address the project lead holds) once node 1 is up; an
|
||||
`target-integration/release/igneum-miner` with `--evm-address 0x...` (any address the founder holds) once node 1 is up; an
|
||||
old miner's blocks are rejected from the first epoch boundary (DAA 3,600).
|
||||
|
||||
Expected after (b): `igneum-miner watch 1 grpc://127.0.0.1:26610` prints `blocks=1 headers=1 ... peers=0 synced=true`
|
||||
|
|
@ -78,11 +78,11 @@ Expected output of the switch: `igneumd: disabled/inactive igneumd-v4: enabled
|
|||
within a minute once node 1 (which dials the seed) has connected and the few v4 blocks have crossed. `./health.sh` then
|
||||
prints `unit=active-v4`. The seed never mines; it relays. Rollback of this step alone: `./switch-v4.sh igneum-seed-1 --back`.
|
||||
|
||||
### (d) the project lead starts the PC on v4
|
||||
### (d) the founder starts the PC on v4
|
||||
|
||||
1. Extract `igneum-windows-v4.zip` to a FRESH folder, for example `C:\igneum-v4` (not over the old one: the old
|
||||
package's built workers and packs must not be mixed in).
|
||||
2. Double-click `START-IGNEUM.bat`. Settings at the top are already right (peers, `devnet-v4`, `MINERS=8`). If the project lead
|
||||
2. Double-click `START-IGNEUM.bat`. Settings at the top are already right (peers, `devnet-v4`, `MINERS=8`). If the founder
|
||||
wants a specific payout address, set `PAYOUT_EVM=0x...` first; otherwise the launcher derives one per card and prints it.
|
||||
3. Firewall prompt for the new `igneumd.exe` path: tick Private networks, Allow access (new exe path = new prompt).
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Prepared by the rollout engineer; the Hetzner rehearsal (section 7) passed. Nothing in this file has been run on the
|
||||
devnet. The main session runs it in the order of section 4. Background: `docs/analysis/difficulty-2026-10-04-oscillation.md`
|
||||
(the finding, rule v2, section 8 rollout), `docs/bench-log.md` "difficulty rule v2". the project lead approved the rollout on
|
||||
(the finding, rule v2, section 8 rollout), `docs/bench-log.md` "difficulty rule v2". The founder approved the rollout on
|
||||
4 October 2026 ("1-5 approved and anything else needed") with two constraints, both built in here: the PCs get
|
||||
igneumd v2 only through an OTA app version, and the activation height leaves at least three hours from the manifest
|
||||
publish.
|
||||
|
|
@ -36,7 +36,7 @@ they are the 3bfe346f miner (seed-mismatch and stall guards). The Hetzner roll s
|
|||
|
||||
## 3. The activation height N, and how every node learns it
|
||||
|
||||
Rule (the project lead, 4 October 2026): `N = DAA score at the manifest publish + 10,800` (three hours at 1 block/s). Why three
|
||||
Rule (the founder, 4 October 2026): `N = DAA score at the manifest publish + 10,800` (three hours at 1 block/s). Why three
|
||||
hours: the apps check the manifest on start and every 60 minutes plus up to 10 minutes of jitter, then download, then
|
||||
wait for a safe moment (synced node, no program boundary within 180 s, no worker starting; up to 6 hours), and the
|
||||
"urgent" path (install at once, red bar) opens only when the node's DAA score is within 1,800 blocks of N
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Ember Tune: every card tuned for MH per watt, out of the box
|
||||
|
||||
5 October 2026, night. the project lead: "make sure we have ember tuning every single card for efficiency out of the box, the
|
||||
5 October 2026, night. The founder: "make sure we have ember tuning every single card for efficiency out of the box, the
|
||||
more data = the better the tune, make an awesome system." Branch `ember-tune`, worktree `../igneum-wt-ember-tune`,
|
||||
on top of the AMD telemetry commit (7adcd4c, branch `opencl-rdna4-telemetry`) and the Power control commit (3562f26,
|
||||
branch `job-console`), both cherry-picked. Lever 3 of docs/plans/miner-eff.md grows two knobs and a fleet memory;
|
||||
|
|
@ -148,7 +148,7 @@ Tonight's constraints, read from PC 1's own uploads: the installed app runs as `
|
|||
`elevated=False` (the account line at 19:02:33 UTC), the two in-app sweep attempts at 20:09 UTC aborted on the
|
||||
cancelled administrator prompt (`SWEEP aborted ... the_elevated_helper_did_not_run_(the_administrator_prompt_was_cancelled)`),
|
||||
so no stored sweep result exists from today, and the RX 9070 XT left the PCI bus at about 20:40 UTC (eGPU link,
|
||||
not restarted tonight). NVIDIA's `-pl` and `-lgc` need administrator rights, the project lead is asleep, and the app never raises
|
||||
not restarted tonight). NVIDIA's `-pl` and `-lgc` need administrator rights, the founder is asleep, and the app never raises
|
||||
the prompt by itself, so tonight's run on PC 1 is the baseline plan on the 5090 through the whole pipeline (probe,
|
||||
measure, TUNE record, upload, aggregation, prior shape in a test manifest). The two-knob tune on the 5090 and the
|
||||
9070 XT run are owed: the 5090 the moment Power control is switched on (one prompt, then the tune runs by itself
|
||||
|
|
@ -161,7 +161,7 @@ maximum, 14,001 MHz memory; 9070 XT present on bus 98 with OFFSET ranges `gmax_r
|
|||
10`). The offset finding changed the AMD mapping (054e041): an offset clock range closes the clock knob and the power
|
||||
ladder runs on a percent scale bounded by `plimit_range`. The re-run follows the 0.3.11 rollout.
|
||||
|
||||
## 6a. A card never shows 0 MH/s without a reason word (the project lead, 6 October 2026, watching PC 1 during run 5)
|
||||
## 6a. A card never shows 0 MH/s without a reason word (the founder, 6 October 2026, watching PC 1 during run 5)
|
||||
|
||||
Rule: the Mine page's rate column is blank, never "0", when a card is not mining, and the row's word says why:
|
||||
`mining`, `tuning: step k of n · measuring W W` (the live rate stays in the rate column), `held for a remote job:
|
||||
|
|
@ -208,7 +208,7 @@ Threat note, `reregister` (6 October 2026): the verb takes no path. The helper,
|
|||
exe from the two install folders itself (`powertask::install_candidates`), so the most a writer of `cmd.txt` can do
|
||||
is point the task back at the installed app. The exposure that remains is the one every per-user install with a
|
||||
highest-run task has: the install folder is the user's own, so a process running as the user can replace the exe the
|
||||
task runs. The installer's code signature and the OTA's hash check are the answer to that, not the task. (0.3.13; the project lead, 6 October 2026, 11:50 UTC)
|
||||
task runs. The installer's code signature and the OTA's hash check are the answer to that, not the task. (0.3.13; the founder, 6 October 2026, 11:50 UTC)
|
||||
|
||||
What 0.3.12 does: Power control on raises one prompt and sets every cap in that step; every later cap (an app start, a
|
||||
reboot, a slider move) and every tune's helper is another elevated launch, so another prompt. Not "once, ever".
|
||||
|
|
@ -231,7 +231,7 @@ process, registry key or other binary is reachable through it. Tests: `powertask
|
|||
non-digit or extra argument, the arguments reach nvidia-smi as a list, the registration is per-user, highest,
|
||||
trigger-less and quote-safe, a stale command file runs nothing).
|
||||
|
||||
### Run 6 (6 October 2026, 16:01Z, PC 1 on 0.3.13 with kit-6 = 564bdea, elevated, the project lead's one click)
|
||||
### Run 6 (6 October 2026, 16:01Z, PC 1 on 0.3.13 with kit-6 = 564bdea, elevated, the founder's one click)
|
||||
|
||||
The scheduled task registered inside the run ("helper registered=true"), but its action was the run's scratch copy
|
||||
(`igneum-tune-20261006-170105\bin\igneum-app.exe`): `task_exe` preferred the installed exe only for a path under
|
||||
|
|
@ -327,7 +327,7 @@ Earlier (shipped in 0.3.12 and 0.3.13 unless marked):
|
|||
prior that is wrong on both knobs.
|
||||
- Intel: no knob yet; the row says measure only.
|
||||
|
||||
## 7a. One administrator approval, ever (0.3.13; the project lead, 6 October 2026, 11:50 UTC)
|
||||
## 7a. One administrator approval, ever (0.3.13; the founder, 6 October 2026, 11:50 UTC)
|
||||
|
||||
What 0.3.12 does: Power control on raises one prompt and sets every cap in that step; every later cap (an app start, a
|
||||
reboot, a slider move) and every tune's helper is another elevated launch, so another prompt. Not "once, ever".
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Epoch length as an era parameter (Counter ASIC 2.0, layer 9)
|
||||
|
||||
5 October 2026 (night), branch `ca2-epoch`, worker "ca2-epoch". the project lead: "what about faster program changes?". Status: Designed, with one Measured section (the Mac compile-ahead, section 6) and cited figures for the PC cards. Reserve-only tonight: nothing here changes the devnet's 3,600-DAA-s epoch, no code moves, no consensus effect. The parameter joins the era-parameter table of spec 01 section 1.13.1 beside the layer 4 and 8 draws of `docs/plans/era-layout.md` (branch `ca2-era`).
|
||||
5 October 2026 (night), branch `ca2-epoch`, worker "ca2-epoch". The founder: "what about faster program changes?". Status: Designed, with one Measured section (the Mac compile-ahead, section 6) and cited figures for the PC cards. Reserve-only tonight: nothing here changes the devnet's 3,600-DAA-s epoch, no code moves, no consensus effect. The parameter joins the era-parameter table of spec 01 section 1.13.1 beside the layer 4 and 8 draws of `docs/plans/era-layout.md` (branch `ca2-era`).
|
||||
|
||||
## 1. What the layer is
|
||||
|
||||
|
|
@ -333,4 +333,4 @@ Reading, with every caveat in the table: at the only measured FPGA random-read r
|
|||
| The chain | 6% of each epoch in difficulty settle at 2,400, 24% at 600 | nothing |
|
||||
| Reversibility | by the same 90% signal, up or down, in 9 days | a family unlocked by height stays; by signal it can be voted off, but the vendors' relative rates are what they are while it is on |
|
||||
|
||||
Ranking: layer 9 sits above layer 7 in the reserve. Layer 9 removes one adversary class outright (the per-program bitstream, the first adversary of Lyra2REv2 and X16R in the history), costs every GPU tier under 2% at the first step and under 1% with the race off, and is reversible by the same signal that set it. Layer 7 removes no adversary class (every chip and every FPGA has an int8 dot product; the history's "watch ML hardware"), and its cost lands on one honest tier, Apple at 1.6x per emulated op, with a 10% relative shift against AMD. The chip model does not move for either (the on-die recompute chip's cost is the item derivation): layer 9's value is response time against the FPGA lane, layer 7's is a family a 12-op chip lacks, which the overlay and the chip both acquire cheaply. Item 6 (order the reserve by chip-unfriendliness, mm8 last) follows from the same two tables. Decision for the project lead: reserve order layer 9 (epoch length, already live at the base) first, the 32-bit datapath families next, mm8 last; and fund one HBM FPGA hour to replace the ceiling row of 12.2 with a measurement before the public testnet's benchmark page claims a number for this lane.
|
||||
Ranking: layer 9 sits above layer 7 in the reserve. Layer 9 removes one adversary class outright (the per-program bitstream, the first adversary of Lyra2REv2 and X16R in the history), costs every GPU tier under 2% at the first step and under 1% with the race off, and is reversible by the same signal that set it. Layer 7 removes no adversary class (every chip and every FPGA has an int8 dot product; the history's "watch ML hardware"), and its cost lands on one honest tier, Apple at 1.6x per emulated op, with a 10% relative shift against AMD. The chip model does not move for either (the on-die recompute chip's cost is the item derivation): layer 9's value is response time against the FPGA lane, layer 7's is a family a 12-op chip lacks, which the overlay and the chip both acquire cheaply. Item 6 (order the reserve by chip-unfriendliness, mm8 last) follows from the same two tables. Decision for the founder: reserve order layer 9 (epoch length, already live at the base) first, the 32-bit datapath families next, mm8 last; and fund one HBM FPGA hour to replace the ceiling row of 12.2 with a measurement before the public testnet's benchmark page claims a number for this lane.
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ k_off = below(3) window = the dataset, a half or a quarter
|
|||
o = low32(next()) AND (2^k_off - 1) which aligned window
|
||||
```
|
||||
|
||||
Bounds: the window never goes below `2^26` words (256 MiB; `k = min(k_off, D - 26)` in 1.3), which exceeds the largest on-chip cache of any card in the benchmark (the RTX 5090's 96 MiB L2, the RX 9070 XT's 64 MB Infinity Cache, vendor figures), and never above the dataset. At the prototype dataset (2^28) the windows are 1 GiB, 512 MiB and 256 MiB; at the genesis dataset (2^29) 2 GiB, 1 GiB and 512 MiB. The dataset grows by the step schedule recommended to the project lead (spec 01 section 1.13.3 option (b), `docs/analysis/card-lifetime-2026-10-05.md`: power-of-two steps, 4 GiB at year 4, 8 GiB at year 12, 16 GiB at year 28, 32 GiB at year 60, every index `AND MASK`), so the window ceiling follows the steps and the floor stays the genesis constant 2^26 words; nothing in the address of 1.3 needs a range reduction. A program has 16 load sites and so up to 16 windows; the set a program reads is their union (section 7 computes its distribution). The verifier bound is unchanged (1.2).
|
||||
Bounds: the window never goes below `2^26` words (256 MiB; `k = min(k_off, D - 26)` in 1.3), which exceeds the largest on-chip cache of any card in the benchmark (the RTX 5090's 96 MiB L2, the RX 9070 XT's 64 MB Infinity Cache, vendor figures), and never above the dataset. At the prototype dataset (2^28) the windows are 1 GiB, 512 MiB and 256 MiB; at the genesis dataset (2^29) 2 GiB, 1 GiB and 512 MiB. The dataset grows by the step schedule recommended to the founder (spec 01 section 1.13.3 option (b), `docs/analysis/card-lifetime-2026-10-05.md`: power-of-two steps, 4 GiB at year 4, 8 GiB at year 12, 16 GiB at year 28, 32 GiB at year 60, every index `AND MASK`), so the window ceiling follows the steps and the floor stays the genesis constant 2^26 words; nothing in the address of 1.3 needs a range reduction. A program has 16 load sites and so up to 16 windows; the set a program reads is their union (section 7 computes its distribution). The verifier bound is unchanged (1.2).
|
||||
|
||||
Why per load site and not per program: a per-program window of a quarter of the dataset would hand a 256 MiB SRAM mirror a third of the hours at the prototype size. Sixteen sites with drawn offsets cover the dataset with high probability (section 7), so the mirror a chip would need is the whole dataset in every hour, and the hour-to-hour variation lands on the memory design (which quarter, which half, how many distinct windows), not on its size.
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ Until the 1-hour VDF of section 4.4 is in the node, in the shape of the epoch se
|
|||
|
||||
The era of a block is `floor(DAA score / 15,552,000)`, a function of the header alone. `E_n` for `n >= 1` is known 7,200 DAA seconds before the era starts, which covers the 1-hour VDF when it arrives and the kernel compile and dataset rebuild now. Test seeds for packs and tests: `E_n` = the 32 bytes (little-endian words) of `seed_words_from_bytes("igneum-era-test/<n>")` (`igneum-pow ... --era igneum-era-test/<n>`, the number only names the pack); raw bytes with `--era <n>:<64 hex>`.
|
||||
|
||||
## 3. Memory budget (the project lead, 5 October 2026: under 6 GB on an 8 GB card)
|
||||
## 3. Memory budget (the founder, 5 October 2026: under 6 GB on an 8 GB card)
|
||||
|
||||
The era layout adds no resident memory: a window is a mask and an offset in the kernel text, the interleave is address arithmetic, the stride is two operations. The whole working set on a card, every item from this branch and the others:
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ Filled from a CPU census over programs (section 6).
|
|||
## 8. What is unverified
|
||||
|
||||
- Everything in section 6 marked pending.
|
||||
- The 1-hour VDF does not exist; the devnet stand-in of section 2 is a proposal.
|
||||
- The 1-hour VDF: BUILT on 7 October 2026 (era VDF lane, after the attack pass's F7 row named it the gating dependency): `kaspa_consensus_core::era_vdf` (the class-group Wesolowski scheme on a fixed-width integer and the hash-chain fallback behind the genesis byte `vdf_scheme`), `kaspa_consensus::processes::era_vdf` (the cut rule, the day-of-blues input, the evaluator thread, the record store), behind `Params::era_vdf_activation_daa` (never on every network until the founder's word per network); the stand-in of section 2 stands below the activation and is what the VDF reads its input from above it. Verified: the F7 re-roll harness against the real era cut fires with the VDF off and is silent with it on across 6 cuts (`tools/era-vdf/reroll.mjs`, the record `docs/analysis/era-vdf-2026-10-07.md` section 3), the parameters and the measured prove and verify times are in spec 04 section 4.6. Still unverified: the P2P relay of a record to a syncing peer (spec 4.5, owed before era 1 of any network with the switch set), the binding of the cut to the certified checkpoint (left at the O-4.3 reading, one function to change), an external review of the class-group port (O-4.1), and the 2019-class-core verify time, which is measured on a proxy until a 2019 host is rented (record section 5).
|
||||
- The interleave's value against a chip with a programmable address decoder is nil (1.2); the claim is limited to hard-wired layouts.
|
||||
- The window floor of 2^26 words is set by the 5090's L2 (96 MiB) and the 9070 XT's Infinity Cache (64 MB, vendor figures); a future card with a larger cache moves the floor, which is a genesis constant.
|
||||
- No cryptanalysis of the stride (a multiply and a rotate before the mask); it is a bijection, so the address distribution is that of the register value, as today.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Explorer: plan and recommendation
|
||||
|
||||
5 October 2026, after the project lead read WhatToMine's listing requirements ("build it, and do we build our own explorer? who
|
||||
5 October 2026, after the founder read WhatToMine's listing requirements ("build it, and do we build our own explorer? who
|
||||
built etherscan?"). Branch `explorer`. What exists tonight: the public stats API (`docs/api/public-stats.md`) and the
|
||||
first DAG explorer pages on the site, fed by the observer. What is recommended: Blockscout for the EVM side, our own
|
||||
DAG and mining pages, one shared search box.
|
||||
|
|
@ -9,7 +9,7 @@ DAG and mining pages, one shared search box.
|
|||
|
||||
| Explorer | What it is | Licence and cost | Fit for Igneum |
|
||||
|---|---|---|---|
|
||||
| Etherscan | Built and launched in 2015 by Matthew Tan (CEO and founder); the office since January 2017 (etherscan.io/aboutus, read 5 October 2026; the page does not name the city, the project lead's brief says Kuala Lumpur). Since 2020 it sells "Explorer as a Service", a white-label instance for other chains, 40 clients by 2025 (same page) | Closed source, a private company; a chain pays for an instance. Price not published; not asked | Not for us: closed, paid, and it would show nothing of the DAG, the finality or the proving layer |
|
||||
| Etherscan | Built and launched in 2015 by Matthew Tan (CEO and founder); the office since January 2017 (etherscan.io/aboutus, read 5 October 2026; the page does not name the city, the founder's brief says Kuala Lumpur). Since 2020 it sells "Explorer as a Service", a white-label instance for other chains, 40 clients by 2025 (same page) | Closed source, a private company; a chain pays for an instance. Price not published; not asked | Not for us: closed, paid, and it would show nothing of the DAG, the finality or the proving layer |
|
||||
| Blockscout | Open-source EVM explorer: blocks, transactions, accounts, verified contracts, token pages, an API in Etherscan's shape. Elixir (Phoenix) backend, PostgreSQL, a separate frontend; "several hundred chains and rollups" use it (README, read 5 October 2026) | "Blockscout Software Licence" (the README badge; the licence text was not read line by line, so what it permits for a hosted instance is unverified) | The EVM side for free: contracts, transactions, logs, tokens, an API developers already know |
|
||||
| Otterscan | "open-source, fast, local, laptop-friendly Ethereum block explorer": a React app over an Erigon archive node, using Erigon's custom `ots_` JSON-RPC methods (github.com/otterscan/otterscan, read 5 October 2026) | MIT (the app); the `ots_` API lives inside Erigon under its licence | Not for us: it needs Erigon's RPC extensions, which the Igneum node does not have, and it has no contract verification |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Finality rule v3 on the devnet: the publish, 5 October 2026
|
||||
|
||||
the project lead, 17:5xZ: "deploy n3 now". Published by the 0.3.9 release engineer with the fee-switch mechanism
|
||||
The founder, 17:5xZ: "deploy n3 now". Published by the 0.3.9 release engineer with the fee-switch mechanism
|
||||
(`release-0.3.9.md` section 10), from the runbook `finality-v3-rollout-devnet.md` sections 3 and 4, right after every
|
||||
node carried the fee-switch digest ab8847da.... No new binary: the switch has been in every node since 0.3.4 (the
|
||||
a24ab01a Mac, Windows and Linux builds all carry `finality_v3_activation_daa`, checked with `strings`).
|
||||
|
|
@ -66,7 +66,7 @@ the object on its next check and is refused by every peer from its next restart
|
|||
|
||||
Open from this publish: the Mac app without a node of its own means the Mac no longer verifies proof records (node 1
|
||||
reports `verifier off`; PC 2's node verifies and includes its own); the app's port 26610 clashing with node 1's is the
|
||||
cause and is for the owner to decide (stop node 1, or move it). The Mac's miner at 0.0 MH/s is paused on the project lead's
|
||||
cause and is for the owner to decide (stop node 1, or move it). The Mac's miner at 0.0 MH/s is paused on the founder's
|
||||
instruction and left alone.
|
||||
|
||||
## The first v3 checkpoint (pending)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Finality rule v3 on the live devnet: rollout plan, 4 October 2026 (evening)
|
||||
|
||||
Prepared by the finality engineer after the project lead's "we need to fix these serious issues before making things public"
|
||||
Prepared by the finality engineer after the founder's "we need to fix these serious issues before making things public"
|
||||
(ledger F21 and F22). Nothing in this file has been run on the devnet, and the 12-node Hetzner network of the morning
|
||||
was destroyed at 15:30 UTC, so there was no cloud rehearsal; the measurements are the simulator (`sim/results_v2.md`,
|
||||
"Rule v3"), the node's unit tests and the fast-time 3-node network with emulated 300-ms links (`docs/bench-log.md`,
|
||||
|
|
@ -52,7 +52,7 @@ guards); it carries no v3 change and the devnet miners can stay on what they run
|
|||
|
||||
## 3. The activation height N3, and how every node learns it
|
||||
|
||||
Same rule as difficulty v2 (the project lead, 4 October 2026): `N3 = DAA score at the manifest publish + 10,800`, chosen as
|
||||
Same rule as difficulty v2 (the founder, 4 October 2026): `N3 = DAA score at the manifest publish + 10,800`, chosen as
|
||||
`DAA now + 14,400` when the line is edited and checked (`N3 - DAA >= 10,800`) at publish. The switch keys on the
|
||||
DAA score of the checkpoint block, which trails the sink by 20 to 50 blocks, so the first v3 checkpoint comes about
|
||||
a minute after the sink crosses N3.
|
||||
|
|
@ -82,7 +82,7 @@ sed -i '' "s/^NODE_OVERRIDE_PARAMS=.*/NODE_OVERRIDE_PARAMS='{\"difficulty_v2_act
|
|||
### Step 2: the Windows payload inputs
|
||||
|
||||
The inputs were staged on 4 October 2026 into a scratch downloads folder (section 7a) and NOT deployed. To publish
|
||||
them to the real downloads host, when the project lead says so:
|
||||
them to the real downloads host, when the founder says so:
|
||||
|
||||
```
|
||||
IGNEUM_WIN_RELEASE=vendor/igneum-node/target-finality-win/x86_64-pc-windows-gnu/release IGNEUM_NODE_SRC=vendor/igneum-node-finality packaging/windows/push-inputs.sh
|
||||
|
|
@ -159,4 +159,4 @@ bound with the heal, the 70/30 split, the fold before and after), the simulator'
|
|||
|
||||
`packaging/windows/push-inputs.sh --no-deploy` was run with `IGNEUM_WIN_RELEASE` at the v3 Windows release directory,
|
||||
`IGNEUM_NODE_SRC` at the finality worktree and `IGNEUM_DLSITE` at a scratch copy of the downloads folder, so the live
|
||||
downloads folder and host are untouched: `payload-inputs.zip` 64,294,811 bytes, sha256 `7c9d21e3df26fabf1761fa50fc627e628c46af80255d86429ef7d9d6ba5653a9`, manifest `node_source_commit` 6aa69a45, `igneumd.exe` cc1d1001b5b39bba2f4890e947f049292dc7cd7fda472e6c7f65f5a3d018f4db (50,484,224 bytes), `igneum-miner.exe` f1f9a7d96460e4d32e23aa3562c64058c5a2d4d87bb5058d287a697dc360fc1d (10,307,072 bytes), with the same CUDA and OpenCL workers, NVRTC and mingw DLLs as the morning's payload. The zip sits in the scratch folder only; the deploy command the script printed is `cd <dlsite> && npx vercel@latest --global-config ~/.config/igneum/vercel deploy --prod --yes`, to be run against the real folder after the step 2 command above, when the project lead says so.
|
||||
downloads folder and host are untouched: `payload-inputs.zip` 64,294,811 bytes, sha256 `7c9d21e3df26fabf1761fa50fc627e628c46af80255d86429ef7d9d6ba5653a9`, manifest `node_source_commit` 6aa69a45, `igneumd.exe` cc1d1001b5b39bba2f4890e947f049292dc7cd7fda472e6c7f65f5a3d018f4db (50,484,224 bytes), `igneum-miner.exe` f1f9a7d96460e4d32e23aa3562c64058c5a2d4d87bb5058d287a697dc360fc1d (10,307,072 bytes), with the same CUDA and OpenCL workers, NVRTC and mingw DLLs as the morning's payload. The zip sits in the scratch folder only; the deploy command the script printed is `cd <dlsite> && npx vercel@latest --global-config ~/.config/igneum/vercel deploy --prod --yes`, to be run against the real folder after the step 2 command above, when the founder says so.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue