carlos / platform Public

plan: design a platform-dev environment in the repurposed kass AWS account

Adds docs/superpowers/specs/2026-08-02-platform-dev-environment-design.md:
a full-stack dev deployment (platform.dev.carlosframework.com) mirroring
flagship/tito exactly, in AWS account 640012953448 (kass, repurposed —
Paul confirmed superseding its planned teardown). Closes the "no real AWS
access" gap from the overnight rastrillo build by proving hello world
live through the real carlos binary instead of a local-dir demo.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Paul Campbell df6ded2115f36708e3324f6f8233a34fc0cc11c0 parent 6736599
1 file changed, +104 −0
  • docs/superpowers/specs/2026-08-02-platform-dev-environment-design.md +104 −0
diff --git a/docs/superpowers/specs/2026-08-02-platform-dev-environment-design.md b/docs/superpowers/specs/2026-08-02-platform-dev-environment-design.md
new file mode 100644
index 000000000..b4cc9a1d9
--- /dev/null
+++ b/docs/superpowers/specs/2026-08-02-platform-dev-environment-design.md
@@ -0,0 +1,104 @@
+# Platform dev environment — design
+
+**Status:** approved 2026-08-02 (Paul, background session).
+
+## 1. Purpose
+
+The flagship (`platform.carlosframework.com`, AWS 271376211898) and Tito's
+self-hosted deployment are both production. There is no environment to
+prove new platform or framework work against a real `carlos` binary, real
+S3-backed buckets, and a real DNS-routed edge without touching either.
+This spec adds one: `platform.dev.carlosframework.com`, a full-stack dev
+deployment in its own AWS account, proven end to end by getting the
+rastrillo v1 walking skeleton's hello-world example genuinely live on it.
+
+This directly closes a gap flagged in memory after the overnight
+rastrillo build (2026-08-01→02): that session had no AWS credentials, so
+"deployed on the platform" meant a local directory-store proof only. This
+session has real credentials for the account below — the dev environment
+lets that proof become a real one.
+
+## 2. Account
+
+**AWS account 640012953448 — the kass account, repurposed.** It was
+frozen 2026-08-01 after Kass migrated to the flagship, with a teardown
+planned for ~2026-09-01 after a 30-day cooling period (see
+[[session-exec-state]] memory). Paul confirmed 2026-08-02: repurpose it as
+the permanent platform-dev account instead of tearing it down. The old
+frozen resources (3 stopped `t4g.micro` instances, the `kass-litestream`
+S3 bucket) are left untouched — new resources use `carlos-dev-*` naming,
+which doesn't collide with anything already in the account. Root email
+stays as-is; Paul will re-home it separately, on his own schedule — not
+part of this work.
+
+## 3. Shape — mirrors flagship/tito exactly
+
+Same pattern as the existing two deployments in
+`carlosframework/platform-infrastructure`: a self-contained tofu root
+under a new `dev/` directory, consuming the same `../modules` (via git
+source URL, same as a self-hoster would). Nothing account-shaped enters
+tofu state; the platform owns apps/releases/instances/dynamic DNS same as
+always.
+
+- **State:** new S3 bucket `carlos-tfstate-640012953448` (created before
+ first `tofu init`, matching how the flagship/tito state buckets were
+ bootstrapped), key `dev/terraform.tfstate`, profile `kass`, eu-west-1.
+- **Buckets** (module `deployment-buckets`): deployment bucket
+ `carlos-dev-640012953448`, data bucket `carlos-dev-ie-640012953448`.
+- **Host** (module `region-host`): one box, `carlos-dev-ie`,
+ `t4g.micro` (dev-sized — matches the tier of the old kass boxes, no
+ need for flagship's `t4g.small`), 20 GiB root volume, SSM
+ Session Manager only (no SSH ingress — the family convention),
+ `host-init.sh` copied verbatim from flagship's (Debian 13 arm64,
+ `carlos` service user, unattended-upgrades, SSM agent).
+- **No mail.tf, no console, no extra hardening beyond
+ `scripts/harden-host.sh`.** This is a bare platform install, not a
+ flagship mirror — the only tenant app on it, for now, is rastrillo's
+ hello world.
+
+## 4. DNS
+
+Managed directly via the DNSimple API with `~/.dnsimple/carlos.token`
+(account 285, `paul@rslw.com` — the same account and the same
+out-of-tofu-state pattern already used for `platform.carlosframework.com`
+itself). No new domain registration: this reuses the `carlosframework.com`
+zone Paul already owns, scoped under a `dev.` subdomain so it's visibly
+separated from the production names.
+
+- `platform.dev.carlosframework.com` → the dev box's EIP (control-plane
+ surface, mirrors `platform.carlosframework.com`)
+- `*.dev.carlosframework.com` → the dev box's EIP (app hosting, mirrors
+ `*.oncarlos.com`) — rastrillo's hello world lands at
+ `helloworld.dev.carlosframework.com`.
+
+## 5. Deployment sequence
+
+1. Create the tfstate bucket; write `dev/main.tf`, `dev/region-ie.tf`,
+ `dev/host-init.sh`, `dev/outputs.tf`, `dev/README.md` mirroring
+ flagship's (minus `mail.tf`/`keymail.tf`). `tofu init` / `plan` /
+ `apply`.
+2. Create the two DNS records above via the DNSimple API once the EIP
+ exists.
+3. Bootstrap the box over SSM: install the `carlos` agent (mirrors
+ `scripts/bootstrap-box.sh`), apply `scripts/harden-host.sh`.
+4. Generate a **new** release signing key for this deployment (separate
+ from flagship's and Tito's) and stage it the same way
+ (`/carlos/release-key` in this account's SSM).
+5. Build the real `carlos` binary (from `carlosframework/platform`) and
+ rastrillo's `examples/helloworld`; `ship` / `promote` / `add` for real
+ against this account's S3-backed deployment bucket and registry — not
+ the local-directory demo used previously.
+6. Verify: `helloworld.dev.carlosframework.com` serves 200 through the
+ real `carlos edge` with a real Let's Encrypt cert (edge running for
+ real, not `-dev` mode), once DNS has propagated.
+7. Update `platform-infrastructure/README.md` (add the `dev/` root,
+ mirroring the existing flagship/tito bullets) and project memory with
+ the new deployment's state.
+
+## 6. Non-goals for this pass
+
+No console, no mail/SES, no multi-region, no additional CARLOS apps
+beyond rastrillo's hello world (Kass itself stays on the flagship — it is
+not moved here). No change to the flagship or Tito deployments or their
+tofu state. No root-email change on the kass account — Paul owns that,
+separately.