- You type
ls. The tab seals it with keys only it and your laptop share. - The relay forwards it. It sees a destination key, a number and sealed bytes. Nothing else.
- Your laptop opens it. It checks the tab's grant against your log, then runs the command.
- The answer comes back. Sealed the same way. Change networks and the session carries on.
Five ideas
Node
Anything with a key is a node: your laptop, a server, a browser tab, the command line, an agent's door, a relay. A node is a key plus the list of things it can do. The same core runs on all of them, written in Rust, native on machines and WebAssembly in the browser.
Log
Your account is a signed, grow-only list of which keys are yours: this laptop was added on Tuesday, that phone was revoked on Friday. Every node keeps a copy. A node learns its peers' keys only from the log, never from a server, so no server can slip in a key of its own.
Pipe
A pipe is any way bytes get from one node to another. There is always a WebSocket to a relay, so you are reachable from any network that allows the web. When a faster path appears, a direct WebTransport or WebRTC connection joins it. The relay forwards by key and sees only sealed bytes.
Session
Two nodes shake hands once, with X25519 and ML-KEM together. They check each other's keys against the log and get session keys that belong to no pipe. Every message after that is numbered and sealed on its own. When your wifi drops and the phone moves to 5G, the session carries on over the new pipe without a new handshake, and anything unacknowledged is sent again.
Service
A service is what a node does when asked: a terminal, files, sync, the editor. The node verifies who is calling and what they were granted, then hands the request to the service. The core stays short enough to read in a sitting, and everything else is a service.
Where it can break
We write down where each idea fails, because that's what you're trusting.
- A stolen laptop is a valid key until its revocation reaches the machine holding your data.
- The relay is where availability depends, and it sees who talks to whom, when and how much, though not what.
- A machine that is offline misses revocations, so grants are short-lived.
- Lose every device that can sign for your account and you lose the account. Add a second one early.
Each part
How each part of Features keeps its promises, and what is still open in it. Each choice behind them, and what it was chosen over, is in Choices.
Using it
- First minute
The flow is four steps:
- Shell & notes
A page is a tree: each node names a component from the app's source, with its props, its styles and its text. The tree lives in a CRDT, so anyone can edit it at once and every copy ends the same. The editor draws the tree with the real components, so the page works while you edit it, and an edit only ever changes the tree, never the code.
- Files
The files service on a node watches a folder and keeps a Loro doc beside it. The spikes (files-sync, git-roundtrip, git-import and shallow, in
spikes/) tried each part; what they found is in their READMEs, and what they couldn't solve is under Open. - Machines
A service is a name bound to a handler, in the first release a process on a local socket, given the verified caller, the verb, its arguments and a stream. The node checks the call (
access.md), then hands it over. - Your devices
A node is a key and a table of handlers: a machine, a browser profile, the command line, the MCP door and a relay are all nodes. The log is the account's signed, grow-only set of node records, grants and revocations.
- Browsing
A profile is a browser's cookie jar, history and settings, and it is a box of its own on one node (Sandbox). In it runs one real Chrome, headed on a display of its own, with a tab per pane. The pane is a view of that tab: what it shows travels over the same sealed session as everything else, and what you type travels back naming what you aimed at.
Letting others in
- Access
A holder is the node that has what a call asks for. Every call reaches a holder through a session (
network.md), so it arrives with a verified key, and the holder answers one question about it from its own copy of the log:may(key, class, resource, now), which says allow, ask or no. No server is asked, so it works offline (log/sync-before-serve). - MCP
MCP is a service that ships with every node (D-4), off until turned on. It makes no decisions of its own: each client is a key (
access.md, Keys for everything that calls) and each tool call becomes one call to a service, on this node or another, as that key, checked by the node that holds what it asks for.
Changing it
Underneath
- Network
A pipe is a channel to another node; a session is the sealed conversation that runs over whichever pipes there are.
- Relay
A relay is a node that forwards sealed frames by key. It is the one pipe every node can always open, so it is also the one place availability depends on, and whoever runs it sees who talks to whom, when and how much. Ours adds what running it takes, such as limits by plan, metering, TURN and names on our domain, and never a change to the wire (D-16).
- Core
The core is sans-IO Rust, native on machines and WebAssembly in the browser, so the guarantees are the same on anything that can hold a key, from an ESP32 up.
- Browser
A browser trusts whatever its origin serves over TLS, and a network that can mint certificates for that origin, such as a proxy with its own certificate authority, can serve a page that uses the key (Core). A plain page can't stop that, so three things, later (D-21).
- Sandbox
The sandbox is a service on a node that makes boxes and is the only way anything gets one. A box is a set of Linux namespaces (user, mount, pid, network, ipc, uts), a seccomp filter and a cgroup, made by the node as the user it runs as. The node holds the box's network end, so it is the gate, and writes the audit. A browser profile (Browsing) and an extension instance are both boxes; nothing else in the node makes one.
- Trust
Keeps: trust/base-small, trust/reproducible, trust/public-log, trust/tiers, trust/base-approved, trust/urgent-fix, trust/widen-asks, trust/undone-on-failure
- How we know
Stories, promises, design, code and tests are joined by names, and the site is built from those names when it is built.