feat(agent): add ssh_scheduler + update README with diff, SshSyncBackend, test count
- ssh_scheduler() convenience constructor mirrors tcp_scheduler for SSH backend - Re-exported from clawsync_agent crate root - README: diff command section, SshSyncBackend library usage table + example, updated crate interdependency description, test count 617→644 Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
11f946a608
commit
40994eaabe
@@ -163,7 +163,7 @@ crates/
|
|||||||
clawsync-onion/ Packet differ/merger, IBLT sketch, Merkle tree, ClawSyncManifest
|
clawsync-onion/ Packet differ/merger, IBLT sketch, Merkle tree, ClawSyncManifest
|
||||||
clawsync-hdf5/ Dataset-level manifest, differ, patcher (HDF5-aware sync)
|
clawsync-hdf5/ Dataset-level manifest, differ, patcher (HDF5-aware sync)
|
||||||
clawsync-transport/ TCP, QUIC (quinn 0.11/TLS 1.3), length-prefixed wire protocol
|
clawsync-transport/ TCP, QUIC (quinn 0.11/TLS 1.3), length-prefixed wire protocol
|
||||||
clawsync-agent/ OnionMemory, SyncScheduler, TcpSyncBackend, capability negotiation
|
clawsync-agent/ OnionMemory, SyncScheduler, TcpSyncBackend/QuicSyncBackend/SshSyncBackend
|
||||||
clawsync-fs/ CDC-based delta sync for any file type (FsSyncClient, FsSyncServer)
|
clawsync-fs/ CDC-based delta sync for any file type (FsSyncClient, FsSyncServer)
|
||||||
clawsync-cli/ clawsync binary — all commands wired here
|
clawsync-cli/ clawsync binary — all commands wired here
|
||||||
```
|
```
|
||||||
@@ -193,7 +193,7 @@ The workspace `.cargo/config.toml` sets `target-cpu=native` for SIMD throughput
|
|||||||
### Run tests
|
### Run tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo test --workspace # ~573 tests
|
cargo test --workspace # ~644 tests
|
||||||
cargo test --workspace --features simd-cdc # +16 SIMD CDC tests
|
cargo test --workspace --features simd-cdc # +16 SIMD CDC tests
|
||||||
cargo bench -p clawhdf5-onion # Criterion benchmarks
|
cargo bench -p clawhdf5-onion # Criterion benchmarks
|
||||||
```
|
```
|
||||||
@@ -642,6 +642,33 @@ clawsync branch merge model.h5 experiment --into main --strategy latest-wins
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### diff
|
||||||
|
|
||||||
|
Show page-level differences between two revisions of a local `.onion` sidecar. If `REV2` is omitted, compares `REV1` against the current HEAD.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
clawsync diff <LOCAL.h5> <REV1> [REV2] [--porcelain]
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
clawsync diff model.h5 5 8
|
||||||
|
# Diff rev 5 → rev 8:
|
||||||
|
# ~ page 0 (changed, 4096 B)
|
||||||
|
# + page 12 (added, 4096 B)
|
||||||
|
# - page 7 (removed)
|
||||||
|
# 1 page(s) changed, 1 added, 1 removed.
|
||||||
|
|
||||||
|
# Machine-readable output
|
||||||
|
clawsync diff model.h5 5 8 --porcelain
|
||||||
|
# ~ 0 4096
|
||||||
|
# + 12 4096
|
||||||
|
# - 7
|
||||||
|
```
|
||||||
|
|
||||||
|
Detection is based on `data_offset` equality in the append-only sidecar: two revisions referencing the same offset contain identical bytes, so a changed entry is unambiguous without decompressing any page data.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Transport: TCP, QUIC, and SSH
|
## Transport: TCP, QUIC, and SSH
|
||||||
|
|
||||||
All network commands support TCP (default), QUIC (`--quic`), and SSH (automatic when the remote address contains `@`).
|
All network commands support TCP (default), QUIC (`--quic`), and SSH (automatic when the remote address contains `@`).
|
||||||
@@ -774,7 +801,7 @@ cargo build --workspace --release
|
|||||||
### Testing
|
### Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# All tests (~617 default, ~633 with SIMD CDC)
|
# All tests (~644 default, ~660 with SIMD CDC)
|
||||||
cargo test --workspace
|
cargo test --workspace
|
||||||
cargo test --workspace --features simd-cdc
|
cargo test --workspace --features simd-cdc
|
||||||
|
|
||||||
@@ -809,6 +836,50 @@ clawsync-cli
|
|||||||
└── clawsync-core (BLAKE3, xxHash3, FastCDC, zstd)
|
└── clawsync-core (BLAKE3, xxHash3, FastCDC, zstd)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Using `clawsync-agent` as a library
|
||||||
|
|
||||||
|
The `clawsync-agent` crate exposes a `SyncBackend` trait with three implementations:
|
||||||
|
|
||||||
|
| Backend | When to use |
|
||||||
|
|---------|-------------|
|
||||||
|
| `TcpSyncBackend` | Pre-running `clawsync serve` on LAN |
|
||||||
|
| `QuicSyncBackend` | Encrypted WAN, pre-running `clawsync serve --quic` |
|
||||||
|
| `SshSyncBackend` | No pre-running server; spawns `clawsync serve --stdio` on demand |
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use clawsync_agent::{SshSyncBackend, SyncBackend, ssh_scheduler};
|
||||||
|
use clawsync_agent::{TcpSyncBackend, tcp_scheduler};
|
||||||
|
use clawsync_onion::selector::SyncSelector;
|
||||||
|
|
||||||
|
// SSH — no daemon needed
|
||||||
|
let scheduler = ssh_scheduler(
|
||||||
|
"[email protected]",
|
||||||
|
"/data/agent.claws",
|
||||||
|
local_h5_path,
|
||||||
|
"my-agent",
|
||||||
|
SyncSelector::All,
|
||||||
|
);
|
||||||
|
|
||||||
|
// TCP — pre-running serve required
|
||||||
|
let scheduler = tcp_scheduler(
|
||||||
|
"127.0.0.1:9999",
|
||||||
|
local_h5_path,
|
||||||
|
"my-agent",
|
||||||
|
SyncSelector::All,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Drive the scheduler manually
|
||||||
|
let stats = scheduler.sync_once().await?;
|
||||||
|
|
||||||
|
// Or hook into OnionMemory for autonomous post-flush sync
|
||||||
|
use clawsync_agent::OnionMemory;
|
||||||
|
let backend = SshSyncBackend::new("user@host", "/remote/agent.claws", "agent-1");
|
||||||
|
let memory = OnionMemory::new(local_h5_path, backend);
|
||||||
|
memory.record_and_flush(data).await?;
|
||||||
|
```
|
||||||
|
|
||||||
|
Override the SSH binary (e.g. for testing) by setting `CLAWSYNC_SSH_COMMAND` or calling `.with_ssh_command(path)` on the backend.
|
||||||
|
|
||||||
### Wire protocol stability
|
### Wire protocol stability
|
||||||
|
|
||||||
`SyncMessage` variants are serialized with rkyv and assigned discriminants positionally. **Never insert or reorder variants** — always append. The current variant list:
|
`SyncMessage` variants are serialized with rkyv and assigned discriminants positionally. **Never insert or reorder variants** — always append. The current variant list:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//!
|
//!
|
||||||
//! ## Modules
|
//! ## Modules
|
||||||
//!
|
//!
|
||||||
//! - [`backend`]: `SyncBackend` trait + `TcpSyncBackend` / `QuicSyncBackend` implementations
|
//! - [`backend`]: `SyncBackend` trait + `TcpSyncBackend` / `QuicSyncBackend` / `SshSyncBackend`
|
||||||
//! - [`onion_memory`]: `OnionMemory` — revision-aware wrapper around `HDF5Memory`
|
//! - [`onion_memory`]: `OnionMemory` — revision-aware wrapper around `HDF5Memory`
|
||||||
//! - [`scheduler`]: `SyncScheduler` — autonomous push after each flush
|
//! - [`scheduler`]: `SyncScheduler` — autonomous push after each flush
|
||||||
//! - [`negotiator`]: Peer capability negotiation
|
//! - [`negotiator`]: Peer capability negotiation
|
||||||
@@ -38,4 +38,4 @@ pub use backend::{
|
|||||||
pub use error::AgentSyncError;
|
pub use error::AgentSyncError;
|
||||||
pub use negotiator::{SessionCapabilities, assert_compatible, negotiate};
|
pub use negotiator::{SessionCapabilities, assert_compatible, negotiate};
|
||||||
pub use onion_memory::{MemorySnapshot, OnionMemory};
|
pub use onion_memory::{MemorySnapshot, OnionMemory};
|
||||||
pub use scheduler::{SyncScheduler, tcp_scheduler};
|
pub use scheduler::{SyncScheduler, ssh_scheduler, tcp_scheduler};
|
||||||
|
|||||||
@@ -103,6 +103,31 @@ pub fn tcp_scheduler(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convenience constructor: create a [`SyncScheduler`] backed by
|
||||||
|
/// [`SshSyncBackend`].
|
||||||
|
///
|
||||||
|
/// - `user_host` — SSH target, e.g. `"[email protected]"`
|
||||||
|
/// - `remote_path` — absolute path on the remote, e.g. `"/data/agent.claws"`
|
||||||
|
/// - `h5_path` — local HDF5 file to sync
|
||||||
|
/// - `agent_id` — identifier sent in protocol messages
|
||||||
|
/// - `selector` — which revisions to push
|
||||||
|
///
|
||||||
|
/// The `CLAWSYNC_SSH_COMMAND` environment variable overrides the SSH binary
|
||||||
|
/// (defaults to `ssh`).
|
||||||
|
pub fn ssh_scheduler(
|
||||||
|
user_host: &str,
|
||||||
|
remote_path: &str,
|
||||||
|
h5_path: PathBuf,
|
||||||
|
agent_id: &str,
|
||||||
|
selector: SyncSelector,
|
||||||
|
) -> SyncScheduler<crate::backend::SshSyncBackend> {
|
||||||
|
SyncScheduler::new(
|
||||||
|
crate::backend::SshSyncBackend::new(user_host, remote_path, agent_id),
|
||||||
|
h5_path,
|
||||||
|
selector,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
// Tests
|
// Tests
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user