Short answer: Write time must be strict so every memory gets the required scope; query time can flexibly narrow or widen within that already-correct data.
Missing a required scope on write cannot be fixed by later search filters. Search may optionally filter by conversation or look across a user’s history because write-time already attached the fields. Deletes often need the stricter search-side identification. Engram applies that write-strict, search-flexible pattern in practice.
Several chapters in this Part have described scoping as something a request either supplies or omits, without pausing to distinguish exactly when that supplying actually matters. This chapter looks at that timing directly, because scope enforcement behaves genuinely differently depending on whether a memory is being written for the first time or being searched for later, and understanding that difference clarifies why certain mistakes get caught immediately while others could otherwise slip through.
Why Does Enforcing Scope When a Memory Is Written Need to Be Stricter Than Enforcing It When a Memory Is Searched?
Writing a memory is the one moment a scope gets permanently attached to that memory, and whatever isolation it will honor for its entire lifetime gets decided right then. If a memory that should have carried a user identifier gets written without one, no later search-time enforcement can retroactively fix that mistake, the memory is already sitting somewhere it was never supposed to be, mixed into a pool it should never have joined. This is exactly why a well-designed system rejects a write outright when a required scope parameter is missing, rather than accepting the write and hoping searches later filter around the gap.
Why Can Scope Enforcement at Search Time Afford to Be More Flexible Than Enforcement at Write Time?
A search doesn’t create new, permanent facts about how data is organized, it only asks a question against data that’s already correctly scoped from when it was written. This means a search can meaningfully choose to narrow its results by including a specific scope parameter, or broaden them by omitting one, without ever risking the kind of permanent, uncorrectable mistake a bad write would cause. A search omitting a property filter simply returns a wider result set, it doesn’t misplace anything or create a lasting isolation gap the way an incorrectly scoped write would.
What Actually Happens When a Write Request Is Missing a Scope Parameter That the Target Topic Genuinely Requires?
A well-designed system rejects the request outright, refusing to store the memory at all rather than silently defaulting to some broader, unscoped placement. This might look like unnecessary strictness at first glance, but it’s precisely the behavior that prevents an entire category of leakage, since a rejected write forces the mistake to surface immediately, as a visible error a developer has to notice and fix, rather than as a silent, permanent gap discovered only much later when someone’s data unexpectedly turns up somewhere it shouldn’t.
Why Does Search-Time Flexibility Actually Make a Memory System More Useful, Not Just More Permissive?
The ability to search broadly, omitting a property filter to sweep across every value it could take, is what lets a system answer genuinely different kinds of questions using the exact same underlying data. A caller narrowing to one specific conversation and a caller sweeping across a user’s entire history aren’t using two different systems, they’re using the same correctly scoped data with two different search-time choices about how widely to look. This flexibility only works safely because the write-time strictness already guaranteed every memory carries the scope information a search might later choose to filter on or ignore.
Does This Distinction Between Write-Time Strictness and Search-Time Flexibility Ever Reverse, With a Search Needing to Be the Stricter of the Two?
It can, specifically for operations that permanently remove data rather than merely reading it. Deleting a specific memory needs exactly the correct scoping parameters to identify precisely the memory being removed, since a poorly scoped delete request risks permanently destroying data outside the caller’s intended target, an outcome at least as serious as a poorly scoped write. This is why deletion, unlike an ordinary search, tends to require the same firm, non-optional scoping discipline that writing does, rather than the looser, filter-as-you-choose flexibility an ordinary read enjoys.
How Does Weaviate Engram Apply This Difference Between Write-Time Strictness and Search-Time Flexibility in Practice?
Weaviate Engram rejects a memory-creation request outright when a required scope parameter is missing, while accepting an optional, narrowing or broadening set of scope parameters on an ordinary search. Consider a driving school’s lesson-scheduling assistant, where an instructor logs private notes about a specific student’s progress after each lesson, and later needs to search either one specific lesson’s notes or a student’s entire learning history at once:
from engram import EngramClient
client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])
client.memories.add(
"Student struggled with parallel parking during this lesson but showed strong improvement with highway merging.",
user_id="student-drivingschool-4471",
properties={"lesson_id": "lesson-2026-02-18"},
)
this_lesson_only = client.memories.search(
query="How did this student do during this specific lesson?",
user_id="student-drivingschool-4471",
properties={"lesson_id": "lesson-2026-02-18"},
)
full_learning_history = client.memories.search(
query="What skills has this student consistently struggled with across all lessons?",
user_id="student-drivingschool-4471",
)
Attempting to write this note without the required student identifier would be rejected immediately, catching the mistake right where it happened rather than letting a misplaced note quietly slip into the wrong pool of data, while the two searches that follow freely choose whether to narrow to one specific lesson or sweep across the student’s entire history, neither choice risking any lasting harm to how the underlying data is organized. This is exactly the value distinguishing write-time strictness from search-time flexibility delivers for a use case like a driving school’s lesson notes, where getting the scope right at the moment of writing protects every future search, however narrow or broad that search later chooses to be.
Enforcing scope strictly at write time and flexibly at search time reflects a simple asymmetry: a write permanently decides how data is organized, while a search merely asks a question against data that’s already correctly organized. This same asymmetry becomes especially important for a specific kind of topic that’s meant to hold exactly one memory per scope rather than accumulating many. Our next chapter, What are bounded topics in memory?, takes up exactly that case.