Sierra Story Co

A registered Reno LLC, not a demo. An n8n pipeline turns a recorded life story into a chapter draft and next session's questions, so a solo interviewer can spend the hour listening instead of typing.

Sierra Story Co product screenshot

Why this stack

n8n runs the whole pipeline because a solo operator building a real business, not a research prototype, needs a workflow change to ship in an afternoon: drag a node, redeploy, done. Docker on a spare Intel NUC keeps every client's recorded life story on a LAN-only machine instead of a SaaS vendor's database, which matters more here than for most software since the raw material is someone's memories. Obsidian's plain Markdown vault means the whole product (transcripts, chapter drafts, photos) is just files I can open, diff, and back up myself, with no proprietary export format standing between me and a client's book. Claude and OpenAI are both wired in behind a swappable key file so a provider outage or a model swap never blocks a session review a client is waiting on.

AI-assist note

The chapter drafts, refinement passes, and memory-jogger questions are LLM output (Claude and OpenAI) inside a pipeline I designed, wired, and debugged by hand, with Claude Code assisting on the n8n Code-node JavaScript and the print-pipeline Python and shell scripts. This is an automation and operations build, not a deep ML project. The model calls are a capable drafting and critique engine; the judgment is in the pipeline design, the sandbox workarounds, and the print QA, not in the model itself.

Stack

  • n8n
  • Docker
  • Obsidian
  • Anthropic Claude (+ OpenAI)
  • Pandoc + XeLaTeX
  • Google Sheets
  • MacWhisper

Domains

  • Workflow Automation
  • Operations & Client Delivery
  • Print Production
  • Small Business Operations
Live5 mo
Users1 completed memoir (proof of concept); customer acquisition underway
Payments40/30/30 milestone deposit schedule (signing, midpoint, pre-print) per the signed service agreement; pre-first-client, no revenue yet
Infran8n (Docker, self-hosted on an Intel NUC), Obsidian vault (Markdown, LAN-only), Pandoc + XeLaTeX print pipeline, Google Sheets client tracker
Authn8n admin JWT + per-service credential files on a LAN-only NUC (no public exposure); REST API scripted for workflow deploys
MarketingLive site at sierrastoryco.com (SEO + Search Console), Google Business Profile, founding-member testimonial program, flyer campaign for 55+ communities
Specs1

Why this exists

I started this to write my dad’s life story down before it was gone, sitting with him and turning recordings into chapters by hand. That turned into a question worth testing as an actual business: could an automated pipeline make a professionally produced memoir affordable for retirees who’d never otherwise get one written? Sierra Story Co. is the answer I registered as a Nevada LLC: a real company, with a signed service agreement, a live website, and a pricing structure, not a side experiment. An n8n pipeline on a home NUC handles the repeatable parts (transcription, first-draft chapters, next-session questions, client tracking) so my own hours go into the interview itself and the editing pass, not retyping.

Architecture

Sierra Story Co. memoir pipelineA recorded interview session is transcribed, drafted into a chapter by an LLM, and refined through a critique pass. The refined chapter splits into a memory jogger that feeds next session’s questions and a tracker and notification step. Once all chapters are approved, a separate print pipeline compiles the manuscript, runs a local KDP-equivalent preflight gate, and hands the file to a print vendor.In-Home Interview Sessionclient + interviewer, recorded on a phone micMacWhisper Transcription (Mac)speech-to-text, localwebhook POSTn8n Webhook IngestDocker, self-hosted on the NUCObsidian Vault: transcript.mdper-client folder, plain Markdown, LAN-onlyLLM Chapter DraftClaude / OpenAI, per-client voice profileRefine Pass (critique + revise)scene, voice, sensory detail, pacing, emotionMemory Joggerdecade-aware, transcript-grounded8-10 next-session questionsTracker + NotificationGoogle Sheets client trackeremail via Resendfeeds next session’s questionsafter all chapters approvedPrint Production (pandoc + XeLaTeX)local KDP-preflight gate: margins, DPI, EXIFPrinted Book DeliveredKDP paperback / Lulu hardcover / bespoke leather binderyvendor fulfillment, outside the pipeline

Every session flows the same direction: MacWhisper transcribes the recording, n8n picks it up over a webhook, and the transcript lands as plain Markdown in an Obsidian vault before anything touches an LLM. From there, a chapter draft and a critique-and-revise refinement pass both run through the same n8n workflow. The refined chapter splits two ways: a tracker and notification step updates the client record, and a memory-jogger step reads the chapter, the transcript, and the client’s birth decade to write next session’s questions, which loop back to the human interviewer instead of getting written by hand between sessions. Once every chapter for a client is approved, a separate print pipeline compiles the manuscript, runs a local preflight check built to mirror a print vendor’s own rejection rules, and only then hands the file to KDP, Lulu, or a bespoke bindery.

What shipped

Bill Belk’s memoir, Honeysuckle, Barbecue, and Pioneer in Silicon Valley, was the first full run through the print side of the pipeline: 7 chapters and 54 photos, built into a 6x9 interior and preflighted clean for a KDP paperback and a Lulu hardcover on the first real upload, with a leather-bound premium edition following on a longer bindery timeline. It didn’t go through the automated interview pipeline (it was co-written in person using ChatGPT directly, with no recorded sessions to transcribe), which is exactly why the pipeline’s next real client matters: that’s the first book where transcription, drafting, refinement, and the memory jogger all run end to end.

The business side is built and live, not aspirational: Sierra Story Co. LLC is filed in Nevada with an EIN and an operating agreement, sierrastoryco.com is indexed and serving a sales handout and a founding-member testimonial program, and the service agreement, intake form, and session script are all print-ready. The pipeline is production-hardened on a real book; the current phase is converting that into paying clients.

Skill stories

Click a skill to open the story behind it: the decision, what broke, how it got measured, and how it got fixed.

  1. n8n Secrets Under a Sandboxed RuntimeWorkflow Automation
  2. Decade-Aware Question Generation, Not a Generic Prompt ListContent Pipeline Design
  3. A Local KDP Preflight Gate, Not the Upload-and-Wait CyclePrint Production QA
  4. Deploying n8n Workflows Without Duplicate DriftSystems Reliability

Workflow Automation

n8n Secrets Under a Sandboxed Runtime

Decision
n8n's Code nodes run in a sandboxed VM that always blocks process.env and $env access, with no config flag to unlock it (only require() for specific Node builtins like fs, path, and https can be allowlisted). Instead of storing API keys inside the workflow JSON itself, which n8n exports and shares as one importable file, I wrote provider keys to a JSON file on the same Obsidian vault volume already mounted into the container, and had every LLM-calling Code node read it with fs.readFileSync at the top of the function.
What broke
The first attempt used a Set node with a {{ $env.ANTHROPIC_API_KEY }} expression feeding into the Code node, on the assumption that only the Code node's own require() calls were sandboxed. Both the Set node's expression evaluator and the Code node threw the identical 'access to env vars denied' error, so the block wasn't a Code-node quirk. It was a blanket n8n rule with no allowlist override.
How I measured it
Reproduced the failure against both node types directly to confirm it was a hard sandbox rule and not a missing config flag, then checked the fs.readFileSync workaround against every workflow that calls an LLM: chapter drafting, the refinement pass, the memory jogger, the knowledge-graph extractor, and the consistency checker. 5 separate call sites, all reading the same mounted key file.
How I fixed it
Standardized every LLM call site on the same pattern, with a documented one-line regen command that sources the real .env on the host and writes the JSON file the container reads. Switching between Claude and OpenAI, or between the first-draft model and the refinement-pass model, became a file edit with 0 redeploy, and the workaround is now the first entry in the project's n8n lessons-learned doc instead of something the next workflow has to rediscover.

Content Pipeline Design

Decade-Aware Question Generation, Not a Generic Prompt List

Decision
Rather than have the interviewer freehand next-session questions, or reuse the same generic prompt list for every client the way most competitor memoir services do, I chained a memory-jogger step onto the end of the chapter-drafting workflow: an LLM call that takes the finished chapter draft, a transcript excerpt, and the client's birth decade, and produces 8-10 follow-up questions using 6 named elicitation techniques (sensory anchor, place-based, people-centered, contrast, specific moment, dialogue) drawn from a research bank I compiled from oral-history and reminiscence-therapy sources.
What broke
The first version of the jogger prompt produced exactly the generic output the research bank had flagged as weaker: 'tell me more about your childhood' style questions with no connection to what the client had actually said.
How I measured it
Read jogger output from several completed sessions against the 6-technique checklist and checked each generated question for whether it named an actual person, place, or event from that specific transcript, versus a swappable placeholder that could apply to any client.
How I fixed it
Rewrote the prompt to require the model tag which technique each question used and anchor it to a specific name, place, or event pulled from the transcript, so a generic question can't pass the format. The step runs automatically after every chapter draft, so the interviewer walks into the next session with a decade-appropriate, transcript-grounded prep sheet instead of one written by hand between sessions.

Print Production QA

A Local KDP Preflight Gate, Not the Upload-and-Wait Cycle

Decision
Instead of relying on Amazon KDP's own previewer to catch formatting problems (a 10-minute upload-and-wait cycle per attempt), I built a local preflight script that walks every text block on every rendered PDF page via pdftotext's bounding-box output and flags anything crossing KDP's actual rejection thresholds (a 0.375 inch gutter, 0.25 inch outer and top and bottom margins), then wired it as a gate the print build script can't skip.
What broke
The first production run, Bill Belk's memoir, hit KDP's rejection queue 3 separate times: a oneside document class put the binding gutter on the wrong side for verso pages, and a closing line on one page ran past the outer margin. Each rejection cost a 10-minute upload, a wait for KDP's review, an edit, and a full rebuild before the next attempt.
How I measured it
Ran the local preflight against the full rebuilt interior after the layout fix and confirmed 0 flagged text blocks before ever re-uploading to KDP.
How I fixed it
Made the check mandatory: the build script won't produce a vendor-ready file until preflight passes clean, with any override requiring a written reason in a status file. Switching to a twoside, openright layout with a 0.875 inch gutter (more than double KDP's 0.375 inch floor, to leave room for hyphenation) and confirming 0 flagged text blocks locally meant the next upload passed the first time. The same 'catch it before the vendor does' approach also caught photos that would have printed sideways from unread EXIF rotation data, and low-DPI scans, before either reached a printer.

Systems Reliability

Deploying n8n Workflows Without Duplicate Drift

Decision
n8n's CLI import always creates a new workflow record; it never updates an existing one in place, even when the name matches exactly. On a single-operator system already carrying real clients' recorded life stories, I documented and enforced a fixed deploy sequence instead of trusting memory: import the new version, pull its versionId from the REST API, deactivate the old workflow, activate the new one with that versionId, then archive and delete the old copy.
What broke
By the 4th iteration of the chapter-drafting workflow, the n8n instance had 4 copies of it sitting in the workflow list, only 1 of which was both active and correct. Nothing in the n8n UI warns you this is happening; import just quietly adds another entry.
How I measured it
Audited the workflow list against the REST API's active flag before and after a deploy to confirm exactly 1 active copy per workflow name, and verified the login flow (the API takes emailOrLdapLoginId, not email) and cookie-based JWT extraction worked reliably enough to script instead of clicking through by hand.
How I fixed it
Wrote the exact archive, deactivate, activate, delete sequence into the project's lessons-learned doc as a repeatable runbook, so a deploy doesn't silently leave 2 active copies of the same workflow double-processing the same webhook on a system handling real clients' recordings.