<?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: 张振</title>
    <description>The latest articles on DEV Community by 张振 (@angelalexzhangt).</description>
    <link>https://dev.to/angelalexzhangt</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3963715%2Fae618621-012a-4e9b-9324-43d8f0d350a7.png</url>
      <title>DEV Community: 张振</title>
      <link>https://dev.to/angelalexzhangt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/angelalexzhangt"/>
    <language>en</language>
    <item>
      <title>I stopped letting AI review its own code</title>
      <dc:creator>张振</dc:creator>
      <pubDate>Thu, 04 Jun 2026 02:45:39 +0000</pubDate>
      <link>https://dev.to/angelalexzhangt/i-stopped-letting-ai-review-its-own-code-5c56</link>
      <guid>https://dev.to/angelalexzhangt/i-stopped-letting-ai-review-its-own-code-5c56</guid>
      <description>&lt;h2&gt;
  
  
  The blind spot problem
&lt;/h2&gt;

&lt;p&gt;I had Claude add input validation to an API endpoint. It wrote clean, idiomatic TypeScript. I asked it to review the diff. It approved it. Tests passed. I shipped it.&lt;/p&gt;

&lt;p&gt;Two days later a colleague pointed out that the validation silently accepted empty strings — which the original spec explicitly prohibited. Claude had written the validator, approved it, and neither caught the gap.&lt;/p&gt;

&lt;p&gt;When I went back and asked Claude &lt;em&gt;why&lt;/em&gt; it missed it, the answer was essentially: "I interpreted the requirement as non-null rather than non-empty, which is a reasonable reading."&lt;/p&gt;

&lt;p&gt;That's exactly the problem. A model that wrote subtly wrong code doesn't just fail to catch the bug — it &lt;em&gt;actively defends&lt;/em&gt; its interpretation. It doesn't have independent judgment about its own output. It has motivated reasoning.&lt;/p&gt;

&lt;p&gt;Human code review works because reviewers bring different priors. A senior engineer who didn't write the code asks different questions than the person who did. They notice different things. They haven't already committed to an interpretation.&lt;/p&gt;

&lt;p&gt;The same principle applies to LLMs. The model that wrote your function and the model that reviews it shouldn't share weights.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I tried first
&lt;/h2&gt;

&lt;p&gt;The obvious fix is to use a second model for review. Have Claude write, have GPT-5 or Codex review.&lt;/p&gt;

&lt;p&gt;This helps. It's not a complete solution.&lt;/p&gt;

&lt;p&gt;The problem is that most orchestration setups run these models sequentially on the same output. Claude produces a diff. You pipe that diff to Codex and ask it to review. Codex can catch logical errors that Claude missed.&lt;/p&gt;

&lt;p&gt;But now you have a different problem: Codex is reviewing someone else's implementation choices. It might flag valid decisions as bugs, or miss problems that are specific to how Claude structured the code. You end up with noisy reviews and unclear signal about which model actually produces better output for &lt;em&gt;your&lt;/em&gt; use case.&lt;/p&gt;

&lt;p&gt;I wanted something different. I wanted to know: &lt;strong&gt;for this specific task, in this specific codebase, which model writes better code?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Racing instead of reviewing
&lt;/h2&gt;

&lt;p&gt;The answer I landed on was running both models on the same task simultaneously.&lt;/p&gt;

&lt;p&gt;Give Claude Code and Codex the identical prompt. Let them each produce a full implementation in parallel, isolated git worktrees so they can't interfere with each other. Then compare the two outputs side by side and pick.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;npx runoff run &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="go"&gt;    --prompt "Add formatRelativeTime() to src/utils/format.ts" \
    --config pipeline.config.json

Running race: claude-code vs opencode/DeepSeek...

  candidate 0  (claude-code)      +27 lines
    formatRelativeTime(isoString: string)
    handles: seconds, minutes, hours, days
    no future date support

  candidate 1  (opencode/DeepSeek) +60 lines
    formatRelativeTime(dateInput: string | Date)
    handles: seconds, minutes, hours, days, weeks
    future dates ("2 hours from now")
    edge cases: null, invalid date, DST boundary

Pipeline paused — awaiting judge decision.

&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;npx runoff race apply &lt;span class="nt"&gt;--session&lt;/span&gt; abc123 &lt;span class="nt"&gt;--winner&lt;/span&gt; 1
&lt;span class="go"&gt;✓ Merged candidate 1. Worktree 0 cleaned up.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The race pause is intentional. I don't want the system to automatically pick a winner. The whole point is that &lt;em&gt;I&lt;/em&gt; decide, because I know what matters for my codebase. Does the function need to handle &lt;code&gt;Date&lt;/code&gt; objects? Is future-date support worth the extra complexity? Only I know.&lt;/p&gt;

&lt;p&gt;This is the key insight: &lt;strong&gt;the race is not trying to determine which model is objectively better. It's trying to surface the trade-offs so a human can make an informed decision.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I learned from running 50+ races
&lt;/h2&gt;

&lt;p&gt;After a few weeks of this workflow, some patterns emerged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model strengths are task-specific and codebase-specific.&lt;/strong&gt; In my TypeScript API codebase, Claude Code consistently produces more idiomatic code that matches my existing style. But for Go utility functions and data processing scripts, Codex/DeepSeek tends to produce more comprehensive implementations that handle more edge cases. Neither is universally better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The races that surprised me most were the most valuable.&lt;/strong&gt; When I expected Claude to win and Codex produced a clearly superior implementation, that was information I wouldn't have gotten from a single-model workflow. And vice versa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt phrasing interacts with model strengths in unexpected ways.&lt;/strong&gt; "Add validation" produces very different relative results from "Add validation to reject empty strings, null, and strings over 255 characters." The same models, different specs, different winner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Over time, I started to predict which model would win on which type of task.&lt;/strong&gt; That meta-knowledge is now more valuable to me than any individual race outcome.&lt;/p&gt;




&lt;h2&gt;
  
  
  The memory angle
&lt;/h2&gt;

&lt;p&gt;The pattern I noticed — "Codex tends to be more thorough on utility functions, Claude tends to match my style better on API handlers" — is the kind of thing I wanted the system to learn and use.&lt;/p&gt;

&lt;p&gt;That's what the Dream system in runoff does. Every race you run produces a trace. When you pick a winner, the system records which provider won, what kind of task it was, which files were involved. Over time it builds a pattern library from your actual picks.&lt;/p&gt;

&lt;p&gt;When you start a new race, runoff retrieves relevant past patterns: "In similar utility function tasks involving &lt;code&gt;src/utils/&lt;/code&gt;, you've picked Codex 7 out of 9 times." That doesn't determine the race outcome — you still see both diffs and decide — but it gives you context from your own history.&lt;/p&gt;

&lt;p&gt;The retrieval uses a multi-strategy approach (semantic similarity, keyword matching, file-path graph hops, entity matching) fused with a weighted ranking that the system tunes based on which patterns actually correlated with your picks. After enough races, the system knows which retrieval strategy works best for your codebase.&lt;/p&gt;

&lt;p&gt;It's a slow accumulation. After 10 races you have weak signal. After 50 you have something useful. After 100 you have a surprisingly good model of your own taste.&lt;/p&gt;




&lt;h2&gt;
  
  
  How this compares to other approaches
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;vs. single-model review:&lt;/strong&gt; The fundamental limitation is the shared-weights problem. A model reviewing its own code has motivated reasoning. Racing gives you genuinely independent assessments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vs. Vibe Kanban / parallel agent dashboards:&lt;/strong&gt; These tools run different agents on different tasks in parallel to increase throughput. That's a different problem — scale and speed. runoff runs different agents on the &lt;em&gt;same&lt;/em&gt; task to improve quality. The goals are orthogonal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vs. Cadence's role-split approach:&lt;/strong&gt; Cadence uses different models for different SDLC phases: Claude writes, Codex reviews, Gemini sits on the architectural council. This is smart — it breaks the shared-weights problem at the phase level. The difference is that runoff compares &lt;em&gt;outputs&lt;/em&gt; from the same phase rather than &lt;em&gt;roles&lt;/em&gt; in different phases. You learn which model produces better first-pass implementations for your specific task types, not just which model is better at review in general.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vs. manually running both models:&lt;/strong&gt; You can absolutely do this by hand — open Claude Code in one terminal, Codex in another, give them the same prompt, compare the diffs yourself. runoff automates the isolation (separate worktrees, no cross-contamination), the parallel execution, the diff surfacing, the trace logging, and the pattern accumulation. The workflow is the same; the overhead is much lower.&lt;/p&gt;




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

&lt;p&gt;runoff works as an MCP server, so it integrates with Claude Code, Cursor, and Claude Desktop without leaving your IDE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"runoff"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"runoff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/path/to/your/project"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A race config is just an array in your pipeline JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pipeline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"implement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"claude-code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"opencode"&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"review"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"claude-code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"implement"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;[["claude-code", "opencode"]]&lt;/code&gt; syntax means "run both in parallel and pause for a judge decision." A single string would run that provider sequentially. The pipeline continues after you pick.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I don't know yet
&lt;/h2&gt;

&lt;p&gt;A few open questions I'm still working through:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the accumulated pattern memory actually help?&lt;/strong&gt; Anecdotally yes — I've noticed that retrieval surfaces relevant context when I start a new race. But I haven't run a controlled experiment comparing race outcomes with and without pattern retrieval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the right race cadence?&lt;/strong&gt; I don't race every task — that would double my token spend and slow things down. I race tasks where I have genuine uncertainty about the implementation approach, or where I've been burned by a model's blind spots before. Finding the right selection criteria is still intuition more than system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does this work at team scale?&lt;/strong&gt; The current setup is single-user. Pattern memory is per-machine. I haven't thought through what it would look like to share race history across a team, or whether team patterns would be useful or just noisy.&lt;/p&gt;




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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx runoff init &lt;span class="nt"&gt;--work-dir&lt;/span&gt; /path/to/your/repo
npx runoff run &lt;span class="nt"&gt;--prompt&lt;/span&gt; &lt;span class="s2"&gt;"your task here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;init&lt;/code&gt; command generates a &lt;code&gt;pipeline.config.json&lt;/code&gt; for your repo. The demo mode (&lt;code&gt;npm run demo&lt;/code&gt;) runs with mock providers if you want to see the race mechanics before connecting real backends.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://github.com/alexangelzhang/runoff" rel="noopener noreferrer"&gt;github.com/alexangelzhang/runoff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've built something similar or have a different take on the shared-weights problem, I'd be interested to hear it.&lt;/p&gt;

&lt;p&gt;Tags:ai, programming, productivity, claude&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>llm</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Qualix: semantic coverage gates for AI-generated code</title>
      <dc:creator>张振</dc:creator>
      <pubDate>Tue, 02 Jun 2026 11:13:51 +0000</pubDate>
      <link>https://dev.to/angelalexzhangt/qualix-semantic-coverage-gates-for-ai-generated-code-557g</link>
      <guid>https://dev.to/angelalexzhangt/qualix-semantic-coverage-gates-for-ai-generated-code-557g</guid>
      <description>&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%2Fraw.githubusercontent.com%2Falexangelzhang%2Fqualix%2Fmain%2Fdocs%2Fassets%2Fdemo.gif" 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%2Fraw.githubusercontent.com%2Falexangelzhang%2Fqualix%2Fmain%2Fdocs%2Fassets%2Fdemo.gif" alt="Qualix demo — tests pass but 500 USD boundary is missing" width="600" height="260"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/wtI07KJYXRI"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;AI coding agents write tests. The tests pass. Coverage is green. And then the bug ships.&lt;/p&gt;

&lt;p&gt;Here is a concrete example. A PRD says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Requests at or above 500 USD require manager and finance approval.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A generated test suite might contain:&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;def&lt;/span&gt; &lt;span class="nf"&gt;test_low_amount&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# 120 USD → manager approval only
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;120&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;manager_only&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_high_amount&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# 600 USD → finance required
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;600&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;finance_required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both tests pass. Branch coverage is green. The implementation, however, uses &lt;code&gt;&amp;gt; 500&lt;/code&gt; instead of &lt;code&gt;&amp;gt;= 500&lt;/code&gt;. The case of exactly 500 USD — which the PRD says requires finance approval — silently routes to the wrong path.&lt;/p&gt;

&lt;p&gt;This is not a clever edge case. It is the boundary the PRD explicitly defined. A coverage tool reports it as fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Qualix does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Qualix is a quality gate that starts from the requirement, not from the code.&lt;/p&gt;

&lt;p&gt;Given the PRD, it extracts semantic expectations (SEs) — the business behaviors that tests should prove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SE-003: a request at exactly 500 USD requires manager AND finance approval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It then audits the test suite against those expectations. If no test exercises &lt;code&gt;amount == 500&lt;/code&gt;, SE-003 is flagged as &lt;code&gt;PARTIAL&lt;/code&gt; or &lt;code&gt;MISSING&lt;/code&gt;, regardless of what line coverage says.&lt;/p&gt;

&lt;p&gt;The full pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Q01  Structure the PRD into traceable REQ/BR/SE items
Q05a Design test targets from those semantics (EUT matrix)
Q05b Generate test code (optional, needs compile gate)
Q06  Audit the test suite against the original SE items
Q07  Structured code review tied back to requirement IDs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works with your existing test runner. It does not replace pytest, JUnit, or Jest. It sits above them and answers a different question: did the tests prove the requirement, or just execute the code?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why now&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI coding agents have made it cheap to generate code and tests. That changes the bottleneck. The bottleneck is no longer "can we write this?" but "does this actually do what the product asked for?"&lt;/p&gt;

&lt;p&gt;Line coverage was designed for the world where tests were hand-written. In that world, a developer who wrote the test usually understood the requirement. The test was evidence of understanding.&lt;/p&gt;

&lt;p&gt;AI-generated tests are evidence of execution. The model generates what it can infer from the code. If the code has a logic error at the boundary, the generated test will probably pass — because the test is generated from the same (wrong) implementation.&lt;/p&gt;

&lt;p&gt;Qualix is an attempt to inject the requirement back into the loop, at a point where it can still catch the gap before the code ships.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current state&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache 2.0, public alpha (0.2.0a1 on PyPI)&lt;/li&gt;
&lt;li&gt;Java has the deepest path; TypeScript, Go, Python supported at basic level&lt;/li&gt;
&lt;li&gt;GitHub Actions composite action for CI gate integration&lt;/li&gt;
&lt;li&gt;Real-world results: in three production Java services, Q06 found 18 EUT targets with assertion gaps that line coverage did not flag (16 partial, 2 missing)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;qualix
./scripts/run_expense_demo.sh   &lt;span class="c"&gt;# no API key needed, shows pre-computed findings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What I am looking for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the semantic coverage framing make sense? Is there a clearer way to explain the gap between line coverage and business-rule verification?&lt;/li&gt;
&lt;li&gt;Java is the strongest path today. What language / framework would make this immediately useful for your team?&lt;/li&gt;
&lt;li&gt;The current workflow requires an AI coding agent (Claude Code, Codex, Gemini CLI). Is the friction too high for evaluation?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The GitHub repo is at: &lt;a href="https://github.com/alexangelzhang/qualix" rel="noopener noreferrer"&gt;https://github.com/alexangelzhang/qualix&lt;/a&gt;&lt;/p&gt;

</description>
      <category>qualix</category>
      <category>ai</category>
      <category>showdev</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
