<?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 怼怼胡 (@huv0310arch).</description>
    <link>https://dev.to/huv0310arch</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%2F4235010%2Fd875121f-82e9-495a-bad1-a7b08cc12030.png</url>
      <title>DEV Community: 怼怼胡</title>
      <link>https://dev.to/huv0310arch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/huv0310arch"/>
    <language>en</language>
    <item>
      <title>Verdict Ledger v3.3: verify an AI agent's judgment history without receiving a single row</title>
      <dc:creator>怼怼胡</dc:creator>
      <pubDate>Mon, 09 Nov 2026 11:48:42 +0000</pubDate>
      <link>https://dev.to/huv0310arch/verdict-ledger-v33-verify-an-ai-agents-judgment-history-without-receiving-a-single-row-26dn</link>
      <guid>https://dev.to/huv0310arch/verdict-ledger-v33-verify-an-ai-agents-judgment-history-without-receiving-a-single-row-26dn</guid>
      <description>&lt;h1&gt;
  
  
  Verdict Ledger v3.3: verify an AI agent's judgment history without receiving a single row
&lt;/h1&gt;

&lt;p&gt;An AI that judges other AI has a credibility problem: the record is written by the judge. "Trust my log" is self-serving evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verdict Ledger&lt;/strong&gt; is an append-only, hash-chained judgment ledger in pure Python standard library — zero dependencies, MIT. V2 gives every judgment an AI makes a court case; V3 gives "AI improving itself" an inspection room. v3.3 adds two things.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Merkle consistency proofs (RFC 9162)
&lt;/h2&gt;

&lt;p&gt;Until now, proving the history was intact meant handing over the history. v3.3 doesn't.&lt;/p&gt;

&lt;p&gt;The verifier receives a chain head — entry count, root hash, timestamp, signature — plus a Merkle proof, and &lt;strong&gt;no ledger rows at all&lt;/strong&gt;. From those they recompute the root themselves and confirm entries 1..N are continuous, with nothing dropped in the middle. Tamper with one row or truncate the tail and the recomputed root disagrees: red. No anchor yet? The tool says so and refuses to answer — it never fabricates a pass.&lt;/p&gt;

&lt;p&gt;Challenge responses come in two shapes (&lt;code&gt;--merkle-only&lt;/code&gt; zero-row, or with rows attached), and the verifier trusts neither form: only the recomputation counts.&lt;/p&gt;

&lt;p&gt;The tree follows RFC 9162 §2.1.1 (construction) and §2.1.4.2 (proof verification). The test suite checks it against the RFC's own seven-leaf example and against an independently written implementation, then sweeps every prefix of 2..24 leaves.&lt;/p&gt;

&lt;p&gt;This is the signed chain head published with the release:&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;"v"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"algo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256-chain"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entry_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1084&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"root_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:18bbb7207255201cf6e455c1d8455d81d3f7916e7309b945dee980d0b299113e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issued_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1794216446.8824673&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"key_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hmac-sha256:1e17ffcdd67384fd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"037df2df4239979eea7a7b5b3709731c2baf073bddf69642eb83c7f933a23a5c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"merkle_root"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:25be80fc6da3a2aa4537ada13603aedd321df3224dc0e0c6e4a7311163a37d0e"&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;h2&gt;
  
  
  2. The first external anchor
&lt;/h2&gt;

&lt;p&gt;A hash on your own disk proves nothing against whoever controls the disk. v3.3 writes that signed chain head into the GitHub release notes &lt;strong&gt;and&lt;/strong&gt; the signed &lt;code&gt;v3.3&lt;/code&gt; tag — a second copy, outside the ledger, held by the repo host. Local edits can't match it.&lt;/p&gt;

&lt;p&gt;It's a weak anchor and we say so in the release notes: the host is still a party we can influence.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we have not done
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RFC 3161 authoritative timestamps&lt;/strong&gt; — not yet. The timestamps are ours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Witness gossip&lt;/strong&gt; (independent parties watching each other's chains) — on the books, not built.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asymmetric signatures&lt;/strong&gt; — still HMAC. Symmetric means the key holder can sign anything, so the key must live with the verifier, not the writer. That's a real limit, not a footnote.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a claim can't be verified, it gets written down as unverifiable. No exceptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/huv0310-arch/verdict-ledger.git
&lt;span class="nb"&gt;cd &lt;/span&gt;verdict-ledger &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; python ci/run_ci.py
&lt;span class="c"&gt;# ALL GREEN: 50 acceptance cases&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The chain head above is published and signed. The challenge: make the numbers disagree.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/huv0310-arch/verdict-ledger" rel="noopener noreferrer"&gt;github.com/huv0310-arch/verdict-ledger&lt;/a&gt; — MIT · zero dependencies · English docs in &lt;code&gt;README.en.md&lt;/code&gt; · release notes with the full anchor: &lt;a href="https://github.com/huv0310-arch/verdict-ledger/releases/tag/v3.3" rel="noopener noreferrer"&gt;v3.3&lt;/a&gt;&lt;/p&gt;

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