docs/prominence.md
Rama main · réplica de lectura del repositorio original.
<!-- authority:non-specification -->
# Prominence — how much Exomem speaks up
Exomem has one knob for how much it participates in a conversation. It is separate
from `exomem mode`, which governs how much of your *machine* Exomem may use. A laptop
on battery can still want maximal recall; a workstation can still want Exomem to stay
out of the way.
| Level | Recall | Capture | Narration |
|---|---|---|---|
| `off` | never on its own | never on its own | silent |
| `light` | only when you ask, or the turn is unmistakably on-topic | only when you ask | silent |
| `balanced` | on topic match | durable conclusions | quiet; mentions the KB only on a hit |
| `maximal` | before every substantive turn | every stepping stone | says what it recalled and saved |
For generated files, balanced and maximal apply a bounded adoption rule:
handing a file to the user is the trigger. The agent keeps the exact bytes of
every generated file it hands over, at hand-over, under `proactive_capture`, and
chooses Source or Evidence by semantic role rather than MIME. Drafts it never
hands over stay unwritten, and so do files it writes in your own workspace or
repository. Without a usable handle, it returns a non-committing handoff status
instead of claiming a save. Delivery is later and receipt-gated through an
existing compatible Records collection; reported remote identity never proves
remote byte equality.
Off and light remain explicit-request-only.
## Change the level through your agent
Ask your connected agent to inspect or change your engagement level. It uses
`configure_memory(action="inspect")`, then passes the returned `revision` as
`expected_revision` to `configure_memory(action="set", prominence="maximal", ...)`.
The response includes the saved level and effective contract; the agent should
apply that contract immediately. Subsequent calls read the setting without a
service restart.
This preference belongs to the addressed vault and authenticated identity.
Clients presenting the same identity share it. Local CLI/stdio and the shared REST
key use the local owner identity; OAuth identities remain distinct. The generated
`configure_memory` CLI command uses the same operation. A stale revision requires
a fresh inspect; an operator's conflicting `EXOMEM_PROMINENCE` override is reported
instead of claiming that the requested change took effect.
## One level while coding, another in chat
You can hold two levels at once. Every request lands in one of two **engagement
contexts**, and a saved level can belong to a context rather than to you as a
whole:
- `conversation` — claude.ai, ChatGPT, the hosted service, and every other client
that cannot run hooks.
- `coding` — Codex, Claude Code, and any client the server does not recognise.
Add `context` to a set and the level applies only to clients of that context:
`configure_memory(action="set", prominence="balanced", expected_revision=..., context="coding")`
leaves your identity-wide value untouched and quiets coding clients alone.
`configure_memory(action="clear", context="coding", expected_revision=...)` removes
it again; clearing a context that holds nothing changes nothing and says so.
A set without a `context` keeps its original meaning and writes the identity-wide
value.
A clear still goes through when an operator has pinned `EXOMEM_PROMINENCE`, and the
response reports that the pin is active and still decides the effective level —
removing a saved value cannot contradict the pin, and refusing would leave saved
context values stuck. A *set* that conflicts with the pin is still refused.
The context that applies to a request is **detected from the calling client**, or
from an operator's explicit `EXOMEM_SURFACE`. On Exomem Cloud, the control plane's
client registry assigns each connected app its context, and the cell applies that
before detection. No argument selects it, and it is an
eagerness knob only: it never picks an identity, a vault, a storage path, or an
authority ceiling. An unrecognised client is treated as `coding`, so it keeps the
generic default.
`inspect` reports the identity-wide value, every saved context value, the context
this request resolved under, and the effective level. All of it lives in one record
under one revision, so a set and a clear cannot interleave behind each other's back:
whichever lands second is asked to inspect again.
The older `exomem prominence <level>` command remains a machine-wide control.
Standalone hooks read that legacy configuration and environment; they do not
inherit another authenticated identity's vault preference.
The versioned hosted agent profiles retain their pinned command lists and do not
yet expose `manage_memory` with `settings.set`. Adding it there requires a new hosted profile.
## Which level you get by default, and why
**Assistants with hooks — Claude Code, Codex — default to `balanced`.** Those clients
run a capture/retrieve nudge that re-arms the check, so moderate
instructions are enough. Below `maximal` the capture reminder fires on turns that
land work (a commit, push, merge, tag, or PR/release create or merge),
not on reply length; `maximal` keeps the length gate. The periodic episode check
(every few substantive turns) also needs a landing since the last check or record, so a
session that never lands work is not asked and an unanswered check waits for the next landing.
**Assistants without hooks — claude.ai, ChatGPT, the hosted service — default to
`maximal`.** There is nothing there to re-arm the check, and instruction text decays
over a long conversation: the model reads it at turn 1, then gradually stops acting on
it. `maximal` on a hookless client produces roughly the behaviour `balanced` produces
on a hooked one. If Exomem seems to "forget to remember" in a web chat, this is why —
raise the level rather than concluding recall is broken.
Nothing stops you overriding either default. The intent is that you **tune down** if
it is too chatty, not that you have to tune up to get it working.
## Setting it
On a local install, where the setting reaches both the server and the CLI:
```
exomem prominence # show the active level and its full contract
exomem prominence maximal # set it
exomem prominence --hook-env # print the nudge tunables this level implies
```
Precedence is `EXOMEM_PROMINENCE` (env) → the saved value for this request's
engagement context → the saved identity-wide value → the legacy machine config →
the known client default. The legacy command stores its level beside `mode`, so
setting one never clears the other. `bootstrap()` reports the effective level, the
applied context and the source under `engagement` — `preference:context` when a
context value won, `preference` when the identity-wide value did.
Connected web clients save their choice through `manage_memory` with `settings.set`, just like
other agents. The optional custom-instruction blocks below help the assistant
follow the policy, or provide instructions when that tool is unavailable; they
do not persist a server preference.
### The nudge hooks read your own machine, not the server
A level saved through `settings.set` is stored on the **server**, per
identity. The capture and retrieve nudge hooks are standalone copies installed
into a hook directory on your **client** machine, and they resolve from
`EXOMEM_PROMINENCE` and that machine's exomem configuration file only. They
cannot ask the service: they do not import the package, and a client talking to
a service on another box has no credential to ask with.
So on a client that runs them the two can disagree. Saving `off` through the
agent makes every response say "never write on your own initiative" while the
Stop hook on your laptop keeps injecting the capture reminder on its own timer.
That is why `bootstrap()` and `settings.set` serve a `hook_cadence` block to
every client in the **coding** context -- Claude Code, Codex, and any client
Exomem does not recognise, since an unrecognised client is far more likely to be
a hooked CLI than a web connector. Conversational clients get nothing, because
there is genuinely no cadence there to be out of step with.
Run `exomem prominence <level>` **on the machine running the hooks** to change
the nudge cadence. That command moves the hooks and nothing else: your saved
preference still decides what the server serves, which is why the block says so
in as many words. Where the server and the client are the same machine, the one
command settles both, because the CLI writes the file the hooks read and the
server resolves that file as its last rung before the client default.
---
## Copy-paste blocks
Each block is self-contained. Paste it into:
- **claude.ai** — Settings → Profile → *"What personal preferences should Claude
consider in responses?"*
- **ChatGPT** — Settings → Personalization → Custom instructions → *"Anything else
ChatGPT should know?"* (each field caps around 1500 characters; these fit)
Replace the connector name if you named yours something other than Exomem. Otherwise
paste the block as it stands rather than writing your own shorter version of it.
These blocks set how much Exomem speaks up; what it may DO on its own is the
delegation envelope, with its own block in
[What Exomem does on its own](#what-exomem-does-on-its-own) below.
**Each item in the capture list is a separate switch, not an example of a general
idea.** An assistant treats that list as the definition of what is worth saving, so
dropping an item deletes that whole class of capture — silently. Nothing errors, no
warning appears, and the symptom is only that some kind of thing never gets written,
which is close to impossible to notice from inside a conversation. A shortened list
has already cost a real user months of uncaptured hands-on results: it kept the four
knowledge-work items and dropped the rest, so every method actually carried out fell
through. If a level is nearly right, append a tuning line from the section below
instead of trimming the block — that keeps the classes intact and changes only the
threshold.
Watch the recall and capture lines separately, too. A clause such as "stay quiet on
chit-chat" belongs to recall; moved or generalised to capture, it suppresses exactly
the casual-looking conversations where a real result tends to arrive.
### The learning instruction — paste it first at Balanced and Maximal
The level blocks state policy. This instruction is your own request to recall
before a task and to save what the task establishes. Paste it ahead of the
Balanced or Maximal block. With either block it is longer than one 1,500-character
field, so on ChatGPT give it a field of its own. `exomem setup` offers the same
text for Claude Code and Codex. Leave it out at Light and Off: those levels save
only when you ask.
```text
Use Exomem as the memory for my work. Before you start a task, recall what Exomem holds about the systems, projects or topics it touches. As you work, save each reusable fact you establish (how something is structured, a pitfall, a method that worked) as one concise observation, and update an existing note when one covers it, so a later session does not have to find it again.
```
### Maximal — recommended for web and hosted
```
I use Exomem as my durable Knowledge Base. If no skill is loaded, call bootstrap(profile="compact") once per chat and follow it.
Exomem prominence: MAXIMAL.
- Recall: search before every substantive turn; skip only chit-chat/control. Cite useful hits. An empty result is a scoped miss and reason to capture.
- Capture: save every stepping stone: decision, solved problem, diagnosed failure, reusable pattern, reusable fact about a recurring entity, or a method carried out with a reported useful result. A stable preference, recurring routine, historical baseline, or durable affiliation qualifies only with stability or recurrence plus reusable comparison, interpretation, or decision value. Use a uniquely resolved Entity's narrow facet, else concise compiled observation; these, new Entity, own edge: `proactive_capture`; Records only for a compatible measurement; queued relation: `link_acceptance`; merge/structural change: confirmed `restructure_execution`. Fleeting preferences, one-offs, incidental associations, trivial metrics, and tentative claims stay quiet. When torn between saving and letting it pass, save. Never save transcripts.
- Entities: once per chat, after primary work and before the final response, list_review_items(queue="due", categories=["entity_recurrence"], limit=3); skip if unavailable.
- Narration: cite recalls; after a write say "Saved -> <title>".
- A committed final mutation result is authoritative; never invent a failure code from warnings.
```
### Balanced — the default where hooks exist
```
I use Exomem as my durable Knowledge Base. If no skill is loaded, call bootstrap(profile="compact") once per chat and follow it.
Exomem prominence: BALANCED.
- Recall: search when a turn concerns my projects, domains, named entities, or prior conclusions, attempts, or decisions. Skip chit-chat, control, and answered follow-ups; cite useful hits.
- Capture: save at a stepping stone: a durable conclusion, reusable fact about a recurring entity, or a method carried out with a reported result. A stable preference, recurring routine, historical baseline, or durable affiliation qualifies only with stability or recurrence plus reusable comparison, interpretation, or decision value. Use a uniquely resolved Entity's narrow facet, else concise compiled observation; these, new Entity, own edge: `proactive_capture`; Records only for a compatible measurement; queued relation: `link_acceptance`; merge/structural change: confirmed `restructure_execution`. Fleeting preferences, one-offs, incidental associations, trivial metrics, and tentative claims stay quiet. Not mid-thought exploration, tangents, or open questions. Never save transcripts.
- Entities: once per chat, after primary work and before the final response, list_review_items(queue="due", categories=["entity_recurrence"], limit=3); skip if unavailable.
- Narration: stay quiet; cite useful recalls and after a write say "Saved -> <title>".
- A committed final mutation result is authoritative despite adjacent warnings.
```
### Light — when it is getting in the way
```
I keep a personal Knowledge Base served by the Exomem MCP connector.
Exomem prominence: LIGHT.
- Recall: search Exomem only when I ask a recall question outright, or when the turn is unmistakably about a topic it covers. When in doubt, don't search.
- Capture: write to Exomem only when I ask. Do not save on your own judgment, however durable the conclusion looks.
- Narration: never mention searching. Fold anything you retrieve into the answer with a citation and nothing more.
```
### Off — explicit invocation only
```
I keep a personal Knowledge Base served by the Exomem MCP connector. Use it only when I explicitly ask you to search it or save to it. Never search or write on your own judgment, and don't mention it otherwise.
```
---
## Tuning without changing level
If a level is nearly right, these are the usual adjustments, each a line you can
append to the block:
- Too much saving, recall is fine — *"Capture only decisions and diagnosed failures;
skip patterns and entity facts."*
- Right amount of work, too much talking — *"Do not narrate recall; keep the one-line
save report."*
- Should stay out of one area — *"Never search or save anything about <topic>."*
- Recall keeps missing — check coverage first with a direct question before raising
the level. An empty result on a topic you never captured is honest, not a failure.
## What the level does not change
The level governs *when* Exomem acts, never what it is allowed to touch. Governed
writes stay inside the Knowledge Base folder at every level, `Sources/` and `Evidence/`
stay append-only, and access policy is enforced independently. `maximal` is more
eager, not more privileged.
---
## What Exomem does on its own
The level says how much Exomem speaks up. A second, separate contract — the
**delegation envelope** — says what it may do on its own, per kind of action,
and it is the one that keeps an eager level from turning into an eager hand.
Each kind of action carries a hard **ceiling**, which is product law: no level,
no setting and no amount of use authorizes anything above it. Below the ceiling
each kind carries a disposition — `off`, `advisory`, `silent`, `confirm` or
`confirm-shortcut` — derived from your level unless you set one explicitly.
You do not have to memorise the table and you should not paste one: `bootstrap()`
reports the live envelope under `engagement`, and
`list_review_items(queue="dispositions")` shows it beside whatever you have quieted.
Append this to your custom instructions instead:
```
Exomem serves a delegation envelope under `engagement` when you call bootstrap. Follow it: name the action class before you act; treat an intent above that class's ceiling as a proposal rather than an act; honour the class disposition (off — do not start it on your own, though anything I ask for outright is never blocked; advisory — tell me in plain language and stop; silent — go ahead, and narrate as the level says; confirm or confirm-shortcut — get my confirmation first). Record what I decide through triage so it sticks. Restructure application, supersession, entity merge, deletion, removing an edge and reverting a promotion always need my confirmation, while a new entity, your own edge and my type or relation saves follow proactive capture, and "always allow that from now on" does not exist yet — say so rather than inventing either a refusal or a permission for it; it is a founder decision, not yours or mine. If I ask you to stop suggesting some KIND of thing, quiet that signal family rather than lowering my level, which silences everything: the registered family names are listed by list_review_items(queue="dispositions"), and you pick the one my words mean.
```
That block is deliberately not a table. The envelope moves when you change level
or set an override, so a pasted copy of today's values is a copy that goes
stale in every account that ever used it — and unlike the level blocks above,
nobody re-pastes this one.
To set or reset a served class, use
`triage_memory(ref="exomem://envelope/<action-class>", action="<disposition>|reset")`.
Two consequences worth knowing as a user. **Confirm-required is not advice.**
Deletion, restructure application, supersession and entity merge ask you every time,
whatever your level; some of those are enforced by the server and some are the
assistant honouring the contract, and the served envelope says which is which
rather than implying a gate that is not there. **Nothing here adapts behind your
back.** Three items of one family put down by hand earns one offer to quiet that
family, once; declining it by saying nothing is durable, and nothing is ever
quieted, loosened or tightened except by a decision you actually make.