Inspiration

Monday morning. Legal blocks the summer launch hero.

You have the PNG. You don't have the proof - no prompt on record, no model name, no approver, no sidecar. Friday night was three browser tabs, the same brief pasted three times, forty dollars gone, and a Slack thread that ends with "Which model won?"

That's the gap we kept hitting: generation tools are excellent at output and terrible at accountability. Sponsors asked for reactive multi-provider pipelines with failover, streaming progress, and cryptographic provenance - not another single-model tab. EU AI Act Article 50 pushes machine-readable synthetic media marking into production timelines.

We built ProvLedger because campaigns need a ledger, not another generator.


What it does

ProvLedger is a provenance-aware AI media production ledger for creative teams and agencies.

The story in four beats

Beat What happens
Make Generate across GMI Cloud and Google through Genblaze - single-step failover, image→video chains, video fan-out, image tournament (Seedream + Gemini + FLUX in parallel)
Compare Every run is a branch in a version tree - prompt, model, cost, provider chain, parent lineage
Approve Human review workflow - approve with a required reason stored as an immutable B2 decision sidecar
Prove Public /verify/{content_hash}, embeddable badge, live tamper demo, C2PA + SHA-256 manifests

Also built for real production

  • Pre-spend dedup - identical bytes skip B2 re-upload; near-duplicate prompts suggest reuse before spend
  • Semantic search over version embeddings
  • Multi-workspace RBAC - team invites, scoped service keys, Postgres RLS
  • Spend governance - budget gates before generation
  • Compliance export - portable sidecar + EU AI Act disclosure fields

Problem intro for video

Record /demo-story first (~40s, 11 slides) - proof-first narrative before the live demo.


How we built it

Stack

Layer Technology
Frontend Next.js 14 · TypeScript · App Router
API Python 3.12 · FastAPI
Worker RQ on Redis
Database PostgreSQL (Supabase) + RLS
Auth Supabase JWT (ES256 JWKS)
Storage Backblaze B2 (S3-compatible, boto3 CAS)
Orchestration Genblaze SDK (genblaze[gmicloud,google,…])

Architecture (one paragraph)

Browser talks to FastAPI with JWT + workspace header. Heavy generation runs in an RQ worker via pipeline/orchestrate.py. Postgres holds the version graph and governance; B2 holds bytes and immutable proof artifacts. Genblaze Pipeline.stream() publishes SSE events through Redis to GET /jobs/{id}/events.

Visual diagrams: open docs/diagrams/index.html - architecture, user flow, B2 layout, Genblaze modes, trust layers.

flowchart LR
  Make[Make · Genblaze] --> Compare[Compare · Tournament]
  Compare --> Approve[Approve · B2 sidecar]
  Approve --> Prove[Prove · /verify]

Genblaze integration

  • Curated provider catalog with preset chains (fast / balanced / premium)
  • Pipeline(max_concurrency=3) for image tournament and video fan-out
  • stream_bridge.py → Redis → SSE for live UI progress
  • Hybrid storage: CAS assets/{sha256} + Genblaze ObjectStorageSink dual-write to runs/
  • Manifest.verify() surfaced on public verify page
  • Agent QC loop (agent_qc) retries until eval threshold (single-step path)
  • Chaos failover toggle for resilience demo

B2 integration

Artifact Key pattern Notes
Media (CAS) assets/{aa}/{sha256}.ext Dedup skip on existing hash
Manifest manifests/{sha256}.json Object Lock (governance)
Decision packet decisions/{sha256}.json Human approval evidence
Sidecars portable/, genblaze/manifests/ Export + SDK verify
Run logs logs/{version_id}.json Provider chain diagnostics

Also: lifecycle rules, event notification webhook, presigned private access.

Trust surface

  • Authenticated verify on asset provenance panel
  • Public GET /public/verify/{hash} - no login
  • Tamper demo corrupts bytes in-memory; B2 audit record survives
  • Embeddable badge: GET /public/badge/{hash}.js

Built with

backblaze-b2 · genblaze · fastapi · next.js · python · typescript · postgresql · redis · c2pa · object-lock · server-sent-events · docker · pytest · supabase · gmi-cloud · google-gemini


Providers & models

Modality Provider Models used in demo
Image GMI Cloud seedream-5.0-lite, flux-kontext-pro
Image Google gemini-2.5-flash-image, Imagen family
Video GMI Cloud Seedance, Kling i2v, Wan i2v, PixVerse
Video Google Veo 3.x
Audio ElevenLabs / GMI TTS via catalog
QC Eval gate OpenCLIP similarity + optional Gemini judge

List dynamically at runtime: GET /providers


Demo walkthrough (what to click)

See DEMO-SEED-CHECKLIST.md for exact prompts.

  1. /demo-story - 40s animated problem (optional in video)
  2. Dashboard → asset Summer launch hero
  3. Generate → Pipeline: Image tournament
  4. Watch SSE progress - three models concurrent
  5. Tournament compare → pick winner → Request review
  6. Approve with reason: "Best brand fit; tournament winner matches summer launch brief."
  7. Copy hash → /verify/{hash}Tamper demo
  8. Export compliance bundle (optional)

Challenges we ran into

  • Hybrid ledger vs Genblaze samples - Sponsor repos use hierarchical runs/ keys; we needed CAS dedup across workspaces. Solution: dual-write manifests + Genblaze sidecar pattern (genblaze_sidecar.py).
  • Windows + Upstash Redis - SSL cert verification required certifi bundle in redis_client.py.
  • Failover visibility - Judges need to see recovery - we added chaos toggle and provider chain UI.
  • Approval as evidence - Approving without a reason felt like theater - we require decision text and store it on B2 with Object Lock.
  • Provider quota limits during demo prep - Tournament degrades gracefully when one model 429s; at least one variant still lands for verify path.

Accomplishments we're proud of

  • Deepest version tree + dedup + search + spend governance in the hackathon field
  • Image tournament + video fan-out in one product with live SSE
  • Public verify + tamper demo + embed badge - no login required
  • Real B2 CAS savings (reuse skips re-upload)
  • 11-slide proof-first story at /demo-story for video intro
  • 30+ automated tests including public verify and approval gates
  • Judge-ready HTML architecture diagrams in docs/diagrams/

What we learned

Judges optimize for a 60-second click path, not architecture essays. We learned to lead with tournament → approve → verify, and keep platform breadth for follow-up questions.

Genblaze's manifest model is the right atomic unit for provenance - our job was connecting it to team workflows (review, budgets, reuse) and B2 durability.

The story that lands: "Had the PNG. No proof to ship." - then show the verify link.


What's next

  • Full ObjectStorageSink migration path (documented in GENBLAZE-FEEDBACK-ISSUE.md)
  • Trusted C2PA production certificate chain
  • Identity-anchor reuse for episodic campaigns
  • Campaign replay across assets for agency workflows

Built With

Share this project:

Updates