Skip to content

feat(cloud): named remotes with per-project sync routing #570

Description

@ceeesar13

📋 Pre-flight Checks

  • I have searched existing issues and this is not a duplicate
  • I understand this issue needs status:approved before a PR can be opened

🔍 Problem Description

Cloud replication currently supports a single destination per installation. For anyone whose memory spans multiple trust boundaries, that makes cloud sync an all-or-nothing choice.

Concrete case: I'm a freelancer working with multiple clients and with a dev team. My Engram holds:

  • Team projects — the team wants shared memory in the team's cloud.
  • Personal projects (e.g. my personal finances) — must replicate only to my own cloud.
  • Client projects — client A's context must never be able to reach client B's, and often must not leave my machine at all (professional confidentiality).

Today, enrolling in the team's cloud would expose everything; staying out means losing team collaboration. This also bites autonomous agents: an agent with memory access needs boundaries enforced by infrastructure, not by prompt discipline.

Engram's design already points this way — engram sync --cloud --all is intentionally blocked and sync is per-project. This proposal completes that idea.

💡 Proposed Solution

Separate where I can sync from what goes where, following the git remote mental model:

  1. Named remotes — N cloud destinations, each with its own enrollment/credentials.
  2. Per-project routes — explicit project → remote; zero or one route per project.
  3. Default-deny — a project with no route (and no default remote) never leaves the machine; syncing it fails with a clear blocked_no_route reason code. The most likely misconfiguration results in privacy, not leakage.
  4. Backwards compatible — an existing single-cloud install migrates to a default remote and keeps its current behavior with zero user action.

Proposed CLI surface (happy to adapt to existing conventions):

engram cloud remote add <name> --server <url> [--token <token>]
engram cloud remote list | remove <name> | set-default <name>
engram cloud route set --project <p> --remote <name>
engram cloud route list | unset --project <p>

Routing is enforced consistently across sync --cloud, cloud status, and the cloud upgrade paths. Background autosync refuses to start when per-project routing is configured (per-remote autosync is a deliberate follow-up), so it can never push an unrouted or other-routed project through the wrong destination.

📦 Affected Area

Sync (multi-instance)

🔄 Alternatives Considered

  • Multiple Engram installations/profiles per trust boundary — heavy, loses cross-project local search, and agents would have to juggle instances.
  • Wrapper/proxy in front of sync — works, but duplicates routing logic outside Engram and fragments the ecosystem; this belongs in core.
  • Fan-out (one project → many remotes) — deliberately excluded to keep the model simple; can be discussed separately if there's demand.

📎 Additional Context

Relationship to existing issues — this is orthogonal to the scope/identity work already in flight, and I want to be explicit so it isn't read as a duplicate:

Why not one multi-tenant cloud with per-project tokens? That resolves who sees what inside a cloud I control. It doesn't cover the real freelance case: (a) the team cloud isn't mine — I can't put my personal finances or another client's data there even with permissions; (b) many contracts require isolation of infrastructure, not only logical access; (c) machine-level default-deny (a project with no route goes nowhere) is a stronger guarantee than a grant on a shared server. Named remotes + routing is the "which cloud" layer; the grant model keeps applying per destination.

Working spike: built at Release Before Ready Bogotá on a fork, branch feat/scoped-cloud-routing:
https://github.com/ceeesar13/engram/tree/feat/scoped-cloud-routing

It implements a v2 cloud.json (named remotes + per-project routes + default_remote, with backward-compatible migration from the legacy single-destination format), the CLI above, route resolution with default-deny (blocked_no_route), routing-aware status/upgrade paths, an autosync safety gate, and unit + integration tests. I'll turn it into a PR once this issue is approved (Closes #N, one type:feature label, conventional commits). Engram changed how my team and I work across all our projects — I'd love to give back.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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