Inspiration
Generative media makes it easy to create another take. It does not make it easy to remember what changed, recover the exact recipe, or explain why one result was approved. In a normal handoff, the final file survives while the rejected alternatives, provenance, and creative judgment disappear across chats, downloads, and folders.
That is a quiet but expensive loss. The next editor cannot reliably reproduce, defend, or branch the work. Shot Ledger treats approval as a production artifact, not a comment that gets separated from the media.
What it does
Shot Ledger records one scene contract, uses Genblaze to generate three takes with one named creative variable intentionally changed, and stores every take, manifest, and partial-run checkpoint in Backblaze B2. A human then reviews the B2-backed takes side by side, chooses one keeper, and records an image-specific reason.
The app seals the keeper, rejected siblings, prompt, parameters, provider/model, Genblaze manifests, media hashes, and human decision into one B2 decision packet. A fresh process reloads the packet, all three images, and all three manifests from B2 alone and verifies their hashes.
The result answers two questions together: How was this made? Why did we choose it?
Shot Ledger is not a prompt gallery and it does not ask a model to grade its own output. Generation supplies the candidates and machine provenance. A human supplies the creative decision.
How we built it
Python powers generation, storage, verification, and the operator review service. Genblaze runs a declared three-take pipeline through its OpenAI image adapter and emits canonical provenance manifests. GPT Image 2 generates the contest proof. Backblaze B2 stores the images, manifests, partial-run state, and sealed decision packet.
The public review surface runs on Cloudflare Workers and serves the verified B2 evidence read-only. It recomputes the decision hash before serving media or packet exports. An authenticated operator can choose and reseal a keeper; an anonymous visitor cannot overwrite the shared decision.
If a provider call fails, successful sibling takes remain in B2. Retry generates only failed or pending takes, preserving the original assets, manifests, and generation cost.
How Backblaze B2 is used
B2 is the system of record, not a backup destination. The workflow writes generated media, Genblaze manifests, retry state, and the sealed decision packet to a private B2 bucket. A separate verification process then reloads one decision packet, three images, and three manifests from B2. It verifies every hash before the public edge serves the evidence.
Challenges
- Keeping the intended comparison legible while letting a human reviewer see model drift.
- Separating a valid decision hash from proof that the underlying image bytes and provenance manifests still match.
- Recovering partial provider runs without discarding successful paid takes.
- Presenting enough provenance for trust without turning the review surface into an infrastructure console.
Accomplishments
- Built a functional desktop and mobile review workflow.
- Created a tamper-evident keeper/rejection decision packet.
- Added byte-level image verification plus Genblaze manifest and recipe checks.
- Added selective retry that preserves completed paid takes.
- Built a fresh-process B2 reload verifier and a read-only public edge.
What we learned
Provenance becomes useful only when it travels with a human decision. A perfect generation log cannot explain why a creative lead chose one take, and a comment cannot reconstruct the generation. The durable handoff needs both.
What's next
The next useful step is a handoff test with working creative teams, followed by exports into the asset and approval systems they already use. The same receipt model can later support controlled video and audio dailies without changing the human-decision boundary.
Built With
- backblaze-b2
Log in or sign up for Devpost to join the conversation.