Understanding Per-Operator Memory Slots and Per-User Isolation in ai-memory

Per-operator memory slots give each authenticated user a private, namespaced workspace by prefixing storage paths with deterministic identifiers, enabling isolation through injection rather than read restrictions.

The akitaonrails/ai-memory repository implements a multi-user memory architecture where operators (authenticated users) maintain distinct scratch pads for consolidation and auto-improvement. The system achieves per-user isolation not through access control lists, but by namespacing slot paths with deterministic, operator-specific segments that prevent collision while remaining globally searchable. This design allows the engine to inject private context into individual user sessions without breaking the wiki-like transparency of the underlying storage.

What Are Per-Operator Memory Slots?

Per-operator memory slots function as private "scratch pads" that the ai-memory engine writes to during consolidation and auto-improvement processes. According to the per-operator memory slots documentation, these slots follow an "absent means shared" rule: if a slot lacks a user-specific segment, it becomes available to all operators.

When enabled, the engine stores operator-specific data in paths like _slots/<segment>/current-focus.md rather than the shared _slots/current-focus.md location. This ensures that each user's consolidation summaries and focus areas remain distinct from others' workloads.

Namespacing Conventions

The system generates three types of path segments to guarantee uniqueness across different identity providers:

  • u-<username> – Used when the username is already lowercase and path-safe.
  • uh-<uuid> – Applied to mixed-case usernames or those ending with periods, hashing the identifier to prevent filesystem collisions.
  • o-<uuid> – Reserved for full OIDC issuer-subject pairs, creating a deterministic global identifier.

These segments appear in the slot path immediately after _slots/, such as _slots/uh-e8a7c3f2/current-focus.md, ensuring compatibility with case-insensitive filesystems while maintaining human readability where possible.

The Configuration Flag

Isolation behavior is controlled by the [slots] per_user setting in the configuration template. As defined in [crates/ai-memory-cli/templates/config.default.toml](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-cli/templates/config.default.toml), this boolean flag determines whether the engine uses namespaced or shared storage:

[slots]
per_user = true

When per_user = true, the system activates strict namespacing for all slot operations.

How Per-User Isolation Works

The isolation model relies on injection rather than access control. Slot pages remain regular wiki pages that any operator can read or search; the "privacy" emerges from path conventions that prevent unauthorized writes.

Injection vs. Access Control

Unlike traditional systems that restrict read access, ai-memory allows any operator to read another's slot content. The isolation occurs at write time:

  • Consolidation writes target only the operator's own namespaced slot. If the model proposes a path belonging to another user, the write operation is skipped or refused.
  • Search and retrieval remain global, preserving the system's wiki architecture where information remains discoverable even when organized by owner.

This approach aligns with the design philosophy documented in [crates/ai-memory-core/src/slots.rs](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/slots.rs), where slots are treated as conventional pages with specialized naming conventions rather than privileged resources.

Write Enforcement and Auto-Improvement

The enforcement logic resides in [crates/ai-memory-store/src/auto_improve.rs](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/auto_improve.rs#L1128), where the engine validates write destinations before persisting auto-improvement proposals:

  • Standard operators attempting to write to _slots/current-focus.md have their requests automatically redirected to their personal namespace (e.g., _slots/u-alice/current-focus.md).
  • Administrators retain the ability to write to any namespace, enabling maintenance and migration tasks.
  • Auto-improvement proposals become per-operator, allowing each user to maintain one pending proposal per page without blocking others' workflows.

The system also tracks page reinforcement counters per operator, enabling weighting algorithms configured via [decay] breadth_weight to influence retention scores based on individual usage patterns.

Configuration and Code Examples

Enable per-user isolation by setting the configuration flag in your config.toml:

[slots]
per_user = true

When calling memory_write_page from Rust, the engine automatically handles namespacing based on the authenticated context:

// Writing to a slot - automatically namespaced for the current operator
let path = "_slots/current-focus.md";
let content = "Priority: refactor authentication module";
let response = ai_memory::memory_write_page(&ctx, path, content).await?;

// The response contains the actual stored path with namespace
assert!(response.actual_path.contains("u-") || response.actual_path.contains("uh-"));
println!("Stored at: {}", response.actual_path);

Reading slots works identically regardless of ownership, as isolation does not restrict read access:

// Any operator can read another's slot
let namespaced_path = "_slots/uh-a1b2c3d4/current-focus.md";
let page = ai_memory::read_page(&ctx, namespaced_path).await?;
println!("Content: {}", page.body);

Key Implementation Files

Summary

  • Per-operator memory slots provide private workspaces through deterministic path namespacing rather than access control lists.
  • The system uses three segment types (u-, uh-, o-) to handle varying username formats and prevent filesystem collisions.
  • Enabling [slots] per_user = true redirects all slot writes to operator-specific paths while maintaining global read access.
  • Auto-improvement proposals and consolidation summaries become per-operator, preventing interference between users.
  • Existing shared slots become invisible to briefs when the flag is enabled until manually migrated or the flag is disabled.

Frequently Asked Questions

How does per-operator memory slots differ from traditional access control?

Traditional systems restrict read access using permissions or ACLs, whereas per-operator memory slots restrict write destinations while keeping pages globally readable. This "injection-based" isolation means any operator can view another's slot content by knowing the path, but only the owning operator (or administrators) can modify the specific namespaced file.

What happens to existing slot pages when enabling per-user mode?

Existing slot pages written before enabling the flag (e.g., _slots/backend/architecture.md) contain segments that no current operator can produce. With [slots] per_user = true, these historical pages become invisible to all briefs. Administrators must manually migrate content into proper operator namespaces, or temporarily disable the flag to access legacy data.

Can administrators override per-user isolation?

Yes. While standard operators are restricted to writing within their own namespace (with automatic redirection for shared paths), administrators retain the ability to write to any operator's slot directory. This privilege enables maintenance tasks, content migration, and manual consolidation when the engine's automatic proposals require adjustment.

How does the system handle case-insensitive filesystems?

The uh-<uuid> segment type specifically addresses case-insensitivity and unsafe filename characters by hashing mixed-case usernames or those ending with periods. This guarantees unique, filesystem-safe paths regardless of underlying storage case sensitivity, preventing collision scenarios where User and user might otherwise overwrite each other.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →