fix(#2557): sweep unread rooms post-sync so a dropped matrix wake self-heals

This commit is contained in:
damocles 2026-07-17 15:44:04 +02:00 committed by mara
commit 742ed51d57
3 changed files with 96 additions and 133 deletions

View file

@ -19,11 +19,6 @@ use anyhow::{Context, Result};
use tokio::io::AsyncWriteExt;
use tokio::net::UnixStream;
/// Max characters of `body` to embed in the wake payload. Shorter than
/// `forge_notify`'s 500-byte excerpt because the agent has a follow-up
/// `read_room` tool to fetch the full event.
pub const WAKE_BODY_TRUNCATE: usize = 100;
/// Send an `AgentRequest::Wake { from: "matrix", body }` to the hyperhive
/// control socket at `socket`. Best-effort: returns Err on any plumbing
/// failure; callers log + ignore so a wake delivery hiccup doesn't tear
@ -68,16 +63,6 @@ pub async fn send_wake(socket: &Path, body: impl AsRef<str>) -> Result<()> {
Ok(())
}
/// Format a wake-message body from a matrix event's sender + room
/// canonical alias + body text. Truncates at [`WAKE_BODY_TRUNCATE`]
/// chars with an ellipsis. Shape: `[matrix] <sender> in <room>: <text>`
/// matches the `forge_notify` `[issue …]` framing convention.
#[must_use]
pub fn format_wake_body(sender: &str, room: &str, text: &str) -> String {
let truncated = truncate_chars(text, WAKE_BODY_TRUNCATE);
format!("[matrix] {sender} in {room}: {truncated}")
}
/// Format a wake-message body from a list of per-room unread summaries.
/// Single-room / single-message case collapses to the terse one-liner
/// format; multiple rooms expand to a bulleted list. Always appends a
@ -154,27 +139,6 @@ pub fn truncate_chars(s: &str, max: usize) -> String {
mod tests {
use super::*;
#[test]
fn format_wake_body_short_passes_through() {
let body = format_wake_body("@iris:matrix.darkest.space", "#general", "hi all");
assert_eq!(
body,
"[matrix] @iris:matrix.darkest.space in #general: hi all"
);
}
#[test]
fn format_wake_body_long_truncates_with_ellipsis() {
let long = "x".repeat(200);
let body = format_wake_body("@iris:m", "#x", &long);
assert!(body.contains("xxxxxxx"));
assert!(body.ends_with(""));
// Header + truncated body should be well under the absolute
// wake-message ceiling (forge_notify uses ~600 bytes; we're
// way under that).
assert!(body.len() < 200);
}
#[test]
fn truncate_chars_handles_multibyte() {
// `ü` is 2 bytes / 1 char. truncating to 3 chars on "üüüüüü"