Subsystem
Memory Core (GraphService / SQLite Storage)
Description
Context: In PR #10308, we fixed cross-process message retrieval (A2A Mailbox) by explicitly setting userId: null for MESSAGE nodes. This bypasses the Row-Level Security (RLS) in SQLite.loadNodeVicinitySync (user_id = ? OR user_id IS NULL).
Problem: Using userId: null is an implicit wildcard bypass. It obscures the provenance of who actually created the node, forcing us to rely purely on edges (like SENDER) to determine the original author. This breaks the expected contract that userId tracks node authorship in multi-tenant environments.
Proposal:
Introduce an explicit sharedEntity: true boolean flag in the Graph Node schema properties.
Modify the SQLite RLS layer to check user_id = ? OR json_extract(properties, '$.sharedEntity') = 1.
Retain the actual author's ID in the user_id column for accurate provenance tracking.
The Architectural "Why"
- Provenance Integrity: Nodes should inherently record who spawned them.
userId: null destroys this metadata.
- Explicit Security Intent: A
sharedEntity property explicitly signals that a node is meant to be visible across isolation boundaries, making security audits straightforward.
- Future-proofing: Multi-tenant memory architectures need explicit permission models, not wildcard hacks.
Avoided Traps
- Performance Hit: Be cautious with
json_extract in the WHERE clause if the graph grows large. We may need to index the sharedEntity extraction or add a dedicated column to the SQLite nodes table instead of storing it inside properties if performance degrades.
- Retroactive Migration: Do not write heavy migrations for existing
MESSAGE nodes. Just treat user_id IS NULL as a legacy fallback for sharedEntity: true alongside the new flag.
Definition of Done
Subsystem
Memory Core (GraphService / SQLite Storage)
Description
Context: In PR #10308, we fixed cross-process message retrieval (A2A Mailbox) by explicitly setting
userId: nullforMESSAGEnodes. This bypasses the Row-Level Security (RLS) inSQLite.loadNodeVicinitySync(user_id = ? OR user_id IS NULL).Problem: Using
userId: nullis an implicit wildcard bypass. It obscures the provenance of who actually created the node, forcing us to rely purely on edges (likeSENDER) to determine the original author. This breaks the expected contract thatuserIdtracks node authorship in multi-tenant environments.Proposal: Introduce an explicit
sharedEntity: trueboolean flag in the Graph Node schema properties. Modify the SQLite RLS layer to checkuser_id = ? OR json_extract(properties, '$.sharedEntity') = 1. Retain the actual author's ID in theuser_idcolumn for accurate provenance tracking.The Architectural "Why"
userId: nulldestroys this metadata.sharedEntityproperty explicitly signals that a node is meant to be visible across isolation boundaries, making security audits straightforward.Avoided Traps
json_extractin the WHERE clause if the graph grows large. We may need to index thesharedEntityextraction or add a dedicated column to the SQLitenodestable instead of storing it insidepropertiesif performance degrades.MESSAGEnodes. Just treatuser_id IS NULLas a legacy fallback forsharedEntity: truealongside the new flag.Definition of Done
sharedEntityon Graph Nodes is added and documented.SQLite.mjsbackend query logic is updated to supportsharedEntity.MailboxService.mjsis refactored to setsharedEntity: trueand populateuserIdproperly, rather than settinguserId: null.