Most "agent memory" writeups are about getting things in: which vector store, how to chunk, how to embed. The harder question in practice is the op...
For further actions, you may consider blocking this person and/or reporting abuse
The working-set framing is the cleanest version of this I've seen — the OS analogy pays off instead of being decorative. The quadrant that bites us most is the one you flagged: high-fidelity-but-low-salience. Exact content you're afraid to compress because it might matter, so it sits at full token cost forever. The practical trap is that salience is expensive to compute — you don't want an extra model call per step just to rank what to evict. What's worked for us is a cheap reachability heuristic instead of semantic scoring: an item stays "hot" if the last action referenced it (its ID showed up in tool args, its claim got cited), and decays otherwise. That's graph-reachability, not embeddings, and it's basically free. On "trusting your own summaries" — I'd underline that twice. The moment a compressed claim re-enters context it's indistinguishable from a retrieved fact, and the agent can't tell "I verified this" from "I summarized this into existence." We tag summarized items with provenance so a later step can page the raw back in before acting on anything load-bearing. Do you version summaries against their source, or treat them as write-once?
the blind spot in reachability is constraints. a constraint that is being respected is never referenced, because nothing violated it, so it decays to cold exactly when it is working. then it gets paged out and violated on the next step, which is the one failure the heuristic cannot see coming.
cheap patch is to make constraints non-decaying by class rather than by use, or to count a constraint as touched whenever an action was checked against it, not just when it appears in args. the second is more honest but needs the check to be explicit somewhere.
the summary point deserves the underline. a compressed claim losing its provenance is how a guess becomes a fact.
The RAM/disk reframe lands, and the line I'd underline is "source pointer, not lossy deletion," because that's the mechanism carrying the rest. We shipped almost exactly this taxonomy this week, except across sessions instead of inside one window, and the build surfaced something your two axes don't split evenly.
Fidelity survives a session boundary. A pinned invariant is a file, so the next cold agent still has it exact. Salience does not survive. A fresh session has no memory of what was salient, so "evict by salience, not age" has neither age nor carried salience to work from. Salience has to be recomputed from the pointer metadata on every cold start. Which makes your dangerous quadrant, high-fidelity-low-salience, the default state of everything persisted, not an edge case.
That also settles the token-budget-vs-invalidation question from the thread below, at least across runs. Token budget is a within-run trigger; there is no live budget pressure at a cold start, only staleness. So the only coherent cross-session trigger is invalidation events. Not a preference, a consequence of salience not persisting.
The failure mode you name, a compressed claim becoming indistinguishable from a retrieved fact, is why we kept source-of-truth on the live artifact and treated the summary as an index that never gets trusted on a load-bearing step. Same reason your pointers exist.
the salience-doesn't-survive cut is the sharp one, and i'd push it one step further. if salience has to be recomputed at cold start, notice you can't really compute it there either, because cross-session salience isn't a property of the stored item, it's a function of the item and whatever task just showed up. at a cold start with no task yet, there's nothing to rank against. so it's not high-fidelity-low-salience by default, it's salience-undefined-until-queried. which means across runs it stops being an eviction problem and becomes a retrieval one: you don't decay or evict by salience, you keep enough pointer metadata to score relevance on demand. invalidation stays your fidelity trigger, but salience only resolves at query time.
Salience-undefined-until-queried is the load-bearing move, and it collapses the eviction axis entirely rather than just relocating it. If salience only resolves against a task that has not arrived yet, then whatever you drop at storage time was never chosen by salience, because salience was not computable there. So the thing you are actually deciding to keep or drop is fidelity you cannot cheaply rebuild, and the axis quietly becomes cost-to-reconstruct. Keep the pointer when the pointed-at thing is stably re-derivable, drop the materialized copy, and let salience be computed against the live task at read. Salience never enters storage at all. The stored unit is not item plus salience, it is item plus reconstruction-cost plus invalidation-key.
Which moves the hard case somewhere more honest. It is not eviction anymore, it is a pointer whose target drifted since you stored it. The invalidation trigger has to fire on the source, not on your copy, or you do the retrieval you described, score the item salient against the current task, and hand back a confident stale thing exactly when the task made it look relevant. That is the failure mode the RAM-disk reframe imports and does not yet name: disk that rots silently is worse than eviction, because eviction at least knows it dropped something and can go re-fetch. A stale pointer returns something, with full confidence, and the salience score you compute at query time will happily rank the rotten copy as the thing you needed.
So the reframe holds, and the piece it still owes is that keeping a pointer is only cheaper than keeping the value if the invalidation is sourced from the target and not from the age of the copy. Freshness by timestamp is the trap. Freshness by a key the source can invalidate is the version that survives being queried.
the fourth field is verification cost, and it decides the case you ended on.
an invalidation key only helps when the source can tell you it moved. for a file or a git object you get that trigger for free. for someone else's page or another agent's output there is nothing to subscribe to, so invalidation quietly degrades into a ttl, which is a guess about drift rate dressed up as a policy.
so store cost-to-rebuild and cost-to-verify separately. cheap to verify and expensive to rebuild is the ideal pointer, you check at read and skip the work. expensive to verify is where you materialise after all, because you will never trust that pointer at read time anyway.
Verification cost as its own axis is the right addition, and it explains a failure I'd been treating as a TTL tuning problem rather than a category error: I kept trying to find the right expiry window for a value that should never have been time-boxed at all, because the actual problem was that nothing could tell me it changed, not that I'd guessed the decay rate wrong.
Splitting cost-to-rebuild from cost-to-verify gives you a four-quadrant version worth naming explicitly. Cheap-verify, cheap-rebuild doesn't need a cache at all, just recompute. Cheap-verify, expensive-rebuild is the pointer you described, check-then-skip. Expensive-verify, cheap-rebuild is the one people miss, because intuition says cheap-rebuild means don't bother caching, but if verification itself is expensive you still want the cached value, you just materialize proactively instead of on read. Expensive-verify, expensive-rebuild is where you're stuck trusting a TTL and calling it a policy.
Interesting take on context window management—very much like CPU cache hierarchy. In GPU-accelerated systems, we often face similar trade-offs between precision and memory bandwidth. When working on VoltageGPU, we had to decide what to keep in high-speed memory and what to offload, which parallels the "working set" idea you mention.
Context eviction is one of the most practical agent design problems. The working set should keep exact constraints, current state, and irreversible decisions; everything else can be summarized or paged out. The failure mode is treating all context as equally precious until the important parts drown.
The OS working-set framing is the right lens. The part that's hard in practice is measuring salience cheaply per step without burning a second model call on it. What worked for me: give every context item a clock/LRU 'last-touched step' counter plus a pinned flag for the must-stay-exact items, then compress anything untouched for N steps into a one-line handle that can be paged back by ID. That turns eviction into an actual pager instead of a judgment call you re-run every step.
the trap in the counter is what increments it. everything in the window is seen every step, so if last-touched updates on presence then nothing ever goes cold and the pager never fires. it has to key off explicit reference events instead, an id showing up in tool args or a claim getting cited, which is the reachability version someone described further up this thread.
which means the real prerequisite is that your agent's actions are structured enough to observe references at all. free-text reasoning gives you nothing to count, and that tends to be the actual blocker rather than the eviction policy itself.
The eviction framing is the right one. Running several agents against the same codebase, my failures are almost never 'not enough context', they're an agent dragging forward a decision from ten turns back that already got reversed, then reasoning from that stale state with full confidence. What's helped most is compressing down to the decision and the reason behind it once it lands, not keeping the raw exchange that produced it. I'd add that the eviction trigger should be actual invalidation, like a file changing or a call getting reverted, not just a token count, since trimming by token count alone throws away the wrong things at the wrong time.
the invalidation trigger works when the reversal leaves an artifact. file changed, call reverted, those you can watch.
the case that still gets through is the decision reversed in conversation. someone says actually let us not, and nothing moved on disk, so there is no event to subscribe to. both the original decision and its reversal then sit in the store as equally valid records, and retrieval hands back whichever scores better against the current phrasing.
that one has to be handled at write time rather than by a trigger: when a new decision contradicts a stored one, link them and mark the old superseded. costs a comparison on write, and it is the only thing that catches the reversal that never touched a file.