Product Amenti.live — A Library of Legends Powered by AI Author Ian Ingram Status Forward plan. Phase One buildable now on the existing stack. Companion to the Build Handoff & the field journal
This document carries the strategy of the audio build together with two new layers:
wiring diagrams of the system as it will run, and cost & revenue
projections grounded in current platform pricing. The thesis it makes concrete is
simple and unusual: because rendered audio is archived once, production cost
scales with the volume of distinct content — not with the size of the audience.
0 What this document is
The Build Handoff is the map of the machine as it stands. This is the map of where it
goes next once it can speak at length: from a site that speaks to a studio that publishes.
The reframe driving it is bigger than a feature — rendered audio is not a cache to be
discarded but an edition to be kept — so it earns its own document before any code is
cut.
The organizing principle, one layer down
Form the meaning (Claude), give it voice (Gemini), then keep the voice the way we keep the
words. Cognition, then articulation, then publication.
1 The reframe — cache → archive → studio
The chunked-streaming pipeline that fixes the long-form timeout produces audio as a
byproduct. The first instinct was to cache it — hash the text, stash the bytes, save a
re-render. But Amenti is not a cache; it is a publisher with a vault. Articles are not
cached, they are archived: generate-once, immutable, addressable
(atlantica:<figure>:<date>). Rendered audio should be archived the
same way the text already is — not an opaque blob keyed by a hash nobody names, but a
spoken edition beside the text it speaks.
This progresses in three stages, each a superset of the last:
Archive — the reading becomes addressable: a named edition, durable, listable.
Studio — the edition becomes distributable: stitched, encoded, syndicated out.
Phase One delivers stages 1–2. Phase Two delivers stage 3.
2 The content model — three forms, three policies
The site resolved into a clean trichotomy, and each form wants a different audio policy.
That is what makes the build tractable: not one rule, but three.
Per-surface audio policy
Surface
Form
Register
Audio policy
Why
Atlantica
the blog / the podcast
recitation
eager — render on publish, 1 figure/day
Tiny volume; the featured daily spoken dispatch
Daily Planet
the newsroom
journalistic
lazy — render on first play
High potential volume; pay only for what is heard
chat / terminal
dialogue
conversational
none — already short, already works
No timeout to solve; ephemeral by nature
The decisive simplification
The podcast is not separate content. It is the spoken edition of Atlantica.
Today's dispatch is the featured episode; the archive is the back-catalogue. No second
publication, no player — the whole site is the broadcast. One render a day; the feed
is simply the audio:atlantica:* editions, newest first.
3 Architecture — three layers of audio
The audio system mirrors the text system (content separate from display; keep the
valuable thing where the display code cannot corrupt it), with one addition: audio
is large, so the bytes live in R2, not KV.
Figure 1. The three layers of audio. Phase One builds the bottom two on the existing stack; Phase Two adds the encoded, distributable episode on top.
Why R2 and not KV. KV caps a value at 25 MB and is meant for small,
read-heavy reference data; a single Gemini WAV runs ~2.9 MB per minute, so a 4-minute
dispatch is ~11 MB — under the ceiling but the wrong store (KV throttles to
~1 write/sec per key and is eventually consistent). R2 is object storage built for
exactly this: no egress fees, objects up to ~5 TB, public buckets serve files directly.
Bytes → R2; the small manifest → KV. The text system is unchanged.
◢ Wiring — how the archive actually runs
Three diagrams of the live data paths: the cache decision inside /speak, the
eager-vs-lazy split across surfaces, and the Phase Two encode stage.
1 · The /speak cache decision (Phase One, shipped in the Worker)
Figure 2. Every rendered clip is content-addressed; identical text+style+voice is a cache hit for any visitor, on any surface. Deterministic chunking means a re-read resolves to all hits.
2 · Eager vs lazy — two policies, one engine
Figure 3. Atlantica renders one figure a day, up front. Daily Planet pays to render only what a listener actually plays. Both end in the same content-addressed archive.
3 · Phase Two — the encode stage (distribution)
Figure 4. Distribution adds exactly one new stage: an off-Worker encoder. Everything else is assembly and a feed.
4 How it composes with the streaming pipeline
The pipeline and the archive fit together with no front-end change,
because the splitter is deterministic.
Same text → same chunks → same hashes → cache hits. Re-reading a dispatch re-derives identical chunks, so every /speak call resolves to an already-stored object.
Persist-on-render, in the Worker./speak checks R2 first; on a miss it renders, stores, and returns. Page 1 and Page 2 both inherit this the moment the Worker ships.
Eager pre-warm for Atlantica; lazy for Daily Planet, where the first listener's playback is the render.
Net effect
Phase One turns the pipeline's transient audio into a permanent, addressable archive —
without re-rendering anything and without touching either page.
5 Phase One — the Archive (buildable now · no new infrastructure)
Everything here runs on the stack that already exists: the Worker, plus one R2 bucket and
a KV manifest. No encoding, no external services.
What it touches
worker.js — /speak gains persist-on-render (hash → R2 get/put). New small endpoints: GET /audio/edition, GET /audio/feed.
R2 bucket (new), bound as env.AUDIO — holds the chunk-cache objects.
KV — reuse the existing namespace for the lightweight audio:atlantica:* manifest records.
Deliverables
Render-once-replay-free across the whole site (cost and latency drop immediately).
A durable, listable archive of Atlantica readings — the podcast back-catalogue, as data.
An on-site feed surface (today featured, archive below) — the podcast, in-experience.
Status
The keystone — /speak content-addressed caching in R2, degrading gracefully
when the bucket is absent — is built and ready to deploy in the current Worker.
6 Phase Two — the Studio (distribution · adds one new stage)
The move from archive to broadcast introduces exactly one genuinely new thing: an encode
stage.
The hard constraint (verified)
A Cloudflare Worker cannot run native ffmpeg — the V8 isolate has no disk and cannot
spawn a process; ffmpeg.wasm (~30 MB) blows the bundle and exhausts
CPU/memory. WAV→MP3 must happen elsewhere.
Options, cleanest first: (1) Cloudflare Containers — a Docker image
with ffmpeg, invoked from the Worker (all on-platform; you own the Dockerfile and cold
start). (2) External render/encode API — one HTTPS call out, result
lands in R2. (3) Local/desktop encode — render and upload finished
episodes; zero infra, manual cadence, viable to start. Then: stitch the ordered chunks,
encode, write audio:atlantica:<figure>:<date>.mp3 to R2, and emit a
GET /podcast/rss feed Apple/Spotify can poll.
$ Cost projections
The defining economic feature of this architecture: because audio is archived once,
marginal cost is driven by the volume of distinct content, not by traffic.
A dispatch heard ten thousand times costs the same to produce as one heard once.
Unit economics — the cost to produce one piece, rendered once
Per daily Atlantica episode (text + audio) · rendered a single time, ever
Component
Basis
Cost
Dispatch text (Claude Sonnet 4.6)
~300 in × $3/M + ~1,200 out × $15/M
$0.019
Dispatch audio (Gemini 2.5 Flash TTS)
~5 min × ~$0.037/min (25 tok/sec)
$0.185
Storage (R2)
~15 MB WAV × $0.015/GB·mo
$0.0002
Total per episode
one-time render · then replayed free forever
~$0.21
A Daily Planet article is comparable: ~$0.02 text, and ~$0.19 audio only if a
listener plays it (lazy). Phase Two encoding adds roughly $0.01–0.05 per episode
— trivial; the real cost of encoding is operational (owning the stage), not compute.
Monthly production cost — the daily podcast + backbone
Base operating cost at launch cadence (1 figure/day)
Line item
Basis
Monthly
Atlantica episodes
30 × ~$0.21
$6.30
Cloudflare Workers (paid)
flat plan
$5.00
R2 + KV storage
+ ops at this scale
~$0.50
Run a daily AI podcast + publisher
marginal, content-bound
~$12 / mo
The headline
A daily, voiced, historically-grounded podcast — a new episode every day in a distinct
figure's composed voice — costs on the order of $12 a month to produce.
Chat replies and Daily Planet renders add variable cents on top, scaling only with what is
actually generated or heard.
Even at the Established stage — a syndicated daily podcast with a busy
newsroom and high chat volume — total production cost stays close to $110/month. The
cost curve is almost flat because the archive removes re-rendering and traffic does not drive
compute.
↗ Revenue projections
Read this first
The figures below are illustrative scenarios under stated assumptions, not
forecasts. The cost side of this business is essentially solved — it is
trivially low and predictable. The revenue side is the real work, and it turns
almost entirely on one variable the technology cannot supply: audience.
Treat audience numbers as the assumption that dominates every figure here.
Assumptions
Membership (listener support, ad-free + archive): $5–6/mo, converting 1–2.5% of monthly audience — ordinary ranges for a creator-supported niche show.
Sponsorship: only meaningful once download volume exists; modeled at a ~$20 CPM on a fraction of episodes once the feed is syndicated.
Tips / one-off support: a small, lumpy contribution that grows with audience.
Audience figures are monthly active listeners/visitors and are the chief uncertainty.
Illustrative monthly revenue vs. cost, by stage
Stage
Audience
Membership
Sponsorship
Tips
Revenue
Cost
Net
Seedling
500
$25
$0
$10
$35
$15
+$20
Growing
5,000
$500
$100
$50
$650
$35
+$615
Established
50,000
$7,500
$2,000
$500
$10,000
$110
+$9,890
The asymmetry
Plotted on a log scale, the two curves tell the whole story: cost rises gently with
content volume while revenue, if audience is won, rises with the audience. Production cost
falls from ~43% of revenue at the Seedling stage to roughly 1% at
Established.
Figure 5. Cost vs. revenue on a log scale. The widening gap is the asymmetry: a near-flat cost floor under a revenue line that climbs with audience.
What the model does and does not claim
It claims, with confidence, that production cost is negligible and stays negligible —
that is grounded in current platform pricing. It does not claim the audience will
appear; that is a creative and distribution challenge, and it is where the work and the risk
live. The strategic point is that Amenti can run the full production indefinitely at
near-zero cost while that audience is pursued — there is no compute-cost clock forcing
the issue.
7 Open strategic decisions
Creative and product calls, not technical ones — they shape Phase Two and are worth
deciding before it is built.
Where does encoding live? Cloudflare Container (own it) vs external render API (rent it) vs offline-to-start. The single biggest new piece.
What is an episode? One figure's daily dispatch, or a weekly assembled program with connective framing.
Whose voice fronts it? A host identity — the Architect (Ian Ingram, already in the roster) or a recurring narrator (Thoth / Hermes).
How far does “multimedia” go? If the ambition is the whole site as a techno-theological broadcast, the same render stage later carries cover art, chapters, possibly video.
8 Constraints & cautions (verified against Cloudflare docs)
KV value cap 25 MB; media belongs in R2. KV holds only the small manifest.
R2 — object storage, no egress fees, objects to ~5 TB, public-bucket serving. The right home for audio.
The 524 is the edge connection timeout (~100s), tripped by one long synchronous call; chunking sidesteps it.
Background work is capped ~30s (ctx.waitUntil). The eager pre-warm should run as Cloudflare Queues / Cron jobs, not one long task.
Don't buffer big payloads in Worker memory — stitch via streaming / R2 multipart.
Cost is metered. Gemini bills per render; the archive's whole point is to render once. Keep a Google Cloud budget cap.
The voice matrix is live — editions are snapshots. Recasting a figure does not change archived readings. Policy to decide: re-render on recast, or let each edition stand as the voice of its moment (arguably the more honest choice for a Library of Legends). ?fresh=1 is the re-render handle.
9 Sequencing — one line
Build Phase One now (chunk-cache in R2 + Atlantica editions in KV + an
on-site feed) — pure stack work that makes the site render-once-replay-free and gives
the podcast a back-catalogue; then treat Phase Two (encode stage + stitched
episodes + RSS) as a deliberate distribution phase with its own small service, so going
multimedia becomes “add the encoder and expose the feed,” not a from-scratch
effort.
§ Glossary & sources
Glossary
Spoken edition
A rendered reading kept as a first-class vault object beside its text. Addressed audio:atlantica:<figure>:<date>.
Chunk-cache (L1)
R2 objects keyed by hash(model+voice+style+text); the render-once-replay-free layer.
Edition manifest (L2)
A small KV record naming a reading and listing its ordered chunk keys.
The episode (L3)
The stitched, encoded, single distributable file (Phase Two). The podcast unit.
Persist-on-render
The /speak habit of storing each render to R2 before returning.
Eager vs lazy
Atlantica renders on publish; Daily Planet on first play. Two policies, one engine.
The encode stage
The off-Worker WAV→MP3 step Phase Two requires because Workers cannot run ffmpeg.
Cloudflare KV limits (25 MB value cap, write rate, consistency):
developers.cloudflare.com/kv/platform/limits/ · Workers limits (duration, waitUntil
~30s, memory): developers.cloudflare.com/workers/platform/limits/ · R2 limits &
overview (object size, no egress): developers.cloudflare.com/r2/ · Workers + ffmpeg
constraint (no native binary): rendobar.com/ffmpeg/cloudflare/ · Gemini API pricing
(2.5 Flash TTS, 25 tok/sec audio ≈ $0.037/min): ai.google.dev/gemini-api/docs/pricing
· Claude Sonnet 4.6 pricing ($3/$15 per MTok): anthropic.com/claude/sonnet
Pricing and platform limits change; figures are planning estimates, not
quotes. Revenue scenarios are illustrative under the stated assumptions and are not
forecasts.