---
slug: links
title: "Links: reading another team's memory"
description: "Two memories are joined by entity aliases. The link is one-directional, and when memory content changes the aliases have to be updated too."
lang: en
---


# Links: reading another team's memory

AiAkiv's memories are **completely separated.** Search never turns up the team
next door. That's deliberate. Someone else's memories must not leak.

But real work doesn't stop at one memory. You want to pull an idea from your
personal memory into a company project; a head office and a partner firm serve
the same customer; a consultant can't bring accumulated case knowledge into a
client. **You know the answer is over there and there's no way to reach it.**
That's what a **link** solves.

> **In one line.** Two memories are joined by **entity aliases**. The link is
> **one-directional**, and when memory content changes the aliases have to be
> updated too.

## What a link is

**One line of read permission that two teams agreed to.** It has three
properties.

- **No copy is made.** You aren't handed the data; you look at it live. Changes
  to the original show immediately, and cutting the link makes it disappear.
- **It doesn't touch where you save.** It isn't a project switch. You name the
  link when calling a tool and read **only the other side.** Saying `ak save
  this` in that conversation goes into your Main as usual.
- **It's one-directional.** Accepting means **you read them**, not that your
  memory opens to them. To open the other way, **make a second link.**

### How this differs from importing

| | Does a copy exist | If the original changes | Undoing it |
|---|---|---|---|
| **Import** (export/import) | **Yes** | You don't know | You have to delete what you received |
| **Link** | No | Reflected immediately | Cut it and that's that |

### Linking to public memory is worth doing too

Public memory is readable by anyone already. But **being able to read something
and having it come up in your questions are different things.** If it isn't tied
to your memory, it won't surface when you ask. That's why making a link to a
public memory and connecting aliases is worthwhile.

## Making and managing links in the console

**Console → Teams → Links.** The screen is visible **only to the team owner**:
opening memory outward isn't something to view alongside internal permissions.

The list is split into **two groups**. The two kinds are opposites, and mixed
together they look like the same thing with a different status.

- **Links we read through** — we read the other team's memory. Five columns:
  `partner team · status · contract · readable now · expiry`. These are what the
  tools use during a conversation.
- **Links we provide** — the link opens our memory to the other team. There is
  nothing here for us to read, so there is no `readable now` column at all.
  Pausing, ending and aliases are done here.

Either way, pressing **Details** opens two tabs, `Details` and `Aliases`.

### Making one: propose and accept

One side **issues an invitation** and the other side's owner **accepts**, which
brings it to life. The acceptance dialog states the direction plainly.

> Accepting means we will read ○○ team's memories. **This is one-directional**:
> our memories do not open to them. For them to read ours, **we must issue an
> invitation.**

**Declining** closes that proposal. Making one again requires a new proposal.

### Cutting it: one side acting alone

**Pausing cuts even a read in progress, immediately.** And **only the team that
paused it can resume.**

Making it takes agreement from both; cutting it takes one. Deliberately. If
cutting required agreement, you'd be trapped whenever the other side stopped
responding.

### The Details tab: five conditions for reading now

Reading works only when **all five** hold. The screen shows them as a checklist.

| Condition | If it fails |
|---|---|
| Link status is 'connected' | It's pending, paused, or terminated |
| **Contract v2 in effect** | **Both owners must consent again** |
| The partner team still exists | They're gone |
| Not expired | The term has passed |
| This direction is open | This direction is closed |

If even one is off, **the tools are blocked.** It's the same determination as the
`readable now` column, so start here when reading doesn't work. When re-consent
is needed, it also shows which side (**ours or theirs**) hasn't done it.

**A link we provide shows only four.** The heading becomes `What has to hold for
the other team to read` and the last row (`This direction is open`) drops out —
that row is about the direction *we* read in, so a healthy link would carry a red
mark. The real direction is right below, under `Read direction`.

> **The display name is a record from contract time.** If the partner team
> renames itself afterwards, it isn't reflected. The `generation` number on
> screen means how many times this link has been established.

When and how the contract changed is in **Teams → Link history**. Who made,
changed, and cut it is recorded **for both sides**: it makes no sense for your
access to be cut without the affected party being able to see it.

## Aliases: this is the crux

### An alias is a path (but not a path for permissions)

The two teams' entities live in **different id spaces.** When **your memory and
theirs call the same thing by different names**, a person knows they're the same
and the system doesn't.

**An alias is the bridge that joins the two as "the same thing."** Traversal
steps on that bridge to move between the two entities.

```
the name in our memory   ←── same thing ──→   the name in theirs
```

**The most common misunderstanding here**: an alias is **not permission.** A
linked team's memories are **already readable** regardless of aliases. The table
below is that boundary.

| Tool | Works without aliases |
|---|---|
| `search_partner_memory`: search the partner memory directly | ✅ **Yes** |
| `find_partner_memory_connections`: cross-traverse starting from your side | ❌ Reaches them **only via a bridge** |
| `query_partner_memory_graph`: a graph query spanning both teams | ❌ The start point only resolves on your side |

So with zero aliases you can still **find** things on their side. The bridge is
needed for **starting in your memory, crossing over, and coming back**: and
that's where a link's real value is.

### What to connect and what to cut

The `Aliases` tab lists `ours ↔ theirs` pairs one after another. They come from
**automatic discovery** and **manual assignment**.

- **If it's the same name but a different thing, cut it with `Exclude`.** A wrong
  connection creates a false link between two memories, and once that gets into
  answers it's hard to find later.
- If you cut one by mistake, use `Reconnect`; to defer the judgment, send it back
  to `Candidate`.

The system finds candidates, but **the final call is a person's.** A similar name
doesn't mean the same thing.

### ⚠ Re-connect after saving new content

Bridges **do not maintain themselves.**

- **Newly created entities are not connected automatically.** After saving, press
  **`Connect same names`** again in the `Aliases` tab. It reports `Connected M of
  N same-name pairs`. If the result says it was truncated, **run it again and it
  continues from there.**
- **Merging an entity kills the bridge.** If an endpoint entity is absorbed by a
  merge, that alias becomes **`broken`** and stops working. Nobody cut it.

So **re-connecting periodically** is a good habit. If the link is alive but only
your cross-traversal results have gone thin, this is almost certainly why.

## Actually reading: five tools

Reading is done by **tools during a conversation**, not by a screen. The console
is where you make, cut, and tune aliases.

```
list_partner_links                     which links exist and which work now (usable)
  ├ search_partner_memory(sentence, link_id)   search the partner memory directly
  ├ find_partner_memory_connections(link_id, sentence)    start in your memory, cross the bridge
  ├ query_partner_memory_graph(link_id, query) a graph query spanning both teams
  └ get_partner_memory_content           read a partner record's body
```

Start with `list_partner_links`. `usable` tells you **which links will produce an
answer right now**, and for those that won't, `blocked_reason` points at **what
to fix.**

| `blocked_reason` | Meaning | What to do |
|---|---|---|
| `link_not_active` | Pending, paused, or terminated | Check the status in the console |
| `contract_version_too_old` | The contract is stale | **Both owners re-consent** |
| `principal_not_active` | This direction is closed | Open the direction |

**Links we provide are not in this list at all.** Links are one-directional, so
the side that issued the invitation has nothing to read — and nothing to fix.
Only the count comes back, as `provided_link_count`; they are managed in the
console's `Links we provide` group. Passing one of their ids to a tool anyway is
refused with `principal_not_active`.

### What cross-traversal tells you

`find_partner_memory_connections` marks each result with **which side it came from** (`side`), and
loads each bridge with **how common the term is on each side**. **"1 on our side,
109 on theirs"** means what's a passing mention to you is a central topic to
them. That number can be the answer by itself.

Entry happens **only from your side**, so nothing coming back from their side
doesn't mean "there's nothing there." It may be that **there was no bridge to
cross.**

## What doesn't work · things to know

- **You cannot save through a link.** A link is a reading capability.
- **Cutting takes effect immediately**: even mid-read. If a link is terminated
  while reading, it stops with **an explicit error**, not a truncated answer. You
  never receive a half answer.
- **It can't stop what the reader remembers.** You can't stop the other side from
  copying what they saw on screen into their own notes. What a link prevents is
  **the system copying everything wholesale**, not what's in someone's head. So
  **who you link with is still a question of trust.**
- **Treat their results as theirs.** When an AI mixes both memories in an answer,
  it's hard to retrace later unless which side each statement came from is kept
  distinct.

## Scenario: a consultant and a client

Consultant A goes into client B. B decides to open their memory to A for three
months.

1. **Making it**: B's owner issues an invitation to A, and A's owner accepts.
   Direction is B→A only; term is three months.
2. **Connecting aliases**: A presses `Connect same names` in the `Aliases` tab.
   When B's "payments module" and A's "payment gateway" come up as candidates,
   **a person confirms** and connects them, and `Exclude`s anything that only
   shares a name.
3. **Checking**: A checks `usable` with `list_partner_links`.
4. **Using it.** A asks: *"Retry policy for the payments module: have we done
   something similar before?"* Traversal **starts in A's memory**, picks up the
   older case, crosses the "payment gateway" bridge, and brings back **B's
   payment issues.** Next to the bridge it reads `ours 2 / theirs 87`: a topic
   that came up twice for A is a central topic for B.
5. **Reading bodies**: the partner-side results open with
   `get_partner_memory_content`. Throughout, **A's save target is unchanged**,
   so writing it up with `ak save this` goes into A's Main.
6. **The end**: after three months it closes automatically. Before that, B can
   cut it alone.

## Related

- Teams, projects, and the save target → [Teams and projects](teams-and-projects)
- Dividing visibility **inside** one team (sub-parts and roles) → [Creating and managing teams](teams)
- The console menus overall → [Console](console)
- What you may store → [What to store](what-to-store)
