Scopes and identity
Every SDK operation carries a scope — the partition the memory lives in. Scope is what separates Alice's memory from Bob's, the personal workspace from the team workspace, one agent's lessons from another. The SDK's scope type and Core's scope model align, but the SDK adds a layer on top: identity resolution and platform normalization.
Core is canonical for the HTTP-level scope semantics. See platform/scope for the wire-format view. This page covers what the SDK adds on the client side.
The Scope type
type Scope = {
user?: string;
agent?: string;
namespace?: string; // typically workspace or tenant
thread?: string; // conversation / session
};
Every ingest, search, get, delete, list, and package request includes a scope. The fields are additive: the more you specify, the narrower the partition.
The minimum required scope is determined by the active provider's capabilities().requiredScope. A personal-memory provider might require only user; a workspace-oriented provider might require user + namespace.
Identity resolution
Applications usually don't hard-code user / namespace strings — they look them up from a session. That lookup is UserAccountsManager's job.
UserAccountsManager is configured at SDK construction time:
new AtomicMemorySDK({
userAccounts: {
identity: {
providerType: 'web2',
apiBaseUrl: 'http://localhost:8787',
testMode: true,
},
preferences: {
providerType: 'web2',
apiBaseUrl: 'http://localhost:8787',
testMode: true,
encryption: { keySource: 'provided', key: new Uint8Array(32) },
},
},
context: { /* ... */ },
});
Three modes are supported:
| Mode | When to use | Behaviour |
|---|---|---|
testMode: true | Local development, tests, demos | Installs a hardcoded test provider with permissive defaults. No network calls for identity. |
| Hardcoded provider | Simple apps with a single known user | Returns a fixed identity. Useful for CLIs and server-side jobs. |
| Real web2 provider | Production browser / web apps | Calls the configured identity and preferences services over HTTP. |
ContextManager assumes a UserAccountsManager is present for ingest (which runs the capture gate). Operations that do not gate — pure searchDirect, operations under the subpath-primitive topology — do not require one.
Platform normalization
In browser contexts, the originating platform (e.g., chatgpt.com) is the key the user's capture rules are keyed on. Real platform strings vary (chat.openai.com, chatgpt.com, with or without subdomain, with or without trailing slash). The SDK normalizes these through normalizePlatformId so rules match reliably.
That normalization is internal, but it matters for understanding what shouldCaptureFromPlatform(platform) is actually comparing.
Scope patterns
| Pattern | Scope shape | Use case |
|---|---|---|
| Personal | { user } | Single-user assistant, personal memory |
| Team workspace | { user, namespace } | Shared memory within an org/project |
| Per-agent memory | { user, namespace, agent } | Multi-agent systems where agents keep their own memories |
| Per-conversation | { user, thread } | Scratch memory tied to a single session |
A memory written at { user: 'alice', namespace: 'team-acme' } is not visible to a search at { user: 'alice' } unless the provider opts into upward-narrowing (most do not, on purpose — this is what makes the isolation real).
Next
- Consent and gating — how
UserAccountsManagerprovides the preferences the gates consult - Core's platform/scope — the HTTP-level scope model and visibility rules