Forget When Full
Your agent's working memory is not infinite. It's a fixed-size buffer — a few slots of recent facts, the last handful of tool results, whatever fits in the context budget you set in the last lesson. So the real question isn't what to remember; it's what to throw away when the slots run out. Get that wrong and the agent forgets the thing it's about to need while still holding junk it touched once an hour ago.
The cheap, surprisingly good answer is LRU — least-recently-used. When memory is full and something new arrives, evict the item that has gone untouched the longest. Not a random victim (you might nuke the fact you need next). Not the oldest-inserted item (that punishes things you keep coming back to). Recency of use is the proxy: if you haven't touched it in a while, you probably won't miss it.
The trick is that reading counts as using. Keep memory ordered
most-recently-used-first, and every access — write or read — moves that key to
the front. Walk the trace ["set a","set b","set c","get a","set d"] over a
capacity of 3: after the three sets, memory is [c, b, a] (c freshest). Then
get a touches a, sliding it to the front: [a, c, b]. Now set d arrives and
memory is full — so you evict the tail, b, the one nobody has touched since the
start, and unshift d: [d, a, c]. That one read of a is exactly what saved it
from being evicted.
Below, the recency-refresh is already wired — use pulls an existing key out and
unshifts it to the front. The missing piece is the eviction itself: when mem is
already full and a new key comes in, drop the least-recently-used key (the one at
the end of the array) and record it before unshifting. Make it print the
survivors MRU-first, then the key you let go.
A bounded memory is only as smart as its eviction rule — keep what you keep touching, forget what you stopped touching.