agent permissions: one set, tool groups included, set at agent creation
mara on #5170: "dont split caps and perms. its all perms. / dont include the now empty tool groups / nothing set -> default / also add perms to agent creation screen". - hive-sh4re: one `Permission` enum (messaging, meta, inbox, execution, web_tools, manage_root_agent) replaces `ToolGroup` and `Capability`; `lifecycle`/`forge` are gone. `Permission::default_for` is the default for an agent the swarm sets nothing for. - The record is `{ "permissions": [...] }`. Missing key, unset field or no successful read yet = default; `[]` = none; a failed read after a good one keeps the last value. - hive-agent reads its own key every 10s and builds each turn's --tools, --allowedTools and MCP config (rewritten before every turn) from it; the subagent daemon reads it on each start/continue. Agents get a read-only grant on their own key. - hive-c0re restarts an agent only when its manage_root_agent changes. The import now merges meta/capabilities.json and meta/tool-groups.json into one list per agent and deletes both; the "import pending, don't read" decision is `ImportOutcome::read_allowed`, table-tested. - swarm-controller: `GET /api/permissions` (names + default) and an optional `permissions` on `POST /api/agents`, stored before the job is queued. swarm-ui's create-agent form gets a permissions field. - Deleted: HIVE_TOOL_GROUPS and its forward to the subagent daemon, tool_groups.rs, ruth's tool-group seed, the permissions rebuild job (PermPayload/WritePermFile/perm_change), the dashboard permissions tab and its stale-entries panel. Part of #5170.
This commit is contained in:
parent
f862354e43
commit
f0844f6da3
73 changed files with 1578 additions and 2742 deletions
|
|
@ -23,7 +23,6 @@ use anyhow::Result;
|
|||
|
||||
use crate::coordinator::Coordinator;
|
||||
use crate::lifecycle::{self, AGENT_PREFIX, MANAGER_NAME};
|
||||
use crate::tool_groups;
|
||||
|
||||
/// Resolve the current rev of `hyperhive_flake`. For a path on disk we
|
||||
/// canonicalize (following symlinks) so a /etc/hyperhive → /nix/store/...
|
||||
|
|
@ -200,7 +199,6 @@ pub async fn ensure_root_agent(coord: &Arc<Coordinator>) -> Result<()> {
|
|||
let hive = coord.hive_env();
|
||||
let paths = Coordinator::agent_paths(MANAGER_NAME, runtime)?;
|
||||
lifecycle::spawn(MANAGER_NAME, &hive, &paths).await?;
|
||||
seed_manager_tool_groups();
|
||||
if let Err(e) = coord.power.set(MANAGER_NAME, crate::power::Wanted::Up) {
|
||||
tracing::warn!(error = ?e, "agent_power: set manager wanted=up failed");
|
||||
}
|
||||
|
|
@ -212,47 +210,6 @@ pub async fn ensure_root_agent(coord: &Arc<Coordinator>) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Give ruth her privileged tool groups on the one path that creates her.
|
||||
///
|
||||
/// `effective_tool_groups()` has no manager-flavour fallback, so an agent
|
||||
/// with no entry in `tool-groups.json` is an agent with no privileged
|
||||
/// tools. Ruth needs hers from her first turn, and this is the only place
|
||||
/// she is brought into existence — so it is written once, here, rather
|
||||
/// than re-checked on every hive-c0re boot.
|
||||
///
|
||||
/// Skips a name that already has an entry: a destroy+recreate under the
|
||||
/// same name must not silently reset an operator's chosen group set back
|
||||
/// to the default. An unreadable file is logged and left alone: ruth has
|
||||
/// already been spawned, and seeding stays best-effort like the write
|
||||
/// below.
|
||||
fn seed_manager_tool_groups() {
|
||||
match tool_groups::groups_for(MANAGER_NAME) {
|
||||
Ok(groups) if groups.is_empty() => {}
|
||||
Ok(_) => {
|
||||
tracing::debug!("manager tool groups already set — leaving as-is");
|
||||
return;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
error = ?e,
|
||||
"tool-groups file unreadable — not seeding ruth's tool groups"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let all_groups: Vec<String> = hive_sh4re::permissions::ToolGroup::MANAGER_DEFAULT
|
||||
.iter()
|
||||
.map(|g| <&str>::from(*g).to_owned())
|
||||
.collect();
|
||||
match tool_groups::set_groups(MANAGER_NAME, &all_groups) {
|
||||
Ok(()) => tracing::info!("seeded ruth's tool groups to MANAGER_DEFAULT (all groups)"),
|
||||
Err(e) => tracing::warn!(
|
||||
error = ?e,
|
||||
"failed to seed ruth's tool groups — she will start without privileged tools"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Boot reconcile (see the module doc): classify every agent by rev
|
||||
/// freshness + persisted `wanted` intent, submit one `Boot` DAG
|
||||
/// (hyperhive lock bump growing an in-DAG rebuild subgraph per stale
|
||||
|
|
|
|||
Loading…
Reference in a new issue