Entity graph
The entity graph (schema head V11) links observations through shared
entities — files, symbols, concepts, people, agents — and typed edges
(mentions, fixes, contradicts, about). It is what makes
obs context return the right neighborhood on the agent’s first call.
How it works
Section titled “How it works”- Save —
WriteRequest::IndexGraphrides the per-project write thread: entities are upserted (dedupe bynorm_name), mentions wired, pairwisementionsedges accumulated. - Query —
obs search/obs contextextract query entities, walk up tograph.hopshops overgraph.edge_types, and fuse a third rank list into the hybrid RRF path viagraph_rank::graph_score. - Briefing —
obs contextappends budgeted graph-expanded hits capped atgraph.budget_pct × max_tokens; it never displaces primary hits, and stale/withdrawn observations drop out with the same rules as the main path.
statefulmemory graph query <entity> --hops 2 # traverse the neighborhoodstatefulmemory graph query <entity> --relation fixes # narrow to a relationstatefulmemory graph rebuild # backfill entities from anchorsstatefulmemory graph statsConfig
Section titled “Config”[graph]enabled = true # default off until the CI multi-hop gate passes (+5 pts)hops = 2 # hard cap 2boost = 0.15 # post-fusion multiplier for graph-lift-only hitsedge_types = ["mentions", "fixes", "contradicts"]budget_pct = 0.4 # max share of briefing tokens from expansiondegree_cap = 256 # skip traversal into hub entitiesmax_query_entities = 3Environment overrides: STATEFULMEMORY_GRAPH_ENABLED, STATEFULMEMORY_GRAPH_HOPS,
STATEFULMEMORY_GRAPH_BOOST.
Rationale (SQLite, not a graph database)
Section titled “Rationale (SQLite, not a graph database)”The graph stays in the same SQLite file as observations (“inspectable by default” thesis). Recursive-CTE traversal at ≤2 hops with a degree cap returns in milliseconds; a dedicated graph engine (Neo4j-grade) is out of scope by design — see the gap list’s “do not build Neo4j-scale graphs” rule.
memory_graph_query(entity, hops?, relation_filter?) returns the neighborhood
as a tree of from --[relation]--> to edges plus observation provenance when
an edge carries src_observation_id.
Additive: ListEntities(status), GetEntity, GraphQuery.