Memory structure and hygiene (planned)
Status: planned. Nothing on this page is implemented yet. It describes how project memory should stay small, current and complete to discover as projects grow, for every project and not through one-off cleanups.
Problem
- Recall truncates by accident.
memory_recallwrites one line per memory (reference, scope, type, title, summary) until its character budget (default 6000) runs out. Which memories fall off depends on sort order, not relevance, and the agent cannot tell what is missing (#215). - Discovery is never complete.
item_searchreturns at most 30 memories andKnowledgeService.Listloads at most 100, without a cursor or a "has more" signal. An agent cannot prove that something does not exist (#219). - Summaries are second descriptions. A summary may be 1200 characters. Written for people, it grows into prose, and recall pays for it on every line.
- Memory only grows. Session summaries, near-duplicates and superseded decisions pile up. Cleaning up one project once helps that project today and nobody else.
The strategy therefore has two parts: slow growth down at the moment of writing, and make the state measurable so every session sees when cleanup is due.
1. Fields with distinct roles
| Field | Limit | Audience | Content |
|---|---|---|---|
| Title | 80 | People, lists | What the memory is about |
| Summary | 300 | Agents in recall | The gist, deliberately terse, no prose: IIS deploy never deletes App_Data; keys lost otherwise |
| Detail | 30000 | People, item_get |
Reasoning, context, evidence |
Migration: a summary over the new limit moves into an empty detail and is shortened by its author; where detail is already filled, the hygiene score reports it instead of cutting text automatically.
2. Weight
Every memory has a weight:
- critical – always shown in recall from a reserved part of the budget, never inside a bag. A project should have few; exceeding the target count lowers the hygiene score rather than being rejected.
- normal – today's behaviour.
- low – found through
item_searchand bags, not listed in recall. For background and history that should be kept but not read every session.
3. Bags: one level of submemories
A memory may have a parent memory in the same project and scope, like tasks and documentation pages.
- A bag is derived, not declared. A memory with at least one active child is a bag. No flag can disagree with the structure.
- Exactly one level. A bag cannot have a parent, and a child cannot have children.
- Critical memories cannot be children.
- Recall lists the top level only. A bag line shows its summary, the number of children the reader may see, and their titles, shortened to fit:
[#48] Deployment: IIS web deploy and hosting • 7 submemories: Data Protection keys, App_Data, migrations, …. The child titles are always current even when the bag summary is not, which is why they are shown. item_geton a bag returns its children with title and summary, paginated.- Search still finds children directly and names their bag (
parent: #48), so nothing becomes reachable only through recall. - Visibility. Counts and titles include only children the reader is allowed to see; a public bag never reveals that private children exist.
- Archiving a bag moves its children to the top level instead of hiding them with it.
- Recall mode per project. By default recall stays flat below a threshold of top-level memories (for example 25) and groups above it. A project setting can force flat or grouped output or change the threshold.
4. Deterministic hygiene score
A score from 0 to 100 per project, computed from structure and timestamps only, without an LLM. It always comes with findings that name the items, because a number alone tells an agent nothing to do.
| Finding | Rule |
|---|---|
| Stale bag | A child changed after the bag's last revision that changed its summary. Weighted by the child's weight. |
| Crowded top level | More top-level memories than the threshold. |
| Too many critical memories | More critical memories than the target (for example 10). |
| Long summary | Summary over the limit, or nearly as long as its detail. |
| Leftovers | Expired but not archived; memories of type task older than a set age. |
| Session summaries | Session summaries older than a set age that were neither consolidated nor lowered. |
| Lopsided bag | A bag with one child, or with more children than a set maximum. |
| Duplicate titles | Normalized titles that are equal or overlap strongly in words. |
A revision that leaves a bag's summary unchanged does not count as refreshing it, so saving without editing does not clear a stale-bag finding.
The score is shown in the project overview and as one line in recall, for example Hygiene 58/100 • 3 stale bags • 14 old session summaries. The system guide tells agents to clean up at the end of a session when the score is below a threshold. Shared and public changes go through review as usual.
5. Slowing growth at write time
- Limits enforced by the tools: summary length, one bag level, no critical children.
- Feedback from
memory_store: deterministic hints in the response, such as a similar existing title (Similar: #48 – update instead?) or a bag that has just become stale. - Session summary lifecycle: after a set age session summaries drop to low weight or are consolidated into a history bag.
- Consolidation guidance in the system guide: true duplicates are merged into one memory and the rest archived with a supersedes link (#214); related but independent memories go into a bag instead, which keeps their revisions and origin.
6. Complete discovery
Memory lists and bag children are paginated with deterministic ordering, a continuation cursor and an explicit hasMore, and recall states how many memories it did not show. Details and acceptance criteria are in #219 and #215.
Order of work
- Hygiene score with findings, and the shorter summary with its migration.
- Weight.
- Bags and grouped recall.
- Pagination and complete discovery (#219, #215).
Related: session-end memory suggestions and focused recall (#77), evidence freshness (#216).