Watch
0
0
Fork
You've already forked hyperhive
0

hive-c0re: drop the subtree check from the scheduling verbs

The topology predicate `is_descendant_of` gated the four schedule-
managing verbs: a caller could only name a schedule owned by an agent at
or below itself in `topology.json`. Those gates now permit any requester,
so the predicate, its pure `_in` form and the `schedule_authorized`
wrapper built on it are gone rather than left returning a constant. The
other two wrappers went earlier with the verbs they served —
`require_descendant` with the lifecycle MCP verbs in 87970a8c, and
`resolve_agent_state_target` with `get_loose_ends`'s agent parameter.

`require_group(agent, "scheduling", ...)` is untouched and still fires at
dispatch for every one of the five scheduling verbs, so holding the tool
group remains the gate; what goes is the ownership restriction layered on
top of it.

The three schedule-mutating verbs keep their row lookup as a plain
existence check, so a caller naming a schedule that does not exist still
gets `not found` rather than a message from deeper in the cancel path.
`list_schedules` stops filtering per row: it would only have hidden rows
the requester may act on anyway.

Error messages, tool descriptions and docs that described the subtree
relation are reworded — a refusal message naming a topology that no
longer decides anything is worse than none.

The six `is_descendant_of_in` unit tests go with the function they test;
the permit behaviour they leave unasserted is picked up by the next
commit.

Refs #4472
This commit is contained in:
atlas 2026-09-17 19:27:15 +02:00 • committed by mara
commit 4121e11d87
8 changed files with 67 additions and 277 deletions

View file

@ -4,10 +4,10 @@
//! you are `foo`; the manager socket simply serves as `ruth`. There is no
//! privilege flag — both transports run the same [`serve`] / [`dispatch`]
//! code, and authority derives uniformly from the caller's identity:
//! topology (`is_descendant_of`) for subtree-relational verbs, capabilities
//! for hive-wide queries, and tool-group membership for the orchestration
//! verbs. `ruth` reaches every agent only as a consequence of being the
//! topology root, not via any hardcoded name match.
//! capabilities for the hive-wide queries and tool-group membership for the
//! orchestration verbs. An agent-targeting verb may name any agent, so `ruth`
//! reaches every agent exactly the way every other agent does, not via any
//! hardcoded name match.
use std::path::{Path, PathBuf};
use std::sync::Arc;
@ -87,10 +87,9 @@ pub fn start(agent: &str, socket_path: &Path, coord: Arc<Coordinator>) -> Result
/// Bind + serve the manager socket. This is now **pure transport**: it grants
/// no authority of its own — it just serves requests as `agent = MANAGER_AGENT`
/// ("ruth"), and ruth's reach comes entirely from being the topology root
/// (`is_descendant_of` covers every agent) plus the capabilities / tool-groups
/// it holds, identical to connecting on a per-agent socket — ruth uses the
/// standard per-agent runtime dir + socket, with no dedicated helpers.
/// ("ruth"), and ruth's reach comes entirely from the capabilities /
/// tool-groups it holds, identical to connecting on a per-agent socket — ruth
/// uses the standard per-agent runtime dir + socket, with no dedicated helpers.
pub fn start_manager(coord: Arc<Coordinator>) -> Result<()> {
use std::os::unix::fs::PermissionsExt as _;
let dir = crate::paths::agent_runtime_dir(crate::lifecycle::MANAGER_NAME);