<?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: Omar Moustafa</title>
    <description>The latest articles on DEV Community by Omar Moustafa (@omar8345).</description>
    <link>https://dev.to/omar8345</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%2F778742%2Fc5831bbd-855e-4fa2-9399-7e7b0802a18e.png</url>
      <title>DEV Community: Omar Moustafa</title>
      <link>https://dev.to/omar8345</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/omar8345"/>
    <language>en</language>
    <item>
      <title>Introducing IMPACT: Why Does This PR Actually Affect?</title>
      <dc:creator>Omar Moustafa</dc:creator>
      <pubDate>Sun, 18 Oct 2026 14:55:00 +0000</pubDate>
      <link>https://dev.to/omar8345/introducing-impact-why-does-this-pr-actually-affect-jhk</link>
      <guid>https://dev.to/omar8345/introducing-impact-why-does-this-pr-actually-affect-jhk</guid>
      <description>&lt;p&gt;Did you ever look at a one-line code change and thought, &lt;em&gt;okay, but what else could this break?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That question led me to build &lt;em&gt;IMPACT&lt;/em&gt;, a Python PR review tool for &lt;a href="https://www.wemakedevs.org/hackathons/falkordb" rel="noopener noreferrer"&gt;Graph Hacks by WeMakeDevs and FalkorDB&lt;/a&gt;. 🚀&lt;/p&gt;

&lt;p&gt;A diff shows what changed. It doesn't always show the functions that call that code, or which tests might be affected. IMPACT maps these relations in &lt;em&gt;FalkorDB&lt;/em&gt;, then follows them to produce a graph you can inspect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the idea
&lt;/h2&gt;

&lt;p&gt;I started with a small checkout repo instead of a huge project. It has pricing, cart, checkout, receipts, and a few tests—enough for one change to travel through different files.&lt;/p&gt;

&lt;p&gt;Then I broke the coupon calculation on purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Before
&lt;/span&gt;&lt;span class="n"&gt;discount_cents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subtotal_cents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;coupon_cents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# After
&lt;/span&gt;&lt;span class="n"&gt;discount_cents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coupon_cents&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A $30 coupon on a $20 cart now gives a negative total. The receipt test expects &lt;code&gt;0&lt;/code&gt; but gets &lt;code&gt;-1000&lt;/code&gt;. The checkout test raises an error because it refuses to charge a negative amount. The normal-coupon test still passes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsqkdtvc7opy3h5sbum8q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsqkdtvc7opy3h5sbum8q.gif" alt="A developer discovering another bug" width="400" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One line later...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I wanted IMPACT to find those tests from the code relationships, and to show me &lt;em&gt;why&lt;/em&gt; it picked them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fviap6p3ehxn20f43k9mi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fviap6p3ehxn20f43k9mi.gif" alt="IMPACT runs the graph-selected tests and records their real results" width="560" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The graph selects the relevant tests; the test runner records what actually happened.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Following the calls
&lt;/h2&gt;

&lt;p&gt;IMPACT stores files and functions in FalkorDB, with a &lt;code&gt;CALLS&lt;/code&gt; connection whenever one function calls another. In the demo, checkout eventually reaches the changed &lt;code&gt;apply_coupon&lt;/code&gt; function through cart and pricing code.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;apply_coupon&lt;/code&gt; changes, IMPACT walks those connections backwards. It finds seven reachable callers, including three tests. One of the test paths is four calls long—something I wouldn't get from looking at the diff alone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzcuo5wmn11ql84fyu3g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzcuo5wmn11ql84fyu3g.gif" alt="Mind blown reaction" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Me after seeing how far one line can travel.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is the Cypher query behind it:&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="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;caller:&lt;/span&gt;&lt;span class="n"&gt;Function&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;:CALLS&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;changed:&lt;/span&gt;&lt;span class="n"&gt;Function&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;$id&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;caller.id&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caller.is_test&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;IN&lt;/span&gt; &lt;span class="nf"&gt;nodes&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;n.id&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HTML report uses those same paths. Click a test, and you can follow its connection back to the changed code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foivoffgalbc990stx321.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foivoffgalbc990stx321.gif" alt="Selecting a test in IMPACT highlights its call path to the changed function" width="760" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Selecting a test reveals the exact path connecting it to the changed function.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Getting there took a few tries. I got stuck connecting to FalkorDB at first, and later had to fix a shortest-path query to use the syntax FalkorDB accepts. The &lt;code&gt;doctor&lt;/code&gt; command now checks the connection and graph queries before I run a review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who should review the change?
&lt;/h2&gt;

&lt;p&gt;I added another question to the demo: &lt;em&gt;who knows this part of the code, and why was it written this way?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For that, I made a small, fictional company dataset. It links a code file to its owner, her team, and three source records: a decision about coupon limits, a support ticket about negative charges, and a team chat. IMPACT puts those links in FalkorDB alongside the call graph. Ask it about &lt;code&gt;apply_coupon&lt;/code&gt;, and it suggests Maya Chen as a reviewer and points to the records behind that suggestion.&lt;/p&gt;

&lt;p&gt;You can see the same context in the HTML report next to the test paths. It's a demo of the idea, with synthetic people and documents; it doesn't connect to a real company's Slack or ticket system yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI part
&lt;/h2&gt;

&lt;p&gt;At first, I thought an AI agent for this hackathon might have to be a chatbot. For IMPACT, the useful action turned out to be choosing what to inspect and which test to prioritize.&lt;/p&gt;

&lt;p&gt;The AI step is optional. The model calls a FalkorDB tool, looks at the affected code, and picks a test to inspect first. IMPACT checks that the choice is actually connected to the change. Then the test runner supplies the real pass, fail, or error result.&lt;/p&gt;

&lt;p&gt;If I leave out the AI API key, the graph analysis and test selection still work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking it to a real PR
&lt;/h2&gt;

&lt;p&gt;The broken checkout demo was useful, but I also wanted to see what IMPACT would say about a fix. So I put the checkout code in a separate &lt;a href="https://github.com/Omar8345/impact-checkout-demo" rel="noopener noreferrer"&gt;sample repo&lt;/a&gt; and opened &lt;a href="https://github.com/Omar8345/impact-checkout-demo/pull/1" rel="noopener noreferrer"&gt;a PR that caps oversized coupons&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;IMPACT picked three tests from the graph and ran them on both commits. Two failed on the base and passed on the PR; the normal-coupon test passed on both. That tells me more than a list of tests to run: I can see whether the change actually fixed the cases it was meant to fix. &lt;a href="https://omar8345.github.io/IMPACT/checkout-pr/" rel="noopener noreferrer"&gt;Here's the report with the paths and results&lt;/a&gt;.&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%2Fx9jnkriimyoz920yvu1n.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%2Fx9jnkriimyoz920yvu1n.png" alt="IMPACT report comparing the base commit with the pull request" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The same graph-selected tests on both commits: two now pass, with no new failures.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I then put the same review into &lt;a href="https://github.com/Omar8345/impact-checkout-demo/blob/main/.github/workflows/impact-review.yml" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;. A Python PR now starts a temporary FalkorDB instance, generates the graph and report, compares the tests, and &lt;a href="https://github.com/Omar8345/impact-checkout-demo/pull/1#issuecomment-6247534059" rel="noopener noreferrer"&gt;updates a comment on the PR&lt;/a&gt;. I tested that with an &lt;a href="https://github.com/Omar8345/impact-checkout-demo/actions/runs/39111057836" rel="noopener noreferrer"&gt;automatic run&lt;/a&gt;. The workflow doesn't need an AI key; the graph and test results are enough for this part.&lt;/p&gt;

&lt;p&gt;I also tried IMPACT on &lt;a href="https://omar8345.github.io/IMPACT/httpie-pr-1327/" rel="noopener noreferrer"&gt;a larger HTTPie PR&lt;/a&gt;. It found 18 test targets that expanded to 43 cases: 34 passed, nine remote-service cases skipped, and none failed. I like the small checkout example for explaining the idea, but this one showed me what the report looks like with a lot more code.&lt;/p&gt;

&lt;p&gt;The parser is still static Python analysis. Dynamic calls and runtime imports may be missed, so a call path means &lt;em&gt;possible impact&lt;/em&gt;. I want to keep trying it on different repositories and improve the coverage where it falls short.&lt;/p&gt;

&lt;p&gt;I'm entering IMPACT in &lt;em&gt;Track 01: Agents That Act on Connected Data&lt;/em&gt; and &lt;em&gt;Track 03: Company Brain&lt;/em&gt;. The first follows the code graph to help review a change; the second adds the people and decisions connected to that code.&lt;/p&gt;

&lt;p&gt;If you review Python PRs, would seeing both the path to a suggested test and the reason behind a past decision help you? 🤔&lt;/p&gt;

&lt;p&gt;🎥 Demo: &lt;a href="https://youtu.be/mbj6c4p4VNk" rel="noopener noreferrer"&gt;https://youtu.be/mbj6c4p4VNk&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💻 Source code: &lt;a href="https://github.com/Omar8345/IMPACT" rel="noopener noreferrer"&gt;https://github.com/Omar8345/IMPACT&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>python</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
