From e9026814be51a95a5236f35e0601dbe7c9e54599 Mon Sep 17 00:00:00 2001 From: Hanmiao Li <894876246@qq.com> Date: Thu, 28 May 2026 11:53:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20integrate=20SlopLedger=20completion-gat?= =?UTF-8?q?e=20into=20turn=20loop=20=E2=80=94=20auto-check=20on=20every=20?= =?UTF-8?q?completed=20turn=20(#2127)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/tui/src/tui/ui.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/tui/src/tui/ui.rs b/crates/tui/src/tui/ui.rs index 61cb195c..1512c5bb 100644 --- a/crates/tui/src/tui/ui.rs +++ b/crates/tui/src/tui/ui.rs @@ -1491,6 +1491,27 @@ async fn run_event_loop( // Generate post-turn receipt for completed turns. if status == crate::core::events::TurnOutcomeStatus::Completed { + // SlopLedger completion-gate: after every completed + // turn, check whether there are unresolved slop entries + // the agent should address before claiming the task is + // done (#2127). This runs autonomously — no tool call + // required — so the agent can't forget to check. + if let Ok(ledger) = crate::slop_ledger::SlopLedger::load() + && ledger.has_open_entries() + { + if let Some(gate_msg) = ledger.completion_gate_summary() { + let short = gate_msg + .lines() + .nth(4) + .unwrap_or("review before done"); + app.push_status_toast( + format!("⚠️ SlopLedger: {short}"), + crate::tui::app::StatusToastLevel::Warning, + Some(12_000), + ); + } + } + let tool_count = app.tool_evidence.len(); let mut receipt = "✓ turn completed".to_string(); if tool_count > 0 {