Skip to content

Share a memory with someone

PortalCLIAPIIntermediate~10 min

Let exactly one person in, and take it back whenever you want. A memory share hands one named colleague reader or writer access to a memory of yours — without adding them to a team, without making it org-wide, and without changing who owns it. Nobody else gains anything.

You can do all of it in the portal. Open a personal-class memory you own and pick its Sharing tab: it lists who currently has access, and lets you grant a person, change their role, or revoke them. That is the whole task, with nothing installed — the numbered steps further down are the same four operations from the hadron CLI, for when you want to script them. (The tab appears only for someone who may see the share list, so on a memory that is not yours you will not find it.)

It's the narrowest of Hadron's access mechanisms. If you want a group with symmetric access, you want team membership on a group-class memory instead; if you want a whole organization to read something, you want a knowledge memory and org membership.

What can be shared

Only personal-class memories. That's the whole rule, and it's worth internalising because the failure mode is opaque (see Troubleshooting).

Class Shareable? Use instead
personal Yes —
private No — owner-only, by design Nothing; privacy is the point.
knowledge No Org membership, or a cross-org subscription.
group No hadron memory member — symmetric team access.
app, system No App/Agent scoping.

Who you're allowed to share with

There's a second rule on top of the class, and it depends on whether the memory belongs to an org:

  • An org-owned personal memory can be shared only with a current member of that org. Naming an outsider fails with CrossOrgShareNotAllowedError.
  • A free-standing (org-less) personal memory — one created with --owner-me — can be shared with anyone.
  • Agent-scoped personal memories are exempt from the org-membership restriction above — their audience is governed by App membership and the user's Agent subscription rather than by org membership. Shares still apply; in fact this is the pattern shares were built for (see below).

Shares are how per-pairing isolation works

On an Agent-scoped personal memory, the share is the mechanism: Alice's memory paired with Mentor A is a different memory from the one paired with Mentor B, each with its own share. So don't read the exemption above as "shares don't apply here" — it only means the grantee doesn't have to be an org member; App membership and the Agent subscription govern instead.

Before you start

  • You must be the memory's principal — its owner. Only the principal can grant, change, or revoke a share on it. There's no admin override.
  • You need a way to name the grantee. Any of these work:
usr_01hx…                 the user's id
jane@acme.com             email
@jane                     handle
hrn:user:jane             the user URN

The server resolves the reference against the full user table, so sharing a free-standing memory by email or handle works even when you have nothing else about the person.

1. Grant access

hadron memory share create acme.com:my-notes --grantee jane@acme.com --role reader

Two roles, and the difference is exactly what it sounds like:

Role Can
reader Read every node in the memory.
writer Read, and create, edit, and delete nodes.

Neither confers ownership. A share never lets the grantee re-share the memory, delete it, or manage its other shares — those stay with the principal.

create upserts: naming someone who already has a share updates their role instead of failing, so it's safe to re-run.

2. See who has access

hadron memory share list acme.com:my-notes   # `ls` is an alias

Each row shows the grantee, the role, and when it was granted. The grantor is always the principal — even when an App backend made the call on their behalf, in which case the acting party is recorded separately in createdBy.

3. Change a role

hadron memory share set-role acme.com:my-notes --grantee @jane --role writer

Re-running create with a different role does the same thing; set-role just says what you mean.

4. Revoke, or leave

The principal removes someone else's access by naming them:

hadron memory share rm acme.com:my-notes --grantee @jane --yes

A grantee removes their own access by omitting --grantee — the "stop sharing this with me" path:

hadron memory share rm acme.com:my-notes --yes

Two things to know about revocation:

  • It takes effect on the next read. There's no deactivated state — the row is deleted — so an in-flight request may still complete.
  • Revoking as the principal is idempotent: removing a share that's already gone succeeds. Leaving is not — the share row is your authorization, so a second leave answers FORBIDDEN (you already left).

A grantee can leave a memory even after its owner has soft-deleted it, so a share can't strand you.

Troubleshooting: FORBIDDEN is deliberately vague

If you're not the principal, every failure looks the same. FORBIDDEN does not distinguish between:

  • the memory doesn't exist,
  • the memory isn't personal-class, or
  • you aren't its principal.

That's intentional — collapsing them stops the API being used to probe which memories exist. The same uniformity covers the grantee reference: a non-principal gets FORBIDDEN whether or not the named user exists, so users can't be enumerated either.

So if a share fails and you are the owner, check the class first — a private or knowledge memory will refuse a share and tell you nothing more. As the principal you will get a distinct NOT_FOUND when the grantee reference resolves to nobody, which is the one case that's safe to report.

Other named failures: CrossOrgShareNotAllowedError (the grantee isn't a member of the org that owns the memory) and MemoryShareGranteeMissingError (the reference didn't resolve to a user).

Other surfaces

  • GraphQL — createMemoryShare / deleteMemoryShare / the share list, with granteeRef taking the same id / email / handle / URN forms. (The older granteeId argument is deprecated in favour of granteeRef.) See the GraphQL API reference.
  • Portal — the full owner's half: the memory's Sharing tab lists who has access and lets you grant, change a role, and revoke (portal#839, closing #668). Separately, you can see memories shared with you, and leave one, from the memories list.
  • MCP — no share tools yet.