Skip to content

Design: Team-safe bidirectional sync using Tigris snapshots #862

Description

@groksrc

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:

  1. Creates or identifies a snapshot-enabled Team bucket.
  2. Stores a per-client last_synced_snapshot_version.
  3. Lists base cloud from that snapshot and current cloud from the live bucket.
  4. Scans local state and compares it to a stored local manifest.
  5. Produces an operation plan without applying it.
  6. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    cloudBasic Memory CloudenhancementNew feature or request
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions