← All posts

Memory you can read, edit, scope and approve

Vocion's agents now carry typed, scoped memory — preferences, knowledge and procedures, filed per workspace, agent, user, mission or workflow. Every rule is a file a person can read and reword, approval is still the only way one is written, and approved rules finally reach the model instead of waiting to be noticed. Release notes 2026-09-16.

Vocion Teamvocion-v2.82.0

Status: shipped. Five commits on main — 38c975e4, 411574da, 5d2a1ffa, 537a78e4, 31589fca — in v2.82.0, with migrations 0103–0107. The consolidation loop described at the end is off by default. Part of the 2026-09-16 release notes. The mechanics are in the developer post.

Vocion already turned a correction into a rule. Decisions become learning candidates described that loop: you reject a draft, say why, and the system proposes a rule; you approve it and it becomes part of how the agent works. What that loop produced was a flat pile of approved sentences in whichever bucket the system guessed. This release gives those sentences a type, a scope, a place a person can find and edit them — and it fixes the embarrassing part, which was that an approved rule was only applied if the model happened to go looking for it.

The bug worth leading with

Approved rules were mounted into the agent's virtual filesystem, and nothing told the model they were there. The runtime's automatic file loader enumerates skills and playbooks, not memories. So a rule a person had read, edited and deliberately approved reached the model only if it happened to list the directory.

They now arrive as a block on the system message every turn, wrapped in <approved_learnings>, followed by guidance that names them as requirements rather than suggestions, and says plainly: you cannot edit these files; approval is the only write path. That change alone is the difference between a review queue that shapes behaviour and one that feels like it does.

Memory now has a type

Every candidate carries one of three kinds, and you can change it on the card before you approve:

The distinction is not decoration. It is what lets a preference apply to one person without leaking into everyone's agents, and a procedure apply to a role without being re-taught per user.

And a scope

A rule is filed against a layer, not thrown into one shared pile. The layers, and the order they are applied in when there is more prompt than budget:

  1. workspace policies — everything, everywhere.
  2. agent procedures — how this role does its job.
  3. workflow learnings — a procedure attached to a named workflow.
  4. mission context — what is true for this piece of work.
  5. user preferences — one person's.

There is also object knowledge, which deliberately does not mount on every turn: it rides the record lookup instead, so a fact about a customer arrives attached to that customer rather than sitting in the prompt on every unrelated turn.

Scope has a second job, which is isolation. One user's preference never appears on another user's turn, and one organisation's memory never appears on another's — the assembly tests exist specifically to hold that line.

Feedback lands in the right bucket now

The old classifier had no way to say which bucket a piece of feedback belonged in, so an unlabelled one fell back to the organisation's first learning namespace by database id. That is how rules about drafting email ended up filed under CRM judgment — visible in production, not a hypothetical.

The classifier is now shown the actual list of namespaces with their descriptions and asked to pick one, and the answer is checked against that list afterwards: a name that is not on it is discarded rather than trusted. An explicitly targeted piece of feedback still wins over the model's guess. For rules already misfiled, there is a re-homing script that moves a rule to the right namespace and re-points the evidence links behind it in the same pass.

The pages a person actually uses

/dashboard/learnings lists your namespaces with their store path, their scope, how many rules they hold, which agents read them, and when one was last actually mounted on a turn — so a namespace nothing reads is visible as never used rather than quietly ignored.

On a pending candidate you can reword it (the original wording is kept, never overwritten), move it to a different namespace, change its type, change its scope to the agent or the person the evidence points at, then approve or reject. A rejection has to carry a reason.

On an adopted rule, /dashboard/learnings/<namespace> is a plain editor: add, reword, delete.

At the bottom of the page, Recent decisions shows what was decided, by whom, in what scope — and where the agent has an eval dataset, the pass rate before and after the adoption, as eval 80% → 100%. That number is evidence, not proof: it is the dataset's pass rate on the run stamped to this decision against the previous run on the same dataset.

Confidence you can check

The agent's own confidence is now plotted against what people actually did with its recommendations, on /dashboard/adoption/agents/<slug>. Three buckets — Agent confident (≥ 0.9), Agent unsure (0.6 – 0.9), Agent hesitant (< 0.6) — each with the share that was not rejected. An empty bucket shows as —, never as zero.

The row that matters is the misalignment one: recommendations the agent was confident about that a person rejected in the last seven days. That is the number that tells you the agent's confidence means something, or does not.

The approval-rate trend carries amber diamonds on the days rules were adopted. The page says outright that this is adjacency, not causality — it puts cause next to effect and leaves the reading to you.

One fast lane, deliberately narrow

Being asked to remember something personal and answering "I'll file that for review" is a bad interaction. So remember_preference applies immediately when a person explicitly asks the agent to remember something about them: it writes to that user's own preference layer, for that user only, and files an already-approved candidate so a reviewer sees it on the decided list and can revoke it.

It is fenced on every side. No signed-in user, no preference. User scope only. The duplicate guard still runs. And the guidance the model reads names it as the one exception — everything else is proposed and a person decides.

Episodes, and a loop that can close itself

Runs now leave short notes behind — a review decision with the confidence the agent had, an eval outcome, a thumbs-up or thumbs-down on a run — written into the same store with an expiry, thirty days by default.

Episodes never mount into a prompt. They have no namespace entry, which is the structural reason they cannot: if they mounted, they would be an ungated write path into how the agent behaves. What they are for is mining. A consolidation pass reads them and proposes rules; another pass finds rules in the same namespace that have drifted into near-duplicates and proposes one merged rule to replace several; a third drafts an amendment for a workflow procedure that has accumulated enough rules to be worth revisiting.

Every one of those passes produces a pending candidate and nothing else. Nothing in memory moves until a person approves it, and the pass fails closed — if the model's answer cannot be parsed, nothing is proposed. Approving a merge records how many rules it retired, and the agent's memory panel shows it: Consolidated: 2026-09-15 (4 → 1).

Consolidation is off unless ENABLE_CONSOLIDATION=1. There is also a command to run it once for one organisation, which is how it should be tried first.

What this does not do

The scoped-memory store has no semantic search — a query returns the same rows as no query, unranked. Object-scoped knowledge and workflow-scoped learnings can be authored in a workspace file but cannot yet be created from the review card. And one honest gap the developer post goes into properly: the filesystem route into memory is sealed shut for agents, but the agent's rule-writing tools are still governed by instructions rather than by structure.

Where this lives