<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anvit Devadiga</title>
    <description>The latest articles on DEV Community by Anvit Devadiga (@anvitdevadiga).</description>
    <link>https://dev.to/anvitdevadiga</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4189176%2F3749395f-9e61-4c9e-8879-a1578f6271c7.png</url>
      <title>DEV Community: Anvit Devadiga</title>
      <link>https://dev.to/anvitdevadiga</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anvitdevadiga"/>
    <language>en</language>
    <item>
      <title>The version changed. The broken dependency didn’t: building Revora with FalkorDB</title>
      <dc:creator>Anvit Devadiga</dc:creator>
      <pubDate>Sun, 18 Oct 2026 07:10:24 +0000</pubDate>
      <link>https://dev.to/anvitdevadiga/the-version-changed-the-broken-dependency-didnt-building-revora-with-falkordb-3nl6</link>
      <guid>https://dev.to/anvitdevadiga/the-version-changed-the-broken-dependency-didnt-building-revora-with-falkordb-3nl6</guid>
      <description>&lt;p&gt;A release fails. An agent rolls it back. Someone retries the same build, and the system goes through the same failure again.&lt;/p&gt;

&lt;p&gt;Now change the version number. The release looks new, but it still carries the dependency that caused trouble last time. Remembering a version number won’t catch that.&lt;/p&gt;

&lt;p&gt;That is the problem I explored with &lt;strong&gt;Revora&lt;/strong&gt;, my project for &lt;a href="https://www.wemakedevs.org/hackathons/falkordb" rel="noopener noreferrer"&gt;Graph Hacks: Context for AI Agents&lt;/a&gt;, in Track 2: Agent Memory and Coordination.&lt;/p&gt;

&lt;p&gt;Revora stores release history, measurements, agent handoffs and component relationships in FalkorDB. Those records influence whether the next candidate is allowed to serve traffic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://revora-anvitdevadiga.vercel.app/" rel="noopener noreferrer"&gt;Try the live app&lt;/a&gt; · &lt;a href="https://github.com/AnvitDevadiga/revora" rel="noopener noreferrer"&gt;Source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ezqdiSkRHpM" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with something that can actually fail
&lt;/h2&gt;

&lt;p&gt;I wanted a visible consequence for a wrong decision. The demo uses an isolated HTTP gateway with a stable service and a candidate service. Introducing a fault sends requests to a candidate that returns HTTP 503. Recovery restores healthy routing and verifies HTTP 200.&lt;/p&gt;

&lt;p&gt;The fault is intentional. The HTTP requests, status codes and recovery checks are real. This is a controlled demonstration on a project-owned service, not a production outage.&lt;/p&gt;

&lt;p&gt;In the recorded demo, I introduce &lt;code&gt;v9-demo&lt;/code&gt; with &lt;code&gt;base@3&lt;/code&gt; and &lt;code&gt;checkout-sdk@1.0&lt;/code&gt;. After the failure and recovery, retrying that version is blocked from memory before candidate traffic begins.&lt;/p&gt;

&lt;p&gt;The more interesting attempt is &lt;code&gt;v10-demo&lt;/code&gt;. It has a different version number and the same components. Revora follows the relationships back to the earlier failure and blocks it too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The query that made the graph useful
&lt;/h2&gt;

&lt;p&gt;The relevant path is small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new release → USES → component ← USES ← failed release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is an important exception: a shared component may also have appeared in a healthy release. Blaming every shared dependency would make memory too aggressive.&lt;/p&gt;

&lt;p&gt;This is the component check used by the backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;c:&lt;/span&gt;&lt;span class="n"&gt;Component&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;c.key&lt;/span&gt; &lt;span class="ow"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;$components&lt;/span&gt;
&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:USES&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;bad:&lt;/span&gt;&lt;span class="n"&gt;ReleaseIncident&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;service:&lt;/span&gt;&lt;span class="n"&gt;$service&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;decision:&lt;/span&gt;&lt;span class="s1"&gt;'rollback'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;failed:&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="ss"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;bad.version&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;$version&lt;/span&gt;
  &lt;span class="ow"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:USES&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:ReleaseIncident&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;service:&lt;/span&gt;&lt;span class="n"&gt;$service&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;decision:&lt;/span&gt;&lt;span class="s1"&gt;'promote'&lt;/span&gt;
  &lt;span class="ss"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;c.key&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bad.id&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bad.version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That exclusion matters in the demo. The base component has healthy history, so it is excluded from the blocking match. The SDK has failed history without a healthy appearance, so it triggers the gate.&lt;/p&gt;

&lt;p&gt;This is still a heuristic. A component appearing in a failed release does &lt;strong&gt;not&lt;/strong&gt; establish that it caused the failure. A healthy appearance does not prove universal safety either. The rule is deliberately conservative and inspectable; it needs richer evidence before being trusted with real deployments.&lt;/p&gt;

&lt;p&gt;A relational database could represent these relationships too. FalkorDB let me express the path directly in Cypher and use the same connected records for the decision and its explanation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three roles, with a check between observation and action
&lt;/h2&gt;

&lt;p&gt;The recovery workflow has three bounded roles.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Release Analyst&lt;/strong&gt; measures twelve HTTP requests and persists a handoff containing the raw statuses, latencies and reported metrics.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Evidence Reviewer&lt;/strong&gt; reads that handoff and recomputes the measurements. Missing evidence can produce a request for more information. Contradictory evidence can reject the handoff.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Recovery Planner&lt;/strong&gt; receives the reviewed evidence and graph context. When configured with the Groq API, an LLM proposes an allowlisted action and cites graph IDs. A deterministic guard checks that proposal against the evidence before recovery proceeds.&lt;/p&gt;

&lt;p&gt;The analyst and reviewer are deterministic. The planner has an LLM path and a deterministic fallback. These are bounded roles in an orchestrated workflow; they are not three autonomous agents freely negotiating with each other.&lt;/p&gt;

&lt;p&gt;FalkorDB holds the handoff and the records connecting it to the incident, review and decision. The receiving role reads persisted evidence, which also makes the handoff available to another process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3vv71ohjzvexh1939ag2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3vv71ohjzvexh1939ag2.png" alt="Revora’s coordination graph, connecting incidents, handoffs and decisions" width="800" height="761"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What building it taught me
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Saving history is only the beginning.&lt;/strong&gt; A useful memory needs an identity, scope and a retrieval rule. Then it needs a clear point where it can change an action. In Revora, that point is the gate before candidate traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An explanation needs evidence behind it.&lt;/strong&gt; A convincing paragraph from a model is easy to mistake for a verified result. Keeping raw samples lets the reviewer check the numbers independently. Persisting the proposed action and guardrail verdict makes disagreement visible too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retries deserve their own design.&lt;/strong&gt; One audit found that replaying an old completed recovery could clear a newer active incident. The repair had to distinguish replaying a historical result from repairing the same interrupted incident. That became a regression case. “Idempotent” needs to describe exactly which state a retry may change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment is part of the demonstration.&lt;/strong&gt; A documentation commit triggered a Vercel deployment that served a 404 because the project root was wrong. Setting the root to &lt;code&gt;frontend&lt;/code&gt; and the framework to Next.js restored it. A green deployment status alone did not tell me the app was usable; opening the public page and checking its backend connection did.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the project proves—and what comes next
&lt;/h2&gt;

&lt;p&gt;The demo shows a remembered failure changing a later release decision, a component relationship extending that memory to a different version, and recovery decisions connected to their evidence.&lt;/p&gt;

&lt;p&gt;It does not establish general autonomous learning or prove that memory beats every well-designed static policy. The hosted setup is one workspace and one backend worker. Tenant isolation and distributed coordination would need further work.&lt;/p&gt;

&lt;p&gt;The next improvement I would make is better handling of uncertainty: distinguish a suspected component from a confirmed cause, and define when new measurements should override an older memory.&lt;/p&gt;

&lt;p&gt;For now, the question I want Revora to answer is simple: &lt;strong&gt;what did the previous failure teach the next decision?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can follow that path in the &lt;a href="https://revora-anvitdevadiga.vercel.app/" rel="noopener noreferrer"&gt;live workspace&lt;/a&gt;, watch the &lt;a href="https://youtu.be/ezqdiSkRHpM" rel="noopener noreferrer"&gt;demo&lt;/a&gt;, or inspect the &lt;a href="https://github.com/AnvitDevadiga/revora" rel="noopener noreferrer"&gt;implementation and local setup&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>falkordb</category>
      <category>ai</category>
      <category>devops</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
