use meld::agent::{AgentIdentity, AgentRegistry, AgentRole};
use meld::api::{ContextApi, ContextView};
use meld::concurrency::NodeLockManager;
use meld::context::frame::{Basis, Frame, FrameStorage};
use meld::error::ApiError;
use meld::heads::HeadIndex;
use meld::metadata::frame_key_registry::{
KEY_CONTEXT_DIGEST, KEY_MODEL, KEY_PROMPT_DIGEST, KEY_PROMPT_LINK_ID, KEY_PROVIDER,
KEY_PROVIDER_TYPE,
};
use meld::metadata::frame_write_contract::{METADATA_PER_KEY_MAX_BYTES, METADATA_TOTAL_MAX_BYTES};
use meld::prompt_context::PromptContextArtifactStorage;
use meld::store::{NodeRecord, NodeType, SledNodeRecordStore};
use meld::types::NodeID;
use meld::views::OrderingPolicy;
use std::collections::HashMap;
use std::sync::Arc;
use std::thread;
use tempfile::TempDir;
fn create_test_api() -> (ContextApi, TempDir) {
let temp_dir = TempDir::new().unwrap();
let store_path = temp_dir.path().join("store");
let frame_storage_path = temp_dir.path().join("frames");
let artifact_storage_path = temp_dir.path().join("artifacts");
let node_store = Arc::new(SledNodeRecordStore::new(&store_path).unwrap());
let frame_storage = Arc::new(FrameStorage::new(&frame_storage_path).unwrap());
let prompt_context_storage =
Arc::new(PromptContextArtifactStorage::new(&artifact_storage_path).unwrap());
let head_index = Arc::new(parking_lot::RwLock::new(HeadIndex::new()));
let agent_registry = Arc::new(parking_lot::RwLock::new(AgentRegistry::new()));
let provider_registry = Arc::new(parking_lot::RwLock::new(
meld::provider::ProviderRegistry::new(),
));
let lock_manager = Arc::new(NodeLockManager::new());
let api = ContextApi::new(
node_store,
frame_storage,
head_index,
prompt_context_storage,
agent_registry,
provider_registry,
lock_manager,
);
(api, temp_dir)
}
fn create_test_node_record(node_id: NodeID) -> NodeRecord {
use std::path::PathBuf;
NodeRecord {
node_id,
path: PathBuf::from("/test/file.txt"),
node_type: NodeType::File {
size: 100,
content_hash: [0u8; 32],
},
children: vec![],
parent: None,
frame_set_root: None,
metadata: Default::default(),
tombstoned_at: None,
}
}
fn required_frame_metadata(agent_id: &str) -> HashMap<String, String> {
let mut metadata = HashMap::new();
metadata.insert("agent_id".to_string(), agent_id.to_string());
metadata.insert(KEY_PROVIDER.to_string(), "provider-a".to_string());
metadata.insert(KEY_MODEL.to_string(), "model-a".to_string());
metadata.insert(KEY_PROVIDER_TYPE.to_string(), "local".to_string());
metadata.insert(KEY_PROMPT_DIGEST.to_string(), "prompt-digest-a".to_string());
metadata.insert(
KEY_CONTEXT_DIGEST.to_string(),
"context-digest-a".to_string(),
);
metadata.insert(KEY_PROMPT_LINK_ID.to_string(), "prompt-link-a".to_string());
metadata
}
#[test]
fn test_get_node_deterministic() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [1u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
let agent = AgentIdentity::new("writer-1".to_string(), AgentRole::Writer);
registry.register(agent);
}
let basis = Basis::Node(node_id);
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
for i in 0..5 {
let content = format!("content {}", i).into_bytes();
let metadata = required_frame_metadata(&agent_id);
let frame = Frame::new(
basis.clone(),
content,
frame_type.clone(),
agent_id.clone(),
metadata,
)
.unwrap();
api.put_frame(node_id, frame, agent_id.clone()).unwrap();
}
let view = ContextView {
max_frames: 100,
ordering: OrderingPolicy::Recency,
filters: vec![],
};
let context1 = api.get_node(node_id, view.clone()).unwrap();
let context2 = api.get_node(node_id, view).unwrap();
assert_eq!(context1.node_id, context2.node_id);
assert_eq!(context1.frames.len(), context2.frames.len());
assert_eq!(context1.frame_count, context2.frame_count);
let frame_ids1: Vec<_> = context1.frames.iter().map(|f| f.frame_id).collect();
let frame_ids2: Vec<_> = context2.frames.iter().map(|f| f.frame_id).collect();
assert_eq!(frame_ids1, frame_ids2);
}
#[test]
fn test_put_frame_deterministic() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [1u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
let agent = AgentIdentity::new("writer-1".to_string(), AgentRole::Writer);
registry.register(agent);
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let metadata = HashMap::new();
let frame = Frame::new(
basis.clone(),
content.clone(),
frame_type.clone(),
agent_id.clone(),
metadata.clone(),
)
.unwrap();
let frame_id1 = frame.frame_id;
let frame2 = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let frame_id2 = frame2.frame_id;
assert_eq!(frame_id1, frame_id2);
}
#[test]
fn test_concurrent_get_node() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [1u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
let agent = AgentIdentity::new("writer-1".to_string(), AgentRole::Writer);
registry.register(agent);
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let metadata = required_frame_metadata(&agent_id);
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
api.put_frame(node_id, frame, agent_id).unwrap();
let api = Arc::new(api);
let mut handles = vec![];
let success_count = Arc::new(std::sync::atomic::AtomicUsize::new(0));
for _ in 0..10 {
let api = api.clone();
let success_count = success_count.clone();
let handle = thread::spawn(move || {
let view = ContextView {
max_frames: 100,
ordering: OrderingPolicy::Recency,
filters: vec![],
};
let result = api.get_node(node_id, view);
if result.is_ok() {
success_count.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(success_count.load(std::sync::atomic::Ordering::SeqCst), 10);
}
#[test]
fn test_concurrent_put_frame() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [1u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
for i in 0..5 {
let agent = AgentIdentity::new(format!("writer-{}", i), AgentRole::Writer);
registry.register(agent);
}
}
let api = Arc::new(api);
let mut handles = vec![];
let success_count = Arc::new(std::sync::atomic::AtomicUsize::new(0));
for i in 0..5 {
let api = api.clone();
let success_count = success_count.clone();
let agent_id = format!("writer-{}", i);
let frame_type = format!("test-{}", i); let handle = thread::spawn(move || {
let basis = Basis::Node(node_id);
let content = format!("content from {}", agent_id).into_bytes();
let metadata = required_frame_metadata(&agent_id);
let frame = Frame::new(
basis,
content,
frame_type.clone(),
agent_id.clone(),
metadata,
)
.unwrap();
let result = api.put_frame(node_id, frame, agent_id);
if result.is_ok() {
success_count.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(success_count.load(std::sync::atomic::Ordering::SeqCst), 5);
let view = ContextView {
max_frames: 100,
ordering: OrderingPolicy::Recency,
filters: vec![],
};
let context = api.get_node(node_id, view).unwrap();
assert_eq!(context.frames.len(), 5);
}
#[test]
fn test_error_handling_node_not_found() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [1u8; 32];
let view = ContextView {
max_frames: 100,
ordering: OrderingPolicy::Recency,
filters: vec![],
};
let result = api.get_node(node_id, view);
assert!(result.is_err());
match result {
Err(ApiError::NodeNotFound(id)) => assert_eq!(id, node_id),
_ => panic!("Expected NodeNotFound error"),
}
}
#[test]
fn test_error_handling_unauthorized() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [1u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
let agent = AgentIdentity::new("reader-1".to_string(), AgentRole::Reader);
registry.register(agent);
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "reader-1".to_string();
let metadata = HashMap::new();
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(result.is_err());
match result {
Err(ApiError::Unauthorized(_)) => {}
_ => panic!("Expected Unauthorized error"),
}
}
#[test]
fn test_error_handling_invalid_frame_basis() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [1u8; 32];
let other_node_id: NodeID = [2u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
let agent = AgentIdentity::new("writer-1".to_string(), AgentRole::Writer);
registry.register(agent);
}
let basis = Basis::Node(other_node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let metadata = HashMap::new();
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(result.is_err());
match result {
Err(ApiError::InvalidFrame(_)) => {}
_ => panic!("Expected InvalidFrame error"),
}
}
#[test]
fn test_put_frame_rejects_non_frame_metadata_key() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [3u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
registry.register(AgentIdentity::new(
"writer-1".to_string(),
AgentRole::Writer,
));
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let mut metadata = HashMap::new();
metadata.insert("leaked_key".to_string(), "value".to_string());
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(matches!(
result,
Err(ApiError::FrameMetadataUnknownKey { .. })
));
}
#[test]
fn test_put_frame_rejects_forbidden_metadata_key() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [4u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
registry.register(AgentIdentity::new(
"writer-1".to_string(),
AgentRole::Writer,
));
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let mut metadata = HashMap::new();
metadata.insert("raw_prompt".to_string(), "raw prompt data".to_string());
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(matches!(
result,
Err(ApiError::FrameMetadataForbiddenKey { .. })
));
}
#[test]
fn test_put_frame_rejects_forbidden_raw_context_metadata_key() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [9u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
registry.register(AgentIdentity::new(
"writer-1".to_string(),
AgentRole::Writer,
));
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let mut metadata = HashMap::new();
metadata.insert("raw_context".to_string(), "raw context data".to_string());
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(matches!(
result,
Err(ApiError::FrameMetadataForbiddenKey { .. })
));
}
#[test]
fn test_put_frame_rejects_prompt_metadata_key() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [10u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
registry.register(AgentIdentity::new(
"writer-1".to_string(),
AgentRole::Writer,
));
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let mut metadata = HashMap::new();
metadata.insert("prompt".to_string(), "compat prompt".to_string());
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(matches!(
result,
Err(ApiError::FrameMetadataForbiddenKey { .. })
));
}
#[test]
fn test_put_frame_rejects_per_key_metadata_budget_overflow() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [5u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
registry.register(AgentIdentity::new(
"writer-1".to_string(),
AgentRole::Writer,
));
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let mut metadata = required_frame_metadata(&agent_id);
metadata.insert(
"provider".to_string(),
"x".repeat(METADATA_PER_KEY_MAX_BYTES + 1),
);
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(matches!(
result,
Err(ApiError::FrameMetadataPerKeyBudgetExceeded { .. })
));
}
#[test]
fn test_put_frame_rejects_total_metadata_budget_overflow() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [6u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
registry.register(AgentIdentity::new(
"writer-1".to_string(),
AgentRole::Writer,
));
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let per_key = (METADATA_TOTAL_MAX_BYTES / 6).max(1);
let mut metadata = required_frame_metadata(&agent_id);
metadata.insert("provider".to_string(), "p".repeat(per_key));
metadata.insert("model".to_string(), "m".repeat(per_key));
metadata.insert("provider_type".to_string(), "t".repeat(per_key));
metadata.insert("prompt_digest".to_string(), "d".repeat(per_key));
metadata.insert("context_digest".to_string(), "c".repeat(per_key));
metadata.insert("prompt_link_id".to_string(), "l".repeat(per_key));
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(matches!(
result,
Err(ApiError::FrameMetadataTotalBudgetExceeded { .. })
));
}
#[test]
fn test_put_frame_rejects_missing_required_metadata_key() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [7u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
registry.register(AgentIdentity::new(
"writer-1".to_string(),
AgentRole::Writer,
));
}
let basis = Basis::Node(node_id);
let content = b"test content".to_vec();
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let mut metadata = required_frame_metadata(&agent_id);
metadata.remove(KEY_CONTEXT_DIGEST);
let frame = Frame::new(basis, content, frame_type, agent_id.clone(), metadata).unwrap();
let result = api.put_frame(node_id, frame, agent_id);
assert!(matches!(
result,
Err(ApiError::FrameMetadataMissingRequiredKey { .. })
));
}
#[test]
fn test_put_frame_rejects_mutability_transition_for_attested_key() {
let (api, _temp_dir) = create_test_api();
let node_id: NodeID = [8u8; 32];
let node_record = create_test_node_record(node_id);
api.node_store().put(&node_record).unwrap();
{
let mut registry = api.agent_registry().write();
registry.register(AgentIdentity::new(
"writer-1".to_string(),
AgentRole::Writer,
));
}
let basis = Basis::Node(node_id);
let frame_type = "test".to_string();
let agent_id = "writer-1".to_string();
let metadata_a = required_frame_metadata(&agent_id);
let frame_a = Frame::new(
basis.clone(),
b"first".to_vec(),
frame_type.clone(),
agent_id.clone(),
metadata_a,
)
.unwrap();
api.put_frame(node_id, frame_a, agent_id.clone()).unwrap();
let mut metadata_b = required_frame_metadata(&agent_id);
metadata_b.insert(KEY_MODEL.to_string(), "model-b".to_string());
let frame_b = Frame::new(
basis,
b"second".to_vec(),
frame_type,
agent_id.clone(),
metadata_b,
)
.unwrap();
let result = api.put_frame(node_id, frame_b, agent_id);
assert!(matches!(
result,
Err(ApiError::FrameMetadataMutabilityViolation { .. })
));
}
#[test]
fn test_runtime_write_paths_use_shared_put_frame_boundary() {
let queue_source = include_str!("../../src/context/queue.rs");
let orchestration_source = include_str!("../../src/context/generation/orchestration.rs");
let adapter_source = include_str!("../../src/agent/context_access/context_api.rs");
assert!(!queue_source.contains("frame_storage().store("));
assert!(!queue_source.contains("frame_storage.store("));
assert!(!orchestration_source.contains("frame_storage().store("));
assert!(!orchestration_source.contains("frame_storage.store("));
assert!(!adapter_source.contains("frame_storage().store("));
assert!(!adapter_source.contains("frame_storage.store("));
assert!(orchestration_source.contains("api.put_frame("));
assert!(adapter_source.contains("self.api.put_frame("));
}