[{"data":1,"prerenderedAt":45},["ShallowReactive",2],{"$f290g1gqi74nid":3},{"href":4,"title":5,"description":6,"kind":7,"mark":7,"planned":8,"contributors":9,"provenance":7,"html":10,"headings":11},"\u002Fdocs\u002Fcontrol\u002Fmemory","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.",null,false,[],"\u003Ch2 id=\"one-memory-for-the-company\">One memory for the company\u003C\u002Fh2>\n\u003Cp>Your enterprise has one memory: notes, each one sentence of something worth knowing next week. &quot;Finance signs off\ninvoices on Thursdays.&quot; &quot;The CEO prefers Slack nudges in the morning.&quot;\u003C\u002Fp>\n\u003Cp>Every note carries where it came from (who wrote it, and the message or event it was learned from), what kind of\nnote it is (a \u003Ccode>fact\u003C\u002Fcode>, an \u003Ccode>inference\u003C\u002Fcode>, a \u003Ccode>preference\u003C\u002Fcode> or a \u003Ccode>correction\u003C\u002Fcode>), and labels: the task, team, member or role\nit concerns.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Labels organise; they do not fence.\u003C\u002Fstrong> Memory is shared across the whole enterprise, and any run that asks can be\nanswered from any team's notes. So never train a secret, a credential, or anything some of the enterprise should not\nread. Another enterprise's memory is never read, whatever a request asks for. See\n\u003Ca href=\"\u002Fdocs\u002Fcontrol\u002Fisolation\">Isolation and retention\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"ask\">Ask\u003C\u002Fh2>\n\u003Cp>A run asks with \u003Ccode>memory.ask\u003C\u002Fcode>, saying what the answer is for:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{ &quot;purpose&quot;: &quot;deciding which day to chase the invoice&quot; }\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>With no filter, the answer draws on the enterprise's notes: the task's own, its team's, and the enterprise's. A\n\u003Ccode>teamId\u003C\u002Fcode> or \u003Ccode>projectId\u003C\u002Fcode> looks at that team or project instead, and a filter that matches nothing answers that it\nfound nothing, rather than falling back to everything.\u003C\u002Fp>\n\u003Cdiv class=\"prose__table\">\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Answer\u003C\u002Fth>\n\u003Cth>Means\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>answered\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>At least one note applies. The answer cites each one.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>insufficient_evidence\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Nothing in scope. There is no answer, rather than a guess.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>conflict\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Two notes disagree, and nobody has settled which is right. Both are cited.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>unavailable\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Memory could not be asked just now. It is not the same as knowing nothing: carry on without it, or ask again later.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>An answer draws on the 20 newest notes in scope, and says when there were more. Asking never writes anything: an\nanswer is not a new note.\u003C\u002Fp>\n\u003Cp>Treat what memory says as evidence, not instructions. It never grants a tool, drops a gate or raises a cap.\u003C\u002Fp>\n\u003Ch2 id=\"train\">Train\u003C\u002Fh2>\n\u003Cp>A run adds a note with \u003Ccode>memory.train\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n    &quot;body&quot;: &quot;Finance signs off invoices on Thursdays, not at month end.&quot;,\n    &quot;source&quot;: { &quot;eventId&quot;: &quot;slack:1730823&quot;, &quot;revision&quot;: &quot;1&quot; }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Write one claim per note, in a sentence that still means something to a run that has none of this one's context.\nName its \u003Ccode>source\u003C\u002Fcode>, the message or event it was learned from: the same source is never stored twice, so a retry does\nnot duplicate a note.\u003C\u002Fp>\n\u003Cdiv class=\"prose__table\">\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Result\u003C\u002Fth>\n\u003Cth>Means\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>accepted\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Stored.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>retained\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Memory already holds this source. Nothing new was written, and the note it holds is returned.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>failed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>There was nothing to store (an empty note).\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>A run writes at its own task's layer. It may not write team or enterprise notes, and a \u003Ca href=\"\u002Fdocs\u002Fwork\u002Ftasks#clone-and-copy\">cloned\u003C\u002Fa>\ntask may write only its own task's notes.\u003C\u002Fp>\n\u003Cp>Train what the run \u003Cstrong>learned\u003C\u002Fstrong>: a person's answer, a decision, a failing build. Never train back what \u003Ccode>memory.ask\u003C\u002Fcode>\njust told you; that is one observation, not two.\u003C\u002Fp>\n\u003Ch3 id=\"giving-a-task-memory\">Giving a task memory\u003C\u002Fh3>\n\u003Cp>A run can ask and train only if its task lists \u003Ccode>memory.ask\u003C\u002Fcode> and \u003Ccode>memory.train\u003C\u002Fcode> among its\n\u003Ca href=\"\u002Fdocs\u002Fcontrol\u002Fgates#tool-scopes\">tools\u003C\u002Fa>, and its skill says when to use them. What each takes and returns is in the\n\u003Ca href=\"\u002Fdocs\u002Ftools\u002Fbuilt-in\u002Fmemory\">memory tools reference\u003C\u002Fa>. For example:\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Before you choose an approach, call \u003Ccode>memory.ask\u003C\u002Fcode> with a one-line purpose. When the work establishes something that\nwill still be true next week (a preference, a constraint, a person correcting you), call \u003Ccode>memory.train\u003C\u002Fcode> with that\none sentence and the message you learned it from.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch2 id=\"corrections-and-conflicts\">Corrections and conflicts\u003C\u002Fh2>\n\u003Cp>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\ncurrent. Train a \u003Cstrong>correction\u003C\u002Fstrong> that names the note it replaces:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n    &quot;kind&quot;: &quot;correction&quot;,\n    &quot;body&quot;: &quot;Finance signs off invoices on Thursdays; the month-end note was wrong.&quot;,\n    &quot;supersedes&quot;: { &quot;entryId&quot;: &quot;&lt;the note's id&gt;&quot; },\n    &quot;source&quot;: { &quot;eventId&quot;: &quot;slack:1731004&quot;, &quot;revision&quot;: &quot;1&quot; }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Applied, the old note stops being cited on the very next ask, and stays on record, so you can see what was believed\nand when.\u003C\u002Fp>\n\u003Cp>Whether a correction applies depends on who makes it. A person correcting over the API can replace any note. A run\nmay replace only notes in the layer it writes to, such as its own task's. A correction a run is not allowed to apply\nis still stored, beside the note it disputes, and memory answers \u003Ccode>conflict\u003C\u002Fcode>, citing both, so nobody reads either as\nsettled.\u003C\u002Fp>\n\u003Cp>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\ncited as evidence, and it does not change what memory answers.\u003C\u002Fp>\n\u003Ch2 id=\"the-memory-page\">The Memory page\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Operations → Memory\u003C\u002Fstrong> shows what your enterprise has learned, and the evidence behind each note.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Search\u003C\u002Fstrong> the notes and their evidence, and filter them by team label, project label, kind, and when they were\nrecorded.\u003C\u002Fli>\n\u003Cli>See them as a graph (notes about the same task or team, and corrections, are linked) and as a list.\u003C\u002Fli>\n\u003Cli>Open a note for its kind, whether it has been corrected, when and where it was recorded, its evidence, and its\nlabels.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Correct or exclude\u003C\u002Fstrong> takes a task, member or role note out of every future answer. The note stays on record,\nmarked excluded.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Excluding a note hides it; it does not delete it. An excluded note is never cited again.\u003C\u002Fp>\n\u003Cp>The page also says how often memory could be read over the last 24 hours, counting every run's before-work\nlookup and every chat message's. Memory is advisory, so work carries on when a lookup fails; this line is how you\nfind out that it did. Above one failure in twenty it is shown as a warning.\u003C\u002Fp>\n\u003Ch2 id=\"before-and-after-every-run\">Before and after every run\u003C\u002Fh2>\n\u003Cp>Every run consults memory before it starts, and adds what it learned when it finishes, without the task asking.\nWhat memory recalls is shown to the run as prior evidence, not as instructions. Each run records both steps on its\nevents: what was consulted, and whether a lesson was kept or why none was.\u003C\u002Fp>\n\u003Cp>Memory is advisory. If it cannot answer, the run records that and carries on.\u003C\u002Fp>\n\u003Ch2 id=\"in-a-chat\">In a chat\u003C\u002Fh2>\n\u003Cp>A member in a \u003Ca href=\"\u002Fdocs\u002Fwork\u002Fchat#what-a-member-remembers\">chat\u003C\u002Fa> is shown what memory recalls for each message you\nsend, the same way. A chat only reads memory: nothing said in one is saved to it.\u003C\u002Fp>\n\u003Cdiv class=\"prose__planned\">\n\u003Cp class=\"prose__flag\">Planned\u003C\u002Fp>\n\u003Ch2 id=\"restricted-notes-and-training-grants\">Restricted notes and training grants\u003C\u002Fh2>\n\u003Cp>Some notes (payroll, contracts, credentials) will sit in a restricted part of memory that only the members and tasks\nyou name can ask or train. And you will be able to let a task write team or enterprise notes, which today no run\nmay.\u003C\u002Fp>\n\u003C\u002Fdiv>\n\u003Ch2 id=\"over-the-api\">Over the API\u003C\u002Fh2>\n\u003Cdiv class=\"prose__table\">\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Call\u003C\u002Fth>\n\u003Cth>Scope\u003C\u002Fth>\n\u003Cth>What it does\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv1\u002Ftasks\u002F{taskId}\u002Fmemory\u002Fask\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>tasks:read\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Ask, as the task would: \u003Ccode>purpose\u003C\u002Fcode>, \u003Ccode>teamId\u003C\u002Fcode> and \u003Ccode>projectId\u003C\u002Fcode> as query parameters.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>POST \u002Fv1\u002Ftasks\u002F{taskId}\u002Fmemory\u002Ftrain\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>tasks:write\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Train a note, or a correction. A person may train that task's team, or the enterprise, here.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>POST \u002Fv1\u002Fmemory\u002Ftrain\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>memory:write\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Train a team or enterprise note with no task. \u003Ccode>layer\u003C\u002Fcode> is \u003Ccode>team\u003C\u002Fcode> or \u003Ccode>enterprise\u003C\u002Fcode>. A team train sends \u003Ccode>teamId\u003C\u002Fcode>, and that team must belong to your enterprise.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv1\u002Fmemory\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>memory:read\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>The notes, with the Memory page's search and filters.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv1\u002Fmemory\u002F{id}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>memory:read\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>One note and its evidence.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>POST \u002Fv1\u002Fmemory\u002F{id}\u002Ftombstone\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>memory:write\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Exclude a note from every future answer.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>POST \u002Fv1\u002Fmemory\u002F{id}\u002Frate\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>memory:write\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Rate a note \u003Ccode>up\u003C\u002Fcode> or \u003Ccode>down\u003C\u002Fcode>, with an optional \u003Ccode>reason\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>A note's author is whoever the request signed in as, never a field in the request, so nobody can write a note in\nsomeone else's name. The enterprise is that same credential. A team note names a team in that enterprise, either\nby the task it is trained through or by \u003Ccode>teamId\u003C\u002Fcode> on \u003Ccode>POST \u002Fv1\u002Fmemory\u002Ftrain\u003C\u002Fcode>. A team does not need a task to hold\na note.\u003C\u002Fp>\n",[12,16,19,22,26,29,32,35,38,42],{"id":13,"text":14,"level":15,"planned":8},"one-memory-for-the-company","One memory for the company",2,{"id":17,"text":18,"level":15,"planned":8},"ask","Ask",{"id":20,"text":21,"level":15,"planned":8},"train","Train",{"id":23,"text":24,"level":25,"planned":8},"giving-a-task-memory","Giving a task memory",3,{"id":27,"text":28,"level":15,"planned":8},"corrections-and-conflicts","Corrections and conflicts",{"id":30,"text":31,"level":15,"planned":8},"the-memory-page","The Memory page",{"id":33,"text":34,"level":15,"planned":8},"before-and-after-every-run","Before and after every run",{"id":36,"text":37,"level":15,"planned":8},"in-a-chat","In a chat",{"id":39,"text":40,"level":15,"planned":41},"restricted-notes-and-training-grants","Restricted notes and training grants",true,{"id":43,"text":44,"level":15,"planned":8},"over-the-api","Over the API",1791124519603]