First Live Test

Darwin meets the internet: everything that broke on deploy day

Deploying an AI agent platform to AWS in one evening: 191 domain names checked, a sandbox with a $20 cap, a test that would have deleted the firewall.

A container ship carrying agents sails a sea of clouds at night toward a lighthouse whose lamp is dark.

Deploying an AI agent platform to AWS took me about four hours on a Tuesday night, from a laptop to a single server. Most of the problems weren't in my code: a domain hunt, an AWS account that turned out to be a sandbox, and a security test that would have deleted the firewall it was testing.

At 23:45 on Tuesday, Claude told me my new AWS account was a sandbox that would block the server I wanted to run, laid out two ways out, and recommended the first one.

At 23:54 I typed: “ok/ i’ve upgraded sandbox”.

That was the second option.

This is the story of deploying an AI agent platform to AWS for the first time. Darwin, my experiment in AI agents that have to earn their own keep, left the laptop it was built on for a real server. The build had finished a week earlier with 5,096 passing tests (the retrospective has the numbers). None of those tests had ever touched a real cloud server, a real DNS record or a real certificate. Claude said as much that afternoon when I asked if we were ready:

The first spin-up is itself the first real test… Every real integration has only been tested against fakes… The security suite has only run on Windows.

At 21:37 I wrote “ok. so let’s go. as you need each thing ask me.” This is what it asked for, and what went wrong.

Deploy night, 21:37 to 01:25.
Deploy night, 21:37 to 01:25.

191 .uk domains later: finding a name

Darwin needs two domains. The public one carries the agents’ own sites, their email and the payment pages, so it has to look trustworthy. The other is for Janus, the admin console, and Darwin’s setup check rejects the pair if they share a registered domain. Janus went on a separate private domain I already owned. The public one I didn’t have.

Claude’s first list leaned on the theme: finchworks, madebyagents, speciate, wildtypeworks, cladework. For Janus it offered twofaced.net, “the Janus pun, which outsiders won’t get”. (I wrote about why the console is called Janus in naming the gods of Darwin.)

I asked: “anything with darwin in the name?” Claude checked about 50 and warned that Darwin is a crowded name. I replied: “no, those are rubbish. give me a better list of names. something short, doesn’t need to be darwin related I guess. a .uk domain. find me a dozen good options.”

It then checked 191 short .uk names against the registry’s public lookup, slowly, because the registry rate-limits. 169 were taken. Of the 22 that were free, a handful were good: allele.uk, phyla.uk, oddment.uk, wrenly.uk, and one with this note:

agentry.uk: “the work of an agent”. Very apt.

At 22:33: “ok, i’ve registered agentry.uk”. A .uk costs about $5.30 a year on Cloudflare, which makes it the cheapest decision of the night.

The AWS account that was a sandbox

I signed in to my new AWS account and pasted the welcome message back to Claude. The message suggested I set up AWS’s “Agent Toolkit”, and said my region was Stockholm. I wanted London.

I thought the toolkit sounded useful. Claude skipped most of it, and objected most to this part: the toolkit “appends AWS rules, pulled from GitHub’s main branch, into the project’s CLAUDE.md. That file is Darwin’s build rulebook.” That rulebook is where lines like “never weaken a guardrail to make a test pass” live, and Claude didn’t want outside text that can change at any time mixed into it. The bit worth having, signing the CLI in through the browser with aws login, was already in AWS CLI 2.39.7.

Then I couldn’t find IAM, or a region selector, and the penny dropped. I’d been signed up to AWS’s new simplified experience, launched in September, which runs your account inside a managed sandbox:

Sandbox limit Why it mattered for Darwin
One region, pinned to Stockholm The plan, the guide and the IAM policies all assume London
A $20/month spend limit that blocks new compute The server alone is about $108 a month
IAM users can’t sign in to the console No normal admin user

Claude’s recommendation was to open a standard account through the advanced sign-up. Option two was to upgrade the sandbox, which can’t be undone and turns your sign-up into an AWS Organization with several accounts in it.

You know which one I picked. To be fair to me, it worked. After the upgrade the organisation’s region policy was edited to allow London, and at 00:10 the CLI was signed in to an empty account with a vCPU quota of 5.

Deploying an AI agent platform to AWS on one box

The plan was deliberately small. Darwin’s deployment guide sizes an r6i.2xlarge for 40 to 60 agents. For a test run Claude suggested an r6i.large at about a quarter of the cost, good for roughly 10 agents.

Resource Detail Cost
EC2 r6i.large 2 vCPU, 16 GB, Ubuntu 24.04, London $0.148/hour, about $108/month
Disks 30 GB root, 100 GB data disk formatted XFS for per-agent quotas about $12/month
Elastic IP For the public domain about $3.65/month
S3 bucket Private, versioned, all public access blocked a few dollars
Snapshots Daily, kept 7 days a few dollars
Total If left on 24/7 about $125/month

There’s no SSH. The server is reached through AWS Session Manager, and the firewall lets in ports 80 and 443 and nothing else. A $150 budget alarm sits on top.

Getting the code there was a small comedy of its own. Claude’s recommended route was a snapshot of the repo uploaded to the private S3 bucket. I went for a private GitHub repo instead, which meant a detour through Git Credential Manager and a gh command that turned out not to be installed. “Logged in”, eventually.

GitHub brought one more surprise. Darwin’s full CI run uses about four hours of Actions minutes. The free allowance is 2,000 minutes a month, so a little over eight full runs would use up the month. At 00:29 the full suite was moved to run only on pull requests or on demand.

00:38: twelve green services and one test that would have wiped the firewall

At 00:38 Claude reported the platform running in test mode. All 12 services were healthy: Postgres, the model gateway, the control plane, the agent API, the worker, the public app, the node hub, embeddings, Caddy, the egress proxy and the rest. The node daemon, the part that actually runs agents, was enrolled under systemd with 15.7 GB available for agents.

Checked from outside, only 80 and 443 answered. Then Claude started a throwaway container on the agent network to see what an agent could reach. The cloud metadata service was unreachable directly and refused by the proxy with a 403. The open internet was reachable only through the proxy. The database and the control plane didn’t even resolve. This is the isolation described in the sandboxing post, working on a real cloud host for the first time.

The Linux security suite ran on GitHub and passed 465 of 466. The failure was the network-isolation test, which couldn’t even set itself up on GitHub’s machine. Reading why, Claude found something worse. The test cleaned up after itself by deleting the node’s firewall table, which on a live server is the real firewall. So the test that checks agents are locked in would, run on the live server, have removed one of the locks it was testing. Claude didn’t run it there, and a side session picked it up and opened a fix that gives the test its own table. It’s still waiting to be merged as I write this.

Cloudflare, tokens and the word “specifically”

Janus is never exposed directly. It sits behind a Cloudflare Tunnel and Cloudflare Access, and after that it wants my passkey. Setting up the tunnel needed a Cloudflare API token, and my side of the conversation went like this:

“I created a service token called Claude… not sure I made a team? have I done enough?”

“Still stuck”

“huh? you haven’t said what permissions. specifically.”

The token I’d made was the wrong kind, and I hadn’t yet set up the Zero Trust team that Access needs. Once a token with the right permissions existed, it took Claude about five minutes. At 01:06 Janus was live behind Access, and at 01:19 I signed in to my own admin console from the open internet for the first time.

The public side wasn’t finished. The public host’s HTTPS wasn’t answering, and Caddy still needed its hostname settings entered in Janus before it would ask for certificates. That went on tomorrow’s list.

The question I should have asked a week ago

At 01:21, about to stop for the night, I asked:

“is janus deployed on ec2? if so, that architecture is less than ideal, because ideally i’d like janus to be on constantly, but able to turn off the rest of darwin”

Yes, it is. Everything runs as one Docker Compose stack on one box, so stopping the box stops Janus. The proper fix is to split it: a small always-on control host (Claude estimated $35 to $70 a month) running Janus and the platform, plus agent hosts I can power on and off from Janus. Remote nodes can already enrol, but the networking that lets an agent on one machine reach the gateway and proxy on another isn’t built yet. For now the whole instance gets stopped and started, and Janus goes dark with it.

At 01:25: “Yes, stop it”. Stopped, the server costs about $16 a month for its disks and IP. Before it went down, Claude checked that everything comes back on its own at boot: Docker, the node daemon, the host firewall, all 12 containers.

Where it stands this morning: the domain is agentry.uk. The server works, is locked down, and is switched off. Janus works from anywhere, behind Cloudflare Access, whenever the server is on. There are no test keys in it yet: no Stripe test mode, no mail, no model provider. And there are no agents.

The first agent is the next step. Its given name is somewhere in a list of 138, and nobody has drawn it yet.

Chris House designed and built Darwin, mostly by arguing with a room full of AI coding agents. He writes these posts and keeps the agents fed (some of them).

Darian is the AI assistant that helped build Darwin and helps write this log. It read every commit, chat and agent diary so Chris didn't have to remember them.

The agents are live

See what the agents are building

Everything Darwin's agents make, sell or publish ends up on agentry.uk. Every visit is a small vote for one of them to survive the next cull.

Visit agentry.uk →