Receipt of the implementation of chain-economy
(and the amended chain.md, chain-wire.md, chain-conformance.md §14) in
crate/src/chain/. Branch soft3 feat/focus-economy on origin/main
518c2ae. Requirements stay in the specs; this file records what was
built, what was run, and what was observed.
Stand: ~/cyber/soft3/.worktrees/focus-economy/ — soft3 on the branch;
hemera release/0.4 7237a23; bbg master be5c5db (bbg#51, dimension
version 4); tru master 1ea853e (tru#40, the epoch engine); lens
feat/hemera-0.4 529adcb; zheng and nox release/0.4; cybergraph
feat/durable-applications; foculus b28f0a2; mudra, tok master; strata,
honeycrisp, tade, radio, neuron, inf, file, joy, trident default checkouts.
bbg, tru, zheng, nox, cybergraph, foculus, mudra and tok still require
cyber-hemera = "0.3" on their default branches and carry a one-line
stand-local bump to "0.4" (the hemera 0.4 receipt's open item). Machine:
M4 Max, 48 GB, shared with other agents' builds.
what landed
| spec | where | what |
|---|---|---|
| §0 | params.rs |
every economy constant; EpochClock { L, D, MIN_LOCK } — SPEC on the launch chains, a shortened clock only on dev/test nets (SOFT3_DEV_EPOCH=L:D:MIN_LOCK, ignored for pussy and bostrom) |
| §3.1 | wallet/tx.rs, economy/mod.rs |
card_id, stake_key, focus_key, payout leaf/node/root, φ digest |
| §3.2 | bbg_state.rs |
positions as bbg CardRecord { owner, particle, author, valence, since } (dimension version 4); stakes and the pool as raw balance keys; zero rows absent |
| §3.3 | apply.rs |
kind 2 with amount > 0: native only (TxError::StakeToken), valence fixed while staked (TxError::Valence), amount + fee spendable, stake to stake_key, card created or since restarted; TxError::Box retired |
| §3.4–§3.5 | wallet/tx.rs, chain/tx.rs, net/codec.rs, apply.rs |
kind 6 unlock (120 B body, 224 B), kind 7 payout (144 B body, 248 B); NSIG1 over the chain.md §2.1 statement, subject from; unlock after since + MIN_LOCK, partial or full (card deleted at 0), fee payable from what it returns; kinds 8–10 rejected |
| §2, §5 | economy/settle.rs, economy/run.rs, engine.rs |
at every boundary block the state is frozen (Snapshot, keyed by block id) and the epoch's settlement starts on a worker thread; the block at boundary + D joins it (waits if unfinished, never guesses); results keyed by the two boundary ids, cached under $home/epochs/ (keyed by engine id and quadrature too) |
| §4.1 | economy/weights.rs |
genesis weights from the genesis file at load, stored nowhere |
| §4.2–§4.4, §5.1 | economy/focus.rs |
FocusEngine seam; the node runs tru's epoch engine (Tru, threads = cores − 1, ≤ 8); A_mid; the gradient integrated over k Gauss–Legendre nodes, k = 1 (the midpoint of §5.1) by default, k a parameter |
| §5.2–§5.6 | economy/settle.rs |
Δs per card and side (a side switch is a decrease and an increase), active only, new-high rule with marks per axon side, ρ = 1, budget pool/4, 1 % cap, floor rounding, dust stays; payouts to the payout owner of G_E; marks rewritten; time[settle(E)] = hemera(D_EPOCH ‖ record) (198 B) |
| §6 | apply.rs |
coinbase SUBSIDY − cut + fees, the pool takes cut; focus_bps(E) = min(5,000, isqrt(active · 10^8 / supply)) fixed at the end of each boundary block; conservation counts stakes and the pool; Σ stake keys = running total checked at every settlement block |
| §11 | economy_api.rs, node/chain_routes.rs, node/chain_node.rs |
GET /epoch/{E}, /epochs, /focus, /focus/{particle}, /card/{id}, /cards/{neuron}, /economy; /status gains epoch, next-boundary, last-settled, focus-bps, pool, active-stake, total-stake, stake-keys-match, settlement-ok, focus-engine |
| CLI | bin/soft3.rs |
soft3 chain tx --kind link --valence V --amount A, --kind unlock, --kind payout --payout OWNER |
| §10 | economy/vectors.rs, conformance.rs |
chain-conformance §14 scenarios driven through apply::transition (no PoW), blessed |
High-water marks and the economy scalars (focus_bps, stake totals,
last_settled) are kernel state: pure functions of history, journaled with
the block's undo, not committed; their effects reach state_root through the
balances (payouts, coinbase) and time (the record).
tests
cargo test --release --no-default-features --features chain-conformance
(in crate/, __CARGO_TEST_ROOT at the wrapper): 276 lib passed, 1
ignored (the cost measurement), 17 bin, 2 adversary, 1 mine e2e — 0
failed (lib was 263 on 518c2ae). 25 of the lib tests are the economy's.
Economy tests (chain::economy::*, chain::tests::economy::*):
- §14 identities and integers exactly as the spec quotes them (card, stake
key, focus key, payout leaf and node, φ digest of
[2^59, 2^59];focus_bps,cut, mark decay 998,077 / 500,047, budget division 333×3 and 10,000/250,000,epoch/settle); - the reference engine's adjoint against a finite difference; tru's digest equals hemera over tru's preimage; 1 and 8 threads bit-identical; quadrature k = 1 and 2;
- new-high rule exact (
xat mark = height is 0, one epoch of decay givesx/100, the other side's mark does not limit), linearity in stake (one author 100 vs 60 + 40), passive earns nothing, −1 on an absent axon does nothing, hedging pays only the side witha > 0; - engine end to end over five epochs: +1 on the dominant edge, a passive
lock, −1 against a spreading edge, a ring, 20 zero-stake spam links, a
payout owner change (paid to the owner of the snapshot), partial and full
unlock, an unlock-and-relock on the same side (
xof the relock < 1/20 of the first), the ring paid ≤ 1 % of its added stake; - determinism: a second node fed the blocks has every epoch record equal; a restart replays through the settlement cache to the same root and records;
- reorgs: three blocks above the boundary reproduce the record; a fork below the boundary replaces it and changes the record; roots equal;
- off the block path: with a slow engine, four blocks validated while the
worker ran;
settle(1)joined it; - 2,000 random blocks of locks, unlocks and payout changes: conservation and Σ stake keys at every height, settlements every 10 blocks;
- the node surface:
/epoch,/epochs,/focus,/card,/cards,/economy.
settlement cost (§7.2)
Measured with the ignored test settlement_cost_on_genesis_files on the
real genesis files (~/.cache/cyber/genesis/*.tade, dimension version 4)
through tru 1ea853e, epoch 1 = genesis weights plus 2,000 positions (half
+1, half −1, stake ½ of the axon's genesis weight) on genesis axons:
| graph | axons | particles | φ*_0 (1 thread) | settlement: φ*_E + gradient at A_mid + attribution, 1 thread | same, 8 threads | peak RSS |
|---|---|---|---|---|---|---|
| pussy | 26,805 | 16,270 | 0.036 s | 0.12 s | 0.14 s | — |
| bostrom | 2,990,817 | 3,237,461 | 9.3 s | 27.0 s | 9.6 s | 5.0 GB (incl. the 331 MB file decode) |
Digests equal across thread counts (bostrom φ*_0 0b889535…, pussy
95606683…). Against SETTLE_BUDGET = 900 s the bostrom settlement is
33× under on one core and 94× under on eight; a node starting at the
boundary has finished long before settle(E) an hour later. Genesis
weights: bostrom Σ G 344,014,106,319,158, 282,860 frames at the floor,
digest d5f6f23c…; pussy Σ G 41,802,483,829,015,338, 30 at the floor,
digest 218a8775….
genesis under dimension version 4
soft3 genesis build rebuilt both files into /tmp: byte-identical to the
cached files (pussy sha256 ec7aee79…, bostrom ffa3d6dd…; the chain ids
do not move). Only the roots move:
| state root | block-0 id | |
|---|---|---|
| pussy | d48fee478584d248123c63e2ee6c56224f159c7dadbc625f4261f6af49130371 (v3 a3607987…) |
73208ee2d43fbb0420119ceff23eab79e9d96921050e2a2137d0705c461852d4 |
| bostrom | fa0c2c9404a6eff04737ed7dfe11c63c1992b4820fdf039a55c6d2f103d7508d (v3 c50a6d84…) |
a13f0f627dae47a00fe50f7f9c538148345f52ab6200518e2360798c504fc3d5 |
Bostrom root: 73 s wall, 91 s user, 7.9 GB max RSS. The reports
(*.tade.json) in ~/.cache/cyber/genesis/ were replaced; the files were
not touched. conformance/chain-genesis.toml carries the new values;
cyber/launch row 14 owes the same update.
conformance
soft3 conformance bless chain --genesis ~/.cache/cyber/genesis/pussy.tade:
54 entries, 28 moved (every state root and block-0 id: dimension version
4), 26 new under chain::economy@v1 and the pussy genesis entries (genesis
weights, φ*_0 at 1 and 8 threads). soft3 conformance check chain green.
the fleet
nu scripts/chain-fleet.nu --bin crate/target/release/soft3 --threads 1 --secs 40 --epoch 6:3:9 --http-base 17980 --radio-base 17990 --keep (the
--epoch flag is new: it exports SOFT3_DEV_EPOCH for the dev net and adds
an economy step). GREEN, every scenario of the hemera receipt plus:
- the depth-3 fork from 14 (main 17, fork 19) replaced the boundary block at 18 — a reorg across a boundary on four live nodes; every node moved to the fork and settled from its snapshot;
- a staked link (
soft3 chain tx --kind link --valence 1 --amount 10^9) mined at 21; the records of epochs 4 and 5 equal on all four nodes (0d7c586e…,199931f0…; budgets 225 and 675, pool 900 → 2,700; paid 0 — the dev graph is that one axon, whose weight does not move a two-particle φ*);/cardsshows the position, unlock at 30; - node 3 killed at 33, replayed from disk (through
$home/epochs/), synced to 45, conserved.
Log /tmp/fe-genesis/fleet-1.log, artifacts /tmp/chain-fleet.9K8DTD.
findings for the owner and the spec
- The new-high rule does not bound a quiet-epoch recycler. Attribution
scales
x(c)byN/R, butpay = min(cap, ⌊B · x / X⌋)normalises byX: a relock that is the only earner of its epoch takesmin(cap, B)however small itsx. The blessed new-high scenario shows it: the first lock was paid 649,257, the relock under a mark two decays below the old height (99.6 % of it) 1,785,458. The bound left is the 1 % cap per settlement and the 7-day lock per cycle, not "the mark's decay" of §9. A fix that keeps everything else: cap on the new height,cap(c) = ⌊Δs · (N/R) · R_MAX_PPM / 10^6⌋(or scale the budget byΣ x / Σ a⁺). Not implemented — a spec decision. - Under J = D_KL(φ ‖ u), most new links lower syntropy. Stake on a minor edge spreads focus (∂J/∂A < 0) and earns nothing as +1; it earns as −1. On the test graphs the earners are +1 on dominant edges and −1 against minor ones. This is the spec's objective working as written; the owner should see it before launch (rewards.md §1 "pay for descent").
- The record's
syntropy: i64overflows on bostrom. J(φ*_0) is 9,886,742,015,786,730,065 at 2^60 (8.58 nats) > i64::MAX; the kernel saturates. tru's agent reports an amendment to i128 is coming; the record grows to 230 bytes then. - Hedging pays. +1 and −1 of equal size on one axon leave A unchanged and the +1 side is paid as if it had added weight (§9 says "capital doubled for the same credit" — that is the behaviour; the credit is for no change of the graph).