Conflicts
Conflict handling in `agentfs-mirror` — typed conflict cases, resolution strategies, and per-session conflict journals.
Purpose
Mirror engine with conflict resolution, sparse sync, progress reporting, checkpoint plans, stats, and watchers.
This page follows the real source shape for Agentfs Mirror and explains the workflow a developer is likely to use first.
Developer workflow
Start from the smallest constructor or builder, perform one meaningful operation, inspect the returned state, then add the relevant policy, storage, or network integration. The examples below should be expanded whenever the crate API changes.
Choosing a ConflictResolver is a product decision. "Last-writer-wins" loses data; "manual review" stalls sync until a human acts. Pick the strategy that matches your data semantics — there is no universally correct default.
Primary types to know
Checkpoint— local/agentfs-mirror/src/sync.rsConflict— local/agentfs-mirror/src/conflict.rsConflictResolver— local/agentfs-mirror/src/conflict.rsFileInfo— local/agentfs-mirror/src/conflict.rsFileStats— local/agentfs-mirror/src/stats.rsMirror— local/agentfs-mirror/src/mirror.rsMirrorOptions— local/agentfs-mirror/src/options.rsMirrorWatcher— local/agentfs-mirror/src/watcher.rsPlan— local/agentfs-mirror/src/sync.rsPlanOp— local/agentfs-mirror/src/sync.rsProgressReporter— local/agentfs-mirror/src/progress.rsSparseOptions— local/agentfs-mirror/src/sparse.rs
Example shape
use agentfs_mirror::{ConflictResolution, ConflictResolver, ConflictStrategy};
use agentfs_mirror::conflict::{Conflict, ConflictType, FileInfo};
use chrono::Utc;
use std::path::PathBuf;
use weave_identity::Identity;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Pick a strategy. The resolver evaluates each Conflict the SyncEngine
// produces and returns a ConflictResolution that the engine then applies.
let resolver = ConflictResolver::new(ConflictStrategy::NewerWins);
let owner = Identity::agent_from_public_key(vec![0u8; 32], Some("local"))?;
let conflict = Conflict {
path: PathBuf::from("/docs/README.md"),
source_info: FileInfo {
size: 1024,
mtime: Utc::now(),
owner: owner.clone(),
hash: Some("source-hash".into()),
},
target_info: FileInfo {
size: 1000,
mtime: Utc::now() - chrono::Duration::seconds(60),
owner,
hash: Some("target-hash".into()),
},
conflict_type: ConflictType::BothModified,
};
let resolution = resolver.resolve(&conflict).await;
assert_eq!(resolution, ConflictResolution::UseSource);
println!("strategy resolved BothModified -> {:?}", resolution);
Ok(())
}