WeaveDocs
Agentfs Mirror

Sparse Sync

Sparse sync in `agentfs-mirror` — partial replication with checkpoint plans and progress tracking.

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.

Primary types to know

  • Checkpoint — local/agentfs-mirror/src/sync.rs
  • Conflict — local/agentfs-mirror/src/conflict.rs
  • ConflictResolver — local/agentfs-mirror/src/conflict.rs
  • FileInfo — local/agentfs-mirror/src/conflict.rs
  • FileStats — local/agentfs-mirror/src/stats.rs
  • Mirror — local/agentfs-mirror/src/mirror.rs
  • MirrorOptions — local/agentfs-mirror/src/options.rs
  • MirrorWatcher — local/agentfs-mirror/src/watcher.rs
  • Plan — local/agentfs-mirror/src/sync.rs
  • PlanOp — local/agentfs-mirror/src/sync.rs
  • ProgressReporter — local/agentfs-mirror/src/progress.rs
  • SparseOptions — local/agentfs-mirror/src/sparse.rs

Example shape

use agentfs_mirror::{SparseOptions, SparseSync};
use std::path::{Path, PathBuf};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // SparseSync filters which paths the mirror processes — useful for narrowing
    // a multi-GB drive to a working set without touching unrelated trees.
    let options = SparseOptions {
        paths: vec![PathBuf::from("/docs"), PathBuf::from("/configs")],
        include_deps: true,
        max_depth: Some(4),
        include_patterns: vec!["*.md".into(), "*.toml".into()],
        exclude_patterns: vec!["**/target/**".into()],
        min_size: Some(64),
        max_size: Some(10 * 1024 * 1024),
        ..SparseOptions::default()
    };

    let mut sync = SparseSync::new(options);

    let candidates = [
        Path::new("/docs/intro.md"),
        Path::new("/configs/server.toml"),
        Path::new("/secrets/private.key"),
    ];
    for path in candidates {
        if sync.should_sync(path) {
            sync.mark_synced(path.to_path_buf());
        }
    }

    println!(
        "synced_count={} target_sample_synced={}",
        candidates.iter().filter(|p| sync.is_synced(p)).count(),
        sync.is_synced(Path::new("/docs/intro.md")),
    );
    Ok(())
}