travismetcalf.com · patterns
The rules this platform is built by — each one a real decision made once, applied everywhere, and written down with its reasoning. An undisturbed date is a decision that has held; when one changes it is superseded in place with a successor, never silently rewritten. This is the public edition: patterns as ideas. The full operating reference — hostnames, ports, runbooks, the gotchas — lives behind SSO.
All decisions reviewed & current as of 2026-08-04Security
Public traffic reaches the lab through a managed CDN + WAF (AWS CloudFront), then an encrypted tunnel (Tailscale) to a reverse proxy (Caddy), with single sign-on + MFA (authentik) in front of every app. Two rules make the chain honest:
Convenience surfaces on the home network are read-only by design — mutating routes answer with a redirect to the authenticated public URL. "Ungated reads" must never quietly become "ungated writes."
Operations
Every project ships the same skeleton: a git repo with an
.env.example, containerized runtime, a scheduled smoke test
that exercises real behavior, a success-marker the monitoring can check,
and email alerts through one shared notifier library. A weekly summary
job re-runs every project's checks and sends a single heartbeat.
Liveness checks miss whole failure classes. The fleet is watched on four axes: is it running; is its output right; does the deployed state match git and the pinned images; and is a healthy service quietly burning resources. That last axis exists because a container once burned two cores for five days while every green check stayed green — measured properly, lifetime-average CPU separates "busy" from "stuck" where a snapshot is a coin flip.
Edit on the laptop, push, pull on the server, restart if needed. No CI
pipeline to babysit for a one-person platform — but drift checks verify
the deployed state matches the remote, so the simple path stays honest.
Static sites (including this one) deploy by git pull alone.
Nightly snapshots of runtime data to network storage with 30-day retention — and restore tests, because a backup that's never been restored is a hope, not a backup.
AI
AI isn't a demo on this platform; it's on the payroll. Models score the intelligence reader's stories in production, local models handle what should never leave the house, and an AI engineering partner helps build and operate the platform itself — including this site.
The leverage is only safe because the guardrails don't care who's working: every agent spends from its own budgeted key at the gateway, every change lands through git and the same drift checks, and nothing AI-made skips the smoke tests. Trust the output because the system verifies it, not because the model sounded confident.
Design & frontend
Brand values live in one namespaced CSS custom-property file; each app maps them onto its own variables through a thin adapter and vendors a copy at deploy time. Plain CSS custom properties are the only layer low enough to skin a React app, server-rendered Python templates, a themed third-party app, and (via generated constants) a native iOS build from the same source. The styleguide renders from the live values, so it cannot drift.
Content and document sites are static HTML consuming the tokens — no
build step, nothing to operate for a decade. Interactive app frontends
default to Next.js + TypeScript + Tailwind (v4's @theme maps
the custom-property tokens cleanly). Existing apps are not
retrofitted: operational simplicity outranks framework uniformity, and a
read-mostly dashboard doesn't need a Node build chain.