events.sqlite vacuum moves host-side

retention is a host concern — agents have no business doing their
own cleanup, and a misbehaving harness could skip it. drop
spawn_events_vacuum from both hive-ag3nt and hive-m1nd, drop the
matching Bus::vacuum + EventStore::vacuum methods. new
hive_c0re::events_vacuum module sweeps every existing
agents/<name>/state/hyperhive-events.sqlite on the same hourly
cadence as the broker vacuum. same two-stage delete (older than 7
days, trim to 2000 newest). called from main alongside broker
vacuum.

also: server-side state badge entered into todo.md (today's badge
is derived client-side from sse, fine for idle/thinking but a
state machine that grows compacting/napping wants authoritative
status from the harness).
This commit is contained in:
müde 2026-05-15 20:10:34 +02:00
parent 897e7c07ae
commit 89ccc5e6c5
6 changed files with 89 additions and 63 deletions

View file

@ -58,7 +58,6 @@ async fn main() -> Result<()> {
let login_state = Arc::new(Mutex::new(initial));
let ui_state = login_state.clone();
let bus = Bus::new();
spawn_events_vacuum(bus.clone());
let ui_bus = bus.clone();
let ui_socket = cli.socket.clone();
tokio::spawn(async move {
@ -154,23 +153,6 @@ async fn serve(
}
}
/// Vacuum events older than 7 days, cap to 2000 most-recent rows.
/// Runs immediately, then hourly.
fn spawn_events_vacuum(bus: Bus) {
tokio::spawn(async move {
let interval_secs = 3600u64;
let keep_secs: i64 = 7 * 24 * 3600;
let keep_rows = 2000;
loop {
let n = bus.vacuum(keep_secs, keep_rows);
if n > 0 {
tracing::info!(removed = n, "events vacuum");
}
tokio::time::sleep(Duration::from_secs(interval_secs)).await;
}
});
}
/// Per-turn user prompt. The role/tools/etc. is in the system prompt
/// (`prompts/agent.md` → `claude --system-prompt-file`); this is just the
/// wake signal claude reacts to. `unread` is the count of *other*