# How ai-memory Handles Global Preferences and Context: Understanding the `_global` Scope

> Learn how ai-memory manages global preferences using the _global scope. Discover automatic merging for cross-project settings with lookup_global_scope and create_global_scope.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: deep-dive
- Published: 2026-08-31

---

**ai-memory stores global preferences in a reserved `_global` project and automatically merges them into query results using `lookup_global_scope` and `create_global_scope` helpers, enabling cross-project settings without breaking scoped isolation.**

The **akitaonrails/ai-memory** repository implements a unique approach to managing global preferences and context by treating them as a special reserved project rather than process-wide singletons. This design allows teams to define universal settings that apply across all workspaces while maintaining the system's core architecture of typed, scoped storage.

## The Reserved `_global` Project

Unlike systems that rely on environment variables or process-wide singletons, ai-memory stores global preferences in a project literally named `_global`. This reserved scope acts as a container for settings that should propagate across every workspace and project in the system. According to the source code in [`crates/ai-memory-store/src/scope.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/scope.rs), the store layer provides dedicated helper functions—`lookup_global_scope` and `create_global_scope`—to manage this special project. When a write operation specifies `scope: "global"`, the system routes the data to this `_global` project instead of the current workspace, making the stored pages available as cross-project preferences.

## Writing Global Preferences

### Using `scope: "global"` in Write Operations

To store a preference that applies globally, you pass `scope: "global"` in your write request. As documented in [`docs/ARCHITECTURE.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md), the `memory_write_page` RPC uses this parameter to force storage into the `_global` project regardless of the active workspace. This ensures that user settings, team defaults, or system configurations persist independently of any specific project context.

```rust
// Creating the global preferences scope (usually done once)
let global = ai_memory_store::create_global_scope(&writer).await?;

// Writing a preference page into the global scope
ai_memory_store::write_page(
    &writer,
    ai_memory_store::WritePageOpts {
        path: "settings/auto_save.md".into(),
        content: "enabled = true".into(),
        scope: Some("global".into()),   // <- forces write into _global
        ..Default::default()
    },
).await?;

```

### Helper Functions in [`scope.rs`](https://github.com/akitaonrails/ai-memory/blob/main/scope.rs)

The `create_global_scope` function instantiates the `_global` project if it does not exist, while `lookup_global_scope` retrieves it for read operations. Both functions are defined in [`crates/ai-memory-store/src/scope.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/scope.rs) and enforce the typed scope resolution invariants that prevent scope confusion. These helpers ensure that all global access goes through the same typed APIs used for regular projects, preserving the single-writer SQLite guarantees.

## Querying Global Context

### Automatic Inclusion in Unscoped Queries

When a request does not specify an explicit workspace, project, or scope, the server automatically adds `_global` preferences to the result set. In [`crates/ai-memory-mcp/src/server.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/server.rs), the implementation includes a comment explaining that these are "standing user/team preferences from the reserved `_global` scope; treat them as context that applies to the query." The system returns these hits separately as `global_scope_hits`, allowing clients to distinguish between local project data and universal preferences.

### Broadening Searches with `global=true`

For broader discovery, you can set `global=true` in your query parameters. This changes the search behavior to perform an FTS-only scan across **all** projects while still returning the `_global` hits separately in a `global_hits` field. This approach lets you search the entire corpus while maintaining a clear separation between global context and project-specific results.

```rust
// Reading preferences from any project
let hits = client
    .memory_query(
        MemoryQueryOpts {
            q: "auto_save".into(),
            global: Some(true),           // <- search all projects + global prefs
            ..Default::default()
        },
    )
    .await?;

```

## Project-Level Defaults with Marker Files

Individual projects can opt into treating unscoped queries as global by adding a marker file entry `default_global = "true"`. As documented in [`docs/marker-file.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/marker-file.md), when this marker is present, a plain `memory_recent` call returns the most recent **global** pages rather than project-local ones. This allows specific workspaces to inherit global preferences by default while others maintain strict local isolation.

## Ranking and Security Considerations

Global hits retain their original FTS-only ranking and are explicitly excluded from LLM-based reranking when `AI_MEMORY_RERANKER=llm` is enabled. They still carry workspace and project identifiers so callers can trace where each preference originated. Security-wise, the design avoids process-wide singletons; because global preferences are just another scoped project, all access control flows through the same typed APIs that enforce single-writer SQLite constraints and scope resolution invariants.

## Summary

- ai-memory stores cross-project preferences in the `_global` reserved project, managed by `create_global_scope` and `lookup_global_scope`.
- Write operations use `scope: "global"` to target this universal scope as defined in [`docs/ARCHITECTURE.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md).
- Unscoped queries automatically receive `_global` context in the `global_scope_hits` response field via [`crates/ai-memory-mcp/src/server.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/server.rs).
- Setting `global=true` performs an FTS-only search across all projects while isolating global hits in `global_hits`.
- Projects can opt into default-global behavior by setting `default_global = "true"` in their marker file.

## Frequently Asked Questions

### What is the `_global` project in ai-memory?

The `_global` project is a reserved scope that stores preferences applying to every workspace and project in the system. It behaves like any other project but is accessed via dedicated helper functions in [`crates/ai-memory-store/src/scope.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/scope.rs) when the `scope: "global"` parameter is used.

### How do I write a preference that applies to all projects?

Pass `scope: "global"` in your `write_page` call to store the page under the `_global` project. The `create_global_scope` helper ensures the reserved project exists before writing, making the preference available as global context in subsequent queries.

### Why are global hits excluded from LLM reranking?

Global preferences maintain their original FTS-only ranking and bypass LLM-based reranking to ensure predictable, consistent behavior across all projects. This prevents AI-driven ranking fluctuations from affecting foundational user or team settings.

### What happens if a project has `default_global = "true"` configured?

When a project includes `default_global = "true"` in its marker file (as documented in [`docs/marker-file.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/marker-file.md)), unscoped queries such as `memory_recent` return the most recent global pages instead of project-local results, effectively making the project inherit global preferences by default.