Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,22 @@ export const STAGE_SELF_MANAGED_M66 = "$0.0001";
usezombie is in **stealth-mode testing** and pre-production. APIs and agent behavior may change between releases without long deprecation windows. Email [usezombie@agentmail.to](mailto:usezombie@agentmail.to) if you want a hand calibrating an agent or to join as a design partner.
</Tip>

<Update label="Jun 12, 2026" tags={["What's new"]}>
## `core` memories now survive the hydration window and the entry cap

Memory selection previously ran on write-recency alone: an identity fact stored once — an owner, a deploy target, a customer's plan — was the first thing both the hydration window and cap eviction discarded once noisier `daily` writes piled up. Both mechanisms are now category-pinned, so the facts an agent marked durable stop being the first casualties of the byte budget and the entry cap.

## What's new

- **Category-pinned hydration** — every `core` entry that fits the hydration byte budget loads before any non-core entry is considered; the remaining budget fills with the newest non-core entries. A `core` fact written in run 1 is still in context at entry 1001.
- **Tiered cap eviction** — at the per-agent entry cap, the coldest non-core rows are deleted first; a `core` row is evicted only when no non-core row remains.
- **Safe default for custom categories** — a category the platform doesn't recognise is windowed by recency, never silently pinned.
- **Deterministic selection** — same entries, same budget, same hydration on every run, so "why does my agent remember X but not Y?" has a checkable answer: X was `core`, Y was windowed.
- **Memory-hygiene guidance** — the [Memory page](/memory) now documents what to store as `core`, why stable keys beat dated ones, and why hoarding everything as `core` defeats the pinning.

The four memory tools, the wire shapes, the hydration byte budget, and the entry cap are unchanged — only which entries fill the window.
</Update>

<Update label="Jun 12, 2026" tags={["Bug fixes"]}>
## Platform token spend now actually bills

Expand Down
21 changes: 19 additions & 2 deletions memory.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Memory is always on — no setup, no flag.

| Category | Scope | Lifetime | Use for |
|---|---|---|---|
| `core` | agent | permanent until forgotten | Learned facts about durable entities — customers, accounts, preferences. |
| `core` | agent | durable; evicted last at the entry cap | Learned facts about durable entities — customers, accounts, preferences. |
| `daily` | agent | 72h auto-prune | Time-bounded follow-ups, open tickets, scheduled reminders. |
| `conversation` | event | dies with the run | Within-run scratch — checkpoint findings during a long incident. |
| `workspace` | workspace | durable | Facts shared across every agent in the workspace. |
Expand Down Expand Up @@ -43,6 +43,23 @@ flowchart LR
Store --> End([run closes])
```

## What survives — selection and eviction

Hydration (what an agent sees at run start) and eviction (what the platform deletes at the per-agent entry cap) are both **category-pinned**: `core` wins.

- **Hydration** fills a fixed byte budget: every `core` entry that fits loads first (newest first), then the newest non-core entries fill the remainder. A `core` fact written once — an owner, a deploy target, a customer's plan — is still in context at entry 1001, even after a noisy month of `daily` writes.
- **Eviction** at the entry cap deletes the coldest non-core entries first. A `core` entry is deleted only when nothing else remains.
- **Custom categories** (and anything the platform doesn't recognise) are windowed by recency — never silently pinned.

Selection is deterministic — same entries, same budget, same result — so "why does my agent remember X but not Y?" always has a checkable answer: X was `core`; Y was windowed, or too big for the budget.

Four habits make selection work for you instead of against you:

1. **Store load-bearing facts as `core`.** If a future event must know it, it's `core`. Everything windowed ages out of hydration.
2. **Reuse stable keys.** Re-storing a key refreshes the entry instead of duplicating it — `deploy_target`, not `deploy_target_jun12`.
3. **Forget what's stale.** `memory_forget` beats letting eviction pick the victim. Hoarding everything as `core` defeats the pinning: an all-`core` set over the cap evicts your coldest `core` facts.
4. **Keep entries small.** The hydration budget is bytes, not entries — snapshot conclusions, not transcripts.

## Entry format

Memory is stored in Postgres but exports as markdown for human review.
Expand Down Expand Up @@ -93,6 +110,6 @@ The underlying system changed but memory didn't. Steer the agent to call `memory
| Symptom | Cause | Fix |
|---|---|---|
| Recall returns nothing on a known entity | Inconsistent key convention | Use a stable, deterministic key derivation in `SKILL.md` (e.g. `customer_<email-slug>`). |
| Memory grows forever | No pruning on `core` (by design) | Steer the agent to call `memory_forget` on stale keys, or move time-bounded entries to `daily`. |
| Memory grows forever | `core` has no time-based pruning; at the entry cap, coldest `core` entries are evicted when no non-core entries remain | Steer the agent to call `memory_forget` on stale keys, or move time-bounded entries to `daily`. |
| `UZ-MEM-003` on store | Memory backend unavailable | Re-run the trigger; if persistent, file an issue. |
| `UZ-MEM-001` on store | Memory scope denied (cross-agent access attempt) | Memory is per-agent. Use `workspace`-category writes if you need to share facts across agents. |
Loading