Short answer: Property scopes attach optional identifiers like conversation or case so callers can narrow within a user’s data without replacing hard user isolation.
Unlike always-on user scoping, property filters can be applied or omitted at search time for narrow vs cross-session views. That flexibility is soft isolation, not a weaker substitute for separating users. Using property scope where user scope is required is unsafe because the filter can be skipped. Engram implements this optional narrowing through custom properties.
The previous two chapters treated project-wide and user-scoped memory as a binary choice, shared with everyone or locked strictly to one person. Property-scoped memory sits in a genuinely different position, offering a kind of isolation that’s real and enforced, but flexible enough that a caller can choose how narrowly to apply it at search time. This chapter looks at what that flexibility actually means and where it earns its place.
What Distinguishes a Property Scope from the Strict Isolation User Scoping Provides?
A property scope attaches an arbitrary identifier, a conversation, a session, a case number, to a memory, and that identifier genuinely narrows a search when a caller chooses to filter by it. The key difference from user scoping is that a caller retains a choice here, a search can include that property to narrow results down to one specific conversation, or omit it entirely to search across every value that property has ever taken for a given user. User scoping never offers this choice, one user’s memories are never visible to another user’s search under any circumstances, but a property scope’s narrowing is something a caller opts into deliberately for a given request.
Why Is This Kind of Flexible Narrowing Actually Called Soft Isolation Rather Than Simply a Weaker Version of Hard Isolation?
Calling it soft isolation isn’t a judgment that it’s less rigorous, it’s a description of how the separation actually behaves. The separation between memories at different property values is real and consistently enforced whenever a caller chooses to filter by that property, memories tagged to one conversation are genuinely kept apart from memories tagged to a different one when a search asks for exactly that conversation. What makes it soft rather than hard is that the boundary is optional on the reading side, a caller can choose to cross it deliberately by simply not specifying a value, something that’s never an option with strict user isolation.
What Kind of Situation Actually Calls for This Flexible, Optional Narrowing Rather Than a Fixed, Always-On Boundary?
A running summary of one specific conversation is the clearest example, a memory that should absolutely stay distinguishable from a summary of a different conversation the same user had last week, yet a system might also occasionally want to search across every conversation that same user has ever had, gathering their full history rather than one narrow slice of it. A strict, always-on boundary between conversations would make that broader search impossible without some separate mechanism to bypass it, while a property scope handles both needs cleanly with the exact same underlying data, just different search parameters.
Does Choosing Property Scoping Over Strict User Scoping Ever Risk Weakening Isolation in a Way That Actually Matters for Privacy?
It can, if property scoping gets used for something that genuinely needed a hard, non-negotiable boundary instead. A property scope’s flexibility is exactly right for organizing one user’s own memories into meaningful sub-categories, conversations, sessions, cases, but it was never designed to separate one user’s data from a different user’s data entirely. Mixing up these two purposes, using a property scope where user scoping was actually required, would recreate the very risk strict isolation exists to prevent, since a property filter can always be omitted, and omitting the wrong one could expose data across a boundary that should never have been optional in the first place.
How Should a System Decide Which Property Identifiers Are Actually Worth Attaching to a Given Memory?
The right identifiers trace back to how memory will actually need to be searched later, not to whatever happens to be available at the moment a memory gets written. A system that will only ever need a user’s complete history, never narrowed to one specific interaction, doesn’t need a property scope at all. A system that genuinely benefits from sometimes narrowing to one specific conversation, one specific support ticket, or one specific ongoing negotiation, benefits from attaching exactly that identifier, and no more, since each additional property adds a dimension of narrowing that has to be correctly supplied every time a memory needing it gets written.
How Does Weaviate Engram Implement This Kind of Flexible, Optional Narrowing Through Custom Properties?
Weaviate Engram lets a topic declare custom scope properties like a conversation identifier, enforcing that separation whenever a caller filters by it while still allowing a broader search across every value when a caller omits it. Consider a wealth management firm’s client portal, where an advisor discusses several distinct financial goals with the same client over separate planning sessions, and sometimes needs one specific session’s details while other times needs the client’s full advisory history at once:
from engram import EngramClient
client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])
client.memories.add(
"Client expressed interest in increasing retirement contributions after this session's discussion of employer matching limits.",
user_id="client-wealthfirm-2291",
properties={"session_id": "planning-session-2026-03-12"},
)
this_session_only = client.memories.search(
query="What did we discuss about retirement contributions?",
user_id="client-wealthfirm-2291",
properties={"session_id": "planning-session-2026-03-12"},
)
full_advisory_history = client.memories.search(
query="What has this client expressed interest in across all our sessions?",
user_id="client-wealthfirm-2291",
)
Including the session identifier narrows the search down to exactly one planning conversation, useful when an advisor is preparing follow-up notes for that specific meeting, while omitting it broadens the search across every session this client has ever had, useful when preparing a comprehensive annual review. Throughout both searches, the user scope itself never wavers, this client’s memories never surface for a different client regardless of how the session filter is used. This is exactly the value property-scoped soft isolation delivers for a use case like wealth management, where an advisor genuinely needs both a narrow, session-specific view and a comprehensive, cross-session view of the same underlying client relationship.
Property scoping gives a system the flexibility to organize memory within a user’s own data without sacrificing the strict isolation that separates one user from another. All three scoping mechanisms covered so far, project, user, and property, rely on an underlying enforcement mechanism that makes the strict boundaries actually hold. Our next chapter, How does multi-tenancy isolate memory?, takes up exactly that underlying enforcement.