# Memory in Connect

Memory is what Connect has learned about a business and the people it deals with, held at four tiers — workspace, channel, endpoint and contact — and resolved narrowest-first when a reply is being written. Anyone in the workspace can read every tier, correct a line that is wrong, and forget any of it. Nothing here is a black box you have to argue with.

- **Status:** Available
- **Audience:** both
- **In the app:** #/relationships, #/data
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/memory/

## Four tiers, and why the narrowest wins

`connect_memory` holds memory at four scopes, and `tiers()` returns everything that applies to one piece of work split by the tier that owns it. The order is the same one [autonomy](/docs/autonomy/) uses — **workspace → channel → endpoint → contact** — which is not a coincidence: a business that has learned to think about permission at four scopes should not have to learn a second hierarchy for what Connect knows.

| Tier | Covers | A line that belongs here |
|---|---|---|
| Workspace | The whole business, every channel, every contact | How the business describes what it sells |
| Channel | One of email, whatsapp, sms or voice | How replies on this channel should be signed off |
| Endpoint | One mailbox or one phone number | That this number is the service line, not the sales line |
| Contact | One person | That this person prefers WhatsApp and works nights |

An **empty tier is returned rather than dropped**. That sounds like an implementation detail and is the reason the viewer can tell you "nothing is set here" as a positive answer instead of showing you a gap you have to interpret. When a reply reads oddly and the contact tier is genuinely empty, you have learned something; if the empty tier were silently omitted you would have learned nothing at all.

## Memory is not Knowledge

These are two different things with two different screens, and confusing them is the most common mistake on this subject. **Knowledge** is material a workspace supplies — a price list, a policy document, a specification — that an answer has to be grounded in. **Memory** is what Connect worked out for itself, or was told directly, in the course of the work.

**Knowledge** — Supplied. Lives in the [knowledge bank](/docs/knowledge/), is retrieved for an answer, and is the thing a claim is checked against.
**Memory** — Learned or dictated. Lives in `connect_memory` at one of four tiers, and shapes how Connect behaves rather than what it cites.
**Fact** — One grounded statement pulled out of Knowledge or a conversation. Narrower than either — see [the facts editor](/docs/knowledge/facts/).
**Standing instruction** — A durable direction from a person. It is written as memory, but it is an instruction, not an observation.

> **Note** Connect has no vector database. Grounding is retrieval over the Knowledge a workspace supplied, not embedding search over everything it has ever seen — the honest account is on [grounding without a vector database](/research/grounding-without-a-vector-database/). Memory is a small, readable set of rows, which is exactly why a person can audit it.

## Everything a person may do to it

- **Read** every tier, from the memory viewer, the contact panel, the channel screen or the memory sheet in [Data](/docs/files-data/).
- **Write** a line by hand, or tell the [Connect Assistant](/docs/assistant/) to remember something.
- **Correct** a line that is wrong, which is the fastest way to change future behaviour.
- **Supersede** a line whose truth has changed, keeping the old one readable.
- **Forget** any of it, at any tier, including something Connect learned by itself.
- **Block** a contact on one channel or all of them, which is a memory row rather than a column.

None of that is an administrator-only capability, and none of it differs between the Owner workspace and a customer's. Memory runs on one implementation for both audiences, so a screenshot from one is a true picture of the other.

## Where it is actually used

Memory reaches an email reply through the drafting step of the agent loop, and it reaches a phone call through `voice_engine.brief()`, which renders the persona, the line's purpose, the contact's facts and standing instructions, the knowledge and the hard rules once per call. Those two doors have very different budgets. A drafted email can afford to carry more context than a live call can, because on a call every character of the instruction is paid for in the time before the caller hears a voice.

The measured numbers are blunt: an instruction of 7,500 characters produced a first token in 1.2–1.8 seconds, and 9,600 characters produced 2.3–3.4 seconds. That is why the call path caps memory at **700 characters** and the contact block at **600** — see [how memory reaches a reply](/docs/memory/memory-in-channels/) for the full set of doors and budgets.

## Everything in this section

14 pages, each with its own status and the date it was last checked against the running system.

| Page | What it covers |
|---|---|
| [Block and guidance directives](/docs/memory/directives/) | The two memories that direct behaviour rather than describe it: a block carried in the tag list, and a standing instruction carried in the text. |
| [Business memory](/docs/memory/business-memory/) | The workspace tier: what a business should tell Connect once so it holds everywhere, and the four kinds of line that do not belong there. |
| [Channel and endpoint memory](/docs/memory/channel-context/) | The two middle tiers: what Connect should know about a whole channel, and what belongs to one mailbox or one phone number instead. |
| [Editing a memory](/docs/memory/editing/) | Changing a memory that is worded badly or plainly wrong: what an edit touches, what it does not touch, and when superseding is the right move instead. |
| [Forgetting something](/docs/memory/deleting/) | What forgetting actually removes in Connect, what deliberately survives it, and the two deletions that have consequences people do not expect. |
| [How a memory is created](/docs/memory/creating-memory/) | The four ways a memory gets written in Connect — by hand, by the Assistant, at the end of a call, or as a deliberate correction — and what each one records. |
| [How memory reaches a reply](/docs/memory/memory-in-channels/) | The door memory goes through on each channel, the character budgets on the voice path, and why instruction size is a latency decision rather than a preference. |
| [Memory from a phone call](/docs/memory/memory-from-call/) | What a phone call leaves behind: the end-of-call write, the two filters that stop a thin call producing facts, and the guards that refuse a misheard name. |
| [Memory from an email or a chat](/docs/memory/memory-from-conversation/) | Why an email or a chat does not silently become memory, what a person or the Assistant may take from one, and how a written instruction inside content is treated. |
| [Person memory](/docs/memory/person-memory/) | The contact tier: what Connect keeps about one human, how it follows them across channels, and the 600-character block that reaches a live call. |
| [Seeing what Connect knows](/docs/memory/viewing/) | Where the memory viewer opens from, how it groups what it shows, and the second route through the Data grid when you want to read a whole tier at once. |
| [Superseding a memory](/docs/memory/superseding/) | Replacing a memory whose truth has changed while keeping the earlier statement readable, and why that is different from editing it in place. |
| [The four memory tiers](/docs/memory/tiers/) | Workspace, channel, endpoint and contact: what each tier is for, how tiers() resolves them narrowest-first, and why an empty tier is still returned. |
| [Where a memory came from](/docs/memory/provenance/) | Why every memory needs an answer to 'who said so': the four origins, what the record keeps, and how to write a row that explains itself later. |

## Questions

### Does Connect remember every conversation automatically?

No. Conversations are stored as threads and messages and stay readable, but that is history, not memory. A memory row is a deliberate, durable claim about how things are — written by a person, by the Assistant on request, or extracted at the end of a call. The difference matters because memory changes future behaviour and a message archive does not.

### Is memory shared between workspaces?

Never. `connect_memory` is a workspace-scoped table, so it is filtered by the SQLAlchemy workspace kernel and again by PostgreSQL row-level security. One business cannot read another's memory, and neither can a mistake in a query.

### Can Connect remember something I did not ask it to?

Yes — a call or a conversation can produce a memory without anyone typing it. That is why the viewer exists and why every tier is readable. If Connect has learned something you would rather it had not, forgetting it is one action and takes effect on the next piece of work.

## Related

- [The four memory tiers](https://connectbyjbrh.com/docs/memory/tiers/)
- [How a memory is created](https://connectbyjbrh.com/docs/memory/creating-memory/)
- [Seeing what Connect knows](https://connectbyjbrh.com/docs/memory/viewing/)
- [Block and guidance directives](https://connectbyjbrh.com/docs/memory/directives/)
- [Knowledge in Connect](https://connectbyjbrh.com/docs/knowledge/)
- [What Connect may do](https://connectbyjbrh.com/docs/autonomy/)

## What this page is based on

- docs-source/sources/GENERAL.md §6 — memory, four tiers and directives()
- docs-source/sources/GENERAL.md §3 — the data model and workspace scoping
- docs-source/sources/PHONE.md §7 — instruction size and the character budgets
- `docs-source/facts.py` — CAPABILITY_STATUS.memory_tiers, MEASURED
