How I Built
The Newsletter OS
in Two Weeks
A Portfolio Executive's walkthrough of the pipeline that takes my work-product (build logs, KB digests, podcast transcripts), runs it through a voice-lint and an editor-prompt, and ships a Leverage Brief issue to beehiiv plus three syndication destinations — on a fixed Tuesday cadence, Shabbat-safe.
Yuri Kruman
Author of The Leverage Brief · Jun 2026
push to ship across 4 platforms
syndication destinations
human edit time per issue
to fully automated pipeline
The 30-Second Version
The Automated Newsletter OS is the pipeline behind The Leverage Brief. Sources come from a single inbox (build logs, KB digests, podcast transcripts, tweets). An editor prompt picks the anchor + 3 satellites. A voice-lint hard-fails on em dashes, Oxford commas and 18 banned AI phrases. The composer produces beehiiv-ready HTML, a LinkedIn long-form, a Substack mirror and 5 tweets. Tuesday 06:00 ET, automatic. Friday and Saturday: dead in the schedule by design.
The Problem
Founders who ship a great newsletter for 6 issues then go silent because the marginal cost of issue 7 broke them.
The Stack
Node + Claude API + voice-rules.js + beehiiv API + LinkedIn API + Buffer + Plausible.
What It Doesn't Need
No n8n. No Zapier. No CMS. No "AI ghostwriter." No human pre-editor.
Build Time
Two weeks: one for the pipeline, one for voice-lint and syndication.
If you are an expert who has ever shipped 6 newsletter issues and gone silent on issue 7, this build log is for you. The marginal cost of issue 7 is the entire game. Cut it and the newsletter ships forever.
Why Automation, and Why Two Weeks In
I shipped the first 6 issues of The Leverage Brief manually. They took 4-6 hours each. By issue 7 my brain priced the next edition at "skip this week." By issue 9 the newsletter was dead. I had seen exactly this pattern in 30+ executive newsletters I had subscribed to. The reason is always the same:
4-6 hrs
per issue at issue 1, manually
~85%
of that time was source gathering and reformatting, not writing
3 places
to syndicate each issue (LinkedIn, X, Substack mirror)
~6-9
issues before most expert newsletters die
What I refused to do was hire a ghostwriter. The voice is the product. Hand the voice to someone else and within four issues subscribers can tell. Voice is what makes a newsletter compound; ghosted newsletters peak fast and decay faster.
- 1Automate the source aggregation, not the writing. 85% of the pain was finding and shaping inputs.
- 2Use Claude as an editor, not an author. The model proposes the anchor + 3 satellites; I make every final word call.
- 3The voice-lint is the immune system. Em dashes, Oxford commas and 18 AI tells hard-fail the build.
The voice-lint runs BEFORE Claude generates, AFTER Claude generates, and again before publish.
It's both a prompt constraint and a post-generation gate. Hard fail on Oxford comma. Hard fail on em dash. Hard fail on banned phrases. Soft warn on weaker tells. Run on every output, every time. The lint is what makes "automated" compatible with "still sounds like me."
The Stack (and Why Each Piece)
Click each layer for the reasoning.
Source
Single inbox folder
Everything pours into newsletter-os/inbox/. Build logs, KB digests, podcast transcripts, tweets, my own scratch markdown. Every file has frontmatter {source, date, weight, tags}. The pipeline reads inbox once per issue.
Editor
Claude Sonnet (prompt-cached brand voice)
Sonnet, not Opus. The editor's job is selection + structure, not original prose. Brand-voice doc is prompt-cached every call (5-min TTL). Cheap, fast, consistent.
Voice Lint
voice-rules.js (hard + soft)
Hard fail: em dash (U+2014), Oxford comma pattern, the 18 banned AI phrases (delve, tapestry, in today's landscape, leverage synergies, etc.). Soft warn: weaker tells. Hard fails auto-regen with stricter prompt; second fail halts and surfaces.
Publishing
beehiiv API + LinkedIn API + Buffer
beehiiv is the canonical home. LinkedIn long-form goes out via their post API. Tweets queue to Buffer. Substack mirror posted via web automation since they have no native API. Every destination publishes within 30 minutes of beehiiv.
Cadence
Tue 06:00 ET, Shabbat-safe
Tuesday is the inbox-friendliest day per beehiiv data. 06:00 ET catches both coasts on commute. Pipeline runs Sunday 21:00 IDT (after Shabbat) for human review, then auto-ships Tuesday morning. Friday-Saturday: the pipeline does not run.
Feedback Loop
Plausible + beehiiv stats → weight
Open rate, click rate per CTA, LinkedIn impression and tweet engagement all flow back into stats.json. The editor prompt reads the last 4 issues' performance, biases the next anchor toward what worked.
The Six-Phase Build Sequence
Each phase is ~1-3 days. Sequence in order. The voice-lint MUST exist before the editor prompt; otherwise you spend the next week pulling em dashes out by hand.
The Inbox + Frontmatter Contract
Every potential source goes into newsletter-os/inbox/YYYY-MM-DD-slug.md with frontmatter. The pipeline only reads files with frontmatter. If you don't tag it, the editor doesn't see it.
--- source: build_log # build_log | kb_digest | podcast | tweet | scratch date: 2026-06-08 weight: 8 # 1-10, editor uses this as a prior tags: [duedrill, stripe, payments] hook: "Stripe org-key Context header silently breaks every checkout" --- Stripe organization-scoped API keys require the Stripe-Context header on every call. The error text says "Please include the Stripe-Context header" with no mention of WHY...
The hook field is doing 80% of the work. Write the one-line tease at the moment you drop the file in inbox, not three days later. You'll remember why the story matters now; you won't on Sunday.
What I'd Do Differently Today
Write the voice-lint on day one, ship it before the editor prompt
I shipped the editor first. The first three issues had em dashes in production. Wire the lint module first; everything else is a consumer of it.
Skip Substack entirely. Pour energy into LinkedIn.
Substack mirror brought ~3% of new subs. The Playwright automation cost a day. LinkedIn brought 60%. I'd kill Substack and use that day on LinkedIn comment outreach.
Don't let the editor write “why_this_week.” Make me do it.
The editor's why_this_week field was a quiet ghostwriting vector. Now I write that line myself; the editor only picks the slug.
Treat the inbox as the product
Newsletter quality is downstream of inbox quality. Build a habit of dropping 3-5 frontmatter-tagged files into inbox/ every day. The pipeline does the rest.
Adapt This for YOUR Publication
The architecture (inbox → lint → editor → renders → publish → loop) is the template for any expert-led recurring publication. Five adaptations off the same skeleton:
| Publication | Inbox Sources | Renders | Cadence |
|---|---|---|---|
| VC weekly memo | Deal notes, partner calls, market data | LP letter, X thread | Mon 08:00 ET |
| Nonprofit donor brief | Program updates, donor stories | Email, mail letter, board pack | Quarterly |
| Sales leader weekly | Pipeline notes, win calls | LinkedIn, Slack, podcast | Fri 16:00 PT |
| Pastor weekly devotional | Sermon notes, parishioner Q&A | Email, podcast, YouTube short | Sun 18:00 local |
| The Leverage Brief | Build logs, KB digests, podcast | beehiiv, LinkedIn, Substack, 5 tweets | Tue 06:00 ET |
Starter Prompts for Claude / Cursor
If you want your publication automated by next week, these four prompts get you there.
"Write lib/voice-rules.js exporting lint(text) returning {ok, violations}. Hard fails (regex array): [LIST YOUR PHRASES, syntax patterns, brand tells]. Soft warns (separate array): [WEAKER TELLS]. Export tryRetryPrompt(violations) that builds a stricter-prompt rider quoting the violated rule names back. Include 12+ Vitest tests covering hits and misses."
"Write the system prompt for a Claude Sonnet editor that, given a folder of frontmattered inbox files, picks: (1) ONE anchor story biased toward weight ≥ 7 and themes that performed in the last 4 issues, (2) THREE satellites with distinct angles, (3) ONE question of the week. Output JSON only. Voice rules: NO Oxford commas, NO em dashes, NO [YOUR BANNED PHRASES]. Editor DOES NOT write prose. Editor DOES NOT quote source text. Editor returns structure only."
"Write scripts/render.mjs that takes my prose markdown + the editor's JSON outline + the inbox files and produces 4 outputs: (a) beehiiv-ready HTML with their callout components and Plausible UTMs, (b) LinkedIn long-form ~600 words anchored on the lead story with a CTA at end, (c) Substack mirror full markdown, (d) 5 tweets (1 anchor, 3 satellites, 1 CTA) under 280 chars each. Run voice-lint on each output. Hard fail blocks the publish; soft warn logs and continues."
"Write scripts/publish.mjs that: (a) POSTs the beehiiv HTML to /v2/publications/{id}/posts with status=scheduled, send_at=Tue 06:00 ET, (b) queues the LinkedIn long-form into a SQLite job table to fire Tue 06:30 via the LinkedIn personal-profile post API, (c) creates a Substack draft via a Playwright-driven login flow, (d) batches 5 tweets to Buffer's queue API spaced Tue/Wed/Thu/Fri. Each platform's call is wrapped in retry-on-5xx and surfaces a structured failure to me on hard error."
What the Newsletter OS Is Not
It is not a ghostwriter. It does not generate the prose. It is not a content farm; the inbox is curated, not scraped. It does not replace beehiiv, LinkedIn, Substack or Buffer; it orchestrates them.
What it is: a marginal-cost crusher. It takes the cost of shipping issue 7 from "four hours I don't have" to "forty-five minutes of writing prose I want to write anyway." The narrowness is the point. Newsletters die because issue 7 is expensive. Cut issue 7's cost and the publication compounds.
The question is not
"can AI write my newsletter?"
The question is:
"What is the marginal cost of MY issue 7, and what would it take to cut that cost by 80% without giving up the voice?"
Answer that in one sentence and you have a pipeline outline. The next two weeks are the lint, the editor and the four renders. Then it ships for years.
This walkthrough is part of the Portfolio Leverage Co. Build Bench series. For the cohort where we build these together, apply here.
