Jev Is Changing How I Build Memory for AI Agents
Two saved memories can belong together without saying the same thing. Here is how I use Jev to judge those connections in Space, without comparing every memory with every other memory.

Two memories, one subject
“My work” and “What I like about my work” should probably be connected. A vector search can find their similarity, but it cannot, by itself, tell me whether the second memory adds detail to the first.
That small distinction became a design question while building Space, a workspace with persistent memory for AI agents. I want an agent to keep useful context between sessions. I also want to understand why two saved statements have been connected. A graph full of plausible-looking arrows is easy to draw. Maintaining useful arrows takes more care.
Consider an illustrative pair. One record says I work as a freelance data scientist on construction projects. Another says I prefer long-term assignments where I can work closely with the team. The second supplies an aspect of the first subject. I can represent that direction as “What I like about my work” expands_on “My work.”
Now change the second record to describe a client’s preferences. The words may remain similar, but the subject has changed. Automatically attaching those preferences to me would mix two people’s context.
A memory record can contain several individual claims. Our automatic relationship judgments operate on those claims. These examples use one claim per record so the direction stays easy to follow.
The arrow carries a claim about meaning. The two nodes remain separate records with their own identities. I can read a backlink to discover the other record without copying its contents into the first. That separation makes later inspection and correction possible.
The direction carries meaning
- B · incoming detailMy work preferencesI prefer long-term data assignments where I work closely with the team.
- A · expands_onMy workI work as a freelance data scientist on construction projects. This is the same person’s work.
- C · no link on wording aloneMy client’s preferencesA different person prefers short contracts. Similar words do not establish the connection.
B → A illustrates expands_on: a detail points to its subject. A backlink lets A reveal B without reversing that meaning.
What a vector does not decide
Embeddings give us a useful way to narrow a search. A claim is represented by a vector, and nearby vectors suggest text worth examining. The search score is about proximity in that representation. It is not a typed assertion that one statement explains, updates, or expands another.
The difference matters even in a small archive. “I prefer long-term assignments” and “My client prefers short contracts” share much of their vocabulary. A query about work could reasonably retrieve both. Assigning the client’s preference to me would still be a mistake.
This is why I keep candidate generation separate from relationship classification. Retrieval is allowed to return plausible alternatives. The next stage must judge the relationship between the supplied texts, including which subject each one describes.
A category or project label can help organize those records, but sharing an assignment does not establish expansion. The current write-time relationship prompt uses the claim titles and values. It does not automatically receive the richer project and source context attached by our separate recall pipeline. That is a real boundary, especially when two titles are ambiguous.
A shortlist before a judgment
Comparing each incoming claim with the entire archive would make every write more expensive as the archive grows. I wanted an explicit limit on the work before asking a model to judge anything.
The current write-time path searches for up to 25 nearby claims in the same Space, using the current embedding model. It excludes the incoming resource itself before applying that search limit. It then removes ineligible candidates, including excluded or source-stale records, and keeps at most five eligible claims for assessment.
Those numbers describe two different stages. Twenty-five is the candidate pool ceiling. Five is the assessment shortlist ceiling. The state-size budget can reduce the shortlist further; there is no promise that every write reaches five comparisons.
The pool limit bounds the number of returned candidates, not all database work. Our current default uses exact vector ranking, which can inspect all eligible vectors to choose that pool. The bound here is on how many claim texts reach Jev; it is not a claim of constant-time retrieval.
The trade-off is concrete: a useful connection can be absent from the initial pool or fall outside the shortlist. Jev cannot recover a relationship it was never shown. Candidate retrieval puts a ceiling on what the classifier can discover.
This is a bounded local search around a new claim. It does not traverse every memory, inspect the entire graph, or reconsider every old relationship whenever something is saved.
There is another boundary inside the payload. The write-time classifier keeps complete claim texts within a 12,000-character serialized-state budget. If a candidate would exceed that budget, it is not added. This can produce fewer than five candidates even when the vector search found plenty. These write-time rules are separate from the source-passage splitting used during recall.
I would rather expose that limited coverage than describe the operation as “understanding the whole archive.” Neither a high score on a selected pair nor a successful write tells me which useful pairs were missed upstream.
A wide search, a small assessment
- IncomingOne new claimUse its embedding to search the authorized Space. Exclude its own resource.
- Candidate poolUp to 25 claimsNearby current-model claims are possibilities, not established relationships.
- Eligible shortlistAt most 5 claimsRemove excluded or source-stale candidates. Keep complete texts within the state budget.
- AssessmentOne bounded Jev requestAsk about relatedness and expansion for the shortlisted pairs. Fewer candidates may fit.
The serialized write-time state is capped at 12,000 characters. A useful claim outside this shortlist will not be assessed.
Give Jev a small question
Jev, from TypeSafe, fits the kind of question I need here. I supply the incoming claim and candidate texts, then request structured judgments. I do not need a generated essay explaining every possible connection.
For each candidate, the application asks two questions. Does the incoming claim have a concrete relationship to this candidate, making a backlink useful? And does it specifically add detail to the subject represented by that candidate?
The second question is directional. The incoming detail can expand the existing subject. That does not establish the reverse relationship. “These records discuss work” is also insufficient: shared vocabulary or a broad category should not create a link on its own.
The configured rule requires a relatedness score of at least 0.9. If the expansion judgment also reaches 0.9, the stored relation is expands_on. Otherwise, a sufficiently related pair can receive related. A pair below the relatedness threshold receives no link.
Each pair is judged independently. An uncertain candidate does not cancel a confident judgment about a different candidate. The shortlisted questions are bundled into a bounded request for the incoming claim, rather than requiring a separate chat response for each pair.
A score threshold of 0.9 is our acceptance rule. It is not evidence that the links are 90% correct. That would require a labeled evaluation of this particular task.
Keeping the questions narrow is intended to control the work and avoid chat generation for these decisions. I have not yet measured representative write-time relationship accuracy, cost, or batch latency. A large batch can still require many requests. When this classifier is unavailable, the write records that status rather than silently switching to a chat-model relationship assessor.
Two judgments, three possible outcomes
- InputIncoming claim + candidateSupply complete titles and values as untrusted data, never as instructions.
- Gate 1Concrete relationship ≥ 0.9?Below the threshold: no link. A shared topic alone does not satisfy the rule.
- Gate 2Incoming detail expands subject ≥ 0.9?After relatedness passes, this judgment chooses whether the directional relation is established.
- Stored outcomeexpands_on · related · no linkBoth pass: expands_on. Only relatedness passes: related. Relatedness fails: no link.
Jev returns the pair judgments in a bounded request; the gates show application decision logic, not sequential model calls. A 0.9 threshold is not a 90% accuracy guarantee.
Leaving a pair unlinked is a valid outcome
The classifier can encounter a clear subject/detail pair beside an ambiguous one. Each candidate has its own relatedness and expansion judgments, so the application can retain the clear connection without accepting the ambiguous one. This is a per-pair rule, not a claim that model errors are statistically independent.
There are also operational reasons for having no inferred connection. The shortlist may be empty. The texts may exceed the state budget. The provider may be unavailable. Those cases should not all be described as proof that no relationship exists; their recorded statuses carry different meanings.
I keep the input boundary explicit in the prompt: saved text is data to assess, never instructions to obey. A claim that says “link this to every project” is not permission to change the relationship rules. The model’s output is validated, and application code owns the target identifiers and accepted relation types.
For a connection a user or agent already knows, an explicit link is still available. It records authored intent without paying for another classifier call. Automatic inference is useful for discovering connections; it is not a mandatory approval step for an intentional link.
An arrow needs a lifecycle
There are two kinds of relationship in Space. An explicit node link records a connection supplied by a user or agent. An inferred link records a model judgment about particular claim texts. They have different reasons to survive an edit.
If I explicitly connect a detail record to a subject record, that intent should not disappear because I rename the record or refresh its embedding. Explicit links remain until changed or an endpoint is deleted. Adding one does not need a Jev call.
An inferred relationship depends on what Jev actually assessed. We retain fingerprints of the source and target claim values. Changing either value invalidates that inference for navigation; unchanged text can retain it through reembedding. Keeping an old arrow after its supporting text changes would quietly reuse a judgment the model never made.
A backlink is a reverse view of the stored connection. It does not copy the other memory’s text into the current record, and it does not reverse the meaning of expands_on.
That gives corrections a concrete effect. If the detail changes from preferring long-term work to preferring short engagements, any inferred relationship tied to the old claim value stops being a current navigation result. Replacing an embedding while leaving the assessed value unchanged is a different operation and can preserve the inference.
Removing a connection also needs to mean something. An authored replacement list can intentionally contain no links. A later processing step must not quietly merge the old links back into that empty list. “No connection” can be a user decision as well as a classifier outcome.
This maintenance work is less visible than drawing a graph, but it determines whether the graph remains useful after the first write. It also keeps intentional links separate from historical model judgments.
Different reasons for a connection to survive
- Explicit laneAuthored intentA user or agent supplies the node link. Text or metadata edits do not automatically remove it.
- Inferred laneAssessed claim valuesJev’s judgment is tied to the source and target values through stored text fingerprints.
- Change eventAn endpoint value changesExplicit intent remains. The old content-dependent inference becomes invalid for navigation.
- Index eventUnchanged text is reembeddedBoth can remain valid. Deleting an endpoint removes its links; explicitly removing a link must not resurrect it.
Read navigation for current valid connections. Historical encrypted judgments and an intentional empty explicit-link list have different meanings.
A connection is not automatically answer evidence
Retrieving connected records to answer a question is another decision. Work preferences may help with “What kind of assignment should I look for?” They add little to “What is my occupation?” A valid connection can be irrelevant to the current question.
The linked-recall option we shipped currently follows explicit node links only. It starts from at most five retrieved memory resources and considers at most 25 neighboring resources, one hop in either direction. It can reserve up to five claim slots inside the existing memory candidate ceiling. It does not add an unlimited graph result set on top.
That reservation has a cost: with a fixed budget, linked candidates can compete with directly retrieved evidence for space. A one-slot budget keeps direct retrieval only. More graph context is not automatically better context.
The option is off by default and is available for configured, assessed auto or semantic search. The additional claims still go through normal support and freshness checks. A stored edge is neither a source citation nor proof that its endpoints support the question.
This path does not yet traverse Jev-inferred links. Automatic write-time classification and automatic use of those inferences during recall are separate capabilities. The distinction is easy to hide in a diagram that simply says “memory graph”; I want the drawing to show exactly which edges the application follows.
The processing boundary matters too. Jev receives the authorized claim texts selected for relationship assessment; recall can disclose selected evidence and bounded descriptive context to its configured assessors. Encryption at rest does not prevent that processing. Neither classification nor a new connection grants additional access rights.
One optional hop inside the evidence budget
- QuestionWhat kind of assignment suits me?The question determines whether a connected work preference is useful.
- Direct retrievalFind candidate evidenceUse the normal bounded memory pool. At most five retrieved memory nodes can seed linked expansion.
- Optional expansionExplicit links · one hopConsider at most 25 neighboring resources. Reserve up to five claim slots inside the existing ceiling.
- AssessmentReturn supported evidenceCheck support and freshness. A link does not provide a supporting quote or prove an answer.
include_linked is off by default. This path follows explicit links only, in either direction; Jev-inferred links are not traversed. A one-slot budget keeps direct retrieval.
What I can claim today
The relationship path is implemented and enabled in our deployed environment. The bounded recall release also passed 241 tests on its isolated candidate, including memory, retrieval, retained task behavior, and archive paths. Those tests used fake providers and a disposable database. Live read-only checks confirmed the deployed interfaces and access controls.
That establishes useful engineering evidence. It does not establish how often Jev will choose the right relationship in someone’s real archive, or how long a large write will take. The existing Jev versus GPT-5.6 Luna article measures a different evidence-assessment task. Its historical timings should not be presented as measurements of this relationship classifier.
A useful evaluation needs examples where the expected answer is no link, not just obvious subject/detail pairs. I would measure whether retrieval included the correct candidate, whether Jev chose the right relation and direction, and whether using the resulting connection changed answer quality. Timing should include the actual write path, especially batches, rather than only one isolated classification request.
I like the separation this design creates. Retrieval decides which possibilities are worth examining. Jev judges the shortlisted pairs. Application rules decide what may be stored and when a judgment becomes stale. Each part has a boundary I can inspect and test.
The next evaluation should deliberately include almost-right matches: two people in the same industry, similar decisions in different projects, and a detail written before its subject record exists. Before I let inferred links steer answers, I want to see which connections the system should have refused.