eleven / messenger Public

deploy: ops canary defaults to the dev mesh (Helsinki), prod becomes the exception (#1265)

Paul, 2026-07-22: throwaway per-session canaries don't belong on the box
real members live on. Default box/domain flip to elevendev-fi /
fi.dev.11ch.at (amd64, matching build-linux.sh); LCHAT_CANARY_BOX=elevenbox
LCHAT_CANARY_DOMAIN=11ch.at is the deliberate prod exception. Script header
documents the ssh alias and the per-host-cert budget caveat (no wildcard on
dev by design); CLAUDE.md prose updated to match.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 5bfbec96188480ab6174bd102be25068441c6357 parent 9026acc
3 files changed, +30 −11
  • CLAUDE.md +12 −6
  • deploy/ops +1 −1
  • deploy/ops-canary.sh +17 −4
diff --git a/CLAUDE.md b/CLAUDE.md
index 61ddd6a..45abca0 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -634,12 +634,18 @@ Principles that hold regardless of environment:
shell. Every operator SSH session gets a public why-entry in the status
ledger (`web/status/ssh/`). Recipe: `docs/instance-router.md ยง Hardening`.
-### ๐Ÿค– Per-session canaries (test-*.11ch.at)
-
-Instances are disposable โ€” wildcard DNS **and** a wildcard TLS cert cover
-`*.11ch.at`, so creating one needs no DNS step, no cert wait, and burns no
-rate limit. So instead of sharing one `test` instance across parallel
-sessions (they trample each other):
+### ๐Ÿค– Per-session canaries (test-*.fi.dev.11ch.at)
+
+Instances are disposable โ€” wildcard DNS covers the canary domains, so
+creating one needs no DNS step. **Canaries live on the dev mesh by default**
+(Paul, 2026-07-22): throwaway test instances don't belong on the box real
+members live on, and they'd eat its instance cap. The default is the
+Helsinki dev box (`fi.dev.11ch.at` โ€” amd64, matching `build-linux.sh`);
+targeting production (`LCHAT_CANARY_BOX=elevenbox LCHAT_CANARY_DOMAIN=11ch.at`)
+is a deliberate, stated exception. One dev caveat: no wildcard cert there by
+design, so each dev canary burns a per-host HTTP-01 cert from the shared
+50/week 11ch.at budget โ€” fine at canary cadence. So instead of sharing one
+`test` instance across parallel sessions (they trample each other):
The encoded path is `./deploy/ops canary create|deploy|destroy <slug>` โ€”
each verb enforces the rules below, so prefer it over hand-run `lchat`
diff --git a/deploy/ops b/deploy/ops
index 85cf7f0..6edc882 100755
--- a/deploy/ops
+++ b/deploy/ops
@@ -39,7 +39,7 @@ ledger; `ops ledger` drafts it.
Env overrides (defaults live in the verb scripts):
LCHAT_BOXES fleet box ssh aliases (doctor, ship)
- LCHAT_CANARY_BOX the router box canaries live on
+ LCHAT_CANARY_BOX the box canaries live on (default: the dev mesh; prod is the deliberate exception)
LCHAT_RELEASES_REPO the public releases repo
No verb for your task? EXTEND ops โ€” a new verb or flag in a small PR
diff --git a/deploy/ops-canary.sh b/deploy/ops-canary.sh
index 1ebbfe6..5f0ed03 100755
--- a/deploy/ops-canary.sh
+++ b/deploy/ops-canary.sh
@@ -29,10 +29,23 @@ set -eu
here="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
root="$(CDPATH= cd -- "$here/.." && pwd)"
-# The router box canaries live on โ€” an ssh alias; user/hostname come from
-# ~/.ssh/config over WireGuard (box specifics in CLAUDE.local.md).
-BOX="${LCHAT_CANARY_BOX:-${LCHAT_BOX:-elevenbox}}"
-DOMAIN="${LCHAT_CANARY_DOMAIN:-11ch.at}"
+# The box canaries live on โ€” an ssh alias; user/hostname come from
+# ~/.ssh/config (box specifics in CLAUDE.local.md). Canaries live on the DEV
+# MESH by default (Paul, 2026-07-22): throwaway test instances don't belong on
+# the box real members live on, and they'd eat its instance cap. Helsinki is
+# the dev default because build-linux.sh emits amd64 (Dublin is arm64). Alias
+# to add once per machine:
+# Host elevendev-fi
+# HostName 157.180.123.183
+# User root
+# IdentityFile ~/.ssh/eleven-dev-box
+# Prod (LCHAT_CANARY_BOX=elevenbox LCHAT_CANARY_DOMAIN=11ch.at) is the
+# deliberate exception, not the default.
+# NB dev has no wildcard cert BY DESIGN (the DNSimple token never goes on a
+# dev box), so each dev canary host burns one per-host HTTP-01 cert from the
+# shared 50/week 11ch.at LE budget โ€” fine at canary cadence, not for bursts.
+BOX="${LCHAT_CANARY_BOX:-elevendev-fi}"
+DOMAIN="${LCHAT_CANARY_DOMAIN:-fi.dev.11ch.at}"
LCHAT=/opt/lchat/lchat
usage() {