use lys_pass::{Mode, Right};
pub(super) fn gamma_sender(holder: &str) -> Vec<Right> {
if holder == "gamma" {
return Vec::new();
}
let right = |kind: &str, id: &str, action: &str| Right {
resource: lys_pass::rights::Resource {
kind: kind.to_owned(),
id: id.to_owned(),
},
actions: vec![action.to_owned()],
mode: Mode::Outright,
grant: "agt-fixture".to_owned(),
};
vec![
right("liminal.subject", "agents.gamma.inbox", "publish"),
right("liminal.agent", "gamma", "message"),
]
}
#[derive(Debug)]
pub(super) struct AgentPlacement;
impl liminal_server::services::lifecycle::Placer for AgentPlacement {
fn place(
&self,
_operation: &str,
child: (&str, &str),
parent: (&str, &str),
) -> Result<(), String> {
if child.1.is_empty()
|| parent.1.is_empty()
|| !matches!(child.0, "liminal.agent" | "liminal.subject")
{
return Err("fixture placement refused".into());
}
Ok(())
}
}
pub(super) fn provision_agents(
services: &liminal_server::server::connection::LiminalConnectionServices,
) -> super::channel_test_support::TestResult {
use liminal_server::agents::records::{AgentAct, AgentEvent, AgentHarness, AgentSpec};
use liminal_server::server::connection::ConnectionServices;
let agents = services.agents().ok_or("fixture agents missing")?;
for name in ["alpha", "beta"] {
let words = serde_json::to_string(&AgentAct {
name: name.into(),
holder: "fixture-person".into(),
owner: "fixture-person".into(),
at_ms: 1,
change: AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose: "Exchange contract fixture.".into(),
service: None,
}),
})?;
let draft = lys_pass::drafts::ApprovedDraft {
id: format!("create-{name}"),
app: "liminal".into(),
grant: "fixture-approved".into(),
target: lys_pass::Target::new("liminal.agent", name, "create_agent")?,
request_digest: lys_pass::drafts::request_digest(&words),
approved_by: vec!["fixture-owner".into()],
mode: lys_pass::Mode::ByDraft,
words,
};
agents.execute_approved(&draft)?;
services.agent_created(name)?;
}
Ok(())
}