feat(#2302): thread &Ident through agent path builders

This commit is contained in:
damocles 2026-07-20 00:22:06 +02:00 committed by mara
commit bf644cc126
23 changed files with 168 additions and 85 deletions

View file

@ -195,7 +195,9 @@ pub(crate) fn submit_init_config(
parent: Option<&str>,
description: Option<String>,
) -> anyhow::Result<i64> {
let proposed_dir = crate::coordinator::Coordinator::agent_proposed_dir(name);
let agent = hive_host_sock::Ident::parse(name)
.map_err(|e| anyhow::anyhow!("invalid agent name {name:?}: {e}"))?;
let proposed_dir = crate::coordinator::Coordinator::agent_proposed_dir(&agent);
if proposed_dir.join(".git").exists() {
anyhow::bail!(
"proposed config repo for '{name}' already exists at {} - \

View file

@ -425,13 +425,16 @@ async fn handle_get_agent_meta(
// the OS level. Validate it before any path is built. The `None` default
// (`target == agent`) is the caller's own authenticated name, already
// valid — but validating unconditionally is simplest and harmless.
if let Err(reason) = hive_host_sock::Ident::parse(target) {
return hive_agent_sock::Response::Err {
message: format!("get_agent_meta: invalid agent name {target:?}: {reason}"),
};
}
let target_id = match hive_host_sock::Ident::parse(target) {
Ok(id) => id,
Err(reason) => {
return hive_agent_sock::Response::Err {
message: format!("get_agent_meta: invalid agent name {target:?}: {reason}"),
};
}
};
let (status_text, status_set_at, running) =
crate::container_view::read_agent_status_live(target).await;
crate::container_view::read_agent_status_live(&target_id).await;
let (hive_name, swarm_name) = crate::container_view::hive_swarm_names();
hive_agent_sock::Response::AgentMeta {
name: target.to_owned(),
@ -448,7 +451,7 @@ async fn handle_get_agent_meta(
// another on a public matrix instance. The `Ident::parse` gate
// above is what closes the real vector here (path traversal via `../`
// in an agent-supplied name).
matrix_accounts: read_agent_matrix_identities(target),
matrix_accounts: read_agent_matrix_identities(&target_id),
}
}
@ -458,7 +461,7 @@ async fn handle_get_agent_meta(
/// or the daemon not up yet) yields an empty list. The `MatrixIdentity`
/// serde shape matches the snapshot entries; the snapshot's `live` field is
/// ignored (only live accounts are written).
fn read_agent_matrix_identities(agent: &str) -> Vec<hive_sh4re::MatrixIdentity> {
fn read_agent_matrix_identities(agent: &hive_host_sock::Ident) -> Vec<hive_sh4re::MatrixIdentity> {
let path = Coordinator::agent_notes_dir(agent).join("matrix-accounts.json");
std::fs::read_to_string(&path)
.ok()
@ -1112,8 +1115,12 @@ pub(crate) fn handle_send(
};
}
if resolved != hive_sh4re::OPERATOR_RECIPIENT {
let state_root = crate::paths::agent_state_dir(&resolved);
if !state_root.exists() {
// A name that doesn't parse as an Ident can't be a local agent, so
// it collapses into the same "unknown recipient" error as a valid
// name with no state dir.
let exists = hive_host_sock::Ident::parse(&resolved)
.is_ok_and(|id| crate::paths::agent_state_dir(&id).exists());
if !exists {
return Response::Err {
message: format!(
"send failed: unknown recipient `{resolved}` \