CASTIRON · MISSION CONTROL
SYSTEM LIVE · 0 DROPPED
◆  BUILT FOR THE BACKBLAZE GENERATIVE MEDIA HACKATHON

CastIron

Script to published episode — even when your TTS provider dies.
A self-healing audio-episode factory on Genblaze + Backblaze B2.

96/96 SHIPPED VERIFIED FAILOVER p50 ≈ 120 ms GENBLAZE 0.4.1 · B2 OBJECT LOCK
NARRATION LADDER · LIVECHAOS: TTS OUTAGE
rung 0 · elevenlabs
rung 1 · lmnt
rung 2 · humeSTANDBY
episode.mp3 · manifest.verify() ✓SHIPPED
CASTIRON
02 · FAILURE MODE
The Problem

One vendor call
kills the whole episode.

Generative-media pipelines are brittle in exactly one place that matters: the vendor call. TTS providers throttle, return 500s, and go down.

A naive pipeline drops everything — narration, music, cover, the run.
On a schedule — a daily brief, a podcast — one upstream outage = dead air.
And once produced, most pipelines can't prove the episode wasn't silently altered afterward.
script.md──▶tts · elevenlabs ✕
HTTP 500 · provider outage, 2 a.m., episode 214 of the daily brief
EVERYTHING DOWNSTREAM DIES WITH IT
narration.mp3music.mp3cover.png
└─▶episode.mp3 — never assembled
RUN TERMINATED · NOTHING PUBLISHED
Entire episode dropped.
CASTIRON
03 · DESIGN THESIS
The Solution

Failure is the expected case.

CastIron makes one measurable promise — zero dropped episodes — and backs it with four load-bearing mechanisms.

PILLAR 01
ladder.py

Cross-provider failover ladder

Every narration render tries distinct vendors in order — ElevenLabs → LMNT → Hume. One goes dark mid-render, the ladder steps down a rung, the episode still ships. The manifest records the actual provider used, not the requested one.

PILLAR 02
media.py

Provenance hashed into the file

The asset manifest is embedded inside the MP3 (ID3). Edit one byte and verify() flips to False — tamper-evidence travels with the episode.

PILLAR 03
publish.py

Immutable publish

Finished episodes land in Backblaze B2 under a real Object Lock (GOVERNANCE, 30 days). "Published" means provably unaltered.

PILLAR 04
gate.py · resume.py

Self-healing orchestration

An AgentLoop quality gate (loudness · silence · duration), transient resume with a single charge, a budget hard-abort, and an always-green OFFLINE fallback keep the run alive.

CASTIRON
04 · CHAOS DRILL · LIVE
The Hero Moment

Kill the provider.
Ship anyway.

Flip the chaos toggle: the primary voice dies mid-render. The ladder catches it on rung 0, steps to rung 1 — and the episode still lands, verified and published.

CHAOS · TTS OUTAGE
0
DROPPED EPISODES — EVER
NARRATION · FAILOVER LADDERPOST /runs · chaos="tts"
RUNG 0
elevenlabs
RUNG 1
lmnt
RUNG 2
hume
STANDBY
▸ manifest records ACTUAL provider · lmnt · fallback_rung=1
✓ read_manifest(verify=True) → episode.mp3 hash-verified
✓ published → B2 ci-published/ · Object Lock 30d
CASTIRON
05 · PIPELINE
Architecture

Fan-out. Verify. Seal.

01 · INGEST POST /runs {script, chaos?} 02 · FAN-OUT · astream(×3) Pipeline.astream(max_concurrency=3) · typed event stream narration LadderTTS · elevenlabs→lmnt→hume music Stability-shaped provider cover FLUX / DALL·E-shaped provider 03 · STORE ObjectStorageSink B2 · HIERARCHICAL layout runs/{date}/{run} + manifest.json 04 · VERIFY + EMBED read_manifest(verify=True) SmartEmbedder → in-file ID3 manifest → episode.mp3 · tamper-evident event log · SQLite astream events → SSE live console 05 · EVENT-DRIVEN PUBLISH B2 IS THE CONTROL PLANE B2 Event Notification HMAC-signed · constant-time verify idempotent stage machine render → mix → verify → publish ci-published/{run}/episode.mp3 ⬢ Object Lock · GOVERNANCE · 30 days immutable — provably unaltered episode lands in B2 → notification fires
CASTIRON
06 · SPONSOR INTEGRATION
Genblaze + Backblaze B2

The SDK is the engine — not decoration.

GENBLAZE 0.4.1 · 8 SURFACES IN PRODUCTION
Pipeline.astream / arunparallel fan-out + typed event streampipeline.py
ObjectStorageSink + read_manifestHIERARCHICAL store, verified read-backpipeline.py
SmartEmbedderin-file ID3 manifest embedmedia.py
resume_step / aresume_steptransient resume — single chargeresume.py
AgentLoop evaluatorsLUFS + silence + duration quality gategate.py
ObjectLockConfig(GOVERNANCE)immutable publishpublish.py
StorageBackend subclass+ ProviderComplianceTests conformancebackends.py
RetryPolicy · for_backblazeper-rung retries · LIVE B2 swapladder.py
Every surface sits on a production code path — audited via scripts/sdk_introspect.py, not a demo shim.
BACKBLAZE B2 · STORAGE PLANE

S3 API, hierarchical layout

Every run's assets + manifest.json land in B2 under runs/{date}/{run}/… via the S3-compatible API.

BACKBLAZE B2 · CONTROL PLANE

Event Notifications drive publish

HMAC-signed notifications trigger the idempotent render→mix→verify→publish stage machine. Storage events are the workflow.

BACKBLAZE B2 · PROOF

Object Lock, verified live

Immutability isn't claimed — it's read back: get_object_retention confirms the lock on the real bucket.

CASTIRON
07 · BENCH · SEED=42
Proof, Not Promises

Every number reproduces.

96/96
EPISODES SHIPPED HASH-VERIFIED · HEALTHY + FORCED OUTAGE
0
DROPPED EPISODES ACROSS ALL RUNS
120ms
FAILOVER p50 · p95 ≈ 134 ms (OFFLINE ORCHESTRATION)
129
TESTS PASSING · ~92% LINE COVERAGE
CHAOS MATRIX · bench.pyn = 6 scripts × 8 repeats
Scenarionp50 / p95Correctness gate
Healthy — provider up48119 / 126 ms48/48 shipped verified ✓
Failover — primary TTS killed48120 / 134 msrung steps + still ships ✓
Tamper — 1 byte edited1verify() → False
Budget — spend over cap1BUDGET_ABORT before spend ✓
castiron — bench
$ OFFLINE=1 .venv/bin/python bench.py
seed=42 · mock providers · LocalDirBackend

HEADLINE: 96/96 episodes shipped hash-verified
  across healthy + forced-outage runs — 0 dropped.
failover p50≈120ms · p95≈134ms
ALL GREEN — 0 dropped episodes
$ echo $?
0   # exits non-zero on any correctness failure
CASTIRON
08 · HARDENING
Production Readiness

Built like it runs every night.

QUALITY
✓ ruff · 3.11+3.12
SECURITY
✓ CodeQL · audit
BUILD
✓ wheel + sdist
E2E
✓ 4-scenario proof
PERFORMANCE
✓ p50/p95 gate
DEPLOY
✓ gated on green
SECURITY · 0 OPEN ALERTS

CodeQL + Dependabot + secret scanning all enabled, all clean. Webhook HMAC verified in constant time.

IDEMPOTENT BY DESIGN

The publish stage machine converges under duplicate and reordered webhook delivery. Typed failures: BUDGET_ABORT, degraded-but-recorded runs.

ALWAYS-GREEN OFFLINE

Mock providers + local backend = zero-network, zero-credential path. It's the dev loop, the regression net, and the demo-day disaster fallback.

DURABLE LIVE RAIL

The SQLite event log is the source of truth — reconnect-safe SSE; the hub is just a low-latency nudge. State survives the stream.

LIVE EVIDENCE PACKS

Real B2 runs archived in-repo: docs/evidence/ — kill-switch drill + live publish with the Object Lock retention read back.

LOCAL MIRROR OF CI

The whole harness runs on a laptop: make ci · make e2e · make bench · make security-scan.

Honest scope: E2E = API/ASGI + the deterministic offline proof — this is a FastAPI backend, not a web UI. Performance gate measures orchestration, not vendor synthesis.

CASTIRON
09 · THE MOAT
Why Only This Stack

The thesis needs both halves.

GENBLAZE · THE ABSTRACTION HALF

Makes the ladder possible

One uniform provider + manifest layer is what a cross-provider failover ladder and manifest-verified resume can exist on top of.

uniform provider interface → rungs are swappable
manifest layer → the ACTUAL rung is recorded
resume_step → recovery without double-charging
+
BACKBLAZE B2 · THE TRUST HALF

Makes publish provable

Object Lock is what turns "published" into "provably unaltered" — and Event Notifications make storage the control plane.

Object Lock (GOVERNANCE) → immutable episodes
Event Notifications → publish is event-driven
get_object_retention → immutability read back live
Remove either half and the differentiator collapses.
CASTIRON
10 · ROADMAP
What's Next

From proven engine to scheduled show.

NOW

Live demo + failover video

The hosted console and the recorded chaos-drill walkthrough ship next — until then, everything on these slides reproduces from the repo with OFFLINE=1 .venv/bin/python bench.py.

NEXT

Full live event round-trip

Deploy the notification receiver to a public URL so B2 Event Notifications drive publish end-to-end in production — the HMAC verify and stage machine are already proven against synthetic deliveries.

THEN

Cross-provider failover, upstream

Genblaze's built-in fallback is in-provider only — the cross-vendor gap CastIron fills is filed upstream as a dossier issue, with our ladder as the working reference.

GOAL

Run a real daily brief on schedule

The product claim is operational: a show that publishes every day because vendor outages stop mattering. Zero dropped episodes, indefinitely.

CASTIRON
11 · REPRODUCE IT YOURSELF
The Ask

Break it.
It ships anyway.

Don't take the deck's word for it — the whole claim reproduces in one command, no keys, no config.

Vendors die. Episodes ship.

reproduce — 60 seconds
$ git clone github.com/edycutjong/castiron
$ uv sync   # genblaze==0.4.1 + deps
$ OFFLINE=1 .venv/bin/python bench.py

HEADLINE: 96/96 shipped hash-verified — 0 dropped.
ALL GREEN — 0 dropped episodes

$ OFFLINE=1 .venv/bin/python -m uvicorn app.main:app
# → open /console · flip the chaos toggle yourself
129 TESTS · CI GREEN OBJECT LOCK · PROVEN LIVE MIT LICENSE
← → NAVIGATE · ESC OVERVIEW · P NOTES01 / 11
SPEAKER NOTES