`GRAPH_EXTRACTION_ENABLED=false` does not stop graph writes - structural extraction runs unconditionally on session stop

Author: sla-teCreated Aug 22, 2026Updated Sep 11, 2026

Setting GRAPH_EXTRACTION_ENABLED=false does not stop the knowledge graph from growing. The flag only gates the LLM relation half. Structural extraction still runs, still writes KV.graphNodes / KV.graphEdges, and still appends provenance per node and edge.

The boot log says so directly, so I assume the behaviour is intended - but the flag name and the docs say otherwise:

javascript
bootLog(`Knowledge graph: structural extraction on (LLM relations ${isGraphExtractionEnabled() ? "enabled" : "off"})`);

In the extractor the heuristic path runs first and unconditionally, and the flag is only consulted for the LLM step:

javascript
const heuristic = extractGraphHeuristics(data.observations);
nodes = heuristic.nodes;
edges = heuristic.edges;
...
const llmEnabled = isGraphExtractionEnabled() && !provider.name.includes("noop");

The session-stop trigger has no guard at all:

javascript
const compressed = (await kv.list(KV.observations(data.sessionId))).filter((o) => o.title);
if (compressed.length > 0) fireVoid("mem::graph-extract", { observations: compressed });

.env.example:112 calls it "Extract concept-graph edges on remember" and api::config-flags reports affects: ["Graph", "Dashboard"]. Both read as "false means no graph".

Why it matters on my install: the graph reached 235 MB holding 1222 nodes and 2207 edges, about 170 KB per node for short concept strings. Tarred it compressed 235 MB to 5.5 MB, a 43:1 ratio, which is what the duplicated provenance arrays in #1168 and #1171 look like. At that size mem::reflect died with {"error":"Invocation stopped"} in 0.7s, since reflect enumerates graphNodes and graphEdges with no pagination (#655, #825). Deleting the six mem:graph:* files with the daemon stopped fixed reflect immediately, took iii RSS from 15.4 GB to 3.4 GB, and moved /agentmemory/health from degraded to healthy.

I set the flag to false expecting that to stop the regrowth. It did not - back to 36 MB and 1570 nodes within about 25 minutes of restarts.

0.9.29, iii 0.11.2, node v24.19.0, Linux (WSL2).

Either one would fix this for me:

  1. have GRAPH_EXTRACTION_ENABLED=false gate the structural path too, or
  2. add a separate flag for it and correct the description, because right now there is no supported way to stop graph writes at all.

Is structural-always-on deliberate, or is the missing guard on the session-stop trigger the actual bug?