<?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: Brad Kinnard</title>
    <description>The latest articles on DEV Community by Brad Kinnard (@moonrunnerkc).</description>
    <link>https://dev.to/moonrunnerkc</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%2F3727405%2Fdace59d9-5970-49b1-9ee7-0836891c5a65.png</url>
      <title>DEV Community: Brad Kinnard</title>
      <link>https://dev.to/moonrunnerkc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moonrunnerkc"/>
    <language>en</language>
    <item>
      <title>Reproducible vulnerability scans with dumpscan</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Fri, 04 Sep 2026 01:54:07 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/making-vulnerability-scans-reproducible-with-dumpscan-1j9i</link>
      <guid>https://dev.to/moonrunnerkc/making-vulnerability-scans-reproducible-with-dumpscan-1j9i</guid>
      <description>&lt;p&gt;Vulnerability scan results can change even when the code does not. Advisory data, comparison rules, or exclusions may change between scans, making earlier results difficult to explain.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/moonrunnerkc/dumpscan" rel="noopener noreferrer"&gt;dumpscan&lt;/a&gt; to make vulnerability scans reproducible.&lt;/p&gt;

&lt;p&gt;Each scan records four inputs by digest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependency lockfile&lt;/li&gt;
&lt;li&gt;OSV vulnerability snapshot&lt;/li&gt;
&lt;li&gt;Version comparison rules&lt;/li&gt;
&lt;li&gt;Applied exclusions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the same inputs produces the same findings byte for byte. When results differ, dumpscan identifies which input changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a reproducible scan
&lt;/h2&gt;

&lt;p&gt;Instead of relying on the latest advisory data, dumpscan requires a content-addressed OSV snapshot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dumpscan scan package-lock.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--snapshot&lt;/span&gt; ./snapshot &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--out&lt;/span&gt; scan.bundle.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting bundle contains the input digests, findings, and findings root needed to verify the result later.&lt;/p&gt;

&lt;p&gt;This is useful during audits, incident reviews, and investigations where teams need to understand what the scanner knew at a specific time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sign and verify results
&lt;/h2&gt;

&lt;p&gt;A signature proves that a file was signed, but not that its findings can be reproduced.&lt;/p&gt;

&lt;p&gt;dumpscan records the input digests and findings root in an in-toto statement. It also supports keyless signing with Sigstore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dumpscan scan package-lock.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--snapshot&lt;/span&gt; ./snapshot &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--out&lt;/span&gt; scan.bundle.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sign&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the bundle without running another scan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dumpscan verify scan.bundle.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verification checks the signature, payload binding, findings root, findings count, input manifest, and lockfile digest. It can also verify the certificate issuer and workflow identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replay a scan
&lt;/h2&gt;

&lt;p&gt;Replay derives the findings again from the recorded inputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dumpscan replay scan.bundle.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lockfile&lt;/span&gt; package-lock.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--snapshot&lt;/span&gt; ./snapshot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The replay must produce the same findings root. If it does not, dumpscan reports the expected and observed digests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explain changed results
&lt;/h2&gt;

&lt;p&gt;When two scans differ, &lt;code&gt;dumpscan diff&lt;/code&gt; determines whether the change came from the project or the scanning inputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dumpscan diff scan-day-1.bundle.json scan-day-2.bundle.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--snapshot-a&lt;/span&gt; ./snapshot-day-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--snapshot-b&lt;/span&gt; ./snapshot-day-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It compares the lockfile, vulnerability feed, version rules, and exclusions. When snapshots are available, it can also identify changed advisory fields.&lt;/p&gt;

&lt;p&gt;This helps distinguish a dependency update from an advisory being rescored, withdrawn, or assigned a new fixed version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep uncertainty visible
&lt;/h2&gt;

&lt;p&gt;Excluded, withdrawn, and unevaluated findings remain in the findings set with their status and reason.&lt;/p&gt;

&lt;p&gt;Unsupported version ranges are not treated as unaffected, and exclusions are recorded as scan inputs. This keeps the result complete and makes policy decisions visible during review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;dumpscan requires Node 22.22.2 or later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt; dumpscan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also run it without a global installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx dumpscan &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a snapshot from local OSV records:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dumpscan snapshot &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from&lt;/span&gt; fixtures/osv/synthetic/records &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--out&lt;/span&gt; ./snapshot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate SARIF 2.1.0 output for GitHub code scanning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dumpscan scan package-lock.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--snapshot&lt;/span&gt; ./snapshot &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--out&lt;/span&gt; scan.bundle.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sarif&lt;/span&gt; scan.sarif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SARIF file is derived output. The bundle remains the reproducible source of truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope
&lt;/h2&gt;

&lt;p&gt;The first release focuses on lockfile scanning. It does not provide reachability analysis, exploitability analysis, risk scoring, container scanning, or SBOM generation.&lt;/p&gt;

&lt;p&gt;These limits are intentional. dumpscan prioritizes reproducible, verifiable results over broad vulnerability-management coverage.&lt;/p&gt;

&lt;p&gt;dumpscan is available under the Apache 2.0 license:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/dumpscan" rel="noopener noreferrer"&gt;github.com/moonrunnerkc/dumpscan&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>devsecops</category>
      <category>opensource</category>
      <category>node</category>
    </item>
    <item>
      <title>skillcheck Update: Scorer Fixes, Cleaner Failures, Honest Token Numbers</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Sun, 23 Aug 2026 03:04:23 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/skillcheck-update-scorer-fixes-cleaner-failures-honest-token-numbers-2j8h</link>
      <guid>https://dev.to/moonrunnerkc/skillcheck-update-scorer-fixes-cleaner-failures-honest-token-numbers-2j8h</guid>
      <description>&lt;p&gt;skillcheck is a static analyzer for &lt;code&gt;SKILL.md&lt;/code&gt; files, the format agents like Claude Code, Copilot, Codex, and Cursor use to load reusable skills. It validates frontmatter, scores description discoverability, checks file references, enforces token budgets, and flags cross-agent compatibility issues. No network calls, no LLM calls, no file mutations. Runs as a CLI, a GitHub Action, or a pre-commit hook.&lt;br&gt;
&lt;/p&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;skillcheck
skillcheck skills/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Latest pass was hardening and accuracy, not features. Here's what changed and why.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description scores went up.&lt;/strong&gt; Skills that were scoring low because the scorer was broken will now see a jump in scoring. Median across the reference corpus went from 75 to 90. &lt;code&gt;--explain-score&lt;/code&gt; also now tells you which pattern hits or misses instead of just a number. The score exists to predict whether an agent will actually find and trigger your skill, so a scorer that under-credits good descriptions defeats the point. The fix was validated against real-world skills, and the separation held: filler still scores 28-65, well-written descriptions 85-100.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Corrupt files now fail cleanly instead of crashing.&lt;/strong&gt; Before, a bad history ledger or non-UTF-8 skillcheck.toml above the skill dumped a Python traceback. It's now a clear error naming the file and byte offset (exit code 2). Config discovery walks up the directory tree, so one bad file could break every scan under it. Now every untrusted read (ingest, history, config) goes through the same guard before parsing, so they all reject the same way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;README has been corrected in regards to token estimates.&lt;/strong&gt; Without tiktoken, expect roughly 20-30% over-estimation, so install the extra if you're near a budget limit. The offline heuristic feeds the budget checks and its accuracy had never actually been measured, just assumed. It's benchmarked against tiktoken across the full corpus now, and the documented numbers are the measured ones.&lt;br&gt;
&lt;/p&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; &lt;span class="s2"&gt;"skillcheck[tiktoken]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The rest of the pass is invisible on purpose: flag-conflict logic consolidated to one source of truth, golden-file tests pinning exact diagnostic output, coverage floor raised from 75% to 80% (actual sits at 90%). Diagnostic output across the corpus verified byte-for-byte identical before and after. Nothing changed except what's above.&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/moonrunnerkc" rel="noopener noreferrer"&gt;
        moonrunnerkc
      &lt;/a&gt; / &lt;a href="https://github.com/moonrunnerkc/skillcheck" rel="noopener noreferrer"&gt;
        skillcheck
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Cross-agent skill quality gate for SKILL.md files. Validates frontmatter, scores description discoverability, checks file references, enforces three-tier token budgets, and flags compatibility issues across Claude Code, VS Code/Copilot, Codex, and Cursor.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;

  
  
  &lt;img alt="skillcheck" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmoonrunnerkc%2Fskillcheck%2FHEAD%2F.github%2Fbanner.svg" width="600"&gt;

&lt;br&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/e219b966b89d006ba21e62aac3d3764816d1cc825d8e1f48b4ea77700ace972a/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f736b696c6c636865636b3f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/e219b966b89d006ba21e62aac3d3764816d1cc825d8e1f48b4ea77700ace972a/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f736b696c6c636865636b3f7374796c653d666c61742d737175617265" alt="PyPI version"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/22398629855c0654c7c86bd76afefdc8546665f8540e3cc58aae6ec25f7b5abc/68747470733a2f2f696d672e736869656c64732e696f2f707970692f707976657273696f6e732f736b696c6c636865636b3f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/22398629855c0654c7c86bd76afefdc8546665f8540e3cc58aae6ec25f7b5abc/68747470733a2f2f696d672e736869656c64732e696f2f707970692f707976657273696f6e732f736b696c6c636865636b3f7374796c653d666c61742d737175617265" alt="Python"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/c8ce7d3aba8be46b50d959c786b12ea1cded9c2a0f3cac043e8fc7fbffa8007b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6f6f6e72756e6e65726b632f736b696c6c636865636b2f63692e796d6c3f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/c8ce7d3aba8be46b50d959c786b12ea1cded9c2a0f3cac043e8fc7fbffa8007b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6f6f6e72756e6e65726b632f736b696c6c636865636b2f63692e796d6c3f7374796c653d666c61742d737175617265" alt="CI status"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/e24f94c61d79c21063e8b202c236c1ea013985b9800775ca0b7cd0ad0b732a4c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d6f6f6e72756e6e65726b632f736b696c6c636865636b3f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/e24f94c61d79c21063e8b202c236c1ea013985b9800775ca0b7cd0ad0b732a4c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d6f6f6e72756e6e65726b632f736b696c6c636865636b3f7374796c653d666c61742d737175617265" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Static analyzer for &lt;code&gt;SKILL.md&lt;/code&gt; files. Validates frontmatter, body sizing, file references, and cross-agent compatibility against the &lt;a href="https://agentskills.io/specification" rel="nofollow noopener noreferrer"&gt;agentskills.io specification&lt;/a&gt;. No network calls. No LLM API calls. No file mutations.&lt;/p&gt;

&lt;p&gt;1058 tests cover all rule modules.&lt;/p&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 skillcheck&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Requires Python 3.10 or later. For more accurate token estimates, install the optional extra:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pip install &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;skillcheck[tiktoken]&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;h3 class="heading-element"&gt;Token estimation accuracy&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;Token counts are estimates, and the sizing rules report them as such. The bands below are measured, not estimated: &lt;code&gt;scripts/measure_token_error.py&lt;/code&gt; compares the offline heuristic against &lt;code&gt;tiktoken&lt;/code&gt; &lt;code&gt;cl100k_base&lt;/code&gt; across a corpus of 61 real &lt;code&gt;SKILL.md&lt;/code&gt; files, for the three spans the rules actually size.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;table&gt;

&lt;thead&gt;

&lt;tr&gt;

&lt;th&gt;Span&lt;/th&gt;

&lt;th&gt;Rule&lt;/th&gt;

&lt;th&gt;Median error&lt;/th&gt;

&lt;th&gt;p95 error&lt;/th&gt;

&lt;th&gt;Direction&lt;/th&gt;

&lt;/tr&gt;

&lt;/thead&gt;

&lt;tbody&gt;

&lt;tr&gt;

&lt;td&gt;Whole file&lt;/td&gt;

&lt;td&gt;&lt;code&gt;sizing.total-tokens&lt;/code&gt;&lt;/td&gt;

&lt;td&gt;23.0%&lt;/td&gt;

&lt;td&gt;30.7%&lt;/td&gt;

&lt;td&gt;over-estimates 61/61&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;Frontmatter&lt;/td&gt;

&lt;td&gt;&lt;code&gt;disclosure.metadata-budget&lt;/code&gt;&lt;/td&gt;

&lt;td&gt;25.9%&lt;/td&gt;

&lt;td&gt;35.3%&lt;/td&gt;

&lt;td&gt;over-estimates 61/61&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;Body&lt;/td&gt;

&lt;td&gt;&lt;code&gt;disclosure.body-budget&lt;/code&gt;&lt;/td&gt;

&lt;td&gt;22.7%&lt;/td&gt;

&lt;td&gt;30.7%&lt;/td&gt;

&lt;td&gt;over-estimates 61/61&lt;/td&gt;

&lt;/tr&gt;

&lt;/tbody&gt;

&lt;/table&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The bias is one-directional: the offline heuristic read high on every file in the corpus. For a budget check that…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/moonrunnerkc/skillcheck" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;If skillcheck flags something in your skills that looks wrong, open an issue. The reference corpus grows from real-world cases and the scorer improves with them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>developertools</category>
      <category>python</category>
    </item>
    <item>
      <title>It Fits and It Benchmarks Well. Will It Do Your Job?</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Mon, 20 Jul 2026 03:05:45 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/it-fits-and-it-benchmarks-well-will-it-do-your-job-12fb</link>
      <guid>https://dev.to/moonrunnerkc/it-fits-and-it-benchmarks-well-will-it-do-your-job-12fb</guid>
      <description>&lt;p&gt;A fit calculator answers one question: will these weights load in your memory. A leaderboard answers a different one: is this model good at tests in general. The question that decides what you actually run is neither. It's "will Q4_K_M hurt my invoice extraction accuracy on my machine," and the only reliable way to answer it is to run your extraction on Q4_K_M and measure.&lt;/p&gt;

&lt;p&gt;QuantProof automates that. Point it at a folder of real examples from your task. It sweeps every model you already have in Ollama (or whatever a Rapid-MLX server is serving), scores every output with deterministic scorers, measures time to first token, tokens per second, and peak memory, then recommends the smallest quant whose quality stays within 2% of the best measured result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; quantproof
quantproof ingest my-tasks.md   &lt;span class="c"&gt;# a local model drafts the task pack from your notes&lt;/span&gt;
&lt;span class="c"&gt;# or: quantproof init my-task   # scaffold it yourself&lt;/span&gt;
quantproof run &lt;span class="nt"&gt;--pack&lt;/span&gt; my-tasks
quantproof report &lt;span class="nt"&gt;--markdown&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Why measure instead of estimate
&lt;/h2&gt;

&lt;p&gt;Three task packs ran on an M5 Max: ticket classification, invoice extraction, config generation. Three models, 540 scored generations. No model won all three.&lt;/p&gt;

&lt;p&gt;An 8B at Q8_0 took classification at 0.950, beating a 30B at 45% of the memory. The 30B was the only model to score 1.000 on extraction. They tied at 1.000 on config generation, where the 8B needs about 17 GiB less.&lt;/p&gt;

&lt;p&gt;The 8B's zero on extraction was a token-budget truncation issue, not a quality failure. On 57 of 60 generations it spent its entire 512-token budget on reasoning and never emitted content. Because every raw output is journaled, the report flags the zero &lt;code&gt;trunc!&lt;/code&gt; and names the fix (raise &lt;code&gt;max_tokens&lt;/code&gt;) instead of letting it read as "this model can't extract."&lt;/p&gt;

&lt;p&gt;Which model is "best" changed with every task. That is the leaderboard problem in one paragraph: the ranking is a property of the model and the workload together, and a leaderboard only knows the model.&lt;/p&gt;
&lt;h2&gt;
  
  
  Determinism is a backend version property, not a model property
&lt;/h2&gt;

&lt;p&gt;Every example runs 3 times at temperature 0 with a fixed seed, and repetitions are compared byte for byte. On Apple Metal, every candidate repeated exactly, across 240+ scored units. Then the same check ran on an RTX 5070. Same pack, same seed, same driver, two Ollama versions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;candidate&lt;/th&gt;
&lt;th&gt;ollama 0.15.2&lt;/th&gt;
&lt;th&gt;ollama 0.32.1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;llama3.1:latest (Q4_K_M)&lt;/td&gt;
&lt;td&gt;nondet&lt;/td&gt;
&lt;td&gt;deterministic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llama3.1:8b-instruct-q4_0&lt;/td&gt;
&lt;td&gt;nondet&lt;/td&gt;
&lt;td&gt;deterministic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma3:4b&lt;/td&gt;
&lt;td&gt;nondet&lt;/td&gt;
&lt;td&gt;nondet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma3:1b&lt;/td&gt;
&lt;td&gt;deterministic&lt;/td&gt;
&lt;td&gt;nondet&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both 8B quants became deterministic after the upgrade. The 1B flipped the other way.&lt;/p&gt;

&lt;p&gt;Not even the direction of the effect survived a backend upgrade, which is why the check runs on every sweep instead of being trusted once. One example answered "As needed" on repetition 1 and "Weekly" on repetitions 2 and 3, at temperature 0 with a seed: identical conditions, different outputs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Predictions print next to measurements
&lt;/h2&gt;

&lt;p&gt;The fit prediction is deliberately simple: weights on disk, plus f16 KV cache for the context, plus a fixed 1 GiB compute allowance. On the 5070, three of four candidates measured within 15% of prediction; the 1B ran over 20% under its intentionally conservative estimate. Every report shows both. Use predictions for planning. Measured peak is your actual constraint.&lt;/p&gt;

&lt;p&gt;Peak memory comes from the most honest source each machine has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;nvidia-smi&lt;/strong&gt; on NVIDIA GPUs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend process RSS&lt;/strong&gt; on Apple Silicon (validated against Ollama's own accounting)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metal accounting&lt;/strong&gt; on Rapid-MLX&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;/proc/meminfo-based RSS&lt;/strong&gt; on everything else&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A machine with no working source reports "not measured." Nothing is ever estimated.&lt;/p&gt;
&lt;h2&gt;
  
  
  Anyone can recheck the scores
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;quantproof report --bundle&lt;/code&gt; exports a zip with every raw output, all scores, model digests, sampler params, and the backend version. Re-scoring the 5070 sweep from bundle contents alone reproduced 264 of 264 scores exactly, on both Ollama versions. A number you can't recheck is marketing.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  The fine print (read before citing any of these numbers)
  &lt;ul&gt;
&lt;li&gt;Memory is sampled at roughly 200 ms. The recorded peak is the highest sample, a floor on the true peak, not an allocator trace.&lt;/li&gt;
&lt;li&gt;TTFT is measured from HTTP request to first streamed chunk, including connection overhead and prompt evaluation. The real latency a user experiences, not a pure decode metric.&lt;/li&gt;
&lt;li&gt;Scorers are deterministic only: schema conformance, field comparison, label match, pattern presence, numeric tolerance. Tasks that need judgment (summarization, open QA) are out of scope, not approximated with a judge model.&lt;/li&gt;
&lt;li&gt;Partial GPU offload is flagged with its reasoning, not measured. Ollama decides offload, not the harness.&lt;/li&gt;
&lt;li&gt;A pack drafted by &lt;code&gt;quantproof ingest&lt;/code&gt; measures agreement with its drafting model until human review. One run: drafter got 1 of 22 expected values wrong. The provenance label exists because of that.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Run it on your task
&lt;/h2&gt;

&lt;p&gt;Node 22+, Ollama or Rapid-MLX. Out-of-memory failures are recorded as results, not crashes, and the same packs can also sweep Claude models over the Anthropic API when no GPU is around.&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/moonrunnerkc" rel="noopener noreferrer"&gt;
        moonrunnerkc
      &lt;/a&gt; / &lt;a href="https://github.com/moonrunnerkc/quantproof" rel="noopener noreferrer"&gt;
        quantproof
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Run your real task on quantized models and get measured quality, latency, and peak VRAM, plus the smallest quant that holds quality.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/moonrunnerkc/quantproof/docs/assets/cover.svg"&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%2Fmoonrunnerkc%2Fquantproof%2FHEAD%2Fdocs%2Fassets%2Fcover.svg" alt="QuantProof: measured quality, latency, and peak VRAM for quantized models on your own task" width="100%"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://www.npmjs.com/package/quantproof" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8b1624d5603d5d53b2799db0a158b85fe4b0e548d54a95b26fe325ec9b70854d/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f7175616e7470726f6f66" alt="npm version"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://github.com/moonrunnerkc/quantproof#why-measure" rel="noopener noreferrer"&gt;Why measure&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/quantproof#how-it-works" rel="noopener noreferrer"&gt;How it works&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/quantproof#case-study" rel="noopener noreferrer"&gt;Case study&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/quantproof#run-it-on-your-task" rel="noopener noreferrer"&gt;Run it on your task&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/quantproof#api-runs" rel="noopener noreferrer"&gt;API runs&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/quantproof#documentation" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;
&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;QuantProof&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Point QuantProof at a folder of real examples from your task, and it tells
you which quantized model performs best on your hardware.&lt;/p&gt;
&lt;p&gt;It measures, not estimates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Quality&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Peak VRAM usage&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then it recommends the smallest quantized model whose quality is within 2%
of the best-performing model.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why measure&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Fit calculators only tell you whether a model's weights will fit in memory
Benchmark leaderboards rank models on general tests, not your specific
workload.&lt;/p&gt;
&lt;p&gt;If your real question is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Will Q4_K_M hurt my invoice extraction accuracy?"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;there's only one reliable way to answer it: run your invoice extraction on
Q4_K_M and measure the results.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;QuantProof automates that process. It:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Tests candidate models one at a time&lt;/li&gt;
&lt;li&gt;Scores every output deterministically&lt;/li&gt;
&lt;li&gt;Measures latency and peak VRAM&lt;/li&gt;
&lt;li&gt;Reports…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/moonrunnerkc/quantproof" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/quantproof" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Run your own 20 examples&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>llm</category>
      <category>ollama</category>
    </item>
    <item>
      <title>AI Agents Cheat on Pull Requests. I Mined 327 of Them to Prove It.</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Thu, 09 Jul 2026 22:45:30 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/ai-agents-cheat-on-pull-requests-i-mined-327-of-them-to-prove-it-43ij</link>
      <guid>https://dev.to/moonrunnerkc/ai-agents-cheat-on-pull-requests-i-mined-327-of-them-to-prove-it-43ij</guid>
      <description>&lt;p&gt;AI coding agents cheat. Not maliciously, and usually not on purpose. They optimize for "looks done," because shipping code that &lt;em&gt;appears&lt;/em&gt; complete is easier than shipping code that &lt;em&gt;is&lt;/em&gt; complete. Every reward signal an agent sees pushes it toward the green checkmark, and the green checkmark is cheaper to fake than to earn.&lt;/p&gt;

&lt;p&gt;That was a curiosity when one engineer babysat one agent. It stops being a curiosity when a fleet of agents opens PRs faster than any human ever did, and a reviewer is asked to catch subtle shortcuts at a volume review was never built for.&lt;/p&gt;

&lt;p&gt;So I went and measured it. I mined &lt;strong&gt;327 agent-attributed pull requests&lt;/strong&gt; from public GitHub, looked for the ones maintainers publicly called out as cheating, and then tried to catch the same cheats with software. This post is what I found, including the parts that did not work.&lt;/p&gt;

&lt;h3&gt;
  
  
  What "cheating" actually means
&lt;/h3&gt;

&lt;p&gt;The word "cheating" invites eye-rolling AI-doom takes, so let me make it concrete. Here are real, recognizable patterns. Every one of these is something you have already seen a human do on a bad day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Swallowed errors.&lt;/strong&gt; The failure path is caught and dropped on the floor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;syncRemoteState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// handled&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing is handled. The test that expected no throw now passes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relaxed assertions.&lt;/strong&gt; A strict matcher becomes a loose one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- expect(result).toEqual({ id: 7, status: 'settled', total: 4200 });
&lt;/span&gt;&lt;span class="gi"&gt;+ expect(result).toBeTruthy();
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;{}&lt;/code&gt; is truthy. The test is now green for almost any output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assertion stripping.&lt;/strong&gt; The checks that actually pin behavior quietly disappear.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  const rows = await repo.findByOrg(orgId);
&lt;span class="gd"&gt;- expect(rows).toHaveLength(3);
- expect(rows[0].email).toBe('a@b.co');
&lt;/span&gt;&lt;span class="gi"&gt;+ expect(rows).toBeDefined();
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;No-op fix.&lt;/strong&gt; The PR claims to fix a bug. The source is untouched; only the test changed to stop failing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fake refactor.&lt;/strong&gt; A symbol is renamed at its definition, callers still reference the old name, and it only compiles because a type got loosened somewhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type/lint suppression.&lt;/strong&gt; A &lt;code&gt;@ts-ignore&lt;/code&gt; or &lt;code&gt;eslint-disable&lt;/code&gt; lands directly over the line that stopped type-checking after the change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gi"&gt;+ // @ts-ignore
&lt;/span&gt;  return handler(req as AuthedRequest);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;None of these are exotic. That is the point. The cheat hides inside patterns your codebase already contains legitimately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this matters &lt;em&gt;now&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Agents do not cheat more per PR than a rushed human does. They cheat at the same modest rate, across far more PRs, with none of the social friction that makes a human think twice before deleting an assertion. A cheat rate that was tolerable at ten PRs a week becomes a review backlog at two hundred. It is a signal-to-noise problem, and the noise floor is rising.&lt;/p&gt;

&lt;h3&gt;
  
  
  The data, honestly
&lt;/h3&gt;

&lt;p&gt;Of the 327 agent-attributed PRs I mined, &lt;strong&gt;27 (about 8%)&lt;/strong&gt; carried a maintainer complaint that named a cheat. Agents cheat in the wild, and maintainers do catch them: &lt;strong&gt;20 of the 27 were rejected at review.&lt;/strong&gt; The other &lt;strong&gt;7 merged anyway&lt;/strong&gt;, including on &lt;code&gt;microsoft/testfx&lt;/code&gt; and &lt;code&gt;outline/outline&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now the caveat that most AI posts skip. That 8% is a &lt;em&gt;loose&lt;/em&gt; bar: any maintainer comment naming a cheat counts, including terse ones and self-flags. When I re-audited the same 27 against a &lt;em&gt;strict&lt;/em&gt; independent-human bar (a second person, reading the actual diff, agreeing it is a cheat), only &lt;strong&gt;7 survived&lt;/strong&gt;. So the honest range is "8% by a generous reading, closer to 2% by a strict one." Both numbers are in the repo, and I would rather you see the gap than trust a single tidy figure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why your existing tools miss it
&lt;/h3&gt;

&lt;p&gt;Linters and SAST (Semgrep, ESLint security rules, and friends) do not catch these, because a cheat is usually &lt;em&gt;structurally valid code&lt;/em&gt;. An empty catch block is legal. A renamed function is legal. A loosened matcher is legal.&lt;/p&gt;

&lt;p&gt;Two of the merged examples above make the point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;microsoft/testfx#8513&lt;/code&gt; deleted a test in &lt;strong&gt;C#&lt;/strong&gt;, a language the structural detectors do not even parse.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;outline/outline#12197&lt;/code&gt; removed a single &lt;code&gt;jest.mock&lt;/code&gt; line. There is nothing malformed to match. The behavior changed; the syntax did not.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A pattern matcher keyed on "bad syntax" has nothing to grab onto. You need something that reasons about whether the diff delivers what the PR claims, and something that can run the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I built
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;Swarm Orchestrator&lt;/a&gt; is an open-source auditor for exactly this. It walks a PR diff through &lt;strong&gt;eleven cheat detectors&lt;/strong&gt; (test relaxation, mock-of-hallucination, assertion strip, no-op fix, swallowed error, dead-branch insertion, fake refactor, type suppression, and more), fingerprints which agent wrote the PR, and posts a finding back.&lt;/p&gt;

&lt;p&gt;The design rule is one sentence: &lt;strong&gt;flags are tips, blocks are proof.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detectors are &lt;strong&gt;advisory by default&lt;/strong&gt;. They flag cheat-shaped patterns and never block a merge on suspicion alone. No detector is allowed to block on its own opinion.&lt;/li&gt;
&lt;li&gt;A finding only escalates to a &lt;strong&gt;block&lt;/strong&gt; when the tool can reproduce a runtime proof in a fresh checkout: revert the suspicious hunk, rerun the suite, and confirm the code only "passed" because of the doctored change. The block ships with the exact command to reproduce it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It runs &lt;strong&gt;offline against a committed diff&lt;/strong&gt;, so nothing here is a number you have to take on faith:&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/moonrunnerkc/swarm-orchestrator
&lt;span class="nb"&gt;cd &lt;/span&gt;swarm-orchestrator &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build
git diff origin/main | node dist/src/cli.js audit &lt;span class="nt"&gt;--diff-stdin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The honest limitations
&lt;/h3&gt;

&lt;p&gt;This is the section that should make you trust the rest.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No detector clears the bar to auto-block.&lt;/strong&gt; Zero of eleven are gate-eligible. Every one is advisory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The proof gate proved zero of the 27 wild cheats on its own.&lt;/strong&gt; The kind of cheat a machine can prove without a human (a merged test-tamper whose restoration provably fails) simply did not occur in the sample it could execute. Cheats that need judgment to see stayed invisible to the gate, by design, because the gate refuses to fire on an accusation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There is a known false-positive class.&lt;/strong&gt; Refactors that &lt;em&gt;relocate&lt;/em&gt; test coverage (moving a check into a golden-file test the engine cannot see) once tripped a false proof. It is pinned by a regression test now, but it is a real limit, not a solved problem.&lt;/li&gt;
&lt;li&gt;The advisory tier is where the daily value lives: across the hunt it flagged 148 candidates and corroborated all 27 human-caught cheats. On a defect-injection corpus it recovers &lt;strong&gt;301 of 325 planted cheats (92.6%)&lt;/strong&gt;. Corroboration with a known ceiling, not a replacement for review.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The uncomfortable finding under all of this: agent cheating is common &lt;em&gt;and&lt;/em&gt; mostly the kind only a human currently catches. Automation can raise the signal and prove the rare merged case. It cannot yet stand in for the reviewer.&lt;/p&gt;

&lt;h3&gt;
  
  
  If you want to poke holes in it
&lt;/h3&gt;

&lt;p&gt;Run it against your own diffs. Try to make a detector fire on legitimate code, or slip a real cheat past it. Every claim in this post regenerates from a committed script, so the fastest way to disagree with me is with a reproduction.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;https://github.com/moonrunnerkc/swarm-orchestrator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is an open problem, not a finished product.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>agents</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Catching the shortcuts AI coding agents take to look done</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Fri, 05 Jun 2026 21:40:35 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/catching-the-shortcuts-ai-coding-agents-take-to-look-done-45mm</link>
      <guid>https://dev.to/moonrunnerkc/catching-the-shortcuts-ai-coding-agents-take-to-look-done-45mm</guid>
      <description>&lt;p&gt;A green test suite is supposed to mean the change works. It doesn't. A test can be weakened just enough to pass. An error can be caught and thrown away. A rename can stop halfway and still compile. None of that turns red, and none of it shows up in the linters most teams already run.&lt;/p&gt;

&lt;p&gt;Swarm Orchestrator is built to catch exactly that class of problem in AI-written pull requests.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
&lt;strong&gt;Two parts.&lt;/strong&gt; One audits AI-written PRs for the shortcuts that fake "done" (11 checks). The other gates a patch against a contract you define: it builds, passes tests, satisfies your requirement, and survives a falsifier that tries to break it.

&lt;p&gt;TypeScript, Node 20, ISC license. The audit side runs with no model credentials.&lt;br&gt;

&lt;/p&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  The gap linters leave
&lt;/h2&gt;

&lt;p&gt;Semgrep and ESLint are built around risky APIs and known-bad code patterns. Whether a diff is &lt;em&gt;honest&lt;/em&gt; is a different question. They won't tell you a test was edited until it passed, or that a &lt;code&gt;catch&lt;/code&gt; block quietly eats the error it caught. That's the gap.&lt;/p&gt;

&lt;p&gt;Two examples from merged Cloudflare pull requests:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PR&lt;/th&gt;
&lt;th&gt;Finding&lt;/th&gt;
&lt;th&gt;Semgrep + ESLint&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;workers-sdk#14063&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Function renamed, some callers still using the old name&lt;/td&gt;
&lt;td&gt;No finding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;workers-sdk#14132&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Empty catch block hiding errors&lt;/td&gt;
&lt;td&gt;No finding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Across 72 known-bad pull requests from 12 repositories, that pair of analyzers produced one finding. The auditor flagged 67.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the auditor checks
&lt;/h2&gt;

&lt;p&gt;Eleven checks total. Eight run by default. The other three exist but stay off, because they haven't shown useful signal on real pull requests yet, and a noisy check is worse than no check.&lt;/p&gt;

&lt;p&gt;The default set looks for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Errors caught and ignored&lt;/li&gt;
&lt;li&gt;Renames left unfinished&lt;/li&gt;
&lt;li&gt;Test coverage reduced&lt;/li&gt;
&lt;li&gt;Tests weakened&lt;/li&gt;
&lt;li&gt;Assertions removed&lt;/li&gt;
&lt;li&gt;New &lt;code&gt;@ts-ignore&lt;/code&gt; or &lt;code&gt;eslint-disable&lt;/code&gt; comments&lt;/li&gt;
&lt;li&gt;Test-only fixes with no code change behind them&lt;/li&gt;
&lt;li&gt;Mocks pointing at modules that don't exist&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Measured, not assumed
&lt;/h2&gt;

&lt;p&gt;The detection rate isn't a guess. Known defects get injected into real pull requests, then the auditor runs against them. It caught 253 of 300, or 84 percent.&lt;/p&gt;

&lt;p&gt;Reproduce it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run benchmarks:full
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Runtime mode (optional)
&lt;/h2&gt;

&lt;p&gt;The checks can also execute code instead of only reading a diff: mutation testing, coverage, and reproducing reported issues.&lt;/p&gt;

&lt;p&gt;On &lt;code&gt;trpc#6098&lt;/code&gt; it found mutations surviving on lines a later hotfix changed. The tests passed. They weren't actually exercising that code.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  Why this mode stays optional
  &lt;br&gt;
Running code is louder than reading a diff: it averages about 3.4 findings on a clean pull request. That noise is fine when you're deliberately hunting, but it's too much to leave on by default, so it's opt-in.&lt;br&gt;


&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Defining "done" with a contract
&lt;/h2&gt;

&lt;p&gt;The second command is &lt;code&gt;swarm run&lt;/code&gt;. You write down what done means:&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="na"&gt;obligations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build-must-pass&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-must-pass&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A patch is accepted only if every obligation passes and the falsifier can't break it. The default provider is deterministic, so identical inputs give identical results, and every input and hash gets written to a hash-chained ledger.&lt;/p&gt;
&lt;h2&gt;
  
  
  Blocking merges
&lt;/h2&gt;

&lt;p&gt;Findings are advisory out of the box. Gate mode can block a merge, but only on reproducible evidence. The structural checks throw too many false positives to trust as automatic blockers on their own.&lt;/p&gt;

&lt;p&gt;Right now no runtime signal has enough real-world evidence to justify auto-rejection, so the gate stays open and reports that fact directly instead of pretending otherwise.&lt;/p&gt;
&lt;h2&gt;
  
  
  Who it's for
&lt;/h2&gt;

&lt;p&gt;If you review a lot of AI-written pull requests and want signals the usual linters skip, that's the case this is built for. It also emits CycloneDX-ML and SPDX AI BOM documents with &lt;code&gt;--emit-aibom&lt;/code&gt;, supports TypeScript and JavaScript, and runs offline.&lt;/p&gt;

&lt;p&gt;It points reviewers at the code worth inspecting. It doesn't claim to prove anything bug-free.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;View the repo on GitHub&lt;/a&gt;
&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/moonrunnerkc" rel="noopener noreferrer"&gt;
        moonrunnerkc
      &lt;/a&gt; / &lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;
        swarm-orchestrator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Reviews pull requests for the shortcuts AI coding agents take to look done without being done: relaxed tests, swallowed errors, fake renames, 11 checks in all. Flags them for a human by default, or blocks the merge if you turn that on. Can also turn a goal into a checklist and only accept a patch once every check passes.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/moonrunnerkc/swarm-orchestrator/docs/assets/hero.svg"&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%2Fmoonrunnerkc%2Fswarm-orchestrator%2FHEAD%2Fdocs%2Fassets%2Fhero.svg" alt="Swarm Orchestrator" width="100%"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Swarm Orchestrator&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A CLI for auditing AI-generated PRs and grading patches against typed contracts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/moonrunnerkc/swarm-orchestrator/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b2fb74275f8f290e0e17da6c7b2b8ceecf7ef860624ee954342634379e92b7d6/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d6c6963656e7365266d6573736167653d49534326636f6c6f723d626c7565" alt="license ISC"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/package.json" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/65e1143f37f35b2f692fa7f512ab25981789cb40c23884114b252264acf3f1c7/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d6e6f6465266d6573736167653d253345253344253230323026636f6c6f723d336338373361" alt="node &gt;= 20"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/package.json" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f45c3031bd0c1aea772a330c3c72852af253199fad35f4a31cdf4e74789a4b01/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d76657273696f6e266d6573736167653d31312e312e3126636f6c6f723d323264336565" alt="version 11.1.1"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/benchmarks/results/AB-REPORT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2f31c035ec528ae829ed557db45c910db20902eb97f27480c9db81324ef9346f/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d6f7261636c65253230726563616c6c266d6573736167653d3834253235253230283235332532463330302926636f6c6f723d627269676874677265656e" alt="oracle recall 84% (253/300)"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/benchmarks/real-prs/REAL-WORLD-REPORT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fffb2faa74c149f4ac968bb0a16f0fb360329e8b405f17f2707edc99881df8d7/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d7265616c2d505225323066616c7365253230616c61726d73266d6573736167653d302e3131253246505226636f6c6f723d627269676874677265656e" alt="real-PR false alarms 0.11/PR"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/benchmarks/real-prs/v11-BENEFIT-REPORT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c42baf2f2499ee7d6e4fea4776d8cddf44be88a85b1153efc2f91aa083e928d9/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d7265616c2d505225323063686561747325323076732532306c696e74657273266d6573736167653d34253230636f6e6669726d65642532302853656d6772657025324245534c696e74253341253230312926636f6c6f723d627269676874677265656e" alt="real-PR cheats vs linters 4 confirmed (Semgrep+ESLint: 1)"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator#install" rel="noopener noreferrer"&gt;&lt;b&gt;Install&lt;/b&gt;&lt;/a&gt; ·
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator#quick-start" rel="noopener noreferrer"&gt;&lt;b&gt;Quick start&lt;/b&gt;&lt;/a&gt; ·
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator#what-this-does" rel="noopener noreferrer"&gt;&lt;b&gt;What it does&lt;/b&gt;&lt;/a&gt; ·
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator#results" rel="noopener noreferrer"&gt;&lt;b&gt;Results&lt;/b&gt;&lt;/a&gt; ·
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator#cheat-detectors" rel="noopener noreferrer"&gt;&lt;b&gt;Detectors&lt;/b&gt;&lt;/a&gt; ·
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator#ai-bom" rel="noopener noreferrer"&gt;&lt;b&gt;AI-BOM&lt;/b&gt;&lt;/a&gt; ·
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator#reference" rel="noopener noreferrer"&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What This Does&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Swarm Orchestrator reads a pull-request diff and flags the shortcuts an AI coding agent takes to look done without being done: relaxed tests, stripped assertions, swallowed errors, fake renames, eleven checks in all.
On a benchmark of planted cheats it recovers 253 of 300 (84%, up 20.5% from the prior version), and on real merged Cloudflare PRs it caught two cheats that Semgrep and the ESLint security rules missed, both reproducible offline.
Findings are advisory by default, so it never blocks a merge unless you turn that on.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Who it's for&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;You review AI-written PRs at volume and want a "this change may be gaming the tests" signal that ordinary linters do not give you.&lt;/li&gt;
&lt;li&gt;You have…&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/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>ai</category>
      <category>typescript</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>AI wrote the PR. How do you know it actually works?</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Wed, 03 Jun 2026 01:26:44 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/ai-wrote-the-pr-how-do-you-know-it-actually-works-40ai</link>
      <guid>https://dev.to/moonrunnerkc/ai-wrote-the-pr-how-do-you-know-it-actually-works-40ai</guid>
      <description>&lt;p&gt;AI agents open a lot of pull requests now. Most are fine. Some quietly cheat to make the checks go green: they delete the failing test, weaken an assertion, wrap the broken call in an empty &lt;code&gt;catch&lt;/code&gt; so the error disappears. The diff looks done. A reviewer skimming forty agent PRs a day will not catch that by eye.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;swarm audit&lt;/code&gt; is a command-line tool that does. I maintain it. It runs three jobs on AI-written code, all offline, no API key.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Catch the cheat
&lt;/h2&gt;

&lt;p&gt;Eleven checks read a pull-request diff and flag the shortcut patterns: a deleted test with no matching code change, a function renamed while its callers still use the old name, an error swallowed by an empty catch, a mock of a package that exists in no manifest, a type-checker suppression dropped over a changed line, and more.&lt;/p&gt;

&lt;p&gt;The detection is measured, not asserted. Hide one known cheat in each of 300 real merged PRs, run the auditor, count the catches: 254, about 85%, reproducible with one command.&lt;/p&gt;

&lt;p&gt;The catch that matters most is on real code. On two merged Cloudflare PRs it flagged a rename that left two callers pointing at a dead function, and an empty &lt;code&gt;catch {}&lt;/code&gt; that throws every error away. Semgrep (210 rules) and ESLint's security rules flagged neither, because they hunt for dangerous code like an injection or a leaked secret, and a deleted test is not dangerous code, it is missing code. The auditor also names the agent that wrote the PR: on a live fetch it tagged the author as Devin. Findings ship advisory, so it reports and never blocks your merge unless you ask it to.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Prove the change meets its spec
&lt;/h2&gt;

&lt;p&gt;The second mode runs before a change is accepted. You hand it a plain goal. It compiles that goal into a contract of machine-checkable obligations: build passes, tests pass, coverage holds, a named function has the right signature, a property holds, performance does not regress. Candidate patches get generated, and one is admitted only if it satisfies every obligation. Adversarial falsifiers actively try to break a patch before it counts.&lt;/p&gt;

&lt;p&gt;In a fresh project it compiled a goal into two obligations, verified both, confirmed nothing regressed after the merge, and spent zero tokens doing it. Turn on gate mode and it becomes a hard merge rule: a diff that strips a test exits non-zero and never lands.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Document it for compliance
&lt;/h2&gt;

&lt;p&gt;If you ship or buy AI-written code under the EU AI Act or CISA's SBOM-for-AI guidance, someone will ask for a record of the AI involvement. The tool emits one: a CycloneDX 1.6 ML bill-of-materials and an SPDX 3.0 AI-Profile, both valid against their specs, plus a hash-chained evidence ledger where altering any entry breaks the chain. It ships with the mappings to EU AI Act Annex IV and the CISA minimum elements.&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;git clone https://github.com/moonrunnerkc/swarm-orchestrator
&lt;span class="nb"&gt;cd &lt;/span&gt;swarm-orchestrator &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build

npm run benchmarks:oracle   &lt;span class="c"&gt;# the ~85% number&lt;/span&gt;
node dist/src/cli.js audit &lt;span class="nt"&gt;--diff-file&lt;/span&gt; benchmarks/real-prs/diffs/cloudflare-workers-sdk/14132.diff &lt;span class="nt"&gt;--detectors&lt;/span&gt; all
swarm init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; swarm run &lt;span class="nt"&gt;--goal&lt;/span&gt; &lt;span class="s2"&gt;"verify this project builds and tests pass"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open Source Repo: &lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;https://github.com/moonrunnerkc/swarm-orchestrator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Your AI's tests pass. That doesn't mean the code works.</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Sun, 31 May 2026 22:21:05 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/your-ais-tests-pass-that-doesnt-mean-the-code-works-239c</link>
      <guid>https://dev.to/moonrunnerkc/your-ais-tests-pass-that-doesnt-mean-the-code-works-239c</guid>
      <description>&lt;p&gt;You ask a coding agent to fix a bug. It writes the code, writes the tests, CI goes green, you merge. The bug's still there.&lt;/p&gt;

&lt;p&gt;The agent's job was to turn the check green. The honest way to do that is to fix the code. The lazy way is to write a test that passes no matter what the code does. CI can't tell those two apart. A green check means the tests passed, not that the code is right.&lt;/p&gt;

&lt;p&gt;It's easy to miss in review, because the test sits right there looking like proof:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parses the config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rawInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeDefined&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That passes whether &lt;code&gt;parseConfig&lt;/code&gt; works perfectly or returns nothing useful on every input. It checks nothing. Adding more tests like it just raises your coverage number, not your odds of catching a bad change.&lt;/p&gt;

&lt;p&gt;So I built ClaimCheck (&lt;a href="https://github.com/moonrunnerkc/claimcheck" rel="noopener noreferrer"&gt;https://github.com/moonrunnerkc/claimcheck&lt;/a&gt;). Instead of trusting the agent's tests, it tries to break them. If a test still passes after the supposedly fixed code is broken on purpose, the test was never really checking the fix, and it gets blocked. Same answer every time, no AI making the call. So far it's caught every cheat in a set of twelve hand-built cases. Twelve is small, and there's no public release yet, so treat that as a direction, not a finished result.&lt;/p&gt;

&lt;p&gt;Some cheats slip through anyway. If the agent writes a real, solid test that locks in the wrong answer, every check passes. The only way to know the answer's wrong is to already know the right one, and nothing in the pull request can tell you that except the agent you're trying to catch. The one thing that helps is a clue from outside it, like a human-written bug report you can run the fix against.&lt;/p&gt;

&lt;p&gt;There's a second, wider tool, Swarm Orchestrator (&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;https://github.com/moonrunnerkc/swarm-orchestrator&lt;/a&gt;). It flags suspicious changes and keeps a tamper-evident record for audits. The record-keeping is the solid part. The catching is not: on real pull requests its accuracy is still low, and that's the half I'm hardening now.&lt;/p&gt;

&lt;p&gt;The next step is comparing the old code's behavior to the new directly. The catch is that a wrong change and a harmless cleanup can look the same from the outside, and a tool that blocks good code is worse than one that lets a bad change through. That's the part I'm still working out.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Audit AI-Generated PRs Before You Merge Them (Swarm Orchestrator 10.3.0)</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Sun, 24 May 2026 20:54:59 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/audit-ai-generated-prs-before-you-merge-them-swarm-orchestrator-1030-3a6e</link>
      <guid>https://dev.to/moonrunnerkc/audit-ai-generated-prs-before-you-merge-them-swarm-orchestrator-1030-3a6e</guid>
      <description>&lt;p&gt;If you let Claude Code, Cursor, Devin, Aider, Copilot, or any other coding agent open PRs against your repo, you already know the problem. The diff looks fine on a fast read. CI is green. You merge it. A week later you find the test that "passed" got deleted, or the error handling is a silent &lt;code&gt;catch {}&lt;/code&gt;, or the "fix" was a comment swap that never touched the bug.&lt;/p&gt;

&lt;p&gt;Swarm Orchestrator looks at those PRs and flags the suspicious bits before you click merge.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;A CLI and a GitHub Action. Open source. Node 20 or later. You point it at a PR (or a local diff) and it scores the patch against a set of cheat-pattern detectors. It posts a comment back to the PR with what it found and why.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swarm audit moonrunnerkc/swarm-orchestrator#42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the whole interface for most people.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The default detector set has four checks, all aimed at patterns AI agents actually produce on real PRs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;error-swallow&lt;/code&gt;: a new empty or comment-only &lt;code&gt;catch&lt;/code&gt; block in non-test code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mock-of-hallucination&lt;/code&gt;: a &lt;code&gt;jest.mock&lt;/code&gt; or &lt;code&gt;vi.mock&lt;/code&gt; against a module that doesn't exist anywhere in the repo.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;no-op-fix&lt;/code&gt;: tests changed without source, or source changed without tests, when the diff claims to fix something.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fake-refactor&lt;/code&gt;: an exported symbol renamed in source, with no caller in the diff updated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Six more detectors live behind &lt;code&gt;--detectors experimental&lt;/code&gt; for shadow runs. They're not scored well enough on real PRs to be on by default, and the README says so.&lt;/p&gt;

&lt;p&gt;Every finding renders with its measured precision number inline, so a reviewer sees the false-positive rate every time the bot speaks.&lt;/p&gt;

&lt;p&gt;If you need compliance artifacts, &lt;code&gt;--emit-aibom cyclonedx-ml&lt;/code&gt; writes a CycloneDX 1.6 ML-BOM and an SPDX 3.0 AI-Profile per audit. That covers the EU AI Act Annex IV and CISA SBOM-for-AI minimums without bolting on a separate vendor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who it's for
&lt;/h2&gt;

&lt;p&gt;Teams that let AI agents open PRs and want a second pair of eyes that runs in CI, costs nothing per call, and produces a deterministic comment instead of vibes. Also useful for procurement and security folks who need an AI-BOM next to their SBOM and don't want another tool in the chain.&lt;/p&gt;

&lt;p&gt;If you have one developer eyeballing every line of every AI PR by hand, you probably don't need this yet. If you have ten agents pushing diffs to a queue at 2am, you do.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new in 10.3.0
&lt;/h2&gt;

&lt;p&gt;Four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;no-op-fix&lt;/code&gt; got a v2.0 with a gated LLM judge. The judge is off by default and only fires when you set &lt;code&gt;--enable-llm-judge&lt;/code&gt; (or &lt;code&gt;SWARM_AUDIT_LLM_JUDGE=1&lt;/code&gt;) and have an Anthropic key. Verdicts are content-addressed and cached, so the same diff and title always gets the same answer. The model id is pinned in the ledger so replay stays deterministic.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--shadow-output &amp;lt;path&amp;gt;&lt;/code&gt;. One JSON file per audit with detector verdicts, judge call count, and the rendered comment. Drops into a directory you can &lt;code&gt;jq&lt;/code&gt; later. The existing &lt;code&gt;--shadow &amp;lt;repo&amp;gt;&lt;/code&gt; per-repo rollup still works.&lt;/li&gt;
&lt;li&gt;Public leaderboard on GitHub Pages. Fetches the real-corpus score snapshot and renders precision, recall, F1, and a sortable per-detector table. No build step, no CDN, just an HTML page and one JS file: &lt;a href="https://moonrunnerkc.github.io/swarm-orchestrator/docs/leaderboard/" rel="noopener noreferrer"&gt;moonrunnerkc.github.io/swarm-orchestrator/docs/leaderboard/&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Real-corpus headline rescored against the v2.0 detectors. F1 moved from 0.109 (P 0.067, R 0.300) to 0.167 (P 0.100, R 0.500). &lt;code&gt;mock-of-hallucination&lt;/code&gt; picked up two true positives the v1 shape missed.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;The real-corpus F1 is 0.167 across 205 AI-labeled PRs (10 broken, 195 clean, eight agent vendors). Precision is 0.100. Recall is 0.500.&lt;/p&gt;

&lt;p&gt;That precision number is exactly why the default mode is &lt;code&gt;advise&lt;/code&gt; and not &lt;code&gt;gate&lt;/code&gt;. Most flags will be false positives. The tool is calibrated to be useful as a reviewer-assist signal, not a merge blocker. If you want it to block, opt in: &lt;code&gt;--mode gate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The 205-PR corpus is currently labeled by an AI judge with "pending human review" stamped on every entry. That's the largest credibility hole in the project and the next milestone closes it. The labeling rubric, the kappa script, and the labels-v2 scaffold already live in the repo.&lt;/p&gt;

&lt;p&gt;Don't read this as "ship this into your release gate today." Read it as "here's a tool you can run in shadow mode, look at what it flags, and decide for yourself if those flags are useful."&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;git clone https://github.com/moonrunnerkc/swarm-orchestrator.git
&lt;span class="nb"&gt;cd &lt;/span&gt;swarm-orchestrator
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run build
npm &lt;span class="nb"&gt;link&lt;/span&gt;

&lt;span class="c"&gt;# audit a PR (advisory, never blocks)&lt;/span&gt;
&lt;span class="nv"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;... swarm audit owner/repo#PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or wire it into a workflow with &lt;code&gt;uses: moonrunnerkc/swarm-orchestrator@main&lt;/code&gt; and &lt;code&gt;audit-mode: true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;https://github.com/moonrunnerkc/swarm-orchestrator&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Leaderboard: &lt;a href="https://moonrunnerkc.github.io/swarm-orchestrator/docs/leaderboard/" rel="noopener noreferrer"&gt;https://moonrunnerkc.github.io/swarm-orchestrator/docs/leaderboard/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Real-corpus score snapshot: &lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/blob/main/benchmarks/real-corpus/scores/latest.json" rel="noopener noreferrer"&gt;https://github.com/moonrunnerkc/swarm-orchestrator/blob/main/benchmarks/real-corpus/scores/latest.json&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CycloneDX 1.6 ML-BOM spec: &lt;a href="https://cyclonedx.org/specification/overview/" rel="noopener noreferrer"&gt;https://cyclonedx.org/specification/overview/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SPDX 3.0 AI Profile: &lt;a href="https://spdx.dev/use/specifications/" rel="noopener noreferrer"&gt;https://spdx.dev/use/specifications/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;EU AI Act Annex IV: &lt;a href="https://artificialintelligenceact.eu/annex/4/" rel="noopener noreferrer"&gt;https://artificialintelligenceact.eu/annex/4/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>githubactions</category>
      <category>devops</category>
    </item>
    <item>
      <title>Cryptographic Forensics for AI Coding Agent Sessions</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Wed, 20 May 2026 14:58:25 +0000</pubDate>
      <link>https://dev.to/aftermathtech/cryptographic-forensics-for-ai-coding-agent-sessions-2oaa</link>
      <guid>https://dev.to/aftermathtech/cryptographic-forensics-for-ai-coding-agent-sessions-2oaa</guid>
      <description>&lt;p&gt;A Claude Code or Codex CLI session writes a JSONL file to disk. If the agent runs &lt;code&gt;rm -rf&lt;/code&gt; on a training-data directory or &lt;code&gt;terraform destroy -auto-approve&lt;/code&gt; on production, that file is where an incident review starts.&lt;/p&gt;

&lt;p&gt;A JSONL file is not evidence. Anyone with shell access can rewrite it. To a third party who doesn't trust the machine it came from, it proves nothing.&lt;/p&gt;

&lt;p&gt;That gap matters once agents have credentials to real infrastructure. Most agent observability tooling is built for debugging and quality, not for the moment after damage is done. This post is about the three cryptographic properties that turn a transcript into something an auditor or regulator can verify, and how the DEPOSE project wires them together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three properties
&lt;/h2&gt;

&lt;p&gt;Assume the machine that produced the bundle can't be trusted. Three things need to hold at once:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tamper-evident.&lt;/strong&gt; Any byte change has to be detectable. Hash chain over events: change a byte, replay fails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authenticated.&lt;/strong&gt; The record has to be bound to a key the producer controls and publishes a fingerprint for. Ed25519 signatures over a manifest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anti-backdated.&lt;/strong&gt; A party other than the producer has to anchor the record in time. RFC 3161 tokens from a public TSA.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The primitives are old and well understood. The hard part is wiring them through a normalized event schema and shipping a verifier that doesn't depend on the producer's runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  No LLM in the signed path
&lt;/h2&gt;

&lt;p&gt;Every event is captured at execution time or normalized from the session JSONL, then committed to the hash chain. The human-readable narrative is generated separately, from deterministic Handlebars templates over the signed events. It's excluded from the root hash.&lt;/p&gt;

&lt;p&gt;If generated prose became part of the signed record, verification would depend on model behavior staying stable and reproducible. DEPOSE avoids that dependency. The signed record is event data and hashes. The prose is templated commentary with &lt;code&gt;[#evt-&amp;lt;ulid&amp;gt;]&lt;/code&gt; citations back to the signed events. You can rewrite the narrative without affecting verification. Change an event and verification fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in a bundle
&lt;/h2&gt;

&lt;p&gt;A DEPOSE bundle is a directory, not an opaque archive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;incident-01JABC.../
├── manifest.json            bundleId, rootHash, eventsJsonlSha256, sigs, timestamps
├── events.jsonl             every event in canonical JSON, byte-pinned by manifest
├── rules/destructive.yaml   ruleset used at reconstruction time
├── narrative.md / .html     templated prose with per-event citations
├── verify.txt               human-readable verification summary
├── artifacts/               captured file diffs, payloads
├── attestations/            Ed25519 signatures, RFC 3161 timestamp tokens
└── raw/                     source JSONL, shell history, capture records
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change a byte of &lt;code&gt;events.jsonl&lt;/code&gt;, &lt;code&gt;manifest.json&lt;/code&gt;, or &lt;code&gt;rules/destructive.yaml&lt;/code&gt; and verification fails. Canonical JSON follows RFC 8785 (JCS), which is what lets a Go verifier check a TypeScript-produced bundle without either side trusting the other's serializer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two binaries
&lt;/h2&gt;

&lt;p&gt;The producer is TypeScript. The verifier is a separately-built static Go binary, &lt;code&gt;depose-verify&lt;/code&gt;. The separation is deliberate: you hand the binary to whoever needs to check the bundle (auditor, opposing counsel, regulator, a customer's security team) and they run it on their own machine. No producer stack required.&lt;/p&gt;

&lt;p&gt;A passing run prints:&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="go"&gt;parse        OK
signature    OK
chain-replay OK
artifacts    OK
timestamp    OK
PASS  bundleId=...  rootHash=...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cryptography here is mostly off-the-shelf. The actual engineering work is in normalization: getting Go and Node to serialize identically, getting timing and ordering right across capture sources, deciding what counts as one event versus two. Canonical JSON is the unsexy part. Float formatting, key ordering, unicode escapes: Go and Node have to agree byte-for-byte or the verifier rejects a bundle the producer thinks is fine. That's what the cross-language conformance vectors in &lt;code&gt;tests/conformance/&lt;/code&gt; are for.&lt;/p&gt;

&lt;p&gt;Verifiers can pin a producer's expected key fingerprint and consult a revocation list, both at the command line. The RFC 3161 timestamp does double duty here: a bundle stamped before a key is revoked stays time-anchored, so "when was this signed" remains answerable even if the key is later compromised.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capture modes
&lt;/h2&gt;

&lt;p&gt;Two modes, different coverage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reconstruction&lt;/strong&gt; reads the Claude Code session JSONL after the fact, compares it against shell history (bash, zsh, fish) and git reflog where available, and builds a bundle. Lower-bound mode. It can verify integrity after packaging. It can't prove the original session file was complete before capture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Active capture&lt;/strong&gt; installs a Claude Code &lt;code&gt;PreToolUse&lt;/code&gt; hook and POSIX shell shims for the binaries that tend to do destructive things: &lt;code&gt;terraform&lt;/code&gt;, &lt;code&gt;aws&lt;/code&gt;, &lt;code&gt;gh&lt;/code&gt;, &lt;code&gt;kubectl&lt;/code&gt;, &lt;code&gt;psql&lt;/code&gt;, &lt;code&gt;gcloud&lt;/code&gt;, &lt;code&gt;railway&lt;/code&gt;, &lt;code&gt;rm&lt;/code&gt;. Records land under &lt;code&gt;~/.depose/captures/&lt;/code&gt; at execution time. A later &lt;code&gt;depose package&lt;/code&gt; merges them with the session JSONL so every covered event has a verified pre-execution intent on record.&lt;/p&gt;

&lt;p&gt;DEPOSE can prove integrity of captured events. It can't prove an uninstrumented system captured everything. An agent that shells out to a binary not in the shim list, or hits an API directly, still shows up in the JSONL but won't have an active-capture record. The coverage matrix is in the repo.&lt;/p&gt;

&lt;p&gt;macOS and Linux only. Windows isn't supported (POSIX 0600 on the key store, POSIX shell scripts for the shims). WSL2 works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Release pipeline
&lt;/h2&gt;

&lt;p&gt;Releases ship with SBOMs, provenance attestations, and signed checksums. The specifics: CycloneDX for both halves, SLSA L3 provenance, and &lt;code&gt;SHA256SUMS&lt;/code&gt; signed via cosign keyless. CI rebuilds the two checked-in example bundles (an &lt;code&gt;rm -rf&lt;/code&gt; on training data, a &lt;code&gt;terraform destroy&lt;/code&gt; on infrastructure) on every push and runs three semantic tamper rejections to confirm the verifier fails closed.&lt;/p&gt;




&lt;p&gt;Right now most coding-agent session logs are treated like disposable debug output. That assumption gets weaker the moment an agent can modify infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Aftermath-Technologies-Ltd/depose" rel="noopener noreferrer"&gt;https://github.com/Aftermath-Technologies-Ltd/depose&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>Gemma.Witness - Offline Multimodal Evidence Capture with Gemma 4</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Sun, 17 May 2026 03:43:46 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/gemmawitness-offline-multimodal-evidence-capture-with-gemma-4-2d53</link>
      <guid>https://dev.to/moonrunnerkc/gemmawitness-offline-multimodal-evidence-capture-with-gemma-4-2d53</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Build with Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Gemma.Witness is an offline-first multimodal evidence capture system built for environments where cloud access, trust, or chain-of-custody assumptions fail.&lt;/p&gt;

&lt;p&gt;The system records audio alongside supporting images, runs local multimodal analysis through Gemma 4, and produces a signed evidence bundle containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structured incident reports&lt;/li&gt;
&lt;li&gt;Timestamped evidence metadata&lt;/li&gt;
&lt;li&gt;Local reasoning traces&lt;/li&gt;
&lt;li&gt;Hash-linked verification artifacts&lt;/li&gt;
&lt;li&gt;Exportable forensic bundles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The focus was reliability and local verification instead of "AI assistant" behavior.&lt;/p&gt;

&lt;p&gt;Most evidence tooling today assumes internet access, centralized APIs, or mutable storage. Gemma.Witness was designed around the opposite assumption: the network may be unavailable, the machine may be isolated, and every generated output may eventually need independent verification.&lt;/p&gt;

&lt;p&gt;The application runs fully local through a desktop interface using Rust, Tauri, and local inference orchestration.&lt;/p&gt;

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

&lt;p&gt;github: &lt;a href="https://github.com/moonrunnerkc/gemma-witness" rel="noopener noreferrer"&gt;https://github.com/moonrunnerkc/gemma-witness&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Source code is available at the repository above.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Gemma 4
&lt;/h2&gt;

&lt;p&gt;Gemma 4 is the reasoning layer behind the entire evidence pipeline.&lt;/p&gt;

&lt;p&gt;I used Gemma 4's multimodal capabilities to process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audio-derived transcripts&lt;/li&gt;
&lt;li&gt;Scene images&lt;/li&gt;
&lt;li&gt;Cross-evidence consistency analysis&lt;/li&gt;
&lt;li&gt;Structured incident extraction&lt;/li&gt;
&lt;li&gt;Reasoning trace generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model is used in a multi-pass workflow instead of a single prompt-response cycle. Each pass validates or expands on the previous stage before the final signed bundle is emitted.&lt;/p&gt;

&lt;p&gt;This matters because evidence systems fail quietly when models hallucinate details, merge assumptions into facts, or overstate certainty. The pipeline was intentionally designed to separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raw observations&lt;/li&gt;
&lt;li&gt;Inferred conclusions&lt;/li&gt;
&lt;li&gt;Confidence scoring&lt;/li&gt;
&lt;li&gt;Verifiable artifacts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemma 4 was a strong fit because it could operate locally while still handling multimodal reasoning tasks without requiring cloud APIs or external orchestration services.&lt;/p&gt;

&lt;p&gt;The project prioritizes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Offline operation&lt;/li&gt;
&lt;li&gt;Verifiable outputs&lt;/li&gt;
&lt;li&gt;Local ownership of evidence&lt;/li&gt;
&lt;li&gt;Minimal trust assumptions&lt;/li&gt;
&lt;li&gt;Reproducible forensic artifacts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A surprising challenge was not getting the model to generate reports. That part was easy.&lt;/p&gt;

&lt;p&gt;The difficult part was building guardrails around evidence integrity so the system does not quietly become a very confident fiction generator wearing a necktie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Gemma 4&lt;/li&gt;
&lt;li&gt;Rust&lt;/li&gt;
&lt;li&gt;Tauri&lt;/li&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Local multimodal inference&lt;/li&gt;
&lt;li&gt;Cryptographic hashing and bundle verification&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Repository
&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/moonrunnerkc" rel="noopener noreferrer"&gt;
        moonrunnerkc
      &lt;/a&gt; / &lt;a href="https://github.com/moonrunnerkc/gemma-witness" rel="noopener noreferrer"&gt;
        gemma-witness
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Offline multimodal evidence capture that emits a signed, locally verifiable .witness bundle. Tauri + Rust + Gemma 4 + Ed25519. Static HTML verifier runs with no server.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/moonrunnerkc/gemma-witness/docs/cover.svg"&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%2Fmoonrunnerkc%2Fgemma-witness%2FHEAD%2Fdocs%2Fcover.svg" alt="Gemma.Witness: offline, multimodal, tamper-evident evidence capture" width="100%"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Gemma.Witness&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;
  Offline, tamper-evident evidence capture for field journalism. Signed in your hand, verified in a browser, with no server in the loop
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness/LICENSE" rel="noopener noreferrer"&gt;&lt;img alt="License: MIT" src="https://camo.githubusercontent.com/61e87a946e1d1e4f95e16a52e349a61c65e00addb6e1f6352e004edb7b00f251/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d3764643366633f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/56affe7b8dd50ea73a7fdf8d92fc10df1d58a8771f211c9e945e2de0b22c9fb9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f727573742d312e38302532422d3161323534383f7374796c653d666c61742d737175617265266c6f676f3d72757374266c6f676f436f6c6f723d666666666666"&gt;&lt;img alt="Rust 1.80+" src="https://camo.githubusercontent.com/56affe7b8dd50ea73a7fdf8d92fc10df1d58a8771f211c9e945e2de0b22c9fb9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f727573742d312e38302532422d3161323534383f7374796c653d666c61742d737175617265266c6f676f3d72757374266c6f676f436f6c6f723d666666666666"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/3d0ddbbe52ba06ef509b8814cc17cc0b1ffbfe2c08554b1c96a1dee2dbef60e7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d32322e782d3161323534383f7374796c653d666c61742d737175617265266c6f676f3d6e6f64652e6a73266c6f676f436f6c6f723d666666666666"&gt;&lt;img alt="Node 22" src="https://camo.githubusercontent.com/3d0ddbbe52ba06ef509b8814cc17cc0b1ffbfe2c08554b1c96a1dee2dbef60e7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d32322e782d3161323534383f7374796c653d666c61742d737175617265266c6f676f3d6e6f64652e6a73266c6f676f436f6c6f723d666666666666"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/40ee04c06557c4dae7dcd7dcc2e96ac467317a2e7dbec324f892d71b746f5db6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74617572692d322e782d3161323534383f7374796c653d666c61742d737175617265266c6f676f3d7461757269266c6f676f436f6c6f723d666666666666"&gt;&lt;img alt="Tauri 2" src="https://camo.githubusercontent.com/40ee04c06557c4dae7dcd7dcc2e96ac467317a2e7dbec324f892d71b746f5db6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74617572692d322e782d3161323534383f7374796c653d666c61742d737175617265266c6f676f3d7461757269266c6f676f436f6c6f723d666666666666"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/cf681d7792cecf4a73b78f013297fb124c0fba63ad8e10fb3c1234fb03537845/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374617475732d626574612d3362383266363f7374796c653d666c61742d737175617265"&gt;&lt;img alt="Status: beta" src="https://camo.githubusercontent.com/cf681d7792cecf4a73b78f013297fb124c0fba63ad8e10fb3c1234fb03537845/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374617475732d626574612d3362383266363f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
&lt;/p&gt;




  
    
    &lt;span class="m-1"&gt;demo.mov&lt;/span&gt;
    
  

  

  





&lt;p&gt;
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#why-this-matters" rel="noopener noreferrer"&gt;Why&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#status" rel="noopener noreferrer"&gt;Status&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#installation" rel="noopener noreferrer"&gt;Install&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#configuration" rel="noopener noreferrer"&gt;Configuration&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#threat-model" rel="noopener noreferrer"&gt;Threat model&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#current-limitations" rel="noopener noreferrer"&gt;Limitations&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#what-you-can-verify-yourself" rel="noopener noreferrer"&gt;Verify yourself&lt;/a&gt; ·
  &lt;a href="https://github.com/moonrunnerkc/gemma-witness#contributing" rel="noopener noreferrer"&gt;Contributing&lt;/a&gt;
&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why this matters&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;A reporter is working in a country where journalists are detained for their reporting. She records a witness account. She attaches the photos she just took. She seals the file before she leaves the room.&lt;/p&gt;

&lt;p&gt;A week later, an editor on another continent opens a single static HTML page in any browser and drags the file in. Three checks turn green:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the signature comes from the reporter's device&lt;/li&gt;
&lt;li&gt;the audio and the photos have not been altered by a single byte&lt;/li&gt;
&lt;li&gt;the AI model in the chain is bit-for-bit the published Gemma model her manifest names, by &lt;code&gt;model_id&lt;/code&gt;, &lt;code&gt;revision&lt;/code&gt;, and &lt;code&gt;model.safetensors&lt;/code&gt; SHA-256&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/moonrunnerkc/gemma-witness" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>gemma</category>
      <category>ai</category>
      <category>rust</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Swarm Orchestrator v8.0.2</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Tue, 12 May 2026 02:31:18 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/swarm-orchestrator-v802-pf</link>
      <guid>https://dev.to/moonrunnerkc/swarm-orchestrator-v802-pf</guid>
      <description>&lt;p&gt;v8.0.2 is out now and it cleans up several rough edges that kept showing up under heavy tournament and falsification workloads.&lt;/p&gt;

&lt;p&gt;The biggest operational change is that all four previously documented architectural limitations are now closed in the same release (7b68867).&lt;/p&gt;

&lt;h2&gt;
  
  
  Notable Changes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tournament mode now streams through the same pipeline as single mode. If one candidate fails streaming verification, it gets aborted independently instead of poisoning the whole run.&lt;/li&gt;
&lt;li&gt;Live cost-cap enforcement is now real-time. Concurrent streams project cumulative USD usage continuously and abort the moment projected spend crosses the configured cap.&lt;/li&gt;
&lt;li&gt;Snapshot cleanup is automatic now and supports retention policies like:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  retain-last:N
  max-age:&amp;lt;dur&amp;gt;
  max-disk:&amp;lt;sz&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Adaptive falsifier dispatch using UCB1 is available behind:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--falsifier-scheduler&lt;/span&gt; ucb1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ARIES-style rollback support landed for falsified obligations. If a counter-example appears after apply, the workspace restores from the pre-apply snapshot and verifies the rollback by hashing the restored bytes against the original SHA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  New Command
&lt;/h2&gt;

&lt;p&gt;There is also a new command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swarm v8 stats &amp;lt;run-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That surfaces persisted falsifier metrics directly from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;.swarm/falsifier-stats.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;including regression discoveries, false positives, success counts, and latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replay Determinism
&lt;/h2&gt;

&lt;p&gt;One important detail: replay determinism remains intact across all of this. Every scheduler decision and abort event still lands in the ledger so replay reproduces the same winner consistently. That part was non-negotiable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Release
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/" rel="noopener noreferrer"&gt;https://github.com/moonrunnerkc/swarm-orchestrator/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>devops</category>
    </item>
    <item>
      <title>How Swarm Orchestrator v8 Tries to Break Its Own AI Patches</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Sun, 10 May 2026 02:10:05 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/how-swarm-orchestrator-v8-tries-to-break-its-own-ai-patches-2513</link>
      <guid>https://dev.to/moonrunnerkc/how-swarm-orchestrator-v8-tries-to-break-its-own-ai-patches-2513</guid>
      <description>&lt;p&gt;Most AI coding tools commit when their own checks pass. Swarm Orchestrator v8 adds a second adversarial layer: independent falsifier adapters that try to break each patch before it merges. v8.0.1 is on &lt;code&gt;main&lt;/code&gt; with that subsystem on by default.&lt;/p&gt;

&lt;p&gt;This post walks through the v8 architecture, the four verification points, the producer/falsifier adapter split, and the limitations that haven't been solved in v8.0 yet.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
&lt;strong&gt;What is Swarm Orchestrator?&lt;/strong&gt; A contract-first AI coding swarm with hash-chained evidence and verifier-gated commits. It compiles a natural-language goal into a typed contract, dispatches it to a population of personas inside one cached Anthropic session, races candidate diffs per obligation, and commits only what passes verification. It wraps an LLM; it doesn't replace one.&lt;br&gt;

&lt;/div&gt;


&lt;h2&gt;
  
  
  The shape of a run
&lt;/h2&gt;

&lt;p&gt;You hand it a goal in plain English. The contract compiler turns that into &lt;code&gt;contract.jsonl&lt;/code&gt; plus a &lt;code&gt;manifest.json&lt;/code&gt; carrying the goal, repo context, extractor provenance, and a SHA-256 of the canonical contract bytes. Identical inputs produce identical contract hashes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;goal (text)
   |
   v
contract compiler  -&amp;gt;  contract.jsonl + manifest.json
   |
   v
+-------------------------------------------------+
|        population manager (single session)      |
|                                                 |
|  ledger (jsonl, hash-chain) &amp;lt;- personas (8)     |
|       ^                          |              |
|       | tournament + verifier scoring           |
|       |                                         |
|  WASM deterministic floor (zero-LLM obligs)     |
+-------------------------------------------------+
   |                              |
   v                              v
streaming verifier      post-merge integration
   |                              |
   +--------------+---------------+
                  v
       falsifier adapters (Codex, Copilot)
                  |
                  v
            committed diffs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The population manager opens one cached Anthropic session and walks each obligation. It picks the persona whose trigger predicate matches the obligation type. In tournament mode, N candidates run in parallel; the verifier scores them, the top scorer is a commit candidate, and losers get logged but never merge.&lt;/p&gt;
&lt;h2&gt;
  
  
  Two adapter subsystems
&lt;/h2&gt;

&lt;p&gt;The most common confusion in v6 was treating the coding CLIs and the falsifiers as one thing. v8 splits them cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Producer adapters&lt;/strong&gt; (&lt;code&gt;src/adapters/&lt;/code&gt;) wrap third-party coding CLIs as the worker in the v6 verified-branch pipeline. Backends: Copilot, Claude Code, Codex, Claude Code Teams. All four are opt-in via &lt;code&gt;swarm run --v6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Falsifier adapters&lt;/strong&gt; (&lt;code&gt;src/falsification/adapters/&lt;/code&gt;) take a patch the producer's verifier already accepted and try to falsify the obligation by surfacing a counter-example, regression fixture, or property-violation trace. A confirmed counter-example flips the obligation back to &lt;code&gt;failed&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Falsifier&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Obligation types&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodexFalsifier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;on&lt;/td&gt;
&lt;td&gt;&lt;code&gt;property-must-hold&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CopilotFalsifier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;on&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;import-graph-must-satisfy&lt;/code&gt;, &lt;code&gt;function-must-have-signature&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ClaudeCodeFalsifier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;off (per-adapter opt-in)&lt;/td&gt;
&lt;td&gt;all three&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The CLI surface is one flag: &lt;code&gt;--falsifiers &amp;lt;on|off&amp;gt;&lt;/code&gt; (default on). Per-adapter selection happens at the API layer via &lt;code&gt;defaultAdapterRegistry({ includeCopilot, includeClaudeCode })&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Four verification points
&lt;/h2&gt;

&lt;p&gt;A patch has to survive these before it merges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pre-generation memoization.&lt;/strong&gt; Skip generation if the obligation result is already cached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mid-stream abort.&lt;/strong&gt; During generation, the streaming verifier can abort the call. Works in &lt;code&gt;--mode single&lt;/code&gt; only; tournament mode skips it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post-generation per-obligation verifier.&lt;/strong&gt; Scores the candidate diff. In tournament mode, top scorer wins; in single mode it's pass/fail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post-merge integration check.&lt;/strong&gt; After the diff lands, the integration check confirms the broader system still holds.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The architectural rule from the README: nothing commits without passing the obligation's verifier. Then the falsifiers get a shot.&lt;/p&gt;
&lt;h2&gt;
  
  
  The hash-chained ledger
&lt;/h2&gt;

&lt;p&gt;Every action lands in &lt;code&gt;.swarm/ledger/&amp;lt;run-id&amp;gt;.jsonl&lt;/code&gt; with the SHA of the prior entry. Tampering is detectable; runs resume from any prior state. If a process is killed mid-run, &lt;code&gt;swarm v8 resume &amp;lt;run-id&amp;gt;&lt;/code&gt; walks the ledger and picks up where it left off.&lt;/p&gt;

&lt;p&gt;The ledger format is shared with v6, but v8 writes more granular events (per-persona dispatch, per-candidate score, falsifier verdict) so a run can be replayed or audited end-to-end.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick start
&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/moonrunnerkc/swarm-orchestrator.git
&lt;span class="nb"&gt;cd &lt;/span&gt;swarm-orchestrator &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;link&lt;/span&gt;

&lt;span class="c"&gt;# Compile a goal, then run it&lt;/span&gt;
swarm v8 compile &lt;span class="s2"&gt;"add a /health endpoint that returns 200 OK"&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
swarm v8 run .swarm/contracts/&amp;lt;contract-id&amp;gt;

&lt;span class="c"&gt;# Or both in one step (defaults to v8)&lt;/span&gt;
swarm run &lt;span class="nt"&gt;--goal&lt;/span&gt; &lt;span class="s2"&gt;"add a /health endpoint that returns 200 OK"&lt;/span&gt;

&lt;span class="c"&gt;# Resume a killed run&lt;/span&gt;
swarm v8 resume &amp;lt;run-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Requires Node &amp;gt;= 20, git &amp;gt;= 2.40, and &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;. Pass &lt;code&gt;--extractor stub --session stub&lt;/code&gt; to run offline.&lt;/p&gt;

&lt;p&gt;There's also a GitHub Action:&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;moonrunnerkc/swarm-orchestrator@v8&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;goal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;add&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/health&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;endpoint"&lt;/span&gt;
    &lt;span class="na"&gt;contract-only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;cost-cap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5.00"&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ANTHROPIC_API_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  What v8.0 doesn't do
&lt;/h2&gt;

&lt;p&gt;&lt;/p&gt;
  Limitations worth reading before adopting
  &lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tournament mode doesn't stream.&lt;/strong&gt; &lt;code&gt;--mode tournament&lt;/code&gt; plus &lt;code&gt;--forbid-import&lt;/code&gt; skips the streaming abort; streaming verification is &lt;code&gt;--mode single&lt;/code&gt; only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post-merge failure doesn't auto-rollback.&lt;/strong&gt; The run is marked failed; per-obligation worktree snapshots are post-v8.0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--cost-cap&lt;/code&gt; is enforced post-obligation, not mid-call.&lt;/strong&gt; Cumulative spend is checked at the end of each obligation against estimated Sonnet 4 pricing. Exit code 6 if exceeded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bandit dispatch is not built (Phase 5).&lt;/strong&gt; Codex and Copilot have disjoint obligation types, so there's nothing to arbitrate between yet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cross-vendor producer race is deferred (Phase 6).&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full list with rationale lives in &lt;code&gt;docs/v8-architecture-deviations.md&lt;/code&gt;.&lt;/p&gt;



&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Repo
&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/moonrunnerkc" rel="noopener noreferrer"&gt;
        moonrunnerkc
      &lt;/a&gt; / &lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;
        swarm-orchestrator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Contract-first AI coding swarm with hash-chained evidence. Compiles a goal into typed obligations, races persona candidates per obligation in a single cached inference session, verifies before commit, and logs every action in an append-only ledger.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/moonrunnerkc/swarm-orchestrator/assets/header.svg"&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%2Fmoonrunnerkc%2Fswarm-orchestrator%2FHEAD%2Fassets%2Fheader.svg" alt="Swarm Orchestrator" width="100%"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Swarm Orchestrator&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Contract-first AI coding swarm with hash-chained evidence and verifier-gated commits.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fc208599ef300dfbb7d7b65c32d4e1364b62c8c0bd3cc6df8a16615f7ccd9991/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4953432d626c75653f7374796c653d666c61742d737175617265" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/package.json" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/37e12b341829a2c53b69b36b6fe5a9a4f42cf56b82722fac6b5011085a3749e6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d25334525334432302d3333393933333f7374796c653d666c61742d737175617265" alt="Node"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3f31914b57bc82fa5dcbe2b429e1d486362f11bfa4411282ff311f2885102e19/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6f6f6e72756e6e65726b632f737761726d2d6f7263686573747261746f722f63692e796d6c3f6272616e63683d6d61696e266c6162656c3d6369267374796c653d666c61742d737175617265" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/moonrunnerkc/swarm-orchestrator/package.json" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4aea3e72d83f2dd34ce19e0393e3a10766f325d0d6356fc71c7c190676acf5e2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7061636b6167652d6a736f6e2f762f6d6f6f6e72756e6e65726b632f737761726d2d6f7263686573747261746f723f7374796c653d666c61742d737175617265" alt="Version"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;swarm&lt;/code&gt; compiles a natural-language goal into a typed contract, dispatches it to a
population of personas inside one cached Anthropic session, races candidate diffs per
obligation, and commits only the diffs that pass verification. After the producer's
verifier accepts a patch, registered falsifier adapters get a chance to break it
before it merges. Every action lands in an append-only hash-chained ledger you can
audit, resume, or replay.&lt;/p&gt;
&lt;p&gt;It wraps an LLM; it does not replace one. The model writes the code, the orchestrator
decides what reaches your repo.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Status&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Version &lt;code&gt;8.0.1&lt;/code&gt; on &lt;code&gt;main&lt;/code&gt;. Node &lt;code&gt;&amp;gt;= 20&lt;/code&gt; (CI matrix: 20, 22). License ISC. The v8
architecture is the default for &lt;code&gt;swarm run&lt;/code&gt;; the v6 verified-branch pipeline is
preserved under &lt;code&gt;swarm run --v6&lt;/code&gt; and the &lt;code&gt;swarm swarm&lt;/code&gt; / &lt;code&gt;swarm execute&lt;/code&gt; commands
Falsifier subsystem: Codex on, Copilot on, ClaudeCode…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/moonrunnerkc/swarm-orchestrator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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