delete c0re-side reminder plumbing (#2635 inc 1 commit 6)

This commit is contained in:
damocles 2026-07-22 23:01:16 +02:00 committed by mara
commit a80d0b0fed
16 changed files with 70 additions and 1136 deletions

View file

@ -23,7 +23,6 @@ use crate::coordinator::Coordinator;
mod config_approvals;
mod lifecycle_handlers;
mod reminders;
mod schedules;
pub(crate) use config_approvals::submit_merge_config_pr;
@ -34,7 +33,6 @@ use config_approvals::{handle_request_init_config, handle_request_update_meta_in
use lifecycle_handlers::{
handle_kill, handle_list_descendants, handle_restart, handle_start, handle_update,
};
use reminders::{handle_remind, resolve_agent_state_target};
use schedules::{
EditSchedulePatch, handle_cancel_schedule, handle_edit_schedule, handle_fire_schedule_now,
handle_list_schedules, handle_request_schedule_prompt,
@ -184,8 +182,8 @@ pub(crate) fn recv_timeout(wait_seconds: Option<u64>) -> std::time::Duration {
/// Handle the subset of `Request` variants that are identical on both
/// the agent socket and the manager socket. Returns `Some(response)` for
/// every variant it handles; returns `None` for variants with socket-specific
/// semantics (e.g. `GetLooseEnds` / `CountPendingReminders` / `ReminderRollup`
/// where the manager can target other agents) or for manager-only variants.
/// semantics (e.g. `GetLooseEnds`, where the manager can target other
/// agents) or for manager-only variants.
///
/// The unified `dispatch` calls this first; the remaining arms (which gate
/// on topology / capabilities / tool-groups) are handled there.
@ -234,11 +232,6 @@ pub(crate) async fn dispatch_shared(
|()| hive_core_agent_sock::Response::Ok,
)
}
hive_core_agent_sock::Request::Remind {
message,
timing,
file_path,
} => handle_remind(coord, agent, message, timing, file_path.as_deref()),
hive_core_agent_sock::Request::SetStatus { text } => handle_set_status(coord, text),
hive_core_agent_sock::Request::GetAgentMeta { name } => {
handle_get_agent_meta(coord, agent, name.as_ref()).await
@ -590,13 +583,6 @@ async fn dispatch(req: &Request, agent: &str, coord: &Arc<Coordinator>) -> Respo
Request::GetLooseEnds { agent: target } => {
handle_get_loose_ends(coord, agent, target.as_deref())
}
Request::CountPendingReminders { agent: target } => {
handle_count_pending_reminders(coord, agent, target.as_deref())
}
Request::ReminderRollup {
since_secs,
agent: target,
} => handle_reminder_rollup(coord, agent, target.as_deref(), *since_secs),
// Orchestration / diagnostics verbs — gated per-verb on tool-group
// membership or topology (see `dispatch_orchestration`).
_ => dispatch_orchestration(req, agent, coord).await,
@ -791,41 +777,38 @@ fn handle_get_loose_ends(coord: &Arc<Coordinator>, agent: &str, target: Option<&
}
}
/// `CountPendingReminders` — resolve the target (own / subtree free, else
/// `QueryAgentState`) then count its pending reminders.
fn handle_count_pending_reminders(
coord: &Arc<Coordinator>,
agent: &str,
target: Option<&str>,
) -> Response {
match resolve_agent_state_target(agent, target) {
Ok(name) => match coord.broker.count_pending_reminders_for(name) {
Ok(count) => Response::PendingRemindersCount { count },
Err(e) => Response::Err {
message: format!("{e:#}"),
},
},
Err(message) => Response::Err { message },
}
}
/// `ReminderRollup` — resolve the target (own / subtree free, else
/// `QueryAgentState`) then roll up its reminders fired in the last
/// `since_secs`.
fn handle_reminder_rollup(
coord: &Arc<Coordinator>,
agent: &str,
target: Option<&str>,
since_secs: u64,
) -> Response {
match resolve_agent_state_target(agent, target) {
Ok(name) => match coord.broker.reminder_rollup_for(name, since_secs) {
Ok(stats) => Response::ReminderRollup(stats),
Err(e) => Response::Err {
message: format!("{e:#}"),
},
},
Err(message) => Response::Err { message },
/// Resolve the target agent name for a *named* `GetLooseEnds` query. Rules:
///
/// - `None` (or `Some(caller)`) → the caller's own threads (always allowed).
/// - `Some(descendant)` in the caller's subtree (the root's subtree is the whole hive) → allowed, no extra capability.
/// - `Some(other)` outside the subtree → requires the `query_agent_state` capability; error otherwise.
/// - `Some("*")` → rejected here; the hive-wide sweep is handled by `handle_get_loose_ends` under the same `query_agent_state` gate.
fn resolve_agent_state_target<'a>(
caller: &'a str,
target: Option<&'a str>,
) -> Result<&'a str, String> {
match target {
None => Ok(caller),
Some("*") => Err(
"hive-wide query (agent=\"*\") is only valid for loose-ends; \
not available for this query"
.to_owned(),
),
Some(name) => {
// Own subtree (the root covers all) is visible without extra
// capability; `is_descendant_of` returns true for `name == caller`.
if crate::topology::is_descendant_of(name, caller) {
return Ok(name);
}
if crate::capabilities::has_cap(caller, hive_sh4re::Capability::QueryAgentState) {
Ok(name)
} else {
Err(format!(
"agent `{caller}` cannot query `{name}`: not in its subtree and \
`query_agent_state` capability is not granted"
))
}
}
}
}