So I spent the weekend at Graph Hacks 2026 (WeMakeDevs x FalkorDB) and ended up building something around a problem I'd honestly never thought much about before.

When a release goes bad, you roll back. Pretty standard. The old version comes back up, the health checks pass, and you assume you're fine. But the new version was running for a while before you rolled back, and it was saving data. The old version has never seen that data. So sometimes it starts up totally fine and then falls over the first time it tries to read something the new version wrote.

That's what I built RollbackWitness for. It checks whether the old versions can actually read the data that's already there, before anyone approves the rollback.

The example I used

I made a small fake version of the OpenTelemetry Astronomy Shop (it's a demo online store a lot of people use for testing). I only modeled four of its services. The important ones are checkout, which writes orders into a Kafka topic, and accounting and fraud detection, which both read every order from that topic.

In my version 3.2.0, checkout started charging people in euros, pounds and yen instead of only dollars. Accounting and fraud detection got updated so they could handle that.

Now say you want to put all three back on 3.1.0. Feels safe, right? You're rolling back the thing that started writing euro orders in the first place. But 16 of the 40 orders sitting in the topic are already in other currencies, and the old accounting and fraud detection only know dollars. Everything boots. Then 32 out of 80 checks fail.

If you only roll back checkout and leave the other two on 3.2.0, all 80 checks pass.

How it works

You just type what you want to undo, like "undo the local currency checkout but keep the accounting fix". An agent figures out which actual release versions that means and quotes the release notes it used. If what you asked is vague, it asks you instead of guessing. You can also drive it from Claude Code over MCP, which is what I did in the demo.

The interesting part is FalkorDB. I put everything in the graph: the releases, the bits of code that read saved data, the stores, each saved order and which release wrote it. Then one Cypher query walks from the rollback plan, to the release, to the code that reads data, to the store, to the orders in it, to whoever wrote them. That gives me the exact list of things that need checking. Then I actually run the old code on each saved order and see if it breaks.

You get back one of three answers: safe, unsafe, or can't confirm. Only a person can approve, and the "deploy" is just a local simulation, nothing real.

Did the graph actually matter?

I wanted to be honest about this, so I tested it. Plain SQL joins over the same data found the same checks. So no, a graph isn't doing anything magic here.

What it did give me is a really natural way to ask the question. The problem in the demo is a link between two different services that only exists because they share data. In the graph that's just a path, and I can pull it up in the FalkorDB browser and literally point at it.

The comparison that surprised me was against a plain LLM that got all the same files as text. It spotted the obvious crashes fine. But when I gave it an order list that was marked as incomplete, it still said "safe" two out of three times. My version said "can't confirm", because the graph knows the list isn't complete and it won't count stuff it couldn't check as a pass.

What I took away

LLMs are good at understanding what you mean and not great at making sure they checked everything. Splitting it up worked well: let the model handle the request, and let the graph and normal code decide what actually gets tested.

Also, having a "can't confirm" answer turned out to be more useful than I expected.

It's all fake data and the tests were small, so this is a prototype, not something I'd point at production yet. Code's here if you want to poke at it: https://github.com/Ep1cGaimer/FalkorDB_agent