Prerequisite for #361. MRAgent (arXiv 2606.06036) represents memory as a Cue-Tag-Content heterogeneous graph M = (C, G, V) with typed relations R ⊆ C × G × V, where the tag layer is not decoration — it is the mechanism that makes iterative traversal tractable.
Current state (verified 2026-08-06)
grep -niE 'def .*tag|tag_' mcp_server/core/knowledge_graph.py returns nothing. Cortex's graph is cue→content: core/knowledge_graph.py extracts entities and relationships, and core/spreading_activation.py propagates over that entity graph directly (Collins & Loftus 1975). Memory tags exist as flat classification labels on a memory row, not as an addressable intermediate node type bridging cues to contents.
Why the layer matters
Their construction is two LLM distillations per episodic unit e_i:
g_i = F_LLM^tag(e_i) — an associative tag summarising the relational pattern of the episode
C_i = F_LLM^cue(e_i) — the fine-grained cues (entities, attributes)
Each cue links to the episode through the tag. Retrieval is then two-stage: select relevant tags, then fetch content conditioned on the selected tags. The paper is explicit that this is what prevents "combinatorial explosion caused by unconstrained expansion" — the failure mode their Figure 2 shows for plain graph expansion, which "retrieves additional but irrelevant neighbors, yet still fails to recover information about Caroline."
This is also where their token win comes from: "MRAgent maintains a lightweight construction phase and defers complex relation-building to the retrieval stage, where it is performed in a query-specific manner." Cortex does the opposite — heavy write-time structure building in core/curation.py and core/knowledge_graph.py.
Their justification is engram-theoretic (Frankland & Josselyn 2019; Rashid et al. 2016), with tags as "intermediate associative structures" analogous to engram reactivation — the same literature core/engram.py already cites via Josselyn & Tonegawa (2020). So this is an extension of a lineage Cortex is already in, not a foreign graft.
Ask
Introduce an addressable associative-tag node type between cues and contents, with the three traversal operators (Cue→Tag, (Cue,Tag)→Content, Content→(Cue,Tag)) as the graph API #361 consumes.
Constraints
Acceptance criteria
- Tag nodes are addressable and the three operators are implemented and unit-tested on both SQLite and PostgreSQL.
- A migration converts an existing store with row counts asserted before and after — not merely "no exception raised" (silent-success trap).
- Write-path cost measured: the two extra LLM distillations per episode are a real ingest cost, so the before/after ingest latency is recorded and either accepted in writing or offset.
- Zero surviving non-equivalent mutants on changed files (§12).
Prerequisite for #361. MRAgent (arXiv 2606.06036) represents memory as a Cue-Tag-Content heterogeneous graph
M = (C, G, V)with typed relationsR ⊆ C × G × V, where the tag layer is not decoration — it is the mechanism that makes iterative traversal tractable.Current state (verified 2026-08-06)
grep -niE 'def .*tag|tag_' mcp_server/core/knowledge_graph.pyreturns nothing. Cortex's graph is cue→content:core/knowledge_graph.pyextracts entities and relationships, andcore/spreading_activation.pypropagates over that entity graph directly (Collins & Loftus 1975). Memory tags exist as flat classification labels on a memory row, not as an addressable intermediate node type bridging cues to contents.Why the layer matters
Their construction is two LLM distillations per episodic unit
e_i:g_i = F_LLM^tag(e_i)— an associative tag summarising the relational pattern of the episodeC_i = F_LLM^cue(e_i)— the fine-grained cues (entities, attributes)Each cue links to the episode through the tag. Retrieval is then two-stage: select relevant tags, then fetch content conditioned on the selected tags. The paper is explicit that this is what prevents "combinatorial explosion caused by unconstrained expansion" — the failure mode their Figure 2 shows for plain graph expansion, which "retrieves additional but irrelevant neighbors, yet still fails to recover information about Caroline."
This is also where their token win comes from: "MRAgent maintains a lightweight construction phase and defers complex relation-building to the retrieval stage, where it is performed in a query-specific manner." Cortex does the opposite — heavy write-time structure building in
core/curation.pyandcore/knowledge_graph.py.Their justification is engram-theoretic (Frankland & Josselyn 2019; Rashid et al. 2016), with tags as "intermediate associative structures" analogous to engram reactivation — the same literature
core/engram.pyalready cites via Josselyn & Tonegawa (2020). So this is an extension of a lineage Cortex is already in, not a foreign graft.Ask
Introduce an addressable associative-tag node type between cues and contents, with the three traversal operators (Cue→Tag, (Cue,Tag)→Content, Content→(Cue,Tag)) as the graph API #361 consumes.
Constraints
numpy.float32/structuredContentincident).Acceptance criteria