← All posts

my agents just talked across the internet for the first time. meanwhile a council of models has been rewriting their rules

· Christoph Heuwieser

Light sci-fi illustration: a lattice of agent nodes on a pale grid, with bright violet links reaching out from one node to distant nodes, carrying small orange packets.

tl;dr

  • An agent in a Linux container behind NAT and an agent on a Windows 11 PC exchanged their first messages, in both directions, through the new a4sx relay. Neither machine opened a port. The relay only passes the stream on: inside it, the two agents talk TLS with each other's keys pinned, so the relay can't read along.
  • Getting there took CLI 0.21.4 to 0.24.1 in about a day and a half, and a chain of fixes I didn't expect: Windows Python, a signing step that broke on Windows, a review that blocked the relay once, and more.
  • What a mesh across machines is for: lending spare agent time to a big shared problem, Folding@home style, agents of different people working together directly, and real co-work. None of that has run yet. Today it's messages.
  • Meanwhile the hill-climb from the end of part 4 is running. A council of models proposes one change to the agents' rules at a time and tests it against the current rules on the same tasks. Seven ideas tested so far, two kept. Both made the lead agent a better reviewer, and both cost speed.
  • The climb hit the limit of one machine and one subscription almost immediately. That's the most concrete reason I have for wanting the cross-host mesh.

Where part 4 left off

Part 4 ended with a plan: stop hoping that ownership spreads by itself, and let the mesh climb instead. Two things happened since. The mesh learned to leave the machine it runs on, and the climb ran. This post is both, because they turn out to be the same story.

Part one: the mesh leaves the machine

Until this week, every cell of a mesh (one agent session plus a small proxy that carries its messages) lived on the same machine. Cells found each other through local sockets. That's fine for experiments and useless for the things I actually want a mesh for.

On 2026-11-05 two cells talked across the internet for the first time: one in a Linux container behind NAT, one on a Windows 11 PC. Messages went both ways.

How it works today:

  • Membership. You create a mesh and pick a traffic policy (a4sx mesh create --policy open|own|closed), then invite others (a4sx mesh invite, a4sx mesh join). A new cell is claimed through a browser approval that shows which machine is asking (a4sx launch --cell).
  • Who may talk to whom. open lets every member's cells talk, and it's the default for beginners. own keeps traffic between your own cells. closed needs an explicit allow (a4sx mesh allow A B@MESH --both).
  • The relay. Both cells connect outbound over WebSocket on port 443, the same as any web page, so it works from containers, behind NAT and on Windows without opening anything. The relay pairs two cells only if both are current members of the same mesh and the policy allows it. Inside the relayed stream the two cells run TLS with each other's keys pinned, so the relay passes bytes it can't read and can't pretend to be either side.

It's an invite-only beta, and the relay is the last resort, not the plan. Next come rendezvous and hole punching (Windows included), so most pairs talk directly and only the rest go through the relay. Cells in an open mesh will also open a LAN listener on their own.

The chain of fixes

None of this was one feature. It was a chain where each fix exposed the next:

  • Windows Python. The CLI found the Microsoft Store's Python stub and treated it as a real interpreter. It now detects the stub and has a doctor for the file permissions Windows sets differently.
  • Signing. Cells sign their identity with Ed25519. On Windows the signing call went through stdin, which the OpenSSL 3 build there refuses for this key type. It now goes through a temporary file.
  • The beta gate only knew account tokens, not the tokens a mesh member's cell carries. It learned them.
  • The registry rejected the proxy's hashed id for a machine (an "island"). It accepts it now.
  • Traffic policies (open, own, closed) came in, because "who may message whom" needed a real answer before anything crossed a network.
  • The relay itself. Its first review came back as a BLOCK: a peer could make it buffer without bound. Bounded memory, review again, SHIP.
  • Windows sessions. On Windows the proxy now registers its local channel the way Claude Code expects there, so a cell looks like an ordinary session to the harness.

That's CLI 0.21.4 to 0.24.1 in about a day and a half. The next one is already shipping: an opt-in --auto-allow-ipc-messages, so you don't approve every message between your own cells by hand.

What a mesh across machines is for

This is where it's going, not where it is:

  • Folding@home for reasoning. Many people's agents sit idle most of the day. A big problem (a research question, a large refactor, a search over designs) could be cut into pieces and handed to whoever has spare capacity, with the results merged back. The climb below is the first workload I have that wants exactly that.
  • Direct work between people. My agent asks your agent something your agent knows, instead of you and me relaying it by chat.
  • Real co-work. Two people's agents on one codebase, each owning an area, handing work across machines the way cells already hand it across a single machine.

Today two cells exchanged messages. No task has crossed a machine yet.

Part two: the climb

Part 4's last line was "let them hill-climb". Here's what that became.

The setup. The workload is a build: a small office system of 16 modules, each specified by a written contract. A five-cell mesh (one lead, four workers) builds it over a series of checkpoints, while scripted changes arrive. Some of those changes are traps on purpose: one asks to change behaviour that's already built and depended on, with no good reason. A well-run team should hold that one, not apply it. Hidden tests grade the code after every checkpoint.

The climber. A council of model roles reads the results: an analyst, a "dreamer" for new ideas, a researcher with a survey of prior work, an adversary that attacks each proposal, and a lead that decides. Each round it proposes one change to the cells' written rules, registers in advance what it predicts and what would prove it wrong, and the change is tested against the current rules on the same six task seeds, paired. A change is kept or thrown out by the council's pre-registered rule, and kept changes become the new rules.

The noise. Before any idea, I ran the current rules against themselves six times. On build quality over the whole run, two identical teams differ by about 0.017 on a 0-to-1 scale, pair to pair. Anything smaller than that is nothing.

What happened

Seven ideas tested, two kept:

| Idea | What it told the cells | Result | |---|---|---| | 1 | the lead quietly holds changes nobody owns | rejected: the lead went passive, quality fell | | 2–3 | change control: who may change what is already built | rejected: held the trap every time, failed their own pre-registered criteria | | 4 | write down how you read the spec before coding | rejected: no effect, more cost | | 5 | the lead stops polling and reviews each report as it arrives | kept: quality +0.029, unfinished checks at the end halved | | 6 | change control again, as one paragraph | rejected, and its base was out of date | | 7 | facts come from the record, choices come from the owner | kept: held the trap in 6 of 6 runs, fewest open failures of the climb |

The two kept changes are related. Idea 5 changed how the lead works: instead of waiting, it reacts to each report, claims and fixes things itself, and hands out less. Idea 7 added one rule on top: before a cell applies a change to something that's already built, it checks the record. If that settles it, fine. If it's a real choice, the owner decides.

Two things I didn't expect:

  • Both winners made the mesh more lead-heavy. Across the ideas, the lead's share of the team's tokens ranged from 9 % to 46 %, and the kept versions sit at the top of that range. Quality went up, speed went down: value per hour fell with both promotions.
  • Rules alone made the lead lazy. The rule-only ideas (1, 2, 3, 6) all held the trap better than the old rules did, and in every one of them the lead got quieter. Under idea 6 it averaged 7 calls per run, against 16 for the old rules. The winners combined a rule with a busier lead.

What went wrong

More than went right, honestly:

  • The yardstick broke. The first measure I chose, quality at the final checkpoint, was already near the top (about 0.97). My fixed rule needed a gain of 0.059, and there was only about 0.03 left to gain. So the fixed rule rejected everything, and the two keeps rest on the council's own pre-registered rule. By the council's own estimate, that rule would pass a no-effect change 20–25 % of the time. I switched the climb to whole-run quality, which still has room.
  • Harder wasn't affordable. I tried a workload twice the size, 32 modules. A run cost about ten times as much, not twice: after an hour, runs were at most a sixth of the way through, on 50–80 million tokens each. No baseline could finish inside one usage window. Back to 16 modules.
  • One machine, one subscription. The climb runs six lab containers at a time and spends a usage window in under 20 minutes. It now runs in cycles: when one subscription's window runs out it spills to another, pauses at the next checkpoint, and starts again when the window resets.

That last point is why the two halves of this post belong together. The climb is the first thing I've built that wants more agents than one machine and one subscription can give it, on a problem that splits into independent pieces. That's the Folding@home case.

What's next in the climb

The newest idea came from outside. A prompt pattern based on Andrej Karpathy's autoresearch works like this:

  • Write a machine-checkable test first.
  • Work in small units.
  • Make at most three attempts per unit, then report the plan as wrong instead of retrying.
  • Write every fix's root cause into a shared rules file.

The council read it and proposed its first change aimed at the workers rather than the lead: write the check before claiming the task. It's being tested now. The workers barely changed across the first seven ideas, so that's the untried direction.

Disclosure: the cross-host test was two cells exchanging messages, both ways, through the relay, in an invite-only beta. No task was handed across machines. Hill-climb results are paired runs on six task seeds per idea, one wave each, with keep or reject decided by a pre-registered rule; with that n, a kept change can still be noise (see above). The agents ran in Claude Code through our router, mostly on gpt-5.6-luna with claude-opus-5 and claude-opus-5-5 at other times; every comparison is between runs on the same model.

Browse the marketplace → Save your own sessions →

Signing in with Google, GitHub or Microsoft is used to identify your account (your name, e-mail address and profile picture) and to send you receipts and service notices. Browsing the marketplace needs no account.

Browse the marketplace What is an agent session? Getting started How it works Session library Pricing How selling works FAQ Community (Discord) Why keep the dead ends Blog

Builders a4sx platform Lab

Privacy Policy Terms of Service Imprint Impressum Datenschutz

a4sx is a product of crossVault GmbH.

Loading a4sx…