Watch
0
0
Fork
You've already forked hyperhive
0

agents: remove send(operator) and the operator inbox; alert on turn failures

Agents reach the operator over matrix now (#5115). A `send` to
`operator` is refused, by the broker and by the MCP allow-list check,
with an error that names the matrix MCP tools. The dashboard's Y3R C4LL
tab goes with it: the operator inbox, `GET /api/operator-inbox`,
`Broker::unread_for_recipient`, and the browser notifications that only
ever fired on operator-bound messages.

The harness no longer posts turn failures and plugin-install failures
to the operator inbox. Both are already logged at warn; a new Grafana
rule, `hh-agent-turn-failed`, fires per agent on the harness's
`turn failed` line.

Dashboard-to-agent messaging (op-send, the agent web UI's message box,
mark-all-read for agent inboxes) is unchanged.

Decisions per mara on #5115: q1 a, q2 a plus a grafana alert, q3 keep
dashboard-to-agent messaging and leave swarm-level code alone.
This commit is contained in:
atlas 2026-10-12 00:44:11 +02:00 • committed by mara
commit 7e6a4c7727
37 changed files with 246 additions and 848 deletions

View file

@ -48,20 +48,9 @@ pub fn swarm_name() -> Option<String> {
non_empty_env("HYPERHIVE_SWARM_NAME")
}
/// Hive-qualified agent identity. When the hive domain is configured, returns
/// `${label}@${domain}` (e.g. `iris@darkest.space`); when not, returns just
/// the short label so callers can render a single string regardless of
/// deployment shape. Callers that want to know whether the result is
/// qualified should check [`hive_domain`] directly.
#[must_use]
pub fn qualified_label() -> String {
qualify(&label())
}
/// Apply hive qualification to an arbitrary agent label (e.g. a peer name
/// from the broker). Mirrors [`qualified_label`] but lets a caller qualify
/// names it didn't read from the env. Returns `${label}@${domain}` when the
/// hive domain is set, else just `label`.
/// Apply hive qualification to an agent label (e.g. a peer name from the
/// broker). Returns `${label}@${domain}` when the hive domain is set, else
/// just `label`.
#[must_use]
pub fn qualify(label: &str) -> String {
match hive_domain() {
@ -151,27 +140,27 @@ mod tests {
}
#[test]
fn qualified_label_with_domain_set() {
fn qualify_with_domain_set() {
with_env(Some("iris"), Some("darkest.space"), || {
assert_eq!(qualified_label(), "iris@darkest.space");
assert_eq!(qualify(&label()), "iris@darkest.space");
assert_eq!(hive_domain().as_deref(), Some("darkest.space"));
});
}
#[test]
fn qualified_label_falls_back_to_short_when_domain_unset() {
fn qualify_falls_back_to_short_when_domain_unset() {
with_env(Some("iris"), None, || {
assert_eq!(qualified_label(), "iris");
assert_eq!(qualify(&label()), "iris");
assert!(hive_domain().is_none());
});
}
#[test]
fn qualified_label_falls_back_to_short_when_domain_empty() {
fn qualify_falls_back_to_short_when_domain_empty() {
// Empty string is treated the same as unset — a misconfigured
// module shouldn't surface `iris@` (no domain) to the operator.
with_env(Some("iris"), Some(""), || {
assert_eq!(qualified_label(), "iris");
assert_eq!(qualify(&label()), "iris");
assert!(hive_domain().is_none());
});
}
@ -247,8 +236,8 @@ mod tests {
assert!(hive_domain().is_none());
assert_eq!(hive_name().as_deref(), Some("pr1ma"));
assert_eq!(swarm_name().as_deref(), Some("constellat1on"));
// qualified_label still degrades to short label without domain.
assert_eq!(qualified_label(), "iris");
// qualify still degrades to the short label without a domain.
assert_eq!(qualify(&label()), "iris");
},
);
}