Every assumption, named.
Validity is cryptographic. Ordering, liveness and censorship resistance rest on committee stake. Facts about the world rest on priced assumptions. An agent’s spending rests on the ledger, and the rest of its limits on the machine it runs on. This page lists what each guarantee rests on, what the reference implementation adds or leaves out, and how to report a flaw.
A devnet secures nothing of value. Its validator keys are derived from the chain name, so anyone can derive them.
What each guarantee rests on
The architecture paper’s security model, with what the reference implementation does today. Equivocation leaves signed evidence and is slashed; censorship is made visible and answered by replacing the committee.
| Guarantee | Rests on, in the design | If that fails | In the reference implementation |
|---|---|---|---|
| Validity of every transition | Sound proofs, correct circuits and a correct specification, checked by two independent proof stacks | Both stacks must fail together, or the specification must be wrong | Replay proofs from two stacks that share hashing, Merkle, signature, Assurance Algebra and clearing-certificate code |
| No double spend | Less than a third of each committee’s stake is Byzantine; partial synchrony | Conflicting certificates appear, and signed evidence slashes the equivocators | Built; a slashed validator keeps its seat until the epoch ends |
| Liveness and inclusion | Less than a third Byzantine stake and partial synchrony; one honest proposer per round, plus forced inclusion | Progress stalls visibly; a censoring shard is frozen and its committee rotated | Simplified: overdue intents appear in certified headers and the committee is rotated; the shard is not frozen |
| Data availability | Enough honest samplers whose requests cannot be linked, and a proven-correct encoding | Withholding is detected and the Pulse is rejected | Built: sampling with fresh randomness; the World Proof checks that the published data encodes to the certified root |
| Authorization | Lattice ∨ hash: two unrelated signature families | Both families must break | Built on pure-Rust FIPS 204 and 205 crates that have not been audited |
| Facts about the world | Each claim’s trust formula and the bonds behind it | Losses up to the cost of corruption, compensated from slashed bonds | Built: cost of corruption, reservations, challenges, slashing with compensation |
A light client pins one value, the chain identity: a digest of the genesis specification, the genesis validators with their stake and keys, and the shard layout. Every later committee is in the state, and the client follows it one epoch boundary at a time, so it trusts nothing a node serves. Without a pin, sion verify says that the node is vouching for itself.
Post-quantum signatures
Every account and validator signs with two unrelated families at once: ML-DSA-44 (FIPS 204, module lattices) and SLH-DSA (FIPS 205, hash-based). SLH-DSA-SHA2-128f is the default; the smaller and slower SLH-DSA-SHA2-128s suits accounts that sign rarely. Payloads are encrypted to viewing keys with ML-KEM-768 (FIPS 203) and ChaCha20-Poly1305.
An account is identified by the hash of its genesis authorization policy, so its keys can rotate without changing the account. The cost is bandwidth: kilobytes per signature, which is why validators sign one Merkle root per batch of approvals rather than each approval.
Two signature families
Every account and validator signs with two unrelated families at once: ML-DSA-44 (FIPS 204, module lattices) and SLH-DSA (FIPS 205, hash-based). A verifier requires both. An attacker who breaks lattices forges only the first signature and is refused; one who breaks hash functions forges only the second and is refused. Forgery needs both families broken, so the trust formula of an authorization is lattice ∨ hash. The bars show the cost in bytes: 2,420 for ML-DSA-44 and 17,088 for SLH-DSA-SHA2-128f, the repository's default second signature, against 64 for Ed25519, which is not post-quantum and is not used for authorization.
Stake and slashing
Proofs stop invalid state, not equivocation. A validator that signs two consensus headers for one round, or approves two spends of one object version, leaves signed evidence. Anyone can submit it: the whole stake is forfeited, the reporter receives a share of it (5 % on the devnet), and the validator loses its seat at the next epoch boundary. Committees are derived from the validator set in the state, so every change of who certifies is covered by the World Proof. The technology page shows the full cycle from the staking demo.
On the devnet, validators stake devnet USD, which has no value. Siontology has no token and nothing is on offer. Fees are paid in stablecoins.
Agents on your machine
An agent’s limits live in two places. Its charter, what it may spend, to whom and until when, is enforced by the ledger, whatever the agent was told. Its autonomy level, the approvals people give, and the taint of content from outside are enforced by the runtime on the machine it runs on, so they hold only as far as that machine does (agent:local-policy). The model is not trusted to behave: a test gives nine attacks to a scripted model that does whatever it reads, and records what stopped each.
| What | Rests on | Atoms |
|---|---|---|
| What it spends | Its charter on the ledger, checked by the validators at every payment from its budget; one revocation stops it and every subagent. A storage deal it posts is paid from the account it pays fees from, which the charter does not bound, and what a tool does elsewhere is up to that tool’s server | As for the chain; agent:storage-from-account, agent:mcp-effects |
| What it does without asking | The runtime on its machine: the autonomy level, approvals and the taint of content from outside | agent:local-policy |
| Commands it runs | Bubblewrap’s namespaces or a container runtime; with a network allowed, whatever that network reaches | agent:sandbox, agent:sandbox-network |
| Keys and credentials | Encryption under a key in a file only your user can read; a variable set in the environment is used instead | agent:kept-credentials, agent:secret-store |
| Its conversations | The model provider you chose, which sees them; on your machine they are stored unencrypted | agent:provider-sees-context, agent:plain-sessions |
| Who it answers | Each messenger’s word for who wrote, the signatures on its webhooks, and the pairing codes you approve | agent:messenger-identity, agent:webhooks, agent:pairing |
| The tools of MCP servers | Your review of each tool, pinned by a digest; a server you add without a sandbox runs as your user | agent:mcp-effects, agent:mcp-unsandboxed |
| Updates | A release whose checksums are signed by the release key the program names; the installer’s first download trusts HTTPS and GitHub | release:signing-key |
Two of the nine attacks got through: a file in the workspace that tells the agent to post it, since what it reads from its own workspace does not taint a session (agent:workspace-content), and a page that has it send a key through a tool you contained, which reaches only where you named. The attacks, row by row. Every agent atom, more than sixty, is in the trust model.
What is simulated
The reference implementation adds assumptions of its own. Each one is an atom in the trust formula of anything the devnet reports, and each is labelled in the types and in the output.
| Atom | What it means |
|---|---|
impl:replay-proofs | World Proofs are checked by re-execution, so proof finality costs a verifier as much as executing. Succinctness is assumed, not delivered. |
impl:shared-primitives | Both proof stacks use the same hashing, Merkle, signature, Assurance Algebra and clearing-certificate code; a bug there is common to both. |
impl:devnet-keys | Devnet validator keys are derived from the chain name, so anyone can derive them. |
impl:in-process-network | sion devnet only: validators share a machine and a process, and network faults are exercised only through an in-process fault injector and the consensus simulator. A network of sion node processes does not carry this atom. |
impl:reliable-handover | At an epoch boundary each validator starts a new consensus session, relying on the in-process network to deliver every message already sent. A real network needs a drain period: on a network of processes, a validator that misses messages at a boundary can stall. |
net:transport-ml-dsa | Networks of processes: transport authentication rests on ML-DSA-44 alone, each node’s network key pinned at both ends. A forger could delay, drop or isolate a peer’s messages, not sign consensus messages, which carry dual signatures. |
net:aws-lc | Networks of processes: the TLS provider is aws-lc-rs, C code outside the workspace’s audit scope. |
net:raw-public-keys | Networks of processes: TLS authenticates nodes with RFC 7250 raw public keys, pinned at both ends, not with certificates. |
net:static-peers | Networks of processes: peers come from a genesis file and a peer file read when a node starts, not from the state. A validator that joins by staking is reachable only by nodes started with its record. |
net:partial-synchrony | Networks of processes: liveness needs message delays to become bounded after some time. |
net:gateway-trusts-node | Networks of processes: a gateway running alone learns committees and answers state queries from one node it trusts. A lying node can mislead it, not get a transaction certified that a committee did not approve. |
net:no-rejoin | Networks of processes: a validator that stops cannot rejoin, so each stopped validator is a permanent fault, and more than a third of the stake stopped halts the chain. |
impl:slashed-seat | A slashed validator keeps its seat, and its weight in quorums, until the epoch ends. |
impl:active-floor | Validators can leave until one remains: nothing keeps the active set large enough to tolerate a faulty member. |
impl:evidence-scope | Equivocation evidence is not bound to one chain, so a validator’s keys must not be used on another network. |
impl:lock-handover | Lane certificates are not drained when a shard’s committee changes, so certificate finality for owned transactions holds within one committee’s term. An owner who signs two spends could get the second certified by a committee that has been fully replaced. |
impl:hash-chain-beacon | The beacon is a hash-chain commit and reveal; the last validator to reveal can bias it by withholding, at the cost of being seen. |
impl:public-amounts | Amounts and balances are visible to everyone. |
impl:memory-index | The ledger stores a memory log’s index root without checking it; nothing on the ledger yet acts on proof that an index left a memory out. |
impl:unaudited-pq-crates | The FIPS 203, 204 and 205 implementations are unaudited pure-Rust crates. |
storage:no-replication | A storage proof shows that the provider could produce the challenged pieces during the round, not that it keeps a copy of its own. |
storage:raw-proofs | Every storage proof carries its challenged pieces and their Merkle paths on the ledger, about 17 to 22 KiB a deal a round. Proofs are not aggregated, so ledger bandwidth bounds how many deals a network can keep. |
storage:no-retrieval | Getting data back is not part of the protocol: a provider proves custody, and returning the data is up to the provider and its client. |
app:first-use-pin | The app pins the chain identity of the first node it verifies unless its user pins one first. A first use against a lying node pins the liar’s chain. |
app:plain-key | The app keeps the device’s key unencrypted in its directory, not in the platform’s keystore. Anything that can read the directory can spend. |
app:unproven-balances | The balances the app shows come from the node unproven; its own receipts and the Pulses it verifies are proven. |
impl:insecure-sim-signatures | Only when a devnet is started with --insecure-fast-signatures: validators sign with a simulation MAC. The chain identity records it, and light-client reports say so. |
What is not claimed
It does not make a model safe.
A model that reads an attacker’s words may do what they say. What holds it back is the runtime, which is only as safe as the machine it runs on, and the ledger, which holds its spending to its charter.
It does not make the world honest.
A claim about a physical event is only as strong as the bonds and evidence behind it. The design prices that risk instead of hiding it.
It does not remove stake from safety.
A Byzantine third of a committee can still double-certify, and is slashed for it. Two conflicting World Proofs could then exist, and only stake decides which is canonical.
It is not proven at scale.
The capacity and latency figures are design targets, not measurements. There is no testnet and no mainnet.
It is not private yet.
Payloads can be encrypted and orders sealed, but amounts and balances are public. Confidential transfers and compliance by proof need a zero-knowledge stack that is not built.
Some defences are not built.
Personhood, a proving market, payments to provers and a cap on value in flight are missing. Networking between machines is simplified: processes have talked over QUIC on one machine, and a validator that stops cannot rejoin.
Reviews
Independent reviews, run by AI agents that had not written the code, read the consensus-critical libraries, the node, the validator machinery, the networking plan, and storage deals with the app, and confirmed their findings with tests. Everything they found is fixed with a regression test, except where marked open. Among the fixes:
- an unbounded chain of claim references could overflow a validator’s stack; claim references and formulas now have bounded depth;
- a signature cache keyed on the transaction body but not its signatures, so a copy with stripped signatures could split replicas;
- lane validation skipped the checks execution makes before charging a fee, so zero-fee transactions were published for free;
- certificate finality did not survive a restart; approvals are now logged before they leave a validator, and locks are restored;
- transactions and validator messages were not bound to a chain; transaction signatures now cover the chain configuration;
- light-client sampling used a fixed seed, and a missing World Proof did not fail verification;
- an owner could get honest validators slashed: the node released a rejected transaction’s lane locks at once, so its next approval of the same inputs counted as equivocation; a rejected transaction now keeps its locks until it expires;
- if every active validator was slashed within an epoch, they kept their seats into the next one; since specification v1.5 they lose them regardless, and such a chain halts;
- a storage provider working with a validator could steer which pieces of data it was asked for, by timing its proofs; since specification v1.12 a round’s challenge comes from the beacon of the round’s first Pulse, which the ledger records;
- a provider fetched from any address a deal named, including its own machine and network; it now refuses local files and private addresses unless told otherwise;
- the app presented the node’s account of what a transaction did as fact; it now shows what the receipt it proved says, and labels anything else as the node’s unproven report.
Open: fee-paying transactions with large bodies can still make Pulses slow, since data-availability encoding of the largest allowed Pulse takes seconds on one core; an account query scans every object; the active set can shrink to a single validator (impl:active-floor); Pulse headers do not yet commit to the beacon reveals a validator syncing from certified headers will need.
Differential testing of the two proof stacks found two defects in the reference executor, including a market deadline overflow that let any account halt the chain; both were fixed in specification v1.1. The full list is in docs/implementation-status.md.
Reporting a vulnerability
If you find a way to break a guarantee that Siontology claims, tell us privately before anyone else. Please do not open a public issue for it.
Say which commit you tested, what an attacker gains, and how to reproduce it, ideally as a failing test. A devnet on your own machine is the place to try an attack: the command line includes adversary simulations for exactly that. Do not test against machines you do not own.
The simplifications listed on this page are known, and are not vulnerabilities in themselves. A way around a guarantee the implementation does claim is.
- Include
- The commit, the impact, and steps or a test that reproduce it
- In scope
- The reference implementation, the specification and this website
- Known
- The simulated parts and simplifications listed above