<?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: Krishnasai Rollamadugu</title>
    <description>The latest articles on DEV Community by Krishnasai Rollamadugu (@rollamadugu).</description>
    <link>https://dev.to/rollamadugu</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%2F4195957%2Fdd718bee-5e3c-496c-995d-f562ce4cd247.png</url>
      <title>DEV Community: Krishnasai Rollamadugu</title>
      <link>https://dev.to/rollamadugu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rollamadugu"/>
    <language>en</language>
    <item>
      <title>LLM-as-judge, responsibly: a checklist before you trust an AI to grade anything</title>
      <dc:creator>Krishnasai Rollamadugu</dc:creator>
      <pubDate>Wed, 21 Oct 2026 08:33:48 +0000</pubDate>
      <link>https://dev.to/rollamadugu/llm-as-judge-responsibly-a-checklist-before-you-trust-an-ai-to-grade-anything-1k0a</link>
      <guid>https://dev.to/rollamadugu/llm-as-judge-responsibly-a-checklist-before-you-trust-an-ai-to-grade-anything-1k0a</guid>
      <description>&lt;p&gt;"LLM-as-judge" has quietly become infrastructure. We use one model to grade another's answers, to decide if a test really passed, to score RAG relevance, to moderate, to rank. It's cheap, fast, and scales to volumes no human can touch.&lt;/p&gt;

&lt;p&gt;It's also a measurement instrument — and most teams deploy it without ever checking whether the instrument is accurate. Here's a practical checklist before you let an LLM grade anything that matters. (Context: I built a small harness that runs a local LLM as a test judge and scores it against ground truth; some numbers below come from that.)&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Measure it against ground truth at least once
&lt;/h2&gt;

&lt;p&gt;You cannot manage what you haven't measured. Assemble a set of cases where you &lt;em&gt;know&lt;/em&gt; the right verdict (labelled correct/wrong) and run the judge over them. You're looking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;False-pass rate&lt;/strong&gt; — of everything it approved, how much was actually wrong? (The dangerous direction.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Miss rate&lt;/strong&gt; — of the genuinely wrong items, how many did it wave through?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False-alarm rate&lt;/strong&gt; — how often does it reject good work? (The annoying direction.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my run, a capable open model missed &lt;strong&gt;26%&lt;/strong&gt; of wrong outputs — a quarter of real failures, passed. You want &lt;em&gt;your&lt;/em&gt; number, on &lt;em&gt;your&lt;/em&gt; task, before you rely on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Check calibration, not just accuracy
&lt;/h2&gt;

&lt;p&gt;Ask the judge for a confidence, then check whether that confidence means anything. A well-calibrated judge that says "90% sure" should be right about 90% of the time. Measure &lt;strong&gt;Expected Calibration Error (ECE)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The common failure: models are &lt;strong&gt;massively overconfident.&lt;/strong&gt; Mine answered with ~100% confidence on nearly every call — including the wrong ones (ECE ≈ 0.31). If the confidence is always "very sure," it carries no signal and you can't use it to route hard cases to a human.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Pin everything and version it
&lt;/h2&gt;

&lt;p&gt;An LLM judge whose model, prompt, or temperature drifts is a ruler that changes length. Pin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the exact model (and version),&lt;/li&gt;
&lt;li&gt;the prompt template,&lt;/li&gt;
&lt;li&gt;temperature (use 0 for grading — you want determinism, not creativity).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open-weight models help here: you can pin a local model and &lt;em&gt;know&lt;/em&gt; it won't change under you. A hosted endpoint can be swapped silently.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Watch for the known biases
&lt;/h2&gt;

&lt;p&gt;LLM judges have documented, reproducible biases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Position bias&lt;/strong&gt; — prefers the first (or last) option in a pairwise comparison. Mitigate by running both orders and averaging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verbosity bias&lt;/strong&gt; — rates longer answers higher regardless of correctness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-preference&lt;/strong&gt; — a model tends to favour outputs that look like its own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leniency&lt;/strong&gt; — many judges default to "PASS" when unsure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your eval drives a leaderboard or a release decision, these biases become &lt;em&gt;your&lt;/em&gt; biases.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Never let it be the only gate
&lt;/h2&gt;

&lt;p&gt;The safe pattern isn't "judge decides, ship." It's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the judge as a &lt;strong&gt;cheap first-pass filter&lt;/strong&gt;, not the final word.&lt;/li&gt;
&lt;li&gt;Keep a &lt;strong&gt;ground-truth backstop&lt;/strong&gt; on a sample — spot-check the judge continuously, not once.&lt;/li&gt;
&lt;li&gt;Route &lt;strong&gt;low-confidence or high-stakes&lt;/strong&gt; cases to a human or a stronger check.&lt;/li&gt;
&lt;li&gt;Treat a PASS as "probably fine," not "verified."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The one-line version
&lt;/h2&gt;

&lt;p&gt;An LLM judge is a fast, cheap, biased, overconfident grader that is right often enough to be useful and wrong often enough to be dangerous. Measure it, pin it, debias it, and keep a human backstop — then it's a great tool. Trust it blindly and it will quietly approve your worst bug with total confidence.&lt;/p&gt;

&lt;p&gt;Are you using LLM-as-judge in production? What did you find when you checked it against ground truth — or have you checked yet?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Krishnasai Rollamadugu — a test automation architect researching trust and measurement in AI-driven software testing. Related: an open experiment measuring a local LLM judge — &lt;a href="https://github.com/rollamadugu/trust-judge" rel="noopener noreferrer"&gt;trust-judge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>testing</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>The oracle problem: testing's oldest unsolved question, and why AI just made it urgent</title>
      <dc:creator>Krishnasai Rollamadugu</dc:creator>
      <pubDate>Wed, 21 Oct 2026 08:33:25 +0000</pubDate>
      <link>https://dev.to/rollamadugu/the-oracle-problem-testings-oldest-unsolved-question-and-why-ai-just-made-it-urgent-320n</link>
      <guid>https://dev.to/rollamadugu/the-oracle-problem-testings-oldest-unsolved-question-and-why-ai-just-made-it-urgent-320n</guid>
      <description>&lt;p&gt;Here's a question that sounds trivial and isn't: &lt;strong&gt;when your program produces an output, how do you know it's the right one?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's the &lt;strong&gt;test oracle problem&lt;/strong&gt;, and it's one of the oldest open problems in software testing (the definitive survey is Barr, Harman, McMinn, Shahbaz &amp;amp; Yoo, IEEE TSE 2015). Every test you've ever written quietly answered it somehow — and AI testing tools are now answering it &lt;em&gt;for&lt;/em&gt; you, which is exactly why it's worth understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an "oracle" actually is
&lt;/h2&gt;

&lt;p&gt;An oracle is the mechanism that decides pass or fail. When you write:&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="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the &lt;code&gt;== 5&lt;/code&gt; is your oracle. You, the human, knew the right answer and hard-coded it. Easy.&lt;/p&gt;

&lt;p&gt;Now scale that up. What's the correct output of a route planner for a 10,000-node graph? A tax calculation across 40 interacting rules? An ML model's ranking? A PDF renderer? You often &lt;strong&gt;cannot&lt;/strong&gt; just write down the expected answer. That's the oracle problem: the hard part of testing isn't running the program, it's &lt;em&gt;knowing what correct looks like.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How we actually cope (the oracle taxonomy)
&lt;/h2&gt;

&lt;p&gt;We rarely have a perfect oracle, so we use partial ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Specified oracle&lt;/strong&gt; — a spec or reference implementation says the exact answer. Strongest, rarest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Derived oracle&lt;/strong&gt; — infer correctness from other artifacts: a previous version (regression), documentation, or a slower-but-trusted implementation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metamorphic oracle&lt;/strong&gt; — when you can't check one output, check a &lt;em&gt;relation&lt;/em&gt; between outputs. You may not know &lt;code&gt;sin(x)&lt;/code&gt;, but you know &lt;code&gt;sin(x) == sin(x + 2π)&lt;/code&gt;. Hugely useful for scientific code, ML, and anything without a ground truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implicit oracle&lt;/strong&gt; — the "obvious" failures anyone can detect without a spec: crashes, hangs, memory corruption. Cheap but weak — "it didn't crash" is a very low bar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human oracle&lt;/strong&gt; — a person eyeballs it. Expensive, unscalable, inconsistent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most real suites are a pile of implicit + specified oracles, which is why they catch crashes and the handful of cases someone thought to assert — and miss the subtle wrong-but-plausible outputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI makes this urgent
&lt;/h2&gt;

&lt;p&gt;Two shifts just collided with the oracle problem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AI writes the oracle.&lt;/strong&gt; When an LLM generates your assertions, &lt;em&gt;it&lt;/em&gt; is deciding what "correct" means — and models love weak, behaviour-echoing assertions (type checks, "no exception", loose ranges) that look like tests but barely constrain the output. A green suite full of weak oracles is the oracle problem wearing a disguise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI &lt;em&gt;is&lt;/em&gt; the oracle.&lt;/strong&gt; "LLM-as-judge" makes the model itself the pass/fail mechanism. That's an &lt;strong&gt;implicit-ish oracle with opinions&lt;/strong&gt; — convenient, scalable, and unaccountable unless you measure it. (I've measured one: a local LLM judge waved through ~1 in 4 genuinely wrong outputs while ~100% confident.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In both cases we've quietly handed the oldest hard problem in testing to a system that's fluent, fast, and frequently wrong — without noticing we did it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The practical takeaway
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name your oracle.&lt;/strong&gt; For any important test, ask: &lt;em&gt;what decides correct here, and how strong is it?&lt;/em&gt; "It returns a string" is not an oracle; it's a vibe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reach for metamorphic relations&lt;/strong&gt; when there's no ground truth — they're underused and powerful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If an AI is your oracle, treat it as an oracle under test:&lt;/strong&gt; check it against real ground truth, measure how often it's wrong, and don't trust its confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The oracle problem never went away. We just built tools that paper over it more convincingly. Knowing it's there is most of the battle.&lt;/p&gt;

&lt;p&gt;How do you solve the oracle problem on your hardest-to-verify code? Metamorphic testing? A reference implementation? I'd love to hear the approaches.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Krishnasai Rollamadugu — a test automation architect researching trust and measurement in AI-driven software testing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>ai</category>
      <category>computerscience</category>
      <category>qa</category>
    </item>
    <item>
      <title>Flaky tests aren't random: a field guide to finding and killing them</title>
      <dc:creator>Krishnasai Rollamadugu</dc:creator>
      <pubDate>Wed, 21 Oct 2026 08:31:47 +0000</pubDate>
      <link>https://dev.to/rollamadugu/flaky-tests-arent-random-a-field-guide-to-finding-and-killing-them-1bnp</link>
      <guid>https://dev.to/rollamadugu/flaky-tests-arent-random-a-field-guide-to-finding-and-killing-them-1bnp</guid>
      <description>&lt;p&gt;A flaky test is one that passes and fails on the &lt;em&gt;same code&lt;/em&gt; with no change in between. It's the most corrosive thing in a test suite — not because any single failure is scary, but because flakiness teaches your team the worst possible habit: &lt;strong&gt;ignoring red.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once "just re-run it" becomes the reflex, your suite stops being a safety net and becomes a slot machine. Here's a practical field guide to the usual culprits and how to actually kill them — built from years of chasing these in real automation suites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flakiness is never truly random
&lt;/h2&gt;

&lt;p&gt;It &lt;em&gt;feels&lt;/em&gt; random, but it almost always traces to one of a handful of non-determinisms. The job is to find which one.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Timing / async (the #1 cause in UI and integration tests)
&lt;/h3&gt;

&lt;p&gt;The test checks for something before the app is ready. It passes when the machine is fast, fails when CI is loaded.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; never sleep for a fixed time. Wait for a &lt;em&gt;condition&lt;/em&gt; — an element state, a network response, a value. Modern frameworks (Playwright, Cypress) auto-wait on assertions; lean on that instead of &lt;code&gt;sleep(2)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smell to grep for:&lt;/strong&gt; &lt;code&gt;sleep&lt;/code&gt;, &lt;code&gt;setTimeout&lt;/code&gt;, hard-coded waits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Test order dependence / shared state
&lt;/h3&gt;

&lt;p&gt;Test B passes only because Test A ran first and left data behind. Run them in a different order (or in parallel) and B falls over.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; each test sets up and tears down its own state. No reliance on execution order. Tools like &lt;code&gt;pytest-randomly&lt;/code&gt; or &lt;code&gt;iDFlakies&lt;/code&gt; surface these by shuffling order.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Shared external resources
&lt;/h3&gt;

&lt;p&gt;A real database, a shared test account, a live third-party API. Two runs collide, or the API has a bad day.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; isolate data per test (unique keys), and &lt;strong&gt;stub the network&lt;/strong&gt; at the boundary (&lt;code&gt;cy.intercept&lt;/code&gt;, WireMock, VCR). Test &lt;em&gt;your&lt;/em&gt; logic, not someone's uptime.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Time, timezones, randomness, locale
&lt;/h3&gt;

&lt;p&gt;Tests that use &lt;code&gt;now()&lt;/code&gt;, random seeds, or locale-dependent formatting fail at midnight, on a CI box in another timezone, or on the one day the random value hits an edge.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; inject the clock and the seed. Freeze time (&lt;code&gt;freezegun&lt;/code&gt;, &lt;code&gt;sinon&lt;/code&gt;), pin the seed, pin the locale.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Resource leaks and ordering in the app itself
&lt;/h3&gt;

&lt;p&gt;Sometimes the test is honest and the &lt;em&gt;code&lt;/em&gt; is flaky — an unawaited promise, a race in the app, a dictionary iteration order assumption. The test just exposed it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; this one's a gift. The flaky test found a real concurrency bug. Fix the app, not the test.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A triage process that works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Quarantine, don't ignore.&lt;/strong&gt; Move the flaky test to a separate suite that doesn't block the pipeline — but &lt;em&gt;tracks&lt;/em&gt; it. The goal is to stop the "ignore red" habit, not to hide the problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproduce deterministically.&lt;/strong&gt; Run it 50 times locally (&lt;code&gt;pytest --count=50&lt;/code&gt;, or loop it). If it never fails locally but fails in CI, the difference &lt;em&gt;is&lt;/em&gt; the clue — load, parallelism, environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bisect the cause.&lt;/strong&gt; Run it in isolation vs. with the suite (order dependence?). Disable the network (external dependency?). Freeze the clock (time?).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix the root cause, then de-quarantine.&lt;/strong&gt; And add the reason to your commit message, so the next person learns the pattern.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Measure it, don't vibe it
&lt;/h2&gt;

&lt;p&gt;Track a &lt;strong&gt;flaky rate&lt;/strong&gt; per test (failures ÷ runs over the last N runs). It turns "the suite feels flaky" into a number you can drive down, and it tells you &lt;em&gt;which&lt;/em&gt; tests to fix first. A test that's failed 8% of the last 200 runs is a priority; one that failed once six weeks ago is noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mindset
&lt;/h2&gt;

&lt;p&gt;Every flaky test is a small lie your suite tells. The fix isn't more retries — retries just make the lie quieter. The fix is removing the non-determinism, one category at a time, until green means green again.&lt;/p&gt;

&lt;p&gt;What's the flakiest test you've ever had to hunt down — and what turned out to be the cause? I collect these war stories.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Krishnasai Rollamadugu — a test automation architect who writes about test reliability and trust in AI-driven testing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>qa</category>
      <category>automation</category>
      <category>devops</category>
    </item>
    <item>
      <title>Mutation testing in 5 minutes: catch the tests that secretly test nothing</title>
      <dc:creator>Krishnasai Rollamadugu</dc:creator>
      <pubDate>Wed, 21 Oct 2026 08:20:45 +0000</pubDate>
      <link>https://dev.to/rollamadugu/mutation-testing-in-5-minutes-catch-the-tests-that-secretly-test-nothing-2o67</link>
      <guid>https://dev.to/rollamadugu/mutation-testing-in-5-minutes-catch-the-tests-that-secretly-test-nothing-2o67</guid>
      <description>&lt;p&gt;Your test suite is green. 100% passing. Maybe even 90% coverage.&lt;/p&gt;

&lt;p&gt;Here's the uncomfortable question: if someone introduced a real bug right now, would your tests actually go red?&lt;/p&gt;

&lt;p&gt;Coverage can't answer that — it only tells you a line &lt;em&gt;ran&lt;/em&gt;, not that anything &lt;em&gt;checked&lt;/em&gt; the result. A test can execute every line and assert nothing meaningful. It'll be green forever, including when the code is broken.&lt;/p&gt;

&lt;p&gt;The technique that &lt;em&gt;does&lt;/em&gt; answer it is &lt;strong&gt;mutation testing&lt;/strong&gt;, and you can try it on your own code in about five minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea in one sentence
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Change the code to introduce a bug on purpose, run your tests, and see if they catch it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each small deliberate change is a "mutant" — flip a &lt;code&gt;+&lt;/code&gt; to a &lt;code&gt;-&lt;/code&gt;, a &lt;code&gt;&amp;gt;&lt;/code&gt; to a &lt;code&gt;&amp;lt;&lt;/code&gt;, a &lt;code&gt;True&lt;/code&gt; to a &lt;code&gt;False&lt;/code&gt;. For every mutant you run your suite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tests &lt;strong&gt;fail&lt;/strong&gt; → the mutant is &lt;em&gt;killed&lt;/em&gt; → good, your tests caught the bug.&lt;/li&gt;
&lt;li&gt;tests still &lt;strong&gt;pass&lt;/strong&gt; → the mutant &lt;em&gt;survived&lt;/em&gt; → a blind spot. Your tests didn't notice the code changed behaviour.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your &lt;strong&gt;mutation score&lt;/strong&gt; = killed / total. It's an honest measure of fault-detection, not just execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in 5 minutes
&lt;/h2&gt;

&lt;p&gt;I'll use a tiny open-source tool I built, &lt;a href="https://github.com/rollamadugu/trust-gate" rel="noopener noreferrer"&gt;&lt;strong&gt;trust-gate&lt;/strong&gt;&lt;/a&gt; — zero dependencies, works with any test runner. (If you're on the JVM or JS, use &lt;a href="https://pitest.org/" rel="noopener noreferrer"&gt;PIT&lt;/a&gt; or &lt;a href="https://stryker-mutator.io/" rel="noopener noreferrer"&gt;Stryker&lt;/a&gt; instead — same idea.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rollamadugu/trust-gate
&lt;span class="nb"&gt;cd &lt;/span&gt;trust-gate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;".[dev]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The repo ships a tiny &lt;code&gt;pricing.py&lt;/code&gt; with a &lt;strong&gt;weak&lt;/strong&gt; test suite and a &lt;strong&gt;strong&lt;/strong&gt; one. Both are 100% green. Watch what mutation testing says about each.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weak suite&lt;/strong&gt; — it runs the code but barely checks the values:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;trust-gate examples/pricing.py &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"pytest examples/test_pricing_weak.py -q"&lt;/span&gt; &lt;span class="nt"&gt;--cwd&lt;/span&gt; examples
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutants         : 7
caught (killed) : 0
survived        : 7
mutation score  : 0.00%
gate: FAIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Zero. Every injected bug slipped through while the suite stayed green.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strong suite&lt;/strong&gt; — same code, same "all passing", but it checks real values across branches:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;trust-gate examples/pricing.py &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"pytest examples/test_pricing_strong.py -q"&lt;/span&gt; &lt;span class="nt"&gt;--cwd&lt;/span&gt; examples
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutants         : 7
caught (killed) : 7
survived        : 0
mutation score  : 100.00%
gate: PASS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F6h755v5o13ysjjmzwmzo.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%2F6h755v5o13ysjjmzwmzo.png" alt="Same code, both green, only one would catch a bug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same green checkmark on your dashboard. Completely different safety nets.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reading the result
&lt;/h2&gt;

&lt;p&gt;The useful part isn't the score — it's the &lt;strong&gt;surviving mutants&lt;/strong&gt;. trust-gate prints each one with a line number and what it changed:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SURVIVED  line 9: Gt -&amp;gt; Lt
SURVIVED  line 11: 2 -&amp;gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each survivor is a precise to-do: &lt;em&gt;"nothing you wrote would notice if line 9's comparison flipped."&lt;/em&gt; That points you straight at the assertion you're missing — far more actionable than a coverage percentage.&lt;/p&gt;
&lt;h2&gt;
  
  
  Make it a CI gate
&lt;/h2&gt;

&lt;p&gt;Because trust-gate exits non-zero when the score is below a threshold, you can fail the build when test strength drops:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pip install trust-gate&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trust-gate src/your_module.py -c "pytest -q" --min-score &lt;/span&gt;&lt;span class="m"&gt;0.75&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now "green" means &lt;em&gt;"and the tests would actually catch a bug,"&lt;/em&gt; not just "ran without error."&lt;/p&gt;
&lt;h2&gt;
  
  
  Caveats (so you use it well)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Equivalent mutants&lt;/strong&gt;: some changes don't alter behaviour, so they can't be killed. Don't chase 100%; chase &lt;em&gt;understanding your survivors&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: mutation testing re-runs your suite many times. Start on one important module, not the whole repo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It grades the tests, not the code.&lt;/strong&gt; A surviving mutant means your &lt;em&gt;tests&lt;/em&gt; have a gap — exactly what you want to know.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Coverage tells you what ran. Mutation testing tells you what your tests would actually &lt;em&gt;catch&lt;/em&gt;. Point it at your most important module today and look at the survivors — it's usually a humbling five minutes, in the best way.&lt;/p&gt;

&lt;p&gt;Tool used: &lt;a href="https://github.com/rollamadugu/trust-gate" rel="noopener noreferrer"&gt;trust-gate&lt;/a&gt; (MIT, open source). Feedback and PRs welcome.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rollamadugu" rel="noopener noreferrer"&gt;
        rollamadugu
      &lt;/a&gt; / &lt;a href="https://github.com/rollamadugu/trust-gate" rel="noopener noreferrer"&gt;
        trust-gate
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Mutation-based test-strength gate: fail CI when your passing tests are too weak to catch real bugs. Zero dependencies, any test runner.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;trust-gate&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/e801a66299d2c15286fe0fee660d9ffa666c1c5576e5e1536acc07b49ce8ac8f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31302532422d626c7565"&gt;&lt;img src="https://camo.githubusercontent.com/e801a66299d2c15286fe0fee660d9ffa666c1c5576e5e1536acc07b49ce8ac8f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31302532422d626c7565" alt="Python"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/5864b8e0bc8eaf07b1f738081979edde099027dce508c2b2c87c84d56227805d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d7374616e646172642d2d6c6962726172792d73756363657373"&gt;&lt;img src="https://camo.githubusercontent.com/5864b8e0bc8eaf07b1f738081979edde099027dce508c2b2c87c84d56227805d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d7374616e646172642d2d6c6962726172792d73756363657373" alt="Dependencies"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e"&gt;&lt;img src="https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Your tests are green. But are they strong enough to catch a real bug?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;trust-gate&lt;/code&gt; injects small faults (mutants) into your code, runs your test
command for each one, and measures how many faults your &lt;strong&gt;passing&lt;/strong&gt; tests
actually catch. Green tests that miss injected faults are weak tests —
&lt;code&gt;trust-gate&lt;/code&gt; makes that measurable and lets you &lt;strong&gt;fail CI&lt;/strong&gt; when test strength
drops below a threshold.&lt;/p&gt;
&lt;p&gt;It's a focused, zero-dependency mutation-testing gate. Pure Python standard
library. Works with any test runner (pytest, unittest, a shell script — anything
that exits non-zero on failure).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Part of a broader line of work on &lt;strong&gt;trust in AI-driven testing&lt;/strong&gt;
(&lt;a href="https://github.com/rollamadugu/trustlab" rel="noopener noreferrer"&gt;TrustLab&lt;/a&gt;). As AI writes more of our
tests, "it passed" needs to mean "it would have caught the bug." This gate
checks exactly that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Install&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pip install trust-gate        &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; from PyPI (coming soon)&lt;/span&gt;
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or, from source:&lt;/span&gt;
pip install -e &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;.[dev]&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rollamadugu/trust-gate" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;&lt;em&gt;I'm Krishnasai Rollamadugu — a test automation architect researching trust and measurement in AI-driven software testing. If weak-but-green tests are your kind of problem, I write about this a lot.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>python</category>
      <category>qa</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The lazy dream is an AI that judges your tests. I measured what it costs</title>
      <dc:creator>Krishnasai Rollamadugu</dc:creator>
      <pubDate>Wed, 21 Oct 2026 07:52:40 +0000</pubDate>
      <link>https://dev.to/rollamadugu/the-lazy-dream-is-an-ai-that-judges-your-tests-i-measured-what-it-costs-1g11</link>
      <guid>https://dev.to/rollamadugu/the-lazy-dream-is-an-ai-that-judges-your-tests-i-measured-what-it-costs-1g11</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;The laziest dream in software testing goes like this: stop checking your tests yourself — just let an AI read the output and tell you PASS or FAIL. The effort it promises to save is the most tedious part of QA: &lt;em&gt;deciding whether a result is actually correct.&lt;/em&gt; The person who gets to be lazier is every tester who'd rather not eyeball one more assertion.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;&lt;a href="https://github.com/rollamadugu/trust-judge" rel="noopener noreferrer"&gt;trust-judge&lt;/a&gt;&lt;/strong&gt; to take that lazy dream seriously and &lt;strong&gt;measure what it actually costs.&lt;/strong&gt; It runs a local, open-weight LLM (Llama 3.1 8B via Ollama) as a test "judge" and scores how often you can believe its verdict — against objective ground truth the model never sees.&lt;/p&gt;

&lt;p&gt;The theme is "Slow and Steady," and that became the finding, not just the vibe: the lazy shortcut (trust the fast AI green and move on) quietly misses real bugs. The slow, steady habit — measure it, keep a ground-truth check — is what actually works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;A local Llama 3.1 8B judged 81 test outcomes (correct vs. buggy), scored against a reference implementation it never saw:&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%2Fpc9y71as9w4q82v1srd1.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%2Fpc9y71as9w4q82v1srd1.png" alt="Can you trust a local LLM to judge your tests?" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accuracy 69%&lt;/strong&gt; — wrong about 1 in 3 times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Miss rate 26%&lt;/strong&gt; — it waved through a quarter of genuinely wrong outputs as PASS. Silent false passes: dashboard green, bug shipped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False-pass rate 10.6%&lt;/strong&gt; (95% CI 4.6–22.6%).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calibration ECE 0.31&lt;/strong&gt; — it answered with confidence ≈ 1.00 almost every time, &lt;em&gt;even when wrong.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It fails exactly where it matters — arithmetic and inclusive boundaries:&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%2Frkonrm8476c35t0p5clr.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%2Frkonrm8476c35t0p5clr.png" alt="Judge accuracy by task" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;discount&lt;/code&gt; (rounding) collapses to 40% accuracy with 80% of wrong answers missed; on &lt;code&gt;letter_grade&lt;/code&gt; it decided a score of exactly 60 was an "F" — failing the correct "D" and passing the wrong "F".&lt;/p&gt;

&lt;p&gt;Run it yourself in ~5 minutes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama serve &amp;amp;
ollama pull llama3.1:8b
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;".[dev]"&lt;/span&gt;
trust-judge &lt;span class="nt"&gt;--model&lt;/span&gt; llama3.1:8b &lt;span class="nt"&gt;-o&lt;/span&gt; results/run.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rollamadugu" rel="noopener noreferrer"&gt;
        rollamadugu
      &lt;/a&gt; / &lt;a href="https://github.com/rollamadugu/trust-judge" rel="noopener noreferrer"&gt;
        trust-judge
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Measure how much you can trust a local open-weight LLM (Ollama) acting as a software test oracle (LLM-as-judge), against objective ground truth. Built for the DEV Hacktoberfest 2026 open-source AI challenge.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;trust-judge&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/e801a66299d2c15286fe0fee660d9ffa666c1c5576e5e1536acc07b49ce8ac8f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31302532422d626c7565"&gt;&lt;img src="https://camo.githubusercontent.com/e801a66299d2c15286fe0fee660d9ffa666c1c5576e5e1536acc07b49ce8ac8f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31302532422d626c7565" alt="Python"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/5864b8e0bc8eaf07b1f738081979edde099027dce508c2b2c87c84d56227805d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d7374616e646172642d2d6c6962726172792d73756363657373"&gt;&lt;img src="https://camo.githubusercontent.com/5864b8e0bc8eaf07b1f738081979edde099027dce508c2b2c87c84d56227805d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d7374616e646172642d2d6c6962726172792d73756363657373" alt="Dependencies"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/ea9e0612888eb3eec4bcdb219fae6ab275638d36d37e06d3e2442a9aa37fb1a5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c4c4d2d6c6f63616c2532306f70656e2d2d776569676874253230284f6c6c616d61292d366161383466"&gt;&lt;img src="https://camo.githubusercontent.com/ea9e0612888eb3eec4bcdb219fae6ab275638d36d37e06d3e2442a9aa37fb1a5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c4c4d2d6c6f63616c2532306f70656e2d2d776569676874253230284f6c6c616d61292d366161383466" alt="LLM"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e"&gt;&lt;img src="https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"LLM-as-judge" is everywhere now. But can you trust the judge?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;trust-judge&lt;/code&gt; points a &lt;strong&gt;local, open-weight LLM&lt;/strong&gt; (Llama 3.1 8B via &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt;
running entirely on your machine) at software test outcomes and measures how
often you can believe its verdict — against &lt;strong&gt;objective ground truth&lt;/strong&gt; (a
reference implementation). No cloud, no API key, no data leaving your laptop.&lt;/p&gt;
&lt;p&gt;Built for the DEV Hacktoberfest 2026 "open-source AI" challenge: an &lt;strong&gt;open-weight
model running locally&lt;/strong&gt; is the engine, and that openness is exactly what makes a
&lt;em&gt;trust&lt;/em&gt; study like this possible — you can inspect it, pin it, and reproduce it
for free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The result (Llama 3.1 8B, 81 labelled cases)&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/rollamadugu/trust-judge/assets/headline.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Frollamadugu%2Ftrust-judge%2FHEAD%2Fassets%2Fheadline.png" alt="Can you trust a local LLM to judge your tests?"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accuracy 69%&lt;/strong&gt; — the judge is wrong about &lt;strong&gt;1 in 3&lt;/strong&gt; times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Miss rate 26%&lt;/strong&gt; — it waved through &lt;strong&gt;a quarter of genuinely wrong outputs&lt;/strong&gt; as PASS. Those are silent false passes: the dashboard stays green, the bug ships.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False-pass rate&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rollamadugu/trust-judge" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Open-weight model, 100% local, pure standard library (plus pytest):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subjects&lt;/strong&gt; — small functions with a plain-English spec, a correct reference implementation, and a realistic buggy variant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cases&lt;/strong&gt; — for each input, a &lt;em&gt;correct&lt;/em&gt; case (reference output) and a &lt;em&gt;wrong&lt;/em&gt; case (buggy output when it differs). Truth is objective: correct ⟺ output equals the reference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The judge&lt;/strong&gt; sees only spec + call + returned value — never the reference — and must answer PASS/FAIL with a confidence, through the &lt;strong&gt;local Ollama API&lt;/strong&gt; (stdlib &lt;code&gt;urllib&lt;/code&gt;, no SDK).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt; — false-pass rate (+ Wilson CI), miss rate, false-alarm rate, accuracy, confidence ROC-AUC vs. a naive baseline, and Expected Calibration Error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The test suite (12 tests) is self-contained and never calls the model, so CI stays green without a GPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;A study about &lt;em&gt;trust&lt;/em&gt; only works if the thing you're studying is open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No internet, no API key&lt;/strong&gt; — the model runs on my laptop. Nothing leaves the machine, which matters when the "outputs" under test could be real, sensitive code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducible for free, forever&lt;/strong&gt; — anyone can &lt;code&gt;ollama pull llama3.1:8b&lt;/code&gt; and get the exact setup. No vendor can silently swap the model under my results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable&lt;/strong&gt; — change one flag (&lt;code&gt;--model qwen2.5:7b&lt;/code&gt;) and re-run. Open weights turn "trust the AI" from faith into an experiment you can rerun and challenge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You cannot do an honest, reproducible trust study on a black box you rent by the token. Open models are what let &lt;em&gt;you&lt;/em&gt; check my numbers instead of taking my word.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;Here's the honest version of the payoff, because the whole project is a test of it.&lt;/p&gt;

&lt;p&gt;Does an LLM judge save effort? Yes — it does the tedious "is this output right?" check for you, instantly, at zero marginal cost. That's the sloth dream.&lt;/p&gt;

&lt;p&gt;But the bill comes due quietly: it let &lt;strong&gt;26% of real bugs through&lt;/strong&gt; and was &lt;strong&gt;~100% confident while doing it.&lt;/strong&gt; So the fully-lazy move — fire the judge into your pipeline and stop checking — doesn't actually save you; it just moves the cost to the bug that ships.&lt;/p&gt;

&lt;p&gt;The payoff that &lt;em&gt;survives&lt;/em&gt; contact with the data is the slow-and-steady one: use the judge as a cheap &lt;strong&gt;first-pass filter&lt;/strong&gt;, keep a ground-truth backstop, and distrust its confidence. That genuinely saves time &lt;em&gt;and&lt;/em&gt; stays honest. Lazy where you can afford it; steady where it counts.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built by Krishnasai Rollamadugu — Test Automation Architect researching trust in AI-driven software testing. Related: &lt;a href="https://github.com/rollamadugu/trustlab" rel="noopener noreferrer"&gt;TrustLab&lt;/a&gt; · &lt;a href="https://github.com/rollamadugu/awesome-ai-software-testing" rel="noopener noreferrer"&gt;awesome-ai-software-testing&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Can you trust a green test written by AI? I measured it.</title>
      <dc:creator>Krishnasai Rollamadugu</dc:creator>
      <pubDate>Tue, 20 Oct 2026 10:41:06 +0000</pubDate>
      <link>https://dev.to/rollamadugu/can-you-trust-a-green-test-written-by-ai-i-measured-it-2bk6</link>
      <guid>https://dev.to/rollamadugu/can-you-trust-a-green-test-written-by-ai-i-measured-it-2bk6</guid>
      <description>&lt;p&gt;I've spent eleven years building test automation for enterprise systems. The whole job rests on one quiet assumption: &lt;strong&gt;a passing test is evidence.&lt;/strong&gt; Green means safe. We ship on green.&lt;/p&gt;

&lt;p&gt;Lately that assumption has been getting shakier, because more and more of the test itself is being produced by AI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI &lt;strong&gt;generates&lt;/strong&gt; the test oracle (the assertion that decides pass/fail).&lt;/li&gt;
&lt;li&gt;AI &lt;strong&gt;heals&lt;/strong&gt; broken UI locators when the page changes (self-healing frameworks).&lt;/li&gt;
&lt;li&gt;AI &lt;strong&gt;adjudicates&lt;/strong&gt; whether a run actually passed or was "just flaky" (LLM-as-judge).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these can hand you a &lt;strong&gt;GREEN&lt;/strong&gt; result that isn't actually sound:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An AI-written assertion can be too weak to catch a real bug — it checks the type but not the value, so the test passes even when the output is wrong.&lt;/li&gt;
&lt;li&gt;A self-healing locator can "repair" itself onto the &lt;strong&gt;wrong&lt;/strong&gt; element and sail through, silently testing nothing.&lt;/li&gt;
&lt;li&gt;An LLM judge can wave a genuine failure through as a flake.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all three cases the dashboard stays green while the safety net quietly grows holes. I wanted to stop hand-waving about this and actually &lt;strong&gt;measure&lt;/strong&gt; it. So I built a small, open research prototype called &lt;strong&gt;TrustLab&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: the False-Confidence Gap
&lt;/h2&gt;

&lt;p&gt;The core concept is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;False-Confidence Gap&lt;/strong&gt; = how often tests &lt;em&gt;appear&lt;/em&gt; to pass − how often they are &lt;em&gt;actually&lt;/em&gt; sound.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To measure it honestly you need ground truth for "sound." I use &lt;strong&gt;mutation testing&lt;/strong&gt;: an engine injects real faults into a program (flip a &lt;code&gt;+&lt;/code&gt; to a &lt;code&gt;-&lt;/code&gt;, a &lt;code&gt;&amp;lt;&lt;/code&gt; to a &lt;code&gt;&amp;lt;=&lt;/code&gt;, and so on), and a verdict only counts as sound if it actually &lt;strong&gt;catches&lt;/strong&gt; those faults. No opinions, no self-report — a test either kills the mutant or it doesn't.&lt;/p&gt;

&lt;p&gt;I ran this across the three modalities above, on a set of small subject programs, repeated over 15 random seeds with held-out evaluation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What came out
&lt;/h2&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%2Fnz34841zz5nmxqa33izz.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%2Fnz34841zz5nmxqa33izz.png" alt="False-Confidence Gap by AI testing modality" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI-generated oracles: ~62% gap.&lt;/strong&gt; This is the scary one. A huge share of "passing" came from assertions that don't actually catch injected faults.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM-as-judge: ~41% gap.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI self-healing: ~11% gap&lt;/strong&gt; — lower, but with silent mis-heals hiding in the tail (the worst kind, because nothing looks wrong).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A detail I didn't expect: for AI-generated oracles, the danger tracks &lt;strong&gt;code structure.&lt;/strong&gt; Branch-heavy logic like a grading function (99.7% gap) or a triangle classifier (93.6%) was far more dangerous than a simple BMI bucket (5.2%). The more branches your code has, the more room a weak AI oracle has to look green while missing faults.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can we do anything about it?
&lt;/h2&gt;

&lt;p&gt;Measuring the problem is only half of it. The other half: can we &lt;strong&gt;predict&lt;/strong&gt; which green verdicts to believe, using only signals we can actually observe at runtime (not the ground truth, which in real life we don't have)?&lt;/p&gt;

&lt;p&gt;I trained a small, calibrated &lt;strong&gt;trust metric&lt;/strong&gt; on observable features and compared it to the naive policy everyone uses today — "it's green, trust it."&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%2Ft2ip0d77u1psy1lx9rel.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%2Ft2ip0d77u1psy1lx9rel.png" alt="False-pass rate: naive vs trust-gated" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you keep the 70% most-trusted green verdicts and set aside the least-trusted 30%, the silent false-pass rate drops hard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-healing: &lt;strong&gt;11% → 0.5%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;LLM-judge: &lt;strong&gt;40% → 19%&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The naive "trust any green" baseline can't separate sound from unsound at all (ROC-AUC 0.50 by construction). The trust metric reaches ROC-AUC up to ~0.95, with calibration (Expected Calibration Error) reported so the scores actually mean something. Effect sizes are "large" (Vargha–Delaney A12 0.76–0.95), Mann–Whitney p &amp;lt; 0.001.&lt;/p&gt;

&lt;h2&gt;
  
  
  Being honest about what's real
&lt;/h2&gt;

&lt;p&gt;I think credibility matters more than hype, so I'm explicit about this in the repo too:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;oracle&lt;/strong&gt; results are &lt;em&gt;real&lt;/em&gt;: a genuine AST mutation engine injects faults, and runtime coverage decides whether a verdict is sound.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;self-healing&lt;/strong&gt; and &lt;strong&gt;adjudication&lt;/strong&gt; results are &lt;strong&gt;empirically-shaped models&lt;/strong&gt; of documented tool and LLM behaviour, placed behind an adapter interface. That means you can drop a &lt;strong&gt;real&lt;/strong&gt; Playwright self-healer or a &lt;strong&gt;real&lt;/strong&gt; LLM judge into the same seam and re-run the exact experiments without touching the metric. (That's literally one of the open issues on the repo — contributions welcome.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd rather you know exactly where the solid ground is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters for the rest of us
&lt;/h2&gt;

&lt;p&gt;If your pipeline uses AI to generate assertions, heal locators, or judge flakiness, "green" is no longer self-evidently trustworthy. Two practical takeaways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Weak oracles are the biggest risk&lt;/strong&gt;, and they're worst exactly where your code is most complex. AI-generated assertions deserve review in proportion to branch complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A trust score beats a raw green/red.&lt;/strong&gt; Even a simple calibrated metric over observable signals can tell you &lt;em&gt;which&lt;/em&gt; passes to re-examine — turning a binary into a prioritised queue.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try it / break it
&lt;/h2&gt;

&lt;p&gt;Everything is open and reproducible — pure Python standard library core, 19 passing tests, the benchmark dataset, and the experiment outputs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 github.com/rollamadugu/trustlab&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd genuinely value feedback from people who build test oracles, self-healing frameworks, or LLM-evaluation pipelines — especially if you can poke holes in the methodology. There are a couple of "good first issues" open if you want to plug in a real tool. A fuller write-up (preprint) is in preparation.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Krishnasai Rollamadugu, a test automation architect (11+ years) researching trust and measurement in AI-driven software testing. If this resonates, follow along — this is the first step of a longer research direction.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>llm</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
