Add blog section (4 draft posts) and social post drafts for /platform funnel

Continues the content-engine plan: /platform, the homepage link, and the
small-business-infrastructure course are already live. This adds the
remaining pieces — a content/blog/ section with 4 long-form posts (kept
draft:true, so nothing goes live until reviewed) and a committed set of
~12 ready-to-copy social posts in drafts/social-posts.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 12:33:28 -04:00
parent e967ddccbc
commit 0bdf2b982b
6 changed files with 495 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
---
title: "Blog"
description: "Notes on running production infrastructure for small businesses, one honest mistake at a time."
---
@@ -0,0 +1,73 @@
---
title: "How I Run Infrastructure for Five Small Businesses From One Server"
date: 2026-08-14
draft: true
description: "A full walkthrough of the hub-and-spoke setup behind five real small businesses — what's shared, what's scoped per brand, and why that split is the whole point."
---
Right now, one hub server runs the entire technical backend for five real
small businesses. An author's site. A short-fiction writer's site. A
small-batch soap shop. A literary press running open submissions. A small
press with multiple authors. Different industries, different products,
different customers — same infrastructure underneath, run by one person.
This is the long version of the story I tell on [/platform](/platform/).
Here's what "one hub, five brands" actually looks like, mechanically.
## What's on the hub
One server runs:
- Mail for every domain — inbound and outbound, for every business, from one
mail platform instead of five.
- The CI/CD pipeline that builds and ships every site, on every push to its
own repo.
- The email courses and campaigns that go out under each business's own
name and voice, from a shared engine that just happens to run five times.
- A shared Postgres database, holding each business's data in its own scope.
- The checkout and fulfillment system behind every book and product sale.
- Continuous monitoring watching all of it, all the time, instead of five
separate someones checking in occasionally.
Each of those five businesses would otherwise need to find, pay for, and
separately manage their own version of every single one of those pieces —
their own email platform, their own checkout stack, their own hosting
provider, their own monitoring. Here, it's one system, config-scoped per
brand, watched by one person the whole time.
## What "config-scoped" actually means
This isn't five businesses crammed into one undifferentiated system hoping
nothing collides. Each business's site, mailing list, and checkout
configuration are separate, brand-specific settings layered on top of the
same underlying engine — not separate codebases someone has to keep in sync
by hand.
When a real fix is needed — a security patch, a new feature, a bug fix — it
gets written once, verified once, and it's live for every business
immediately. When something is client-specific — their branding, their
content, their pricing — it lives in that client's own configuration, and
nowhere else.
That split is the entire value proposition: shared reliability, individual
identity.
## The part that actually makes this safe
None of the above works if a routine, one-line change to one business's site
could somehow reach into another's, or if "shared server" quietly meant
"shared risk." The thing that makes consolidation safe isn't which machine
everything runs on — it's how tightly every path between the pieces is
scoped. That's a big enough topic on its own that it gets [its own
post](/blog/guardrails-for-running-production-alone/).
## Is this the right shape for your business?
If you're currently paying for and separately managing a stack of vendors —
a hosting provider, an email platform, a checkout processor, a project
tool — that have never heard of each other, this is what the alternative
looks like in practice: one coherent system, run by someone personally
accountable for how the pieces fit together.
If that's where you are, the [5-day email course on /platform](/platform/)
walks through why this approach holds up, one honest mistake at a time.
@@ -0,0 +1,83 @@
---
title: "The Guardrails That Let One Person Safely Run Production Email for Five Businesses"
date: 2026-08-14
draft: true
description: "What actually happens when you're not around and something breaks — the specific, boring mechanisms that make one-person-run infrastructure safe."
---
The honest question anyone should ask before trusting one person with their
technical backend is: what happens when you're not around and something
breaks? Not "do you have good intentions" — systems don't run on intentions.
Here are the specific, unglamorous mechanisms that make it safe, today, in
production, for five real businesses.
## A routine push can never trigger a real send
Every campaign content repo I run has the same rule built into the tooling
itself, not just into a process someone has to remember: pushing content
changes can only ever produce a *draft* campaign. There's no field, no flag,
no config value that lets a routine content push schedule or trigger an
actual send to real subscribers.
Sending for real requires a separate, deliberate command — normally
triggered by pushing a dedicated `send/<slug>` tag, not a content commit.
If the worst outcome of a typo'd push is "an unsent draft appeared,"
the failure mode is designed correctly.
## Storage that's supposed to be private can't quietly go public
Every object storage bucket I run defaults to private. There's an automated
check in CI that fails the build if a change would make one publicly
listable — unless there's a deliberate, documented comment explaining
exactly why, right next to the code making the change. Not a wiki policy
somewhere. A build that won't go green until you either fix it or justify it
in writing.
## One business's access can't reach another's
Each site I run has its own deploy key, and each key is scoped so narrowly
it can only touch that one site's own files — nothing else on the server, no
other business's credentials or data. If one site's repo were ever
compromised, the blast radius stops at that one site.
This is worth being specific about, because "shared server" and "shared
risk" get conflated constantly. The thing that actually determines whether
one business's problem can become another's isn't which physical machine
they're on — it's whether access is properly scoped. You can have that
property, or fail to have it, on a dedicated server or a shared one.
## Anything touching real customer data defaults to "show me," not "do it"
Every ops script that could affect real subscribers — bulk name backfills,
unsubscribes, list edits — defaults to a dry run. Actually writing a change
requires an explicit `--apply` flag, every time, no exceptions. The safe
path is the path of least resistance; the dangerous one takes an extra,
deliberate step.
This isn't hypothetical caution. When one client's mailing list switched to
double opt-in partway through, their earlier import batch — people who'd
already agreed to be on the list through a real prior relationship, just not
yet confirmed in the system — stayed exactly as `unconfirmed`, honestly
reflecting what was actually true about them, instead of getting swept into
a clean-looking but false "confirmed" count. Boring and correct beat clean
and wrong.
## You verify after every step, not just at the end
Moving a production deploy key off a root account isn't safe to do in one
commit if you're doing it carefully. It took three: move the key to a
dedicated account, verify the deploy still works. Fix the account's shell
so the key actually functions, verify again. Remove the old root-level
access, verify a final time. Three commits, three separate verifications —
because "I'm pretty sure that worked" isn't good enough on a production
system running mail for five businesses.
## None of this is exotic
Every mechanism above is the ordinary, unglamorous work of making the
dangerous action harder than the safe one — done once, for the whole
system, instead of relied on per person, per day. That's what "safe to hand
this to someone else" actually means in practice.
Curious how the whole system fits together? Start at
[/platform](/platform/).
@@ -0,0 +1,60 @@
---
title: "Why Small Businesses Don't Need a SaaS Stack"
date: 2026-08-14
draft: true
description: "The real cost of renting a different tool for every job — and what the alternative looks like once you stop assuming it's the only option."
---
Ask most small businesses how their technical backend is put together, and
you'll get some version of the same answer: a checkout processor here, a
storefront platform there, a separate email tool, a separate hosting
provider, maybe a separate project tracker — a different vendor for every
job, each with its own login, its own bill, its own outage schedule, and
none of them aware the others exist.
That's not a personal failing. It's the default path, because every one of
those tools is easy to sign up for individually and hard to evaluate as a
system. Nobody sits down and designs a five-vendor stack on purpose — it
just accumulates, one "we needed this by Friday" decision at a time.
## What that actually costs
The sticker price of each individual tool is rarely the real cost. The real
cost is what happens at the seams: the storefront platform doesn't know
about the email tool's suppression list, so a customer who unsubscribed
from one still gets marketed to by the other. The checkout processor's
receipts don't match the bookkeeping tool's categories, so someone
reconciles them by hand every month. Nobody owns the whole picture, because
no single vendor is responsible for more than their own piece of it.
And when something breaks at a seam — a webhook silently stops firing, a
sync job quietly drops records — there's often no single person whose job
it is to notice, because it's not clearly any one vendor's fault.
## The alternative isn't "bigger," it's "coherent"
The fix for SaaS sprawl usually gets pitched as an enterprise platform —
Salesforce-scale software that can theoretically do everything one tool at
a time was doing. But that trades a pile of small vendors for one giant one,
with all the same seam problems just moved inside a single product's
byzantine configuration, plus an enterprise price tag a small business never
needed.
The actual alternative is smaller than that: one coherent system —
hosting, email, checkout, project tracking — run as one thing by someone
personally accountable for how the pieces fit together, instead of managed
piecemeal across a stack of vendors who've never heard of each other. Not
bigger. Just not fragmented.
That's the whole premise behind the way I run infrastructure for five real
small businesses today — one hub, config-scoped per brand, one person
watching the whole system instead of five partial views of five different
pieces.
## If this sounds like where you are
If your current setup is "it mostly works, but I'm the one reconciling the
seams by hand," it's worth seeing what the non-fragmented version actually
looks like in practice — not in theory, but running, today, for real
businesses. The [5-day email course on /platform](/platform/) walks through
it, one honest mistake at a time.
+56
View File
@@ -0,0 +1,56 @@
---
title: "Template, Don't Fork: How a New Client Goes Live Without Inheriting Anyone Else's History"
date: 2026-08-14
draft: true
description: "Why onboarding a new business starts from a genuinely clean slate — and why that's cheap and low-risk instead of a corner cut."
---
When a new business signs on, the easy shortcut would be to copy an existing
client's site, swap out the branding, and call it done. It's faster to set
up. It's also a quiet liability: that new site inherits the old one's full
git history, whatever secrets or config might have leaked into old commits,
and a codebase shaped by decisions made for a completely different business.
Every new site I bring on instead starts from a template, generated fresh —
not forked, not cloned. Zero inherited commit history. Zero leftover config
from whoever came before. The skeleton — the site structure, the shared
tooling — is identical across every client, because it's the proven,
already-working shape. What diverges from day one is content, branding, and
the client's own secrets, nothing else.
## Why this matters more than it sounds like it should
Onboarding risk is usually invisible until it isn't. A forked repo carries
forward every decision — good or bad — that was ever made in the original
site's history, plus whatever accumulated in there that nobody remembers is
still there. A generated repo carries forward none of that. The new
business gets exactly the current, proven template, with a clean history
that's theirs alone from commit one.
It also means a shared tool can be pinned to a specific, tested version per
client, rolled out deliberately, one business at a time — instead of every
site silently inheriting whatever the "source" repo happened to be running
on the day it was forked.
## What actually diverges between clients
Looking across the five real businesses running on this setup, what's
different from one to the next is narrow and deliberate: their content,
their branding, their pricing, their own credentials for their own mailing
list. What's identical is the skeleton underneath — the site structure, the
shared engines for email and checkout, the deployment pipeline.
That's what makes bringing on a new business cheap and low-risk instead of a
bespoke project every time: there's no "figuring out this client's
infrastructure from scratch." There's a proven shape, and a short list of
things that actually need to be decided for them specifically.
## What this means if you're considering this for your own business
Onboarding you doesn't mean untangling your business from someone else's
history, and it doesn't mean building your infrastructure from a blank
page either. It means slotting your business into a shape that's already
running, safely, for others — with your own data and credentials scoped
to you, and nothing carried over that shouldn't be.
More on how the whole system fits together: [/platform](/platform/).