<?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>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>
    <item>
      <title>How to Write a CLAUDE.md Rule That Actually Gets Enforced</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Sun, 10 May 2026 02:06:45 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/how-to-write-a-claudemd-rule-that-actually-gets-enforced-3npa</link>
      <guid>https://dev.to/moonrunnerkc/how-to-write-a-claudemd-rule-that-actually-gets-enforced-3npa</guid>
      <description>&lt;p&gt;Open a CLAUDE.md file at random and you'll find build commands, architecture notes, and rules. The rules tend to be the unenforceable kind. "Write clean code." "Be careful with types." "Follow our conventions." The author meant every word. The agent reads them. And nothing checks whether the agent followed them, because nothing can.&lt;/p&gt;

&lt;p&gt;In a corpus of 580 CLAUDE.md, AGENTS.md, and &lt;code&gt;.cursorrules&lt;/code&gt; files from public GitHub repos with 10+ stars, &lt;strong&gt;74% contained zero machine-extractable rules&lt;/strong&gt;. Not because the authors didn't care about rules. Because most rules were written in a form no parser could pull out as a deterministic check.&lt;/p&gt;

&lt;p&gt;This post is about the difference. Specifically: how to phrase a rule so a parser can extract it and a verifier can check it, without sacrificing what you actually meant.&lt;/p&gt;

&lt;h2&gt;
  
  
  The principle
&lt;/h2&gt;

&lt;p&gt;Enforceability comes from a verifiable surface. A rule is verifiable when there's a concrete pattern in code that either matches it or doesn't. "Use &lt;code&gt;camelCase&lt;/code&gt; for function names" is verifiable: read the AST, list the function names, check the casing. "Name things consistently" is not: there's no concrete pattern to check, only a judgment to make.&lt;/p&gt;

&lt;p&gt;The gap between the two is the gap between intent and enforcement. You meant the same thing in both cases. But only one of them survives translation into a check.&lt;/p&gt;

&lt;p&gt;Here's the heuristic I use: &lt;strong&gt;could a junior engineer with no context mechanically check whether code follows this rule, just by reading the rule and looking at the code?&lt;/strong&gt; If yes, the rule is enforceable. If they'd have to ask "what does 'consistent' mean here?", it isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three pairs, walked through
&lt;/h2&gt;

&lt;p&gt;Take a few common intents and look at how they fail or succeed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type safety.&lt;/strong&gt; You want strong typing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bad:  Be careful with types.
Good: No `any` types in `src/`. Async functions require explicit return types.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bad version has no surface. "Careful" isn't a check. The good version has two: a forbidden token (&lt;code&gt;any&lt;/code&gt;) and a structural property (return type annotation on async function declarations). Both check directly against the AST.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Module structure.&lt;/strong&gt; You want predictable imports and exports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bad:  Prefer clean module structure.
Good: Named exports only. No default exports. Filenames in kebab-case.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Clean" is meaningless to a parser. Named-only and kebab-case are both binary properties of code that exist or don't. The first version sounds like more guidance because it's broader, but breadth is the problem: it covers everything and enforces nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preferences over alternatives.&lt;/strong&gt; You want React functional components, not class components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bad:  Write modern React.
Good: Prefer functional components over class components.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Modern" is a moving target with no fixed surface. The "prefer X over Y" pattern, on the other hand, has a clean check: count instances of each, compute a ratio, score against a threshold. This is one of the most useful patterns in instruction files because it captures real-world preference (not absolute prohibition) in a measurable way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reference table
&lt;/h2&gt;

&lt;p&gt;Twelve common intents, paired:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Intent&lt;/th&gt;
&lt;th&gt;Unenforceable&lt;/th&gt;
&lt;th&gt;Enforceable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Naming functions&lt;/td&gt;
&lt;td&gt;Name things consistently&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;camelCase&lt;/code&gt; for function names&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Filenames&lt;/td&gt;
&lt;td&gt;Pick reasonable filenames&lt;/td&gt;
&lt;td&gt;All filenames in kebab-case&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type safety&lt;/td&gt;
&lt;td&gt;Be careful with types&lt;/td&gt;
&lt;td&gt;No &lt;code&gt;any&lt;/code&gt; types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Async return types&lt;/td&gt;
&lt;td&gt;Make types clear&lt;/td&gt;
&lt;td&gt;Async functions require explicit return types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Module exports&lt;/td&gt;
&lt;td&gt;Prefer clean module structure&lt;/td&gt;
&lt;td&gt;Named exports only, no default exports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File size&lt;/td&gt;
&lt;td&gt;Keep files manageable&lt;/td&gt;
&lt;td&gt;Maximum 300 lines per file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logging&lt;/td&gt;
&lt;td&gt;Be mindful of logging&lt;/td&gt;
&lt;td&gt;Never use &lt;code&gt;console.log&lt;/code&gt;; use &lt;code&gt;src/logger.ts&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Component style&lt;/td&gt;
&lt;td&gt;Write modern React&lt;/td&gt;
&lt;td&gt;Prefer functional components over class components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Package manager&lt;/td&gt;
&lt;td&gt;Use the right package manager&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;pnpm&lt;/code&gt;, not &lt;code&gt;npm&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test files&lt;/td&gt;
&lt;td&gt;Keep tests organized&lt;/td&gt;
&lt;td&gt;All test files end with &lt;code&gt;.test.ts&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error handling&lt;/td&gt;
&lt;td&gt;Handle errors properly&lt;/td&gt;
&lt;td&gt;Async functions must use &lt;code&gt;try/catch&lt;/code&gt; or return a &lt;code&gt;Result&lt;/code&gt; type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commit format&lt;/td&gt;
&lt;td&gt;Write clear commit messages&lt;/td&gt;
&lt;td&gt;Use conventional commits (&lt;code&gt;feat:&lt;/code&gt;, &lt;code&gt;fix:&lt;/code&gt;, &lt;code&gt;chore:&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every right-hand cell points at a concrete check: a token, a casing rule, a count, a file pattern, a configured tool. Every left-hand cell points at a judgment.&lt;/p&gt;

&lt;p&gt;Real-world rules usually carry scope: "no &lt;code&gt;any&lt;/code&gt; in &lt;code&gt;src/&lt;/code&gt;," "named exports outside &lt;code&gt;index.ts&lt;/code&gt; files," "no &lt;code&gt;console.log&lt;/code&gt; in production code paths." Scope makes a rule narrower and more accurate without making it less enforceable. The interop layer that genuinely needs &lt;code&gt;any&lt;/code&gt; keeps it; the rest of the codebase doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  What kinds of checks exist
&lt;/h2&gt;

&lt;p&gt;Worth knowing what's available, because it shapes what's writable. Static analysis tools targeting AI instruction files generally support a few classes of check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AST-level&lt;/strong&gt;: function names, type annotations, import patterns, forbidden tokens, structural properties&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filesystem&lt;/strong&gt;: file existence, naming conventions, directory layout, file size limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regex&lt;/strong&gt;: literal strings, content patterns, conventional formats&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tooling&lt;/strong&gt;: presence and configuration of linters, formatters, package managers, test runners&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Config-file&lt;/strong&gt;: contents of &lt;code&gt;.eslintrc&lt;/code&gt;, &lt;code&gt;tsconfig.json&lt;/code&gt;, &lt;code&gt;.prettierrc&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git-history&lt;/strong&gt;: commit message formats, branch naming conventions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preference ratios&lt;/strong&gt;: "prefer X over Y" with a compliance percentage instead of a binary verdict&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your rule maps to one of these classes, it's enforceable. If it doesn't, it isn't. The trick when writing instruction files is to keep that map in mind: when you're about to write "be careful with X", ask which of these classes "carefulness with X" lives in. Usually the answer points at a concrete reformulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unenforceable rules aren't worthless
&lt;/h2&gt;

&lt;p&gt;Here's a real tension: most of what makes a CLAUDE.md useful isn't enforceable at all. Project context (what the repo does, where the architecture lives), agent behavior directives (be succinct, ask before deleting, don't touch &lt;code&gt;/legacy&lt;/code&gt;), and onboarding instructions are all valuable. None of them extract as rules.&lt;/p&gt;

&lt;p&gt;Don't try to make them enforceable. They're a different kind of content with a different purpose. Project context grounds the agent. Behavior directives shape its style. Neither is supposed to be checked against output; they're checked against the agent's process, which is a different problem.&lt;/p&gt;

&lt;p&gt;The mistake worth avoiding is letting unenforceable prose crowd out enforceable rules. Anthropic's Claude Code best practices doc recommends deleting any instruction the model already follows correctly without it. Most "write clean code" style rules fail that test: the model already does its version of clean code, so the line is taking up attention budget your agent could be spending on the specific, verifiable rules that actually distinguish your codebase from a generic project. Cut what the model already does. Keep the checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  A test for your own files
&lt;/h2&gt;

&lt;p&gt;Pull up your CLAUDE.md or AGENTS.md right now. For each line that looks like a rule, ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Could a junior engineer check this without asking clarifying questions?&lt;/li&gt;
&lt;li&gt;Does it name a specific pattern, file, token, casing, or value?&lt;/li&gt;
&lt;li&gt;Would 5 different reviewers all agree on whether a piece of code passes this rule?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a rule fails 1 or 2, it's not a rule, it's a wish. If it fails 3, it's ambiguous. Rewrite or delete.&lt;/p&gt;

&lt;p&gt;If you want a mechanical version of this test, &lt;a href="https://github.com/moonrunnerkc/ruleprobe" rel="noopener noreferrer"&gt;RuleProbe&lt;/a&gt; parses CLAUDE.md, AGENTS.md, &lt;code&gt;.cursorrules&lt;/code&gt;, &lt;code&gt;.windsurfrules&lt;/code&gt;, GEMINI.md, and &lt;code&gt;copilot-instructions.md&lt;/code&gt; against 102 matchers and tells you which lines extracted as rules and which didn't:&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; ruleprobe
ruleprobe parse ./CLAUDE.md &lt;span class="nt"&gt;--show-unparseable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--show-unparseable&lt;/code&gt; flag is the interesting one. It surfaces every line that looked rule-shaped but didn't map to a check. That list is your rewrite queue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/moonrunnerkc/ruleprobe" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;RuleProbe on GitHub&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What this leaves out
&lt;/h2&gt;

&lt;p&gt;The hardest case is rules like "follow the existing error handling pattern in this codebase." That's enforceable in principle (compare new code's structural shape against the codebase's dominant pattern), but not by simple AST or regex matching. It needs codebase-aware analysis. Some tools handle that; most don't. If you find yourself writing those kinds of rules, know that they'll either need a tool that does pattern profiling or they'll stay aspirational.&lt;/p&gt;

&lt;p&gt;The other thing enforceability doesn't catch: an agent that follows every rule and still writes broken code. Static rules reduce variance, they don't eliminate it. A function with &lt;code&gt;any&lt;/code&gt; removed and an explicit return type can still have wrong logic. Treat passing rule checks as a floor, not a ceiling.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Dropped Multi-Agent Coordination for a 5-Layer Falsification Battery</title>
      <dc:creator>Brad Kinnard</dc:creator>
      <pubDate>Sat, 02 May 2026 15:00:11 +0000</pubDate>
      <link>https://dev.to/moonrunnerkc/i-dropped-multi-agent-coordination-for-a-5-layer-falsification-battery-48cb</link>
      <guid>https://dev.to/moonrunnerkc/i-dropped-multi-agent-coordination-for-a-5-layer-falsification-battery-48cb</guid>
      <description>&lt;p&gt;Swarm Orchestrator just lost its swarm. Dropped the multi-agent parallel coordination layer. Running one agent now and putting all the weight on a five-layer post-merge falsification battery instead.&lt;/p&gt;

&lt;p&gt;This is an experiment, not an endpoint. v8 will bring proper multi-agent swarming back. The reason for cutting it temporarily: I want to know whether the value I was getting from coordinated parallel agents was the coordination itself, or the verification pressure that coordination produced. Easier to measure with one variable. Intended side effect: cost reduction, since the previous architecture spun up multiple CLI agent instances per run. Real benchmarks pending.&lt;/p&gt;


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

  &lt;br&gt;
&lt;strong&gt;TL;DR&lt;/strong&gt;: every patch survives a five-layer post-merge battery before the orchestrator declares success. Layers 1 and 2 are hard gates. Layers 3, 4, 5 are advisory and feed a composite score. Hard-gate failure throws before attestation, before final gates, before any external success signal.&lt;br&gt;

&lt;/div&gt;


&lt;h2&gt;
  
  
  Pipeline Order
&lt;/h2&gt;

&lt;p&gt;The battery runs once per orchestrator execution against the merged working tree, not per-step branches. The per-step verifier is a separate component. Layers fire in fixed order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Differential gate (hard)&lt;/li&gt;
&lt;li&gt;Mutation gate (hard)&lt;/li&gt;
&lt;li&gt;Cheat detector (advisory)&lt;/li&gt;
&lt;li&gt;Property gate (advisory)&lt;/li&gt;
&lt;li&gt;Attestation (advisory on first run, signed after)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the hard gate fails, the composite is forced to &lt;code&gt;0&lt;/code&gt; and the orchestrator throws &lt;code&gt;falsification battery blocked the patch&lt;/code&gt; before any external success signal can fire.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: Differential Gate (Hard)
&lt;/h2&gt;

&lt;p&gt;Before any agent touches the repo, a synthesizer generates a regression test against the goal. Layer 1 then runs that test in two detached worktrees: one at the base commit, one at the patch commit.&lt;/p&gt;

&lt;p&gt;The contract: the test must fail at base and pass at patch.&lt;/p&gt;

&lt;p&gt;If the test passes at base, the layer returns &lt;code&gt;INVALID_TEST&lt;/code&gt;. This catches the specific failure mode where an agent writes a tautological test that passes against any code. Without this gate, that pattern slips through every other check downstream.&lt;/p&gt;

&lt;p&gt;If no command can be synthesized and the caller doesn't pass &lt;code&gt;--differentialTestCommand&lt;/code&gt;, the layer fails closed. Deliberate policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: Mutation Gate (Hard)
&lt;/h2&gt;

&lt;p&gt;Runs Stryker for JS/TS, mutmut for Python, PITest (Gradle/Maven) for Java, against changed files only. First runs the regression command; if that fails, the layer fails immediately. On pass, dispatches the mutation tool and parses the reporter output, including Stryker's clear-text table layout.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt; 0.6&lt;/td&gt;
&lt;td&gt;FAIL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt; 0.8&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≥ 0.8&lt;/td&gt;
&lt;td&gt;PASS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Patches with no meaningful test coverage of the changed lines fail here even when &lt;code&gt;npm test&lt;/code&gt; is green.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Cheat Detector (Advisory)
&lt;/h2&gt;

&lt;p&gt;Diff-static scan for known agent-shortcut patterns. Each rule maps to a real category of behaviour I've watched agents fall into under pressure.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  Cheat detector rule IDs
  &lt;ul&gt;
&lt;li&gt;
&lt;code&gt;test-modification&lt;/code&gt;: agent edited the test instead of the implementation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;complexity-mismatch&lt;/code&gt;: trivial implementation paired with a non-trivial test&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mock-mutation&lt;/code&gt;: real call replaced with a mock that returns the expected value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exception-swallowing&lt;/code&gt;: caught and ignored exceptions to make tests pass&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hardcoded-answer&lt;/code&gt;: literal return of the expected output
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Optional Semgrep integration loads any registered cheat-rule packs into a transient config. The scan reads added and removed lines and patterns; it does not execute the patch. An agent that hides a hardcoded answer behind a small computation can still pass this layer. Honest about that.&lt;/p&gt;
&lt;h2&gt;
  
  
  Layer 4: Property Gate (Advisory)
&lt;/h2&gt;

&lt;p&gt;Discovers modified TS/JS/Python functions, parses their parameter types, maps each to a fast-check arbitrary or Hypothesis strategy, generates a harness, runs it. Counterexamples surface as findings. Untyped or unsupported types degrade to a low-severity advisory finding rather than blocking.&lt;/p&gt;
&lt;h2&gt;
  
  
  Layer 5: Attestation (Advisory on First Run)
&lt;/h2&gt;

&lt;p&gt;Reads the &lt;code&gt;refs/notes/swarm-attestation&lt;/code&gt; git note for the patch commit, validates the in-toto SLSA v1.0 envelope's subject SHA against the patch commit, then verifies the cosign signature. On the first run for a commit there's no note yet, so this layer reports advisory-warn and the post-battery attestation step writes the note.&lt;/p&gt;

&lt;p&gt;The note is verifiable later via &lt;code&gt;swarm attest verify &amp;lt;commit&amp;gt;&lt;/code&gt;. A downstream consumer can verify the patch survived the battery without trusting the running orchestrator process.&lt;/p&gt;
&lt;h2&gt;
  
  
  Composite Scoring
&lt;/h2&gt;

&lt;p&gt;When the hard gate passes, a weighted composite is computed across the three advisory layers and any optional advisory quality-gate results. Failed advisory gates each subtract a fixed penalty.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  Default scoring (overridable via .swarm/gates.yaml)
  &lt;ul&gt;
&lt;li&gt;composite threshold: &lt;code&gt;0.7&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;weights: cheat detector &lt;code&gt;0.4&lt;/code&gt;, property gate &lt;code&gt;0.4&lt;/code&gt;, attestation &lt;code&gt;0.2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;advisory gate penalty: &lt;code&gt;0.02&lt;/code&gt; per failure
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;humanReviewRequired&lt;/code&gt; is true when the composite score is below threshold or any advisory layer is in advisory-warn status.&lt;/p&gt;
&lt;h2&gt;
  
  
  Where It Actually Runs
&lt;/h2&gt;

&lt;p&gt;Three real call sites, not just unit tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Production orchestrator on every &lt;code&gt;swarm&lt;/code&gt; run&lt;/li&gt;
&lt;li&gt;Synthetic calibration corpus (36 paired test specs across 6 broken-category families) executing in CI on every push&lt;/li&gt;
&lt;li&gt;SWE-bench harness using Layer 1 and Layer 4 as standalone spot-check eval drivers&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Honest Caveats
&lt;/h2&gt;

&lt;p&gt;These are in &lt;code&gt;docs/known-gaps.md&lt;/code&gt; and I won't hide them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Differential gate is host-Python-sensitive on legacy codebases. The synth-eval can reflect import-chain errors rather than assertion outcomes. The authoritative resolution gate in the per-instance Docker image is unaffected.&lt;/li&gt;
&lt;li&gt;Mutation gate skips quietly when no changed files match supported languages. YAML, Markdown, Rust, Go diffs don't get mutation-tested.&lt;/li&gt;
&lt;li&gt;Cheat detector is diff-static, not behavioural. The hidden-computation-around-hardcoded-answer pattern can pass it.&lt;/li&gt;
&lt;li&gt;Attestation signing is best-effort. Cosign-not-installed errors get logged and the run proceeds without a note. The note's absence is reflected in Layer 5's advisory-warn on subsequent runs but does not block.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Why Run This Experiment
&lt;/h2&gt;

&lt;p&gt;If the falsification battery alone produces patches that survive scrutiny at acceptable quality, then a lot of the apparent value of multi-agent coordination was actually the verification pressure it created, not the agent diversity itself. If the battery alone isn't enough, then v8 multi-agent gets a clearer mandate: the swarm is the value, not the side effect.&lt;/p&gt;

&lt;p&gt;Either result is useful. The point of the rewrite is to make the answer measurable.&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 on GitHub&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
