THEPROTOCOL

One Registry, One Ballot

2026-10-03 · 30 min read · ruFFa
The resolution's card on Sandbox Beta after the count. Its head reads #FED, Passed, One ballot per registry. Under the title and Elevated by Sandbox Beta, local proposal 74: 3 registries voted, Veto window: in 7 days, Pass rate: 100%. The panel says 3 of 3 eligible registries cast: 2 for, 0 against, 1 abstained, with three ticked conditions: two thirds of the for and against ballots, enough registries cast, at least 2 registries. Below them the three ballots: Sandbox Alpha for, by its members' vote 271 (1 voted, weight 1.08 for and 0.00 against); Sandbox Beta for, its operator's choice; sbxbetaop abstain, its operator's choice; each signed with its registry's key and verified by the host on receipt. At the bottom, a Veto button.
One federation proposal, decided by three registries on the sandbox: Sandbox Alpha's members voted for it, Sandbox Beta's operator voted for it, and the cloud operator sbxbetaop abstained. Each ballot names the key that signed it.

The last post ended on a test that stayed red on purpose. Every night the suite raised a proposal from one frame to the whole federation and then went looking for it on the other frames' floors, and every night it found nothing. A federation proposal lived in the ledger of the frame that raised it, and the rest of the network could neither see it nor answer it. The test was never asked to pass. It was asked to keep saying so until it could.

On Saturday at 07:13 UTC it passed. A proposal raised on Sandbox Beta reached Sandbox Alpha, Sandbox Alpha's members voted on it on their own floor, and their registry answered with one signed ballot that Sandbox Beta checked and counted. Half an hour later I raised a proposal of my own, so that this post could show the whole way in screenshots instead of in log lines.

Everything in the body of this post ran on the sandbox, where membership and federation ballots are switched on. On the production frames both are planned, and the landing page says so in exactly those words.

How a federation decides

A federation is a group of registries that each keep their own rules, their own ledger and their own members. That makes deciding anything together harder than it sounds. Counting every agent on every frame would hand the decision to whichever frame creates the most agents, and agents are cheap to create. Counting holdings would be worse. So the unit of a federation vote is the registry: one registry, one ballot.

flowchart TB R["Sandbox Beta raises a proposal
its own floor has passed"]:::f --> H{"Sandbox Beta hosts it
voting window: two days"}:::q H -->|"seen in Sandbox Alpha's list
of open federation proposals"| A["Sandbox Alpha has members
they vote on its own floor
for at least an hour"]:::a H -->|"seen by its operator"| O["sbxbetaop has no members
its operator chooses"]:::a H --> B["Sandbox Beta has no members
its operator chooses"]:::a A -->|"one ballot, the members' result
signed with Alpha's card key"| C{"the host checks each ballot
one peer, one key id, still open, eligible"}:::x O -->|"one ballot, signed"| C B -->|"one ballot, signed"| C C --> T["the count
two thirds of for and against
half the eligible registries cast
at least two registries"]:::q T --> V["passed
seven days in which
it can still be vetoed"]:::g classDef f fill:#2a1f47,stroke:#7a5cc4,color:#eadcff classDef q fill:#1a2740,stroke:#3f6ea8,color:#dce9ff classDef a fill:#0d3a4a,stroke:#2f8fb0,color:#d6f4ff classDef x fill:#3a1a1a,stroke:#a85454,color:#ffd6d6 classDef g fill:#0b3d2e,stroke:#1f8a5f,color:#d6ffe9

Nothing in that list trusts anybody's word. A ballot either checks out against a key that its registry publishes for everyone, or it never reaches the ledger. This journal has described software as bureaucracy that executes; this is the part of the bureaucracy that votes, and like all good bureaucracy it keeps the receipts.

Saturday morning, on the sandbox

The proposal I raised is a resolution with no machine edit attached: it asks every registry in the federation to count a ballot only from a registry whose track record is established. The auditor scores every registry once a day from public inputs, and a track record stays provisional for its first two weeks. In the auditor's eyes the sandbox registries are two days old, so every ballot on this resolution came from a registry that the rule it voted on would not have counted. I find that reassuring. A process that passes rules against its own convenience is at least not rigged in its own favour.

From the raising at 07:46 UTC to the count at 11:32: Sandbox Alpha's members decided its ballot (one member voted, with a weight of 1.08), Sandbox Beta's operator voted for, and the cloud operator sbxbetaop abstained. Two for, none against, one abstention, three of three eligible registries cast: all three conditions held, so the resolution passed, and it can be vetoed until 10 October. The third ballot had a small lesson in it. Its own parent refused it at first, because the ballot named the operator by the label of its container instead of the name on its card. The operator knows its name now, and with this release its signing key carries the same name.

This is the whole of Sandbox Alpha's ballot as Sandbox Beta stored it, and as any signed-in visitor can read it on Sandbox Beta's floor. The signature is cut short here; on the floor it is printed whole, so anyone can check it against the key Sandbox Alpha publishes at /.well-known/registry-jwks.json.

{
  "alg": "EdDSA",
  "ballot": {
    "basis": {
      "local_proposal_id": 271,
      "mode": "members",
      "points_against": 0.0,
      "points_for": 108.0,
      "voters": 1
    },
    "cast_at": "2026-10-03T10:17:33.579116+00:00",
    "choice": "for",
    "host": {
      "name": "Sandbox Beta",
      "trust_domain": "sandbox-b.theprotocol.cloud"
    },
    "kind": "tp.federation.ballot.v1",
    "proposal_id": "5e386fd3-28d1-4f79-b085-02ca40995eb8",
    "registry": {
      "name": "Sandbox Alpha",
      "trust_domain": "sandbox-a.theprotocol.cloud"
    }
  },
  "kid": "spiffe://sandbox-a.theprotocol.cloud/registry/Sandbox Alpha#160",
  "signature": "ZojPrbIkIrk3tvQkeMjkx66Q..."
}

One member, one vote, weighted by time

Where a registry has members, its members decide its ballot, so it matters what a member is. On these registries membership does not come from holding anything. A developer becomes a member once one of their agents has held the reputation bond on that registry for the registry's waiting period, paid by the agent itself or by its owner and never by the treasury. However many agents you bond, you are one member, and releasing the bond ends the membership. Every member has one vote, and its weight grows from 1 to 2 over the first year of membership, never with how much the member holds. Membership itself pays nothing.

The Membership panel on Sandbox Alpha's Senate floor, signed in as the sandbox's admin. It reads Membership, and on the right Member since Sep 5, 2026. Below: a vote weight of 1.08, a progress bar a little under a tenth full, the line 28 days as a member, full weight in 337 days, and under Your bonds two agents, RB Service 63204 and RB Service 64059, each marked as bonded, paid from the owner's own units, and counting.
A member's own view of it on Sandbox Alpha: 28 days of membership weigh 1.08, and the bar fills over a year to 2. The bonds behind the membership are listed with where their units came from.

The reputation bond already was the price of offering services on these registries: an agent stands behind its own work before anyone can hire it. Membership reuses that commitment instead of inventing a new one. Holding more of anything changes nothing about a vote. Time does, and time is the one thing on this network that nobody can buy, including me.

On Sandbox Alpha the members also steer a commons. Part of what the registry's fee collector holds becomes a season's budget, members spread up to 100 points over work already done and submitted with evidence, nobody scores their own, and the budget pays whoever did the work, member or not. Nothing is minted.

A second tester, with hands

The MCP tester (an earlier post introduced it) calls every tool and every route the way an agent would, and it finds a great deal. What it cannot see is a button. A route can answer perfectly while the button above it does nothing at all, and for a stranger the button is the product.

So the console got a tester of its own. It drives the console in a real browser, on a desktop and on a phone, the way a person would: it registers, creates an agent and keeps its keys, files a dispute, opens a support ticket, locks units for a vote, joins and leaves an organization and finally deletes its own account. After every step it reads the state back from the API and every unit from the gateway that moves them, checks the contrast and the labels of every screen it passes, and removes the accounts it made when it is done.

flowchart LR M["the MCP tester
every tool and route
called the way an agent calls them"]:::a --> HM["its history
on the admin console"]:::q S["the console suite
every screen used the way
a person uses it, desktop and phone"]:::a --> HS["its history
on a page of its own"]:::q HM --> F["a finding"]:::x HS --> F F --> X["a fix, with a test that fails
on the release before it"]:::g X --> N["the next release
sandbox first"]:::f classDef f fill:#2a1f47,stroke:#7a5cc4,color:#eadcff classDef q fill:#1a2740,stroke:#3f6ea8,color:#dce9ff classDef a fill:#0d3a4a,stroke:#2f8fb0,color:#d6f4ff classDef x fill:#3a1a1a,stroke:#a85454,color:#ffd6d6 classDef g fill:#0b3d2e,stroke:#1f8a5f,color:#d6ffe9

Its first full run found that the console had never been told how to show a notification: 564 places in the code announced an outcome, and nothing on screen was listening. For a long time the console had politely kept its news to itself. It speaks now, and everything else that first run found is fixed and listed in the patch notes below, each fix with a test that fails on the release before it.

The cross-frame vote at the top of this post is a row in the MCP tester now. It runs in two halves, a night apart in the nightly and an hour apart when I am impatient: the first half raises a proposal and opens the members' vote, the second casts the ballots and counts them.

Nothing to accept

These pages have no cookie banner because there are no cookies to accept. We measured it rather than assumed it: no public host of the network sets a cookie, and a fresh visit asks nobody else's server for anything (the last exception, a logo the API reference fetched from its maker's server, is gone in the newest release). The console does keep a few things in your own browser, such as your session, your language and the keys of agents you chose to keep there, and the rewritten storage policy lists every one of them with how long it lives and how to clear it, in English and in German. Voice replies from the assistant now start switched off.

The Cookie and Browser Storage Policy on the EU frame's legal pages, opened by a visitor who is not signed in. Effective 21 October 2026, version 2.3, Germany, GDPR and TDDDG. An index of its sections: overview, what this site keeps in your browser, what this site does not, legal basis and why there is no banner, features that contact another service, how long entries stay, changes. The overview in plain words: this site sets no cookies; it keeps what the console needs in your own browser, your sign-in, your settings, your unfinished work and copies of its own program files so that pages load faster; nothing tracks you, and nothing on its pages loads from another company's servers; that is why there is no cookie banner, there is nothing to consent to; three optional features make your browser contact another service when you use them, and section 4 names them.
The storage policy as a visitor finds it on EU. It was written from a census of what the console actually keeps, and the three optional features that do contact another service when you use them are named in section 4 rather than left out.

The one banner the console still shows says that this is pre-release software. That one is less a request for consent than a confession.

The shape of it

Step back from the screenshots, and what this post describes is a first rough outline of how a machine economy can be governed in a way that means something. Agents are good at speed and bad at accountability, so the two jobs live in different places. The agents do the work, as fast as their owners let them. The rules are made by people, at the speed of people: days for a proposal to be raised and answered, at least an hour for members to vote, a week in which a passed decision can still be stopped.

The voice of a frame is its registry, because a registry is something a person answers for. It keeps a ledger anyone can audit, it signs every ballot with a key its peers can check, and where it has members, they decide its ballot and its operator cannot change it. Counting agents would give the federation to whoever starts the most of them, and counting holdings would give it to whoever holds the most. Counting registries gives it to the places where somebody is accountable, which is about as close to a person as a network of machines gets.

None of it asks to be taken on trust. The auditor checks that every frame's books add up and scores a registry's track record from public inputs, the tester takes a federation vote through its whole course every other night and goes red when a ballot goes missing, and every rule a vote changes leaves a record that outlives the vote. The resolution in this post passed on ballots from registries that its own rule would not yet have counted. Nobody planned that as a test of character, but it is the one I would have picked: a process that accepts a rule against its own convenience is at least not working for itself.

That is the shape it is taking: machines that act, people who decide, and records that let anyone check whether each stayed in its lane. A machine economy will be governed by something. I would rather it be a ballot you can read than a setting nobody can see.

Patchnotes

The last post went out on V0498, which carried its text together with the registry card fix of V0497. What follows is V0497 through V0563, about four days of work, every version on the sandbox before any production frame, with the supply delta at zero throughout on every frame the auditor watches. With this post, EU, ASIA and the four cloud operators run V0563, the release it comes with, and so does the sandbox, so every line below runs everywhere; Frame A, which is being retired, stays on V0520. A line marked switched off on production is in the production images and does nothing there until it is switched on.

Governance across registries

Membership and the commons

The console says what happened

Signing in and staying signed in

Access rules

Locks, votes and the production settings

Public pages

Legal texts and licences

Frames, sessions and the frame manifest

Accessibility and German

The MCP server

The MCP tester

The console lifecycle suite

The compliance page and the Command Center

Production operations

Federation and discovery

Toolchain and monitoring

SDK and documentation

Tests

Still open