carlos / platform Public

docs: pi-enablement review fixes — limiter cost, edge add step, runbook concrete values, module index

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell c7ec608473120f76647b69425488b006a5a09583 parent eff8f6e
4 files changed, +50 −8
  • infra/dev/region-pi.md +14 −2
  • infra/modules/README.md +19 −0
  • infra/remote-host.md +6 −2
  • scripts/seed-pi-demo.sh +11 −4
diff --git a/infra/dev/region-pi.md b/infra/dev/region-pi.md
index 51515b3ac..e32af707e 100644
--- a/infra/dev/region-pi.md
+++ b/infra/dev/region-pi.md
@@ -16,7 +16,7 @@ Follow infra/remote-host.md with these dev-platform values:
source = "git::https://github.com/carlosframework/platform.git//infra/modules/region-remote-host"
region_code = "pi"
data_bucket_name = "carlos-dev-pi-640012953448"
- deployment_bucket_arn = <dev deployment bucket ARN>
+ deployment_bucket_arn = "arn:aws:s3:::carlos-dev-640012953448"
}
Apply from the platform-infrastructure checkout (operator step — the
root module is not in this repo).
@@ -37,7 +37,19 @@ Follow infra/remote-host.md with these dev-platform values:
shows UNREACHABLE in the fleet view and `carlos status -live`; instances
resume when it re-dials. This is the approved demo posture.
-Seeding: scripts/seed-pi-demo.sh (batches of ≤10/day — console limiter).
+Seeding: scripts/seed-pi-demo.sh (batches of ≤10/day — console limiter;
+re-running an already-seeded batch is safe but not free, since the limiter
+counts attempts, not successes, so only re-run a batch that actually
+failed). Requires:
+
+- `CARLOS_PI_TUNNEL_NAME=pi-box` — the same channel name set as
+ `CARLOS_TUNNEL_NAME` on the Pi and matched in the dev edge's
+ `CARLOS_TUNNEL_CLIENTS=pi-box=<token>` entry above.
+- A carlos CLI build carrying PR #52's `apps create` verb — seeding is
+ blocked until #52 merges and a release ships.
+- App hostnames on dev resolve as `<app>.dev.carlosframework.com` — that's
+ what the script's echoed `<hostname-of-app>` means.
+
Target: ≥5 resident + ≥50 parked.
## Demo acceptance (run these, tick them)
diff --git a/infra/modules/README.md b/infra/modules/README.md
index 245ee36a9..4fecbcbda 100644
--- a/infra/modules/README.md
+++ b/infra/modules/README.md
@@ -78,6 +78,25 @@ only the fleet, with *no* bucket or parameter grants; statelessness is
imposed, not promised). Generalise it only when a second deployment
wants one.
+## region-remote-host
+
+What an off-cloud CARLOS host (a Raspberry Pi today, tito's hq box later)
+needs from AWS when there is no EC2 instance profile to lean on: a region
+data bucket plus a scoped IAM user + access key, limited to exactly the
+deployment bucket and this region's data bucket — the same
+wrong-region-fails-at-IAM residency property `region-host` gives cloud
+hosts. Two consumers: the dev Raspberry Pi (`region_code = "pi"`) and
+tito's hq box (`region_code = "hq"`, later); the module is reusable as-is
+for both.
+
+| Variable | Description |
+|---|---|
+| `region_code` | Short region code this host serves (e.g. `pi`, `hq`). |
+| `data_bucket_name` | Name of this region's data bucket (created here). |
+| `deployment_bucket_arn` | ARN of the existing deployment bucket the host reads releases/status from and writes heartbeats to. |
+
+Outputs: `bucket_name`, `access_key_id`, `secret_access_key` (sensitive).
+
## Self-hosting from your own repo
A minimal root module — backend + providers + the two module blocks + a
diff --git a/infra/remote-host.md b/infra/remote-host.md
index 9782cfdb4..7c02f1dc1 100644
--- a/infra/remote-host.md
+++ b/infra/remote-host.md
@@ -63,8 +63,10 @@ Set in the edge box's `host.env`:
name in `CARLOS_TUNNEL_CLIENTS` must match `^[a-z0-9-]{1,32}$` or the edge
refuses to boot.
-Back routes to a tunneled host with:
+`carlos route` repoints an EXISTING route — it does not create one. Add the
+route first, then back it with the tunnel channel:
+ carlos add <h>
carlos route -host <h> -tunnel <name>
## Security note
@@ -92,4 +94,6 @@ never point `CARLOS_TUNNEL_URL` at an HTTP edge outside a dev sandbox.
## Related
The hq PHYSICAL half (racking, power, network uplink for a region-hq box)
-lands separately in `infra/tito/region-hq.md`.
+lands separately in `infra/tito/region-hq.md`. For the dev-platform Pi
+instantiation of this runbook (concrete values, seeding), see
+`infra/dev/region-pi.md`.
diff --git a/scripts/seed-pi-demo.sh b/scripts/seed-pi-demo.sh
index ad5eb0b5d..a46503622 100755
--- a/scripts/seed-pi-demo.sh
+++ b/scripts/seed-pi-demo.sh
@@ -6,9 +6,14 @@
#
# The console API's app-create limiter is 10/address/day, so run this in
# daily batches: seed-pi-demo.sh <start-index> <count>. State is the dev
-# platform itself — re-running an already-claimed index is a no-op: `carlos
-# apps create` refuses a taken name with "that name is taken" (HTTP 409),
-# and this script treats that refusal as success rather than a fresh error.
+# platform itself — re-running an already-claimed index is SAFE (it will
+# not double-create), but it is NOT free: the limiter counts attempts, not
+# successes, and is checked before the claim (internal/console/authcli.go),
+# so every `exists:` line still spends one of the day's 10. Only re-run a
+# batch that actually failed — don't re-run a batch that already succeeded
+# just to double-check it. `carlos apps create` refuses a taken name with
+# "that name is taken" (HTTP 409), and this script treats that refusal as
+# success rather than a fresh error.
#
# Requires a carlos CLI build carrying PR #52's `apps create` verb (API
# mode ONLY — sign in first with `carlos auth login -console <url>`; direct
@@ -40,7 +45,9 @@ for i in $(seq "$START" $((START + COUNT - 1))); do
done
echo
-echo "Next, on the DEV EDGE box, back each new hostname with the Pi channel:"
+echo "Next, on the DEV EDGE box, add the route then back it with the Pi channel"
+echo "(carlos route repoints an EXISTING route — it does not create one):"
+echo " carlos add <hostname-of-app>"
echo " carlos route -host <hostname-of-app> -tunnel ${TUNNEL_NAME}"
echo "and on the PI, add the matching local routes (carlos add / adopt as usual)."
echo "First 5 apps stay resident (no hibernate flag); the rest get the"