content-pipeline¶
Weekly, automated: research what the field is actually asking → write an engineering note → derive social posts and a short narrated video → publish at the best time. Requested by Angel 2026-09-11. Site: embeddedera-site · business: embeddedera-business · brand: ../brand/README
Why¶
One note a week is the cheapest durable marketing a shop like this has: each one is a page that answers a real search, a post for every platform, and raw material for a video. Doing it by hand never survives a busy month, so it has to run itself.
Shape (4 stages)¶
- Research (Mon 06:00) — read what people are asking this week in the places our clients and peers actually post, plus vendor obsolescence notices. Pick ONE topic that (a) matches a service we sell, (b) has real questions behind it, (c) we have not already written. Output: a topic brief with sources.
- Write (same run) — a 1,100–1,500 word note in the brand voice, saved to
src/content/notes/<slug>.mdon theapple-stylebranch, committed, pushed, deployed to the dev preview. ntfy to Angel with the preview link. - Approve — Angel reads it and replies "publish" (or edits). Then it is merged to
mainand goes live. Deliberate gate: the notes carry Angel's name and engineering reputation; an unreviewed factual error is expensive and permanent. One tap, not a workflow. - Distribute (on approval) — derive: LinkedIn post, X thread, Instagram caption + carousel text, YouTube/Shorts script; render a 60–90 s narrated video (local TTS + slides + captions); schedule each to its platform's best slot.
Sources for stage 1 (all free, no key unless noted)¶
- Reddit JSON (
/r/<sub>/top.json?t=week): PrintedCircuitBoard, embedded, AskElectronics, ECE, rfelectronics, KiCad, FPGA, diyelectronics. - Hacker News via Algolia API (
hn.algolia.com/api/v1/search_by_date?tags=story). - Stack Exchange API: electronics.stackexchange.com (300 req/day unauthenticated).
- EEVblog forum boards (scrape the recent-topics page).
- Vendor obsolescence/PCN feeds: ST, Microchip, TI, NXP product-change notices.
- Distributor lifecycle flags (Digi-Key API needs a key — optional later).
- Our own inbox: recurring questions from
[EE-requests (already labelled EmbeddedEra/Leads).
Publishing times (B2B, US Eastern — revisit with real analytics after 3 months)¶
| Platform | Slot |
|---|---|
| Site note | Tue 07:00 (gives Google the week to index before the weekend) |
| Tue or Wed 08:00–10:00 | |
| X | Tue–Thu 09:00 and a second post 13:00 |
| Tue–Thu 11:00 or 19:00 | |
| YouTube / Shorts | Thu 15:00 |
| Rule: one note a week, posts staggered across 3 days, never more than one post per platform per day. |
Video (stage 4) — free, local, no subscriptions¶
- TTS: Piper (open source, runs on CPU, good English voices;
en_US-ryan-highor similar). Alternative if a warmer voice is wanted later: a paid API — not free, avoid for now. - Render: ffmpeg. Slides generated from the note's headings (brand colours, JetBrains Mono), plus captions burned in (whisper.cpp for timing, or Piper's own phoneme timings).
- Output: 1080×1920 vertical for Shorts/Reels, 1920×1080 for YouTube.
- Angel's own bench footage (2026-09-19 shoot) becomes the b-roll pool.
Parked¶
- Video (2026-09-11, Angel's call): the narrated-video stage is built and works
(
render-note-video, Piper + PIL + ffmpeg, 48 kHz stereo, brand slides) but Angel does not want video for now. Leave the scripts in place; thevideoblock insocial.jsonis still generated and costs nothing. Revisit after the 2026-09-19 shoot, when real bench footage could carry it.
Visuals: carousel cards, designed in HTML¶
render-cards <social.json> [outdir] [--square] → hook card, one numbered card per point, a
closing card with the URL; 1080x1350 portrait (or --square), plus a combined PDF (LinkedIn
takes a PDF as a swipeable document post, which currently reaches furthest there).
How it works: the design is embeddedera-site-apple/tools/cards/carousel.html — real CSS
with Inter + JetBrains Mono from Google Fonts, a copper radial light, an SVG board-routing
pattern generated per card from a seed, a grain layer, and headline auto-fit measured by the
browser. tools/cards/render-cards.py injects the note's data, waits for fonts, and screenshots
each .card with headless Chromium (~/.local/share/shots-venv, Chromium in ~/.cache/ms-playwright).
About 6 seconds for a six-card set. To iterate on the design, open carousel.html?demo=1 in a
browser — it renders with demo data, no build step.
Why not Canva: the Connect API's autofill (fill a brand template from data and export) requires a Canva Enterprise organisation; paid plans get only a development trial. Free/Pro accounts can upload assets and export, but not the automation we need. Canva stays a fine manual tool for Angel if he wants one; it is not an automation target. Checked 2026-09-11 against canva.dev docs.
Superseded: render-note-carousel (the PIL version) still exists but is no longer called.
Diagrams in notes¶
render-diagram <data.json> <out.webp> and npm run diagrams (wired into npm run build).
Design: embeddedera-site-apple/tools/cards/diagram.html, four types — decision (tree with
labelled branches), process (numbered strip), compare (columns), stack (layers) — at wide
1600x900, square or tall. Definitions live in src/content/notes/_diagrams/<slug>/<name>.json,
output to public/notes/<slug>/<name>.webp, re-rendered only when the JSON is newer.
WebP, not PNG: a flat dark 3200x1800 diagram is ~2.2 MB as PNG and ~130 KB as WebP with no
visible loss. The notes keep their 99/100 performance score. render-diagram writes a PNG too if
the output path ends in .png.
Two diagrams shipped in the EOL note (decision tree + qualifying process).
Card types¶
render-card <data.json> <out.webp> → tools/cards/cards.html, one card per run, 1080x1350
(or square, or wide 1200x675 for link images). Types: quote (pulled sentence + role-only
attribution), spec (2–6 big figures with labels), myth (MYTH / ACTUALLY), photo (full-bleed
image + heavy scrim + headline). Samples and their JSON: ~/embeddedera-content/_samples/.
Photo rule learned 2026-09-11: the scrim had to be doubled to stay readable over a cluttered bench photo, and the sample shot shows third-party equipment brand names on screens and printers — the brand rule forbids naming equipment, so shots for publication must avoid legible brands. Add that to the 2026-09-19 shoot list: angle away from brand plates, or cover them.
Quote follow-ups¶
quote-drafts now runs two passes: new requests, then stalled threads — a warm nudge at 3–5 days
of client silence, a graceful close-out at 10–14, hard cap of two per thread ever, skips anyone
who declined or already replied. Still draft-only; send/reply/forward stay disallowed in the
wrapper. The follow-up branch has not yet run against a real aged thread — watch the first one.
Status¶
- 2026-09-11: notes section live on the site; first note published (microcontroller EOL).
- 2026-09-11: Stages 1+2 built.
~/.claude/routines/weekly-research.md(prompt) +~/.local/bin/weekly-research(wrapper), cron0 6 * * 1. The model only researches and writes ONE markdown file; the wrapper does git, build, deploy and ntfy, so a bad run cannot publish. Gates before commit: ≥700 words, frontmatter present, no standards claims, no prices, no banned words, site must build. Topic backlog at~/.claude/routines/note-backlog.md; it reads the existing note titles so it never repeats one. Lands on the DEV preview; Angel says "publish the note" to promote. - 2026-09-11: Stage 4a+4c built.
note-to-social <slug>→~/embeddedera-content/<slug>/withsocial.json,posts.txt(copy-paste ready, each piece labelled with its posting slot) and two MP4s. Prompt~/.claude/routines/note-to-social.md; validation in the wrapper rejects prices, standards claims, banned words, over-length X posts.render-note-video <social.json>does the video: Piper voiceen_US-ryan-high(~/.local/share/piper-venv, voices in~/.local/share/piper-voices), PIL slides in brand colours with the logo, ffmpeg assembly; 1080x1920 and 1920x1080. ~40 s to render a ~20 s video on this box. Tested on the EOL note. - Stage 4b: Postiz (self-hosted, API) or direct platform APIs — Angel must create/connect the app credentials for LinkedIn, X, Instagram (Meta), YouTube.
Open¶
See ~/Notes/tasks.md — this section is now generated from the task register.