Answering (1) directly: a region box today is edge-only — not by design, but because nothing tells it otherwise and nothing checks. So armed advertising it as placement-capable is the bug, and that is what this fixes.
What the 502 told us
Every wake failure internal/activator's serve() has — lease held, wake timeout, spawn error, restore error — answers 503. It declines the request entirely, returning false, in exactly one case: the route is not a hibernating instance. So the 502 you saw was never a failed wake. It was the edge proxying straight to /run/carlos/<host>.sock — the path the route derives, and which only an armed activator ever creates — into the stdlib ReverseProxy's default handler. That also explains the ~13s you may have noticed per request: dialUnixWithRetry retries ENOENT for 13 seconds first.
Your empty bucket is the same finding arriving independently, and it was the most useful thing in the report. Every wake claims an S3 lease before it does anything else, so a bucket with no lock object means no wake was ever attempted on that box. Not attempted and failed — never reached.
Why
An activator arms on CARLOS_HIBERNATE_BUCKET in the box's /etc/carlos/host.env, read by carlos-edge.service at start. Nothing in the platform repo puts it there: carlos bootstrap deliberately doesn't, and infra/modules/region-host grants the host role its region's data bucket and then never mentions it again. The bring-up procedure's minimum host.env is four variables and none of them is this one. That is why the bucket exists, is granted, and is empty.
Everything else you saw follows: adoption and staging are region-blind and activator-blind, so the binary staged and the symlink repointed exactly as designed; the provisioning pass minted the route the same way; and then nothing on the box owned the process. No unit because exec-backed instances don't get one; no socket and nothing under /data because those are all minted at spawn.
What landed
Branch region-hosting-armed, CI green, not merged — it changes a production gate, so it wants your eyes.
armed now means "can host". It was "a box publishes this placement code and has an EIP" — an edge-membership fact — while the regions endpoint, the create door and every consumer picker read the set as "regions that can take an instance right now". armedPlacements now also requires the box's published data_bucket, which is CARLOS_HIBERNATE_BUCKET verbatim, written by the same process, from the same env, that decides whether the activator arms. It has been on the wire since the instance-move work; nothing read it.
It is dormant until some box publishes a data bucket, so roll order is safe, and it heals with no console change: the moment a region box's host.env grows the variable, its next edges-file pass publishes the key and that region arms itself.
The box now says it out loud. Edge Reload names a hibernate-flagged instance route on a box with no activator — which host, which socket nobody will bind, which variable fixes it. That condition was completely silent before, which is most of why this cost you fifteen minutes and an SSM session.
On (3), the pilot
It is a box-side change, not a platform one, and it is small: add CARLOS_HIBERNATE_BUCKET (and _REGION, _PREFIX) to carlos-tito-us's /etc/carlos/host.env and systemctl restart carlos-edge. The IAM grant and the bucket are already there. Watch for agent: hibernation activator armed in the journal — that line is the whole confirmation. us then re-arms itself in the console within a pass, with nothing to deploy.
Your sizing note stands and is worth acting on before real tenants: 2 GB against ~128 MB PSS per instance is a handful, and carlos-edge.service caps the whole exec-child tree at MemoryMax=80%.
Two things I found on the way, not fixed here
Per-instance DNS for a region-placed host is recorded but not built (internal/console/apiinstances.go says so in as many words). So region-probe.go.tito.io almost certainly still resolved to the home edge and arrived at the US box over the backhaul — whose dial and TLS failures are also bare 502s. If a region box turns out to be armed and still 502s, that is the next place to look, and it is the same class of problem as #103.
"Setting up" was a separate bug, and not region-specific. instanceHealth opens the console box's own local registry and joins records against it, so a route minted on any other box hits "no route minted yet" and reads Setting up forever. The fleet snapshot carries only route_versions, not the kind/status/hibernate/provisioned columns healthWord needs, so the console currently cannot compute health for any off-console-box route. Worth its own issue — say the word and I'll file it.
One correction to the framing in the report, offered gently: this was not five regions failing. It was one missing line in a hand-rolled host.env, replicated five times, that the platform had no way to notice and every reason to. The consumer-side work you shipped is not inert — it was being told the truth about edges and reading it as a truth about hosting.