Documentation / 5. The Stoic System

Chapter 5

The Stoic System

Philosophy, eligibility engine, ledger, shadow vs live, mint model.

Philosophy

Stoicism rewards operators who run their nodes in a way that benefits the network— not for uptime alone. Nodes earn when they run with the flags and configuration that strengthen StoaChain (accepting peers, valid p2p hostname, backup-api reachable, serving chainweb data). Configurations that only help the operator without helping the network don’t earn. That’s why it’s called Stoicism.

6.1 · Overview

  • What it is.The hub’s reward unit, keyed to an Ouronet account (Ѻ.…— the standard Ouronet prefix, U+047A “barred O”, not Kadena-style k:). Accrued points are minted into the real on-chain Stoicism asset by the scheduled on-chain Minter (§6.8) — to verified accounts only.
  • Who earns. Any node the hub manages whose owner has set an Ouronet account on their profile. Per-node overrides let an Ancient Admin direct a specific node’s earnings to a different account. The earnings page breaks earnings down per Ouronet account and shows each account’s verification status. To verify, click Verify on your account — you sign a one-time challenge in OuronetUI (your private key never leaves your Codex) and the hub checks it against the account’s on-chain public key. On-chain minting requires a verified account.
  • What currently matters. Scoring is LIVE — and the live state is LOCKED (since 2026-06-12): the economy is real, balances are real, and on-chain mints credit verified accounts. The pre-launch shadow ledger was hard-reset at go-live so everyone started the live era from zero; the lock makes the live state irreversible without an explicit Ancient-admin unlock (see §6.7 for the full launch state machine).

6.1a · The Stoicism token

On chain, Stoicism is an Ouronet DPTF — a TrueFungible token — but a deliberately unusual one: it is transfer-restricted. It is fungible and divisible like any token (so the protocol can mint, stake and reward it precisely), yet it is soulbound to the Ouronet account that earned it. You cannot send it, gift it, sell it, or trade it to anyone else. The only “movement” the restriction permits is staking your own Stoicism into the Stoicism Vault — the earning pool — where it keeps working for you (it earns wSTOA + OURO; see the roadmap). It never changes owner.

That makes Stoicism a record of proof of operator contribution, not a speculative asset. Every unit corresponds to real work a specific operator’s hardware did to keep StoaChain at the tip. You can’t buy your way into it, and nobody can cash out of the responsibility of actually running a node.

Why it can’t be sold — the parallel

Think of Stoicism the way you’d think of physical conditioning, a professional reputation, or academic tenure. Those are built only through sustained personal effort over time — and they are inherently non-transferable. No amount of money lets you buy another person’s years in the gym, their earned expertise, or their standing; the muscle and the skill belong to the one who did the work, and to no one else. Stoicism is engineered to behave the same way: it is the on-chain embodiment of your accumulated contribution to the network — earned by showing up and doing the work, tick after tick — and for exactly that reason it can never be handed to someone who simply has capital. Capital buys hardware; only running it earns Stoicism.

6.2 · Base rate

ServerScore ÷ 1,000,000points / second

Equivalently per day = ServerScore × 0.0864. A node at ServerScore = 1.0 earns ~0.0864 points/day; a top node at ServerScore = 10 earns ~0.864 points/day. Linear in ServerScore; no cap. Stoicism is deliberately very hard to accumulate — these are intentionally tiny amounts.

The hub landing shows the fleet-wide version of this next to the on-chain supply: the total Hub Score (the summed ServerScore of every container currently generating Stoicism) and the daily production it mints at — so you can see, against the settled supply, by how much it grows each day.

ServerScore is stamped by the benchmark job on first run + re-evaluated on commitment changes. It weights CPU, disk (read/write/latency), network (bandwidth + RTT), RAM, and a provisioning-commitment multiplier. See Mechanics / commitment curve below.

6.3 · The seven eligibility gates

Every 60 seconds the scoring worker checks each node against seven gates. Failing any gate pauses accrual silently; previously-banked points are never lost.

#GateWhy it exists
1Ouronet boundWithout an account to credit, there\’s no destination for the reward.
2Benchmark presentServerScore is the rate multiplier; without a benchmark the rate is undefined.
3Cut within tip toleranceAccrual only while the node is actually near the network\’s tip. Lagging nodes don\’t count.
4Warmup cleared24 h of cumulative eligible time before the main tap opens. Filters transient setups + drive-by operators.
5Provisioning okCommitted storage ≥ actual use + 5 GB headroom. Stops rewarding nodes about to run out of disk.
6Reachable on last tickSSH hub\’s last contact within the tolerance window. An unreachable node isn\’t contributing.
7Not in breachCommitment violations, provision breaches, or flag violations (see §6.4) freeze accrual until the operator fixes.

6.4 · Enforced flag list

The distinguishing mechanic: Stoicism enforces how the node is run, not just that it runs. The hub maintains a required-flag list; a node whose live argv (read via ps) is missing a required flag, or carries a disallowed one, fails gate #7 and stops accruing until the operator corrects the configuration.

Why flag enforcement matters

A node that rejects incoming peers, sets p2p-hostname to a non-resolvable value, or disables backup-api is still a running stoa node— but it’s not helping the rest of the network. Rewarding those configurations would make Stoicism a participation trophy. By making enforcement explicit + public, the philosophy (reward contribution, not presence) becomes durable and operator-facing.

The exact required-flag list lives in lib/stoachain-flags-catalog.ts (the full catalog) combined with the Ancient-Admin-configured policy in system_state.mandatory_flags. Two layers:

  1. Baseline — every catalog entry with role: ‘mandatory’ is always required (e.g. --chainweb-version, --database-directory, --p2p-port). These can’t be unticked; a node missing them can’t sync at all.
  2. Admin policy — every other catalog entry is ticked on/off by the Ancient Admin on /admin/stoicism/settings. Changes apply at the next scoring tick (~60 s); a node that fell out of compliance sees a pulsing red banner on its scoring card naming the missing flags.

The scoring worker logs a flag_violation event on every tick a node remains non-compliant, so the operator’s earnings timeline shows exactly when accrual paused and why. Restart chainweb-node with the missing flag present and the very next tick resumes earning — no re-benchmark, no grace period, just immediate correction.

Known limitation (z20).Some mandatory flags require operator-supplied values that the hub can’t infer (e.g. --hostname, --p2p-hostname). For these, Gate 7 checks presence only — any value satisfies. A follow-up patch will surface per-node value collection so the policy can enforce specific values too (and so the auto-restart path knows what to inject).

6.5 · The three-bucket ledger

Pending

Probationary. Earned during warmup; swept into Current on warmup complete; discarded on warmup reset.

Current

Ready to mint. Grows every scoring tick; the scheduled on-chain Minter sweeps floor(Current) into Redeemed for every VERIFIED account when it fires.

Redeemed

On-chain amount (integer) — REAL minted Stoicism, settled per on-chain transaction (keyed by request key) and visible in your Ouronet wallet. Verified accounts only.

Grand Total = Current + Redeemed. Pending is not counted until it completes warmup — a node that warmups-resets loses Pending but keeps what was already swept into Current.

6.6 · Commitment curve

Operators commit a storage amount on each node. The ServerScore provisioning multiplier scales with how much headroom they commit vs. the fleet-wide minimum (which moves as chainweb grows). Over-committing is cheap rewards; committing at exactly the minimum is correct + fair; under-committing fails gate #5.

Formula (simplified)

fleet_min_gb = ceil((fleet_data_gb + 5) / 10) × 10
provision_mult = clamp(
  ln(committed_gb / fleet_min_gb),
  lower = 0.0,   // no bonus below floor
  upper = +log_growth  // no cap but log scaling
)

Logarithmic scaling means doubling commitment doesn’t double the reward — rewarding responsibility, not rent-seeking over-commitment. Fleet-wide minimum moves with actual chainweb data growth; operators near the floor are nudged to top up before they breach.

6.7 · Shadow → Light: the launch state machine

The hub is LIVE, and the live state is LOCKED — the real launch happened on 2026-06-12. Every balance you see is the real economy; on-chain mints credit verified accounts. The journey here was a deliberate state machine, kept documented because it defines what today’s numbers mean:

  • Shadow (the validation era — over). Scoring ran end-to-end for months with visible balances but no on-chain representation: the calibration ground for rates, gates and benchmarks. Everything earned in shadow was test data.
  • Go-live was a hard reset, not a carry-over. At the flip (2026-06-12 10:00 UTC) the entire shadow ledger was nuked — every Pending / Current / Redeemed zeroed, all history cleared — so the live economy started from a clean slate. (Benchmark stamps + ServerScore were preserved; nobody re-benchmarked.)
  • Warmup restarted with a tiered grace. Nodes already working at-tip at the moment of go-live needed only 3 h before earning live Stoicism; new and dead nodes started the full 24 h from zero.
  • The live state is LOCKED. Once the launch was confirmed real, the Ancient Admin locked the live state — reverting to shadow is disabled (a revert-and-reflip would nuke the live ledger), and only an explicit Ancient-admin unlock can change that. The lock is also what stamps every Stoicism-Minter fire LIVE in the public mint-transparency view — fires recorded before it carry the TEST badge.

6.8 · Mint mechanics (real on-chain)

Minting is performed by the Stoicism Minter codex cronoton — a scheduled, server-signed A_StoicismMinter transaction (see Codex Cronotons):

  1. At fire time the hub resolves every verified account with floor(Current) ≥ 1 and builds the mint lists (stoicism-values / stoicism-targets).
  2. A safety simulate runs first; the tx is postponed if it cannot land. Otherwise the mint is submitted on-chain.
  3. On a confirmed success the hub settles: each account’s Current drops by its minted integer and Redeemed rises by the same. Settlement is keyed by the on-chain request key, so it applies exactly once per real transaction.
  4. The fire (with its TEST/LIVE provenance badge, chain result and explorer link) is publicly visible in the cronoton’s fire history.

The legacy hub-side “simulated” 06:00 UTC daily mint (runDailyIntegerMint — bookkeeping only, no on-chain tx) is retired: real on-chain minting has shipped and owns the Current → Redeemed move. See the scaling plan §500k for why a 500k-account sweep fits comfortably within StoaChain’s gas ceiling.

6.9 · Precision contract (Pythagoras, v0.7.11)

Stoicism is a financial-layer record. The hub stores, computes, and audits every Stoicism balance using arbitrary-precision decimal arithmetic (decimal.js, TEXT-stored). f64 floats — the JavaScript default and the SQLite REAL type — are explicitly banned for any Stoicism balance because they silently lose precision when small accruals accumulate into large balances.

Marketing-grade claim: every Stoicism point earned is preserved exactly. Forever. Replay the events log on any other instance running the same code and migrations and you arrive at byte-identical balances. Read the v0.7.11 audit →

The numerical contract

  • server_score: 6 decimals (stays f64 — it’s a benchmark output, not a balance).
  • tunneler_fee_promile: 1 decimal (= 2-decimal percent). Capped at the input layer (UI step="0.1") and rejected by the server-side validator if finer.
  • Stoicism balances (pending, current, redeemed, lifetime): 15 decimals exact. decimal.js arithmetic; SQLite TEXT storage as canonical 15-decimal strings.
  • BASE_POINTS_PER_SEC: exact const = 0.000001 (ServerScore / 1,000,000 per second).
  • Tick duration: exact const = 60s.

Balance precision is sized to the smallest earning the system can produce, so nothing ever rounds to zero. That floor is the tunneler-fee path at every input’s minimum:

0.000001 × 60 × 1e-6 (min score) × 1e-4 (0.1 promile / 1000) = 6e-15

6e-15 has its digit at the 15th decimal place, so balances carry 15 decimals — enough to represent that smallest fee exactly (at the old 12 decimals it underflowed to zero).

6.10 · Tunneler fee architecture

A Tunneler is a server with a public IPv4 + port-triplet allocator that hosts Tunnelees — CGNAT’d home boxes whose chainweb traffic relays through frps tunnels. One Tunneler can host many Tunnelees; each Tunnelee gets its own port triplet (ssh, p2p, service) from the Tunneler’s pool.

The Tunneler operator sets a fee in promile (1/1000) — their infrastructure-rent rate. Every tip-tick a Tunnelee earns, the fee fraction goes to the Tunneler:

tunnelee_share = N × (1 - promile / 1000) tunneler_share = N × (promile / 1000)

Routing rule:the Tunneler’s fee credit respects the Tunneler’s own warmup state, not the Tunnelee’s. A warmed-up Tunneler’s fee lands inaccount.current; a non-warmed Tunneler’s lands in account.pending.

Worked example:Spartacuz (Tunnelee, server_score 3.0) accrues 0.00018 points/tick (0.000001 × 60 × 3). StoaTunnelZero (Tunneler, fee 10 promile = 1%) gets 0.0000018 of that, every tick. The precision contract lands this in StoaTunnelZero’s account.pending exactly — no f64 truncation.

6.11 · Multi-container servers (segregated mode)

A standalone server can host either ONE full-machine chainweb container OR multiple segregated chainweb containers (port-isolated, independent of each other). Mutual exclusion is enforced both directions: the install wizard refuses full-machine if segregated children exist; the self-container creator refuses segregation when full-machine is installed.

Minimum requirements per segregated container (operator-locked):

  • 3 vCPU dedicated
  • 6 GB RAM
  • SSD-backed storage (HDD rejected at the install wizard — chainweb random-read IOPS exceeds rotational disk capability by 2-3 orders of magnitude)
  • Allocated commit space (per the existing committed_gb rule)

Each segregated container gets its own ServerScore (its own benchmark + commitment) and accrues Stoicism independently. Multiple containers on one box mean multiple scoring rows in the operator’s ledger; the same f64-banned exact-decimal rules apply to each.

6.11a · Warmup mechanics & identity rules

Warmup gates a chainweb’s "earnings count toward the realized bucket" status. The bar: 24 hours of cumulative eligible time at tip. Gate 4 of the seven eligibility checks (§6.3). Until cleared, accruals route to the Pending bucket; on completion they sweep into Current and stay there.

Counters tracked per chainweb container

  • scoring_warmup_since— first observation at tip. Set once per chainweb identity. Acts as the "earning since X" anchor.
  • warmup_cumulative_seconds — total time at tip. Advances by 60s every successful scoring tick where the chainweb is at tip. Never decremented.
  • warmup_last_tick_at — most recent successful tick. Used by the offline-detection display gate (§6.3, gate 6).
  • scoring_warmup_completed_at — stamped once when cumulative crosses the 24 h threshold. Permanent.

What does NOT reset warmup

  • Brief drops(chainweb temporarily off-tip, single-tick miss). Cumulative pauses but doesn’t lose ground.
  • Benchmarks (auto-stop + restart, ~3-5 min). The chainweb is hub-paused; warmup state is preserved.
  • Prime ↔ Slave conversions(~30 s rebind downtime). The chainweb’s identity moves with the chainweb across the conversion; warmup, lifetime, mining and Ouronet account all carry over to the new row.
  • Operator-driven container restarts (Stop + Start from the Control tab). Same data dir, same chainweb identity, same warmup state.

What DOES start a fresh warmup

  • Adding a new slave to a segregated host (Add SLAVE 002, etc.). The new chainweb is a genuinely new identity with a fresh data dir, separate sync from peers, and its own benchmark. Starts at warmup zero. Existing slaves are unaffected.
  • A wholesale reinstall— operator deletes the chainweb data dir + reseeds. The chainweb’s peer- identity and on-chain history reset; treated as a new commitment.
  • Long unplanned downtime(planned for v0.7.13a) — when chainweb is unreachable for > 1 hour outside any hub-induced operation, warmup_cumulative_seconds resets to zero. Hub actions (rebind, bench, conversion) stamp a planned- downtime window so they don’t count against the operator.

Identity rule (the core invariant)

Warmup is a property of the chainweb identity, not the database row or the docker container. As long as the chainweb’s data dir, P2P key, mining pubkey, and Ouronet account remain the same, the warmup counter persists across any operational change to the wrapping container.

Concretely: a Prime → Slave → Prime → Slave round trip is identity-preserving. Each conversion moves the four warmup fields (plus lifetime + pending Stoicism, plus mining / Ouronet) from the source row to the destination row. The wrapper changes; the chainweb is the same.

6.12 · Operator FAQ

My node is online but not earning. Why?
Open the node\’s Scoring card in /admin/nodes/[id]. Each of the 7 gates is listed with its current state; the failing one tells you exactly what to fix.
I re-benchmarked. Will my warmup reset?
No. Benchmarks change the rate, not the warmup clock. The only things that reset warmup are: staying off-tip for > tolerance, or an explicit warmup-reset from an Ancient Admin (emergency tool).
If I unmanage a node, do I lose my Stoicism?
No. Stoicism is keyed to your Ouronet account, not the node. Adding and removing nodes doesn\’t affect any Stoicism already earned. The node\’s own lifetime_points counter stops at the value it had when unmanaged.
When does the mint go on chain?
It already does — the system is LIVE (locked 2026-06-12). The scheduled Stoicism Minter fires a real on-chain transaction that mints floor(Current) to every VERIFIED Ouronet account; on confirmation the hub settles Current → Redeemed keyed by the transaction's request key. Every fire is publicly auditable in the Codex Cronotons mint-transparency view, with a LIVE badge and an explorer link. Unverified accounts keep accruing but are skipped at mint time — verify on My Profile to be included.
Why does committing more storage help?
Nodes with comfortable commitment headroom are less likely to hit the provisioning gate during chainweb growth, which means steadier accrual. The multiplier is logarithmic — diminishing returns past ~2× the fleet minimum — to avoid rent-seeking.