sync

package
v0.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClassifyForAutoSync added in v0.5.9

func ClassifyForAutoSync(m memory.Memory, projectRoot string) (content string, ok bool)

ClassifyForAutoSync decides whether a single memory may leave the machine for the auto write-through path. It runs the same classification as the preview/sync path (secrets, local paths, user scope, episodic/precompact, low quality, blocked categories). When syncable it returns the REDACTED content (home paths rewritten to <user-home>, etc.) — callers MUST push this, never the original, so redactions aren't bypassed. ok is false for anything not classified Syncable.

func IsRemoteForbidden

func IsRemoteForbidden(err error) bool

func IsRemoteUnavailable

func IsRemoteUnavailable(err error) bool

func ResolveProjectAcrossRemotes added in v0.6.8

func ResolveProjectAcrossRemotes(ctx context.Context, cfg *config.Config, cwd, clientID string, keys ...string) (*config.RemoteEntry, string, string)

ResolveProjectAcrossRemotes finds which configured remote knows the given git-origin remote_key(s), returning that remote, the server-side project ID, and the key that matched on it.

This is what makes a freshly-configured second server work with zero extra setup: `remote configure --name company` adds an entry with no routing paths, so path/default resolution alone would keep sending a company repo to the personal server (which rejects the unknown key). The probe asks each configured remote "do you know this repository?" and routes to the one that does.

Each remote is probed with every key in order (canonical first, then the legacy key) so a project still registered under the old normalization on a not-yet-rekeyed server is found.

Probe order is deterministic: the path/default-resolved remote for cwd first (so explicit routing always wins when its server knows the repo), then the remaining remotes by name. Remotes that fail to answer are skipped — best-effort. Returns (nil, "", "") when no remote knows any key.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a minimal HTTP client for the anchored_oss sync server. It is deliberately simple: no retries, no background goroutines, no auto-sync. All operations are explicit and require a server URL.

func NewClient

func NewClient(cfg config.RemoteConfig, clientID string) *Client

NewClient creates a sync client from RemoteConfig. Returns nil when RemoteConfig.Enabled is false.

func NewClientFromEntry

func NewClientFromEntry(entry config.RemoteEntry, clientID string) *Client

func (*Client) GetProjectByID added in v0.6.10

func (c *Client) GetProjectByID(ctx context.Context, id string) *RemoteProject

GetProjectByID returns the listed project with the given ID, or nil when the listing doesn't contain it (or fails). Used to verify that a forced/linked target project actually belongs to the repository being synced.

func (*Client) ListProjects added in v0.5.9

func (c *Client) ListProjects(ctx context.Context) ([]RemoteProject, error)

ListProjects returns the projects the configured API key can access on the remote server. Used by `remote sync` to validate linked project IDs (and pick a live default) instead of blindly trusting the local link list, which can go stale when the server's projects change.

func (*Client) Pull

Pull fetches new/updated memories from the remote server since the given watermark. The response memories are not filtered — the server is trusted to send safe content.

func (*Client) Push

Push sends classified memories to the remote server. All memories are validated through RemoteSafetyFilter before sending using the same projectRoot the caller used for preview, so a memory classified as syncable cannot be silently re-blocked here. Personal preferences (PreferenceScope=="user") are rejected as a defense-in-depth net even if the caller forgot to pre-filter them.

The caller SHOULD run ClassifyForPreview first and only push syncable memories; this method is the last line of defense.

func (*Client) PushTriples added in v0.5.5

func (c *Client) PushTriples(ctx context.Context, projectID string, triples []SyncTriple) (*SyncTripleResponse, error)

PushTriples sends a batch of knowledge-graph triples to the remote server for a previously-resolved project. The server applies the same hardening rules as anchored_oss does for memories (logical dedup, functional supersession, alias resolution).

Caller is expected to have already resolved the remote projectID via a memory sync (the server's project_claim flow). PushTriples does not perform safety filtering — triples are entity strings, not free text, and the server's quality/policy filter doesn't apply to them.

func (*Client) ResolveProjectIDByRemoteKey added in v0.6.3

func (c *Client) ResolveProjectIDByRemoteKey(ctx context.Context, remoteKey string) string

ResolveProjectIDByRemoteKey returns the ID of the remote project whose remote_key matches, or "" when none does (or the listing fails). Thin wrapper over ResolveProjectIDByRemoteKeys for single-key callers.

func (*Client) ResolveProjectIDByRemoteKeys added in v0.6.9

func (c *Client) ResolveProjectIDByRemoteKeys(ctx context.Context, keys ...string) (projectID, matchedKey string)

ResolveProjectIDByRemoteKeys probes the remote project listing for the first of keys (in order) that matches, returning the project ID and the key that matched, or ("", "") when none does (or the listing fails). The listing is fetched once and matched in memory, so passing multiple keys (e.g. canonical then legacy) costs a single round-trip. Empty keys are skipped.

func (*Client) SaveRemote

func (c *Client) SaveRemote(ctx context.Context, mem RemoteMemory) (*SaveRemoteResponse, error)

func (*Client) SearchRemote

func (c *Client) SearchRemote(ctx context.Context, projectID string, query string, limit int) ([]RemoteSearchResult, error)

type ClientCapabilities added in v0.7.0

type ClientCapabilities struct {
	PromotionQueue bool `json:"promotion_queue,omitempty"`
	TeamCache      bool `json:"team_cache,omitempty"`
	// ArtifactSummaries is reserved for a later wave (artifact-summary sync);
	// it stays false here so the server never emits the response plumbing,
	// while the field reserves the wire name for forward compatibility.
	ArtifactSummaries bool `json:"artifact_summaries,omitempty"`
}

ClientCapabilities mirrors the server's negotiation struct. This wave only the (empty) presence matters — it opts into policy hints; the feature flags stay false until later waves implement them.

type HTTPError

type HTTPError struct {
	Status int
	Body   string
}

HTTPError represents a non-2xx response from the sync server.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type Memory

type Memory struct {
	ID               string  `json:"id"`
	Category         string  `json:"category"`
	Content          string  `json:"content"`
	ProjectID        *string `json:"project_id,omitempty"`
	Source           string  `json:"source"`
	SyncOrigin       string  `json:"sync_origin"`
	SyncDirty        bool    `json:"sync_dirty"`
	RemoteProjectKey *string `json:"remote_project_key,omitempty"`
	PreferenceScope  string  `json:"preference_scope,omitempty"`
	Metadata         any     `json:"metadata,omitempty"`
}

func ToSyncMemory added in v0.5.9

func ToSyncMemory(m memory.Memory) Memory

ToSyncMemory converts a local memory into the sync wire model. Exported so both the CLI sync command and the MCP auto write-through path share one mapping.

type PolicyHints added in v0.7.0

type PolicyHints struct {
	QualityThreshold   float64  `json:"quality_threshold"`
	BlockedCategories  []string `json:"blocked_categories"`
	MaxMemoriesPerSync int      `json:"max_memories_per_sync"`
}

PolicyHints is the server's advisory sync policy, returned only when the request advertised ClientCapabilities. nil from older servers.

type PreviewClassification

type PreviewClassification string
const (
	ClassificationSyncable    PreviewClassification = "syncable"
	ClassificationBlocked     PreviewClassification = "blocked"
	ClassificationNeedsReview PreviewClassification = "needs_review"
)

type PreviewItem

type PreviewItem struct {
	Memory         Memory                `json:"memory"`
	Classification PreviewClassification `json:"classification"`
	Reason         string                `json:"reason"`
}

type PreviewResult

type PreviewResult struct {
	Total       int           `json:"total"`
	Syncable    int           `json:"syncable"`
	Blocked     int           `json:"blocked"`
	NeedsReview int           `json:"needs_review"`
	Items       []PreviewItem `json:"items,omitempty"`
}

func ClassifyForPreview

func ClassifyForPreview(memories []Memory, projectRoot string) PreviewResult

type ProjectClaim

type ProjectClaim struct {
	Name      string `json:"name"`
	RemoteKey string `json:"remote_key"`
}

type RemoteError

type RemoteError struct {
	StatusCode int
	Body       string
}

func (*RemoteError) Error

func (e *RemoteError) Error() string

type RemoteMemory

type RemoteMemory struct {
	ID           string        `json:"id"`
	Category     string        `json:"category"`
	Content      string        `json:"content"`
	Source       string        `json:"source,omitempty"`
	ProjectID    string        `json:"project_id,omitempty"`
	ProjectClaim *ProjectClaim `json:"project_claim,omitempty"`
}

type RemoteProject added in v0.5.9

type RemoteProject struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	Slug      string `json:"slug"`
	RemoteKey string `json:"remote_key"`
	// RemoteKeyV1 is the legacy routing key servers >= v0.4.7 expose alongside
	// the canonical one; empty on older servers.
	RemoteKeyV1 string `json:"remote_key_v1"`
}

RemoteProject is a minimal view of a project as returned by GET /v1/projects.

type RemoteSafetyResult

type RemoteSafetyResult struct {
	Content    string
	Allowed    bool
	Blocked    bool
	Violations []RemoteSafetyViolation
	// Rewritten is true when Content was modified (paths or secrets redacted).
	// A memory can be both Rewritten and Blocked — rewriting reduces sensitive
	// content but other violations may still block sync.
	Rewritten bool
}

func RemoteSafetyFilter

func RemoteSafetyFilter(content string, metadata map[string]any, projectRoot string) RemoteSafetyResult

type RemoteSafetyViolation

type RemoteSafetyViolation struct {
	Field   string
	Pattern string
	Value   string
	Reason  string
}

type RemoteSearchResult

type RemoteSearchResult struct {
	ID         string `json:"id"`
	Category   string `json:"category"`
	Content    string `json:"content"`
	ProjectID  string `json:"project_id"`
	Source     string `json:"source,omitempty"`
	AuthorName string `json:"author_name,omitempty"`
	UpdatedAt  string `json:"updated_at"`
}

type SaveRemoteResponse

type SaveRemoteResponse struct {
	ID        string `json:"id"`
	Category  string `json:"category"`
	ProjectID string `json:"project_id,omitempty"`
	Created   bool   `json:"created"`
}

type SyncMemory

type SyncMemory struct {
	ID               string `json:"id"`
	Category         string `json:"category"`
	Content          string `json:"content"`
	Source           string `json:"source"`
	PreferenceScope  string `json:"preference_scope,omitempty"`
	RemoteProjectKey string `json:"remote_project_key,omitempty"`
	Metadata         any    `json:"metadata,omitempty"`
}

SyncMemory is a memory ready for remote sync (no embeddings, no local paths).

type SyncPullRequest

type SyncPullRequest struct {
	ClientID  string `json:"client_id"`
	ProjectID string `json:"project_id"`
	Watermark string `json:"watermark,omitempty"`
}

SyncPullRequest requests new/updated memories from the server.

type SyncPullResponse

type SyncPullResponse struct {
	Memories  []SyncMemory `json:"memories"`
	Watermark string       `json:"watermark"`
}

SyncPullResponse is the server's response with remote memories.

type SyncPushRequest

type SyncPushRequest struct {
	ClientID  string `json:"client_id"`
	ProjectID string `json:"project_id"`
	// ProjectClaim lets the client route a push to a remote project by its
	// git-origin remote_key instead of a server-side project_id. When set and
	// ProjectID is empty, the server resolves-or-creates the project by
	// remote_key, using Name for a human-readable label. This is how
	// repo-scoped sync identifies a repository regardless of its local
	// directory name.
	ProjectClaim *ProjectClaim `json:"project_claim,omitempty"`
	Memories     []SyncMemory  `json:"memories"`
	ProjectRoot  string        `json:"-"`
	// ClientCapabilities advertises optional protocol features and, by its
	// presence, opts into the server's Policy hints. Omitted -> the server
	// responds exactly as it did before negotiation existed.
	ClientCapabilities *ClientCapabilities `json:"client_capabilities,omitempty"`
}

SyncPushRequest is the payload sent to anchored_oss for pushing local memories. ProjectRoot is a client-side hint used by the local safety filter to rewrite in-project paths to relative form. It is intentionally not serialized.

type SyncPushResponse

type SyncPushResponse struct {
	Accepted int      `json:"accepted"`
	Rejected int      `json:"rejected"`
	Errors   []string `json:"errors,omitempty"`
	// ProjectID is the remote project the batch landed in, resolved by the
	// server (servers >= v0.4.4). Needed for follow-up per-project calls
	// (e.g. PushTriples) when routing by project_claim, where the client
	// doesn't know the remote ID upfront. Empty on older servers.
	ProjectID string `json:"project_id,omitempty"`
	// Policy is the server's advisory sync policy, present only when the
	// request advertised capabilities and the server supports negotiation
	// (>= v0.5.1). nil otherwise.
	Policy *PolicyHints `json:"policy,omitempty"`
}

SyncPushResponse is the server's response to a push request.

type SyncTriple added in v0.5.5

type SyncTriple struct {
	Subject    string  `json:"subject"`
	Predicate  string  `json:"predicate"`
	Object     string  `json:"object"`
	Confidence float64 `json:"confidence,omitempty"`
}

type SyncTripleRequest added in v0.5.5

type SyncTripleRequest struct {
	Triples []SyncTriple `json:"triples"`
}

SyncTripleRequest pushes a batch of knowledge-graph triples to the remote server. Triples are scoped to a project; the caller must have resolved the remote project ID (e.g. via a prior memory sync) before calling.

type SyncTripleResponse added in v0.5.5

type SyncTripleResponse struct {
	Accepted int      `json:"accepted"`
	Rejected int      `json:"rejected"`
	Errors   []string `json:"errors,omitempty"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL