From 664b3694f8088db76b734790dd236f4b8cd3e9b9 Mon Sep 17 00:00:00 2001 From: Cameron Cordes Date: Sat, 13 Jun 2026 23:16:14 -0400 Subject: [PATCH] Reels pre-gen: always render the agentic reel, don't adopt on-demand mp4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Past the key-aware dedup, any mp4 already at the cache key was not pre-generated by us (no matching ledger row) — typically an on-demand fast-scripted reel sharing the key after the max_segments alignment. Adopting it recorded a ledger row pointing at the fast reel, silently defeating agentic pre-gen. Drop the adopt-existing-mp4 shortcut and always produce_reel (atomic overwrite). Worst case is one redundant re-render if a prior run crashed between render and ledger write. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/reels/mod.rs | 45 +++++++-------------------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/src/reels/mod.rs b/src/reels/mod.rs index c5d7492..95769ad 100644 --- a/src/reels/mod.rs +++ b/src/reels/mod.rs @@ -1121,44 +1121,13 @@ async fn pregen_one( return Ok(()); } - // Check if MP4 already on disk (from a previous run that crashed after render) - let mp4_path = reel_mp4_path(app_state, &key); - if mp4_path.exists() { - log::info!( - "Precomputed reel MP4 already exists for key={}, recording ledger and skipping render", - key - ); - // Read title from sidecar if available - let sidecar_path = mp4_path.with_extension("json"); - let title = if sidecar_path.exists() { - let sidecar = tokio::fs::read_to_string(&sidecar_path).await.ok(); - sidecar - .and_then(|s| serde_json::from_str::(&s).ok()) - .map(|s| s.title) - .unwrap_or_else(|| format!("{} reel", span)) - } else { - format!("{} reel", span) - }; - let mut reel_dao = app_state.precomputed_reel_dao.lock().expect("lock"); - reel_dao.record_reel( - &ctx, - &crate::database::models::InsertablePrecomputedReel { - span: span.to_string(), - library_key: library.to_string(), - cache_key: key.clone(), - output_path: mp4_path.to_string_lossy().to_string(), - title, - media_count, - render_version: RENDER_VERSION as i32, - tz_offset_minutes: tz, - voice: voice.clone(), - generated_at: now, - }, - )?; - return Ok(()); - } - - // Generate the reel + // Past the key-aware dedup above, any MP4 already at this key was NOT + // pre-generated by us (it has no matching ledger row) — most likely an + // on-demand fast-scripted reel that happens to share the key. Don't adopt + // it: regenerate so the precomputed reel is the agentic one. produce_reel + // publishes atomically, overwriting whatever is there. (The narrow + // render-succeeded-but-ledger-write-failed crash window just costs one + // redundant re-render next run.) log::info!("Generating precomputed reel for span={}, key={}", span, key); let (title, mp4) = produce_reel( app_state,