Watch
0
0
Fork
You've already forked hyperhive
0

refactor(hive-c0re): drop the request_init_config tool and InitConfig approval

swarm-controller's `InitAgentConfigRepo` node already covers config-repo
creation, so this deletes a duplicate rather than a capability; old
`init_config` rows are skipped by `collect_lenient` with no migration, by
operator decision.

Refs #4398
This commit is contained in:
atlas 2026-09-14 18:50:24 +02:00
commit a3b672d1d5
31 changed files with 134 additions and 601 deletions

View file

@ -30,7 +30,7 @@ pub(crate) use config_approvals::submit_merge_config_pr;
pub(crate) use schedules::filter_ghost_schedule_targets;
pub use schedules::schedule_to_wire_public;
use config_approvals::{handle_request_init_config, handle_request_update_meta_inputs};
use config_approvals::handle_request_update_meta_inputs;
use lifecycle_handlers::{
handle_kill, handle_list_descendants, handle_restart, handle_start, handle_update,
};
@ -560,9 +560,6 @@ async fn dispatch(req: &Request, agent: &str, coord: &Arc<Coordinator>) -> Respo
Request::Kill { name } => handle_kill(coord, agent, name).await,
Request::Update { name } => handle_update(coord, agent, name),
Request::ListDescendants => handle_list_descendants(coord, agent).await,
Request::RequestInitConfig { name, description } => {
handle_request_init_config(coord, agent, name, description.clone())
}
// Agent-state queries: own subtree is free; other agents + the
// hive-wide `"*"` sweep require `QueryAgentState`.
Request::GetLooseEnds { agent: target } => {
@ -695,46 +692,6 @@ fn require_group(agent: &str, group: &str, action: &str) -> Option<Response> {
}
}
/// Topology guard for `request_init_config`, which may legitimately target a
/// child that does not exist *yet* (seeding a brand-new sub-agent's config
/// repo). The caller may act on a
/// `target` that is EITHER already in its subtree (re-init / config
/// update of an agent it owns) OR brand-new (absent from the topology
/// tree — the requester becomes its parent). A name that already
/// exists outside the caller's subtree is refused so
/// one agent can't hijack another's sub-tree.
///
/// Also re-runs the agent-name format check (a traversal / malformed name
/// could never be a descendant): a brand-new name now flows straight to
/// `submit_init_config`, which builds filesystem paths from it, so validate
/// before that.
fn require_new_child(agent: &str, target: &str, action: &str) -> Option<Response> {
if let Err(reason) = hive_types::Ident::parse(target) {
return Some(Response::Err {
message: format!("agent `{agent}` cannot {action} `{target}`: {reason}"),
});
}
// brand-new name (absent from topology) — requester becomes the parent on
// approval; allowed for any caller.
if !crate::topology::read().contains_key(target) {
return None;
}
// existing agent — allowed only if it's in the caller's subtree
// (re-init / config update of an agent the caller owns; the root owns
// every existing agent). Refuses an agent outside the caller's subtree
// so one agent can't hijack another's config.
if crate::topology::is_descendant_of(target, agent) {
None
} else {
Some(Response::Err {
message: format!(
"agent `{agent}` cannot {action} `{target}`: it already exists \
outside its subtree in the topology tree"
),
})
}
}
/// `GetLooseEnds` — read the target's loose ends. `None` / own / a subtree
/// descendant resolve freely (a parent sees its subtree, the root sees all);
/// any other named agent needs `QueryAgentState`; `"*"` is a hive-wide sweep