> ## Documentation Index
> Fetch the complete documentation index at: https://docs.platform.nora.my/llms.txt
> Use this file to discover all available pages before exploring further.

# Scoping

> Keep memory isolated per user, per tenant, per conversation — without duplicating data.

**Scoping** is how you make sure one user's memory doesn't leak into another user's. Every memory read and write carries a **scope key**. Reads only see items with matching scope; writes are tagged with the current scope.

## Why scoping matters

Without scoping, an Agent that helps *Alice* would also see notes it wrote about *Bob*. This is:

* A privacy problem.
* A quality problem (Bob's context contaminates Alice's answer).
* A compliance problem (GDPR, HIPAA).

Scoping fixes all three with one setting.

## Scope shape

A scope key is a JSON-ish object. Common shapes:

```json theme={null}
{ "user_id": "alice@example.com" }
```

```json theme={null}
{ "tenant": "acme-corp", "user": "u_9231" }
```

```json theme={null}
{ "conversation_id": "conv_abc" }
```

You choose the shape. Nora doesn't mandate keys — it just enforces equality.

## Setting scope at runtime

Two ways:

### From the Trigger

The Trigger passes the scope key into the run. All memory operations in that run use it automatically.

For chat triggers, the scope defaults to `{ conversation_id: <session> }`. Override in the Trigger block config.

For webhook triggers, extract from the payload:

```
scope.user_id = payload.user.id
scope.tenant  = payload.user.tenant
```

### Per-tool override

A tool can call memory with an explicit scope, overriding the run default. Rare — usually a smell. Use only when the Agent legitimately needs to read cross-scope data (support agent reading their own knowledge across all customers, for example).

## Scope hierarchy

Scopes can be **nested**. Writing at a broader scope makes an item visible at all narrower scopes.

Example:

* Write at `{ tenant: "acme" }` — everyone in Acme sees it.
* Write at `{ tenant: "acme", user: "alice" }` — only Alice sees it.
* Alice's reads see both her own items and tenant-wide items.

Configure hierarchy under **Space settings → Scope schema** — declare which keys nest under which.

## Cross-scope access (careful!)

Some Agents legitimately need cross-scope reads — support agents, admin dashboards. Grant per-space:

* **Cross-scope read** — Agent can read any scope. Writes still respect current scope.
* **Cross-scope everything** — read and write. Only for admin use cases.

Both require explicit opt-in on the space. Off by default.

## Testing scope isolation

Space settings → **Test isolation**. Enter two scope keys and a query. Nora runs the query under each scope and shows that no items leak between them. Fails loudly if isolation is broken.

Recommended before shipping any Flow with multi-user memory.

## Debugging leaks

If an Agent seems to know something it shouldn't:

1. Check the Trace's memory ops — every read and write is logged with its scope.
2. Look for items written under a broader scope than intended.
3. Look for accidental cross-scope tool calls.

The most common bug: forgetting to set scope on the Trigger, so everything lands in a single global scope. Test isolation catches this.
