I don't just build one application at a time - I run a real engineering platform underneath all of them: the same CI/CD discipline, the same production host, the same GPU inference setup, and reusable code I built once and use everywhere. Tourney, Runway, and GetSeen are the proof, not the point.
I put every deploy through the same five gates: a secrets scan, the full automated test suite, lint, security-lint, and a dependency audit - all before anything reaches a live environment. I wired it so a commit to main auto-promotes to system integration the instant those gates go green, and I keep production promotion a deliberate, separate step - never automatic, never skipped.
Promotion itself is one deliberate action, not a form to fill out: Actions tab → "Promote to prod" → Run workflow (or gh workflow run promote-to-prod.yml), defaulting to SIT's current tip. That single trigger verifies every gate is green, fast-forwards the prod branch to that exact commit, kicks off the real deploy, and confirms the live app answers healthy - I did this for real on Runway's first production promotion, and hit (then fixed) a genuine gap along the way: a GitHub-token push doesn't cascade into another workflow run, so the promotion step has to explicitly trigger the deploy rather than assume the branch move alone will do it - the same fix Tourney's own pipeline already had, discovered the same way, on its first promotion too.
I host multiple live applications on one AWS EC2 box, side by side, behind one nginx - I didn't stand up a second server for the second app; I added a container and one nginx config file, and nothing already running had to change. I did this myself tonight, live: added a new app to an existing production box, got it its own TLS certificate, and verified the existing app never went down.
I run a dedicated NVIDIA DGX Spark - physical, owned GPU hardware - serving self-hosted, open-weight models through Ollama, and I put every AI workload through both that and a frontier model (Claude) before deciding which one runs it in production. That's a real cost/quality tradeoff I make deliberately, not a default I never revisited.
When I hit the same problem in a second application, I don't solve it twice - I extract what I built the first time into its own package and reuse it.
I generalized a job-queue, tool-using model loop I originally built for one app into a portable package any app can drop in - the queue, the tool registry, and the security boundary between an app and a worker it doesn't fully trust.
I built document ingestion, chunking, embedding, retrieval, and citation enforcement once, as a standalone package - pointing it at a different document set is the only thing that changes between applications.
I extracted the client that talks to my self-hosted GPU box - the HTTP polling loop, the claim logic, the usage tracking - so every app that needs the Spark reuses the same battle-tested code instead of its own copy.
Every app I run has exactly one supported way to start it in development - never a bare command I have to remember the right flags for.