use serde::{Deserialize, Serialize};
pub use converge_pack::ContextKey;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum InvariantClass {
Structural,
Semantic,
Acceptance,
}
#[derive(Debug, Clone)]
pub struct AgentMeta {
pub name: &'static str,
pub dependencies: &'static [ContextKey],
pub fact_prefix: &'static str,
pub target_key: ContextKey,
pub description: &'static str,
}
#[derive(Debug, Clone)]
pub struct InvariantMeta {
pub name: &'static str,
pub class: InvariantClass,
pub description: &'static str,
}
pub trait Pack {
fn name(&self) -> &str;
fn agents(&self) -> &[AgentMeta];
fn invariants(&self) -> &[InvariantMeta];
}
#[derive(Debug, Clone, Default)]
pub struct PackProfile {
pub entities: &'static [&'static str],
pub required_capabilities: &'static [&'static str],
pub uses_llm: bool,
pub requires_hitl: bool,
pub handles_irreversible: bool,
pub keywords: &'static [&'static str],
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn invariant_class_serde_roundtrip() {
for class in [
InvariantClass::Structural,
InvariantClass::Semantic,
InvariantClass::Acceptance,
] {
let json = serde_json::to_string(&class).unwrap();
let back: InvariantClass = serde_json::from_str(&json).unwrap();
assert_eq!(class, back);
}
}
#[test]
fn agent_meta_fields() {
let agent = AgentMeta {
name: "test_agent",
dependencies: &[ContextKey::Seeds, ContextKey::Signals],
fact_prefix: "test:",
target_key: ContextKey::Proposals,
description: "A test agent",
};
assert_eq!(agent.name, "test_agent");
assert_eq!(agent.dependencies.len(), 2);
assert_eq!(agent.target_key, ContextKey::Proposals);
}
#[test]
fn invariant_meta_fields() {
let inv = InvariantMeta {
name: "test_invariant",
class: InvariantClass::Acceptance,
description: "Must pass",
};
assert_eq!(inv.name, "test_invariant");
assert_eq!(inv.class, InvariantClass::Acceptance);
}
#[test]
fn pack_profile_default() {
let profile = PackProfile::default();
assert!(profile.entities.is_empty());
assert!(profile.required_capabilities.is_empty());
assert!(!profile.uses_llm);
assert!(!profile.requires_hitl);
assert!(!profile.handles_irreversible);
assert!(profile.keywords.is_empty());
}
}