From 2c4b380620c294cb6f62f123a69f629e0d61b25a Mon Sep 17 00:00:00 2001 From: Jer Miller Date: Fri, 31 Jul 2026 10:54:04 -0600 Subject: [PATCH] stop telling owners a held segment was rejected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A held segment has two possible histories and the .failed suffix does not record which: the journal declined it, or startup recovery could not finalize an interrupted one and it never left the machine. The status and doctor line asserted the first cause for both. On the machine this was found, both held segments carried no media at all — pure recovery artifacts — while the owner was told the journal had rejected two segments. Say only what is true of both histories. Also assert the doctor test against its own fixture; it pinned a separate literal and stopped matching the line it was checking. --- crates/solstone-linux/src/capture_stats.rs | 15 ++++++++------- crates/solstone-linux/src/doctor.rs | 14 +++++++++----- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/crates/solstone-linux/src/capture_stats.rs b/crates/solstone-linux/src/capture_stats.rs index 9805f0e..1a6a258 100644 --- a/crates/solstone-linux/src/capture_stats.rs +++ b/crates/solstone-linux/src/capture_stats.rs @@ -188,17 +188,18 @@ pub fn compute_quarantine_stats(root: &Path, now: f64) -> QuarantineStats { } } +/// A held segment has two possible histories and the suffix does not record which: the +/// journal declined it, or startup recovery could not finalize an interrupted one and it +/// was never sent at all. Naming either cause asserts something we cannot know — say only +/// what is true of both, which is that the segment is held and will not be retried. pub fn format_quarantine_line(stats: &QuarantineStats) -> Option { if stats.count == 0 { return None; } match stats.oldest_age_seconds { - None => Some(format!( - "Quarantine: {} rejected segment(s) held", - stats.count - )), + None => Some(format!("Held: {} segment(s) not sent", stats.count)), Some(age) => Some(format!( - "Quarantine: {} rejected segment(s) held, oldest {}d", + "Held: {} segment(s) not sent, oldest {}d", stats.count, (age / 86_400.0) as u64 )), @@ -309,7 +310,7 @@ mod tests { oldest_age_seconds: None }) .as_deref(), - Some("Quarantine: 2 rejected segment(s) held") + Some("Held: 2 segment(s) not sent") ); } #[test] @@ -320,7 +321,7 @@ mod tests { oldest_age_seconds: Some(5.9 * 86_400.0) }) .as_deref(), - Some("Quarantine: 2 rejected segment(s) held, oldest 5d") + Some("Held: 2 segment(s) not sent, oldest 5d") ); } // AC: injected now clamps future mtimes to zero age. diff --git a/crates/solstone-linux/src/doctor.rs b/crates/solstone-linux/src/doctor.rs index 39aaca1..7bfc32e 100644 --- a/crates/solstone-linux/src/doctor.rs +++ b/crates/solstone-linux/src/doctor.rs @@ -548,15 +548,19 @@ mod tests { // tests/test_doctor.py::test_run_doctor_omits_empty_quarantine_line #[test] fn quarantine_optional() { - for value in [Some("Quarantine: 1 rejected segment(s) held".into()), None] { + for value in [Some("Held: 1 segment(s) not sent".to_owned()), None] { let mut checks = FakeChecks::all(Severity::Ok); checks.quarantine = value.clone(); let mut out = Vec::new(); run_doctor(&mut checks, &mut out); - assert_eq!( - String::from_utf8(out).unwrap().contains("Quarantine:"), - value.is_some() - ); + let rendered = String::from_utf8(out).unwrap(); + // Assert against the fixture itself rather than a separately-copied literal: + // the previous form pinned its own substring and silently stopped matching the + // line it was meant to be checking when that line's wording changed. + match &value { + Some(line) => assert!(rendered.contains(line.as_str())), + None => assert!(!rendered.contains("segment(s) not sent")), + } } } // AC: aggregation keeps warnings non-fatal and failures fatal for each warn-capable slot. -- 2.51.2