diff --git a/crates/tui/src/core/engine/turn_loop.rs b/crates/tui/src/core/engine/turn_loop.rs index 6b7ffd1ff..472bc9bc7 100644 --- a/crates/tui/src/core/engine/turn_loop.rs +++ b/crates/tui/src/core/engine/turn_loop.rs @@ -314,7 +314,9 @@ impl Engine { // Three-zone prefix contract (#2264): freeze baseline on first // turn, verify against it on subsequent turns. Operates alongside // PrefixStabilityManager as an independent diagnostic layer. - // Phase 2: warn-only, auto-re-freeze on drift. + // Phase 3: emit a one-shot 'frozen' event on first turn. + // Drift is logged (tracing::debug!) but not re-emitted — + // PrefixStabilityManager already reports the change above. let system_text = crate::prefix_cache::system_prompt_text(self.session.system_prompt.as_ref()); let current_tools: &[crate::models::Tool] = active_tools.as_deref().unwrap_or_default(); @@ -338,7 +340,19 @@ impl Engine { self.session.system_prompt.as_ref(), current_tools.to_vec(), ); - self.session.frozen_prefix = Some(pinned.freeze()); + let frozen = pinned.freeze(); + let _ = self + .tx_event + .send(Event::PrefixCacheChange { + description: format!("frozen: {}", frozen.short_id()), + system_prompt_changed: false, + tools_changed: false, + stability_pct: 100, + changed: false, + pinned_combined_hash: frozen.hash().to_string(), + }) + .await; + self.session.frozen_prefix = Some(frozen); } }