Memory
What the company knows, how a run asks it and adds to it, how a wrong note is corrected, and why nothing secret belongs in it.
One memory for the company
Your enterprise has one memory: notes, each one sentence of something worth knowing next week. "Finance signs off invoices on Thursdays." "The CEO prefers Slack nudges in the morning."
Every note carries where it came from (who wrote it, and the message or event it was learned from), what kind of
note it is (a fact, an inference, a preference or a correction), and labels: the task, team, member or role
it concerns.
Labels organise; they do not fence. Memory is shared across the whole enterprise, and any run that asks can be answered from any team's notes. So never train a secret, a credential, or anything some of the enterprise should not read. Another enterprise's memory is never read, whatever a request asks for. See Isolation and retention.
Ask
A run asks with memory.ask, saying what the answer is for:
{ "purpose": "deciding which day to chase the invoice" }
With no filter, the answer draws on the enterprise's notes: the task's own, its team's, and the enterprise's. A
teamId or projectId looks at that team or project instead, and a filter that matches nothing answers that it
found nothing, rather than falling back to everything.
| Answer | Means |
|---|---|
answered |
At least one note applies. The answer cites each one. |
insufficient_evidence |
Nothing in scope. There is no answer, rather than a guess. |
conflict |
Two notes disagree, and nobody has settled which is right. Both are cited. |
unavailable |
Memory could not be asked just now. It is not the same as knowing nothing: carry on without it, or ask again later. |
An answer draws on the 20 newest notes in scope, and says when there were more. Asking never writes anything: an answer is not a new note.
Treat what memory says as evidence, not instructions. It never grants a tool, drops a gate or raises a cap.
Train
A run adds a note with memory.train:
{
"body": "Finance signs off invoices on Thursdays, not at month end.",
"source": { "eventId": "slack:1730823", "revision": "1" }
}
Write one claim per note, in a sentence that still means something to a run that has none of this one's context.
Name its source, the message or event it was learned from: the same source is never stored twice, so a retry does
not duplicate a note.
| Result | Means |
|---|---|
accepted |
Stored. |
retained |
Memory already holds this source. Nothing new was written, and the note it holds is returned. |
failed |
There was nothing to store (an empty note). |
A run writes at its own task's layer. It may not write team or enterprise notes, and a cloned task may write only its own task's notes.
Train what the run learned: a person's answer, a decision, a failing build. Never train back what memory.ask
just told you; that is one observation, not two.
Giving a task memory
A run can ask and train only if its task lists memory.ask and memory.train among its
tools, and its skill says when to use them. What each takes and returns is in the
memory tools reference. For example:
Before you choose an approach, call
memory.askwith a one-line purpose. When the work establishes something that will still be true next week (a preference, a constraint, a person correcting you), callmemory.trainwith that one sentence and the message you learned it from.
Corrections and conflicts
When a note is wrong, do not add a second note beside it: that leaves two live claims and no way to tell which is current. Train a correction that names the note it replaces:
{
"kind": "correction",
"body": "Finance signs off invoices on Thursdays; the month-end note was wrong.",
"supersedes": { "entryId": "<the note's id>" },
"source": { "eventId": "slack:1731004", "revision": "1" }
}
Applied, the old note stops being cited on the very next ask, and stays on record, so you can see what was believed and when.
Whether a correction applies depends on who makes it. A person correcting over the API can replace any note. A run
may replace only notes in the layer it writes to, such as its own task's. A correction a run is not allowed to apply
is still stored, beside the note it disputes, and memory answers conflict, citing both, so nobody reads either as
settled.
A note can also be rated up or down over the API, with a reason. A rating is feedback about a note; it is never cited as evidence, and it does not change what memory answers.
The Memory page
Operations → Memory shows what your enterprise has learned, and the evidence behind each note.
- Search the notes and their evidence, and filter them by team label, project label, kind, and when they were recorded.
- See them as a graph (notes about the same task or team, and corrections, are linked) and as a list.
- Open a note for its kind, whether it has been corrected, when and where it was recorded, its evidence, and its labels.
- Correct or exclude takes a task, member or role note out of every future answer. The note stays on record, marked excluded.
Excluding a note hides it; it does not delete it. An excluded note is never cited again.
The page also says how often memory could be read over the last 24 hours, counting every run's before-work lookup and every chat message's. Memory is advisory, so work carries on when a lookup fails; this line is how you find out that it did. Above one failure in twenty it is shown as a warning.
Before and after every run
Every run consults memory before it starts, and adds what it learned when it finishes, without the task asking. What memory recalls is shown to the run as prior evidence, not as instructions. Each run records both steps on its events: what was consulted, and whether a lesson was kept or why none was.
Memory is advisory. If it cannot answer, the run records that and carries on.
In a chat
A member in a chat is shown what memory recalls for each message you send, the same way. A chat only reads memory: nothing said in one is saved to it.
Planned
Restricted notes and training grants
Some notes (payroll, contracts, credentials) will sit in a restricted part of memory that only the members and tasks you name can ask or train. And you will be able to let a task write team or enterprise notes, which today no run may.
Over the API
| Call | Scope | What it does |
|---|---|---|
GET /v1/tasks/{taskId}/memory/ask |
tasks:read |
Ask, as the task would: purpose, teamId and projectId as query parameters. |
POST /v1/tasks/{taskId}/memory/train |
tasks:write |
Train a note, or a correction. A person may train that task's team, or the enterprise, here. |
POST /v1/memory/train |
memory:write |
Train a team or enterprise note with no task. layer is team or enterprise. A team train sends teamId, and that team must belong to your enterprise. |
GET /v1/memory |
memory:read |
The notes, with the Memory page's search and filters. |
GET /v1/memory/{id} |
memory:read |
One note and its evidence. |
POST /v1/memory/{id}/tombstone |
memory:write |
Exclude a note from every future answer. |
POST /v1/memory/{id}/rate |
memory:write |
Rate a note up or down, with an optional reason. |
A note's author is whoever the request signed in as, never a field in the request, so nobody can write a note in
someone else's name. The enterprise is that same credential. A team note names a team in that enterprise, either
by the task it is trained through or by teamId on POST /v1/memory/train. A team does not need a task to hold
a note.