Memory

Context management

The store has two layers. The first layer is an event log. Glider only adds to this log, and each event has RUNTIME provenance. The second layer is a graph of entities and edges. Each entity has EXTRACTED, INFERRED or RUNTIME provenance. A turn index in memory gives sticky routing.

Why Glider keeps a context store

A Cursor Composer summary message and a subagent message look like new small prompts. Without a memory layer, the router sends them to the local model, which is not correct. The graph tells the router if a message is still part of turn family X. Refer to MITM · sticky-cloud.

The layers

LayerFunctionStorage
Event logGlider only adds events. The event names include RouteDecided, FulfilledLocal, OriginPassthrough, TurnOpened and StickyBound.~/.glider/context/events-*.jsonl
Entity and edge storeFiles, directories, symbols and the relations between them~/.glider/context/entities.jsonl
EpisodesShort summaries of a session. Glider adds them to a local prompt.contextkit (rings in memory)

What Glider keeps, and for how long

SettingDefaultFunction
context.max_events4096The size of the event ring in memory
context.retain_days14How long the events-*.jsonl files stay on disk. POST /api/context/prune uses this value.
context.warm_load_days2How many days of JSONL Glider reads again when it starts

How to query the store

The context_query tool and Store.Query search the two layers:

context_query: <turn_id> [key=clone_path|goal|plan|file-tree]
  [kind=note|file|dir|symbol] [prov=RUNTIME|EXTRACTED|INFERRED]
  [path=<from>-><to>] [neigh=id] [explain=id] [communities=1] [limit=N] keyword…

Keywords accept OR or | to match any term. For example, goal OR plan.

Explain(id) gives the neighborhood of an entity, its hubs, and the path to a hub. DetectCommunities finds connected components. It is a first version, and it is not the full Leiden algorithm.

What the local model receives

Glider never sends the full transcript. It sends a pack with a limited size. The pack has the most recent user turn and a maximum of N short episodes. The settings transform.local_context and transform.local_episode_count control the pack. The Overview page of the dashboard shows the episodes from GET /api/context/episodes.

What a delegate receives

This is a different layer from the store above, and it has a different file. Glider keeps one continuity record for each workspace. The record holds what occurred in the calling session: the turns of the user, and what each earlier delegate changed. Glider puts a block from this record at the start of every delegate call. The delegate sees the block with the name "Earlier in the calling session".

How context moves across CLIs

The diagram shows one session with three turns. The person stays in Claude Code for all three. Turn 2 goes to cursor-agent, and turn 3 goes to agy. Neither delegate can see the Claude Code session, and neither can see the other. The continuity record is the only thing that connects them.

You — Claude Code Glider Delegate turn 1 turn 2 turn 3 "the auth test fails" no flag "fix it /cursor-agent" "now document it /agy" continuity record — one per workspace ~/.glider/continuity/<name>-<hash>.md · a ring of 60 entries ranked against THIS task, not by time includes what cursor-agent did cursor-agent reads AGENTS.md agy reads AGENTS.md the outcome is written back under YOUR identity, so the next delegate does not redo or undo it
One session, three turns, two different delegates. Turn 1 carries no flag and still enters the record — that is why the delegate in turn 2 knows which test was failing.

Two properties matter, and both are easy to miss:

PropertyWhy it is there
A turn with no flag is still recorded Most turns in a session are ordinary chat. If Glider recorded only the delegate turns, a delegate would receive the instruction and nothing that led to it.
The outcome returns under the identity of the front CLI The result belongs to the session that sent the work, and not to the delegate that did it. A later delegate in the same workspace then knows the run occurred. Without this, a second delegate can undo the change the first one made.

A delegate receives a file, and not a longer prompt. Glider makes a private directory for each run and writes the context into the file that the vendor already reads by itself: AGENTS.md for cursor-agent and agy, glider-context.md for claude. The directory goes away when the run ends.

ItemValue
The file~/.glider/continuity/<name>-<hash>.md, one for each workspace
The recordA ring of 60 entries
The blockA maximum of 20 entries, and a maximum of 20000 tokens

The record stays in ~/.glider, and not in your project. Glider does the bookkeeping, and the project does not own that data. A file in your repository would show in git status permanently.

How Glider selects the entries

Glider does not take the last N entries. Time is not relevance: a person who does five turns about CSS, and then delegates a defect in Go, must not receive five turns about CSS. Three rules control the selection:

RuleWhat it does
RankingGlider scores each entry against the task of THIS delegate. A rare term has more weight than a frequent one. At equal relevance, the result of an earlier delegate wins against an ordinary turn, because it describes a change that a delegate already made to these files.
A protected tailThe 2 most recent entries go in the block with no score. What the user says now is never noise.
Middle-out truncationAn entry that is too long loses its MIDDLE. The start gives the objective, and the end gives the condition.

Three settings control the size. Each one is a ceiling, and not a target:

SettingDefaultFunction
context.background.token_budget20000The full block
context.background.max_entries20The count of entries
context.background.max_entry_chars4000One entry, before middle-out truncation

Know the cost. This block goes with EVERY delegate call. Therefore a large budget gives better orientation, and it makes each delegation more expensive and more slow.

Compaction

A record with more than 40 entries gets compaction: Glider replaces the older entries with one summary, and keeps a tail of entries with no change. This always occurs. The context.summary settings only select WHO writes the summary.

Compaction runs in the background. It never runs on the clock of a request. Therefore the list of sources can contain an option as slow as the cold start of a CLI.

SourceWhat it usesWhat it costs
originAn installed agent CLI, with no windowThe subscription that you have. No API credits. Approximately 20 s.
cloudA BYOK cloud backendYour own API credits
localA local modelNothing
noneStops the list hereNothing

The default order is [origin, cloud, local]. Glider tries each source until one gives an answer. A source with no configuration does not cause an error. Glider goes to the next source.

If each source fails, or if context.summary.enabled is false, Glider uses a deterministic digest. The digest keeps the first turns and every delegate outcome, and it counts what it removed. Compaction never fails and leaves nothing.

Glider puts [session summary] at the start of a compacted entry. A later pass reads that mark and never makes a summary of a summary. Repeated compaction is where these systems lose data.

How to examine the store

GET  /api/context/recent
GET  /api/context/turns · /api/context/turns/{id}
GET  /api/context/episodes
GET  /api/context/export
POST /api/context/index-tree
POST /api/context/index-symbols
GET  /api/context/communities?turn_id=
GET  /api/context/explain?turn_id=&id=
POST /api/context/prune

The functions RecordHoopContext and LookupHoopContext in contextgraph stay in use. The removed stage runner did not use them. IndexFileTree writes the file-tree key, and the key= path in QueryWith reads it. But the thread facts (RecordThreadWave and RecordEpisodeFact) have no caller today. They are unused library code, not a function of the product.

The full description is in planning/routing_and_context.md.