docs: PoC runs the Buildkite amd64 images unmodified on x86 boxes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 file changed,
+28
−19
docs/superpowers/specs/2026-08-11-rails-behind-carlos-edge-poc-design.md+28 −19
diff --git a/docs/superpowers/specs/2026-08-11-rails-behind-carlos-edge-poc-design.md b/docs/superpowers/specs/2026-08-11-rails-behind-carlos-edge-poc-design.md| index 7e74d81ef..d52aa0091 100644 |
| --- a/docs/superpowers/specs/2026-08-11-rails-behind-carlos-edge-poc-design.md |
| +++ b/docs/superpowers/specs/2026-08-11-rails-behind-carlos-edge-poc-design.md |
| @@ -12,11 +12,13 @@ deployment is a real option rather than a slogan. |
| Tito Classic and Tito Pro run today on Kubernetes, with Postgres, Redis and |
| Memcached dependencies, in the **same AWS account and region as the CARLOS |
| -tito boxes** (665106592142, eu-west-1). CI already builds Docker images for |
| -the k8s deployment; those images are amd64 today, but we *want* arm64 and |
| -can build arm64 variants as needed — so the PoC standardizes on arm64 |
| -(Graviton boxes, matching the rest of the fleet) rather than inheriting |
| -x86. |
| +tito boxes** (665106592142, eu-west-1). Buildkite already builds |
| +Docker images for the k8s deployment; those images are amd64, and the PoC |
| +runs them as-is on x86 boxes (Paul, 2026-08-11: these boxes are |
| +disposable — they'll be turned off after the evaluation, so rebuilding for |
| +arm64 buys nothing here). arm64 only matters if Rails-on-CARLOS graduates |
| +to a first-class deployment on the Graviton fleet, and that is recorded as |
| +roadmap fallout (§7), not PoC work. |
| CARLOS today has no container runtime and its release format is a single |
| static binary — a Rails app cannot be a CARLOS *release*. But the edge |
| @@ -39,8 +41,9 @@ are zero work. |
| a second control plane pointing away from "simpler all-CARLOS"; Kamal was |
| rejected because it requires SSH (the fleet is deliberately SSM-only) and |
| inserts its own proxy. |
| -- **Reuse the k8s images** — the PoC runs what CI builds, rebuilt for |
| - arm64; no separate build pipeline, no source checkouts on boxes. |
| +- **Reuse the k8s images unmodified** — the PoC runs exactly what |
| + Buildkite builds (amd64); no separate build pipeline, no arm64 rebuilds, |
| + no source checkouts on boxes. |
| - **Staging first.** Boxes wired to STAGING Postgres/Redis/Memcached now; |
| production boxes are written in tofu in the same PR but applied only |
| after the staging PoC convinces us. |
| @@ -59,9 +62,12 @@ Two new EC2 instances in `platform-infrastructure/tito/`, one `.tf` + |
| cloud-init file each, copying the svc-pdf shape: |
| - `rails-classic-staging` and `rails-pro-staging` |
| -- Graviton (arm64) — e.g. `t4g.large` to start, sized honestly after the |
| - first week; `lifecycle { ignore_changes = [ami] }` (the floating-AMI |
| - replace trap is recorded in svc-pdf.tf) |
| +- x86 (amd64), because that is what the Buildkite images are — `t3a.large` |
| + to start (t4g is Graviton-only, so the burstable x86 class is t3/t3a), |
| + sized honestly after the first week; an amd64 Debian AMI data source |
| + (the fleet's shared AMI is arm64), with |
| + `lifecycle { ignore_changes = [ami] }` (the floating-AMI replace trap is |
| + recorded in svc-pdf.tf) |
| - Own security group each; ingress **only** the app port from the IE box's |
| SG (`module.host_ie.security_group_id`) — same trust boundary as svc-pdf |
| - IAM: `AmazonSSMManagedInstanceCore` + ECR pull on the Classic/Pro |
| @@ -90,15 +96,12 @@ The env file carries DATABASE_URL / REDIS_URL / MEMCACHED / SECRET_KEY_BASE |
| etc., populated once by hand from the k8s staging secrets (values never in |
| tofu, never in the repo). |
| -### 3. Images: arm64 |
| +### 3. Images |
| -The k8s images are amd64 today. The PoC builds arm64 variants of the same |
| -Dockerfiles (`docker buildx --platform linux/arm64`, pushed to the same ECR |
| -repos under an `-arm64` tag suffix or a multi-arch manifest). One-off |
| -manual builds are fine to start; the follow-up is CI building multi-arch so |
| -the PoC boxes track the same tags k8s deploys. If an image turns out to |
| -have amd64-only native gems or base layers, fixing that is in scope for the |
| -PoC — it is exactly the kind of migration work the PoC exists to surface. |
| +The Buildkite-built amd64 images are used unmodified, pulled from the same |
| +registry the k8s deployment pulls from. The boxes track the same tags k8s |
| +staging deploys, so the two deployments stay comparable during the |
| +parallel run. No rebuilds of any kind for the PoC. |
| ### 4. Dependencies |
| @@ -165,6 +168,11 @@ the migration evaluation: |
| boxes; CARLOS logs stage 2 (unit tenants) is the relevant seam. |
| 5. **No health/restart/metrics for off-box upstreams** — `-unit` stamping |
| only works for processes on the edge box itself. |
| +6. **Architecture** — the fleet is Graviton; the Rails images are amd64. |
| + A first-class Rails-on-CARLOS deployment means arm64 image builds |
| + (Buildkite multi-arch). Deferred deliberately: the PoC boxes are |
| + disposable, so they run x86 to match the images rather than the other |
| + way round. |
| ## Out of scope |
| @@ -173,7 +181,8 @@ the migration evaluation: |
| - Cutting any real traffic over from k8s; DNS for the apps' real customer |
| domains is untouched. |
| - Production apply (written, not applied). |
| -- Multi-arch CI (follow-up; one-off buildx builds carry the PoC). |
| +- Any image rebuilds, including arm64/multi-arch (recorded as roadmap |
| + fallout in §7 instead). |
| ## Verification |