Watch
0
0
Fork
You've already forked hyperhive
0

hive-agent: self-announce boot instead of host-side kick_agent

This commit is contained in:
damocles 2026-10-04 15:28:58 +02:00 • committed by mara
commit cd61ea4a37
4 changed files with 79 additions and 9 deletions

View file

@ -0,0 +1,47 @@
//! One-shot startup self-announce: pushes a todo on every harness boot so
//! the agent gets a "you were just (re)started" notice without the host
//! having to send one.
//!
//! Replaces `hive-c0re`'s old `Coordinator::kick_agent` calls at the tail
//! of the rebuild and start DAG nodes, which an operator reported as
//! duplicate restart messages: those fired one broker message per DAG
//! node, so a single rebuild — always a real
//! `StopForUpdate` → `Swap` → `RebuildBookkeeping` → `Reconcile` → `Start`
//! cycle — queued *two* separate restart messages for one actual boot, and
//! an agent paused for days could rack up dozens more from repeated
//! host-side sweeps. The harness itself has perfect knowledge of "did a
//! boot actually happen": it only runs this once, at the top of
//! `serve_main`. Self-announcing here dedups for free — one todo per real
//! process start, no host-side bookkeeping needed.
//!
//! No first-spawn-vs-restart distinction: every boot gets the same notice
//! (the old first-spawn message didn't reliably fire anyway, so unifying
//! the two loses nothing).
//!
//! Keyless on purpose: each boot is a genuinely new occurrence, not a
//! reconciled condition like `disk_watch`'s, so there's nothing to dedup
//! *against* within one store — `Todos::upsert`'s keyless path always
//! inserts a fresh row and always reports `changed`, which is exactly
//! "wake me, this happened" with no extra bookkeeping.
use tokio::sync::Notify;
use crate::todos::Todos;
/// Producing subsystem marker for the boot-announce todo row.
const SUBSYSTEM: &str = "harness";
/// Push the "you were just (re)started" todo and wake the turn loop.
/// Best-effort: a store error is logged, never fatal to boot.
pub fn announce(label: &str, todos: &Todos, wake: &Notify) {
let summary = format!(
"You were just (re)started. If you were mid-task, check \
`/agents/{label}/state/` for your notes and pick up where you left \
off — claude's `--continue` session is intact, so prior context is \
still in your window."
);
match todos.upsert(SUBSYSTEM, None, &summary, None, false) {
Ok(_) => wake.notify_one(),
Err(e) => tracing::warn!(error = ?e, "boot_announce: todo upsert failed"),
}
}