---
name: conversational-memory
description: "Notice, store, and recall who the owner is and how they work, accumulated from natural conversation rather than forms. Use when recording or retrieving user profile, preferences, and remembered context across sessions."
---

# Conversational Memory

Invoked by the admin agent directly.

Memory accumulates from conversation — never from questionnaires, quizzes, or onboarding forms. The owner reveals who they are and how they work through natural interaction. Your role is to notice, store, and recall that knowledge so every session feels continuous rather than starting from scratch.

## Every active preference is injected on every turn, so keep each one minimal

Every active preference is prepended to the agent's context on **every single turn**, for the life of the account. A verbose preference is not a one-time cost. It is paid again on every future turn, and it crowds out the live conversation. Concision here is not a matter of style. It is a hard, non-negotiable requirement: a preference that is not precise and concise is a defect.

Injection surfaces every stored active preference verbatim. Nothing de-duplicates or trims at injection time, so a redundant or bloated preference you store is injected on every future turn exactly as written. Write-time discipline is the only guard: keep each value minimal, and fold an overlapping preference into the existing one rather than storing a second.

Each `value` is one precise imperative: the rule itself and nothing else. Strip everything that is not the rule.

- No provenance or history ("Set 09/07/2026 after X went wrong", "SUPERSEDES the old rule", "Confirmed by Dale").
- No rationale, justification, or worked examples.
- No restating the contents of a file or asset. Point to it by path instead.
- No exceptions essay. State the rule, and at most the single exception that matters.

Write the shortest form that is still unambiguous. If a preference runs longer than a sentence or two, it is carrying something that is not the rule. Cut it, or move the detail to a file and point at the file.

Verbose (defect): "Dale's email sign-off is always 'Regards,' followed by 'Dale Smith', never 'Cheers,' or any other closer. Applies to every email drafted or sent on his behalf, in both the plain-text and the HTML signature block. Use 'Regards, Dale Smith' going forward without exception."

Terse (correct): "Email signature: apply quoting/templates/assets/gls-email-signature.{html,txt} verbatim to every draft; never re-create it."

## A preference points at the capability it needs, never reimplements it

If an installed skill, tool, or plugin already provides what a preference asks for, the preference names that mechanism and directs you to it. A preference is configuration and routing. It is never a reimplementation of a capability the install already has.

"Wants reminders" is not a preference. Reminders are a scheduler job. The scheduling plugin owns them. So either the preference routes to that owner:

Terse (correct): "Chase outstanding client sign-offs by scheduling reminders via the scheduling plugin."

or, better, it becomes an actual scheduled task and there is no preference at all.

The failure this prevents: a behavioural note that says "wants proactive reminders" implies you should freehand-remember to act, which you cannot do reliably, and it drifts from the real mechanism. The same test applies to any capability the install owns: recalling past conversation is `conversation-search`, putting something on the calendar is the scheduling plugin. When a preference's substance is one of those, route it, do not restate it.

## Memory Tools

| Tool | Purpose |
|---|---|
| `profile-read` | Read profile and preferences. Use `detail: true` for transparency (confidence, evidence, stats). |
| `profile-update` | Create or update a preference. Modes: `reinforce`, `update`, `contradict`, `merge`. Also sets UserProfile fields via `profileFields`. |
| `profile-delete` | Remove a preference. Use when the owner says to forget something. |
| `conversation-search` | Semantic search over past messages. Use to recall specific past interactions. |
| `session-compact` | Write session context to the graph at compaction time. |

## When to Observe

Store a preference when the owner reveals something about how they work — either by telling you directly or by demonstrating it through their behaviour.

**Explicit signals** — the owner states something directly:
- "I prefer short answers"
- "Never schedule before 10am"
- "Always CC my partner on invoices"
- "I make decisions quickly — just give me the options"

Store these with `source: "explicit"`. They carry high initial confidence because the owner said them intentionally.

**Behavioural signals** — the owner demonstrates a pattern without naming it:
- They consistently ask for summaries instead of details (→ `communication/response_detail: "prefers summaries over detail"`)
- They always reschedule Monday tasks to Tuesday (→ `scheduling/monday_preference: "avoids Mondays for deep work"`)
- They reject formal language in drafts and rewrite casually (→ `content/writing_tone: "casual, direct tone"`)

Store these with `source: "behavioural"`. Only store after observing the pattern at least twice — a single instance is noise, not signal. Use `mode: "reinforce"` on second observation.

**What NOT to observe:**
- One-off task instructions ("send that email now") — these are commands, not preferences
- Emotional reactions to external events — transient, not characteristic
- Anything the owner explicitly asks you NOT to remember

## Operating a client's account on the owner's behalf

When you are a house operator working inside a client's sub-account, the preferences you capture there belong to that client, the account's owner on record, not to you. Attribution is automatic. A preference stored while you operate a client's account is written against that owner, and "what does this owner prefer?" reads the owner's list. You pass no target and no flag; the tool decides from who is driving the session.

Your own working preferences belong to your own session, not a client's. Store them when you are operating your own account.

If a client's account has no owner on record, a preference write is refused out loud rather than saved to your profile. That means the account's graph root was never seeded, so it cannot hold owner preferences until it is.

## How to Store

Every `profile-update` call should include:
- `category` — one of: `communication`, `scheduling`, `decision`, `workflow`, `content`, `interaction`
- `key` — a stable identifier for this preference (e.g., `response_length`, `meeting_time`, `writing_tone`)
- `value` — the rule itself, one precise imperative, nothing more (see "keep each one minimal" above)
- `source` — `"explicit"` or `"behavioural"`
- `sessionId` — always include this for evidence linking. The conversation ID is available in the session context.

### Modes

- **First observation**: omit `mode` (creates new preference at confidence 0.5)
- **Re-observation**: use `mode: "reinforce"` (boosts confidence toward 1.0)
- **Value changed**: use `mode: "update"` (new value, same confidence)
- **Contradicted**: use `mode: "contradict"` (drops confidence by 0.3)
- **Overlapping preferences**: use `mode: "merge"` with `mergeSourceIds` to combine

### Keys

Use consistent, descriptive keys. If a preference already exists for the same concept, reinforce or update it rather than creating a duplicate with a different key.

## UserProfile Fields

`profile-update` also sets top-level properties on the UserProfile node via the `profileFields` parameter. This is distinct from preference management:

- **Preferences** (category/key/value) — learned behavioural patterns stored as separate Preference nodes with confidence scores and evidence trails
- **UserProfile fields** (profileFields) — account metadata stored directly on the UserProfile node: `timezone`, `locale`, `givenName`, `role`, `expertise`

Use `profileFields` when the owner provides factual account information (their timezone, their name, their role) rather than a behavioural preference. Both can be set in a single `profile-update` call.

## Remember and Forget

When the owner explicitly asks you to remember something:
1. Store it with `source: "explicit"` — this signals high intentionality
2. Confirm what you stored: "I'll remember that you prefer meetings after 2pm."
3. Do not embellish — store exactly what they said, not your interpretation

When the owner asks you to forget something:
1. Call `profile-delete` with the matching `category` and `key`
2. Confirm: "Done — I've forgotten your preference about meeting times."
3. If you're unsure which preference they mean, ask before deleting

When the owner corrects a preference:
1. Call `profile-update` with `mode: "update"` and the new value
2. Confirm: "Updated — I now know you prefer Tuesdays over Wednesdays for reviews."

## "What Do You Know About Me?"

When the owner asks what you know about them (or any variation — "what have you learned?", "what do you remember?", "do you know my preferences?"):

1. Call `profile-read` with `detail: true`
2. Present the results conversationally — do not dump raw data
3. Group by category, include confidence level and how you learned each preference
4. Offer to correct or remove anything: "Want me to update or forget any of these?"

The detailed response includes confidence labels (strong, moderate, fading, weak) and evidence (which conversations the preference was observed in). Use these to explain your knowledge transparently.

## Memory Precedence

Memory informs the current conversation — it does not override it.

- If the owner's current message contradicts a stored preference, follow the current message. Call `profile-update` with `mode: "contradict"` to adjust the stored preference.
- If a preference is labelled "fading" (confidence below 0.5), treat it as tentative — do not act on it without checking. Preferences decay over time when not re-observed.
- If the owner's behaviour has clearly changed, update the preference rather than clinging to the old value. People evolve.

## Session Context

At compaction time, `session-compact` captures the session's key context (decisions, work in progress, open questions, things learned about the owner). This context can be recalled in future sessions via `session-compact-status`.

Preferences captured during a session persist independently of compaction — they are written to the graph as they are observed, not batched at session end.
