ct.prod is a SHARED DMZ (Prospector's apps.ftw.pw + macsync). The old edge
script overwrote /etc/caddy/Caddyfile wholesale, so it and Prospector's deploy
clobbered each other (an outage: a Prospector deploy dropped the macsync site
and repointed DNS). Now each service owns one /etc/caddy/conf.d/<svc>.caddy and
the main Caddyfile just `import conf.d/*.caddy`. deploy-edge.sh idempotently adds
the import, removes any legacy inline macsync block, writes conf.d/macsync.caddy,
validates, and hot-reloads — never touching other sites.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
deploy-edge.sh reproducibly configures macsync's public edge on ct.prod (Caddy
-> macsync 10.20.0.5:3201 over the VPC), so a ct.prod rebuild restores it (it was
hand-configured during cut-over). docs/DEPLOY.md documents the two-box DMZ/internal
topology, one-command deploys, rebuild recovery, secrets model, security posture,
and how to run the tests. Verified: edge returns 200.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Captures the working DO-native deployment so a terraform rebuild (which wipes
the manual install) is recovered with one command: installs runtime (bun/redis/
caddy), syncs code, pushes secrets OVER SSH (never in cloud-init user-data — that
is metadata-readable, per the gpu.sh finding), wires the systemd unit + Caddy TLS
edge, verifies health. Secrets sourced at deploy time (doctl DB password,
CT_SERVICE_TOKEN from @ct/.env.local, Spaces keys from vault) — none hardcoded.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- logger: emit straight to fd 1/2 (unbuffered). The buffered process.std*
streams block-buffer to a pipe under systemd, so low-volume logs never
flushed and were invisible.
- /client/imessage/contacts: return 401 (like /sync/batch) when the caller
presents the operator/service token instead of a device token, instead of
500ing on a null deviceId downstream.
- systemd unit: reflect the working deploy (root + /root/.bun, Redis
dependency, file logging since the droplet journald is volatile).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Homebrew's rclone is compiled without 'mount' support on macOS. Resolve a
mount-capable binary ($HOME/bin/rclone, official rclone.org build) and fail
fast with install guidance if none is found. brew rclone still serves plain
transfers via spaces-env.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generalize the photos-originals rclone-mount pattern to a video-projects
prefix so the video studio (and imajin ETL, per storage-portability-plan
§2.3) can read/write multi-GB project sources/renders as local files while
only hot data stays resident on plum (bounded VFS LRU cache). Lets a
small-disk laptop work with large footage without filling APFS.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>