pub struct SyncSubsystem { /* private fields */ }Expand description
A daemon device’s sync endpoint + lease coordinator. Held behind a
tokio::sync::Mutex on ServerState; every method is &mut self.
Implementations§
Source§impl SyncSubsystem
impl SyncSubsystem
Sourcepub fn open(root: &Path) -> Result<Self, String>
pub fn open(root: &Path) -> Result<Self, String>
Open the daemon-default subsystem rooted at root (<journal_dir>/sync/):
a persistent per-device id at root/device-id, this device’s oplog +
checkpoints under root/<device_id>/, and a shared FsRelay at
root/relay/. Uses the real system wall clock and a fresh in-process
lease coordinator.
Sourcepub fn open_with(
device_id: String,
device_dir: &Path,
relay_dir: &Path,
coordinator: Box<dyn LeaseCoordinator + Send>,
wall: WallClock,
) -> Result<Self, String>
pub fn open_with( device_id: String, device_dir: &Path, relay_dir: &Path, coordinator: Box<dyn LeaseCoordinator + Send>, wall: WallClock, ) -> Result<Self, String>
Open with explicit paths, coordinator, and clock — the injection point
the tests use to run two devices (distinct device_dirs, one shared
relay_dir, a cloned coordinator register).
Sourcepub fn open_remote(
root: &Path,
transport: Arc<dyn SyncTransport>,
scope: impl Into<String>,
key_provider: Arc<dyn SyncKeyProvider>,
) -> Result<Self, String>
pub fn open_remote( root: &Path, transport: Arc<dyn SyncTransport>, scope: impl Into<String>, key_provider: Arc<dyn SyncKeyProvider>, ) -> Result<Self, String>
Open a remote (Parslee-backed) subsystem. This device’s oplog +
checkpoints stay local under root/<device_id>/, but the relay and lease
register are the network transport (e.g. ParsleeSyncTransport, or a
LoopbackTransport in tests), scoped to scope — the user’s Parslee
identity (user:<id> / org:<id>) — so every device on that login
converges through one service. Op payloads are E2E-encrypted under
key_provider (login-derived), so the relay only ever holds ciphertext.
The daemon selects this over SyncSubsystem::open when
.car/config.toml [sync] backend = "parslee".
pub fn device_id(&self) -> &str
Sourcepub fn status(&mut self) -> Result<Value, String>
pub fn status(&mut self) -> Result<Value, String>
sync.status — the roster, this device’s journal frontier (per-device
max seq), the relay’s stable frontier, and the divergence-invariant
state hash.
Sourcepub fn append(
&mut self,
scope: Scope,
surface: Surface,
payload: Value,
) -> Result<Value, String>
pub fn append( &mut self, scope: Scope, surface: Surface, payload: Value, ) -> Result<Value, String>
sync.append — record an op on any surface (the generic domain tee).
Sourcepub fn tee_config(
&mut self,
domain: &str,
value: Value,
) -> Result<Value, String>
pub fn tee_config( &mut self, domain: &str, value: Value, ) -> Result<Value, String>
Replicate a portable config domain onto the oplog so every device
on this login converges it (LWW per domain) — how a setting changed on
the Mac reaches the phone. The tee primitive: the daemon’s own config
write-paths (agent-permissions, messaging allowlist, …) call this after a
local write; that per-subsystem adoption is the remaining wiring. It
refuses a device-local domain (car_sync::partition) — the guard that
keeps a secret or an OS grant off the relay; value must already exclude
any device-local sub-field (e.g. a keychain ref stays a per-device
pointer). Safer than raw sync.append (which any surface can use).
Sourcepub fn config_get(&self, domain: &str) -> Value
pub fn config_get(&self, domain: &str) -> Value
The converged (folded LWW) value of a config domain, or null if no
device has teed it yet — the read side an adopting subsystem applies
after a pull to reconcile a peer’s change onto this device.
Sourcepub fn publish_host_endpoint(
&mut self,
name: &str,
url: &str,
pubkey: &str,
) -> Result<Value, String>
pub fn publish_host_endpoint( &mut self, name: &str, url: &str, pubkey: &str, ) -> Result<Value, String>
Announce this device’s peer-reachable A2A endpoint to the user’s other devices.
Idempotent by construction: the entry is keyed on this device’s id and
folds LWW, so re-announcing on every start overwrites rather than
accumulates. Call it whenever the A2A listener comes up — the address can
change between runs (DHCP, a new --a2a-public-url), and a stale entry
would send peers at an address nothing answers on.
Sourcepub fn host_endpoints(&self) -> Vec<HostEndpoint>
pub fn host_endpoints(&self) -> Vec<HostEndpoint>
Every other device’s announced endpoint.
This device is excluded: it is not its own peer, and listing it would put a self-addressed row in every peer listing.
The pubkey is what makes these peers reachable rather than merely
visible. It arrived over the E2E-encrypted oplog, so only a device
holding this login’s key material could have published it — which is
exactly the property that lets this host trust it without an operator
comparing fingerprints by hand.
Sourcepub fn knowledge(&self) -> Vec<Value>
pub fn knowledge(&self) -> Vec<Value>
The converged (folded) knowledge facts — the read side of the assistant’s
synced memory. Returns each fact’s {subject, body} payload in ASCENDING
(hlc, op_id) order (as log_entries yields them), so a reducer that
keeps the LAST occurrence per subject gets the newest value. The assistant
re-ingests these after a pull so a fact learned on one device surfaces in
recall on another. Raw (unreduced) on purpose — the caller reduces
newest-per-subject so the ordering contract stays in one place.
Sourcepub fn assistant_checkpoint_put(
&mut self,
checkpoint: AssistantCheckpoint,
) -> Result<Value, String>
pub fn assistant_checkpoint_put( &mut self, checkpoint: AssistantCheckpoint, ) -> Result<Value, String>
Persist the exact model-facing supervised-assistant checkpoint in the
existing append-only oplog. LWW is per session id, while revision
prevents a delayed writer from replacing a newer local checkpoint.
Sourcepub fn assistant_checkpoint_get(
&self,
session_id: &str,
) -> Result<Option<AssistantCheckpoint>, String>
pub fn assistant_checkpoint_get( &self, session_id: &str, ) -> Result<Option<AssistantCheckpoint>, String>
Load the latest exact checkpoint for one supervised session.
Sourcepub fn assistant_action_put(
&mut self,
record: SupervisedActionRecord,
) -> Result<Value, String>
pub fn assistant_action_put( &mut self, record: SupervisedActionRecord, ) -> Result<Value, String>
Append one monotone supervised-action lifecycle record. This ledger is separate from scheduled-run Intent because approval and indeterminate dispatch are distinct safety states, not aliases for pending/failed.
pub fn assistant_action_get( &self, action_id: &str, ) -> Result<Option<SupervisedActionRecord>, String>
Sourcepub fn record_turn(
&mut self,
scope: Scope,
conversation_id: &str,
role: &str,
content: &str,
tool_calls: Vec<Value>,
tool_use_id: Option<&str>,
timestamp: u64,
) -> Result<Value, String>
pub fn record_turn( &mut self, scope: Scope, conversation_id: &str, role: &str, content: &str, tool_calls: Vec<Value>, tool_use_id: Option<&str>, timestamp: u64, ) -> Result<Value, String>
sync.record_turn — the Conversation domain, routed through the oplog so
sync.resume is real. role ∈ user|assistant|tool.
Sourcepub fn record_intent(
&mut self,
scope: Scope,
intent: &Intent,
) -> Result<Value, String>
pub fn record_intent( &mut self, scope: Scope, intent: &Intent, ) -> Result<Value, String>
sync.record_intent — write a leased-execution intent to the
Surface::Intent ledger (terminal-guarded: a pending/failed write
for an already-committed run is a no-op). This is what populates the
committed-run oracle the dispatch fence reads.
Sourcepub fn pump(&mut self) -> Result<Value, String>
pub fn pump(&mut self) -> Result<Value, String>
sync.pump — one reconciliation round (push journal-durable own ops →
pull → verify → fold → ack). This drives push/pull/ack against the relay.
Sourcepub fn checkpoint(&mut self) -> Result<Value, String>
pub fn checkpoint(&mut self) -> Result<Value, String>
sync.checkpoint — compute + publish a device-side checkpoint at the
relay’s stable frontier (the E2E-ready snapshot; the relay never folds).
Sourcepub fn rebase(&mut self) -> Result<Value, String>
pub fn rebase(&mut self) -> Result<Value, String>
sync.rebase — cold bootstrap / straggler re-entry: re-anchor on the
relay’s latest checkpoint (carrying uncovered local ops across).
Sourcepub fn transcript(&self, conversation_id: &str) -> Value
pub fn transcript(&self, conversation_id: &str) -> Value
sync.transcript — the ordered, role-threaded raw transcript projection.
Sourcepub fn resume(&self, conversation_id: &str) -> Result<Value, String>
pub fn resume(&self, conversation_id: &str) -> Result<Value, String>
sync.resume — the repaired, provider-valid Vec<Message> a host
replays to continue the conversation (the verbatim resume path).
Sourcepub fn fence_check(
&mut self,
agent_id: &str,
run_id: &str,
epoch: u64,
) -> Result<Value, String>
pub fn fence_check( &mut self, agent_id: &str, run_id: &str, epoch: u64, ) -> Result<Value, String>
sync.fence_check — the B6 executor dispatch fence at the point of
effect: the durable committed-run oracle read + the linearizable “am I
still epoch N?” read. Only may_dispatch == true authorizes the effect.
Sourcepub fn lease_acquire(
&mut self,
agent_id: &str,
ttl_ms: u64,
) -> Result<Value, String>
pub fn lease_acquire( &mut self, agent_id: &str, ttl_ms: u64, ) -> Result<Value, String>
lease.acquire — CAS-acquire the per-agent execution lease (this device
is the holder); on grant the monotone fencing epoch bumps.
Sourcepub fn lease_renew(
&mut self,
agent_id: &str,
epoch: u64,
ttl_ms: u64,
) -> Result<Value, String>
pub fn lease_renew( &mut self, agent_id: &str, epoch: u64, ttl_ms: u64, ) -> Result<Value, String>
lease.renew — heartbeat the lease (no epoch bump), iff still the holder.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for SyncSubsystem
impl !Sync for SyncSubsystem
impl !UnwindSafe for SyncSubsystem
impl Freeze for SyncSubsystem
impl Send for SyncSubsystem
impl Unpin for SyncSubsystem
impl UnsafeUnpin for SyncSubsystem
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more