One ad is a guess.
A salvo is a decision.
Brief in → N scored ad variants out — the best three ship. Salvo is a batch creative factory on Genblaze + Backblaze B2: one real pipeline fan-out, every variant stored with verified provenance, ranked by explainable, deterministic scores.
Zero credentials, zero signup — the OFFLINE demo is always green.
- pytest tests green, OFFLINE
- 0/19
- pytest tests green, OFFLINE
- transparent scoring signals
- 0
- transparent scoring signals
- credentials needed to demo
- 0
- credentials needed to demo
- variants per salvo, top 3 ship
- 0
- variants per salvo, top 3 ship
$ The response shape is verbatim from the live API — try it yourself.
Watch a salvo land
This is not a video. It runs a line-for-line port of salvo/ranking.py in your browser — same signals, same weights, same reason strings. Type any brief: the board is deterministic, so the same brief always lands the same way.
Enter a brief and fire — variants pop in, the scan ranks the board, and the top three get the ring.
Honest scope: swatches stand in for the OFFLINE mock PNGs, and this demo seeds content hashes from each variant’s descriptor instead of server-side image bytes — the scoring math, reason strings, and tie-breaks are the real thing. The live console runs the full pipeline: Genblaze fan-out, object storage, manifest verification.
Fire one on the real APIBrief in.
Decision out.
Four moves, all real SDK code paths. The sponsor stack is the engine here, not a sticker: Genblaze owns the fan-out and the manifest, Backblaze B2 owns the bytes.
OFFLINE=1 (default) runs everything on a local StorageBackend.
B2_KEY_ID + B2_APP_KEY flips storage to a real Backblaze B2 bucket.
- 01
Fan out
Your brief becomes N variant steps — one PNG + headline each — fired in parallel through one genuine Genblaze pipeline. Not a for-loop of fakes.
Pipeline.astream(max_concurrency=N) - 02
Store
Every variant lands in object storage with hierarchical keys — campaigns/{date}/{run}/… — through Genblaze’s documented StorageBackend interface.
ObjectStorageSink(backend, HIERARCHICAL) - 03
Verify
The provenance manifest is read back and checked, content hashes and all. If it doesn’t verify, the run says so.
read_manifest(verify=True) - 04
Rank & ship
Explainable, deterministic scores order the board. The three highest scorers are the three that ship — with the reasoning shown, not hidden.
rank_variants(brief, variants)
Every score shows its work
Three transparent signals with fixed weights. Nothing is random: the same brief and variant always yield the same score and the same reasons — which is what makes the ranking testable and the demo honest.
0.00
Brief coverage
How many of the brief’s keywords the headline actually uses. An ad that ignores the brief is a bad ad, no matter how pretty — so coverage dominates.
0.00
Headline length
Closeness to a 22–42 character scannable sweet spot: long enough to say something, short enough to scan.
0.00
Engagement index
A deterministic pseudo-signal seeded from the content hash, so the ranking is reproducible offline. Explicitly not real click data — and labeled as such in every reason string.
what one variant’s reasons[] looks like
- Brief coverage 2/4 keywords (eco, water) → +22.5 pts
- Headline length 25 chars, inside the 22-42 sweet spot → +25.0 pts
- Engagement index 0.91 (seeded from content hash, not real click data) → +27.3 pts
= 74.8 / 100 · same input, same output, every run — ties break on sha256 so ordering never wobbles
⚠ honesty note — quoted from the README
“The engagement index is not real click/CTR data — it is a deterministic stand-in seeded from the content hash so the ranking is reproducible offline, and every reason string says so. No fabricated metrics are presented as real.”
Built narrow. Built deep.
One flow — brief to shipped top three — done devastatingly well, on real sponsor SDK code paths instead of decoration.
A real fan-out, not a loop of fakes
All N variants run in parallel through one genuine Genblaze Pipeline.astream(max_concurrency=N) — the “batch factory” claim is backed by real SDK code paths, provenance-verified.
Green even when your provider dies
OFFLINE=1 is the default: a mock provider emits real PNG bytes through a dependency-free raw-PNG encoder — no Pillow, no ffmpeg, no network — while fan-out, storage, verification and ranking stay 100% real. The demo path is always green.
Provenance you can verify
Every variant is stored with a manifest that gets read back via read_manifest(verify=True). manifest_verified: true, or the run says otherwise.
Ranking that shows its work
Three transparent signals, fixed weights, plain-English reasons on every score — deterministic end to end.
B2 is one env-var away
Set B2_KEY_ID / B2_APP_KEY and storage flips from the local backend to a real Backblaze B2 bucket via Genblaze’s S3StorageBackend — auto-detected at startup.
Proof lives in the repo
19 pytest tests green with zero credentials, Dockerized with a /healthz healthcheck, live on Railway behind api.salvo.edycu.dev.
The variants speak for themselves
No invented praise, no stock-photo customers. These cards quote the ranking engine’s own reason strings from a representative run — fire the demo above and generate your own.
Nothing here is random: the same brief + variant always yields the same score — which is what makes the ranking testable and the demo honest.
salvo/ranking.py
module docstring, in the public repo
Brief coverage 2/4 keywords (eco, water) → +22.5 pts
Variant #0 — “Eco, reimagined for water”
Rank #1 · shipped
Headline length 29 chars, inside the 22-42 sweet spot → +25.0 pts
Variant #4 — “Your water, upgraded with eco”
Rank #2 · shipped
Engagement index 0.66 (seeded from content hash, not real click data) → +19.8 pts
Variant #1 — “The water built for bottle”
Rank #3 · shipped
Brief coverage 2/4 keywords (bottle, hikers) → +22.5 pts
Variant #2 — “Bottle: hikers without compromise”
Rank #4 · benched
$ OFFLINE=1 .venv/bin/python -m pytest → 19 passedend-to-end offline run · deterministic ranking · top-3 selection · manifest provenance · valid PNGs · the whole FastAPI surface
Asked by
skeptics
The questions that decide whether a “generate N variants” tool is real. Salvo answers all of them in code.
OFFLINE=1 is the default: a mock image provider emits real PNG bytes and an on-disk backend implements Genblaze’s documented StorageBackend interface, so the full pipeline runs with zero credentials and zero network. Setting B2_KEY_ID / B2_APP_KEY switches storage to a real Backblaze B2 bucket via Genblaze’s S3StorageBackend — auto-detected at startup.Pipeline fans out all N variant steps in parallel via astream(max_concurrency=N), stores them through an ObjectStorageSink with hierarchical keys, and reads the provenance manifest back with verify=True. The batch claim is backed by real SDK code paths.GET /healthz (liveness + mode + genblaze version), POST /campaigns (brief in → variants + ranking + top-3), GET /campaigns/{id}, GET /campaigns/{id}/variants/{i}.png, and GET /console — the operator console. Interactive docs are live.uv sync --extra dev, then OFFLINE=1 .venv/bin/python -m pytest (19 tests, all green), then OFFLINE=1 .venv/bin/python -m uvicorn app.main:app --port 8000 and open localhost:8000/console — type a brief, hit Generate, watch the scored grid render with the top 3 highlighted./healthz healthcheck, behind the custom domain api.salvo.edycu.dev. MIT licensed, source on GitHub.zero credentials · zero signup · offline demo is live right now
Fire your first
salvo.
Type a brief. Get a ranked batch with the reasoning shown. Ship the top three — with a verified manifest behind every variant.
$ curl -X POST https://api.salvo.edycu.dev/campaigns \
-H 'content-type: application/json' \
-d '{"brief":"eco water bottle for hikers","n":6}'