The Self-Maintaining Knowledge Graph
What if a knowledge graph could keep itself correct? Not with a cron job that reindexes everything overnight. Not with an agent sitting outside the graph calling write APIs. An actual self-maintaining graph: one where the graph itself notices what needs updating, spawns a worker to investigate, and lets that worker walk its own edges to figure out what changed and what to do about it.
That's what we've been building at Alago, and it rests on a single idea: the graph needs a layer of its own that's there to keep itself up to date.
Most discussions of AI memory focus on what the graph stores — entities, relationships, facts, timelines. Almost none focus on what the graph watches for. But a living graph in an enterprise setting — emails arriving, commitments shifting, deadlines passing, contractors going silent — is only as valuable as its willingness to invalidate itself when reality moves. And the way we think about that layer has two parts, one with precedent and one whose shape, as far as we can tell, doesn't.

The layer that watches
Call it the condition layer. It sits alongside the data, a second structure inside the same graph, and its job is to notice when edges need to change. Every condition is a first-class node, connected to the edges it guards by an explicit relationship. One condition can guard many edges at once — fan-in comes for free. When a condition fires, a graph worker — an agent spawned by the graph itself — is dispatched to investigate. The worker has autonomy: it walks connected edges, pulls in whatever context it needs, decides whether invalidation is warranted, makes the updates. When it's done, it can also update the condition that spawned it, because conditions go stale as projects evolve and the layer that maintains the graph needs to maintain itself too.
There's a useful frame for this from Hu et al.'s recent survey of agent memory [7]. They split a memory system's lifecycle into three operators: formation, retrieval, and evolution — where evolution is everything that happens to a memory after it's been written. Merging duplicates, reconciling contradictions, dropping things that no longer matter. The condition layer is an evolution operator, and it's triggered by the two reasons edges in a living graph go wrong.
Case-based conditions: watching for things that happen
The first kind is what we call a case — a semantic description of the kind of event under which an edge would need to change. When a new item enters the graph, its embedding is compared not against other items but against the cases in the condition layer. Matches spawn a worker. The worker adjudicates, updates what it needs to, and adjusts the case itself if the event revealed a failure mode the original case didn't cover.
This part has lineage. Graphiti showed that narrow candidate filtering plus LLM adjudication works in production for temporal contradiction [1]. HyDE and HyPE established that embedding a hypothetical description of what you're looking for outperforms embedding the thing itself [2, 3]. Classical ECA rules from 1980s active-database research proposed reactive writes driven by event-condition-action triggers, but stalled on rigid exact-match conditions [4]. Complex event processing, surveyed by Cugola & Margara, extended ECA into the streaming era with richer pattern operators and time windows — but kept the rigid exact-match assumption [5].
Case-based conditions generalize all of this: the escalation shape from Graphiti, extended to arbitrary edge types; the hypothetical-proxy idea from HyDE, moved from read time to write time; and ECA's reactive-write abstraction, finally equipped with the fuzzy semantic triggers it always needed.
Scheduled conditions: watching for things that don't
The second kind of condition is where the breakthrough actually lives.
A scheduled condition carries a temporal expectation: by date D, an item matching this description should exist in the graph; if none does by then, fire. A node in the graph, watching a specific part of itself for a specific kind of silence, spawning a worker when that silence arrives.
Absence detection itself isn't new. Complex event processing has had it since the 2000s — Esper's not + timer:interval pattern was catching missing acknowledgments fifteen years ago, and missing-event LEFT JOINs in Flink are still the production standard. Distributed-systems theory formalized it even earlier: Lamport's bounded liveness — something good must happen by time T — is exactly what a scheduled condition encodes [6].
Knowledge graphs, though, have been built half-deaf — fluent at hearing what arrives, blind to what doesn't. In any real workflow, a meaningful fraction of the ways commitments go wrong involve something that was supposed to happen and didn't. The approval that got stuck on someone's desk. The delivery that slipped without notice. The engineer who left without the handover. These are not edge cases — they are the texture of how complex work actually fails. A graph that cannot represent or react to that silence cannot be the memory substrate for agents doing real work.
When a scheduled condition fires, it does what a case-based condition does: spawns a graph worker, hands it autonomy, lets it navigate. The worker checks whether the expected item really is absent or whether it arrived in a form that didn't match cleanly. It pulls context from neighboring edges. It decides whether to invalidate the affected commitments, downgrade their confidence, escalate to a human, or extend the deadline because something legitimate caused it to shift. And — importantly — it updates the scheduled condition itself: pushing the deadline forward if the project's timeline moved, narrowing the anchor if the original description turned out to be too broad, adding new scheduled conditions elsewhere in the graph if its investigation surfaced other commitments that should have been being watched all along.
This is what we mean by self-maintaining. The graph has a part of itself whose job is noticing when it should update, and that part has agents inside it who can walk the graph, do the updates, and improve the watching itself as they learn.
Why this matters
Once you have this layer in place, a few things change about what a context graph actually is.
It stops being a data structure that needs external babysitting. The babysitting is inside the graph, done by workers the graph itself spawns when they're needed, scaled proportionally to what's actually happening. Most writes touch zero conditions and cost essentially nothing. Writes that should matter trigger investigation where investigation is warranted. Silences that should matter are noticed when they happen, not at a batch interval someone set up during deployment.
It becomes queryable in a new way. What is this graph currently watching for? becomes a first-class question with a first-class answer: the set of active conditions, organized by what they guard and when they expect to fire next. A project's risk posture is no longer scattered across assumptions buried in documents — it's visible structure inside the graph.
And it becomes the substrate agents can actually rely on. An agent acting on a Context Graph doesn't have to worry whether the graph reflects reality, because the graph has been actively checking itself. Commitments that have quietly gone stale are marked stale. Silences that have quietly become meaningful are flagged. Edges that should have been invalidated are invalidated.
This is, as far as we can tell, the missing piece. Everyone working on AI memory has been building better graphs. The harder and more interesting problem is building graphs that keep themselves honest.
Open questions
Two questions are doing most of the interesting work ahead of us.
The first is coverage. A scheduled condition only helps if someone — an LLM, at condition-creation time — thought to create it. Graph workers refine the conditions they trigger on, so over time the layer gets more accurate about what it's watching for, but conditions that never fire never get refined. Generating scheduled conditions that catch what matters without drowning the graph in busywork is where real calibration happens, and we haven't fully nailed that part yet.
The second is the one we think about most. We've described a graph that watches itself for silences in the data. The next step — the step that turns a useful self-maintaining graph into a genuinely intelligent one — is a graph that watches itself for silences in its own watching. A scheduled condition that hasn't fired in an unexpectedly long time: is that because the situation is fine, or because the condition has drifted from what the graph now actually cares about? A cluster of conditions that used to fire constantly and now doesn't: has the project moved past that phase, or has the layer lost touch with reality?
A condition layer that monitors the graph for silences is the foundation. A condition layer that monitors itself for silences is where context graphs stop being a data structure and start being something closer to an operational consciousness for the work they represent. That's the direction.
Closing
Context graphs are becoming the substrate of enterprise AI, and the ones that will actually stay useful are the ones that maintain themselves. A condition layer with case-based and scheduled conditions, graph workers spawned into the graph with autonomy to navigate and update, and a layer that refines itself as it learns — this is what self-maintaining looks like in practice. It closes the write-time problem on the arrival side and opens it for the first time on the absence side.
That's what we're building at Alago. More to come on how conditions get generated, how workers decide, and how the layer eventually starts reasoning about its own blind spots.
Resources
[1] Zep: A Temporal Knowledge Graph Architecture for Agent Memory, Rasmussen et al., 2025
[2] Precise Zero-Shot Dense Retrieval without Relevance Labels, Gao et al., ACL 2023
[3] HyPE: Hypothetical Prompt Embeddings for index-time hypothetical generation
[4] Active Database Systems, Paton & Díaz, ACM Computing Surveys, 1999; and earlier work by Dayal, Widom, McCarthy on ECA rules in active databases
[5] Processing Flows of Information: From Data Stream to Complex Event Processing, Cugola & Margara, ACM Computing Surveys, 2012
[6] Defining Liveness, Alpern & Schneider, Information Processing Letters, 1985
[7] Memory in the Age of AI Agents, Hu et al., 2025
All Posts