use std::path::{Path, PathBuf};
use std::time::Duration;
use aion_awl::{CompiledHarness, CompiledHarnessKind, CwdSource, HarnessPermission};
use aion_integrations::HarnessWorkspace;
use super::catalogue;
#[cfg(any(feature = "norn", feature = "acp"))]
use super::catalogue::HarnessKind;
type TestResult = Result<(), Box<dyn std::error::Error>>;
fn document() -> PathBuf {
PathBuf::from("/srv/flows/assistant.awl")
}
fn declared(kind: CompiledHarnessKind) -> CompiledHarness {
CompiledHarness {
concurrency: 4,
reconnect_initial_backoff: Duration::from_secs(5),
reconnect_max_backoff: Duration::from_secs(120),
reconnect_max_attempts: 100,
env_pass: vec![String::from("PATH"), String::from("HOME")],
args: Vec::new(),
kind,
}
}
fn literal(path: &str) -> CwdSource {
CwdSource::Literal(PathBuf::from(path))
}
fn acp() -> CompiledHarness {
declared(CompiledHarnessKind::Acp {
command: PathBuf::from("/usr/local/bin/claude-code-acp"),
cwd: literal("/srv/agents/workspace"),
permission: HarnessPermission::Deny,
exit_grace: Duration::from_secs(10),
})
}
fn norn() -> CompiledHarness {
declared(CompiledHarnessKind::Norn {
binary: None,
cwd: literal("/srv/agents/workspace"),
})
}
#[cfg(any(feature = "norn", feature = "acp"))]
fn declared_for(kind: HarnessKind) -> CompiledHarness {
match kind {
#[cfg(feature = "norn")]
HarnessKind::Norn => norn(),
#[cfg(feature = "acp")]
HarnessKind::Acp => acp(),
}
}
#[test]
fn a_declared_kind_resolves_against_the_adapters_this_build_links() -> TestResult {
let compiled = catalogue::compiled();
if compiled.is_empty() {
let resolved = catalogue::resolve("norn", &document())?;
assert!(
resolved.is_none(),
"a build with no adapter resolves to nothing rather than erroring, so the \
action surface is still reported"
);
return Ok(());
}
for kind in compiled {
let resolved = catalogue::resolve(kind.name(), &document())?;
assert_eq!(
resolved,
Some(kind),
"a declared kind this build links must resolve to it"
);
}
Ok(())
}
#[test]
fn an_uncompiled_harness_name_is_refused_naming_what_is_compiled_in() -> TestResult {
let compiled = catalogue::compiled();
if compiled.is_empty() {
return Ok(());
}
let Err(error) = catalogue::resolve("gemini-cli", &document()) else {
return Err("a kind this build does not carry must be refused".into());
};
let message = error.to_string();
assert!(
message.contains("gemini-cli"),
"the refusal names what was declared: {message}"
);
assert!(
message.contains("assistant.awl"),
"the refusal names the document that declared it: {message}"
);
for kind in compiled {
assert!(
message.contains(kind.name()),
"the refusal names `{}`, which this build does carry: {message}",
kind.name()
);
}
Ok(())
}
#[cfg(any(feature = "norn", feature = "acp"))]
#[test]
fn the_declared_env_pass_list_is_the_childs_whole_environment() -> TestResult {
let Some(kind) = catalogue::compiled().first().copied() else {
return Ok(());
};
let mut launch = declared_for(kind);
launch.env_pass = vec![String::from("PATH")];
let Some(resolved) = super::settings::resolve(&launch, &document())? else {
return Err("a build carrying an adapter must resolve the declared kind".into());
};
let environment = environment_of(&resolved.config);
assert!(
std::env::var_os("CARGO_PKG_NAME").is_some(),
"this test needs a variable the launching process really carries, or the \
absence assertion below proves nothing"
);
assert!(
environment.carries("PATH"),
"the declared variable IS carried, so an absent reading cannot come from an \
environment that resolved nothing: {:?}",
environment.pairs()
);
assert_eq!(
environment.declared(),
["PATH"],
"the declaration is exactly what the document wrote"
);
assert!(
!environment.carries("CARGO_PKG_NAME"),
"a variable this process really carries, and the document does not name, does \
not cross: {:?}",
environment.pairs()
);
assert!(
!environment.carries("CLAUDECODE"),
"a variable the document does not name is absent whatever this process carries"
);
Ok(())
}
#[cfg(any(feature = "norn", feature = "acp"))]
fn environment_of(config: &super::settings::HarnessConfig) -> &aion_integrations::ChildEnvironment {
match config {
#[cfg(feature = "norn")]
super::settings::HarnessConfig::Norn(norn) => &norn.environment,
#[cfg(feature = "acp")]
super::settings::HarnessConfig::Acp(acp) => &acp.environment,
}
}
#[cfg(any(feature = "norn", feature = "acp"))]
#[test]
fn an_env_pass_entry_carrying_a_value_is_refused_at_the_launch_boundary() -> TestResult {
let Some(kind) = catalogue::compiled().first().copied() else {
return Ok(());
};
let mut launch = declared_for(kind);
launch.env_pass = vec![String::from("ANTHROPIC_API_KEY=sk-live")];
let Err(error) = super::settings::resolve(&launch, &document()) else {
return Err("a KEY=VALUE entry is not a pass-through name".into());
};
let message = format!("{error:#}");
assert!(
message.contains("ANTHROPIC_API_KEY=sk-live"),
"the refusal quotes the entry: {message}"
);
assert!(
message.contains("assistant.awl"),
"the refusal names the document: {message}"
);
Ok(())
}
#[cfg(feature = "acp")]
#[test]
fn a_declared_acp_launch_reaches_the_adapter_verbatim() -> TestResult {
let mut launch = acp();
launch.args = vec![String::from("--acp")];
launch.kind = CompiledHarnessKind::Acp {
command: PathBuf::from("/opt/gemini/bin/gemini"),
cwd: literal("/srv/agents/gemini"),
permission: HarnessPermission::AllowOnce,
exit_grace: Duration::from_secs(0),
};
let Some(resolved) = super::settings::resolve(&launch, &document())? else {
return Err("this build links the acp adapter".into());
};
assert_eq!(resolved.kind, HarnessKind::Acp);
let super::settings::HarnessConfig::Acp(config) = resolved.config else {
return Err("an acp declaration must produce an acp configuration".into());
};
assert_eq!(config.command, Path::new("/opt/gemini/bin/gemini"));
assert_eq!(config.args, vec![String::from("--acp")]);
assert_eq!(
config.workspace,
HarnessWorkspace::Fixed(PathBuf::from("/srv/agents/gemini"))
);
assert_eq!(
config.permission,
aion_integration_acp::PermissionPolicy::AllowOnce
);
assert_eq!(
config.exit_grace,
Duration::ZERO,
"zero is a legitimate grace and means close stdin, then kill at once"
);
Ok(())
}
#[cfg(feature = "acp")]
#[test]
fn each_permission_spelling_resolves_to_the_adapters_policy() -> TestResult {
for (declared, expected) in [
(
HarnessPermission::Deny,
aion_integration_acp::PermissionPolicy::Deny,
),
(
HarnessPermission::AllowOnce,
aion_integration_acp::PermissionPolicy::AllowOnce,
),
] {
let mut launch = acp();
launch.kind = CompiledHarnessKind::Acp {
command: PathBuf::from("/usr/local/bin/claude-code-acp"),
cwd: literal("/srv/agents/workspace"),
permission: declared,
exit_grace: Duration::from_secs(1),
};
let Some(resolved) = super::settings::resolve(&launch, &document())? else {
return Err("this build links the acp adapter".into());
};
let super::settings::HarnessConfig::Acp(config) = resolved.config else {
return Err("an acp declaration must produce an acp configuration".into());
};
assert_eq!(
config.permission, expected,
"the document's policy and the adapter's must be one decision, not two"
);
}
Ok(())
}
#[cfg(feature = "norn")]
#[test]
fn the_norn_binary_is_optional_and_the_absence_takes_the_adapters_own_default() -> TestResult {
let Some(resolved) = super::settings::resolve(&norn(), &document())? else {
return Err("this build links the norn adapter".into());
};
let super::settings::HarnessConfig::Norn(config) = resolved.config else {
return Err("a norn declaration must produce a norn configuration".into());
};
assert_eq!(
config.binary, None,
"an omitted `binary` takes the adapter's own documented `norn`-on-PATH default, \
which is the library's value rather than one invented at this boundary"
);
let mut declared_binary = norn();
declared_binary.kind = CompiledHarnessKind::Norn {
binary: Some(PathBuf::from("/opt/norn/bin/norn")),
cwd: literal("/srv/agents/workspace"),
};
let Some(resolved) = super::settings::resolve(&declared_binary, &document())? else {
return Err("this build links the norn adapter".into());
};
let super::settings::HarnessConfig::Norn(config) = resolved.config else {
return Err("a norn declaration must produce a norn configuration".into());
};
assert_eq!(
config.binary.as_deref(),
Some(Path::new("/opt/norn/bin/norn"))
);
Ok(())
}
#[cfg(feature = "norn")]
#[test]
fn a_workspace_rooted_cwd_is_expanded_against_this_boxs_own_root() -> TestResult {
let scratch = tempfile::tempdir()?;
let root = scratch.path().join("clones");
let workspace = aion_server::worker::WorkspaceRoot::from_resolution(Ok(root.clone()));
let mut launch = norn();
launch.kind = CompiledHarnessKind::Norn {
binary: None,
cwd: literal("{workspace_root}/assistant"),
};
let Some(resolved) = super::settings::resolve_against(&launch, &document(), &workspace)? else {
return Err("this build links the norn adapter".into());
};
let super::settings::HarnessConfig::Norn(config) = resolved.config else {
return Err("a norn declaration must produce a norn configuration".into());
};
assert_eq!(
config.workspace,
HarnessWorkspace::Fixed(root.join("assistant")),
"the placeholder must be replaced by THIS box's root, so one shipped document is \
correct on every machine that runs it"
);
assert!(
config.workspace.fixed().is_some_and(Path::is_absolute),
"expansion does not soften the absolute rule; it is what makes it satisfiable for a \
document that cannot name any one machine's path"
);
Ok(())
}
#[cfg(feature = "norn")]
#[test]
fn the_reported_launch_directory_is_the_one_the_child_will_stand_in() -> TestResult {
let scratch = tempfile::tempdir()?;
let root = scratch.path().join("clones");
let workspace = aion_server::worker::WorkspaceRoot::from_resolution(Ok(root.clone()));
let mut launch = norn();
launch.kind = CompiledHarnessKind::Norn {
binary: None,
cwd: literal("{workspace_root}/assistant"),
};
let Some(resolved) = super::settings::resolve_against(&launch, &document(), &workspace)? else {
return Err("this build links the norn adapter".into());
};
let reported = resolved.launch_directory_report();
let super::settings::HarnessConfig::Norn(config) = resolved.config else {
return Err("a norn declaration must produce a norn configuration".into());
};
assert_eq!(
Some(Path::new(&reported)),
config.workspace.fixed(),
"the operator's report and the adapter's spawn must read ONE value — a report the \
child can disagree with is worth less than no report"
);
assert_eq!(
Path::new(&reported),
root.join("assistant"),
"and that one value is the EXPANDED directory, not the placeholder the document wrote"
);
Ok(())
}
#[cfg(feature = "norn")]
#[test]
fn a_bound_cwd_resolves_to_the_parameter_the_job_will_carry() -> TestResult {
let scratch = tempfile::tempdir()?;
let workspace =
aion_server::worker::WorkspaceRoot::from_resolution(Ok(scratch.path().join("clones")));
let mut launch = norn();
launch.kind = CompiledHarnessKind::Norn {
binary: None,
cwd: CwdSource::Bound(String::from("repo")),
};
let Some(resolved) = super::settings::resolve_against(&launch, &document(), &workspace)? else {
return Err("this build links the norn adapter".into());
};
let reported = resolved.launch_directory_report();
assert_eq!(
resolved.launch_workspace(),
&HarnessWorkspace::PerRun(String::from("repo"))
);
assert!(
reported.contains("repo"),
"the startup line names the parameter each job's directory arrives in: {reported}"
);
assert_eq!(
resolved.launch_workspace().fixed(),
None,
"a per-run workspace has no directory to report before a job exists, and must not \
invent one — the whole hazard is an agent standing somewhere nobody chose"
);
Ok(())
}
#[cfg(feature = "norn")]
#[test]
fn a_cwd_that_cannot_be_absolute_is_refused_at_the_composition_root() -> TestResult {
let scratch = tempfile::tempdir()?;
let workspace =
aion_server::worker::WorkspaceRoot::from_resolution(Ok(scratch.path().join("clones")));
for written in ["agents/workspace", "agents/{workspace_root}"] {
let mut launch = norn();
launch.kind = CompiledHarnessKind::Norn {
binary: None,
cwd: literal(written),
};
let Err(error) = super::settings::resolve_against(&launch, &document(), &workspace) else {
return Err(
format!("`cwd \"{written}\"` cannot name one place on every launch").into(),
);
};
let message = format!("{error:#}");
assert!(
message.contains("not an absolute path"),
"the refusal names the rule that was broken: {message}"
);
assert!(
message.contains(written),
"the refusal quotes what the document wrote: {message}"
);
assert!(
message.contains("assistant.awl"),
"the refusal names the document: {message}"
);
}
Ok(())
}
#[cfg(feature = "norn")]
#[test]
fn a_workspace_rooted_cwd_on_a_box_with_no_root_refuses_before_anything_spawns() -> TestResult {
let workspace = aion_server::worker::WorkspaceRoot::from_resolution(Err(
aion_server::worker::WorkspaceRootError::Unresolvable {
reason: String::from("AION_HOME must not be empty"),
},
));
let mut launch = norn();
launch.kind = CompiledHarnessKind::Norn {
binary: None,
cwd: literal("{workspace_root}/assistant"),
};
let Err(error) = super::settings::resolve_against(&launch, &document(), &workspace) else {
return Err("a box that cannot say where its workspaces live cannot launch there".into());
};
let message = format!("{error:#}");
assert!(
message.contains("{workspace_root}/assistant"),
"the refusal quotes what the document wrote: {message}"
);
assert!(
message.contains("AION_HOME must not be empty"),
"the refusal carries the resolution's own reason, so the operator knows what to fix: \
{message}"
);
assert!(
message.contains("assistant.awl"),
"the refusal names the document: {message}"
);
let Some(resolved) = super::settings::resolve_against(&norn(), &document(), &workspace)? else {
return Err("this build links the norn adapter".into());
};
let super::settings::HarnessConfig::Norn(config) = resolved.config else {
return Err("a norn declaration must produce a norn configuration".into());
};
assert_eq!(
config.workspace,
HarnessWorkspace::Fixed(PathBuf::from("/srv/agents/workspace")),
"a document that names its own path asks this box for nothing"
);
Ok(())
}
#[cfg(feature = "norn")]
#[test]
fn the_declared_argv_reaches_the_child_expanded_and_in_order() -> TestResult {
use aion_core::{ActivityId, ContentType, Payload, RunId, WorkflowId};
use aion_integrations::AgentRunSpec;
let mut launch = norn();
launch.args = [
"--workspace-root",
"/tmp/{workflow_id}/repo",
"-C",
"/tmp/{workflow_id}/repo",
"--session-id",
"{workflow_id}-{activity_type}",
"--resume-if-exists",
"--account",
"default",
"--fast",
]
.map(str::to_owned)
.to_vec();
launch.env_pass = vec![String::from("PATH")];
let Some(resolved) = super::settings::resolve(&launch, &document())? else {
return Err("this build links the norn adapter".into());
};
let super::settings::HarnessConfig::Norn(config) = resolved.config else {
return Err("a norn declaration must produce a norn configuration".into());
};
let harness = super::compose::build_norn(&config);
let workflow_id = WorkflowId::new_v4();
let spec = AgentRunSpec::new(
workflow_id.clone(),
RunId::new_v4(),
ActivityId::from_sequence_position(1),
1,
"assistant",
Payload::new(ContentType::Json, b"\"prompt\"".to_vec()),
);
let invocation = harness.invocation(&spec)?;
let clone = format!("/tmp/{workflow_id}/repo");
assert_eq!(
invocation.argv,
vec![
String::from("--protocol"),
String::from("jsonrpc"),
String::from("--workspace-root"),
clone.clone(),
String::from("-C"),
clone,
String::from("--session-id"),
format!("{workflow_id}-assistant"),
String::from("--resume-if-exists"),
String::from("--account"),
String::from("default"),
String::from("--fast"),
],
"the child argv must be the document's arguments, in order, with the \
run-identity placeholders expanded"
);
let Some(environment) = invocation.declared_environment else {
return Err("the document's env_pass must reach the child as a declaration".into());
};
assert_eq!(
environment.declared(),
["PATH"],
"the declaration reaches the previewable invocation, so what this root composed \
is what the spawn performs"
);
Ok(())
}
#[test]
fn the_document_vocabulary_and_the_catalogue_vocabulary_are_one_table() {
let language = [aion_awl::HARNESS_KIND_ACP, aion_awl::HARNESS_KIND_NORN];
for harness in catalogue::compiled() {
assert!(
language.contains(&harness.name()),
"the catalogue carries `{}`, which no document can declare",
harness.name()
);
}
}
#[test]
fn each_harness_advertises_its_adapters_published_capabilities() {
for harness in catalogue::compiled() {
let advertised = harness.registration_capabilities();
let published = match harness.name() {
#[cfg(feature = "norn")]
"norn" => aion_integration_norn::registration_capabilities(),
#[cfg(feature = "acp")]
"acp" => aion_integration_acp::registration_capabilities(),
other => unreachable!("unknown harness `{other}`"),
};
assert_eq!(
advertised, published,
"the root must publish the ADAPTER's set, never one of its own"
);
}
}
#[test]
fn a_build_with_no_harness_advertises_the_empty_set() {
assert_eq!(
super::registration_capabilities(None),
aion_core::InterventionCapabilities::none(),
"an empty advertisement is first-class: a build with no harness supports no \
interventions and the console offers none"
);
}
#[cfg(all(any(feature = "norn", feature = "acp"), feature = "liminal-transport"))]
#[test]
fn every_compiled_harness_composes() {
for harness in catalogue::compiled() {
let config = harness.test_config();
let advertised = aion_worker::AgentHarnessConfig::new(
super::compose::build(&config),
[String::from("review")],
catalogue::registration_capabilities(Some(harness)),
);
assert!(
advertised.agent_activity_types().contains("review"),
"`{}` must compose into a harness the worker binds",
harness.name()
);
}
}