What I took from EverMind's open engine, and what I left
Reading a memory system's open source before building my own assistant branch: what I adopted, what I refused, and why.
Ivy is an experiment I’m running on myself: a personal tool that’s supposed to bend to its user instead of the other way around, and for now that user is me. Today it does one loop well: I type whatever is on my mind, it becomes structured data I own, and I get views over that data that I can actually read. That was v0.1, and its limit is simple: the app only answers when spoken to. An assistant worth the name is supposed to be proactive. It notices things, offers things, asks things, and knows when to stay quiet. v0.2 is where I start building that side, under the name “Ivy gives back”, and the work is to design that proactivity mechanically, piece by piece, rather than pointing a model at my data and hoping it behaves. The part of v0.2 that does this is what I call the assistant branch.
While scoping it, I figured it would be pretty stupid to design the assistant branch with a closed mindset and accidentally reinvent the wheel. People have been pursuing assistant intelligence for a while now, and some of them publish. So before agreeing on any design I went looking at what already ships, and in that exploration I stumbled upon EverMind, the nearest system to what my assistant branch needs. They’re not a competitor, Ivy isn’t a memory product, but the machinery overlaps: both need a model to decide when something is worth recording, and both need it to shut up when it isn’t.
I did the first teardown with Claude, and it reached a wrong conclusion: that
the open packages were plumbing and the prompts, the interesting part, were
closed. They weren’t. The whole intelligence layer was sitting on PyPI as
eight everalgo-* wheels next to a public monorepo, and once I pointed
Claude there, it read everything, prompts included. That team spent months
getting to their current system, and their changelogs document the trials and
errors release by release: rules that plateaued, fixes that regressed
something else, a prompt compression that shipped unmeasured and, in their
own words, “cost roughly 4ד. Time to dig in!
I went in expecting to learn memory semantics. That part turned out to be the
least useful, because Ivy already made those decisions differently. A quick
note on naming, since the rest of this post leans on it: every value Ivy
stores carries its provenance, said when I actually stated the thing, inferred when the model concluded it from what I wrote, and corrected when I overrode either. EverMind splits the same idea into explicit and
implicit, discovered by measurement and enforced by prompt, and the third
state, corrected, they don’t have at all. What was
actually worth taking is their gating: how the system decides a model call is
worth spending, and how it refuses to emit. So I went through all of it,
picked what I liked, left the rest, and noted down why for every choice.
These are the findings I ended up with, each carrying the numbers they measured, and they probably apply to more than just my use case in Ivy:
A positive definition beats a stack of prohibitions. Their profile prompt spent four rounds adding rules against restating actions as capabilities and plateaued at 0.80 bad items per run. One sentence stating what a profile is (“a portrait of a person, not a log of what happened”) took it to 0.20. Ivy’s interpreter prompt already leads with its own positive definition, and now I know why that matters enough to test for.

“None is a complete and correct answer.” To update the profile they have of the user when a new conversation comes in, their path treats an empty result as the expected outcome most of the time, and manufacturing an item as the error. Ivy’s briefing will run on the same rule. The briefing is one of the first things v0.2 ships: a short message Ivy composes on a schedule, a few items at most, each citing the data behind it. That makes it the first surface where Ivy speaks unprompted, and when it has nothing worth seeking, it sends nothing.
Verify honesty in code, don’t request it in a prompt. Their strongest
control is a code check: claimed evidence must appear verbatim,
whitespace-normalised, in the user’s own text, or the claim is rejected. Ivy’s
interpreter currently emits said provenance on the model’s word. In v0.2 a said value whose surface form isn’t findable in the capture text gets
demoted to inferred and an event written. After that, said means the
words are actually in what I typed, not that the model claims they are.

Name the output language, never let the model infer it. They measured this across 8 arms, 1,750 calls and five models: naming the language produced zero drift in 1,400 calls, while every self-judging variant drifted 10 to 26 percent, pulled toward whichever script dominated the input. My own captures are in English, but I’m not building Ivy with only English in mind, so in v0.2 its reply language comes from a setting the user chooses instead of a guess the model makes.
Structural gates before any model call. Their case extraction is an eleven-step funnel where the LLM is the last resort: cheap structural pre-filters first, then a yes/no filter on a slim view, then the expensive draft on the full view, with “default each signal to False when uncertain” written into the rubric. One of v0.2’s planned behaviours is Ivy noticing when captures pile up that fit none of my schemas and offering to track them, drafting the schema itself. Deciding when that offer is worth a model call is exactly this kind of gate, and their funnel is the shape I’m giving it. And when the gate says no, Ivy records why with the observed numbers, a habit from their code: an empty result could mean nothing qualified, the model offered nothing, or something broke, and without the reason written down there’s no way to tell which one happened.

Two signals, and actions are not signals. Half of their profile is things the user never stated, what they prefer, insist on, avoid, concluded from how they behave. Their measured rule for admitting one: it needs two or more signals, a signal is something the person chose or asserted, never an operation they carried out, and it has to recur across at least two sessions. Ivy’s version of this is the part of v0.2 where it notices something recurring about me and asks instead of assuming, and I’m adopting their thresholds nearly verbatim.
And these are the ones I left, with their own measurements as the reason:
Foresight. Their operator that has the model invent predictions about a person, “had a tooth pulled, will choose soft food”, each with a validity window, and their own code stores those windows and then never checks them. I left it because it inverts how Ivy is supposed to learn about me: a guess committed straight to storage is a belief nobody verified, and Ivy’s rule is that when the model thinks it noticed something, it asks, and what I answer is what becomes data. So Foresight stays a cautionary tale rather than a source.
Reflection. Their consolidation step that merges episodes into narratives, switched off in their own benchmark because it costs 5 to 12 points of recall. That settles a question I had open for later: when Ivy searches its own data, the index should hold the small individual records, not summaries written over them, since their numbers show the merging loses exactly the specific facts a search needs. Merged prose is for me to read.
Model-written provenance. They shipped a Profile.sources field and then
dropped it as “LLM-hallucinated, no reliable traceability”. Ivy’s provenance
is a column written by code, and now I have someone else’s measurement for
why it has to stay that way.
What impressed me most is also the part I can’t take: the measurement loop that produced those prompts, thirty-five hand-written conversations, five models, five-figure call counts, kept outside the repository. They can afford to publish the prompt text because without that corpus, nobody can rerun the experiments that justify each rule. So I’m adopting their way of working instead: before I read any result, I run the same test five times and look at the spread, I count every failure against Ivy rather than explaining it away, and I decide up front how big a difference has to be before I call it an improvement. None of that works without a test to run, which is why v0.2 starts with the eval and not with the first feature.
None of this is running code yet. Every item is agreed, none is built, and nothing will count as done until it carries a before/after measurement. What I have is a build order and someone else’s receipts for why it’s ordered that way.
Reading their source ended up costing me a day, while the mistakes it
documents cost them months. Everything quoted in this post is theirs, and it
all sits in the open at github.com/EverMind-AI/EverAlgo.