Kvasir architecture
One map of the whole system: wallets, the gateway that takes payment, the bridge that fronts the engine, and the p4 network that runs the model.
Kvasir is four layers with one seam each. Wallets hold the keys. The gateway takes the payment and keeps the ledger. The bridge puts an HTTP face on the inference engine. The p4 network actually runs the model. Everything below is a consequence of where those seams fall — and the diagram marks what runs today against what is still a design.
Keys never leave the device
iOS (Swift), Android (Kotlin) and desktop (React + Electron) are separate builds of the same wallet, and the desktop build is also what the gateway serves at / as a browser wallet — a full wallet with in-page signing, not a read-only console. Rewards are paid to each owner's own Solana address; the gateway never holds a user key.
One process, two surfaces
solana/staking-service is both the API gateway (an OpenAI-compatible /v1/chat/completions, plus the pay-per-request flow at /api/pay/quote → /api/inference) and the settlement gateway (staking, the node registry, credit accounts, contribution credit). They are one process because they share one ledger: a request is only served after its KVR transfer is verified on-chain, and the same ledger credits the nodes that served it.
The payment settles before the inference runs. If the bridge then fails, the gateway refunds the payer from the treasury and returns a 502 rather than charging for nothing. There is no mock model and no placeholder catalogue behind it: a model the app offers is one a bridge is serving, or the list is empty.
The HTTP face of the engine
The bridge (p4bridge) is an OUTER in p4 terms: it installs a session across the stages, submits to the head, and gathers the token stream. To the gateway it is a small, fixed contract — which models are loaded, who contributed how much, and completions.
| Route | What it answers |
|---|---|
/api/controllers | which models are loaded, and every stage's state |
/api/runtime | the operator wallet and the machines behind it |
/api/contributions | per-node rows, units, requests, throughput |
/c/<model>/v1/chat/completions | inference |
Two jobs p4 deliberately leaves to the bridge: the chat template (p4 hands the stage server an opaque prompt and applies none, so an instruct model would continue your text instead of answering it) and the reasoning block (returned as reasoning_content, separate from content, so a thinking pass cannot silently eat the token budget and bill the payer for a blank reply).
The bridge is never published. Its only authentication is a shared service token, and anything that reaches it can run the ring. It binds loopback; the tunnel is the door.
Agents own nodes, stage servers hold layers
An agent owns a host's nodes; a stage server is one process holding a slice of the model's layers. A stage hands its result to the next by asking its own agent to dial that stage's agent at the address that agent advertises — so the advertised address has to be reachable from the other hosts, and should be the fastest network they share. On the MI250 rack that is the InfiniBand link, not the office LAN and never loopback.
- `p4-agent` and `p4_staged_server` are one release. An agent built from a newer tree fails at READY with a missing HELLO capability — after loading the whole model.
- Placement is an operator artifact. Which layers sit on which GPU, at which load generation, comes from a placement plan; the bridge answers
409to anyone asking it to serve, and the gateway's watchdog says so once and stops asking. - A pipeline needs at least two stages. The session command refuses a one-stage pipeline.
A dialable address for a laptop
Edge nodes — a desktop app, a phone — have no address anyone can dial. The relay gives them one: the node connects out, proves the wallet keypair over an ed25519 challenge, and is then reachable through the relay. The relay is the authentication boundary and never parses payloads. The desktop installer ships the p4 agent alongside the app, so joining is not a second install.
Credit follows participation
Each stage reports the token rows it ran. The bridge accumulates them per node, and the gateway polls /api/contributions every 30 seconds and credits the wallet the bridge names, as rows / 1000 units scaled by the node's performance tier. In a pipeline every stage sees the same rows, so a four-stage ring pays its four stages equally no matter how many layers each holds — credit follows participation, not weight share. Expert sharding, where nodes hold different fractions of a layer, is the case that will need this revisited.
What the diagram marks as proposed
P4 Studio is p4's own operator console. The per-request observability feed it wants from the agents is a proposal upstream, not something running here — the diagram draws it dashed for that reason, alongside expert shards served from edge nodes, which is designed and not yet running.