<?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: newmathphys</title>
    <description>The latest articles on DEV Community by newmathphys (@newmathphys).</description>
    <link>https://dev.to/newmathphys</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%2F4188788%2F8168d05f-8fe8-4e76-a6e3-9dd72c8eb008.png</url>
      <title>DEV Community: newmathphys</title>
      <link>https://dev.to/newmathphys</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/newmathphys"/>
    <language>en</language>
    <item>
      <title>Why "1 passed in 0.01s" is a lie when AI writes the tests (and how I built a Z3 + Zig 0.17 truth gate to stop it)</title>
      <dc:creator>newmathphys</dc:creator>
      <pubDate>Fri, 16 Oct 2026 11:55:55 +0000</pubDate>
      <link>https://dev.to/newmathphys/why-1-passed-in-001s-is-a-lie-when-ai-writes-the-tests-and-how-i-built-a-z3-zig-017-truth-177m</link>
      <guid>https://dev.to/newmathphys/why-1-passed-in-001s-is-a-lie-when-ai-writes-the-tests-and-how-i-built-a-z3-zig-017-truth-177m</guid>
      <description>&lt;h1&gt;
  
  
  Why "1 passed in 0.01s" is a lie when AI writes the tests
&lt;/h1&gt;

&lt;h2&gt;
  
  
  (and how I built a Z3 + Zig 0.17 truth gate to stop it)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/newmathphys/kern" rel="noopener noreferrer"&gt;https://github.com/newmathphys/kern&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License:&lt;/strong&gt; PolyForm Noncommercial 1.0.0 / Commercial (source-available)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static binary:&lt;/strong&gt; &lt;code&gt;kernc-x86_64-linux-musl&lt;/code&gt; in the release assets (no Zig install needed)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  The lie is not in pytest
&lt;/h3&gt;

&lt;p&gt;Let me be precise, because the title is deliberately blunt. &lt;code&gt;pytest&lt;/code&gt; does not lie.&lt;br&gt;
It reports what happened: &lt;strong&gt;the test function ran to completion without raising&lt;/strong&gt;.&lt;br&gt;
That is all &lt;code&gt;1 passed in 0.01s&lt;/code&gt; ever meant.&lt;/p&gt;

&lt;p&gt;The lie is in the &lt;em&gt;inference&lt;/em&gt;. When an AI agent writes both the fix and the test,&lt;br&gt;
"1 passed" is presented as evidence that the fix is correct. It is not evidence of&lt;br&gt;
anything, because &lt;strong&gt;the test was never able to fail&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is the actual demo from this repo (&lt;code&gt;make run-example&lt;/code&gt;), a withdrawal function&lt;br&gt;
where the agent dropped the &lt;code&gt;amount &amp;lt;= 0&lt;/code&gt; guard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1] pytest:  1 passed in 0.01s              &amp;lt;- green. The bug ships.
[2] KERN:    contract_refuted.smt2: SAT  -&amp;gt; e=0 (F)  COUNTEREXAMPLE
             contract_fixed.smt2:   UNSAT -&amp;gt; e=1 (T)  PROVED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test contained no &lt;code&gt;assert&lt;/code&gt; at all. It called the function and checked that no&lt;br&gt;
exception was raised. An agent optimising for a green checkmark will write exactly&lt;br&gt;
that, and it will keep writing it, because nothing in a boolean CI pipeline&lt;br&gt;
distinguishes &lt;code&gt;1 passed&lt;/code&gt; (a real test) from &lt;code&gt;1 passed&lt;/code&gt; (an empty one).&lt;/p&gt;
&lt;h3&gt;
  
  
  What I built instead
&lt;/h3&gt;

&lt;p&gt;KERN is an L0–L5 verification gateway written in Zig 0.17. A claim does not become&lt;br&gt;
&lt;code&gt;e = 1&lt;/code&gt; because a test printed green. It becomes &lt;code&gt;e = 1&lt;/code&gt; only when an &lt;strong&gt;external&lt;br&gt;
trusted checker&lt;/strong&gt; (Z3) proves it, or when a reproducible execution record backs it.&lt;/p&gt;

&lt;p&gt;Three mechanisms do the work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Belnap B₄ accumulator.&lt;/strong&gt; Verdicts are not overwritten, they are accumulated:&lt;br&gt;
&lt;code&gt;(p, n) -&amp;gt; N | T | F | B&lt;/code&gt;. A passing test (&lt;code&gt;T&lt;/code&gt;) joined with a counterexample (&lt;code&gt;F&lt;/code&gt;)&lt;br&gt;
yields &lt;code&gt;B&lt;/code&gt; — conflict. The conflict is never resolved in favour of the proof. This&lt;br&gt;
is &lt;code&gt;JOIN_K(T, F) = B&lt;/code&gt;, and it is proved in Lean 4, not asserted in a comment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Can-fail harness (&lt;code&gt;tools/canfail.py&lt;/code&gt;).&lt;/strong&gt; Every check in the repository must&lt;br&gt;
prove that it is &lt;em&gt;capable of failing&lt;/em&gt;: the harness injects a fault and requires a&lt;br&gt;
non-zero exit code. Current state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;total make targets:  89
CHECK targets:       68   (must be able to fail)
CHECK with proof of "can fail":  64/68
registered fault-injection cases: 73
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the part that found the real problems. Auditing my own suite turned up&lt;br&gt;
&lt;strong&gt;26 defects of a single class: "silently broken checks"&lt;/strong&gt; — scripts or tests that&lt;br&gt;
returned exit code &lt;code&gt;0&lt;/code&gt; while the check itself was broken. Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;./formal/check.sh | tail -3&lt;/code&gt; without &lt;code&gt;pipefail&lt;/code&gt; — the pipeline reported the
status of &lt;code&gt;tail&lt;/code&gt;, so a failing proof check looked green;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kernc cat image /raw/missing&lt;/code&gt; printed data to &lt;strong&gt;stderr&lt;/strong&gt; and exited &lt;code&gt;0&lt;/code&gt;, so
&lt;code&gt;kernc cat ... &amp;gt; out.txt&lt;/code&gt; produced an &lt;strong&gt;empty file&lt;/strong&gt; and no error;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;.gitignore&lt;/code&gt; rule &lt;code&gt;*.log&lt;/code&gt; placed &lt;em&gt;after&lt;/em&gt; &lt;code&gt;!docs/evidence/*.log&lt;/code&gt; silently
excluded every verification log — the repo published claims without evidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Independent proof-DAG checker (&lt;code&gt;src/verifier/proof_check.zig&lt;/code&gt;).&lt;/strong&gt; Z3's &lt;code&gt;unsat&lt;/code&gt;&lt;br&gt;
is not taken on faith. KERN parses the solver's proof DAG and re-derives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no proof holes (&lt;code&gt;hole&lt;/code&gt; / &lt;code&gt;trust&lt;/code&gt; / &lt;code&gt;sorry&lt;/code&gt; → immediate rejection);&lt;/li&gt;
&lt;li&gt;premise binding — every nested &lt;code&gt;(asserted ...)&lt;/code&gt; must match a clause of the input
contract (&lt;code&gt;premises_unbound == 0&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mp&lt;/code&gt;, &lt;code&gt;unit-resolution&lt;/code&gt;, &lt;code&gt;refl&lt;/code&gt;/&lt;code&gt;symm&lt;/code&gt;/&lt;code&gt;trans&lt;/code&gt;, &lt;code&gt;and-elim&lt;/code&gt;, &lt;code&gt;not-or-elim&lt;/code&gt;,
&lt;code&gt;monotonicity&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Farkas arithmetic certificates&lt;/strong&gt; for linear integer inequalities — including
the &lt;code&gt;¬(l ≤ r) ⟺ r − l + 1 ≤ 0&lt;/code&gt; normalisation over ℤ (where most hand-written
checkers silently get the sign or the &lt;code&gt;+1&lt;/code&gt; wrong);&lt;/li&gt;
&lt;li&gt;the DAG must conclude &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the reference proof this now reports &lt;strong&gt;&lt;code&gt;trusted: 0&lt;/code&gt;&lt;/strong&gt; — every one of the 16&lt;br&gt;
steps is independently re-derived:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[PROOF VERIFIED] steps: 16 | premises bound: 1/1 | mp: 2 | rewrite (linear): 5 |
                 farkas: 1 | trusted: 0 | holes: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Honest limits (this is the part most write-ups skip)
&lt;/h3&gt;

&lt;p&gt;I would rather publish the boundaries than have someone find them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The static gate does not raise &lt;code&gt;pass@1&lt;/code&gt;.&lt;/strong&gt; Measured on HumanEval+ with a real
model: 0.524 base / 0.500 plus. The gate's precision is 100 % (55/55 blocks were
genuine failures, 0 false blocks), but it fires &lt;em&gt;before&lt;/em&gt; the tests, so the score
is unchanged. Raising it requires execution evidence and iterative repair, not
one-shot filtering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;zstd&lt;/code&gt; is declared in the format and NOT implemented.&lt;/strong&gt; Zig's std ships a zstd
&lt;em&gt;decompressor&lt;/em&gt; only, and there is no static &lt;code&gt;libzstd.a&lt;/code&gt; here, so linking it would
break the hermetic musl build. Requesting it returns &lt;code&gt;error.CodecUnsupported&lt;/code&gt;
rather than failing quietly. &lt;code&gt;deflate&lt;/code&gt; (&lt;code&gt;0x02&lt;/code&gt;, a KERN extension) &lt;em&gt;is&lt;/em&gt;
implemented and tested.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compression and zero-copy are mutually exclusive.&lt;/strong&gt; Reading a compressed object
needs a buffer, so the zero-copy path refuses it explicitly instead of handing
back compressed bytes as content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QuixBugs 31/31 is execution, not proof&lt;/strong&gt; — those bugs are caught by running the
official test cases, not by a ∀-quantified argument.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Refactory numbers are a Python harness, not the KERN core.&lt;/strong&gt; Two scripts
exist; the first reported 83.2 % on buggy files and 83.7 % on &lt;em&gt;correct&lt;/em&gt; ones —
rates that coincide, so it measured nothing. The second (1705/1782 buggy at 0
false positives on 2442/2442 correct) agrees with the dataset's own test suite,
which makes it close to tautological. Neither uses Z3 or the Zig core at all, and
the README says so in a footnote.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;26 of 86 logged defects were "silently broken checks."&lt;/strong&gt; That is not a brag —
it is the base rate I measured while building the harness that catches them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What it actually costs to adopt
&lt;/h3&gt;

&lt;p&gt;No Zig install, no build step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; kernc https://github.com/newmathphys/kern/releases/download/v2.2.0/kernc-x86_64-linux-musl
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x kernc &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./kernc prove formal/example.smt2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or as a GitHub Action, one line:&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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;newmathphys/kern@v2.2.0&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;contract&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;formal/spec.smt2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or from an AI agent over MCP (&lt;code&gt;examples/kern_mcp_server.py&lt;/code&gt;, stdlib only):&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="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="nl"&gt;"kern"&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="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;"python3"&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;"/path/to/kern/examples/kern_mcp_server.py"&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 MCP server exposes &lt;code&gt;kern_verify_smt&lt;/code&gt;, &lt;code&gt;kern_prove_with_checker&lt;/code&gt; and&lt;br&gt;
&lt;code&gt;kern_verify_multi_belnap&lt;/code&gt;. The last one returns &lt;code&gt;JOIN_K(T, F) = B&lt;/code&gt; when two&lt;br&gt;
contracts contradict each other, and refuses to collapse it into a proof.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the blunt title
&lt;/h3&gt;

&lt;p&gt;Because the failure mode is not exotic. It is the default outcome of putting an&lt;br&gt;
optimiser (an agent) next to a boolean signal (a green checkmark) with no&lt;br&gt;
independent verifier in between. The agent is not malicious; it is doing exactly&lt;br&gt;
what the signal rewards. The fix is not a better prompt — it is removing the&lt;br&gt;
boolean and replacing it with something that cannot be satisfied vacuously.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;1 passed in 0.01s&lt;/code&gt; is not a lie. Treating it as proof is.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Defect registry: #1–#86. 230 core tests, cross-arch runs on ARM64 and&lt;br&gt;
big-endian POWERPC64, 32 Lean 4 theorems with 0 &lt;code&gt;sorry&lt;/code&gt;, 100 % decision coverage.&lt;br&gt;
Every number above is reproduced by &lt;code&gt;make evidence&lt;/code&gt; and published under&lt;br&gt;
&lt;code&gt;docs/evidence/&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>zig</category>
      <category>ai</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
