Summary
Explore a Team-safe bidirectional local mirror workflow for cloud projects using
Tigris snapshot versions as the remote baseline.
This is intentionally separate from the short-term push / pull CLI work in
#858. The immediate commands can provide useful one-way primitives, while this
issue tracks the deeper design needed for safe multi-user bidirectional sync.
Background
Plain rclone bisync is not safe enough for Team workspaces because each
client only has its own prior local/remote listings. In a multi-user workspace,
a missing or changed file can mean several different things:
- the local user intentionally deleted it
- the local user has not pulled a teammate's newer file yet
- a teammate intentionally deleted it in cloud
- both local and cloud changed since this client last synced
- a filter, listing failure, or stale baseline made a file appear absent
Rclone can compare two paths, but it cannot know the application-level intent
behind those changes. The dangerous case is letting one stale local tree become
authoritative for shared cloud state.
Tigris snapshots may provide the missing cloud-history primitive. Snapshot
enabled buckets can expose a point-in-time view of the bucket, and Tigris returns
a snapshot version that can be used to list/read/head bucket state at that point
in time:
https://www.tigrisdata.com/docs/buckets/snapshots-and-forks/
That gives Basic Memory a way to ask: "what did the cloud look like when this
client last successfully synced?"
Proposed model
Each client stores a sync record for a project:
- stable client id
- last successfully synced Tigris snapshot version
- local manifest captured at that successful sync
- per-path content hash, size, mtime, and file type
- remote object metadata when available, such as ETag/checksum/version/snapshot
On the next run, Basic Memory compares four states:
- base local: local manifest from last successful sync
- current local: current filesystem scan
- base cloud: bucket listing at the last synced Tigris snapshot version
- current cloud: current bucket listing
Then Basic Memory decides operations from a three-way reconciliation model:
| Local delta |
Cloud delta since baseline |
Action |
| changed |
unchanged |
upload |
| unchanged |
changed |
download |
| deleted |
unchanged |
delete/tombstone cloud |
| unchanged |
deleted |
delete local |
| changed |
changed |
conflict, do not overwrite silently |
| deleted |
changed |
conflict: local delete vs teammate edit |
| changed |
deleted |
conflict: local edit vs teammate delete |
Rclone can still be used as the byte-transfer engine once Basic Memory has
decided the safe operation list, but Basic Memory should own the reconciliation
logic.
Why Tigris snapshots help
Rclone bisync retains local prior listings for a pair of paths. For one user,
that is usually enough. For Teams, each client needs to know not only "what did
I last see locally?" but also "what cloud revision did I last sync against?"
Tigris snapshot versions can become that remote baseline. With a per-client
baseline snapshot, Basic Memory can distinguish:
- local changed while cloud stayed the same
- teammate changed cloud while local stayed the same
- local and cloud both changed
- local delete vs teammate edit
- local edit vs teammate delete
That is the distinction raw two-path sync cannot make reliably.
Open questions
- Should this be a new command, e.g.
bm cloud reconcile, bm cloud mirror, or
bm cloud team-sync, instead of changing bm cloud bisync semantics?
- Should Team local mirrors require snapshot-enabled Tigris buckets?
- How do we handle existing buckets that were not created with snapshots enabled?
- Where should per-client manifests live: Basic Memory config dir, project dir,
cloud metadata, or a combination?
- What should be the canonical content identity: explicit SHA256 in the Basic
Memory manifest, S3/Tigris checksum metadata, or both?
- How should conflicts be represented in Markdown files and surfaced to agents?
- Should deletes become tombstones first, rather than immediate remote deletes?
- Can the cloud API/MCP write path share the same revision/conflict machinery?
Possible first milestone
Build a design doc or proof of concept that:
- Creates or identifies a snapshot-enabled Team bucket.
- Stores a per-client
last_synced_snapshot_version.
- Lists base cloud from that snapshot and current cloud from the live bucket.
- Scans local state and compares it to a stored local manifest.
- Produces an operation plan without applying it.
- Marks all ambiguous cases as conflicts.
No destructive writes are needed for the first milestone. The goal is to prove
that Tigris snapshots give us the remote baseline needed for Team-safe
reconciliation.
Related
Summary
Explore a Team-safe bidirectional local mirror workflow for cloud projects using
Tigris snapshot versions as the remote baseline.
This is intentionally separate from the short-term
push/pullCLI work in#858. The immediate commands can provide useful one-way primitives, while this
issue tracks the deeper design needed for safe multi-user bidirectional sync.
Background
Plain
rclone bisyncis not safe enough for Team workspaces because eachclient only has its own prior local/remote listings. In a multi-user workspace,
a missing or changed file can mean several different things:
Rclone can compare two paths, but it cannot know the application-level intent
behind those changes. The dangerous case is letting one stale local tree become
authoritative for shared cloud state.
Tigris snapshots may provide the missing cloud-history primitive. Snapshot
enabled buckets can expose a point-in-time view of the bucket, and Tigris returns
a snapshot version that can be used to list/read/head bucket state at that point
in time:
https://www.tigrisdata.com/docs/buckets/snapshots-and-forks/
That gives Basic Memory a way to ask: "what did the cloud look like when this
client last successfully synced?"
Proposed model
Each client stores a sync record for a project:
On the next run, Basic Memory compares four states:
Then Basic Memory decides operations from a three-way reconciliation model:
Rclone can still be used as the byte-transfer engine once Basic Memory has
decided the safe operation list, but Basic Memory should own the reconciliation
logic.
Why Tigris snapshots help
Rclone bisync retains local prior listings for a pair of paths. For one user,
that is usually enough. For Teams, each client needs to know not only "what did
I last see locally?" but also "what cloud revision did I last sync against?"
Tigris snapshot versions can become that remote baseline. With a per-client
baseline snapshot, Basic Memory can distinguish:
That is the distinction raw two-path sync cannot make reliably.
Open questions
bm cloud reconcile,bm cloud mirror, orbm cloud team-sync, instead of changingbm cloud bisyncsemantics?cloud metadata, or a combination?
Memory manifest, S3/Tigris checksum metadata, or both?
Possible first milestone
Build a design doc or proof of concept that:
last_synced_snapshot_version.No destructive writes are needed for the first milestone. The goal is to prove
that Tigris snapshots give us the remote baseline needed for Team-safe
reconciliation.
Related
bm cloud sync#858